diff --git a/docs/cookbook-index.md b/docs/cookbook-index.md index 2929cbeab6..213b8e91f5 100644 --- a/docs/cookbook-index.md +++ b/docs/cookbook-index.md @@ -2,7 +2,7 @@ > **Generated by `tools/cookbook_index.py` — do not hand-edit** (R33). Regenerate after adding a cookbook section. > -> `docs/matching-cookbook.md` is ~716 KB / 554 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses. +> `docs/matching-cookbook.md` is ~716 KB / 564 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses. **How to use:** name what you SEE in the diff (a stolen delay slot, an extra `la`, a swapped register pair, a `conflicting types` error), find that symptom below, read those sections first. If nothing fits, THEN grind — and add a section when you win. @@ -43,7 +43,7 @@ - **§162** — CROSS-JUMP DIRECTION: the surviving copy is always the LATER one, so a BACKWARD `j` into a sibling arm is a source `goto` (P30 S48) L11263 - **§162** — The cross-jump "CALL veto" is a COUNT law, not a CALL law (BOUNDS §88a; P30 S48, `func_80189540`) L11299 - **§177** — 🔴 THE EPILOGUE RETURN-DELAY SLOT IS DECIDED BY YOUR SAVED-REGISTER SET, NOT BY SCHEDULING L17156 -- **§176-A** — "SCHEDULE / DELAY-SLOT / LENGTH-DRIFT ±1" ⇒ check STATEMENT ORDER around the call first L17306 +- **§176-A** — "SCHEDULE / DELAY-SLOT / LENGTH-DRIFT ±1" ⇒ check STATEMENT ORDER around the call first L17602 ### instruction scheduling (24) @@ -69,10 +69,10 @@ - **§175** — A CALLER-SAVED REGISTER PIN CAN BE A CORRECTNESS BUG, NOT JUST A SCHEDULING CHOICE (P31 wave H, 2026-08-15) L16709 - **§177** — 🔴 THE EPILOGUE RETURN-DELAY SLOT IS DECIDED BY YOUR SAVED-REGISTER SET, NOT BY SCHEDULING L17156 - **§3-B.** — A `return ` IS A PRIORITY-1 HARD-REG SET THE SCHEDULER PLACES FIRST (func_8001BE30, 92 ins) L17230 -- **§176-A** — "SCHEDULE / DELAY-SLOT / LENGTH-DRIFT ±1" ⇒ check STATEMENT ORDER around the call first L17306 -- **§176-C** — 🔴 WALL REFUTATION: a hard-register pin CANNOT schedule around a call, because of a genuine gcc-2.7.2 bug L17370 +- **§176-A** — "SCHEDULE / DELAY-SLOT / LENGTH-DRIFT ±1" ⇒ check STATEMENT ORDER around the call first L17602 +- **§176-C** — 🔴 WALL REFUTATION: a hard-register pin CANNOT schedule around a call, because of a genuine gcc-2.7.2 bug L17666 -### register allocation & pins (48) +### register allocation & pins (51) - **§10** — Closing the regalloc/scheduling hard tail by hand (LZSS, Phase 7 session F — the full close) L835 - **Residual** — A — commutative `|`/`&`/`+` result lands in the wrong source-operand register L856 @@ -119,18 +119,21 @@ - **§175** — A CALLER-SAVED REGISTER PIN CAN BE A CORRECTNESS BUG, NOT JUST A SCHEDULING CHOICE (P31 wave H, 2026-08-15) L16709 - **§176j** — STOPPING A WAVE MID-FLIGHT COSTS THE IN-FLIGHT TAIL (and how much is recoverable) L17093 - **§177** — 🔴 THE EPILOGUE RETURN-DELAY SLOT IS DECIDED BY YOUR SAVED-REGISTER SET, NOT BY SCHEDULING L17156 -- **§176** — SEVEN LEVERS FROM THE P31 OVERNIGHT WAVES (2026-08-15): statement order, false regalloc, and the pin that fights back L17300 -- **§176-B** — "REGALLOC-PERM, 1-4 instructions off" ⇒ it is usually NOT register allocation L17330 -- **§176-C** — 🔴 WALL REFUTATION: a hard-register pin CANNOT schedule around a call, because of a genuine gcc-2.7.2 bug L17370 +- **§179-A** — 🔴 A LOOP-WALKED POINTER **PARAMETER** HANDS ITS ARGUMENT REGISTER TO THE GIV (9 byte-proofs) L17299 +- **§179-F** — PINNING A LOOP-WALKED POINTER IS A TOTAL OFF-SWITCH FOR STRENGTH REDUCTION L17495 +- **§179-G** — 🟡 A PIN CAN **CREATE** A COMBINE `LOG_LINK` AND DELETE AN `andi` (sixth RC-5 channel, n=1) L17518 +- **§176** — SEVEN LEVERS FROM THE P31 OVERNIGHT WAVES (2026-08-15): statement order, false regalloc, and the pin that fights back L17596 +- **§176-B** — "REGALLOC-PERM, 1-4 instructions off" ⇒ it is usually NOT register allocation L17626 +- **§176-C** — 🔴 WALL REFUTATION: a hard-register pin CANNOT schedule around a call, because of a genuine gcc-2.7.2 bug L17666 ### CSE / redundancy / rematerialization (4) - **§46** — The `func_80178D40` crack (890 ins ×134, the heaviest core in the game): four LOOP-STRUCTURE levers cheap-Opus found by reading loop.c/jump.c/cse.c (Phase 26 session 8, 2026-07-13) L3313 - **§83d** — CSE's quantity budget is WHOLE-FUNCTION, so a local rewrite cannot fix a local symptom L6452 - **§153** — THE ADDRESS-REMATERIALISATION LAUNDER: a third zero-emission asm lever (P30 S43, `func_8018D98C`, 710 ins) L10463 -- **§176-D** — CSE-class levers used in reverse (two sharpenings of §153 and cse_expr §2) L17396 +- **§176-D** — CSE-class levers used in reverse (two sharpenings of §153 and cse_expr §2) L17692 -### loops & induction variables (10) +### loops & induction variables (13) - **§3-T1** — Loop pointer: top-of-body for `addu` induction, not constant-folded `addiu` L71 - **§34** — The `func_80138ED0` giant crack: gcc-2.7.2's **3-qty sort bug** + the **zero-byte asm allocation toolkit** + the **giv-init fence** (Phase 24 T5; Opus→close=21, Fable5→MATCH ×134) L2454 @@ -142,8 +145,11 @@ - **§145** — Three loop/combine levers from the S40 wave-2 drafters (16/16 match_one) L9924 - **§148** — The loop.c hoisting THRESHOLD is arithmetic you can compute, and the `?:` clamp that folds to MIN_EXPR (P30 S42, `func_8017C6F4`, 947 ins) L10142 - **§171a** — THE MECHANICAL A-PROP DRAFT (P30 S50): 256 members banked with no agent in the loop L16417 +- **§179-A** — 🔴 A LOOP-WALKED POINTER **PARAMETER** HANDS ITS ARGUMENT REGISTER TO THE GIV (9 byte-proofs) L17299 +- **§179-E** — A `>2*MAX_MOVE_BYTES` BLOCK COPY IS A **STRUCT ASSIGNMENT**, NOT A HAND LOOP L17469 +- **§179-F** — PINNING A LOOP-WALKED POINTER IS A TOTAL OFF-SWITCH FOR STRENGTH REDUCTION L17495 -### structs, block moves & memcpy (38) +### structs, block moves & memcpy (39) - **§3-T2** — Source statement order drives instruction scheduling L78 - **§5** — Known hard-residual classes (instruction-identical, one byte-exact blocker) L199 @@ -182,7 +188,8 @@ - **§3-The** — ADDRESS-CLASS TABLE: which load/store pairs even REACH the `/s` clause (P30 S48 wave 4, `func_80185B44`, ov_SC03_014) L14339 - **§176g** — SIZE A WAVE BY INSTRUCTIONS, NOT BY CARDS (P31 S52 — the adopted doctrine) L16927 - **§3-F.** — `MEM_IN_STRUCT_P` ASYMMETRY IN `true_dependence` (func_80037144, 124 ins) L17267 -- **§176-B** — "REGALLOC-PERM, 1-4 instructions off" ⇒ it is usually NOT register allocation L17330 +- **§179-E** — A `>2*MAX_MOVE_BYTES` BLOCK COPY IS A **STRUCT ASSIGNMENT**, NOT A HAND LOOP L17469 +- **§176-B** — "REGALLOC-PERM, 1-4 instructions off" ⇒ it is usually NOT register allocation L17626 ### types, signedness & load/store width (36) @@ -284,7 +291,7 @@ - **§168** — THE COUSIN TIER (P30 S49, 2026-08-12): h_seq's exact-hash brittleness, measured — and the similarity map above it L16208 - **§176f** — THE DECLARATION FORM IS A MATCHING LEVER, SO RECONCILE TOWARD THE FORM THE MATCH NEEDS (P31 S52) L16896 -### jump tables & switches (27) +### jump tables & switches (28) - **§8** — rodata island (compiler jump tables) — the `.data→.rodata→.data` sandwich (Phase 7) L320 - **§8a** — rodata island in a flat OVERLAY — the tail sandwich, per matched jr-function (Phase 26 — PoC PROVEN) L342 @@ -313,6 +320,7 @@ - **§132b** — When the span's already-matched owner is ITSELF multi-switch: `--span-rel` (P30 S1, `func_8014032C`) L8660 - **§139** — A GATE THAT GREPS FOR VERDICTS MUST ASSERT 1:1 ACCOUNTING; and a `--src` filter must not survive a carve (P30 S38, wave 6: 10 of 16 drafts vanished) L9591 - **§161** — THE RETRY-WAVE HARVEST: a jump table indexed from zero, and two allocator traps (P30 S47) L10966 +- **§179-F** — PINNING A LOOP-WALKED POINTER IS A TOTAL OFF-SWITCH FOR STRENGTH REDUCTION L17495 ### optimisation level (-O0/-O2) (12) @@ -463,7 +471,7 @@ - **§173** — THE STORED-PLUMBING RECOVERY RECIPE (P31 T6): symfix-first, per-group isolation, and where the verdicts have no drafts L16603 - **§176d** — THE CONFLICT TABLE MUST BE SEEDED FROM THE TU, AND KEYED PER FILE (P31 S52, 2026-08-15) L16800 -### build graph, splat & the harness (115) +### build graph, splat & the harness (117) - **§4** — Flag/toolchain gotchas L190 - **Build** — mechanism — per-file opt override (splat resegmentation) L288 @@ -579,7 +587,9 @@ - **§3-C2.** — RECONCILE BEFORE THE FIRST GATE — a parked draft gets HARDER to bank, not easier L17020 - **§3-D.** — The measured cost shape, and what to build next L17043 - **§176i** — WHAT A STATIC PRE-GATE CHECK CAN AND CANNOT PROVE (P31 S52, wave Q) L17061 -- **§176c** — MAIN (SLUS_007.26) CANNOT BE GATED INCREMENTALLY L17289 +- **§179** — IDIOMS MINED FROM THE WAVE P/Q JOURNALS (P31 S52, harvest pass) L17289 +- **§179-G** — 🟡 A PIN CAN **CREATE** A COMBINE `LOG_LINK` AND DELETE AN `andi` (sixth RC-5 channel, n=1) L17518 +- **§176c** — MAIN (SLUS_007.26) CANNOT BE GATED INCREMENTALLY L17585 ### process, measurement & doctrine (79) @@ -660,10 +670,10 @@ - **§176h** — THE BATCH-SUBSTITUTION HAZARD MAP (P31 S52): seven holes, three wrong fixes, one law L16965 - **§3-D.** — The measured cost shape, and what to build next L17043 - **§176j-2** — THE REPAIR PASS, MEASURED (do this instead of resuming) L17119 -- **§176-C** — 🔴 WALL REFUTATION: a hard-register pin CANNOT schedule around a call, because of a genuine gcc-2.7.2 bug L17370 -- **§176-E** — Two cheap source spellings, both cc1-probed L17422 +- **§176-C** — 🔴 WALL REFUTATION: a hard-register pin CANNOT schedule around a call, because of a genuine gcc-2.7.2 bug L17666 +- **§176-E** — Two cheap source spellings, both cc1-probed L17718 -### (unbucketed — title matched no symptom vocabulary) (183) +### (unbucketed — title matched no symptom vocabulary) (188) - **§3-How** — to use this L30 - **§1** — Idiom catalog (asm pattern → C that produces it) L39 @@ -846,8 +856,13 @@ - **§3-A.** — THE `$0`-ADD OPAQUE COPY defeats `make_regs_eqv` (func_80033398, 93 ins) L17214 - **§3-C.** — SINGLE-SET TEMPS GET THE BIRTHING BOOST (func_8001D3FC, 196 ins) L17243 - **§3-E.** — THE ZERO-OFFSET ALIAS HOLE (func_80037028, 71 ins) L17258 -- **§176-F** — Misdiagnosis triage: four residual verdicts that were lying L17444 -- **What** — is NOT banked here L17461 +- **§179-B** — 🔴 THE HAND-WRITTEN-ASM TRANSCRIPTION CHECKLIST (maspsx + masked_diff; 10 byte-proofs) L17348 +- **§179-C** — 🔴 A FUNCTION WITH NO EPILOGUE (falls into a sibling's shared tail) MUST BE FILE-SCOPE `__asm__` L17398 +- **§179-D** — `gte_stflg` MUST CLOBBER `"$12"` OR THE WHOLE TEMP FILE ROTATES BY ONE L17449 +- **§179-H** — A MID-BODY `.global LABEL` PAIR SLICES A BYTE-COMPARABLE FRAGMENT OUT OF A LARGER ROUTINE L17545 +- **Considered** — and NOT banked L17568 +- **§176-F** — Misdiagnosis triage: four residual verdicts that were lying L17740 +- **What** — is NOT banked here L17757 ## All sections, in order @@ -1397,12 +1412,22 @@ - **§3-E.** — THE ZERO-OFFSET ALIAS HOLE (func_80037028, 71 ins) L17258 - **§3-F.** — `MEM_IN_STRUCT_P` ASYMMETRY IN `true_dependence` (func_80037144, 124 ins) L17267 - **§3-G.** — TWO MODELLING TRAPS THAT COST THESE AGENTS SWEEPS OF HUNDREDS OF COMPILES L17273 -- **§176c** — MAIN (SLUS_007.26) CANNOT BE GATED INCREMENTALLY L17289 -- **§176** — SEVEN LEVERS FROM THE P31 OVERNIGHT WAVES (2026-08-15): statement order, false regalloc, and the pin that fights back L17300 -- **§176-A** — "SCHEDULE / DELAY-SLOT / LENGTH-DRIFT ±1" ⇒ check STATEMENT ORDER around the call first L17306 -- **§176-B** — "REGALLOC-PERM, 1-4 instructions off" ⇒ it is usually NOT register allocation L17330 -- **§176-C** — 🔴 WALL REFUTATION: a hard-register pin CANNOT schedule around a call, because of a genuine gcc-2.7.2 bug L17370 -- **§176-D** — CSE-class levers used in reverse (two sharpenings of §153 and cse_expr §2) L17396 -- **§176-E** — Two cheap source spellings, both cc1-probed L17422 -- **§176-F** — Misdiagnosis triage: four residual verdicts that were lying L17444 -- **What** — is NOT banked here L17461 +- **§179** — IDIOMS MINED FROM THE WAVE P/Q JOURNALS (P31 S52, harvest pass) L17289 +- **§179-A** — 🔴 A LOOP-WALKED POINTER **PARAMETER** HANDS ITS ARGUMENT REGISTER TO THE GIV (9 byte-proofs) L17299 +- **§179-B** — 🔴 THE HAND-WRITTEN-ASM TRANSCRIPTION CHECKLIST (maspsx + masked_diff; 10 byte-proofs) L17348 +- **§179-C** — 🔴 A FUNCTION WITH NO EPILOGUE (falls into a sibling's shared tail) MUST BE FILE-SCOPE `__asm__` L17398 +- **§179-D** — `gte_stflg` MUST CLOBBER `"$12"` OR THE WHOLE TEMP FILE ROTATES BY ONE L17449 +- **§179-E** — A `>2*MAX_MOVE_BYTES` BLOCK COPY IS A **STRUCT ASSIGNMENT**, NOT A HAND LOOP L17469 +- **§179-F** — PINNING A LOOP-WALKED POINTER IS A TOTAL OFF-SWITCH FOR STRENGTH REDUCTION L17495 +- **§179-G** — 🟡 A PIN CAN **CREATE** A COMBINE `LOG_LINK` AND DELETE AN `andi` (sixth RC-5 channel, n=1) L17518 +- **§179-H** — A MID-BODY `.global LABEL` PAIR SLICES A BYTE-COMPARABLE FRAGMENT OUT OF A LARGER ROUTINE L17545 +- **Considered** — and NOT banked L17568 +- **§176c** — MAIN (SLUS_007.26) CANNOT BE GATED INCREMENTALLY L17585 +- **§176** — SEVEN LEVERS FROM THE P31 OVERNIGHT WAVES (2026-08-15): statement order, false regalloc, and the pin that fights back L17596 +- **§176-A** — "SCHEDULE / DELAY-SLOT / LENGTH-DRIFT ±1" ⇒ check STATEMENT ORDER around the call first L17602 +- **§176-B** — "REGALLOC-PERM, 1-4 instructions off" ⇒ it is usually NOT register allocation L17626 +- **§176-C** — 🔴 WALL REFUTATION: a hard-register pin CANNOT schedule around a call, because of a genuine gcc-2.7.2 bug L17666 +- **§176-D** — CSE-class levers used in reverse (two sharpenings of §153 and cse_expr §2) L17692 +- **§176-E** — Two cheap source spellings, both cc1-probed L17718 +- **§176-F** — Misdiagnosis triage: four residual verdicts that were lying L17740 +- **What** — is NOT banked here L17757 diff --git a/docs/matching-cookbook.md b/docs/matching-cookbook.md index 44778c5f6a..9ce099021f 100644 --- a/docs/matching-cookbook.md +++ b/docs/matching-cookbook.md @@ -17286,6 +17286,302 @@ scheduling decision, not cosmetics. fully DAG-determined. When order does not matter, the answer is an *alias* or a *set-count* property, not a permutation. +## §179 — IDIOMS MINED FROM THE WAVE P/Q JOURNALS (P31 S52, harvest pass) + +Twelve readers mined the wave-P and wave-Q agent journals; 16 candidate findings survived their +novelty filter, and merging duplicates + dropping what §174–§178 already own leaves the **eight +levers below**. Every gcc/tool citation here was re-read against `tools/reference/gcc-2.7.2/`, +`tools/maspsx/`, and `tools/masked_diff.py` in this pass — three line numbers were wrong in the raw +findings and are corrected inline (marked ⚠). Ordered by how many functions each unblocks. + +--- + +### §179-A — 🔴 A LOOP-WALKED POINTER **PARAMETER** HANDS ITS ARGUMENT REGISTER TO THE GIV (9 byte-proofs) + +**Symptom.** A NEAR whose only residual is a register rotation around a pointer loop: the draft has +a spurious `move $tN,$aM` that the target does not, the offset-K access lands on the *argument* +register `$aM`, and the base cursor lands on a scratch temp — the exact mirror image of the target's +allocation. `cc1 -dg` shows the argument register in the conflict set of the cursor pseudo +(`N conflicts: … 7`, `M preferences: 7` for the `$a3` cases). + +**Mechanism** (all lines re-read and confirmed). When a pointer **parameter** is used undecorated as +a loop's biv *and* the loop also touches a fixed offset off that same pointer (so gcc mints a giv), +`record_initial` (`loop.c:6327`) records the biv's defining insn — which is `assign_parms`' own +incoming-argument copy `(set P (reg $aN))` — as `bl->init_set`. At `loop.c:3500` `src = +SET_SRC (bl->init_set)` is therefore the **hard register** itself; `valid_initial_value_p` +(`loop.c:4120`, called at `loop.c:3509`) accepts it, since it returns 1 for `CONSTANT_P` or any +`GET_CODE == REG` (hard regs pass its `REGNO < max_reg_before_loop` test), given no intervening +call. `bl->initial_value = src` (`loop.c:3511`). Then `emit_iv_add_mult (bl->initial_value, …, +loop_start)` (`loop.c:3879`) emits the giv's preheader init as `new_giv = $aN + K` — **a fresh +reference to the hard register, inserted after P's own copy-from-`$aN`**. That extends `$aN`'s live +range past where P's copy would have let it die, `$aN` and P become simultaneously live, P loses the +hard-reg tie, the giv inherits `$aN`, and the dead `move` survives. + +**C lever — two spellings, both zero-byte, pick either:** +```c +/* 1. body-local copy: rename the parameter, route EVERY in-loop access through the copy */ +void f(T *param0, …) { T *p = param0; for (…) { … p->fld … p++; } } + +/* 2. identity re-tie, placed in the preheader BELOW the n!=0 guard so it can't eat the + guard branch's delay slot */ +if (n) { __asm__("" : "=r"(p) : "0"(p)); do { … } while (--n); } +``` +Spelling 2 works by the *defeat* route: the init insn's `SET_SRC` becomes an `ASM_OPERANDS` rtx, +which is neither `CONSTANT_P` nor `GET_CODE == REG`, so `valid_initial_value_p` returns 0, +`bl->initial_value` falls back to the freely-allocatable pseudo, and `$aN` is released. + +**Evidence (all MATCH).** `func_800262D8` (144→143, dead `move t1,a3` removed), `func_8002528C`, +`func_80025000` (164/154-wrong → 163/4-wrong from this lever alone), `GsTMDfastF3GL`, +`func_80025EB8`, `func_80025A30` (re-tie spelling), `func_80025504` (197 ins, poly pointer vs `$a3`), +`func_80024DE8` (134/134, `-dg` confirmed the `$a3` conflict), `func_80025818`. + +**Relationship to §70 (L5639) — read this before applying.** §70 documents the *same* chain used in +the **opposite direction**: when the target wants the giv based on the argument register, walk the +parameter directly and do **not** copy it. §179-A is the mirror. Decide by what the target's giv is +based on, then choose: raw parameter (§70) vs. local copy / re-tie (§179-A). +*Honest limit:* why a second-level copy does not simply recreate the identical chain one level +removed was not re-derived from `assign_parms`' pseudo lowering; it rests on the source-verified +general mechanism plus nine consistent byte-proofs. + +--- + +### §179-B — 🔴 THE HAND-WRITTEN-ASM TRANSCRIPTION CHECKLIST (maspsx + masked_diff; 10 byte-proofs) + +**Symptom.** A splat-flagged handwritten / PsyQ LIBGS routine transcribed as inline asm comes out ++N instructions (LENGTH-DRIFT), or the build dies with `MASPSX FAIL: invalid literal for int() with +base 10: '0x18'`, or `masked_diff` reports a huge mismatch on a body you copied verbatim. + +**Five rules, each source-verified, each a byte-miss or a crash if violated:** + +1. **`.set` directives need a literal TAB.** `maspsx/__init__.py:844-848` is + `elif line.startswith(".set\t"): if line.endswith("\tnoreorder"): self.is_reorder = False; elif + line.endswith("\treorder"): self.is_reorder = True`. A space-separated `.set noreorder` matches + neither test, is forwarded to `as` unchanged, and leaves maspsx's tracker at its default `True` — + after which it auto-appends `nop # DEBUG: branch/jump` after **every** branch/jump it emits + (`:1054-1057`, gated on `is_reorder`), clobbering your hand-filled delay slots. Write + `".set\tnoreorder\n"`. +2. **`.ent` does NOT update maspsx's state.** `:856-859` appends `.set\tnoreorder` to the *output* + stream but never touches `self.is_reorder`. Never rely on it; write your own tab-formed directive. +3. **Every displacement and immediate in DECIMAL.** `:970` and `:1038` both call bare `int(operand)` + (base-10 default) on the raw offset string *before* the magnitude comparison short-circuits, so + `lw $2,0x18($3)` throws `ValueError` regardless of range. Write `lw $2,24($3)`. (`.word` + constants are unaffected and may stay hex.) +4. **maspsx's LOAD-delay nop is UNCONDITIONAL — do not write it yourself.** + `_handle_nop_before_next_instruction` (`:642-675`, called from `:908,931,964,991,1137,1181`) + contains **no** `is_reorder` reference anywhere in its body or call sites — unlike the + branch-delay path, which is explicitly gated. So even inside `.set\tnoreorder`, a `lw $v0,56($t1)` + followed by a consumer of `$v0` still gets maspsx's own nop spliced in. This is the asymmetry + that bites: **you manage branch-delay nops yourself; you must NOT manage load-delay nops.** +5. **Prefix internal labels with `.L`.** `masked_diff.py:34` is + `_HDR_RE = re.compile(r"^[0-9a-f]+ <([^>]+)>:")`, and `insns_from_object`'s collection loop + (`:141-146`) sets `infn = (fn is None) or (h.group(1) == fn)` on **every** objdump `