This enables allocation of i128. The type is not yet usable, as we have not yet added data movement ops.
Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- include/tcg/tcg.h | 32 ++++++++++++++++++++++++++++++++ tcg/tci/tcg-target.h | 3 +++ tcg/tcg.c | 32 +++++++++++++++++++++++++++----- 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index e80c78b2e8..185408935b 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -695,6 +695,11 @@ static inline TCGTemp *tcgv_i64_temp(TCGv_i64 v) return tcgv_i32_temp((TCGv_i32)v); } +static inline TCGTemp *tcgv_i128_temp(TCGv_i128 v) +{ + return tcgv_i32_temp((TCGv_i32)v); +} + static inline TCGTemp *tcgv_ptr_temp(TCGv_ptr v) { return tcgv_i32_temp((TCGv_i32)v); @@ -715,6 +720,11 @@ static inline TCGArg tcgv_i64_arg(TCGv_i64 v) return temp_arg(tcgv_i64_temp(v)); } +static inline TCGArg tcgv_i128_arg(TCGv_i128 v) +{ + return temp_arg(tcgv_i128_temp(v)); +} + static inline TCGArg tcgv_ptr_arg(TCGv_ptr v) { return temp_arg(tcgv_ptr_temp(v)); @@ -736,6 +746,11 @@ static inline TCGv_i64 temp_tcgv_i64(TCGTemp *t) return (TCGv_i64)temp_tcgv_i32(t); } +static inline TCGv_i128 temp_tcgv_i128(TCGTemp *t) +{ + return (TCGv_i128)temp_tcgv_i32(t); +} + static inline TCGv_ptr temp_tcgv_ptr(TCGTemp *t) { return (TCGv_ptr)temp_tcgv_i32(t); @@ -858,6 +873,11 @@ static inline void tcg_temp_free_i64(TCGv_i64 arg) tcg_temp_free_internal(tcgv_i64_temp(arg)); } +static inline void tcg_temp_free_i128(TCGv_i128 arg) +{ + tcg_temp_free_internal(tcgv_i128_temp(arg)); +} + static inline void tcg_temp_free_ptr(TCGv_ptr arg) { tcg_temp_free_internal(tcgv_ptr_temp(arg)); @@ -906,6 +926,18 @@ static inline TCGv_i64 tcg_temp_local_new_i64(void) return temp_tcgv_i64(t); } +static inline TCGv_i128 tcg_temp_new_i128(void) +{ + TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, false); + return temp_tcgv_i128(t); +} + +static inline TCGv_i128 tcg_temp_local_new_i128(void) +{ + TCGTemp *t = tcg_temp_new_internal(TCG_TYPE_I128, true); + return temp_tcgv_i128(t); +} + static inline TCGv_ptr tcg_global_mem_new_ptr(TCGv_ptr reg, intptr_t offset, const char *name) { diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h index 94ec541b4e..9d569c9e04 100644 --- a/tcg/tci/tcg-target.h +++ b/tcg/tci/tcg-target.h @@ -161,10 +161,13 @@ typedef enum { #if TCG_TARGET_REG_BITS == 32 # define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_EVEN # define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_EVEN +# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_EVEN #else # define TCG_TARGET_CALL_ARG_I32 TCG_CALL_ARG_NORMAL # define TCG_TARGET_CALL_ARG_I64 TCG_CALL_ARG_NORMAL +# define TCG_TARGET_CALL_ARG_I128 TCG_CALL_ARG_NORMAL #endif +#define TCG_TARGET_CALL_RET_I128 TCG_CALL_RET_NORMAL #define HAVE_TCG_QEMU_TB_EXEC #define TCG_TARGET_NEED_POOL_LABELS diff --git a/tcg/tcg.c b/tcg/tcg.c index 352175afcd..c6e856a2cc 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1250,18 +1250,39 @@ TCGTemp *tcg_temp_new_internal(TCGType type, bool temp_local) tcg_debug_assert(ts->base_type == type); tcg_debug_assert(ts->kind == kind); } else { + bool want_pair = false; + TCGType half = type; + + switch (type) { + case TCG_TYPE_I32: + case TCG_TYPE_V64: + case TCG_TYPE_V128: + case TCG_TYPE_V256: + break; + case TCG_TYPE_I64: + half = TCG_TYPE_I32; + want_pair = TCG_TARGET_REG_BITS == 32; + break; + case TCG_TYPE_I128: + half = TCG_TYPE_I64; + want_pair = TCG_TARGET_REG_BITS == 64; + break; + default: + g_assert_not_reached(); + } + ts = tcg_temp_alloc(s); - if (TCG_TARGET_REG_BITS == 32 && type == TCG_TYPE_I64) { + if (want_pair) { TCGTemp *ts2 = tcg_temp_alloc(s); ts->base_type = type; - ts->type = TCG_TYPE_I32; + ts->type = half; ts->temp_allocated = 1; ts->kind = kind; tcg_debug_assert(ts2 == ts + 1); - ts2->base_type = TCG_TYPE_I64; - ts2->type = TCG_TYPE_I32; + ts2->base_type = type; + ts2->type = half; ts2->temp_allocated = 1; ts2->temp_subindex = 1; ts2->kind = kind; @@ -2773,7 +2794,7 @@ static void la_cross_call(TCGContext *s, int nt) for (i = 0; i < nt; i++) { TCGTemp *ts = &s->temps[i]; - if (!(ts->state & TS_DEAD)) { + if (ts->type != TCG_TYPE_I128 && !(ts->state & TS_DEAD)) { TCGRegSet *pset = la_temp_pref(ts); TCGRegSet set = *pset; @@ -3404,6 +3425,7 @@ static void temp_allocate_frame(TCGContext *s, TCGTemp *ts) case TCG_TYPE_V64: align = 8; break; + case TCG_TYPE_I128: case TCG_TYPE_V128: case TCG_TYPE_V256: /* Note that we do not require aligned storage for V256. */ -- 2.34.1