]> git.proxmox.com Git - mirror_qemu.git/commit
target/riscv: Zero extend the inputs of divuw and remuw
authorPalmer Dabbelt <palmer@sifive.com>
Thu, 21 Mar 2019 14:59:20 +0000 (07:59 -0700)
committerPalmer Dabbelt <palmer@sifive.com>
Fri, 22 Mar 2019 07:26:39 +0000 (00:26 -0700)
commitf17e02cd3731bdfe2942d1d0b2a92f26da02408c
tree3a8b92ab24b1c9aee2d32c1277914916d2a2f62c
parent62a172e6a77d9072bb1a18f295ce0fcf4b90a4f2
target/riscv: Zero extend the inputs of divuw and remuw

While running the GCC test suite against 4.0.0-rc0, Kito found a
regression introduced by the decodetree conversion that caused divuw and
remuw to sign-extend their inputs.  The ISA manual says they are
supposed to be zero extended:

    DIVW and DIVUW instructions are only valid for RV64, and divide the
    lower 32 bits of rs1 by the lower 32 bits of rs2, treating them as
    signed and unsigned integers respectively, placing the 32-bit
    quotient in rd, sign-extended to 64 bits. REMW and REMUW
    instructions are only valid for RV64, and provide the corresponding
    signed and unsigned remainder operations respectively.  Both REMW
    and REMUW always sign-extend the 32-bit result to 64 bits, including
    on a divide by zero.

Here's Kito's reduced test case from the GCC test suite

    unsigned calc_mp(unsigned mod)
    {
         unsigned a,b,c;
         c=-1;
         a=c/mod;
         b=0-a*mod;
         if (b > mod) { a += 1; b-=mod; }
         return b;
    }

    int main(int argc, char *argv[])
    {
         unsigned x = 1234;
         unsigned y = calc_mp(x);

         if ((sizeof (y) == 4 && y != 680)
      || (sizeof (y) == 2 && y != 134))
    abort ();
         exit (0);
    }

I haven't done any other testing on this, but it does fix the test case.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
target/riscv/insn_trans/trans_rvm.inc.c
target/riscv/translate.c