kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

asm_04_register_callee_saved.c (1864B)


      1 /* A hard-register inline-asm operand may name a callee-saved register. The
      2  * callee must preserve the caller's register value even though it loads the asm
      3  * operand through that hard register internally. */
      4 
      5 #if defined(__aarch64__)
      6 __asm__(
      7     ".text\n"
      8     ".globl write_saved_reg\n"
      9     "write_saved_reg:\n"
     10     "mov x19, x0\n"
     11     "ret\n"
     12     ".globl read_saved_reg\n"
     13     "read_saved_reg:\n"
     14     "mov x0, x19\n"
     15     "ret\n");
     16 extern void write_saved_reg(long);
     17 extern long read_saved_reg(void);
     18 #elif defined(__x86_64__)
     19 __asm__(
     20     ".text\n"
     21     ".globl write_saved_reg\n"
     22     "write_saved_reg:\n"
     23     "movq %rdi, %r13\n"
     24     "retq\n"
     25     ".globl read_saved_reg\n"
     26     "read_saved_reg:\n"
     27     "movq %r13, %rax\n"
     28     "retq\n");
     29 extern void write_saved_reg(long);
     30 extern long read_saved_reg(void);
     31 #elif defined(__riscv) && __riscv_xlen == 64
     32 __asm__(
     33     ".text\n"
     34     ".globl write_saved_reg\n"
     35     "write_saved_reg:\n"
     36     "mv s1, a0\n"
     37     "ret\n"
     38     ".globl read_saved_reg\n"
     39     "read_saved_reg:\n"
     40     "mv a0, s1\n"
     41     "ret\n");
     42 extern void write_saved_reg(long);
     43 extern long read_saved_reg(void);
     44 #else
     45 static long saved_fallback;
     46 static void write_saved_reg(long v) { saved_fallback = v; }
     47 static long read_saved_reg(void) { return saved_fallback; }
     48 #endif
     49 
     50 __attribute__((noinline)) static void touch_callee_saved(void) {
     51 #if defined(__aarch64__)
     52   register long v __asm__("x19") = 123;
     53   __asm__ volatile("" : "+r"(v));
     54 #elif defined(__x86_64__)
     55   register long v __asm__("r13") = 123;
     56   __asm__ volatile("" : "+r"(v));
     57 #elif defined(__riscv) && __riscv_xlen == 64
     58   register long v __asm__("s1") = 123;
     59   __asm__ volatile("" : "+r"(v));
     60 #endif
     61 }
     62 
     63 int test_main(void) {
     64   long saved = read_saved_reg();
     65   long after;
     66   write_saved_reg(77);
     67   touch_callee_saved();
     68   after = read_saved_reg();
     69   write_saved_reg(saved);
     70   return (int)after;
     71 }