Search code examples
compilationmicrocontrollerieee-754microprocessorsriscv

Which exceptions will be raised for the FCVT.WU.D floating point instruction


What would happen if the instruction fcvt.wu.d receives a negative double-precision floating point value as its input? What would the output of the operation be and/or which exception would it raise (is it invalid)?


Solution

  • First thing to note: no floating point instruction throws an exception in RISC-V. Floating point exceptions are "accrued" into a Floating Point Control & Status Register (fcsr). It is the job of the software to check the fcsr and jump to the appropriate exception handling routine.

    From the manual, paraphrased:

    The instruction fcvt.wu.d takes a 64b floating point double (located in the floating point register file at register rs1) and converts it to an unsigned 32b integer word (placed in the integer register file at rd).

    Numbers will be rounded as specified by the rm field of the instruction.

    I wrote some code and ran it through the ISA simulator "spike" to check the behavior myself. I'm loading "-64" into a dp register and then trying to load it back into the integer register file.

     register long test, fcsr;
     asm volatile(" li %0, 64\n\tsub %0, x0, %0\n\tfcvt.d.w f1, %0\n\tfcvt.wu.d %0,f1" : "=r"(test));
     asm volatile(" frcsr %0" : "=r"(fcsr));
     printf("result: %d %lu %lx %x\n", test, test, fcsr);
    

    This returns:

    result: -1 18446744073709551615 ffffffffffffffff 10.

    The NV exception bit is set! If we change the last instruction to a fcvt.w.d we get the expected result:

    tmp: -64 18446744073709551552 ffffffffffffffc0 0

    Summary: the NV exception bit will be set in the fscr, but that must be manually checked by software to be properly handled.