qemu/target/mips/msa_helper.c
<<
>>
Prefs
   1/*
   2 * MIPS SIMD Architecture Module Instruction emulation helpers for QEMU.
   3 *
   4 * Copyright (c) 2014 Imagination Technologies
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include "qemu/osdep.h"
  21#include "cpu.h"
  22#include "internal.h"
  23#include "exec/exec-all.h"
  24#include "exec/helper-proto.h"
  25#include "fpu/softfloat.h"
  26
  27/* Data format min and max values */
  28#define DF_BITS(df) (1 << ((df) + 3))
  29
  30#define DF_MAX_INT(df)  (int64_t)((1LL << (DF_BITS(df) - 1)) - 1)
  31#define M_MAX_INT(m)    (int64_t)((1LL << ((m)         - 1)) - 1)
  32
  33#define DF_MIN_INT(df)  (int64_t)(-(1LL << (DF_BITS(df) - 1)))
  34#define M_MIN_INT(m)    (int64_t)(-(1LL << ((m)         - 1)))
  35
  36#define DF_MAX_UINT(df) (uint64_t)(-1ULL >> (64 - DF_BITS(df)))
  37#define M_MAX_UINT(m)   (uint64_t)(-1ULL >> (64 - (m)))
  38
  39#define UNSIGNED(x, df) ((x) & DF_MAX_UINT(df))
  40#define SIGNED(x, df)                                                   \
  41    ((((int64_t)x) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df)))
  42
  43/* Element-by-element access macros */
  44#define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df))
  45
  46
  47
  48/*
  49 * Bit Count
  50 * ---------
  51 *
  52 * +---------------+----------------------------------------------------------+
  53 * | NLOC.B        | Vector Leading Ones Count (byte)                         |
  54 * | NLOC.H        | Vector Leading Ones Count (halfword)                     |
  55 * | NLOC.W        | Vector Leading Ones Count (word)                         |
  56 * | NLOC.D        | Vector Leading Ones Count (doubleword)                   |
  57 * | NLZC.B        | Vector Leading Zeros Count (byte)                        |
  58 * | NLZC.H        | Vector Leading Zeros Count (halfword)                    |
  59 * | NLZC.W        | Vector Leading Zeros Count (word)                        |
  60 * | NLZC.D        | Vector Leading Zeros Count (doubleword)                  |
  61 * | PCNT.B        | Vector Population Count (byte)                           |
  62 * | PCNT.H        | Vector Population Count (halfword)                       |
  63 * | PCNT.W        | Vector Population Count (word)                           |
  64 * | PCNT.D        | Vector Population Count (doubleword)                     |
  65 * +---------------+----------------------------------------------------------+
  66 */
  67
  68static inline int64_t msa_nlzc_df(uint32_t df, int64_t arg)
  69{
  70    uint64_t x, y;
  71    int n, c;
  72
  73    x = UNSIGNED(arg, df);
  74    n = DF_BITS(df);
  75    c = DF_BITS(df) / 2;
  76
  77    do {
  78        y = x >> c;
  79        if (y != 0) {
  80            n = n - c;
  81            x = y;
  82        }
  83        c = c >> 1;
  84    } while (c != 0);
  85
  86    return n - x;
  87}
  88
  89static inline int64_t msa_nloc_df(uint32_t df, int64_t arg)
  90{
  91    return msa_nlzc_df(df, UNSIGNED((~arg), df));
  92}
  93
  94void helper_msa_nloc_b(CPUMIPSState *env, uint32_t wd, uint32_t ws)
  95{
  96    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
  97    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
  98
  99    pwd->b[0]  = msa_nloc_df(DF_BYTE, pws->b[0]);
 100    pwd->b[1]  = msa_nloc_df(DF_BYTE, pws->b[1]);
 101    pwd->b[2]  = msa_nloc_df(DF_BYTE, pws->b[2]);
 102    pwd->b[3]  = msa_nloc_df(DF_BYTE, pws->b[3]);
 103    pwd->b[4]  = msa_nloc_df(DF_BYTE, pws->b[4]);
 104    pwd->b[5]  = msa_nloc_df(DF_BYTE, pws->b[5]);
 105    pwd->b[6]  = msa_nloc_df(DF_BYTE, pws->b[6]);
 106    pwd->b[7]  = msa_nloc_df(DF_BYTE, pws->b[7]);
 107    pwd->b[8]  = msa_nloc_df(DF_BYTE, pws->b[8]);
 108    pwd->b[9]  = msa_nloc_df(DF_BYTE, pws->b[9]);
 109    pwd->b[10] = msa_nloc_df(DF_BYTE, pws->b[10]);
 110    pwd->b[11] = msa_nloc_df(DF_BYTE, pws->b[11]);
 111    pwd->b[12] = msa_nloc_df(DF_BYTE, pws->b[12]);
 112    pwd->b[13] = msa_nloc_df(DF_BYTE, pws->b[13]);
 113    pwd->b[14] = msa_nloc_df(DF_BYTE, pws->b[14]);
 114    pwd->b[15] = msa_nloc_df(DF_BYTE, pws->b[15]);
 115}
 116
 117void helper_msa_nloc_h(CPUMIPSState *env, uint32_t wd, uint32_t ws)
 118{
 119    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 120    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 121
 122    pwd->h[0]  = msa_nloc_df(DF_HALF, pws->h[0]);
 123    pwd->h[1]  = msa_nloc_df(DF_HALF, pws->h[1]);
 124    pwd->h[2]  = msa_nloc_df(DF_HALF, pws->h[2]);
 125    pwd->h[3]  = msa_nloc_df(DF_HALF, pws->h[3]);
 126    pwd->h[4]  = msa_nloc_df(DF_HALF, pws->h[4]);
 127    pwd->h[5]  = msa_nloc_df(DF_HALF, pws->h[5]);
 128    pwd->h[6]  = msa_nloc_df(DF_HALF, pws->h[6]);
 129    pwd->h[7]  = msa_nloc_df(DF_HALF, pws->h[7]);
 130}
 131
 132void helper_msa_nloc_w(CPUMIPSState *env, uint32_t wd, uint32_t ws)
 133{
 134    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 135    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 136
 137    pwd->w[0]  = msa_nloc_df(DF_WORD, pws->w[0]);
 138    pwd->w[1]  = msa_nloc_df(DF_WORD, pws->w[1]);
 139    pwd->w[2]  = msa_nloc_df(DF_WORD, pws->w[2]);
 140    pwd->w[3]  = msa_nloc_df(DF_WORD, pws->w[3]);
 141}
 142
 143void helper_msa_nloc_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
 144{
 145    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 146    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 147
 148    pwd->d[0]  = msa_nloc_df(DF_DOUBLE, pws->d[0]);
 149    pwd->d[1]  = msa_nloc_df(DF_DOUBLE, pws->d[1]);
 150}
 151
 152void helper_msa_nlzc_b(CPUMIPSState *env, uint32_t wd, uint32_t ws)
 153{
 154    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 155    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 156
 157    pwd->b[0]  = msa_nlzc_df(DF_BYTE, pws->b[0]);
 158    pwd->b[1]  = msa_nlzc_df(DF_BYTE, pws->b[1]);
 159    pwd->b[2]  = msa_nlzc_df(DF_BYTE, pws->b[2]);
 160    pwd->b[3]  = msa_nlzc_df(DF_BYTE, pws->b[3]);
 161    pwd->b[4]  = msa_nlzc_df(DF_BYTE, pws->b[4]);
 162    pwd->b[5]  = msa_nlzc_df(DF_BYTE, pws->b[5]);
 163    pwd->b[6]  = msa_nlzc_df(DF_BYTE, pws->b[6]);
 164    pwd->b[7]  = msa_nlzc_df(DF_BYTE, pws->b[7]);
 165    pwd->b[8]  = msa_nlzc_df(DF_BYTE, pws->b[8]);
 166    pwd->b[9]  = msa_nlzc_df(DF_BYTE, pws->b[9]);
 167    pwd->b[10] = msa_nlzc_df(DF_BYTE, pws->b[10]);
 168    pwd->b[11] = msa_nlzc_df(DF_BYTE, pws->b[11]);
 169    pwd->b[12] = msa_nlzc_df(DF_BYTE, pws->b[12]);
 170    pwd->b[13] = msa_nlzc_df(DF_BYTE, pws->b[13]);
 171    pwd->b[14] = msa_nlzc_df(DF_BYTE, pws->b[14]);
 172    pwd->b[15] = msa_nlzc_df(DF_BYTE, pws->b[15]);
 173}
 174
 175void helper_msa_nlzc_h(CPUMIPSState *env, uint32_t wd, uint32_t ws)
 176{
 177    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 178    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 179
 180    pwd->h[0]  = msa_nlzc_df(DF_HALF, pws->h[0]);
 181    pwd->h[1]  = msa_nlzc_df(DF_HALF, pws->h[1]);
 182    pwd->h[2]  = msa_nlzc_df(DF_HALF, pws->h[2]);
 183    pwd->h[3]  = msa_nlzc_df(DF_HALF, pws->h[3]);
 184    pwd->h[4]  = msa_nlzc_df(DF_HALF, pws->h[4]);
 185    pwd->h[5]  = msa_nlzc_df(DF_HALF, pws->h[5]);
 186    pwd->h[6]  = msa_nlzc_df(DF_HALF, pws->h[6]);
 187    pwd->h[7]  = msa_nlzc_df(DF_HALF, pws->h[7]);
 188}
 189
 190void helper_msa_nlzc_w(CPUMIPSState *env, uint32_t wd, uint32_t ws)
 191{
 192    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 193    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 194
 195    pwd->w[0]  = msa_nlzc_df(DF_WORD, pws->w[0]);
 196    pwd->w[1]  = msa_nlzc_df(DF_WORD, pws->w[1]);
 197    pwd->w[2]  = msa_nlzc_df(DF_WORD, pws->w[2]);
 198    pwd->w[3]  = msa_nlzc_df(DF_WORD, pws->w[3]);
 199}
 200
 201void helper_msa_nlzc_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
 202{
 203    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 204    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 205
 206    pwd->d[0]  = msa_nlzc_df(DF_DOUBLE, pws->d[0]);
 207    pwd->d[1]  = msa_nlzc_df(DF_DOUBLE, pws->d[1]);
 208}
 209
 210static inline int64_t msa_pcnt_df(uint32_t df, int64_t arg)
 211{
 212    uint64_t x;
 213
 214    x = UNSIGNED(arg, df);
 215
 216    x = (x & 0x5555555555555555ULL) + ((x >>  1) & 0x5555555555555555ULL);
 217    x = (x & 0x3333333333333333ULL) + ((x >>  2) & 0x3333333333333333ULL);
 218    x = (x & 0x0F0F0F0F0F0F0F0FULL) + ((x >>  4) & 0x0F0F0F0F0F0F0F0FULL);
 219    x = (x & 0x00FF00FF00FF00FFULL) + ((x >>  8) & 0x00FF00FF00FF00FFULL);
 220    x = (x & 0x0000FFFF0000FFFFULL) + ((x >> 16) & 0x0000FFFF0000FFFFULL);
 221    x = (x & 0x00000000FFFFFFFFULL) + ((x >> 32));
 222
 223    return x;
 224}
 225
 226void helper_msa_pcnt_b(CPUMIPSState *env, uint32_t wd, uint32_t ws)
 227{
 228    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 229    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 230
 231    pwd->b[0]  = msa_pcnt_df(DF_BYTE, pws->b[0]);
 232    pwd->b[1]  = msa_pcnt_df(DF_BYTE, pws->b[1]);
 233    pwd->b[2]  = msa_pcnt_df(DF_BYTE, pws->b[2]);
 234    pwd->b[3]  = msa_pcnt_df(DF_BYTE, pws->b[3]);
 235    pwd->b[4]  = msa_pcnt_df(DF_BYTE, pws->b[4]);
 236    pwd->b[5]  = msa_pcnt_df(DF_BYTE, pws->b[5]);
 237    pwd->b[6]  = msa_pcnt_df(DF_BYTE, pws->b[6]);
 238    pwd->b[7]  = msa_pcnt_df(DF_BYTE, pws->b[7]);
 239    pwd->b[8]  = msa_pcnt_df(DF_BYTE, pws->b[8]);
 240    pwd->b[9]  = msa_pcnt_df(DF_BYTE, pws->b[9]);
 241    pwd->b[10] = msa_pcnt_df(DF_BYTE, pws->b[10]);
 242    pwd->b[11] = msa_pcnt_df(DF_BYTE, pws->b[11]);
 243    pwd->b[12] = msa_pcnt_df(DF_BYTE, pws->b[12]);
 244    pwd->b[13] = msa_pcnt_df(DF_BYTE, pws->b[13]);
 245    pwd->b[14] = msa_pcnt_df(DF_BYTE, pws->b[14]);
 246    pwd->b[15] = msa_pcnt_df(DF_BYTE, pws->b[15]);
 247}
 248
 249void helper_msa_pcnt_h(CPUMIPSState *env, uint32_t wd, uint32_t ws)
 250{
 251    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 252    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 253
 254    pwd->h[0]  = msa_pcnt_df(DF_HALF, pws->h[0]);
 255    pwd->h[1]  = msa_pcnt_df(DF_HALF, pws->h[1]);
 256    pwd->h[2]  = msa_pcnt_df(DF_HALF, pws->h[2]);
 257    pwd->h[3]  = msa_pcnt_df(DF_HALF, pws->h[3]);
 258    pwd->h[4]  = msa_pcnt_df(DF_HALF, pws->h[4]);
 259    pwd->h[5]  = msa_pcnt_df(DF_HALF, pws->h[5]);
 260    pwd->h[6]  = msa_pcnt_df(DF_HALF, pws->h[6]);
 261    pwd->h[7]  = msa_pcnt_df(DF_HALF, pws->h[7]);
 262}
 263
 264void helper_msa_pcnt_w(CPUMIPSState *env, uint32_t wd, uint32_t ws)
 265{
 266    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 267    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 268
 269    pwd->w[0]  = msa_pcnt_df(DF_WORD, pws->w[0]);
 270    pwd->w[1]  = msa_pcnt_df(DF_WORD, pws->w[1]);
 271    pwd->w[2]  = msa_pcnt_df(DF_WORD, pws->w[2]);
 272    pwd->w[3]  = msa_pcnt_df(DF_WORD, pws->w[3]);
 273}
 274
 275void helper_msa_pcnt_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
 276{
 277    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 278    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 279
 280    pwd->d[0]  = msa_pcnt_df(DF_DOUBLE, pws->d[0]);
 281    pwd->d[1]  = msa_pcnt_df(DF_DOUBLE, pws->d[1]);
 282}
 283
 284
 285/*
 286 * Bit Move
 287 * --------
 288 *
 289 * +---------------+----------------------------------------------------------+
 290 * | BINSL.B       | Vector Bit Insert Left (byte)                            |
 291 * | BINSL.H       | Vector Bit Insert Left (halfword)                        |
 292 * | BINSL.W       | Vector Bit Insert Left (word)                            |
 293 * | BINSL.D       | Vector Bit Insert Left (doubleword)                      |
 294 * | BINSR.B       | Vector Bit Insert Right (byte)                           |
 295 * | BINSR.H       | Vector Bit Insert Right (halfword)                       |
 296 * | BINSR.W       | Vector Bit Insert Right (word)                           |
 297 * | BINSR.D       | Vector Bit Insert Right (doubleword)                     |
 298 * | BMNZ.V        | Vector Bit Move If Not Zero                              |
 299 * | BMZ.V         | Vector Bit Move If Zero                                  |
 300 * | BSEL.V        | Vector Bit Select                                        |
 301 * +---------------+----------------------------------------------------------+
 302 */
 303
 304/* Data format bit position and unsigned values */
 305#define BIT_POSITION(x, df) ((uint64_t)(x) % DF_BITS(df))
 306
 307static inline int64_t msa_binsl_df(uint32_t df,
 308                                   int64_t dest, int64_t arg1, int64_t arg2)
 309{
 310    uint64_t u_arg1 = UNSIGNED(arg1, df);
 311    uint64_t u_dest = UNSIGNED(dest, df);
 312    int32_t sh_d = BIT_POSITION(arg2, df) + 1;
 313    int32_t sh_a = DF_BITS(df) - sh_d;
 314    if (sh_d == DF_BITS(df)) {
 315        return u_arg1;
 316    } else {
 317        return UNSIGNED(UNSIGNED(u_dest << sh_d, df) >> sh_d, df) |
 318               UNSIGNED(UNSIGNED(u_arg1 >> sh_a, df) << sh_a, df);
 319    }
 320}
 321
 322void helper_msa_binsl_b(CPUMIPSState *env,
 323                        uint32_t wd, uint32_t ws, uint32_t wt)
 324{
 325    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 326    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 327    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 328
 329    pwd->b[0]  = msa_binsl_df(DF_BYTE, pwd->b[0],  pws->b[0],  pwt->b[0]);
 330    pwd->b[1]  = msa_binsl_df(DF_BYTE, pwd->b[1],  pws->b[1],  pwt->b[1]);
 331    pwd->b[2]  = msa_binsl_df(DF_BYTE, pwd->b[2],  pws->b[2],  pwt->b[2]);
 332    pwd->b[3]  = msa_binsl_df(DF_BYTE, pwd->b[3],  pws->b[3],  pwt->b[3]);
 333    pwd->b[4]  = msa_binsl_df(DF_BYTE, pwd->b[4],  pws->b[4],  pwt->b[4]);
 334    pwd->b[5]  = msa_binsl_df(DF_BYTE, pwd->b[5],  pws->b[5],  pwt->b[5]);
 335    pwd->b[6]  = msa_binsl_df(DF_BYTE, pwd->b[6],  pws->b[6],  pwt->b[6]);
 336    pwd->b[7]  = msa_binsl_df(DF_BYTE, pwd->b[7],  pws->b[7],  pwt->b[7]);
 337    pwd->b[8]  = msa_binsl_df(DF_BYTE, pwd->b[8],  pws->b[8],  pwt->b[8]);
 338    pwd->b[9]  = msa_binsl_df(DF_BYTE, pwd->b[9],  pws->b[9],  pwt->b[9]);
 339    pwd->b[10] = msa_binsl_df(DF_BYTE, pwd->b[10], pws->b[10], pwt->b[10]);
 340    pwd->b[11] = msa_binsl_df(DF_BYTE, pwd->b[11], pws->b[11], pwt->b[11]);
 341    pwd->b[12] = msa_binsl_df(DF_BYTE, pwd->b[12], pws->b[12], pwt->b[12]);
 342    pwd->b[13] = msa_binsl_df(DF_BYTE, pwd->b[13], pws->b[13], pwt->b[13]);
 343    pwd->b[14] = msa_binsl_df(DF_BYTE, pwd->b[14], pws->b[14], pwt->b[14]);
 344    pwd->b[15] = msa_binsl_df(DF_BYTE, pwd->b[15], pws->b[15], pwt->b[15]);
 345}
 346
 347void helper_msa_binsl_h(CPUMIPSState *env,
 348                        uint32_t wd, uint32_t ws, uint32_t wt)
 349{
 350    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 351    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 352    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 353
 354    pwd->h[0]  = msa_binsl_df(DF_HALF, pwd->h[0],  pws->h[0],  pwt->h[0]);
 355    pwd->h[1]  = msa_binsl_df(DF_HALF, pwd->h[1],  pws->h[1],  pwt->h[1]);
 356    pwd->h[2]  = msa_binsl_df(DF_HALF, pwd->h[2],  pws->h[2],  pwt->h[2]);
 357    pwd->h[3]  = msa_binsl_df(DF_HALF, pwd->h[3],  pws->h[3],  pwt->h[3]);
 358    pwd->h[4]  = msa_binsl_df(DF_HALF, pwd->h[4],  pws->h[4],  pwt->h[4]);
 359    pwd->h[5]  = msa_binsl_df(DF_HALF, pwd->h[5],  pws->h[5],  pwt->h[5]);
 360    pwd->h[6]  = msa_binsl_df(DF_HALF, pwd->h[6],  pws->h[6],  pwt->h[6]);
 361    pwd->h[7]  = msa_binsl_df(DF_HALF, pwd->h[7],  pws->h[7],  pwt->h[7]);
 362}
 363
 364void helper_msa_binsl_w(CPUMIPSState *env,
 365                        uint32_t wd, uint32_t ws, uint32_t wt)
 366{
 367    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 368    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 369    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 370
 371    pwd->w[0]  = msa_binsl_df(DF_WORD, pwd->w[0],  pws->w[0],  pwt->w[0]);
 372    pwd->w[1]  = msa_binsl_df(DF_WORD, pwd->w[1],  pws->w[1],  pwt->w[1]);
 373    pwd->w[2]  = msa_binsl_df(DF_WORD, pwd->w[2],  pws->w[2],  pwt->w[2]);
 374    pwd->w[3]  = msa_binsl_df(DF_WORD, pwd->w[3],  pws->w[3],  pwt->w[3]);
 375}
 376
 377void helper_msa_binsl_d(CPUMIPSState *env,
 378                        uint32_t wd, uint32_t ws, uint32_t wt)
 379{
 380    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 381    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 382    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 383
 384    pwd->d[0]  = msa_binsl_df(DF_DOUBLE, pwd->d[0],  pws->d[0],  pwt->d[0]);
 385    pwd->d[1]  = msa_binsl_df(DF_DOUBLE, pwd->d[1],  pws->d[1],  pwt->d[1]);
 386}
 387
 388static inline int64_t msa_binsr_df(uint32_t df,
 389                                   int64_t dest, int64_t arg1, int64_t arg2)
 390{
 391    uint64_t u_arg1 = UNSIGNED(arg1, df);
 392    uint64_t u_dest = UNSIGNED(dest, df);
 393    int32_t sh_d = BIT_POSITION(arg2, df) + 1;
 394    int32_t sh_a = DF_BITS(df) - sh_d;
 395    if (sh_d == DF_BITS(df)) {
 396        return u_arg1;
 397    } else {
 398        return UNSIGNED(UNSIGNED(u_dest >> sh_d, df) << sh_d, df) |
 399               UNSIGNED(UNSIGNED(u_arg1 << sh_a, df) >> sh_a, df);
 400    }
 401}
 402
 403void helper_msa_binsr_b(CPUMIPSState *env,
 404                        uint32_t wd, uint32_t ws, uint32_t wt)
 405{
 406    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 407    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 408    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 409
 410    pwd->b[0]  = msa_binsr_df(DF_BYTE, pwd->b[0],  pws->b[0],  pwt->b[0]);
 411    pwd->b[1]  = msa_binsr_df(DF_BYTE, pwd->b[1],  pws->b[1],  pwt->b[1]);
 412    pwd->b[2]  = msa_binsr_df(DF_BYTE, pwd->b[2],  pws->b[2],  pwt->b[2]);
 413    pwd->b[3]  = msa_binsr_df(DF_BYTE, pwd->b[3],  pws->b[3],  pwt->b[3]);
 414    pwd->b[4]  = msa_binsr_df(DF_BYTE, pwd->b[4],  pws->b[4],  pwt->b[4]);
 415    pwd->b[5]  = msa_binsr_df(DF_BYTE, pwd->b[5],  pws->b[5],  pwt->b[5]);
 416    pwd->b[6]  = msa_binsr_df(DF_BYTE, pwd->b[6],  pws->b[6],  pwt->b[6]);
 417    pwd->b[7]  = msa_binsr_df(DF_BYTE, pwd->b[7],  pws->b[7],  pwt->b[7]);
 418    pwd->b[8]  = msa_binsr_df(DF_BYTE, pwd->b[8],  pws->b[8],  pwt->b[8]);
 419    pwd->b[9]  = msa_binsr_df(DF_BYTE, pwd->b[9],  pws->b[9],  pwt->b[9]);
 420    pwd->b[10] = msa_binsr_df(DF_BYTE, pwd->b[10], pws->b[10], pwt->b[10]);
 421    pwd->b[11] = msa_binsr_df(DF_BYTE, pwd->b[11], pws->b[11], pwt->b[11]);
 422    pwd->b[12] = msa_binsr_df(DF_BYTE, pwd->b[12], pws->b[12], pwt->b[12]);
 423    pwd->b[13] = msa_binsr_df(DF_BYTE, pwd->b[13], pws->b[13], pwt->b[13]);
 424    pwd->b[14] = msa_binsr_df(DF_BYTE, pwd->b[14], pws->b[14], pwt->b[14]);
 425    pwd->b[15] = msa_binsr_df(DF_BYTE, pwd->b[15], pws->b[15], pwt->b[15]);
 426}
 427
 428void helper_msa_binsr_h(CPUMIPSState *env,
 429                        uint32_t wd, uint32_t ws, uint32_t wt)
 430{
 431    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 432    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 433    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 434
 435    pwd->h[0]  = msa_binsr_df(DF_HALF, pwd->h[0],  pws->h[0],  pwt->h[0]);
 436    pwd->h[1]  = msa_binsr_df(DF_HALF, pwd->h[1],  pws->h[1],  pwt->h[1]);
 437    pwd->h[2]  = msa_binsr_df(DF_HALF, pwd->h[2],  pws->h[2],  pwt->h[2]);
 438    pwd->h[3]  = msa_binsr_df(DF_HALF, pwd->h[3],  pws->h[3],  pwt->h[3]);
 439    pwd->h[4]  = msa_binsr_df(DF_HALF, pwd->h[4],  pws->h[4],  pwt->h[4]);
 440    pwd->h[5]  = msa_binsr_df(DF_HALF, pwd->h[5],  pws->h[5],  pwt->h[5]);
 441    pwd->h[6]  = msa_binsr_df(DF_HALF, pwd->h[6],  pws->h[6],  pwt->h[6]);
 442    pwd->h[7]  = msa_binsr_df(DF_HALF, pwd->h[7],  pws->h[7],  pwt->h[7]);
 443}
 444
 445void helper_msa_binsr_w(CPUMIPSState *env,
 446                        uint32_t wd, uint32_t ws, uint32_t wt)
 447{
 448    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 449    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 450    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 451
 452    pwd->w[0]  = msa_binsr_df(DF_WORD, pwd->w[0],  pws->w[0],  pwt->w[0]);
 453    pwd->w[1]  = msa_binsr_df(DF_WORD, pwd->w[1],  pws->w[1],  pwt->w[1]);
 454    pwd->w[2]  = msa_binsr_df(DF_WORD, pwd->w[2],  pws->w[2],  pwt->w[2]);
 455    pwd->w[3]  = msa_binsr_df(DF_WORD, pwd->w[3],  pws->w[3],  pwt->w[3]);
 456}
 457
 458void helper_msa_binsr_d(CPUMIPSState *env,
 459                        uint32_t wd, uint32_t ws, uint32_t wt)
 460{
 461    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 462    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 463    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 464
 465    pwd->d[0]  = msa_binsr_df(DF_DOUBLE, pwd->d[0],  pws->d[0],  pwt->d[0]);
 466    pwd->d[1]  = msa_binsr_df(DF_DOUBLE, pwd->d[1],  pws->d[1],  pwt->d[1]);
 467}
 468
 469void helper_msa_bmnz_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
 470{
 471    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 472    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 473    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 474
 475    pwd->d[0] = UNSIGNED(                                                     \
 476        ((pwd->d[0] & (~pwt->d[0])) | (pws->d[0] & pwt->d[0])), DF_DOUBLE);
 477    pwd->d[1] = UNSIGNED(                                                     \
 478        ((pwd->d[1] & (~pwt->d[1])) | (pws->d[1] & pwt->d[1])), DF_DOUBLE);
 479}
 480
 481void helper_msa_bmz_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
 482{
 483    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 484    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 485    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 486
 487    pwd->d[0] = UNSIGNED(                                                     \
 488        ((pwd->d[0] & pwt->d[0]) | (pws->d[0] & (~pwt->d[0]))), DF_DOUBLE);
 489    pwd->d[1] = UNSIGNED(                                                     \
 490        ((pwd->d[1] & pwt->d[1]) | (pws->d[1] & (~pwt->d[1]))), DF_DOUBLE);
 491}
 492
 493void helper_msa_bsel_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
 494{
 495    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 496    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 497    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 498
 499    pwd->d[0] = UNSIGNED(                                                     \
 500        (pws->d[0] & (~pwd->d[0])) | (pwt->d[0] & pwd->d[0]), DF_DOUBLE);
 501    pwd->d[1] = UNSIGNED(                                                     \
 502        (pws->d[1] & (~pwd->d[1])) | (pwt->d[1] & pwd->d[1]), DF_DOUBLE);
 503}
 504
 505
 506/*
 507 * Bit Set
 508 * -------
 509 *
 510 * +---------------+----------------------------------------------------------+
 511 * | BCLR.B        | Vector Bit Clear (byte)                                  |
 512 * | BCLR.H        | Vector Bit Clear (halfword)                              |
 513 * | BCLR.W        | Vector Bit Clear (word)                                  |
 514 * | BCLR.D        | Vector Bit Clear (doubleword)                            |
 515 * | BNEG.B        | Vector Bit Negate (byte)                                 |
 516 * | BNEG.H        | Vector Bit Negate (halfword)                             |
 517 * | BNEG.W        | Vector Bit Negate (word)                                 |
 518 * | BNEG.D        | Vector Bit Negate (doubleword)                           |
 519 * | BSET.B        | Vector Bit Set (byte)                                    |
 520 * | BSET.H        | Vector Bit Set (halfword)                                |
 521 * | BSET.W        | Vector Bit Set (word)                                    |
 522 * | BSET.D        | Vector Bit Set (doubleword)                              |
 523 * +---------------+----------------------------------------------------------+
 524 */
 525
 526static inline int64_t msa_bclr_df(uint32_t df, int64_t arg1, int64_t arg2)
 527{
 528    int32_t b_arg2 = BIT_POSITION(arg2, df);
 529    return UNSIGNED(arg1 & (~(1LL << b_arg2)), df);
 530}
 531
 532void helper_msa_bclr_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
 533{
 534    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 535    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 536    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 537
 538    pwd->b[0]  = msa_bclr_df(DF_BYTE, pws->b[0],  pwt->b[0]);
 539    pwd->b[1]  = msa_bclr_df(DF_BYTE, pws->b[1],  pwt->b[1]);
 540    pwd->b[2]  = msa_bclr_df(DF_BYTE, pws->b[2],  pwt->b[2]);
 541    pwd->b[3]  = msa_bclr_df(DF_BYTE, pws->b[3],  pwt->b[3]);
 542    pwd->b[4]  = msa_bclr_df(DF_BYTE, pws->b[4],  pwt->b[4]);
 543    pwd->b[5]  = msa_bclr_df(DF_BYTE, pws->b[5],  pwt->b[5]);
 544    pwd->b[6]  = msa_bclr_df(DF_BYTE, pws->b[6],  pwt->b[6]);
 545    pwd->b[7]  = msa_bclr_df(DF_BYTE, pws->b[7],  pwt->b[7]);
 546    pwd->b[8]  = msa_bclr_df(DF_BYTE, pws->b[8],  pwt->b[8]);
 547    pwd->b[9]  = msa_bclr_df(DF_BYTE, pws->b[9],  pwt->b[9]);
 548    pwd->b[10] = msa_bclr_df(DF_BYTE, pws->b[10], pwt->b[10]);
 549    pwd->b[11] = msa_bclr_df(DF_BYTE, pws->b[11], pwt->b[11]);
 550    pwd->b[12] = msa_bclr_df(DF_BYTE, pws->b[12], pwt->b[12]);
 551    pwd->b[13] = msa_bclr_df(DF_BYTE, pws->b[13], pwt->b[13]);
 552    pwd->b[14] = msa_bclr_df(DF_BYTE, pws->b[14], pwt->b[14]);
 553    pwd->b[15] = msa_bclr_df(DF_BYTE, pws->b[15], pwt->b[15]);
 554}
 555
 556void helper_msa_bclr_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
 557{
 558    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 559    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 560    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 561
 562    pwd->h[0]  = msa_bclr_df(DF_HALF, pws->h[0],  pwt->h[0]);
 563    pwd->h[1]  = msa_bclr_df(DF_HALF, pws->h[1],  pwt->h[1]);
 564    pwd->h[2]  = msa_bclr_df(DF_HALF, pws->h[2],  pwt->h[2]);
 565    pwd->h[3]  = msa_bclr_df(DF_HALF, pws->h[3],  pwt->h[3]);
 566    pwd->h[4]  = msa_bclr_df(DF_HALF, pws->h[4],  pwt->h[4]);
 567    pwd->h[5]  = msa_bclr_df(DF_HALF, pws->h[5],  pwt->h[5]);
 568    pwd->h[6]  = msa_bclr_df(DF_HALF, pws->h[6],  pwt->h[6]);
 569    pwd->h[7]  = msa_bclr_df(DF_HALF, pws->h[7],  pwt->h[7]);
 570}
 571
 572void helper_msa_bclr_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
 573{
 574    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 575    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 576    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 577
 578    pwd->w[0]  = msa_bclr_df(DF_WORD, pws->w[0],  pwt->w[0]);
 579    pwd->w[1]  = msa_bclr_df(DF_WORD, pws->w[1],  pwt->w[1]);
 580    pwd->w[2]  = msa_bclr_df(DF_WORD, pws->w[2],  pwt->w[2]);
 581    pwd->w[3]  = msa_bclr_df(DF_WORD, pws->w[3],  pwt->w[3]);
 582}
 583
 584void helper_msa_bclr_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
 585{
 586    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 587    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 588    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 589
 590    pwd->d[0]  = msa_bclr_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
 591    pwd->d[1]  = msa_bclr_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
 592}
 593
 594static inline int64_t msa_bneg_df(uint32_t df, int64_t arg1, int64_t arg2)
 595{
 596    int32_t b_arg2 = BIT_POSITION(arg2, df);
 597    return UNSIGNED(arg1 ^ (1LL << b_arg2), df);
 598}
 599
 600void helper_msa_bneg_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
 601{
 602    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 603    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 604    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 605
 606    pwd->b[0]  = msa_bneg_df(DF_BYTE, pws->b[0],  pwt->b[0]);
 607    pwd->b[1]  = msa_bneg_df(DF_BYTE, pws->b[1],  pwt->b[1]);
 608    pwd->b[2]  = msa_bneg_df(DF_BYTE, pws->b[2],  pwt->b[2]);
 609    pwd->b[3]  = msa_bneg_df(DF_BYTE, pws->b[3],  pwt->b[3]);
 610    pwd->b[4]  = msa_bneg_df(DF_BYTE, pws->b[4],  pwt->b[4]);
 611    pwd->b[5]  = msa_bneg_df(DF_BYTE, pws->b[5],  pwt->b[5]);
 612    pwd->b[6]  = msa_bneg_df(DF_BYTE, pws->b[6],  pwt->b[6]);
 613    pwd->b[7]  = msa_bneg_df(DF_BYTE, pws->b[7],  pwt->b[7]);
 614    pwd->b[8]  = msa_bneg_df(DF_BYTE, pws->b[8],  pwt->b[8]);
 615    pwd->b[9]  = msa_bneg_df(DF_BYTE, pws->b[9],  pwt->b[9]);
 616    pwd->b[10] = msa_bneg_df(DF_BYTE, pws->b[10], pwt->b[10]);
 617    pwd->b[11] = msa_bneg_df(DF_BYTE, pws->b[11], pwt->b[11]);
 618    pwd->b[12] = msa_bneg_df(DF_BYTE, pws->b[12], pwt->b[12]);
 619    pwd->b[13] = msa_bneg_df(DF_BYTE, pws->b[13], pwt->b[13]);
 620    pwd->b[14] = msa_bneg_df(DF_BYTE, pws->b[14], pwt->b[14]);
 621    pwd->b[15] = msa_bneg_df(DF_BYTE, pws->b[15], pwt->b[15]);
 622}
 623
 624void helper_msa_bneg_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
 625{
 626    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 627    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 628    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 629
 630    pwd->h[0]  = msa_bneg_df(DF_HALF, pws->h[0],  pwt->h[0]);
 631    pwd->h[1]  = msa_bneg_df(DF_HALF, pws->h[1],  pwt->h[1]);
 632    pwd->h[2]  = msa_bneg_df(DF_HALF, pws->h[2],  pwt->h[2]);
 633    pwd->h[3]  = msa_bneg_df(DF_HALF, pws->h[3],  pwt->h[3]);
 634    pwd->h[4]  = msa_bneg_df(DF_HALF, pws->h[4],  pwt->h[4]);
 635    pwd->h[5]  = msa_bneg_df(DF_HALF, pws->h[5],  pwt->h[5]);
 636    pwd->h[6]  = msa_bneg_df(DF_HALF, pws->h[6],  pwt->h[6]);
 637    pwd->h[7]  = msa_bneg_df(DF_HALF, pws->h[7],  pwt->h[7]);
 638}
 639
 640void helper_msa_bneg_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
 641{
 642    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 643    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 644    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 645
 646    pwd->w[0]  = msa_bneg_df(DF_WORD, pws->w[0],  pwt->w[0]);
 647    pwd->w[1]  = msa_bneg_df(DF_WORD, pws->w[1],  pwt->w[1]);
 648    pwd->w[2]  = msa_bneg_df(DF_WORD, pws->w[2],  pwt->w[2]);
 649    pwd->w[3]  = msa_bneg_df(DF_WORD, pws->w[3],  pwt->w[3]);
 650}
 651
 652void helper_msa_bneg_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
 653{
 654    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 655    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 656    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 657
 658    pwd->d[0]  = msa_bneg_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
 659    pwd->d[1]  = msa_bneg_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
 660}
 661
 662static inline int64_t msa_bset_df(uint32_t df, int64_t arg1,
 663        int64_t arg2)
 664{
 665    int32_t b_arg2 = BIT_POSITION(arg2, df);
 666    return UNSIGNED(arg1 | (1LL << b_arg2), df);
 667}
 668
 669void helper_msa_bset_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
 670{
 671    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 672    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 673    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 674
 675    pwd->b[0]  = msa_bset_df(DF_BYTE, pws->b[0],  pwt->b[0]);
 676    pwd->b[1]  = msa_bset_df(DF_BYTE, pws->b[1],  pwt->b[1]);
 677    pwd->b[2]  = msa_bset_df(DF_BYTE, pws->b[2],  pwt->b[2]);
 678    pwd->b[3]  = msa_bset_df(DF_BYTE, pws->b[3],  pwt->b[3]);
 679    pwd->b[4]  = msa_bset_df(DF_BYTE, pws->b[4],  pwt->b[4]);
 680    pwd->b[5]  = msa_bset_df(DF_BYTE, pws->b[5],  pwt->b[5]);
 681    pwd->b[6]  = msa_bset_df(DF_BYTE, pws->b[6],  pwt->b[6]);
 682    pwd->b[7]  = msa_bset_df(DF_BYTE, pws->b[7],  pwt->b[7]);
 683    pwd->b[8]  = msa_bset_df(DF_BYTE, pws->b[8],  pwt->b[8]);
 684    pwd->b[9]  = msa_bset_df(DF_BYTE, pws->b[9],  pwt->b[9]);
 685    pwd->b[10] = msa_bset_df(DF_BYTE, pws->b[10], pwt->b[10]);
 686    pwd->b[11] = msa_bset_df(DF_BYTE, pws->b[11], pwt->b[11]);
 687    pwd->b[12] = msa_bset_df(DF_BYTE, pws->b[12], pwt->b[12]);
 688    pwd->b[13] = msa_bset_df(DF_BYTE, pws->b[13], pwt->b[13]);
 689    pwd->b[14] = msa_bset_df(DF_BYTE, pws->b[14], pwt->b[14]);
 690    pwd->b[15] = msa_bset_df(DF_BYTE, pws->b[15], pwt->b[15]);
 691}
 692
 693void helper_msa_bset_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
 694{
 695    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 696    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 697    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 698
 699    pwd->h[0]  = msa_bset_df(DF_HALF, pws->h[0],  pwt->h[0]);
 700    pwd->h[1]  = msa_bset_df(DF_HALF, pws->h[1],  pwt->h[1]);
 701    pwd->h[2]  = msa_bset_df(DF_HALF, pws->h[2],  pwt->h[2]);
 702    pwd->h[3]  = msa_bset_df(DF_HALF, pws->h[3],  pwt->h[3]);
 703    pwd->h[4]  = msa_bset_df(DF_HALF, pws->h[4],  pwt->h[4]);
 704    pwd->h[5]  = msa_bset_df(DF_HALF, pws->h[5],  pwt->h[5]);
 705    pwd->h[6]  = msa_bset_df(DF_HALF, pws->h[6],  pwt->h[6]);
 706    pwd->h[7]  = msa_bset_df(DF_HALF, pws->h[7],  pwt->h[7]);
 707}
 708
 709void helper_msa_bset_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
 710{
 711    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 712    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 713    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 714
 715    pwd->w[0]  = msa_bset_df(DF_WORD, pws->w[0],  pwt->w[0]);
 716    pwd->w[1]  = msa_bset_df(DF_WORD, pws->w[1],  pwt->w[1]);
 717    pwd->w[2]  = msa_bset_df(DF_WORD, pws->w[2],  pwt->w[2]);
 718    pwd->w[3]  = msa_bset_df(DF_WORD, pws->w[3],  pwt->w[3]);
 719}
 720
 721void helper_msa_bset_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
 722{
 723    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 724    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 725    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 726
 727    pwd->d[0]  = msa_bset_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
 728    pwd->d[1]  = msa_bset_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
 729}
 730
 731
 732/*
 733 * Fixed Multiply
 734 * --------------
 735 *
 736 * +---------------+----------------------------------------------------------+
 737 * | MADD_Q.H      | Vector Fixed-Point Multiply and Add (halfword)           |
 738 * | MADD_Q.W      | Vector Fixed-Point Multiply and Add (word)               |
 739 * | MADDR_Q.H     | Vector Fixed-Point Multiply and Add Rounded (halfword)   |
 740 * | MADDR_Q.W     | Vector Fixed-Point Multiply and Add Rounded (word)       |
 741 * | MSUB_Q.H      | Vector Fixed-Point Multiply and Subtr. (halfword)        |
 742 * | MSUB_Q.W      | Vector Fixed-Point Multiply and Subtr. (word)            |
 743 * | MSUBR_Q.H     | Vector Fixed-Point Multiply and Subtr. Rounded (halfword)|
 744 * | MSUBR_Q.W     | Vector Fixed-Point Multiply and Subtr. Rounded (word)    |
 745 * | MUL_Q.H       | Vector Fixed-Point Multiply (halfword)                   |
 746 * | MUL_Q.W       | Vector Fixed-Point Multiply (word)                       |
 747 * | MULR_Q.H      | Vector Fixed-Point Multiply Rounded (halfword)           |
 748 * | MULR_Q.W      | Vector Fixed-Point Multiply Rounded (word)               |
 749 * +---------------+----------------------------------------------------------+
 750 */
 751
 752/* TODO: insert Fixed Multiply group helpers here */
 753
 754
 755/*
 756 * Float Max Min
 757 * -------------
 758 *
 759 * +---------------+----------------------------------------------------------+
 760 * | FMAX_A.W      | Vector Floating-Point Maximum (Absolute) (word)          |
 761 * | FMAX_A.D      | Vector Floating-Point Maximum (Absolute) (doubleword)    |
 762 * | FMAX.W        | Vector Floating-Point Maximum (word)                     |
 763 * | FMAX.D        | Vector Floating-Point Maximum (doubleword)               |
 764 * | FMIN_A.W      | Vector Floating-Point Minimum (Absolute) (word)          |
 765 * | FMIN_A.D      | Vector Floating-Point Minimum (Absolute) (doubleword)    |
 766 * | FMIN.W        | Vector Floating-Point Minimum (word)                     |
 767 * | FMIN.D        | Vector Floating-Point Minimum (doubleword)               |
 768 * +---------------+----------------------------------------------------------+
 769 */
 770
 771/* TODO: insert Float Max Min group helpers here */
 772
 773
 774/*
 775 * Int Add
 776 * -------
 777 *
 778 * +---------------+----------------------------------------------------------+
 779 * | ADD_A.B       | Vector Add Absolute Values (byte)                        |
 780 * | ADD_A.H       | Vector Add Absolute Values (halfword)                    |
 781 * | ADD_A.W       | Vector Add Absolute Values (word)                        |
 782 * | ADD_A.D       | Vector Add Absolute Values (doubleword)                  |
 783 * | ADDS_A.B      | Vector Signed Saturated Add (of Absolute) (byte)         |
 784 * | ADDS_A.H      | Vector Signed Saturated Add (of Absolute) (halfword)     |
 785 * | ADDS_A.W      | Vector Signed Saturated Add (of Absolute) (word)         |
 786 * | ADDS_A.D      | Vector Signed Saturated Add (of Absolute) (doubleword)   |
 787 * | ADDS_S.B      | Vector Signed Saturated Add (of Signed) (byte)           |
 788 * | ADDS_S.H      | Vector Signed Saturated Add (of Signed) (halfword)       |
 789 * | ADDS_S.W      | Vector Signed Saturated Add (of Signed) (word)           |
 790 * | ADDS_S.D      | Vector Signed Saturated Add (of Signed) (doubleword)     |
 791 * | ADDS_U.B      | Vector Unsigned Saturated Add (of Unsigned) (byte)       |
 792 * | ADDS_U.H      | Vector Unsigned Saturated Add (of Unsigned) (halfword)   |
 793 * | ADDS_U.W      | Vector Unsigned Saturated Add (of Unsigned) (word)       |
 794 * | ADDS_U.D      | Vector Unsigned Saturated Add (of Unsigned) (doubleword) |
 795 * | ADDV.B        | Vector Add (byte)                                        |
 796 * | ADDV.H        | Vector Add (halfword)                                    |
 797 * | ADDV.W        | Vector Add (word)                                        |
 798 * | ADDV.D        | Vector Add (doubleword)                                  |
 799 * | HADD_S.H      | Vector Signed Horizontal Add (halfword)                  |
 800 * | HADD_S.W      | Vector Signed Horizontal Add (word)                      |
 801 * | HADD_S.D      | Vector Signed Horizontal Add (doubleword)                |
 802 * | HADD_U.H      | Vector Unigned Horizontal Add (halfword)                 |
 803 * | HADD_U.W      | Vector Unigned Horizontal Add (word)                     |
 804 * | HADD_U.D      | Vector Unigned Horizontal Add (doubleword)               |
 805 * +---------------+----------------------------------------------------------+
 806 */
 807
 808
 809static inline int64_t msa_add_a_df(uint32_t df, int64_t arg1, int64_t arg2)
 810{
 811    uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
 812    uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
 813    return abs_arg1 + abs_arg2;
 814}
 815
 816void helper_msa_add_a_b(CPUMIPSState *env,
 817                        uint32_t wd, uint32_t ws, uint32_t wt)
 818{
 819    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 820    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 821    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 822
 823    pwd->b[0]  = msa_add_a_df(DF_BYTE, pws->b[0],  pwt->b[0]);
 824    pwd->b[1]  = msa_add_a_df(DF_BYTE, pws->b[1],  pwt->b[1]);
 825    pwd->b[2]  = msa_add_a_df(DF_BYTE, pws->b[2],  pwt->b[2]);
 826    pwd->b[3]  = msa_add_a_df(DF_BYTE, pws->b[3],  pwt->b[3]);
 827    pwd->b[4]  = msa_add_a_df(DF_BYTE, pws->b[4],  pwt->b[4]);
 828    pwd->b[5]  = msa_add_a_df(DF_BYTE, pws->b[5],  pwt->b[5]);
 829    pwd->b[6]  = msa_add_a_df(DF_BYTE, pws->b[6],  pwt->b[6]);
 830    pwd->b[7]  = msa_add_a_df(DF_BYTE, pws->b[7],  pwt->b[7]);
 831    pwd->b[8]  = msa_add_a_df(DF_BYTE, pws->b[8],  pwt->b[8]);
 832    pwd->b[9]  = msa_add_a_df(DF_BYTE, pws->b[9],  pwt->b[9]);
 833    pwd->b[10] = msa_add_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
 834    pwd->b[11] = msa_add_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
 835    pwd->b[12] = msa_add_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
 836    pwd->b[13] = msa_add_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
 837    pwd->b[14] = msa_add_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
 838    pwd->b[15] = msa_add_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
 839}
 840
 841void helper_msa_add_a_h(CPUMIPSState *env,
 842                        uint32_t wd, uint32_t ws, uint32_t wt)
 843{
 844    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 845    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 846    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 847
 848    pwd->h[0]  = msa_add_a_df(DF_HALF, pws->h[0],  pwt->h[0]);
 849    pwd->h[1]  = msa_add_a_df(DF_HALF, pws->h[1],  pwt->h[1]);
 850    pwd->h[2]  = msa_add_a_df(DF_HALF, pws->h[2],  pwt->h[2]);
 851    pwd->h[3]  = msa_add_a_df(DF_HALF, pws->h[3],  pwt->h[3]);
 852    pwd->h[4]  = msa_add_a_df(DF_HALF, pws->h[4],  pwt->h[4]);
 853    pwd->h[5]  = msa_add_a_df(DF_HALF, pws->h[5],  pwt->h[5]);
 854    pwd->h[6]  = msa_add_a_df(DF_HALF, pws->h[6],  pwt->h[6]);
 855    pwd->h[7]  = msa_add_a_df(DF_HALF, pws->h[7],  pwt->h[7]);
 856}
 857
 858void helper_msa_add_a_w(CPUMIPSState *env,
 859                        uint32_t wd, uint32_t ws, uint32_t wt)
 860{
 861    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 862    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 863    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 864
 865    pwd->w[0]  = msa_add_a_df(DF_WORD, pws->w[0],  pwt->w[0]);
 866    pwd->w[1]  = msa_add_a_df(DF_WORD, pws->w[1],  pwt->w[1]);
 867    pwd->w[2]  = msa_add_a_df(DF_WORD, pws->w[2],  pwt->w[2]);
 868    pwd->w[3]  = msa_add_a_df(DF_WORD, pws->w[3],  pwt->w[3]);
 869}
 870
 871void helper_msa_add_a_d(CPUMIPSState *env,
 872                        uint32_t wd, uint32_t ws, uint32_t wt)
 873{
 874    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 875    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 876    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 877
 878    pwd->d[0]  = msa_add_a_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
 879    pwd->d[1]  = msa_add_a_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
 880}
 881
 882
 883static inline int64_t msa_adds_a_df(uint32_t df, int64_t arg1, int64_t arg2)
 884{
 885    uint64_t max_int = (uint64_t)DF_MAX_INT(df);
 886    uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
 887    uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
 888    if (abs_arg1 > max_int || abs_arg2 > max_int) {
 889        return (int64_t)max_int;
 890    } else {
 891        return (abs_arg1 < max_int - abs_arg2) ? abs_arg1 + abs_arg2 : max_int;
 892    }
 893}
 894
 895void helper_msa_adds_a_b(CPUMIPSState *env,
 896                         uint32_t wd, uint32_t ws, uint32_t wt)
 897{
 898    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 899    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 900    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 901
 902    pwd->b[0]  = msa_adds_a_df(DF_BYTE, pws->b[0],  pwt->b[0]);
 903    pwd->b[1]  = msa_adds_a_df(DF_BYTE, pws->b[1],  pwt->b[1]);
 904    pwd->b[2]  = msa_adds_a_df(DF_BYTE, pws->b[2],  pwt->b[2]);
 905    pwd->b[3]  = msa_adds_a_df(DF_BYTE, pws->b[3],  pwt->b[3]);
 906    pwd->b[4]  = msa_adds_a_df(DF_BYTE, pws->b[4],  pwt->b[4]);
 907    pwd->b[5]  = msa_adds_a_df(DF_BYTE, pws->b[5],  pwt->b[5]);
 908    pwd->b[6]  = msa_adds_a_df(DF_BYTE, pws->b[6],  pwt->b[6]);
 909    pwd->b[7]  = msa_adds_a_df(DF_BYTE, pws->b[7],  pwt->b[7]);
 910    pwd->b[8]  = msa_adds_a_df(DF_BYTE, pws->b[8],  pwt->b[8]);
 911    pwd->b[9]  = msa_adds_a_df(DF_BYTE, pws->b[9],  pwt->b[9]);
 912    pwd->b[10] = msa_adds_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
 913    pwd->b[11] = msa_adds_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
 914    pwd->b[12] = msa_adds_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
 915    pwd->b[13] = msa_adds_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
 916    pwd->b[14] = msa_adds_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
 917    pwd->b[15] = msa_adds_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
 918}
 919
 920void helper_msa_adds_a_h(CPUMIPSState *env,
 921                         uint32_t wd, uint32_t ws, uint32_t wt)
 922{
 923    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 924    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 925    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 926
 927    pwd->h[0]  = msa_adds_a_df(DF_HALF, pws->h[0],  pwt->h[0]);
 928    pwd->h[1]  = msa_adds_a_df(DF_HALF, pws->h[1],  pwt->h[1]);
 929    pwd->h[2]  = msa_adds_a_df(DF_HALF, pws->h[2],  pwt->h[2]);
 930    pwd->h[3]  = msa_adds_a_df(DF_HALF, pws->h[3],  pwt->h[3]);
 931    pwd->h[4]  = msa_adds_a_df(DF_HALF, pws->h[4],  pwt->h[4]);
 932    pwd->h[5]  = msa_adds_a_df(DF_HALF, pws->h[5],  pwt->h[5]);
 933    pwd->h[6]  = msa_adds_a_df(DF_HALF, pws->h[6],  pwt->h[6]);
 934    pwd->h[7]  = msa_adds_a_df(DF_HALF, pws->h[7],  pwt->h[7]);
 935}
 936
 937void helper_msa_adds_a_w(CPUMIPSState *env,
 938                         uint32_t wd, uint32_t ws, uint32_t wt)
 939{
 940    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 941    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 942    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 943
 944    pwd->w[0]  = msa_adds_a_df(DF_WORD, pws->w[0],  pwt->w[0]);
 945    pwd->w[1]  = msa_adds_a_df(DF_WORD, pws->w[1],  pwt->w[1]);
 946    pwd->w[2]  = msa_adds_a_df(DF_WORD, pws->w[2],  pwt->w[2]);
 947    pwd->w[3]  = msa_adds_a_df(DF_WORD, pws->w[3],  pwt->w[3]);
 948}
 949
 950void helper_msa_adds_a_d(CPUMIPSState *env,
 951                         uint32_t wd, uint32_t ws, uint32_t wt)
 952{
 953    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 954    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 955    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 956
 957    pwd->d[0]  = msa_adds_a_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
 958    pwd->d[1]  = msa_adds_a_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
 959}
 960
 961
 962static inline int64_t msa_adds_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 963{
 964    int64_t max_int = DF_MAX_INT(df);
 965    int64_t min_int = DF_MIN_INT(df);
 966    if (arg1 < 0) {
 967        return (min_int - arg1 < arg2) ? arg1 + arg2 : min_int;
 968    } else {
 969        return (arg2 < max_int - arg1) ? arg1 + arg2 : max_int;
 970    }
 971}
 972
 973void helper_msa_adds_s_b(CPUMIPSState *env,
 974                         uint32_t wd, uint32_t ws, uint32_t wt)
 975{
 976    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
 977    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
 978    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
 979
 980    pwd->b[0]  = msa_adds_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
 981    pwd->b[1]  = msa_adds_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
 982    pwd->b[2]  = msa_adds_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
 983    pwd->b[3]  = msa_adds_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
 984    pwd->b[4]  = msa_adds_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
 985    pwd->b[5]  = msa_adds_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
 986    pwd->b[6]  = msa_adds_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
 987    pwd->b[7]  = msa_adds_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
 988    pwd->b[8]  = msa_adds_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
 989    pwd->b[9]  = msa_adds_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
 990    pwd->b[10] = msa_adds_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
 991    pwd->b[11] = msa_adds_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
 992    pwd->b[12] = msa_adds_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
 993    pwd->b[13] = msa_adds_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
 994    pwd->b[14] = msa_adds_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
 995    pwd->b[15] = msa_adds_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
 996}
 997
 998void helper_msa_adds_s_h(CPUMIPSState *env,
 999                         uint32_t wd, uint32_t ws, uint32_t wt)
