|
@@ -353,6 +353,13 @@ static inline void tcg_gen_movi_i32(TCGv_i32 ret, int32_t arg)
|
|
|
tcg_gen_op2i_i32(INDEX_op_movi_i32, ret, arg);
|
|
|
}
|
|
|
|
|
|
+/* A version of dh_sizemask from def-helper.h that doesn't rely on
|
|
|
+ preprocessor magic. */
|
|
|
+static inline int tcg_gen_sizemask(int n, int is_64bit, int is_signed)
|
|
|
+{
|
|
|
+ return (is_64bit << n*2) | (is_signed << (n*2 + 1));
|
|
|
+}
|
|
|
+
|
|
|
/* helper calls */
|
|
|
static inline void tcg_gen_helperN(void *func, int flags, int sizemask,
|
|
|
TCGArg ret, int nargs, TCGArg *args)
|
|
@@ -369,7 +376,7 @@ static inline void tcg_gen_helperN(void *func, int flags, int sizemask,
|
|
|
and pure, hence the call to tcg_gen_callN() with TCG_CALL_CONST |
|
|
|
TCG_CALL_PURE. This may need to be adjusted if these functions
|
|
|
start to be used with other helpers. */
|
|
|
-static inline void tcg_gen_helper32(void *func, TCGv_i32 ret,
|
|
|
+static inline void tcg_gen_helper32(void *func, int sizemask, TCGv_i32 ret,
|
|
|
TCGv_i32 a, TCGv_i32 b)
|
|
|
{
|
|
|
TCGv_ptr fn;
|
|
@@ -377,12 +384,12 @@ static inline void tcg_gen_helper32(void *func, TCGv_i32 ret,
|
|
|
fn = tcg_const_ptr((tcg_target_long)func);
|
|
|
args[0] = GET_TCGV_I32(a);
|
|
|
args[1] = GET_TCGV_I32(b);
|
|
|
- tcg_gen_callN(&tcg_ctx, fn, TCG_CALL_CONST | TCG_CALL_PURE,
|
|
|
- 0, GET_TCGV_I32(ret), 2, args);
|
|
|
+ tcg_gen_callN(&tcg_ctx, fn, TCG_CALL_CONST | TCG_CALL_PURE, sizemask,
|
|
|
+ GET_TCGV_I32(ret), 2, args);
|
|
|
tcg_temp_free_ptr(fn);
|
|
|
}
|
|
|
|
|
|
-static inline void tcg_gen_helper64(void *func, TCGv_i64 ret,
|
|
|
+static inline void tcg_gen_helper64(void *func, int sizemask, TCGv_i64 ret,
|
|
|
TCGv_i64 a, TCGv_i64 b)
|
|
|
{
|
|
|
TCGv_ptr fn;
|
|
@@ -390,8 +397,8 @@ static inline void tcg_gen_helper64(void *func, TCGv_i64 ret,
|
|
|
fn = tcg_const_ptr((tcg_target_long)func);
|
|
|
args[0] = GET_TCGV_I64(a);
|
|
|
args[1] = GET_TCGV_I64(b);
|
|
|
- tcg_gen_callN(&tcg_ctx, fn, TCG_CALL_CONST | TCG_CALL_PURE,
|
|
|
- 7, GET_TCGV_I64(ret), 2, args);
|
|
|
+ tcg_gen_callN(&tcg_ctx, fn, TCG_CALL_CONST | TCG_CALL_PURE, sizemask,
|
|
|
+ GET_TCGV_I64(ret), 2, args);
|
|
|
tcg_temp_free_ptr(fn);
|
|
|
}
|
|
|
|
|
@@ -692,22 +699,46 @@ static inline void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
|
|
|
#else
|
|
|
static inline void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
|
|
|
{
|
|
|
- tcg_gen_helper32(tcg_helper_div_i32, ret, arg1, arg2);
|
|
|
+ int sizemask = 0;
|
|
|
+ /* Return value and both arguments are 32-bit and signed. */
|
|
|
+ sizemask |= tcg_gen_sizemask(0, 0, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(1, 0, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(2, 0, 1);
|
|
|
+
|
|
|
+ tcg_gen_helper32(tcg_helper_div_i32, sizemask, ret, arg1, arg2);
|
|
|
}
|
|
|
|
|
|
static inline void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
|
|
|
{
|
|
|
- tcg_gen_helper32(tcg_helper_rem_i32, ret, arg1, arg2);
|
|
|
+ int sizemask = 0;
|
|
|
+ /* Return value and both arguments are 32-bit and signed. */
|
|
|
+ sizemask |= tcg_gen_sizemask(0, 0, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(1, 0, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(2, 0, 1);
|
|
|
+
|
|
|
+ tcg_gen_helper32(tcg_helper_rem_i32, sizemask, ret, arg1, arg2);
|
|
|
}
|
|
|
|
|
|
static inline void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
|
|
|
{
|
|
|
- tcg_gen_helper32(tcg_helper_divu_i32, ret, arg1, arg2);
|
|
|
+ int sizemask = 0;
|
|
|
+ /* Return value and both arguments are 32-bit and unsigned. */
|
|
|
+ sizemask |= tcg_gen_sizemask(0, 0, 0);
|
|
|
+ sizemask |= tcg_gen_sizemask(1, 0, 0);
|
|
|
+ sizemask |= tcg_gen_sizemask(2, 0, 0);
|
|
|
+
|
|
|
+ tcg_gen_helper32(tcg_helper_divu_i32, ret, arg1, arg2, 0);
|
|
|
}
|
|
|
|
|
|
static inline void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
|
|
|
{
|
|
|
- tcg_gen_helper32(tcg_helper_remu_i32, ret, arg1, arg2);
|
|
|
+ int sizemask = 0;
|
|
|
+ /* Return value and both arguments are 32-bit and unsigned. */
|
|
|
+ sizemask |= tcg_gen_sizemask(0, 0, 0);
|
|
|
+ sizemask |= tcg_gen_sizemask(1, 0, 0);
|
|
|
+ sizemask |= tcg_gen_sizemask(2, 0, 0);
|
|
|
+
|
|
|
+ tcg_gen_helper32(tcg_helper_remu_i32, ret, arg1, arg2, 0);
|
|
|
}
|
|
|
#endif
|
|
|
|
|
@@ -867,7 +898,13 @@ static inline void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
|
|
|
specific code (x86) */
|
|
|
static inline void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
|
|
{
|
|
|
- tcg_gen_helper64(tcg_helper_shl_i64, ret, arg1, arg2);
|
|
|
+ int sizemask = 0;
|
|
|
+ /* Return value and both arguments are 64-bit and signed. */
|
|
|
+ sizemask |= tcg_gen_sizemask(0, 1, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(1, 1, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(2, 1, 1);
|
|
|
+
|
|
|
+ tcg_gen_helper64(tcg_helper_shl_i64, sizemask, ret, arg1, arg2);
|
|
|
}
|
|
|
|
|
|
static inline void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
|
|
@@ -877,7 +914,13 @@ static inline void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
|
|
|
|
|
|
static inline void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
|
|
{
|
|
|
- tcg_gen_helper64(tcg_helper_shr_i64, ret, arg1, arg2);
|
|
|
+ int sizemask = 0;
|
|
|
+ /* Return value and both arguments are 64-bit and signed. */
|
|
|
+ sizemask |= tcg_gen_sizemask(0, 1, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(1, 1, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(2, 1, 1);
|
|
|
+
|
|
|
+ tcg_gen_helper64(tcg_helper_shr_i64, sizemask, ret, arg1, arg2);
|
|
|
}
|
|
|
|
|
|
static inline void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
|
|
@@ -887,7 +930,13 @@ static inline void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
|
|
|
|
|
|
static inline void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
|
|
{
|
|
|
- tcg_gen_helper64(tcg_helper_sar_i64, ret, arg1, arg2);
|
|
|
+ int sizemask = 0;
|
|
|
+ /* Return value and both arguments are 64-bit and signed. */
|
|
|
+ sizemask |= tcg_gen_sizemask(0, 1, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(1, 1, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(2, 1, 1);
|
|
|
+
|
|
|
+ tcg_gen_helper64(tcg_helper_sar_i64, sizemask, ret, arg1, arg2);
|
|
|
}
|
|
|
|
|
|
static inline void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
|
|
@@ -935,22 +984,46 @@ static inline void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
|
|
|
|
|
static inline void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
|
|
{
|
|
|
- tcg_gen_helper64(tcg_helper_div_i64, ret, arg1, arg2);
|
|
|
+ int sizemask = 0;
|
|
|
+ /* Return value and both arguments are 64-bit and signed. */
|
|
|
+ sizemask |= tcg_gen_sizemask(0, 1, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(1, 1, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(2, 1, 1);
|
|
|
+
|
|
|
+ tcg_gen_helper64(tcg_helper_div_i64, sizemask, ret, arg1, arg2);
|
|
|
}
|
|
|
|
|
|
static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
|
|
{
|
|
|
- tcg_gen_helper64(tcg_helper_rem_i64, ret, arg1, arg2);
|
|
|
+ int sizemask = 0;
|
|
|
+ /* Return value and both arguments are 64-bit and signed. */
|
|
|
+ sizemask |= tcg_gen_sizemask(0, 1, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(1, 1, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(2, 1, 1);
|
|
|
+
|
|
|
+ tcg_gen_helper64(tcg_helper_rem_i64, sizemask, ret, arg1, arg2);
|
|
|
}
|
|
|
|
|
|
static inline void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
|
|
{
|
|
|
- tcg_gen_helper64(tcg_helper_divu_i64, ret, arg1, arg2);
|
|
|
+ int sizemask = 0;
|
|
|
+ /* Return value and both arguments are 64-bit and unsigned. */
|
|
|
+ sizemask |= tcg_gen_sizemask(0, 1, 0);
|
|
|
+ sizemask |= tcg_gen_sizemask(1, 1, 0);
|
|
|
+ sizemask |= tcg_gen_sizemask(2, 1, 0);
|
|
|
+
|
|
|
+ tcg_gen_helper64(tcg_helper_divu_i64, sizemask, ret, arg1, arg2);
|
|
|
}
|
|
|
|
|
|
static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
|
|
{
|
|
|
- tcg_gen_helper64(tcg_helper_remu_i64, ret, arg1, arg2);
|
|
|
+ int sizemask = 0;
|
|
|
+ /* Return value and both arguments are 64-bit and unsigned. */
|
|
|
+ sizemask |= tcg_gen_sizemask(0, 1, 0);
|
|
|
+ sizemask |= tcg_gen_sizemask(1, 1, 0);
|
|
|
+ sizemask |= tcg_gen_sizemask(2, 1, 0);
|
|
|
+
|
|
|
+ tcg_gen_helper64(tcg_helper_remu_i64, sizemask, ret, arg1, arg2);
|
|
|
}
|
|
|
|
|
|
#else
|
|
@@ -1212,22 +1285,46 @@ static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
|
|
#else
|
|
|
static inline void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
|
|
{
|
|
|
- tcg_gen_helper64(tcg_helper_div_i64, ret, arg1, arg2);
|
|
|
+ int sizemask = 0;
|
|
|
+ /* Return value and both arguments are 64-bit and signed. */
|
|
|
+ sizemask |= tcg_gen_sizemask(0, 1, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(1, 1, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(2, 1, 1);
|
|
|
+
|
|
|
+ tcg_gen_helper64(tcg_helper_div_i64, sizemask, ret, arg1, arg2);
|
|
|
}
|
|
|
|
|
|
static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
|
|
{
|
|
|
- tcg_gen_helper64(tcg_helper_rem_i64, ret, arg1, arg2);
|
|
|
+ int sizemask = 0;
|
|
|
+ /* Return value and both arguments are 64-bit and signed. */
|
|
|
+ sizemask |= tcg_gen_sizemask(0, 1, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(1, 1, 1);
|
|
|
+ sizemask |= tcg_gen_sizemask(2, 1, 1);
|
|
|
+
|
|
|
+ tcg_gen_helper64(tcg_helper_rem_i64, sizemask, ret, arg1, arg2);
|
|
|
}
|
|
|
|
|
|
static inline void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
|
|
{
|
|
|
- tcg_gen_helper64(tcg_helper_divu_i64, ret, arg1, arg2);
|
|
|
+ int sizemask = 0;
|
|
|
+ /* Return value and both arguments are 64-bit and unsigned. */
|
|
|
+ sizemask |= tcg_gen_sizemask(0, 1, 0);
|
|
|
+ sizemask |= tcg_gen_sizemask(1, 1, 0);
|
|
|
+ sizemask |= tcg_gen_sizemask(2, 1, 0);
|
|
|
+
|
|
|
+ tcg_gen_helper64(tcg_helper_divu_i64, sizemask, ret, arg1, arg2);
|
|
|
}
|
|
|
|
|
|
static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
|
|
{
|
|
|
- tcg_gen_helper64(tcg_helper_remu_i64, ret, arg1, arg2);
|
|
|
+ int sizemask = 0;
|
|
|
+ /* Return value and both arguments are 64-bit and unsigned. */
|
|
|
+ sizemask |= tcg_gen_sizemask(0, 1, 0);
|
|
|
+ sizemask |= tcg_gen_sizemask(1, 1, 0);
|
|
|
+ sizemask |= tcg_gen_sizemask(2, 1, 0);
|
|
|
+
|
|
|
+ tcg_gen_helper64(tcg_helper_remu_i64, sizemask, ret, arg1, arg2);
|
|
|
}
|
|
|
#endif
|
|
|
|