diff options
-rw-r--r-- | target/hppa/insns.decode | 7 | ||||
-rw-r--r-- | target/hppa/translate.c | 42 |
2 files changed, 36 insertions, 13 deletions
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode index 12684b5..7b51f39 100644 --- a/target/hppa/insns.decode +++ b/target/hppa/insns.decode @@ -335,8 +335,11 @@ addbi 101011 ..... ..... ... ........... . . @rib_cf f=1 shrpw_sar 110100 r2:5 r1:5 c:3 00 0 00000 t:5 shrpw_imm 110100 r2:5 r1:5 c:3 01 0 cpos:5 t:5 -extrw_sar 110100 r:5 t:5 c:3 10 se:1 00000 clen:5 -extrw_imm 110100 r:5 t:5 c:3 11 se:1 pos:5 clen:5 +extr_sar 110100 r:5 t:5 c:3 10 se:1 00 000 ..... d=0 len=%len5 +extr_sar 110100 r:5 t:5 c:3 10 se:1 1. 000 ..... d=1 len=%len6_8 +extr_imm 110100 r:5 t:5 c:3 11 se:1 pos:5 ..... d=0 len=%len5 +extr_imm 110110 r:5 t:5 c:3 .. se:1 ..... ..... \ + d=1 len=%len6_12 pos=%cpos6_11 dep_sar 110101 t:5 r:5 c:3 00 nz:1 00 000 ..... d=0 len=%len5 dep_sar 110101 t:5 r:5 c:3 00 nz:1 1. 000 ..... d=1 len=%len6_8 diff --git a/target/hppa/translate.c b/target/hppa/translate.c index ea2150c..533e298 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -3354,11 +3354,14 @@ static bool trans_shrpw_imm(DisasContext *ctx, arg_shrpw_imm *a) return nullify_end(ctx); } -static bool trans_extrw_sar(DisasContext *ctx, arg_extrw_sar *a) +static bool trans_extr_sar(DisasContext *ctx, arg_extr_sar *a) { - unsigned len = 32 - a->clen; + unsigned widthm1 = a->d ? 63 : 31; TCGv_reg dest, src, tmp; + if (!ctx->is_pa20 && a->d) { + return false; + } if (a->c) { nullify_over(ctx); } @@ -3368,36 +3371,53 @@ static bool trans_extrw_sar(DisasContext *ctx, arg_extrw_sar *a) tmp = tcg_temp_new(); /* Recall that SAR is using big-endian bit numbering. */ - tcg_gen_andi_reg(tmp, cpu_sar, 31); - tcg_gen_xori_reg(tmp, tmp, 31); + tcg_gen_andi_reg(tmp, cpu_sar, widthm1); + tcg_gen_xori_reg(tmp, tmp, widthm1); if (a->se) { + if (!a->d) { + tcg_gen_ext32s_reg(dest, src); + src = dest; + } tcg_gen_sar_reg(dest, src, tmp); - tcg_gen_sextract_reg(dest, dest, 0, len); + tcg_gen_sextract_reg(dest, dest, 0, a->len); } else { + if (!a->d) { + tcg_gen_ext32u_reg(dest, src); + src = dest; + } tcg_gen_shr_reg(dest, src, tmp); - tcg_gen_extract_reg(dest, dest, 0, len); + tcg_gen_extract_reg(dest, dest, 0, a->len); } save_gpr(ctx, a->t, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (a->c) { - ctx->null_cond = do_sed_cond(ctx, a->c, false, dest); + ctx->null_cond = do_sed_cond(ctx, a->c, a->d, dest); } return nullify_end(ctx); } -static bool trans_extrw_imm(DisasContext *ctx, arg_extrw_imm *a) +static bool trans_extr_imm(DisasContext *ctx, arg_extr_imm *a) { - unsigned len = 32 - a->clen; - unsigned cpos = 31 - a->pos; + unsigned len, cpos, width; TCGv_reg dest, src; + if (!ctx->is_pa20 && a->d) { + return false; + } if (a->c) { nullify_over(ctx); } + len = a->len; + width = a->d ? 64 : 32; + cpos = width - 1 - a->pos; + if (cpos + len > width) { + len = width - cpos; + } + dest = dest_gpr(ctx, a->t); src = load_gpr(ctx, a->r); if (a->se) { @@ -3410,7 +3430,7 @@ static bool trans_extrw_imm(DisasContext *ctx, arg_extrw_imm *a) /* Install the new nullification. */ cond_free(&ctx->null_cond); if (a->c) { - ctx->null_cond = do_sed_cond(ctx, a->c, false, dest); + ctx->null_cond = do_sed_cond(ctx, a->c, a->d, dest); } return nullify_end(ctx); } |