@@ -2619,59 +2619,63 @@ static bool trans_and(DisasContext *ctx, arg_rrr_cf *a)
return do_log_reg(ctx, a, tcg_gen_and_reg);
}
+static bool trans_copy(DisasContext *ctx, arg_copy *a)
+{
+ unsigned r = a->r;
+ unsigned t = a->t;
+
+ if (r == 0) {
+ TCGv_reg dest = dest_gpr(ctx, t);
+ tcg_gen_movi_reg(dest, 0);
+ save_gpr(ctx, t, dest);
+ } else {
+ save_gpr(ctx, t, cpu_gr[r]);
+ }
+ cond_free(&ctx->null_cond);
+ return true;
+}
+
+static bool trans_pause(DisasContext *ctx, arg_pause *a)
+{
+#ifndef CONFIG_USER_ONLY
+ /*
+ * These are QEMU extensions and are nops in the real architecture:
+ *
+ * or %r10,%r10,%r10 -- idle loop; wait for interrupt
+ * or %r31,%r31,%r31 -- death loop; offline cpu
+ * currently implemented as idle.
+ */
+ TCGv_i32 tmp;
+
+ /*
+ * No need to check for supervisor, as userland can only pause
+ * until the next timer interrupt.
+ */
+ nullify_over(ctx);
+
+ /* Advance the instruction queue. */
+ copy_iaoq_entry(cpu_iaoq_f, ctx->iaoq_b, cpu_iaoq_b);
+ copy_iaoq_entry(cpu_iaoq_b, ctx->iaoq_n, ctx->iaoq_n_var);
+ nullify_set(ctx, 0);
+
+ /* Tell the qemu main loop to halt until this cpu has work. */
+ tmp = tcg_const_i32(1);
+ tcg_gen_st_i32(tmp, cpu_env, -offsetof(HPPACPU, env) +
+ offsetof(CPUState, halted));
+ tcg_temp_free_i32(tmp);
+ gen_excp_1(EXCP_HALTED);
+ ctx->base.is_jmp = DISAS_NORETURN;
+
+ return nullify_end(ctx);
+#else
+ /* For user-only, don't pause but treat as nop. */
+ cond_free(&ctx->null_cond);
+ return true;
+#endif
+}
+
static bool trans_or(DisasContext *ctx, arg_rrr_cf *a)
{
- if (a->cf == 0) {
- unsigned r2 = a->r2;
- unsigned r1 = a->r1;
- unsigned rt = a->t;
-
- if (rt == 0) { /* NOP */
- cond_free(&ctx->null_cond);
- return true;
- }
- if (r2 == 0) { /* COPY */
- if (r1 == 0) {
- TCGv_reg dest = dest_gpr(ctx, rt);
- tcg_gen_movi_reg(dest, 0);
- save_gpr(ctx, rt, dest);
- } else {
- save_gpr(ctx, rt, cpu_gr[r1]);
- }
- cond_free(&ctx->null_cond);
- return true;
- }
-#ifndef CONFIG_USER_ONLY
- /* These are QEMU extensions and are nops in the real architecture:
- *
- * or %r10,%r10,%r10 -- idle loop; wait for interrupt
- * or %r31,%r31,%r31 -- death loop; offline cpu
- * currently implemented as idle.
- */
- if ((rt == 10 || rt == 31) && r1 == rt && r2 == rt) { /* PAUSE */
- TCGv_i32 tmp;
-
- /* No need to check for supervisor, as userland can only pause
- until the next timer interrupt. */
- nullify_over(ctx);
-
- /* Advance the instruction queue. */
- copy_iaoq_entry(cpu_iaoq_f, ctx->iaoq_b, cpu_iaoq_b);
- copy_iaoq_entry(cpu_iaoq_b, ctx->iaoq_n, ctx->iaoq_n_var);
- nullify_set(ctx, 0);
-
- /* Tell the qemu main loop to halt until this cpu has work. */
- tmp = tcg_const_i32(1);
- tcg_gen_st_i32(tmp, cpu_env, -offsetof(HPPACPU, env) +
- offsetof(CPUState, halted));
- tcg_temp_free_i32(tmp);
- gen_excp_1(EXCP_HALTED);
- ctx->base.is_jmp = DISAS_NORETURN;
-
- return nullify_end(ctx);
- }
-#endif
- }
return do_log_reg(ctx, a, tcg_gen_or_reg);
}
@@ -148,7 +148,15 @@ lci 000001 ----- ----- -- 01001100 0 t:5
andcm 000010 ..... ..... .... 000000 0 ..... @rrr_cf
and 000010 ..... ..... .... 001000 0 ..... @rrr_cf
-or 000010 ..... ..... .... 001001 0 ..... @rrr_cf
+{
+ {
+ nop 000010 ----- ----- 0000 001001 0 00000
+ copy 000010 00000 r:5 0000 001001 0 t:5
+ pause 000010 01010 01010 0000 001001 0 01010
+ pause 000010 11111 11111 0000 001001 0 11111
+ }
+ or 000010 ..... ..... .... 001001 0 ..... @rrr_cf
+}
xor 000010 ..... ..... .... 001010 0 ..... @rrr_cf
uxor 000010 ..... ..... .... 001110 0 ..... @rrr_cf
ds 000010 ..... ..... .... 010001 0 ..... @rrr_cf
It seems clearer to decode specializations of OR within decodetree instead of by hand within the translation function. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/hppa/translate.c | 106 ++++++++++++++++++++------------------- target/hppa/insns.decode | 10 +++- 2 files changed, 64 insertions(+), 52 deletions(-) -- 2.17.2