target/hppa: Implement DEPD, DEPDI
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
51416c4e41
commit
72ae4f2b82
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user