Skip to content

harm: refactor tbz/tbnz - #48

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

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

Conversation

@monoid

@monoidmonoid commented Dec 27, 2025

Copy link
Copy Markdown
Owner
  • 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.
@monoidmonoid self-assigned this Dec 27, 2025
@monoidmonoid added enhancement New feature or request harm The `harm` dynamic assembler labels Dec 27, 2025
@coderabbitai

coderabbitaiBot commented Dec 27, 2025

Copy link
Copy Markdown
📝 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately reflects the main refactoring work on tbz/tbnz instructions, covering type aliases, offset generalization, and improved test readability.
Docstring Coverage✅ PassedDocstring 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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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]fntest_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 offsetassert_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 masterDec 27, 2025
2 checks passed
@monoid
monoid deleted the harm/refactor-tbz branch December 27, 2025 16:56
@coderabbitaicoderabbitaiBot mentioned this pull request Dec 27, 2025
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 14, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestharmThe `harm` dynamic assembler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@monoid
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
harm: refactor `tbz`/`tbnz` by monoid · Pull Request #48 · monoid/harm · GitHub
Skip to content

harm: refactor tbz/tbnz - #48

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

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

Conversation

@monoid

@monoidmonoid commented Dec 27, 2025

Copy link
Copy Markdown
Owner
  • 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.
@monoidmonoid self-assigned this Dec 27, 2025
@monoidmonoid added enhancement New feature or request harm The `harm` dynamic assembler labels Dec 27, 2025
@coderabbitai

coderabbitaiBot commented Dec 27, 2025

Copy link
Copy Markdown
📝 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately reflects the main refactoring work on tbz/tbnz instructions, covering type aliases, offset generalization, and improved test readability.
Docstring Coverage✅ PassedDocstring 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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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]fntest_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 offsetassert_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 masterDec 27, 2025
2 checks passed
@monoid
monoid deleted the harm/refactor-tbz branch December 27, 2025 16:56
@coderabbitaicoderabbitaiBot mentioned this pull request Dec 27, 2025
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 14, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestharmThe `harm` dynamic assembler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@monoid
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' harm: refactor `tbz`/`tbnz` by monoid · Pull Request #48 · monoid/harm · GitHub
Skip to content

harm: refactor tbz/tbnz - #48

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

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

Conversation

@monoid

@monoidmonoid commented Dec 27, 2025

Copy link
Copy Markdown
Owner
  • 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.
@monoidmonoid self-assigned this Dec 27, 2025
@monoidmonoid added enhancement New feature or request harm The `harm` dynamic assembler labels Dec 27, 2025
@coderabbitai

coderabbitaiBot commented Dec 27, 2025

Copy link
Copy Markdown
📝 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately reflects the main refactoring work on tbz/tbnz instructions, covering type aliases, offset generalization, and improved test readability.
Docstring Coverage✅ PassedDocstring 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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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]fntest_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 offsetassert_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 masterDec 27, 2025
2 checks passed
@monoid
monoid deleted the harm/refactor-tbz branch December 27, 2025 16:56
@coderabbitaicoderabbitaiBot mentioned this pull request Dec 27, 2025
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 14, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestharmThe `harm` dynamic assembler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@monoid
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' harm: refactor `tbz`/`tbnz` by monoid · Pull Request #48 · monoid/harm · GitHub
Skip to content

harm: refactor tbz/tbnz - #48

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

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

Conversation

@monoid

@monoidmonoid commented Dec 27, 2025

Copy link
Copy Markdown
Owner
  • 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.
@monoidmonoid self-assigned this Dec 27, 2025
@monoidmonoid added enhancement New feature or request harm The `harm` dynamic assembler labels Dec 27, 2025
@coderabbitai

coderabbitaiBot commented Dec 27, 2025

Copy link
Copy Markdown
📝 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately reflects the main refactoring work on tbz/tbnz instructions, covering type aliases, offset generalization, and improved test readability.
Docstring Coverage✅ PassedDocstring 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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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]fntest_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 offsetassert_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 masterDec 27, 2025
2 checks passed
@monoid
monoid deleted the harm/refactor-tbz branch December 27, 2025 16:56
@coderabbitaicoderabbitaiBot mentioned this pull request Dec 27, 2025
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 14, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestharmThe `harm` dynamic assembler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@monoid
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' harm: refactor `tbz`/`tbnz` by monoid · Pull Request #48 · monoid/harm · GitHub
Skip to content

