[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td X86RegisterInfo.td
Evan Cheng
evan.cheng at apple.com
Tue Dec 20 18:39:33 PST 2005
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;
}
More information about the llvm-commits
mailing list