From 9e4dd9dfc97f3930f58ca6e47bebbd8eb5cdd8a1 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Tue, 20 Dec 2005 00:26:01 +0000 Subject: [PATCH] Pattern-match return. Includes gross hack! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24874 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 23 ---------------------- lib/Target/PowerPC/PPCISelLowering.cpp | 27 ++++++++++++++++++-------- lib/Target/PowerPC/PPCISelLowering.h | 6 ++++-- lib/Target/PowerPC/PPCInstrFormats.td | 8 +++++--- lib/Target/PowerPC/PPCInstrInfo.td | 12 +++++++++--- lib/Target/PowerPC/PPCRegisterInfo.td | 8 ++++++++ 6 files changed, 45 insertions(+), 39 deletions(-) diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 338be660808..4d9abdc9a7f 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -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)); diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index ba3fa0ed2c9..0e5000e37fb 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -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, diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index 4cce315185a..daf392ce0a7 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -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 { diff --git a/lib/Target/PowerPC/PPCInstrFormats.td b/lib/Target/PowerPC/PPCInstrFormats.td index 8b28e5f8145..07f0e1ca309 100644 --- a/lib/Target/PowerPC/PPCInstrFormats.td +++ b/lib/Target/PowerPC/PPCInstrFormats.td @@ -328,12 +328,14 @@ class XLForm_1 opcode, bits<10> xo, dag OL, string asmstr, } class XLForm_2 opcode, bits<10> xo, bit lk, dag OL, string asmstr, - InstrItinClass itin> + InstrItinClass itin, list pattern> : I { 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 opcode, bits<10> xo, bit lk, dag OL, string asmstr, } class XLForm_2_ext opcode, bits<10> xo, bits<5> bo, bits<5> bi, bit lk, - dag OL, string asmstr, InstrItinClass itin> - : XLForm_2 { + dag OL, string asmstr, InstrItinClass itin, list pattern> + : XLForm_2 { let BO = bo; let BI = bi; let BH = 0; diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 12a6cfba4f7..a0356a67c50 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -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), diff --git a/lib/Target/PowerPC/PPCRegisterInfo.td b/lib/Target/PowerPC/PPCRegisterInfo.td index f34950054a5..c8ac374c85d 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.td +++ b/lib/Target/PowerPC/PPCRegisterInfo.td @@ -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