diff options
author | Jon Medhurst <tixy@yxit.co.uk> | 2011-08-27 07:40:30 -0400 |
---|---|---|
committer | Jon Medhurst <tixy@yxit.co.uk> | 2011-09-20 14:17:43 -0400 |
commit | c7054aad538c18bc4c311e74a24cb2e205f02e04 (patch) | |
tree | 436e5b6bf57c756ab1b6fd1c95064b49edb49334 | |
parent | a43bc69b39484a448293f2eddc7e98ff15437414 (diff) |
ARM: kprobes: Add Thumb instruction simulation test cases
Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
-rw-r--r-- | arch/arm/kernel/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/kernel/kprobes-test-thumb.c | 1187 | ||||
-rw-r--r-- | arch/arm/kernel/kprobes-test.c | 25 | ||||
-rw-r--r-- | arch/arm/kernel/kprobes-test.h | 6 |
4 files changed, 1221 insertions, 0 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index c7cbd965af94..ee9c049fc177 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -45,6 +45,9 @@ obj-$(CONFIG_KPROBES) += kprobes-arm.o | |||
45 | endif | 45 | endif |
46 | obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o | 46 | obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o |
47 | test-kprobes-objs := kprobes-test.o | 47 | test-kprobes-objs := kprobes-test.o |
48 | ifdef CONFIG_THUMB2_KERNEL | ||
49 | test-kprobes-objs += kprobes-test-thumb.o | ||
50 | endif | ||
48 | obj-$(CONFIG_ATAGS_PROC) += atags.o | 51 | obj-$(CONFIG_ATAGS_PROC) += atags.o |
49 | obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o | 52 | obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o |
50 | obj-$(CONFIG_ARM_THUMBEE) += thumbee.o | 53 | obj-$(CONFIG_ARM_THUMBEE) += thumbee.o |
diff --git a/arch/arm/kernel/kprobes-test-thumb.c b/arch/arm/kernel/kprobes-test-thumb.c new file mode 100644 index 000000000000..5e726c31c45a --- /dev/null +++ b/arch/arm/kernel/kprobes-test-thumb.c | |||
@@ -0,0 +1,1187 @@ | |||
1 | /* | ||
2 | * arch/arm/kernel/kprobes-test-thumb.c | ||
3 | * | ||
4 | * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/module.h> | ||
13 | |||
14 | #include "kprobes-test.h" | ||
15 | |||
16 | |||
17 | #define TEST_ISA "16" | ||
18 | |||
19 | #define DONT_TEST_IN_ITBLOCK(tests) \ | ||
20 | kprobe_test_flags |= TEST_FLAG_NO_ITBLOCK; \ | ||
21 | tests \ | ||
22 | kprobe_test_flags &= ~TEST_FLAG_NO_ITBLOCK; | ||
23 | |||
24 | #define CONDITION_INSTRUCTIONS(cc_pos, tests) \ | ||
25 | kprobe_test_cc_position = cc_pos; \ | ||
26 | DONT_TEST_IN_ITBLOCK(tests) \ | ||
27 | kprobe_test_cc_position = 0; | ||
28 | |||
29 | #define TEST_ITBLOCK(code) \ | ||
30 | kprobe_test_flags |= TEST_FLAG_FULL_ITBLOCK; \ | ||
31 | TESTCASE_START(code) \ | ||
32 | TEST_ARG_END("") \ | ||
33 | "50: nop \n\t" \ | ||
34 | "1: "code" \n\t" \ | ||
35 | " mov r1, #0x11 \n\t" \ | ||
36 | " mov r2, #0x22 \n\t" \ | ||
37 | " mov r3, #0x33 \n\t" \ | ||
38 | "2: nop \n\t" \ | ||
39 | TESTCASE_END \ | ||
40 | kprobe_test_flags &= ~TEST_FLAG_FULL_ITBLOCK; | ||
41 | |||
42 | #define TEST_THUMB_TO_ARM_INTERWORK_P(code1, reg, val, code2) \ | ||
43 | TESTCASE_START(code1 #reg code2) \ | ||
44 | TEST_ARG_PTR(reg, val) \ | ||
45 | TEST_ARG_REG(14, 99f+1) \ | ||
46 | TEST_ARG_MEM(15, 3f) \ | ||
47 | TEST_ARG_END("") \ | ||
48 | " nop \n\t" /* To align 1f */ \ | ||
49 | "50: nop \n\t" \ | ||
50 | "1: "code1 #reg code2" \n\t" \ | ||
51 | " bx lr \n\t" \ | ||
52 | ".arm \n\t" \ | ||
53 | "3: adr lr, 2f+1 \n\t" \ | ||
54 | " bx lr \n\t" \ | ||
55 | ".thumb \n\t" \ | ||
56 | "2: nop \n\t" \ | ||
57 | TESTCASE_END | ||
58 | |||
59 | |||
60 | void kprobe_thumb16_test_cases(void) | ||
61 | { | ||
62 | kprobe_test_flags = TEST_FLAG_NARROW_INSTR; | ||
63 | |||
64 | TEST_GROUP("Shift (immediate), add, subtract, move, and compare") | ||
65 | |||
66 | TEST_R( "lsls r7, r",0,VAL1,", #5") | ||
67 | TEST_R( "lsls r0, r",7,VAL2,", #11") | ||
68 | TEST_R( "lsrs r7, r",0,VAL1,", #5") | ||
69 | TEST_R( "lsrs r0, r",7,VAL2,", #11") | ||
70 | TEST_R( "asrs r7, r",0,VAL1,", #5") | ||
71 | TEST_R( "asrs r0, r",7,VAL2,", #11") | ||
72 | TEST_RR( "adds r2, r",0,VAL1,", r",7,VAL2,"") | ||
73 | TEST_RR( "adds r5, r",7,VAL2,", r",0,VAL2,"") | ||
74 | TEST_RR( "subs r2, r",0,VAL1,", r",7,VAL2,"") | ||
75 | TEST_RR( "subs r5, r",7,VAL2,", r",0,VAL2,"") | ||
76 | TEST_R( "adds r7, r",0,VAL1,", #5") | ||
77 | TEST_R( "adds r0, r",7,VAL2,", #2") | ||
78 | TEST_R( "subs r7, r",0,VAL1,", #5") | ||
79 | TEST_R( "subs r0, r",7,VAL2,", #2") | ||
80 | TEST( "movs.n r0, #0x5f") | ||
81 | TEST( "movs.n r7, #0xa0") | ||
82 | TEST_R( "cmp.n r",0,0x5e, ", #0x5f") | ||
83 | TEST_R( "cmp.n r",5,0x15f,", #0x5f") | ||
84 | TEST_R( "cmp.n r",7,0xa0, ", #0xa0") | ||
85 | TEST_R( "adds.n r",0,VAL1,", #0x5f") | ||
86 | TEST_R( "adds.n r",7,VAL2,", #0xa0") | ||
87 | TEST_R( "subs.n r",0,VAL1,", #0x5f") | ||
88 | TEST_R( "subs.n r",7,VAL2,", #0xa0") | ||
89 | |||
90 | TEST_GROUP("16-bit Thumb data-processing instructions") | ||
91 | |||
92 | #define DATA_PROCESSING16(op,val) \ | ||
93 | TEST_RR( op" r",0,VAL1,", r",7,val,"") \ | ||
94 | TEST_RR( op" r",7,VAL2,", r",0,val,"") | ||
95 | |||
96 | DATA_PROCESSING16("ands",0xf00f00ff) | ||
97 | DATA_PROCESSING16("eors",0xf00f00ff) | ||
98 | DATA_PROCESSING16("lsls",11) | ||
99 | DATA_PROCESSING16("lsrs",11) | ||
100 | DATA_PROCESSING16("asrs",11) | ||
101 | DATA_PROCESSING16("adcs",VAL2) | ||
102 | DATA_PROCESSING16("sbcs",VAL2) | ||
103 | DATA_PROCESSING16("rors",11) | ||
104 | DATA_PROCESSING16("tst",0xf00f00ff) | ||
105 | TEST_R("rsbs r",0,VAL1,", #0") | ||
106 | TEST_R("rsbs r",7,VAL2,", #0") | ||
107 | DATA_PROCESSING16("cmp",0xf00f00ff) | ||
108 | DATA_PROCESSING16("cmn",0xf00f00ff) | ||
109 | DATA_PROCESSING16("orrs",0xf00f00ff) | ||
110 | DATA_PROCESSING16("muls",VAL2) | ||
111 | DATA_PROCESSING16("bics",0xf00f00ff) | ||
112 | DATA_PROCESSING16("mvns",VAL2) | ||
113 | |||
114 | TEST_GROUP("Special data instructions and branch and exchange") | ||
115 | |||
116 | TEST_RR( "add r",0, VAL1,", r",7,VAL2,"") | ||
117 | TEST_RR( "add r",3, VAL2,", r",8,VAL3,"") | ||
118 | TEST_RR( "add r",8, VAL3,", r",0,VAL1,"") | ||
119 | TEST_R( "add sp" ", r",8,-8, "") | ||
120 | TEST_R( "add r",14,VAL1,", pc") | ||
121 | TEST_BF_R("add pc" ", r",0,2f-1f-8,"") | ||
122 | TEST_UNSUPPORTED(".short 0x44ff @ add pc, pc") | ||
123 | |||
124 | TEST_RR( "cmp r",3,VAL1,", r",8,VAL2,"") | ||
125 | TEST_RR( "cmp r",8,VAL2,", r",0,VAL1,"") | ||
126 | TEST_R( "cmp sp" ", r",8,-8, "") | ||
127 | |||
128 | TEST_R( "mov r0, r",7,VAL2,"") | ||
129 | TEST_R( "mov r3, r",8,VAL3,"") | ||
130 | TEST_R( "mov r8, r",0,VAL1,"") | ||
131 | TEST_P( "mov sp, r",8,-8, "") | ||
132 | TEST( "mov lr, pc") | ||
133 | TEST_BF_R("mov pc, r",0,2f, "") | ||
134 | |||
135 | TEST_BF_R("bx r",0, 2f+1,"") | ||
136 | TEST_BF_R("bx r",14,2f+1,"") | ||
137 | TESTCASE_START("bx pc") | ||
138 | TEST_ARG_REG(14, 99f+1) | ||
139 | TEST_ARG_END("") | ||
140 | " nop \n\t" /* To align the bx pc*/ | ||
141 | "50: nop \n\t" | ||
142 | "1: bx pc \n\t" | ||
143 | " bx lr \n\t" | ||
144 | ".arm \n\t" | ||
145 | " adr lr, 2f+1 \n\t" | ||
146 | " bx lr \n\t" | ||
147 | ".thumb \n\t" | ||
148 | "2: nop \n\t" | ||
149 | TESTCASE_END | ||
150 | |||
151 | TEST_BF_R("blx r",0, 2f+1,"") | ||
152 | TEST_BB_R("blx r",14,2f+1,"") | ||
153 | TEST_UNSUPPORTED(".short 0x47f8 @ blx pc") | ||
154 | |||
155 | TEST_GROUP("Load from Literal Pool") | ||
156 | |||
157 | TEST_X( "ldr r0, 3f", | ||
158 | ".align \n\t" | ||
159 | "3: .word "__stringify(VAL1)) | ||
160 | TEST_X( "ldr r7, 3f", | ||
161 | ".space 128 \n\t" | ||
162 | ".align \n\t" | ||
163 | "3: .word "__stringify(VAL2)) | ||
164 | |||
165 | TEST_GROUP("16-bit Thumb Load/store instructions") | ||
166 | |||
167 | TEST_RPR("str r",0, VAL1,", [r",1, 24,", r",2, 48,"]") | ||
168 | TEST_RPR("str r",7, VAL2,", [r",6, 24,", r",5, 48,"]") | ||
169 | TEST_RPR("strh r",0, VAL1,", [r",1, 24,", r",2, 48,"]") | ||
170 | TEST_RPR("strh r",7, VAL2,", [r",6, 24,", r",5, 48,"]") | ||
171 | TEST_RPR("strb r",0, VAL1,", [r",1, 24,", r",2, 48,"]") | ||
172 | TEST_RPR("strb r",7, VAL2,", [r",6, 24,", r",5, 48,"]") | ||
173 | TEST_PR( "ldrsb r0, [r",1, 24,", r",2, 48,"]") | ||
174 | TEST_PR( "ldrsb r7, [r",6, 24,", r",5, 50,"]") | ||
175 | TEST_PR( "ldr r0, [r",1, 24,", r",2, 48,"]") | ||
176 | TEST_PR( "ldr r7, [r",6, 24,", r",5, 48,"]") | ||
177 | TEST_PR( "ldrh r0, [r",1, 24,", r",2, 48,"]") | ||
178 | TEST_PR( "ldrh r7, [r",6, 24,", r",5, 50,"]") | ||
179 | TEST_PR( "ldrb r0, [r",1, 24,", r",2, 48,"]") | ||
180 | TEST_PR( "ldrb r7, [r",6, 24,", r",5, 50,"]") | ||
181 | TEST_PR( "ldrsh r0, [r",1, 24,", r",2, 48,"]") | ||
182 | TEST_PR( "ldrsh r7, [r",6, 24,", r",5, 50,"]") | ||
183 | |||
184 | TEST_RP("str r",0, VAL1,", [r",1, 24,", #120]") | ||
185 | TEST_RP("str r",7, VAL2,", [r",6, 24,", #120]") | ||
186 | TEST_P( "ldr r0, [r",1, 24,", #120]") | ||
187 | TEST_P( "ldr r7, [r",6, 24,", #120]") | ||
188 | TEST_RP("strb r",0, VAL1,", [r",1, 24,", #30]") | ||
189 | TEST_RP("strb r",7, VAL2,", [r",6, 24,", #30]") | ||
190 | TEST_P( "ldrb r0, [r",1, 24,", #30]") | ||
191 | TEST_P( "ldrb r7, [r",6, 24,", #30]") | ||
192 | TEST_RP("strh r",0, VAL1,", [r",1, 24,", #60]") | ||
193 | TEST_RP("strh r",7, VAL2,", [r",6, 24,", #60]") | ||
194 | TEST_P( "ldrh r0, [r",1, 24,", #60]") | ||
195 | TEST_P( "ldrh r7, [r",6, 24,", #60]") | ||
196 | |||
197 | TEST_R( "str r",0, VAL1,", [sp, #0]") | ||
198 | TEST_R( "str r",7, VAL2,", [sp, #160]") | ||
199 | TEST( "ldr r0, [sp, #0]") | ||
200 | TEST( "ldr r7, [sp, #160]") | ||
201 | |||
202 | TEST_RP("str r",0, VAL1,", [r",0, 24,"]") | ||
203 | TEST_P( "ldr r0, [r",0, 24,"]") | ||
204 | |||
205 | TEST_GROUP("Generate PC-/SP-relative address") | ||
206 | |||
207 | TEST("add r0, pc, #4") | ||
208 | TEST("add r7, pc, #1020") | ||
209 | TEST("add r0, sp, #4") | ||
210 | TEST("add r7, sp, #1020") | ||
211 | |||
212 | TEST_GROUP("Miscellaneous 16-bit instructions") | ||
213 | |||
214 | TEST_UNSUPPORTED( "cpsie i") | ||
215 | TEST_UNSUPPORTED( "cpsid i") | ||
216 | TEST_UNSUPPORTED( "setend le") | ||
217 | TEST_UNSUPPORTED( "setend be") | ||
218 | |||
219 | TEST("add sp, #"__stringify(TEST_MEMORY_SIZE)) /* Assumes TEST_MEMORY_SIZE < 0x400 */ | ||
220 | TEST("sub sp, #0x7f*4") | ||
221 | |||
222 | DONT_TEST_IN_ITBLOCK( | ||
223 | TEST_BF_R( "cbnz r",0,0, ", 2f") | ||
224 | TEST_BF_R( "cbz r",2,-1,", 2f") | ||
225 | TEST_BF_RX( "cbnz r",4,1, ", 2f",0x20) | ||
226 | TEST_BF_RX( "cbz r",7,0, ", 2f",0x40) | ||
227 | ) | ||
228 | TEST_R("sxth r0, r",7, HH1,"") | ||
229 | TEST_R("sxth r7, r",0, HH2,"") | ||
230 | TEST_R("sxtb r0, r",7, HH1,"") | ||
231 | TEST_R("sxtb r7, r",0, HH2,"") | ||
232 | TEST_R("uxth r0, r",7, HH1,"") | ||
233 | TEST_R("uxth r7, r",0, HH2,"") | ||
234 | TEST_R("uxtb r0, r",7, HH1,"") | ||
235 | TEST_R("uxtb r7, r",0, HH2,"") | ||
236 | TEST_R("rev r0, r",7, VAL1,"") | ||
237 | TEST_R("rev r7, r",0, VAL2,"") | ||
238 | TEST_R("rev16 r0, r",7, VAL1,"") | ||
239 | TEST_R("rev16 r7, r",0, VAL2,"") | ||
240 | TEST_UNSUPPORTED(".short 0xba80") | ||
241 | TEST_UNSUPPORTED(".short 0xbabf") | ||
242 | TEST_R("revsh r0, r",7, VAL1,"") | ||
243 | TEST_R("revsh r7, r",0, VAL2,"") | ||
244 | |||
245 | #define TEST_POPPC(code, offset) \ | ||
246 | TESTCASE_START(code) \ | ||
247 | TEST_ARG_PTR(13, offset) \ | ||
248 | TEST_ARG_END("") \ | ||
249 | TEST_BRANCH_F(code,0) \ | ||
250 | TESTCASE_END | ||
251 | |||
252 | TEST("push {r0}") | ||
253 | TEST("push {r7}") | ||
254 | TEST("push {r14}") | ||
255 | TEST("push {r0-r7,r14}") | ||
256 | TEST("push {r0,r2,r4,r6,r14}") | ||
257 | TEST("push {r1,r3,r5,r7}") | ||
258 | TEST("pop {r0}") | ||
259 | TEST("pop {r7}") | ||
260 | TEST("pop {r0,r2,r4,r6}") | ||
261 | TEST_POPPC("pop {pc}",15*4) | ||
262 | TEST_POPPC("pop {r0-r7,pc}",7*4) | ||
263 | TEST_POPPC("pop {r1,r3,r5,r7,pc}",11*4) | ||
264 | TEST_THUMB_TO_ARM_INTERWORK_P("pop {pc} @ ",13,15*4,"") | ||
265 | TEST_THUMB_TO_ARM_INTERWORK_P("pop {r0-r7,pc} @ ",13,7*4,"") | ||
266 | |||
267 | TEST_UNSUPPORTED("bkpt.n 0") | ||
268 | TEST_UNSUPPORTED("bkpt.n 255") | ||
269 | |||
270 | TEST_SUPPORTED("yield") | ||
271 | TEST("sev") | ||
272 | TEST("nop") | ||
273 | TEST("wfi") | ||
274 | TEST_SUPPORTED("wfe") | ||
275 | TEST_UNSUPPORTED(".short 0xbf50") /* Unassigned hints */ | ||
276 | TEST_UNSUPPORTED(".short 0xbff0") /* Unassigned hints */ | ||
277 | |||
278 | #define TEST_IT(code, code2) \ | ||
279 | TESTCASE_START(code) \ | ||
280 | TEST_ARG_END("") \ | ||
281 | "50: nop \n\t" \ | ||
282 | "1: "code" \n\t" \ | ||
283 | " "code2" \n\t" \ | ||
284 | "2: nop \n\t" \ | ||
285 | TESTCASE_END | ||
286 | |||
287 | DONT_TEST_IN_ITBLOCK( | ||
288 | TEST_IT("it eq","moveq r0,#0") | ||
289 | TEST_IT("it vc","movvc r0,#0") | ||
290 | TEST_IT("it le","movle r0,#0") | ||
291 | TEST_IT("ite eq","moveq r0,#0\n\t movne r1,#1") | ||
292 | TEST_IT("itet vc","movvc r0,#0\n\t movvs r1,#1\n\t movvc r2,#2") | ||
293 | TEST_IT("itete le","movle r0,#0\n\t movgt r1,#1\n\t movle r2,#2\n\t movgt r3,#3") | ||
294 | TEST_IT("itttt le","movle r0,#0\n\t movle r1,#1\n\t movle r2,#2\n\t movle r3,#3") | ||
295 | TEST_IT("iteee le","movle r0,#0\n\t movgt r1,#1\n\t movgt r2,#2\n\t movgt r3,#3") | ||
296 | ) | ||
297 | |||
298 | TEST_GROUP("Load and store multiple") | ||
299 | |||
300 | TEST_P("ldmia r",4, 16*4,"!, {r0,r7}") | ||
301 | TEST_P("ldmia r",7, 16*4,"!, {r0-r6}") | ||
302 | TEST_P("stmia r",4, 16*4,"!, {r0,r7}") | ||
303 | TEST_P("stmia r",0, 16*4,"!, {r0-r7}") | ||
304 | |||
305 | TEST_GROUP("Conditional branch and Supervisor Call instructions") | ||
306 | |||
307 | CONDITION_INSTRUCTIONS(8, | ||
308 | TEST_BF("beq 2f") | ||
309 | TEST_BB("bne 2b") | ||
310 | TEST_BF("bgt 2f") | ||
311 | TEST_BB("blt 2b") | ||
312 | ) | ||
313 | TEST_UNSUPPORTED(".short 0xde00") | ||
314 | TEST_UNSUPPORTED(".short 0xdeff") | ||
315 | TEST_UNSUPPORTED("svc #0x00") | ||
316 | TEST_UNSUPPORTED("svc #0xff") | ||
317 | |||
318 | TEST_GROUP("Unconditional branch") | ||
319 | |||
320 | TEST_BF( "b 2f") | ||
321 | TEST_BB( "b 2b") | ||
322 | TEST_BF_X("b 2f", 0x400) | ||
323 | TEST_BB_X("b 2b", 0x400) | ||
324 | |||
325 | TEST_GROUP("Testing instructions in IT blocks") | ||
326 | |||
327 | TEST_ITBLOCK("subs.n r0, r0") | ||
328 | |||
329 | verbose("\n"); | ||
330 | } | ||
331 | |||
332 | |||
333 | void kprobe_thumb32_test_cases(void) | ||
334 | { | ||
335 | kprobe_test_flags = 0; | ||
336 | |||
337 | TEST_GROUP("Load/store multiple") | ||
338 | |||
339 | TEST_UNSUPPORTED("rfedb sp") | ||
340 | TEST_UNSUPPORTED("rfeia sp") | ||
341 | TEST_UNSUPPORTED("rfedb sp!") | ||
342 | TEST_UNSUPPORTED("rfeia sp!") | ||
343 | |||
344 | TEST_P( "stmia r",0, 16*4,", {r0,r8}") | ||
345 | TEST_P( "stmia r",4, 16*4,", {r0-r12,r14}") | ||
346 | TEST_P( "stmia r",7, 16*4,"!, {r8-r12,r14}") | ||
347 | TEST_P( "stmia r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") | ||
348 | |||
349 | TEST_P( "ldmia r",0, 16*4,", {r0,r8}") | ||
350 | TEST_P( "ldmia r",4, 0, ", {r0-r12,r14}") | ||
351 | TEST_BF_P("ldmia r",5, 8*4, "!, {r6-r12,r15}") | ||
352 | TEST_P( "ldmia r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") | ||
353 | TEST_BF_P("ldmia r",14,14*4,"!, {r4,pc}") | ||
354 | |||
355 | TEST_P( "stmdb r",0, 16*4,", {r0,r8}") | ||
356 | TEST_P( "stmdb r",4, 16*4,", {r0-r12,r14}") | ||
357 | TEST_P( "stmdb r",5, 16*4,"!, {r8-r12,r14}") | ||
358 | TEST_P( "stmdb r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") | ||
359 | |||
360 | TEST_P( "ldmdb r",0, 16*4,", {r0,r8}") | ||
361 | TEST_P( "ldmdb r",4, 16*4,", {r0-r12,r14}") | ||
362 | TEST_BF_P("ldmdb r",5, 16*4,"!, {r6-r12,r15}") | ||
363 | TEST_P( "ldmdb r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") | ||
364 | TEST_BF_P("ldmdb r",14,16*4,"!, {r4,pc}") | ||
365 | |||
366 | TEST_P( "stmdb r",13,16*4,"!, {r3-r12,lr}") | ||
367 | TEST_P( "stmdb r",13,16*4,"!, {r3-r12}") | ||
368 | TEST_P( "stmdb r",2, 16*4,", {r3-r12,lr}") | ||
369 | TEST_P( "stmdb r",13,16*4,"!, {r2-r12,lr}") | ||
370 | TEST_P( "stmdb r",0, 16*4,", {r0-r12}") | ||
371 | TEST_P( "stmdb r",0, 16*4,", {r0-r12,lr}") | ||
372 | |||
373 | TEST_BF_P("ldmia r",13,5*4, "!, {r3-r12,pc}") | ||
374 | TEST_P( "ldmia r",13,5*4, "!, {r3-r12}") | ||
375 | TEST_BF_P("ldmia r",2, 5*4, "!, {r3-r12,pc}") | ||
376 | TEST_BF_P("ldmia r",13,4*4, "!, {r2-r12,pc}") | ||
377 | TEST_P( "ldmia r",0, 16*4,", {r0-r12}") | ||
378 | TEST_P( "ldmia r",0, 16*4,", {r0-r12,lr}") | ||
379 | |||
380 | TEST_THUMB_TO_ARM_INTERWORK_P("ldmia r",0,14*4,", {r12,pc}") | ||
381 | TEST_THUMB_TO_ARM_INTERWORK_P("ldmia r",13,2*4,", {r0-r12,pc}") | ||
382 | |||
383 | TEST_UNSUPPORTED(".short 0xe88f,0x0101 @ stmia pc, {r0,r8}") | ||
384 | TEST_UNSUPPORTED(".short 0xe92f,0x5f00 @ stmdb pc!, {r8-r12,r14}") | ||
385 | TEST_UNSUPPORTED(".short 0xe8bd,0xc000 @ ldmia r13!, {r14,pc}") | ||
386 | TEST_UNSUPPORTED(".short 0xe93e,0xc000 @ ldmdb r14!, {r14,pc}") | ||
387 | TEST_UNSUPPORTED(".short 0xe8a7,0x3f00 @ stmia r7!, {r8-r12,sp}") | ||
388 | TEST_UNSUPPORTED(".short 0xe8a7,0x9f00 @ stmia r7!, {r8-r12,pc}") | ||
389 | TEST_UNSUPPORTED(".short 0xe93e,0x2010 @ ldmdb r14!, {r4,sp}") | ||
390 | |||
391 | TEST_GROUP("Load/store double or exclusive, table branch") | ||
392 | |||
393 | TEST_P( "ldrd r0, r1, [r",1, 24,", #-16]") | ||
394 | TEST( "ldrd r12, r14, [sp, #16]") | ||
395 | TEST_P( "ldrd r1, r0, [r",7, 24,", #-16]!") | ||
396 | TEST( "ldrd r14, r12, [sp, #16]!") | ||
397 | TEST_P( "ldrd r1, r0, [r",7, 24,"], #16") | ||
398 | TEST( "ldrd r7, r8, [sp], #-16") | ||
399 | |||
400 | TEST_X( "ldrd r12, r14, 3f", | ||
401 | ".align 3 \n\t" | ||
402 | "3: .word "__stringify(VAL1)" \n\t" | ||
403 | " .word "__stringify(VAL2)) | ||
404 | |||
405 | TEST_UNSUPPORTED(".short 0xe9ff,0xec04 @ ldrd r14, r12, [pc, #16]!") | ||
406 | TEST_UNSUPPORTED(".short 0xe8ff,0xec04 @ ldrd r14, r12, [pc], #16") | ||
407 | TEST_UNSUPPORTED(".short 0xe9d4,0xd800 @ ldrd sp, r8, [r4]") | ||
408 | TEST_UNSUPPORTED(".short 0xe9d4,0xf800 @ ldrd pc, r8, [r4]") | ||
409 | TEST_UNSUPPORTED(".short 0xe9d4,0x7d00 @ ldrd r7, sp, [r4]") | ||
410 | TEST_UNSUPPORTED(".short 0xe9d4,0x7f00 @ ldrd r7, pc, [r4]") | ||
411 | |||
412 | TEST_RRP("strd r",0, VAL1,", r",1, VAL2,", [r",1, 24,", #-16]") | ||
413 | TEST_RR( "strd r",12,VAL2,", r",14,VAL1,", [sp, #16]") | ||
414 | TEST_RRP("strd r",1, VAL1,", r",0, VAL2,", [r",7, 24,", #-16]!") | ||
415 | TEST_RR( "strd r",14,VAL2,", r",12,VAL1,", [sp, #16]!") | ||
416 | TEST_RRP("strd r",1, VAL1,", r",0, VAL2,", [r",7, 24,"], #16") | ||
417 | TEST_RR( "strd r",7, VAL2,", r",8, VAL1,", [sp], #-16") | ||
418 | TEST_UNSUPPORTED(".short 0xe9ef,0xec04 @ strd r14, r12, [pc, #16]!") | ||
419 | TEST_UNSUPPORTED(".short 0xe8ef,0xec04 @ strd r14, r12, [pc], #16") | ||
420 | |||
421 | TEST_RX("tbb [pc, r",0, (9f-(1f+4)),"]", | ||
422 | "9: \n\t" | ||
423 | ".byte (2f-1b-4)>>1 \n\t" | ||
424 | ".byte (3f-1b-4)>>1 \n\t" | ||
425 | "3: mvn r0, r0 \n\t" | ||
426 | "2: nop \n\t") | ||
427 | |||
428 | TEST_RX("tbb [pc, r",4, (9f-(1f+4)+1),"]", | ||
429 | "9: \n\t" | ||
430 | ".byte (2f-1b-4)>>1 \n\t" | ||
431 | ".byte (3f-1b-4)>>1 \n\t" | ||
432 | "3: mvn r0, r0 \n\t" | ||
433 | "2: nop \n\t") | ||
434 | |||
435 | TEST_RRX("tbb [r",1,9f,", r",2,0,"]", | ||
436 | "9: \n\t" | ||
437 | ".byte (2f-1b-4)>>1 \n\t" | ||
438 | ".byte (3f-1b-4)>>1 \n\t" | ||
439 | "3: mvn r0, r0 \n\t" | ||
440 | "2: nop \n\t") | ||
441 | |||
442 | TEST_RX("tbh [pc, r",7, (9f-(1f+4))>>1,"]", | ||
443 | "9: \n\t" | ||
444 | ".short (2f-1b-4)>>1 \n\t" | ||
445 | ".short (3f-1b-4)>>1 \n\t" | ||
446 | "3: mvn r0, r0 \n\t" | ||
447 | "2: nop \n\t") | ||
448 | |||
449 | TEST_RX("tbh [pc, r",12, ((9f-(1f+4))>>1)+1,"]", | ||
450 | "9: \n\t" | ||
451 | ".short (2f-1b-4)>>1 \n\t" | ||
452 | ".short (3f-1b-4)>>1 \n\t" | ||
453 | "3: mvn r0, r0 \n\t" | ||
454 | "2: nop \n\t") | ||
455 | |||
456 | TEST_RRX("tbh [r",1,9f, ", r",14,1,"]", | ||
457 | "9: \n\t" | ||
458 | ".short (2f-1b-4)>>1 \n\t" | ||
459 | ".short (3f-1b-4)>>1 \n\t" | ||
460 | "3: mvn r0, r0 \n\t" | ||
461 | "2: nop \n\t") | ||
462 | |||
463 | TEST_UNSUPPORTED(".short 0xe8d1,0xf01f @ tbh [r1, pc]") | ||
464 | TEST_UNSUPPORTED(".short 0xe8d1,0xf01d @ tbh [r1, sp]") | ||
465 | TEST_UNSUPPORTED(".short 0xe8dd,0xf012 @ tbh [sp, r2]") | ||
466 | |||
467 | TEST_UNSUPPORTED("strexb r0, r1, [r2]") | ||
468 | TEST_UNSUPPORTED("strexh r0, r1, [r2]") | ||
469 | TEST_UNSUPPORTED("strexd r0, r1, [r2]") | ||
470 | TEST_UNSUPPORTED("ldrexb r0, [r1]") | ||
471 | TEST_UNSUPPORTED("ldrexh r0, [r1]") | ||
472 | TEST_UNSUPPORTED("ldrexd r0, [r1]") | ||
473 | |||
474 | TEST_GROUP("Data-processing (shifted register) and (modified immediate)") | ||
475 | |||
476 | #define _DATA_PROCESSING32_DNM(op,s,val) \ | ||
477 | TEST_RR(op s".w r0, r",1, VAL1,", r",2, val, "") \ | ||
478 | TEST_RR(op s" r1, r",1, VAL1,", r",2, val, ", lsl #3") \ | ||
479 | TEST_RR(op s" r2, r",3, VAL1,", r",2, val, ", lsr #4") \ | ||
480 | TEST_RR(op s" r3, r",3, VAL1,", r",2, val, ", asr #5") \ | ||
481 | TEST_RR(op s" r4, r",5, VAL1,", r",2, N(val),", asr #6") \ | ||
482 | TEST_RR(op s" r5, r",5, VAL1,", r",2, val, ", ror #7") \ | ||
483 | TEST_RR(op s" r8, r",9, VAL1,", r",10,val, ", rrx") \ | ||
484 | TEST_R( op s" r0, r",11,VAL1,", #0x00010001") \ | ||
485 | TEST_R( op s" r11, r",0, VAL1,", #0xf5000000") \ | ||
486 | TEST_R( op s" r7, r",8, VAL2,", #0x000af000") | ||
487 | |||
488 | #define DATA_PROCESSING32_DNM(op,val) \ | ||
489 | _DATA_PROCESSING32_DNM(op,"",val) \ | ||
490 | _DATA_PROCESSING32_DNM(op,"s",val) | ||
491 | |||
492 | #define DATA_PROCESSING32_NM(op,val) \ | ||
493 | TEST_RR(op".w r",1, VAL1,", r",2, val, "") \ | ||
494 | TEST_RR(op" r",1, VAL1,", r",2, val, ", lsl #3") \ | ||
495 | TEST_RR(op" r",3, VAL1,", r",2, val, ", lsr #4") \ | ||
496 | TEST_RR(op" r",3, VAL1,", r",2, val, ", asr #5") \ | ||
497 | TEST_RR(op" r",5, VAL1,", r",2, N(val),", asr #6") \ | ||
498 | TEST_RR(op" r",5, VAL1,", r",2, val, ", ror #7") \ | ||
499 | TEST_RR(op" r",9, VAL1,", r",10,val, ", rrx") \ | ||
500 | TEST_R( op" r",11,VAL1,", #0x00010001") \ | ||
501 | TEST_R( op" r",0, VAL1,", #0xf5000000") \ | ||
502 | TEST_R( op" r",8, VAL2,", #0x000af000") | ||
503 | |||
504 | #define _DATA_PROCESSING32_DM(op,s,val) \ | ||
505 | TEST_R( op s".w r0, r",14, val, "") \ | ||
506 | TEST_R( op s" r1, r",12, val, ", lsl #3") \ | ||
507 | TEST_R( op s" r2, r",11, val, ", lsr #4") \ | ||
508 | TEST_R( op s" r3, r",10, val, ", asr #5") \ | ||
509 | TEST_R( op s" r4, r",9, N(val),", asr #6") \ | ||
510 | TEST_R( op s" r5, r",8, val, ", ror #7") \ | ||
511 | TEST_R( op s" r8, r",7,val, ", rrx") \ | ||
512 | TEST( op s" r0, #0x00010001") \ | ||
513 | TEST( op s" r11, #0xf5000000") \ | ||
514 | TEST( op s" r7, #0x000af000") \ | ||
515 | TEST( op s" r4, #0x00005a00") | ||
516 | |||
517 | #define DATA_PROCESSING32_DM(op,val) \ | ||
518 | _DATA_PROCESSING32_DM(op,"",val) \ | ||
519 | _DATA_PROCESSING32_DM(op,"s",val) | ||
520 | |||
521 | DATA_PROCESSING32_DNM("and",0xf00f00ff) | ||
522 | DATA_PROCESSING32_NM("tst",0xf00f00ff) | ||
523 | DATA_PROCESSING32_DNM("bic",0xf00f00ff) | ||
524 | DATA_PROCESSING32_DNM("orr",0xf00f00ff) | ||
525 | DATA_PROCESSING32_DM("mov",VAL2) | ||
526 | DATA_PROCESSING32_DNM("orn",0xf00f00ff) | ||
527 | DATA_PROCESSING32_DM("mvn",VAL2) | ||
528 | DATA_PROCESSING32_DNM("eor",0xf00f00ff) | ||
529 | DATA_PROCESSING32_NM("teq",0xf00f00ff) | ||
530 | DATA_PROCESSING32_DNM("add",VAL2) | ||
531 | DATA_PROCESSING32_NM("cmn",VAL2) | ||
532 | DATA_PROCESSING32_DNM("adc",VAL2) | ||
533 | DATA_PROCESSING32_DNM("sbc",VAL2) | ||
534 | DATA_PROCESSING32_DNM("sub",VAL2) | ||
535 | DATA_PROCESSING32_NM("cmp",VAL2) | ||
536 | DATA_PROCESSING32_DNM("rsb",VAL2) | ||
537 | |||
538 | TEST_RR("pkhbt r0, r",0, HH1,", r",1, HH2,"") | ||
539 | TEST_RR("pkhbt r14,r",12, HH1,", r",10,HH2,", lsl #2") | ||
540 | TEST_RR("pkhtb r0, r",0, HH1,", r",1, HH2,"") | ||
541 | TEST_RR("pkhtb r14,r",12, HH1,", r",10,HH2,", asr #2") | ||
542 | |||
543 | TEST_UNSUPPORTED(".short 0xea17,0x0f0d @ tst.w r7, sp") | ||
544 | TEST_UNSUPPORTED(".short 0xea17,0x0f0f @ tst.w r7, pc") | ||
545 | TEST_UNSUPPORTED(".short 0xea1d,0x0f07 @ tst.w sp, r7") | ||
546 | TEST_UNSUPPORTED(".short 0xea1f,0x0f07 @ tst.w pc, r7") | ||
547 | TEST_UNSUPPORTED(".short 0xf01d,0x1f08 @ tst sp, #0x00080008") | ||
548 | TEST_UNSUPPORTED(".short 0xf01f,0x1f08 @ tst pc, #0x00080008") | ||
549 | |||
550 | TEST_UNSUPPORTED(".short 0xea97,0x0f0d @ teq.w r7, sp") | ||
551 | TEST_UNSUPPORTED(".short 0xea97,0x0f0f @ teq.w r7, pc") | ||
552 | TEST_UNSUPPORTED(".short 0xea9d,0x0f07 @ teq.w sp, r7") | ||
553 | TEST_UNSUPPORTED(".short 0xea9f,0x0f07 @ teq.w pc, r7") | ||
554 | TEST_UNSUPPORTED(".short 0xf09d,0x1f08 @ tst sp, #0x00080008") | ||
555 | TEST_UNSUPPORTED(".short 0xf09f,0x1f08 @ tst pc, #0x00080008") | ||
556 | |||
557 | TEST_UNSUPPORTED(".short 0xeb17,0x0f0d @ cmn.w r7, sp") | ||
558 | TEST_UNSUPPORTED(".short 0xeb17,0x0f0f @ cmn.w r7, pc") | ||
559 | TEST_P("cmn.w sp, r",7,0,"") | ||
560 | TEST_UNSUPPORTED(".short 0xeb1f,0x0f07 @ cmn.w pc, r7") | ||
561 | TEST( "cmn sp, #0x00080008") | ||
562 | TEST_UNSUPPORTED(".short 0xf11f,0x1f08 @ cmn pc, #0x00080008") | ||
563 | |||
564 | TEST_UNSUPPORTED(".short 0xebb7,0x0f0d @ cmp.w r7, sp") | ||
565 | TEST_UNSUPPORTED(".short 0xebb7,0x0f0f @ cmp.w r7, pc") | ||
566 | TEST_P("cmp.w sp, r",7,0,"") | ||
567 | TEST_UNSUPPORTED(".short 0xebbf,0x0f07 @ cmp.w pc, r7") | ||
568 | TEST( "cmp sp, #0x00080008") | ||
569 | TEST_UNSUPPORTED(".short 0xf1bf,0x1f08 @ cmp pc, #0x00080008") | ||
570 | |||
571 | TEST_UNSUPPORTED(".short 0xea5f,0x070d @ movs.w r7, sp") | ||
572 | TEST_UNSUPPORTED(".short 0xea5f,0x070f @ movs.w r7, pc") | ||
573 | TEST_UNSUPPORTED(".short 0xea5f,0x0d07 @ movs.w sp, r7") | ||
574 | TEST_UNSUPPORTED(".short 0xea4f,0x0f07 @ mov.w pc, r7") | ||
575 | TEST_UNSUPPORTED(".short 0xf04f,0x1d08 @ mov sp, #0x00080008") | ||
576 | TEST_UNSUPPORTED(".short 0xf04f,0x1f08 @ mov pc, #0x00080008") | ||
577 | |||
578 | TEST_R("add.w r0, sp, r",1, 4,"") | ||
579 | TEST_R("adds r0, sp, r",1, 4,", asl #3") | ||
580 | TEST_R("add r0, sp, r",1, 4,", asl #4") | ||
581 | TEST_R("add r0, sp, r",1, 16,", ror #1") | ||
582 | TEST_R("add.w sp, sp, r",1, 4,"") | ||
583 | TEST_R("add sp, sp, r",1, 4,", asl #3") | ||
584 | TEST_UNSUPPORTED(".short 0xeb0d,0x1d01 @ add sp, sp, r1, asl #4") | ||
585 | TEST_UNSUPPORTED(".short 0xeb0d,0x0d71 @ add sp, sp, r1, ror #1") | ||
586 | TEST( "add.w r0, sp, #24") | ||
587 | TEST( "add.w sp, sp, #24") | ||
588 | TEST_UNSUPPORTED(".short 0xeb0d,0x0f01 @ add pc, sp, r1") | ||
589 | TEST_UNSUPPORTED(".short 0xeb0d,0x000f @ add r0, sp, pc") | ||
590 | TEST_UNSUPPORTED(".short 0xeb0d,0x000d @ add r0, sp, sp") | ||
591 | TEST_UNSUPPORTED(".short 0xeb0d,0x0d0f @ add sp, sp, pc") | ||
592 | TEST_UNSUPPORTED(".short 0xeb0d,0x0d0d @ add sp, sp, sp") | ||
593 | |||
594 | TEST_R("sub.w r0, sp, r",1, 4,"") | ||
595 | TEST_R("subs r0, sp, r",1, 4,", asl #3") | ||
596 | TEST_R("sub r0, sp, r",1, 4,", asl #4") | ||
597 | TEST_R("sub r0, sp, r",1, 16,", ror #1") | ||
598 | TEST_R("sub.w sp, sp, r",1, 4,"") | ||
599 | TEST_R("sub sp, sp, r",1, 4,", asl #3") | ||
600 | TEST_UNSUPPORTED(".short 0xebad,0x1d01 @ sub sp, sp, r1, asl #4") | ||
601 | TEST_UNSUPPORTED(".short 0xebad,0x0d71 @ sub sp, sp, r1, ror #1") | ||
602 | TEST_UNSUPPORTED(".short 0xebad,0x0f01 @ sub pc, sp, r1") | ||
603 | TEST( "sub.w r0, sp, #24") | ||
604 | TEST( "sub.w sp, sp, #24") | ||
605 | |||
606 | TEST_UNSUPPORTED(".short 0xea02,0x010f @ and r1, r2, pc") | ||
607 | TEST_UNSUPPORTED(".short 0xea0f,0x0103 @ and r1, pc, r3") | ||
608 | TEST_UNSUPPORTED(".short 0xea02,0x0f03 @ and pc, r2, r3") | ||
609 | TEST_UNSUPPORTED(".short 0xea02,0x010d @ and r1, r2, sp") | ||
610 | TEST_UNSUPPORTED(".short 0xea0d,0x0103 @ and r1, sp, r3") | ||
611 | TEST_UNSUPPORTED(".short 0xea02,0x0d03 @ and sp, r2, r3") | ||
612 | TEST_UNSUPPORTED(".short 0xf00d,0x1108 @ and r1, sp, #0x00080008") | ||
613 | TEST_UNSUPPORTED(".short 0xf00f,0x1108 @ and r1, pc, #0x00080008") | ||
614 | TEST_UNSUPPORTED(".short 0xf002,0x1d08 @ and sp, r8, #0x00080008") | ||
615 | TEST_UNSUPPORTED(".short 0xf002,0x1f08 @ and pc, r8, #0x00080008") | ||
616 | |||
617 | TEST_UNSUPPORTED(".short 0xeb02,0x010f @ add r1, r2, pc") | ||
618 | TEST_UNSUPPORTED(".short 0xeb0f,0x0103 @ add r1, pc, r3") | ||
619 | TEST_UNSUPPORTED(".short 0xeb02,0x0f03 @ add pc, r2, r3") | ||
620 | TEST_UNSUPPORTED(".short 0xeb02,0x010d @ add r1, r2, sp") | ||
621 | TEST_SUPPORTED( ".short 0xeb0d,0x0103 @ add r1, sp, r3") | ||
622 | TEST_UNSUPPORTED(".short 0xeb02,0x0d03 @ add sp, r2, r3") | ||
623 | TEST_SUPPORTED( ".short 0xf10d,0x1108 @ add r1, sp, #0x00080008") | ||
624 | TEST_UNSUPPORTED(".short 0xf10d,0x1f08 @ add pc, sp, #0x00080008") | ||
625 | TEST_UNSUPPORTED(".short 0xf10f,0x1108 @ add r1, pc, #0x00080008") | ||
626 | TEST_UNSUPPORTED(".short 0xf102,0x1d08 @ add sp, r8, #0x00080008") | ||
627 | TEST_UNSUPPORTED(".short 0xf102,0x1f08 @ add pc, r8, #0x00080008") | ||
628 | |||
629 | TEST_UNSUPPORTED(".short 0xeaa0,0x0000") | ||
630 | TEST_UNSUPPORTED(".short 0xeaf0,0x0000") | ||
631 | TEST_UNSUPPORTED(".short 0xeb20,0x0000") | ||
632 | TEST_UNSUPPORTED(".short 0xeb80,0x0000") | ||
633 | TEST_UNSUPPORTED(".short 0xebe0,0x0000") | ||
634 | |||
635 | TEST_UNSUPPORTED(".short 0xf0a0,0x0000") | ||
636 | TEST_UNSUPPORTED(".short 0xf0c0,0x0000") | ||
637 | TEST_UNSUPPORTED(".short 0xf0f0,0x0000") | ||
638 | TEST_UNSUPPORTED(".short 0xf120,0x0000") | ||
639 | TEST_UNSUPPORTED(".short 0xf180,0x0000") | ||
640 | TEST_UNSUPPORTED(".short 0xf1e0,0x0000") | ||
641 | |||
642 | TEST_GROUP("Coprocessor instructions") | ||
643 | |||
644 | TEST_UNSUPPORTED(".short 0xec00,0x0000") | ||
645 | TEST_UNSUPPORTED(".short 0xeff0,0x0000") | ||
646 | TEST_UNSUPPORTED(".short 0xfc00,0x0000") | ||
647 | TEST_UNSUPPORTED(".short 0xfff0,0x0000") | ||
648 | |||
649 | TEST_GROUP("Data-processing (plain binary immediate)") | ||
650 | |||
651 | TEST_R("addw r0, r",1, VAL1,", #0x123") | ||
652 | TEST( "addw r14, sp, #0xf5a") | ||
653 | TEST( "addw sp, sp, #0x20") | ||
654 | TEST( "addw r7, pc, #0x888") | ||
655 | TEST_UNSUPPORTED(".short 0xf20f,0x1f20 @ addw pc, pc, #0x120") | ||
656 | TEST_UNSUPPORTED(".short 0xf20d,0x1f20 @ addw pc, sp, #0x120") | ||
657 | TEST_UNSUPPORTED(".short 0xf20f,0x1d20 @ addw sp, pc, #0x120") | ||
658 | TEST_UNSUPPORTED(".short 0xf200,0x1d20 @ addw sp, r0, #0x120") | ||
659 | |||
660 | TEST_R("subw r0, r",1, VAL1,", #0x123") | ||
661 | TEST( "subw r14, sp, #0xf5a") | ||
662 | TEST( "subw sp, sp, #0x20") | ||
663 | TEST( "subw r7, pc, #0x888") | ||
664 | TEST_UNSUPPORTED(".short 0xf2af,0x1f20 @ subw pc, pc, #0x120") | ||
665 | TEST_UNSUPPORTED(".short 0xf2ad,0x1f20 @ subw pc, sp, #0x120") | ||
666 | TEST_UNSUPPORTED(".short 0xf2af,0x1d20 @ subw sp, pc, #0x120") | ||
667 | TEST_UNSUPPORTED(".short 0xf2a0,0x1d20 @ subw sp, r0, #0x120") | ||
668 | |||
669 | TEST("movw r0, #0") | ||
670 | TEST("movw r0, #0xffff") | ||
671 | TEST("movw lr, #0xffff") | ||
672 | TEST_UNSUPPORTED(".short 0xf240,0x0d00 @ movw sp, #0") | ||
673 | TEST_UNSUPPORTED(".short 0xf240,0x0f00 @ movw pc, #0") | ||
674 | |||
675 | TEST_R("movt r",0, VAL1,", #0") | ||
676 | TEST_R("movt r",0, VAL2,", #0xffff") | ||
677 | TEST_R("movt r",14,VAL1,", #0xffff") | ||
678 | TEST_UNSUPPORTED(".short 0xf2c0,0x0d00 @ movt sp, #0") | ||
679 | TEST_UNSUPPORTED(".short 0xf2c0,0x0f00 @ movt pc, #0") | ||
680 | |||
681 | TEST_R( "ssat r0, #24, r",0, VAL1,"") | ||
682 | TEST_R( "ssat r14, #24, r",12, VAL2,"") | ||
683 | TEST_R( "ssat r0, #24, r",0, VAL1,", lsl #8") | ||
684 | TEST_R( "ssat r14, #24, r",12, VAL2,", asr #8") | ||
685 | TEST_UNSUPPORTED(".short 0xf30c,0x0d17 @ ssat sp, #24, r12") | ||
686 | TEST_UNSUPPORTED(".short 0xf30c,0x0f17 @ ssat pc, #24, r12") | ||
687 | TEST_UNSUPPORTED(".short 0xf30d,0x0c17 @ ssat r12, #24, sp") | ||
688 | TEST_UNSUPPORTED(".short 0xf30f,0x0c17 @ ssat r12, #24, pc") | ||
689 | |||
690 | TEST_R( "usat r0, #24, r",0, VAL1,"") | ||
691 | TEST_R( "usat r14, #24, r",12, VAL2,"") | ||
692 | TEST_R( "usat r0, #24, r",0, VAL1,", lsl #8") | ||
693 | TEST_R( "usat r14, #24, r",12, VAL2,", asr #8") | ||
694 | TEST_UNSUPPORTED(".short 0xf38c,0x0d17 @ usat sp, #24, r12") | ||
695 | TEST_UNSUPPORTED(".short 0xf38c,0x0f17 @ usat pc, #24, r12") | ||
696 | TEST_UNSUPPORTED(".short 0xf38d,0x0c17 @ usat r12, #24, sp") | ||
697 | TEST_UNSUPPORTED(".short 0xf38f,0x0c17 @ usat r12, #24, pc") | ||
698 | |||
699 | TEST_R( "ssat16 r0, #12, r",0, HH1,"") | ||
700 | TEST_R( "ssat16 r14, #12, r",12, HH2,"") | ||
701 | TEST_UNSUPPORTED(".short 0xf32c,0x0d0b @ ssat16 sp, #12, r12") | ||
702 | TEST_UNSUPPORTED(".short 0xf32c,0x0f0b @ ssat16 pc, #12, r12") | ||
703 | TEST_UNSUPPORTED(".short 0xf32d,0x0c0b @ ssat16 r12, #12, sp") | ||
704 | TEST_UNSUPPORTED(".short 0xf32f,0x0c0b @ ssat16 r12, #12, pc") | ||
705 | |||
706 | TEST_R( "usat16 r0, #12, r",0, HH1,"") | ||
707 | TEST_R( "usat16 r14, #12, r",12, HH2,"") | ||
708 | TEST_UNSUPPORTED(".short 0xf3ac,0x0d0b @ usat16 sp, #12, r12") | ||
709 | TEST_UNSUPPORTED(".short 0xf3ac,0x0f0b @ usat16 pc, #12, r12") | ||
710 | TEST_UNSUPPORTED(".short 0xf3ad,0x0c0b @ usat16 r12, #12, sp") | ||
711 | TEST_UNSUPPORTED(".short 0xf3af,0x0c0b @ usat16 r12, #12, pc") | ||
712 | |||
713 | TEST_R( "sbfx r0, r",0 , VAL1,", #0, #31") | ||
714 | TEST_R( "sbfx r14, r",12, VAL2,", #8, #16") | ||
715 | TEST_R( "sbfx r4, r",10, VAL1,", #16, #15") | ||
716 | TEST_UNSUPPORTED(".short 0xf34c,0x2d0f @ sbfx sp, r12, #8, #16") | ||
717 | TEST_UNSUPPORTED(".short 0xf34c,0x2f0f @ sbfx pc, r12, #8, #16") | ||
718 | TEST_UNSUPPORTED(".short 0xf34d,0x2c0f @ sbfx r12, sp, #8, #16") | ||
719 | TEST_UNSUPPORTED(".short 0xf34f,0x2c0f @ sbfx r12, pc, #8, #16") | ||
720 | |||
721 | TEST_R( "ubfx r0, r",0 , VAL1,", #0, #31") | ||
722 | TEST_R( "ubfx r14, r",12, VAL2,", #8, #16") | ||
723 | TEST_R( "ubfx r4, r",10, VAL1,", #16, #15") | ||
724 | TEST_UNSUPPORTED(".short 0xf3cc,0x2d0f @ ubfx sp, r12, #8, #16") | ||
725 | TEST_UNSUPPORTED(".short 0xf3cc,0x2f0f @ ubfx pc, r12, #8, #16") | ||
726 | TEST_UNSUPPORTED(".short 0xf3cd,0x2c0f @ ubfx r12, sp, #8, #16") | ||
727 | TEST_UNSUPPORTED(".short 0xf3cf,0x2c0f @ ubfx r12, pc, #8, #16") | ||
728 | |||
729 | TEST_R( "bfc r",0, VAL1,", #4, #20") | ||
730 | TEST_R( "bfc r",14,VAL2,", #4, #20") | ||
731 | TEST_R( "bfc r",7, VAL1,", #0, #31") | ||
732 | TEST_R( "bfc r",8, VAL2,", #0, #31") | ||
733 | TEST_UNSUPPORTED(".short 0xf36f,0x0d1e @ bfc sp, #0, #31") | ||
734 | TEST_UNSUPPORTED(".short 0xf36f,0x0f1e @ bfc pc, #0, #31") | ||
735 | |||
736 | TEST_RR( "bfi r",0, VAL1,", r",0 , VAL2,", #0, #31") | ||
737 | TEST_RR( "bfi r",12,VAL1,", r",14 , VAL2,", #4, #20") | ||
738 | TEST_UNSUPPORTED(".short 0xf36e,0x1d17 @ bfi sp, r14, #4, #20") | ||
739 | TEST_UNSUPPORTED(".short 0xf36e,0x1f17 @ bfi pc, r14, #4, #20") | ||
740 | TEST_UNSUPPORTED(".short 0xf36d,0x1e17 @ bfi r14, sp, #4, #20") | ||
741 | |||
742 | TEST_GROUP("Branches and miscellaneous control") | ||
743 | |||
744 | CONDITION_INSTRUCTIONS(22, | ||
745 | TEST_BF("beq.w 2f") | ||
746 | TEST_BB("bne.w 2b") | ||
747 | TEST_BF("bgt.w 2f") | ||
748 | TEST_BB("blt.w 2b") | ||
749 | TEST_BF_X("bpl.w 2f",0x1000) | ||
750 | ) | ||
751 | |||
752 | TEST_UNSUPPORTED("msr cpsr, r0") | ||
753 | TEST_UNSUPPORTED("msr cpsr_f, r1") | ||
754 | TEST_UNSUPPORTED("msr spsr, r2") | ||
755 | |||
756 | TEST_UNSUPPORTED("cpsie.w i") | ||
757 | TEST_UNSUPPORTED("cpsid.w i") | ||
758 | TEST_UNSUPPORTED("cps 0x13") | ||
759 | |||
760 | TEST_SUPPORTED("yield.w") | ||
761 | TEST("sev.w") | ||
762 | TEST("nop.w") | ||
763 | TEST("wfi.w") | ||
764 | TEST_SUPPORTED("wfe.w") | ||
765 | TEST_UNSUPPORTED("dbg.w #0") | ||
766 | |||
767 | TEST_UNSUPPORTED("clrex") | ||
768 | TEST_UNSUPPORTED("dsb") | ||
769 | TEST_UNSUPPORTED("dmb") | ||
770 | TEST_UNSUPPORTED("isb") | ||
771 | |||
772 | TEST_UNSUPPORTED("bxj r0") | ||
773 | |||
774 | TEST_UNSUPPORTED("subs pc, lr, #4") | ||
775 | |||
776 | TEST("mrs r0, cpsr") | ||
777 | TEST("mrs r14, cpsr") | ||
778 | TEST_UNSUPPORTED(".short 0xf3ef,0x8d00 @ mrs sp, spsr") | ||
779 | TEST_UNSUPPORTED(".short 0xf3ef,0x8f00 @ mrs pc, spsr") | ||
780 | TEST_UNSUPPORTED("mrs r0, spsr") | ||
781 | TEST_UNSUPPORTED("mrs lr, spsr") | ||
782 | |||
783 | TEST_UNSUPPORTED(".short 0xf7f0,0x8000 @ smc #0") | ||
784 | |||
785 | TEST_UNSUPPORTED(".short 0xf7f0,0xa000 @ undefeined") | ||
786 | |||
787 | TEST_BF( "b.w 2f") | ||
788 | TEST_BB( "b.w 2b") | ||
789 | TEST_BF_X("b.w 2f", 0x1000) | ||
790 | |||
791 | TEST_BF( "bl.w 2f") | ||
792 | TEST_BB( "bl.w 2b") | ||
793 | TEST_BB_X("bl.w 2b", 0x1000) | ||
794 | |||
795 | TEST_X( "blx __dummy_arm_subroutine", | ||
796 | ".arm \n\t" | ||
797 | ".align \n\t" | ||
798 | ".type __dummy_arm_subroutine, %%function \n\t" | ||
799 | "__dummy_arm_subroutine: \n\t" | ||
800 | "mov r0, pc \n\t" | ||
801 | "bx lr \n\t" | ||
802 | ".thumb \n\t" | ||
803 | ) | ||
804 | TEST( "blx __dummy_arm_subroutine") | ||
805 | |||
806 | TEST_GROUP("Store single data item") | ||
807 | |||
808 | #define SINGLE_STORE(size) \ | ||
809 | TEST_RP( "str"size" r",0, VAL1,", [r",11,-1024,", #1024]") \ | ||
810 | TEST_RP( "str"size" r",14,VAL2,", [r",1, -1024,", #1080]") \ | ||
811 | TEST_RP( "str"size" r",0, VAL1,", [r",11,256, ", #-120]") \ | ||
812 | TEST_RP( "str"size" r",14,VAL2,", [r",1, 256, ", #-128]") \ | ||
813 | TEST_RP( "str"size" r",0, VAL1,", [r",11,24, "], #120") \ | ||
814 | TEST_RP( "str"size" r",14,VAL2,", [r",1, 24, "], #128") \ | ||
815 | TEST_RP( "str"size" r",0, VAL1,", [r",11,24, "], #-120") \ | ||
816 | TEST_RP( "str"size" r",14,VAL2,", [r",1, 24, "], #-128") \ | ||
817 | TEST_RP( "str"size" r",0, VAL1,", [r",11,24, ", #120]!") \ | ||
818 | TEST_RP( "str"size" r",14,VAL2,", [r",1, 24, ", #128]!") \ | ||
819 | TEST_RP( "str"size" r",0, VAL1,", [r",11,256, ", #-120]!") \ | ||
820 | TEST_RP( "str"size" r",14,VAL2,", [r",1, 256, ", #-128]!") \ | ||
821 | TEST_RPR("str"size".w r",0, VAL1,", [r",1, 0,", r",2, 4,"]") \ | ||
822 | TEST_RPR("str"size" r",14,VAL2,", [r",10,0,", r",11,4,", lsl #1]") \ | ||
823 | TEST_R( "str"size".w r",7, VAL1,", [sp, #24]") \ | ||
824 | TEST_RP( "str"size".w r",0, VAL2,", [r",0,0, "]") \ | ||
825 | TEST_UNSUPPORTED("str"size"t r0, [r1, #4]") | ||
826 | |||
827 | SINGLE_STORE("b") | ||
828 | SINGLE_STORE("h") | ||
829 | SINGLE_STORE("") | ||
830 | |||
831 | TEST("str sp, [sp]") | ||
832 | TEST_UNSUPPORTED(".short 0xf8cf,0xe000 @ str r14, [pc]") | ||
833 | TEST_UNSUPPORTED(".short 0xf8ce,0xf000 @ str pc, [r14]") | ||
834 | |||
835 | TEST_GROUP("Advanced SIMD element or structure load/store instructions") | ||
836 | |||
837 | TEST_UNSUPPORTED(".short 0xf900,0x0000") | ||
838 | TEST_UNSUPPORTED(".short 0xf92f,0xffff") | ||
839 | TEST_UNSUPPORTED(".short 0xf980,0x0000") | ||
840 | TEST_UNSUPPORTED(".short 0xf9ef,0xffff") | ||
841 | |||
842 | TEST_GROUP("Load single data item and memory hints") | ||
843 | |||
844 | #define SINGLE_LOAD(size) \ | ||
845 | TEST_P( "ldr"size" r0, [r",11,-1024, ", #1024]") \ | ||
846 | TEST_P( "ldr"size" r14, [r",1, -1024,", #1080]") \ | ||
847 | TEST_P( "ldr"size" r0, [r",11,256, ", #-120]") \ | ||
848 | TEST_P( "ldr"size" r14, [r",1, 256, ", #-128]") \ | ||
849 | TEST_P( "ldr"size" r0, [r",11,24, "], #120") \ | ||
850 | TEST_P( "ldr"size" r14, [r",1, 24, "], #128") \ | ||
851 | TEST_P( "ldr"size" r0, [r",11,24, "], #-120") \ | ||
852 | TEST_P( "ldr"size" r14, [r",1,24, "], #-128") \ | ||
853 | TEST_P( "ldr"size" r0, [r",11,24, ", #120]!") \ | ||
854 | TEST_P( "ldr"size" r14, [r",1, 24, ", #128]!") \ | ||
855 | TEST_P( "ldr"size" r0, [r",11,256, ", #-120]!") \ | ||
856 | TEST_P( "ldr"size" r14, [r",1, 256, ", #-128]!") \ | ||
857 | TEST_PR("ldr"size".w r0, [r",1, 0,", r",2, 4,"]") \ | ||
858 | TEST_PR("ldr"size" r14, [r",10,0,", r",11,4,", lsl #1]") \ | ||
859 | TEST_X( "ldr"size".w r0, 3f", \ | ||
860 | ".align 3 \n\t" \ | ||
861 | "3: .word "__stringify(VAL1)) \ | ||
862 | TEST_X( "ldr"size".w r14, 3f", \ | ||
863 | ".align 3 \n\t" \ | ||
864 | "3: .word "__stringify(VAL2)) \ | ||
865 | TEST( "ldr"size".w r7, 3b") \ | ||
866 | TEST( "ldr"size".w r7, [sp, #24]") \ | ||
867 | TEST_P( "ldr"size".w r0, [r",0,0, "]") \ | ||
868 | TEST_UNSUPPORTED("ldr"size"t r0, [r1, #4]") | ||
869 | |||
870 | SINGLE_LOAD("b") | ||
871 | SINGLE_LOAD("sb") | ||
872 | SINGLE_LOAD("h") | ||
873 | SINGLE_LOAD("sh") | ||
874 | SINGLE_LOAD("") | ||
875 | |||
876 | TEST_BF_P("ldr pc, [r",14, 15*4,"]") | ||
877 | TEST_P( "ldr sp, [r",14, 13*4,"]") | ||
878 | TEST_BF_R("ldr pc, [sp, r",14, 15*4,"]") | ||
879 | TEST_R( "ldr sp, [sp, r",14, 13*4,"]") | ||
880 | TEST_THUMB_TO_ARM_INTERWORK_P("ldr pc, [r",0,0,", #15*4]") | ||
881 | TEST_SUPPORTED("ldr sp, 99f") | ||
882 | TEST_SUPPORTED("ldr pc, 99f") | ||
883 | |||
884 | TEST_UNSUPPORTED(".short 0xf854,0x700d @ ldr r7, [r4, sp]") | ||
885 | TEST_UNSUPPORTED(".short 0xf854,0x700f @ ldr r7, [r4, pc]") | ||
886 | TEST_UNSUPPORTED(".short 0xf814,0x700d @ ldrb r7, [r4, sp]") | ||
887 | TEST_UNSUPPORTED(".short 0xf814,0x700f @ ldrb r7, [r4, pc]") | ||
888 | TEST_UNSUPPORTED(".short 0xf89f,0xd004 @ ldrb sp, 99f") | ||
889 | TEST_UNSUPPORTED(".short 0xf814,0xd008 @ ldrb sp, [r4, r8]") | ||
890 | TEST_UNSUPPORTED(".short 0xf894,0xd000 @ ldrb sp, [r4]") | ||
891 | |||
892 | TEST_UNSUPPORTED(".short 0xf860,0x0000") /* Unallocated space */ | ||
893 | TEST_UNSUPPORTED(".short 0xf9ff,0xffff") /* Unallocated space */ | ||
894 | TEST_UNSUPPORTED(".short 0xf950,0x0000") /* Unallocated space */ | ||
895 | TEST_UNSUPPORTED(".short 0xf95f,0xffff") /* Unallocated space */ | ||
896 | TEST_UNSUPPORTED(".short 0xf800,0x0800") /* Unallocated space */ | ||
897 | TEST_UNSUPPORTED(".short 0xf97f,0xfaff") /* Unallocated space */ | ||
898 | |||
899 | TEST( "pli [pc, #4]") | ||
900 | TEST( "pli [pc, #-4]") | ||
901 | TEST( "pld [pc, #4]") | ||
902 | TEST( "pld [pc, #-4]") | ||
903 | |||
904 | TEST_P( "pld [r",0,-1024,", #1024]") | ||
905 | TEST( ".short 0xf8b0,0xf400 @ pldw [r0, #1024]") | ||
906 | TEST_P( "pli [r",4, 0b,", #1024]") | ||
907 | TEST_P( "pld [r",7, 120,", #-120]") | ||
908 | TEST( ".short 0xf837,0xfc78 @ pldw [r7, #-120]") | ||
909 | TEST_P( "pli [r",11,120,", #-120]") | ||
910 | TEST( "pld [sp, #0]") | ||
911 | |||
912 | TEST_PR("pld [r",7, 24, ", r",0, 16,"]") | ||
913 | TEST_PR("pld [r",8, 24, ", r",12,16,", lsl #3]") | ||
914 | TEST_SUPPORTED(".short 0xf837,0xf000 @ pldw [r7, r0]") | ||
915 | TEST_SUPPORTED(".short 0xf838,0xf03c @ pldw [r8, r12, lsl #3]"); | ||
916 | TEST_RR("pli [r",12,0b,", r",0, 16,"]") | ||
917 | TEST_RR("pli [r",0, 0b,", r",12,16,", lsl #3]") | ||
918 | TEST_R( "pld [sp, r",1, 16,"]") | ||
919 | TEST_UNSUPPORTED(".short 0xf817,0xf00d @pld [r7, sp]") | ||
920 | TEST_UNSUPPORTED(".short 0xf817,0xf00f @pld [r7, pc]") | ||
921 | |||
922 | TEST_GROUP("Data-processing (register)") | ||
923 | |||
924 | #define SHIFTS32(op) \ | ||
925 | TEST_RR(op" r0, r",1, VAL1,", r",2, 3, "") \ | ||
926 | TEST_RR(op" r14, r",12,VAL2,", r",11,10,"") | ||
927 | |||
928 | SHIFTS32("lsl") | ||
929 | SHIFTS32("lsls") | ||
930 | SHIFTS32("lsr") | ||
931 | SHIFTS32("lsrs") | ||
932 | SHIFTS32("asr") | ||
933 | SHIFTS32("asrs") | ||
934 | SHIFTS32("ror") | ||
935 | SHIFTS32("rors") | ||
936 | |||
937 | TEST_UNSUPPORTED(".short 0xfa01,0xff02 @ lsl pc, r1, r2") | ||
938 | TEST_UNSUPPORTED(".short 0xfa01,0xfd02 @ lsl sp, r1, r2") | ||
939 | TEST_UNSUPPORTED(".short 0xfa0f,0xf002 @ lsl r0, pc, r2") | ||
940 | TEST_UNSUPPORTED(".short 0xfa0d,0xf002 @ lsl r0, sp, r2") | ||
941 | TEST_UNSUPPORTED(".short 0xfa01,0xf00f @ lsl r0, r1, pc") | ||
942 | TEST_UNSUPPORTED(".short 0xfa01,0xf00d @ lsl r0, r1, sp") | ||
943 | |||
944 | TEST_RR( "sxtah r0, r",0, HH1,", r",1, HH2,"") | ||
945 | TEST_RR( "sxtah r14,r",12, HH2,", r",10,HH1,", ror #8") | ||
946 | TEST_R( "sxth r8, r",7, HH1,"") | ||
947 | |||
948 | TEST_UNSUPPORTED(".short 0xfa0f,0xff87 @ sxth pc, r7"); | ||
949 | TEST_UNSUPPORTED(".short 0xfa0f,0xfd87 @ sxth sp, r7"); | ||
950 | TEST_UNSUPPORTED(".short 0xfa0f,0xf88f @ sxth r8, pc"); | ||
951 | TEST_UNSUPPORTED(".short 0xfa0f,0xf88d @ sxth r8, sp"); | ||
952 | |||
953 | TEST_RR( "uxtah r0, r",0, HH1,", r",1, HH2,"") | ||
954 | TEST_RR( "uxtah r14,r",12, HH2,", r",10,HH1,", ror #8") | ||
955 | TEST_R( "uxth r8, r",7, HH1,"") | ||
956 | |||
957 | TEST_RR( "sxtab16 r0, r",0, HH1,", r",1, HH2,"") | ||
958 | TEST_RR( "sxtab16 r14,r",12, HH2,", r",10,HH1,", ror #8") | ||
959 | TEST_R( "sxtb16 r8, r",7, HH1,"") | ||
960 | |||
961 | TEST_RR( "uxtab16 r0, r",0, HH1,", r",1, HH2,"") | ||
962 | TEST_RR( "uxtab16 r14,r",12, HH2,", r",10,HH1,", ror #8") | ||
963 | TEST_R( "uxtb16 r8, r",7, HH1,"") | ||
964 | |||
965 | TEST_RR( "sxtab r0, r",0, HH1,", r",1, HH2,"") | ||
966 | TEST_RR( "sxtab r14,r",12, HH2,", r",10,HH1,", ror #8") | ||
967 | TEST_R( "sxtb r8, r",7, HH1,"") | ||
968 | |||
969 | TEST_RR( "uxtab r0, r",0, HH1,", r",1, HH2,"") | ||
970 | TEST_RR( "uxtab r14,r",12, HH2,", r",10,HH1,", ror #8") | ||
971 | TEST_R( "uxtb r8, r",7, HH1,"") | ||
972 | |||
973 | TEST_UNSUPPORTED(".short 0xfa60,0x00f0") | ||
974 | TEST_UNSUPPORTED(".short 0xfa7f,0xffff") | ||
975 | |||
976 | #define PARALLEL_ADD_SUB(op) \ | ||
977 | TEST_RR( op"add16 r0, r",0, HH1,", r",1, HH2,"") \ | ||
978 | TEST_RR( op"add16 r14, r",12,HH2,", r",10,HH1,"") \ | ||
979 | TEST_RR( op"asx r0, r",0, HH1,", r",1, HH2,"") \ | ||
980 | TEST_RR( op"asx r14, r",12,HH2,", r",10,HH1,"") \ | ||
981 | TEST_RR( op"sax r0, r",0, HH1,", r",1, HH2,"") \ | ||
982 | TEST_RR( op"sax r14, r",12,HH2,", r",10,HH1,"") \ | ||
983 | TEST_RR( op"sub16 r0, r",0, HH1,", r",1, HH2,"") \ | ||
984 | TEST_RR( op"sub16 r14, r",12,HH2,", r",10,HH1,"") \ | ||
985 | TEST_RR( op"add8 r0, r",0, HH1,", r",1, HH2,"") \ | ||
986 | TEST_RR( op"add8 r14, r",12,HH2,", r",10,HH1,"") \ | ||
987 | TEST_RR( op"sub8 r0, r",0, HH1,", r",1, HH2,"") \ | ||
988 | TEST_RR( op"sub8 r14, r",12,HH2,", r",10,HH1,"") | ||
989 | |||
990 | TEST_GROUP("Parallel addition and subtraction, signed") | ||
991 | |||
992 | PARALLEL_ADD_SUB("s") | ||
993 | PARALLEL_ADD_SUB("q") | ||
994 | PARALLEL_ADD_SUB("sh") | ||
995 | |||
996 | TEST_GROUP("Parallel addition and subtraction, unsigned") | ||
997 | |||
998 | PARALLEL_ADD_SUB("u") | ||
999 | PARALLEL_ADD_SUB("uq") | ||
1000 | PARALLEL_ADD_SUB("uh") | ||
1001 | |||
1002 | TEST_GROUP("Miscellaneous operations") | ||
1003 | |||
1004 | TEST_RR("qadd r0, r",1, VAL1,", r",2, VAL2,"") | ||
1005 | TEST_RR("qadd lr, r",9, VAL2,", r",8, VAL1,"") | ||
1006 | TEST_RR("qsub r0, r",1, VAL1,", r",2, VAL2,"") | ||
1007 | TEST_RR("qsub lr, r",9, VAL2,", r",8, VAL1,"") | ||
1008 | TEST_RR("qdadd r0, r",1, VAL1,", r",2, VAL2,"") | ||
1009 | TEST_RR("qdadd lr, r",9, VAL2,", r",8, VAL1,"") | ||
1010 | TEST_RR("qdsub r0, r",1, VAL1,", r",2, VAL2,"") | ||
1011 | TEST_RR("qdsub lr, r",9, VAL2,", r",8, VAL1,"") | ||
1012 | |||
1013 | TEST_R("rev.w r0, r",0, VAL1,"") | ||
1014 | TEST_R("rev r14, r",12, VAL2,"") | ||
1015 | TEST_R("rev16.w r0, r",0, VAL1,"") | ||
1016 | TEST_R("rev16 r14, r",12, VAL2,"") | ||
1017 | TEST_R("rbit r0, r",0, VAL1,"") | ||
1018 | TEST_R("rbit r14, r",12, VAL2,"") | ||
1019 | TEST_R("revsh.w r0, r",0, VAL1,"") | ||
1020 | TEST_R("revsh r14, r",12, VAL2,"") | ||
1021 | |||
1022 | TEST_UNSUPPORTED(".short 0xfa9c,0xff8c @ rev pc, r12"); | ||
1023 | TEST_UNSUPPORTED(".short 0xfa9c,0xfd8c @ rev sp, r12"); | ||
1024 | TEST_UNSUPPORTED(".short 0xfa9f,0xfe8f @ rev r14, pc"); | ||
1025 | TEST_UNSUPPORTED(".short 0xfa9d,0xfe8d @ rev r14, sp"); | ||
1026 | |||
1027 | TEST_RR("sel r0, r",0, VAL1,", r",1, VAL2,"") | ||
1028 | TEST_RR("sel r14, r",12,VAL1,", r",10, VAL2,"") | ||
1029 | |||
1030 | TEST_R("clz r0, r",0, 0x0,"") | ||
1031 | TEST_R("clz r7, r",14,0x1,"") | ||
1032 | TEST_R("clz lr, r",7, 0xffffffff,"") | ||
1033 | |||
1034 | TEST_UNSUPPORTED(".short 0xfa80,0xf030") /* Unallocated space */ | ||
1035 | TEST_UNSUPPORTED(".short 0xfaff,0xff7f") /* Unallocated space */ | ||
1036 | TEST_UNSUPPORTED(".short 0xfab0,0xf000") /* Unallocated space */ | ||
1037 | TEST_UNSUPPORTED(".short 0xfaff,0xff7f") /* Unallocated space */ | ||
1038 | |||
1039 | TEST_GROUP("Multiply, multiply accumulate, and absolute difference operations") | ||
1040 | |||
1041 | TEST_RR( "mul r0, r",1, VAL1,", r",2, VAL2,"") | ||
1042 | TEST_RR( "mul r7, r",8, VAL2,", r",9, VAL2,"") | ||
1043 | TEST_UNSUPPORTED(".short 0xfb08,0xff09 @ mul pc, r8, r9") | ||
1044 | TEST_UNSUPPORTED(".short 0xfb08,0xfd09 @ mul sp, r8, r9") | ||
1045 | TEST_UNSUPPORTED(".short 0xfb0f,0xf709 @ mul r7, pc, r9") | ||
1046 | TEST_UNSUPPORTED(".short 0xfb0d,0xf709 @ mul r7, sp, r9") | ||
1047 | TEST_UNSUPPORTED(".short 0xfb08,0xf70f @ mul r7, r8, pc") | ||
1048 | TEST_UNSUPPORTED(".short 0xfb08,0xf70d @ mul r7, r8, sp") | ||
1049 | |||
1050 | TEST_RRR( "mla r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"") | ||
1051 | TEST_RRR( "mla r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") | ||
1052 | TEST_UNSUPPORTED(".short 0xfb08,0xaf09 @ mla pc, r8, r9, r10"); | ||
1053 | TEST_UNSUPPORTED(".short 0xfb08,0xad09 @ mla sp, r8, r9, r10"); | ||
1054 | TEST_UNSUPPORTED(".short 0xfb0f,0xa709 @ mla r7, pc, r9, r10"); | ||
1055 | TEST_UNSUPPORTED(".short 0xfb0d,0xa709 @ mla r7, sp, r9, r10"); | ||
1056 | TEST_UNSUPPORTED(".short 0xfb08,0xa70f @ mla r7, r8, pc, r10"); | ||
1057 | TEST_UNSUPPORTED(".short 0xfb08,0xa70d @ mla r7, r8, sp, r10"); | ||
1058 | TEST_UNSUPPORTED(".short 0xfb08,0xd709 @ mla r7, r8, r9, sp"); | ||
1059 | |||
1060 | TEST_RRR( "mls r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"") | ||
1061 | TEST_RRR( "mls r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") | ||
1062 | |||
1063 | TEST_RRR( "smlabb r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"") | ||
1064 | TEST_RRR( "smlabb r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") | ||
1065 | TEST_RRR( "smlatb r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"") | ||
1066 | TEST_RRR( "smlatb r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") | ||
1067 | TEST_RRR( "smlabt r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"") | ||
1068 | TEST_RRR( "smlabt r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") | ||
1069 | TEST_RRR( "smlatt r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"") | ||
1070 | TEST_RRR( "smlatt r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") | ||
1071 | TEST_RR( "smulbb r0, r",1, VAL1,", r",2, VAL2,"") | ||
1072 | TEST_RR( "smulbb r7, r",8, VAL3,", r",9, VAL1,"") | ||
1073 | TEST_RR( "smultb r0, r",1, VAL1,", r",2, VAL2,"") | ||
1074 | TEST_RR( "smultb r7, r",8, VAL3,", r",9, VAL1,"") | ||
1075 | TEST_RR( "smulbt r0, r",1, VAL1,", r",2, VAL2,"") | ||
1076 | TEST_RR( "smulbt r7, r",8, VAL3,", r",9, VAL1,"") | ||
1077 | TEST_RR( "smultt r0, r",1, VAL1,", r",2, VAL2,"") | ||
1078 | TEST_RR( "smultt r7, r",8, VAL3,", r",9, VAL1,"") | ||
1079 | |||
1080 | TEST_RRR( "smlad r0, r",0, HH1,", r",1, HH2,", r",2, VAL1,"") | ||
1081 | TEST_RRR( "smlad r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"") | ||
1082 | TEST_RRR( "smladx r0, r",0, HH1,", r",1, HH2,", r",2, VAL1,"") | ||
1083 | TEST_RRR( "smladx r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"") | ||
1084 | TEST_RR( "smuad r0, r",0, HH1,", r",1, HH2,"") | ||
1085 | TEST_RR( "smuad r14, r",12,HH2,", r",10,HH1,"") | ||
1086 | TEST_RR( "smuadx r0, r",0, HH1,", r",1, HH2,"") | ||
1087 | TEST_RR( "smuadx r14, r",12,HH2,", r",10,HH1,"") | ||
1088 | |||
1089 | TEST_RRR( "smlawb r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"") | ||
1090 | TEST_RRR( "smlawb r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") | ||
1091 | TEST_RRR( "smlawt r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"") | ||
1092 | TEST_RRR( "smlawt r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") | ||
1093 | TEST_RR( "smulwb r0, r",1, VAL1,", r",2, VAL2,"") | ||
1094 | TEST_RR( "smulwb r7, r",8, VAL3,", r",9, VAL1,"") | ||
1095 | TEST_RR( "smulwt r0, r",1, VAL1,", r",2, VAL2,"") | ||
1096 | TEST_RR( "smulwt r7, r",8, VAL3,", r",9, VAL1,"") | ||
1097 | |||
1098 | TEST_RRR( "smlsd r0, r",0, HH1,", r",1, HH2,", r",2, VAL1,"") | ||
1099 | TEST_RRR( "smlsd r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"") | ||
1100 | TEST_RRR( "smlsdx r0, r",0, HH1,", r",1, HH2,", r",2, VAL1,"") | ||
1101 | TEST_RRR( "smlsdx r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"") | ||
1102 | TEST_RR( "smusd r0, r",0, HH1,", r",1, HH2,"") | ||
1103 | TEST_RR( "smusd r14, r",12,HH2,", r",10,HH1,"") | ||
1104 | TEST_RR( "smusdx r0, r",0, HH1,", r",1, HH2,"") | ||
1105 | TEST_RR( "smusdx r14, r",12,HH2,", r",10,HH1,"") | ||
1106 | |||
1107 | TEST_RRR( "smmla r0, r",0, VAL1,", r",1, VAL2,", r",2, VAL1,"") | ||
1108 | TEST_RRR( "smmla r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"") | ||
1109 | TEST_RRR( "smmlar r0, r",0, VAL1,", r",1, VAL2,", r",2, VAL1,"") | ||
1110 | TEST_RRR( "smmlar r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"") | ||
1111 | TEST_RR( "smmul r0, r",0, VAL1,", r",1, VAL2,"") | ||
1112 | TEST_RR( "smmul r14, r",12,VAL2,", r",10,VAL1,"") | ||
1113 | TEST_RR( "smmulr r0, r",0, VAL1,", r",1, VAL2,"") | ||
1114 | TEST_RR( "smmulr r14, r",12,VAL2,", r",10,VAL1,"") | ||
1115 | |||
1116 | TEST_RRR( "smmls r0, r",0, VAL1,", r",1, VAL2,", r",2, VAL1,"") | ||
1117 | TEST_RRR( "smmls r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"") | ||
1118 | TEST_RRR( "smmlsr r0, r",0, VAL1,", r",1, VAL2,", r",2, VAL1,"") | ||
1119 | TEST_RRR( "smmlsr r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"") | ||
1120 | |||
1121 | TEST_RRR( "usada8 r0, r",0, VAL1,", r",1, VAL2,", r",2, VAL3,"") | ||
1122 | TEST_RRR( "usada8 r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL3,"") | ||
1123 | TEST_RR( "usad8 r0, r",0, VAL1,", r",1, VAL2,"") | ||
1124 | TEST_RR( "usad8 r14, r",12,VAL2,", r",10,VAL1,"") | ||
1125 | |||
1126 | TEST_UNSUPPORTED(".short 0xfb00,0xf010") /* Unallocated space */ | ||
1127 | TEST_UNSUPPORTED(".short 0xfb0f,0xff1f") /* Unallocated space */ | ||
1128 | TEST_UNSUPPORTED(".short 0xfb70,0xf010") /* Unallocated space */ | ||
1129 | TEST_UNSUPPORTED(".short 0xfb7f,0xff1f") /* Unallocated space */ | ||
1130 | TEST_UNSUPPORTED(".short 0xfb70,0x0010") /* Unallocated space */ | ||
1131 | TEST_UNSUPPORTED(".short 0xfb7f,0xff1f") /* Unallocated space */ | ||
1132 | |||
1133 | TEST_GROUP("Long multiply, long multiply accumulate, and divide") | ||
1134 | |||
1135 | TEST_RR( "smull r0, r1, r",2, VAL1,", r",3, VAL2,"") | ||
1136 | TEST_RR( "smull r7, r8, r",9, VAL2,", r",10, VAL1,"") | ||
1137 | TEST_UNSUPPORTED(".short 0xfb89,0xf80a @ smull pc, r8, r9, r10"); | ||
1138 | TEST_UNSUPPORTED(".short 0xfb89,0xd80a @ smull sp, r8, r9, r10"); | ||
1139 | TEST_UNSUPPORTED(".short 0xfb89,0x7f0a @ smull r7, pc, r9, r10"); | ||
1140 | TEST_UNSUPPORTED(".short 0xfb89,0x7d0a @ smull r7, sp, r9, r10"); | ||
1141 | TEST_UNSUPPORTED(".short 0xfb8f,0x780a @ smull r7, r8, pc, r10"); | ||
1142 | TEST_UNSUPPORTED(".short 0xfb8d,0x780a @ smull r7, r8, sp, r10"); | ||
1143 | TEST_UNSUPPORTED(".short 0xfb89,0x780f @ smull r7, r8, r9, pc"); | ||
1144 | TEST_UNSUPPORTED(".short 0xfb89,0x780d @ smull r7, r8, r9, sp"); | ||
1145 | |||
1146 | TEST_RR( "umull r0, r1, r",2, VAL1,", r",3, VAL2,"") | ||
1147 | TEST_RR( "umull r7, r8, r",9, VAL2,", r",10, VAL1,"") | ||
1148 | |||
1149 | TEST_RRRR( "smlal r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) | ||
1150 | TEST_RRRR( "smlal r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) | ||
1151 | |||
1152 | TEST_RRRR( "smlalbb r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) | ||
1153 | TEST_RRRR( "smlalbb r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) | ||
1154 | TEST_RRRR( "smlalbt r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) | ||
1155 | TEST_RRRR( "smlalbt r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) | ||
1156 | TEST_RRRR( "smlaltb r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) | ||
1157 | TEST_RRRR( "smlaltb r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) | ||
1158 | TEST_RRRR( "smlaltt r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) | ||
1159 | TEST_RRRR( "smlaltt r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) | ||
1160 | |||
1161 | TEST_RRRR( "smlald r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2) | ||
1162 | TEST_RRRR( "smlald r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1) | ||
1163 | TEST_RRRR( "smlaldx r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2) | ||
1164 | TEST_RRRR( "smlaldx r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1) | ||
1165 | |||
1166 | TEST_RRRR( "smlsld r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2) | ||
1167 | TEST_RRRR( "smlsld r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1) | ||
1168 | TEST_RRRR( "smlsldx r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2) | ||
1169 | TEST_RRRR( "smlsldx r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1) | ||
1170 | |||
1171 | TEST_RRRR( "umlal r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) | ||
1172 | TEST_RRRR( "umlal r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) | ||
1173 | TEST_RRRR( "umaal r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) | ||
1174 | TEST_RRRR( "umaal r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) | ||
1175 | |||
1176 | TEST_GROUP("Coprocessor instructions") | ||
1177 | |||
1178 | TEST_UNSUPPORTED(".short 0xfc00,0x0000") | ||
1179 | TEST_UNSUPPORTED(".short 0xffff,0xffff") | ||
1180 | |||
1181 | TEST_GROUP("Testing instructions in IT blocks") | ||
1182 | |||
1183 | TEST_ITBLOCK("sub.w r0, r0") | ||
1184 | |||
1185 | verbose("\n"); | ||
1186 | } | ||
1187 | |||
diff --git a/arch/arm/kernel/kprobes-test.c b/arch/arm/kernel/kprobes-test.c index e22c3f2aff10..1cef0fa996e2 100644 --- a/arch/arm/kernel/kprobes-test.c +++ b/arch/arm/kernel/kprobes-test.c | |||
@@ -1117,6 +1117,15 @@ end: | |||
1117 | * Top level test functions | 1117 | * Top level test functions |
1118 | */ | 1118 | */ |
1119 | 1119 | ||
1120 | static int run_test_cases(void (*tests)(void)) | ||
1121 | { | ||
1122 | pr_info(" Run test cases\n"); | ||
1123 | tests(); | ||
1124 | |||
1125 | return 0; | ||
1126 | } | ||
1127 | |||
1128 | |||
1120 | static int __init run_all_tests(void) | 1129 | static int __init run_all_tests(void) |
1121 | { | 1130 | { |
1122 | int ret = 0; | 1131 | int ret = 0; |
@@ -1147,8 +1156,24 @@ static int __init run_all_tests(void) | |||
1147 | if (ret) | 1156 | if (ret) |
1148 | goto out; | 1157 | goto out; |
1149 | 1158 | ||
1159 | pr_info("16-bit Thumb instruction simulation\n"); | ||
1160 | ret = run_test_cases(kprobe_thumb16_test_cases); | ||
1161 | if (ret) | ||
1162 | goto out; | ||
1163 | |||
1164 | pr_info("32-bit Thumb instruction simulation\n"); | ||
1165 | ret = run_test_cases(kprobe_thumb32_test_cases); | ||
1166 | if (ret) | ||
1167 | goto out; | ||
1150 | #endif | 1168 | #endif |
1151 | 1169 | ||
1170 | pr_info("Total instruction simulation tests=%d, pass=%d fail=%d\n", | ||
1171 | test_try_count, test_pass_count, test_fail_count); | ||
1172 | if (test_fail_count) { | ||
1173 | ret = -EINVAL; | ||
1174 | goto out; | ||
1175 | } | ||
1176 | |||
1152 | out: | 1177 | out: |
1153 | if (ret == 0) | 1178 | if (ret == 0) |
1154 | pr_info("Finished kprobe tests OK\n"); | 1179 | pr_info("Finished kprobe tests OK\n"); |
diff --git a/arch/arm/kernel/kprobes-test.h b/arch/arm/kernel/kprobes-test.h index 50ecc2a36434..7d982290908f 100644 --- a/arch/arm/kernel/kprobes-test.h +++ b/arch/arm/kernel/kprobes-test.h | |||
@@ -382,3 +382,9 @@ struct test_arg_end { | |||
382 | #define VALR 0xdeaddead | 382 | #define VALR 0xdeaddead |
383 | #define HH1 0x0123fecb | 383 | #define HH1 0x0123fecb |
384 | #define HH2 0xa9874567 | 384 | #define HH2 0xa9874567 |
385 | |||
386 | |||
387 | #ifdef CONFIG_THUMB2_KERNEL | ||
388 | void kprobe_thumb16_test_cases(void); | ||
389 | void kprobe_thumb32_test_cases(void); | ||
390 | #endif | ||