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