blob: 2493e8321c3ddc8cbb486d21e62e7ad3dfdcbc5f [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
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000464 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
465 assert(N == 1 && "Invalid number of operands!");
466 unsigned RegNo = getReg();
467 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
Craig Toppera3f52aa2018-04-29 00:53:10 +0000468 RegNo = getX86SubSuperRegister(RegNo, 32);
Jim Grosbache9119e42015-05-13 18:37:00 +0000469 Inst.addOperand(MCOperand::createReg(RegNo));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000470 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000471
Elena Demikhovsky18fd4962015-03-02 15:00:34 +0000472 void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
473 assert(N == 1 && "Invalid number of operands!");
474 addExpr(Inst, getImm());
475 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000476
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000477 void addImmOperands(MCInst &Inst, unsigned N) const {
478 assert(N == 1 && "Invalid number of operands!");
479 addExpr(Inst, getImm());
480 }
481
482 void addMemOperands(MCInst &Inst, unsigned N) const {
483 assert((N == 5) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000484 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
485 Inst.addOperand(MCOperand::createImm(getMemScale()));
486 Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000487 addExpr(Inst, getMemDisp());
Jim Grosbache9119e42015-05-13 18:37:00 +0000488 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000489 }
490
491 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
492 assert((N == 1) && "Invalid number of operands!");
493 // Add as immediates when possible.
494 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000495 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000496 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000497 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000498 }
499
500 void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
501 assert((N == 2) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000502 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
503 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000504 }
Eugene Zelenko90562df2017-02-06 21:55:43 +0000505
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000506 void addDstIdxOperands(MCInst &Inst, unsigned N) const {
507 assert((N == 1) && "Invalid number of operands!");
Jim Grosbache9119e42015-05-13 18:37:00 +0000508 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000509 }
510
511 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
512 assert((N == 2) && "Invalid number of operands!");
513 // Add as immediates when possible.
514 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
Jim Grosbache9119e42015-05-13 18:37:00 +0000515 Inst.addOperand(MCOperand::createImm(CE->getValue()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000516 else
Jim Grosbache9119e42015-05-13 18:37:00 +0000517 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
518 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000519 }
520
David Blaikie960ea3f2014-06-08 16:18:35 +0000521 static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000522 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
David Blaikie960ea3f2014-06-08 16:18:35 +0000523 auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000524 Res->Tok.Data = Str.data();
525 Res->Tok.Length = Str.size();
526 return Res;
527 }
528
David Blaikie960ea3f2014-06-08 16:18:35 +0000529 static std::unique_ptr<X86Operand>
530 CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
Peter Collingbourne0da86302016-10-10 22:49:37 +0000531 bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
532 StringRef SymName = StringRef(), void *OpDecl = nullptr) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000533 auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000534 Res->Reg.RegNo = RegNo;
535 Res->AddressOf = AddressOf;
Peter Collingbourne0da86302016-10-10 22:49:37 +0000536 Res->OffsetOfLoc = OffsetOfLoc;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000537 Res->SymName = SymName;
538 Res->OpDecl = OpDecl;
539 return Res;
540 }
541
Andrew V. Tischenkobfc90612017-10-16 11:14:29 +0000542 static std::unique_ptr<X86Operand>
543 CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {
544 auto Res = llvm::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);
545 Res->Pref.Prefixes = Prefixes;
546 return Res;
547 }
548
David Blaikie960ea3f2014-06-08 16:18:35 +0000549 static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
550 SMLoc StartLoc, SMLoc EndLoc) {
551 auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000552 Res->Imm.Val = Val;
553 return Res;
554 }
555
556 /// Create an absolute memory operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000557 static std::unique_ptr<X86Operand>
Craig Topper055845f2015-01-02 07:02:25 +0000558 CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
559 unsigned Size = 0, StringRef SymName = StringRef(),
Daniel Jasper07a17712017-05-05 07:31:40 +0000560 void *OpDecl = nullptr, unsigned FrontendSize = 0) {
David Blaikie960ea3f2014-06-08 16:18:35 +0000561 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000562 Res->Mem.SegReg = 0;
563 Res->Mem.Disp = Disp;
564 Res->Mem.BaseReg = 0;
565 Res->Mem.IndexReg = 0;
566 Res->Mem.Scale = 1;
567 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000568 Res->Mem.ModeSize = ModeSize;
Daniel Jasper07a17712017-05-05 07:31:40 +0000569 Res->Mem.FrontendSize = FrontendSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000570 Res->SymName = SymName;
571 Res->OpDecl = OpDecl;
572 Res->AddressOf = false;
573 return Res;
574 }
575
576 /// Create a generalized memory operand.
David Blaikie960ea3f2014-06-08 16:18:35 +0000577 static std::unique_ptr<X86Operand>
Craig Topper055845f2015-01-02 07:02:25 +0000578 CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
579 unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
580 SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +0000581 void *OpDecl = nullptr, unsigned FrontendSize = 0) {
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000582 // We should never just have a displacement, that should be parsed as an
583 // absolute memory operand.
584 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
585
586 // The scale should always be one of {1,2,4,8}.
587 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
588 "Invalid scale!");
David Blaikie960ea3f2014-06-08 16:18:35 +0000589 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000590 Res->Mem.SegReg = SegReg;
591 Res->Mem.Disp = Disp;
592 Res->Mem.BaseReg = BaseReg;
593 Res->Mem.IndexReg = IndexReg;
594 Res->Mem.Scale = Scale;
595 Res->Mem.Size = Size;
Craig Topper055845f2015-01-02 07:02:25 +0000596 Res->Mem.ModeSize = ModeSize;
Reid Kleckner6d2ea6e2017-05-04 18:19:52 +0000597 Res->Mem.FrontendSize = FrontendSize;
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000598 Res->SymName = SymName;
599 Res->OpDecl = OpDecl;
600 Res->AddressOf = false;
601 return Res;
602 }
603};
604
Eugene Zelenko90562df2017-02-06 21:55:43 +0000605} // end namespace llvm
Evgeniy Stepanove3804d42014-02-28 12:28:07 +0000606
Eugene Zelenko90562df2017-02-06 21:55:43 +0000607#endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H