cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

iwmmxt_helper.c (27710B)


      1/*
      2 * iwMMXt micro operations for XScale.
      3 *
      4 * Copyright (c) 2007 OpenedHand, Ltd.
      5 * Written by Andrzej Zaborowski <andrew@openedhand.com>
      6 * Copyright (c) 2008 CodeSourcery
      7 *
      8 * This library is free software; you can redistribute it and/or
      9 * modify it under the terms of the GNU Lesser General Public
     10 * License as published by the Free Software Foundation; either
     11 * version 2.1 of the License, or (at your option) any later version.
     12 *
     13 * This library is distributed in the hope that it will be useful,
     14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     16 * Lesser General Public License for more details.
     17 *
     18 * You should have received a copy of the GNU Lesser General Public
     19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     20 */
     21
     22#include "qemu/osdep.h"
     23
     24#include "cpu.h"
     25#include "exec/helper-proto.h"
     26
     27/* iwMMXt macros extracted from GNU gdb.  */
     28
     29/* Set the SIMD wCASF flags for 8, 16, 32 or 64-bit operations.  */
     30#define SIMD8_SET(v, n, b)      ((v != 0) << ((((b) + 1) * 4) + (n)))
     31#define SIMD16_SET(v, n, h)     ((v != 0) << ((((h) + 1) * 8) + (n)))
     32#define SIMD32_SET(v, n, w)     ((v != 0) << ((((w) + 1) * 16) + (n)))
     33#define SIMD64_SET(v, n)        ((v != 0) << (32 + (n)))
     34/* Flags to pass as "n" above.  */
     35#define SIMD_NBIT       -1
     36#define SIMD_ZBIT       -2
     37#define SIMD_CBIT       -3
     38#define SIMD_VBIT       -4
     39/* Various status bit macros.  */
     40#define NBIT8(x)        ((x) & 0x80)
     41#define NBIT16(x)       ((x) & 0x8000)
     42#define NBIT32(x)       ((x) & 0x80000000)
     43#define NBIT64(x)       ((x) & 0x8000000000000000ULL)
     44#define ZBIT8(x)        (((x) & 0xff) == 0)
     45#define ZBIT16(x)       (((x) & 0xffff) == 0)
     46#define ZBIT32(x)       (((x) & 0xffffffff) == 0)
     47#define ZBIT64(x)       (x == 0)
     48/* Sign extension macros.  */
     49#define EXTEND8H(a)     ((uint16_t) (int8_t) (a))
     50#define EXTEND8(a)      ((uint32_t) (int8_t) (a))
     51#define EXTEND16(a)     ((uint32_t) (int16_t) (a))
     52#define EXTEND16S(a)    ((int32_t) (int16_t) (a))
     53#define EXTEND32(a)     ((uint64_t) (int32_t) (a))
     54
     55uint64_t HELPER(iwmmxt_maddsq)(uint64_t a, uint64_t b)
     56{
     57    a = ((
     58            EXTEND16S((a >> 0) & 0xffff) * EXTEND16S((b >> 0) & 0xffff) +
     59            EXTEND16S((a >> 16) & 0xffff) * EXTEND16S((b >> 16) & 0xffff)
     60        ) & 0xffffffff) | ((uint64_t) (
     61            EXTEND16S((a >> 32) & 0xffff) * EXTEND16S((b >> 32) & 0xffff) +
     62            EXTEND16S((a >> 48) & 0xffff) * EXTEND16S((b >> 48) & 0xffff)
     63        ) << 32);
     64    return a;
     65}
     66
     67uint64_t HELPER(iwmmxt_madduq)(uint64_t a, uint64_t b)
     68{
     69    a = ((
     70            ((a >> 0) & 0xffff) * ((b >> 0) & 0xffff) +
     71            ((a >> 16) & 0xffff) * ((b >> 16) & 0xffff)
     72        ) & 0xffffffff) | ((
     73            ((a >> 32) & 0xffff) * ((b >> 32) & 0xffff) +
     74            ((a >> 48) & 0xffff) * ((b >> 48) & 0xffff)
     75        ) << 32);
     76    return a;
     77}
     78
     79uint64_t HELPER(iwmmxt_sadb)(uint64_t a, uint64_t b)
     80{
     81#define abs(x) (((x) >= 0) ? x : -x)
     82#define SADB(SHR) abs((int) ((a >> SHR) & 0xff) - (int) ((b >> SHR) & 0xff))
     83    return
     84        SADB(0) + SADB(8) + SADB(16) + SADB(24) +
     85        SADB(32) + SADB(40) + SADB(48) + SADB(56);
     86#undef SADB
     87}
     88
     89uint64_t HELPER(iwmmxt_sadw)(uint64_t a, uint64_t b)
     90{
     91#define SADW(SHR) \
     92    abs((int) ((a >> SHR) & 0xffff) - (int) ((b >> SHR) & 0xffff))
     93    return SADW(0) + SADW(16) + SADW(32) + SADW(48);
     94#undef SADW
     95}
     96
     97uint64_t HELPER(iwmmxt_mulslw)(uint64_t a, uint64_t b)
     98{
     99#define MULS(SHR) ((uint64_t) ((( \
    100        EXTEND16S((a >> SHR) & 0xffff) * EXTEND16S((b >> SHR) & 0xffff) \
    101    ) >> 0) & 0xffff) << SHR)
    102    return MULS(0) | MULS(16) | MULS(32) | MULS(48);
    103#undef MULS
    104}
    105
    106uint64_t HELPER(iwmmxt_mulshw)(uint64_t a, uint64_t b)
    107{
    108#define MULS(SHR) ((uint64_t) ((( \
    109        EXTEND16S((a >> SHR) & 0xffff) * EXTEND16S((b >> SHR) & 0xffff) \
    110    ) >> 16) & 0xffff) << SHR)
    111    return MULS(0) | MULS(16) | MULS(32) | MULS(48);
    112#undef MULS
    113}
    114
    115uint64_t HELPER(iwmmxt_mululw)(uint64_t a, uint64_t b)
    116{
    117#define MULU(SHR) ((uint64_t) ((( \
    118        ((a >> SHR) & 0xffff) * ((b >> SHR) & 0xffff) \
    119    ) >> 0) & 0xffff) << SHR)
    120    return MULU(0) | MULU(16) | MULU(32) | MULU(48);
    121#undef MULU
    122}
    123
    124uint64_t HELPER(iwmmxt_muluhw)(uint64_t a, uint64_t b)
    125{
    126#define MULU(SHR) ((uint64_t) ((( \
    127        ((a >> SHR) & 0xffff) * ((b >> SHR) & 0xffff) \
    128    ) >> 16) & 0xffff) << SHR)
    129    return MULU(0) | MULU(16) | MULU(32) | MULU(48);
    130#undef MULU
    131}
    132
    133uint64_t HELPER(iwmmxt_macsw)(uint64_t a, uint64_t b)
    134{
    135#define MACS(SHR) ( \
    136        EXTEND16((a >> SHR) & 0xffff) * EXTEND16S((b >> SHR) & 0xffff))
    137    return (int64_t) (MACS(0) + MACS(16) + MACS(32) + MACS(48));
    138#undef MACS
    139}
    140
    141uint64_t HELPER(iwmmxt_macuw)(uint64_t a, uint64_t b)
    142{
    143#define MACU(SHR) ( \
    144        (uint32_t) ((a >> SHR) & 0xffff) * \
    145        (uint32_t) ((b >> SHR) & 0xffff))
    146    return MACU(0) + MACU(16) + MACU(32) + MACU(48);
    147#undef MACU
    148}
    149
    150#define NZBIT8(x, i) \
    151    SIMD8_SET(NBIT8((x) & 0xff), SIMD_NBIT, i) | \
    152    SIMD8_SET(ZBIT8((x) & 0xff), SIMD_ZBIT, i)
    153#define NZBIT16(x, i) \
    154    SIMD16_SET(NBIT16((x) & 0xffff), SIMD_NBIT, i) | \
    155    SIMD16_SET(ZBIT16((x) & 0xffff), SIMD_ZBIT, i)
    156#define NZBIT32(x, i) \
    157    SIMD32_SET(NBIT32((x) & 0xffffffff), SIMD_NBIT, i) | \
    158    SIMD32_SET(ZBIT32((x) & 0xffffffff), SIMD_ZBIT, i)
    159#define NZBIT64(x) \
    160    SIMD64_SET(NBIT64(x), SIMD_NBIT) | \
    161    SIMD64_SET(ZBIT64(x), SIMD_ZBIT)
    162#define IWMMXT_OP_UNPACK(S, SH0, SH1, SH2, SH3)                         \
    163uint64_t HELPER(glue(iwmmxt_unpack, glue(S, b)))(CPUARMState *env, \
    164                                                 uint64_t a, uint64_t b) \
    165{                                                               \
    166    a =                                                                 \
    167        (((a >> SH0) & 0xff) << 0) | (((b >> SH0) & 0xff) << 8) |       \
    168        (((a >> SH1) & 0xff) << 16) | (((b >> SH1) & 0xff) << 24) |     \
    169        (((a >> SH2) & 0xff) << 32) | (((b >> SH2) & 0xff) << 40) |     \
    170        (((a >> SH3) & 0xff) << 48) | (((b >> SH3) & 0xff) << 56);      \
    171    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =                       \
    172        NZBIT8(a >> 0, 0) | NZBIT8(a >> 8, 1) |                         \
    173        NZBIT8(a >> 16, 2) | NZBIT8(a >> 24, 3) |               \
    174        NZBIT8(a >> 32, 4) | NZBIT8(a >> 40, 5) |               \
    175        NZBIT8(a >> 48, 6) | NZBIT8(a >> 56, 7);                \
    176    return a;                                                   \
    177}                                                               \
    178uint64_t HELPER(glue(iwmmxt_unpack, glue(S, w)))(CPUARMState *env, \
    179                                        uint64_t a, uint64_t b) \
    180{                                                               \
    181    a =                                                                 \
    182        (((a >> SH0) & 0xffff) << 0) |                          \
    183        (((b >> SH0) & 0xffff) << 16) |                                 \
    184        (((a >> SH2) & 0xffff) << 32) |                                 \
    185        (((b >> SH2) & 0xffff) << 48);                          \
    186    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =                       \
    187        NZBIT8(a >> 0, 0) | NZBIT8(a >> 16, 1) |                \
    188        NZBIT8(a >> 32, 2) | NZBIT8(a >> 48, 3);                \
    189    return a;                                                   \
    190}                                                               \
    191uint64_t HELPER(glue(iwmmxt_unpack, glue(S, l)))(CPUARMState *env, \
    192                                        uint64_t a, uint64_t b) \
    193{                                                               \
    194    a =                                                                 \
    195        (((a >> SH0) & 0xffffffff) << 0) |                      \
    196        (((b >> SH0) & 0xffffffff) << 32);                      \
    197    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =                       \
    198        NZBIT32(a >> 0, 0) | NZBIT32(a >> 32, 1);               \
    199    return a;                                                   \
    200}                                                               \
    201uint64_t HELPER(glue(iwmmxt_unpack, glue(S, ub)))(CPUARMState *env, \
    202                                                  uint64_t x)   \
    203{                                                               \
    204    x =                                                                 \
    205        (((x >> SH0) & 0xff) << 0) |                            \
    206        (((x >> SH1) & 0xff) << 16) |                           \
    207        (((x >> SH2) & 0xff) << 32) |                           \
    208        (((x >> SH3) & 0xff) << 48);                            \
    209    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =                       \
    210        NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) |              \
    211        NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);              \
    212    return x;                                                   \
    213}                                                               \
    214uint64_t HELPER(glue(iwmmxt_unpack, glue(S, uw)))(CPUARMState *env, \
    215                                                  uint64_t x)   \
    216{                                                               \
    217    x =                                                                 \
    218        (((x >> SH0) & 0xffff) << 0) |                          \
    219        (((x >> SH2) & 0xffff) << 32);                          \
    220    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =                       \
    221        NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1);               \
    222    return x;                                                   \
    223}                                                               \
    224uint64_t HELPER(glue(iwmmxt_unpack, glue(S, ul)))(CPUARMState *env, \
    225                                                  uint64_t x)   \
    226{                                                               \
    227    x = (((x >> SH0) & 0xffffffff) << 0);                       \
    228    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x >> 0);      \
    229    return x;                                                   \
    230}                                                               \
    231uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sb)))(CPUARMState *env, \
    232                                                  uint64_t x)   \
    233{                                                               \
    234    x =                                                                 \
    235        ((uint64_t) EXTEND8H((x >> SH0) & 0xff) << 0) |                 \
    236        ((uint64_t) EXTEND8H((x >> SH1) & 0xff) << 16) |        \
    237        ((uint64_t) EXTEND8H((x >> SH2) & 0xff) << 32) |        \
    238        ((uint64_t) EXTEND8H((x >> SH3) & 0xff) << 48);                 \
    239    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =                       \
    240        NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) |              \
    241        NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);              \
    242    return x;                                                   \
    243}                                                               \
    244uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sw)))(CPUARMState *env, \
    245                                                  uint64_t x)   \
    246{                                                               \
    247    x =                                                                 \
    248        ((uint64_t) EXTEND16((x >> SH0) & 0xffff) << 0) |       \
    249        ((uint64_t) EXTEND16((x >> SH2) & 0xffff) << 32);       \
    250    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =                       \
    251        NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1);               \
    252    return x;                                                   \
    253}                                                               \
    254uint64_t HELPER(glue(iwmmxt_unpack, glue(S, sl)))(CPUARMState *env, \
    255                                                  uint64_t x)   \
    256{                                                               \
    257    x = EXTEND32((x >> SH0) & 0xffffffff);                      \
    258    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x >> 0);      \
    259    return x;                                                   \
    260}
    261IWMMXT_OP_UNPACK(l, 0, 8, 16, 24)
    262IWMMXT_OP_UNPACK(h, 32, 40, 48, 56)
    263
    264#define IWMMXT_OP_CMP(SUFF, Tb, Tw, Tl, O)                      \
    265uint64_t HELPER(glue(iwmmxt_, glue(SUFF, b)))(CPUARMState *env,    \
    266                                        uint64_t a, uint64_t b) \
    267{                                                               \
    268    a =                                                                 \
    269        CMP(0, Tb, O, 0xff) | CMP(8, Tb, O, 0xff) |             \
    270        CMP(16, Tb, O, 0xff) | CMP(24, Tb, O, 0xff) |           \
    271        CMP(32, Tb, O, 0xff) | CMP(40, Tb, O, 0xff) |           \
    272        CMP(48, Tb, O, 0xff) | CMP(56, Tb, O, 0xff);            \
    273    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =                       \
    274        NZBIT8(a >> 0, 0) | NZBIT8(a >> 8, 1) |                         \
    275        NZBIT8(a >> 16, 2) | NZBIT8(a >> 24, 3) |               \
    276        NZBIT8(a >> 32, 4) | NZBIT8(a >> 40, 5) |               \
    277        NZBIT8(a >> 48, 6) | NZBIT8(a >> 56, 7);                \
    278    return a;                                                   \
    279}                                                               \
    280uint64_t HELPER(glue(iwmmxt_, glue(SUFF, w)))(CPUARMState *env,    \
    281                                        uint64_t a, uint64_t b) \
    282{                                                               \
    283    a = CMP(0, Tw, O, 0xffff) | CMP(16, Tw, O, 0xffff) |        \
    284        CMP(32, Tw, O, 0xffff) | CMP(48, Tw, O, 0xffff);        \
    285    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =                       \
    286        NZBIT16(a >> 0, 0) | NZBIT16(a >> 16, 1) |              \
    287        NZBIT16(a >> 32, 2) | NZBIT16(a >> 48, 3);              \
    288    return a;                                                   \
    289}                                                               \
    290uint64_t HELPER(glue(iwmmxt_, glue(SUFF, l)))(CPUARMState *env,    \
    291                                        uint64_t a, uint64_t b) \
    292{                                                               \
    293    a = CMP(0, Tl, O, 0xffffffff) |                             \
    294        CMP(32, Tl, O, 0xffffffff);                             \
    295    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =                       \
    296        NZBIT32(a >> 0, 0) | NZBIT32(a >> 32, 1);               \
    297    return a;                                                   \
    298}
    299#define CMP(SHR, TYPE, OPER, MASK) ((((TYPE) ((a >> SHR) & MASK) OPER \
    300            (TYPE) ((b >> SHR) & MASK)) ? (uint64_t) MASK : 0) << SHR)
    301IWMMXT_OP_CMP(cmpeq, uint8_t, uint16_t, uint32_t, ==)
    302IWMMXT_OP_CMP(cmpgts, int8_t, int16_t, int32_t, >)
    303IWMMXT_OP_CMP(cmpgtu, uint8_t, uint16_t, uint32_t, >)
    304#undef CMP
    305#define CMP(SHR, TYPE, OPER, MASK) ((((TYPE) ((a >> SHR) & MASK) OPER \
    306            (TYPE) ((b >> SHR) & MASK)) ? a : b) & ((uint64_t) MASK << SHR))
    307IWMMXT_OP_CMP(mins, int8_t, int16_t, int32_t, <)
    308IWMMXT_OP_CMP(minu, uint8_t, uint16_t, uint32_t, <)
    309IWMMXT_OP_CMP(maxs, int8_t, int16_t, int32_t, >)
    310IWMMXT_OP_CMP(maxu, uint8_t, uint16_t, uint32_t, >)
    311#undef CMP
    312#define CMP(SHR, TYPE, OPER, MASK) ((uint64_t) (((TYPE) ((a >> SHR) & MASK) \
    313            OPER (TYPE) ((b >> SHR) & MASK)) & MASK) << SHR)
    314IWMMXT_OP_CMP(subn, uint8_t, uint16_t, uint32_t, -)
    315IWMMXT_OP_CMP(addn, uint8_t, uint16_t, uint32_t, +)
    316#undef CMP
    317/* TODO Signed- and Unsigned-Saturation */
    318#define CMP(SHR, TYPE, OPER, MASK) ((uint64_t) (((TYPE) ((a >> SHR) & MASK) \
    319            OPER (TYPE) ((b >> SHR) & MASK)) & MASK) << SHR)
    320IWMMXT_OP_CMP(subu, uint8_t, uint16_t, uint32_t, -)
    321IWMMXT_OP_CMP(addu, uint8_t, uint16_t, uint32_t, +)
    322IWMMXT_OP_CMP(subs, int8_t, int16_t, int32_t, -)
    323IWMMXT_OP_CMP(adds, int8_t, int16_t, int32_t, +)
    324#undef CMP
    325#undef IWMMXT_OP_CMP
    326
    327#define AVGB(SHR) ((( \
    328        ((a >> SHR) & 0xff) + ((b >> SHR) & 0xff) + round) >> 1) << SHR)
    329#define IWMMXT_OP_AVGB(r)                                                 \
    330uint64_t HELPER(iwmmxt_avgb##r)(CPUARMState *env, uint64_t a, uint64_t b)    \
    331{                                                                         \
    332    const int round = r;                                                  \
    333    a = AVGB(0) | AVGB(8) | AVGB(16) | AVGB(24) |                         \
    334        AVGB(32) | AVGB(40) | AVGB(48) | AVGB(56);                        \
    335    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =                                 \
    336        SIMD8_SET(ZBIT8((a >> 0) & 0xff), SIMD_ZBIT, 0) |                 \
    337        SIMD8_SET(ZBIT8((a >> 8) & 0xff), SIMD_ZBIT, 1) |                 \
    338        SIMD8_SET(ZBIT8((a >> 16) & 0xff), SIMD_ZBIT, 2) |                \
    339        SIMD8_SET(ZBIT8((a >> 24) & 0xff), SIMD_ZBIT, 3) |                \
    340        SIMD8_SET(ZBIT8((a >> 32) & 0xff), SIMD_ZBIT, 4) |                \
    341        SIMD8_SET(ZBIT8((a >> 40) & 0xff), SIMD_ZBIT, 5) |                \
    342        SIMD8_SET(ZBIT8((a >> 48) & 0xff), SIMD_ZBIT, 6) |                \
    343        SIMD8_SET(ZBIT8((a >> 56) & 0xff), SIMD_ZBIT, 7);                 \
    344    return a;                                                             \
    345}
    346IWMMXT_OP_AVGB(0)
    347IWMMXT_OP_AVGB(1)
    348#undef IWMMXT_OP_AVGB
    349#undef AVGB
    350
    351#define AVGW(SHR) ((( \
    352        ((a >> SHR) & 0xffff) + ((b >> SHR) & 0xffff) + round) >> 1) << SHR)
    353#define IWMMXT_OP_AVGW(r)                                               \
    354uint64_t HELPER(iwmmxt_avgw##r)(CPUARMState *env, uint64_t a, uint64_t b)  \
    355{                                                                       \
    356    const int round = r;                                                \
    357    a = AVGW(0) | AVGW(16) | AVGW(32) | AVGW(48);                       \
    358    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =                               \
    359        SIMD16_SET(ZBIT16((a >> 0) & 0xffff), SIMD_ZBIT, 0) |           \
    360        SIMD16_SET(ZBIT16((a >> 16) & 0xffff), SIMD_ZBIT, 1) |          \
    361        SIMD16_SET(ZBIT16((a >> 32) & 0xffff), SIMD_ZBIT, 2) |          \
    362        SIMD16_SET(ZBIT16((a >> 48) & 0xffff), SIMD_ZBIT, 3);           \
    363    return a;                                                           \
    364}
    365IWMMXT_OP_AVGW(0)
    366IWMMXT_OP_AVGW(1)
    367#undef IWMMXT_OP_AVGW
    368#undef AVGW
    369
    370uint64_t HELPER(iwmmxt_align)(uint64_t a, uint64_t b, uint32_t n)
    371{
    372    a >>= n << 3;
    373    a |= b << (64 - (n << 3));
    374    return a;
    375}
    376
    377uint64_t HELPER(iwmmxt_insr)(uint64_t x, uint32_t a, uint32_t b, uint32_t n)
    378{
    379    x &= ~((uint64_t) b << n);
    380    x |= (uint64_t) (a & b) << n;
    381    return x;
    382}
    383
    384uint32_t HELPER(iwmmxt_setpsr_nz)(uint64_t x)
    385{
    386    return SIMD64_SET((x == 0), SIMD_ZBIT) |
    387           SIMD64_SET((x & (1ULL << 63)), SIMD_NBIT);
    388}
    389
    390uint64_t HELPER(iwmmxt_bcstb)(uint32_t arg)
    391{
    392    arg &= 0xff;
    393    return
    394        ((uint64_t) arg << 0 ) | ((uint64_t) arg << 8 ) |
    395        ((uint64_t) arg << 16) | ((uint64_t) arg << 24) |
    396        ((uint64_t) arg << 32) | ((uint64_t) arg << 40) |
    397        ((uint64_t) arg << 48) | ((uint64_t) arg << 56);
    398}
    399
    400uint64_t HELPER(iwmmxt_bcstw)(uint32_t arg)
    401{
    402    arg &= 0xffff;
    403    return
    404        ((uint64_t) arg << 0 ) | ((uint64_t) arg << 16) |
    405        ((uint64_t) arg << 32) | ((uint64_t) arg << 48);
    406}
    407
    408uint64_t HELPER(iwmmxt_bcstl)(uint32_t arg)
    409{
    410    return arg | ((uint64_t) arg << 32);
    411}
    412
    413uint64_t HELPER(iwmmxt_addcb)(uint64_t x)
    414{
    415    return
    416        ((x >> 0) & 0xff) + ((x >> 8) & 0xff) +
    417        ((x >> 16) & 0xff) + ((x >> 24) & 0xff) +
    418        ((x >> 32) & 0xff) + ((x >> 40) & 0xff) +
    419        ((x >> 48) & 0xff) + ((x >> 56) & 0xff);
    420}
    421
    422uint64_t HELPER(iwmmxt_addcw)(uint64_t x)
    423{
    424    return
    425        ((x >> 0) & 0xffff) + ((x >> 16) & 0xffff) +
    426        ((x >> 32) & 0xffff) + ((x >> 48) & 0xffff);
    427}
    428
    429uint64_t HELPER(iwmmxt_addcl)(uint64_t x)
    430{
    431    return (x & 0xffffffff) + (x >> 32);
    432}
    433
    434uint32_t HELPER(iwmmxt_msbb)(uint64_t x)
    435{
    436    return
    437        ((x >> 7) & 0x01) | ((x >> 14) & 0x02) |
    438        ((x >> 21) & 0x04) | ((x >> 28) & 0x08) |
    439        ((x >> 35) & 0x10) | ((x >> 42) & 0x20) |
    440        ((x >> 49) & 0x40) | ((x >> 56) & 0x80);
    441}
    442
    443uint32_t HELPER(iwmmxt_msbw)(uint64_t x)
    444{
    445    return
    446        ((x >> 15) & 0x01) | ((x >> 30) & 0x02) |
    447        ((x >> 45) & 0x04) | ((x >> 52) & 0x08);
    448}
    449
    450uint32_t HELPER(iwmmxt_msbl)(uint64_t x)
    451{
    452    return ((x >> 31) & 0x01) | ((x >> 62) & 0x02);
    453}
    454
    455/* FIXME: Split wCASF setting into a separate op to avoid env use.  */
    456uint64_t HELPER(iwmmxt_srlw)(CPUARMState *env, uint64_t x, uint32_t n)
    457{
    458    x = (((x & (0xffffll << 0)) >> n) & (0xffffll << 0)) |
    459        (((x & (0xffffll << 16)) >> n) & (0xffffll << 16)) |
    460        (((x & (0xffffll << 32)) >> n) & (0xffffll << 32)) |
    461        (((x & (0xffffll << 48)) >> n) & (0xffffll << 48));
    462    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
    463        NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) |
    464        NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);
    465    return x;
    466}
    467
    468uint64_t HELPER(iwmmxt_srll)(CPUARMState *env, uint64_t x, uint32_t n)
    469{
    470    x = ((x & (0xffffffffll << 0)) >> n) |
    471        ((x >> n) & (0xffffffffll << 32));
    472    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
    473        NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1);
    474    return x;
    475}
    476
    477uint64_t HELPER(iwmmxt_srlq)(CPUARMState *env, uint64_t x, uint32_t n)
    478{
    479    x >>= n;
    480    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x);
    481    return x;
    482}
    483
    484uint64_t HELPER(iwmmxt_sllw)(CPUARMState *env, uint64_t x, uint32_t n)
    485{
    486    x = (((x & (0xffffll << 0)) << n) & (0xffffll << 0)) |
    487        (((x & (0xffffll << 16)) << n) & (0xffffll << 16)) |
    488        (((x & (0xffffll << 32)) << n) & (0xffffll << 32)) |
    489        (((x & (0xffffll << 48)) << n) & (0xffffll << 48));
    490    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
    491        NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) |
    492        NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);
    493    return x;
    494}
    495
    496uint64_t HELPER(iwmmxt_slll)(CPUARMState *env, uint64_t x, uint32_t n)
    497{
    498    x = ((x << n) & (0xffffffffll << 0)) |
    499        ((x & (0xffffffffll << 32)) << n);
    500    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
    501        NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1);
    502    return x;
    503}
    504
    505uint64_t HELPER(iwmmxt_sllq)(CPUARMState *env, uint64_t x, uint32_t n)
    506{
    507    x <<= n;
    508    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x);
    509    return x;
    510}
    511
    512uint64_t HELPER(iwmmxt_sraw)(CPUARMState *env, uint64_t x, uint32_t n)
    513{
    514    x = ((uint64_t) ((EXTEND16(x >> 0) >> n) & 0xffff) << 0) |
    515        ((uint64_t) ((EXTEND16(x >> 16) >> n) & 0xffff) << 16) |
    516        ((uint64_t) ((EXTEND16(x >> 32) >> n) & 0xffff) << 32) |
    517        ((uint64_t) ((EXTEND16(x >> 48) >> n) & 0xffff) << 48);
    518    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
    519        NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) |
    520        NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);
    521    return x;
    522}
    523
    524uint64_t HELPER(iwmmxt_sral)(CPUARMState *env, uint64_t x, uint32_t n)
    525{
    526    x = (((EXTEND32(x >> 0) >> n) & 0xffffffff) << 0) |
    527        (((EXTEND32(x >> 32) >> n) & 0xffffffff) << 32);
    528    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
    529        NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1);
    530    return x;
    531}
    532
    533uint64_t HELPER(iwmmxt_sraq)(CPUARMState *env, uint64_t x, uint32_t n)
    534{
    535    x = (int64_t) x >> n;
    536    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x);
    537    return x;
    538}
    539
    540uint64_t HELPER(iwmmxt_rorw)(CPUARMState *env, uint64_t x, uint32_t n)
    541{
    542    x = ((((x & (0xffffll << 0)) >> n) |
    543          ((x & (0xffffll << 0)) << (16 - n))) & (0xffffll << 0)) |
    544        ((((x & (0xffffll << 16)) >> n) |
    545          ((x & (0xffffll << 16)) << (16 - n))) & (0xffffll << 16)) |
    546        ((((x & (0xffffll << 32)) >> n) |
    547          ((x & (0xffffll << 32)) << (16 - n))) & (0xffffll << 32)) |
    548        ((((x & (0xffffll << 48)) >> n) |
    549          ((x & (0xffffll << 48)) << (16 - n))) & (0xffffll << 48));
    550    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
    551        NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) |
    552        NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);
    553    return x;
    554}
    555
    556uint64_t HELPER(iwmmxt_rorl)(CPUARMState *env, uint64_t x, uint32_t n)
    557{
    558    x = ((x & (0xffffffffll << 0)) >> n) |
    559        ((x >> n) & (0xffffffffll << 32)) |
    560        ((x << (32 - n)) & (0xffffffffll << 0)) |
    561        ((x & (0xffffffffll << 32)) << (32 - n));
    562    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
    563        NZBIT32(x >> 0, 0) | NZBIT32(x >> 32, 1);
    564    return x;
    565}
    566
    567uint64_t HELPER(iwmmxt_rorq)(CPUARMState *env, uint64_t x, uint32_t n)
    568{
    569    x = ror64(x, n);
    570    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] = NZBIT64(x);
    571    return x;
    572}
    573
    574uint64_t HELPER(iwmmxt_shufh)(CPUARMState *env, uint64_t x, uint32_t n)
    575{
    576    x = (((x >> ((n << 4) & 0x30)) & 0xffff) << 0) |
    577        (((x >> ((n << 2) & 0x30)) & 0xffff) << 16) |
    578        (((x >> ((n << 0) & 0x30)) & 0xffff) << 32) |
    579        (((x >> ((n >> 2) & 0x30)) & 0xffff) << 48);
    580    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
    581        NZBIT16(x >> 0, 0) | NZBIT16(x >> 16, 1) |
    582        NZBIT16(x >> 32, 2) | NZBIT16(x >> 48, 3);
    583    return x;
    584}
    585
    586/* TODO: Unsigned-Saturation */
    587uint64_t HELPER(iwmmxt_packuw)(CPUARMState *env, uint64_t a, uint64_t b)
    588{
    589    a = (((a >> 0) & 0xff) << 0) | (((a >> 16) & 0xff) << 8) |
    590        (((a >> 32) & 0xff) << 16) | (((a >> 48) & 0xff) << 24) |
    591        (((b >> 0) & 0xff) << 32) | (((b >> 16) & 0xff) << 40) |
    592        (((b >> 32) & 0xff) << 48) | (((b >> 48) & 0xff) << 56);
    593    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
    594        NZBIT8(a >> 0, 0) | NZBIT8(a >> 8, 1) |
    595        NZBIT8(a >> 16, 2) | NZBIT8(a >> 24, 3) |
    596        NZBIT8(a >> 32, 4) | NZBIT8(a >> 40, 5) |
    597        NZBIT8(a >> 48, 6) | NZBIT8(a >> 56, 7);
    598    return a;
    599}
    600
    601uint64_t HELPER(iwmmxt_packul)(CPUARMState *env, uint64_t a, uint64_t b)
    602{
    603    a = (((a >> 0) & 0xffff) << 0) | (((a >> 32) & 0xffff) << 16) |
    604        (((b >> 0) & 0xffff) << 32) | (((b >> 32) & 0xffff) << 48);
    605    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
    606        NZBIT16(a >> 0, 0) | NZBIT16(a >> 16, 1) |
    607        NZBIT16(a >> 32, 2) | NZBIT16(a >> 48, 3);
    608    return a;
    609}
    610
    611uint64_t HELPER(iwmmxt_packuq)(CPUARMState *env, uint64_t a, uint64_t b)
    612{
    613    a = (a & 0xffffffff) | ((b & 0xffffffff) << 32);
    614    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
    615        NZBIT32(a >> 0, 0) | NZBIT32(a >> 32, 1);
    616    return a;
    617}
    618
    619/* TODO: Signed-Saturation */
    620uint64_t HELPER(iwmmxt_packsw)(CPUARMState *env, uint64_t a, uint64_t b)
    621{
    622    a = (((a >> 0) & 0xff) << 0) | (((a >> 16) & 0xff) << 8) |
    623        (((a >> 32) & 0xff) << 16) | (((a >> 48) & 0xff) << 24) |
    624        (((b >> 0) & 0xff) << 32) | (((b >> 16) & 0xff) << 40) |
    625        (((b >> 32) & 0xff) << 48) | (((b >> 48) & 0xff) << 56);
    626    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
    627        NZBIT8(a >> 0, 0) | NZBIT8(a >> 8, 1) |
    628        NZBIT8(a >> 16, 2) | NZBIT8(a >> 24, 3) |
    629        NZBIT8(a >> 32, 4) | NZBIT8(a >> 40, 5) |
    630        NZBIT8(a >> 48, 6) | NZBIT8(a >> 56, 7);
    631    return a;
    632}
    633
    634uint64_t HELPER(iwmmxt_packsl)(CPUARMState *env, uint64_t a, uint64_t b)
    635{
    636    a = (((a >> 0) & 0xffff) << 0) | (((a >> 32) & 0xffff) << 16) |
    637        (((b >> 0) & 0xffff) << 32) | (((b >> 32) & 0xffff) << 48);
    638    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
    639        NZBIT16(a >> 0, 0) | NZBIT16(a >> 16, 1) |
    640        NZBIT16(a >> 32, 2) | NZBIT16(a >> 48, 3);
    641    return a;
    642}
    643
    644uint64_t HELPER(iwmmxt_packsq)(CPUARMState *env, uint64_t a, uint64_t b)
    645{
    646    a = (a & 0xffffffff) | ((b & 0xffffffff) << 32);
    647    env->iwmmxt.cregs[ARM_IWMMXT_wCASF] =
    648        NZBIT32(a >> 0, 0) | NZBIT32(a >> 32, 1);
    649    return a;
    650}
    651
    652uint64_t HELPER(iwmmxt_muladdsl)(uint64_t c, uint32_t a, uint32_t b)
    653{
    654    return c + ((int32_t) EXTEND32(a) * (int32_t) EXTEND32(b));
    655}
    656
    657uint64_t HELPER(iwmmxt_muladdsw)(uint64_t c, uint32_t a, uint32_t b)
    658{
    659    c += EXTEND32(EXTEND16S((a >> 0) & 0xffff) *
    660                  EXTEND16S((b >> 0) & 0xffff));
    661    c += EXTEND32(EXTEND16S((a >> 16) & 0xffff) *
    662                  EXTEND16S((b >> 16) & 0xffff));
    663    return c;
    664}
    665
    666uint64_t HELPER(iwmmxt_muladdswl)(uint64_t c, uint32_t a, uint32_t b)
    667{
    668    return c + (EXTEND32(EXTEND16S(a & 0xffff) *
    669                         EXTEND16S(b & 0xffff)));
    670}