Patchwork target-mips: fix mips16 MULT/DIV (broken by ASE_DSP)

login
register
mail settings
Submitter Leon Yu
Date Feb. 20, 2013, 4:57 a.m.
Message ID <1361336255-7464-1-git-send-email-chianglungyu@gmail.com>
Download mbox | patch
Permalink /patch/221972/
State New
Headers show

Comments

Leon Yu - Feb. 20, 2013, 4:57 a.m.
using bit[11-12] of opcode as acc is not correct for ASE_MIPS16 instructions.
doing so generates RI/DSPDIS exception when decoding MIPS16 MULT/DIV.

Signed-off-by: Leon Yu <chianglungyu@gmail.com>
---
 target-mips/translate.c |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)
Aurelien Jarno - March 5, 2013, 12:08 a.m.
On Wed, Feb 20, 2013 at 12:57:35PM +0800, Leon Yu wrote:
> using bit[11-12] of opcode as acc is not correct for ASE_MIPS16 instructions.
> doing so generates RI/DSPDIS exception when decoding MIPS16 MULT/DIV.
> 
> Signed-off-by: Leon Yu <chianglungyu@gmail.com>
> ---
>  target-mips/translate.c |   14 +++++++-------
>  1 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 4ee9615..c5834cd 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -2594,7 +2594,7 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
>      }
>  
>      if (opc == OPC_MFHI || opc == OPC_MFLO) {
> -        acc = ((ctx->opcode) >> 21) & 0x03;
> +        acc = (ctx->hflags & MIPS_HFLAG_M16) ? 0 : ((ctx->opcode) >> 21) & 0x03;
>      } else {
>          acc = ((ctx->opcode) >> 11) & 0x03;
>      }
> @@ -2717,7 +2717,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
>          {
>              TCGv_i64 t2 = tcg_temp_new_i64();
>              TCGv_i64 t3 = tcg_temp_new_i64();
> -            acc = ((ctx->opcode) >> 11) & 0x03;
> +            acc = (ctx->hflags & MIPS_HFLAG_M16) ? 0 : ((ctx->opcode) >> 11) & 0x03;
>              if (acc != 0) {
>                  check_dsp(ctx);
>              }
> @@ -2739,7 +2739,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
>          {
>              TCGv_i64 t2 = tcg_temp_new_i64();
>              TCGv_i64 t3 = tcg_temp_new_i64();
> -            acc = ((ctx->opcode) >> 11) & 0x03;
> +            acc = (ctx->hflags & MIPS_HFLAG_M16) ? 0 : ((ctx->opcode) >> 11) & 0x03;
>              if (acc != 0) {
>                  check_dsp(ctx);
>              }
> @@ -2803,7 +2803,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
>          {
>              TCGv_i64 t2 = tcg_temp_new_i64();
>              TCGv_i64 t3 = tcg_temp_new_i64();
> -            acc = ((ctx->opcode) >> 11) & 0x03;
> +            acc = (ctx->hflags & MIPS_HFLAG_M16) ? 0 : ((ctx->opcode) >> 11) & 0x03;
>              if (acc != 0) {
>                  check_dsp(ctx);
>              }
> @@ -2827,7 +2827,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
>          {
>              TCGv_i64 t2 = tcg_temp_new_i64();
>              TCGv_i64 t3 = tcg_temp_new_i64();
> -            acc = ((ctx->opcode) >> 11) & 0x03;
> +            acc = (ctx->hflags & MIPS_HFLAG_M16) ? 0 : ((ctx->opcode) >> 11) & 0x03;
>              if (acc != 0) {
>                  check_dsp(ctx);
>              }
> @@ -2853,7 +2853,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
>          {
>              TCGv_i64 t2 = tcg_temp_new_i64();
>              TCGv_i64 t3 = tcg_temp_new_i64();
> -            acc = ((ctx->opcode) >> 11) & 0x03;
> +            acc = (ctx->hflags & MIPS_HFLAG_M16) ? 0 : ((ctx->opcode) >> 11) & 0x03;
>              if (acc != 0) {
>                  check_dsp(ctx);
>              }
> @@ -2877,7 +2877,7 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
>          {
>              TCGv_i64 t2 = tcg_temp_new_i64();
>              TCGv_i64 t3 = tcg_temp_new_i64();
> -            acc = ((ctx->opcode) >> 11) & 0x03;
> +            acc = (ctx->hflags & MIPS_HFLAG_M16) ? 0 : ((ctx->opcode) >> 11) & 0x03;
>              if (acc != 0) {
>                  check_dsp(ctx);
>              }

Thanks for your patch. However I have applied a patch from Richard
Sandiford instead, which does the same as yours, but also fixes
micromips.

Patch

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 4ee9615..c5834cd 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -2594,7 +2594,7 @@  static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
     }
 
     if (opc == OPC_MFHI || opc == OPC_MFLO) {
-        acc = ((ctx->opcode) >> 21) & 0x03;
+        acc = (ctx->hflags & MIPS_HFLAG_M16) ? 0 : ((ctx->opcode) >> 21) & 0x03;
     } else {
         acc = ((ctx->opcode) >> 11) & 0x03;
     }
@@ -2717,7 +2717,7 @@  static void gen_muldiv (DisasContext *ctx, uint32_t opc,
         {
             TCGv_i64 t2 = tcg_temp_new_i64();
             TCGv_i64 t3 = tcg_temp_new_i64();
-            acc = ((ctx->opcode) >> 11) & 0x03;
+            acc = (ctx->hflags & MIPS_HFLAG_M16) ? 0 : ((ctx->opcode) >> 11) & 0x03;
             if (acc != 0) {
                 check_dsp(ctx);
             }
@@ -2739,7 +2739,7 @@  static void gen_muldiv (DisasContext *ctx, uint32_t opc,
         {
             TCGv_i64 t2 = tcg_temp_new_i64();
             TCGv_i64 t3 = tcg_temp_new_i64();
-            acc = ((ctx->opcode) >> 11) & 0x03;
+            acc = (ctx->hflags & MIPS_HFLAG_M16) ? 0 : ((ctx->opcode) >> 11) & 0x03;
             if (acc != 0) {
                 check_dsp(ctx);
             }
@@ -2803,7 +2803,7 @@  static void gen_muldiv (DisasContext *ctx, uint32_t opc,
         {
             TCGv_i64 t2 = tcg_temp_new_i64();
             TCGv_i64 t3 = tcg_temp_new_i64();
-            acc = ((ctx->opcode) >> 11) & 0x03;
+            acc = (ctx->hflags & MIPS_HFLAG_M16) ? 0 : ((ctx->opcode) >> 11) & 0x03;
             if (acc != 0) {
                 check_dsp(ctx);
             }
@@ -2827,7 +2827,7 @@  static void gen_muldiv (DisasContext *ctx, uint32_t opc,
         {
             TCGv_i64 t2 = tcg_temp_new_i64();
             TCGv_i64 t3 = tcg_temp_new_i64();
-            acc = ((ctx->opcode) >> 11) & 0x03;
+            acc = (ctx->hflags & MIPS_HFLAG_M16) ? 0 : ((ctx->opcode) >> 11) & 0x03;
             if (acc != 0) {
                 check_dsp(ctx);
             }
@@ -2853,7 +2853,7 @@  static void gen_muldiv (DisasContext *ctx, uint32_t opc,
         {
             TCGv_i64 t2 = tcg_temp_new_i64();
             TCGv_i64 t3 = tcg_temp_new_i64();
-            acc = ((ctx->opcode) >> 11) & 0x03;
+            acc = (ctx->hflags & MIPS_HFLAG_M16) ? 0 : ((ctx->opcode) >> 11) & 0x03;
             if (acc != 0) {
                 check_dsp(ctx);
             }
@@ -2877,7 +2877,7 @@  static void gen_muldiv (DisasContext *ctx, uint32_t opc,
         {
             TCGv_i64 t2 = tcg_temp_new_i64();
             TCGv_i64 t3 = tcg_temp_new_i64();
-            acc = ((ctx->opcode) >> 11) & 0x03;
+            acc = (ctx->hflags & MIPS_HFLAG_M16) ? 0 : ((ctx->opcode) >> 11) & 0x03;
             if (acc != 0) {
                 check_dsp(ctx);
             }