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