stage2 更多底层函数 stage1 layout正确使用 内置函数重新编写
This commit is contained in:
1 parent
fb0ff9b663
commit
4141e7d574
15 files changed
+2588
-122
No files matched your search
+46
-63
@@ -3,49 +3,24 @@
|
||||
|
||||
static usize align_up(usize x, usize a);
|
||||
|
||||
/* size/align/offset 统一取自 layout(spl_layout 是唯一准确来源)。 */
|
||||
static const spl_layout_info_t *ir_layout(spl_ir2vm_t *ctx, spl_type_id_t tid) {
|
||||
return spl_layout_info_of(ctx->layout, tid);
|
||||
}
|
||||
|
||||
static usize ir_type_size(spl_ir2vm_t *ctx, spl_type_id_t tid) {
|
||||
spl_type_node_t *tn = spl_type_node(ctx->type, tid);
|
||||
if (!tn)
|
||||
return 8;
|
||||
switch (tn->kind) {
|
||||
case SPL_TYPE_UNIT:
|
||||
const spl_layout_info_t *info = ir_layout(ctx, tid);
|
||||
if (!info)
|
||||
return 0;
|
||||
case SPL_TYPE_BOOL:
|
||||
return (info->size_bits + 7) / 8;
|
||||
}
|
||||
|
||||
static usize ir_type_align(spl_ir2vm_t *ctx, spl_type_id_t tid) {
|
||||
const spl_layout_info_t *info = ir_layout(ctx, tid);
|
||||
if (!info)
|
||||
return 1;
|
||||
case SPL_TYPE_INT:
|
||||
return (tn->int_type.bits + 7) / 8;
|
||||
case SPL_TYPE_FLOAT:
|
||||
return (tn->float_type.bits + 7) / 8;
|
||||
case SPL_TYPE_PTR:
|
||||
return sizeof(void *);
|
||||
case SPL_TYPE_FN:
|
||||
return sizeof(void *);
|
||||
case SPL_TYPE_ARRAY:
|
||||
return ir_type_size(ctx, tn->array_type.element) * tn->array_type.len;
|
||||
case SPL_TYPE_ENUM: {
|
||||
usize tag_sz = ir_type_size(ctx, tn->agg_type.tag_type);
|
||||
usize payload_align = 1;
|
||||
usize payload_size = 0;
|
||||
for (usize i = 0; i < vec_size(tn->agg_type.variants); ++i) {
|
||||
usize vs = ir_type_size(ctx, vec_at(tn->agg_type.variants, i).type_id);
|
||||
if (vs > payload_align)
|
||||
payload_align = vs;
|
||||
if (vs > payload_size)
|
||||
payload_size = vs;
|
||||
}
|
||||
usize payload_off = align_up(tag_sz, payload_align);
|
||||
return align_up(payload_off + payload_size, payload_align);
|
||||
}
|
||||
case SPL_TYPE_STRUCT:
|
||||
case SPL_TYPE_UNION: {
|
||||
usize s = 0;
|
||||
for (usize i = 0; i < vec_size(tn->agg_type.variants); ++i)
|
||||
s += ir_type_size(ctx, vec_at(tn->agg_type.variants, i).type_id);
|
||||
return s;
|
||||
}
|
||||
default:
|
||||
return 8;
|
||||
}
|
||||
usize a = info->align_bits / 8;
|
||||
return a ? a : 1;
|
||||
}
|
||||
|
||||
static bool ir_is_aggregate(spl_ir2vm_t *ctx, spl_type_id_t tid) {
|
||||
@@ -98,27 +73,13 @@ static usize ir_agg_field_off(spl_ir2vm_t *ctx, spl_type_id_t tid, usize idx) {
|
||||
spl_type_node_t *tn = spl_type_node(ctx->type, tid);
|
||||
if (!tn)
|
||||
return 0;
|
||||
if (tn->kind == SPL_TYPE_STRUCT || tn->kind == SPL_TYPE_UNION) {
|
||||
usize off = 0;
|
||||
for (usize i = 0; i < idx && i < vec_size(tn->agg_type.variants); ++i)
|
||||
off += ir_type_size(ctx, vec_at(tn->agg_type.variants, i).type_id);
|
||||
return off;
|
||||
}
|
||||
if (tn->kind == SPL_TYPE_ARRAY)
|
||||
return idx * ir_type_size(ctx, tn->array_type.element);
|
||||
if (tn->kind == SPL_TYPE_ENUM) {
|
||||
if (idx == 0)
|
||||
return 0;
|
||||
usize tag_sz = ir_type_size(ctx, tn->agg_type.tag_type);
|
||||
usize payload_align = 1;
|
||||
for (usize i = 0; i < vec_size(tn->agg_type.variants); ++i) {
|
||||
usize vs = ir_type_size(ctx, vec_at(tn->agg_type.variants, i).type_id);
|
||||
if (vs > payload_align)
|
||||
payload_align = vs;
|
||||
}
|
||||
return align_up(tag_sz, payload_align);
|
||||
}
|
||||
return 0;
|
||||
|
||||
const spl_layout_info_t *info = ir_layout(ctx, tid);
|
||||
if (!info || idx >= vec_size(info->field_bit_offsets))
|
||||
return 0;
|
||||
return vec_at(info->field_bit_offsets, idx) / 8;
|
||||
}
|
||||
|
||||
static int get_or_add_native(spl_ir2vm_t *ctx, const char *name) {
|
||||
@@ -752,12 +713,31 @@ static void cg_typeop(cgen_t *cg, usize ref, const spl_ir_node_t *n) {
|
||||
case SPL_IR_TYPE_SIZEOF:
|
||||
v = ir_type_size(ctx, n->ir_sizeof.tid);
|
||||
break;
|
||||
case SPL_IR_TYPE_BITSIZEOF:
|
||||
v = ir_type_size(ctx, n->bitsizeof.tid) * 8;
|
||||
case SPL_IR_TYPE_BITSIZEOF: {
|
||||
const spl_layout_info_t *info = ir_layout(ctx, n->bitsizeof.tid);
|
||||
v = info ? info->size_bits : 0;
|
||||
break;
|
||||
}
|
||||
case SPL_IR_TYPE_ALIGNOF:
|
||||
v = ir_type_size(ctx, n->ir_alignof.tid);
|
||||
v = ir_type_align(ctx, n->ir_alignof.tid);
|
||||
break;
|
||||
case SPL_IR_TYPE_OFFSETOF: {
|
||||
usize idx = 0;
|
||||
if (n->ir_offsetof.field_idx < vec_size(cg->irf->nodes)) {
|
||||
const spl_ir_node_t *idx_node = &vec_at(cg->irf->nodes, n->ir_offsetof.field_idx);
|
||||
if (idx_node->kind == SPL_IR_TYPE_CONST)
|
||||
idx = (usize)idx_node->type_const.int_lit;
|
||||
}
|
||||
v = ir_agg_field_off(ctx, n->ir_offsetof.tid, idx);
|
||||
break;
|
||||
}
|
||||
case SPL_IR_TYPE_FIELD_COUNT: {
|
||||
spl_type_node_t *tn = spl_type_node(ctx->type, n->field_count.tid);
|
||||
if (tn && (tn->kind == SPL_TYPE_STRUCT || tn->kind == SPL_TYPE_UNION ||
|
||||
tn->kind == SPL_TYPE_ENUM || tn->kind == SPL_TYPE_SHAPE))
|
||||
v = vec_size(tn->agg_type.variants);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@@ -1028,6 +1008,8 @@ static void cg_node(cgen_t *cg, usize ref, const spl_ir_node_t *n) {
|
||||
case SPL_IR_TYPE_SIZEOF:
|
||||
case SPL_IR_TYPE_BITSIZEOF:
|
||||
case SPL_IR_TYPE_ALIGNOF:
|
||||
case SPL_IR_TYPE_OFFSETOF:
|
||||
case SPL_IR_TYPE_FIELD_COUNT:
|
||||
cg_typeop(cg, ref, n);
|
||||
break;
|
||||
|
||||
@@ -1142,11 +1124,12 @@ static usize spl_map_hash(usize k) { return MAP_HASH_INT(k); }
|
||||
static int spl_map_cmp(usize a, usize b) { return MAP_CMP_INT(a, b); }
|
||||
|
||||
void spl_ir2vm_init(spl_ir2vm_t *ctx, const spl_ir_t *ir, const spl_type_t *type,
|
||||
const spl_attr_t *attr) {
|
||||
spl_layout_t *layout, const spl_attr_t *attr) {
|
||||
Assert(ir != NULL && type != NULL && attr != NULL);
|
||||
ctx->ir = ir;
|
||||
ctx->type = type;
|
||||
ctx->attr = attr;
|
||||
ctx->layout = layout;
|
||||
map_init(ctx->extern_native, spl_map_hash, spl_map_cmp);
|
||||
spl_prog_init(&ctx->prog);
|
||||
|
||||
|
||||
Reference in new issue
Block a user