FFmpeg
tests.c
Go to the documentation of this file.
1 #include "tests.h"
2 
3 #if ARCH_AARCH64
4 
6 {
7  return SELFTEST_CPU_FLAG_AARCH64;
8 }
9 
10 DEF_NOOP_FUNC(clobber_x0);
11 DEF_NOOP_FUNC(clobber_x1);
12 DEF_NOOP_FUNC(clobber_x2);
13 DEF_NOOP_FUNC(clobber_x3);
14 DEF_NOOP_FUNC(clobber_x4);
15 DEF_NOOP_FUNC(clobber_x5);
16 DEF_NOOP_FUNC(clobber_x6);
17 DEF_NOOP_FUNC(clobber_x7);
18 DEF_NOOP_FUNC(clobber_x8);
19 DEF_NOOP_FUNC(clobber_x9);
20 DEF_NOOP_FUNC(clobber_x10);
21 DEF_NOOP_FUNC(clobber_x11);
22 DEF_NOOP_FUNC(clobber_x12);
23 DEF_NOOP_FUNC(clobber_x13);
24 DEF_NOOP_FUNC(clobber_x14);
25 DEF_NOOP_FUNC(clobber_x15);
26 DEF_NOOP_FUNC(clobber_x16);
27 DEF_NOOP_FUNC(clobber_x17);
28 // x18 skipped
29 DEF_NOOP_FUNC(clobber_x19);
30 DEF_NOOP_FUNC(clobber_x20);
31 DEF_NOOP_FUNC(clobber_x21);
32 DEF_NOOP_FUNC(clobber_x22);
33 DEF_NOOP_FUNC(clobber_x23);
34 DEF_NOOP_FUNC(clobber_x24);
35 DEF_NOOP_FUNC(clobber_x25);
36 DEF_NOOP_FUNC(clobber_x26);
37 DEF_NOOP_FUNC(clobber_x27);
38 DEF_NOOP_FUNC(clobber_x28);
39 DEF_NOOP_FUNC(clobber_x29);
40 
41 DEF_NOOP_FUNC(clobber_d0);
42 DEF_NOOP_FUNC(clobber_d1);
43 DEF_NOOP_FUNC(clobber_d2);
44 DEF_NOOP_FUNC(clobber_d3);
45 DEF_NOOP_FUNC(clobber_d4);
46 DEF_NOOP_FUNC(clobber_d5);
47 DEF_NOOP_FUNC(clobber_d6);
48 DEF_NOOP_FUNC(clobber_d7);
49 DEF_NOOP_FUNC(clobber_d8);
50 DEF_NOOP_FUNC(clobber_d9);
51 DEF_NOOP_FUNC(clobber_d10);
52 DEF_NOOP_FUNC(clobber_d11);
53 DEF_NOOP_FUNC(clobber_d12);
54 DEF_NOOP_FUNC(clobber_d13);
55 DEF_NOOP_FUNC(clobber_d14);
56 DEF_NOOP_FUNC(clobber_d15);
57 DEF_NOOP_FUNC(clobber_d16);
58 DEF_NOOP_FUNC(clobber_d17);
59 DEF_NOOP_FUNC(clobber_d18);
60 DEF_NOOP_FUNC(clobber_d19);
61 DEF_NOOP_FUNC(clobber_d20);
62 DEF_NOOP_FUNC(clobber_d21);
63 DEF_NOOP_FUNC(clobber_d22);
64 DEF_NOOP_FUNC(clobber_d23);
65 DEF_NOOP_FUNC(clobber_d24);
66 DEF_NOOP_FUNC(clobber_d25);
67 DEF_NOOP_FUNC(clobber_d26);
68 DEF_NOOP_FUNC(clobber_d27);
69 DEF_NOOP_FUNC(clobber_d28);
70 DEF_NOOP_FUNC(clobber_d29);
71 DEF_NOOP_FUNC(clobber_d30);
72 DEF_NOOP_FUNC(clobber_d31);
73 
74 DEF_NOOP_FUNC(clobber_v8_upper);
75 DEF_NOOP_FUNC(clobber_v9_upper);
76 DEF_NOOP_FUNC(clobber_v10_upper);
77 DEF_NOOP_FUNC(clobber_v11_upper);
78 DEF_NOOP_FUNC(clobber_v12_upper);
79 DEF_NOOP_FUNC(clobber_v13_upper);
80 DEF_NOOP_FUNC(clobber_v14_upper);
81 DEF_NOOP_FUNC(clobber_v15_upper);
82 
83 DEF_NOOP_FUNC(sigill_aarch64);
84 
85 // A function with 8 parameters in registers and 3 on the stack.
86 typedef void(many_args_func)(int, int, int, int, int, int, int, int, int, int, int);
87 
88 #define DEF_MANY_ARGS_FUNC(NAME) \
89  void selftest_##NAME(int, int, int, int, int, int, int, int, int, int, int)
90 #define DEF_MANY_ARGS_GETTER(FLAG, NAME) DEF_GETTER(FLAG, NAME, many_args_func, NULL)
91 
92 DEF_MANY_ARGS_FUNC(clobber_stack_args_aarch64);
93 DEF_MANY_ARGS_FUNC(clobber_stack_aarch64);
94 DEF_MANY_ARGS_FUNC(check_clobber_upper_x0_aarch64);
95 DEF_MANY_ARGS_FUNC(check_clobber_upper_x1_aarch64);
96 DEF_MANY_ARGS_FUNC(check_clobber_upper_x2_aarch64);
97 DEF_MANY_ARGS_FUNC(check_clobber_upper_x3_aarch64);
98 DEF_MANY_ARGS_FUNC(check_clobber_upper_x4_aarch64);
99 DEF_MANY_ARGS_FUNC(check_clobber_upper_x5_aarch64);
100 DEF_MANY_ARGS_FUNC(check_clobber_upper_x6_aarch64);
101 DEF_MANY_ARGS_FUNC(check_clobber_upper_x7_aarch64);
102 DEF_MANY_ARGS_FUNC(check_clobber_upper_stack0_aarch64);
103 DEF_MANY_ARGS_FUNC(check_clobber_upper_stack1_aarch64);
104 DEF_MANY_ARGS_FUNC(check_clobber_upper_stack2_aarch64);
105 
106 // A function with MAX_ARGS (15) arguments
107 typedef void(max_int_args_func)(int, int, int, int, int, int, int, int, int, int, int,
108  int, int, int, int);
109 typedef void(max_int64_args_func)(int64_t, int64_t, int64_t, int64_t, int64_t, int64_t,
112 
113 #define DEF_MAX_INT_ARGS_FUNC(NAME) \
114  void selftest_##NAME(int, int, int, int, int, int, int, int, int, int, int, int, \
115  int, int, int)
116 #define DEF_MAX_INT_ARGS_GETTER(FLAG, NAME) \
117  DEF_GETTER(FLAG, NAME, max_int_args_func, NULL)
118 #define DEF_MAX_INT64_ARGS_FUNC(NAME) \
119  void selftest_##NAME(int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, \
120  int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, \
121  int64_t)
122 #define DEF_MAX_INT64_ARGS_GETTER(FLAG, NAME) \
123  DEF_GETTER(FLAG, NAME, max_int64_args_func, NULL)
124 
125 DEF_MAX_INT_ARGS_FUNC(check_max_int_args_aarch64);
126 DEF_MAX_INT64_ARGS_FUNC(check_max_int64_args_aarch64);
127 
128 static noop_func *get_clobber_x(int reg)
129 {
130  if (!(checkasm_get_cpu_flags() & SELFTEST_CPU_FLAG_AARCH64))
131  return NULL;
132 
133  switch (reg) {
134  case 0: return selftest_clobber_x0;
135  case 1: return selftest_clobber_x1;
136  case 2: return selftest_clobber_x2;
137  case 3: return selftest_clobber_x3;
138  case 4: return selftest_clobber_x4;
139  case 5: return selftest_clobber_x5;
140  case 6: return selftest_clobber_x6;
141  case 7: return selftest_clobber_x7;
142  case 8: return selftest_clobber_x8;
143  case 9: return selftest_clobber_x9;
144  case 10: return selftest_clobber_x10;
145  case 11: return selftest_clobber_x11;
146  case 12: return selftest_clobber_x12;
147  case 13: return selftest_clobber_x13;
148  case 14: return selftest_clobber_x14;
149  case 15: return selftest_clobber_x15;
150  case 16: return selftest_clobber_x16;
151  case 17: return selftest_clobber_x17;
152  // x18 skipped
153  case 19: return selftest_clobber_x19;
154  case 20: return selftest_clobber_x20;
155  case 21: return selftest_clobber_x21;
156  case 22: return selftest_clobber_x22;
157  case 23: return selftest_clobber_x23;
158  case 24: return selftest_clobber_x24;
159  case 25: return selftest_clobber_x25;
160  case 26: return selftest_clobber_x26;
161  case 27: return selftest_clobber_x27;
162  case 28: return selftest_clobber_x28;
163  case 29: return selftest_clobber_x29;
164  default: return NULL;
165  }
166 }
167 
168 static noop_func *get_clobber_d(int reg)
169 {
170  if (!(checkasm_get_cpu_flags() & SELFTEST_CPU_FLAG_AARCH64))
171  return NULL;
172 
173  switch (reg) {
174  case 0: return selftest_clobber_d0;
175  case 1: return selftest_clobber_d1;
176  case 2: return selftest_clobber_d2;
177  case 3: return selftest_clobber_d3;
178  case 4: return selftest_clobber_d4;
179  case 5: return selftest_clobber_d5;
180  case 6: return selftest_clobber_d6;
181  case 7: return selftest_clobber_d7;
182  case 8: return selftest_clobber_d8;
183  case 9: return selftest_clobber_d9;
184  case 10: return selftest_clobber_d10;
185  case 11: return selftest_clobber_d11;
186  case 12: return selftest_clobber_d12;
187  case 13: return selftest_clobber_d13;
188  case 14: return selftest_clobber_d14;
189  case 15: return selftest_clobber_d15;
190  case 16: return selftest_clobber_d16;
191  case 17: return selftest_clobber_d17;
192  case 18: return selftest_clobber_d18;
193  case 19: return selftest_clobber_d19;
194  case 20: return selftest_clobber_d20;
195  case 21: return selftest_clobber_d21;
196  case 22: return selftest_clobber_d22;
197  case 23: return selftest_clobber_d23;
198  case 24: return selftest_clobber_d24;
199  case 25: return selftest_clobber_d25;
200  case 26: return selftest_clobber_d26;
201  case 27: return selftest_clobber_d27;
202  case 28: return selftest_clobber_d28;
203  case 29: return selftest_clobber_d29;
204  case 30: return selftest_clobber_d30;
205  case 31: return selftest_clobber_d31;
206  default: return NULL;
207  }
208 }
209 
210 static noop_func *get_clobber_v_upper(int reg)
211 {
212  if (!(checkasm_get_cpu_flags() & SELFTEST_CPU_FLAG_AARCH64))
213  return NULL;
214 
215  switch (reg) {
216  case 8: return selftest_clobber_v8_upper;
217  case 9: return selftest_clobber_v9_upper;
218  case 10: return selftest_clobber_v10_upper;
219  case 11: return selftest_clobber_v11_upper;
220  case 12: return selftest_clobber_v12_upper;
221  case 13: return selftest_clobber_v13_upper;
222  case 14: return selftest_clobber_v14_upper;
223  case 15: return selftest_clobber_v15_upper;
224  default: return NULL;
225  }
226 }
227 
228 static many_args_func *get_check_clobber_upper(int arg)
229 {
230  if (!(checkasm_get_cpu_flags() & SELFTEST_CPU_FLAG_AARCH64))
231  return NULL;
232 
233  switch (arg) {
234  case 0: return selftest_check_clobber_upper_x0_aarch64;
235  case 1: return selftest_check_clobber_upper_x1_aarch64;
236  case 2: return selftest_check_clobber_upper_x2_aarch64;
237  case 3: return selftest_check_clobber_upper_x3_aarch64;
238  case 4: return selftest_check_clobber_upper_x4_aarch64;
239  case 5: return selftest_check_clobber_upper_x5_aarch64;
240  case 6: return selftest_check_clobber_upper_x6_aarch64;
241  case 7: return selftest_check_clobber_upper_x7_aarch64;
242  case 8: return selftest_check_clobber_upper_stack0_aarch64;
243  case 9: return selftest_check_clobber_upper_stack1_aarch64;
244  case 10: return selftest_check_clobber_upper_stack2_aarch64;
245  default: return NULL;
246  }
247 }
248 
249 DEF_NOOP_GETTER(SELFTEST_CPU_FLAG_AARCH64, sigill_aarch64)
250 DEF_MANY_ARGS_GETTER(SELFTEST_CPU_FLAG_AARCH64, clobber_stack_args_aarch64)
251 DEF_MANY_ARGS_GETTER(SELFTEST_CPU_FLAG_AARCH64, clobber_stack_aarch64)
252 
253 DEF_MAX_INT_ARGS_GETTER(SELFTEST_CPU_FLAG_AARCH64, check_max_int_args_aarch64)
254 DEF_MAX_INT64_ARGS_GETTER(SELFTEST_CPU_FLAG_AARCH64, check_max_int64_args_aarch64)
255 
256 static void check_clobber_x(int from, int to)
257 {
258  checkasm_declare(void, int);
259 
260  for (int reg = from; reg < to; reg++) {
261  noop_func *clobber = get_clobber_x(reg);
262  if (!clobber)
263  break;
264 
265  if (checkasm_check_func(clobber, "clobber_x%d", reg)) {
267  }
268  }
269 
270  checkasm_report("clobber_x");
271 }
272 
273 static void check_clobber_d(int from, int to)
274 {
275  checkasm_declare(void, int);
276 
277  for (int reg = from; reg < to; reg++) {
278  noop_func *clobber = get_clobber_d(reg);
279  if (!clobber)
280  break;
281 
282  if (checkasm_check_func(clobber, "clobber_d%d", reg)) {
284  }
285  }
286 
287  checkasm_report("clobber_d");
288 }
289 
290 static void check_clobber_v_upper(int from, int to)
291 {
292  checkasm_declare(void, int);
293 
294  for (int reg = from; reg < to; reg++) {
295  noop_func *clobber = get_clobber_v_upper(reg);
296  if (!clobber)
297  break;
298 
299  if (checkasm_check_func(clobber, "clobber_v%d_upper", reg)) {
301  }
302  }
303 
304  checkasm_report("clobber_v_upper");
305 }
306 
307 static void check_clobber_arg_upper(void)
308 {
309  checkasm_declare(void, int, int, int, int, int, int, int, int, int, int, int);
310 
311  for (int arg = 0; arg < 11; arg++) {
312  many_args_func *check_clobber = get_check_clobber_upper(arg);
313  if (!check_clobber)
314  break;
315 
316  if (checkasm_check_func(check_clobber, "check_clobber_arg_upper_%d", arg)) {
317  checkasm_call_new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
318  }
319  }
320 
321  checkasm_report("check_clobber_arg_upper");
322 }
323 
324 static void selftest_test_many_args(many_args_func fun, const char *name)
325 {
326  checkasm_declare(void, int, int, int, int, int, int, int, int, int, int, int);
327 
328  if (checkasm_check_func(fun, "%s", name)) {
329  /* don't call unchecked because that one is called without wrapping,
330  * and we try to cloober the stack here. */
331  (void) func_ref;
332  checkasm_call_new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
333  }
334 
335  checkasm_report("%s", name);
336 }
337 
338 static void selftest_test_max_int_args(max_int_args_func fun, const char *name)
339 {
340  checkasm_declare(void, int, int, int, int, int, int, int, int, int, int, int, int,
341  int, int, int);
342 
343  if (checkasm_check_func(fun, "%s", name)) {
344  (void) func_ref;
345  checkasm_call_new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
346  }
347 
348  checkasm_report("%s", name);
349 }
350 
351 static void selftest_test_max_int64_args(max_int64_args_func fun, const char *name)
352 {
355  int64_t);
356 
357  if (checkasm_check_func(fun, "%s", name)) {
358  (void) func_ref;
359  checkasm_call_new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
360  }
361 
362  checkasm_report("%s", name);
363 }
364 
365 void selftest_check_aarch64(void)
366 {
367  check_clobber_x(0, 18);
368  // Don't try testing x18 - it has platform specific behaviour.
369  check_clobber_d(0, 8);
370  check_clobber_d(16, 32);
371  check_clobber_v_upper(8, 16);
372  selftest_test_many_args(get_clobber_stack_args_aarch64(), "clobber_stack_args");
373 
374  selftest_test_max_int_args(get_check_max_int_args_aarch64(), "check_max_int_args");
375  selftest_test_max_int64_args(get_check_max_int64_args_aarch64(),
376  "check_max_int64_args");
377  check_clobber_arg_upper();
378 
379  if (!checkasm_should_fail(SELFTEST_CPU_FLAG_AARCH64))
380  return;
381  selftest_test_noop(get_sigill_aarch64(), "sigill");
382  selftest_test_many_args(get_clobber_stack_aarch64(), "clobber_stack");
383  check_clobber_x(19, 30);
384  check_clobber_d(8, 16);
385 }
386 
387 #endif
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
checkasm_check_func
#define checkasm_check_func(func,...)
Check if a function should be tested and set up function references.
Definition: test.h:77
int64_t
long long int64_t
Definition: coverity.c:34
selftest_check_aarch64
void selftest_check_aarch64(void)
from
const char * from
Definition: jacosubdec.c:64
selftest_get_cpu_flags_aarch64
uint64_t selftest_get_cpu_flags_aarch64(void)
arg
const char * arg
Definition: jacosubdec.c:65
NULL
#define NULL
Definition: coverity.c:32
func_ref
#define func_ref
Definition: test.h:482
noop_func
void() noop_func(int unused)
Do nothing.
Definition: tests.h:94
to
const char * to
Definition: webvttdec.c:36
checkasm_declare
#define checkasm_declare(ret,...)
Declare a function signature for testing.
Definition: test.h:205
checkasm_report
CHECKASM_API void checkasm_report(const char *name,...) CHECKASM_PRINTF(1
Report test outcome for a named group of functions.
checkasm_get_cpu_flags
CHECKASM_API CheckasmCpu checkasm_get_cpu_flags(void)
Get the current active set of CPU flags.
Definition: checkasm.c:121
tests.h
DEF_NOOP_GETTER
#define DEF_NOOP_GETTER(FLAG, NAME)
Definition: tests.h:98
selftest_test_noop
void selftest_test_noop(noop_func fun, const char *name)
Definition: generic.c:83
DEF_NOOP_FUNC
#define DEF_NOOP_FUNC(NAME)
Definition: tests.h:97
checkasm_should_fail
CHECKASM_API int checkasm_should_fail(CheckasmCpu cpu_flags)
Mark a block of tests as expected to fail.
Definition: checkasm.c:1017
checkasm_call_new
#define checkasm_call_new(...)
Call the implementation being tested with validation.
Definition: test.h:381