allow !strconcat to take more than two operands to eliminate
authorChris Lattner <sabre@nondot.org>
Tue, 5 Oct 2010 23:58:18 +0000 (23:58 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 5 Oct 2010 23:58:18 +0000 (23:58 +0000)
!strconcat(!strconcat(!strconcat(!strconcat

Simplify some x86 td files to use it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115719 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86InstrArithmetic.td
lib/Target/X86/X86InstrFPStack.td
lib/Target/X86/X86InstrSSE.td
utils/TableGen/TGParser.cpp

index 7ce073842d868e77d8b0af4573b04d4672d0aeaf..024bae679587ca7752be6a868eb5bacd2677b6f9 100644 (file)
@@ -499,8 +499,8 @@ let CodeSize = 2 in {
 class BinOpRR<bits<8> opcode, Format format, string mnemonic,
               X86RegisterClass regclass, SDNode opnode>
   : I<opcode, format, (outs regclass:$dst), (ins regclass:$src1,regclass:$src2),
-      !strconcat(mnemonic, !strconcat("{", !strconcat(regclass.InstrSuffix,
-                 "}\t{$src2, $dst|$dst, $src2}"))),
+      !strconcat(mnemonic, "{", regclass.InstrSuffix,
+                 "}\t{$src2, $dst|$dst, $src2}"),
       [(set regclass:$dst, EFLAGS, (opnode regclass:$src1, regclass:$src2))]>;
 
 // Logical operators.
index 32811e73831d6f8d0ad239912febc2db8fa2006a..0087e4892bb981d0eb923e5789cc9aef30728046 100644 (file)
@@ -215,11 +215,11 @@ def _Fp80m64: FpI_<(outs RFP80:$dst),
                   [(set RFP80:$dst, 
                     (OpNode RFP80:$src1, (f80 (extloadf64 addr:$src2))))]>;
 def _F32m  : FPI<0xD8, fp, (outs), (ins f32mem:$src), 
-                 !strconcat("f", !strconcat(asmstring, "{s}\t$src"))> { 
+                 !strconcat("f", asmstring, "{s}\t$src")> { 
   let mayLoad = 1; 
 }
 def _F64m  : FPI<0xDC, fp, (outs), (ins f64mem:$src), 
-                 !strconcat("f", !strconcat(asmstring, "{l}\t$src"))> { 
+                 !strconcat("f", asmstring, "{l}\t$src")> { 
   let mayLoad = 1; 
 }
 // ST(0) = ST(0) + [memint]
@@ -248,11 +248,11 @@ def _FpI32m80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, i32mem:$src2),
                     [(set RFP80:$dst, (OpNode RFP80:$src1,
                                        (X86fild addr:$src2, i32)))]>;
 def _FI16m  : FPI<0xDE, fp, (outs), (ins i16mem:$src), 
-                  !strconcat("fi", !strconcat(asmstring, "{s}\t$src"))> { 
+                  !strconcat("fi", asmstring, "{s}\t$src")> { 
   let mayLoad = 1; 
 }
 def _FI32m  : FPI<0xDA, fp, (outs), (ins i32mem:$src), 
-                  !strconcat("fi", !strconcat(asmstring, "{l}\t$src"))> { 
+                  !strconcat("fi", asmstring, "{l}\t$src")> { 
   let mayLoad = 1; 
 }
 }
index b49d2fcf2767c4ade6e7f59140ca14a2a21cd3af..1dac75fa344d325d83adceb9daa6a88ba9f0b480 100644 (file)
@@ -46,16 +46,14 @@ multiclass sse12_fp_scalar_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
        [(set RC:$dst, (!nameconcat<Intrinsic>("int_x86_sse",
-                       !strconcat(SSEVer, !strconcat("_",
-                       !strconcat(OpcodeStr, FPSizeStr))))
+                       !strconcat(SSEVer, "_", OpcodeStr, FPSizeStr))
              RC:$src1, RC:$src2))]>;
   def rm_Int : SI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, memopr:$src2),
        !if(Is2Addr,
            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
        [(set RC:$dst, (!nameconcat<Intrinsic>("int_x86_sse",
-                       !strconcat(SSEVer, !strconcat("_",
-                       !strconcat(OpcodeStr, FPSizeStr))))
+                       !strconcat(SSEVer, "_", OpcodeStr, FPSizeStr))
              RC:$src1, mem_cpat:$src2))]>;
 }
 
@@ -106,16 +104,14 @@ multiclass sse12_fp_packed_int<bits<8> opc, string OpcodeStr, RegisterClass RC,
            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
            [(set RC:$dst, (!nameconcat<Intrinsic>("int_x86_",
-                           !strconcat(SSEVer, !strconcat("_",
-                           !strconcat(OpcodeStr, FPSizeStr))))
+                           !strconcat(SSEVer, "_", OpcodeStr, FPSizeStr))
                  RC:$src1, RC:$src2))], d>;
   def rm_Int : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1,x86memop:$src2),
        !if(Is2Addr,
            !strconcat(asm, "\t{$src2, $dst|$dst, $src2}"),
            !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}")),
        [(set RC:$dst, (!nameconcat<Intrinsic>("int_x86_",
-                       !strconcat(SSEVer, !strconcat("_",
-                       !strconcat(OpcodeStr, FPSizeStr))))
+                       !strconcat(SSEVer, "_", OpcodeStr, FPSizeStr))
              RC:$src1, (mem_frag addr:$src2)))], d>;
 }
 
