Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 2e4bd2a

Browse files
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321866 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 545ec94 commit 2e4bd2a

File tree

2 files changed

+81
-8
lines changed

2 files changed

+81
-8
lines changed

lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,10 +1150,30 @@ class ARMOperand : public MCParsedAsmOperand {
11501150
bool isToken() const override { return Kind == k_Token; }
11511151
bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
11521152
bool isInstSyncBarrierOpt() const { return Kind == k_InstSyncBarrierOpt; }
1153-
bool isMem() const override { return Kind == k_Memory; }
1153+
bool isMem() const override {
1154+
if (Kind != k_Memory)
1155+
return false;
1156+
if (Memory.BaseRegNum &&
1157+
!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.BaseRegNum))
1158+
return false;
1159+
if (Memory.OffsetRegNum &&
1160+
!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.OffsetRegNum))
1161+
return false;
1162+
return true;
1163+
}
11541164
bool isShifterImm() const { return Kind == k_ShifterImmediate; }
1155-
bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; }
1156-
bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; }
1165+
bool isRegShiftedReg() const {
1166+
return Kind == k_ShiftedRegister &&
1167+
ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1168+
RegShiftedReg.SrcReg) &&
1169+
ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1170+
RegShiftedReg.ShiftReg);
1171+
}
1172+
bool isRegShiftedImm() const {
1173+
return Kind == k_ShiftedImmediate &&
1174+
ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1175+
RegShiftedImm.SrcReg);
1176+
}
11571177
bool isRotImm() const { return Kind == k_RotateImmediate; }
11581178
bool isModImm() const { return Kind == k_ModifiedImmediate; }
11591179

@@ -1192,9 +1212,12 @@ class ARMOperand : public MCParsedAsmOperand {
11921212

11931213
bool isConstantPoolImm() const { return Kind == k_ConstantPoolImmediate; }
11941214
bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
1195-
bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; }
1215+
bool isPostIdxRegShifted() const {
1216+
return Kind == k_PostIndexRegister &&
1217+
ARMMCRegisterClasses[ARM::GPRRegClassID].contains(PostIdxReg.RegNum);
1218+
}
11961219
bool isPostIdxReg() const {
1197-
return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift;
1220+
return isPostIdxRegShifted() && PostIdxReg.ShiftTy == ARM_AM::no_shift;
11981221
}
11991222
bool isMemNoOffset(bool alignOK = false, unsigned Alignment = 0) const {
12001223
if (!isMem())
@@ -1331,10 +1354,10 @@ class ARMOperand : public MCParsedAsmOperand {
13311354
}
13321355

13331356
bool isAM3Offset() const {
1334-
if (Kind != k_Immediate && Kind != k_PostIndexRegister)
1357+
if (isPostIdxReg())
1358+
return true;
1359+
if (!isImm())
13351360
return false;
1336-
if (Kind == k_PostIndexRegister)
1337-
return PostIdxReg.ShiftTy == ARM_AM::no_shift;
13381361
// Immediate offset in range [-255, 255].
13391362
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13401363
if (!CE) return false;

test/MC/ARM/arm-reg-addr-errors.s

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
@ RUN: not llvm-mc -triple=armv7a-eabi < %s 2>&1 | FileCheck %s
2+
3+
ldr r4, [s1, #12]
4+
@ CHECK: [[@LINE-1]]{{.*}}error: invalid operand for instruction
5+
6+
ldr r4, [d2, #12]
7+
@ CHECK: [[@LINE-1]]{{.*}}error: invalid operand for instruction
8+
9+
ldr r4, [q3, #12]
10+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
11+
ldr r4, [cpsr, #12]
12+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
13+
ldr r4, [r1, s12]
14+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
15+
ldr r4, [r1, d12]
16+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
17+
ldr r4, [r1, q12]
18+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
19+
ldr r4, [r1, cpsr]
20+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
21+
ldr r4, [r3], s12
22+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
23+
ldr r4, [r3], d12
24+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
25+
ldr r4, [r3], q12
26+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
27+
ldr r4, [r3], cpsr
28+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
29+
add r3, r0, s1, lsl #2
30+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
31+
add r3, r0, d1, lsl #2
32+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
33+
add r3, r0, q1, lsl #2
34+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
35+
add r3, r0, cpsr, lsl #2
36+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
37+
add r3, r0, r1, lsl s6
38+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
39+
add r3, r0, r1, lsl d6
40+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
41+
add r3, r0, r1, lsl q6
42+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
43+
add r3, r0, r1, lsl cpsr
44+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
45+
ldrd r2, r3, [s4]
46+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
47+
ldrd r2, r3, [r4, s5]
48+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction
49+
ldrd r2, r3, [r4], s5
50+
@ CHECK: [[@LINE-1]]{{.*}} invalid operand for instruction

0 commit comments

Comments
 (0)