MachineInstr.cpp revision 7a4be9580e095ca4bffd16ec6ec4882f6270fb09
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/Value.h"
17#include <iostream>
18using std::cerr;
19
20
21//************************ Class Implementations **************************/
22
23// Constructor for instructions with fixed #operands (nearly all)
24MachineInstr::MachineInstr(MachineOpCode _opCode,
25			   OpCodeMask    _opCodeMask)
26  : opCode(_opCode),
27    opCodeMask(_opCodeMask),
28    operands(TargetInstrDescriptors[_opCode].numOperands)
29{
30  assert(TargetInstrDescriptors[_opCode].numOperands >= 0);
31}
32
33// Constructor for instructions with variable #operands
34MachineInstr::MachineInstr(MachineOpCode _opCode,
35			   unsigned	 numOperands,
36			   OpCodeMask    _opCodeMask)
37  : opCode(_opCode),
38    opCodeMask(_opCodeMask),
39    operands(numOperands)
40{
41}
42
43void
44MachineInstr::SetMachineOperandVal(unsigned int i,
45                                   MachineOperand::MachineOperandType opType,
46                                   Value* _val,
47                                   bool isdef=false,
48                                   bool isDefAndUse=false)
49{
50  assert(i < operands.size());
51  operands[i].Initialize(opType, _val);
52  operands[i].isDef = isdef ||
53    TargetInstrDescriptors[opCode].resultPos == (int) i;
54  operands[i].isDefAndUse = isDefAndUse;
55}
56
57void
58MachineInstr::SetMachineOperandConst(unsigned int i,
59				MachineOperand::MachineOperandType operandType,
60                                     int64_t intValue)
61{
62  assert(i < operands.size());
63  assert(TargetInstrDescriptors[opCode].resultPos != (int) i &&
64         "immed. constant cannot be defined");
65  operands[i].InitializeConst(operandType, intValue);
66  operands[i].isDef = false;
67  operands[i].isDefAndUse = false;
68}
69
70void
71MachineInstr::SetMachineOperandReg(unsigned int i,
72                                   int regNum,
73                                   bool isdef=false,
74                                   bool isDefAndUse=false,
75                                   bool isCCReg=false)
76{
77  assert(i < operands.size());
78  operands[i].InitializeReg(regNum, isCCReg);
79  operands[i].isDef = isdef ||
80    TargetInstrDescriptors[opCode].resultPos == (int) i;
81  operands[i].isDefAndUse = isDefAndUse;
82  regsUsed.insert(regNum);
83}
84
85void
86MachineInstr::SetRegForOperand(unsigned i, int regNum)
87{
88  operands[i].setRegForValue(regNum);
89  regsUsed.insert(regNum);
90}
91
92
93void
94MachineInstr::dump() const
95{
96  cerr << "  " << *this;
97}
98
99static inline std::ostream &OutputValue(std::ostream &os,
100                                        const Value* val)
101{
102  os << "(val ";
103  if (val && val->hasName())
104    return os << val->getName();
105  else
106    return os << (void*) val;              // print address only
107  os << ")";
108}
109
110std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr)
111{
112  os << TargetInstrDescriptors[minstr.opCode].opCodeString;
113
114  for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) {
115    os << "\t" << minstr.getOperand(i);
116    if( minstr.operandIsDefined(i) )
117      os << "*";
118    if( minstr.operandIsDefinedAndUsed(i) )
119      os << "*";
120  }
121
122  // code for printing implict references
123  unsigned NumOfImpRefs =  minstr.getNumImplicitRefs();
124  if(  NumOfImpRefs > 0 ) {
125    os << "\tImplicit: ";
126    for(unsigned z=0; z < NumOfImpRefs; z++) {
127      OutputValue(os, minstr.getImplicitRef(z));
128      if( minstr.implicitRefIsDefined(z)) os << "*";
129      if( minstr.implicitRefIsDefinedAndUsed(z)) os << "*";
130      os << "\t";
131    }
132  }
133
134  return os << "\n";
135}
136
137static inline std::ostream &OutputOperand(std::ostream &os,
138                                          const MachineOperand &mop)
139{
140  Value* val;
141  switch (mop.getOperandType())
142    {
143    case MachineOperand::MO_CCRegister:
144    case MachineOperand::MO_VirtualRegister:
145      return OutputValue(os, mop.getVRegValue());
146    case MachineOperand::MO_MachineRegister:
147      return os << "(" << mop.getMachineRegNum() << ")";
148    default:
149      assert(0 && "Unknown operand type");
150      return os;
151    }
152}
153
154std::ostream &operator<<(std::ostream &os, const MachineOperand &mop)
155{
156  switch(mop.opType)
157    {
158    case MachineOperand::MO_VirtualRegister:
159    case MachineOperand::MO_MachineRegister:
160      os << "%reg";
161      return OutputOperand(os, mop);
162    case MachineOperand::MO_CCRegister:
163      os << "%ccreg";
164      return OutputOperand(os, mop);
165    case MachineOperand::MO_SignExtendedImmed:
166      return os << (long)mop.immedVal;
167    case MachineOperand::MO_UnextendedImmed:
168      return os << (long)mop.immedVal;
169    case MachineOperand::MO_PCRelativeDisp:
170      {
171        const Value* opVal = mop.getVRegValue();
172        bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
173        os << "%disp(" << (isLabel? "label " : "addr-of-val ");
174        if (opVal->hasName())
175          os << opVal->getName();
176        else
177          os << (const void*) opVal;
178        return os << ")";
179      }
180    default:
181      assert(0 && "Unrecognized operand type");
182      break;
183    }
184
185  return os;
186}
187