forked from OSchip/llvm-project
* Add special entry code main() (to set x87 to 64-bit precision).
* Allow a register node as SelectAddr() base. * ExternalSymbol -> TargetExternalSymbol as direct function callee. * Use X86::ESP register rather than CopyFromReg(X86::ESP) as stack ptr for call parmater passing. llvm-svn: 25207
This commit is contained in:
parent
21f0c31c43
commit
bc7a0f44bd
|
@ -13,6 +13,7 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "X86.h"
|
#include "X86.h"
|
||||||
|
#include "X86InstrBuilder.h"
|
||||||
#include "X86RegisterInfo.h"
|
#include "X86RegisterInfo.h"
|
||||||
#include "X86Subtarget.h"
|
#include "X86Subtarget.h"
|
||||||
#include "X86ISelLowering.h"
|
#include "X86ISelLowering.h"
|
||||||
|
@ -95,6 +96,8 @@ namespace {
|
||||||
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
||||||
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
|
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
|
||||||
|
|
||||||
|
virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF);
|
||||||
|
|
||||||
// Include the pieces autogenerated from the target description.
|
// Include the pieces autogenerated from the target description.
|
||||||
#include "X86GenDAGISel.inc"
|
#include "X86GenDAGISel.inc"
|
||||||
|
|
||||||
|
@ -208,7 +211,29 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FIXME: copied from X86ISelPattern.cpp
|
/// EmitSpecialCodeForMain - Emit any code that needs to be executed only in
|
||||||
|
/// the main function.
|
||||||
|
static void EmitSpecialCodeForMain(MachineBasicBlock *BB,
|
||||||
|
MachineFrameInfo *MFI) {
|
||||||
|
// Switch the FPU to 64-bit precision mode for better compatibility and speed.
|
||||||
|
int CWFrameIdx = MFI->CreateStackObject(2, 2);
|
||||||
|
addFrameReference(BuildMI(BB, X86::FNSTCW16m, 4), CWFrameIdx);
|
||||||
|
|
||||||
|
// Set the high part to be 64-bit precision.
|
||||||
|
addFrameReference(BuildMI(BB, X86::MOV8mi, 5),
|
||||||
|
CWFrameIdx, 1).addImm(2);
|
||||||
|
|
||||||
|
// Reload the modified control word now.
|
||||||
|
addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void X86DAGToDAGISel::EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {
|
||||||
|
// If this is main, emit special code for main.
|
||||||
|
MachineBasicBlock *BB = MF.begin();
|
||||||
|
if (Fn.hasExternalLinkage() && Fn.getName() == "main")
|
||||||
|
EmitSpecialCodeForMain(BB, MF.getFrameInfo());
|
||||||
|
}
|
||||||
|
|
||||||
/// MatchAddress - Add the specified node to the specified addressing mode,
|
/// MatchAddress - Add the specified node to the specified addressing mode,
|
||||||
/// returning true if it cannot be done. This just pattern matches for the
|
/// returning true if it cannot be done. This just pattern matches for the
|
||||||
/// addressing mode
|
/// addressing mode
|
||||||
|
@ -338,22 +363,25 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM) {
|
||||||
bool X86DAGToDAGISel::SelectAddr(SDOperand N, SDOperand &Base, SDOperand &Scale,
|
bool X86DAGToDAGISel::SelectAddr(SDOperand N, SDOperand &Base, SDOperand &Scale,
|
||||||
SDOperand &Index, SDOperand &Disp) {
|
SDOperand &Index, SDOperand &Disp) {
|
||||||
X86ISelAddressMode AM;
|
X86ISelAddressMode AM;
|
||||||
if (!MatchAddress(N, AM)) {
|
if (MatchAddress(N, AM))
|
||||||
if (AM.BaseType == X86ISelAddressMode::RegBase) {
|
return false;
|
||||||
if (AM.Base.Reg.Val)
|
|
||||||
AM.Base.Reg = Select(AM.Base.Reg);
|
|
||||||
else
|
|
||||||
AM.Base.Reg = CurDAG->getRegister(0, MVT::i32);
|
|
||||||
}
|
|
||||||
if (AM.IndexReg.Val)
|
|
||||||
AM.IndexReg = Select(AM.IndexReg);
|
|
||||||
else
|
|
||||||
AM.IndexReg = CurDAG->getRegister(0, MVT::i32);
|
|
||||||
|
|
||||||
getAddressOperands(AM, Base, Scale, Index, Disp);
|
if (AM.BaseType == X86ISelAddressMode::RegBase) {
|
||||||
return true;
|
if (AM.Base.Reg.Val) {
|
||||||
|
if (AM.Base.Reg.getOpcode() != ISD::Register)
|
||||||
|
AM.Base.Reg = Select(AM.Base.Reg);
|
||||||
|
} else {
|
||||||
|
AM.Base.Reg = CurDAG->getRegister(0, MVT::i32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
if (AM.IndexReg.Val)
|
||||||
|
AM.IndexReg = Select(AM.IndexReg);
|
||||||
|
else
|
||||||
|
AM.IndexReg = CurDAG->getRegister(0, MVT::i32);
|
||||||
|
|
||||||
|
getAddressOperands(AM, Base, Scale, Index, Disp);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool X86DAGToDAGISel::TryFoldLoad(SDOperand N, SDOperand &Base,
|
bool X86DAGToDAGISel::TryFoldLoad(SDOperand N, SDOperand &Base,
|
||||||
|
|
|
@ -220,6 +220,8 @@ X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
||||||
// turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
|
// turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
|
||||||
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
|
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
|
||||||
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
|
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
|
||||||
|
else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
|
||||||
|
Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
|
||||||
|
|
||||||
if (CallingConv == CallingConv::Fast && EnableFastCC)
|
if (CallingConv == CallingConv::Fast && EnableFastCC)
|
||||||
return LowerFastCCCallTo(Chain, RetTy, isTailCall, Callee, Args, DAG);
|
return LowerFastCCCallTo(Chain, RetTy, isTailCall, Callee, Args, DAG);
|
||||||
|
@ -412,8 +414,7 @@ X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy,
|
||||||
|
|
||||||
// Arguments go on the stack in reverse order, as specified by the ABI.
|
// Arguments go on the stack in reverse order, as specified by the ABI.
|
||||||
unsigned ArgOffset = 0;
|
unsigned ArgOffset = 0;
|
||||||
SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(),
|
SDOperand StackPtr = DAG.getRegister(X86::ESP, MVT::i32);
|
||||||
X86::ESP, MVT::i32);
|
|
||||||
std::vector<SDOperand> Stores;
|
std::vector<SDOperand> Stores;
|
||||||
|
|
||||||
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
|
||||||
|
|
|
@ -1223,12 +1223,15 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||||
SDNode *Node = N.Val;
|
SDNode *Node = N.Val;
|
||||||
SDOperand Op0, Op1;
|
SDOperand Op0, Op1;
|
||||||
|
|
||||||
if (Node->getOpcode() == ISD::CopyFromReg) {
|
if (Node->getOpcode() == ISD::CopyFromReg ||
|
||||||
unsigned Reg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
|
Node->getOpcode() == ISD::Register) {
|
||||||
|
unsigned Reg = (Node->getOpcode() == ISD::CopyFromReg) ?
|
||||||
|
cast<RegisterSDNode>(Node->getOperand(1))->getReg() :
|
||||||
|
cast<RegisterSDNode>(Node)->getReg();
|
||||||
// Just use the specified register as our input if we can.
|
// Just use the specified register as our input if we can.
|
||||||
if (MRegisterInfo::isVirtualRegister(Reg) || Reg == X86::ESP)
|
if (MRegisterInfo::isVirtualRegister(Reg) || Reg == X86::ESP)
|
||||||
return Reg;
|
return Reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned &Reg = ExprMap[N];
|
unsigned &Reg = ExprMap[N];
|
||||||
if (Reg) return Reg;
|
if (Reg) return Reg;
|
||||||
|
|
|
@ -2916,8 +2916,8 @@ def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", [(X86rdtsc)]>,
|
||||||
// Calls
|
// Calls
|
||||||
def : Pat<(X86call tglobaladdr:$dst),
|
def : Pat<(X86call tglobaladdr:$dst),
|
||||||
(CALLpcrel32 tglobaladdr:$dst)>;
|
(CALLpcrel32 tglobaladdr:$dst)>;
|
||||||
def : Pat<(X86call externalsym:$dst),
|
def : Pat<(X86call texternalsym:$dst),
|
||||||
(CALLpcrel32 externalsym:$dst)>;
|
(CALLpcrel32 texternalsym:$dst)>;
|
||||||
|
|
||||||
// X86 specific add which produces a flag.
|
// X86 specific add which produces a flag.
|
||||||
def : Pat<(X86addflag R32:$src1, R32:$src2),
|
def : Pat<(X86addflag R32:$src1, R32:$src2),
|
||||||
|
|
Loading…
Reference in New Issue