I3312_LDRSHX = 0x38000000 | LDST_LD_S_X << 22 | MO_16 << 30,
I3312_LDRSWX = 0x38000000 | LDST_LD_S_X << 22 | MO_32 << 30,
- I3312_TO_I3310 = 0x00206800,
+ I3312_TO_I3310 = 0x00200800,
I3312_TO_I3313 = 0x01000000,
/* Load/store register pair instructions. */
}
static void tcg_out_insn_3310(TCGContext *s, AArch64Insn insn,
- TCGReg rd, TCGReg base, TCGReg regoff)
+ TCGReg rd, TCGReg base, TCGType ext,
+ TCGReg regoff)
{
/* Note the AArch64Insn constants above are for C3.3.12. Adjust. */
- tcg_out32(s, insn | I3312_TO_I3310 | regoff << 16 | base << 5 | rd);
+ tcg_out32(s, insn | I3312_TO_I3310 | regoff << 16 |
+ 0x4000 | ext << 13 | base << 5 | rd);
}
-
static void tcg_out_insn_3312(TCGContext *s, AArch64Insn insn,
TCGReg rd, TCGReg rn, intptr_t offset)
{
/* Worst-case scenario, move offset to temp register, use reg offset. */
tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, offset);
- tcg_out_ldst_r(s, insn, rd, rn, TCG_REG_TMP);
+ tcg_out_ldst_r(s, insn, rd, rn, TCG_TYPE_I64, TCG_REG_TMP);
}
static inline void tcg_out_mov(TCGContext *s,
flush_icache_range(jmp_addr, jmp_addr + 4);
}
-static inline void tcg_out_goto_label(TCGContext *s, int label_index)
+static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l)
{
- TCGLabel *l = &s->labels[label_index];
-
if (!l->has_value) {
- tcg_out_reloc(s, s->code_ptr, R_AARCH64_JUMP26, label_index, 0);
+ tcg_out_reloc(s, s->code_ptr, R_AARCH64_JUMP26, l, 0);
tcg_out_goto_noaddr(s);
} else {
tcg_out_goto(s, l->u.value_ptr);
}
static void tcg_out_brcond(TCGContext *s, TCGMemOp ext, TCGCond c, TCGArg a,
- TCGArg b, bool b_const, int label)
+ TCGArg b, bool b_const, TCGLabel *l)
{
- TCGLabel *l = &s->labels[label];
intptr_t offset;
bool need_cmp;
}
if (!l->has_value) {
- tcg_out_reloc(s, s->code_ptr, R_AARCH64_CONDBR19, label, 0);
+ tcg_out_reloc(s, s->code_ptr, R_AARCH64_CONDBR19, l, 0);
offset = tcg_in32(s) >> 5;
} else {
offset = l->u.value_ptr - s->code_ptr;
#ifdef CONFIG_SOFTMMU
/* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
- * int mmu_idx, uintptr_t ra)
+ * TCGMemOpIdx oi, uintptr_t ra)
*/
static void * const qemu_ld_helpers[16] = {
[MO_UB] = helper_ret_ldub_mmu,
};
/* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
- * uintxx_t val, int mmu_idx, uintptr_t ra)
+ * uintxx_t val, TCGMemOpIdx oi,
+ * uintptr_t ra)
*/
static void * const qemu_st_helpers[16] = {
[MO_UB] = helper_ret_stb_mmu,
static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
{
- TCGMemOp opc = lb->opc;
+ TCGMemOpIdx oi = lb->oi;
+ TCGMemOp opc = get_memop(oi);
TCGMemOp size = opc & MO_SIZE;
reloc_pc19(lb->label_ptr[0], s->code_ptr);
- tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_X0, TCG_AREG0);
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_X0, TCG_AREG0);
tcg_out_mov(s, TARGET_LONG_BITS == 64, TCG_REG_X1, lb->addrlo_reg);
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X2, lb->mem_index);
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X2, oi);
tcg_out_adr(s, TCG_REG_X3, lb->raddr);
- tcg_out_call(s, qemu_ld_helpers[opc & ~MO_SIGN]);
+ tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SIZE)]);
if (opc & MO_SIGN) {
- tcg_out_sxt(s, TCG_TYPE_I64, size, lb->datalo_reg, TCG_REG_X0);
+ tcg_out_sxt(s, lb->type, size, lb->datalo_reg, TCG_REG_X0);
} else {
tcg_out_mov(s, size == MO_64, lb->datalo_reg, TCG_REG_X0);
}
static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
{
- TCGMemOp opc = lb->opc;
+ TCGMemOpIdx oi = lb->oi;
+ TCGMemOp opc = get_memop(oi);
TCGMemOp size = opc & MO_SIZE;
reloc_pc19(lb->label_ptr[0], s->code_ptr);
- tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_X0, TCG_AREG0);
+ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_X0, TCG_AREG0);
tcg_out_mov(s, TARGET_LONG_BITS == 64, TCG_REG_X1, lb->addrlo_reg);
tcg_out_mov(s, size == MO_64, TCG_REG_X2, lb->datalo_reg);
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X3, lb->mem_index);
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X3, oi);
tcg_out_adr(s, TCG_REG_X4, lb->raddr);
- tcg_out_call(s, qemu_st_helpers[opc]);
+ tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
tcg_out_goto(s, lb->raddr);
}
-static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc,
- TCGReg data_reg, TCGReg addr_reg,
- int mem_index, tcg_insn_unit *raddr,
- tcg_insn_unit *label_ptr)
+static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
+ TCGType ext, TCGReg data_reg, TCGReg addr_reg,
+ tcg_insn_unit *raddr, tcg_insn_unit *label_ptr)
{
TCGLabelQemuLdst *label = new_ldst_label(s);
label->is_ld = is_ld;
- label->opc = opc;
+ label->oi = oi;
+ label->type = ext;
label->datalo_reg = data_reg;
label->addrlo_reg = addr_reg;
- label->mem_index = mem_index;
label->raddr = raddr;
label->label_ptr[0] = label_ptr;
}
#endif /* CONFIG_SOFTMMU */
-static void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp memop,
- TCGReg data_r, TCGReg addr_r, TCGReg off_r)
+static void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp memop, TCGType ext,
+ TCGReg data_r, TCGReg addr_r,
+ TCGType otype, TCGReg off_r)
{
const TCGMemOp bswap = memop & MO_BSWAP;
switch (memop & MO_SSIZE) {
case MO_UB:
- tcg_out_ldst_r(s, I3312_LDRB, data_r, addr_r, off_r);
+ tcg_out_ldst_r(s, I3312_LDRB, data_r, addr_r, otype, off_r);
break;
case MO_SB:
- tcg_out_ldst_r(s, I3312_LDRSBX, data_r, addr_r, off_r);
+ tcg_out_ldst_r(s, ext ? I3312_LDRSBX : I3312_LDRSBW,
+ data_r, addr_r, otype, off_r);
break;
case MO_UW:
- tcg_out_ldst_r(s, I3312_LDRH, data_r, addr_r, off_r);
+ tcg_out_ldst_r(s, I3312_LDRH, data_r, addr_r, otype, off_r);
if (bswap) {
tcg_out_rev16(s, data_r, data_r);
}
break;
case MO_SW:
if (bswap) {
- tcg_out_ldst_r(s, I3312_LDRH, data_r, addr_r, off_r);
+ tcg_out_ldst_r(s, I3312_LDRH, data_r, addr_r, otype, off_r);
tcg_out_rev16(s, data_r, data_r);
- tcg_out_sxt(s, TCG_TYPE_I64, MO_16, data_r, data_r);
+ tcg_out_sxt(s, ext, MO_16, data_r, data_r);
} else {
- tcg_out_ldst_r(s, I3312_LDRSHX, data_r, addr_r, off_r);
+ tcg_out_ldst_r(s, (ext ? I3312_LDRSHX : I3312_LDRSHW),
+ data_r, addr_r, otype, off_r);
}
break;
case MO_UL:
- tcg_out_ldst_r(s, I3312_LDRW, data_r, addr_r, off_r);
+ tcg_out_ldst_r(s, I3312_LDRW, data_r, addr_r, otype, off_r);
if (bswap) {
tcg_out_rev32(s, data_r, data_r);
}
break;
case MO_SL:
if (bswap) {
- tcg_out_ldst_r(s, I3312_LDRW, data_r, addr_r, off_r);
+ tcg_out_ldst_r(s, I3312_LDRW, data_r, addr_r, otype, off_r);
tcg_out_rev32(s, data_r, data_r);
tcg_out_sxt(s, TCG_TYPE_I64, MO_32, data_r, data_r);
} else {
- tcg_out_ldst_r(s, I3312_LDRSWX, data_r, addr_r, off_r);
+ tcg_out_ldst_r(s, I3312_LDRSWX, data_r, addr_r, otype, off_r);
}
break;
case MO_Q:
- tcg_out_ldst_r(s, I3312_LDRX, data_r, addr_r, off_r);
+ tcg_out_ldst_r(s, I3312_LDRX, data_r, addr_r, otype, off_r);
if (bswap) {
tcg_out_rev64(s, data_r, data_r);
}
}
static void tcg_out_qemu_st_direct(TCGContext *s, TCGMemOp memop,
- TCGReg data_r, TCGReg addr_r, TCGReg off_r)
+ TCGReg data_r, TCGReg addr_r,
+ TCGType otype, TCGReg off_r)
{
const TCGMemOp bswap = memop & MO_BSWAP;
switch (memop & MO_SIZE) {
case MO_8:
- tcg_out_ldst_r(s, I3312_STRB, data_r, addr_r, off_r);
+ tcg_out_ldst_r(s, I3312_STRB, data_r, addr_r, otype, off_r);
break;
case MO_16:
if (bswap && data_r != TCG_REG_XZR) {
tcg_out_rev16(s, TCG_REG_TMP, data_r);
data_r = TCG_REG_TMP;
}
- tcg_out_ldst_r(s, I3312_STRH, data_r, addr_r, off_r);
+ tcg_out_ldst_r(s, I3312_STRH, data_r, addr_r, otype, off_r);
break;
case MO_32:
if (bswap && data_r != TCG_REG_XZR) {
tcg_out_rev32(s, TCG_REG_TMP, data_r);
data_r = TCG_REG_TMP;
}
- tcg_out_ldst_r(s, I3312_STRW, data_r, addr_r, off_r);
+ tcg_out_ldst_r(s, I3312_STRW, data_r, addr_r, otype, off_r);
break;
case MO_64:
if (bswap && data_r != TCG_REG_XZR) {
tcg_out_rev64(s, TCG_REG_TMP, data_r);
data_r = TCG_REG_TMP;
}
- tcg_out_ldst_r(s, I3312_STRX, data_r, addr_r, off_r);
+ tcg_out_ldst_r(s, I3312_STRX, data_r, addr_r, otype, off_r);
break;
default:
tcg_abort();
}
static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg,
- TCGMemOp memop, int mem_index)
+ TCGMemOpIdx oi, TCGType ext)
{
+ TCGMemOp memop = get_memop(oi);
#ifdef CONFIG_SOFTMMU
+ unsigned mem_index = get_mmuidx(oi);
TCGMemOp s_bits = memop & MO_SIZE;
tcg_insn_unit *label_ptr;
tcg_out_tlb_read(s, addr_reg, s_bits, &label_ptr, mem_index, 1);
- tcg_out_qemu_ld_direct(s, memop, data_reg, addr_reg, TCG_REG_X1);
- add_qemu_ldst_label(s, true, memop, data_reg, addr_reg,
- mem_index, s->code_ptr, label_ptr);
+ tcg_out_qemu_ld_direct(s, memop, ext, data_reg, addr_reg,
+ TCG_TYPE_I64, TCG_REG_X1);
+ add_qemu_ldst_label(s, true, oi, ext, data_reg, addr_reg,
+ s->code_ptr, label_ptr);
#else /* !CONFIG_SOFTMMU */
- tcg_out_qemu_ld_direct(s, memop, data_reg, addr_reg,
- GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR);
+ const TCGType otype = TARGET_LONG_BITS == 64 ? TCG_TYPE_I64 : TCG_TYPE_I32;
+ tcg_out_qemu_ld_direct(s, memop, ext, data_reg,
+ GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR,
+ otype, addr_reg);
#endif /* CONFIG_SOFTMMU */
}
static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg,
- TCGMemOp memop, int mem_index)
+ TCGMemOpIdx oi)
{
+ TCGMemOp memop = get_memop(oi);
#ifdef CONFIG_SOFTMMU
+ unsigned mem_index = get_mmuidx(oi);
TCGMemOp s_bits = memop & MO_SIZE;
tcg_insn_unit *label_ptr;
tcg_out_tlb_read(s, addr_reg, s_bits, &label_ptr, mem_index, 0);
- tcg_out_qemu_st_direct(s, memop, data_reg, addr_reg, TCG_REG_X1);
- add_qemu_ldst_label(s, false, memop, data_reg, addr_reg,
- mem_index, s->code_ptr, label_ptr);
-#else /* !CONFIG_SOFTMMU */
tcg_out_qemu_st_direct(s, memop, data_reg, addr_reg,
- GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR);
+ TCG_TYPE_I64, TCG_REG_X1);
+ add_qemu_ldst_label(s, false, oi, s_bits == MO_64, data_reg, addr_reg,
+ s->code_ptr, label_ptr);
+#else /* !CONFIG_SOFTMMU */
+ const TCGType otype = TARGET_LONG_BITS == 64 ? TCG_TYPE_I64 : TCG_TYPE_I32;
+ tcg_out_qemu_st_direct(s, memop, data_reg,
+ GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR,
+ otype, addr_reg);
#endif /* CONFIG_SOFTMMU */
}
break;
case INDEX_op_br:
- tcg_out_goto_label(s, a0);
+ tcg_out_goto_label(s, arg_label(a0));
break;
case INDEX_op_ld8u_i32:
a1 = (int32_t)a1;
/* FALLTHRU */
case INDEX_op_brcond_i64:
- tcg_out_brcond(s, ext, a2, a0, a1, const_args[1], args[3]);
+ tcg_out_brcond(s, ext, a2, a0, a1, const_args[1], arg_label(args[3]));
break;
case INDEX_op_setcond_i32:
case INDEX_op_qemu_ld_i32:
case INDEX_op_qemu_ld_i64:
- tcg_out_qemu_ld(s, a0, a1, a2, args[3]);
+ tcg_out_qemu_ld(s, a0, a1, a2, ext);
break;
case INDEX_op_qemu_st_i32:
case INDEX_op_qemu_st_i64:
- tcg_out_qemu_st(s, REG0(0), a1, a2, args[3]);
+ tcg_out_qemu_st(s, REG0(0), a1, a2);
break;
case INDEX_op_bswap64_i64:
}
typedef struct {
- DebugFrameCIE cie;
- DebugFrameFDEHeader fde;
+ DebugFrameHeader h;
uint8_t fde_def_cfa[4];
uint8_t fde_reg_ofs[24];
} DebugFrame;
#define ELF_HOST_MACHINE EM_AARCH64
-static DebugFrame debug_frame = {
- .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
- .cie.id = -1,
- .cie.version = 1,
- .cie.code_align = 1,
- .cie.data_align = 0x78, /* sleb128 -8 */
- .cie.return_column = TCG_REG_LR,
+static const DebugFrame debug_frame = {
+ .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
+ .h.cie.id = -1,
+ .h.cie.version = 1,
+ .h.cie.code_align = 1,
+ .h.cie.data_align = 0x78, /* sleb128 -8 */
+ .h.cie.return_column = TCG_REG_LR,
/* Total FDE size does not include the "len" member. */
- .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
+ .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
.fde_def_cfa = {
12, TCG_REG_SP, /* DW_CFA_def_cfa sp, ... */
void tcg_register_jit(void *buf, size_t buf_size)
{
- debug_frame.fde.func_start = (intptr_t)buf;
- debug_frame.fde.func_len = buf_size;
-
tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
}