blob: b33dd022f1b9862dc5e2be24802111533461e3e4 [file] [log] [blame]
Vikram S. Advea21cf202001-07-21 12:42:19 +00001// $Id$
2//***************************************************************************
3// File:
4// SparcInstrSelection.cpp
5//
6// Purpose:
7//
8// History:
9// 7/02/01 - Vikram Adve - Created
10//***************************************************************************
11
Vikram S. Advea21cf202001-07-21 12:42:19 +000012#include "llvm/Type.h"
13#include "llvm/DerivedTypes.h"
14#include "llvm/SymbolTable.h"
15#include "llvm/Value.h"
16#include "llvm/Instruction.h"
17#include "llvm/InstrTypes.h"
18#include "llvm/iTerminators.h"
19#include "llvm/iMemory.h"
20#include "llvm/iOther.h"
21#include "llvm/BasicBlock.h"
22#include "llvm/Method.h"
23#include "llvm/ConstPoolVals.h"
Chris Lattner7e583cf2001-07-21 20:58:30 +000024#include "llvm/CodeGen/Sparc.h"
25#include "llvm/CodeGen/MachineInstr.h"
26#include "llvm/CodeGen/InstrForest.h"
27#include "llvm/CodeGen/InstrSelection.h"
Vikram S. Advea21cf202001-07-21 12:42:19 +000028
29
30//******************** Internal Data Declarations ************************/
31
32// to be used later
33struct BranchPattern {
34 bool flipCondition; // should the sense of the test be reversed
35 BasicBlock* targetBB; // which basic block to branch to
36 MachineInstr* extraBranch; // if neither branch is fall-through, then this
37 // BA must be inserted after the cond'l one
38};
39
40//************************* Forward Declarations ***************************/
41
42
Chris Lattner51a9ad92001-07-21 22:57:05 +000043static MachineOpCode ChooseBprInstruction (const InstructionNode* instrNod);
Vikram S. Advea21cf202001-07-21 12:42:19 +000044
Chris Lattner51a9ad92001-07-21 22:57:05 +000045static MachineOpCode ChooseBccInstruction (const InstructionNode* instrNode,
46 bool& isFPBranch);
Vikram S. Advea21cf202001-07-21 12:42:19 +000047
Chris Lattner51a9ad92001-07-21 22:57:05 +000048static MachineOpCode ChooseBpccInstruction (const InstructionNode* instrNode,
49 const BinaryOperator* setCCInst);
Vikram S. Advea21cf202001-07-21 12:42:19 +000050
Chris Lattner51a9ad92001-07-21 22:57:05 +000051static MachineOpCode ChooseBfpccInstruction (const InstructionNode* instrNode,
52 const BinaryOperator* setCCInst);
Vikram S. Advea21cf202001-07-21 12:42:19 +000053
Chris Lattner51a9ad92001-07-21 22:57:05 +000054static MachineOpCode ChooseConvertToFloatInstr(const InstructionNode* instrNode,
55 const Type* opType);
Vikram S. Advea21cf202001-07-21 12:42:19 +000056
Chris Lattner51a9ad92001-07-21 22:57:05 +000057static MachineOpCode ChooseConvertToIntInstr (const InstructionNode* instrNode,
58 const Type* opType);
Vikram S. Advea21cf202001-07-21 12:42:19 +000059
Chris Lattner51a9ad92001-07-21 22:57:05 +000060static MachineOpCode ChooseAddInstruction (const InstructionNode* instrNod);
Vikram S. Advea21cf202001-07-21 12:42:19 +000061
Chris Lattner51a9ad92001-07-21 22:57:05 +000062static MachineOpCode ChooseSubInstruction (const InstructionNode* instrNod);
Vikram S. Advea21cf202001-07-21 12:42:19 +000063
Chris Lattner51a9ad92001-07-21 22:57:05 +000064static MachineOpCode ChooseFcmpInstruction (const InstructionNode* instrNod);
Vikram S. Advea21cf202001-07-21 12:42:19 +000065
Chris Lattner51a9ad92001-07-21 22:57:05 +000066static MachineOpCode ChooseMulInstruction (const InstructionNode* instrNode,
67 bool checkCasts);
Vikram S. Advea21cf202001-07-21 12:42:19 +000068
Chris Lattner51a9ad92001-07-21 22:57:05 +000069static MachineOpCode ChooseDivInstruction (const InstructionNode* instrNod);
Vikram S. Advea21cf202001-07-21 12:42:19 +000070
Chris Lattner51a9ad92001-07-21 22:57:05 +000071static MachineOpCode ChooseLoadInstruction (const Type* resultType);
Vikram S. Advea21cf202001-07-21 12:42:19 +000072
Chris Lattner51a9ad92001-07-21 22:57:05 +000073static MachineOpCode ChooseStoreInstruction (const Type* valueType);
Vikram S. Advea21cf202001-07-21 12:42:19 +000074
75static void SetOperandsForMemInstr (MachineInstr* minstr,
76 const InstructionNode* vmInstrNode,
77 const TargetMachine& targetMachine);
78
79static void SetMemOperands_Internal (MachineInstr* minstr,
80 const InstructionNode* vmInstrNode,
81 Value* ptrVal,
82 Value* arrayOffsetVal,
83 const vector<ConstPoolVal*>& idxVec,
84 const TargetMachine& targetMachine);
85
86static unsigned FixConstantOperands(const InstructionNode* vmInstrNode,
87 MachineInstr** mvec,
88 unsigned numInstr,
89 TargetMachine& targetMachine);
90
91static unsigned InsertLoadConstInstructions(unsigned loadConstFlags,
92 const InstructionNode* vmInstrNode,
93 MachineInstr** mvec,
94 unsigned numInstr);
95
96static MachineInstr* MakeOneLoadConstInstr(Instruction* vmInstr,
97 Value* val);
98
99
100//******************* Externally Visible Functions *************************/
101
102
103//------------------------------------------------------------------------
104// External Function: ThisIsAChainRule
105//
106// Purpose:
107// Check if a given BURG rule is a chain rule.
108//------------------------------------------------------------------------
109
110extern bool
111ThisIsAChainRule(int eruleno)
112{
113 switch(eruleno)
114 {
115 case 111: // stmt: reg
116 case 112: // stmt: boolconst
117 case 113: // stmt: bool
118 case 121:
119 case 122:
120 case 123:
121 case 124:
122 case 125:
123 case 126:
124 case 127:
125 case 128:
126 case 129:
127 case 130:
128 case 131:
129 case 132:
130 case 153: return true; break;
131
132 default: return false; break;
133 }
134}
135
136//------------------------------------------------------------------------
137// External Function: GetInstructionsByRule
138//
139// Purpose:
140// Choose machine instructions for the SPARC according to the
141// patterns chosen by the BURG-generated parser.
142//------------------------------------------------------------------------
143
144unsigned
145GetInstructionsByRule(InstructionNode* subtreeRoot,
146 int ruleForNode,
147 short* nts,
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000148 TargetMachine &Target,
Vikram S. Advea21cf202001-07-21 12:42:19 +0000149 MachineInstr** mvec)
150{
151 int numInstr = 1; // initialize for common case
152 bool checkCast = false; // initialize here to use fall-through
153 Value *leftVal, *rightVal;
154 const Type* opType;
155 int nextRule;
156 BranchPattern brPattern;
157
158 mvec[0] = mvec[1] = mvec[2] = mvec[3] = NULL; // just for safety
159
160 switch(ruleForNode) {
161 case 1: // stmt: Ret
162 case 2: // stmt: RetValue(reg)
163 // NOTE: Prepass of register allocation is responsible
164 // for moving return value to appropriate register.
165 // Mark the return-address register as a hidden virtual reg.
166 {
167 Instruction* returnReg = new TmpInstruction(Instruction::UserOp1,
168 subtreeRoot->getInstruction(), NULL);
169 subtreeRoot->getInstruction()->getMachineInstrVec().addTempValue(returnReg);
170
171 mvec[0] = new MachineInstr(RETURN);
172 mvec[0]->SetMachineOperand(0, MachineOperand::MO_Register, returnReg);
173 mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
174 (int64_t) 0);
175
176 mvec[numInstr++] = new MachineInstr(NOP); // delay slot
177 break;
178 }
179
180 case 3: // stmt: Store(reg,reg)
181 case 4: // stmt: Store(reg,ptrreg)
182 mvec[0] = new MachineInstr(ChooseStoreInstruction(subtreeRoot->leftChild()->getValue()->getType()));
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000183 SetOperandsForMemInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000184 break;
185
186 case 5: // stmt: BrUncond
187 mvec[0] = new MachineInstr(BA);
188 mvec[0]->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp,
189 ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
190
191 mvec[numInstr++] = new MachineInstr(NOP); // delay slot
192 break;
193
194 case 6: // stmt: BrCond(boolconst)
195 // boolconst => boolean was computed with `%b = setCC type reg1 constant'
196 // If the constant is ZERO, we can use the branch-on-integer-register
197 // instructions and avoid the SUBcc instruction entirely.
198 // Otherwise this is just the same as case 5, so just fall through.
199 {
200 InstrTreeNode* constNode = subtreeRoot->leftChild()->rightChild();
201 assert(constNode && constNode->getNodeType() ==InstrTreeNode::NTConstNode);
202 ConstPoolVal* constVal = (ConstPoolVal*) constNode->getValue();
203
204 if (constVal->getType()->isIntegral()
205 && ((constVal->getType()->isSigned()
206 && ((ConstPoolSInt*) constVal)->getValue()==0)
207 || (constVal->getType()->isUnsigned()
208 && ((ConstPoolUInt*) constVal)->getValue()== 0)))
209 {
210 // Whew! Ok, that was zero after all...
211 // Use the left child of the setCC instruction as the first argument!
212 mvec[0] = new MachineInstr(ChooseBprInstruction(subtreeRoot));
213 mvec[0]->SetMachineOperand(0, MachineOperand::MO_Register,
214 subtreeRoot->leftChild()->leftChild()->getValue());
215 mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
216 ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
217
218 mvec[numInstr++] = new MachineInstr(NOP); // delay slot
219
220 mvec[numInstr++] = new MachineInstr(BA); // false branch
221 mvec[numInstr-1]->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp, ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(1));
222 break;
223 }
224 // ELSE FALL THROUGH
225 }
226
227 case 7: // stmt: BrCond(bool)
228 // bool => boolean was computed with `%b = setcc type reg1 reg2'
229 // Need to check whether the type was a FP, signed int or unsigned int,
230 // nad check the branching condition in order to choose the branch to use.
231 // Also, for FP branches, an extra operand specifies which FCCn reg to use.
232 //
233 {
234 bool isFPBranch;
235 mvec[0] = new MachineInstr(ChooseBccInstruction(subtreeRoot, isFPBranch));
236
237 int opNum = 0;
238 if (isFPBranch)
239 mvec[0]->SetMachineOperand(opNum++, MachineOperand::MO_CCRegister,
240 subtreeRoot->leftChild()->getValue());
241
242 mvec[0]->SetMachineOperand(opNum, MachineOperand::MO_PCRelativeDisp,
243 ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
244
245 mvec[numInstr++] = new MachineInstr(NOP); // delay slot
246
247 mvec[numInstr++] = new MachineInstr(BA); // false branch
248 mvec[numInstr-1]->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp, ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(1));
249 break;
250 }
251
252 case 8: // stmt: BrCond(boolreg)
253 // bool => boolean is stored in an existing register.
254 // Just use the branch-on-integer-register instruction!
255 //
256 mvec[0] = new MachineInstr(BRNZ);
257 mvec[0]->SetMachineOperand(0, MachineOperand::MO_Register,
258 subtreeRoot->leftChild()->getValue());
259 mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
260 ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
261 mvec[numInstr++] = new MachineInstr(NOP); // delay slot
262 break;
263
264 case 9: // stmt: Switch(reg)
265 assert(0 && "*** SWITCH instruction is not implemented yet.");
266 numInstr = 0;
267 break;
268
269 case 10: // reg: VRegList(reg, reg)
270 assert(0 && "VRegList should never be the topmost non-chain rule");
271 break;
272
273 case 21: // reg: Not(reg): Implemented as reg = reg XOR-NOT 0
274 mvec[0] = new MachineInstr(XNOR);
275 mvec[0]->SetMachineOperand(0, MachineOperand::MO_Register,
276 subtreeRoot->leftChild()->getValue());
277 mvec[0]->SetMachineOperand(1, /*regNum %g0*/ (unsigned int) 0);
278 mvec[0]->SetMachineOperand(2, MachineOperand::MO_Register,
279 subtreeRoot->getValue());
280 break;
281
282 case 22: // reg: ToBoolTy(reg):
283 opType = subtreeRoot->leftChild()->getValue()->getType();
284 assert(opType->isIntegral() || opType == Type::BoolTy);
285 numInstr = 0;
286 break;
287
288 case 23: // reg: ToUByteTy(reg)
289 case 25: // reg: ToUShortTy(reg)
290 case 27: // reg: ToUIntTy(reg)
291 case 29: // reg: ToULongTy(reg)
292 opType = subtreeRoot->leftChild()->getValue()->getType();
293 assert(opType->isIntegral() || opType == Type::BoolTy);
294 numInstr = 0;
295 break;
296
297 case 24: // reg: ToSByteTy(reg)
298 case 26: // reg: ToShortTy(reg)
299 case 28: // reg: ToIntTy(reg)
300 case 30: // reg: ToLongTy(reg)
301 opType = subtreeRoot->leftChild()->getValue()->getType();
302 if (opType->isIntegral() || opType == Type::BoolTy)
303 numInstr = 0;
304 else
305 {
306 mvec[0] =new MachineInstr(ChooseConvertToIntInstr(subtreeRoot,opType));
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000307 Set2OperandsFromInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000308 }
309 break;
310
311 case 31: // reg: ToFloatTy(reg):
312 case 32: // reg: ToDoubleTy(reg):
313
314 // If this instruction has a parent (a user) in the tree
315 // and the user is translated as an FsMULd instruction,
316 // then the cast is unnecessary. So check that first.
317 // In the future, we'll want to do the same for the FdMULq instruction,
318 // so do the check here instead of only for ToFloatTy(reg).
319 //
320 if (subtreeRoot->parent() != NULL &&
321 ((InstructionNode*) subtreeRoot->parent())->getInstruction()->getMachineInstrVec()[0]->getOpCode() == FSMULD)
322 {
323 numInstr = 0;
324 }
325 else
326 {
327 opType = subtreeRoot->leftChild()->getValue()->getType();
328 mvec[0] = new MachineInstr(ChooseConvertToFloatInstr(subtreeRoot, opType));
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000329 Set2OperandsFromInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000330 }
331 break;
332
333 case 19: // reg: ToArrayTy(reg):
334 case 20: // reg: ToPointerTy(reg):
335 numInstr = 0;
336 break;
337
338 case 33: // reg: Add(reg, reg)
339 mvec[0] = new MachineInstr(ChooseAddInstruction(subtreeRoot));
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000340 Set3OperandsFromInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000341 break;
342
343 case 34: // reg: Sub(reg, reg)
344 mvec[0] = new MachineInstr(ChooseSubInstruction(subtreeRoot));
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000345 Set3OperandsFromInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000346 break;
347
348 case 135: // reg: Mul(todouble, todouble)
349 checkCast = true;
350 // FALL THROUGH
351
352 case 35: // reg: Mul(reg, reg)
353 mvec[0] = new MachineInstr(ChooseMulInstruction(subtreeRoot, checkCast));
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000354 Set3OperandsFromInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000355 break;
356
357 case 36: // reg: Div(reg, reg)
358 mvec[0] = new MachineInstr(ChooseDivInstruction(subtreeRoot));
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000359 Set3OperandsFromInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000360 break;
361
362 case 37: // reg: Rem(reg, reg)
363 assert(0 && "REM instruction unimplemented for the SPARC.");
364 break;
365
366 case 38: // reg: And(reg, reg)
367 mvec[0] = new MachineInstr(AND);
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000368 Set3OperandsFromInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000369 break;
370
371 case 138: // reg: And(reg, not)
372 mvec[0] = new MachineInstr(ANDN);
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000373 Set3OperandsFromInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000374 break;
375
376 case 39: // reg: Or(reg, reg)
377 mvec[0] = new MachineInstr(ORN);
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000378 Set3OperandsFromInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000379 break;
380
381 case 139: // reg: Or(reg, not)
382 mvec[0] = new MachineInstr(ORN);
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000383 Set3OperandsFromInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000384 break;
385
386 case 40: // reg: Xor(reg, reg)
387 mvec[0] = new MachineInstr(XOR);
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000388 Set3OperandsFromInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000389 break;
390
391 case 140: // reg: Xor(reg, not)
392 mvec[0] = new MachineInstr(XNOR);
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000393 Set3OperandsFromInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000394 break;
395
396 case 41: // boolconst: SetCC(reg, Constant)
397 // Check if this is an integer comparison, and
398 // there is a parent, and the parent decided to use
399 // a branch-on-integer-register instead of branch-on-condition-code.
400 // If so, the SUBcc instruction is not required.
401 // (However, we must still check for constants to be loaded from
402 // the constant pool so that such a load can be associated with
403 // this instruction.)
404 //
405 // Otherwise this is just the same as case 7, so just fall through.
406 //
407 if (subtreeRoot->leftChild()->getValue()->getType()->isIntegral() &&
408 subtreeRoot->parent() != NULL)
409 {
410 InstructionNode* parentNode = (InstructionNode*) subtreeRoot->parent();
411 assert(parentNode->getNodeType() == InstrTreeNode::NTInstructionNode);
412 const vector<MachineInstr*>&
413 minstrVec = parentNode->getInstruction()->getMachineInstrVec();
414 MachineOpCode parentOpCode;
415 if (minstrVec.size() == 1 &&
416 (parentOpCode = minstrVec[0]->getOpCode()) >= BRZ &&
417 parentOpCode <= BRGEZ)
418 {
419 numInstr = 0;
420 break;
421 }
422 }
423 // ELSE FALL THROUGH
424
425 case 42: // bool: SetCC(reg, reg):
426 if (subtreeRoot->leftChild()->getValue()->getType()->isIntegral())
427 {
428 // integer condition: destination should be %g0
429 mvec[0] = new MachineInstr(SUBcc);
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000430 Set3OperandsFromInstr(mvec[0], subtreeRoot, Target,
Vikram S. Advea21cf202001-07-21 12:42:19 +0000431 /*canDiscardResult*/ true);
432 }
433 else
434 {
435 // FP condition: dest should be a FCCn register chosen by reg-alloc
436 mvec[0] = new MachineInstr(ChooseFcmpInstruction(subtreeRoot));
437
438 leftVal = subtreeRoot->leftChild()->getValue();
439 rightVal = subtreeRoot->rightChild()->getValue();
440 mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
441 subtreeRoot->getValue());
442 mvec[0]->SetMachineOperand(1, MachineOperand::MO_Register, leftVal);
443 mvec[0]->SetMachineOperand(2, MachineOperand::MO_Register, rightVal);
444 }
445 break;
446
447 case 43: // boolreg: VReg
448 numInstr = 0;
449 break;
450
451 case 51: // reg: Load(reg)
452 case 52: // reg: Load(ptrreg)
453 case 53: // reg: LoadIdx(reg,reg)
454 case 54: // reg: LoadIdx(ptrreg,reg)
455 mvec[0] = new MachineInstr(ChooseLoadInstruction(subtreeRoot->getValue()->getType()));
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000456 SetOperandsForMemInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000457 break;
458
459 case 55: // reg: GetElemPtr(reg)
460 case 56: // reg: GetElemPtrIdx(reg,reg)
461 if (subtreeRoot->parent() != NULL)
462 {
463 // Check if the parent was an array access.
464 // If so, we still need to generate this instruction.
465 MemAccessInst* memInst =(MemAccessInst*) subtreeRoot->getInstruction();
466 const PointerType* ptrType =
467 (const PointerType*) memInst->getPtrOperand()->getType();
468 if (! ptrType->getValueType()->isArrayType())
469 {// we don't need a separate instr
470 numInstr = 0;
471 break;
472 }
473 }
474 // else in all other cases we need to a separate ADD instruction
475 mvec[0] = new MachineInstr(ADD);
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000476 SetOperandsForMemInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000477 break;
478
479 case 57: // reg: Alloca: Implement as 2 instructions:
480 // sub %sp, tmp -> %sp
481 { // add %sp, 0 -> result
482 Instruction* instr = subtreeRoot->getInstruction();
483 const PointerType* instrType = (const PointerType*) instr->getType();
484 assert(instrType->isPointerType());
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000485 int tsize = (int) Target.findOptimalStorageSize(instrType->getValueType());
Vikram S. Advea21cf202001-07-21 12:42:19 +0000486 if (tsize == 0)
487 {
488 numInstr = 0;
489 break;
490 }
491 //else go on to create the instructions needed...
492
493 // Create a temporary Value to hold the constant type-size
494 ConstPoolSInt* valueForTSize = new ConstPoolSInt(Type::IntTy, tsize);
495 ConstantPool &cpool = instr->getParent()->getParent()->getConstantPool();
496 if (cpool.find(valueForTSize) == 0)
497 cpool.insert(valueForTSize);
498
499 // Instruction 1: sub %sp, tsize -> %sp
500 // tsize is always constant, but it may have to be put into a
501 // register if it doesn't fit in the immediate field.
502 //
503 mvec[0] = new MachineInstr(SUB);
504 mvec[0]->SetMachineOperand(0, /*regNum %sp = o6 = r[14]*/(unsigned int)14);
505 mvec[0]->SetMachineOperand(1, MachineOperand::MO_Register, valueForTSize);
506 mvec[0]->SetMachineOperand(2, /*regNum %sp = o6 = r[14]*/(unsigned int)14);
507
508 // Instruction 2: add %sp, 0 -> result
509 numInstr++;
510 mvec[1] = new MachineInstr(ADD);
511 mvec[1]->SetMachineOperand(0, /*regNum %sp = o6 = r[14]*/(unsigned int)14);
512 mvec[1]->SetMachineOperand(1, /*regNum %g0*/ (unsigned int) 0);
513 mvec[1]->SetMachineOperand(2, MachineOperand::MO_Register, instr);
514 break;
515 }
516
517 case 58: // reg: Alloca(reg): Implement as 3 instructions:
518 // mul num, typeSz -> tmp
519 // sub %sp, tmp -> %sp
520 { // add %sp, 0 -> result
521 Instruction* instr = subtreeRoot->getInstruction();
522 const PointerType* instrType = (const PointerType*) instr->getType();
523 assert(instrType->isPointerType() &&
524 instrType->getValueType()->isArrayType());
525 const Type* eltType =
526 ((ArrayType*) instrType->getValueType())->getElementType();
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000527 int tsize = (int) Target.findOptimalStorageSize(eltType);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000528
529 if (tsize == 0)
530 {
531 numInstr = 0;
532 break;
533 }
534 //else go on to create the instructions needed...
535
536 // Create a temporary Value to hold the constant type-size
537 ConstPoolSInt* valueForTSize = new ConstPoolSInt(Type::IntTy, tsize);
538 ConstantPool &cpool = instr->getParent()->getParent()->getConstantPool();
539 if (cpool.find(valueForTSize) == 0)
540 cpool.insert(valueForTSize);
541
542 // Create a temporary value to hold `tmp'
543 Instruction* tmpInstr = new TmpInstruction(Instruction::UserOp1,
544 subtreeRoot->leftChild()->getValue(),
545 NULL /*could insert tsize here*/);
546 subtreeRoot->getInstruction()->getMachineInstrVec().addTempValue(tmpInstr);
547
548 // Instruction 1: mul numElements, typeSize -> tmp
549 mvec[0] = new MachineInstr(MULX);
550 mvec[0]->SetMachineOperand(0, MachineOperand::MO_Register,
551 subtreeRoot->leftChild()->getValue());
552 mvec[0]->SetMachineOperand(1, MachineOperand::MO_Register, valueForTSize);
553 mvec[0]->SetMachineOperand(2, MachineOperand::MO_Register, tmpInstr);
554
555 // Instruction 2: sub %sp, tmp -> %sp
556 numInstr++;
557 mvec[1] = new MachineInstr(SUB);
558 mvec[1]->SetMachineOperand(0, /*regNum %sp = o6 = r[14]*/(unsigned int)14);
559 mvec[1]->SetMachineOperand(1, MachineOperand::MO_Register, tmpInstr);
560 mvec[1]->SetMachineOperand(2, /*regNum %sp = o6 = r[14]*/(unsigned int)14);
561
562 // Instruction 3: add %sp, 0 -> result
563 numInstr++;
564 mvec[2] = new MachineInstr(ADD);
565 mvec[2]->SetMachineOperand(0, /*regNum %sp = o6 = r[14]*/(unsigned int)14);
566 mvec[2]->SetMachineOperand(1, /*regNum %g0*/ (unsigned int) 0);
567 mvec[2]->SetMachineOperand(2, MachineOperand::MO_Register, instr);
568 break;
569 }
570
571 case 61: // reg: Call
572 // Generate a call-indirect (i.e., JMPL) for now to expose
573 // the potential need for registers. If an absolute address
574 // is available, replace this with a CALL instruction.
575 // Mark both the indirection register and the return-address
576 { // register as hidden virtual registers.
577
578 Instruction* targetReg = new TmpInstruction(Instruction::UserOp1,
579 ((CallInst*) subtreeRoot->getInstruction())->getCalledMethod(), NULL);
580 Instruction* returnReg = new TmpInstruction(Instruction::UserOp1,
581 subtreeRoot->getValue(), NULL);
582 subtreeRoot->getInstruction()->getMachineInstrVec().addTempValue(targetReg);
583 subtreeRoot->getInstruction()->getMachineInstrVec().addTempValue(returnReg);
584
585 mvec[0] = new MachineInstr(JMPL);
586 mvec[0]->SetMachineOperand(0, MachineOperand::MO_Register, targetReg);
587 mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
588 (int64_t) 0);
589 mvec[0]->SetMachineOperand(2, MachineOperand::MO_Register, returnReg);
590
591 mvec[numInstr++] = new MachineInstr(NOP); // delay slot
592 break;
593 }
594
595 case 62: // reg: Shl(reg, reg)
596 opType = subtreeRoot->leftChild()->getValue()->getType();
597 assert(opType->isIntegral() || opType == Type::BoolTy);
598 mvec[0] = new MachineInstr((opType == Type::LongTy)? SLLX : SLL);
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000599 Set3OperandsFromInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000600 break;
601
602 case 63: // reg: Shr(reg, reg)
603 opType = subtreeRoot->leftChild()->getValue()->getType();
604 assert(opType->isIntegral() || opType == Type::BoolTy);
605 mvec[0] = new MachineInstr((opType->isSigned()
606 ? ((opType == Type::LongTy)? SRAX : SRA)
607 : ((opType == Type::LongTy)? SRLX : SRL)));
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000608 Set3OperandsFromInstr(mvec[0], subtreeRoot, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000609 break;
610
611 case 71: // reg: VReg
612 case 72: // reg: Constant
613 numInstr = 0;
614 break;
615
616 case 111: // stmt: reg
617 case 112: // stmt: boolconst
618 case 113: // stmt: bool
619 case 121:
620 case 122:
621 case 123:
622 case 124:
623 case 125:
624 case 126:
625 case 127:
626 case 128:
627 case 129:
628 case 130:
629 case 131:
630 case 132:
631 case 153:
632 //
633 // These are all chain rules, which have a single nonterminal on the RHS.
634 // Get the rule that matches the RHS non-terminal and use that instead.
635 //
636 assert(ThisIsAChainRule(ruleForNode));
637 assert(nts[0] && ! nts[1]
638 && "A chain rule should have only one RHS non-terminal!");
639 nextRule = burm_rule(subtreeRoot->getBasicNode()->state, nts[0]);
640 nts = burm_nts[nextRule];
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000641 numInstr = GetInstructionsByRule(subtreeRoot, nextRule, nts,Target,mvec);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000642 break;
643
644 default:
645 numInstr = 0;
646 break;
647 }
648
649 numInstr =
Chris Lattner6c5a32d2001-07-23 03:09:03 +0000650 FixConstantOperands(subtreeRoot, mvec, numInstr, Target);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000651
652 return numInstr;
653}
654
655
656//---------------------------------------------------------------------------
657// Private helper routines for SPARC instruction selection.
658//---------------------------------------------------------------------------
659
660
661static MachineOpCode
662ChooseBprInstruction(const InstructionNode* instrNode)
663{
664 MachineOpCode opCode;
665
666 Instruction* setCCInstr =
667 ((InstructionNode*) instrNode->leftChild())->getInstruction();
668
669 switch(setCCInstr->getOpcode())
670 {
671 case Instruction::SetEQ: opCode = BRZ; break;
672 case Instruction::SetNE: opCode = BRNZ; break;
673 case Instruction::SetLE: opCode = BRLEZ; break;
674 case Instruction::SetGE: opCode = BRGEZ; break;
675 case Instruction::SetLT: opCode = BRLZ; break;
676 case Instruction::SetGT: opCode = BRGZ; break;
677 default:
678 assert(0 && "Unrecognized VM instruction!");
679 opCode = INVALID_OPCODE;
680 break;
681 }
682
683 return opCode;
684}
685
686
687static MachineOpCode
688ChooseBccInstruction(const InstructionNode* instrNode,
689 bool& isFPBranch)
690{
691 InstructionNode* setCCNode = (InstructionNode*) instrNode->leftChild();
692 BinaryOperator* setCCInstr = (BinaryOperator*) setCCNode->getInstruction();
693 const Type* setCCType = setCCInstr->getOperand(0)->getType();
694
695 isFPBranch = (setCCType == Type::FloatTy || setCCType == Type::DoubleTy);
696
697 if (isFPBranch)
698 return ChooseBfpccInstruction(instrNode, setCCInstr);
699 else
700 return ChooseBpccInstruction(instrNode, setCCInstr);
701}
702
703
704static MachineOpCode
705ChooseBpccInstruction(const InstructionNode* instrNode,
706 const BinaryOperator* setCCInstr)
707{
708 MachineOpCode opCode = INVALID_OPCODE;
709
710 bool isSigned = setCCInstr->getOperand(0)->getType()->isSigned();
711
712 if (isSigned)
713 {
714 switch(setCCInstr->getOpcode())
715 {
716 case Instruction::SetEQ: opCode = BE; break;
717 case Instruction::SetNE: opCode = BNE; break;
718 case Instruction::SetLE: opCode = BLE; break;
719 case Instruction::SetGE: opCode = BGE; break;
720 case Instruction::SetLT: opCode = BL; break;
721 case Instruction::SetGT: opCode = BG; break;
722 default:
723 assert(0 && "Unrecognized VM instruction!");
724 break;
725 }
726 }
727 else
728 {
729 switch(setCCInstr->getOpcode())
730 {
731 case Instruction::SetEQ: opCode = BE; break;
732 case Instruction::SetNE: opCode = BNE; break;
733 case Instruction::SetLE: opCode = BLEU; break;
734 case Instruction::SetGE: opCode = BCC; break;
735 case Instruction::SetLT: opCode = BCS; break;
736 case Instruction::SetGT: opCode = BGU; break;
737 default:
738 assert(0 && "Unrecognized VM instruction!");
739 break;
740 }
741 }
742
743 return opCode;
744}
745
746static MachineOpCode
747ChooseBfpccInstruction(const InstructionNode* instrNode,
748 const BinaryOperator* setCCInstr)
749{
750 MachineOpCode opCode = INVALID_OPCODE;
751
752 switch(setCCInstr->getOpcode())
753 {
754 case Instruction::SetEQ: opCode = FBE; break;
755 case Instruction::SetNE: opCode = FBNE; break;
756 case Instruction::SetLE: opCode = FBLE; break;
757 case Instruction::SetGE: opCode = FBGE; break;
758 case Instruction::SetLT: opCode = FBL; break;
759 case Instruction::SetGT: opCode = FBG; break;
760 default:
761 assert(0 && "Unrecognized VM instruction!");
762 break;
763 }
764
765 return opCode;
766}
767
768static MachineOpCode
769ChooseConvertToFloatInstr(const InstructionNode* instrNode,
770 const Type* opType)
771{
772 MachineOpCode opCode = INVALID_OPCODE;
773
774 switch(instrNode->getOpLabel())
775 {
776 case ToFloatTy:
777 if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
778 opCode = FITOS;
779 else if (opType == Type::LongTy)
780 opCode = FXTOS;
781 else if (opType == Type::DoubleTy)
782 opCode = FDTOS;
783 else
784 assert(0 && "Cannot convert this type to FLOAT on SPARC");
785 break;
786
787 case ToDoubleTy:
788 if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
789 opCode = FITOD;
790 else if (opType == Type::LongTy)
791 opCode = FXTOD;
792 else if (opType == Type::FloatTy)
793 opCode = FSTOD;
794 else
795 assert(0 && "Cannot convert this type to DOUBLE on SPARC");
796 break;
797
798 default:
799 break;
800 }
801
802 return opCode;
803}
804
805static MachineOpCode
806ChooseConvertToIntInstr(const InstructionNode* instrNode,
807 const Type* opType)
808{
809 MachineOpCode opCode = INVALID_OPCODE;;
810
811 int instrType = (int) instrNode->getOpLabel();
812
813 if (instrType == ToSByteTy || instrType == ToShortTy || instrType == ToIntTy)
814 {
815 switch (opType->getPrimitiveID())
816 {
817 case Type::FloatTyID: opCode = FSTOI; break;
818 case Type::DoubleTyID: opCode = FDTOI; break;
819 default:
820 assert(0 && "Non-numeric non-bool type cannot be converted to Int");
821 break;
822 }
823 }
824 else if (instrType == ToLongTy)
825 {
826 switch (opType->getPrimitiveID())
827 {
828 case Type::FloatTyID: opCode = FSTOX; break;
829 case Type::DoubleTyID: opCode = FDTOX; break;
830 default:
831 assert(0 && "Non-numeric non-bool type cannot be converted to Long");
832 break;
833 }
834 }
835 else
836 assert(0 && "Should not get here, Mo!");
837
838 return opCode;
839}
840
841
842static MachineOpCode
843ChooseAddInstruction(const InstructionNode* instrNode)
844{
845 MachineOpCode opCode = INVALID_OPCODE;
846
847 const Type* resultType = instrNode->getInstruction()->getType();
848
849 if (resultType->isIntegral() ||
850 resultType->isPointerType() ||
851 resultType->isMethodType() ||
852 resultType->isLabelType())
853 {
854 opCode = ADD;
855 }
856 else
857 {
858 Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue();
859 switch(operand->getType()->getPrimitiveID())
860 {
861 case Type::FloatTyID: opCode = FADDS; break;
862 case Type::DoubleTyID: opCode = FADDD; break;
863 default: assert(0 && "Invalid type for ADD instruction"); break;
864 }
865 }
866
867 return opCode;
868}
869
870static MachineOpCode
871ChooseSubInstruction(const InstructionNode* instrNode)
872{
873 MachineOpCode opCode = INVALID_OPCODE;
874
875 const Type* resultType = instrNode->getInstruction()->getType();
876
877 if (resultType->isIntegral() ||
878 resultType->isPointerType())
879 {
880 opCode = SUB;
881 }
882 else
883 {
884 Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue();
885 switch(operand->getType()->getPrimitiveID())
886 {
887 case Type::FloatTyID: opCode = FSUBS; break;
888 case Type::DoubleTyID: opCode = FSUBD; break;
889 default: assert(0 && "Invalid type for SUB instruction"); break;
890 }
891 }
892
893 return opCode;
894}
895
896
897static MachineOpCode
898ChooseFcmpInstruction(const InstructionNode* instrNode)
899{
900 MachineOpCode opCode = INVALID_OPCODE;
901
902 Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue();
903 switch(operand->getType()->getPrimitiveID())
904 {
905 case Type::FloatTyID: opCode = FCMPS; break;
906 case Type::DoubleTyID: opCode = FCMPD; break;
907 default: assert(0 && "Invalid type for ADD instruction"); break;
908 }
909
910 return opCode;
911}
912
913
914static MachineOpCode
915ChooseMulInstruction(const InstructionNode* instrNode,
916 bool checkCasts)
917{
918 MachineOpCode opCode = INVALID_OPCODE;
919
920 if (checkCasts)
921 {
922 // Assume that leftArg and rightArg are both cast instructions.
923 //
924 InstrTreeNode* leftArg = instrNode->leftChild();
925 InstrTreeNode* rightArg = instrNode->rightChild();
926 InstrTreeNode* leftArgArg = leftArg->leftChild();
927 InstrTreeNode* rightArgArg = rightArg->leftChild();
928 assert(leftArg->getValue()->getType() ==rightArg->getValue()->getType());
929
930 // If both arguments are floats cast to double, use FsMULd
931 if (leftArg->getValue()->getType() == Type::DoubleTy &&
932 leftArgArg->getValue()->getType() == Type::FloatTy &&
933 rightArgArg->getValue()->getType() == Type::FloatTy)
934 {
935 return opCode = FSMULD;
936 }
937 // else fall through and use the regular multiply instructions
938 }
939
940 const Type* resultType = instrNode->getInstruction()->getType();
941
942 if (resultType->isIntegral())
943 {
944 opCode = MULX;
945 }
946 else
947 {
948 switch(instrNode->leftChild()->getValue()->getType()->getPrimitiveID())
949 {
950 case Type::FloatTyID: opCode = FMULS; break;
951 case Type::DoubleTyID: opCode = FMULD; break;
952 default: assert(0 && "Invalid type for MUL instruction"); break;
953 }
954 }
955
956 return opCode;
957}
958
959
960static MachineOpCode
961ChooseDivInstruction(const InstructionNode* instrNode)
962{
963 MachineOpCode opCode = INVALID_OPCODE;
964
965 const Type* resultType = instrNode->getInstruction()->getType();
966
967 if (resultType->isIntegral())
968 {
969 opCode = resultType->isSigned()? SDIVX : UDIVX;
970 }
971 else
972 {
973 Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue();
974 switch(operand->getType()->getPrimitiveID())
975 {
976 case Type::FloatTyID: opCode = FDIVS; break;
977 case Type::DoubleTyID: opCode = FDIVD; break;
978 default: assert(0 && "Invalid type for DIV instruction"); break;
979 }
980 }
981
982 return opCode;
983}
984
985
986static MachineOpCode
987ChooseLoadInstruction(const Type* resultType)
988{
989 MachineOpCode opCode = INVALID_OPCODE;
990
991 switch (resultType->getPrimitiveID())
992 {
993 case Type::BoolTyID: opCode = LDUB; break;
994 case Type::UByteTyID: opCode = LDUB; break;
995 case Type::SByteTyID: opCode = LDSB; break;
996 case Type::UShortTyID: opCode = LDUH; break;
997 case Type::ShortTyID: opCode = LDSH; break;
998 case Type::UIntTyID: opCode = LDUW; break;
999 case Type::IntTyID: opCode = LDSW; break;
1000 case Type::ULongTyID:
1001 case Type::LongTyID: opCode = LDX; break;
1002 case Type::FloatTyID: opCode = LD; break;
1003 case Type::DoubleTyID: opCode = LDD; break;
1004 default: assert(0 && "Invalid type for Load instruction"); break;
1005 }
1006
1007 return opCode;
1008}
1009
1010
1011static MachineOpCode
1012ChooseStoreInstruction(const Type* valueType)
1013{
1014 MachineOpCode opCode = INVALID_OPCODE;
1015
1016 switch (valueType->getPrimitiveID())
1017 {
1018 case Type::BoolTyID:
1019 case Type::UByteTyID:
1020 case Type::SByteTyID: opCode = STB; break;
1021 case Type::UShortTyID:
1022 case Type::ShortTyID: opCode = STH; break;
1023 case Type::UIntTyID:
1024 case Type::IntTyID: opCode = STW; break;
1025 case Type::ULongTyID:
1026 case Type::LongTyID: opCode = STX; break;
1027 case Type::FloatTyID: opCode = ST; break;
1028 case Type::DoubleTyID: opCode = STD; break;
1029 default: assert(0 && "Invalid type for Store instruction"); break;
1030 }
1031
1032 return opCode;
1033}
1034
1035
1036//------------------------------------------------------------------------
1037// Function SetOperandsForMemInstr
1038//
1039// Choose addressing mode for the given load or store instruction.
1040// Use [reg+reg] if it is an indexed reference, and the index offset is
1041// not a constant or if it cannot fit in the offset field.
1042// Use [reg+offset] in all other cases.
1043//
1044// This assumes that all array refs are "lowered" to one of these forms:
1045// %x = load (subarray*) ptr, constant ; single constant offset
1046// %x = load (subarray*) ptr, offsetVal ; single non-constant offset
1047// Generally, this should happen via strength reduction + LICM.
1048// Also, strength reduction should take care of using the same register for
1049// the loop index variable and an array index, when that is profitable.
1050//------------------------------------------------------------------------
1051
1052static void
1053SetOperandsForMemInstr(MachineInstr* minstr,
1054 const InstructionNode* vmInstrNode,
1055 const TargetMachine& targetMachine)
1056{
1057 MemAccessInst* memInst = (MemAccessInst*) vmInstrNode->getInstruction();
1058
1059 // Variables to hold the index vector, ptr value, and offset value.
1060 // The major work here is to extract these for all 3 instruction types
1061 // and then call the common function SetMemOperands_Internal().
1062 //
1063 const vector<ConstPoolVal*>* idxVec = & memInst->getIndexVec();
1064 vector<ConstPoolVal*>* newIdxVec = NULL;
1065 Value* ptrVal;
1066 Value* arrayOffsetVal = NULL;
1067
1068 // Test if a GetElemPtr instruction is being folded into this mem instrn.
1069 // If so, it will be in the left child for Load and GetElemPtr,
1070 // and in the right child for Store instructions.
1071 //
1072 InstrTreeNode* ptrChild = (vmInstrNode->getOpLabel() == Instruction::Store
1073 ? vmInstrNode->rightChild()
1074 : vmInstrNode->leftChild());
1075
1076 if (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
1077 ptrChild->getOpLabel() == GetElemPtrIdx)
1078 {
1079 // There is a GetElemPtr instruction and there may be a chain of
1080 // more than one. Use the pointer value of the last one in the chain.
1081 // Fold the index vectors from the entire chain and from the mem
1082 // instruction into one single index vector.
1083 // Finally, we never fold for an array instruction so make that NULL.
1084
1085 newIdxVec = new vector<ConstPoolVal*>;
1086 ptrVal = FoldGetElemChain((InstructionNode*) ptrChild, *newIdxVec);
1087
1088 newIdxVec->insert(newIdxVec->end(), idxVec->begin(), idxVec->end());
1089 idxVec = newIdxVec;
1090
1091 assert(! ((PointerType*)ptrVal->getType())->getValueType()->isArrayType()
1092 && "GetElemPtr cannot be folded into array refs in selection");
1093 }
1094 else
1095 {
1096 // There is no GetElemPtr instruction.
1097 // Use the pointer value and the index vector from the Mem instruction.
1098 // If it is an array reference, get the array offset value.
1099 //
1100 ptrVal = memInst->getPtrOperand();
1101
1102 const Type* opType =
1103 ((const PointerType*) ptrVal->getType())->getValueType();
1104 if (opType->isArrayType())
1105 {
1106 assert((memInst->getNumOperands()
1107 == (unsigned) 1 + memInst->getFirstOffsetIdx())
1108 && "Array refs must be lowered before Instruction Selection");
1109
1110 arrayOffsetVal = memInst->getOperand(memInst->getFirstOffsetIdx());
1111 }
1112 }
1113
1114 SetMemOperands_Internal(minstr, vmInstrNode, ptrVal, arrayOffsetVal,
1115 *idxVec, targetMachine);
1116
1117 if (newIdxVec != NULL)
1118 delete newIdxVec;
1119}
1120
1121
1122static void
1123SetMemOperands_Internal(MachineInstr* minstr,
1124 const InstructionNode* vmInstrNode,
1125 Value* ptrVal,
1126 Value* arrayOffsetVal,
1127 const vector<ConstPoolVal*>& idxVec,
1128 const TargetMachine& targetMachine)
1129{
1130 MemAccessInst* memInst = (MemAccessInst*) vmInstrNode->getInstruction();
1131
1132 // Initialize so we default to storing the offset in a register.
1133 int64_t smallConstOffset;
1134 Value* valueForRegOffset = NULL;
1135 MachineOperand::MachineOperandType offsetOpType =MachineOperand::MO_Register;
1136
1137 // Check if there is an index vector and if so, if it translates to
1138 // a small enough constant to fit in the immediate-offset field.
1139 //
1140 if (idxVec.size() > 0)
1141 {
1142 bool isConstantOffset = false;
1143 unsigned offset;
1144
1145 const PointerType* ptrType = (PointerType*) ptrVal->getType();
1146
1147 if (ptrType->getValueType()->isStructType())
1148 {
1149 // the offset is always constant for structs
1150 isConstantOffset = true;
1151
1152 // Compute the offset value using the index vector
1153 offset = MemAccessInst::getIndexedOfsetForTarget(ptrType,
1154 idxVec, targetMachine);
1155 }
1156 else
1157 {
1158 // It must be an array ref. Check if the offset is a constant,
1159 // and that the indexing has been lowered to a single offset.
1160 //
1161 assert(ptrType->getValueType()->isArrayType());
1162 assert(arrayOffsetVal != NULL
1163 && "Expect to be given Value* for array offsets");
1164
1165 if (arrayOffsetVal->getValueType() == Value::ConstantVal)
1166 {
1167 isConstantOffset = true; // always constant for structs
1168 assert(arrayOffsetVal->getType()->isIntegral());
1169 offset = (arrayOffsetVal->getType()->isSigned())
1170 ? ((ConstPoolSInt*) arrayOffsetVal)->getValue()
1171 : (int64_t) ((ConstPoolUInt*) arrayOffsetVal)->getValue();
1172 }
1173 else
1174 {
1175 valueForRegOffset = arrayOffsetVal;
1176 }
1177 }
1178
1179 if (isConstantOffset)
1180 {
1181 // create a virtual register for the constant
1182 valueForRegOffset = new ConstPoolSInt(Type::IntTy, offset);
1183 }
1184 }
1185 else
1186 {
1187 offsetOpType = MachineOperand::MO_SignExtendedImmed;
1188 smallConstOffset = 0;
1189 }
1190
1191 // Operand 0 is value for STORE, ptr for LOAD or GET_ELEMENT_PTR
1192 // It is the left child in the instruction tree in all cases.
1193 Value* leftVal = vmInstrNode->leftChild()->getValue();
1194 minstr->SetMachineOperand(0, MachineOperand::MO_Register, leftVal);
1195
1196 // Operand 1 is ptr for STORE, offset for LOAD or GET_ELEMENT_PTR
1197 // Operand 3 is offset for STORE, result reg for LOAD or GET_ELEMENT_PTR
1198 //
1199 unsigned offsetOpNum = (memInst->getOpcode() == Instruction::Store)? 2 : 1;
1200 if (offsetOpType == MachineOperand::MO_Register)
1201 {
1202 assert(valueForRegOffset != NULL);
1203 minstr->SetMachineOperand(offsetOpNum, offsetOpType, valueForRegOffset);
1204 }
1205 else
1206 minstr->SetMachineOperand(offsetOpNum, offsetOpType, smallConstOffset);
1207
1208 if (memInst->getOpcode() == Instruction::Store)
1209 minstr->SetMachineOperand(1, MachineOperand::MO_Register, ptrVal);
1210 else
1211 minstr->SetMachineOperand(2, MachineOperand::MO_Register,
1212 vmInstrNode->getValue());
1213}
1214
1215
1216// Create one or two load instructions to load constants from the
1217// constant pool. The first instructions is stored in instrA;
1218// the second (if any) in instrB.
1219//
1220static unsigned
1221FixConstantOperands(const InstructionNode* vmInstrNode,
1222 MachineInstr** mvec,
1223 unsigned numInstr,
1224 TargetMachine& targetMachine)
1225{
1226 static MachineInstr* loadConstVec[MAX_INSTR_PER_VMINSTR];
1227
1228 unsigned numNew = 0;
1229 Instruction* vmInstr = vmInstrNode->getInstruction();
1230
1231 for (unsigned i=0; i < numInstr; i++)
1232 {
1233 MachineInstr* minstr = mvec[i];
1234 const MachineInstrInfo& instrInfo =
1235 targetMachine.machineInstrInfo[minstr->getOpCode()];
1236
1237 for (unsigned op=0; op < instrInfo.numOperands; op++)
1238 {
1239 const MachineOperand& mop = minstr->getOperand(op);
1240 Value* opValue = mop.value;
1241
1242 // skip the result position and any other positions already
1243 // marked as not a virtual register
1244 if (instrInfo.resultPos == (int) op ||
1245 opValue == NULL ||
1246 ! (mop.machineOperandType == MachineOperand::MO_Register &&
1247 mop.vregType == MachineOperand::MO_VirtualReg))
1248 {
1249 break;
1250 }
1251
1252 if (opValue->getValueType() == Value::ConstantVal)
1253 {
1254 MachineOperand::VirtualRegisterType vregType;
1255 unsigned int machineRegNum;
1256 int64_t immedValue;
1257 MachineOperand::MachineOperandType opType =
1258 ChooseRegOrImmed(opValue, minstr->getOpCode(), targetMachine,
1259 /*canUseImmed*/ (op == 1),
1260 vregType, machineRegNum, immedValue);
1261
1262 if (opType == MachineOperand::MO_Register)
1263 {
1264 if (vregType == MachineOperand::MO_MachineReg)
1265 minstr->SetMachineOperand(op, machineRegNum);
1266 else
1267 { // value is constant and must be loaded into a register
1268 loadConstVec[numNew++] =
1269 MakeOneLoadConstInstr(vmInstr, opValue);
1270 }
1271 }
1272 else
1273 minstr->SetMachineOperand(op, opType, immedValue);
1274 }
1275
1276#if 0
1277 // Either put the constant in the immediate field or
1278 // create an instruction to "put" it in a register.
1279 // Check first if it is 0 and then just use %g0.
1280 //
1281
1282 bool isValidConstant;
1283 int64_t intValue = GetConstantValueAsSignedInt(opValue,
1284 isValidConstant);
1285 if (intValue == 0 && targetMachine.zeroRegNum >= 0)
1286 {// put it in register %g0
1287 minstr->SetMachineOperand(op, targetMachine.zeroRegNum);
1288 }
1289 else if (op == 1 &&
1290 instrInfo.constantFitsInImmedField(intValue))
1291 {// put it in the immediate field
1292 MachineOperand::MachineOperandType opType =
1293 (opValue->getType()->isSigned()
1294 ? MachineOperand::MO_SignExtendedImmed
1295 : MachineOperand::MO_UnextendedImmed);
1296
1297 minstr->SetMachineOperand(op, opType, intValue);
1298 }
1299 else
1300 {// create an instruction to "put" the value in a register.
1301 loadConstVec[numNew++] =
1302 MakeOneLoadConstInstr(vmInstr, opValue);
1303 }
1304#endif
1305 }
1306 }
1307
1308 if (numNew > 0)
1309 {
1310 // Insert the new instructions *before* the old ones by moving
1311 // the old ones over `numNew' positions (last-to-first, of course!).
1312 //
1313 for (int i=numInstr-1; i >= ((int) numInstr) - (int) numNew; i--)
1314 mvec[i+numNew] = mvec[i];
1315
1316 for (unsigned i=0; i < numNew; i++)
1317 mvec[i] = loadConstVec[i];
1318 }
1319
1320 return (numInstr + numNew);
1321}
1322
1323
1324// Create one or two load instructions to load constants from the
1325// constant pool. The first instructions is stored in instrA;
1326// the second (if any) in instrB.
1327//
1328static unsigned
1329InsertLoadConstInstructions(unsigned loadConstFlags,
1330 const InstructionNode* vmInstrNode,
1331 MachineInstr** mvec,
1332 unsigned numInstr)
1333{
1334 MachineInstr *instrA = NULL, *instrB = NULL;
1335
1336 unsigned numNew = 0;
1337
1338 if (loadConstFlags & 0x01)
1339 {
1340 instrA = MakeOneLoadConstInstr(vmInstrNode->getInstruction(),
1341 vmInstrNode->leftChild()->getValue());
1342 numNew++;
1343 }
1344
1345 if (loadConstFlags & 0x02)
1346 {
1347 instrB = MakeOneLoadConstInstr(vmInstrNode->getInstruction(),
1348 vmInstrNode->rightChild()->getValue());
1349 numNew++;
1350 }
1351
1352 // Now insert the new instructions *before* the old ones by
1353 // moving the old ones over `numNew' positions (last-to-first, of course!).
1354 //
1355 for (int i=numInstr-1; i >= ((int) numInstr) - (int) numNew; i--)
1356 mvec[i+numNew] = mvec[i];
1357
1358 unsigned whichNew = 0;
1359 if (instrA != NULL)
1360 mvec[whichNew++] = instrA;
1361 if (instrB != NULL)
1362 mvec[whichNew++] = instrB;
1363 assert(whichNew == numNew);
1364
1365 return numInstr + numNew;
1366}
1367
1368
1369static MachineInstr*
1370MakeOneLoadConstInstr(Instruction* vmInstr,
1371 Value* val)
1372{
1373 assert(val->getValueType() == Value::ConstantVal);
1374
1375 MachineInstr* minstr;
1376
1377 // Use a "set" instruction for known constants that can go in an integer reg.
1378 // Use a "load" instruction for all other constants, in particular,
1379 // floating point constants.
1380 //
1381 const Type* valType = val->getType();
1382 if (valType->isIntegral() ||
1383 valType->isPointerType() ||
1384 valType == Type::BoolTy)
1385 {
1386 bool isValidConstant;
1387 if (val->getType()->isSigned())
1388 {
1389 minstr = new MachineInstr(SETSW);
1390 minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed,
1391 GetSignedIntConstantValue(val, isValidConstant));
1392 }
1393 else
1394 {
1395 minstr = new MachineInstr(SETUW);
1396 minstr->SetMachineOperand(0, MachineOperand::MO_UnextendedImmed,
1397 GetUnsignedIntConstantValue(val, isValidConstant));
1398 }
1399 minstr->SetMachineOperand(1, MachineOperand::MO_Register, val);
1400 assert(isValidConstant && "Unrecognized constant");
1401 }
1402 else
1403 {
1404 assert(valType == Type::FloatTy ||
1405 valType == Type::DoubleTy);
1406
1407 int64_t zeroOffset = 0; // to avoid overloading ambiguity with (Value*) 0
1408
1409 // Make a Load instruction, and make `val' both the ptr value *and*
1410 // the result value, and set the offset field to 0. Final code
1411 // generation will have to generate the base+offset for the constant.
1412 //
1413 minstr = new MachineInstr(ChooseLoadInstruction(val->getType()));
1414 minstr->SetMachineOperand(0, MachineOperand::MO_Register, val);
1415 minstr->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
1416 zeroOffset);
1417 minstr->SetMachineOperand(2, MachineOperand::MO_Register, val);
1418
1419 }
1420
1421 Instruction* tmpInstr = new TmpInstruction(Instruction::UserOp1, val, NULL);
1422 vmInstr->getMachineInstrVec().addTempValue(tmpInstr);
1423
1424 return minstr;
1425}
1426
1427
1428// This function is currently unused and incomplete but will be
1429// used if we have a linear layout of basic blocks in LLVM code.
1430// It decides which branch should fall-through, and whether an
1431// extra unconditional branch is needed (when neither falls through).
1432//
1433void
1434ChooseBranchPattern(Instruction* vmInstr, BranchPattern& brPattern)
1435{
1436 BranchInst* brInstr = (BranchInst*) vmInstr;
1437
1438 brPattern.flipCondition = false;
1439 brPattern.targetBB = brInstr->getSuccessor(0);
1440 brPattern.extraBranch = NULL;
1441
1442 assert(brInstr->getNumSuccessors() > 1 &&
1443 "Unnecessary analysis for unconditional branch");
1444
1445 assert(0 && "Fold branches in peephole optimization");
1446}
1447