diff options
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/PowerPC/PPC.h | 9 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCCodeEmitter.cpp | 56 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCMachOWriter.cpp | 41 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCTargetMachine.cpp | 26 | ||||
-rw-r--r-- | lib/Target/X86/X86TargetMachine.cpp | 2 |
5 files changed, 90 insertions, 44 deletions
diff --git a/lib/Target/PowerPC/PPC.h b/lib/Target/PowerPC/PPC.h index 5e8e15c..f34b9b0 100644 --- a/lib/Target/PowerPC/PPC.h +++ b/lib/Target/PowerPC/PPC.h @@ -19,11 +19,18 @@ namespace llvm { -class FunctionPass; class PPCTargetMachine; +class PassManager; +class FunctionPass; +class MachineCodeEmitter; + FunctionPass *createPPCBranchSelectionPass(); FunctionPass *createPPCISelDag(PPCTargetMachine &TM); FunctionPass *createDarwinAsmPrinter(std::ostream &OS, PPCTargetMachine &TM); +FunctionPass *createPPCCodeEmitterPass(PPCTargetMachine &TM, + MachineCodeEmitter &MCE); +void addPPCMachOObjectWriterPass(PassManager &FPM, std::ostream &o, + PPCTargetMachine &tm); } // end namespace llvm; // GCC #defines PPC on Linux but we use it as our namespace name diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index 49d3f25..85697f9 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -21,7 +21,7 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/Passes.h" -#include "llvm/Support/Debug.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/Visibility.h" #include "llvm/Target/TargetOptions.h" #include <iostream> @@ -62,19 +62,11 @@ namespace { }; } -/// 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. -/// -bool PPCTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM, - MachineCodeEmitter &MCE) { - // Machine code emitter pass for PowerPC - PM.add(new PPCCodeEmitter(*this, MCE)); - // Delete machine code for this function after emitting it - PM.add(createMachineCodeDeleter()); - return false; +/// createPPCCodeEmitterPass - Return a pass that emits the collected PPC code +/// to the specified MCE object. +FunctionPass *llvm::createPPCCodeEmitterPass(PPCTargetMachine &TM, + MachineCodeEmitter &MCE) { + return new PPCCodeEmitter(TM, MCE); } #ifdef __APPLE__ @@ -132,7 +124,8 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { } } else if (MO.isImmediate()) { rv = MO.getImmedValue(); - } else if (MO.isGlobalAddress() || MO.isExternalSymbol()) { + } else if (MO.isGlobalAddress() || MO.isExternalSymbol() || + MO.isConstantPoolIndex() || MO.isJumpTableIndex()) { unsigned Reloc = 0; if (MI.getOpcode() == PPC::BL) Reloc = PPC::reloc_pcrel_bx; @@ -141,6 +134,7 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { default: DEBUG(MI.dump()); assert(0 && "Unknown instruction for relocation!"); case PPC::LIS: case PPC::LIS8: + case PPC::ADDIS: case PPC::ADDIS8: Reloc = PPC::reloc_absolute_high; // Pointer to symbol break; @@ -176,9 +170,17 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { if (MO.isGlobalAddress()) MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, MO.getGlobal(), 0)); - else + else if (MO.isExternalSymbol()) MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), Reloc, MO.getSymbolName(), 0)); + else if (MO.isConstantPoolIndex()) + MCE.addRelocation(MachineRelocation::getConstPool( + MCE.getCurrentPCOffset(), + Reloc, MO.getConstantPoolIndex(), 0)); + else // isJumpTableIndex + MCE.addRelocation(MachineRelocation::getJumpTable( + MCE.getCurrentPCOffset(), + Reloc, MO.getJumpTableIndex(), 0)); } else if (MO.isMachineBasicBlock()) { unsigned Reloc = 0; unsigned Opcode = MI.getOpcode(); @@ -190,28 +192,6 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), Reloc, MO.getMachineBasicBlock())); - } else if (MO.isConstantPoolIndex() || MO.isJumpTableIndex()) { - if (MO.isConstantPoolIndex()) - rv = MCE.getConstantPoolEntryAddress(MO.getConstantPoolIndex()); - else - rv = MCE.getJumpTableEntryAddress(MO.getJumpTableIndex()); - - unsigned Opcode = MI.getOpcode(); - if (Opcode == PPC::LIS || Opcode == PPC::LIS8 || - Opcode == PPC::ADDIS || Opcode == PPC::ADDIS8) { - // lis wants hi16(addr) - if ((short)rv < 0) rv += 1 << 16; - rv >>= 16; - } else if (Opcode == PPC::LWZ || Opcode == PPC::LWZ8 || - Opcode == PPC::LA || - Opcode == PPC::LI || Opcode == PPC::LI8 || - Opcode == PPC::LFS || Opcode == PPC::LFD) { - // These load opcodes want lo16(addr) - rv &= 0xffff; - } else { - MI.dump(); - assert(0 && "Unknown constant pool or jump table using instruction!"); - } } else { std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; abort(); diff --git a/lib/Target/PowerPC/PPCMachOWriter.cpp b/lib/Target/PowerPC/PPCMachOWriter.cpp new file mode 100644 index 0000000..29f8238 --- /dev/null +++ b/lib/Target/PowerPC/PPCMachOWriter.cpp @@ -0,0 +1,41 @@ +//===-- PPCMachOWriter.cpp - Emit a Mach-O file for the PowerPC backend ---===// +// +// 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 a Mach-O writer for the PowerPC backend. The public +// interface to this file is the createPPCMachOObjectWriterPass function. +// +//===----------------------------------------------------------------------===// + +#include "PPCTargetMachine.h" +#include "llvm/PassManager.h" +#include "llvm/CodeGen/MachOWriter.h" +#include "llvm/Support/Visibility.h" +using namespace llvm; + +namespace { + class VISIBILITY_HIDDEN PPCMachOWriter : public MachOWriter { + public: + PPCMachOWriter(std::ostream &O, PPCTargetMachine &TM) : MachOWriter(O, TM) { + // FIMXE: choose ppc64 when appropriate + Header.cputype = MachOHeader::CPU_TYPE_POWERPC; + Header.cpusubtype = MachOHeader::CPU_SUBTYPE_POWERPC_ALL; + } + + }; +} + +/// addPPCMachOObjectWriterPass - Returns a pass that outputs the generated code +/// as a Mach-O object file. +/// +void llvm::addPPCMachOObjectWriterPass(PassManager &FPM, + std::ostream &O, PPCTargetMachine &TM) { + PPCMachOWriter *EW = new PPCMachOWriter(O, TM); + FPM.add(EW); + FPM.add(createPPCCodeEmitterPass(TM, EW->getMachineCodeEmitter())); +} diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp index deb479a..e360f37 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -109,11 +109,11 @@ PPC64TargetMachine::PPC64TargetMachine(const Module &M, const std::string &FS) /// addPassesToEmitFile - Add passes to the specified pass manager to implement /// a static compiler for this target. /// -bool PPCTargetMachine::addPassesToEmitFile(PassManager &PM, - std::ostream &Out, +bool PPCTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out, CodeGenFileType FileType, bool Fast) { - if (FileType != TargetMachine::AssemblyFile) return true; + if (FileType != TargetMachine::AssemblyFile && + FileType != TargetMachine::ObjectFile) return true; // Run loop strength reduction before anything else. if (!Fast) PM.add(createLoopStrengthReducePass(&TLInfo)); @@ -146,7 +146,11 @@ bool PPCTargetMachine::addPassesToEmitFile(PassManager &PM, // Must run branch selection immediately preceding the asm printer PM.add(createPPCBranchSelectionPass()); - PM.add(createDarwinAsmPrinter(Out, *this)); + if (FileType == TargetMachine::AssemblyFile) + PM.add(createDarwinAsmPrinter(Out, *this)); + else + // FIXME: support PPC ELF files at some point + addPPCMachOObjectWriterPass(PM, Out, *this); PM.add(createMachineCodeDeleter()); return false; @@ -184,3 +188,17 @@ void PPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) { PM.add(createMachineFunctionPrinterPass(&std::cerr)); } +/// 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. +/// +bool PPCTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM, + MachineCodeEmitter &MCE) { + // Machine code emitter pass for PowerPC + PM.add(createPPCCodeEmitterPass(*this, MCE)); + // Delete machine code for this function after emitting it + PM.add(createMachineCodeDeleter()); + return false; +} diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp index 90175ac..9616dc1 100644 --- a/lib/Target/X86/X86TargetMachine.cpp +++ b/lib/Target/X86/X86TargetMachine.cpp @@ -136,7 +136,7 @@ bool X86TargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out, case TargetMachine::ObjectFile: // FIXME: We only support emission of ELF files for now, this should check // the target triple and decide on the format to write (e.g. COFF on - // win32). + // win32 or Mach-O on darwin). addX86ELFObjectWriterPass(PM, Out, *this); break; } |