mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-16 14:31:59 +00:00
* 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25207 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a2664c50d6
commit
8700e14ba1
@ -13,6 +13,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "X86.h"
|
||||
#include "X86InstrBuilder.h"
|
||||
#include "X86RegisterInfo.h"
|
||||
#include "X86Subtarget.h"
|
||||
#include "X86ISelLowering.h"
|
||||
@ -95,6 +96,8 @@ namespace {
|
||||
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
|
||||
virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
|
||||
|
||||
virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF);
|
||||
|
||||
// Include the pieces autogenerated from the target description.
|
||||
#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,
|
||||
/// returning true if it cannot be done. This just pattern matches for the
|
||||
/// addressing mode
|
||||
@ -338,22 +363,25 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM) {
|
||||
bool X86DAGToDAGISel::SelectAddr(SDOperand N, SDOperand &Base, SDOperand &Scale,
|
||||
SDOperand &Index, SDOperand &Disp) {
|
||||
X86ISelAddressMode AM;
|
||||
if (!MatchAddress(N, AM)) {
|
||||
if (AM.BaseType == X86ISelAddressMode::RegBase) {
|
||||
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);
|
||||
if (MatchAddress(N, AM))
|
||||
return false;
|
||||
|
||||
getAddressOperands(AM, Base, Scale, Index, Disp);
|
||||
return true;
|
||||
if (AM.BaseType == X86ISelAddressMode::RegBase) {
|
||||
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,
|
||||
|
@ -220,6 +220,8 @@ X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
||||
// turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
|
||||
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
|
||||
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)
|
||||
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.
|
||||
unsigned ArgOffset = 0;
|
||||
SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(),
|
||||
X86::ESP, MVT::i32);
|
||||
SDOperand StackPtr = DAG.getRegister(X86::ESP, MVT::i32);
|
||||
std::vector<SDOperand> Stores;
|
||||
|
||||
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
|
||||
|
@ -1223,12 +1223,15 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||
SDNode *Node = N.Val;
|
||||
SDOperand Op0, Op1;
|
||||
|
||||
if (Node->getOpcode() == ISD::CopyFromReg) {
|
||||
unsigned Reg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
|
||||
if (Node->getOpcode() == ISD::CopyFromReg ||
|
||||
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.
|
||||
if (MRegisterInfo::isVirtualRegister(Reg) || Reg == X86::ESP)
|
||||
return Reg;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned &Reg = ExprMap[N];
|
||||
if (Reg) return Reg;
|
||||
|
@ -2916,8 +2916,8 @@ def RDTSC : I<0x31, RawFrm, (ops), "rdtsc", [(X86rdtsc)]>,
|
||||
// Calls
|
||||
def : Pat<(X86call tglobaladdr:$dst),
|
||||
(CALLpcrel32 tglobaladdr:$dst)>;
|
||||
def : Pat<(X86call externalsym:$dst),
|
||||
(CALLpcrel32 externalsym:$dst)>;
|
||||
def : Pat<(X86call texternalsym:$dst),
|
||||
(CALLpcrel32 texternalsym:$dst)>;
|
||||
|
||||
// X86 specific add which produces a flag.
|
||||
def : Pat<(X86addflag R32:$src1, R32:$src2),
|
||||
|
Loading…
x
Reference in New Issue
Block a user