asm_03_register_operand.c (1422B)
1 /* GNU local register variables (`register T x __asm__("reg")`) used as inline- 2 * asm operands must appear in the named hard register at the asm boundary. 3 * Each template below addresses its registers directly (not via %N operand 4 * substitution), so the result is correct only when a/b/r are staged into 5 * those registers for this instruction — a regression guard for the -O0 6 * binder and the optimizer's instruction-local requirement/staging path. 7 * 40 + 2 == 42. 8 * 9 * Arch-guarded; the asm is target-specific. The wasm backend has no native 10 * hard-register file, so this case opts out of W via sidecar. */ 11 12 int test_main(void) { 13 long out = 0; 14 #if defined(__aarch64__) 15 register long a __asm__("x12") = 40; 16 register long b __asm__("x13") = 2; 17 register long r __asm__("x14"); 18 __asm__ volatile("add x14, x12, x13" : "=r"(r) : "r"(a), "r"(b)); 19 out = r; 20 #elif defined(__x86_64__) 21 register long a __asm__("rdi") = 40; 22 register long b __asm__("rsi") = 2; 23 register long r __asm__("rdx"); 24 __asm__ volatile("movq %%rdi, %%rdx\n\taddq %%rsi, %%rdx" 25 : "=r"(r) 26 : "r"(a), "r"(b)); 27 out = r; 28 #elif defined(__riscv) && __riscv_xlen == 64 29 register long a __asm__("a3") = 40; 30 register long b __asm__("a4") = 2; 31 register long r __asm__("a5"); 32 __asm__ volatile("add a5, a3, a4" : "=r"(r) : "r"(a), "r"(b)); 33 out = r; 34 #else 35 out = 42; 36 #endif 37 return (int)out; 38 }