blob: 685463c49fe1065e0637d981d95dd602bb56594a [file] [log] [blame]
Vikram S. Advea1d14f32001-10-10 20:50:43 +00001// $Id$ -*-c++-*-
2//***************************************************************************
3// File:
4// InstrSelectionSupport.h
5//
6// Purpose:
7// Target-independent instruction selection code.
8// See SparcInstrSelection.cpp for usage.
9//
10// History:
11// 10/10/01 - Vikram Adve - Created
12//**************************************************************************/
13
14#include "llvm/CodeGen/InstrSelectionSupport.h"
15#include "llvm/CodeGen/InstrSelection.h"
16#include "llvm/CodeGen/MachineInstr.h"
17#include "llvm/Target/TargetMachine.h"
18#include "llvm/Target/MachineRegInfo.h"
19#include "llvm/ConstPoolVals.h"
20#include "llvm/Instruction.h"
21#include "llvm/Type.h"
22#include "llvm/iMemory.h"
23
24
25//*************************** Local Functions ******************************/
26
27inline int64_t
28GetSignedIntConstantValue(Value* val, bool& isValidConstant)
29{
30 int64_t intValue = 0;
31 isValidConstant = false;
32
33 if (val->getValueType() == Value::ConstantVal)
34 {
35 switch(val->getType()->getPrimitiveID())
36 {
37 case Type::BoolTyID:
38 intValue = ((ConstPoolBool*) val)->getValue()? 1 : 0;
39 isValidConstant = true;
40 break;
41 case Type::SByteTyID:
42 case Type::ShortTyID:
43 case Type::IntTyID:
44 case Type::LongTyID:
45 intValue = ((ConstPoolSInt*) val)->getValue();
46 isValidConstant = true;
47 break;
48 default:
49 break;
50 }
51 }
52
53 return intValue;
54}
55
56inline uint64_t
57GetUnsignedIntConstantValue(Value* val, bool& isValidConstant)
58{
59 uint64_t intValue = 0;
60 isValidConstant = false;
61
62 if (val->getValueType() == Value::ConstantVal)
63 {
64 switch(val->getType()->getPrimitiveID())
65 {
66 case Type::BoolTyID:
67 intValue = ((ConstPoolBool*) val)->getValue()? 1 : 0;
68 isValidConstant = true;
69 break;
70 case Type::UByteTyID:
71 case Type::UShortTyID:
72 case Type::UIntTyID:
73 case Type::ULongTyID:
74 intValue = ((ConstPoolUInt*) val)->getValue();
75 isValidConstant = true;
76 break;
77 default:
78 break;
79 }
80 }
81
82 return intValue;
83}
84
85
86inline int64_t
87GetConstantValueAsSignedInt(Value* val, bool& isValidConstant)
88{
89 int64_t intValue = 0;
90
91 if (val->getType()->isSigned())
92 {
93 intValue = GetSignedIntConstantValue(val, isValidConstant);
94 }
95 else // non-numeric types will fall here
96 {
97 uint64_t uintValue = GetUnsignedIntConstantValue(val, isValidConstant);
98 if (isValidConstant && uintValue < INT64_MAX) // safe to use signed
99 intValue = (int64_t) uintValue;
100 else
101 isValidConstant = false;
102 }
103
104 return intValue;
105}
106
107
108//---------------------------------------------------------------------------
109// Function: FoldGetElemChain
110//
111// Purpose:
112// Fold a chain of GetElementPtr instructions into an equivalent
113// (Pointer, IndexVector) pair. Returns the pointer Value, and
114// stores the resulting IndexVector in argument chainIdxVec.
115//---------------------------------------------------------------------------
116
117Value*
118FoldGetElemChain(const InstructionNode* getElemInstrNode,
119 vector<ConstPoolVal*>& chainIdxVec)
120{
121 MemAccessInst* getElemInst = (MemAccessInst*)
122 getElemInstrNode->getInstruction();
123
124 // Initialize return values from the incoming instruction
125 Value* ptrVal = getElemInst->getPtrOperand();
126 chainIdxVec = getElemInst->getIndexVec(); // copies index vector values
127
128 // Now chase the chain of getElementInstr instructions, if any
129 InstrTreeNode* ptrChild = getElemInstrNode->leftChild();
130 while (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
131 ptrChild->getOpLabel() == GetElemPtrIdx)
132 {
133 // Child is a GetElemPtr instruction
134 getElemInst = (MemAccessInst*)
135 ((InstructionNode*) ptrChild)->getInstruction();
136 const vector<ConstPoolVal*>& idxVec = getElemInst->getIndexVec();
137
138 // Get the pointer value out of ptrChild and *prepend* its index vector
139 ptrVal = getElemInst->getPtrOperand();
140 chainIdxVec.insert(chainIdxVec.begin(), idxVec.begin(), idxVec.end());
141
142 ptrChild = ptrChild->leftChild();
143 }
144
145 return ptrVal;
146}
147
148
149//------------------------------------------------------------------------
150// Function Set2OperandsFromInstr
151// Function Set3OperandsFromInstr
152//
153// For the common case of 2- and 3-operand arithmetic/logical instructions,
154// set the m/c instr. operands directly from the VM instruction's operands.
155// Check whether the first or second operand is 0 and can use a dedicated "0"
156// register.
157// Check whether the second operand should use an immediate field or register.
158// (First and third operands are never immediates for such instructions.)
159//
160// Arguments:
161// canDiscardResult: Specifies that the result operand can be discarded
162// by using the dedicated "0"
163//
164// op1position, op2position and resultPosition: Specify in which position
165// in the machine instruction the 3 operands (arg1, arg2
166// and result) should go.
167//
168// RETURN VALUE: unsigned int flags, where
169// flags & 0x01 => operand 1 is constant and needs a register
170// flags & 0x02 => operand 2 is constant and needs a register
171//------------------------------------------------------------------------
172
173void
174Set2OperandsFromInstr(MachineInstr* minstr,
175 InstructionNode* vmInstrNode,
176 const TargetMachine& target,
177 bool canDiscardResult,
178 int op1Position,
179 int resultPosition)
180{
181 Set3OperandsFromInstr(minstr, vmInstrNode, target,
182 canDiscardResult, op1Position,
183 /*op2Position*/ -1, resultPosition);
184}
185
186#undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
187#ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
188unsigned
189Set3OperandsFromInstrJUNK(MachineInstr* minstr,
190 InstructionNode* vmInstrNode,
191 const TargetMachine& target,
192 bool canDiscardResult,
193 int op1Position,
194 int op2Position,
195 int resultPosition)
196{
197 assert(op1Position >= 0);
198 assert(resultPosition >= 0);
199
200 unsigned returnFlags = 0x0;
201
202 // Check if operand 1 is 0. If so, try to use a hardwired 0 register.
203 Value* op1Value = vmInstrNode->leftChild()->getValue();
204 bool isValidConstant;
205 int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
206 if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0)
207 minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum);
208 else
209 {
210 if (isa<ConstPoolVal>(op1Value))
211 {
212 // value is constant and must be loaded from constant pool
213 returnFlags = returnFlags | (1 << op1Position);
214 }
215 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
216 op1Value);
217 }
218
219 // Check if operand 2 (if any) fits in the immed. field of the instruction,
220 // or if it is 0 and can use a dedicated machine register
221 if (op2Position >= 0)
222 {
223 Value* op2Value = vmInstrNode->rightChild()->getValue();
224 int64_t immedValue;
225 unsigned int machineRegNum;
226
227 MachineOperand::MachineOperandType
228 op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
229 /*canUseImmed*/ true,
230 machineRegNum, immedValue);
231
232 if (op2type == MachineOperand::MO_MachineRegister)
233 minstr->SetMachineOperand(op2Position, machineRegNum);
234 else if (op2type == MachineOperand::MO_VirtualRegister)
235 {
236 if (isa<ConstPoolVal>(op2Value))
237 {
238 // value is constant and must be loaded from constant pool
239 returnFlags = returnFlags | (1 << op2Position);
240 }
241 minstr->SetMachineOperand(op2Position, op2type, op2Value);
242 }
243 else
244 {
245 assert(op2type != MO_CCRegister);
246 minstr->SetMachineOperand(op2Position, op2type, immedValue);
247 }
248 }
249
250 // If operand 3 (result) can be discarded, use a dead register if one exists
251 if (canDiscardResult && target.zeroRegNum >= 0)
252 minstr->SetMachineOperand(resultPosition, target.zeroRegNum);
253 else
254 minstr->SetMachineOperand(resultPosition,
255 MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
256
257 return returnFlags;
258}
259#endif
260
261
262void
263Set3OperandsFromInstr(MachineInstr* minstr,
264 InstructionNode* vmInstrNode,
265 const TargetMachine& target,
266 bool canDiscardResult,
267 int op1Position,
268 int op2Position,
269 int resultPosition)
270{
271 assert(op1Position >= 0);
272 assert(resultPosition >= 0);
273
274 // operand 1
275 minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
276 vmInstrNode->leftChild()->getValue());
277
278 // operand 2 (if any)
279 if (op2Position >= 0)
280 minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
281 vmInstrNode->rightChild()->getValue());
282
283 // result operand: if it can be discarded, use a dead register if one exists
284 if (canDiscardResult && target.getRegInfo().getZeroRegNum() >= 0)
285 minstr->SetMachineOperand(resultPosition,
286 target.getRegInfo().getZeroRegNum());
287 else
288 minstr->SetMachineOperand(resultPosition,
289 MachineOperand::MO_VirtualRegister, vmInstrNode->getValue());
290}
291
292
293MachineOperand::MachineOperandType
294ChooseRegOrImmed(Value* val,
295 MachineOpCode opCode,
296 const TargetMachine& target,
297 bool canUseImmed,
298 unsigned int& getMachineRegNum,
299 int64_t& getImmedValue)
300{
301 MachineOperand::MachineOperandType opType =
302 MachineOperand::MO_VirtualRegister;
303 getMachineRegNum = 0;
304 getImmedValue = 0;
305
306 // Check for the common case first: argument is not constant
307 //
308 ConstPoolVal *CPV = dyn_cast<ConstPoolVal>(val);
309 if (!CPV) return opType;
310
311 if (CPV->getType() == Type::BoolTy)
312 {
313 ConstPoolBool *CPB = (ConstPoolBool*)CPV;
314 if (!CPB->getValue() && target.getRegInfo().getZeroRegNum() >= 0)
315 {
316 getMachineRegNum = target.getRegInfo().getZeroRegNum();
317 return MachineOperand::MO_MachineRegister;
318 }
319
320 getImmedValue = 1;
321 return MachineOperand::MO_SignExtendedImmed;
322 }
323
324 if (!CPV->getType()->isIntegral()) return opType;
325
326 // Now get the constant value and check if it fits in the IMMED field.
327 // Take advantage of the fact that the max unsigned value will rarely
328 // fit into any IMMED field and ignore that case (i.e., cast smaller
329 // unsigned constants to signed).
330 //
331 int64_t intValue;
332 if (CPV->getType()->isSigned())
333 {
334 intValue = ((ConstPoolSInt*)CPV)->getValue();
335 }
336 else
337 {
338 uint64_t V = ((ConstPoolUInt*)CPV)->getValue();
339 if (V >= INT64_MAX) return opType;
340 intValue = (int64_t)V;
341 }
342
343 if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0)
344 {
345 opType = MachineOperand::MO_MachineRegister;
346 getMachineRegNum = target.getRegInfo().getZeroRegNum();
347 }
348 else if (canUseImmed &&
349 target.getInstrInfo().constantFitsInImmedField(opCode, intValue))
350 {
351 opType = MachineOperand::MO_SignExtendedImmed;
352 getImmedValue = intValue;
353 }
354
355 return opType;
356}
357