#include <stdio.h>

int x86;
int arm;
int aarch64;
int arm_aarch64;
int riscv;

void sp8() {
  printf("        ");
  return;
}

void newline() {
  putchar('\n');
  return;
}

void print_int(int n) {
  printf("%d", n);
  return;
}

void comment() {
  if (x86)
    printf("# ");
  else
  if (arm)
    printf("@ ");
  else
  if (aarch64)
    printf("// ");
  else // riscv
    printf("# ");
  return;
}

void ltorg() {
  if (arm_aarch64)
    printf(".ltorg\n");
  return;
}

void print_reg_letter(int reg) {
  if (x86) {
    if (reg == 0)
      putchar('a');
    else
    if (reg == 1)
      putchar('b');
    else // reg == 2
      putchar('c');
    putchar('x');
  }
  else
  if (arm_aarch64) {
    if (arm)
      putchar('r');
    else
    if (aarch64)
      putchar('w');
    print_int(reg);
  }
  else { // riscv
    putchar('s');
    print_int(reg);
  }
  return;
}

void print_reg(int reg) {
  if (x86)
    printf("%%e");
  print_reg_letter(reg);
  return;
}

void print_reg_r(int reg) {
  printf("%%r");
  print_reg_letter(reg);
  return;
}

void print_reg_x(int reg) {
  putchar('x');
  print_int(reg);
  return;
}

void _call() {
  if (arm_aarch64)
    printf("bl     ");
  else
    printf("call   ");
  return;
}

void br() {
  sp8();
  if (x86)
    printf("jmp    ");
  else
  if (riscv)
    printf("j      ");
  else
    printf("b      ");
  return;
}

int a0() {
  return 0;
}

int a2() {
  if (x86)
    return 0;
  else
    return 2;
}

int b0() {
  if (x86)
    return 1;
  else
    return 0;
}

int b1() {
  return 1;
}

int b2() {
  if (x86)
    return 1;
  else
    return 2;
}

int b4() {
  if (x86)
    return 1;
  else
    return 4;
}

int c2() {
  return 2;
}

int c4() {
  if (x86)
    return 2;
  else
    return 4;
}

void li_riscv(int n, int reg) {
  sp8(); printf("li     ");
  print_reg(reg);
  printf(", ");
  print_int(n);
  newline();
  return;
}

void inc_rdi() {
  sp8(); printf("add    $4, %%rdi\n");
  return;
}

void two_regs(int reg1, int reg2) {
  print_reg(reg2);
  printf(", ");
  print_reg(reg1);
  if (x86)
    newline();
  return;
}

void three_regs(int reg1, int reg2) {
  two_regs(reg1, reg2);
  printf(", ");
  print_reg(reg2);
  newline();
  return;
}

void three_regs2(int reg1, int reg2) {
  two_regs(reg1, reg1);
  printf(", ");
  print_reg(reg2);
  newline();
  return;
}

void add_reg(int reg1, int reg2) {
  sp8(); printf("add    ");
  if (x86)
    two_regs(reg2, reg1);
  else
    three_regs(reg1, reg2);
  return;
}

void sub_reg(int reg1, int reg2) {
  sp8(); printf("sub    ");
  if (x86)
    two_regs(reg2, reg1);
  else
    three_regs(reg1, reg2);
  return;
}

void sub_reg3(int reg1, int reg2) {
  // only riscv
  sp8(); printf("sub    ");
  three_regs2(reg1, reg2);
  return;
}

void print_arm_aarch64_n(int n) {
  printf(", ");
  if (arm)
    putchar('$');
  print_int(n);
  return;
}

void get_local(int offset, int reg) {
  sp8();
  if (x86) {
    printf("mov    ");
    if (offset != 0)
      print_int(offset);
    printf("(%%rbp), ");
    print_reg(reg);
    newline();
  }
  else
  if (arm_aarch64) {
    printf("ldr    "); print_reg(reg);
    if (arm)
      printf(", [r10");
    else
      printf(", [x10");
    if (offset != 0)
      print_arm_aarch64_n(offset);
    printf("]\n");
  }
  else { // riscv
    printf("lw     "); print_reg(reg);
    if (offset != 0)
      print_arm_aarch64_n(offset);
    else
      printf(", ");
    printf("(s10)\n");
  }
  return;
}

