target/hppa: Implement DEPD, DEPDI

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2023-09-20 11:44:17 +02:00
parent 51416c4e41
commit 72ae4f2b82
2 changed files with 69 additions and 30 deletions

View File

@ -46,6 +46,10 @@
%im5_0 0:s1 1:4
%im5_16 16:s1 17:4
%len5 0:5 !function=assemble_6
%len6_8 8:1 0:5 !function=assemble_6
%len6_12 12:1 0:5 !function=assemble_6
%cpos6_11 11:1 5:5
%ma_to_m 5:1 13:1 !function=ma_to_m
%ma2_to_m 2:2 !function=ma_to_m
%pos_to_m 0:1 !function=pos_to_m
@ -334,10 +338,17 @@ 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
depw_sar 110101 t:5 r:5 c:3 00 nz:1 00000 clen:5
depw_imm 110101 t:5 r:5 c:3 01 nz:1 cpos:5 clen:5
depwi_sar 110101 t:5 ..... c:3 10 nz:1 00000 clen:5 i=%im5_16
depwi_imm 110101 t:5 ..... c:3 11 nz:1 cpos:5 clen:5 i=%im5_16
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
dep_imm 110101 t:5 r:5 c:3 01 nz:1 cpos:5 ..... d=0 len=%len5
dep_imm 111100 t:5 r:5 c:3 .. nz:1 ..... ..... \
d=1 len=%len6_12 cpos=%cpos6_11
depi_sar 110101 t:5 ..... c:3 10 nz:1 d:1 . 000 ..... \
i=%im5_16 len=%len6_8
depi_imm 110101 t:5 ..... c:3 11 nz:1 cpos:5 ..... \
d=0 i=%im5_16 len=%len5
depi_imm 111101 t:5 ..... c:3 .. nz:1 ..... ..... \
d=1 i=%im5_16 len=%len6_12 cpos=%cpos6_11
####
# Branch External

View File

@ -329,6 +329,17 @@ static int expand_shl11(DisasContext *ctx, int val)
return val << 11;
}
static int assemble_6(DisasContext *ctx, int val)
{
/*
* Officially, 32 * x + 32 - y.
* Here, x is already in bit 5, and y is [4:0].
* Since -y = ~y + 1, in 5 bits 32 - y => y ^ 31 + 1,
* with the overflow from bit 4 summing with x.
*/
return (val ^ 31) + 1;
}
/* Translate CMPI doubleword conditions to standard. */
static int cmpbid_c(DisasContext *ctx, int val)
{
@ -3404,17 +3415,23 @@ static bool trans_extrw_imm(DisasContext *ctx, arg_extrw_imm *a)
return nullify_end(ctx);
}
static bool trans_depwi_imm(DisasContext *ctx, arg_depwi_imm *a)
static bool trans_depi_imm(DisasContext *ctx, arg_depi_imm *a)
{
unsigned len = 32 - a->clen;
unsigned len, width;
target_sreg mask0, mask1;
TCGv_reg dest;
if (!ctx->is_pa20 && a->d) {
return false;
}
if (a->c) {
nullify_over(ctx);
}
if (a->cpos + len > 32) {
len = 32 - a->cpos;
len = a->len;
width = a->d ? 64 : 32;
if (a->cpos + len > width) {
len = width - a->cpos;
}
dest = dest_gpr(ctx, a->t);
@ -3423,11 +3440,8 @@ static bool trans_depwi_imm(DisasContext *ctx, arg_depwi_imm *a)
if (a->nz) {
TCGv_reg src = load_gpr(ctx, a->t);
if (mask1 != -1) {
tcg_gen_andi_reg(dest, src, mask1);
src = dest;
}
tcg_gen_ori_reg(dest, src, mask0);
tcg_gen_andi_reg(dest, src, mask1);
tcg_gen_ori_reg(dest, dest, mask0);
} else {
tcg_gen_movi_reg(dest, mask0);
}
@ -3436,22 +3450,28 @@ static bool trans_depwi_imm(DisasContext *ctx, arg_depwi_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);
}
static bool trans_depw_imm(DisasContext *ctx, arg_depw_imm *a)
static bool trans_dep_imm(DisasContext *ctx, arg_dep_imm *a)
{
unsigned rs = a->nz ? a->t : 0;
unsigned len = 32 - a->clen;
unsigned len, width;
TCGv_reg dest, val;
if (!ctx->is_pa20 && a->d) {
return false;
}
if (a->c) {
nullify_over(ctx);
}
if (a->cpos + len > 32) {
len = 32 - a->cpos;
len = a->len;
width = a->d ? 64 : 32;
if (a->cpos + len > width) {
len = width - a->cpos;
}
dest = dest_gpr(ctx, a->t);
@ -3466,26 +3486,26 @@ static bool trans_depw_imm(DisasContext *ctx, arg_depw_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);
}
static bool do_depw_sar(DisasContext *ctx, unsigned rt, unsigned c,
unsigned nz, unsigned clen, TCGv_reg val)
static bool do_dep_sar(DisasContext *ctx, unsigned rt, unsigned c,
bool d, bool nz, unsigned len, TCGv_reg val)
{
unsigned rs = nz ? rt : 0;
unsigned len = 32 - clen;
unsigned widthm1 = d ? 63 : 31;
TCGv_reg mask, tmp, shift, dest;
unsigned msb = 1U << (len - 1);
target_ureg msb = 1ULL << (len - 1);
dest = dest_gpr(ctx, rt);
shift = tcg_temp_new();
tmp = tcg_temp_new();
/* Convert big-endian bit numbering in SAR to left-shift. */
tcg_gen_andi_reg(shift, cpu_sar, 31);
tcg_gen_xori_reg(shift, shift, 31);
tcg_gen_andi_reg(shift, cpu_sar, widthm1);
tcg_gen_xori_reg(shift, shift, widthm1);
mask = tcg_temp_new();
tcg_gen_movi_reg(mask, msb + (msb - 1));
@ -3503,25 +3523,33 @@ static bool do_depw_sar(DisasContext *ctx, unsigned rt, unsigned c,
/* Install the new nullification. */
cond_free(&ctx->null_cond);
if (c) {
ctx->null_cond = do_sed_cond(ctx, c, false, dest);
ctx->null_cond = do_sed_cond(ctx, c, d, dest);
}
return nullify_end(ctx);
}
static bool trans_depw_sar(DisasContext *ctx, arg_depw_sar *a)
static bool trans_dep_sar(DisasContext *ctx, arg_dep_sar *a)
{
if (!ctx->is_pa20 && a->d) {
return false;
}
if (a->c) {
nullify_over(ctx);
}
return do_depw_sar(ctx, a->t, a->c, a->nz, a->clen, load_gpr(ctx, a->r));
return do_dep_sar(ctx, a->t, a->c, a->d, a->nz, a->len,
load_gpr(ctx, a->r));
}
static bool trans_depwi_sar(DisasContext *ctx, arg_depwi_sar *a)
static bool trans_depi_sar(DisasContext *ctx, arg_depi_sar *a)
{
if (!ctx->is_pa20 && a->d) {
return false;
}
if (a->c) {
nullify_over(ctx);
}
return do_depw_sar(ctx, a->t, a->c, a->nz, a->clen, tcg_constant_reg(a->i));
return do_dep_sar(ctx, a->t, a->c, a->d, a->nz, a->len,
tcg_constant_reg(a->i));
}
static bool trans_be(DisasContext *ctx, arg_be *a)