Skip to content

rv32c: complete the Zcb extension (unblocks RP2350 flash/bootrom boot)#1

Open
prat96 wants to merge 1 commit into
c1570:rp2350js/WIPfrom
prat96:fix/rv32c-zcb-completion
Open

rv32c: complete the Zcb extension (unblocks RP2350 flash/bootrom boot)#1
prat96 wants to merge 1 commit into
c1570:rp2350js/WIPfrom
prat96:fix/rv32c-zcb-completion

Conversation

@prat96

@prat96 prat96 commented Jun 26, 2026

Copy link
Copy Markdown

What

Completes RV32 Zcb compressed-instruction decoding in src/riscv/rv32c.ts. The decoder
previously handled only c.lbu, c.lhu, and c.not; this adds the rest of the extension:

  • C0 loads/stores: c.lh, c.sb, c.sh
  • C1 unary: c.zext.b, c.sext.b, c.zext.h, c.sext.h
  • c.mul

Each is decompressed to an instruction the core already executes — andi, sext.b/sext.h
(Zbb), pack rd,rd,x0 (= zext.h), xori, mul (RV32M), and lh/sb/sh.

Why

The RP2350 boot ROM is built with Zcb, so these encodings appear during early boot. With
them missing, any RP2350 flash binary aborts almost immediately — booting a real board's
firmware died at Unknown compressed instruction: 0x9fe1 (c.zext.b) inside the ROM, then
Unsupported Zcb instruction: 0x8c24 (c.sh). Completing Zcb lets flash images boot through
the ROM. (The rp2350js/WIP README already lists RV32Zcb (lbu, lhu, not) as partial.)

Tests

Adds src/riscv/rv32c-zcb.spec.ts — 9 cases covering every new opcode, including the two real
bootrom encodings (0x9fe1, 0x8c24) that triggered this. npx vitest run is green
(355 passed, including the existing suite).

Notes

  • c.zext.w is RV64-only and intentionally not handled.
  • Also makes the decompress_rv32c_inst "cannot handle index" error include the raw encoding
    and PC, which is what made the missing instructions easy to spot.

Based on rp2350js/WIP.

The decoder handled only c.lbu/c.lhu/c.not from Zcb. The RP2350 boot ROM is
compiled with Zcb, so every flash binary aborts in early ROM with e.g.
"Unknown compressed instruction: 0x9fe1" (c.zext.b) or
"Unsupported Zcb instruction: 0x8c24" (c.sh).

Add the rest of Zcb, decompressing each to an instruction the core already
runs: c.zext.b->andi, c.sext.b/c.sext.h->Zbb, c.zext.h->pack(rd,rd,x0),
c.not->xori, c.mul->mul, and the c.lh/c.sb/c.sh loads/stores. c.zext.w is
RV64-only and left out.

Adds src/riscv/rv32c-zcb.spec.ts (9 cases, including the two real bootrom
encodings that originally blocked boot). Full suite stays green.

Signed-off-by: Pratheek Balakrishna <pratheekb96@gmail.com>
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.

1 participant