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.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 842f74ea5b..6499b392f9 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2380,21 +2380,33 @@ static DisasJumpType trans_probe(DisasContext *ctx, uint32_t insn,
{
unsigned rt = extract32(insn, 0, 5);
unsigned sp = extract32(insn, 14, 2);
+ unsigned rr = extract32(insn, 16, 5);
unsigned rb = extract32(insn, 21, 5);
unsigned is_write = extract32(insn, 6, 1);
+ unsigned is_imm = extract32(insn, 13, 1);
TCGv_reg dest, ofs;
+ TCGv_i32 level, want;
TCGv_tl addr;
nullify_over(ctx);
- /* ??? Do something with priv level operand. */
dest = dest_gpr(ctx, rt);
form_gva(ctx, &addr, &ofs, rb, 0, 0, 0, sp, 0, false);
- if (is_write) {
- gen_helper_probe_w(dest, addr);
+
+ if (is_imm) {
+ level = tcg_const_i32(extract32(insn, 16, 2));
} else {
- gen_helper_probe_r(dest, addr);
+ level = tcg_temp_new_i32();
+ tcg_gen_trunc_reg_i32(level, load_gpr(ctx, rr));
+ tcg_gen_andi_i32(level, level, 3);
}
+ want = tcg_const_i32(is_write ? PAGE_WRITE : PAGE_READ);
+
+ gen_helper_probe(dest, cpu_env, addr, level, want);
+
+ tcg_temp_free_i32(want);
+ tcg_temp_free_i32(level);
+
save_gpr(ctx, rt, dest);
return nullify_end(ctx, DISAS_NEXT);
}