Get rid of the old byte-at-a-time emission code used when the Sparc JIT was
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9InstrSelectionSupport.h
1 //===-- llvm/CodeGen/SparcV9InstrSelectionSupport.h ---------------*- C++ -*-===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // TODO: Need a description here.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef SPARC_INSTR_SELECTION_SUPPORT_h
15 #define SPARC_INSTR_SELECTION_SUPPORT_h
16
17 #include "llvm/DerivedTypes.h"
18 #include "SparcV9Internals.h"
19
20 namespace llvm {
21
22 // Choose load instruction opcode based on type of value
23 inline MachineOpCode
24 ChooseLoadInstruction(const Type *DestTy)
25 {
26   switch (DestTy->getPrimitiveID()) {
27   case Type::BoolTyID:
28   case Type::UByteTyID:   return V9::LDUBr;
29   case Type::SByteTyID:   return V9::LDSBr;
30   case Type::UShortTyID:  return V9::LDUHr;
31   case Type::ShortTyID:   return V9::LDSHr;
32   case Type::UIntTyID:    return V9::LDUWr;
33   case Type::IntTyID:     return V9::LDSWr;
34   case Type::PointerTyID:
35   case Type::ULongTyID:
36   case Type::LongTyID:    return V9::LDXr;
37   case Type::FloatTyID:   return V9::LDFr;
38   case Type::DoubleTyID:  return V9::LDDFr;
39   default: assert(0 && "Invalid type for Load instruction");
40   }
41   
42   return 0;
43 }
44
45 // Choose store instruction opcode based on type of value
46 inline MachineOpCode
47 ChooseStoreInstruction(const Type *DestTy)
48 {
49   switch (DestTy->getPrimitiveID()) {
50   case Type::BoolTyID:
51   case Type::UByteTyID:
52   case Type::SByteTyID:   return V9::STBr;
53   case Type::UShortTyID:
54   case Type::ShortTyID:   return V9::STHr;
55   case Type::UIntTyID:
56   case Type::IntTyID:     return V9::STWr;
57   case Type::PointerTyID:
58   case Type::ULongTyID:
59   case Type::LongTyID:    return V9::STXr;
60   case Type::FloatTyID:   return V9::STFr;
61   case Type::DoubleTyID:  return V9::STDFr;
62   default: assert(0 && "Invalid type for Store instruction");
63   }
64   
65   return 0;
66 }
67
68
69 inline MachineOpCode 
70 ChooseAddInstructionByType(const Type* resultType)
71 {
72   MachineOpCode opCode = V9::INVALID_OPCODE;
73   
74   if (resultType->isIntegral() ||
75       isa<PointerType>(resultType) ||
76       isa<FunctionType>(resultType) ||
77       resultType == Type::LabelTy)
78   {
79     opCode = V9::ADDr;
80   }
81   else
82     switch(resultType->getPrimitiveID())
83     {
84     case Type::FloatTyID:  opCode = V9::FADDS; break;
85     case Type::DoubleTyID: opCode = V9::FADDD; break;
86     default: assert(0 && "Invalid type for ADD instruction"); break; 
87     }
88   
89   return opCode;
90 }
91
92
93 // Because the SparcV9 instruction selector likes to re-write operands to
94 // instructions, making them change from a Value* (virtual register) to a
95 // Constant* (making an immediate field), we need to change the opcode from a
96 // register-based instruction to an immediate-based instruction, hence this
97 // mapping.
98 static unsigned
99 convertOpcodeFromRegToImm(unsigned Opcode) {
100   switch (Opcode) {
101     /* arithmetic */
102   case V9::ADDr:     return V9::ADDi;
103   case V9::ADDccr:   return V9::ADDcci;
104   case V9::ADDCr:    return V9::ADDCi;
105   case V9::ADDCccr:  return V9::ADDCcci;
106   case V9::SUBr:     return V9::SUBi;
107   case V9::SUBccr:   return V9::SUBcci;
108   case V9::SUBCr:    return V9::SUBCi;
109   case V9::SUBCccr:  return V9::SUBCcci;
110   case V9::MULXr:    return V9::MULXi;
111   case V9::SDIVXr:   return V9::SDIVXi;
112   case V9::UDIVXr:   return V9::UDIVXi;
113
114     /* logical */
115   case V9::ANDr:    return V9::ANDi;
116   case V9::ANDccr:  return V9::ANDcci;
117   case V9::ANDNr:   return V9::ANDNi;
118   case V9::ANDNccr: return V9::ANDNcci;
119   case V9::ORr:     return V9::ORi;
120   case V9::ORccr:   return V9::ORcci;
121   case V9::ORNr:    return V9::ORNi;
122   case V9::ORNccr:  return V9::ORNcci;
123   case V9::XORr:    return V9::XORi;
124   case V9::XORccr:  return V9::XORcci;
125   case V9::XNORr:   return V9::XNORi;
126   case V9::XNORccr: return V9::XNORcci;
127
128     /* shift */
129   case V9::SLLr5:   return V9::SLLi5;
130   case V9::SRLr5:   return V9::SRLi5;
131   case V9::SRAr5:   return V9::SRAi5;
132   case V9::SLLXr6:  return V9::SLLXi6;
133   case V9::SRLXr6:  return V9::SRLXi6;
134   case V9::SRAXr6:  return V9::SRAXi6;
135
136     /* Conditional move on int comparison with zero */
137   case V9::MOVRZr:   return V9::MOVRZi;
138   case V9::MOVRLEZr: return V9::MOVRLEZi;
139   case V9::MOVRLZr:  return V9::MOVRLZi;
140   case V9::MOVRNZr:  return V9::MOVRNZi;
141   case V9::MOVRGZr:  return V9::MOVRGZi;
142   case V9::MOVRGEZr: return V9::MOVRGEZi;
143
144
145     /* Conditional move on int condition code */
146   case V9::MOVAr:   return V9::MOVAi;
147   case V9::MOVNr:   return V9::MOVNi;
148   case V9::MOVNEr:  return V9::MOVNEi;
149   case V9::MOVEr:   return V9::MOVEi;
150   case V9::MOVGr:   return V9::MOVGi;
151   case V9::MOVLEr:  return V9::MOVLEi;
152   case V9::MOVGEr:  return V9::MOVGEi;
153   case V9::MOVLr:   return V9::MOVLi;
154   case V9::MOVGUr:  return V9::MOVGUi;
155   case V9::MOVLEUr: return V9::MOVLEUi;
156   case V9::MOVCCr:  return V9::MOVCCi;
157   case V9::MOVCSr:  return V9::MOVCSi;
158   case V9::MOVPOSr: return V9::MOVPOSi;
159   case V9::MOVNEGr: return V9::MOVNEGi;
160   case V9::MOVVCr:  return V9::MOVVCi;
161   case V9::MOVVSr:  return V9::MOVVSi;
162
163     /* Conditional move of int reg on fp condition code */
164   case V9::MOVFAr:   return V9::MOVFAi;
165   case V9::MOVFNr:   return V9::MOVFNi;
166   case V9::MOVFUr:   return V9::MOVFUi;
167   case V9::MOVFGr:   return V9::MOVFGi;
168   case V9::MOVFUGr:  return V9::MOVFUGi;
169   case V9::MOVFLr:   return V9::MOVFLi;
170   case V9::MOVFULr:  return V9::MOVFULi;
171   case V9::MOVFLGr:  return V9::MOVFLGi;
172   case V9::MOVFNEr:  return V9::MOVFNEi;
173   case V9::MOVFEr:   return V9::MOVFEi;
174   case V9::MOVFUEr:  return V9::MOVFUEi;
175   case V9::MOVFGEr:  return V9::MOVFGEi;
176   case V9::MOVFUGEr: return V9::MOVFUGEi;
177   case V9::MOVFLEr:  return V9::MOVFLEi;
178   case V9::MOVFULEr: return V9::MOVFULEi;
179   case V9::MOVFOr:   return V9::MOVFOi;
180
181     /* load */
182   case V9::LDSBr:   return V9::LDSBi;
183   case V9::LDSHr:   return V9::LDSHi;
184   case V9::LDSWr:   return V9::LDSWi;
185   case V9::LDUBr:   return V9::LDUBi;
186   case V9::LDUHr:   return V9::LDUHi;
187   case V9::LDUWr:   return V9::LDUWi;
188   case V9::LDXr:    return V9::LDXi;
189   case V9::LDFr:    return V9::LDFi;
190   case V9::LDDFr:   return V9::LDDFi;
191   case V9::LDQFr:   return V9::LDQFi;
192   case V9::LDFSRr:  return V9::LDFSRi;
193   case V9::LDXFSRr: return V9::LDXFSRi;
194
195     /* store */
196   case V9::STBr:    return V9::STBi;
197   case V9::STHr:    return V9::STHi;
198   case V9::STWr:    return V9::STWi;
199   case V9::STXr:    return V9::STXi;
200   case V9::STFr:    return V9::STFi;
201   case V9::STDFr:   return V9::STDFi;
202   case V9::STFSRr:  return V9::STFSRi;
203   case V9::STXFSRr: return V9::STXFSRi;
204
205     /* jump & return */
206   case V9::JMPLCALLr: return V9::JMPLCALLi;
207   case V9::JMPLRETr:  return V9::JMPLRETi;
208   case V9::RETURNr:   return V9::RETURNi;
209
210   /* save and restore */
211   case V9::SAVEr:     return V9::SAVEi;
212   case V9::RESTOREr:  return V9::RESTOREi;
213
214   default:
215     // It's already in correct format
216     // Or, it's just not handled yet, but an assert() would break LLC
217 #if 0
218     std::cerr << "Unhandled opcode in convertOpcodeFromRegToImm(): " << Opcode 
219               << "\n";
220 #endif
221     return Opcode;
222   }
223 }
224
225 MachineOperand::MachineOperandType
226 ChooseRegOrImmed(Value* val, MachineOpCode opCode,
227                  const TargetMachine& targetMachine, bool canUseImmed,
228                  unsigned& getMachineRegNum, int64_t& getImmedValue);
229
230 } // End llvm namespace
231
232 #endif