stage1 重构代码
This commit is contained in:
138
stage1/spl_emit.h
Normal file
138
stage1/spl_emit.h
Normal file
@@ -0,0 +1,138 @@
|
||||
#ifndef __SPL_EMIT_H__
|
||||
#define __SPL_EMIT_H__
|
||||
|
||||
#include "../stage0/spl_ir.h"
|
||||
#include "spl_type.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* ============================================================
|
||||
* Frame allocator
|
||||
* ============================================================ */
|
||||
|
||||
typedef struct {
|
||||
int current_bytes;
|
||||
int peak_bytes;
|
||||
} spl_frame_alloc_t;
|
||||
|
||||
static inline void fa_init(spl_frame_alloc_t *fa) {
|
||||
fa->current_bytes = 0;
|
||||
fa->peak_bytes = 0;
|
||||
}
|
||||
|
||||
static inline int fa_alloc(spl_frame_alloc_t *fa, usize byte_size) {
|
||||
usize aligned = (byte_size + sizeof(spl_val_t) - 1) & ~(sizeof(spl_val_t) - 1);
|
||||
if (aligned < sizeof(spl_val_t))
|
||||
aligned = sizeof(spl_val_t);
|
||||
int offset = fa->current_bytes;
|
||||
fa->current_bytes += (int)aligned;
|
||||
if (fa->current_bytes > fa->peak_bytes)
|
||||
fa->peak_bytes = fa->current_bytes;
|
||||
return offset;
|
||||
}
|
||||
|
||||
int fa_alloc_type(spl_frame_alloc_t *fa, spl_type_ctx_t *tctx, int type_idx);
|
||||
|
||||
static inline void fa_reset_to(spl_frame_alloc_t *fa, int mark) { fa->current_bytes = mark; }
|
||||
|
||||
static inline int fa_alloc_slots(spl_frame_alloc_t *fa, usize nslots) {
|
||||
return fa_alloc(fa, nslots * sizeof(spl_val_t));
|
||||
}
|
||||
|
||||
static inline int fa_alloc_temp(spl_frame_alloc_t *fa, usize nslots) {
|
||||
return fa_alloc_slots(fa, nslots);
|
||||
}
|
||||
|
||||
static inline void fa_free(spl_frame_alloc_t *fa, int mark) { fa->current_bytes = mark; }
|
||||
|
||||
/* ============================================================
|
||||
* Emit context
|
||||
* ============================================================ */
|
||||
|
||||
typedef struct {
|
||||
spl_prog_t *prog;
|
||||
spl_frame_alloc_t frame;
|
||||
VEC(spl_val_t) call_fixups;
|
||||
VEC(int) call_fixup_funcs;
|
||||
} spl_emit_t;
|
||||
|
||||
void spl_emit_init(spl_emit_t *e, spl_prog_t *prog);
|
||||
void spl_emit_drop(spl_emit_t *e);
|
||||
|
||||
/* ============================================================
|
||||
* Layer 1 — single-instruction semantic wrappers
|
||||
* ============================================================ */
|
||||
|
||||
/* Stack ops */
|
||||
void emit_drop(spl_emit_t *e);
|
||||
void emit_dup(spl_emit_t *e);
|
||||
void emit_swap(spl_emit_t *e);
|
||||
void emit_rot(spl_emit_t *e);
|
||||
void emit_pick(spl_emit_t *e, int n);
|
||||
|
||||
/* Push */
|
||||
void emit_push_i32(spl_emit_t *e, int v);
|
||||
void emit_push_usize(spl_emit_t *e, usize v);
|
||||
void emit_push_u64(spl_emit_t *e, uint64_t v);
|
||||
void emit_push_f64(spl_emit_t *e, uint64_t v);
|
||||
void emit_push_ptr(spl_emit_t *e, spl_val_t v);
|
||||
void emit_push_type(spl_emit_t *e, uint16_t bt, spl_val_t v);
|
||||
|
||||
/* Load */
|
||||
void emit_load_ptr(spl_emit_t *e);
|
||||
void emit_load_usize(spl_emit_t *e);
|
||||
void emit_load_type(spl_emit_t *e, uint16_t bt);
|
||||
|
||||
/* Store */
|
||||
void emit_store_i32(spl_emit_t *e);
|
||||
void emit_store_ptr(spl_emit_t *e);
|
||||
void emit_store_usize(spl_emit_t *e);
|
||||
void emit_store_type(spl_emit_t *e, uint16_t bt);
|
||||
|
||||
/* Arithmetic */
|
||||
void emit_add_usize(spl_emit_t *e);
|
||||
void emit_add_u64(spl_emit_t *e);
|
||||
void emit_mul_u64(spl_emit_t *e);
|
||||
void emit_sub_usize(spl_emit_t *e);
|
||||
|
||||
/* Compare */
|
||||
void emit_ult_usize(spl_emit_t *e);
|
||||
|
||||
/* Branch */
|
||||
void emit_jmp(spl_emit_t *e, spl_val_t offset);
|
||||
spl_val_t emit_jmp_here(spl_emit_t *e);
|
||||
spl_val_t emit_bz_here(spl_emit_t *e);
|
||||
spl_val_t emit_bnz_here(spl_emit_t *e);
|
||||
void emit_patch(spl_emit_t *e, spl_val_t addr, spl_val_t target);
|
||||
void emit_patch_here(spl_emit_t *e, spl_val_t addr);
|
||||
|
||||
/* Address */
|
||||
void emit_laddr(spl_emit_t *e, int offset);
|
||||
void emit_gaddr(spl_emit_t *e, int idx);
|
||||
|
||||
/* Call */
|
||||
void emit_call(spl_emit_t *e, int nargs);
|
||||
void emit_ncall(spl_emit_t *e, int nargs);
|
||||
|
||||
/* Misc */
|
||||
void emit_alloc(spl_emit_t *e, int slots);
|
||||
void emit_binop(spl_emit_t *e, uint16_t op, uint16_t bt);
|
||||
void emit_dbg_void(spl_emit_t *e);
|
||||
void emit_dbg_usize(spl_emit_t *e);
|
||||
|
||||
/* ============================================================
|
||||
* Layer 2 — semantic-level helpers
|
||||
* ============================================================ */
|
||||
|
||||
void emit_frame_copy(spl_emit_t *e, int dest_offset, usize nslots);
|
||||
void emit_copy_addr_to_addr(spl_emit_t *e, usize nslots, int depth);
|
||||
void emit_load_to_var(spl_emit_t *e, spl_type_ctx_t *tctx, int ptr_slot_offset,
|
||||
usize byte_offset, int data_type_idx, int var_offset);
|
||||
void emit_store_to_laddr(spl_emit_t *e, int offset, uint16_t type);
|
||||
void emit_ptr_add(spl_emit_t *e, usize byte_off);
|
||||
spl_val_t emit_call_with_fixup(spl_emit_t *e, int nargs, int func_idx);
|
||||
void emit_return(spl_emit_t *e, spl_type_ctx_t *tctx, int ret_type_idx);
|
||||
|
||||
/* Patch all fixups */
|
||||
void emit_patch_call_fixups(spl_emit_t *e, spl_prog_t *prog);
|
||||
|
||||
#endif /* __SPL_EMIT_H__ */
|
||||
Reference in New Issue
Block a user