@@ -366,7 +362,7 @@ multiclass sse12_mov_hilo_packed<bits<8>opc, RegisterClass RC,
                                  string asm_opr> {
   def PSrm : PI<opc, MRMSrcMem,
          (outs VR128:$dst), (ins VR128:$src1, f64mem:$src2),
-         !strconcat(!strconcat(base_opc,"s"), asm_opr),
+         !strconcat(base_opc, "s", asm_opr),
      [(set RC:$dst,
        (mov_frag RC:$src1,
               (bc_v4f32 (v2f64 (scalar_to_vector (loadf64 addr:$src2))))))],
@@ -374,7 +370,7 @@ multiclass sse12_mov_hilo_packed<bits<8>opc, RegisterClass RC,
 
   def PDrm : PI<opc, MRMSrcMem,
          (outs RC:$dst), (ins RC:$src1, f64mem:$src2),
-         !strconcat(!strconcat(base_opc,"d"), asm_opr),
+         !strconcat(base_opc, "d", asm_opr),
      [(set RC:$dst, (v2f64 (mov_frag RC:$src1,
                               (scalar_to_vector (loadf64 addr:$src2)))))],
               SSEPackedDouble>, TB, OpSize;
index d3bd5cd710c59ea8320465663f59e8c53dc472cf..0c46a814c25fb4cc53a26880c032b40bc2d952a8 100644 (file)
@@ -16,6 +16,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include <algorithm>
 #include <sstream>
+#include "llvm/ADT/SmallVector.h"
 using namespace llvm;
 
 //===----------------------------------------------------------------------===//
@@ -798,53 +799,46 @@ Init *TGParser::ParseOperation(Record *CurRec) {
   case tgtok::XEq:
   case tgtok::XStrConcat:
   case tgtok::XNameConcat: {  // Value ::= !binop '(' Value ',' Value ')'
+    tgtok::TokKind OpTok = Lex.getCode();
+    SMLoc OpLoc = Lex.getLoc();
+    Lex.Lex();  // eat the operation
+
     BinOpInit::BinaryOp Code;
     RecTy *Type = 0;
 
-
-    switch (Lex.getCode()) {
+    switch (OpTok) {
     default: assert(0 && "Unhandled code!");
     case tgtok::XConcat:
-      Lex.Lex();  // eat the operation
       Code = BinOpInit::CONCAT;
       Type = new DagRecTy();
       break;
     case tgtok::XSRA:
-      Lex.Lex();  // eat the operation
       Code = BinOpInit::SRA;
       Type = new IntRecTy();
       break;
     case tgtok::XSRL:
-      Lex.Lex();  // eat the operation
       Code = BinOpInit::SRL;
       Type = new IntRecTy();
       break;
     case tgtok::XSHL:
-      Lex.Lex();  // eat the operation
       Code = BinOpInit::SHL;
       Type = new IntRecTy();
       break;
     case tgtok::XEq:  
-      Lex.Lex();  // eat the operation
       Code = BinOpInit::EQ;
       Type = new IntRecTy();
       break;
     case tgtok::XStrConcat:
-      Lex.Lex();  // eat the operation
       Code = BinOpInit::STRCONCAT;
       Type = new StringRecTy();
       break;
     case tgtok::XNameConcat:
-      Lex.Lex();  // eat the operation
       Code = BinOpInit::NAMECONCAT;
-
       Type = ParseOperatorType();
-
       if (Type == 0) {
         TokError("did not get type for binary operator");
         return 0;
       }
-
       break;
     }
     if (Lex.getCode() != tgtok::l_paren) {
@@ -853,24 +847,41 @@ Init *TGParser::ParseOperation(Record *CurRec) {
     }
     Lex.Lex();  // eat the '('
 
-    Init *LHS = ParseValue(CurRec);
-    if (LHS == 0) return 0;
+    SmallVector<Init*, 2> InitList;
+    
+    InitList.push_back(ParseValue(CurRec));
+    if (InitList.back() == 0) return 0;
 
-    if (Lex.getCode() != tgtok::comma) {
-      TokError("expected ',' in binary operator");
-      return 0;
-    }
-    Lex.Lex();  // eat the ','
+    while (Lex.getCode() == tgtok::comma) {
+      Lex.Lex();  // eat the ','
 
-    Init *RHS = ParseValue(CurRec);
-    if (RHS == 0) return 0;
+      InitList.push_back(ParseValue(CurRec));
+      if (InitList.back() == 0) return 0;
+    }
 
     if (Lex.getCode() != tgtok::r_paren) {
-      TokError("expected ')' in binary operator");
+      TokError("expected ')' in operator");
       return 0;
     }
     Lex.Lex();  // eat the ')'
-    return (new BinOpInit(Code, LHS, RHS, Type))->Fold(CurRec, CurMultiClass);
+
+    // We allow multiple operands to associative operators like !strconcat as
+    // shorthand for nesting them.
+    if (Code == BinOpInit::STRCONCAT) {
+      while (InitList.size() > 2) {
+        Init *RHS = InitList.pop_back_val();
+        RHS = (new BinOpInit(Code, InitList.back(), RHS, Type))
+                      ->Fold(CurRec, CurMultiClass);
+        InitList.back() = RHS;
+      }
+    }
+    
+    if (InitList.size() == 2)
+      return (new BinOpInit(Code, InitList[0], InitList[1], Type))
+        ->Fold(CurRec, CurMultiClass);
+    
+    Error(OpLoc, "expected two operands to operator");
+    return 0;
   }
 
   case tgtok::XIf: