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