Commit ad88e425 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-jun-1-2019' into staging



MIPS queue for June 1st, 2019

# gpg: Signature made Sat 01 Jun 2019 19:20:47 BST
# gpg:                using RSA key D4972A8967F75A65
# gpg: Good signature from "Aleksandar Markovic <amarkovic@wavecomp.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8526 FBF1 5DA3 811F 4A01  DD75 D497 2A89 67F7 5A65

* remotes/amarkovic/tags/mips-queue-jun-1-2019:
  target/mips: Improve performance of certain MSA instructions
  target/mips: Clean up lmi_helper.c
  target/mips: Clean up dsp_helper.c
  tests/tcg: target/mips: Add tests for MSA bit set instructions
  target/mips: Amend and cleanup MSA TCG tests
  target/mips: Add emulation of MMI instruction PCPYUD
  target/mips: Add emulation of MMI instruction PCPYLD
  target/mips: Add emulation of MMI instruction PCPYH

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 60905286 0df911fd
Loading
Loading
Loading
Loading
+29 −11
Original line number Diff line number Diff line
@@ -22,8 +22,10 @@
#include "exec/helper-proto.h"
#include "qemu/bitops.h"

/* As the byte ordering doesn't matter, i.e. all columns are treated
   identically, these unions can be used directly.  */
/*
 * As the byte ordering doesn't matter, i.e. all columns are treated
 * identically, these unions can be used directly.
 */
typedef union {
    uint8_t  ub[4];
    int8_t   sb[4];
@@ -1445,8 +1447,14 @@ target_ulong helper_precr_ob_qh(target_ulong rs, target_ulong rt)
    return temp;
}


/*
 * In case sa == 0, use rt2, rt0, rs2, rs0.
 * In case sa != 0, use rt3, rt1, rs3, rs1.
 */
