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,
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,
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
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),
(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),
"($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,
"($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
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", []>;
"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,
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,
[]>;
"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)]>;
"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;
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)]>;
[(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,
[]>;
// 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)]>;
let isBranch = 1;
let isTerminator = 1;
let hasDelaySlot = 1;
+ let noResults = 1;
}
let isBarrier = 1 in
let isBranch = 1;
let isTerminator = 1;
let hasDelaySlot = 1;
+ let noResults = 1;
}
def FBU : FPBranchV8<0b0111, (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),
// 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)]>;
let isBranch = 1;
let isTerminator = 1;
let hasDelaySlot = 1;
+ let noResults = 1;
}
let isBarrier = 1 in
let isBranch = 1;
let isTerminator = 1;
let hasDelaySlot = 1;
+ let noResults = 1;
}
def FBU : FPBranchV8<0b0111, (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),
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.
}
//
// 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)]>;
}
}
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>;
//===----------------------------------------------------------------------===//
// 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 {
}
// 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", []>;
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
bool hasCtrlDep;
bool hasInFlag;
bool hasOutFlag;
+ bool noResults;
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;
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);