# RV32D `fld` leaves the upper 32 bits stale ## RV32D setup - The RV32D config is built from two custom mix-ins: ``` class WithRV32 extends RocketCoreConfig(c => c.copy( xLen = 32, pgLevels = 2, fpu = c.fpu.map(_.copy(fLen = 32)), mulDiv = Some(MulDivParams(mulUnroll = 8)) )) class WithRV32DoublePrecision extends RocketCoreConfig(c => c.copy(fpu = c.fpu.map(_.copy(fLen = 64)))) ``` - Compose them on top of your base config to form the RV32D target: ``` class RV32DConfig extends Config( new WithRV32DoublePrecision ++ new WithRV32 ++ new BaseConfig // or your project’s base ) ``` - Build Rocket with that config and run the generated RV32D binary; no extra extensions (vector, etc.) are required to reproduce the issue. ## Reproduction 1. Build and run Rocket in RV32 with the D extension enabled (e.g., using the `RV32DConfig` above). 2. Run the trimmed program below (`fmv.w.x` seeds `f16`, two `sw` zero the 8 bytes to be loaded): ``` li x5, 0x7fc00000 fmv.w.x f16, x5 li x2, 0x8ffffff8 sw x0, 0(x2) sw x0, 4(x2) li x26, 0x8fffff00 fld f16, 0(x2) fsd f16, 0(x26) lw x18, 0(x26) lw x17, 4(x26) ``` 3. After the `fld`, `f16` reads back as `0xc5ad84e600000000` and the stored doubleword at 0x8fffff00 matches that value. The expected result is `0x0`. ## Comparison - Rocket: `fld` keeps the prior upper 32 bits, so `fsd` writes `0xc5ad84e600000000` and `lw x17` sees `0xc5ad84e6`. - Spike: `fld` returns `0x0`, and `fsd` stores zeros.
RV32D
fldleaves the upper 32 bits staleRV32D setup
Reproduction
RV32DConfigabove).fmv.w.xseedsf16, twoswzero the 8 bytes to be loaded):fld,f16reads back as0xc5ad84e600000000and the stored doubleword at 0x8fffff00 matches that value. The expected result is0x0.Comparison
fldkeeps the prior upper 32 bits, sofsdwrites0xc5ad84e600000000andlw x17sees0xc5ad84e6.fldreturns0x0, andfsdstores zeros.