Skip to content

harm: refactor tbz/tbnz#48

Merged
monoid merged 3 commits intomasterfrom
harm/refactor-tbz
Dec 27, 2025
Merged

harm: refactor tbz/tbnz#48
monoid merged 3 commits intomasterfrom
harm/refactor-tbz

Conversation

@monoid
Copy link
Owner

@monoid monoid commented Dec 27, 2025

  • Use type aliases.
  • Generalize on offsets.
  • Make tests more readable.

Summary by CodeRabbit

  • Refactor
    • Test-and-branch instructions now accept a generic offset and explicit bit-width variants, improving flexibility for 32/64-bit encodings.
    • Public constructors and APIs for tbnz/tbz were updated to require an explicit offset parameter.
  • Tests
    • Encoding tests updated to the new generic paths, covering varied offsets (including negative) and register cases with compact expected outputs.

✏️ Tip: You can customize this high-level summary in your review settings.

+ Use type aliases.
+ Generalize on offsets.
+ Make tests more readable.
@monoid monoid self-assigned this Dec 27, 2025
@monoid monoid added enhancement New feature or request harm The `harm` dynamic assembler labels Dec 27, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 27, 2025

📝 Walkthrough

Walkthrough

Introduces a generic Offset parameter to TestBranch, adds TestBranchBit64/TestBranchBit32 and TestBranchOffset aliases, and updates Sealed, MakeTestBranch, RawInstruction impls, tbnz/tbz signatures, and tests to use the new generic offset and encodings. (50 words)

Changes

Cohort / File(s) Summary
TestBranch genericization & encodings
harm/src/instructions/control/testbranch.rs
Replaced TestBranch<Reg, Bit> with TestBranch<Reg, Bit, Offset>; added pub type TestBranchBit64 = UBitValue<6>, TestBranchBit32 = UBitValue<5>, TestBranchOffset = SBitValue<14, 2>; extended Sealed implementations for 32/64 variants; changed MakeTestBranch trait to MakeTestBranch<Reg, Bit, Offset> and updated impls; updated RawInstruction impls and tbnz/tbz constructors; adjusted tests and expected encodings.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I nibble bits beneath the moonlit rack,
Offsets stretched — I hop and never look back,
Traits aligned, encodings set to play,
A tiny rabbit tests branches all day,
Hopping through bits with a jubilant tack. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main refactoring work on tbz/tbnz instructions, covering type aliases, offset generalization, and improved test readability.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch harm/refactor-tbz

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 58de0d3 and a82ac80.

📒 Files selected for processing (1)
  • harm/src/instructions/control/testbranch.rs
🔇 Additional comments (10)
harm/src/instructions/control/testbranch.rs (10)

18-20: Well-chosen type aliases improve clarity.

The aliases clearly express intent: TestBranchBit64 vs TestBranchBit32 makes the 64-bit/32-bit distinction explicit, and TestBranchOffset encapsulates the signed 14-bit PC-relative offset semantics.


22-27: Offset generalization enables flexible encoding.

Adding Offset as a generic parameter allows TestBranch to work with different offset representations while maintaining type safety. This aligns well with the PR's goal to generalize on offsets.


29-30: Sealed trait implementations correctly constrain the API.

The two concrete instantiations properly seal the trait to only the intended 64-bit and 32-bit variants.


32-34: Trait signature properly reflects the generalization.

The addition of the Offset parameter maintains consistency with the struct changes.


36-47: 64-bit implementation correctly uses concrete types.

The implementation properly instantiates the generic trait with TestBranchBit64 and TestBranchOffset.


49-60: Good consistency fix on line 55.

Changing reg.into() to reg.into_reg() aligns the 32-bit implementation with the 64-bit version (line 42), improving code consistency.


62-75: 64-bit encoding correctly splits the 6-bit position.

The bit extraction logic properly decomposes the 6-bit register bit position into b5 (high bit) and b40 (low 5 bits) for the ARM64 instruction encoding.


77-90: 32-bit encoding correctly uses 5-bit position.

Setting b5 = 0 is correct because 32-bit registers require only a 5-bit position (0-31), which fits entirely in b40.


92-108: Public functions properly generalized over Offset.

The generic Offset parameter in tbnz and tbz enables callers to use different offset types while maintaining type safety through the MakeTestBranch bound. This increases API flexibility.


123-253: Tests are more explicit and comprehensive.

The explicit type constructors (TestBranchOffset::new(), TestBranchBit64::new()) make the tests clearer, and the inst! macro improves readability of expected encodings. The new tbnz tests provide excellent coverage mirroring the tbz cases.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
harm/src/instructions/control/testbranch.rs (1)

49-60: Align 32-bit trait bounds with 64-bit implementation.

The 32-bit MakeTestBranch implementation uses Into<RegOrZero32> and .into(), while the 64-bit version uses IntoReg<RegOrZero64> and .into_reg(). Since IntoReg is implemented for RegOrZero32, update the 32-bit implementation to use IntoReg<RegOrZero32> and call .into_reg() for consistency.

🧹 Nitpick comments (2)
harm/src/instructions/control/testbranch.rs (2)

36-47: Inconsistent type alias usage.

Lines 37 and 39 use the raw UBitValue<6> type instead of the TestBit64 alias, which is inconsistent with the alias definition and its usage on line 36.

🔎 Suggested fix
 impl<R: IntoReg<RegOrZero64>> MakeTestBranch<R, TestBit64, TestOffset>
