Changed SetMachineOpernad calls in Set3OperandsFromInstr so that the
[oota-llvm.git] / lib / CodeGen / MachineInstr.cpp
1 // $Id$
2 //***************************************************************************
3 // File:
4 //      MachineInstr.cpp
5 // 
6 // Purpose:
7 //      
8 // 
9 // Strategy:
10 // 
11 // History:
12 //      7/2/01   -  Vikram Adve  -  Created
13 //**************************************************************************/
14
15 #include "llvm/CodeGen/MachineInstr.h"
16 #include "llvm/ConstPoolVals.h"
17 #include "llvm/Instruction.h"
18 #include <strstream>
19
20 //************************ Class Implementations **************************/
21
22 // Constructor for instructions with fixed #operands (nearly all)
23 MachineInstr::MachineInstr(MachineOpCode _opCode,
24                            OpCodeMask    _opCodeMask)
25   : opCode(_opCode),
26     opCodeMask(_opCodeMask),
27     operands(TargetInstrDescriptors[_opCode].numOperands)
28 {
29   assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
30 }
31
32 // Constructor for instructions with variable #operands
33 MachineInstr::MachineInstr(MachineOpCode _opCode,
34                            unsigned      numOperands,
35                            OpCodeMask    _opCodeMask)
36   : opCode(_opCode),
37     opCodeMask(_opCodeMask),
38     operands(numOperands)
39 {
40 }
41
42 void
43 MachineInstr::SetMachineOperand(unsigned int i,
44                                 MachineOperand::MachineOperandType operandType,
45                                 Value* _val, bool isdef=false)
46 {
47   assert(i < operands.size());
48   operands[i].Initialize(operandType, _val);
49   operands[i].isDef = isdef;
50 }
51
52 void
53 MachineInstr::SetMachineOperand(unsigned int i,
54                                 MachineOperand::MachineOperandType operandType,
55                                 int64_t intValue, bool isdef=false)
56 {
57   assert(i < operands.size());
58   operands[i].InitializeConst(operandType, intValue);
59   operands[i].isDef = isdef;
60 }
61
62 void
63 MachineInstr::SetMachineOperand(unsigned int i,
64                                 unsigned int regNum, bool isdef=false)
65 {
66   assert(i < operands.size());
67   operands[i].InitializeReg(regNum);
68   operands[i].isDef = isdef;
69 }
70
71 void
72 MachineInstr::dump(unsigned int indent) const 
73 {
74   for (unsigned i=0; i < indent; i++)
75     cout << "    ";
76   
77   cout << *this;
78 }
79
80 ostream&
81 operator<< (ostream& os, const MachineInstr& minstr)
82 {
83   os << TargetInstrDescriptors[minstr.opCode].opCodeString;
84   
85   for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++)
86     os << "\t" << minstr.getOperand(i);
87   
88 #undef DEBUG_VAL_OP_ITERATOR
89 #ifdef DEBUG_VAL_OP_ITERATOR
90   os << endl << "\tValue operands are: ";
91   for (MachineInstr::val_op_const_iterator vo(&minstr); ! vo.done(); ++vo)
92     {
93       const Value* val = *vo;
94       os << val << (vo.isDef()? "(def), " : ", ");
95     }
96   os << endl;
97 #endif
98   
99   return os;
100 }
101
102 ostream&
103 operator<< (ostream& os, const MachineOperand& mop)
104 {
105   strstream regInfo;
106   if (mop.opType == MachineOperand::MO_VirtualRegister)
107     regInfo << "(val " << mop.value << ")" << ends;
108   else if (mop.opType == MachineOperand::MO_MachineRegister)
109     regInfo << "("       << mop.regNum << ")" << ends;
110   else if (mop.opType == MachineOperand::MO_CCRegister)
111     regInfo << "(val " << mop.value << ")" << ends;
112   
113   switch(mop.opType)
114     {
115     case MachineOperand::MO_VirtualRegister:
116     case MachineOperand::MO_MachineRegister:
117       os << "%reg" << regInfo.str();
118       free(regInfo.str());
119       break;
120       
121     case MachineOperand::MO_CCRegister:
122       os << "%ccreg" << regInfo.str();
123       free(regInfo.str());
124       break;
125
126     case MachineOperand::MO_SignExtendedImmed:
127       os << mop.immedVal;
128       break;
129
130     case MachineOperand::MO_UnextendedImmed:
131       os << mop.immedVal;
132       break;
133
134     case MachineOperand::MO_PCRelativeDisp:
135       os << "%disp(label " << mop.value << ")";
136       break;
137
138     default:
139       assert(0 && "Unrecognized operand type");
140       break;
141     }
142
143   return os;
144 }
145
146
147 //---------------------------------------------------------------------------
148 // Target-independent utility routines for creating machine instructions
149 //---------------------------------------------------------------------------
150
151
152 //------------------------------------------------------------------------ 
153 // Function Set2OperandsFromInstr
154 // Function Set3OperandsFromInstr
155 // 
156 // For the common case of 2- and 3-operand arithmetic/logical instructions,
157 // set the m/c instr. operands directly from the VM instruction's operands.
158 // Check whether the first or second operand is 0 and can use a dedicated "0" register.
159 // Check whether the second operand should use an immediate field or register.
160 // (First and third operands are never immediates for such instructions.)
161 // 
162 // Arguments:
163 // canDiscardResult: Specifies that the result operand can be discarded
164 //                   by using the dedicated "0"
165 // 
166 // op1position, op2position and resultPosition: Specify in which position
167 //                   in the machine instruction the 3 operands (arg1, arg2
168 //                   and result) should go.
169 // 
170 // RETURN VALUE: unsigned int flags, where
171 //      flags & 0x01    => operand 1 is constant and needs a register
172 //      flags & 0x02    => operand 2 is constant and needs a register
173 //------------------------------------------------------------------------ 
174
175 void
176 Set2OperandsFromInstr(MachineInstr* minstr,
177                       InstructionNode* vmInstrNode,
178                       const TargetMachine& target,
179                       bool canDiscardResult,
180                       int op1Position,
181                       int resultPosition)
182 {
183   Set3OperandsFromInstr(minstr, vmInstrNode, target,
184                         canDiscardResult, op1Position,
185                         /*op2Position*/ -1, resultPosition);
186 }
187
188 #undef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
189 #ifdef REVERT_TO_EXPLICIT_CONSTANT_CHECKS
190 unsigned
191 Set3OperandsFromInstrJUNK(MachineInstr* minstr,
192                       InstructionNode* vmInstrNode,
193                       const TargetMachine& target,
194                       bool canDiscardResult,
195                       int op1Position,
196                       int op2Position,
197                       int resultPosition)
198 {
199   assert(op1Position >= 0);
200   assert(resultPosition >= 0);
201   
202   unsigned returnFlags = 0x0;
203   
204   // Check if operand 1 is 0 and if so, try to use the register that gives 0, if any.
205   Value* op1Value = vmInstrNode->leftChild()->getValue();
206   bool isValidConstant;
207   int64_t intValue = GetConstantValueAsSignedInt(op1Value, isValidConstant);
208   if (isValidConstant && intValue == 0 && target.zeroRegNum >= 0)
209     minstr->SetMachineOperand(op1Position, /*regNum*/ target.zeroRegNum);
210   else
211     {
212       if (op1Value->getValueType() == Value::ConstantVal)
213         {// value is constant and must be loaded from constant pool
214           returnFlags = returnFlags | (1 << op1Position);
215         }
216       minstr->SetMachineOperand(op1Position,MachineOperand::MO_VirtualRegister,
217                                             op1Value);
218     }
219   
220   // Check if operand 2 (if any) fits in the immediate field of the instruction,
221   // of if it is 0 and can use a dedicated machine register
222   if (op2Position >= 0)
223     {
224       Value* op2Value = vmInstrNode->rightChild()->getValue();
225       int64_t immedValue;
226       unsigned int machineRegNum;
227       
228       MachineOperand::MachineOperandType
229         op2type = ChooseRegOrImmed(op2Value, minstr->getOpCode(), target,
230                                    /*canUseImmed*/ true,
231                                    machineRegNum, immedValue);
232       
233       if (op2type == MachineOperand::MO_MachineRegister)
234         minstr->SetMachineOperand(op2Position, machineRegNum);
235       else if (op2type == MachineOperand::MO_VirtualRegister)
236         {
237           if (op2Value->getValueType() == Value::ConstantVal)
238             {// value is constant and must be loaded from constant pool
239               returnFlags = returnFlags | (1 << op2Position);
240             }
241           minstr->SetMachineOperand(op2Position, op2type, op2Value);
242         }
243       else
244         {
245           assert(op2type != MO_CCRegister);
246           minstr->SetMachineOperand(op2Position, op2type, immedValue);
247         }
248     }
249   
250   // If operand 3 (result) can be discarded, use a dead register if one exists
251   if (canDiscardResult && target.zeroRegNum >= 0)
252     minstr->SetMachineOperand(resultPosition, target.zeroRegNum, true);
253   else
254     minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue(), true);
255
256   return returnFlags;
257 }
258 #endif
259
260
261 void
262 Set3OperandsFromInstr(MachineInstr* minstr,
263                       InstructionNode* vmInstrNode,
264                       const TargetMachine& target,
265                       bool canDiscardResult,
266                       int op1Position,
267                       int op2Position,
268                       int resultPosition)
269 {
270   assert(op1Position >= 0);
271   assert(resultPosition >= 0);
272   
273   // operand 1
274   minstr->SetMachineOperand(op1Position, MachineOperand::MO_VirtualRegister,
275                             vmInstrNode->leftChild()->getValue());   
276   
277   // operand 2 (if any)
278   if (op2Position >= 0)
279     minstr->SetMachineOperand(op2Position, MachineOperand::MO_VirtualRegister,
280                               vmInstrNode->rightChild()->getValue());   
281   
282   // result operand: if it can be discarded, use a dead register if one exists
283   if (canDiscardResult && target.zeroRegNum >= 0)
284     minstr->SetMachineOperand(resultPosition, target.zeroRegNum, true);
285   else
286     minstr->SetMachineOperand(resultPosition, MachineOperand::MO_VirtualRegister, vmInstrNode->getValue(), true);
287 }
288
289
290 MachineOperand::MachineOperandType
291 ChooseRegOrImmed(Value* val,
292                  MachineOpCode opCode,
293                  const TargetMachine& target,
294                  bool canUseImmed,
295                  unsigned int& getMachineRegNum,
296                  int64_t& getImmedValue)
297 {
298   MachineOperand::MachineOperandType opType =
299     MachineOperand::MO_VirtualRegister;
300   getMachineRegNum = 0;
301   getImmedValue = 0;
302   
303   // Check for the common case first: argument is not constant
304   // 
305   if (val->getValueType() != Value::ConstantVal)
306     return opType;
307   
308   // Now get the constant value and check if it fits in the IMMED field.
309   // Take advantage of the fact that the max unsigned value will rarely
310   // fit into any IMMED field and ignore that case (i.e., cast smaller
311   // unsigned constants to signed).
312   // 
313   bool isValidConstant;
314   int64_t intValue = GetConstantValueAsSignedInt(val, isValidConstant);
315   
316   if (isValidConstant)
317     {
318       if (intValue == 0 && target.zeroRegNum >= 0)
319         {
320           opType = MachineOperand::MO_MachineRegister;
321           getMachineRegNum = target.zeroRegNum;
322         }
323       else if (canUseImmed &&
324                target.getInstrInfo().constantFitsInImmedField(opCode,intValue))
325         {
326           opType = MachineOperand::MO_SignExtendedImmed;
327           getImmedValue = intValue;
328         }
329     }
330   
331   return opType;
332 }