10b57cec5SDimitry Andric //===- X86Operand.h - Parsed X86 machine instruction ------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H 100b57cec5SDimitry Andric #define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "MCTargetDesc/X86IntelInstPrinter.h" 130b57cec5SDimitry Andric #include "MCTargetDesc/X86MCTargetDesc.h" 140b57cec5SDimitry Andric #include "X86AsmParserCommon.h" 150b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 160b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 170b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 180b57cec5SDimitry Andric #include "llvm/MC/MCInst.h" 190b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 2081ad6265SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 2181ad6265SDimitry Andric #include "llvm/MC/MCSymbol.h" 220b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 230b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h" 240b57cec5SDimitry Andric #include <cassert> 250b57cec5SDimitry Andric #include <memory> 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric namespace llvm { 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric /// X86Operand - Instances of this class represent a parsed X86 machine 300b57cec5SDimitry Andric /// instruction. 310b57cec5SDimitry Andric struct X86Operand final : public MCParsedAsmOperand { 320b57cec5SDimitry Andric enum KindTy { Token, Register, Immediate, Memory, Prefix, DXRegister } Kind; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric SMLoc StartLoc, EndLoc; 350b57cec5SDimitry Andric SMLoc OffsetOfLoc; 360b57cec5SDimitry Andric StringRef SymName; 370b57cec5SDimitry Andric void *OpDecl; 380b57cec5SDimitry Andric bool AddressOf; 390b57cec5SDimitry Andric 4081ad6265SDimitry Andric /// This used for inline asm which may specify base reg and index reg for 4181ad6265SDimitry Andric /// MemOp. e.g. ARR[eax + ecx*4], so no extra reg can be used for MemOp. 4281ad6265SDimitry Andric bool UseUpRegs = false; 4381ad6265SDimitry Andric 440b57cec5SDimitry Andric struct TokOp { 450b57cec5SDimitry Andric const char *Data; 460b57cec5SDimitry Andric unsigned Length; 470b57cec5SDimitry Andric }; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric struct RegOp { 500b57cec5SDimitry Andric unsigned RegNo; 510b57cec5SDimitry Andric }; 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric struct PrefOp { 540b57cec5SDimitry Andric unsigned Prefixes; 550b57cec5SDimitry Andric }; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric struct ImmOp { 580b57cec5SDimitry Andric const MCExpr *Val; 59480093f4SDimitry Andric bool LocalRef; 600b57cec5SDimitry Andric }; 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric struct MemOp { 630b57cec5SDimitry Andric unsigned SegReg; 640b57cec5SDimitry Andric const MCExpr *Disp; 650b57cec5SDimitry Andric unsigned BaseReg; 665ffd83dbSDimitry Andric unsigned DefaultBaseReg; 670b57cec5SDimitry Andric unsigned IndexReg; 680b57cec5SDimitry Andric unsigned Scale; 690b57cec5SDimitry Andric unsigned Size; 700b57cec5SDimitry Andric unsigned ModeSize; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric /// If the memory operand is unsized and there are multiple instruction 730b57cec5SDimitry Andric /// matches, prefer the one with this size. 740b57cec5SDimitry Andric unsigned FrontendSize; 7581ad6265SDimitry Andric 7681ad6265SDimitry Andric /// If false, then this operand must be a memory operand for an indirect 7781ad6265SDimitry Andric /// branch instruction. Otherwise, this operand may belong to either a 7881ad6265SDimitry Andric /// direct or indirect branch instruction. 7981ad6265SDimitry Andric bool MaybeDirectBranchDest; 800b57cec5SDimitry Andric }; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric union { 830b57cec5SDimitry Andric struct TokOp Tok; 840b57cec5SDimitry Andric struct RegOp Reg; 850b57cec5SDimitry Andric struct ImmOp Imm; 860b57cec5SDimitry Andric struct MemOp Mem; 870b57cec5SDimitry Andric struct PrefOp Pref; 880b57cec5SDimitry Andric }; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric X86Operand(KindTy K, SMLoc Start, SMLoc End) 91fe6060f1SDimitry Andric : Kind(K), StartLoc(Start), EndLoc(End), OpDecl(nullptr), 92349cc55cSDimitry Andric AddressOf(false) {} 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric StringRef getSymName() override { return SymName; } 950b57cec5SDimitry Andric void *getOpDecl() override { return OpDecl; } 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric /// getStartLoc - Get the location of the first token of this operand. 980b57cec5SDimitry Andric SMLoc getStartLoc() const override { return StartLoc; } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric /// getEndLoc - Get the location of the last token of this operand. 1010b57cec5SDimitry Andric SMLoc getEndLoc() const override { return EndLoc; } 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric /// getLocRange - Get the range between the first and last token of this 1040b57cec5SDimitry Andric /// operand. 1050b57cec5SDimitry Andric SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric /// getOffsetOfLoc - Get the location of the offset operator. 1080b57cec5SDimitry Andric SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; } 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric void print(raw_ostream &OS) const override { 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric auto PrintImmValue = [&](const MCExpr *Val, const char *VName) { 1130b57cec5SDimitry Andric if (Val->getKind() == MCExpr::Constant) { 1140b57cec5SDimitry Andric if (auto Imm = cast<MCConstantExpr>(Val)->getValue()) 1150b57cec5SDimitry Andric OS << VName << Imm; 1160b57cec5SDimitry Andric } else if (Val->getKind() == MCExpr::SymbolRef) { 1170b57cec5SDimitry Andric if (auto *SRE = dyn_cast<MCSymbolRefExpr>(Val)) { 1180b57cec5SDimitry Andric const MCSymbol &Sym = SRE->getSymbol(); 119480093f4SDimitry Andric if (const char *SymNameStr = Sym.getName().data()) 120480093f4SDimitry Andric OS << VName << SymNameStr; 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric }; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric switch (Kind) { 1260b57cec5SDimitry Andric case Token: 1270b57cec5SDimitry Andric OS << Tok.Data; 1280b57cec5SDimitry Andric break; 1290b57cec5SDimitry Andric case Register: 1300b57cec5SDimitry Andric OS << "Reg:" << X86IntelInstPrinter::getRegisterName(Reg.RegNo); 1310b57cec5SDimitry Andric break; 1320b57cec5SDimitry Andric case DXRegister: 1330b57cec5SDimitry Andric OS << "DXReg"; 1340b57cec5SDimitry Andric break; 1350b57cec5SDimitry Andric case Immediate: 1360b57cec5SDimitry Andric PrintImmValue(Imm.Val, "Imm:"); 1370b57cec5SDimitry Andric break; 1380b57cec5SDimitry Andric case Prefix: 1390b57cec5SDimitry Andric OS << "Prefix:" << Pref.Prefixes; 1400b57cec5SDimitry Andric break; 1410b57cec5SDimitry Andric case Memory: 1420b57cec5SDimitry Andric OS << "Memory: ModeSize=" << Mem.ModeSize; 1430b57cec5SDimitry Andric if (Mem.Size) 1440b57cec5SDimitry Andric OS << ",Size=" << Mem.Size; 1450b57cec5SDimitry Andric if (Mem.BaseReg) 1460b57cec5SDimitry Andric OS << ",BaseReg=" << X86IntelInstPrinter::getRegisterName(Mem.BaseReg); 1470b57cec5SDimitry Andric if (Mem.IndexReg) 1480b57cec5SDimitry Andric OS << ",IndexReg=" 1490b57cec5SDimitry Andric << X86IntelInstPrinter::getRegisterName(Mem.IndexReg); 1500b57cec5SDimitry Andric if (Mem.Scale) 1510b57cec5SDimitry Andric OS << ",Scale=" << Mem.Scale; 1520b57cec5SDimitry Andric if (Mem.Disp) 1530b57cec5SDimitry Andric PrintImmValue(Mem.Disp, ",Disp="); 1540b57cec5SDimitry Andric if (Mem.SegReg) 1550b57cec5SDimitry Andric OS << ",SegReg=" << X86IntelInstPrinter::getRegisterName(Mem.SegReg); 1560b57cec5SDimitry Andric break; 1570b57cec5SDimitry Andric } 1580b57cec5SDimitry Andric } 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric StringRef getToken() const { 1610b57cec5SDimitry Andric assert(Kind == Token && "Invalid access!"); 1620b57cec5SDimitry Andric return StringRef(Tok.Data, Tok.Length); 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric void setTokenValue(StringRef Value) { 1650b57cec5SDimitry Andric assert(Kind == Token && "Invalid access!"); 1660b57cec5SDimitry Andric Tok.Data = Value.data(); 1670b57cec5SDimitry Andric Tok.Length = Value.size(); 1680b57cec5SDimitry Andric } 1690b57cec5SDimitry Andric 170*0fca6ea1SDimitry Andric MCRegister getReg() const override { 1710b57cec5SDimitry Andric assert(Kind == Register && "Invalid access!"); 1720b57cec5SDimitry Andric return Reg.RegNo; 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric unsigned getPrefix() const { 1760b57cec5SDimitry Andric assert(Kind == Prefix && "Invalid access!"); 1770b57cec5SDimitry Andric return Pref.Prefixes; 1780b57cec5SDimitry Andric } 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric const MCExpr *getImm() const { 1810b57cec5SDimitry Andric assert(Kind == Immediate && "Invalid access!"); 1820b57cec5SDimitry Andric return Imm.Val; 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric const MCExpr *getMemDisp() const { 1860b57cec5SDimitry Andric assert(Kind == Memory && "Invalid access!"); 1870b57cec5SDimitry Andric return Mem.Disp; 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric unsigned getMemSegReg() const { 1900b57cec5SDimitry Andric assert(Kind == Memory && "Invalid access!"); 1910b57cec5SDimitry Andric return Mem.SegReg; 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric unsigned getMemBaseReg() const { 1940b57cec5SDimitry Andric assert(Kind == Memory && "Invalid access!"); 1950b57cec5SDimitry Andric return Mem.BaseReg; 1960b57cec5SDimitry Andric } 1975ffd83dbSDimitry Andric unsigned getMemDefaultBaseReg() const { 1985ffd83dbSDimitry Andric assert(Kind == Memory && "Invalid access!"); 1995ffd83dbSDimitry Andric return Mem.DefaultBaseReg; 2005ffd83dbSDimitry Andric } 2010b57cec5SDimitry Andric unsigned getMemIndexReg() const { 2020b57cec5SDimitry Andric assert(Kind == Memory && "Invalid access!"); 2030b57cec5SDimitry Andric return Mem.IndexReg; 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric unsigned getMemScale() const { 2060b57cec5SDimitry Andric assert(Kind == Memory && "Invalid access!"); 2070b57cec5SDimitry Andric return Mem.Scale; 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric unsigned getMemModeSize() const { 2100b57cec5SDimitry Andric assert(Kind == Memory && "Invalid access!"); 2110b57cec5SDimitry Andric return Mem.ModeSize; 2120b57cec5SDimitry Andric } 2130b57cec5SDimitry Andric unsigned getMemFrontendSize() const { 2140b57cec5SDimitry Andric assert(Kind == Memory && "Invalid access!"); 2150b57cec5SDimitry Andric return Mem.FrontendSize; 2160b57cec5SDimitry Andric } 21781ad6265SDimitry Andric bool isMaybeDirectBranchDest() const { 21881ad6265SDimitry Andric assert(Kind == Memory && "Invalid access!"); 21981ad6265SDimitry Andric return Mem.MaybeDirectBranchDest; 22081ad6265SDimitry Andric } 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric bool isToken() const override {return Kind == Token; } 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric bool isImm() const override { return Kind == Immediate; } 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric bool isImmSExti16i8() const { 2270b57cec5SDimitry Andric if (!isImm()) 2280b57cec5SDimitry Andric return false; 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric // If this isn't a constant expr, just assume it fits and let relaxation 2310b57cec5SDimitry Andric // handle it. 2320b57cec5SDimitry Andric const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2330b57cec5SDimitry Andric if (!CE) 2340b57cec5SDimitry Andric return true; 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric // Otherwise, check the value is in a range that makes sense for this 2370b57cec5SDimitry Andric // extension. 2380b57cec5SDimitry Andric return isImmSExti16i8Value(CE->getValue()); 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric bool isImmSExti32i8() const { 2410b57cec5SDimitry Andric if (!isImm()) 2420b57cec5SDimitry Andric return false; 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric // If this isn't a constant expr, just assume it fits and let relaxation 2450b57cec5SDimitry Andric // handle it. 2460b57cec5SDimitry Andric const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2470b57cec5SDimitry Andric if (!CE) 2480b57cec5SDimitry Andric return true; 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric // Otherwise, check the value is in a range that makes sense for this 2510b57cec5SDimitry Andric // extension. 2520b57cec5SDimitry Andric return isImmSExti32i8Value(CE->getValue()); 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric bool isImmSExti64i8() const { 2550b57cec5SDimitry Andric if (!isImm()) 2560b57cec5SDimitry Andric return false; 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric // If this isn't a constant expr, just assume it fits and let relaxation 2590b57cec5SDimitry Andric // handle it. 2600b57cec5SDimitry Andric const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2610b57cec5SDimitry Andric if (!CE) 2620b57cec5SDimitry Andric return true; 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric // Otherwise, check the value is in a range that makes sense for this 2650b57cec5SDimitry Andric // extension. 2660b57cec5SDimitry Andric return isImmSExti64i8Value(CE->getValue()); 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric bool isImmSExti64i32() const { 2690b57cec5SDimitry Andric if (!isImm()) 2700b57cec5SDimitry Andric return false; 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric // If this isn't a constant expr, just assume it fits and let relaxation 2730b57cec5SDimitry Andric // handle it. 2740b57cec5SDimitry Andric const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2750b57cec5SDimitry Andric if (!CE) 2760b57cec5SDimitry Andric return true; 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andric // Otherwise, check the value is in a range that makes sense for this 2790b57cec5SDimitry Andric // extension. 2800b57cec5SDimitry Andric return isImmSExti64i32Value(CE->getValue()); 2810b57cec5SDimitry Andric } 2820b57cec5SDimitry Andric 2838bcb0991SDimitry Andric bool isImmUnsignedi4() const { 2848bcb0991SDimitry Andric if (!isImm()) return false; 2858bcb0991SDimitry Andric // If this isn't a constant expr, reject it. The immediate byte is shared 2868bcb0991SDimitry Andric // with a register encoding. We can't have it affected by a relocation. 2878bcb0991SDimitry Andric const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2888bcb0991SDimitry Andric if (!CE) return false; 2898bcb0991SDimitry Andric return isImmUnsignedi4Value(CE->getValue()); 2908bcb0991SDimitry Andric } 2918bcb0991SDimitry Andric 2920b57cec5SDimitry Andric bool isImmUnsignedi8() const { 2930b57cec5SDimitry Andric if (!isImm()) return false; 2940b57cec5SDimitry Andric // If this isn't a constant expr, just assume it fits and let relaxation 2950b57cec5SDimitry Andric // handle it. 2960b57cec5SDimitry Andric const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 2970b57cec5SDimitry Andric if (!CE) return true; 2980b57cec5SDimitry Andric return isImmUnsignedi8Value(CE->getValue()); 2990b57cec5SDimitry Andric } 3000b57cec5SDimitry Andric 301480093f4SDimitry Andric bool isOffsetOfLocal() const override { return isImm() && Imm.LocalRef; } 3020b57cec5SDimitry Andric 303480093f4SDimitry Andric bool needAddressOf() const override { return AddressOf; } 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric bool isMem() const override { return Kind == Memory; } 3060b57cec5SDimitry Andric bool isMemUnsized() const { 3070b57cec5SDimitry Andric return Kind == Memory && Mem.Size == 0; 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric bool isMem8() const { 3100b57cec5SDimitry Andric return Kind == Memory && (!Mem.Size || Mem.Size == 8); 3110b57cec5SDimitry Andric } 3120b57cec5SDimitry Andric bool isMem16() const { 3130b57cec5SDimitry Andric return Kind == Memory && (!Mem.Size || Mem.Size == 16); 3140b57cec5SDimitry Andric } 3150b57cec5SDimitry Andric bool isMem32() const { 3160b57cec5SDimitry Andric return Kind == Memory && (!Mem.Size || Mem.Size == 32); 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric bool isMem64() const { 3190b57cec5SDimitry Andric return Kind == Memory && (!Mem.Size || Mem.Size == 64); 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric bool isMem80() const { 3220b57cec5SDimitry Andric return Kind == Memory && (!Mem.Size || Mem.Size == 80); 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric bool isMem128() const { 3250b57cec5SDimitry Andric return Kind == Memory && (!Mem.Size || Mem.Size == 128); 3260b57cec5SDimitry Andric } 3270b57cec5SDimitry Andric bool isMem256() const { 3280b57cec5SDimitry Andric return Kind == Memory && (!Mem.Size || Mem.Size == 256); 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric bool isMem512() const { 3310b57cec5SDimitry Andric return Kind == Memory && (!Mem.Size || Mem.Size == 512); 3320b57cec5SDimitry Andric } 3335ffd83dbSDimitry Andric 3345ffd83dbSDimitry Andric bool isSibMem() const { 3355ffd83dbSDimitry Andric return isMem() && Mem.BaseReg != X86::RIP && Mem.BaseReg != X86::EIP; 3365ffd83dbSDimitry Andric } 3375ffd83dbSDimitry Andric 3380b57cec5SDimitry Andric bool isMemIndexReg(unsigned LowR, unsigned HighR) const { 3390b57cec5SDimitry Andric assert(Kind == Memory && "Invalid access!"); 3400b57cec5SDimitry Andric return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR; 3410b57cec5SDimitry Andric } 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric bool isMem64_RC128() const { 3440b57cec5SDimitry Andric return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15); 3450b57cec5SDimitry Andric } 3460b57cec5SDimitry Andric bool isMem128_RC128() const { 3470b57cec5SDimitry Andric return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15); 3480b57cec5SDimitry Andric } 3490b57cec5SDimitry Andric bool isMem128_RC256() const { 3500b57cec5SDimitry Andric return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15); 3510b57cec5SDimitry Andric } 3520b57cec5SDimitry Andric bool isMem256_RC128() const { 3530b57cec5SDimitry Andric return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15); 3540b57cec5SDimitry Andric } 3550b57cec5SDimitry Andric bool isMem256_RC256() const { 3560b57cec5SDimitry Andric return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15); 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric bool isMem64_RC128X() const { 3605f757f3fSDimitry Andric return isMem64() && X86II::isXMMReg(Mem.IndexReg); 3610b57cec5SDimitry Andric } 3620b57cec5SDimitry Andric bool isMem128_RC128X() const { 3635f757f3fSDimitry Andric return isMem128() && X86II::isXMMReg(Mem.IndexReg); 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric bool isMem128_RC256X() const { 3665f757f3fSDimitry Andric return isMem128() && X86II::isYMMReg(Mem.IndexReg); 3670b57cec5SDimitry Andric } 3680b57cec5SDimitry Andric bool isMem256_RC128X() const { 3695f757f3fSDimitry Andric return isMem256() && X86II::isXMMReg(Mem.IndexReg); 3700b57cec5SDimitry Andric } 3710b57cec5SDimitry Andric bool isMem256_RC256X() const { 3725f757f3fSDimitry Andric return isMem256() && X86II::isYMMReg(Mem.IndexReg); 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric bool isMem256_RC512() const { 3755f757f3fSDimitry Andric return isMem256() && X86II::isZMMReg(Mem.IndexReg); 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric bool isMem512_RC256X() const { 3785f757f3fSDimitry Andric return isMem512() && X86II::isYMMReg(Mem.IndexReg); 3790b57cec5SDimitry Andric } 3800b57cec5SDimitry Andric bool isMem512_RC512() const { 3815f757f3fSDimitry Andric return isMem512() && X86II::isZMMReg(Mem.IndexReg); 3820b57cec5SDimitry Andric } 38306c3fb27SDimitry Andric bool isMem512_GR16() const { 38406c3fb27SDimitry Andric if (!isMem512()) 38506c3fb27SDimitry Andric return false; 38606c3fb27SDimitry Andric if (getMemBaseReg() && 38706c3fb27SDimitry Andric !X86MCRegisterClasses[X86::GR16RegClassID].contains(getMemBaseReg())) 38806c3fb27SDimitry Andric return false; 38906c3fb27SDimitry Andric return true; 39006c3fb27SDimitry Andric } 39106c3fb27SDimitry Andric bool isMem512_GR32() const { 39206c3fb27SDimitry Andric if (!isMem512()) 39306c3fb27SDimitry Andric return false; 39406c3fb27SDimitry Andric if (getMemBaseReg() && 39506c3fb27SDimitry Andric !X86MCRegisterClasses[X86::GR32RegClassID].contains(getMemBaseReg()) && 39606c3fb27SDimitry Andric getMemBaseReg() != X86::EIP) 39706c3fb27SDimitry Andric return false; 39806c3fb27SDimitry Andric if (getMemIndexReg() && 39906c3fb27SDimitry Andric !X86MCRegisterClasses[X86::GR32RegClassID].contains(getMemIndexReg()) && 40006c3fb27SDimitry Andric getMemIndexReg() != X86::EIZ) 40106c3fb27SDimitry Andric return false; 40206c3fb27SDimitry Andric return true; 40306c3fb27SDimitry Andric } 40406c3fb27SDimitry Andric bool isMem512_GR64() const { 40506c3fb27SDimitry Andric if (!isMem512()) 40606c3fb27SDimitry Andric return false; 40706c3fb27SDimitry Andric if (getMemBaseReg() && 40806c3fb27SDimitry Andric !X86MCRegisterClasses[X86::GR64RegClassID].contains(getMemBaseReg()) && 40906c3fb27SDimitry Andric getMemBaseReg() != X86::RIP) 41006c3fb27SDimitry Andric return false; 41106c3fb27SDimitry Andric if (getMemIndexReg() && 41206c3fb27SDimitry Andric !X86MCRegisterClasses[X86::GR64RegClassID].contains(getMemIndexReg()) && 41306c3fb27SDimitry Andric getMemIndexReg() != X86::RIZ) 41406c3fb27SDimitry Andric return false; 41506c3fb27SDimitry Andric return true; 41606c3fb27SDimitry Andric } 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric bool isAbsMem() const { 4190b57cec5SDimitry Andric return Kind == Memory && !getMemSegReg() && !getMemBaseReg() && 42081ad6265SDimitry Andric !getMemIndexReg() && getMemScale() == 1 && isMaybeDirectBranchDest(); 4210b57cec5SDimitry Andric } 42281ad6265SDimitry Andric 4230b57cec5SDimitry Andric bool isAVX512RC() const{ 4240b57cec5SDimitry Andric return isImm(); 4250b57cec5SDimitry Andric } 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric bool isAbsMem16() const { 4280b57cec5SDimitry Andric return isAbsMem() && Mem.ModeSize == 16; 4290b57cec5SDimitry Andric } 4300b57cec5SDimitry Andric 43181ad6265SDimitry Andric bool isMemUseUpRegs() const override { return UseUpRegs; } 43281ad6265SDimitry Andric 4330b57cec5SDimitry Andric bool isSrcIdx() const { 4340b57cec5SDimitry Andric return !getMemIndexReg() && getMemScale() == 1 && 4350b57cec5SDimitry Andric (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI || 4360b57cec5SDimitry Andric getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) && 4370b57cec5SDimitry Andric cast<MCConstantExpr>(getMemDisp())->getValue() == 0; 4380b57cec5SDimitry Andric } 4390b57cec5SDimitry Andric bool isSrcIdx8() const { 4400b57cec5SDimitry Andric return isMem8() && isSrcIdx(); 4410b57cec5SDimitry Andric } 4420b57cec5SDimitry Andric bool isSrcIdx16() const { 4430b57cec5SDimitry Andric return isMem16() && isSrcIdx(); 4440b57cec5SDimitry Andric } 4450b57cec5SDimitry Andric bool isSrcIdx32() const { 4460b57cec5SDimitry Andric return isMem32() && isSrcIdx(); 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric bool isSrcIdx64() const { 4490b57cec5SDimitry Andric return isMem64() && isSrcIdx(); 4500b57cec5SDimitry Andric } 4510b57cec5SDimitry Andric 4520b57cec5SDimitry Andric bool isDstIdx() const { 4530b57cec5SDimitry Andric return !getMemIndexReg() && getMemScale() == 1 && 4540b57cec5SDimitry Andric (getMemSegReg() == 0 || getMemSegReg() == X86::ES) && 4550b57cec5SDimitry Andric (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI || 4560b57cec5SDimitry Andric getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) && 4570b57cec5SDimitry Andric cast<MCConstantExpr>(getMemDisp())->getValue() == 0; 4580b57cec5SDimitry Andric } 4590b57cec5SDimitry Andric bool isDstIdx8() const { 4600b57cec5SDimitry Andric return isMem8() && isDstIdx(); 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric bool isDstIdx16() const { 4630b57cec5SDimitry Andric return isMem16() && isDstIdx(); 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric bool isDstIdx32() const { 4660b57cec5SDimitry Andric return isMem32() && isDstIdx(); 4670b57cec5SDimitry Andric } 4680b57cec5SDimitry Andric bool isDstIdx64() const { 4690b57cec5SDimitry Andric return isMem64() && isDstIdx(); 4700b57cec5SDimitry Andric } 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric bool isMemOffs() const { 4730b57cec5SDimitry Andric return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() && 4740b57cec5SDimitry Andric getMemScale() == 1; 4750b57cec5SDimitry Andric } 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric bool isMemOffs16_8() const { 4780b57cec5SDimitry Andric return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8); 4790b57cec5SDimitry Andric } 4800b57cec5SDimitry Andric bool isMemOffs16_16() const { 4810b57cec5SDimitry Andric return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16); 4820b57cec5SDimitry Andric } 4830b57cec5SDimitry Andric bool isMemOffs16_32() const { 4840b57cec5SDimitry Andric return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32); 4850b57cec5SDimitry Andric } 4860b57cec5SDimitry Andric bool isMemOffs32_8() const { 4870b57cec5SDimitry Andric return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8); 4880b57cec5SDimitry Andric } 4890b57cec5SDimitry Andric bool isMemOffs32_16() const { 4900b57cec5SDimitry Andric return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16); 4910b57cec5SDimitry Andric } 4920b57cec5SDimitry Andric bool isMemOffs32_32() const { 4930b57cec5SDimitry Andric return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32); 4940b57cec5SDimitry Andric } 4950b57cec5SDimitry Andric bool isMemOffs32_64() const { 4960b57cec5SDimitry Andric return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64); 4970b57cec5SDimitry Andric } 4980b57cec5SDimitry Andric bool isMemOffs64_8() const { 4990b57cec5SDimitry Andric return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8); 5000b57cec5SDimitry Andric } 5010b57cec5SDimitry Andric bool isMemOffs64_16() const { 5020b57cec5SDimitry Andric return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16); 5030b57cec5SDimitry Andric } 5040b57cec5SDimitry Andric bool isMemOffs64_32() const { 5050b57cec5SDimitry Andric return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32); 5060b57cec5SDimitry Andric } 5070b57cec5SDimitry Andric bool isMemOffs64_64() const { 5080b57cec5SDimitry Andric return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64); 5090b57cec5SDimitry Andric } 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric bool isPrefix() const { return Kind == Prefix; } 5120b57cec5SDimitry Andric bool isReg() const override { return Kind == Register; } 5130b57cec5SDimitry Andric bool isDXReg() const { return Kind == DXRegister; } 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andric bool isGR32orGR64() const { 5160b57cec5SDimitry Andric return Kind == Register && 5170b57cec5SDimitry Andric (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) || 5180b57cec5SDimitry Andric X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg())); 5190b57cec5SDimitry Andric } 5200b57cec5SDimitry Andric 521590d96feSDimitry Andric bool isGR16orGR32orGR64() const { 522590d96feSDimitry Andric return Kind == Register && 523590d96feSDimitry Andric (X86MCRegisterClasses[X86::GR16RegClassID].contains(getReg()) || 524590d96feSDimitry Andric X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) || 525590d96feSDimitry Andric X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg())); 526590d96feSDimitry Andric } 527590d96feSDimitry Andric 5285ffd83dbSDimitry Andric bool isVectorReg() const { 5295ffd83dbSDimitry Andric return Kind == Register && 5305ffd83dbSDimitry Andric (X86MCRegisterClasses[X86::VR64RegClassID].contains(getReg()) || 5315ffd83dbSDimitry Andric X86MCRegisterClasses[X86::VR128XRegClassID].contains(getReg()) || 5325ffd83dbSDimitry Andric X86MCRegisterClasses[X86::VR256XRegClassID].contains(getReg()) || 5335ffd83dbSDimitry Andric X86MCRegisterClasses[X86::VR512RegClassID].contains(getReg())); 5345ffd83dbSDimitry Andric } 5355ffd83dbSDimitry Andric 5360b57cec5SDimitry Andric bool isVK1Pair() const { 5370b57cec5SDimitry Andric return Kind == Register && 5380b57cec5SDimitry Andric X86MCRegisterClasses[X86::VK1RegClassID].contains(getReg()); 5390b57cec5SDimitry Andric } 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andric bool isVK2Pair() const { 5420b57cec5SDimitry Andric return Kind == Register && 5430b57cec5SDimitry Andric X86MCRegisterClasses[X86::VK2RegClassID].contains(getReg()); 5440b57cec5SDimitry Andric } 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric bool isVK4Pair() const { 5470b57cec5SDimitry Andric return Kind == Register && 5480b57cec5SDimitry Andric X86MCRegisterClasses[X86::VK4RegClassID].contains(getReg()); 5490b57cec5SDimitry Andric } 5500b57cec5SDimitry Andric 5510b57cec5SDimitry Andric bool isVK8Pair() const { 5520b57cec5SDimitry Andric return Kind == Register && 5530b57cec5SDimitry Andric X86MCRegisterClasses[X86::VK8RegClassID].contains(getReg()); 5540b57cec5SDimitry Andric } 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andric bool isVK16Pair() const { 5570b57cec5SDimitry Andric return Kind == Register && 5580b57cec5SDimitry Andric X86MCRegisterClasses[X86::VK16RegClassID].contains(getReg()); 5590b57cec5SDimitry Andric } 5600b57cec5SDimitry Andric 5610b57cec5SDimitry Andric void addExpr(MCInst &Inst, const MCExpr *Expr) const { 5620b57cec5SDimitry Andric // Add as immediates when possible. 5630b57cec5SDimitry Andric if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 5640b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(CE->getValue())); 5650b57cec5SDimitry Andric else 5660b57cec5SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr)); 5670b57cec5SDimitry Andric } 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric void addRegOperands(MCInst &Inst, unsigned N) const { 5700b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 5710b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(getReg())); 5720b57cec5SDimitry Andric } 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric void addGR32orGR64Operands(MCInst &Inst, unsigned N) const { 5750b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 5768bcb0991SDimitry Andric MCRegister RegNo = getReg(); 5770b57cec5SDimitry Andric if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo)) 5780b57cec5SDimitry Andric RegNo = getX86SubSuperRegister(RegNo, 32); 5790b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(RegNo)); 5800b57cec5SDimitry Andric } 5810b57cec5SDimitry Andric 582590d96feSDimitry Andric void addGR16orGR32orGR64Operands(MCInst &Inst, unsigned N) const { 583590d96feSDimitry Andric assert(N == 1 && "Invalid number of operands!"); 584590d96feSDimitry Andric MCRegister RegNo = getReg(); 585590d96feSDimitry Andric if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo) || 586590d96feSDimitry Andric X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo)) 587590d96feSDimitry Andric RegNo = getX86SubSuperRegister(RegNo, 16); 588590d96feSDimitry Andric Inst.addOperand(MCOperand::createReg(RegNo)); 589590d96feSDimitry Andric } 590590d96feSDimitry Andric 5910b57cec5SDimitry Andric void addAVX512RCOperands(MCInst &Inst, unsigned N) const { 5920b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 5930b57cec5SDimitry Andric addExpr(Inst, getImm()); 5940b57cec5SDimitry Andric } 5950b57cec5SDimitry Andric 5960b57cec5SDimitry Andric void addImmOperands(MCInst &Inst, unsigned N) const { 5970b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 5980b57cec5SDimitry Andric addExpr(Inst, getImm()); 5990b57cec5SDimitry Andric } 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andric void addMaskPairOperands(MCInst &Inst, unsigned N) const { 6020b57cec5SDimitry Andric assert(N == 1 && "Invalid number of operands!"); 6030b57cec5SDimitry Andric unsigned Reg = getReg(); 6040b57cec5SDimitry Andric switch (Reg) { 6050b57cec5SDimitry Andric case X86::K0: 6060b57cec5SDimitry Andric case X86::K1: 6070b57cec5SDimitry Andric Reg = X86::K0_K1; 6080b57cec5SDimitry Andric break; 6090b57cec5SDimitry Andric case X86::K2: 6100b57cec5SDimitry Andric case X86::K3: 6110b57cec5SDimitry Andric Reg = X86::K2_K3; 6120b57cec5SDimitry Andric break; 6130b57cec5SDimitry Andric case X86::K4: 6140b57cec5SDimitry Andric case X86::K5: 6150b57cec5SDimitry Andric Reg = X86::K4_K5; 6160b57cec5SDimitry Andric break; 6170b57cec5SDimitry Andric case X86::K6: 6180b57cec5SDimitry Andric case X86::K7: 6190b57cec5SDimitry Andric Reg = X86::K6_K7; 6200b57cec5SDimitry Andric break; 6210b57cec5SDimitry Andric } 6220b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(Reg)); 6230b57cec5SDimitry Andric } 6240b57cec5SDimitry Andric 6250b57cec5SDimitry Andric void addMemOperands(MCInst &Inst, unsigned N) const { 6260b57cec5SDimitry Andric assert((N == 5) && "Invalid number of operands!"); 6275ffd83dbSDimitry Andric if (getMemBaseReg()) 6280b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(getMemBaseReg())); 6295ffd83dbSDimitry Andric else 6305ffd83dbSDimitry Andric Inst.addOperand(MCOperand::createReg(getMemDefaultBaseReg())); 6310b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(getMemScale())); 6320b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(getMemIndexReg())); 6330b57cec5SDimitry Andric addExpr(Inst, getMemDisp()); 6340b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(getMemSegReg())); 6350b57cec5SDimitry Andric } 6360b57cec5SDimitry Andric 6370b57cec5SDimitry Andric void addAbsMemOperands(MCInst &Inst, unsigned N) const { 6380b57cec5SDimitry Andric assert((N == 1) && "Invalid number of operands!"); 6390b57cec5SDimitry Andric // Add as immediates when possible. 6400b57cec5SDimitry Andric if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp())) 6410b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(CE->getValue())); 6420b57cec5SDimitry Andric else 6430b57cec5SDimitry Andric Inst.addOperand(MCOperand::createExpr(getMemDisp())); 6440b57cec5SDimitry Andric } 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric void addSrcIdxOperands(MCInst &Inst, unsigned N) const { 6470b57cec5SDimitry Andric assert((N == 2) && "Invalid number of operands!"); 6480b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(getMemBaseReg())); 6490b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(getMemSegReg())); 6500b57cec5SDimitry Andric } 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric void addDstIdxOperands(MCInst &Inst, unsigned N) const { 6530b57cec5SDimitry Andric assert((N == 1) && "Invalid number of operands!"); 6540b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(getMemBaseReg())); 6550b57cec5SDimitry Andric } 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric void addMemOffsOperands(MCInst &Inst, unsigned N) const { 6580b57cec5SDimitry Andric assert((N == 2) && "Invalid number of operands!"); 6590b57cec5SDimitry Andric // Add as immediates when possible. 6600b57cec5SDimitry Andric if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp())) 6610b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(CE->getValue())); 6620b57cec5SDimitry Andric else 6630b57cec5SDimitry Andric Inst.addOperand(MCOperand::createExpr(getMemDisp())); 6640b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(getMemSegReg())); 6650b57cec5SDimitry Andric } 6660b57cec5SDimitry Andric 6670b57cec5SDimitry Andric static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) { 6680b57cec5SDimitry Andric SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size()); 6698bcb0991SDimitry Andric auto Res = std::make_unique<X86Operand>(Token, Loc, EndLoc); 6700b57cec5SDimitry Andric Res->Tok.Data = Str.data(); 6710b57cec5SDimitry Andric Res->Tok.Length = Str.size(); 6720b57cec5SDimitry Andric return Res; 6730b57cec5SDimitry Andric } 6740b57cec5SDimitry Andric 6750b57cec5SDimitry Andric static std::unique_ptr<X86Operand> 6760b57cec5SDimitry Andric CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc, 6770b57cec5SDimitry Andric bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(), 6780b57cec5SDimitry Andric StringRef SymName = StringRef(), void *OpDecl = nullptr) { 6798bcb0991SDimitry Andric auto Res = std::make_unique<X86Operand>(Register, StartLoc, EndLoc); 6800b57cec5SDimitry Andric Res->Reg.RegNo = RegNo; 6810b57cec5SDimitry Andric Res->AddressOf = AddressOf; 6820b57cec5SDimitry Andric Res->OffsetOfLoc = OffsetOfLoc; 6830b57cec5SDimitry Andric Res->SymName = SymName; 6840b57cec5SDimitry Andric Res->OpDecl = OpDecl; 6850b57cec5SDimitry Andric return Res; 6860b57cec5SDimitry Andric } 6870b57cec5SDimitry Andric 6880b57cec5SDimitry Andric static std::unique_ptr<X86Operand> 6890b57cec5SDimitry Andric CreateDXReg(SMLoc StartLoc, SMLoc EndLoc) { 6908bcb0991SDimitry Andric return std::make_unique<X86Operand>(DXRegister, StartLoc, EndLoc); 6910b57cec5SDimitry Andric } 6920b57cec5SDimitry Andric 6930b57cec5SDimitry Andric static std::unique_ptr<X86Operand> 6940b57cec5SDimitry Andric CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) { 6958bcb0991SDimitry Andric auto Res = std::make_unique<X86Operand>(Prefix, StartLoc, EndLoc); 6960b57cec5SDimitry Andric Res->Pref.Prefixes = Prefixes; 6970b57cec5SDimitry Andric return Res; 6980b57cec5SDimitry Andric } 6990b57cec5SDimitry Andric 7000b57cec5SDimitry Andric static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val, 701480093f4SDimitry Andric SMLoc StartLoc, SMLoc EndLoc, 702480093f4SDimitry Andric StringRef SymName = StringRef(), 703480093f4SDimitry Andric void *OpDecl = nullptr, 704480093f4SDimitry Andric bool GlobalRef = true) { 7058bcb0991SDimitry Andric auto Res = std::make_unique<X86Operand>(Immediate, StartLoc, EndLoc); 7060b57cec5SDimitry Andric Res->Imm.Val = Val; 707480093f4SDimitry Andric Res->Imm.LocalRef = !GlobalRef; 708480093f4SDimitry Andric Res->SymName = SymName; 709480093f4SDimitry Andric Res->OpDecl = OpDecl; 710480093f4SDimitry Andric Res->AddressOf = true; 7110b57cec5SDimitry Andric return Res; 7120b57cec5SDimitry Andric } 7130b57cec5SDimitry Andric 7140b57cec5SDimitry Andric /// Create an absolute memory operand. 7150b57cec5SDimitry Andric static std::unique_ptr<X86Operand> 7160b57cec5SDimitry Andric CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, 7170b57cec5SDimitry Andric unsigned Size = 0, StringRef SymName = StringRef(), 71881ad6265SDimitry Andric void *OpDecl = nullptr, unsigned FrontendSize = 0, 71981ad6265SDimitry Andric bool UseUpRegs = false, bool MaybeDirectBranchDest = true) { 7208bcb0991SDimitry Andric auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc); 7210b57cec5SDimitry Andric Res->Mem.SegReg = 0; 7220b57cec5SDimitry Andric Res->Mem.Disp = Disp; 7230b57cec5SDimitry Andric Res->Mem.BaseReg = 0; 7245ffd83dbSDimitry Andric Res->Mem.DefaultBaseReg = 0; 7250b57cec5SDimitry Andric Res->Mem.IndexReg = 0; 7260b57cec5SDimitry Andric Res->Mem.Scale = 1; 7270b57cec5SDimitry Andric Res->Mem.Size = Size; 7280b57cec5SDimitry Andric Res->Mem.ModeSize = ModeSize; 7290b57cec5SDimitry Andric Res->Mem.FrontendSize = FrontendSize; 73081ad6265SDimitry Andric Res->Mem.MaybeDirectBranchDest = MaybeDirectBranchDest; 73181ad6265SDimitry Andric Res->UseUpRegs = UseUpRegs; 7320b57cec5SDimitry Andric Res->SymName = SymName; 7330b57cec5SDimitry Andric Res->OpDecl = OpDecl; 7340b57cec5SDimitry Andric Res->AddressOf = false; 7350b57cec5SDimitry Andric return Res; 7360b57cec5SDimitry Andric } 7370b57cec5SDimitry Andric 7380b57cec5SDimitry Andric /// Create a generalized memory operand. 7390b57cec5SDimitry Andric static std::unique_ptr<X86Operand> 7400b57cec5SDimitry Andric CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp, 7410b57cec5SDimitry Andric unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc, 7425ffd83dbSDimitry Andric SMLoc EndLoc, unsigned Size = 0, 7435ffd83dbSDimitry Andric unsigned DefaultBaseReg = X86::NoRegister, 7445ffd83dbSDimitry Andric StringRef SymName = StringRef(), void *OpDecl = nullptr, 74581ad6265SDimitry Andric unsigned FrontendSize = 0, bool UseUpRegs = false, 74681ad6265SDimitry Andric bool MaybeDirectBranchDest = true) { 7470b57cec5SDimitry Andric // We should never just have a displacement, that should be parsed as an 7480b57cec5SDimitry Andric // absolute memory operand. 7495ffd83dbSDimitry Andric assert((SegReg || BaseReg || IndexReg || DefaultBaseReg) && 7505ffd83dbSDimitry Andric "Invalid memory operand!"); 7510b57cec5SDimitry Andric 7520b57cec5SDimitry Andric // The scale should always be one of {1,2,4,8}. 7530b57cec5SDimitry Andric assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) && 7540b57cec5SDimitry Andric "Invalid scale!"); 7558bcb0991SDimitry Andric auto Res = std::make_unique<X86Operand>(Memory, StartLoc, EndLoc); 7560b57cec5SDimitry Andric Res->Mem.SegReg = SegReg; 7570b57cec5SDimitry Andric Res->Mem.Disp = Disp; 7580b57cec5SDimitry Andric Res->Mem.BaseReg = BaseReg; 7595ffd83dbSDimitry Andric Res->Mem.DefaultBaseReg = DefaultBaseReg; 7600b57cec5SDimitry Andric Res->Mem.IndexReg = IndexReg; 7610b57cec5SDimitry Andric Res->Mem.Scale = Scale; 7620b57cec5SDimitry Andric Res->Mem.Size = Size; 7630b57cec5SDimitry Andric Res->Mem.ModeSize = ModeSize; 7640b57cec5SDimitry Andric Res->Mem.FrontendSize = FrontendSize; 76581ad6265SDimitry Andric Res->Mem.MaybeDirectBranchDest = MaybeDirectBranchDest; 76681ad6265SDimitry Andric Res->UseUpRegs = UseUpRegs; 7670b57cec5SDimitry Andric Res->SymName = SymName; 7680b57cec5SDimitry Andric Res->OpDecl = OpDecl; 7690b57cec5SDimitry Andric Res->AddressOf = false; 7700b57cec5SDimitry Andric return Res; 7710b57cec5SDimitry Andric } 7720b57cec5SDimitry Andric }; 7730b57cec5SDimitry Andric 7740b57cec5SDimitry Andric } // end namespace llvm 7750b57cec5SDimitry Andric 7760b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H 777