LLVM API Documentation

X86Operand.h
Go to the documentation of this file.
00001 //===-- X86Operand.h - Parsed X86 machine instruction --------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
00011 #define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
00012 
00013 #include "X86AsmParserCommon.h"
00014 #include "llvm/MC/MCExpr.h"
00015 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
00016 #include "llvm/ADT/STLExtras.h"
00017 
00018 namespace llvm {
00019 
00020 /// X86Operand - Instances of this class represent a parsed X86 machine
00021 /// instruction.
00022 struct X86Operand : public MCParsedAsmOperand {
00023   enum KindTy {
00024     Token,
00025     Register,
00026     Immediate,
00027     Memory
00028   } Kind;
00029 
00030   SMLoc StartLoc, EndLoc;
00031   SMLoc OffsetOfLoc;
00032   StringRef SymName;
00033   void *OpDecl;
00034   bool AddressOf;
00035 
00036   struct TokOp {
00037     const char *Data;
00038     unsigned Length;
00039   };
00040 
00041   struct RegOp {
00042     unsigned RegNo;
00043   };
00044 
00045   struct ImmOp {
00046     const MCExpr *Val;
00047   };
00048 
00049   struct MemOp {
00050     unsigned SegReg;
00051     const MCExpr *Disp;
00052     unsigned BaseReg;
00053     unsigned IndexReg;
00054     unsigned Scale;
00055     unsigned Size;
00056   };
00057 
00058   union {
00059     struct TokOp Tok;
00060     struct RegOp Reg;
00061     struct ImmOp Imm;
00062     struct MemOp Mem;
00063   };
00064 
00065   X86Operand(KindTy K, SMLoc Start, SMLoc End)
00066     : Kind(K), StartLoc(Start), EndLoc(End) {}
00067 
00068   StringRef getSymName() override { return SymName; }
00069   void *getOpDecl() override { return OpDecl; }
00070 
00071   /// getStartLoc - Get the location of the first token of this operand.
00072   SMLoc getStartLoc() const override { return StartLoc; }
00073   /// getEndLoc - Get the location of the last token of this operand.
00074   SMLoc getEndLoc() const override { return EndLoc; }
00075   /// getLocRange - Get the range between the first and last token of this
00076   /// operand.
00077   SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
00078   /// getOffsetOfLoc - Get the location of the offset operator.
00079   SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
00080 
00081   void print(raw_ostream &OS) const override {}
00082 
00083   StringRef getToken() const {
00084     assert(Kind == Token && "Invalid access!");
00085     return StringRef(Tok.Data, Tok.Length);
00086   }
00087   void setTokenValue(StringRef Value) {
00088     assert(Kind == Token && "Invalid access!");
00089     Tok.Data = Value.data();
00090     Tok.Length = Value.size();
00091   }
00092 
00093   unsigned getReg() const override {
00094     assert(Kind == Register && "Invalid access!");
00095     return Reg.RegNo;
00096   }
00097 
00098   const MCExpr *getImm() const {
00099     assert(Kind == Immediate && "Invalid access!");
00100     return Imm.Val;
00101   }
00102 
00103   const MCExpr *getMemDisp() const {
00104     assert(Kind == Memory && "Invalid access!");
00105     return Mem.Disp;
00106   }
00107   unsigned getMemSegReg() const {
00108     assert(Kind == Memory && "Invalid access!");
00109     return Mem.SegReg;
00110   }
00111   unsigned getMemBaseReg() const {
00112     assert(Kind == Memory && "Invalid access!");
00113     return Mem.BaseReg;
00114   }
00115   unsigned getMemIndexReg() const {
00116     assert(Kind == Memory && "Invalid access!");
00117     return Mem.IndexReg;
00118   }
00119   unsigned getMemScale() const {
00120     assert(Kind == Memory && "Invalid access!");
00121     return Mem.Scale;
00122   }
00123 
00124   bool isToken() const override {return Kind == Token; }
00125 
00126   bool isImm() const override { return Kind == Immediate; }
00127 
00128   bool isImmSExti16i8() const {
00129     if (!isImm())
00130       return false;
00131 
00132     // If this isn't a constant expr, just assume it fits and let relaxation
00133     // handle it.
00134     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
00135     if (!CE)
00136       return true;
00137 
00138     // Otherwise, check the value is in a range that makes sense for this
00139     // extension.
00140     return isImmSExti16i8Value(CE->getValue());
00141   }
00142   bool isImmSExti32i8() const {
00143     if (!isImm())
00144       return false;
00145 
00146     // If this isn't a constant expr, just assume it fits and let relaxation
00147     // handle it.
00148     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
00149     if (!CE)
00150       return true;
00151 
00152     // Otherwise, check the value is in a range that makes sense for this
00153     // extension.
00154     return isImmSExti32i8Value(CE->getValue());
00155   }
00156   bool isImmSExti64i8() const {
00157     if (!isImm())
00158       return false;
00159 
00160     // If this isn't a constant expr, just assume it fits and let relaxation
00161     // handle it.
00162     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
00163     if (!CE)
00164       return true;
00165 
00166     // Otherwise, check the value is in a range that makes sense for this
00167     // extension.
00168     return isImmSExti64i8Value(CE->getValue());
00169   }
00170   bool isImmSExti64i32() const {
00171     if (!isImm())
00172       return false;
00173 
00174     // If this isn't a constant expr, just assume it fits and let relaxation
00175     // handle it.
00176     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
00177     if (!CE)
00178       return true;
00179 
00180     // Otherwise, check the value is in a range that makes sense for this
00181     // extension.
00182     return isImmSExti64i32Value(CE->getValue());
00183   }
00184 
00185   bool isOffsetOf() const override {
00186     return OffsetOfLoc.getPointer();
00187   }
00188 
00189   bool needAddressOf() const override {
00190     return AddressOf;
00191   }
00192 
00193   bool isMem() const override { return Kind == Memory; }
00194   bool isMemUnsized() const {
00195     return Kind == Memory && Mem.Size == 0;
00196   }
00197   bool isMem8() const {
00198     return Kind == Memory && (!Mem.Size || Mem.Size == 8);
00199   }
00200   bool isMem16() const {
00201     return Kind == Memory && (!Mem.Size || Mem.Size == 16);
00202   }
00203   bool isMem32() const {
00204     return Kind == Memory && (!Mem.Size || Mem.Size == 32);
00205   }
00206   bool isMem64() const {
00207     return Kind == Memory && (!Mem.Size || Mem.Size == 64);
00208   }
00209   bool isMem80() const {
00210     return Kind == Memory && (!Mem.Size || Mem.Size == 80);
00211   }
00212   bool isMem128() const {
00213     return Kind == Memory && (!Mem.Size || Mem.Size == 128);
00214   }
00215   bool isMem256() const {
00216     return Kind == Memory && (!Mem.Size || Mem.Size == 256);
00217   }
00218   bool isMem512() const {
00219     return Kind == Memory && (!Mem.Size || Mem.Size == 512);
00220   }
00221 
00222   bool isMemVX32() const {
00223     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
00224       getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
00225   }
00226   bool isMemVY32() const {
00227     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
00228       getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
00229   }
00230   bool isMemVX64() const {
00231     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
00232       getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
00233   }
00234   bool isMemVY64() const {
00235     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
00236       getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
00237   }
00238   bool isMemVZ32() const {
00239     return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
00240       getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
00241   }
00242   bool isMemVZ64() const {
00243     return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
00244       getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
00245   }
00246 
00247   bool isAbsMem() const {
00248     return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
00249       !getMemIndexReg() && getMemScale() == 1;
00250   }
00251 
00252   bool isSrcIdx() const {
00253     return !getMemIndexReg() && getMemScale() == 1 &&
00254       (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
00255        getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
00256       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
00257   }
00258   bool isSrcIdx8() const {
00259     return isMem8() && isSrcIdx();
00260   }
00261   bool isSrcIdx16() const {
00262     return isMem16() && isSrcIdx();
00263   }
00264   bool isSrcIdx32() const {
00265     return isMem32() && isSrcIdx();
00266   }
00267   bool isSrcIdx64() const {
00268     return isMem64() && isSrcIdx();
00269   }
00270 
00271   bool isDstIdx() const {
00272     return !getMemIndexReg() && getMemScale() == 1 &&
00273       (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
00274       (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
00275        getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
00276       cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
00277   }
00278   bool isDstIdx8() const {
00279     return isMem8() && isDstIdx();
00280   }
00281   bool isDstIdx16() const {
00282     return isMem16() && isDstIdx();
00283   }
00284   bool isDstIdx32() const {
00285     return isMem32() && isDstIdx();
00286   }
00287   bool isDstIdx64() const {
00288     return isMem64() && isDstIdx();
00289   }
00290 
00291   bool isMemOffs8() const {
00292     return Kind == Memory && !getMemBaseReg() &&
00293       !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 8);
00294   }
00295   bool isMemOffs16() const {
00296     return Kind == Memory && !getMemBaseReg() &&
00297       !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 16);
00298   }
00299   bool isMemOffs32() const {
00300     return Kind == Memory && !getMemBaseReg() &&
00301       !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 32);
00302   }
00303   bool isMemOffs64() const {
00304     return Kind == Memory && !getMemBaseReg() &&
00305       !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 64);
00306   }
00307 
00308   bool isReg() const override { return Kind == Register; }
00309 
00310   bool isGR32orGR64() const {
00311     return Kind == Register &&
00312       (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
00313       X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
00314   }
00315 
00316   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
00317     // Add as immediates when possible.
00318     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
00319       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
00320     else
00321       Inst.addOperand(MCOperand::CreateExpr(Expr));
00322   }
00323 
00324   void addRegOperands(MCInst &Inst, unsigned N) const {
00325     assert(N == 1 && "Invalid number of operands!");
00326     Inst.addOperand(MCOperand::CreateReg(getReg()));
00327   }
00328 
00329   static unsigned getGR32FromGR64(unsigned RegNo) {
00330     switch (RegNo) {
00331     default: llvm_unreachable("Unexpected register");
00332     case X86::RAX: return X86::EAX;
00333     case X86::RCX: return X86::ECX;
00334     case X86::RDX: return X86::EDX;
00335     case X86::RBX: return X86::EBX;
00336     case X86::RBP: return X86::EBP;
00337     case X86::RSP: return X86::ESP;
00338     case X86::RSI: return X86::ESI;
00339     case X86::RDI: return X86::EDI;
00340     case X86::R8: return X86::R8D;
00341     case X86::R9: return X86::R9D;
00342     case X86::R10: return X86::R10D;
00343     case X86::R11: return X86::R11D;
00344     case X86::R12: return X86::R12D;
00345     case X86::R13: return X86::R13D;
00346     case X86::R14: return X86::R14D;
00347     case X86::R15: return X86::R15D;
00348     case X86::RIP: return X86::EIP;
00349     }
00350   }
00351 
00352   void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
00353     assert(N == 1 && "Invalid number of operands!");
00354     unsigned RegNo = getReg();
00355     if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
00356       RegNo = getGR32FromGR64(RegNo);
00357     Inst.addOperand(MCOperand::CreateReg(RegNo));
00358   }
00359 
00360   void addImmOperands(MCInst &Inst, unsigned N) const {
00361     assert(N == 1 && "Invalid number of operands!");
00362     addExpr(Inst, getImm());
00363   }
00364 
00365   void addMemOperands(MCInst &Inst, unsigned N) const {
00366     assert((N == 5) && "Invalid number of operands!");
00367     Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
00368     Inst.addOperand(MCOperand::CreateImm(getMemScale()));
00369     Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
00370     addExpr(Inst, getMemDisp());
00371     Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
00372   }
00373 
00374   void addAbsMemOperands(MCInst &Inst, unsigned N) const {
00375     assert((N == 1) && "Invalid number of operands!");
00376     // Add as immediates when possible.
00377     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
00378       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
00379     else
00380       Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
00381   }
00382 
00383   void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
00384     assert((N == 2) && "Invalid number of operands!");
00385     Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
00386     Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
00387   }
00388   void addDstIdxOperands(MCInst &Inst, unsigned N) const {
00389     assert((N == 1) && "Invalid number of operands!");
00390     Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
00391   }
00392 
00393   void addMemOffsOperands(MCInst &Inst, unsigned N) const {
00394     assert((N == 2) && "Invalid number of operands!");
00395     // Add as immediates when possible.
00396     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
00397       Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
00398     else
00399       Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
00400     Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
00401   }
00402 
00403   static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
00404     SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
00405     auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
00406     Res->Tok.Data = Str.data();
00407     Res->Tok.Length = Str.size();
00408     return Res;
00409   }
00410 
00411   static std::unique_ptr<X86Operand>
00412   CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
00413             bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
00414             StringRef SymName = StringRef(), void *OpDecl = nullptr) {
00415     auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
00416     Res->Reg.RegNo = RegNo;
00417     Res->AddressOf = AddressOf;
00418     Res->OffsetOfLoc = OffsetOfLoc;
00419     Res->SymName = SymName;
00420     Res->OpDecl = OpDecl;
00421     return Res;
00422   }
00423 
00424   static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
00425                                                SMLoc StartLoc, SMLoc EndLoc) {
00426     auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
00427     Res->Imm.Val = Val;
00428     return Res;
00429   }
00430 
00431   /// Create an absolute memory operand.
00432   static std::unique_ptr<X86Operand>
00433   CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size = 0,
00434             StringRef SymName = StringRef(), void *OpDecl = nullptr) {
00435     auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
00436     Res->Mem.SegReg   = 0;
00437     Res->Mem.Disp     = Disp;
00438     Res->Mem.BaseReg  = 0;
00439     Res->Mem.IndexReg = 0;
00440     Res->Mem.Scale    = 1;
00441     Res->Mem.Size     = Size;
00442     Res->SymName      = SymName;
00443     Res->OpDecl       = OpDecl;
00444     Res->AddressOf    = false;
00445     return Res;
00446   }
00447 
00448   /// Create a generalized memory operand.
00449   static std::unique_ptr<X86Operand>
00450   CreateMem(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
00451             unsigned IndexReg, unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
00452             unsigned Size = 0, StringRef SymName = StringRef(),
00453             void *OpDecl = nullptr) {
00454     // We should never just have a displacement, that should be parsed as an
00455     // absolute memory operand.
00456     assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
00457 
00458     // The scale should always be one of {1,2,4,8}.
00459     assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
00460            "Invalid scale!");
00461     auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
00462     Res->Mem.SegReg   = SegReg;
00463     Res->Mem.Disp     = Disp;
00464     Res->Mem.BaseReg  = BaseReg;
00465     Res->Mem.IndexReg = IndexReg;
00466     Res->Mem.Scale    = Scale;
00467     Res->Mem.Size     = Size;
00468     Res->SymName      = SymName;
00469     Res->OpDecl       = OpDecl;
00470     Res->AddressOf    = false;
00471     return Res;
00472   }
00473 };
00474 
00475 } // End of namespace llvm
00476 
00477 #endif