diff mbox series

[1/2] target/mips: Fix decoding mechanism of R5900 MFLO1, MFHI1, MTLO1 and MTHI1

Message ID fa2941ee17c35fba2512ab530bde3a1807d5769e.1541174426.git.noring@nocrew.org
State New
Headers show
Series target/mips: Fix decoding mechanisms of R5900 M{F, T}{HI, LO}1 and DIV[U]1 | expand

Commit Message

Fredrik Noring Nov. 2, 2018, 4:08 p.m. UTC
MFLO1, MFHI1, MTLO1 and MTHI1 are generated in gen_HILO1_tx79 instead of
the generic gen_HILO.

Signed-off-by: Fredrik Noring <noring@nocrew.org>
---
 target/mips/translate.c | 67 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 56 insertions(+), 11 deletions(-)

Comments

Philippe Mathieu-Daudé Nov. 2, 2018, 6:10 p.m. UTC | #1
On 2/11/18 17:08, Fredrik Noring wrote:
> MFLO1, MFHI1, MTLO1 and MTHI1 are generated in gen_HILO1_tx79 instead of
> the generic gen_HILO.
> 

Aleksandar, if you are OK with this patch, can you add:

Fixes: 8d927f7cb4b

> Signed-off-by: Fredrik Noring <noring@nocrew.org>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>   target/mips/translate.c | 67 ++++++++++++++++++++++++++++++++++-------
>   1 file changed, 56 insertions(+), 11 deletions(-)
> 
> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index 60320cbe69..f3993cf7d7 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -4359,24 +4359,72 @@ static void gen_shift(DisasContext *ctx, uint32_t opc,
>       tcg_temp_free(t1);
>   }
>   
> +/* Move to and from TX79 HI1/LO1 registers. */
> +static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
> +{
> +    if (reg == 0 && (opc == TX79_MMI_MFHI1 || opc == TX79_MMI_MFLO1)) {
> +        /* Treat as NOP. */
> +        return;
> +    }
> +
> +    switch (opc) {
> +    case TX79_MMI_MFHI1:
> +#if defined(TARGET_MIPS64)
> +        tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[1]);
> +#else
> +        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
> +#endif
> +        break;
> +    case TX79_MMI_MFLO1:
> +#if defined(TARGET_MIPS64)
> +        tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[1]);
> +#else
> +        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
> +#endif
> +        break;
> +    case TX79_MMI_MTHI1:
> +        if (reg != 0) {
> +#if defined(TARGET_MIPS64)
> +            tcg_gen_ext32s_tl(cpu_HI[1], cpu_gpr[reg]);
> +#else
> +            tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
> +#endif
> +        } else {
> +            tcg_gen_movi_tl(cpu_HI[1], 0);
> +        }
> +        break;
> +    case TX79_MMI_MTLO1:
> +        if (reg != 0) {
> +#if defined(TARGET_MIPS64)
> +            tcg_gen_ext32s_tl(cpu_LO[1], cpu_gpr[reg]);
> +#else
> +            tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
> +#endif
> +        } else {
> +            tcg_gen_movi_tl(cpu_LO[1], 0);
> +        }
> +        break;
> +    default:
> +        MIPS_INVAL("MFTHILO TX79");
> +        generate_exception_end(ctx, EXCP_RI);
> +        break;
> +    }
> +}
> +
>   /* Arithmetic on HI/LO registers */
>   static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
>   {
> -    if (reg == 0 && (opc == OPC_MFHI || opc == TX79_MMI_MFHI1 ||
> -                     opc == OPC_MFLO || opc == TX79_MMI_MFLO1)) {
> +    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
>           /* Treat as NOP. */
>           return;
>       }
>   
>       if (acc != 0) {
> -        if (!(ctx->insn_flags & INSN_R5900)) {
> -            check_dsp(ctx);
> -        }
> +        check_dsp(ctx);
>       }
>   
>       switch (opc) {
>       case OPC_MFHI:
> -    case TX79_MMI_MFHI1:
>   #if defined(TARGET_MIPS64)
>           if (acc != 0) {
>               tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
> @@ -4387,7 +4435,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
>           }
>           break;
>       case OPC_MFLO:
> -    case TX79_MMI_MFLO1:
>   #if defined(TARGET_MIPS64)
>           if (acc != 0) {
>               tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
> @@ -4398,7 +4445,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
>           }
>           break;
>       case OPC_MTHI:
> -    case TX79_MMI_MTHI1:
>           if (reg != 0) {
>   #if defined(TARGET_MIPS64)
>               if (acc != 0) {
> @@ -4413,7 +4459,6 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
>           }
>           break;
>       case OPC_MTLO:
> -    case TX79_MMI_MTLO1:
>           if (reg != 0) {
>   #if defined(TARGET_MIPS64)
>               if (acc != 0) {
> @@ -26500,11 +26545,11 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx)
>           break;
>       case TX79_MMI_MTLO1:
>       case TX79_MMI_MTHI1:
> -        gen_HILO(ctx, opc, 1, rs);
> +        gen_HILO1_tx79(ctx, opc, rs);
>           break;
>       case TX79_MMI_MFLO1:
>       case TX79_MMI_MFHI1:
> -        gen_HILO(ctx, opc, 1, rd);
> +        gen_HILO1_tx79(ctx, opc, rd);
>           break;
>       case TX79_MMI_MADD:          /* TODO: TX79_MMI_MADD */
>       case TX79_MMI_MADDU:         /* TODO: TX79_MMI_MADDU */
>
Richard Henderson Nov. 4, 2018, 10:15 a.m. UTC | #2
On 11/2/18 4:08 PM, Fredrik Noring wrote:
> +    switch (opc) {
> +    case TX79_MMI_MFHI1:
> +#if defined(TARGET_MIPS64)
> +        tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[1]);
> +#else
> +        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
> +#endif

You do not need this ifdef.  This is already done in tcg/tcg-op.h:

$ grep tcg_gen_ext32s_tl tcg/tcg-op.h
#define tcg_gen_ext32s_tl tcg_gen_ext32s_i64
#define tcg_gen_ext32s_tl tcg_gen_mov_i32


r~
Fredrik Noring Nov. 4, 2018, 1:12 p.m. UTC | #3
Thank you for your reviews, Philippe and Richard,

> > +    switch (opc) {
> > +    case TX79_MMI_MFHI1:
> > +#if defined(TARGET_MIPS64)
> > +        tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[1]);
> > +#else
> > +        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
> > +#endif
> 
> You do not need this ifdef.  This is already done in tcg/tcg-op.h:
> 
> $ grep tcg_gen_ext32s_tl tcg/tcg-op.h
> #define tcg_gen_ext32s_tl tcg_gen_ext32s_i64
> #define tcg_gen_ext32s_tl tcg_gen_mov_i32

It appears the correct function is tcg_gen_mov_tl because the TX79 manual
says

	MFHI:  GPR[rd]63..0 <- HI63..0
	MFLO:  GPR[rd]63..0 <- LO63..0
	MTHI:  HI63..0 <- GPR[rs]63..0
	MTLO:  LO63..0 <- GPR[rs]63..0
	MFHI1: GPR[rd]63..0 <- HI127..64
	MFLO1: GPR[rd]63..0 <- LO127..64
	MTHI1: HI127..64 <- GPR[rs]63..0
	MTLO1: LO127..64 <- GPR[rs]63..0

so the GPR is copied to/from in full in all cases. This is slightly
different to how acc = 1 is handled in gen_HILO.

Fredrik
Maciej W. Rozycki Nov. 4, 2018, 3:09 p.m. UTC | #4
On Sun, 4 Nov 2018, Fredrik Noring wrote:

> It appears the correct function is tcg_gen_mov_tl because the TX79 manual
> says
> 
> 	MFHI:  GPR[rd]63..0 <- HI63..0
> 	MFLO:  GPR[rd]63..0 <- LO63..0
> 	MTHI:  HI63..0 <- GPR[rs]63..0
> 	MTLO:  LO63..0 <- GPR[rs]63..0
> 	MFHI1: GPR[rd]63..0 <- HI127..64
> 	MFLO1: GPR[rd]63..0 <- LO127..64
> 	MTHI1: HI127..64 <- GPR[rs]63..0
> 	MTLO1: LO127..64 <- GPR[rs]63..0
> 
> so the GPR is copied to/from in full in all cases. This is slightly
> different to how acc = 1 is handled in gen_HILO.

 However `gen_HILO' looks wrong to me as it'll truncate the values of 
$acc3-$acc1 with the 64-bit DSP ASE.

  Maciej
Fredrik Noring Nov. 5, 2018, 3:40 p.m. UTC | #5
Thanks for checking this, Maciej,

[ Cc-ing Jia Liu, who added MIPS ASE DSP support in commit 4133498f8e532f
"Use correct acc value to index cpu_HI/cpu_LO rather than using a fix
number", in case there are known ISA deviations. ]

>  However `gen_HILO' looks wrong to me as it'll truncate the values of 
> $acc3-$acc1 with the 64-bit DSP ASE.

I can post a patch to fix gen_HILO. The best reference I have found so far
is "MIPS Architecture for Programmers Volume IV-e: MIPS DSP Module for
microMIPS64 Architecture"

https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00765-2B-microMIPS64DSP-AFP-03.02.pdf

that says

	MFHI: GPR[rds]63..0 <- HI[ac]63..0
	MFLO: GPR[rdt]63..0 <- LO[ac]63..0
	MTHI: HI[ac]63..0 <- GPR[rs]63..0
	MTLO: LO[ac]63..0 <- GPR[rs]63..0

where ac can range from 0 to 3. Do you have a link to a better reference,
by chance, that isn't tied to microMIPS?

Fredrik
Maciej W. Rozycki Nov. 5, 2018, 4:06 p.m. UTC | #6
On Mon, 5 Nov 2018, Fredrik Noring wrote:

> where ac can range from 0 to 3. Do you have a link to a better reference,
> by chance, that isn't tied to microMIPS?

 Here: <https://www.mips.com/downloads/> you'll find everything you need I 
believe.

 HTH,

  Maciej
diff mbox series

Patch

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 60320cbe69..f3993cf7d7 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -4359,24 +4359,72 @@  static void gen_shift(DisasContext *ctx, uint32_t opc,
     tcg_temp_free(t1);
 }
 
+/* Move to and from TX79 HI1/LO1 registers. */
+static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
+{
+    if (reg == 0 && (opc == TX79_MMI_MFHI1 || opc == TX79_MMI_MFLO1)) {
+        /* Treat as NOP. */
+        return;
+    }
+
+    switch (opc) {
+    case TX79_MMI_MFHI1:
+#if defined(TARGET_MIPS64)
+        tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[1]);
+#else
+        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
+#endif
+        break;
+    case TX79_MMI_MFLO1:
+#if defined(TARGET_MIPS64)
+        tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[1]);
+#else
+        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
+#endif
+        break;
+    case TX79_MMI_MTHI1:
+        if (reg != 0) {
+#if defined(TARGET_MIPS64)
+            tcg_gen_ext32s_tl(cpu_HI[1], cpu_gpr[reg]);
+#else
+            tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
+#endif
+        } else {
+            tcg_gen_movi_tl(cpu_HI[1], 0);
+        }
+        break;
+    case TX79_MMI_MTLO1:
+        if (reg != 0) {
+#if defined(TARGET_MIPS64)
+            tcg_gen_ext32s_tl(cpu_LO[1], cpu_gpr[reg]);
+#else
+            tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
+#endif
+        } else {
+            tcg_gen_movi_tl(cpu_LO[1], 0);
+        }
+        break;
+    default:
+        MIPS_INVAL("MFTHILO TX79");
+        generate_exception_end(ctx, EXCP_RI);
+        break;
+    }
+}
+
 /* Arithmetic on HI/LO registers */
 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
 {
-    if (reg == 0 && (opc == OPC_MFHI || opc == TX79_MMI_MFHI1 ||
-                     opc == OPC_MFLO || opc == TX79_MMI_MFLO1)) {
+    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
         /* Treat as NOP. */
         return;
     }
 
     if (acc != 0) {
-        if (!(ctx->insn_flags & INSN_R5900)) {
-            check_dsp(ctx);
-        }
+        check_dsp(ctx);
     }
 
     switch (opc) {
     case OPC_MFHI:
-    case TX79_MMI_MFHI1:
 #if defined(TARGET_MIPS64)
         if (acc != 0) {
             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
@@ -4387,7 +4435,6 @@  static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
         }
         break;
     case OPC_MFLO:
-    case TX79_MMI_MFLO1:
 #if defined(TARGET_MIPS64)
         if (acc != 0) {
             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
@@ -4398,7 +4445,6 @@  static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
         }
         break;
     case OPC_MTHI:
-    case TX79_MMI_MTHI1:
         if (reg != 0) {
 #if defined(TARGET_MIPS64)
             if (acc != 0) {
@@ -4413,7 +4459,6 @@  static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
         }
         break;
     case OPC_MTLO:
-    case TX79_MMI_MTLO1:
         if (reg != 0) {
 #if defined(TARGET_MIPS64)
             if (acc != 0) {
@@ -26500,11 +26545,11 @@  static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx)
         break;
     case TX79_MMI_MTLO1:
     case TX79_MMI_MTHI1:
-        gen_HILO(ctx, opc, 1, rs);
+        gen_HILO1_tx79(ctx, opc, rs);
         break;
     case TX79_MMI_MFLO1:
     case TX79_MMI_MFHI1:
-        gen_HILO(ctx, opc, 1, rd);
+        gen_HILO1_tx79(ctx, opc, rd);
         break;
     case TX79_MMI_MADD:          /* TODO: TX79_MMI_MADD */
     case TX79_MMI_MADDU:         /* TODO: TX79_MMI_MADDU */