| /* |
| * 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] |