Index: lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp =================================================================== --- lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp +++ lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp @@ -143,6 +143,7 @@ class X86AddressSanitizer32 : public X86AddressSanitizer { public: static const long kShadowOffset = 0x20000000; + static const unsigned kDefaultMemSize = 32; X86AddressSanitizer32(const MCSubtargetInfo &STI) : X86AddressSanitizer(STI) {} @@ -201,7 +202,7 @@ Inst.addOperand(MCOperand::CreateReg(X86::CL)); const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx); std::unique_ptr Op( - X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc())); + X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc(), kDefaultMemSize)); Op->addMemOperands(Inst, 5); EmitInstruction(Out, Inst); } @@ -227,7 +228,7 @@ const MCExpr *Disp = MCConstantExpr::Create(1, Ctx); std::unique_ptr Op( - X86Operand::CreateMem(0, Disp, X86::EDX, 0, 1, SMLoc(), SMLoc())); + X86Operand::CreateMem(0, Disp, X86::EDX, 0, 1, SMLoc(), SMLoc(), kDefaultMemSize)); Op->addMemOperands(Inst, 5); EmitInstruction(Out, Inst); break; @@ -289,7 +290,7 @@ } const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx); std::unique_ptr Op( - X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc())); + X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc(), kDefaultMemSize)); Op->addMemOperands(Inst, 5); Inst.addOperand(MCOperand::CreateImm(0)); EmitInstruction(Out, Inst); @@ -320,6 +321,7 @@ virtual void InstrumentMemOperandLargeImpl( X86Operand &Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx, MCStreamer &Out) override; + static const unsigned kDefaultMemSize = 64; private: void EmitAdjustRSP(MCContext &Ctx, MCStreamer &Out, long Offset) { @@ -329,7 +331,7 @@ const MCExpr *Disp = MCConstantExpr::Create(Offset, Ctx); std::unique_ptr Op( - X86Operand::CreateMem(0, Disp, X86::RSP, 0, 1, SMLoc(), SMLoc())); + X86Operand::CreateMem(0, Disp, X86::RSP, 0, 1, SMLoc(), SMLoc(), kDefaultMemSize)); Op->addMemOperands(Inst, 5); EmitInstruction(Out, Inst); } @@ -375,7 +377,7 @@ Inst.addOperand(MCOperand::CreateReg(X86::AL)); const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx); std::unique_ptr Op( - X86Operand::CreateMem(0, Disp, X86::RAX, 0, 1, SMLoc(), SMLoc())); + X86Operand::CreateMem(0, Disp, X86::RAX, 0, 1, SMLoc(), SMLoc(), kDefaultMemSize)); Op->addMemOperands(Inst, 5); EmitInstruction(Out, Inst); } @@ -401,7 +403,7 @@ const MCExpr *Disp = MCConstantExpr::Create(1, Ctx); std::unique_ptr Op( - X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc())); + X86Operand::CreateMem(0, Disp, X86::ECX, 0, 1, SMLoc(), SMLoc(), kDefaultMemSize)); Op->addMemOperands(Inst, 5); EmitInstruction(Out, Inst); break; @@ -462,7 +464,7 @@ } const MCExpr *Disp = MCConstantExpr::Create(kShadowOffset, Ctx); std::unique_ptr Op( - X86Operand::CreateMem(0, Disp, X86::RAX, 0, 1, SMLoc(), SMLoc())); + X86Operand::CreateMem(0, Disp, X86::RAX, 0, 1, SMLoc(), SMLoc(), kDefaultMemSize)); Op->addMemOperands(Inst, 5); Inst.addOperand(MCOperand::CreateImm(0)); EmitInstruction(Out, Inst); Index: lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- lib/Target/X86/AsmParser/X86AsmParser.cpp +++ lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -719,6 +719,10 @@ // FIXME: Can tablegen auto-generate this? return (STI.getFeatureBits() & X86::Mode16Bit) != 0; } + + unsigned DefaultMemSize() const { + return is64BitMode() ? 64 : (is32BitMode() ? 32 : 16); + } void SwitchMode(uint64_t mode) { uint64_t oldMode = STI.getFeatureBits() & (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit); @@ -942,7 +946,7 @@ is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI); const MCExpr *Disp = MCConstantExpr::Create(0, getContext()); return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/basereg, - /*IndexReg=*/0, /*Scale=*/1, Loc, Loc, 0); + /*IndexReg=*/0, /*Scale=*/1, Loc, Loc, DefaultMemSize(), 0); } std::unique_ptr X86AsmParser::DefaultMemDIOperand(SMLoc Loc) { @@ -950,7 +954,7 @@ is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI); const MCExpr *Disp = MCConstantExpr::Create(0, getContext()); return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/basereg, - /*IndexReg=*/0, /*Scale=*/1, Loc, Loc, 0); + /*IndexReg=*/0, /*Scale=*/1, Loc, Loc, DefaultMemSize(), 0); } std::unique_ptr X86AsmParser::ParseOperand() { @@ -1010,7 +1014,7 @@ // get the matching correct in some cases. BaseReg = BaseReg ? BaseReg : 1; return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, Start, - End, Size, Identifier, Info.OpDecl); + End, DefaultMemSize(), Size, Identifier, Info.OpDecl); } static void @@ -1251,7 +1255,7 @@ if (!SegReg) return X86Operand::CreateMem(Disp, Start, End, Size); else - return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, Start, End, Size); + return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, Start, End, DefaultMemSize(), Size); } StringRef ErrMsg; if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) { @@ -1259,7 +1263,7 @@ return nullptr; } return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, Start, - End, Size); + End, DefaultMemSize(), Size); } InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo(); @@ -1325,7 +1329,7 @@ const MCExpr *Disp = MCConstantExpr::Create(ImmDisp, getContext()); return X86Operand::CreateMem(SegReg, Disp, /*BaseReg=*/0, /*IndexReg=*/0, /*Scale=*/1, Start, ImmDispToken.getEndLoc(), - Size); + DefaultMemSize(), Size); } } @@ -1406,7 +1410,7 @@ // we're pointing to a local variable in memory, so the base register is // really the frame or stack pointer. return X86Operand::CreateMem(/*SegReg=*/0, Disp, /*BaseReg=*/1, /*IndexReg=*/0, - /*Scale=*/1, Start, End, Size, Identifier, + /*Scale=*/1, Start, End, DefaultMemSize(), Size, Identifier, Info.OpDecl); } @@ -1549,6 +1553,8 @@ if (Tok.getString() != "PTR" && Tok.getString() != "ptr") return ErrorOperand(Start, "Expected 'PTR' or 'ptr' token!"); Parser.Lex(); // Eat ptr. + } else { + // Size = is64BitMode() ? 64 : (is32BitMode() ? 32 : 16); } Start = Tok.getLoc(); @@ -1729,8 +1735,8 @@ if (getLexer().isNot(AsmToken::LParen)) { // Unless we have a segment register, treat this as an immediate. if (SegReg == 0) - return X86Operand::CreateMem(Disp, MemStart, ExprEnd); - return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); + return X86Operand::CreateMem(Disp, MemStart, ExprEnd, DefaultMemSize()); + return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd, DefaultMemSize()); } // Eat the '('. @@ -1756,8 +1762,8 @@ if (getLexer().isNot(AsmToken::LParen)) { // Unless we have a segment register, treat this as an immediate. if (SegReg == 0) - return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd); - return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); + return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd, DefaultMemSize()); + return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd, DefaultMemSize()); } // Eat the '('. @@ -1873,7 +1879,7 @@ } return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, - MemStart, MemEnd); + MemStart, MemEnd, DefaultMemSize()); } bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, Index: lib/Target/X86/AsmParser/X86Operand.h =================================================================== --- lib/Target/X86/AsmParser/X86Operand.h +++ lib/Target/X86/AsmParser/X86Operand.h @@ -53,6 +53,7 @@ unsigned IndexReg; unsigned Scale; unsigned Size; + unsigned DefaultSize; }; union { @@ -211,9 +212,15 @@ bool isMem16() const { return Kind == Memory && (!Mem.Size || Mem.Size == 16); } + bool isMem16Default() const { + return Kind == Memory && ((!Mem.Size && Mem.DefaultSize == 16) || Mem.Size == 16); + } bool isMem32() const { return Kind == Memory && (!Mem.Size || Mem.Size == 32); } + bool isMem32Default() const { + return Kind == Memory && ((!Mem.Size && Mem.DefaultSize == 32) || Mem.Size == 32); + } bool isMem64() const { return Kind == Memory && (!Mem.Size || Mem.Size == 64); } @@ -441,7 +448,7 @@ /// Create an absolute memory operand. static std::unique_ptr - CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned Size = 0, + CreateMem(const MCExpr *Disp, SMLoc StartLoc, SMLoc EndLoc, unsigned DefaultSize, unsigned Size = 0, StringRef SymName = StringRef(), void *OpDecl = nullptr) { auto Res = llvm::make_unique(Memory, StartLoc, EndLoc); Res->Mem.SegReg = 0; @@ -449,6 +456,7 @@ Res->Mem.BaseReg = 0; Res->Mem.IndexReg = 0; Res->Mem.Scale = 1; + Res->Mem.DefaultSize = DefaultSize; Res->Mem.Size = Size; Res->SymName = SymName; Res->OpDecl = OpDecl; @@ -460,7 +468,7 @@ static std::unique_ptr CreateMem(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc, SMLoc EndLoc, - unsigned Size = 0, StringRef SymName = StringRef(), + unsigned DefaultSize, unsigned Size = 0, StringRef SymName = StringRef(), void *OpDecl = nullptr) { // We should never just have a displacement, that should be parsed as an // absolute memory operand. @@ -475,6 +483,7 @@ Res->Mem.BaseReg = BaseReg; Res->Mem.IndexReg = IndexReg; Res->Mem.Scale = Scale; + Res->Mem.DefaultSize = DefaultSize; Res->Mem.Size = Size; Res->SymName = SymName; Res->OpDecl = OpDecl; Index: lib/Target/X86/X86InstrControl.td =================================================================== --- lib/Target/X86/X86InstrControl.td +++ lib/Target/X86/X86InstrControl.td @@ -193,7 +193,7 @@ def CALL16r : I<0xFF, MRM2r, (outs), (ins GR16:$dst), "call{w}\t{*}$dst", [(X86call GR16:$dst)], IIC_CALL_RI>, OpSize16, Requires<[Not64BitMode]>, Sched<[WriteJump]>; - def CALL16m : I<0xFF, MRM2m, (outs), (ins i16mem:$dst), + def CALL16m : I<0xFF, MRM2m, (outs), (ins i16memdefault:$dst), "call{w}\t{*}$dst", [(X86call (loadi16 addr:$dst))], IIC_CALL_MEM>, OpSize16, Requires<[Not64BitMode,FavorMemIndirectCall]>, @@ -201,7 +201,7 @@ def CALL32r : I<0xFF, MRM2r, (outs), (ins GR32:$dst), "call{l}\t{*}$dst", [(X86call GR32:$dst)], IIC_CALL_RI>, OpSize32, Requires<[Not64BitMode]>, Sched<[WriteJump]>; - def CALL32m : I<0xFF, MRM2m, (outs), (ins i32mem:$dst), + def CALL32m : I<0xFF, MRM2m, (outs), (ins i32memdefault:$dst), "call{l}\t{*}$dst", [(X86call (loadi32 addr:$dst))], IIC_CALL_MEM>, OpSize32, Requires<[Not64BitMode,FavorMemIndirectCall]>, Index: lib/Target/X86/X86InstrInfo.td =================================================================== --- lib/Target/X86/X86InstrInfo.td +++ lib/Target/X86/X86InstrInfo.td @@ -267,9 +267,15 @@ def X86Mem16AsmOperand : AsmOperandClass { let Name = "Mem16"; let RenderMethod = "addMemOperands"; } +def X86Mem16DefaultAsmOperand : AsmOperandClass { + let Name = "Mem16Default"; let RenderMethod = "addMemOperands"; +} def X86Mem32AsmOperand : AsmOperandClass { let Name = "Mem32"; let RenderMethod = "addMemOperands"; } +def X86Mem32DefaultAsmOperand : AsmOperandClass { + let Name = "Mem32Default"; let RenderMethod = "addMemOperands"; +} def X86Mem64AsmOperand : AsmOperandClass { let Name = "Mem64"; let RenderMethod = "addMemOperands"; } @@ -326,8 +332,12 @@ let ParserMatchClass = X86Mem8AsmOperand; } def i16mem : X86MemOperand<"printi16mem"> { let ParserMatchClass = X86Mem16AsmOperand; } +def i16memdefault : X86MemOperand<"printi16mem"> { + let ParserMatchClass = X86Mem16DefaultAsmOperand; } def i32mem : X86MemOperand<"printi32mem"> { let ParserMatchClass = X86Mem32AsmOperand; } +def i32memdefault : X86MemOperand<"printi32mem"> { + let ParserMatchClass = X86Mem32DefaultAsmOperand; } def i64mem : X86MemOperand<"printi64mem"> { let ParserMatchClass = X86Mem64AsmOperand; } def i128mem : X86MemOperand<"printi128mem"> { Index: test/MC/X86/intel-syntax-unsized-operand.s =================================================================== --- /dev/null +++ test/MC/X86/intel-syntax-unsized-operand.s @@ -0,0 +1,11 @@ +// RUN: llvm-mc -triple i386-unknown-unknown -x86-asm-syntax=intel %s | FileCheck -check-prefix=CHECK-32 %s +// RUN: llvm-mc -triple i386-unknown-unknown-code16 -x86-asm-syntax=intel %s | FileCheck -check-prefix=CHECK-16 %s +// CHECK-32: calll *(%edx) +// CHECK-16: callw *(%edx) +// CHECK-32: calll *(%edx) +// CHECK-16: calll *(%edx) +// CHECK-32: callw *(%edx) +// CHECK-16: callw *(%edx) +call [edx] +call dword ptr [edx] +call word ptr [edx] Index: utils/TableGen/X86RecognizableInstr.cpp =================================================================== --- utils/TableGen/X86RecognizableInstr.cpp +++ utils/TableGen/X86RecognizableInstr.cpp @@ -890,10 +890,12 @@ TYPE("GR32", TYPE_Rv) } TYPE("i16mem", TYPE_Mv) + TYPE("i16memdefault", TYPE_Mv) TYPE("i16imm", TYPE_IMM16) TYPE("i16i8imm", TYPE_IMMv) TYPE("GR16", TYPE_R16) TYPE("i32mem", TYPE_Mv) + TYPE("i32memdefault", TYPE_Mv) TYPE("i32imm", TYPE_IMMv) TYPE("i32i8imm", TYPE_IMM32) TYPE("u32u8imm", TYPE_IMM32) @@ -1108,7 +1110,9 @@ RecognizableInstr::memoryEncodingFromString(const std::string &s, uint8_t OpSize) { ENCODING("i16mem", ENCODING_RM) + ENCODING("i16memdefault", ENCODING_RM) ENCODING("i32mem", ENCODING_RM) + ENCODING("i32memdefault", ENCODING_RM) ENCODING("i64mem", ENCODING_RM) ENCODING("i8mem", ENCODING_RM) ENCODING("ssmem", ENCODING_RM)