3
votes

I have been testing the following code on RiscV with the RV32I and RV64I assembler.

The assembly source file is

.text
slli   x31,x31,63

When I assemble for 32 bit targets I obtain the following machine code output.

 03ff9f93                slli    x31,x31,0x3f

A warning is thrown but it appears the upper 7 bits of the instruction word are not 'reserved'. Doing a quick hand assembly I would expect 01ff9f93. I realize that it is incorrect to use the immediate operand value of 63 but the assembler will write the 63 value anyway. This does not seem like correct operation.

One way to avoid this potential problem is to set the assembler command line option of --fatal-warnings. And the build process will halt. But at a -warn level it appears the 7 upper bits of the 32 target for the 'slli' command can be overwritten and you can create a legitimate RV64I instruction.

To keep the build simple for this test, I did the following.

  1. Created source file - "test.s"
  2. Copied source file to the bin directory of the RiscV 32 bit build. Then,

    ./riscv32-unknown-elf-as -L --fatal-warnings test.s

or

 ./riscv32-unknown-elf-as -L -warn test.s
  1. Create list file

    ./riscv32-unknown-elf-objdump -h -l -M numeric,no-aliases -S -d -EL a.out

The lower lines of output will look something like this below if you set -warn level in the assembler.

Disassembly of section .text:

00000000 <.text>:
   0:   03ff9f93                slli    x31,x31,0x3f

I am wondering why the assembler takes this approach and shouldn't the upper 7 bits for 'slii' with RV32I always be stuck-at 0?

2
What is the version of your RiscV 32 bit toolchain (binutils)? Where and when did you get it and how it was built to 32-bit mode? Implementation is there - MATCH_SLLI: github.com/riscv/riscv-binutils-gdb/blob/… github.com/riscv/riscv-binutils-gdb/blob/… github.com/riscv/riscv-binutils-gdb/blob/…. There are no separate 32/64 bit encodersosgx
> ./riscv32-unknown-elf-as --version GNU assembler (GNU Binutils) 2.28.51.20170101 Copyright (C) 2016 Free Software Foundation, Inc. This program is free software; you may redistribute it under the terms of the GNU General Public License version 3 or later. This program has absolutely no warranty. This assembler was configured for a target of `riscv32-unknown-elf'.daveW
osgx - my recollection is I downloaded the complete RiscV toolchain from GitHub and built it from source using one of the provided install scripts. This was done early this year (2017).daveW
osgx - I will be not have access to this post until about 24 hours from now - I have to travel and attend a technical meeting tomorrow. So, I am not ignoring this issue but please be patient - I will be slow to respond. My original post is basically asking why is an overflow value programmed to the 'shamt' field - creating non zero values to be written to reserved bits in the instruction word? Shouldn't the appropriate lower order bits of 'shamt' be written to the instruction word - no matter what size value (albeit a bug) the software developer incorrectly uses for 'shamt'?daveW
osgx - I have exchanged emails with Palmer. First, he suggests these type of problems be sent to [email protected] - and you should see some messages on 'sw-dev' already from me and Palmer on this topic. Second, he has asked me to post this issue as a bug on riscv-binutils-gdb. So, I think this wraps up this thread and the conversation continues at another forum/list. Lastly, I wonder if the poor readability of the spec when it comes to the format of the detailed instruction encoding tables contributes to creating these type of bugs. Counting long string of 0's is error prone.daveW

2 Answers

1
votes

This problem was considered a bug and the assembler code has been changed and merged. You can see details at GitHub riscv/riscv-binutils-gdb on the riscv-next branch. In 'gas' (the assembler) the severity level was changed from 'warn' to 'error' - preventing any illegal RV32I machine code to be created (03ff9f93 is not legal machine code for the slli command on RV32I).

For osgx - I am still intrigued by your comment that there are no separate 32/64 bit encoders. Can you please clarify?

1
votes

Just a short remark:

I can see from the spec (Version 20190608-Base-Ratified ) on pages 130 for RV32I and 131 for RV64I that there should be a difference in the encoding of the SLLI instruction.

RV32I for the shift amount is limited to 5 bits and for RV64I this is extended to 6 bits. So depending on the used assembler, there should be differences in the binary that results and in the displayed warnings or errors.

Greets Joachim