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   bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
    237     assert(Kind == Memory && "Invalid access!");
    238     return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
    239   }
    240 
    241   bool isMem64_RC128() const {
    242     return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
    243   }
    244   bool isMem128_RC128() const {
    245     return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
    246   }
    247   bool isMem128_RC256() const {
    248     return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
    249   }
    250   bool isMem256_RC128() const {
    251     return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
    252   }
    253   bool isMem256_RC256() const {
    254     return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
    255   }
    256 
    257   bool isMem64_RC128X() const {
    258     return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
    259   }
    260   bool isMem128_RC128X() const {
    261     return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
    262   }
    263   bool isMem128_RC256X() const {
    264     return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
    265   }
    266   bool isMem256_RC128X() const {
    267     return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
    268   }
    269   bool isMem256_RC256X() const {
    270     return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
    271   }
    272   bool isMem512_RC256X() const {
    273     return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
    274   }
    275   bool isMem512_RC512() const {
    276     return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
    277   }
    278 
    279   bool isAbsMem() const {
    280     return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
    281       !getMemIndexReg() && getMemScale() == 1;
    282   }
    283   bool isAVX512RC() const{
    284       return isImm();
    285   }
    286 
    287   bool isAbsMem16() const {
    288     return isAbsMem() && Mem.ModeSize == 16;
    289   }
    290 
    291   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   }
    297   bool isSrcIdx8() const {
    298     return isMem8() && isSrcIdx();
    299   }
    300   bool isSrcIdx16() const {
    301     return isMem16() && isSrcIdx();
    302   }
    303   bool isSrcIdx32() const {
    304     return isMem32() && isSrcIdx();
    305   }
    306   bool isSrcIdx64() const {
    307     return isMem64() && isSrcIdx();
    308   }
    309 
    310   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   }
    317   bool isDstIdx8() const {
    318     return isMem8() && isDstIdx();
    319   }
    320   bool isDstIdx16() const {
    321     return isMem16() && isDstIdx();
    322   }
    323   bool isDstIdx32() const {
    324     return isMem32() && isDstIdx();
    325   }
    326   bool isDstIdx64() const {
    327     return isMem64() && isDstIdx();
    328   }
    329 
    330   bool isMemOffs() const {
    331     return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
    332       getMemScale() == 1;
    333   }
    334 
    335   bool isMemOffs16_8() const {
    336     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
    337   }
    338   bool isMemOffs16_16() const {
    339     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
    340   }
    341   bool isMemOffs16_32() const {
    342     return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
    343   }
    344   bool isMemOffs32_8() const {
    345     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
    346   }
    347   bool isMemOffs32_16() const {
    348     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
    349   }
    350   bool isMemOffs32_32() const {
    351     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
    352   }
    353   bool isMemOffs32_64() const {
    354     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
    355   }
    356   bool isMemOffs64_8() const {
    357     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
    358   }
    359   bool isMemOffs64_16() const {
    360     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
    361   }
    362   bool isMemOffs64_32() const {
    363     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
    364   }
    365   bool isMemOffs64_64() const {
    366     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
    367   }
    368 
    369   bool isReg() const override { return Kind == Register; }
    370 
    371   bool isGR32orGR64() const {
    372     return Kind == Register &&
    373       (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
    374       X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
    375   }
    376 
    377   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 
    385   void addRegOperands(MCInst &Inst, unsigned N) const {
    386     assert(N == 1 && "Invalid number of operands!");
    387     Inst.addOperand(MCOperand::createReg(getReg()));
    388   }
    389 
    390   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 
    413   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   }
    420   void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
    421     assert(N == 1 && "Invalid number of operands!");
    422     addExpr(Inst, getImm());
    423   }
    424   void addImmOperands(MCInst &Inst, unsigned N) const {
    425     assert(N == 1 && "Invalid number of operands!");
    426     addExpr(Inst, getImm());
    427   }
    428 
    429   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 
    438   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 
    447   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   }
    452   void addDstIdxOperands(MCInst &Inst, unsigned N) const {
    453     assert((N == 1) && "Invalid number of operands!");
    454     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
    455   }
    456 
    457   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 
    467   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 
    488   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