Skip to content

PowerPC: Keep BI out of the CTR-only branch predicate - #3043

Merged
Rot127 merged 3 commits into
capstone-engine:nextfrom
phix33:ppc-branch-pred-ctr
Aug 29, 2026
Merged

PowerPC: Keep BI out of the CTR-only branch predicate#3043
Rot127 merged 3 commits into
capstone-engine:nextfrom
phix33:ppc-branch-pred-ctr

Conversation

@phix33

@phix33 phix33 commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Your checklist for this pull request

  • I've documented or updated the documentation of every API function and struct this PR changes.
  • I've added tests that prove my fix is effective or that my feature works (if possible)

Detailed description

For a BO that encodes only the counter condition, PPC_get_branch_pred() falls through to PPC_get_no_hint_pred(((bi % 4) << 5) | bo). BI selects a CR bit and has no part in that predicate, so mixing it in lands outside ppc_pred and the counter test is lost:

42 00 ff f0   BO=16 BI=0  ->  pred_ctr = PPC_PRED_NZ        correct
42 06 00 10   BO=16 BI=6  ->  pred_ctr = PPC_PRED_INVALID   same BO

The combined-condition branch above already gets this right — it computes (bo | PPC_BO_TEST_CR) & ~PPC_BO_CR_CMP and notes that BI is ignored. Rather than repeat that expression, the !get_cr_pred case is hoisted above the TestCR && DecrCTR block, so the CTR predicate is derived in one place and the ctr_bo_cond local goes away. The function's doc comment already promises PPC_PRED_INVALID only when no such predicate is encoded, so this restores the documented contract rather than changing it.

Test plan

One case in tests/details/ppc.yaml covering BO=16 and BO=18 with a non-zero BI on bc, plus a bclr for the XL form, whose BI and BO come out of a different field mask. The BO=16 BI=6 bc fails against unpatched next; the others state the invariant in the fixture rather than in one encoding.

Each case also asserts pred_cr: PPC_PRED_INVALID, so that deriving the CTR predicate in one place cannot start manufacturing a CR one. That needed the one-line map addition: PPC_PRED_INVALID was the only ppc_pred member missing from cs_enum_map, and compare_enum_ret is wrapped in if (expected), so until the name resolves the field is silently not compared at all. It is asserted only on the new cases — a combined-condition branch legitimately has both predicates, as the existing bdztla 4*cr5+eq case shows.

  • Purely additive over the full BO x BI space (32x32) of bc, bclr and bcctr — 3072 encodings: those that returned PPC_PRED_INVALID now return the predicate they encode, and no existing value changes.
  • cstest tests/ goes 87971/87034/932/5 -> 87972/87035/932/5 — the same five failures, all tests/negative/, and no expectation edited.
  • Re-checked that the new pred_cr assertion does not mask the pred_ctr one it sits beside (a case stops at its first mismatch, and pred_cr is compared first): with the ppc.h change reverted, the case still fails on pred_ctr.

Closing issues

None

Copilot AI 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.

Pull request overview

Fixes PowerPC branch-predicate decoding so that CTR-only BO encodings produce the correct pred_ctr regardless of BI (which selects a CR bit and must not influence CTR-only predicates), restoring the documented PPC_get_branch_pred() contract.

Changes:

  • Adjust PPC_get_branch_pred() to derive CTR predicates without mixing in BI when get_cr_pred == false.
  • Add YAML test cases covering CTR-only BO values with non-zero BI for both bc and bclr encodings.
  • Add missing PPC_PRED_INVALID entry to the cstest enum-name map so expected/actual comparisons don’t silently skip that value.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
tests/details/ppc.yaml Adds regression tests for CTR-only branch predicate decoding with non-zero BI (bc + bclr).
suite/cstest/include/test_mapping.h Adds PPC_PRED_INVALID to cs_enum_map so cstest can compare that enum value by name.
include/capstone/ppc.h Fixes PPC_get_branch_pred() to keep BI out of the CTR-only predicate derivation path.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@phix33
phix33 force-pushed the ppc-branch-pred-ctr branch from fb4ac6a to 53119d2 Compare August 29, 2026 12:39
@Rot127

Rot127 commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Thanks

@Rot127

Rot127 commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Did you use an LLM to generate this PR description btw?

@phix33

phix33 commented Aug 29, 2026

Copy link
Copy Markdown
Contributor Author

Did you use an LLM to generate this PR description btw?

Yes but I typically edit them as they're too verbose. The co-pilot summary is better, I'll aim for that level of detail next time.

@Rot127

Rot127 commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

For the next PR please be so kind and consider more what is the minimal example showing the problem.

A description like below would have saved me a lot of time understanding what was going on.


This cstool command doesn't contain the BO, BI bits. Because if the PPC_BO_TEST_CR bit is set, but the BI contains bits as well, it decodes to invalid.

E.g. here the Branching details are missing:

cstool -r -d ppc32be "42 06 00 10"
 0  42 06 00 10  bc	0x10, 4*cr1+eq, 0x10
	ID: 1706 (bc)
	op_count: 3
		operands[0].type: IMM = 0x10
		operands[0].access: READ
		operands[1].type: REG = 6
		operands[1].access: READ
		operands[2].type: IMM = 0x10
		operands[2].access: READ
	Implicit registers read: ctr **ROUNDING MODE**
	Implicit registers modified: ctr
	Groups: jump branch_relative 

@Rot127

Rot127 commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Actually, I would kindly request to not write PR descriptions at all with LLMs. They are really hard to read.

@phix33

phix33 commented Aug 29, 2026

Copy link
Copy Markdown
Contributor Author

Will do, thanks for taking the time to show me the way.

@Rot127

Rot127 commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

np, thanks for the fix!

@Rot127
Rot127 merged commit 210b0ab into capstone-engine:next Aug 29, 2026
58 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants