mabye one day

This commit is contained in:
ed
2026-06-01 22:01:22 -04:00
parent 690d184acf
commit d776d71574
2 changed files with 81 additions and 38 deletions
+52 -14
View File
@@ -298,20 +298,58 @@
#define asm_clobber(...) : __VA_ARGS__
/* `asm_inline(...)` dispatches into `_INL_<count>` to emit up to 99 encoded
* instruction words. This is the "compiled-instruction" form of `asm_code`. */
* instruction words. This is the "compiled-instruction" form of `asm_code`.
*
* Result is a 3-colon statement body WITHOUT the final clobber section:
* ".word %c0, %c1, ..." : : "i"(p0), "i"(p1)
* |----- code -----| |--- empty ---| |------- inputs -------|
*
* Append `: clobbers` after it and wrap in `asm volatile (...)`. */
#define asm_inline(...) m_expand(glue(_INL_, _ASM_COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__))
/* `asm_blob(inlines, clobbers)` — the original 2-section shell. Emits
* `asm volatile ( inlines clobbers )`
* which is the `.word`-only shape (no inputs/outputs): the inlines expand
* to `".word %c0, ..." : : "i"(...)` already including the empty output
* and input sections via their trailing `:`, so clobbers just tacks on the
* end. */
// #define asm_blob(inlines, clobbers) asm volatile ( inlines clobbers )
// Not a fan rather just do asm volatile ( ... )
/* ============================================================================
* SECTION-STRIP HELPER — let users wrap multi-token sections in `(...)` so
* the preprocessor treats them as a single argument.
* ============================================================================
*
* Without paren-stripping, calling
* asm_block_4(asm_inline(w0, w1), , "r"(p), "$2", "$8")
* would tokenize the last `clb` as TWO args (`"$2"` and `"$8"`) because
* the preprocessor counts top-level commas. The parens `("$2", "$8")`
* shield the comma, so the preprocessor sees ONE arg — but those parens
* would then survive into the C source as a syntax error.
*
* The trick:
* _strip((a, b, c)) -> _strip_IMPL (a, b, c) -> _strip_IMPL a, b, c
* (function-call syntax!)
* -> a, b, c
*
* The outer call is on `a, b, c` (which is fine as macro args), and the
* variadic capture `__VA_ARGS__` then re-emits the comma-separated list. */
#define _strip(x) _strip_IMPL x
#define _strip_IMPL(...) __VA_ARGS__
/* `asm_block(code, outs, ins, clb)` — the full 4-section shell. Each
* argument is expected to already include its own leading `:` (via the
* `asm_out` / `asm_in` / `asm_clb` builders) or be empty. The `code`
* argument should NOT have a leading `:`. */
#define asm_block(code, outs, ins, clb) asm volatile ( code outs ins clb )
/* ============================================================================
* asm_block_4(code, outs, ins, clb) — the assembler for the 4-section form
* ============================================================================
*
* You pass 4 section BODIES (no colons). To allow multi-token sections, wrap
* them in `(...)` — the parens shield internal commas from the preprocessor
* and are stripped by the `_strip` helper.
*
* asm_block_4(
* (asm_inline(w0, w1)), // code body — parens protect inner commas
* (), // empty outputs
* ("r"(p)), // inputs body
* ("$2", "$8", "memory") // clobbers body
* )
*
* Expands to:
* asm volatile( asm_inline(w0, w1) : : "r"(p) : "$2", "$8", "memory" )
* |-- 3 colons inserted here --|
*
* If a section is a single token (no internal commas), you can omit the
* parens: `asm_block_4("...", , "r"(p), "$2")`.
*/
#define asm_block_4(code, outs, ins, clb) \
asm volatile( _strip(code) : _strip(outs) : _strip(ins) : _strip(clb) )
+29 -24
View File
@@ -207,45 +207,50 @@ enum { _C2_OPS_ = 0
* hardwired form the "placeholder-pun" — GCC is forced to bind r_ptr to
* $12, which is exactly the register the .word constants expect.
*
* Uses asm_volatile_4(code, outs, ins, clb) from gcc_asm.h.
* Uses asm_block_4(code, outs, ins, clb) from gcc_asm.h.
* asm_inline(...) produces the 2-colon code:outputs:inputs body
* "r"(r_ptr) is the runtime-input section body
* "$2", ..., "$12" is the clobber section body
* asm_volatile_4() joins them with 3 colons and wraps in asm volatile
* asm_block_4() joins them with 3 colons and wraps in asm volatile
*
* The parens `(...)` around each section let the preprocessor treat the
* section's contents as a single arg (shielding internal commas), and
* the `_strip` helper inside asm_block_4 removes those parens so the
* final C code is clean.
*/
#define gte_load_v0(r_ptr) \
asm_volatile_4( \
(asm_inline( gte_lwc2_v0_RT4, gte_lwc2_v0z_RT4 )), \
(), \
("r"(r_ptr)), \
("$2", "$8", "$9", "$31", "memory", "$12") \
asm_block_4( \
(asm_inline( gte_lwc2_v0_RT4, gte_lwc2_v0z_RT4 )), \
(), \
("r"(r_ptr)), \
("$2", "$8", "$9", "$31", "memory", "$12") \
)
#define gte_load_v1(r_ptr) \
asm_volatile_4( \
(asm_inline( gte_lwc2_v1_RT4, gte_lwc2_v1z_RT4 )), \
(), \
("r"(r_ptr)), \
("$2", "$8", "$9", "$31", "memory", "$12") \
asm_block_4( \
(asm_inline( gte_lwc2_v1_RT4, gte_lwc2_v1z_RT4 )), \
(), \
("r"(r_ptr)), \
("$2", "$8", "$9", "$31", "memory", "$12") \
)
#define gte_load_v2(r_ptr) \
asm_volatile_4( \
(asm_inline( gte_lwc2_v2_RT4, gte_lwc2_v2z_RT4 )), \
(), \
("r"(r_ptr)), \
("$2", "$8", "$9", "$31", "memory", "$12") \
asm_block_4( \
(asm_inline( gte_lwc2_v2_RT4, gte_lwc2_v2z_RT4 )), \
(), \
("r"(r_ptr)), \
("$2", "$8", "$9", "$31", "memory", "$12") \
)
/* All three at once -- the canonical prelude to gte_cmd_rtpt. */
#define gte_load_v0v1v2(r_ptr) \
asm_volatile_4( \
(asm_inline( gte_lwc2_v0_RT4, gte_lwc2_v0z_RT4, \
gte_lwc2_v1_RT4, gte_lwc2_v1z_RT4, \
gte_lwc2_v2_RT4, gte_lwc2_v2z_RT4 )), \
(), \
("r"(r_ptr)), \
("$2", "$8", "$9", "$31", "memory", "$12") \
asm_block_4( \
(asm_inline( gte_lwc2_v0_RT4, gte_lwc2_v0z_RT4, \
gte_lwc2_v1_RT4, gte_lwc2_v1z_RT4, \
gte_lwc2_v2_RT4, gte_lwc2_v2z_RT4 )), \
(), \
("r"(r_ptr)), \
("$2", "$8", "$9", "$31", "memory", "$12") \
)
/**