mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-03 17:24:24 +00:00
Pattern-match return. Includes gross hack!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24874 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e08705134f
commit
9e4dd9dfc9
@ -1043,29 +1043,6 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
|
||||
Select(N->getOperand(3)),
|
||||
getI32Imm(BROpc));
|
||||
}
|
||||
|
||||
case ISD::RET: {
|
||||
SDOperand Chain = Select(N->getOperand(0)); // Token chain.
|
||||
|
||||
if (N->getNumOperands() == 2) {
|
||||
SDOperand Val = Select(N->getOperand(1));
|
||||
if (N->getOperand(1).getValueType() == MVT::i32) {
|
||||
Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Val);
|
||||
} else {
|
||||
assert(MVT::isFloatingPoint(N->getOperand(1).getValueType()));
|
||||
Chain = CurDAG->getCopyToReg(Chain, PPC::F1, Val);
|
||||
}
|
||||
} else if (N->getNumOperands() > 1) {
|
||||
assert(N->getOperand(1).getValueType() == MVT::i32 &&
|
||||
N->getOperand(2).getValueType() == MVT::i32 &&
|
||||
N->getNumOperands() == 3 && "Unknown two-register ret value!");
|
||||
Chain = CurDAG->getCopyToReg(Chain, PPC::R4, Select(N->getOperand(1)));
|
||||
Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Select(N->getOperand(2)));
|
||||
}
|
||||
|
||||
// Finally, select this to a blr (return) instruction.
|
||||
return CurDAG->SelectNodeTo(N, PPC::BLR, MVT::Other, Chain);
|
||||
}
|
||||
case ISD::BR_CC:
|
||||
case ISD::BRTWOWAY_CC: {
|
||||
SDOperand Chain = Select(N->getOperand(0));
|
||||
|
@ -793,15 +793,26 @@ PPCTargetLowering::LowerCallTo(SDOperand Chain,
|
||||
|
||||
SDOperand PPCTargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
|
||||
SelectionDAG &DAG) {
|
||||
if (Op.getValueType() == MVT::i64) {
|
||||
SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
|
||||
DAG.getConstant(1, MVT::i32));
|
||||
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
|
||||
DAG.getConstant(0, MVT::i32));
|
||||
return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Hi);
|
||||
} else {
|
||||
return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
|
||||
SDOperand Copy;
|
||||
switch (Op.getValueType()) {
|
||||
default: assert(0 && "Unknown type to return!");
|
||||
case MVT::i32:
|
||||
Copy = DAG.getCopyToReg(Chain, PPC::R3, Op, SDOperand());
|
||||
break;
|
||||
case MVT::f32:
|
||||
case MVT::f64:
|
||||
Copy = DAG.getCopyToReg(Chain, PPC::F1, Op, SDOperand());
|
||||
break;
|
||||
case MVT::i64:
|
||||
SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
|
||||
DAG.getConstant(1, MVT::i32));
|
||||
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
|
||||
DAG.getConstant(0, MVT::i32));
|
||||
Copy = DAG.getCopyToReg(Chain, PPC::R3, Hi, SDOperand());
|
||||
Copy = DAG.getCopyToReg(Copy, PPC::R4, Lo, Copy.getValue(1));
|
||||
break;
|
||||
}
|
||||
return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
|
||||
}
|
||||
|
||||
SDOperand PPCTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
|
||||
|
@ -54,12 +54,14 @@ namespace llvm {
|
||||
/// at function entry, used for PIC code.
|
||||
GlobalBaseReg,
|
||||
|
||||
|
||||
/// These nodes represent the 32-bit PPC shifts that operate on 6-bit
|
||||
/// shift amounts. These nodes are generated by the multi-precision shift
|
||||
/// code.
|
||||
SRL, SRA, SHL,
|
||||
};
|
||||
|
||||
/// Return with a flag operand, matched by 'blr'
|
||||
RET_FLAG,
|
||||
};
|
||||
}
|
||||
|
||||
class PPCTargetLowering : public TargetLowering {
|
||||
|
@ -328,12 +328,14 @@ class XLForm_1<bits<6> opcode, bits<10> xo, dag OL, string asmstr,
|
||||
}
|
||||
|
||||
class XLForm_2<bits<6> opcode, bits<10> xo, bit lk, dag OL, string asmstr,
|
||||
InstrItinClass itin>
|
||||
InstrItinClass itin, list<dag> pattern>
|
||||
: I<opcode, OL, asmstr, itin> {
|
||||
bits<5> BO;
|
||||
bits<5> BI;
|
||||
bits<2> BH;
|
||||
|
||||
let Pattern = pattern;
|
||||
|
||||
let Inst{6-10} = BO;
|
||||
let Inst{11-15} = BI;
|
||||
let Inst{16-18} = 0;
|
||||
@ -343,8 +345,8 @@ class XLForm_2<bits<6> opcode, bits<10> xo, bit lk, dag OL, string asmstr,
|
||||
}
|
||||
|
||||
class XLForm_2_ext<bits<6> opcode, bits<10> xo, bits<5> bo, bits<5> bi, bit lk,
|
||||
dag OL, string asmstr, InstrItinClass itin>
|
||||
: XLForm_2<opcode, xo, lk, OL, asmstr, itin> {
|
||||
dag OL, string asmstr, InstrItinClass itin, list<dag> pattern>
|
||||
: XLForm_2<opcode, xo, lk, OL, asmstr, itin, pattern> {
|
||||
let BO = bo;
|
||||
let BI = bi;
|
||||
let BH = 0;
|
||||
|
@ -46,6 +46,9 @@ def SDT_PPCCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
|
||||
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 retflag : SDNode<"PPCISD::RET_FLAG", SDT_PPCRetFlag, [SDNPHasChain]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PowerPC specific transformation functions and pattern fragments.
|
||||
//
|
||||
@ -221,8 +224,8 @@ let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler.
|
||||
|
||||
let isTerminator = 1 in {
|
||||
let isReturn = 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 BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr", BrB, [(ret)]>;
|
||||
def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (ops), "bctr", BrB, []>;
|
||||
}
|
||||
|
||||
let Defs = [LR] in
|
||||
@ -267,7 +270,8 @@ let isCall = 1,
|
||||
"bl $func", BrB, []>;
|
||||
def BLA : IForm<18, 1, 1, (ops aaddr:$func, variable_ops),
|
||||
"bla $func", BrB, []>;
|
||||
def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (ops variable_ops), "bctrl", BrB>;
|
||||
def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (ops variable_ops), "bctrl", BrB,
|
||||
[]>;
|
||||
}
|
||||
|
||||
// D-Form instructions. Most instructions that perform an operation on a
|
||||
@ -1052,6 +1056,8 @@ def : Pat<(f64 (extload iaddr:$src, f32)),
|
||||
def : Pat<(f64 (extload xaddr:$src, f32)),
|
||||
(FMRSD (LFSX xaddr:$src))>;
|
||||
|
||||
def : Pat<(retflag FLAG), (BLR)>;
|
||||
|
||||
// Same as above, but using a temporary. FIXME: implement temporaries :)
|
||||
/*
|
||||
def : Pattern<(xor GPRC:$in, imm:$imm),
|
||||
|
@ -132,6 +132,14 @@ def CTR : SPR<9, "ctr">;
|
||||
// VRsave register
|
||||
def VRSAVE: SPR<256, "VRsave">;
|
||||
|
||||
// FIXME:
|
||||
// HACKTROCITY: define a flags reg class for things that need to take a flag.
|
||||
// this should really be handled by tablgen.
|
||||
def FLAG: SPR<1023, "Flag">;
|
||||
def FLAGRC : RegisterClass<"PPC", [FlagVT], 32, [FLAG]> {
|
||||
let Size = 32;
|
||||
}
|
||||
|
||||
/// Register classes
|
||||
// Allocate volatiles first
|
||||
// then nonvolatiles in reverse order since stmw/lmw save from rN to r31
|
||||
|
Loading…
x
Reference in New Issue
Block a user