-    for TestBranch<RegOrZero64, UBitValue<6>, TestOffset>
+    for TestBranch<RegOrZero64, TestBit64, TestOffset>
 {
-    fn new(op: bool, reg: R, bit: UBitValue<6>, offset: TestOffset) -> Self {
+    fn new(op: bool, reg: R, bit: TestBit64, offset: TestOffset) -> Self {
         Self {
             op,
             reg: reg.into_reg(),
             bit,
             offset,
         }
     }
 }

110-121: Consider adding tbnz tests.

All current tests cover tbz only. While tbnz shares the encoding logic (differing only in the op bit), adding at least one tbnz test would improve coverage and serve as a regression guard.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a759507 and 5e82e4e.

📒 Files selected for processing (1)
  • harm/src/instructions/control/testbranch.rs
🔇 Additional comments (5)
harm/src/instructions/control/testbranch.rs (5)

18-21: LGTM!

The type aliases improve readability and provide meaningful names for the bit-width constraints.


22-30: LGTM!

The struct generalization and sealed implementations correctly constrain the valid instantiations.


62-90: LGTM!

The bit extraction logic correctly handles the encoding differences between 64-bit (6-bit index, b5 can be 0 or 1) and 32-bit (5-bit index, b5 always 0) variants.


92-108: LGTM!

The generalized constructors properly leverage the trait bounds for type-safe instruction construction.


123-177: LGTM!

Tests provide good coverage for:

  • 64-bit registers with both high (≥32) and low (<32) bit positions
  • 32-bit registers
  • Zero registers (XZR, WZR)

The compact inst!() macro format improves readability as noted in PR objectives.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
harm/src/instructions/control/testbranch.rs (1)

36-60: Fix trait bound inconsistency: use IntoReg<RegOrZero32> instead of Into<RegOrZero32> for the 32-bit implementation.

Line 49 uses the standard Into<RegOrZero32> trait while line 36 uses the custom IntoReg<RegOrZero64> trait. Since IntoReg<RegOrZero32> has proper implementations for Reg32 and RegOrZero32 and is used consistently throughout the codebase for register conversions, the 32-bit variant should also use IntoReg<RegOrZero32> with into_reg() (line 55) to match the 64-bit pattern.

🧹 Nitpick comments (1)
harm/src/instructions/control/testbranch.rs (1)

123-177: LGTM: Tests updated correctly with improved readability.

The tests now use explicit type aliases, making them more self-documenting. Coverage includes both 64-bit and 32-bit variants, different bit positions, and zero registers.

Optional: Consider adding test coverage for negative offsets.

All tests currently use positive offset 76. Since TestBranchOffset is a signed value (SBitValue<14, 2>), adding at least one test with a negative offset would improve coverage.

Example test for negative offset
#[test]
fn test_tbz_64_neg_offset() {
    let offset = TestBranchOffset::new(-8).unwrap();
    let bit = TestBranchBit64::new(10).unwrap();
    let it = tbz(X5, bit, offset);
    let words: Vec<_> = it.encode().collect();
    // Verify expected encoding for negative offset
    assert_eq!(words, inst!(0x...));  // Fill in expected value
}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5e82e4e and 58de0d3.

📒 Files selected for processing (1)
  • harm/src/instructions/control/testbranch.rs
🧰 Additional context used
🧬 Code graph analysis (1)
harm/src/instructions/control/testbranch.rs (3)
harm/src/instructions/control/branch_reg.rs (2)
  • new (26-28)
  • reg (31-34)
harm/src/instructions/control/branch_imm.rs (5)
  • new (200-200)
  • new (209-215)
  • new (226-232)
  • new (241-247)
  • new (256-262)
harm/src/instructions/arith/add.rs (3)
  • new (42-42)
  • new (57-59)
  • new (66-68)
🔇 Additional comments (7)
harm/src/instructions/control/testbranch.rs (7)

18-20: LGTM: Type aliases improve clarity.

The type aliases appropriately encode ARM64 test-and-branch constraints (6-bit for 64-bit registers, 5-bit for 32-bit registers, 14-bit signed offset with 4-byte alignment).


22-27: LGTM: Generalization improves flexibility.

Adding the Offset type parameter allows for future extensibility while maintaining type safety through trait bounds.


29-30: LGTM: Sealed trait pattern correctly applied.

The explicit implementations restrict MakeTestBranch to only the two intended concrete types.


32-34: LGTM: Trait signature correctly updated.

The trait now accepts the generic Offset parameter, consistent with the struct definition.


62-75: LGTM: Bit extraction logic is correct.

The 6-bit value is correctly split into b5 (MSB) and b40 (bits 4-0) for ARM64 test-and-branch encoding.


77-90: LGTM: 32-bit encoding correctly sets b5 to 0.

The implementation correctly handles 5-bit test positions (0-31) by hardcoding b5=0, since bit 5 doesn't exist for 32-bit registers.


92-108: LGTM: Public API correctly generalized.

The functions now accept a generic Offset parameter with appropriate trait bounds, improving flexibility while maintaining type safety.

@monoid monoid merged commit 663fe0b into master Dec 27, 2025
2 checks passed
@monoid monoid deleted the harm/refactor-tbz branch December 27, 2025 16:56
@coderabbitai coderabbitai bot mentioned this pull request Dec 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request harm The `harm` dynamic assembler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant