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 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/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     unsigned ModeSize;
     57   };
     58 
     59   union {
     60     struct TokOp Tok;
     61     struct RegOp Reg;
     62     struct ImmOp Imm;
     63     struct MemOp Mem;
     64   };
     65 
     66   X86Operand(KindTy K, SMLoc Start, SMLoc End)
     67     : Kind(K), StartLoc(Start), EndLoc(End) {}
     68 
     69   StringRef getSymName() override { return SymName; }
     70   void *getOpDecl() override { return OpDecl; }
     71 
     72   /// getStartLoc - Get the location of the first token of this operand.
     73   SMLoc getStartLoc() const override { return StartLoc; }
     74   /// getEndLoc - Get the location of the last token of this operand.
     75   SMLoc getEndLoc() const override { return EndLoc; }
     76   /// getLocRange - Get the range between the first and last token of this
     77   /// operand.
     78   SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
     79   /// getOffsetOfLoc - Get the location of the offset operator.
     80   SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
     81 
     82   void print(raw_ostream &OS) const override {}
     83 
     84   StringRef getToken() const {
     85     assert(Kind == Token && "Invalid access!");
     86     return StringRef(Tok.Data, Tok.Length);
     87   }
     88   void setTokenValue(StringRef Value) {
     89     assert(Kind == Token && "Invalid access!");
     90     Tok.Data = Value.data();
     91     Tok.Length = Value.size();
     92   }
     93 
     94   unsigned getReg() const override {
     95     assert(Kind == Register && "Invalid access!");
     96     return Reg.RegNo;
     97   }
     98 
     99   const MCExpr *getImm() const {
    100     assert(Kind == Immediate && "Invalid access!");
    101     return Imm.Val;
    102   }
    103 
    104   const MCExpr *getMemDisp() const {
    105     assert(Kind == Memory && "Invalid access!");
    106     return Mem.Disp;
    107   }
    108   unsigned getMemSegReg() const {
    109     assert(Kind == Memory && "Invalid access!");
    110     return Mem.SegReg;
    111   }
    112   unsigned getMemBaseReg() const {
    113     assert(Kind == Memory && "Invalid access!");
    114     return Mem.BaseReg;
    115   }
    116   unsigned getMemIndexReg() const {
    117     assert(Kind == Memory && "Invalid access!");
    118     return Mem.IndexReg;
    119   }
    120   unsigned getMemScale() const {
    121     assert(Kind == Memory && "Invalid access!");
    122     return Mem.Scale;
    123   }
    124   unsigned getMemModeSize() const {
    125     assert(Kind == Memory && "Invalid access!");
    126     return Mem.ModeSize;
    127   }
    128 
    129   bool isToken() const override {return Kind == Token; }
    130 
    131   bool isImm() const override { return Kind == Immediate; }
    132 
    133   bool isImmSExti16i8() const {
    134     if (!isImm())
    135       return false;
    136 
    137     // If this isn't a constant expr, just assume it fits and let relaxation
    138     // handle it.
    139     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    140     if (!CE)
    141       return true;
    142 
    143     // Otherwise, check the value is in a range that makes sense for this
    144     // extension.
    145     return isImmSExti16i8Value(CE->getValue());
    146   }
    147   bool isImmSExti32i8() const {
    148     if (!isImm())
    149       return false;
    150 
    151     // If this isn't a constant expr, just assume it fits and let relaxation
    152     // handle it.
    153     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    154     if (!CE)
    155       return true;
    156 
    157     // Otherwise, check the value is in a range that makes sense for this
    158     // extension.
    159     return isImmSExti32i8Value(CE->getValue());
    160   }
    161   bool isImmSExti64i8() const {
    162     if (!isImm())
    163       return false;
    164 
    165     // If this isn't a constant expr, just assume it fits and let relaxation
    166     // handle it.
    167     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    168     if (!CE)
    169       return true;
    170 
    171     // Otherwise, check the value is in a range that makes sense for this
    172     // extension.
    173     return isImmSExti64i8Value(CE->getValue());
    174   }
    175   bool isImmSExti64i32() const {
    176     if (!isImm())
    177       return false;
    178 
    179     // If this isn't a constant expr, just assume it fits and let relaxation
    180     // handle it.
    181     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    182     if (!CE)
    183       return true;
    184 
    185     // Otherwise, check the value is in a range that makes sense for this
    186     // extension.
    187     return isImmSExti64i32Value(CE->getValue());
    188   }
    189 
    190   bool isImmUnsignedi8() const {
    191     if (!isImm()) return false;
    192     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    193     if (!CE) return false;
    194     return isImmUnsignedi8Value(CE->getValue());
    195   }
    196 
    197   bool isOffsetOf() const override {
    198     return OffsetOfLoc.getPointer();
    199   }
    200 
    201   bool needAddressOf() const override {
    202     return AddressOf;
    203   }
    204 
    205   bool isMem() const override { return Kind == Memory; }
    206   bool isMemUnsized() const {
    207     return Kind == Memory && Mem.Size == 0;
    208   }
    209   bool isMem8() const {
    210     return Kind == Memory && (!Mem.Size || Mem.Size == 8);
    211   }
    212   bool isMem16() const {
    213     return Kind == Memory && (!Mem.Size || Mem.Size == 16);
    214   }
    215   bool isMem32() const {
    216     return Kind == Memory && (!Mem.Size || Mem.Size == 32);
    217   }
    218   bool isMem64() const {
    219     return Kind == Memory && (!Mem.Size || Mem.Size == 64);
    220   }
    221   bool isMem80() const {
    222     return Kind == Memory && (!Mem.Size || Mem.Size == 80);
    223   }
    224   bool isMem128() const {
    225     return Kind == Memory && (!Mem.Size || Mem.Size == 128);
    226   }
    227   bool isMem256() const {
    228     return Kind == Memory && (!Mem.Size || Mem.Size == 256);
    229   }
    230   bool isMem512() const {
    231     return Kind == Memory && (!Mem.Size || Mem.Size == 512);
    232   }
    233 
    234   bool isMemVX32() const {
    235     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
    236       getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
    237   }
    238   bool isMemVY32() const {
    239     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
    240       getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
    241   }
    242   bool isMemVX64() const {
    243     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
    244       getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
    245   }
    246   bool isMemVY64() const {
    247     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
    248       getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
    249   }
    250   bool isMemVZ32() const {
    251     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
    252       getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
    253   }
    254   bool isMemVZ64() const {
    255     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
    256       getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
    257   }
    258 
    259   bool isAbsMem() const {
    260     return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
    261       !getMemIndexReg() && getMemScale() == 1;
    262   }
    263   bool isAVX512RC() const{
    264       return isImm();
    265   }
    266 
    267   bool isAbsMem16() const {
    268     return isAbsMem() && Mem.ModeSize == 16;
    269   }
    270 
    271   bool isSrcIdx() const {
    272     return !getMemIndexReg() && getMemScale() == 1 &&
    273       (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
    274        getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
    275       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
    276   }
    277   bool isSrcIdx8() const {
    278     return isMem8() && isSrcIdx();
    279   }
    280   bool isSrcIdx16() const {
    281     return isMem16() && isSrcIdx();
    282   }
    283   bool isSrcIdx32() const {
    284     return isMem32() && isSrcIdx();
    285   }
    286   bool isSrcIdx64() const {
    287     return isMem64() && isSrcIdx();
    288   }
    289 
    290   bool isDstIdx() const {
    291     return !getMemIndexReg() && getMemScale() == 1 &&
    292       (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
    293       (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
    294        getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
    295       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
    296   }
    297   bool isDstIdx8() const {
    298     return isMem8() && isDstIdx();
    299   }
    300   bool isDstIdx16() const {
    301     return isMem16() && isDstIdx();
    302   }
    303   bool isDstIdx32() const {
    304     return isMem32() && isDstIdx();
    305   }
    306   bool isDstIdx64() const {
    307     return isMem64() && isDstIdx();
    308   }
    309 
    310   bool isMemOffs() const {
    311     return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
    312       getMemScale() == 1;
    313   }
    314 
    315   bool isMemOffs16_8() const {
    316     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
    317   }
    318   bool isMemOffs16_16() const {
    319     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
    320   }
    321   bool isMemOffs16_32() const {
    322     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
    323   }
    324   bool isMemOffs32_8() const {
    325     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
    326   }
    327   bool isMemOffs32_16() const {
    328     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
    329   }
    330   bool isMemOffs32_32() const {
    331     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
    332   }
    333   bool isMemOffs32_64() const {
    334     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
    335   }
    336   bool isMemOffs64_8() const {
    337     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
    338   }
    339   bool isMemOffs64_16() const {
    340     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
    341   }
    342   bool isMemOffs64_32() const {
    343     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
    344   }
    345   bool isMemOffs64_64() const {
    346     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
    347   }
    348 
    349   bool isReg() const override { return Kind == Register; }
    350 
    351   bool isGR32orGR64() const {
    352     return Kind == Register &&
    353       (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
    354       X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
    355   }
    356 
    357   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
    358     // Add as immediates when possible.
    359     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
    360       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
    361     else
    362       Inst.addOperand(MCOperand::CreateExpr(Expr));
    363   }
    364 
    365   void addRegOperands(MCInst &Inst, unsigned N) const {
    366     assert(N == 1 && "Invalid number of operands!");
    367     Inst.addOperand(MCOperand::CreateReg(getReg()));
    368   }
    369 
    370   static unsigned getGR32FromGR64(unsigned RegNo) {
    371     switch (RegNo) {
    372     default: llvm_unreachable("Unexpected register");
    373     case X86::RAX: return X86::EAX;
    374     case X86::RCX: return X86::ECX;
    375     case X86::RDX: return X86::EDX;
    376     case X86::RBX: return X86::EBX;
    377     case X86::RBP: return X86::EBP;
    378     case X86::RSP: return X86::ESP;
    379     case X86::RSI: return X86::ESI;
    380     case X86::RDI: return X86::EDI;
    381     case X86::R8: return X86::R8D;
    382     case X86::R9: return X86::R9D;
    383     case X86::R10: return X86::R10D;
    384     case X86::R11: return X86::R11D;
    385     case X86::R12: return X86::R12D;
    386     case X86::R13: return X86::R13D;
    387     case X86::R14: return X86::R14D;
    388     case X86::R15: return X86::R15D;
    389     case X86::RIP: return X86::EIP;
    390     }
    391   }
    392 
    393   void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
    394     assert(N == 1 && "Invalid number of operands!");
    395     unsigned RegNo = getReg();
    396     if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
    397       RegNo = getGR32FromGR64(RegNo);
    398     Inst.addOperand(MCOperand::CreateReg(RegNo));
    399   }
    400   void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
    401     assert(N == 1 && "Invalid number of operands!");
    402     addExpr(Inst, getImm());
    403   }
    404   void addImmOperands(MCInst &Inst, unsigned N) const {
    405     assert(N == 1 && "Invalid number of operands!");
    406     addExpr(Inst, getImm());
    407   }
    408 
    409   void addMemOperands(MCInst &Inst, unsigned N) const {
    410     assert((N == 5) && "Invalid number of operands!");
    411     Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
    412     Inst.addOperand(MCOperand::CreateImm(getMemScale()));
    413     Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
    414     addExpr(Inst, getMemDisp());
    415     Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
    416   }
    417 
    418   void addAbsMemOperands(MCInst &Inst, unsigned N) const {
    419     assert((N == 1) && "Invalid number of operands!");
    420     // Add as immediates when possible.
    421     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
    422       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
    423     else
    424       Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
    425   }
    426 
    427   void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
    428     assert((N == 2) && "Invalid number of operands!");
    429     Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
    430     Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
    431   }
    432   void addDstIdxOperands(MCInst &Inst, unsigned N) const {
    433     assert((N == 1) && "Invalid number of operands!");
    434     Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
    435   }
    436 
    437   void addMemOffsOperands(MCInst &Inst, unsigned N) const {
    438     assert((N == 2) && "Invalid number of operands!");
    439     // Add as immediates when possible.
    440     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
    441       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
    442     else
    443       Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
    444     Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
    445   }
    446 
    447   static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
    448     SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
    449     auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
    450     Res->Tok.Data = Str.data();
    451     Res->Tok.Length = Str.size();
    452     return Res;
    453   }
    454 
    455   static std::unique_ptr<X86Operand>
    456   CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
    457             bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
    458             StringRef SymName = StringRef(), void *OpDecl = nullptr) {
    459     auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
    460     Res->Reg.RegNo = RegNo;
    461     Res->AddressOf = AddressOf;
    462     Res->OffsetOfLoc = OffsetOfLoc;
    463     Res->SymName = SymName;
    464     Res->OpDecl = OpDecl;
    465     return Res;
    466   }
    467 
    468   static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
    469                                                SMLoc StartLoc, SMLoc EndLoc) {
    470     auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
    471     Res->Imm.Val = Val;
    472     return Res;
    473   }
    474 
    475   /// Create an absolute memory operand.
    476   static std::unique_ptr<X86Operand>
    477   CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
    478             unsigned Size = 0, StringRef SymName = StringRef(),
    479             void *OpDecl = nullptr) {
    480     auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
    481     Res->Mem.SegReg   = 0;
    482     Res->Mem.Disp     = Disp;
    483     Res->Mem.BaseReg  = 0;
    484     Res->Mem.IndexReg = 0;
    485     Res->Mem.Scale    = 1;
    486     Res->Mem.Size     = Size;
    487     Res->Mem.ModeSize = ModeSize;
    488     Res->SymName      = SymName;
    489     Res->OpDecl       = OpDecl;
    490     Res->AddressOf    = false;
    491     return Res;
    492   }
    493 
    494   /// Create a generalized memory operand.
    495   static std::unique_ptr<X86Operand>
    496   CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
    497             unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
    498             SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
    499             void *OpDecl = nullptr) {
    500     // We should never just have a displacement, that should be parsed as an
    501     // absolute memory operand.
    502     assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
    503 
    504     // The scale should always be one of {1,2,4,8}.
    505     assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
    506            "Invalid scale!");
    507     auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
    508     Res->Mem.SegReg   = SegReg;
    509     Res->Mem.Disp     = Disp;
    510     Res->Mem.BaseReg  = BaseReg;
    511     Res->Mem.IndexReg = IndexReg;
    512     Res->Mem.Scale    = Scale;
    513     Res->Mem.Size     = Size;
    514     Res->Mem.ModeSize = ModeSize;
    515     Res->SymName      = SymName;
    516     Res->OpDecl       = OpDecl;
    517     Res->AddressOf    = false;
    518     return Res;
    519   }
    520 };
    521 
    522 } // End of namespace llvm
    523 
    524 #endif
    525