Loading target/hppa/translate.c +309 −0 Original line number Diff line number Diff line Loading @@ -1719,6 +1719,311 @@ static ExitStatus trans_movb(DisasContext *ctx, uint32_t insn, bool is_imm) return do_cbranch(ctx, disp, n, &cond); } static ExitStatus trans_shrpw_sar(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned rt = extract32(insn, 0, 5); unsigned c = extract32(insn, 13, 3); unsigned r1 = extract32(insn, 16, 5); unsigned r2 = extract32(insn, 21, 5); TCGv dest; if (c) { nullify_over(ctx); } dest = dest_gpr(ctx, rt); if (r1 == 0) { tcg_gen_ext32u_tl(dest, load_gpr(ctx, r2)); tcg_gen_shr_tl(dest, dest, cpu_sar); } else if (r1 == r2) { TCGv_i32 t32 = tcg_temp_new_i32(); tcg_gen_trunc_tl_i32(t32, load_gpr(ctx, r2)); tcg_gen_rotr_i32(t32, t32, cpu_sar); tcg_gen_extu_i32_tl(dest, t32); tcg_temp_free_i32(t32); } else { TCGv_i64 t = tcg_temp_new_i64(); TCGv_i64 s = tcg_temp_new_i64(); tcg_gen_concat_tl_i64(t, load_gpr(ctx, r2), load_gpr(ctx, r1)); tcg_gen_extu_tl_i64(s, cpu_sar); tcg_gen_shr_i64(t, t, s); tcg_gen_trunc_i64_tl(dest, t); tcg_temp_free_i64(t); tcg_temp_free_i64(s); } save_gpr(ctx, rt, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (c) { ctx->null_cond = do_sed_cond(c, dest); } return nullify_end(ctx, NO_EXIT); } static ExitStatus trans_shrpw_imm(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned rt = extract32(insn, 0, 5); unsigned cpos = extract32(insn, 5, 5); unsigned c = extract32(insn, 13, 3); unsigned r1 = extract32(insn, 16, 5); unsigned r2 = extract32(insn, 21, 5); unsigned sa = 31 - cpos; TCGv dest, t2; if (c) { nullify_over(ctx); } dest = dest_gpr(ctx, rt); t2 = load_gpr(ctx, r2); if (r1 == r2) { TCGv_i32 t32 = tcg_temp_new_i32(); tcg_gen_trunc_tl_i32(t32, t2); tcg_gen_rotri_i32(t32, t32, sa); tcg_gen_extu_i32_tl(dest, t32); tcg_temp_free_i32(t32); } else if (r1 == 0) { tcg_gen_extract_tl(dest, t2, sa, 32 - sa); } else { TCGv t0 = tcg_temp_new(); tcg_gen_extract_tl(t0, t2, sa, 32 - sa); tcg_gen_deposit_tl(dest, t0, cpu_gr[r1], 32 - sa, sa); tcg_temp_free(t0); } save_gpr(ctx, rt, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (c) { ctx->null_cond = do_sed_cond(c, dest); } return nullify_end(ctx, NO_EXIT); } static ExitStatus trans_extrw_sar(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned clen = extract32(insn, 0, 5); unsigned is_se = extract32(insn, 10, 1); unsigned c = extract32(insn, 13, 3); unsigned rt = extract32(insn, 16, 5); unsigned rr = extract32(insn, 21, 5); unsigned len = 32 - clen; TCGv dest, src, tmp; if (c) { nullify_over(ctx); } dest = dest_gpr(ctx, rt); src = load_gpr(ctx, rr); tmp = tcg_temp_new(); /* Recall that SAR is using big-endian bit numbering. */ tcg_gen_xori_tl(tmp, cpu_sar, TARGET_LONG_BITS - 1); if (is_se) { tcg_gen_sar_tl(dest, src, tmp); tcg_gen_sextract_tl(dest, dest, 0, len); } else { tcg_gen_shr_tl(dest, src, tmp); tcg_gen_extract_tl(dest, dest, 0, len); } tcg_temp_free(tmp); save_gpr(ctx, rt, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (c) { ctx->null_cond = do_sed_cond(c, dest); } return nullify_end(ctx, NO_EXIT); } static ExitStatus trans_extrw_imm(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned clen = extract32(insn, 0, 5); unsigned pos = extract32(insn, 5, 5); unsigned is_se = extract32(insn, 10, 1); unsigned c = extract32(insn, 13, 3); unsigned rt = extract32(insn, 16, 5); unsigned rr = extract32(insn, 21, 5); unsigned len = 32 - clen; unsigned cpos = 31 - pos; TCGv dest, src; if (c) { nullify_over(ctx); } dest = dest_gpr(ctx, rt); src = load_gpr(ctx, rr); if (is_se) { tcg_gen_sextract_tl(dest, src, cpos, len); } else { tcg_gen_extract_tl(dest, src, cpos, len); } save_gpr(ctx, rt, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (c) { ctx->null_cond = do_sed_cond(c, dest); } return nullify_end(ctx, NO_EXIT); } static const DisasInsn table_sh_ex[] = { { 0xd0000000u, 0xfc001fe0u, trans_shrpw_sar }, { 0xd0000800u, 0xfc001c00u, trans_shrpw_imm }, { 0xd0001000u, 0xfc001be0u, trans_extrw_sar }, { 0xd0001800u, 0xfc001800u, trans_extrw_imm }, }; static ExitStatus trans_depw_imm_c(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned clen = extract32(insn, 0, 5); unsigned cpos = extract32(insn, 5, 5); unsigned nz = extract32(insn, 10, 1); unsigned c = extract32(insn, 13, 3); target_long val = low_sextract(insn, 16, 5); unsigned rt = extract32(insn, 21, 5); unsigned len = 32 - clen; target_long mask0, mask1; TCGv dest; if (c) { nullify_over(ctx); } if (cpos + len > 32) { len = 32 - cpos; } dest = dest_gpr(ctx, rt); mask0 = deposit64(0, cpos, len, val); mask1 = deposit64(-1, cpos, len, val); if (nz) { TCGv src = load_gpr(ctx, rt); if (mask1 != -1) { tcg_gen_andi_tl(dest, src, mask1); src = dest; } tcg_gen_ori_tl(dest, src, mask0); } else { tcg_gen_movi_tl(dest, mask0); } save_gpr(ctx, rt, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (c) { ctx->null_cond = do_sed_cond(c, dest); } return nullify_end(ctx, NO_EXIT); } static ExitStatus trans_depw_imm(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned clen = extract32(insn, 0, 5); unsigned cpos = extract32(insn, 5, 5); unsigned nz = extract32(insn, 10, 1); unsigned c = extract32(insn, 13, 3); unsigned rr = extract32(insn, 16, 5); unsigned rt = extract32(insn, 21, 5); unsigned rs = nz ? rt : 0; unsigned len = 32 - clen; TCGv dest, val; if (c) { nullify_over(ctx); } if (cpos + len > 32) { len = 32 - cpos; } dest = dest_gpr(ctx, rt); val = load_gpr(ctx, rr); if (rs == 0) { tcg_gen_deposit_z_tl(dest, val, cpos, len); } else { tcg_gen_deposit_tl(dest, cpu_gr[rs], val, cpos, len); } save_gpr(ctx, rt, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (c) { ctx->null_cond = do_sed_cond(c, dest); } return nullify_end(ctx, NO_EXIT); } static ExitStatus trans_depw_sar(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned clen = extract32(insn, 0, 5); unsigned nz = extract32(insn, 10, 1); unsigned i = extract32(insn, 12, 1); unsigned c = extract32(insn, 13, 3); unsigned rt = extract32(insn, 21, 5); unsigned rs = nz ? rt : 0; unsigned len = 32 - clen; TCGv val, mask, tmp, shift, dest; unsigned msb = 1U << (len - 1); if (c) { nullify_over(ctx); } if (i) { val = load_const(ctx, low_sextract(insn, 16, 5)); } else { val = load_gpr(ctx, extract32(insn, 16, 5)); } 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_xori_tl(shift, cpu_sar, TARGET_LONG_BITS - 1); mask = tcg_const_tl(msb + (msb - 1)); tcg_gen_and_tl(tmp, val, mask); if (rs) { tcg_gen_shl_tl(mask, mask, shift); tcg_gen_shl_tl(tmp, tmp, shift); tcg_gen_andc_tl(dest, cpu_gr[rs], mask); tcg_gen_or_tl(dest, dest, tmp); } else { tcg_gen_shl_tl(dest, tmp, shift); } tcg_temp_free(shift); tcg_temp_free(mask); tcg_temp_free(tmp); save_gpr(ctx, rt, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (c) { ctx->null_cond = do_sed_cond(c, dest); } return nullify_end(ctx, NO_EXIT); } static const DisasInsn table_depw[] = { { 0xd4000000u, 0xfc000be0u, trans_depw_sar }, { 0xd4000800u, 0xfc001800u, trans_depw_imm }, { 0xd4001800u, 0xfc001800u, trans_depw_imm_c }, }; static ExitStatus trans_be(DisasContext *ctx, uint32_t insn, bool is_l) { unsigned n = extract32(insn, 1, 1); Loading Loading @@ -1874,6 +2179,10 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) return trans_movb(ctx, insn, false); case 0x33: return trans_movb(ctx, insn, true); case 0x34: return translate_table(ctx, insn, table_sh_ex); case 0x35: return translate_table(ctx, insn, table_depw); case 0x38: return trans_be(ctx, insn, false); case 0x39: Loading Loading
target/hppa/translate.c +309 −0 Original line number Diff line number Diff line Loading @@ -1719,6 +1719,311 @@ static ExitStatus trans_movb(DisasContext *ctx, uint32_t insn, bool is_imm) return do_cbranch(ctx, disp, n, &cond); } static ExitStatus trans_shrpw_sar(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned rt = extract32(insn, 0, 5); unsigned c = extract32(insn, 13, 3); unsigned r1 = extract32(insn, 16, 5); unsigned r2 = extract32(insn, 21, 5); TCGv dest; if (c) { nullify_over(ctx); } dest = dest_gpr(ctx, rt); if (r1 == 0) { tcg_gen_ext32u_tl(dest, load_gpr(ctx, r2)); tcg_gen_shr_tl(dest, dest, cpu_sar); } else if (r1 == r2) { TCGv_i32 t32 = tcg_temp_new_i32(); tcg_gen_trunc_tl_i32(t32, load_gpr(ctx, r2)); tcg_gen_rotr_i32(t32, t32, cpu_sar); tcg_gen_extu_i32_tl(dest, t32); tcg_temp_free_i32(t32); } else { TCGv_i64 t = tcg_temp_new_i64(); TCGv_i64 s = tcg_temp_new_i64(); tcg_gen_concat_tl_i64(t, load_gpr(ctx, r2), load_gpr(ctx, r1)); tcg_gen_extu_tl_i64(s, cpu_sar); tcg_gen_shr_i64(t, t, s); tcg_gen_trunc_i64_tl(dest, t); tcg_temp_free_i64(t); tcg_temp_free_i64(s); } save_gpr(ctx, rt, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (c) { ctx->null_cond = do_sed_cond(c, dest); } return nullify_end(ctx, NO_EXIT); } static ExitStatus trans_shrpw_imm(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned rt = extract32(insn, 0, 5); unsigned cpos = extract32(insn, 5, 5); unsigned c = extract32(insn, 13, 3); unsigned r1 = extract32(insn, 16, 5); unsigned r2 = extract32(insn, 21, 5); unsigned sa = 31 - cpos; TCGv dest, t2; if (c) { nullify_over(ctx); } dest = dest_gpr(ctx, rt); t2 = load_gpr(ctx, r2); if (r1 == r2) { TCGv_i32 t32 = tcg_temp_new_i32(); tcg_gen_trunc_tl_i32(t32, t2); tcg_gen_rotri_i32(t32, t32, sa); tcg_gen_extu_i32_tl(dest, t32); tcg_temp_free_i32(t32); } else if (r1 == 0) { tcg_gen_extract_tl(dest, t2, sa, 32 - sa); } else { TCGv t0 = tcg_temp_new(); tcg_gen_extract_tl(t0, t2, sa, 32 - sa); tcg_gen_deposit_tl(dest, t0, cpu_gr[r1], 32 - sa, sa); tcg_temp_free(t0); } save_gpr(ctx, rt, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (c) { ctx->null_cond = do_sed_cond(c, dest); } return nullify_end(ctx, NO_EXIT); } static ExitStatus trans_extrw_sar(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned clen = extract32(insn, 0, 5); unsigned is_se = extract32(insn, 10, 1); unsigned c = extract32(insn, 13, 3); unsigned rt = extract32(insn, 16, 5); unsigned rr = extract32(insn, 21, 5); unsigned len = 32 - clen; TCGv dest, src, tmp; if (c) { nullify_over(ctx); } dest = dest_gpr(ctx, rt); src = load_gpr(ctx, rr); tmp = tcg_temp_new(); /* Recall that SAR is using big-endian bit numbering. */ tcg_gen_xori_tl(tmp, cpu_sar, TARGET_LONG_BITS - 1); if (is_se) { tcg_gen_sar_tl(dest, src, tmp); tcg_gen_sextract_tl(dest, dest, 0, len); } else { tcg_gen_shr_tl(dest, src, tmp); tcg_gen_extract_tl(dest, dest, 0, len); } tcg_temp_free(tmp); save_gpr(ctx, rt, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (c) { ctx->null_cond = do_sed_cond(c, dest); } return nullify_end(ctx, NO_EXIT); } static ExitStatus trans_extrw_imm(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned clen = extract32(insn, 0, 5); unsigned pos = extract32(insn, 5, 5); unsigned is_se = extract32(insn, 10, 1); unsigned c = extract32(insn, 13, 3); unsigned rt = extract32(insn, 16, 5); unsigned rr = extract32(insn, 21, 5); unsigned len = 32 - clen; unsigned cpos = 31 - pos; TCGv dest, src; if (c) { nullify_over(ctx); } dest = dest_gpr(ctx, rt); src = load_gpr(ctx, rr); if (is_se) { tcg_gen_sextract_tl(dest, src, cpos, len); } else { tcg_gen_extract_tl(dest, src, cpos, len); } save_gpr(ctx, rt, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (c) { ctx->null_cond = do_sed_cond(c, dest); } return nullify_end(ctx, NO_EXIT); } static const DisasInsn table_sh_ex[] = { { 0xd0000000u, 0xfc001fe0u, trans_shrpw_sar }, { 0xd0000800u, 0xfc001c00u, trans_shrpw_imm }, { 0xd0001000u, 0xfc001be0u, trans_extrw_sar }, { 0xd0001800u, 0xfc001800u, trans_extrw_imm }, }; static ExitStatus trans_depw_imm_c(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned clen = extract32(insn, 0, 5); unsigned cpos = extract32(insn, 5, 5); unsigned nz = extract32(insn, 10, 1); unsigned c = extract32(insn, 13, 3); target_long val = low_sextract(insn, 16, 5); unsigned rt = extract32(insn, 21, 5); unsigned len = 32 - clen; target_long mask0, mask1; TCGv dest; if (c) { nullify_over(ctx); } if (cpos + len > 32) { len = 32 - cpos; } dest = dest_gpr(ctx, rt); mask0 = deposit64(0, cpos, len, val); mask1 = deposit64(-1, cpos, len, val); if (nz) { TCGv src = load_gpr(ctx, rt); if (mask1 != -1) { tcg_gen_andi_tl(dest, src, mask1); src = dest; } tcg_gen_ori_tl(dest, src, mask0); } else { tcg_gen_movi_tl(dest, mask0); } save_gpr(ctx, rt, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (c) { ctx->null_cond = do_sed_cond(c, dest); } return nullify_end(ctx, NO_EXIT); } static ExitStatus trans_depw_imm(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned clen = extract32(insn, 0, 5); unsigned cpos = extract32(insn, 5, 5); unsigned nz = extract32(insn, 10, 1); unsigned c = extract32(insn, 13, 3); unsigned rr = extract32(insn, 16, 5); unsigned rt = extract32(insn, 21, 5); unsigned rs = nz ? rt : 0; unsigned len = 32 - clen; TCGv dest, val; if (c) { nullify_over(ctx); } if (cpos + len > 32) { len = 32 - cpos; } dest = dest_gpr(ctx, rt); val = load_gpr(ctx, rr); if (rs == 0) { tcg_gen_deposit_z_tl(dest, val, cpos, len); } else { tcg_gen_deposit_tl(dest, cpu_gr[rs], val, cpos, len); } save_gpr(ctx, rt, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (c) { ctx->null_cond = do_sed_cond(c, dest); } return nullify_end(ctx, NO_EXIT); } static ExitStatus trans_depw_sar(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned clen = extract32(insn, 0, 5); unsigned nz = extract32(insn, 10, 1); unsigned i = extract32(insn, 12, 1); unsigned c = extract32(insn, 13, 3); unsigned rt = extract32(insn, 21, 5); unsigned rs = nz ? rt : 0; unsigned len = 32 - clen; TCGv val, mask, tmp, shift, dest; unsigned msb = 1U << (len - 1); if (c) { nullify_over(ctx); } if (i) { val = load_const(ctx, low_sextract(insn, 16, 5)); } else { val = load_gpr(ctx, extract32(insn, 16, 5)); } 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_xori_tl(shift, cpu_sar, TARGET_LONG_BITS - 1); mask = tcg_const_tl(msb + (msb - 1)); tcg_gen_and_tl(tmp, val, mask); if (rs) { tcg_gen_shl_tl(mask, mask, shift); tcg_gen_shl_tl(tmp, tmp, shift); tcg_gen_andc_tl(dest, cpu_gr[rs], mask); tcg_gen_or_tl(dest, dest, tmp); } else { tcg_gen_shl_tl(dest, tmp, shift); } tcg_temp_free(shift); tcg_temp_free(mask); tcg_temp_free(tmp); save_gpr(ctx, rt, dest); /* Install the new nullification. */ cond_free(&ctx->null_cond); if (c) { ctx->null_cond = do_sed_cond(c, dest); } return nullify_end(ctx, NO_EXIT); } static const DisasInsn table_depw[] = { { 0xd4000000u, 0xfc000be0u, trans_depw_sar }, { 0xd4000800u, 0xfc001800u, trans_depw_imm }, { 0xd4001800u, 0xfc001800u, trans_depw_imm_c }, }; static ExitStatus trans_be(DisasContext *ctx, uint32_t insn, bool is_l) { unsigned n = extract32(insn, 1, 1); Loading Loading @@ -1874,6 +2179,10 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) return trans_movb(ctx, insn, false); case 0x33: return trans_movb(ctx, insn, true); case 0x34: return translate_table(ctx, insn, table_sh_ex); case 0x35: return translate_table(ctx, insn, table_depw); case 0x38: return trans_be(ctx, insn, false); case 0x39: Loading