diff --git a/lib/Target/PIC16/PIC16.h b/lib/Target/PIC16/PIC16.h index f9f51ab9cce..e37ef4f2090 100644 --- a/lib/Target/PIC16/PIC16.h +++ b/lib/Target/PIC16/PIC16.h @@ -31,7 +31,11 @@ namespace PIC16CC { LT, LE, GT, - GE + GE, + ULT, + UGT, + ULE, + UGE }; } @@ -41,12 +45,32 @@ namespace PIC16CC { case PIC16CC::NE: return "ne"; case PIC16CC::EQ: return "eq"; case PIC16CC::LT: return "lt"; + case PIC16CC::ULT: return "lt"; case PIC16CC::LE: return "le"; case PIC16CC::GT: return "gt"; + case PIC16CC::UGT: return "gt"; case PIC16CC::GE: return "ge"; } } + inline static bool isSignedComparison(PIC16CC::CondCodes CC) { + switch (CC) { + default: assert(0 && "Unknown condition code"); + case PIC16CC::NE: + case PIC16CC::EQ: + case PIC16CC::LT: + case PIC16CC::LE: + case PIC16CC::GE: + case PIC16CC::GT: + return true; + case PIC16CC::ULT: + case PIC16CC::UGT: + case PIC16CC::ULE: + case PIC16CC::UGE: + return false; // condition codes for unsigned comparison. + } + } + FunctionPass *createPIC16ISelDag(PIC16TargetMachine &TM); FunctionPass *createPIC16CodePrinterPass(raw_ostream &OS, diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp index 1f1f9e477ca..72f073adcb9 100644 --- a/lib/Target/PIC16/PIC16ISelLowering.cpp +++ b/lib/Target/PIC16/PIC16ISelLowering.cpp @@ -41,21 +41,27 @@ PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM) setShiftAmountFlavor(Extend); // SRA library call names - setPIC16LibCallName(PIC16ISD::SRA_I8, "__intrinsics.sra.i8"); - setPIC16LibCallName(PIC16ISD::SRA_I16, "__intrinsics.sra.i16"); - setPIC16LibCallName(PIC16ISD::SRA_I32, "__intrinsics.sra.i32"); + setPIC16LibcallName(PIC16ISD::SRA_I8, "__intrinsics.sra.i8"); + setLibcallName(RTLIB::SRA_I16, "__intrinsics.sra.i16"); + setLibcallName(RTLIB::SRA_I32, "__intrinsics.sra.i32"); - // SLL library call names - setPIC16LibCallName(PIC16ISD::SLL_I8, "__intrinsics.sll.i8"); - setPIC16LibCallName(PIC16ISD::SLL_I16, "__intrinsics.sll.i16"); - setPIC16LibCallName(PIC16ISD::SLL_I32, "__intrinsics.sll.i32"); + // SHL library call names + setPIC16LibcallName(PIC16ISD::SLL_I8, "__intrinsics.sll.i8"); + setLibcallName(RTLIB::SHL_I16, "__intrinsics.sll.i16"); + setLibcallName(RTLIB::SHL_I32, "__intrinsics.sll.i32"); // SRL library call names - setPIC16LibCallName(PIC16ISD::SRL_I8, "__intrinsics.srl.i8"); - setPIC16LibCallName(PIC16ISD::SRL_I16, "__intrinsics.srl.i16"); - setPIC16LibCallName(PIC16ISD::SRL_I32, "__intrinsics.srl.i32"); + setPIC16LibcallName(PIC16ISD::SRL_I8, "__intrinsics.srl.i8"); + setLibcallName(RTLIB::SRL_I16, "__intrinsics.srl.i16"); + setLibcallName(RTLIB::SRL_I32, "__intrinsics.srl.i32"); + + // MUL Library call names + setPIC16LibcallName(PIC16ISD::MUL_I8, "__intrinsics.mul.i8"); + setLibcallName(RTLIB::MUL_I16, "__intrinsics.mul.i16"); + setLibcallName(RTLIB::MUL_I32, "__intrinsics.mul.i32"); setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); + setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom); setOperationAction(ISD::LOAD, MVT::i8, Legal); setOperationAction(ISD::LOAD, MVT::i16, Custom); @@ -69,7 +75,7 @@ PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM) setOperationAction(ISD::ADDC, MVT::i8, Custom); setOperationAction(ISD::SUBE, MVT::i8, Custom); setOperationAction(ISD::SUBC, MVT::i8, Custom); - setOperationAction(ISD::ADD, MVT::i8, Legal); + setOperationAction(ISD::ADD, MVT::i8, Custom); setOperationAction(ISD::ADD, MVT::i16, Custom); setOperationAction(ISD::OR, MVT::i8, Custom); @@ -80,16 +86,44 @@ PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM) setOperationAction(ISD::CALL, MVT::i16, Custom); setOperationAction(ISD::RET, MVT::Other, Custom); - setOperationAction(ISD::SRA, MVT::i8, Custom); - setOperationAction(ISD::SRA, MVT::i16, Custom); - setOperationAction(ISD::SRA, MVT::i32, Custom); + setOperationAction(ISD::MUL, MVT::i8, Custom); + setOperationAction(ISD::MUL, MVT::i16, Expand); + setOperationAction(ISD::MUL, MVT::i32, Expand); + + setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand); + setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand); + setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); + setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand); + setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand); + setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); + setOperationAction(ISD::MULHU, MVT::i8, Expand); + setOperationAction(ISD::MULHU, MVT::i16, Expand); + setOperationAction(ISD::MULHU, MVT::i32, Expand); + setOperationAction(ISD::MULHS, MVT::i8, Expand); + setOperationAction(ISD::MULHS, MVT::i16, Expand); + setOperationAction(ISD::MULHS, MVT::i32, Expand); + + setOperationAction(ISD::SRA, MVT::i8, Custom); + setOperationAction(ISD::SRA, MVT::i16, Expand); + setOperationAction(ISD::SRA, MVT::i32, Expand); + setOperationAction(ISD::SHL, MVT::i8, Custom); + setOperationAction(ISD::SHL, MVT::i16, Expand); + setOperationAction(ISD::SHL, MVT::i32, Expand); + setOperationAction(ISD::SRL, MVT::i8, Custom); + setOperationAction(ISD::SRL, MVT::i16, Expand); + setOperationAction(ISD::SRL, MVT::i32, Expand); + + // PIC16 does not support shift parts + setOperationAction(ISD::SRA_PARTS, MVT::i8, Expand); + setOperationAction(ISD::SRA_PARTS, MVT::i16, Expand); + setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); + setOperationAction(ISD::SHL_PARTS, MVT::i8, Expand); + setOperationAction(ISD::SHL_PARTS, MVT::i16, Expand); + setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); + setOperationAction(ISD::SRL_PARTS, MVT::i8, Expand); + setOperationAction(ISD::SRL_PARTS, MVT::i16, Expand); + setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); - setOperationAction(ISD::SHL, MVT::i8, Custom); - setOperationAction(ISD::SHL, MVT::i16, Custom); - setOperationAction(ISD::SHL, MVT::i32, Custom); - setOperationAction(ISD::SRL, MVT::i8, Custom); - setOperationAction(ISD::SRL, MVT::i16, Custom); - setOperationAction(ISD::SRL, MVT::i32, Custom); // PIC16 does not have a SETCC, expand it to SELECT_CC. setOperationAction(ISD::SETCC, MVT::i8, Expand); @@ -124,18 +158,18 @@ MVT PIC16TargetLowering::getSetCCResultType(MVT ValType) const { void -PIC16TargetLowering::setPIC16LibCallName(PIC16ISD::PIC16LibCall Call, +PIC16TargetLowering::setPIC16LibcallName(PIC16ISD::PIC16Libcall Call, const char *Name) { - PIC16LibCallNames[Call] = Name; + PIC16LibcallNames[Call] = Name; } const char * -PIC16TargetLowering::getPIC16LibCallName(PIC16ISD::PIC16LibCall Call) { - return PIC16LibCallNames[Call]; +PIC16TargetLowering::getPIC16LibcallName(PIC16ISD::PIC16Libcall Call) { + return PIC16LibcallNames[Call]; } SDValue -PIC16TargetLowering::MakePIC16LibCall(PIC16ISD::PIC16LibCall Call, +PIC16TargetLowering::MakePIC16Libcall(PIC16ISD::PIC16Libcall Call, MVT RetVT, const SDValue *Ops, unsigned NumOps, bool isSigned, SelectionDAG &DAG) { @@ -151,7 +185,7 @@ PIC16TargetLowering::MakePIC16LibCall(PIC16ISD::PIC16LibCall Call, Entry.isZExt = !isSigned; Args.push_back(Entry); } - SDValue Callee = DAG.getExternalSymbol(getPIC16LibCallName(Call), MVT::i8); + SDValue Callee = DAG.getExternalSymbol(getPIC16LibcallName(Call), MVT::i8); const Type *RetTy = RetVT.getTypeForMVT(); std::pair CallInfo = @@ -247,15 +281,6 @@ void PIC16TargetLowering::ReplaceNodeResults(SDNode *N, case ISD::ADD: // Results.push_back(ExpandAdd(N, DAG)); return; - case ISD::SHL: - case ISD::SRL: - case ISD::SRA: - { - SDValue Res = ExpandShift(N, DAG); - if (Res.getNode()) - Results.push_back(Res); - return; - } case ISD::FrameIndex: Results.push_back(ExpandFrameIndex(N, DAG)); return; @@ -708,94 +733,64 @@ SDValue PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) { return DAG.getNode(ISD::MERGE_VALUES, Tys, BP, Chain); } -SDValue PIC16TargetLowering::ExpandShift(SDNode *N, SelectionDAG &DAG) { +SDValue PIC16TargetLowering::LowerShift(SDValue Op, SelectionDAG &DAG) { + // We should have handled larger operands in type legalizer itself. + assert (Op.getValueType() == MVT::i8 && "illegal shift to lower"); + + SDNode *N = Op.getNode(); SDValue Value = N->getOperand(0); SDValue Amt = N->getOperand(1); - SDValue BCF, BCFInput; - SDValue ShfCom; // Shift Component - Lo component should be shifted - SDValue RotCom; // Rotate Component- Hi component should be rotated - - PIC16ISD::PIC16LibCall CallCode; - - // Shift amount should be MVT::i8 only. If it is more than that then - // extract MVT::i8 from that - if (Amt.getValueType() == MVT::i8) { - // Do Nothing - This is ok - } else if (Amt.getValueType() == MVT::i16) { - SDValue Lo, Hi; - GetExpandedParts(Amt, DAG, Lo, Hi); - Amt = Lo; // Take the Lo part as amount - - } else if (Amt.getValueType() == MVT::i32) { - SDValue Lo, Hi; - // Get MVT::i16 Components - GetExpandedParts(Amt, DAG, Lo, Hi); - // Get MVT::i8 Components - GetExpandedParts(Lo, DAG, Lo, Hi); - Amt = Lo; - - } else { - assert ( 0 && "Invalid Shift amount"); - } - - // Shift library call will always have two operands - if (N->getValueType(0) == MVT::i8) { - switch (N->getOpcode()) { - case ISD::SRA: - CallCode = PIC16ISD::SRA_I8; - break; - case ISD::SHL: - CallCode = PIC16ISD::SLL_I8; - break; - case ISD::SRL: - CallCode = PIC16ISD::SRL_I8; - break; - default: - assert ( 0 && "This shift is not implemented yet."); - return SDValue(); - } - } else if (N->getValueType(0) == MVT::i16) { - switch (N->getOpcode()) { - case ISD::SRA: - CallCode = PIC16ISD::SRA_I16; - break; - case ISD::SHL: - CallCode = PIC16ISD::SLL_I16; - break; - case ISD::SRL: - CallCode = PIC16ISD::SRL_I16; - break; - default: - assert ( 0 && "This shift is not implemented yet."); - return SDValue(); - } - } else if (N->getValueType(0) == MVT::i32) { - switch (N->getOpcode()) { - case ISD::SRA: - CallCode = PIC16ISD::SRA_I32; - break; - case ISD::SHL: - CallCode = PIC16ISD::SLL_I32; - break; - case ISD::SRL: - CallCode = PIC16ISD::SRL_I32; - break; - default: - assert ( 0 && "This shift is not implemented yet."); - return SDValue(); - } - } else { - //assert ( 0 && "Shift for this value type not yet implemented."); + PIC16ISD::PIC16Libcall CallCode; + switch (N->getOpcode()) { + case ISD::SRA: + CallCode = PIC16ISD::SRA_I8; + break; + case ISD::SHL: + CallCode = PIC16ISD::SLL_I8; + break; + case ISD::SRL: + CallCode = PIC16ISD::SRL_I8; + break; + default: + assert ( 0 && "This shift is not implemented yet."); return SDValue(); } - SmallVector Ops(2); Ops[0] = Value; Ops[1] = Amt; - SDValue Call = MakePIC16LibCall(CallCode, N->getValueType(0), &Ops[0], 2, true, DAG); + SDValue Call = MakePIC16Libcall(CallCode, N->getValueType(0), &Ops[0], 2, true, DAG); return Call; } +void PIC16TargetLowering::LowerOperationWrapper(SDValue Op, + SmallVectorImpl&Results, + SelectionDAG &DAG) { + SDValue Res; + unsigned i; + switch (Op.getOpcode()) { + case ISD::FORMAL_ARGUMENTS: + Res = LowerFORMAL_ARGUMENTS(Op, DAG); break; + case ISD::LOAD: + Res = ExpandLoad(Op.getNode(), DAG); break; + case ISD::CALL: + Res = LowerCALL(Op, DAG); break; + default: { + // All other operations are handled in LowerOperation. + Res = LowerOperation(Op, DAG); + if (Res.getNode()) + Results.push_back(Res); + + return; + } + } + SDNode *N = Res.getNode(); + unsigned NumValues = N->getNumValues(); + for (i=0; i< NumValues ; i++) { + Results.push_back(SDValue(N, i)); + } + +} + SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { case ISD::FORMAL_ARGUMENTS: @@ -815,14 +810,12 @@ SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::SHL: case ISD::SRA: case ISD::SRL: - return ExpandShift(Op.getNode(), DAG); + return LowerShift(Op, DAG); case ISD::OR: case ISD::AND: case ISD::XOR: return LowerBinOp(Op, DAG); case ISD::CALL: - // This is called only from LegalizeDAG. No call is made to - // legalize CALL node from LegalizeType. return LowerCALL(Op, DAG); case ISD::RET: return LowerRET(Op, DAG); @@ -1142,6 +1135,9 @@ SDValue PIC16TargetLowering:: LowerADD(SDValue Op, SelectionDAG &DAG) { else return DAG.getNode(Op.getOpcode(), Tys, Op.getOperand(MemOp ^ 1), NewVal); } + else if (Op.getOpcode() == ISD::ADD) { + return Op; + } else { return SDValue(); } @@ -1219,10 +1215,10 @@ static PIC16CC::CondCodes IntCCToPIC16CC(ISD::CondCode CC) { case ISD::SETGE: return PIC16CC::GE; case ISD::SETLT: return PIC16CC::LT; case ISD::SETLE: return PIC16CC::LE; - case ISD::SETULT: return PIC16CC::LT; + case ISD::SETULT: return PIC16CC::ULT; case ISD::SETULE: return PIC16CC::LE; case ISD::SETUGE: return PIC16CC::GE; - case ISD::SETUGT: return PIC16CC::GT; + case ISD::SETUGT: return PIC16CC::UGT; } } @@ -1268,18 +1264,36 @@ SDValue PIC16TargetLowering::getPIC16Cmp(SDValue LHS, SDValue RHS, case PIC16CC::GT: CondCode = PIC16CC::LT; break; + case PIC16CC::ULT: + CondCode = PIC16CC::UGT; + break; + case PIC16CC::UGT: + CondCode = PIC16CC::ULT; + break; case PIC16CC::GE: CondCode = PIC16CC::LE; break; case PIC16CC::LE: CondCode = PIC16CC::GE; break; + case PIC16CC::ULE: + CondCode = PIC16CC::UGE; + break; + case PIC16CC::UGE: + CondCode = PIC16CC::ULE; + break; } } PIC16CC = DAG.getConstant(CondCode, MVT::i8); SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Flag); + // These are signed comparisons. + SDValue Mask = DAG.getConstant(128, MVT::i8); + if (isSignedComparison(CondCode)) { + LHS = DAG.getNode (ISD::XOR, MVT::i8, LHS, Mask); + RHS = DAG.getNode (ISD::XOR, MVT::i8, RHS, Mask); + } // We can use a subtract operation to set the condition codes. But // we need to put one operand in memory if required. // Nothing to do if the first operand is already a direct load and it has diff --git a/lib/Target/PIC16/PIC16ISelLowering.h b/lib/Target/PIC16/PIC16ISelLowering.h index 503b72c42c4..73cebebc3b7 100644 --- a/lib/Target/PIC16/PIC16ISelLowering.h +++ b/lib/Target/PIC16/PIC16ISelLowering.h @@ -52,16 +52,11 @@ namespace llvm { RAM_SPACE = 0, // RAM address space ROM_SPACE = 1 // ROM address space number is 1 }; - enum PIC16LibCall { + enum PIC16Libcall { + MUL_I8, SRA_I8, SLL_I8, SRL_I8, - SRA_I16, - SLL_I16, - SRL_I16, - SRA_I32, - SLL_I32, - SRL_I32, PIC16UnknownCall }; } @@ -79,8 +74,8 @@ namespace llvm { virtual const char *getTargetNodeName(unsigned Opcode) const; /// getSetCCResultType - Return the ISD::SETCC ValueType virtual MVT getSetCCResultType(MVT ValType) const; - SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG); + SDValue LowerShift(SDValue Op, SelectionDAG &DAG); SDValue LowerADD(SDValue Op, SelectionDAG &DAG); SDValue LowerSUB(SDValue Op, SelectionDAG &DAG); SDValue LowerBinOp(SDValue Op, SelectionDAG &DAG); @@ -98,15 +93,19 @@ namespace llvm { MachineBasicBlock *MBB); + virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl &Results, SelectionDAG &DAG); + virtual void LowerOperationWrapper(SDValue Op, + SmallVectorImpl &Results, + SelectionDAG &DAG); + SDValue ExpandStore(SDNode *N, SelectionDAG &DAG); SDValue ExpandLoad(SDNode *N, SelectionDAG &DAG); //SDValue ExpandAdd(SDNode *N, SelectionDAG &DAG); SDValue ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG); SDValue ExpandExternalSymbol(SDNode *N, SelectionDAG &DAG); - SDValue ExpandShift(SDNode *N, SelectionDAG &DAG); SDValue ExpandFrameIndex(SDNode *N, SelectionDAG &DAG); SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; @@ -159,15 +158,15 @@ namespace llvm { // Extending the LIB Call framework of LLVM - // To hold the names of PIC16LibCalls - const char *PIC16LibCallNames[PIC16ISD::PIC16UnknownCall]; + // To hold the names of PIC16Libcalls + const char *PIC16LibcallNames[PIC16ISD::PIC16UnknownCall]; // To set and retrieve the lib call names - void setPIC16LibCallName(PIC16ISD::PIC16LibCall Call, const char *Name); - const char *getPIC16LibCallName(PIC16ISD::PIC16LibCall Call); + void setPIC16LibcallName(PIC16ISD::PIC16Libcall Call, const char *Name); + const char *getPIC16LibcallName(PIC16ISD::PIC16Libcall Call); - // Make PIC16 LibCall - SDValue MakePIC16LibCall(PIC16ISD::PIC16LibCall Call, MVT RetVT, + // Make PIC16 Libcall + SDValue MakePIC16Libcall(PIC16ISD::PIC16Libcall Call, MVT RetVT, const SDValue *Ops, unsigned NumOps, bool isSigned, SelectionDAG &DAG); diff --git a/lib/Target/PIC16/PIC16InstrInfo.cpp b/lib/Target/PIC16/PIC16InstrInfo.cpp index 47ac6d31703..5fe5dacee8c 100644 --- a/lib/Target/PIC16/PIC16InstrInfo.cpp +++ b/lib/Target/PIC16/PIC16InstrInfo.cpp @@ -138,9 +138,8 @@ bool PIC16InstrInfo::copyRegToReg (MachineBasicBlock &MBB, } bool PIC16InstrInfo::isMoveInstr(const MachineInstr &MI, - unsigned &SrcReg, unsigned &DestReg, - unsigned &SrcSubIdx, unsigned &DstSubIdx) const { - SrcSubIdx = DstSubIdx = 0; // No sub-registers. + unsigned &SrcReg, + unsigned &DestReg) const { if (MI.getOpcode() == PIC16::copy_fsr || MI.getOpcode() == PIC16::copy_w) { diff --git a/lib/Target/PIC16/PIC16InstrInfo.h b/lib/Target/PIC16/PIC16InstrInfo.h index 04927b7f344..98475dbaa3d 100644 --- a/lib/Target/PIC16/PIC16InstrInfo.h +++ b/lib/Target/PIC16/PIC16InstrInfo.h @@ -61,8 +61,8 @@ public: const TargetRegisterClass *DestRC, const TargetRegisterClass *SrcRC) const; virtual bool isMoveInstr(const MachineInstr &MI, - unsigned &SrcReg, unsigned &DstReg, - unsigned &SrcSubIdx, unsigned &DstSubIdx) const; + unsigned &SrcReg, + unsigned &DestReg) const; };