kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit aa0e953fc88b10a364d5acf246726733acaca5bc
parent 333f933dd57d8ea74433ff8b24ab2972b7660d07
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Wed,  3 Jun 2026 10:37:36 -0700

econ(native-shared): hoist NativeLoc + scalar helpers into native_target.h

Sub-refactor (A): x64_/rv_/aa_ reg_loc, stack_loc, loc_is_fp, mem_for_type,
type_size/align, class_for_type were byte-identical copies. Add shared inlines
to native_target.h (native_loc_reg/stack/is_fp, native_type_size/align,
native_mem_for_type, native_class_for_type_fp_le8) as the single source of
truth and replace the per-arch copies. loc_reg keeps its arch-specific mask;
aa64 keeps its own type_size32/class_for_type/aa_mem_for_type (extra clamps).
nd_reg_loc folded into native_loc_reg with reordered call sites.

(cherry picked from commit 3c391e041c984ddf760d40247d01e71d9652606b)

Diffstat:
Msrc/arch/aa64/native.c | 162++++++++++++++++++++++++++++++++++---------------------------------------------
Msrc/arch/native_target.h | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/arch/rv64/native.c | 256++++++++++++++++++++++++++++++++-----------------------------------------------
Msrc/arch/x64/native.c | 222+++++++++++++++++++++++++++++++------------------------------------------------
Msrc/cg/native_direct_target.c | 29+++++++++++------------------
5 files changed, 340 insertions(+), 397 deletions(-)