void set_local(int offset, int reg) {
  sp8();
  if (x86) {
    printf("mov    ");
    print_reg(reg);
    printf(", ");
    if (offset != 0)
      print_int(offset);
    printf("(%%rbp)\n");
  }
  else
  if (arm_aarch64) {
    printf("str    "); print_reg(reg);
    if (arm)
      printf(", [r10");
    else
      printf(", [x10");
    if (offset != 0)
      print_arm_aarch64_n(offset);
    printf("]\n");
  }
  else { // riscv
    printf("sw     "); print_reg(reg);
    if (offset != 0)
      print_arm_aarch64_n(offset);
    else
      printf(", ");
    printf("(s10)\n");
  }
  return;
}

void function_proc_begin(int n1, int n2, int n3) {
  if (x86) {
    sp8(); printf("mov    %%rbp, %%rcx\n");
    sp8(); printf("mov    %%rdi, %%rdx\n");
    sp8(); printf("sub    $"); print_int(n1 * 4); printf(", %%rdx\n");
    sp8(); printf("mov    %%rdx, %%rbp\n");
    sp8(); printf("add    $"); print_int((n2 + 1) * 4); printf(", %%rdi\n");
    sp8(); printf("add    $"); print_int(n3 * 4); printf(", %%rdx\n");
    sp8(); printf("mov    %%rcx, (%%rdx)\n");
  }
  else
  if (arm) {
    sp8(); printf("stmfd  sp!, {fp, lr}\n");
    sp8(); printf("add    fp, sp, $4\n");
    sp8(); printf("mov    r1, r10\n");
    sp8(); printf("sub    r10, r3, $"); print_int(n1 * 4); newline();
    sp8(); printf("add    r3, r10, $"); print_int(n2 * 4); newline();
    sp8(); printf("add    r0, r10, $"); print_int(n3 * 4); newline();
    sp8(); printf("str    r1, [r0]\n");
  }
  else
  if (aarch64) {
    sp8(); printf("str    x30, [sp, -16]!\n");
    sp8(); printf("mov    x1, x10\n");
    sp8(); printf("sub    x10, x3, "); print_int(n1 * 4); newline();
    sp8(); printf("add    x3, x10, "); print_int((n2 + 1) * 4); newline();
    sp8(); printf("add    x0, x10, "); print_int(n3 * 4); newline();
    sp8(); printf("str    x1, [x0]\n");
  }
  else { // riscv
    sp8(); printf("add    sp, sp, -8\n");
    sp8(); printf("sd     ra, (sp)\n");
    sp8(); printf("mv     s1, s10\n");
    sp8(); printf("addi   s10, s3, -"); print_int(n1 * 4); newline();
    sp8(); printf("addi   s3, s10, "); print_int((n2 + 1) * 4); newline();
    sp8(); printf("addi   s0, s10, "); print_int(n3 * 4); newline();
    sp8(); printf("sd     s1, (s0)\n");
  }
  return;
}

void proc_end(int n) {
  if (x86) {
    sp8(); printf("mov    %%rbp, %%rdi\n");
    sp8(); printf("add    $"); print_int(n * 4); printf(", %%rbp\n");
    sp8(); printf("mov    (%%rbp), %%rbp\n");
  }
  else
  if (arm) {
    sp8(); printf("mov    r3, r10\n");
    sp8(); printf("ldr    r10, [r10, $"); print_int(n * 4); printf("]\n");
  }
  else
  if (aarch64) {
    sp8(); printf("mov    x3, x10\n");
    sp8(); printf("ldr    x10, [x10, "); print_int(n * 4); printf("]\n");
  }
  else { // riscv
    sp8(); printf("mv     s3, s10\n");
    sp8(); printf("ld     s10, "); print_int(n * 4); printf("(s10)\n");
  }
  return;
}

void function_end(int n) {
  if (x86) {
    sp8(); printf("mov    %%rbp, %%rdi\n"); inc_rdi();
    sp8(); printf("add    $"); print_int(n * 4); printf(", %%rbp\n");
    sp8(); printf("mov    (%%rbp), %%rbp\n");
  }
  else
  if (arm) {
    sp8(); printf("add    r3, r10, $4\n");
    sp8(); printf("ldr    r10, [r10, $"); print_int(n * 4); printf("]\n");
  }
  else
  if (aarch64) {
    sp8(); printf("add    x3, x10, 4\n");
    sp8(); printf("ldr    x10, [x10, "); print_int(n * 4); printf("]\n");
  }
  else { // riscv
    sp8(); printf("addi   s3, s10, 4\n");
    sp8(); printf("ld     s10, "); print_int(n * 4); printf("(s10)\n");
  }
  return;
}

