fix(cpu): PPCBUG-046 PPCBUG-561 add mb_md() accessor; fix all 6 rld* mb fields
PPCBUG-561: Add DecodedInstr::mb_md() to decoder.rs — the correct MD-form 6-bit mask-begin reconstruction (MB[4:0] at PPC bits 21-25, MB[5] at PPC bit 26). The disassembler already had the correct local formula; this promotes it to a single source of truth on DecodedInstr. PPCBUG-046: All 6 doubleword-rotate arms (rldicl, rldicr, rldic, rldimi, rldcl, rldcr) inlined "(instr.mb() << 1) | ((instr.raw >> 1) & 1)" which reads SH5 (host bit 1) instead of MB5 (host bit 5). For the canonical "clrldi r3, r4, 32" zero-extend idiom (mb=32 → MB5=1, MB[4:0]=0), the wrong formula produced mb=0, making the instruction a no-op and leaving upper 32 bits of the GPR polluted. Replace all 6 sites with instr.mb_md(). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -92,6 +92,12 @@ impl DecodedInstr {
|
||||
(extract_bits(self.raw, 30, 30) << 5) | extract_bits(self.raw, 16, 20)
|
||||
}
|
||||
|
||||
/// MB/ME field for MD-form and MDS-form instructions (6-bit field, split encoding).
|
||||
/// MB[4:0] at PPC bits 21-25; MB[5] at PPC bit 26.
|
||||
#[inline] pub fn mb_md(&self) -> u32 {
|
||||
extract_bits(self.raw, 21, 25) | (extract_bits(self.raw, 26, 26) << 5)
|
||||
}
|
||||
|
||||
/// SPR field (bits 11-20, swapped halves)
|
||||
#[inline] pub fn spr(&self) -> u32 {
|
||||
let spr_raw = extract_bits(self.raw, 11, 20);
|
||||
|
||||
Reference in New Issue
Block a user