def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PPCCallSeq,[SDNPHasChain]>;
def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_PPCCallSeq,[SDNPHasChain]>;
-def SDT_PPCRetFlag : SDTypeProfile<0, 1, [ SDTCisVT<0, FlagVT>]>;
+def SDT_PPCRetFlag : SDTypeProfile<0, 0, []>;
def retflag : SDNode<"PPCISD::RET_FLAG", SDT_PPCRetFlag, [SDNPHasChain]>;
//===----------------------------------------------------------------------===//
let isTerminator = 1 in {
+ // FIXME: temporary workaround for return without an incoming flag.
let isReturn = 1 in
- def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr", BrB, [(ret)]>;
+ def BLRVOID : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr", BrB, [(ret)]>;
+ let isReturn = 1, hasInFlag = 1 in
+ def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr", BrB, []>;
def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (ops), "bctr", BrB, []>;
}
def : Pat<(f64 (extload xaddr:$src, f32)),
(FMRSD (LFSX xaddr:$src))>;
-def : Pat<(retflag FLAG), (BLR)>;
+def : Pat<(retflag), (BLR)>;
// Same as above, but using a temporary. FIXME: implement temporaries :)
/*
const MachineFrameInfo *MFI = MF.getFrameInfo();
MachineBasicBlock::iterator MBBI = prior(MBB.end());
MachineInstr *MI;
- assert(MBBI->getOpcode() == PPC::BLR &&
+ // FIXME: BLRVOID should be removed. See PPCInstrInfo.td
+ assert((MBBI->getOpcode() == PPC::BLR || MBBI->getOpcode() == PPC::BLRVOID) &&
"Can only insert epilog into returning blocks");
// Get the number of bytes allocated from the FrameInfo...
def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_V8CallSeq, [SDNPHasChain]>;
def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_V8CallSeq, [SDNPHasChain]>;
-def SDT_V8Call : SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisVT<1, i32>,
- SDTCisVT<2, FlagVT>]>;
+def SDT_V8Call : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
def call : SDNode<"ISD::CALL", SDT_V8Call, [SDNPHasChain]>;
-def SDT_V8RetFlag : SDTypeProfile<0, 1, [ SDTCisVT<0, FlagVT>]>;
+def SDT_V8RetFlag : SDTypeProfile<0, 0, []>;
def retflag : SDNode<"V8ISD::RET_FLAG", SDT_V8RetFlag, [SDNPHasChain]>;
//===----------------------------------------------------------------------===//
// special cases of JMPL:
let isReturn = 1, isTerminator = 1, hasDelaySlot = 1 in {
let rd = O7.Num, rs1 = G0.Num, simm13 = 8 in
- def RETL: F3_2<2, 0b111000, (ops),
- "retl", [(ret)]>;
+ // FIXME: temporary workaround for return without an incoming flag.
+ def RETVOID: F3_2<2, 0b111000, (ops), "retl", [(ret)]>;
+ let hasInFlag = 1 in
+ def RETL: F3_2<2, 0b111000, (ops), "retl", []>;
}
// Section B.1 - Load Integer Instructions, p. 90
// 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,
+let Uses = [O0, O1, O2, O3, O4, O5],
+ hasDelaySlot = 1, isCall = 1, hasInFlag = 1, hasOutFlag = 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 {
- // pc-relative call:
def CALL : InstV8<(ops calltarget:$dst),
- "call $dst",
- [(set FLAG, (call tglobaladdr:$dst, FLAG))]> {
+ "call $dst", []> {
bits<30> disp;
let op = 1;
let Inst{29-0} = disp;
}
-
+
// indirect calls
def JMPLrr : F3_1<2, 0b111000,
(ops MEMrr:$ptr),
"call $ptr",
- [(set FLAG, (call ADDRrr:$ptr, FLAG))]>;
+ [(call ADDRrr:$ptr)]>;
def JMPLri : F3_2<2, 0b111000,
(ops MEMri:$ptr),
"call $ptr",
- [(set FLAG, (call ADDRri:$ptr, FLAG))]>;
+ [(call ADDRri:$ptr)]>;
}
// Section B.28 - Read State Register Instructions
def : Pat<(V8lo tconstpool:$in), (ORri G0, tconstpool:$in)>;
// Return of a value, which has an input flag.
-def : Pat<(retflag FLAG), (RETL)>;
+def : Pat<(retflag), (RETL)>;
+
+
+// Calls:
+def : Pat<(call tglobaladdr:$dst),
+ (CALL tglobaladdr:$dst)>;
+def : Pat<(call externalsym:$dst),
+ (CALL externalsym:$dst)>;
+
// Map integer extload's to zextloads.
def : Pat<(i32 (extload ADDRrr:$src, i1)), (LDUBrr ADDRrr:$src)>;
void SparcV8RegisterInfo::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator MBBI = prior(MBB.end());
- assert(MBBI->getOpcode() == V8::RETL &&
+ // FIXME: RETVOID should be removed. See SparcV8InstrInfo.td
+ assert((MBBI->getOpcode() == V8::RETL || MBBI->getOpcode() == V8::RETVOID) &&
"Can only put epilog before 'retl' instruction!");
BuildMI(MBB, MBBI, V8::RESTORErr, 2, V8::G0).addReg(V8::G0).addReg(V8::G0);
}
def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_V8CallSeq, [SDNPHasChain]>;
def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_V8CallSeq, [SDNPHasChain]>;
-def SDT_V8Call : SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisVT<1, i32>,
- SDTCisVT<2, FlagVT>]>;
+def SDT_V8Call : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
def call : SDNode<"ISD::CALL", SDT_V8Call, [SDNPHasChain]>;
-def SDT_V8RetFlag : SDTypeProfile<0, 1, [ SDTCisVT<0, FlagVT>]>;
+def SDT_V8RetFlag : SDTypeProfile<0, 0, []>;
def retflag : SDNode<"V8ISD::RET_FLAG", SDT_V8RetFlag, [SDNPHasChain]>;
//===----------------------------------------------------------------------===//
// special cases of JMPL:
let isReturn = 1, isTerminator = 1, hasDelaySlot = 1 in {
let rd = O7.Num, rs1 = G0.Num, simm13 = 8 in
- def RETL: F3_2<2, 0b111000, (ops),
- "retl", [(ret)]>;
+ // FIXME: temporary workaround for return without an incoming flag.
+ def RETVOID: F3_2<2, 0b111000, (ops), "retl", [(ret)]>;
+ let hasInFlag = 1 in
+ def RETL: F3_2<2, 0b111000, (ops), "retl", []>;
}
// Section B.1 - Load Integer Instructions, p. 90
// 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,
+let Uses = [O0, O1, O2, O3, O4, O5],
+ hasDelaySlot = 1, isCall = 1, hasInFlag = 1, hasOutFlag = 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 {
- // pc-relative call:
def CALL : InstV8<(ops calltarget:$dst),
- "call $dst",
- [(set FLAG, (call tglobaladdr:$dst, FLAG))]> {
+ "call $dst", []> {
bits<30> disp;
let op = 1;
let Inst{29-0} = disp;
}
-
+
// indirect calls
def JMPLrr : F3_1<2, 0b111000,
(ops MEMrr:$ptr),
"call $ptr",
- [(set FLAG, (call ADDRrr:$ptr, FLAG))]>;
+ [(call ADDRrr:$ptr)]>;
def JMPLri : F3_2<2, 0b111000,
(ops MEMri:$ptr),
"call $ptr",
- [(set FLAG, (call ADDRri:$ptr, FLAG))]>;
+ [(call ADDRri:$ptr)]>;
}
// Section B.28 - Read State Register Instructions
def : Pat<(V8lo tconstpool:$in), (ORri G0, tconstpool:$in)>;
// Return of a value, which has an input flag.
-def : Pat<(retflag FLAG), (RETL)>;
+def : Pat<(retflag), (RETL)>;
+
+
+// Calls:
+def : Pat<(call tglobaladdr:$dst),
+ (CALL tglobaladdr:$dst)>;
+def : Pat<(call externalsym:$dst),
+ (CALL externalsym:$dst)>;
+
// Map integer extload's to zextloads.
def : Pat<(i32 (extload ADDRrr:$src, i1)), (LDUBrr ADDRrr:$src)>;
void SparcV8RegisterInfo::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator MBBI = prior(MBB.end());
- assert(MBBI->getOpcode() == V8::RETL &&
+ // FIXME: RETVOID should be removed. See SparcV8InstrInfo.td
+ assert((MBBI->getOpcode() == V8::RETL || MBBI->getOpcode() == V8::RETVOID) &&
"Can only put epilog before 'retl' instruction!");
BuildMI(MBB, MBBI, V8::RESTORErr, 2, V8::G0).addReg(V8::G0).addReg(V8::G0);
}
bit hasDelaySlot = 0; // Does this instruction have an delay slot?
bit usesCustomDAGSchedInserter = 0; // Pseudo instr needing special help.
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?
InstrItinClass Itinerary; // Execution steps used for scheduling.
}
def set;
def node;
def srcvalue;
-def FLAG;
def imm : SDNode<"ISD::Constant" , SDTIntLeaf , [], "ConstantSDNode">;
def vt : SDNode<"ISD::VALUETYPE" , SDTOther , [], "VTSDNode">;
[SDTCisVT<0, i8>, SDTCisVT<1, OtherVT>,
SDTCisVT<2, FlagVT>]>;
-def SDTX86RetFlag : SDTypeProfile<0, 2, [SDTCisVT<0, i16>,
- SDTCisVT<1, FlagVT>]>;
+def SDTX86RetFlag : SDTypeProfile<0, 1, [SDTCisVT<0, i16>]>;
def SDTX86Fld : SDTypeProfile<1, 2, [SDTCisVT<0, f64>,
SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
-def SDTX86FpSet : SDTypeProfile<1, 1, [SDTCisVT<0, FlagVT>, SDTCisFP<1>]>;
+def SDTX86FpSet : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest, []>;
def X86test : SDNode<"X86ISD::TEST", SDTX86CmpTest, []>;
def X86Brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond, [SDNPHasChain]>;
def X86SetCC : SDNode<"X86ISD::SETCC", SDTX86SetCC, []>;
-def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86RetFlag, [SDNPHasChain]>;
+def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86RetFlag, [SDNPHasChain]>;
def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld, [SDNPHasChain]>;
//
// Return instructions.
-let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in
- def RET : I<0xC3, RawFrm, (ops), "ret", [(ret)]>;
-let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in
- def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt", []>;
+let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 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 : Pat<(X86retflag 0, FLAG), (RET)>;
-def : Pat<(X86retflag imm:$amt, FLAG), (RETI imm:$amt)>;
+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
}
// Random Pseudo Instructions.
-def FpGETRESULT : FpPseudoI<(ops RFP:$dst), SpecialFP, // FPR = ST(0)
- []>;
-def FpSETRESULT : FpPseudoI<(ops RFP:$src), SpecialFP,
- [(set FLAG, (X86fpset RFP:$src))]>,
- Imp<[], [ST0]>; // ST(0) = FPR
+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 FpMOV : FpI<(ops RFP:$dst, RFP:$src), SpecialFP,
- []>; // f1 = fmov f2
+def FpMOV : FpI<(ops RFP:$dst, RFP:$src), SpecialFP, []>; // f1 = fmov f2
// Arithmetic
-
// Add, Sub, Mul, Div.
def FpADD : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
[(set RFP:$dst, (fadd RFP:$src1, RFP:$src2))]>;
switch (MBBI->getOpcode()) {
case X86::RET:
case X86::RETI:
+ case X86::RETVOID: // FIXME: See X86InstrInfo.td
case X86::TAILJMPd:
case X86::TAILJMPr:
case X86::TAILJMPm: break; // These are ok