diff mbox series

[v2,08/33] target/mips: Add emulation of nanoMIPS FP instructions

Message ID 1531169431-10772-9-git-send-email-aleksandar.markovic@rt-rk.com
State New
Headers show
Series Add nanoMIPS support to QEMU | expand

Commit Message

Aleksandar Markovic July 9, 2018, 8:50 p.m. UTC
From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of basic floating point arithmetic for nanoMIPS.

Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 300 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 300 insertions(+)

Comments

Aleksandar Markovic July 10, 2018, 1:52 p.m. UTC | #1
> Subject: [PATCH v2 08/33] target/mips: Add emulation of nanoMIPS FP instructions
>
> From: Yongbok Kim <yongbok.kim@mips.com>
>
> Add emulation of basic floating point arithmetic for nanoMIPS.
>
> Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> ---
>  target/mips/translate.c | 300 ++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 300 insertions(+)
>
> diff --git a/target/mips/translate.c b/target/mips/translate.c

For future cleanups, the code should be organized so that there is one-to-one correspondence between functions (in the code) and instruction pools (as they are defined in the documentation).

Also, opcode/register extraction should be consistent, as mentioned in other reviewer comments.

That said, for the present development stage:

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

> index ae46de2..176d51d 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -16447,6 +16447,305 @@ static void gen_pool16c_nanomips_insn(DisasContext *ctx)
>      }
>  }
>
> +static void gen_pool32f_nanomips_insn(DisasContext *ctx)
> +{
> +    int rt, rs, rd;
> +
> +    rt = (ctx->opcode >> 21) & 0x1f;
> +    rs = (ctx->opcode >> 16) & 0x1f;
> +    rd = (ctx->opcode >> 11) & 0x1f;
> +
> +    if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
> +        generate_exception_end(ctx, EXCP_RI);
> +        return;
> +    }
> +    check_cp1_enabled(ctx);
> +    switch (ctx->opcode & 0x07) {
> +    case NM_POOL32F_0:
> +        switch ((ctx->opcode >> 3) & 0x7f) {
> +        case NM_RINT_S:
> +            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
> +            break;
> +        case NM_RINT_D:
> +            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
> +            break;
> +        case NM_CLASS_S:
> +            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
> +            break;
> +        case NM_CLASS_D:
> +            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
> +            break;
> +        case NM_ADD_S:
> +            gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
> +            break;
> +        case NM_ADD_D:
> +            gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
> +            break;
> +        case NM_SUB_S:
> +            gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
> +            break;
> +        case NM_SUB_D:
> +            gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
> +            break;
> +        case NM_MUL_S:
> +            gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
> +            break;
> +        case NM_MUL_D:
> +            gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
> +            break;
> +        case NM_DIV_S:
> +            gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
> +            break;
> +        case NM_DIV_D:
> +            gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
> +            break;
> +        case NM_SELEQZ_S:
> +            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
> +            break;
> +        case NM_SELEQZ_D:
> +            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
> +            break;
> +        case NM_SELNEZ_S:
> +            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
> +            break;
> +        case NM_SELNEZ_D:
> +            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
> +            break;
> +        case NM_SEL_S:
> +            gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
> +            break;
> +        case NM_SEL_D:
> +            gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
> +            break;
> +        case NM_MADDF_S:
> +            gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
> +            break;
> +        case NM_MADDF_D:
> +            gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
> +            break;
> +        case NM_MSUBF_S:
> +            gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
> +            break;
> +        case NM_MSUBF_D:
> +            gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
> +            break;
> +        default:
> +            generate_exception_end(ctx, EXCP_RI);
> +            break;
> +        }
> +        break;
> +    case NM_POOL32F_3:
> +        switch ((ctx->opcode >> 3) & 0x07) {
> +        case NM_MIN_FMT:
> +            switch ((ctx->opcode >> 9) & 1) {
> +            case FMT_SDPS_S:
> +                gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
> +                break;
> +            case FMT_SDPS_D:
> +                gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
> +                break;
> +            }
> +            break;
> +        case NM_MAX_FMT:
> +            switch ((ctx->opcode >> 9) & 1) {
> +            case FMT_SDPS_S:
> +                gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
> +                break;
> +            case FMT_SDPS_D:
> +                gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
> +                break;
> +            }
> +            break;
> +        case NM_MINA_FMT:
> +            switch ((ctx->opcode >> 9) & 1) {
> +            case FMT_SDPS_S:
> +                gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
> +                break;
> +            case FMT_SDPS_D:
> +                gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
> +                break;
> +            }
> +            break;
> +        case NM_MAXA_FMT:
> +            switch ((ctx->opcode >> 9) & 1) {
> +            case FMT_SDPS_S:
> +                gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
> +                break;
> +            case FMT_SDPS_D:
> +                gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
> +                break;
> +            }
> +            break;
> +        case NM_POOL32FXF:
> +            switch ((ctx->opcode >> 6) & 0xff) {
> +            case NM_CFC1:
> +                gen_cp1(ctx, OPC_CFC1, rt, rs);
> +                break;
> +            case NM_CTC1:
> +                gen_cp1(ctx, OPC_CTC1, rt, rs);
> +                break;
> +            case NM_MFC1:
> +                gen_cp1(ctx, OPC_MFC1, rt, rs);
> +                break;
> +            case NM_MTC1:
> +                gen_cp1(ctx, OPC_MTC1, rt, rs);
> +                break;
> +            case NM_MFHC1:
> +                gen_cp1(ctx, OPC_MFHC1, rt, rs);
> +                break;
> +            case NM_MTHC1:
> +                gen_cp1(ctx, OPC_MTHC1, rt, rs);
> +                break;
> +            case NM_CVT_S_PL:
> +                gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
> +                break;
> +            case NM_CVT_S_PU:
> +                gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
> +                break;
> +            default:
> +                switch ((ctx->opcode >> 6) & 0x1ff) {
> +                case NM_CVT_L_S:
> +                    gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_CVT_L_D:
> +                    gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_CVT_W_S:
> +                    gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_CVT_W_D:
> +                    gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_RSQRT_S:
> +                    gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_RSQRT_D:
> +                    gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_SQRT_S:
> +                    gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_SQRT_D:
> +                    gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_RECIP_S:
> +                    gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_RECIP_D:
> +                    gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_FLOOR_L_S:
> +                    gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_FLOOR_L_D:
> +                    gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_FLOOR_W_S:
> +                    gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_FLOOR_W_D:
> +                    gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_CEIL_L_S:
> +                    gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_CEIL_L_D:
> +                    gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_CEIL_W_S:
> +                    gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_CEIL_W_D:
> +                    gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_TRUNC_L_S:
> +                    gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_TRUNC_L_D:
> +                    gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_TRUNC_W_S:
> +                    gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_TRUNC_W_D:
> +                    gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_ROUND_L_S:
> +                    gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_ROUND_L_D:
> +                    gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_ROUND_W_S:
> +                    gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_ROUND_W_D:
> +                    gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_MOV_S:
> +                    gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_MOV_D:
> +                    gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_ABS_S:
> +                    gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_ABS_D:
> +                    gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_NEG_S:
> +                    gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_NEG_D:
> +                    gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_CVT_D_S:
> +                    gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
> +                    break;
> +                case NM_CVT_D_W:
> +                    gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
> +                    break;
> +                case NM_CVT_D_L:
> +                    gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
> +                    break;
> +                case NM_CVT_S_D:
> +                    gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
> +                    break;
> +                case NM_CVT_S_W:
> +                    gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
> +                    break;
> +                case NM_CVT_S_L:
> +                    gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
> +                    break;
> +                default:
> +                    generate_exception_end(ctx, EXCP_RI);
> +                    break;
> +                }
> +                break;
> +            }
> +            break;
> +        }
> +        break;
> +    case NM_POOL32F_5:
> +        switch ((ctx->opcode >> 3) & 0x07) {
> +        case NM_CMP_CONDN_S:
> +            gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
> +            break;
> +        case NM_CMP_CONDN_D:
> +            gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
> +            break;
> +        default:
> +            generate_exception_end(ctx, EXCP_RI);
> +            break;
> +        }
> +        break;
> +    default:
> +        generate_exception_end(ctx, EXCP_RI);
> +        break;
> +    }
> +}
> +
>  static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
>  {
>      uint16_t insn;
> @@ -16746,6 +17045,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, > DisasContext *ctx)
>          }
>          break;
>      case NM_POOL32F:
> +        gen_pool32f_nanomips_insn(ctx);
>          break;
>      case NM_POOL32S:
>          break;
> --
> 2.7.4
>
>
diff mbox series

