[Qemu-devel] [PATCH 05/19] target/hppa: Unify specializations of OR

2019-02-07 Thread Richard Henderson
With decodetree.py, the specializations would conflict so we
must have a single entry point for all variants of OR.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 108 ++--
 1 file changed, 59 insertions(+), 49 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 2ca0f5da10..6c2f560fc1 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2622,21 +2622,69 @@ static bool trans_log(DisasContext *ctx, uint32_t insn, 
const DisasInsn *di)
 return nullify_end(ctx);
 }
 
-/* OR r,0,t -> COPY (according to gas) */
-static bool trans_copy(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static bool trans_or(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
 {
+unsigned r2 = extract32(insn, 21, 5);
 unsigned r1 = extract32(insn, 16, 5);
+unsigned cf = extract32(insn, 12, 4);
 unsigned rt = extract32(insn,  0, 5);
+TCGv_reg tcg_r1, tcg_r2;
 
-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]);
+if (cf == 0) {
+if (rt == 0) { /* NOP */
+cond_free(>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(>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
 }
-cond_free(>null_cond);
-return true;
+
+if (cf) {
+nullify_over(ctx);
+}
+tcg_r1 = load_gpr(ctx, r1);
+tcg_r2 = load_gpr(ctx, r2);
+do_log(ctx, rt, tcg_r1, tcg_r2, cf, tcg_gen_or_reg);
+return nullify_end(ctx);
 }
 
 static bool trans_cmpclr(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
@@ -2781,48 +2829,10 @@ static bool trans_ds(DisasContext *ctx, uint32_t insn, 
const DisasInsn *di)
 return nullify_end(ctx);
 }
 
-#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.
- */
-static bool trans_pause(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
-{
-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
-
 static const DisasInsn table_arith_log[] = {
-{ 0x08000240u, 0xfc00u, trans_nop },  /* or x,y,0 */
-{ 0x08000240u, 0xffe0ffe0u, trans_copy }, /* or x,0,t */
-#ifndef CONFIG_USER_ONLY
-{ 0x094a024au, 0xu, trans_pause }, /* or r10,r10,r10 */
-{ 0x0bff025fu, 0xu, trans_pause }, /* or r31,r31,r31 */
-#endif
+{ 0x08000240u, 0xfc000fe0u, trans_or },
 { 0x0800u, 0xfc000fe0u, trans_log, .f.ttt = tcg_gen_andc_reg },
 { 0x08000200u, 0xfc000fe0u, trans_log, .f.ttt = tcg_gen_and_reg },
-{ 0x08000240u, 

Re: [Qemu-devel] [PATCH 05/19] target/hppa: Unify specializations of OR

2018-04-06 Thread Bastian Koppelmann
On 02/17/2018 09:31 PM, Richard Henderson wrote:
> With decodetree.py, the specializations would conflict so we
> must have a single entry point for all variants of OR.
> 
> Signed-off-by: Richard Henderson 
> ---
>  target/hppa/translate.c | 108 
> +++-
>  1 file changed, 60 insertions(+), 48 deletions(-)
> 

Reviewed-by: Bastian Koppelmann 

Cheers,
Bastian





[Qemu-devel] [PATCH 05/19] target/hppa: Unify specializations of OR

2018-02-17 Thread Richard Henderson
With decodetree.py, the specializations would conflict so we
must have a single entry point for all variants of OR.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 108 +++-
 1 file changed, 60 insertions(+), 48 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index ae5969be0b..074234b1e0 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -2634,20 +2634,70 @@ static void trans_log(DisasContext *ctx, uint32_t insn, 
const DisasInsn *di)
 nullify_end(ctx);
 }
 
-/* OR r,0,t -> COPY (according to gas) */
-static void trans_copy(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
+static void trans_or(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
 {
+unsigned r2 = extract32(insn, 21, 5);
 unsigned r1 = extract32(insn, 16, 5);
+unsigned cf = extract32(insn, 12, 4);
 unsigned rt = extract32(insn,  0, 5);
+TCGv_reg tcg_r1, tcg_r2;
 
-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]);
+if (cf == 0) {
+if (rt == 0) { /* NOP */
+cond_free(>null_cond);
+return;
+}
+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(>null_cond);
+return;
+}
+#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;
+
+nullify_end(ctx);
+return;
+}
+#endif
 }
-cond_free(>null_cond);
+
+if (cf) {
+nullify_over(ctx);
+}
+tcg_r1 = load_gpr(ctx, r1);
+tcg_r2 = load_gpr(ctx, r2);
+do_log(ctx, rt, tcg_r1, tcg_r2, cf, tcg_gen_or_reg);
+nullify_end(ctx);
 }
 
 static void trans_cmpclr(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
@@ -2792,48 +2842,10 @@ static void trans_ds(DisasContext *ctx, uint32_t insn, 
const DisasInsn *di)
 nullify_end(ctx);
 }
 
-#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.
- */
-static void trans_pause(DisasContext *ctx, uint32_t insn, const DisasInsn *di)
-{
-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;
-
-nullify_end(ctx);
-}
-#endif
-
 static const DisasInsn table_arith_log[] = {
-{ 0x08000240u, 0xfc00u, trans_nop },  /* or x,y,0 */
-{ 0x08000240u, 0xffe0ffe0u, trans_copy }, /* or x,0,t */
-#ifndef CONFIG_USER_ONLY
-{ 0x094a024au, 0xu, trans_pause }, /* or r10,r10,r10 */
-{ 0x0bff025fu, 0xu, trans_pause }, /* or r31,r31,r31 */
-#endif
+{ 0x08000240u, 0xfc000fe0u, trans_or },
 { 0x0800u, 0xfc000fe0u, trans_log, .f.ttt = tcg_gen_andc_reg },
 { 0x08000200u, 0xfc000fe0u, trans_log, .f.ttt = tcg_gen_and_reg },
-{ 0x08000240u,