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;
65 X86Operand(KindTy K, SMLoc Start, SMLoc End)
66 : Kind(K), StartLoc(Start), EndLoc(End) {}
68 StringRef getSymName() override { return SymName; }
69 void *getOpDecl() override { return OpDecl; }
71 /// getStartLoc - Get the location of the first token of this operand.
72 SMLoc getStartLoc() const override { return StartLoc; }
73 /// getEndLoc - Get the location of the last token of this operand.
74 SMLoc getEndLoc() const override { return EndLoc; }
75 /// getLocRange - Get the range between the first and last token of this
77 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
78 /// getOffsetOfLoc - Get the location of the offset operator.
79 SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
81 void print(raw_ostream &OS) const override {}
83 StringRef getToken() const {
84 assert(Kind == Token && "Invalid access!");
85 return StringRef(Tok.Data, Tok.Length);
87 void setTokenValue(StringRef Value) {
88 assert(Kind == Token && "Invalid access!");
89 Tok.Data = Value.data();
90 Tok.Length = Value.size();
93 unsigned getReg() const override {
94 assert(Kind == Register && "Invalid access!");
98 const MCExpr *getImm() const {
99 assert(Kind == Immediate && "Invalid access!");
103 const MCExpr *getMemDisp() const {
104 assert(Kind == Memory && "Invalid access!");
107 unsigned getMemSegReg() const {
108 assert(Kind == Memory && "Invalid access!");
111 unsigned getMemBaseReg() const {
112 assert(Kind == Memory && "Invalid access!");
115 unsigned getMemIndexReg() const {
116 assert(Kind == Memory && "Invalid access!");
119 unsigned getMemScale() const {
120 assert(Kind == Memory && "Invalid access!");
124 bool isToken() const override {return Kind == Token; }
126 bool isImm() const override { return Kind == Immediate; }
128 bool isImmSExti16i8() const {
132 // If this isn't a constant expr, just assume it fits and let relaxation
134 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
138 // Otherwise, check the value is in a range that makes sense for this
140 return isImmSExti16i8Value(CE->getValue());
142 bool isImmSExti32i8() const {
146 // If this isn't a constant expr, just assume it fits and let relaxation
148 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
152 // Otherwise, check the value is in a range that makes sense for this
154 return isImmSExti32i8Value(CE->getValue());
156 bool isImmSExti64i8() const {
160 // If this isn't a constant expr, just assume it fits and let relaxation
162 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
166 // Otherwise, check the value is in a range that makes sense for this
168 return isImmSExti64i8Value(CE->getValue());
170 bool isImmSExti64i32() const {
174 // If this isn't a constant expr, just assume it fits and let relaxation
176 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
180 // Otherwise, check the value is in a range that makes sense for this
182 return isImmSExti64i32Value(CE->getValue());
185 bool isOffsetOf() const override {
186 return OffsetOfLoc.getPointer();
189 bool needAddressOf() const override {
193 bool isMem() const override { return Kind == Memory; }
194 bool isMemUnsized() const {
195 return Kind == Memory && Mem.Size == 0;
197 bool isMem8() const {
198 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
200 bool isMem16() const {
201 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
203 bool isMem32() const {
204 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
206 bool isMem64() const {
207 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
209 bool isMem80() const {
210 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
212 bool isMem128() const {
213 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
215 bool isMem256() const {
216 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
218 bool isMem512() const {
219 return Kind == Memory && (!Mem.Size || Mem.Size == 512);
222 bool isMemVX32() const {
223 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
224 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
226 bool isMemVY32() const {
227 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
228 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
230 bool isMemVX64() const {
231 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
232 getMemIndexReg() >= X86::XMM0 && getMemIndexReg() <= X86::XMM15;
234 bool isMemVY64() const {
235 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
236 getMemIndexReg() >= X86::YMM0 && getMemIndexReg() <= X86::YMM15;
238 bool isMemVZ32() const {
239 return Kind == Memory && (!Mem.Size || Mem.Size == 32) &&
240 getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
242 bool isMemVZ64() const {
243 return Kind == Memory && (!Mem.Size || Mem.Size == 64) &&
244 getMemIndexReg() >= X86::ZMM0 && getMemIndexReg() <= X86::ZMM31;
247 bool isAbsMem() const {
248 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
249 !getMemIndexReg() && getMemScale() == 1;
252 bool isSrcIdx() const {
253 return !getMemIndexReg() && getMemScale() == 1 &&
254 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
255 getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
256 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
258 bool isSrcIdx8() const {
259 return isMem8() && isSrcIdx();
261 bool isSrcIdx16() const {
262 return isMem16() && isSrcIdx();
264 bool isSrcIdx32() const {
265 return isMem32() && isSrcIdx();
267 bool isSrcIdx64() const {
268 return isMem64() && isSrcIdx();
271 bool isDstIdx() const {
272 return !getMemIndexReg() && getMemScale() == 1 &&
273 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
274 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
275 getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
276 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
278 bool isDstIdx8() const {
279 return isMem8() && isDstIdx();
281 bool isDstIdx16() const {
282 return isMem16() && isDstIdx();
284 bool isDstIdx32() const {
285 return isMem32() && isDstIdx();
287 bool isDstIdx64() const {
288 return isMem64() && isDstIdx();
291 bool isMemOffs8() const {
292 return Kind == Memory && !getMemBaseReg() &&
293 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 8);
295 bool isMemOffs16() const {
296 return Kind == Memory && !getMemBaseReg() &&
297 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 16);
299 bool isMemOffs32() const {
300 return Kind == Memory && !getMemBaseReg() &&
301 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 32);
303 bool isMemOffs64() const {
304 return Kind == Memory && !getMemBaseReg() &&
305 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 64);
308 bool isReg() const override { return Kind == Register; }
310 bool isGR32orGR64() const {
311 return Kind == Register &&
312 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
313 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
316 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
317 // Add as immediates when possible.
318 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
319 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
321 Inst.addOperand(MCOperand::CreateExpr(Expr));
324 void addRegOperands(MCInst &Inst, unsigned N) const {
325 assert(N == 1 && "Invalid number of operands!");
326 Inst.addOperand(MCOperand::CreateReg(getReg()));
329 static unsigned getGR32FromGR64(unsigned RegNo) {
331 default: llvm_unreachable("Unexpected register");
332 case X86::RAX: return X86::EAX;
333 case X86::RCX: return X86::ECX;
334 case X86::RDX: return X86::EDX;
335 case X86::RBX: return X86::EBX;
336 case X86::RBP: return X86::EBP;
337 case X86::RSP: return X86::ESP;
338 case X86::RSI: return X86::ESI;
339 case X86::RDI: return X86::EDI;
340 case X86::R8: return X86::R8D;
341 case X86::R9: return X86::R9D;
342 case X86::R10: return X86::R10D;
343 case X86::R11: return X86::R11D;
344 case X86::R12: return X86::R12D;
345 case X86::R13: return X86::R13D;
346 case X86::R14: return X86::R14D;
347 case X86::R15: return X86::R15D;
348 case X86::RIP: return X86::EIP;
352 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
353 assert(N == 1 && "Invalid number of operands!");
354 unsigned RegNo = getReg();
355 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
356 RegNo = getGR32FromGR64(RegNo);
357 Inst.addOperand(MCOperand::CreateReg(RegNo));
360 void addImmOperands(MCInst &Inst, unsigned N) const {
361 assert(N == 1 && "Invalid number of operands!");
362 addExpr(Inst, getImm());
365 void addMemOperands(MCInst &Inst, unsigned N) const {
366 assert((N == 5) && "Invalid number of operands!");
367 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
368 Inst.addOperand(MCOperand::CreateImm(getMemScale()));
369 Inst.addOperand(MCOperand::CreateReg(getMemIndexReg()));
370 addExpr(Inst, getMemDisp());
371 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
374 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
375 assert((N == 1) && "Invalid number of operands!");
376 // Add as immediates when possible.
377 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
378 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
380 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
383 void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
384 assert((N == 2) && "Invalid number of operands!");
385 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
386 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
388 void addDstIdxOperands(MCInst &Inst, unsigned N) const {
389 assert((N == 1) && "Invalid number of operands!");
390 Inst.addOperand(MCOperand::CreateReg(getMemBaseReg()));
393 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
394 assert((N == 2) && "Invalid number of operands!");
395 // Add as immediates when possible.
396 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
397 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
399 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
400 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
403 static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
404 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
405 auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
406 Res->Tok.Data = Str.data();
407 Res->Tok.Length = Str.size();
411 static std::unique_ptr<X86Operand>
412 CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
413 bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
414 StringRef SymName = StringRef(), void *OpDecl = nullptr) {
415 auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
416 Res->Reg.RegNo = RegNo;
417 Res->AddressOf = AddressOf;
418 Res->OffsetOfLoc = OffsetOfLoc;
419 Res->SymName = SymName;
420 Res->OpDecl = OpDecl;
424 static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
425 SMLoc StartLoc, SMLoc EndLoc) {
426 auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
431 /// Create an absolute memory operand.
432 static std::unique_ptr<X86Operand>
433 CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size = 0,
434 StringRef SymName = StringRef(), void *OpDecl = nullptr) {
435 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
437 Res->Mem.Disp = Disp;
438 Res->Mem.BaseReg = 0;
439 Res->Mem.IndexReg = 0;
441 Res->Mem.Size = Size;
442 Res->SymName = SymName;
443 Res->OpDecl = OpDecl;
444 Res->AddressOf = false;
448 /// Create a generalized memory operand.
449 static std::unique_ptr<X86Operand>
450 CreateMem(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
451 unsigned IndexReg, unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
452 unsigned Size = 0, StringRef SymName = StringRef(),
453 void *OpDecl = nullptr) {
454 // We should never just have a displacement, that should be parsed as an
455 // absolute memory operand.
456 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
458 // The scale should always be one of {1,2,4,8}.
459 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
461 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
462 Res->Mem.SegReg = SegReg;
463 Res->Mem.Disp = Disp;
464 Res->Mem.BaseReg = BaseReg;
465 Res->Mem.IndexReg = IndexReg;
466 Res->Mem.Scale = Scale;
467 Res->Mem.Size = Size;
468 Res->SymName = SymName;
469 Res->OpDecl = OpDecl;
470 Res->AddressOf = false;
475 } // End of namespace llvm