""" Canonical bit layout per PPC instruction form. Tables derived from xenia-canary/src/xenia/cpu/ppc/ppc_instr.h (struct PPCOpcodeBits union). In PPC notation bit 0 is the MSB of the 32-bit word (big-endian bit numbering). Each entry is a list of (bit_start, bit_end_inclusive, field_name, notes) tuples laid out from MSB (bit 0) to LSB (bit 31). """ # NOTE: bit ranges use PPC big-endian numbering (0 = MSB, 31 = LSB). FORM_LAYOUTS: dict[str, list[tuple[int, int, str, str]]] = { "I": [ (0, 5, "OPCD", "primary opcode"), (6, 29, "LI", "signed 24-bit word-offset target"), (30, 30, "AA", "absolute-address flag"), (31, 31, "LK", "link flag (bl/ba/bla)"), ], "B": [ (0, 5, "OPCD", "primary opcode"), (6, 10, "BO", "branch options"), (11, 15, "BI", "CR bit to test"), (16, 29, "BD", "signed 14-bit word-offset target"), (30, 30, "AA", "absolute-address flag"), (31, 31, "LK", "link flag"), ], "SC": [ (0, 5, "OPCD", "primary opcode (17)"), (6, 19, "—", "reserved"), (20, 26, "LEV", "exception level"), (27, 29, "—", "reserved"), (30, 30, "1", "fixed 1"), (31, 31, "—", "reserved"), ], "D": [ (0, 5, "OPCD", "primary opcode"), (6, 10, "RT", "destination GPR (or RS when storing)"), (11, 15, "RA", "source GPR (0 ⇒ literal 0 for RA0 forms)"), (16, 31, "D/SI/UI", "16-bit signed or unsigned immediate"), ], "DS": [ (0, 5, "OPCD", "primary opcode"), (6, 10, "RT", "destination GPR (or RS)"), (11, 15, "RA", "source GPR (0 ⇒ literal 0)"), (16, 29, "DS", "14-bit signed word-scaled displacement"), (30, 31, "XO", "extended opcode"), ], "X": [ (0, 5, "OPCD", "primary opcode"), (6, 10, "RT/FRT/VRT", "destination"), (11, 15, "RA/FRA/VRA", "source A"), (16, 20, "RB/FRB/VRB", "source B"), (21, 30, "XO", "extended opcode (10 bits)"), (31, 31, "Rc", "record-form flag"), ], "XL": [ (0, 5, "OPCD", "primary opcode (19)"), (6, 10, "BT/BO", "target / branch options"), (11, 15, "BA/BI", "source A / CR bit to test"), (16, 20, "BB", "source B"), (21, 30, "XO", "extended opcode (10 bits)"), (31, 31, "LK", "link flag"), ], "XFX": [ (0, 5, "OPCD", "primary opcode (31)"), (6, 10, "RT", "destination / source GPR"), (11, 20, "spr/tbr/FXM", "SPR/TBR number (byte-swapped halves) or CR field mask"), (21, 30, "XO", "extended opcode"), (31, 31, "—", "reserved"), ], "XFL": [ (0, 5, "OPCD", "primary opcode (63)"), (6, 6, "L", "field-select behaviour"), (7, 14, "FM", "FPSCR field mask"), (15, 15, "W", "immediate-value flag"), (16, 20, "FRB", "source FPR"), (21, 30, "XO", "extended opcode"), (31, 31, "Rc", "record-form flag (updates CR1)"), ], "XS": [ (0, 5, "OPCD", "primary opcode (31)"), (6, 10, "RS", "source GPR"), (11, 15, "RA", "destination GPR"), (16, 20, "sh", "shift amount low 5 bits"), (21, 29, "XO", "extended opcode (9 bits)"), (30, 30, "sh5", "shift amount high bit"), (31, 31, "Rc", "record-form flag"), ], "XO": [ (0, 5, "OPCD", "primary opcode (31)"), (6, 10, "RT", "destination GPR"), (11, 15, "RA", "source A"), (16, 20, "RB", "source B"), (21, 21, "OE", "overflow-enable flag"), (22, 30, "XO", "extended opcode (9 bits)"), (31, 31, "Rc", "record-form flag"), ], "A": [ (0, 5, "OPCD", "primary opcode (59 or 63)"), (6, 10, "FRT", "destination FPR"), (11, 15, "FRA", "source A FPR"), (16, 20, "FRB", "source B FPR"), (21, 25, "FRC", "source C FPR (multiplier for madd-style ops)"), (26, 30, "XO", "extended opcode (5 bits)"), (31, 31, "Rc", "record-form flag (updates CR1)"), ], "M": [ (0, 5, "OPCD", "primary opcode"), (6, 10, "RS", "source GPR"), (11, 15, "RA", "destination GPR"), (16, 20, "SH/RB", "shift amount or source B"), (21, 25, "MB", "mask begin"), (26, 30, "ME", "mask end"), (31, 31, "Rc", "record-form flag"), ], "MD": [ (0, 5, "OPCD", "primary opcode (30)"), (6, 10, "RS", "source GPR"), (11, 15, "RA", "destination GPR"), (16, 20, "sh", "shift amount low 5 bits"), (21, 26, "mb/me", "6-bit mask field (swapped halves)"), (27, 29, "XO", "extended opcode"), (30, 30, "sh5", "shift amount high bit"), (31, 31, "Rc", "record-form flag"), ], "MDS": [ (0, 5, "OPCD", "primary opcode (30)"), (6, 10, "RS", "source GPR"), (11, 15, "RA", "destination GPR"), (16, 20, "RB", "source B GPR"), (21, 26, "mb/me", "6-bit mask field (swapped halves)"), (27, 30, "XO", "extended opcode"), (31, 31, "Rc", "record-form flag"), ], "DCBZ": [ (0, 5, "OPCD", "primary opcode (31)"), (6, 10, "—", "reserved"), (11, 15, "RA", "base register (0 ⇒ literal 0)"), (16, 20, "RB", "offset register"), (21, 30, "XO", "extended opcode (1014 for dcbz / 1010 for dcbz128)"), (31, 31, "—", "reserved"), ], "VX": [ (0, 5, "OPCD", "primary opcode (4)"), (6, 10, "VRT/VD", "destination vector register"), (11, 15, "VRA/VA", "source A vector register"), (16, 20, "VRB/VB", "source B vector register"), (21, 31, "XO", "extended opcode (11 bits)"), ], "VA": [ (0, 5, "OPCD", "primary opcode (4)"), (6, 10, "VRT", "destination vector register"), (11, 15, "VRA", "source A"), (16, 20, "VRB", "source B"), (21, 25, "VRC", "source C / shift"), (26, 31, "XO", "extended opcode (6 bits)"), ], "VC": [ (0, 5, "OPCD", "primary opcode (4)"), (6, 10, "VRT", "destination vector register"), (11, 15, "VRA", "source A"), (16, 20, "VRB", "source B"), (21, 21, "Rc", "record-form flag (updates CR6)"), (22, 31, "XO", "extended opcode (10 bits)"), ], "VX128": [ (0, 5, "OPCD", "primary opcode (4 or 5)"), (6, 10, "VD128l", "destination low 5 bits"), (11, 15, "VA128l", "source A low 5 bits"), (16, 20, "VB128l", "source B low 5 bits"), (21, 21, "VA128H", "source A high bit"), (22, 22, "—", "reserved"), (23, 25, "VC", "optional VC / XO sub-field"), (26, 26, "VA128h", "source A middle bit"), (27, 27, "—", "reserved"), (28, 29, "VD128h", "destination high 2 bits"), (30, 31, "VB128h", "source B high 2 bits"), ], "VX128_1": [ (0, 5, "OPCD", "primary opcode (4)"), (6, 10, "VD128l", "destination low 5 bits"), (11, 15, "RA", "address register"), (16, 20, "RB", "offset register"), (21, 27, "XO", "extended opcode"), (28, 29, "VD128h", "destination high 2 bits"), (30, 31, "—", "reserved"), ], "VX128_2": [ (0, 5, "OPCD", "primary opcode (5)"), (6, 10, "VD128l", "destination low 5 bits"), (11, 15, "VA128l", "source A low 5 bits"), (16, 20, "VB128l", "source B low 5 bits"), (21, 21, "VA128H", "source A high bit"), (23, 25, "VC", "source C 3-bit field"), (26, 26, "VA128h", "source A middle bit"), (28, 29, "VD128h", "destination high 2 bits"), (30, 31, "VB128h", "source B high 2 bits"), ], "VX128_3": [ (0, 5, "OPCD", "primary opcode (6)"), (6, 10, "VD128l", "destination low 5 bits"), (11, 15, "IMM", "5-bit immediate"), (16, 20, "VB128l", "source B low 5 bits"), (21, 27, "XO", "extended opcode"), (28, 29, "VD128h", "destination high 2 bits"), (30, 31, "VB128h", "source B high 2 bits"), ], "VX128_4": [ (0, 5, "OPCD", "primary opcode (6)"), (6, 10, "VD128l", "destination low 5 bits"), (11, 15, "IMM", "5-bit immediate"), (16, 20, "VB128l", "source B low 5 bits"), (21, 23, "XO", "extended opcode"), (24, 25, "z", "sub-operation selector"), (28, 29, "VD128h", "destination high 2 bits"), (30, 31, "VB128h", "source B high 2 bits"), ], "VX128_5": [ (0, 5, "OPCD", "primary opcode (4)"), (6, 10, "VD128l", "destination low 5 bits"), (11, 15, "VA128l", "source A low 5 bits"), (16, 20, "VB128l", "source B low 5 bits"), (21, 21, "VA128H", "source A high bit"), (22, 25, "SH", "4-bit shift amount"), (26, 26, "VA128h", "source A middle bit"), (28, 29, "VD128h", "destination high 2 bits"), (30, 31, "VB128h", "source B high 2 bits"), ], "VX128_P": [ (0, 5, "OPCD", "primary opcode (6)"), (6, 10, "VD128l", "destination low 5 bits"), (11, 15, "PERMl", "permute selector low 5 bits"), (16, 20, "VB128l", "source B low 5 bits"), (21, 22, "—", "reserved"), (23, 25, "PERMh", "permute selector high 3 bits"), (28, 29, "VD128h", "destination high 2 bits"), (30, 31, "VB128h", "source B high 2 bits"), ], "VX128_R": [ (0, 5, "OPCD", "primary opcode (4)"), (6, 10, "VD128l", "destination low 5 bits"), (11, 15, "VA128l", "source A low 5 bits"), (16, 20, "VB128l", "source B low 5 bits"), (21, 21, "VA128H", "source A high bit"), (22, 25, "XO", "extended opcode (compare)"), (26, 26, "VA128h", "source A middle bit"), (27, 27, "Rc", "record-form flag (updates CR6)"), (28, 29, "VD128h", "destination high 2 bits"), (30, 31, "VB128h", "source B high 2 bits"), ], } def render_bit_table(form: str) -> str: """Return a markdown table of the form's bit layout.""" layout = FORM_LAYOUTS.get(form) if not layout: return f"_Unknown form_ `{form}` _— see `forms/` for details._" rows = ["| Bits | Field | Meaning |", "| --- | --- | --- |"] for start, end, name, notes in layout: span = f"{start}" if start == end else f"{start}–{end}" rows.append(f"| {span} | `{name}` | {notes} |") return "\n".join(rows)