blob: 492a52f623711b7195573cf8e2b40578989d177e [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
Vikram S. Adved4228a52001-08-28 23:12:57 +000010//**************************************************************************/
Vikram S. Advea21cf202001-07-21 12:42:19 +000011
Vikram S. Adved4228a52001-08-28 23:12:57 +000012#include "llvm/Support/MathExtras.h"
Vikram S. Advea21cf202001-07-21 12:42:19 +000013#include "llvm/Type.h"
14#include "llvm/DerivedTypes.h"
15#include "llvm/SymbolTable.h"
16#include "llvm/Value.h"
17#include "llvm/Instruction.h"
18#include "llvm/InstrTypes.h"
19#include "llvm/iTerminators.h"
20#include "llvm/iMemory.h"
21#include "llvm/iOther.h"
22#include "llvm/BasicBlock.h"
23#include "llvm/Method.h"
24#include "llvm/ConstPoolVals.h"
Chris Lattner7e583cf2001-07-21 20:58:30 +000025#include "llvm/CodeGen/Sparc.h"
26#include "llvm/CodeGen/MachineInstr.h"
27#include "llvm/CodeGen/InstrForest.h"
28#include "llvm/CodeGen/InstrSelection.h"
Vikram S. Advea21cf202001-07-21 12:42:19 +000029
30
31//******************** Internal Data Declarations ************************/
32
33// to be used later
34struct BranchPattern {
35 bool flipCondition; // should the sense of the test be reversed
36 BasicBlock* targetBB; // which basic block to branch to
37 MachineInstr* extraBranch; // if neither branch is fall-through, then this
38 // BA must be inserted after the cond'l one
39};
40
41//************************* Forward Declarations ***************************/
42
43
Vikram S. Adve4f231662001-07-28 04:15:15 +000044static MachineOpCode ChooseBprInstruction (const InstructionNode* instrNode);
Vikram S. Advea21cf202001-07-21 12:42:19 +000045
Vikram S. Adve4f231662001-07-28 04:15:15 +000046static MachineOpCode ChooseBccInstruction (const InstructionNode* instrNode,
47 bool& isFPBranch);
Vikram S. Advea21cf202001-07-21 12:42:19 +000048
Vikram S. Adve4f231662001-07-28 04:15:15 +000049static MachineOpCode ChooseBpccInstruction (const InstructionNode* instrNode,
50 const BinaryOperator* setCCInst);
Vikram S. Advea21cf202001-07-21 12:42:19 +000051
Vikram S. Adve4f231662001-07-28 04:15:15 +000052static MachineOpCode ChooseBFpccInstruction (const InstructionNode* instrNode,
53 const BinaryOperator* setCCInst);
Vikram S. Advea21cf202001-07-21 12:42:19 +000054
Vikram S. Adve4f231662001-07-28 04:15:15 +000055static MachineOpCode ChooseMovFpccInstruction(const InstructionNode*);
56
57static MachineOpCode ChooseMovpccAfterSub (const InstructionNode* instrNode,
58 bool& mustClearReg,
59 int& valueToMove);
60
61static MachineOpCode ChooseConvertToFloatInstr(const InstructionNode*,
Chris Lattner51a9ad92001-07-21 22:57:05 +000062 const Type* opType);
Vikram S. Advea21cf202001-07-21 12:42:19 +000063
Vikram S. Adve4f231662001-07-28 04:15:15 +000064static MachineOpCode ChooseConvertToIntInstr(const InstructionNode* instrNode,
65 const Type* opType);
Vikram S. Advea21cf202001-07-21 12:42:19 +000066
Vikram S. Adve4f231662001-07-28 04:15:15 +000067static MachineOpCode ChooseAddInstruction (const InstructionNode* instrNode);
Vikram S. Advea21cf202001-07-21 12:42:19 +000068
Vikram S. Adve4f231662001-07-28 04:15:15 +000069static MachineOpCode ChooseSubInstruction (const InstructionNode* instrNode);
Vikram S. Advea21cf202001-07-21 12:42:19 +000070
Vikram S. Adve4f231662001-07-28 04:15:15 +000071static MachineOpCode ChooseFcmpInstruction (const InstructionNode* instrNode);
Vikram S. Advea21cf202001-07-21 12:42:19 +000072
Vikram S. Adve4f231662001-07-28 04:15:15 +000073static MachineOpCode ChooseMulInstruction (const InstructionNode* instrNode,
74 bool checkCasts);
Vikram S. Advea21cf202001-07-21 12:42:19 +000075
Vikram S. Adve4f231662001-07-28 04:15:15 +000076static MachineOpCode ChooseDivInstruction (const InstructionNode* instrNode);
Vikram S. Advea21cf202001-07-21 12:42:19 +000077
Vikram S. Adve4f231662001-07-28 04:15:15 +000078static MachineOpCode ChooseLoadInstruction (const Type* resultType);
Vikram S. Advea21cf202001-07-21 12:42:19 +000079
Vikram S. Adve4f231662001-07-28 04:15:15 +000080static MachineOpCode ChooseStoreInstruction (const Type* valueType);
Vikram S. Advea21cf202001-07-21 12:42:19 +000081
Vikram S. Adve4f231662001-07-28 04:15:15 +000082static void SetOperandsForMemInstr(MachineInstr* minstr,
Vikram S. Advea21cf202001-07-21 12:42:19 +000083 const InstructionNode* vmInstrNode,
Vikram S. Adve4f231662001-07-28 04:15:15 +000084 const TargetMachine& target);
Vikram S. Advea21cf202001-07-21 12:42:19 +000085
86static void SetMemOperands_Internal (MachineInstr* minstr,
87 const InstructionNode* vmInstrNode,
88 Value* ptrVal,
89 Value* arrayOffsetVal,
90 const vector<ConstPoolVal*>& idxVec,
Vikram S. Adve4f231662001-07-28 04:15:15 +000091 const TargetMachine& target);
Vikram S. Advea21cf202001-07-21 12:42:19 +000092
93static unsigned FixConstantOperands(const InstructionNode* vmInstrNode,
Vikram S. Adve4f231662001-07-28 04:15:15 +000094 MachineInstr** mvec,
95 unsigned numInstr,
96 TargetMachine& target);
Vikram S. Advea21cf202001-07-21 12:42:19 +000097
Vikram S. Adved4228a52001-08-28 23:12:57 +000098static MachineInstr* MakeLoadConstInstr(Instruction* vmInstr,
99 Value* val,
100 TmpInstruction*& tmpReg,
101 MachineInstr*& getMinstr2);
Vikram S. Adve4f231662001-07-28 04:15:15 +0000102
103static void ForwardOperand (InstructionNode* treeNode,
104 InstructionNode* parent,
105 int operandNum);
Vikram S. Advea21cf202001-07-21 12:42:19 +0000106
107
Vikram S. Adved4228a52001-08-28 23:12:57 +0000108//************************ Internal Functions ******************************/
Vikram S. Advea21cf202001-07-21 12:42:19 +0000109
Chris Lattner52bdd8a2001-09-09 23:01:47 +0000110// Convenience function to get the value of an integer constant, for an
111// appropriate integer or non-integer type that can be held in an integer.
112// The type of the argument must be the following:
113// GetConstantValueAsSignedInt: any of the above, but the value
114// must fit into a int64_t.
115//
116// isValidConstant is set to true if a valid constant was found.
117//
118
119static int64_t GetConstantValueAsSignedInt(const Value *V,
120 bool &isValidConstant) {
121 if (!V->isConstant()) { isValidConstant = false; return 0; }
122 isValidConstant = true;
123
124 if (V->getType() == Type::BoolTy)
125 return ((ConstPoolBool*)V)->getValue();
126 if (V->getType()->isIntegral()) {
127 if (V->getType()->isSigned())
128 return ((ConstPoolSInt*)V)->getValue();
129
130 assert(V->getType()->isUnsigned());
131 uint64_t Val = ((ConstPoolUInt*)V)->getValue();
132
133 if (Val < INT64_MAX) // then safe to cast to signed
134 return (int64_t)Val;
135 }
136
137 isValidConstant = false;
138 return 0;
139}
140
141
Vikram S. Advea21cf202001-07-21 12:42:19 +0000142
143//------------------------------------------------------------------------
144// External Function: ThisIsAChainRule
145//
146// Purpose:
147// Check if a given BURG rule is a chain rule.
148//------------------------------------------------------------------------
149
150extern bool
151ThisIsAChainRule(int eruleno)
152{
153 switch(eruleno)
154 {
155 case 111: // stmt: reg
156 case 112: // stmt: boolconst
157 case 113: // stmt: bool
158 case 121:
159 case 122:
160 case 123:
161 case 124:
162 case 125:
163 case 126:
164 case 127:
165 case 128:
166 case 129:
167 case 130:
168 case 131:
169 case 132:
Vikram S. Adve74f4a132001-07-31 21:46:57 +0000170 case 153:
171 case 155: return true; break;
Vikram S. Advea21cf202001-07-21 12:42:19 +0000172
173 default: return false; break;
174 }
175}
176
Vikram S. Adved4228a52001-08-28 23:12:57 +0000177
178static inline MachineOpCode
179ChooseBprInstruction(const InstructionNode* instrNode)
180{
181 MachineOpCode opCode;
182
183 Instruction* setCCInstr =
184 ((InstructionNode*) instrNode->leftChild())->getInstruction();
185
186 switch(setCCInstr->getOpcode())
187 {
188 case Instruction::SetEQ: opCode = BRZ; break;
189 case Instruction::SetNE: opCode = BRNZ; break;
190 case Instruction::SetLE: opCode = BRLEZ; break;
191 case Instruction::SetGE: opCode = BRGEZ; break;
192 case Instruction::SetLT: opCode = BRLZ; break;
193 case Instruction::SetGT: opCode = BRGZ; break;
194 default:
195 assert(0 && "Unrecognized VM instruction!");
196 opCode = INVALID_OPCODE;
197 break;
198 }
199
200 return opCode;
201}
202
203
204static inline MachineOpCode
205ChooseBccInstruction(const InstructionNode* instrNode,
206 bool& isFPBranch)
207{
208 InstructionNode* setCCNode = (InstructionNode*) instrNode->leftChild();
209 BinaryOperator* setCCInstr = (BinaryOperator*) setCCNode->getInstruction();
210 const Type* setCCType = setCCInstr->getOperand(0)->getType();
211
212 isFPBranch = (setCCType == Type::FloatTy || setCCType == Type::DoubleTy);
213
214 if (isFPBranch)
215 return ChooseBFpccInstruction(instrNode, setCCInstr);
216 else
217 return ChooseBpccInstruction(instrNode, setCCInstr);
218}
219
220
221static inline MachineOpCode
222ChooseBpccInstruction(const InstructionNode* instrNode,
223 const BinaryOperator* setCCInstr)
224{
225 MachineOpCode opCode = INVALID_OPCODE;
226
227 bool isSigned = setCCInstr->getOperand(0)->getType()->isSigned();
228
229 if (isSigned)
230 {
231 switch(setCCInstr->getOpcode())
232 {
233 case Instruction::SetEQ: opCode = BE; break;
234 case Instruction::SetNE: opCode = BNE; break;
235 case Instruction::SetLE: opCode = BLE; break;
236 case Instruction::SetGE: opCode = BGE; break;
237 case Instruction::SetLT: opCode = BL; break;
238 case Instruction::SetGT: opCode = BG; break;
239 default:
240 assert(0 && "Unrecognized VM instruction!");
241 break;
242 }
243 }
244 else
245 {
246 switch(setCCInstr->getOpcode())
247 {
248 case Instruction::SetEQ: opCode = BE; break;
249 case Instruction::SetNE: opCode = BNE; break;
250 case Instruction::SetLE: opCode = BLEU; break;
251 case Instruction::SetGE: opCode = BCC; break;
252 case Instruction::SetLT: opCode = BCS; break;
253 case Instruction::SetGT: opCode = BGU; break;
254 default:
255 assert(0 && "Unrecognized VM instruction!");
256 break;
257 }
258 }
259
260 return opCode;
261}
262
263static inline MachineOpCode
264ChooseBFpccInstruction(const InstructionNode* instrNode,
265 const BinaryOperator* setCCInstr)
266{
267 MachineOpCode opCode = INVALID_OPCODE;
268
269 switch(setCCInstr->getOpcode())
270 {
271 case Instruction::SetEQ: opCode = FBE; break;
272 case Instruction::SetNE: opCode = FBNE; break;
273 case Instruction::SetLE: opCode = FBLE; break;
274 case Instruction::SetGE: opCode = FBGE; break;
275 case Instruction::SetLT: opCode = FBL; break;
276 case Instruction::SetGT: opCode = FBG; break;
277 default:
278 assert(0 && "Unrecognized VM instruction!");
279 break;
280 }
281
282 return opCode;
283}
284
285
286static inline MachineOpCode
287ChooseMovFpccInstruction(const InstructionNode* instrNode)
288{
289 MachineOpCode opCode = INVALID_OPCODE;
290
291 switch(instrNode->getInstruction()->getOpcode())
292 {
293 case Instruction::SetEQ: opCode = MOVFE; break;
294 case Instruction::SetNE: opCode = MOVFNE; break;
295 case Instruction::SetLE: opCode = MOVFLE; break;
296 case Instruction::SetGE: opCode = MOVFGE; break;
297 case Instruction::SetLT: opCode = MOVFL; break;
298 case Instruction::SetGT: opCode = MOVFG; break;
299 default:
300 assert(0 && "Unrecognized VM instruction!");
301 break;
302 }
303
304 return opCode;
305}
306
307
308// Assumes that SUBcc v1, v2 -> v3 has been executed.
309// In most cases, we want to clear v3 and then follow it by instruction
310// MOVcc 1 -> v3.
311// Set mustClearReg=false if v3 need not be cleared before conditional move.
312// Set valueToMove=0 if we want to conditionally move 0 instead of 1
313// (i.e., we want to test inverse of a condition)
314//
315//
316static MachineOpCode
317ChooseMovpccAfterSub(const InstructionNode* instrNode,
318 bool& mustClearReg,
319 int& valueToMove)
320{
321 MachineOpCode opCode = INVALID_OPCODE;
322 mustClearReg = true;
323 valueToMove = 1;
324
325 switch(instrNode->getInstruction()->getOpcode())
326 {
327 case Instruction::SetEQ: opCode = MOVNE; mustClearReg = false;
328 valueToMove = 0; break;
329 case Instruction::SetLE: opCode = MOVLE; break;
330 case Instruction::SetGE: opCode = MOVGE; break;
331 case Instruction::SetLT: opCode = MOVL; break;
332 case Instruction::SetGT: opCode = MOVG; break;
333
334 case Instruction::SetNE: assert(0 && "No move required!");
335
336 default:
337 assert(0 && "Unrecognized VM instruction!");
338 break;
339 }
340
341 return opCode;
342}
343
344
345static inline MachineOpCode
346ChooseConvertToFloatInstr(const InstructionNode* instrNode,
347 const Type* opType)
348{
349 MachineOpCode opCode = INVALID_OPCODE;
350
351 switch(instrNode->getOpLabel())
352 {
353 case ToFloatTy:
354 if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
355 opCode = FITOS;
356 else if (opType == Type::LongTy)
357 opCode = FXTOS;
358 else if (opType == Type::DoubleTy)
359 opCode = FDTOS;
Vikram S. Adve9856e0c2001-09-09 20:35:34 +0000360 else if (opType == Type::FloatTy)
361 ;
Vikram S. Adved4228a52001-08-28 23:12:57 +0000362 else
Vikram S. Adve9856e0c2001-09-09 20:35:34 +0000363 assert(0 && "Cannot convert this type to FLOAT on SPARC");
Vikram S. Adved4228a52001-08-28 23:12:57 +0000364 break;
365
366 case ToDoubleTy:
367 if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
368 opCode = FITOD;
369 else if (opType == Type::LongTy)
370 opCode = FXTOD;
371 else if (opType == Type::FloatTy)
372 opCode = FSTOD;
Vikram S. Adve9856e0c2001-09-09 20:35:34 +0000373 else if (opType == Type::DoubleTy)
374 ;
Vikram S. Adved4228a52001-08-28 23:12:57 +0000375 else
Vikram S. Adve9856e0c2001-09-09 20:35:34 +0000376 assert(0 && "Cannot convert this type to DOUBLE on SPARC");
Vikram S. Adved4228a52001-08-28 23:12:57 +0000377 break;
378
379 default:
380 break;
381 }
382
383 return opCode;
384}
385
386static inline MachineOpCode
387ChooseConvertToIntInstr(const InstructionNode* instrNode,
388 const Type* opType)
389{
390 MachineOpCode opCode = INVALID_OPCODE;;
391
392 int instrType = (int) instrNode->getOpLabel();
393
394 if (instrType == ToSByteTy || instrType == ToShortTy || instrType == ToIntTy)
395 {
396 switch (opType->getPrimitiveID())
397 {
398 case Type::FloatTyID: opCode = FSTOI; break;
399 case Type::DoubleTyID: opCode = FDTOI; break;
400 default:
401 assert(0 && "Non-numeric non-bool type cannot be converted to Int");
402 break;
403 }
404 }
405 else if (instrType == ToLongTy)
406 {
407 switch (opType->getPrimitiveID())
408 {
409 case Type::FloatTyID: opCode = FSTOX; break;
410 case Type::DoubleTyID: opCode = FDTOX; break;
411 default:
412 assert(0 && "Non-numeric non-bool type cannot be converted to Long");
413 break;
414 }
415 }
416 else
417 assert(0 && "Should not get here, Mo!");
418
419 return opCode;
420}
421
422
423static inline MachineOpCode
424ChooseAddInstruction(const InstructionNode* instrNode)
425{
426 MachineOpCode opCode = INVALID_OPCODE;
427
428 const Type* resultType = instrNode->getInstruction()->getType();
429
430 if (resultType->isIntegral() ||
431 resultType->isPointerType() ||
432 resultType->isMethodType() ||
433 resultType->isLabelType())
434 {
435 opCode = ADD;
436 }
437 else
438 {
439 Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue();
440 switch(operand->getType()->getPrimitiveID())
441 {
442 case Type::FloatTyID: opCode = FADDS; break;
443 case Type::DoubleTyID: opCode = FADDD; break;
444 default: assert(0 && "Invalid type for ADD instruction"); break;
445 }
446 }
447
448 return opCode;
449}
450
451
452static inline MachineInstr*
453CreateMovFloatInstruction(const InstructionNode* instrNode,
454 const Type* resultType)
455{
456 MachineInstr* minstr = new MachineInstr((resultType == Type::FloatTy)
457 ? FMOVS : FMOVD);
458 minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
459 instrNode->leftChild()->getValue());
460 minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
461 instrNode->getValue());
462 return minstr;
463}
464
465static inline MachineInstr*
466CreateAddConstInstruction(const InstructionNode* instrNode)
467{
468 MachineInstr* minstr = NULL;
469
470 Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
Chris Lattnerc4e09ec2001-09-10 20:10:26 +0000471 assert(constOp->isConstant());
Vikram S. Adved4228a52001-08-28 23:12:57 +0000472
473 // Cases worth optimizing are:
474 // (1) Add with 0 for float or double: use an FMOV of appropriate type,
475 // instead of an FADD (1 vs 3 cycles). There is no integer MOV.
476 //
477 const Type* resultType = instrNode->getInstruction()->getType();
478
Chris Lattnerc4e09ec2001-09-10 20:10:26 +0000479 if (resultType == Type::FloatTy || resultType == Type::DoubleTy) {
480 double dval = ((ConstPoolFP*) constOp)->getValue();
481 if (dval == 0.0)
482 minstr = CreateMovFloatInstruction(instrNode, resultType);
483 }
Vikram S. Adved4228a52001-08-28 23:12:57 +0000484
485 return minstr;
486}
487
488
489static inline MachineOpCode
490ChooseSubInstruction(const InstructionNode* instrNode)
491{
492 MachineOpCode opCode = INVALID_OPCODE;
493
494 const Type* resultType = instrNode->getInstruction()->getType();
495
496 if (resultType->isIntegral() ||
497 resultType->isPointerType())
498 {
499 opCode = SUB;
500 }
501 else
502 {
503 Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue();
504 switch(operand->getType()->getPrimitiveID())
505 {
506 case Type::FloatTyID: opCode = FSUBS; break;
507 case Type::DoubleTyID: opCode = FSUBD; break;
508 default: assert(0 && "Invalid type for SUB instruction"); break;
509 }
510 }
511
512 return opCode;
513}
514
515
516static inline MachineInstr*
517CreateSubConstInstruction(const InstructionNode* instrNode)
518{
519 MachineInstr* minstr = NULL;
520
521 Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
Chris Lattnerc4e09ec2001-09-10 20:10:26 +0000522 assert(constOp->isConstant());
Vikram S. Adved4228a52001-08-28 23:12:57 +0000523
524 // Cases worth optimizing are:
525 // (1) Sub with 0 for float or double: use an FMOV of appropriate type,
526 // instead of an FSUB (1 vs 3 cycles). There is no integer MOV.
527 //
528 const Type* resultType = instrNode->getInstruction()->getType();
529
530 if (resultType == Type::FloatTy ||
531 resultType == Type::DoubleTy)
532 {
533 double dval = ((ConstPoolFP*) constOp)->getValue();
534 if (dval == 0.0)
535 minstr = CreateMovFloatInstruction(instrNode, resultType);
536 }
537
538 return minstr;
539}
540
541
542static inline MachineOpCode
543ChooseFcmpInstruction(const InstructionNode* instrNode)
544{
545 MachineOpCode opCode = INVALID_OPCODE;
546
547 Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue();
548 switch(operand->getType()->getPrimitiveID())
549 {
550 case Type::FloatTyID: opCode = FCMPS; break;
551 case Type::DoubleTyID: opCode = FCMPD; break;
552 default: assert(0 && "Invalid type for FCMP instruction"); break;
553 }
554
555 return opCode;
556}
557
558
559// Assumes that leftArg and rightArg are both cast instructions.
560//
561static inline bool
562BothFloatToDouble(const InstructionNode* instrNode)
563{
564 InstrTreeNode* leftArg = instrNode->leftChild();
565 InstrTreeNode* rightArg = instrNode->rightChild();
566 InstrTreeNode* leftArgArg = leftArg->leftChild();
567 InstrTreeNode* rightArgArg = rightArg->leftChild();
568 assert(leftArg->getValue()->getType() == rightArg->getValue()->getType());
569
570 // Check if both arguments are floats cast to double
571 return (leftArg->getValue()->getType() == Type::DoubleTy &&
572 leftArgArg->getValue()->getType() == Type::FloatTy &&
573 rightArgArg->getValue()->getType() == Type::FloatTy);
574}
575
576
577static inline MachineOpCode
578ChooseMulInstruction(const InstructionNode* instrNode,
579 bool checkCasts)
580{
581 MachineOpCode opCode = INVALID_OPCODE;
582
583 if (checkCasts && BothFloatToDouble(instrNode))
584 {
585 return opCode = FSMULD;
586 }
587 // else fall through and use the regular multiply instructions
588
589 const Type* resultType = instrNode->getInstruction()->getType();
590
591 if (resultType->isIntegral())
592 {
593 opCode = MULX;
594 }
595 else
596 {
597 switch(instrNode->leftChild()->getValue()->getType()->getPrimitiveID())
598 {
599 case Type::FloatTyID: opCode = FMULS; break;
600 case Type::DoubleTyID: opCode = FMULD; break;
601 default: assert(0 && "Invalid type for MUL instruction"); break;
602 }
603 }
604
605 return opCode;
606}
607
608
609static inline MachineInstr*
610CreateIntNegInstruction(Value* vreg)
611{
612 MachineInstr* minstr = new MachineInstr(SUB);
613 minstr->SetMachineOperand(0, /*regNum %g0*/(unsigned int) 0);
614 minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, vreg);
615 minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, vreg);
616 return minstr;
617}
618
619
620static inline MachineInstr*
621CreateMulConstInstruction(const InstructionNode* instrNode,
622 MachineInstr*& getMinstr2)
623{
624 MachineInstr* minstr = NULL;
625 getMinstr2 = NULL;
626 bool needNeg = false;
627
628 Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
Chris Lattnerc4e09ec2001-09-10 20:10:26 +0000629 assert(constOp->isConstant());
Vikram S. Adved4228a52001-08-28 23:12:57 +0000630
631 // Cases worth optimizing are:
632 // (1) Multiply by 0 or 1 for any type: replace with copy (ADD or FMOV)
633 // (2) Multiply by 2^x for integer types: replace with Shift
634 //
635 const Type* resultType = instrNode->getInstruction()->getType();
636
637 if (resultType->isIntegral())
638 {
639 unsigned pow;
640 bool isValidConst;
641 int64_t C = GetConstantValueAsSignedInt(constOp, isValidConst);
642 if (isValidConst)
643 {
644 bool needNeg = false;
645 if (C < 0)
646 {
647 needNeg = true;
648 C = -C;
649 }
650
651 if (C == 0 || C == 1)
652 {
653 minstr = new MachineInstr(ADD);
654
655 if (C == 0)
656 minstr->SetMachineOperand(0, /*regNum %g0*/ (unsigned int) 0);
657 else
658 minstr->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
659 instrNode->leftChild()->getValue());
660 minstr->SetMachineOperand(1, /*regNum %g0*/ (unsigned int) 0);
661 }
662 else if (IsPowerOf2(C, pow))
663 {
664 minstr = new MachineInstr((resultType == Type::LongTy)
665 ? SLLX : SLL);
666 minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
667 instrNode->leftChild()->getValue());
668 minstr->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
669 pow);
670 }
671
672 if (minstr && needNeg)
673 { // insert <reg = SUB 0, reg> after the instr to flip the sign
674 getMinstr2 = CreateIntNegInstruction(instrNode->getValue());
675 }
676 }
677 }
678 else
679 {
680 if (resultType == Type::FloatTy ||
681 resultType == Type::DoubleTy)
682 {
683 bool isValidConst;
684 double dval = ((ConstPoolFP*) constOp)->getValue();
685
686 if (isValidConst)
687 {
688 if (dval == 0)
689 {
690 minstr = new MachineInstr((resultType == Type::FloatTy)
691 ? FITOS : FITOD);
692 minstr->SetMachineOperand(0, /*regNum %g0*/(unsigned int) 0);
693 }
694 else if (fabs(dval) == 1)
695 {
696 bool needNeg = (dval < 0);
697
698 MachineOpCode opCode = needNeg
699 ? (resultType == Type::FloatTy? FNEGS : FNEGD)
700 : (resultType == Type::FloatTy? FMOVS : FMOVD);
701
702 minstr = new MachineInstr(opCode);
703 minstr->SetMachineOperand(0,
704 MachineOperand::MO_VirtualRegister,
705 instrNode->leftChild()->getValue());
706 }
707 }
708 }
709 }
710
711 if (minstr != NULL)
712 minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
713 instrNode->getValue());
714
715 return minstr;
716}
717
718
719static inline MachineOpCode
720ChooseDivInstruction(const InstructionNode* instrNode)
721{
722 MachineOpCode opCode = INVALID_OPCODE;
723
724 const Type* resultType = instrNode->getInstruction()->getType();
725
726 if (resultType->isIntegral())
727 {
728 opCode = resultType->isSigned()? SDIVX : UDIVX;
729 }
730 else
731 {
732 Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue();
733 switch(operand->getType()->getPrimitiveID())
734 {
735 case Type::FloatTyID: opCode = FDIVS; break;
736 case Type::DoubleTyID: opCode = FDIVD; break;
737 default: assert(0 && "Invalid type for DIV instruction"); break;
738 }
739 }
740
741 return opCode;
742}
743
744
745static inline MachineInstr*
746CreateDivConstInstruction(const InstructionNode* instrNode,
747 MachineInstr*& getMinstr2)
748{
749 MachineInstr* minstr = NULL;
750 getMinstr2 = NULL;
751
752 Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
Chris Lattnerc4e09ec2001-09-10 20:10:26 +0000753 assert(constOp->isConstant());
Vikram S. Adved4228a52001-08-28 23:12:57 +0000754
755 // Cases worth optimizing are:
756 // (1) Divide by 1 for any type: replace with copy (ADD or FMOV)
757 // (2) Divide by 2^x for integer types: replace with SR[L or A]{X}
758 //
759 const Type* resultType = instrNode->getInstruction()->getType();
760
761 if (resultType->isIntegral())
762 {
763 unsigned pow;
764 bool isValidConst;
765 int64_t C = GetConstantValueAsSignedInt(constOp, isValidConst);
766 if (isValidConst)
767 {
768 bool needNeg = false;
769 if (C < 0)
770 {
771 needNeg = true;
772 C = -C;
773 }
774
775 if (C == 1)
776 {
777 minstr = new MachineInstr(ADD);
778 minstr->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
779 instrNode->leftChild()->getValue());
780 minstr->SetMachineOperand(1, /*regNum %g0*/ (unsigned int) 0);
781 }
782 else if (IsPowerOf2(C, pow))
783 {
784 MachineOpCode opCode= ((resultType->isSigned())
785 ? (resultType==Type::LongTy)? SRAX : SRA
786 : (resultType==Type::LongTy)? SRLX : SRL);
787 minstr = new MachineInstr(opCode);
788 minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
789 instrNode->leftChild()->getValue());
790 minstr->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
791 pow);
792 }
793
794 if (minstr && needNeg)
795 { // insert <reg = SUB 0, reg> after the instr to flip the sign
796 getMinstr2 = CreateIntNegInstruction(instrNode->getValue());
797 }
798 }
799 }
800 else
801 {
802 if (resultType == Type::FloatTy ||
803 resultType == Type::DoubleTy)
804 {
805 bool isValidConst;
806 double dval = ((ConstPoolFP*) constOp)->getValue();
807
808 if (isValidConst && fabs(dval) == 1)
809 {
810 bool needNeg = (dval < 0);
811
812 MachineOpCode opCode = needNeg
813 ? (resultType == Type::FloatTy? FNEGS : FNEGD)
814 : (resultType == Type::FloatTy? FMOVS : FMOVD);
815
816 minstr = new MachineInstr(opCode);
817 minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
818 instrNode->leftChild()->getValue());
819 }
820 }
821 }
822
823 if (minstr != NULL)
824 minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
825 instrNode->getValue());
826
827 return minstr;
828}
829
830
831static inline MachineOpCode
832ChooseLoadInstruction(const Type* resultType)
833{
834 MachineOpCode opCode = INVALID_OPCODE;
835
836 switch (resultType->getPrimitiveID())
837 {
838 case Type::BoolTyID: opCode = LDUB; break;
839 case Type::UByteTyID: opCode = LDUB; break;
840 case Type::SByteTyID: opCode = LDSB; break;
841 case Type::UShortTyID: opCode = LDUH; break;
842 case Type::ShortTyID: opCode = LDSH; break;
843 case Type::UIntTyID: opCode = LDUW; break;
844 case Type::IntTyID: opCode = LDSW; break;
845 case Type::ULongTyID:
846 case Type::LongTyID: opCode = LDX; break;
847 case Type::FloatTyID: opCode = LD; break;
848 case Type::DoubleTyID: opCode = LDD; break;
849 default: assert(0 && "Invalid type for Load instruction"); break;
850 }
851
852 return opCode;
853}
854
855
856static inline MachineOpCode
857ChooseStoreInstruction(const Type* valueType)
858{
859 MachineOpCode opCode = INVALID_OPCODE;
860
861 switch (valueType->getPrimitiveID())
862 {
863 case Type::BoolTyID:
864 case Type::UByteTyID:
865 case Type::SByteTyID: opCode = STB; break;
866 case Type::UShortTyID:
867 case Type::ShortTyID: opCode = STH; break;
868 case Type::UIntTyID:
869 case Type::IntTyID: opCode = STW; break;
870 case Type::ULongTyID:
871 case Type::LongTyID: opCode = STX; break;
872 case Type::FloatTyID: opCode = ST; break;
873 case Type::DoubleTyID: opCode = STD; break;
874 default: assert(0 && "Invalid type for Store instruction"); break;
875 }
876
877 return opCode;
878}
879
880
881//------------------------------------------------------------------------
882// Function SetOperandsForMemInstr
883//
884// Choose addressing mode for the given load or store instruction.
885// Use [reg+reg] if it is an indexed reference, and the index offset is
886// not a constant or if it cannot fit in the offset field.
887// Use [reg+offset] in all other cases.
888//
889// This assumes that all array refs are "lowered" to one of these forms:
890// %x = load (subarray*) ptr, constant ; single constant offset
891// %x = load (subarray*) ptr, offsetVal ; single non-constant offset
892// Generally, this should happen via strength reduction + LICM.
893// Also, strength reduction should take care of using the same register for
894// the loop index variable and an array index, when that is profitable.
895//------------------------------------------------------------------------
896
897static void
898SetOperandsForMemInstr(MachineInstr* minstr,
899 const InstructionNode* vmInstrNode,
900 const TargetMachine& target)
901{
902 MemAccessInst* memInst = (MemAccessInst*) vmInstrNode->getInstruction();
903
904 // Variables to hold the index vector, ptr value, and offset value.
905 // The major work here is to extract these for all 3 instruction types
906 // and then call the common function SetMemOperands_Internal().
907 //
908 const vector<ConstPoolVal*>* idxVec = & memInst->getIndexVec();
909 vector<ConstPoolVal*>* newIdxVec = NULL;
910 Value* ptrVal;
911 Value* arrayOffsetVal = NULL;
912
913 // Test if a GetElemPtr instruction is being folded into this mem instrn.
914 // If so, it will be in the left child for Load and GetElemPtr,
915 // and in the right child for Store instructions.
916 //
917 InstrTreeNode* ptrChild = (vmInstrNode->getOpLabel() == Instruction::Store
918 ? vmInstrNode->rightChild()
919 : vmInstrNode->leftChild());
920
921 if (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
922 ptrChild->getOpLabel() == GetElemPtrIdx)
923 {
924 // There is a GetElemPtr instruction and there may be a chain of
925 // more than one. Use the pointer value of the last one in the chain.
926 // Fold the index vectors from the entire chain and from the mem
927 // instruction into one single index vector.
928 // Finally, we never fold for an array instruction so make that NULL.
929
930 newIdxVec = new vector<ConstPoolVal*>;
931 ptrVal = FoldGetElemChain((InstructionNode*) ptrChild, *newIdxVec);
932
933 newIdxVec->insert(newIdxVec->end(), idxVec->begin(), idxVec->end());
934 idxVec = newIdxVec;
935
936 assert(! ((PointerType*)ptrVal->getType())->getValueType()->isArrayType()
937 && "GetElemPtr cannot be folded into array refs in selection");
938 }
939 else
940 {
941 // There is no GetElemPtr instruction.
942 // Use the pointer value and the index vector from the Mem instruction.
943 // If it is an array reference, get the array offset value.
944 //
945 ptrVal = memInst->getPtrOperand();
946
947 const Type* opType =
948 ((const PointerType*) ptrVal->getType())->getValueType();
949 if (opType->isArrayType())
950 {
951 assert((memInst->getNumOperands()
952 == (unsigned) 1 + memInst->getFirstOffsetIdx())
953 && "Array refs must be lowered before Instruction Selection");
954
955 arrayOffsetVal = memInst->getOperand(memInst->getFirstOffsetIdx());
956 }
957 }
958
959 SetMemOperands_Internal(minstr, vmInstrNode, ptrVal, arrayOffsetVal,
960 *idxVec, target);
961
962 if (newIdxVec != NULL)
963 delete newIdxVec;
964}
965
966
967static void
968SetMemOperands_Internal(MachineInstr* minstr,
969 const InstructionNode* vmInstrNode,
970 Value* ptrVal,
971 Value* arrayOffsetVal,
972 const vector<ConstPoolVal*>& idxVec,
973 const TargetMachine& target)
974{
975 MemAccessInst* memInst = (MemAccessInst*) vmInstrNode->getInstruction();
976
977 // Initialize so we default to storing the offset in a register.
978 int64_t smallConstOffset;
979 Value* valueForRegOffset = NULL;
980 MachineOperand::MachineOperandType offsetOpType =MachineOperand::MO_VirtualRegister;
981
982 // Check if there is an index vector and if so, if it translates to
983 // a small enough constant to fit in the immediate-offset field.
984 //
985 if (idxVec.size() > 0)
986 {
987 bool isConstantOffset = false;
988 unsigned offset;
989
990 const PointerType* ptrType = (PointerType*) ptrVal->getType();
991
992 if (ptrType->getValueType()->isStructType())
993 {
994 // the offset is always constant for structs
995 isConstantOffset = true;
996
997 // Compute the offset value using the index vector
998 offset = target.DataLayout.getIndexedOffset(ptrType, idxVec);
999 }
1000 else
1001 {
1002 // It must be an array ref. Check if the offset is a constant,
1003 // and that the indexing has been lowered to a single offset.
1004 //
1005 assert(ptrType->getValueType()->isArrayType());
1006 assert(arrayOffsetVal != NULL
1007 && "Expect to be given Value* for array offsets");
1008
1009 if (ConstPoolVal *CPV = arrayOffsetVal->castConstant())
1010 {
1011 isConstantOffset = true; // always constant for structs
1012 assert(arrayOffsetVal->getType()->isIntegral());
1013 offset = (CPV->getType()->isSigned()
1014 ? ((ConstPoolSInt*)CPV)->getValue()
1015 : (int64_t) ((ConstPoolUInt*)CPV)->getValue());
1016 }
1017 else
1018 {
1019 valueForRegOffset = arrayOffsetVal;
1020 }
1021 }
1022
1023 if (isConstantOffset)
1024 {
1025 // create a virtual register for the constant
Chris Lattner1fa0c092001-09-07 21:22:57 +00001026 valueForRegOffset = ConstPoolSInt::get(Type::IntTy, offset);
Vikram S. Adved4228a52001-08-28 23:12:57 +00001027 }
1028 }
1029 else
1030 {
1031 offsetOpType = MachineOperand::MO_SignExtendedImmed;
1032 smallConstOffset = 0;
1033 }
1034
1035 // Operand 0 is value for STORE, ptr for LOAD or GET_ELEMENT_PTR
1036 // It is the left child in the instruction tree in all cases.
1037 Value* leftVal = vmInstrNode->leftChild()->getValue();
1038 minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, leftVal);
1039
1040 // Operand 1 is ptr for STORE, offset for LOAD or GET_ELEMENT_PTR
1041 // Operand 3 is offset for STORE, result reg for LOAD or GET_ELEMENT_PTR
1042 //
1043 unsigned offsetOpNum = (memInst->getOpcode() == Instruction::Store)? 2 : 1;
1044 if (offsetOpType == MachineOperand::MO_VirtualRegister)
1045 {
1046 assert(valueForRegOffset != NULL);
1047 minstr->SetMachineOperand(offsetOpNum, offsetOpType, valueForRegOffset);
1048 }
1049 else
1050 minstr->SetMachineOperand(offsetOpNum, offsetOpType, smallConstOffset);
1051
1052 if (memInst->getOpcode() == Instruction::Store)
1053 minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, ptrVal);
1054 else
1055 minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
1056 vmInstrNode->getValue());
1057}
1058
1059
1060// Special handling for constant operands:
1061// -- if the constant is 0, use the hardwired 0 register, if any;
1062// -- if the constant is of float or double type but has an integer value,
1063// use int-to-float conversion instruction instead of generating a load;
1064// -- if the constant fits in the IMMEDIATE field, use that field;
1065// -- else insert instructions to put the constant into a register, either
1066// directly or by loading explicitly from the constant pool.
1067//
1068static unsigned
1069FixConstantOperands(const InstructionNode* vmInstrNode,
1070 MachineInstr** mvec,
1071 unsigned numInstr,
1072 TargetMachine& target)
1073{
1074 static MachineInstr* loadConstVec[MAX_INSTR_PER_VMINSTR];
1075
1076 unsigned numNew = 0;
1077 Instruction* vmInstr = vmInstrNode->getInstruction();
1078
1079 for (unsigned i=0; i < numInstr; i++)
1080 {
1081 MachineInstr* minstr = mvec[i];
1082 const MachineInstrDescriptor& instrDesc =
1083 target.getInstrInfo().getDescriptor(minstr->getOpCode());
1084
1085 for (unsigned op=0; op < minstr->getNumOperands(); op++)
1086 {
1087 const MachineOperand& mop = minstr->getOperand(op);
1088
1089 // skip the result position (for efficiency below) and any other
1090 // positions already marked as not a virtual register
1091 if (instrDesc.resultPos == (int) op ||
1092 mop.getOperandType() != MachineOperand::MO_VirtualRegister ||
1093 mop.getVRegValue() == NULL)
1094 {
1095 break;
1096 }
1097
1098 Value* opValue = mop.getVRegValue();
1099
Chris Lattnerc4e09ec2001-09-10 20:10:26 +00001100 if (opValue->isConstant())
Vikram S. Adved4228a52001-08-28 23:12:57 +00001101 {
1102 unsigned int machineRegNum;
1103 int64_t immedValue;
1104 MachineOperand::MachineOperandType opType =
1105 ChooseRegOrImmed(opValue, minstr->getOpCode(), target,
1106 /*canUseImmed*/ (op == 1),
1107 machineRegNum, immedValue);
1108
1109 if (opType == MachineOperand::MO_MachineRegister)
1110 minstr->SetMachineOperand(op, machineRegNum);
1111 else if (opType == MachineOperand::MO_VirtualRegister)
1112 {
1113 // value is constant and must be loaded into a register
1114 TmpInstruction* tmpReg;
1115 MachineInstr* minstr2;
1116 loadConstVec[numNew++] = MakeLoadConstInstr(vmInstr, opValue,
1117 tmpReg, minstr2);
1118 minstr->SetMachineOperand(op, opType, tmpReg);
1119 if (minstr2 != NULL)
1120 loadConstVec[numNew++] = minstr2;
1121 }
1122 else
1123 minstr->SetMachineOperand(op, opType, immedValue);
1124 }
1125 }
1126 }
1127
1128 if (numNew > 0)
1129 {
1130 // Insert the new instructions *before* the old ones by moving
1131 // the old ones over `numNew' positions (last-to-first, of course!).
1132 // We do check *after* returning that we did not exceed the vector mvec.
1133 for (int i=numInstr-1; i >= 0; i--)
1134 mvec[i+numNew] = mvec[i];
1135
1136 for (unsigned i=0; i < numNew; i++)
1137 mvec[i] = loadConstVec[i];
1138 }
1139
1140 return (numInstr + numNew);
1141}
1142
1143
1144static inline MachineInstr*
1145MakeIntSetInstruction(int64_t C, bool isSigned, Value* dest)
1146{
1147 MachineInstr* minstr;
1148 if (isSigned)
1149 {
1150 minstr = new MachineInstr(SETSW);
1151 minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C);
1152 }
1153 else
1154 {
1155 minstr = new MachineInstr(SETUW);
1156 minstr->SetMachineOperand(0, MachineOperand::MO_UnextendedImmed, C);
1157 }
1158
1159 minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, dest);
1160
1161 return minstr;
1162}
1163
1164
1165static MachineInstr*
1166MakeLoadConstInstr(Instruction* vmInstr,
1167 Value* val,
1168 TmpInstruction*& tmpReg,
1169 MachineInstr*& getMinstr2)
1170{
Chris Lattnerc4e09ec2001-09-10 20:10:26 +00001171 assert(val->isConstant());
Vikram S. Adved4228a52001-08-28 23:12:57 +00001172
1173 MachineInstr* minstr;
1174
1175 getMinstr2 = NULL;
1176
1177 // Create a TmpInstruction to mark the hidden register used for the constant
1178 tmpReg = new TmpInstruction(Instruction::UserOp1, val, NULL);
1179 vmInstr->getMachineInstrVec().addTempValue(tmpReg);
1180
1181 // Use a "set" instruction for known constants that can go in an integer reg.
1182 // Use a "set" instruction followed by a int-to-float conversion for known
1183 // constants that must go in a floating point reg but have an integer value.
1184 // Use a "load" instruction for all other constants, in particular,
1185 // floating point constants.
1186 //
1187 const Type* valType = val->getType();
1188
1189 if (valType->isIntegral() ||
1190 valType->isPointerType() ||
1191 valType == Type::BoolTy)
1192 {
1193 bool isValidConstant;
1194 int64_t C = GetConstantValueAsSignedInt(val, isValidConstant);
1195 assert(isValidConstant && "Unrecognized constant");
1196
1197 minstr = MakeIntSetInstruction(C, valType->isSigned(), tmpReg);
1198 }
1199 else
1200 {
1201 assert(valType == Type::FloatTy || valType == Type::DoubleTy);
1202 double dval = ((ConstPoolFP*) val)->getValue();
1203 if (dval == (int64_t) dval)
1204 {
1205 // The constant actually has an integer value, so use a
1206 // [set; int-to-float] sequence instead of a load instruction.
1207 //
1208 TmpInstruction* tmpReg2 = NULL;
1209 if (dval != 0.0)
1210 { // First, create an integer constant of the same value as dval
Chris Lattner1fa0c092001-09-07 21:22:57 +00001211 ConstPoolSInt* ival = ConstPoolSInt::get(Type::IntTy,
1212 (int64_t) dval);
Vikram S. Adved4228a52001-08-28 23:12:57 +00001213 // Create another TmpInstruction for the hidden integer register
1214 TmpInstruction* tmpReg2 =
1215 new TmpInstruction(Instruction::UserOp1, ival, NULL);
1216 vmInstr->getMachineInstrVec().addTempValue(tmpReg2);
1217
1218 // Create the `SET' instruction
1219 minstr = MakeIntSetInstruction((int64_t)dval, true, tmpReg2);
1220 }
1221
1222 // In which variable do we put the second instruction?
1223 MachineInstr*& instr2 = (minstr)? getMinstr2 : minstr;
1224
1225 // Create the int-to-float instruction
1226 instr2 = new MachineInstr(valType == Type::FloatTy? FITOS : FITOD);
1227
1228 if (dval == 0.0)
1229 instr2->SetMachineOperand(0, /*regNum %g0*/ (unsigned int) 0);
1230 else
1231 instr2->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
1232 tmpReg2);
1233
1234 instr2->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
1235 tmpReg);
1236 }
1237 else
1238 {
1239 // Make a Load instruction, and make `val' both the ptr value *and*
1240 // the result value, and set the offset field to 0. Final code
1241 // generation will have to generate the base+offset for the constant.
1242 //
1243 int64_t zeroOffset = 0; // to avoid ambiguity with (Value*) 0
1244 minstr = new MachineInstr(ChooseLoadInstruction(val->getType()));
1245 minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,val);
1246 minstr->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
1247 zeroOffset);
1248 minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
1249 tmpReg);
1250 }
1251 }
1252
1253 tmpReg->addMachineInstruction(minstr);
1254
1255 assert(minstr);
1256 return minstr;
1257}
1258
1259//
1260// Substitute operand `operandNum' of the instruction in node `treeNode'
1261// in place the use(s) of that instruction in node `parent'.
1262//
1263static void
1264ForwardOperand(InstructionNode* treeNode,
1265 InstructionNode* parent,
1266 int operandNum)
1267{
1268 Instruction* unusedOp = treeNode->getInstruction();
1269 Value* fwdOp = unusedOp->getOperand(operandNum);
1270 Instruction* userInstr = parent->getInstruction();
1271 MachineCodeForVMInstr& mvec = userInstr->getMachineInstrVec();
1272 for (unsigned i=0, N=mvec.size(); i < N; i++)
1273 {
1274 MachineInstr* minstr = mvec[i];
1275 for (unsigned i=0, numOps=minstr->getNumOperands(); i < numOps; i++)
1276 {
1277 const MachineOperand& mop = minstr->getOperand(i);
1278 if (mop.getOperandType() == MachineOperand::MO_VirtualRegister &&
1279 mop.getVRegValue() == unusedOp)
1280 {
1281 minstr->SetMachineOperand(i, MachineOperand::MO_VirtualRegister,
1282 fwdOp);
1283 }
1284 }
1285 }
1286}
1287
1288
1289// This function is currently unused and incomplete but will be
1290// used if we have a linear layout of basic blocks in LLVM code.
1291// It decides which branch should fall-through, and whether an
1292// extra unconditional branch is needed (when neither falls through).
1293//
1294void
1295ChooseBranchPattern(Instruction* vmInstr, BranchPattern& brPattern)
1296{
1297 BranchInst* brInstr = (BranchInst*) vmInstr;
1298
1299 brPattern.flipCondition = false;
1300 brPattern.targetBB = brInstr->getSuccessor(0);
1301 brPattern.extraBranch = NULL;
1302
1303 assert(brInstr->getNumSuccessors() > 1 &&
1304 "Unnecessary analysis for unconditional branch");
1305
1306 assert(0 && "Fold branches in peephole optimization");
1307}
1308
1309
1310//******************* Externally Visible Functions *************************/
1311
1312
Vikram S. Advea21cf202001-07-21 12:42:19 +00001313//------------------------------------------------------------------------
1314// External Function: GetInstructionsByRule
1315//
1316// Purpose:
1317// Choose machine instructions for the SPARC according to the
1318// patterns chosen by the BURG-generated parser.
1319//------------------------------------------------------------------------
1320
1321unsigned
1322GetInstructionsByRule(InstructionNode* subtreeRoot,
1323 int ruleForNode,
1324 short* nts,
Vikram S. Adve4f231662001-07-28 04:15:15 +00001325 TargetMachine &target,
Vikram S. Advea21cf202001-07-21 12:42:19 +00001326 MachineInstr** mvec)
1327{
1328 int numInstr = 1; // initialize for common case
1329 bool checkCast = false; // initialize here to use fall-through
1330 Value *leftVal, *rightVal;
1331 const Type* opType;
1332 int nextRule;
Vikram S. Adve4f231662001-07-28 04:15:15 +00001333 int forwardOperandNum = -1;
Vikram S. Advea21cf202001-07-21 12:42:19 +00001334 BranchPattern brPattern;
Vikram S. Adve4f231662001-07-28 04:15:15 +00001335 int64_t s0 = 0; // variables holding zero to avoid
1336 uint64_t u0 = 0; // overloading ambiguities below
Vikram S. Advea21cf202001-07-21 12:42:19 +00001337
1338 mvec[0] = mvec[1] = mvec[2] = mvec[3] = NULL; // just for safety
1339
1340 switch(ruleForNode) {
1341 case 1: // stmt: Ret
1342 case 2: // stmt: RetValue(reg)
1343 // NOTE: Prepass of register allocation is responsible
1344 // for moving return value to appropriate register.
1345 // Mark the return-address register as a hidden virtual reg.
1346 {
1347 Instruction* returnReg = new TmpInstruction(Instruction::UserOp1,
1348 subtreeRoot->getInstruction(), NULL);
1349 subtreeRoot->getInstruction()->getMachineInstrVec().addTempValue(returnReg);
1350
1351 mvec[0] = new MachineInstr(RETURN);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001352 mvec[0]->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,returnReg);
1353 mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed, s0);
1354
1355 returnReg->addMachineInstruction(mvec[0]);
1356
Vikram S. Advea21cf202001-07-21 12:42:19 +00001357 mvec[numInstr++] = new MachineInstr(NOP); // delay slot
1358 break;
1359 }
1360
1361 case 3: // stmt: Store(reg,reg)
1362 case 4: // stmt: Store(reg,ptrreg)
1363 mvec[0] = new MachineInstr(ChooseStoreInstruction(subtreeRoot->leftChild()->getValue()->getType()));
Vikram S. Adve4f231662001-07-28 04:15:15 +00001364 SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001365 break;
1366
1367 case 5: // stmt: BrUncond
1368 mvec[0] = new MachineInstr(BA);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001369 mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister, (Value*)NULL);
1370 mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
Vikram S. Advea21cf202001-07-21 12:42:19 +00001371 ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
1372
Vikram S. Adved4228a52001-08-28 23:12:57 +00001373 // delay slot
1374 mvec[numInstr++] = new MachineInstr(NOP);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001375 break;
1376
1377 case 6: // stmt: BrCond(boolconst)
1378 // boolconst => boolean was computed with `%b = setCC type reg1 constant'
1379 // If the constant is ZERO, we can use the branch-on-integer-register
1380 // instructions and avoid the SUBcc instruction entirely.
1381 // Otherwise this is just the same as case 5, so just fall through.
1382 {
1383 InstrTreeNode* constNode = subtreeRoot->leftChild()->rightChild();
1384 assert(constNode && constNode->getNodeType() ==InstrTreeNode::NTConstNode);
1385 ConstPoolVal* constVal = (ConstPoolVal*) constNode->getValue();
Vikram S. Adve4f231662001-07-28 04:15:15 +00001386 bool isValidConst;
Vikram S. Advea21cf202001-07-21 12:42:19 +00001387
1388 if (constVal->getType()->isIntegral()
Vikram S. Adve4f231662001-07-28 04:15:15 +00001389 && GetConstantValueAsSignedInt(constVal, isValidConst) == 0
1390 && isValidConst)
Vikram S. Advea21cf202001-07-21 12:42:19 +00001391 {
Vikram S. Adve4f231662001-07-28 04:15:15 +00001392 // That constant ia a zero after all...
Vikram S. Advea21cf202001-07-21 12:42:19 +00001393 // Use the left child of the setCC instruction as the first argument!
1394 mvec[0] = new MachineInstr(ChooseBprInstruction(subtreeRoot));
Vikram S. Adve4f231662001-07-28 04:15:15 +00001395 mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
Vikram S. Advea21cf202001-07-21 12:42:19 +00001396 subtreeRoot->leftChild()->leftChild()->getValue());
1397 mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
1398 ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
1399
Vikram S. Adve4f231662001-07-28 04:15:15 +00001400 // delay slot
1401 mvec[numInstr++] = new MachineInstr(NOP);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001402
Vikram S. Adve4f231662001-07-28 04:15:15 +00001403 // false branch
1404 mvec[numInstr++] = new MachineInstr(BA);
1405 mvec[numInstr-1]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
1406 (Value*) NULL);
1407 mvec[numInstr-1]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp, ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(1));
Vikram S. Adved4228a52001-08-28 23:12:57 +00001408
1409 // delay slot
1410 mvec[numInstr++] = new MachineInstr(NOP);
1411
Vikram S. Advea21cf202001-07-21 12:42:19 +00001412 break;
1413 }
1414 // ELSE FALL THROUGH
1415 }
1416
1417 case 7: // stmt: BrCond(bool)
1418 // bool => boolean was computed with `%b = setcc type reg1 reg2'
1419 // Need to check whether the type was a FP, signed int or unsigned int,
Vikram S. Adve4f231662001-07-28 04:15:15 +00001420 // and check the branching condition in order to choose the branch to use.
Vikram S. Advea21cf202001-07-21 12:42:19 +00001421 //
1422 {
1423 bool isFPBranch;
1424 mvec[0] = new MachineInstr(ChooseBccInstruction(subtreeRoot, isFPBranch));
Vikram S. Adve4f231662001-07-28 04:15:15 +00001425 mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
1426 subtreeRoot->leftChild()->getValue());
1427 mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
Vikram S. Advea21cf202001-07-21 12:42:19 +00001428 ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
1429
Vikram S. Adve4f231662001-07-28 04:15:15 +00001430 // delay slot
1431 mvec[numInstr++] = new MachineInstr(NOP);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001432
Vikram S. Adve4f231662001-07-28 04:15:15 +00001433 // false branch
1434 mvec[numInstr++] = new MachineInstr(BA);
1435 mvec[numInstr-1]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
1436 (Value*) NULL);
1437 mvec[numInstr-1]->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp,
1438 ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(1));
Vikram S. Adved4228a52001-08-28 23:12:57 +00001439
1440 // delay slot
1441 mvec[numInstr++] = new MachineInstr(NOP);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001442 break;
1443 }
Vikram S. Adve4f231662001-07-28 04:15:15 +00001444
Vikram S. Advea21cf202001-07-21 12:42:19 +00001445 case 8: // stmt: BrCond(boolreg)
1446 // bool => boolean is stored in an existing register.
1447 // Just use the branch-on-integer-register instruction!
1448 //
1449 mvec[0] = new MachineInstr(BRNZ);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001450 mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
1451 subtreeRoot->leftChild()->getValue());
Vikram S. Advea21cf202001-07-21 12:42:19 +00001452 mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
1453 ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
Vikram S. Adved4228a52001-08-28 23:12:57 +00001454
1455 // delay slot
Vikram S. Advea21cf202001-07-21 12:42:19 +00001456 mvec[numInstr++] = new MachineInstr(NOP); // delay slot
Vikram S. Adved4228a52001-08-28 23:12:57 +00001457
1458 // false branch
1459 mvec[numInstr++] = new MachineInstr(BA);
1460 mvec[numInstr-1]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
1461 (Value*) NULL);
1462 mvec[numInstr-1]->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp,
1463 ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(1));
1464
1465 // delay slot
1466 mvec[numInstr++] = new MachineInstr(NOP);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001467 break;
1468
1469 case 9: // stmt: Switch(reg)
1470 assert(0 && "*** SWITCH instruction is not implemented yet.");
1471 numInstr = 0;
1472 break;
1473
1474 case 10: // reg: VRegList(reg, reg)
1475 assert(0 && "VRegList should never be the topmost non-chain rule");
1476 break;
1477
1478 case 21: // reg: Not(reg): Implemented as reg = reg XOR-NOT 0
1479 mvec[0] = new MachineInstr(XNOR);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001480 mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
Vikram S. Advea21cf202001-07-21 12:42:19 +00001481 subtreeRoot->leftChild()->getValue());
1482 mvec[0]->SetMachineOperand(1, /*regNum %g0*/ (unsigned int) 0);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001483 mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
Vikram S. Advea21cf202001-07-21 12:42:19 +00001484 subtreeRoot->getValue());
1485 break;
1486
1487 case 22: // reg: ToBoolTy(reg):
1488 opType = subtreeRoot->leftChild()->getValue()->getType();
1489 assert(opType->isIntegral() || opType == Type::BoolTy);
1490 numInstr = 0;
Vikram S. Adve4f231662001-07-28 04:15:15 +00001491 forwardOperandNum = 0;
Vikram S. Advea21cf202001-07-21 12:42:19 +00001492 break;
1493
1494 case 23: // reg: ToUByteTy(reg)
1495 case 25: // reg: ToUShortTy(reg)
1496 case 27: // reg: ToUIntTy(reg)
1497 case 29: // reg: ToULongTy(reg)
1498 opType = subtreeRoot->leftChild()->getValue()->getType();
Vikram S. Adve74f4a132001-07-31 21:46:57 +00001499 assert(opType->isIntegral() ||
1500 opType->isPointerType() ||
1501 opType == Type::BoolTy && "Ignoring cast: illegal for other types");
Vikram S. Advea21cf202001-07-21 12:42:19 +00001502 numInstr = 0;
Vikram S. Adve4f231662001-07-28 04:15:15 +00001503 forwardOperandNum = 0;
Vikram S. Advea21cf202001-07-21 12:42:19 +00001504 break;
1505
1506 case 24: // reg: ToSByteTy(reg)
1507 case 26: // reg: ToShortTy(reg)
1508 case 28: // reg: ToIntTy(reg)
1509 case 30: // reg: ToLongTy(reg)
1510 opType = subtreeRoot->leftChild()->getValue()->getType();
1511 if (opType->isIntegral() || opType == Type::BoolTy)
Vikram S. Adve4f231662001-07-28 04:15:15 +00001512 {
1513 numInstr = 0;
1514 forwardOperandNum = 0;
1515 }
Vikram S. Advea21cf202001-07-21 12:42:19 +00001516 else
1517 {
1518 mvec[0] =new MachineInstr(ChooseConvertToIntInstr(subtreeRoot,opType));
Vikram S. Adve4f231662001-07-28 04:15:15 +00001519 Set2OperandsFromInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001520 }
1521 break;
1522
1523 case 31: // reg: ToFloatTy(reg):
1524 case 32: // reg: ToDoubleTy(reg):
1525
1526 // If this instruction has a parent (a user) in the tree
1527 // and the user is translated as an FsMULd instruction,
1528 // then the cast is unnecessary. So check that first.
1529 // In the future, we'll want to do the same for the FdMULq instruction,
1530 // so do the check here instead of only for ToFloatTy(reg).
1531 //
1532 if (subtreeRoot->parent() != NULL &&
1533 ((InstructionNode*) subtreeRoot->parent())->getInstruction()->getMachineInstrVec()[0]->getOpCode() == FSMULD)
1534 {
1535 numInstr = 0;
Vikram S. Adve4f231662001-07-28 04:15:15 +00001536 forwardOperandNum = 0;
Vikram S. Advea21cf202001-07-21 12:42:19 +00001537 }
1538 else
1539 {
1540 opType = subtreeRoot->leftChild()->getValue()->getType();
Vikram S. Adve9856e0c2001-09-09 20:35:34 +00001541 MachineOpCode opCode = ChooseConvertToFloatInstr(subtreeRoot, opType);
1542 if (opCode == INVALID_OPCODE) // no conversion needed
1543 {
1544 numInstr = 0;
1545 forwardOperandNum = 0;
1546 }
1547 else
1548 {
1549 mvec[0] = new MachineInstr(opCode);
1550 Set2OperandsFromInstr(mvec[0], subtreeRoot, target);
1551 }
Vikram S. Advea21cf202001-07-21 12:42:19 +00001552 }
1553 break;
1554
1555 case 19: // reg: ToArrayTy(reg):
1556 case 20: // reg: ToPointerTy(reg):
1557 numInstr = 0;
Vikram S. Adve4f231662001-07-28 04:15:15 +00001558 forwardOperandNum = 0;
Vikram S. Advea21cf202001-07-21 12:42:19 +00001559 break;
1560
Vikram S. Adved4228a52001-08-28 23:12:57 +00001561 case 233: // reg: Add(reg, Constant)
1562 mvec[0] = CreateAddConstInstruction(subtreeRoot);
1563 if (mvec[0] != NULL)
1564 break;
1565 // ELSE FALL THROUGH
1566
Vikram S. Advea21cf202001-07-21 12:42:19 +00001567 case 33: // reg: Add(reg, reg)
1568 mvec[0] = new MachineInstr(ChooseAddInstruction(subtreeRoot));
Vikram S. Adve4f231662001-07-28 04:15:15 +00001569 Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001570 break;
1571
Vikram S. Adved4228a52001-08-28 23:12:57 +00001572 case 234: // reg: Sub(reg, Constant)
1573 mvec[0] = CreateSubConstInstruction(subtreeRoot);
1574 if (mvec[0] != NULL)
1575 break;
1576 // ELSE FALL THROUGH
1577
Vikram S. Advea21cf202001-07-21 12:42:19 +00001578 case 34: // reg: Sub(reg, reg)
1579 mvec[0] = new MachineInstr(ChooseSubInstruction(subtreeRoot));
Vikram S. Adve4f231662001-07-28 04:15:15 +00001580 Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001581 break;
1582
1583 case 135: // reg: Mul(todouble, todouble)
1584 checkCast = true;
1585 // FALL THROUGH
1586
1587 case 35: // reg: Mul(reg, reg)
1588 mvec[0] = new MachineInstr(ChooseMulInstruction(subtreeRoot, checkCast));
Vikram S. Adve4f231662001-07-28 04:15:15 +00001589 Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001590 break;
Vikram S. Adved4228a52001-08-28 23:12:57 +00001591
1592 case 335: // reg: Mul(todouble, todoubleConst)
1593 checkCast = true;
1594 // FALL THROUGH
1595
1596 case 235: // reg: Mul(reg, Constant)
1597 mvec[0] = CreateMulConstInstruction(subtreeRoot, mvec[1]);
1598 if (mvec[0] == NULL)
1599 {
1600 mvec[0]=new MachineInstr(ChooseMulInstruction(subtreeRoot, checkCast));
1601 Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
1602 }
1603 else
1604 if (mvec[1] != NULL)
1605 ++numInstr;
1606 break;
1607
1608 case 236: // reg: Div(reg, Constant)
1609 mvec[0] = CreateDivConstInstruction(subtreeRoot, mvec[1]);
1610 if (mvec[0] != NULL)
1611 {
1612 if (mvec[1] != NULL)
1613 ++numInstr;
1614 }
1615 else
1616 // ELSE FALL THROUGH
Vikram S. Advea21cf202001-07-21 12:42:19 +00001617
1618 case 36: // reg: Div(reg, reg)
1619 mvec[0] = new MachineInstr(ChooseDivInstruction(subtreeRoot));
Vikram S. Adve4f231662001-07-28 04:15:15 +00001620 Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001621 break;
1622
Vikram S. Adved4228a52001-08-28 23:12:57 +00001623 case 37: // reg: Rem(reg, reg)
1624 case 237: // reg: Rem(reg, Constant)
Vikram S. Advea21cf202001-07-21 12:42:19 +00001625 assert(0 && "REM instruction unimplemented for the SPARC.");
1626 break;
1627
Vikram S. Adved4228a52001-08-28 23:12:57 +00001628 case 38: // reg: And(reg, reg)
1629 case 238: // reg: And(reg, Constant)
Vikram S. Advea21cf202001-07-21 12:42:19 +00001630 mvec[0] = new MachineInstr(AND);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001631 Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001632 break;
1633
1634 case 138: // reg: And(reg, not)
1635 mvec[0] = new MachineInstr(ANDN);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001636 Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001637 break;
1638
Vikram S. Adved4228a52001-08-28 23:12:57 +00001639 case 39: // reg: Or(reg, reg)
1640 case 239: // reg: Or(reg, Constant)
Vikram S. Advea21cf202001-07-21 12:42:19 +00001641 mvec[0] = new MachineInstr(ORN);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001642 Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001643 break;
1644
1645 case 139: // reg: Or(reg, not)
1646 mvec[0] = new MachineInstr(ORN);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001647 Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001648 break;
1649
Vikram S. Adved4228a52001-08-28 23:12:57 +00001650 case 40: // reg: Xor(reg, reg)
1651 case 240: // reg: Xor(reg, Constant)
Vikram S. Advea21cf202001-07-21 12:42:19 +00001652 mvec[0] = new MachineInstr(XOR);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001653 Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001654 break;
1655
1656 case 140: // reg: Xor(reg, not)
1657 mvec[0] = new MachineInstr(XNOR);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001658 Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001659 break;
1660
1661 case 41: // boolconst: SetCC(reg, Constant)
1662 // Check if this is an integer comparison, and
1663 // there is a parent, and the parent decided to use
1664 // a branch-on-integer-register instead of branch-on-condition-code.
1665 // If so, the SUBcc instruction is not required.
1666 // (However, we must still check for constants to be loaded from
1667 // the constant pool so that such a load can be associated with
1668 // this instruction.)
1669 //
Vikram S. Adve4f231662001-07-28 04:15:15 +00001670 // Otherwise this is just the same as case 42, so just fall through.
Vikram S. Advea21cf202001-07-21 12:42:19 +00001671 //
1672 if (subtreeRoot->leftChild()->getValue()->getType()->isIntegral() &&
1673 subtreeRoot->parent() != NULL)
1674 {
1675 InstructionNode* parentNode = (InstructionNode*) subtreeRoot->parent();
1676 assert(parentNode->getNodeType() == InstrTreeNode::NTInstructionNode);
1677 const vector<MachineInstr*>&
1678 minstrVec = parentNode->getInstruction()->getMachineInstrVec();
1679 MachineOpCode parentOpCode;
Vikram S. Adve4f231662001-07-28 04:15:15 +00001680 if (parentNode->getInstruction()->getOpcode() == Instruction::Br &&
Vikram S. Advea21cf202001-07-21 12:42:19 +00001681 (parentOpCode = minstrVec[0]->getOpCode()) >= BRZ &&
1682 parentOpCode <= BRGEZ)
1683 {
Vikram S. Adve4f231662001-07-28 04:15:15 +00001684 numInstr = 0; // don't forward the operand!
Vikram S. Advea21cf202001-07-21 12:42:19 +00001685 break;
1686 }
1687 }
1688 // ELSE FALL THROUGH
1689
1690 case 42: // bool: SetCC(reg, reg):
Vikram S. Adve4f231662001-07-28 04:15:15 +00001691 {
1692 // If result of the SetCC is only used for a branch, we can
1693 // discard the result. otherwise, it must go into an integer register.
1694 // Note that the user may or may not be in the same tree, so we have
1695 // to follow SSA def-use edges here, not BURG tree edges.
1696 //
1697 Instruction* result = subtreeRoot->getInstruction();
1698 Value* firstUse = (Value*) * result->use_begin();
1699 bool discardResult =
1700 (result->use_size() == 1
Chris Lattnerc4e09ec2001-09-10 20:10:26 +00001701 && firstUse->isInstruction()
Vikram S. Adve4f231662001-07-28 04:15:15 +00001702 && ((Instruction*) firstUse)->getOpcode() == Instruction::Br);
1703
1704 bool mustClearReg;
1705 int valueToMove;
1706 MachineOpCode movOpCode;
1707
Vikram S. Advea21cf202001-07-21 12:42:19 +00001708 if (subtreeRoot->leftChild()->getValue()->getType()->isIntegral())
1709 {
Vikram S. Adve4f231662001-07-28 04:15:15 +00001710 // integer condition: destination should be %g0 or integer register
1711 // if result must be saved but condition is not SetEQ then we need
1712 // a separate instruction to compute the bool result, so discard
1713 // result of SUBcc instruction anyway.
1714 //
Vikram S. Advea21cf202001-07-21 12:42:19 +00001715 mvec[0] = new MachineInstr(SUBcc);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001716 Set3OperandsFromInstr(mvec[0], subtreeRoot, target, discardResult);
1717
Vikram S. Adve98a9c972001-08-06 21:06:10 +00001718 // mark the 4th operand as being a CC register, and a "result"
1719 mvec[0]->SetMachineOperand(3, MachineOperand::MO_CCRegister,
1720 subtreeRoot->getValue(), /*def*/ true);
1721
1722 if (!discardResult)
Vikram S. Adve4f231662001-07-28 04:15:15 +00001723 { // recompute bool if needed, using the integer condition codes
1724 if (result->getOpcode() == Instruction::SetNE)
1725 discardResult = true;
1726 else
1727 movOpCode =
1728 ChooseMovpccAfterSub(subtreeRoot, mustClearReg, valueToMove);
1729 }
Vikram S. Advea21cf202001-07-21 12:42:19 +00001730 }
1731 else
1732 {
Vikram S. Adve4f231662001-07-28 04:15:15 +00001733 // FP condition: dest of FCMP should be some FCCn register
Vikram S. Advea21cf202001-07-21 12:42:19 +00001734 mvec[0] = new MachineInstr(ChooseFcmpInstruction(subtreeRoot));
Vikram S. Advea21cf202001-07-21 12:42:19 +00001735 mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
Vikram S. Adve4f231662001-07-28 04:15:15 +00001736 subtreeRoot->getValue());
1737 mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
1738 subtreeRoot->leftChild()->getValue());
1739 mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
1740 subtreeRoot->rightChild()->getValue());
1741
1742 if (!discardResult)
1743 {// recompute bool using the FP condition codes
1744 mustClearReg = true;
1745 valueToMove = 1;
1746 movOpCode = ChooseMovFpccInstruction(subtreeRoot);
1747 }
1748 }
1749
1750 if (!discardResult)
1751 {
1752 if (mustClearReg)
1753 {// Unconditionally set register to 0
1754 int n = numInstr++;
1755 mvec[n] = new MachineInstr(SETHI);
1756 mvec[n]->SetMachineOperand(0,MachineOperand::MO_UnextendedImmed,s0);
1757 mvec[n]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
1758 subtreeRoot->getValue());
1759 }
1760
1761 // Now conditionally move `valueToMove' (0 or 1) into the register
1762 int n = numInstr++;
1763 mvec[n] = new MachineInstr(movOpCode);
1764 mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
1765 subtreeRoot->getValue());
1766 mvec[n]->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
1767 valueToMove);
1768 mvec[n]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
1769 subtreeRoot->getValue());
Vikram S. Advea21cf202001-07-21 12:42:19 +00001770 }
1771 break;
Vikram S. Adve4f231662001-07-28 04:15:15 +00001772 }
1773
Vikram S. Advea21cf202001-07-21 12:42:19 +00001774 case 43: // boolreg: VReg
Vikram S. Adve74f4a132001-07-31 21:46:57 +00001775 case 44: // boolreg: Constant
Vikram S. Advea21cf202001-07-21 12:42:19 +00001776 numInstr = 0;
1777 break;
1778
1779 case 51: // reg: Load(reg)
1780 case 52: // reg: Load(ptrreg)
1781 case 53: // reg: LoadIdx(reg,reg)
1782 case 54: // reg: LoadIdx(ptrreg,reg)
1783 mvec[0] = new MachineInstr(ChooseLoadInstruction(subtreeRoot->getValue()->getType()));
Vikram S. Adve4f231662001-07-28 04:15:15 +00001784 SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001785 break;
1786
1787 case 55: // reg: GetElemPtr(reg)
1788 case 56: // reg: GetElemPtrIdx(reg,reg)
1789 if (subtreeRoot->parent() != NULL)
1790 {
1791 // Check if the parent was an array access.
1792 // If so, we still need to generate this instruction.
1793 MemAccessInst* memInst =(MemAccessInst*) subtreeRoot->getInstruction();
1794 const PointerType* ptrType =
1795 (const PointerType*) memInst->getPtrOperand()->getType();
1796 if (! ptrType->getValueType()->isArrayType())
1797 {// we don't need a separate instr
Vikram S. Adve4f231662001-07-28 04:15:15 +00001798 numInstr = 0; // don't forward operand!
Vikram S. Advea21cf202001-07-21 12:42:19 +00001799 break;
1800 }
1801 }
1802 // else in all other cases we need to a separate ADD instruction
1803 mvec[0] = new MachineInstr(ADD);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001804 SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001805 break;
1806
1807 case 57: // reg: Alloca: Implement as 2 instructions:
1808 // sub %sp, tmp -> %sp
1809 { // add %sp, 0 -> result
1810 Instruction* instr = subtreeRoot->getInstruction();
1811 const PointerType* instrType = (const PointerType*) instr->getType();
1812 assert(instrType->isPointerType());
Vikram S. Adve4f231662001-07-28 04:15:15 +00001813 int tsize = (int) target.findOptimalStorageSize(instrType->getValueType());
1814 assert(tsize != 0 && "Just to check when this can happen");
1815 // if (tsize == 0)
1816 // {
1817 // numInstr = 0;
1818 // break;
1819 // }
Vikram S. Advea21cf202001-07-21 12:42:19 +00001820 //else go on to create the instructions needed...
1821
1822 // Create a temporary Value to hold the constant type-size
Chris Lattner1fa0c092001-09-07 21:22:57 +00001823 ConstPoolSInt* valueForTSize = ConstPoolSInt::get(Type::IntTy, tsize);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001824
1825 // Instruction 1: sub %sp, tsize -> %sp
1826 // tsize is always constant, but it may have to be put into a
1827 // register if it doesn't fit in the immediate field.
1828 //
1829 mvec[0] = new MachineInstr(SUB);
1830 mvec[0]->SetMachineOperand(0, /*regNum %sp = o6 = r[14]*/(unsigned int)14);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001831 mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, valueForTSize);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001832 mvec[0]->SetMachineOperand(2, /*regNum %sp = o6 = r[14]*/(unsigned int)14);
1833
1834 // Instruction 2: add %sp, 0 -> result
1835 numInstr++;
1836 mvec[1] = new MachineInstr(ADD);
1837 mvec[1]->SetMachineOperand(0, /*regNum %sp = o6 = r[14]*/(unsigned int)14);
1838 mvec[1]->SetMachineOperand(1, /*regNum %g0*/ (unsigned int) 0);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001839 mvec[1]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, instr);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001840 break;
1841 }
1842
1843 case 58: // reg: Alloca(reg): Implement as 3 instructions:
1844 // mul num, typeSz -> tmp
1845 // sub %sp, tmp -> %sp
1846 { // add %sp, 0 -> result
1847 Instruction* instr = subtreeRoot->getInstruction();
1848 const PointerType* instrType = (const PointerType*) instr->getType();
1849 assert(instrType->isPointerType() &&
1850 instrType->getValueType()->isArrayType());
1851 const Type* eltType =
1852 ((ArrayType*) instrType->getValueType())->getElementType();
Vikram S. Adve4f231662001-07-28 04:15:15 +00001853 int tsize = (int) target.findOptimalStorageSize(eltType);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001854
Vikram S. Adve4f231662001-07-28 04:15:15 +00001855 assert(tsize != 0 && "Just to check when this can happen");
1856 // if (tsize == 0)
1857 // {
1858 // numInstr = 0;
1859 // break;
1860 // }
Vikram S. Advea21cf202001-07-21 12:42:19 +00001861 //else go on to create the instructions needed...
1862
1863 // Create a temporary Value to hold the constant type-size
Chris Lattner1fa0c092001-09-07 21:22:57 +00001864 ConstPoolSInt* valueForTSize = ConstPoolSInt::get(Type::IntTy, tsize);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001865
1866 // Create a temporary value to hold `tmp'
1867 Instruction* tmpInstr = new TmpInstruction(Instruction::UserOp1,
1868 subtreeRoot->leftChild()->getValue(),
1869 NULL /*could insert tsize here*/);
1870 subtreeRoot->getInstruction()->getMachineInstrVec().addTempValue(tmpInstr);
1871
1872 // Instruction 1: mul numElements, typeSize -> tmp
1873 mvec[0] = new MachineInstr(MULX);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001874 mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
Vikram S. Advea21cf202001-07-21 12:42:19 +00001875 subtreeRoot->leftChild()->getValue());
Vikram S. Adve4f231662001-07-28 04:15:15 +00001876 mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, valueForTSize);
1877 mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,tmpInstr);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001878
Vikram S. Adve4f231662001-07-28 04:15:15 +00001879 tmpInstr->addMachineInstruction(mvec[0]);
1880
Vikram S. Advea21cf202001-07-21 12:42:19 +00001881 // Instruction 2: sub %sp, tmp -> %sp
1882 numInstr++;
1883 mvec[1] = new MachineInstr(SUB);
1884 mvec[1]->SetMachineOperand(0, /*regNum %sp = o6 = r[14]*/(unsigned int)14);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001885 mvec[1]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,tmpInstr);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001886 mvec[1]->SetMachineOperand(2, /*regNum %sp = o6 = r[14]*/(unsigned int)14);
1887
1888 // Instruction 3: add %sp, 0 -> result
1889 numInstr++;
1890 mvec[2] = new MachineInstr(ADD);
1891 mvec[2]->SetMachineOperand(0, /*regNum %sp = o6 = r[14]*/(unsigned int)14);
1892 mvec[2]->SetMachineOperand(1, /*regNum %g0*/ (unsigned int) 0);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001893 mvec[2]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, instr);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001894 break;
1895 }
1896
1897 case 61: // reg: Call
1898 // Generate a call-indirect (i.e., JMPL) for now to expose
1899 // the potential need for registers. If an absolute address
1900 // is available, replace this with a CALL instruction.
1901 // Mark both the indirection register and the return-address
1902 { // register as hidden virtual registers.
1903
Vikram S. Adve4f231662001-07-28 04:15:15 +00001904 Instruction* jmpAddrReg = new TmpInstruction(Instruction::UserOp1,
Vikram S. Advea21cf202001-07-21 12:42:19 +00001905 ((CallInst*) subtreeRoot->getInstruction())->getCalledMethod(), NULL);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001906 Instruction* retAddrReg = new TmpInstruction(Instruction::UserOp1,
1907 subtreeRoot->getValue(), NULL);
1908 subtreeRoot->getInstruction()->getMachineInstrVec().addTempValue(jmpAddrReg);
1909 subtreeRoot->getInstruction()->getMachineInstrVec().addTempValue(retAddrReg);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001910
1911 mvec[0] = new MachineInstr(JMPL);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001912 mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, jmpAddrReg);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001913 mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
1914 (int64_t) 0);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001915 mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, retAddrReg);
1916
1917 // NOTE: jmpAddrReg will be loaded by a different instruction generated
1918 // by the final code generator, so we just mark the CALL instruction
1919 // as computing that value.
1920 // The retAddrReg is actually computed by the CALL instruction.
1921 //
1922 jmpAddrReg->addMachineInstruction(mvec[0]);
1923 retAddrReg->addMachineInstruction(mvec[0]);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001924
1925 mvec[numInstr++] = new MachineInstr(NOP); // delay slot
1926 break;
1927 }
1928
1929 case 62: // reg: Shl(reg, reg)
1930 opType = subtreeRoot->leftChild()->getValue()->getType();
1931 assert(opType->isIntegral() || opType == Type::BoolTy);
1932 mvec[0] = new MachineInstr((opType == Type::LongTy)? SLLX : SLL);
Vikram S. Adve4f231662001-07-28 04:15:15 +00001933 Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001934 break;
1935
1936 case 63: // reg: Shr(reg, reg)
1937 opType = subtreeRoot->leftChild()->getValue()->getType();
1938 assert(opType->isIntegral() || opType == Type::BoolTy);
1939 mvec[0] = new MachineInstr((opType->isSigned()
1940 ? ((opType == Type::LongTy)? SRAX : SRA)
1941 : ((opType == Type::LongTy)? SRLX : SRL)));
Vikram S. Adve4f231662001-07-28 04:15:15 +00001942 Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001943 break;
1944
Vikram S. Adve74f4a132001-07-31 21:46:57 +00001945 case 64: // reg: Phi(reg,reg)
1946 { // This instruction has variable #operands, so resultPos is 0.
1947 Instruction* phi = subtreeRoot->getInstruction();
1948 mvec[0] = new MachineInstr(PHI, 1 + phi->getNumOperands());
1949 mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
Vikram S. Adved4228a52001-08-28 23:12:57 +00001950 subtreeRoot->getValue());
Vikram S. Adve74f4a132001-07-31 21:46:57 +00001951 for (unsigned i=0, N=phi->getNumOperands(); i < N; i++)
1952 mvec[0]->SetMachineOperand(i+1, MachineOperand::MO_VirtualRegister,
1953 phi->getOperand(i));
1954 break;
1955 }
Vikram S. Advea21cf202001-07-21 12:42:19 +00001956 case 71: // reg: VReg
1957 case 72: // reg: Constant
Vikram S. Adve4f231662001-07-28 04:15:15 +00001958 numInstr = 0; // don't forward the value
Vikram S. Advea21cf202001-07-21 12:42:19 +00001959 break;
1960
1961 case 111: // stmt: reg
1962 case 112: // stmt: boolconst
1963 case 113: // stmt: bool
1964 case 121:
1965 case 122:
1966 case 123:
1967 case 124:
1968 case 125:
1969 case 126:
1970 case 127:
1971 case 128:
1972 case 129:
1973 case 130:
1974 case 131:
1975 case 132:
1976 case 153:
Vikram S. Adve74f4a132001-07-31 21:46:57 +00001977 case 155:
Vikram S. Advea21cf202001-07-21 12:42:19 +00001978 //
1979 // These are all chain rules, which have a single nonterminal on the RHS.
1980 // Get the rule that matches the RHS non-terminal and use that instead.
1981 //
1982 assert(ThisIsAChainRule(ruleForNode));
1983 assert(nts[0] && ! nts[1]
1984 && "A chain rule should have only one RHS non-terminal!");
1985 nextRule = burm_rule(subtreeRoot->getBasicNode()->state, nts[0]);
1986 nts = burm_nts[nextRule];
Vikram S. Adve4f231662001-07-28 04:15:15 +00001987 numInstr = GetInstructionsByRule(subtreeRoot, nextRule, nts,target,mvec);
Vikram S. Advea21cf202001-07-21 12:42:19 +00001988 break;
1989
1990 default:
Vikram S. Adve4f231662001-07-28 04:15:15 +00001991 assert(0 && "Unrecognized BURG rule");
Vikram S. Advea21cf202001-07-21 12:42:19 +00001992 numInstr = 0;
1993 break;
1994 }
1995
Vikram S. Adve4f231662001-07-28 04:15:15 +00001996 if (forwardOperandNum >= 0)
1997 { // We did not generate a machine instruction but need to use operand.
1998 // If user is in the same tree, replace Value in its machine operand.
1999 // If not, insert a copy instruction which should get coalesced away
2000 // by register allocation.
2001 if (subtreeRoot->parent() != NULL)
2002 ForwardOperand(subtreeRoot, (InstructionNode*) subtreeRoot->parent(),
2003 forwardOperandNum);
2004 else
2005 {
2006 int n = numInstr++;
2007 mvec[n] = new MachineInstr(ADD);
2008 mvec[n]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
2009 subtreeRoot->getInstruction()->getOperand(forwardOperandNum));
2010 mvec[n]->SetMachineOperand(1, /*regNum %g0*/ (unsigned int) 0);
2011 mvec[n]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
2012 subtreeRoot->getInstruction());
2013 }
2014 }
2015
2016 if (! ThisIsAChainRule(ruleForNode))
2017 numInstr = FixConstantOperands(subtreeRoot, mvec, numInstr, target);
Vikram S. Advea21cf202001-07-21 12:42:19 +00002018
2019 return numInstr;
2020}
2021
2022