1// RUN: not llvm-mc -triple=thumbv7 -show-encoding < %s 2>&1 | FileCheck --check-prefix=CHECK --check-prefix=CHECK-V7 %s
2// RUN: not llvm-mc -triple=thumbv8 -show-encoding < %s 2>&1 | FileCheck --check-prefix=CHECK --check-prefix=CHECK-V8 %s
3
4        // Tests to check handling of sp and pc in thumb mov instructions. We
5        // have to be careful about the order of things, as stdout/stderr
6        // buffering means the errors appear before the non-error output, so
7        // we have to put all the error checks at the top.
8
9        // First check instructions that are never valid. These are thumb2
10        // instructions that uses pc
11
12        // t2MOVr selected because no thumb1 movs that can access high regs
13        movs pc, r0
14        movs r0, pc
15        movs pc, pc
16// CHECK: error: operand must be a register in range [r0, r14]
17// CHECK-NEXT: movs pc, r0
18// CHECK: note: operand must be a register in range [r0, r14]
19// CHECK-NEXT: movs r0, pc
20// CHECK: note: invalid operand for instruction
21// CHECK-NEXT: movs r0, pc
22// CHECK: error: invalid instruction
23// CHECK-NEXT: movs pc, pc
24
25        // mov.w selects t2MOVr
26        mov.w pc, r0
27        mov.w r0, pc
28        mov.w pc, pc
29// CHECK: error: operand must be a register in range [r0, r14]
30// CHECK-NEXT: mov.w pc, r0
31// CHECK: note: operand must be a register in range [r0, r14]
32// CHECK-NEXT: mov.w r0, pc
33// CHECK: note: invalid operand for instruction
34// CHECK-NEXT: mov.w r0, pc
35// CHECK: error: invalid instruction
36// CHECK-NEXT: mov.w pc, pc
37
38        // movs.w selects t2MOVr
39        movs.w pc, r0
40        movs.w r0, pc
41        movs.w pc, pc
42// CHECK: error: operand must be a register in range [r0, r14]
43// CHECK-NEXT: movs.w pc, r0
44// CHECK: note: operand must be a register in range [r0, r14]
45// CHECK-NEXT: movs.w r0, pc
46// CHECK: note: invalid operand for instruction
47// CHECK-NEXT: movs.w r0, pc
48// CHECK: error: invalid instruction
49// CHECK-NEXT: movs.w pc, pc
50
51
52        // Now check instructions that are invalid before ARMv8 due to SP usage
53
54        movs sp, r0
55        movs r0, sp
56        movs sp, sp
57// CHECK-V7: error: instruction variant requires ARMv8 or later
58// CHECK-V7-NEXT: movs sp, r0
59// CHECK-V7: instruction variant requires ARMv8 or later
60// CHECK-V7-NEXT: movs r0, sp
61// CHECK-V7: error: instruction variant requires ARMv8 or later
62// CHECK-V7-NEXT: movs sp, sp
63// CHECK-V8: movs.w sp, r0            @ encoding: [0x5f,0xea,0x00,0x0d]
64// CHECK-V8: movs.w r0, sp            @ encoding: [0x5f,0xea,0x0d,0x00]
65// CHECK-V8: movs.w sp, sp            @ encoding: [0x5f,0xea,0x0d,0x0d]
66
67        mov.w sp, sp
68// CHECK-V7: error: instruction variant requires ARMv8 or later
69// CHECK-V7-NEXT: mov.w sp, sp
70// CHECK-V8: mov.w sp, sp             @ encoding: [0x4f,0xea,0x0d,0x0d]
71
72        movs.w sp, r0
73        movs.w r0, sp
74        movs.w sp, sp
75// CHECK-V7: error: instruction variant requires ARMv8 or later
76// CHECK-V7-NEXT: movs.w sp, r0
77// CHECK-V7: instruction variant requires ARMv8 or later
78// CHECK-V7-NEXT: movs.w r0, sp
79// CHECK-V7: error: instruction variant requires ARMv8 or later
80// CHECK-V7-NEXT: movs.w sp, sp
81// CHECK-V8: movs.w sp, r0            @ encoding: [0x5f,0xea,0x00,0x0d]
82// CHECK-V8: movs.w r0, sp            @ encoding: [0x5f,0xea,0x0d,0x00]
83// CHECK-V8: movs.w sp, sp            @ encoding: [0x5f,0xea,0x0d,0x0d]
84
85
86        // Now instructions that are always valid
87
88        // mov selects tMOVr, where sp and pc are allowed
89        mov sp, r0
90        mov r0, sp
91        mov sp, sp
92        mov pc, r0
93        mov r0, pc
94        mov pc, pc
95// CHECK: mov sp, r0                  @ encoding: [0x85,0x46]
96// CHECK: mov r0, sp                  @ encoding: [0x68,0x46]
97// CHECK: mov sp, sp                  @ encoding: [0xed,0x46]
98// CHECK: mov pc, r0                  @ encoding: [0x87,0x46]
99// CHECK: mov r0, pc                  @ encoding: [0x78,0x46]
100// CHECK: mov pc, pc                  @ encoding: [0xff,0x46]
101
102        // sp allowed in non-flags-setting t2MOVr
103        mov.w sp, r0
104        mov.w r0, sp
105// CHECK: mov.w sp, r0                @ encoding: [0x4f,0xea,0x00,0x0d]
106// CHECK: mov.w r0, sp                @ encoding: [0x4f,0xea,0x0d,0x00]
107