blob: 95e8642a0d276ab1284cda3badb2b8c0a93e5717 [file] [log] [blame]
Chris Lattner72614082002-10-25 22:55:53 +00001//===-- X86/Printer.cpp - Convert X86 code to human readable rep. ---------===//
2//
3// This file contains a printer that converts from our internal representation
4// of LLVM code to a nice human readable form that is suitable for debuggging.
5//
6//===----------------------------------------------------------------------===//
7
8#include "X86.h"
Brian Gaeke6559bb92002-11-14 22:32:30 +00009#include "X86InstrInfo.h"
Brian Gaeke6559bb92002-11-14 22:32:30 +000010#include "llvm/Function.h"
Chris Lattnerb7089442003-01-13 00:35:03 +000011#include "llvm/Constant.h"
Brian Gaeke6559bb92002-11-14 22:32:30 +000012#include "llvm/Target/TargetMachine.h"
Chris Lattner0285a332002-12-28 20:25:38 +000013#include "llvm/CodeGen/MachineFunctionPass.h"
Chris Lattnerb7089442003-01-13 00:35:03 +000014#include "llvm/CodeGen/MachineConstantPool.h"
Chris Lattnerdbb61c62002-11-17 22:53:13 +000015#include "llvm/CodeGen/MachineInstr.h"
Chris Lattner233ad712002-11-21 01:33:44 +000016#include "Support/Statistic.h"
Chris Lattner72614082002-10-25 22:55:53 +000017
Chris Lattnerb4f68ed2002-10-29 22:37:54 +000018namespace {
Chris Lattner0285a332002-12-28 20:25:38 +000019 struct Printer : public MachineFunctionPass {
Chris Lattnerb4f68ed2002-10-29 22:37:54 +000020 std::ostream &O;
Chris Lattnerb7089442003-01-13 00:35:03 +000021 unsigned ConstIdx;
22 Printer(std::ostream &o) : O(o), ConstIdx(0) {}
Chris Lattnerb4f68ed2002-10-29 22:37:54 +000023
Chris Lattnerf0eb7be2002-12-15 21:13:40 +000024 virtual const char *getPassName() const {
25 return "X86 Assembly Printer";
26 }
27
Chris Lattnerb7089442003-01-13 00:35:03 +000028 void printConstantPool(MachineConstantPool *MCP, const TargetData &TD);
Chris Lattner0285a332002-12-28 20:25:38 +000029 bool runOnMachineFunction(MachineFunction &F);
Chris Lattnerb4f68ed2002-10-29 22:37:54 +000030 };
31}
32
Chris Lattnerdbb61c62002-11-17 22:53:13 +000033/// createX86CodePrinterPass - Print out the specified machine code function to
34/// the specified stream. This function should work regardless of whether or
35/// not the function is in SSA form or not.
36///
Chris Lattner0285a332002-12-28 20:25:38 +000037Pass *createX86CodePrinterPass(std::ostream &O) {
38 return new Printer(O);
Chris Lattnerdbb61c62002-11-17 22:53:13 +000039}
40
41
Chris Lattnerb7089442003-01-13 00:35:03 +000042// printConstantPool - Print out any constants which have been spilled to
43// memory...
44void Printer::printConstantPool(MachineConstantPool *MCP, const TargetData &TD){
45 const std::vector<Constant*> &CP = MCP->getConstants();
46 if (CP.empty()) return;
47
48 for (unsigned i = 0, e = CP.size(); i != e; ++i) {
49 O << "\t.section .rodata\n";
50 O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType()) << "\n";
51 O << ".CPI" << i+ConstIdx << ":\t\t\t\t\t;" << *CP[i] << "\n";
52 O << "\t*Constant output not implemented yet!*\n\n";
53 }
54 ConstIdx += CP.size(); // Don't recycle constant pool index numbers
55}
56
Brian Gaeke6559bb92002-11-14 22:32:30 +000057/// runOnFunction - This uses the X86InstructionInfo::print method
58/// to print assembly for each instruction.
Chris Lattner0285a332002-12-28 20:25:38 +000059bool Printer::runOnMachineFunction(MachineFunction &MF) {
60 static unsigned BBNumber = 0;
61 const TargetMachine &TM = MF.getTarget();
Chris Lattner3501fea2003-01-14 22:00:31 +000062 const TargetInstrInfo &TII = TM.getInstrInfo();
Brian Gaeke6559bb92002-11-14 22:32:30 +000063
Chris Lattnerb7089442003-01-13 00:35:03 +000064 // Print out constants referenced by the function
65 printConstantPool(MF.getConstantPool(), TM.getTargetData());
66
Brian Gaeke6559bb92002-11-14 22:32:30 +000067 // Print out labels for the function.
Chris Lattnerb7089442003-01-13 00:35:03 +000068 O << "\t.text\n";
69 O << "\t.align 16\n";
Chris Lattner0285a332002-12-28 20:25:38 +000070 O << "\t.globl\t" << MF.getFunction()->getName() << "\n";
71 O << "\t.type\t" << MF.getFunction()->getName() << ", @function\n";
72 O << MF.getFunction()->getName() << ":\n";
Brian Gaeke6559bb92002-11-14 22:32:30 +000073
74 // Print out code for the function.
Chris Lattner0285a332002-12-28 20:25:38 +000075 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
76 I != E; ++I) {
77 // Print a label for the basic block.
78 O << ".BB" << BBNumber++ << ":\n";
79 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
80 II != E; ++II) {
81 // Print the assembly for the instruction.
82 O << "\t";
Chris Lattner3501fea2003-01-14 22:00:31 +000083 TII.print(*II, O, TM);
Brian Gaeke6559bb92002-11-14 22:32:30 +000084 }
Chris Lattner0285a332002-12-28 20:25:38 +000085 }
Brian Gaeke6559bb92002-11-14 22:32:30 +000086
87 // We didn't modify anything.
Chris Lattnerb4f68ed2002-10-29 22:37:54 +000088 return false;
89}
90
Chris Lattner3d3067b2002-11-21 20:44:15 +000091static bool isScale(const MachineOperand &MO) {
Chris Lattnerd9096832002-12-15 08:01:39 +000092 return MO.isImmediate() &&
Chris Lattner3d3067b2002-11-21 20:44:15 +000093 (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 ||
94 MO.getImmedValue() == 4 || MO.getImmedValue() == 8);
95}
96
97static bool isMem(const MachineInstr *MI, unsigned Op) {
Chris Lattnerb7089442003-01-13 00:35:03 +000098 if (MI->getOperand(Op).isFrameIndex()) return true;
99 if (MI->getOperand(Op).isConstantPoolIndex()) return true;
Chris Lattner3d3067b2002-11-21 20:44:15 +0000100 return Op+4 <= MI->getNumOperands() &&
Chris Lattnerd9096832002-12-15 08:01:39 +0000101 MI->getOperand(Op ).isRegister() &&isScale(MI->getOperand(Op+1)) &&
102 MI->getOperand(Op+2).isRegister() &&MI->getOperand(Op+3).isImmediate();
Chris Lattner3d3067b2002-11-21 20:44:15 +0000103}
104
Chris Lattnerf9f60882002-11-18 06:56:51 +0000105static void printOp(std::ostream &O, const MachineOperand &MO,
106 const MRegisterInfo &RI) {
107 switch (MO.getType()) {
108 case MachineOperand::MO_VirtualRegister:
Chris Lattnerac573f62002-12-04 17:32:52 +0000109 if (Value *V = MO.getVRegValueOrNull()) {
Chris Lattnerdbf30f72002-12-04 06:45:19 +0000110 O << "<" << V->getName() << ">";
111 return;
112 }
Chris Lattnerb7089442003-01-13 00:35:03 +0000113 // FALLTHROUGH
Misha Brukmane1f0d812002-11-20 18:56:41 +0000114 case MachineOperand::MO_MachineRegister:
Chris Lattnerf9f60882002-11-18 06:56:51 +0000115 if (MO.getReg() < MRegisterInfo::FirstVirtualRegister)
116 O << RI.get(MO.getReg()).Name;
117 else
118 O << "%reg" << MO.getReg();
119 return;
Chris Lattner77875d82002-11-21 02:00:20 +0000120
121 case MachineOperand::MO_SignExtendedImmed:
122 case MachineOperand::MO_UnextendedImmed:
123 O << (int)MO.getImmedValue();
124 return;
Chris Lattnerf8bafe82002-12-01 23:25:59 +0000125 case MachineOperand::MO_PCRelativeDisp:
Chris Lattnerea1ddab2002-12-03 06:34:06 +0000126 O << "<" << MO.getVRegValue()->getName() << ">";
Chris Lattnerf8bafe82002-12-01 23:25:59 +0000127 return;
Chris Lattnerb7089442003-01-13 00:35:03 +0000128 case MachineOperand::MO_GlobalAddress:
129 O << "<" << MO.getGlobal()->getName() << ">";
130 return;
131 case MachineOperand::MO_ExternalSymbol:
132 O << "<" << MO.getSymbolName() << ">";
133 return;
Chris Lattnerf9f60882002-11-18 06:56:51 +0000134 default:
135 O << "<unknown op ty>"; return;
136 }
137}
138
Chris Lattner3501fea2003-01-14 22:00:31 +0000139static const std::string sizePtr(const TargetInstrDescriptor &Desc) {
Chris Lattnera0f38c82002-12-13 03:51:55 +0000140 switch (Desc.TSFlags & X86II::ArgMask) {
Chris Lattnereca1f632002-12-25 05:09:01 +0000141 default: assert(0 && "Unknown arg size!");
Chris Lattnera0f38c82002-12-13 03:51:55 +0000142 case X86II::Arg8: return "BYTE PTR";
143 case X86II::Arg16: return "WORD PTR";
144 case X86II::Arg32: return "DWORD PTR";
Chris Lattnerb7089442003-01-13 00:35:03 +0000145 case X86II::Arg64: return "QWORD PTR";
Chris Lattnereca1f632002-12-25 05:09:01 +0000146 case X86II::ArgF32: return "DWORD PTR";
147 case X86II::ArgF64: return "QWORD PTR";
148 case X86II::ArgF80: return "XWORD PTR";
Brian Gaeke86764d72002-12-05 08:30:40 +0000149 }
150}
151
Chris Lattner3d3067b2002-11-21 20:44:15 +0000152static void printMemReference(std::ostream &O, const MachineInstr *MI,
153 unsigned Op, const MRegisterInfo &RI) {
154 assert(isMem(MI, Op) && "Invalid memory reference!");
Chris Lattnerb7089442003-01-13 00:35:03 +0000155
156 if (MI->getOperand(Op).isFrameIndex()) {
157 O << "[frame slot #" << MI->getOperand(Op).getFrameIndex();
158 if (MI->getOperand(Op+3).getImmedValue())
159 O << " + " << MI->getOperand(Op+3).getImmedValue();
160 O << "]";
161 return;
162 } else if (MI->getOperand(Op).isConstantPoolIndex()) {
163 O << "[.CPI" << MI->getOperand(Op).getConstantPoolIndex();
164 if (MI->getOperand(Op+3).getImmedValue())
165 O << " + " << MI->getOperand(Op+3).getImmedValue();
166 O << "]";
167 return;
168 }
169
Chris Lattner3d3067b2002-11-21 20:44:15 +0000170 const MachineOperand &BaseReg = MI->getOperand(Op);
Chris Lattner0285a332002-12-28 20:25:38 +0000171 int ScaleVal = MI->getOperand(Op+1).getImmedValue();
Chris Lattner3d3067b2002-11-21 20:44:15 +0000172 const MachineOperand &IndexReg = MI->getOperand(Op+2);
Chris Lattner0285a332002-12-28 20:25:38 +0000173 int DispVal = MI->getOperand(Op+3).getImmedValue();
Chris Lattner3d3067b2002-11-21 20:44:15 +0000174
175 O << "[";
176 bool NeedPlus = false;
177 if (BaseReg.getReg()) {
178 printOp(O, BaseReg, RI);
179 NeedPlus = true;
180 }
181
182 if (IndexReg.getReg()) {
183 if (NeedPlus) O << " + ";
Chris Lattner0285a332002-12-28 20:25:38 +0000184 if (ScaleVal != 1)
185 O << ScaleVal << "*";
Chris Lattner3d3067b2002-11-21 20:44:15 +0000186 printOp(O, IndexReg, RI);
187 NeedPlus = true;
188 }
189
Chris Lattner0285a332002-12-28 20:25:38 +0000190 if (DispVal) {
191 if (NeedPlus)
192 if (DispVal > 0)
193 O << " + ";
194 else {
195 O << " - ";
196 DispVal = -DispVal;
197 }
198 O << DispVal;
Chris Lattner3d3067b2002-11-21 20:44:15 +0000199 }
200 O << "]";
201}
202
Chris Lattnerdbb61c62002-11-17 22:53:13 +0000203// print - Print out an x86 instruction in intel syntax
Chris Lattner927dd092002-11-17 23:20:37 +0000204void X86InstrInfo::print(const MachineInstr *MI, std::ostream &O,
205 const TargetMachine &TM) const {
Chris Lattnerf9f60882002-11-18 06:56:51 +0000206 unsigned Opcode = MI->getOpcode();
Chris Lattner3501fea2003-01-14 22:00:31 +0000207 const TargetInstrDescriptor &Desc = get(Opcode);
Chris Lattnerf9f60882002-11-18 06:56:51 +0000208
Chris Lattnereca1f632002-12-25 05:09:01 +0000209 switch (Desc.TSFlags & X86II::FormMask) {
210 case X86II::Pseudo:
211 if (Opcode == X86::PHI) {
212 printOp(O, MI->getOperand(0), RI);
213 O << " = phi ";
214 for (unsigned i = 1, e = MI->getNumOperands(); i != e; i+=2) {
215 if (i != 1) O << ", ";
216 O << "[";
217 printOp(O, MI->getOperand(i), RI);
218 O << ", ";
219 printOp(O, MI->getOperand(i+1), RI);
220 O << "]";
221 }
222 } else {
223 unsigned i = 0;
224 if (MI->getNumOperands() && MI->getOperand(0).opIsDef()) {
225 printOp(O, MI->getOperand(0), RI);
226 O << " = ";
227 ++i;
228 }
229 O << getName(MI->getOpcode());
230
231 for (unsigned e = MI->getNumOperands(); i != e; ++i) {
232 O << " ";
233 if (MI->getOperand(i).opIsDef()) O << "*";
234 printOp(O, MI->getOperand(i), RI);
235 if (MI->getOperand(i).opIsDef()) O << "*";
236 }
Chris Lattner3faae2d2002-12-13 09:59:26 +0000237 }
238 O << "\n";
239 return;
Chris Lattner3faae2d2002-12-13 09:59:26 +0000240
Chris Lattnerf9f60882002-11-18 06:56:51 +0000241 case X86II::RawFrm:
Chris Lattnerf8bafe82002-12-01 23:25:59 +0000242 // The accepted forms of Raw instructions are:
243 // 1. nop - No operand required
244 // 2. jmp foo - PC relative displacement operand
Chris Lattnerb7089442003-01-13 00:35:03 +0000245 // 3. call bar - GlobalAddress Operand or External Symbol Operand
Chris Lattnerf8bafe82002-12-01 23:25:59 +0000246 //
247 assert(MI->getNumOperands() == 0 ||
Chris Lattnerb7089442003-01-13 00:35:03 +0000248 (MI->getNumOperands() == 1 &&
249 (MI->getOperand(0).isPCRelativeDisp() ||
250 MI->getOperand(0).isGlobalAddress() ||
251 MI->getOperand(0).isExternalSymbol())) &&
Chris Lattnerf8bafe82002-12-01 23:25:59 +0000252 "Illegal raw instruction!");
Chris Lattnereca1f632002-12-25 05:09:01 +0000253 O << getName(MI->getOpcode()) << " ";
Chris Lattnerf9f60882002-11-18 06:56:51 +0000254
Chris Lattnerf8bafe82002-12-01 23:25:59 +0000255 if (MI->getNumOperands() == 1) {
256 printOp(O, MI->getOperand(0), RI);
Chris Lattnerf9f60882002-11-18 06:56:51 +0000257 }
258 O << "\n";
259 return;
260
Chris Lattner77875d82002-11-21 02:00:20 +0000261 case X86II::AddRegFrm: {
262 // There are currently two forms of acceptable AddRegFrm instructions.
263 // Either the instruction JUST takes a single register (like inc, dec, etc),
264 // or it takes a register and an immediate of the same size as the register
Chris Lattnerdbf30f72002-12-04 06:45:19 +0000265 // (move immediate f.e.). Note that this immediate value might be stored as
266 // an LLVM value, to represent, for example, loading the address of a global
Chris Lattnerfacc9fb2002-12-23 23:46:00 +0000267 // into a register. The initial register might be duplicated if this is a
268 // M_2_ADDR_REG instruction
Chris Lattner77875d82002-11-21 02:00:20 +0000269 //
Chris Lattnerd9096832002-12-15 08:01:39 +0000270 assert(MI->getOperand(0).isRegister() &&
Chris Lattner77875d82002-11-21 02:00:20 +0000271 (MI->getNumOperands() == 1 ||
Chris Lattnerdbf30f72002-12-04 06:45:19 +0000272 (MI->getNumOperands() == 2 &&
Chris Lattner6d669442002-12-04 17:28:40 +0000273 (MI->getOperand(1).getVRegValueOrNull() ||
Chris Lattnerfacc9fb2002-12-23 23:46:00 +0000274 MI->getOperand(1).isImmediate() ||
Chris Lattnerb7089442003-01-13 00:35:03 +0000275 MI->getOperand(1).isRegister() ||
276 MI->getOperand(1).isGlobalAddress() ||
277 MI->getOperand(1).isExternalSymbol()))) &&
Chris Lattner77875d82002-11-21 02:00:20 +0000278 "Illegal form for AddRegFrm instruction!");
Chris Lattnerf9f60882002-11-18 06:56:51 +0000279
Chris Lattner77875d82002-11-21 02:00:20 +0000280 unsigned Reg = MI->getOperand(0).getReg();
Chris Lattner77875d82002-11-21 02:00:20 +0000281
Chris Lattner77875d82002-11-21 02:00:20 +0000282 O << getName(MI->getOpCode()) << " ";
283 printOp(O, MI->getOperand(0), RI);
Chris Lattnerb7089442003-01-13 00:35:03 +0000284 if (MI->getNumOperands() == 2 &&
285 (!MI->getOperand(1).isRegister() ||
286 MI->getOperand(1).getVRegValueOrNull() ||
287 MI->getOperand(1).isGlobalAddress() ||
288 MI->getOperand(1).isExternalSymbol())) {
Chris Lattner77875d82002-11-21 02:00:20 +0000289 O << ", ";
Chris Lattner675dd2c2002-11-21 17:09:01 +0000290 printOp(O, MI->getOperand(1), RI);
Chris Lattner77875d82002-11-21 02:00:20 +0000291 }
292 O << "\n";
293 return;
294 }
Chris Lattner233ad712002-11-21 01:33:44 +0000295 case X86II::MRMDestReg: {
Chris Lattnerb7089442003-01-13 00:35:03 +0000296 // There are two acceptable forms of MRMDestReg instructions, those with 2,
297 // 3 and 4 operands:
298 //
299 // 2 Operands: this is for things like mov that do not read a second input
Chris Lattnerf9f60882002-11-18 06:56:51 +0000300 //
301 // 3 Operands: in this form, the first two registers (the destination, and
302 // the first operand) should be the same, post register allocation. The 3rd
303 // operand is an additional input. This should be for things like add
304 // instructions.
305 //
Chris Lattnerb7089442003-01-13 00:35:03 +0000306 // 4 Operands: This form is for instructions which are 3 operands forms, but
307 // have a constant argument as well.
Chris Lattnerf9f60882002-11-18 06:56:51 +0000308 //
Chris Lattnerb7089442003-01-13 00:35:03 +0000309 bool isTwoAddr = isTwoAddrInstr(Opcode);
Chris Lattnerd9096832002-12-15 08:01:39 +0000310 assert(MI->getOperand(0).isRegister() &&
Chris Lattnerb7089442003-01-13 00:35:03 +0000311 (MI->getNumOperands() == 2 ||
312 (isTwoAddr && MI->getOperand(1).isRegister() &&
313 MI->getOperand(0).getReg() == MI->getOperand(1).getReg() &&
314 (MI->getNumOperands() == 3 ||
315 (MI->getNumOperands() == 4 && MI->getOperand(3).isImmediate()))))
Misha Brukmane1f0d812002-11-20 18:56:41 +0000316 && "Bad format for MRMDestReg!");
Chris Lattnerf9f60882002-11-18 06:56:51 +0000317
Chris Lattnerf9f60882002-11-18 06:56:51 +0000318 O << getName(MI->getOpCode()) << " ";
319 printOp(O, MI->getOperand(0), RI);
320 O << ", ";
Chris Lattnerb7089442003-01-13 00:35:03 +0000321 printOp(O, MI->getOperand(1+isTwoAddr), RI);
322 if (MI->getNumOperands() == 4) {
323 O << ", ";
324 printOp(O, MI->getOperand(3), RI);
325 }
Chris Lattnerf9f60882002-11-18 06:56:51 +0000326 O << "\n";
327 return;
Chris Lattner233ad712002-11-21 01:33:44 +0000328 }
Chris Lattner18042332002-11-21 21:03:39 +0000329
330 case X86II::MRMDestMem: {
331 // These instructions are the same as MRMDestReg, but instead of having a
332 // register reference for the mod/rm field, it's a memory reference.
333 //
334 assert(isMem(MI, 0) && MI->getNumOperands() == 4+1 &&
Chris Lattnerd9096832002-12-15 08:01:39 +0000335 MI->getOperand(4).isRegister() && "Bad format for MRMDestMem!");
Chris Lattner18042332002-11-21 21:03:39 +0000336
Chris Lattnerb7089442003-01-13 00:35:03 +0000337 O << getName(MI->getOpCode()) << " " << sizePtr(Desc) << " ";
Chris Lattner18042332002-11-21 21:03:39 +0000338 printMemReference(O, MI, 0, RI);
339 O << ", ";
340 printOp(O, MI->getOperand(4), RI);
341 O << "\n";
342 return;
343 }
344
Chris Lattner233ad712002-11-21 01:33:44 +0000345 case X86II::MRMSrcReg: {
Chris Lattner644e1ab2002-11-21 00:30:01 +0000346 // There is a two forms that are acceptable for MRMSrcReg instructions,
347 // those with 3 and 2 operands:
348 //
349 // 3 Operands: in this form, the last register (the second input) is the
350 // ModR/M input. The first two operands should be the same, post register
351 // allocation. This is for things like: add r32, r/m32
352 //
353 // 2 Operands: this is for things like mov that do not read a second input
354 //
Chris Lattnerd9096832002-12-15 08:01:39 +0000355 assert(MI->getOperand(0).isRegister() &&
356 MI->getOperand(1).isRegister() &&
Chris Lattner644e1ab2002-11-21 00:30:01 +0000357 (MI->getNumOperands() == 2 ||
Chris Lattnerd9096832002-12-15 08:01:39 +0000358 (MI->getNumOperands() == 3 && MI->getOperand(2).isRegister()))
Chris Lattnerb7089442003-01-13 00:35:03 +0000359 && "Bad format for MRMSrcReg!");
Chris Lattner644e1ab2002-11-21 00:30:01 +0000360 if (MI->getNumOperands() == 3 &&
361 MI->getOperand(0).getReg() != MI->getOperand(1).getReg())
362 O << "**";
363
Chris Lattner644e1ab2002-11-21 00:30:01 +0000364 O << getName(MI->getOpCode()) << " ";
365 printOp(O, MI->getOperand(0), RI);
366 O << ", ";
367 printOp(O, MI->getOperand(MI->getNumOperands()-1), RI);
368 O << "\n";
369 return;
Chris Lattner233ad712002-11-21 01:33:44 +0000370 }
Chris Lattner675dd2c2002-11-21 17:09:01 +0000371
Chris Lattner3d3067b2002-11-21 20:44:15 +0000372 case X86II::MRMSrcMem: {
373 // These instructions are the same as MRMSrcReg, but instead of having a
374 // register reference for the mod/rm field, it's a memory reference.
Chris Lattner18042332002-11-21 21:03:39 +0000375 //
Chris Lattnerd9096832002-12-15 08:01:39 +0000376 assert(MI->getOperand(0).isRegister() &&
Chris Lattner3d3067b2002-11-21 20:44:15 +0000377 (MI->getNumOperands() == 1+4 && isMem(MI, 1)) ||
Chris Lattnerd9096832002-12-15 08:01:39 +0000378 (MI->getNumOperands() == 2+4 && MI->getOperand(1).isRegister() &&
Chris Lattner3d3067b2002-11-21 20:44:15 +0000379 isMem(MI, 2))
380 && "Bad format for MRMDestReg!");
381 if (MI->getNumOperands() == 2+4 &&
382 MI->getOperand(0).getReg() != MI->getOperand(1).getReg())
383 O << "**";
384
Chris Lattner3d3067b2002-11-21 20:44:15 +0000385 O << getName(MI->getOpCode()) << " ";
386 printOp(O, MI->getOperand(0), RI);
Chris Lattnerb7089442003-01-13 00:35:03 +0000387 O << ", " << sizePtr(Desc) << " ";
Chris Lattner3d3067b2002-11-21 20:44:15 +0000388 printMemReference(O, MI, MI->getNumOperands()-4, RI);
389 O << "\n";
390 return;
391 }
392
Chris Lattner675dd2c2002-11-21 17:09:01 +0000393 case X86II::MRMS0r: case X86II::MRMS1r:
394 case X86II::MRMS2r: case X86II::MRMS3r:
395 case X86II::MRMS4r: case X86II::MRMS5r:
396 case X86II::MRMS6r: case X86II::MRMS7r: {
Chris Lattner675dd2c2002-11-21 17:09:01 +0000397 // In this form, the following are valid formats:
398 // 1. sete r
Chris Lattner1d53ce42002-11-21 23:30:00 +0000399 // 2. cmp reg, immediate
Chris Lattner675dd2c2002-11-21 17:09:01 +0000400 // 2. shl rdest, rinput <implicit CL or 1>
401 // 3. sbb rdest, rinput, immediate [rdest = rinput]
402 //
403 assert(MI->getNumOperands() > 0 && MI->getNumOperands() < 4 &&
Chris Lattnerd9096832002-12-15 08:01:39 +0000404 MI->getOperand(0).isRegister() && "Bad MRMSxR format!");
Chris Lattner1d53ce42002-11-21 23:30:00 +0000405 assert((MI->getNumOperands() != 2 ||
Chris Lattnerd9096832002-12-15 08:01:39 +0000406 MI->getOperand(1).isRegister() || MI->getOperand(1).isImmediate())&&
Chris Lattner675dd2c2002-11-21 17:09:01 +0000407 "Bad MRMSxR format!");
Chris Lattner1d53ce42002-11-21 23:30:00 +0000408 assert((MI->getNumOperands() < 3 ||
Chris Lattnerd9096832002-12-15 08:01:39 +0000409 (MI->getOperand(1).isRegister() && MI->getOperand(2).isImmediate())) &&
Chris Lattner675dd2c2002-11-21 17:09:01 +0000410 "Bad MRMSxR format!");
411
Chris Lattnerd9096832002-12-15 08:01:39 +0000412 if (MI->getNumOperands() > 1 && MI->getOperand(1).isRegister() &&
Chris Lattner675dd2c2002-11-21 17:09:01 +0000413 MI->getOperand(0).getReg() != MI->getOperand(1).getReg())
414 O << "**";
415
Chris Lattner675dd2c2002-11-21 17:09:01 +0000416 O << getName(MI->getOpCode()) << " ";
417 printOp(O, MI->getOperand(0), RI);
Chris Lattnerd9096832002-12-15 08:01:39 +0000418 if (MI->getOperand(MI->getNumOperands()-1).isImmediate()) {
Chris Lattner675dd2c2002-11-21 17:09:01 +0000419 O << ", ";
Chris Lattner1d53ce42002-11-21 23:30:00 +0000420 printOp(O, MI->getOperand(MI->getNumOperands()-1), RI);
Chris Lattner675dd2c2002-11-21 17:09:01 +0000421 }
422 O << "\n";
423
424 return;
425 }
426
Chris Lattnerb7089442003-01-13 00:35:03 +0000427 case X86II::MRMS0m: case X86II::MRMS1m:
428 case X86II::MRMS2m: case X86II::MRMS3m:
429 case X86II::MRMS4m: case X86II::MRMS5m:
430 case X86II::MRMS6m: case X86II::MRMS7m: {
431 // In this form, the following are valid formats:
432 // 1. sete [m]
433 // 2. cmp [m], immediate
434 // 2. shl [m], rinput <implicit CL or 1>
435 // 3. sbb [m], immediate
436 //
437 assert(MI->getNumOperands() >= 4 && MI->getNumOperands() <= 5 &&
438 isMem(MI, 0) && "Bad MRMSxM format!");
439 assert((MI->getNumOperands() != 5 || MI->getOperand(4).isImmediate()) &&
440 "Bad MRMSxM format!");
441
442 O << getName(MI->getOpCode()) << " ";
443 O << sizePtr(Desc) << " ";
444 printMemReference(O, MI, 0, RI);
445 if (MI->getNumOperands() == 5) {
446 O << ", ";
447 printOp(O, MI->getOperand(4), RI);
448 }
449 O << "\n";
450 return;
451 }
452
Chris Lattnerf9f60882002-11-18 06:56:51 +0000453 default:
Chris Lattnerb7089442003-01-13 00:35:03 +0000454 O << "\tUNKNOWN FORM:\t\t-"; MI->print(O, TM); break;
Chris Lattnerf9f60882002-11-18 06:56:51 +0000455 }
Chris Lattner72614082002-10-25 22:55:53 +0000456}