mirror of
https://github.com/Ed94/pikuma_ps1.git
synced 2026-07-30 19:30:09 +00:00
mabye one day
This commit is contained in:
+52
-14
@@ -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
@@ -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") \
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user