2 //***************************************************************************
9 // 10/15/01 - Vikram Adve - Created
10 //**************************************************************************/
13 #include "SparcInternals.h"
14 #include "SparcInstrSelectionSupport.h"
15 #include "llvm/Target/Sparc.h"
16 #include "llvm/CodeGen/InstrSelection.h"
17 #include "llvm/CodeGen/InstrSelectionSupport.h"
18 #include "llvm/CodeGen/MachineInstr.h"
19 #include "llvm/ConstPoolVals.h"
20 #include "llvm/Type.h"
23 //************************ Internal Functions ******************************/
26 static inline MachineInstr*
27 CreateIntSetInstruction(int64_t C, bool isSigned, Value* dest,
28 vector<TmpInstruction*>& tempVec)
31 uint64_t absC = (C >= 0)? C : -C;
32 if (absC > (unsigned int) ~0)
33 { // C does not fit in 32 bits
34 TmpInstruction* tmpReg =
35 new TmpInstruction(Instruction::UserOp1, NULL, NULL);
36 tempVec.push_back(tmpReg);
38 minstr = new MachineInstr(SETX);
39 minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C);
40 minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, tmpReg,
42 minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,dest);
46 minstr = new MachineInstr(SETSW);
47 minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C);
48 minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, dest);
52 minstr = new MachineInstr(SETUW);
53 minstr->SetMachineOperand(0, MachineOperand::MO_UnextendedImmed, C);
54 minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, dest);
60 //************************* External Classes *******************************/
62 //---------------------------------------------------------------------------
63 // class UltraSparcInstrInfo
66 // Information about individual instructions.
67 // Most information is stored in the SparcMachineInstrDesc array above.
68 // Other information is computed on demand, and most such functions
69 // default to member functions in base class MachineInstrInfo.
70 //---------------------------------------------------------------------------
73 UltraSparcInstrInfo::UltraSparcInstrInfo()
74 : MachineInstrInfo(SparcMachineInstrDesc,
75 /*descSize = */ NUM_TOTAL_OPCODES,
76 /*numRealOpCodes = */ NUM_REAL_OPCODES)
81 // Create an instruction sequence to put the constant `val' into
82 // the virtual register `dest'. `val' may be a ConstPoolVal or a
83 // GlobalValue, viz., the constant address of a global variable or function.
84 // The generated instructions are returned in `minstrVec'.
85 // Any temp. registers (TmpInstruction) created are returned in `tempVec'.
88 UltraSparcInstrInfo::CreateCodeToLoadConst(Value* val,
90 vector<MachineInstr*>& minstrVec,
91 vector<TmpInstruction*>& tempVec) const
95 assert(isa<ConstPoolVal>(val) || isa<GlobalValue>(val) &&
96 "I only know about constant values and global addresses");
98 // Use a "set" instruction for known constants that can go in an integer reg.
99 // Use a "load" instruction for all other constants, in particular,
100 // floating point constants and addresses of globals.
102 const Type* valType = val->getType();
104 if (valType->isIntegral() || valType == Type::BoolTy)
106 bool isValidConstant;
107 int64_t C = GetConstantValueAsSignedInt(val, isValidConstant);
108 assert(isValidConstant && "Unrecognized constant");
109 minstr = CreateIntSetInstruction(C, valType->isSigned(), dest, tempVec);
110 minstrVec.push_back(minstr);
114 // Make an instruction sequence to load the constant, viz:
115 // SETX <addr-of-constant>, tmpReg, addrReg
116 // LOAD /*addr*/ addrReg, /*offset*/ 0, dest
117 // Only the SETX is needed if `val' is a GlobalValue, i.e,. it is
118 // itself a constant address. Otherwise, both are needed.
121 int64_t zeroOffset = 0; // to avoid ambiguity with (Value*) 0
123 TmpInstruction* tmpReg =
124 new TmpInstruction(Instruction::UserOp1, val, NULL);
125 tempVec.push_back(tmpReg);
127 if (isa<ConstPoolVal>(val))
129 // Create another TmpInstruction for the hidden integer register
130 TmpInstruction* addrReg =
131 new TmpInstruction(Instruction::UserOp1, val, NULL);
132 tempVec.push_back(addrReg);
138 minstr = new MachineInstr(SETX);
139 minstr->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp, val);
140 minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, tmpReg,
142 minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,addrVal);
143 minstrVec.push_back(minstr);
145 if (isa<ConstPoolVal>(val))
147 // addrVal->addMachineInstruction(minstr);
149 minstr = new MachineInstr(ChooseLoadInstruction(val->getType()));
150 minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
152 minstr->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
154 minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
156 minstrVec.push_back(minstr);
162 //************************ External Functions ******************************/