commit 0282ae36cdb7c754f96c931b6c0101d5ee56d31f
parent aa0e953fc88b10a364d5acf246726733acaca5bc
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Wed, 3 Jun 2026 10:39:43 -0700
econ(native-shared): share file_scope_asm + finalize in cg/native_asm
Sub-refactor (B): aa_/rv_/x64_ file_scope_asm and finalize were byte-identical
leaf wrappers over base NativeTarget fields (t->c, t->mc). Move them verbatim
into new cg/native_asm.{c,h} as native_file_scope_asm / native_finalize and
point all three vtables there. set_loc stays per-arch (it needs the per-arch
loc field).
(cherry picked from commit fb890f2a8282d52fd9dfabc180db1b2dc1fc3db3)
Diffstat:
5 files changed, 48 insertions(+), 34 deletions(-)
diff --git a/src/arch/aa64/native.c b/src/arch/aa64/native.c
@@ -37,6 +37,7 @@
#include "asm/asm.h"
#include "asm/asm_lex.h"
#include "cg/native_argmove.h"
+#include "cg/native_asm.h"
#include "cg/native_direct_target.h"
#include "cg/native_frame.h"
#include "cg/type.h"
@@ -3496,11 +3497,7 @@ static void aa_intrinsic(NativeTarget* t, IntrinKind kind,
static void aa_trap(NativeTarget* t) { aa_emit32(t->mc, aa64_brk(0)); }
-static void aa_file_scope_asm(NativeTarget* t, const char* src, size_t len) {
- AsmLexer* lex = asm_lex_open_mem(t->c, "<file-scope-asm>", src, len);
- asm_parse(t->c, lex, t->mc);
- asm_lex_close(lex);
-}
+/* file_scope_asm + finalize are shared (cg/native_asm.h). */
static void aa_set_loc(NativeTarget* t, SrcLoc loc) {
AANativeTarget* a = aa_of(t);
@@ -3508,10 +3505,6 @@ static void aa_set_loc(NativeTarget* t, SrcLoc loc) {
if (t->mc && t->mc->set_loc) t->mc->set_loc(t->mc, loc);
}
-static void aa_finalize(NativeTarget* t) {
- if (t->mc) mc_emit_eh_frame(t->mc);
-}
-
static void aa_bind_native_param(NativeTarget* t, const CGParamDesc* p,
NativeLoc dst);
@@ -3767,10 +3760,10 @@ NativeTarget* aa64_native_target_new(Compiler* c, ObjBuilder* obj,
t->va_copy_ = aa_va_copy_native;
t->intrinsic = aa_intrinsic;
t->asm_block = aa_asm_block_native;
- t->file_scope_asm = aa_file_scope_asm;
+ t->file_scope_asm = native_file_scope_asm;
t->trap = aa_trap;
t->set_loc = aa_set_loc;
- t->finalize = aa_finalize;
+ t->finalize = native_finalize;
return t;
}
diff --git a/src/arch/rv64/native.c b/src/arch/rv64/native.c
@@ -24,6 +24,7 @@
#include "asm/asm.h"
#include "asm/asm_lex.h"
#include "cg/native_argmove.h"
+#include "cg/native_asm.h"
#include "cg/native_direct_target.h"
#include "cg/native_frame.h"
#include "cg/type.h"
@@ -3456,22 +3457,13 @@ static void rv_asm_block_native(NativeTarget* t, const char* tmpl,
rv64_asm_run_template(asmh, t->mc, tmpl);
rv64_asm_close(asmh);
}
-static void rv_file_scope_asm(NativeTarget* t, const char* src, size_t len) {
- /* Top-level __asm__("...") — assemble through the generic .s parser, which
- * dispatches instruction lines to the rv64 asm driver and handles directives
- * (.data/.word/.globl/.text/...) itself. */
- AsmLexer* lex = asm_lex_open_mem(t->c, "<file-scope-asm>", src, len);
- asm_parse(t->c, lex, t->mc);
- asm_lex_close(lex);
-}
+/* file_scope_asm + finalize are shared (cg/native_asm.h). */
+
static void rv_trap(NativeTarget* t) { rv64_emit32(t->mc, rv_ebreak()); }
static void rv_set_loc(NativeTarget* t, SrcLoc loc) {
rv_of(t)->loc = loc;
if (t->mc->set_loc) t->mc->set_loc(t->mc, loc);
}
-static void rv_finalize(NativeTarget* t) {
- if (t->mc) mc_emit_eh_frame(t->mc);
-}
/* ============================ construction ============================ */
@@ -3542,10 +3534,10 @@ NativeTarget* rv64_native_target_new(Compiler* c, ObjBuilder* obj,
t->va_copy_ = rv_va_copy_native;
t->intrinsic = rv_intrinsic;
t->asm_block = rv_asm_block_native;
- t->file_scope_asm = rv_file_scope_asm;
+ t->file_scope_asm = native_file_scope_asm;
t->trap = rv_trap;
t->set_loc = rv_set_loc;
- t->finalize = rv_finalize;
+ t->finalize = native_finalize;
return t;
}
diff --git a/src/arch/x64/native.c b/src/arch/x64/native.c
@@ -35,6 +35,7 @@
#include "asm/asm.h"
#include "asm/asm_lex.h"
#include "cg/native_argmove.h"
+#include "cg/native_asm.h"
#include "cg/native_direct_target.h"
#include "cg/native_frame.h"
#include "cg/type.h"
@@ -3924,20 +3925,13 @@ static void x64_asm_block_native(NativeTarget* t, const char* tmpl,
x64_asm_close(asmh);
}
-static void x64_file_scope_asm(NativeTarget* t, const char* src, size_t len) {
- AsmLexer* lex = asm_lex_open_mem(t->c, "<file-scope-asm>", src, len);
- asm_parse(t->c, lex, t->mc);
- asm_lex_close(lex);
-}
+/* file_scope_asm + finalize are shared (cg/native_asm.h). */
static void x64_trap(NativeTarget* t) { emit_ud2(t->mc); }
static void x64_set_loc(NativeTarget* t, SrcLoc loc) {
x64_of(t)->loc = loc;
if (t->mc->set_loc) t->mc->set_loc(t->mc, loc);
}
-static void x64_finalize(NativeTarget* t) {
- if (t->mc) mc_emit_eh_frame(t->mc);
-}
/* Physical registers each x86-64 instruction's encoding clobbers as a side
* effect, so the optimizer keeps values live across them out of those registers
@@ -4064,10 +4058,10 @@ NativeTarget* x64_native_target_new(Compiler* c, ObjBuilder* obj,
t->va_copy_ = x64_va_copy_native;
t->intrinsic = x64_intrinsic;
t->asm_block = x64_asm_block_native;
- t->file_scope_asm = x64_file_scope_asm;
+ t->file_scope_asm = native_file_scope_asm;
t->trap = x64_trap;
t->set_loc = x64_set_loc;
- t->finalize = x64_finalize;
+ t->finalize = native_finalize;
return t;
}
diff --git a/src/cg/native_asm.c b/src/cg/native_asm.c
@@ -0,0 +1,15 @@
+#include "cg/native_asm.h"
+
+#include "arch/mc.h"
+#include "asm/asm.h"
+#include "asm/asm_lex.h"
+
+void native_file_scope_asm(NativeTarget* t, const char* src, size_t len) {
+ AsmLexer* lex = asm_lex_open_mem(t->c, "<file-scope-asm>", src, len);
+ asm_parse(t->c, lex, t->mc);
+ asm_lex_close(lex);
+}
+
+void native_finalize(NativeTarget* t) {
+ if (t->mc) mc_emit_eh_frame(t->mc);
+}
diff --git a/src/cg/native_asm.h b/src/cg/native_asm.h
@@ -0,0 +1,20 @@
+#ifndef KIT_CG_NATIVE_ASM_H
+#define KIT_CG_NATIVE_ASM_H
+
+/* Shared, target-neutral native helpers that touch only the base NativeTarget
+ * (its Compiler and MCEmitter): the file-scope-asm assembler entry and the
+ * eh-frame finalize step. Both were byte-identical across the aa64/rv64/x64
+ * backends, so they live here as the single source of truth; each backend's
+ * vtable points its file_scope_asm / finalize slots straight at these. */
+
+#include "arch/native_target.h"
+
+/* Top-level __asm__("...") — assemble through the generic .s parser, which
+ * dispatches instruction lines to the active arch asm driver and handles
+ * directives (.data/.word/.globl/.text/...) itself. */
+void native_file_scope_asm(NativeTarget* t, const char* src, size_t len);
+
+/* Emit the function's eh-frame (CFI) once code emission is complete. */
+void native_finalize(NativeTarget* t);
+
+#endif