1 //===-- SparcV9InstrSelectionSupport.h --------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
10 // More instruction selection support routines for the SparcV9 target.
12 //===----------------------------------------------------------------------===//
14 #ifndef SPARCV9INSTRSELECTIONSUPPORT_H
15 #define SPARCV9INSTRSELECTIONSUPPORT_H
17 #include "llvm/DerivedTypes.h"
18 #include "SparcV9Internals.h"
22 // Choose load instruction opcode based on type of value
24 ChooseLoadInstruction(const Type *DestTy)
26 switch (DestTy->getTypeID()) {
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:
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");
45 // Choose store instruction opcode based on type of value
47 ChooseStoreInstruction(const Type *DestTy)
49 switch (DestTy->getTypeID()) {
52 case Type::SByteTyID: return V9::STBr;
53 case Type::UShortTyID:
54 case Type::ShortTyID: return V9::STHr;
56 case Type::IntTyID: return V9::STWr;
57 case Type::PointerTyID:
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");
70 ChooseAddInstructionByType(const Type* resultType)
72 MachineOpCode opCode = V9::INVALID_OPCODE;
74 if (resultType->isIntegral() ||
75 isa<PointerType>(resultType) ||
76 isa<FunctionType>(resultType) ||
77 resultType == Type::LabelTy)
82 switch(resultType->getTypeID())
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;
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
99 convertOpcodeFromRegToImm(unsigned Opcode) {
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;
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;
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;
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;
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;
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;
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;
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;
206 case V9::JMPLCALLr: return V9::JMPLCALLi;
207 case V9::JMPLRETr: return V9::JMPLRETi;
209 /* save and restore */
210 case V9::SAVEr: return V9::SAVEi;
211 case V9::RESTOREr: return V9::RESTOREi;
214 // It's already in correct format
215 // Or, it's just not handled yet, but an assert() would break LLC
217 std::cerr << "Unhandled opcode in convertOpcodeFromRegToImm(): " << Opcode
224 MachineOperand::MachineOperandType
225 ChooseRegOrImmed(Value* val, MachineOpCode opCode,
226 const TargetMachine& targetMachine, bool canUseImmed,
227 unsigned& getMachineRegNum, int64_t& getImmedValue);
229 /// ConvertConstantToIntType - Get the value of an integral constant in the
230 /// form that must be put into the machine register. The specified constant is
231 /// interpreted as (i.e., converted if necessary to) the specified destination
232 /// type. The result is always returned as an uint64_t, since the
233 /// representation of int64_t and uint64_t are identical. The argument can be
234 /// any known const. isValidConstant is set to true if a valid constant was
237 uint64_t ConvertConstantToIntType (const TargetMachine &target,
238 const Value *V, const Type *destType, bool &isValidConstant);
240 /// ConstantMayNotFitInImmedField - Test if this constant may not fit in the
241 /// immediate field of the machine instructions (probably) generated for this
244 bool ConstantMayNotFitInImmedField (const Constant *CV, const Instruction *I);
246 /// CreateCodeToLoadConst - Create an instruction sequence to put the
247 /// constant `val' into the virtual register `dest'. `val' may be a Constant
248 /// or a GlobalValue, viz., the constant address of a global variable or
249 /// function. The generated instructions are returned in `mvec'. Any temp.
250 /// registers (TmpInstruction) created are recorded in mcfi.
252 void CreateCodeToLoadConst (const TargetMachine &target, Function *F,
253 Value *val, Instruction *dest, std::vector<MachineInstr*> &mvec,
254 MachineCodeForInstruction &mcfi);
256 /// CreateSignExtensionInstructions - Create instruction sequence to produce a
257 /// sign-extended register value from an arbitrary sized value (sized in bits,
258 /// not bytes). The generated instructions are appended to `mvec'. Any temp.
259 /// registers (TmpInstruction) created are recorded in mcfi.
261 void CreateSignExtensionInstructions (const TargetMachine &target,
262 Function *F, Value *srcVal, Value *destVal, unsigned int numLowBits,
263 std::vector<MachineInstr*> &mvec, MachineCodeForInstruction &mcfi);
265 /// CreateZeroExtensionInstructions - Create instruction sequence to produce a
266 /// zero-extended register value from an arbitrary sized value (sized in bits,
267 /// not bytes). The generated instructions are appended to `mvec'. Any temp.
268 /// registers (TmpInstruction) created are recorded in mcfi.
270 void CreateZeroExtensionInstructions (const TargetMachine &target,
271 Function *F, Value *srcVal, Value *destVal, unsigned int numLowBits,
272 std::vector<MachineInstr*> &mvec, MachineCodeForInstruction &mcfi);
274 /// CreateCodeToCopyIntToFloat - Create an instruction sequence to copy an
275 /// integer value `val' to a floating point value `dest' by copying to memory
276 /// and back. val must be an integral type. dest must be a Float or Double.
277 /// The generated instructions are returned in `mvec'. Any temp. registers
278 /// (TmpInstruction) created are recorded in mcfi.
280 void CreateCodeToCopyIntToFloat (const TargetMachine &target,
281 Function *F, Value *val, Instruction *dest, std::vector<MachineInstr*> &mvec,
282 MachineCodeForInstruction &mcfi);
284 /// CreateCodeToCopyFloatToInt - Create an instruction sequence to copy an FP
285 /// value `val' to an integer value `dest' by copying to memory and back. The
286 /// generated instructions are returned in `mvec'. Any temp. registers
287 /// (TmpInstruction) created are recorded in mcfi.
289 void CreateCodeToCopyFloatToInt (const TargetMachine &target, Function *F,
290 Value *val, Instruction *dest, std::vector<MachineInstr*> &mvec,
291 MachineCodeForInstruction &mcfi);
293 /// CreateCopyInstructionsByType - Create instruction(s) to copy src to dest,
294 /// for arbitrary types The generated instructions are returned in `mvec'. Any
295 /// temp. registers (TmpInstruction) created are recorded in mcfi.
297 void CreateCopyInstructionsByType (const TargetMachine &target,
298 Function *F, Value *src, Instruction *dest, std::vector<MachineInstr*> &mvec,
299 MachineCodeForInstruction &mcfi);
301 /// CreateSignExtensionInstructions - Create instruction sequence to produce a
302 /// sign-extended register value from an arbitrary sized value (sized in bits,
303 /// not bytes). The generated instructions are appended to `mvec'. Any temp.
304 /// registers (TmpInstruction) created are recorded in mcfi.
306 void CreateSignExtensionInstructions (const TargetMachine &target,
307 Function *F, Value *srcVal, Value *destVal, unsigned int numLowBits,
308 std::vector<MachineInstr*> &mvec, MachineCodeForInstruction &mcfi);
310 /// CreateZeroExtensionInstructions - Create instruction sequence to produce a
311 /// zero-extended register value from an arbitrary sized value (sized in bits,
312 /// not bytes). The generated instructions are appended to `mvec'. Any temp.
313 /// registers (TmpInstruction) created are recorded in mcfi.
315 void CreateZeroExtensionInstructions (const TargetMachine &target,
316 Function *F, Value *srcVal, Value *destVal, unsigned int numLowBits,
317 std::vector<MachineInstr*> &mvec, MachineCodeForInstruction &mcfi);
319 } // End llvm namespace