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