diff options
author | Nate Begeman <natebegeman@mac.com> | 2005-07-12 01:41:54 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2005-07-12 01:41:54 +0000 |
commit | fb5792f416089d8d8d0c6ee62c1f41a55d2cf75d (patch) | |
tree | e2b2a65b1d1e7f426d6f3035bca964ce25c0d79d /lib/Target/X86/X86ISelPattern.cpp | |
parent | 73213f6c07afc1479f8d7bf53ea99adf7fd60b78 (diff) |
Implement Subtarget support
Implement the X86 Subtarget.
This consolidates the checks for target triple, and setting options based
on target triple into one place. This allows us to convert the asm printer
and isel over from being littered with "forDarwin", "forCygwin", etc. into
just having the appropriate flags for each subtarget feature controlling
the code for that feature.
This patch also implements indirect external and weak references in the
X86 pattern isel, for darwin. Next up is to convert over the asm printers
to use this new interface.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22389 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86/X86ISelPattern.cpp')
-rw-r--r-- | lib/Target/X86/X86ISelPattern.cpp | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp index 66e6f71bff..6bd8e27607 100644 --- a/lib/Target/X86/X86ISelPattern.cpp +++ b/lib/Target/X86/X86ISelPattern.cpp @@ -14,6 +14,7 @@ #include "X86.h" #include "X86InstrBuilder.h" #include "X86RegisterInfo.h" +#include "X86Subtarget.h" #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" @@ -26,6 +27,7 @@ #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLowering.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Support/CFG.h" #include "llvm/Support/MathExtras.h" @@ -996,8 +998,13 @@ namespace { /// TheDAG - The DAG being selected during Select* operations. SelectionDAG *TheDAG; + + /// Subtarget - Keep a pointer to the X86Subtarget around so that we can + /// make the right decision when generating code for different targets. + const X86Subtarget *Subtarget; public: ISel(TargetMachine &TM) : SelectionDAGISel(X86Lowering), X86Lowering(TM) { + Subtarget = TM.getSubtarget<const X86Subtarget>(); } virtual const char *getPassName() const { @@ -1314,8 +1321,18 @@ bool ISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM) { break; case ISD::GlobalAddress: if (AM.GV == 0) { - AM.GV = cast<GlobalAddressSDNode>(N)->getGlobal(); - return false; + 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())) { + break; + } else { + AM.GV = GV; + return false; + } } break; case ISD::Constant: @@ -2236,7 +2253,15 @@ unsigned ISel::SelectExpr(SDOperand N) { return Result; case ISD::GlobalAddress: { GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal(); - BuildMI(BB, X86::MOV32ri, 1, Result).addGlobalAddress(GV); + // For Darwin, external and weak symbols are indirect, so we want to load + // the value at address GV, not the value of GV itself. + if (Subtarget->getIndirectExternAndWeakGlobals() && + (GV->hasWeakLinkage() || GV->isExternal())) { + BuildMI(BB, X86::MOV32rm, 4, Result).addReg(0).addZImm(1).addReg(0) + .addGlobalAddress(GV, false, 0); + } else { + BuildMI(BB, X86::MOV32ri, 1, Result).addGlobalAddress(GV); + } return Result; } case ISD::ExternalSymbol: { |