Unified · Split
| @@ -338,7 +338,16 @@ int main(int argc, char **argv) · 337 unmodified lines | |||
| 338 | #else | 338 | #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 | ||
| 347 | void LIBTCC_TEST_WINAPI Sleep(unsigned int milliseconds); | ||
| 348 | #else | ||
| 341 | unsigned int sleep(unsigned int seconds); | 349 | unsigned int sleep(unsigned int seconds); |
| 350 | #endif | ||
| 342 | 351 | ||
| 343 | int fib(n) | 352 | int fib(n) |
| 344 | { | 353 | { |
| @@ -347,7 +356,11 @@ int fib(n) · 2 unmodified lines | |||
| 347 | 356 | ||
| 348 | int main(int argc, char **argv) | 357 | int 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 | } |
| @@ -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 | struct hfa33 { long double a, b, c; } hfa33 = { 33.1, 33.2, 33.3 }; | 38 | struct hfa33 { long double a, b, c; } hfa33 = { 33.1, 33.2, 33.3 }; |
| 39 | struct hfa34 { long double a, b, c, d; } hfa34 = { 34.1, 34.2, 34.3, 34.4 }; | 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 | void fa_s1(struct s1 a) { printf("%.1s\n", a.x); } | 46 | void fa_s1(struct s1 a) { printf("%.1s\n", a.x); } |
| 42 | void fa_s2(struct s2 a) { printf("%.2s\n", a.x); } | 47 | void fa_s2(struct s2 a) { printf("%.2s\n", a.x); } |
| 43 | void fa_s3(struct s3 a) { printf("%.3s\n", a.x); } | 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 | { printf("%.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c); } | 87 | { printf("%.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c); } |
| 83 | void fa_hfa34(struct hfa34 a) | 88 | void 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); } |
| 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 | void fa1(struct s8 a, struct s9 b, struct s10 c, struct s11 d, | 95 | void 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 | |||
| 178 | struct hfa32 fr_hfa32(void) { return hfa32; } | 189 | struct hfa32 fr_hfa32(void) { return hfa32; } |
| 179 | struct hfa33 fr_hfa33(void) { return hfa33; } | 190 | struct hfa33 fr_hfa33(void) { return hfa33; } |
| 180 | struct hfa34 fr_hfa34(void) { return hfa34; } | 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 | void ret(void) | 195 | void 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 | ||
| 233 | void* | 248 | void* |
| @@ -28,6 +28,8 @@ cdefghijklmnopqrs · 27 unmodified lines | |||
| 28 | 32.1 32.1 | 28 | 32.1 32.1 |
| 29 | 33.1 33.2 33.3 | 29 | 33.1 33.2 33.3 |
| 30 | 34.1 34.2 34.3 34.4 | 30 | 34.1 34.2 34.3 34.4 |
| 31 | 112.1 112.2 | ||
| 32 | 122.1 122.2 | ||
| 31 | stu ABC JKL TUV 456 ghi | 33 | stu ABC JKL TUV 456 ghi |
| 32 | ABC JKL TUV 456 ghi tuv | 34 | ABC JKL TUV 456 ghi tuv |
| 33 | 14.1 14.4 23.1 23.3 32.1 32.2 | 35 | 14.1 14.4 23.1 23.3 32.1 32.2 |
| @@ -62,6 +64,8 @@ cdefghijklmnopqrs · 28 unmodified lines | |||
| 62 | 32.1 32.2 | 64 | 32.1 32.2 |
| 63 | 33.1 33.3 | 65 | 33.1 33.3 |
| 64 | 34.1 34.4 | 66 | 34.1 34.4 |
| 67 | 112.1 112.2 | ||
| 68 | 122.1 122.2 | ||
| 65 | stdarg: | 69 | stdarg: |
| 66 | ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI | 70 | ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI |
| 67 | lmnopqr ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI | 71 | lmnopqr ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI |