diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.cpp b/llvm/lib/Target/Sparc/SparcInstrInfo.cpp new file mode 100644 index 000000000000..6b6a40627f1a --- /dev/null +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.cpp @@ -0,0 +1,143 @@ +// $Id$ +//*************************************************************************** +// File: +// SparcInstrInfo.cpp +// +// Purpose: +// +// History: +// 10/15/01 - Vikram Adve - Created +//**************************************************************************/ + + +#include "SparcInternals.h" +#include "SparcInstrSelectionSupport.h" +#include "llvm/Target/Sparc.h" +#include "llvm/CodeGen/InstrSelection.h" +#include "llvm/CodeGen/InstrSelectionSupport.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/ConstPoolVals.h" +#include "llvm/Type.h" + + +//************************ Internal Functions ******************************/ + + +static inline MachineInstr* +CreateIntSetInstruction(int64_t C, bool isSigned, Value* dest) +{ + MachineInstr* minstr; + if (isSigned) + { + minstr = new MachineInstr(SETSW); + minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C); + } + else + { + minstr = new MachineInstr(SETUW); + minstr->SetMachineOperand(0, MachineOperand::MO_UnextendedImmed, C); + } + + minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, dest); + + return minstr; +} + +//************************* External Classes *******************************/ + +//--------------------------------------------------------------------------- +// class UltraSparcInstrInfo +// +// Purpose: +// Information about individual instructions. +// Most information is stored in the SparcMachineInstrDesc array above. +// Other information is computed on demand, and most such functions +// default to member functions in base class MachineInstrInfo. +//--------------------------------------------------------------------------- + +/*ctor*/ +UltraSparcInstrInfo::UltraSparcInstrInfo() + : MachineInstrInfo(SparcMachineInstrDesc, + /*descSize = */ NUM_TOTAL_OPCODES, + /*numRealOpCodes = */ NUM_REAL_OPCODES) +{ +} + + +// Create an instruction sequence to put the constant `val' into +// the virtual register `dest'. `val' may be a ConstPoolVal or a +// GlobalValue, viz., the constant address of a global variable or function. +// The generated instructions are returned in `minstrVec'. +// Any temp. registers (TmpInstruction) created are returned in `tempVec'. +// +void +UltraSparcInstrInfo::CreateCodeToLoadConst(Value* val, + Instruction* dest, + vector& minstrVec, + vector& tempVec) const +{ + MachineInstr* minstr; + + assert(isa(val) || isa(val) && + "I only know about constant values and global addresses"); + + // Use a "set" instruction for known constants that can go in an integer reg. + // Use a "load" instruction for all other constants, in particular, + // floating point constants and addresses of globals. + // + const Type* valType = val->getType(); + + if (valType->isIntegral() || valType == Type::BoolTy) + { + bool isValidConstant; + int64_t C = GetConstantValueAsSignedInt(val, isValidConstant); + assert(isValidConstant && "Unrecognized constant"); + minstr = CreateIntSetInstruction(C, valType->isSigned(), dest); + minstrVec.push_back(minstr); + } + else + { + // Make an instruction sequence to load the constant, viz: + // SETSW , addrReg + // LOAD /*addr*/ addrReg, /*offset*/ 0, dest + // Only the SETSW is needed if `val' is a GlobalValue, i.e,. it is + // itself a constant address. Otherwise, both are needed. + + Value* addrVal; + int64_t zeroOffset = 0; // to avoid ambiguity with (Value*) 0 + + if (isa(val)) + { + // Create another TmpInstruction for the hidden integer register + TmpInstruction* addrReg = + new TmpInstruction(Instruction::UserOp1, val, NULL); + tempVec.push_back(addrReg); + addrVal = addrReg; + } + else + addrVal = dest; + + minstr = new MachineInstr(SETUW); + minstr->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp, val); + minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,addrVal); + minstrVec.push_back(minstr); + + if (isa(val)) + { + // addrVal->addMachineInstruction(minstr); + + minstr = new MachineInstr(ChooseLoadInstruction(val->getType())); + minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, + addrVal); + minstr->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed, + zeroOffset); + minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, + dest); + minstrVec.push_back(minstr); + } + } +} + + +//************************ External Functions ******************************/ +