• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 X86_OPERAND_H
11 #define X86_OPERAND_H
12 
13 #include "X86AsmParserCommon.h"
14 #include "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
16 #include "llvm/ADT/STLExtras.h"
17 
18 namespace llvm {
19 
20 /// X86Operand - Instances of this class represent a parsed X86 machine
21 /// instruction.
22 struct X86Operand : public MCParsedAsmOperand {
23   enum KindTy {
24     Token,
25     Register,
26     Immediate,
27     Memory
28   } Kind;
29 
30   SMLoc StartLoc, EndLoc;
31   SMLoc OffsetOfLoc;
32   StringRef SymName;
33   void *OpDecl;
34   bool AddressOf;
35 
36   struct TokOp {
37     const char *Data;
38     unsigned Length;
39   };
40 
41   struct RegOp {
42     unsigned RegNo;
43   };
44 
45   struct ImmOp {
46     const MCExpr *Val;
47   };
48 
49   struct MemOp {
50     unsigned SegReg;
51     const MCExpr *Disp;
52     unsigned BaseReg;
53     unsigned IndexReg;
54     unsigned Scale;
55     unsigned Size;
56   };
57 
58   union {
59     struct TokOp Tok;
60     struct RegOp Reg;
61     struct ImmOp Imm;
62     struct MemOp Mem;
63   };
64 
X86OperandX86Operand65   X86Operand(KindTy K, SMLoc Start, SMLoc End)
66     : Kind(K), StartLoc(Start), EndLoc(End) {}
67 
getSymNameX86Operand68   StringRef getSymName() override { return SymName; }
getOpDeclX86Operand69   void *getOpDecl() override { return OpDecl; }
70 
71   /// getStartLoc - Get the location of the first token of this operand.
getStartLocX86Operand72   SMLoc getStartLoc() const override { return StartLoc; }
73   /// getEndLoc - Get the location of the last token of this operand.
getEndLocX86Operand74   SMLoc getEndLoc() const override { return EndLoc; }
75   /// getLocRange - Get the range between the first and last token of this
76   /// operand.
getLocRangeX86Operand77   SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
78   /// getOffsetOfLoc - Get the location of the offset operator.
getOffsetOfLocX86Operand79   SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
80 
printX86Operand81   void print(raw_ostream &OS) const override {}
82 
getTokenX86Operand83   StringRef getToken() const {
84     assert(Kind == Token && "Invalid access!");
85     return StringRef(Tok.Data, Tok.Length);
86   }
setTokenValueX86Operand87   void setTokenValue(StringRef Value) {
88     assert(Kind == Token && "Invalid access!");
89     Tok.Data = Value.data();
90     Tok.Length = Value.size();
91   }
92 
getRegX86Operand93   unsigned getReg() const override {
94     assert(Kind == Register && "Invalid access!");
95     return Reg.RegNo;
96   }
97 
getImmX86Operand98   const MCExpr *getImm() const {
99     assert(Kind == Immediate && "Invalid access!");
100     return Imm.Val;
101   }
102 
getMemDispX86Operand103   const MCExpr *getMemDisp() const {
104     assert(Kind == Memory && "Invalid access!");
105     return Mem.Disp;
106   }
getMemSegRegX86Operand107   unsigned getMemSegReg() const {
108     assert(Kind == Memory && "Invalid access!");
109     return Mem.SegReg;
110   }
getMemBaseRegX86Operand111   unsigned getMemBaseReg() const {
112     assert(Kind == Memory && "Invalid access!");
113     return Mem.BaseReg;
114   }
getMemIndexRegX86Operand115   unsigned getMemIndexReg() const {
116     assert(Kind == Memory && "Invalid access!");
117     return Mem.IndexReg;
118   }
getMemScaleX86Operand119   unsigned getMemScale() const {
120     assert(Kind == Memory && "Invalid access!");
121     return Mem.Scale;
122   }
123 
isTokenX86Operand124   bool isToken() const override {return Kind == Token; }
125 
isImmX86Operand126   bool isImm() const override { return Kind == Immediate; }
127 
isImmSExti16i8X86Operand128   bool isImmSExti16i8() const {
129     if (!isImm())
130       return false;
131 
132     // If this isn't a constant expr, just assume it fits and let relaxation
133     // handle it.
134     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
135     if (!CE)
136       return true;
137 
138     // Otherwise, check the value is in a range that makes sense for this
139     // extension.
140     return isImmSExti16i8Value(CE->getValue());
141   }
isImmSExti32i8X86Operand142   bool isImmSExti32i8() const {
143     if (!isImm())
144       return false;
145 
146     // If this isn't a constant expr, just assume it fits and let relaxation
147     // handle it.
148     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
149     if (!CE)
150       return true;
151 
152     // Otherwise, check the value is in a range that makes sense for this
153     // extension.
154     return isImmSExti32i8Value(CE->getValue());
155   }
isImmZExtu32u8X86Operand156   bool isImmZExtu32u8() const {
157     if (!isImm())
158       return false;
159 
160     // If this isn't a constant expr, just assume it fits and let relaxation
161     // handle it.
162     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
163     if (!CE)
164       return true;
165 
166     // Otherwise, check the value is in a range that makes sense for this
167     // extension.
168     return isImmZExtu32u8Value(CE->getValue());
169   }
isImmSExti64i8X86Operand170   bool isImmSExti64i8() const {
171     if (!isImm())
172       return false;
173 
174     // If this isn't a constant expr, just assume it fits and let relaxation
175     // handle it.
176     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
177     if (!CE)
178       return true;
179 
180     // Otherwise, check the value is in a range that makes sense for this
181     // extension.
182     return isImmSExti64i8Value(CE->getValue());
183   }
isImmSExti64i32X86Operand184   bool isImmSExti64i32() const {
185     if (!isImm())
186       return false;
187 
188     // If this isn't a constant expr, just assume it fits and let relaxation
189     // handle it.
190     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
191     if (!CE)
192       return true;
193 
194     // Otherwise, check the value is in a range that makes sense for this
195     // extension.
196     return isImmSExti64i32Value(CE->getValue());
197   }
198 
isOffsetOfX86Operand199   bool isOffsetOf() const override {
200     return OffsetOfLoc.getPointer();
201   }
202 
needAddressOfX86Operand203   bool needAddressOf() const override {
204     return AddressOf;
205   }
206 
isMemX86Operand207   bool isMem() const override { return Kind == Memory; }
isMem8X86Operand208   bool isMem8() const {
209     return Kind == Memory && (!Mem.Size || Mem.Size == 8);
210   }
isMem16X86Operand211   bool isMem16() const {
212     return Kind == Memory && (!Mem.Size || Mem.Size == 16);
213   }
isMem32X86Operand214   bool isMem32() const {
215     return Kind == Memory && (!Mem.Size || Mem.Size == 32);
216   }
isMem64X86Operand217   bool isMem64() const {
218     return Kind == Memory && (!Mem.Size || Mem.Size == 64);
219   }
isMem80X86Operand220   bool isMem80() const {
221     return Kind == Memory && (!Mem.Size || Mem.Size == 80);
222   }
isMem128X86Operand223   bool isMem128() const {
224     return Kind == Memory && (!Mem.Size || Mem.Size == 128);
225   }
isMem256X86Operand226   bool isMem256() const {
227     return Kind == Memory && (!Mem.Size || Mem.Size == 256);
228   }
isMem512X86Operand229   bool isMem512() const {
230     return Kind == Memory && (!Mem.Size || Mem.Size == 512);
231   }
232 
isMemVX32X86Operand233   bool isMemVX32() const {
234     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
235       getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
236   }
isMemVY32X86Operand237   bool isMemVY32() const {
238     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
239       getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
240   }
isMemVX64X86Operand241   bool isMemVX64() const {
242     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
243       getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
244   }
isMemVY64X86Operand245   bool isMemVY64() const {
246     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
247       getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
248   }
isMemVZ32X86Operand249   bool isMemVZ32() const {
250     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
251       getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
252   }
isMemVZ64X86Operand253   bool isMemVZ64() const {
254     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
255       getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
256   }
257 
isAbsMemX86Operand258   bool isAbsMem() const {
259     return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
260       !getMemIndexReg() && getMemScale() == 1;
261   }
262 
isSrcIdxX86Operand263   bool isSrcIdx() const {
264     return !getMemIndexReg() && getMemScale() == 1 &&
265       (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
266        getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
267       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
268   }
isSrcIdx8X86Operand269   bool isSrcIdx8() const {
270     return isMem8() && isSrcIdx();
271   }
isSrcIdx16X86Operand272   bool isSrcIdx16() const {
273     return isMem16() && isSrcIdx();
274   }
isSrcIdx32X86Operand275   bool isSrcIdx32() const {
276     return isMem32() && isSrcIdx();
277   }
isSrcIdx64X86Operand278   bool isSrcIdx64() const {
279     return isMem64() && isSrcIdx();
280   }
281 
isDstIdxX86Operand282   bool isDstIdx() const {
283     return !getMemIndexReg() && getMemScale() == 1 &&
284       (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
285       (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
286        getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
287       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
288   }
isDstIdx8X86Operand289   bool isDstIdx8() const {
290     return isMem8() && isDstIdx();
291   }
isDstIdx16X86Operand292   bool isDstIdx16() const {
293     return isMem16() && isDstIdx();
294   }
isDstIdx32X86Operand295   bool isDstIdx32() const {
296     return isMem32() && isDstIdx();
297   }
isDstIdx64X86Operand298   bool isDstIdx64() const {
299     return isMem64() && isDstIdx();
300   }
301 
isMemOffs8X86Operand302   bool isMemOffs8() const {
303     return Kind == Memory && !getMemBaseReg() &&
304       !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 8);
305   }
isMemOffs16X86Operand306   bool isMemOffs16() const {
307     return Kind == Memory && !getMemBaseReg() &&
308       !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 16);
309   }
isMemOffs32X86Operand310   bool isMemOffs32() const {
311     return Kind == Memory && !getMemBaseReg() &&
312       !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 32);
313   }
isMemOffs64X86Operand314   bool isMemOffs64() const {
315     return Kind == Memory && !getMemBaseReg() &&
316       !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 64);
317   }
318 
isRegX86Operand319   bool isReg() const override { return Kind == Register; }
320 
isGR32orGR64X86Operand321   bool isGR32orGR64() const {
322     return Kind == Register &&
323       (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
324       X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
325   }
326 
addExprX86Operand327   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
328     // Add as immediates when possible.
329     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
330       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
331     else
332       Inst.addOperand(MCOperand::CreateExpr(Expr));
333   }
334 
addRegOperandsX86Operand335   void addRegOperands(MCInst &Inst, unsigned N) const {
336     assert(N == 1 && "Invalid number of operands!");
337     Inst.addOperand(MCOperand::CreateReg(getReg()));
338   }
339 
getGR32FromGR64X86Operand340   static unsigned getGR32FromGR64(unsigned RegNo) {
341     switch (RegNo) {
342     default: llvm_unreachable("Unexpected register");
343     case X86::RAX: return X86::EAX;
344     case X86::RCX: return X86::ECX;
345     case X86::RDX: return X86::EDX;
346     case X86::RBX: return X86::EBX;
347     case X86::RBP: return X86::EBP;
348     case X86::RSP: return X86::ESP;
349     case X86::RSI: return X86::ESI;
350     case X86::RDI: return X86::EDI;
351     case X86::R8: return X86::R8D;
352     case X86::R9: return X86::R9D;
353     case X86::R10: return X86::R10D;
354     case X86::R11: return X86::R11D;
355     case X86::R12: return X86::R12D;
356     case X86::R13: return X86::R13D;
357     case X86::R14: return X86::R14D;
358     case X86::R15: return X86::R15D;
359     case X86::RIP: return X86::EIP;
360     }
361   }
362 
addGR32orGR64OperandsX86Operand363   void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
364     assert(N == 1 && "Invalid number of operands!");
365     unsigned RegNo = getReg();
366     if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
367       RegNo = getGR32FromGR64(RegNo);
368     Inst.addOperand(MCOperand::CreateReg(RegNo));
369   }
370 
addImmOperandsX86Operand371   void addImmOperands(MCInst &Inst, unsigned N) const {
372     assert(N == 1 && "Invalid number of operands!");
373     addExpr(Inst, getImm());
374   }
375 
addMemOperandsX86Operand376   void addMemOperands(MCInst &Inst, unsigned N) const {
377     assert((N == 5) && "Invalid number of operands!");
378     Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
379     Inst.addOperand(MCOperand::CreateImm(getMemScale()));
380     Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
381     addExpr(Inst, getMemDisp());
382     Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
383   }
384 
addAbsMemOperandsX86Operand385   void addAbsMemOperands(MCInst &Inst, unsigned N) const {
386     assert((N == 1) && "Invalid number of operands!");
387     // Add as immediates when possible.
388     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
389       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
390     else
391       Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
392   }
393 
addSrcIdxOperandsX86Operand394   void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
395     assert((N == 2) && "Invalid number of operands!");
396     Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
397     Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
398   }
addDstIdxOperandsX86Operand399   void addDstIdxOperands(MCInst &Inst, unsigned N) const {
400     assert((N == 1) && "Invalid number of operands!");
401     Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
402   }
403 
addMemOffsOperandsX86Operand404   void addMemOffsOperands(MCInst &Inst, unsigned N) const {
405     assert((N == 2) && "Invalid number of operands!");
406     // Add as immediates when possible.
407     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
408       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
409     else
410       Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
411     Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
412   }
413 
CreateTokenX86Operand414   static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
415     SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
416     auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
417     Res->Tok.Data = Str.data();
418     Res->Tok.Length = Str.size();
419     return Res;
420   }
421 
422   static std::unique_ptr<X86Operand>
423   CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
424             bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
425             StringRef SymName = StringRef(), void *OpDecl = nullptr) {
426     auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
427     Res->Reg.RegNo = RegNo;
428     Res->AddressOf = AddressOf;
429     Res->OffsetOfLoc = OffsetOfLoc;
430     Res->SymName = SymName;
431     Res->OpDecl = OpDecl;
432     return Res;
433   }
434 
CreateImmX86Operand435   static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
436                                                SMLoc StartLoc, SMLoc EndLoc) {
437     auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
438     Res->Imm.Val = Val;
439     return Res;
440   }
441 
442   /// Create an absolute memory operand.
443   static std::unique_ptr<X86Operand>
444   CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size = 0,
445             StringRef SymName = StringRef(), void *OpDecl = nullptr) {
446     auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
447     Res->Mem.SegReg   = 0;
448     Res->Mem.Disp     = Disp;
449     Res->Mem.BaseReg  = 0;
450     Res->Mem.IndexReg = 0;
451     Res->Mem.Scale    = 1;
452     Res->Mem.Size     = Size;
453     Res->SymName      = SymName;
454     Res->OpDecl       = OpDecl;
455     Res->AddressOf    = false;
456     return Res;
457   }
458 
459   /// Create a generalized memory operand.
460   static std::unique_ptr<X86Operand>
461   CreateMem(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
462             unsigned IndexReg, unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
463             unsigned Size = 0, StringRef SymName = StringRef(),
464             void *OpDecl = nullptr) {
465     // We should never just have a displacement, that should be parsed as an
466     // absolute memory operand.
467     assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
468 
469     // The scale should always be one of {1,2,4,8}.
470     assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
471            "Invalid scale!");
472     auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
473     Res->Mem.SegReg   = SegReg;
474     Res->Mem.Disp     = Disp;
475     Res->Mem.BaseReg  = BaseReg;
476     Res->Mem.IndexReg = IndexReg;
477     Res->Mem.Scale    = Scale;
478     Res->Mem.Size     = Size;
479     Res->SymName      = SymName;
480     Res->OpDecl       = OpDecl;
481     Res->AddressOf    = false;
482     return Res;
483   }
484 };
485 
486 } // End of namespace llvm
487 
488 #endif // X86_OPERAND
489