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:
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);
}
}
}