1 //===-- X86Operand.h - Parsed X86 machine instruction --------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
11 #define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
13 #include "X86AsmParserCommon.h"
14 #include "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
16 #include "llvm/ADT/STLExtras.h"
20 /// X86Operand - Instances of this class represent a parsed X86 machine
22 struct X86Operand : public MCParsedAsmOperand {
30 SMLoc StartLoc, EndLoc;
66 X86Operand(KindTy K, SMLoc Start, SMLoc End)
67 : Kind(K), StartLoc(Start), EndLoc(End) {}
69 StringRef getSymName() override { return SymName; }
70 void *getOpDecl() override { return OpDecl; }
72 /// getStartLoc - Get the location of the first token of this operand.
73 SMLoc getStartLoc() const override { return StartLoc; }
74 /// getEndLoc - Get the location of the last token of this operand.
75 SMLoc getEndLoc() const override { return EndLoc; }
76 /// getLocRange - Get the range between the first and last token of this
78 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
79 /// getOffsetOfLoc - Get the location of the offset operator.
80 SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
82 void print(raw_ostream &OS) const override {}
84 StringRef getToken() const {
85 assert(Kind == Token && "Invalid access!");
86 return StringRef(Tok.Data, Tok.Length);
88 void setTokenValue(StringRef Value) {
89 assert(Kind == Token && "Invalid access!");
90 Tok.Data = Value.data();
91 Tok.Length = Value.size();
94 unsigned getReg() const override {
95 assert(Kind == Register && "Invalid access!");
99 const MCExpr *getImm() const {
100 assert(Kind == Immediate && "Invalid access!");
104 const MCExpr *getMemDisp() const {
105 assert(Kind == Memory && "Invalid access!");
108 unsigned getMemSegReg() const {
109 assert(Kind == Memory && "Invalid access!");
112 unsigned getMemBaseReg() const {
113 assert(Kind == Memory && "Invalid access!");
116 unsigned getMemIndexReg() const {
117 assert(Kind == Memory && "Invalid access!");
120 unsigned getMemScale() const {
121 assert(Kind == Memory && "Invalid access!");
124 unsigned getMemModeSize() const {
125 assert(Kind == Memory && "Invalid access!");
129 bool isToken() const override {return Kind == Token; }
131 bool isImm() const override { return Kind == Immediate; }
133 bool isImmSExti16i8() const {
137 // If this isn't a constant expr, just assume it fits and let relaxation
139 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
143 // Otherwise, check the value is in a range that makes sense for this
145 return isImmSExti16i8Value(CE->getValue());
147 bool isImmSExti32i8() const {
151 // If this isn't a constant expr, just assume it fits and let relaxation
153 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
157 // Otherwise, check the value is in a range that makes sense for this
159 return isImmSExti32i8Value(CE->getValue());
161 bool isImmSExti64i8() const {
165 // If this isn't a constant expr, just assume it fits and let relaxation
167 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
171 // Otherwise, check the value is in a range that makes sense for this
173 return isImmSExti64i8Value(CE->getValue());
175 bool isImmSExti64i32() const {
179 // If this isn't a constant expr, just assume it fits and let relaxation
181 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
185 // Otherwise, check the value is in a range that makes sense for this
187 return isImmSExti64i32Value(CE->getValue());
190 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());
197 bool isOffsetOf() const override {
198 return OffsetOfLoc.getPointer();
201 bool needAddressOf() const override {
205 bool isMem() const override { return Kind == Memory; }
206 bool isMemUnsized() const {
207 return Kind == Memory && Mem.Size == 0;
209 bool isMem8() const {
210 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
212 bool isMem16() const {
213 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
215 bool isMem32() const {
216 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
218 bool isMem64() const {
219 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
221 bool isMem80() const {
222 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
224 bool isMem128() const {
225 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
227 bool isMem256() const {
228 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
230 bool isMem512() const {
231 return Kind == Memory && (!Mem.Size || Mem.Size == 512);
234 bool isMemVX32() const {
235 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
236 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
238 bool isMemVY32() const {
239 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
240 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
242 bool isMemVX64() const {
243 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
244 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
246 bool isMemVY64() const {
247 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
248 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
250 bool isMemVZ32() const {
251 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
252 getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
254 bool isMemVZ64() const {
255 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
256 getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
259 bool isAbsMem() const {
260 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
261 !getMemIndexReg() && getMemScale() == 1;
264 bool isAbsMem16() const {
265 return isAbsMem() && Mem.ModeSize == 16;
268 bool isAbsMem32() const {
269 return isAbsMem() && Mem.ModeSize != 16;
272 bool isSrcIdx() const {
273 return !getMemIndexReg() && getMemScale() == 1 &&
274 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
275 getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
276 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
278 bool isSrcIdx8() const {
279 return isMem8() && isSrcIdx();
281 bool isSrcIdx16() const {
282 return isMem16() && isSrcIdx();
284 bool isSrcIdx32() const {
285 return isMem32() && isSrcIdx();
287 bool isSrcIdx64() const {
288 return isMem64() && isSrcIdx();
291 bool isDstIdx() const {
292 return !getMemIndexReg() && getMemScale() == 1 &&
293 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
294 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
295 getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
296 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
298 bool isDstIdx8() const {
299 return isMem8() && isDstIdx();
301 bool isDstIdx16() const {
302 return isMem16() && isDstIdx();
304 bool isDstIdx32() const {
305 return isMem32() && isDstIdx();
307 bool isDstIdx64() const {
308 return isMem64() && isDstIdx();
311 bool isMemOffs() const {
312 return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
316 bool isMemOffs16_8() const {
317 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
319 bool isMemOffs16_16() const {
320 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
322 bool isMemOffs16_32() const {
323 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
325 bool isMemOffs32_8() const {
326 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
328 bool isMemOffs32_16() const {
329 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
331 bool isMemOffs32_32() const {
332 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
334 bool isMemOffs32_64() const {
335 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
337 bool isMemOffs64_8() const {
338 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
340 bool isMemOffs64_16() const {
341 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
343 bool isMemOffs64_32() const {
344 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
346 bool isMemOffs64_64() const {
347 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
350 bool isReg() const override { return Kind == Register; }
352 bool isGR32orGR64() const {
353 return Kind == Register &&
354 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
355 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
358 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
359 // Add as immediates when possible.
360 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
361 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
363 Inst.addOperand(MCOperand::CreateExpr(Expr));
366 void addRegOperands(MCInst &Inst, unsigned N) const {
367 assert(N == 1 && "Invalid number of operands!");
368 Inst.addOperand(MCOperand::CreateReg(getReg()));
371 static unsigned getGR32FromGR64(unsigned RegNo) {
373 default: llvm_unreachable("Unexpected register");
374 case X86::RAX: return X86::EAX;
375 case X86::RCX: return X86::ECX;
376 case X86::RDX: return X86::EDX;
377 case X86::RBX: return X86::EBX;
378 case X86::RBP: return X86::EBP;
379 case X86::RSP: return X86::ESP;
380 case X86::RSI: return X86::ESI;
381 case X86::RDI: return X86::EDI;
382 case X86::R8: return X86::R8D;
383 case X86::R9: return X86::R9D;
384 case X86::R10: return X86::R10D;
385 case X86::R11: return X86::R11D;
386 case X86::R12: return X86::R12D;
387 case X86::R13: return X86::R13D;
388 case X86::R14: return X86::R14D;
389 case X86::R15: return X86::R15D;
390 case X86::RIP: return X86::EIP;
394 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
395 assert(N == 1 && "Invalid number of operands!");
396 unsigned RegNo = getReg();
397 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
398 RegNo = getGR32FromGR64(RegNo);
399 Inst.addOperand(MCOperand::CreateReg(RegNo));
402 void addImmOperands(MCInst &Inst, unsigned N) const {
403 assert(N == 1 && "Invalid number of operands!");
404 addExpr(Inst, getImm());
407 void addMemOperands(MCInst &Inst, unsigned N) const {
408 assert((N == 5) && "Invalid number of operands!");
409 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
410 Inst.addOperand(MCOperand::CreateImm(getMemScale()));
411 Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
412 addExpr(Inst, getMemDisp());
413 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
416 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
417 assert((N == 1) && "Invalid number of operands!");
418 // Add as immediates when possible.
419 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
420 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
422 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
425 void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
426 assert((N == 2) && "Invalid number of operands!");
427 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
428 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
430 void addDstIdxOperands(MCInst &Inst, unsigned N) const {
431 assert((N == 1) && "Invalid number of operands!");
432 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
435 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
436 assert((N == 2) && "Invalid number of operands!");
437 // Add as immediates when possible.
438 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
439 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
441 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
442 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
445 static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
446 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
447 auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
448 Res->Tok.Data = Str.data();
449 Res->Tok.Length = Str.size();
453 static std::unique_ptr<X86Operand>
454 CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
455 bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
456 StringRef SymName = StringRef(), void *OpDecl = nullptr) {
457 auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
458 Res->Reg.RegNo = RegNo;
459 Res->AddressOf = AddressOf;
460 Res->OffsetOfLoc = OffsetOfLoc;
461 Res->SymName = SymName;
462 Res->OpDecl = OpDecl;
466 static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
467 SMLoc StartLoc, SMLoc EndLoc) {
468 auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
473 /// Create an absolute memory operand.
474 static std::unique_ptr<X86Operand>
475 CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
476 unsigned Size = 0, StringRef SymName = StringRef(),
477 void *OpDecl = nullptr) {
478 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
480 Res->Mem.Disp = Disp;
481 Res->Mem.BaseReg = 0;
482 Res->Mem.IndexReg = 0;
484 Res->Mem.Size = Size;
485 Res->Mem.ModeSize = ModeSize;
486 Res->SymName = SymName;
487 Res->OpDecl = OpDecl;
488 Res->AddressOf = false;
492 /// Create a generalized memory operand.
493 static std::unique_ptr<X86Operand>
494 CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
495 unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
496 SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
497 void *OpDecl = nullptr) {
498 // We should never just have a displacement, that should be parsed as an
499 // absolute memory operand.
500 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
502 // The scale should always be one of {1,2,4,8}.
503 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
505 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
506 Res->Mem.SegReg = SegReg;
507 Res->Mem.Disp = Disp;
508 Res->Mem.BaseReg = BaseReg;
509 Res->Mem.IndexReg = IndexReg;
510 Res->Mem.Scale = Scale;
511 Res->Mem.Size = Size;
512 Res->Mem.ModeSize = ModeSize;
513 Res->SymName = SymName;
514 Res->OpDecl = OpDecl;
515 Res->AddressOf = false;
520 } // End of namespace llvm