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