Home | History | Annotate | Download | only in AsmParser
      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 
     65   X86Operand(KindTy K, SMLoc Start, SMLoc End)
     66     : Kind(K), StartLoc(Start), EndLoc(End) {}
     67 
     68   StringRef getSymName() override { return SymName; }
     69   void *getOpDecl() override { return OpDecl; }
     70 
     71   /// getStartLoc - Get the location of the first token of this operand.
     72   SMLoc getStartLoc() const override { return StartLoc; }
     73   /// getEndLoc - Get the location of the last token of this operand.
     74   SMLoc getEndLoc() const override { return EndLoc; }
     75   /// getLocRange - Get the range between the first and last token of this
     76   /// operand.
     77   SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
     78   /// getOffsetOfLoc - Get the location of the offset operator.
     79   SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
     80 
     81   void print(raw_ostream &OS) const override {}
     82 
     83   StringRef getToken() const {
     84     assert(Kind == Token && "Invalid access!");
     85     return StringRef(Tok.Data, Tok.Length);
     86   }
     87   void setTokenValue(StringRef Value) {
     88     assert(Kind == Token && "Invalid access!");
     89     Tok.Data = Value.data();
     90     Tok.Length = Value.size();
     91   }
     92 
     93   unsigned getReg() const override {
     94     assert(Kind == Register && "Invalid access!");
     95     return Reg.RegNo;
     96   }
     97 
     98   const MCExpr *getImm() const {
     99     assert(Kind == Immediate && "Invalid access!");
    100     return Imm.Val;
    101   }
    102 
    103   const MCExpr *getMemDisp() const {
    104     assert(Kind == Memory && "Invalid access!");
    105     return Mem.Disp;
    106   }
    107   unsigned getMemSegReg() const {
    108     assert(Kind == Memory && "Invalid access!");
    109     return Mem.SegReg;
    110   }
    111   unsigned getMemBaseReg() const {
    112     assert(Kind == Memory && "Invalid access!");
    113     return Mem.BaseReg;
    114   }
    115   unsigned getMemIndexReg() const {
    116     assert(Kind == Memory && "Invalid access!");
    117     return Mem.IndexReg;
    118   }
    119   unsigned getMemScale() const {
    120     assert(Kind == Memory && "Invalid access!");
    121     return Mem.Scale;
    122   }
    123 
    124   bool isToken() const override {return Kind == Token; }
    125 
    126   bool isImm() const override { return Kind == Immediate; }
    127 
    128   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   }
    142   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   }
    156   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   }
    170   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   }
    184   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 
    199   bool isOffsetOf() const override {
    200     return OffsetOfLoc.getPointer();
    201   }
    202 
    203   bool needAddressOf() const override {
    204     return AddressOf;
    205   }
    206 
    207   bool isMem() const override { return Kind == Memory; }
    208   bool isMem8() const {
    209     return Kind == Memory && (!Mem.Size || Mem.Size == 8);
    210   }
    211   bool isMem16() const {
    212     return Kind == Memory && (!Mem.Size || Mem.Size == 16);
    213   }
    214   bool isMem32() const {
    215     return Kind == Memory && (!Mem.Size || Mem.Size == 32);
    216   }
    217   bool isMem64() const {
    218     return Kind == Memory && (!Mem.Size || Mem.Size == 64);
    219   }
    220   bool isMem80() const {
    221     return Kind == Memory && (!Mem.Size || Mem.Size == 80);
    222   }
    223   bool isMem128() const {
    224     return Kind == Memory && (!Mem.Size || Mem.Size == 128);
    225   }
    226   bool isMem256() const {
    227     return Kind == Memory && (!Mem.Size || Mem.Size == 256);
    228   }
    229   bool isMem512() const {
    230     return Kind == Memory && (!Mem.Size || Mem.Size == 512);
    231   }
    232 
    233   bool isMemVX32() const {
    234     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
    235       getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
    236   }
    237   bool isMemVY32() const {
    238     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
    239       getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
    240   }
    241   bool isMemVX64() const {
    242     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
    243       getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
    244   }
    245   bool isMemVY64() const {
    246     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
    247       getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
    248   }
    249   bool isMemVZ32() const {
    250     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
    251       getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
    252   }
    253   bool isMemVZ64() const {
    254     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
    255       getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
    256   }
    257 
    258   bool isAbsMem() const {
    259     return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
    260       !getMemIndexReg() && getMemScale() == 1;
    261   }
    262 
    263   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   }
    269   bool isSrcIdx8() const {
    270     return isMem8() && isSrcIdx();
    271   }
    272   bool isSrcIdx16() const {
    273     return isMem16() && isSrcIdx();
    274   }
    275   bool isSrcIdx32() const {
    276     return isMem32() && isSrcIdx();
    277   }
    278   bool isSrcIdx64() const {
    279     return isMem64() && isSrcIdx();
    280   }
    281 
    282   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   }
    289   bool isDstIdx8() const {
    290     return isMem8() && isDstIdx();
    291   }
    292   bool isDstIdx16() const {
    293     return isMem16() && isDstIdx();
    294   }
    295   bool isDstIdx32() const {
    296     return isMem32() && isDstIdx();
    297   }
    298   bool isDstIdx64() const {
    299     return isMem64() && isDstIdx();
    300   }
    301 
    302   bool isMemOffs8() const {
    303     return Kind == Memory && !getMemBaseReg() &&
    304       !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 8);
    305   }
    306   bool isMemOffs16() const {
    307     return Kind == Memory && !getMemBaseReg() &&
    308       !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 16);
    309   }
    310   bool isMemOffs32() const {
    311     return Kind == Memory && !getMemBaseReg() &&
    312       !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 32);
    313   }
    314   bool isMemOffs64() const {
    315     return Kind == Memory && !getMemBaseReg() &&
    316       !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 64);
    317   }
    318 
    319   bool isReg() const override { return Kind == Register; }
    320 
    321   bool isGR32orGR64() const {
    322     return Kind == Register &&
    323       (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
    324       X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
    325   }
    326 
    327   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 
    335   void addRegOperands(MCInst &Inst, unsigned N) const {
    336     assert(N == 1 && "Invalid number of operands!");
    337     Inst.addOperand(MCOperand::CreateReg(getReg()));
    338   }
    339 
    340   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 
    363   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 
    371   void addImmOperands(MCInst &Inst, unsigned N) const {
    372     assert(N == 1 && "Invalid number of operands!");
    373     addExpr(Inst, getImm());
    374   }
    375 
    376   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 
    385   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 
    394   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   }
    399   void addDstIdxOperands(MCInst &Inst, unsigned N) const {
    400     assert((N == 1) && "Invalid number of operands!");
    401     Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
    402   }
    403 
    404   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 
    414   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 
    435   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