void _return() {
  sp8();
  if (x86)
    printf("ret\n");
  else
  if (arm)
    printf("ldmfd  sp!, {fp, pc}\n");
  else
  if (aarch64) {
    printf("ldr    x30, [sp], 16\n");
    sp8(); printf("ret    \n");
  }
  else { // riscv
    printf("ld     ra, (sp)\n");
    sp8(); printf("add    sp, sp, 8\n");
    sp8(); printf("jr     ra\n");
  }
  return;
}

void set_fcsr() {
  li_riscv(32, 5); // 32 is round towards zero rounding mode
  sp8(); printf("fscsr  x0, s5\n");
  return;
}

void chk_fcsr(int n) {
  // for riscv if a flotaing exception occurs set f0 to 0.0
  sp8(); printf("frflags s5\n");
  sp8(); printf("andi    s5, s5, 30\n");
  sp8(); printf("beqz    s5, .l"); print_int(n); printf("_chk_fcsr\n");
  li_riscv(0, 5);
  sp8(); printf("fcvt.d.w f0, s5\n"); // set to 0.0
  printf(".l"); print_int(n); printf("_chk_fcsr:\n");
  set_fcsr();
  return;
}

void n_0_1(int n) {
  if (n == 0)
    putchar('0');
  else
    putchar('1');
  return;
}

int read_char() {
  return getchar() - '0';
}

