forked from OSchip/llvm-project
[ARM] Issue an erorr when non-general-purpose registers are used in address operands
Currently the assembler would accept, e.g. `ldr r0, [s0, #12]` and similar. This patch add checks that only general-purpose registers are used in address operands, shifted registers, and shift amounts. Differential revision: https://reviews.llvm.org/D39910 llvm-svn: 321866
This commit is contained in:
parent
e970d64ec5
commit
7efdd090e2
|
@ -1150,10 +1150,30 @@ public:
|
|||
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 @@ public:
|
|||
|
||||
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 @@ public:
|
|||
}
|
||||
|
||||
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<MCConstantExpr>(getImm());
|
||||
if (!CE) return false;
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue