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