llvm.org GIT mirror llvm / 71fc42d
[X86] Make the instructions that use AdSize16/32/64 co-exist together without using mode predicates. This is necessary to allow the disassembler to be able to handle AdSize32 instructions in 64-bit mode when address size prefix is used. Eventually we should probably also support 'addr32' and 'addr16' in the assembler to override the address size on some of these instructions. But for now we'll just use special operand types that will lookup the current mode size to select the right instruction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225075 91177308-0d34-0410-b5e6-96231b3b80d8 Craig Topper 4 years ago
9 changed file(s) with 305 addition(s) and 183 deletion(s). Raw diff Collapse all Expand all
260260 int64_t Displacement,
261261 MCContext &Ctx, int64_t *Residue);
262262
263 bool is64BitMode() const {
264 return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
265 }
266 bool is32BitMode() const {
267 return (STI.getFeatureBits() & X86::Mode32Bit) != 0;
268 }
269 bool is16BitMode() const {
270 return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
271 }
272
273 unsigned getPointerWidth() {
274 if (is16BitMode()) return 16;
275 if (is32BitMode()) return 32;
276 if (is64BitMode()) return 64;
277 llvm_unreachable("invalid mode");
278 }
279
263280 // True when previous instruction was actually REP prefix.
264281 bool RepPrefix;
265282
300317 {
301318 const MCExpr *Disp = MCConstantExpr::Create(0, Ctx);
302319 std::unique_ptr Op(X86Operand::CreateMem(
303 0, Disp, SrcReg, 0, AccessSize, SMLoc(), SMLoc()));
320 getPointerWidth(), 0, Disp, SrcReg, 0, AccessSize, SMLoc(), SMLoc()));
304321 InstrumentMemOperand(*Op, AccessSize, false /* IsWrite */, RegCtx, Ctx,
305322 Out);
306323 }
309326 {
310327 const MCExpr *Disp = MCConstantExpr::Create(-1, Ctx);
311328 std::unique_ptr Op(X86Operand::CreateMem(
312 0, Disp, SrcReg, CntReg, AccessSize, SMLoc(), SMLoc()));
329 getPointerWidth(), 0, Disp, SrcReg, CntReg, AccessSize, SMLoc(),
330 SMLoc()));
313331 InstrumentMemOperand(*Op, AccessSize, false /* IsWrite */, RegCtx, Ctx,
314332 Out);
315333 }
318336 {
319337 const MCExpr *Disp = MCConstantExpr::Create(0, Ctx);
320338 std::unique_ptr Op(X86Operand::CreateMem(
321 0, Disp, DstReg, 0, AccessSize, SMLoc(), SMLoc()));
339 getPointerWidth(), 0, Disp, DstReg, 0, AccessSize, SMLoc(), SMLoc()));
322340 InstrumentMemOperand(*Op, AccessSize, true /* IsWrite */, RegCtx, Ctx, Out);
323341 }
324342
326344 {
327345 const MCExpr *Disp = MCConstantExpr::Create(-1, Ctx);
328346 std::unique_ptr Op(X86Operand::CreateMem(
329 0, Disp, DstReg, CntReg, AccessSize, SMLoc(), SMLoc()));
347 getPointerWidth(), 0, Disp, DstReg, CntReg, AccessSize, SMLoc(),
348 SMLoc()));
330349 InstrumentMemOperand(*Op, AccessSize, true /* IsWrite */, RegCtx, Ctx, Out);
331350 }
332351
444463 const MCConstantExpr *Disp =
445464 MCConstantExpr::Create(ApplyDisplacementBounds(Residue), Ctx);
446465 std::unique_ptr DispOp =
447 X86Operand::CreateMem(0, Disp, Reg, 0, 1, SMLoc(), SMLoc());
466 X86Operand::CreateMem(getPointerWidth(), 0, Disp, Reg, 0, 1, SMLoc(),
467 SMLoc());
448468 EmitLEA(*DispOp, VT, Reg, Out);
449469 Residue -= Disp->getValue();
450470 }
458478 if (Displacement == 0 ||
459479 (Op.getMemDisp() && Op.getMemDisp()->getKind() != MCExpr::Constant)) {
460480 *Residue = Displacement;
461 return X86Operand::CreateMem(Op.getMemSegReg(), Op.getMemDisp(),
462 Op.getMemBaseReg(), Op.getMemIndexReg(),
463 Op.getMemScale(), SMLoc(), SMLoc());
481 return X86Operand::CreateMem(Op.getMemModeSize(), Op.getMemSegReg(),
482 Op.getMemDisp(), Op.getMemBaseReg(),
483 Op.getMemIndexReg(), Op.getMemScale(),
484 SMLoc(), SMLoc());
464485 }
465486
466487 int64_t OrigDisplacement =
473494
474495 *Residue = Displacement - NewDisplacement;
475496 const MCExpr *Disp = MCConstantExpr::Create(NewDisplacement, Ctx);
476 return X86Operand::CreateMem(Op.getMemSegReg(), Disp, Op.getMemBaseReg(),
477 Op.getMemIndexReg(), Op.getMemScale(), SMLoc(),
478 SMLoc());
497 return X86Operand::CreateMem(Op.getMemModeSize(), Op.getMemSegReg(), Disp,
498 Op.getMemBaseReg(), Op.getMemIndexReg(),
499 Op.getMemScale(), SMLoc(), SMLoc());
479500 }
480501
481502 class X86AddressSanitizer32 : public X86AddressSanitizer {
624645 Inst.addOperand(MCOperand::CreateReg(ShadowRegI8));
625646 const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
626647 std::unique_ptr Op(
627 X86Operand::CreateMem(0, Disp, ShadowRegI32, 0, 1, SMLoc(), SMLoc()));
648 X86Operand::CreateMem(getPointerWidth(), 0, Disp, ShadowRegI32, 0, 1,
649 SMLoc(), SMLoc()));
628650 Op->addMemOperands(Inst, 5);
629651 EmitInstruction(Out, Inst);
630652 }
648670 case 2: {
649671 const MCExpr *Disp = MCConstantExpr::Create(1, Ctx);
650672 std::unique_ptr Op(
651 X86Operand::CreateMem(0, Disp, ScratchRegI32, 0, 1, SMLoc(), SMLoc()));
673 X86Operand::CreateMem(getPointerWidth(), 0, Disp, ScratchRegI32, 0, 1,
674 SMLoc(), SMLoc()));
652675 EmitLEA(*Op, MVT::i32, ScratchRegI32, Out);
653676 break;
654677 }
703726 }
704727 const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
705728 std::unique_ptr Op(
706 X86Operand::CreateMem(0, Disp, ShadowRegI32, 0, 1, SMLoc(), SMLoc()));
729 X86Operand::CreateMem(getPointerWidth(), 0, Disp, ShadowRegI32, 0, 1,
730 SMLoc(), SMLoc()));
707731 Op->addMemOperands(Inst, 5);
708732 Inst.addOperand(MCOperand::CreateImm(0));
709733 EmitInstruction(Out, Inst);
842866 void EmitAdjustRSP(MCContext &Ctx, MCStreamer &Out, long Offset) {
843867 const MCExpr *Disp = MCConstantExpr::Create(Offset, Ctx);
844868 std::unique_ptr Op(
845 X86Operand::CreateMem(0, Disp, X86::RSP, 0, 1, SMLoc(), SMLoc()));
869 X86Operand::CreateMem(getPointerWidth(), 0, Disp, X86::RSP, 0, 1,
870 SMLoc(), SMLoc()));
846871 EmitLEA(*Op, MVT::i64, X86::RSP, Out);
847872 OrigSPOffset += Offset;
848873 }
895920 Inst.addOperand(MCOperand::CreateReg(ShadowRegI8));
896921 const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
897922 std::unique_ptr Op(
898 X86Operand::CreateMem(0, Disp, ShadowRegI64, 0, 1, SMLoc(), SMLoc()));
923 X86Operand::CreateMem(getPointerWidth(), 0, Disp, ShadowRegI64, 0, 1,
924 SMLoc(), SMLoc()));
899925 Op->addMemOperands(Inst, 5);
900926 EmitInstruction(Out, Inst);
901927 }
919945 case 2: {
920946 const MCExpr *Disp = MCConstantExpr::Create(1, Ctx);
921947 std::unique_ptr Op(
922 X86Operand::CreateMem(0, Disp, ScratchRegI32, 0, 1, SMLoc(), SMLoc()));
948 X86Operand::CreateMem(getPointerWidth(), 0, Disp, ScratchRegI32, 0, 1,
949 SMLoc(), SMLoc()));
923950 EmitLEA(*Op, MVT::i32, ScratchRegI32, Out);
924951 break;
925952 }
9741001 }
9751002 const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx);
9761003 std::unique_ptr Op(
977 X86Operand::CreateMem(0, Disp, ShadowRegI64, 0, 1, SMLoc(), SMLoc()));
1004 X86Operand::CreateMem(getPointerWidth(), 0, Disp, ShadowRegI64, 0, 1,
1005 SMLoc(), SMLoc()));
9781006 Op->addMemOperands(Inst, 5);
9791007 Inst.addOperand(MCOperand::CreateImm(0));
9801008 EmitInstruction(Out, Inst);
710710 uint64_t &ErrorInfo,
711711 bool MatchingInlineAsm);
712712
713 unsigned getPointerSize() {
714 if (is16BitMode()) return 16;
715 if (is32BitMode()) return 32;
716 if (is64BitMode()) return 64;
717 llvm_unreachable("invalid mode");
718 }
719
720713 bool OmitRegisterFromClobberLists(unsigned RegNo) override;
721714
722715 /// doSrcDstMatch - Returns true if operands are matching in their
976969 unsigned basereg =
977970 is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);
978971 const MCExpr *Disp = MCConstantExpr::Create(0, getContext());
979 return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/basereg,
980 /*IndexReg=*/0, /*Scale=*/1, Loc, Loc, 0);
972 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
973 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
974 Loc, Loc, 0);
981975 }
982976
983977 std::unique_ptr X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
984978 unsigned basereg =
985979 is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI);
986980 const MCExpr *Disp = MCConstantExpr::Create(0, getContext());
987 return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/basereg,
988 /*IndexReg=*/0, /*Scale=*/1, Loc, Loc, 0);
981 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
982 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
983 Loc, Loc, 0);
989984 }
990985
991986 std::unique_ptr X86AsmParser::ParseOperand() {
10261021
10271022 // Create an absolute memory reference in order to match against
10281023 // instructions taking a PC relative operand.
1029 return X86Operand::CreateMem(Disp, Start, End, Size, Identifier,
1030 Info.OpDecl);
1024 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size,
1025 Identifier, Info.OpDecl);
10311026 }
10321027
10331028 // We either have a direct symbol reference, or an offset from a symbol. The
10491044 // if we don't know the actual value at this time. This is necessary to
10501045 // get the matching correct in some cases.
10511046 BaseReg = BaseReg ? BaseReg : 1;
1052 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1053 End, Size, Identifier, Info.OpDecl);
1047 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1048 IndexReg, Scale, Start, End, Size, Identifier,
1049 Info.OpDecl);
10541050 }
10551051
10561052 static void
12911287 // handle [-42]
12921288 if (!BaseReg && !IndexReg) {
12931289 if (!SegReg)
1294 return X86Operand::CreateMem(Disp, Start, End, Size);
1295 else
1296 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, Start, End, Size);
1290 return X86Operand::CreateMem(getPointerWidth(), Disp, Start, End, Size);
1291 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1292 Start, End, Size);
12971293 }
12981294 StringRef ErrMsg;
12991295 if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
13001296 Error(StartInBrac, ErrMsg);
13011297 return nullptr;
13021298 }
1303 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
1304 End, Size);
1299 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1300 IndexReg, Scale, Start, End, Size);
13051301 }
13061302
13071303 InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo();
13821378 // be followed by a bracketed expression. If it isn't we know we have our
13831379 // final segment override.
13841380 const MCExpr *Disp = MCConstantExpr::Create(ImmDisp, getContext());
1385 return X86Operand::CreateMem(SegReg, Disp, /*BaseReg=*/0, /*IndexReg=*/0,
1386 /*Scale=*/1, Start, ImmDispToken.getEndLoc(),
1387 Size);
1381 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
1382 /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1,
1383 Start, ImmDispToken.getEndLoc(), Size);
13881384 }
13891385 }
13901386
13971393 if (getParser().parsePrimaryExpr(Val, End))
13981394 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
13991395
1400 return X86Operand::CreateMem(Val, Start, End, Size);
1396 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
14011397 }
14021398
14031399 InlineAsmIdentifierInfo Info;
14271423 if (getParser().parsePrimaryExpr(Val, End))
14281424 return ErrorOperand(Tok.getLoc(), "unknown token in expression");
14291425
1430 return X86Operand::CreateMem(Val, Start, End, Size);
1426 return X86Operand::CreateMem(getPointerWidth(), Val, Start, End, Size);
14311427 }
14321428
14331429 InlineAsmIdentifierInfo Info;
14651461 // BaseReg is non-zero to avoid assertions. In the context of inline asm,
14661462 // we're pointing to a local variable in memory, so the base register is
14671463 // really the frame or stack pointer.
1468 return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/1, /*IndexReg=*/0,
1469 /*Scale=*/1, Start, End, Size, Identifier,
1470 Info.OpDecl);
1464 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
1465 /*BaseReg=*/1, /*IndexReg=*/0, /*Scale=*/1,
1466 Start, End, Size, Identifier, Info.OpDecl);
14711467 }
14721468
14731469 /// Parse the '.' operator.
16421638 // to the MCExpr with the directional local symbol and this is a
16431639 // memory operand not an immediate operand.
16441640 if (SM.getSym())
1645 return X86Operand::CreateMem(SM.getSym(), Start, End, Size);
1641 return X86Operand::CreateMem(getPointerWidth(), SM.getSym(), Start, End,
1642 Size);
16461643
16471644 const MCExpr *ImmExpr = MCConstantExpr::Create(Imm, getContext());
16481645 return X86Operand::CreateImm(ImmExpr, Start, End);
18011798 if (getLexer().isNot(AsmToken::LParen)) {
18021799 // Unless we have a segment register, treat this as an immediate.
18031800 if (SegReg == 0)
1804 return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
1805 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
1801 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, ExprEnd);
1802 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1803 MemStart, ExprEnd);
18061804 }
18071805
18081806 // Eat the '('.
18281826 if (getLexer().isNot(AsmToken::LParen)) {
18291827 // Unless we have a segment register, treat this as an immediate.
18301828 if (SegReg == 0)
1831 return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
1832 return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
1829 return X86Operand::CreateMem(getPointerWidth(), Disp, LParenLoc,
1830 ExprEnd);
1831 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, 0, 0, 1,
1832 MemStart, ExprEnd);
18331833 }
18341834
18351835 // Eat the '('.
19451945 }
19461946
19471947 if (SegReg || BaseReg || IndexReg)
1948 return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
1949 MemStart, MemEnd);
1950 return X86Operand::CreateMem(Disp, MemStart, MemEnd);
1948 return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
1949 IndexReg, Scale, MemStart, MemEnd);
1950 return X86Operand::CreateMem(getPointerWidth(), Disp, MemStart, MemEnd);
19511951 }
19521952
19531953 bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
26132613 static const char *const PtrSizedInstrs[] = {"call", "jmp", "push"};
26142614 for (const char *Instr : PtrSizedInstrs) {
26152615 if (Mnemonic == Instr) {
2616 UnsizedMemOp->Mem.Size = getPointerSize();
2616 UnsizedMemOp->Mem.Size = getPointerWidth();
26172617 break;
26182618 }
26192619 }
5252 unsigned IndexReg;
5353 unsigned Scale;
5454 unsigned Size;
55 unsigned ModeSize;
5556 };
5657
5758 union {
119120 assert(Kind == Memory && "Invalid access!");
120121 return Mem.Scale;
121122 }
123 unsigned getMemModeSize() const {
124 assert(Kind == Memory && "Invalid access!");
125 return Mem.ModeSize;
126 }
122127
123128 bool isToken() const override {return Kind == Token; }
124129
287292 return isMem64() && isDstIdx();
288293 }
289294
290 bool isMemOffs8() const {
291 return Kind == Memory && !getMemBaseReg() &&
292 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 8);
293 }
294 bool isMemOffs16() const {
295 return Kind == Memory && !getMemBaseReg() &&
296 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 16);
297 }
298 bool isMemOffs32() const {
299 return Kind == Memory && !getMemBaseReg() &&
300 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 32);
301 }
302 bool isMemOffs64() const {
303 return Kind == Memory && !getMemBaseReg() &&
304 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 64);
295 bool isMemOffs() const {
296 return Kind == Memory && !getMemBaseReg() && !getMemIndexReg() &&
297 getMemScale() == 1;
298 }
299
300 bool isMemOffs16_8() const {
301 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 8);
302 }
303 bool isMemOffs16_16() const {
304 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 16);
305 }
306 bool isMemOffs16_32() const {
307 return isMemOffs() && Mem.ModeSize == 16 && (!Mem.Size || Mem.Size == 32);
308 }
309 bool isMemOffs32_8() const {
310 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 8);
311 }
312 bool isMemOffs32_16() const {
313 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 16);
314 }
315 bool isMemOffs32_32() const {
316 return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
317 }
318 bool isMemOffs64_8() const {
319 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
320 }
321 bool isMemOffs64_16() const {
322 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 16);
323 }
324 bool isMemOffs64_32() const {
325 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 32);
326 }
327 bool isMemOffs64_64() const {
328 return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 64);
305329 }
306330
307331 bool isReg() const override { return Kind == Register; }
429453
430454 /// Create an absolute memory operand.
431455 static std::unique_ptr
432 CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size = 0,
433 StringRef SymName = StringRef(), void *OpDecl = nullptr) {
456 CreateMem(unsigned ModeSize, const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc,
457 unsigned Size = 0, StringRef SymName = StringRef(),
458 void *OpDecl = nullptr) {
434459 auto Res = llvm::make_unique(Memory, StartLoc, EndLoc);
435460 Res->Mem.SegReg = 0;
436461 Res->Mem.Disp = Disp;
438463 Res->Mem.IndexReg = 0;
439464 Res->Mem.Scale = 1;
440465 Res->Mem.Size = Size;
466 Res->Mem.ModeSize = ModeSize;
441467 Res->SymName = SymName;
442468 Res->OpDecl = OpDecl;
443469 Res->AddressOf = false;
446472
447473 /// Create a generalized memory operand.
448474 static std::unique_ptr
449 CreateMem(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg,
450 unsigned IndexReg, unsigned Scale, SMLoc StartLoc, SMLoc EndLoc,
451 unsigned Size = 0, StringRef SymName = StringRef(),
475 CreateMem(unsigned ModeSize, unsigned SegReg, const MCExpr *Disp,
476 unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc,
477 SMLoc EndLoc, unsigned Size = 0, StringRef SymName = StringRef(),
452478 void *OpDecl = nullptr) {
453479 // We should never just have a displacement, that should be parsed as an
454480 // absolute memory operand.
464490 Res->Mem.IndexReg = IndexReg;
465491 Res->Mem.Scale = Scale;
466492 Res->Mem.Size = Size;
493 Res->Mem.ModeSize = ModeSize;
467494 Res->SymName = SymName;
468495 Res->OpDecl = OpDecl;
469496 Res->AddressOf = false;
105105 // jecxz.
106106 let Uses = [CX] in
107107 def JCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
108 "jcxz\t$dst", [], IIC_JCXZ>, AdSize16, Requires<[Not64BitMode]>;
108 "jcxz\t$dst", [], IIC_JCXZ>, AdSize16;
109109 let Uses = [ECX] in
110 def JECXZ_32 : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
111 "jecxz\t$dst", [], IIC_JCXZ>, AdSize32, Requires<[Not64BitMode]>;
112
113 // J*CXZ instruction: 64-bit versions of this instruction for the asmparser.
114 // In 64-bit mode, the address size prefix is jecxz and the unprefixed version
115 // is jrcxz.
116 let Uses = [ECX] in
117 def JECXZ_64 : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
118 "jecxz\t$dst", [], IIC_JCXZ>, AdSize32, Requires<[In64BitMode]>;
110 def JECXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
111 "jecxz\t$dst", [], IIC_JCXZ>, AdSize32;
112
119113 let Uses = [RCX] in
120114 def JRCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
121 "jrcxz\t$dst", [], IIC_JCXZ>, AdSize64, Requires<[In64BitMode]>;
115 "jrcxz\t$dst", [], IIC_JCXZ>, AdSize64;
122116 }
123117
124118 // Indirect branches
463463 let RenderMethod = "addDstIdxOperands";
464464 let SuperClasses = [X86Mem64AsmOperand];
465465 }
466 def X86MemOffs8AsmOperand : AsmOperandClass {
467 let Name = "MemOffs8";
466 def X86MemOffs16_8AsmOperand : AsmOperandClass {
467 let Name = "MemOffs16_8";
468468 let RenderMethod = "addMemOffsOperands";
469469 let SuperClasses = [X86Mem8AsmOperand];
470470 }
471 def X86MemOffs16AsmOperand : AsmOperandClass {
472 let Name = "MemOffs16";
471 def X86MemOffs16_16AsmOperand : AsmOperandClass {
472 let Name = "MemOffs16_16";
473473 let RenderMethod = "addMemOffsOperands";
474474 let SuperClasses = [X86Mem16AsmOperand];
475475 }
476 def X86MemOffs32AsmOperand : AsmOperandClass {
477 let Name = "MemOffs32";
476 def X86MemOffs16_32AsmOperand : AsmOperandClass {
477 let Name = "MemOffs16_32";
478478 let RenderMethod = "addMemOffsOperands";
479479 let SuperClasses = [X86Mem32AsmOperand];
480480 }
481 def X86MemOffs64AsmOperand : AsmOperandClass {
482 let Name = "MemOffs64";
481 def X86MemOffs32_8AsmOperand : AsmOperandClass {
482 let Name = "MemOffs32_8";
483 let RenderMethod = "addMemOffsOperands";
484 let SuperClasses = [X86Mem8AsmOperand];
485 }
486 def X86MemOffs32_16AsmOperand : AsmOperandClass {
487 let Name = "MemOffs32_16";
488 let RenderMethod = "addMemOffsOperands";
489 let SuperClasses = [X86Mem16AsmOperand];
490 }
491 def X86MemOffs32_32AsmOperand : AsmOperandClass {
492 let Name = "MemOffs32_32";
493 let RenderMethod = "addMemOffsOperands";
494 let SuperClasses = [X86Mem32AsmOperand];
495 }
496 def X86MemOffs64_8AsmOperand : AsmOperandClass {
497 let Name = "MemOffs64_8";
498 let RenderMethod = "addMemOffsOperands";
499 let SuperClasses = [X86Mem8AsmOperand];
500 }
501 def X86MemOffs64_16AsmOperand : AsmOperandClass {
502 let Name = "MemOffs64_16";
503 let RenderMethod = "addMemOffsOperands";
504 let SuperClasses = [X86Mem16AsmOperand];
505 }
506 def X86MemOffs64_32AsmOperand : AsmOperandClass {
507 let Name = "MemOffs64_32";
508 let RenderMethod = "addMemOffsOperands";
509 let SuperClasses = [X86Mem32AsmOperand];
510 }
511 def X86MemOffs64_64AsmOperand : AsmOperandClass {
512 let Name = "MemOffs64_64";
483513 let RenderMethod = "addMemOffsOperands";
484514 let SuperClasses = [X86Mem64AsmOperand];
485515 }
516546 let ParserMatchClass = X86DstIdx64Operand;
517547 let MIOperandInfo = (ops ptr_rc);
518548 let PrintMethod = "printDstIdx64"; }
519 def offset8 : Operand {
520 let ParserMatchClass = X86MemOffs8AsmOperand;
549 def offset16_8 : Operand {
550 let ParserMatchClass = X86MemOffs16_8AsmOperand;
521551 let MIOperandInfo = (ops i64imm, i8imm);
522552 let PrintMethod = "printMemOffs8"; }
523 def offset16 : Operand {
524 let ParserMatchClass = X86MemOffs16AsmOperand;
553 def offset16_16 : Operand {
554 let ParserMatchClass = X86MemOffs16_16AsmOperand;
525555 let MIOperandInfo = (ops i64imm, i8imm);
526556 let PrintMethod = "printMemOffs16"; }
527 def offset32 : Operand {
528 let ParserMatchClass = X86MemOffs32AsmOperand;
557 def offset16_32 : Operand {
558 let ParserMatchClass = X86MemOffs16_32AsmOperand;
529559 let MIOperandInfo = (ops i64imm, i8imm);
530560 let PrintMethod = "printMemOffs32"; }
531 def offset64 : Operand {
532 let ParserMatchClass = X86MemOffs64AsmOperand;
561 def offset32_8 : Operand {
562 let ParserMatchClass = X86MemOffs32_8AsmOperand;
563 let MIOperandInfo = (ops i64imm, i8imm);
564 let PrintMethod = "printMemOffs8"; }
565 def offset32_16 : Operand {
566 let ParserMatchClass = X86MemOffs32_16AsmOperand;
567 let MIOperandInfo = (ops i64imm, i8imm);
568 let PrintMethod = "printMemOffs16"; }
569 def offset32_32 : Operand {
570 let ParserMatchClass = X86MemOffs32_32AsmOperand;
571 let MIOperandInfo = (ops i64imm, i8imm);
572 let PrintMethod = "printMemOffs32"; }
573 def offset64_8 : Operand {
574 let ParserMatchClass = X86MemOffs64_8AsmOperand;
575 let MIOperandInfo = (ops i64imm, i8imm);
576 let PrintMethod = "printMemOffs8"; }
577 def offset64_16 : Operand {
578 let ParserMatchClass = X86MemOffs64_16AsmOperand;
579 let MIOperandInfo = (ops i64imm, i8imm);
580 let PrintMethod = "printMemOffs16"; }
581 def offset64_32 : Operand {
582 let ParserMatchClass = X86MemOffs64_32AsmOperand;
583 let MIOperandInfo = (ops i64imm, i8imm);
584 let PrintMethod = "printMemOffs32"; }
585 def offset64_64 : Operand {
586 let ParserMatchClass = X86MemOffs64_64AsmOperand;
533587 let MIOperandInfo = (ops i64imm, i8imm);
534588 let PrintMethod = "printMemOffs64"; }
535589 }
12521306 let SchedRW = [WriteALU] in {
12531307 let mayLoad = 1 in {
12541308 let Defs = [AL] in
1255 def MOV8o8a : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset8:$src),
1309 def MOV8o8a : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
12561310 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1257 AdSize32, Requires<[In32BitMode]>;
1311 AdSize32;
12581312 let Defs = [AX] in
1259 def MOV16o16a : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset16:$src),
1313 def MOV16o16a : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
12601314 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1261 OpSize16, AdSize32, Requires<[In32BitMode]>;
1315 OpSize16, AdSize32;
12621316 let Defs = [EAX] in
1263 def MOV32o32a : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32:$src),
1317 def MOV32o32a : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
12641318 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1265 OpSize32, AdSize32, Requires<[In32BitMode]>;
1319 OpSize32, AdSize32;
12661320
12671321 let Defs = [AL] in
1268 def MOV8o8a_16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset8:$src),
1322 def MOV8o8a_16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
12691323 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1270 AdSize16, Requires<[In16BitMode]>;
1324 AdSize16;
12711325 let Defs = [AX] in
1272 def MOV16o16a_16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16:$src),
1326 def MOV16o16a_16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
12731327 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1274 OpSize16, AdSize16, Requires<[In16BitMode]>;
1328 OpSize16, AdSize16;
12751329 let Defs = [EAX] in
1276 def MOV32o32a_16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset32:$src),
1330 def MOV32o32a_16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
12771331 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1278 AdSize16, OpSize32, Requires<[In16BitMode]>;
1332 AdSize16, OpSize32;
12791333 }
12801334 let mayStore = 1 in {
12811335 let Uses = [AL] in
1282 def MOV8ao8 : Ii32<0xA2, RawFrmMemOffs, (outs offset8:$dst), (ins),
1336 def MOV8ao8 : Ii32<0xA2, RawFrmMemOffs, (outs offset32_8:$dst), (ins),
12831337 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>,
1284 AdSize32, Requires<[In32BitMode]>;
1338 AdSize32;
12851339 let Uses = [AX] in
1286 def MOV16ao16 : Ii32<0xA3, RawFrmMemOffs, (outs offset16:$dst), (ins),
1340 def MOV16ao16 : Ii32<0xA3, RawFrmMemOffs, (outs offset32_16:$dst), (ins),
12871341 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1288 OpSize16, AdSize32, Requires<[In32BitMode]>;
1342 OpSize16, AdSize32;
12891343 let Uses = [EAX] in
1290 def MOV32ao32 : Ii32<0xA3, RawFrmMemOffs, (outs offset32:$dst), (ins),
1344 def MOV32ao32 : Ii32<0xA3, RawFrmMemOffs, (outs offset32_32:$dst), (ins),
12911345 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1292 OpSize32, AdSize32, Requires<[In32BitMode]>;
1346 OpSize32, AdSize32;
12931347
12941348 let Uses = [AL] in
1295 def MOV8ao8_16 : Ii16<0xA2, RawFrmMemOffs, (outs offset8:$dst), (ins),
1349 def MOV8ao8_16 : Ii16<0xA2, RawFrmMemOffs, (outs offset16_8:$dst), (ins),
12961350 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>,
1297 AdSize16, Requires<[In16BitMode]>;
1351 AdSize16;
12981352 let Uses = [AX] in
1299 def MOV16ao16_16 : Ii16<0xA3, RawFrmMemOffs, (outs offset16:$dst), (ins),
1353 def MOV16ao16_16 : Ii16<0xA3, RawFrmMemOffs, (outs offset16_16:$dst), (ins),
13001354 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1301 OpSize16, AdSize16, Requires<[In16BitMode]>;
1355 OpSize16, AdSize16;
13021356 let Uses = [EAX] in
1303 def MOV32ao32_16 : Ii16<0xA3, RawFrmMemOffs, (outs offset32:$dst), (ins),
1357 def MOV32ao32_16 : Ii16<0xA3, RawFrmMemOffs, (outs offset16_32:$dst), (ins),
13041358 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1305 OpSize32, AdSize16, Requires<[In16BitMode]>;
1359 OpSize32, AdSize16;
13061360 }
13071361 }
13081362
13101364 // and use the movabs mnemonic to indicate this specific form.
13111365 let mayLoad = 1 in {
13121366 let Defs = [AL] in
1313 def MOV64o8a : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset8:$src),
1314 "movabs{b}\t{$src, %al|al, $src}", []>,
1315 AdSize64, Requires<[In64BitMode]>;
1367 def MOV64o8a : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
1368 "movabs{b}\t{$src, %al|al, $src}", []>, AdSize64;
13161369 let Defs = [AX] in
1317 def MOV64o16a : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset16:$src),
1318 "movabs{w}\t{$src, %ax|ax, $src}", []>, OpSize16,
1319 AdSize64, Requires<[In64BitMode]>;
1370 def MOV64o16a : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
1371 "movabs{w}\t{$src, %ax|ax, $src}", []>, OpSize16, AdSize64;
13201372 let Defs = [EAX] in
1321 def MOV64o32a : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset32:$src),
1373 def MOV64o32a : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
13221374 "movabs{l}\t{$src, %eax|eax, $src}", []>, OpSize32,
1323 AdSize64, Requires<[In64BitMode]>;
1375 AdSize64;
13241376 let Defs = [RAX] in
1325 def MOV64o64a : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64:$src),
1326 "movabs{q}\t{$src, %rax|rax, $src}", []>,
1327 AdSize64, Requires<[In64BitMode]>;
1377 def MOV64o64a : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
1378 "movabs{q}\t{$src, %rax|rax, $src}", []>, AdSize64;
13281379 }
13291380
13301381 let mayStore = 1 in {
13311382 let Uses = [AL] in
1332 def MOV64ao8 : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs offset8:$dst), (ins),
1333 "movabs{b}\t{%al, $dst|$dst, al}", []>,
1334 AdSize64, Requires<[In64BitMode]>;
1383 def MOV64ao8 : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs offset64_8:$dst), (ins),
1384 "movabs{b}\t{%al, $dst|$dst, al}", []>, AdSize64;
13351385 let Uses = [AX] in
1336 def MOV64ao16 : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset16:$dst), (ins),
1337 "movabs{w}\t{%ax, $dst|$dst, ax}", []>, OpSize16,
1338 AdSize64, Requires<[In64BitMode]>;
1386 def MOV64ao16 : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset64_16:$dst), (ins),
1387 "movabs{w}\t{%ax, $dst|$dst, ax}", []>, OpSize16, AdSize64;
13391388 let Uses = [EAX] in
1340 def MOV64ao32 : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset32:$dst), (ins),
1389 def MOV64ao32 : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset64_32:$dst), (ins),
13411390 "movabs{l}\t{%eax, $dst|$dst, eax}", []>, OpSize32,
1342 AdSize64, Requires<[In64BitMode]>;
1391 AdSize64;
13431392 let Uses = [RAX] in
1344 def MOV64ao64 : RIi64<0xA3, RawFrmMemOffs, (outs offset64:$dst), (ins),
1345 "movabs{q}\t{%rax, $dst|$dst, rax}", []>,
1346 AdSize64, Requires<[In64BitMode]>;
1393 def MOV64ao64 : RIi64<0xA3, RawFrmMemOffs, (outs offset64_64:$dst), (ins),
1394 "movabs{q}\t{%rax, $dst|$dst, rax}", []>, AdSize64;
13471395 }
13481396 } // hasSideEffects = 0
13491397
33
44 # 16: movb 0x5a5a, %al # encoding: [0xa0,0x5a,0x5a]
55 # 32: movb 0x5a5a5a5a, %al # encoding: [0xa0,0x5a,0x5a,0x5a,0x5a]
6 # 64: movabsb 0x5a5a5a5a5a5a5a5a, %al
6 # 64: movabsb 0x5a5a5a5a5a5a5a5a, %al # encoding: [0xa0,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a]
77 0xa0 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
88
99 # 16: movb 0x5a5a5a5a, %al # encoding: [0x67,0xa0,0x5a,0x5a,0x5a,0x5a]
1010 # 32: movb 0x5a5a, %al # encoding: [0x67,0xa0,0x5a,0x5a]
11 # 64: movabsb 0x5a5a5a5a, %al
11 # 64: movb 0x5a5a5a5a, %al # encoding: [0x67,0xa0,0x5a,0x5a,0x5a,0x5a]
1212 0x67 0xa0 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
1313
1414 # 16: movw 0x5a5a, %ax # encoding: [0xa1,0x5a,0x5a]
1515 # 32: movl 0x5a5a5a5a, %eax # encoding: [0xa1,0x5a,0x5a,0x5a,0x5a]
16 # 64: movabsl 0x5a5a5a5a5a5a5a5a, %eax
16 # 64: movabsl 0x5a5a5a5a5a5a5a5a, %eax # encoding: [0xa1,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a]
1717 0xa1 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
1818
1919 # 16: movw 0x5a5a5a5a, %ax # encoding: [0x67,0xa1,0x5a,0x5a,0x5a,0x5a]
2020 # 32: movl 0x5a5a, %eax # encoding: [0x67,0xa1,0x5a,0x5a]
21 # 64: movabsl 0x5a5a5a5a, %eax
21 # 64: movl 0x5a5a5a5a, %eax # encoding: [0x67,0xa1,0x5a,0x5a,0x5a,0x5a]
2222 0x67 0xa1 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
2323
2424 # 16: movl 0x5a5a, %eax # encoding: [0x66,0xa1,0x5a,0x5a]
2525 # 32: movw 0x5a5a5a5a, %ax # encoding: [0x66,0xa1,0x5a,0x5a,0x5a,0x5a]
26 # 64: movabsw 0x5a5a5a5a5a5a5a5a, %ax
26 # 64: movabsw 0x5a5a5a5a5a5a5a5a, %ax # encoding: [0x66,0xa1,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a]
2727 0x66 0xa1 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
2828
2929 # 16: movl 0x5a5a5a5a, %eax # encoding: [0x67,0x66,0xa1,0x5a,0x5a,0x5a,0x5a]
3030 # 32: movw 0x5a5a, %ax # encoding: [0x67,0x66,0xa1,0x5a,0x5a]
31 # 64: movabsw 0x5a5a5a5a, %ax
31 # 64: movw 0x5a5a5a5a, %ax # encoding: [0x67,0x66,0xa1,0x5a,0x5a,0x5a,0x5a]
3232 0x66 0x67 0xa1 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
3333
3434 # 16: movl 0x5a5a5a5a, %eax # encoding: [0x67,0x66,0xa1,0x5a,0x5a,0x5a,0x5a]
3535 # 32: movw 0x5a5a, %ax # encoding: [0x67,0x66,0xa1,0x5a,0x5a]
36 # 64: movabsw 0x5a5a5a5a, %ax
36 # 64: movw 0x5a5a5a5a, %ax # encoding: [0x67,0x66,0xa1,0x5a,0x5a,0x5a,0x5a]
3737 0x67 0x66 0xa1 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
3838
3939 # 16: movl %es:0x5a5a5a5a, %eax # encoding: [0x67,0x66,0x26,0xa1,0x5a,0x5a,0x5a,0x5a]
4040 # 32: movw %es:0x5a5a, %ax # encoding: [0x67,0x66,0x26,0xa1,0x5a,0x5a]
41 # 64: movabsw %es:0x5a5a5a5a, %ax
41 # 64: movw %es:0x5a5a5a5a, %ax # encoding: [0x67,0x66,0x26,0xa1,0x5a,0x5a,0x5a,0x5a]
4242 0x67 0x26 0x66 0xa1 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a # encoding: [0xa0,0x5a,0x5a]
4343
4444
4545
4646 # 16: movb %al, 0x5a5a # encoding: [0xa2,0x5a,0x5a]
4747 # 32: movb %al, 0x5a5a5a5a # encoding: [0xa2,0x5a,0x5a,0x5a,0x5a]
48 # 64: movabsb %al, 0x5a5a5a5a5a5a5a5a
48 # 64: movabsb %al, 0x5a5a5a5a5a5a5a5a # encoding: [0xa2,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a]
4949 0xa2 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a # encoding: [0xa0,0x5a,0x5a]
5050
5151 # 16: movb %al, 0x5a5a5a5a # encoding: [0x67,0xa2,0x5a,0x5a,0x5a,0x5a]
5252 # 32: movb %al, 0x5a5a # encoding: [0x67,0xa2,0x5a,0x5a]
53 # 64: movabsb %al, 0x5a5a5a5a
53 # 64: movb %al, 0x5a5a5a5a # encoding: [0x67,0xa2,0x5a,0x5a,0x5a,0x5a]
5454 0x67 0xa2 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
5555
5656 # 16: movw %ax, 0x5a5a # encoding: [0xa3,0x5a,0x5a]
5757 # 32: movl %eax, 0x5a5a5a5a # encoding: [0xa3,0x5a,0x5a,0x5a,0x5a]
58 # 64: movabsl %eax, 0x5a5a5a5a5a5a5a5a
58 # 64: movabsl %eax, 0x5a5a5a5a5a5a5a5a # encoding: [0xa3,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a]
5959 0xa3 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
6060
6161 # 16: movw %ax, %gs:0x5a5a5a5a # encoding: [0x67,0x65,0xa3,0x5a,0x5a,0x5a,0x5a]
6262 # 32: movl %eax, %gs:0x5a5a # encoding: [0x67,0x65,0xa3,0x5a,0x5a]
63 # 64: movabsl %eax, %gs:0x5a5a5a5a
63 # 64: movl %eax, %gs:0x5a5a5a5a # encoding: [0x67,0x65,0xa3,0x5a,0x5a,0x5a,0x5a]
6464 0x65 0x67 0xa3 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
6565
6666 # 16: movl %eax, 0x5a5a # encoding: [0x66,0xa3,0x5a,0x5a]
6767 # 32: movw %ax, 0x5a5a5a5a # encoding: [0x66,0xa3,0x5a,0x5a,0x5a,0x5a]
68 # 64: movabsw %ax, 0x5a5a5a5a5a5a5a5a
68 # 64: movabsw %ax, 0x5a5a5a5a5a5a5a5a # encoding: [0x66,0xa3,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a,0x5a]
6969 0x66 0xa3 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
7070
7171 # 16: movl %eax, 0x5a5a5a5a # encoding: [0x67,0x66,0xa3,0x5a,0x5a,0x5a,0x5a]
7272 # 32: movw %ax, 0x5a5a # encoding: [0x67,0x66,0xa3,0x5a,0x5a]
73 # 64: movabsw %ax, 0x5a5a5a5a
73 # 64: movw %ax, 0x5a5a5a5a # encoding: [0x67,0x66,0xa3,0x5a,0x5a,0x5a,0x5a]
7474 0x66 0x67 0xa3 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
7575
7676 # 16: movl %eax, 0x5a5a5a5a # encoding: [0x67,0x66,0xa3,0x5a,0x5a,0x5a,0x5a]
7777 # 32: movw %ax, 0x5a5a # encoding: [0x67,0x66,0xa3,0x5a,0x5a]
78 # 64: movabsw %ax, 0x5a5a5a5a
78 # 64: movw %ax, 0x5a5a5a5a # encoding: [0x67,0x66,0xa3,0x5a,0x5a,0x5a,0x5a]
7979 0x67 0x66 0xa3 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
8080
8181 # 16: movl %eax, %es:0x5a5a5a5a # encoding: [0x67,0x66,0x26,0xa3,0x5a,0x5a,0x5a,0x5a]
8282 # 32: movw %ax, %es:0x5a5a # encoding: [0x67,0x66,0x26,0xa3,0x5a,0x5a]
83 # 64: movabsw %ax, %es:0x5a5a5a5a
83 # 64: movw %ax, %es:0x5a5a5a5a # encoding: [0x67,0x66,0x26,0xa3,0x5a,0x5a,0x5a,0x5a]
8484 0x67 0x26 0x66 0xa3 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
8585
7474 /// @return - True if child is a subset of parent, false otherwise.
7575 static inline bool inheritsFrom(InstructionContext child,
7676 InstructionContext parent,
77 bool VEX_LIG = false) {
77 bool VEX_LIG = false, bool AdSize64 = false) {
7878 if (child == parent)
7979 return true;
8080
8181 switch (parent) {
8282 case IC:
83 return(inheritsFrom(child, IC_64BIT) ||
83 return(inheritsFrom(child, IC_64BIT, AdSize64) ||
8484 inheritsFrom(child, IC_OPSIZE) ||
8585 inheritsFrom(child, IC_ADSIZE) ||
8686 inheritsFrom(child, IC_XD) ||
8888 case IC_64BIT:
8989 return(inheritsFrom(child, IC_64BIT_REXW) ||
9090 inheritsFrom(child, IC_64BIT_OPSIZE) ||
91 inheritsFrom(child, IC_64BIT_ADSIZE) ||
91 (!AdSize64 && inheritsFrom(child, IC_64BIT_ADSIZE)) ||
9292 inheritsFrom(child, IC_64BIT_XD) ||
9393 inheritsFrom(child, IC_64BIT_XS));
9494 case IC_OPSIZE:
116116 inheritsFrom(child, IC_64BIT_REXW_OPSIZE));
117117 case IC_64BIT_OPSIZE:
118118 return inheritsFrom(child, IC_64BIT_REXW_OPSIZE) ||
119 inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE);
119 (!AdSize64 && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE));
120120 case IC_64BIT_XD:
121121 return(inheritsFrom(child, IC_64BIT_REXW_XD));
122122 case IC_64BIT_XS:
864864 const ModRMFilter &filter,
865865 InstrUID uid,
866866 bool is32bit,
867 bool ignoresVEX_L) {
867 bool ignoresVEX_L,
868 unsigned addressSize) {
868869 ContextDecision &decision = *Tables[type];
869870
870871 for (unsigned index = 0; index < IC_max; ++index) {
871 if (is32bit && inheritsFrom((InstructionContext)index, IC_64BIT))
872 if ((is32bit || addressSize == 16) &&
873 inheritsFrom((InstructionContext)index, IC_64BIT))
872874 continue;
873875
876 bool adSize64 = addressSize == 64;
874877 if (inheritsFrom((InstructionContext)index,
875 InstructionSpecifiers[uid].insnContext, ignoresVEX_L))
878 InstructionSpecifiers[uid].insnContext, ignoresVEX_L,
879 adSize64))
876880 setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode],
877881 filter,
878882 uid,
244244 /// @param uid - The unique ID of the instruction.
245245 /// @param is32bit - Instructon is only 32-bit
246246 /// @param ignoresVEX_L - Instruction ignores VEX.L
247 /// @param AddrSize - Instructions address size 16/32/64. 0 is unspecified
247248 void setTableFields(OpcodeType type,
248249 InstructionContext insnContext,
249250 uint8_t opcode,
250251 const ModRMFilter &filter,
251252 InstrUID uid,
252253 bool is32bit,
253 bool ignoresVEX_L);
254 bool ignoresVEX_L,
255 unsigned AddrSize);
254256
255257 /// specForUID - Returns the instruction specifier for a given unique
256258 /// instruction ID. Used when resolving collisions.
404404 errs() << "Instruction does not use a prefix: " << Name << "\n";
405405 llvm_unreachable("Invalid prefix");
406406 }
407 } else if (Is64Bit || HasREX_WPrefix) {
407 } else if (Is64Bit || HasREX_WPrefix || AdSize == X86Local::AdSize64) {
408408 if (HasREX_WPrefix && (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD))
409409 insnContext = IC_64BIT_REXW_OPSIZE;
410410 else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD)
857857 break;
858858 } // switch (OpMap)
859859
860 unsigned AddressSize = 0;
861 switch (AdSize) {
862 case X86Local::AdSize16: AddressSize = 16; break;
863 case X86Local::AdSize32: AddressSize = 32; break;
864 case X86Local::AdSize64: AddressSize = 64; break;
865 }
866
860867 assert(opcodeType != (OpcodeType)-1 &&
861868 "Opcode type not set");
862869 assert(filter && "Filter not set");
874881 insnContext(),
875882 currentOpcode,
876883 *filter,
877 UID, Is32Bit, IgnoresVEX_L);
884 UID, Is32Bit, IgnoresVEX_L, AddressSize);
878885 } else {
879886 tables.setTableFields(opcodeType,
880887 insnContext(),
881888 opcodeToSet,
882889 *filter,
883 UID, Is32Bit, IgnoresVEX_L);
890 UID, Is32Bit, IgnoresVEX_L, AddressSize);
884891 }
885892
886893 delete filter;
970977 TYPE("dstidx16", TYPE_DSTIDX16)
971978 TYPE("dstidx32", TYPE_DSTIDX32)
972979 TYPE("dstidx64", TYPE_DSTIDX64)
973 TYPE("offset8", TYPE_MOFFS8)
974 TYPE("offset16", TYPE_MOFFS16)
975 TYPE("offset32", TYPE_MOFFS32)
976 TYPE("offset64", TYPE_MOFFS64)
980 TYPE("offset16_8", TYPE_MOFFS8)
981 TYPE("offset16_16", TYPE_MOFFS16)
982 TYPE("offset16_32", TYPE_MOFFS32)
983 TYPE("offset32_8", TYPE_MOFFS8)
984 TYPE("offset32_16", TYPE_MOFFS16)
985 TYPE("offset32_32", TYPE_MOFFS32)
986 TYPE("offset64_8", TYPE_MOFFS8)
987 TYPE("offset64_16", TYPE_MOFFS16)
988 TYPE("offset64_32", TYPE_MOFFS32)
989 TYPE("offset64_64", TYPE_MOFFS64)
977990 TYPE("VR256", TYPE_XMM256)
978991 TYPE("VR256X", TYPE_XMM256)
979992 TYPE("VR512", TYPE_XMM512)
11991212 ENCODING("brtarget", ENCODING_Iv)
12001213 ENCODING("brtarget8", ENCODING_IB)
12011214 ENCODING("i64imm", ENCODING_IO)
1202 ENCODING("offset8", ENCODING_Ia)
1203 ENCODING("offset16", ENCODING_Ia)
1204 ENCODING("offset32", ENCODING_Ia)
1205 ENCODING("offset64", ENCODING_Ia)
1215 ENCODING("offset16_8", ENCODING_Ia)
1216 ENCODING("offset16_16", ENCODING_Ia)
1217 ENCODING("offset16_32", ENCODING_Ia)
1218 ENCODING("offset32_8", ENCODING_Ia)
1219 ENCODING("offset32_16", ENCODING_Ia)
1220 ENCODING("offset32_32", ENCODING_Ia)
1221 ENCODING("offset64_8", ENCODING_Ia)
1222 ENCODING("offset64_16", ENCODING_Ia)
1223 ENCODING("offset64_32", ENCODING_Ia)
1224 ENCODING("offset64_64", ENCODING_Ia)
12061225 ENCODING("srcidx8", ENCODING_SI)
12071226 ENCODING("srcidx16", ENCODING_SI)
12081227 ENCODING("srcidx32", ENCODING_SI)