diff options
author | Chris Lattner <sabre@nondot.org> | 2010-10-05 23:58:18 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-10-05 23:58:18 +0000 |
commit | 8d978a75b477c0e4861d937096518eebba639e72 (patch) | |
tree | 6f3d80445489a8265336dd12af682f5d4b5d3d40 | |
parent | 3729d0052bda365d04fee900c6f3d09460f1e108 (diff) | |
download | llvm-8d978a75b477c0e4861d937096518eebba639e72.tar.gz llvm-8d978a75b477c0e4861d937096518eebba639e72.tar.bz2 llvm-8d978a75b477c0e4861d937096518eebba639e72.tar.xz |
allow !strconcat to take more than two operands to eliminate
!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
-rw-r--r-- | lib/Target/X86/X86InstrArithmetic.td | 4 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrFPStack.td | 8 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrSSE.td | 16 | ||||
-rw-r--r-- | utils/TableGen/TGParser.cpp | 57 |
4 files changed, 46 insertions, 39 deletions
diff --git a/lib/Target/X86/X86InstrArithmetic.td b/lib/Target/X86/X86InstrArithmetic.td index 7ce073842d..024bae6795 100644 --- a/lib/Target/X86/X86InstrArithmetic.td +++ b/lib/Target/X86/X86InstrArithmetic.td @@ -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. diff --git a/lib/Target/X86/X86InstrFPStack.td b/lib/Target/X86/X86InstrFPStack.td index 32811e7383..0087e4892b 100644 --- a/lib/Target/X86/X86InstrFPStack.td +++ b/lib/Target/X86/X86InstrFPStack.td @@ -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; } } diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td index b49d2fcf27..1dac75fa34 100644 --- a/lib/Target/X86/X86InstrSSE.td +++ b/lib/Target/X86/X86InstrSSE.td @@ -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; diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp index d3bd5cd710..0c46a814c2 100644 --- a/utils/TableGen/TGParser.cpp +++ b/utils/TableGen/TGParser.cpp @@ -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: |