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 
12 #include "MCTargetDesc/X86IntelInstPrinter.h"
13 #include "MCTargetDesc/X86MCTargetDesc.h"
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"
19 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
20 #include "llvm/Support/Casting.h"
21 #include "llvm/Support/SMLoc.h"
22 #include <cassert>
23 #include <memory>
24 
25 namespace llvm {
26 
27 /// X86Operand - Instances of this class represent a parsed X86 machine
28 /// instruction.
29 struct X86Operand final : public MCParsedAsmOperand {
30   enum KindTy { Token, Register, Immediate, Memory, Prefix, DXRegister } Kind;
31 
32   SMLoc StartLoc, EndLoc;
33   SMLoc OffsetOfLoc;
34   StringRef SymName;
35   void *OpDecl;
36   bool AddressOf;
37   bool CallOperand;
38 
39   struct TokOp {
40     const char *Data;
41     unsigned Length;
42   };
43 
44   struct RegOp {
45     unsigned RegNo;
46   };
47 
48   struct PrefOp {
49     unsigned Prefixes;
50   };
51 
52   struct ImmOp {
53     const MCExpr *Val;
54     bool LocalRef;
55   };
56 
57   struct MemOp {
58     unsigned SegReg;
59     const MCExpr *Disp;
60     unsigned BaseReg;
61     unsigned DefaultBaseReg;
62     unsigned IndexReg;
63     unsigned Scale;
64     unsigned Size;
65     unsigned ModeSize;
66 
67     /// If the memory operand is unsized and there are multiple instruction
68     /// matches, prefer the one with this size.
69     unsigned FrontendSize;
70   };
71 
72   union {
73     struct TokOp Tok;
74     struct RegOp Reg;
75     struct ImmOp Imm;
76     struct MemOp Mem;
77     struct PrefOp Pref;
78   };
79 
X86Operandfinal80   X86Operand(KindTy K, SMLoc Start, SMLoc End)
81       : Kind(K), StartLoc(Start), EndLoc(End), CallOperand(false) {}
82 
getSymNamefinal83   StringRef getSymName() override { return SymName; }
getOpDeclfinal84   void *getOpDecl() override { return OpDecl; }
85 
86   /// getStartLoc - Get the location of the first token of this operand.
getStartLocfinal87   SMLoc getStartLoc() const override { return StartLoc; }
88 
89   /// getEndLoc - Get the location of the last token of this operand.
getEndLocfinal90   SMLoc getEndLoc() const override { return EndLoc; }
91 
92   /// getLocRange - Get the range between the first and last token of this
93   /// operand.
getLocRangefinal94   SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
95 
96   /// getOffsetOfLoc - Get the location of the offset operator.
getOffsetOfLocfinal97   SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
98 
printfinal99   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 (const char *SymNameStr = Sym.getName().data())
109             OS << VName << SymNameStr;
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 DXRegister:
122       OS << "DXReg";
123       break;
124     case Immediate:
125       PrintImmValue(Imm.Val, "Imm:");
126       break;
127     case Prefix:
128       OS << "Prefix:" << Pref.Prefixes;
129       break;
130     case Memory:
131       OS << "Memory: ModeSize=" << Mem.ModeSize;
132       if (Mem.Size)
133         OS << ",Size=" << Mem.Size;
134       if (Mem.BaseReg)
135         OS << ",BaseReg=" << X86IntelInstPrinter::getRegisterName(Mem.BaseReg);
136       if (Mem.IndexReg)
137         OS << ",IndexReg="
138            << X86IntelInstPrinter::getRegisterName(Mem.IndexReg);
139       if (Mem.Scale)
140         OS << ",Scale=" << Mem.Scale;
141       if (Mem.Disp)
142         PrintImmValue(Mem.Disp, ",Disp=");
143       if (Mem.SegReg)
144         OS << ",SegReg=" << X86IntelInstPrinter::getRegisterName(Mem.SegReg);
145       break;
146     }
147   }
148 
getTokenfinal149   StringRef getToken() const {
150     assert(Kind == Token && "Invalid access!");
151     return StringRef(Tok.Data, Tok.Length);
152   }
setTokenValuefinal153   void setTokenValue(StringRef Value) {
154     assert(Kind == Token && "Invalid access!");
155     Tok.Data = Value.data();
156     Tok.Length = Value.size();
157   }
158 
getRegfinal159   unsigned getReg() const override {
160     assert(Kind == Register && "Invalid access!");
161     return Reg.RegNo;
162   }
163 
getPrefixfinal164   unsigned getPrefix() const {
165     assert(Kind == Prefix && "Invalid access!");
166     return Pref.Prefixes;
167   }
168 
getImmfinal169   const MCExpr *getImm() const {
170     assert(Kind == Immediate && "Invalid access!");
171     return Imm.Val;
172   }
173 
getMemDispfinal174   const MCExpr *getMemDisp() const {
175     assert(Kind == Memory && "Invalid access!");
176     return Mem.Disp;
177   }
getMemSegRegfinal178   unsigned getMemSegReg() const {
179     assert(Kind == Memory && "Invalid access!");
180     return Mem.SegReg;
181   }
getMemBaseRegfinal182   unsigned getMemBaseReg() const {
183     assert(Kind == Memory && "Invalid access!");
184     return Mem.BaseReg;
185   }
getMemDefaultBaseRegfinal186   unsigned getMemDefaultBaseReg() const {
187     assert(Kind == Memory && "Invalid access!");
188     return Mem.DefaultBaseReg;
189   }
getMemIndexRegfinal190   unsigned getMemIndexReg() const {
191     assert(Kind == Memory && "Invalid access!");
192     return Mem.IndexReg;
193   }
getMemScalefinal194   unsigned getMemScale() const {
195     assert(Kind == Memory && "Invalid access!");
196     return Mem.Scale;
197   }
getMemModeSizefinal198   unsigned getMemModeSize() const {
199     assert(Kind == Memory && "Invalid access!");
200     return Mem.ModeSize;
201   }
getMemFrontendSizefinal202   unsigned getMemFrontendSize() const {
203     assert(Kind == Memory && "Invalid access!");
204     return Mem.FrontendSize;
205   }
206 
isTokenfinal207   bool isToken() const override {return Kind == Token; }
208 
isImmfinal209   bool isImm() const override { return Kind == Immediate; }
210 
isImmSExti16i8final211   bool isImmSExti16i8() const {
212     if (!isImm())
213       return false;
214 
215     // If this isn't a constant expr, just assume it fits and let relaxation
216     // handle it.
217     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
218     if (!CE)
219       return true;
220 
221     // Otherwise, check the value is in a range that makes sense for this
222     // extension.
223     return isImmSExti16i8Value(CE->getValue());
224   }
isImmSExti32i8final225   bool isImmSExti32i8() 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 isImmSExti32i8Value(CE->getValue());
238   }
isImmSExti64i8final239   bool isImmSExti64i8() 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 isImmSExti64i8Value(CE->getValue());
252   }
isImmSExti64i32final253   bool isImmSExti64i32() 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 isImmSExti64i32Value(CE->getValue());
266   }
267 
isImmUnsignedi4final268   bool isImmUnsignedi4() const {
269     if (!isImm()) return false;
270     // If this isn't a constant expr, reject it. The immediate byte is shared
271     // with a register encoding. We can't have it affected by a relocation.
272     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
273     if (!CE) return false;
274     return isImmUnsignedi4Value(CE->getValue());
275   }
276 
isImmUnsignedi8final277   bool isImmUnsignedi8() const {
278     if (!isImm()) return false;
279     // If this isn't a constant expr, just assume it fits and let relaxation
280     // handle it.
281     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
282     if (!CE) return true;
283     return isImmUnsignedi8Value(CE->getValue());
284   }
285 
isOffsetOfLocalfinal286   bool isOffsetOfLocal() const override { return isImm() && Imm.LocalRef; }
287 
needAddressOffinal288   bool needAddressOf() const override { return AddressOf; }
289 
isMemfinal290   bool isMem() const override { return Kind == Memory; }
isMemUnsizedfinal291   bool isMemUnsized() const {
292     return Kind == Memory && Mem.Size == 0;
293   }
isMem8final294   bool isMem8() const {
295     return Kind == Memory && (!Mem.Size || Mem.Size == 8);
296   }
isMem16final297   bool isMem16() const {
298     return Kind == Memory && (!Mem.Size || Mem.Size == 16);
299   }
isMem32final300   bool isMem32() const {
301     return Kind == Memory && (!Mem.Size || Mem.Size == 32);
302   }
isMem64final303   bool isMem64() const {
304     return Kind == Memory && (!Mem.Size || Mem.Size == 64);
305   }
isMem80final306   bool isMem80() const {
307     return Kind == Memory && (!Mem.Size || Mem.Size == 80);
308   }
isMem128final309   bool isMem128() const {
310     return Kind == Memory && (!Mem.Size || Mem.Size == 128);
311   }
isMem256final312   bool isMem256() const {
313     return Kind == Memory && (!Mem.Size || Mem.Size == 256);
314   }
isMem512final315   bool isMem512() const {
316     return Kind == Memory && (!Mem.Size || Mem.Size == 512);
317   }
318 
isSibMemfinal319   bool isSibMem() const {
320     return isMem() && Mem.BaseReg != X86::RIP && Mem.BaseReg != X86::EIP;
321   }
322 
isMemIndexRegfinal323   bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
324     assert(Kind == Memory && "Invalid access!");
325     return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
326   }
327 
isMem64_RC128final328   bool isMem64_RC128() const {
329     return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
330   }
isMem128_RC128final331   bool isMem128_RC128() const {
332     return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
333   }
isMem128_RC256final334   bool isMem128_RC256() const {
335     return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
336   }
isMem256_RC128final337   bool isMem256_RC128() const {
338     return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
339   }
isMem256_RC256final340   bool isMem256_RC256() const {
341     return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
342   }
343 
isMem64_RC128Xfinal344   bool isMem64_RC128X() const {
345     return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
346   }
isMem128_RC128Xfinal347   bool isMem128_RC128X() const {
348     return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
349   }
isMem128_RC256Xfinal350   bool isMem128_RC256X() const {
351     return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
352   }
isMem256_RC128Xfinal353   bool isMem256_RC128X() const {
354     return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
355   }
isMem256_RC256Xfinal356   bool isMem256_RC256X() const {
357     return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
358   }
isMem256_RC512final359   bool isMem256_RC512() const {
360     return isMem256() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
361   }
isMem512_RC256Xfinal362   bool isMem512_RC256X() const {
363     return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
364   }
isMem512_RC512final365   bool isMem512_RC512() const {
366     return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
367   }
368 
isAbsMemfinal369   bool isAbsMem() const {
370     return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
371       !getMemIndexReg() && getMemScale() == 1;
372   }
isAVX512RCfinal373   bool isAVX512RC() const{
374       return isImm();
375   }
376 
isAbsMem16final377   bool isAbsMem16() const {
378     return isAbsMem() && Mem.ModeSize == 16;
379   }
380 
isSrcIdxfinal381   bool isSrcIdx() const {
382     return !getMemIndexReg() && getMemScale() == 1 &&
383       (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
384        getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
385       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
386   }
isSrcIdx8final387   bool isSrcIdx8() const {
388     return isMem8() && isSrcIdx();
389   }
isSrcIdx16final390   bool isSrcIdx16() const {
391     return isMem16() && isSrcIdx();
392   }
isSrcIdx32final393   bool isSrcIdx32() const {
394     return isMem32() && isSrcIdx();
395   }
isSrcIdx64final396   bool isSrcIdx64() const {
397     return isMem64() && isSrcIdx();
398   }
399 
isDstIdxfinal400   bool isDstIdx() const {
401     return !getMemIndexReg() && getMemScale() == 1 &&
402       (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
403       (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
404        getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
405       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
406   }
isDstIdx8final407   bool isDstIdx8() const {
408     return isMem8() && isDstIdx();
409   }
isDstIdx16final410   bool isDstIdx16() const {
411     return isMem16() && isDstIdx();
412   }
isDstIdx32final413   bool isDstIdx32() const {
414     return isMem32() && isDstIdx();
415   }
isDstIdx64final416   bool isDstIdx64() const {
417     return isMem64() && isDstIdx();
418   }
419 
isMemOffsfinal420   bool isMemOffs() const {
421     return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
422       getMemScale() == 1;
423   }
424 
isMemOffs16_8final425   bool isMemOffs16_8() const {
426     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
427   }
isMemOffs16_16final428   bool isMemOffs16_16() const {
429     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
430   }
isMemOffs16_32final431   bool isMemOffs16_32() const {
432     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
433   }
isMemOffs32_8final434   bool isMemOffs32_8() const {
435     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
436   }
isMemOffs32_16final437   bool isMemOffs32_16() const {
438     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
439   }
isMemOffs32_32final440   bool isMemOffs32_32() const {
441     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
442   }
isMemOffs32_64final443   bool isMemOffs32_64() const {
444     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
445   }
isMemOffs64_8final446   bool isMemOffs64_8() const {
447     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
448   }
isMemOffs64_16final449   bool isMemOffs64_16() const {
450     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
451   }
isMemOffs64_32final452   bool isMemOffs64_32() const {
453     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
454   }
isMemOffs64_64final455   bool isMemOffs64_64() const {
456     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
457   }
458 
isPrefixfinal459   bool isPrefix() const { return Kind == Prefix; }
isRegfinal460   bool isReg() const override { return Kind == Register; }
isDXRegfinal461   bool isDXReg() const { return Kind == DXRegister; }
462 
isGR32orGR64final463   bool isGR32orGR64() const {
464     return Kind == Register &&
465       (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
466        X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
467   }
468 
isGR16orGR32orGR64final469   bool isGR16orGR32orGR64() const {
470     return Kind == Register &&
471       (X86MCRegisterClasses[X86::GR16RegClassID].contains(getReg()) ||
472        X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
473        X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
474   }
475 
isVectorRegfinal476   bool isVectorReg() const {
477     return Kind == Register &&
478            (X86MCRegisterClasses[X86::VR64RegClassID].contains(getReg()) ||
479             X86MCRegisterClasses[X86::VR128XRegClassID].contains(getReg()) ||
480             X86MCRegisterClasses[X86::VR256XRegClassID].contains(getReg()) ||
481             X86MCRegisterClasses[X86::VR512RegClassID].contains(getReg()));
482   }
483 
isVK1Pairfinal484   bool isVK1Pair() const {
485     return Kind == Register &&
486       X86MCRegisterClasses[X86::VK1RegClassID].contains(getReg());
487   }
488 
isVK2Pairfinal489   bool isVK2Pair() const {
490     return Kind == Register &&
491       X86MCRegisterClasses[X86::VK2RegClassID].contains(getReg());
492   }
493 
isVK4Pairfinal494   bool isVK4Pair() const {
495     return Kind == Register &&
496       X86MCRegisterClasses[X86::VK4RegClassID].contains(getReg());
497   }
498 
isVK8Pairfinal499   bool isVK8Pair() const {
500     return Kind == Register &&
501       X86MCRegisterClasses[X86::VK8RegClassID].contains(getReg());
502   }
503 
isVK16Pairfinal504   bool isVK16Pair() const {
505     return Kind == Register &&
506       X86MCRegisterClasses[X86::VK16RegClassID].contains(getReg());
507   }
508 
addExprfinal509   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
510     // Add as immediates when possible.
511     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
512       Inst.addOperand(MCOperand::createImm(CE->getValue()));
513     else
514       Inst.addOperand(MCOperand::createExpr(Expr));
515   }
516 
addRegOperandsfinal517   void addRegOperands(MCInst &Inst, unsigned N) const {
518     assert(N == 1 && "Invalid number of operands!");
519     Inst.addOperand(MCOperand::createReg(getReg()));
520   }
521 
addGR32orGR64Operandsfinal522   void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
523     assert(N == 1 && "Invalid number of operands!");
524     MCRegister RegNo = getReg();
525     if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
526       RegNo = getX86SubSuperRegister(RegNo, 32);
527     Inst.addOperand(MCOperand::createReg(RegNo));
528   }
529 
addGR16orGR32orGR64Operandsfinal530   void addGR16orGR32orGR64Operands(MCInst &Inst, unsigned N) const {
531     assert(N == 1 && "Invalid number of operands!");
532     MCRegister RegNo = getReg();
533     if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo) ||
534         X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
535       RegNo = getX86SubSuperRegister(RegNo, 16);
536     Inst.addOperand(MCOperand::createReg(RegNo));
537   }
538 
addAVX512RCOperandsfinal539   void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
540     assert(N == 1 && "Invalid number of operands!");
541     addExpr(Inst, getImm());
542   }
543 
addImmOperandsfinal544   void addImmOperands(MCInst &Inst, unsigned N) const {
545     assert(N == 1 && "Invalid number of operands!");
546     addExpr(Inst, getImm());
547   }
548 
addMaskPairOperandsfinal549   void addMaskPairOperands(MCInst &Inst, unsigned N) const {
550     assert(N == 1 && "Invalid number of operands!");
551     unsigned Reg = getReg();
552     switch (Reg) {
553     case X86::K0:
554     case X86::K1:
555       Reg = X86::K0_K1;
556       break;
557     case X86::K2:
558     case X86::K3:
559       Reg = X86::K2_K3;
560       break;
561     case X86::K4:
562     case X86::K5:
563       Reg = X86::K4_K5;
564       break;
565     case X86::K6:
566     case X86::K7:
567       Reg = X86::K6_K7;
568       break;
569     }
570     Inst.addOperand(MCOperand::createReg(Reg));
571   }
572 
addMemOperandsfinal573   void addMemOperands(MCInst &Inst, unsigned N) const {
574     assert((N == 5) && "Invalid number of operands!");
575     if (getMemBaseReg())
576       Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
577     else
578       Inst.addOperand(MCOperand::createReg(getMemDefaultBaseReg()));
579     Inst.addOperand(MCOperand::createImm(getMemScale()));
580     Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
581     addExpr(Inst, getMemDisp());
582     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
583   }
584 
addAbsMemOperandsfinal585   void addAbsMemOperands(MCInst &Inst, unsigned N) const {
586     assert((N == 1) && "Invalid number of operands!");
587     // Add as immediates when possible.
588     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
589       Inst.addOperand(MCOperand::createImm(CE->getValue()));
590     else
591       Inst.addOperand(MCOperand::createExpr(getMemDisp()));
592   }
593 
addSrcIdxOperandsfinal594   void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
595     assert((N == 2) && "Invalid number of operands!");
596     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
597     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
598   }
599 
addDstIdxOperandsfinal600   void addDstIdxOperands(MCInst &Inst, unsigned N) const {
601     assert((N == 1) && "Invalid number of operands!");
602     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
603   }
604 
addMemOffsOperandsfinal605   void addMemOffsOperands(MCInst &Inst, unsigned N) const {
606     assert((N == 2) && "Invalid number of operands!");
607     // Add as immediates when possible.
608     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
609       Inst.addOperand(MCOperand::createImm(CE->getValue()));
610     else
611       Inst.addOperand(MCOperand::createExpr(getMemDisp()));
612     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
613   }
614 
CreateTokenfinal615   static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
616     SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
617     auto Res = std::make_unique<X86Operand>(Token, Loc, EndLoc);
618     Res->Tok.Data = Str.data();
619     Res->Tok.Length = Str.size();
620     return Res;
621   }
622 
623   static std::unique_ptr<X86Operand>
624   CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
625             bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
626             StringRef SymName = StringRef(), void *OpDecl = nullptr) {
627     auto Res = std::make_unique<X86Operand>(Register, StartLoc, EndLoc);
628     Res->Reg.RegNo = RegNo;
629     Res->AddressOf = AddressOf;
630     Res->OffsetOfLoc = OffsetOfLoc;
631     Res->SymName = SymName;
632     Res->OpDecl = OpDecl;
633     return Res;
634   }
635 
636   static std::unique_ptr<X86Operand>
CreateDXRegfinal637   CreateDXReg(SMLoc StartLoc, SMLoc EndLoc) {
638     return std::make_unique<X86Operand>(DXRegister, StartLoc, EndLoc);
639   }
640 
641   static std::unique_ptr<X86Operand>
CreatePrefixfinal642   CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {
643     auto Res = std::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);
644     Res->Pref.Prefixes = Prefixes;
645     return Res;
646   }
647 
648   static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
649                                                SMLoc StartLoc, SMLoc EndLoc,
650                                                StringRef SymName = StringRef(),
651                                                void *OpDecl = nullptr,
652                                                bool GlobalRef = true) {
653     auto Res = std::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
654     Res->Imm.Val      = Val;
655     Res->Imm.LocalRef = !GlobalRef;
656     Res->SymName      = SymName;
657     Res->OpDecl       = OpDecl;
658     Res->AddressOf    = true;
659     return Res;
660   }
661 
662   /// Create an absolute memory operand.
663   static std::unique_ptr<X86Operand>
664   CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
665             unsigned Size = 0, StringRef SymName = StringRef(),
666             void *OpDecl = nullptr, unsigned FrontendSize = 0) {
667     auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
668     Res->Mem.SegReg   = 0;
669     Res->Mem.Disp     = Disp;
670     Res->Mem.BaseReg  = 0;
671     Res->Mem.DefaultBaseReg = 0;
672     Res->Mem.IndexReg = 0;
673     Res->Mem.Scale    = 1;
674     Res->Mem.Size     = Size;
675     Res->Mem.ModeSize = ModeSize;
676     Res->Mem.FrontendSize = FrontendSize;
677     Res->SymName      = SymName;
678     Res->OpDecl       = OpDecl;
679     Res->AddressOf    = false;
680     return Res;
681   }
682 
683   /// Create a generalized memory operand.
684   static std::unique_ptr<X86Operand>
685   CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
686             unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
687             SMLoc EndLoc, unsigned Size = 0,
688             unsigned DefaultBaseReg = X86::NoRegister,
689             StringRef SymName = StringRef(), void *OpDecl = nullptr,
690             unsigned FrontendSize = 0) {
691     // We should never just have a displacement, that should be parsed as an
692     // absolute memory operand.
693     assert((SegReg || BaseReg || IndexReg || DefaultBaseReg) &&
694            "Invalid memory operand!");
695 
696     // The scale should always be one of {1,2,4,8}.
697     assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
698            "Invalid scale!");
699     auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
700     Res->Mem.SegReg   = SegReg;
701     Res->Mem.Disp     = Disp;
702     Res->Mem.BaseReg  = BaseReg;
703     Res->Mem.DefaultBaseReg = DefaultBaseReg;
704     Res->Mem.IndexReg = IndexReg;
705     Res->Mem.Scale    = Scale;
706     Res->Mem.Size     = Size;
707     Res->Mem.ModeSize = ModeSize;
708     Res->Mem.FrontendSize = FrontendSize;
709     Res->SymName      = SymName;
710     Res->OpDecl       = OpDecl;
711     Res->AddressOf    = false;
712     return Res;
713   }
714 };
715 
716 } // end namespace llvm
717 
718 #endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
719