LLVM 22.0.0git
X86Operand.h
Go to the documentation of this file.
1//===- X86Operand.h - Parsed X86 machine instruction ------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
10#define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
11
14#include "X86AsmParserCommon.h"
15#include "llvm/ADT/STLExtras.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCSymbol.h"
23#include "llvm/Support/SMLoc.h"
24#include <cassert>
25#include <memory>
26
27namespace llvm {
28
29/// X86Operand - Instances of this class represent a parsed X86 machine
30/// instruction.
31struct X86Operand final : public MCParsedAsmOperand {
33
37 void *OpDecl;
39
40 /// This used for inline asm which may specify base reg and index reg for
41 /// MemOp. e.g. ARR[eax + ecx*4], so no extra reg can be used for MemOp.
42 bool UseUpRegs = false;
43
44 struct TokOp {
45 const char *Data;
46 unsigned Length;
47 };
48
49 struct RegOp {
51 };
52
53 struct PrefOp {
54 unsigned Prefixes;
55 };
56
57 struct ImmOp {
58 const MCExpr *Val;
60 };
61
62 struct MemOp {
64 const MCExpr *Disp;
68 unsigned Scale;
69 unsigned Size;
70 unsigned ModeSize;
71
72 /// If the memory operand is unsized and there are multiple instruction
73 /// matches, prefer the one with this size.
74 unsigned FrontendSize;
75
76 /// If false, then this operand must be a memory operand for an indirect
77 /// branch instruction. Otherwise, this operand may belong to either a
78 /// direct or indirect branch instruction.
80 };
81
82 union {
83 struct TokOp Tok;
84 struct RegOp Reg;
85 struct ImmOp Imm;
86 struct MemOp Mem;
87 struct PrefOp Pref;
88 };
89
91 : Kind(K), StartLoc(Start), EndLoc(End), OpDecl(nullptr),
93
94 StringRef getSymName() override { return SymName; }
95 void *getOpDecl() override { return OpDecl; }
96
97 /// getStartLoc - Get the location of the first token of this operand.
98 SMLoc getStartLoc() const override { return StartLoc; }
99
100 /// getEndLoc - Get the location of the last token of this operand.
101 SMLoc getEndLoc() const override { return EndLoc; }
102
103 /// getLocRange - Get the range between the first and last token of this
104 /// operand.
106
107 /// getOffsetOfLoc - Get the location of the offset operator.
108 SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
109
110 void print(raw_ostream &OS, const MCAsmInfo &) const override {
111 auto PrintImmValue = [&](const MCExpr *Val, const char *VName) {
112 if (Val->getKind() == MCExpr::Constant) {
113 if (auto Imm = cast<MCConstantExpr>(Val)->getValue())
114 OS << VName << Imm;
115 } else if (Val->getKind() == MCExpr::SymbolRef) {
116 if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Val)) {
117 const MCSymbol &Sym = SRE->getSymbol();
118 if (const char *SymNameStr = Sym.getName().data())
119 OS << VName << SymNameStr;
120 }
121 }
122 };
123
124 switch (Kind) {
125 case Token:
126 OS << Tok.Data;
127 break;
128 case Register:
130 break;
131 case DXRegister:
132 OS << "DXReg";
133 break;
134 case Immediate:
135 PrintImmValue(Imm.Val, "Imm:");
136 break;
137 case Prefix:
138 OS << "Prefix:" << Pref.Prefixes;
139 break;
140 case Memory:
141 OS << "Memory: ModeSize=" << Mem.ModeSize;
142 if (Mem.Size)
143 OS << ",Size=" << Mem.Size;
144 if (Mem.BaseReg)
146 if (Mem.IndexReg)
147 OS << ",IndexReg="
149 if (Mem.Scale)
150 OS << ",Scale=" << Mem.Scale;
151 if (Mem.Disp)
152 PrintImmValue(Mem.Disp, ",Disp=");
153 if (Mem.SegReg)
155 break;
156 }
157 }
158
160 assert(Kind == Token && "Invalid access!");
161 return StringRef(Tok.Data, Tok.Length);
162 }
164 assert(Kind == Token && "Invalid access!");
165 Tok.Data = Value.data();
166 Tok.Length = Value.size();
167 }
168
169 MCRegister getReg() const override {
170 assert(Kind == Register && "Invalid access!");
171 return Reg.RegNo;
172 }
173
174 unsigned getPrefix() const {
175 assert(Kind == Prefix && "Invalid access!");
176 return Pref.Prefixes;
177 }
178
179 const MCExpr *getImm() const {
180 assert(Kind == Immediate && "Invalid access!");
181 return Imm.Val;
182 }
183
184 const MCExpr *getMemDisp() const {
185 assert(Kind == Memory && "Invalid access!");
186 return Mem.Disp;
187 }
189 assert(Kind == Memory && "Invalid access!");
190 return Mem.SegReg;
191 }
193 assert(Kind == Memory && "Invalid access!");
194 return Mem.BaseReg;
195 }
197 assert(Kind == Memory && "Invalid access!");
198 return Mem.DefaultBaseReg;
199 }
201 assert(Kind == Memory && "Invalid access!");
202 return Mem.IndexReg;
203 }
204 unsigned getMemScale() const {
205 assert(Kind == Memory && "Invalid access!");
206 return Mem.Scale;
207 }
208 unsigned getMemModeSize() const {
209 assert(Kind == Memory && "Invalid access!");
210 return Mem.ModeSize;
211 }
212 unsigned getMemFrontendSize() const {
213 assert(Kind == Memory && "Invalid access!");
214 return Mem.FrontendSize;
215 }
217 assert(Kind == Memory && "Invalid access!");
219 }
220
221 bool isToken() const override {return Kind == Token; }
222
223 bool isImm() const override { return Kind == Immediate; }
224
225 bool isImmSExti16i8() const {
226 if (!isImm())
227 return false;
228
229 // If this isn't a constant expr, just assume it fits and let relaxation
230 // handle it.
231 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
232 if (!CE)
233 return true;
234
235 // Otherwise, check the value is in a range that makes sense for this
236 // extension.
237 return isImmSExti16i8Value(CE->getValue());
238 }
239 bool isImmSExti32i8() const {
240 if (!isImm())
241 return false;
242
243 // If this isn't a constant expr, just assume it fits and let relaxation
244 // handle it.
245 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
246 if (!CE)
247 return true;
248
249 // Otherwise, check the value is in a range that makes sense for this
250 // extension.
251 return isImmSExti32i8Value(CE->getValue());
252 }
253 bool isImmSExti64i8() const {
254 if (!isImm())
255 return false;
256
257 // If this isn't a constant expr, just assume it fits and let relaxation
258 // handle it.
259 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
260 if (!CE)
261 return true;
262
263 // Otherwise, check the value is in a range that makes sense for this
264 // extension.
265 return isImmSExti64i8Value(CE->getValue());
266 }
267 bool isImmSExti64i32() const {
268 if (!isImm())
269 return false;
270
271 // If this isn't a constant expr, just assume it fits and let relaxation
272 // handle it.
273 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
274 if (!CE)
275 return true;
276
277 // Otherwise, check the value is in a range that makes sense for this
278 // extension.
279 return isImmSExti64i32Value(CE->getValue());
280 }
281
282 bool isImmUnsignedi4() const {
283 if (!isImm()) return false;
284 // If this isn't a constant expr, reject it. The immediate byte is shared
285 // with a register encoding. We can't have it affected by a relocation.
286 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
287 if (!CE) return false;
288 return isImmUnsignedi4Value(CE->getValue());
289 }
290
291 bool isImmUnsignedi8() const {
292 if (!isImm()) return false;
293 // If this isn't a constant expr, just assume it fits and let relaxation
294 // handle it.
295 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
296 if (!CE) return true;
297 return isImmUnsignedi8Value(CE->getValue());
298 }
299
300 bool isOffsetOfLocal() const override { return isImm() && Imm.LocalRef; }
301
302 bool needAddressOf() const override { return AddressOf; }
303
304 bool isMem() const override { return Kind == Memory; }
305 bool isMemUnsized() const {
306 return Kind == Memory && Mem.Size == 0;
307 }
308 bool isMem8() const {
309 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
310 }
311 bool isMem16() const {
312 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
313 }
314 bool isMem32() const {
315 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
316 }
317 bool isMem64() const {
318 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
319 }
320 bool isMem80() const {
321 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
322 }
323 bool isMem128() const {
324 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
325 }
326 bool isMem256() const {
327 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
328 }
329 bool isMem512() const {
330 return Kind == Memory && (!Mem.Size || Mem.Size == 512);
331 }
332
333 bool isSibMem() const {
334 return isMem() && Mem.BaseReg != X86::RIP && Mem.BaseReg != X86::EIP;
335 }
336
337 bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
338 assert(Kind == Memory && "Invalid access!");
339 return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
340 }
341
342 bool isMem32_RC128() const {
343 return isMem32() && isMemIndexReg(X86::XMM0, X86::XMM15);
344 }
345 bool isMem64_RC128() const {
346 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
347 }
348 bool isMem32_RC256() const {
349 return isMem32() && isMemIndexReg(X86::YMM0, X86::YMM15);
350 }
351 bool isMem64_RC256() const {
352 return isMem64() && isMemIndexReg(X86::YMM0, X86::YMM15);
353 }
354
355 bool isMem32_RC128X() const {
356 return isMem32() && X86II::isXMMReg(Mem.IndexReg);
357 }
358 bool isMem64_RC128X() const {
359 return isMem64() && X86II::isXMMReg(Mem.IndexReg);
360 }
361 bool isMem32_RC256X() const {
362 return isMem32() && X86II::isYMMReg(Mem.IndexReg);
363 }
364 bool isMem64_RC256X() const {
365 return isMem64() && X86II::isYMMReg(Mem.IndexReg);
366 }
367 bool isMem32_RC512() const {
368 return isMem32() && X86II::isZMMReg(Mem.IndexReg);
369 }
370 bool isMem64_RC512() const {
371 return isMem64() && X86II::isZMMReg(Mem.IndexReg);
372 }
373
374 bool isMem512_GR16() const {
375 if (!isMem512())
376 return false;
377 if (getMemBaseReg() &&
378 !X86MCRegisterClasses[X86::GR16RegClassID].contains(getMemBaseReg()))
379 return false;
380 return true;
381 }
382 bool isMem512_GR32() const {
383 if (!isMem512())
384 return false;
385 if (getMemBaseReg() &&
386 !X86MCRegisterClasses[X86::GR32RegClassID].contains(getMemBaseReg()) &&
387 getMemBaseReg() != X86::EIP)
388 return false;
389 if (getMemIndexReg() &&
390 !X86MCRegisterClasses[X86::GR32RegClassID].contains(getMemIndexReg()) &&
391 getMemIndexReg() != X86::EIZ)
392 return false;
393 return true;
394 }
395 bool isMem512_GR64() const {
396 if (!isMem512())
397 return false;
398 if (getMemBaseReg() &&
399 !X86MCRegisterClasses[X86::GR64RegClassID].contains(getMemBaseReg()) &&
400 getMemBaseReg() != X86::RIP)
401 return false;
402 if (getMemIndexReg() &&
403 !X86MCRegisterClasses[X86::GR64RegClassID].contains(getMemIndexReg()) &&
404 getMemIndexReg() != X86::RIZ)
405 return false;
406 return true;
407 }
408
409 bool isAbsMem() const {
410 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
412 }
413
414 bool isAVX512RC() const{
415 return isImm();
416 }
417
418 bool isAbsMemMode16() const { return isAbsMem() && Mem.ModeSize == 16; }
419
420 bool isDispImm8() const {
421 if (auto *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
422 return isImmSExti64i8Value(CE->getValue());
423 return true;
424 }
425
426 bool isAbsMem8() const { return isAbsMem() && isMem8() && isDispImm8(); }
427
428 bool isMemUseUpRegs() const override { return UseUpRegs; }
429
430 bool isSrcIdx() const {
431 return !getMemIndexReg() && getMemScale() == 1 &&
432 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
433 getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
434 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
435 }
436 bool isSrcIdx8() const {
437 return isMem8() && isSrcIdx();
438 }
439 bool isSrcIdx16() const {
440 return isMem16() && isSrcIdx();
441 }
442 bool isSrcIdx32() const {
443 return isMem32() && isSrcIdx();
444 }
445 bool isSrcIdx64() const {
446 return isMem64() && isSrcIdx();
447 }
448
449 bool isDstIdx() const {
450 return !getMemIndexReg() && getMemScale() == 1 &&
451 (!getMemSegReg() || getMemSegReg() == X86::ES) &&
452 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
453 getMemBaseReg() == X86::DI) &&
454 isa<MCConstantExpr>(getMemDisp()) &&
455 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
456 }
457 bool isDstIdx8() const {
458 return isMem8() && isDstIdx();
459 }
460 bool isDstIdx16() const {
461 return isMem16() && isDstIdx();
462 }
463 bool isDstIdx32() const {
464 return isMem32() && isDstIdx();
465 }
466 bool isDstIdx64() const {
467 return isMem64() && isDstIdx();
468 }
469
470 bool isMemOffs() const {
471 return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
472 getMemScale() == 1;
473 }
474
475 bool isMemOffs16_8() const {
476 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
477 }
478 bool isMemOffs16_16() const {
479 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
480 }
481 bool isMemOffs16_32() const {
482 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
483 }
484 bool isMemOffs32_8() const {
485 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
486 }
487 bool isMemOffs32_16() const {
488 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
489 }
490 bool isMemOffs32_32() const {
491 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
492 }
493 bool isMemOffs32_64() const {
494 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
495 }
496 bool isMemOffs64_8() const {
497 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
498 }
499 bool isMemOffs64_16() const {
500 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
501 }
502 bool isMemOffs64_32() const {
503 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
504 }
505 bool isMemOffs64_64() const {
506 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
507 }
508
509 bool isPrefix() const { return Kind == Prefix; }
510 bool isReg() const override { return Kind == Register; }
511 bool isDXReg() const { return Kind == DXRegister; }
512
513 bool isGR32orGR64() const {
514 return Kind == Register &&
515 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
516 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
517 }
518
519 bool isGR16orGR32orGR64() const {
520 return Kind == Register &&
521 (X86MCRegisterClasses[X86::GR16RegClassID].contains(getReg()) ||
522 X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
523 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
524 }
525
526 bool isVectorReg() const {
527 return Kind == Register &&
528 (X86MCRegisterClasses[X86::VR64RegClassID].contains(getReg()) ||
529 X86MCRegisterClasses[X86::VR128XRegClassID].contains(getReg()) ||
530 X86MCRegisterClasses[X86::VR256XRegClassID].contains(getReg()) ||
531 X86MCRegisterClasses[X86::VR512RegClassID].contains(getReg()));
532 }
533
534 bool isVK1Pair() const {
535 return Kind == Register &&
536 X86MCRegisterClasses[X86::VK1RegClassID].contains(getReg());
537 }
538
539 bool isVK2Pair() const {
540 return Kind == Register &&
541 X86MCRegisterClasses[X86::VK2RegClassID].contains(getReg());
542 }
543
544 bool isVK4Pair() const {
545 return Kind == Register &&
546 X86MCRegisterClasses[X86::VK4RegClassID].contains(getReg());
547 }
548
549 bool isVK8Pair() const {
550 return Kind == Register &&
551 X86MCRegisterClasses[X86::VK8RegClassID].contains(getReg());
552 }
553
554 bool isVK16Pair() const {
555 return Kind == Register &&
556 X86MCRegisterClasses[X86::VK16RegClassID].contains(getReg());
557 }
558
559 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
560 // Add as immediates when possible.
561 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
562 Inst.addOperand(MCOperand::createImm(CE->getValue()));
563 else
565 }
566
567 void addRegOperands(MCInst &Inst, unsigned N) const {
568 assert(N == 1 && "Invalid number of operands!");
570 }
571
572 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
573 assert(N == 1 && "Invalid number of operands!");
574 MCRegister RegNo = getReg();
575 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
576 RegNo = getX86SubSuperRegister(RegNo, 32);
577 Inst.addOperand(MCOperand::createReg(RegNo));
578 }
579
580 void addGR16orGR32orGR64Operands(MCInst &Inst, unsigned N) const {
581 assert(N == 1 && "Invalid number of operands!");
582 MCRegister RegNo = getReg();
583 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo) ||
584 X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
585 RegNo = getX86SubSuperRegister(RegNo, 16);
586 Inst.addOperand(MCOperand::createReg(RegNo));
587 }
588
589 void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
590 assert(N == 1 && "Invalid number of operands!");
591 addExpr(Inst, getImm());
592 }
593
594 void addImmOperands(MCInst &Inst, unsigned N) const {
595 assert(N == 1 && "Invalid number of operands!");
596 addExpr(Inst, getImm());
597 }
598
599 void addMaskPairOperands(MCInst &Inst, unsigned N) const {
600 assert(N == 1 && "Invalid number of operands!");
602 switch (Reg.id()) {
603 case X86::K0:
604 case X86::K1:
605 Reg = X86::K0_K1;
606 break;
607 case X86::K2:
608 case X86::K3:
609 Reg = X86::K2_K3;
610 break;
611 case X86::K4:
612 case X86::K5:
613 Reg = X86::K4_K5;
614 break;
615 case X86::K6:
616 case X86::K7:
617 Reg = X86::K6_K7;
618 break;
619 }
621 }
622
623 bool isTILEPair() const {
624 return Kind == Register &&
625 X86MCRegisterClasses[X86::TILERegClassID].contains(getReg());
626 }
627
628 void addTILEPairOperands(MCInst &Inst, unsigned N) const {
629 assert(N == 1 && "Invalid number of operands!");
631 switch (Reg.id()) {
632 default:
633 llvm_unreachable("Invalid tile register!");
634 case X86::TMM0:
635 case X86::TMM1:
636 Reg = X86::TMM0_TMM1;
637 break;
638 case X86::TMM2:
639 case X86::TMM3:
640 Reg = X86::TMM2_TMM3;
641 break;
642 case X86::TMM4:
643 case X86::TMM5:
644 Reg = X86::TMM4_TMM5;
645 break;
646 case X86::TMM6:
647 case X86::TMM7:
648 Reg = X86::TMM6_TMM7;
649 break;
650 }
652 }
653
654 void addMemOperands(MCInst &Inst, unsigned N) const {
655 assert((N == 5) && "Invalid number of operands!");
656 if (getMemBaseReg())
658 else
662 addExpr(Inst, getMemDisp());
664 }
665
666 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
667 assert((N == 1) && "Invalid number of operands!");
668 // Add as immediates when possible.
669 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
670 Inst.addOperand(MCOperand::createImm(CE->getValue()));
671 else
673 }
674
675 void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
676 assert((N == 2) && "Invalid number of operands!");
679 }
680
681 void addDstIdxOperands(MCInst &Inst, unsigned N) const {
682 assert((N == 1) && "Invalid number of operands!");
684 }
685
686 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
687 assert((N == 2) && "Invalid number of operands!");
688 // Add as immediates when possible.
689 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
690 Inst.addOperand(MCOperand::createImm(CE->getValue()));
691 else
694 }
695
696 static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
697 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
698 auto Res = std::make_unique<X86Operand>(Token, Loc, EndLoc);
699 Res->Tok.Data = Str.data();
700 Res->Tok.Length = Str.size();
701 return Res;
702 }
703
704 static std::unique_ptr<X86Operand>
706 bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
707 StringRef SymName = StringRef(), void *OpDecl = nullptr) {
708 auto Res = std::make_unique<X86Operand>(Register, StartLoc, EndLoc);
709 Res->Reg.RegNo = Reg;
710 Res->AddressOf = AddressOf;
711 Res->OffsetOfLoc = OffsetOfLoc;
712 Res->SymName = SymName;
713 Res->OpDecl = OpDecl;
714 return Res;
715 }
716
717 static std::unique_ptr<X86Operand>
719 return std::make_unique<X86Operand>(DXRegister, StartLoc, EndLoc);
720 }
721
722 static std::unique_ptr<X86Operand>
723 CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {
724 auto Res = std::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);
725 Res->Pref.Prefixes = Prefixes;
726 return Res;
727 }
728
729 static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
732 void *OpDecl = nullptr,
733 bool GlobalRef = true) {
734 auto Res = std::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
735 Res->Imm.Val = Val;
736 Res->Imm.LocalRef = !GlobalRef;
737 Res->SymName = SymName;
738 Res->OpDecl = OpDecl;
739 Res->AddressOf = true;
740 return Res;
741 }
742
743 /// Create an absolute memory operand.
744 static std::unique_ptr<X86Operand>
745 CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
746 unsigned Size = 0, StringRef SymName = StringRef(),
747 void *OpDecl = nullptr, unsigned FrontendSize = 0,
748 bool UseUpRegs = false, bool MaybeDirectBranchDest = true) {
749 auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
750 Res->Mem.SegReg = MCRegister();
751 Res->Mem.Disp = Disp;
752 Res->Mem.BaseReg = MCRegister();
753 Res->Mem.DefaultBaseReg = MCRegister();
754 Res->Mem.IndexReg = MCRegister();
755 Res->Mem.Scale = 1;
756 Res->Mem.Size = Size;
757 Res->Mem.ModeSize = ModeSize;
758 Res->Mem.FrontendSize = FrontendSize;
759 Res->Mem.MaybeDirectBranchDest = MaybeDirectBranchDest;
760 Res->UseUpRegs = UseUpRegs;
761 Res->SymName = SymName;
762 Res->OpDecl = OpDecl;
763 Res->AddressOf = false;
764 return Res;
765 }
766
767 /// Create a generalized memory operand.
768 static std::unique_ptr<X86Operand>
769 CreateMem(unsigned ModeSize, MCRegister SegReg, const MCExpr *Disp,
770 MCRegister BaseReg, MCRegister IndexReg, unsigned Scale,
771 SMLoc StartLoc, SMLoc EndLoc, unsigned Size = 0,
772 MCRegister DefaultBaseReg = MCRegister(),
773 StringRef SymName = StringRef(), void *OpDecl = nullptr,
774 unsigned FrontendSize = 0, bool UseUpRegs = false,
775 bool MaybeDirectBranchDest = true) {
776 // We should never just have a displacement, that should be parsed as an
777 // absolute memory operand.
778 assert((SegReg || BaseReg || IndexReg || DefaultBaseReg) &&
779 "Invalid memory operand!");
780
781 // The scale should always be one of {1,2,4,8}.
782 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
783 "Invalid scale!");
784 auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
785 Res->Mem.SegReg = SegReg;
786 Res->Mem.Disp = Disp;
787 Res->Mem.BaseReg = BaseReg;
788 Res->Mem.DefaultBaseReg = DefaultBaseReg;
789 Res->Mem.IndexReg = IndexReg;
790 Res->Mem.Scale = Scale;
791 Res->Mem.Size = Size;
792 Res->Mem.ModeSize = ModeSize;
793 Res->Mem.FrontendSize = FrontendSize;
794 Res->Mem.MaybeDirectBranchDest = MaybeDirectBranchDest;
795 Res->UseUpRegs = UseUpRegs;
796 Res->SymName = SymName;
797 Res->OpDecl = OpDecl;
798 Res->AddressOf = false;
799 return Res;
800 }
801};
802
803} // end namespace llvm
804
805#endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t Size
bool End
Definition: ELF_riscv.cpp:480
Symbol * Sym
Definition: ELF_riscv.cpp:479
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:480
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:64
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
@ Constant
Constant expressions.
Definition: MCExpr.h:42
@ SymbolRef
References to labels and assigned expressions.
Definition: MCExpr.h:43
ExprKind getKind() const
Definition: MCExpr.h:85
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:188
void addOperand(const MCOperand Op)
Definition: MCInst.h:215
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:166
static MCOperand createReg(MCRegister Reg)
Definition: MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:145
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Represents a location in source code.
Definition: SMLoc.h:23
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
constexpr const char * getPointer() const
Definition: SMLoc.h:34
Represents a range in source code.
Definition: SMLoc.h:48
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
LLVM Value Representation.
Definition: Value.h:75
static const char * getRegisterName(MCRegister Reg)
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
This class provides various memory handling functions that manipulate MemoryBlock instances.
Definition: Memory.h:54
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isZMMReg(MCRegister Reg)
Definition: X86BaseInfo.h:1179
bool isXMMReg(MCRegister Reg)
Definition: X86BaseInfo.h:1159
bool isYMMReg(MCRegister Reg)
Definition: X86BaseInfo.h:1169
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool isImmSExti64i32Value(uint64_t Value)
MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)
bool isImmUnsignedi4Value(uint64_t Value)
bool isImmSExti64i8Value(uint64_t Value)
bool isImmUnsignedi8Value(uint64_t Value)
bool isImmSExti16i8Value(uint64_t Value)
bool isImmSExti32i8Value(uint64_t Value)
#define N
const MCExpr * Val
Definition: X86Operand.h:58
bool MaybeDirectBranchDest
If false, then this operand must be a memory operand for an indirect branch instruction.
Definition: X86Operand.h:79
unsigned FrontendSize
If the memory operand is unsized and there are multiple instruction matches, prefer the one with this...
Definition: X86Operand.h:74
MCRegister DefaultBaseReg
Definition: X86Operand.h:66
const MCExpr * Disp
Definition: X86Operand.h:64
X86Operand - Instances of this class represent a parsed X86 machine instruction.
Definition: X86Operand.h:31
bool isMemOffs64_64() const
Definition: X86Operand.h:505
SMLoc getStartLoc() const override
getStartLoc - Get the location of the first token of this operand.
Definition: X86Operand.h:98
bool isVK8Pair() const
Definition: X86Operand.h:549
enum llvm::X86Operand::KindTy Kind
bool isMem64_RC256X() const
Definition: X86Operand.h:364
bool isPrefix() const
Definition: X86Operand.h:509
bool isTILEPair() const
Definition: X86Operand.h:623
void addAVX512RCOperands(MCInst &Inst, unsigned N) const
Definition: X86Operand.h:589
bool isImm() const override
isImm - Is this an immediate operand?
Definition: X86Operand.h:223
bool isMemUseUpRegs() const override
isMemUseUpRegs - Is memory operand use up regs, for example, intel MS inline asm may use ARR[baseReg ...
Definition: X86Operand.h:428
bool isMemOffs64_32() const
Definition: X86Operand.h:502
static std::unique_ptr< X86Operand > CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc, StringRef SymName=StringRef(), void *OpDecl=nullptr, bool GlobalRef=true)
Definition: X86Operand.h:729
void addMaskPairOperands(MCInst &Inst, unsigned N) const
Definition: X86Operand.h:599
void addExpr(MCInst &Inst, const MCExpr *Expr) const
Definition: X86Operand.h:559
bool isImmSExti64i32() const
Definition: X86Operand.h:267
X86Operand(KindTy K, SMLoc Start, SMLoc End)
Definition: X86Operand.h:90
MCRegister getMemSegReg() const
Definition: X86Operand.h:188
bool isMem64() const
Definition: X86Operand.h:317
bool isOffsetOfLocal() const override
isOffsetOfLocal - Do we need to emit code to get the offset of the local variable,...
Definition: X86Operand.h:300
void addGR16orGR32orGR64Operands(MCInst &Inst, unsigned N) const
Definition: X86Operand.h:580
bool isMem512_GR16() const
Definition: X86Operand.h:374
static std::unique_ptr< X86Operand > CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc)
Definition: X86Operand.h:723
bool isMemOffs32_32() const
Definition: X86Operand.h:490
static std::unique_ptr< X86Operand > CreateDXReg(SMLoc StartLoc, SMLoc EndLoc)
Definition: X86Operand.h:718
bool UseUpRegs
This used for inline asm which may specify base reg and index reg for MemOp.
Definition: X86Operand.h:42
bool isImmSExti64i8() const
Definition: X86Operand.h:253
bool isMaybeDirectBranchDest() const
Definition: X86Operand.h:216
void addTILEPairOperands(MCInst &Inst, unsigned N) const
Definition: X86Operand.h:628
void addAbsMemOperands(MCInst &Inst, unsigned N) const
Definition: X86Operand.h:666
bool isGR32orGR64() const
Definition: X86Operand.h:513
void addImmOperands(MCInst &Inst, unsigned N) const
Definition: X86Operand.h:594
bool isSrcIdx8() const
Definition: X86Operand.h:436
void print(raw_ostream &OS, const MCAsmInfo &) const override
print - Print a debug representation of the operand to the given stream.
Definition: X86Operand.h:110
bool isSrcIdx() const
Definition: X86Operand.h:430
void setTokenValue(StringRef Value)
Definition: X86Operand.h:163
bool isMem512_GR64() const
Definition: X86Operand.h:395
void addMemOffsOperands(MCInst &Inst, unsigned N) const
Definition: X86Operand.h:686
bool isImmUnsignedi8() const
Definition: X86Operand.h:291
void addSrcIdxOperands(MCInst &Inst, unsigned N) const
Definition: X86Operand.h:675
bool isMem16() const
Definition: X86Operand.h:311
bool isMem32_RC256X() const
Definition: X86Operand.h:361
bool isSrcIdx32() const
Definition: X86Operand.h:442
bool isVK1Pair() const
Definition: X86Operand.h:534
bool isAbsMemMode16() const
Definition: X86Operand.h:418
void * getOpDecl() override
Definition: X86Operand.h:95
bool isMem128() const
Definition: X86Operand.h:323
bool isMemOffs32_8() const
Definition: X86Operand.h:484
bool isSibMem() const
Definition: X86Operand.h:333
static std::unique_ptr< X86Operand > CreateReg(MCRegister Reg, SMLoc StartLoc, SMLoc EndLoc, bool AddressOf=false, SMLoc OffsetOfLoc=SMLoc(), StringRef SymName=StringRef(), void *OpDecl=nullptr)
Definition: X86Operand.h:705
bool isMemOffs64_8() const
Definition: X86Operand.h:496
bool isDstIdx8() const
Definition: X86Operand.h:457
bool isImmSExti16i8() const
Definition: X86Operand.h:225
SMRange getLocRange() const
getLocRange - Get the range between the first and last token of this operand.
Definition: X86Operand.h:105
bool isMem32_RC512() const
Definition: X86Operand.h:367
bool isMem512() const
Definition: X86Operand.h:329
MCRegister getMemBaseReg() const
Definition: X86Operand.h:192
unsigned getMemScale() const
Definition: X86Operand.h:204
SMLoc getEndLoc() const override
getEndLoc - Get the location of the last token of this operand.
Definition: X86Operand.h:101
bool isReg() const override
isReg - Is this a register operand?
Definition: X86Operand.h:510
bool isMem() const override
isMem - Is this a memory operand?
Definition: X86Operand.h:304
bool isImmUnsignedi4() const
Definition: X86Operand.h:282
bool isAVX512RC() const
Definition: X86Operand.h:414
const MCExpr * getMemDisp() const
Definition: X86Operand.h:184
bool isMemOffs16_8() const
Definition: X86Operand.h:475
unsigned getPrefix() const
Definition: X86Operand.h:174
bool isMem512_GR32() const
Definition: X86Operand.h:382
bool isVK4Pair() const
Definition: X86Operand.h:544
struct ImmOp Imm
Definition: X86Operand.h:85
static std::unique_ptr< X86Operand > CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size=0, StringRef SymName=StringRef(), void *OpDecl=nullptr, unsigned FrontendSize=0, bool UseUpRegs=false, bool MaybeDirectBranchDest=true)
Create an absolute memory operand.
Definition: X86Operand.h:745
struct MemOp Mem
Definition: X86Operand.h:86
bool isImmSExti32i8() const
Definition: X86Operand.h:239
void addGR32orGR64Operands(MCInst &Inst, unsigned N) const
Definition: X86Operand.h:572
bool isDstIdx64() const
Definition: X86Operand.h:466
bool isMemOffs() const
Definition: X86Operand.h:470
bool isDXReg() const
Definition: X86Operand.h:511
bool isMem32_RC128X() const
Definition: X86Operand.h:355
bool isMem64_RC512() const
Definition: X86Operand.h:370
bool isDispImm8() const
Definition: X86Operand.h:420
bool isMem64_RC128() const
Definition: X86Operand.h:345
bool isMemIndexReg(unsigned LowR, unsigned HighR) const
Definition: X86Operand.h:337
StringRef SymName
Definition: X86Operand.h:36
bool isMemOffs32_16() const
Definition: X86Operand.h:487
bool isMem256() const
Definition: X86Operand.h:326
bool isMem32() const
Definition: X86Operand.h:314
bool isVK2Pair() const
Definition: X86Operand.h:539
void addMemOperands(MCInst &Inst, unsigned N) const
Definition: X86Operand.h:654
void addRegOperands(MCInst &Inst, unsigned N) const
Definition: X86Operand.h:567
void addDstIdxOperands(MCInst &Inst, unsigned N) const
Definition: X86Operand.h:681
struct RegOp Reg
Definition: X86Operand.h:84
static std::unique_ptr< X86Operand > CreateMem(unsigned ModeSize, MCRegister SegReg, const MCExpr *Disp, MCRegister BaseReg, MCRegister IndexReg, unsigned Scale, SMLoc StartLoc, SMLoc EndLoc, unsigned Size=0, MCRegister DefaultBaseReg=MCRegister(), StringRef SymName=StringRef(), void *OpDecl=nullptr, unsigned FrontendSize=0, bool UseUpRegs=false, bool MaybeDirectBranchDest=true)
Create a generalized memory operand.
Definition: X86Operand.h:769
bool isDstIdx16() const
Definition: X86Operand.h:460
unsigned getMemModeSize() const
Definition: X86Operand.h:208
bool isVK16Pair() const
Definition: X86Operand.h:554
bool isVectorReg() const
Definition: X86Operand.h:526
bool isDstIdx32() const
Definition: X86Operand.h:463
bool isMem64_RC256() const
Definition: X86Operand.h:351
bool isMemOffs64_16() const
Definition: X86Operand.h:499
bool needAddressOf() const override
needAddressOf - Do we need to emit code to get the address of the variable/label? Only valid when par...
Definition: X86Operand.h:302
bool isDstIdx() const
Definition: X86Operand.h:449
bool isAbsMem() const
Definition: X86Operand.h:409
MCRegister getMemDefaultBaseReg() const
Definition: X86Operand.h:196
static std::unique_ptr< X86Operand > CreateToken(StringRef Str, SMLoc Loc)
Definition: X86Operand.h:696
bool isMemUnsized() const
Definition: X86Operand.h:305
const MCExpr * getImm() const
Definition: X86Operand.h:179
SMLoc getOffsetOfLoc() const override
getOffsetOfLoc - Get the location of the offset operator.
Definition: X86Operand.h:108
MCRegister getMemIndexReg() const
Definition: X86Operand.h:200
bool isMem32_RC128() const
Definition: X86Operand.h:342
bool isMem32_RC256() const
Definition: X86Operand.h:348
bool isMemOffs16_16() const
Definition: X86Operand.h:478
StringRef getToken() const
Definition: X86Operand.h:159
bool isAbsMem8() const
Definition: X86Operand.h:426
unsigned getMemFrontendSize() const
Definition: X86Operand.h:212
bool isMem8() const
Definition: X86Operand.h:308
struct PrefOp Pref
Definition: X86Operand.h:87
bool isMem80() const
Definition: X86Operand.h:320
MCRegister getReg() const override
Definition: X86Operand.h:169
struct TokOp Tok
Definition: X86Operand.h:83
bool isMemOffs16_32() const
Definition: X86Operand.h:481
bool isSrcIdx16() const
Definition: X86Operand.h:439
bool isMemOffs32_64() const
Definition: X86Operand.h:493
bool isToken() const override
isToken - Is this a token operand?
Definition: X86Operand.h:221
bool isMem64_RC128X() const
Definition: X86Operand.h:358
StringRef getSymName() override
Definition: X86Operand.h:94
bool isGR16orGR32orGR64() const
Definition: X86Operand.h:519
bool isSrcIdx64() const
Definition: X86Operand.h:445