MachineInstr.cpp revision 93240fe6b1f79e9ccb271a214a01141f8c2c123a
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 operandType,
46				Value* _val, bool isdef=false)
47{
48  assert(i < operands.size());
49  operands[i].Initialize(operandType, _val);
50  operands[i].isDef = isdef ||
51    TargetInstrDescriptors[opCode].resultPos == (int) i;
52}
53
54void
55MachineInstr::SetMachineOperandConst(unsigned int i,
56				MachineOperand::MachineOperandType operandType,
57                                     int64_t intValue)
58{
59  assert(i < operands.size());
60  assert(TargetInstrDescriptors[opCode].resultPos != (int) i &&
61         "immed. constant cannot be defined");
62  operands[i].InitializeConst(operandType, intValue);
63  operands[i].isDef = false;
64}
65
66void
67MachineInstr::SetMachineOperandReg(unsigned int i,
68                                   int regNum,
69                                   bool isdef=false,
70                                   bool isCCReg=false)
71{
72  assert(i < operands.size());
73  operands[i].InitializeReg(regNum, isCCReg);
74  operands[i].isDef = isdef ||
75    TargetInstrDescriptors[opCode].resultPos == (int) i;
76}
77
78void
79MachineInstr::dump(unsigned int indent) const
80{
81  for (unsigned i=0; i < indent; i++)
82    cerr << "    ";
83
84  cerr << *this;
85}
86
87static inline std::ostream &OutputValue(std::ostream &os,
88                                        const Value* val)
89{
90  os << "(val ";
91  if (val && val->hasName())
92    return os << val->getName();
93  else
94    return os << (void*) val;              // print address only
95  os << ")";
96}
97
98std::ostream &operator<<(std::ostream& os, const MachineInstr& minstr)
99{
100  os << TargetInstrDescriptors[minstr.opCode].opCodeString;
101
102  for (unsigned i=0, N=minstr.getNumOperands(); i < N; i++) {
103    os << "\t" << minstr.getOperand(i);
104    if( minstr.getOperand(i).opIsDef() )
105      os << "*";
106  }
107
108  // code for printing implict references
109  unsigned NumOfImpRefs =  minstr.getNumImplicitRefs();
110  if(  NumOfImpRefs > 0 ) {
111    os << "\tImplicit: ";
112    for(unsigned z=0; z < NumOfImpRefs; z++) {
113      OutputValue(os, minstr.getImplicitRef(z));
114      if( minstr.implicitRefIsDefined(z)) os << "*";
115      os << "\t";
116    }
117  }
118
119  return os << "\n";
120}
121
122static inline std::ostream &OutputOperand(std::ostream &os,
123                                          const MachineOperand &mop)
124{
125  Value* val;
126  switch (mop.getOperandType())
127    {
128    case MachineOperand::MO_CCRegister:
129    case MachineOperand::MO_VirtualRegister:
130      return OutputValue(os, mop.getVRegValue());
131    case MachineOperand::MO_MachineRegister:
132      return os << "(" << mop.getMachineRegNum() << ")";
133    default:
134      assert(0 && "Unknown operand type");
135      return os;
136    }
137}
138
139
140std::ostream &operator<<(std::ostream &os, const MachineOperand &mop)
141{
142  switch(mop.opType)
143    {
144    case MachineOperand::MO_VirtualRegister:
145    case MachineOperand::MO_MachineRegister:
146      os << "%reg";
147      return OutputOperand(os, mop);
148    case MachineOperand::MO_CCRegister:
149      os << "%ccreg";
150      return OutputOperand(os, mop);
151    case MachineOperand::MO_SignExtendedImmed:
152      return os << (long)mop.immedVal;
153    case MachineOperand::MO_UnextendedImmed:
154      return os << (long)mop.immedVal;
155    case MachineOperand::MO_PCRelativeDisp:
156      {
157        const Value* opVal = mop.getVRegValue();
158        bool isLabel = isa<Function>(opVal) || isa<BasicBlock>(opVal);
159        os << "%disp(" << (isLabel? "label " : "addr-of-val ");
160        if (opVal->hasName())
161          os << opVal->getName();
162        else
163          os << opVal;
164        return os << ")";
165      }
166    default:
167      assert(0 && "Unrecognized operand type");
168      break;
169    }
170
171  return os;
172}
173