blob: 4d4aae0a1c6ab1bb6606cf5597b365a0bd92107f [file] [log] [blame]
Eugene Zelenko90562df2017-02-06 21:55:43 +00001//===- X86Operand.h - Parsed X86 machine instruction ------------*- C++ -*-===//
Evgeniy Stepanove3804d42014-02-28 12:28:07 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Benjamin Kramera7c40ef2014-08-13 16:26:38 +000010#ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
11#define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000012
Andrew V. Tischenkod037b142018-01-11 10:31:01 +000013#include "InstPrinter/X86IntelInstPrinter.h"
David Blaikie1032b512017-10-24 21:29:15 +000014#include "MCTargetDesc/X86MCTargetDesc.h"
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000015#include "X86AsmParserCommon.h"
Eugene Zelenko90562df2017-02-06 21:55:43 +000016#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/StringRef.h"
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000018#include "llvm/MC/MCExpr.h"
Pete Cooper3de83e42015-05-15 21:58:42 +000019#include "llvm/MC/MCInst.h"
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000020#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000021#include "llvm/MC/MCRegisterInfo.h"
Eugene Zelenko90562df2017-02-06 21:55:43 +000022#include "llvm/Support/Casting.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/SMLoc.h"
25#include <cassert>
26#include <memory>
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000027
28namespace llvm {
29
30/// X86Operand - Instances of this class represent a parsed X86 machine
31/// instruction.
Craig Topper15349292018-06-02 02:15:10 +000032struct X86Operand final : public MCParsedAsmOperand {
Nirav Dave1468d6e2019-01-04 17:11:15 +000033 enum KindTy { Token, Register, Immediate, Memory, Prefix, DXRegister } Kind;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000034
35 SMLoc StartLoc, EndLoc;
Peter Collingbourne0da86302016-10-10 22:49:37 +000036 SMLoc OffsetOfLoc;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000037 StringRef SymName;
38 void *OpDecl;
39 bool AddressOf;
40
41 struct TokOp {
42 const char *Data;
43 unsigned Length;
44 };
45
46 struct RegOp {
47 unsigned RegNo;
48 };
49
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +000050 struct PrefOp {
51 unsigned Prefixes;
52 };
53
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000054 struct ImmOp {
55 const MCExpr *Val;
56 };
57
58 struct MemOp {
59 unsigned SegReg;
60 const MCExpr *Disp;
61 unsigned BaseReg;
62 unsigned IndexReg;
63 unsigned Scale;
64 unsigned Size;
Craig Topper055845f2015-01-02 07:02:25 +000065 unsigned ModeSize;
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +000066
67 /// If the memory operand is unsized and there are multiple instruction
68 /// matches, prefer the one with this size.
69 unsigned FrontendSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000070 };
71
72 union {
73 struct TokOp Tok;
74 struct RegOp Reg;
75 struct ImmOp Imm;
76 struct MemOp Mem;
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +000077 struct PrefOp Pref;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000078 };
79
80 X86Operand(KindTy K, SMLoc Start, SMLoc End)
Andrew V. Tischenkod037b142018-01-11 10:31:01 +000081 : Kind(K), StartLoc(Start), EndLoc(End) {}
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000082
Craig Topper39012cc2014-03-09 18:03:14 +000083 StringRef getSymName() override { return SymName; }
84 void *getOpDecl() override { return OpDecl; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000085
86 /// getStartLoc - Get the location of the first token of this operand.
Craig Topper39012cc2014-03-09 18:03:14 +000087 SMLoc getStartLoc() const override { return StartLoc; }
Eugene Zelenko90562df2017-02-06 21:55:43 +000088
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000089 /// getEndLoc - Get the location of the last token of this operand.
Peter Collingbourne0da86302016-10-10 22:49:37 +000090 SMLoc getEndLoc() const override { return EndLoc; }
Eugene Zelenko90562df2017-02-06 21:55:43 +000091
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000092 /// getLocRange - Get the range between the first and last token of this
93 /// operand.
94 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
Eugene Zelenko90562df2017-02-06 21:55:43 +000095
Peter Collingbourne0da86302016-10-10 22:49:37 +000096 /// getOffsetOfLoc - Get the location of the offset operator.
97 SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +000098
Andrew V. Tischenkod037b142018-01-11 10:31:01 +000099 void print(raw_ostream &OS) const override {
100
101 auto PrintImmValue = [&](const MCExpr *Val, const char *VName) {
102 if (Val->getKind() == MCExpr::Constant) {
103 if (auto Imm = cast<MCConstantExpr>(Val)->getValue())
104 OS << VName << Imm;
105 } else if (Val->getKind() == MCExpr::SymbolRef) {
106 if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Val)) {
107 const MCSymbol &Sym = SRE->getSymbol();
108 if (auto SymName = Sym.getName().data())
109 OS << VName << SymName;
110 }
111 }
112 };
113
114 switch (Kind) {
115 case Token:
116 OS << Tok.Data;
117 break;
118 case Register:
119 OS << "Reg:" << X86IntelInstPrinter::getRegisterName(Reg.RegNo);
120 break;
Nirav Dave1468d6e2019-01-04 17:11:15 +0000121 case DXRegister:
122 OS << "DXReg";
123 break;
Andrew V. Tischenkod037b142018-01-11 10:31:01 +0000124 case Immediate:
125 PrintImmValue(Imm.Val, "Imm:");
126 break;
127 case Prefix:
128 OS << "Prefix:" << Pref.Prefixes;
129 break;
130 case Memory:
131 OS << "Memory: ModeSize=" << Mem.ModeSize;
132 if (Mem.Size)
133 OS << ",Size=" << Mem.Size;
134 if (Mem.BaseReg)
135 OS << ",BaseReg=" << X86IntelInstPrinter::getRegisterName(Mem.BaseReg);
136 if (Mem.IndexReg)
137 OS << ",IndexReg="
138 << X86IntelInstPrinter::getRegisterName(Mem.IndexReg);
139 if (Mem.Scale)
140 OS << ",Scale=" << Mem.Scale;
141 if (Mem.Disp)
142 PrintImmValue(Mem.Disp, ",Disp=");
143 if (Mem.SegReg)
144 OS << ",SegReg=" << X86IntelInstPrinter::getRegisterName(Mem.SegReg);
145 break;
146 }
147 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000148
149 StringRef getToken() const {
150 assert(Kind == Token && "Invalid access!");
151 return StringRef(Tok.Data, Tok.Length);
152 }
153 void setTokenValue(StringRef Value) {
154 assert(Kind == Token && "Invalid access!");
155 Tok.Data = Value.data();
156 Tok.Length = Value.size();
157 }
158
Craig Topper39012cc2014-03-09 18:03:14 +0000159 unsigned getReg() const override {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000160 assert(Kind == Register && "Invalid access!");
161 return Reg.RegNo;
162 }
163
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +0000164 unsigned getPrefix() const {
165 assert(Kind == Prefix && "Invalid access!");
166 return Pref.Prefixes;
167 }
168
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000169 const MCExpr *getImm() const {
170 assert(Kind == Immediate && "Invalid access!");
171 return Imm.Val;
172 }
173
174 const MCExpr *getMemDisp() const {
175 assert(Kind == Memory && "Invalid access!");
176 return Mem.Disp;
177 }
178 unsigned getMemSegReg() const {
179 assert(Kind == Memory && "Invalid access!");
180 return Mem.SegReg;
181 }
182 unsigned getMemBaseReg() const {
183 assert(Kind == Memory && "Invalid access!");
184 return Mem.BaseReg;
185 }
186 unsigned getMemIndexReg() const {
187 assert(Kind == Memory && "Invalid access!");
188 return Mem.IndexReg;
189 }
190 unsigned getMemScale() const {
191 assert(Kind == Memory && "Invalid access!");
192 return Mem.Scale;
193 }
Craig Topper055845f2015-01-02 07:02:25 +0000194 unsigned getMemModeSize() const {
195 assert(Kind == Memory && "Invalid access!");
196 return Mem.ModeSize;
197 }
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +0000198 unsigned getMemFrontendSize() const {
199 assert(Kind == Memory && "Invalid access!");
200 return Mem.FrontendSize;
201 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000202
Craig Topper39012cc2014-03-09 18:03:14 +0000203 bool isToken() const override {return Kind == Token; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000204
Craig Topper39012cc2014-03-09 18:03:14 +0000205 bool isImm() const override { return Kind == Immediate; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000206
207 bool isImmSExti16i8() const {
208 if (!isImm())
209 return false;
210
211 // If this isn't a constant expr, just assume it fits and let relaxation
212 // handle it.
213 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
214 if (!CE)
215 return true;
216
217 // Otherwise, check the value is in a range that makes sense for this
218 // extension.
219 return isImmSExti16i8Value(CE->getValue());
220 }
221 bool isImmSExti32i8() const {
222 if (!isImm())
223 return false;
224
225 // If this isn't a constant expr, just assume it fits and let relaxation
226 // handle it.
227 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
228 if (!CE)
229 return true;
230
231 // Otherwise, check the value is in a range that makes sense for this
232 // extension.
233 return isImmSExti32i8Value(CE->getValue());
234 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000235 bool isImmSExti64i8() const {
236 if (!isImm())
237 return false;
238
239 // If this isn't a constant expr, just assume it fits and let relaxation
240 // handle it.
241 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
242 if (!CE)
243 return true;
244
245 // Otherwise, check the value is in a range that makes sense for this
246 // extension.
247 return isImmSExti64i8Value(CE->getValue());
248 }
249 bool isImmSExti64i32() const {
250 if (!isImm())
251 return false;
252
253 // If this isn't a constant expr, just assume it fits and let relaxation
254 // handle it.
255 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
256 if (!CE)
257 return true;
258
259 // Otherwise, check the value is in a range that makes sense for this
260 // extension.
261 return isImmSExti64i32Value(CE->getValue());
262 }
263
Craig Topperf38dea12015-01-21 06:07:53 +0000264 bool isImmUnsignedi8() const {
265 if (!isImm()) return false;
Peter Collingbournec7766772016-10-20 01:58:34 +0000266 // If this isn't a constant expr, just assume it fits and let relaxation
267 // handle it.
Craig Topperf38dea12015-01-21 06:07:53 +0000268 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
Peter Collingbournec7766772016-10-20 01:58:34 +0000269 if (!CE) return true;
Craig Topperf38dea12015-01-21 06:07:53 +0000270 return isImmUnsignedi8Value(CE->getValue());
271 }
272
Peter Collingbourne0da86302016-10-10 22:49:37 +0000273 bool isOffsetOf() const override {
274 return OffsetOfLoc.getPointer();
275 }
276
Craig Topper39012cc2014-03-09 18:03:14 +0000277 bool needAddressOf() const override {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000278 return AddressOf;
279 }
280
Craig Topper39012cc2014-03-09 18:03:14 +0000281 bool isMem() const override { return Kind == Memory; }
Reid Klecknerf6fb7802014-08-26 20:32:34 +0000282 bool isMemUnsized() const {
283 return Kind == Memory && Mem.Size == 0;
284 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000285 bool isMem8() const {
286 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
287 }
288 bool isMem16() const {
289 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
290 }
291 bool isMem32() const {
292 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
293 }
294 bool isMem64() const {
295 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
296 }
297 bool isMem80() const {
298 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
299 }
300 bool isMem128() const {
301 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
302 }
303 bool isMem256() const {
304 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
305 }
306 bool isMem512() const {
307 return Kind == Memory && (!Mem.Size || Mem.Size == 512);
308 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000309 bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
310 assert(Kind == Memory && "Invalid access!");
311 return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
312 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000313
Igor Breger45ef10f2016-02-25 13:30:17 +0000314 bool isMem64_RC128() const {
315 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000316 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000317 bool isMem128_RC128() const {
318 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000319 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000320 bool isMem128_RC256() const {
321 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000322 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000323 bool isMem256_RC128() const {
324 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000325 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000326 bool isMem256_RC256() const {
327 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000328 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000329
330 bool isMem64_RC128X() const {
331 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000332 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000333 bool isMem128_RC128X() const {
334 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000335 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000336 bool isMem128_RC256X() const {
337 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000338 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000339 bool isMem256_RC128X() const {
340 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000341 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000342 bool isMem256_RC256X() const {
343 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
344 }
Craig Topper7dfd5832017-01-16 00:55:58 +0000345 bool isMem256_RC512() const {
346 return isMem256() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
347 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000348 bool isMem512_RC256X() const {
349 return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
350 }
351 bool isMem512_RC512() const {
352 return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000353 }
354
355 bool isAbsMem() const {
356 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
357 !getMemIndexReg() && getMemScale() == 1;
358 }
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000359 bool isAVX512RC() const{
360 return isImm();
361 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000362
Craig Topper63944542015-01-06 08:59:30 +0000363 bool isAbsMem16() const {
364 return isAbsMem() && Mem.ModeSize == 16;
365 }
366
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000367 bool isSrcIdx() const {
368 return !getMemIndexReg() && getMemScale() == 1 &&
369 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
370 getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
371 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
372 }
373 bool isSrcIdx8() const {
374 return isMem8() && isSrcIdx();
375 }
376 bool isSrcIdx16() const {
377 return isMem16() && isSrcIdx();
378 }
379 bool isSrcIdx32() const {
380 return isMem32() && isSrcIdx();
381 }
382 bool isSrcIdx64() const {
383 return isMem64() && isSrcIdx();
384 }
385
386 bool isDstIdx() const {
387 return !getMemIndexReg() && getMemScale() == 1 &&
388 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
389 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
390 getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
391 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
392 }
393 bool isDstIdx8() const {
394 return isMem8() && isDstIdx();
395 }
396 bool isDstIdx16() const {
397 return isMem16() && isDstIdx();
398 }
399 bool isDstIdx32() const {
400 return isMem32() && isDstIdx();
401 }
402 bool isDstIdx64() const {
403 return isMem64() && isDstIdx();
404 }
405
Craig Topper055845f2015-01-02 07:02:25 +0000406 bool isMemOffs() const {
407 return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
408 getMemScale() == 1;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000409 }
Craig Topper055845f2015-01-02 07:02:25 +0000410
411 bool isMemOffs16_8() const {
412 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000413 }
Craig Topper055845f2015-01-02 07:02:25 +0000414 bool isMemOffs16_16() const {
415 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000416 }
Craig Topper055845f2015-01-02 07:02:25 +0000417 bool isMemOffs16_32() const {
418 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
419 }
420 bool isMemOffs32_8() const {
421 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
422 }
423 bool isMemOffs32_16() const {
424 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
425 }
426 bool isMemOffs32_32() const {
427 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
428 }
Craig Topperae8e1b32015-01-03 00:00:20 +0000429 bool isMemOffs32_64() const {
430 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
431 }
Craig Topper055845f2015-01-02 07:02:25 +0000432 bool isMemOffs64_8() const {
433 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
434 }
435 bool isMemOffs64_16() const {
436 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
437 }
438 bool isMemOffs64_32() const {
439 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
440 }
441 bool isMemOffs64_64() const {
442 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000443 }
444
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +0000445 bool isPrefix() const { return Kind == Prefix; }
Craig Topper39012cc2014-03-09 18:03:14 +0000446 bool isReg() const override { return Kind == Register; }
Nirav Dave1468d6e2019-01-04 17:11:15 +0000447 bool isDXReg() const { return Kind == DXRegister; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000448
449 bool isGR32orGR64() const {
450 return Kind == Register &&
451 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
452 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
453 }
454
455 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
456 // Add as immediates when possible.
457 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
Jim Grosbache9119e42015-05-13 18:37:00 +0000458 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000459 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000460 Inst.addOperand(MCOperand::createExpr(Expr));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000461 }
462
463 void addRegOperands(MCInst &Inst, unsigned N) const {
464 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000465 Inst.addOperand(MCOperand::createReg(getReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000466 }
467
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000468 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
469 assert(N == 1 && "Invalid number of operands!");
470 unsigned RegNo = getReg();
471 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
Craig Toppera3f52aa2018-04-29 00:53:10 +0000472 RegNo = getX86SubSuperRegister(RegNo, 32);
Jim Grosbache9119e42015-05-13 18:37:00 +0000473 Inst.addOperand(MCOperand::createReg(RegNo));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000474 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000475
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000476 void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
477 assert(N == 1 && "Invalid number of operands!");
478 addExpr(Inst, getImm());
479 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000480
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000481 void addImmOperands(MCInst &Inst, unsigned N) const {
482 assert(N == 1 && "Invalid number of operands!");
483 addExpr(Inst, getImm());
484 }
485
486 void addMemOperands(MCInst &Inst, unsigned N) const {
487 assert((N == 5) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000488 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
489 Inst.addOperand(MCOperand::createImm(getMemScale()));
490 Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000491 addExpr(Inst, getMemDisp());
Jim Grosbache9119e42015-05-13 18:37:00 +0000492 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000493 }
494
495 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
496 assert((N == 1) && "Invalid number of operands!");
497 // Add as immediates when possible.
498 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000499 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000500 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000501 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000502 }
503
504 void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
505 assert((N == 2) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000506 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
507 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000508 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000509
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000510 void addDstIdxOperands(MCInst &Inst, unsigned N) const {
511 assert((N == 1) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000512 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000513 }
514
515 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
516 assert((N == 2) && "Invalid number of operands!");
517 // Add as immediates when possible.
518 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000519 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000520 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000521 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
522 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000523 }
524
David Blaikie960ea3f2014-06-08 16:18:35 +0000525 static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000526 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
David Blaikie960ea3f2014-06-08 16:18:35 +0000527 auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000528 Res->Tok.Data = Str.data();
529 Res->Tok.Length = Str.size();
530 return Res;
531 }
532
David Blaikie960ea3f2014-06-08 16:18:35 +0000533 static std::unique_ptr<X86Operand>
534 CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
Peter Collingbourne0da86302016-10-10 22:49:37 +0000535 bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
536 StringRef SymName = StringRef(), void *OpDecl = nullptr) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000537 auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000538 Res->Reg.RegNo = RegNo;
539 Res->AddressOf = AddressOf;
Peter Collingbourne0da86302016-10-10 22:49:37 +0000540 Res->OffsetOfLoc = OffsetOfLoc;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000541 Res->SymName = SymName;
542 Res->OpDecl = OpDecl;
543 return Res;
544 }
545
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +0000546 static std::unique_ptr<X86Operand>
Nirav Dave1468d6e2019-01-04 17:11:15 +0000547 CreateDXReg(SMLoc StartLoc, SMLoc EndLoc) {
548 return llvm::make_unique<X86Operand>(DXRegister, StartLoc, EndLoc);
549 }
550
551 static std::unique_ptr<X86Operand>
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +0000552 CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {
553 auto Res = llvm::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);
554 Res->Pref.Prefixes = Prefixes;
555 return Res;
556 }
557
David Blaikie960ea3f2014-06-08 16:18:35 +0000558 static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
559 SMLoc StartLoc, SMLoc EndLoc) {
560 auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000561 Res->Imm.Val = Val;
562 return Res;
563 }
564
565 /// Create an absolute memory operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000566 static std::unique_ptr<X86Operand>
Craig Topper055845f2015-01-02 07:02:25 +0000567 CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
568 unsigned Size = 0, StringRef SymName = StringRef(),
Daniel Jasper07a17712017-05-05 07:31:40 +0000569 void *OpDecl = nullptr, unsigned FrontendSize = 0) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000570 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000571 Res->Mem.SegReg = 0;
572 Res->Mem.Disp = Disp;
573 Res->Mem.BaseReg = 0;
574 Res->Mem.IndexReg = 0;
575 Res->Mem.Scale = 1;
576 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000577 Res->Mem.ModeSize = ModeSize;
Daniel Jasper07a17712017-05-05 07:31:40 +0000578 Res->Mem.FrontendSize = FrontendSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000579 Res->SymName = SymName;
580 Res->OpDecl = OpDecl;
581 Res->AddressOf = false;
582 return Res;
583 }
584
585 /// Create a generalized memory operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000586 static std::unique_ptr<X86Operand>
Craig Topper055845f2015-01-02 07:02:25 +0000587 CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
588 unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
589 SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +0000590 void *OpDecl = nullptr, unsigned FrontendSize = 0) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000591 // We should never just have a displacement, that should be parsed as an
592 // absolute memory operand.
593 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
594
595 // The scale should always be one of {1,2,4,8}.
596 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
597 "Invalid scale!");
David Blaikie960ea3f2014-06-08 16:18:35 +0000598 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000599 Res->Mem.SegReg = SegReg;
600 Res->Mem.Disp = Disp;
601 Res->Mem.BaseReg = BaseReg;
602 Res->Mem.IndexReg = IndexReg;
603 Res->Mem.Scale = Scale;
604 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000605 Res->Mem.ModeSize = ModeSize;
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +0000606 Res->Mem.FrontendSize = FrontendSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000607 Res->SymName = SymName;
608 Res->OpDecl = OpDecl;
609 Res->AddressOf = false;
610 return Res;
611 }
612};
613
Eugene Zelenko90562df2017-02-06 21:55:43 +0000614} // end namespace llvm
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000615
Eugene Zelenko90562df2017-02-06 21:55:43 +0000616#endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H