Added field noResults to Instruction.
authorEvan Cheng <evan.cheng@apple.com>
Mon, 26 Dec 2005 09:11:45 +0000 (09:11 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Mon, 26 Dec 2005 09:11:45 +0000 (09:11 +0000)
Currently tblgen cannot tell which operands in the operand list are results so
it assumes the first one is a result. This is bad. Ideally we would fix this
by separating results from inputs, e.g. (res R32:$dst),
(ops R32:$src1, R32:$src2). But that's a more distruptive change. Adding
'let noResults = 1' is the workaround to tell tblgen that the instruction does
not produces a result. It works for now since tblgen does not support
instructions which produce multiple results.

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

lib/Target/Alpha/AlphaInstrInfo.td
lib/Target/IA64/IA64InstrInfo.td
lib/Target/PowerPC/PPCInstrInfo.td
lib/Target/Sparc/SparcInstrInfo.td
lib/Target/SparcV8/SparcV8InstrInfo.td
lib/Target/Target.td
lib/Target/X86/X86InstrInfo.td
utils/TableGen/CodeGenInstruction.h
utils/TableGen/CodeGenTarget.cpp
utils/TableGen/DAGISelEmitter.cpp

index 939456fef08ad0d65578b31bafe405ccd8ff179b..97c9d81f7ad581374b173d71187cbc10449cd8fb 100644 (file)
@@ -404,14 +404,14 @@ def : Pat<(setune GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
 def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>;
 
 
-let isReturn = 1, isTerminator = 1 in 
+let isReturn = 1, isTerminator = 1, noResults = 1 in 
   def RET : MbrForm< 0x1A, 0x02, (ops GPRC:$RD, GPRC:$RS, s64imm:$DISP), "ret $RD,($RS),$DISP">; //Return from subroutine
 //DAG Version:
-let isReturn = 1, isTerminator = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in 
+let isReturn = 1, isTerminator = 1, noResults = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in 
   def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1">; //Return from subroutine
 
 def JMP : MbrForm< 0x1A, 0x00, (ops GPRC:$RD, GPRC:$RS, GPRC:$DISP), "jmp $RD,($RS),$DISP">; //Jump
-let isCall = 1, Ra = 26,
+let isCall = 1, noResults = 1, Ra = 26,
     Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
             R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
             F0, F1,
@@ -419,7 +419,7 @@ let isCall = 1, Ra = 26,
             F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R29] in {
     def BSR : BFormD<0x34, "bsr $$26,$$$DISP..ng", []>; //Branch to subroutine
 }
-let isCall = 1,
+let isCall = 1, noResults = 1,
     Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
             R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
             F0, F1,
@@ -428,7 +428,7 @@ let isCall = 1,
     def JSR : MbrForm< 0x1A, 0x01, (ops ), "jsr $$26,($$27),0">; //Jump to subroutine
 }
 
-let isCall = 1, Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in
+let isCall = 1, noResults = 1, Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in
   def JSRs : MbrForm< 0x1A, 0x01, (ops ), "jsr $$23,($$27),0">; //Jump to div or rem
 
 
index d64682fe86526f6220b5e1fc3d1caae2387f9c0d..a38338ffca6f610f83eb4fcc63a5feb86fd8f712 100644 (file)
@@ -520,7 +520,7 @@ def CADDIMM22 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src1, s22imm:$imm, PR:$qp),
 def SUBIMM8 : AForm<0x03, 0x0b, (ops GR:$dst, s8imm:$imm, GR:$src2),
   "sub $dst = $imm, $src2;;">;
 
-let isStore = 1 in {
+let isStore = 1, noResults = 1 in {
   def ST1 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value),
     "st1 [$dstPtr] = $value;;">;
   def ST2 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value),
@@ -643,7 +643,7 @@ def FP_TO_UINT : Pat<(i64 (fp_to_uint FP:$src)),
   (GETFSIG (FCVTFXUTRUNC FP:$src))>;
 
 
