From 50b37845ef3ecc706806ca6da76c68db283f6e1e Mon Sep 17 00:00:00 2001 From: Andrew Lenharth Date: Tue, 22 Nov 2005 04:20:06 +0000 Subject: [PATCH] massive DAGISel patch. lots and lots more stuff compiles now git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24483 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Alpha/AlphaCodeEmitter.cpp | 4 +- lib/Target/Alpha/AlphaISelDAGToDAG.cpp | 151 +++++++++++++++++++------ lib/Target/Alpha/AlphaISelPattern.cpp | 12 +- lib/Target/Alpha/AlphaInstrFormats.td | 4 +- lib/Target/Alpha/AlphaInstrInfo.td | 88 +++++++++++--- 5 files changed, 207 insertions(+), 52 deletions(-) diff --git a/lib/Target/Alpha/AlphaCodeEmitter.cpp b/lib/Target/Alpha/AlphaCodeEmitter.cpp index a0da7aa144e..81026265d0c 100644 --- a/lib/Target/Alpha/AlphaCodeEmitter.cpp +++ b/lib/Target/Alpha/AlphaCodeEmitter.cpp @@ -117,7 +117,9 @@ void AlphaCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { case Alpha::ALTENT: case Alpha::PCLABEL: case Alpha::MEMLABEL: - case Alpha::IDEF: + case Alpha::IDEF_I: + case Alpha::IDEF_F32: + case Alpha::IDEF_F64: break; //skip these } } diff --git a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp index 256ae549898..b920bc4d8cc 100644 --- a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp +++ b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp @@ -38,6 +38,10 @@ namespace { class AlphaDAGToDAGISel : public SelectionDAGISel { AlphaTargetLowering AlphaLowering; + static const int IMM_LOW = -32768; + static const int IMM_HIGH = 32767; + static const int IMM_MULT = 65536; + public: AlphaDAGToDAGISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {} @@ -108,13 +112,42 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) { case ISD::TAILCALL: case ISD::CALL: return SelectCALL(Op); - case ISD::DYNAMIC_STACKALLOC: - assert(0 && "You want these too?"); + case ISD::DYNAMIC_STACKALLOC: { + if (!isa(N->getOperand(2)) || + cast(N->getOperand(2))->getValue() != 0) { + std::cerr << "Cannot allocate stack object with greater alignment than" + << " the stack alignment yet!"; + abort(); + } + SDOperand Chain = Select(N->getOperand(0)); + SDOperand Amt = Select(N->getOperand(1)); + SDOperand Reg = CurDAG->getRegister(Alpha::R30, MVT::i64); + SDOperand Val = CurDAG->getCopyFromReg(Chain, Alpha::R30, MVT::i64); + Chain = Val.getValue(1); + + // Subtract the amount (guaranteed to be a multiple of the stack alignment) + // from the stack pointer, giving us the result pointer. + SDOperand Result = CurDAG->getTargetNode(Alpha::SUBQ, MVT::i64, Val, Amt); + + // Copy this result back into R30. + Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, Reg, Result); + + // Copy this result back out of R30 to make sure we're not using the stack + // space without decrementing the stack pointer. + Result = CurDAG->getCopyFromReg(Chain, Alpha::R30, MVT::i64); + + // Finally, replace the DYNAMIC_STACKALLOC with the copyfromreg. + CodeGenMap[Op.getValue(0)] = Result; + CodeGenMap[Op.getValue(1)] = Result.getValue(1); + return SDOperand(Result.Val, Op.ResNo); + } case ISD::BRCOND: { SDOperand Chain = Select(N->getOperand(0)); SDOperand CC = Select(N->getOperand(1)); - CurDAG->SelectNodeTo(N, Alpha::BNE, MVT::Other, CC, Chain); + MachineBasicBlock *Dest = + cast(N->getOperand(2))->getBasicBlock(); + CurDAG->SelectNodeTo(N, Alpha::BNE, MVT::Other, CC, CurDAG->getBasicBlock(Dest), Chain); return SDOperand(N, 0); } case ISD::LOAD: @@ -148,6 +181,33 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) { getI64Imm(0), Address, Chain); return SDOperand(N, Op.ResNo); } + case ISD::STORE: + case ISD::TRUNCSTORE: { + SDOperand Chain = Select(N->getOperand(0)); + SDOperand Value = Select(N->getOperand(1)); + SDOperand Address = Select(N->getOperand(2)); + + unsigned Opc = Alpha::WTF; + + if (N->getOpcode() == ISD::STORE) { + switch (N->getOperand(1).getValueType()) { + case MVT::i64: Opc = Alpha::STQ; break; + case MVT::f64: Opc = Alpha::STT; break; + case MVT::f32: Opc = Alpha::STS; break; + default: assert(0 && "Bad store!"); + }; + } else { //TRUNCSTORE + switch (cast(N->getOperand(4))->getVT()) { + case MVT::i32: Opc = Alpha::STL; break; + case MVT::i16: Opc = Alpha::STW; break; + case MVT::i8: Opc = Alpha::STB; break; + default: assert(0 && "Bad truncstore!"); + }; + } + CurDAG->SelectNodeTo(N, Opc, MVT::Other, Value, getI64Imm(0), Address, + Chain); + return SDOperand(N, 0); + } case ISD::BR: { CurDAG->SelectNodeTo(N, Alpha::BR_DAG, MVT::Other, N->getOperand(1), @@ -155,32 +215,19 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) { return SDOperand(N, 0); } - case ISD::UNDEF: - if (N->getValueType(0) == MVT::i64) - CurDAG->SelectNodeTo(N, Alpha::IDEF, MVT::i64); -// else if (N->getValueType(0) == MVT::f32) -// CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F4, MVT::f32); -// else -// CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F8, MVT::f64); - return SDOperand(N, 0); case ISD::FrameIndex: { -// int FI = cast(N)->getIndex(); -// CurDAG->SelectNodeTo(N, Alpha::LDA, MVT::i64, -// CurDAG->getTargetFrameIndex(FI, MVT::i32), -// getI32Imm(0)); -// return SDOperand(N, 0); - assert(0 && "Frame?, you are suppose to look through the window, not at the frame!"); + int FI = cast(N)->getIndex(); + CurDAG->SelectNodeTo(N, Alpha::LDA, MVT::i64, + CurDAG->getTargetFrameIndex(FI, MVT::i32), + getI64Imm(0)); + return SDOperand(N, 0); } case ISD::ConstantPool: { -// Constant *C = cast(N)->get(); -// SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i32); -// if (PICEnabled) -// Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(),CPI); -// else -// Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, CPI); -// CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, CPI); -// return SDOperand(N, 0); - assert(0 && "Constants are overrated"); + Constant *C = cast(N)->get(); + SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i64); + Tmp = CurDAG->getTargetNode(Alpha::LDAHr, MVT::i64, CPI, getGlobalBaseReg()); + CurDAG->SelectNodeTo(N, Alpha::LDAr, MVT::i64, CPI, Tmp); + return SDOperand(N, 0); } case ISD::GlobalAddress: { GlobalValue *GV = cast(N)->getGlobal(); @@ -219,15 +266,45 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) { CurDAG->SelectNodeTo(N, Alpha::RETDAG, MVT::Other, Chain); return SDOperand(N, 0); } - - - + case ISD::Constant: { + int64_t val = (int64_t)cast(N)->getValue(); + if (val > (int64_t)IMM_HIGH +(int64_t)IMM_HIGH* (int64_t)IMM_MULT || + val < (int64_t)IMM_LOW + (int64_t)IMM_LOW * (int64_t)IMM_MULT) { + MachineConstantPool *CP = BB->getParent()->getConstantPool(); + ConstantUInt *C = + ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val); + SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i64); + Tmp = CurDAG->getTargetNode(Alpha::LDAHr, MVT::i64, CPI, getGlobalBaseReg()); + CurDAG->SelectNodeTo(N, Alpha::LDAr, MVT::i64, CPI, Tmp); + return SDOperand(N, 0); + } + } + case ISD::ConstantFP: + if (ConstantFPSDNode *CN = dyn_cast(N)) { + bool isDouble = N->getValueType(0) == MVT::f64; + MVT::ValueType T = isDouble ? MVT::f64 : MVT::f32; + if (CN->isExactlyValue(+0.0)) { + CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYST : Alpha::CPYSS, T, + CurDAG->getRegister(Alpha::F31, T), + CurDAG->getRegister(Alpha::F31, T)); + return SDOperand(N, 0); + } else if ( CN->isExactlyValue(-0.0)) { + CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYSNT : Alpha::CPYSNS, T, + CurDAG->getRegister(Alpha::F31, T), + CurDAG->getRegister(Alpha::F31, T)); + return SDOperand(N, 0); + } else { + abort(); + } + } } return SelectCode(Op); } SDOperand AlphaDAGToDAGISel::SelectCALL(SDOperand Op) { + //TODO: add flag stuff to prevent nondeturministic breakage! + SDNode *N = Op.Val; SDOperand Chain = Select(N->getOperand(0)); SDOperand Addr = Select(N->getOperand(1)); @@ -251,10 +328,12 @@ SDOperand AlphaDAGToDAGISel::SelectCALL(SDOperand Op) { for (int i = 0; i < std::min(6, count); ++i) { if (MVT::isInteger(TypeOperands[i])) { Chain = CurDAG->getCopyToReg(Chain, args_int[i], CallOperands[i]); - } else { - assert(0 && "No FP support yet"); - } + } else if (TypeOperands[i] == MVT::f64 || TypeOperands[i] == MVT::f64) { + Chain = CurDAG->getCopyToReg(Chain, args_float[i], CallOperands[i]); + } else + assert(0 && "Unknown operand"); } + assert(CallOperands.size() <= 6 && "Too big a call"); Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, Addr); @@ -271,6 +350,14 @@ SDOperand AlphaDAGToDAGISel::SelectCALL(SDOperand Op) { Chain = CurDAG->getCopyFromReg(Chain, Alpha::R0, MVT::i64).getValue(1); CallResults.push_back(Chain.getValue(0)); break; + case MVT::f32: + Chain = CurDAG->getCopyFromReg(Chain, Alpha::F0, MVT::f32).getValue(1); + CallResults.push_back(Chain.getValue(0)); + break; + case MVT::f64: + Chain = CurDAG->getCopyFromReg(Chain, Alpha::F0, MVT::f64).getValue(1); + CallResults.push_back(Chain.getValue(0)); + break; } CallResults.push_back(Chain); diff --git a/lib/Target/Alpha/AlphaISelPattern.cpp b/lib/Target/Alpha/AlphaISelPattern.cpp index 1e6bab6c3a9..e9e52372174 100644 --- a/lib/Target/Alpha/AlphaISelPattern.cpp +++ b/lib/Target/Alpha/AlphaISelPattern.cpp @@ -592,7 +592,9 @@ unsigned AlphaISel::SelectExpr(SDOperand N) { return Result; } case ISD::UNDEF: { - BuildMI(BB, Alpha::IDEF, 0, Result); + Opc = isFP ? (DestType == MVT::f32 ? Alpha::IDEF_F32 : Alpha::IDEF_F64) + : Alpha::IDEF_I; + BuildMI(BB, Opc, 0, Result); return Result; } @@ -1610,7 +1612,13 @@ void AlphaISel::Select(SDOperand N) { case ISD::ImplicitDef: ++count_ins; Select(N.getOperand(0)); - BuildMI(BB, Alpha::IDEF, 0, + switch(N.getValueType()) { + case MVT::f32: Opc = Alpha::IDEF_F32; break; + case MVT::f64: Opc = Alpha::IDEF_F64; break; + case MVT::i64: Opc = Alpha::IDEF_I; break; + default: assert(0 && "should have been legalized"); + }; + BuildMI(BB, Opc, 0, cast(N.getOperand(1))->getReg()); return; diff --git a/lib/Target/Alpha/AlphaInstrFormats.td b/lib/Target/Alpha/AlphaInstrFormats.td index 7180409ef51..1f446072758 100644 --- a/lib/Target/Alpha/AlphaInstrFormats.td +++ b/lib/Target/Alpha/AlphaInstrFormats.td @@ -218,5 +218,7 @@ class PALForm opcode, dag OL, string asmstr> : InstAlpha : InstAlpha<0, OL, nm> { +class PseudoInstAlpha pattern> : InstAlpha<0, OL, nm> { + let Pattern = pattern; + } diff --git a/lib/Target/Alpha/AlphaInstrInfo.td b/lib/Target/Alpha/AlphaInstrInfo.td index e1ae7d13d5c..aea28619947 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.td +++ b/lib/Target/Alpha/AlphaInstrInfo.td @@ -74,15 +74,22 @@ def sub8 : PatFrag<(ops node:$op1, node:$op2), // //#define GP $29 // //#define SP $30 -def PHI : PseudoInstAlpha<(ops variable_ops), "#phi">; -def IDEF : PseudoInstAlpha<(ops GPRC:$RA), "#idef $RA">; -def WTF : PseudoInstAlpha<(ops variable_ops), "#wtf">; -def ADJUSTSTACKUP : PseudoInstAlpha<(ops variable_ops), "ADJUP">; -def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops variable_ops), "ADJDOWN">; -def ALTENT : PseudoInstAlpha<(ops s64imm:$TARGET), "$TARGET:\n">; -def PCLABEL : PseudoInstAlpha<(ops s64imm:$num), "PCMARKER_$num:\n">; +def PHI : PseudoInstAlpha<(ops variable_ops), "#phi", []>; + +def IDEF_I : PseudoInstAlpha<(ops GPRC:$RA), "#idef $RA", + [(set GPRC:$RA, (undef))]>; +def IDEF_F32 : PseudoInstAlpha<(ops F4RC:$RA), "#idef $RA", + [(set F4RC:$RA, (undef))]>; +def IDEF_F64 : PseudoInstAlpha<(ops F8RC:$RA), "#idef $RA", + [(set F8RC:$RA, (undef))]>; + +def WTF : PseudoInstAlpha<(ops variable_ops), "#wtf", []>; +def ADJUSTSTACKUP : PseudoInstAlpha<(ops variable_ops), "ADJUP", []>; +def ADJUSTSTACKDOWN : PseudoInstAlpha<(ops variable_ops), "ADJDOWN", []>; +def ALTENT : PseudoInstAlpha<(ops s64imm:$TARGET), "$TARGET:\n", []>; +def PCLABEL : PseudoInstAlpha<(ops s64imm:$num), "PCMARKER_$num:\n",[]>; def MEMLABEL : PseudoInstAlpha<(ops s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m), - "LSMARKER$$$i$$$j$$$k$$$m:\n">; + "LSMARKER$$$i$$$j$$$k$$$m:\n",[]>; //***************** //These are shortcuts, the assembler expands them @@ -97,19 +104,19 @@ def MEMLABEL : PseudoInstAlpha<(ops s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m), let isTwoAddress = 1 in { //Conditional move of an int based on a FP CC def CMOVEQ_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND), - "fbne $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n">; + "fbne $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>; def CMOVEQi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, F8RC:$RCOND), - "fbne $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n">; + "fbne $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n", []>; def CMOVNE_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND), - "fbeq $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n">; + "fbeq $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>; def CMOVNEi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, F8RC:$RCOND), - "fbeq $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n">; + "fbeq $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n", []>; //Conditional move of an FP based on a Int CC def FCMOVEQ_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND), - "bne $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n">; + "bne $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>; def FCMOVNE_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND), - "beq $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n">; + "beq $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>; } //*********************** @@ -330,9 +337,9 @@ def CMPULE : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC", def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC", [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))]>; def CMPULT : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC", - [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))]>; + [(set GPRC:$RC, (setult GPRC:$RA, GPRC:$RB))]>; def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC", - [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))]>; + [(set GPRC:$RC, (setult GPRC:$RA, immUExt8:$L))]>; //Patterns for unsupported int comparisons def : Pat<(setueq GPRC:$X, GPRC:$Y), (CMPEQ GPRC:$X, GPRC:$Y)>; @@ -588,7 +595,56 @@ def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC", //def AMASKi : OFormL<0x11, 0x61, "AMASK $RA,$L,$RC", []>; //Architecture mask +//Constant handling +def immConst2Part : PatLeaf<(imm), [{ + // immZAP predicate - True if the immediate fits is suitable for use in a + // ZAP instruction + int64_t val = (int64_t)N->getValue(); + return (val <= (int64_t)IMM_HIGH +(int64_t)IMM_HIGH* (int64_t)IMM_MULT & + val >= (int64_t)IMM_LOW + (int64_t)IMM_LOW * (int64_t)IMM_MULT); +}]>; + +//TODO: factor this out +def LL16 : SDNodeXFormgetValue(); + int64_t y = l / IMM_MULT; + if (l % IMM_MULT > IMM_HIGH) + ++y; + return getI64Imm(l - y * IMM_MULT); +}]>; +//TODO: factor this out +def LH16 : SDNodeXFormgetValue(); + int64_t y = l / IMM_MULT; + if (l % IMM_MULT > IMM_HIGH) + ++y; + return getI64Imm(y); +}]>; + +def : Pat<(i64 immConst2Part:$imm), + (LDA (LL16 immConst2Part:$imm), (LDAH (LH16 immConst2Part:$imm), R31))>; def : Pat<(i64 immSExt16:$imm), (LDA immSExt16:$imm, R31)>; + +//TODO: I want to just define these like this! +//def : Pat<(i64 0), +// (R31)>; +//def : Pat<(f64 0.0), +// (F31)>; +//def : Pat<(f64 -0.0), +// (CPYSNT F31, F31)>; +//def : Pat<(f32 0.0), +// (F31)>; +//def : Pat<(f32 -0.0), +// (CPYSNS F31, F31)>; + +//Misc Patterns: + +def : Pat<(sext_inreg GPRC:$RB, i32), + (ADDLi GPRC:$RB, 0)>; + +def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2), + (CMOVEQ GPRC:$src1, GPRC:$src2, GPRC:$which)>; //may be CMOVNE + -- 2.34.1