From: Misha Brukman Date: Wed, 11 Aug 2004 00:09:42 +0000 (+0000) Subject: Breaking up the PowerPC target into 32- and 64-bit subparts, Part I: 32-bit. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=3d9a6c2842599b9d8659ae97e19c413d435d7b34;p=oota-llvm.git Breaking up the PowerPC target into 32- and 64-bit subparts, Part I: 32-bit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15634 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/PowerPC/PPC32.h b/lib/Target/PowerPC/PPC32.h new file mode 100644 index 00000000000..c74208f8837 --- /dev/null +++ b/lib/Target/PowerPC/PPC32.h @@ -0,0 +1,31 @@ +//===-- PPC32.h - Top-level interface for 32-bit PowerPC -----------*- C++ -*-// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the entry points for global functions defined in the LLVM +// Darwin/PowerPC back-end. +// +//===----------------------------------------------------------------------===// + +#ifndef TARGET_POWERPC32_H +#define TARGET_POWERPC32_H + +#include "PowerPC.h" +#include + +namespace llvm { + +class FunctionPass; +class TargetMachine; + +FunctionPass *createPPC32ISelSimple(TargetMachine &TM); +FunctionPass *createPPC32AsmPrinter(std::ostream &OS,TargetMachine &TM); + +} // end namespace llvm; + +#endif diff --git a/lib/Target/PowerPC/PPC32AsmPrinter.cpp b/lib/Target/PowerPC/PPC32AsmPrinter.cpp index b52f055c8cf..5f3b5de7c6c 100644 --- a/lib/Target/PowerPC/PPC32AsmPrinter.cpp +++ b/lib/Target/PowerPC/PPC32AsmPrinter.cpp @@ -1,4 +1,4 @@ -//===-- PowerPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --===// +//===-- PPC32AsmPrinter.cpp - Print machine instrs to PowerPC assembly ----===// // // The LLVM Compiler Infrastructure // @@ -19,7 +19,7 @@ #define DEBUG_TYPE "asmprinter" #include "PowerPC.h" #include "PowerPCInstrInfo.h" -#include "PowerPCTargetMachine.h" +#include "PPC32TargetMachine.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" @@ -48,7 +48,7 @@ namespace { /// Target machine description which we query for reg. names, data /// layout, etc. /// - PowerPCTargetMachine &TM; + PPC32TargetMachine &TM; /// Name-mangler for global names. /// @@ -57,7 +57,7 @@ namespace { std::set Strings; Printer(std::ostream &o, TargetMachine &tm) : O(o), - TM(reinterpret_cast(tm)), LabelNumber(0) {} + TM(reinterpret_cast(tm)), LabelNumber(0) {} /// Cache of mangled name for current function. This is /// recalculated at the beginning of each call to @@ -70,7 +70,7 @@ namespace { unsigned LabelNumber; virtual const char *getPassName() const { - return "PowerPC Assembly Printer"; + return "PPC32 Assembly Printer"; } void printMachineInstruction(const MachineInstr *MI); @@ -85,12 +85,12 @@ namespace { }; } // end of anonymous namespace -/// createPPCAsmPrinterPass - Returns a pass that prints the PPC +/// createPPC32AsmPrinterPass - Returns a pass that prints the PPC /// assembly code for a MachineFunction to the given output stream, /// using the given target machine description. This should work /// regardless of whether the function is in SSA form or not. /// -FunctionPass *createPPCAsmPrinterPass(std::ostream &o,TargetMachine &tm) { +FunctionPass *createPPC32AsmPrinter(std::ostream &o,TargetMachine &tm) { return new Printer(o, tm); } diff --git a/lib/Target/PowerPC/PPC32ISelSimple.cpp b/lib/Target/PowerPC/PPC32ISelSimple.cpp index 5d438e7ca21..41d3e15c9e6 100644 --- a/lib/Target/PowerPC/PPC32ISelSimple.cpp +++ b/lib/Target/PowerPC/PPC32ISelSimple.cpp @@ -11,7 +11,8 @@ #include "PowerPC.h" #include "PowerPCInstrBuilder.h" #include "PowerPCInstrInfo.h" -#include "PowerPCTargetMachine.h" +#include "PPC32.h" +#include "PPC32TargetMachine.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" @@ -74,7 +75,7 @@ static inline TypeClass getClassB(const Type *Ty) { namespace { struct ISel : public FunctionPass, InstVisitor { - PowerPCTargetMachine &TM; + PPC32TargetMachine &TM; MachineFunction *F; // The function we are compiling into MachineBasicBlock *BB; // The current MBB we are compiling int VarArgsFrameIndex; // FrameIndex for start of varargs area @@ -98,7 +99,7 @@ namespace { unsigned GlobalBaseReg; bool GlobalBaseInitialized; - ISel(TargetMachine &tm) : TM(reinterpret_cast(tm)), + ISel(TargetMachine &tm) : TM(reinterpret_cast(tm)), F(0), BB(0) {} bool doInitialization(Module &M) { @@ -3390,10 +3391,9 @@ void ISel::visitFreeInst(FreeInst &I) { TM.CalledFunctions.insert(freeFn); } -/// createPPCSimpleInstructionSelector - This pass converts an LLVM function -/// into a machine code representation is a very simple peep-hole fashion. The -/// generated code sucks but the implementation is nice and simple. +/// createPPC32ISelSimple - This pass converts an LLVM function into a machine +/// code representation is a very simple peep-hole fashion. /// -FunctionPass *llvm::createPPCSimpleInstructionSelector(TargetMachine &TM) { +FunctionPass *llvm::createPPC32ISelSimple(TargetMachine &TM) { return new ISel(TM); } diff --git a/lib/Target/PowerPC/PPC32JITInfo.h b/lib/Target/PowerPC/PPC32JITInfo.h new file mode 100644 index 00000000000..c887a2c0728 --- /dev/null +++ b/lib/Target/PowerPC/PPC32JITInfo.h @@ -0,0 +1,48 @@ +//===- PPC32JITInfo.h - PowerPC/Darwin JIT interface --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the PowerPC implementation of the TargetJITInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef POWERPC_DARWIN_JITINFO_H +#define POWERPC_DARWIN_JITINFO_H + +#include "PowerPCJITInfo.h" + +namespace llvm { + class TargetMachine; + class IntrinsicLowering; + + class PPC32JITInfo : public PowerPCJITInfo { + public: + PPC32JITInfo(TargetMachine &tm) : PowerPCJITInfo(tm) {} + + /// addPassesToJITCompile - Add passes to the specified pass manager to + /// implement a fast dynamic compiler for this target. Return true if this + /// is not supported for this target. + /// + virtual void addPassesToJITCompile(FunctionPassManager &PM); + + /// replaceMachineCodeForFunction - Make it so that calling the function + /// whose machine code is at OLD turns into a call to NEW, perhaps by + /// overwriting OLD with a branch to NEW. This is used for self-modifying + /// code. + /// + virtual void replaceMachineCodeForFunction(void *Old, void *New); + + /// getJITStubForFunction - Create or return a stub for the specified + /// function. This stub acts just like the specified function, except that + /// it allows the "address" of the function to be taken without having to + /// generate code for it. + virtual void *getJITStubForFunction(Function *F, MachineCodeEmitter &MCE); + }; +} + +#endif diff --git a/lib/Target/PowerPC/PPC32TargetMachine.cpp b/lib/Target/PowerPC/PPC32TargetMachine.cpp new file mode 100644 index 00000000000..523c371fe3e --- /dev/null +++ b/lib/Target/PowerPC/PPC32TargetMachine.cpp @@ -0,0 +1,115 @@ +//===-- PowerPCTargetMachine.cpp - Define TargetMachine for PowerPC -------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// +//===----------------------------------------------------------------------===// + +#include "PPC32.h" +#include "PPC32JITInfo.h" +#include "PPC32TargetMachine.h" +#include "llvm/Module.h" +#include "llvm/PassManager.h" +#include "llvm/CodeGen/IntrinsicLowering.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/Target/TargetMachineRegistry.h" +#include "llvm/Transforms/Scalar.h" +#include +using namespace llvm; + +namespace { + const std::string PPC32 = "Darwin/PowerPC"; + // Register the target + RegisterTarget + X("powerpc-darwin", " Darwin/PowerPC (experimental)"); +} + +/// PowerPCTargetMachine ctor - Create an ILP32 architecture model +/// +PPC32TargetMachine::PPC32TargetMachine(const Module &M, + IntrinsicLowering *IL) + : PowerPCTargetMachine(PPC32, IL, + TargetData(PPC32,false,4,4,4,4,4,4,2,1,4), + TargetFrameInfo(TargetFrameInfo::StackGrowsDown,16,-4), + PPC32JITInfo(*this)) {} + +/// addPassesToEmitAssembly - Add passes to the specified pass manager +/// to implement a static compiler for this target. +/// +bool PPC32TargetMachine::addPassesToEmitAssembly(PassManager &PM, + std::ostream &Out) { + // FIXME: Implement efficient support for garbage collection intrinsics. + PM.add(createLowerGCPass()); + + // FIXME: Implement the invoke/unwind instructions! + PM.add(createLowerInvokePass()); + + // FIXME: Implement the switch instruction in the instruction selector! + PM.add(createLowerSwitchPass()); + + PM.add(createLowerConstantExpressionsPass()); + + // Make sure that no unreachable blocks are instruction selected. + PM.add(createUnreachableBlockEliminationPass()); + + PM.add(createPPC32ISelSimple(*this)); + + if (PrintMachineCode) + PM.add(createMachineFunctionPrinterPass(&std::cerr)); + + PM.add(createRegisterAllocator()); + + if (PrintMachineCode) + PM.add(createMachineFunctionPrinterPass(&std::cerr)); + + // I want a PowerPC specific prolog/epilog code inserter so I can put the + // fills/spills in the right spots. + PM.add(createPowerPCPEI()); + + // Must run branch selection immediately preceding the printer + PM.add(createPPCBranchSelectionPass()); + PM.add(createPPC32AsmPrinter(Out, *this)); + PM.add(createMachineCodeDeleter()); + return false; +} + +/// addPassesToJITCompile - Add passes to the specified pass manager to +/// implement a fast dynamic compiler for this target. +/// +void PPC32JITInfo::addPassesToJITCompile(FunctionPassManager &PM) { + // FIXME: Implement efficient support for garbage collection intrinsics. + PM.add(createLowerGCPass()); + + // FIXME: Implement the invoke/unwind instructions! + PM.add(createLowerInvokePass()); + + // FIXME: Implement the switch instruction in the instruction selector! + PM.add(createLowerSwitchPass()); + + PM.add(createLowerConstantExpressionsPass()); + + // Make sure that no unreachable blocks are instruction selected. + PM.add(createUnreachableBlockEliminationPass()); + + PM.add(createPPC32ISelSimple(TM)); + PM.add(createRegisterAllocator()); + PM.add(createPrologEpilogCodeInserter()); +} + +unsigned PPC32TargetMachine::getModuleMatchQuality(const Module &M) { + if (M.getEndianness() == Module::BigEndian && + M.getPointerSize() == Module::Pointer32) + return 10; // Direct match + else if (M.getEndianness() != Module::AnyEndianness || + M.getPointerSize() != Module::AnyPointerSize) + return 0; // Match for some other target + + return getJITMatchQuality()/2; +} diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index b52f055c8cf..5f3b5de7c6c 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -1,4 +1,4 @@ -//===-- PowerPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --===// +//===-- PPC32AsmPrinter.cpp - Print machine instrs to PowerPC assembly ----===// // // The LLVM Compiler Infrastructure // @@ -19,7 +19,7 @@ #define DEBUG_TYPE "asmprinter" #include "PowerPC.h" #include "PowerPCInstrInfo.h" -#include "PowerPCTargetMachine.h" +#include "PPC32TargetMachine.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" @@ -48,7 +48,7 @@ namespace { /// Target machine description which we query for reg. names, data /// layout, etc. /// - PowerPCTargetMachine &TM; + PPC32TargetMachine &TM; /// Name-mangler for global names. /// @@ -57,7 +57,7 @@ namespace { std::set Strings; Printer(std::ostream &o, TargetMachine &tm) : O(o), - TM(reinterpret_cast(tm)), LabelNumber(0) {} + TM(reinterpret_cast(tm)), LabelNumber(0) {} /// Cache of mangled name for current function. This is /// recalculated at the beginning of each call to @@ -70,7 +70,7 @@ namespace { unsigned LabelNumber; virtual const char *getPassName() const { - return "PowerPC Assembly Printer"; + return "PPC32 Assembly Printer"; } void printMachineInstruction(const MachineInstr *MI); @@ -85,12 +85,12 @@ namespace { }; } // end of anonymous namespace -/// createPPCAsmPrinterPass - Returns a pass that prints the PPC +/// createPPC32AsmPrinterPass - Returns a pass that prints the PPC /// assembly code for a MachineFunction to the given output stream, /// using the given target machine description. This should work /// regardless of whether the function is in SSA form or not. /// -FunctionPass *createPPCAsmPrinterPass(std::ostream &o,TargetMachine &tm) { +FunctionPass *createPPC32AsmPrinter(std::ostream &o,TargetMachine &tm) { return new Printer(o, tm); } diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index e7a36009cb1..b8eb6b67142 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -1,4 +1,4 @@ -//===-- PowerPCCodeEmitter.cpp - JIT Code Emitter for PowerPC -----*- C++ -*-=// +//===-- PPC32CodeEmitter.cpp - JIT Code Emitter for PowerPC32 -----*- C++ -*-=// // // The LLVM Compiler Infrastructure // @@ -10,7 +10,8 @@ // //===----------------------------------------------------------------------===// -#include "PowerPCTargetMachine.h" +#include "PPC32JITInfo.h" +#include "PPC32TargetMachine.h" #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/Passes.h" @@ -19,12 +20,12 @@ namespace llvm { namespace { - class PowerPCCodeEmitter : public MachineFunctionPass { + class PPC32CodeEmitter : public MachineFunctionPass { TargetMachine &TM; MachineCodeEmitter &MCE; public: - PowerPCCodeEmitter(TargetMachine &T, MachineCodeEmitter &M) + PPC32CodeEmitter(TargetMachine &T, MachineCodeEmitter &M) : TM(T), MCE(M) {} const char *getPassName() const { return "PowerPC Machine Code Emitter"; } @@ -55,17 +56,17 @@ namespace { /// of functions. This method should returns true if machine code emission is /// not supported. /// -bool PowerPCTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM, - MachineCodeEmitter &MCE) { +bool PPC32TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM, + MachineCodeEmitter &MCE) { // Machine code emitter pass for PowerPC - PM.add(new PowerPCCodeEmitter(*this, MCE)); + PM.add(new PPC32CodeEmitter(*this, MCE)); // Delete machine code for this function after emitting it: PM.add(createMachineCodeDeleter()); // We don't yet support machine code emission return true; } -bool PowerPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) { +bool PPC32CodeEmitter::runOnMachineFunction(MachineFunction &MF) { MCE.startFunction(MF); MCE.emitConstantPool(MF.getConstantPool()); for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) @@ -74,24 +75,24 @@ bool PowerPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) { return false; } -void PowerPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { +void PPC32CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I) emitWord(getBinaryCodeForInstr(*I)); } -unsigned PowerPCCodeEmitter::getValueBit(int64_t Val, unsigned bit) { +unsigned PPC32CodeEmitter::getValueBit(int64_t Val, unsigned bit) { Val >>= bit; return (Val & 1); } -void *PowerPCJITInfo::getJITStubForFunction(Function *F, - MachineCodeEmitter &MCE) { - assert (0 && "PowerPCJITInfo::getJITStubForFunction not implemented"); +void *PPC32JITInfo::getJITStubForFunction(Function *F, + MachineCodeEmitter &MCE) { + assert (0 && "PPC32JITInfo::getJITStubForFunction not implemented"); return 0; } -void PowerPCJITInfo::replaceMachineCodeForFunction (void *Old, void *New) { - assert (0 && "PowerPCJITInfo::replaceMachineCodeForFunction not implemented"); +void PPC32JITInfo::replaceMachineCodeForFunction (void *Old, void *New) { + assert (0 && "PPC32JITInfo::replaceMachineCodeForFunction not implemented"); } //#include "PowerPCGenCodeEmitter.inc" diff --git a/lib/Target/PowerPC/PPCTargetMachine.h b/lib/Target/PowerPC/PPCTargetMachine.h new file mode 100644 index 00000000000..4b4d2c548c5 --- /dev/null +++ b/lib/Target/PowerPC/PPCTargetMachine.h @@ -0,0 +1,53 @@ +//===-- PPC32TargetMachine.h - PowerPC/Darwin TargetMachine ---*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the PowerPC/Darwin specific subclass of TargetMachine. +// +//===----------------------------------------------------------------------===// + +#ifndef POWERPC_DARWIN_TARGETMACHINE_H +#define POWERPC_DARWIN_TARGETMACHINE_H + +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetFrameInfo.h" +#include "llvm/PassManager.h" +#include "PowerPCTargetMachine.h" +#include + +namespace llvm { + +class GlobalValue; +class IntrinsicLowering; + +class PPC32TargetMachine : public PowerPCTargetMachine { +public: + PPC32TargetMachine(const Module &M, IntrinsicLowering *IL); + + /// addPassesToEmitMachineCode - Add passes to the specified pass manager to + /// get machine code emitted. This uses a MachineCodeEmitter object to handle + /// actually outputting the machine code and resolving things like the address + /// of functions. This method should returns true if machine code emission is + /// not supported. + /// + virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM, + MachineCodeEmitter &MCE); + + virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out); + + static unsigned getModuleMatchQuality(const Module &M); + + // Two shared sets between the instruction selector and the printer allow for + // correct linkage on Darwin + std::set CalledFunctions; + std::set AddressTaken; +}; + +} // end namespace llvm + +#endif