Index: lib/Target/ARM64/ARM64InstrFormats.td =================================================================== --- lib/Target/ARM64/ARM64InstrFormats.td +++ lib/Target/ARM64/ARM64InstrFormats.td @@ -2251,6 +2251,7 @@ class MemROAsmOperand : AsmOperandClass { let Name = "MemoryRegisterOffset"#sz; + let DiagnosticType = "InvalidMemoryIndexed"; } def MemROAsmOperand8 : MemROAsmOperand<8>; Index: lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp =================================================================== --- lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp +++ lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp @@ -3699,6 +3699,8 @@ return Error(Loc, "index must be a multiple of 8 in range [-512, 504]."); case Match_InvalidMemoryIndexed128SImm7: return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008]."); + case Match_InvalidMemoryIndexed: + return Error(Loc, "invalid offset in memory address."); case Match_InvalidMemoryIndexed8: return Error(Loc, "index must be an integer in range [0, 4095]."); case Match_InvalidMemoryIndexed16: @@ -4114,17 +4116,11 @@ if (Operands.size() == ErrorInfo + 1 && !((ARM64Operand *)Operands[ErrorInfo])->isImm() && !Tok.startswith("stur") && !Tok.startswith("ldur")) { - // whether we want an Indexed64 or Indexed32 diagnostic depends on - // the register class of the previous operand. Default to 64 in case - // we see something unexpected. - MatchResult = Match_InvalidMemoryIndexed64; - if (ErrorInfo) { - ARM64Operand *PrevOp = (ARM64Operand *)Operands[ErrorInfo - 1]; - if (PrevOp->isReg() && - ARM64MCRegisterClasses[ARM64::GPR32RegClassID].contains( - PrevOp->getReg())) - MatchResult = Match_InvalidMemoryIndexed32; - } + // FIXME: Here we use a vague diagnostic for memory operand in many + // instructions of various formats. This diagnostic can be more accurate + // if splitting memory operand into many smaller operands to help + // diagnose. + MatchResult = Match_InvalidMemoryIndexed; } SMLoc ErrorLoc = ((ARM64Operand *)Operands[ErrorInfo])->getStartLoc(); if (ErrorLoc == SMLoc()) Index: test/MC/ARM64/diags.s =================================================================== --- test/MC/ARM64/diags.s +++ test/MC/ARM64/diags.s @@ -33,10 +33,10 @@ ldur x0, [x1, #-257] -; CHECK-ERRORS: error: index must be a multiple of 8 in range [0, 32760]. +; CHECK-ERRORS: error: invalid offset in memory address. ; CHECK-ERRORS: ldr x0, [x0, #804] ; CHECK-ERRORS: ^ -; CHECK-ERRORS: error: index must be a multiple of 4 in range [0, 16380]. +; CHECK-ERRORS: error: invalid offset in memory address. ; CHECK-ERRORS: ldr w0, [x0, #802] ; CHECK-ERRORS: ^ ; CHECK-ERRORS: error: index must be an integer in range [-256, 255]. @@ -74,6 +74,44 @@ ; CHECK-ERRORS: ^ +ldrb w1, [x3, w3, sxtw #4] +ldrh w1, [x3, w3, sxtw #4] +ldr w1, [x3, w3, sxtw #4] +ldr x1, [x3, w3, sxtw #4] +ldr b1, [x3, w3, sxtw #4] +ldr h1, [x3, w3, sxtw #4] +ldr s1, [x3, w3, sxtw #4] +ldr d1, [x3, w3, sxtw #4] +ldr q1, [x3, w3, sxtw #1] + +; CHECK-ERRORS: error: invalid offset in memory address. +; CHECK-ERRORS:ldrb w1, [x3, w3, sxtw #4] +; CHECK-ERRORS: ^ +; CHECK-ERRORS: error: invalid offset in memory address. +; CHECK-ERRORS:ldrh w1, [x3, w3, sxtw #4] +; CHECK-ERRORS: ^ +; CHECK-ERRORS: error: invalid offset in memory address. +; CHECK-ERRORS:ldr w1, [x3, w3, sxtw #4] +; CHECK-ERRORS: ^ +; CHECK-ERRORS: error: invalid offset in memory address. +; CHECK-ERRORS:ldr x1, [x3, w3, sxtw #4] +; CHECK-ERRORS: ^ +; CHECK-ERRORS: error: invalid offset in memory address. +; CHECK-ERRORS:ldr b1, [x3, w3, sxtw #4] +; CHECK-ERRORS: ^ +; CHECK-ERRORS: invalid offset in memory address. +; CHECK-ERRORS:ldr h1, [x3, w3, sxtw #4] +; CHECK-ERRORS: ^ +; CHECK-ERRORS: invalid offset in memory address. +; CHECK-ERRORS:ldr s1, [x3, w3, sxtw #4] +; CHECK-ERRORS: ^ +; CHECK-ERRORS: invalid offset in memory address. +; CHECK-ERRORS:ldr d1, [x3, w3, sxtw #4] +; CHECK-ERRORS: ^ +; CHECK-ERRORS: invalid offset in memory address. +; CHECK-ERRORS:ldr q1, [x3, w3, sxtw #1] +; CHECK-ERRORS: ^ + ; Check that register offset addressing modes only accept 32-bit offset ; registers when using uxtw/sxtw extends. Everything else requires a 64-bit ; register.