Nitpick Inline Assembly Specification

Nitpick provides direct, low-level access to the LLVM inline assembly backend via two powerful compiler built-ins: asm!! and asm!!!.

These built-ins act as ultimate escape hatches for performance-critical inner loops, SIMD optimizations, and direct hardware interaction.

1. Syntax and Structure

Both built-ins use a variadic generic signature that maps cleanly to LLVM’s inline assembly constructs.

asm!!<T>(string:arch, string:asm_code, string:constraints, args...);
asm!!!<T>(string:arch, string:asm_code, string:constraints, args...);

2. Safety Tiers

Nitpick splits inline assembly into two tiers of safety regarding error handling.

2.1 The Supervised Tier: asm!!<T>

This variant enforces Nitpick’s standard error propagation by wrapping the return value in a Result<T>. By convention, if the assembly block leaves a negative integer in the primary output register, Nitpick interprets it as an error code, mapping it into the tbb error field of the Result<T>.

// Safe wrapping: Must unwrap with raw, drop, or check .is_error
Result<int32>:res = asm!!<int32>("x86_64", "add %eax, %ebx", "=r,r,r", x, y);
int32:val = raw res;

2.2 The Raw Tier: asm!!!<T>

This variant is completely unchecked. It returns a bare T, totally bypassing the Result<T> wrapper. It assumes the operation cannot fail or that the developer will manually check the output value.

// Raw return: no `raw` keyword or Result handling needed
int32:res = asm!!!<int32>("x86_64", "add %eax, %ebx", "=r,r,r", x, y);

3. Compiler Integration

The Nitpick compiler passes the assembly strings and constraints directly to the LLVM backend. Therefore, any constraint violations (e.g., couldn't allocate output register for constraint 'a') will be caught and reported natively during the LLVM code generation phase.

[!NOTE] By default, LLVM (and therefore Nitpick) uses AT&T syntax for x86/x86_64 inline assembly. Ensure your assembly strings follow AT&T register and instruction formatting (e.g., add %eax, %ebx instead of Intel’s add ebx, eax).

4. JIT SIMD Instruction Emission (v0.80.3)

The JIT engine provides direct SIMD instruction emission for runtime-generated vectorized code. These are not inline assembly — they are assembler API calls that emit machine code into a wildx code buffer.

4.1 CPUID Runtime Detection

JitCpuFeatures npk_jit_detect_cpu(void);   // Returns cached feature flags
bool npk_jit_has_avx2(void);                // AVX2 available?
bool npk_jit_has_sse42(void);               // SSE4.2 available?
bool npk_jit_has_neon(void);                // NEON available? (AArch64 only)

JitCpuFeatures fields: sse2, sse3, ssse3, sse41, sse42, avx, avx2, avx512f.

4.2 x86_64 SSE2 Instructions (128-bit, XMM)

Function Instruction Description
npk_asm_movdqu_xmm_mem MOVDQU Unaligned 128-bit load
npk_asm_movdqu_mem_xmm MOVDQU Unaligned 128-bit store
npk_asm_movdqa_xmm_mem MOVDQA Aligned 128-bit load
npk_asm_movdqa_mem_xmm MOVDQA Aligned 128-bit store
npk_asm_paddd PADDD 4×int32 add
npk_asm_paddw PADDW 8×int16 add
npk_asm_paddb PADDB 16×int8 add
npk_asm_psubd PSUBD 4×int32 subtract
npk_asm_psubw PSUBW 8×int16 subtract
npk_asm_pmulld PMULLD 4×int32 multiply
npk_asm_pcmpeqd PCMPEQD Lane-wise compare equal
npk_asm_pand PAND Bitwise AND
npk_asm_por POR Bitwise OR
npk_asm_pxor PXOR Bitwise XOR
npk_asm_pshufb PSHUFB Byte shuffle

4.3 x86_64 AVX2 Instructions (256-bit, YMM, VEX-encoded)

Function Instruction Description
npk_asm_vmovdqu_ymm_mem VMOVDQU 256-bit unaligned load
npk_asm_vmovdqu_mem_ymm VMOVDQU 256-bit unaligned store
npk_asm_vpaddd_ymm VPADDD 8×int32 add (3-operand)
npk_asm_vpsubd_ymm VPSUBD 8×int32 subtract (3-operand)
npk_asm_vpbroadcastd VPBROADCASTD Broadcast int32 to all 8 lanes

4.4 AArch64 NEON/AdvSIMD Instructions (128-bit, V registers)

Function Instruction Description
a64_emit_ld1_4s LD1 {Vt.4S},[Xn] 128-bit vector load
a64_emit_st1_4s ST1 {Vt.4S},[Xn] 128-bit vector store
a64_emit_add_vec_4s ADD Vd.4S 4×int32 add
a64_emit_sub_vec_4s SUB Vd.4S 4×int32 subtract
a64_emit_mul_vec_4s MUL Vd.4S 4×int32 multiply
a64_emit_dup_4s_gpr DUP Vd.4S,Wn Broadcast GPR to all lanes
a64_emit_and_vec AND Vd.16B Bitwise AND
a64_emit_orr_vec ORR Vd.16B Bitwise OR
a64_emit_eor_vec EOR Vd.16B Bitwise XOR
a64_emit_cmeq_4s CMEQ Vd.4S Lane-wise compare equal