572e1b175b3cdb173f307cabc5e3a551e62cf8c3
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9InstrSelection.cpp
1 // $Id$
2 //***************************************************************************
3 // File:
4 //      SparcInstrSelection.cpp
5 // 
6 // Purpose:
7 //      BURS instruction selection for SPARC V9 architecture.      
8 //      
9 // History:
10 //      7/02/01  -  Vikram Adve  -  Created
11 //**************************************************************************/
12
13 #include "SparcInternals.h"
14 #include "llvm/CodeGen/MachineInstr.h"
15 #include "llvm/CodeGen/InstrForest.h"
16 #include "llvm/CodeGen/InstrSelection.h"
17 #include "llvm/Support/MathExtras.h"
18 #include "llvm/DerivedTypes.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"
25
26
27 //******************** Internal Data Declarations ************************/
28
29 // to be used later
30 struct BranchPattern {
31   bool          flipCondition; // should the sense of the test be reversed
32   BasicBlock*   targetBB;      // which basic block to branch to
33   MachineInstr* extraBranch;   // if neither branch is fall-through, then this
34                                // BA must be inserted after the cond'l one
35 };
36
37 //************************* Forward Declarations ***************************/
38
39
40 static void SetMemOperands_Internal     (MachineInstr* minstr,
41                                          const InstructionNode* vmInstrNode,
42                                          Value* ptrVal,
43                                          Value* arrayOffsetVal,
44                                          const vector<ConstPoolVal*>& idxVec,
45                                          const TargetMachine& target);
46
47
48 //************************ Internal Functions ******************************/
49
50 // Convenience function to get the value of an integer constant, for an
51 // appropriate integer or non-integer type that can be held in an integer.
52 // The type of the argument must be the following:
53 //      Signed or unsigned integer
54 //      Boolean
55 //      Pointer
56 // 
57 // isValidConstant is set to true if a valid constant was found.
58 // 
59 static int64_t
60 GetConstantValueAsSignedInt(const Value *V,
61                             bool &isValidConstant)
62 {
63   if (!V->isConstant())
64     {
65       isValidConstant = false;
66       return 0;
67     }
68   
69   isValidConstant = true;
70   
71   if (V->getType() == Type::BoolTy)
72     return (int64_t) ((ConstPoolBool*)V)->getValue();
73   
74   if (V->getType()->isIntegral())
75     {
76       if (V->getType()->isSigned())
77         return ((ConstPoolSInt*)V)->getValue();
78       
79       assert(V->getType()->isUnsigned());
80       uint64_t Val = ((ConstPoolUInt*)V)->getValue();
81       if (Val < INT64_MAX)     // then safe to cast to signed
82         return (int64_t)Val;
83     }
84
85   isValidConstant = false;
86   return 0;
87 }
88
89
90
91 //------------------------------------------------------------------------ 
92 // External Function: ThisIsAChainRule
93 //
94 // Purpose:
95 //   Check if a given BURG rule is a chain rule.
96 //------------------------------------------------------------------------ 
97
98 extern bool
99 ThisIsAChainRule(int eruleno)
100 {
101   switch(eruleno)
102     {
103     case 111:   // stmt:  reg
104     case 113:   // stmt:  bool
105     case 123:
106     case 124:
107     case 125:
108     case 126:
109     case 127:
110     case 128:
111     case 129:
112     case 130:
113     case 131:
114     case 132:
115     case 133:
116     case 155:
117     case 221:
118     case 222:
119     case 241:
120     case 242:
121     case 243:
122     case 244:
123       return true; break;
124       
125     default:
126       return false; break;
127     }
128 }
129
130
131 static inline MachineOpCode 
132 ChooseBprInstruction(const InstructionNode* instrNode)
133 {
134   MachineOpCode opCode;
135   
136   Instruction* setCCInstr =
137     ((InstructionNode*) instrNode->leftChild())->getInstruction();
138   
139   switch(setCCInstr->getOpcode())
140     {
141     case Instruction::SetEQ: opCode = BRZ;   break;
142     case Instruction::SetNE: opCode = BRNZ;  break;
143     case Instruction::SetLE: opCode = BRLEZ; break;
144     case Instruction::SetGE: opCode = BRGEZ; break;
145     case Instruction::SetLT: opCode = BRLZ;  break;
146     case Instruction::SetGT: opCode = BRGZ;  break;
147     default:
148       assert(0 && "Unrecognized VM instruction!");
149       opCode = INVALID_OPCODE;
150       break; 
151     }
152   
153   return opCode;
154 }
155
156
157 static inline MachineOpCode 
158 ChooseBpccInstruction(const InstructionNode* instrNode,
159                       const BinaryOperator* setCCInstr)
160 {
161   MachineOpCode opCode = INVALID_OPCODE;
162   
163   bool isSigned = setCCInstr->getOperand(0)->getType()->isSigned();
164   
165   if (isSigned)
166     {
167       switch(setCCInstr->getOpcode())
168         {
169         case Instruction::SetEQ: opCode = BE;  break;
170         case Instruction::SetNE: opCode = BNE; break;
171         case Instruction::SetLE: opCode = BLE; break;
172         case Instruction::SetGE: opCode = BGE; break;
173         case Instruction::SetLT: opCode = BL;  break;
174         case Instruction::SetGT: opCode = BG;  break;
175         default:
176           assert(0 && "Unrecognized VM instruction!");
177           break; 
178         }
179     }
180   else
181     {
182       switch(setCCInstr->getOpcode())
183         {
184         case Instruction::SetEQ: opCode = BE;   break;
185         case Instruction::SetNE: opCode = BNE;  break;
186         case Instruction::SetLE: opCode = BLEU; break;
187         case Instruction::SetGE: opCode = BCC;  break;
188         case Instruction::SetLT: opCode = BCS;  break;
189         case Instruction::SetGT: opCode = BGU;  break;
190         default:
191           assert(0 && "Unrecognized VM instruction!");
192           break; 
193         }
194     }
195   
196   return opCode;
197 }
198
199 static inline MachineOpCode 
200 ChooseBFpccInstruction(const InstructionNode* instrNode,
201                        const BinaryOperator* setCCInstr)
202 {
203   MachineOpCode opCode = INVALID_OPCODE;
204   
205   switch(setCCInstr->getOpcode())
206     {
207     case Instruction::SetEQ: opCode = FBE;  break;
208     case Instruction::SetNE: opCode = FBNE; break;
209     case Instruction::SetLE: opCode = FBLE; break;
210     case Instruction::SetGE: opCode = FBGE; break;
211     case Instruction::SetLT: opCode = FBL;  break;
212     case Instruction::SetGT: opCode = FBG;  break;
213     default:
214       assert(0 && "Unrecognized VM instruction!");
215       break; 
216     }
217   
218   return opCode;
219 }
220
221
222 static inline MachineOpCode 
223 ChooseBccInstruction(const InstructionNode* instrNode,
224                      bool& isFPBranch)
225 {
226   InstructionNode* setCCNode = (InstructionNode*) instrNode->leftChild();
227   BinaryOperator* setCCInstr = (BinaryOperator*) setCCNode->getInstruction();
228   const Type* setCCType = setCCInstr->getOperand(0)->getType();
229   
230   isFPBranch = (setCCType == Type::FloatTy || setCCType == Type::DoubleTy); 
231   
232   if (isFPBranch) 
233     return ChooseBFpccInstruction(instrNode, setCCInstr);
234   else
235     return ChooseBpccInstruction(instrNode, setCCInstr);
236 }
237
238
239 static inline MachineOpCode 
240 ChooseMovFpccInstruction(const InstructionNode* instrNode)
241 {
242   MachineOpCode opCode = INVALID_OPCODE;
243   
244   switch(instrNode->getInstruction()->getOpcode())
245     {
246     case Instruction::SetEQ: opCode = MOVFE;  break;
247     case Instruction::SetNE: opCode = MOVFNE; break;
248     case Instruction::SetLE: opCode = MOVFLE; break;
249     case Instruction::SetGE: opCode = MOVFGE; break;
250     case Instruction::SetLT: opCode = MOVFL;  break;
251     case Instruction::SetGT: opCode = MOVFG;  break;
252     default:
253       assert(0 && "Unrecognized VM instruction!");
254       break; 
255     }
256   
257   return opCode;
258 }
259
260
261 // Assumes that SUBcc v1, v2 -> v3 has been executed.
262 // In most cases, we want to clear v3 and then follow it by instruction
263 // MOVcc 1 -> v3.
264 // Set mustClearReg=false if v3 need not be cleared before conditional move.
265 // Set valueToMove=0 if we want to conditionally move 0 instead of 1
266 //                      (i.e., we want to test inverse of a condition)
267 // (The latter two cases do not seem to arise because SetNE needs nothing.)
268 // 
269 static MachineOpCode
270 ChooseMovpccAfterSub(const InstructionNode* instrNode,
271                      bool& mustClearReg,
272                      int& valueToMove)
273 {
274   MachineOpCode opCode = INVALID_OPCODE;
275   mustClearReg = true;
276   valueToMove = 1;
277   
278   switch(instrNode->getInstruction()->getOpcode())
279     {
280     case Instruction::SetEQ: opCode = MOVE;  break;
281     case Instruction::SetLE: opCode = MOVLE; break;
282     case Instruction::SetGE: opCode = MOVGE; break;
283     case Instruction::SetLT: opCode = MOVL;  break;
284     case Instruction::SetGT: opCode = MOVG;  break;
285     case Instruction::SetNE: assert(0 && "No move required!"); break;
286     default:                 assert(0 && "Unrecognized VM instr!"); break; 
287     }
288   
289   return opCode;
290 }
291
292
293 static inline MachineOpCode
294 ChooseConvertToFloatInstr(const InstructionNode* instrNode,
295                           const Type* opType)
296 {
297   MachineOpCode opCode = INVALID_OPCODE;
298   
299   switch(instrNode->getOpLabel())
300     {
301     case ToFloatTy: 
302       if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
303         opCode = FITOS;
304       else if (opType == Type::LongTy)
305         opCode = FXTOS;
306       else if (opType == Type::DoubleTy)
307         opCode = FDTOS;
308       else if (opType == Type::FloatTy)
309         ;
310       else
311         assert(0 && "Cannot convert this type to FLOAT on SPARC");
312       break;
313       
314     case ToDoubleTy: 
315       if (opType == Type::SByteTy || opType == Type::ShortTy || opType == Type::IntTy)
316         opCode = FITOD;
317       else if (opType == Type::LongTy)
318         opCode = FXTOD;
319       else if (opType == Type::FloatTy)
320         opCode = FSTOD;
321       else if (opType == Type::DoubleTy)
322         ;
323       else
324         assert(0 && "Cannot convert this type to DOUBLE on SPARC");
325       break;
326       
327     default:
328       break;
329     }
330   
331   return opCode;
332 }
333
334 static inline MachineOpCode 
335 ChooseConvertToIntInstr(const InstructionNode* instrNode,
336                         const Type* opType)
337 {
338   MachineOpCode opCode = INVALID_OPCODE;;
339   
340   int instrType = (int) instrNode->getOpLabel();
341   
342   if (instrType == ToSByteTy || instrType == ToShortTy || instrType == ToIntTy)
343     {
344       switch (opType->getPrimitiveID())
345         {
346         case Type::FloatTyID:   opCode = FSTOI; break;
347         case Type::DoubleTyID:  opCode = FDTOI; break;
348         default:
349           assert(0 && "Non-numeric non-bool type cannot be converted to Int");
350           break;
351         }
352     }
353   else if (instrType == ToLongTy)
354     {
355       switch (opType->getPrimitiveID())
356         {
357         case Type::FloatTyID:   opCode = FSTOX; break;
358         case Type::DoubleTyID:  opCode = FDTOX; break;
359         default:
360           assert(0 && "Non-numeric non-bool type cannot be converted to Long");
361           break;
362         }
363     }
364   else
365       assert(0 && "Should not get here, Mo!");
366   
367   return opCode;
368 }
369
370
371 static inline MachineOpCode 
372 ChooseAddInstructionByType(const Type* resultType)
373 {
374   MachineOpCode opCode = INVALID_OPCODE;
375   
376   if (resultType->isIntegral() ||
377       resultType->isPointerType() ||
378       resultType->isMethodType() ||
379       resultType->isLabelType() ||
380       resultType == Type::BoolTy)
381     {
382       opCode = ADD;
383     }
384   else
385     switch(resultType->getPrimitiveID())
386       {
387       case Type::FloatTyID:  opCode = FADDS; break;
388       case Type::DoubleTyID: opCode = FADDD; break;
389       default: assert(0 && "Invalid type for ADD instruction"); break; 
390       }
391   
392   return opCode;
393 }
394
395
396 static inline MachineOpCode 
397 ChooseAddInstruction(const InstructionNode* instrNode)
398 {
399   return ChooseAddInstructionByType(instrNode->getInstruction()->getType());
400 }
401
402
403 static inline MachineInstr* 
404 CreateMovFloatInstruction(const InstructionNode* instrNode,
405                           const Type* resultType)
406 {
407   MachineInstr* minstr = new MachineInstr((resultType == Type::FloatTy)
408                                           ? FMOVS : FMOVD);
409   minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
410                             instrNode->leftChild()->getValue());
411   minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
412                             instrNode->getValue());
413   return minstr;
414 }
415
416 static inline MachineInstr* 
417 CreateAddConstInstruction(const InstructionNode* instrNode)
418 {
419   MachineInstr* minstr = NULL;
420   
421   Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
422   assert(constOp->isConstant());
423   
424   // Cases worth optimizing are:
425   // (1) Add with 0 for float or double: use an FMOV of appropriate type,
426   //     instead of an FADD (1 vs 3 cycles).  There is no integer MOV.
427   // 
428   const Type* resultType = instrNode->getInstruction()->getType();
429   
430   if (resultType == Type::FloatTy ||
431       resultType == Type::DoubleTy)
432     {
433       double dval = ((ConstPoolFP*) constOp)->getValue();
434       if (dval == 0.0)
435         minstr = CreateMovFloatInstruction(instrNode, resultType);
436     }
437   
438   return minstr;
439 }
440
441
442 static inline MachineOpCode 
443 ChooseSubInstruction(const InstructionNode* instrNode)
444 {
445   MachineOpCode opCode = INVALID_OPCODE;
446   
447   const Type* resultType = instrNode->getInstruction()->getType();
448   
449   if (resultType->isIntegral() ||
450       resultType->isPointerType())
451     {
452       opCode = SUB;
453     }
454   else
455     switch(resultType->getPrimitiveID())
456       {
457       case Type::FloatTyID:  opCode = FSUBS; break;
458       case Type::DoubleTyID: opCode = FSUBD; break;
459       default: assert(0 && "Invalid type for SUB instruction"); break; 
460       }
461   
462   return opCode;
463 }
464
465
466 static inline MachineInstr* 
467 CreateSubConstInstruction(const InstructionNode* instrNode)
468 {
469   MachineInstr* minstr = NULL;
470   
471   Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
472   assert(constOp->isConstant());
473   
474   // Cases worth optimizing are:
475   // (1) Sub with 0 for float or double: use an FMOV of appropriate type,
476   //     instead of an FSUB (1 vs 3 cycles).  There is no integer MOV.
477   // 
478   const Type* resultType = instrNode->getInstruction()->getType();
479   
480   if (resultType == Type::FloatTy ||
481       resultType == Type::DoubleTy)
482     {
483       double dval = ((ConstPoolFP*) constOp)->getValue();
484       if (dval == 0.0)
485         minstr = CreateMovFloatInstruction(instrNode, resultType);
486     }
487   
488   return minstr;
489 }
490
491
492 static inline MachineOpCode 
493 ChooseFcmpInstruction(const InstructionNode* instrNode)
494 {
495   MachineOpCode opCode = INVALID_OPCODE;
496   
497   Value* operand = ((InstrTreeNode*) instrNode->leftChild())->getValue();
498   switch(operand->getType()->getPrimitiveID()) {
499   case Type::FloatTyID:  opCode = FCMPS; break;
500   case Type::DoubleTyID: opCode = FCMPD; break;
501   default: assert(0 && "Invalid type for FCMP instruction"); break; 
502   }
503   
504   return opCode;
505 }
506
507
508 // Assumes that leftArg and rightArg are both cast instructions.
509 //
510 static inline bool
511 BothFloatToDouble(const InstructionNode* instrNode)
512 {
513   InstrTreeNode* leftArg = instrNode->leftChild();
514   InstrTreeNode* rightArg = instrNode->rightChild();
515   InstrTreeNode* leftArgArg = leftArg->leftChild();
516   InstrTreeNode* rightArgArg = rightArg->leftChild();
517   assert(leftArg->getValue()->getType() == rightArg->getValue()->getType());
518   
519   // Check if both arguments are floats cast to double
520   return (leftArg->getValue()->getType() == Type::DoubleTy &&
521           leftArgArg->getValue()->getType() == Type::FloatTy &&
522           rightArgArg->getValue()->getType() == Type::FloatTy);
523 }
524
525
526 static inline MachineOpCode 
527 ChooseMulInstruction(const InstructionNode* instrNode,
528                      bool checkCasts)
529 {
530   MachineOpCode opCode = INVALID_OPCODE;
531   
532   if (checkCasts && BothFloatToDouble(instrNode))
533     {
534       return opCode = FSMULD;
535     }
536   // else fall through and use the regular multiply instructions
537   
538   const Type* resultType = instrNode->getInstruction()->getType();
539   
540   if (resultType->isIntegral())
541     {
542       opCode = MULX;
543     }
544   else
545     switch(resultType->getPrimitiveID())
546       {
547       case Type::FloatTyID:  opCode = FMULS; break;
548       case Type::DoubleTyID: opCode = FMULD; break;
549       default: assert(0 && "Invalid type for MUL instruction"); break; 
550       }
551   
552   return opCode;
553 }
554
555
556 static inline MachineInstr*
557 CreateIntNegInstruction(TargetMachine& target,
558                         Value* vreg)
559 {
560   MachineInstr* minstr = new MachineInstr(SUB);
561   minstr->SetMachineOperand(0, target.getRegInfo().getZeroRegNum());
562   minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, vreg);
563   minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, vreg);
564   return minstr;
565 }
566
567
568 static inline MachineInstr* 
569 CreateMulConstInstruction(TargetMachine &target,
570                           const InstructionNode* instrNode,
571                           MachineInstr*& getMinstr2)
572 {
573   MachineInstr* minstr = NULL;
574   getMinstr2 = NULL;
575   bool needNeg = false;
576
577   Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
578   assert(constOp->isConstant());
579   
580   // Cases worth optimizing are:
581   // (1) Multiply by 0 or 1 for any type: replace with copy (ADD or FMOV)
582   // (2) Multiply by 2^x for integer types: replace with Shift
583   // 
584   const Type* resultType = instrNode->getInstruction()->getType();
585   
586   if (resultType->isIntegral() || resultType->isPointerType())
587     {
588       unsigned pow;
589       bool isValidConst;
590       int64_t C = GetConstantValueAsSignedInt(constOp, isValidConst);
591       if (isValidConst)
592         {
593           bool needNeg = false;
594           if (C < 0)
595             {
596               needNeg = true;
597               C = -C;
598             }
599           
600           if (C == 0 || C == 1)
601             {
602               minstr = new MachineInstr(ADD);
603               
604               if (C == 0)
605                 minstr->SetMachineOperand(0,
606                                           target.getRegInfo().getZeroRegNum());
607               else
608                 minstr->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
609                                           instrNode->leftChild()->getValue());
610               minstr->SetMachineOperand(1,target.getRegInfo().getZeroRegNum());
611             }
612           else if (IsPowerOf2(C, pow))
613             {
614               minstr = new MachineInstr((resultType == Type::LongTy)
615                                         ? SLLX : SLL);
616               minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
617                                            instrNode->leftChild()->getValue());
618               minstr->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
619                                            pow);
620             }
621           
622           if (minstr && needNeg)
623             { // insert <reg = SUB 0, reg> after the instr to flip the sign
624               getMinstr2 = CreateIntNegInstruction(target,
625                                                    instrNode->getValue());
626             }
627         }
628     }
629   else
630     {
631       if (resultType == Type::FloatTy ||
632           resultType == Type::DoubleTy)
633         {
634           bool isValidConst;
635           double dval = ((ConstPoolFP*) constOp)->getValue();
636           
637           if (isValidConst)
638             {
639               if (dval == 0)
640                 {
641                   minstr = new MachineInstr((resultType == Type::FloatTy)
642                                             ? FITOS : FITOD);
643                   minstr->SetMachineOperand(0,
644                                         target.getRegInfo().getZeroRegNum());
645                 }
646               else if (fabs(dval) == 1)
647                 {
648                   bool needNeg = (dval < 0);
649                   
650                   MachineOpCode opCode = needNeg
651                     ? (resultType == Type::FloatTy? FNEGS : FNEGD)
652                     : (resultType == Type::FloatTy? FMOVS : FMOVD);
653                   
654                   minstr = new MachineInstr(opCode);
655                   minstr->SetMachineOperand(0,
656                                            MachineOperand::MO_VirtualRegister,
657                                            instrNode->leftChild()->getValue());
658                 } 
659             }
660         }
661     }
662   
663   if (minstr != NULL)
664     minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
665                               instrNode->getValue());   
666   
667   return minstr;
668 }
669
670
671 static inline MachineOpCode 
672 ChooseDivInstruction(TargetMachine &target,
673                      const InstructionNode* instrNode)
674 {
675   MachineOpCode opCode = INVALID_OPCODE;
676   
677   const Type* resultType = instrNode->getInstruction()->getType();
678   
679   if (resultType->isIntegral())
680     opCode = resultType->isSigned()? SDIVX : UDIVX;
681   else
682     switch(resultType->getPrimitiveID())
683       {
684       case Type::FloatTyID:  opCode = FDIVS; break;
685       case Type::DoubleTyID: opCode = FDIVD; break;
686       default: assert(0 && "Invalid type for DIV instruction"); break; 
687       }
688   
689   return opCode;
690 }
691
692
693 static inline MachineInstr* 
694 CreateDivConstInstruction(TargetMachine &target,
695                           const InstructionNode* instrNode,
696                           MachineInstr*& getMinstr2)
697 {
698   MachineInstr* minstr = NULL;
699   getMinstr2 = NULL;
700   
701   Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
702   assert(constOp->isConstant());
703   
704   // Cases worth optimizing are:
705   // (1) Divide by 1 for any type: replace with copy (ADD or FMOV)
706   // (2) Divide by 2^x for integer types: replace with SR[L or A]{X}
707   // 
708   const Type* resultType = instrNode->getInstruction()->getType();
709   
710   if (resultType->isIntegral())
711     {
712       unsigned pow;
713       bool isValidConst;
714       int64_t C = GetConstantValueAsSignedInt(constOp, isValidConst);
715       if (isValidConst)
716         {
717           bool needNeg = false;
718           if (C < 0)
719             {
720               needNeg = true;
721               C = -C;
722             }
723           
724           if (C == 1)
725             {
726               minstr = new MachineInstr(ADD);
727               minstr->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
728                                           instrNode->leftChild()->getValue());
729               minstr->SetMachineOperand(1,target.getRegInfo().getZeroRegNum());
730             }
731           else if (IsPowerOf2(C, pow))
732             {
733               MachineOpCode opCode= ((resultType->isSigned())
734                                      ? (resultType==Type::LongTy)? SRAX : SRA
735                                      : (resultType==Type::LongTy)? SRLX : SRL);
736               minstr = new MachineInstr(opCode);
737               minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
738                                            instrNode->leftChild()->getValue());
739               minstr->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
740                                            pow);
741             }
742           
743           if (minstr && needNeg)
744             { // insert <reg = SUB 0, reg> after the instr to flip the sign
745               getMinstr2 = CreateIntNegInstruction(target,
746                                                    instrNode->getValue());
747             }
748         }
749     }
750   else
751     {
752       if (resultType == Type::FloatTy ||
753           resultType == Type::DoubleTy)
754         {
755           bool isValidConst;
756           double dval = ((ConstPoolFP*) constOp)->getValue();
757           
758           if (isValidConst && fabs(dval) == 1)
759             {
760               bool needNeg = (dval < 0);
761               
762               MachineOpCode opCode = needNeg
763                 ? (resultType == Type::FloatTy? FNEGS : FNEGD)
764                 : (resultType == Type::FloatTy? FMOVS : FMOVD);
765               
766               minstr = new MachineInstr(opCode);
767               minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
768                                            instrNode->leftChild()->getValue());
769             } 
770         }
771     }
772   
773   if (minstr != NULL)
774     minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
775                               instrNode->getValue());   
776   
777   return minstr;
778 }
779
780
781 static inline MachineOpCode
782 ChooseLoadInstruction(const Type *DestTy)
783 {
784   switch (DestTy->getPrimitiveID()) {
785   case Type::BoolTyID:
786   case Type::UByteTyID:   return LDUB;
787   case Type::SByteTyID:   return LDSB;
788   case Type::UShortTyID:  return LDUH;
789   case Type::ShortTyID:   return LDSH;
790   case Type::UIntTyID:    return LDUW;
791   case Type::IntTyID:     return LDSW;
792   case Type::PointerTyID:
793   case Type::ULongTyID:
794   case Type::LongTyID:    return LDX;
795   case Type::FloatTyID:   return LD;
796   case Type::DoubleTyID:  return LDD;
797   default: assert(0 && "Invalid type for Load instruction");
798   }
799   
800   return 0;
801 }
802
803
804 static inline MachineOpCode
805 ChooseStoreInstruction(const Type *DestTy)
806 {
807   switch (DestTy->getPrimitiveID()) {
808   case Type::BoolTyID:
809   case Type::UByteTyID:
810   case Type::SByteTyID:   return STB;
811   case Type::UShortTyID:
812   case Type::ShortTyID:   return STH;
813   case Type::UIntTyID:
814   case Type::IntTyID:     return STW;
815   case Type::PointerTyID:
816   case Type::ULongTyID:
817   case Type::LongTyID:    return STX;
818   case Type::FloatTyID:   return ST;
819   case Type::DoubleTyID:  return STD;
820   default: assert(0 && "Invalid type for Store instruction");
821   }
822   
823   return 0;
824 }
825
826
827 //------------------------------------------------------------------------ 
828 // Function SetOperandsForMemInstr
829 //
830 // Choose addressing mode for the given load or store instruction.
831 // Use [reg+reg] if it is an indexed reference, and the index offset is
832 //               not a constant or if it cannot fit in the offset field.
833 // Use [reg+offset] in all other cases.
834 // 
835 // This assumes that all array refs are "lowered" to one of these forms:
836 //      %x = load (subarray*) ptr, constant     ; single constant offset
837 //      %x = load (subarray*) ptr, offsetVal    ; single non-constant offset
838 // Generally, this should happen via strength reduction + LICM.
839 // Also, strength reduction should take care of using the same register for
840 // the loop index variable and an array index, when that is profitable.
841 //------------------------------------------------------------------------ 
842
843 static void
844 SetOperandsForMemInstr(MachineInstr* minstr,
845                        const InstructionNode* vmInstrNode,
846                        const TargetMachine& target)
847 {
848   MemAccessInst* memInst = (MemAccessInst*) vmInstrNode->getInstruction();
849   
850   // Variables to hold the index vector, ptr value, and offset value.
851   // The major work here is to extract these for all 3 instruction types
852   // and then call the common function SetMemOperands_Internal().
853   // 
854   const vector<ConstPoolVal*>* idxVec = & memInst->getIndexVec();
855   vector<ConstPoolVal*>* newIdxVec = NULL;
856   Value* ptrVal;
857   Value* arrayOffsetVal = NULL;
858   
859   // Test if a GetElemPtr instruction is being folded into this mem instrn.
860   // If so, it will be in the left child for Load and GetElemPtr,
861   // and in the right child for Store instructions.
862   // 
863   InstrTreeNode* ptrChild = (vmInstrNode->getOpLabel() == Instruction::Store
864                              ? vmInstrNode->rightChild()
865                              : vmInstrNode->leftChild()); 
866   
867   if (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
868       ptrChild->getOpLabel() == GetElemPtrIdx)
869     {
870       // There is a GetElemPtr instruction and there may be a chain of
871       // more than one.  Use the pointer value of the last one in the chain.
872       // Fold the index vectors from the entire chain and from the mem
873       // instruction into one single index vector.
874       // Finally, we never fold for an array instruction so make that NULL.
875       
876       newIdxVec = new vector<ConstPoolVal*>;
877       ptrVal = FoldGetElemChain((InstructionNode*) ptrChild, *newIdxVec);
878       
879       newIdxVec->insert(newIdxVec->end(), idxVec->begin(), idxVec->end());
880       idxVec = newIdxVec;
881       
882       assert(! ((PointerType*)ptrVal->getType())->getValueType()->isArrayType()
883              && "GetElemPtr cannot be folded into array refs in selection");
884     }
885   else
886     {
887       // There is no GetElemPtr instruction.
888       // Use the pointer value and the index vector from the Mem instruction.
889       // If it is an array reference, get the array offset value.
890       // 
891       ptrVal = memInst->getPtrOperand();
892
893       const Type* opType =
894         ((const PointerType*) ptrVal->getType())->getValueType();
895       if (opType->isArrayType())
896         {
897           assert((memInst->getNumOperands()
898                   == (unsigned) 1 + memInst->getFirstOffsetIdx())
899                  && "Array refs must be lowered before Instruction Selection");
900           
901           arrayOffsetVal = memInst->getOperand(memInst->getFirstOffsetIdx());
902         }
903     }
904   
905   SetMemOperands_Internal(minstr, vmInstrNode, ptrVal, arrayOffsetVal,
906                           *idxVec, target);
907   
908   if (newIdxVec != NULL)
909     delete newIdxVec;
910 }
911
912
913 static void
914 SetMemOperands_Internal(MachineInstr* minstr,
915                         const InstructionNode* vmInstrNode,
916                         Value* ptrVal,
917                         Value* arrayOffsetVal,
918                         const vector<ConstPoolVal*>& idxVec,
919                         const TargetMachine& target)
920 {
921   MemAccessInst* memInst = (MemAccessInst*) vmInstrNode->getInstruction();
922   
923   // Initialize so we default to storing the offset in a register.
924   int64_t smallConstOffset;
925   Value* valueForRegOffset = NULL;
926   MachineOperand::MachineOperandType offsetOpType =MachineOperand::MO_VirtualRegister;
927
928   // Check if there is an index vector and if so, if it translates to
929   // a small enough constant to fit in the immediate-offset field.
930   // 
931   if (idxVec.size() > 0)
932     {
933       bool isConstantOffset = false;
934       unsigned offset;
935       
936       const PointerType* ptrType = (PointerType*) ptrVal->getType();
937       
938       if (ptrType->getValueType()->isStructType())
939         {
940           // the offset is always constant for structs
941           isConstantOffset = true;
942           
943           // Compute the offset value using the index vector
944           offset = target.DataLayout.getIndexedOffset(ptrType, idxVec);
945         }
946       else
947         {
948           // It must be an array ref.  Check if the offset is a constant,
949           // and that the indexing has been lowered to a single offset.
950           // 
951           assert(ptrType->getValueType()->isArrayType());
952           assert(arrayOffsetVal != NULL
953                  && "Expect to be given Value* for array offsets");
954           
955           if (ConstPoolVal *CPV = arrayOffsetVal->castConstant())
956             {
957               isConstantOffset = true;  // always constant for structs
958               assert(arrayOffsetVal->getType()->isIntegral());
959               offset = (CPV->getType()->isSigned()
960                         ? ((ConstPoolSInt*)CPV)->getValue()
961                         : (int64_t) ((ConstPoolUInt*)CPV)->getValue());
962             }
963           else
964             {
965               valueForRegOffset = arrayOffsetVal;
966             }
967         }
968       
969       if (isConstantOffset)
970         {
971           // create a virtual register for the constant
972           valueForRegOffset = ConstPoolSInt::get(Type::IntTy, offset);
973         }
974     }
975   else
976     {
977       offsetOpType = MachineOperand::MO_SignExtendedImmed;
978       smallConstOffset = 0;
979     }
980   
981   // Operand 0 is value for STORE, ptr for LOAD or GET_ELEMENT_PTR
982   // It is the left child in the instruction tree in all cases.
983   Value* leftVal = vmInstrNode->leftChild()->getValue();
984   minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, leftVal);
985   
986   // Operand 1 is ptr for STORE, offset for LOAD or GET_ELEMENT_PTR
987   // Operand 2 is offset for STORE, result reg for LOAD or GET_ELEMENT_PTR
988   //
989   unsigned offsetOpNum = (memInst->getOpcode() == Instruction::Store)? 2 : 1;
990   if (offsetOpType == MachineOperand::MO_VirtualRegister)
991     {
992       assert(valueForRegOffset != NULL);
993       minstr->SetMachineOperand(offsetOpNum, offsetOpType, valueForRegOffset); 
994     }
995   else
996     minstr->SetMachineOperand(offsetOpNum, offsetOpType, smallConstOffset);
997   
998   if (memInst->getOpcode() == Instruction::Store)
999     minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, ptrVal);
1000   else
1001     minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
1002                                  vmInstrNode->getValue());
1003 }
1004
1005
1006 static inline MachineInstr*
1007 CreateIntSetInstruction(int64_t C, bool isSigned, Value* dest)
1008 {
1009   MachineInstr* minstr;
1010   if (isSigned)
1011     {
1012       minstr = new MachineInstr(SETSW);
1013       minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C);
1014     }
1015   else
1016     {
1017       minstr = new MachineInstr(SETUW);
1018       minstr->SetMachineOperand(0, MachineOperand::MO_UnextendedImmed, C);
1019     }
1020   
1021   minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, dest);
1022   
1023   return minstr;
1024 }
1025
1026
1027 // Create an instruction sequence to load a constant into a register.
1028 // This always creates either one or two instructions.
1029 // If two instructions are created, the second one is returned in getMinstr2
1030 // The implicit virtual register used to hold the constant is returned in
1031 // tmpReg.
1032 // 
1033 static MachineInstr*
1034 CreateLoadConstInstr(const TargetMachine &target,
1035                      Instruction* vmInstr,
1036                      Value* val,
1037                      Instruction* dest,
1038                      MachineInstr*& getMinstr2)
1039 {
1040   assert(val->isConstant());
1041   
1042   MachineInstr* minstr1 = NULL;
1043   
1044   getMinstr2 = NULL;
1045   
1046   // Use a "set" instruction for known constants that can go in an integer reg.
1047   // Use a "set" instruction followed by a int-to-float conversion for known
1048   // constants that must go in a floating point reg but have an integer value.
1049   // Use a "load" instruction for all other constants, in particular,
1050   // floating point constants.
1051   // 
1052   const Type* valType = val->getType();
1053   
1054   if (valType->isIntegral() || valType == Type::BoolTy)
1055     {
1056       bool isValidConstant;
1057       int64_t C = GetConstantValueAsSignedInt(val, isValidConstant);
1058       assert(isValidConstant && "Unrecognized constant");
1059       minstr1 = CreateIntSetInstruction(C, valType->isSigned(), dest);
1060     }
1061   else
1062     {
1063       
1064 #undef MOVE_INT_TO_FP_REG_AVAILABLE
1065 #ifdef MOVE_INT_TO_FP_REG_AVAILABLE
1066       //
1067       // This code was written to generate the following sequence:
1068       //        SET[SU]W <int-const> <int-reg>
1069       //        FITO[SD] <int-reg>   <fp-reg>
1070       // (it really should have moved the int-reg to an fp-reg and then FITOS).
1071       // But for now the only way to move a value from an int-reg to an fp-reg
1072       // is via memory.  Leave this code here but unused.
1073       // 
1074       assert(valType == Type::FloatTy || valType == Type::DoubleTy);
1075       double dval = ((ConstPoolFP*) val)->getValue();
1076       if (dval == (int64_t) dval)
1077         {
1078           // The constant actually has an integer value, so use a
1079           // [set; int-to-float] sequence instead of a load instruction.
1080           // 
1081           TmpInstruction* tmpReg2 = NULL;
1082           if (dval != 0.0)
1083             { // First, create an integer constant of the same value as dval
1084               ConstPoolSInt* ival = ConstPoolSInt::get(Type::IntTy,
1085                                                        (int64_t) dval);
1086               // Create another TmpInstruction for the hidden integer register
1087               tmpReg2 = new TmpInstruction(Instruction::UserOp1, ival, NULL);
1088               vmInstr->getMachineInstrVec().addTempValue(tmpReg2);
1089               
1090               // Create the `SET' instruction
1091               minstr1 = CreateIntSetInstruction((int64_t)dval, true, tmpReg2);
1092               tmpReg2->addMachineInstruction(minstr1);
1093             }
1094           
1095           // In which variable do we put the second instruction?
1096           MachineInstr*& instr2 = (minstr1)? getMinstr2 : minstr1;
1097           
1098           // Create the int-to-float instruction
1099           instr2 = new MachineInstr(valType == Type::FloatTy? FITOS : FITOD);
1100           
1101           if (dval == 0.0)
1102             instr2->SetMachineOperand(0, target.getRegInfo().getZeroRegNum());
1103           else
1104             instr2->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
1105                                          tmpReg2);
1106           
1107           instr2->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
1108                                          dest);
1109         }
1110       else
1111 #endif MOVE_INT_TO_FP_REG_AVAILABLE
1112         
1113         {
1114           // Make an instruction sequence to load the constant, viz:
1115           //            SETSW <addr-of-constant>, tmpReg2
1116           //            LOAD  /*addr*/ tmpReg2, /*offset*/ 0, dest
1117           // set the offset field to 0.
1118           // 
1119           int64_t zeroOffset = 0; // to avoid ambiguity with (Value*) 0
1120
1121           // Create another TmpInstruction for the hidden integer register
1122           TmpInstruction* tmpReg2 =
1123             new TmpInstruction(Instruction::UserOp1, val, NULL);
1124           vmInstr->getMachineInstrVec().addTempValue(tmpReg2);
1125           
1126           minstr1 = new MachineInstr(SETUW);
1127           minstr1->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp,val);
1128           minstr1->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
1129                                         tmpReg2);
1130           tmpReg2->addMachineInstruction(minstr1);
1131           
1132           getMinstr2 = new MachineInstr(ChooseLoadInstruction(val->getType()));
1133           getMinstr2->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
1134                                           tmpReg2);
1135           getMinstr2->SetMachineOperand(1,MachineOperand::MO_SignExtendedImmed,
1136                                           zeroOffset);
1137           getMinstr2->SetMachineOperand(2,MachineOperand::MO_VirtualRegister,
1138                                           dest);
1139         }
1140     }
1141   
1142   assert(minstr1);
1143   return minstr1;
1144 }
1145
1146 // Special handling for constant operands:
1147 // -- if the constant is 0, use the hardwired 0 register, if any;
1148 // -- if the constant is of float or double type but has an integer value,
1149 //    use int-to-float conversion instruction instead of generating a load;
1150 // -- if the constant fits in the IMMEDIATE field, use that field;
1151 // -- else insert instructions to put the constant into a register, either
1152 //    directly or by loading explicitly from the constant pool.
1153 // 
1154 static unsigned
1155 FixConstantOperands(const InstructionNode* vmInstrNode,
1156                     MachineInstr** mvec,
1157                     unsigned numInstr,
1158                     TargetMachine& target)
1159 {
1160   static MachineInstr* loadConstVec[MAX_INSTR_PER_VMINSTR];
1161
1162   unsigned numNew = 0;
1163   Instruction* vmInstr = vmInstrNode->getInstruction();
1164   
1165   for (unsigned i=0; i < numInstr; i++)
1166     {
1167       MachineInstr* minstr = mvec[i];
1168       const MachineInstrDescriptor& instrDesc =
1169         target.getInstrInfo().getDescriptor(minstr->getOpCode());
1170       
1171       for (unsigned op=0; op < minstr->getNumOperands(); op++)
1172         {
1173           const MachineOperand& mop = minstr->getOperand(op);
1174           
1175           // skip the result position (for efficiency below) and any other
1176           // positions already marked as not a virtual register
1177           if (instrDesc.resultPos == (int) op || 
1178               mop.getOperandType() != MachineOperand::MO_VirtualRegister ||
1179               mop.getVRegValue() == NULL)
1180             {
1181               continue;
1182             }
1183           
1184           Value* opValue = mop.getVRegValue();
1185           
1186           if (opValue->isConstant())
1187             {
1188               unsigned int machineRegNum;
1189               int64_t immedValue;
1190               MachineOperand::MachineOperandType opType =
1191                 ChooseRegOrImmed(opValue, minstr->getOpCode(), target,
1192                                  /*canUseImmed*/ (op == 1),
1193                                  machineRegNum, immedValue);
1194               
1195               if (opType == MachineOperand::MO_MachineRegister)
1196                 minstr->SetMachineOperand(op, machineRegNum);
1197               else if (opType == MachineOperand::MO_VirtualRegister)
1198                 {
1199                   // value is constant and must be loaded into a register.
1200                   // First, create a tmp virtual register (TmpInstruction)
1201                   // to hold the constant.
1202                   // This will replace the constant operand in `minstr'.
1203                   TmpInstruction* tmpReg =
1204                     new TmpInstruction(Instruction::UserOp1, opValue, NULL);
1205                   vmInstr->getMachineInstrVec().addTempValue(tmpReg);
1206                   minstr->SetMachineOperand(op, opType, tmpReg);
1207                   
1208                   MachineInstr *minstr1, *minstr2;
1209                   minstr1 = CreateLoadConstInstr(target, vmInstr,
1210                                                  opValue, tmpReg, minstr2);
1211                   tmpReg->addMachineInstruction(minstr1);
1212                   
1213                   loadConstVec[numNew++] = minstr1;
1214                   if (minstr2 != NULL)
1215                     loadConstVec[numNew++] = minstr2;
1216                 }
1217               else
1218                 minstr->SetMachineOperand(op, opType, immedValue);
1219             }
1220         }
1221     }
1222   
1223   if (numNew > 0)
1224     {
1225       // Insert the new instructions *before* the old ones by moving
1226       // the old ones over `numNew' positions (last-to-first, of course!).
1227       // We do check *after* returning that we did not exceed the vector mvec.
1228       for (int i=numInstr-1; i >= 0; i--)
1229         mvec[i+numNew] = mvec[i];
1230       
1231       for (unsigned i=0; i < numNew; i++)
1232         mvec[i] = loadConstVec[i];
1233     }
1234   
1235   return (numInstr + numNew);
1236 }
1237
1238
1239 // 
1240 // Substitute operand `operandNum' of the instruction in node `treeNode'
1241 // in place the use(s) of that instruction in node `parent'.
1242 // 
1243 static void
1244 ForwardOperand(InstructionNode* treeNode,
1245                InstrTreeNode*   parent,
1246                int operandNum)
1247 {
1248   assert(treeNode && parent && "Invalid invocation of ForwardOperand");
1249   
1250   Instruction* unusedOp = treeNode->getInstruction();
1251   Value* fwdOp = unusedOp->getOperand(operandNum);
1252
1253   // The parent itself may be a list node, so find the real parent instruction
1254   while (parent->getNodeType() != InstrTreeNode::NTInstructionNode)
1255     {
1256       parent = parent->parent();
1257       assert(parent && "ERROR: Non-instruction node has no parent in tree.");
1258     }
1259   InstructionNode* parentInstrNode = (InstructionNode*) parent;
1260   
1261   Instruction* userInstr = parentInstrNode->getInstruction();
1262   MachineCodeForVMInstr& mvec = userInstr->getMachineInstrVec();
1263   for (unsigned i=0, N=mvec.size(); i < N; i++)
1264     {
1265       MachineInstr* minstr = mvec[i];
1266       for (unsigned i=0, numOps=minstr->getNumOperands(); i < numOps; i++)
1267         {
1268           const MachineOperand& mop = minstr->getOperand(i);
1269           if (mop.getOperandType() == MachineOperand::MO_VirtualRegister &&
1270               mop.getVRegValue() == unusedOp)
1271             {
1272               minstr->SetMachineOperand(i, MachineOperand::MO_VirtualRegister,
1273                                            fwdOp);
1274             }
1275         }
1276     }
1277 }
1278
1279
1280 MachineInstr*
1281 CreateCopyInstructionsByType(const TargetMachine& target,
1282                              Value* src,
1283                              Instruction* dest,
1284                              MachineInstr*& getMinstr2)
1285 {
1286   getMinstr2 = NULL;                    // initialize second return value
1287   
1288   MachineInstr* minstr1 = NULL;
1289   
1290   const Type* resultType = dest->getType();
1291   
1292   MachineOpCode opCode = ChooseAddInstructionByType(resultType);
1293   if (opCode == INVALID_OPCODE)
1294     {
1295       assert(0 && "Unsupported result type in CreateCopyInstructionsByType()");
1296       return NULL;
1297     }
1298   
1299   // if `src' is a constant that doesn't fit in the immed field, generate
1300   // a load instruction instead of an add
1301   if (src->isConstant())
1302     {
1303       unsigned int machineRegNum;
1304       int64_t immedValue;
1305       MachineOperand::MachineOperandType opType =
1306         ChooseRegOrImmed(src, opCode, target, /*canUseImmed*/ true,
1307                          machineRegNum, immedValue);
1308       
1309       if (opType == MachineOperand::MO_VirtualRegister)
1310         { // value is constant and cannot fit in immed field for the ADD
1311           minstr1 = CreateLoadConstInstr(target, dest, src, dest, getMinstr2);
1312         }
1313     }
1314   
1315   if (minstr1 == NULL)
1316     { // Create the appropriate add instruction.
1317       // Make `src' the second operand, in case it is a constant
1318       // Use (unsigned long) 0 for a NULL pointer value.
1319       // 
1320       const Type* nullValueType =
1321         (resultType->getPrimitiveID() == Type::PointerTyID)? Type::ULongTy
1322                                                            : resultType;
1323       minstr1 = new MachineInstr(opCode);
1324       minstr1->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
1325                                  ConstPoolVal::getNullConstant(nullValueType));
1326       minstr1->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, src);
1327       minstr1->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, dest);
1328     }
1329   
1330   return minstr1;
1331 }
1332
1333
1334 // This function is currently unused and incomplete but will be 
1335 // used if we have a linear layout of basic blocks in LLVM code.
1336 // It decides which branch should fall-through, and whether an
1337 // extra unconditional branch is needed (when neither falls through).
1338 // 
1339 void
1340 ChooseBranchPattern(Instruction* vmInstr, BranchPattern& brPattern)
1341 {
1342   BranchInst* brInstr = (BranchInst*) vmInstr;
1343   
1344   brPattern.flipCondition = false;
1345   brPattern.targetBB      = brInstr->getSuccessor(0);
1346   brPattern.extraBranch   = NULL;
1347   
1348   assert(brInstr->getNumSuccessors() > 1 &&
1349          "Unnecessary analysis for unconditional branch");
1350   
1351   assert(0 && "Fold branches in peephole optimization");
1352 }
1353
1354
1355 //******************* Externally Visible Functions *************************/
1356
1357
1358 //------------------------------------------------------------------------ 
1359 // External Function: GetInstructionsByRule
1360 //
1361 // Purpose:
1362 //   Choose machine instructions for the SPARC according to the
1363 //   patterns chosen by the BURG-generated parser.
1364 //------------------------------------------------------------------------ 
1365
1366 unsigned
1367 GetInstructionsByRule(InstructionNode* subtreeRoot,
1368                       int ruleForNode,
1369                       short* nts,
1370                       TargetMachine &target,
1371                       MachineInstr** mvec)
1372 {
1373   int numInstr = 1;                     // initialize for common case
1374   bool checkCast = false;               // initialize here to use fall-through
1375   Value *leftVal, *rightVal;
1376   const Type* opType;
1377   int nextRule;
1378   int forwardOperandNum = -1;
1379   int64_t s0 = 0;                       // variables holding zero to avoid
1380   uint64_t u0 = 0;                      // overloading ambiguities below
1381   
1382   mvec[0] = mvec[1] = mvec[2] = mvec[3] = NULL; // just for safety
1383   
1384   // 
1385   // Let's check for chain rules outside the switch so that we don't have
1386   // to duplicate the list of chain rule production numbers here again
1387   // 
1388   if (ThisIsAChainRule(ruleForNode))
1389     {
1390       // Chain rules have a single nonterminal on the RHS.
1391       // Get the rule that matches the RHS non-terminal and use that instead.
1392       // 
1393       assert(nts[0] && ! nts[1]
1394              && "A chain rule should have only one RHS non-terminal!");
1395       nextRule = burm_rule(subtreeRoot->state, nts[0]);
1396       nts = burm_nts[nextRule];
1397       numInstr = GetInstructionsByRule(subtreeRoot, nextRule, nts,target,mvec);
1398     }
1399   else
1400     {
1401       switch(ruleForNode) {
1402       case 1:   // stmt:   Ret
1403       case 2:   // stmt:   RetValue(reg)
1404                 // NOTE: Prepass of register allocation is responsible
1405                 //       for moving return value to appropriate register.
1406                 // Mark the return-address register as a hidden virtual reg.
1407                 // Mark the return value   register as an implicit use.
1408         {               
1409         ReturnInst* returnInstr = (ReturnInst*) subtreeRoot->getInstruction();
1410         assert(returnInstr->getOpcode() == Instruction::Ret);
1411         
1412         Instruction* returnReg = new TmpInstruction(Instruction::UserOp1,
1413                                                     returnInstr, NULL);
1414         returnInstr->getMachineInstrVec().addTempValue(returnReg);
1415
1416         if (returnInstr->getReturnValue() != NULL)
1417           returnInstr->getMachineInstrVec().addImplicitUse(
1418                                              returnInstr->getReturnValue());
1419         
1420         mvec[0] = new MachineInstr(RETURN);
1421         mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
1422                                       returnReg);
1423         mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,s0);
1424         
1425         returnReg->addMachineInstruction(mvec[0]);
1426         
1427         mvec[numInstr++] = new MachineInstr(NOP); // delay slot
1428         break;
1429         }  
1430         
1431       case 3:   // stmt:   Store(reg,reg)
1432       case 4:   // stmt:   Store(reg,ptrreg)
1433         mvec[0] = new MachineInstr(
1434                        ChooseStoreInstruction(
1435                             subtreeRoot->leftChild()->getValue()->getType()));
1436         SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
1437         break;
1438
1439       case 5:   // stmt:   BrUncond
1440         mvec[0] = new MachineInstr(BA);
1441         mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
1442                                       (Value*)NULL);
1443         mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
1444               ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
1445         
1446         // delay slot
1447         mvec[numInstr++] = new MachineInstr(NOP);
1448         break;
1449
1450       case 206: // stmt:   BrCond(setCCconst)
1451         // setCCconst => boolean was computed with `%b = setCC type reg1 const'
1452         // If the constant is ZERO, we can use the branch-on-integer-register
1453         // instructions and avoid the SUBcc instruction entirely.
1454         // Otherwise this is just the same as case 5, so just fall through.
1455         {
1456         InstrTreeNode* constNode = subtreeRoot->leftChild()->rightChild();
1457         assert(constNode &&
1458                constNode->getNodeType() ==InstrTreeNode::NTConstNode);
1459         ConstPoolVal* constVal = (ConstPoolVal*) constNode->getValue();
1460         bool isValidConst;
1461
1462         if ((constVal->getType()->isIntegral()
1463              || constVal->getType()->isPointerType())
1464             && GetConstantValueAsSignedInt(constVal, isValidConst) == 0
1465             && isValidConst)
1466           {
1467             // That constant is a zero after all...
1468             // Use the left child of setCC as the first argument!
1469             mvec[0] = new MachineInstr(ChooseBprInstruction(subtreeRoot));
1470             mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
1471                           subtreeRoot->leftChild()->leftChild()->getValue());
1472             mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
1473               ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
1474
1475             // delay slot
1476             mvec[numInstr++] = new MachineInstr(NOP);
1477
1478             // false branch
1479             int n = numInstr++; 
1480             mvec[n] = new MachineInstr(BA);
1481             mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
1482                                           (Value*) NULL);
1483             mvec[n]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
1484                ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(1));
1485             
1486             // delay slot
1487             mvec[numInstr++] = new MachineInstr(NOP);
1488             
1489             break;
1490           }
1491         // ELSE FALL THROUGH
1492         }
1493
1494       case 6:   // stmt:   BrCond(bool)
1495         // bool => boolean was computed with some boolean operator
1496         // (SetCC, Not, ...).  We need to check whether the type was a FP,
1497         // signed int or unsigned int, and check the branching condition in
1498         // order to choose the branch to use.
1499         // 
1500         {
1501         bool isFPBranch;
1502         mvec[0] = new MachineInstr(ChooseBccInstruction(subtreeRoot,
1503                                                         isFPBranch));
1504         mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
1505                                       subtreeRoot->leftChild()->getValue());
1506         mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
1507               ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
1508
1509         // delay slot
1510         mvec[numInstr++] = new MachineInstr(NOP);
1511
1512         // false branch
1513         int n = numInstr++;
1514         mvec[n] = new MachineInstr(BA);
1515         mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
1516                                       (Value*) NULL);
1517         mvec[n]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
1518               ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(1));
1519         
1520         // delay slot
1521         mvec[numInstr++] = new MachineInstr(NOP);
1522         break;
1523         }
1524         
1525       case 208: // stmt:   BrCond(boolconst)
1526         {
1527         // boolconst => boolean is a constant; use BA to first or second label
1528         ConstPoolVal* constVal = 
1529           cast<ConstPoolVal>(subtreeRoot->leftChild()->getValue());
1530         unsigned dest = ((ConstPoolBool*) constVal)->getValue()? 0 : 1;
1531         
1532         mvec[0] = new MachineInstr(BA);
1533         mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
1534                                       (Value*) NULL);
1535         mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
1536           ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(dest));
1537         
1538         // delay slot
1539         mvec[numInstr++] = new MachineInstr(NOP);
1540         break;
1541         }
1542         
1543       case   8: // stmt:   BrCond(boolreg)
1544         // boolreg   => boolean is stored in an existing register.
1545         // Just use the branch-on-integer-register instruction!
1546         // 
1547         {
1548         mvec[0] = new MachineInstr(BRNZ);
1549         mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
1550                                       subtreeRoot->leftChild()->getValue());
1551         mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
1552               ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
1553
1554         // delay slot
1555         mvec[numInstr++] = new MachineInstr(NOP); // delay slot
1556
1557         // false branch
1558         int n = numInstr++;
1559         mvec[n] = new MachineInstr(BA);
1560         mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
1561                                       (Value*) NULL);
1562         mvec[n]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
1563               ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(1));
1564         
1565         // delay slot
1566         mvec[numInstr++] = new MachineInstr(NOP);
1567         break;
1568         }  
1569       
1570       case 9:   // stmt:   Switch(reg)
1571         assert(0 && "*** SWITCH instruction is not implemented yet.");
1572         numInstr = 0;
1573         break;
1574
1575       case 10:  // reg:   VRegList(reg, reg)
1576         assert(0 && "VRegList should never be the topmost non-chain rule");
1577         break;
1578
1579       case 21:  // reg:   Not(reg):     Implemented as reg = reg XOR-NOT 0
1580         mvec[0] = new MachineInstr(XNOR);
1581         mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
1582                                       subtreeRoot->leftChild()->getValue());
1583         mvec[0]->SetMachineOperand(1, target.getRegInfo().getZeroRegNum());
1584         mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
1585                                      subtreeRoot->getValue());
1586         break;
1587
1588       case 322: // reg:   ToBoolTy(bool):
1589       case 22:  // reg:   ToBoolTy(reg):
1590         opType = subtreeRoot->leftChild()->getValue()->getType();
1591         assert(opType->isIntegral() || opType == Type::BoolTy);
1592         numInstr = 0;
1593         forwardOperandNum = 0;
1594         break;
1595
1596       case 23:  // reg:   ToUByteTy(reg)
1597       case 25:  // reg:   ToUShortTy(reg)
1598       case 27:  // reg:   ToUIntTy(reg)
1599       case 29:  // reg:   ToULongTy(reg)
1600         opType = subtreeRoot->leftChild()->getValue()->getType();
1601         assert(opType->isIntegral() ||
1602                opType->isPointerType() ||
1603                opType == Type::BoolTy && "Cast is illegal for other types");
1604         numInstr = 0;
1605         forwardOperandNum = 0;
1606         break;
1607         
1608       case 24:  // reg:   ToSByteTy(reg)
1609       case 26:  // reg:   ToShortTy(reg)
1610       case 28:  // reg:   ToIntTy(reg)
1611       case 30:  // reg:   ToLongTy(reg)
1612         opType = subtreeRoot->leftChild()->getValue()->getType();
1613         if (opType->isIntegral() || opType == Type::BoolTy)
1614           {
1615             numInstr = 0;
1616             forwardOperandNum = 0;
1617           }
1618         else
1619           {
1620             mvec[0] = new MachineInstr(ChooseConvertToIntInstr(subtreeRoot,
1621                                                               opType));
1622             Set2OperandsFromInstr(mvec[0], subtreeRoot, target);
1623           }
1624         break;
1625         
1626       case  31: // reg:   ToFloatTy(reg):
1627       case  32: // reg:   ToDoubleTy(reg):
1628       case 232: // reg:   ToDoubleTy(Constant):
1629         
1630         // If this instruction has a parent (a user) in the tree 
1631         // and the user is translated as an FsMULd instruction,
1632         // then the cast is unnecessary.  So check that first.
1633         // In the future, we'll want to do the same for the FdMULq instruction,
1634         // so do the check here instead of only for ToFloatTy(reg).
1635         // 
1636         if (subtreeRoot->parent() != NULL &&
1637             ((InstructionNode*) subtreeRoot->parent())->getInstruction()->getMachineInstrVec()[0]->getOpCode() == FSMULD)
1638           {
1639             numInstr = 0;
1640             forwardOperandNum = 0;
1641           }
1642         else
1643           {
1644             opType = subtreeRoot->leftChild()->getValue()->getType();
1645             MachineOpCode opCode=ChooseConvertToFloatInstr(subtreeRoot,opType);
1646             if (opCode == INVALID_OPCODE)       // no conversion needed
1647               {
1648                 numInstr = 0;
1649                 forwardOperandNum = 0;
1650               }
1651             else
1652               {
1653                 mvec[0] = new MachineInstr(opCode);
1654                 Set2OperandsFromInstr(mvec[0], subtreeRoot, target);
1655               }
1656           }
1657         break;
1658
1659       case 19:  // reg:   ToArrayTy(reg):
1660       case 20:  // reg:   ToPointerTy(reg):
1661         numInstr = 0;
1662         forwardOperandNum = 0;
1663         break;
1664
1665       case 233: // reg:   Add(reg, Constant)
1666         mvec[0] = CreateAddConstInstruction(subtreeRoot);
1667         if (mvec[0] != NULL)
1668           break;
1669         // ELSE FALL THROUGH
1670
1671       case 33:  // reg:   Add(reg, reg)
1672         mvec[0] = new MachineInstr(ChooseAddInstruction(subtreeRoot));
1673         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
1674         break;
1675
1676       case 234: // reg:   Sub(reg, Constant)
1677         mvec[0] = CreateSubConstInstruction(subtreeRoot);
1678         if (mvec[0] != NULL)
1679           break;
1680         // ELSE FALL THROUGH
1681
1682       case 34:  // reg:   Sub(reg, reg)
1683         mvec[0] = new MachineInstr(ChooseSubInstruction(subtreeRoot));
1684         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
1685         break;
1686
1687       case 135: // reg:   Mul(todouble, todouble)
1688         checkCast = true;
1689         // FALL THROUGH 
1690
1691       case 35:  // reg:   Mul(reg, reg)
1692         mvec[0] =new MachineInstr(ChooseMulInstruction(subtreeRoot,checkCast));
1693         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
1694         break;
1695
1696       case 335: // reg:   Mul(todouble, todoubleConst)
1697         checkCast = true;
1698         // FALL THROUGH 
1699
1700       case 235: // reg:   Mul(reg, Constant)
1701         mvec[0] = CreateMulConstInstruction(target, subtreeRoot, mvec[1]);
1702         if (mvec[0] == NULL)
1703           {
1704             mvec[0] = new MachineInstr(ChooseMulInstruction(subtreeRoot,
1705                                                             checkCast));
1706             Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
1707           }
1708         else
1709           if (mvec[1] != NULL)
1710             ++numInstr;
1711         break;
1712
1713       case 236: // reg:   Div(reg, Constant)
1714         mvec[0] = CreateDivConstInstruction(target, subtreeRoot, mvec[1]);
1715         if (mvec[0] != NULL)
1716           {
1717             if (mvec[1] != NULL)
1718               ++numInstr;
1719           }
1720         else
1721         // ELSE FALL THROUGH
1722
1723       case 36:  // reg:   Div(reg, reg)
1724         mvec[0] = new MachineInstr(ChooseDivInstruction(target, subtreeRoot));
1725         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
1726         break;
1727
1728       case  37: // reg:   Rem(reg, reg)
1729       case 237: // reg:   Rem(reg, Constant)
1730         assert(0 && "REM instruction unimplemented for the SPARC.");
1731         break;
1732
1733       case  38: // reg:   And(reg, reg)
1734       case 238: // reg:   And(reg, Constant)
1735         mvec[0] = new MachineInstr(AND);
1736         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
1737         break;
1738
1739       case 138: // reg:   And(reg, not)
1740         mvec[0] = new MachineInstr(ANDN);
1741         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
1742         break;
1743
1744       case  39: // reg:   Or(reg, reg)
1745       case 239: // reg:   Or(reg, Constant)
1746         mvec[0] = new MachineInstr(ORN);
1747         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
1748         break;
1749
1750       case 139: // reg:   Or(reg, not)
1751         mvec[0] = new MachineInstr(ORN);
1752         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
1753         break;
1754
1755       case  40: // reg:   Xor(reg, reg)
1756       case 240: // reg:   Xor(reg, Constant)
1757         mvec[0] = new MachineInstr(XOR);
1758         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
1759         break;
1760
1761       case 140: // reg:   Xor(reg, not)
1762         mvec[0] = new MachineInstr(XNOR);
1763         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
1764         break;
1765
1766       case 41:  // boolconst:   SetCC(reg, Constant)
1767         // Check if this is an integer comparison, and
1768         // there is a parent, and the parent decided to use
1769         // a branch-on-integer-register instead of branch-on-condition-code.
1770         // If so, the SUBcc instruction is not required.
1771         // (However, we must still check for constants to be loaded from
1772         // the constant pool so that such a load can be associated with
1773         // this instruction.)
1774         // 
1775         // Otherwise this is just the same as case 42, so just fall through.
1776         // 
1777         if (subtreeRoot->leftChild()->getValue()->getType()->isIntegral() &&
1778             subtreeRoot->parent() != NULL)
1779           {
1780             InstructionNode* parent = (InstructionNode*) subtreeRoot->parent();
1781             assert(parent->getNodeType() == InstrTreeNode::NTInstructionNode);
1782             const vector<MachineInstr*>&
1783               minstrVec = parent->getInstruction()->getMachineInstrVec();
1784             MachineOpCode parentOpCode;
1785             if (parent->getInstruction()->getOpcode() == Instruction::Br &&
1786                 (parentOpCode = minstrVec[0]->getOpCode()) >= BRZ &&
1787                 parentOpCode <= BRGEZ)
1788               {
1789                 numInstr = 0;           // don't forward the operand!
1790                 break;
1791               }
1792           }
1793         // ELSE FALL THROUGH
1794
1795       case 42:  // bool:   SetCC(reg, reg):
1796       {
1797         // If result of the SetCC is only used for a single branch, we can
1798         // discard the result.  Otherwise, the boolean value must go into
1799         // an integer register.
1800         // 
1801         bool keepBoolVal = (subtreeRoot->parent() == NULL ||
1802                             ((InstructionNode*) subtreeRoot->parent())
1803                             ->getInstruction()->getOpcode() !=Instruction::Br);
1804         bool subValIsBoolVal =
1805           subtreeRoot->getInstruction()->getOpcode() == Instruction::SetNE;
1806         bool keepSubVal = keepBoolVal && subValIsBoolVal;
1807         bool computeBoolVal = keepBoolVal && ! subValIsBoolVal;
1808         
1809         bool mustClearReg;
1810         int valueToMove;
1811         MachineOpCode movOpCode;
1812         
1813         if (subtreeRoot->leftChild()->getValue()->getType()->isIntegral() ||
1814             subtreeRoot->leftChild()->getValue()->getType()->isPointerType())
1815           {
1816             // Integer condition: dest. should be %g0 or an integer register.
1817             // If result must be saved but condition is not SetEQ then we need
1818             // a separate instruction to compute the bool result, so discard
1819             // result of SUBcc instruction anyway.
1820             // 
1821             mvec[0] = new MachineInstr(SUBcc);
1822             Set3OperandsFromInstr(mvec[0], subtreeRoot, target, ! keepSubVal);
1823             
1824             // mark the 4th operand as being a CC register, and a "result"
1825             mvec[0]->SetMachineOperand(3, MachineOperand::MO_CCRegister,
1826                                           subtreeRoot->getValue(),/*def*/true);
1827             
1828             if (computeBoolVal)
1829               { // recompute bool using the integer condition codes
1830                 movOpCode =
1831                   ChooseMovpccAfterSub(subtreeRoot,mustClearReg,valueToMove);
1832               }
1833           }
1834         else
1835           {
1836             // FP condition: dest of FCMP should be some FCCn register
1837             mvec[0] = new MachineInstr(ChooseFcmpInstruction(subtreeRoot));
1838             mvec[0]->SetMachineOperand(0,MachineOperand::MO_CCRegister,
1839                                          subtreeRoot->getValue());
1840             mvec[0]->SetMachineOperand(1,MachineOperand::MO_VirtualRegister,
1841                                          subtreeRoot->leftChild()->getValue());
1842             mvec[0]->SetMachineOperand(2,MachineOperand::MO_VirtualRegister,
1843                                         subtreeRoot->rightChild()->getValue());
1844             
1845             if (computeBoolVal)
1846               {// recompute bool using the FP condition codes
1847                 mustClearReg = true;
1848                 valueToMove = 1;
1849                 movOpCode = ChooseMovFpccInstruction(subtreeRoot);
1850               }
1851           }
1852         
1853         if (computeBoolVal)
1854           {
1855             if (mustClearReg)
1856               {// Unconditionally set register to 0
1857                int n = numInstr++;
1858                mvec[n] = new MachineInstr(SETHI);
1859                mvec[n]->SetMachineOperand(0,MachineOperand::MO_UnextendedImmed,
1860                                             s0);
1861                mvec[n]->SetMachineOperand(1,MachineOperand::MO_VirtualRegister,
1862                                             subtreeRoot->getValue());
1863               }
1864             
1865             // Now conditionally move `valueToMove' (0 or 1) into the register
1866             int n = numInstr++;
1867             mvec[n] = new MachineInstr(movOpCode);
1868             mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
1869                                           subtreeRoot->getValue());
1870             mvec[n]->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
1871                                           valueToMove);
1872             mvec[n]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
1873                                           subtreeRoot->getValue());
1874           }
1875         break;
1876       }    
1877
1878       case 43:  // boolreg: VReg
1879       case 44:  // boolreg: Constant
1880         numInstr = 0;
1881         break;
1882
1883       case 51:  // reg:   Load(reg)
1884       case 52:  // reg:   Load(ptrreg)
1885       case 53:  // reg:   LoadIdx(reg,reg)
1886       case 54:  // reg:   LoadIdx(ptrreg,reg)
1887         mvec[0] = new MachineInstr(ChooseLoadInstruction(
1888                                      subtreeRoot->getValue()->getType()));
1889         SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
1890         break;
1891
1892       case 55:  // reg:   GetElemPtr(reg)
1893       case 56:  // reg:   GetElemPtrIdx(reg,reg)
1894         if (subtreeRoot->parent() != NULL)
1895           {
1896             // Check if the parent was an array access.
1897             // If so, we still need to generate this instruction.
1898             MemAccessInst* memInst = (MemAccessInst*)
1899               subtreeRoot->getInstruction();
1900             const PointerType* ptrType =
1901               (const PointerType*) memInst->getPtrOperand()->getType();
1902             if (! ptrType->getValueType()->isArrayType())
1903               {// we don't need a separate instr
1904                 numInstr = 0;           // don't forward operand!
1905                 break;
1906               }
1907           }
1908         // else in all other cases we need to a separate ADD instruction
1909         mvec[0] = new MachineInstr(ADD);
1910         SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
1911         break;
1912
1913       case 57:  // reg:   Alloca: Implement as 2 instructions:
1914                     //  sub %sp, tmp -> %sp
1915         {               //      add %sp, 0   -> result
1916         Instruction* instr = subtreeRoot->getInstruction();
1917         const PointerType* instrType = (const PointerType*) instr->getType();
1918         assert(instrType->isPointerType());
1919         int tsize = (int)
1920           target.findOptimalStorageSize(instrType->getValueType());
1921         assert(tsize != 0 && "Just to check when this can happen");
1922         
1923         // Create a temporary Value to hold the constant type-size
1924         ConstPoolSInt* valueForTSize = ConstPoolSInt::get(Type::IntTy, tsize);
1925
1926         // Instruction 1: sub %sp, tsize -> %sp
1927         // tsize is always constant, but it may have to be put into a
1928         // register if it doesn't fit in the immediate field.
1929         // 
1930         mvec[0] = new MachineInstr(SUB);
1931         mvec[0]->SetMachineOperand(0, /*regNum %sp=o6=r[14]*/(unsigned int)14);
1932         mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
1933                                       valueForTSize);
1934         mvec[0]->SetMachineOperand(2, /*regNum %sp=o6=r[14]*/(unsigned int)14);
1935
1936         // Instruction 2: add %sp, 0 -> result
1937         numInstr++;
1938         mvec[1] = new MachineInstr(ADD);
1939         mvec[1]->SetMachineOperand(0, /*regNum %sp=o6=r[14]*/(unsigned int)14);
1940         mvec[1]->SetMachineOperand(1, target.getRegInfo().getZeroRegNum());
1941         mvec[1]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
1942                                       instr);
1943         break;
1944         }
1945         
1946       case 58:  // reg:   Alloca(reg): Implement as 3 instructions:
1947                 //      mul num, typeSz -> tmp
1948                 //      sub %sp, tmp    -> %sp
1949         {       //      add %sp, 0      -> result
1950         Instruction* instr = subtreeRoot->getInstruction();
1951         const PointerType* instrType = (const PointerType*) instr->getType();
1952         assert(instrType->isPointerType() &&
1953                instrType->getValueType()->isArrayType());
1954         const Type* eltType =
1955           ((ArrayType*) instrType->getValueType())->getElementType();
1956         int tsize = (int) target.findOptimalStorageSize(eltType);
1957
1958         assert(tsize != 0 && "Just to check when this can happen");
1959         // if (tsize == 0)
1960           // {
1961             // numInstr = 0;
1962             // break;
1963           // }
1964         //else go on to create the instructions needed...
1965
1966         // Create a temporary Value to hold the constant type-size
1967         ConstPoolSInt* valueForTSize = ConstPoolSInt::get(Type::IntTy, tsize);
1968
1969         // Create a temporary value to hold `tmp'
1970         Instruction* tmpInstr = new TmpInstruction(Instruction::UserOp1,
1971                                           subtreeRoot->leftChild()->getValue(),
1972                                           NULL /*could insert tsize here*/);
1973         subtreeRoot->getInstruction()->getMachineInstrVec().addTempValue(tmpInstr);
1974         
1975         // Instruction 1: mul numElements, typeSize -> tmp
1976         mvec[0] = new MachineInstr(MULX);
1977         mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
1978                                     subtreeRoot->leftChild()->getValue());
1979         mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
1980                                       valueForTSize);
1981         mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
1982                                       tmpInstr);
1983
1984         tmpInstr->addMachineInstruction(mvec[0]);
1985
1986         // Instruction 2: sub %sp, tmp -> %sp
1987         numInstr++;
1988         mvec[1] = new MachineInstr(SUB);
1989         mvec[1]->SetMachineOperand(0, /*regNum %sp=o6=r[14]*/(unsigned int)14);
1990         mvec[1]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
1991                                       tmpInstr);
1992         mvec[1]->SetMachineOperand(2, /*regNum %sp=o6=r[14]*/(unsigned int)14);
1993         
1994         // Instruction 3: add %sp, 0 -> result
1995         numInstr++;
1996         mvec[2] = new MachineInstr(ADD);
1997         mvec[2]->SetMachineOperand(0, /*regNum %sp=o6=r[14]*/(unsigned int)14);
1998         mvec[2]->SetMachineOperand(1, target.getRegInfo().getZeroRegNum());
1999         mvec[2]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
2000                                       instr);
2001         break;
2002         }
2003
2004       case 61:  // reg:   Call
2005                 // Generate a call-indirect (i.e., JMPL) for now to expose
2006                 // the potential need for registers.  If an absolute address
2007                 // is available, replace this with a CALL instruction.
2008                 // Mark both the indirection register and the return-address
2009                 // register as hidden virtual registers.
2010                 // Also, mark the operands of the Call as implicit operands
2011                 // of the machine instruction.
2012         {
2013         CallInst* callInstr = (CallInst*) subtreeRoot->getInstruction();
2014         Method* callee = callInstr->getCalledMethod();
2015         assert(callInstr->getOpcode() == Instruction::Call); 
2016         
2017         Instruction* jmpAddrReg = new TmpInstruction(Instruction::UserOp1,
2018                                                      callee, NULL);
2019         Instruction* retAddrReg = new TmpInstruction(Instruction::UserOp1,
2020                                                      callInstr, NULL);
2021
2022         // Note temporary values and implicit uses in mvec
2023         callInstr->getMachineInstrVec().addTempValue(jmpAddrReg);
2024         callInstr->getMachineInstrVec().addTempValue(retAddrReg);
2025         for (unsigned i=0, N=callInstr->getNumOperands(); i < N; ++i)
2026           if (callInstr->getOperand(i) != callee)
2027             callInstr->getMachineInstrVec().addImplicitUse(
2028                                                    callInstr->getOperand(i));
2029         
2030         // Generate the machine instruction and its operands
2031         mvec[0] = new MachineInstr(JMPL);
2032         mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
2033                                       jmpAddrReg);
2034         mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
2035                                       (int64_t) 0);
2036         mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
2037                                       retAddrReg);
2038         
2039         // NOTE: jmpAddrReg will be loaded by a different instruction generated
2040         //   by the final code generator, so we just mark the CALL instruction
2041         //   as computing that value.
2042         //   The retAddrReg is actually computed by the CALL instruction.
2043         //
2044         jmpAddrReg->addMachineInstruction(mvec[0]);
2045         retAddrReg->addMachineInstruction(mvec[0]);
2046         
2047         mvec[numInstr++] = new MachineInstr(NOP); // delay slot
2048         break;
2049         }
2050
2051       case 62:  // reg:   Shl(reg, reg)
2052         opType = subtreeRoot->leftChild()->getValue()->getType();
2053         assert(opType->isIntegral()
2054                || opType == Type::BoolTy
2055                || opType->isPointerType()&& "Shl unsupported for other types");
2056         mvec[0] = new MachineInstr((opType == Type::LongTy)? SLLX : SLL);
2057         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
2058         break;
2059
2060       case 63:  // reg:   Shr(reg, reg)
2061         opType = subtreeRoot->leftChild()->getValue()->getType();
2062         assert(opType->isIntegral()
2063                || opType == Type::BoolTy
2064                || opType->isPointerType() &&"Shr unsupported for other types");
2065         mvec[0] = new MachineInstr((opType->isSigned()
2066                                     ? ((opType == Type::LongTy)? SRAX : SRA)
2067                                     : ((opType == Type::LongTy)? SRLX : SRL)));
2068         Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
2069         break;
2070
2071       case 64:  // reg:   Phi(reg,reg)
2072       {         // This instruction has variable #operands, so resultPos is 0.
2073         Instruction* phi = subtreeRoot->getInstruction();
2074         mvec[0] = new MachineInstr(PHI, 1 + phi->getNumOperands());
2075         mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
2076                                       subtreeRoot->getValue());
2077         for (unsigned i=0, N=phi->getNumOperands(); i < N; i++)
2078           mvec[0]->SetMachineOperand(i+1, MachineOperand::MO_VirtualRegister,
2079                                           phi->getOperand(i));
2080         break;
2081       }  
2082       case 71:  // reg:     VReg
2083       case 72:  // reg:     Constant
2084         numInstr = 0;                   // don't forward the value
2085         break;
2086
2087       default:
2088         assert(0 && "Unrecognized BURG rule");
2089         numInstr = 0;
2090         break;
2091       }
2092     }
2093   
2094   if (forwardOperandNum >= 0)
2095     { // We did not generate a machine instruction but need to use operand.
2096       // If user is in the same tree, replace Value in its machine operand.
2097       // If not, insert a copy instruction which should get coalesced away
2098       // by register allocation.
2099       if (subtreeRoot->parent() != NULL)
2100         ForwardOperand(subtreeRoot, subtreeRoot->parent(), forwardOperandNum);
2101       else
2102         {
2103           MachineInstr *minstr1 = NULL, *minstr2 = NULL;
2104           minstr1 = CreateCopyInstructionsByType(target,
2105                 subtreeRoot->getInstruction()->getOperand(forwardOperandNum),
2106                 subtreeRoot->getInstruction(), minstr2);
2107           assert(minstr1);
2108           mvec[numInstr++] = minstr1;
2109           if (minstr2 != NULL)
2110             mvec[numInstr++] = minstr2;
2111         }
2112     }
2113   
2114   if (! ThisIsAChainRule(ruleForNode))
2115     numInstr = FixConstantOperands(subtreeRoot, mvec, numInstr, target);
2116   
2117   return numInstr;
2118 }
2119
2120