aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/X86/X86ISelDAGToDAG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/X86/X86ISelDAGToDAG.cpp')
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp56
1 files changed, 42 insertions, 14 deletions
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index c6d4e6727e..9f5c588df8 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -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)
+ if (MatchAddress(N, AM))
+ return false;
+
+ 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);
+ } 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);
- return true;
}
- 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,