// $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 ******************************/