Index: lib/Target/ARM/AsmParser/ARMAsmParser.cpp =================================================================== --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -1150,10 +1150,30 @@ bool isToken() const override { return Kind == k_Token; } bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; } bool isInstSyncBarrierOpt() const { return Kind == k_InstSyncBarrierOpt; } - bool isMem() const override { return Kind == k_Memory; } + bool isMem() const override { + if (Kind != k_Memory) + return false; + if (Memory.BaseRegNum && + !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.BaseRegNum)) + return false; + if (Memory.OffsetRegNum && + !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.OffsetRegNum)) + return false; + return true; + } bool isShifterImm() const { return Kind == k_ShifterImmediate; } - bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; } - bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; } + bool isRegShiftedReg() const { + return Kind == k_ShiftedRegister && + ARMMCRegisterClasses[ARM::GPRRegClassID].contains( + RegShiftedReg.SrcReg) && + ARMMCRegisterClasses[ARM::GPRRegClassID].contains( + RegShiftedReg.ShiftReg); + } + bool isRegShiftedImm() const { + return Kind == k_ShiftedImmediate && + ARMMCRegisterClasses[ARM::GPRRegClassID].contains( + RegShiftedImm.SrcReg); + } bool isRotImm() const { return Kind == k_RotateImmediate; } bool isModImm() const { return Kind == k_ModifiedImmediate; } @@ -1192,9 +1212,12 @@ bool isConstantPoolImm() const { return Kind == k_ConstantPoolImmediate; } bool isBitfield() const { return Kind == k_BitfieldDescriptor; } - bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; } + bool isPostIdxRegShifted() const { + return Kind == k_PostIndexRegister && + ARMMCRegisterClasses[ARM::GPRRegClassID].contains(PostIdxReg.RegNum); + } bool isPostIdxReg() const { - return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift; + return isPostIdxRegShifted() && PostIdxReg.ShiftTy == ARM_AM::no_shift; } bool isMemNoOffset(bool alignOK = false, unsigned Alignment = 0) const { if (!isMem()) @@ -1331,10 +1354,10 @@ } bool isAM3Offset() const { - if (Kind != k_Immediate && Kind != k_PostIndexRegister) + if (isPostIdxReg()) + return true; + if (!isImm()) return false; - if (Kind == k_PostIndexRegister) - return PostIdxReg.ShiftTy == ARM_AM::no_shift; // Immediate offset in range [-255, 255]. const MCConstantExpr *CE = dyn_cast(getImm()); if (!CE) return false; Index: test/MC/ARM/arm-reg-addr-errors.s =================================================================== --- /dev/null +++ test/MC/ARM/arm-reg-addr-errors.s @@ -0,0 +1,50 @@ +@ RUN: not llvm-mc -triple=armv7a-eabi < %s 2>&1 | FileCheck %s + +ldr r4, [s1, #12] +@ CHECK: [[@LINE-1]]{{.*}}error: invalid operand for instruction + +ldr r4, [d2, #12] +@ CHECK: [[@LINE-1]]{{.*}}error: invalid operand for instruction + +ldr r4, [q3, #12] +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +ldr r4, [cpsr, #12] +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +ldr r4, [r1, s12] +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +ldr r4, [r1, d12] +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +ldr r4, [r1, q12] +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +ldr r4, [r1, cpsr] +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +ldr r4, [r3], s12 +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +ldr r4, [r3], d12 +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +ldr r4, [r3], q12 +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +ldr r4, [r3], cpsr +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +add r3, r0, s1, lsl #2 +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +add r3, r0, d1, lsl #2 +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +add r3, r0, q1, lsl #2 +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +add r3, r0, cpsr, lsl #2 +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +add r3, r0, r1, lsl s6 +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +add r3, r0, r1, lsl d6 +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +add r3, r0, r1, lsl q6 +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +add r3, r0, r1, lsl cpsr +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +ldrd r2, r3, [s4] +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +ldrd r2, r3, [r4, s5] +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction +ldrd r2, r3, [r4], s5 +@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction