Better interface to generating machine instr for common cases
[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_UImmed(MachineOpCode opCode,
119                            unsigned int unextendedImmed, Value* argVal2)
120 {
121   MachineInstr* M = new MachineInstr(opCode);
122   M->SetMachineOperandConst(0, MachineOperand::MO_UnextendedImmed,
123                                unextendedImmed);
124   M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, argVal2);
125   return M;
126 }
127
128 inline MachineInstr*
129 Create2OperandInstr_SImmed(MachineOpCode opCode,
130                            int signExtendedImmed, Value* argVal2)
131 {
132   MachineInstr* M = new MachineInstr(opCode);
133   M->SetMachineOperandConst(0, MachineOperand::MO_SignExtendedImmed,
134                                signExtendedImmed);
135   M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, argVal2);
136   return M;
137 }
138
139 inline MachineInstr*
140 Create3OperandInstr(MachineOpCode opCode,
141                     Value* argVal1, MachineOperand::MachineOperandType type1,
142                     Value* argVal2, MachineOperand::MachineOperandType type2,
143                     Value* argVal3, MachineOperand::MachineOperandType type3)
144 {
145   MachineInstr* M = new MachineInstr(opCode);
146   M->SetMachineOperandVal(0, type1, argVal1);
147   M->SetMachineOperandVal(1, type2, argVal2);
148   M->SetMachineOperandVal(2, type3, argVal3);
149   return M;
150 }
151
152 inline MachineInstr*
153 Create3OperandInstr(MachineOpCode opCode, Value* argVal1,
154                     Value* argVal2, Value* argVal3)
155 {
156   return Create3OperandInstr(opCode,
157                              argVal1, MachineOperand::MO_VirtualRegister, 
158                              argVal2, MachineOperand::MO_VirtualRegister, 
159                              argVal3, MachineOperand::MO_VirtualRegister); 
160 }
161
162 inline MachineInstr*
163 Create3OperandInstr_UImmed(MachineOpCode opCode, Value* argVal1,
164                            unsigned int unextendedImmed, Value* argVal3)
165 {
166   MachineInstr* M = new MachineInstr(opCode);
167   M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, argVal1);
168   M->SetMachineOperandConst(1, MachineOperand::MO_UnextendedImmed,
169                                  unextendedImmed);
170   M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, argVal3);
171   return M;
172 }
173
174 inline MachineInstr*
175 Create3OperandInstr_SImmed(MachineOpCode opCode, Value* argVal1,
176                            int signExtendedImmed, Value* argVal3)
177 {
178   MachineInstr* M = new MachineInstr(opCode);
179   M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, argVal1);
180   M->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,
181                                  signExtendedImmed);
182   M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, argVal3);
183   return M;
184 }
185
186 inline MachineInstr*
187 Create3OperandInstr_Reg(MachineOpCode opCode, Value* argVal1,
188                         unsigned int regNum, Value* argVal3)
189 {
190   MachineInstr* M = new MachineInstr(opCode);
191   M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, argVal1);
192   M->SetMachineOperandReg(1, regNum);
193   M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, argVal3);
194   return M;
195 }
196
197 inline MachineInstr*
198 Create3OperandInstr_Reg(MachineOpCode opCode, unsigned int regNum1,
199                         unsigned int regNum2, Value* argVal3)
200                  
201 {
202   MachineInstr* M = new MachineInstr(opCode);
203   M->SetMachineOperandReg(0, regNum1);
204   M->SetMachineOperandReg(1, regNum2);
205   M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, argVal3);
206   return M;
207 }
208
209 inline MachineInstr*
210 Create3OperandInstr_Reg(MachineOpCode opCode, unsigned int regNum1,
211                         unsigned int regNum2, unsigned int regNum3)
212                  
213 {
214   MachineInstr* M = new MachineInstr(opCode);
215   M->SetMachineOperandReg(0, regNum1);
216   M->SetMachineOperandReg(1, regNum2);
217   M->SetMachineOperandReg(2, regNum3);
218   return M;
219 }
220
221
222 //---------------------------------------------------------------------------
223 // Function: ChooseRegOrImmed
224 // 
225 // Purpose:
226 // 
227 //---------------------------------------------------------------------------
228
229 MachineOperand::MachineOperandType ChooseRegOrImmed(
230                                          Value* val,
231                                          MachineOpCode opCode,
232                                          const TargetMachine& targetMachine,
233                                          bool canUseImmed,
234                                          unsigned int& getMachineRegNum,
235                                          int64_t& getImmedValue);
236
237
238 //---------------------------------------------------------------------------
239 // Function: FixConstantOperandsForInstr
240 // 
241 // Purpose:
242 // Special handling for constant operands of a machine instruction
243 // -- if the constant is 0, use the hardwired 0 register, if any;
244 // -- if the constant fits in the IMMEDIATE field, use that field;
245 // -- else create instructions to put the constant into a register, either
246 //    directly or by loading explicitly from the constant pool.
247 // 
248 // In the first 2 cases, the operand of `minstr' is modified in place.
249 // Returns a vector of machine instructions generated for operands that
250 // fall under case 3; these must be inserted before `minstr'.
251 //---------------------------------------------------------------------------
252
253 std::vector<MachineInstr*> FixConstantOperandsForInstr (Instruction* vmInstr,
254                                                         MachineInstr* minstr,
255                                                         TargetMachine& target);
256
257 #endif