1 //===-- X86Operand.h - Parsed X86 machine instruction --------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
11 #define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
12 
13 #include "X86AsmParserCommon.h"
14 #include "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCInst.h"
16 #include "llvm/MC/MCRegisterInfo.h"
17 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "MCTargetDesc/X86MCTargetDesc.h"
20 
21 namespace llvm {
22 
23 /// X86Operand - Instances of this class represent a parsed X86 machine
24 /// instruction.
25 struct X86Operand : public MCParsedAsmOperand {
26   enum KindTy {
27     Token,
28     Register,
29     Immediate,
30     Memory
31   } Kind;
32 
33   SMLoc StartLoc, EndLoc;
34   SMLoc OffsetOfLoc;
35   StringRef SymName;
36   void *OpDecl;
37   bool AddressOf;
38 
39   struct TokOp {
40     const char *Data;
41     unsigned Length;
42   };
43 
44   struct RegOp {
45     unsigned RegNo;
46   };
47 
48   struct ImmOp {
49     const MCExpr *Val;
50   };
51 
52   struct MemOp {
53     unsigned SegReg;
54     const MCExpr *Disp;
55     unsigned BaseReg;
56     unsigned IndexReg;
57     unsigned Scale;
58     unsigned Size;
59     unsigned ModeSize;
60   };
61 
62   union {
63     struct TokOp Tok;
64     struct RegOp Reg;
65     struct ImmOp Imm;
66     struct MemOp Mem;
67   };
68 
X86OperandX86Operand69   X86Operand(KindTy K, SMLoc Start, SMLoc End)
70     : Kind(K), StartLoc(Start), EndLoc(End) {}
71 
getSymNameX86Operand72   StringRef getSymName() override { return SymName; }
getOpDeclX86Operand73   void *getOpDecl() override { return OpDecl; }
74 
75   /// getStartLoc - Get the location of the first token of this operand.
getStartLocX86Operand76   SMLoc getStartLoc() const override { return StartLoc; }
77   /// getEndLoc - Get the location of the last token of this operand.
getEndLocX86Operand78   SMLoc getEndLoc() const override { return EndLoc; }
79   /// getLocRange - Get the range between the first and last token of this
80   /// operand.
getLocRangeX86Operand81   SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
82   /// getOffsetOfLoc - Get the location of the offset operator.
getOffsetOfLocX86Operand83   SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
84 
printX86Operand85   void print(raw_ostream &OS) const override {}
86 
getTokenX86Operand87   StringRef getToken() const {
88     assert(Kind == Token && "Invalid access!");
89     return StringRef(Tok.Data, Tok.Length);
90   }
setTokenValueX86Operand91   void setTokenValue(StringRef Value) {
92     assert(Kind == Token && "Invalid access!");
93     Tok.Data = Value.data();
94     Tok.Length = Value.size();
95   }
96 
getRegX86Operand97   unsigned getReg() const override {
98     assert(Kind == Register && "Invalid access!");
99     return Reg.RegNo;
100   }
101 
getImmX86Operand102   const MCExpr *getImm() const {
103     assert(Kind == Immediate && "Invalid access!");
104     return Imm.Val;
105   }
106 
getMemDispX86Operand107   const MCExpr *getMemDisp() const {
108     assert(Kind == Memory && "Invalid access!");
109     return Mem.Disp;
110   }
getMemSegRegX86Operand111   unsigned getMemSegReg() const {
112     assert(Kind == Memory && "Invalid access!");
113     return Mem.SegReg;
114   }
getMemBaseRegX86Operand115   unsigned getMemBaseReg() const {
116     assert(Kind == Memory && "Invalid access!");
117     return Mem.BaseReg;
118   }
getMemIndexRegX86Operand119   unsigned getMemIndexReg() const {
120     assert(Kind == Memory && "Invalid access!");
121     return Mem.IndexReg;
122   }
getMemScaleX86Operand123   unsigned getMemScale() const {
124     assert(Kind == Memory && "Invalid access!");
125     return Mem.Scale;
126   }
getMemModeSizeX86Operand127   unsigned getMemModeSize() const {
128     assert(Kind == Memory && "Invalid access!");
129     return Mem.ModeSize;
130   }
131 
isTokenX86Operand132   bool isToken() const override {return Kind == Token; }
133 
isImmX86Operand134   bool isImm() const override { return Kind == Immediate; }
135 
isImmSExti16i8X86Operand136   bool isImmSExti16i8() const {
137     if (!isImm())
138       return false;
139 
140     // If this isn't a constant expr, just assume it fits and let relaxation
141     // handle it.
142     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
143     if (!CE)
144       return true;
145 
146     // Otherwise, check the value is in a range that makes sense for this
147     // extension.
148     return isImmSExti16i8Value(CE->getValue());
149   }
isImmSExti32i8X86Operand150   bool isImmSExti32i8() const {
151     if (!isImm())
152       return false;
153 
154     // If this isn't a constant expr, just assume it fits and let relaxation
155     // handle it.
156     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
157     if (!CE)
158       return true;
159 
160     // Otherwise, check the value is in a range that makes sense for this
161     // extension.
162     return isImmSExti32i8Value(CE->getValue());
163   }
isImmSExti64i8X86Operand164   bool isImmSExti64i8() const {
165     if (!isImm())
166       return false;
167 
168     // If this isn't a constant expr, just assume it fits and let relaxation
169     // handle it.
170     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
171     if (!CE)
172       return true;
173 
174     // Otherwise, check the value is in a range that makes sense for this
175     // extension.
176     return isImmSExti64i8Value(CE->getValue());
177   }
isImmSExti64i32X86Operand178   bool isImmSExti64i32() const {
179     if (!isImm())
180       return false;
181 
182     // If this isn't a constant expr, just assume it fits and let relaxation
183     // handle it.
184     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
185     if (!CE)
186       return true;
187 
188     // Otherwise, check the value is in a range that makes sense for this
189     // extension.
190     return isImmSExti64i32Value(CE->getValue());
191   }
192 
isImmUnsignedi8X86Operand193   bool isImmUnsignedi8() const {
194     if (!isImm()) return false;
195     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
196     if (!CE) return false;
197     return isImmUnsignedi8Value(CE->getValue());
198   }
199 
isOffsetOfX86Operand200   bool isOffsetOf() const override {
201     return OffsetOfLoc.getPointer();
202   }
203 
needAddressOfX86Operand204   bool needAddressOf() const override {
205     return AddressOf;
206   }
207 
isMemX86Operand208   bool isMem() const override { return Kind == Memory; }
isMemUnsizedX86Operand209   bool isMemUnsized() const {
210     return Kind == Memory && Mem.Size == 0;
211   }
isMem8X86Operand212   bool isMem8() const {
213     return Kind == Memory && (!Mem.Size || Mem.Size == 8);
214   }
isMem16X86Operand215   bool isMem16() const {
216     return Kind == Memory && (!Mem.Size || Mem.Size == 16);
217   }
isMem32X86Operand218   bool isMem32() const {
219     return Kind == Memory && (!Mem.Size || Mem.Size == 32);
220   }
isMem64X86Operand221   bool isMem64() const {
222     return Kind == Memory && (!Mem.Size || Mem.Size == 64);
223   }
isMem80X86Operand224   bool isMem80() const {
225     return Kind == Memory && (!Mem.Size || Mem.Size == 80);
226   }
isMem128X86Operand227   bool isMem128() const {
228     return Kind == Memory && (!Mem.Size || Mem.Size == 128);
229   }
isMem256X86Operand230   bool isMem256() const {
231     return Kind == Memory && (!Mem.Size || Mem.Size == 256);
232   }
isMem512X86Operand233   bool isMem512() const {
234     return Kind == Memory && (!Mem.Size || Mem.Size == 512);
235   }
isMemIndexRegX86Operand236   bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
237     assert(Kind == Memory && "Invalid access!");
238     return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
239   }
240 
isMem64_RC128X86Operand241   bool isMem64_RC128() const {
242     return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
243   }
isMem128_RC128X86Operand244   bool isMem128_RC128() const {
245     return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
246   }
isMem128_RC256X86Operand247   bool isMem128_RC256() const {
248     return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
249   }
isMem256_RC128X86Operand250   bool isMem256_RC128() const {
251     return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
252   }
isMem256_RC256X86Operand253   bool isMem256_RC256() const {
254     return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
255   }
256 
isMem64_RC128XX86Operand257   bool isMem64_RC128X() const {
258     return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
259   }
isMem128_RC128XX86Operand260   bool isMem128_RC128X() const {
261     return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
262   }
isMem128_RC256XX86Operand263   bool isMem128_RC256X() const {
264     return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
265   }
isMem256_RC128XX86Operand266   bool isMem256_RC128X() const {
267     return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
268   }
isMem256_RC256XX86Operand269   bool isMem256_RC256X() const {
270     return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
271   }
isMem512_RC256XX86Operand272   bool isMem512_RC256X() const {
273     return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
274   }
isMem512_RC512X86Operand275   bool isMem512_RC512() const {
276     return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
277   }
278 
isAbsMemX86Operand279   bool isAbsMem() const {
280     return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
281       !getMemIndexReg() && getMemScale() == 1;
282   }
isAVX512RCX86Operand283   bool isAVX512RC() const{
284       return isImm();
285   }
286 
isAbsMem16X86Operand287   bool isAbsMem16() const {
288     return isAbsMem() && Mem.ModeSize == 16;
289   }
290 
isSrcIdxX86Operand291   bool isSrcIdx() const {
292     return !getMemIndexReg() && getMemScale() == 1 &&
293       (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
294        getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
295       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
296   }
isSrcIdx8X86Operand297   bool isSrcIdx8() const {
298     return isMem8() && isSrcIdx();
299   }
isSrcIdx16X86Operand300   bool isSrcIdx16() const {
301     return isMem16() && isSrcIdx();
302   }
isSrcIdx32X86Operand303   bool isSrcIdx32() const {
304     return isMem32() && isSrcIdx();
305   }
isSrcIdx64X86Operand306   bool isSrcIdx64() const {
307     return isMem64() && isSrcIdx();
308   }
309 
isDstIdxX86Operand310   bool isDstIdx() const {
311     return !getMemIndexReg() && getMemScale() == 1 &&
312       (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
313       (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
314        getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
315       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
316   }
isDstIdx8X86Operand317   bool isDstIdx8() const {
318     return isMem8() && isDstIdx();
319   }
isDstIdx16X86Operand320   bool isDstIdx16() const {
321     return isMem16() && isDstIdx();
322   }
isDstIdx32X86Operand323   bool isDstIdx32() const {
324     return isMem32() && isDstIdx();
325   }
isDstIdx64X86Operand326   bool isDstIdx64() const {
327     return isMem64() && isDstIdx();
328   }
329 
isMemOffsX86Operand330   bool isMemOffs() const {
331     return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
332       getMemScale() == 1;
333   }
334 
isMemOffs16_8X86Operand335   bool isMemOffs16_8() const {
336     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
337   }
isMemOffs16_16X86Operand338   bool isMemOffs16_16() const {
339     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
340   }
isMemOffs16_32X86Operand341   bool isMemOffs16_32() const {
342     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
343   }
isMemOffs32_8X86Operand344   bool isMemOffs32_8() const {
345     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
346   }
isMemOffs32_16X86Operand347   bool isMemOffs32_16() const {
348     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
349   }
isMemOffs32_32X86Operand350   bool isMemOffs32_32() const {
351     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
352   }
isMemOffs32_64X86Operand353   bool isMemOffs32_64() const {
354     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
355   }
isMemOffs64_8X86Operand356   bool isMemOffs64_8() const {
357     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
358   }
isMemOffs64_16X86Operand359   bool isMemOffs64_16() const {
360     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
361   }
isMemOffs64_32X86Operand362   bool isMemOffs64_32() const {
363     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
364   }
isMemOffs64_64X86Operand365   bool isMemOffs64_64() const {
366     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
367   }
368 
isRegX86Operand369   bool isReg() const override { return Kind == Register; }
370 
isGR32orGR64X86Operand371   bool isGR32orGR64() const {
372     return Kind == Register &&
373       (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
374       X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
375   }
376 
addExprX86Operand377   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
378     // Add as immediates when possible.
379     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
380       Inst.addOperand(MCOperand::createImm(CE->getValue()));
381     else
382       Inst.addOperand(MCOperand::createExpr(Expr));
383   }
384 
addRegOperandsX86Operand385   void addRegOperands(MCInst &Inst, unsigned N) const {
386     assert(N == 1 && "Invalid number of operands!");
387     Inst.addOperand(MCOperand::createReg(getReg()));
388   }
389 
getGR32FromGR64X86Operand390   static unsigned getGR32FromGR64(unsigned RegNo) {
391     switch (RegNo) {
392     default: llvm_unreachable("Unexpected register");
393     case X86::RAX: return X86::EAX;
394     case X86::RCX: return X86::ECX;
395     case X86::RDX: return X86::EDX;
396     case X86::RBX: return X86::EBX;
397     case X86::RBP: return X86::EBP;
398     case X86::RSP: return X86::ESP;
399     case X86::RSI: return X86::ESI;
400     case X86::RDI: return X86::EDI;
401     case X86::R8: return X86::R8D;
402     case X86::R9: return X86::R9D;
403     case X86::R10: return X86::R10D;
404     case X86::R11: return X86::R11D;
405     case X86::R12: return X86::R12D;
406     case X86::R13: return X86::R13D;
407     case X86::R14: return X86::R14D;
408     case X86::R15: return X86::R15D;
409     case X86::RIP: return X86::EIP;
410     }
411   }
412 
addGR32orGR64OperandsX86Operand413   void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
414     assert(N == 1 && "Invalid number of operands!");
415     unsigned RegNo = getReg();
416     if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
417       RegNo = getGR32FromGR64(RegNo);
418     Inst.addOperand(MCOperand::createReg(RegNo));
419   }
addAVX512RCOperandsX86Operand420   void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
421     assert(N == 1 && "Invalid number of operands!");
422     addExpr(Inst, getImm());
423   }
addImmOperandsX86Operand424   void addImmOperands(MCInst &Inst, unsigned N) const {
425     assert(N == 1 && "Invalid number of operands!");
426     addExpr(Inst, getImm());
427   }
428 
addMemOperandsX86Operand429   void addMemOperands(MCInst &Inst, unsigned N) const {
430     assert((N == 5) && "Invalid number of operands!");
431     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
432     Inst.addOperand(MCOperand::createImm(getMemScale()));
433     Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
434     addExpr(Inst, getMemDisp());
435     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
436   }
437 
addAbsMemOperandsX86Operand438   void addAbsMemOperands(MCInst &Inst, unsigned N) const {
439     assert((N == 1) && "Invalid number of operands!");
440     // Add as immediates when possible.
441     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
442       Inst.addOperand(MCOperand::createImm(CE->getValue()));
443     else
444       Inst.addOperand(MCOperand::createExpr(getMemDisp()));
445   }
446 
addSrcIdxOperandsX86Operand447   void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
448     assert((N == 2) && "Invalid number of operands!");
449     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
450     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
451   }
addDstIdxOperandsX86Operand452   void addDstIdxOperands(MCInst &Inst, unsigned N) const {
453     assert((N == 1) && "Invalid number of operands!");
454     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
455   }
456 
addMemOffsOperandsX86Operand457   void addMemOffsOperands(MCInst &Inst, unsigned N) const {
458     assert((N == 2) && "Invalid number of operands!");
459     // Add as immediates when possible.
460     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
461       Inst.addOperand(MCOperand::createImm(CE->getValue()));
462     else
463       Inst.addOperand(MCOperand::createExpr(getMemDisp()));
464     Inst.addOperand(MCOperand::createReg(getMemSegReg()));
465   }
466 
CreateTokenX86Operand467   static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
468     SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
469     auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
470     Res->Tok.Data = Str.data();
471     Res->Tok.Length = Str.size();
472     return Res;
473   }
474 
475   static std::unique_ptr<X86Operand>
476   CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
477             bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
478             StringRef SymName = StringRef(), void *OpDecl = nullptr) {
479     auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
480     Res->Reg.RegNo = RegNo;
481     Res->AddressOf = AddressOf;
482     Res->OffsetOfLoc = OffsetOfLoc;
483     Res->SymName = SymName;
484     Res->OpDecl = OpDecl;
485     return Res;
486   }
487 
CreateImmX86Operand488   static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
489                                                SMLoc StartLoc, SMLoc EndLoc) {
490     auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
491     Res->Imm.Val = Val;
492     return Res;
493   }
494 
495   /// Create an absolute memory operand.
496   static std::unique_ptr<X86Operand>
497   CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
498             unsigned Size = 0, StringRef SymName = StringRef(),
499             void *OpDecl = nullptr) {
500     auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
501     Res->Mem.SegReg   = 0;
502     Res->Mem.Disp     = Disp;
503     Res->Mem.BaseReg  = 0;
504     Res->Mem.IndexReg = 0;
505     Res->Mem.Scale    = 1;
506     Res->Mem.Size     = Size;
507     Res->Mem.ModeSize = ModeSize;
508     Res->SymName      = SymName;
509     Res->OpDecl       = OpDecl;
510     Res->AddressOf    = false;
511     return Res;
512   }
513 
514   /// Create a generalized memory operand.
515   static std::unique_ptr<X86Operand>
516   CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
517             unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
518             SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
519             void *OpDecl = nullptr) {
520     // We should never just have a displacement, that should be parsed as an
521     // absolute memory operand.
522     assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
523 
524     // The scale should always be one of {1,2,4,8}.
525     assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
526            "Invalid scale!");
527     auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
528     Res->Mem.SegReg   = SegReg;
529     Res->Mem.Disp     = Disp;
530     Res->Mem.BaseReg  = BaseReg;
531     Res->Mem.IndexReg = IndexReg;
532     Res->Mem.Scale    = Scale;
533     Res->Mem.Size     = Size;
534     Res->Mem.ModeSize = ModeSize;
535     Res->SymName      = SymName;
536     Res->OpDecl       = OpDecl;
537     Res->AddressOf    = false;
538     return Res;
539   }
540 };
541 
542 } // End of namespace llvm
543 
544 #endif
545