Files
xenia-rs/migration/project-root/ppc-manual/branch/bx.md
MechaCat02 e6d43a23ac chore: add migration/ bundle for cross-machine setup
Bundles state that lives OUTSIDE the xenia-rs repo so a fresh clone on
another machine can be brought up to identical configuration via
migration/setup.sh:

  - claude-memory/             ~/.claude/projects/-home-fabi-RE-Project-Sylpheed/memory/
                               (103 files, 1.1 MB - MEMORY.md + every
                                project_xenia_rs_*.md from audits
                                addis_signext through audit-058)
  - project-root/dot-claude/   <project-root>/.claude/settings.json
                               (Stop hook + permissions)
  - project-root/ppc-manual/   <project-root>/ppc-manual/
                               (PowerPC reference docs, 397 files, 3.7 MB)
  - project-root/run-canary.sh <project-root>/run-canary.sh
  - README.md                  Human-readable setup checklist
  - setup.sh                   Idempotent installer (also reclones
                               xenia-canary at pinned HEAD 6de80dffe)
  - MANIFEST.md                Per-file mapping + per-file-not-bundled
                               restoration recipe

Excluded from bundle (not shippable via git):
  - Sylpheed ISO (7.8 GB; copyright; manual copy required)
  - sylpheed.db (395 MB; regenerable from XEX via analysis tooling)
  - target/ build artifacts (rebuild on target)
  - audit-runs probe firehoses (.log/.stdout/.stderr ~11 GB; rerun if needed)
  - audit-runs memory dumps (.bin ~4.5 GB; rerun audit-026/027/029 if needed)
  - xenia-canary checkout (setup.sh reclones from
    git.mc02.dev/fabi/Xenia-Canary.git at HEAD 6de80dffe)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 21:38:38 +02:00

