native_asm.h (4091B)
1 #ifndef KIT_CG_NATIVE_ASM_H 2 #define KIT_CG_NATIVE_ASM_H 3 4 /* Shared, target-neutral native helpers that touch only the base NativeTarget 5 * (its Compiler and MCEmitter): the file-scope-asm assembler entry and the 6 * eh-frame finalize step. Both were byte-identical across the aa64/rv64/x64 7 * backends, so they live here as the single source of truth; each backend's 8 * vtable points its file_scope_asm / finalize slots straight at these. */ 9 10 #include "arch/native_target.h" 11 12 /* Top-level __asm__("...") — assemble through the generic .s parser, which 13 * dispatches instruction lines to the active arch asm driver and handles 14 * directives (.data/.word/.globl/.text/...) itself. */ 15 void native_file_scope_asm(NativeTarget* t, const char* src, size_t len); 16 17 /* Emit the function's eh-frame (CFI) once code emission is complete. */ 18 void native_finalize(NativeTarget* t); 19 20 /* ---- Inline-asm constraint-string helpers ---- 21 * 22 * Pure, target-neutral parsing of a GCC-style operand constraint string. These 23 * were byte-identical across the aa64/rv64/x64 inline-asm lowering paths, so 24 * they live here as the single source of truth. They read only the string, 25 * never any target state. 26 */ 27 28 /* Skip the leading modifier flags ('=', '+', '&', and the '=&' early-clobber 29 * pair) and return a pointer to the constraint body (e.g. "r", "w", "m", "i", 30 * or a matching-constraint digit run). Returns "" for a NULL string. */ 31 const char* native_asm_constraint_body(const char* s); 32 33 /* Whether the constraint marks an early-clobber output ('=&' or a leading 34 * '&'). */ 35 int native_asm_constraint_early(const char* s); 36 37 /* For a matching constraint (a leading decimal digit run naming an output 38 * operand index), return that index; -1 when the constraint is not a matching 39 * constraint. */ 40 int native_asm_match_index(const char* s); 41 42 /* Expand the arch-neutral clobber-ABI sets (KitCgAsmClobberAbiSet bits) into 43 * this target's live per-class caller/callee-saved register masks. */ 44 void native_asm_abi_clobber_masks(NativeTarget* t, u32 abi_sets, u32* int_mask, 45 u32* fp_mask); 46 47 typedef enum NativeAsmRegPinStatus { 48 NATIVE_ASM_REG_PIN_ABSENT = 0, 49 NATIVE_ASM_REG_PIN_OK = 1, 50 NATIVE_ASM_REG_PIN_UNKNOWN = -1, 51 NATIVE_ASM_REG_PIN_FORBIDDEN = -2, 52 NATIVE_ASM_REG_PIN_BAD_CONSTRAINT = -3, 53 NATIVE_ASM_REG_PIN_CLASS_MISMATCH = -4, 54 NATIVE_ASM_REG_PIN_FIXED_MISMATCH = -5, 55 } NativeAsmRegPinStatus; 56 57 typedef struct NativeAsmRegPin { 58 Reg reg; 59 NativeAllocClass cls; 60 } NativeAsmRegPin; 61 62 typedef struct NativeAsmConstraintInfo { 63 NativeAllocClass cls; 64 Reg fixed_reg; /* REG_NONE when the constraint only names a register class. */ 65 u32 allowed_mask; /* 0 means any valid register in cls. */ 66 } NativeAsmConstraintInfo; 67 68 typedef struct NativeAsmPinnedLoc { 69 NativeLoc loc; 70 NativeAsmRegPinStatus pin_status; 71 u8 has_pin; 72 u8 needs_stage; 73 u8 wrong_reg; 74 } NativeAsmPinnedLoc; 75 76 int native_asm_constraint_reg_info(NativeTarget* t, const char* constraint, 77 NativeAsmConstraintInfo* out); 78 int native_asm_constraint_is_reg(NativeTarget* t, const char* constraint); 79 80 /* Resolve and validate an inline-asm operand's explicit hard-register pin 81 * (AsmConstraint.reg, from a GNU local register variable). Distinguishes no pin 82 * from invalid pins, and verifies that the operand uses a register constraint 83 * of the matching target class. */ 84 NativeAsmRegPinStatus native_asm_resolve_pin(NativeTarget* t, Sym reg, 85 const char* constraint, 86 NativeAsmRegPin* out); 87 NativeAsmPinnedLoc native_asm_prepare_pinned_loc(NativeTarget* t, Sym reg, 88 const char* constraint, 89 KitCgTypeId type, 90 NativeLoc loc); 91 const char* native_asm_pin_status_message(NativeAsmRegPinStatus st); 92 int native_asm_constraint_reg_class(const char* constraint, 93 NativeAllocClass* cls_out); 94 95 #endif