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