Added a few more methods for creating instructions.
[oota-llvm.git] / include / llvm / CodeGen / InstrSelectionSupport.h
1 // $Id$ -*-c++-*-
2 //***************************************************************************
3 // File:
4 //      InstrSelectionSupport.h
5 // 
6 // Purpose:
7 //      Target-independent instruction selection code.
8 //      See SparcInstrSelection.cpp for usage.
9 //      
10 // History:
11 //      10/10/01         -  Vikram Adve  -  Created
12 //**************************************************************************/
13
14 #ifndef LLVM_CODEGEN_INSTR_SELECTION_SUPPORT_H
15 #define LLVM_CODEGEN_INSTR_SELECTION_SUPPORT_H
16
17 #include "llvm/Instruction.h"
18 #include "llvm/CodeGen/MachineInstr.h"
19 class InstructionNode;
20 class TargetMachine;
21
22
23 //---------------------------------------------------------------------------
24 // Function GetConstantValueAsSignedInt
25 // 
26 // Convenience function to get the value of an integer constant, for an
27 // appropriate integer or non-integer type that can be held in an integer.
28 // The type of the argument must be the following:
29 //      Signed or unsigned integer
30 //      Boolean
31 //      Pointer
32 // 
33 // isValidConstant is set to true if a valid constant was found.
34 //---------------------------------------------------------------------------
35
36 int64_t         GetConstantValueAsSignedInt     (const Value *V,
37                                                  bool &isValidConstant);
38
39
40 //---------------------------------------------------------------------------
41 // Function: FoldGetElemChain
42 // 
43 // Purpose:
44 //   Fold a chain of GetElementPtr instructions into an equivalent
45 //   (Pointer, IndexVector) pair.  Returns the pointer Value, and
46 //   stores the resulting IndexVector in argument chainIdxVec.
47 //---------------------------------------------------------------------------
48
49 Value*          FoldGetElemChain    (const InstructionNode* getElemInstrNode,
50                                      std::vector<Value*>& chainIdxVec);
51
52
53 //------------------------------------------------------------------------ 
54 // Function Set2OperandsFromInstr
55 // Function Set3OperandsFromInstr
56 // 
57 // Purpose:
58 // 
59 // For the common case of 2- and 3-operand arithmetic/logical instructions,
60 // set the m/c instr. operands directly from the VM instruction's operands.
61 // Check whether the first or second operand is 0 and can use a dedicated
62 // "0" register.
63 // Check whether the second operand should use an immediate field or register.
64 // (First and third operands are never immediates for such instructions.)
65 // 
66 // Arguments:
67 // canDiscardResult: Specifies that the result operand can be discarded
68 //                   by using the dedicated "0"
69 // 
70 // op1position, op2position and resultPosition: Specify in which position
71 //                   in the machine instruction the 3 operands (arg1, arg2
72 //                   and result) should go.
73 // 
74 // RETURN VALUE: unsigned int flags, where
75 //      flags & 0x01    => operand 1 is constant and needs a register
76 //      flags & 0x02    => operand 2 is constant and needs a register
77 //------------------------------------------------------------------------ 
78
79 void            Set2OperandsFromInstr   (MachineInstr* minstr,
80                                          InstructionNode* vmInstrNode,
81                                          const TargetMachine& targetMachine,
82                                          bool canDiscardResult = false,
83                                          int op1Position = 0,
84                                          int resultPosition = 1);
85
86 void            Set3OperandsFromInstr   (MachineInstr* minstr,
87                                          InstructionNode* vmInstrNode,
88                                          const TargetMachine& targetMachine,
89                                          bool canDiscardResult = false,
90                                          int op1Position = 0,
91                                          int op2Position = 1,
92                                          int resultPosition = 2);
93
94
95 //------------------------------------------------------------------------ 
96 // Common machine instruction operand combinations
97 // to simplify code generation.
98 //------------------------------------------------------------------------ 
99
100 inline MachineInstr*
101 Create1OperandInstr(MachineOpCode opCode, Value* argVal1)
102 {
103   MachineInstr* M = new MachineInstr(opCode);
104   M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, argVal1);
105   return M;
106 }
107
108 inline MachineInstr*
109 Create2OperandInstr(MachineOpCode opCode, Value* argVal1, Value* argVal2)
110 {
111   MachineInstr* M = new MachineInstr(opCode);
112   M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, argVal1);
113   M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, argVal2);
114   return M;
115 }
116
117 inline MachineInstr*
118 Create2OperandInstr(MachineOpCode opCode,
119                     Value* argVal1, MachineOperand::MachineOperandType type1,
120                     Value* argVal2, MachineOperand::MachineOperandType type2)
121 {
122   MachineInstr* M = new MachineInstr(opCode);
123   M->SetMachineOperandVal(0, type1, argVal1);
124   M->SetMachineOperandVal(1, type2, argVal2);
125   return M;
126 }
127
128
129 inline MachineInstr*
130 Create2OperandInstr_UImmed(MachineOpCode opCode,
131                            unsigned int unextendedImmed, Value* argVal2)
132 {
133   MachineInstr* M = new MachineInstr(opCode);
134   M->SetMachineOperandConst(0, MachineOperand::MO_UnextendedImmed,
135                                unextendedImmed);
136   M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, argVal2);
137   return M;
138 }
139
140 inline MachineInstr*
141 Create2OperandInstr_SImmed(MachineOpCode opCode,
142                            int signExtendedImmed, Value* argVal2)
143 {
144   MachineInstr* M = new MachineInstr(opCode);
145   M->SetMachineOperandConst(0, MachineOperand::MO_SignExtendedImmed,
146                                signExtendedImmed);
147   M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, argVal2);
148   return M;
149 }
150
151 inline MachineInstr*
152 Create2OperandInstr_Addr(MachineOpCode opCode,
153                          Value* label, Value* argVal2)
154 {
155   MachineInstr* M = new MachineInstr(opCode);
156   M->SetMachineOperandVal(0, MachineOperand::MO_PCRelativeDisp,  label);
157   M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, argVal2);
158   return M;
159 }
160
161 inline MachineInstr*
162 Create2OperandInstr_Reg(MachineOpCode opCode,
163                         Value* argVal1, unsigned int regNum)
164 {
165   MachineInstr* M = new MachineInstr(opCode);
166   M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, argVal1);
167   M->SetMachineOperandReg(1, regNum);
168   return M;
169 }
170
171 inline MachineInstr*
172 Create2OperandInstr_Reg(MachineOpCode opCode,
173                         unsigned int regNum1, unsigned int regNum2)
174                  
175 {
176   MachineInstr* M = new MachineInstr(opCode);
177   M->SetMachineOperandReg(0, regNum1);
178   M->SetMachineOperandReg(1, regNum2);
179   return M;
180 }
181
182 inline MachineInstr*
183 Create3OperandInstr(MachineOpCode opCode,
184                     Value* argVal1, MachineOperand::MachineOperandType type1,
185                     Value* argVal2, MachineOperand::MachineOperandType type2,
186                     Value* argVal3, MachineOperand::MachineOperandType type3)
187 {
188   MachineInstr* M = new MachineInstr(opCode);
189   M->SetMachineOperandVal(0, type1, argVal1);
190   M->SetMachineOperandVal(1, type2, argVal2);
191   M->SetMachineOperandVal(2, type3, argVal3);
192   return M;
193 }
194
195 inline MachineInstr*
196 Create3OperandInstr(MachineOpCode opCode, Value* argVal1,
197                     Value* argVal2, Value* argVal3)
198 {
199   return Create3OperandInstr(opCode,
200                              argVal1, MachineOperand::MO_VirtualRegister, 
201                              argVal2, MachineOperand::MO_VirtualRegister, 
202                              argVal3, MachineOperand::MO_VirtualRegister); 
203 }
204
205 inline MachineInstr*
206 Create3OperandInstr_UImmed(MachineOpCode opCode, Value* argVal1,
207                            unsigned int unextendedImmed, Value* argVal3)
208 {
209   MachineInstr* M = new MachineInstr(opCode);
210   M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, argVal1);
211   M->SetMachineOperandConst(1, MachineOperand::MO_UnextendedImmed,
212                                  unextendedImmed);
213   M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, argVal3);
214   return M;
215 }
216
217 inline MachineInstr*
218 Create3OperandInstr_SImmed(MachineOpCode opCode, Value* argVal1,
219                            int signExtendedImmed, Value* argVal3)
220 {
221   MachineInstr* M = new MachineInstr(opCode);
222   M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, argVal1);
223   M->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,
224                                  signExtendedImmed);
225   M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, argVal3);
226   return M;
227 }
228
229 inline MachineInstr*
230 Create3OperandInstr_Addr(MachineOpCode opCode, Value* argVal1,
231                          Value* label, Value* argVal3)
232 {
233   MachineInstr* M = new MachineInstr(opCode);
234   M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, argVal1);
235   M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,  label);
236   M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, argVal3);
237   return M;
238 }
239
240 inline MachineInstr*
241 Create3OperandInstr_Reg(MachineOpCode opCode, Value* argVal1,
242                         unsigned int regNum, Value* argVal3)
243 {
244   MachineInstr* M = new MachineInstr(opCode);
245   M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, argVal1);
246   M->SetMachineOperandReg(1, regNum);
247   M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, argVal3);
248   return M;
249 }
250
251 inline MachineInstr*
252 Create3OperandInstr_Reg(MachineOpCode opCode, unsigned int regNum1,
253                         unsigned int regNum2, Value* argVal3)
254                  
255 {
256   MachineInstr* M = new MachineInstr(opCode);
257   M->SetMachineOperandReg(0, regNum1);
258   M->SetMachineOperandReg(1, regNum2);
259   M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, argVal3);
260   return M;
261 }
262
263 inline MachineInstr*
264 Create3OperandInstr_Reg(MachineOpCode opCode, unsigned int regNum1,
265                         unsigned int regNum2, unsigned int regNum3)
266                  
267 {
268   MachineInstr* M = new MachineInstr(opCode);
269   M->SetMachineOperandReg(0, regNum1);
270   M->SetMachineOperandReg(1, regNum2);
271   M->SetMachineOperandReg(2, regNum3);
272   return M;
273 }
274
275
276 //---------------------------------------------------------------------------
277 // Function: ChooseRegOrImmed
278 // 
279 // Purpose:
280 // 
281 //---------------------------------------------------------------------------
282
283 MachineOperand::MachineOperandType ChooseRegOrImmed(
284                                          Value* val,
285                                          MachineOpCode opCode,
286                                          const TargetMachine& targetMachine,
287                                          bool canUseImmed,
288                                          unsigned int& getMachineRegNum,
289                                          int64_t& getImmedValue);
290
291
292 //---------------------------------------------------------------------------
293 // Function: FixConstantOperandsForInstr
294 // 
295 // Purpose:
296 // Special handling for constant operands of a machine instruction
297 // -- if the constant is 0, use the hardwired 0 register, if any;
298 // -- if the constant fits in the IMMEDIATE field, use that field;
299 // -- else create instructions to put the constant into a register, either
300 //    directly or by loading explicitly from the constant pool.
301 // 
302 // In the first 2 cases, the operand of `minstr' is modified in place.
303 // Returns a vector of machine instructions generated for operands that
304 // fall under case 3; these must be inserted before `minstr'.
305 //---------------------------------------------------------------------------
306
307 std::vector<MachineInstr*> FixConstantOperandsForInstr (Instruction* vmInstr,
308                                                         MachineInstr* minstr,
309                                                         TargetMachine& target);
310
311 #endif