#define PRECR_QH_PW(name, var)                                        \
target_ulong helper_precr_##name##_qh_pw(target_ulong rs, target_ulong rt, \
target_ulong helper_precr_##name##_qh_pw(target_ulong rs,             \
                                         target_ulong rt,             \
                                         uint32_t sa)                 \
{                                                                     \
    uint16_t rs3, rs2, rs1, rs0;                                      \
@@ -1456,8 +1464,6 @@ target_ulong helper_precr_##name##_qh_pw(target_ulong rs, target_ulong rt, \
    MIPSDSP_SPLIT64_16(rs, rs3, rs2, rs1, rs0);                       \
    MIPSDSP_SPLIT64_16(rt, rt3, rt2, rt1, rt0);                       \
                                                                      \
    /* When sa = 0, we use rt2, rt0, rs2, rs0;                        \
     * when sa != 0, we use rt3, rt1, rs3, rs1. */                    \
    if (sa == 0) {                                                    \
        tempD = rt2 << var;                                           \
        tempC = rt0 << var;                                           \
@@ -1965,7 +1971,8 @@ SHIFT_PH(shra_r, rnd16_rashift);
#undef SHIFT_PH

/** DSP Multiply Sub-class insns **/
/* Return value made up by two 16bits value.
/*
 * Return value made up by two 16bits value.
 * FIXME give the macro a better name.
 */
#define MUL_RETURN32_16_PH(name, func, \
@@ -3274,11 +3281,15 @@ target_ulong helper_dextr_l(target_ulong ac, target_ulong shift,
                            CPUMIPSState *env)
{
    uint64_t temp[3];
    target_ulong ret;

    shift = shift & 0x3F;

    mipsdsp_rndrashift_acc(temp, ac, shift, env);
    return (temp[1] << 63) | (temp[0] >> 1);

    ret = (temp[1] << 63) | (temp[0] >> 1);

    return ret;
}

target_ulong helper_dextr_r_l(target_ulong ac, target_ulong shift,
@@ -3286,6 +3297,7 @@ target_ulong helper_dextr_r_l(target_ulong ac, target_ulong shift,
{
    uint64_t temp[3];
    uint32_t temp128;
    target_ulong ret;

    shift = shift & 0x3F;
    mipsdsp_rndrashift_acc(temp, ac, shift, env);
@@ -3305,7 +3317,9 @@ target_ulong helper_dextr_r_l(target_ulong ac, target_ulong shift,
        set_DSPControl_overflow_flag(1, 23, env);
    }

    return (temp[1] << 63) | (temp[0] >> 1);
    ret = (temp[1] << 63) | (temp[0] >> 1);

    return ret;
}

target_ulong helper_dextr_rs_l(target_ulong ac, target_ulong shift,
@@ -3313,6 +3327,7 @@ target_ulong helper_dextr_rs_l(target_ulong ac, target_ulong shift,
{
    uint64_t temp[3];
    uint32_t temp128;
    target_ulong ret;

    shift = shift & 0x3F;
    mipsdsp_rndrashift_acc(temp, ac, shift, env);
@@ -3338,7 +3353,10 @@ target_ulong helper_dextr_rs_l(target_ulong ac, target_ulong shift,
        }
        set_DSPControl_overflow_flag(1, 23, env);
    }
    return (temp[1] << 63) | (temp[0] >> 1);

    ret = (temp[1] << 63) | (temp[0] >> 1);

    return ret;
}
#endif

+5 −3
Original line number Diff line number Diff line
@@ -21,9 +21,11 @@
#include "cpu.h"
#include "exec/helper-proto.h"

/* If the byte ordering doesn't matter, i.e. all columns are treated
   identically, then this union can be used directly.  If byte ordering
   does matter, we generally ignore dumping to memory.  */
/*
 * If the byte ordering doesn't matter, i.e. all columns are treated
 * identically, then this union can be used directly.  If byte ordering
 * does matter, we generally ignore dumping to memory.
 */
typedef union {
    uint8_t  ub[8];
    int8_t   sb[8];
+433 −109

File changed.

Preview size limit exceeded, changes collapsed.

+149 −3
Original line number Diff line number Diff line
@@ -24357,6 +24357,146 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
 *                     PEXTUW
 */
/*
 *  PCPYH rd, rt
 *
 *    Parallel Copy Halfword
 *
 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
 *  +-----------+---------+---------+---------+---------+-----------+
 *  |    MMI    |0 0 0 0 0|   rt    |   rd    |  PCPYH  |    MMI3   |
 *  +-----------+---------+---------+---------+---------+-----------+
 */
static void gen_mmi_pcpyh(DisasContext *ctx)
{
    uint32_t pd, rt, rd;
    uint32_t opcode;
    opcode = ctx->opcode;
    pd = extract32(opcode, 21, 5);
    rt = extract32(opcode, 16, 5);
    rd = extract32(opcode, 11, 5);
    if (unlikely(pd != 0)) {
        generate_exception_end(ctx, EXCP_RI);
    } else if (rd == 0) {
        /* nop */
    } else if (rt == 0) {
        tcg_gen_movi_i64(cpu_gpr[rd], 0);
        tcg_gen_movi_i64(cpu_mmr[rd], 0);
    } else {
        TCGv_i64 t0 = tcg_temp_new();
        TCGv_i64 t1 = tcg_temp_new();
        uint64_t mask = (1ULL << 16) - 1;
        tcg_gen_andi_i64(t0, cpu_gpr[rt], mask);
        tcg_gen_movi_i64(t1, 0);
        tcg_gen_or_i64(t1, t0, t1);
        tcg_gen_shli_i64(t0, t0, 16);
        tcg_gen_or_i64(t1, t0, t1);
        tcg_gen_shli_i64(t0, t0, 16);
        tcg_gen_or_i64(t1, t0, t1);
        tcg_gen_shli_i64(t0, t0, 16);
        tcg_gen_or_i64(t1, t0, t1);
        tcg_gen_mov_i64(cpu_gpr[rd], t1);
        tcg_gen_andi_i64(t0, cpu_mmr[rt], mask);
        tcg_gen_movi_i64(t1, 0);
        tcg_gen_or_i64(t1, t0, t1);
        tcg_gen_shli_i64(t0, t0, 16);
        tcg_gen_or_i64(t1, t0, t1);
        tcg_gen_shli_i64(t0, t0, 16);
        tcg_gen_or_i64(t1, t0, t1);
        tcg_gen_shli_i64(t0, t0, 16);
        tcg_gen_or_i64(t1, t0, t1);
        tcg_gen_mov_i64(cpu_mmr[rd], t1);
        tcg_temp_free(t0);
        tcg_temp_free(t1);
    }
}
/*
 *  PCPYLD rd, rs, rt
 *
 *    Parallel Copy Lower Doubleword
 *
 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
 *  +-----------+---------+---------+---------+---------+-----------+
 *  |    MMI    |   rs    |   rt    |   rd    | PCPYLD  |    MMI2   |
 *  +-----------+---------+---------+---------+---------+-----------+
 */
static void gen_mmi_pcpyld(DisasContext *ctx)
{
    uint32_t rs, rt, rd;
    uint32_t opcode;
    opcode = ctx->opcode;
    rs = extract32(opcode, 21, 5);
    rt = extract32(opcode, 16, 5);
    rd = extract32(opcode, 11, 5);
    if (rd == 0) {
        /* nop */
    } else {
        if (rs == 0) {
            tcg_gen_movi_i64(cpu_mmr[rd], 0);
        } else {
            tcg_gen_mov_i64(cpu_mmr[rd], cpu_gpr[rs]);
        }
        if (rt == 0) {
            tcg_gen_movi_i64(cpu_gpr[rd], 0);
        } else {
            if (rd != rt) {
                tcg_gen_mov_i64(cpu_gpr[rd], cpu_gpr[rt]);
            }
        }
    }
}
/*
 *  PCPYUD rd, rs, rt
 *
 *    Parallel Copy Upper Doubleword
 *
 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
 *  +-----------+---------+---------+---------+---------+-----------+
 *  |    MMI    |   rs    |   rt    |   rd    | PCPYUD  |    MMI3   |
 *  +-----------+---------+---------+---------+---------+-----------+
 */
static void gen_mmi_pcpyud(DisasContext *ctx)
{
    uint32_t rs, rt, rd;
    uint32_t opcode;
    opcode = ctx->opcode;
    rs = extract32(opcode, 21, 5);
    rt = extract32(opcode, 16, 5);
    rd = extract32(opcode, 11, 5);
    if (rd == 0) {
        /* nop */
    } else {
        if (rs == 0) {
            tcg_gen_movi_i64(cpu_gpr[rd], 0);
        } else {
            tcg_gen_mov_i64(cpu_gpr[rd], cpu_mmr[rs]);
        }
        if (rt == 0) {
            tcg_gen_movi_i64(cpu_mmr[rd], 0);
        } else {
            if (rd != rt) {
                tcg_gen_mov_i64(cpu_mmr[rd], cpu_mmr[rt]);
            }
        }
    }
}
#endif
@@ -27371,7 +27511,6 @@ static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
    case MMI_OPC_2_PINTH:     /* TODO: MMI_OPC_2_PINTH */
    case MMI_OPC_2_PMULTW:    /* TODO: MMI_OPC_2_PMULTW */
    case MMI_OPC_2_PDIVW:     /* TODO: MMI_OPC_2_PDIVW */
    case MMI_OPC_2_PCPYLD:    /* TODO: MMI_OPC_2_PCPYLD */
    case MMI_OPC_2_PMADDH:    /* TODO: MMI_OPC_2_PMADDH */
    case MMI_OPC_2_PHMADH:    /* TODO: MMI_OPC_2_PHMADH */
    case MMI_OPC_2_PAND:      /* TODO: MMI_OPC_2_PAND */
@@ -27386,6 +27525,9 @@ static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
    case MMI_OPC_2_PROT3W:    /* TODO: MMI_OPC_2_PROT3W */
        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
        break;
    case MMI_OPC_2_PCPYLD:
        gen_mmi_pcpyld(ctx);
        break;
    default:
        MIPS_INVAL("TX79 MMI class MMI2");
        generate_exception_end(ctx, EXCP_RI);
@@ -27405,14 +27547,18 @@ static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
    case MMI_OPC_3_PINTEH:     /* TODO: MMI_OPC_3_PINTEH */
    case MMI_OPC_3_PMULTUW:    /* TODO: MMI_OPC_3_PMULTUW */
    case MMI_OPC_3_PDIVUW:     /* TODO: MMI_OPC_3_PDIVUW */
    case MMI_OPC_3_PCPYUD:     /* TODO: MMI_OPC_3_PCPYUD */
    case MMI_OPC_3_POR:        /* TODO: MMI_OPC_3_POR */
    case MMI_OPC_3_PNOR:       /* TODO: MMI_OPC_3_PNOR */
    case MMI_OPC_3_PEXCH:      /* TODO: MMI_OPC_3_PEXCH */
    case MMI_OPC_3_PCPYH:      /* TODO: MMI_OPC_3_PCPYH */
    case MMI_OPC_3_PEXCW:      /* TODO: MMI_OPC_3_PEXCW */
        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
        break;
    case MMI_OPC_3_PCPYH:
        gen_mmi_pcpyh(ctx);
        break;
    case MMI_OPC_3_PCPYUD:
        gen_mmi_pcpyud(ctx);
        break;
    default:
        MIPS_INVAL("TX79 MMI class MMI3");
        generate_exception_end(ctx, EXCP_RI);
+1 −1
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ static inline int32_t check_results(const char *instruction_name,
        }
    }

    printf("PASS: %3d   FAIL: %3d   elapsed time: %5.2f ms\n",
    printf("\tPASS: %3d \tFAIL: %3d \telapsed time: %5.2f ms\n",
           pass_count, fail_count, elapsed_time);

    if (fail_count > 0) {
Loading