Floating Point Numbers

We will use RARS for this lab. Working with floating numbers is quite different than working with integers. In RISC-V, the F extension adds support for 32 bit floating point numbers (single precision). There is also an extension (D) that supports 64 bit floating point numbers (double precision). The simulator (RARS) implements commands from both extensions. Thus, for the lab, we have 64 bit registers available and can refer to them as 32 or 64 bit values. The registers are named f0, f1, ... f31, but also have aliases such as argument registers fa0, fa1, saved registers fs0, fs1, and temporary registers ft0, ft1. Below, you will see how we load, store, and manipulate floating point numbers.



Part 1

The following line shows how we would assign a label to a floating point value. Notice that the value contains a decimal point.

    FP_value: .float  1.23
We have seen how to print integer values, such as this code:

    # Load the value at my_value, then print it
    la    x10, my_value
    lw    a0, 0(x10)
    li    a7, 1
    ecall
You might expect that printing floating point values is a matter of simply loading "FP_value" into a0 and using ecall 1, as we did with an integer, but that does not give a correct result. We need to use the flw command, and load the value into fa0. Notice that the ecall number is 2 now.

    # Load the value at FP_value, then print it
    la      x10, FP_value
    flw     fa0, 0(x10)     # Load 32-bit F.P. number into fa0
    li       a7, 2          # print a float
    ecall
Implement the code from above, try it out, and verify that it works.

Questions




Part 2

Put two float values (2.15 and 3.35) in registers, add them, and display the result. Recall the flw command from the previous example. Then, use the fadd.s command to add two floating numbers. Finally, to print the result you need to follow the ecall of previous example.

    fadd.s f2, f0, f1  # f2 = f0 + f1, single precision
    # ...
    fmv.s  fa0, f2    # copy the value to print

Before printing the value, write it to memory with the fsw command. Implement this, and show that it works.

Questions




Part 3

Load 2 FP values (1.7 and 32.4), add them together, and print the result.

    .data       # Data section, initialized variables
    FP_values: .float  1.7, 32.4
    FP_result: .word  0
Implement this code, and run it. Verify that it works.

Questions




Part 4

Next, add "val1" to "val2", store the result in "result", and display the result.

    val1:   .float 3.64
    val2:   .word  5
    result: .word  0
To accomplish this, you will need to convert a floating point value to an integer. Use a size with the larger range (float) for the calculations, then convert the result to an int. This means that you will need to convert the val2 integer to a floating point value.

    fcvt.s.w  fa0, a1        # convert a1's int value to FP 
    # ...
    fcvt.w.s   a0, fa0       # convert fa0's FP value to int

Questions


In this lab, we have learned: