blob: 4065cfe4f742df618075a8a7ffc339462d0f3db6 [file] [log] [blame]
/*
* MIPS SIMD Architecture Module Instruction emulation helpers for QEMU.
*
* Copyright (c) 2014 Imagination Technologies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "cpu.h"
#include "internal.h"
#include "exec/exec-all.h"
#include "exec/helper-proto.h"
#include "fpu/softfloat.h"
/* Data format min and max values */
#define DF_BITS(df) (1 << ((df) + 3))
#define DF_MAX_INT(df) (int64_t)((1LL << (DF_BITS(df) - 1)) - 1)
#define M_MAX_INT(m) (int64_t)((1LL << ((m) - 1)) - 1)
#define DF_MIN_INT(df) (int64_t)(-(1LL << (DF_BITS(df) - 1)))
#define M_MIN_INT(m) (int64_t)(-(1LL << ((m) - 1)))
#define DF_MAX_UINT(df) (uint64_t)(-1ULL >> (64 - DF_BITS(df)))
#define M_MAX_UINT(m) (uint64_t)(-1ULL >> (64 - (m)))
#define UNSIGNED(x, df) ((x) & DF_MAX_UINT(df))
#define SIGNED(x, df) \
((((int64_t)x) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df)))
/* Element-by-element access macros */
#define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df))
/*
* Bit Count
* ---------
*
* +---------------+----------------------------------------------------------+
* | NLOC.B | Vector Leading Ones Count (byte) |
* | NLOC.H | Vector Leading Ones Count (halfword) |
* | NLOC.W | Vector Leading Ones Count (word) |
* | NLOC.D | Vector Leading Ones Count (doubleword) |
* | NLZC.B | Vector Leading Zeros Count (byte) |
* | NLZC.H | Vector Leading Zeros Count (halfword) |
* | NLZC.W | Vector Leading Zeros Count (word) |
* | NLZC.D | Vector Leading Zeros Count (doubleword) |
* | PCNT.B | Vector Population Count (byte) |
* | PCNT.H | Vector Population Count (halfword) |
* | PCNT.W | Vector Population Count (word) |
* | PCNT.D | Vector Population Count (doubleword) |
* +---------------+----------------------------------------------------------+
*/
static inline int64_t msa_nlzc_df(uint32_t df, int64_t arg)
{
uint64_t x, y;
int n, c;
x = UNSIGNED(arg, df);
n = DF_BITS(df);
c = DF_BITS(df) / 2;
do {
y = x >> c;
if (y != 0) {
n = n - c;
x = y;
}
c = c >> 1;
} while (c != 0);
return n - x;
}
static inline int64_t msa_nloc_df(uint32_t df, int64_t arg)
{
return msa_nlzc_df(df, UNSIGNED((~arg), df));
}
void helper_msa_nloc_b(CPUMIPSState *env, uint32_t wd, uint32_t ws)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
pwd->b[0] = msa_nloc_df(DF_BYTE, pws->b[0]);
pwd->b[1] = msa_nloc_df(DF_BYTE, pws->b[1]);
pwd->b[2] = msa_nloc_df(DF_BYTE, pws->b[2]);
pwd->b[3] = msa_nloc_df(DF_BYTE, pws->b[3]);
pwd->b[4] = msa_nloc_df(DF_BYTE, pws->b[4]);
pwd->b[5] = msa_nloc_df(DF_BYTE, pws->b[5]);
pwd->b[6] = msa_nloc_df(DF_BYTE, pws->b[6]);
pwd->b[7] = msa_nloc_df(DF_BYTE, pws->b[7]);
pwd->b[8] = msa_nloc_df(DF_BYTE, pws->b[8]);
pwd->b[9] = msa_nloc_df(DF_BYTE, pws->b[9]);
pwd->b[10] = msa_nloc_df(DF_BYTE, pws->b[10]);
pwd->b[11] = msa_nloc_df(DF_BYTE, pws->b[11]);
pwd->b[12] = msa_nloc_df(DF_BYTE, pws->b[12]);
pwd->b[13] = msa_nloc_df(DF_BYTE, pws->b[13]);
pwd->b[14] = msa_nloc_df(DF_BYTE, pws->b[14]);
pwd->b[15] = msa_nloc_df(DF_BYTE, pws->b[15]);
}
void helper_msa_nloc_h(CPUMIPSState *env, uint32_t wd, uint32_t ws)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
pwd->h[0] = msa_nloc_df(DF_HALF, pws->h[0]);
pwd->h[1] = msa_nloc_df(DF_HALF, pws->h[1]);
pwd->h[2] = msa_nloc_df(DF_HALF, pws->h[2]);
pwd->h[3] = msa_nloc_df(DF_HALF, pws->h[3]);
pwd->h[4] = msa_nloc_df(DF_HALF, pws->h[4]);
pwd->h[5] = msa_nloc_df(DF_HALF, pws->h[5]);
pwd->h[6] = msa_nloc_df(DF_HALF, pws->h[6]);
pwd->h[7] = msa_nloc_df(DF_HALF, pws->h[7]);
}
void helper_msa_nloc_w(CPUMIPSState *env, uint32_t wd, uint32_t ws)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
pwd->w[0] = msa_nloc_df(DF_WORD, pws->w[0]);
pwd->w[1] = msa_nloc_df(DF_WORD, pws->w[1]);
pwd->w[2] = msa_nloc_df(DF_WORD, pws->w[2]);
pwd->w[3] = msa_nloc_df(DF_WORD, pws->w[3]);
}
void helper_msa_nloc_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
pwd->d[0] = msa_nloc_df(DF_DOUBLE, pws->d[0]);
pwd->d[1] = msa_nloc_df(DF_DOUBLE, pws->d[1]);
}
void helper_msa_nlzc_b(CPUMIPSState *env, uint32_t wd, uint32_t ws)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
pwd->b[0] = msa_nlzc_df(DF_BYTE, pws->b[0]);
pwd->b[1] = msa_nlzc_df(DF_BYTE, pws->b[1]);
pwd->b[2] = msa_nlzc_df(DF_BYTE, pws->b[2]);
pwd->b[3] = msa_nlzc_df(DF_BYTE, pws->b[3]);
pwd->b[4] = msa_nlzc_df(DF_BYTE, pws->b[4]);
pwd->b[5] = msa_nlzc_df(DF_BYTE, pws->b[5]);
pwd->b[6] = msa_nlzc_df(DF_BYTE, pws->b[6]);
pwd->b[7] = msa_nlzc_df(DF_BYTE, pws->b[7]);
pwd->b[8] = msa_nlzc_df(DF_BYTE, pws->b[8]);
pwd->b[9] = msa_nlzc_df(DF_BYTE, pws->b[9]);
pwd->b[10] = msa_nlzc_df(DF_BYTE, pws->b[10]);
pwd->b[11] = msa_nlzc_df(DF_BYTE, pws->b[11]);
pwd->b[12] = msa_nlzc_df(DF_BYTE, pws->b[12]);
pwd->b[13] = msa_nlzc_df(DF_BYTE, pws->b[13]);
pwd->b[14] = msa_nlzc_df(DF_BYTE, pws->b[14]);
pwd->b[15] = msa_nlzc_df(DF_BYTE, pws->b[15]);
}
void helper_msa_nlzc_h(CPUMIPSState *env, uint32_t wd, uint32_t ws)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
pwd->h[0] = msa_nlzc_df(DF_HALF, pws->h[0]);
pwd->h[1] = msa_nlzc_df(DF_HALF, pws->h[1]);
pwd->h[2] = msa_nlzc_df(DF_HALF, pws->h[2]);
pwd->h[3] = msa_nlzc_df(DF_HALF, pws->h[3]);
pwd->h[4] = msa_nlzc_df(DF_HALF, pws->h[4]);
pwd->h[5] = msa_nlzc_df(DF_HALF, pws->h[5]);
pwd->h[6] = msa_nlzc_df(DF_HALF, pws->h[6]);
pwd->h[7] = msa_nlzc_df(DF_HALF, pws->h[7]);
}
void helper_msa_nlzc_w(CPUMIPSState *env, uint32_t wd, uint32_t ws)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
pwd->w[0] = msa_nlzc_df(DF_WORD, pws->w[0]);
pwd->w[1] = msa_nlzc_df(DF_WORD, pws->w[1]);
pwd->w[2] = msa_nlzc_df(DF_WORD, pws->w[2]);
pwd->w[3] = msa_nlzc_df(DF_WORD, pws->w[3]);
}
void helper_msa_nlzc_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
pwd->d[0] = msa_nlzc_df(DF_DOUBLE, pws->d[0]);
pwd->d[1] = msa_nlzc_df(DF_DOUBLE, pws->d[1]);
}
static inline int64_t msa_pcnt_df(uint32_t df, int64_t arg)
{
uint64_t x;
x = UNSIGNED(arg, df);
x = (x & 0x5555555555555555ULL) + ((x >> 1) & 0x5555555555555555ULL);
x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL);
x = (x & 0x0F0F0F0F0F0F0F0FULL) + ((x >> 4) & 0x0F0F0F0F0F0F0F0FULL);
x = (x & 0x00FF00FF00FF00FFULL) + ((x >> 8) & 0x00FF00FF00FF00FFULL);
x = (x & 0x0000FFFF0000FFFFULL) + ((x >> 16) & 0x0000FFFF0000FFFFULL);
x = (x & 0x00000000FFFFFFFFULL) + ((x >> 32));
return x;
}
void helper_msa_pcnt_b(CPUMIPSState *env, uint32_t wd, uint32_t ws)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
pwd->b[0] = msa_pcnt_df(DF_BYTE, pws->b[0]);
pwd->b[1] = msa_pcnt_df(DF_BYTE, pws->b[1]);
pwd->b[2] = msa_pcnt_df(DF_BYTE, pws->b[2]);
pwd->b[3] = msa_pcnt_df(DF_BYTE, pws->b[3]);
pwd->b[4] = msa_pcnt_df(DF_BYTE, pws->b[4]);
pwd->b[5] = msa_pcnt_df(DF_BYTE, pws->b[5]);
pwd->b[6] = msa_pcnt_df(DF_BYTE, pws->b[6]);
pwd->b[7] = msa_pcnt_df(DF_BYTE, pws->b[7]);
pwd->b[8] = msa_pcnt_df(DF_BYTE, pws->b[8]);
pwd->b[9] = msa_pcnt_df(DF_BYTE, pws->b[9]);
pwd->b[10] = msa_pcnt_df(DF_BYTE, pws->b[10]);
pwd->b[11] = msa_pcnt_df(DF_BYTE, pws->b[11]);
pwd->b[12] = msa_pcnt_df(DF_BYTE, pws->b[12]);
pwd->b[13] = msa_pcnt_df(DF_BYTE, pws->b[13]);
pwd->b[14] = msa_pcnt_df(DF_BYTE, pws->b[14]);
pwd->b[15] = msa_pcnt_df(DF_BYTE, pws->b[15]);
}
void helper_msa_pcnt_h(CPUMIPSState *env, uint32_t wd, uint32_t ws)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
pwd->h[0] = msa_pcnt_df(DF_HALF, pws->h[0]);
pwd->h[1] = msa_pcnt_df(DF_HALF, pws->h[1]);
pwd->h[2] = msa_pcnt_df(DF_HALF, pws->h[2]);
pwd->h[3] = msa_pcnt_df(DF_HALF, pws->h[3]);
pwd->h[4] = msa_pcnt_df(DF_HALF, pws->h[4]);
pwd->h[5] = msa_pcnt_df(DF_HALF, pws->h[5]);
pwd->h[6] = msa_pcnt_df(DF_HALF, pws->h[6]);
pwd->h[7] = msa_pcnt_df(DF_HALF, pws->h[7]);
}
void helper_msa_pcnt_w(CPUMIPSState *env, uint32_t wd, uint32_t ws)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
pwd->w[0] = msa_pcnt_df(DF_WORD, pws->w[0]);
pwd->w[1] = msa_pcnt_df(DF_WORD, pws->w[1]);
pwd->w[2] = msa_pcnt_df(DF_WORD, pws->w[2]);
pwd->w[3] = msa_pcnt_df(DF_WORD, pws->w[3]);
}
void helper_msa_pcnt_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
pwd->d[0] = msa_pcnt_df(DF_DOUBLE, pws->d[0]);
pwd->d[1] = msa_pcnt_df(DF_DOUBLE, pws->d[1]);
}
/*
* Bit Move
* --------
*
* +---------------+----------------------------------------------------------+
* | BINSL.B | Vector Bit Insert Left (byte) |
* | BINSL.H | Vector Bit Insert Left (halfword) |
* | BINSL.W | Vector Bit Insert Left (word) |
* | BINSL.D | Vector Bit Insert Left (doubleword) |
* | BINSR.B | Vector Bit Insert Right (byte) |
* | BINSR.H | Vector Bit Insert Right (halfword) |
* | BINSR.W | Vector Bit Insert Right (word) |
* | BINSR.D | Vector Bit Insert Right (doubleword) |
* | BMNZ.V | Vector Bit Move If Not Zero |
* | BMZ.V | Vector Bit Move If Zero |
* | BSEL.V | Vector Bit Select |
* +---------------+----------------------------------------------------------+
*/
/* Data format bit position and unsigned values */
#define BIT_POSITION(x, df) ((uint64_t)(x) % DF_BITS(df))
static inline int64_t msa_binsl_df(uint32_t df,
int64_t dest, int64_t arg1, int64_t arg2)
{
uint64_t u_arg1 = UNSIGNED(arg1, df);
uint64_t u_dest = UNSIGNED(dest, df);
int32_t sh_d = BIT_POSITION(arg2, df) + 1;
int32_t sh_a = DF_BITS(df) - sh_d;
if (sh_d == DF_BITS(df)) {
return u_arg1;
} else {
return UNSIGNED(UNSIGNED(u_dest << sh_d, df) >> sh_d, df) |
UNSIGNED(UNSIGNED(u_arg1 >> sh_a, df) << sh_a, df);
}
}
void helper_msa_binsl_b(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_binsl_df(DF_BYTE, pwd->b[0], pws->b[0], pwt->b[0]);
pwd->b[1] = msa_binsl_df(DF_BYTE, pwd->b[1], pws->b[1], pwt->b[1]);
pwd->b[2] = msa_binsl_df(DF_BYTE, pwd->b[2], pws->b[2], pwt->b[2]);
pwd->b[3] = msa_binsl_df(DF_BYTE, pwd->b[3], pws->b[3], pwt->b[3]);
pwd->b[4] = msa_binsl_df(DF_BYTE, pwd->b[4], pws->b[4], pwt->b[4]);
pwd->b[5] = msa_binsl_df(DF_BYTE, pwd->b[5], pws->b[5], pwt->b[5]);
pwd->b[6] = msa_binsl_df(DF_BYTE, pwd->b[6], pws->b[6], pwt->b[6]);
pwd->b[7] = msa_binsl_df(DF_BYTE, pwd->b[7], pws->b[7], pwt->b[7]);
pwd->b[8] = msa_binsl_df(DF_BYTE, pwd->b[8], pws->b[8], pwt->b[8]);
pwd->b[9] = msa_binsl_df(DF_BYTE, pwd->b[9], pws->b[9], pwt->b[9]);
pwd->b[10] = msa_binsl_df(DF_BYTE, pwd->b[10], pws->b[10], pwt->b[10]);
pwd->b[11] = msa_binsl_df(DF_BYTE, pwd->b[11], pws->b[11], pwt->b[11]);
pwd->b[12] = msa_binsl_df(DF_BYTE, pwd->b[12], pws->b[12], pwt->b[12]);
pwd->b[13] = msa_binsl_df(DF_BYTE, pwd->b[13], pws->b[13], pwt->b[13]);
pwd->b[14] = msa_binsl_df(DF_BYTE, pwd->b[14], pws->b[14], pwt->b[14]);
pwd->b[15] = msa_binsl_df(DF_BYTE, pwd->b[15], pws->b[15], pwt->b[15]);
}
void helper_msa_binsl_h(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_binsl_df(DF_HALF, pwd->h[0], pws->h[0], pwt->h[0]);
pwd->h[1] = msa_binsl_df(DF_HALF, pwd->h[1], pws->h[1], pwt->h[1]);
pwd->h[2] = msa_binsl_df(DF_HALF, pwd->h[2], pws->h[2], pwt->h[2]);
pwd->h[3] = msa_binsl_df(DF_HALF, pwd->h[3], pws->h[3], pwt->h[3]);
pwd->h[4] = msa_binsl_df(DF_HALF, pwd->h[4], pws->h[4], pwt->h[4]);
pwd->h[5] = msa_binsl_df(DF_HALF, pwd->h[5], pws->h[5], pwt->h[5]);
pwd->h[6] = msa_binsl_df(DF_HALF, pwd->h[6], pws->h[6], pwt->h[6]);
pwd->h[7] = msa_binsl_df(DF_HALF, pwd->h[7], pws->h[7], pwt->h[7]);
}
void helper_msa_binsl_w(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_binsl_df(DF_WORD, pwd->w[0], pws->w[0], pwt->w[0]);
pwd->w[1] = msa_binsl_df(DF_WORD, pwd->w[1], pws->w[1], pwt->w[1]);
pwd->w[2] = msa_binsl_df(DF_WORD, pwd->w[2], pws->w[2], pwt->w[2]);
pwd->w[3] = msa_binsl_df(DF_WORD, pwd->w[3], pws->w[3], pwt->w[3]);
}
void helper_msa_binsl_d(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_binsl_df(DF_DOUBLE, pwd->d[0], pws->d[0], pwt->d[0]);
pwd->d[1] = msa_binsl_df(DF_DOUBLE, pwd->d[1], pws->d[1], pwt->d[1]);
}
static inline int64_t msa_binsr_df(uint32_t df,
int64_t dest, int64_t arg1, int64_t arg2)
{
uint64_t u_arg1 = UNSIGNED(arg1, df);
uint64_t u_dest = UNSIGNED(dest, df);
int32_t sh_d = BIT_POSITION(arg2, df) + 1;
int32_t sh_a = DF_BITS(df) - sh_d;
if (sh_d == DF_BITS(df)) {
return u_arg1;
} else {
return UNSIGNED(UNSIGNED(u_dest >> sh_d, df) << sh_d, df) |
UNSIGNED(UNSIGNED(u_arg1 << sh_a, df) >> sh_a, df);
}
}
void helper_msa_binsr_b(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_binsr_df(DF_BYTE, pwd->b[0], pws->b[0], pwt->b[0]);
pwd->b[1] = msa_binsr_df(DF_BYTE, pwd->b[1], pws->b[1], pwt->b[1]);
pwd->b[2] = msa_binsr_df(DF_BYTE, pwd->b[2], pws->b[2], pwt->b[2]);
pwd->b[3] = msa_binsr_df(DF_BYTE, pwd->b[3], pws->b[3], pwt->b[3]);
pwd->b[4] = msa_binsr_df(DF_BYTE, pwd->b[4], pws->b[4], pwt->b[4]);
pwd->b[5] = msa_binsr_df(DF_BYTE, pwd->b[5], pws->b[5], pwt->b[5]);
pwd->b[6] = msa_binsr_df(DF_BYTE, pwd->b[6], pws->b[6], pwt->b[6]);
pwd->b[7] = msa_binsr_df(DF_BYTE, pwd->b[7], pws->b[7], pwt->b[7]);
pwd->b[8] = msa_binsr_df(DF_BYTE, pwd->b[8], pws->b[8], pwt->b[8]);
pwd->b[9] = msa_binsr_df(DF_BYTE, pwd->b[9], pws->b[9], pwt->b[9]);
pwd->b[10] = msa_binsr_df(DF_BYTE, pwd->b[10], pws->b[10], pwt->b[10]);
pwd->b[11] = msa_binsr_df(DF_BYTE, pwd->b[11], pws->b[11], pwt->b[11]);
pwd->b[12] = msa_binsr_df(DF_BYTE, pwd->b[12], pws->b[12], pwt->b[12]);
pwd->b[13] = msa_binsr_df(DF_BYTE, pwd->b[13], pws->b[13], pwt->b[13]);
pwd->b[14] = msa_binsr_df(DF_BYTE, pwd->b[14], pws->b[14], pwt->b[14]);
pwd->b[15] = msa_binsr_df(DF_BYTE, pwd->b[15], pws->b[15], pwt->b[15]);
}
void helper_msa_binsr_h(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_binsr_df(DF_HALF, pwd->h[0], pws->h[0], pwt->h[0]);
pwd->h[1] = msa_binsr_df(DF_HALF, pwd->h[1], pws->h[1], pwt->h[1]);
pwd->h[2] = msa_binsr_df(DF_HALF, pwd->h[2], pws->h[2], pwt->h[2]);
pwd->h[3] = msa_binsr_df(DF_HALF, pwd->h[3], pws->h[3], pwt->h[3]);
pwd->h[4] = msa_binsr_df(DF_HALF, pwd->h[4], pws->h[4], pwt->h[4]);
pwd->h[5] = msa_binsr_df(DF_HALF, pwd->h[5], pws->h[5], pwt->h[5]);
pwd->h[6] = msa_binsr_df(DF_HALF, pwd->h[6], pws->h[6], pwt->h[6]);
pwd->h[7] = msa_binsr_df(DF_HALF, pwd->h[7], pws->h[7], pwt->h[7]);
}
void helper_msa_binsr_w(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_binsr_df(DF_WORD, pwd->w[0], pws->w[0], pwt->w[0]);
pwd->w[1] = msa_binsr_df(DF_WORD, pwd->w[1], pws->w[1], pwt->w[1]);
pwd->w[2] = msa_binsr_df(DF_WORD, pwd->w[2], pws->w[2], pwt->w[2]);
pwd->w[3] = msa_binsr_df(DF_WORD, pwd->w[3], pws->w[3], pwt->w[3]);
}
void helper_msa_binsr_d(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_binsr_df(DF_DOUBLE, pwd->d[0], pws->d[0], pwt->d[0]);
pwd->d[1] = msa_binsr_df(DF_DOUBLE, pwd->d[1], pws->d[1], pwt->d[1]);
}
void helper_msa_bmnz_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = UNSIGNED( \
((pwd->d[0] & (~pwt->d[0])) | (pws->d[0] & pwt->d[0])), DF_DOUBLE);
pwd->d[1] = UNSIGNED( \
((pwd->d[1] & (~pwt->d[1])) | (pws->d[1] & pwt->d[1])), DF_DOUBLE);
}
void helper_msa_bmz_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = UNSIGNED( \
((pwd->d[0] & pwt->d[0]) | (pws->d[0] & (~pwt->d[0]))), DF_DOUBLE);
pwd->d[1] = UNSIGNED( \
((pwd->d[1] & pwt->d[1]) | (pws->d[1] & (~pwt->d[1]))), DF_DOUBLE);
}
void helper_msa_bsel_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = UNSIGNED( \
(pws->d[0] & (~pwd->d[0])) | (pwt->d[0] & pwd->d[0]), DF_DOUBLE);
pwd->d[1] = UNSIGNED( \
(pws->d[1] & (~pwd->d[1])) | (pwt->d[1] & pwd->d[1]), DF_DOUBLE);
}
/*
* Bit Set
* -------
*
* +---------------+----------------------------------------------------------+
* | BCLR.B | Vector Bit Clear (byte) |
* | BCLR.H | Vector Bit Clear (halfword) |
* | BCLR.W | Vector Bit Clear (word) |
* | BCLR.D | Vector Bit Clear (doubleword) |
* | BNEG.B | Vector Bit Negate (byte) |
* | BNEG.H | Vector Bit Negate (halfword) |
* | BNEG.W | Vector Bit Negate (word) |
* | BNEG.D | Vector Bit Negate (doubleword) |
* | BSET.B | Vector Bit Set (byte) |
* | BSET.H | Vector Bit Set (halfword) |
* | BSET.W | Vector Bit Set (word) |
* | BSET.D | Vector Bit Set (doubleword) |
* +---------------+----------------------------------------------------------+
*/
static inline int64_t msa_bclr_df(uint32_t df, int64_t arg1, int64_t arg2)
{
int32_t b_arg2 = BIT_POSITION(arg2, df);
return UNSIGNED(arg1 & (~(1LL << b_arg2)), df);
}
void helper_msa_bclr_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_bclr_df(DF_BYTE, pws->b[0], pwt->b[0]);
pwd->b[1] = msa_bclr_df(DF_BYTE, pws->b[1], pwt->b[1]);
pwd->b[2] = msa_bclr_df(DF_BYTE, pws->b[2], pwt->b[2]);
pwd->b[3] = msa_bclr_df(DF_BYTE, pws->b[3], pwt->b[3]);
pwd->b[4] = msa_bclr_df(DF_BYTE, pws->b[4], pwt->b[4]);
pwd->b[5] = msa_bclr_df(DF_BYTE, pws->b[5], pwt->b[5]);
pwd->b[6] = msa_bclr_df(DF_BYTE, pws->b[6], pwt->b[6]);
pwd->b[7] = msa_bclr_df(DF_BYTE, pws->b[7], pwt->b[7]);
pwd->b[8] = msa_bclr_df(DF_BYTE, pws->b[8], pwt->b[8]);
pwd->b[9] = msa_bclr_df(DF_BYTE, pws->b[9], pwt->b[9]);
pwd->b[10] = msa_bclr_df(DF_BYTE, pws->b[10], pwt->b[10]);
pwd->b[11] = msa_bclr_df(DF_BYTE, pws->b[11], pwt->b[11]);
pwd->b[12] = msa_bclr_df(DF_BYTE, pws->b[12], pwt->b[12]);
pwd->b[13] = msa_bclr_df(DF_BYTE, pws->b[13], pwt->b[13]);
pwd->b[14] = msa_bclr_df(DF_BYTE, pws->b[14], pwt->b[14]);
pwd->b[15] = msa_bclr_df(DF_BYTE, pws->b[15], pwt->b[15]);
}
void helper_msa_bclr_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_bclr_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_bclr_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_bclr_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_bclr_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_bclr_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_bclr_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_bclr_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_bclr_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_bclr_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_bclr_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_bclr_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_bclr_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_bclr_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_bclr_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_bclr_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_bclr_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
static inline int64_t msa_bneg_df(uint32_t df, int64_t arg1, int64_t arg2)
{
int32_t b_arg2 = BIT_POSITION(arg2, df);
return UNSIGNED(arg1 ^ (1LL << b_arg2), df);
}
void helper_msa_bneg_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_bneg_df(DF_BYTE, pws->b[0], pwt->b[0]);
pwd->b[1] = msa_bneg_df(DF_BYTE, pws->b[1], pwt->b[1]);
pwd->b[2] = msa_bneg_df(DF_BYTE, pws->b[2], pwt->b[2]);
pwd->b[3] = msa_bneg_df(DF_BYTE, pws->b[3], pwt->b[3]);
pwd->b[4] = msa_bneg_df(DF_BYTE, pws->b[4], pwt->b[4]);
pwd->b[5] = msa_bneg_df(DF_BYTE, pws->b[5], pwt->b[5]);
pwd->b[6] = msa_bneg_df(DF_BYTE, pws->b[6], pwt->b[6]);
pwd->b[7] = msa_bneg_df(DF_BYTE, pws->b[7], pwt->b[7]);
pwd->b[8] = msa_bneg_df(DF_BYTE, pws->b[8], pwt->b[8]);
pwd->b[9] = msa_bneg_df(DF_BYTE, pws->b[9], pwt->b[9]);
pwd->b[10] = msa_bneg_df(DF_BYTE, pws->b[10], pwt->b[10]);
pwd->b[11] = msa_bneg_df(DF_BYTE, pws->b[11], pwt->b[11]);
pwd->b[12] = msa_bneg_df(DF_BYTE, pws->b[12], pwt->b[12]);
pwd->b[13] = msa_bneg_df(DF_BYTE, pws->b[13], pwt->b[13]);
pwd->b[14] = msa_bneg_df(DF_BYTE, pws->b[14], pwt->b[14]);
pwd->b[15] = msa_bneg_df(DF_BYTE, pws->b[15], pwt->b[15]);
}
void helper_msa_bneg_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_bneg_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_bneg_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_bneg_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_bneg_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_bneg_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_bneg_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_bneg_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_bneg_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_bneg_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_bneg_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_bneg_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_bneg_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_bneg_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_bneg_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_bneg_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_bneg_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
static inline int64_t msa_bset_df(uint32_t df, int64_t arg1,
int64_t arg2)
{
int32_t b_arg2 = BIT_POSITION(arg2, df);
return UNSIGNED(arg1 | (1LL << b_arg2), df);
}
void helper_msa_bset_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_bset_df(DF_BYTE, pws->b[0], pwt->b[0]);
pwd->b[1] = msa_bset_df(DF_BYTE, pws->b[1], pwt->b[1]);
pwd->b[2] = msa_bset_df(DF_BYTE, pws->b[2], pwt->b[2]);
pwd->b[3] = msa_bset_df(DF_BYTE, pws->b[3], pwt->b[3]);
pwd->b[4] = msa_bset_df(DF_BYTE, pws->b[4], pwt->b[4]);
pwd->b[5] = msa_bset_df(DF_BYTE, pws->b[5], pwt->b[5]);
pwd->b[6] = msa_bset_df(DF_BYTE, pws->b[6], pwt->b[6]);
pwd->b[7] = msa_bset_df(DF_BYTE, pws->b[7], pwt->b[7]);
pwd->b[8] = msa_bset_df(DF_BYTE, pws->b[8], pwt->b[8]);
pwd->b[9] = msa_bset_df(DF_BYTE, pws->b[9], pwt->b[9]);
pwd->b[10] = msa_bset_df(DF_BYTE, pws->b[10], pwt->b[10]);
pwd->b[11] = msa_bset_df(DF_BYTE, pws->b[11], pwt->b[11]);
pwd->b[12] = msa_bset_df(DF_BYTE, pws->b[12], pwt->b[12]);
pwd->b[13] = msa_bset_df(DF_BYTE, pws->b[13], pwt->b[13]);
pwd->b[14] = msa_bset_df(DF_BYTE, pws->b[14], pwt->b[14]);
pwd->b[15] = msa_bset_df(DF_BYTE, pws->b[15], pwt->b[15]);
}
void helper_msa_bset_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_bset_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_bset_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_bset_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_bset_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_bset_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_bset_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_bset_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_bset_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_bset_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_bset_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_bset_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_bset_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_bset_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_bset_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_bset_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_bset_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
/*
* Fixed Multiply
* --------------
*
* +---------------+----------------------------------------------------------+
* | MADD_Q.H | Vector Fixed-Point Multiply and Add (halfword) |
* | MADD_Q.W | Vector Fixed-Point Multiply and Add (word) |
* | MADDR_Q.H | Vector Fixed-Point Multiply and Add Rounded (halfword) |
* | MADDR_Q.W | Vector Fixed-Point Multiply and Add Rounded (word) |
* | MSUB_Q.H | Vector Fixed-Point Multiply and Subtr. (halfword) |
* | MSUB_Q.W | Vector Fixed-Point Multiply and Subtr. (word) |
* | MSUBR_Q.H | Vector Fixed-Point Multiply and Subtr. Rounded (halfword)|
* | MSUBR_Q.W | Vector Fixed-Point Multiply and Subtr. Rounded (word) |
* | MUL_Q.H | Vector Fixed-Point Multiply (halfword) |
* | MUL_Q.W | Vector Fixed-Point Multiply (word) |
* | MULR_Q.H | Vector Fixed-Point Multiply Rounded (halfword) |
* | MULR_Q.W | Vector Fixed-Point Multiply Rounded (word) |
* +---------------+----------------------------------------------------------+
*/
/* TODO: insert Fixed Multiply group helpers here */
/*
* Float Max Min
* -------------
*
* +---------------+----------------------------------------------------------+
* | FMAX_A.W | Vector Floating-Point Maximum (Absolute) (word) |
* | FMAX_A.D | Vector Floating-Point Maximum (Absolute) (doubleword) |
* | FMAX.W | Vector Floating-Point Maximum (word) |
* | FMAX.D | Vector Floating-Point Maximum (doubleword) |
* | FMIN_A.W | Vector Floating-Point Minimum (Absolute) (word) |
* | FMIN_A.D | Vector Floating-Point Minimum (Absolute) (doubleword) |
* | FMIN.W | Vector Floating-Point Minimum (word) |
* | FMIN.D | Vector Floating-Point Minimum (doubleword) |
* +---------------+----------------------------------------------------------+
*/
/* TODO: insert Float Max Min group helpers here */
/*
* Int Add
* -------
*
* +---------------+----------------------------------------------------------+
* | ADD_A.B | Vector Add Absolute Values (byte) |
* | ADD_A.H | Vector Add Absolute Values (halfword) |
* | ADD_A.W | Vector Add Absolute Values (word) |
* | ADD_A.D | Vector Add Absolute Values (doubleword) |
* | ADDS_A.B | Vector Signed Saturated Add (of Absolute) (byte) |
* | ADDS_A.H | Vector Signed Saturated Add (of Absolute) (halfword) |
* | ADDS_A.W | Vector Signed Saturated Add (of Absolute) (word) |
* | ADDS_A.D | Vector Signed Saturated Add (of Absolute) (doubleword) |
* | ADDS_S.B | Vector Signed Saturated Add (of Signed) (byte) |
* | ADDS_S.H | Vector Signed Saturated Add (of Signed) (halfword) |
* | ADDS_S.W | Vector Signed Saturated Add (of Signed) (word) |
* | ADDS_S.D | Vector Signed Saturated Add (of Signed) (doubleword) |
* | ADDS_U.B | Vector Unsigned Saturated Add (of Unsigned) (byte) |
* | ADDS_U.H | Vector Unsigned Saturated Add (of Unsigned) (halfword) |
* | ADDS_U.W | Vector Unsigned Saturated Add (of Unsigned) (word) |
* | ADDS_U.D | Vector Unsigned Saturated Add (of Unsigned) (doubleword) |
* | ADDV.B | Vector Add (byte) |
* | ADDV.H | Vector Add (halfword) |
* | ADDV.W | Vector Add (word) |
* | ADDV.D | Vector Add (doubleword) |
* | HADD_S.H | Vector Signed Horizontal Add (halfword) |
* | HADD_S.W | Vector Signed Horizontal Add (word) |
* | HADD_S.D | Vector Signed Horizontal Add (doubleword) |
* | HADD_U.H | Vector Unigned Horizontal Add (halfword) |
* | HADD_U.W | Vector Unigned Horizontal Add (word) |
* | HADD_U.D | Vector Unigned Horizontal Add (doubleword) |
* +---------------+----------------------------------------------------------+
*/
static inline int64_t msa_add_a_df(uint32_t df, int64_t arg1, int64_t arg2)
{
uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
return abs_arg1 + abs_arg2;
}
void helper_msa_add_a_b(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_add_a_df(DF_BYTE, pws->b[0], pwt->b[0]);
pwd->b[1] = msa_add_a_df(DF_BYTE, pws->b[1], pwt->b[1]);
pwd->b[2] = msa_add_a_df(DF_BYTE, pws->b[2], pwt->b[2]);
pwd->b[3] = msa_add_a_df(DF_BYTE, pws->b[3], pwt->b[3]);
pwd->b[4] = msa_add_a_df(DF_BYTE, pws->b[4], pwt->b[4]);
pwd->b[5] = msa_add_a_df(DF_BYTE, pws->b[5], pwt->b[5]);
pwd->b[6] = msa_add_a_df(DF_BYTE, pws->b[6], pwt->b[6]);
pwd->b[7] = msa_add_a_df(DF_BYTE, pws->b[7], pwt->b[7]);
pwd->b[8] = msa_add_a_df(DF_BYTE, pws->b[8], pwt->b[8]);
pwd->b[9] = msa_add_a_df(DF_BYTE, pws->b[9], pwt->b[9]);
pwd->b[10] = msa_add_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
pwd->b[11] = msa_add_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
pwd->b[12] = msa_add_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
pwd->b[13] = msa_add_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
pwd->b[14] = msa_add_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
pwd->b[15] = msa_add_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
}
void helper_msa_add_a_h(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_add_a_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_add_a_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_add_a_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_add_a_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_add_a_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_add_a_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_add_a_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_add_a_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_add_a_w(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_add_a_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_add_a_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_add_a_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_add_a_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_add_a_d(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_add_a_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_add_a_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
static inline int64_t msa_adds_a_df(uint32_t df, int64_t arg1, int64_t arg2)
{
uint64_t max_int = (uint64_t)DF_MAX_INT(df);
uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
if (abs_arg1 > max_int || abs_arg2 > max_int) {
return (int64_t)max_int;
} else {
return (abs_arg1 < max_int - abs_arg2) ? abs_arg1 + abs_arg2 : max_int;
}
}
void helper_msa_adds_a_b(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_adds_a_df(DF_BYTE, pws->b[0], pwt->b[0]);
pwd->b[1] = msa_adds_a_df(DF_BYTE, pws->b[1], pwt->b[1]);
pwd->b[2] = msa_adds_a_df(DF_BYTE, pws->b[2], pwt->b[2]);
pwd->b[3] = msa_adds_a_df(DF_BYTE, pws->b[3], pwt->b[3]);
pwd->b[4] = msa_adds_a_df(DF_BYTE, pws->b[4], pwt->b[4]);
pwd->b[5] = msa_adds_a_df(DF_BYTE, pws->b[5], pwt->b[5]);
pwd->b[6] = msa_adds_a_df(DF_BYTE, pws->b[6], pwt->b[6]);
pwd->b[7] = msa_adds_a_df(DF_BYTE, pws->b[7], pwt->b[7]);
pwd->b[8] = msa_adds_a_df(DF_BYTE, pws->b[8], pwt->b[8]);
pwd->b[9] = msa_adds_a_df(DF_BYTE, pws->b[9], pwt->b[9]);
pwd->b[10] = msa_adds_a_df(DF_BYTE, pws->b[10], pwt->b[10]);
pwd->b[11] = msa_adds_a_df(DF_BYTE, pws->b[11], pwt->b[11]);
pwd->b[12] = msa_adds_a_df(DF_BYTE, pws->b[12], pwt->b[12]);
pwd->b[13] = msa_adds_a_df(DF_BYTE, pws->b[13], pwt->b[13]);
pwd->b[14] = msa_adds_a_df(DF_BYTE, pws->b[14], pwt->b[14]);
pwd->b[15] = msa_adds_a_df(DF_BYTE, pws->b[15], pwt->b[15]);
}
void helper_msa_adds_a_h(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_adds_a_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_adds_a_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_adds_a_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_adds_a_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_adds_a_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_adds_a_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_adds_a_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_adds_a_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_adds_a_w(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_adds_a_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_adds_a_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_adds_a_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_adds_a_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_adds_a_d(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_adds_a_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_adds_a_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
static inline int64_t msa_adds_s_df(uint32_t df, int64_t arg1, int64_t arg2)
{
int64_t max_int = DF_MAX_INT(df);
int64_t min_int = DF_MIN_INT(df);
if (arg1 < 0) {
return (min_int - arg1 < arg2) ? arg1 + arg2 : min_int;
} else {
return (arg2 < max_int - arg1) ? arg1 + arg2 : max_int;
}
}
void helper_msa_adds_s_b(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_adds_s_df(DF_BYTE, pws->b[0], pwt->b[0]);
pwd->b[1] = msa_adds_s_df(DF_BYTE, pws->b[1], pwt->b[1]);
pwd->b[2] = msa_adds_s_df(DF_BYTE, pws->b[2], pwt->b[2]);
pwd->b[3] = msa_adds_s_df(DF_BYTE, pws->b[3], pwt->b[3]);
pwd->b[4] = msa_adds_s_df(DF_BYTE, pws->b[4], pwt->b[4]);
pwd->b[5] = msa_adds_s_df(DF_BYTE, pws->b[5], pwt->b[5]);
pwd->b[6] = msa_adds_s_df(DF_BYTE, pws->b[6], pwt->b[6]);
pwd->b[7] = msa_adds_s_df(DF_BYTE, pws->b[7], pwt->b[7]);
pwd->b[8] = msa_adds_s_df(DF_BYTE, pws->b[8], pwt->b[8]);
pwd->b[9] = msa_adds_s_df(DF_BYTE, pws->b[9], pwt->b[9]);
pwd->b[10] = msa_adds_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
pwd->b[11] = msa_adds_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
pwd->b[12] = msa_adds_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
pwd->b[13] = msa_adds_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
pwd->b[14] = msa_adds_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
pwd->b[15] = msa_adds_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
}
void helper_msa_adds_s_h(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_adds_s_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_adds_s_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_adds_s_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_adds_s_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_adds_s_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_adds_s_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_adds_s_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_adds_s_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_adds_s_w(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_adds_s_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_adds_s_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_adds_s_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_adds_s_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_adds_s_d(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_adds_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_adds_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
static inline uint64_t msa_adds_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
{
uint64_t max_uint = DF_MAX_UINT(df);
uint64_t u_arg1 = UNSIGNED(arg1, df);
uint64_t u_arg2 = UNSIGNED(arg2, df);
return (u_arg1 < max_uint - u_arg2) ? u_arg1 + u_arg2 : max_uint;
}
void helper_msa_adds_u_b(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_adds_u_df(DF_BYTE, pws->b[0], pwt->b[0]);
pwd->b[1] = msa_adds_u_df(DF_BYTE, pws->b[1], pwt->b[1]);
pwd->b[2] = msa_adds_u_df(DF_BYTE, pws->b[2], pwt->b[2]);
pwd->b[3] = msa_adds_u_df(DF_BYTE, pws->b[3], pwt->b[3]);
pwd->b[4] = msa_adds_u_df(DF_BYTE, pws->b[4], pwt->b[4]);
pwd->b[5] = msa_adds_u_df(DF_BYTE, pws->b[5], pwt->b[5]);
pwd->b[6] = msa_adds_u_df(DF_BYTE, pws->b[6], pwt->b[6]);
pwd->b[7] = msa_adds_u_df(DF_BYTE, pws->b[7], pwt->b[7]);
pwd->b[8] = msa_adds_u_df(DF_BYTE, pws->b[8], pwt->b[8]);
pwd->b[9] = msa_adds_u_df(DF_BYTE, pws->b[9], pwt->b[9]);
pwd->b[10] = msa_adds_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
pwd->b[11] = msa_adds_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
pwd->b[12] = msa_adds_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
pwd->b[13] = msa_adds_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
pwd->b[14] = msa_adds_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
pwd->b[15] = msa_adds_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
}
void helper_msa_adds_u_h(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_adds_u_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_adds_u_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_adds_u_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_adds_u_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_adds_u_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_adds_u_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_adds_u_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_adds_u_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_adds_u_w(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_adds_u_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_adds_u_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_adds_u_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_adds_u_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_adds_u_d(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_adds_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_adds_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
static inline int64_t msa_addv_df(uint32_t df, int64_t arg1, int64_t arg2)
{
return arg1 + arg2;
}
void helper_msa_addv_b(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_addv_df(DF_BYTE, pws->b[0], pwt->b[0]);
pwd->b[1] = msa_addv_df(DF_BYTE, pws->b[1], pwt->b[1]);
pwd->b[2] = msa_addv_df(DF_BYTE, pws->b[2], pwt->b[2]);
pwd->b[3] = msa_addv_df(DF_BYTE, pws->b[3], pwt->b[3]);
pwd->b[4] = msa_addv_df(DF_BYTE, pws->b[4], pwt->b[4]);
pwd->b[5] = msa_addv_df(DF_BYTE, pws->b[5], pwt->b[5]);
pwd->b[6] = msa_addv_df(DF_BYTE, pws->b[6], pwt->b[6]);
pwd->b[7] = msa_addv_df(DF_BYTE, pws->b[7], pwt->b[7]);
pwd->b[8] = msa_addv_df(DF_BYTE, pws->b[8], pwt->b[8]);
pwd->b[9] = msa_addv_df(DF_BYTE, pws->b[9], pwt->b[9]);
pwd->b[10] = msa_addv_df(DF_BYTE, pws->b[10], pwt->b[10]);
pwd->b[11] = msa_addv_df(DF_BYTE, pws->b[11], pwt->b[11]);
pwd->b[12] = msa_addv_df(DF_BYTE, pws->b[12], pwt->b[12]);
pwd->b[13] = msa_addv_df(DF_BYTE, pws->b[13], pwt->b[13]);
pwd->b[14] = msa_addv_df(DF_BYTE, pws->b[14], pwt->b[14]);
pwd->b[15] = msa_addv_df(DF_BYTE, pws->b[15], pwt->b[15]);
}
void helper_msa_addv_h(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_addv_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_addv_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_addv_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_addv_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_addv_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_addv_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_addv_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_addv_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_addv_w(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_addv_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_addv_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_addv_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_addv_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_addv_d(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_addv_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_addv_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
#define SIGNED_EVEN(a, df) \
((((int64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2))
#define UNSIGNED_EVEN(a, df) \
((((uint64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2))
#define SIGNED_ODD(a, df) \
((((int64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2))
#define UNSIGNED_ODD(a, df) \
((((uint64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2))
static inline int64_t msa_hadd_s_df(uint32_t df, int64_t arg1, int64_t arg2)
{
return SIGNED_ODD(arg1, df) + SIGNED_EVEN(arg2, df);
}
void helper_msa_hadd_s_h(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_hadd_s_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_hadd_s_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_hadd_s_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_hadd_s_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_hadd_s_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_hadd_s_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_hadd_s_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_hadd_s_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_hadd_s_w(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_hadd_s_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_hadd_s_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_hadd_s_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_hadd_s_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_hadd_s_d(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_hadd_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_hadd_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
static inline int64_t msa_hadd_u_df(uint32_t df, int64_t arg1, int64_t arg2)
{
return UNSIGNED_ODD(arg1, df) + UNSIGNED_EVEN(arg2, df);
}
void helper_msa_hadd_u_h(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_hadd_u_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_hadd_u_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_hadd_u_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_hadd_u_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_hadd_u_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_hadd_u_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_hadd_u_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_hadd_u_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_hadd_u_w(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_hadd_u_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_hadd_u_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_hadd_u_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_hadd_u_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_hadd_u_d(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_hadd_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_hadd_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
/*
* Int Average
* -----------
*
* +---------------+----------------------------------------------------------+
* | AVE_S.B | Vector Signed Average (byte) |
* | AVE_S.H | Vector Signed Average (halfword) |
* | AVE_S.W | Vector Signed Average (word) |
* | AVE_S.D | Vector Signed Average (doubleword) |
* | AVE_U.B | Vector Unsigned Average (byte) |
* | AVE_U.H | Vector Unsigned Average (halfword) |
* | AVE_U.W | Vector Unsigned Average (word) |
* | AVE_U.D | Vector Unsigned Average (doubleword) |
* | AVER_S.B | Vector Signed Average Rounded (byte) |
* | AVER_S.H | Vector Signed Average Rounded (halfword) |
* | AVER_S.W | Vector Signed Average Rounded (word) |
* | AVER_S.D | Vector Signed Average Rounded (doubleword) |
* | AVER_U.B | Vector Unsigned Average Rounded (byte) |
* | AVER_U.H | Vector Unsigned Average Rounded (halfword) |
* | AVER_U.W | Vector Unsigned Average Rounded (word) |
* | AVER_U.D | Vector Unsigned Average Rounded (doubleword) |
* +---------------+----------------------------------------------------------+
*/
static inline int64_t msa_ave_s_df(uint32_t df, int64_t arg1, int64_t arg2)
{
/* signed shift */
return (arg1 >> 1) + (arg2 >> 1) + (arg1 & arg2 & 1);
}
void helper_msa_ave_s_b(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_ave_s_df(DF_BYTE, pws->b[0], pwt->b[0]);
pwd->b[1] = msa_ave_s_df(DF_BYTE, pws->b[1], pwt->b[1]);
pwd->b[2] = msa_ave_s_df(DF_BYTE, pws->b[2], pwt->b[2]);
pwd->b[3] = msa_ave_s_df(DF_BYTE, pws->b[3], pwt->b[3]);
pwd->b[4] = msa_ave_s_df(DF_BYTE, pws->b[4], pwt->b[4]);
pwd->b[5] = msa_ave_s_df(DF_BYTE, pws->b[5], pwt->b[5]);
pwd->b[6] = msa_ave_s_df(DF_BYTE, pws->b[6], pwt->b[6]);
pwd->b[7] = msa_ave_s_df(DF_BYTE, pws->b[7], pwt->b[7]);
pwd->b[8] = msa_ave_s_df(DF_BYTE, pws->b[8], pwt->b[8]);
pwd->b[9] = msa_ave_s_df(DF_BYTE, pws->b[9], pwt->b[9]);
pwd->b[10] = msa_ave_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
pwd->b[11] = msa_ave_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
pwd->b[12] = msa_ave_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
pwd->b[13] = msa_ave_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
pwd->b[14] = msa_ave_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
pwd->b[15] = msa_ave_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
}
void helper_msa_ave_s_h(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_ave_s_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_ave_s_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_ave_s_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_ave_s_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_ave_s_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_ave_s_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_ave_s_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_ave_s_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_ave_s_w(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_ave_s_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_ave_s_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_ave_s_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_ave_s_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_ave_s_d(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_ave_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_ave_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
static inline uint64_t msa_ave_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
{
uint64_t u_arg1 = UNSIGNED(arg1, df);
uint64_t u_arg2 = UNSIGNED(arg2, df);
/* unsigned shift */
return (u_arg1 >> 1) + (u_arg2 >> 1) + (u_arg1 & u_arg2 & 1);
}
void helper_msa_ave_u_b(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_ave_u_df(DF_BYTE, pws->b[0], pwt->b[0]);
pwd->b[1] = msa_ave_u_df(DF_BYTE, pws->b[1], pwt->b[1]);
pwd->b[2] = msa_ave_u_df(DF_BYTE, pws->b[2], pwt->b[2]);
pwd->b[3] = msa_ave_u_df(DF_BYTE, pws->b[3], pwt->b[3]);
pwd->b[4] = msa_ave_u_df(DF_BYTE, pws->b[4], pwt->b[4]);
pwd->b[5] = msa_ave_u_df(DF_BYTE, pws->b[5], pwt->b[5]);
pwd->b[6] = msa_ave_u_df(DF_BYTE, pws->b[6], pwt->b[6]);
pwd->b[7] = msa_ave_u_df(DF_BYTE, pws->b[7], pwt->b[7]);
pwd->b[8] = msa_ave_u_df(DF_BYTE, pws->b[8], pwt->b[8]);
pwd->b[9] = msa_ave_u_df(DF_BYTE, pws->b[9], pwt->b[9]);
pwd->b[10] = msa_ave_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
pwd->b[11] = msa_ave_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
pwd->b[12] = msa_ave_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
pwd->b[13] = msa_ave_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
pwd->b[14] = msa_ave_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
pwd->b[15] = msa_ave_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
}
void helper_msa_ave_u_h(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_ave_u_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_ave_u_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_ave_u_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_ave_u_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_ave_u_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_ave_u_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_ave_u_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_ave_u_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_ave_u_w(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_ave_u_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_ave_u_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_ave_u_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_ave_u_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_ave_u_d(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_ave_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_ave_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
static inline int64_t msa_aver_s_df(uint32_t df, int64_t arg1, int64_t arg2)
{
/* signed shift */
return (arg1 >> 1) + (arg2 >> 1) + ((arg1 | arg2) & 1);
}
void helper_msa_aver_s_b(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_aver_s_df(DF_BYTE, pws->b[0], pwt->b[0]);
pwd->b[1] = msa_aver_s_df(DF_BYTE, pws->b[1], pwt->b[1]);
pwd->b[2] = msa_aver_s_df(DF_BYTE, pws->b[2], pwt->b[2]);
pwd->b[3] = msa_aver_s_df(DF_BYTE, pws->b[3], pwt->b[3]);
pwd->b[4] = msa_aver_s_df(DF_BYTE, pws->b[4], pwt->b[4]);
pwd->b[5] = msa_aver_s_df(DF_BYTE, pws->b[5], pwt->b[5]);
pwd->b[6] = msa_aver_s_df(DF_BYTE, pws->b[6], pwt->b[6]);
pwd->b[7] = msa_aver_s_df(DF_BYTE, pws->b[7], pwt->b[7]);
pwd->b[8] = msa_aver_s_df(DF_BYTE, pws->b[8], pwt->b[8]);
pwd->b[9] = msa_aver_s_df(DF_BYTE, pws->b[9], pwt->b[9]);
pwd->b[10] = msa_aver_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
pwd->b[11] = msa_aver_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
pwd->b[12] = msa_aver_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
pwd->b[13] = msa_aver_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
pwd->b[14] = msa_aver_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
pwd->b[15] = msa_aver_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
}
void helper_msa_aver_s_h(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_aver_s_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_aver_s_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_aver_s_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_aver_s_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_aver_s_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_aver_s_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_aver_s_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_aver_s_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_aver_s_w(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_aver_s_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_aver_s_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_aver_s_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_aver_s_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_aver_s_d(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_aver_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_aver_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
static inline uint64_t msa_aver_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
{
uint64_t u_arg1 = UNSIGNED(arg1, df);
uint64_t u_arg2 = UNSIGNED(arg2, df);
/* unsigned shift */
return (u_arg1 >> 1) + (u_arg2 >> 1) + ((u_arg1 | u_arg2) & 1);
}
void helper_msa_aver_u_b(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_aver_u_df(DF_BYTE, pws->b[0], pwt->b[0]);
pwd->b[1] = msa_aver_u_df(DF_BYTE, pws->b[1], pwt->b[1]);
pwd->b[2] = msa_aver_u_df(DF_BYTE, pws->b[2], pwt->b[2]);
pwd->b[3] = msa_aver_u_df(DF_BYTE, pws->b[3], pwt->b[3]);
pwd->b[4] = msa_aver_u_df(DF_BYTE, pws->b[4], pwt->b[4]);
pwd->b[5] = msa_aver_u_df(DF_BYTE, pws->b[5], pwt->b[5]);
pwd->b[6] = msa_aver_u_df(DF_BYTE, pws->b[6], pwt->b[6]);
pwd->b[7] = msa_aver_u_df(DF_BYTE, pws->b[7], pwt->b[7]);
pwd->b[8] = msa_aver_u_df(DF_BYTE, pws->b[8], pwt->b[8]);
pwd->b[9] = msa_aver_u_df(DF_BYTE, pws->b[9], pwt->b[9]);
pwd->b[10] = msa_aver_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
pwd->b[11] = msa_aver_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
pwd->b[12] = msa_aver_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
pwd->b[13] = msa_aver_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
pwd->b[14] = msa_aver_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
pwd->b[15] = msa_aver_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
}
void helper_msa_aver_u_h(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_aver_u_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_aver_u_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_aver_u_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_aver_u_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_aver_u_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_aver_u_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_aver_u_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_aver_u_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_aver_u_w(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_aver_u_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_aver_u_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_aver_u_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_aver_u_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_aver_u_d(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_aver_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_aver_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
/*
* Int Compare
* -----------
*
* +---------------+----------------------------------------------------------+
* | CEQ.B | Vector Compare Equal (byte) |
* | CEQ.H | Vector Compare Equal (halfword) |
* | CEQ.W | Vector Compare Equal (word) |
* | CEQ.D | Vector Compare Equal (doubleword) |
* | CLE_S.B | Vector Compare Signed Less Than or Equal (byte) |
* | CLE_S.H | Vector Compare Signed Less Than or Equal (halfword) |
* | CLE_S.W | Vector Compare Signed Less Than or Equal (word) |
* | CLE_S.D | Vector Compare Signed Less Than or Equal (doubleword) |
* | CLE_U.B | Vector Compare Unsigned Less Than or Equal (byte) |
* | CLE_U.H | Vector Compare Unsigned Less Than or Equal (halfword) |
* | CLE_U.W | Vector Compare Unsigned Less Than or Equal (word) |
* | CLE_U.D | Vector Compare Unsigned Less Than or Equal (doubleword) |
* | CLT_S.B | Vector Compare Signed Less Than (byte) |
* | CLT_S.H | Vector Compare Signed Less Than (halfword) |
* | CLT_S.W | Vector Compare Signed Less Than (word) |
* | CLT_S.D | Vector Compare Signed Less Than (doubleword) |
* | CLT_U.B | Vector Compare Unsigned Less Than (byte) |
* | CLT_U.H | Vector Compare Unsigned Less Than (halfword) |
* | CLT_U.W | Vector Compare Unsigned Less Than (word) |
* | CLT_U.D | Vector Compare Unsigned Less Than (doubleword) |
* +---------------+----------------------------------------------------------+
*/
static inline int64_t msa_ceq_df(uint32_t df, int64_t arg1, int64_t arg2)
{
return arg1 == arg2 ? -1 : 0;
}
static inline int8_t msa_ceq_b(int8_t arg1, int8_t arg2)
{
return arg1 == arg2 ? -1 : 0;
}
void helper_msa_ceq_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_ceq_b(pws->b[0], pwt->b[0]);
pwd->b[1] = msa_ceq_b(pws->b[1], pwt->b[1]);
pwd->b[2] = msa_ceq_b(pws->b[2], pwt->b[2]);
pwd->b[3] = msa_ceq_b(pws->b[3], pwt->b[3]);
pwd->b[4] = msa_ceq_b(pws->b[4], pwt->b[4]);
pwd->b[5] = msa_ceq_b(pws->b[5], pwt->b[5]);
pwd->b[6] = msa_ceq_b(pws->b[6], pwt->b[6]);
pwd->b[7] = msa_ceq_b(pws->b[7], pwt->b[7]);
pwd->b[8] = msa_ceq_b(pws->b[8], pwt->b[8]);
pwd->b[9] = msa_ceq_b(pws->b[9], pwt->b[9]);
pwd->b[10] = msa_ceq_b(pws->b[10], pwt->b[10]);
pwd->b[11] = msa_ceq_b(pws->b[11], pwt->b[11]);
pwd->b[12] = msa_ceq_b(pws->b[12], pwt->b[12]);
pwd->b[13] = msa_ceq_b(pws->b[13], pwt->b[13]);
pwd->b[14] = msa_ceq_b(pws->b[14], pwt->b[14]);
pwd->b[15] = msa_ceq_b(pws->b[15], pwt->b[15]);
}
static inline int16_t msa_ceq_h(int16_t arg1, int16_t arg2)
{
return arg1 == arg2 ? -1 : 0;
}
void helper_msa_ceq_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_ceq_h(pws->h[0], pwt->h[0]);
pwd->h[1] = msa_ceq_h(pws->h[1], pwt->h[1]);
pwd->h[2] = msa_ceq_h(pws->h[2], pwt->h[2]);
pwd->h[3] = msa_ceq_h(pws->h[3], pwt->h[3]);
pwd->h[4] = msa_ceq_h(pws->h[4], pwt->h[4]);
pwd->h[5] = msa_ceq_h(pws->h[5], pwt->h[5]);
pwd->h[6] = msa_ceq_h(pws->h[6], pwt->h[6]);
pwd->h[7] = msa_ceq_h(pws->h[7], pwt->h[7]);
}
static inline int32_t msa_ceq_w(int32_t arg1, int32_t arg2)
{
return arg1 == arg2 ? -1 : 0;
}
void helper_msa_ceq_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_ceq_w(pws->w[0], pwt->w[0]);
pwd->w[1] = msa_ceq_w(pws->w[1], pwt->w[1]);
pwd->w[2] = msa_ceq_w(pws->w[2], pwt->w[2]);
pwd->w[3] = msa_ceq_w(pws->w[3], pwt->w[3]);
}
static inline int64_t msa_ceq_d(int64_t arg1, int64_t arg2)
{
return arg1 == arg2 ? -1 : 0;
}
void helper_msa_ceq_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_ceq_d(pws->d[0], pwt->d[0]);
pwd->d[1] = msa_ceq_d(pws->d[1], pwt->d[1]);
}
static inline int64_t msa_cle_s_df(uint32_t df, int64_t arg1, int64_t arg2)
{
return arg1 <= arg2 ? -1 : 0;
}
void helper_msa_cle_s_b(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_cle_s_df(DF_BYTE, pws->b[0], pwt->b[0]);
pwd->b[1] = msa_cle_s_df(DF_BYTE, pws->b[1], pwt->b[1]);
pwd->b[2] = msa_cle_s_df(DF_BYTE, pws->b[2], pwt->b[2]);
pwd->b[3] = msa_cle_s_df(DF_BYTE, pws->b[3], pwt->b[3]);
pwd->b[4] = msa_cle_s_df(DF_BYTE, pws->b[4], pwt->b[4]);
pwd->b[5] = msa_cle_s_df(DF_BYTE, pws->b[5], pwt->b[5]);
pwd->b[6] = msa_cle_s_df(DF_BYTE, pws->b[6], pwt->b[6]);
pwd->b[7] = msa_cle_s_df(DF_BYTE, pws->b[7], pwt->b[7]);
pwd->b[8] = msa_cle_s_df(DF_BYTE, pws->b[8], pwt->b[8]);
pwd->b[9] = msa_cle_s_df(DF_BYTE, pws->b[9], pwt->b[9]);
pwd->b[10] = msa_cle_s_df(DF_BYTE, pws->b[10], pwt->b[10]);
pwd->b[11] = msa_cle_s_df(DF_BYTE, pws->b[11], pwt->b[11]);
pwd->b[12] = msa_cle_s_df(DF_BYTE, pws->b[12], pwt->b[12]);
pwd->b[13] = msa_cle_s_df(DF_BYTE, pws->b[13], pwt->b[13]);
pwd->b[14] = msa_cle_s_df(DF_BYTE, pws->b[14], pwt->b[14]);
pwd->b[15] = msa_cle_s_df(DF_BYTE, pws->b[15], pwt->b[15]);
}
void helper_msa_cle_s_h(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_cle_s_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_cle_s_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_cle_s_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_cle_s_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_cle_s_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_cle_s_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_cle_s_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_cle_s_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_cle_s_w(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_cle_s_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_cle_s_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_cle_s_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_cle_s_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_cle_s_d(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_cle_s_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_cle_s_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
static inline int64_t msa_cle_u_df(uint32_t df, int64_t arg1, int64_t arg2)
{
uint64_t u_arg1 = UNSIGNED(arg1, df);
uint64_t u_arg2 = UNSIGNED(arg2, df);
return u_arg1 <= u_arg2 ? -1 : 0;
}
void helper_msa_cle_u_b(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_cle_u_df(DF_BYTE, pws->b[0], pwt->b[0]);
pwd->b[1] = msa_cle_u_df(DF_BYTE, pws->b[1], pwt->b[1]);
pwd->b[2] = msa_cle_u_df(DF_BYTE, pws->b[2], pwt->b[2]);
pwd->b[3] = msa_cle_u_df(DF_BYTE, pws->b[3], pwt->b[3]);
pwd->b[4] = msa_cle_u_df(DF_BYTE, pws->b[4], pwt->b[4]);
pwd->b[5] = msa_cle_u_df(DF_BYTE, pws->b[5], pwt->b[5]);
pwd->b[6] = msa_cle_u_df(DF_BYTE, pws->b[6], pwt->b[6]);
pwd->b[7] = msa_cle_u_df(DF_BYTE, pws->b[7], pwt->b[7]);
pwd->b[8] = msa_cle_u_df(DF_BYTE, pws->b[8], pwt->b[8]);
pwd->b[9] = msa_cle_u_df(DF_BYTE, pws->b[9], pwt->b[9]);
pwd->b[10] = msa_cle_u_df(DF_BYTE, pws->b[10], pwt->b[10]);
pwd->b[11] = msa_cle_u_df(DF_BYTE, pws->b[11], pwt->b[11]);
pwd->b[12] = msa_cle_u_df(DF_BYTE, pws->b[12], pwt->b[12]);
pwd->b[13] = msa_cle_u_df(DF_BYTE, pws->b[13], pwt->b[13]);
pwd->b[14] = msa_cle_u_df(DF_BYTE, pws->b[14], pwt->b[14]);
pwd->b[15] = msa_cle_u_df(DF_BYTE, pws->b[15], pwt->b[15]);
}
void helper_msa_cle_u_h(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->h[0] = msa_cle_u_df(DF_HALF, pws->h[0], pwt->h[0]);
pwd->h[1] = msa_cle_u_df(DF_HALF, pws->h[1], pwt->h[1]);
pwd->h[2] = msa_cle_u_df(DF_HALF, pws->h[2], pwt->h[2]);
pwd->h[3] = msa_cle_u_df(DF_HALF, pws->h[3], pwt->h[3]);
pwd->h[4] = msa_cle_u_df(DF_HALF, pws->h[4], pwt->h[4]);
pwd->h[5] = msa_cle_u_df(DF_HALF, pws->h[5], pwt->h[5]);
pwd->h[6] = msa_cle_u_df(DF_HALF, pws->h[6], pwt->h[6]);
pwd->h[7] = msa_cle_u_df(DF_HALF, pws->h[7], pwt->h[7]);
}
void helper_msa_cle_u_w(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->w[0] = msa_cle_u_df(DF_WORD, pws->w[0], pwt->w[0]);
pwd->w[1] = msa_cle_u_df(DF_WORD, pws->w[1], pwt->w[1]);
pwd->w[2] = msa_cle_u_df(DF_WORD, pws->w[2], pwt->w[2]);
pwd->w[3] = msa_cle_u_df(DF_WORD, pws->w[3], pwt->w[3]);
}
void helper_msa_cle_u_d(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->d[0] = msa_cle_u_df(DF_DOUBLE, pws->d[0], pwt->d[0]);
pwd->d[1] = msa_cle_u_df(DF_DOUBLE, pws->d[1], pwt->d[1]);
}
static inline int64_t msa_clt_s_df(uint32_t df, int64_t arg1, int64_t arg2)
{
return arg1 < arg2 ? -1 : 0;
}
static inline int8_t msa_clt_s_b(int8_t arg1, int8_t arg2)
{
return arg1 < arg2 ? -1 : 0;
}
void helper_msa_clt_s_b(CPUMIPSState *env,
uint32_t wd, uint32_t ws, uint32_t wt)
{
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
pwd->b[0] = msa_clt_s_b(pws->b[0], pwt->b[0]);
pwd->b[1] = msa_clt_s_b(pws->b[1], pwt->b[1]);
pwd->b[2] = msa_clt_s_b(pws->b[2], pwt->b[2]);
pwd->b[3] = msa_clt_s_b(pws->b[3], pwt->b[3]);
pwd->b[4] = msa_clt_s_b(pws->b[4], pwt->b[4]);
pwd->b[5] = msa_clt_s_b(pws->b[5], pwt->b[5]);
pwd->b[6]