134 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# `bx` — Branch
> **Category:** [Branch & System](../categories/branch.md) · **Form:** [I](../forms/I.md) · **Opcode:** `0x48000000` · _sync_
<!-- GENERATED: BEGIN -->
## Assembler Mnemonics
| Mnemonic | XML entry | Flags | Description |
| --- | --- | --- | --- |
| `b` | `bx` | — | Branch |
| `bl` | `bx` | LK=1 | Branch |
## Syntax
```asm
b[LK][AA] [ADDR]
```
## Encoding
### `bx` — form `I`
- **Opcode word:** `0x48000000`
- **Primary opcode (bits 05):** `18`
- **Extended opcode:** —
- **Synchronising:** yes
| Bits | Field | Meaning |
| --- | --- | --- |
| 05 | `OPCD` | primary opcode |
| 629 | `LI` | signed 24-bit word-offset target |
| 30 | `AA` | absolute-address flag |
| 31 | `LK` | link flag (bl/ba/bla) |
## Operands
| Field | Role | Description |
| --- | --- | --- |
| `LK` | bx: read | Link bit. When 1, LR ← address-of-next-instruction before the branch is taken. |
| `AA` | bx: read | Absolute-address bit. When 1, the branch target is the sign-extended displacement itself; when 0, it is added to the current instruction address. |
| `ADDR` | bx: read | Encoded branch target displacement (24-bit for I-form, 14-bit for B-form, word-shifted). |
| `LR` | bx: write (conditional) | Link register. Written by `bl`/`bla`/`bcl`/`bclrl`/`bcctrl`; read by `bclr`/`bclrl`. |
## Register Effects
### `bx`
- **Reads (always):** `LK`, `AA`, `ADDR`
- **Reads (conditional):** _none_
- **Writes (always):** _none_
- **Writes (conditional):** `LR`
## Status-Register Effects
_No condition-register or status-register effects._
## Operation (pseudocode)
```
NIA <- (CIA + EXTS(LI || 0b00)) if AA=0
<- EXTS(LI || 0b00) if AA=1
if LK then LR <- CIA + 4
```
## C Translation Example
```c
/* b / bl / ba / bla — unconditional branch (I-form, primary 18) */
int32_t li = (int32_t)(insn.LI << 2); /* sign-extended word-offset */
uint32_t target = insn.AA ? (uint32_t)li : (uint32_t)(pc + li);
uint32_t next = pc + 4;
if (insn.LK) lr = next; /* bl / bla save return addr */
pc = target;
```
## Implementation References
**`bx`**
- xenia-canary XML: [`tools/ppc-instructions.xml` — search for `mnem="bx"`](../../xenia-canary/tools/ppc-instructions.xml)
- xenia-canary emit: [`src/xenia/cpu/ppc/ppc_emit_control.cc:154`](../../xenia-canary/src/xenia/cpu/ppc/ppc_emit_control.cc#L154)
- xenia-rs opcode: [`crates/xenia-cpu/src/opcode.rs:11`](../../xenia-rs/crates/xenia-cpu/src/opcode.rs#L11)
- xenia-rs decoder: [`crates/xenia-cpu/src/decoder.rs:342`](../../xenia-rs/crates/xenia-cpu/src/decoder.rs#L342)
- xenia-rs interpreter: [`crates/xenia-cpu/src/interpreter.rs:897-907`](../../xenia-rs/crates/xenia-cpu/src/interpreter.rs#L897-L907)
<details><summary>xenia-rs interpreter body (frozen snapshot)</summary>
```rust
PpcOpcode::bx => {
let target = if instr.aa() {
instr.li() as u32
} else {
ctx.pc.wrapping_add(instr.li() as u32)
};
if instr.lk() {
ctx.lr = (ctx.pc + 4) as u64;
}
ctx.pc = target;
}
```
</details>
<!-- GENERATED: END -->
## Special Cases & Edge Conditions
- **24-bit word-aligned target.** `LI` is a 24-bit signed word-count. Hardware concatenates `LI || 0b00` (adds the implicit two low zero bits) and sign-extends to 64 bits before using it as an address. The displacement range is therefore ±32 MiB in bytes (`2^25 … +2^25 4`).
- **Four mnemonics, one opcode.** The four runtime variants selected by `AA` and `LK`:
- `b``AA = 0, LK = 0` — PC-relative, no link.
- `bl``AA = 0, LK = 1` — PC-relative, `LR = CIA + 4` (the ubiquitous function-call primitive).
- `ba``AA = 1, LK = 0` — absolute, no link.
- `bla``AA = 1, LK = 1` — absolute, link.
Xbox 360 code almost exclusively uses `b` and `bl`; `ba` / `bla` appear only in kernel / firmware stubs.
- **Target alignment.** `LI` is scaled by 4, so all targets are 4-byte aligned by construction. There is no low-bit encoding of ARM-style Thumb — PPC has one instruction width.
- **LR write is *before* the branch.** In `bl`, `LR` receives `CIA + 4` (the address of the instruction *after* the branch) before execution transfers to the target. Nested calls naturally overwrite LR; callees must spill it ([`mflr`](../control/mfspr.md) + `std`) before making their own `bl`.
- **Indirect tail calls.** A tail call to an indirect target is encoded as `mtctr` + `bctr` (see [`bcctrx`](bcctrx.md)), not `bx``bx` has no register-based form.
- **No condition test.** Use [`bcx`](bcx.md) for conditional displacement branches or [`bclrx`](bclrx.md) / [`bcctrx`](bcctrx.md) for conditional LR/CTR jumps.
- **Speculative execution.** The Xenon fetches past `bx`; translators that mask control flow must treat the target as a single-destination control transfer.
## Related Instructions
- [`bcx`](bcx.md) — conditional displacement branch (B-form, ±32 KiB range).
- [`bclrx`](bclrx.md), [`bcctrx`](bcctrx.md) — branch to LR / CTR, conditional and unconditional.
- [`mtlr`](../control/mtspr.md), [`mflr`](../control/mfspr.md) — LR save/restore for nested `bl` calls.
- [`sc`](sc.md) — system call; an alternative control-flow exit to the kernel.
## Simplified Mnemonics
Assemblers emit `b`, `bl`, `ba`, `bla` for the four runtime combinations. There is no further simplification.
## IBM Reference
- [AIX 7.3 — `b` (Branch)](https://www.ibm.com/docs/en/aix/7.3.0?topic=set-b-branch-instruction)
- [AIX 7.3 — `bl` (Branch with Link, simplified mnemonic)](https://www.ibm.com/docs/en/aix/7.3.0?topic=mnemonics-branch-simplified)