blob: b3bcf4034eda039fb84f5a3904bb957c2c2dc169 [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.
32struct X86Operand : public MCParsedAsmOperand {
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +000033 enum KindTy { Token, Register, Immediate, Memory, Prefix } 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;
121 case Immediate:
122 PrintImmValue(Imm.Val, "Imm:");
123 break;
124 case Prefix:
125 OS << "Prefix:" << Pref.Prefixes;
126 break;
127 case Memory:
128 OS << "Memory: ModeSize=" << Mem.ModeSize;
129 if (Mem.Size)
130 OS << ",Size=" << Mem.Size;
131 if (Mem.BaseReg)
132 OS << ",BaseReg=" << X86IntelInstPrinter::getRegisterName(Mem.BaseReg);
133 if (Mem.IndexReg)
134 OS << ",IndexReg="
135 << X86IntelInstPrinter::getRegisterName(Mem.IndexReg);
136 if (Mem.Scale)
137 OS << ",Scale=" << Mem.Scale;
138 if (Mem.Disp)
139 PrintImmValue(Mem.Disp, ",Disp=");
140 if (Mem.SegReg)
141 OS << ",SegReg=" << X86IntelInstPrinter::getRegisterName(Mem.SegReg);
142 break;
143 }
144 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000145
146 StringRef getToken() const {
147 assert(Kind == Token && "Invalid access!");
148 return StringRef(Tok.Data, Tok.Length);
149 }
150 void setTokenValue(StringRef Value) {
151 assert(Kind == Token && "Invalid access!");
152 Tok.Data = Value.data();
153 Tok.Length = Value.size();
154 }
155
Craig Topper39012cc2014-03-09 18:03:14 +0000156 unsigned getReg() const override {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000157 assert(Kind == Register && "Invalid access!");
158 return Reg.RegNo;
159 }
160
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +0000161 unsigned getPrefix() const {
162 assert(Kind == Prefix && "Invalid access!");
163 return Pref.Prefixes;
164 }
165
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000166 const MCExpr *getImm() const {
167 assert(Kind == Immediate && "Invalid access!");
168 return Imm.Val;
169 }
170
171 const MCExpr *getMemDisp() const {
172 assert(Kind == Memory && "Invalid access!");
173 return Mem.Disp;
174 }
175 unsigned getMemSegReg() const {
176 assert(Kind == Memory && "Invalid access!");
177 return Mem.SegReg;
178 }
179 unsigned getMemBaseReg() const {
180 assert(Kind == Memory && "Invalid access!");
181 return Mem.BaseReg;
182 }
183 unsigned getMemIndexReg() const {
184 assert(Kind == Memory && "Invalid access!");
185 return Mem.IndexReg;
186 }
187 unsigned getMemScale() const {
188 assert(Kind == Memory && "Invalid access!");
189 return Mem.Scale;
190 }
Craig Topper055845f2015-01-02 07:02:25 +0000191 unsigned getMemModeSize() const {
192 assert(Kind == Memory && "Invalid access!");
193 return Mem.ModeSize;
194 }
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +0000195 unsigned getMemFrontendSize() const {
196 assert(Kind == Memory && "Invalid access!");
197 return Mem.FrontendSize;
198 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000199
Craig Topper39012cc2014-03-09 18:03:14 +0000200 bool isToken() const override {return Kind == Token; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000201
Craig Topper39012cc2014-03-09 18:03:14 +0000202 bool isImm() const override { return Kind == Immediate; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000203
204 bool isImmSExti16i8() const {
205 if (!isImm())
206 return false;
207
208 // If this isn't a constant expr, just assume it fits and let relaxation
209 // handle it.
210 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
211 if (!CE)
212 return true;
213
214 // Otherwise, check the value is in a range that makes sense for this
215 // extension.
216 return isImmSExti16i8Value(CE->getValue());
217 }
218 bool isImmSExti32i8() const {
219 if (!isImm())
220 return false;
221
222 // If this isn't a constant expr, just assume it fits and let relaxation
223 // handle it.
224 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
225 if (!CE)
226 return true;
227
228 // Otherwise, check the value is in a range that makes sense for this
229 // extension.
230 return isImmSExti32i8Value(CE->getValue());
231 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000232 bool isImmSExti64i8() const {
233 if (!isImm())
234 return false;
235
236 // If this isn't a constant expr, just assume it fits and let relaxation
237 // handle it.
238 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
239 if (!CE)
240 return true;
241
242 // Otherwise, check the value is in a range that makes sense for this
243 // extension.
244 return isImmSExti64i8Value(CE->getValue());
245 }
246 bool isImmSExti64i32() const {
247 if (!isImm())
248 return false;
249
250 // If this isn't a constant expr, just assume it fits and let relaxation
251 // handle it.
252 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
253 if (!CE)
254 return true;
255
256 // Otherwise, check the value is in a range that makes sense for this
257 // extension.
258 return isImmSExti64i32Value(CE->getValue());
259 }
260
Craig Topperf38dea12015-01-21 06:07:53 +0000261 bool isImmUnsignedi8() const {
262 if (!isImm()) return false;
Peter Collingbournec7766772016-10-20 01:58:34 +0000263 // If this isn't a constant expr, just assume it fits and let relaxation
264 // handle it.
Craig Topperf38dea12015-01-21 06:07:53 +0000265 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
Peter Collingbournec7766772016-10-20 01:58:34 +0000266 if (!CE) return true;
Craig Topperf38dea12015-01-21 06:07:53 +0000267 return isImmUnsignedi8Value(CE->getValue());
268 }
269
Peter Collingbourne0da86302016-10-10 22:49:37 +0000270 bool isOffsetOf() const override {
271 return OffsetOfLoc.getPointer();
272 }
273
Craig Topper39012cc2014-03-09 18:03:14 +0000274 bool needAddressOf() const override {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000275 return AddressOf;
276 }
277
Craig Topper39012cc2014-03-09 18:03:14 +0000278 bool isMem() const override { return Kind == Memory; }
Reid Klecknerf6fb7802014-08-26 20:32:34 +0000279 bool isMemUnsized() const {
280 return Kind == Memory && Mem.Size == 0;
281 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000282 bool isMem8() const {
283 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
284 }
285 bool isMem16() const {
286 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
287 }
288 bool isMem32() const {
289 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
290 }
291 bool isMem64() const {
292 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
293 }
294 bool isMem80() const {
295 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
296 }
297 bool isMem128() const {
298 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
299 }
300 bool isMem256() const {
301 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
302 }
303 bool isMem512() const {
304 return Kind == Memory && (!Mem.Size || Mem.Size == 512);
305 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000306 bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
307 assert(Kind == Memory && "Invalid access!");
308 return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
309 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000310
Igor Breger45ef10f2016-02-25 13:30:17 +0000311 bool isMem64_RC128() const {
312 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000313 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000314 bool isMem128_RC128() const {
315 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000316 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000317 bool isMem128_RC256() const {
318 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000319 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000320 bool isMem256_RC128() const {
321 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000322 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000323 bool isMem256_RC256() const {
324 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000325 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000326
327 bool isMem64_RC128X() const {
328 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000329 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000330 bool isMem128_RC128X() const {
331 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000332 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000333 bool isMem128_RC256X() const {
334 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
Elena Demikhovsky6a1a3572015-06-28 10:53:29 +0000335 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000336 bool isMem256_RC128X() const {
337 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000338 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000339 bool isMem256_RC256X() const {
340 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
341 }
Craig Topper7dfd5832017-01-16 00:55:58 +0000342 bool isMem256_RC512() const {
343 return isMem256() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
344 }
Igor Breger45ef10f2016-02-25 13:30:17 +0000345 bool isMem512_RC256X() const {
346 return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
347 }
348 bool isMem512_RC512() const {
349 return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000350 }
351
352 bool isAbsMem() const {
353 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
354 !getMemIndexReg() && getMemScale() == 1;
355 }
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000356 bool isAVX512RC() const{
357 return isImm();
358 }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000359
Craig Topper63944542015-01-06 08:59:30 +0000360 bool isAbsMem16() const {
361 return isAbsMem() && Mem.ModeSize == 16;
362 }
363
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000364 bool isSrcIdx() const {
365 return !getMemIndexReg() && getMemScale() == 1 &&
366 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
367 getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
368 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
369 }
370 bool isSrcIdx8() const {
371 return isMem8() && isSrcIdx();
372 }
373 bool isSrcIdx16() const {
374 return isMem16() && isSrcIdx();
375 }
376 bool isSrcIdx32() const {
377 return isMem32() && isSrcIdx();
378 }
379 bool isSrcIdx64() const {
380 return isMem64() && isSrcIdx();
381 }
382
383 bool isDstIdx() const {
384 return !getMemIndexReg() && getMemScale() == 1 &&
385 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
386 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
387 getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
388 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
389 }
390 bool isDstIdx8() const {
391 return isMem8() && isDstIdx();
392 }
393 bool isDstIdx16() const {
394 return isMem16() && isDstIdx();
395 }
396 bool isDstIdx32() const {
397 return isMem32() && isDstIdx();
398 }
399 bool isDstIdx64() const {
400 return isMem64() && isDstIdx();
401 }
402
Craig Topper055845f2015-01-02 07:02:25 +0000403 bool isMemOffs() const {
404 return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
405 getMemScale() == 1;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000406 }
Craig Topper055845f2015-01-02 07:02:25 +0000407
408 bool isMemOffs16_8() const {
409 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000410 }
Craig Topper055845f2015-01-02 07:02:25 +0000411 bool isMemOffs16_16() const {
412 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000413 }
Craig Topper055845f2015-01-02 07:02:25 +0000414 bool isMemOffs16_32() const {
415 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
416 }
417 bool isMemOffs32_8() const {
418 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
419 }
420 bool isMemOffs32_16() const {
421 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
422 }
423 bool isMemOffs32_32() const {
424 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
425 }
Craig Topperae8e1b32015-01-03 00:00:20 +0000426 bool isMemOffs32_64() const {
427 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
428 }
Craig Topper055845f2015-01-02 07:02:25 +0000429 bool isMemOffs64_8() const {
430 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
431 }
432 bool isMemOffs64_16() const {
433 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
434 }
435 bool isMemOffs64_32() const {
436 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
437 }
438 bool isMemOffs64_64() const {
439 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000440 }
441
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +0000442 bool isPrefix() const { return Kind == Prefix; }
Craig Topper39012cc2014-03-09 18:03:14 +0000443 bool isReg() const override { return Kind == Register; }
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000444
445 bool isGR32orGR64() const {
446 return Kind == Register &&
447 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
448 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
449 }
450
451 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
452 // Add as immediates when possible.
453 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
Jim Grosbache9119e42015-05-13 18:37:00 +0000454 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000455 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000456 Inst.addOperand(MCOperand::createExpr(Expr));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000457 }
458
459 void addRegOperands(MCInst &Inst, unsigned N) const {
460 assert(N == 1 && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000461 Inst.addOperand(MCOperand::createReg(getReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000462 }
463
464 static unsigned getGR32FromGR64(unsigned RegNo) {
465 switch (RegNo) {
466 default: llvm_unreachable("Unexpected register");
467 case X86::RAX: return X86::EAX;
468 case X86::RCX: return X86::ECX;
469 case X86::RDX: return X86::EDX;
470 case X86::RBX: return X86::EBX;
471 case X86::RBP: return X86::EBP;
472 case X86::RSP: return X86::ESP;
473 case X86::RSI: return X86::ESI;
474 case X86::RDI: return X86::EDI;
475 case X86::R8: return X86::R8D;
476 case X86::R9: return X86::R9D;
477 case X86::R10: return X86::R10D;
478 case X86::R11: return X86::R11D;
479 case X86::R12: return X86::R12D;
480 case X86::R13: return X86::R13D;
481 case X86::R14: return X86::R14D;
482 case X86::R15: return X86::R15D;
483 case X86::RIP: return X86::EIP;
484 }
485 }
486
487 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
488 assert(N == 1 && "Invalid number of operands!");
489 unsigned RegNo = getReg();
490 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
491 RegNo = getGR32FromGR64(RegNo);
Jim Grosbache9119e42015-05-13 18:37:00 +0000492 Inst.addOperand(MCOperand::createReg(RegNo));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000493 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000494
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000495 void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
496 assert(N == 1 && "Invalid number of operands!");
497 addExpr(Inst, getImm());
498 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000499
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000500 void addImmOperands(MCInst &Inst, unsigned N) const {
501 assert(N == 1 && "Invalid number of operands!");
502 addExpr(Inst, getImm());
503 }
504
505 void addMemOperands(MCInst &Inst, unsigned N) const {
506 assert((N == 5) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000507 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
508 Inst.addOperand(MCOperand::createImm(getMemScale()));
509 Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000510 addExpr(Inst, getMemDisp());
Jim Grosbache9119e42015-05-13 18:37:00 +0000511 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000512 }
513
514 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
515 assert((N == 1) && "Invalid number of operands!");
516 // Add as immediates when possible.
517 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000518 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000519 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000520 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000521 }
522
523 void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
524 assert((N == 2) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000525 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
526 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000527 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000528
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000529 void addDstIdxOperands(MCInst &Inst, unsigned N) const {
530 assert((N == 1) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000531 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000532 }
533
534 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
535 assert((N == 2) && "Invalid number of operands!");
536 // Add as immediates when possible.
537 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000538 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000539 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000540 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
541 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000542 }
543
David Blaikie960ea3f2014-06-08 16:18:35 +0000544 static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000545 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
David Blaikie960ea3f2014-06-08 16:18:35 +0000546 auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000547 Res->Tok.Data = Str.data();
548 Res->Tok.Length = Str.size();
549 return Res;
550 }
551
David Blaikie960ea3f2014-06-08 16:18:35 +0000552 static std::unique_ptr<X86Operand>
553 CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
Peter Collingbourne0da86302016-10-10 22:49:37 +0000554 bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
555 StringRef SymName = StringRef(), void *OpDecl = nullptr) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000556 auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000557 Res->Reg.RegNo = RegNo;
558 Res->AddressOf = AddressOf;
Peter Collingbourne0da86302016-10-10 22:49:37 +0000559 Res->OffsetOfLoc = OffsetOfLoc;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000560 Res->SymName = SymName;
561 Res->OpDecl = OpDecl;
562 return Res;
563 }
564
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +0000565 static std::unique_ptr<X86Operand>
566 CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {
567 auto Res = llvm::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);
568 Res->Pref.Prefixes = Prefixes;
569 return Res;
570 }
571
David Blaikie960ea3f2014-06-08 16:18:35 +0000572 static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
573 SMLoc StartLoc, SMLoc EndLoc) {
574 auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000575 Res->Imm.Val = Val;
576 return Res;
577 }
578
579 /// Create an absolute memory operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000580 static std::unique_ptr<X86Operand>
Craig Topper055845f2015-01-02 07:02:25 +0000581 CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
582 unsigned Size = 0, StringRef SymName = StringRef(),
Daniel Jasper07a17712017-05-05 07:31:40 +0000583 void *OpDecl = nullptr, unsigned FrontendSize = 0) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000584 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000585 Res->Mem.SegReg = 0;
586 Res->Mem.Disp = Disp;
587 Res->Mem.BaseReg = 0;
588 Res->Mem.IndexReg = 0;
589 Res->Mem.Scale = 1;
590 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000591 Res->Mem.ModeSize = ModeSize;
Daniel Jasper07a17712017-05-05 07:31:40 +0000592 Res->Mem.FrontendSize = FrontendSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000593 Res->SymName = SymName;
594 Res->OpDecl = OpDecl;
595 Res->AddressOf = false;
596 return Res;
597 }
598
599 /// Create a generalized memory operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000600 static std::unique_ptr<X86Operand>
Craig Topper055845f2015-01-02 07:02:25 +0000601 CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
602 unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
603 SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +0000604 void *OpDecl = nullptr, unsigned FrontendSize = 0) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000605 // We should never just have a displacement, that should be parsed as an
606 // absolute memory operand.
607 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
608
609 // The scale should always be one of {1,2,4,8}.
610 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
611 "Invalid scale!");
David Blaikie960ea3f2014-06-08 16:18:35 +0000612 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000613 Res->Mem.SegReg = SegReg;
614 Res->Mem.Disp = Disp;
615 Res->Mem.BaseReg = BaseReg;
616 Res->Mem.IndexReg = IndexReg;
617 Res->Mem.Scale = Scale;
618 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000619 Res->Mem.ModeSize = ModeSize;
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +0000620 Res->Mem.FrontendSize = FrontendSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000621 Res->SymName = SymName;
622 Res->OpDecl = OpDecl;
623 Res->AddressOf = false;
624 return Res;
625 }
626};
627
Eugene Zelenko90562df2017-02-06 21:55:43 +0000628} // end namespace llvm
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000629
Eugene Zelenko90562df2017-02-06 21:55:43 +0000630#endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H