Skip to content

Fix RV64 Zcmp push/pop offsets - #3564

Open
124107157-KV wants to merge 1 commit into
openhwfoundation:masterfrom
124107157-KV:fix/3440-rv64-zcmp-offsets
Open

124107157-KV wants to merge 1 commit into
openhwfoundation:masterfrom
124107157-KV:fix/3440-rv64-zcmp-offsets

Conversation

@124107157-KV

Copy link
Copy Markdown
Contributor
  • I have searched for similar pull requests
  • I am a human engaging in an interpersonal interaction. During this interaction, my words are my own and are not generated. If relevant, I provide links to my sources.

Why is this PR needed?

The RV64 Zcmp PUSH/POP macro expansion currently uses the RV32 register-slot size when calculating stack offsets.

On RV32, registers occupy 4-byte stack slots, so decrementing the generated offset by 4 bytes is correct. On RV64, however, the generated SD and LD operations operate on 8-byte values and therefore the offset must advance in 8-byte steps.

The existing implementation continues to decrement offsets by 4 bytes for both XLEN values and compensates for RV64 by forcing immediate bit 2 of generated SD/LD instructions to zero. This causes consecutive RV64 register accesses to alias the same stack location.

For example:

cm.push {ra, s0-s1}, -32

should expand on RV64 as:

sd   s1, -8(sp)
sd   s0, -16(sp)
sd   ra, -24(sp)
addi sp, sp, -32

Before this change, the expansion effectively produces overlapping stack accesses:

sd   s1, -8(sp)
sd   s0, -8(sp)
sd   ra, -16(sp)
addi sp, sp, -36

The same offset problem affects cm.pop, cm.popret, and cm.popretz.

The RV64 path also applies an additional 4-byte correction to the final stack-pointer update. As a result, PUSH adjusts SP by four bytes too much and POP-family instructions adjust SP by four bytes too little.

What does this PR change?

This PR makes the Zcmp register-slot offset dependent on XLEN:

  • RV32 uses a 4-byte register-slot step.
  • RV64 uses an 8-byte register-slot step.

The new XLEN-dependent offset is used throughout the PUSH/POP macro expansion state machine.

The change also:

  • fixes the initial POP-family register offset on RV64;
  • uses the correct offset progression for all subsequent expanded register accesses;
  • removes the RV64-specific immediate bit-2 masking from generated SD and LD instructions;
  • removes the extra 4-byte correction from the final RV64 stack-pointer adjustment;
  • keeps the existing RV32 behavior unchanged;
  • fixes the special maximum-rlist path handled through PUSH_POP_INSTR_2.

Verification

A focused RV64 macro-decoder regression was added.

Before applying the RTL fix, the regression reproduced the issue with the following incorrect behavior:

  • cm.push {ra,s0-s1}, -32

    • s1: -8(sp)
    • s0: -8(sp) instead of -16(sp)
    • ra: -16(sp) instead of -24(sp)
    • SP adjustment: -36 instead of -32
  • cm.pop {ra,s0-s1}, 32

    • s1: 24(sp)
    • s0: 24(sp) instead of 16(sp)
    • ra: 16(sp) instead of 8(sp)
    • SP adjustment: 28 instead of 32
  • the maximum-rlist PUSH and POP paths also repeated adjacent stack offsets instead of progressing by 8 bytes.

After the fix, the RV64 regression verifies:

  • cm.push

    • offsets -8, -16, and -24
    • final SP adjustment -32
  • cm.pop

    • offsets 24, 16, and 8
    • final SP adjustment 32
  • cm.popret

    • correct RV64 load offsets
    • correct SP adjustment
    • correct final return micro-op
  • cm.popretz

    • correct RV64 load offsets
    • correct zeroing of a0
    • correct SP adjustment
    • correct final return micro-op
  • maximum-rlist PUSH/POP offset progression through PUSH_POP_INSTR_2.

The existing RV32 macro-decoder regression continues to pass.

The following checks were run successfully:

make -C verif/tb/macro_decoder_unit
make -C util/sanitize xlen
make verilate target=cv64a6_imafdc_sv39

The full RV64 Verilator build completes successfully.

Related issue

Fixes #3440

Limitations

The new regression tests the macro decoder directly rather than executing the compressed instructions as a full architectural software test.

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.

[BUG] RV64 Zcmp PUSH/POP expansion uses 4-byte offset increments, causing overlapping accesses and incorrect SP adjustment

1 participant