History

arm64-win32 support : tests

Benjamin Oldenburg committed 7 months ago

Commit ea823181 parent 03d58b09 files · +972 −0Browse files

Unified · Split

9 files
  1. tests/libtcc_test_mt.c +13 −0
  2. tests/tests2/138_arm64_encoding.c +280 −0
  3. tests/tests2/138_arm64_encoding.expect +50 −0
  4. tests/tests2/139_arm64_errors.c +91 −0
  5. tests/tests2/139_arm64_errors.expect +32 −0
  6. tests/tests2/140_arm64_extasm.c +451 −0
  7. tests/tests2/140_arm64_extasm.expect +36 −0
  8. tests/tests2/73_arm64.c +15 −0
  9. tests/tests2/73_arm64.expect +4 −0
tests/libtcc_test_mt.c+13−0
@@ -338,7 +338,16 @@ int main(int argc, char **argv) · 337 unmodified lines
338#else338#else
339#include <tcclib.h>339#include <tcclib.h>
340 340
341#ifdef _WIN32
342# ifdef __i386__
343# define LIBTCC_TEST_WINAPI __attribute__((__stdcall__))
344# else
345# define LIBTCC_TEST_WINAPI
346# endif
347void LIBTCC_TEST_WINAPI Sleep(unsigned int milliseconds);
348#else
341unsigned int sleep(unsigned int seconds);349unsigned int sleep(unsigned int seconds);
350#endif
342 351
343int fib(n)352int fib(n)
344{353{
@@ -347,7 +356,11 @@ int fib(n) · 2 unmodified lines
347 356
348int main(int argc, char **argv)357int main(int argc, char **argv)
349{358{
359#ifdef _WIN32
360 Sleep(1000);
361#else
350 sleep(1);362 sleep(1);
363#endif
351 printf(" %d", fib(atoi(argv[1])));364 printf(" %d", fib(atoi(argv[1])));
352 return 0;365 return 0;
353}366}
tests/tests2/138_arm64_encoding.c+280−0
@@ -0,0 +1,280 @@
1/* ARM64 instruction encoding verification test.
2 Exercises shift-by-immediate, load/store addressing modes,
3 conditional branches, and system register access. */
4
5#include <stdio.h>
6#include <stdint.h>
7
8/* ---- shift-by-immediate helpers ---- */
9
10static uint32_t lsl32(uint32_t x, int n) { return x << n; }
11static uint32_t lsr32(uint32_t x, int n) { return x >> n; }
12static int32_t asr32(int32_t x, int n) { return x >> n; }
13static uint64_t lsl64(uint64_t x, int n) { return x << n; }
14static uint64_t lsr64(uint64_t x, int n) { return x >> n; }
15static int64_t asr64(int64_t x, int n) { return x >> n; }
16
17static void test_shifts(void)
18{
19 printf("shift-imm:\n");
20 printf("%x\n", lsl32(1, 0));
21 printf("%x\n", lsl32(1, 15));
22 printf("%x\n", lsl32(1, 31));
23 printf("%x\n", lsr32(0x80000000U, 31));
24 printf("%x\n", lsr32(0x80000000U, 16));
25 printf("%x\n", asr32(-1, 1));
26 printf("%x\n", asr32(-256, 4));
27 printf("%llx\n", (unsigned long long)lsl64(1ULL, 0));
28 printf("%llx\n", (unsigned long long)lsl64(1ULL, 32));
29 printf("%llx\n", (unsigned long long)lsl64(1ULL, 63));
30 printf("%llx\n", (unsigned long long)lsr64(0x8000000000000000ULL, 63));
31 printf("%llx\n", (unsigned long long)asr64(-1LL, 1));
32 printf("%llx\n", (unsigned long long)asr64(-256LL, 4));
33}
34
35/* ---- load/store with various addressing modes ---- */
36
37static void test_ldr_str(void)
38{
39 int64_t buf[4] = { 0x1122334455667788LL, 0x99AABBCCDDEEFF00LL,
40 0x0F1E2D3C4B5A6978LL, 0x0000000000000001LL };
41 int64_t val;
42 int32_t wval;
43 int64_t *p;
44
45 printf("ldr-str:\n");
46
47 /* LDR X, [Xn, #offset] */
48 val = buf[0];
49 printf("%llx\n", (unsigned long long)val);
50 val = buf[1];
51 printf("%llx\n", (unsigned long long)val);
52
53 /* LDR W, [Xn, #offset] (32-bit load) */
54 wval = *(int32_t*)&buf[0];
55 printf("%x\n", (unsigned)wval);
56
57 /* Pre-indexed: store pointer, modify */
58 p = &buf[0];
59 val = *(p + 2);
60 printf("%llx\n", (unsigned long long)val);
61
62 /* Post-indexed simulation via pointer arithmetic */
63 p = &buf[0];
64 val = *p;
65 p++;
66 printf("%llx %llx\n", (unsigned long long)val,
67 (unsigned long long)*p);
68}
69
70/* ---- STP/LDP (store/load pair) ---- */
71
72static void test_ldp_stp(void)
73{
74 int64_t src[2] = { 0xAAAABBBBCCCCDDDDLL, 0x1111222233334444LL };
75 int64_t dst[2];
76
77 /* The compiler should use stp/ldp for this */
78 dst[0] = src[0];
79 dst[1] = src[1];
80
81 printf("ldp-stp:\n");
82 printf("%llx %llx\n",
83 (unsigned long long)dst[0],
84 (unsigned long long)dst[1]);
85}
86
87/* ---- CBZ / CBNZ via C patterns ---- */
88
89static const char *cbz_test(int x)
90{
91 if (x == 0)
92 return "zero";
93 return "nonzero";
94}
95
96static const char *cbnz_test(int x)
97{
98 if (x != 0)
99 return "nonzero";
100 return "zero";
101}
102
103static void test_cond_branches(void)
104{
105 printf("cbz-cbnz:\n");
106 printf("%s\n", cbz_test(0));
107 printf("%s\n", cbz_test(42));
108 printf("%s\n", cbnz_test(0));
109 printf("%s\n", cbnz_test(42));
110}
111
112/* ---- conditional compare patterns (CCMP/CCMN) ---- */
113
114static int cond_select(int a, int b)
115{
116 /* TCC should generate csel or equivalent */
117 return a > b ? a : b;
118}
119
120static void test_cond_select(void)
121{
122 printf("csel:\n");
123 printf("%d\n", cond_select(5, 10));
124 printf("%d\n", cond_select(10, 5));
125 printf("%d\n", cond_select(0, 0));
126 printf("%d\n", cond_select(-1, 1));
127}
128
129/* ---- MRS/MSR system registers (FPCR/FPSR) ---- */
130
131static void test_sysregs(void)
132{
133 unsigned int fpcr, fpsr;
134
135 printf("sysregs:\n");
136
137 /* Read FPCR */
138 __asm__ volatile ("mrs %0, fpcr" : "=r"(fpcr));
139 printf("%u\n", fpcr & 0x0F);
140
141 /* Read FPSR */
142 __asm__ volatile ("mrs %0, fpsr" : "=r"(fpsr));
143 printf("%u\n", fpsr);
144
145 /* Write/restore FPCR (should be same value) */
146 __asm__ volatile ("msr fpcr, %0" : : "r"(fpcr));
147
148 /* Read back and verify */
149 {
150 unsigned int check;
151 __asm__ volatile ("mrs %0, fpcr" : "=r"(check));
152 printf("%s\n", check == fpcr ? "ok" : "fail");
153 }
154}
155
156/* ---- NOP encoding (should not crash) ---- */
157
158static void test_nop(void)
159{
160 printf("nop:\n");
161 __asm__ volatile ("nop");
162 __asm__ volatile ("nop");
163 __asm__ volatile ("nop");
164 printf("ok\n");
165}
166
167/* ---- barrier instructions ---- */
168
169static void test_barriers(void)
170{
171 printf("barriers:\n");
172 __asm__ volatile ("dmb sy");
173 __asm__ volatile ("dsb sy");
174 __asm__ volatile ("isb");
175 printf("ok\n");
176}
177
178/* ---- MOV (register) patterns ---- */
179
180static int64_t mov_x0_x1(int64_t x)
181{
182 register int64_t r __asm__("x0") = x;
183 __asm__ volatile ("" : "=r"(r) : "0"(r));
184 return r;
185}
186
187static void test_mov_reg(void)
188{
189 printf("mov-reg:\n");
190 printf("%lld\n", (long long)mov_x0_x1(42));
191 printf("%lld\n", (long long)mov_x0_x1(-1));
192}
193
194/* ---- large struct passing (reference semantics) ---- */
195
196struct large { int64_t a, b, c, d; };
197
198static int64_t sum_large(struct large s)
199{
200 return s.a + s.b + s.c + s.d;
201}
202
203static struct large make_large(int64_t a, int64_t b, int64_t c, int64_t d)
204{
205 struct large s = { a, b, c, d };
206 return s;
207}
208
209static void test_large_structs(void)
210{
211 struct large s = { 1, 2, 3, 4 };
212 struct large t;
213
214 printf("large-struct:\n");
215 printf("%lld\n", (long long)sum_large(s));
216
217 t = make_large(10, 20, 30, 40);
218 printf("%lld %lld %lld %lld\n",
219 (long long)t.a, (long long)t.b,
220 (long long)t.c, (long long)t.d);
221}
222
223/* ---- boundary-sized structs ---- */
224
225struct s18 { char x[18]; };
226struct s24 { char x[24]; };
227struct s32 { char x[32]; };
228
229static void print_s18(struct s18 s) { printf("%.18s\n", s.x); }
230static void print_s24(struct s24 s) { printf("%.24s\n", s.x); }
231static void print_s32(struct s32 s) { printf("%.32s\n", s.x); }
232
233static struct s18 ret_s18(void)
234{
235 struct s18 s = { "123456789012345678" };
236 return s;
237}
238
239static struct s24 ret_s24(void)
240{
241 struct s24 s = { "123456789012345678901234" };
242 return s;
243}
244
245static struct s32 ret_s32(void)
246{
247 struct s32 s = { "12345678901234567890123456789012" };
248 return s;
249}
250
251static void test_boundary_structs(void)
252{
253 struct s18 a;
254 struct s24 b;
255 struct s32 c;
256
257 printf("boundary-structs:\n");
258 a = ret_s18();
259 printf("%.18s\n", a.x);
260 b = ret_s24();
261 printf("%.24s\n", b.x);
262 c = ret_s32();
263 printf("%.32s\n", c.x);
264}
265
266int main(void)
267{
268 test_shifts();
269 test_ldr_str();
270 test_ldp_stp();
271 test_cond_branches();
272 test_cond_select();
273 test_sysregs();
274 test_nop();
275 test_barriers();
276 test_mov_reg();
277 test_large_structs();
278 test_boundary_structs();
279 return 0;
280}
tests/tests2/138_arm64_encoding.expect+50−0
@@ -0,0 +1,50 @@
1shift-imm:
21
38000
480000000
51
68000
7ffffffff
8fffffff0
91
10100000000
118000000000000000
121
13ffffffffffffffff
14fffffffffffffff0
15ldr-str:
161122334455667788
1799aabbccddeeff00
1855667788
19f1e2d3c4b5a6978
201122334455667788 99aabbccddeeff00
21ldp-stp:
22aaaabbbbccccdddd 1111222233334444
23cbz-cbnz:
24zero
25nonzero
26zero
27nonzero
28csel:
2910
3010
310
321
33sysregs:
340
350
36ok
37nop:
38ok
39barriers:
40ok
41mov-reg:
4242
43-1
44large-struct:
4510
4610 20 30 40
47boundary-structs:
48123456789012345678
49123456789012345678901234
5012345678901234567890123456789012
tests/tests2/139_arm64_errors.c+91−0
@@ -0,0 +1,91 @@
1/* ARM64 inline assembly error tests.
2 Verify that invalid assembly produces proper error messages.
3 Run with -dt; skipped on non-arm64 architectures. */
4
5#include <stdio.h>
6
7#if defined test_unknown_instruction
8int main(void)
9{
10 __asm__("fubar x0, x1, x2");
11 return 0;
12}
13
14#elif defined test_shift_imm_range_32
15int main(void)
16{
17 /* LSL by 32 is out of range for 32-bit operand */
18 __asm__("lsl w0, w1, #32");
19 return 0;
20}
21
22#elif defined test_shift_imm_range_64
23int main(void)
24{
25 /* LSL by 64 is out of range for 64-bit operand */
26 __asm__("lsl x0, x1, #64");
27 return 0;
28}
29
30#elif defined test_invalid_sysreg
31int main(void)
32{
33 /* Bogus system register name */
34 __asm__("mrs x0, bogusreg");
35 return 0;
36}
37
38#elif defined test_invalid_barrier_option
39int main(void)
40{
41 /* Invalid barrier scope name */
42 __asm__("dmb xyz");
43 return 0;
44}
45
46#elif defined test_missing_third_operand
47int main(void)
48{
49 __asm__("add x0, x1");
50 return 0;
51}
52
53#elif defined test_movz_imm_range
54int main(void)
55{
56 __asm__("movz x0, #0x10000");
57 return 0;
58}
59
60#elif defined test_movz_shift_range
61int main(void)
62{
63 __asm__("movz x0, #1, lsl #8");
64 return 0;
65}
66
67#elif defined test_invalid_muls
68int main(void)
69{
70 __asm__("muls x0, x1, x2");
71 return 0;
72}
73
74#elif defined test_extended_inline_asm
75int main(void)
76{
77 int x = 1;
78 /* Invalid operand reference in extended inline asm */
79 __asm__("add %0, %1, #1" : "=r"(x) : "2"(x));
80 return 0;
81}
82
83#elif defined test_extended_inline_clobber
84int main(void)
85{
86 /* Invalid clobber register name */
87 __asm__ volatile ("nop" : : : "bogus");
88 return 0;
89}
90
91#endif
tests/tests2/139_arm64_errors.expect+32−0
@@ -0,0 +1,32 @@
1[test_unknown_instruction]
2139_arm64_errors.c:10: error: ARM64 instruction 'fubar' not implemented
3
4[test_shift_imm_range_32]
5139_arm64_errors.c:17: error: shift immediate out of range
6
7[test_shift_imm_range_64]
8139_arm64_errors.c:25: error: shift immediate out of range
9
10[test_invalid_sysreg]
11139_arm64_errors.c:34: error: unsupported system register
12
13[test_invalid_barrier_option]
14139_arm64_errors.c:42: error: invalid operand 'xyz'
15
16[test_missing_third_operand]
17139_arm64_errors.c:48: error: missing third operand
18
19[test_movz_imm_range]
20139_arm64_errors.c:55: error: move wide immediate out of range
21
22[test_movz_shift_range]
23139_arm64_errors.c:62: error: move wide shift out of range
24
25[test_invalid_muls]
26139_arm64_errors.c:70: error: ARM64 instruction 'muls' not implemented
27
28[test_extended_inline_asm]
29139_arm64_errors.c:79: error: invalid reference in constraint 1 ('2')
30
31[test_extended_inline_clobber]
32139_arm64_errors.c:87: error: invalid clobber register 'bogus'
tests/tests2/140_arm64_extasm.c+451−0
@@ -0,0 +1,451 @@
1/*
2 * ARM64 Extended Inline Assembly Tests
3 * Tests for GCC-style extended inline assembly with operands, constraints, and clobbers
4 */
5
6#include <stdio.h>
7#include <stdint.h>
8#include <assert.h>
9
10struct pair64 {
11 uint64_t a;
12 uint64_t b;
13};
14
15static int arm64_symbol_target(void)
16{
17 return 7;
18}
19
20static void test_symbolic_address_constraint_compile_only(void)
21{
22 asm volatile("" : : "S"(arm64_symbol_target));
23}
24
25/* Test 1: Basic output operand */
26void test_basic_output(void)
27{
28 int x;
29 asm("mov %0, #42" : "=r"(x));
30 assert(x == 42);
31 printf("Test 1 (basic output): PASSED\n");
32}
33
34/* Test 2: Input operand */
35void test_input_operand(void)
36{
37 int x = 10;
38 int y;
39 asm("add %0, %1, #5" : "=r"(y) : "r"(x));
40 assert(y == 15);
41 printf("Test 2 (input operand): PASSED\n");
42}
43
44/* Test 3: Read-write operand */
45void test_read_write_operand(void)
46{
47 int x = 10;
48 asm("add %0, %0, #1" : "+r"(x));
49 assert(x == 11);
50 printf("Test 3 (read-write operand): PASSED\n");
51}
52
53/* Test 4: Memory operand - load */
54void test_memory_load(void)
55{
56 int x = 42;
57 int y;
58 asm("ldr %w0, [%1]" : "=r"(y) : "r"(&x));
59 assert(y == 42);
60 printf("Test 4 (memory load): PASSED\n");
61}
62
63/* Test 5: Memory operand - store */
64void test_memory_store(void)
65{
66 int x;
67 int val = 123;
68 asm("str %w1, [%0]" : : "r"(&x), "r"(val));
69 assert(x == 123);
70 printf("Test 5 (memory store): PASSED\n");
71}
72
73/* Test 5a: Stack memory operand with frame-relative offset */
74void test_stack_memory_operand(void)
75{
76 long x = 0;
77 long val = 321;
78
79 asm volatile("str %0, %1" : : "r"(val), "m"(x));
80 assert(x == 321);
81 printf("Test 5a (stack memory operand): PASSED\n");
82}
83
84/* Test 5b: Symbol memory operand */
85static long arm64_symbol_mem;
86
87void test_symbol_memory_operand(void)
88{
89 long val = 654;
90
91 arm64_symbol_mem = 0;
92 asm volatile("str %0, %1" : : "r"(val), "m"(arm64_symbol_mem));
93 assert(arm64_symbol_mem == 654);
94 printf("Test 5b (symbol memory operand): PASSED\n");
95}
96
97/* Test 6: Clobber list */
98void test_clobber_list(void)
99{
100 int x = 10;
101 int y = 20;
102 int result;
103 asm("add %0, %1, %2"
104 : "=r"(result)
105 : "r"(x), "r"(y)
106 : "cc");
107 assert(result == 30);
108 printf("Test 6 (clobber list): PASSED\n");
109}
110
111/* Test 7: Multiple outputs */
112void test_multiple_outputs(void)
113{
114 int a, b;
115 asm("mov %0, #1; mov %1, #2"
116 : "=r"(a), "=r"(b));
117 assert(a == 1 && b == 2);
118 printf("Test 7 (multiple outputs): PASSED\n");
119}
120
121/* Test 8: Constraint reference */
122void test_constraint_reference(void)
123{
124 int x = 10;
125 int y;
126 asm("add %0, %1, #5" : "=r"(y) : "0"(x));
127 assert(y == 15);
128 printf("Test 8 (constraint reference): PASSED\n");
129}
130
131/* Test 9: Early clobber */
132void test_early_clobber(void)
133{
134 int x = 10;
135 int y;
136 asm("mov %0, #42" : "=&r"(y) : "r"(x));
137 assert(y == 42);
138 printf("Test 9 (early clobber): PASSED\n");
139}
140
141/* Test 10: 32-bit register modifier */
142void test_w_register(void)
143{
144 uint32_t x = 100;
145 uint32_t y;
146 asm("add %w0, %w1, #50" : "=r"(y) : "r"(x));
147 assert(y == 150);
148 printf("Test 10 (w register modifier): PASSED\n");
149}
150
151/* Test 11: Immediate constraint 'I' (12-bit immediate) */
152void test_immediate_i_constraint(void)
153{
154 int x = 100;
155 int y;
156 asm("add %0, %1, #200" : "=r"(y) : "r"(x), "I"(200));
157 assert(y == 300);
158 printf("Test 11 (immediate I constraint): PASSED\n");
159}
160
161/* Test 12: Register constraint */
162void test_general_operand_constraint(void)
163{
164 int x = 50;
165 int y;
166 asm("add %0, %1, #10" : "=r"(y) : "r"(x));
167 assert(y == 60);
168 printf("Test 12 (general operand constraint): PASSED\n");
169}
170
171/* Test 13: Multiple inputs and outputs */
172void test_multiple_io(void)
173{
174 int a = 10, b = 20;
175 int sum, diff;
176 asm("add %0, %1, %2" : "=r"(sum) : "r"(a), "r"(b));
177 asm("sub %0, %1, %2" : "=r"(diff) : "r"(a), "r"(b));
178 assert(sum == 30 && diff == -10);
179 printf("Test 13 (multiple IO): PASSED\n");
180}
181
182/* Test 14: Register variable preservation */
183void test_regvar_preservation(void)
184{
185 register uint64_t keep asm("x19") = 0x123456789abcdef0ULL;
186 uint64_t out;
187
188 asm volatile("mov x19, #7; add %0, x19, #1"
189 : "=r"(out)
190 :
191 : "x19");
192 assert(keep == 0x123456789abcdef0ULL);
193 assert(out == 8);
194 printf("Test 14 (regvar preservation): PASSED\n");
195}
196
197/* Test 15: Complex arithmetic */
198void test_complex_arithmetic(void)
199{
200 int a = 100, b = 50, c = 25;
201 int result;
202 asm("add %0, %1, %2; sub %0, %0, %3"
203 : "=&r"(result)
204 : "r"(a), "r"(b), "r"(c));
205 assert(result == 125);
206 printf("Test 15 (complex arithmetic): PASSED\n");
207}
208
209/* Test 16: Named operand (GCC extension) */
210void test_named_operand(void)
211{
212 int input = 10;
213 int output;
214 asm("add %[out], %[in], #5"
215 : [out] "=r"(output)
216 : [in] "r"(input));
217 assert(output == 15);
218 printf("Test 16 (named operand): PASSED\n");
219}
220
221/* Test 17: Memory clobber */
222void test_memory_clobber(void)
223{
224 int x = 10;
225 asm volatile("" : : : "memory");
226 assert(x == 10);
227 printf("Test 17 (memory clobber): PASSED\n");
228}
229
230/* Test 18: Condition flags clobber */
231void test_cc_clobber(void)
232{
233 int x = 100;
234 int y;
235 asm("adds %0, %1, #0" : "=r"(y) : "r"(x) : "cc");
236 assert(y == 100);
237 printf("Test 18 (cc clobber): PASSED\n");
238}
239
240/* Test 19: Large immediate with movz/movk */
241void test_large_immediate(void)
242{
243 uint64_t val;
244 asm("movz %0, #0x1234, lsl #16; movk %0, #0x5678" : "=r"(val));
245 assert(val == 0x12345678ULL);
246 printf("Test 19 (large immediate): PASSED\n");
247}
248
249/* Test 20: Bitwise operations */
250void test_bitwise_ops(void)
251{
252 uint64_t a = 0xf0f0f0f00f0f0f0fULL;
253 uint64_t b = 0x3333ffff0000ccccULL;
254 uint64_t andv;
255 uint64_t orv;
256 uint64_t xorv;
257 uint64_t imm_and;
258
259 asm("and %0, %1, %2" : "=r"(andv) : "r"(a), "r"(b));
260 asm("orr %0, %1, %2" : "=r"(orv) : "r"(a), "r"(b));
261 asm("eor %0, %1, %2" : "=r"(xorv) : "r"(a), "r"(b));
262 asm("and %0, %1, %2" : "=r"(imm_and)
263 : "r"(~0ULL), "L"(0xff00ff00ff00ff00ULL));
264
265 assert(andv == (a & b));
266 assert(orv == (a | b));
267 assert(xorv == (a ^ b));
268 assert(imm_and == 0xff00ff00ff00ff00ULL);
269 printf("Test 20 (bitwise ops): PASSED\n");
270}
271
272/* Test 21: Register shift operands */
273void test_register_shift_operands(void)
274{
275 uint64_t val = 3;
276 uint64_t amount = 4;
277 uint64_t shifted;
278 uint64_t rotated;
279
280 asm("lsl %0, %1, %2" : "=r"(shifted) : "r"(val), "r"(amount));
281 asm("ror %0, %1, %2" : "=r"(rotated)
282 : "r"(0x0123456789abcdefULL), "r"(8ULL));
283 assert(shifted == 48);
284 assert(rotated == 0xef0123456789abcdULL);
285 printf("Test 21 (register shifts): PASSED\n");
286}
287
288/* Test 22: ROR immediate alias of EXTR */
289void test_ror_immediate(void)
290{
291 uint64_t rotated;
292
293 asm("ror %0, %1, #8" : "=r"(rotated) : "r"(0x0123456789abcdefULL));
294 assert(rotated == 0xef0123456789abcdULL);
295 printf("Test 22 (ror immediate): PASSED\n");
296}
297
298/* Test 23: FP/SIMD register constraint and modifier */
299void test_fp_register_operand(void)
300{
301 double x = 3.5;
302 double y;
303
304 asm("ldr %d0, [%1]" : "=w"(y) : "r"(&x));
305 assert(y == x);
306 printf("Test 23 (fp register operand): PASSED\n");
307}
308
309/* Test 24: Zero constraint */
310void test_zero_constraint(void)
311{
312 uint64_t x = 41;
313 uint64_t y;
314
315 asm("add %0, %1, %x2" : "=r"(y) : "r"(x), "Z"(0));
316 assert(y == x);
317 printf("Test 24 (Z constraint): PASSED\n");
318}
319
320/* Test 25: 32-bit logical immediate constraint */
321void test_logical_imm32_constraint(void)
322{
323 uint32_t y;
324
325 asm("orr %w0, wzr, %1" : "=r"(y) : "K"(0xff));
326 assert(y == 0xff);
327 printf("Test 25 (K constraint): PASSED\n");
328}
329
330/* Test 26: 64-bit logical immediate constraint */
331void test_logical_imm64_constraint(void)
332{
333 uint64_t y;
334
335 asm("orr %0, xzr, %1" : "=r"(y) : "L"(0xff00ff00ff00ff00ULL));
336 assert(y == 0xff00ff00ff00ff00ULL);
337 printf("Test 26 (L constraint): PASSED\n");
338}
339
340/* Test 27: 32-bit MOV pseudo immediate constraint */
341void test_mov_imm32_constraint(void)
342{
343 uint32_t y;
344
345 asm("mov %w0, %1" : "=r"(y) : "M"(0x1234));
346 assert(y == 0x1234);
347 printf("Test 27 (M constraint): PASSED\n");
348}
349
350/* Test 28: 64-bit MOV pseudo immediate constraint */
351void test_mov_imm64_constraint(void)
352{
353 uint64_t y;
354
355 asm("mov %0, %1" : "=r"(y) : "N"(0x12340000ULL));
356 assert(y == 0x12340000ULL);
357 printf("Test 28 (N constraint): PASSED\n");
358}
359
360/* Test 29: x FP/SIMD register constraint */
361void test_x_constraint_fp(void)
362{
363 double x = 6.25;
364 double y;
365
366 asm("ldr %d0, [%1]" : "=x"(y) : "r"(&x));
367 assert(y == x);
368 printf("Test 29 (x constraint): PASSED\n");
369}
370
371/* Test 30: y FP/SIMD register constraint */
372void test_y_constraint_fp(void)
373{
374 double x = 7.25;
375 double y;
376
377 asm("ldr %d0, [%1]" : "=y"(y) : "r"(&x));
378 assert(y == x);
379 printf("Test 30 (y constraint): PASSED\n");
380}
381
382/* Test 31: Q memory constraint */
383static int arm64_q_load(int *ptr)
384{
385 int y;
386
387 asm("ldr %w0, %1" : "=r"(y) : "Q"(*ptr));
388 return y;
389}
390
391void test_q_memory_constraint(void)
392{
393 int x = 91;
394 assert(arm64_q_load(&x) == 91);
395 printf("Test 31 (Q constraint): PASSED\n");
396}
397
398/* Test 32: Ump pair-memory constraint */
399void test_ump_memory_constraint(void)
400{
401 struct pair64 pair = { 0x1122334455667788ULL, 0x99aabbccddeeff00ULL };
402 uint64_t a;
403 uint64_t b;
404
405 asm("ldp %0, %1, %2" : "=r"(a), "=r"(b) : "Ump"(pair));
406 assert(a == pair.a);
407 assert(b == pair.b);
408 printf("Test 32 (Ump constraint): PASSED\n");
409}
410
411int main(void)
412{
413 printf("ARM64 Extended Inline Assembly Tests\n");
414 test_basic_output();
415 test_input_operand();
416 test_read_write_operand();
417 test_memory_load();
418 test_memory_store();
419 test_stack_memory_operand();
420 test_symbol_memory_operand();
421 test_clobber_list();
422 test_multiple_outputs();
423 test_constraint_reference();
424 test_early_clobber();
425 test_w_register();
426 test_immediate_i_constraint();
427 test_general_operand_constraint();
428 test_multiple_io();
429 test_regvar_preservation();
430 test_complex_arithmetic();
431 test_named_operand();
432 test_memory_clobber();
433 test_cc_clobber();
434 test_large_immediate();
435 test_bitwise_ops();
436 test_register_shift_operands();
437 test_ror_immediate();
438 test_fp_register_operand();
439 test_zero_constraint();
440 test_logical_imm32_constraint();
441 test_logical_imm64_constraint();
442 test_mov_imm32_constraint();
443 test_mov_imm64_constraint();
444 test_x_constraint_fp();
445 test_y_constraint_fp();
446 test_q_memory_constraint();
447 test_ump_memory_constraint();
448 test_symbolic_address_constraint_compile_only();
449 printf("ARM64 Extended Inline Assembly Tests PASSED!\n");
450 return 0;
451}
tests/tests2/140_arm64_extasm.expect+36−0
@@ -0,0 +1,36 @@
1ARM64 Extended Inline Assembly Tests
2Test 1 (basic output): PASSED
3Test 2 (input operand): PASSED
4Test 3 (read-write operand): PASSED
5Test 4 (memory load): PASSED
6Test 5 (memory store): PASSED
7Test 5a (stack memory operand): PASSED
8Test 5b (symbol memory operand): PASSED
9Test 6 (clobber list): PASSED
10Test 7 (multiple outputs): PASSED
11Test 8 (constraint reference): PASSED
12Test 9 (early clobber): PASSED
13Test 10 (w register modifier): PASSED
14Test 11 (immediate I constraint): PASSED
15Test 12 (general operand constraint): PASSED
16Test 13 (multiple IO): PASSED
17Test 14 (regvar preservation): PASSED
18Test 15 (complex arithmetic): PASSED
19Test 16 (named operand): PASSED
20Test 17 (memory clobber): PASSED
21Test 18 (cc clobber): PASSED
22Test 19 (large immediate): PASSED
23Test 20 (bitwise ops): PASSED
24Test 21 (register shifts): PASSED
25Test 22 (ror immediate): PASSED
26Test 23 (fp register operand): PASSED
27Test 24 (Z constraint): PASSED
28Test 25 (K constraint): PASSED
29Test 26 (L constraint): PASSED
30Test 27 (M constraint): PASSED
31Test 28 (N constraint): PASSED
32Test 29 (x constraint): PASSED
33Test 30 (y constraint): PASSED
34Test 31 (Q constraint): PASSED
35Test 32 (Ump constraint): PASSED
36ARM64 Extended Inline Assembly Tests PASSED!
tests/tests2/73_arm64.c+15−0
@@ -38,6 +38,11 @@ struct hfa32 { long double a, b; } hfa32 = { 32.1, 32.2 }; · 37 unmodified lines
38struct hfa33 { long double a, b, c; } hfa33 = { 33.1, 33.2, 33.3 };38struct hfa33 { long double a, b, c; } hfa33 = { 33.1, 33.2, 33.3 };
39struct hfa34 { long double a, b, c, d; } hfa34 = { 34.1, 34.2, 34.3, 34.4 };39struct hfa34 { long double a, b, c, d; } hfa34 = { 34.1, 34.2, 34.3, 34.4 };
40 40
41struct empty { };
42/* Keep the top-level offsets at zero without changing the type into a union. */
43struct hfae12 { struct empty e; struct hfa12 h; } hfae12 = { { }, { 112.1, 112.2 } };
44struct hfae22 { struct empty e; struct hfa22 h; } hfae22 = { { }, { 122.1, 122.2 } };
45
41void fa_s1(struct s1 a) { printf("%.1s\n", a.x); }46void fa_s1(struct s1 a) { printf("%.1s\n", a.x); }
42void fa_s2(struct s2 a) { printf("%.2s\n", a.x); }47void fa_s2(struct s2 a) { printf("%.2s\n", a.x); }
43void fa_s3(struct s3 a) { printf("%.3s\n", a.x); }48void fa_s3(struct s3 a) { printf("%.3s\n", a.x); }
@@ -82,6 +87,10 @@ void fa_hfa33(struct hfa33 a) · 38 unmodified lines
82{ printf("%.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c); }87{ printf("%.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c); }
83void fa_hfa34(struct hfa34 a)88void fa_hfa34(struct hfa34 a)
84{ printf("%.1Lf %.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c, a.d); }89{ printf("%.1Lf %.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c, a.d); }
90void fa_hfae12(struct hfae12 a)
91{ printf("%.1f %.1f\n", a.h.a, a.h.b); }
92void fa_hfae22(struct hfae22 a)
93{ printf("%.1f %.1f\n", a.h.a, a.h.b); }
85 94
86void fa1(struct s8 a, struct s9 b, struct s10 c, struct s11 d,95void fa1(struct s8 a, struct s9 b, struct s10 c, struct s11 d,
87 struct s12 e, struct s13 f)96 struct s12 e, struct s13 f)
@@ -140,6 +149,8 @@ void arg(void) · 52 unmodified lines
140 fa_hfa32(hfa32);149 fa_hfa32(hfa32);
141 fa_hfa33(hfa33);150 fa_hfa33(hfa33);
142 fa_hfa34(hfa34);151 fa_hfa34(hfa34);
152 fa_hfae12(hfae12);
153 fa_hfae22(hfae22);
143 fa1(s8, s9, s10, s11, s12, s13);154 fa1(s8, s9, s10, s11, s12, s13);
144 fa2(s9, s10, s11, s12, s13, s14);155 fa2(s9, s10, s11, s12, s13, s14);
145 fa3(hfa14, hfa23, hfa32);156 fa3(hfa14, hfa23, hfa32);
@@ -178,6 +189,8 @@ struct hfa31 fr_hfa31(void) { return hfa31; } · 32 unmodified lines
178struct hfa32 fr_hfa32(void) { return hfa32; }189struct hfa32 fr_hfa32(void) { return hfa32; }
179struct hfa33 fr_hfa33(void) { return hfa33; }190struct hfa33 fr_hfa33(void) { return hfa33; }
180struct hfa34 fr_hfa34(void) { return hfa34; }191struct hfa34 fr_hfa34(void) { return hfa34; }
192struct hfae12 fr_hfae12(void) { return hfae12; }
193struct hfae22 fr_hfae22(void) { return hfae22; }
181 194
182void ret(void)195void ret(void)
183{196{
@@ -228,6 +241,8 @@ void ret(void) · 44 unmodified lines
228 printf("%.1Lf %.1Lf\n", fr_hfa32().a, fr_hfa32().b);241 printf("%.1Lf %.1Lf\n", fr_hfa32().a, fr_hfa32().b);
229 printf("%.1Lf %.1Lf\n", fr_hfa33().a, fr_hfa33().c);242 printf("%.1Lf %.1Lf\n", fr_hfa33().a, fr_hfa33().c);
230 printf("%.1Lf %.1Lf\n", fr_hfa34().a, fr_hfa34().d);243 printf("%.1Lf %.1Lf\n", fr_hfa34().a, fr_hfa34().d);
244 printf("%.1f %.1f\n", fr_hfae12().h.a, fr_hfae12().h.b);
245 printf("%.1f %.1f\n", fr_hfae22().h.a, fr_hfae22().h.b);
231}246}
232 247
233void*248void*
tests/tests2/73_arm64.expect+4−0
@@ -28,6 +28,8 @@ cdefghijklmnopqrs · 27 unmodified lines
2832.1 32.12832.1 32.1
2933.1 33.2 33.32933.1 33.2 33.3
3034.1 34.2 34.3 34.43034.1 34.2 34.3 34.4
31112.1 112.2
32122.1 122.2
31stu ABC JKL TUV 456 ghi33stu ABC JKL TUV 456 ghi
32ABC JKL TUV 456 ghi tuv34ABC JKL TUV 456 ghi tuv
3314.1 14.4 23.1 23.3 32.1 32.23514.1 14.4 23.1 23.3 32.1 32.2
@@ -62,6 +64,8 @@ cdefghijklmnopqrs · 28 unmodified lines
6232.1 32.26432.1 32.2
6333.1 33.36533.1 33.3
6434.1 34.46634.1 34.4
67112.1 112.2
68122.1 122.2
65stdarg:69stdarg:
66ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI70ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI
67lmnopqr ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI71lmnopqr ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t