diff --git a/src/arch/aa64/native.c b/src/arch/aa64/native.c @@ -334,9 +334,7 @@ static int loc_is_64(NativeTarget* t, NativeLoc loc) { return type_size32(t, loc.type) == 8u || cg_type_is_ptr(t->c, loc.type); } -static int loc_is_fp(NativeLoc loc) { - return (NativeAllocClass)loc.cls == NATIVE_REG_FP; -} +/* native_loc_is_fp is shared in native_target.h. */ static __attribute__((unused)) int aa_use_got_for_sym(NativeTarget* t, ObjSymId sym) { @@ -753,14 +751,14 @@ static void aa_emit_mem(AANativeTarget* a, int load, NativeLoc reg, sz = size_idx(mem.size ? mem.size : type_size32(&a->base, reg.type ? reg.type : mem.type)); - if (loc_is_fp(reg) && + if (native_loc_is_fp(reg) && (mem.size ? mem.size : type_size32(&a->base, reg.type ? reg.type : mem.type)) == 16u) { aa_emit_mem_q(a, load, reg, addr); return; } - if (loc_is_fp(reg) && sz < 2u) sz = 2u; + if (native_loc_is_fp(reg) && sz < 2u) sz = 2u; if (addr.base_kind == NATIVE_ADDR_BASE_GLOBAL && addr.index_kind == NATIVE_ADDR_INDEX_NONE) { i64 addend = addr.base.global.addend + (i64)addr.offset; @@ -775,16 +773,16 @@ static void aa_emit_mem(AANativeTarget* a, int load, NativeLoc reg, mc->emit_reloc_at(mc, mc->section_id, pos, R_AARCH64_LD64_GOT_LO12_NC, addr.base.global.sym, 0, 0, 0); if (addend) aa_emit_add_i64(a, scratch, scratch, addend); - aa_emit32(mc, load ? aa_ldur_v(sz, loc_is_fp(reg), rt, scratch, 0) - : aa_stur_v(sz, loc_is_fp(reg), rt, scratch, 0)); + aa_emit32(mc, load ? aa_ldur_v(sz, native_loc_is_fp(reg), rt, scratch, 0) + : aa_stur_v(sz, native_loc_is_fp(reg), rt, scratch, 0)); return; } aa_emit32(mc, aa64_adrp(scratch, 0, 0)); mc->emit_reloc_at(mc, mc->section_id, pos, R_AARCH64_ADR_PREL_PG_HI21, addr.base.global.sym, addend, 0, 0); pos = mc->pos(mc); - aa_emit32(mc, load ? aa_ldr_uimm_v(sz, loc_is_fp(reg), rt, scratch, 0) - : aa_str_uimm_v(sz, loc_is_fp(reg), rt, scratch, 0)); + aa_emit32(mc, load ? aa_ldr_uimm_v(sz, native_loc_is_fp(reg), rt, scratch, 0) + : aa_str_uimm_v(sz, native_loc_is_fp(reg), rt, scratch, 0)); mc->emit_reloc_at(mc, mc->section_id, pos, aa_ldst_reloc_for_size(sz), addr.base.global.sym, addend, 0, 0); return; @@ -806,24 +804,24 @@ static void aa_emit_mem(AANativeTarget* a, int load, NativeLoc reg, } else { aa_panic(a, "unsupported memory address scale"); } - aa_emit32(mc, aa_ldst_regoff_v(sz, loc_is_fp(reg), load, rt, use_base, + aa_emit32(mc, aa_ldst_regoff_v(sz, native_loc_is_fp(reg), load, rt, use_base, addr.index.reg, scaled)); return; } if (off >= 0 && (((u32)off & ((1u << sz) - 1u)) == 0) && ((u32)off >> sz) <= 0xfffu) { - aa_emit32(mc, load ? aa_ldr_uimm_v(sz, loc_is_fp(reg), rt, base, (u32)off) - : aa_str_uimm_v(sz, loc_is_fp(reg), rt, base, (u32)off)); + aa_emit32(mc, load ? aa_ldr_uimm_v(sz, native_loc_is_fp(reg), rt, base, (u32)off) + : aa_str_uimm_v(sz, native_loc_is_fp(reg), rt, base, (u32)off)); return; } if (off >= -256 && off <= 255) { - aa_emit32(mc, load ? aa_ldur_v(sz, loc_is_fp(reg), rt, base, off) - : aa_stur_v(sz, loc_is_fp(reg), rt, base, off)); + aa_emit32(mc, load ? aa_ldur_v(sz, native_loc_is_fp(reg), rt, base, off) + : aa_stur_v(sz, native_loc_is_fp(reg), rt, base, off)); return; } aa_emit_add_imm(a, AA_TMP1, base, off); - aa_emit32(mc, load ? aa_ldur_v(sz, loc_is_fp(reg), rt, AA_TMP1, 0) - : aa_stur_v(sz, loc_is_fp(reg), rt, AA_TMP1, 0)); + aa_emit32(mc, load ? aa_ldur_v(sz, native_loc_is_fp(reg), rt, AA_TMP1, 0) + : aa_stur_v(sz, native_loc_is_fp(reg), rt, AA_TMP1, 0)); } static NativeAllocClass aa_class_for_type(NativeTarget* t, KitCgTypeId type) { @@ -963,7 +961,7 @@ static void aa_materialize_frame_index(AANativeTarget* a, NativeAddr* addr, addr->index.reg = reg; } -static NativeLoc aa_reg_loc(KitCgTypeId type, NativeAllocClass cls, Reg reg); +static NativeLoc native_loc_reg(KitCgTypeId type, NativeAllocClass cls, Reg reg); static u32 aa_ldst_q_uimm(int load, u32 rt, u32 rn, u32 byte_off) { return aa64_ldst_uimm_pack((AA64LdStUimm){.size = 0, @@ -1036,7 +1034,7 @@ static void aa_emit_variadic_reg_save_stores(AANativeTarget* a) { addr.base.frame = a->va_gr_slot; addr.base_type = i64; for (u32 r = 0; r < vai.gp_reg_count && r < 8u; ++r) { - NativeLoc src = aa_reg_loc(i64, NATIVE_REG_INT, r); + NativeLoc src = native_loc_reg(i64, NATIVE_REG_INT, r); addr.offset = (i32)(r * vai.gp_slot_size); aa_emit_mem(a, 0, src, addr, mem); } @@ -1759,18 +1757,18 @@ static void aa_move(NativeTarget* t, NativeLoc dst, NativeLoc src) { * elided here even when the reg numbers match — the register files are * disjoint. */ if (dst.kind == NATIVE_LOC_REG && src.kind == NATIVE_LOC_REG && - loc_is_fp(dst) == loc_is_fp(src) && dst.v.reg == src.v.reg) + native_loc_is_fp(dst) == native_loc_is_fp(src) && dst.v.reg == src.v.reg) return; - if (loc_is_fp(dst) && loc_is_fp(src)) { + if (native_loc_is_fp(dst) && native_loc_is_fp(src)) { if (type_size32(t, dst.type) == 16u) aa_emit32(t->mc, aa_mov_vec16(loc_reg(dst), loc_reg(src))); else aa_emit32(t->mc, aa_fmov_fp(type_size32(t, dst.type) == 8u, loc_reg(dst), loc_reg(src))); - } else if (loc_is_fp(dst)) { + } else if (native_loc_is_fp(dst)) { aa_emit32(t->mc, aa_fmov_gpr_to_fp(loc_is_64(t, src), loc_reg(dst), loc_reg(src))); - } else if (loc_is_fp(src)) { + } else if (native_loc_is_fp(src)) { aa_emit32(t->mc, aa_fmov_fp_to_gpr(loc_is_64(t, dst), loc_reg(dst), loc_reg(src))); } else { @@ -1791,7 +1789,7 @@ static void aa_load_const(NativeTarget* t, NativeLoc dst, ConstBytes cbytes) { compiler_panic(t->c, ((AANativeTarget*)t)->loc, "aarch64 native target: byte constant too large"); for (u32 i = 0; i < cbytes.size; ++i) v |= (u64)cbytes.bytes[i] << (i * 8u); - if (loc_is_fp(dst)) { + if (native_loc_is_fp(dst)) { NativeLoc tmp = aa_tmp_loc(cbytes.type, AA_TMP0); aa_emit_load_imm(t->mc, cbytes.size == 8u, AA_TMP0, (i64)v); aa_move(t, dst, tmp); @@ -2119,7 +2117,7 @@ static void aa_binop(NativeTarget* t, BinOp op, NativeLoc dst, NativeLoc lhs, NativeLoc rhs) { u32 sf = loc_is_64(t, dst) ? 1u : 0u; u32 rd = loc_reg(dst), rn = loc_reg(lhs), rm = loc_reg(rhs); - if (loc_is_fp(dst)) { + if (native_loc_is_fp(dst)) { u32 d = type_size32(t, dst.type) == 8u; switch (op) { case BO_FADD: @@ -2231,7 +2229,7 @@ static void aa_binop(NativeTarget* t, BinOp op, NativeLoc dst, NativeLoc lhs, static void aa_unop(NativeTarget* t, UnOp op, NativeLoc dst, NativeLoc src) { u32 sf = loc_is_64(t, dst) ? 1u : 0u; - if (loc_is_fp(dst)) { + if (native_loc_is_fp(dst)) { switch (op) { case UO_FNEG: case UO_NEG: @@ -2260,7 +2258,7 @@ static void aa_unop(NativeTarget* t, UnOp op, NativeLoc dst, NativeLoc src) { static void aa_emit_cmp_to_flags(NativeTarget* t, NativeLoc lhs, NativeLoc rhs) { - if (loc_is_fp(lhs)) { + if (native_loc_is_fp(lhs)) { aa_emit32(t->mc, aa_fcmp(type_size32(t, lhs.type) == 8u, loc_reg(lhs), loc_reg(rhs))); return; @@ -2305,8 +2303,8 @@ static void aa_cmp(NativeTarget* t, CmpOp op, NativeLoc dst, NativeLoc lhs, static void aa_convert(NativeTarget* t, ConvKind op, NativeLoc dst, NativeLoc src) { - int dst_fp = loc_is_fp(dst); - int src_fp = loc_is_fp(src); + int dst_fp = native_loc_is_fp(dst); + int src_fp = native_loc_is_fp(src); switch (op) { case CV_TRUNC: case CV_BITCAST: @@ -2412,27 +2410,7 @@ static MemAccess aa_mem_for_type(NativeTarget* t, KitCgTypeId type, u32 size) { return mem; } -static NativeLoc aa_reg_loc(KitCgTypeId type, NativeAllocClass cls, Reg reg) { - NativeLoc loc; - memset(&loc, 0, sizeof loc); - loc.kind = NATIVE_LOC_REG; - loc.cls = (u8)cls; - loc.type = type; - loc.v.reg = reg; - return loc; -} - -static NativeLoc aa_stack_loc(KitCgTypeId type, NativeFrameSlot slot, - i32 offset) { - NativeLoc loc; - memset(&loc, 0, sizeof loc); - loc.kind = NATIVE_LOC_STACK; - loc.cls = NATIVE_REG_INT; - loc.type = type; - loc.v.stack.slot = slot; - loc.v.stack.offset = offset; - return loc; -} +/* native_loc_reg / native_loc_stack are shared in native_target.h. */ static NativeAddr aa_loc_addr(AANativeTarget* a, NativeLoc loc, u32 offset) { NativeAddr addr; @@ -2712,7 +2690,7 @@ static void aa_plan_call(NativeTarget* t, const NativeCallDesc* desc, if (plan->callee.kind == NATIVE_LOC_REG && (NativeAllocClass)plan->callee.cls == NATIVE_REG_INT && plan->callee.v.reg < 8u) { - NativeLoc scratch = aa_reg_loc(plan->callee.type, NATIVE_REG_INT, AA_TMP0); + NativeLoc scratch = native_loc_reg(plan->callee.type, NATIVE_REG_INT, AA_TMP0); aa_move(t, scratch, plan->callee); plan->callee = scratch; } @@ -2737,7 +2715,7 @@ static void aa_plan_call(NativeTarget* t, const NativeCallDesc* desc, if (ai->kind == ABI_ARG_IGNORE) continue; if (force_stack) { NativeLoc tmpreg = - aa_reg_loc(desc->args[i].type, NATIVE_REG_INT, AA_TMP0); + native_loc_reg(desc->args[i].type, NATIVE_REG_INT, AA_TMP0); u32 n = aa_class_stack_size(ai); u32 off = 0; while (off < n) { @@ -2751,14 +2729,14 @@ static void aa_plan_call(NativeTarget* t, const NativeCallDesc* desc, if (ai->kind == ABI_ARG_INDIRECT) { if (next_int < 8u) { AAArgMove* m = &moves[nmoves++]; - m->dst = aa_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, + m->dst = native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, next_int++); m->src = desc->args[i]; m->src_offset = 0; m->size = 8; m->is_addr = 1; } else { - NativeLoc ptr = aa_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), + NativeLoc ptr = native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, AA_TMP0); aa_addr_of_loc(t, ptr, desc->args[i]); aa_store_outgoing_part(t, tail_call, stack, ptr, 8); @@ -2773,14 +2751,14 @@ static void aa_plan_call(NativeTarget* t, const NativeCallDesc* desc, if ((cls == NATIVE_REG_FP && next_fp < 8u) || (cls == NATIVE_REG_INT && next_int < 8u)) { AAArgMove* m = &moves[nmoves++]; - m->dst = aa_reg_loc(desc->args[i].type, cls, + m->dst = native_loc_reg(desc->args[i].type, cls, cls == NATIVE_REG_FP ? next_fp++ : next_int++); m->src = desc->args[i]; m->src_offset = part->src_offset; m->size = part->size; m->is_addr = 0; } else { - NativeLoc tmpreg = aa_reg_loc(desc->args[i].type, cls, + NativeLoc tmpreg = native_loc_reg(desc->args[i].type, cls, cls == NATIVE_REG_FP ? 16u : AA_TMP0); aa_load_part(t, tmpreg, desc->args[i], part->src_offset, part->size); stack = align_up_u32(stack, aa_part_stack_align(part)); @@ -2796,10 +2774,10 @@ static void aa_plan_call(NativeTarget* t, const NativeCallDesc* desc, * register. */ if (abi && abi->has_sret) { NativeLoc x8 = - aa_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, 8u); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, 8u); if (desc->flags & CG_CALL_TAIL) { AANativeTarget* a = aa_of(t); - NativeLoc saved = aa_stack_loc(x8.type, a->sret_ptr_slot, 0); + NativeLoc saved = native_loc_stack(x8.type, a->sret_ptr_slot, 0); aa_load_part(t, x8, saved, 0, 8); } else if (desc->nresults) { aa_addr_of_loc(t, x8, desc->results[0]); @@ -2813,11 +2791,11 @@ static void aa_plan_call(NativeTarget* t, const NativeCallDesc* desc, NativeAllocClass cls = part->cls == ABI_CLASS_FP ? NATIVE_REG_FP : NATIVE_REG_INT; KitCgTypeId pty = aa_part_scalar_type(part); - rets[nr].src = aa_reg_loc(pty, cls, cls == NATIVE_REG_FP ? nf++ : ni++); + rets[nr].src = native_loc_reg(pty, cls, cls == NATIVE_REG_FP ? nf++ : ni++); rets[nr].dst = desc->results[0]; if (rets[nr].dst.kind == NATIVE_LOC_FRAME) rets[nr].dst = - aa_stack_loc(pty, desc->results[0].v.frame, (i32)part->src_offset); + native_loc_stack(pty, desc->results[0].v.frame, (i32)part->src_offset); else if (rets[nr].dst.kind == NATIVE_LOC_STACK) { rets[nr].dst.v.stack.offset += (i32)part->src_offset; rets[nr].dst.type = pty; @@ -2832,7 +2810,7 @@ static void aa_plan_call(NativeTarget* t, const NativeCallDesc* desc, } else if (abi && abi->ret.kind == ABI_ARG_IGNORE) { plan->nrets = 0; } else if (!abi && desc->nresults) { - rets[0].src = aa_reg_loc(desc->results[0].type, NATIVE_REG_INT, 0); + rets[0].src = native_loc_reg(desc->results[0].type, NATIVE_REG_INT, 0); rets[0].dst = desc->results[0]; rets[0].mem = aa_mem_for_type(t, desc->results[0].type, 0); plan->nrets = 1; @@ -2918,8 +2896,8 @@ static void aa_plan_ret(NativeTarget* t, const CGFuncDesc* fd, * would clobber the destination base mid-copy (only triggered once a frame * is large enough that the source offset escapes stur's signed-9 range). */ NativeLoc dstp = - aa_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, AA_X8); - NativeLoc saved = aa_stack_loc(dstp.type, a->sret_ptr_slot, 0); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, AA_X8); + NativeLoc saved = native_loc_stack(dstp.type, a->sret_ptr_slot, 0); NativeAddr dst_addr, src_addr; AggregateAccess access; aa_load_part(t, dstp, saved, 0, 8); @@ -2948,7 +2926,7 @@ static void aa_plan_ret(NativeTarget* t, const CGFuncDesc* fd, rets[nr].src = values[0]; if (rets[nr].src.kind == NATIVE_LOC_FRAME) rets[nr].src = - aa_stack_loc(pty, values[0].v.frame, (i32)part->src_offset); + native_loc_stack(pty, values[0].v.frame, (i32)part->src_offset); else if (rets[nr].src.kind == NATIVE_LOC_STACK) { rets[nr].src.v.stack.offset += (i32)part->src_offset; rets[nr].src.type = pty; @@ -2956,13 +2934,13 @@ static void aa_plan_ret(NativeTarget* t, const CGFuncDesc* fd, rets[nr].src.v.addr.offset += (i32)part->src_offset; rets[nr].src.type = pty; } - rets[nr].dst = aa_reg_loc(pty, cls, cls == NATIVE_REG_FP ? nf++ : ni++); + rets[nr].dst = native_loc_reg(pty, cls, cls == NATIVE_REG_FP ? nf++ : ni++); rets[nr].mem = aa_mem_for_type(t, pty, part->size); nr++; } } else if (nvalues) { rets[0].src = values[0]; - rets[0].dst = aa_reg_loc(values[0].type, NATIVE_REG_INT, 0); + rets[0].dst = native_loc_reg(values[0].type, NATIVE_REG_INT, 0); rets[0].mem = aa_mem_for_type(t, values[0].type, 0); nr = 1; } @@ -3055,7 +3033,7 @@ static int aa_order_release(KitCgMemOrder order) { } static NativeLoc aa_i64_reg_loc(u32 reg) { - return aa_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); + return native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); } static void aa_atomic_addr_reg(NativeTarget* t, NativeAddr addr, u32 reg) { @@ -3255,7 +3233,7 @@ static void aa_intrinsic(NativeTarget* t, IntrinKind kind, memset(&src_addr, 0, sizeof src_addr); switch (kind) { case INTRIN_NONE: - if (ndst == 1u && narg == 3u && loc_is_fp(dsts[0])) { + if (ndst == 1u && narg == 3u && native_loc_is_fp(dsts[0])) { u32 d = type_size32(t, dsts[0].type) == 8u; aa_emit32(t->mc, aa_fp_bin(0x000800u, d, loc_reg(dsts[0]), loc_reg(args[0]), loc_reg(args[1]))); @@ -3813,7 +3791,7 @@ static void aa_bind_native_param(NativeTarget* t, const CGParamDesc* p, NativeAddr d_addr, from; AggregateAccess access; NativeLoc src = - aa_reg_loc(p->type, NATIVE_REG_INT, + native_loc_reg(p->type, NATIVE_REG_INT, a->next_param_int < 8u ? a->next_param_int++ : AA_TMP0); if (src.v.reg == AA_TMP0) { NativeAddr saddr; @@ -3848,16 +3826,16 @@ static void aa_bind_native_param(NativeTarget* t, const CGParamDesc* p, int reg_dst = to_reg && (NativeAllocClass)dst.cls == cls; NativeLoc src; if (cls == NATIVE_REG_FP && a->next_param_fp < 8u) { - src = aa_reg_loc(p->type, cls, a->next_param_fp++); + src = native_loc_reg(p->type, cls, a->next_param_fp++); } else if (cls == NATIVE_REG_INT && a->next_param_int < 8u) { - src = aa_reg_loc(p->type, cls, a->next_param_int++); + src = native_loc_reg(p->type, cls, a->next_param_int++); } else { /* Stack-passed part: load straight into the dst register when possible, * otherwise a scratch for the store-to-frame path. */ Reg tmp = reg_dst ? (Reg)dst.v.reg : (cls == NATIVE_REG_FP ? 16u : AA_TMP0); NativeAddr saddr; - src = aa_reg_loc(p->type, cls, tmp); + src = native_loc_reg(p->type, cls, tmp); a->next_param_stack = align_up_u32(a->next_param_stack, aa_part_stack_align(part)); memset(&saddr, 0, sizeof saddr); @@ -3871,14 +3849,14 @@ static void aa_bind_native_param(NativeTarget* t, const CGParamDesc* p, if (dst.kind == NATIVE_LOC_NONE) { /* Unused parameter: only the ABI cursor advances. */ } else if (to_reg) { - NativeLoc d = aa_reg_loc(dst.type ? dst.type : p->type, + NativeLoc d = native_loc_reg(dst.type ? dst.type : p->type, (NativeAllocClass)dst.cls, (Reg)dst.v.reg); if (!(src.kind == NATIVE_LOC_REG && src.v.reg == d.v.reg && (NativeAllocClass)src.cls == (NativeAllocClass)d.cls)) aa_move(t, d, src); } else { aa_store_part(t, - aa_stack_loc(p->type, dst.v.frame, (i32)part->src_offset), + native_loc_stack(p->type, dst.v.frame, (i32)part->src_offset), src, 0, part->size); } } @@ -3954,7 +3932,7 @@ static NativeAddr aa_direct_materialize_addr(NativeDirectTarget* d, Operand op) { NativeAddr addr = aa_direct_addr(d, op); if (addr.base_kind == NATIVE_ADDR_BASE_FRAME_VALUE) { - NativeLoc base = aa_reg_loc(addr.base_type, NATIVE_REG_INT, AA_TMP1); + NativeLoc base = native_loc_reg(addr.base_type, NATIVE_REG_INT, AA_TMP1); NativeAddr load; memset(&load, 0, sizeof load); load.base_kind = NATIVE_ADDR_BASE_FRAME; @@ -3972,7 +3950,7 @@ static NativeAddr aa_direct_pointer_addr(NativeDirectTarget* d, Operand op) { NativeAddr addr; memset(&addr, 0, sizeof addr); if (op.kind == OPK_LOCAL) { - NativeLoc base = aa_reg_loc(op.type, NATIVE_REG_INT, AA_TMP1); + NativeLoc base = native_loc_reg(op.type, NATIVE_REG_INT, AA_TMP1); NativeAddr load; memset(&load, 0, sizeof load); load.base_kind = NATIVE_ADDR_BASE_FRAME; @@ -4001,7 +3979,7 @@ static NativeAddr aa_reg_addr(KitCgTypeId type, u32 reg, i32 offset) { static void aa_load_ap_addr(NativeDirectTarget* d, Operand ap_addr, u32 dst_reg) { NativeLoc dst = - aa_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, dst_reg); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, dst_reg); NativeAddr ap = aa_direct_pointer_addr(d, ap_addr); d->native->load_addr(d->native, dst, ap); } @@ -4024,7 +4002,7 @@ static void aa_va_start_core(AANativeTarget* a, NativeAddr ap) { NativeTarget* t = &a->base; ABIVaListInfo vai = abi_va_list_layout(t->c->abi); NativeLoc ptr = - aa_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, AA_TMP0); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, AA_TMP0); if (vai.kind == ABI_VA_LIST_POINTER) { /* `va_list = &<first vararg>`. Variadic stack args follow the fixed * incoming params in the same caller window, so the offset is the @@ -4036,7 +4014,7 @@ static void aa_va_start_core(AANativeTarget* a, NativeAddr ap) { } if (vai.kind == ABI_VA_LIST_AAPCS64) { KitCgTypeId i32_ty = builtin_id(KIT_CG_BUILTIN_I32); - NativeLoc i32tmp = aa_reg_loc(i32_ty, NATIVE_REG_INT, AA_TMP1); + NativeLoc i32tmp = native_loc_reg(i32_ty, NATIVE_REG_INT, AA_TMP1); MemAccess ptr_mem = aa_mem_for_type(t, ptr.type, 8); MemAccess i32_mem = aa_mem_for_type(t, i32_ty, 4); AANativeSlot* gr = aa_slot(a, a->va_gr_slot); @@ -4082,7 +4060,7 @@ static void aa_va_arg_core(AANativeTarget* a, NativeLoc dst, NativeAddr ap, NativeTarget* t = &a->base; ABIVaListInfo vai = abi_va_list_layout(t->c->abi); NativeLoc cur = - aa_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, AA_TMP0); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, AA_TMP0); /* The fetched value is written directly into the caller-provided register * `dst`, which the caller guarantees is distinct from the va_list base * register. Only TMP0/TMP1 are used as private scratch. */ @@ -4098,14 +4076,14 @@ static void aa_va_arg_core(AANativeTarget* a, NativeLoc dst, NativeAddr ap, aa_emit_mem(a, 1, cur, ap, ptr_mem); src = aa_reg_addr(type, AA_TMP0, 0); aa_emit_add_imm(a, AA_TMP1, AA_TMP0, 8); - aa_emit_mem(a, 0, aa_reg_loc(cur.type, NATIVE_REG_INT, AA_TMP1), ap, + aa_emit_mem(a, 0, native_loc_reg(cur.type, NATIVE_REG_INT, AA_TMP1), ap, ptr_mem); aa_emit_mem(a, 1, val, src, val_mem); return; } if (vai.kind == ABI_VA_LIST_AAPCS64) { KitCgTypeId i32_ty = builtin_id(KIT_CG_BUILTIN_I32); - NativeLoc off = aa_reg_loc(i32_ty, NATIVE_REG_INT, AA_TMP1); + NativeLoc off = native_loc_reg(i32_ty, NATIVE_REG_INT, AA_TMP1); MemAccess i32_mem = aa_mem_for_type(t, i32_ty, 4); int is_fp = cg_type_is_float(t->c, type); u32 base = aa_va_base_reg(a, ap); @@ -4147,7 +4125,7 @@ static void aa_va_copy_core(AANativeTarget* a, NativeAddr dst_ap, NativeTarget* t = &a->base; ABIVaListInfo vai = abi_va_list_layout(t->c->abi); NativeLoc tmp = - aa_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, AA_TMP0); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, AA_TMP0); MemAccess mem = aa_mem_for_type(t, tmp.type, 8); if (vai.kind == ABI_VA_LIST_POINTER) { aa_emit_mem(a, 1, tmp, src_ap, mem); @@ -4188,7 +4166,7 @@ static void aa_va_arg_(NativeDirectTarget* d, Operand dst_op, Operand ap_addr, KitCgTypeId type) { AANativeTarget* a = aa_of(d->native); int is_fp = cg_type_is_float(d->base.c, type); - NativeLoc res = aa_reg_loc(type, is_fp ? NATIVE_REG_FP : NATIVE_REG_INT, + NativeLoc res = native_loc_reg(type, is_fp ? NATIVE_REG_FP : NATIVE_REG_INT, is_fp ? 16u : 9u); MemAccess val_mem = aa_mem_for_type(d->native, type, type_size32(d->native, type)); @@ -4444,14 +4422,14 @@ static void aa_asm_save_one(AANativeTarget* a, AAAsmSavedClobber* s) { addr.base_kind = NATIVE_ADDR_BASE_FRAME; addr.base.frame = s->slot; addr.base_type = s->type; - reg = aa_reg_loc(s->type, s->cls, s->reg); + reg = native_loc_reg(s->type, s->cls, s->reg); aa_emit_mem(a, 0, reg, addr, aa_mem_for_type(&a->base, s->type, 8)); } AA_UNUSED_FN static void aa_asm_restore_one(AANativeTarget* a, const AAAsmSavedClobber* s) { NativeAddr addr; - NativeLoc reg = aa_reg_loc(s->type, s->cls, s->reg); + NativeLoc reg = native_loc_reg(s->type, s->cls, s->reg); memset(&addr, 0, sizeof addr); addr.base_kind = NATIVE_ADDR_BASE_FRAME; addr.base.frame = s->slot; @@ -4514,13 +4492,13 @@ static void aa_direct_asm_block(NativeDirectTarget* d, const char* tmpl, KitCgTypeId type = outs[i].type ? outs[i].type : out_ops[i].type; aa_asm_bound_reg(&bound_outs[i], type, cls, reg); if (outs[i].dir == KIT_CG_ASM_INOUT) { - NativeLoc loc = aa_reg_loc(type, cls, reg); + NativeLoc loc = native_loc_reg(type, cls, reg); aa_direct_load_operand_to_reg(d, out_ops[i], loc); } } else if (body[0] == 'm') { Reg reg = aa_asm_alloc_reg(d, NATIVE_REG_INT, &used_int, &used_fp); NativeLoc loc = - aa_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); KitCgTypeId type = outs[i].type ? outs[i].type : out_ops[i].type; aa_direct_load_address_to_reg(d, out_ops[i], loc); aa_asm_bound_mem(&bound_outs[i], type, reg); @@ -4542,7 +4520,7 @@ static void aa_direct_asm_block(NativeDirectTarget* d, const char* tmpl, bound_ins[i] = bound_outs[matched]; aa_direct_load_operand_to_reg( d, in_ops[i], - aa_reg_loc(bound_ins[i].type, + native_loc_reg(bound_ins[i].type, bound_ins[i].pad[0] == AA64_INLINE_OPCLS_FP ? NATIVE_REG_FP : NATIVE_REG_INT, @@ -4554,7 +4532,7 @@ static void aa_direct_asm_block(NativeDirectTarget* d, const char* tmpl, Reg reg = aa_asm_alloc_reg(d, cls, &used_int, &used_fp); KitCgTypeId type = ins[i].type ? ins[i].type : in_ops[i].type; aa_asm_bound_reg(&bound_ins[i], type, cls, reg); - aa_direct_load_operand_to_reg(d, in_ops[i], aa_reg_loc(type, cls, reg)); + aa_direct_load_operand_to_reg(d, in_ops[i], native_loc_reg(type, cls, reg)); } else if (body[0] == 'i') { if (in_ops[i].kind != OPK_IMM) aa_asm_panic(d, "immediate constraint requires immediate operand"); @@ -4562,7 +4540,7 @@ static void aa_direct_asm_block(NativeDirectTarget* d, const char* tmpl, } else if (body[0] == 'm') { Reg reg = aa_asm_alloc_reg(d, NATIVE_REG_INT, &used_int, &used_fp); NativeLoc loc = - aa_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); KitCgTypeId type = ins[i].type ? ins[i].type : in_ops[i].type; aa_direct_load_address_to_reg(d, in_ops[i], loc); aa_asm_bound_mem(&bound_ins[i], type, reg); @@ -4585,7 +4563,7 @@ static void aa_direct_asm_block(NativeDirectTarget* d, const char* tmpl, if (bound_outs[i].kind != AA64_INLINE_OPK_REG) continue; cls = bound_outs[i].pad[0] == AA64_INLINE_OPCLS_FP ? NATIVE_REG_FP : NATIVE_REG_INT; - src = aa_reg_loc(bound_outs[i].type, cls, (Reg)bound_outs[i].v.local); + src = native_loc_reg(bound_outs[i].type, cls, (Reg)bound_outs[i].v.local); aa_direct_store_reg_to_operand(d, out_ops[i], src); } for (u32 i = nsaved; i > 0; --i) @@ -4719,7 +4697,7 @@ static void aa_asm_block_native(NativeTarget* t, const char* tmpl, if (ntmp >= 2u) aa_asm_panic_at(c, loc, "too many memory asm operands"); r = (ntmp == 0u) ? AA_TMP0 : AA_TMP1; ntmp++; - inloc = aa_reg_loc(type, NATIVE_REG_INT, r); + inloc = native_loc_reg(type, NATIVE_REG_INT, r); aa_emit_mem(a, 1, inloc, aa_asm_loc_to_addr(a, loc, in_locs[i]), aa_mem_for_type(t, type, type_size32(t, type))); } diff --git a/src/arch/native_target.h b/src/arch/native_target.h @@ -5,6 +5,7 @@ #include "arch/mc.h" #include "cg/cgtarget.h" +#include "cg/type.h" #include "core/core.h" /* NativeTarget is the physical native-emission contract. It is driven after @@ -507,4 +508,71 @@ static inline NativeLoc native_loc_none(void) { return loc; } +/* Target-neutral location constructors and scalar queries. These are + * byte-identical across the native backends, so they live here as the single + * source of truth. (loc_reg's register mask differs per arch and stays + * per-backend.) */ +static inline NativeLoc native_loc_reg(KitCgTypeId type, NativeAllocClass cls, + Reg reg) { + NativeLoc loc; + memset(&loc, 0, sizeof loc); + loc.kind = NATIVE_LOC_REG; + loc.cls = (u8)cls; + loc.type = type; + loc.v.reg = reg; + return loc; +} + +static inline NativeLoc native_loc_stack(KitCgTypeId type, NativeFrameSlot slot, + i32 offset) { + NativeLoc loc; + memset(&loc, 0, sizeof loc); + loc.kind = NATIVE_LOC_STACK; + loc.cls = NATIVE_REG_INT; + loc.type = type; + loc.v.stack.slot = slot; + loc.v.stack.offset = offset; + return loc; +} + +static inline int native_loc_is_fp(NativeLoc loc) { + return (NativeAllocClass)loc.cls == NATIVE_REG_FP; +} + +/* Scalar size/align, clamped to a usable register-sized default. Shared by the + * backends whose scalars are at most pointer-width (x64, rv64); aa64 keeps its + * own size query because it asserts on over-wide scalars. */ +static inline u32 native_type_size(NativeTarget* t, KitCgTypeId type) { + u64 n = type ? cg_type_size(t->c, type) : 8u; + if (n == 0) n = 8u; + return (u32)n; +} + +static inline u32 native_type_align(NativeTarget* t, KitCgTypeId type) { + u64 n = type ? cg_type_align(t->c, type) : 8u; + if (n == 0) n = 1u; + if (n > 16u) n = 16u; + return (u32)n; +} + +static inline MemAccess native_mem_for_type(NativeTarget* t, KitCgTypeId type, + u32 size) { + MemAccess m; + memset(&m, 0, sizeof m); + m.type = type; + m.size = size ? size : native_type_size(t, type); + m.align = native_type_align(t, type); + return m; +} + +/* FP register class for a scalar type, FP only when float and <= 8 bytes. + * aa64 keeps its own (the predicate is the same, but it pairs with a distinct + * mem helper). */ +static inline NativeAllocClass native_class_for_type_fp_le8(NativeTarget* t, + KitCgTypeId type) { + if (type && cg_type_is_float(t->c, type) && cg_type_size(t->c, type) <= 8u) + return NATIVE_REG_FP; + return NATIVE_REG_INT; +} + #endif diff --git a/src/arch/rv64/native.c b/src/arch/rv64/native.c @@ -290,67 +290,19 @@ static u32 rv_fp_pair_off(const RvNativeTarget* a, u32 frame_size) { /* ============================ type helpers ============================ */ -static u32 rv_type_size(NativeTarget* t, KitCgTypeId type) { - u64 n = type ? cg_type_size(t->c, type) : 8u; - if (n == 0) n = 8u; - return (u32)n; -} - -static u32 rv_type_align(NativeTarget* t, KitCgTypeId type) { - u64 n = type ? cg_type_align(t->c, type) : 8u; - if (n == 0) n = 1u; - if (n > 16u) n = 16u; - return (u32)n; -} +/* Scalar size/align/mem/class/loc constructors are shared in native_target.h + * (native_type_size, native_type_align, native_mem_for_type, + * native_class_for_type_fp_le8, native_loc_reg, native_loc_stack, + * native_loc_is_fp). loc_reg's mask is arch-specific and stays here. */ /* A scalar value occupies a 64-bit register when it is pointer-sized or wider, * else it is a 32-bit value (drives ADDW vs ADD selection etc). */ static int rv_is_64(NativeTarget* t, KitCgTypeId type) { - return rv_type_size(t, type) >= 8u || cg_type_is_ptr(t->c, type); + return native_type_size(t, type) >= 8u || cg_type_is_ptr(t->c, type); } -static int loc_is_fp(NativeLoc loc) { - return (NativeAllocClass)loc.cls == NATIVE_REG_FP; -} static u32 loc_reg(NativeLoc loc) { return loc.v.reg & 0x1fu; } -static NativeAllocClass rv_class_for_type(NativeTarget* t, KitCgTypeId type) { - if (type && cg_type_is_float(t->c, type) && cg_type_size(t->c, type) <= 8u) - return NATIVE_REG_FP; - return NATIVE_REG_INT; -} - -static MemAccess rv_mem_for_type(NativeTarget* t, KitCgTypeId type, u32 size) { - MemAccess m; - memset(&m, 0, sizeof m); - m.type = type; - m.size = size ? size : rv_type_size(t, type); - m.align = rv_type_align(t, type); - return m; -} - -static NativeLoc rv_reg_loc(KitCgTypeId type, NativeAllocClass cls, Reg reg) { - NativeLoc loc; - memset(&loc, 0, sizeof loc); - loc.kind = NATIVE_LOC_REG; - loc.cls = (u8)cls; - loc.type = type; - loc.v.reg = reg; - return loc; -} - -static NativeLoc rv_stack_loc(KitCgTypeId type, NativeFrameSlot slot, - i32 offset) { - NativeLoc loc; - memset(&loc, 0, sizeof loc); - loc.kind = NATIVE_LOC_STACK; - loc.cls = NATIVE_REG_INT; - loc.type = type; - loc.v.stack.slot = slot; - loc.v.stack.offset = offset; - return loc; -} - /* ============================ register tables ============================ */ #define RV_PHYS_INT_ARG(r, idx) \ @@ -672,8 +624,8 @@ static void rv_emit_mem(RvNativeTarget* a, int is_load, NativeLoc reg, NativeTarget* t = &a->base; MCEmitter* mc = t->mc; u32 r = loc_reg(reg); - int fp = loc_is_fp(reg); - u32 sz = mem.size ? mem.size : rv_type_size(t, reg.type); + int fp = native_loc_is_fp(reg); + u32 sz = mem.size ? mem.size : native_type_size(t, reg.type); u32 base; i32 off; @@ -692,21 +644,21 @@ static void rv_emit_mem(RvNativeTarget* a, int is_load, NativeLoc reg, static void rv_move(NativeTarget* t, NativeLoc dst, NativeLoc src) { MCEmitter* mc = t->mc; - int dfp = loc_is_fp(dst), sfp = loc_is_fp(src); + int dfp = native_loc_is_fp(dst), sfp = native_loc_is_fp(src); u32 rd = loc_reg(dst), rs = loc_reg(src); if (dfp && sfp) { - u32 fmt = rv_type_size(t, dst.type) == 8u ? RV_FMT_D : RV_FMT_S; + u32 fmt = native_type_size(t, dst.type) == 8u ? RV_FMT_D : RV_FMT_S; if (rd == rs) return; rv64_emit32(mc, rv_fsgnj(fmt, rd, rs, rs)); return; } if (!dfp && sfp) { - u32 sz = rv_type_size(t, src.type); + u32 sz = native_type_size(t, src.type); rv64_emit32(mc, sz == 8u ? rv_fmv_x_d(rd, rs) : rv_fmv_x_w(rd, rs)); return; } if (dfp && !sfp) { - u32 sz = rv_type_size(t, dst.type); + u32 sz = native_type_size(t, dst.type); rv64_emit32(mc, sz == 8u ? rv_fmv_d_x(rd, rs) : rv_fmv_w_x(rd, rs)); return; } @@ -722,7 +674,7 @@ static void rv_load_const(NativeTarget* t, NativeLoc dst, ConstBytes cb) { RvNativeTarget* a = rv_of(t); u64 v = 0; u32 i; - if (!loc_is_fp(dst)) { + if (!native_loc_is_fp(dst)) { for (i = 0; i < cb.size && i < 8u; ++i) v |= (u64)cb.bytes[i] << (i * 8u); rv_load_imm(t, dst, (i64)v); return; @@ -808,8 +760,8 @@ static void rv_copy_bytes(NativeTarget* t, NativeAddr dst, NativeAddr src, MCEmitter* mc = t->mc; KitCgTypeId i64t = builtin_id(KIT_CG_BUILTIN_I64); u32 rem = access.size; - rv_load_addr(t, rv_reg_loc(i64t, NATIVE_REG_INT, RV_TMP3), dst); - rv_load_addr(t, rv_reg_loc(i64t, NATIVE_REG_INT, RV_TMP0), src); + rv_load_addr(t, native_loc_reg(i64t, NATIVE_REG_INT, RV_TMP3), dst); + rv_load_addr(t, native_loc_reg(i64t, NATIVE_REG_INT, RV_TMP0), src); while (rem) { u32 sz = rem >= 8u ? 8u : rem >= 4u ? 4u : rem >= 2u ? 2u : 1u; rv64_emit32(mc, enc_int_load(sz, 0, RV_TMP1, RV_TMP0, 0)); @@ -826,7 +778,7 @@ static void rv_set_bytes(NativeTarget* t, NativeAddr dst, NativeLoc byte_value, KitCgTypeId i64t = builtin_id(KIT_CG_BUILTIN_I64); u32 bv = loc_reg(byte_value); u32 rem = access.size; - rv_load_addr(t, rv_reg_loc(i64t, NATIVE_REG_INT, RV_TMP3), dst); + rv_load_addr(t, native_loc_reg(i64t, NATIVE_REG_INT, RV_TMP3), dst); while (rem) { rv64_emit32(mc, rv_sb(bv, RV_TMP3, 0)); rv64_emit32(mc, rv_addi(RV_TMP3, RV_TMP3, 1)); @@ -851,7 +803,7 @@ static void rv_binop(NativeTarget* t, BinOp op, NativeLoc dst, NativeLoc aop, case BO_FSUB: case BO_FMUL: case BO_FDIV: { - u32 fmt = rv_type_size(t, dst.type) == 8u ? RV_FMT_D : RV_FMT_S; + u32 fmt = native_type_size(t, dst.type) == 8u ? RV_FMT_D : RV_FMT_S; switch (op) { case BO_FADD: rv64_emit32(mc, rv_fadd(fmt, rd, ra, rb)); @@ -943,7 +895,7 @@ static void rv_unop(NativeTarget* t, UnOp op, NativeLoc dst, NativeLoc src) { rv64_emit32(mc, sf ? rv_sub(rd, RV_ZERO, rs) : rv_subw(rd, RV_ZERO, rs)); return; case UO_FNEG: { - u32 fmt = rv_type_size(t, dst.type) == 8u ? RV_FMT_D : RV_FMT_S; + u32 fmt = native_type_size(t, dst.type) == 8u ? RV_FMT_D : RV_FMT_S; rv64_emit32(mc, rv_fsgnjn(fmt, rd, rs, rs)); return; } @@ -1053,7 +1005,7 @@ static void rv_cmp(NativeTarget* t, CmpOp op, NativeLoc dst, NativeLoc aop, * primitive and OR the two strict relations (a<b | a>b) via scratch RV_TMP2 * (x7, reserved & never allocable, so it can't alias rd). */ if (op >= CMP_OEQ_F) { - u32 fmt = rv_type_size(t, aop.type) == 8u ? RV_FMT_D : RV_FMT_S; + u32 fmt = native_type_size(t, aop.type) == 8u ? RV_FMT_D : RV_FMT_S; u32 ra = loc_reg(aop), rb = loc_reg(bop); switch (op) { case CMP_OEQ_F: @@ -1118,8 +1070,8 @@ static void rv_convert(NativeTarget* t, ConvKind op, NativeLoc dst, NativeLoc src) { MCEmitter* mc = t->mc; u32 rd = loc_reg(dst), rs = loc_reg(src); - u32 src_sz = rv_type_size(t, src.type); - u32 dst_sz = rv_type_size(t, dst.type); + u32 src_sz = native_type_size(t, src.type); + u32 dst_sz = native_type_size(t, dst.type); switch (op) { case CV_SEXT: if (src_sz >= 4u) { @@ -1141,7 +1093,7 @@ static void rv_convert(NativeTarget* t, ConvKind op, NativeLoc dst, rv64_emit32(mc, rv_addi(rd, rs, 0)); /* low bits; users re-narrow */ return; case CV_ITOF_S: - if (rv_type_size(t, dst.type) == 8u) + if (native_type_size(t, dst.type) == 8u) rv64_emit32(mc, src_sz == 8u ? rv_fcvt_d_l(rd, rs) : rv_fcvt_d_w(rd, rs)); else @@ -1149,7 +1101,7 @@ static void rv_convert(NativeTarget* t, ConvKind op, NativeLoc dst, src_sz == 8u ? rv_fcvt_s_l(rd, rs) : rv_fcvt_s_w(rd, rs)); return; case CV_ITOF_U: - if (rv_type_size(t, dst.type) == 8u) + if (native_type_size(t, dst.type) == 8u) rv64_emit32(mc, src_sz == 8u ? rv_fcvt_d_lu(rd, rs) : rv_fcvt_d_wu(rd, rs)); else @@ -1233,7 +1185,7 @@ static void rv_cmp_branch(NativeTarget* t, CmpOp op, NativeLoc aop, */ if (op >= CMP_OEQ_F) { NativeLoc tmp = - rv_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, RV_TMP0); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, RV_TMP0); rv_cmp(t, op, tmp, aop, bop); /* Skip the jal when the result is 0 (condition false). */ rv64_emit32(mc, rv_beq(RV_TMP0, RV_ZERO, SKIP_JAL)); @@ -1391,8 +1343,8 @@ static void rv_emit_entry_save_stores(RvNativeTarget* a) { addr.base_kind = NATIVE_ADDR_BASE_FRAME; addr.base.frame = a->sret_ptr_slot; addr.base_type = i64t; - rv_emit_mem(a, 0, rv_reg_loc(i64t, NATIVE_REG_INT, RV_A0), addr, - rv_mem_for_type(t, i64t, 8)); + rv_emit_mem(a, 0, native_loc_reg(i64t, NATIVE_REG_INT, RV_A0), addr, + native_mem_for_type(t, i64t, 8)); } } @@ -1770,8 +1722,8 @@ static const ABIArgInfo* rv_param_abi(NativeTarget* t, const ABIFuncInfo* abi, (!variadic && cg_type_is_float(t->c, desc->args[i].type)) ? ABI_CLASS_FP : ABI_CLASS_INT; ((ABIArgPart*)scratch->parts)[0].loc = ABI_LOC_REG; - ((ABIArgPart*)scratch->parts)[0].size = rv_type_size(t, desc->args[i].type); - ((ABIArgPart*)scratch->parts)[0].align = rv_type_align(t, desc->args[i].type); + ((ABIArgPart*)scratch->parts)[0].size = native_type_size(t, desc->args[i].type); + ((ABIArgPart*)scratch->parts)[0].align = native_type_align(t, desc->args[i].type); return scratch; } @@ -1912,7 +1864,7 @@ static void rv_load_part(NativeTarget* t, NativeLoc dst, NativeLoc src, src.kind == NATIVE_LOC_ADDR) { NativeAddr addr = rv_loc_addr(a, src, offset); addr.base_type = dst.type; - rv_emit_mem(a, 1, dst, addr, rv_mem_for_type(t, dst.type, size)); + rv_emit_mem(a, 1, dst, addr, native_mem_for_type(t, dst.type, size)); return; } if (src.kind == NATIVE_LOC_IMM) { @@ -1930,7 +1882,7 @@ static void rv_store_part(NativeTarget* t, NativeLoc dst, NativeLoc src, dst.kind == NATIVE_LOC_ADDR) { NativeAddr addr = rv_loc_addr(a, dst, offset); addr.base_type = src.type; - rv_emit_mem(a, 0, src, addr, rv_mem_for_type(t, src.type, size)); + rv_emit_mem(a, 0, src, addr, native_mem_for_type(t, src.type, size)); return; } if (dst.kind == NATIVE_LOC_REG) { @@ -1962,7 +1914,7 @@ static void rv_store_outgoing_part(NativeTarget* t, int tail_call, addr.base.reg = RV_SP; addr.offset = (i32)stack_off; } - rv_emit_mem(rv_of(t), 0, src, addr, rv_mem_for_type(t, src.type, size)); + rv_emit_mem(rv_of(t), 0, src, addr, native_mem_for_type(t, src.type, size)); } /* NativeTarget bind_param: route incoming param (ABI loc) into dst. */ @@ -1976,7 +1928,7 @@ static void rv_bind_native_param(NativeTarget* t, const CGParamDesc* p, u32 i; if (!ai || ai->kind == ABI_ARG_IGNORE) return; if (ai->kind == ABI_ARG_INDIRECT) { - NativeLoc src = rv_reg_loc( + NativeLoc src = native_loc_reg( builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, a->next_param_int < 8u ? RV_A0 + a->next_param_int : RV_TMP0); NativeAddr d_addr, from; @@ -1990,7 +1942,7 @@ static void rv_bind_native_param(NativeTarget* t, const CGParamDesc* p, sa.base.reg = RV_S0; sa.offset = rv_s0_off_in_arg(a, a->next_param_stack); sa.base_type = src.type; - rv_emit_mem(a, 1, src, sa, rv_mem_for_type(t, src.type, 8)); + rv_emit_mem(a, 1, src, sa, native_mem_for_type(t, src.type, 8)); a->next_param_stack += 8u; } if (dst.kind != NATIVE_LOC_FRAME) @@ -2006,7 +1958,7 @@ static void rv_bind_native_param(NativeTarget* t, const CGParamDesc* p, memset(&access, 0, sizeof access); access.type = p->type; access.size = p->size ? p->size : (u32)cg_type_size(t->c, p->type); - access.align = p->align ? p->align : rv_type_align(t, p->type); + access.align = p->align ? p->align : native_type_align(t, p->type); rv_copy_bytes(t, d_addr, from, access); return; } @@ -2016,13 +1968,13 @@ static void rv_bind_native_param(NativeTarget* t, const CGParamDesc* p, part->cls == ABI_CLASS_FP ? NATIVE_REG_FP : NATIVE_REG_INT; NativeLoc src; if (cls == NATIVE_REG_FP && a->next_param_fp < 8u) { - src = rv_reg_loc(p->type, cls, RV_FA0 + a->next_param_fp++); + src = native_loc_reg(p->type, cls, RV_FA0 + a->next_param_fp++); } else if (cls == NATIVE_REG_INT && a->next_param_int < 8u) { - src = rv_reg_loc(p->type, cls, RV_A0 + a->next_param_int++); + src = native_loc_reg(p->type, cls, RV_A0 + a->next_param_int++); } else { Reg tmp = (cls == NATIVE_REG_FP) ? RV_FTMP0 : RV_TMP0; NativeAddr sa; - src = rv_reg_loc(p->type, cls, tmp); + src = native_loc_reg(p->type, cls, tmp); a->next_param_stack = align_up_u32(a->next_param_stack, rv_part_stack_align(part)); memset(&sa, 0, sizeof sa); @@ -2030,20 +1982,20 @@ static void rv_bind_native_param(NativeTarget* t, const CGParamDesc* p, sa.base.reg = RV_S0; sa.base_type = p->type; sa.offset = rv_s0_off_in_arg(a, a->next_param_stack); - rv_emit_mem(a, 1, src, sa, rv_mem_for_type(t, p->type, part->size)); + rv_emit_mem(a, 1, src, sa, native_mem_for_type(t, p->type, part->size)); a->next_param_stack += rv_part_stack_size(part); } if (dst.kind == NATIVE_LOC_NONE) { /* unused parameter; cursors already advanced */ } else if (to_reg) { - NativeLoc d = rv_reg_loc(dst.type ? dst.type : p->type, + NativeLoc d = native_loc_reg(dst.type ? dst.type : p->type, (NativeAllocClass)dst.cls, (Reg)dst.v.reg); if (!(src.kind == NATIVE_LOC_REG && loc_reg(src) == loc_reg(d) && (NativeAllocClass)src.cls == (NativeAllocClass)d.cls)) rv_move(t, d, src); } else { rv_store_part(t, - rv_stack_loc(p->type, dst.v.frame, (i32)part->src_offset), + native_loc_stack(p->type, dst.v.frame, (i32)part->src_offset), src, 0, part->size); } } @@ -2096,7 +2048,7 @@ static void rv_plan_call(NativeTarget* t, const NativeCallDesc* desc, if (plan->callee.kind == NATIVE_LOC_REG && (NativeAllocClass)plan->callee.cls == NATIVE_REG_INT && plan->callee.v.reg >= RV_A0 && plan->callee.v.reg <= RV_A7) { - NativeLoc scratch = rv_reg_loc(plan->callee.type, NATIVE_REG_INT, RV_TMP0); + NativeLoc scratch = native_loc_reg(plan->callee.type, NATIVE_REG_INT, RV_TMP0); rv_move(t, scratch, plan->callee); plan->callee = scratch; } @@ -2115,7 +2067,7 @@ static void rv_plan_call(NativeTarget* t, const NativeCallDesc* desc, if (ai->kind == ABI_ARG_IGNORE) continue; if (force_stack) { NativeLoc tmpreg = - rv_reg_loc(desc->args[i].type, NATIVE_REG_INT, RV_TMP0); + native_loc_reg(desc->args[i].type, NATIVE_REG_INT, RV_TMP0); u32 n = rv_class_stack_size(ai), off = 0; while (off < n) { rv_load_part(t, tmpreg, desc->args[i], off, 8); @@ -2128,13 +2080,13 @@ static void rv_plan_call(NativeTarget* t, const NativeCallDesc* desc, if (ai->kind == ABI_ARG_INDIRECT) { if (next_int < 8u) { RvArgMove* m = &moves[nmoves++]; - m->dst = rv_reg_loc(i64t, NATIVE_REG_INT, RV_A0 + next_int++); + m->dst = native_loc_reg(i64t, NATIVE_REG_INT, RV_A0 + next_int++); m->src = desc->args[i]; m->src_offset = 0; m->size = 8; m->is_addr = 1; } else { - NativeLoc ptr = rv_reg_loc(i64t, NATIVE_REG_INT, RV_TMP0); + NativeLoc ptr = native_loc_reg(i64t, NATIVE_REG_INT, RV_TMP0); rv_addr_of_loc(t, ptr, desc->args[i]); rv_store_outgoing_part(t, tail, stack, ptr, 8); stack += 8u; @@ -2150,14 +2102,14 @@ static void rv_plan_call(NativeTarget* t, const NativeCallDesc* desc, RvArgMove* m = &moves[nmoves++]; Reg areg = cls == NATIVE_REG_FP ? RV_FA0 + next_fp++ : RV_A0 + next_int++; - m->dst = rv_reg_loc(desc->args[i].type, cls, areg); + m->dst = native_loc_reg(desc->args[i].type, cls, areg); m->src = desc->args[i]; m->src_offset = part->src_offset; m->size = part->size; m->is_addr = 0; } else { Reg tmp = cls == NATIVE_REG_FP ? RV_FTMP0 : RV_TMP0; - NativeLoc tmpreg = rv_reg_loc(desc->args[i].type, cls, tmp); + NativeLoc tmpreg = native_loc_reg(desc->args[i].type, cls, tmp); rv_load_part(t, tmpreg, desc->args[i], part->src_offset, part->size); stack = align_up_u32(stack, rv_part_stack_align(part)); rv_store_outgoing_part(t, tail, stack, tmpreg, part->size); @@ -2171,9 +2123,9 @@ static void rv_plan_call(NativeTarget* t, const NativeCallDesc* desc, * the caller's own incoming sret pointer (spilled at entry) so the * sibling writes the result into the caller's caller's destination; * otherwise pass the address of this call's result slot. */ - NativeLoc a0 = rv_reg_loc(i64t, NATIVE_REG_INT, RV_A0); + NativeLoc a0 = native_loc_reg(i64t, NATIVE_REG_INT, RV_A0); if (tail) - rv_load_part(t, a0, rv_stack_loc(i64t, a->sret_ptr_slot, 0), 0, 8); + rv_load_part(t, a0, native_loc_stack(i64t, a->sret_ptr_slot, 0), 0, 8); else rv_addr_of_loc(t, a0, desc->results[0]); } @@ -2186,25 +2138,25 @@ static void rv_plan_call(NativeTarget* t, const NativeCallDesc* desc, part->cls == ABI_CLASS_FP ? NATIVE_REG_FP : NATIVE_REG_INT; KitCgTypeId pty = rv_part_scalar_type(part); Reg rreg = cls == NATIVE_REG_FP ? RV_FA0 + nf++ : RV_A0 + ni++; - rets[nr].src = rv_reg_loc(pty, cls, rreg); + rets[nr].src = native_loc_reg(pty, cls, rreg); rets[nr].dst = desc->results[0]; if (rets[nr].dst.kind == NATIVE_LOC_FRAME) rets[nr].dst = - rv_stack_loc(pty, desc->results[0].v.frame, (i32)part->src_offset); + native_loc_stack(pty, desc->results[0].v.frame, (i32)part->src_offset); else if (rets[nr].dst.kind == NATIVE_LOC_STACK) { rets[nr].dst.v.stack.offset += (i32)part->src_offset; rets[nr].dst.type = pty; } - rets[nr].mem = rv_mem_for_type(t, pty, part->size); + rets[nr].mem = native_mem_for_type(t, pty, part->size); nr++; } plan->nrets = nr; } else if (abi && abi->ret.kind == ABI_ARG_IGNORE) { plan->nrets = 0; } else if (!abi && desc->nresults) { - rets[0].src = rv_reg_loc(desc->results[0].type, NATIVE_REG_INT, RV_A0); + rets[0].src = native_loc_reg(desc->results[0].type, NATIVE_REG_INT, RV_A0); rets[0].dst = desc->results[0]; - rets[0].mem = rv_mem_for_type(t, desc->results[0].type, 0); + rets[0].mem = native_mem_for_type(t, desc->results[0].type, 0); plan->nrets = 1; } } @@ -2285,8 +2237,8 @@ static void rv_plan_ret(NativeTarget* t, const CGFuncDesc* fd, if (nvalues) rets = arena_zarray(t->c->tu, NativeCallPlanRet, 4); if (nvalues && abi && abi->ret.kind == ABI_ARG_INDIRECT) { KitCgTypeId i64t = builtin_id(KIT_CG_BUILTIN_I64); - NativeLoc dstp = rv_reg_loc(i64t, NATIVE_REG_INT, RV_TMP1); - NativeLoc saved = rv_stack_loc(i64t, a->sret_ptr_slot, 0); + NativeLoc dstp = native_loc_reg(i64t, NATIVE_REG_INT, RV_TMP1); + NativeLoc saved = native_loc_stack(i64t, a->sret_ptr_slot, 0); NativeAddr dst_addr, src_addr; AggregateAccess access; rv_load_part(t, dstp, saved, 0, 8); @@ -2299,7 +2251,7 @@ static void rv_plan_ret(NativeTarget* t, const CGFuncDesc* fd, memset(&access, 0, sizeof access); access.type = values[0].type; access.size = (u32)cg_type_size(t->c, values[0].type); - access.align = rv_type_align(t, values[0].type); + access.align = native_type_align(t, values[0].type); rv_copy_bytes(t, dst_addr, src_addr, access); *out_rets = NULL; *out_nrets = 0; @@ -2316,19 +2268,19 @@ static void rv_plan_ret(NativeTarget* t, const CGFuncDesc* fd, rets[nr].src = values[0]; if (rets[nr].src.kind == NATIVE_LOC_FRAME) rets[nr].src = - rv_stack_loc(pty, values[0].v.frame, (i32)part->src_offset); + native_loc_stack(pty, values[0].v.frame, (i32)part->src_offset); else if (rets[nr].src.kind == NATIVE_LOC_STACK) { rets[nr].src.v.stack.offset += (i32)part->src_offset; rets[nr].src.type = pty; } - rets[nr].dst = rv_reg_loc(pty, cls, rreg); - rets[nr].mem = rv_mem_for_type(t, pty, part->size); + rets[nr].dst = native_loc_reg(pty, cls, rreg); + rets[nr].mem = native_mem_for_type(t, pty, part->size); nr++; } } else if (nvalues) { rets[0].src = values[0]; - rets[0].dst = rv_reg_loc(values[0].type, NATIVE_REG_INT, RV_A0); - rets[0].mem = rv_mem_for_type(t, values[0].type, 0); + rets[0].dst = native_loc_reg(values[0].type, NATIVE_REG_INT, RV_A0); + rets[0].mem = native_mem_for_type(t, values[0].type, 0); nr = 1; } *out_rets = rets; @@ -2470,7 +2422,7 @@ static int rv_order_release(KitCgMemOrder o) { * LR/SC and AMO take a base register with no offset) and return it. */ static u32 rv_atomic_addr_reg(RvNativeTarget* a, NativeAddr addr) { NativeLoc dst = - rv_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, RV_TMP0); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, RV_TMP0); rv_load_addr(&a->base, dst, addr); return RV_TMP0; } @@ -2479,7 +2431,7 @@ static void rv_atomic_load(NativeTarget* t, NativeLoc dst, NativeAddr addr, MemAccess mem, KitCgMemOrder mo) { RvNativeTarget* a = rv_of(t); MCEmitter* mc = t->mc; - u32 sf = (mem.size ? mem.size : rv_type_size(t, dst.type)) == 8u ? 1u : 0u; + u32 sf = (mem.size ? mem.size : native_type_size(t, dst.type)) == 8u ? 1u : 0u; u32 base = rv_atomic_addr_reg(a, addr); if (mo == KIT_CG_MO_SEQ_CST) rv64_emit32(mc, rv_fence_rw_rw()); if (rv_order_acquire(mo)) { @@ -2488,7 +2440,7 @@ static void rv_atomic_load(NativeTarget* t, NativeLoc dst, NativeAddr addr, : rv_lr_w(loc_reg(dst), base, 1, 0)); } else { rv64_emit32(mc, - enc_int_load(mem.size ? mem.size : rv_type_size(t, dst.type), 0, + enc_int_load(mem.size ? mem.size : native_type_size(t, dst.type), 0, loc_reg(dst), base, 0)); } } @@ -2497,7 +2449,7 @@ static void rv_atomic_store(NativeTarget* t, NativeAddr addr, NativeLoc src, MemAccess mem, KitCgMemOrder mo) { RvNativeTarget* a = rv_of(t); MCEmitter* mc = t->mc; - u32 sz = mem.size ? mem.size : rv_type_size(t, src.type); + u32 sz = mem.size ? mem.size : native_type_size(t, src.type); /* RV_TMP0 holds the address; never collides with src (an allocable reg). */ u32 base = rv_atomic_addr_reg(a, addr); if (rv_order_release(mo)) rv64_emit32(mc, rv_fence_rw_rw()); @@ -2510,7 +2462,7 @@ static void rv_atomic_rmw(NativeTarget* t, KitCgAtomicOp op, NativeLoc dst, KitCgMemOrder mo) { RvNativeTarget* a = rv_of(t); MCEmitter* mc = t->mc; - u32 sf = (mem.size ? mem.size : rv_type_size(t, dst.type)) == 8u ? 1u : 0u; + u32 sf = (mem.size ? mem.size : native_type_size(t, dst.type)) == 8u ? 1u : 0u; u32 base = rv_atomic_addr_reg(a, addr); /* RV_TMP0 */ u32 vreg = loc_reg(val); u32 rd = loc_reg(dst); @@ -2561,7 +2513,7 @@ static void rv_atomic_cas(NativeTarget* t, NativeLoc prior, NativeLoc ok, KitCgMemOrder success, KitCgMemOrder failure) { RvNativeTarget* a = rv_of(t); MCEmitter* mc = t->mc; - u32 sf = (mem.size ? mem.size : rv_type_size(t, prior.type)) == 8u ? 1u : 0u; + u32 sf = (mem.size ? mem.size : native_type_size(t, prior.type)) == 8u ? 1u : 0u; u32 base = rv_atomic_addr_reg(a, addr); /* RV_TMP0 */ u32 rprior = loc_reg(prior); u32 rexp = loc_reg(expected); @@ -2613,8 +2565,8 @@ static void rv_va_start_core(RvNativeTarget* a, NativeAddr ap) { if (!a->is_variadic) rv_panic(a, "va_start: function not variadic"); /* *ap = s0 + 16 + next_param_int*8 (skip past named-int save slots). */ rv64_emit32(mc, rv_addi(RV_TMP1, RV_S0, 16 + (i32)(a->next_param_int * 8u))); - rv_emit_mem(a, 0, rv_reg_loc(i64t, NATIVE_REG_INT, RV_TMP1), ap, - rv_mem_for_type(t, i64t, 8)); + rv_emit_mem(a, 0, native_loc_reg(i64t, NATIVE_REG_INT, RV_TMP1), ap, + native_mem_for_type(t, i64t, 8)); } static void rv_va_arg_core(RvNativeTarget* a, NativeLoc dst, NativeAddr ap, @@ -2623,40 +2575,40 @@ static void rv_va_arg_core(RvNativeTarget* a, NativeLoc dst, NativeAddr ap, MCEmitter* mc = t->mc; ABIVaListInfo vai = abi_va_list_layout(t->c->abi); KitCgTypeId i64t = builtin_id(KIT_CG_BUILTIN_I64); - u32 sz = rv_type_size(t, type); - NativeLoc cur = rv_reg_loc(i64t, NATIVE_REG_INT, RV_TMP1); + u32 sz = native_type_size(t, type); + NativeLoc cur = native_loc_reg(i64t, NATIVE_REG_INT, RV_TMP1); NativeAddr from; if (vai.kind != ABI_VA_LIST_POINTER) rv_panic(a, "unsupported va_list layout"); if (dst.kind != NATIVE_LOC_REG) rv_panic(a, "va_arg destination must be reg"); /* cur = *ap; load value from [cur]; *ap = cur + 8 (each slot is 8 bytes). */ - rv_emit_mem(a, 1, cur, ap, rv_mem_for_type(t, i64t, 8)); + rv_emit_mem(a, 1, cur, ap, native_mem_for_type(t, i64t, 8)); memset(&from, 0, sizeof from); from.base_kind = NATIVE_ADDR_BASE_REG; from.base.reg = RV_TMP1; from.base_type = type; - if (loc_is_fp(dst)) { + if (native_loc_is_fp(dst)) { /* Variadic FP args sit in the integer save area as their bit pattern; * load into RV_TMP2 and bitcast into the FPR. */ - NativeLoc itmp = rv_reg_loc(type, NATIVE_REG_INT, RV_TMP2); - rv_emit_mem(a, 1, itmp, from, rv_mem_for_type(t, type, sz)); + NativeLoc itmp = native_loc_reg(type, NATIVE_REG_INT, RV_TMP2); + rv_emit_mem(a, 1, itmp, from, native_mem_for_type(t, type, sz)); rv64_emit32(mc, sz == 8u ? rv_fmv_d_x(loc_reg(dst), RV_TMP2) : rv_fmv_w_x(loc_reg(dst), RV_TMP2)); } else { - rv_emit_mem(a, 1, dst, from, rv_mem_for_type(t, type, sz)); + rv_emit_mem(a, 1, dst, from, native_mem_for_type(t, type, sz)); } rv64_emit32(mc, rv_addi(RV_TMP1, RV_TMP1, 8)); - rv_emit_mem(a, 0, cur, ap, rv_mem_for_type(t, i64t, 8)); + rv_emit_mem(a, 0, cur, ap, native_mem_for_type(t, i64t, 8)); } static void rv_va_copy_core(RvNativeTarget* a, NativeAddr dst_ap, NativeAddr src_ap) { NativeTarget* t = &a->base; KitCgTypeId i64t = builtin_id(KIT_CG_BUILTIN_I64); - NativeLoc tmp = rv_reg_loc(i64t, NATIVE_REG_INT, RV_TMP1); + NativeLoc tmp = native_loc_reg(i64t, NATIVE_REG_INT, RV_TMP1); /* va_list is a single 8-byte pointer. */ - rv_emit_mem(a, 1, tmp, src_ap, rv_mem_for_type(t, i64t, 8)); - rv_emit_mem(a, 0, tmp, dst_ap, rv_mem_for_type(t, i64t, 8)); + rv_emit_mem(a, 1, tmp, src_ap, native_mem_for_type(t, i64t, 8)); + rv_emit_mem(a, 0, tmp, dst_ap, native_mem_for_type(t, i64t, 8)); } static NativeAddr rv_va_addr_from_ptr(NativeLoc ap_ptr) { @@ -3237,14 +3189,14 @@ static NativeAddr rv_direct_materialize_addr(NativeDirectTarget* d, RvNativeTarget* a = rv_of(d->native); NativeAddr addr = rv_direct_addr(d, op); if (addr.base_kind == NATIVE_ADDR_BASE_FRAME_VALUE) { - NativeLoc base = rv_reg_loc(addr.base_type, NATIVE_REG_INT, RV_TMP1); + NativeLoc base = native_loc_reg(addr.base_type, NATIVE_REG_INT, RV_TMP1); NativeAddr load; memset(&load, 0, sizeof load); load.base_kind = NATIVE_ADDR_BASE_FRAME; load.base.frame = addr.base.frame; load.base_type = addr.base_type; rv_emit_mem(a, 1, base, load, - rv_mem_for_type(d->native, addr.base_type, 8)); + native_mem_for_type(d->native, addr.base_type, 8)); addr.base_kind = NATIVE_ADDR_BASE_REG; addr.base.reg = RV_TMP1; } @@ -3266,7 +3218,7 @@ static void rv_direct_load_operand_to_reg(NativeDirectTarget* d, Operand op, addr.base_kind = NATIVE_ADDR_BASE_FRAME; addr.base.frame = d->locals[op.v.local - 1u].home; addr.base_type = op.type; - rv_emit_mem(a, 1, dst, addr, rv_mem_for_type(d->native, op.type, 0)); + rv_emit_mem(a, 1, dst, addr, native_mem_for_type(d->native, op.type, 0)); return; case OPK_GLOBAL: addr.base_kind = NATIVE_ADDR_BASE_GLOBAL; @@ -3277,7 +3229,7 @@ static void rv_direct_load_operand_to_reg(NativeDirectTarget* d, Operand op, return; case OPK_INDIRECT: addr = rv_direct_materialize_addr(d, op); - rv_emit_mem(a, 1, dst, addr, rv_mem_for_type(d->native, op.type, 0)); + rv_emit_mem(a, 1, dst, addr, native_mem_for_type(d->native, op.type, 0)); return; } rv_asm_panic(d, "unsupported asm input operand"); @@ -3300,7 +3252,7 @@ static void rv_direct_store_reg_to_operand(NativeDirectTarget* d, Operand op, } else { addr = rv_direct_materialize_addr(d, op); } - rv_emit_mem(a, 0, src, addr, rv_mem_for_type(d->native, op.type, 0)); + rv_emit_mem(a, 0, src, addr, native_mem_for_type(d->native, op.type, 0)); } /* Callee-saved registers an asm block clobbers must be spilled/restored around @@ -3325,8 +3277,8 @@ static void rv_asm_save_one(RvNativeTarget* a, RvAsmSavedClobber* s) { addr.base_kind = NATIVE_ADDR_BASE_FRAME; addr.base.frame = s->slot; addr.base_type = s->type; - rv_emit_mem(a, 0, rv_reg_loc(s->type, s->cls, s->reg), addr, - rv_mem_for_type(&a->base, s->type, 8)); + rv_emit_mem(a, 0, native_loc_reg(s->type, s->cls, s->reg), addr, + native_mem_for_type(&a->base, s->type, 8)); } static void rv_asm_restore_one(RvNativeTarget* a, const RvAsmSavedClobber* s) { NativeAddr addr; @@ -3334,8 +3286,8 @@ static void rv_asm_restore_one(RvNativeTarget* a, const RvAsmSavedClobber* s) { addr.base_kind = NATIVE_ADDR_BASE_FRAME; addr.base.frame = s->slot; addr.base_type = s->type; - rv_emit_mem(a, 1, rv_reg_loc(s->type, s->cls, s->reg), addr, - rv_mem_for_type(&a->base, s->type, 8)); + rv_emit_mem(a, 1, native_loc_reg(s->type, s->cls, s->reg), addr, + native_mem_for_type(&a->base, s->type, 8)); } /* psABI callee-saved: integer s0..s11 (x8,x9,x18..x27), fp fs0..fs11 @@ -3488,9 +3440,9 @@ static void rv_asm_block_native(NativeTarget* t, const char* tmpl, if (ntmp >= 2u) rv_asm_panic_at(c, loc, "too many memory asm operands"); r = (ntmp == 0u) ? RV_TMP0 : RV_TMP1; ntmp++; - inloc = rv_reg_loc(type, NATIVE_REG_INT, r); + inloc = native_loc_reg(type, NATIVE_REG_INT, r); rv_emit_mem(a, 1, inloc, rv_asm_loc_to_addr(a, loc, in_locs[i]), - rv_mem_for_type(t, type, rv_type_size(t, type))); + native_mem_for_type(t, type, native_type_size(t, type))); } rv_asm_bind_native(a, loc, &bound_ins[i], ins[i].str, type, inloc, &ntmp); } @@ -3534,7 +3486,7 @@ NativeTarget* rv64_native_target_new(Compiler* c, ObjBuilder* obj, t->mc = mc; native_frame_init(&a->frame, c); t->regs = &rv_reg_info; - t->class_for_type = rv_class_for_type; + t->class_for_type = native_class_for_type_fp_le8; t->imm_legal = rv_imm_legal; t->addr_legal = rv_addr_legal; t->func_begin = rv_func_begin; @@ -3663,13 +3615,13 @@ static NativeAddr rv_direct_pointer_addr(NativeDirectTarget* d, Operand op) { NativeAddr addr; memset(&addr, 0, sizeof addr); if (op.kind == OPK_LOCAL) { - NativeLoc base = rv_reg_loc(op.type, NATIVE_REG_INT, RV_TMP1); + NativeLoc base = native_loc_reg(op.type, NATIVE_REG_INT, RV_TMP1); NativeAddr load; memset(&load, 0, sizeof load); load.base_kind = NATIVE_ADDR_BASE_FRAME; load.base.frame = d->locals[op.v.local - 1u].home; load.base_type = op.type; - rv_emit_mem(a, 1, base, load, rv_mem_for_type(d->native, op.type, 8)); + rv_emit_mem(a, 1, base, load, native_mem_for_type(d->native, op.type, 8)); addr.base_kind = NATIVE_ADDR_BASE_REG; addr.base.reg = RV_TMP1; addr.base_type = op.type; @@ -3681,7 +3633,7 @@ static NativeAddr rv_direct_pointer_addr(NativeDirectTarget* d, Operand op) { static NativeAddr rv_direct_va_base(NativeDirectTarget* d, Operand ap_addr, Reg reg) { NativeLoc dst = - rv_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); NativeAddr addr; d->native->load_addr(d->native, dst, rv_direct_pointer_addr(d, ap_addr)); memset(&addr, 0, sizeof addr); @@ -3699,26 +3651,26 @@ static void rv_va_arg_(NativeDirectTarget* d, Operand dst, Operand ap_addr, KitCgTypeId type) { RvNativeTarget* a = rv_of(d->native); int is_fp = cg_type_is_float(d->base.c, type); - NativeLoc res = rv_reg_loc(type, is_fp ? NATIVE_REG_FP : NATIVE_REG_INT, + NativeLoc res = native_loc_reg(type, is_fp ? NATIVE_REG_FP : NATIVE_REG_INT, is_fp ? RV_FTMP0 : RV_TMP0); NativeAddr dst_addr; rv_va_arg_core(a, res, rv_direct_va_base(d, ap_addr, RV_TMP3), type); /* Store the fetched value back into the semantic destination. */ dst_addr = rv_direct_addr(d, dst); if (dst_addr.base_kind == NATIVE_ADDR_BASE_FRAME_VALUE) { - NativeLoc base = rv_reg_loc(dst_addr.base_type, NATIVE_REG_INT, RV_TMP1); + NativeLoc base = native_loc_reg(dst_addr.base_type, NATIVE_REG_INT, RV_TMP1); NativeAddr load; memset(&load, 0, sizeof load); load.base_kind = NATIVE_ADDR_BASE_FRAME; load.base.frame = dst_addr.base.frame; load.base_type = dst_addr.base_type; rv_emit_mem(a, 1, base, load, - rv_mem_for_type(d->native, dst_addr.base_type, 8)); + native_mem_for_type(d->native, dst_addr.base_type, 8)); dst_addr.base_kind = NATIVE_ADDR_BASE_REG; dst_addr.base.reg = RV_TMP1; } rv_emit_mem(a, 0, res, dst_addr, - rv_mem_for_type(d->native, type, rv_type_size(d->native, type))); + native_mem_for_type(d->native, type, native_type_size(d->native, type))); } static void rv_va_end_(NativeDirectTarget* d, Operand ap_addr) { (void)d; @@ -3767,11 +3719,11 @@ static void rv_direct_asm_block(NativeDirectTarget* d, const char* tmpl, rv_asm_bound_reg(&bound_outs[i], type, cls, reg); if (outs[i].dir == KIT_CG_ASM_INOUT) rv_direct_load_operand_to_reg(d, out_ops[i], - rv_reg_loc(type, cls, reg)); + native_loc_reg(type, cls, reg)); } else if (body[0] == 'm') { Reg reg = rv_asm_alloc_reg(d, NATIVE_REG_INT, &used_int, &used_fp); NativeLoc lloc = - rv_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); rv_direct_load_address_to_reg(d, out_ops[i], lloc); rv_asm_bound_mem(&bound_outs[i], type, reg); } else { @@ -3793,7 +3745,7 @@ static void rv_direct_asm_block(NativeDirectTarget* d, const char* tmpl, bound_ins[i] = bound_outs[matched]; rv_direct_load_operand_to_reg( d, in_ops[i], - rv_reg_loc(bound_ins[i].type, + native_loc_reg(bound_ins[i].type, bound_ins[i].pad[0] == RV64_INLINE_OPCLS_FP ? NATIVE_REG_FP : NATIVE_REG_INT, @@ -3804,7 +3756,7 @@ static void rv_direct_asm_block(NativeDirectTarget* d, const char* tmpl, NativeAllocClass cls = rv_asm_constraint_class(d, body); Reg reg = rv_asm_alloc_reg(d, cls, &used_int, &used_fp); rv_asm_bound_reg(&bound_ins[i], type, cls, reg); - rv_direct_load_operand_to_reg(d, in_ops[i], rv_reg_loc(type, cls, reg)); + rv_direct_load_operand_to_reg(d, in_ops[i], native_loc_reg(type, cls, reg)); } else if (body[0] == 'i') { if (in_ops[i].kind != OPK_IMM) rv_asm_panic(d, "immediate constraint requires immediate operand"); @@ -3812,7 +3764,7 @@ static void rv_direct_asm_block(NativeDirectTarget* d, const char* tmpl, } else if (body[0] == 'm') { Reg reg = rv_asm_alloc_reg(d, NATIVE_REG_INT, &used_int, &used_fp); NativeLoc lloc = - rv_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); rv_direct_load_address_to_reg(d, in_ops[i], lloc); rv_asm_bound_mem(&bound_ins[i], type, reg); } else { @@ -3833,7 +3785,7 @@ static void rv_direct_asm_block(NativeDirectTarget* d, const char* tmpl, if (bound_outs[i].kind != RV64_INLINE_OPK_REG) continue; cls = bound_outs[i].pad[0] == RV64_INLINE_OPCLS_FP ? NATIVE_REG_FP : NATIVE_REG_INT; - src = rv_reg_loc(bound_outs[i].type, cls, (Reg)bound_outs[i].v.local); + src = native_loc_reg(bound_outs[i].type, cls, (Reg)bound_outs[i].v.local); rv_direct_store_reg_to_operand(d, out_ops[i], src); } for (i = nsaved; i > 0; --i) rv_asm_restore_one(a, &saved[i - 1u]); diff --git a/src/arch/x64/native.c b/src/arch/x64/native.c @@ -145,67 +145,19 @@ static u32 align_up_u32(u32 v, u32 align) { /* ============================ type helpers ============================ */ -static u32 x64_type_size(NativeTarget* t, KitCgTypeId type) { - u64 n = type ? cg_type_size(t->c, type) : 8u; - if (n == 0) n = 8u; - return (u32)n; -} - -static u32 x64_type_align(NativeTarget* t, KitCgTypeId type) { - u64 n = type ? cg_type_align(t->c, type) : 8u; - if (n == 0) n = 1u; - if (n > 16u) n = 16u; - return (u32)n; -} +/* Scalar size/align/mem/class/loc constructors are shared in native_target.h + * (native_type_size, native_type_align, native_mem_for_type, + * native_class_for_type_fp_le8, native_loc_reg, native_loc_stack, + * native_loc_is_fp). loc_reg's mask is arch-specific and stays here. */ /* A scalar value occupies a 64-bit register when it is pointer-sized or wider * (drives REX.W selection). */ static int x64_is_64(NativeTarget* t, KitCgTypeId type) { - return x64_type_size(t, type) >= 8u || cg_type_is_ptr(t->c, type); + return native_type_size(t, type) >= 8u || cg_type_is_ptr(t->c, type); } -static int loc_is_fp(NativeLoc loc) { - return (NativeAllocClass)loc.cls == NATIVE_REG_FP; -} static u32 loc_reg(NativeLoc loc) { return loc.v.reg & 0xfu; } -static NativeAllocClass x64_class_for_type(NativeTarget* t, KitCgTypeId type) { - if (type && cg_type_is_float(t->c, type) && cg_type_size(t->c, type) <= 8u) - return NATIVE_REG_FP; - return NATIVE_REG_INT; -} - -static MemAccess x64_mem_for_type(NativeTarget* t, KitCgTypeId type, u32 size) { - MemAccess m; - memset(&m, 0, sizeof m); - m.type = type; - m.size = size ? size : x64_type_size(t, type); - m.align = x64_type_align(t, type); - return m; -} - -static NativeLoc x64_reg_loc(KitCgTypeId type, NativeAllocClass cls, Reg reg) { - NativeLoc loc; - memset(&loc, 0, sizeof loc); - loc.kind = NATIVE_LOC_REG; - loc.cls = (u8)cls; - loc.type = type; - loc.v.reg = reg; - return loc; -} - -static NativeLoc x64_stack_loc(KitCgTypeId type, NativeFrameSlot slot, - i32 offset) { - NativeLoc loc; - memset(&loc, 0, sizeof loc); - loc.kind = NATIVE_LOC_STACK; - loc.cls = NATIVE_REG_INT; - loc.type = type; - loc.v.stack.slot = slot; - loc.v.stack.offset = offset; - return loc; -} - /* SSE scalar prefix: F2 (double / 8-byte) vs F3 (single / 4-byte). */ static u8 sse_scalar_prefix(u32 size) { return size == 8u ? 0xF2u : 0xF3u; } @@ -546,8 +498,8 @@ static void x64_emit_mem(X64NativeTarget* a, int is_load, NativeLoc reg, NativeTarget* t = &a->base; MCEmitter* mc = t->mc; u32 r = loc_reg(reg); - int fp = loc_is_fp(reg); - u32 sz = mem.size ? mem.size : x64_type_size(t, reg.type); + int fp = native_loc_is_fp(reg); + u32 sz = mem.size ? mem.size : native_type_size(t, reg.type); u32 base, idx, scale; i32 off; @@ -635,21 +587,21 @@ static void x64_emit_mem(X64NativeTarget* a, int is_load, NativeLoc reg, static void x64_move(NativeTarget* t, NativeLoc dst, NativeLoc src) { MCEmitter* mc = t->mc; - int dfp = loc_is_fp(dst), sfp = loc_is_fp(src); + int dfp = native_loc_is_fp(dst), sfp = native_loc_is_fp(src); u32 rd = loc_reg(dst), rs = loc_reg(src); if (dfp && sfp) { if (rd == rs) return; - emit_sse_rr(mc, sse_scalar_prefix(x64_type_size(t, dst.type)), 0x10, rd, + emit_sse_rr(mc, sse_scalar_prefix(native_type_size(t, dst.type)), 0x10, rd, rs); return; } if (dfp && !sfp) { /* movd/movq gpr -> xmm: 66 0F 6E /r */ - int w = x64_type_size(t, dst.type) == 8u; + int w = native_type_size(t, dst.type) == 8u; emit_sse_rr_w(mc, 0x66, 0x6E, w, rd, rs); return; } if (!dfp && sfp) { /* movd/movq xmm -> gpr: 66 0F 7E /r (xmm is reg field) */ - int w = x64_type_size(t, src.type) == 8u; + int w = native_type_size(t, src.type) == 8u; emit_sse_rr_w(mc, 0x66, 0x7E, w, rs, rd); return; } @@ -667,7 +619,7 @@ static void x64_load_const(NativeTarget* t, NativeLoc dst, ConstBytes cb) { u64 v = 0; u32 i; for (i = 0; i < cb.size && i < 8u; ++i) v |= (u64)cb.bytes[i] << (i * 8u); - if (!loc_is_fp(dst)) { + if (!native_loc_is_fp(dst)) { x64_load_imm(t, dst, (i64)v); return; } @@ -782,7 +734,7 @@ static void x64_copy_bytes(NativeTarget* t, NativeAddr dst, NativeAddr src, sa.base_type = ty; da.offset += (i32)i; da.base_type = ty; - val = x64_reg_loc(ty, NATIVE_REG_INT, X64_TMP_INT); + val = native_loc_reg(ty, NATIVE_REG_INT, X64_TMP_INT); memset(&mem, 0, sizeof mem); mem.type = ty; mem.size = s; @@ -896,7 +848,7 @@ static void x64_binop(NativeTarget* t, BinOp op, NativeLoc dst, NativeLoc aop, /* FP binops: two-address. dst = aop op bop. */ if (op == BO_FADD || op == BO_FSUB || op == BO_FMUL || op == BO_FDIV) { u32 ra = loc_reg(aop), rb = loc_reg(bop); - u8 prefix = sse_scalar_prefix(x64_type_size(t, dst.type)); + u8 prefix = sse_scalar_prefix(native_type_size(t, dst.type)); u8 opcode; switch (op) { case BO_FADD: @@ -1090,7 +1042,7 @@ static void x64_unop(NativeTarget* t, UnOp op, NativeLoc dst, NativeLoc src) { MCEmitter* mc = t->mc; u32 rd = loc_reg(dst), rs = loc_reg(src); if (op == UO_FNEG) { - int dbl = x64_type_size(t, dst.type) == 8u; + int dbl = native_type_size(t, dst.type) == 8u; if (rd != rs) emit_sse_rr(mc, sse_scalar_prefix(dbl ? 8u : 4u), 0x10, rd, rs); /* sign mask into fp scratch via gpr, then XORPS/XORPD. */ @@ -1165,7 +1117,7 @@ static void x64_emit_cmp_flags(NativeTarget* t, NativeLoc aop, NativeLoc bop, X64NativeTarget* a = x64_of(t); MCEmitter* mc = t->mc; if (fp) { - u8 prefix = x64_type_size(t, aop.type) == 8u ? 0x66u : 0u; + u8 prefix = native_type_size(t, aop.type) == 8u ? 0x66u : 0u; emit_sse_rr(mc, prefix, 0x2E, loc_reg(aop), loc_reg(bop)); /* ucomis */ return; } @@ -1277,13 +1229,13 @@ static void x64_convert(NativeTarget* t, ConvKind k, NativeLoc dst, u32 rd = loc_reg(dst), rs = loc_reg(src); switch (k) { case CV_SEXT: { - u32 src_sz = x64_type_size(t, src.type); + u32 src_sz = native_type_size(t, src.type); int w = x64_is_64(t, dst.type) ? 1 : 0; emit_extend_rr(mc, w, 1, src_sz, rd, rs); return; } case CV_ZEXT: { - u32 src_sz = x64_type_size(t, src.type); + u32 src_sz = native_type_size(t, src.type); int w = x64_is_64(t, dst.type) ? 1 : 0; emit_extend_rr(mc, w, 0, src_sz, rd, rs); return; @@ -1294,7 +1246,7 @@ static void x64_convert(NativeTarget* t, ConvKind k, NativeLoc dst, case CV_ITOF_S: case CV_ITOF_U: { int w_src = x64_is_64(t, src.type) ? 1 : 0; - u8 prefix = sse_scalar_prefix(x64_type_size(t, dst.type)); + u8 prefix = sse_scalar_prefix(native_type_size(t, dst.type)); if (k == CV_ITOF_U && w_src == 1) { MCLabel L_high = mc->label_new(mc); MCLabel L_done = mc->label_new(mc); @@ -1324,11 +1276,11 @@ static void x64_convert(NativeTarget* t, ConvKind k, NativeLoc dst, case CV_FTOI_S: case CV_FTOI_U: { int w_dst = x64_is_64(t, dst.type) ? 1 : 0; - u8 prefix = sse_scalar_prefix(x64_type_size(t, src.type)); + u8 prefix = sse_scalar_prefix(native_type_size(t, src.type)); /* Unsigned 64-bit FTOI needs the 2^63 bias dance; otherwise cvtt * (with the destination widened to 64 for u32) is exact. */ if (k == CV_FTOI_U && w_dst == 1) { - int dbl = x64_type_size(t, src.type) == 8u; + int dbl = native_type_size(t, src.type) == 8u; MCLabel L_small = mc->label_new(mc); MCLabel L_done = mc->label_new(mc); /* limit = 2^63 in fp scratch. */ @@ -1360,9 +1312,9 @@ static void x64_convert(NativeTarget* t, ConvKind k, NativeLoc dst, emit_sse_rr(mc, 0xF2, 0x5A, rd, rs); /* cvtsd2ss */ return; case CV_BITCAST: - if (!loc_is_fp(src) && loc_is_fp(dst)) { + if (!native_loc_is_fp(src) && native_loc_is_fp(dst)) { emit_sse_rr_w(mc, 0x66, 0x6E, x64_is_64(t, dst.type), rd, rs); - } else if (loc_is_fp(src) && !loc_is_fp(dst)) { + } else if (native_loc_is_fp(src) && !native_loc_is_fp(dst)) { emit_sse_rr_w(mc, 0x66, 0x7E, x64_is_64(t, src.type), rs, rd); } else { x64_move(t, dst, src); @@ -1424,7 +1376,7 @@ static void x64_cmp_branch(NativeTarget* t, CmpOp op, NativeLoc aop, if (fp) { /* Materialize the 0/1 result, then branch on nonzero. */ NativeLoc tmp = - x64_reg_loc(builtin_id(KIT_CG_BUILTIN_I32), NATIVE_REG_INT, X64_RAX); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I32), NATIVE_REG_INT, X64_RAX); x64_cmp(t, op, tmp, aop, bop); emit_test_self(mc, 0, X64_RAX); emit_jcc_rel32(mc, X64_CC_NE, l); @@ -1962,9 +1914,9 @@ static const ABIArgInfo* x64_param_abi(NativeTarget* t, const ABIFuncInfo* abi, ((ABIArgPart*)scratch->parts)[0].cls = cg_type_is_float(t->c, desc->args[i].type) ? ABI_CLASS_FP : ABI_CLASS_INT; ((ABIArgPart*)scratch->parts)[0].loc = ABI_LOC_REG; - ((ABIArgPart*)scratch->parts)[0].size = x64_type_size(t, desc->args[i].type); + ((ABIArgPart*)scratch->parts)[0].size = native_type_size(t, desc->args[i].type); ((ABIArgPart*)scratch->parts)[0].align = - x64_type_align(t, desc->args[i].type); + native_type_align(t, desc->args[i].type); return scratch; } @@ -2094,7 +2046,7 @@ static void x64_load_part(NativeTarget* t, NativeLoc dst, NativeLoc src, src.kind == NATIVE_LOC_ADDR) { NativeAddr addr = x64_loc_addr(a, src, offset); addr.base_type = dst.type; - x64_emit_mem(a, 1, dst, addr, x64_mem_for_type(t, dst.type, size)); + x64_emit_mem(a, 1, dst, addr, native_mem_for_type(t, dst.type, size)); return; } if (src.kind == NATIVE_LOC_IMM) { @@ -2112,7 +2064,7 @@ static void x64_store_part(NativeTarget* t, NativeLoc dst, NativeLoc src, dst.kind == NATIVE_LOC_ADDR) { NativeAddr addr = x64_loc_addr(a, dst, offset); addr.base_type = src.type; - x64_emit_mem(a, 0, src, addr, x64_mem_for_type(t, src.type, size)); + x64_emit_mem(a, 0, src, addr, native_mem_for_type(t, src.type, size)); return; } if (dst.kind == NATIVE_LOC_REG) { @@ -2146,7 +2098,7 @@ static void x64_store_outgoing_part(NativeTarget* t, int tail_call, addr.base.reg = X64_RSP; addr.offset = (i32)stack_off; } - x64_emit_mem(a, 0, src, addr, x64_mem_for_type(t, src.type, size)); + x64_emit_mem(a, 0, src, addr, native_mem_for_type(t, src.type, size)); } /* NativeTarget bind_param: route incoming param (ABI loc) into dst. */ @@ -2223,7 +2175,7 @@ static void x64_bind_native_param(NativeTarget* t, const CGParamDesc* p, memset(&access, 0, sizeof access); access.type = p->type; access.size = p->size ? p->size : (u32)cg_type_size(t->c, p->type); - access.align = p->align ? p->align : x64_type_align(t, p->type); + access.align = p->align ? p->align : native_type_align(t, p->type); x64_copy_bytes(t, d_addr, from, access); return; } @@ -2244,17 +2196,17 @@ static void x64_bind_native_param(NativeTarget* t, const CGParamDesc* p, /* Defer: a register dst may be another param's incoming reg. */ x64_defer_reg_bind( a, - x64_reg_loc(dst.type ? dst.type : p->type, + native_loc_reg(dst.type ? dst.type : p->type, (NativeAllocClass)dst.cls, (Reg)dst.v.reg), isrc, part->size); } else { /* Frame dst: load to scratch then store (memory dst is never a cycle * source, so emit eagerly — it only reads the incoming slot). */ Reg tmp = cls == NATIVE_REG_FP ? X64_TMP_FP : X64_TMP_INT; - NativeLoc tloc = x64_reg_loc(p->type, cls, tmp); + NativeLoc tloc = native_loc_reg(p->type, cls, tmp); x64_load_part(t, tloc, isrc, 0, part->size); x64_store_part( - t, x64_stack_loc(p->type, dst.v.frame, (i32)part->src_offset), tloc, + t, native_loc_stack(p->type, dst.v.frame, (i32)part->src_offset), tloc, 0, part->size); } } @@ -2268,10 +2220,10 @@ static void x64_bind_native_param(NativeTarget* t, const CGParamDesc* p, NativeLoc src; /* incoming: arg register, or NATIVE_LOC_ADDR for a stack arg */ if (cls == NATIVE_REG_FP && a->next_param_fp < a->abi->n_fp_args) { - src = x64_reg_loc(p->type, cls, (Reg)(X64_XMM0 + a->next_param_fp++)); + src = native_loc_reg(p->type, cls, (Reg)(X64_XMM0 + a->next_param_fp++)); } else if (cls == NATIVE_REG_INT && a->next_param_int < a->abi->n_int_args) { - src = x64_reg_loc(p->type, cls, a->abi->int_args[a->next_param_int++]); + src = native_loc_reg(p->type, cls, a->abi->int_args[a->next_param_int++]); } else { src = x64_incoming_stack_loc(p->type, cls, incoming_bias + (i32)a->next_param_stack); @@ -2286,20 +2238,20 @@ static void x64_bind_native_param(NativeTarget* t, const CGParamDesc* p, * another bind still needs. x64_bind_params_end resolves them together as * a parallel copy. */ x64_defer_reg_bind(a, - x64_reg_loc(dst.type ? dst.type : p->type, + native_loc_reg(dst.type ? dst.type : p->type, (NativeAllocClass)dst.cls, (Reg)dst.v.reg), src, part->size); } else if (src.kind == NATIVE_LOC_REG) { x64_store_part(t, - x64_stack_loc(p->type, dst.v.frame, (i32)part->src_offset), + native_loc_stack(p->type, dst.v.frame, (i32)part->src_offset), src, 0, part->size); } else { /* Stack source -> frame dst: load to scratch, then store. */ Reg tmp = cls == NATIVE_REG_FP ? X64_TMP_FP : X64_TMP_INT; - NativeLoc tloc = x64_reg_loc(p->type, cls, tmp); + NativeLoc tloc = native_loc_reg(p->type, cls, tmp); x64_load_part(t, tloc, src, 0, part->size); x64_store_part(t, - x64_stack_loc(p->type, dst.v.frame, (i32)part->src_offset), + native_loc_stack(p->type, dst.v.frame, (i32)part->src_offset), tloc, 0, part->size); } } @@ -2410,7 +2362,7 @@ static void x64_plan_call(NativeTarget* t, const NativeCallDesc* desc, if (plan->callee.kind == NATIVE_LOC_REG && (NativeAllocClass)plan->callee.cls == NATIVE_REG_INT && plan->callee.v.reg != X64_R11) { - NativeLoc scratch = x64_reg_loc(plan->callee.type, NATIVE_REG_INT, X64_R11); + NativeLoc scratch = native_loc_reg(plan->callee.type, NATIVE_REG_INT, X64_R11); x64_move(t, scratch, plan->callee); plan->callee = scratch; } @@ -2431,12 +2383,12 @@ static void x64_plan_call(NativeTarget* t, const NativeCallDesc* desc, X64ArgMove* m = &moves[nmoves++]; memset(m, 0, sizeof *m); m->dst = - x64_reg_loc(i64t, NATIVE_REG_INT, aregs->int_args[next_int++]); + native_loc_reg(i64t, NATIVE_REG_INT, aregs->int_args[next_int++]); m->src = desc->args[i]; m->size = 8; m->is_addr = 1; } else { - NativeLoc ptr = x64_reg_loc(i64t, NATIVE_REG_INT, X64_RAX); + NativeLoc ptr = native_loc_reg(i64t, NATIVE_REG_INT, X64_RAX); x64_addr_of_loc(t, ptr, desc->args[i]); x64_store_outgoing_part(t, tail, stack, ptr, 8); stack += 8u; @@ -2451,7 +2403,7 @@ static void x64_plan_call(NativeTarget* t, const NativeCallDesc* desc, NativeAllocClass cls = part->cls == ABI_CLASS_FP ? NATIVE_REG_FP : NATIVE_REG_INT; Reg tmp = cls == NATIVE_REG_FP ? X64_TMP_FP : X64_TMP_INT; - NativeLoc tmpreg = x64_reg_loc(desc->args[i].type, cls, tmp); + NativeLoc tmpreg = native_loc_reg(desc->args[i].type, cls, tmp); x64_load_part(t, tmpreg, desc->args[i], part->src_offset, part->size); x64_store_outgoing_part(t, tail, stack, tmpreg, part->size); stack += 8u; @@ -2467,7 +2419,7 @@ static void x64_plan_call(NativeTarget* t, const NativeCallDesc* desc, u32 slot = next_fp; memset(m, 0, sizeof *m); m->dst = - x64_reg_loc(desc->args[i].type, cls, (Reg)(X64_XMM0 + next_fp++)); + native_loc_reg(desc->args[i].type, cls, (Reg)(X64_XMM0 + next_fp++)); m->src = desc->args[i]; m->src_offset = part->src_offset; m->size = part->size; @@ -2481,14 +2433,14 @@ static void x64_plan_call(NativeTarget* t, const NativeCallDesc* desc, X64ArgMove* m = &moves[nmoves++]; memset(m, 0, sizeof *m); m->dst = - x64_reg_loc(desc->args[i].type, cls, aregs->int_args[next_int++]); + native_loc_reg(desc->args[i].type, cls, aregs->int_args[next_int++]); m->src = desc->args[i]; m->src_offset = part->src_offset; m->size = part->size; x64_sync_slot(aregs, &next_int, &next_fp); } else { Reg tmp = cls == NATIVE_REG_FP ? X64_TMP_FP : X64_TMP_INT; - NativeLoc tmpreg = x64_reg_loc(desc->args[i].type, cls, tmp); + NativeLoc tmpreg = native_loc_reg(desc->args[i].type, cls, tmp); x64_load_part(t, tmpreg, desc->args[i], part->src_offset, part->size); x64_store_outgoing_part(t, tail, stack, tmpreg, part->size); stack += 8u; @@ -2507,9 +2459,9 @@ static void x64_plan_call(NativeTarget* t, const NativeCallDesc* desc, /* sret pointer in the first int-arg reg. A tail call forwards the * caller's own incoming sret pointer (spilled at entry); otherwise pass * the address of this call's result slot. */ - NativeLoc sret = x64_reg_loc(i64t, NATIVE_REG_INT, aregs->int_args[0]); + NativeLoc sret = native_loc_reg(i64t, NATIVE_REG_INT, aregs->int_args[0]); if (tail) - x64_load_part(t, sret, x64_stack_loc(i64t, a->sret_ptr_slot, 0), 0, 8); + x64_load_part(t, sret, native_loc_stack(i64t, a->sret_ptr_slot, 0), 0, 8); else x64_addr_of_loc(t, sret, desc->results[0]); } @@ -2529,25 +2481,25 @@ static void x64_plan_call(NativeTarget* t, const NativeCallDesc* desc, KitCgTypeId pty = x64_part_scalar_type(part); Reg rreg = cls == NATIVE_REG_FP ? (Reg)(X64_XMM0 + nf++) : (Reg)ret_int_regs[ni++]; - rets[nr].src = x64_reg_loc(pty, cls, rreg); + rets[nr].src = native_loc_reg(pty, cls, rreg); rets[nr].dst = desc->results[0]; if (rets[nr].dst.kind == NATIVE_LOC_FRAME) rets[nr].dst = - x64_stack_loc(pty, desc->results[0].v.frame, (i32)part->src_offset); + native_loc_stack(pty, desc->results[0].v.frame, (i32)part->src_offset); else if (rets[nr].dst.kind == NATIVE_LOC_STACK) { rets[nr].dst.v.stack.offset += (i32)part->src_offset; rets[nr].dst.type = pty; } - rets[nr].mem = x64_mem_for_type(t, pty, part->size); + rets[nr].mem = native_mem_for_type(t, pty, part->size); nr++; } plan->nrets = nr; } else if (abi && abi->ret.kind == ABI_ARG_IGNORE) { plan->nrets = 0; } else if (!abi && desc->nresults) { - rets[0].src = x64_reg_loc(desc->results[0].type, NATIVE_REG_INT, X64_RAX); + rets[0].src = native_loc_reg(desc->results[0].type, NATIVE_REG_INT, X64_RAX); rets[0].dst = desc->results[0]; - rets[0].mem = x64_mem_for_type(t, desc->results[0].type, 0); + rets[0].mem = native_mem_for_type(t, desc->results[0].type, 0); plan->nrets = 1; } } @@ -2645,8 +2597,8 @@ static void x64_plan_ret(NativeTarget* t, const CGFuncDesc* fd, /* sret: reload destination pointer (spilled at entry) into r11, memcpy the * source aggregate into [r11], and convention-return the pointer in rax. */ KitCgTypeId i64t = builtin_id(KIT_CG_BUILTIN_I64); - NativeLoc dstp = x64_reg_loc(i64t, NATIVE_REG_INT, X64_R11); - NativeLoc saved = x64_stack_loc(i64t, a->sret_ptr_slot, 0); + NativeLoc dstp = native_loc_reg(i64t, NATIVE_REG_INT, X64_R11); + NativeLoc saved = native_loc_stack(i64t, a->sret_ptr_slot, 0); NativeAddr dst_addr, src_addr; AggregateAccess access; x64_load_part(t, dstp, saved, 0, 8); @@ -2659,10 +2611,10 @@ static void x64_plan_ret(NativeTarget* t, const CGFuncDesc* fd, memset(&access, 0, sizeof access); access.type = values[0].type; access.size = (u32)cg_type_size(t->c, values[0].type); - access.align = x64_type_align(t, values[0].type); + access.align = native_type_align(t, values[0].type); x64_copy_bytes(t, dst_addr, src_addr, access); /* rax = sret pointer. Reload it (copy_bytes clobbered r11/rax). */ - x64_load_part(t, x64_reg_loc(i64t, NATIVE_REG_INT, X64_RAX), saved, 0, 8); + x64_load_part(t, native_loc_reg(i64t, NATIVE_REG_INT, X64_RAX), saved, 0, 8); *out_rets = NULL; *out_nrets = 0; return; @@ -2681,19 +2633,19 @@ static void x64_plan_ret(NativeTarget* t, const CGFuncDesc* fd, rets[nr].src = values[0]; if (rets[nr].src.kind == NATIVE_LOC_FRAME) rets[nr].src = - x64_stack_loc(pty, values[0].v.frame, (i32)part->src_offset); + native_loc_stack(pty, values[0].v.frame, (i32)part->src_offset); else if (rets[nr].src.kind == NATIVE_LOC_STACK) { rets[nr].src.v.stack.offset += (i32)part->src_offset; rets[nr].src.type = pty; } - rets[nr].dst = x64_reg_loc(pty, cls, rreg); - rets[nr].mem = x64_mem_for_type(t, pty, part->size); + rets[nr].dst = native_loc_reg(pty, cls, rreg); + rets[nr].mem = native_mem_for_type(t, pty, part->size); nr++; } } else if (nvalues) { rets[0].src = values[0]; - rets[0].dst = x64_reg_loc(values[0].type, NATIVE_REG_INT, X64_RAX); - rets[0].mem = x64_mem_for_type(t, values[0].type, 0); + rets[0].dst = native_loc_reg(values[0].type, NATIVE_REG_INT, X64_RAX); + rets[0].mem = native_mem_for_type(t, values[0].type, 0); nr = 1; } *out_rets = rets; @@ -2927,7 +2879,7 @@ static u32 x64_atomic_base(X64NativeTarget* a, NativeAddr addr) { static void x64_atomic_load(NativeTarget* t, NativeLoc dst, NativeAddr addr, MemAccess mem, KitCgMemOrder mo) { X64NativeTarget* a = x64_of(t); - u32 sz = mem.size ? mem.size : x64_type_size(t, dst.type); + u32 sz = mem.size ? mem.size : native_type_size(t, dst.type); u32 base; (void)mo; /* x86 plain MOV is an acquire load. */ base = x64_atomic_base(a, addr); @@ -2938,7 +2890,7 @@ static void x64_atomic_store(NativeTarget* t, NativeAddr addr, NativeLoc src, MemAccess mem, KitCgMemOrder mo) { X64NativeTarget* a = x64_of(t); MCEmitter* mc = t->mc; - u32 sz = mem.size ? mem.size : x64_type_size(t, src.type); + u32 sz = mem.size ? mem.size : native_type_size(t, src.type); int w = sz == 8u ? 1 : 0; u32 base = x64_atomic_base(a, addr); u32 sr = loc_reg(src); @@ -2962,7 +2914,7 @@ static void x64_atomic_rmw(NativeTarget* t, KitCgAtomicOp op, NativeLoc dst, KitCgMemOrder mo) { X64NativeTarget* a = x64_of(t); MCEmitter* mc = t->mc; - u32 sz = mem.size ? mem.size : x64_type_size(t, dst.type); + u32 sz = mem.size ? mem.size : native_type_size(t, dst.type); int w = sz == 8u ? 1 : 0; u32 base = x64_atomic_base(a, addr); u32 dr = loc_reg(dst); @@ -3042,7 +2994,7 @@ static void x64_atomic_cas(NativeTarget* t, NativeLoc prior, NativeLoc ok, KitCgMemOrder success, KitCgMemOrder failure) { X64NativeTarget* a = x64_of(t); MCEmitter* mc = t->mc; - u32 sz = mem.size ? mem.size : x64_type_size(t, prior.type); + u32 sz = mem.size ? mem.size : native_type_size(t, prior.type); int w = sz == 8u ? 1 : 0; u32 base = x64_atomic_base(a, addr); u32 rprior = loc_reg(prior); @@ -3169,8 +3121,8 @@ static void x64_va_arg_core(X64NativeTarget* a, NativeLoc dst, NativeAddr ap, KitCgTypeId type) { NativeTarget* t = &a->base; MCEmitter* mc = t->mc; - u32 sz = x64_type_size(t, type); - int is_fp = loc_is_fp(dst); + u32 sz = native_type_size(t, type); + int is_fp = native_loc_is_fp(dst); u32 dr = loc_reg(dst); u32 ap_base = x64_va_base(a, ap, X64_TMP_INT2); /* r11 */ /* GPR scratch for the offset/address arithmetic. For integer results the @@ -3735,7 +3687,7 @@ static void x64_direct_load_operand_to_reg(NativeDirectTarget* d, Operand op, addr.base_kind = NATIVE_ADDR_BASE_FRAME; addr.base.frame = d->locals[op.v.local - 1u].home; addr.base_type = op.type; - x64_emit_mem(a, 1, dst, addr, x64_mem_for_type(d->native, op.type, 0)); + x64_emit_mem(a, 1, dst, addr, native_mem_for_type(d->native, op.type, 0)); return; case OPK_GLOBAL: addr.base_kind = NATIVE_ADDR_BASE_GLOBAL; @@ -3746,7 +3698,7 @@ static void x64_direct_load_operand_to_reg(NativeDirectTarget* d, Operand op, return; case OPK_INDIRECT: addr = x64_direct_materialize_addr(d, op); - x64_emit_mem(a, 1, dst, addr, x64_mem_for_type(d->native, op.type, 0)); + x64_emit_mem(a, 1, dst, addr, native_mem_for_type(d->native, op.type, 0)); return; } x64_asm_panic(d, "unsupported asm input operand"); @@ -3769,7 +3721,7 @@ static void x64_direct_store_reg_to_operand(NativeDirectTarget* d, Operand op, } else { addr = x64_direct_materialize_addr(d, op); } - x64_emit_mem(a, 0, src, addr, x64_mem_for_type(d->native, op.type, 0)); + x64_emit_mem(a, 0, src, addr, native_mem_for_type(d->native, op.type, 0)); } /* Callee-saved registers an asm block clobbers must be saved around the block. @@ -3794,8 +3746,8 @@ static void x64_asm_save_one(X64NativeTarget* a, X64AsmSavedClobber* s) { addr.base_kind = NATIVE_ADDR_BASE_FRAME; addr.base.frame = s->slot; addr.base_type = s->type; - x64_emit_mem(a, 0, x64_reg_loc(s->type, s->cls, s->reg), addr, - x64_mem_for_type(&a->base, s->type, desc.size)); + x64_emit_mem(a, 0, native_loc_reg(s->type, s->cls, s->reg), addr, + native_mem_for_type(&a->base, s->type, desc.size)); } static void x64_asm_restore_one(X64NativeTarget* a, const X64AsmSavedClobber* s) { @@ -3805,8 +3757,8 @@ static void x64_asm_restore_one(X64NativeTarget* a, addr.base.frame = s->slot; addr.base_type = s->type; x64_emit_mem( - a, 1, x64_reg_loc(s->type, s->cls, s->reg), addr, - x64_mem_for_type(&a->base, s->type, s->cls == NATIVE_REG_FP ? 16u : 8u)); + a, 1, native_loc_reg(s->type, s->cls, s->reg), addr, + native_mem_for_type(&a->base, s->type, s->cls == NATIVE_REG_FP ? 16u : 8u)); } /* SysV callee-saved: int rbx,r12-r15; no fp. Win64 adds rdi,rsi + xmm6-15. */ @@ -3955,9 +3907,9 @@ static void x64_asm_block_native(NativeTarget* t, const char* tmpl, if (ntmp >= 2u) x64_asm_panic_at(c, loc, "too many memory asm operands"); r = (ntmp == 0u) ? (Reg)X64_RAX : (Reg)X64_R11; ntmp++; - inloc = x64_reg_loc(type, NATIVE_REG_INT, r); + inloc = native_loc_reg(type, NATIVE_REG_INT, r); x64_emit_mem(a, 1, inloc, x64_asm_loc_to_addr(a, loc, in_locs[i]), - x64_mem_for_type(t, type, x64_type_size(t, type))); + native_mem_for_type(t, type, native_type_size(t, type))); } x64_asm_bind_native(a, loc, &bound_ins[i], ins[i].str, type, inloc, &ntmp); } @@ -4055,7 +4007,7 @@ NativeTarget* x64_native_target_new(Compiler* c, ObjBuilder* obj, t->mc = mc; native_frame_init(&a->frame, c); t->regs = &x64_reg_info; - t->class_for_type = x64_class_for_type; + t->class_for_type = native_class_for_type_fp_le8; t->imm_legal = x64_imm_legal; t->addr_legal = x64_addr_legal; t->machine_op_clobbers = x64_machine_op_clobbers; @@ -4191,7 +4143,7 @@ static NativeAddr x64_direct_pointer_addr(NativeDirectTarget* d, Operand op) { static NativeAddr x64_direct_va_base(NativeDirectTarget* d, Operand ap_addr, Reg reg) { NativeLoc dst = - x64_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); NativeAddr addr; d->native->load_addr(d->native, dst, x64_direct_pointer_addr(d, ap_addr)); memset(&addr, 0, sizeof addr); @@ -4212,7 +4164,7 @@ static void x64_va_arg_(NativeDirectTarget* d, Operand dst, Operand ap_addr, KitCgTypeId type) { X64NativeTarget* a = x64_of(d->native); int is_fp = cg_type_is_float(d->base.c, type); - NativeLoc res = x64_reg_loc(type, is_fp ? NATIVE_REG_FP : NATIVE_REG_INT, + NativeLoc res = native_loc_reg(type, is_fp ? NATIVE_REG_FP : NATIVE_REG_INT, is_fp ? X64_TMP_FP : (Reg)X64_RDX); NativeAddr dst_addr; /* Base in R11: the core advances/loads through R11 plus one GPR scratch (the @@ -4228,7 +4180,7 @@ static void x64_va_arg_(NativeDirectTarget* d, Operand dst, Operand ap_addr, } x64_emit_mem( a, 0, res, dst_addr, - x64_mem_for_type(d->native, type, x64_type_size(d->native, type))); + native_mem_for_type(d->native, type, native_type_size(d->native, type))); } static void x64_va_end_(NativeDirectTarget* d, Operand ap_addr) { (void)d; @@ -4276,11 +4228,11 @@ static void x64_direct_asm_block(NativeDirectTarget* d, const char* tmpl, x64_asm_bound_reg(&bound_outs[i], type, cls, reg); if (outs[i].dir == KIT_CG_ASM_INOUT) x64_direct_load_operand_to_reg(d, out_ops[i], - x64_reg_loc(type, cls, reg)); + native_loc_reg(type, cls, reg)); } else if (body[0] == 'm') { Reg reg = x64_asm_alloc_reg(d, NATIVE_REG_INT, &used_int, &used_fp); NativeLoc lloc = - x64_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); x64_direct_load_address_to_reg(d, out_ops[i], lloc); x64_asm_bound_mem(&bound_outs[i], type, reg); } else { @@ -4302,7 +4254,7 @@ static void x64_direct_asm_block(NativeDirectTarget* d, const char* tmpl, bound_ins[i] = bound_outs[matched]; x64_direct_load_operand_to_reg( d, in_ops[i], - x64_reg_loc(bound_ins[i].type, + native_loc_reg(bound_ins[i].type, bound_ins[i].pad[0] == X64_INLINE_OPCLS_FP ? NATIVE_REG_FP : NATIVE_REG_INT, @@ -4313,7 +4265,7 @@ static void x64_direct_asm_block(NativeDirectTarget* d, const char* tmpl, NativeAllocClass cls = x64_asm_constraint_class(d, body); Reg reg = x64_asm_alloc_reg(d, cls, &used_int, &used_fp); x64_asm_bound_reg(&bound_ins[i], type, cls, reg); - x64_direct_load_operand_to_reg(d, in_ops[i], x64_reg_loc(type, cls, reg)); + x64_direct_load_operand_to_reg(d, in_ops[i], native_loc_reg(type, cls, reg)); } else if (body[0] == 'i') { if (in_ops[i].kind != OPK_IMM) x64_asm_panic(d, "immediate constraint requires immediate operand"); @@ -4321,7 +4273,7 @@ static void x64_direct_asm_block(NativeDirectTarget* d, const char* tmpl, } else if (body[0] == 'm') { Reg reg = x64_asm_alloc_reg(d, NATIVE_REG_INT, &used_int, &used_fp); NativeLoc lloc = - x64_reg_loc(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); + native_loc_reg(builtin_id(KIT_CG_BUILTIN_I64), NATIVE_REG_INT, reg); x64_direct_load_address_to_reg(d, in_ops[i], lloc); x64_asm_bound_mem(&bound_ins[i], type, reg); } else { @@ -4342,7 +4294,7 @@ static void x64_direct_asm_block(NativeDirectTarget* d, const char* tmpl, if (bound_outs[i].kind != X64_INLINE_OPK_REG) continue; cls = bound_outs[i].pad[0] == X64_INLINE_OPCLS_FP ? NATIVE_REG_FP : NATIVE_REG_INT; - src = x64_reg_loc(bound_outs[i].type, cls, (Reg)bound_outs[i].v.local); + src = native_loc_reg(bound_outs[i].type, cls, (Reg)bound_outs[i].v.local); x64_direct_store_reg_to_operand(d, out_ops[i], src); } for (i = nsaved; i > 0; --i) x64_asm_restore_one(a, &saved[i - 1u]); diff --git a/src/cg/native_direct_target.c b/src/cg/native_direct_target.c @@ -99,15 +99,8 @@ static const NativeAllocClassInfo* nd_class_info(NativeDirectTarget* d, return ci; } -static NativeLoc nd_reg_loc(Reg reg, NativeAllocClass cls, KitCgTypeId type) { - NativeLoc out; - memset(&out, 0, sizeof out); - out.kind = NATIVE_LOC_REG; - out.cls = (u8)cls; - out.type = type; - out.v.reg = reg; - return out; -} +/* Register-location constructor is shared as native_loc_reg in + * native_target.h (arg order: type, cls, reg). */ static void nd_flush_local(NativeDirectTarget* d, CGLocal local); static Reg nd_cache_reg_for(NativeDirectTarget* d, CGLocal local, @@ -590,7 +583,7 @@ static void nd_flush_local(NativeDirectTarget* d, CGLocal local) { if (l->dirty) nd_store_reg_to_frame( d, l->home, l->type, - nd_reg_loc(l->reg, (NativeAllocClass)l->cls, l->type)); + native_loc_reg(l->type, (NativeAllocClass)l->cls, l->reg)); nd_cache_unlink(d, local); d->reg_owner[l->cls][l->reg] = CG_LOCAL_NONE; l->reg = REG_NONE; @@ -635,7 +628,7 @@ static NativeAddr nd_addr_materialize(NativeDirectTarget* d, NativeAddr in, if (out.base_kind == NATIVE_ADDR_BASE_FRAME_VALUE) { NativeAllocClass cls = (NativeAllocClass)out.cls; Reg r = nd_scratch_acquire(d, cls); - NativeLoc dst = nd_reg_loc(r, cls, out.base_type); + NativeLoc dst = native_loc_reg(out.base_type, cls, r); nd_load_frame_to_reg(d, dst, out.base.frame, out.base_type); out.base_kind = NATIVE_ADDR_BASE_REG; out.base.reg = r; @@ -645,7 +638,7 @@ static NativeAddr nd_addr_materialize(NativeDirectTarget* d, NativeAddr in, if (out.index_kind == NATIVE_ADDR_INDEX_FRAME_VALUE) { NativeAllocClass cls = (NativeAllocClass)out.index_cls; Reg r = nd_scratch_acquire(d, cls); - NativeLoc dst = nd_reg_loc(r, cls, out.index_type); + NativeLoc dst = native_loc_reg(out.index_type, cls, r); nd_load_frame_to_reg(d, dst, out.index.frame, out.index_type); out.index_kind = NATIVE_ADDR_INDEX_REG; out.index.reg = r; @@ -656,8 +649,8 @@ static NativeAddr nd_addr_materialize(NativeDirectTarget* d, NativeAddr in, !d->native->addr_legal(d->native, &out, mem)) { NativeAllocClass cls = NATIVE_REG_INT; Reg r = nd_scratch_acquire(d, cls); - NativeLoc dst = nd_reg_loc( - r, cls, out.base_type ? out.base_type : builtin_id(KIT_CG_BUILTIN_I64)); + NativeLoc dst = native_loc_reg( + out.base_type ? out.base_type : builtin_id(KIT_CG_BUILTIN_I64), cls, r); ND_REQUIRE_NATIVE(d, load_addr, "target does not materialize addresses"); d->native->load_addr(d->native, dst, out); nd_addr_temps_release(d, temps); @@ -691,7 +684,7 @@ static NativeLoc nd_materialize_loc(NativeDirectTarget* d, NativeLoc src, NativeLoc dst; if (src.kind == NATIVE_LOC_REG) return src; r = nd_scratch_acquire(d, cls); - dst = nd_reg_loc(r, cls, type ? type : src.type); + dst = native_loc_reg(type ? type : src.type, cls, r); nd_copy_to_reg(d, dst, src); return dst; } @@ -816,7 +809,7 @@ static NativeLoc nd_materialize_operand(NativeDirectTarget* d, Operand op) { /* Cache hit: pin and reuse the live register, no reload. */ d->scratch_used[l->cls] |= 1u << l->reg; nd_touch_local(d, l); - return nd_reg_loc(l->reg, (NativeAllocClass)l->cls, op.type); + return native_loc_reg(op.type, (NativeAllocClass)l->cls, l->reg); } /* A live entry under a different access width must reach memory before we * bypass the cache for this access. */ @@ -829,7 +822,7 @@ static NativeLoc nd_materialize_operand(NativeDirectTarget* d, Operand op) { static NativeLoc nd_dst_scratch(NativeDirectTarget* d, Operand dst) { NativeAllocClass cls = nd_class_for_type(d, dst.type); Reg r = nd_scratch_acquire(d, cls); - return nd_reg_loc(r, cls, dst.type); + return native_loc_reg(dst.type, cls, r); } /* Arithmetic/compare RHS: keep a constant operand as an immediate when the @@ -865,7 +858,7 @@ static NativeLoc nd_dst_reg(NativeDirectTarget* d, Operand dst) { if (r != REG_NONE) { d->scratch_used[l->cls] |= 1u << r; /* pin for the instruction */ nd_touch_local(d, l); - return nd_reg_loc(r, (NativeAllocClass)l->cls, dst.type); + return native_loc_reg(dst.type, (NativeAllocClass)l->cls, r); } } }