X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FSparcV9%2FSparcV9InstrInfo.cpp;h=134bdacae07ce6faf68a3ad4dbb2c5605cfb0651;hb=f44f905196d9e83f5a8878211ed8f82634f1ed3d;hp=ffec82445dce15f4038f0934099be25c16b1d806;hpb=84c0fcbde4fa37fb78db20d558364fabd63c6d9c;p=oota-llvm.git diff --git a/lib/Target/SparcV9/SparcV9InstrInfo.cpp b/lib/Target/SparcV9/SparcV9InstrInfo.cpp index ffec82445dc..134bdacae07 100644 --- a/lib/Target/SparcV9/SparcV9InstrInfo.cpp +++ b/lib/Target/SparcV9/SparcV9InstrInfo.cpp @@ -6,11 +6,12 @@ #include "SparcInstrSelectionSupport.h" #include "llvm/CodeGen/InstrSelection.h" #include "llvm/CodeGen/InstrSelectionSupport.h" -#include "llvm/CodeGen/MachineCodeForMethod.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/Function.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include using std::vector; static const uint32_t MAXLO = (1 << 10) - 1; // set bits set by %lo(*) @@ -257,6 +258,61 @@ CreateIntSetInstruction(const TargetMachine& target, } +//--------------------------------------------------------------------------- +// Create a table of LLVM opcode -> max. immediate constant likely to +// be usable for that operation. +//--------------------------------------------------------------------------- + +// Entry == 0 ==> no immediate constant field exists at all. +// Entry > 0 ==> abs(immediate constant) <= Entry +// +vector MaxConstantsTable(Instruction::OtherOpsEnd); + +static int +MaxConstantForInstr(unsigned llvmOpCode) +{ + int modelOpCode = -1; + + if (llvmOpCode >= Instruction::BinaryOpsBegin && + llvmOpCode < Instruction::BinaryOpsEnd) + modelOpCode = ADD; + else + switch(llvmOpCode) { + case Instruction::Ret: modelOpCode = JMPLCALL; break; + + case Instruction::Malloc: + case Instruction::Alloca: + case Instruction::GetElementPtr: + case Instruction::PHINode: + case Instruction::Cast: + case Instruction::Call: modelOpCode = ADD; break; + + case Instruction::Shl: + case Instruction::Shr: modelOpCode = SLLX; break; + + default: break; + }; + + return (modelOpCode < 0)? 0: SparcMachineInstrDesc[modelOpCode].maxImmedConst; +} + +static void +InitializeMaxConstantsTable() +{ + unsigned op; + assert(MaxConstantsTable.size() == Instruction::OtherOpsEnd && + "assignments below will be illegal!"); + for (op = Instruction::TermOpsBegin; op < Instruction::TermOpsEnd; ++op) + MaxConstantsTable[op] = MaxConstantForInstr(op); + for (op = Instruction::BinaryOpsBegin; op < Instruction::BinaryOpsEnd; ++op) + MaxConstantsTable[op] = MaxConstantForInstr(op); + for (op = Instruction::MemoryOpsBegin; op < Instruction::MemoryOpsEnd; ++op) + MaxConstantsTable[op] = MaxConstantForInstr(op); + for (op = Instruction::OtherOpsBegin; op < Instruction::OtherOpsEnd; ++op) + MaxConstantsTable[op] = MaxConstantForInstr(op); +} + + //--------------------------------------------------------------------------- // class UltraSparcInstrInfo // @@ -268,11 +324,35 @@ CreateIntSetInstruction(const TargetMachine& target, //--------------------------------------------------------------------------- /*ctor*/ -UltraSparcInstrInfo::UltraSparcInstrInfo(const TargetMachine& tgt) - : MachineInstrInfo(tgt, SparcMachineInstrDesc, +UltraSparcInstrInfo::UltraSparcInstrInfo() + : MachineInstrInfo(SparcMachineInstrDesc, /*descSize = */ NUM_TOTAL_OPCODES, /*numRealOpCodes = */ NUM_REAL_OPCODES) { + InitializeMaxConstantsTable(); +} + +bool +UltraSparcInstrInfo::ConstantMayNotFitInImmedField(const Constant* CV, + const Instruction* I) const +{ + if (I->getOpcode() >= MaxConstantsTable.size()) // user-defined op (or bug!) + return true; + + if (isa(CV)) // can always use %g0 + return false; + + if (const ConstantUInt* U = dyn_cast(CV)) + /* Large unsigned longs may really just be small negative signed longs */ + return (labs((int64_t) U->getValue()) > MaxConstantsTable[I->getOpcode()]); + + if (const ConstantSInt* S = dyn_cast(CV)) + return (labs(S->getValue()) > MaxConstantsTable[I->getOpcode()]); + + if (isa(CV)) + return (1 > MaxConstantsTable[I->getOpcode()]); + + return true; } // @@ -281,7 +361,7 @@ UltraSparcInstrInfo::UltraSparcInstrInfo(const TargetMachine& tgt) // GlobalValue, viz., the constant address of a global variable or function. // The generated instructions are returned in `mvec'. // Any temp. registers (TmpInstruction) created are recorded in mcfi. -// Any stack space required is allocated via MachineCodeForMethod. +// Any stack space required is allocated via MachineFunction. // void UltraSparcInstrInfo::CreateCodeToLoadConst(const TargetMachine& target, @@ -301,6 +381,11 @@ UltraSparcInstrInfo::CreateCodeToLoadConst(const TargetMachine& target, // const Type* valType = val->getType(); + // Unfortunate special case: a ConstantPointerRef is just a + // reference to GlobalValue. + if (isa(val)) + val = cast(val)->getValue(); + if (isa(val)) { TmpInstruction* tmpReg = @@ -376,7 +461,7 @@ UltraSparcInstrInfo::CreateCodeToLoadConst(const TargetMachine& target, mvec.push_back(MI); // Make sure constant is emitted to constant pool in assembly code. - MachineCodeForMethod::get(F).addToConstantPool(cast(val)); + MachineFunction::get(F).addToConstantPool(cast(val)); } } @@ -386,7 +471,7 @@ UltraSparcInstrInfo::CreateCodeToLoadConst(const TargetMachine& target, // val must be an integral type. dest must be a Float or Double. // The generated instructions are returned in `mvec'. // Any temp. registers (TmpInstruction) created are recorded in mcfi. -// Any stack space required is allocated via MachineCodeForMethod. +// Any stack space required is allocated via MachineFunction. // void UltraSparcInstrInfo::CreateCodeToCopyIntToFloat(const TargetMachine& target, @@ -402,7 +487,7 @@ UltraSparcInstrInfo::CreateCodeToCopyIntToFloat(const TargetMachine& target, && "Dest type must be float/double"); // Get a stack slot to use for the copy - int offset = MachineCodeForMethod::get(F).allocateLocalVar(target, val); + int offset = MachineFunction::get(F).allocateLocalVar(target, val); // Get the size of the source value being copied. size_t srcSize = target.DataLayout.getTypeSize(val->getType()); @@ -418,10 +503,10 @@ UltraSparcInstrInfo::CreateCodeToCopyIntToFloat(const TargetMachine& target, { // sign- or zero-extend respectively storeVal = new TmpInstruction(storeType, val); if (val->getType()->isSigned()) - CreateSignExtensionInstructions(target, F, val, 8*srcSize, storeVal, + CreateSignExtensionInstructions(target, F, val, storeVal, 8*srcSize, mvec, mcfi); else - CreateZeroExtensionInstructions(target, F, val, 8*srcSize, storeVal, + CreateZeroExtensionInstructions(target, F, val, storeVal, 8*srcSize, mvec, mcfi); } MachineInstr* store=new MachineInstr(ChooseStoreInstruction(storeType)); @@ -447,7 +532,7 @@ UltraSparcInstrInfo::CreateCodeToCopyIntToFloat(const TargetMachine& target, // `val' to an integer register `dest' by copying to memory and back. // The generated instructions are returned in `mvec'. // Any temp. registers (TmpInstruction) created are recorded in mcfi. -// Any stack space required is allocated via MachineCodeForMethod. +// Any stack space required is allocated via MachineFunction. // void UltraSparcInstrInfo::CreateCodeToCopyFloatToInt(const TargetMachine& target, @@ -464,7 +549,7 @@ UltraSparcInstrInfo::CreateCodeToCopyFloatToInt(const TargetMachine& target, assert((destTy->isIntegral() || isa(destTy)) && "Dest type must be integer, bool or pointer"); - int offset = MachineCodeForMethod::get(F).allocateLocalVar(target, val); + int offset = MachineFunction::get(F).allocateLocalVar(target, val); // Store instruction stores `val' to [%fp+offset]. // The store opCode is based only the source value being copied. @@ -494,7 +579,7 @@ UltraSparcInstrInfo::CreateCodeToCopyFloatToInt(const TargetMachine& target, // Create instruction(s) to copy src to dest, for arbitrary types // The generated instructions are returned in `mvec'. // Any temp. registers (TmpInstruction) created are recorded in mcfi. -// Any stack space required is allocated via MachineCodeForMethod. +// Any stack space required is allocated via MachineFunction. // void UltraSparcInstrInfo::CreateCopyInstructionsByType(const TargetMachine& target, @@ -561,27 +646,27 @@ CreateBitExtensionInstructions(bool signExtend, const TargetMachine& target, Function* F, Value* srcVal, - unsigned int srcSizeInBits, - Value* dest, + Value* destVal, + unsigned int numLowBits, vector& mvec, MachineCodeForInstruction& mcfi) { MachineInstr* M; - assert(srcSizeInBits <= 32 && - "Hmmm... 32 < srcSizeInBits < 64 unexpected but could be handled."); - if (srcSizeInBits < 32) + assert(numLowBits <= 32 && "Otherwise, nothing should be done here!"); + + if (numLowBits < 32) { // SLL is needed since operand size is < 32 bits. - TmpInstruction *tmpI = new TmpInstruction(dest->getType(), - srcVal, dest,"make32"); + TmpInstruction *tmpI = new TmpInstruction(destVal->getType(), + srcVal, destVal, "make32"); mcfi.addTemp(tmpI); - M = Create3OperandInstr_UImmed(SLLX, srcVal, 32-srcSizeInBits, tmpI); + M = Create3OperandInstr_UImmed(SLLX, srcVal, 32-numLowBits, tmpI); mvec.push_back(M); srcVal = tmpI; } M = Create3OperandInstr_UImmed(signExtend? SRA : SRL, - srcVal, 32-srcSizeInBits, dest); + srcVal, 32-numLowBits, destVal); mvec.push_back(M); } @@ -590,20 +675,20 @@ CreateBitExtensionInstructions(bool signExtend, // from an arbitrary-sized integer value (sized in bits, not bytes). // The generated instructions are returned in `mvec'. // Any temp. registers (TmpInstruction) created are recorded in mcfi. -// Any stack space required is allocated via MachineCodeForMethod. +// Any stack space required is allocated via MachineFunction. // void UltraSparcInstrInfo::CreateSignExtensionInstructions( const TargetMachine& target, Function* F, Value* srcVal, - unsigned int srcSizeInBits, - Value* dest, + Value* destVal, + unsigned int numLowBits, vector& mvec, MachineCodeForInstruction& mcfi) const { CreateBitExtensionInstructions(/*signExtend*/ true, target, F, srcVal, - srcSizeInBits, dest, mvec, mcfi); + destVal, numLowBits, mvec, mcfi); } @@ -612,18 +697,18 @@ UltraSparcInstrInfo::CreateSignExtensionInstructions( // For SPARC v9, we sign-extend the given operand using SLL; SRL. // The generated instructions are returned in `mvec'. // Any temp. registers (TmpInstruction) created are recorded in mcfi. -// Any stack space required is allocated via MachineCodeForMethod. +// Any stack space required is allocated via MachineFunction. // void UltraSparcInstrInfo::CreateZeroExtensionInstructions( const TargetMachine& target, Function* F, Value* srcVal, - unsigned int srcSizeInBits, - Value* dest, + Value* destVal, + unsigned int numLowBits, vector& mvec, MachineCodeForInstruction& mcfi) const { CreateBitExtensionInstructions(/*signExtend*/ false, target, F, srcVal, - srcSizeInBits, dest, mvec, mcfi); + destVal, numLowBits, mvec, mcfi); }