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 X86_OPERAND_H 11 #define X86_OPERAND_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 }; 57 58 union { 59 struct TokOp Tok; 60 struct RegOp Reg; 61 struct ImmOp Imm; 62 struct MemOp Mem; 63 }; 64 X86OperandX86Operand65 X86Operand(KindTy K, SMLoc Start, SMLoc End) 66 : Kind(K), StartLoc(Start), EndLoc(End) {} 67 getSymNameX86Operand68 StringRef getSymName() override { return SymName; } getOpDeclX86Operand69 void *getOpDecl() override { return OpDecl; } 70 71 /// getStartLoc - Get the location of the first token of this operand. getStartLocX86Operand72 SMLoc getStartLoc() const override { return StartLoc; } 73 /// getEndLoc - Get the location of the last token of this operand. getEndLocX86Operand74 SMLoc getEndLoc() const override { return EndLoc; } 75 /// getLocRange - Get the range between the first and last token of this 76 /// operand. getLocRangeX86Operand77 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } 78 /// getOffsetOfLoc - Get the location of the offset operator. getOffsetOfLocX86Operand79 SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; } 80 printX86Operand81 void print(raw_ostream &OS) const override {} 82 getTokenX86Operand83 StringRef getToken() const { 84 assert(Kind == Token && "Invalid access!"); 85 return StringRef(Tok.Data, Tok.Length); 86 } setTokenValueX86Operand87 void setTokenValue(StringRef Value) { 88 assert(Kind == Token && "Invalid access!"); 89 Tok.Data = Value.data(); 90 Tok.Length = Value.size(); 91 } 92 getRegX86Operand93 unsigned getReg() const override { 94 assert(Kind == Register && "Invalid access!"); 95 return Reg.RegNo; 96 } 97 getImmX86Operand98 const MCExpr *getImm() const { 99 assert(Kind == Immediate && "Invalid access!"); 100 return Imm.Val; 101 } 102 getMemDispX86Operand103 const MCExpr *getMemDisp() const { 104 assert(Kind == Memory && "Invalid access!"); 105 return Mem.Disp; 106 } getMemSegRegX86Operand107 unsigned getMemSegReg() const { 108 assert(Kind == Memory && "Invalid access!"); 109 return Mem.SegReg; 110 } getMemBaseRegX86Operand111 unsigned getMemBaseReg() const { 112 assert(Kind == Memory && "Invalid access!"); 113 return Mem.BaseReg; 114 } getMemIndexRegX86Operand115 unsigned getMemIndexReg() const { 116 assert(Kind == Memory && "Invalid access!"); 117 return Mem.IndexReg; 118 } getMemScaleX86Operand119 unsigned getMemScale() const { 120 assert(Kind == Memory && "Invalid access!"); 121 return Mem.Scale; 122 } 123 isTokenX86Operand124 bool isToken() const override {return Kind == Token; } 125 isImmX86Operand126 bool isImm() const override { return Kind == Immediate; } 127 isImmSExti16i8X86Operand128 bool isImmSExti16i8() const { 129 if (!isImm()) 130 return false; 131 132 // If this isn't a constant expr, just assume it fits and let relaxation 133 // handle it. 134 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 135 if (!CE) 136 return true; 137 138 // Otherwise, check the value is in a range that makes sense for this 139 // extension. 140 return isImmSExti16i8Value(CE->getValue()); 141 } isImmSExti32i8X86Operand142 bool isImmSExti32i8() const { 143 if (!isImm()) 144 return false; 145 146 // If this isn't a constant expr, just assume it fits and let relaxation 147 // handle it. 148 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 149 if (!CE) 150 return true; 151 152 // Otherwise, check the value is in a range that makes sense for this 153 // extension. 154 return isImmSExti32i8Value(CE->getValue()); 155 } isImmZExtu32u8X86Operand156 bool isImmZExtu32u8() const { 157 if (!isImm()) 158 return false; 159 160 // If this isn't a constant expr, just assume it fits and let relaxation 161 // handle it. 162 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 163 if (!CE) 164 return true; 165 166 // Otherwise, check the value is in a range that makes sense for this 167 // extension. 168 return isImmZExtu32u8Value(CE->getValue()); 169 } isImmSExti64i8X86Operand170 bool isImmSExti64i8() const { 171 if (!isImm()) 172 return false; 173 174 // If this isn't a constant expr, just assume it fits and let relaxation 175 // handle it. 176 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 177 if (!CE) 178 return true; 179 180 // Otherwise, check the value is in a range that makes sense for this 181 // extension. 182 return isImmSExti64i8Value(CE->getValue()); 183 } isImmSExti64i32X86Operand184 bool isImmSExti64i32() const { 185 if (!isImm()) 186 return false; 187 188 // If this isn't a constant expr, just assume it fits and let relaxation 189 // handle it. 190 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 191 if (!CE) 192 return true; 193 194 // Otherwise, check the value is in a range that makes sense for this 195 // extension. 196 return isImmSExti64i32Value(CE->getValue()); 197 } 198 isOffsetOfX86Operand199 bool isOffsetOf() const override { 200 return OffsetOfLoc.getPointer(); 201 } 202 needAddressOfX86Operand203 bool needAddressOf() const override { 204 return AddressOf; 205 } 206 isMemX86Operand207 bool isMem() const override { return Kind == Memory; } isMem8X86Operand208 bool isMem8() const { 209 return Kind == Memory && (!Mem.Size || Mem.Size == 8); 210 } isMem16X86Operand211 bool isMem16() const { 212 return Kind == Memory && (!Mem.Size || Mem.Size == 16); 213 } isMem32X86Operand214 bool isMem32() const { 215 return Kind == Memory && (!Mem.Size || Mem.Size == 32); 216 } isMem64X86Operand217 bool isMem64() const { 218 return Kind == Memory && (!Mem.Size || Mem.Size == 64); 219 } isMem80X86Operand220 bool isMem80() const { 221 return Kind == Memory && (!Mem.Size || Mem.Size == 80); 222 } isMem128X86Operand223 bool isMem128() const { 224 return Kind == Memory && (!Mem.Size || Mem.Size == 128); 225 } isMem256X86Operand226 bool isMem256() const { 227 return Kind == Memory && (!Mem.Size || Mem.Size == 256); 228 } isMem512X86Operand229 bool isMem512() const { 230 return Kind == Memory && (!Mem.Size || Mem.Size == 512); 231 } 232 isMemVX32X86Operand233 bool isMemVX32() const { 234 return Kind == Memory && (!Mem.Size || Mem.Size == 32) && 235 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15; 236 } isMemVY32X86Operand237 bool isMemVY32() const { 238 return Kind == Memory && (!Mem.Size || Mem.Size == 32) && 239 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15; 240 } isMemVX64X86Operand241 bool isMemVX64() const { 242 return Kind == Memory && (!Mem.Size || Mem.Size == 64) && 243 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15; 244 } isMemVY64X86Operand245 bool isMemVY64() const { 246 return Kind == Memory && (!Mem.Size || Mem.Size == 64) && 247 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15; 248 } isMemVZ32X86Operand249 bool isMemVZ32() const { 250 return Kind == Memory && (!Mem.Size || Mem.Size == 32) && 251 getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31; 252 } isMemVZ64X86Operand253 bool isMemVZ64() const { 254 return Kind == Memory && (!Mem.Size || Mem.Size == 64) && 255 getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31; 256 } 257 isAbsMemX86Operand258 bool isAbsMem() const { 259 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() && 260 !getMemIndexReg() && getMemScale() == 1; 261 } 262 isSrcIdxX86Operand263 bool isSrcIdx() const { 264 return !getMemIndexReg() && getMemScale() == 1 && 265 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI || 266 getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) && 267 cast<MCConstantExpr>(getMemDisp())->getValue() == 0; 268 } isSrcIdx8X86Operand269 bool isSrcIdx8() const { 270 return isMem8() && isSrcIdx(); 271 } isSrcIdx16X86Operand272 bool isSrcIdx16() const { 273 return isMem16() && isSrcIdx(); 274 } isSrcIdx32X86Operand275 bool isSrcIdx32() const { 276 return isMem32() && isSrcIdx(); 277 } isSrcIdx64X86Operand278 bool isSrcIdx64() const { 279 return isMem64() && isSrcIdx(); 280 } 281 isDstIdxX86Operand282 bool isDstIdx() const { 283 return !getMemIndexReg() && getMemScale() == 1 && 284 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) && 285 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI || 286 getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) && 287 cast<MCConstantExpr>(getMemDisp())->getValue() == 0; 288 } isDstIdx8X86Operand289 bool isDstIdx8() const { 290 return isMem8() && isDstIdx(); 291 } isDstIdx16X86Operand292 bool isDstIdx16() const { 293 return isMem16() && isDstIdx(); 294 } isDstIdx32X86Operand295 bool isDstIdx32() const { 296 return isMem32() && isDstIdx(); 297 } isDstIdx64X86Operand298 bool isDstIdx64() const { 299 return isMem64() && isDstIdx(); 300 } 301 isMemOffs8X86Operand302 bool isMemOffs8() const { 303 return Kind == Memory && !getMemBaseReg() && 304 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 8); 305 } isMemOffs16X86Operand306 bool isMemOffs16() const { 307 return Kind == Memory && !getMemBaseReg() && 308 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 16); 309 } isMemOffs32X86Operand310 bool isMemOffs32() const { 311 return Kind == Memory && !getMemBaseReg() && 312 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 32); 313 } isMemOffs64X86Operand314 bool isMemOffs64() const { 315 return Kind == Memory && !getMemBaseReg() && 316 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 64); 317 } 318 isRegX86Operand319 bool isReg() const override { return Kind == Register; } 320 isGR32orGR64X86Operand321 bool isGR32orGR64() const { 322 return Kind == Register && 323 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) || 324 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg())); 325 } 326 addExprX86Operand327 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 328 // Add as immediates when possible. 329 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 330 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 331 else 332 Inst.addOperand(MCOperand::CreateExpr(Expr)); 333 } 334 addRegOperandsX86Operand335 void addRegOperands(MCInst &Inst, unsigned N) const { 336 assert(N == 1 && "Invalid number of operands!"); 337 Inst.addOperand(MCOperand::CreateReg(getReg())); 338 } 339 getGR32FromGR64X86Operand340 static unsigned getGR32FromGR64(unsigned RegNo) { 341 switch (RegNo) { 342 default: llvm_unreachable("Unexpected register"); 343 case X86::RAX: return X86::EAX; 344 case X86::RCX: return X86::ECX; 345 case X86::RDX: return X86::EDX; 346 case X86::RBX: return X86::EBX; 347 case X86::RBP: return X86::EBP; 348 case X86::RSP: return X86::ESP; 349 case X86::RSI: return X86::ESI; 350 case X86::RDI: return X86::EDI; 351 case X86::R8: return X86::R8D; 352 case X86::R9: return X86::R9D; 353 case X86::R10: return X86::R10D; 354 case X86::R11: return X86::R11D; 355 case X86::R12: return X86::R12D; 356 case X86::R13: return X86::R13D; 357 case X86::R14: return X86::R14D; 358 case X86::R15: return X86::R15D; 359 case X86::RIP: return X86::EIP; 360 } 361 } 362 addGR32orGR64OperandsX86Operand363 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const { 364 assert(N == 1 && "Invalid number of operands!"); 365 unsigned RegNo = getReg(); 366 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo)) 367 RegNo = getGR32FromGR64(RegNo); 368 Inst.addOperand(MCOperand::CreateReg(RegNo)); 369 } 370 addImmOperandsX86Operand371 void addImmOperands(MCInst &Inst, unsigned N) const { 372 assert(N == 1 && "Invalid number of operands!"); 373 addExpr(Inst, getImm()); 374 } 375 addMemOperandsX86Operand376 void addMemOperands(MCInst &Inst, unsigned N) const { 377 assert((N == 5) && "Invalid number of operands!"); 378 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); 379 Inst.addOperand(MCOperand::CreateImm(getMemScale())); 380 Inst.addOperand(MCOperand::CreateReg(getMemIndexReg())); 381 addExpr(Inst, getMemDisp()); 382 Inst.addOperand(MCOperand::CreateReg(getMemSegReg())); 383 } 384 addAbsMemOperandsX86Operand385 void addAbsMemOperands(MCInst &Inst, unsigned N) const { 386 assert((N == 1) && "Invalid number of operands!"); 387 // Add as immediates when possible. 388 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp())) 389 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 390 else 391 Inst.addOperand(MCOperand::CreateExpr(getMemDisp())); 392 } 393 addSrcIdxOperandsX86Operand394 void addSrcIdxOperands(MCInst &Inst, unsigned N) const { 395 assert((N == 2) && "Invalid number of operands!"); 396 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); 397 Inst.addOperand(MCOperand::CreateReg(getMemSegReg())); 398 } addDstIdxOperandsX86Operand399 void addDstIdxOperands(MCInst &Inst, unsigned N) const { 400 assert((N == 1) && "Invalid number of operands!"); 401 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); 402 } 403 addMemOffsOperandsX86Operand404 void addMemOffsOperands(MCInst &Inst, unsigned N) const { 405 assert((N == 2) && "Invalid number of operands!"); 406 // Add as immediates when possible. 407 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp())) 408 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 409 else 410 Inst.addOperand(MCOperand::CreateExpr(getMemDisp())); 411 Inst.addOperand(MCOperand::CreateReg(getMemSegReg())); 412 } 413 CreateTokenX86Operand414 static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) { 415 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size()); 416 auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc); 417 Res->Tok.Data = Str.data(); 418 Res->Tok.Length = Str.size(); 419 return Res; 420 } 421 422 static std::unique_ptr<X86Operand> 423 CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc, 424 bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(), 425 StringRef SymName = StringRef(), void *OpDecl = nullptr) { 426 auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc); 427 Res->Reg.RegNo = RegNo; 428 Res->AddressOf = AddressOf; 429 Res->OffsetOfLoc = OffsetOfLoc; 430 Res->SymName = SymName; 431 Res->OpDecl = OpDecl; 432 return Res; 433 } 434 CreateImmX86Operand435 static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val, 436 SMLoc StartLoc, SMLoc EndLoc) { 437 auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc); 438 Res->Imm.Val = Val; 439 return Res; 440 } 441 442 /// Create an absolute memory operand. 443 static std::unique_ptr<X86Operand> 444 CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size = 0, 445 StringRef SymName = StringRef(), void *OpDecl = nullptr) { 446 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc); 447 Res->Mem.SegReg = 0; 448 Res->Mem.Disp = Disp; 449 Res->Mem.BaseReg = 0; 450 Res->Mem.IndexReg = 0; 451 Res->Mem.Scale = 1; 452 Res->Mem.Size = Size; 453 Res->SymName = SymName; 454 Res->OpDecl = OpDecl; 455 Res->AddressOf = false; 456 return Res; 457 } 458 459 /// Create a generalized memory operand. 460 static std::unique_ptr<X86Operand> 461 CreateMem(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, 462 unsigned IndexReg, unsigned Scale, SMLoc StartLoc, SMLoc EndLoc, 463 unsigned Size = 0, StringRef SymName = StringRef(), 464 void *OpDecl = nullptr) { 465 // We should never just have a displacement, that should be parsed as an 466 // absolute memory operand. 467 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!"); 468 469 // The scale should always be one of {1,2,4,8}. 470 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) && 471 "Invalid scale!"); 472 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc); 473 Res->Mem.SegReg = SegReg; 474 Res->Mem.Disp = Disp; 475 Res->Mem.BaseReg = BaseReg; 476 Res->Mem.IndexReg = IndexReg; 477 Res->Mem.Scale = Scale; 478 Res->Mem.Size = Size; 479 Res->SymName = SymName; 480 Res->OpDecl = OpDecl; 481 Res->AddressOf = false; 482 return Res; 483 } 484 }; 485 486 } // End of namespace llvm 487 488 #endif // X86_OPERAND 489