@@ -595,6 +595,14 @@
gen_helper_vacsh_val(RxxV, cpu_env, RxxV, RssV, RttV); \
} while (0)
+#define fGEN_TCG_S2_cabacdecbin(SHORTCODE) \
+ do { \
+ TCGv p0 = tcg_temp_new(); \
+ gen_helper_cabacdecbin_pred(p0, RssV, RttV); \
+ gen_helper_cabacdecbin_val(RddV, RssV, RttV); \
+ gen_log_pred_write(ctx, 0, p0); \
+ } while (0)
+
/*
* Approximate reciprocal
* r3,p1 = sfrecipa(r0, r1)
@@ -900,6 +908,14 @@
#define fGEN_TCG_J4_tstbit0_fp1_jump_t(SHORTCODE) \
gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_NE, riV)
+/* p0 = cmp.eq(r0, #7) */
+#define fGEN_TCG_SA1_cmpeqi(SHORTCODE) \
+ do { \
+ TCGv p0 = tcg_temp_new(); \
+ gen_comparei(TCG_COND_EQ, p0, RsV, uiV); \
+ gen_log_pred_write(ctx, 0, p0); \
+ } while (0)
+
#define fGEN_TCG_J2_jump(SHORTCODE) \
gen_jump(ctx, riV)
#define fGEN_TCG_J2_jumpr(SHORTCODE) \
@@ -31,6 +31,8 @@ DEF_HELPER_3(sfrecipa, i64, env, f32, f32)
DEF_HELPER_2(sfinvsqrta, i64, env, f32)
DEF_HELPER_4(vacsh_val, s64, env, s64, s64, s64)
DEF_HELPER_FLAGS_4(vacsh_pred, TCG_CALL_NO_RWG_SE, s32, env, s64, s64, s64)
+DEF_HELPER_FLAGS_2(cabacdecbin_val, TCG_CALL_NO_RWG_SE, s64, s64, s64)
+DEF_HELPER_FLAGS_2(cabacdecbin_pred, TCG_CALL_NO_RWG_SE, s32, s64, s64)
/* Floating point */
DEF_HELPER_2(conv_sf2df, f64, env, f32)
@@ -371,10 +371,6 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
#define fSET_OVERFLOW() SET_USR_FIELD(USR_OVF, 1)
#define fSET_LPCFG(VAL) SET_USR_FIELD(USR_LPCFG, (VAL))
#define fGET_LPCFG (GET_USR_FIELD(USR_LPCFG))
-#define fWRITE_P0(VAL) log_pred_write(env, 0, VAL)
-#define fWRITE_P1(VAL) log_pred_write(env, 1, VAL)
-#define fWRITE_P2(VAL) log_pred_write(env, 2, VAL)
-#define fWRITE_P3(VAL) log_pred_write(env, 3, VAL)
#define fPART1(WORK) if (part1) { WORK; return; }
#define fCAST4u(A) ((uint32_t)(A))
#define fCAST4s(A) ((int32_t)(A))
@@ -560,6 +560,11 @@ static void gen_ploopNsi(DisasContext *ctx, int N, int count, int riV)
{
gen_ploopNsr(ctx, N, tcg_constant_tl(count), riV);
}
+
+static inline void gen_comparei(TCGCond cond, TCGv res, TCGv arg1, int arg2)
+{
+ gen_compare(cond, res, arg1, tcg_constant_tl(arg2));
+}
#endif
static void gen_cond_jumpr(DisasContext *ctx, TCGv dst_pc,
@@ -52,21 +52,6 @@ G_NORETURN void HELPER(raise_exception)(CPUHexagonState *env, uint32_t excp)
do_raise_exception_err(env, excp, 0);
}
-static void log_pred_write(CPUHexagonState *env, int pnum, target_ulong val)
-{
- HEX_DEBUG_LOG("log_pred_write[%d] = " TARGET_FMT_ld
- " (0x" TARGET_FMT_lx ")\n",
- pnum, val, val);
-
- /* Multiple writes to the same preg are and'ed together */
- if (env->pred_written & (1 << pnum)) {
- env->new_pred_value[pnum] &= val & 0xff;
- } else {
- env->new_pred_value[pnum] = val & 0xff;
- env->pred_written |= 1 << pnum;
- }
-}
-
void log_store32(CPUHexagonState *env, target_ulong addr,
target_ulong val, int width, int slot)
{
@@ -399,6 +384,87 @@ int32_t HELPER(vacsh_pred)(CPUHexagonState *env,
return PeV;
}
+int64_t HELPER(cabacdecbin_val)(int64_t RssV, int64_t RttV)
+{
+ int64_t RddV = 0;
+ size4u_t state;
+ size4u_t valMPS;
+ size4u_t bitpos;
+ size4u_t range;
+ size4u_t offset;
+ size4u_t rLPS;
+ size4u_t rMPS;
+
+ state = fEXTRACTU_RANGE(fGETWORD(1, RttV), 5, 0);
+ valMPS = fEXTRACTU_RANGE(fGETWORD(1, RttV), 8, 8);
+ bitpos = fEXTRACTU_RANGE(fGETWORD(0, RttV), 4, 0);
+ range = fGETWORD(0, RssV);
+ offset = fGETWORD(1, RssV);
+
+ /* calculate rLPS */
+ range <<= bitpos;
+ offset <<= bitpos;
+ rLPS = rLPS_table_64x4[state][(range >> 29) & 3];
+ rLPS = rLPS << 23; /* left aligned */
+
+ /* calculate rMPS */
+ rMPS = (range & 0xff800000) - rLPS;
+
+ /* most probable region */
+ if (offset < rMPS) {
+ RddV = AC_next_state_MPS_64[state];
+ fINSERT_RANGE(RddV, 8, 8, valMPS);
+ fINSERT_RANGE(RddV, 31, 23, (rMPS >> 23));
+ fSETWORD(1, RddV, offset);
+ }
+ /* least probable region */
+ else {
+ RddV = AC_next_state_LPS_64[state];
+ fINSERT_RANGE(RddV, 8, 8, ((!state) ? (1 - valMPS) : (valMPS)));
+ fINSERT_RANGE(RddV, 31, 23, (rLPS >> 23));
+ fSETWORD(1, RddV, (offset - rMPS));
+ }
+ return RddV;
+}
+
+int32_t HELPER(cabacdecbin_pred)(int64_t RssV, int64_t RttV)
+{
+ int32_t p0 = 0;
+ size4u_t state;
+ size4u_t valMPS;
+ size4u_t bitpos;
+ size4u_t range;
+ size4u_t offset;
+ size4u_t rLPS;
+ size4u_t rMPS;
+
+ state = fEXTRACTU_RANGE(fGETWORD(1, RttV), 5, 0);
+ valMPS = fEXTRACTU_RANGE(fGETWORD(1, RttV), 8, 8);
+ bitpos = fEXTRACTU_RANGE(fGETWORD(0, RttV), 4, 0);
+ range = fGETWORD(0, RssV);
+ offset = fGETWORD(1, RssV);
+
+ /* calculate rLPS */
+ range <<= bitpos;
+ offset <<= bitpos;
+ rLPS = rLPS_table_64x4[state][(range >> 29) & 3];
+ rLPS = rLPS << 23; /* left aligned */
+
+ /* calculate rMPS */
+ rMPS = (range & 0xff800000) - rLPS;
+
+ /* most probable region */
+ if (offset < rMPS) {
+ p0 = valMPS;
+
+ }
+ /* least probable region */
+ else {
+ p0 = valMPS ^ 1;
+ }
+ return p0;
+}
+
static void probe_store(CPUHexagonState *env, int slot, int mmu_idx,
bool is_predicated)
{
These instructions have implicit writes to registers, so we don't want them to be helpers when idef-parser is off. The following instructions are overriden S2_cabacdecbin SA1_cmpeqi Remove the log_pred_write function from op_helper.c Remove references in macros.h Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> --- target/hexagon/gen_tcg.h | 16 +++++++ target/hexagon/helper.h | 2 + target/hexagon/macros.h | 4 -- target/hexagon/genptr.c | 5 ++ target/hexagon/op_helper.c | 96 ++++++++++++++++++++++++++++++++------ 5 files changed, 104 insertions(+), 19 deletions(-)