Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document addi immediate #71

Merged
merged 2 commits into from
Feb 20, 2023
Merged

Conversation

nick-knight
Copy link
Contributor

@nick-knight nick-knight commented Sep 16, 2021

The RISC-V assembly language allows negative addi immediates to be expressed in more than one way, which may be surprising to newcomers. This PR is intended to resolve #70.

@aswaterman
Copy link
Contributor

Suggest "Representation of Signed Immediates for I-type Instructions" or something; as it is, it sounds addi-specific.

I thought about generalizing it to N-bit signed immediates, but the extra arithmetic will make it too opaque to be useful.

@nick-knight
Copy link
Contributor Author

nick-knight commented Sep 16, 2021

I intended it to be addi-specific because I didn't verify it exhaustively for all I-type instructions, or prove it by analyzing the binutils source tree. I will certainly take your word for it if this is a general feature.

However, it doesn't appear to work when using the LLVM integrated assembler:

$ riscv64-unknown-elf-clang -march=rv32i -integrated-as -c tmp.S
tmp.S:1:14: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
addi x0, x0, 0xfffff800

so perhaps I've stumbled across another GNU vs. LLVM debate.

@aswaterman
Copy link
Contributor

aswaterman commented Sep 16, 2021

All I-type and S-type instructions that have 12-bit signed immediates. (e.g. doesn't apply to shift instructions, which although I-type have only lg(XLEN)-bit unsigned immediates)

topperc added a commit to llvm/llvm-project that referenced this pull request Feb 17, 2023
Internally we store constants in int64_t after parsing, but this is
kind of an implementation detail. If we only supported rv32, we might
have chosen int32_t.

For rv32, I think it makes sense to accept the constants that we
would accept if int32_t was the internal type. In fact we already
do this for the `li` alias. This patch extends this to sign
extended constants for other instructions.

This matches the GNU assembler. The difference between LLVM and gcc
was previously noted here. riscv-non-isa/riscv-asm-manual#71

Reviewed By: reames

Differential Revision: https://reviews.llvm.org/D144166
@topperc
Copy link
Contributor

topperc commented Feb 17, 2023

LLVM should match GNU as now.

Though I noticed that GNU as doesn't support 0xffffffff as a valid constant for c.addi on RV32.

@nick-knight
Copy link
Contributor Author

nick-knight commented Feb 17, 2023

@topperc: Thanks for the update. Your observation about c.addi is interesting but beyond the scope of this PR (it's CI-type).

I've also attempted to address @aswaterman's feedback from a while back.

It appears both GNU and LLVM assemblers accept the assembly syntax described in this PR. It's up to the community to decide whether this behavior should be enshrined in our assembly language.

Copy link
Contributor

@aswaterman aswaterman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I'll approve, but I don't want to unilaterally click the merge button.

CarlosAlbertoEnciso pushed a commit to SNSystems/llvm-debuginfo-analyzer that referenced this pull request Feb 18, 2023
Internally we store constants in int64_t after parsing, but this is
kind of an implementation detail. If we only supported rv32, we might
have chosen int32_t.

For rv32, I think it makes sense to accept the constants that we
would accept if int32_t was the internal type. In fact we already
do this for the `li` alias. This patch extends this to sign
extended constants for other instructions.

This matches the GNU assembler. The difference between LLVM and gcc
was previously noted here. riscv-non-isa/riscv-asm-manual#71

Reviewed By: reames

Differential Revision: https://reviews.llvm.org/D144166
@kito-cheng
Copy link
Collaborator

LGTM
@asb @luismarques do you mind that a look if this looks good to you?

@luismarques
Copy link
Contributor

LGTM. Shouldn't the commits be squashed during the merge?

@nick-knight
Copy link
Contributor Author

I only have "Read" access to this repo so I can't do anything useful.

@kito-cheng
Copy link
Collaborator

Gonna to merge, thanks @nick-knight, and thanks @topperc push this forward!

@kito-cheng kito-cheng merged commit 307c7f0 into riscv-non-isa:master Feb 20, 2023
veselypeta pushed a commit to veselypeta/cherillvm that referenced this pull request Aug 12, 2024
Internally we store constants in int64_t after parsing, but this is
kind of an implementation detail. If we only supported rv32, we might
have chosen int32_t.

For rv32, I think it makes sense to accept the constants that we
would accept if int32_t was the internal type. In fact we already
do this for the `li` alias. This patch extends this to sign
extended constants for other instructions.

This matches the GNU assembler. The difference between LLVM and gcc
was previously noted here. riscv-non-isa/riscv-asm-manual#71

Reviewed By: reames

Differential Revision: https://reviews.llvm.org/D144166
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Document immediate encoding for addi
5 participants