-let isTerminator = 1, isBranch = 1 in {
+let isTerminator = 1, isBranch = 1, noResults = 1 in {
   def BRL_NOTCALL : RawForm<0x03, 0xb0, (ops i64imm:$dst),
     "(p0) brl.cond.sptk $dst;;">;
   def BRLCOND_NOTCALL : RawForm<0x03, 0xb0, (ops PR:$qp, i64imm:$dst),
@@ -652,7 +652,7 @@ let isTerminator = 1, isBranch = 1 in {
     "($qp) br.cond.sptk $dst;;">;
 }
 
-let isCall = 1, /* isTerminator = 1, isBranch = 1, */
+let isCall = 1, noResults = 1, /* isTerminator = 1, isBranch = 1, */
   Uses = [out0,out1,out2,out3,out4,out5,out6,out7],
 // all calls clobber non-callee-saved registers, and for now, they are these:
   Defs = [r2,r3,r8,r9,r10,r11,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24,
@@ -688,7 +688,7 @@ let isCall = 1, /* isTerminator = 1, isBranch = 1, */
     "($qp) br.cond.call.sptk $dst;;">;
 }
 
-let isTerminator = 1, isReturn = 1 in
+let isTerminator = 1, isReturn = 1, noResults = 1 in
   def RET : RawForm<0x03, 0xb0, (ops), "br.ret.sptk.many rp;;">; // return
 
 
index 55eea5fcd46d154a1a1d8ee250982924cdc097ce..2830964c6a9f2bf282962f59e84b4020e1d803db 100644 (file)
@@ -224,17 +224,18 @@ let usesCustomDAGSchedInserter = 1 in {  // Expanded by the scheduler.
 
 let isTerminator = 1 in {
   // FIXME: temporary workaround for return without an incoming flag.
-  let isReturn = 1 in
+  let isReturn = 1, noResults = 1 in
     def BLRVOID : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr", BrB, [(ret)]>;
-  let isReturn = 1, hasInFlag = 1 in
+  let isReturn = 1, noResults = 1, hasInFlag = 1 in
     def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr", BrB, []>;
+  let noResults = 1 in
   def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (ops), "bctr", BrB, []>;
 }
 
 let Defs = [LR] in
   def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label", []>;
 
-let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
+let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, noResults = 1 in {
   def COND_BRANCH : Pseudo<(ops CRRC:$crS, u16imm:$opc,
                                 target:$true, target:$false),
                            "; COND_BRANCH", []>;
@@ -262,7 +263,7 @@ let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
                   "bnu $crS, $block", BrB>;
 }
 
-let isCall = 1, 
+let isCall = 1, noResults = 1, 
   // All calls clobber the non-callee saved registers...
   Defs = [R0,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,
           F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13,
@@ -328,7 +329,7 @@ def LI  : DForm_2_r0<14, (ops GPRC:$rD, symbolLo:$imm),
 def LIS : DForm_2_r0<15, (ops GPRC:$rD, symbolHi:$imm),
                      "lis $rD, $imm", IntGeneral,
                      [(set GPRC:$rD, imm16Shifted:$imm)]>;
-let isStore = 1 in {
+let isStore = 1, noResults = 1 in {
 def STMW : DForm_3<47, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA),
                    "stmw $rS, $disp($rA)", LdStLMW,
                    []>;
@@ -385,7 +386,7 @@ def LFD : DForm_8<50, (ops F8RC:$rD, memri:$src),
                   "lfd $rD, $src", LdStLFD,
                   [(set F8RC:$rD, (load iaddr:$src))]>;
 }
-let isStore = 1 in {
+let isStore = 1, noResults = 1 in {
 def STFS : DForm_9<52, (ops F4RC:$rS, memri:$dst),
                    "stfs $rS, $dst", LdStUX,
                    [(store F4RC:$rS, iaddr:$dst)]>;
@@ -404,7 +405,7 @@ def LD   : DSForm_2<58, 0, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA),
                     "ld $rT, $DS($rA)", LdStLD,
                     []>, isPPC64;
 }
-let isStore = 1 in {
+let isStore = 1, noResults = 1 in {
 def STD  : DSForm_2<62, 0, (ops GPRC:$rT, s16immX4:$DS, GPRC:$rA),
                     "std $rT, $DS($rA)", LdStSTD,
                     []>, isPPC64;
@@ -511,7 +512,7 @@ def SRAD : XForm_6<31, 794, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
 def SRAW : XForm_6<31, 792, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
                    "sraw $rA, $rS, $rB", IntShift,
                    [(set GPRC:$rA, (PPCsra GPRC:$rS, GPRC:$rB))]>;
-let isStore = 1 in {
+let isStore = 1, noResults = 1 in {
 def STBX  : XForm_8<31, 215, (ops GPRC:$rS, memrr:$dst),
                    "stbx $rS, $dst", LdStGeneral,
                    [(truncstore GPRC:$rS, xaddr:$dst, i8)]>;
@@ -636,7 +637,7 @@ def FNEGD  : XForm_26<63, 40, (ops F8RC:$frD, F8RC:$frB),
                       [(set F8RC:$frD, (fneg F8RC:$frB))]>;
                       
                       
-let isStore = 1 in {
+let isStore = 1, noResults = 1 in {
 def STFIWX: XForm_28<31, 983, (ops F4RC:$frS, memrr:$dst),
                      "stfiwx $frS, $dst", LdStUX,
                      []>;
index 79c054eab57e648a29acd6b8f4f48bf84a53d92c..b0fc405d07c0b9d302bd1a0840f7b38d27674a6e 100644 (file)
@@ -171,7 +171,7 @@ let usesCustomDAGSchedInserter = 1 in {  // Expanded by the scheduler.
 
 // Section A.3 - Synthetic Instructions, p. 85
 // special cases of JMPL:
-let isReturn = 1, isTerminator = 1, hasDelaySlot = 1 in {
+let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, noResults = 1 in {
   let rd = O7.Num, rs1 = G0.Num, simm13 = 8 in
     // FIXME: temporary workaround for return without an incoming flag.
     def RETVOID: F3_2<2, 0b111000, (ops), "retl", [(ret)]>;
@@ -466,6 +466,7 @@ class BranchV8<bits<4> cc, dag ops, string asmstr, list<dag> pattern>
   let isBranch = 1;
   let isTerminator = 1;
   let hasDelaySlot = 1;
+  let noResults = 1;
 }
 
 let isBarrier = 1 in
@@ -511,6 +512,7 @@ class FPBranchV8<bits<4> cc, dag ops, string asmstr, list<dag> pattern>
   let isBranch = 1;
   let isTerminator = 1;
   let hasDelaySlot = 1;
+  let noResults = 1;
 }
 
 def FBU  : FPBranchV8<0b0111, (ops brtarget:$dst),
@@ -561,7 +563,7 @@ def FBO  : FPBranchV8<0b1111, (ops brtarget:$dst),
 // Section B.24 - Call and Link Instruction, p. 125
 // This is the only Format 1 instruction
 let Uses = [O0, O1, O2, O3, O4, O5],
-    hasDelaySlot = 1, isCall = 1, hasInFlag = 1, hasOutFlag = 1,
+    hasDelaySlot = 1, isCall = 1, hasInFlag = 1, hasOutFlag = 1, noResults = 1,
     Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7,
     D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in { 
   def CALL : InstV8<(ops calltarget:$dst),
index 79c054eab57e648a29acd6b8f4f48bf84a53d92c..b0fc405d07c0b9d302bd1a0840f7b38d27674a6e 100644 (file)
@@ -171,7 +171,7 @@ let usesCustomDAGSchedInserter = 1 in {  // Expanded by the scheduler.
 
 // Section A.3 - Synthetic Instructions, p. 85
 // special cases of JMPL:
-let isReturn = 1, isTerminator = 1, hasDelaySlot = 1 in {
+let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, noResults = 1 in {
   let rd = O7.Num, rs1 = G0.Num, simm13 = 8 in
     // FIXME: temporary workaround for return without an incoming flag.
     def RETVOID: F3_2<2, 0b111000, (ops), "retl", [(ret)]>;
@@ -466,6 +466,7 @@ class BranchV8<bits<4> cc, dag ops, string asmstr, list<dag> pattern>
   let isBranch = 1;
   let isTerminator = 1;
   let hasDelaySlot = 1;
+  let noResults = 1;
 }
 
 let isBarrier = 1 in
@@ -511,6 +512,7 @@ class FPBranchV8<bits<4> cc, dag ops, string asmstr, list<dag> pattern>
   let isBranch = 1;
   let isTerminator = 1;
   let hasDelaySlot = 1;
+  let noResults = 1;
 }
 
 def FBU  : FPBranchV8<0b0111, (ops brtarget:$dst),
@@ -561,7 +563,7 @@ def FBO  : FPBranchV8<0b1111, (ops brtarget:$dst),
 // Section B.24 - Call and Link Instruction, p. 125
 // This is the only Format 1 instruction
 let Uses = [O0, O1, O2, O3, O4, O5],
-    hasDelaySlot = 1, isCall = 1, hasInFlag = 1, hasOutFlag = 1,
+    hasDelaySlot = 1, isCall = 1, hasInFlag = 1, hasOutFlag = 1, noResults = 1,
     Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7,
     D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in { 
   def CALL : InstV8<(ops calltarget:$dst),
index f2b98ad499561a103c76f0e12c8778bf1117034b..4622fe44ba2d626f8fc27bf615db45d336eac4fd 100644 (file)
@@ -171,6 +171,7 @@ class Instruction {
   bit hasCtrlDep   = 0;     // Does this instruction r/w ctrl-flow chains?
   bit hasInFlag    = 0;     // Does this instruction read a flag operand?
   bit hasOutFlag   = 0;     // Does this instruction write a flag operand?
+  bit noResults    = 0;     // Does this instruction produce no results?
   
   InstrItinClass Itinerary; // Execution steps used for scheduling. 
 }
index f69162e23f2567101c8a30158cfa7fffa9ff7205..edb7285c0d8b616295c190996842f38ac4f7975e 100644 (file)
@@ -289,12 +289,15 @@ let isTerminator = 1 in
 //
 
 // Return instructions.
-let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in {
+let isTerminator = 1, isReturn = 1, isBarrier = 1,
+    hasCtrlDep = 1, noResults = 1 in {
   // FIXME: temporary workaround for return without an incoming flag.
   def RETVOID : I<0xC3, RawFrm, (ops), "ret", [(ret)]>;
   let hasInFlag = 1 in {
-    def RET : I<0xC3, RawFrm, (ops), "ret", []>;
-    def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt", []>;
+    def RET  : I<0xC3, RawFrm, (ops), "ret",
+                 [(X86retflag 0)]>;
+    def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt",
+                    [(X86retflag imm:$amt)]>;
   }
 }
 
@@ -302,7 +305,7 @@ def : Pat<(X86retflag 0),        (RET)>;
 def : Pat<(X86retflag imm:$amt), (RETI imm:$amt)>;
 
 // All branches are RawFrm, Void, Branch, and Terminators
-let isBranch = 1, isTerminator = 1 in
+let isBranch = 1, isTerminator = 1, noResults = 1 in
   class IBr<bits<8> opcode, dag ops, string asm, list<dag> pattern> :
         I<opcode, RawFrm, ops, asm, pattern>;
 
@@ -339,7 +342,7 @@ def JNP : IBr<0x8B, (ops brtarget:$dst), "jnp $dst", []>, TB;
 //===----------------------------------------------------------------------===//
 //  Call Instructions...
 //
-let isCall = 1 in
+let isCall = 1, noResults = 1 in
   // All calls clobber the non-callee saved registers...
   let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
               XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7] in {
@@ -349,11 +352,11 @@ let isCall = 1 in
   }
 
 // Tail call stuff.
-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
+let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
   def TAILJMPd : IBr<0xE9, (ops calltarget:$dst), "jmp $dst  # TAIL CALL", []>;
-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
+let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
   def TAILJMPr : I<0xFF, MRM4r, (ops R32:$dst), "jmp {*}$dst  # TAIL CALL", []>;
-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
+let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
   def TAILJMPm : I<0xFF, MRM4m, (ops i32mem:$dst),
                    "jmp {*}$dst  # TAIL CALL", []>;
 
@@ -2305,20 +2308,13 @@ class FpI<dag ops, FPFormat fp, list<dag> pattern>
   let Pattern = pattern;
 }
 
-// FpI - Floating Point Psuedo Instruction template.
-// TEMPORARY: for FpGETRESULT and FpSETRESULT only. Since
-// they must match regardless of X86Vector.
-class FpPseudoI<dag ops, FPFormat fp, list<dag> pattern>
-  : X86Inst<0, Pseudo, NoImm, ops, ""> {
-  let FPForm = fp; let FPFormBits = FPForm.Value;
-  let Pattern = pattern;
-}
-
 // Random Pseudo Instructions.
-def FpGETRESULT : FpPseudoI<(ops RFP:$dst), SpecialFP, []>;     // FPR = ST(0)
-let hasOutFlag = 1 in 
-  def FpSETRESULT : FpPseudoI<(ops RFP:$src), SpecialFP,
-                    [(X86fpset RFP:$src)]>, Imp<[], [ST0]>;     // ST(0) = FPR
+def FpGETRESULT : FpI<(ops RFP:$dst), SpecialFP, []>;     // FPR = ST(0)
+let noResults = 1, hasOutFlag = 1 in 
+  def FpSETRESULT : FpI<(ops RFP:$src), SpecialFP,
+                        []>, Imp<[], [ST0]>;              // ST(0) = FPR
+
+def : Pat<(X86fpset RFP:$src), (FpSETRESULT RFP:$src)>;
 
 def FpMOV       : FpI<(ops RFP:$dst, RFP:$src), SpecialFP, []>; // f1 = fmov f2
 
index 703da46804e6d0d342ad6a57e13b3df10a52165d..b76d3b98694a75bf4a09a08b4d8260fb2ea76f04 100644 (file)
@@ -87,6 +87,7 @@ namespace llvm {
     bool hasCtrlDep;
     bool hasInFlag;
     bool hasOutFlag;
+    bool noResults;
 
     CodeGenInstruction(Record *R, const std::string &AsmStr);
 
index b6ddd6285c3b54049421a663d0eeaf7d5db9b384..25d01fc05536723b30451b4c0a2f653e1ded6f3b 100644 (file)
@@ -273,6 +273,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
   hasCtrlDep   = R->getValueAsBit("hasCtrlDep");
   hasInFlag    = R->getValueAsBit("hasInFlag");
   hasOutFlag   = R->getValueAsBit("hasOutFlag");
+  noResults    = R->getValueAsBit("noResults");
   hasVariableNumberOfOperands = false;
   
   DagInit *DI;
index 8754097d904f0b2f4f48a71e97ecce150424fb23..85ebfdece9a7555b334e00ef203a8fd3e41b5e37 100644 (file)
@@ -1097,11 +1097,8 @@ void DAGISelEmitter::ParseInstructions() {
       CodeGenInstruction &InstInfo =Target.getInstruction(Instrs[i]->getName());
 
       if (InstInfo.OperandList.size() != 0) {
-        // It's possible for some instruction, e.g. RET for X86 that only has an
-        // implicit flag operand.
         // FIXME: temporary hack...
-        if (InstInfo.isReturn || InstInfo.isBranch || InstInfo.isCall ||
-            InstInfo.isStore) {
+        if (InstInfo.noResults) {
           // These produce no results
           for (unsigned j = 0, e = InstInfo.OperandList.size(); j < e; ++j)
             Operands.push_back(InstInfo.OperandList[j].Rec);