/** * @file intrinsics.ic * @brief Ironclad Hardware Intrinsics Engine * * This module registers compiler-native semantic hardware operations into * the global AST symbol table. Intrinsics provide deterministic, low-level hardware control * with explicit optimizer semantics. * * Metadata bitmasks (IntrinPropReadsMemory, IntrinPropWritesMemory, etc.) * are bound to each intrinsic to rigorously govern the VRP Optimizer's * Alias Analysis and Instruction Scheduling passes. */ import compiler.types; import compiler.utils; import compiler.errors; import compiler.ast; import compiler.symbol; // ============================================================================ // === PARAMETRIC PROOFS & AXIOMS // ============================================================================ // Proof: Guarantee the basic symbol flags for all intrinsics are statically frozen. // Evaluates to a unified compile-time flag mask. proof INTRINSIC_BASE_FLAGS = FlagFunc | FlagIntrinsic; // Proof: Establish a strict purity mask for Dead Code Elimination (DCE). // Marks deterministic side-effect-free intrinsics for constant folding and DCE. proof INTRIN_PURE_MASK = IntrinPropPure | IntrinPropDeterministic; // ============================================================================ // === AST TOPOLOGY MACROS // ============================================================================ // AST helper macro for consistent intrinsic registration. #define REG_INTRIN(name, t_id, offset_val, props) { \ sym = AddSymbol(ctx, globals, name, t_id); \ sym->flags = INTRINSIC_BASE_FLAGS; \ sym->offset = offset_val; \ sym->intrin_props = props; \ } // AST Macro explicitly for Variadic standard intrinsics. #define REG_VAR_INTRIN(name, t_id, offset_val, props) { \ sym = AddSymbol(ctx, globals, name, t_id); \ sym->flags = INTRINSIC_BASE_FLAGS | FlagVariadic; \ sym->offset = offset_val; \ sym->intrin_props = props; \ } // AST Macro explicitly for Polymorphic/Generic () intrinsics. // Instantiates `TypeIdGeneric` to force the AST semantic analyzer // to dynamically deduce physical hardware bounds during instantiation. #define REG_GENERIC(name, offset_val, props) { \ sym = AddSymbol(ctx, globals, name, TypeIdGeneric); \ sym->flags = INTRINSIC_BASE_FLAGS; \ sym->offset = offset_val; \ sym->intrin_props = props; \ } // AST Macro explicitly for Variadic Polymorphic/Generic () intrinsics. #define REG_VAR_GENERIC(name, offset_val, props) { \ sym = AddSymbol(ctx, globals, name, TypeIdGeneric); \ sym->flags = INTRINSIC_BASE_FLAGS | FlagVariadic; \ sym->offset = offset_val; \ sym->intrin_props = props; \ } // ============================================================================ // === INTRINSICS REGISTRATION // ============================================================================ void RegisterIntrinsics(struct CompilerState* ctx, struct SymbolTable* globals) { // Scratch symbol pointer used by registration macros struct Symbol* sym; // ======================================================================== // === SYSTEM CALL BOUNDARY // ======================================================================== // Explicitly uses FlagSyscall so the Semantic Analyzer routes it to AstSyscall, // preserving node->val for argument count pop extraction in CodeGen. sym = AddSymbol(ctx, globals, "__builtin_syscall", TypeIdI64); sym->flags = FlagFunc | FlagSyscall | FlagVariadic; // ======================================================================== // === HARDWARE STATE & BARRIERS // ======================================================================== // Cycle counters provide non-deterministic timing data; the VRP engine automatically // bounds their evaluation exclusively to [VrpMin, VrpMax]. REG_INTRIN("__builtin_cycle_count", TypeIdI64, IntrinCycleCount, IntrinPropVolatile); // Explicit hardware pointer state extraction REG_INTRIN("__builtin_stack_ptr", MakePtr(TypeIdU8), IntrinStackPtr, IntrinPropDeterministic); REG_INTRIN("__builtin_frame_ptr", MakePtr(TypeIdU8), IntrinFramePtr, IntrinPropDeterministic); // Optimizer and Hardware Memory Barriers REG_INTRIN("__builtin_fence", TypeIdVoid, IntrinFence, IntrinPropBarrier | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_INTRIN("__builtin_prefetch", TypeIdVoid, IntrinPrefetch, IntrinPropReadsMemory); REG_INTRIN("__builtin_cache_flush", TypeIdVoid, IntrinCacheFlush, IntrinPropVolatile | IntrinPropReadsMemory | IntrinPropWritesMemory); // ======================================================================== // === ATOMICS & CONCURRENCY // ======================================================================== // Atomics operate on generic types () via parametric specialization. // Width and alignment legality are validated before lowering. REG_GENERIC("__builtin_atomic_load", IntrinAtomicLoad, IntrinPropVolatile | IntrinPropBarrier | IntrinPropReadsMemory); REG_GENERIC("__builtin_atomic_fetch_add", IntrinAtomicFetchAdd, IntrinPropVolatile | IntrinPropBarrier | IntrinPropStateMutating | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_GENERIC("__builtin_atomic_fetch_sub", IntrinAtomicFetchSub, IntrinPropVolatile | IntrinPropBarrier | IntrinPropStateMutating | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_GENERIC("__builtin_fetch_and", IntrinFetchAnd, IntrinPropVolatile | IntrinPropBarrier | IntrinPropStateMutating | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_GENERIC("__builtin_fetch_or", IntrinFetchOr, IntrinPropVolatile | IntrinPropBarrier | IntrinPropStateMutating | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_GENERIC("__builtin_fetch_xor", IntrinFetchXor, IntrinPropVolatile | IntrinPropBarrier | IntrinPropStateMutating | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_GENERIC("__builtin_atomic_swap", IntrinAtomicSwap, IntrinPropVolatile | IntrinPropBarrier | IntrinPropStateMutating | IntrinPropReadsMemory | IntrinPropWritesMemory); // Stores and CAS utilize strict Boolean and Void routing topologies REG_INTRIN ("__builtin_atomic_store", TypeIdVoid, IntrinAtomicStore, IntrinPropVolatile | IntrinPropBarrier | IntrinPropStateMutating | IntrinPropWritesMemory); REG_INTRIN ("__builtin_cmpxchg", TypeIdBool, IntrinCmpxchg, IntrinPropVolatile | IntrinPropBarrier | IntrinPropStateMutating | IntrinPropReadsMemory | IntrinPropWritesMemory); // ======================================================================== // === DOMAINS & ABI BOUNDARIES // ======================================================================== // Cross-domain execution and ABI boundary intrinsics (Flags explicitly forbid passing Ephemeral Slices) REG_VAR_INTRIN("__builtin_core_invoke", TypeIdVoid, IntrinCoreInvoke, IntrinPropStateMutating | IntrinPropBarrier | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_VAR_GENERIC("__builtin_foreign_call", IntrinForeignCall, IntrinPropStateMutating | IntrinPropBarrier | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_INTRIN("__builtin_core_sync", TypeIdVoid, IntrinCoreSync, IntrinPropBarrier | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_INTRIN("__builtin_core_sync_all", TypeIdVoid, IntrinCoreSyncAll, IntrinPropBarrier | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_INTRIN("__builtin_smt_active", TypeIdI64, IntrinSmtActive, IntrinPropDeterministic); // Static hardware properties are eligible for constant folding and DCE. REG_INTRIN("__builtin_cache_line", TypeIdI64, IntrinCacheLine, INTRIN_PURE_MASK); REG_INTRIN("__builtin_page_size", TypeIdI64, IntrinPageSize, INTRIN_PURE_MASK); // Dynamic hardware state is runtime-volatile. REG_INTRIN("__builtin_current_core_cache_line", TypeIdI64, IntrinCurrentCoreCacheLine, IntrinPropVolatile); // ======================================================================== // === SIMD VECTORS & HARDWARE ARRAYS // ======================================================================== // Vector operations preserve stride, alignment, and layout semantics during lowering. REG_GENERIC("__builtin_vec_add", IntrinVecAdd, IntrinPropPure | IntrinPropDeterministic | IntrinPropReadsMemory); REG_GENERIC("__builtin_vec_sub", IntrinVecSub, IntrinPropPure | IntrinPropDeterministic | IntrinPropReadsMemory); REG_GENERIC("__builtin_vec_mul", IntrinVecMul, IntrinPropPure | IntrinPropDeterministic | IntrinPropReadsMemory); REG_GENERIC("__builtin_vec_div", IntrinVecDiv, IntrinPropPure | IntrinPropDeterministic | IntrinPropReadsMemory); REG_GENERIC("__builtin_vec_and", IntrinVecAnd, IntrinPropPure | IntrinPropDeterministic | IntrinPropReadsMemory); REG_GENERIC("__builtin_vec_or", IntrinVecOr, IntrinPropPure | IntrinPropDeterministic | IntrinPropReadsMemory); REG_GENERIC("__builtin_vec_xor", IntrinVecXor, IntrinPropPure | IntrinPropDeterministic | IntrinPropReadsMemory); REG_GENERIC("__builtin_vec_shuffle", IntrinVecShuffle, IntrinPropPure | IntrinPropDeterministic | IntrinPropReadsMemory); REG_GENERIC("__builtin_vec_blend", IntrinVecBlend, IntrinPropPure | IntrinPropDeterministic | IntrinPropReadsMemory); REG_GENERIC("__builtin_vector_load", IntrinVecLoad, IntrinPropPure | IntrinPropReadsMemory); REG_GENERIC("__builtin_vector_gather", IntrinVecGather, IntrinPropPure | IntrinPropReadsMemory); REG_INTRIN ("__builtin_vector_store", TypeIdVoid, IntrinVecStore, IntrinPropStateMutating | IntrinPropWritesMemory); REG_INTRIN ("__builtin_vector_scatter", TypeIdVoid, IntrinVecScatter, IntrinPropStateMutating | IntrinPropWritesMemory); // ======================================================================== // === FPU / IEEE-754 // ======================================================================== // Floating-point intrinsics operate on generic IEEE-compatible types (``). // demanding strict f32/f64 bitwise geometry. REG_GENERIC("__builtin_fpu_sqrt", IntrinFpuSqrt, INTRIN_PURE_MASK); REG_GENERIC("__builtin_fpu_abs", IntrinFpuAbs, INTRIN_PURE_MASK); REG_GENERIC("__builtin_fpu_ceil", IntrinFpuCeil, INTRIN_PURE_MASK); REG_GENERIC("__builtin_fpu_fma", IntrinFpuFma, INTRIN_PURE_MASK); // Modifying the host FCSR introduces a global execution barrier. REG_INTRIN ("__builtin_fpu_get_exceptions", TypeIdU32, IntrinFpuGetExc, IntrinPropVolatile); REG_INTRIN ("__builtin_fpu_clear_exceptions", TypeIdVoid, IntrinFpuClearExc, IntrinPropVolatile | IntrinPropBarrier); REG_INTRIN ("__builtin_fpu_set_round", TypeIdVoid, IntrinFpuSetRound, IntrinPropVolatile | IntrinPropBarrier); REG_INTRIN ("__builtin_fpu_set_daz", TypeIdVoid, IntrinFpuSetDaz, IntrinPropVolatile | IntrinPropBarrier); // ======================================================================== // === EXECUTION CONTROL & TERMINAL DOMAINS // ======================================================================== REG_INTRIN("__builtin_halt", TypeIdVoid, IntrinHalt, IntrinPropTerminal | IntrinPropPrivileged); REG_INTRIN("__builtin_pause", TypeIdVoid, IntrinPause, IntrinPropVolatile); REG_INTRIN("__builtin_yield", TypeIdVoid, IntrinYield, IntrinPropVolatile); // <-- FIX: Yield restored REG_INTRIN("__builtin_nop", TypeIdVoid, IntrinNop, IntrinPropPure); REG_INTRIN("__builtin_breakpoint", TypeIdVoid, IntrinBreakpoint, IntrinPropTerminal); REG_INTRIN("__builtin_trap", TypeIdVoid, IntrinTrap, IntrinPropTerminal); REG_INTRIN("__builtin_unreachable", TypeIdVoid, IntrinUnreachable, IntrinPropTerminal); // ======================================================================== // === RING 0 PRIVILEGED HARDWARE & OS INTRINSICS // ======================================================================== REG_INTRIN("__builtin_cli", TypeIdVoid, IntrinCli, IntrinPropPrivileged | IntrinPropBarrier); REG_INTRIN("__builtin_sti", TypeIdVoid, IntrinSti, IntrinPropPrivileged | IntrinPropBarrier); REG_INTRIN("__builtin_irq_save", TypeIdU64, IntrinIrqSave, IntrinPropPrivileged | IntrinPropVolatile | IntrinPropBarrier); REG_INTRIN("__builtin_irq_restore", TypeIdVoid, IntrinIrqRestore, IntrinPropPrivileged | IntrinPropBarrier); REG_INTRIN("__builtin_read_cr0", TypeIdU64, IntrinReadCr0, IntrinPropPrivileged | IntrinPropVolatile); REG_INTRIN("__builtin_write_cr0", TypeIdVoid, IntrinWriteCr0, IntrinPropPrivileged | IntrinPropBarrier | IntrinPropStateMutating); REG_INTRIN("__builtin_read_cr2", TypeIdU64, IntrinReadCr2, IntrinPropPrivileged | IntrinPropVolatile); REG_INTRIN("__builtin_write_cr3", TypeIdVoid, IntrinWriteCr3, IntrinPropPrivileged | IntrinPropBarrier | IntrinPropStateMutating); REG_INTRIN("__builtin_read_cr4", TypeIdU64, IntrinReadCr4, IntrinPropPrivileged | IntrinPropVolatile); REG_INTRIN("__builtin_write_cr4", TypeIdVoid, IntrinWriteCr4, IntrinPropPrivileged | IntrinPropBarrier | IntrinPropStateMutating); REG_INTRIN("__builtin_rdmsr", TypeIdU64, IntrinRdMsr, IntrinPropPrivileged | IntrinPropVolatile); REG_INTRIN("__builtin_wrmsr", TypeIdVoid, IntrinWrMsr, IntrinPropPrivileged | IntrinPropBarrier | IntrinPropStateMutating); REG_INTRIN("__builtin_rdtsc", TypeIdU64, IntrinRdtsc, IntrinPropVolatile); REG_INTRIN("__builtin_rdtscp", TypeIdU64, IntrinRdtscp, IntrinPropVolatile | IntrinPropBarrier); REG_INTRIN("__builtin_invlpg", TypeIdVoid, IntrinInvlpg, IntrinPropPrivileged | IntrinPropBarrier | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_INTRIN("__builtin_in8", TypeIdU8, IntrinIn8, IntrinPropPrivileged | IntrinPropVolatile | IntrinPropReadsMemory); REG_INTRIN("__builtin_in16", TypeIdU16, IntrinIn16, IntrinPropPrivileged | IntrinPropVolatile | IntrinPropReadsMemory); REG_INTRIN("__builtin_in32", TypeIdU32, IntrinIn32, IntrinPropPrivileged | IntrinPropVolatile | IntrinPropReadsMemory); REG_INTRIN("__builtin_out8", TypeIdVoid, IntrinOut8, IntrinPropPrivileged | IntrinPropVolatile | IntrinPropBarrier | IntrinPropWritesMemory); REG_INTRIN("__builtin_out16", TypeIdVoid, IntrinOut16, IntrinPropPrivileged | IntrinPropVolatile | IntrinPropBarrier | IntrinPropWritesMemory); REG_INTRIN("__builtin_out32", TypeIdVoid, IntrinOut32, IntrinPropPrivileged | IntrinPropVolatile | IntrinPropBarrier | IntrinPropWritesMemory); REG_INTRIN("__builtin_fred_enter", TypeIdVoid, IntrinFredEnter, IntrinPropPrivileged | IntrinPropBarrier | IntrinPropTerminal); REG_INTRIN("__builtin_fred_exit", TypeIdVoid, IntrinFredExit, IntrinPropPrivileged | IntrinPropBarrier | IntrinPropTerminal); // ======================================================================== // === MEMORY OPERATIONS // ======================================================================== REG_INTRIN("__builtin_memcpy", TypeIdVoid, IntrinMemcpy, IntrinPropStateMutating | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_INTRIN("__builtin_memset", TypeIdVoid, IntrinMemset, IntrinPropStateMutating | IntrinPropWritesMemory); // ======================================================================== // === PURE BIT-MATH & CPUID // ======================================================================== REG_INTRIN("__builtin_popcount", TypeIdI64, IntrinPopcount, INTRIN_PURE_MASK); REG_INTRIN("__builtin_clz", TypeIdI64, IntrinClz, INTRIN_PURE_MASK); REG_INTRIN("__builtin_ctz", TypeIdI64, IntrinCtz, INTRIN_PURE_MASK); // Bit-manipulation intrinsics preserve type width and bit layout semantics. REG_GENERIC("__builtin_bswap", IntrinBswap, INTRIN_PURE_MASK); REG_GENERIC("__builtin_rotate_left", IntrinRotl, INTRIN_PURE_MASK); REG_GENERIC("__builtin_rotate_right", IntrinRotr, INTRIN_PURE_MASK); REG_INTRIN("__builtin_cpu_supports", TypeIdBool, IntrinCpuSupports, INTRIN_PURE_MASK); REG_INTRIN("__builtin_cpuid", TypeIdU64, IntrinCpuid, IntrinPropVolatile | IntrinPropDeterministic); // ======================================================================== // === EXPLICIT FENCES // ======================================================================== REG_INTRIN("__builtin_fence_relaxed", TypeIdVoid, IntrinFenceRelaxed, IntrinPropBarrier | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_INTRIN("__builtin_fence_acquire", TypeIdVoid, IntrinFenceAcquire, IntrinPropBarrier | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_INTRIN("__builtin_fence_release", TypeIdVoid, IntrinFenceRelease, IntrinPropBarrier | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_INTRIN("__builtin_fence_acqrel", TypeIdVoid, IntrinFenceAcqRel, IntrinPropBarrier | IntrinPropReadsMemory | IntrinPropWritesMemory); REG_INTRIN("__builtin_fence_seqcst", TypeIdVoid, IntrinFenceSeqCst, IntrinPropBarrier | IntrinPropReadsMemory | IntrinPropWritesMemory); }