1000{
1001    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1002    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1003    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1004
1005    pwd->h[0]  = msa_adds_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
1006    pwd->h[1]  = msa_adds_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
1007    pwd->h[2]  = msa_adds_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
1008    pwd->h[3]  = msa_adds_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
1009    pwd->h[4]  = msa_adds_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
1010    pwd->h[5]  = msa_adds_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
1011    pwd->h[6]  = msa_adds_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
1012    pwd->h[7]  = msa_adds_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
1013}
1014
1015void helper_msa_adds_s_w(CPUMIPSState *env,
1016                         uint32_t wd, uint32_t ws, uint32_t wt)
1017{
1018    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1019    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1020    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1021
1022    pwd->w[0]  = msa_adds_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
1023    pwd->w[1]  = msa_adds_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
1024    pwd->w[2]  = msa_adds_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
1025    pwd->w[3]  = msa_adds_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
1026}
1027
1028void helper_msa_adds_s_d(CPUMIPSState *env,
1029                         uint32_t wd, uint32_t ws, uint32_t wt)
1030{
1031    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1032    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1033    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1034
1035    pwd->d[0]  = msa_adds_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1036    pwd->d[1]  = msa_adds_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1037}
1038
1039
1040static inline uint64_t msa_adds_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1041{
1042    uint64_t max_uint = DF_MAX_UINT(df);
1043    uint64_t u_arg1 = UNSIGNED(arg1, df);
1044    uint64_t u_arg2 = UNSIGNED(arg2, df);
1045    return (u_arg1 < max_uint - u_arg2) ? u_arg1 + u_arg2 : max_uint;
1046}
1047
1048void helper_msa_adds_u_b(CPUMIPSState *env,
1049                         uint32_t wd, uint32_t ws, uint32_t wt)
1050{
1051    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1052    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1053    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1054
1055    pwd->b[0]  = msa_adds_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1056    pwd->b[1]  = msa_adds_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1057    pwd->b[2]  = msa_adds_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1058    pwd->b[3]  = msa_adds_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1059    pwd->b[4]  = msa_adds_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1060    pwd->b[5]  = msa_adds_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1061    pwd->b[6]  = msa_adds_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1062    pwd->b[7]  = msa_adds_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1063    pwd->b[8]  = msa_adds_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1064    pwd->b[9]  = msa_adds_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1065    pwd->b[10] = msa_adds_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1066    pwd->b[11] = msa_adds_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1067    pwd->b[12] = msa_adds_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1068    pwd->b[13] = msa_adds_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1069    pwd->b[14] = msa_adds_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1070    pwd->b[15] = msa_adds_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1071}
1072
1073void helper_msa_adds_u_h(CPUMIPSState *env,
1074                         uint32_t wd, uint32_t ws, uint32_t wt)
1075{
1076    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1077    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1078    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1079
1080    pwd->h[0]  = msa_adds_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
1081    pwd->h[1]  = msa_adds_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
1082    pwd->h[2]  = msa_adds_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
1083    pwd->h[3]  = msa_adds_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
1084    pwd->h[4]  = msa_adds_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
1085    pwd->h[5]  = msa_adds_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
1086    pwd->h[6]  = msa_adds_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
1087    pwd->h[7]  = msa_adds_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
1088}
1089
1090void helper_msa_adds_u_w(CPUMIPSState *env,
1091                         uint32_t wd, uint32_t ws, uint32_t wt)
1092{
1093    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1094    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1095    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1096
1097    pwd->w[0]  = msa_adds_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
1098    pwd->w[1]  = msa_adds_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
1099    pwd->w[2]  = msa_adds_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
1100    pwd->w[3]  = msa_adds_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
1101}
1102
1103void helper_msa_adds_u_d(CPUMIPSState *env,
1104                         uint32_t wd, uint32_t ws, uint32_t wt)
1105{
1106    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1107    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1108    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1109
1110    pwd->d[0]  = msa_adds_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1111    pwd->d[1]  = msa_adds_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1112}
1113
1114
1115static inline int64_t msa_addv_df(uint32_t df, int64_t arg1, int64_t arg2)
1116{
1117    return arg1 + arg2;
1118}
1119
1120void helper_msa_addv_b(CPUMIPSState *env,
1121                       uint32_t wd, uint32_t ws, uint32_t wt)
1122{
1123    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1124    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1125    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1126
1127    pwd->b[0]  = msa_addv_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1128    pwd->b[1]  = msa_addv_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1129    pwd->b[2]  = msa_addv_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1130    pwd->b[3]  = msa_addv_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1131    pwd->b[4]  = msa_addv_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1132    pwd->b[5]  = msa_addv_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1133    pwd->b[6]  = msa_addv_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1134    pwd->b[7]  = msa_addv_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1135    pwd->b[8]  = msa_addv_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1136    pwd->b[9]  = msa_addv_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1137    pwd->b[10] = msa_addv_df(DF_BYTE, pws->b[10], pwt->b[10]);
1138    pwd->b[11] = msa_addv_df(DF_BYTE, pws->b[11], pwt->b[11]);
1139    pwd->b[12] = msa_addv_df(DF_BYTE, pws->b[12], pwt->b[12]);
1140    pwd->b[13] = msa_addv_df(DF_BYTE, pws->b[13], pwt->b[13]);
1141    pwd->b[14] = msa_addv_df(DF_BYTE, pws->b[14], pwt->b[14]);
1142    pwd->b[15] = msa_addv_df(DF_BYTE, pws->b[15], pwt->b[15]);
1143}
1144
1145void helper_msa_addv_h(CPUMIPSState *env,
1146                       uint32_t wd, uint32_t ws, uint32_t wt)
1147{
1148    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1149    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1150    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1151
1152    pwd->h[0]  = msa_addv_df(DF_HALF, pws->h[0],  pwt->h[0]);
1153    pwd->h[1]  = msa_addv_df(DF_HALF, pws->h[1],  pwt->h[1]);
1154    pwd->h[2]  = msa_addv_df(DF_HALF, pws->h[2],  pwt->h[2]);
1155    pwd->h[3]  = msa_addv_df(DF_HALF, pws->h[3],  pwt->h[3]);
1156    pwd->h[4]  = msa_addv_df(DF_HALF, pws->h[4],  pwt->h[4]);
1157    pwd->h[5]  = msa_addv_df(DF_HALF, pws->h[5],  pwt->h[5]);
1158    pwd->h[6]  = msa_addv_df(DF_HALF, pws->h[6],  pwt->h[6]);
1159    pwd->h[7]  = msa_addv_df(DF_HALF, pws->h[7],  pwt->h[7]);
1160}
1161
1162void helper_msa_addv_w(CPUMIPSState *env,
1163                       uint32_t wd, uint32_t ws, uint32_t wt)
1164{
1165    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1166    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1167    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1168
1169    pwd->w[0]  = msa_addv_df(DF_WORD, pws->w[0],  pwt->w[0]);
1170    pwd->w[1]  = msa_addv_df(DF_WORD, pws->w[1],  pwt->w[1]);
1171    pwd->w[2]  = msa_addv_df(DF_WORD, pws->w[2],  pwt->w[2]);
1172    pwd->w[3]  = msa_addv_df(DF_WORD, pws->w[3],  pwt->w[3]);
1173}
1174
1175void helper_msa_addv_d(CPUMIPSState *env,
1176                       uint32_t wd, uint32_t ws, uint32_t wt)
1177{
1178    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1179    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1180    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1181
1182    pwd->d[0]  = msa_addv_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1183    pwd->d[1]  = msa_addv_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1184}
1185
1186
1187#define SIGNED_EVEN(a, df) \
1188        ((((int64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2))
1189
1190#define UNSIGNED_EVEN(a, df) \
1191        ((((uint64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2))
1192
1193#define SIGNED_ODD(a, df) \
1194        ((((int64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2))
1195
1196#define UNSIGNED_ODD(a, df) \
1197        ((((uint64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2))
1198
1199
1200static inline int64_t msa_hadd_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1201{
1202    return SIGNED_ODD(arg1, df) + SIGNED_EVEN(arg2, df);
1203}
1204
1205void helper_msa_hadd_s_h(CPUMIPSState *env,
1206                         uint32_t wd, uint32_t ws, uint32_t wt)
1207{
1208    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1209    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1210    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1211
1212    pwd->h[0]  = msa_hadd_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
1213    pwd->h[1]  = msa_hadd_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
1214    pwd->h[2]  = msa_hadd_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
1215    pwd->h[3]  = msa_hadd_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
1216    pwd->h[4]  = msa_hadd_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
1217    pwd->h[5]  = msa_hadd_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
1218    pwd->h[6]  = msa_hadd_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
1219    pwd->h[7]  = msa_hadd_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
1220}
1221
1222void helper_msa_hadd_s_w(CPUMIPSState *env,
1223                         uint32_t wd, uint32_t ws, uint32_t wt)
1224{
1225    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1226    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1227    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1228
1229    pwd->w[0]  = msa_hadd_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
1230    pwd->w[1]  = msa_hadd_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
1231    pwd->w[2]  = msa_hadd_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
1232    pwd->w[3]  = msa_hadd_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
1233}
1234
1235void helper_msa_hadd_s_d(CPUMIPSState *env,
1236                         uint32_t wd, uint32_t ws, uint32_t wt)
1237{
1238    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1239    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1240    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1241
1242    pwd->d[0]  = msa_hadd_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1243    pwd->d[1]  = msa_hadd_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1244}
1245
1246
1247static inline int64_t msa_hadd_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1248{
1249    return UNSIGNED_ODD(arg1, df) + UNSIGNED_EVEN(arg2, df);
1250}
1251
1252void helper_msa_hadd_u_h(CPUMIPSState *env,
1253                         uint32_t wd, uint32_t ws, uint32_t wt)
1254{
1255    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1256    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1257    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1258
1259    pwd->h[0]  = msa_hadd_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
1260    pwd->h[1]  = msa_hadd_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
1261    pwd->h[2]  = msa_hadd_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
1262    pwd->h[3]  = msa_hadd_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
1263    pwd->h[4]  = msa_hadd_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
1264    pwd->h[5]  = msa_hadd_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
1265    pwd->h[6]  = msa_hadd_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
1266    pwd->h[7]  = msa_hadd_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
1267}
1268
1269void helper_msa_hadd_u_w(CPUMIPSState *env,
1270                         uint32_t wd, uint32_t ws, uint32_t wt)
1271{
1272    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1273    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1274    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1275
1276    pwd->w[0]  = msa_hadd_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
1277    pwd->w[1]  = msa_hadd_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
1278    pwd->w[2]  = msa_hadd_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
1279    pwd->w[3]  = msa_hadd_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
1280}
1281
1282void helper_msa_hadd_u_d(CPUMIPSState *env,
1283                         uint32_t wd, uint32_t ws, uint32_t wt)
1284{
1285    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1286    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1287    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1288
1289    pwd->d[0]  = msa_hadd_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1290    pwd->d[1]  = msa_hadd_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1291}
1292
1293
1294/*
1295 * Int Average
1296 * -----------
1297 *
1298 * +---------------+----------------------------------------------------------+
1299 * | AVE_S.B       | Vector Signed Average (byte)                             |
1300 * | AVE_S.H       | Vector Signed Average (halfword)                         |
1301 * | AVE_S.W       | Vector Signed Average (word)                             |
1302 * | AVE_S.D       | Vector Signed Average (doubleword)                       |
1303 * | AVE_U.B       | Vector Unsigned Average (byte)                           |
1304 * | AVE_U.H       | Vector Unsigned Average (halfword)                       |
1305 * | AVE_U.W       | Vector Unsigned Average (word)                           |
1306 * | AVE_U.D       | Vector Unsigned Average (doubleword)                     |
1307 * | AVER_S.B      | Vector Signed Average Rounded (byte)                     |
1308 * | AVER_S.H      | Vector Signed Average Rounded (halfword)                 |
1309 * | AVER_S.W      | Vector Signed Average Rounded (word)                     |
1310 * | AVER_S.D      | Vector Signed Average Rounded (doubleword)               |
1311 * | AVER_U.B      | Vector Unsigned Average Rounded (byte)                   |
1312 * | AVER_U.H      | Vector Unsigned Average Rounded (halfword)               |
1313 * | AVER_U.W      | Vector Unsigned Average Rounded (word)                   |
1314 * | AVER_U.D      | Vector Unsigned Average Rounded (doubleword)             |
1315 * +---------------+----------------------------------------------------------+
1316 */
1317
1318static inline int64_t msa_ave_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1319{
1320    /* signed shift */
1321    return (arg1 >> 1) + (arg2 >> 1) + (arg1 & arg2 & 1);
1322}
1323
1324void helper_msa_ave_s_b(CPUMIPSState *env,
1325                        uint32_t wd, uint32_t ws, uint32_t wt)
1326{
1327    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1328    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1329    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1330
1331    pwd->b[0]  = msa_ave_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1332    pwd->b[1]  = msa_ave_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1333    pwd->b[2]  = msa_ave_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1334    pwd->b[3]  = msa_ave_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1335    pwd->b[4]  = msa_ave_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1336    pwd->b[5]  = msa_ave_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1337    pwd->b[6]  = msa_ave_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1338    pwd->b[7]  = msa_ave_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1339    pwd->b[8]  = msa_ave_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1340    pwd->b[9]  = msa_ave_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1341    pwd->b[10] = msa_ave_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
1342    pwd->b[11] = msa_ave_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
1343    pwd->b[12] = msa_ave_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
1344    pwd->b[13] = msa_ave_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
1345    pwd->b[14] = msa_ave_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
1346    pwd->b[15] = msa_ave_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
1347}
1348
1349void helper_msa_ave_s_h(CPUMIPSState *env,
1350                        uint32_t wd, uint32_t ws, uint32_t wt)
1351{
1352    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1353    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1354    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1355
1356    pwd->h[0]  = msa_ave_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
1357    pwd->h[1]  = msa_ave_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
1358    pwd->h[2]  = msa_ave_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
1359    pwd->h[3]  = msa_ave_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
1360    pwd->h[4]  = msa_ave_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
1361    pwd->h[5]  = msa_ave_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
1362    pwd->h[6]  = msa_ave_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
1363    pwd->h[7]  = msa_ave_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
1364}
1365
1366void helper_msa_ave_s_w(CPUMIPSState *env,
1367                        uint32_t wd, uint32_t ws, uint32_t wt)
1368{
1369    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1370    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1371    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1372
1373    pwd->w[0]  = msa_ave_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
1374    pwd->w[1]  = msa_ave_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
1375    pwd->w[2]  = msa_ave_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
1376    pwd->w[3]  = msa_ave_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
1377}
1378
1379void helper_msa_ave_s_d(CPUMIPSState *env,
1380                        uint32_t wd, uint32_t ws, uint32_t wt)
1381{
1382    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1383    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1384    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1385
1386    pwd->d[0]  = msa_ave_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1387    pwd->d[1]  = msa_ave_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1388}
1389
1390static inline uint64_t msa_ave_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1391{
1392    uint64_t u_arg1 = UNSIGNED(arg1, df);
1393    uint64_t u_arg2 = UNSIGNED(arg2, df);
1394    /* unsigned shift */
1395    return (u_arg1 >> 1) + (u_arg2 >> 1) + (u_arg1 & u_arg2 & 1);
1396}
1397
1398void helper_msa_ave_u_b(CPUMIPSState *env,
1399                        uint32_t wd, uint32_t ws, uint32_t wt)
1400{
1401    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1402    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1403    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1404
1405    pwd->b[0]  = msa_ave_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1406    pwd->b[1]  = msa_ave_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1407    pwd->b[2]  = msa_ave_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1408    pwd->b[3]  = msa_ave_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1409    pwd->b[4]  = msa_ave_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1410    pwd->b[5]  = msa_ave_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1411    pwd->b[6]  = msa_ave_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1412    pwd->b[7]  = msa_ave_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1413    pwd->b[8]  = msa_ave_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1414    pwd->b[9]  = msa_ave_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1415    pwd->b[10] = msa_ave_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1416    pwd->b[11] = msa_ave_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1417    pwd->b[12] = msa_ave_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1418    pwd->b[13] = msa_ave_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1419    pwd->b[14] = msa_ave_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1420    pwd->b[15] = msa_ave_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1421}
1422
1423void helper_msa_ave_u_h(CPUMIPSState *env,
1424                        uint32_t wd, uint32_t ws, uint32_t wt)
1425{
1426    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1427    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1428    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1429
1430    pwd->h[0]  = msa_ave_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
1431    pwd->h[1]  = msa_ave_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
1432    pwd->h[2]  = msa_ave_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
1433    pwd->h[3]  = msa_ave_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
1434    pwd->h[4]  = msa_ave_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
1435    pwd->h[5]  = msa_ave_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
1436    pwd->h[6]  = msa_ave_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
1437    pwd->h[7]  = msa_ave_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
1438}
1439
1440void helper_msa_ave_u_w(CPUMIPSState *env,
1441                        uint32_t wd, uint32_t ws, uint32_t wt)
1442{
1443    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1444    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1445    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1446
1447    pwd->w[0]  = msa_ave_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
1448    pwd->w[1]  = msa_ave_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
1449    pwd->w[2]  = msa_ave_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
1450    pwd->w[3]  = msa_ave_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
1451}
1452
1453void helper_msa_ave_u_d(CPUMIPSState *env,
1454                        uint32_t wd, uint32_t ws, uint32_t wt)
1455{
1456    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1457    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1458    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1459
1460    pwd->d[0]  = msa_ave_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1461    pwd->d[1]  = msa_ave_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1462}
1463
1464static inline int64_t msa_aver_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1465{
1466    /* signed shift */
1467    return (arg1 >> 1) + (arg2 >> 1) + ((arg1 | arg2) & 1);
1468}
1469
1470void helper_msa_aver_s_b(CPUMIPSState *env,
1471                         uint32_t wd, uint32_t ws, uint32_t wt)
1472{
1473    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1474    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1475    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1476
1477    pwd->b[0]  = msa_aver_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1478    pwd->b[1]  = msa_aver_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1479    pwd->b[2]  = msa_aver_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1480    pwd->b[3]  = msa_aver_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1481    pwd->b[4]  = msa_aver_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1482    pwd->b[5]  = msa_aver_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1483    pwd->b[6]  = msa_aver_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1484    pwd->b[7]  = msa_aver_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1485    pwd->b[8]  = msa_aver_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1486    pwd->b[9]  = msa_aver_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1487    pwd->b[10] = msa_aver_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
1488    pwd->b[11] = msa_aver_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
1489    pwd->b[12] = msa_aver_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
1490    pwd->b[13] = msa_aver_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
1491    pwd->b[14] = msa_aver_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
1492    pwd->b[15] = msa_aver_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
1493}
1494
1495void helper_msa_aver_s_h(CPUMIPSState *env,
1496                         uint32_t wd, uint32_t ws, uint32_t wt)
1497{
1498    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1499    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1500    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1501
1502    pwd->h[0]  = msa_aver_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
1503    pwd->h[1]  = msa_aver_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
1504    pwd->h[2]  = msa_aver_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
1505    pwd->h[3]  = msa_aver_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
1506    pwd->h[4]  = msa_aver_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
1507    pwd->h[5]  = msa_aver_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
1508    pwd->h[6]  = msa_aver_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
1509    pwd->h[7]  = msa_aver_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
1510}
1511
1512void helper_msa_aver_s_w(CPUMIPSState *env,
1513                         uint32_t wd, uint32_t ws, uint32_t wt)
1514{
1515    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1516    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1517    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1518
1519    pwd->w[0]  = msa_aver_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
1520    pwd->w[1]  = msa_aver_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
1521    pwd->w[2]  = msa_aver_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
1522    pwd->w[3]  = msa_aver_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
1523}
1524
1525void helper_msa_aver_s_d(CPUMIPSState *env,
1526                         uint32_t wd, uint32_t ws, uint32_t wt)
1527{
1528    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1529    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1530    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1531
1532    pwd->d[0]  = msa_aver_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1533    pwd->d[1]  = msa_aver_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1534}
1535
1536static inline uint64_t msa_aver_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1537{
1538    uint64_t u_arg1 = UNSIGNED(arg1, df);
1539    uint64_t u_arg2 = UNSIGNED(arg2, df);
1540    /* unsigned shift */
1541    return (u_arg1 >> 1) + (u_arg2 >> 1) + ((u_arg1 | u_arg2) & 1);
1542}
1543
1544void helper_msa_aver_u_b(CPUMIPSState *env,
1545                         uint32_t wd, uint32_t ws, uint32_t wt)
1546{
1547    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1548    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1549    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1550
1551    pwd->b[0]  = msa_aver_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1552    pwd->b[1]  = msa_aver_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1553    pwd->b[2]  = msa_aver_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1554    pwd->b[3]  = msa_aver_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1555    pwd->b[4]  = msa_aver_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1556    pwd->b[5]  = msa_aver_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1557    pwd->b[6]  = msa_aver_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1558    pwd->b[7]  = msa_aver_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1559    pwd->b[8]  = msa_aver_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1560    pwd->b[9]  = msa_aver_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1561    pwd->b[10] = msa_aver_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1562    pwd->b[11] = msa_aver_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1563    pwd->b[12] = msa_aver_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1564    pwd->b[13] = msa_aver_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1565    pwd->b[14] = msa_aver_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1566    pwd->b[15] = msa_aver_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1567}
1568
1569void helper_msa_aver_u_h(CPUMIPSState *env,
1570                         uint32_t wd, uint32_t ws, uint32_t wt)
1571{
1572    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1573    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1574    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1575
1576    pwd->h[0]  = msa_aver_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
1577    pwd->h[1]  = msa_aver_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
1578    pwd->h[2]  = msa_aver_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
1579    pwd->h[3]  = msa_aver_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
1580    pwd->h[4]  = msa_aver_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
1581    pwd->h[5]  = msa_aver_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
1582    pwd->h[6]  = msa_aver_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
1583    pwd->h[7]  = msa_aver_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
1584}
1585
1586void helper_msa_aver_u_w(CPUMIPSState *env,
1587                         uint32_t wd, uint32_t ws, uint32_t wt)
1588{
1589    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1590    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1591    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1592
1593    pwd->w[0]  = msa_aver_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
1594    pwd->w[1]  = msa_aver_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
1595    pwd->w[2]  = msa_aver_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
1596    pwd->w[3]  = msa_aver_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
1597}
1598
1599void helper_msa_aver_u_d(CPUMIPSState *env,
1600                         uint32_t wd, uint32_t ws, uint32_t wt)
1601{
1602    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1603    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1604    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1605
1606    pwd->d[0]  = msa_aver_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1607    pwd->d[1]  = msa_aver_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1608}
1609
1610
1611/*
1612 * Int Compare
1613 * -----------
1614 *
1615 * +---------------+----------------------------------------------------------+
1616 * | CEQ.B         | Vector Compare Equal (byte)                              |
1617 * | CEQ.H         | Vector Compare Equal (halfword)                          |
1618 * | CEQ.W         | Vector Compare Equal (word)                              |
1619 * | CEQ.D         | Vector Compare Equal (doubleword)                        |
1620 * | CLE_S.B       | Vector Compare Signed Less Than or Equal (byte)          |
1621 * | CLE_S.H       | Vector Compare Signed Less Than or Equal (halfword)      |
1622 * | CLE_S.W       | Vector Compare Signed Less Than or Equal (word)          |
1623 * | CLE_S.D       | Vector Compare Signed Less Than or Equal (doubleword)    |
1624 * | CLE_U.B       | Vector Compare Unsigned Less Than or Equal (byte)        |
1625 * | CLE_U.H       | Vector Compare Unsigned Less Than or Equal (halfword)    |
1626 * | CLE_U.W       | Vector Compare Unsigned Less Than or Equal (word)        |
1627 * | CLE_U.D       | Vector Compare Unsigned Less Than or Equal (doubleword)  |
1628 * | CLT_S.B       | Vector Compare Signed Less Than (byte)                   |
1629 * | CLT_S.H       | Vector Compare Signed Less Than (halfword)               |
1630 * | CLT_S.W       | Vector Compare Signed Less Than (word)                   |
1631 * | CLT_S.D       | Vector Compare Signed Less Than (doubleword)             |
1632 * | CLT_U.B       | Vector Compare Unsigned Less Than (byte)                 |
1633 * | CLT_U.H       | Vector Compare Unsigned Less Than (halfword)             |
1634 * | CLT_U.W       | Vector Compare Unsigned Less Than (word)                 |
1635 * | CLT_U.D       | Vector Compare Unsigned Less Than (doubleword)           |
1636 * +---------------+----------------------------------------------------------+
1637 */
1638
1639static inline int64_t msa_ceq_df(uint32_t df, int64_t arg1, int64_t arg2)
1640{
1641    return arg1 == arg2 ? -1 : 0;
1642}
1643
1644static inline int8_t msa_ceq_b(int8_t arg1, int8_t arg2)
1645{
1646    return arg1 == arg2 ? -1 : 0;
1647}
1648
1649void helper_msa_ceq_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1650{
1651    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1652    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1653    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1654
1655    pwd->b[0]  = msa_ceq_b(pws->b[0],  pwt->b[0]);
1656    pwd->b[1]  = msa_ceq_b(pws->b[1],  pwt->b[1]);
1657    pwd->b[2]  = msa_ceq_b(pws->b[2],  pwt->b[2]);
1658    pwd->b[3]  = msa_ceq_b(pws->b[3],  pwt->b[3]);
1659    pwd->b[4]  = msa_ceq_b(pws->b[4],  pwt->b[4]);
1660    pwd->b[5]  = msa_ceq_b(pws->b[5],  pwt->b[5]);
1661    pwd->b[6]  = msa_ceq_b(pws->b[6],  pwt->b[6]);
1662    pwd->b[7]  = msa_ceq_b(pws->b[7],  pwt->b[7]);
1663    pwd->b[8]  = msa_ceq_b(pws->b[8],  pwt->b[8]);
1664    pwd->b[9]  = msa_ceq_b(pws->b[9],  pwt->b[9]);
1665    pwd->b[10] = msa_ceq_b(pws->b[10], pwt->b[10]);
1666    pwd->b[11] = msa_ceq_b(pws->b[11], pwt->b[11]);
1667    pwd->b[12] = msa_ceq_b(pws->b[12], pwt->b[12]);
1668    pwd->b[13] = msa_ceq_b(pws->b[13], pwt->b[13]);
1669    pwd->b[14] = msa_ceq_b(pws->b[14], pwt->b[14]);
1670    pwd->b[15] = msa_ceq_b(pws->b[15], pwt->b[15]);
1671}
1672
1673static inline int16_t msa_ceq_h(int16_t arg1, int16_t arg2)
1674{
1675    return arg1 == arg2 ? -1 : 0;
1676}
1677
1678void helper_msa_ceq_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1679{
1680    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1681    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1682    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1683
1684    pwd->h[0]  = msa_ceq_h(pws->h[0],  pwt->h[0]);
1685    pwd->h[1]  = msa_ceq_h(pws->h[1],  pwt->h[1]);
1686    pwd->h[2]  = msa_ceq_h(pws->h[2],  pwt->h[2]);
1687    pwd->h[3]  = msa_ceq_h(pws->h[3],  pwt->h[3]);
1688    pwd->h[4]  = msa_ceq_h(pws->h[4],  pwt->h[4]);
1689    pwd->h[5]  = msa_ceq_h(pws->h[5],  pwt->h[5]);
1690    pwd->h[6]  = msa_ceq_h(pws->h[6],  pwt->h[6]);
1691    pwd->h[7]  = msa_ceq_h(pws->h[7],  pwt->h[7]);
1692}
1693
1694static inline int32_t msa_ceq_w(int32_t arg1, int32_t arg2)
1695{
1696    return arg1 == arg2 ? -1 : 0;
1697}
1698
1699void helper_msa_ceq_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1700{
1701    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1702    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1703    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1704
1705    pwd->w[0]  = msa_ceq_w(pws->w[0],  pwt->w[0]);
1706    pwd->w[1]  = msa_ceq_w(pws->w[1],  pwt->w[1]);
1707    pwd->w[2]  = msa_ceq_w(pws->w[2],  pwt->w[2]);
1708    pwd->w[3]  = msa_ceq_w(pws->w[3],  pwt->w[3]);
1709}
1710
1711static inline int64_t msa_ceq_d(int64_t arg1, int64_t arg2)
1712{
1713    return arg1 == arg2 ? -1 : 0;
1714}
1715
1716void helper_msa_ceq_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
1717{
1718    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1719    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1720    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1721
1722    pwd->d[0]  = msa_ceq_d(pws->d[0],  pwt->d[0]);
1723    pwd->d[1]  = msa_ceq_d(pws->d[1],  pwt->d[1]);
1724}
1725
1726static inline int64_t msa_cle_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1727{
1728    return arg1 <= arg2 ? -1 : 0;
1729}
1730
1731void helper_msa_cle_s_b(CPUMIPSState *env,
1732                        uint32_t wd, uint32_t ws, uint32_t wt)
1733{
1734    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1735    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1736    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1737
1738    pwd->b[0]  = msa_cle_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1739    pwd->b[1]  = msa_cle_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1740    pwd->b[2]  = msa_cle_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1741    pwd->b[3]  = msa_cle_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1742    pwd->b[4]  = msa_cle_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1743    pwd->b[5]  = msa_cle_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1744    pwd->b[6]  = msa_cle_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1745    pwd->b[7]  = msa_cle_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1746    pwd->b[8]  = msa_cle_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1747    pwd->b[9]  = msa_cle_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1748    pwd->b[10] = msa_cle_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
1749    pwd->b[11] = msa_cle_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
1750    pwd->b[12] = msa_cle_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
1751    pwd->b[13] = msa_cle_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
1752    pwd->b[14] = msa_cle_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
1753    pwd->b[15] = msa_cle_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
1754}
1755
1756void helper_msa_cle_s_h(CPUMIPSState *env,
1757                        uint32_t wd, uint32_t ws, uint32_t wt)
1758{
1759    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1760    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1761    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1762
1763    pwd->h[0]  = msa_cle_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
1764    pwd->h[1]  = msa_cle_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
1765    pwd->h[2]  = msa_cle_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
1766    pwd->h[3]  = msa_cle_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
1767    pwd->h[4]  = msa_cle_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
1768    pwd->h[5]  = msa_cle_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
1769    pwd->h[6]  = msa_cle_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
1770    pwd->h[7]  = msa_cle_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
1771}
1772
1773void helper_msa_cle_s_w(CPUMIPSState *env,
1774                        uint32_t wd, uint32_t ws, uint32_t wt)
1775{
1776    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1777    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1778    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1779
1780    pwd->w[0]  = msa_cle_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
1781    pwd->w[1]  = msa_cle_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
1782    pwd->w[2]  = msa_cle_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
1783    pwd->w[3]  = msa_cle_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
1784}
1785
1786void helper_msa_cle_s_d(CPUMIPSState *env,
1787                        uint32_t wd, uint32_t ws, uint32_t wt)
1788{
1789    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1790    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1791    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1792
1793    pwd->d[0]  = msa_cle_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1794    pwd->d[1]  = msa_cle_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1795}
1796
1797static inline int64_t msa_cle_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1798{
1799    uint64_t u_arg1 = UNSIGNED(arg1, df);
1800    uint64_t u_arg2 = UNSIGNED(arg2, df);
1801    return u_arg1 <= u_arg2 ? -1 : 0;
1802}
1803
1804void helper_msa_cle_u_b(CPUMIPSState *env,
1805                        uint32_t wd, uint32_t ws, uint32_t wt)
1806{
1807    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1808    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1809    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1810
1811    pwd->b[0]  = msa_cle_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1812    pwd->b[1]  = msa_cle_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1813    pwd->b[2]  = msa_cle_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1814    pwd->b[3]  = msa_cle_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1815    pwd->b[4]  = msa_cle_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1816    pwd->b[5]  = msa_cle_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1817    pwd->b[6]  = msa_cle_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1818    pwd->b[7]  = msa_cle_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1819    pwd->b[8]  = msa_cle_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1820    pwd->b[9]  = msa_cle_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1821    pwd->b[10] = msa_cle_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1822    pwd->b[11] = msa_cle_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1823    pwd->b[12] = msa_cle_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1824    pwd->b[13] = msa_cle_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1825    pwd->b[14] = msa_cle_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1826    pwd->b[15] = msa_cle_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1827}
1828
1829void helper_msa_cle_u_h(CPUMIPSState *env,
1830                        uint32_t wd, uint32_t ws, uint32_t wt)
1831{
1832    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1833    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1834    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1835
1836    pwd->h[0]  = msa_cle_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
1837    pwd->h[1]  = msa_cle_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
1838    pwd->h[2]  = msa_cle_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
1839    pwd->h[3]  = msa_cle_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
1840    pwd->h[4]  = msa_cle_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
1841    pwd->h[5]  = msa_cle_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
1842    pwd->h[6]  = msa_cle_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
1843    pwd->h[7]  = msa_cle_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
1844}
1845
1846void helper_msa_cle_u_w(CPUMIPSState *env,
1847                        uint32_t wd, uint32_t ws, uint32_t wt)
1848{
1849    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1850    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1851    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1852
1853    pwd->w[0]  = msa_cle_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
1854    pwd->w[1]  = msa_cle_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
1855    pwd->w[2]  = msa_cle_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
1856    pwd->w[3]  = msa_cle_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
1857}
1858
1859void helper_msa_cle_u_d(CPUMIPSState *env,
1860                        uint32_t wd, uint32_t ws, uint32_t wt)
1861{
1862    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1863    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1864    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1865
1866    pwd->d[0]  = msa_cle_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
1867    pwd->d[1]  = msa_cle_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
1868}
1869
1870static inline int64_t msa_clt_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1871{
1872    return arg1 < arg2 ? -1 : 0;
1873}
1874
1875static inline int8_t msa_clt_s_b(int8_t arg1, int8_t arg2)
1876{
1877    return arg1 < arg2 ? -1 : 0;
1878}
1879
1880void helper_msa_clt_s_b(CPUMIPSState *env,
1881                        uint32_t wd, uint32_t ws, uint32_t wt)
1882{
1883    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1884    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1885    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1886
1887    pwd->b[0]  = msa_clt_s_b(pws->b[0],  pwt->b[0]);
1888    pwd->b[1]  = msa_clt_s_b(pws->b[1],  pwt->b[1]);
1889    pwd->b[2]  = msa_clt_s_b(pws->b[2],  pwt->b[2]);
1890    pwd->b[3]  = msa_clt_s_b(pws->b[3],  pwt->b[3]);
1891    pwd->b[4]  = msa_clt_s_b(pws->b[4],  pwt->b[4]);
1892    pwd->b[5]  = msa_clt_s_b(pws->b[5],  pwt->b[5]);
1893    pwd->b[6]  = msa_clt_s_b(pws->b[6],  pwt->b[6]);
1894    pwd->b[7]  = msa_clt_s_b(pws->b[7],  pwt->b[7]);
1895    pwd->b[8]  = msa_clt_s_b(pws->b[8],  pwt->b[8]);
1896    pwd->b[9]  = msa_clt_s_b(pws->b[9],  pwt->b[9]);
1897    pwd->b[10] = msa_clt_s_b(pws->b[10], pwt->b[10]);
1898    pwd->b[11] = msa_clt_s_b(pws->b[11], pwt->b[11]);
1899    pwd->b[12] = msa_clt_s_b(pws->b[12], pwt->b[12]);
1900    pwd->b[13] = msa_clt_s_b(pws->b[13], pwt->b[13]);
1901    pwd->b[14] = msa_clt_s_b(pws->b[14], pwt->b[14]);
1902    pwd->b[15] = msa_clt_s_b(pws->b[15], pwt->b[15]);
1903}
1904
1905static inline int16_t msa_clt_s_h(int16_t arg1, int16_t arg2)
1906{
1907    return arg1 < arg2 ? -1 : 0;
1908}
1909
1910void helper_msa_clt_s_h(CPUMIPSState *env,
1911                        uint32_t wd, uint32_t ws, uint32_t wt)
1912{
1913    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1914    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1915    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1916
1917    pwd->h[0]  = msa_clt_s_h(pws->h[0],  pwt->h[0]);
1918    pwd->h[1]  = msa_clt_s_h(pws->h[1],  pwt->h[1]);
1919    pwd->h[2]  = msa_clt_s_h(pws->h[2],  pwt->h[2]);
1920    pwd->h[3]  = msa_clt_s_h(pws->h[3],  pwt->h[3]);
1921    pwd->h[4]  = msa_clt_s_h(pws->h[4],  pwt->h[4]);
1922    pwd->h[5]  = msa_clt_s_h(pws->h[5],  pwt->h[5]);
1923    pwd->h[6]  = msa_clt_s_h(pws->h[6],  pwt->h[6]);
1924    pwd->h[7]  = msa_clt_s_h(pws->h[7],  pwt->h[7]);
1925}
1926
1927static inline int32_t msa_clt_s_w(int32_t arg1, int32_t arg2)
1928{
1929    return arg1 < arg2 ? -1 : 0;
1930}
1931
1932void helper_msa_clt_s_w(CPUMIPSState *env,
1933                        uint32_t wd, uint32_t ws, uint32_t wt)
1934{
1935    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1936    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1937    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1938
1939    pwd->w[0]  = msa_clt_s_w(pws->w[0],  pwt->w[0]);
1940    pwd->w[1]  = msa_clt_s_w(pws->w[1],  pwt->w[1]);
1941    pwd->w[2]  = msa_clt_s_w(pws->w[2],  pwt->w[2]);
1942    pwd->w[3]  = msa_clt_s_w(pws->w[3],  pwt->w[3]);
1943}
1944
1945static inline int64_t msa_clt_s_d(int64_t arg1, int64_t arg2)
1946{
1947    return arg1 < arg2 ? -1 : 0;
1948}
1949
1950void helper_msa_clt_s_d(CPUMIPSState *env,
1951                        uint32_t wd, uint32_t ws, uint32_t wt)
1952{
1953    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1954    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1955    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1956
1957    pwd->d[0]  = msa_clt_s_d(pws->d[0],  pwt->d[0]);
1958    pwd->d[1]  = msa_clt_s_d(pws->d[1],  pwt->d[1]);
1959}
1960
1961static inline int64_t msa_clt_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1962{
1963    uint64_t u_arg1 = UNSIGNED(arg1, df);
1964    uint64_t u_arg2 = UNSIGNED(arg2, df);
1965    return u_arg1 < u_arg2 ? -1 : 0;
1966}
1967
1968void helper_msa_clt_u_b(CPUMIPSState *env,
1969                        uint32_t wd, uint32_t ws, uint32_t wt)
1970{
1971    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1972    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1973    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1974
1975    pwd->b[0]  = msa_clt_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
1976    pwd->b[1]  = msa_clt_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
1977    pwd->b[2]  = msa_clt_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
1978    pwd->b[3]  = msa_clt_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
1979    pwd->b[4]  = msa_clt_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
1980    pwd->b[5]  = msa_clt_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
1981    pwd->b[6]  = msa_clt_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
1982    pwd->b[7]  = msa_clt_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
1983    pwd->b[8]  = msa_clt_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
1984    pwd->b[9]  = msa_clt_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
1985    pwd->b[10] = msa_clt_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
1986    pwd->b[11] = msa_clt_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
1987    pwd->b[12] = msa_clt_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
1988    pwd->b[13] = msa_clt_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
1989    pwd->b[14] = msa_clt_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
1990    pwd->b[15] = msa_clt_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
1991}
1992
1993void helper_msa_clt_u_h(CPUMIPSState *env,
1994                        uint32_t wd, uint32_t ws, uint32_t wt)
1995{
1996    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1997    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1998    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1999
2000    pwd->h[0]  = msa_clt_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
2001    pwd->h[1]  = msa_clt_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
2002    pwd->h[2]  = msa_clt_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
2003    pwd->h[3]  = msa_clt_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
2004    pwd->h[4]  = msa_clt_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
2005    pwd->h[5]  = msa_clt_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
2006    pwd->h[6]  = msa_clt_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
2007    pwd->h[7]  = msa_clt_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
2008}
2009
2010void helper_msa_clt_u_w(CPUMIPSState *env,
2011                        uint32_t wd, uint32_t ws, uint32_t wt)
2012{
2013    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2014    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2015    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2016
2017    pwd->w[0]  = msa_clt_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
2018    pwd->w[1]  = msa_clt_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
2019    pwd->w[2]  = msa_clt_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
2020    pwd->w[3]  = msa_clt_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
2021}
2022
2023void helper_msa_clt_u_d(CPUMIPSState *env,
2024                        uint32_t wd, uint32_t ws, uint32_t wt)
2025{
2026    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2027    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2028    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2029
2030    pwd->d[0]  = msa_clt_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2031    pwd->d[1]  = msa_clt_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2032}
2033
2034
2035/*
2036 * Int Divide
2037 * ----------
2038 *
2039 * +---------------+----------------------------------------------------------+
2040 * | DIV_S.B       | Vector Signed Divide (byte)                              |
2041 * | DIV_S.H       | Vector Signed Divide (halfword)                          |
2042 * | DIV_S.W       | Vector Signed Divide (word)                              |
2043 * | DIV_S.D       | Vector Signed Divide (doubleword)                        |
2044 * | DIV_U.B       | Vector Unsigned Divide (byte)                            |
2045 * | DIV_U.H       | Vector Unsigned Divide (halfword)                        |
2046 * | DIV_U.W       | Vector Unsigned Divide (word)                            |
2047 * | DIV_U.D       | Vector Unsigned Divide (doubleword)                      |
2048 * +---------------+----------------------------------------------------------+
2049 */
2050
2051
2052static inline int64_t msa_div_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2053{
2054    if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
2055        return DF_MIN_INT(df);
2056    }
2057    return arg2 ? arg1 / arg2
2058                : arg1 >= 0 ? -1 : 1;
2059}
2060
2061void helper_msa_div_s_b(CPUMIPSState *env,
2062                        uint32_t wd, uint32_t ws, uint32_t wt)
2063{
2064    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2065    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2066    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2067
2068    pwd->b[0]  = msa_div_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2069    pwd->b[1]  = msa_div_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2070    pwd->b[2]  = msa_div_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2071    pwd->b[3]  = msa_div_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2072    pwd->b[4]  = msa_div_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2073    pwd->b[5]  = msa_div_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2074    pwd->b[6]  = msa_div_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2075    pwd->b[7]  = msa_div_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2076    pwd->b[8]  = msa_div_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2077    pwd->b[9]  = msa_div_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2078    pwd->b[10] = msa_div_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2079    pwd->b[11] = msa_div_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2080    pwd->b[12] = msa_div_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2081    pwd->b[13] = msa_div_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2082    pwd->b[14] = msa_div_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2083    pwd->b[15] = msa_div_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2084}
2085
2086void helper_msa_div_s_h(CPUMIPSState *env,
2087                        uint32_t wd, uint32_t ws, uint32_t wt)
2088{
2089    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2090    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2091    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2092
2093    pwd->h[0]  = msa_div_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
2094    pwd->h[1]  = msa_div_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
2095    pwd->h[2]  = msa_div_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
2096    pwd->h[3]  = msa_div_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
2097    pwd->h[4]  = msa_div_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
2098    pwd->h[5]  = msa_div_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
2099    pwd->h[6]  = msa_div_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
2100    pwd->h[7]  = msa_div_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
2101}
2102
2103void helper_msa_div_s_w(CPUMIPSState *env,
2104                        uint32_t wd, uint32_t ws, uint32_t wt)
2105{
2106    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2107    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2108    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2109
2110    pwd->w[0]  = msa_div_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
2111    pwd->w[1]  = msa_div_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
2112    pwd->w[2]  = msa_div_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
2113    pwd->w[3]  = msa_div_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
2114}
2115
2116void helper_msa_div_s_d(CPUMIPSState *env,
2117                        uint32_t wd, uint32_t ws, uint32_t wt)
2118{
2119    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2120    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2121    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2122
2123    pwd->d[0]  = msa_div_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2124    pwd->d[1]  = msa_div_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2125}
2126
2127static inline int64_t msa_div_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2128{
2129    uint64_t u_arg1 = UNSIGNED(arg1, df);
2130    uint64_t u_arg2 = UNSIGNED(arg2, df);
2131    return arg2 ? u_arg1 / u_arg2 : -1;
2132}
2133
2134void helper_msa_div_u_b(CPUMIPSState *env,
2135                        uint32_t wd, uint32_t ws, uint32_t wt)
2136{
2137    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2138    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2139    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2140
2141    pwd->b[0]  = msa_div_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2142    pwd->b[1]  = msa_div_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2143    pwd->b[2]  = msa_div_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2144    pwd->b[3]  = msa_div_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2145    pwd->b[4]  = msa_div_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2146    pwd->b[5]  = msa_div_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2147    pwd->b[6]  = msa_div_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2148    pwd->b[7]  = msa_div_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2149    pwd->b[8]  = msa_div_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2150    pwd->b[9]  = msa_div_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2151    pwd->b[10] = msa_div_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
2152    pwd->b[11] = msa_div_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
2153    pwd->b[12] = msa_div_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
2154    pwd->b[13] = msa_div_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
2155    pwd->b[14] = msa_div_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
2156    pwd->b[15] = msa_div_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
2157}
2158
2159void helper_msa_div_u_h(CPUMIPSState *env,
2160                        uint32_t wd, uint32_t ws, uint32_t wt)
2161{
2162    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2163    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2164    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2165
2166    pwd->h[0]  = msa_div_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
2167    pwd->h[1]  = msa_div_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
2168    pwd->h[2]  = msa_div_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
2169    pwd->h[3]  = msa_div_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
2170    pwd->h[4]  = msa_div_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
2171    pwd->h[5]  = msa_div_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
2172    pwd->h[6]  = msa_div_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
2173    pwd->h[7]  = msa_div_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
2174}
2175
2176void helper_msa_div_u_w(CPUMIPSState *env,
2177                        uint32_t wd, uint32_t ws, uint32_t wt)
2178{
2179    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2180    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2181    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2182
2183    pwd->w[0]  = msa_div_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
2184    pwd->w[1]  = msa_div_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
2185    pwd->w[2]  = msa_div_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
2186    pwd->w[3]  = msa_div_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
2187}
2188
2189void helper_msa_div_u_d(CPUMIPSState *env,
2190                        uint32_t wd, uint32_t ws, uint32_t wt)
2191{
2192    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2193    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2194    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2195
2196    pwd->d[0]  = msa_div_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2197    pwd->d[1]  = msa_div_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2198}
2199
2200
2201/*
2202 * Int Dot Product
2203 * ---------------
2204 *
2205 * +---------------+----------------------------------------------------------+
2206 * | DOTP_S.H      | Vector Signed Dot Product (halfword)                     |
2207 * | DOTP_S.W      | Vector Signed Dot Product (word)                         |
2208 * | DOTP_S.D      | Vector Signed Dot Product (doubleword)                   |
2209 * | DOTP_U.H      | Vector Unsigned Dot Product (halfword)                   |
2210 * | DOTP_U.W      | Vector Unsigned Dot Product (word)                       |
2211 * | DOTP_U.D      | Vector Unsigned Dot Product (doubleword)                 |
2212 * | DPADD_S.H     | Vector Signed Dot Product (halfword)                     |
2213 * | DPADD_S.W     | Vector Signed Dot Product (word)                         |
2214 * | DPADD_S.D     | Vector Signed Dot Product (doubleword)                   |
2215 * | DPADD_U.H     | Vector Unsigned Dot Product (halfword)                   |
2216 * | DPADD_U.W     | Vector Unsigned Dot Product (word)                       |
2217 * | DPADD_U.D     | Vector Unsigned Dot Product (doubleword)                 |
2218 * | DPSUB_S.H     | Vector Signed Dot Product (halfword)                     |
2219 * | DPSUB_S.W     | Vector Signed Dot Product (word)                         |
2220 * | DPSUB_S.D     | Vector Signed Dot Product (doubleword)                   |
2221 * | DPSUB_U.H     | Vector Unsigned Dot Product (halfword)                   |
2222 * | DPSUB_U.W     | Vector Unsigned Dot Product (word)                       |
2223 * | DPSUB_U.D     | Vector Unsigned Dot Product (doubleword)                 |
2224 * +---------------+----------------------------------------------------------+
2225 */
2226
2227/* TODO: insert Int Dot Product group helpers here */
2228
2229
2230/*
2231 * Int Max Min
2232 * -----------
2233 *
2234 * +---------------+----------------------------------------------------------+
2235 * | MAX_A.B       | Vector Maximum Based on Absolute Value (byte)            |
2236 * | MAX_A.H       | Vector Maximum Based on Absolute Value (halfword)        |
2237 * | MAX_A.W       | Vector Maximum Based on Absolute Value (word)            |
2238 * | MAX_A.D       | Vector Maximum Based on Absolute Value (doubleword)      |
2239 * | MAX_S.B       | Vector Signed Maximum (byte)                             |
2240 * | MAX_S.H       | Vector Signed Maximum (halfword)                         |
2241 * | MAX_S.W       | Vector Signed Maximum (word)                             |
2242 * | MAX_S.D       | Vector Signed Maximum (doubleword)                       |
2243 * | MAX_U.B       | Vector Unsigned Maximum (byte)                           |
2244 * | MAX_U.H       | Vector Unsigned Maximum (halfword)                       |
2245 * | MAX_U.W       | Vector Unsigned Maximum (word)                           |
2246 * | MAX_U.D       | Vector Unsigned Maximum (doubleword)                     |
2247 * | MIN_A.B       | Vector Minimum Based on Absolute Value (byte)            |
2248 * | MIN_A.H       | Vector Minimum Based on Absolute Value (halfword)        |
2249 * | MIN_A.W       | Vector Minimum Based on Absolute Value (word)            |
2250 * | MIN_A.D       | Vector Minimum Based on Absolute Value (doubleword)      |
2251 * | MIN_S.B       | Vector Signed Minimum (byte)                             |
2252 * | MIN_S.H       | Vector Signed Minimum (halfword)                         |
2253 * | MIN_S.W       | Vector Signed Minimum (word)                             |
2254 * | MIN_S.D       | Vector Signed Minimum (doubleword)                       |
2255 * | MIN_U.B       | Vector Unsigned Minimum (byte)                           |
2256 * | MIN_U.H       | Vector Unsigned Minimum (halfword)                       |
2257 * | MIN_U.W       | Vector Unsigned Minimum (word)                           |
2258 * | MIN_U.D       | Vector Unsigned Minimum (doubleword)                     |
2259 * +---------------+----------------------------------------------------------+
2260 */
2261
2262static inline int64_t msa_max_a_df(uint32_t df, int64_t arg1, int64_t arg2)
2263{
2264    uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
2265    uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
2266    return abs_arg1 > abs_arg2 ? arg1 : arg2;
2267}
2268
2269void helper_msa_max_a_b(CPUMIPSState *env,
2270                        uint32_t wd, uint32_t ws, uint32_t wt)
2271{
2272    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2273    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2274    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2275
2276    pwd->b[0]  = msa_max_a_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2277    pwd->b[1]  = msa_max_a_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2278    pwd->b[2]  = msa_max_a_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2279    pwd->b[3]  = msa_max_a_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2280    pwd->b[4]  = msa_max_a_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2281    pwd->b[5]  = msa_max_a_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2282    pwd->b[6]  = msa_max_a_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2283    pwd->b[7]  = msa_max_a_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2284    pwd->b[8]  = msa_max_a_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2285    pwd->b[9]  = msa_max_a_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2286    pwd->b[10] = msa_max_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
2287    pwd->b[11] = msa_max_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
2288    pwd->b[12] = msa_max_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
2289    pwd->b[13] = msa_max_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
2290    pwd->b[14] = msa_max_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
2291    pwd->b[15] = msa_max_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
2292}
2293
2294void helper_msa_max_a_h(CPUMIPSState *env,
2295                        uint32_t wd, uint32_t ws, uint32_t wt)
2296{
2297    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2298    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2299    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2300
2301    pwd->h[0]  = msa_max_a_df(DF_HALF, pws->h[0],  pwt->h[0]);
2302    pwd->h[1]  = msa_max_a_df(DF_HALF, pws->h[1],  pwt->h[1]);
2303    pwd->h[2]  = msa_max_a_df(DF_HALF, pws->h[2],  pwt->h[2]);
2304    pwd->h[3]  = msa_max_a_df(DF_HALF, pws->h[3],  pwt->h[3]);
2305    pwd->h[4]  = msa_max_a_df(DF_HALF, pws->h[4],  pwt->h[4]);
2306    pwd->h[5]  = msa_max_a_df(DF_HALF, pws->h[5],  pwt->h[5]);
2307    pwd->h[6]  = msa_max_a_df(DF_HALF, pws->h[6],  pwt->h[6]);
2308    pwd->h[7]  = msa_max_a_df(DF_HALF, pws->h[7],  pwt->h[7]);
2309}
2310
2311void helper_msa_max_a_w(CPUMIPSState *env,
2312                        uint32_t wd, uint32_t ws, uint32_t wt)
2313{
2314    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2315    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2316    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2317
2318    pwd->w[0]  = msa_max_a_df(DF_WORD, pws->w[0],  pwt->w[0]);
2319    pwd->w[1]  = msa_max_a_df(DF_WORD, pws->w[1],  pwt->w[1]);
2320    pwd->w[2]  = msa_max_a_df(DF_WORD, pws->w[2],  pwt->w[2]);
2321    pwd->w[3]  = msa_max_a_df(DF_WORD, pws->w[3],  pwt->w[3]);
2322}
2323
2324void helper_msa_max_a_d(CPUMIPSState *env,
2325                        uint32_t wd, uint32_t ws, uint32_t wt)
2326{
2327    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2328    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2329    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2330
2331    pwd->d[0]  = msa_max_a_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2332    pwd->d[1]  = msa_max_a_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2333}
2334
2335
2336static inline int64_t msa_max_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2337{
2338    return arg1 > arg2 ? arg1 : arg2;
2339}
2340
2341void helper_msa_max_s_b(CPUMIPSState *env,
2342                        uint32_t wd, uint32_t ws, uint32_t wt)
2343{
2344    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2345    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2346    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2347
2348    pwd->b[0]  = msa_max_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2349    pwd->b[1]  = msa_max_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2350    pwd->b[2]  = msa_max_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2351    pwd->b[3]  = msa_max_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2352    pwd->b[4]  = msa_max_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2353    pwd->b[5]  = msa_max_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2354    pwd->b[6]  = msa_max_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2355    pwd->b[7]  = msa_max_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2356    pwd->b[8]  = msa_max_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2357    pwd->b[9]  = msa_max_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2358    pwd->b[10] = msa_max_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2359    pwd->b[11] = msa_max_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2360    pwd->b[12] = msa_max_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2361    pwd->b[13] = msa_max_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2362    pwd->b[14] = msa_max_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2363    pwd->b[15] = msa_max_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2364}
2365
2366void helper_msa_max_s_h(CPUMIPSState *env,
2367                        uint32_t wd, uint32_t ws, uint32_t wt)
2368{
2369    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2370    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2371    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2372
2373    pwd->h[0]  = msa_max_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
2374    pwd->h[1]  = msa_max_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
2375    pwd->h[2]  = msa_max_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
2376    pwd->h[3]  = msa_max_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
2377    pwd->h[4]  = msa_max_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
2378    pwd->h[5]  = msa_max_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
2379    pwd->h[6]  = msa_max_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
2380    pwd->h[7]  = msa_max_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
2381}
2382
2383void helper_msa_max_s_w(CPUMIPSState *env,
2384                        uint32_t wd, uint32_t ws, uint32_t wt)
2385{
2386    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2387    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2388    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2389
2390    pwd->w[0]  = msa_max_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
2391    pwd->w[1]  = msa_max_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
2392    pwd->w[2]  = msa_max_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
2393    pwd->w[3]  = msa_max_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
2394}
2395
2396void helper_msa_max_s_d(CPUMIPSState *env,
2397                        uint32_t wd, uint32_t ws, uint32_t wt)
2398{
2399    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2400    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2401    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2402
2403    pwd->d[0]  = msa_max_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2404    pwd->d[1]  = msa_max_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2405}
2406
2407
2408static inline int64_t msa_max_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2409{
2410    uint64_t u_arg1 = UNSIGNED(arg1, df);
2411    uint64_t u_arg2 = UNSIGNED(arg2, df);
2412    return u_arg1 > u_arg2 ? arg1 : arg2;
2413}
2414
2415void helper_msa_max_u_b(CPUMIPSState *env,
2416                        uint32_t wd, uint32_t ws, uint32_t wt)
2417{
2418    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2419    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2420    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2421
2422    pwd->b[0]  = msa_max_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2423    pwd->b[1]  = msa_max_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2424    pwd->b[2]  = msa_max_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2425    pwd->b[3]  = msa_max_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2426    pwd->b[4]  = msa_max_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2427    pwd->b[5]  = msa_max_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2428    pwd->b[6]  = msa_max_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2429    pwd->b[7]  = msa_max_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2430    pwd->b[8]  = msa_max_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2431    pwd->b[9]  = msa_max_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2432    pwd->b[10] = msa_max_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
2433    pwd->b[11] = msa_max_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
2434    pwd->b[12] = msa_max_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
2435    pwd->b[13] = msa_max_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
2436    pwd->b[14] = msa_max_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
2437    pwd->b[15] = msa_max_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
2438}
2439
2440void helper_msa_max_u_h(CPUMIPSState *env,
2441                        uint32_t wd, uint32_t ws, uint32_t wt)
2442{
2443    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2444    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2445    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2446
2447    pwd->h[0]  = msa_max_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
2448    pwd->h[1]  = msa_max_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
2449    pwd->h[2]  = msa_max_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
2450    pwd->h[3]  = msa_max_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
2451    pwd->h[4]  = msa_max_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
2452    pwd->h[5]  = msa_max_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
2453    pwd->h[6]  = msa_max_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
2454    pwd->h[7]  = msa_max_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
2455}
2456
2457void helper_msa_max_u_w(CPUMIPSState *env,
2458                        uint32_t wd, uint32_t ws, uint32_t wt)
2459{
2460    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2461    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2462    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2463
2464    pwd->w[0]  = msa_max_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
2465    pwd->w[1]  = msa_max_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
2466    pwd->w[2]  = msa_max_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
2467    pwd->w[3]  = msa_max_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
2468}
2469
2470void helper_msa_max_u_d(CPUMIPSState *env,
2471                        uint32_t wd, uint32_t ws, uint32_t wt)
2472{
2473    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2474    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2475    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2476
2477    pwd->d[0]  = msa_max_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2478    pwd->d[1]  = msa_max_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2479}
2480
2481
2482static inline int64_t msa_min_a_df(uint32_t df, int64_t arg1, int64_t arg2)
2483{
2484    uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
2485    uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
2486    return abs_arg1 < abs_arg2 ? arg1 : arg2;
2487}
2488
2489void helper_msa_min_a_b(CPUMIPSState *env,
2490                        uint32_t wd, uint32_t ws, uint32_t wt)
2491{
2492    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2493    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2494    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2495
2496    pwd->b[0]  = msa_min_a_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2497    pwd->b[1]  = msa_min_a_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2498    pwd->b[2]  = msa_min_a_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2499    pwd->b[3]  = msa_min_a_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2500    pwd->b[4]  = msa_min_a_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2501    pwd->b[5]  = msa_min_a_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2502    pwd->b[6]  = msa_min_a_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2503    pwd->b[7]  = msa_min_a_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2504    pwd->b[8]  = msa_min_a_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2505    pwd->b[9]  = msa_min_a_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2506    pwd->b[10] = msa_min_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
2507    pwd->b[11] = msa_min_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
2508    pwd->b[12] = msa_min_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
2509    pwd->b[13] = msa_min_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
2510    pwd->b[14] = msa_min_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
2511    pwd->b[15] = msa_min_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
2512}
2513
2514void helper_msa_min_a_h(CPUMIPSState *env,
2515                        uint32_t wd, uint32_t ws, uint32_t wt)
2516{
2517    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2518    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2519    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2520
2521    pwd->h[0]  = msa_min_a_df(DF_HALF, pws->h[0],  pwt->h[0]);
2522    pwd->h[1]  = msa_min_a_df(DF_HALF, pws->h[1],  pwt->h[1]);
2523    pwd->h[2]  = msa_min_a_df(DF_HALF, pws->h[2],  pwt->h[2]);
2524    pwd->h[3]  = msa_min_a_df(DF_HALF, pws->h[3],  pwt->h[3]);
2525    pwd->h[4]  = msa_min_a_df(DF_HALF, pws->h[4],  pwt->h[4]);
2526    pwd->h[5]  = msa_min_a_df(DF_HALF, pws->h[5],  pwt->h[5]);
2527    pwd->h[6]  = msa_min_a_df(DF_HALF, pws->h[6],  pwt->h[6]);
2528    pwd->h[7]  = msa_min_a_df(DF_HALF, pws->h[7],  pwt->h[7]);
2529}
2530
2531void helper_msa_min_a_w(CPUMIPSState *env,
2532                        uint32_t wd, uint32_t ws, uint32_t wt)
2533{
2534    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2535    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2536    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2537
2538    pwd->w[0]  = msa_min_a_df(DF_WORD, pws->w[0],  pwt->w[0]);
2539    pwd->w[1]  = msa_min_a_df(DF_WORD, pws->w[1],  pwt->w[1]);
2540    pwd->w[2]  = msa_min_a_df(DF_WORD, pws->w[2],  pwt->w[2]);
2541    pwd->w[3]  = msa_min_a_df(DF_WORD, pws->w[3],  pwt->w[3]);
2542}
2543
2544void helper_msa_min_a_d(CPUMIPSState *env,
2545                        uint32_t wd, uint32_t ws, uint32_t wt)
2546{
2547    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2548    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2549    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2550
2551    pwd->d[0]  = msa_min_a_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2552    pwd->d[1]  = msa_min_a_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2553}
2554
2555
2556static inline int64_t msa_min_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2557{
2558    return arg1 < arg2 ? arg1 : arg2;
2559}
2560
2561void helper_msa_min_s_b(CPUMIPSState *env,
2562                        uint32_t wd, uint32_t ws, uint32_t wt)
2563{
2564    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2565    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2566    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2567
2568    pwd->b[0]  = msa_min_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2569    pwd->b[1]  = msa_min_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2570    pwd->b[2]  = msa_min_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2571    pwd->b[3]  = msa_min_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2572    pwd->b[4]  = msa_min_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2573    pwd->b[5]  = msa_min_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2574    pwd->b[6]  = msa_min_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2575    pwd->b[7]  = msa_min_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2576    pwd->b[8]  = msa_min_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2577    pwd->b[9]  = msa_min_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2578    pwd->b[10] = msa_min_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2579    pwd->b[11] = msa_min_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2580    pwd->b[12] = msa_min_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2581    pwd->b[13] = msa_min_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2582    pwd->b[14] = msa_min_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2583    pwd->b[15] = msa_min_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2584}
2585
2586void helper_msa_min_s_h(CPUMIPSState *env,
2587                        uint32_t wd, uint32_t ws, uint32_t wt)
2588{
2589    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2590    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2591    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2592
2593    pwd->h[0]  = msa_min_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
2594    pwd->h[1]  = msa_min_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
2595    pwd->h[2]  = msa_min_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
2596    pwd->h[3]  = msa_min_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
2597    pwd->h[4]  = msa_min_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
2598    pwd->h[5]  = msa_min_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
2599    pwd->h[6]  = msa_min_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
2600    pwd->h[7]  = msa_min_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
2601}
2602
2603void helper_msa_min_s_w(CPUMIPSState *env,
2604                        uint32_t wd, uint32_t ws, uint32_t wt)
2605{
2606    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2607    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2608    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2609
2610    pwd->w[0]  = msa_min_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
2611    pwd->w[1]  = msa_min_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
2612    pwd->w[2]  = msa_min_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
2613    pwd->w[3]  = msa_min_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
2614}
2615
2616void helper_msa_min_s_d(CPUMIPSState *env,
2617                        uint32_t wd, uint32_t ws, uint32_t wt)
2618{
2619    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2620    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2621    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2622
2623    pwd->d[0]  = msa_min_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2624    pwd->d[1]  = msa_min_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2625}
2626
2627
2628static inline int64_t msa_min_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2629{
2630    uint64_t u_arg1 = UNSIGNED(arg1, df);
2631    uint64_t u_arg2 = UNSIGNED(arg2, df);
2632    return u_arg1 < u_arg2 ? arg1 : arg2;
2633}
2634
2635void helper_msa_min_u_b(CPUMIPSState *env,
2636                        uint32_t wd, uint32_t ws, uint32_t wt)
2637{
2638    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2639    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2640    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2641
2642    pwd->b[0]  = msa_min_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2643    pwd->b[1]  = msa_min_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2644    pwd->b[2]  = msa_min_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2645    pwd->b[3]  = msa_min_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2646    pwd->b[4]  = msa_min_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2647    pwd->b[5]  = msa_min_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2648    pwd->b[6]  = msa_min_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2649    pwd->b[7]  = msa_min_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2650    pwd->b[8]  = msa_min_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2651    pwd->b[9]  = msa_min_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2652    pwd->b[10] = msa_min_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
2653    pwd->b[11] = msa_min_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
2654    pwd->b[12] = msa_min_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
2655    pwd->b[13] = msa_min_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
2656    pwd->b[14] = msa_min_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
2657    pwd->b[15] = msa_min_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
2658}
2659
2660void helper_msa_min_u_h(CPUMIPSState *env,
2661                        uint32_t wd, uint32_t ws, uint32_t wt)
2662{
2663    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2664    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2665    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2666
2667    pwd->h[0]  = msa_min_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
2668    pwd->h[1]  = msa_min_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
2669    pwd->h[2]  = msa_min_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
2670    pwd->h[3]  = msa_min_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
2671    pwd->h[4]  = msa_min_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
2672    pwd->h[5]  = msa_min_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
2673    pwd->h[6]  = msa_min_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
2674    pwd->h[7]  = msa_min_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
2675}
2676
2677void helper_msa_min_u_w(CPUMIPSState *env,
2678                        uint32_t wd, uint32_t ws, uint32_t wt)
2679{
2680    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2681    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2682    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2683
2684    pwd->w[0]  = msa_min_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
2685    pwd->w[1]  = msa_min_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
2686    pwd->w[2]  = msa_min_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
2687    pwd->w[3]  = msa_min_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
2688}
2689
2690void helper_msa_min_u_d(CPUMIPSState *env,
2691                        uint32_t wd, uint32_t ws, uint32_t wt)
2692{
2693    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2694    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2695    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2696
2697    pwd->d[0]  = msa_min_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2698    pwd->d[1]  = msa_min_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2699}
2700
2701
2702/*
2703 * Int Modulo
2704 * ----------
2705 *
2706 * +---------------+----------------------------------------------------------+
2707 * | MOD_S.B       | Vector Signed Modulo (byte)                              |
2708 * | MOD_S.H       | Vector Signed Modulo (halfword)                          |
2709 * | MOD_S.W       | Vector Signed Modulo (word)                              |
2710 * | MOD_S.D       | Vector Signed Modulo (doubleword)                        |
2711 * | MOD_U.B       | Vector Unsigned Modulo (byte)                            |
2712 * | MOD_U.H       | Vector Unsigned Modulo (halfword)                        |
2713 * | MOD_U.W       | Vector Unsigned Modulo (word)                            |
2714 * | MOD_U.D       | Vector Unsigned Modulo (doubleword)                      |
2715 * +---------------+----------------------------------------------------------+
2716 */
2717
2718static inline int64_t msa_mod_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2719{
2720    if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
2721        return 0;
2722    }
2723    return arg2 ? arg1 % arg2 : arg1;
2724}
2725
2726void helper_msa_mod_s_b(CPUMIPSState *env,
2727                        uint32_t wd, uint32_t ws, uint32_t wt)
2728{
2729    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2730    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2731    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2732
2733    pwd->b[0]  = msa_mod_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2734    pwd->b[1]  = msa_mod_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2735    pwd->b[2]  = msa_mod_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2736    pwd->b[3]  = msa_mod_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2737    pwd->b[4]  = msa_mod_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2738    pwd->b[5]  = msa_mod_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2739    pwd->b[6]  = msa_mod_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2740    pwd->b[7]  = msa_mod_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2741    pwd->b[8]  = msa_mod_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2742    pwd->b[9]  = msa_mod_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2743    pwd->b[10] = msa_mod_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2744    pwd->b[11] = msa_mod_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2745    pwd->b[12] = msa_mod_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2746    pwd->b[13] = msa_mod_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2747    pwd->b[14] = msa_mod_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2748    pwd->b[15] = msa_mod_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2749}
2750
2751void helper_msa_mod_s_h(CPUMIPSState *env,
2752                        uint32_t wd, uint32_t ws, uint32_t wt)
2753{
2754    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2755    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2756    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2757
2758    pwd->h[0]  = msa_mod_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
2759    pwd->h[1]  = msa_mod_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
2760    pwd->h[2]  = msa_mod_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
2761    pwd->h[3]  = msa_mod_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
2762    pwd->h[4]  = msa_mod_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
2763    pwd->h[5]  = msa_mod_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
2764    pwd->h[6]  = msa_mod_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
2765    pwd->h[7]  = msa_mod_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
2766}
2767
2768void helper_msa_mod_s_w(CPUMIPSState *env,
2769                        uint32_t wd, uint32_t ws, uint32_t wt)
2770{
2771    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2772    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2773    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2774
2775    pwd->w[0]  = msa_mod_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
2776    pwd->w[1]  = msa_mod_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
2777    pwd->w[2]  = msa_mod_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
2778    pwd->w[3]  = msa_mod_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
2779}
2780
2781void helper_msa_mod_s_d(CPUMIPSState *env,
2782                        uint32_t wd, uint32_t ws, uint32_t wt)
2783{
2784    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2785    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2786    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2787
2788    pwd->d[0]  = msa_mod_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2789    pwd->d[1]  = msa_mod_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2790}
2791
2792static inline int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2)
2793{
2794    uint64_t u_arg1 = UNSIGNED(arg1, df);
2795    uint64_t u_arg2 = UNSIGNED(arg2, df);
2796    return u_arg2 ? u_arg1 % u_arg2 : u_arg1;
2797}
2798
2799void helper_msa_mod_u_b(CPUMIPSState *env,
2800                        uint32_t wd, uint32_t ws, uint32_t wt)
2801{
2802    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2803    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2804    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2805
2806    pwd->b[0]  = msa_mod_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2807    pwd->b[1]  = msa_mod_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2808    pwd->b[2]  = msa_mod_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2809    pwd->b[3]  = msa_mod_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2810    pwd->b[4]  = msa_mod_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2811    pwd->b[5]  = msa_mod_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2812    pwd->b[6]  = msa_mod_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2813    pwd->b[7]  = msa_mod_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2814    pwd->b[8]  = msa_mod_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2815    pwd->b[9]  = msa_mod_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2816    pwd->b[10] = msa_mod_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
2817    pwd->b[11] = msa_mod_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
2818    pwd->b[12] = msa_mod_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
2819    pwd->b[13] = msa_mod_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
2820    pwd->b[14] = msa_mod_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
2821    pwd->b[15] = msa_mod_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
2822}
2823
2824void helper_msa_mod_u_h(CPUMIPSState *env,
2825                        uint32_t wd, uint32_t ws, uint32_t wt)
2826{
2827    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2828    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2829    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2830
2831    pwd->h[0]  = msa_mod_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
2832    pwd->h[1]  = msa_mod_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
2833    pwd->h[2]  = msa_mod_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
2834    pwd->h[3]  = msa_mod_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
2835    pwd->h[4]  = msa_mod_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
2836    pwd->h[5]  = msa_mod_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
2837    pwd->h[6]  = msa_mod_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
2838    pwd->h[7]  = msa_mod_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
2839}
2840
2841void helper_msa_mod_u_w(CPUMIPSState *env,
2842                        uint32_t wd, uint32_t ws, uint32_t wt)
2843{
2844    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2845    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2846    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2847
2848    pwd->w[0]  = msa_mod_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
2849    pwd->w[1]  = msa_mod_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
2850    pwd->w[2]  = msa_mod_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
2851    pwd->w[3]  = msa_mod_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
2852}
2853
2854void helper_msa_mod_u_d(CPUMIPSState *env,
2855                        uint32_t wd, uint32_t ws, uint32_t wt)
2856{
2857    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2858    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2859    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2860
2861    pwd->d[0]  = msa_mod_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
2862    pwd->d[1]  = msa_mod_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
2863}
2864
2865
2866/*
2867 * Int Multiply
2868 * ------------
2869 *
2870 * +---------------+----------------------------------------------------------+
2871 * | MADDV.B       | Vector Multiply and Add (byte)                           |
2872 * | MADDV.H       | Vector Multiply and Add (halfword)                       |
2873 * | MADDV.W       | Vector Multiply and Add (word)                           |
2874 * | MADDV.D       | Vector Multiply and Add (doubleword)                     |
2875 * | MSUBV.B       | Vector Multiply and Subtract (byte)                      |
2876 * | MSUBV.H       | Vector Multiply and Subtract (halfword)                  |
2877 * | MSUBV.W       | Vector Multiply and Subtract (word)                      |
2878 * | MSUBV.D       | Vector Multiply and Subtract (doubleword)                |
2879 * | MULV.B        | Vector Multiply (byte)                                   |
2880 * | MULV.H        | Vector Multiply (halfword)                               |
2881 * | MULV.W        | Vector Multiply (word)                                   |
2882 * | MULV.D        | Vector Multiply (doubleword)                             |
2883 * +---------------+----------------------------------------------------------+
2884 */
2885
2886/* TODO: insert Int Multiply group helpers here */
2887
2888
2889/*
2890 * Int Subtract
2891 * ------------
2892 *
2893 * +---------------+----------------------------------------------------------+
2894 * | ASUB_S.B      | Vector Absolute Values of Signed Subtract (byte)         |
2895 * | ASUB_S.H      | Vector Absolute Values of Signed Subtract (halfword)     |
2896 * | ASUB_S.W      | Vector Absolute Values of Signed Subtract (word)         |
2897 * | ASUB_S.D      | Vector Absolute Values of Signed Subtract (doubleword)   |
2898 * | ASUB_U.B      | Vector Absolute Values of Unsigned Subtract (byte)       |
2899 * | ASUB_U.H      | Vector Absolute Values of Unsigned Subtract (halfword)   |
2900 * | ASUB_U.W      | Vector Absolute Values of Unsigned Subtract (word)       |
2901 * | ASUB_U.D      | Vector Absolute Values of Unsigned Subtract (doubleword) |
2902 * | HSUB_S.H      | Vector Signed Horizontal Subtract (halfword)             |
2903 * | HSUB_S.W      | Vector Signed Horizontal Subtract (word)                 |
2904 * | HSUB_S.D      | Vector Signed Horizontal Subtract (doubleword)           |
2905 * | HSUB_U.H      | Vector Unigned Horizontal Subtract (halfword)            |
2906 * | HSUB_U.W      | Vector Unigned Horizontal Subtract (word)                |
2907 * | HSUB_U.D      | Vector Unigned Horizontal Subtract (doubleword)          |
2908 * | SUBS_S.B      | Vector Signed Saturated Subtract (of Signed) (byte)      |
2909 * | SUBS_S.H      | Vector Signed Saturated Subtract (of Signed) (halfword)  |
2910 * | SUBS_S.W      | Vector Signed Saturated Subtract (of Signed) (word)      |
2911 * | SUBS_S.D      | Vector Signed Saturated Subtract (of Signed) (doubleword)|
2912 * | SUBS_U.B      | Vector Unsigned Saturated Subtract (of Uns.) (byte)      |
2913 * | SUBS_U.H      | Vector Unsigned Saturated Subtract (of Uns.) (halfword)  |
2914 * | SUBS_U.W      | Vector Unsigned Saturated Subtract (of Uns.) (word)      |
2915 * | SUBS_U.D      | Vector Unsigned Saturated Subtract (of Uns.) (doubleword)|
2916 * | SUBSUS_U.B    | Vector Uns. Sat. Subtract (of S. from Uns.) (byte)       |
2917 * | SUBSUS_U.H    | Vector Uns. Sat. Subtract (of S. from Uns.) (halfword)   |
2918 * | SUBSUS_U.W    | Vector Uns. Sat. Subtract (of S. from Uns.) (word)       |
2919 * | SUBSUS_U.D    | Vector Uns. Sat. Subtract (of S. from Uns.) (doubleword) |
2920 * | SUBSUU_S.B    | Vector Signed Saturated Subtract (of Uns.) (byte)        |
2921 * | SUBSUU_S.H    | Vector Signed Saturated Subtract (of Uns.) (halfword)    |
2922 * | SUBSUU_S.W    | Vector Signed Saturated Subtract (of Uns.) (word)        |
2923 * | SUBSUU_S.D    | Vector Signed Saturated Subtract (of Uns.) (doubleword)  |
2924 * | SUBV.B        | Vector Subtract (byte)                                   |
2925 * | SUBV.H        | Vector Subtract (halfword)                               |
2926 * | SUBV.W        | Vector Subtract (word)                                   |
2927 * | SUBV.D        | Vector Subtract (doubleword)                             |
2928 * +---------------+----------------------------------------------------------+
2929 */
2930
2931
2932static inline int64_t msa_asub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
2933{
2934    /* signed compare */
2935    return (arg1 < arg2) ?
2936        (uint64_t)(arg2 - arg1) : (uint64_t)(arg1 - arg2);
2937}
2938
2939void helper_msa_asub_s_b(CPUMIPSState *env,
2940                         uint32_t wd, uint32_t ws, uint32_t wt)
2941{
2942    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2943    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2944    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2945
2946    pwd->b[0]  = msa_asub_s_df(DF_BYTE, pws->b[0],  pwt->b[0]);
2947    pwd->b[1]  = msa_asub_s_df(DF_BYTE, pws->b[1],  pwt->b[1]);
2948    pwd->b[2]  = msa_asub_s_df(DF_BYTE, pws->b[2],  pwt->b[2]);
2949    pwd->b[3]  = msa_asub_s_df(DF_BYTE, pws->b[3],  pwt->b[3]);
2950    pwd->b[4]  = msa_asub_s_df(DF_BYTE, pws->b[4],  pwt->b[4]);
2951    pwd->b[5]  = msa_asub_s_df(DF_BYTE, pws->b[5],  pwt->b[5]);
2952    pwd->b[6]  = msa_asub_s_df(DF_BYTE, pws->b[6],  pwt->b[6]);
2953    pwd->b[7]  = msa_asub_s_df(DF_BYTE, pws->b[7],  pwt->b[7]);
2954    pwd->b[8]  = msa_asub_s_df(DF_BYTE, pws->b[8],  pwt->b[8]);
2955    pwd->b[9]  = msa_asub_s_df(DF_BYTE, pws->b[9],  pwt->b[9]);
2956    pwd->b[10] = msa_asub_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
2957    pwd->b[11] = msa_asub_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
2958    pwd->b[12] = msa_asub_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
2959    pwd->b[13] = msa_asub_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
2960    pwd->b[14] = msa_asub_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
2961    pwd->b[15] = msa_asub_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
2962}
2963
2964void helper_msa_asub_s_h(CPUMIPSState *env,
2965                         uint32_t wd, uint32_t ws, uint32_t wt)
2966{
2967    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2968    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2969    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2970
2971    pwd->h[0]  = msa_asub_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
2972    pwd->h[1]  = msa_asub_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
2973    pwd->h[2]  = msa_asub_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
2974    pwd->h[3]  = msa_asub_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
2975    pwd->h[4]  = msa_asub_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
2976    pwd->h[5]  = msa_asub_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
2977    pwd->h[6]  = msa_asub_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
2978    pwd->h[7]  = msa_asub_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
2979}
2980
2981void helper_msa_asub_s_w(CPUMIPSState *env,
2982                         uint32_t wd, uint32_t ws, uint32_t wt)
2983{
2984    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2985    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2986    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2987
2988    pwd->w[0]  = msa_asub_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
2989    pwd->w[1]  = msa_asub_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
2990    pwd->w[2]  = msa_asub_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
2991    pwd->w[3]  = msa_asub_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
2992}
2993
2994void helper_msa_asub_s_d(CPUMIPSState *env,
2995                         uint32_t wd, uint32_t ws, uint32_t wt)
2996{
2997    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2998    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2999    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3000
3001    pwd->d[0]  = msa_asub_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3002    pwd->d[1]  = msa_asub_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3003}
3004
3005
3006static inline uint64_t msa_asub_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
3007{
3008    uint64_t u_arg1 = UNSIGNED(arg1, df);
3009    uint64_t u_arg2 = UNSIGNED(arg2, df);
3010    /* unsigned compare */
3011    return (u_arg1 < u_arg2) ?
3012        (uint64_t)(u_arg2 - u_arg1) : (uint64_t)(u_arg1 - u_arg2);
3013}
3014
3015void helper_msa_asub_u_b(CPUMIPSState *env,
3016                         uint32_t wd, uint32_t ws, uint32_t wt)
3017{
3018    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3019    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3020    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3021
3022    pwd->b[0]  = msa_asub_u_df(DF_BYTE, pws->b[0],  pwt->b[0]);
3023    pwd->b[1]  = msa_asub_u_df(DF_BYTE, pws->b[1],  pwt->b[1]);
3024    pwd->b[2]  = msa_asub_u_df(DF_BYTE, pws->b[2],  pwt->b[2]);
3025    pwd->b[3]  = msa_asub_u_df(DF_BYTE, pws->b[3],  pwt->b[3]);
3026    pwd->b[4]  = msa_asub_u_df(DF_BYTE, pws->b[4],  pwt->b[4]);
3027    pwd->b[5]  = msa_asub_u_df(DF_BYTE, pws->b[5],  pwt->b[5]);
3028    pwd->b[6]  = msa_asub_u_df(DF_BYTE, pws->b[6],  pwt->b[6]);
3029    pwd->b[7]  = msa_asub_u_df(DF_BYTE, pws->b[7],  pwt->b[7]);
3030    pwd->b[8]  = msa_asub_u_df(DF_BYTE, pws->b[8],  pwt->b[8]);
3031    pwd->b[9]  = msa_asub_u_df(DF_BYTE, pws->b[9],  pwt->b[9]);
3032    pwd->b[10] = msa_asub_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
3033    pwd->b[11] = msa_asub_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
3034    pwd->b[12] = msa_asub_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
3035    pwd->b[13] = msa_asub_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
3036    pwd->b[14] = msa_asub_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
3037    pwd->b[15] = msa_asub_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
3038}
3039
3040void helper_msa_asub_u_h(CPUMIPSState *env,
3041                         uint32_t wd, uint32_t ws, uint32_t wt)
3042{
3043    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3044    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3045    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3046
3047    pwd->h[0]  = msa_asub_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
3048    pwd->h[1]  = msa_asub_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
3049    pwd->h[2]  = msa_asub_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
3050    pwd->h[3]  = msa_asub_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
3051    pwd->h[4]  = msa_asub_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
3052    pwd->h[5]  = msa_asub_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
3053    pwd->h[6]  = msa_asub_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
3054    pwd->h[7]  = msa_asub_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
3055}
3056
3057void helper_msa_asub_u_w(CPUMIPSState *env,
3058                         uint32_t wd, uint32_t ws, uint32_t wt)
3059{
3060    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3061    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3062    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3063
3064    pwd->w[0]  = msa_asub_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
3065    pwd->w[1]  = msa_asub_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
3066    pwd->w[2]  = msa_asub_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
3067    pwd->w[3]  = msa_asub_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
3068}
3069
3070void helper_msa_asub_u_d(CPUMIPSState *env,
3071                         uint32_t wd, uint32_t ws, uint32_t wt)
3072{
3073    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3074    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3075    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3076
3077    pwd->d[0]  = msa_asub_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3078    pwd->d[1]  = msa_asub_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3079}
3080
3081
3082/* TODO: insert the rest of Int Subtract group helpers here */
3083
3084
3085static inline int64_t msa_hsub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
3086{
3087    return SIGNED_ODD(arg1, df) - SIGNED_EVEN(arg2, df);
3088}
3089
3090void helper_msa_hsub_s_h(CPUMIPSState *env,
3091                         uint32_t wd, uint32_t ws, uint32_t wt)
3092{
3093    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3094    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3095    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3096
3097    pwd->h[0]  = msa_hsub_s_df(DF_HALF, pws->h[0],  pwt->h[0]);
3098    pwd->h[1]  = msa_hsub_s_df(DF_HALF, pws->h[1],  pwt->h[1]);
3099    pwd->h[2]  = msa_hsub_s_df(DF_HALF, pws->h[2],  pwt->h[2]);
3100    pwd->h[3]  = msa_hsub_s_df(DF_HALF, pws->h[3],  pwt->h[3]);
3101    pwd->h[4]  = msa_hsub_s_df(DF_HALF, pws->h[4],  pwt->h[4]);
3102    pwd->h[5]  = msa_hsub_s_df(DF_HALF, pws->h[5],  pwt->h[5]);
3103    pwd->h[6]  = msa_hsub_s_df(DF_HALF, pws->h[6],  pwt->h[6]);
3104    pwd->h[7]  = msa_hsub_s_df(DF_HALF, pws->h[7],  pwt->h[7]);
3105}
3106
3107void helper_msa_hsub_s_w(CPUMIPSState *env,
3108                         uint32_t wd, uint32_t ws, uint32_t wt)
3109{
3110    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3111    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3112    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3113
3114    pwd->w[0]  = msa_hsub_s_df(DF_WORD, pws->w[0],  pwt->w[0]);
3115    pwd->w[1]  = msa_hsub_s_df(DF_WORD, pws->w[1],  pwt->w[1]);
3116    pwd->w[2]  = msa_hsub_s_df(DF_WORD, pws->w[2],  pwt->w[2]);
3117    pwd->w[3]  = msa_hsub_s_df(DF_WORD, pws->w[3],  pwt->w[3]);
3118}
3119
3120void helper_msa_hsub_s_d(CPUMIPSState *env,
3121                         uint32_t wd, uint32_t ws, uint32_t wt)
3122{
3123    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3124    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3125    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3126
3127    pwd->d[0]  = msa_hsub_s_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3128    pwd->d[1]  = msa_hsub_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3129}
3130
3131
3132static inline int64_t msa_hsub_u_df(uint32_t df, int64_t arg1, int64_t arg2)
3133{
3134    return UNSIGNED_ODD(arg1, df) - UNSIGNED_EVEN(arg2, df);
3135}
3136
3137void helper_msa_hsub_u_h(CPUMIPSState *env,
3138                         uint32_t wd, uint32_t ws, uint32_t wt)
3139{
3140    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3141    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3142    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3143
3144    pwd->h[0]  = msa_hsub_u_df(DF_HALF, pws->h[0],  pwt->h[0]);
3145    pwd->h[1]  = msa_hsub_u_df(DF_HALF, pws->h[1],  pwt->h[1]);
3146    pwd->h[2]  = msa_hsub_u_df(DF_HALF, pws->h[2],  pwt->h[2]);
3147    pwd->h[3]  = msa_hsub_u_df(DF_HALF, pws->h[3],  pwt->h[3]);
3148    pwd->h[4]  = msa_hsub_u_df(DF_HALF, pws->h[4],  pwt->h[4]);
3149    pwd->h[5]  = msa_hsub_u_df(DF_HALF, pws->h[5],  pwt->h[5]);
3150    pwd->h[6]  = msa_hsub_u_df(DF_HALF, pws->h[6],  pwt->h[6]);
3151    pwd->h[7]  = msa_hsub_u_df(DF_HALF, pws->h[7],  pwt->h[7]);
3152}
3153
3154void helper_msa_hsub_u_w(CPUMIPSState *env,
3155                         uint32_t wd, uint32_t ws, uint32_t wt)
3156{
3157    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3158    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3159    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3160
3161    pwd->w[0]  = msa_hsub_u_df(DF_WORD, pws->w[0],  pwt->w[0]);
3162    pwd->w[1]  = msa_hsub_u_df(DF_WORD, pws->w[1],  pwt->w[1]);
3163    pwd->w[2]  = msa_hsub_u_df(DF_WORD, pws->w[2],  pwt->w[2]);
3164    pwd->w[3]  = msa_hsub_u_df(DF_WORD, pws->w[3],  pwt->w[3]);
3165}
3166
3167void helper_msa_hsub_u_d(CPUMIPSState *env,
3168                         uint32_t wd, uint32_t ws, uint32_t wt)
3169{
3170    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3171    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3172    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3173
3174    pwd->d[0]  = msa_hsub_u_df(DF_DOUBLE, pws->d[0],  pwt->d[0]);
3175    pwd->d[1]  = msa_hsub_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
3176}
3177
3178
3179/*
3180 * Interleave
3181 * ----------
3182 *
3183 * +---------------+----------------------------------------------------------+
3184 * | ILVEV.B       | Vector Interleave Even (byte)                            |
3185 * | ILVEV.H       | Vector Interleave Even (halfword)                        |
3186 * | ILVEV.W       | Vector Interleave Even (word)                            |
3187 * | ILVEV.D       | Vector Interleave Even (doubleword)                      |
3188 * | ILVOD.B       | Vector Interleave Odd (byte)                             |
3189 * | ILVOD.H       | Vector Interleave Odd (halfword)                         |
3190 * | ILVOD.W       | Vector Interleave Odd (word)                             |
3191 * | ILVOD.D       | Vector Interleave Odd (doubleword)                       |
3192 * | ILVL.B        | Vector Interleave Left (byte)                            |
3193 * | ILVL.H        | Vector Interleave Left (halfword)                        |
3194 * | ILVL.W        | Vector Interleave Left (word)                            |
3195 * | ILVL.D        | Vector Interleave Left (doubleword)                      |
3196 * | ILVR.B        | Vector Interleave Right (byte)                           |
3197 * | ILVR.H        | Vector Interleave Right (halfword)                       |
3198 * | ILVR.W        | Vector Interleave Right (word)                           |
3199 * | ILVR.D        | Vector Interleave Right (doubleword)                     |
3200 * +---------------+----------------------------------------------------------+
3201 */
3202
3203
3204void helper_msa_ilvev_b(CPUMIPSState *env,
3205                        uint32_t wd, uint32_t ws, uint32_t wt)
3206{
3207    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3208    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3209    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3210
3211#if defined(HOST_WORDS_BIGENDIAN)
3212    pwd->b[8]  = pws->b[9];
3213    pwd->b[9]  = pwt->b[9];
3214    pwd->b[10] = pws->b[11];
3215    pwd->b[11] = pwt->b[11];
3216    pwd->b[12] = pws->b[13];
3217    pwd->b[13] = pwt->b[13];
3218    pwd->b[14] = pws->b[15];
3219    pwd->b[15] = pwt->b[15];
3220    pwd->b[0]  = pws->b[1];
3221    pwd->b[1]  = pwt->b[1];
3222    pwd->b[2]  = pws->b[3];
3223    pwd->b[3]  = pwt->b[3];
3224    pwd->b[4]  = pws->b[5];
3225    pwd->b[5]  = pwt->b[5];
3226    pwd->b[6]  = pws->b[7];
3227    pwd->b[7]  = pwt->b[7];
3228#else
3229    pwd->b[15] = pws->b[14];
3230    pwd->b[14] = pwt->b[14];
3231    pwd->b[13] = pws->b[12];
3232    pwd->b[12] = pwt->b[12];
3233    pwd->b[11] = pws->b[10];
3234    pwd->b[10] = pwt->b[10];
3235    pwd->b[9]  = pws->b[8];
3236    pwd->b[8]  = pwt->b[8];
3237    pwd->b[7]  = pws->b[6];
3238    pwd->b[6]  = pwt->b[6];
3239    pwd->b[5]  = pws->b[4];
3240    pwd->b[4]  = pwt->b[4];
3241    pwd->b[3]  = pws->b[2];
3242    pwd->b[2]  = pwt->b[2];
3243    pwd->b[1]  = pws->b[0];
3244    pwd->b[0]  = pwt->b[0];
3245#endif
3246}
3247
3248void helper_msa_ilvev_h(CPUMIPSState *env,
3249                        uint32_t wd, uint32_t ws, uint32_t wt)
3250{
3251    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3252    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3253    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3254
3255#if defined(HOST_WORDS_BIGENDIAN)
3256    pwd->h[4] = pws->h[5];
3257    pwd->h[5] = pwt->h[5];
3258    pwd->h[6] = pws->h[7];
3259    pwd->h[7] = pwt->h[7];
3260    pwd->h[0] = pws->h[1];
3261    pwd->h[1] = pwt->h[1];
3262    pwd->h[2] = pws->h[3];
3263    pwd->h[3] = pwt->h[3];
3264#else
3265    pwd->h[7] = pws->h[6];
3266    pwd->h[6] = pwt->h[6];
3267    pwd->h[5] = pws->h[4];
3268    pwd->h[4] = pwt->h[4];
3269    pwd->h[3] = pws->h[2];
3270    pwd->h[2] = pwt->h[2];
3271    pwd->h[1] = pws->h[0];
3272    pwd->h[0] = pwt->h[0];
3273#endif
3274}
3275
3276void helper_msa_ilvev_w(CPUMIPSState *env,
3277                        uint32_t wd, uint32_t ws, uint32_t wt)
3278{
3279    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3280    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3281    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3282
3283#if defined(HOST_WORDS_BIGENDIAN)
3284    pwd->w[2] = pws->w[3];
3285    pwd->w[3] = pwt->w[3];
3286    pwd->w[0] = pws->w[1];
3287    pwd->w[1] = pwt->w[1];
3288#else
3289    pwd->w[3] = pws->w[2];
3290    pwd->w[2] = pwt->w[2];
3291    pwd->w[1] = pws->w[0];
3292    pwd->w[0] = pwt->w[0];
3293#endif
3294}
3295
3296void helper_msa_ilvev_d(CPUMIPSState *env,
3297                        uint32_t wd, uint32_t ws, uint32_t wt)
3298{
3299    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3300    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3301    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3302
3303    pwd->d[1] = pws->d[0];
3304    pwd->d[0] = pwt->d[0];
3305}
3306
3307
3308void helper_msa_ilvod_b(CPUMIPSState *env,
3309                        uint32_t wd, uint32_t ws, uint32_t wt)
3310{
3311    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3312    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3313    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3314
3315#if defined(HOST_WORDS_BIGENDIAN)
3316    pwd->b[7]  = pwt->b[6];
3317    pwd->b[6]  = pws->b[6];
3318    pwd->b[5]  = pwt->b[4];
3319    pwd->b[4]  = pws->b[4];
3320    pwd->b[3]  = pwt->b[2];
3321    pwd->b[2]  = pws->b[2];
3322    pwd->b[1]  = pwt->b[0];
3323    pwd->b[0]  = pws->b[0];
3324    pwd->b[15] = pwt->b[14];
3325    pwd->b[14] = pws->b[14];
3326    pwd->b[13] = pwt->b[12];
3327    pwd->b[12] = pws->b[12];
3328    pwd->b[11] = pwt->b[10];
3329    pwd->b[10] = pws->b[10];
3330    pwd->b[9]  = pwt->b[8];
3331    pwd->b[8]  = pws->b[8];
3332#else
3333    pwd->b[0]  = pwt->b[1];
3334    pwd->b[1]  = pws->b[1];
3335    pwd->b[2]  = pwt->b[3];
3336    pwd->b[3]  = pws->b[3];
3337    pwd->b[4]  = pwt->b[5];
3338    pwd->b[5]  = pws->b[5];
3339    pwd->b[6]  = pwt->b[7];
3340    pwd->b[7]  = pws->b[7];
3341    pwd->b[8]  = pwt->b[9];
3342    pwd->b[9]  = pws->b[9];
3343    pwd->b[10] = pwt->b[11];
3344    pwd->b[11] = pws->b[11];
3345    pwd->b[12] = pwt->b[13];
3346    pwd->b[13] = pws->b[13];
3347    pwd->b[14] = pwt->b[15];
3348    pwd->b[15] = pws->b[15];
3349#endif
3350}
3351
3352void helper_msa_ilvod_h(CPUMIPSState *env,
3353                        uint32_t wd, uint32_t ws, uint32_t wt)
3354{
3355    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3356    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3357    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3358
3359#if defined(HOST_WORDS_BIGENDIAN)
3360    pwd->h[3] = pwt->h[2];
3361    pwd->h[2] = pws->h[2];
3362    pwd->h[1] = pwt->h[0];
3363    pwd->h[0] = pws->h[0];
3364    pwd->h[7] = pwt->h[6];
3365    pwd->h[6] = pws->h[6];
3366    pwd->h[5] = pwt->h[4];
3367    pwd->h[4] = pws->h[4];
3368#else
3369    pwd->h[0] = pwt->h[1];
3370    pwd->h[1] = pws->h[1];
3371    pwd->h[2] = pwt->h[3];
3372    pwd->h[3] = pws->h[3];
3373    pwd->h[4] = pwt->h[5];
3374    pwd->h[5] = pws->h[5];
3375    pwd->h[6] = pwt->h[7];
3376    pwd->h[7] = pws->h[7];
3377#endif
3378}
3379
3380void helper_msa_ilvod_w(CPUMIPSState *env,
3381                        uint32_t wd, uint32_t ws, uint32_t wt)
3382{
3383    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3384    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3385    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3386
3387#if defined(HOST_WORDS_BIGENDIAN)
3388    pwd->w[1] = pwt->w[0];
3389    pwd->w[0] = pws->w[0];
3390    pwd->w[3] = pwt->w[2];
3391    pwd->w[2] = pws->w[2];
3392#else
3393    pwd->w[0] = pwt->w[1];
3394    pwd->w[1] = pws->w[1];
3395    pwd->w[2] = pwt->w[3];
3396    pwd->w[3] = pws->w[3];
3397#endif
3398}
3399
3400void helper_msa_ilvod_d(CPUMIPSState *env,
3401                        uint32_t wd, uint32_t ws, uint32_t wt)
3402{
3403    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3404    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3405    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3406
3407    pwd->d[0] = pwt->d[1];
3408    pwd->d[1] = pws->d[1];
3409}
3410
3411
3412void helper_msa_ilvl_b(CPUMIPSState *env,
3413                       uint32_t wd, uint32_t ws, uint32_t wt)
3414{
3415    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3416    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3417    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3418
3419#if defined(HOST_WORDS_BIGENDIAN)
3420    pwd->b[7]  = pwt->b[15];
3421    pwd->b[6]  = pws->b[15];
3422    pwd->b[5]  = pwt->b[14];
3423    pwd->b[4]  = pws->b[14];
3424    pwd->b[3]  = pwt->b[13];
3425    pwd->b[2]  = pws->b[13];
3426    pwd->b[1]  = pwt->b[12];
3427    pwd->b[0]  = pws->b[12];
3428    pwd->b[15] = pwt->b[11];
3429    pwd->b[14] = pws->b[11];
3430    pwd->b[13] = pwt->b[10];
3431    pwd->b[12] = pws->b[10];
3432    pwd->b[11] = pwt->b[9];
3433    pwd->b[10] = pws->b[9];
3434    pwd->b[9]  = pwt->b[8];
3435    pwd->b[8]  = pws->b[8];
3436#else
3437    pwd->b[0]  = pwt->b[8];
3438    pwd->b[1]  = pws->b[8];
3439    pwd->b[2]  = pwt->b[9];
3440    pwd->b[3]  = pws->b[9];
3441    pwd->b[4]  = pwt->b[10];
3442    pwd->b[5]  = pws->b[10];
3443    pwd->b[6]  = pwt->b[11];
3444    pwd->b[7]  = pws->b[11];
3445    pwd->b[8]  = pwt->b[12];
3446    pwd->b[9]  = pws->b[12];
3447    pwd->b[10] = pwt->b[13];
3448    pwd->b[11] = pws->b[13];
3449    pwd->b[12] = pwt->b[14];
3450    pwd->b[13] = pws->b[14];
3451    pwd->b[14] = pwt->b[15];
3452    pwd->b[15] = pws->b[15];
3453#endif
3454}
3455
3456void helper_msa_ilvl_h(CPUMIPSState *env,
3457                       uint32_t wd, uint32_t ws, uint32_t wt)
3458{
3459    wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3460    wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3461    wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3462
3463#if defined(HOST_WORDS_BIGENDIAN)
3464    pwd->h[3] = pwt->h[7];
3465    pwd->h[2] = pws->h[7];
3466    pwd->h[1] = pwt->h[6];
3467    pwd->