boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

riscv64-gen-cvt-sxtw.after (945B)


      1 ST_FUNC void gen_cvt_sxtw(void)
      2 {
      3     /* int -> long widening on riscv64.  RV64 32-bit ops sign-extend their
      4        results into bits 63:32, so for *signed* int -> long the register is
      5        already correctly extended (a no-op suffices, or a defensive
      6        addiw r,r,0).  For *unsigned* int -> ulong we must explicitly zero
      7        the upper 32 bits via slli;srli — otherwise an unsigned value with
      8        bit 31 set (e.g. 0x80000000) is read back as 0xffffffff80000000.
      9        Without this, kernel.c's `((u64)be32(p) << 32) | (u64)be32(p+4)`
     10        produces sign-extended garbage for any DTB cell whose top bit is
     11        set, which the seed kernel hits on the riscv64 virt machine. */
     12     int r = ireg(gv(RC_INT));
     13     if (vtop->type.t & VT_UNSIGNED) {
     14         EI(0x13, 1, r, r, 32); // slli r, r, 32
     15         EI(0x13, 5, r, r, 32); // srli r, r, 32
     16     } else {
     17         EI(0x1b, 0, r, r, 0);  // addiw r, r, 0  (sign-extend low 32)
     18     }
     19 }