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 X86OperandX86Operand66 X86Operand(KindTy K, SMLoc Start, SMLoc End) 67 : Kind(K), StartLoc(Start), EndLoc(End) {} 68 getSymNameX86Operand69 StringRef getSymName() override { return SymName; } getOpDeclX86Operand70 void *getOpDecl() override { return OpDecl; } 71 72 /// getStartLoc - Get the location of the first token of this operand. getStartLocX86Operand73 SMLoc getStartLoc() const override { return StartLoc; } 74 /// getEndLoc - Get the location of the last token of this operand. getEndLocX86Operand75 SMLoc getEndLoc() const override { return EndLoc; } 76 /// getLocRange - Get the range between the first and last token of this 77 /// operand. getLocRangeX86Operand78 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } 79 /// getOffsetOfLoc - Get the location of the offset operator. getOffsetOfLocX86Operand80 SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; } 81 printX86Operand82 void print(raw_ostream &OS) const override {} 83 getTokenX86Operand84 StringRef getToken() const { 85 assert(Kind == Token && "Invalid access!"); 86 return StringRef(Tok.Data, Tok.Length); 87 } setTokenValueX86Operand88 void setTokenValue(StringRef Value) { 89 assert(Kind == Token && "Invalid access!"); 90 Tok.Data = Value.data(); 91 Tok.Length = Value.size(); 92 } 93 getRegX86Operand94 unsigned getReg() const override { 95 assert(Kind == Register && "Invalid access!"); 96 return Reg.RegNo; 97 } 98 getImmX86Operand99 const MCExpr *getImm() const { 100 assert(Kind == Immediate && "Invalid access!"); 101 return Imm.Val; 102 } 103 getMemDispX86Operand104 const MCExpr *getMemDisp() const { 105 assert(Kind == Memory && "Invalid access!"); 106 return Mem.Disp; 107 } getMemSegRegX86Operand108 unsigned getMemSegReg() const { 109 assert(Kind == Memory && "Invalid access!"); 110 return Mem.SegReg; 111 } getMemBaseRegX86Operand112 unsigned getMemBaseReg() const { 113 assert(Kind == Memory && "Invalid access!"); 114 return Mem.BaseReg; 115 } getMemIndexRegX86Operand116 unsigned getMemIndexReg() const { 117 assert(Kind == Memory && "Invalid access!"); 118 return Mem.IndexReg; 119 } getMemScaleX86Operand120 unsigned getMemScale() const { 121 assert(Kind == Memory && "Invalid access!"); 122 return Mem.Scale; 123 } getMemModeSizeX86Operand124 unsigned getMemModeSize() const { 125 assert(Kind == Memory && "Invalid access!"); 126 return Mem.ModeSize; 127 } 128 isTokenX86Operand129 bool isToken() const override {return Kind == Token; } 130 isImmX86Operand131 bool isImm() const override { return Kind == Immediate; } 132 isImmSExti16i8X86Operand133 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 } isImmSExti32i8X86Operand147 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 } isImmSExti64i8X86Operand161 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 } isImmSExti64i32X86Operand175 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 isImmUnsignedi8X86Operand190 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 isOffsetOfX86Operand197 bool isOffsetOf() const override { 198 return OffsetOfLoc.getPointer(); 199 } 200 needAddressOfX86Operand201 bool needAddressOf() const override { 202 return AddressOf; 203 } 204 isMemX86Operand205 bool isMem() const override { return Kind == Memory; } isMemUnsizedX86Operand206 bool isMemUnsized() const { 207 return Kind == Memory && Mem.Size == 0; 208 } isMem8X86Operand209 bool isMem8() const { 210 return Kind == Memory && (!Mem.Size || Mem.Size == 8); 211 } isMem16X86Operand212 bool isMem16() const { 213 return Kind == Memory && (!Mem.Size || Mem.Size == 16); 214 } isMem32X86Operand215 bool isMem32() const { 216 return Kind == Memory && (!Mem.Size || Mem.Size == 32); 217 } isMem64X86Operand218 bool isMem64() const { 219 return Kind == Memory && (!Mem.Size || Mem.Size == 64); 220 } isMem80X86Operand221 bool isMem80() const { 222 return Kind == Memory && (!Mem.Size || Mem.Size == 80); 223 } isMem128X86Operand224 bool isMem128() const { 225 return Kind == Memory && (!Mem.Size || Mem.Size == 128); 226 } isMem256X86Operand227 bool isMem256() const { 228 return Kind == Memory && (!Mem.Size || Mem.Size == 256); 229 } isMem512X86Operand230 bool isMem512() const { 231 return Kind == Memory && (!Mem.Size || Mem.Size == 512); 232 } 233 isMemVX32X86Operand234 bool isMemVX32() const { 235 return Kind == Memory && (!Mem.Size || Mem.Size == 32) && 236 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15; 237 } isMemVY32X86Operand238 bool isMemVY32() const { 239 return Kind == Memory && (!Mem.Size || Mem.Size == 32) && 240 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15; 241 } isMemVX64X86Operand242 bool isMemVX64() const { 243 return Kind == Memory && (!Mem.Size || Mem.Size == 64) && 244 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15; 245 } isMemVY64X86Operand246 bool isMemVY64() const { 247 return Kind == Memory && (!Mem.Size || Mem.Size == 64) && 248 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15; 249 } isMemVZ32X86Operand250 bool isMemVZ32() const { 251 return Kind == Memory && (!Mem.Size || Mem.Size == 32) && 252 getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31; 253 } isMemVZ64X86Operand254 bool isMemVZ64() const { 255 return Kind == Memory && (!Mem.Size || Mem.Size == 64) && 256 getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31; 257 } 258 isAbsMemX86Operand259 bool isAbsMem() const { 260 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() && 261 !getMemIndexReg() && getMemScale() == 1; 262 } isAVX512RCX86Operand263 bool isAVX512RC() const{ 264 return isImm(); 265 } 266 isAbsMem16X86Operand267 bool isAbsMem16() const { 268 return isAbsMem() && Mem.ModeSize == 16; 269 } 270 isSrcIdxX86Operand271 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 } isSrcIdx8X86Operand277 bool isSrcIdx8() const { 278 return isMem8() && isSrcIdx(); 279 } isSrcIdx16X86Operand280 bool isSrcIdx16() const { 281 return isMem16() && isSrcIdx(); 282 } isSrcIdx32X86Operand283 bool isSrcIdx32() const { 284 return isMem32() && isSrcIdx(); 285 } isSrcIdx64X86Operand286 bool isSrcIdx64() const { 287 return isMem64() && isSrcIdx(); 288 } 289 isDstIdxX86Operand290 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 } isDstIdx8X86Operand297 bool isDstIdx8() const { 298 return isMem8() && isDstIdx(); 299 } isDstIdx16X86Operand300 bool isDstIdx16() const { 301 return isMem16() && isDstIdx(); 302 } isDstIdx32X86Operand303 bool isDstIdx32() const { 304 return isMem32() && isDstIdx(); 305 } isDstIdx64X86Operand306 bool isDstIdx64() const { 307 return isMem64() && isDstIdx(); 308 } 309 isMemOffsX86Operand310 bool isMemOffs() const { 311 return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() && 312 getMemScale() == 1; 313 } 314 isMemOffs16_8X86Operand315 bool isMemOffs16_8() const { 316 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8); 317 } isMemOffs16_16X86Operand318 bool isMemOffs16_16() const { 319 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16); 320 } isMemOffs16_32X86Operand321 bool isMemOffs16_32() const { 322 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32); 323 } isMemOffs32_8X86Operand324 bool isMemOffs32_8() const { 325 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8); 326 } isMemOffs32_16X86Operand327 bool isMemOffs32_16() const { 328 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16); 329 } isMemOffs32_32X86Operand330 bool isMemOffs32_32() const { 331 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32); 332 } isMemOffs32_64X86Operand333 bool isMemOffs32_64() const { 334 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64); 335 } isMemOffs64_8X86Operand336 bool isMemOffs64_8() const { 337 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8); 338 } isMemOffs64_16X86Operand339 bool isMemOffs64_16() const { 340 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16); 341 } isMemOffs64_32X86Operand342 bool isMemOffs64_32() const { 343 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32); 344 } isMemOffs64_64X86Operand345 bool isMemOffs64_64() const { 346 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64); 347 } 348 isRegX86Operand349 bool isReg() const override { return Kind == Register; } 350 isGR32orGR64X86Operand351 bool isGR32orGR64() const { 352 return Kind == Register && 353 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) || 354 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg())); 355 } 356 addExprX86Operand357 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 addRegOperandsX86Operand365 void addRegOperands(MCInst &Inst, unsigned N) const { 366 assert(N == 1 && "Invalid number of operands!"); 367 Inst.addOperand(MCOperand::CreateReg(getReg())); 368 } 369 getGR32FromGR64X86Operand370 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 addGR32orGR64OperandsX86Operand393 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 } addAVX512RCOperandsX86Operand400 void addAVX512RCOperands(MCInst &Inst, unsigned N) const { 401 assert(N == 1 && "Invalid number of operands!"); 402 addExpr(Inst, getImm()); 403 } addImmOperandsX86Operand404 void addImmOperands(MCInst &Inst, unsigned N) const { 405 assert(N == 1 && "Invalid number of operands!"); 406 addExpr(Inst, getImm()); 407 } 408 addMemOperandsX86Operand409 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 addAbsMemOperandsX86Operand418 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 addSrcIdxOperandsX86Operand427 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 } addDstIdxOperandsX86Operand432 void addDstIdxOperands(MCInst &Inst, unsigned N) const { 433 assert((N == 1) && "Invalid number of operands!"); 434 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); 435 } 436 addMemOffsOperandsX86Operand437 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 CreateTokenX86Operand447 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 CreateImmX86Operand468 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