Changes in directory llvm/lib/Target/X86:
X86ISelDAGToDAG.cpp updated: 1.16 -> 1.17 X86ISelLowering.cpp updated: 1.11 -> 1.12 X86ISelLowering.h updated: 1.5 -> 1.6 X86InstrInfo.td updated: 1.175 -> 1.176 X86RegisterInfo.td updated: 1.25 -> 1.26 --- Log message: * Added lowering hook for external weak global address. It inserts a load for Darwin. * Added lowering hook for ISD::RET. It inserts CopyToRegs for the return value (or store / fld / copy to ST(0) for floating point value). This eliminate the need to write C++ code to handle RET with variable number of operands. --- Diffs of the changes: (+135 -22) X86ISelDAGToDAG.cpp | 17 ----------- X86ISelLowering.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ X86ISelLowering.h | 17 +++++++++++ X86InstrInfo.td | 37 +++++++++++++++++++++--- X86RegisterInfo.td | 7 +++- 5 files changed, 135 insertions(+), 22 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.16 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.17 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.16 Mon Dec 19 16:36:02 2005 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Dec 20 20:39:21 2005 @@ -173,22 +173,7 @@ case ISD::GlobalAddress: if (AM.GV == 0) { - GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal(); - // For Darwin, external and weak symbols are indirect, so we want to load - // the value at address GV, not the value of GV itself. This means that - // the GlobalAddress must be in the base or index register of the address, - // not the GV offset field. - if (Subtarget->getIndirectExternAndWeakGlobals() && - (GV->hasWeakLinkage() || GV->isExternal())) { - AM.Base.Reg = - CurDAG->getTargetNode(X86::MOV32rm, MVT::i32, MVT::Other, - CurDAG->getRegister(0, MVT::i32), - getI8Imm(1), CurDAG->getRegister(0, MVT::i32), - CurDAG->getTargetGlobalAddress(GV, MVT::i32), - CurDAG->getEntryNode()); - } else { - AM.GV = GV; - } + AM.GV = cast<GlobalAddressSDNode>(N)->getGlobal(); return false; } break; Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.11 llvm/lib/Target/X86/X86ISelLowering.cpp:1.12 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.11 Tue Dec 20 00:22:03 2005 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Dec 20 20:39:21 2005 @@ -197,6 +197,68 @@ return LowerCCCCallTo(Chain, RetTy, isVarArg, isTailCall, Callee, Args, DAG); } +SDOperand X86TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, + SelectionDAG &DAG) { + if (!X86DAGIsel) + return DAG.getNode(ISD::RET, MVT::Other, Chain, Op); + + SDOperand Copy; + MVT::ValueType OpVT = Op.getValueType(); + switch (OpVT) { + default: assert(0 && "Unknown type to return!"); + case MVT::i32: + Copy = DAG.getCopyToReg(Chain, X86::EAX, 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, X86::EAX, Hi, SDOperand()); + Copy = DAG.getCopyToReg(Copy, X86::EDX, Lo, Copy.getValue(1)); + break; + } + case MVT::f32: + assert(X86ScalarSSE && "MVT::f32 only legal with scalar sse fp"); + // Fallthrough intended + case MVT::f64: + if (!X86ScalarSSE) { + std::vector<MVT::ValueType> Tys; + Tys.push_back(MVT::Other); + Tys.push_back(MVT::Flag); + std::vector<SDOperand> Ops; + Ops.push_back(Chain); + Ops.push_back(Op); + Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops); + } else { + // Spill the value to memory and reload it into top of stack. + unsigned Size = MVT::getSizeInBits(OpVT)/8; + MachineFunction &MF = DAG.getMachineFunction(); + int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size); + SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); + Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, Op, + StackSlot, DAG.getSrcValue(NULL)); + std::vector<MVT::ValueType> Tys; + Tys.push_back(MVT::f64); + Tys.push_back(MVT::Other); + std::vector<SDOperand> Ops; + Ops.push_back(Chain); + Ops.push_back(StackSlot); + Ops.push_back(DAG.getValueType(OpVT)); + Copy = DAG.getNode(X86ISD::FLD, Tys, Ops); + Tys.clear(); + Tys.push_back(MVT::Other); + Tys.push_back(MVT::Flag); + Ops.clear(); + Ops.push_back(Copy.getValue(1)); + Ops.push_back(Copy); + Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops); + } + break; + } + return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); +} + //===----------------------------------------------------------------------===// // C Calling Convention implementation //===----------------------------------------------------------------------===// @@ -968,6 +1030,20 @@ return DAG.getNode(X86ISD::BRCOND, Op.getValueType(), Op.getOperand(0), Op.getOperand(2), CC, Cond); } + case ISD::GlobalAddress: + GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); + // For Darwin, external and weak symbols are indirect, so we want to load + // the value at address GV, not the value of GV itself. This means that + // the GlobalAddress must be in the base or index register of the address, + // not the GV offset field. + if (getTargetMachine(). + getSubtarget<X86Subtarget>().getIndirectExternAndWeakGlobals() && + (GV->hasWeakLinkage() || GV->isExternal())) + return DAG.getLoad(MVT::i32, DAG.getEntryNode(), Op, + DAG.getSrcValue(NULL)); + else + return Op; + break; } } @@ -978,6 +1054,8 @@ case X86ISD::FP_TO_INT16_IN_MEM: return "X86ISD::FP_TO_INT16_IN_MEM"; case X86ISD::FP_TO_INT32_IN_MEM: return "X86ISD::FP_TO_INT32_IN_MEM"; case X86ISD::FP_TO_INT64_IN_MEM: return "X86ISD::FP_TO_INT64_IN_MEM"; + case X86ISD::FLD: return "X86ISD::FLD"; + case X86ISD::FP_SET_RESULT: return "X86ISD::FP_SET_RESULT"; case X86ISD::CALL: return "X86ISD::CALL"; case X86ISD::TAILCALL: return "X86ISD::TAILCALL"; case X86ISD::RDTSC_DAG: return "X86ISD::RDTSC_DAG"; @@ -985,5 +1063,6 @@ case X86ISD::TEST: return "X86ISD::TEST"; case X86ISD::CMOV: return "X86ISD::CMOV"; case X86ISD::BRCOND: return "X86ISD::BRCOND"; + case X86ISD::RET_FLAG: return "X86ISD::RET_FLAG"; } } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.5 llvm/lib/Target/X86/X86ISelLowering.h:1.6 --- llvm/lib/Target/X86/X86ISelLowering.h:1.5 Tue Dec 20 00:22:03 2005 +++ llvm/lib/Target/X86/X86ISelLowering.h Tue Dec 20 20:39:21 2005 @@ -40,6 +40,17 @@ FP_TO_INT32_IN_MEM, FP_TO_INT64_IN_MEM, + /// FLD - This instruction implements an extending load to FP stack slots. + /// This corresponds to the X86::FLD32m / X86::FLD64m. It takes a chain + /// operand, ptr to load from, and a VALUETYPE node indicating the type + /// to load. + FLD, + + /// FP_SET_RESULT - This corresponds to FpSETRESULT pseudo instrcuction + /// which copies the source operand to ST(0). It takes a chain and writes + /// a chain and a flag. + FP_SET_RESULT, + /// CALL/TAILCALL - These operations represent an abstract X86 call /// instruction, which includes a bunch of information. In particular the /// operands of these node are: @@ -75,6 +86,9 @@ /// X86 conditional branches. BRCOND, + + // Return with a flag operand. + RET_FLAG, }; } @@ -113,6 +127,9 @@ bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); + virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op, + SelectionDAG &DAG); + virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, Value *VAListV, SelectionDAG &DAG); virtual std::pair<SDOperand,SDOperand> Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.175 llvm/lib/Target/X86/X86InstrInfo.td:1.176 --- llvm/lib/Target/X86/X86InstrInfo.td:1.175 Tue Dec 20 16:59:50 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Tue Dec 20 20:39:21 2005 @@ -28,11 +28,25 @@ [SDTCisVT<0, OtherVT>, SDTCisVT<1, OtherVT>, SDTCisVT<2, FlagVT>]>; -def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest, []>; -def X86test : SDNode<"X86ISD::TEST", SDTX86CmpTest, []>; +def SDTX86RetFlag : SDTypeProfile<0, 1, [SDTCisVT<0, FlagVT>]>; -def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov, []>; -def X86Brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond, [SDNPHasChain]>; +def SDTX86Fld : SDTypeProfile<1, 2, [SDTCisFP<0>, + SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>; + +def SDTX86FpSet : SDTypeProfile<0, 1, [SDTCisFP<0>]>; + +def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest, []>; +def X86test : SDNode<"X86ISD::TEST", SDTX86CmpTest, []>; + +def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov, []>; +def X86Brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond, [SDNPHasChain]>; + +def X86retflag: SDNode<"X86ISD::RET_FLAG", SDTX86RetFlag, [SDNPHasChain]>; + +def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld, [SDNPHasChain]>; + +def X86fpset : SDNode<"X86ISD::FP_SET_RESULT", + SDTX86FpSet, [SDNPHasChain]>; //===----------------------------------------------------------------------===// // X86 Operand Definitions. @@ -274,6 +288,8 @@ let isTerminator = 1, isReturn = 1, isBarrier = 1 in def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt", []>; +def : Pat<(X86retflag FLAG), (RET)>; + // All branches are RawFrm, Void, Branch, and Terminators let isBranch = 1, isTerminator = 1 in class IBr<bits<8> opcode, dag ops, string asm, list<dag> pattern> : @@ -2188,10 +2204,21 @@ (ops RFP:$dst, RFP:$src1, RFP:$src2), "", []>; // f1 = fdiv f2, f3 +def FpLD32m : FPI<0xD9, MRM0m, ZeroArgFP, + (ops RFP:$dst, f32mem:$src), + "fld{s} $src", + [(set RFP:$dst, (X86fld addr:$src, f32))]>; + +def FpLD64m : FPI<0xDD, MRM0m, ZeroArgFP, + (ops RFP:$dst, f64mem:$src), + "fld{l} $src", + [(set RFP:$dst, (X86fld addr:$src, f64))]>; + def FpGETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP:$dst), "", []>, Imp<[ST0], []>; // FPR = ST(0) -def FpSETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP:$src), "", []>, +def FpSETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP:$src), "", + [(X86fpset RFP:$src)]>, Imp<[], [ST0]>; // ST(0) = FPR // FADD reg, mem: Before stackification, these are represented by: Index: llvm/lib/Target/X86/X86RegisterInfo.td diff -u llvm/lib/Target/X86/X86RegisterInfo.td:1.25 llvm/lib/Target/X86/X86RegisterInfo.td:1.26 --- llvm/lib/Target/X86/X86RegisterInfo.td:1.25 Tue Dec 20 16:59:51 2005 +++ llvm/lib/Target/X86/X86RegisterInfo.td Tue Dec 20 20:39:21 2005 @@ -142,6 +142,11 @@ }]; } -def FLAGS_REGS : RegisterClass<"X86", [FlagVT], 32, [STATUS]> { +// FIXME: +// HACKTROCITY: define a flags reg class for things that need to take a flag. +// this should really be handled by tablgen. +let Namespace = "X86" in + def FLAG : Register<"FLAG">; +def FLAGS_REGS : RegisterClass<"X86", [FlagVT], 32, [STATUS, FLAG]> { let Size = 32; } _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits