Moved implementation of class UltraSparcInstrInfo here.
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9InstrInfo.cpp
1 // $Id$
2 //***************************************************************************
3 // File:
4 //      SparcInstrInfo.cpp
5 // 
6 // Purpose:
7 //      
8 // History:
9 //      10/15/01         -  Vikram Adve  -  Created
10 //**************************************************************************/
11
12
13 #include "SparcInternals.h"
14 #include "SparcInstrSelectionSupport.h"
15 #include "llvm/Target/Sparc.h"
16 #include "llvm/CodeGen/InstrSelection.h"
17 #include "llvm/CodeGen/InstrSelectionSupport.h"
18 #include "llvm/CodeGen/MachineInstr.h"
19 #include "llvm/ConstPoolVals.h"
20 #include "llvm/Type.h"
21
22
23 //************************ Internal Functions ******************************/
24
25
26 static inline MachineInstr*
27 CreateIntSetInstruction(int64_t C, bool isSigned, Value* dest)
28 {
29   MachineInstr* minstr;
30   if (isSigned)
31     {
32       minstr = new MachineInstr(SETSW);
33       minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C);
34     }
35   else
36     {
37       minstr = new MachineInstr(SETUW);
38       minstr->SetMachineOperand(0, MachineOperand::MO_UnextendedImmed, C);
39     }
40   
41   minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, dest);
42   
43   return minstr;
44 }
45
46 //************************* External Classes *******************************/
47
48 //---------------------------------------------------------------------------
49 // class UltraSparcInstrInfo 
50 // 
51 // Purpose:
52 //   Information about individual instructions.
53 //   Most information is stored in the SparcMachineInstrDesc array above.
54 //   Other information is computed on demand, and most such functions
55 //   default to member functions in base class MachineInstrInfo. 
56 //---------------------------------------------------------------------------
57
58 /*ctor*/
59 UltraSparcInstrInfo::UltraSparcInstrInfo()
60   : MachineInstrInfo(SparcMachineInstrDesc,
61                      /*descSize = */ NUM_TOTAL_OPCODES,
62                      /*numRealOpCodes = */ NUM_REAL_OPCODES)
63 {
64 }
65
66
67 // Create an instruction sequence to put the constant `val' into
68 // the virtual register `dest'.  `val' may be a ConstPoolVal or a
69 // GlobalValue, viz., the constant address of a global variable or function.
70 // The generated instructions are returned in `minstrVec'.
71 // Any temp. registers (TmpInstruction) created are returned in `tempVec'.
72 // 
73 void
74 UltraSparcInstrInfo::CreateCodeToLoadConst(Value* val,
75                                        Instruction* dest,
76                                        vector<MachineInstr*>& minstrVec,
77                                        vector<TmpInstruction*>& tempVec) const
78 {
79   MachineInstr* minstr;
80   
81   assert(isa<ConstPoolVal>(val) || isa<GlobalValue>(val) &&
82          "I only know about constant values and global addresses");
83   
84   // Use a "set" instruction for known constants that can go in an integer reg.
85   // Use a "load" instruction for all other constants, in particular,
86   // floating point constants and addresses of globals.
87   // 
88   const Type* valType = val->getType();
89   
90   if (valType->isIntegral() || valType == Type::BoolTy)
91     {
92       bool isValidConstant;
93       int64_t C = GetConstantValueAsSignedInt(val, isValidConstant);
94       assert(isValidConstant && "Unrecognized constant");
95       minstr = CreateIntSetInstruction(C, valType->isSigned(), dest);
96       minstrVec.push_back(minstr);
97     }
98   else
99     {
100       // Make an instruction sequence to load the constant, viz:
101       //            SETSW <addr-of-constant>, addrReg
102       //            LOAD  /*addr*/ addrReg, /*offset*/ 0, dest
103       // Only the SETSW is needed if `val' is a GlobalValue, i.e,. it is
104       // itself a constant address.  Otherwise, both are needed.
105       
106       Value* addrVal;
107       int64_t zeroOffset = 0; // to avoid ambiguity with (Value*) 0
108       
109       if (isa<ConstPoolVal>(val))
110         {
111           // Create another TmpInstruction for the hidden integer register
112           TmpInstruction* addrReg =
113             new TmpInstruction(Instruction::UserOp1, val, NULL);
114           tempVec.push_back(addrReg);
115           addrVal = addrReg;
116         }
117       else
118         addrVal = dest;
119       
120       minstr = new MachineInstr(SETUW);
121       minstr->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp, val);
122       minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,addrVal);
123       minstrVec.push_back(minstr);
124       
125       if (isa<ConstPoolVal>(val))
126         {
127           // addrVal->addMachineInstruction(minstr);
128       
129           minstr = new MachineInstr(ChooseLoadInstruction(val->getType()));
130           minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
131                                        addrVal);
132           minstr->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
133                                        zeroOffset);
134           minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
135                                        dest);
136           minstrVec.push_back(minstr);
137         }
138     }
139 }
140
141
142 //************************ External Functions ******************************/
143