Patch

diff --git a/target/mips/translate.c b/target/mips/translate.c
index ae46de2..176d51d 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16447,6 +16447,305 @@  static void gen_pool16c_nanomips_insn(DisasContext *ctx)
     }
 }
 
+static void gen_pool32f_nanomips_insn(DisasContext *ctx)
+{
+    int rt, rs, rd;
+
+    rt = (ctx->opcode >> 21) & 0x1f;
+    rs = (ctx->opcode >> 16) & 0x1f;
+    rd = (ctx->opcode >> 11) & 0x1f;
+
+    if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
+        generate_exception_end(ctx, EXCP_RI);
+        return;
+    }
+    check_cp1_enabled(ctx);
+    switch (ctx->opcode & 0x07) {
+    case NM_POOL32F_0:
+        switch ((ctx->opcode >> 3) & 0x7f) {
+        case NM_RINT_S:
+            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
+            break;
+        case NM_RINT_D:
+            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
+            break;
+        case NM_CLASS_S:
+            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
+            break;
+        case NM_CLASS_D:
+            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
+            break;
+        case NM_ADD_S:
+            gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
+            break;
+        case NM_ADD_D:
+            gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
+            break;
+        case NM_SUB_S:
+            gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
+            break;
+        case NM_SUB_D:
+            gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
+            break;
+        case NM_MUL_S:
+            gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
+            break;
+        case NM_MUL_D:
+            gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
+            break;
+        case NM_DIV_S:
+            gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
+            break;
+        case NM_DIV_D:
+            gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
+            break;
+        case NM_SELEQZ_S:
+            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
+            break;
+        case NM_SELEQZ_D:
+            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
+            break;
+        case NM_SELNEZ_S:
+            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
+            break;
+        case NM_SELNEZ_D:
+            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
+            break;
+        case NM_SEL_S:
+            gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
+            break;
+        case NM_SEL_D:
+            gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
+            break;
+        case NM_MADDF_S:
+            gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
+            break;
+        case NM_MADDF_D:
+            gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
+            break;
+        case NM_MSUBF_S:
+            gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
+            break;
+        case NM_MSUBF_D:
+            gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    case NM_POOL32F_3:
+        switch ((ctx->opcode >> 3) & 0x07) {
+        case NM_MIN_FMT:
+            switch ((ctx->opcode >> 9) & 1) {
+            case FMT_SDPS_S:
+                gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
+                break;
+            case FMT_SDPS_D:
+                gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
+                break;
+            }
+            break;
+        case NM_MAX_FMT:
+            switch ((ctx->opcode >> 9) & 1) {
+            case FMT_SDPS_S:
+                gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
+                break;
+            case FMT_SDPS_D:
+                gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
+                break;
+            }
+            break;
+        case NM_MINA_FMT:
+            switch ((ctx->opcode >> 9) & 1) {
+            case FMT_SDPS_S:
+                gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
+                break;
+            case FMT_SDPS_D:
+                gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
+                break;
+            }
+            break;
+        case NM_MAXA_FMT:
+            switch ((ctx->opcode >> 9) & 1) {
+            case FMT_SDPS_S:
+                gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
+                break;
+            case FMT_SDPS_D:
+                gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
+                break;
+            }
+            break;
+        case NM_POOL32FXF:
+            switch ((ctx->opcode >> 6) & 0xff) {
+            case NM_CFC1:
+                gen_cp1(ctx, OPC_CFC1, rt, rs);
+                break;
+            case NM_CTC1:
+                gen_cp1(ctx, OPC_CTC1, rt, rs);
+                break;
+            case NM_MFC1:
+                gen_cp1(ctx, OPC_MFC1, rt, rs);
+                break;
+            case NM_MTC1:
+                gen_cp1(ctx, OPC_MTC1, rt, rs);
+                break;
+            case NM_MFHC1:
+                gen_cp1(ctx, OPC_MFHC1, rt, rs);
+                break;
+            case NM_MTHC1:
+                gen_cp1(ctx, OPC_MTHC1, rt, rs);
+                break;
+            case NM_CVT_S_PL:
+                gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
+                break;
+            case NM_CVT_S_PU:
+                gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
+                break;
+            default:
+                switch ((ctx->opcode >> 6) & 0x1ff) {
+                case NM_CVT_L_S:
+                    gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_L_D:
+                    gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_W_S:
+                    gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_W_D:
+                    gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
+                    break;
+                case NM_RSQRT_S:
+                    gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
+                    break;
+                case NM_RSQRT_D:
+                    gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
+                    break;
+                case NM_SQRT_S:
+                    gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
+                    break;
+                case NM_SQRT_D:
+                    gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
+                    break;
+                case NM_RECIP_S:
+                    gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
+                    break;
+                case NM_RECIP_D:
+                    gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
+                    break;
+                case NM_FLOOR_L_S:
+                    gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
+                    break;
+                case NM_FLOOR_L_D:
+                    gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
+                    break;
+                case NM_FLOOR_W_S:
+                    gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
+                    break;
+                case NM_FLOOR_W_D:
+                    gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
+                    break;
+                case NM_CEIL_L_S:
+                    gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
+                    break;
+                case NM_CEIL_L_D:
+                    gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
+                    break;
+                case NM_CEIL_W_S:
+                    gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
+                    break;
+                case NM_CEIL_W_D:
+                    gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
+                    break;
+                case NM_TRUNC_L_S:
+                    gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
+                    break;
+                case NM_TRUNC_L_D:
+                    gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
+                    break;
+                case NM_TRUNC_W_S:
+                    gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
+                    break;
+                case NM_TRUNC_W_D:
+                    gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
+                    break;
+                case NM_ROUND_L_S:
+                    gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
+                    break;
+                case NM_ROUND_L_D:
+                    gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
+                    break;
+                case NM_ROUND_W_S:
+                    gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
+                    break;
+                case NM_ROUND_W_D:
+                    gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
+                    break;
+                case NM_MOV_S:
+                    gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
+                    break;
+                case NM_MOV_D:
+                    gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
+                    break;
+                case NM_ABS_S:
+                    gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
+                    break;
+                case NM_ABS_D:
+                    gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
+                    break;
+                case NM_NEG_S:
+                    gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
+                    break;
+                case NM_NEG_D:
+                    gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_D_S:
+                    gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_D_W:
+                    gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_D_L:
+                    gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_S_D:
+                    gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_S_W:
+                    gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_S_L:
+                    gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
+                    break;
+                default:
+                    generate_exception_end(ctx, EXCP_RI);
+                    break;
+                }
+                break;
+            }
+            break;
+        }
+        break;
+    case NM_POOL32F_5:
+        switch ((ctx->opcode >> 3) & 0x07) {
+        case NM_CMP_CONDN_S:
+            gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
+            break;
+        case NM_CMP_CONDN_D:
+            gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    default:
+        generate_exception_end(ctx, EXCP_RI);
+        break;
+    }
+}
+
 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
 {
     uint16_t insn;
@@ -16746,6 +17045,7 @@  static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_POOL32F:
+        gen_pool32f_nanomips_insn(ctx);
         break;
     case NM_POOL32S:
         break;