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