Index: lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- lib/Target/X86/AsmParser/X86AsmParser.cpp +++ lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -430,6 +430,13 @@ } PrevState = CurrState; } + bool checkIndexReg(StringRef &ErrMsg) { + if (IndexReg) { + ErrMsg = "BaseReg/IndexReg already set!"; + return true; + } + return false; + } bool onPlus(StringRef &ErrMsg) { IntelExprState CurrState = State; switch (State) { @@ -447,10 +454,8 @@ if (!BaseReg) { BaseReg = TmpReg; } else { - if (IndexReg) { - ErrMsg = "BaseReg/IndexReg already set!"; + if (checkIndexReg(ErrMsg)) return true; - } IndexReg = TmpReg; Scale = 1; } @@ -499,10 +504,8 @@ if (!BaseReg) { BaseReg = TmpReg; } else { - if (IndexReg) { - ErrMsg = "BaseReg/IndexReg already set!"; + if (checkIndexReg(ErrMsg)) return true; - } IndexReg = TmpReg; Scale = 1; } @@ -543,7 +546,8 @@ switch (State) { default: State = IES_ERROR; - break; + ErrMsg = "Invalid operation with register"; + return true; case IES_PLUS: case IES_LPAREN: State = IES_REGISTER; @@ -553,10 +557,8 @@ case IES_MULTIPLY: // Index Register - Scale * Register if (PrevState == IES_INTEGER) { - if (IndexReg) { - ErrMsg = "BaseReg/IndexReg already set!"; + if (checkIndexReg(ErrMsg)) return true; - } State = IES_REGISTER; IndexReg = Reg; // Get the scale and replace the 'Scale * Register' with '0'. @@ -566,18 +568,33 @@ IC.pushOperand(IC_IMM); IC.popOperator(); } else { - State = IES_ERROR; + ErrMsg = "Invalid operand of multiplication"; + return true; } break; } PrevState = CurrState; return false; } - void onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName) { + bool checkSetScale(int64_t NewScale, StringRef &ErrMsg) { + if (checkIndexReg(ErrMsg)) + return true; + IndexReg = TmpReg; + Scale = NewScale; + if (checkScale(Scale, ErrMsg)) + return true; + // Get the scale and replace the 'Register * Scale' with '0'. + IC.popOperator(); + return false; + } + bool onIdentifierExpr(const MCExpr *SymRef, StringRef SymRefName, + StringRef &ErrMsg) { PrevState = State; switch (State) { default: State = IES_ERROR; + ErrMsg = "invalid address operation"; + return true; break; case IES_PLUS: case IES_MINUS: @@ -588,6 +605,7 @@ IC.pushOperand(IC_IMM); break; } + return false; } bool onInteger(int64_t TmpInt, StringRef &ErrMsg) { IntelExprState CurrState = State; @@ -609,17 +627,8 @@ case IES_LPAREN: State = IES_INTEGER; if (PrevState == IES_REGISTER && CurrState == IES_MULTIPLY) { - // Index Register - Register * Scale - if (IndexReg) { - ErrMsg = "BaseReg/IndexReg already set!"; - return true; - } - IndexReg = TmpReg; - Scale = TmpInt; - if (checkScale(Scale, ErrMsg)) + if (checkSetScale(TmpInt, ErrMsg)) return true; - // Get the scale and replace the 'Register * Scale' with '0'. - IC.popOperator(); } else { IC.pushOperand(IC_IMM, TmpInt); } @@ -1422,7 +1431,13 @@ } else if (!isParsingInlineAsm()) { if (getParser().parsePrimaryExpr(Val, End)) return Error(Tok.getLoc(), "Unexpected identifier!"); - SM.onIdentifierExpr(Val, Identifier); + if (Val->getKind() == MCExpr::Constant) { + if (const auto *CE = dyn_cast(Val)) { + if (SM.onInteger(CE->getValue(), ErrMsg)) + return Error(Tok.getLoc(), ErrMsg); + } + } else if (SM.onIdentifierExpr(Val, Identifier, ErrMsg)) + return Error(IdentLoc, ErrMsg); } else if (unsigned OpKind = IdentifyIntelOperator(Identifier)) { if (OpKind == IOK_OFFSET) return Error(IdentLoc, "Dealing OFFSET operator as part of" @@ -1440,7 +1455,8 @@ if (ParseIntelIdentifier(Val, Identifier, Info, /*Unevaluated=*/false, End)) return true; - SM.onIdentifierExpr(Val, Identifier); + if (SM.onIdentifierExpr(Val, Identifier, ErrMsg)) + return Error(IdentLoc, ErrMsg); } break; } @@ -1463,7 +1479,8 @@ if (IDVal == "b" && Sym->isUndefined()) return Error(Loc, "invalid reference to undefined symbol"); StringRef Identifier = Sym->getName(); - SM.onIdentifierExpr(Val, Identifier); + if (SM.onIdentifierExpr(Val, Identifier, ErrMsg)) + return Error(Loc, ErrMsg); End = consumeToken(); } else { if (SM.onInteger(IntVal, ErrMsg)) Index: test/MC/X86/intel-syntax-3.s =================================================================== --- test/MC/X86/intel-syntax-3.s +++ test/MC/X86/intel-syntax-3.s @@ -1,44 +1,12 @@ // RUN: not llvm-mc -triple x86_64-unknown-unknown -x86-asm-syntax=intel %s 2> %t.err // RUN: FileCheck --check-prefix=CHECK-STDERR < %t.err %s -_test: -// CHECK-LABEL: _test: -// CHECK: xorl %eax, %eax - - xor EAX, EAX - ret - -.set number, 8 .global _foo .text .global main main: -// CHECK-STDERR: error: unknown token in expression - lea RDX, [RAX * number + RBX + _foo] - -// CHECK-STDERR: error: unknown token in expression - lea RDX, [_foo + RAX * number + RBX] - -// CHECK-STDERR: error: unknown token in expression - lea RDX, [number + RAX * number + RCX] - -// CHECK-STDERR: error: unknown token in expression - lea RDX, [_foo + RAX * number] - -// CHECK-STDERR: error: unknown token in expression - lea RDX, [_foo + RAX * number + RBX] - -// CHECK-STDERR: scale factor in address must be 1, 2, 4 or 8 - lea RDX, [number * RAX + RBX + _foo] - -// CHECK-STDERR: scale factor in address must be 1, 2, 4 or 8 - lea RDX, [_foo + number * RAX + RBX] - -// CHECK-STDERR: scale factor in address must be 1, 2, 4 or 8 - lea RDX, [8 + number * RAX + RCX] - // CHECK-STDERR: scale factor in address must be 1, 2, 4 or 8 lea RDX, [unknown_number * RAX + RBX + _foo] Index: test/MC/X86/intel-syntax.s =================================================================== --- test/MC/X86/intel-syntax.s +++ test/MC/X86/intel-syntax.s @@ -14,6 +14,30 @@ main: // CHECK: leaq _foo(%rbx,%rax,8), %rdx + lea RDX, [RAX * number + RBX + _foo] + +// CHECK: leaq _foo(%rbx,%rax,8), %rdx + lea RDX, [_foo + RAX * number + RBX] + +// CHECK: leaq 8(%rcx,%rax,8), %rdx + lea RDX, [number + RAX * number + RCX] + +// CHECK: leaq _foo(,%rax,8), %rdx + lea RDX, [_foo + RAX * number] + +// CHECK: leaq _foo(%rbx,%rax,8), %rdx + lea RDX, [_foo + RAX * number + RBX] + +// CHECK: leaq _foo(%rbx,%rax,8), %rdx + lea RDX, [number * RAX + RBX + _foo] + +// CHECK: leaq _foo(%rbx,%rax,8), %rdx + lea RDX, [_foo + number * RAX + RBX] + +// CHECK: leaq 8(%rcx,%rax,8), %rdx + lea RDX, [8 + number * RAX + RCX] + +// CHECK: leaq _foo(%rbx,%rax,8), %rdx lea RDX, [8 * RAX + RBX + _foo] // CHECK: leaq _foo(%rbx,%rax,8), %rdx @@ -31,7 +55,7 @@ // CHECK: leaq _foo(%rbx,%rax,8), %rdx lea RDX, [_foo + RAX * 8 + RBX] -// CHECK: leaq 8(%rax), %rdx +// CHECK: leaq -8(%rax), %rdx lea RDX, [RAX - number] // CHECK: leaq -8(%rax), %rdx lea RDX, [RAX - 8]