aboutsummaryrefslogtreecommitdiff
path: root/tcg/tci/tcg-target.c.inc
diff options
context:
space:
mode:
Diffstat (limited to 'tcg/tci/tcg-target.c.inc')
-rw-r--r--tcg/tci/tcg-target.c.inc1175
1 files changed, 774 insertions, 401 deletions
diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc
index 36e018d..35c66a4 100644
--- a/tcg/tci/tcg-target.c.inc
+++ b/tcg/tci/tcg-target.c.inc
@@ -39,148 +39,7 @@
static TCGConstraintSetIndex
tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
{
- switch (op) {
- case INDEX_op_goto_ptr:
- return C_O0_I1(r);
-
- case INDEX_op_ld8u_i32:
- case INDEX_op_ld8s_i32:
- case INDEX_op_ld16u_i32:
- case INDEX_op_ld16s_i32:
- case INDEX_op_ld_i32:
- case INDEX_op_ld8u_i64:
- case INDEX_op_ld8s_i64:
- case INDEX_op_ld16u_i64:
- case INDEX_op_ld16s_i64:
- case INDEX_op_ld32u_i64:
- case INDEX_op_ld32s_i64:
- case INDEX_op_ld_i64:
- case INDEX_op_not_i32:
- case INDEX_op_not_i64:
- case INDEX_op_neg_i32:
- case INDEX_op_neg_i64:
- case INDEX_op_ext8s_i32:
- case INDEX_op_ext8s_i64:
- case INDEX_op_ext16s_i32:
- case INDEX_op_ext16s_i64:
- case INDEX_op_ext8u_i32:
- case INDEX_op_ext8u_i64:
- case INDEX_op_ext16u_i32:
- case INDEX_op_ext16u_i64:
- case INDEX_op_ext32s_i64:
- case INDEX_op_ext32u_i64:
- case INDEX_op_ext_i32_i64:
- case INDEX_op_extu_i32_i64:
- case INDEX_op_bswap16_i32:
- case INDEX_op_bswap16_i64:
- case INDEX_op_bswap32_i32:
- case INDEX_op_bswap32_i64:
- case INDEX_op_bswap64_i64:
- case INDEX_op_extract_i32:
- case INDEX_op_extract_i64:
- case INDEX_op_sextract_i32:
- case INDEX_op_sextract_i64:
- case INDEX_op_ctpop_i32:
- case INDEX_op_ctpop_i64:
- return C_O1_I1(r, r);
-
- case INDEX_op_st8_i32:
- case INDEX_op_st16_i32:
- case INDEX_op_st_i32:
- case INDEX_op_st8_i64:
- case INDEX_op_st16_i64:
- case INDEX_op_st32_i64:
- case INDEX_op_st_i64:
- return C_O0_I2(r, r);
-
- case INDEX_op_div_i32:
- case INDEX_op_div_i64:
- case INDEX_op_divu_i32:
- case INDEX_op_divu_i64:
- case INDEX_op_rem_i32:
- case INDEX_op_rem_i64:
- case INDEX_op_remu_i32:
- case INDEX_op_remu_i64:
- case INDEX_op_add_i32:
- case INDEX_op_add_i64:
- case INDEX_op_sub_i32:
- case INDEX_op_sub_i64:
- case INDEX_op_mul_i32:
- case INDEX_op_mul_i64:
- case INDEX_op_and_i32:
- case INDEX_op_and_i64:
- case INDEX_op_andc_i32:
- case INDEX_op_andc_i64:
- case INDEX_op_eqv_i32:
- case INDEX_op_eqv_i64:
- case INDEX_op_nand_i32:
- case INDEX_op_nand_i64:
- case INDEX_op_nor_i32:
- case INDEX_op_nor_i64:
- case INDEX_op_or_i32:
- case INDEX_op_or_i64:
- case INDEX_op_orc_i32:
- case INDEX_op_orc_i64:
- case INDEX_op_xor_i32:
- case INDEX_op_xor_i64:
- case INDEX_op_shl_i32:
- case INDEX_op_shl_i64:
- case INDEX_op_shr_i32:
- case INDEX_op_shr_i64:
- case INDEX_op_sar_i32:
- case INDEX_op_sar_i64:
- case INDEX_op_rotl_i32:
- case INDEX_op_rotl_i64:
- case INDEX_op_rotr_i32:
- case INDEX_op_rotr_i64:
- case INDEX_op_setcond_i32:
- case INDEX_op_setcond_i64:
- case INDEX_op_deposit_i32:
- case INDEX_op_deposit_i64:
- case INDEX_op_clz_i32:
- case INDEX_op_clz_i64:
- case INDEX_op_ctz_i32:
- case INDEX_op_ctz_i64:
- return C_O1_I2(r, r, r);
-
- case INDEX_op_brcond_i32:
- case INDEX_op_brcond_i64:
- return C_O0_I2(r, r);
-
- case INDEX_op_add2_i32:
- case INDEX_op_add2_i64:
- case INDEX_op_sub2_i32:
- case INDEX_op_sub2_i64:
- return C_O2_I4(r, r, r, r, r, r);
-
-#if TCG_TARGET_REG_BITS == 32
- case INDEX_op_brcond2_i32:
- return C_O0_I4(r, r, r, r);
-#endif
-
- case INDEX_op_mulu2_i32:
- case INDEX_op_mulu2_i64:
- case INDEX_op_muls2_i32:
- case INDEX_op_muls2_i64:
- return C_O2_I2(r, r, r, r);
-
- case INDEX_op_movcond_i32:
- case INDEX_op_movcond_i64:
- case INDEX_op_setcond2_i32:
- return C_O1_I4(r, r, r, r, r);
-
- case INDEX_op_qemu_ld_i32:
- return C_O1_I1(r, r);
- case INDEX_op_qemu_ld_i64:
- return TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, r) : C_O2_I1(r, r, r);
- case INDEX_op_qemu_st_i32:
- return C_O0_I2(r, r);
- case INDEX_op_qemu_st_i64:
- return TCG_TARGET_REG_BITS == 64 ? C_O0_I2(r, r) : C_O0_I3(r, r, r);
-
- default:
- return C_NotImplemented;
- }
+ return C_NotImplemented;
}
static const int tcg_target_reg_alloc_order[] = {
@@ -443,31 +302,13 @@ static void tcg_out_op_rrrrrc(TCGContext *s, TCGOpcode op,
tcg_out32(s, insn);
}
-static void tcg_out_op_rrrrrr(TCGContext *s, TCGOpcode op,
- TCGReg r0, TCGReg r1, TCGReg r2,
- TCGReg r3, TCGReg r4, TCGReg r5)
-{
- tcg_insn_unit insn = 0;
-
- insn = deposit32(insn, 0, 8, op);
- insn = deposit32(insn, 8, 4, r0);
- insn = deposit32(insn, 12, 4, r1);
- insn = deposit32(insn, 16, 4, r2);
- insn = deposit32(insn, 20, 4, r3);
- insn = deposit32(insn, 24, 4, r4);
- insn = deposit32(insn, 28, 4, r5);
- tcg_out32(s, insn);
-}
-
static void tcg_out_ldst(TCGContext *s, TCGOpcode op, TCGReg val,
TCGReg base, intptr_t offset)
{
stack_bounds_check(base, offset);
if (offset != sextract32(offset, 0, 16)) {
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP, offset);
- tcg_out_op_rrr(s, (TCG_TARGET_REG_BITS == 32
- ? INDEX_op_add_i32 : INDEX_op_add_i64),
- TCG_REG_TMP, TCG_REG_TMP, base);
+ tcg_out_op_rrr(s, INDEX_op_add, TCG_REG_TMP, TCG_REG_TMP, base);
base = TCG_REG_TMP;
offset = 0;
}
@@ -477,34 +318,17 @@ static void tcg_out_ldst(TCGContext *s, TCGOpcode op, TCGReg val,
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg val, TCGReg base,
intptr_t offset)
{
- switch (type) {
- case TCG_TYPE_I32:
- tcg_out_ldst(s, INDEX_op_ld_i32, val, base, offset);
- break;
-#if TCG_TARGET_REG_BITS == 64
- case TCG_TYPE_I64:
- tcg_out_ldst(s, INDEX_op_ld_i64, val, base, offset);
- break;
-#endif
- default:
- g_assert_not_reached();
+ TCGOpcode op = INDEX_op_ld;
+
+ if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
+ op = INDEX_op_ld32u;
}
+ tcg_out_ldst(s, op, val, base, offset);
}
static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
{
- switch (type) {
- case TCG_TYPE_I32:
- tcg_out_op_rr(s, INDEX_op_mov_i32, ret, arg);
- break;
-#if TCG_TARGET_REG_BITS == 64
- case TCG_TYPE_I64:
- tcg_out_op_rr(s, INDEX_op_mov_i64, ret, arg);
- break;
-#endif
- default:
- g_assert_not_reached();
- }
+ tcg_out_op_rr(s, INDEX_op_mov, ret, arg);
return true;
}
@@ -535,76 +359,62 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
}
}
+static void tcg_out_extract(TCGContext *s, TCGType type, TCGReg rd,
+ TCGReg rs, unsigned pos, unsigned len)
+{
+ tcg_out_op_rrbb(s, INDEX_op_extract, rd, rs, pos, len);
+}
+
+static const TCGOutOpExtract outop_extract = {
+ .base.static_constraint = C_O1_I1(r, r),
+ .out_rr = tcg_out_extract,
+};
+
+static void tcg_out_sextract(TCGContext *s, TCGType type, TCGReg rd,
+ TCGReg rs, unsigned pos, unsigned len)
+{
+ tcg_out_op_rrbb(s, INDEX_op_sextract, rd, rs, pos, len);
+}
+
+static const TCGOutOpExtract outop_sextract = {
+ .base.static_constraint = C_O1_I1(r, r),
+ .out_rr = tcg_out_sextract,
+};
+
+static const TCGOutOpExtract2 outop_extract2 = {
+ .base.static_constraint = C_NotImplemented,
+};
+
static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
{
- switch (type) {
- case TCG_TYPE_I32:
- tcg_debug_assert(TCG_TARGET_HAS_ext8s_i32);
- tcg_out_op_rr(s, INDEX_op_ext8s_i32, rd, rs);
- break;
-#if TCG_TARGET_REG_BITS == 64
- case TCG_TYPE_I64:
- tcg_debug_assert(TCG_TARGET_HAS_ext8s_i64);
- tcg_out_op_rr(s, INDEX_op_ext8s_i64, rd, rs);
- break;
-#endif
- default:
- g_assert_not_reached();
- }
+ tcg_out_sextract(s, type, rd, rs, 0, 8);
}
static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs)
{
- if (TCG_TARGET_REG_BITS == 64) {
- tcg_debug_assert(TCG_TARGET_HAS_ext8u_i64);
- tcg_out_op_rr(s, INDEX_op_ext8u_i64, rd, rs);
- } else {
- tcg_debug_assert(TCG_TARGET_HAS_ext8u_i32);
- tcg_out_op_rr(s, INDEX_op_ext8u_i32, rd, rs);
- }
+ tcg_out_extract(s, TCG_TYPE_REG, rd, rs, 0, 8);
}
static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
{
- switch (type) {
- case TCG_TYPE_I32:
- tcg_debug_assert(TCG_TARGET_HAS_ext16s_i32);
- tcg_out_op_rr(s, INDEX_op_ext16s_i32, rd, rs);
- break;
-#if TCG_TARGET_REG_BITS == 64
- case TCG_TYPE_I64:
- tcg_debug_assert(TCG_TARGET_HAS_ext16s_i64);
- tcg_out_op_rr(s, INDEX_op_ext16s_i64, rd, rs);
- break;
-#endif
- default:
- g_assert_not_reached();
- }
+ tcg_out_sextract(s, type, rd, rs, 0, 16);
}
static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs)
{
- if (TCG_TARGET_REG_BITS == 64) {
- tcg_debug_assert(TCG_TARGET_HAS_ext16u_i64);
- tcg_out_op_rr(s, INDEX_op_ext16u_i64, rd, rs);
- } else {
- tcg_debug_assert(TCG_TARGET_HAS_ext16u_i32);
- tcg_out_op_rr(s, INDEX_op_ext16u_i32, rd, rs);
- }
+ tcg_out_extract(s, TCG_TYPE_REG, rd, rs, 0, 16);
}
static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs)
{
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
- tcg_debug_assert(TCG_TARGET_HAS_ext32s_i64);
- tcg_out_op_rr(s, INDEX_op_ext32s_i64, rd, rs);
+ tcg_out_sextract(s, TCG_TYPE_I64, rd, rs, 0, 32);
}
static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rs)
{
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
- tcg_debug_assert(TCG_TARGET_HAS_ext32u_i64);
- tcg_out_op_rr(s, INDEX_op_ext32u_i64, rd, rs);
+ tcg_out_extract(s, TCG_TYPE_I64, rd, rs, 0, 32);
}
static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
@@ -656,18 +466,6 @@ static void tcg_out_call(TCGContext *s, const tcg_insn_unit *func,
tcg_out32(s, insn);
}
-#if TCG_TARGET_REG_BITS == 64
-# define CASE_32_64(x) \
- case glue(glue(INDEX_op_, x), _i64): \
- case glue(glue(INDEX_op_, x), _i32):
-# define CASE_64(x) \
- case glue(glue(INDEX_op_, x), _i64):
-#else
-# define CASE_32_64(x) \
- case glue(glue(INDEX_op_, x), _i32):
-# define CASE_64(x)
-#endif
-
static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg)
{
tcg_out_op_p(s, INDEX_op_exit_tb, (void *)arg);
@@ -680,197 +478,772 @@ static void tcg_out_goto_tb(TCGContext *s, int which)
set_jmp_reset_offset(s, which);
}
+static void tcg_out_goto_ptr(TCGContext *s, TCGReg a0)
+{
+ tcg_out_op_r(s, INDEX_op_goto_ptr, a0);
+}
+
void tb_target_set_jmp_target(const TranslationBlock *tb, int n,
uintptr_t jmp_rx, uintptr_t jmp_rw)
{
/* Always indirect, nothing to do */
}
-static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
- const TCGArg args[TCG_MAX_OP_ARGS],
- const int const_args[TCG_MAX_OP_ARGS])
+static void tgen_add(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
{
- TCGOpcode exts;
+ tcg_out_op_rrr(s, INDEX_op_add, a0, a1, a2);
+}
- switch (opc) {
- case INDEX_op_goto_ptr:
- tcg_out_op_r(s, opc, args[0]);
- break;
+static const TCGOutOpBinary outop_add = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_add,
+};
- case INDEX_op_br:
- tcg_out_op_l(s, opc, arg_label(args[0]));
- break;
+static TCGConstraintSetIndex cset_addsubcarry(TCGType type, unsigned flags)
+{
+ return type == TCG_TYPE_REG ? C_O1_I2(r, r, r) : C_NotImplemented;
+}
- CASE_32_64(setcond)
- tcg_out_op_rrrc(s, opc, args[0], args[1], args[2], args[3]);
- break;
+static void tgen_addco(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_addco, a0, a1, a2);
+}
- CASE_32_64(movcond)
- case INDEX_op_setcond2_i32:
- tcg_out_op_rrrrrc(s, opc, args[0], args[1], args[2],
- args[3], args[4], args[5]);
- break;
+static const TCGOutOpBinary outop_addco = {
+ .base.static_constraint = C_Dynamic,
+ .base.dynamic_constraint = cset_addsubcarry,
+ .out_rrr = tgen_addco,
+};
- CASE_32_64(ld8u)
- CASE_32_64(ld8s)
- CASE_32_64(ld16u)
- CASE_32_64(ld16s)
- case INDEX_op_ld_i32:
- CASE_64(ld32u)
- CASE_64(ld32s)
- CASE_64(ld)
- CASE_32_64(st8)
- CASE_32_64(st16)
- case INDEX_op_st_i32:
- CASE_64(st32)
- CASE_64(st)
- tcg_out_ldst(s, opc, args[0], args[1], args[2]);
- break;
+static void tgen_addci(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_addci, a0, a1, a2);
+}
- CASE_32_64(add)
- CASE_32_64(sub)
- CASE_32_64(mul)
- CASE_32_64(and)
- CASE_32_64(or)
- CASE_32_64(xor)
- CASE_32_64(andc) /* Optional (TCG_TARGET_HAS_andc_*). */
- CASE_32_64(orc) /* Optional (TCG_TARGET_HAS_orc_*). */
- CASE_32_64(eqv) /* Optional (TCG_TARGET_HAS_eqv_*). */
- CASE_32_64(nand) /* Optional (TCG_TARGET_HAS_nand_*). */
- CASE_32_64(nor) /* Optional (TCG_TARGET_HAS_nor_*). */
- CASE_32_64(shl)
- CASE_32_64(shr)
- CASE_32_64(sar)
- CASE_32_64(rotl) /* Optional (TCG_TARGET_HAS_rot_*). */
- CASE_32_64(rotr) /* Optional (TCG_TARGET_HAS_rot_*). */
- CASE_32_64(div) /* Optional (TCG_TARGET_HAS_div_*). */
- CASE_32_64(divu) /* Optional (TCG_TARGET_HAS_div_*). */
- CASE_32_64(rem) /* Optional (TCG_TARGET_HAS_div_*). */
- CASE_32_64(remu) /* Optional (TCG_TARGET_HAS_div_*). */
- CASE_32_64(clz) /* Optional (TCG_TARGET_HAS_clz_*). */
- CASE_32_64(ctz) /* Optional (TCG_TARGET_HAS_ctz_*). */
- tcg_out_op_rrr(s, opc, args[0], args[1], args[2]);
- break;
+static const TCGOutOpAddSubCarry outop_addci = {
+ .base.static_constraint = C_Dynamic,
+ .base.dynamic_constraint = cset_addsubcarry,
+ .out_rrr = tgen_addci,
+};
- CASE_32_64(deposit)
- tcg_out_op_rrrbb(s, opc, args[0], args[1], args[2], args[3], args[4]);
- break;
+static void tgen_addcio(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_addcio, a0, a1, a2);
+}
- CASE_32_64(extract) /* Optional (TCG_TARGET_HAS_extract_*). */
- CASE_32_64(sextract) /* Optional (TCG_TARGET_HAS_sextract_*). */
- tcg_out_op_rrbb(s, opc, args[0], args[1], args[2], args[3]);
- break;
+static const TCGOutOpBinary outop_addcio = {
+ .base.static_constraint = C_Dynamic,
+ .base.dynamic_constraint = cset_addsubcarry,
+ .out_rrr = tgen_addcio,
+};
- CASE_32_64(brcond)
- tcg_out_op_rrrc(s, (opc == INDEX_op_brcond_i32
- ? INDEX_op_setcond_i32 : INDEX_op_setcond_i64),
- TCG_REG_TMP, args[0], args[1], args[2]);
- tcg_out_op_rl(s, opc, TCG_REG_TMP, arg_label(args[3]));
- break;
+static void tcg_out_set_carry(TCGContext *s)
+{
+ tcg_out_op_v(s, INDEX_op_tci_setcarry);
+}
- CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */
- CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */
- CASE_32_64(ctpop) /* Optional (TCG_TARGET_HAS_ctpop_*). */
- case INDEX_op_bswap32_i32: /* Optional (TCG_TARGET_HAS_bswap32_i32). */
- case INDEX_op_bswap64_i64: /* Optional (TCG_TARGET_HAS_bswap64_i64). */
- tcg_out_op_rr(s, opc, args[0], args[1]);
- break;
+static void tgen_and(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_and, a0, a1, a2);
+}
- case INDEX_op_bswap16_i32: /* Optional (TCG_TARGET_HAS_bswap16_i32). */
- exts = INDEX_op_ext16s_i32;
- goto do_bswap;
- case INDEX_op_bswap16_i64: /* Optional (TCG_TARGET_HAS_bswap16_i64). */
- exts = INDEX_op_ext16s_i64;
- goto do_bswap;
- case INDEX_op_bswap32_i64: /* Optional (TCG_TARGET_HAS_bswap32_i64). */
- exts = INDEX_op_ext32s_i64;
- do_bswap:
- /* The base tci bswaps zero-extend, and ignore high bits. */
- tcg_out_op_rr(s, opc, args[0], args[1]);
- if (args[2] & TCG_BSWAP_OS) {
- tcg_out_op_rr(s, exts, args[0], args[0]);
- }
- break;
+static const TCGOutOpBinary outop_and = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_and,
+};
- CASE_32_64(add2)
- CASE_32_64(sub2)
- tcg_out_op_rrrrrr(s, opc, args[0], args[1], args[2],
- args[3], args[4], args[5]);
- break;
+static void tgen_andc(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_andc, a0, a1, a2);
+}
-#if TCG_TARGET_REG_BITS == 32
- case INDEX_op_brcond2_i32:
- tcg_out_op_rrrrrc(s, INDEX_op_setcond2_i32, TCG_REG_TMP,
- args[0], args[1], args[2], args[3], args[4]);
- tcg_out_op_rl(s, INDEX_op_brcond_i32, TCG_REG_TMP, arg_label(args[5]));
- break;
+static const TCGOutOpBinary outop_andc = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_andc,
+};
+
+static void tgen_clz(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ TCGOpcode opc = (type == TCG_TYPE_I32
+ ? INDEX_op_tci_clz32
+ : INDEX_op_clz);
+ tcg_out_op_rrr(s, opc, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_clz = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_clz,
+};
+
+static void tgen_ctz(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ TCGOpcode opc = (type == TCG_TYPE_I32
+ ? INDEX_op_tci_ctz32
+ : INDEX_op_ctz);
+ tcg_out_op_rrr(s, opc, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_ctz = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_ctz,
+};
+
+static void tgen_deposit(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1,
+ TCGReg a2, unsigned ofs, unsigned len)
+{
+ tcg_out_op_rrrbb(s, INDEX_op_deposit, a0, a1, a2, ofs, len);
+}
+
+static const TCGOutOpDeposit outop_deposit = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_deposit,
+};
+
+static void tgen_divs(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ TCGOpcode opc = (type == TCG_TYPE_I32
+ ? INDEX_op_tci_divs32
+ : INDEX_op_divs);
+ tcg_out_op_rrr(s, opc, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_divs = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_divs,
+};
+
+static const TCGOutOpDivRem outop_divs2 = {
+ .base.static_constraint = C_NotImplemented,
+};
+
+static void tgen_divu(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ TCGOpcode opc = (type == TCG_TYPE_I32
+ ? INDEX_op_tci_divu32
+ : INDEX_op_divu);
+ tcg_out_op_rrr(s, opc, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_divu = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_divu,
+};
+
+static const TCGOutOpDivRem outop_divu2 = {
+ .base.static_constraint = C_NotImplemented,
+};
+
+static void tgen_eqv(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_eqv, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_eqv = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_eqv,
+};
+
+#if TCG_TARGET_REG_BITS == 64
+static void tgen_extrh_i64_i32(TCGContext *s, TCGType t, TCGReg a0, TCGReg a1)
+{
+ tcg_out_extract(s, TCG_TYPE_I64, a0, a1, 32, 32);
+}
+
+static const TCGOutOpUnary outop_extrh_i64_i32 = {
+ .base.static_constraint = C_O1_I1(r, r),
+ .out_rr = tgen_extrh_i64_i32,
+};
#endif
- CASE_32_64(mulu2)
- CASE_32_64(muls2)
- tcg_out_op_rrrr(s, opc, args[0], args[1], args[2], args[3]);
- break;
+static void tgen_mul(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_mul, a0, a1, a2);
+}
- case INDEX_op_qemu_ld_i64:
- case INDEX_op_qemu_st_i64:
- if (TCG_TARGET_REG_BITS == 32) {
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, args[3]);
- tcg_out_op_rrrr(s, opc, args[0], args[1], args[2], TCG_REG_TMP);
- break;
- }
- /* fall through */
- case INDEX_op_qemu_ld_i32:
- case INDEX_op_qemu_st_i32:
- if (TCG_TARGET_REG_BITS == 64 && s->addr_type == TCG_TYPE_I32) {
- tcg_out_ext32u(s, TCG_REG_TMP, args[1]);
- tcg_out_op_rrm(s, opc, args[0], TCG_REG_TMP, args[2]);
- } else {
- tcg_out_op_rrm(s, opc, args[0], args[1], args[2]);
- }
- break;
+static const TCGOutOpBinary outop_mul = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_mul,
+};
- case INDEX_op_mb:
- tcg_out_op_v(s, opc);
- break;
+static TCGConstraintSetIndex cset_mul2(TCGType type, unsigned flags)
+{
+ return type == TCG_TYPE_REG ? C_O2_I2(r, r, r, r) : C_NotImplemented;
+}
- case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
- case INDEX_op_mov_i64:
- case INDEX_op_call: /* Always emitted via tcg_out_call. */
- case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
- case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
- case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
- case INDEX_op_ext8s_i64:
- case INDEX_op_ext8u_i32:
- case INDEX_op_ext8u_i64:
- case INDEX_op_ext16s_i32:
- case INDEX_op_ext16s_i64:
- case INDEX_op_ext16u_i32:
- case INDEX_op_ext16u_i64:
- case INDEX_op_ext32s_i64:
- case INDEX_op_ext32u_i64:
- case INDEX_op_ext_i32_i64:
- case INDEX_op_extu_i32_i64:
- case INDEX_op_extrl_i64_i32:
- default:
- g_assert_not_reached();
+static void tgen_muls2(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2, TCGReg a3)
+{
+ tcg_out_op_rrrr(s, INDEX_op_muls2, a0, a1, a2, a3);
+}
+
+static const TCGOutOpMul2 outop_muls2 = {
+ .base.static_constraint = C_Dynamic,
+ .base.dynamic_constraint = cset_mul2,
+ .out_rrrr = tgen_muls2,
+};
+
+static const TCGOutOpBinary outop_mulsh = {
+ .base.static_constraint = C_NotImplemented,
+};
+
+static void tgen_mulu2(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2, TCGReg a3)
+{
+ tcg_out_op_rrrr(s, INDEX_op_mulu2, a0, a1, a2, a3);
+}
+
+static const TCGOutOpMul2 outop_mulu2 = {
+ .base.static_constraint = C_Dynamic,
+ .base.dynamic_constraint = cset_mul2,
+ .out_rrrr = tgen_mulu2,
+};
+
+static const TCGOutOpBinary outop_muluh = {
+ .base.static_constraint = C_NotImplemented,
+};
+
+static void tgen_nand(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_nand, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_nand = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_nand,
+};
+
+static void tgen_nor(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_nor, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_nor = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_nor,
+};
+
+static void tgen_or(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_or, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_or = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_or,
+};
+
+static void tgen_orc(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_orc, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_orc = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_orc,
+};
+
+static void tgen_rems(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ TCGOpcode opc = (type == TCG_TYPE_I32
+ ? INDEX_op_tci_rems32
+ : INDEX_op_rems);
+ tcg_out_op_rrr(s, opc, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_rems = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_rems,
+};
+
+static void tgen_remu(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ TCGOpcode opc = (type == TCG_TYPE_I32
+ ? INDEX_op_tci_remu32
+ : INDEX_op_remu);
+ tcg_out_op_rrr(s, opc, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_remu = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_remu,
+};
+
+static void tgen_rotl(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ TCGOpcode opc = (type == TCG_TYPE_I32
+ ? INDEX_op_tci_rotl32
+ : INDEX_op_rotl);
+ tcg_out_op_rrr(s, opc, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_rotl = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_rotl,
+};
+
+static void tgen_rotr(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ TCGOpcode opc = (type == TCG_TYPE_I32
+ ? INDEX_op_tci_rotr32
+ : INDEX_op_rotr);
+ tcg_out_op_rrr(s, opc, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_rotr = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_rotr,
+};
+
+static void tgen_sar(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ if (type < TCG_TYPE_REG) {
+ tcg_out_ext32s(s, TCG_REG_TMP, a1);
+ a1 = TCG_REG_TMP;
}
+ tcg_out_op_rrr(s, INDEX_op_sar, a0, a1, a2);
}
-static void tcg_out_st(TCGContext *s, TCGType type, TCGReg val, TCGReg base,
- intptr_t offset)
+static const TCGOutOpBinary outop_sar = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_sar,
+};
+
+static void tgen_shl(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
{
- switch (type) {
- case TCG_TYPE_I32:
- tcg_out_ldst(s, INDEX_op_st_i32, val, base, offset);
- break;
+ tcg_out_op_rrr(s, INDEX_op_shl, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_shl = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_shl,
+};
+
+static void tgen_shr(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ if (type < TCG_TYPE_REG) {
+ tcg_out_ext32u(s, TCG_REG_TMP, a1);
+ a1 = TCG_REG_TMP;
+ }
+ tcg_out_op_rrr(s, INDEX_op_shr, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_shr = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_shr,
+};
+
+static void tgen_sub(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_sub, a0, a1, a2);
+}
+
+static const TCGOutOpSubtract outop_sub = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_sub,
+};
+
+static void tgen_subbo(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_subbo, a0, a1, a2);
+}
+
+static const TCGOutOpAddSubCarry outop_subbo = {
+ .base.static_constraint = C_Dynamic,
+ .base.dynamic_constraint = cset_addsubcarry,
+ .out_rrr = tgen_subbo,
+};
+
+static void tgen_subbi(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_subbi, a0, a1, a2);
+}
+
+static const TCGOutOpAddSubCarry outop_subbi = {
+ .base.static_constraint = C_Dynamic,
+ .base.dynamic_constraint = cset_addsubcarry,
+ .out_rrr = tgen_subbi,
+};
+
+static void tgen_subbio(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_subbio, a0, a1, a2);
+}
+
+static const TCGOutOpAddSubCarry outop_subbio = {
+ .base.static_constraint = C_Dynamic,
+ .base.dynamic_constraint = cset_addsubcarry,
+ .out_rrr = tgen_subbio,
+};
+
+static void tcg_out_set_borrow(TCGContext *s)
+{
+ tcg_out_op_v(s, INDEX_op_tci_setcarry); /* borrow == carry */
+}
+
+static void tgen_xor(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, TCGReg a2)
+{
+ tcg_out_op_rrr(s, INDEX_op_xor, a0, a1, a2);
+}
+
+static const TCGOutOpBinary outop_xor = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_xor,
+};
+
+static void tgen_ctpop(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1)
+{
+ tcg_out_op_rr(s, INDEX_op_ctpop, a0, a1);
+}
+
+static TCGConstraintSetIndex cset_ctpop(TCGType type, unsigned flags)
+{
+ return type == TCG_TYPE_REG ? C_O1_I1(r, r) : C_NotImplemented;
+}
+
+static const TCGOutOpUnary outop_ctpop = {
+ .base.static_constraint = C_Dynamic,
+ .base.dynamic_constraint = cset_ctpop,
+ .out_rr = tgen_ctpop,
+};
+
+static void tgen_bswap16(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, unsigned flags)
+{
+ tcg_out_op_rr(s, INDEX_op_bswap16, a0, a1);
+ if (flags & TCG_BSWAP_OS) {
+ tcg_out_sextract(s, TCG_TYPE_REG, a0, a0, 0, 16);
+ }
+}
+
+static const TCGOutOpBswap outop_bswap16 = {
+ .base.static_constraint = C_O1_I1(r, r),
+ .out_rr = tgen_bswap16,
+};
+
+static void tgen_bswap32(TCGContext *s, TCGType type,
+ TCGReg a0, TCGReg a1, unsigned flags)
+{
+ tcg_out_op_rr(s, INDEX_op_bswap32, a0, a1);
+ if (flags & TCG_BSWAP_OS) {
+ tcg_out_sextract(s, TCG_TYPE_REG, a0, a0, 0, 32);
+ }
+}
+
+static const TCGOutOpBswap outop_bswap32 = {
+ .base.static_constraint = C_O1_I1(r, r),
+ .out_rr = tgen_bswap32,
+};
+
#if TCG_TARGET_REG_BITS == 64
- case TCG_TYPE_I64:
- tcg_out_ldst(s, INDEX_op_st_i64, val, base, offset);
- break;
+static void tgen_bswap64(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1)
+{
+ tcg_out_op_rr(s, INDEX_op_bswap64, a0, a1);
+}
+
+static const TCGOutOpUnary outop_bswap64 = {
+ .base.static_constraint = C_O1_I1(r, r),
+ .out_rr = tgen_bswap64,
+};
#endif
- default:
- g_assert_not_reached();
+
+static void tgen_neg(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1)
+{
+ tcg_out_op_rr(s, INDEX_op_neg, a0, a1);
+}
+
+static const TCGOutOpUnary outop_neg = {
+ .base.static_constraint = C_O1_I1(r, r),
+ .out_rr = tgen_neg,
+};
+
+static void tgen_not(TCGContext *s, TCGType type, TCGReg a0, TCGReg a1)
+{
+ tcg_out_op_rr(s, INDEX_op_not, a0, a1);
+}
+
+static const TCGOutOpUnary outop_not = {
+ .base.static_constraint = C_O1_I1(r, r),
+ .out_rr = tgen_not,
+};
+
+static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,
+ TCGReg dest, TCGReg arg1, TCGReg arg2)
+{
+ TCGOpcode opc = (type == TCG_TYPE_I32
+ ? INDEX_op_tci_setcond32
+ : INDEX_op_setcond);
+ tcg_out_op_rrrc(s, opc, dest, arg1, arg2, cond);
+}
+
+static const TCGOutOpSetcond outop_setcond = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_setcond,
+};
+
+static void tgen_negsetcond(TCGContext *s, TCGType type, TCGCond cond,
+ TCGReg dest, TCGReg arg1, TCGReg arg2)
+{
+ tgen_setcond(s, type, cond, dest, arg1, arg2);
+ tgen_neg(s, type, dest, dest);
+}
+
+static const TCGOutOpSetcond outop_negsetcond = {
+ .base.static_constraint = C_O1_I2(r, r, r),
+ .out_rrr = tgen_negsetcond,
+};
+
+static void tgen_brcond(TCGContext *s, TCGType type, TCGCond cond,
+ TCGReg arg0, TCGReg arg1, TCGLabel *l)
+{
+ tgen_setcond(s, type, cond, TCG_REG_TMP, arg0, arg1);
+ tcg_out_op_rl(s, INDEX_op_brcond, TCG_REG_TMP, l);
+}
+
+static const TCGOutOpBrcond outop_brcond = {
+ .base.static_constraint = C_O0_I2(r, r),
+ .out_rr = tgen_brcond,
+};
+
+static void tgen_movcond(TCGContext *s, TCGType type, TCGCond cond,
+ TCGReg ret, TCGReg c1, TCGArg c2, bool const_c2,
+ TCGArg vt, bool const_vt, TCGArg vf, bool consf_vf)
+{
+ TCGOpcode opc = (type == TCG_TYPE_I32
+ ? INDEX_op_tci_movcond32
+ : INDEX_op_movcond);
+ tcg_out_op_rrrrrc(s, opc, ret, c1, c2, vt, vf, cond);
+}
+
+static const TCGOutOpMovcond outop_movcond = {
+ .base.static_constraint = C_O1_I4(r, r, r, r, r),
+ .out = tgen_movcond,
+};
+
+static void tgen_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah,
+ TCGArg bl, bool const_bl,
+ TCGArg bh, bool const_bh, TCGLabel *l)
+{
+ tcg_out_op_rrrrrc(s, INDEX_op_setcond2_i32, TCG_REG_TMP,
+ al, ah, bl, bh, cond);
+ tcg_out_op_rl(s, INDEX_op_brcond, TCG_REG_TMP, l);
+}
+
+#if TCG_TARGET_REG_BITS != 32
+__attribute__((unused))
+#endif
+static const TCGOutOpBrcond2 outop_brcond2 = {
+ .base.static_constraint = C_O0_I4(r, r, r, r),
+ .out = tgen_brcond2,
+};
+
+static void tgen_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
+ TCGReg al, TCGReg ah,
+ TCGArg bl, bool const_bl,
+ TCGArg bh, bool const_bh)
+{
+ tcg_out_op_rrrrrc(s, INDEX_op_setcond2_i32, ret, al, ah, bl, bh, cond);
+}
+
+#if TCG_TARGET_REG_BITS != 32
+__attribute__((unused))
+#endif
+static const TCGOutOpSetcond2 outop_setcond2 = {
+ .base.static_constraint = C_O1_I4(r, r, r, r, r),
+ .out = tgen_setcond2,
+};
+
+static void tcg_out_mb(TCGContext *s, unsigned a0)
+{
+ tcg_out_op_v(s, INDEX_op_mb);
+}
+
+static void tcg_out_br(TCGContext *s, TCGLabel *l)
+{
+ tcg_out_op_l(s, INDEX_op_br, l);
+}
+
+static void tgen_ld8u(TCGContext *s, TCGType type, TCGReg dest,
+ TCGReg base, ptrdiff_t offset)
+{
+ tcg_out_ldst(s, INDEX_op_ld8u, dest, base, offset);
+}
+
+static const TCGOutOpLoad outop_ld8u = {
+ .base.static_constraint = C_O1_I1(r, r),
+ .out = tgen_ld8u,
+};
+
+static void tgen_ld8s(TCGContext *s, TCGType type, TCGReg dest,
+ TCGReg base, ptrdiff_t offset)
+{
+ tcg_out_ldst(s, INDEX_op_ld8s, dest, base, offset);
+}
+
+static const TCGOutOpLoad outop_ld8s = {
+ .base.static_constraint = C_O1_I1(r, r),
+ .out = tgen_ld8s,
+};
+
+static void tgen_ld16u(TCGContext *s, TCGType type, TCGReg dest,
+ TCGReg base, ptrdiff_t offset)
+{
+ tcg_out_ldst(s, INDEX_op_ld16u, dest, base, offset);
+}
+
+static const TCGOutOpLoad outop_ld16u = {
+ .base.static_constraint = C_O1_I1(r, r),
+ .out = tgen_ld16u,
+};
+
+static void tgen_ld16s(TCGContext *s, TCGType type, TCGReg dest,
+ TCGReg base, ptrdiff_t offset)
+{
+ tcg_out_ldst(s, INDEX_op_ld16s, dest, base, offset);
+}
+
+static const TCGOutOpLoad outop_ld16s = {
+ .base.static_constraint = C_O1_I1(r, r),
+ .out = tgen_ld16s,
+};
+
+#if TCG_TARGET_REG_BITS == 64
+static void tgen_ld32u(TCGContext *s, TCGType type, TCGReg dest,
+ TCGReg base, ptrdiff_t offset)
+{
+ tcg_out_ldst(s, INDEX_op_ld32u, dest, base, offset);
+}
+
+static const TCGOutOpLoad outop_ld32u = {
+ .base.static_constraint = C_O1_I1(r, r),
+ .out = tgen_ld32u,
+};
+
+static void tgen_ld32s(TCGContext *s, TCGType type, TCGReg dest,
+ TCGReg base, ptrdiff_t offset)
+{
+ tcg_out_ldst(s, INDEX_op_ld32s, dest, base, offset);
+}
+
+static const TCGOutOpLoad outop_ld32s = {
+ .base.static_constraint = C_O1_I1(r, r),
+ .out = tgen_ld32s,
+};
+#endif
+
+static void tgen_st8(TCGContext *s, TCGType type, TCGReg data,
+ TCGReg base, ptrdiff_t offset)
+{
+ tcg_out_ldst(s, INDEX_op_st8, data, base, offset);
+}
+
+static const TCGOutOpStore outop_st8 = {
+ .base.static_constraint = C_O0_I2(r, r),
+ .out_r = tgen_st8,
+};
+
+static void tgen_st16(TCGContext *s, TCGType type, TCGReg data,
+ TCGReg base, ptrdiff_t offset)
+{
+ tcg_out_ldst(s, INDEX_op_st16, data, base, offset);
+}
+
+static const TCGOutOpStore outop_st16 = {
+ .base.static_constraint = C_O0_I2(r, r),
+ .out_r = tgen_st16,
+};
+
+static const TCGOutOpStore outop_st = {
+ .base.static_constraint = C_O0_I2(r, r),
+ .out_r = tcg_out_st,
+};
+
+static void tgen_qemu_ld(TCGContext *s, TCGType type, TCGReg data,
+ TCGReg addr, MemOpIdx oi)
+{
+ tcg_out_op_rrm(s, INDEX_op_qemu_ld, data, addr, oi);
+}
+
+static const TCGOutOpQemuLdSt outop_qemu_ld = {
+ .base.static_constraint = C_O1_I1(r, r),
+ .out = tgen_qemu_ld,
+};
+
+static void tgen_qemu_ld2(TCGContext *s, TCGType type, TCGReg datalo,
+ TCGReg datahi, TCGReg addr, MemOpIdx oi)
+{
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, oi);
+ tcg_out_op_rrrr(s, INDEX_op_qemu_ld2, datalo, datahi, addr, TCG_REG_TMP);
+}
+
+static const TCGOutOpQemuLdSt2 outop_qemu_ld2 = {
+ .base.static_constraint =
+ TCG_TARGET_REG_BITS == 64 ? C_NotImplemented : C_O2_I1(r, r, r),
+ .out =
+ TCG_TARGET_REG_BITS == 64 ? NULL : tgen_qemu_ld2,
+};
+
+static void tgen_qemu_st(TCGContext *s, TCGType type, TCGReg data,
+ TCGReg addr, MemOpIdx oi)
+{
+ tcg_out_op_rrm(s, INDEX_op_qemu_st, data, addr, oi);
+}
+
+static const TCGOutOpQemuLdSt outop_qemu_st = {
+ .base.static_constraint = C_O0_I2(r, r),
+ .out = tgen_qemu_st,
+};
+
+static void tgen_qemu_st2(TCGContext *s, TCGType type, TCGReg datalo,
+ TCGReg datahi, TCGReg addr, MemOpIdx oi)
+{
+ tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, oi);
+ tcg_out_op_rrrr(s, INDEX_op_qemu_st2, datalo, datahi, addr, TCG_REG_TMP);
+}
+
+static const TCGOutOpQemuLdSt2 outop_qemu_st2 = {
+ .base.static_constraint =
+ TCG_TARGET_REG_BITS == 64 ? C_NotImplemented : C_O0_I3(r, r, r),
+ .out =
+ TCG_TARGET_REG_BITS == 64 ? NULL : tgen_qemu_st2,
+};
+
+static void tcg_out_st(TCGContext *s, TCGType type, TCGReg val, TCGReg base,
+ intptr_t offset)
+{
+ TCGOpcode op = INDEX_op_st;
+
+ if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
+ op = INDEX_op_st32;
}
+ tcg_out_ldst(s, op, val, base, offset);
}
static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,