namespace llvm {
+class TargetSubtarget;
class TargetInstrInfo;
class TargetInstrDescriptor;
class TargetJITInfo;
virtual const TargetFrameInfo *getFrameInfo() const { return 0; }
const TargetData &getTargetData() const { return DataLayout; }
+ virtual const TargetSubtarget *getSubtargetImpl() const { return 0; }
+ template<typename STC> STC *getSubtarget() const {
+ assert(getSubtargetImpl() && dynamic_cast<STC*>(getSubtargetImpl()) &&
+ "Not the right kind of subtarget!");
+ return (STC*)getSubtargetImpl();
+ }
+
/// getRegisterInfo - If register information is available, return it. If
/// not, return null. This is kept separate from RegInfo until RegInfo has
/// details of graph coloring register allocation removed from it.
--- /dev/null
+//==-- llvm/Target/TargetSubtarget.h - Target Information --------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Nate Begeman and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the subtarget options of a Target machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETSUBTARGET_H
+#define LLVM_TARGET_TARGETSUBTARGET_H
+
+namespace llvm {
+
+class Module;
+
+//===----------------------------------------------------------------------===//
+///
+/// TargetSubtarget - Generic base class for all target subtargets. All
+/// Target-specific options that control code generation and printing should
+/// be exposed through a TargetSubtarget-derived class.
+///
+class TargetSubtarget {
+ TargetSubtarget(const TargetSubtarget&); // DO NOT IMPLEMENT
+ void operator=(const TargetSubtarget&); // DO NOT IMPLEMENT
+protected: // Can only create subclasses...
+ /// This constructor initializes the data members to match that
+ /// of the specified module.
+ ///
+ TargetSubtarget(const Module &M);
+public:
+ virtual ~TargetSubtarget();
+};
+
+} // End llvm namespace
+
+#endif
--- /dev/null
+//===-- TargetSubtarget.cpp - General Target Information -------------------==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Nate Begeman and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the general parts of a Subtarget.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/TargetSubtarget.h"
+using namespace llvm;
+
+//---------------------------------------------------------------------------
+// TargetSubtarget Class
+//
+TargetSubtarget::TargetSubtarget(const Module &M) {}
+
+TargetSubtarget::~TargetSubtarget() {}
#include "X86.h"
#include "X86InstrBuilder.h"
#include "X86RegisterInfo.h"
+#include "X86Subtarget.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#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"
/// 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 {
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:
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: {
--- /dev/null
+//===- X86Subtarget.cpp - X86 Instruction Information -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Nate Begeman and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the X86 specific subclass of TargetSubtarget.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86Subtarget.h"
+#include "llvm/Module.h"
+using namespace llvm;
+
+X86Subtarget::X86Subtarget(const Module &M)
+ : TargetSubtarget(M), stackAlignment(8),
+ indirectExternAndWeakGlobals(false), asmDarwinLinkerStubs(false),
+ asmLeadingUnderscore(false), asmAlignmentIsInBytes(false),
+ asmPrintDotLocalConstants(false), asmPrintDotLCommConstants(false),
+ asmPrintConstantAlignment(false) {
+ // Declare a boolean for each platform
+ bool forCygwin = false;
+ bool forDarwin = false;
+ bool forWindows = false;
+
+ // Set the boolean corresponding to the current target triple, or the default
+ // if one cannot be determined, to true.
+ const std::string& TT = M.getTargetTriple();
+ if (TT.length() > 5) {
+ forCygwin = TT.find("cygwin") != std::string::npos ||
+ TT.find("mingw") != std::string::npos;
+ forDarwin = TT.find("darwin") != std::string::npos;
+ forWindows = TT.find("win32") != std::string::npos;
+ } else if (TT.empty()) {
+#if defined(__CYGWIN__) || defined(__MINGW32__)
+ forCygwin = true;
+#elif defined(__APPLE__)
+ forDarwin = true;
+#elif defined(_WIN32)
+ forWindws = true;
+#endif
+ }
+
+ if (forCygwin) {
+ asmLeadingUnderscore = true;
+ }
+ if (forDarwin) {
+ stackAlignment = 16;
+ indirectExternAndWeakGlobals = true;
+ asmDarwinLinkerStubs = true;
+ asmLeadingUnderscore = true;
+ asmPrintDotLCommConstants = true;
+ }
+ if (forWindows) {
+ }
+}
--- /dev/null
+//=====-- X86Subtarget.h - Define TargetMachine for the X86 ---*- C++ -*--====//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Nate Begeman and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the X86 specific subclass of TargetSubtarget.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef X86SUBTARGET_H
+#define X86SUBTARGET_H
+
+#include "llvm/Target/TargetSubtarget.h"
+
+namespace llvm {
+class Module;
+
+class X86Subtarget : public TargetSubtarget {
+protected:
+ /// Used by the target machine to set up the target frame info
+ unsigned stackAlignment;
+
+ /// Used by instruction selector
+ bool indirectExternAndWeakGlobals;
+
+ /// Used by the asm printer
+ bool asmDarwinLinkerStubs;
+ bool asmLeadingUnderscore;
+ bool asmAlignmentIsInBytes;
+ bool asmPrintDotLocalConstants;
+ bool asmPrintDotLCommConstants;
+ bool asmPrintConstantAlignment;
+public:
+ /// This constructor initializes the data members to match that
+ /// of the specified module.
+ ///
+ X86Subtarget(const Module &M);
+
+ /// Returns the preferred stack alignment for the current target triple, or
+ /// the default if no target triple is set.
+ unsigned getStackAlignment() const { return stackAlignment; }
+
+ /// Returns true if the instruction selector should treat global values
+ /// referencing external or weak symbols as indirect rather than direct
+ /// references.
+ bool getIndirectExternAndWeakGlobals() const {
+ return indirectExternAndWeakGlobals; }
+};
+} // End llvm namespace
+
+#endif
///
X86TargetMachine::X86TargetMachine(const Module &M, IntrinsicLowering *IL)
: TargetMachine("X86", IL, true, 4, 4, 4, 4, 4),
- FrameInfo(TargetFrameInfo::StackGrowsDown, 8, -4),
+ Subtarget(M),
+ FrameInfo(TargetFrameInfo::StackGrowsDown,
+ Subtarget.getStackAlignment(), -4),
JITInfo(*this) {
// Scalar SSE FP requires at least SSE2
X86ScalarSSE &= X86Vector >= SSE2;
#include "llvm/PassManager.h"
#include "X86InstrInfo.h"
#include "X86JITInfo.h"
+#include "X86Subtarget.h"
namespace llvm {
class IntrinsicLowering;
class X86TargetMachine : public TargetMachine {
X86InstrInfo InstrInfo;
+ X86Subtarget Subtarget;
TargetFrameInfo FrameInfo;
X86JITInfo JITInfo;
public:
virtual const X86InstrInfo *getInstrInfo() const { return &InstrInfo; }
virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; }
virtual TargetJITInfo *getJITInfo() { return &JITInfo; }
+ virtual const TargetSubtarget *getSubtargetImpl() const{ return &Subtarget; }
virtual const MRegisterInfo *getRegisterInfo() const {
return &InstrInfo.getRegisterInfo();
}