4 Commits
7 changed files with 765 additions and 515 deletions
+5 -1
View File
@@ -33,6 +33,7 @@
#define align_(value) __attribute__((aligned (value))) // for easy alignment
#define C_(type,data) ((type)(data)) // for enforced precedence
#define expect_(x, y) __builtin_expect(x, y) // so compiler knows the common path
#define cexpr_ __builtin_constant_p
#define I_ internal inline
#define FI_ inline __attribute__((always_inline)) // inline always
#define NI_ internal __attribute__((noinline)) // inline never
@@ -44,7 +45,7 @@
#define V_ volatile
// Fictional, used for intiution.
#define EUB_ restrict // Execute Unit Bound: Data is siloed in the ALU Register File. The Load/Store Unit is bypassed. (Route to Execution Unit. Keep in registers)
#define ISO_ restrict // Sole-access path: Isolated Provenance. Alternative to Exu_. Guarantees electrical memory isolation,
#define ISO_ restrict // Isolated Provenance: Alternative to Exu_. Guarantees electrical memory isolation,
// unlocking the compilers ability to safely pack data across multiple parallel SIMD lanes (vectorization).
#define LSU_ volatile // Load/Store Unit Bound: The compiler is forbidden from caching in registers. Forces physical L1 Cache matrix sampling.
#define LIVE_ volatile // Live External Data: Alternative to Lsu_ emphasizing the memory is tapped by an external electrical actor.
@@ -128,6 +129,9 @@ typedef __UINT32_TYPE__ TSet_(B4);
#define u4_v(value) C_(U4 V_*, value)
enum { false = 0, true = 1, true_overflow, };
#define u4_lo(value) ((value) & 0xFFFFU)
#define u4_hi(value) ((value) >> 12)
typedef void Proc_(VoidFn) (void);
#define kilo(n) (C_(U4, n) << 10)
+416 -361
View File
@@ -4,11 +4,125 @@
#endif
/* ============================================================================
* INLINE ASSEMBLY BLOB DISPATCHER (UP TO 99 INSTRUCTIONS)
* ============================================================================ */
* GCC INLINE ASM STATEMENT DSL
* ============================================================================
* A complete GCC inline-asm statement has up to 5 sections separated by `:`
* asm volatile ( "code template" : OUTPUTS : INPUTS : CLOBBERS : GOTO_LABELS );
*/
// Below are used purely for annotation.
#define asm_out // OUTPUTS section /* cannot be used with asm_words */
#define asm_in // INPUTS section /* can be appended onto after asm_words for pinned registers */
#define asm_clobber // CLOBBERS section
// Pinned Registers after asm_words list (Semantic marker)
// We aren't starting a new offical section, its just a continuation of the input section.
// asm_words(...) // ".words " code word ids... : : code_words...
// asm_rpins, r_use(r0), ... // , pinned registers...
// asm_clobber:
#define asm_rpins
/* --- Logic & Control Flow --- */
/* Annotation for the 'Goto' section of 'asm volatile goto'.
* Allows you to jump from assembly directly to a C label. */
#define asm_goto // Annotate the last `:` in an asm expression.
/* `asm_words(...)` dispatches into `_INL_<count>` to emit up to 99 encoded
* instruction words. This is the "compiled-instruction" form of `asm_code`.
*
* Result is a 2-colon body WITHOUT the final clobber section:
* ".word %c0, %c1, ..." : --- empty --- : "i"(p0), "i"(p1), ...
* |------ code --------| |--- outputs ---| |------- inputs -------|
*
* Use it inside `asm volatile( ... )` like so:
* asm volatile(
* asm_words(w0, w1, w3)
* asm_clobber: clobbers
* )
* which expands to:
* asm volatile(".word %c0, %c1, %c2"
* asm_out: // empty outputs
* asm_in: "i"(w0), "i"(w1), "i"(w2)
* asm_clobber: "$2", "$8", ...
* )
*/
#define asm_words(...) m_expand(glue(GCC_ASM_INL_, GCC_ASM_COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__))
// Very nasty macro expansion. See the Cruft pragma region after all the DSL defines
/* reg_str(n) — Stringify an integer register id into the GCC asm
* string form (e.g. 12 → "$12"). Use this anywhere GCC's parser
* expects a literal string identifying a register: clobber lists,
* asm templates, etc. The two-level macro is the standard preprocessor
* idiom for forcing one level of expansion before stringify — without
* it, `#n` would stringify the macro name `R_T4` to `"R_T4"` instead
* of expanding `R_T4` to its value first.
*
* For declaring a register variable bound to a specific GPR, use the
* `rgcc(n)` bundle from gcc_asm.h instead — it adds the `__asm__()`
* qualifier around the string.
*
* register V3_S2* p0 __asm__(reg_str(R_T4)) = ...; // verbose
* register V3_S2* p0 rgcc(R_T4) = ...; // bundled
*
* asm volatile("nop" : : : reg_str(R_RA), "memory"); // clobber list */
#define rlit_impl(n) "$" #n
#define rlit(n) rlit_impl(n)
/* ------------------------------------------------------------------------ *
* rgcc(n) — GCC-specific bundle for register-variable declarations.
*
* Produces `__asm__(reg_str(tmpl(n, Code)))` at expansion time.
* The `tmpl(n, Code)` indirection derives the preprocessor-visible `_Code`
* form from the enum name (which the preprocessor can't expand on its own).
* So a call is: register V3_S2* p rgcc(R_T4) = verts[0].ptr;
* expands (via tmpl) to: register V3_S2* p __asm__(rlit(R_T4_Code)) = verts[0].ptr;
* which (via reg_str) becomes: register V3_S2* p __asm__("$12") = verts[0].ptr;
*
* Why bundle the `__asm__()` wrapper?
* - The integer R_T4 (= 12, via R_T4_Code) already indicates the register.
* - The string "$12" is derived from it via reg_str, so they cannot drift apart.
* - Spelling `__asm__(reg_str(R_T4_Code))` at every call site is noise.
*
* tmpl defined in dsl.h (the token-paste glue).
* rgcc define here (gcc_asm.h) because the `__asm__` keyword is GCC-specific.
* Anyone porting to a different compiler's asm dialect overrides rgcc,
* and the integer→string derivation in rlit can be retargeted in one place.
*
* For clobber lists and asm-template strings, use the bare `rlit(R_T4_Code)`.
* ------------------------------------------------------------------------ */
#define rgcc_(n) __asm__(rlit(tmpl(n, Code)))
#define rgcc(n) rgcc_(n)
/* rgcc_ref(n) — GCC operand-reference form "%N". Not currently used
* by the placeholder-pun macros (the .word bodies are fully baked
* at compile time and have no runtime operand references), but kept
* here for completeness in case a future asm template needs to refer
* to a runtime input by position. Mirror of rgcc but produces "%N"
* instead of "$N". */
#define rgcc_ref_(n) "%" #n
#define rgcc_ref(n) rgcc_ref_(n)
/* --- Register Constraint Aliases (for Pinned Variables) --- */
#define r_use(var) "r"(var) /* General Purpose Register */
#define r_set(var) "=r"(var) /* Write-only output */
#define r_mod(var) "+r"(var) /* Read-write */
#define r_imm(val) "i"(val) /* Immediate / Constant */
/* Memory: Forces GCC to sync the variable to RAM before the asm runs.
* Essential for DMA buffers or when the hardware reads from memory. */
#define r_mem(var) "m"(var)
#define r_imm(val) "i"(val) /* Immediate: Forces a compile-time constant. */
#define r_fpu(var) "f"(var) /* FPU (PS2/MIPS III/IV): Use for COP1 floating point registers. */
#define r_acc(var) "a"(var) /* Accumulator: Use for HI/LO register results (multiplication/division). */
#define clb_mem_drain "memory"
// C Preprocessor Iterative Expansion Jank
#pragma region Cruft
/* --- 1. The Argument Counter --- */
#define _ASM_COUNT_ARGS_IMPL( \
#define GCC_ASM_COUNT_ARGS_IMPL( \
_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
@@ -20,7 +134,7 @@
_81,_82,_83,_84,_85,_86,_87,_88,_89,_90, \
_91,_92,_93,_94,_95,_96,_97,_98,_99, N, ...) N
#define _ASM_COUNT_ARGS(...) m_expand(_ASM_COUNT_ARGS_IMPL(__VA_ARGS__, \
#define GCC_ASM_COUNT_ARGS(...) m_expand(GCC_ASM_COUNT_ARGS_IMPL(__VA_ARGS__, \
99, 98, 97, 96, 95, 94, 93, 92, 91, 90, \
89, 88, 87, 86, 85, 84, 83, 82, 81, 80, \
79, 78, 77, 76, 75, 74, 73, 72, 71, 70, \
@@ -39,364 +153,305 @@
* integer immediates (the only kind `"i"(...)` produces), the plain
* `%N` form is the right one. Both expand to the bare immediate.
*/
#define _STR1 "%0"
#define _STR2 _STR1 ", %1"
#define _STR3 _STR2 ", %2"
#define _STR4 _STR3 ", %3"
#define _STR5 _STR4 ", %4"
#define _STR6 _STR5 ", %5"
#define _STR7 _STR6 ", %6"
#define _STR8 _STR7 ", %7"
#define _STR9 _STR8 ", %8"
#define _STR10 _STR9 ", %9"
#define _STR11 _STR10 ", %10"
#define _STR12 _STR11 ", %11"
#define _STR13 _STR12 ", %12"
#define _STR14 _STR13 ", %13"
#define _STR15 _STR14 ", %14"
#define _STR16 _STR15 ", %15"
#define _STR17 _STR16 ", %16"
#define _STR18 _STR17 ", %17"
#define _STR19 _STR18 ", %18"
#define _STR20 _STR19 ", %19"
#define _STR21 _STR20 ", %20"
#define _STR22 _STR21 ", %21"
#define _STR23 _STR22 ", %22"
#define _STR24 _STR23 ", %23"
#define _STR25 _STR24 ", %24"
#define _STR26 _STR25 ", %25"
#define _STR27 _STR26 ", %26"
#define _STR28 _STR27 ", %27"
#define _STR29 _STR28 ", %28"
#define _STR30 _STR29 ", %29"
#define _STR31 _STR30 ", %30"
#define _STR32 _STR31 ", %31"
#define _STR33 _STR32 ", %32"
#define _STR34 _STR33 ", %33"
#define _STR35 _STR34 ", %34"
#define _STR36 _STR35 ", %35"
#define _STR37 _STR36 ", %36"
#define _STR38 _STR37 ", %37"
#define _STR39 _STR38 ", %38"
#define _STR40 _STR39 ", %39"
#define _STR41 _STR40 ", %40"
#define _STR42 _STR41 ", %41"
#define _STR43 _STR42 ", %42"
#define _STR44 _STR43 ", %43"
#define _STR45 _STR44 ", %44"
#define _STR46 _STR45 ", %45"
#define _STR47 _STR46 ", %46"
#define _STR48 _STR47 ", %47"
#define _STR49 _STR48 ", %48"
#define _STR50 _STR49 ", %49"
#define _STR51 _STR50 ", %50"
#define _STR52 _STR51 ", %51"
#define _STR53 _STR52 ", %52"
#define _STR54 _STR53 ", %53"
#define _STR55 _STR54 ", %54"
#define _STR56 _STR55 ", %55"
#define _STR57 _STR56 ", %56"
#define _STR58 _STR57 ", %57"
#define _STR59 _STR58 ", %58"
#define _STR60 _STR59 ", %59"
#define _STR61 _STR60 ", %60"
#define _STR62 _STR61 ", %61"
#define _STR63 _STR62 ", %62"
#define _STR64 _STR63 ", %63"
#define _STR65 _STR64 ", %64"
#define _STR66 _STR65 ", %65"
#define _STR67 _STR66 ", %66"
#define _STR68 _STR67 ", %67"
#define _STR69 _STR68 ", %68"
#define _STR70 _STR69 ", %69"
#define _STR71 _STR70 ", %70"
#define _STR72 _STR71 ", %71"
#define _STR73 _STR72 ", %72"
#define _STR74 _STR73 ", %73"
#define _STR75 _STR74 ", %74"
#define _STR76 _STR75 ", %75"
#define _STR77 _STR76 ", %76"
#define _STR78 _STR77 ", %77"
#define _STR79 _STR78 ", %78"
#define _STR80 _STR79 ", %79"
#define _STR81 _STR80 ", %80"
#define _STR82 _STR81 ", %81"
#define _STR83 _STR82 ", %82"
#define _STR84 _STR83 ", %83"
#define _STR85 _STR84 ", %84"
#define _STR86 _STR85 ", %85"
#define _STR87 _STR86 ", %86"
#define _STR88 _STR87 ", %87"
#define _STR89 _STR88 ", %88"
#define _STR90 _STR89 ", %89"
#define _STR91 _STR90 ", %90"
#define _STR92 _STR91 ", %91"
#define _STR93 _STR92 ", %92"
#define _STR94 _STR93 ", %93"
#define _STR95 _STR94 ", %94"
#define _STR96 _STR95 ", %95"
#define _STR97 _STR96 ", %96"
#define _STR98 _STR97 ", %97"
#define _STR99 _STR98 ", %98"
#define GCC_ASM_W1 "%0"
#define GCC_ASM_W2 GCC_ASM_W1 ", %1"
#define GCC_ASM_W3 GCC_ASM_W2 ", %2"
#define GCC_ASM_W4 GCC_ASM_W3 ", %3"
#define GCC_ASM_W5 GCC_ASM_W4 ", %4"
#define GCC_ASM_W6 GCC_ASM_W5 ", %5"
#define GCC_ASM_W7 GCC_ASM_W6 ", %6"
#define GCC_ASM_W8 GCC_ASM_W7 ", %7"
#define GCC_ASM_W9 GCC_ASM_W8 ", %8"
#define GCC_ASM_W10 GCC_ASM_W9 ", %9"
#define GCC_ASM_W11 GCC_ASM_W10 ", %10"
#define GCC_ASM_W12 GCC_ASM_W11 ", %11"
#define GCC_ASM_W13 GCC_ASM_W12 ", %12"
#define GCC_ASM_W14 GCC_ASM_W13 ", %13"
#define GCC_ASM_W15 GCC_ASM_W14 ", %14"
#define GCC_ASM_W16 GCC_ASM_W15 ", %15"
#define GCC_ASM_W17 GCC_ASM_W16 ", %16"
#define GCC_ASM_W18 GCC_ASM_W17 ", %17"
#define GCC_ASM_W19 GCC_ASM_W18 ", %18"
#define GCC_ASM_W20 GCC_ASM_W19 ", %19"
#define GCC_ASM_W21 GCC_ASM_W20 ", %20"
#define GCC_ASM_W22 GCC_ASM_W21 ", %21"
#define GCC_ASM_W23 GCC_ASM_W22 ", %22"
#define GCC_ASM_W24 GCC_ASM_W23 ", %23"
#define GCC_ASM_W25 GCC_ASM_W24 ", %24"
#define GCC_ASM_W26 GCC_ASM_W25 ", %25"
#define GCC_ASM_W27 GCC_ASM_W26 ", %26"
#define GCC_ASM_W28 GCC_ASM_W27 ", %27"
#define GCC_ASM_W29 GCC_ASM_W28 ", %28"
#define GCC_ASM_W30 GCC_ASM_W29 ", %29"
#define GCC_ASM_W31 GCC_ASM_W30 ", %30"
#define GCC_ASM_W32 GCC_ASM_W31 ", %31"
#define GCC_ASM_W33 GCC_ASM_W32 ", %32"
#define GCC_ASM_W34 GCC_ASM_W33 ", %33"
#define GCC_ASM_W35 GCC_ASM_W34 ", %34"
#define GCC_ASM_W36 GCC_ASM_W35 ", %35"
#define GCC_ASM_W37 GCC_ASM_W36 ", %36"
#define GCC_ASM_W38 GCC_ASM_W37 ", %37"
#define GCC_ASM_W39 GCC_ASM_W38 ", %38"
#define GCC_ASM_W40 GCC_ASM_W39 ", %39"
#define GCC_ASM_W41 GCC_ASM_W40 ", %40"
#define GCC_ASM_W42 GCC_ASM_W41 ", %41"
#define GCC_ASM_W43 GCC_ASM_W42 ", %42"
#define GCC_ASM_W44 GCC_ASM_W43 ", %43"
#define GCC_ASM_W45 GCC_ASM_W44 ", %44"
#define GCC_ASM_W46 GCC_ASM_W45 ", %45"
#define GCC_ASM_W47 GCC_ASM_W46 ", %46"
#define GCC_ASM_W48 GCC_ASM_W47 ", %47"
#define GCC_ASM_W49 GCC_ASM_W48 ", %48"
#define GCC_ASM_W50 GCC_ASM_W49 ", %49"
#define GCC_ASM_W51 GCC_ASM_W50 ", %50"
#define GCC_ASM_W52 GCC_ASM_W51 ", %51"
#define GCC_ASM_W53 GCC_ASM_W52 ", %52"
#define GCC_ASM_W54 GCC_ASM_W53 ", %53"
#define GCC_ASM_W55 GCC_ASM_W54 ", %54"
#define GCC_ASM_W56 GCC_ASM_W55 ", %55"
#define GCC_ASM_W57 GCC_ASM_W56 ", %56"
#define GCC_ASM_W58 GCC_ASM_W57 ", %57"
#define GCC_ASM_W59 GCC_ASM_W58 ", %58"
#define GCC_ASM_W60 GCC_ASM_W59 ", %59"
#define GCC_ASM_W61 GCC_ASM_W60 ", %60"
#define GCC_ASM_W62 GCC_ASM_W61 ", %61"
#define GCC_ASM_W63 GCC_ASM_W62 ", %62"
#define GCC_ASM_W64 GCC_ASM_W63 ", %63"
#define GCC_ASM_W65 GCC_ASM_W64 ", %64"
#define GCC_ASM_W66 GCC_ASM_W65 ", %65"
#define GCC_ASM_W67 GCC_ASM_W66 ", %66"
#define GCC_ASM_W68 GCC_ASM_W67 ", %67"
#define GCC_ASM_W69 GCC_ASM_W68 ", %68"
#define GCC_ASM_W70 GCC_ASM_W69 ", %69"
#define GCC_ASM_W71 GCC_ASM_W70 ", %70"
#define GCC_ASM_W72 GCC_ASM_W71 ", %71"
#define GCC_ASM_W73 GCC_ASM_W72 ", %72"
#define GCC_ASM_W74 GCC_ASM_W73 ", %73"
#define GCC_ASM_W75 GCC_ASM_W74 ", %74"
#define GCC_ASM_W76 GCC_ASM_W75 ", %75"
#define GCC_ASM_W77 GCC_ASM_W76 ", %76"
#define GCC_ASM_W78 GCC_ASM_W77 ", %77"
#define GCC_ASM_W79 GCC_ASM_W78 ", %78"
#define GCC_ASM_W80 GCC_ASM_W79 ", %79"
#define GCC_ASM_W81 GCC_ASM_W80 ", %80"
#define GCC_ASM_W82 GCC_ASM_W81 ", %81"
#define GCC_ASM_W83 GCC_ASM_W82 ", %82"
#define GCC_ASM_W84 GCC_ASM_W83 ", %83"
#define GCC_ASM_W85 GCC_ASM_W84 ", %84"
#define GCC_ASM_W86 GCC_ASM_W85 ", %85"
#define GCC_ASM_W87 GCC_ASM_W86 ", %86"
#define GCC_ASM_W88 GCC_ASM_W87 ", %87"
#define GCC_ASM_W89 GCC_ASM_W88 ", %88"
#define GCC_ASM_W90 GCC_ASM_W89 ", %89"
#define GCC_ASM_W91 GCC_ASM_W90 ", %90"
#define GCC_ASM_W92 GCC_ASM_W91 ", %91"
#define GCC_ASM_W93 GCC_ASM_W92 ", %92"
#define GCC_ASM_W94 GCC_ASM_W93 ", %93"
#define GCC_ASM_W95 GCC_ASM_W94 ", %94"
#define GCC_ASM_W96 GCC_ASM_W95 ", %95"
#define GCC_ASM_W97 GCC_ASM_W96 ", %96"
#define GCC_ASM_W98 GCC_ASM_W97 ", %97"
#define GCC_ASM_W99 GCC_ASM_W98 ", %98"
/* Utilizing cascading operand strings to compress the payload */
#define _OP10 "i"(p0),"i"(p1),"i"(p2),"i"(p3),"i"(p4),"i"(p5),"i"(p6),"i"(p7),"i"(p8),"i"(p9)
#define _OP20 _OP10,"i"(p10),"i"(p11),"i"(p12),"i"(p13),"i"(p14),"i"(p15),"i"(p16),"i"(p17),"i"(p18),"i"(p19)
#define _OP30 _OP20,"i"(p20),"i"(p21),"i"(p22),"i"(p23),"i"(p24),"i"(p25),"i"(p26),"i"(p27),"i"(p28),"i"(p29)
#define _OP40 _OP30,"i"(p30),"i"(p31),"i"(p32),"i"(p33),"i"(p34),"i"(p35),"i"(p36),"i"(p37),"i"(p38),"i"(p39)
#define _OP50 _OP40,"i"(p40),"i"(p41),"i"(p42),"i"(p43),"i"(p44),"i"(p45),"i"(p46),"i"(p47),"i"(p48),"i"(p49)
#define _OP60 _OP50,"i"(p50),"i"(p51),"i"(p52),"i"(p53),"i"(p54),"i"(p55),"i"(p56),"i"(p57),"i"(p58),"i"(p59)
#define _OP70 _OP60,"i"(p60),"i"(p61),"i"(p62),"i"(p63),"i"(p64),"i"(p65),"i"(p66),"i"(p67),"i"(p68),"i"(p69)
#define _OP80 _OP70,"i"(p70),"i"(p71),"i"(p72),"i"(p73),"i"(p74),"i"(p75),"i"(p76),"i"(p77),"i"(p78),"i"(p79)
#define _OP90 _OP80,"i"(p80),"i"(p81),"i"(p82),"i"(p83),"i"(p84),"i"(p85),"i"(p86),"i"(p87),"i"(p88),"i"(p89)
#define GCC_ASM_I1(p0) "i"(p0)
#define GCC_ASM_I2(p0, ...) "i"(p0), GCC_ASM_I1( __VA_ARGS__)
#define GCC_ASM_I3(p0, ...) "i"(p0), GCC_ASM_I2( __VA_ARGS__)
#define GCC_ASM_I4(p0, ...) "i"(p0), GCC_ASM_I3( __VA_ARGS__)
#define GCC_ASM_I5(p0, ...) "i"(p0), GCC_ASM_I4( __VA_ARGS__)
#define GCC_ASM_I6(p0, ...) "i"(p0), GCC_ASM_I5( __VA_ARGS__)
#define GCC_ASM_I7(p0, ...) "i"(p0), GCC_ASM_I6( __VA_ARGS__)
#define GCC_ASM_I8(p0, ...) "i"(p0), GCC_ASM_I7( __VA_ARGS__)
#define GCC_ASM_I9(p0, ...) "i"(p0), GCC_ASM_I8( __VA_ARGS__)
#define GCC_ASM_I10(p0, ...) "i"(p0), GCC_ASM_I9( __VA_ARGS__)
#define GCC_ASM_I11(p0, ...) "i"(p0), GCC_ASM_I10(__VA_ARGS__)
#define GCC_ASM_I12(p0, ...) "i"(p0), GCC_ASM_I11(__VA_ARGS__)
#define GCC_ASM_I13(p0, ...) "i"(p0), GCC_ASM_I12(__VA_ARGS__)
#define GCC_ASM_I14(p0, ...) "i"(p0), GCC_ASM_I13(__VA_ARGS__)
#define GCC_ASM_I15(p0, ...) "i"(p0), GCC_ASM_I14(__VA_ARGS__)
#define GCC_ASM_I16(p0, ...) "i"(p0), GCC_ASM_I15(__VA_ARGS__)
#define GCC_ASM_I17(p0, ...) "i"(p0), GCC_ASM_I16(__VA_ARGS__)
#define GCC_ASM_I18(p0, ...) "i"(p0), GCC_ASM_I17(__VA_ARGS__)
#define GCC_ASM_I19(p0, ...) "i"(p0), GCC_ASM_I18(__VA_ARGS__)
#define GCC_ASM_I20(p0, ...) "i"(p0), GCC_ASM_I19(__VA_ARGS__)
#define GCC_ASM_I21(p0, ...) "i"(p0), GCC_ASM_I20(__VA_ARGS__)
#define GCC_ASM_I22(p0, ...) "i"(p0), GCC_ASM_I21(__VA_ARGS__)
#define GCC_ASM_I23(p0, ...) "i"(p0), GCC_ASM_I22(__VA_ARGS__)
#define GCC_ASM_I24(p0, ...) "i"(p0), GCC_ASM_I23(__VA_ARGS__)
#define GCC_ASM_I25(p0, ...) "i"(p0), GCC_ASM_I24(__VA_ARGS__)
#define GCC_ASM_I26(p0, ...) "i"(p0), GCC_ASM_I25(__VA_ARGS__)
#define GCC_ASM_I27(p0, ...) "i"(p0), GCC_ASM_I26(__VA_ARGS__)
#define GCC_ASM_I28(p0, ...) "i"(p0), GCC_ASM_I27(__VA_ARGS__)
#define GCC_ASM_I29(p0, ...) "i"(p0), GCC_ASM_I28(__VA_ARGS__)
#define GCC_ASM_I30(p0, ...) "i"(p0), GCC_ASM_I29(__VA_ARGS__)
#define GCC_ASM_I31(p0, ...) "i"(p0), GCC_ASM_I30(__VA_ARGS__)
#define GCC_ASM_I32(p0, ...) "i"(p0), GCC_ASM_I31(__VA_ARGS__)
#define GCC_ASM_I33(p0, ...) "i"(p0), GCC_ASM_I32(__VA_ARGS__)
#define GCC_ASM_I34(p0, ...) "i"(p0), GCC_ASM_I33(__VA_ARGS__)
#define GCC_ASM_I35(p0, ...) "i"(p0), GCC_ASM_I34(__VA_ARGS__)
#define GCC_ASM_I36(p0, ...) "i"(p0), GCC_ASM_I35(__VA_ARGS__)
#define GCC_ASM_I37(p0, ...) "i"(p0), GCC_ASM_I36(__VA_ARGS__)
#define GCC_ASM_I38(p0, ...) "i"(p0), GCC_ASM_I37(__VA_ARGS__)
#define GCC_ASM_I39(p0, ...) "i"(p0), GCC_ASM_I38(__VA_ARGS__)
#define GCC_ASM_I40(p0, ...) "i"(p0), GCC_ASM_I39(__VA_ARGS__)
#define GCC_ASM_I41(p0, ...) "i"(p0), GCC_ASM_I40(__VA_ARGS__)
#define GCC_ASM_I42(p0, ...) "i"(p0), GCC_ASM_I41(__VA_ARGS__)
#define GCC_ASM_I43(p0, ...) "i"(p0), GCC_ASM_I42(__VA_ARGS__)
#define GCC_ASM_I44(p0, ...) "i"(p0), GCC_ASM_I43(__VA_ARGS__)
#define GCC_ASM_I45(p0, ...) "i"(p0), GCC_ASM_I44(__VA_ARGS__)
#define GCC_ASM_I46(p0, ...) "i"(p0), GCC_ASM_I45(__VA_ARGS__)
#define GCC_ASM_I47(p0, ...) "i"(p0), GCC_ASM_I46(__VA_ARGS__)
#define GCC_ASM_I48(p0, ...) "i"(p0), GCC_ASM_I47(__VA_ARGS__)
#define GCC_ASM_I49(p0, ...) "i"(p0), GCC_ASM_I48(__VA_ARGS__)
#define GCC_ASM_I50(p0, ...) "i"(p0), GCC_ASM_I49(__VA_ARGS__)
#define GCC_ASM_I51(p0, ...) "i"(p0), GCC_ASM_I50(__VA_ARGS__)
#define GCC_ASM_I52(p0, ...) "i"(p0), GCC_ASM_I51(__VA_ARGS__)
#define GCC_ASM_I53(p0, ...) "i"(p0), GCC_ASM_I52(__VA_ARGS__)
#define GCC_ASM_I54(p0, ...) "i"(p0), GCC_ASM_I53(__VA_ARGS__)
#define GCC_ASM_I55(p0, ...) "i"(p0), GCC_ASM_I54(__VA_ARGS__)
#define GCC_ASM_I56(p0, ...) "i"(p0), GCC_ASM_I55(__VA_ARGS__)
#define GCC_ASM_I57(p0, ...) "i"(p0), GCC_ASM_I56(__VA_ARGS__)
#define GCC_ASM_I58(p0, ...) "i"(p0), GCC_ASM_I57(__VA_ARGS__)
#define GCC_ASM_I59(p0, ...) "i"(p0), GCC_ASM_I58(__VA_ARGS__)
#define GCC_ASM_I60(p0, ...) "i"(p0), GCC_ASM_I59(__VA_ARGS__)
#define GCC_ASM_I61(p0, ...) "i"(p0), GCC_ASM_I60(__VA_ARGS__)
#define GCC_ASM_I62(p0, ...) "i"(p0), GCC_ASM_I61(__VA_ARGS__)
#define GCC_ASM_I63(p0, ...) "i"(p0), GCC_ASM_I62(__VA_ARGS__)
#define GCC_ASM_I64(p0, ...) "i"(p0), GCC_ASM_I63(__VA_ARGS__)
#define GCC_ASM_I65(p0, ...) "i"(p0), GCC_ASM_I64(__VA_ARGS__)
#define GCC_ASM_I66(p0, ...) "i"(p0), GCC_ASM_I65(__VA_ARGS__)
#define GCC_ASM_I67(p0, ...) "i"(p0), GCC_ASM_I66(__VA_ARGS__)
#define GCC_ASM_I68(p0, ...) "i"(p0), GCC_ASM_I67(__VA_ARGS__)
#define GCC_ASM_I69(p0, ...) "i"(p0), GCC_ASM_I68(__VA_ARGS__)
#define GCC_ASM_I70(p0, ...) "i"(p0), GCC_ASM_I69(__VA_ARGS__)
#define GCC_ASM_I71(p0, ...) "i"(p0), GCC_ASM_I70(__VA_ARGS__)
#define GCC_ASM_I72(p0, ...) "i"(p0), GCC_ASM_I71(__VA_ARGS__)
#define GCC_ASM_I73(p0, ...) "i"(p0), GCC_ASM_I72(__VA_ARGS__)
#define GCC_ASM_I74(p0, ...) "i"(p0), GCC_ASM_I73(__VA_ARGS__)
#define GCC_ASM_I75(p0, ...) "i"(p0), GCC_ASM_I74(__VA_ARGS__)
#define GCC_ASM_I76(p0, ...) "i"(p0), GCC_ASM_I75(__VA_ARGS__)
#define GCC_ASM_I77(p0, ...) "i"(p0), GCC_ASM_I76(__VA_ARGS__)
#define GCC_ASM_I78(p0, ...) "i"(p0), GCC_ASM_I77(__VA_ARGS__)
#define GCC_ASM_I79(p0, ...) "i"(p0), GCC_ASM_I78(__VA_ARGS__)
#define GCC_ASM_I80(p0, ...) "i"(p0), GCC_ASM_I79(__VA_ARGS__)
#define GCC_ASM_I81(p0, ...) "i"(p0), GCC_ASM_I80(__VA_ARGS__)
#define GCC_ASM_I82(p0, ...) "i"(p0), GCC_ASM_I81(__VA_ARGS__)
#define GCC_ASM_I83(p0, ...) "i"(p0), GCC_ASM_I82(__VA_ARGS__)
#define GCC_ASM_I84(p0, ...) "i"(p0), GCC_ASM_I83(__VA_ARGS__)
#define GCC_ASM_I85(p0, ...) "i"(p0), GCC_ASM_I84(__VA_ARGS__)
#define GCC_ASM_I86(p0, ...) "i"(p0), GCC_ASM_I85(__VA_ARGS__)
#define GCC_ASM_I87(p0, ...) "i"(p0), GCC_ASM_I86(__VA_ARGS__)
#define GCC_ASM_I88(p0, ...) "i"(p0), GCC_ASM_I87(__VA_ARGS__)
#define GCC_ASM_I89(p0, ...) "i"(p0), GCC_ASM_I88(__VA_ARGS__)
#define GCC_ASM_I90(p0, ...) "i"(p0), GCC_ASM_I89(__VA_ARGS__)
#define GCC_ASM_I91(p0, ...) "i"(p0), GCC_ASM_I90(__VA_ARGS__)
#define GCC_ASM_I92(p0, ...) "i"(p0), GCC_ASM_I91(__VA_ARGS__)
#define GCC_ASM_I93(p0, ...) "i"(p0), GCC_ASM_I92(__VA_ARGS__)
#define GCC_ASM_I94(p0, ...) "i"(p0), GCC_ASM_I93(__VA_ARGS__)
#define GCC_ASM_I95(p0, ...) "i"(p0), GCC_ASM_I94(__VA_ARGS__)
#define GCC_ASM_I96(p0, ...) "i"(p0), GCC_ASM_I95(__VA_ARGS__)
#define GCC_ASM_I97(p0, ...) "i"(p0), GCC_ASM_I96(__VA_ARGS__)
#define GCC_ASM_I98(p0, ...) "i"(p0), GCC_ASM_I97(__VA_ARGS__)
#define GCC_ASM_I99(p0, ...) "i"(p0), GCC_ASM_I98(__VA_ARGS__)
/* --- The AST Generators (1 to 99) --- */
#define _INL_1(p0) ".word " _STR1 : : "i"(p0)
#define _INL_2(p0,p1) ".word " _STR2 : : "i"(p0),"i"(p1)
#define _INL_3(p0,p1,p2) ".word " _STR3 : : "i"(p0),"i"(p1),"i"(p2)
#define _INL_4(p0,p1,p2,p3) ".word " _STR4 : : "i"(p0),"i"(p1),"i"(p2),"i"(p3)
#define _INL_5(p0,p1,p2,p3,p4) ".word " _STR5 : : "i"(p0),"i"(p1),"i"(p2),"i"(p3),"i"(p4)
#define _INL_6(p0,p1,p2,p3,p4,p5) ".word " _STR6 : : "i"(p0),"i"(p1),"i"(p2),"i"(p3),"i"(p4),"i"(p5)
#define _INL_7(p0,p1,p2,p3,p4,p5,p6) ".word " _STR7 : : "i"(p0),"i"(p1),"i"(p2),"i"(p3),"i"(p4),"i"(p5),"i"(p6)
#define _INL_8(p0,p1,p2,p3,p4,p5,p6,p7) ".word " _STR8 : : "i"(p0),"i"(p1),"i"(p2),"i"(p3),"i"(p4),"i"(p5),"i"(p6),"i"(p7)
#define _INL_9(p0,p1,p2,p3,p4,p5,p6,p7,p8) ".word " _STR9 : : "i"(p0),"i"(p1),"i"(p2),"i"(p3),"i"(p4),"i"(p5),"i"(p6),"i"(p7),"i"(p8)
#define _INL_10(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9) ".word " _STR10 : : _OP10
#define GCC_ASM_INL_1( a) ".word " GCC_ASM_W1 : : GCC_ASM_I1( a)
#define GCC_ASM_INL_2( a, ...) ".word " GCC_ASM_W2 : : GCC_ASM_I2( a, __VA_ARGS__)
#define GCC_ASM_INL_3( a, ...) ".word " GCC_ASM_W3 : : GCC_ASM_I3( a, __VA_ARGS__)
#define GCC_ASM_INL_4( a, ...) ".word " GCC_ASM_W4 : : GCC_ASM_I4( a, __VA_ARGS__)
#define GCC_ASM_INL_5( a, ...) ".word " GCC_ASM_W5 : : GCC_ASM_I5( a, __VA_ARGS__)
#define GCC_ASM_INL_6( a, ...) ".word " GCC_ASM_W6 : : GCC_ASM_I6( a, __VA_ARGS__)
#define GCC_ASM_INL_7( a, ...) ".word " GCC_ASM_W7 : : GCC_ASM_I7( a, __VA_ARGS__)
#define GCC_ASM_INL_8( a, ...) ".word " GCC_ASM_W8 : : GCC_ASM_I8( a, __VA_ARGS__)
#define GCC_ASM_INL_9( a, ...) ".word " GCC_ASM_W9 : : GCC_ASM_I9( a, __VA_ARGS__)
#define GCC_ASM_INL_10(a, ...) ".word " GCC_ASM_W10 : : GCC_ASM_I10(a, __VA_ARGS__)
#define GCC_ASM_INL_11(a, ...) ".word " GCC_ASM_W11 : : GCC_ASM_I11(a, __VA_ARGS__)
#define GCC_ASM_INL_12(a, ...) ".word " GCC_ASM_W12 : : GCC_ASM_I12(a, __VA_ARGS__)
#define GCC_ASM_INL_13(a, ...) ".word " GCC_ASM_W13 : : GCC_ASM_I13(a, __VA_ARGS__)
#define GCC_ASM_INL_14(a, ...) ".word " GCC_ASM_W14 : : GCC_ASM_I14(a, __VA_ARGS__)
#define GCC_ASM_INL_15(a, ...) ".word " GCC_ASM_W15 : : GCC_ASM_I15(a, __VA_ARGS__)
#define GCC_ASM_INL_16(a, ...) ".word " GCC_ASM_W16 : : GCC_ASM_I16(a, __VA_ARGS__)
#define GCC_ASM_INL_17(a, ...) ".word " GCC_ASM_W17 : : GCC_ASM_I17(a, __VA_ARGS__)
#define GCC_ASM_INL_18(a, ...) ".word " GCC_ASM_W18 : : GCC_ASM_I18(a, __VA_ARGS__)
#define GCC_ASM_INL_19(a, ...) ".word " GCC_ASM_W19 : : GCC_ASM_I19(a, __VA_ARGS__)
#define GCC_ASM_INL_20(a, ...) ".word " GCC_ASM_W20 : : GCC_ASM_I20(a, __VA_ARGS__)
#define GCC_ASM_INL_21(a, ...) ".word " GCC_ASM_W21 : : GCC_ASM_I21(a, __VA_ARGS__)
#define GCC_ASM_INL_22(a, ...) ".word " GCC_ASM_W22 : : GCC_ASM_I22(a, __VA_ARGS__)
#define GCC_ASM_INL_23(a, ...) ".word " GCC_ASM_W23 : : GCC_ASM_I23(a, __VA_ARGS__)
#define GCC_ASM_INL_24(a, ...) ".word " GCC_ASM_W24 : : GCC_ASM_I24(a, __VA_ARGS__)
#define GCC_ASM_INL_25(a, ...) ".word " GCC_ASM_W25 : : GCC_ASM_I25(a, __VA_ARGS__)
#define GCC_ASM_INL_26(a, ...) ".word " GCC_ASM_W26 : : GCC_ASM_I26(a, __VA_ARGS__)
#define GCC_ASM_INL_27(a, ...) ".word " GCC_ASM_W27 : : GCC_ASM_I27(a, __VA_ARGS__)
#define GCC_ASM_INL_28(a, ...) ".word " GCC_ASM_W28 : : GCC_ASM_I28(a, __VA_ARGS__)
#define GCC_ASM_INL_29(a, ...) ".word " GCC_ASM_W29 : : GCC_ASM_I29(a, __VA_ARGS__)
#define GCC_ASM_INL_30(a, ...) ".word " GCC_ASM_W30 : : GCC_ASM_I30(a, __VA_ARGS__)
#define GCC_ASM_INL_31(a, ...) ".word " GCC_ASM_W31 : : GCC_ASM_I31(a, __VA_ARGS__)
#define GCC_ASM_INL_32(a, ...) ".word " GCC_ASM_W32 : : GCC_ASM_I32(a, __VA_ARGS__)
#define GCC_ASM_INL_33(a, ...) ".word " GCC_ASM_W33 : : GCC_ASM_I33(a, __VA_ARGS__)
#define GCC_ASM_INL_34(a, ...) ".word " GCC_ASM_W34 : : GCC_ASM_I34(a, __VA_ARGS__)
#define GCC_ASM_INL_35(a, ...) ".word " GCC_ASM_W35 : : GCC_ASM_I35(a, __VA_ARGS__)
#define GCC_ASM_INL_36(a, ...) ".word " GCC_ASM_W36 : : GCC_ASM_I36(a, __VA_ARGS__)
#define GCC_ASM_INL_37(a, ...) ".word " GCC_ASM_W37 : : GCC_ASM_I37(a, __VA_ARGS__)
#define GCC_ASM_INL_38(a, ...) ".word " GCC_ASM_W38 : : GCC_ASM_I38(a, __VA_ARGS__)
#define GCC_ASM_INL_39(a, ...) ".word " GCC_ASM_W39 : : GCC_ASM_I39(a, __VA_ARGS__)
#define GCC_ASM_INL_40(a, ...) ".word " GCC_ASM_W40 : : GCC_ASM_I40(a, __VA_ARGS__)
#define GCC_ASM_INL_41(a, ...) ".word " GCC_ASM_W41 : : GCC_ASM_I41(a, __VA_ARGS__)
#define GCC_ASM_INL_42(a, ...) ".word " GCC_ASM_W42 : : GCC_ASM_I42(a, __VA_ARGS__)
#define GCC_ASM_INL_43(a, ...) ".word " GCC_ASM_W43 : : GCC_ASM_I43(a, __VA_ARGS__)
#define GCC_ASM_INL_44(a, ...) ".word " GCC_ASM_W44 : : GCC_ASM_I44(a, __VA_ARGS__)
#define GCC_ASM_INL_45(a, ...) ".word " GCC_ASM_W45 : : GCC_ASM_I45(a, __VA_ARGS__)
#define GCC_ASM_INL_46(a, ...) ".word " GCC_ASM_W46 : : GCC_ASM_I46(a, __VA_ARGS__)
#define GCC_ASM_INL_47(a, ...) ".word " GCC_ASM_W47 : : GCC_ASM_I47(a, __VA_ARGS__)
#define GCC_ASM_INL_48(a, ...) ".word " GCC_ASM_W48 : : GCC_ASM_I48(a, __VA_ARGS__)
#define GCC_ASM_INL_49(a, ...) ".word " GCC_ASM_W49 : : GCC_ASM_I49(a, __VA_ARGS__)
#define GCC_ASM_INL_50(a, ...) ".word " GCC_ASM_W50 : : GCC_ASM_I50(a, __VA_ARGS__)
#define GCC_ASM_INL_51(a, ...) ".word " GCC_ASM_W51 : : GCC_ASM_I51(a, __VA_ARGS__)
#define GCC_ASM_INL_52(a, ...) ".word " GCC_ASM_W52 : : GCC_ASM_I52(a, __VA_ARGS__)
#define GCC_ASM_INL_53(a, ...) ".word " GCC_ASM_W53 : : GCC_ASM_I53(a, __VA_ARGS__)
#define GCC_ASM_INL_54(a, ...) ".word " GCC_ASM_W54 : : GCC_ASM_I54(a, __VA_ARGS__)
#define GCC_ASM_INL_55(a, ...) ".word " GCC_ASM_W55 : : GCC_ASM_I55(a, __VA_ARGS__)
#define GCC_ASM_INL_56(a, ...) ".word " GCC_ASM_W56 : : GCC_ASM_I56(a, __VA_ARGS__)
#define GCC_ASM_INL_57(a, ...) ".word " GCC_ASM_W57 : : GCC_ASM_I57(a, __VA_ARGS__)
#define GCC_ASM_INL_58(a, ...) ".word " GCC_ASM_W58 : : GCC_ASM_I58(a, __VA_ARGS__)
#define GCC_ASM_INL_59(a, ...) ".word " GCC_ASM_W59 : : GCC_ASM_I59(a, __VA_ARGS__)
#define GCC_ASM_INL_60(a, ...) ".word " GCC_ASM_W60 : : GCC_ASM_I60(a, __VA_ARGS__)
#define GCC_ASM_INL_61(a, ...) ".word " GCC_ASM_W61 : : GCC_ASM_I61(a, __VA_ARGS__)
#define GCC_ASM_INL_62(a, ...) ".word " GCC_ASM_W62 : : GCC_ASM_I62(a, __VA_ARGS__)
#define GCC_ASM_INL_63(a, ...) ".word " GCC_ASM_W63 : : GCC_ASM_I63(a, __VA_ARGS__)
#define GCC_ASM_INL_64(a, ...) ".word " GCC_ASM_W64 : : GCC_ASM_I64(a, __VA_ARGS__)
#define GCC_ASM_INL_65(a, ...) ".word " GCC_ASM_W65 : : GCC_ASM_I65(a, __VA_ARGS__)
#define GCC_ASM_INL_66(a, ...) ".word " GCC_ASM_W66 : : GCC_ASM_I66(a, __VA_ARGS__)
#define GCC_ASM_INL_67(a, ...) ".word " GCC_ASM_W67 : : GCC_ASM_I67(a, __VA_ARGS__)
#define GCC_ASM_INL_68(a, ...) ".word " GCC_ASM_W68 : : GCC_ASM_I68(a, __VA_ARGS__)
#define GCC_ASM_INL_69(a, ...) ".word " GCC_ASM_W69 : : GCC_ASM_I69(a, __VA_ARGS__)
#define GCC_ASM_INL_70(a, ...) ".word " GCC_ASM_W70 : : GCC_ASM_I70(a, __VA_ARGS__)
#define GCC_ASM_INL_71(a, ...) ".word " GCC_ASM_W71 : : GCC_ASM_I71(a, __VA_ARGS__)
#define GCC_ASM_INL_72(a, ...) ".word " GCC_ASM_W72 : : GCC_ASM_I72(a, __VA_ARGS__)
#define GCC_ASM_INL_73(a, ...) ".word " GCC_ASM_W73 : : GCC_ASM_I73(a, __VA_ARGS__)
#define GCC_ASM_INL_74(a, ...) ".word " GCC_ASM_W74 : : GCC_ASM_I74(a, __VA_ARGS__)
#define GCC_ASM_INL_75(a, ...) ".word " GCC_ASM_W75 : : GCC_ASM_I75(a, __VA_ARGS__)
#define GCC_ASM_INL_76(a, ...) ".word " GCC_ASM_W76 : : GCC_ASM_I76(a, __VA_ARGS__)
#define GCC_ASM_INL_77(a, ...) ".word " GCC_ASM_W77 : : GCC_ASM_I77(a, __VA_ARGS__)
#define GCC_ASM_INL_78(a, ...) ".word " GCC_ASM_W78 : : GCC_ASM_I78(a, __VA_ARGS__)
#define GCC_ASM_INL_79(a, ...) ".word " GCC_ASM_W79 : : GCC_ASM_I79(a, __VA_ARGS__)
#define GCC_ASM_INL_80(a, ...) ".word " GCC_ASM_W80 : : GCC_ASM_I80(a, __VA_ARGS__)
#define GCC_ASM_INL_81(a, ...) ".word " GCC_ASM_W81 : : GCC_ASM_I81(a, __VA_ARGS__)
#define GCC_ASM_INL_82(a, ...) ".word " GCC_ASM_W82 : : GCC_ASM_I82(a, __VA_ARGS__)
#define GCC_ASM_INL_83(a, ...) ".word " GCC_ASM_W83 : : GCC_ASM_I83(a, __VA_ARGS__)
#define GCC_ASM_INL_84(a, ...) ".word " GCC_ASM_W84 : : GCC_ASM_I84(a, __VA_ARGS__)
#define GCC_ASM_INL_85(a, ...) ".word " GCC_ASM_W85 : : GCC_ASM_I85(a, __VA_ARGS__)
#define GCC_ASM_INL_86(a, ...) ".word " GCC_ASM_W86 : : GCC_ASM_I86(a, __VA_ARGS__)
#define GCC_ASM_INL_87(a, ...) ".word " GCC_ASM_W87 : : GCC_ASM_I87(a, __VA_ARGS__)
#define GCC_ASM_INL_88(a, ...) ".word " GCC_ASM_W88 : : GCC_ASM_I88(a, __VA_ARGS__)
#define GCC_ASM_INL_89(a, ...) ".word " GCC_ASM_W89 : : GCC_ASM_I89(a, __VA_ARGS__)
#define GCC_ASM_INL_90(a, ...) ".word " GCC_ASM_W90 : : GCC_ASM_I90(a, __VA_ARGS__)
#define GCC_ASM_INL_91(a, ...) ".word " GCC_ASM_W91 : : GCC_ASM_I91(a, __VA_ARGS__)
#define GCC_ASM_INL_92(a, ...) ".word " GCC_ASM_W92 : : GCC_ASM_I92(a, __VA_ARGS__)
#define GCC_ASM_INL_93(a, ...) ".word " GCC_ASM_W93 : : GCC_ASM_I93(a, __VA_ARGS__)
#define GCC_ASM_INL_94(a, ...) ".word " GCC_ASM_W94 : : GCC_ASM_I94(a, __VA_ARGS__)
#define GCC_ASM_INL_95(a, ...) ".word " GCC_ASM_W95 : : GCC_ASM_I95(a, __VA_ARGS__)
#define GCC_ASM_INL_96(a, ...) ".word " GCC_ASM_W96 : : GCC_ASM_I96(a, __VA_ARGS__)
#define GCC_ASM_INL_97(a, ...) ".word " GCC_ASM_W97 : : GCC_ASM_I97(a, __VA_ARGS__)
#define GCC_ASM_INL_98(a, ...) ".word " GCC_ASM_W98 : : GCC_ASM_I98(a, __VA_ARGS__)
#define GCC_ASM_INL_99(a, ...) ".word " GCC_ASM_W99 : : GCC_ASM_I99(a, __VA_ARGS__)
#define _INL_11(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) ".word " _STR11 : : _OP10,"i"(p10)
#define _INL_12(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11) ".word " _STR12 : : _OP10,"i"(p10),"i"(p11)
#define _INL_13(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12) ".word " _STR13 : : _OP10,"i"(p10),"i"(p11),"i"(p12)
#define _INL_14(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13) ".word " _STR14 : : _OP10,"i"(p10),"i"(p11),"i"(p12),"i"(p13)
#define _INL_15(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14) ".word " _STR15 : : _OP10,"i"(p10),"i"(p11),"i"(p12),"i"(p13),"i"(p14)
#define _INL_16(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15) ".word " _STR16 : : _OP10,"i"(p10),"i"(p11),"i"(p12),"i"(p13),"i"(p14),"i"(p15)
#define _INL_17(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16) ".word " _STR17 : : _OP10,"i"(p10),"i"(p11),"i"(p12),"i"(p13),"i"(p14),"i"(p15),"i"(p16)
#define _INL_18(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17) ".word " _STR18 : : _OP10,"i"(p10),"i"(p11),"i"(p12),"i"(p13),"i"(p14),"i"(p15),"i"(p16),"i"(p17)
#define _INL_19(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18) ".word " _STR19 : : _OP10,"i"(p10),"i"(p11),"i"(p12),"i"(p13),"i"(p14),"i"(p15),"i"(p16),"i"(p17),"i"(p18)
#define _INL_20(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19) ".word " _STR20 : : _OP20
#define _INL_21(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20) ".word " _STR21 : : _OP20,"i"(p20)
#define _INL_22(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21) ".word " _STR22 : : _OP20,"i"(p20),"i"(p21)
#define _INL_23(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22) ".word " _STR23 : : _OP20,"i"(p20),"i"(p21),"i"(p22)
#define _INL_24(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23) ".word " _STR24 : : _OP20,"i"(p20),"i"(p21),"i"(p22),"i"(p23)
#define _INL_25(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24) ".word " _STR25 : : _OP20,"i"(p20),"i"(p21),"i"(p22),"i"(p23),"i"(p24)
#define _INL_26(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25) ".word " _STR26 : : _OP20,"i"(p20),"i"(p21),"i"(p22),"i"(p23),"i"(p24),"i"(p25)
#define _INL_27(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26) ".word " _STR27 : : _OP20,"i"(p20),"i"(p21),"i"(p22),"i"(p23),"i"(p24),"i"(p25),"i"(p26)
#define _INL_28(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27) ".word " _STR28 : : _OP20,"i"(p20),"i"(p21),"i"(p22),"i"(p23),"i"(p24),"i"(p25),"i"(p26),"i"(p27)
#define _INL_29(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28) ".word " _STR29 : : _OP20,"i"(p20),"i"(p21),"i"(p22),"i"(p23),"i"(p24),"i"(p25),"i"(p26),"i"(p27),"i"(p28)
#define _INL_30(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29) ".word " _STR30 : : _OP30
#define _INL_31(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30) ".word " _STR31 : : _OP30,"i"(p30)
#define _INL_32(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31) ".word " _STR32 : : _OP30,"i"(p30),"i"(p31)
#define _INL_33(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32) ".word " _STR33 : : _OP30,"i"(p30),"i"(p31),"i"(p32)
#define _INL_34(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33) ".word " _STR34 : : _OP30,"i"(p30),"i"(p31),"i"(p32),"i"(p33)
#define _INL_35(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34) ".word " _STR35 : : _OP30,"i"(p30),"i"(p31),"i"(p32),"i"(p33),"i"(p34)
#define _INL_36(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35) ".word " _STR36 : : _OP30,"i"(p30),"i"(p31),"i"(p32),"i"(p33),"i"(p34),"i"(p35)
#define _INL_37(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36) ".word " _STR37 : : _OP30,"i"(p30),"i"(p31),"i"(p32),"i"(p33),"i"(p34),"i"(p35),"i"(p36)
#define _INL_38(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37) ".word " _STR38 : : _OP30,"i"(p30),"i"(p31),"i"(p32),"i"(p33),"i"(p34),"i"(p35),"i"(p36),"i"(p37)
#define _INL_39(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38) ".word " _STR39 : : _OP30,"i"(p30),"i"(p31),"i"(p32),"i"(p33),"i"(p34),"i"(p35),"i"(p36),"i"(p37),"i"(p38)
#define _INL_40(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39) ".word " _STR40 : : _OP40
#define _INL_41(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40) ".word " _STR41 : : _OP40,"i"(p40)
#define _INL_42(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41) ".word " _STR42 : : _OP40,"i"(p40),"i"(p41)
#define _INL_43(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42) ".word " _STR43 : : _OP40,"i"(p40),"i"(p41),"i"(p42)
#define _INL_44(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43) ".word " _STR44 : : _OP40,"i"(p40),"i"(p41),"i"(p42),"i"(p43)
#define _INL_45(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44) ".word " _STR45 : : _OP40,"i"(p40),"i"(p41),"i"(p42),"i"(p43),"i"(p44)
#define _INL_46(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45) ".word " _STR46 : : _OP40,"i"(p40),"i"(p41),"i"(p42),"i"(p43),"i"(p44),"i"(p45)
#define _INL_47(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46) ".word " _STR47 : : _OP40,"i"(p40),"i"(p41),"i"(p42),"i"(p43),"i"(p44),"i"(p45),"i"(p46)
#define _INL_48(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47) ".word " _STR48 : : _OP40,"i"(p40),"i"(p41),"i"(p42),"i"(p43),"i"(p44),"i"(p45),"i"(p46),"i"(p47)
#define _INL_49(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48) ".word " _STR49 : : _OP40,"i"(p40),"i"(p41),"i"(p42),"i"(p43),"i"(p44),"i"(p45),"i"(p46),"i"(p47),"i"(p48)
#define _INL_50(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49) ".word " _STR50 : : _OP50
#define _INL_51(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50) ".word " _STR51 : : _OP50,"i"(p50)
#define _INL_52(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51) ".word " _STR52 : : _OP50,"i"(p50),"i"(p51)
#define _INL_53(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52) ".word " _STR53 : : _OP50,"i"(p50),"i"(p51),"i"(p52)
#define _INL_54(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53) ".word " _STR54 : : _OP50,"i"(p50),"i"(p51),"i"(p52),"i"(p53)
#define _INL_55(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54) ".word " _STR55 : : _OP50,"i"(p50),"i"(p51),"i"(p52),"i"(p53),"i"(p54)
#define _INL_56(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55) ".word " _STR56 : : _OP50,"i"(p50),"i"(p51),"i"(p52),"i"(p53),"i"(p54),"i"(p55)
#define _INL_57(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56) ".word " _STR57 : : _OP50,"i"(p50),"i"(p51),"i"(p52),"i"(p53),"i"(p54),"i"(p55),"i"(p56)
#define _INL_58(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57) ".word " _STR58 : : _OP50,"i"(p50),"i"(p51),"i"(p52),"i"(p53),"i"(p54),"i"(p55),"i"(p56),"i"(p57)
#define _INL_59(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58) ".word " _STR59 : : _OP50,"i"(p50),"i"(p51),"i"(p52),"i"(p53),"i"(p54),"i"(p55),"i"(p56),"i"(p57),"i"(p58)
#define _INL_60(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59) ".word " _STR60 : : _OP60
#define _INL_61(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60) ".word " _STR61 : : _OP60,"i"(p60)
#define _INL_62(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61) ".word " _STR62 : : _OP60,"i"(p60),"i"(p61)
#define _INL_63(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62) ".word " _STR63 : : _OP60,"i"(p60),"i"(p61),"i"(p62)
#define _INL_64(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63) ".word " _STR64 : : _OP60,"i"(p60),"i"(p61),"i"(p62),"i"(p63)
#define _INL_65(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64) ".word " _STR65 : : _OP60,"i"(p60),"i"(p61),"i"(p62),"i"(p63),"i"(p64)
#define _INL_66(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65) ".word " _STR66 : : _OP60,"i"(p60),"i"(p61),"i"(p62),"i"(p63),"i"(p64),"i"(p65)
#define _INL_67(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66) ".word " _STR67 : : _OP60,"i"(p60),"i"(p61),"i"(p62),"i"(p63),"i"(p64),"i"(p65),"i"(p66)
#define _INL_68(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67) ".word " _STR68 : : _OP60,"i"(p60),"i"(p61),"i"(p62),"i"(p63),"i"(p64),"i"(p65),"i"(p66),"i"(p67)
#define _INL_69(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68) ".word " _STR69 : : _OP60,"i"(p60),"i"(p61),"i"(p62),"i"(p63),"i"(p64),"i"(p65),"i"(p66),"i"(p67),"i"(p68)
#define _INL_70(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69) ".word " _STR70 : : _OP70
#define _INL_71(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70) ".word " _STR71 : : _OP70,"i"(p70)
#define _INL_72(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71) ".word " _STR72 : : _OP70,"i"(p70),"i"(p71)
#define _INL_73(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72) ".word " _STR73 : : _OP70,"i"(p70),"i"(p71),"i"(p72)
#define _INL_74(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73) ".word " _STR74 : : _OP70,"i"(p70),"i"(p71),"i"(p72),"i"(p73)
#define _INL_75(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74) ".word " _STR75 : : _OP70,"i"(p70),"i"(p71),"i"(p72),"i"(p73),"i"(p74)
#define _INL_76(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75) ".word " _STR76 : : _OP70,"i"(p70),"i"(p71),"i"(p72),"i"(p73),"i"(p74),"i"(p75)
#define _INL_77(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76) ".word " _STR77 : : _OP70,"i"(p70),"i"(p71),"i"(p72),"i"(p73),"i"(p74),"i"(p75),"i"(p76)
#define _INL_78(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77) ".word " _STR78 : : _OP70,"i"(p70),"i"(p71),"i"(p72),"i"(p73),"i"(p74),"i"(p75),"i"(p76),"i"(p77)
#define _INL_79(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78) ".word " _STR79 : : _OP70,"i"(p70),"i"(p71),"i"(p72),"i"(p73),"i"(p74),"i"(p75),"i"(p76),"i"(p77),"i"(p78)
#define _INL_80(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79) ".word " _STR80 : : _OP80
#define _INL_81(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80) ".word " _STR81 : : _OP80,"i"(p80)
#define _INL_82(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81) ".word " _STR82 : : _OP80,"i"(p80),"i"(p81)
#define _INL_83(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82) ".word " _STR83 : : _OP80,"i"(p80),"i"(p81),"i"(p82)
#define _INL_84(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83) ".word " _STR84 : : _OP80,"i"(p80),"i"(p81),"i"(p82),"i"(p83)
#define _INL_85(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84) ".word " _STR85 : : _OP80,"i"(p80),"i"(p81),"i"(p82),"i"(p83),"i"(p84)
#define _INL_86(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85) ".word " _STR86 : : _OP80,"i"(p80),"i"(p81),"i"(p82),"i"(p83),"i"(p84),"i"(p85)
#define _INL_87(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85,p86) ".word " _STR87 : : _OP80,"i"(p80),"i"(p81),"i"(p82),"i"(p83),"i"(p84),"i"(p85),"i"(p86)
#define _INL_88(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85,p86,p87) ".word " _STR88 : : _OP80,"i"(p80),"i"(p81),"i"(p82),"i"(p83),"i"(p84),"i"(p85),"i"(p86),"i"(p87)
#define _INL_89(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85,p86,p87,p88) ".word " _STR89 : : _OP80,"i"(p80),"i"(p81),"i"(p82),"i"(p83),"i"(p84),"i"(p85),"i"(p86),"i"(p87),"i"(p88)
#define _INL_90(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85,p86,p87,p88,p89) ".word " _STR90 : : _OP90
#define _INL_91(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85,p86,p87,p88,p89,p90) ".word " _STR91 : : _OP90,"i"(p90)
#define _INL_92(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85,p86,p87,p88,p89,p90,p91) ".word " _STR92 : : _OP90,"i"(p90),"i"(p91)
#define _INL_93(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85,p86,p87,p88,p89,p90,p91,p92) ".word " _STR93 : : _OP90,"i"(p90),"i"(p91),"i"(p92)
#define _INL_94(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85,p86,p87,p88,p89,p90,p91,p92,p93) ".word " _STR94 : : _OP90,"i"(p90),"i"(p91),"i"(p92),"i"(p93)
#define _INL_95(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85,p86,p87,p88,p89,p90,p91,p92,p93,p94) ".word " _STR95 : : _OP90,"i"(p90),"i"(p91),"i"(p92),"i"(p93),"i"(p94)
#define _INL_96(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85,p86,p87,p88,p89,p90,p91,p92,p93,p94,p95) ".word " _STR96 : : _OP90,"i"(p90),"i"(p91),"i"(p92),"i"(p93),"i"(p94),"i"(p95)
#define _INL_97(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85,p86,p87,p88,p89,p90,p91,p92,p93,p94,p95,p96) ".word " _STR97 : : _OP90,"i"(p90),"i"(p91),"i"(p92),"i"(p93),"i"(p94),"i"(p95),"i"(p96)
#define _INL_98(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85,p86,p87,p88,p89,p90,p91,p92,p93,p94,p95,p96,p97) ".word " _STR98 : : _OP90,"i"(p90),"i"(p91),"i"(p92),"i"(p93),"i"(p94),"i"(p95),"i"(p96),"i"(p97)
#define _INL_99(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85,p86,p87,p88,p89,p90,p91,p92,p93,p94,p95,p96,p97,p98) ".word " _STR99 : : _OP90,"i"(p90),"i"(p91),"i"(p92),"i"(p93),"i"(p94),"i"(p95),"i"(p96),"i"(p97),"i"(p98)
/* ============================================================================
* AST BUILDERS — assemble a complete inline-asm block
* ============================================================================
*
* A complete GCC inline-asm statement has up to 4 sections separated by `:`:
*
* asm volatile ( "code" : OUTPUTS : INPUTS : CLOBBERS );
*
* Every section-builder below prepends the `:` separator that GCC requires,
* so you can compose them inline without thinking about punctuation. The
* master `asm_block(...)` then wraps the four sections in `asm volatile (...)`.
*
* asm_block(
* asm_code( "..." ),
* asm_out ( "=r"(x), "+m"(y) ), // optional
* asm_in ( "r"(a), "m"(b) ), // optional
* asm_clb ( "$8", "memory" ) // optional
* );
*
* Common idioms (kept for back-compat / terseness):
*
* asm_blob(asm_inline(...), asm_clobber(...)) // 2-section, no I/O
* asm_block(asm_inline(...), , , ) // 4-section, empty
*/
/* `asm_code` is a passthrough — it does NOT prepend a colon, since the code
* section is always the first (no separator needed before it). The format
* string + `"i"(...)` operand list are produced by `asm_inline(...)` and
* just pass through unchanged. */
#define asm_code(...) __VA_ARGS__
/* `asm_out` prepends `:` — separates code/outputs/inputs/clobbers */
#define asm_out(...) : __VA_ARGS__
/* `asm_in` prepends `:` */
#define asm_in(...) : __VA_ARGS__
/* `asm_clb` prepends `:` */
#define asm_clb(...) : __VA_ARGS__
/* `asm_clobber` is the legacy single-section name. Kept for existing
* call-sites that put inputs *before* clobbers and want both as one colon-
* prefixed block (i.e. the user wrote `: "r"(x) ... : "..."` by hand). */
#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`.
*
* Result is a 2-colon body WITHOUT the final clobber section:
* ".word %c0, %c1, ..." : : "i"(p0), "i"(p1)
* |----- code -----| |--- empty ---| |------- inputs -------|
*
* Use it inside `asm volatile( ... )` like so:
*
* asm volatile(
* asm_inline(w0, w1, w3)
* : clobbers
* )
*
* which expands to:
*
* asm volatile(
* ".word %c0, %c1, %c2" : : "i"(w0), "i"(w1), "i"(w2)
* : "$2", "$8", ...
* )
*
* 3 colons total. Always valid. */
#define asm_inline(...) m_expand(glue(_INL_, _ASM_COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__))
/* reg_str(n) — Stringify an integer register id into the GCC asm
* string form (e.g. 12 → "$12"). Use this anywhere GCC's parser
* expects a literal string identifying a register: clobber lists,
* asm templates, etc. The two-level macro is the standard preprocessor
* idiom for forcing one level of expansion before stringify — without
* it, `#n` would stringify the macro name `R_T4` to `"R_T4"` instead
* of expanding `R_T4` to its value first.
*
* For declaring a register variable bound to a specific GPR, use the
* `rgcc(n)` bundle from gcc_asm.h instead — it adds the `__asm__()`
* qualifier around the string.
*
* register V3_S2* p0 __asm__(reg_str(R_T4)) = ...; // verbose
* register V3_S2* p0 rgcc(R_T4) = ...; // bundled
*
* asm volatile("nop" : : : reg_str(R_RA), "memory"); // clobber list */
#define reg_str_(n) "$" #n
#define reg_str(n) reg_str_(n)
/* ------------------------------------------------------------------------ *
* rgcc(n) — GCC-specific bundle for register-variable declarations.
*
* Produces `__asm__(reg_str(tmpl(n, Code)))` at expansion time. The
* `tmpl(n, Code)` indirection derives the preprocessor-visible `_Code`
* form from the enum name (which the preprocessor can't expand on
* its own). So a call like
*
* register V3_S2* p rgcc(R_T4) = verts[0].ptr;
*
* expands (via tmpl) to
*
* register V3_S2* p __asm__(reg_str(R_T4_Code))
* = verts[0].ptr;
*
* which (via reg_str) becomes
*
* register V3_S2* p __asm__("$12") = verts[0].ptr;
*
* Why bundle the `__asm__()` wrapper?
* - The integer R_T4 (= 12, via R_T4_Code) is the canonical truth.
* - The string "$12" is derived from it via reg_str, so they
* cannot drift apart.
* - Spelling `__asm__(reg_str(R_T4_Code))` at every call site is
* noise. `rgcc(R_T4)` says what you mean.
*
* The two-level form (rgcc_/rgcc) is the standard preprocessor idiom
* for forcing one level of expansion before the bundle's `__asm__`
* token is written; without it, `rgcc(R_T4)` would expand to
* `__asm__(reg_str(tmpl(R_T4, Code)))` but the inner `tmpl(R_T4, Code)`
* would token-paste prematurely.
*
* Layering: reg_str lives in dsl.h (the integer-to-string primitive,
* compiler-agnostic in name). tmpl lives in dsl.h (the token-paste
* glue). rgcc lives here (gcc_asm.h) because the `__asm__` keyword
* is GCC-specific. Anyone porting to a different compiler's asm
* dialect overrides rgcc, and the integer→string derivation in
* reg_str can be retargeted in one place.
*
* For clobber lists and asm-template strings, use the bare
* `reg_str(R_T4_Code)` — you don't want __asm__() there, you just
* want the string.
* ------------------------------------------------------------------------ */
#define rgcc_(n) __asm__(reg_str(tmpl(n, Code)))
#define rgcc(n) rgcc_(n)
/* rgcc_ref(n) — GCC operand-reference form "%N". Not currently used
* by the placeholder-pun macros (the .word bodies are fully baked
* at compile time and have no runtime operand references), but kept
* here for completeness in case a future asm template needs to refer
* to a runtime input by position. Mirror of rgcc but produces "%N"
* instead of "$N". */
#define rgcc_ref_(n) "%" #n
#define rgcc_ref(n) rgcc_ref_(n)
#pragma endregion Cruft
+74 -66
View File
@@ -260,7 +260,7 @@ enum {
enum { _C2_OPS_ = 0
, op_lwc2 = 0x32 /* Load Word to Coprocessor 2 (GTE) */
, op_lwc2 = 0x32 /* Load Word to Coprocessor 2 (GTE) */
, op_swc2 = 0x3A /* Store Word from Coprocessor 2 (GTE) */
};
@@ -269,7 +269,16 @@ enum { _C2_OPS_ = 0
* - sub: cop_mf (0x00) for cfc2, cop_mt (0x04) for ctc2
* - rt: GPR source/dest
* - rd: COP2 control register index (0..31) */
#define enc_cop2_tx(sub, rt, rd) (enc_op(op_cop2) | enc_rs(sub) | enc_rt(rt) | enc_rd(rd))
#define enc_gte_tx(sub, rt, rd) (enc_op(op_cop2) | enc_rs(sub) | enc_rt(rt) | enc_rd(rd))
// #define gte_mt(rt, rd) enc_gte_tx(cop_mt, (rt), (rd)) /* Move GPR (rt) to GTE Control Register (rd) */
// #define gte_mf(rt, rd) enc_gte_tx(cop_mf, (rt), (rd)) /* Move GTE Control Register (rd) to GPR (rt) */
/* Explicit GTE Data vs Control Register Transfers */
#define gte_mf(rt, rd) enc_gte_tx(0x00, (rt), (rd)) /* Move from GTE Data Reg (e.g. MAC0, OTZ) */
#define gte_cf(rt, rd) enc_gte_tx(0x02, (rt), (rd)) /* Move from GTE Control Reg */
#define gte_mt(rt, rd) enc_gte_tx(0x04, (rt), (rd)) /* Move to GTE Data Reg (e.g. VXY0) */
#define gte_ct(rt, rd) enc_gte_tx(0x06, (rt), (rd)) /* Move to GTE Control Reg (e.g. Matrices) */
/* COP2 Data Load (lwc2): `lwc2 rt, off(rs)`
* Layout: [op_lwc2:6][rs:5][rt:5][imm:16]
@@ -278,8 +287,9 @@ enum { _C2_OPS_ = 0
* - imm: signed 16-bit offset
* NOTE: When `rs` is a runtime register, the encoding cannot be pre-baked
* into a .word — use the string-style `gte_load_v0` macro below instead. */
#define enc_cop2_lwc2(rt, base, off) enc_i(op_lwc2, (base), (rt), (off))
#define enc_cop2_swc2(rt, base, off) enc_i(op_swc2, (base), (rt), (off))
#define enc_gte_lw(rt, base, off) enc_i(op_lwc2, (base), (rt), (off))
/* Store Word */
#define enc_gte_sw(rt, base, off) enc_i(op_swc2, (base), (rt), (off))
/* Semantic aliases for the COP2 data load/store. The `c2` in `lwc2`/
* `swc2` is redundant when we're already inside the `gte_` namespace.
@@ -287,8 +297,8 @@ enum { _C2_OPS_ = 0
* gte_sw rt, base, off → swc2 rt, off(base)
* For the typical user-facing vector-level load (xy + z as two
* instructions), use the higher-level `gte_load_vN` macros below. */
#define gte_lw(rt, base, off) enc_cop2_lwc2(rt, base, off)
#define gte_sw(rt, base, off) enc_cop2_swc2(rt, base, off)
#define gte_lw(rt, base, off) enc_gte_lw(rt, base, off)
#define gte_sw(rt, base, off) enc_gte_sw(rt, base, off)
/* GTE Command Format (The math engine trigger)
* Opcode is always MIPS_OP_COP2, RS is always 1 (CO).
@@ -304,12 +314,12 @@ enum { _C2_OPS_ = 0
#define gte_cmd_base (enc_op(op_cop2) | (1 << 25))
/* Per-field encoders. Each one does (value & mask) << shift on its own. */
#define enc_gte_sf(sf) (((sf) & gte_mask_sf ) << gte_shift_sf )
#define enc_gte_mx(mx) (((mx) & gte_mask_mx ) << gte_shift_mx )
#define enc_gte_v(v) (((v) & gte_mask_v ) << gte_shift_v )
#define enc_gte_cv(cv) (((cv) & gte_mask_cv ) << gte_shift_cv )
#define enc_gte_lm(lm) (((lm) & gte_mask_lm ) << gte_shift_lm )
#define enc_gte_cmd(cmd) (((cmd) & gte_mask_cmd) << gte_shift_cmd)
#define enc_gte_sf(sf) (((sf) & gte_mask_sf ) << gte_shift_sf )
#define enc_gte_mx(mx) (((mx) & gte_mask_mx ) << gte_shift_mx )
#define enc_gte_v(v) (((v) & gte_mask_v ) << gte_shift_v )
#define enc_gte_cv(cv) (((cv) & gte_mask_cv ) << gte_shift_cv )
#define enc_gte_lm(lm) (((lm) & gte_mask_lm ) << gte_shift_lm )
#define enc_gte_cmd(cmd) (((cmd) & gte_mask_cmd) << gte_shift_cmd)
/* Composite: all six GTE fields + the COP2/CO base. */
#define enc_gte_cmdw(sf, mx, v, cv, lm, cmd) ( \
@@ -331,7 +341,7 @@ enum { _C2_OPS_ = 0
*
* Decomposition (per the `enc_gte_<field>` definitions above):
* gte_cmdw_<name> = gte_cmd_base | enc_gte_cmd(<cmd>)
*
* The SF/MX/V/CV/LM fields are all zero in the common cases (standard
* rotation-matrix, no scaling factor, V0 vector, translation vector,
* no clamp), so the only varying bits are the `cmd` field.
@@ -400,12 +410,12 @@ enum {
GTE_Z_Offset = 4
};
#define gte_lwc2_v0(base) enc_cop2_lwc2(gte_in_v0_xy, (base), 0)
#define gte_lwc2_v0z(base) enc_cop2_lwc2(gte_in_v0_z, (base), GTE_Z_Offset)
#define gte_lwc2_v1(base) enc_cop2_lwc2(gte_in_v1_xy, (base), 0)
#define gte_lwc2_v1z(base) enc_cop2_lwc2(gte_in_v1_z, (base), GTE_Z_Offset)
#define gte_lwc2_v2(base) enc_cop2_lwc2(gte_in_v2_xy, (base), 0)
#define gte_lwc2_v2z(base) enc_cop2_lwc2(gte_in_v2_z, (base), GTE_Z_Offset)
#define gte_lw_v0(base) enc_gte_lw(gte_in_v0_xy, (base), 0)
#define gte_lw_v0z(base) enc_gte_lw(gte_in_v0_z, (base), GTE_Z_Offset)
#define gte_lw_v1(base) enc_gte_lw(gte_in_v1_xy, (base), 0)
#define gte_lw_v1z(base) enc_gte_lw(gte_in_v1_z, (base), GTE_Z_Offset)
#define gte_lw_v2(base) enc_gte_lw(gte_in_v2_xy, (base), 0)
#define gte_lw_v2z(base) enc_gte_lw(gte_in_v2_z, (base), GTE_Z_Offset)
/* gte_load_vN(r_ptr, base) — placeholder-punned lwc2 loaders
*
@@ -444,26 +454,23 @@ enum {
*
* The `asm_clobber(...)` helper from gcc_asm.h prepends the colon that
* starts the clobbers section. */
#define gte_load_v0(r_ptr, base) \
asm volatile( \
asm_inline( gte_lwc2_v0(base), gte_lwc2_v0z(base) ) \
, "r"(r_ptr) \
asm_clobber( reg_str(R_V0_Code), reg_str(R_T0_Code), reg_str(R_T1_Code), reg_str(R_RA_Code), "memory" ) \
)
#define gte_load_v0(r_ptr, base) asm volatile( \
asm_words( gte_lw_v0(base), gte_lw_v0z(base) ) \
asm_rpins, r_use(r_ptr) \
asm_clobber: rlit(R_V0_Code), rlit(R_T0_Code), rlit(R_T1_Code), rlit(R_RA_Code), clb_mem_drain \
)
#define gte_load_v1(r_ptr, base) \
asm volatile( \
asm_inline( gte_lwc2_v1(base), gte_lwc2_v1z(base) ) \
, "r"(r_ptr) \
asm_clobber( reg_str(R_V0_Code), reg_str(R_T0_Code), reg_str(R_T1_Code), reg_str(R_RA_Code), "memory" ) \
)
#define gte_load_v1(r_ptr, base) asm volatile( \
asm_words( gte_lw_v1(base), gte_lw_v1z(base) ) \
asm_rpins, r_use(r_ptr) \
asm_clobber: rlit(R_V0_Code), rlit(R_T0_Code), rlit(R_T1_Code), rlit(R_RA_Code), clb_mem_drain \
)
#define gte_load_v2(r_ptr, base) \
asm volatile( \
asm_inline( gte_lwc2_v2(base), gte_lwc2_v2z(base) ) \
, "r"(r_ptr) \
asm_clobber( reg_str(R_V0_Code), reg_str(R_T0_Code), reg_str(R_T1_Code), reg_str(R_RA_Code), "memory" ) \
)
#define gte_load_v2(r_ptr, base) asm volatile( \
asm_words( gte_lw_v2(base), gte_lw_v2z(base) ) \
asm_rpins, r_use(r_ptr) \
asm_clobber: rlit(R_V0_Code), rlit(R_T0_Code), rlit(R_T1_Code), rlit(R_RA_Code), clb_mem_drain \
)
/* gte_load_v0v1v2(p0, p1, p2, b0, b1, b2) — the canonical prelude to gte_cmd_rtpt.
*
@@ -477,14 +484,15 @@ enum {
* gte_load_v0v1v2(p0, p1, p2, R_T4, R_T5, R_T6);
* gte_rtpt();
*/
#define gte_load_v0v1v2(p0, p1, p2, b0, b1, b2) \
asm volatile( \
asm_inline( gte_lwc2_v0(b0), gte_lwc2_v0z(b0), \
gte_lwc2_v1(b1), gte_lwc2_v1z(b1), \
gte_lwc2_v2(b2), gte_lwc2_v2z(b2) ) \
, "r"(p0), "r"(p1), "r"(p2) \
asm_clobber( reg_str(R_V0_Code), reg_str(R_T0_Code), reg_str(R_T1_Code), reg_str(R_RA_Code), "memory" ) \
)
#define gte_load_v0v1v2(p0, p1, p2, b0, b1, b2) asm volatile( \
asm_words( \
gte_lw_v0(b0), gte_lw_v0z(b0), \
gte_lw_v1(b1), gte_lw_v1z(b1), \
gte_lw_v2(b2), gte_lw_v2z(b2) ) \
asm_rpins \
, r_use(p0), r_use(p1), r_use(p2) \
asm_clobber: rlit(R_V0_Code), rlit(R_T0_Code), rlit(R_T1_Code), rlit(R_RA_Code), clb_mem_drain \
)
/**
* @brief Rotate, Translate and Perspective Triple (23 cycles)
@@ -514,8 +522,8 @@ enum {
*/
#define gte_rtpt() \
asm volatile( \
asm_inline( nop, nop, gte_cmdw_rtpt ) \
asm_clobber( clb_system ) \
asm_words( nop, nop, gte_cmdw_rtpt ) \
asm_clobber: clb_system \
)
#define gte_rtpt_ori() \
@@ -553,10 +561,10 @@ enum {
* they need to survive across the call (NCLIP writes MAC0 only; it
* is purely a sign-of-double-product computation on SXY0..2).
*/
#define gte_nclip() \
asm volatile( \
asm_inline( nop, nop, gte_cmdw_nclip ) \
asm_clobber( clb_system ) \
#define gte_nclip() \
asm volatile( \
asm_words( nop, nop, gte_cmdw_nclip ) \
asm_clobber: clb_system \
)
#define gte_stotz(r0) __asm__ volatile("swc2 $7, 0( %0 )" : : "r"(r0) : "memory")
@@ -622,20 +630,20 @@ enum {
* get stale-RT2x/RT3x artifacts in RTPS/RTPT/MVMVA output.
*/
#define asm_gte_matrix_set_rotation(r0) \
asm volatile( \
asm_inline( \
load_imm(R_T4, r0, 0), \
load_imm(R_T5, r0, 4), \
enc_cop2_tx(cop_mt, R_T4, 0), \
enc_cop2_tx(cop_mt, R_T5, 1), \
load_imm(R_T4, r0, 8), \
load_imm(R_T5, r0, 12), \
load_imm(R_T6, r0, 16), \
enc_cop2_tx(cop_mt, R_T4, 2), \
enc_cop2_tx(cop_mt, R_T5, 3), \
enc_cop2_tx(cop_mt, R_T6, 4) \
asm volatile( \
asm_words( \
load_word(R_T5, R_T4, 0) \
, load_word(R_T6, R_T4, 4) \
, gte_mt( R_T5, 0) \
, gte_mt( R_T6, 1) \
, load_word(R_T5, R_T4, 8) \
, load_word(R_T6, R_T4, 12) \
, load_word(R_T4, R_T4, 16) \
, gte_mt( R_T5, 2) \
, gte_mt( R_T6, 3) \
, gte_mt( R_T4, 4) \
) \
asm_clobber( clb_system, reg_str(R_T4_Code), reg_str(R_T5_Code), reg_str(R_T6_Code) ) \
: \
: "r"(r0) \
, r_use(r0) \
asm_clobber: clb_system, rlit(R_T4_Code), rlit(R_T5_Code), rlit(R_T6_Code) \
)
+148
View File
@@ -0,0 +1,148 @@
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "dsl.h"
# include "gcc_asm.h"
# include "mips.h"
# include "gte.h"
# include "memory.h"
#endif
/* R_T8 is our dedicated Tape Pointer (TP) */
#define R_TP R_T8
#define R_TP_Code R_T8_Code
/* The 'Yield' sequence for CodeBlobs */
#define mips_yield \
load_word(R_T9, R_TP, 0) \
, add_ui(R_TP, R_TP, 4) \
, jump_reg(R_T9) \
, nop
/* The 'Exit' Atom */
internal Code CodeBlob_(tape_exit) { jump_reg(rret_addr), nop };
typedef Slice_(U4);
FI_ void tape_run(Slice_U4 tape, B1** r_prim_cursor, void* face_cursor, void* vert_base, void* ot_base) {
register U4* tp rgcc(R_TP) = tape.ptr;
register B1* pcur rgcc(R_T7) = *r_prim_cursor;
register void* r_t4 rgcc(R_T4) = face_cursor;
register void* r_t5 rgcc(R_T5) = vert_base;
register void* r_t6 rgcc(R_T6) = ot_base;
asm volatile(
"lw $25, 0(%0);"
"addiu %0, %0, 4;"
"jalr $25;"
"nop;"
: "+r"(tp), "+r"(pcur), "+r"(r_t4), "+r"(r_t5), "+r"(r_t6)
:
: "at", "v0", "v1", "t0", "t1", "t2", "t3", "t9", "ra", "memory"
);
*r_prim_cursor = pcur;
}
typedef Struct_(TapeBuilder) {FArena* arena;};
FI_ TapeBuilder tb_begin(FArena* arena) {return (TapeBuilder){ arena };}
I_ void tb_emit(TapeBuilder* tb, Code* atom) {
U4* slot = farena_push_type(tb->arena, U4);
slot[0] = (U4)atom;
}
I_ Slice_U4 tb_end(TapeBuilder* tb) {
tb_emit(tb, code_tape_exit);
return (Slice_U4){ (U4*)tb->arena->start, tb->arena->used / 4 };
}
internal Code CodeBlob_(atom_set_gte_world) {
/* Pop matrix address from tape into R_T3 ($11) */
load_word(R_T3, R_TP, 0),
add_ui(R_TP, R_TP, 4),
/* Load 3x3 Rotation + 3x1 Translation from R_T3 into GTE CONTROL Regs (ctc2) */
load_word(R_T0, R_T3, 0), load_word(R_T1, R_T3, 4),
gte_ct(R_T0, gte_cr_RT11), gte_ct(R_T1, gte_cr_RT12),
load_word(R_T0, R_T3, 8), load_word(R_T1, R_T3, 12), load_word(R_T2, R_T3, 16),
gte_ct(R_T0, gte_cr_RT13), gte_ct(R_T1, gte_cr_RT21), gte_ct(R_T2, gte_cr_RT22),
load_word(R_T0, R_T3, 20), load_word(R_T1, R_T3, 24), load_word(R_T2, R_T3, 28),
gte_ct(R_T0, gte_cr_TRX), gte_ct(R_T1, gte_cr_TRY), gte_ct(R_T2, gte_cr_TRZ),
mips_yield
};
internal Code CodeBlob_(atom_floor_tri) {
/* 1. Load 3 indices from $t4 */
load_half_u(R_T0, R_T4, 0),
load_half_u(R_T1, R_T4, 2),
load_half_u(R_T2, R_T4, 4),
/* 2. Load Vertices: Addr = Base + (idx * 8). Write to GTE DATA Regs (mtc2) */
shift_ll(R_AT, R_T0, 3), add_u(R_AT, R_AT, R_T5),
load_word(R_V0, R_AT, 0), load_word(R_V1, R_AT, 4),
gte_mt(R_V0, C2_VXY0), gte_mt(R_V1, C2_VZ0),
shift_ll(R_AT, R_T1, 3), add_u(R_AT, R_AT, R_T5),
load_word(R_V0, R_AT, 0), load_word(R_V1, R_AT, 4),
gte_mt(R_V0, C2_VXY1), gte_mt(R_V1, C2_VZ1),
shift_ll(R_AT, R_T2, 3), add_u(R_AT, R_AT, R_T5),
load_word(R_V0, R_AT, 0), load_word(R_V1, R_AT, 4),
gte_mt(R_V0, C2_VXY2), gte_mt(R_V1, C2_VZ2),
/* 3. RTPT + NCLIP */
nop, nop, gte_cmdw_rtpt,
nop, nop, gte_cmdw_nclip,
nop, nop, /* Wait for NCLIP to finish */
/* 4. Check NCLIP.
If MAC0 <= 0 (Backface), branch to end.
Target is 28 instructions past the delay slot. */
gte_mf(R_T0, C2_MAC0),
branch_le_zero(R_T0, 28),
nop, /* <--- DELAY SLOT (Index 0) */
/* 5. Store Primitive Data */
/* 1 */ store_word(R_0, R_T7, 0),
/* 2 */ load_ui(R_AT, 0x20FF), /* High: Code 0x20 + Color R:FF */
/* 3 */ or_i(R_AT, R_AT, 0xFFFF), /* Low: Color G:FF, B:FF */
/* 4 */ store_word(R_AT, R_T7, 4),
/* 5 */ enc_gte_sw(C2_SXY0, R_T7, 8),
/* 6 */ enc_gte_sw(C2_SXY1, R_T7, 12),
/* 7 */ enc_gte_sw(C2_SXY2, R_T7, 16),
/* 6. OT Insertion with Bounds Checking */
/* 8 */ nop,
/* 9 */ nop,
/* 10 */ enc_gte_cmd(0x2D), /* AVSZ3 */
/* 11 */ nop, /* Wait for AVSZ3 */
/* 12 */ nop, /* Wait for AVSZ3 */
/* 13 */ gte_mf(R_T1, C2_OTZ), /* T1 = Depth index */
/* Bounds Check: OTZ < 2048 */
/* 14 */ load_ui(R_AT, 2048),
/* 15 */ slt_u(R_AT, R_T1, R_AT), /* AT = (OTZ < 2048) ? 1 : 0 */
/* 16 */ branch_equal(R_AT, R_0, 11), /* If AT == 0, skip to end (11 instrs past delay) */
/* 17 */ nop, /* <--- DELAY SLOT (Index 0 for Bounds branch) */
/* 18 (1) */ shift_ll(R_T1, R_T1, 2),
/* 19 (2) */ add_u(R_T1, R_T1, R_T6), /* T1 = &OrderingTable[OTZ] */
/* 20 (3) */ load_word(R_AT, R_T1, 0), /* AT = current head */
/* 21 (4) */ store_word(R_AT, R_T7, 0), /* prim->next = head */
/* Create Tag in AT: Len 4 (0x04) in top 8 bits, T7 in bottom 24 */
/* 22 (5) */ shift_ll(R_AT, R_T7, 8),
/* 23 (6) */ shift_lr(R_AT, R_AT, 8), /* AT = T7 & 0x00FFFFFF */
/* 24 (7) */ load_ui(R_V0, 0x0400), /* V0 = 0x04000000 */
/* 25 (8) */ or_u(R_AT, R_AT, R_V0), /* AT = Tag */
/* 26 (9) */ store_word(R_AT, R_T1, 0), /* OrderingTable[OTZ] = Tag */
/* 27 (10) */ add_ui(R_T7, R_T7, 20), /* Advance Prim Cursor (5 words) */
/* 7. Yield */
/* 28 (11) */ add_ui(R_T4, R_T4, 8), /* Advance Face Cursor (4 * S2 = 8 bytes) */
mips_yield
};
+4 -4
View File
@@ -10,7 +10,7 @@
assert((point) <= (end)); \
} while(0)
inline U4 align_pow2(U4 x, U4 b) {
I_ U4 align_pow2(U4 x, U4 b) {
assert(b != 0);
assert((b & (b - 1)) == 0); // Check power of 2
return ((x + b - 1) & (~(b - 1)));
@@ -54,9 +54,9 @@ FI_ B4 mem_zero (U4 dest, U4 len) { if(dest == 0){return fa
#pragma region Slice
typedef unsigned char UTF8;
typedef Struct_(Str8) { UTF8* ptr; U4 len; };
typedef Struct_(Slice_Str8) { Str8* ptr; U4 len; };
#define txt(string_literal) (Str8){ (UTF8*) string_literal, S_(string_literal) - 1 }
typedef Struct_(Str8) { UTF8* ptr; U4 len; };
typedef Struct_(Slice_Str8) { Str8* ptr; U4 len; };
#define slit(string_literal) (Str8){ (UTF8*) string_literal, S_(string_literal) - 1 }
typedef Struct_(Slice) { U4 ptr, len; }; // Untyped Slice
FI_ Slice slice_ut_(U4 ptr, U4 len) { return (Slice){ptr, len}; }
+81 -82
View File
@@ -18,7 +18,7 @@
* R_T7 = R_T7_Code, // in the enum
*
* User code should always reference the enum form (`R_T4`) at arithmetic
* sites and let `reg_str(R_T4_Code)` / `rgcc(R_T4)` handle the stringify
* sites and let `rlit(R_T4_Code)` / `rgcc(R_T4)` handle the stringify
* cases — never write the bare number `12`.
* ============================================================================ */
#define R_0_Code 0
@@ -80,6 +80,7 @@ enum {
, rtmp_2 = R_T2 /* Temporary (Caller saved) */
, rtmp_3 = R_T3 /* Temporary (Caller saved) */
, rtmp_4 = R_T4 /* Temporary (Caller saved) — common GTE base pointer */
, rtmp_9 = R_T9 /* Temporary (Caller saved) — common GTE base pointer */
, rstatic_0 = R_S0 /* Static (Callee saved, preserved across calls) */
, rstatic_1 = R_S1
, rstatic_2 = R_S2
@@ -165,7 +166,7 @@ enum {
/* --- Coprocessor 0 (System Control & Exceptions) --- */
, cop_mf = 0x00 /* Move From Coprocessor */
, cop_mt = 0x04 /* Move To Coprocessor */
, cop_mt = 0x04 /* Move To Coprocessor */
};
@@ -231,7 +232,7 @@ enum { _BitOffsets = 0
* shift_ll(rd, rt, shamt) → sll rd, rt, shamt
* jump_reg(rs) → jr rs
* jump_link(rs, rd) → jalr rs (link in rd, default $ra)
* nop → sll $0, $0, 0
* nop → sll $0, $0, 0
*/
#define load_word(rt, base, off) enc_i(op_lw, (base), (rt), (off))
#define load_byte(rt, base, off) enc_i(op_lb, (base), (rt), (off))
@@ -240,10 +241,17 @@ enum { _BitOffsets = 0
#define load_half_u(rt, base, off) enc_i(op_lhu, (base), (rt), (off))
#define store_word(rt, base, off) enc_i(op_sw, (base), (rt), (off))
#define add_ui(rt, rs, imm) enc_i(op_addiu, (rs), (rt), (imm))
#define andi_op(rt, rs, imm) enc_i(op_andi, (rs), (rt), (imm))
#define ori_op(rt, rs, imm) enc_i(op_ori, (rs), (rt), (imm))
#define xori_op(rt, rs, imm) enc_i(op_xori, (rs), (rt), (imm))
#define lui_op(rt, imm) enc_i(op_lui, R_0, (rt), (imm))
#define and_si(rt, rs, imm) enc_i(op_andi, (rs), (rt), (imm))
#define or_i(rt, rs, imm) enc_i(op_ori, (rs), (rt), (imm))
#define xor_i(rt, rs, imm) enc_i(op_xori, (rs), (rt), (imm))
#define load_ui(rt, imm) enc_i(op_lui, R_0, (rt), (imm))
/* Logic Opcodes */
#define and_u(rd, rs, rt) enc_r(op_special, (rs), (rt), (rd), 0, fc_and)
#define or_u(rd, rs, rt) enc_r(op_special, (rs), (rt), (rd), 0, fc_or)
#define xor_u(rd, rs, rt) enc_r(op_special, (rs), (rt), (rd), 0, fc_xor)
#define nor_u(rd, rs, rt) enc_r(op_special, (rs), (rt), (rd), 0, fc_nor)
/* Shift family (R-type). shift_ll/lr/ra: `sll rd, rt, shamt` */
#define shift_ll(rd, rt, shamt) enc_r(op_special, R_0, (rt), (rd), (shamt), fc_sll)
@@ -320,19 +328,20 @@ enum { _BitOffsets = 0
* branch_le_zero rs, off → blez rs, off
* branch_ge_zero rs, off → bgez rs, off
* (For `bgez`, the opcode is `op_bcond` with rt=1 to invert the bltz condition.) */
#define branch_equal(rs, rt, off) enc_i(op_beq, (rs), (rt), (off))
#define branch_ne(rs, rt, off) enc_i(op_bne, (rs), (rt), (off))
#define branch_lt_zero(rs, off) enc_i(op_bltz, R_0, (rs), (off))
#define branch_gt_zero(rs, off) enc_i(op_bgtz, R_0, (rs), (off))
#define branch_le_zero(rs, off) enc_i(op_blez, R_0, (rs), (off))
#define branch_ge_zero(rs, off) enc_i(op_bcond, R_0, (rs), (1u << 16) | ((off) & 0xFFFF))
#define branch_lt_zero(rs, off) enc_i(op_bcond, (rs), R_0, (off)) /* bltz is bcond with rt=0 */
#define branch_ge_zero(rs, off) enc_i(op_bcond, (rs), 1, (off)) /* bgez is bcond with rt=1 */
#define branch_le_zero(rs, off) enc_i(op_blez, (rs), R_0, (off)) /* blez has its own opcode, rt=0 */
#define branch_gt_zero(rs, off) enc_i(op_bgtz, (rs), R_0, (off)) /* bgtz has its own opcode, rt=0 */
/* --- System (kernel) instructions --- */
#define syscall() enc_r(op_special, R_0, R_0, R_0, 0, fc_syscall)
#define breakpoint() enc_r(op_special, R_0, R_0, R_0, 0, fc_break)
/* --- Shift-amount alias (matches the gas convention `\p3 = shamt`) --- */
#define shamt(rd, rt, n) shift_ll(rd, rt, n)
#define shift_amount(rd, rt, n) shift_ll(rd, rt, n)
/* nop — canonical sll $0, $0, 0 */
#define nop shift_ll(rdiscard, rdiscard, 0)
@@ -360,48 +369,44 @@ enum { _BitOffsets = 0
*
* Statement-level (not expression-level): emits its own `asm volatile(...)`.
*/
#define load_imm_2w(rt, imm) do { \
U4 _li2_imm_ = (U4)(imm); \
U4 _li2_lo_ = _li2_imm_ & 0xFFFFU; \
U4 _li2_hi_ = _li2_imm_ >> 16; \
if (_li2_lo_ <= 0x7FFFU) { \
asm volatile( \
asm_inline(lui_op((rt), _li2_hi_), \
add_si((rt), (rt), (S2)(U2)_li2_lo_)) \
asm_clobber(reg_str(R_AT_Code), "memory") \
); \
} \
else { \
asm volatile( \
asm_inline(lui_op((rt), _li2_hi_), \
ori_op((rt), (rt), (U2)_li2_lo_)) \
asm_clobber(reg_str(R_AT_Code), "memory") \
); \
} \
#define load_imm_2w(rt, imm) do { \
if (u4_low(imm) <= 0x7FFFU) { \
asm volatile( \
asm_words(load_ui((rt), u4_hi(imm), \
add_si((rt), (rt), (S2)C_(U2,u4_lo(imm))) \
asm_clobber: rlit(R_AT_Code), clb_mem_drain \
); \
} \
else { \
asm volatile(asm_words( \
load_ui((rt), u4_hi(imm)), \
or_i((rt), (rt), C_(U2,u4_lo(imm)) \
asm_clobber: rlit(R_AT_Code), clb_mem_drain \
); \
} \
} while (0)
/* load_imm_2w_ori — force the `lui` + `ori` form regardless of lo16 sign.
* Use when you specifically need zero-extension in the lo half. */
#define load_imm_2w_ori(rt, imm) do { \
U4 _li2o_imm_ = (U4)(imm); \
asm volatile( \
asm_inline(lui_op((rt), _li2o_imm_ >> 16), \
ori_op((rt), (rt), (U2)(_li2o_imm_ & 0xFFFFU))) \
asm_clobber(reg_str(R_AT_Code), "memory") \
); \
#define load_imm_2w_ori(rt, imm) do { \
asm volatile( \
asm_words(load_ui((rt), u4_lo(imm)), \
or_i((rt), (rt), C_(U2,u4_hi(imm))) ) \
asm_clobber: rlit(R_AT_Code), clb_mem_drain \
); \
} while (0)
/* load_imm_2w_addi — force the `lui` + `addi` form regardless of lo16 sign.
* Use when you know sign-extension is fine (e.g. lo16 is treated as
* signed downstream) and you want a smaller effective instruction
* (the assembler/MIPS hardware will sign-extend the imm16). */
#define load_imm_2w_addi(rt, imm) do { \
U4 _li2a_imm_ = (U4)(imm); \
asm volatile( \
asm_inline(lui_op((rt), _li2a_imm_ >> 16), \
add_si((rt), (rt), (S2)(U2)(_li2a_imm_ & 0xFFFFU))) \
asm_clobber(reg_str(R_AT_Code), "memory") \
); \
#define load_imm_2w_addi(rt, imm) do { \
/*U4 _li2a_imm_ = (U4)(imm);*/ \
asm volatile(asm_words( \
lui_op((rt), u4_lo(imm)), \
add_si((rt), (rt), (S2)C_(U2,u4_hi(imm))) ) \
asm_clobber: rlit(R_AT_Code), clb_mem_drain \
); \
} while (0)
/* load_imm rt, imm — true `li` semantics (assembler `li` pseudo)
@@ -424,40 +429,37 @@ enum { _BitOffsets = 0
* but that path is unusual (load_imm is most useful with literal
* addresses and magic numbers). */
#define load_imm(rt, imm) do { \
if (__builtin_constant_p(imm) && ((U4)(imm) <= 0x7FFFU)) { \
if (cexpr_(imm) && ((imm) <= 0x7FFFU)) { \
/* Small positive: addi rt, $0, imm */ \
asm volatile( \
asm_inline(add_si((rt), R_0, (imm))) \
asm_clobber(reg_str(R_AT_Code), "memory") \
asm_words(add_si((rt), R_0, (imm))) \
asm_clobber: rlit(R_AT_Code), clb_mem_drain \
); \
} \
else if (__builtin_constant_p(imm) && ((U4)(imm) <= 0xFFFFU)) { \
else if (cexpr_(imm) && ((U4)(imm) <= 0xFFFFU)) { \
/* 0x8000..0xFFFF: ori rt, $0, imm (zero-extends) */ \
asm volatile( \
asm_inline(ori_op((rt), R_0, (imm))) \
asm_clobber(reg_str(R_AT_Code), "memory") \
asm_words(or_i((rt), R_0, (imm))) \
asm_clobber: rlit(R_AT_Code), clb_mem_drain \
); \
} \
else \
{ \
/* > 16 bits: lui + (ori | addi). \
* If lo16 is in [0, 0x7FFF] use addi (sign-ext is harmless \
* since the high half cleared bits 15..0). Otherwise ori. */ \
U4 _li_imm_ = (U4)(imm); \
U4 _li_lo_ = _li_imm_ & 0xFFFFU; \
U4 _li_hi_ = _li_imm_ >> 16; \
if (_li_lo_ <= 0x7FFFU) { \
asm volatile( \
asm_inline(lui_op((rt), _li_hi_), \
add_si((rt), (rt), (S2)(U2)_li_lo_)) \
asm_clobber(reg_str(R_AT_Code), "memory") \
* If lo16 is in [0, 0x7FFF] use addi (sign-ext is harmless \
* since the high half cleared bits 15..0). Otherwise ori. */ \
if (u4_lo(imm) <= 0x7FFFU) { \
asm volatile(asm_words( \
load_ui((rt), u4_hi(imm)), \
add_si((rt), (rt), (S2)C_(U2,u4_lo(imm))) \
asm_clobber: rlit(R_AT_Code), clb_mem_drain \
); \
} \
else { \
asm volatile( \
asm_inline(lui_op((rt), _li_hi_), \
ori_op((rt), (rt), (U2)_li_lo_)) \
asm_clobber(reg_str(R_AT_Code), "memory") \
asm volatile(asm_words( \
load_ui((rt), u4_hi(imm)), \
or_i((rt), (rt), C_(U2,u4_lo(imm)) \
asm_clobber: rlit(R_AT_Code), clb_mem_drain \
); \
} \
} \
@@ -466,7 +468,7 @@ enum { _BitOffsets = 0
// Binary Metaprogramming
typedef U4 const Code;
#define CodeBlob_(sym) tmpl(codeblob,sym) [] align_(4) =
#define CodeBlob_(sym) tmpl(code,sym) [] align_(4) =
enum {
bios_flushcache = 0x44,
@@ -486,26 +488,25 @@ enum {
*/
internal
Code CodeBlob_(mips_flush_icache) {
add_ui(rstack_ptr, rstack_ptr, -8), /* sp -= 8 */
store_word(rret_addr, rstack_ptr, 4), /* sw $ra, 4($sp) */
add_ui(rret_0, rdiscard, bios_flushcache), /* addiu $a0, $0, 0x44 */
add_ui(rtmp_0, rdiscard, bios_table_addr), /* addiu $t0, $0, 0xA0 */
jump_link(rtmp_0, rret_addr), /* jalr $t0, $ra */
nop, /* BD slot */
load_word(rret_addr, rstack_ptr, 4), /* lw $ra, 4($sp) */
jump_reg(rret_addr), /* jr $ra */
add_ui(rstack_ptr, rstack_ptr, 8) /* sp += 8 (BD) */
add_ui(rstack_ptr, rstack_ptr, -8) /* sp -= 8 */
, store_word(rret_addr, rstack_ptr, 4) /* sw $ra, 4($sp) */
, add_ui(rret_0, rdiscard, bios_flushcache) /* addiu $a0, $0, 0x44 */
, add_ui(rtmp_0, rdiscard, bios_table_addr) /* addiu $t0, $0, 0xA0 */
, jump_link(rtmp_0, rret_addr) /* jalr $t0, $ra */
, nop /* BD slot */
, load_word(rret_addr, rstack_ptr, 4) /* lw $ra, 4($sp) */
, jump_reg(rret_addr) /* jr $ra */
, add_ui(rstack_ptr, rstack_ptr, 8) /* sp += 8 (BD) */
};
FI_ void mips_flush_icache(void) { C_(VoidFn*, codeblob_mips_flush_icache)(); }
I_ void mips_flush_icache(void) { C_(VoidFn*, code_mips_flush_icache)(); }
/* Standard clobber list for pure-MIPS asm volatile blocks: caller-saved
* GPRs that the kernel treats as volatile (v0/v1/t0/t1/ra) plus the
* "memory" barrier. The register ids are passed through `reg_str` so
* "memory" barrier. The register ids are passed through `rlit` so
* the R_*_Code `#define`s are stringified into "$N" at expansion time. */
#define clb_system \
reg_str(R_V0_Code), reg_str(R_T0_Code), reg_str(R_T1_Code), reg_str(R_RA_Code), "memory"
#define clb_system rlit(R_V0_Code), rlit(R_T0_Code), rlit(R_T1_Code), rlit(R_RA_Code), clb_mem_drain
#define asm_mips_flush_icache() asm volatile( asm_inline( \
#define asm_mips_flush_icache() asm volatile( asm_words( \
add_ui(rstack_ptr, rstack_ptr, -8) \
, store_word(rret_addr, rstack_ptr, 4) \
, add_ui(rret_0, rdiscard, bios_flushcache) \
@@ -515,10 +516,8 @@ FI_ void mips_flush_icache(void) { C_(VoidFn*, codeblob_mips_flush_icache)(); }
, load_word(rret_addr, rstack_ptr, 4) \
, jump_reg(rret_addr) \
, add_ui(rstack_ptr, rstack_ptr, 8) \
) asm_clobber( clb_system ) )
) asm_clobber: clb_system )
void test_mips_asm() {
asm_mips_flush_icache();
}
// TAPE & EMITTERS
+37 -1
View File
@@ -12,6 +12,7 @@
#include "duffle/mips.h"
#include "duffle/gp.h"
#include "duffle/gte.h"
#include "duffle/lottes_tape.h"
#include "hello_gte.h"
enum {
@@ -115,7 +116,7 @@ I_ B1* prim__alloc(U4 type_width, Str8 type_name) {
pa->used += type_width;
return next;
}
#define prim_alloc(type) (type*)prim__alloc(S_(type), txt( stringify(type)))
#define prim_alloc(type) (type*)prim__alloc(S_(type), slit( stringify(type)))
void gp_screen_init_c11(DoubleBuffer* screen_buf, S2* active_buf_id)
{
@@ -229,6 +230,7 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
static_mem.cube.rot.y += 30;
}
// Draw Floor
if (0)
{
m3s2_rotation (& static_mem.floor.rot, & static_mem.tform_world);
m3s2_translation(& static_mem.tform_world, & static_mem.floor.pos);
@@ -282,6 +284,40 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
}
static_mem.floor.rot.y += 5;
}
// Draw floor tape method
if (1)
{
LP_ U4 mem_temp_tape[512]; // Buffer for function addresses
FArena tape_arena;
farena_init(&tape_arena, slice_ut(mem_temp_tape, S_(mem_temp_tape)));
TapeBuilder tb = tb_begin(&tape_arena); {
// Setup state atoms
m3s2_rotation(&static_mem.floor.rot, &static_mem.tform_world);
m3s2_translation(&static_mem.tform_world, &static_mem.floor.pos);
// Push "Protocol" to tape
tb_emit(&tb, code_atom_set_gte_world);
tb_emit(&tb, (Code*)&static_mem.tform_world);
for (U4 i = 0; i < Floor_num_faces; i++) {
tb_emit(&tb, code_atom_floor_tri);
}
}
Slice_U4 tape = tb_end(&tb);
// 1. Setup Argument Registers (The Workspace)
register V3_S2* face_cursor rgcc(R_T4) = static_mem.floor.faces;
register V3_S2* vert_base rgcc(R_T5) = static_mem.floor.verts;
register U4* ot_base rgcc(R_T6) = ordering_buf;
// --- EXECUTION ---
B1* prim_cursor = (B1*)r_(pa->buf)[static_mem.active_buf_id] + pa->used;
// 2. Fire the Tape Drive (Explicitly bind the workspace variables)
tape_run(tape, &prim_cursor, static_mem.floor.faces, static_mem.floor.verts, ordering_buf);
// 3. Update C-side state
pa->used = (U4)prim_cursor - (U4)r_(pa->buf)[static_mem.active_buf_id];
static_mem.floor.rot.y += 5;
}
}
int main(void)