int main() {
  int idx;

  x86 = read_char();
  arm = read_char();
  arm_aarch64 = read_char(); // set when arm or aarch64
  aarch64 = read_char();
  riscv = read_char();

  ltorg();
  printf("dbl_load_reg:\n");
  function_proc_begin(2, 3, 2);
  sp8();
  if (x86)
    printf("movsd  (%%rbp), %%xmm0\n");
  else
  if (arm) {
    printf("ldr    r0, [r10]\n");
    sp8(); printf("ldr    r1, [r10, $4]\n");
    sp8(); printf("vmov   d0, r0, r1\n");
  }
  else
  if (aarch64)
    printf("ldr    d0, [x10]\n");
  else // riscv
    printf("fld    f0, (s10)\n");
  proc_end(2);
  _return();

  ltorg();
  printf("dbl_load_reg1:\n");
  function_proc_begin(2, 3, 2);
  sp8();
  if (x86)
    printf("movsd  (%%rbp), %%xmm1\n");
  else
  if (arm) {
    printf("ldr    r0, [r10]\n");
    sp8(); printf("ldr    r1, [r10, $4]\n");
    sp8(); printf("vmov   d1, r0, r1\n");
  }
  else
  if (aarch64)
    printf("ldr    d1, [x10]\n");
  else // riscv
    printf("fld    f1, (s10)\n");
  proc_end(2);
  _return();

  ltorg();
  printf("dbl_load_reg2:\n");
  function_proc_begin(2, 3, 2);
  sp8();
  if (x86)
    printf("movsd  (%%rbp), %%xmm2\n");
  else
  if (arm) {
    printf("ldr    r0, [r10]\n");
    sp8(); printf("ldr    r1, [r10, $4]\n");
    sp8(); printf("vmov   d2, r0, r1\n");
  }
  else
  if (aarch64)
    printf("ldr    d2, [x10]\n");
  else // riscv
    printf("fld    f2, (s10)\n");
  proc_end(2);
  _return();

  ltorg();
  printf("dbl_get_reg_first:\n");
  function_proc_begin(0, 4, 3);
  sp8();
  if (x86)
    printf("movsd  %%xmm0, (%%rbp)\n");
  else
  if (arm) {
    printf("vmov   r0, r1, d0\n");
    sp8(); printf("str    r0, [r10]\n");
  }
  else
  if (aarch64)
    printf("str    d0, [x10]\n");
  else // riscv
    printf("fsd    f0, (s10)\n");
  function_end(3);
  _return();

  ltorg();
  printf("dbl_get_reg_second:\n");
  function_proc_begin(0, 4, 3);
  sp8();
  if (x86)
    printf("movsd  %%xmm0, (%%rbp)\n");
  else
  if (arm) {
    printf("vmov   r0, r1, d0\n");
    sp8(); printf("str    r1, [r10]\n");
  }
  else
  if (aarch64)
    printf("str    d0, [x10]\n");
  else // riscv
    printf("fsd    f0, (s10)\n");
  if (!arm) {
    get_local(4, a0());
    set_local(0, a0());
  }
  function_end(3);
  _return();

  ltorg();
  printf("dbl_etoi:\n");
  function_proc_begin(1, 2, 1);
  comment(); printf("double register 0 = (double)x\n");
  get_local(0, a0());
  sp8();
  if (x86) {
    printf("pxor   %%xmm0, %%xmm0\n");
    sp8(); printf("cvtsi2sdl %%eax, %%xmm0\n");
  }
  else
  if (arm) {
    printf("vmov   s15, r0\n");
    sp8(); printf("vcvt.f64.s32 d0, s15\n");
  }
  if (aarch64)
    printf("scvtf  d0, w0\n");
  else // riscv
  if (riscv) {
    printf("fcvt.d.w f0, s0\n");
    set_fcsr();
  }
  proc_end(1);
  _return();

  ltorg();
  printf("dbl_etoi1:\n");
  function_proc_begin(1, 2, 1);
  comment(); printf("double register 1 = (double)x\n");
  get_local(0, a0());
  sp8();
  if (x86) {
    printf("pxor   %%xmm1, %%xmm1\n");
    sp8(); printf("cvtsi2sdl %%eax, %%xmm1\n");
  }
  else
  if (arm) {
    printf("vmov   s15, r0\n");
    sp8(); printf("vcvt.f64.s32 d1, s15\n");
  }
  if (aarch64)
    printf("scvtf  d1, w0\n");
  else // riscv
  if (riscv) {
    printf("fcvt.d.w f1, s0\n");
    set_fcsr();
  }
  proc_end(1);
  _return();

  ltorg();
  printf("dbl_itoe:\n");
  function_proc_begin(0, 3, 2);
  comment(); printf("return (int)(double register 0)\n");
  sp8();
  if (x86) {
    printf("cvttsd2sil %%xmm0, %%eax\n");
    sp8(); printf("mov    %%eax, (%%rbp)\n");
  }
  else {
    if (arm) {
      printf("vcvt.s32.f64 s15, d0\n");
      sp8(); printf("vmov   r0, s15\n");
    }
    else
    if (aarch64)
      printf("fcvtzs w0, d0\n");
    else
    if (riscv) {
      printf("fcvt.w.d s0, f0\n");
      set_fcsr();
    }
    set_local(0, a0());
  }
  function_end(2);
  _return();

  ltorg();
  printf("dbl_add:\n");
  function_proc_begin(0, 1, 0);
  sp8();
  if (x86)
    printf("addsd  %%xmm1, %%xmm0\n");
  else
  if (arm)
    printf("vadd.f64 d0, d0, d1\n");
  else
  if (aarch64)
    printf("fadd   d0, d0, d1\n");
  else { // riscv
    printf("fadd.d f0, f0, f1\n");
    chk_fcsr(0);
  }
  proc_end(0);
  _return();

  printf("dbl_sub:\n");
  function_proc_begin(0, 1, 0);
  sp8();
  if (x86)
    printf("subsd  %%xmm1, %%xmm0\n");
  else
  if (arm)
    printf("vsub.f64 d0, d0, d1\n");
  else
  if (aarch64)
    printf("fsub   d0, d0, d1\n");
  else { // riscv
    printf("fsub.d f0, f0, f1\n");
    chk_fcsr(1);
  }
  proc_end(0);
  _return();

  ltorg();
  printf("dbl_mul:\n");
  function_proc_begin(0, 1, 0);
  sp8();
  if (x86)
    printf("mulsd  %%xmm1, %%xmm0\n");
  else
  if (arm)
    printf("vmul.f64 d0, d0, d1\n");
  else
  if (aarch64)
    printf("fmul   d0, d0, d1\n");
  else { // riscv
    printf("fmul.d f0, f0, f1\n");
    chk_fcsr(2);
  }
  proc_end(0);
  _return();

  ltorg();
  printf("dbl_mul1:\n");
  function_proc_begin(0, 1, 0);
  sp8();
  if (x86)
    printf("mulsd  %%xmm2, %%xmm1\n");
  else
  if (arm)
    printf("vmul.f64 d1, d1, d2\n");
  else
  if (aarch64)
    printf("fmul   d1, d1, d2\n");
  else { // riscv
    printf("fmul.d f1, f1, f2\n");
    chk_fcsr(3);
  }
  proc_end(0);
  _return();

  ltorg();
  printf("dbl_div:\n");
  function_proc_begin(0, 1, 0);
  sp8();
  if (x86)
    printf("divsd  %%xmm1, %%xmm0\n");
  else
  if (arm)
    printf("vdiv.f64 d0, d0, d1\n");
  else
  if (aarch64)
    printf("fdiv   d0, d0, d1\n");
  else { // riscv
    printf("fdiv.d f0, f0, f1\n");
    chk_fcsr(4);
  }
  proc_end(0);
  _return();

  ltorg();
  printf("dbl_neg:\n");
  function_proc_begin(0, 1, 0);
  sp8();
  if (x86) {
    printf("movaps %%xmm0, %%xmm1\n"); // reg1 = reg0
    sp8(); printf("xorpd  %%xmm0, %%xmm0\n"); // reg0 = 0.0
    sp8(); printf("subsd  %%xmm1, %%xmm0\n"); // reg0 = 0.0 - reg1
  }
  else
  if (arm)
    printf("vneg.f64 d0, d0\n");
  else
  if (aarch64)
    printf("fneg   d0, d0\n");
  else { // riscv
    printf("fneg.d f0, f0\n");
    chk_fcsr(5);
  }
  proc_end(0);
  _return();

  ltorg();
  printf("dbl_eq:\n");
  function_proc_begin(0, 3, 2);
  if (x86) {
    sp8(); printf("xorl   %%eax, %%eax\n");
    sp8(); printf("ucomisd %%xmm0, %%xmm1\n");
    sp8(); printf("movl   $0, %%ebx\n");
    sp8(); printf("setnp  %%al\n");
    sp8(); printf("cmovne %%ebx, %%eax\n");
  }
  else
  if (arm) {
    sp8(); printf("vcmp.f64 d0, d1\n");
    sp8(); printf("vmrs   APSR_nzcv, FPSCR\n");
    sp8(); printf("moveq  r0, $1\n");
    sp8(); printf("movne  r0, $0\n");
  }
  else
  if (aarch64) {
    sp8(); printf("fcmp   d0, d1\n");
    sp8(); printf("bne    .l9_dbl_eq\n");
    sp8(); printf("mov    w0, 1\n");
    sp8(); printf("b      .l10_dbl_eq\n");
    ltorg();
    printf(".l9_dbl_eq:\n");
    sp8(); printf("mov    w0, 0\n");
    printf(".l10_dbl_eq:\n");
  }
  else { // riscv
    sp8(); printf("feq.d  s0, f0, f1\n");
  }
  set_local(0, a0());
  function_end(2);
  _return();

  ltorg();
  printf("dbl_lt:\n");
  function_proc_begin(0, 3, 2);
  if (x86) {
    sp8(); printf("xorl   %%eax, %%eax\n");
    sp8(); printf("comisd %%xmm0, %%xmm1\n");
    sp8(); printf("seta   %%al\n");
  }
  else
  if (arm) {
    sp8(); printf("vcmpe.f64 d0, d1\n");
    sp8(); printf("vmrs   APSR_nzcv, FPSCR\n");
    sp8(); printf("movmi  r0, $1\n");
    sp8(); printf("movpl  r0, $0\n");
  }
  else
  if (aarch64) {
    sp8(); printf("fcmpe  d0, d1\n");
    sp8(); printf("bmi    .dbl_lt_l0\n");
    sp8(); printf("b      .l11_dbl_lt\n");
    printf(".dbl_lt_l0:\n");
    sp8(); printf("mov    w0, 1\n");
    sp8(); printf("b      .l12_dbl_lt\n");
    ltorg();
    printf(".l11_dbl_lt:\n");
    sp8(); printf("mov    w0, 0\n");
    printf(".l12_dbl_lt:\n");
  }
  else { // riscv
    sp8(); printf("flt.d  s0, f0, f1\n");
  }
  set_local(0, a0());
  function_end(2);
  _return();

  ltorg();
  printf("dbl_le:\n");
  function_proc_begin(0, 3, 2);
  if (x86) {
    sp8(); printf("xorl   %%eax, %%eax\n");
    sp8(); printf("comisd %%xmm0, %%xmm1\n");
    sp8(); printf("setnb  %%al\n");
  }
  else
  if (arm) {
    sp8(); printf("vcmpe.f64 d0, d1\n");
    sp8(); printf("vmrs   APSR_nzcv, FPSCR\n");
    sp8(); printf("movls  r0, $1\n");
    sp8(); printf("movhi  r0, $0\n");
  }
  else
  if (aarch64) {
    sp8(); printf("fcmpe  d0, d1\n");
    sp8(); printf("bls    .dbl_le_l0\n");
    sp8(); printf("b      .l13_dbl_le\n");
    printf(".dbl_le_l0:\n");
    sp8(); printf("mov    w0, 1\n");
    sp8(); printf("b      .l14_dbl_le\n");
    ltorg();
    printf(".l13_dbl_le:\n");
    sp8(); printf("mov    w0, 0\n");
    printf(".l14_dbl_le:\n");
  }
  else { // riscv
    sp8(); printf("fle.d  s0, f0, f1\n");
  }
  set_local(0, a0());
  function_end(2);
  _return();

  ltorg();
  printf("dbl_gt:\n");
  function_proc_begin(0, 3, 2);
  if (x86) {
    sp8(); printf("xorl   %%eax, %%eax\n");
    sp8(); printf("comisd %%xmm1, %%xmm0\n"); // swapped
    sp8(); printf("seta   %%al\n");
  }
  else
  if (arm) {
    sp8(); printf("vcmpe.f64 d0, d1\n");
    sp8(); printf("vmrs   APSR_nzcv, FPSCR\n");
    sp8(); printf("movgt  r0, $1\n");
    sp8(); printf("movle  r0, $0\n");
  }
  else
  if (aarch64) {
    sp8(); printf("fcmpe  d0, d1\n");
    sp8(); printf("bgt    .dbl_gt_l0\n");
    sp8(); printf("b      .l15_dbl_gt\n");
    printf(".dbl_gt_l0:\n");
    sp8(); printf("mov    w0, 1\n");
    sp8(); printf("b      .l16_dbl_gt\n");
    ltorg();
    printf(".l15_dbl_gt:\n");
    sp8(); printf("mov    w0, 0\n");
    printf(".l16_dbl_gt:\n");
  }
  else { // riscv
    sp8(); printf("fgt.d  s0, f0, f1\n");
  }
  set_local(0, a0());
  function_end(2);
  _return();

  ltorg();
  printf("dbl_ge:\n");
  function_proc_begin(0, 3, 2);
  if (x86) {
    sp8(); printf("xorl   %%eax, %%eax\n");
    sp8(); printf("comisd %%xmm1, %%xmm0\n"); // swapped
    sp8(); printf("setnb  %%al\n");
  }
  else
  if (arm) {
    sp8(); printf("vcmpe.f64 d0, d1\n");
    sp8(); printf("vmrs   APSR_nzcv, FPSCR\n");
    sp8(); printf("movge  r0, $1\n");
    sp8(); printf("movlt  r0, $0\n");
  }
  else
  if (aarch64) {
    sp8(); printf("fcmpe  d0, d1\n");
    sp8(); printf("bge    .dbl_ge_l0\n");
    sp8(); printf("b      .l17_dbl_ge\n");
    printf(".dbl_ge_l0:\n");
    sp8(); printf("mov    w0, 1\n");
    sp8(); printf("b      .l18_dbl_ge\n");
    ltorg();
    printf(".l17_dbl_ge:\n");
    sp8(); printf("mov    w0, 0\n");
    printf(".l18_dbl_ge:\n");
  }
  else { // riscv
    sp8(); printf("fge.d  s0, f0, f1\n");
  }
  set_local(0, a0());
  function_end(2);
  _return();

  return 0;
}