X86Operand.h revision de2d8694e25a814696358e95141f4b1aa4d8847e
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 21namespace llvm { 22 23/// X86Operand - Instances of this class represent a parsed X86 machine 24/// instruction. 25struct 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