TheThirdOne / rars

RARS -- RISC-V Assembler and Runtime Simulator
Other
1.2k stars 230 forks source link

System calls printing 64-bit registers #111

Open zhijieshi opened 3 years ago

zhijieshi commented 3 years ago

It seems system calls have not updated to print 64-bit registers.

The changes could be minimal. Adding an if statement in all system calls?

In SyscallPrintInt.java:

The following line prints 32-bit registers:

    SystemIO.printString(Integer.toString(RegisterFile.getValue("a0")));

Add/change to the following can handle both int and long:

    SystemIO.printString(Long.toString(RegisterFile.getValue("a0")));

In SyscallPrintIntUnsigned.java:

The line that handles int is:

    Binary.unsignedIntToIntString(RegisterFile.getValue("a0")));

We could use the Java built-in support to print unsigned value?

    Integer.toUnsignedString(RegisterFile.getValue("a0")));  // for 32 bits
    Long.toUnsignedString(RegisterFile.getValue("a0"))); // for 64 bits

BTW, in util/Binary.java, why not just use the long literal to set UNSIGNED_BASE.

    private static final long UNSIGNED_BASE = 0x100000000L;

With Integer.toUnsignedString() and Integer.toUnsginedLong(), UNSIGNED_BASE might not be necessary.

In SyscallPrintIntBinary.Java

Current line for int:

    SystemIO.printString(Binary.intToBinaryString(RegisterFile.getValue("a0")));

Add/change:

    SystemIO.printString(Binary.longToBinaryString(RegisterFile.getValue("a0")));

In SyscallPrintIntHex.Java

Current line for int:

    SystemIO.printString(Binary.intToHexString(RegisterFile.getValue("a0")));

Add/change:

    SystemIO.printString(Binary.longToHexString(RegisterFile.getValue("a0")));
TheThirdOne commented 3 years ago

It certainly would be pretty easy to make print int work with 64 bit values.

My understanding was that most uses of RV64 are not because 64 bit values are important, but instead because minor differences between rv32 and rv64 can trip students up. If you have a use case where supporting 64 bit values in the print system calls is important please share it.

Currently, I believe that all system calls truncate arguments to 32 bits when in RV64 mode. I would be hesitant to make any change to only a few system calls for the sake of consistency. I would be more willing to make a new printInt64 system call.

zhijieshi commented 3 years ago

Thanks.

Students will get confused when they print an 64-bit integer, but only the lower 32-bit are actually printed. Some students are already struggling with two's complement numbers. This will make it even harder for them to figure out what go wrong with their code.

Adding new system calls for 64-bit integers sounds a good solution.

BTW, we stick with 64-bit mode in the course, to avoid unnecessary confusions.

zhijieshi commented 3 years ago

Since the 2nd edition of "Computer organization and design RISC-V edition" has switched back to 32-bit processors, we are going to use RARS in 32-bit mode. Thanks.

ProfPierce commented 6 months ago

I had my students work on an exercise that used the Time system call (code 30) where the return value was split into the a0 and a1 registers. They had to combine the two values into one register and output the value with another system call. They were getting the wrong value on output due to only the lower 32 bits of the 64-bit register being read for PrintInt. We ended up converting the 64-bit long to double FP and printed using PrintDouble. Bottom line: having a straightforward method for handling 64-bit integer output would be most helpful.