diff options
-rw-r--r-- | lib/Target/X86/AsmParser/X86AsmParser.cpp | 32 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 7 | ||||
-rw-r--r-- | test/MC/AsmParser/X86/x86_instructions.s | 6 | ||||
-rw-r--r-- | test/MC/AsmParser/labels.s | 2 |
4 files changed, 40 insertions, 7 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index cc4498b4d9..65e498117f 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -172,6 +172,11 @@ struct X86Operand : public MCParsedAsmOperand { bool isMem() const { return Kind == Memory; } + bool isAbsMem() const { + return Kind == Memory && !getMemSegReg() && !getMemBaseReg() && + !getMemIndexReg() && !getMemScale(); + } + bool isNoSegMem() const { return Kind == Memory && !getMemSegReg(); } @@ -196,7 +201,6 @@ struct X86Operand : public MCParsedAsmOperand { void addMemOperands(MCInst &Inst, unsigned N) const { assert((N == 5) && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); Inst.addOperand(MCOperand::CreateImm(getMemScale())); Inst.addOperand(MCOperand::CreateReg(getMemIndexReg())); @@ -204,9 +208,13 @@ struct X86Operand : public MCParsedAsmOperand { Inst.addOperand(MCOperand::CreateReg(getMemSegReg())); } + void addAbsMemOperands(MCInst &Inst, unsigned N) const { + assert((N == 1) && "Invalid number of operands!"); + Inst.addOperand(MCOperand::CreateExpr(getMemDisp())); + } + void addNoSegMemOperands(MCInst &Inst, unsigned N) const { assert((N == 4) && "Invalid number of operands!"); - Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); Inst.addOperand(MCOperand::CreateImm(getMemScale())); Inst.addOperand(MCOperand::CreateReg(getMemIndexReg())); @@ -232,10 +240,24 @@ struct X86Operand : public MCParsedAsmOperand { return Res; } + /// Create an absolute memory operand. + static X86Operand *CreateMem(const MCExpr *Disp, SMLoc StartLoc, + SMLoc EndLoc) { + X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc); + Res->Mem.SegReg = 0; + Res->Mem.Disp = Disp; + Res->Mem.BaseReg = 0; + Res->Mem.IndexReg = 0; + Res->Mem.Scale = 0; + return Res; + } + + /// Create a generalized memory operand. static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg, unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) { - // We should never just have a displacement, that would be an immediate. + // We should never just have a displacement, that should be parsed as an + // absolute memory operand. assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!"); // The scale should always be one of {1,2,4,8}. @@ -322,7 +344,7 @@ X86Operand *X86ATTAsmParser::ParseMemOperand() { if (getLexer().isNot(AsmToken::LParen)) { // Unless we have a segment register, treat this as an immediate. if (SegReg == 0) - return X86Operand::CreateImm(Disp, MemStart, ExprEnd); + return X86Operand::CreateMem(Disp, MemStart, ExprEnd); return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); } @@ -349,7 +371,7 @@ X86Operand *X86ATTAsmParser::ParseMemOperand() { if (getLexer().isNot(AsmToken::LParen)) { // Unless we have a segment register, treat this as an immediate. if (SegReg == 0) - return X86Operand::CreateImm(Disp, LParenLoc, ExprEnd); + return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd); return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd); } diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 5041263a61..b6f9e162db 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -192,6 +192,10 @@ def X86MemAsmOperand : AsmOperandClass { let Name = "Mem"; let SuperClass = ?; } +def X86AbsMemAsmOperand : AsmOperandClass { + let Name = "AbsMem"; + let SuperClass = X86MemAsmOperand; +} def X86NoSegMemAsmOperand : AsmOperandClass { let Name = "NoSegMem"; let SuperClass = X86MemAsmOperand; @@ -233,7 +237,8 @@ def lea32mem : Operand<i32> { let ParserMatchClass = X86NoSegMemAsmOperand; } -let PrintMethod = "print_pcrel_imm" in { +let ParserMatchClass = X86AbsMemAsmOperand, + PrintMethod = "print_pcrel_imm" in { def i32imm_pcrel : Operand<i32>; def offset8 : Operand<i64>; diff --git a/test/MC/AsmParser/X86/x86_instructions.s b/test/MC/AsmParser/X86/x86_instructions.s index ed806ee734..314fc1add1 100644 --- a/test/MC/AsmParser/X86/x86_instructions.s +++ b/test/MC/AsmParser/X86/x86_instructions.s @@ -16,6 +16,12 @@ movl %eax, 10(%ebp, %ebx, 4) // CHECK: movl %eax, 10(,%ebx,4) movl %eax, 10(, %ebx, 4) + +// CHECK: movl 0, %eax + movl 0, %eax +// CHECK: movl $0, %eax + movl $0, %eax + // CHECK: ret ret diff --git a/test/MC/AsmParser/labels.s b/test/MC/AsmParser/labels.s index 456d61f060..3bc7e630ce 100644 --- a/test/MC/AsmParser/labels.s +++ b/test/MC/AsmParser/labels.s @@ -21,7 +21,7 @@ foo: // CHECK: b$c = 10 "b$c" = 10 // CHECK: addl $10, %eax - addl "b$c", %eax + addl $"b$c", %eax // CHECK: "a 0" = 11 .set "a 0", 11 |