From 8f331325a22746d89fc30ea59672012c8c58cf49 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Sat, 13 Aug 2005 05:59:16 +0000 Subject: [PATCH] Remove support for 64b PPC, it's been broken for a long time. It'll be back once a DAG->DAG ISel exists. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22778 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/Makefile | 5 +- lib/Target/PowerPC/PPC64CodeEmitter.cpp | 35 - lib/Target/PowerPC/PPC64ISelPattern.cpp | 1632 ---------------------- lib/Target/PowerPC/PPC64InstrInfo.cpp | 59 - lib/Target/PowerPC/PPC64InstrInfo.h | 56 - lib/Target/PowerPC/PPC64JITInfo.h | 35 - lib/Target/PowerPC/PPC64RegisterInfo.cpp | 317 ----- lib/Target/PowerPC/PPC64RegisterInfo.h | 56 - lib/Target/PowerPC/PPC64TargetMachine.h | 43 - lib/Target/PowerPC/PPCTargetMachine.cpp | 38 +- 10 files changed, 4 insertions(+), 2272 deletions(-) delete mode 100644 lib/Target/PowerPC/PPC64CodeEmitter.cpp delete mode 100644 lib/Target/PowerPC/PPC64ISelPattern.cpp delete mode 100644 lib/Target/PowerPC/PPC64InstrInfo.cpp delete mode 100644 lib/Target/PowerPC/PPC64InstrInfo.h delete mode 100644 lib/Target/PowerPC/PPC64JITInfo.h delete mode 100644 lib/Target/PowerPC/PPC64RegisterInfo.cpp delete mode 100644 lib/Target/PowerPC/PPC64RegisterInfo.h delete mode 100644 lib/Target/PowerPC/PPC64TargetMachine.h diff --git a/lib/Target/PowerPC/Makefile b/lib/Target/PowerPC/Makefile index 8975398c035..0a6463f62d0 100644 --- a/lib/Target/PowerPC/Makefile +++ b/lib/Target/PowerPC/Makefile @@ -8,12 +8,11 @@ ##===----------------------------------------------------------------------===## LEVEL = ../../.. LIBRARYNAME = LLVMPowerPC -TARGET = PowerPC PPC32 PPC64 +TARGET = PowerPC PPC32 # Make sure that tblgen is run, first thing. BUILT_SOURCES = PowerPCGenInstrNames.inc PowerPCGenRegisterNames.inc \ PowerPCGenAsmWriter.inc PPC32GenCodeEmitter.inc \ - PPC32GenRegisterInfo.h.inc PPC32GenRegisterInfo.inc PPC32GenInstrInfo.inc \ - PPC64GenRegisterInfo.h.inc PPC64GenRegisterInfo.inc PPC64GenInstrInfo.inc + PPC32GenRegisterInfo.h.inc PPC32GenRegisterInfo.inc PPC32GenInstrInfo.inc include $(LEVEL)/Makefile.common diff --git a/lib/Target/PowerPC/PPC64CodeEmitter.cpp b/lib/Target/PowerPC/PPC64CodeEmitter.cpp deleted file mode 100644 index 6c438049f4a..00000000000 --- a/lib/Target/PowerPC/PPC64CodeEmitter.cpp +++ /dev/null @@ -1,35 +0,0 @@ -//===-- PPC64CodeEmitter.cpp - JIT Code Emitter for PPC64 -----*- 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. -// -//===----------------------------------------------------------------------===// -// -// -//===----------------------------------------------------------------------===// - -#include "PPC64JITInfo.h" -#include "PPC64TargetMachine.h" -using namespace llvm; - -/// 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 PPC64TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM, - MachineCodeEmitter &MCE) { - return true; - // It should go something like this: - // PM.add(new Emitter(MCE)); // Machine code emitter pass for PPC64 - // Delete machine code for this function after emitting it: - // PM.add(createMachineCodeDeleter()); -} - -void PPC64JITInfo::replaceMachineCodeForFunction (void *Old, void *New) { - assert (0 && "PPC64JITInfo::replaceMachineCodeForFunction not implemented"); -} - diff --git a/lib/Target/PowerPC/PPC64ISelPattern.cpp b/lib/Target/PowerPC/PPC64ISelPattern.cpp deleted file mode 100644 index eb4410b32ac..00000000000 --- a/lib/Target/PowerPC/PPC64ISelPattern.cpp +++ /dev/null @@ -1,1632 +0,0 @@ -//===-- PPC64ISelPattern.cpp - A pattern matching inst selector for PPC64 -===// -// -// 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 defines a pattern matching instruction selector for 64 bit PowerPC. -// -//===----------------------------------------------------------------------===// - -#include "PowerPC.h" -#include "PowerPCInstrBuilder.h" -#include "PowerPCInstrInfo.h" -#include "PPC64RegisterInfo.h" -#include "llvm/Constants.h" // FIXME: REMOVE -#include "llvm/Function.h" -#include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/SelectionDAG.h" -#include "llvm/CodeGen/SelectionDAGISel.h" -#include "llvm/CodeGen/SSARegMap.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetLowering.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/ADT/Statistic.h" -#include -#include -using namespace llvm; - -//===----------------------------------------------------------------------===// -// PPC64TargetLowering - PPC64 Implementation of the TargetLowering interface -namespace { - class PPC64TargetLowering : public TargetLowering { - int VarArgsFrameIndex; // FrameIndex for start of varargs area. - int ReturnAddrIndex; // FrameIndex for return slot. - public: - PPC64TargetLowering(TargetMachine &TM) : TargetLowering(TM) { - // Fold away setcc operations if possible. - setSetCCIsExpensive(); - - // Set up the register classes. - addRegisterClass(MVT::i64, PPC64::GPRCRegisterClass); - addRegisterClass(MVT::f32, PPC64::FPRCRegisterClass); - addRegisterClass(MVT::f64, PPC64::FPRCRegisterClass); - - // PowerPC has no intrinsics for these particular operations - setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand); - setOperationAction(ISD::MEMMOVE, MVT::Other, Expand); - setOperationAction(ISD::MEMSET, MVT::Other, Expand); - setOperationAction(ISD::MEMCPY, MVT::Other, Expand); - - // We don't support sin/cos/sqrt/fmod - setOperationAction(ISD::FSIN , MVT::f64, Expand); - setOperationAction(ISD::FCOS , MVT::f64, Expand); - setOperationAction(ISD::FSQRT, MVT::f64, Expand); - setOperationAction(ISD::SREM , MVT::f64, Expand); - setOperationAction(ISD::FSIN , MVT::f32, Expand); - setOperationAction(ISD::FCOS , MVT::f32, Expand); - setOperationAction(ISD::FSQRT, MVT::f32, Expand); - setOperationAction(ISD::SREM , MVT::f32, Expand); - - // PPC 64 has i16 and i32 but no i8 (or i1) SEXTLOAD - setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand); - setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); - - // PowerPC has no SREM/UREM instructions - setOperationAction(ISD::SREM, MVT::i64, Expand); - setOperationAction(ISD::UREM, MVT::i64, Expand); - - // PowerPC has these, but they are not implemented - setOperationAction(ISD::CTPOP, MVT::i64, Expand); - setOperationAction(ISD::CTTZ , MVT::i64, Expand); - setOperationAction(ISD::CTLZ , MVT::i64, Expand); - - setShiftAmountFlavor(Extend); // shl X, 32 == 0 - addLegalFPImmediate(+0.0); // Necessary for FSEL - addLegalFPImmediate(-0.0); // - - computeRegisterProperties(); - } - - /// LowerArguments - This hook must be implemented to indicate how we should - /// lower the arguments for the specified function, into the specified DAG. - virtual std::vector - LowerArguments(Function &F, SelectionDAG &DAG); - - /// LowerCallTo - This hook lowers an abstract call to a function into an - /// actual call. - virtual std::pair - LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CC, - bool isTailCall, SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG); - - virtual std::pair - LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest); - - virtual std::pair - LowerVAArgNext(SDOperand Chain, SDOperand VAList, - const Type *ArgTy, SelectionDAG &DAG); - - virtual std::pair - LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, - SelectionDAG &DAG); - }; -} - - -std::vector -PPC64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { - // - // add beautiful description of PPC stack frame format, or at least some docs - // - MachineFunction &MF = DAG.getMachineFunction(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineBasicBlock& BB = MF.front(); - std::vector ArgValues; - - // Due to the rather complicated nature of the PowerPC ABI, rather than a - // fixed size array of physical args, for the sake of simplicity let the STL - // handle tracking them for us. - std::vector argVR, argPR, argOp; - unsigned ArgOffset = 48; - unsigned GPR_remaining = 8; - unsigned FPR_remaining = 13; - unsigned GPR_idx = 0, FPR_idx = 0; - static const unsigned GPR[] = { - PPC::R3, PPC::R4, PPC::R5, PPC::R6, - PPC::R7, PPC::R8, PPC::R9, PPC::R10, - }; - static const unsigned FPR[] = { - PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, - PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 - }; - - // Add DAG nodes to load the arguments... On entry to a function on PPC, - // the arguments start at offset 48, although they are likely to be passed - // in registers. - for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { - SDOperand newroot, argt; - bool needsLoad = false; - MVT::ValueType ObjectVT = getValueType(I->getType()); - - switch (ObjectVT) { - default: assert(0 && "Unhandled argument type!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::i64: - if (GPR_remaining > 0) { - BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); - argt = newroot = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, - DAG.getRoot()); - if (ObjectVT != MVT::i64) - argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, newroot); - } else { - needsLoad = true; - } - break; - case MVT::f32: - case MVT::f64: - if (FPR_remaining > 0) { - BuildMI(&BB, PPC::IMPLICIT_DEF, 0, FPR[FPR_idx]); - argt = newroot = DAG.getCopyFromReg(FPR[FPR_idx], ObjectVT, - DAG.getRoot()); - --FPR_remaining; - ++FPR_idx; - } else { - needsLoad = true; - } - break; - } - - // We need to load the argument to a virtual register if we determined above - // that we ran out of physical registers of the appropriate type - if (needsLoad) { - unsigned SubregOffset = 0; - switch (ObjectVT) { - default: assert(0 && "Unhandled argument type!"); - case MVT::i1: - case MVT::i8: SubregOffset = 7; break; - case MVT::i16: SubregOffset = 6; break; - case MVT::i32: - case MVT::f32: SubregOffset = 4; break; - case MVT::i64: - case MVT::f64: SubregOffset = 0; break; - } - int FI = MFI->CreateFixedObject(8, ArgOffset); - SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64); - FIN = DAG.getNode(ISD::ADD, MVT::i64, FIN, - DAG.getConstant(SubregOffset, MVT::i64)); - argt = newroot = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN, - DAG.getSrcValue(NULL)); - } - - // Every 4 bytes of argument space consumes one of the GPRs available for - // argument passing. - if (GPR_remaining > 0) { - --GPR_remaining; - ++GPR_idx; - } - ArgOffset += 8; - - DAG.setRoot(newroot.getValue(1)); - ArgValues.push_back(argt); - } - - // If the function takes variable number of arguments, make a frame index for - // the start of the first vararg value... for expansion of llvm.va_start. - if (F.isVarArg()) { - VarArgsFrameIndex = MFI->CreateFixedObject(8, ArgOffset); - SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64); - // If this function is vararg, store any remaining integer argument regs - // to their spots on the stack so that they may be loaded by deferencing the - // result of va_next. - std::vector MemOps; - for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) { - BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]); - SDOperand Val = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i64, DAG.getRoot()); - SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), - Val, FIN, DAG.getSrcValue(NULL)); - MemOps.push_back(Store); - // Increment the address by eight for the next argument to store - SDOperand PtrOff = DAG.getConstant(8, getPointerTy()); - FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, PtrOff); - } - DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps)); - } - - return ArgValues; -} - -std::pair -PPC64TargetLowering::LowerCallTo(SDOperand Chain, - const Type *RetTy, bool isVarArg, - unsigned CallingConv, bool isTailCall, - SDOperand Callee, ArgListTy &Args, - SelectionDAG &DAG) { - // args_to_use will accumulate outgoing args for the ISD::CALL case in - // SelectExpr to use to put the arguments in the appropriate registers. - std::vector args_to_use; - - // Count how many bytes are to be pushed on the stack, including the linkage - // area, and parameter passing area. - unsigned NumBytes = 48; - - if (Args.empty()) { - Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, - DAG.getConstant(NumBytes, getPointerTy())); - } else { - NumBytes = 8 * Args.size(); // All arguments are rounded up to 8 bytes - - // Just to be safe, we'll always reserve the full 48 bytes of linkage area - // plus 64 bytes of argument space in case any called code gets funky on us. - // (Required by ABI to support var arg) - if (NumBytes < 112) NumBytes = 112; - - // Adjust the stack pointer for the new arguments... - // These operations are automatically eliminated by the prolog/epilog pass - Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, - DAG.getConstant(NumBytes, getPointerTy())); - - // Set up a copy of the stack pointer for use loading and storing any - // arguments that may not fit in the registers available for argument - // passing. - SDOperand StackPtr = DAG.getCopyFromReg(PPC::R1, MVT::i32, - DAG.getEntryNode()); - - // Figure out which arguments are going to go in registers, and which in - // memory. Also, if this is a vararg function, floating point operations - // must be stored to our stack, and loaded into integer regs as well, if - // any integer regs are available for argument passing. - unsigned ArgOffset = 48; - unsigned GPR_remaining = 8; - unsigned FPR_remaining = 13; - - std::vector MemOps; - for (unsigned i = 0, e = Args.size(); i != e; ++i) { - // PtrOff will be used to store the current argument to the stack if a - // register cannot be found for it. - SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); - MVT::ValueType ArgVT = getValueType(Args[i].second); - - switch (ArgVT) { - default: assert(0 && "Unexpected ValueType for argument!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - // Promote the integer to 64 bits. If the input type is signed use a - // sign extend, otherwise use a zero extend. - if (Args[i].second->isSigned()) - Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].first); - else - Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first); - // FALL THROUGH - case MVT::i64: - if (GPR_remaining > 0) { - args_to_use.push_back(Args[i].first); - --GPR_remaining; - } else { - MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - } - ArgOffset += 8; - break; - case MVT::f32: - case MVT::f64: - if (FPR_remaining > 0) { - args_to_use.push_back(Args[i].first); - --FPR_remaining; - if (isVarArg) { - SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL)); - MemOps.push_back(Store); - // Float varargs are always shadowed in available integer registers - if (GPR_remaining > 0) { - SDOperand Load = DAG.getLoad(MVT::i64, Store, PtrOff, - DAG.getSrcValue(NULL)); - MemOps.push_back(Load); - args_to_use.push_back(Load); - --GPR_remaining; - } - } else { - // If we have any FPRs remaining, we may also have GPRs remaining. - // Args passed in FPRs also consume an available GPR. - if (GPR_remaining > 0) { - args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i64)); - --GPR_remaining; - } - } - } else { - MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, - Args[i].first, PtrOff, - DAG.getSrcValue(NULL))); - } - ArgOffset += 8; - break; - } - } - if (!MemOps.empty()) - Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps); - } - - std::vector RetVals; - MVT::ValueType RetTyVT = getValueType(RetTy); - if (RetTyVT != MVT::isVoid) - RetVals.push_back(RetTyVT); - RetVals.push_back(MVT::Other); - - SDOperand TheCall = SDOperand(DAG.getCall(RetVals, - Chain, Callee, args_to_use), 0); - Chain = TheCall.getValue(RetTyVT != MVT::isVoid); - Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, - DAG.getConstant(NumBytes, getPointerTy())); - return std::make_pair(TheCall, Chain); -} - -std::pair -PPC64TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest) { - // vastart just stores the address of the VarArgsFrameIndex slot. - SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64); - SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, Dest, DAG.getSrcValue(NULL)); - return std::make_pair(Result, Result); -} - -std::pair PPC64TargetLowering:: -LowerVAArgNext(SDOperand Chain, SDOperand VAList, - const Type *ArgTy, SelectionDAG &DAG) { - MVT::ValueType ArgVT = getValueType(ArgTy); - SDOperand Result; - SDOperand Val = DAG.getLoad(MVT::i64, Chain, VAList, DAG.getSrcValue(NULL)); - Result = DAG.getLoad(ArgVT, Val.getValue(1), Val, DAG.getSrcValue(NULL)); - Val = DAG.getNode(ISD::ADD, VAList.getValueType(), Val, - DAG.getConstant(8, VAList.getValueType())); - Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Val, VAList, DAG.getSrcValue(NULL)); - return std::make_pair(Result, Chain); -} - -std::pair PPC64TargetLowering:: -LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth, - SelectionDAG &DAG) { - assert(0 && "LowerFrameReturnAddress unimplemented"); - abort(); -} - -namespace { -Statistic<>NotLogic("ppc-codegen", "Number of inverted logical ops"); -Statistic<>FusedFP("ppc-codegen", "Number of fused fp operations"); -//===--------------------------------------------------------------------===// -/// ISel - PPC64 specific code to select PPC64 machine instructions for -/// SelectionDAG operations. -//===--------------------------------------------------------------------===// -class ISel : public SelectionDAGISel { - - /// Comment Here. - PPC64TargetLowering PPC64Lowering; - - /// ExprMap - As shared expressions are codegen'd, we keep track of which - /// vreg the value is produced in, so we only emit one copy of each compiled - /// tree. - std::map ExprMap; - - unsigned GlobalBaseReg; - bool GlobalBaseInitialized; - -public: - ISel(TargetMachine &TM) : SelectionDAGISel(PPC64Lowering), PPC64Lowering(TM) - {} - - /// runOnFunction - Override this function in order to reset our per-function - /// variables. - virtual bool runOnFunction(Function &Fn) { - // Make sure we re-emit a set of the global base reg if necessary - GlobalBaseInitialized = false; - return SelectionDAGISel::runOnFunction(Fn); - } - - /// InstructionSelectBasicBlock - This callback is invoked by - /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. - virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) { - DEBUG(BB->dump()); - // Codegen the basic block. - Select(DAG.getRoot()); - - // Clear state used for selection. - ExprMap.clear(); - } - - unsigned getGlobalBaseReg(); - unsigned getConstDouble(double floatVal, unsigned Result); - unsigned SelectSetCR0(SDOperand CC); - unsigned SelectExpr(SDOperand N); - unsigned SelectExprFP(SDOperand N, unsigned Result); - void Select(SDOperand N); - - bool SelectAddr(SDOperand N, unsigned& Reg, int& offset); - void SelectBranchCC(SDOperand N); -}; - -/// getImmediateForOpcode - This method returns a value indicating whether -/// the ConstantSDNode N can be used as an immediate to Opcode. The return -/// values are either 0, 1 or 2. 0 indicates that either N is not a -/// ConstantSDNode, or is not suitable for use by that opcode. A return value -/// of 1 indicates that the constant may be used in normal immediate form. A -/// return value of 2 indicates that the constant may be used in shifted -/// immediate form. A return value of 3 indicates that log base 2 of the -/// constant may be used. -/// -static unsigned getImmediateForOpcode(SDOperand N, unsigned Opcode, - unsigned& Imm, bool U = false) { - if (N.getOpcode() != ISD::Constant) return 0; - - int v = (int)cast(N)->getSignExtended(); - - switch(Opcode) { - default: return 0; - case ISD::ADD: - if (isInt16(v)) { Imm = v & 0xFFFF; return 1; } - if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; } - break; - case ISD::AND: - case ISD::XOR: - case ISD::OR: - if (isUInt16(v)) { Imm = v & 0xFFFF; return 1; } - if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; } - break; - case ISD::MUL: - case ISD::SUB: - if (isInt16(v)) { Imm = v & 0xFFFF; return 1; } - break; - case ISD::SETCC: - if (U && isUInt16(v)) { Imm = v & 0xFFFF; return 1; } - if (!U && isInt16(v)) { Imm = v & 0xFFFF; return 1; } - break; - case ISD::SDIV: - if (isPowerOf2_32(v)) { Imm = Log2_32(v); return 3; } - break; - } - return 0; -} - -/// getBCCForSetCC - Returns the PowerPC condition branch mnemonic corresponding -/// to Condition. If the Condition is unordered or unsigned, the bool argument -/// U is set to true, otherwise it is set to false. -static unsigned getBCCForSetCC(unsigned Condition, bool& U) { - U = false; - switch (Condition) { - default: assert(0 && "Unknown condition!"); abort(); - case ISD::SETEQ: return PPC::BEQ; - case ISD::SETNE: return PPC::BNE; - case ISD::SETULT: U = true; - case ISD::SETLT: return PPC::BLT; - case ISD::SETULE: U = true; - case ISD::SETLE: return PPC::BLE; - case ISD::SETUGT: U = true; - case ISD::SETGT: return PPC::BGT; - case ISD::SETUGE: U = true; - case ISD::SETGE: return PPC::BGE; - } - return 0; -} - -/// IndexedOpForOp - Return the indexed variant for each of the PowerPC load -/// and store immediate instructions. -static unsigned IndexedOpForOp(unsigned Opcode) { - switch(Opcode) { - default: assert(0 && "Unknown opcode!"); abort(); - case PPC::LBZ: return PPC::LBZX; case PPC::STB: return PPC::STBX; - case PPC::LHZ: return PPC::LHZX; case PPC::STH: return PPC::STHX; - case PPC::LHA: return PPC::LHAX; case PPC::STW: return PPC::STWX; - case PPC::LWZ: return PPC::LWZX; case PPC::STD: return PPC::STDX; - case PPC::LD: return PPC::LDX; case PPC::STFS: return PPC::STFSX; - case PPC::LFS: return PPC::LFSX; case PPC::STFD: return PPC::STFDX; - case PPC::LFD: return PPC::LFDX; - } - return 0; -} -} - -/// getGlobalBaseReg - Output the instructions required to put the -/// base address to use for accessing globals into a register. -/// -unsigned ISel::getGlobalBaseReg() { - if (!GlobalBaseInitialized) { - // Insert the set of GlobalBaseReg into the first MBB of the function - MachineBasicBlock &FirstMBB = BB->getParent()->front(); - MachineBasicBlock::iterator MBBI = FirstMBB.begin(); - GlobalBaseReg = MakeReg(MVT::i64); - BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR); - BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg).addReg(PPC::LR); - GlobalBaseInitialized = true; - } - return GlobalBaseReg; -} - -/// getConstDouble - Loads a floating point value into a register, via the -/// Constant Pool. Optionally takes a register in which to load the value. -unsigned ISel::getConstDouble(double doubleVal, unsigned Result=0) { - unsigned Tmp1 = MakeReg(MVT::i64); - if (0 == Result) Result = MakeReg(MVT::f64); - MachineConstantPool *CP = BB->getParent()->getConstantPool(); - ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, doubleVal); - unsigned CPI = CP->getConstantPoolIndex(CFP); - BuildMI(BB, PPC::ADDIS, 2, Tmp1).addReg(getGlobalBaseReg()) - .addConstantPoolIndex(CPI); - BuildMI(BB, PPC::LFD, 2, Result).addConstantPoolIndex(CPI).addReg(Tmp1); - return Result; -} - -unsigned ISel::SelectSetCR0(SDOperand CC) { - unsigned Opc, Tmp1, Tmp2; - static const unsigned CompareOpcodes[] = - { PPC::FCMPU, PPC::FCMPU, PPC::CMPW, PPC::CMPLW }; - - // If the first operand to the select is a SETCC node, then we can fold it - // into the branch that selects which value to return. - if (CC.getOpcode() == ISD::SETCC) { - bool U; - Opc = getBCCForSetCC(cast(CC.getOperand(2))->get(), U); - Tmp1 = SelectExpr(CC.getOperand(0)); - - // Pass the optional argument U to getImmediateForOpcode for SETCC, - // so that it knows whether the SETCC immediate range is signed or not. - if (1 == getImmediateForOpcode(CC.getOperand(1), ISD::SETCC, - Tmp2, U)) { - if (U) - BuildMI(BB, PPC::CMPLWI, 2, PPC::CR0).addReg(Tmp1).addImm(Tmp2); - else - BuildMI(BB, PPC::CMPWI, 2, PPC::CR0).addReg(Tmp1).addSImm(Tmp2); - } else { - bool IsInteger = MVT::isInteger(CC.getOperand(0).getValueType()); - unsigned CompareOpc = CompareOpcodes[2 * IsInteger + U]; - Tmp2 = SelectExpr(CC.getOperand(1)); - BuildMI(BB, CompareOpc, 2, PPC::CR0).addReg(Tmp1).addReg(Tmp2); - } - } else { - Tmp1 = SelectExpr(CC); - BuildMI(BB, PPC::CMPLWI, 2, PPC::CR0).addReg(Tmp1).addImm(0); - Opc = PPC::BNE; - } - return Opc; -} - -/// Check to see if the load is a constant offset from a base register -bool ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset) -{ - unsigned imm = 0, opcode = N.getOpcode(); - if (N.getOpcode() == ISD::ADD) { - Reg = SelectExpr(N.getOperand(0)); - if (1 == getImmediateForOpcode(N.getOperand(1), opcode, imm)) { - offset = imm; - return false; - } - offset = SelectExpr(N.getOperand(1)); - return true; - } - Reg = SelectExpr(N); - offset = 0; - return false; -} - -void ISel::SelectBranchCC(SDOperand N) -{ - assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???"); - MachineBasicBlock *Dest = - cast(N.getOperand(2))->getBasicBlock(); - - // Get the MBB we will fall through to so that we can hand it off to the - // branch selection pass as an argument to the PPC::COND_BRANCH pseudo op. - //ilist::iterator It = BB; - //MachineBasicBlock *Fallthrough = ++It; - - Select(N.getOperand(0)); //chain - unsigned Opc = SelectSetCR0(N.getOperand(1)); - // FIXME: Use this once we have something approximating two-way branches - // We cannot currently use this in case the ISel hands us something like - // BRcc MBBx - // BR MBBy - // since the fallthrough basic block for the conditional branch does not start - // with the unconditional branch (it is skipped over). - //BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc) - // .addMBB(Dest).addMBB(Fallthrough); - BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(Dest); - return; -} - -unsigned ISel::SelectExprFP(SDOperand N, unsigned Result) -{ - unsigned Tmp1, Tmp2, Tmp3; - unsigned Opc = 0; - SDNode *Node = N.Val; - MVT::ValueType DestType = N.getValueType(); - unsigned opcode = N.getOpcode(); - - switch (opcode) { - default: - Node->dump(); - assert(0 && "Node not handled!\n"); - - case ISD::SELECT: { - SDNode *Cond = N.getOperand(0).Val; - // Attempt to generate FSEL. We can do this whenever we have an FP result, - // and an FP comparison in the SetCC node. - if (Cond->getOpcode() == ISD::SETCC && - !MVT::isInteger(N.getOperand(1).getValueType()) && - cast(Cond->getOperand(2))->get() != ISD::SETEQ && - cast(Cond->getOperand(2))->get() != ISD::SETNE) { - MVT::ValueType VT = Cond->getOperand(0).getValueType(); - ISD::CondCode CC = cast(Cond->getOperand(2))->get(); - Tmp1 = SelectExpr(Cond->getOperand(0)); // Val to compare against - unsigned TV = SelectExpr(N.getOperand(1)); // Use if TRUE - unsigned FV = SelectExpr(N.getOperand(2)); // Use if FALSE - - ConstantFPSDNode *CN = dyn_cast(Cond->getOperand(1)); - if (CN && (CN->isExactlyValue(-0.0) || CN->isExactlyValue(0.0))) { - switch(CC) { - default: assert(0 && "Invalid FSEL condition"); abort(); - case ISD::SETULT: - case ISD::SETLT: - BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(FV).addReg(TV); - return Result; - case ISD::SETUGE: - case ISD::SETGE: - BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(TV).addReg(FV); - return Result; - case ISD::SETUGT: - case ISD::SETGT: { - Tmp2 = MakeReg(VT); - BuildMI(BB, PPC::FNEG, 1, Tmp2).addReg(Tmp1); - BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp2).addReg(FV).addReg(TV); - return Result; - } - case ISD::SETULE: - case ISD::SETLE: { - Tmp2 = MakeReg(VT); - BuildMI(BB, PPC::FNEG, 1, Tmp2).addReg(Tmp1); - BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp2).addReg(TV).addReg(FV); - return Result; - } - } - } else { - Opc = (MVT::f64 == VT) ? PPC::FSUB : PPC::FSUBS; - Tmp2 = SelectExpr(Cond->getOperand(1)); - Tmp3 = MakeReg(VT); - switch(CC) { - default: assert(0 && "Invalid FSEL condition"); abort(); - case ISD::SETULT: - case ISD::SETLT: - BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2); - BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(FV).addReg(TV); - return Result; - case ISD::SETUGE: - case ISD::SETGE: - BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2); - BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(TV).addReg(FV); - return Result; - case ISD::SETUGT: - case ISD::SETGT: - BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp2).addReg(Tmp1); - BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(FV).addReg(TV); - return Result; - case ISD::SETULE: - case ISD::SETLE: - BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp2).addReg(Tmp1); - BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(TV).addReg(FV); - return Result; - } - } - assert(0 && "Should never get here"); - return 0; - } - - unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE - unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE - Opc = SelectSetCR0(N.getOperand(0)); - - // Create an iterator with which to insert the MBB for copying the false - // value and the MBB to hold the PHI instruction for this SetCC. - MachineBasicBlock *thisMBB = BB; - const BasicBlock *LLVM_BB = BB->getBasicBlock(); - ilist::iterator It = BB; - ++It; - - // thisMBB: - // ... - // TrueVal = ... - // cmpTY cr0, r1, r2 - // bCC copy1MBB - // fallthrough --> copy0MBB - MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); - MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); - BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(sinkMBB); - MachineFunction *F = BB->getParent(); - F->getBasicBlockList().insert(It, copy0MBB); - F->getBasicBlockList().insert(It, sinkMBB); - // Update machine-CFG edges - BB->addSuccessor(copy0MBB); - BB->addSuccessor(sinkMBB); - - // copy0MBB: - // %FalseValue = ... - // # fallthrough to sinkMBB - BB = copy0MBB; - // Update machine-CFG edges - BB->addSuccessor(sinkMBB); - - // sinkMBB: - // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] - // ... - BB = sinkMBB; - BuildMI(BB, PPC::PHI, 4, Result).addReg(FalseValue) - .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB); - return Result; - } - - case ISD::FNEG: - if (!NoExcessFPPrecision && - ISD::ADD == N.getOperand(0).getOpcode() && - N.getOperand(0).Val->hasOneUse() && - ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() && - N.getOperand(0).getOperand(0).Val->hasOneUse()) { - ++FusedFP; // Statistic - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(1)); - Tmp3 = SelectExpr(N.getOperand(0).getOperand(1)); - Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS; - BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); - } else if (!NoExcessFPPrecision && - ISD::SUB == N.getOperand(0).getOpcode() && - N.getOperand(0).Val->hasOneUse() && - ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() && - N.getOperand(0).getOperand(0).Val->hasOneUse()) { - ++FusedFP; // Statistic - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(1)); - Tmp3 = SelectExpr(N.getOperand(0).getOperand(1)); - Opc = DestType == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS; - BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); - } else if (ISD::FABS == N.getOperand(0).getOpcode()) { - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - BuildMI(BB, PPC::FNABS, 1, Result).addReg(Tmp1); - } else { - Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, PPC::FNEG, 1, Result).addReg(Tmp1); - } - return Result; - - case ISD::FABS: - Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, PPC::FABS, 1, Result).addReg(Tmp1); - return Result; - - case ISD::FP_ROUND: - assert (DestType == MVT::f32 && - N.getOperand(0).getValueType() == MVT::f64 && - "only f64 to f32 conversion supported here"); - Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, PPC::FRSP, 1, Result).addReg(Tmp1); - return Result; - - case ISD::FP_EXTEND: - assert (DestType == MVT::f64 && - N.getOperand(0).getValueType() == MVT::f32 && - "only f32 to f64 conversion supported here"); - Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1); - return Result; - - case ISD::CopyFromReg: - if (Result == 1) - Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); - Tmp1 = dyn_cast(Node)->getReg(); - BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1); - return Result; - - case ISD::ConstantFP: { - ConstantFPSDNode *CN = cast(N); - Result = getConstDouble(CN->getValue(), Result); - return Result; - } - - case ISD::ADD: - if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL && - N.getOperand(0).Val->hasOneUse()) { - ++FusedFP; // Statistic - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); - Tmp3 = SelectExpr(N.getOperand(1)); - Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS; - BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); - return Result; - } - Opc = DestType == MVT::f64 ? PPC::FADD : PPC::FADDS; - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); - return Result; - - case ISD::SUB: - if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL && - N.getOperand(0).Val->hasOneUse()) { - ++FusedFP; // Statistic - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); - Tmp3 = SelectExpr(N.getOperand(1)); - Opc = DestType == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS; - BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3); - return Result; - } - Opc = DestType == MVT::f64 ? PPC::FSUB : PPC::FSUBS; - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); - return Result; - - case ISD::MUL: - case ISD::SDIV: - switch( opcode ) { - case ISD::MUL: Opc = DestType == MVT::f64 ? PPC::FMUL : PPC::FMULS; break; - case ISD::SDIV: Opc = DestType == MVT::f64 ? PPC::FDIV : PPC::FDIVS; break; - }; - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); - return Result; - - case ISD::UINT_TO_FP: - case ISD::SINT_TO_FP: { - bool IsUnsigned = (ISD::UINT_TO_FP == opcode); - Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register - Tmp2 = MakeReg(MVT::f64); // temp reg to load the integer value into - Tmp3 = MakeReg(MVT::i64); // temp reg to hold the conversion constant - unsigned ConstF = MakeReg(MVT::f64); // temp reg to hold the fp constant - - int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8); - MachineConstantPool *CP = BB->getParent()->getConstantPool(); - - // FIXME: pull this FP constant generation stuff out into something like - // the simple ISel's getReg. - if (IsUnsigned) { - addFrameReference(BuildMI(BB, PPC::STD, 3).addReg(Tmp1), FrameIdx); - addFrameReference(BuildMI(BB, PPC::LFD, 2, Tmp2), FrameIdx); - BuildMI(BB, PPC::FCFID, 1, Result).addReg(Tmp2); - } else { - ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, 0x1.000008p52); - unsigned CPI = CP->getConstantPoolIndex(CFP); - // Load constant fp value - unsigned Tmp4 = MakeReg(MVT::i32); - unsigned TmpL = MakeReg(MVT::i32); - BuildMI(BB, PPC::ADDIS, 2, Tmp4).addReg(getGlobalBaseReg()) - .addConstantPoolIndex(CPI); - BuildMI(BB, PPC::LFD, 2, ConstF).addConstantPoolIndex(CPI).addReg(Tmp4); - // Store the hi & low halves of the fp value, currently in int regs - BuildMI(BB, PPC::LIS, 1, Tmp3).addSImm(0x4330); - addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(Tmp3), FrameIdx); - BuildMI(BB, PPC::XORIS, 2, TmpL).addReg(Tmp1).addImm(0x8000); - addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(TmpL), FrameIdx, 4); - addFrameReference(BuildMI(BB, PPC::LFD, 2, Tmp2), FrameIdx); - // Generate the return value with a subtract - BuildMI(BB, PPC::FSUB, 2, Result).addReg(Tmp2).addReg(ConstF); - } - return Result; - } - } - assert(0 && "Should never get here"); - return 0; -} - -unsigned ISel::SelectExpr(SDOperand N) { - unsigned Result; - unsigned Tmp1, Tmp2, Tmp3; - unsigned Opc = 0; - unsigned opcode = N.getOpcode(); - - SDNode *Node = N.Val; - MVT::ValueType DestType = N.getValueType(); - - unsigned &Reg = ExprMap[N]; - if (Reg) return Reg; - - switch (N.getOpcode()) { - default: - Reg = Result = (N.getValueType() != MVT::Other) ? - MakeReg(N.getValueType()) : 1; - break; - case ISD::TAILCALL: - case ISD::CALL: - // If this is a call instruction, make sure to prepare ALL of the result - // values as well as the chain. - if (Node->getNumValues() == 1) - Reg = Result = 1; // Void call, just a chain. - else { - Result = MakeReg(Node->getValueType(0)); - ExprMap[N.getValue(0)] = Result; - for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i) - ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i)); - ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1; - } - break; - } - - if (ISD::CopyFromReg == opcode) - DestType = N.getValue(0).getValueType(); - - if (DestType == MVT::f64 || DestType == MVT::f32) - if (ISD::LOAD != opcode && ISD::EXTLOAD != opcode && ISD::UNDEF != opcode) - return SelectExprFP(N, Result); - - switch (opcode) { - default: - Node->dump(); - assert(0 && "Node not handled!\n"); - case ISD::UNDEF: - BuildMI(BB, PPC::IMPLICIT_DEF, 0, Result); - return Result; - case ISD::DYNAMIC_STACKALLOC: - // Generate both result values. FIXME: Need a better commment here? - if (Result != 1) - ExprMap[N.getValue(1)] = 1; - else - Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); - - // FIXME: We are currently ignoring the requested alignment for handling - // greater than the stack alignment. This will need to be revisited at some - // point. Align = N.getOperand(2); - if (!isa(N.getOperand(2)) || - cast(N.getOperand(2))->getValue() != 0) { - std::cerr << "Cannot allocate stack object with greater alignment than" - << " the stack alignment yet!"; - abort(); - } - Select(N.getOperand(0)); - Tmp1 = SelectExpr(N.getOperand(1)); - // Subtract size from stack pointer, thereby allocating some space. - BuildMI(BB, PPC::SUBF, 2, PPC::R1).addReg(Tmp1).addReg(PPC::R1); - // Put a pointer to the space into the result register by copying the SP - BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R1).addReg(PPC::R1); - return Result; - - case ISD::ConstantPool: - Tmp1 = cast(N)->getIndex(); - Tmp2 = MakeReg(MVT::i64); - BuildMI(BB, PPC::ADDIS, 2, Tmp2).addReg(getGlobalBaseReg()) - .addConstantPoolIndex(Tmp1); - BuildMI(BB, PPC::LA, 2, Result).addReg(Tmp2).addConstantPoolIndex(Tmp1); - return Result; - - case ISD::FrameIndex: - Tmp1 = cast(N)->getIndex(); - addFrameReference(BuildMI(BB, PPC::ADDI, 2, Result), (int)Tmp1, 0, false); - return Result; - - case ISD::GlobalAddress: { - GlobalValue *GV = cast(N)->getGlobal(); - Tmp1 = MakeReg(MVT::i64); - BuildMI(BB, PPC::ADDIS, 2, Tmp1).addReg(getGlobalBaseReg()) - .addGlobalAddress(GV); - if (GV->hasWeakLinkage() || GV->isExternal()) { - BuildMI(BB, PPC::LD, 2, Result).addGlobalAddress(GV).addReg(Tmp1); - } else { - BuildMI(BB, PPC::LA, 2, Result).addReg(Tmp1).addGlobalAddress(GV); - } - return Result; - } - - case ISD::LOAD: - case ISD::EXTLOAD: - case ISD::ZEXTLOAD: - case ISD::SEXTLOAD: { - MVT::ValueType TypeBeingLoaded = (ISD::LOAD == opcode) ? - Node->getValueType(0) : cast(Node->getOperand(3))->getVT(); - bool sext = (ISD::SEXTLOAD == opcode); - - // Make sure we generate both values. - if (Result != 1) - ExprMap[N.getValue(1)] = 1; // Generate the token - else - Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); - - SDOperand Chain = N.getOperand(0); - SDOperand Address = N.getOperand(1); - Select(Chain); - - switch (TypeBeingLoaded) { - default: Node->dump(); assert(0 && "Cannot load this type!"); - case MVT::i1: Opc = PPC::LBZ; break; - case MVT::i8: Opc = PPC::LBZ; break; - case MVT::i16: Opc = sext ? PPC::LHA : PPC::LHZ; break; - case MVT::i32: Opc = sext ? PPC::LWA : PPC::LWZ; break; - case MVT::i64: Opc = PPC::LD; break; - case MVT::f32: Opc = PPC::LFS; break; - case MVT::f64: Opc = PPC::LFD; break; - } - - if (ConstantPoolSDNode *CP = dyn_cast(Address)) { - Tmp1 = MakeReg(MVT::i64); - int CPI = CP->getIndex(); - BuildMI(BB, PPC::ADDIS, 2, Tmp1).addReg(getGlobalBaseReg()) - .addConstantPoolIndex(CPI); - BuildMI(BB, Opc, 2, Result).addConstantPoolIndex(CPI).addReg(Tmp1); - } - else if(Address.getOpcode() == ISD::FrameIndex) { - Tmp1 = cast(Address)->getIndex(); - addFrameReference(BuildMI(BB, Opc, 2, Result), (int)Tmp1); - } else { - int offset; - bool idx = SelectAddr(Address, Tmp1, offset); - if (idx) { - Opc = IndexedOpForOp(Opc); - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(offset); - } else { - BuildMI(BB, Opc, 2, Result).addSImm(offset).addReg(Tmp1); - } - } - return Result; - } - - case ISD::TAILCALL: - case ISD::CALL: { - unsigned GPR_idx = 0, FPR_idx = 0; - static const unsigned GPR[] = { - PPC::R3, PPC::R4, PPC::R5, PPC::R6, - PPC::R7, PPC::R8, PPC::R9, PPC::R10, - }; - static const unsigned FPR[] = { - PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, - PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 - }; - - // Lower the chain for this call. - Select(N.getOperand(0)); - ExprMap[N.getValue(Node->getNumValues()-1)] = 1; - - MachineInstr *CallMI; - // Emit the correct call instruction based on the type of symbol called. - if (GlobalAddressSDNode *GASD = - dyn_cast(N.getOperand(1))) { - CallMI = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(), - true); - } else if (ExternalSymbolSDNode *ESSDN = - dyn_cast(N.getOperand(1))) { - CallMI = BuildMI(PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(), - true); - } else { - Tmp1 = SelectExpr(N.getOperand(1)); - BuildMI(BB, PPC::OR, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1); - BuildMI(BB, PPC::MTCTR, 1).addReg(PPC::R12); - CallMI = BuildMI(PPC::CALLindirect, 3).addImm(20).addImm(0) - .addReg(PPC::R12); - } - - // Load the register args to virtual regs - std::vector ArgVR; - for(int i = 2, e = Node->getNumOperands(); i < e; ++i) - ArgVR.push_back(SelectExpr(N.getOperand(i))); - - // Copy the virtual registers into the appropriate argument register - for(int i = 0, e = ArgVR.size(); i < e; ++i) { - switch(N.getOperand(i+2).getValueType()) { - default: Node->dump(); assert(0 && "Unknown value type for call"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::i64: - assert(GPR_idx < 8 && "Too many int args"); - if (N.getOperand(i+2).getOpcode() != ISD::UNDEF) { - BuildMI(BB, PPC::OR,2,GPR[GPR_idx]).addReg(ArgVR[i]).addReg(ArgVR[i]); - CallMI->addRegOperand(GPR[GPR_idx], MachineOperand::Use); - } - ++GPR_idx; - break; - case MVT::f64: - case MVT::f32: - assert(FPR_idx < 13 && "Too many fp args"); - BuildMI(BB, PPC::FMR, 1, FPR[FPR_idx]).addReg(ArgVR[i]); - CallMI->addRegOperand(FPR[FPR_idx], MachineOperand::Use); - ++FPR_idx; - break; - } - } - - // Put the call instruction in the correct place in the MachineBasicBlock - BB->push_back(CallMI); - - switch (Node->getValueType(0)) { - default: assert(0 && "Unknown value type for call result!"); - case MVT::Other: return 1; - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::i64: - BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R3).addReg(PPC::R3); - break; - case MVT::f32: - case MVT::f64: - BuildMI(BB, PPC::FMR, 1, Result).addReg(PPC::F1); - break; - } - return Result+N.ResNo; - } - - case ISD::SIGN_EXTEND: - case ISD::SIGN_EXTEND_INREG: - Tmp1 = SelectExpr(N.getOperand(0)); - switch(cast(Node->getOperand(1))->getVT()) { - default: Node->dump(); assert(0 && "Unhandled SIGN_EXTEND type"); break; - case MVT::i32: - BuildMI(BB, PPC::EXTSW, 1, Result).addReg(Tmp1); - break; - case MVT::i16: - BuildMI(BB, PPC::EXTSH, 1, Result).addReg(Tmp1); - break; - case MVT::i8: - BuildMI(BB, PPC::EXTSB, 1, Result).addReg(Tmp1); - break; - case MVT::i1: - BuildMI(BB, PPC::SUBFIC, 2, Result).addReg(Tmp1).addSImm(0); - break; - } - return Result; - - case ISD::CopyFromReg: - if (Result == 1) - Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType()); - Tmp1 = dyn_cast(Node)->getReg(); - BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp1).addReg(Tmp1); - return Result; - - case ISD::SHL: - Tmp1 = SelectExpr(N.getOperand(0)); - if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { - Tmp2 = CN->getValue() & 0x3F; - BuildMI(BB, PPC::RLDICR, 3, Result).addReg(Tmp1).addImm(Tmp2) - .addImm(63-Tmp2); - } else { - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, PPC::SLD, 2, Result).addReg(Tmp1).addReg(Tmp2); - } - return Result; - - case ISD::SRL: - Tmp1 = SelectExpr(N.getOperand(0)); - if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { - Tmp2 = CN->getValue() & 0x3F; - BuildMI(BB, PPC::RLDICL, 3, Result).addReg(Tmp1).addImm(64-Tmp2) - .addImm(Tmp2); - } else { - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, PPC::SRD, 2, Result).addReg(Tmp1).addReg(Tmp2); - } - return Result; - - case ISD::SRA: - Tmp1 = SelectExpr(N.getOperand(0)); - if (ConstantSDNode *CN = dyn_cast(N.getOperand(1))) { - Tmp2 = CN->getValue() & 0x3F; - BuildMI(BB, PPC::SRADI, 2, Result).addReg(Tmp1).addImm(Tmp2); - } else { - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, PPC::SRAD, 2, Result).addReg(Tmp1).addReg(Tmp2); - } - return Result; - - case ISD::ADD: - Tmp1 = SelectExpr(N.getOperand(0)); - switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { - default: assert(0 && "unhandled result code"); - case 0: // No immediate - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, PPC::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2); - break; - case 1: // Low immediate - BuildMI(BB, PPC::ADDI, 2, Result).addReg(Tmp1).addSImm(Tmp2); - break; - case 2: // Shifted immediate - BuildMI(BB, PPC::ADDIS, 2, Result).addReg(Tmp1).addSImm(Tmp2); - break; - } - return Result; - - case ISD::AND: - case ISD::OR: - Tmp1 = SelectExpr(N.getOperand(0)); - switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { - default: assert(0 && "unhandled result code"); - case 0: // No immediate - Tmp2 = SelectExpr(N.getOperand(1)); - switch (opcode) { - case ISD::AND: Opc = PPC::AND; break; - case ISD::OR: Opc = PPC::OR; break; - } - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); - break; - case 1: // Low immediate - switch (opcode) { - case ISD::AND: Opc = PPC::ANDIo; break; - case ISD::OR: Opc = PPC::ORI; break; - } - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); - break; - case 2: // Shifted immediate - switch (opcode) { - case ISD::AND: Opc = PPC::ANDISo; break; - case ISD::OR: Opc = PPC::ORIS; break; - } - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2); - break; - } - return Result; - - case ISD::XOR: { - // Check for EQV: xor, (xor a, -1), b - if (N.getOperand(0).getOpcode() == ISD::XOR && - N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant && - cast(N.getOperand(0).getOperand(1))->isAllOnesValue()) { - ++NotLogic; - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, PPC::EQV, 2, Result).addReg(Tmp1).addReg(Tmp2); - return Result; - } - // Check for NOT, NOR, and NAND: xor (copy, or, and), -1 - if (N.getOperand(1).getOpcode() == ISD::Constant && - cast(N.getOperand(1))->isAllOnesValue()) { - ++NotLogic; - switch(N.getOperand(0).getOpcode()) { - case ISD::OR: - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); - BuildMI(BB, PPC::NOR, 2, Result).addReg(Tmp1).addReg(Tmp2); - break; - case ISD::AND: - Tmp1 = SelectExpr(N.getOperand(0).getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(0).getOperand(1)); - BuildMI(BB, PPC::NAND, 2, Result).addReg(Tmp1).addReg(Tmp2); - break; - default: - Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, PPC::NOR, 2, Result).addReg(Tmp1).addReg(Tmp1); - break; - } - return Result; - } - Tmp1 = SelectExpr(N.getOperand(0)); - switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) { - default: assert(0 && "unhandled result code"); - case 0: // No immediate - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, PPC::XOR, 2, Result).addReg(Tmp1).addReg(Tmp2); - break; - case 1: // Low immediate - BuildMI(BB, PPC::XORI, 2, Result).addReg(Tmp1).addImm(Tmp2); - break; - case 2: // Shifted immediate - BuildMI(BB, PPC::XORIS, 2, Result).addReg(Tmp1).addImm(Tmp2); - break; - } - return Result; - } - - case ISD::SUB: - Tmp2 = SelectExpr(N.getOperand(1)); - if (1 == getImmediateForOpcode(N.getOperand(0), opcode, Tmp1)) - BuildMI(BB, PPC::SUBFIC, 2, Result).addReg(Tmp2).addSImm(Tmp1); - else { - Tmp1 = SelectExpr(N.getOperand(0)); - BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp2).addReg(Tmp1); - } - return Result; - - case ISD::MUL: - Tmp1 = SelectExpr(N.getOperand(0)); - if (1 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) - BuildMI(BB, PPC::MULLI, 2, Result).addReg(Tmp1).addSImm(Tmp2); - else { - Tmp2 = SelectExpr(N.getOperand(1)); - BuildMI(BB, PPC::MULLD, 2, Result).addReg(Tmp1).addReg(Tmp2); - } - return Result; - - case ISD::SDIV: - case ISD::UDIV: - if (3 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp3)) { - Tmp1 = MakeReg(MVT::i64); - Tmp2 = SelectExpr(N.getOperand(0)); - BuildMI(BB, PPC::SRADI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3); - BuildMI(BB, PPC::ADDZE, 1, Result).addReg(Tmp1); - return Result; - } - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = SelectExpr(N.getOperand(1)); - Opc = (ISD::UDIV == opcode) ? PPC::DIVWU : PPC::DIVW; - BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2); - return Result; - - case ISD::FP_TO_UINT: - case ISD::FP_TO_SINT: { - Tmp1 = SelectExpr(N.getOperand(0)); - Tmp2 = MakeReg(MVT::f64); - BuildMI(BB, PPC::FCTIDZ, 1, Tmp2).addReg(Tmp1); - int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8); - addFrameReference(BuildMI(BB, PPC::STFD, 3).addReg(Tmp2), FrameIdx); - addFrameReference(BuildMI(BB, PPC::LD, 2, Result), FrameIdx); - return Result; - } - - case ISD::SETCC: { - Opc = SelectSetCR0(N); - - unsigned TrueValue = MakeReg(MVT::i32); - BuildMI(BB, PPC::LI, 1, TrueValue).addSImm(1); - unsigned FalseValue = MakeReg(MVT::i32); - BuildMI(BB, PPC::LI, 1, FalseValue).addSImm(0); - - // Create an iterator with which to insert the MBB for copying the false - // value and the MBB to hold the PHI instruction for this SetCC. - MachineBasicBlock *thisMBB = BB; - const BasicBlock *LLVM_BB = BB->getBasicBlock(); - ilist::iterator It = BB; - ++It; - - // thisMBB: - // ... - // cmpTY cr0, r1, r2 - // %TrueValue = li 1 - // bCC sinkMBB - MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); - MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); - BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(sinkMBB); - MachineFunction *F = BB->getParent(); - F->getBasicBlockList().insert(It, copy0MBB); - F->getBasicBlockList().insert(It, sinkMBB); - // Update machine-CFG edges - BB->addSuccessor(copy0MBB); - BB->addSuccessor(sinkMBB); - - // copy0MBB: - // %FalseValue = li 0 - // fallthrough - BB = copy0MBB; - // Update machine-CFG edges - BB->addSuccessor(sinkMBB); - - // sinkMBB: - // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] - // ... - BB = sinkMBB; - BuildMI(BB, PPC::PHI, 4, Result).addReg(FalseValue) - .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB); - return Result; - } - - case ISD::SELECT: { - unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE - unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE - Opc = SelectSetCR0(N.getOperand(0)); - - // Create an iterator with which to insert the MBB for copying the false - // value and the MBB to hold the PHI instruction for this SetCC. - MachineBasicBlock *thisMBB = BB; - const BasicBlock *LLVM_BB = BB->getBasicBlock(); - ilist::iterator It = BB; - ++It; - - // thisMBB: - // ... - // TrueVal = ... - // cmpTY cr0, r1, r2 - // bCC copy1MBB - // fallthrough --> copy0MBB - MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); - MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); - BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(sinkMBB); - MachineFunction *F = BB->getParent(); - F->getBasicBlockList().insert(It, copy0MBB); - F->getBasicBlockList().insert(It, sinkMBB); - // Update machine-CFG edges - BB->addSuccessor(copy0MBB); - BB->addSuccessor(sinkMBB); - - // copy0MBB: - // %FalseValue = ... - // # fallthrough to sinkMBB - BB = copy0MBB; - // Update machine-CFG edges - BB->addSuccessor(sinkMBB); - - // sinkMBB: - // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] - // ... - BB = sinkMBB; - BuildMI(BB, PPC::PHI, 4, Result).addReg(FalseValue) - .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB); - - // FIXME: Select i64? - return Result; - } - - case ISD::Constant: - switch (N.getValueType()) { - default: assert(0 && "Cannot use constants of this type!"); - case MVT::i1: - BuildMI(BB, PPC::LI, 1, Result) - .addSImm(!cast(N)->isNullValue()); - break; - case MVT::i32: - { - int v = (int)cast(N)->getSignExtended(); - if (v < 32768 && v >= -32768) { - BuildMI(BB, PPC::LI, 1, Result).addSImm(v); - } else { - Tmp1 = MakeReg(MVT::i32); - BuildMI(BB, PPC::LIS, 1, Tmp1).addSImm(v >> 16); - BuildMI(BB, PPC::ORI, 2, Result).addReg(Tmp1).addImm(v & 0xFFFF); - } - } - } - return Result; - } - - return 0; -} - -void ISel::Select(SDOperand N) { - unsigned Tmp1, Tmp2, Opc; - unsigned opcode = N.getOpcode(); - - if (!ExprMap.insert(std::make_pair(N, 1)).second) - return; // Already selected. - - SDNode *Node = N.Val; - - switch (Node->getOpcode()) { - default: - Node->dump(); std::cerr << "\n"; - assert(0 && "Node not handled yet!"); - case ISD::EntryToken: return; // Noop - case ISD::TokenFactor: - for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) - Select(Node->getOperand(i)); - return; - case ISD::CALLSEQ_START: - case ISD::CALLSEQ_END: - Select(N.getOperand(0)); - Tmp1 = cast(N.getOperand(1))->getValue(); - Opc = N.getOpcode() == ISD::CALLSEQ_START ? PPC::ADJCALLSTACKDOWN : - PPC::ADJCALLSTACKUP; - BuildMI(BB, Opc, 1).addImm(Tmp1); - return; - case ISD::BR: { - MachineBasicBlock *Dest = - cast(N.getOperand(1))->getBasicBlock(); - Select(N.getOperand(0)); - BuildMI(BB, PPC::B, 1).addMBB(Dest); - return; - } - case ISD::BRCOND: - SelectBranchCC(N); - return; - case ISD::CopyToReg: - Select(N.getOperand(0)); - Tmp1 = SelectExpr(N.getOperand(1)); - Tmp2 = cast(N)->getReg(); - - if (Tmp1 != Tmp2) { - if (N.getOperand(1).getValueType() == MVT::f64 || - N.getOperand(1).getValueType() == MVT::f32) - BuildMI(BB, PPC::FMR, 1, Tmp2).addReg(Tmp1); - else - BuildMI(BB, PPC::OR, 2, Tmp2).addReg(Tmp1).addReg(Tmp1); - } - return; - case ISD::ImplicitDef: - Select(N.getOperand(0)); - BuildMI(BB, PPC::IMPLICIT_DEF, 0, cast(N)->getReg()); - return; - case ISD::RET: - switch (N.getNumOperands()) { - default: - assert(0 && "Unknown return instruction!"); - case 3: - assert(N.getOperand(1).getValueType() == MVT::i32 && - N.getOperand(2).getValueType() == MVT::i32 && - "Unknown two-register value!"); - Select(N.getOperand(0)); - Tmp1 = SelectExpr(N.getOperand(1)); - Tmp2 = SelectExpr(N.getOperand(2)); - BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp2).addReg(Tmp2); - BuildMI(BB, PPC::OR, 2, PPC::R4).addReg(Tmp1).addReg(Tmp1); - break; - case 2: - Select(N.getOperand(0)); - Tmp1 = SelectExpr(N.getOperand(1)); - switch (N.getOperand(1).getValueType()) { - default: - assert(0 && "Unknown return type!"); - case MVT::f64: - case MVT::f32: - BuildMI(BB, PPC::FMR, 1, PPC::F1).addReg(Tmp1); - break; - case MVT::i32: - BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp1).addReg(Tmp1); - break; - } - case 1: - Select(N.getOperand(0)); - break; - } - BuildMI(BB, PPC::BLR, 0); // Just emit a 'ret' instruction - return; - case ISD::TRUNCSTORE: - case ISD::STORE: - { - SDOperand Chain = N.getOperand(0); - SDOperand Value = N.getOperand(1); - SDOperand Address = N.getOperand(2); - Select(Chain); - - Tmp1 = SelectExpr(Value); //value - - if (opcode == ISD::STORE) { - switch(Value.getValueType()) { - default: assert(0 && "unknown Type in store"); - case MVT::i64: Opc = PPC::STD; break; - case MVT::f64: Opc = PPC::STFD; break; - case MVT::f32: Opc = PPC::STFS; break; - } - } else { //ISD::TRUNCSTORE - switch(cast(Node->getOperand(4))->getVT()) { - default: assert(0 && "unknown Type in store"); - case MVT::i1: //FIXME: DAG does not promote this load - case MVT::i8: Opc= PPC::STB; break; - case MVT::i16: Opc = PPC::STH; break; - case MVT::i32: Opc = PPC::STW; break; - } - } - - if(Address.getOpcode() == ISD::FrameIndex) - { - Tmp2 = cast(Address)->getIndex(); - addFrameReference(BuildMI(BB, Opc, 3).addReg(Tmp1), (int)Tmp2); - } - else - { - int offset; - bool idx = SelectAddr(Address, Tmp2, offset); - if (idx) { - Opc = IndexedOpForOp(Opc); - BuildMI(BB, Opc, 3).addReg(Tmp1).addReg(Tmp2).addReg(offset); - } else { - BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2); - } - } - return; - } - case ISD::EXTLOAD: - case ISD::SEXTLOAD: - case ISD::ZEXTLOAD: - case ISD::LOAD: - case ISD::CopyFromReg: - case ISD::TAILCALL: - case ISD::CALL: - case ISD::DYNAMIC_STACKALLOC: - ExprMap.erase(N); - SelectExpr(N); - return; - } - assert(0 && "Should not be reached!"); -} - - -/// createPPC64PatternInstructionSelector - This pass converts an LLVM function -/// into a machine code representation using pattern matching and a machine -/// description file. -/// -FunctionPass *llvm::createPPC64ISelPattern(TargetMachine &TM) { - return new ISel(TM); -} - diff --git a/lib/Target/PowerPC/PPC64InstrInfo.cpp b/lib/Target/PowerPC/PPC64InstrInfo.cpp deleted file mode 100644 index 929f5d1e604..00000000000 --- a/lib/Target/PowerPC/PPC64InstrInfo.cpp +++ /dev/null @@ -1,59 +0,0 @@ -//===- PPC64InstrInfo.cpp - PowerPC64 Instruction Information ---*- 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 TargetInstrInfo class. -// -//===----------------------------------------------------------------------===// - -#include "PowerPC.h" -#include "PPC64InstrInfo.h" -#include "PPC64GenInstrInfo.inc" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include -using namespace llvm; - -PPC64InstrInfo::PPC64InstrInfo() - : TargetInstrInfo(PPC64Insts, sizeof(PPC64Insts)/sizeof(PPC64Insts[0])) { } - -bool PPC64InstrInfo::isMoveInstr(const MachineInstr& MI, - unsigned& sourceReg, - unsigned& destReg) const { - MachineOpCode oc = MI.getOpcode(); - if (oc == PPC::OR) { // or r1, r2, r2 - assert(MI.getNumOperands() == 3 && - MI.getOperand(0).isRegister() && - MI.getOperand(1).isRegister() && - MI.getOperand(2).isRegister() && - "invalid PPC OR instruction!"); - if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) { - sourceReg = MI.getOperand(1).getReg(); - destReg = MI.getOperand(0).getReg(); - return true; - } - } else if (oc == PPC::ADDI) { // addi r1, r2, 0 - assert(MI.getNumOperands() == 3 && - MI.getOperand(0).isRegister() && - MI.getOperand(2).isImmediate() && - "invalid PPC ADDI instruction!"); - if (MI.getOperand(1).isRegister() && MI.getOperand(2).getImmedValue()==0) { - sourceReg = MI.getOperand(1).getReg(); - destReg = MI.getOperand(0).getReg(); - return true; - } - } else if (oc == PPC::FMR) { // fmr r1, r2 - assert(MI.getNumOperands() == 2 && - MI.getOperand(0).isRegister() && - MI.getOperand(1).isRegister() && - "invalid PPC FMR instruction"); - sourceReg = MI.getOperand(1).getReg(); - destReg = MI.getOperand(0).getReg(); - return true; - } - return false; -} diff --git a/lib/Target/PowerPC/PPC64InstrInfo.h b/lib/Target/PowerPC/PPC64InstrInfo.h deleted file mode 100644 index e2e643c56d4..00000000000 --- a/lib/Target/PowerPC/PPC64InstrInfo.h +++ /dev/null @@ -1,56 +0,0 @@ -//===- PPC64InstrInfo.h - PowerPC64 Instruction Information -----*- 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 PowerPC64 implementation of the TargetInstrInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef POWERPC64_INSTRUCTIONINFO_H -#define POWERPC64_INSTRUCTIONINFO_H - -#include "PowerPCInstrInfo.h" -#include "PPC64RegisterInfo.h" - -namespace llvm { - -class PPC64InstrInfo : public TargetInstrInfo { - const PPC64RegisterInfo RI; -public: - PPC64InstrInfo(); - - /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As - /// such, whenever a client has an instance of instruction info, it should - /// always be able to get register info as well (through this method). - /// - virtual const MRegisterInfo &getRegisterInfo() const { return RI; } - - // - // Return true if the instruction is a register to register move and - // leave the source and dest operands in the passed parameters. - // - virtual bool isMoveInstr(const MachineInstr& MI, - unsigned& sourceReg, - unsigned& destReg) const; - - static unsigned invertPPCBranchOpcode(unsigned Opcode) { - switch (Opcode) { - default: assert(0 && "Unknown PPC branch opcode!"); - case PPC::BEQ: return PPC::BNE; - case PPC::BNE: return PPC::BEQ; - case PPC::BLT: return PPC::BGE; - case PPC::BGE: return PPC::BLT; - case PPC::BGT: return PPC::BLE; - case PPC::BLE: return PPC::BGT; - } - } -}; - -} - -#endif diff --git a/lib/Target/PowerPC/PPC64JITInfo.h b/lib/Target/PowerPC/PPC64JITInfo.h deleted file mode 100644 index 9e994c26b6d..00000000000 --- a/lib/Target/PowerPC/PPC64JITInfo.h +++ /dev/null @@ -1,35 +0,0 @@ -//===- PPC64JITInfo.h - PowerPC/AIX impl. of the 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/AIX implementation of the TargetJITInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef POWERPC_AIX_JITINFO_H -#define POWERPC_AIX_JITINFO_H - -#include "PowerPCJITInfo.h" - -namespace llvm { - class TargetMachine; - - class PPC64JITInfo : public PowerPCJITInfo { - public: - PPC64JITInfo(TargetMachine &tm) : PowerPCJITInfo(tm) {} - - /// 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); - }; -} - -#endif diff --git a/lib/Target/PowerPC/PPC64RegisterInfo.cpp b/lib/Target/PowerPC/PPC64RegisterInfo.cpp deleted file mode 100644 index fd5d442d25d..00000000000 --- a/lib/Target/PowerPC/PPC64RegisterInfo.cpp +++ /dev/null @@ -1,317 +0,0 @@ -//===- PPC64RegisterInfo.cpp - PowerPC64 Register Information ---*- 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 PowerPC64 implementation of the MRegisterInfo class. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "reginfo" -#include "PowerPC.h" -#include "PowerPCInstrBuilder.h" -#include "PPC64RegisterInfo.h" -#include "llvm/Constants.h" -#include "llvm/Type.h" -#include "llvm/CodeGen/ValueTypes.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/Target/TargetFrameInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/ADT/STLExtras.h" -#include -#include -using namespace llvm; - -PPC64RegisterInfo::PPC64RegisterInfo() - : PPC64GenRegisterInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP) { - ImmToIdxMap[PPC::LD] = PPC::LDX; ImmToIdxMap[PPC::STD] = PPC::STDX; - ImmToIdxMap[PPC::LBZ] = PPC::LBZX; ImmToIdxMap[PPC::STB] = PPC::STBX; - ImmToIdxMap[PPC::LHZ] = PPC::LHZX; ImmToIdxMap[PPC::LHA] = PPC::LHAX; - ImmToIdxMap[PPC::LWZ] = PPC::LWZX; ImmToIdxMap[PPC::LWA] = PPC::LWAX; - ImmToIdxMap[PPC::LFS] = PPC::LFSX; ImmToIdxMap[PPC::LFD] = PPC::LFDX; - ImmToIdxMap[PPC::STH] = PPC::STHX; ImmToIdxMap[PPC::STW] = PPC::STWX; - ImmToIdxMap[PPC::STFS] = PPC::STFSX; ImmToIdxMap[PPC::STFD] = PPC::STFDX; - ImmToIdxMap[PPC::ADDI] = PPC::ADD; -} - -static const TargetRegisterClass *getClass(unsigned SrcReg) { - if (PPC64::FPRCRegisterClass->contains(SrcReg)) - return PPC64::FPRCRegisterClass; - assert(PPC64::GPRCRegisterClass->contains(SrcReg) && "Reg not FPR or GPR"); - return PPC64::GPRCRegisterClass; -} - -static unsigned getIdx(const TargetRegisterClass *RC) { - if (RC == PPC64::GPRCRegisterClass) { - switch (RC->getSize()) { - default: assert(0 && "Invalid data size!"); - case 1: return 0; - case 2: return 1; - case 4: return 2; - case 8: return 3; - } - } else if (RC == PPC64::FPRCRegisterClass) { - switch (RC->getSize()) { - default: assert(0 && "Invalid data size!"); - case 4: return 4; - case 8: return 5; - } - } - std::cerr << "Invalid register class to getIdx()!\n"; - abort(); -} - -void -PPC64RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx) const { - static const unsigned Opcode[] = { - PPC::STB, PPC::STH, PPC::STW, PPC::STD, PPC::STFS, PPC::STFD - }; - unsigned OC = Opcode[getIdx(getClass(SrcReg))]; - if (SrcReg == PPC::LR) { - BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11).addReg(PPC::LR); - BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0); - addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(PPC::R11),FrameIdx); - } else { - BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0); - addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(SrcReg),FrameIdx); - } -} - -void -PPC64RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIdx) const{ - static const unsigned Opcode[] = { - PPC::LBZ, PPC::LHZ, PPC::LWZ, PPC::LD, PPC::LFS, PPC::LFD - }; - unsigned OC = Opcode[getIdx(getClass(DestReg))]; - if (DestReg == PPC::LR) { - BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0); - addFrameReference(BuildMI(MBB, MI, OC, 2, PPC::R11), FrameIdx); - BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11); - } else { - BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0); - addFrameReference(BuildMI(MBB, MI, OC, 2, DestReg), FrameIdx); - } -} - -void PPC64RegisterInfo::copyRegToReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const { - MachineInstr *I; - - if (RC == PPC64::GPRCRegisterClass) { - BuildMI(MBB, MI, PPC::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg); - } else if (RC == PPC64::FPRCRegisterClass) { - BuildMI(MBB, MI, PPC::FMR, 1, DestReg).addReg(SrcReg); - } else { - std::cerr << "Attempt to copy register that is not GPR or FPR"; - abort(); - } -} - -//===----------------------------------------------------------------------===// -// Stack Frame Processing methods -//===----------------------------------------------------------------------===// - -// hasFP - Return true if the specified function should have a dedicated frame -// pointer register. This is true if the function has variable sized allocas or -// if frame pointer elimination is disabled. -// -static bool hasFP(MachineFunction &MF) { - MachineFrameInfo *MFI = MF.getFrameInfo(); - return MFI->hasVarSizedObjects(); -} - -void PPC64RegisterInfo:: -eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const { - if (hasFP(MF)) { - // If we have a frame pointer, convert as follows: - // ADJCALLSTACKDOWN -> addi, r1, r1, -amount - // ADJCALLSTACKUP -> addi, r1, r1, amount - MachineInstr *Old = I; - unsigned Amount = Old->getOperand(0).getImmedValue(); - if (Amount != 0) { - // We need to keep the stack aligned properly. To do this, we round the - // amount of space needed for the outgoing arguments up to the next - // alignment boundary. - unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); - Amount = (Amount+Align-1)/Align*Align; - - // Replace the pseudo instruction with a new instruction... - if (Old->getOpcode() == PPC::ADJCALLSTACKDOWN) { - MBB.insert(I, BuildMI(PPC::ADDI, 2, PPC::R1).addReg(PPC::R1) - .addSImm(-Amount)); - } else { - assert(Old->getOpcode() == PPC::ADJCALLSTACKUP); - MBB.insert(I, BuildMI(PPC::ADDI, 2, PPC::R1).addReg(PPC::R1) - .addSImm(Amount)); - } - } - } - MBB.erase(I); -} - -void -PPC64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { - unsigned i = 0; - MachineInstr &MI = *II; - MachineBasicBlock &MBB = *MI.getParent(); - MachineFunction &MF = *MBB.getParent(); - - while (!MI.getOperand(i).isFrameIndex()) { - ++i; - assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); - } - - int FrameIndex = MI.getOperand(i).getFrameIndex(); - - // Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP). - MI.SetMachineOperandReg(i, hasFP(MF) ? PPC::R31 : PPC::R1); - - // Take into account whether it's an add or mem instruction - unsigned OffIdx = (i == 2) ? 1 : 2; - - // Now add the frame object offset to the offset from r1. - int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + - MI.getOperand(OffIdx).getImmedValue(); - - // If we're not using a Frame Pointer that has been set to the value of the - // SP before having the stack size subtracted from it, then add the stack size - // to Offset to get the correct offset. - Offset += MF.getFrameInfo()->getStackSize(); - - if (Offset > 32767 || Offset < -32768) { - // Insert a set of r0 with the full offset value before the ld, st, or add - MachineBasicBlock *MBB = MI.getParent(); - MBB->insert(II, BuildMI(PPC::LIS, 1, PPC::R0).addSImm(Offset >> 16)); - MBB->insert(II, BuildMI(PPC::ORI, 2, PPC::R0).addReg(PPC::R0) - .addImm(Offset)); - // convert into indexed form of the instruction - // sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0 - // addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0 - unsigned NewOpcode = - const_cast& >(ImmToIdxMap)[MI.getOpcode()]; - assert(NewOpcode && "No indexed form of load or store available!"); - MI.setOpcode(NewOpcode); - MI.SetMachineOperandReg(1, MI.getOperand(i).getReg()); - MI.SetMachineOperandReg(2, PPC::R0); - } else { - MI.SetMachineOperandConst(OffIdx, MachineOperand::MO_SignExtendedImmed, - Offset); - } -} - - -void PPC64RegisterInfo::emitPrologue(MachineFunction &MF) const { - MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB - MachineBasicBlock::iterator MBBI = MBB.begin(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineInstr *MI; - - // Get the number of bytes to allocate from the FrameInfo - unsigned NumBytes = MFI->getStackSize(); - - // If we have calls, we cannot use the red zone to store callee save registers - // and we must set up a stack frame, so calculate the necessary size here. - if (MFI->hasCalls()) { - // We reserve argument space for call sites in the function immediately on - // entry to the current function. This eliminates the need for add/sub - // brackets around call sites. - NumBytes += MFI->getMaxCallFrameSize(); - } - - // Do we need to allocate space on the stack? - if (NumBytes == 0) return; - - // Add the size of R1 to NumBytes size for the store of R1 to the bottom - // of the stack and round the size to a multiple of the alignment. - unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); - unsigned GPRSize = getSpillSize(PPC::R1)/8; - unsigned Size = hasFP(MF) ? GPRSize + GPRSize : GPRSize; - NumBytes = (NumBytes+Size+Align-1)/Align*Align; - - // Update frame info to pretend that this is part of the stack... - MFI->setStackSize(NumBytes); - - // adjust stack pointer: r1 -= numbytes - if (NumBytes <= 32768) { - MI=BuildMI(PPC::STDU,3).addReg(PPC::R1).addSImm(-NumBytes).addReg(PPC::R1); - MBB.insert(MBBI, MI); - } else { - int NegNumbytes = -NumBytes; - MI = BuildMI(PPC::LIS, 1, PPC::R0).addSImm(NegNumbytes >> 16); - MBB.insert(MBBI, MI); - MI = BuildMI(PPC::ORI, 2, PPC::R0).addReg(PPC::R0) - .addImm(NegNumbytes & 0xFFFF); - MBB.insert(MBBI, MI); - MI = BuildMI(PPC::STDUX, 3).addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0); - MBB.insert(MBBI, MI); - } - - if (hasFP(MF)) { - MI = BuildMI(PPC::STD, 3).addReg(PPC::R31).addSImm(GPRSize).addReg(PPC::R1); - MBB.insert(MBBI, MI); - MI = BuildMI(PPC::OR, 2, PPC::R31).addReg(PPC::R1).addReg(PPC::R1); - MBB.insert(MBBI, MI); - } -} - -void PPC64RegisterInfo::emitEpilogue(MachineFunction &MF, - MachineBasicBlock &MBB) const { - const MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineBasicBlock::iterator MBBI = prior(MBB.end()); - MachineInstr *MI; - assert(MBBI->getOpcode() == PPC::BLR && - "Can only insert epilog into returning blocks"); - - // Get the number of bytes allocated from the FrameInfo... - unsigned NumBytes = MFI->getStackSize(); - - if (NumBytes != 0) { - if (hasFP(MF)) { - MI = BuildMI(PPC::OR, 2, PPC::R1).addReg(PPC::R31).addReg(PPC::R31); - MBB.insert(MBBI, MI); - MI = BuildMI(PPC::LD, 2, PPC::R31).addSImm(4).addReg(PPC::R31); - MBB.insert(MBBI, MI); - } - MI = BuildMI(PPC::LD, 2, PPC::R1).addSImm(0).addReg(PPC::R1); - MBB.insert(MBBI, MI); - } -} - -#include "PPC64GenRegisterInfo.inc" - -const TargetRegisterClass* -PPC64RegisterInfo::getRegClassForType(const Type* Ty) const { - switch (Ty->getTypeID()) { - default: assert(0 && "Invalid type to getClass!"); - case Type::BoolTyID: - case Type::SByteTyID: - case Type::UByteTyID: - case Type::ShortTyID: - case Type::UShortTyID: - case Type::IntTyID: - case Type::UIntTyID: - case Type::PointerTyID: - case Type::LongTyID: - case Type::ULongTyID: return &GPRCInstance; - - case Type::FloatTyID: - case Type::DoubleTyID: return &FPRCInstance; - } -} - diff --git a/lib/Target/PowerPC/PPC64RegisterInfo.h b/lib/Target/PowerPC/PPC64RegisterInfo.h deleted file mode 100644 index 0580dc76095..00000000000 --- a/lib/Target/PowerPC/PPC64RegisterInfo.h +++ /dev/null @@ -1,56 +0,0 @@ -//===- PPC64RegisterInfo.h - PowerPC64 Register Information Impl -*- 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 MRegisterInfo class. -// -//===----------------------------------------------------------------------===// - -#ifndef POWERPC64_REGISTERINFO_H -#define POWERPC64_REGISTERINFO_H - -#include "PowerPC.h" -#include "PPC64GenRegisterInfo.h.inc" -#include - -namespace llvm { - -class Type; - -class PPC64RegisterInfo : public PPC64GenRegisterInfo { - std::map ImmToIdxMap; -public: - PPC64RegisterInfo(); - const TargetRegisterClass* getRegClassForType(const Type* Ty) const; - - /// Code Generation virtual methods... - void storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex) const; - - void loadRegFromStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MBBI, - unsigned DestReg, int FrameIndex) const; - - void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const; - - void eliminateCallFramePseudoInstr(MachineFunction &MF, - MachineBasicBlock &MBB, - MachineBasicBlock::iterator I) const; - - void eliminateFrameIndex(MachineBasicBlock::iterator II) const; - - void emitPrologue(MachineFunction &MF) const; - void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; -}; - -} // end namespace llvm - -#endif diff --git a/lib/Target/PowerPC/PPC64TargetMachine.h b/lib/Target/PowerPC/PPC64TargetMachine.h deleted file mode 100644 index 6d35527b1f8..00000000000 --- a/lib/Target/PowerPC/PPC64TargetMachine.h +++ /dev/null @@ -1,43 +0,0 @@ -//===-- PPC64TargetMachine.h - Define TargetMachine for PowerPC64 -*- 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 specific subclass of TargetMachine. -// -//===----------------------------------------------------------------------===// - -#ifndef POWERPC64_TARGETMACHINE_H -#define POWERPC64_TARGETMACHINE_H - -#include "PowerPCTargetMachine.h" -#include "PPC64InstrInfo.h" -#include "llvm/PassManager.h" - -namespace llvm { - -class IntrinsicLowering; - -class PPC64TargetMachine : public PowerPCTargetMachine { - PPC64InstrInfo InstrInfo; - -public: - PPC64TargetMachine(const Module &M, IntrinsicLowering *IL); - virtual const PPC64InstrInfo *getInstrInfo() const { return &InstrInfo; } - virtual const MRegisterInfo *getRegisterInfo() const { - return &InstrInfo.getRegisterInfo(); - } - - static unsigned getModuleMatchQuality(const Module &M); - - bool addPassesToEmitMachineCode(FunctionPassManager &PM, - MachineCodeEmitter &MCE); -}; - -} // end namespace llvm - -#endif diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp index 9b2670cfcac..cc530a6ea9a 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -14,9 +14,7 @@ #include "PowerPCTargetMachine.h" #include "PowerPCFrameInfo.h" #include "PPC32TargetMachine.h" -#include "PPC64TargetMachine.h" #include "PPC32JITInfo.h" -#include "PPC64JITInfo.h" #include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/Analysis/Verifier.h" @@ -35,16 +33,10 @@ static cl::opt EnablePPCLSR("enable-lsr-for-ppc", cl::Hidden, namespace { const std::string PPC32ID = "PowerPC/32bit"; - const std::string PPC64ID = "PowerPC/64bit"; // Register the targets RegisterTarget X("ppc32", " PowerPC 32-bit"); - -#if 0 - RegisterTarget - Y("ppc64", " PowerPC 64-bit (unimplemented)"); -#endif } PowerPCTargetMachine::PowerPCTargetMachine(const std::string &name, @@ -75,8 +67,6 @@ bool PowerPCTargetMachine::addPassesToEmitFile(PassManager &PM, CodeGenFileType FileType) { if (FileType != TargetMachine::AssemblyFile) return true; - bool LP64 = (0 != dynamic_cast(this)); - if (EnablePPCLSR) { PM.add(createLoopStrengthReducePass()); PM.add(createVerifierPass()); @@ -98,9 +88,7 @@ bool PowerPCTargetMachine::addPassesToEmitFile(PassManager &PM, PM.add(createUnreachableBlockEliminationPass()); // Default to pattern ISel - if (LP64) - PM.add(createPPC64ISelPattern(*this)); - else if (PatternISelTriState == 0) + if (PatternISelTriState == 0) PM.add(createPPC32ISelSimple(*this)); else PM.add(createPPC32ISelPattern(*this)); @@ -138,8 +126,6 @@ void PowerPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) { // The JIT does not support or need PIC. PICEnabled = false; - bool LP64 = (0 != dynamic_cast(&TM)); - if (EnablePPCLSR) { PM.add(createLoopStrengthReducePass()); PM.add(createCFGSimplificationPass()); @@ -160,9 +146,7 @@ void PowerPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) { PM.add(createUnreachableBlockEliminationPass()); // Default to pattern ISel - if (LP64) - PM.add(createPPC64ISelPattern(TM)); - else if (PatternISelTriState == 0) + if (PatternISelTriState == 0) PM.add(createPPC32ISelSimple(TM)); else PM.add(createPPC32ISelPattern(TM)); @@ -184,13 +168,6 @@ PPC32TargetMachine::PPC32TargetMachine(const Module &M, IntrinsicLowering *IL) TargetData(PPC32ID,false,4,4,4,4,4,4,2,1,1), PowerPCFrameInfo(*this, false)), JITInfo(*this) {} -/// PPC64TargetMachine ctor - Create a LP64 architecture model -/// -PPC64TargetMachine::PPC64TargetMachine(const Module &M, IntrinsicLowering *IL) - : PowerPCTargetMachine(PPC64ID, IL, M, - TargetData(PPC64ID,false,8,4,4,4,4,4,2,1,1), - PowerPCFrameInfo(*this, true)) {} - unsigned PPC32TargetMachine::getModuleMatchQuality(const Module &M) { // We strongly match "powerpc-*". std::string TT = M.getTargetTriple(); @@ -206,14 +183,3 @@ unsigned PPC32TargetMachine::getModuleMatchQuality(const Module &M) { return getJITMatchQuality()/2; } - -unsigned PPC64TargetMachine::getModuleMatchQuality(const Module &M) { - if (M.getEndianness() == Module::BigEndian && - M.getPointerSize() == Module::Pointer64) - return 10; // Direct match - else if (M.getEndianness() != Module::AnyEndianness || - M.getPointerSize() != Module::AnyPointerSize) - return 0; // Match for some other target - - return getJITMatchQuality()/2; -}