Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / lib / Target / X86 / AsmParser / X86Operand.h
blob0f489e4449749a3f5f0240b90a049955fca4d9aa
1 //===- X86Operand.h - Parsed X86 machine instruction ------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
10 #define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H
12 #include "InstPrinter/X86IntelInstPrinter.h"
13 #include "MCTargetDesc/X86MCTargetDesc.h"
14 #include "X86AsmParserCommon.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
20 #include "llvm/MC/MCRegisterInfo.h"
21 #include "llvm/Support/Casting.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/SMLoc.h"
24 #include <cassert>
25 #include <memory>
27 namespace llvm {
29 /// X86Operand - Instances of this class represent a parsed X86 machine
30 /// instruction.
31 struct X86Operand final : public MCParsedAsmOperand {
32 enum KindTy { Token, Register, Immediate, Memory, Prefix, DXRegister } Kind;
34 SMLoc StartLoc, EndLoc;
35 SMLoc OffsetOfLoc;
36 StringRef SymName;
37 void *OpDecl;
38 bool AddressOf;
40 struct TokOp {
41 const char *Data;
42 unsigned Length;
45 struct RegOp {
46 unsigned RegNo;
49 struct PrefOp {
50 unsigned Prefixes;
53 struct ImmOp {
54 const MCExpr *Val;
57 struct MemOp {
58 unsigned SegReg;
59 const MCExpr *Disp;
60 unsigned BaseReg;
61 unsigned IndexReg;
62 unsigned Scale;
63 unsigned Size;
64 unsigned ModeSize;
66 /// If the memory operand is unsized and there are multiple instruction
67 /// matches, prefer the one with this size.
68 unsigned FrontendSize;
71 union {
72 struct TokOp Tok;
73 struct RegOp Reg;
74 struct ImmOp Imm;
75 struct MemOp Mem;
76 struct PrefOp Pref;
79 X86Operand(KindTy K, SMLoc Start, SMLoc End)
80 : Kind(K), StartLoc(Start), EndLoc(End) {}
82 StringRef getSymName() override { return SymName; }
83 void *getOpDecl() override { return OpDecl; }
85 /// getStartLoc - Get the location of the first token of this operand.
86 SMLoc getStartLoc() const override { return StartLoc; }
88 /// getEndLoc - Get the location of the last token of this operand.
89 SMLoc getEndLoc() const override { return EndLoc; }
91 /// getLocRange - Get the range between the first and last token of this
92 /// operand.
93 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
95 /// getOffsetOfLoc - Get the location of the offset operator.
96 SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; }
98 void print(raw_ostream &OS) const override {
100 auto PrintImmValue = [&](const MCExpr *Val, const char *VName) {
101 if (Val->getKind() == MCExpr::Constant) {
102 if (auto Imm = cast<MCConstantExpr>(Val)->getValue())
103 OS << VName << Imm;
104 } else if (Val->getKind() == MCExpr::SymbolRef) {
105 if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Val)) {
106 const MCSymbol &Sym = SRE->getSymbol();
107 if (auto SymName = Sym.getName().data())
108 OS << VName << SymName;
113 switch (Kind) {
114 case Token:
115 OS << Tok.Data;
116 break;
117 case Register:
118 OS << "Reg:" << X86IntelInstPrinter::getRegisterName(Reg.RegNo);
119 break;
120 case DXRegister:
121 OS << "DXReg";
122 break;
123 case Immediate:
124 PrintImmValue(Imm.Val, "Imm:");
125 break;
126 case Prefix:
127 OS << "Prefix:" << Pref.Prefixes;
128 break;
129 case Memory:
130 OS << "Memory: ModeSize=" << Mem.ModeSize;
131 if (Mem.Size)
132 OS << ",Size=" << Mem.Size;
133 if (Mem.BaseReg)
134 OS << ",BaseReg=" << X86IntelInstPrinter::getRegisterName(Mem.BaseReg);
135 if (Mem.IndexReg)
136 OS << ",IndexReg="
137 << X86IntelInstPrinter::getRegisterName(Mem.IndexReg);
138 if (Mem.Scale)
139 OS << ",Scale=" << Mem.Scale;
140 if (Mem.Disp)
141 PrintImmValue(Mem.Disp, ",Disp=");
142 if (Mem.SegReg)
143 OS << ",SegReg=" << X86IntelInstPrinter::getRegisterName(Mem.SegReg);
144 break;
148 StringRef getToken() const {
149 assert(Kind == Token && "Invalid access!");
150 return StringRef(Tok.Data, Tok.Length);
152 void setTokenValue(StringRef Value) {
153 assert(Kind == Token && "Invalid access!");
154 Tok.Data = Value.data();
155 Tok.Length = Value.size();
158 unsigned getReg() const override {
159 assert(Kind == Register && "Invalid access!");
160 return Reg.RegNo;
163 unsigned getPrefix() const {
164 assert(Kind == Prefix && "Invalid access!");
165 return Pref.Prefixes;
168 const MCExpr *getImm() const {
169 assert(Kind == Immediate && "Invalid access!");
170 return Imm.Val;
173 const MCExpr *getMemDisp() const {
174 assert(Kind == Memory && "Invalid access!");
175 return Mem.Disp;
177 unsigned getMemSegReg() const {
178 assert(Kind == Memory && "Invalid access!");
179 return Mem.SegReg;
181 unsigned getMemBaseReg() const {
182 assert(Kind == Memory && "Invalid access!");
183 return Mem.BaseReg;
185 unsigned getMemIndexReg() const {
186 assert(Kind == Memory && "Invalid access!");
187 return Mem.IndexReg;
189 unsigned getMemScale() const {
190 assert(Kind == Memory && "Invalid access!");
191 return Mem.Scale;
193 unsigned getMemModeSize() const {
194 assert(Kind == Memory && "Invalid access!");
195 return Mem.ModeSize;
197 unsigned getMemFrontendSize() const {
198 assert(Kind == Memory && "Invalid access!");
199 return Mem.FrontendSize;
202 bool isToken() const override {return Kind == Token; }
204 bool isImm() const override { return Kind == Immediate; }
206 bool isImmSExti16i8() const {
207 if (!isImm())
208 return false;
210 // If this isn't a constant expr, just assume it fits and let relaxation
211 // handle it.
212 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
213 if (!CE)
214 return true;
216 // Otherwise, check the value is in a range that makes sense for this
217 // extension.
218 return isImmSExti16i8Value(CE->getValue());
220 bool isImmSExti32i8() const {
221 if (!isImm())
222 return false;
224 // If this isn't a constant expr, just assume it fits and let relaxation
225 // handle it.
226 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
227 if (!CE)
228 return true;
230 // Otherwise, check the value is in a range that makes sense for this
231 // extension.
232 return isImmSExti32i8Value(CE->getValue());
234 bool isImmSExti64i8() const {
235 if (!isImm())
236 return false;
238 // If this isn't a constant expr, just assume it fits and let relaxation
239 // handle it.
240 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
241 if (!CE)
242 return true;
244 // Otherwise, check the value is in a range that makes sense for this
245 // extension.
246 return isImmSExti64i8Value(CE->getValue());
248 bool isImmSExti64i32() const {
249 if (!isImm())
250 return false;
252 // If this isn't a constant expr, just assume it fits and let relaxation
253 // handle it.
254 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
255 if (!CE)
256 return true;
258 // Otherwise, check the value is in a range that makes sense for this
259 // extension.
260 return isImmSExti64i32Value(CE->getValue());
263 bool isImmUnsignedi8() const {
264 if (!isImm()) return false;
265 // If this isn't a constant expr, just assume it fits and let relaxation
266 // handle it.
267 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
268 if (!CE) return true;
269 return isImmUnsignedi8Value(CE->getValue());
272 bool isOffsetOf() const override {
273 return OffsetOfLoc.getPointer();
276 bool needAddressOf() const override {
277 return AddressOf;
280 bool isMem() const override { return Kind == Memory; }
281 bool isMemUnsized() const {
282 return Kind == Memory && Mem.Size == 0;
284 bool isMem8() const {
285 return Kind == Memory && (!Mem.Size || Mem.Size == 8);
287 bool isMem16() const {
288 return Kind == Memory && (!Mem.Size || Mem.Size == 16);
290 bool isMem32() const {
291 return Kind == Memory && (!Mem.Size || Mem.Size == 32);
293 bool isMem64() const {
294 return Kind == Memory && (!Mem.Size || Mem.Size == 64);
296 bool isMem80() const {
297 return Kind == Memory && (!Mem.Size || Mem.Size == 80);
299 bool isMem128() const {
300 return Kind == Memory && (!Mem.Size || Mem.Size == 128);
302 bool isMem256() const {
303 return Kind == Memory && (!Mem.Size || Mem.Size == 256);
305 bool isMem512() const {
306 return Kind == Memory && (!Mem.Size || Mem.Size == 512);
308 bool isMemIndexReg(unsigned LowR, unsigned HighR) const {
309 assert(Kind == Memory && "Invalid access!");
310 return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR;
313 bool isMem64_RC128() const {
314 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15);
316 bool isMem128_RC128() const {
317 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15);
319 bool isMem128_RC256() const {
320 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15);
322 bool isMem256_RC128() const {
323 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15);
325 bool isMem256_RC256() const {
326 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15);
329 bool isMem64_RC128X() const {
330 return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31);
332 bool isMem128_RC128X() const {
333 return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31);
335 bool isMem128_RC256X() const {
336 return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31);
338 bool isMem256_RC128X() const {
339 return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31);
341 bool isMem256_RC256X() const {
342 return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31);
344 bool isMem256_RC512() const {
345 return isMem256() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
347 bool isMem512_RC256X() const {
348 return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31);
350 bool isMem512_RC512() const {
351 return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31);
354 bool isAbsMem() const {
355 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
356 !getMemIndexReg() && getMemScale() == 1;
358 bool isAVX512RC() const{
359 return isImm();
362 bool isAbsMem16() const {
363 return isAbsMem() && Mem.ModeSize == 16;
366 bool isSrcIdx() const {
367 return !getMemIndexReg() && getMemScale() == 1 &&
368 (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI ||
369 getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) &&
370 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
372 bool isSrcIdx8() const {
373 return isMem8() && isSrcIdx();
375 bool isSrcIdx16() const {
376 return isMem16() && isSrcIdx();
378 bool isSrcIdx32() const {
379 return isMem32() && isSrcIdx();
381 bool isSrcIdx64() const {
382 return isMem64() && isSrcIdx();
385 bool isDstIdx() const {
386 return !getMemIndexReg() && getMemScale() == 1 &&
387 (getMemSegReg() == 0 || getMemSegReg() == X86::ES) &&
388 (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI ||
389 getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) &&
390 cast<MCConstantExpr>(getMemDisp())->getValue() == 0;
392 bool isDstIdx8() const {
393 return isMem8() && isDstIdx();
395 bool isDstIdx16() const {
396 return isMem16() && isDstIdx();
398 bool isDstIdx32() const {
399 return isMem32() && isDstIdx();
401 bool isDstIdx64() const {
402 return isMem64() && isDstIdx();
405 bool isMemOffs() const {
406 return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
407 getMemScale() == 1;
410 bool isMemOffs16_8() const {
411 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
413 bool isMemOffs16_16() const {
414 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
416 bool isMemOffs16_32() const {
417 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
419 bool isMemOffs32_8() const {
420 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
422 bool isMemOffs32_16() const {
423 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
425 bool isMemOffs32_32() const {
426 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
428 bool isMemOffs32_64() const {
429 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
431 bool isMemOffs64_8() const {
432 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
434 bool isMemOffs64_16() const {
435 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
437 bool isMemOffs64_32() const {
438 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
440 bool isMemOffs64_64() const {
441 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
444 bool isPrefix() const { return Kind == Prefix; }
445 bool isReg() const override { return Kind == Register; }
446 bool isDXReg() const { return Kind == DXRegister; }
448 bool isGR32orGR64() const {
449 return Kind == Register &&
450 (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) ||
451 X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg()));
454 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
455 // Add as immediates when possible.
456 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
457 Inst.addOperand(MCOperand::createImm(CE->getValue()));
458 else
459 Inst.addOperand(MCOperand::createExpr(Expr));
462 void addRegOperands(MCInst &Inst, unsigned N) const {
463 assert(N == 1 && "Invalid number of operands!");
464 Inst.addOperand(MCOperand::createReg(getReg()));
467 void addGR32orGR64Operands(MCInst &Inst, unsigned N) const {
468 assert(N == 1 && "Invalid number of operands!");
469 unsigned RegNo = getReg();
470 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo))
471 RegNo = getX86SubSuperRegister(RegNo, 32);
472 Inst.addOperand(MCOperand::createReg(RegNo));
475 void addAVX512RCOperands(MCInst &Inst, unsigned N) const {
476 assert(N == 1 && "Invalid number of operands!");
477 addExpr(Inst, getImm());
480 void addImmOperands(MCInst &Inst, unsigned N) const {
481 assert(N == 1 && "Invalid number of operands!");
482 addExpr(Inst, getImm());
485 void addMemOperands(MCInst &Inst, unsigned N) const {
486 assert((N == 5) && "Invalid number of operands!");
487 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
488 Inst.addOperand(MCOperand::createImm(getMemScale()));
489 Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
490 addExpr(Inst, getMemDisp());
491 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
494 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
495 assert((N == 1) && "Invalid number of operands!");
496 // Add as immediates when possible.
497 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
498 Inst.addOperand(MCOperand::createImm(CE->getValue()));
499 else
500 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
503 void addSrcIdxOperands(MCInst &Inst, unsigned N) const {
504 assert((N == 2) && "Invalid number of operands!");
505 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
506 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
509 void addDstIdxOperands(MCInst &Inst, unsigned N) const {
510 assert((N == 1) && "Invalid number of operands!");
511 Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
514 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
515 assert((N == 2) && "Invalid number of operands!");
516 // Add as immediates when possible.
517 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
518 Inst.addOperand(MCOperand::createImm(CE->getValue()));
519 else
520 Inst.addOperand(MCOperand::createExpr(getMemDisp()));
521 Inst.addOperand(MCOperand::createReg(getMemSegReg()));
524 static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) {
525 SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size());
526 auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc);
527 Res->Tok.Data = Str.data();
528 Res->Tok.Length = Str.size();
529 return Res;
532 static std::unique_ptr<X86Operand>
533 CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc,
534 bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(),
535 StringRef SymName = StringRef(), void *OpDecl = nullptr) {
536 auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc);
537 Res->Reg.RegNo = RegNo;
538 Res->AddressOf = AddressOf;
539 Res->OffsetOfLoc = OffsetOfLoc;
540 Res->SymName = SymName;
541 Res->OpDecl = OpDecl;
542 return Res;
545 static std::unique_ptr<X86Operand>
546 CreateDXReg(SMLoc StartLoc, SMLoc EndLoc) {
547 return llvm::make_unique<X86Operand>(DXRegister, StartLoc, EndLoc);
550 static std::unique_ptr<X86Operand>
551 CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {
552 auto Res = llvm::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);
553 Res->Pref.Prefixes = Prefixes;
554 return Res;
557 static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val,
558 SMLoc StartLoc, SMLoc EndLoc) {
559 auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc);
560 Res->Imm.Val = Val;
561 return Res;
564 /// Create an absolute memory operand.
565 static std::unique_ptr<X86Operand>
566 CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
567 unsigned Size = 0, StringRef SymName = StringRef(),
568 void *OpDecl = nullptr, unsigned FrontendSize = 0) {
569 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
570 Res->Mem.SegReg = 0;
571 Res->Mem.Disp = Disp;
572 Res->Mem.BaseReg = 0;
573 Res->Mem.IndexReg = 0;
574 Res->Mem.Scale = 1;
575 Res->Mem.Size = Size;
576 Res->Mem.ModeSize = ModeSize;
577 Res->Mem.FrontendSize = FrontendSize;
578 Res->SymName = SymName;
579 Res->OpDecl = OpDecl;
580 Res->AddressOf = false;
581 return Res;
584 /// Create a generalized memory operand.
585 static std::unique_ptr<X86Operand>
586 CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
587 unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
588 SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
589 void *OpDecl = nullptr, unsigned FrontendSize = 0) {
590 // We should never just have a displacement, that should be parsed as an
591 // absolute memory operand.
592 assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
594 // The scale should always be one of {1,2,4,8}.
595 assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
596 "Invalid scale!");
597 auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc);
598 Res->Mem.SegReg = SegReg;
599 Res->Mem.Disp = Disp;
600 Res->Mem.BaseReg = BaseReg;
601 Res->Mem.IndexReg = IndexReg;
602 Res->Mem.Scale = Scale;
603 Res->Mem.Size = Size;
604 Res->Mem.ModeSize = ModeSize;
605 Res->Mem.FrontendSize = FrontendSize;
606 Res->SymName = SymName;
607 Res->OpDecl = OpDecl;
608 Res->AddressOf = false;
609 return Res;
613 } // end namespace llvm
615 #endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H