aboutsummaryrefslogtreecommitdiff
path: root/target/hppa/translate.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/hppa/translate.c')
-rw-r--r--target/hppa/translate.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 0d0d1bc..853cba2 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -20,7 +20,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "qemu/host-utils.h"
-#include "exec/exec-all.h"
#include "exec/page-protection.h"
#include "tcg/tcg-op.h"
#include "tcg/tcg-op-gvec.h"
@@ -28,6 +27,7 @@
#include "exec/helper-gen.h"
#include "exec/translator.h"
#include "exec/translation-block.h"
+#include "exec/target_page.h"
#include "exec/log.h"
#define HELPER_H "helper.h"
@@ -104,6 +104,12 @@ typedef struct DisasContext {
#define MMU_DISABLED(C) MMU_IDX_MMU_DISABLED((C)->mmu_idx)
#endif
+static inline MemOp mo_endian(DisasContext *ctx)
+{
+ /* The PSW_E bit sets the (little) endianness, but we don't implement it. */
+ return MO_BE;
+}
+
/* Note that ssm/rsm instructions number PSW_W and PSW_E differently. */
static int expand_sm_imm(DisasContext *ctx, int val)
{
@@ -1208,10 +1214,10 @@ static void do_add(DisasContext *ctx, unsigned rt, TCGv_i64 orig_in1,
cb_msb = tcg_temp_new_i64();
cb = tcg_temp_new_i64();
- tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero, in2, ctx->zero);
if (is_c) {
- tcg_gen_add2_i64(dest, cb_msb, dest, cb_msb,
- get_psw_carry(ctx, d), ctx->zero);
+ tcg_gen_addcio_i64(dest, cb_msb, in1, in2, get_psw_carry(ctx, d));
+ } else {
+ tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero, in2, ctx->zero);
}
tcg_gen_xor_i64(cb, in1, in2);
tcg_gen_xor_i64(cb, cb, dest);
@@ -1307,9 +1313,7 @@ static void do_sub(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
if (is_b) {
/* DEST,C = IN1 + ~IN2 + C. */
tcg_gen_not_i64(cb, in2);
- tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero,
- get_psw_carry(ctx, d), ctx->zero);
- tcg_gen_add2_i64(dest, cb_msb, dest, cb_msb, cb, ctx->zero);
+ tcg_gen_addcio_i64(dest, cb_msb, in1, cb, get_psw_carry(ctx, d));
tcg_gen_xor_i64(cb, cb, in1);
tcg_gen_xor_i64(cb, cb, dest);
} else {
@@ -1601,6 +1605,7 @@ static void do_load_32(DisasContext *ctx, TCGv_i32 dest, unsigned rb,
/* Caller uses nullify_over/nullify_end. */
assert(ctx->null_cond.c == TCG_COND_NEVER);
+ mop |= mo_endian(ctx);
form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
MMU_DISABLED(ctx));
tcg_gen_qemu_ld_i32(dest, addr, ctx->mmu_idx, mop | UNALIGN(ctx));
@@ -1619,6 +1624,7 @@ static void do_load_64(DisasContext *ctx, TCGv_i64 dest, unsigned rb,
/* Caller uses nullify_over/nullify_end. */
assert(ctx->null_cond.c == TCG_COND_NEVER);
+ mop |= mo_endian(ctx);
form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
MMU_DISABLED(ctx));
tcg_gen_qemu_ld_i64(dest, addr, ctx->mmu_idx, mop | UNALIGN(ctx));
@@ -1637,6 +1643,7 @@ static void do_store_32(DisasContext *ctx, TCGv_i32 src, unsigned rb,
/* Caller uses nullify_over/nullify_end. */
assert(ctx->null_cond.c == TCG_COND_NEVER);
+ mop |= mo_endian(ctx);
form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
MMU_DISABLED(ctx));
tcg_gen_qemu_st_i32(src, addr, ctx->mmu_idx, mop | UNALIGN(ctx));
@@ -1655,6 +1662,7 @@ static void do_store_64(DisasContext *ctx, TCGv_i64 src, unsigned rb,
/* Caller uses nullify_over/nullify_end. */
assert(ctx->null_cond.c == TCG_COND_NEVER);
+ mop |= mo_endian(ctx);
form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
MMU_DISABLED(ctx));
tcg_gen_qemu_st_i64(src, addr, ctx->mmu_idx, mop | UNALIGN(ctx));
@@ -1693,7 +1701,7 @@ static bool do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
nullify_over(ctx);
tmp = tcg_temp_new_i32();
- do_load_32(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEUL);
+ do_load_32(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_UL);
save_frw_i32(rt, tmp);
if (rt == 0) {
@@ -1718,7 +1726,7 @@ static bool do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
nullify_over(ctx);
tmp = tcg_temp_new_i64();
- do_load_64(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEUQ);
+ do_load_64(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_UQ);
save_frd(rt, tmp);
if (rt == 0) {
@@ -1752,7 +1760,7 @@ static bool do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
nullify_over(ctx);
tmp = load_frw_i32(rt);
- do_store_32(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEUL);
+ do_store_32(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_UL);
return nullify_end(ctx);
}
@@ -1772,7 +1780,7 @@ static bool do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
nullify_over(ctx);
tmp = load_frd(rt);
- do_store_64(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEUQ);
+ do_store_64(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_UQ);
return nullify_end(ctx);
}
@@ -3007,9 +3015,7 @@ static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
tcg_gen_xor_i64(add2, in2, addc);
tcg_gen_andi_i64(addc, addc, 1);
- tcg_gen_add2_i64(dest, cpu_psw_cb_msb, add1, ctx->zero, add2, ctx->zero);
- tcg_gen_add2_i64(dest, cpu_psw_cb_msb, dest, cpu_psw_cb_msb,
- addc, ctx->zero);
+ tcg_gen_addcio_i64(dest, cpu_psw_cb_msb, add1, add2, addc);
/* Write back the result register. */
save_gpr(ctx, a->t, dest);
@@ -3306,7 +3312,7 @@ static bool trans_ld(DisasContext *ctx, arg_ldst *a)
return gen_illegal(ctx);
}
return do_load(ctx, a->t, a->b, a->x, a->scale ? a->size : 0,
- a->disp, a->sp, a->m, a->size | MO_TE);
+ a->disp, a->sp, a->m, a->size);
}
static bool trans_st(DisasContext *ctx, arg_ldst *a)
@@ -3315,12 +3321,12 @@ static bool trans_st(DisasContext *ctx, arg_ldst *a)
if (!ctx->is_pa20 && a->size > MO_32) {
return gen_illegal(ctx);
}
- return do_store(ctx, a->t, a->b, a->disp, a->sp, a->m, a->size | MO_TE);
+ return do_store(ctx, a->t, a->b, a->disp, a->sp, a->m, a->size);
}
static bool trans_ldc(DisasContext *ctx, arg_ldst *a)
{
- MemOp mop = MO_TE | MO_ALIGN | a->size;
+ MemOp mop = mo_endian(ctx) | MO_ALIGN | a->size;
TCGv_i64 dest, ofs;
TCGv_i64 addr;
@@ -3552,8 +3558,7 @@ static bool do_addb(DisasContext *ctx, unsigned r, TCGv_i64 in1,
TCGv_i64 cb = tcg_temp_new_i64();
TCGv_i64 cb_msb = tcg_temp_new_i64();
- tcg_gen_movi_i64(cb_msb, 0);
- tcg_gen_add2_i64(dest, cb_msb, in1, cb_msb, in2, cb_msb);
+ tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero, in2, ctx->zero);
tcg_gen_xor_i64(cb, in1, in2);
tcg_gen_xor_i64(cb, cb, dest);
cb_cond = get_carry(ctx, d, cb, cb_msb);