Unified · Split
| @@ -338,7 +338,16 @@ int main(int argc, char **argv) · 337 unmodified lines | ||
| 338 | 338 | #else |
| 339 | 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 | |
| 347 | +void LIBTCC_TEST_WINAPI Sleep(unsigned int milliseconds); | |
| 348 | +#else | |
| 341 | 349 | unsigned int sleep(unsigned int seconds); |
| 350 | +#endif | |
| 342 | 351 | |
| 343 | 352 | int fib(n) |
| 344 | 353 | { |
| @@ -347,7 +356,11 @@ int fib(n) · 2 unmodified lines | ||
| 347 | 356 | |
| 348 | 357 | int main(int argc, char **argv) |
| 349 | 358 | { |
| 359 | +#ifdef _WIN32 | |
| 360 | + Sleep(1000); | |
| 361 | +#else | |
| 350 | 362 | sleep(1); |
| 363 | +#endif | |
| 351 | 364 | printf(" %d", fib(atoi(argv[1]))); |
| 352 | 365 | return 0; |
| 353 | 366 | } |
| @@ -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 | + | |
| 10 | +static uint32_t lsl32(uint32_t x, int n) { return x << n; } | |
| 11 | +static uint32_t lsr32(uint32_t x, int n) { return x >> n; } | |
| 12 | +static int32_t asr32(int32_t x, int n) { return x >> n; } | |
| 13 | +static uint64_t lsl64(uint64_t x, int n) { return x << n; } | |
| 14 | +static uint64_t lsr64(uint64_t x, int n) { return x >> n; } | |
| 15 | +static int64_t asr64(int64_t x, int n) { return x >> n; } | |
| 16 | + | |
| 17 | +static 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 | + | |
| 37 | +static 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 | + | |
| 72 | +static 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 | + | |
| 89 | +static const char *cbz_test(int x) | |
| 90 | +{ | |
| 91 | + if (x == 0) | |
| 92 | + return "zero"; | |
| 93 | + return "nonzero"; | |
| 94 | +} | |
| 95 | + | |
| 96 | +static const char *cbnz_test(int x) | |
| 97 | +{ | |
| 98 | + if (x != 0) | |
| 99 | + return "nonzero"; | |
| 100 | + return "zero"; | |
| 101 | +} | |
| 102 | + | |
| 103 | +static 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 | + | |
| 114 | +static int cond_select(int a, int b) | |
| 115 | +{ | |
| 116 | + /* TCC should generate csel or equivalent */ | |
| 117 | + return a > b ? a : b; | |
| 118 | +} | |
| 119 | + | |
| 120 | +static 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 | + | |
| 131 | +static 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 | + | |
| 158 | +static 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 | + | |
| 169 | +static 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 | + | |
| 180 | +static 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 | + | |
| 187 | +static 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 | + | |
| 196 | +struct large { int64_t a, b, c, d; }; | |
| 197 | + | |
| 198 | +static int64_t sum_large(struct large s) | |
| 199 | +{ | |
| 200 | + return s.a + s.b + s.c + s.d; | |
| 201 | +} | |
| 202 | + | |
| 203 | +static 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 | + | |
| 209 | +static 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 | + | |
| 225 | +struct s18 { char x[18]; }; | |
| 226 | +struct s24 { char x[24]; }; | |
| 227 | +struct s32 { char x[32]; }; | |
| 228 | + | |
| 229 | +static void print_s18(struct s18 s) { printf("%.18s\n", s.x); } | |
| 230 | +static void print_s24(struct s24 s) { printf("%.24s\n", s.x); } | |
| 231 | +static void print_s32(struct s32 s) { printf("%.32s\n", s.x); } | |
| 232 | + | |
| 233 | +static struct s18 ret_s18(void) | |
| 234 | +{ | |
| 235 | + struct s18 s = { "123456789012345678" }; | |
| 236 | + return s; | |
| 237 | +} | |
| 238 | + | |
| 239 | +static struct s24 ret_s24(void) | |
| 240 | +{ | |
| 241 | + struct s24 s = { "123456789012345678901234" }; | |
| 242 | + return s; | |
| 243 | +} | |
| 244 | + | |
| 245 | +static struct s32 ret_s32(void) | |
| 246 | +{ | |
| 247 | + struct s32 s = { "12345678901234567890123456789012" }; | |
| 248 | + return s; | |
| 249 | +} | |
| 250 | + | |
| 251 | +static 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 | + | |
| 266 | +int 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 | +} | |
| @@ -0,0 +1,50 @@ | ||
| 1 | +shift-imm: | |
| 2 | +1 | |
| 3 | +8000 | |
| 4 | +80000000 | |
| 5 | +1 | |
| 6 | +8000 | |
| 7 | +ffffffff | |
| 8 | +fffffff0 | |
| 9 | +1 | |
| 10 | +100000000 | |
| 11 | +8000000000000000 | |
| 12 | +1 | |
| 13 | +ffffffffffffffff | |
| 14 | +fffffffffffffff0 | |
| 15 | +ldr-str: | |
| 16 | +1122334455667788 | |
| 17 | +99aabbccddeeff00 | |
| 18 | +55667788 | |
| 19 | +f1e2d3c4b5a6978 | |
| 20 | +1122334455667788 99aabbccddeeff00 | |
| 21 | +ldp-stp: | |
| 22 | +aaaabbbbccccdddd 1111222233334444 | |
| 23 | +cbz-cbnz: | |
| 24 | +zero | |
| 25 | +nonzero | |
| 26 | +zero | |
| 27 | +nonzero | |
| 28 | +csel: | |
| 29 | +10 | |
| 30 | +10 | |
| 31 | +0 | |
| 32 | +1 | |
| 33 | +sysregs: | |
| 34 | +0 | |
| 35 | +0 | |
| 36 | +ok | |
| 37 | +nop: | |
| 38 | +ok | |
| 39 | +barriers: | |
| 40 | +ok | |
| 41 | +mov-reg: | |
| 42 | +42 | |
| 43 | +-1 | |
| 44 | +large-struct: | |
| 45 | +10 | |
| 46 | +10 20 30 40 | |
| 47 | +boundary-structs: | |
| 48 | +123456789012345678 | |
| 49 | +123456789012345678901234 | |
| 50 | +12345678901234567890123456789012 | |
| @@ -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 | |
| 8 | +int main(void) | |
| 9 | +{ | |
| 10 | + __asm__("fubar x0, x1, x2"); | |
| 11 | + return 0; | |
| 12 | +} | |
| 13 | + | |
| 14 | +#elif defined test_shift_imm_range_32 | |
| 15 | +int 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 | |
| 23 | +int 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 | |
| 31 | +int 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 | |
| 39 | +int main(void) | |
| 40 | +{ | |
| 41 | + /* Invalid barrier scope name */ | |
| 42 | + __asm__("dmb xyz"); | |
| 43 | + return 0; | |
| 44 | +} | |
| 45 | + | |
| 46 | +#elif defined test_missing_third_operand | |
| 47 | +int main(void) | |
| 48 | +{ | |
| 49 | + __asm__("add x0, x1"); | |
| 50 | + return 0; | |
| 51 | +} | |
| 52 | + | |
| 53 | +#elif defined test_movz_imm_range | |
| 54 | +int main(void) | |
| 55 | +{ | |
| 56 | + __asm__("movz x0, #0x10000"); | |
| 57 | + return 0; | |
| 58 | +} | |
| 59 | + | |
| 60 | +#elif defined test_movz_shift_range | |
| 61 | +int main(void) | |
| 62 | +{ | |
| 63 | + __asm__("movz x0, #1, lsl #8"); | |
| 64 | + return 0; | |
| 65 | +} | |
| 66 | + | |
| 67 | +#elif defined test_invalid_muls | |
| 68 | +int main(void) | |
| 69 | +{ | |
| 70 | + __asm__("muls x0, x1, x2"); | |
| 71 | + return 0; | |
| 72 | +} | |
| 73 | + | |
| 74 | +#elif defined test_extended_inline_asm | |
| 75 | +int 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 | |
| 84 | +int main(void) | |
| 85 | +{ | |
| 86 | + /* Invalid clobber register name */ | |
| 87 | + __asm__ volatile ("nop" : : : "bogus"); | |
| 88 | + return 0; | |
| 89 | +} | |
| 90 | + | |
| 91 | +#endif | |
| @@ -0,0 +1,32 @@ | ||
| 1 | +[test_unknown_instruction] | |
| 2 | +139_arm64_errors.c:10: error: ARM64 instruction 'fubar' not implemented | |
| 3 | + | |
| 4 | +[test_shift_imm_range_32] | |
| 5 | +139_arm64_errors.c:17: error: shift immediate out of range | |
| 6 | + | |
| 7 | +[test_shift_imm_range_64] | |
| 8 | +139_arm64_errors.c:25: error: shift immediate out of range | |
| 9 | + | |
| 10 | +[test_invalid_sysreg] | |
| 11 | +139_arm64_errors.c:34: error: unsupported system register | |
| 12 | + | |
| 13 | +[test_invalid_barrier_option] | |
| 14 | +139_arm64_errors.c:42: error: invalid operand 'xyz' | |
| 15 | + | |
| 16 | +[test_missing_third_operand] | |
| 17 | +139_arm64_errors.c:48: error: missing third operand | |
| 18 | + | |
| 19 | +[test_movz_imm_range] | |
| 20 | +139_arm64_errors.c:55: error: move wide immediate out of range | |
| 21 | + | |
| 22 | +[test_movz_shift_range] | |
| 23 | +139_arm64_errors.c:62: error: move wide shift out of range | |
| 24 | + | |
| 25 | +[test_invalid_muls] | |
| 26 | +139_arm64_errors.c:70: error: ARM64 instruction 'muls' not implemented | |
| 27 | + | |
| 28 | +[test_extended_inline_asm] | |
| 29 | +139_arm64_errors.c:79: error: invalid reference in constraint 1 ('2') | |
| 30 | + | |
| 31 | +[test_extended_inline_clobber] | |
| 32 | +139_arm64_errors.c:87: error: invalid clobber register 'bogus' | |
| @@ -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 | + | |
| 10 | +struct pair64 { | |
| 11 | + uint64_t a; | |
| 12 | + uint64_t b; | |
| 13 | +}; | |
| 14 | + | |
| 15 | +static int arm64_symbol_target(void) | |
| 16 | +{ | |
| 17 | + return 7; | |
| 18 | +} | |
| 19 | + | |
| 20 | +static void test_symbolic_address_constraint_compile_only(void) | |
| 21 | +{ | |
| 22 | + asm volatile("" : : "S"(arm64_symbol_target)); | |
| 23 | +} | |
| 24 | + | |
| 25 | +/* Test 1: Basic output operand */ | |
| 26 | +void 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 */ | |
| 35 | +void 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 */ | |
| 45 | +void 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 */ | |
| 54 | +void 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 */ | |
| 64 | +void 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 */ | |
| 74 | +void 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 */ | |
| 85 | +static long arm64_symbol_mem; | |
| 86 | + | |
| 87 | +void 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 */ | |
| 98 | +void 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 */ | |
| 112 | +void 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 */ | |
| 122 | +void 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 */ | |
| 132 | +void 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 */ | |
| 142 | +void 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) */ | |
| 152 | +void 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 */ | |
| 162 | +void 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 */ | |
| 172 | +void 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 */ | |
| 183 | +void 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 */ | |
| 198 | +void 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) */ | |
| 210 | +void 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 */ | |
| 222 | +void 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 */ | |
| 231 | +void 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 */ | |
| 241 | +void 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 */ | |
| 250 | +void 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 */ | |
| 273 | +void 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 */ | |
| 289 | +void 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 */ | |
| 299 | +void 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 */ | |
| 310 | +void 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 */ | |
| 321 | +void 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 */ | |
| 331 | +void 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 */ | |
| 341 | +void 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 */ | |
| 351 | +void 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 */ | |
| 361 | +void 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 */ | |
| 372 | +void 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 */ | |
| 383 | +static 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 | + | |
| 391 | +void 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 */ | |
| 399 | +void 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 | + | |
| 411 | +int 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 | +} | |
| @@ -0,0 +1,36 @@ | ||
| 1 | +ARM64 Extended Inline Assembly Tests | |
| 2 | +Test 1 (basic output): PASSED | |
| 3 | +Test 2 (input operand): PASSED | |
| 4 | +Test 3 (read-write operand): PASSED | |
| 5 | +Test 4 (memory load): PASSED | |
| 6 | +Test 5 (memory store): PASSED | |
| 7 | +Test 5a (stack memory operand): PASSED | |
| 8 | +Test 5b (symbol memory operand): PASSED | |
| 9 | +Test 6 (clobber list): PASSED | |
| 10 | +Test 7 (multiple outputs): PASSED | |
| 11 | +Test 8 (constraint reference): PASSED | |
| 12 | +Test 9 (early clobber): PASSED | |
| 13 | +Test 10 (w register modifier): PASSED | |
| 14 | +Test 11 (immediate I constraint): PASSED | |
| 15 | +Test 12 (general operand constraint): PASSED | |
| 16 | +Test 13 (multiple IO): PASSED | |
| 17 | +Test 14 (regvar preservation): PASSED | |
| 18 | +Test 15 (complex arithmetic): PASSED | |
| 19 | +Test 16 (named operand): PASSED | |
| 20 | +Test 17 (memory clobber): PASSED | |
| 21 | +Test 18 (cc clobber): PASSED | |
| 22 | +Test 19 (large immediate): PASSED | |
| 23 | +Test 20 (bitwise ops): PASSED | |
| 24 | +Test 21 (register shifts): PASSED | |
| 25 | +Test 22 (ror immediate): PASSED | |
| 26 | +Test 23 (fp register operand): PASSED | |
| 27 | +Test 24 (Z constraint): PASSED | |
| 28 | +Test 25 (K constraint): PASSED | |
| 29 | +Test 26 (L constraint): PASSED | |
| 30 | +Test 27 (M constraint): PASSED | |
| 31 | +Test 28 (N constraint): PASSED | |
| 32 | +Test 29 (x constraint): PASSED | |
| 33 | +Test 30 (y constraint): PASSED | |
| 34 | +Test 31 (Q constraint): PASSED | |
| 35 | +Test 32 (Ump constraint): PASSED | |
| 36 | +ARM64 Extended Inline Assembly Tests PASSED! | |
| @@ -38,6 +38,11 @@ struct hfa32 { long double a, b; } hfa32 = { 32.1, 32.2 }; · 37 unmodified lines | ||
| 38 | 38 | struct hfa33 { long double a, b, c; } hfa33 = { 33.1, 33.2, 33.3 }; |
| 39 | 39 | struct hfa34 { long double a, b, c, d; } hfa34 = { 34.1, 34.2, 34.3, 34.4 }; |
| 40 | 40 | |
| 41 | +struct empty { }; | |
| 42 | +/* Keep the top-level offsets at zero without changing the type into a union. */ | |
| 43 | +struct hfae12 { struct empty e; struct hfa12 h; } hfae12 = { { }, { 112.1, 112.2 } }; | |
| 44 | +struct hfae22 { struct empty e; struct hfa22 h; } hfae22 = { { }, { 122.1, 122.2 } }; | |
| 45 | + | |
| 41 | 46 | void fa_s1(struct s1 a) { printf("%.1s\n", a.x); } |
| 42 | 47 | void fa_s2(struct s2 a) { printf("%.2s\n", a.x); } |
| 43 | 48 | void fa_s3(struct s3 a) { printf("%.3s\n", a.x); } |
| @@ -82,6 +87,10 @@ void fa_hfa33(struct hfa33 a) · 38 unmodified lines | ||
| 82 | 87 | { printf("%.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c); } |
| 83 | 88 | void fa_hfa34(struct hfa34 a) |
| 84 | 89 | { printf("%.1Lf %.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c, a.d); } |
| 90 | +void fa_hfae12(struct hfae12 a) | |
| 91 | +{ printf("%.1f %.1f\n", a.h.a, a.h.b); } | |
| 92 | +void fa_hfae22(struct hfae22 a) | |
| 93 | +{ printf("%.1f %.1f\n", a.h.a, a.h.b); } | |
| 85 | 94 | |
| 86 | 95 | void fa1(struct s8 a, struct s9 b, struct s10 c, struct s11 d, |
| 87 | 96 | struct s12 e, struct s13 f) |
| @@ -140,6 +149,8 @@ void arg(void) · 52 unmodified lines | ||
| 140 | 149 | fa_hfa32(hfa32); |
| 141 | 150 | fa_hfa33(hfa33); |
| 142 | 151 | fa_hfa34(hfa34); |
| 152 | + fa_hfae12(hfae12); | |
| 153 | + fa_hfae22(hfae22); | |
| 143 | 154 | fa1(s8, s9, s10, s11, s12, s13); |
| 144 | 155 | fa2(s9, s10, s11, s12, s13, s14); |
| 145 | 156 | fa3(hfa14, hfa23, hfa32); |
| @@ -178,6 +189,8 @@ struct hfa31 fr_hfa31(void) { return hfa31; } · 32 unmodified lines | ||
| 178 | 189 | struct hfa32 fr_hfa32(void) { return hfa32; } |
| 179 | 190 | struct hfa33 fr_hfa33(void) { return hfa33; } |
| 180 | 191 | struct hfa34 fr_hfa34(void) { return hfa34; } |
| 192 | +struct hfae12 fr_hfae12(void) { return hfae12; } | |
| 193 | +struct hfae22 fr_hfae22(void) { return hfae22; } | |
| 181 | 194 | |
| 182 | 195 | void ret(void) |
| 183 | 196 | { |
| @@ -228,6 +241,8 @@ void ret(void) · 44 unmodified lines | ||
| 228 | 241 | printf("%.1Lf %.1Lf\n", fr_hfa32().a, fr_hfa32().b); |
| 229 | 242 | printf("%.1Lf %.1Lf\n", fr_hfa33().a, fr_hfa33().c); |
| 230 | 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 | |
| 233 | 248 | void* |
| @@ -28,6 +28,8 @@ cdefghijklmnopqrs · 27 unmodified lines | ||
| 28 | 28 | 32.1 32.1 |
| 29 | 29 | 33.1 33.2 33.3 |
| 30 | 30 | 34.1 34.2 34.3 34.4 |
| 31 | +112.1 112.2 | |
| 32 | +122.1 122.2 | |
| 31 | 33 | stu ABC JKL TUV 456 ghi |
| 32 | 34 | ABC JKL TUV 456 ghi tuv |
| 33 | 35 | 14.1 14.4 23.1 23.3 32.1 32.2 |
| @@ -62,6 +64,8 @@ cdefghijklmnopqrs · 28 unmodified lines | ||
| 62 | 64 | 32.1 32.2 |
| 63 | 65 | 33.1 33.3 |
| 64 | 66 | 34.1 34.4 |
| 67 | +112.1 112.2 | |
| 68 | +122.1 122.2 | |
| 65 | 69 | stdarg: |
| 66 | 70 | ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI |
| 67 | 71 | lmnopqr ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI |