LLVM API Documentation
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