From 60ab61fcfc36d3ce2d07596a2dfad142c287c7e0 Mon Sep 17 00:00:00 2001 From: Andrew Lenharth Date: Fri, 30 Dec 2005 02:30:02 +0000 Subject: [PATCH] improve constant loading. Still sucks, but oh well llvm-svn: 25047 --- llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp | 38 +++++++++++++-------- llvm/lib/Target/Alpha/AlphaInstrInfo.td | 32 +++++++++++++++-- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp b/llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp index e51db4127de1..dd29e912529b 100644 --- a/llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp +++ b/llvm/lib/Target/Alpha/AlphaISelDAGToDAG.cpp @@ -38,13 +38,14 @@ 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; + static const int64_t IMM_LOW = -32768; + static const int64_t IMM_HIGH = 32767; + static const int64_t IMM_MULT = 65536; public: AlphaDAGToDAGISel(TargetMachine &TM) - : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {} + : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) + {} /// getI64Imm - Return a target constant with the specified value, of type /// i64. @@ -240,17 +241,24 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) { return CurDAG->SelectNodeTo(N, Alpha::RETDAG, MVT::Other, Chain, InFlag); } 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()); - return CurDAG->SelectNodeTo(N, Alpha::LDQr, MVT::i64, CPI, Tmp); - } - break; + uint64_t uval = cast(N)->getValue(); + int64_t val = (int64_t)uval; + int32_t val32 = (int32_t)val; + if (val <= IMM_HIGH + IMM_HIGH * IMM_MULT && + val >= IMM_LOW + IMM_LOW * IMM_MULT) + break; //(LDAH (LDA)) + if ((uval >> 32) == 0 && //empty upper bits + val32 <= IMM_HIGH + IMM_HIGH * IMM_MULT && + val32 >= IMM_LOW + IMM_LOW * IMM_MULT) + break; //(zext (LDAH (LDA))) + //Else use the constant pool + MachineConstantPool *CP = BB->getParent()->getConstantPool(); + ConstantUInt *C = + ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , uval); + SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i64); + Tmp = CurDAG->getTargetNode(Alpha::LDAHr, MVT::i64, CPI, getGlobalBaseReg()); + return CurDAG->SelectNodeTo(N, Alpha::LDQr, MVT::i64, MVT::Other, + CPI, Tmp, CurDAG->getEntryNode()); } case ISD::ConstantFP: if (ConstantFPSDNode *CN = dyn_cast(N)) { diff --git a/llvm/lib/Target/Alpha/AlphaInstrInfo.td b/llvm/lib/Target/Alpha/AlphaInstrInfo.td index 13aab77c8235..20a0350d3a90 100644 --- a/llvm/lib/Target/Alpha/AlphaInstrInfo.td +++ b/llvm/lib/Target/Alpha/AlphaInstrInfo.td @@ -57,6 +57,20 @@ def immSExt16 : PatLeaf<(imm), [{ return (int64_t)N->getValue() == (int16_t)N->getValue(); }]>; +def SExtInt : SDNodeXFormgetValue() << 32) >> 32); +}]>; + +def immSExt16int : PatLeaf<(imm), [{ + // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended + // field. Used by instructions like 'lda'. + int64_t val = (int64_t)N->getValue(); + uint32_t uval32 = (uint32_t)val; + int32_t val32 = (int32_t)val; + return (int64_t)uval32 == val && val32 == (int16_t)val32; +}], SExtInt>; + + def iZAPX : SDNodeXFormgetValue(); @@ -778,12 +792,19 @@ def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC", //Constant handling def immConst2Part : PatLeaf<(imm), [{ - // immZAP predicate - True if the immediate fits is suitable for use in a - // ZAP instruction + //true if imm fits in a LDAH LDA pair 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); }]>; +def immConst2PartInt : PatLeaf<(imm), [{ + //true if imm fits in a LDAH LDA pair with zeroext + uint64_t uval = N->getValue(); + int32_t val32 = (int32_t)uval; + return ((uval >> 32) == 0 && //empty upper bits + val32 <= IMM_HIGH + IMM_HIGH * IMM_MULT && + val32 >= IMM_LOW + IMM_LOW * IMM_MULT); +}], SExtInt>; //TODO: factor this out def LL16 : SDNodeXForm; +def : Pat<(i64 immSExt16int:$imm), + (ZAPNOTi (LDA (SExtInt immSExt16int:$imm), R31), 15)>; +def : Pat<(i64 immConst2PartInt:$imm), + (ZAPNOTi (LDA (LL16 (SExtInt immConst2PartInt:$imm)), + (LDAH (LH16 (SExtInt immConst2PartInt:$imm)), R31)), 15)>; + + //TODO: I want to just define these like this! //def : Pat<(i64 0), // (R31)>;