harm: refactor tbz/tbnz - #48

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

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

Conversation

@monoid

@monoidmonoid commented Dec 27, 2025

Copy link
Copy Markdown
Owner
  • 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.
@monoidmonoid self-assigned this Dec 27, 2025
@monoidmonoid added enhancement New feature or request harm The `harm` dynamic assembler labels Dec 27, 2025
@coderabbitai

coderabbitaiBot commented Dec 27, 2025

Copy link
Copy Markdown
📝 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately reflects the main refactoring work on tbz/tbnz instructions, covering type aliases, offset generalization, and improved test readability.
Docstring Coverage✅ PassedDocstring 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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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]fntest_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 offsetassert_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 masterDec 27, 2025
2 checks passed
@monoid
monoid deleted the harm/refactor-tbz branch December 27, 2025 16:56
@coderabbitaicoderabbitaiBot mentioned this pull request Dec 27, 2025
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 14, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestharmThe `harm` dynamic assembler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@monoid
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' harm: refactor `tbz`/`tbnz` by monoid · Pull Request #48 · monoid/harm · GitHub
Skip to content

harm: refactor tbz/tbnz - #48

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

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

Conversation

@monoid

@monoidmonoid commented Dec 27, 2025

Copy link
Copy Markdown
Owner
  • 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.
@monoidmonoid self-assigned this Dec 27, 2025
@monoidmonoid added enhancement New feature or request harm The `harm` dynamic assembler labels Dec 27, 2025
@coderabbitai

coderabbitaiBot commented Dec 27, 2025

Copy link
Copy Markdown
📝 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately reflects the main refactoring work on tbz/tbnz instructions, covering type aliases, offset generalization, and improved test readability.
Docstring Coverage✅ PassedDocstring 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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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]fntest_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 offsetassert_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 masterDec 27, 2025
2 checks passed
@monoid
monoid deleted the harm/refactor-tbz branch December 27, 2025 16:56
@coderabbitaicoderabbitaiBot mentioned this pull request Dec 27, 2025
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 14, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestharmThe `harm` dynamic assembler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@monoid
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' harm: refactor `tbz`/`tbnz` by monoid · Pull Request #48 · monoid/harm · GitHub
Skip to content

harm: refactor tbz/tbnz - #48

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

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

Conversation

@monoid

@monoidmonoid commented Dec 27, 2025

Copy link
Copy Markdown
Owner
  • 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.
@monoidmonoid self-assigned this Dec 27, 2025
@monoidmonoid added enhancement New feature or request harm The `harm` dynamic assembler labels Dec 27, 2025
@coderabbitai

coderabbitaiBot commented Dec 27, 2025

Copy link
Copy Markdown
📝 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately reflects the main refactoring work on tbz/tbnz instructions, covering type aliases, offset generalization, and improved test readability.
Docstring Coverage✅ PassedDocstring 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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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]fntest_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 offsetassert_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 masterDec 27, 2025
2 checks passed
@monoid
monoid deleted the harm/refactor-tbz branch December 27, 2025 16:56
@coderabbitaicoderabbitaiBot mentioned this pull request Dec 27, 2025
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 14, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestharmThe `harm` dynamic assembler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@monoid
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); harm: refactor `tbz`/`tbnz` by monoid · Pull Request #48 · monoid/harm · GitHub
Skip to content

harm: refactor tbz/tbnz - #48

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

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

Conversation

@monoid

@monoidmonoid commented Dec 27, 2025

Copy link
Copy Markdown
Owner
  • 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.
@monoidmonoid self-assigned this Dec 27, 2025
@monoidmonoid added enhancement New feature or request harm The `harm` dynamic assembler labels Dec 27, 2025
@coderabbitai

coderabbitaiBot commented Dec 27, 2025

Copy link
Copy Markdown
📝 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 nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title accurately reflects the main refactoring work on tbz/tbnz instructions, covering type aliases, offset generalization, and improved test readability.
Docstring Coverage✅ PassedDocstring 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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown

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]fntest_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 offsetassert_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 masterDec 27, 2025
2 checks passed
@monoid
monoid deleted the harm/refactor-tbz branch December 27, 2025 16:56
@coderabbitaicoderabbitaiBot mentioned this pull request Dec 27, 2025
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 14, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or requestharmThe `harm` dynamic assembler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@monoid