Added support for caller saving
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9RegInfo.cpp
1 #include "llvm/Target/Sparc.h"
2 #include "SparcInternals.h"
3 #include "llvm/Method.h"
4 #include "llvm/iTerminators.h"
5 #include "llvm/iOther.h"
6 #include "llvm/CodeGen/InstrScheduling.h"
7 #include "llvm/CodeGen/InstrSelection.h"
8
9 #include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
10 #include "llvm/CodeGen/PhyRegAlloc.h"
11
12
13
14
15 //---------------------------------------------------------------------------
16 // UltraSparcRegInfo
17 //---------------------------------------------------------------------------
18
19 //---------------------------------------------------------------------------
20 // Suggests a register for the ret address in the RET machine instruction
21 //---------------------------------------------------------------------------
22 void UltraSparcRegInfo::suggestReg4RetAddr(const MachineInstr * RetMI, 
23                                            LiveRangeInfo& LRI) const {
24
25   assert( (RetMI->getNumOperands() == 2) && "RETURN must have 2 operands");
26   MachineOperand & MO  = ( MachineOperand &) RetMI->getOperand(0);
27
28   MO.setRegForValue( getUnifiedRegNum( IntRegClassID, SparcIntRegOrder::i7) );
29
30
31   // TODO (Optimize): 
32   // Instead of setting the color, we can suggest one. In that case,
33   // we have to test later whether it received the suggested color.
34   // In that case, a LR has to be created at the start of method.
35   // It has to be done as follows (remove the setRegVal above):
36
37   /*
38   const Value *RetAddrVal = MO.getVRegValue();
39
40   assert( RetAddrVal && "LR for ret address must be created at start");
41
42   LiveRange * RetAddrLR = LRI.getLiveRangeForValue( RetAddrVal);  
43   RetAddrLR->setSuggestedColor(getUnifiedRegNum( IntRegClassID, 
44   SparcIntRegOrdr::i7) );
45   */
46
47
48 }
49
50
51 //---------------------------------------------------------------------------
52 // Suggests a register for the ret address in the JMPL/CALL machine instr
53 //---------------------------------------------------------------------------
54 void UltraSparcRegInfo::suggestReg4CallAddr(const MachineInstr * CallMI) const
55 {
56
57   assert( (CallMI->getNumOperands() == 3) && "JMPL must have 3 operands");
58
59   // directly set color since the LR of ret address (if there were one) 
60   // will not extend after the call instr
61
62   MachineOperand & MO  = ( MachineOperand &) CallMI->getOperand(2);
63   MO.setRegForValue( getUnifiedRegNum( IntRegClassID,SparcIntRegOrder::o7) );
64
65 }
66
67
68
69
70 //---------------------------------------------------------------------------
71 //  This method will suggest colors to incoming args to a method. 
72 //  If the arg is passed on stack due to the lack of regs, NOTHING will be
73 //  done - it will be colored (or spilled) as a normal value.
74 //---------------------------------------------------------------------------
75
76 void UltraSparcRegInfo::suggestRegs4MethodArgs(const Method *const Meth, 
77                                                LiveRangeInfo& LRI) const 
78 {
79
80                                                  // get the argument list
81   const Method::ArgumentListType& ArgList = Meth->getArgumentList();           
82                                                  // get an iterator to arg list
83   Method::ArgumentListType::const_iterator ArgIt = ArgList.begin(); 
84
85   // for each argument
86   for( unsigned argNo=0; ArgIt != ArgList.end() ; ++ArgIt, ++argNo) {    
87
88     // get the LR of arg
89     LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *ArgIt); 
90     assert( LR && "No live range found for method arg");
91
92     unsigned RegType = getRegType( LR );
93
94
95     // if the arg is in int class - allocate a reg for an int arg
96     if( RegType == IntRegType ) {
97
98       if( argNo < NumOfIntArgRegs) {
99         LR->setSuggestedColor( SparcIntRegOrder::i0 + argNo );
100
101       }
102   
103       else {
104         // Do NOTHING as this will be colored as a normal value.
105         if (DEBUG_RA) cerr << " Int Regr not suggested for method arg\n";
106       }
107      
108     }
109     else if( RegType==FPSingleRegType && (argNo*2+1) < NumOfFloatArgRegs) 
110       LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2 + 1) );
111     
112  
113     else if( RegType == FPDoubleRegType && (argNo*2) < NumOfFloatArgRegs) 
114       LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2) ); 
115     
116
117   }
118   
119 }
120
121 //---------------------------------------------------------------------------
122 // 
123 //---------------------------------------------------------------------------
124
125 void UltraSparcRegInfo::colorMethodArgs(const Method *const Meth, 
126                                         LiveRangeInfo& LRI,
127                                         AddedInstrns *const FirstAI) const {
128
129                                                  // get the argument list
130   const Method::ArgumentListType& ArgList = Meth->getArgumentList();           
131                                                  // get an iterator to arg list
132   Method::ArgumentListType::const_iterator ArgIt = ArgList.begin(); 
133
134   MachineInstr *AdMI;
135
136
137   // for each argument
138   for( unsigned argNo=0; ArgIt != ArgList.end() ; ++ArgIt, ++argNo) {    
139
140     // get the LR of arg
141     LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *ArgIt); 
142     assert( LR && "No live range found for method arg");
143
144
145     // if the LR received the suggested color, NOTHING to be done
146     if( LR->hasSuggestedColor() && LR->hasColor() )
147       if( LR->getSuggestedColor() == LR->getColor() )
148         continue;
149
150     // We are here because the LR did not have a suggested 
151     // color or did not receive the suggested color. Now handle
152     // individual cases.
153
154
155     unsigned RegType = getRegType( LR );
156     unsigned RegClassID = (LR->getRegClass())->getID();
157
158
159     // find whether this argument is coming in a register (if not, on stack)
160
161     bool isArgInReg = false;
162     unsigned UniArgReg = InvalidRegNum;
163
164     if( (RegType== IntRegType && argNo <  NumOfIntArgRegs)) {
165       isArgInReg = true;
166       UniArgReg = getUnifiedRegNum( RegClassID, SparcIntRegOrder::o0 + argNo );
167     }
168     else if(RegType == FPSingleRegType && argNo < NumOfFloatArgRegs)  { 
169       isArgInReg = true;
170       UniArgReg = getUnifiedRegNum( RegClassID, 
171                                     SparcFloatRegOrder::f0 + argNo*2 + 1 ) ;
172     }
173     else if(RegType == FPDoubleRegType && argNo < NumOfFloatArgRegs)  { 
174       isArgInReg = true;
175       UniArgReg = getUnifiedRegNum(RegClassID, SparcFloatRegOrder::f0+argNo*2);
176     }
177
178     
179     if( LR->hasColor() ) {
180
181       // We are here because the LR did not have a suggested 
182       // color or did not receive the suggested color but LR got a register.
183       // Now we have to copy %ix reg (or stack pos of arg) 
184       // to the register it was colored with.
185
186       unsigned UniLRReg = getUnifiedRegNum(  RegClassID, LR->getColor() );
187        
188       // if the arg is coming in a register and goes into a register
189       if( isArgInReg ) 
190         AdMI = cpReg2RegMI(UniArgReg, UniLRReg, RegType );
191
192       else 
193         assert(0 && "TODO: Color an Incoming arg on stack");
194
195       // Now add the instruction
196       FirstAI->InstrnsBefore.push_back( AdMI );
197
198     }
199
200     else {                                // LR is not colored (i.e., spilled)
201       
202       assert(0 && "TODO: Color a spilled arg ");
203       
204     }
205
206
207   }  // for each incoming argument
208
209 }
210
211
212
213
214 //---------------------------------------------------------------------------
215 // This method is called before graph coloring to suggest colors to the
216 // outgoing call args and the return value of the call.
217 //---------------------------------------------------------------------------
218 void UltraSparcRegInfo::suggestRegs4CallArgs(const MachineInstr *const CallMI, 
219                                              LiveRangeInfo& LRI,
220                                              vector<RegClass *> RCList) const {
221
222   assert ( (UltraSparcInfo->getInstrInfo()).isCall(CallMI->getOpCode()) );
223
224   suggestReg4CallAddr(CallMI);
225
226
227   // First color the return value of the call instruction. The return value
228   // will be in %o0 if the value is an integer type, or in %f0 if the 
229   // value is a float type.
230
231   // the return value cannot have a LR in machine instruction since it is
232   // only defined by the call instruction
233
234   // if type is not void,  create a new live range and set its 
235   // register class and add to LRI
236
237   unsigned NumOfImpRefs =  CallMI->getNumImplicitRefs();
238   unsigned NumOfCallArgs = NumOfImpRefs;  // assume all implicits are args
239
240   if(  NumOfImpRefs > 0 ) {
241
242     // The last implicit operand is the return value of a call
243     if(  CallMI->implicitRefIsDefined(NumOfImpRefs-1) ) {
244
245       const Value *RetVal = CallMI->getImplicitRef(NumOfImpRefs-1); 
246
247       assert( (! LRI.getLiveRangeForValue( RetVal ) ) && 
248               "LR for ret Value of call already definded!");
249
250
251       // create a new LR for the return value
252
253       LiveRange * RetValLR = new LiveRange();  
254       RetValLR->add( RetVal );
255       unsigned RegClassID = getRegClassIDOfValue( RetVal );
256       RetValLR->setRegClass( RCList[RegClassID] );
257       LRI.addLRToMap( RetVal, RetValLR);
258
259       // now suggest a register depending on the register class of ret arg
260
261       if( RegClassID == IntRegClassID ) 
262         RetValLR->setSuggestedColor(SparcIntRegOrder::o0);
263       else if (RegClassID == FloatRegClassID ) 
264         RetValLR->setSuggestedColor(SparcFloatRegOrder::f0 );
265       else assert( 0 && "Unknown reg class for return value of call\n");
266
267       // the last imp ref is the def, so one less arg
268       NumOfCallArgs--; 
269
270     }
271
272   }
273
274   // Now suggest colors for arguments (operands) of the call instruction.
275   // Colors are suggested only if the arg number is smaller than the
276   // the number of registers allocated for argument passing.
277
278   
279   // go thru call args - implicit operands of the call MI
280   for(unsigned argNo=0, i=0; i < NumOfCallArgs; ++i, ++argNo ) {
281
282     const Value *CallArg = CallMI->getImplicitRef(i);
283     
284     // get the LR of call operand (parameter)
285     LiveRange *const LR = LRI.getLiveRangeForValue(CallArg); 
286
287     // not possible to have a null LR since all args (even consts)  
288     // must be defined before
289     if( !LR ) {          
290       if( DEBUG_RA) {
291         cerr << " ERROR: In call instr, no LR for arg:  " ;
292         printValue(CallArg); cerr << endl;
293       }
294       assert(0 && "NO LR for call arg");  
295       // continue;
296     }
297     
298     unsigned RegType = getRegType( LR );
299
300     // if the arg is in int class - allocate a reg for an int arg
301     if( RegType == IntRegType ) {
302
303       if( argNo < NumOfIntArgRegs) 
304         LR->setSuggestedColor( SparcIntRegOrder::o0 + argNo );
305
306       else if (DEBUG_RA) 
307         // Do NOTHING as this will be colored as a normal value.
308         cerr << " Regr not suggested for int call arg" << endl;
309       
310     }
311     else if( RegType == FPSingleRegType &&  (argNo*2 +1)< NumOfFloatArgRegs) 
312       LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2 + 1) );
313     
314  
315     else if( RegType == FPDoubleRegType && (argNo*2) < NumOfFloatArgRegs) 
316       LR->setSuggestedColor( SparcFloatRegOrder::f0 + (argNo * 2) ); 
317     
318
319   } // for all call arguments
320
321 }
322
323
324 //---------------------------------------------------------------------------
325 // After graph coloring, we have call this method to see whehter the return
326 // value and the call args received the correct colors. If not, we have
327 // to instert copy instructions.
328 //---------------------------------------------------------------------------
329
330
331 void UltraSparcRegInfo::colorCallArgs(const MachineInstr *const CallMI,
332                                       LiveRangeInfo& LRI,
333                                       AddedInstrns *const CallAI) const {
334
335
336   assert ( (UltraSparcInfo->getInstrInfo()).isCall(CallMI->getOpCode()) );
337
338   // First color the return value of the call.
339   // If there is a LR for the return value, it means this
340   // method returns a value
341   
342   MachineInstr *AdMI;
343
344   unsigned NumOfImpRefs =  CallMI->getNumImplicitRefs();
345   unsigned NumOfCallArgs = NumOfImpRefs;  // assume all implicits are args
346
347   if(  NumOfImpRefs > 0 ) {
348
349     // The last implicit operand is the return value of a call
350     if(  CallMI->implicitRefIsDefined(NumOfImpRefs-1) ) {
351
352       // one less call arg since last implicit ref is the return value
353       NumOfCallArgs--;
354
355       // find the return value and its LR
356       const Value *RetVal = CallMI->getImplicitRef(NumOfImpRefs-1); 
357       LiveRange * RetValLR = LRI.getLiveRangeForValue( RetVal );
358
359       if( !RetValLR ) {
360         cerr << "\nNo LR for:";
361         printValue( RetVal );
362         cerr << endl;
363         assert( RetValLR && "ERR:No LR for non-void return value");
364         //return;
365       }
366
367       bool recvSugColor = false;
368
369       if( RetValLR->hasSuggestedColor() && RetValLR->hasColor() )
370         if( RetValLR->getSuggestedColor() == RetValLR->getColor())
371           recvSugColor = true;
372
373       // if we didn't receive the suggested color for some reason, 
374       // put copy instruction
375
376       if( !recvSugColor ) {
377
378         if( RetValLR->hasColor() ) {
379
380           unsigned RegType = getRegType( RetValLR );
381           unsigned RegClassID = (RetValLR->getRegClass())->getID();
382
383           unsigned 
384             UniRetLRReg=getUnifiedRegNum(RegClassID,RetValLR->getColor());
385           unsigned UniRetReg = InvalidRegNum;
386
387           // find where we receive the return value depending on
388           // register class
389             
390           if(RegClassID == IntRegClassID)
391             UniRetReg = getUnifiedRegNum( RegClassID, SparcIntRegOrder::o0);
392           else if(RegClassID == FloatRegClassID)
393             UniRetReg = getUnifiedRegNum( RegClassID, SparcFloatRegOrder::f0);
394
395
396           AdMI = cpReg2RegMI(UniRetReg, UniRetLRReg, RegType );         
397           CallAI->InstrnsAfter.push_back( AdMI );
398       
399         
400         } // if LR has color
401         else {
402         
403           assert(0 && "LR of return value is splilled");
404         }
405       
406
407       } // the LR didn't receive the suggested color  
408     
409     } // if there a return value
410
411   } // if there is an implicit arg for a return value
412   
413
414
415   // Now color all args of the call instruction
416
417
418   for(unsigned argNo=0, i=0; i < NumOfCallArgs; ++i, ++argNo ) {
419
420     const Value *CallArg = CallMI->getImplicitRef(i);
421
422     // get the LR of call operand (parameter)
423     LiveRange *const LR = LRI.getLiveRangeForValue(CallArg); 
424
425     unsigned RegType = getRegType( CallArg );
426     unsigned RegClassID =  getRegClassIDOfValue( CallArg);
427     
428     // find whether this argument is coming in a register (if not, on stack)
429
430     bool isArgInReg = false;
431     unsigned UniArgReg = InvalidRegNum;
432
433     if( (RegType== IntRegType && argNo <  NumOfIntArgRegs)) {
434       isArgInReg = true;
435       UniArgReg = getUnifiedRegNum(RegClassID, SparcIntRegOrder::o0 + argNo );
436     }
437     else if(RegType == FPSingleRegType && argNo < NumOfFloatArgRegs)  { 
438       isArgInReg = true;
439       UniArgReg = getUnifiedRegNum(RegClassID, 
440                                    SparcFloatRegOrder::f0 + (argNo*2 + 1) );
441     }
442     else if(RegType == FPDoubleRegType && argNo < NumOfFloatArgRegs)  { 
443       isArgInReg = true;
444       UniArgReg = getUnifiedRegNum(RegClassID, SparcFloatRegOrder::f0+argNo*2);
445     }
446
447
448     // not possible to have a null LR since all args (even consts)  
449     // must be defined before
450     if( !LR ) {          
451       if( DEBUG_RA) {
452         cerr << " ERROR: In call instr, no LR for arg:  " ;
453         printValue(CallArg); cerr << endl;
454       }
455       assert(0 && "NO LR for call arg");  
456       // continue;
457     }
458
459
460     // if the LR received the suggested color, NOTHING to do
461
462     if( LR->hasSuggestedColor() && LR->hasColor() )
463       if( LR->getSuggestedColor() == LR->getColor() )
464         continue;
465         
466     
467     if( LR->hasColor() ) {
468
469       // We are here because though the LR is allocated a register, it
470       // was not allocated the suggested register. So, we have to copy %ix reg 
471       // (or stack pos of arg) to the register it was colored with
472
473
474       unsigned UniLRReg = getUnifiedRegNum( RegClassID,  LR->getColor() );
475
476       if( isArgInReg ) 
477         AdMI = cpReg2RegMI(UniLRReg, UniArgReg, RegType );
478
479       else 
480         assert(0 && "TODO: Push an outgoing arg on stack");
481
482       // Now add the instruction
483       CallAI->InstrnsBefore.push_back( AdMI );
484
485     }
486
487     else {                                // LR is not colored (i.e., spilled)
488       
489       assert(0 && "TODO: Copy a spilled call arg to an output reg ");
490       
491     }
492
493   }  // for each parameter in call instruction
494
495 }
496
497 //---------------------------------------------------------------------------
498 // This method is called for an LLVM return instruction to identify which
499 // values will be returned from this method and to suggest colors.
500 //---------------------------------------------------------------------------
501 void UltraSparcRegInfo::suggestReg4RetValue(const MachineInstr *const RetMI, 
502                                              LiveRangeInfo& LRI) const {
503
504   assert( (UltraSparcInfo->getInstrInfo()).isReturn( RetMI->getOpCode() ) );
505
506   
507   suggestReg4RetAddr(RetMI, LRI);
508
509   // if there is an implicit ref, that has to be the ret value
510   if(  RetMI->getNumImplicitRefs() > 0 ) {
511
512     // The first implicit operand is the return value of a return instr
513     const Value *RetVal =  RetMI->getImplicitRef(0);
514
515     MachineInstr *AdMI;
516     LiveRange *const LR = LRI.getLiveRangeForValue( RetVal ); 
517
518     if( !LR ) {
519      cerr << "\nNo LR for:";
520      printValue( RetVal );
521      cerr << endl;
522      assert( LR && "No LR for return value of non-void method");
523      //return;
524    }
525
526     unsigned RegClassID = (LR->getRegClass())->getID();
527       
528     if( RegClassID == IntRegClassID ) 
529       LR->setSuggestedColor(SparcIntRegOrder::i0);
530     
531     else if ( RegClassID == FloatRegClassID ) 
532       LR->setSuggestedColor(SparcFloatRegOrder::f0);
533       
534   }
535
536 }
537
538 //---------------------------------------------------------------------------
539
540 //---------------------------------------------------------------------------
541 void UltraSparcRegInfo::colorRetValue(const  MachineInstr *const RetMI, 
542                                       LiveRangeInfo& LRI,
543                                       AddedInstrns *const RetAI) const {
544
545   assert( (UltraSparcInfo->getInstrInfo()).isReturn( RetMI->getOpCode() ) );
546
547   // if there is an implicit ref, that has to be the ret value
548   if(  RetMI->getNumImplicitRefs() > 0 ) {
549
550     // The first implicit operand is the return value of a return instr
551     const Value *RetVal =  RetMI->getImplicitRef(0);
552
553     MachineInstr *AdMI;
554     LiveRange *const LR = LRI.getLiveRangeForValue( RetVal ); 
555
556     if( ! LR ) {
557         cerr << "\nNo LR for:";
558         printValue( RetVal );
559         cerr << endl;
560         // assert( LR && "No LR for return value of non-void method");
561         return;
562    }
563
564     unsigned RegClassID =  getRegClassIDOfValue(RetVal);
565     unsigned RegType = getRegType( RetVal );
566     unsigned UniRetReg = InvalidRegNum;
567     
568     if(RegClassID == IntRegClassID)
569       UniRetReg = getUnifiedRegNum( RegClassID, SparcIntRegOrder::i0 );
570     else if(RegClassID == FloatRegClassID)
571       UniRetReg = getUnifiedRegNum( RegClassID, SparcFloatRegOrder::f0);
572      
573
574
575     // if the LR received the suggested color, NOTHING to do
576
577     if( LR->hasSuggestedColor() && LR->hasColor() )
578       if( LR->getSuggestedColor() == LR->getColor() )
579         return;
580
581     if( LR->hasColor() ) {
582
583       // We are here because the LR was allocted a regiter, but NOT
584       // the correct register.
585
586       // copy the LR of retun value to i0 or f0
587
588       unsigned UniLRReg =getUnifiedRegNum( RegClassID, LR->getColor());
589
590       if(RegClassID == IntRegClassID)
591         UniRetReg = getUnifiedRegNum( RegClassID, SparcIntRegOrder::i0);
592       else if(RegClassID == FloatRegClassID)
593         UniRetReg = getUnifiedRegNum( RegClassID, SparcFloatRegOrder::f0);
594       
595       AdMI = cpReg2RegMI( UniLRReg, UniRetReg, RegType); 
596
597     }
598     else 
599       assert(0 && "TODO: Copy the return value from stack\n");
600
601   } // if there is a return value
602
603 }
604
605
606 //---------------------------------------------------------------------------
607 // Copy from a register to register. Register number must be the unified
608 // register number
609 //---------------------------------------------------------------------------
610
611
612 MachineInstr * UltraSparcRegInfo::cpReg2RegMI(const unsigned SrcReg, 
613                                               const unsigned DestReg,
614                                               const int RegType) const {
615
616   assert( ((int)SrcReg != InvalidRegNum) && ((int)DestReg != InvalidRegNum) &&
617           "Invalid Register");
618   
619   MachineInstr * MI = NULL;
620
621   switch( RegType ) {
622     
623   case IntRegType:
624     MI = new MachineInstr(ADD, 3);
625     MI->SetMachineOperand(0, SrcReg, false);
626     MI->SetMachineOperand(1, SparcIntRegOrder::g0, false);
627     MI->SetMachineOperand(2, DestReg, true);
628     break;
629
630   case FPSingleRegType:
631     MI = new MachineInstr(FMOVS, 2);
632     MI->SetMachineOperand(0, SrcReg, false);
633     MI->SetMachineOperand(1, DestReg, true);
634     break;
635
636   case FPDoubleRegType:
637     MI = new MachineInstr(FMOVD, 2);
638     MI->SetMachineOperand(0, SrcReg, false);    
639     MI->SetMachineOperand(1, DestReg, true);
640     break;
641
642   default:
643     assert(0 && "Unknow RegType");
644   }
645
646   return MI;
647 }
648
649
650 //---------------------------------------------------------------------------
651 // Copy from a register to memory. Register number must be the unified
652 // register number
653 //---------------------------------------------------------------------------
654
655
656 MachineInstr * UltraSparcRegInfo::cpReg2MemMI(const unsigned SrcReg, 
657                                               const unsigned DestPtrReg,
658                                               const int Offset,
659                                               const int RegType) const {
660
661
662   MachineInstr * MI = NULL;
663
664   switch( RegType ) {
665     
666   case IntRegType:
667     MI = new MachineInstr(STX, 3);
668     MI->SetMachineOperand(0, DestPtrReg, false);
669     MI->SetMachineOperand(1, SrcReg, false);
670     MI->SetMachineOperand(2, MachineOperand:: MO_SignExtendedImmed, 
671                           (int64_t) Offset, false);
672     break;
673
674   case FPSingleRegType:
675     MI = new MachineInstr(ST, 3);
676     MI->SetMachineOperand(0, DestPtrReg, false);
677     MI->SetMachineOperand(1, SrcReg, false);
678     MI->SetMachineOperand(2, MachineOperand:: MO_SignExtendedImmed, 
679                           (int64_t) Offset, false);
680     break;
681
682   case FPDoubleRegType:
683     MI = new MachineInstr(STD, 3);
684     MI->SetMachineOperand(0, DestPtrReg, false);
685     MI->SetMachineOperand(1, SrcReg, false);
686     MI->SetMachineOperand(2, MachineOperand:: MO_SignExtendedImmed, 
687                           (int64_t) Offset, false);
688     break;
689
690   default:
691     assert(0 && "Unknow RegType");
692   }
693
694   return MI;
695 }
696
697
698 //---------------------------------------------------------------------------
699 // Copy from memory to a reg. Register number must be the unified
700 // register number
701 //---------------------------------------------------------------------------
702
703
704 MachineInstr * UltraSparcRegInfo::cpMem2RegMI(const unsigned SrcPtrReg, 
705                                               const int Offset,
706                                               const unsigned DestReg,
707                                               const int RegType) const {
708   
709   MachineInstr * MI = NULL;
710
711   switch( RegType ) {
712     
713   case IntRegType:
714     MI = new MachineInstr(LDX, 3);
715     MI->SetMachineOperand(0, SrcPtrReg, false);
716     MI->SetMachineOperand(1, MachineOperand:: MO_SignExtendedImmed, 
717                           (int64_t) Offset, false);
718     MI->SetMachineOperand(2, DestReg, false);
719     break;
720
721   case FPSingleRegType:
722     MI = new MachineInstr(LD, 3);
723     MI->SetMachineOperand(0, SrcPtrReg, false);
724     MI->SetMachineOperand(1, MachineOperand:: MO_SignExtendedImmed, 
725                           (int64_t) Offset, false);
726     MI->SetMachineOperand(2, DestReg, false);
727
728     break;
729
730   case FPDoubleRegType:
731     MI = new MachineInstr(LDD, 3);
732     MI->SetMachineOperand(0, SrcPtrReg, false);
733     MI->SetMachineOperand(1, MachineOperand:: MO_SignExtendedImmed, 
734                           (int64_t) Offset, false);
735     MI->SetMachineOperand(2, DestReg, false);
736     break;
737
738   default:
739     assert(0 && "Unknow RegType");
740   }
741
742   return MI;
743 }
744
745
746
747
748
749
750
751
752
753 //---------------------------------------------------------------------------
754 // Only  constant/label values are accepted.
755 // ***This code is temporary ***
756 //---------------------------------------------------------------------------
757
758
759 MachineInstr * UltraSparcRegInfo::cpValue2RegMI(Value * Val, 
760                                                 const unsigned DestReg,
761                                                 const int RegType) const {
762
763   assert( ((int)DestReg != InvalidRegNum) && "Invalid Register");
764
765   /*
766   unsigned MReg;
767   int64_t Imm;
768
769   MachineOperand::MachineOperandType MOTypeInt = 
770     ChooseRegOrImmed(Val, ADD,  *UltraSparcInfo, true, MReg, Imm);
771   */
772
773   MachineOperand::MachineOperandType MOType;
774
775   switch( Val->getValueType() ) {
776
777   case Value::ConstantVal: 
778   case Value::GlobalVariableVal:
779     MOType = MachineOperand:: MO_UnextendedImmed;  // TODO**** correct???
780     break;
781
782   case Value::BasicBlockVal:
783   case Value::MethodVal:
784     MOType = MachineOperand::MO_PCRelativeDisp;
785     break;
786
787   default:
788     cerr << "Value Type: " << Val->getValueType() << endl;
789     assert(0 && "Unknown val type - Only constants/globals/labels are valid");
790   }
791
792
793
794   MachineInstr * MI = NULL;
795
796   switch( RegType ) {
797     
798   case IntRegType:
799     MI = new MachineInstr(ADD);
800     MI->SetMachineOperand(0, MOType, Val, false);
801     MI->SetMachineOperand(1, SparcIntRegOrder::g0, false);
802     MI->SetMachineOperand(2, DestReg, true);
803     break;
804
805   case FPSingleRegType:
806     assert(0 && "FP const move not yet implemented");
807     MI = new MachineInstr(FMOVS);
808     MI->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, Val, false);
809     MI->SetMachineOperand(1, DestReg, true);
810     break;
811
812   case FPDoubleRegType:    
813     assert(0 && "FP const move not yet implemented");
814     MI = new MachineInstr(FMOVD);
815     MI->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, Val, false);
816     MI->SetMachineOperand(1, DestReg, true);
817     break;
818
819   default:
820     assert(0 && "Unknow RegType");
821   }
822
823   return MI;
824 }
825
826
827
828
829
830
831
832 //---------------------------------------------------------------------------
833 // Print the register assigned to a LR
834 //---------------------------------------------------------------------------
835
836 void UltraSparcRegInfo::printReg(const LiveRange *const LR) {
837
838   unsigned RegClassID = (LR->getRegClass())->getID();
839
840   cerr << " *Node " << (LR->getUserIGNode())->getIndex();
841
842   if( ! LR->hasColor() ) {
843     cerr << " - could not find a color" << endl;
844     return;
845   }
846   
847   // if a color is found
848
849   cerr << " colored with color "<< LR->getColor();
850
851   if( RegClassID == IntRegClassID ) {
852
853     cerr<< " [" << SparcIntRegOrder::getRegName(LR->getColor()) ;
854     cerr << "]" << endl;
855   }
856   else if ( RegClassID == FloatRegClassID) {
857     cerr << "[" << SparcFloatRegOrder::getRegName(LR->getColor());
858     if( LR->getTypeID() == Type::DoubleTyID )
859       cerr << "+" << SparcFloatRegOrder::getRegName(LR->getColor()+1);
860     cerr << "]" << endl;
861   }
862 }