Chad Rosier | 095e1cd | 2012-10-03 19:00:20 +0000 | [diff] [blame] | 1 | //===-- X86IntelInstPrinter.cpp - Intel assembly instruction printing -----===// |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 2 | // |
Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
Chad Rosier | 095e1cd | 2012-10-03 19:00:20 +0000 | [diff] [blame] | 9 | // This file includes code for rendering MCInst instances as Intel-style |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 10 | // assembly. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 14 | #include "X86IntelInstPrinter.h" |
Michael Liao | 425c0db | 2012-09-26 05:13:44 +0000 | [diff] [blame] | 15 | #include "MCTargetDesc/X86BaseInfo.h" |
Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 16 | #include "X86InstComments.h" |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 17 | #include "llvm/MC/MCExpr.h" |
Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 18 | #include "llvm/MC/MCInst.h" |
Eugene Zelenko | 90562df | 2017-02-06 21:55:43 +0000 | [diff] [blame] | 19 | #include "llvm/MC/MCInstrDesc.h" |
Craig Topper | dab9e35 | 2012-04-02 07:01:04 +0000 | [diff] [blame] | 20 | #include "llvm/MC/MCInstrInfo.h" |
Craig Topper | e33ed7d6 | 2018-04-22 00:52:02 +0000 | [diff] [blame] | 21 | #include "llvm/MC/MCSubtargetInfo.h" |
Eugene Zelenko | 90562df | 2017-02-06 21:55:43 +0000 | [diff] [blame] | 22 | #include "llvm/Support/Casting.h" |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 23 | #include "llvm/Support/ErrorHandling.h" |
Eugene Zelenko | 90562df | 2017-02-06 21:55:43 +0000 | [diff] [blame] | 24 | #include <cassert> |
| 25 | #include <cstdint> |
| 26 | |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 27 | using namespace llvm; |
| 28 | |
Chandler Carruth | 84e68b2 | 2014-04-22 02:41:26 +0000 | [diff] [blame] | 29 | #define DEBUG_TYPE "asm-printer" |
| 30 | |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 31 | #include "X86GenAsmWriter1.inc" |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 32 | |
Rafael Espindola | d686052 | 2011-06-02 02:34:55 +0000 | [diff] [blame] | 33 | void X86IntelInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { |
| 34 | OS << getRegisterName(RegNo); |
Rafael Espindola | 08600bc | 2011-05-30 20:20:15 +0000 | [diff] [blame] | 35 | } |
| 36 | |
Owen Anderson | a0c3b97 | 2011-09-15 23:38:46 +0000 | [diff] [blame] | 37 | void X86IntelInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, |
Akira Hatanaka | b46d023 | 2015-03-27 20:36:02 +0000 | [diff] [blame] | 38 | StringRef Annot, |
| 39 | const MCSubtargetInfo &STI) { |
Gabor Buella | 349ffce | 2018-06-05 10:41:39 +0000 | [diff] [blame] | 40 | printInstFlags(MI, OS); |
Oren Ben Simhon | fdd72fd | 2018-03-17 13:29:46 +0000 | [diff] [blame] | 41 | |
Craig Topper | e33ed7d6 | 2018-04-22 00:52:02 +0000 | [diff] [blame] | 42 | // In 16-bit mode, print data16 as data32. |
| 43 | if (MI->getOpcode() == X86::DATA16_PREFIX && |
| 44 | STI.getFeatureBits()[X86::Mode16Bit]) { |
| 45 | OS << "\tdata32"; |
| 46 | } else |
| 47 | printInstruction(MI, OS); |
Kevin Enderby | 6fbcd8d | 2012-02-23 18:18:17 +0000 | [diff] [blame] | 48 | |
| 49 | // Next always print the annotation. |
| 50 | printAnnotation(OS, Annot); |
| 51 | |
Chris Lattner | 7a05e6d | 2010-08-28 20:42:31 +0000 | [diff] [blame] | 52 | // If verbose assembly is enabled, we can print some informative comments. |
Kevin Enderby | 6fbcd8d | 2012-02-23 18:18:17 +0000 | [diff] [blame] | 53 | if (CommentStream) |
Craig Topper | a21758f | 2018-03-29 04:14:04 +0000 | [diff] [blame] | 54 | EmitAnyX86InstComments(MI, *CommentStream, MII); |
Chris Lattner | 76c564b | 2010-04-04 04:47:45 +0000 | [diff] [blame] | 55 | } |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 56 | |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 57 | void X86IntelInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, |
Chris Lattner | 76c564b | 2010-04-04 04:47:45 +0000 | [diff] [blame] | 58 | raw_ostream &O) { |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 59 | const MCOperand &Op = MI->getOperand(OpNo); |
| 60 | if (Op.isReg()) { |
Craig Topper | efd67d4 | 2013-07-31 02:47:52 +0000 | [diff] [blame] | 61 | printRegName(O, Op.getReg()); |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 62 | } else if (Op.isImm()) { |
Daniel Malea | a3d4245 | 2013-08-01 21:18:16 +0000 | [diff] [blame] | 63 | O << formatImm((int64_t)Op.getImm()); |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 64 | } else { |
| 65 | assert(Op.isExpr() && "unknown operand kind in printOperand"); |
Konstantin Belochapka | 741099b | 2017-09-25 19:26:48 +0000 | [diff] [blame] | 66 | O << "offset "; |
Matt Arsenault | 8b64355 | 2015-06-09 00:31:39 +0000 | [diff] [blame] | 67 | Op.getExpr()->print(O, &MAI); |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 68 | } |
| 69 | } |
| 70 | |
Chris Lattner | f469307 | 2010-07-08 23:46:44 +0000 | [diff] [blame] | 71 | void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op, |
| 72 | raw_ostream &O) { |
Manuel Jacob | dcb78db | 2014-03-18 16:14:11 +0000 | [diff] [blame] | 73 | const MCOperand &BaseReg = MI->getOperand(Op+X86::AddrBaseReg); |
| 74 | unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm(); |
| 75 | const MCOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg); |
| 76 | const MCOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp); |
Michael Liao | 5bf9578 | 2014-12-04 05:20:33 +0000 | [diff] [blame] | 77 | |
Chris Lattner | f469307 | 2010-07-08 23:46:44 +0000 | [diff] [blame] | 78 | // If this has a segment register, print it. |
Gabor Buella | 349ffce | 2018-06-05 10:41:39 +0000 | [diff] [blame] | 79 | printOptionalSegReg(MI, Op + X86::AddrSegmentReg, O); |
Michael Liao | 5bf9578 | 2014-12-04 05:20:33 +0000 | [diff] [blame] | 80 | |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 81 | O << '['; |
Michael Liao | 5bf9578 | 2014-12-04 05:20:33 +0000 | [diff] [blame] | 82 | |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 83 | bool NeedPlus = false; |
| 84 | if (BaseReg.getReg()) { |
Manuel Jacob | dcb78db | 2014-03-18 16:14:11 +0000 | [diff] [blame] | 85 | printOperand(MI, Op+X86::AddrBaseReg, O); |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 86 | NeedPlus = true; |
| 87 | } |
Michael Liao | 5bf9578 | 2014-12-04 05:20:33 +0000 | [diff] [blame] | 88 | |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 89 | if (IndexReg.getReg()) { |
| 90 | if (NeedPlus) O << " + "; |
| 91 | if (ScaleVal != 1) |
| 92 | O << ScaleVal << '*'; |
Manuel Jacob | dcb78db | 2014-03-18 16:14:11 +0000 | [diff] [blame] | 93 | printOperand(MI, Op+X86::AddrIndexReg, O); |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 94 | NeedPlus = true; |
| 95 | } |
Chad Rosier | 095e1cd | 2012-10-03 19:00:20 +0000 | [diff] [blame] | 96 | |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 97 | if (!DispSpec.isImm()) { |
| 98 | if (NeedPlus) O << " + "; |
| 99 | assert(DispSpec.isExpr() && "non-immediate displacement for LEA?"); |
Matt Arsenault | 8b64355 | 2015-06-09 00:31:39 +0000 | [diff] [blame] | 100 | DispSpec.getExpr()->print(O, &MAI); |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 101 | } else { |
| 102 | int64_t DispVal = DispSpec.getImm(); |
| 103 | if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) { |
| 104 | if (NeedPlus) { |
| 105 | if (DispVal > 0) |
| 106 | O << " + "; |
| 107 | else { |
| 108 | O << " - "; |
| 109 | DispVal = -DispVal; |
| 110 | } |
| 111 | } |
Daniel Malea | a3d4245 | 2013-08-01 21:18:16 +0000 | [diff] [blame] | 112 | O << formatImm(DispVal); |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 113 | } |
| 114 | } |
Michael Liao | 5bf9578 | 2014-12-04 05:20:33 +0000 | [diff] [blame] | 115 | |
Chris Lattner | 4479034 | 2009-09-20 07:17:49 +0000 | [diff] [blame] | 116 | O << ']'; |
| 117 | } |
Craig Topper | 1885417 | 2013-08-25 22:23:38 +0000 | [diff] [blame] | 118 | |
David Woodhouse | 2ef8d9c | 2014-01-22 15:08:08 +0000 | [diff] [blame] | 119 | void X86IntelInstPrinter::printSrcIdx(const MCInst *MI, unsigned Op, |
| 120 | raw_ostream &O) { |
David Woodhouse | 2ef8d9c | 2014-01-22 15:08:08 +0000 | [diff] [blame] | 121 | // If this has a segment register, print it. |
Gabor Buella | 349ffce | 2018-06-05 10:41:39 +0000 | [diff] [blame] | 122 | printOptionalSegReg(MI, Op + 1, O); |
David Woodhouse | 2ef8d9c | 2014-01-22 15:08:08 +0000 | [diff] [blame] | 123 | O << '['; |
| 124 | printOperand(MI, Op, O); |
| 125 | O << ']'; |
| 126 | } |
| 127 | |
David Woodhouse | b33c2ef | 2014-01-22 15:08:21 +0000 | [diff] [blame] | 128 | void X86IntelInstPrinter::printDstIdx(const MCInst *MI, unsigned Op, |
| 129 | raw_ostream &O) { |
| 130 | // DI accesses are always ES-based. |
| 131 | O << "es:["; |
| 132 | printOperand(MI, Op, O); |
| 133 | O << ']'; |
| 134 | } |
| 135 | |
Craig Topper | 1885417 | 2013-08-25 22:23:38 +0000 | [diff] [blame] | 136 | void X86IntelInstPrinter::printMemOffset(const MCInst *MI, unsigned Op, |
| 137 | raw_ostream &O) { |
| 138 | const MCOperand &DispSpec = MI->getOperand(Op); |
Craig Topper | 35da3d1 | 2014-01-16 07:36:58 +0000 | [diff] [blame] | 139 | |
| 140 | // If this has a segment register, print it. |
Gabor Buella | 349ffce | 2018-06-05 10:41:39 +0000 | [diff] [blame] | 141 | printOptionalSegReg(MI, Op + 1, O); |
Craig Topper | 1885417 | 2013-08-25 22:23:38 +0000 | [diff] [blame] | 142 | |
| 143 | O << '['; |
| 144 | |
| 145 | if (DispSpec.isImm()) { |
| 146 | O << formatImm(DispSpec.getImm()); |
| 147 | } else { |
| 148 | assert(DispSpec.isExpr() && "non-immediate displacement?"); |
Matt Arsenault | 8b64355 | 2015-06-09 00:31:39 +0000 | [diff] [blame] | 149 | DispSpec.getExpr()->print(O, &MAI); |
Craig Topper | 1885417 | 2013-08-25 22:23:38 +0000 | [diff] [blame] | 150 | } |
| 151 | |
| 152 | O << ']'; |
| 153 | } |
Craig Topper | 0271d10 | 2015-01-23 08:00:59 +0000 | [diff] [blame] | 154 | |
| 155 | void X86IntelInstPrinter::printU8Imm(const MCInst *MI, unsigned Op, |
| 156 | raw_ostream &O) { |
Peter Collingbourne | c776677 | 2016-10-20 01:58:34 +0000 | [diff] [blame] | 157 | if (MI->getOperand(Op).isExpr()) |
| 158 | return MI->getOperand(Op).getExpr()->print(O, &MAI); |
| 159 | |
Craig Topper | 0271d10 | 2015-01-23 08:00:59 +0000 | [diff] [blame] | 160 | O << formatImm(MI->getOperand(Op).getImm() & 0xff); |
| 161 | } |