1*9880d681SAndroid Build Coastguard Worker //===-- X86Operand.h - Parsed X86 machine instruction --------------------===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H 11*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_TARGET_X86_ASMPARSER_X86OPERAND_H 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Worker #include "X86AsmParserCommon.h" 14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h" 15*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h" 16*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCRegisterInfo.h" 17*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h" 19*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/X86MCTargetDesc.h" 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker namespace llvm { 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker /// X86Operand - Instances of this class represent a parsed X86 machine 24*9880d681SAndroid Build Coastguard Worker /// instruction. 25*9880d681SAndroid Build Coastguard Worker struct X86Operand : public MCParsedAsmOperand { 26*9880d681SAndroid Build Coastguard Worker enum KindTy { 27*9880d681SAndroid Build Coastguard Worker Token, 28*9880d681SAndroid Build Coastguard Worker Register, 29*9880d681SAndroid Build Coastguard Worker Immediate, 30*9880d681SAndroid Build Coastguard Worker Memory 31*9880d681SAndroid Build Coastguard Worker } Kind; 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker SMLoc StartLoc, EndLoc; 34*9880d681SAndroid Build Coastguard Worker SMLoc OffsetOfLoc; 35*9880d681SAndroid Build Coastguard Worker StringRef SymName; 36*9880d681SAndroid Build Coastguard Worker void *OpDecl; 37*9880d681SAndroid Build Coastguard Worker bool AddressOf; 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker struct TokOp { 40*9880d681SAndroid Build Coastguard Worker const char *Data; 41*9880d681SAndroid Build Coastguard Worker unsigned Length; 42*9880d681SAndroid Build Coastguard Worker }; 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Worker struct RegOp { 45*9880d681SAndroid Build Coastguard Worker unsigned RegNo; 46*9880d681SAndroid Build Coastguard Worker }; 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Worker struct ImmOp { 49*9880d681SAndroid Build Coastguard Worker const MCExpr *Val; 50*9880d681SAndroid Build Coastguard Worker }; 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Worker struct MemOp { 53*9880d681SAndroid Build Coastguard Worker unsigned SegReg; 54*9880d681SAndroid Build Coastguard Worker const MCExpr *Disp; 55*9880d681SAndroid Build Coastguard Worker unsigned BaseReg; 56*9880d681SAndroid Build Coastguard Worker unsigned IndexReg; 57*9880d681SAndroid Build Coastguard Worker unsigned Scale; 58*9880d681SAndroid Build Coastguard Worker unsigned Size; 59*9880d681SAndroid Build Coastguard Worker unsigned ModeSize; 60*9880d681SAndroid Build Coastguard Worker }; 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker union { 63*9880d681SAndroid Build Coastguard Worker struct TokOp Tok; 64*9880d681SAndroid Build Coastguard Worker struct RegOp Reg; 65*9880d681SAndroid Build Coastguard Worker struct ImmOp Imm; 66*9880d681SAndroid Build Coastguard Worker struct MemOp Mem; 67*9880d681SAndroid Build Coastguard Worker }; 68*9880d681SAndroid Build Coastguard Worker X86OperandX86Operand69*9880d681SAndroid Build Coastguard Worker X86Operand(KindTy K, SMLoc Start, SMLoc End) 70*9880d681SAndroid Build Coastguard Worker : Kind(K), StartLoc(Start), EndLoc(End) {} 71*9880d681SAndroid Build Coastguard Worker getSymNameX86Operand72*9880d681SAndroid Build Coastguard Worker StringRef getSymName() override { return SymName; } getOpDeclX86Operand73*9880d681SAndroid Build Coastguard Worker void *getOpDecl() override { return OpDecl; } 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Worker /// getStartLoc - Get the location of the first token of this operand. getStartLocX86Operand76*9880d681SAndroid Build Coastguard Worker SMLoc getStartLoc() const override { return StartLoc; } 77*9880d681SAndroid Build Coastguard Worker /// getEndLoc - Get the location of the last token of this operand. getEndLocX86Operand78*9880d681SAndroid Build Coastguard Worker SMLoc getEndLoc() const override { return EndLoc; } 79*9880d681SAndroid Build Coastguard Worker /// getLocRange - Get the range between the first and last token of this 80*9880d681SAndroid Build Coastguard Worker /// operand. getLocRangeX86Operand81*9880d681SAndroid Build Coastguard Worker SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); } 82*9880d681SAndroid Build Coastguard Worker /// getOffsetOfLoc - Get the location of the offset operator. getOffsetOfLocX86Operand83*9880d681SAndroid Build Coastguard Worker SMLoc getOffsetOfLoc() const override { return OffsetOfLoc; } 84*9880d681SAndroid Build Coastguard Worker printX86Operand85*9880d681SAndroid Build Coastguard Worker void print(raw_ostream &OS) const override {} 86*9880d681SAndroid Build Coastguard Worker getTokenX86Operand87*9880d681SAndroid Build Coastguard Worker StringRef getToken() const { 88*9880d681SAndroid Build Coastguard Worker assert(Kind == Token && "Invalid access!"); 89*9880d681SAndroid Build Coastguard Worker return StringRef(Tok.Data, Tok.Length); 90*9880d681SAndroid Build Coastguard Worker } setTokenValueX86Operand91*9880d681SAndroid Build Coastguard Worker void setTokenValue(StringRef Value) { 92*9880d681SAndroid Build Coastguard Worker assert(Kind == Token && "Invalid access!"); 93*9880d681SAndroid Build Coastguard Worker Tok.Data = Value.data(); 94*9880d681SAndroid Build Coastguard Worker Tok.Length = Value.size(); 95*9880d681SAndroid Build Coastguard Worker } 96*9880d681SAndroid Build Coastguard Worker getRegX86Operand97*9880d681SAndroid Build Coastguard Worker unsigned getReg() const override { 98*9880d681SAndroid Build Coastguard Worker assert(Kind == Register && "Invalid access!"); 99*9880d681SAndroid Build Coastguard Worker return Reg.RegNo; 100*9880d681SAndroid Build Coastguard Worker } 101*9880d681SAndroid Build Coastguard Worker getImmX86Operand102*9880d681SAndroid Build Coastguard Worker const MCExpr *getImm() const { 103*9880d681SAndroid Build Coastguard Worker assert(Kind == Immediate && "Invalid access!"); 104*9880d681SAndroid Build Coastguard Worker return Imm.Val; 105*9880d681SAndroid Build Coastguard Worker } 106*9880d681SAndroid Build Coastguard Worker getMemDispX86Operand107*9880d681SAndroid Build Coastguard Worker const MCExpr *getMemDisp() const { 108*9880d681SAndroid Build Coastguard Worker assert(Kind == Memory && "Invalid access!"); 109*9880d681SAndroid Build Coastguard Worker return Mem.Disp; 110*9880d681SAndroid Build Coastguard Worker } getMemSegRegX86Operand111*9880d681SAndroid Build Coastguard Worker unsigned getMemSegReg() const { 112*9880d681SAndroid Build Coastguard Worker assert(Kind == Memory && "Invalid access!"); 113*9880d681SAndroid Build Coastguard Worker return Mem.SegReg; 114*9880d681SAndroid Build Coastguard Worker } getMemBaseRegX86Operand115*9880d681SAndroid Build Coastguard Worker unsigned getMemBaseReg() const { 116*9880d681SAndroid Build Coastguard Worker assert(Kind == Memory && "Invalid access!"); 117*9880d681SAndroid Build Coastguard Worker return Mem.BaseReg; 118*9880d681SAndroid Build Coastguard Worker } getMemIndexRegX86Operand119*9880d681SAndroid Build Coastguard Worker unsigned getMemIndexReg() const { 120*9880d681SAndroid Build Coastguard Worker assert(Kind == Memory && "Invalid access!"); 121*9880d681SAndroid Build Coastguard Worker return Mem.IndexReg; 122*9880d681SAndroid Build Coastguard Worker } getMemScaleX86Operand123*9880d681SAndroid Build Coastguard Worker unsigned getMemScale() const { 124*9880d681SAndroid Build Coastguard Worker assert(Kind == Memory && "Invalid access!"); 125*9880d681SAndroid Build Coastguard Worker return Mem.Scale; 126*9880d681SAndroid Build Coastguard Worker } getMemModeSizeX86Operand127*9880d681SAndroid Build Coastguard Worker unsigned getMemModeSize() const { 128*9880d681SAndroid Build Coastguard Worker assert(Kind == Memory && "Invalid access!"); 129*9880d681SAndroid Build Coastguard Worker return Mem.ModeSize; 130*9880d681SAndroid Build Coastguard Worker } 131*9880d681SAndroid Build Coastguard Worker isTokenX86Operand132*9880d681SAndroid Build Coastguard Worker bool isToken() const override {return Kind == Token; } 133*9880d681SAndroid Build Coastguard Worker isImmX86Operand134*9880d681SAndroid Build Coastguard Worker bool isImm() const override { return Kind == Immediate; } 135*9880d681SAndroid Build Coastguard Worker isImmSExti16i8X86Operand136*9880d681SAndroid Build Coastguard Worker bool isImmSExti16i8() const { 137*9880d681SAndroid Build Coastguard Worker if (!isImm()) 138*9880d681SAndroid Build Coastguard Worker return false; 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Worker // If this isn't a constant expr, just assume it fits and let relaxation 141*9880d681SAndroid Build Coastguard Worker // handle it. 142*9880d681SAndroid Build Coastguard Worker const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 143*9880d681SAndroid Build Coastguard Worker if (!CE) 144*9880d681SAndroid Build Coastguard Worker return true; 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker // Otherwise, check the value is in a range that makes sense for this 147*9880d681SAndroid Build Coastguard Worker // extension. 148*9880d681SAndroid Build Coastguard Worker return isImmSExti16i8Value(CE->getValue()); 149*9880d681SAndroid Build Coastguard Worker } isImmSExti32i8X86Operand150*9880d681SAndroid Build Coastguard Worker bool isImmSExti32i8() const { 151*9880d681SAndroid Build Coastguard Worker if (!isImm()) 152*9880d681SAndroid Build Coastguard Worker return false; 153*9880d681SAndroid Build Coastguard Worker 154*9880d681SAndroid Build Coastguard Worker // If this isn't a constant expr, just assume it fits and let relaxation 155*9880d681SAndroid Build Coastguard Worker // handle it. 156*9880d681SAndroid Build Coastguard Worker const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 157*9880d681SAndroid Build Coastguard Worker if (!CE) 158*9880d681SAndroid Build Coastguard Worker return true; 159*9880d681SAndroid Build Coastguard Worker 160*9880d681SAndroid Build Coastguard Worker // Otherwise, check the value is in a range that makes sense for this 161*9880d681SAndroid Build Coastguard Worker // extension. 162*9880d681SAndroid Build Coastguard Worker return isImmSExti32i8Value(CE->getValue()); 163*9880d681SAndroid Build Coastguard Worker } isImmSExti64i8X86Operand164*9880d681SAndroid Build Coastguard Worker bool isImmSExti64i8() const { 165*9880d681SAndroid Build Coastguard Worker if (!isImm()) 166*9880d681SAndroid Build Coastguard Worker return false; 167*9880d681SAndroid Build Coastguard Worker 168*9880d681SAndroid Build Coastguard Worker // If this isn't a constant expr, just assume it fits and let relaxation 169*9880d681SAndroid Build Coastguard Worker // handle it. 170*9880d681SAndroid Build Coastguard Worker const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 171*9880d681SAndroid Build Coastguard Worker if (!CE) 172*9880d681SAndroid Build Coastguard Worker return true; 173*9880d681SAndroid Build Coastguard Worker 174*9880d681SAndroid Build Coastguard Worker // Otherwise, check the value is in a range that makes sense for this 175*9880d681SAndroid Build Coastguard Worker // extension. 176*9880d681SAndroid Build Coastguard Worker return isImmSExti64i8Value(CE->getValue()); 177*9880d681SAndroid Build Coastguard Worker } isImmSExti64i32X86Operand178*9880d681SAndroid Build Coastguard Worker bool isImmSExti64i32() const { 179*9880d681SAndroid Build Coastguard Worker if (!isImm()) 180*9880d681SAndroid Build Coastguard Worker return false; 181*9880d681SAndroid Build Coastguard Worker 182*9880d681SAndroid Build Coastguard Worker // If this isn't a constant expr, just assume it fits and let relaxation 183*9880d681SAndroid Build Coastguard Worker // handle it. 184*9880d681SAndroid Build Coastguard Worker const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 185*9880d681SAndroid Build Coastguard Worker if (!CE) 186*9880d681SAndroid Build Coastguard Worker return true; 187*9880d681SAndroid Build Coastguard Worker 188*9880d681SAndroid Build Coastguard Worker // Otherwise, check the value is in a range that makes sense for this 189*9880d681SAndroid Build Coastguard Worker // extension. 190*9880d681SAndroid Build Coastguard Worker return isImmSExti64i32Value(CE->getValue()); 191*9880d681SAndroid Build Coastguard Worker } 192*9880d681SAndroid Build Coastguard Worker isImmUnsignedi8X86Operand193*9880d681SAndroid Build Coastguard Worker bool isImmUnsignedi8() const { 194*9880d681SAndroid Build Coastguard Worker if (!isImm()) return false; 195*9880d681SAndroid Build Coastguard Worker const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); 196*9880d681SAndroid Build Coastguard Worker if (!CE) return false; 197*9880d681SAndroid Build Coastguard Worker return isImmUnsignedi8Value(CE->getValue()); 198*9880d681SAndroid Build Coastguard Worker } 199*9880d681SAndroid Build Coastguard Worker isOffsetOfX86Operand200*9880d681SAndroid Build Coastguard Worker bool isOffsetOf() const override { 201*9880d681SAndroid Build Coastguard Worker return OffsetOfLoc.getPointer(); 202*9880d681SAndroid Build Coastguard Worker } 203*9880d681SAndroid Build Coastguard Worker needAddressOfX86Operand204*9880d681SAndroid Build Coastguard Worker bool needAddressOf() const override { 205*9880d681SAndroid Build Coastguard Worker return AddressOf; 206*9880d681SAndroid Build Coastguard Worker } 207*9880d681SAndroid Build Coastguard Worker isMemX86Operand208*9880d681SAndroid Build Coastguard Worker bool isMem() const override { return Kind == Memory; } isMemUnsizedX86Operand209*9880d681SAndroid Build Coastguard Worker bool isMemUnsized() const { 210*9880d681SAndroid Build Coastguard Worker return Kind == Memory && Mem.Size == 0; 211*9880d681SAndroid Build Coastguard Worker } isMem8X86Operand212*9880d681SAndroid Build Coastguard Worker bool isMem8() const { 213*9880d681SAndroid Build Coastguard Worker return Kind == Memory && (!Mem.Size || Mem.Size == 8); 214*9880d681SAndroid Build Coastguard Worker } isMem16X86Operand215*9880d681SAndroid Build Coastguard Worker bool isMem16() const { 216*9880d681SAndroid Build Coastguard Worker return Kind == Memory && (!Mem.Size || Mem.Size == 16); 217*9880d681SAndroid Build Coastguard Worker } isMem32X86Operand218*9880d681SAndroid Build Coastguard Worker bool isMem32() const { 219*9880d681SAndroid Build Coastguard Worker return Kind == Memory && (!Mem.Size || Mem.Size == 32); 220*9880d681SAndroid Build Coastguard Worker } isMem64X86Operand221*9880d681SAndroid Build Coastguard Worker bool isMem64() const { 222*9880d681SAndroid Build Coastguard Worker return Kind == Memory && (!Mem.Size || Mem.Size == 64); 223*9880d681SAndroid Build Coastguard Worker } isMem80X86Operand224*9880d681SAndroid Build Coastguard Worker bool isMem80() const { 225*9880d681SAndroid Build Coastguard Worker return Kind == Memory && (!Mem.Size || Mem.Size == 80); 226*9880d681SAndroid Build Coastguard Worker } isMem128X86Operand227*9880d681SAndroid Build Coastguard Worker bool isMem128() const { 228*9880d681SAndroid Build Coastguard Worker return Kind == Memory && (!Mem.Size || Mem.Size == 128); 229*9880d681SAndroid Build Coastguard Worker } isMem256X86Operand230*9880d681SAndroid Build Coastguard Worker bool isMem256() const { 231*9880d681SAndroid Build Coastguard Worker return Kind == Memory && (!Mem.Size || Mem.Size == 256); 232*9880d681SAndroid Build Coastguard Worker } isMem512X86Operand233*9880d681SAndroid Build Coastguard Worker bool isMem512() const { 234*9880d681SAndroid Build Coastguard Worker return Kind == Memory && (!Mem.Size || Mem.Size == 512); 235*9880d681SAndroid Build Coastguard Worker } isMemIndexRegX86Operand236*9880d681SAndroid Build Coastguard Worker bool isMemIndexReg(unsigned LowR, unsigned HighR) const { 237*9880d681SAndroid Build Coastguard Worker assert(Kind == Memory && "Invalid access!"); 238*9880d681SAndroid Build Coastguard Worker return Mem.IndexReg >= LowR && Mem.IndexReg <= HighR; 239*9880d681SAndroid Build Coastguard Worker } 240*9880d681SAndroid Build Coastguard Worker isMem64_RC128X86Operand241*9880d681SAndroid Build Coastguard Worker bool isMem64_RC128() const { 242*9880d681SAndroid Build Coastguard Worker return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM15); 243*9880d681SAndroid Build Coastguard Worker } isMem128_RC128X86Operand244*9880d681SAndroid Build Coastguard Worker bool isMem128_RC128() const { 245*9880d681SAndroid Build Coastguard Worker return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM15); 246*9880d681SAndroid Build Coastguard Worker } isMem128_RC256X86Operand247*9880d681SAndroid Build Coastguard Worker bool isMem128_RC256() const { 248*9880d681SAndroid Build Coastguard Worker return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM15); 249*9880d681SAndroid Build Coastguard Worker } isMem256_RC128X86Operand250*9880d681SAndroid Build Coastguard Worker bool isMem256_RC128() const { 251*9880d681SAndroid Build Coastguard Worker return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM15); 252*9880d681SAndroid Build Coastguard Worker } isMem256_RC256X86Operand253*9880d681SAndroid Build Coastguard Worker bool isMem256_RC256() const { 254*9880d681SAndroid Build Coastguard Worker return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM15); 255*9880d681SAndroid Build Coastguard Worker } 256*9880d681SAndroid Build Coastguard Worker isMem64_RC128XX86Operand257*9880d681SAndroid Build Coastguard Worker bool isMem64_RC128X() const { 258*9880d681SAndroid Build Coastguard Worker return isMem64() && isMemIndexReg(X86::XMM0, X86::XMM31); 259*9880d681SAndroid Build Coastguard Worker } isMem128_RC128XX86Operand260*9880d681SAndroid Build Coastguard Worker bool isMem128_RC128X() const { 261*9880d681SAndroid Build Coastguard Worker return isMem128() && isMemIndexReg(X86::XMM0, X86::XMM31); 262*9880d681SAndroid Build Coastguard Worker } isMem128_RC256XX86Operand263*9880d681SAndroid Build Coastguard Worker bool isMem128_RC256X() const { 264*9880d681SAndroid Build Coastguard Worker return isMem128() && isMemIndexReg(X86::YMM0, X86::YMM31); 265*9880d681SAndroid Build Coastguard Worker } isMem256_RC128XX86Operand266*9880d681SAndroid Build Coastguard Worker bool isMem256_RC128X() const { 267*9880d681SAndroid Build Coastguard Worker return isMem256() && isMemIndexReg(X86::XMM0, X86::XMM31); 268*9880d681SAndroid Build Coastguard Worker } isMem256_RC256XX86Operand269*9880d681SAndroid Build Coastguard Worker bool isMem256_RC256X() const { 270*9880d681SAndroid Build Coastguard Worker return isMem256() && isMemIndexReg(X86::YMM0, X86::YMM31); 271*9880d681SAndroid Build Coastguard Worker } isMem512_RC256XX86Operand272*9880d681SAndroid Build Coastguard Worker bool isMem512_RC256X() const { 273*9880d681SAndroid Build Coastguard Worker return isMem512() && isMemIndexReg(X86::YMM0, X86::YMM31); 274*9880d681SAndroid Build Coastguard Worker } isMem512_RC512X86Operand275*9880d681SAndroid Build Coastguard Worker bool isMem512_RC512() const { 276*9880d681SAndroid Build Coastguard Worker return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31); 277*9880d681SAndroid Build Coastguard Worker } 278*9880d681SAndroid Build Coastguard Worker isAbsMemX86Operand279*9880d681SAndroid Build Coastguard Worker bool isAbsMem() const { 280*9880d681SAndroid Build Coastguard Worker return Kind == Memory && !getMemSegReg() && !getMemBaseReg() && 281*9880d681SAndroid Build Coastguard Worker !getMemIndexReg() && getMemScale() == 1; 282*9880d681SAndroid Build Coastguard Worker } isAVX512RCX86Operand283*9880d681SAndroid Build Coastguard Worker bool isAVX512RC() const{ 284*9880d681SAndroid Build Coastguard Worker return isImm(); 285*9880d681SAndroid Build Coastguard Worker } 286*9880d681SAndroid Build Coastguard Worker isAbsMem16X86Operand287*9880d681SAndroid Build Coastguard Worker bool isAbsMem16() const { 288*9880d681SAndroid Build Coastguard Worker return isAbsMem() && Mem.ModeSize == 16; 289*9880d681SAndroid Build Coastguard Worker } 290*9880d681SAndroid Build Coastguard Worker isSrcIdxX86Operand291*9880d681SAndroid Build Coastguard Worker bool isSrcIdx() const { 292*9880d681SAndroid Build Coastguard Worker return !getMemIndexReg() && getMemScale() == 1 && 293*9880d681SAndroid Build Coastguard Worker (getMemBaseReg() == X86::RSI || getMemBaseReg() == X86::ESI || 294*9880d681SAndroid Build Coastguard Worker getMemBaseReg() == X86::SI) && isa<MCConstantExpr>(getMemDisp()) && 295*9880d681SAndroid Build Coastguard Worker cast<MCConstantExpr>(getMemDisp())->getValue() == 0; 296*9880d681SAndroid Build Coastguard Worker } isSrcIdx8X86Operand297*9880d681SAndroid Build Coastguard Worker bool isSrcIdx8() const { 298*9880d681SAndroid Build Coastguard Worker return isMem8() && isSrcIdx(); 299*9880d681SAndroid Build Coastguard Worker } isSrcIdx16X86Operand300*9880d681SAndroid Build Coastguard Worker bool isSrcIdx16() const { 301*9880d681SAndroid Build Coastguard Worker return isMem16() && isSrcIdx(); 302*9880d681SAndroid Build Coastguard Worker } isSrcIdx32X86Operand303*9880d681SAndroid Build Coastguard Worker bool isSrcIdx32() const { 304*9880d681SAndroid Build Coastguard Worker return isMem32() && isSrcIdx(); 305*9880d681SAndroid Build Coastguard Worker } isSrcIdx64X86Operand306*9880d681SAndroid Build Coastguard Worker bool isSrcIdx64() const { 307*9880d681SAndroid Build Coastguard Worker return isMem64() && isSrcIdx(); 308*9880d681SAndroid Build Coastguard Worker } 309*9880d681SAndroid Build Coastguard Worker isDstIdxX86Operand310*9880d681SAndroid Build Coastguard Worker bool isDstIdx() const { 311*9880d681SAndroid Build Coastguard Worker return !getMemIndexReg() && getMemScale() == 1 && 312*9880d681SAndroid Build Coastguard Worker (getMemSegReg() == 0 || getMemSegReg() == X86::ES) && 313*9880d681SAndroid Build Coastguard Worker (getMemBaseReg() == X86::RDI || getMemBaseReg() == X86::EDI || 314*9880d681SAndroid Build Coastguard Worker getMemBaseReg() == X86::DI) && isa<MCConstantExpr>(getMemDisp()) && 315*9880d681SAndroid Build Coastguard Worker cast<MCConstantExpr>(getMemDisp())->getValue() == 0; 316*9880d681SAndroid Build Coastguard Worker } isDstIdx8X86Operand317*9880d681SAndroid Build Coastguard Worker bool isDstIdx8() const { 318*9880d681SAndroid Build Coastguard Worker return isMem8() && isDstIdx(); 319*9880d681SAndroid Build Coastguard Worker } isDstIdx16X86Operand320*9880d681SAndroid Build Coastguard Worker bool isDstIdx16() const { 321*9880d681SAndroid Build Coastguard Worker return isMem16() && isDstIdx(); 322*9880d681SAndroid Build Coastguard Worker } isDstIdx32X86Operand323*9880d681SAndroid Build Coastguard Worker bool isDstIdx32() const { 324*9880d681SAndroid Build Coastguard Worker return isMem32() && isDstIdx(); 325*9880d681SAndroid Build Coastguard Worker } isDstIdx64X86Operand326*9880d681SAndroid Build Coastguard Worker bool isDstIdx64() const { 327*9880d681SAndroid Build Coastguard Worker return isMem64() && isDstIdx(); 328*9880d681SAndroid Build Coastguard Worker } 329*9880d681SAndroid Build Coastguard Worker isMemOffsX86Operand330*9880d681SAndroid Build Coastguard Worker bool isMemOffs() const { 331*9880d681SAndroid Build Coastguard Worker return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() && 332*9880d681SAndroid Build Coastguard Worker getMemScale() == 1; 333*9880d681SAndroid Build Coastguard Worker } 334*9880d681SAndroid Build Coastguard Worker isMemOffs16_8X86Operand335*9880d681SAndroid Build Coastguard Worker bool isMemOffs16_8() const { 336*9880d681SAndroid Build Coastguard Worker return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8); 337*9880d681SAndroid Build Coastguard Worker } isMemOffs16_16X86Operand338*9880d681SAndroid Build Coastguard Worker bool isMemOffs16_16() const { 339*9880d681SAndroid Build Coastguard Worker return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16); 340*9880d681SAndroid Build Coastguard Worker } isMemOffs16_32X86Operand341*9880d681SAndroid Build Coastguard Worker bool isMemOffs16_32() const { 342*9880d681SAndroid Build Coastguard Worker return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32); 343*9880d681SAndroid Build Coastguard Worker } isMemOffs32_8X86Operand344*9880d681SAndroid Build Coastguard Worker bool isMemOffs32_8() const { 345*9880d681SAndroid Build Coastguard Worker return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8); 346*9880d681SAndroid Build Coastguard Worker } isMemOffs32_16X86Operand347*9880d681SAndroid Build Coastguard Worker bool isMemOffs32_16() const { 348*9880d681SAndroid Build Coastguard Worker return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16); 349*9880d681SAndroid Build Coastguard Worker } isMemOffs32_32X86Operand350*9880d681SAndroid Build Coastguard Worker bool isMemOffs32_32() const { 351*9880d681SAndroid Build Coastguard Worker return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32); 352*9880d681SAndroid Build Coastguard Worker } isMemOffs32_64X86Operand353*9880d681SAndroid Build Coastguard Worker bool isMemOffs32_64() const { 354*9880d681SAndroid Build Coastguard Worker return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64); 355*9880d681SAndroid Build Coastguard Worker } isMemOffs64_8X86Operand356*9880d681SAndroid Build Coastguard Worker bool isMemOffs64_8() const { 357*9880d681SAndroid Build Coastguard Worker return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8); 358*9880d681SAndroid Build Coastguard Worker } isMemOffs64_16X86Operand359*9880d681SAndroid Build Coastguard Worker bool isMemOffs64_16() const { 360*9880d681SAndroid Build Coastguard Worker return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16); 361*9880d681SAndroid Build Coastguard Worker } isMemOffs64_32X86Operand362*9880d681SAndroid Build Coastguard Worker bool isMemOffs64_32() const { 363*9880d681SAndroid Build Coastguard Worker return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32); 364*9880d681SAndroid Build Coastguard Worker } isMemOffs64_64X86Operand365*9880d681SAndroid Build Coastguard Worker bool isMemOffs64_64() const { 366*9880d681SAndroid Build Coastguard Worker return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64); 367*9880d681SAndroid Build Coastguard Worker } 368*9880d681SAndroid Build Coastguard Worker isRegX86Operand369*9880d681SAndroid Build Coastguard Worker bool isReg() const override { return Kind == Register; } 370*9880d681SAndroid Build Coastguard Worker isGR32orGR64X86Operand371*9880d681SAndroid Build Coastguard Worker bool isGR32orGR64() const { 372*9880d681SAndroid Build Coastguard Worker return Kind == Register && 373*9880d681SAndroid Build Coastguard Worker (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) || 374*9880d681SAndroid Build Coastguard Worker X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg())); 375*9880d681SAndroid Build Coastguard Worker } 376*9880d681SAndroid Build Coastguard Worker addExprX86Operand377*9880d681SAndroid Build Coastguard Worker void addExpr(MCInst &Inst, const MCExpr *Expr) const { 378*9880d681SAndroid Build Coastguard Worker // Add as immediates when possible. 379*9880d681SAndroid Build Coastguard Worker if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 380*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(CE->getValue())); 381*9880d681SAndroid Build Coastguard Worker else 382*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createExpr(Expr)); 383*9880d681SAndroid Build Coastguard Worker } 384*9880d681SAndroid Build Coastguard Worker addRegOperandsX86Operand385*9880d681SAndroid Build Coastguard Worker void addRegOperands(MCInst &Inst, unsigned N) const { 386*9880d681SAndroid Build Coastguard Worker assert(N == 1 && "Invalid number of operands!"); 387*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(getReg())); 388*9880d681SAndroid Build Coastguard Worker } 389*9880d681SAndroid Build Coastguard Worker getGR32FromGR64X86Operand390*9880d681SAndroid Build Coastguard Worker static unsigned getGR32FromGR64(unsigned RegNo) { 391*9880d681SAndroid Build Coastguard Worker switch (RegNo) { 392*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("Unexpected register"); 393*9880d681SAndroid Build Coastguard Worker case X86::RAX: return X86::EAX; 394*9880d681SAndroid Build Coastguard Worker case X86::RCX: return X86::ECX; 395*9880d681SAndroid Build Coastguard Worker case X86::RDX: return X86::EDX; 396*9880d681SAndroid Build Coastguard Worker case X86::RBX: return X86::EBX; 397*9880d681SAndroid Build Coastguard Worker case X86::RBP: return X86::EBP; 398*9880d681SAndroid Build Coastguard Worker case X86::RSP: return X86::ESP; 399*9880d681SAndroid Build Coastguard Worker case X86::RSI: return X86::ESI; 400*9880d681SAndroid Build Coastguard Worker case X86::RDI: return X86::EDI; 401*9880d681SAndroid Build Coastguard Worker case X86::R8: return X86::R8D; 402*9880d681SAndroid Build Coastguard Worker case X86::R9: return X86::R9D; 403*9880d681SAndroid Build Coastguard Worker case X86::R10: return X86::R10D; 404*9880d681SAndroid Build Coastguard Worker case X86::R11: return X86::R11D; 405*9880d681SAndroid Build Coastguard Worker case X86::R12: return X86::R12D; 406*9880d681SAndroid Build Coastguard Worker case X86::R13: return X86::R13D; 407*9880d681SAndroid Build Coastguard Worker case X86::R14: return X86::R14D; 408*9880d681SAndroid Build Coastguard Worker case X86::R15: return X86::R15D; 409*9880d681SAndroid Build Coastguard Worker case X86::RIP: return X86::EIP; 410*9880d681SAndroid Build Coastguard Worker } 411*9880d681SAndroid Build Coastguard Worker } 412*9880d681SAndroid Build Coastguard Worker addGR32orGR64OperandsX86Operand413*9880d681SAndroid Build Coastguard Worker void addGR32orGR64Operands(MCInst &Inst, unsigned N) const { 414*9880d681SAndroid Build Coastguard Worker assert(N == 1 && "Invalid number of operands!"); 415*9880d681SAndroid Build Coastguard Worker unsigned RegNo = getReg(); 416*9880d681SAndroid Build Coastguard Worker if (X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo)) 417*9880d681SAndroid Build Coastguard Worker RegNo = getGR32FromGR64(RegNo); 418*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(RegNo)); 419*9880d681SAndroid Build Coastguard Worker } addAVX512RCOperandsX86Operand420*9880d681SAndroid Build Coastguard Worker void addAVX512RCOperands(MCInst &Inst, unsigned N) const { 421*9880d681SAndroid Build Coastguard Worker assert(N == 1 && "Invalid number of operands!"); 422*9880d681SAndroid Build Coastguard Worker addExpr(Inst, getImm()); 423*9880d681SAndroid Build Coastguard Worker } addImmOperandsX86Operand424*9880d681SAndroid Build Coastguard Worker void addImmOperands(MCInst &Inst, unsigned N) const { 425*9880d681SAndroid Build Coastguard Worker assert(N == 1 && "Invalid number of operands!"); 426*9880d681SAndroid Build Coastguard Worker addExpr(Inst, getImm()); 427*9880d681SAndroid Build Coastguard Worker } 428*9880d681SAndroid Build Coastguard Worker addMemOperandsX86Operand429*9880d681SAndroid Build Coastguard Worker void addMemOperands(MCInst &Inst, unsigned N) const { 430*9880d681SAndroid Build Coastguard Worker assert((N == 5) && "Invalid number of operands!"); 431*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(getMemBaseReg())); 432*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(getMemScale())); 433*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(getMemIndexReg())); 434*9880d681SAndroid Build Coastguard Worker addExpr(Inst, getMemDisp()); 435*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(getMemSegReg())); 436*9880d681SAndroid Build Coastguard Worker } 437*9880d681SAndroid Build Coastguard Worker addAbsMemOperandsX86Operand438*9880d681SAndroid Build Coastguard Worker void addAbsMemOperands(MCInst &Inst, unsigned N) const { 439*9880d681SAndroid Build Coastguard Worker assert((N == 1) && "Invalid number of operands!"); 440*9880d681SAndroid Build Coastguard Worker // Add as immediates when possible. 441*9880d681SAndroid Build Coastguard Worker if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp())) 442*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(CE->getValue())); 443*9880d681SAndroid Build Coastguard Worker else 444*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createExpr(getMemDisp())); 445*9880d681SAndroid Build Coastguard Worker } 446*9880d681SAndroid Build Coastguard Worker addSrcIdxOperandsX86Operand447*9880d681SAndroid Build Coastguard Worker void addSrcIdxOperands(MCInst &Inst, unsigned N) const { 448*9880d681SAndroid Build Coastguard Worker assert((N == 2) && "Invalid number of operands!"); 449*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(getMemBaseReg())); 450*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(getMemSegReg())); 451*9880d681SAndroid Build Coastguard Worker } addDstIdxOperandsX86Operand452*9880d681SAndroid Build Coastguard Worker void addDstIdxOperands(MCInst &Inst, unsigned N) const { 453*9880d681SAndroid Build Coastguard Worker assert((N == 1) && "Invalid number of operands!"); 454*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(getMemBaseReg())); 455*9880d681SAndroid Build Coastguard Worker } 456*9880d681SAndroid Build Coastguard Worker addMemOffsOperandsX86Operand457*9880d681SAndroid Build Coastguard Worker void addMemOffsOperands(MCInst &Inst, unsigned N) const { 458*9880d681SAndroid Build Coastguard Worker assert((N == 2) && "Invalid number of operands!"); 459*9880d681SAndroid Build Coastguard Worker // Add as immediates when possible. 460*9880d681SAndroid Build Coastguard Worker if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemDisp())) 461*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(CE->getValue())); 462*9880d681SAndroid Build Coastguard Worker else 463*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createExpr(getMemDisp())); 464*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(getMemSegReg())); 465*9880d681SAndroid Build Coastguard Worker } 466*9880d681SAndroid Build Coastguard Worker CreateTokenX86Operand467*9880d681SAndroid Build Coastguard Worker static std::unique_ptr<X86Operand> CreateToken(StringRef Str, SMLoc Loc) { 468*9880d681SAndroid Build Coastguard Worker SMLoc EndLoc = SMLoc::getFromPointer(Loc.getPointer() + Str.size()); 469*9880d681SAndroid Build Coastguard Worker auto Res = llvm::make_unique<X86Operand>(Token, Loc, EndLoc); 470*9880d681SAndroid Build Coastguard Worker Res->Tok.Data = Str.data(); 471*9880d681SAndroid Build Coastguard Worker Res->Tok.Length = Str.size(); 472*9880d681SAndroid Build Coastguard Worker return Res; 473*9880d681SAndroid Build Coastguard Worker } 474*9880d681SAndroid Build Coastguard Worker 475*9880d681SAndroid Build Coastguard Worker static std::unique_ptr<X86Operand> 476*9880d681SAndroid Build Coastguard Worker CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc, 477*9880d681SAndroid Build Coastguard Worker bool AddressOf = false, SMLoc OffsetOfLoc = SMLoc(), 478*9880d681SAndroid Build Coastguard Worker StringRef SymName = StringRef(), void *OpDecl = nullptr) { 479*9880d681SAndroid Build Coastguard Worker auto Res = llvm::make_unique<X86Operand>(Register, StartLoc, EndLoc); 480*9880d681SAndroid Build Coastguard Worker Res->Reg.RegNo = RegNo; 481*9880d681SAndroid Build Coastguard Worker Res->AddressOf = AddressOf; 482*9880d681SAndroid Build Coastguard Worker Res->OffsetOfLoc = OffsetOfLoc; 483*9880d681SAndroid Build Coastguard Worker Res->SymName = SymName; 484*9880d681SAndroid Build Coastguard Worker Res->OpDecl = OpDecl; 485*9880d681SAndroid Build Coastguard Worker return Res; 486*9880d681SAndroid Build Coastguard Worker } 487*9880d681SAndroid Build Coastguard Worker CreateImmX86Operand488*9880d681SAndroid Build Coastguard Worker static std::unique_ptr<X86Operand> CreateImm(const MCExpr *Val, 489*9880d681SAndroid Build Coastguard Worker SMLoc StartLoc, SMLoc EndLoc) { 490*9880d681SAndroid Build Coastguard Worker auto Res = llvm::make_unique<X86Operand>(Immediate, StartLoc, EndLoc); 491*9880d681SAndroid Build Coastguard Worker Res->Imm.Val = Val; 492*9880d681SAndroid Build Coastguard Worker return Res; 493*9880d681SAndroid Build Coastguard Worker } 494*9880d681SAndroid Build Coastguard Worker 495*9880d681SAndroid Build Coastguard Worker /// Create an absolute memory operand. 496*9880d681SAndroid Build Coastguard Worker static std::unique_ptr<X86Operand> 497*9880d681SAndroid Build Coastguard Worker CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, 498*9880d681SAndroid Build Coastguard Worker unsigned Size = 0, StringRef SymName = StringRef(), 499*9880d681SAndroid Build Coastguard Worker void *OpDecl = nullptr) { 500*9880d681SAndroid Build Coastguard Worker auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc); 501*9880d681SAndroid Build Coastguard Worker Res->Mem.SegReg = 0; 502*9880d681SAndroid Build Coastguard Worker Res->Mem.Disp = Disp; 503*9880d681SAndroid Build Coastguard Worker Res->Mem.BaseReg = 0; 504*9880d681SAndroid Build Coastguard Worker Res->Mem.IndexReg = 0; 505*9880d681SAndroid Build Coastguard Worker Res->Mem.Scale = 1; 506*9880d681SAndroid Build Coastguard Worker Res->Mem.Size = Size; 507*9880d681SAndroid Build Coastguard Worker Res->Mem.ModeSize = ModeSize; 508*9880d681SAndroid Build Coastguard Worker Res->SymName = SymName; 509*9880d681SAndroid Build Coastguard Worker Res->OpDecl = OpDecl; 510*9880d681SAndroid Build Coastguard Worker Res->AddressOf = false; 511*9880d681SAndroid Build Coastguard Worker return Res; 512*9880d681SAndroid Build Coastguard Worker } 513*9880d681SAndroid Build Coastguard Worker 514*9880d681SAndroid Build Coastguard Worker /// Create a generalized memory operand. 515*9880d681SAndroid Build Coastguard Worker static std::unique_ptr<X86Operand> 516*9880d681SAndroid Build Coastguard Worker CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp, 517*9880d681SAndroid Build Coastguard Worker unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc, 518*9880d681SAndroid Build Coastguard Worker SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(), 519*9880d681SAndroid Build Coastguard Worker void *OpDecl = nullptr) { 520*9880d681SAndroid Build Coastguard Worker // We should never just have a displacement, that should be parsed as an 521*9880d681SAndroid Build Coastguard Worker // absolute memory operand. 522*9880d681SAndroid Build Coastguard Worker assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!"); 523*9880d681SAndroid Build Coastguard Worker 524*9880d681SAndroid Build Coastguard Worker // The scale should always be one of {1,2,4,8}. 525*9880d681SAndroid Build Coastguard Worker assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) && 526*9880d681SAndroid Build Coastguard Worker "Invalid scale!"); 527*9880d681SAndroid Build Coastguard Worker auto Res = llvm::make_unique<X86Operand>(Memory, StartLoc, EndLoc); 528*9880d681SAndroid Build Coastguard Worker Res->Mem.SegReg = SegReg; 529*9880d681SAndroid Build Coastguard Worker Res->Mem.Disp = Disp; 530*9880d681SAndroid Build Coastguard Worker Res->Mem.BaseReg = BaseReg; 531*9880d681SAndroid Build Coastguard Worker Res->Mem.IndexReg = IndexReg; 532*9880d681SAndroid Build Coastguard Worker Res->Mem.Scale = Scale; 533*9880d681SAndroid Build Coastguard Worker Res->Mem.Size = Size; 534*9880d681SAndroid Build Coastguard Worker Res->Mem.ModeSize = ModeSize; 535*9880d681SAndroid Build Coastguard Worker Res->SymName = SymName; 536*9880d681SAndroid Build Coastguard Worker Res->OpDecl = OpDecl; 537*9880d681SAndroid Build Coastguard Worker Res->AddressOf = false; 538*9880d681SAndroid Build Coastguard Worker return Res; 539*9880d681SAndroid Build Coastguard Worker } 540*9880d681SAndroid Build Coastguard Worker }; 541*9880d681SAndroid Build Coastguard Worker 542*9880d681SAndroid Build Coastguard Worker } // End of namespace llvm 543*9880d681SAndroid Build Coastguard Worker 544*9880d681SAndroid Build Coastguard Worker #endif 545