diff options
Diffstat (limited to 'lib/Target/PowerPC')
37 files changed, 1015 insertions, 218 deletions
diff --git a/lib/Target/PowerPC/CMakeLists.txt b/lib/Target/PowerPC/CMakeLists.txt index d1dda37..73b4aba 100644 --- a/lib/Target/PowerPC/CMakeLists.txt +++ b/lib/Target/PowerPC/CMakeLists.txt @@ -1,16 +1,16 @@ set(LLVM_TARGET_DEFINITIONS PPC.td) -tablegen(PPCGenAsmWriter.inc -gen-asm-writer) -tablegen(PPCGenCodeEmitter.inc -gen-emitter) -tablegen(PPCGenMCCodeEmitter.inc -gen-emitter -mc-emitter) -tablegen(PPCGenRegisterInfo.inc -gen-register-info) -tablegen(PPCGenInstrInfo.inc -gen-instr-info) -tablegen(PPCGenDAGISel.inc -gen-dag-isel) -tablegen(PPCGenCallingConv.inc -gen-callingconv) -tablegen(PPCGenSubtargetInfo.inc -gen-subtarget) +llvm_tablegen(PPCGenAsmWriter.inc -gen-asm-writer) +llvm_tablegen(PPCGenCodeEmitter.inc -gen-emitter) +llvm_tablegen(PPCGenMCCodeEmitter.inc -gen-emitter -mc-emitter) +llvm_tablegen(PPCGenRegisterInfo.inc -gen-register-info) +llvm_tablegen(PPCGenInstrInfo.inc -gen-instr-info) +llvm_tablegen(PPCGenDAGISel.inc -gen-dag-isel) +llvm_tablegen(PPCGenCallingConv.inc -gen-callingconv) +llvm_tablegen(PPCGenSubtargetInfo.inc -gen-subtarget) +add_public_tablegen_target(PowerPCCommonTableGen) add_llvm_target(PowerPCCodeGen - PPCAsmBackend.cpp PPCAsmPrinter.cpp PPCBranchSelector.cpp PPCCodeEmitter.cpp @@ -20,15 +20,27 @@ add_llvm_target(PowerPCCodeGen PPCISelLowering.cpp PPCFrameLowering.cpp PPCJITInfo.cpp - PPCMCCodeEmitter.cpp PPCMCInstLower.cpp - PPCPredicates.cpp PPCRegisterInfo.cpp PPCSubtarget.cpp PPCTargetMachine.cpp PPCSelectionDAGInfo.cpp ) +add_llvm_library_dependencies(LLVMPowerPCCodeGen + LLVMAnalysis + LLVMAsmPrinter + LLVMCodeGen + LLVMCore + LLVMMC + LLVMPowerPCAsmPrinter + LLVMPowerPCDesc + LLVMPowerPCInfo + LLVMSelectionDAG + LLVMSupport + LLVMTarget + ) + add_subdirectory(InstPrinter) add_subdirectory(TargetInfo) add_subdirectory(MCTargetDesc) diff --git a/lib/Target/PowerPC/InstPrinter/CMakeLists.txt b/lib/Target/PowerPC/InstPrinter/CMakeLists.txt index 389ea77..1d857e2 100644 --- a/lib/Target/PowerPC/InstPrinter/CMakeLists.txt +++ b/lib/Target/PowerPC/InstPrinter/CMakeLists.txt @@ -3,4 +3,10 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/ add_llvm_library(LLVMPowerPCAsmPrinter PPCInstPrinter.cpp ) -add_dependencies(LLVMPowerPCAsmPrinter PowerPCCodeGenTable_gen) + +add_llvm_library_dependencies(LLVMPowerPCAsmPrinter + LLVMMC + LLVMSupport + ) + +add_dependencies(LLVMPowerPCAsmPrinter PowerPCCommonTableGen) diff --git a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp index 1a9bd76..b6a0835 100644 --- a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp +++ b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp @@ -13,7 +13,8 @@ #define DEBUG_TYPE "asm-printer" #include "PPCInstPrinter.h" -#include "PPCPredicates.h" +#include "MCTargetDesc/PPCBaseInfo.h" +#include "MCTargetDesc/PPCPredicates.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/Support/raw_ostream.h" @@ -30,7 +31,8 @@ void PPCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { OS << getRegisterName(RegNo); } -void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O) { +void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O, + StringRef Annot) { // Check for slwi/srwi mnemonics. if (MI->getOpcode() == PPC::RLWINM) { unsigned char SH = MI->getOperand(2).getImm(); @@ -49,6 +51,8 @@ void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O) { O << ", "; printOperand(MI, 1, O); O << ", " << (unsigned int)SH; + + printAnnotation(O, Annot); return; } } @@ -59,6 +63,7 @@ void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O) { printOperand(MI, 0, O); O << ", "; printOperand(MI, 1, O); + printAnnotation(O, Annot); return; } @@ -72,11 +77,13 @@ void PPCInstPrinter::printInst(const MCInst *MI, raw_ostream &O) { O << ", "; printOperand(MI, 1, O); O << ", " << (unsigned int)SH; + printAnnotation(O, Annot); return; } } printInstruction(MI, O); + printAnnotation(O, Annot); } diff --git a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h index d022a44..4ed4b76 100644 --- a/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h +++ b/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h @@ -32,7 +32,7 @@ public: } virtual void printRegName(raw_ostream &OS, unsigned RegNo) const; - virtual void printInst(const MCInst *MI, raw_ostream &O); + virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot); virtual StringRef getOpcodeName(unsigned Opcode) const; static const char *getInstructionName(unsigned Opcode); diff --git a/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt b/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt index a1b8166..c4041db 100644 --- a/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/PowerPC/MCTargetDesc/CMakeLists.txt @@ -1,4 +1,16 @@ add_llvm_library(LLVMPowerPCDesc + PPCAsmBackend.cpp PPCMCTargetDesc.cpp PPCMCAsmInfo.cpp + PPCMCCodeEmitter.cpp + PPCPredicates.cpp ) + +add_llvm_library_dependencies(LLVMPowerPCDesc + LLVMMC + LLVMPowerPCAsmPrinter + LLVMPowerPCInfo + LLVMSupport + ) + +add_dependencies(LLVMPowerPCDesc PowerPCCommonTableGen) diff --git a/lib/Target/PowerPC/PPCAsmBackend.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp index 4b8cbb7..9f2fd6d 100644 --- a/lib/Target/PowerPC/PPCAsmBackend.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp @@ -7,17 +7,43 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Target/TargetAsmBackend.h" -#include "PPC.h" -#include "PPCFixupKinds.h" +#include "llvm/MC/MCAsmBackend.h" +#include "MCTargetDesc/PPCMCTargetDesc.h" +#include "MCTargetDesc/PPCFixupKinds.h" +#include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCMachObjectWriter.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCValue.h" #include "llvm/Object/MachOFormat.h" -#include "llvm/Target/TargetRegistry.h" +#include "llvm/Support/ELF.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TargetRegistry.h" using namespace llvm; +static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { + switch (Kind) { + default: + llvm_unreachable("Unknown fixup kind!"); + case FK_Data_1: + case FK_Data_2: + case FK_Data_4: + return Value; + case PPC::fixup_ppc_brcond14: + return Value & 0x3ffc; + case PPC::fixup_ppc_br24: + return Value & 0x3fffffc; +#if 0 + case PPC::fixup_ppc_hi16: + return (Value >> 16) & 0xffff; +#endif + case PPC::fixup_ppc_ha16: + return ((Value >> 16) + ((Value & 0x8000) ? 1 : 0)) & 0xffff; + case PPC::fixup_ppc_lo16: + return Value & 0xffff; + } +} + namespace { class PPCMachObjectWriter : public MCMachObjectTargetWriter { public: @@ -31,10 +57,17 @@ public: MCValue Target, uint64_t &FixedValue) {} }; -class PPCAsmBackend : public TargetAsmBackend { +class PPCELFObjectWriter : public MCELFObjectTargetWriter { +public: + PPCELFObjectWriter(bool Is64Bit, Triple::OSType OSType, uint16_t EMachine, + bool HasRelocationAddend, bool isLittleEndian) + : MCELFObjectTargetWriter(Is64Bit, OSType, EMachine, HasRelocationAddend) {} +}; + +class PPCAsmBackend : public MCAsmBackend { const Target &TheTarget; public: - PPCAsmBackend(const Target &T) : TargetAsmBackend(), TheTarget(T) {} + PPCAsmBackend(const Target &T) : MCAsmBackend(), TheTarget(T) {} unsigned getNumFixupKinds() const { return PPC::NumTargetFixupKinds; } @@ -49,7 +82,7 @@ public: }; if (Kind < FirstTargetFixupKind) - return TargetAsmBackend::getFixupKindInfo(Kind); + return MCAsmBackend::getFixupKindInfo(Kind); assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && "Invalid kind!"); @@ -109,15 +142,50 @@ namespace { return false; } }; + + class ELFPPCAsmBackend : public PPCAsmBackend { + Triple::OSType OSType; + public: + ELFPPCAsmBackend(const Target &T, Triple::OSType OSType) : + PPCAsmBackend(T), OSType(OSType) { } + + void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, + uint64_t Value) const { + Value = adjustFixupValue(Fixup.getKind(), Value); + if (!Value) return; // Doesn't change encoding. + + unsigned Offset = Fixup.getOffset(); + + // For each byte of the fragment that the fixup touches, mask in the bits from + // the fixup value. The Value has been "split up" into the appropriate + // bitfields above. + for (unsigned i = 0; i != 4; ++i) + Data[Offset + i] |= uint8_t((Value >> ((4 - i - 1)*8)) & 0xff); + } + + MCObjectWriter *createObjectWriter(raw_ostream &OS) const { + bool is64 = getPointerSize() == 8; + return createELFObjectWriter(new PPCELFObjectWriter( + /*Is64Bit=*/is64, + OSType, + is64 ? ELF::EM_PPC64 : ELF::EM_PPC, + /*addend*/ true, /*isLittleEndian*/ false), + OS, /*IsLittleEndian=*/false); + } + + virtual bool doesSectionRequireSymbols(const MCSection &Section) const { + return false; + } + }; + } // end anonymous namespace -TargetAsmBackend *llvm::createPPCAsmBackend(const Target &T, - const std::string &TT) { +MCAsmBackend *llvm::createPPCAsmBackend(const Target &T, StringRef TT) { if (Triple(TT).isOSDarwin()) return new DarwinPPCAsmBackend(T); - return 0; + return new ELFPPCAsmBackend(T, Triple(TT).getOS()); } diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCBaseInfo.h b/lib/Target/PowerPC/MCTargetDesc/PPCBaseInfo.h new file mode 100644 index 0000000..369bbdc --- /dev/null +++ b/lib/Target/PowerPC/MCTargetDesc/PPCBaseInfo.h @@ -0,0 +1,70 @@ +//===-- PPCBaseInfo.h - Top level definitions for PPC -------- --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains small standalone helper functions and enum definitions for +// the PPC target useful for the compiler back-end and the MC libraries. +// As such, it deliberately does not include references to LLVM core +// code gen types, passes, etc.. +// +//===----------------------------------------------------------------------===// + +#ifndef PPCBASEINFO_H +#define PPCBASEINFO_H + +#include "PPCMCTargetDesc.h" +#include "llvm/Support/ErrorHandling.h" + +namespace llvm { + +/// getPPCRegisterNumbering - Given the enum value for some register, e.g. +/// PPC::F14, return the number that it corresponds to (e.g. 14). +inline static unsigned getPPCRegisterNumbering(unsigned RegEnum) { + using namespace PPC; + switch (RegEnum) { + case 0: return 0; + case R0 : case X0 : case F0 : case V0 : case CR0: case CR0LT: return 0; + case R1 : case X1 : case F1 : case V1 : case CR1: case CR0GT: return 1; + case R2 : case X2 : case F2 : case V2 : case CR2: case CR0EQ: return 2; + case R3 : case X3 : case F3 : case V3 : case CR3: case CR0UN: return 3; + case R4 : case X4 : case F4 : case V4 : case CR4: case CR1LT: return 4; + case R5 : case X5 : case F5 : case V5 : case CR5: case CR1GT: return 5; + case R6 : case X6 : case F6 : case V6 : case CR6: case CR1EQ: return 6; + case R7 : case X7 : case F7 : case V7 : case CR7: case CR1UN: return 7; + case R8 : case X8 : case F8 : case V8 : case CR2LT: return 8; + case R9 : case X9 : case F9 : case V9 : case CR2GT: return 9; + case R10: case X10: case F10: case V10: case CR2EQ: return 10; + case R11: case X11: case F11: case V11: case CR2UN: return 11; + case R12: case X12: case F12: case V12: case CR3LT: return 12; + case R13: case X13: case F13: case V13: case CR3GT: return 13; + case R14: case X14: case F14: case V14: case CR3EQ: return 14; + case R15: case X15: case F15: case V15: case CR3UN: return 15; + case R16: case X16: case F16: case V16: case CR4LT: return 16; + case R17: case X17: case F17: case V17: case CR4GT: return 17; + case R18: case X18: case F18: case V18: case CR4EQ: return 18; + case R19: case X19: case F19: case V19: case CR4UN: return 19; + case R20: case X20: case F20: case V20: case CR5LT: return 20; + case R21: case X21: case F21: case V21: case CR5GT: return 21; + case R22: case X22: case F22: case V22: case CR5EQ: return 22; + case R23: case X23: case F23: case V23: case CR5UN: return 23; + case R24: case X24: case F24: case V24: case CR6LT: return 24; + case R25: case X25: case F25: case V25: case CR6GT: return 25; + case R26: case X26: case F26: case V26: case CR6EQ: return 26; + case R27: case X27: case F27: case V27: case CR6UN: return 27; + case R28: case X28: case F28: case V28: case CR7LT: return 28; + case R29: case X29: case F29: case V29: case CR7GT: return 29; + case R30: case X30: case F30: case V30: case CR7EQ: return 30; + case R31: case X31: case F31: case V31: case CR7UN: return 31; + default: + llvm_unreachable("Unhandled reg in PPCRegisterInfo::getRegisterNumbering!"); + } +} + +} // end namespace llvm; + +#endif diff --git a/lib/Target/PowerPC/PPCFixupKinds.h b/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h index b3c889e..b3c889e 100644 --- a/lib/Target/PowerPC/PPCFixupKinds.h +++ b/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp index b6dca83..e9424d8 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp @@ -31,6 +31,10 @@ PPCMCAsmInfoDarwin::PPCMCAsmInfoDarwin(bool is64Bit) { } PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) { + if (is64Bit) + PointerSize = 8; + IsLittleEndian = false; + // ".comm align is in bytes but .align is pow-2." AlignmentIsInBytes = false; @@ -56,7 +60,7 @@ PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) { ZeroDirective = "\t.space\t"; Data64bitsDirective = is64Bit ? "\t.quad\t" : 0; - HasLCOMMDirective = true; + LCOMMDirectiveType = LCOMM::NoAlignment; AssemblerDialect = 0; // Old-Style mnemonics. } diff --git a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp index cf73d86..262f97c 100644 --- a/lib/Target/PowerPC/PPCMCCodeEmitter.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp @@ -12,9 +12,8 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "mccodeemitter" -#include "PPC.h" -#include "PPCRegisterInfo.h" -#include "PPCFixupKinds.h" +#include "MCTargetDesc/PPCBaseInfo.h" +#include "MCTargetDesc/PPCFixupKinds.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCInst.h" #include "llvm/ADT/Statistic.h" @@ -170,7 +169,7 @@ get_crbitm_encoding(const MCInst &MI, unsigned OpNo, const MCOperand &MO = MI.getOperand(OpNo); assert((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MFOCRF) && (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)); - return 0x80 >> PPCRegisterInfo::getRegisterNumbering(MO.getReg()); + return 0x80 >> getPPCRegisterNumbering(MO.getReg()); } @@ -182,7 +181,7 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO, // The GPR operand should come through here though. assert((MI.getOpcode() != PPC::MTCRF && MI.getOpcode() != PPC::MFOCRF) || MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7); - return PPCRegisterInfo::getRegisterNumbering(MO.getReg()); + return getPPCRegisterNumbering(MO.getReg()); } assert(MO.isImm() && diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp index 484bb1a..d5c8a9e 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp @@ -13,11 +13,14 @@ #include "PPCMCTargetDesc.h" #include "PPCMCAsmInfo.h" +#include "InstPrinter/PPCInstPrinter.h" #include "llvm/MC/MachineLocation.h" +#include "llvm/MC/MCCodeGenInfo.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/Target/TargetRegistry.h" +#include "llvm/Support/TargetRegistry.h" #define GET_INSTRINFO_MC_DESC #include "PPCGenInstrInfo.inc" @@ -36,11 +39,6 @@ static MCInstrInfo *createPPCMCInstrInfo() { return X; } -extern "C" void LLVMInitializePowerPCMCInstrInfo() { - TargetRegistry::RegisterMCInstrInfo(ThePPC32Target, createPPCMCInstrInfo); - TargetRegistry::RegisterMCInstrInfo(ThePPC64Target, createPPCMCInstrInfo); -} - static MCRegisterInfo *createPPCMCRegisterInfo(StringRef TT) { Triple TheTriple(TT); bool isPPC64 = (TheTriple.getArch() == Triple::ppc64); @@ -52,11 +50,6 @@ static MCRegisterInfo *createPPCMCRegisterInfo(StringRef TT) { return X; } -extern "C" void LLVMInitializePowerPCMCRegisterInfo() { - TargetRegistry::RegisterMCRegInfo(ThePPC32Target, createPPCMCRegisterInfo); - TargetRegistry::RegisterMCRegInfo(ThePPC64Target, createPPCMCRegisterInfo); -} - static MCSubtargetInfo *createPPCMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS) { MCSubtargetInfo *X = new MCSubtargetInfo(); @@ -64,13 +57,6 @@ static MCSubtargetInfo *createPPCMCSubtargetInfo(StringRef TT, StringRef CPU, return X; } -extern "C" void LLVMInitializePowerPCMCSubtargetInfo() { - TargetRegistry::RegisterMCSubtargetInfo(ThePPC32Target, - createPPCMCSubtargetInfo); - TargetRegistry::RegisterMCSubtargetInfo(ThePPC64Target, - createPPCMCSubtargetInfo); -} - static MCAsmInfo *createPPCMCAsmInfo(const Target &T, StringRef TT) { Triple TheTriple(TT); bool isPPC64 = TheTriple.getArch() == Triple::ppc64; @@ -89,12 +75,8 @@ static MCAsmInfo *createPPCMCAsmInfo(const Target &T, StringRef TT) { return MAI; } -extern "C" void LLVMInitializePowerPCMCAsmInfo() { - RegisterMCAsmInfoFn C(ThePPC32Target, createPPCMCAsmInfo); - RegisterMCAsmInfoFn D(ThePPC64Target, createPPCMCAsmInfo); -} - -MCCodeGenInfo *createPPCMCCodeGenInfo(StringRef TT, Reloc::Model RM) { +static MCCodeGenInfo *createPPCMCCodeGenInfo(StringRef TT, Reloc::Model RM, + CodeModel::Model CM) { MCCodeGenInfo *X = new MCCodeGenInfo(); if (RM == Reloc::Default) { @@ -104,11 +86,66 @@ MCCodeGenInfo *createPPCMCCodeGenInfo(StringRef TT, Reloc::Model RM) { else RM = Reloc::Static; } - X->InitMCCodeGenInfo(RM); + X->InitMCCodeGenInfo(RM, CM); return X; } -extern "C" void LLVMInitializePowerPCMCCodeGenInfo() { +// This is duplicated code. Refactor this. +static MCStreamer *createMCStreamer(const Target &T, StringRef TT, + MCContext &Ctx, MCAsmBackend &MAB, + raw_ostream &OS, + MCCodeEmitter *Emitter, + bool RelaxAll, + bool NoExecStack) { + if (Triple(TT).isOSDarwin()) + return createMachOStreamer(Ctx, MAB, OS, Emitter, RelaxAll); + + return createELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack); +} + +static MCInstPrinter *createPPCMCInstPrinter(const Target &T, + unsigned SyntaxVariant, + const MCAsmInfo &MAI, + const MCSubtargetInfo &STI) { + return new PPCInstPrinter(MAI, SyntaxVariant); +} + +extern "C" void LLVMInitializePowerPCTargetMC() { + // Register the MC asm info. + RegisterMCAsmInfoFn C(ThePPC32Target, createPPCMCAsmInfo); + RegisterMCAsmInfoFn D(ThePPC64Target, createPPCMCAsmInfo); + + // Register the MC codegen info. TargetRegistry::RegisterMCCodeGenInfo(ThePPC32Target, createPPCMCCodeGenInfo); TargetRegistry::RegisterMCCodeGenInfo(ThePPC64Target, createPPCMCCodeGenInfo); + + // Register the MC instruction info. + TargetRegistry::RegisterMCInstrInfo(ThePPC32Target, createPPCMCInstrInfo); + TargetRegistry::RegisterMCInstrInfo(ThePPC64Target, createPPCMCInstrInfo); + + // Register the MC register info. + TargetRegistry::RegisterMCRegInfo(ThePPC32Target, createPPCMCRegisterInfo); + TargetRegistry::RegisterMCRegInfo(ThePPC64Target, createPPCMCRegisterInfo); + + // Register the MC subtarget info. + TargetRegistry::RegisterMCSubtargetInfo(ThePPC32Target, + createPPCMCSubtargetInfo); + TargetRegistry::RegisterMCSubtargetInfo(ThePPC64Target, + createPPCMCSubtargetInfo); + + // Register the MC Code Emitter + TargetRegistry::RegisterMCCodeEmitter(ThePPC32Target, createPPCMCCodeEmitter); + TargetRegistry::RegisterMCCodeEmitter(ThePPC64Target, createPPCMCCodeEmitter); + + // Register the asm backend. + TargetRegistry::RegisterMCAsmBackend(ThePPC32Target, createPPCAsmBackend); + TargetRegistry::RegisterMCAsmBackend(ThePPC64Target, createPPCAsmBackend); + + // Register the object streamer. + TargetRegistry::RegisterMCObjectStreamer(ThePPC32Target, createMCStreamer); + TargetRegistry::RegisterMCObjectStreamer(ThePPC64Target, createMCStreamer); + + // Register the MCInstPrinter. + TargetRegistry::RegisterMCInstPrinter(ThePPC32Target, createPPCMCInstPrinter); + TargetRegistry::RegisterMCInstPrinter(ThePPC64Target, createPPCMCInstPrinter); } diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h index cee2350..e5bf2a9 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h @@ -15,6 +15,10 @@ #define PPCMCTARGETDESC_H namespace llvm { +class MCAsmBackend; +class MCCodeEmitter; +class MCContext; +class MCInstrInfo; class MCSubtargetInfo; class Target; class StringRef; @@ -22,6 +26,12 @@ class StringRef; extern Target ThePPC32Target; extern Target ThePPC64Target; +MCCodeEmitter *createPPCMCCodeEmitter(const MCInstrInfo &MCII, + const MCSubtargetInfo &STI, + MCContext &Ctx); + +MCAsmBackend *createPPCAsmBackend(const Target &T, StringRef TT); + } // End llvm namespace // Defines symbolic names for PowerPC registers. This defines a mapping from diff --git a/lib/Target/PowerPC/PPCPredicates.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.cpp index 12bb0a1..12bb0a1 100644 --- a/lib/Target/PowerPC/PPCPredicates.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.cpp diff --git a/lib/Target/PowerPC/PPCPredicates.h b/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h index b2c8315..f872e86 100644 --- a/lib/Target/PowerPC/PPCPredicates.h +++ b/lib/Target/PowerPC/MCTargetDesc/PPCPredicates.h @@ -14,8 +14,6 @@ #ifndef LLVM_TARGET_POWERPC_PPCPREDICATES_H #define LLVM_TARGET_POWERPC_PPCPREDICATES_H -#include "PPC.h" - namespace llvm { namespace PPC { /// Predicate - These are "(BI << 5) | BO" for various predicates. diff --git a/lib/Target/PowerPC/PPC.h b/lib/Target/PowerPC/PPC.h index 7191dd1..5dc1863 100644 --- a/lib/Target/PowerPC/PPC.h +++ b/lib/Target/PowerPC/PPC.h @@ -15,6 +15,7 @@ #ifndef LLVM_TARGET_POWERPC_H #define LLVM_TARGET_POWERPC_H +#include "MCTargetDesc/PPCBaseInfo.h" #include "MCTargetDesc/PPCMCTargetDesc.h" #include <string> @@ -30,22 +31,12 @@ namespace llvm { class MachineInstr; class AsmPrinter; class MCInst; - class MCCodeEmitter; - class MCContext; - class MCInstrInfo; - class MCSubtargetInfo; class TargetMachine; - class TargetAsmBackend; FunctionPass *createPPCBranchSelectionPass(); FunctionPass *createPPCISelDag(PPCTargetMachine &TM); FunctionPass *createPPCJITCodeEmitterPass(PPCTargetMachine &TM, JITCodeEmitter &MCE); - MCCodeEmitter *createPPCMCCodeEmitter(const MCInstrInfo &MCII, - const MCSubtargetInfo &STI, - MCContext &Ctx); - TargetAsmBackend *createPPCAsmBackend(const Target &, const std::string &); - void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP, bool isDarwin); diff --git a/lib/Target/PowerPC/PPC.td b/lib/Target/PowerPC/PPC.td index aabf494..367f9cc 100644 --- a/lib/Target/PowerPC/PPC.td +++ b/lib/Target/PowerPC/PPC.td @@ -23,6 +23,7 @@ include "llvm/Target/Target.td" // CPU Directives // //===----------------------------------------------------------------------===// +def Directive440 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_440", "">; def Directive601 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_601", "">; def Directive602 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_602", "">; def Directive603 : SubtargetFeature<"", "DarwinDirective", "PPC::DIR_603", "">; @@ -43,9 +44,11 @@ def FeatureAltivec : SubtargetFeature<"altivec","HasAltivec", "true", def FeatureGPUL : SubtargetFeature<"gpul","IsGigaProcessor", "true", "Enable GPUL instructions">; def FeatureFSqrt : SubtargetFeature<"fsqrt","HasFSQRT", "true", - "Enable the fsqrt instruction">; + "Enable the fsqrt instruction">; def FeatureSTFIWX : SubtargetFeature<"stfiwx","HasSTFIWX", "true", - "Enable the stfiwx instruction">; + "Enable the stfiwx instruction">; +def FeatureBookE : SubtargetFeature<"booke", "IsBookE", "true", + "Enable Book E instructions">; //===----------------------------------------------------------------------===// // Register File Description @@ -60,6 +63,8 @@ include "PPCInstrInfo.td" // def : Processor<"generic", G3Itineraries, [Directive32]>; +def : Processor<"440", PPC440Itineraries, [Directive440, FeatureBookE]>; +def : Processor<"450", PPC440Itineraries, [Directive440, FeatureBookE]>; def : Processor<"601", G3Itineraries, [Directive601]>; def : Processor<"602", G3Itineraries, [Directive602]>; def : Processor<"603", G3Itineraries, [Directive603]>; diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index 9de2200..b8aad8f 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -18,9 +18,9 @@ #define DEBUG_TYPE "asmprinter" #include "PPC.h" -#include "PPCPredicates.h" #include "PPCTargetMachine.h" #include "PPCSubtarget.h" +#include "MCTargetDesc/PPCPredicates.h" #include "llvm/Analysis/DebugInfo.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" @@ -43,11 +43,11 @@ #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetRegistry.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSet.h" @@ -374,6 +374,12 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); OutStreamer.EmitInstruction(TmpInst); return; + case PPC::SYNC: + // In Book E sync is called msync, handle this special case here... + if (Subtarget.isBookE()) { + OutStreamer.EmitRawText(StringRef("\tmsync")); + return; + } } LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); @@ -421,6 +427,7 @@ void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) { static const char *const CPUDirectives[] = { "", "ppc", + "ppc440", "ppc601", "ppc602", "ppc603", @@ -679,18 +686,8 @@ static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm, return new PPCLinuxAsmPrinter(tm, Streamer); } -static MCInstPrinter *createPPCMCInstPrinter(const Target &T, - unsigned SyntaxVariant, - const MCAsmInfo &MAI) { - return new PPCInstPrinter(MAI, SyntaxVariant); -} - - // Force static initialization. extern "C" void LLVMInitializePowerPCAsmPrinter() { TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass); TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass); - - TargetRegistry::RegisterMCInstPrinter(ThePPC32Target, createPPCMCInstPrinter); - TargetRegistry::RegisterMCInstPrinter(ThePPC64Target, createPPCMCInstPrinter); } diff --git a/lib/Target/PowerPC/PPCBranchSelector.cpp b/lib/Target/PowerPC/PPCBranchSelector.cpp index e161d23..475edf3 100644 --- a/lib/Target/PowerPC/PPCBranchSelector.cpp +++ b/lib/Target/PowerPC/PPCBranchSelector.cpp @@ -19,7 +19,7 @@ #include "PPC.h" #include "PPCInstrBuilder.h" #include "PPCInstrInfo.h" -#include "PPCPredicates.h" +#include "MCTargetDesc/PPCPredicates.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/Target/TargetMachine.h" #include "llvm/ADT/Statistic.h" diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index 42232a0..4a1f182 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -140,7 +140,7 @@ unsigned PPCCodeEmitter::get_crbitm_encoding(const MachineInstr &MI, const MachineOperand &MO = MI.getOperand(OpNo); assert((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MFOCRF) && (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)); - return 0x80 >> PPCRegisterInfo::getRegisterNumbering(MO.getReg()); + return 0x80 >> getPPCRegisterNumbering(MO.getReg()); } MachineRelocation PPCCodeEmitter::GetRelocation(const MachineOperand &MO, @@ -250,7 +250,7 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI, // The GPR operand should come through here though. assert((MI.getOpcode() != PPC::MTCRF && MI.getOpcode() != PPC::MFOCRF) || MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7); - return PPCRegisterInfo::getRegisterNumbering(MO.getReg()); + return getPPCRegisterNumbering(MO.getReg()); } assert(MO.isImm() && diff --git a/lib/Target/PowerPC/PPCFrameLowering.cpp b/lib/Target/PowerPC/PPCFrameLowering.cpp index 8dd6cba..7dead10 100644 --- a/lib/Target/PowerPC/PPCFrameLowering.cpp +++ b/lib/Target/PowerPC/PPCFrameLowering.cpp @@ -109,14 +109,14 @@ static void HandleVRSaveUpdate(MachineInstr *MI, const TargetInstrInfo &TII) { for (MachineRegisterInfo::livein_iterator I = MF->getRegInfo().livein_begin(), E = MF->getRegInfo().livein_end(); I != E; ++I) { - unsigned RegNo = PPCRegisterInfo::getRegisterNumbering(I->first); + unsigned RegNo = getPPCRegisterNumbering(I->first); if (VRRegNo[RegNo] == I->first) // If this really is a vector reg. UsedRegMask &= ~(1 << (31-RegNo)); // Doesn't need to be marked. } for (MachineRegisterInfo::liveout_iterator I = MF->getRegInfo().liveout_begin(), E = MF->getRegInfo().liveout_end(); I != E; ++I) { - unsigned RegNo = PPCRegisterInfo::getRegisterNumbering(*I); + unsigned RegNo = getPPCRegisterNumbering(*I); if (VRRegNo[RegNo] == *I) // If this really is a vector reg. UsedRegMask &= ~(1 << (31-RegNo)); // Doesn't need to be marked. } @@ -878,7 +878,7 @@ void PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF) FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); } - LowerBound -= (31 - PPCRegisterInfo::getRegisterNumbering(MinFPR) + 1) * 8; + LowerBound -= (31 - getPPCRegisterNumbering(MinFPR) + 1) * 8; } // Check whether the frame pointer register is allocated. If so, make sure it @@ -912,8 +912,8 @@ void PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF) } unsigned MinReg = - std::min<unsigned>(PPCRegisterInfo::getRegisterNumbering(MinGPR), - PPCRegisterInfo::getRegisterNumbering(MinG8R)); + std::min<unsigned>(getPPCRegisterNumbering(MinGPR), + getPPCRegisterNumbering(MinG8R)); if (Subtarget.isPPC64()) { LowerBound -= (31 - MinReg + 1) * 8; diff --git a/lib/Target/PowerPC/PPCHazardRecognizers.cpp b/lib/Target/PowerPC/PPCHazardRecognizers.cpp index cddc9d8..3197fc8 100644 --- a/lib/Target/PowerPC/PPCHazardRecognizers.cpp +++ b/lib/Target/PowerPC/PPCHazardRecognizers.cpp @@ -22,6 +22,19 @@ using namespace llvm; //===----------------------------------------------------------------------===// +// PowerPC 440 Hazard Recognizer +void PPCHazardRecognizer440::EmitInstruction(SUnit *SU) { + const MCInstrDesc *MCID = DAG->getInstrDesc(SU); + if (!MCID) { + // This is a PPC pseudo-instruction. + // FIXME: Should something else be done? + return; + } + + ScoreboardHazardRecognizer::EmitInstruction(SU); +} + +//===----------------------------------------------------------------------===// // PowerPC 970 Hazard Recognizer // // This models the dispatch group formation of the PPC970 processor. Dispatch diff --git a/lib/Target/PowerPC/PPCHazardRecognizers.h b/lib/Target/PowerPC/PPCHazardRecognizers.h index 2f81f0f..32fac91 100644 --- a/lib/Target/PowerPC/PPCHazardRecognizers.h +++ b/lib/Target/PowerPC/PPCHazardRecognizers.h @@ -15,11 +15,24 @@ #define PPCHAZRECS_H #include "llvm/CodeGen/ScheduleHazardRecognizer.h" +#include "llvm/CodeGen/ScoreboardHazardRecognizer.h" #include "llvm/CodeGen/SelectionDAGNodes.h" #include "PPCInstrInfo.h" namespace llvm { +/// PPCHazardRecognizer440 - This class implements a scoreboard-based +/// hazard recognizer for the PPC 440 and friends. +class PPCHazardRecognizer440 : public ScoreboardHazardRecognizer { + const ScheduleDAG *DAG; +public: + PPCHazardRecognizer440(const InstrItineraryData *ItinData, + const ScheduleDAG *DAG_) : + ScoreboardHazardRecognizer(ItinData, DAG_), DAG(DAG_) {} + + virtual void EmitInstruction(SUnit *SU); +}; + /// PPCHazardRecognizer970 - This class defines a finite state automata that /// models the dispatch logic on the PowerPC 970 (aka G5) processor. This /// promotes good dispatch group formation and implements noop insertion to diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 2176c02..6f204cc 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -14,8 +14,8 @@ #define DEBUG_TYPE "ppc-codegen" #include "PPC.h" -#include "PPCPredicates.h" #include "PPCTargetMachine.h" +#include "MCTargetDesc/PPCPredicates.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionAnalysis.h" diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index f97c467..d6b8a9e 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -14,8 +14,8 @@ #include "PPCISelLowering.h" #include "PPCMachineFunctionInfo.h" #include "PPCPerfectShuffle.h" -#include "PPCPredicates.h" #include "PPCTargetMachine.h" +#include "MCTargetDesc/PPCPredicates.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/VectorExtras.h" #include "llvm/CodeGen/CallingConvLower.h" @@ -211,7 +211,8 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM) setOperationAction(ISD::TRAP, MVT::Other, Legal); // TRAMPOLINE is custom lowered. - setOperationAction(ISD::TRAMPOLINE, MVT::Other, Custom); + setOperationAction(ISD::INIT_TRAMPOLINE, MVT::Other, Custom); + setOperationAction(ISD::ADJUST_TRAMPOLINE, MVT::Other, Custom); // VASTART needs to be custom lowered to use the VarArgsFrameIndex setOperationAction(ISD::VASTART , MVT::Other, Custom); @@ -365,7 +366,11 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM) setOperationAction(ISD::BUILD_VECTOR, MVT::v4f32, Custom); } + setOperationAction(ISD::ATOMIC_LOAD, MVT::i32, Expand); + setOperationAction(ISD::ATOMIC_STORE, MVT::i32, Expand); + setBooleanContents(ZeroOrOneBooleanContent); + setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct? if (TM.getSubtarget<PPCSubtarget>().isPPC64()) { setStackPointerRegisterToSaveRestore(PPC::X1); @@ -401,6 +406,8 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM) if (PPCSubTarget.isDarwin()) setPrefFunctionAlignment(4); + setInsertFencesForAtomic(true); + computeRegisterProperties(); } @@ -463,7 +470,7 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const { } } -MVT::SimpleValueType PPCTargetLowering::getSetCCResultType(EVT VT) const { +EVT PPCTargetLowering::getSetCCResultType(EVT VT) const { return MVT::i32; } @@ -1368,8 +1375,13 @@ SDValue PPCTargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG, return DAG.getLoad(VT, dl, InChain, Result, MachinePointerInfo(), false, false, 0); } -SDValue PPCTargetLowering::LowerTRAMPOLINE(SDValue Op, - SelectionDAG &DAG) const { +SDValue PPCTargetLowering::LowerADJUST_TRAMPOLINE(SDValue Op, + SelectionDAG &DAG) const { + return Op.getOperand(0); +} + +SDValue PPCTargetLowering::LowerINIT_TRAMPOLINE(SDValue Op, + SelectionDAG &DAG) const { SDValue Chain = Op.getOperand(0); SDValue Trmp = Op.getOperand(1); // trampoline SDValue FPtr = Op.getOperand(2); // nested function @@ -1398,16 +1410,13 @@ SDValue PPCTargetLowering::LowerTRAMPOLINE(SDValue Op, // Lower to a call to __trampoline_setup(Trmp, TrampSize, FPtr, ctx_reg) std::pair<SDValue, SDValue> CallResult = - LowerCallTo(Chain, Op.getValueType().getTypeForEVT(*DAG.getContext()), + LowerCallTo(Chain, Type::getVoidTy(*DAG.getContext()), false, false, false, false, 0, CallingConv::C, false, /*isReturnValueUsed=*/true, DAG.getExternalSymbol("__trampoline_setup", PtrVT), Args, DAG, dl); - SDValue Ops[] = - { CallResult.first, CallResult.second }; - - return DAG.getMergeValues(Ops, 2, dl); + return CallResult.second; } SDValue PPCTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG, @@ -2550,7 +2559,7 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag, if (!DAG.getTarget().getSubtarget<PPCSubtarget>().isJITCodeModel()) { unsigned OpFlags = 0; if (DAG.getTarget().getRelocationModel() != Reloc::Static && - (!PPCSubTarget.getTargetTriple().isMacOSX() || + (PPCSubTarget.getTargetTriple().isMacOSX() && PPCSubTarget.getTargetTriple().isMacOSXVersionLT(10, 5)) && (G->getGlobal()->isDeclaration() || G->getGlobal()->isWeakForLinker())) { @@ -2574,7 +2583,7 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag, unsigned char OpFlags = 0; if (DAG.getTarget().getRelocationModel() != Reloc::Static && - (!PPCSubTarget.getTargetTriple().isMacOSX() || + (PPCSubTarget.getTargetTriple().isMacOSX() && PPCSubTarget.getTargetTriple().isMacOSXVersionLT(10, 5))) { // PC-relative references to external symbols should go through $stub, // unless we're building with the leopard linker or later, which @@ -2941,6 +2950,7 @@ PPCTargetLowering::LowerCall_SVR4(SDValue Chain, SDValue Callee, SmallVector<TailCallArgumentInfo, 8> TailCallArguments; SmallVector<SDValue, 8> MemOpChains; + bool seenFloatArg = false; // Walk the register/memloc assignments, inserting copies/loads. for (unsigned i = 0, j = 0, e = ArgLocs.size(); i != e; @@ -2985,6 +2995,7 @@ PPCTargetLowering::LowerCall_SVR4(SDValue Chain, SDValue Callee, } if (VA.isRegLoc()) { + seenFloatArg |= VA.getLocVT().isFloatingPoint(); // Put argument in a physical register. RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); } else { @@ -3011,9 +3022,11 @@ PPCTargetLowering::LowerCall_SVR4(SDValue Chain, SDValue Callee, Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &MemOpChains[0], MemOpChains.size()); - // Set CR6 to true if this is a vararg call. + // Set CR6 to true if this is a vararg call with floating args passed in + // registers. if (isVarArg) { - SDValue SetCR(DAG.getMachineNode(PPC::CRSET, dl, MVT::i32), 0); + SDValue SetCR(DAG.getMachineNode(seenFloatArg ? PPC::CRSET : PPC::CRUNSET, + dl, MVT::i32), 0); RegsToPass.push_back(std::make_pair(unsigned(PPC::CR1EQ), SetCR)); } @@ -3403,6 +3416,17 @@ PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee, Ins, InVals); } +bool +PPCTargetLowering::CanLowerReturn(CallingConv::ID CallConv, + MachineFunction &MF, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + LLVMContext &Context) const { + SmallVector<CCValAssign, 16> RVLocs; + CCState CCInfo(CallConv, isVarArg, MF, getTargetMachine(), + RVLocs, Context); + return CCInfo.CheckReturn(Outs, RetCC_PPC); +} + SDValue PPCTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, @@ -4490,7 +4514,8 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::GlobalTLSAddress: llvm_unreachable("TLS not implemented for PPC"); case ISD::JumpTable: return LowerJumpTable(Op, DAG); case ISD::SETCC: return LowerSETCC(Op, DAG); - case ISD::TRAMPOLINE: return LowerTRAMPOLINE(Op, DAG); + case ISD::INIT_TRAMPOLINE: return LowerINIT_TRAMPOLINE(Op, DAG); + case ISD::ADJUST_TRAMPOLINE: return LowerADJUST_TRAMPOLINE(Op, DAG); case ISD::VASTART: return LowerVASTART(Op, DAG, PPCSubTarget); diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index a4f8e2a..430e45e 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -246,7 +246,7 @@ namespace llvm { virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i32; } /// getSetCCResultType - Return the ISD::SETCC ValueType - virtual MVT::SimpleValueType getSetCCResultType(EVT VT) const; + virtual EVT getSetCCResultType(EVT VT) const; /// getPreIndexedAddressParts - returns true by value, base pointer and /// offset pointer and addressing mode by reference if the node's address @@ -390,7 +390,8 @@ namespace llvm { SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; - SDValue LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget) const; SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG, @@ -444,6 +445,12 @@ namespace llvm { DebugLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const; + virtual bool + CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, + bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + LLVMContext &Context) const; + virtual SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index 143444f..649a45a 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -15,18 +15,18 @@ #include "PPC.h" #include "PPCInstrBuilder.h" #include "PPCMachineFunctionInfo.h" -#include "PPCPredicates.h" #include "PPCTargetMachine.h" #include "PPCHazardRecognizers.h" +#include "MCTargetDesc/PPCPredicates.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/MC/MCAsmInfo.h" -#include "llvm/Target/TargetRegistry.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/STLExtras.h" @@ -53,7 +53,15 @@ ScheduleHazardRecognizer *PPCInstrInfo::CreateTargetHazardRecognizer( // now, always return a PPC970 recognizer. const TargetInstrInfo *TII = TM->getInstrInfo(); assert(TII && "No InstrInfo?"); - return new PPCHazardRecognizer970(*TII); + + unsigned Directive = TM->getSubtarget<PPCSubtarget>().getDarwinDirective(); + if (Directive == PPC::DIR_440) { + const InstrItineraryData *II = TM->getInstrItineraryData(); + return new PPCHazardRecognizer440(II, DAG); + } + else { + return new PPCHazardRecognizer970(*TII); + } } unsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, @@ -334,7 +342,7 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, const TargetRegisterClass *RC, SmallVectorImpl<MachineInstr*> &NewMIs) const{ DebugLoc DL; - if (RC == PPC::GPRCRegisterClass) { + if (PPC::GPRCRegisterClass->hasSubClassEq(RC)) { if (SrcReg != PPC::LR) { NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STW)) .addReg(SrcReg, @@ -350,7 +358,7 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, getKillRegState(isKill)), FrameIdx)); } - } else if (RC == PPC::G8RCRegisterClass) { + } else if (PPC::G8RCRegisterClass->hasSubClassEq(RC)) { if (SrcReg != PPC::LR8) { NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STD)) .addReg(SrcReg, @@ -366,17 +374,17 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, getKillRegState(isKill)), FrameIdx)); } - } else if (RC == PPC::F8RCRegisterClass) { + } else if (PPC::F8RCRegisterClass->hasSubClassEq(RC)) { NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STFD)) .addReg(SrcReg, getKillRegState(isKill)), FrameIdx)); - } else if (RC == PPC::F4RCRegisterClass) { + } else if (PPC::F4RCRegisterClass->hasSubClassEq(RC)) { NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STFS)) .addReg(SrcReg, getKillRegState(isKill)), FrameIdx)); - } else if (RC == PPC::CRRCRegisterClass) { + } else if (PPC::CRRCRegisterClass->hasSubClassEq(RC)) { if ((EnablePPC32RS && !TM.getSubtargetImpl()->isPPC64()) || (EnablePPC64RS && TM.getSubtargetImpl()->isPPC64())) { // FIXME (64-bit): Enable @@ -402,7 +410,7 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, // If the saved register wasn't CR0, shift the bits left so that they are // in CR0's slot. if (SrcReg != PPC::CR0) { - unsigned ShiftBits = PPCRegisterInfo::getRegisterNumbering(SrcReg)*4; + unsigned ShiftBits = getPPCRegisterNumbering(SrcReg)*4; // rlwinm scratch, scratch, ShiftBits, 0, 31. NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), ScratchReg) .addReg(ScratchReg).addImm(ShiftBits) @@ -414,7 +422,7 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, getKillRegState(isKill)), FrameIdx)); } - } else if (RC == PPC::CRBITRCRegisterClass) { + } else if (PPC::CRBITRCRegisterClass->hasSubClassEq(RC)) { // FIXME: We use CRi here because there is no mtcrf on a bit. Since the // backend currently only uses CR1EQ as an individual bit, this should // not cause any bug. If we need other uses of CR bits, the following @@ -448,7 +456,7 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, return StoreRegToStackSlot(MF, Reg, isKill, FrameIdx, PPC::CRRCRegisterClass, NewMIs); - } else if (RC == PPC::VRRCRegisterClass) { + } else if (PPC::VRRCRegisterClass->hasSubClassEq(RC)) { // We don't have indexed addressing for vector loads. Emit: // R0 = ADDI FI# // STVX VAL, 0, R0 @@ -499,7 +507,7 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, SmallVectorImpl<MachineInstr*> &NewMIs)const{ - if (RC == PPC::GPRCRegisterClass) { + if (PPC::GPRCRegisterClass->hasSubClassEq(RC)) { if (DestReg != PPC::LR) { NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ), DestReg), FrameIdx)); @@ -508,7 +516,7 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, PPC::R11), FrameIdx)); NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTLR)).addReg(PPC::R11)); } - } else if (RC == PPC::G8RCRegisterClass) { + } else if (PPC::G8RCRegisterClass->hasSubClassEq(RC)) { if (DestReg != PPC::LR8) { NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LD), DestReg), FrameIdx)); @@ -517,13 +525,13 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, PPC::R11), FrameIdx)); NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTLR8)).addReg(PPC::R11)); } - } else if (RC == PPC::F8RCRegisterClass) { + } else if (PPC::F8RCRegisterClass->hasSubClassEq(RC)) { NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFD), DestReg), FrameIdx)); - } else if (RC == PPC::F4RCRegisterClass) { + } else if (PPC::F4RCRegisterClass->hasSubClassEq(RC)) { NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFS), DestReg), FrameIdx)); - } else if (RC == PPC::CRRCRegisterClass) { + } else if (PPC::CRRCRegisterClass->hasSubClassEq(RC)) { // FIXME: We need a scatch reg here. The trouble with using R0 is that // it's possible for the stack frame to be so big the save location is // out of range of immediate offsets, necessitating another register. @@ -537,7 +545,7 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, // If the reloaded register isn't CR0, shift the bits right so that they are // in the right CR's slot. if (DestReg != PPC::CR0) { - unsigned ShiftBits = PPCRegisterInfo::getRegisterNumbering(DestReg)*4; + unsigned ShiftBits = getPPCRegisterNumbering(DestReg)*4; // rlwinm r11, r11, 32-ShiftBits, 0, 31. NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), ScratchReg) .addReg(ScratchReg).addImm(32-ShiftBits).addImm(0) @@ -546,7 +554,7 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTCRF), DestReg) .addReg(ScratchReg)); - } else if (RC == PPC::CRBITRCRegisterClass) { + } else if (PPC::CRBITRCRegisterClass->hasSubClassEq(RC)) { unsigned Reg = 0; if (DestReg == PPC::CR0LT || DestReg == PPC::CR0GT || @@ -577,7 +585,7 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, return LoadRegFromStackSlot(MF, DL, Reg, FrameIdx, PPC::CRRCRegisterClass, NewMIs); - } else if (RC == PPC::VRRCRegisterClass) { + } else if (PPC::VRRCRegisterClass->hasSubClassEq(RC)) { // We don't have indexed addressing for vector loads. Emit: // R0 = ADDI FI# // Dest = LVX 0, R0 diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 773578c..17f63e0 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -352,7 +352,7 @@ def iaddroff : ComplexPattern<iPTR, 1, "SelectAddrImmOffs", [], []>; def FPContractions : Predicate<"!NoExcessFPPrecision">; def In32BitMode : Predicate<"!PPCSubTarget.isPPC64()">; def In64BitMode : Predicate<"PPCSubTarget.isPPC64()">; - +def IsBookE : Predicate<"PPCSubTarget.isBookE()">; //===----------------------------------------------------------------------===// // PowerPC Instruction Definitions. @@ -1053,6 +1053,10 @@ def CRSET : XLForm_1_ext<19, 289, (outs CRBITRC:$dst), (ins), "creqv $dst, $dst, $dst", BrCR, []>; +def CRUNSET: XLForm_1_ext<19, 193, (outs CRBITRC:$dst), (ins), + "crxor $dst, $dst, $dst", BrCR, + []>; + // XFX-Form instructions. Instructions that deal with SPRs. // let Uses = [CTR] in { @@ -1472,5 +1476,7 @@ def : Pat<(membarrier (i32 imm /*ll*/), (i32 imm /*device*/)), (SYNC)>; +def : Pat<(atomic_fence (imm), (imm)), (SYNC)>; + include "PPCInstrAltivec.td" include "PPCInstr64Bit.td" diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index c9c170e..2e90b7a 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -67,49 +67,6 @@ PPCRegisterInfo::requiresRegisterScavenging(const MachineFunction &) const { (EnablePPC64RS && Subtarget.isPPC64())); } -/// getRegisterNumbering - Given the enum value for some register, e.g. -/// PPC::F14, return the number that it corresponds to (e.g. 14). -unsigned PPCRegisterInfo::getRegisterNumbering(unsigned RegEnum) { - using namespace PPC; - switch (RegEnum) { - case 0: return 0; - case R0 : case X0 : case F0 : case V0 : case CR0: case CR0LT: return 0; - case R1 : case X1 : case F1 : case V1 : case CR1: case CR0GT: return 1; - case R2 : case X2 : case F2 : case V2 : case CR2: case CR0EQ: return 2; - case R3 : case X3 : case F3 : case V3 : case CR3: case CR0UN: return 3; - case R4 : case X4 : case F4 : case V4 : case CR4: case CR1LT: return 4; - case R5 : case X5 : case F5 : case V5 : case CR5: case CR1GT: return 5; - case R6 : case X6 : case F6 : case V6 : case CR6: case CR1EQ: return 6; - case R7 : case X7 : case F7 : case V7 : case CR7: case CR1UN: return 7; - case R8 : case X8 : case F8 : case V8 : case CR2LT: return 8; - case R9 : case X9 : case F9 : case V9 : case CR2GT: return 9; - case R10: case X10: case F10: case V10: case CR2EQ: return 10; - case R11: case X11: case F11: case V11: case CR2UN: return 11; - case R12: case X12: case F12: case V12: case CR3LT: return 12; - case R13: case X13: case F13: case V13: case CR3GT: return 13; - case R14: case X14: case F14: case V14: case CR3EQ: return 14; - case R15: case X15: case F15: case V15: case CR3UN: return 15; - case R16: case X16: case F16: case V16: case CR4LT: return 16; - case R17: case X17: case F17: case V17: case CR4GT: return 17; - case R18: case X18: case F18: case V18: case CR4EQ: return 18; - case R19: case X19: case F19: case V19: case CR4UN: return 19; - case R20: case X20: case F20: case V20: case CR5LT: return 20; - case R21: case X21: case F21: case V21: case CR5GT: return 21; - case R22: case X22: case F22: case V22: case CR5EQ: return 22; - case R23: case X23: case F23: case V23: case CR5UN: return 23; - case R24: case X24: case F24: case V24: case CR6LT: return 24; - case R25: case X25: case F25: case V25: case CR6GT: return 25; - case R26: case X26: case F26: case V26: case CR6EQ: return 26; - case R27: case X27: case F27: case V27: case CR6UN: return 27; - case R28: case X28: case F28: case V28: case CR7LT: return 28; - case R29: case X29: case F29: case V29: case CR7GT: return 29; - case R30: case X30: case F30: case V30: case CR7EQ: return 30; - case R31: case X31: case F31: case V31: case CR7UN: return 31; - default: - llvm_unreachable("Unhandled reg in PPCRegisterInfo::getRegisterNumbering!"); - } -} - PPCRegisterInfo::PPCRegisterInfo(const PPCSubtarget &ST, const TargetInstrInfo &tii) : PPCGenRegisterInfo(ST.isPPC64() ? PPC::LR8 : PPC::LR, @@ -521,7 +478,7 @@ void PPCRegisterInfo::lowerCRSpilling(MachineBasicBlock::iterator II, // rlwinm rA, rA, ShiftBits, 0, 31. BuildMI(MBB, II, dl, TII.get(PPC::RLWINM), Reg) .addReg(Reg, RegState::Kill) - .addImm(PPCRegisterInfo::getRegisterNumbering(SrcReg) * 4) + .addImm(getPPCRegisterNumbering(SrcReg) * 4) .addImm(0) .addImm(31); diff --git a/lib/Target/PowerPC/PPCRegisterInfo.h b/lib/Target/PowerPC/PPCRegisterInfo.h index 114ec22..1cc7213 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.h +++ b/lib/Target/PowerPC/PPCRegisterInfo.h @@ -33,10 +33,6 @@ class PPCRegisterInfo : public PPCGenRegisterInfo { public: PPCRegisterInfo(const PPCSubtarget &SubTarget, const TargetInstrInfo &tii); - /// getRegisterNumbering - Given the enum value for some register, e.g. - /// PPC::F14, return the number that it corresponds to (e.g. 14). - static unsigned getRegisterNumbering(unsigned RegEnum); - /// getPointerRegClass - Return the register class to use to hold pointers. /// This is used for addressing modes. virtual const TargetRegisterClass *getPointerRegClass(unsigned Kind=0) const; diff --git a/lib/Target/PowerPC/PPCSchedule.td b/lib/Target/PowerPC/PPCSchedule.td index 9664f14..69e435b 100644 --- a/lib/Target/PowerPC/PPCSchedule.td +++ b/lib/Target/PowerPC/PPCSchedule.td @@ -103,6 +103,7 @@ def VecVSR : InstrItinClass; // Processor instruction itineraries. include "PPCScheduleG3.td" +include "PPCSchedule440.td" include "PPCScheduleG4.td" include "PPCScheduleG4Plus.td" include "PPCScheduleG5.td" diff --git a/lib/Target/PowerPC/PPCSchedule440.td b/lib/Target/PowerPC/PPCSchedule440.td new file mode 100644 index 0000000..94ee9bd --- /dev/null +++ b/lib/Target/PowerPC/PPCSchedule440.td @@ -0,0 +1,568 @@ +//===- PPCSchedule440.td - PPC 440 Scheduling Definitions --*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Primary reference: +// PowerPC 440x6 Embedded Processor Core User's Manual. +// IBM (as updated in) 2010. + +// The basic PPC 440 does not include a floating-point unit; the pipeline +// timings here are constructed to match the FP2 unit shipped with the +// PPC-440- and PPC-450-based Blue Gene (L and P) supercomputers. +// References: +// S. Chatterjee, et al. Design and exploitation of a high-performance +// SIMD floating-point unit for Blue Gene/L. +// IBM J. Res. & Dev. 49 (2/3) March/May 2005. +// also: +// Carlos Sosa and Brant Knudson. IBM System Blue Gene Solution: +// Blue Gene/P Application Development. +// IBM (as updated in) 2009. + +//===----------------------------------------------------------------------===// +// Functional units on the PowerPC 440/450 chip sets +// +def IFTH1 : FuncUnit; // Fetch unit 1 +def IFTH2 : FuncUnit; // Fetch unit 2 +def PDCD1 : FuncUnit; // Decode unit 1 +def PDCD2 : FuncUnit; // Decode unit 2 +def DISS1 : FuncUnit; // Issue unit 1 +def DISS2 : FuncUnit; // Issue unit 2 +def LRACC : FuncUnit; // Register access and dispatch for + // the simple integer (J-pipe) and + // load/store (L-pipe) pipelines +def IRACC : FuncUnit; // Register access and dispatch for + // the complex integer (I-pipe) pipeline +def FRACC : FuncUnit; // Register access and dispatch for + // the floating-point execution (F-pipe) pipeline +def IEXE1 : FuncUnit; // Execution stage 1 for the I pipeline +def IEXE2 : FuncUnit; // Execution stage 2 for the I pipeline +def IWB : FuncUnit; // Write-back unit for the I pipeline +def JEXE1 : FuncUnit; // Execution stage 1 for the J pipeline +def JEXE2 : FuncUnit; // Execution stage 2 for the J pipeline +def JWB : FuncUnit; // Write-back unit for the J pipeline +def AGEN : FuncUnit; // Address generation for the L pipeline +def CRD : FuncUnit; // D-cache access for the L pipeline +def LWB : FuncUnit; // Write-back unit for the L pipeline +def FEXE1 : FuncUnit; // Execution stage 1 for the F pipeline +def FEXE2 : FuncUnit; // Execution stage 2 for the F pipeline +def FEXE3 : FuncUnit; // Execution stage 3 for the F pipeline +def FEXE4 : FuncUnit; // Execution stage 4 for the F pipeline +def FEXE5 : FuncUnit; // Execution stage 5 for the F pipeline +def FEXE6 : FuncUnit; // Execution stage 6 for the F pipeline +def FWB : FuncUnit; // Write-back unit for the F pipeline + +def LWARX_Hold : FuncUnit; // This is a pseudo-unit which is used + // to make sure that no lwarx/stwcx. + // instructions are issued while another + // lwarx/stwcx. is in the L pipe. + +def GPR_Bypass : Bypass; // The bypass for general-purpose regs. +def FPR_Bypass : Bypass; // The bypass for floating-point regs. + +// Notes: +// Instructions are held in the FRACC, LRACC and IRACC pipeline +// stages until their source operands become ready. Exceptions: +// - Store instructions will hold in the AGEN stage +// - The integer multiply-accumulate instruction will hold in +// the IEXE1 stage +// +// For most I-pipe operations, the result is available at the end of +// the IEXE1 stage. Operations such as multiply and divide must +// continue to execute in IEXE2 and IWB. Divide resides in IWB for +// 33 cycles (multiply also calculates its result in IWB). For all +// J-pipe instructions, the result is available +// at the end of the JEXE1 stage. Loads have a 3-cycle latency +// (data is not available until after the LWB stage). +// +// The L1 cache hit latency is four cycles for floating point loads +// and three cycles for integer loads. +// +// The stwcx. instruction requires both the LRACC and the IRACC +// dispatch stages. It must be issued from DISS0. +// +// All lwarx/stwcx. instructions hold in LRACC if another +// uncommitted lwarx/stwcx. is in AGEN, CRD, or LWB. +// +// msync (a.k.a. sync) and mbar will hold in LWB until all load/store +// resources are empty. AGEN and CRD are held empty until the msync/mbar +// commits. +// +// Most floating-point instructions, computational and move, +// have a 5-cycle latency. Divide takes longer (30 cycles). Instructions that +// update the CR take 2 cycles. Stores take 3 cycles and, as mentioned above, +// loads take 4 cycles (for L1 hit). + +// +// This file defines the itinerary class data for the PPC 440 processor. +// +//===----------------------------------------------------------------------===// + + +def PPC440Itineraries : ProcessorItineraries< + [IFTH1, IFTH2, PDCD1, PDCD2, DISS1, DISS2, FRACC, + IRACC, IEXE1, IEXE2, IWB, LRACC, JEXE1, JEXE2, JWB, AGEN, CRD, LWB, + FEXE1, FEXE2, FEXE3, FEXE4, FEXE5, FEXE6, FWB, LWARX_Hold], + [GPR_Bypass, FPR_Bypass], [ + InstrItinData<IntGeneral , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC, LRACC]>, + InstrStage<1, [IEXE1, JEXE1]>, + InstrStage<1, [IEXE2, JEXE2]>, + InstrStage<1, [IWB, JWB]>], + [6, 4, 4], + [GPR_Bypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<IntCompare , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC, LRACC]>, + InstrStage<1, [IEXE1, JEXE1]>, + InstrStage<1, [IEXE2, JEXE2]>, + InstrStage<1, [IWB, JWB]>], + [6, 4, 4], + [NoBypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<IntDivW , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<33, [IWB]>], + [40, 4, 4], + [NoBypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<IntMFFS , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [7, 4, 4], + [GPR_Bypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<IntMTFSB0 , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [7, 4, 4], + [GPR_Bypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<IntMulHW , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [8, 4, 4], + [NoBypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<IntMulHWU , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [8, 4, 4], + [NoBypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<IntMulLI , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [8, 4, 4], + [NoBypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<IntRotate , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC, LRACC]>, + InstrStage<1, [IEXE1, JEXE1]>, + InstrStage<1, [IEXE2, JEXE2]>, + InstrStage<1, [IWB, JWB]>], + [6, 4, 4], + [GPR_Bypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<IntShift , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC, LRACC]>, + InstrStage<1, [IEXE1, JEXE1]>, + InstrStage<1, [IEXE2, JEXE2]>, + InstrStage<1, [IWB, JWB]>], + [6, 4, 4], + [GPR_Bypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<IntTrapW , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [6, 4], + [GPR_Bypass, GPR_Bypass]>, + InstrItinData<BrB , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [8, 4], + [NoBypass, GPR_Bypass]>, + InstrItinData<BrCR , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [8, 4, 4], + [NoBypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<BrMCR , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [8, 4, 4], + [NoBypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<BrMCRX , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [8, 4, 4], + [NoBypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<LdStDCBA , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [LRACC]>, + InstrStage<1, [AGEN]>, + InstrStage<1, [CRD]>, + InstrStage<1, [LWB]>], + [8, 5], + [NoBypass, GPR_Bypass]>, + InstrItinData<LdStDCBF , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [LRACC]>, + InstrStage<1, [AGEN]>, + InstrStage<1, [CRD]>, + InstrStage<1, [LWB]>], + [8, 5], + [NoBypass, GPR_Bypass]>, + InstrItinData<LdStDCBI , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [LRACC]>, + InstrStage<1, [AGEN]>, + InstrStage<1, [CRD]>, + InstrStage<1, [LWB]>], + [8, 5], + [NoBypass, GPR_Bypass]>, + InstrItinData<LdStGeneral , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [LRACC]>, + InstrStage<1, [AGEN]>, + InstrStage<1, [CRD]>, + InstrStage<2, [LWB]>], + [9, 5], // FIXME: should be [9, 5] for loads and + // [8, 5] for stores. + [NoBypass, GPR_Bypass]>, + InstrItinData<LdStICBI , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [LRACC]>, + InstrStage<1, [AGEN]>, + InstrStage<1, [CRD]>, + InstrStage<1, [LWB]>], + [8, 5], + [NoBypass, GPR_Bypass]>, + InstrItinData<LdStUX , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [LRACC]>, + InstrStage<1, [AGEN]>, + InstrStage<1, [CRD]>, + InstrStage<1, [LWB]>], + [8, 5, 5], + [NoBypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<LdStLFD , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [LRACC]>, + InstrStage<1, [AGEN]>, + InstrStage<1, [CRD]>, + InstrStage<2, [LWB]>], + [9, 5, 5], + [NoBypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<LdStLFDU , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [LRACC]>, + InstrStage<1, [AGEN]>, + InstrStage<1, [CRD]>, + InstrStage<1, [LWB]>], + [9, 5, 5], + [NoBypass, GPR_Bypass, GPR_Bypass]>, + InstrItinData<LdStLHA , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [LRACC]>, + InstrStage<1, [AGEN]>, + InstrStage<1, [CRD]>, + InstrStage<1, [LWB]>], + [8, 5], + [NoBypass, GPR_Bypass]>, + InstrItinData<LdStLMW , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [LRACC]>, + InstrStage<1, [AGEN]>, + InstrStage<1, [CRD]>, + InstrStage<1, [LWB]>], + [8, 5], + [NoBypass, GPR_Bypass]>, + InstrItinData<LdStLWARX , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1]>, + InstrStage<1, [IRACC], 0>, + InstrStage<4, [LWARX_Hold], 0>, + InstrStage<1, [LRACC]>, + InstrStage<1, [AGEN]>, + InstrStage<1, [CRD]>, + InstrStage<1, [LWB]>], + [8, 5], + [NoBypass, GPR_Bypass]>, + InstrItinData<LdStSTWCX , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1]>, + InstrStage<1, [IRACC], 0>, + InstrStage<4, [LWARX_Hold], 0>, + InstrStage<1, [LRACC]>, + InstrStage<1, [AGEN]>, + InstrStage<1, [CRD]>, + InstrStage<1, [LWB]>], + [8, 5], + [NoBypass, GPR_Bypass]>, + InstrItinData<LdStSync , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [LRACC]>, + InstrStage<3, [AGEN], 1>, + InstrStage<2, [CRD], 1>, + InstrStage<1, [LWB]>]>, + InstrItinData<SprISYNC , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [FRACC], 0>, + InstrStage<1, [LRACC], 0>, + InstrStage<1, [IRACC]>, + InstrStage<1, [FEXE1], 0>, + InstrStage<1, [AGEN], 0>, + InstrStage<1, [JEXE1], 0>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [FEXE2], 0>, + InstrStage<1, [CRD], 0>, + InstrStage<1, [JEXE2], 0>, + InstrStage<1, [IEXE2]>, + InstrStage<6, [FEXE3], 0>, + InstrStage<6, [LWB], 0>, + InstrStage<6, [JWB], 0>, + InstrStage<6, [IWB]>]>, + InstrItinData<SprMFSR , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [6, 4], + [GPR_Bypass, GPR_Bypass]>, + InstrItinData<SprMTMSR , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [6, 4], + [GPR_Bypass, GPR_Bypass]>, + InstrItinData<SprMTSR , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<3, [IWB]>], + [9, 4], + [NoBypass, GPR_Bypass]>, + InstrItinData<SprTLBSYNC , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>]>, + InstrItinData<SprMFCR , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [8, 4], + [NoBypass, GPR_Bypass]>, + InstrItinData<SprMFMSR , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [7, 4], + [GPR_Bypass, GPR_Bypass]>, + InstrItinData<SprMFSPR , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<3, [IWB]>], + [10, 4], + [NoBypass, GPR_Bypass]>, + InstrItinData<SprMFTB , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<3, [IWB]>], + [10, 4], + [NoBypass, GPR_Bypass]>, + InstrItinData<SprMTSPR , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<3, [IWB]>], + [10, 4], + [NoBypass, GPR_Bypass]>, + InstrItinData<SprMTSRIN , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<3, [IWB]>], + [10, 4], + [NoBypass, GPR_Bypass]>, + InstrItinData<SprRFI , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [8, 4], + [NoBypass, GPR_Bypass]>, + InstrItinData<SprSC , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [IRACC]>, + InstrStage<1, [IEXE1]>, + InstrStage<1, [IEXE2]>, + InstrStage<1, [IWB]>], + [8, 4], + [NoBypass, GPR_Bypass]>, + InstrItinData<FPGeneral , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [FRACC]>, + InstrStage<1, [FEXE1]>, + InstrStage<1, [FEXE2]>, + InstrStage<1, [FEXE3]>, + InstrStage<1, [FEXE4]>, + InstrStage<1, [FEXE5]>, + InstrStage<1, [FEXE6]>, + InstrStage<1, [FWB]>], + [10, 4, 4], + [FPR_Bypass, FPR_Bypass, FPR_Bypass]>, + InstrItinData<FPCompare , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [FRACC]>, + InstrStage<1, [FEXE1]>, + InstrStage<1, [FEXE2]>, + InstrStage<1, [FEXE3]>, + InstrStage<1, [FEXE4]>, + InstrStage<1, [FEXE5]>, + InstrStage<1, [FEXE6]>, + InstrStage<1, [FWB]>], + [10, 4, 4], + [FPR_Bypass, FPR_Bypass, FPR_Bypass]>, + InstrItinData<FPDivD , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [FRACC]>, + InstrStage<1, [FEXE1]>, + InstrStage<1, [FEXE2]>, + InstrStage<1, [FEXE3]>, + InstrStage<1, [FEXE4]>, + InstrStage<1, [FEXE5]>, + InstrStage<1, [FEXE6]>, + InstrStage<25, [FWB]>], + [35, 4, 4], + [NoBypass, FPR_Bypass, FPR_Bypass]>, + InstrItinData<FPDivS , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [FRACC]>, + InstrStage<1, [FEXE1]>, + InstrStage<1, [FEXE2]>, + InstrStage<1, [FEXE3]>, + InstrStage<1, [FEXE4]>, + InstrStage<1, [FEXE5]>, + InstrStage<1, [FEXE6]>, + InstrStage<13, [FWB]>], + [23, 4, 4], + [NoBypass, FPR_Bypass, FPR_Bypass]>, + InstrItinData<FPFused , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [FRACC]>, + InstrStage<1, [FEXE1]>, + InstrStage<1, [FEXE2]>, + InstrStage<1, [FEXE3]>, + InstrStage<1, [FEXE4]>, + InstrStage<1, [FEXE5]>, + InstrStage<1, [FEXE6]>, + InstrStage<1, [FWB]>], + [10, 4, 4, 4], + [FPR_Bypass, FPR_Bypass, FPR_Bypass, FPR_Bypass]>, + InstrItinData<FPRes , [InstrStage<1, [IFTH1, IFTH2]>, + InstrStage<1, [PDCD1, PDCD2]>, + InstrStage<1, [DISS1, DISS2]>, + InstrStage<1, [FRACC]>, + InstrStage<1, [FEXE1]>, + InstrStage<1, [FEXE2]>, + InstrStage<1, [FEXE3]>, + InstrStage<1, [FEXE4]>, + InstrStage<1, [FEXE5]>, + InstrStage<1, [FEXE6]>, + InstrStage<1, [FWB]>], + [10, 4], + [FPR_Bypass, FPR_Bypass]> +]>; diff --git a/lib/Target/PowerPC/PPCSubtarget.cpp b/lib/Target/PowerPC/PPCSubtarget.cpp index 5ea9b0f..8acf75c 100644 --- a/lib/Target/PowerPC/PPCSubtarget.cpp +++ b/lib/Target/PowerPC/PPCSubtarget.cpp @@ -15,7 +15,7 @@ #include "PPC.h" #include "llvm/GlobalValue.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegistry.h" +#include "llvm/Support/TargetRegistry.h" #include <cstdlib> #define GET_SUBTARGETINFO_TARGET_DESC @@ -74,6 +74,7 @@ PPCSubtarget::PPCSubtarget(const std::string &TT, const std::string &CPU, , HasAltivec(false) , HasFSQRT(false) , HasSTFIWX(false) + , IsBookE(false) , HasLazyResolverStubs(false) , IsJITCodeModel(false) , TargetTriple(TT) { diff --git a/lib/Target/PowerPC/PPCSubtarget.h b/lib/Target/PowerPC/PPCSubtarget.h index e028de6..d2b853d 100644 --- a/lib/Target/PowerPC/PPCSubtarget.h +++ b/lib/Target/PowerPC/PPCSubtarget.h @@ -33,6 +33,7 @@ namespace PPC { enum { DIR_NONE, DIR_32, + DIR_440, DIR_601, DIR_602, DIR_603, @@ -66,6 +67,7 @@ protected: bool HasAltivec; bool HasFSQRT; bool HasSTFIWX; + bool IsBookE; bool HasLazyResolverStubs; bool IsJITCodeModel; @@ -136,6 +138,7 @@ public: bool hasSTFIWX() const { return HasSTFIWX; } bool hasAltivec() const { return HasAltivec; } bool isGigaProcessor() const { return IsGigaProcessor; } + bool isBookE() const { return IsBookE; } const Triple &getTargetTriple() const { return TargetTriple; } diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp index 2046673..f5744b83 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -16,46 +16,21 @@ #include "llvm/PassManager.h" #include "llvm/MC/MCStreamer.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetRegistry.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Support/TargetRegistry.h" using namespace llvm; -// This is duplicated code. Refactor this. -static MCStreamer *createMCStreamer(const Target &T, const std::string &TT, - MCContext &Ctx, TargetAsmBackend &TAB, - raw_ostream &OS, - MCCodeEmitter *Emitter, - bool RelaxAll, - bool NoExecStack) { - if (Triple(TT).isOSDarwin()) - return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll); - - return NULL; -} - extern "C" void LLVMInitializePowerPCTarget() { // Register the targets RegisterTargetMachine<PPC32TargetMachine> A(ThePPC32Target); RegisterTargetMachine<PPC64TargetMachine> B(ThePPC64Target); - - // Register the MC Code Emitter - TargetRegistry::RegisterCodeEmitter(ThePPC32Target, createPPCMCCodeEmitter); - TargetRegistry::RegisterCodeEmitter(ThePPC64Target, createPPCMCCodeEmitter); - - - // Register the asm backend. - TargetRegistry::RegisterAsmBackend(ThePPC32Target, createPPCAsmBackend); - TargetRegistry::RegisterAsmBackend(ThePPC64Target, createPPCAsmBackend); - - // Register the object streamer. - TargetRegistry::RegisterObjectStreamer(ThePPC32Target, createMCStreamer); - TargetRegistry::RegisterObjectStreamer(ThePPC64Target, createMCStreamer); } PPCTargetMachine::PPCTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, - Reloc::Model RM, bool is64Bit) - : LLVMTargetMachine(T, TT, CPU, FS, RM), + Reloc::Model RM, CodeModel::Model CM, + bool is64Bit) + : LLVMTargetMachine(T, TT, CPU, FS, RM, CM), Subtarget(TT, CPU, FS, is64Bit), DataLayout(Subtarget.getTargetDataString()), InstrInfo(*this), FrameLowering(Subtarget), JITInfo(*this, is64Bit), @@ -68,16 +43,16 @@ PPCTargetMachine::PPCTargetMachine(const Target &T, StringRef TT, bool PPCTargetMachine::getEnableTailMergeDefault() const { return false; } PPC32TargetMachine::PPC32TargetMachine(const Target &T, StringRef TT, - StringRef CPU, - StringRef FS, Reloc::Model RM) - : PPCTargetMachine(T, TT, CPU, FS, RM, false) { + StringRef CPU, StringRef FS, + Reloc::Model RM, CodeModel::Model CM) + : PPCTargetMachine(T, TT, CPU, FS, RM, CM, false) { } PPC64TargetMachine::PPC64TargetMachine(const Target &T, StringRef TT, - StringRef CPU, - StringRef FS, Reloc::Model RM) - : PPCTargetMachine(T, TT, CPU, FS, RM, true) { + StringRef CPU, StringRef FS, + Reloc::Model RM, CodeModel::Model CM) + : PPCTargetMachine(T, TT, CPU, FS, RM, CM, true) { } diff --git a/lib/Target/PowerPC/PPCTargetMachine.h b/lib/Target/PowerPC/PPCTargetMachine.h index bdec086..d06f084 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.h +++ b/lib/Target/PowerPC/PPCTargetMachine.h @@ -42,7 +42,7 @@ class PPCTargetMachine : public LLVMTargetMachine { public: PPCTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, - Reloc::Model RM, bool is64Bit); + Reloc::Model RM, CodeModel::Model CM, bool is64Bit); virtual const PPCInstrInfo *getInstrInfo() const { return &InstrInfo; } virtual const PPCFrameLowering *getFrameLowering() const { @@ -78,7 +78,8 @@ public: class PPC32TargetMachine : public PPCTargetMachine { public: PPC32TargetMachine(const Target &T, StringRef TT, - StringRef CPU, StringRef FS, Reloc::Model RM); + StringRef CPU, StringRef FS, + Reloc::Model RM, CodeModel::Model CM); }; /// PPC64TargetMachine - PowerPC 64-bit target machine. @@ -86,7 +87,8 @@ public: class PPC64TargetMachine : public PPCTargetMachine { public: PPC64TargetMachine(const Target &T, StringRef TT, - StringRef CPU, StringRef FS, Reloc::Model RM); + StringRef CPU, StringRef FS, + Reloc::Model RM, CodeModel::Model CM); }; } // end namespace llvm diff --git a/lib/Target/PowerPC/TargetInfo/CMakeLists.txt b/lib/Target/PowerPC/TargetInfo/CMakeLists.txt index 058d599..f63111f 100644 --- a/lib/Target/PowerPC/TargetInfo/CMakeLists.txt +++ b/lib/Target/PowerPC/TargetInfo/CMakeLists.txt @@ -4,4 +4,10 @@ add_llvm_library(LLVMPowerPCInfo PowerPCTargetInfo.cpp ) -add_dependencies(LLVMPowerPCInfo PowerPCCodeGenTable_gen) +add_llvm_library_dependencies(LLVMPowerPCInfo + LLVMMC + LLVMSupport + LLVMTarget + ) + +add_dependencies(LLVMPowerPCInfo PowerPCCommonTableGen) diff --git a/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp b/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp index ad607d0..5dc8568 100644 --- a/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp +++ b/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp @@ -9,7 +9,7 @@ #include "PPC.h" #include "llvm/Module.h" -#include "llvm/Target/TargetRegistry.h" +#include "llvm/Support/TargetRegistry.h" using namespace llvm; Target llvm::ThePPC32Target, llvm::ThePPC64Target; |