qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

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 
     55 uint64_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 
     67 uint64_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 
     79 uint64_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 
     89 uint64_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 
     97 uint64_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 
    106 uint64_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 
    115 uint64_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 
    124 uint64_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 
    133 uint64_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 
    141 uint64_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)                         \
    163 uint64_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 }                                                               \
    178 uint64_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 }                                                               \
    191 uint64_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 }                                                               \
    201 uint64_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 }                                                               \
    214 uint64_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 }                                                               \
    224 uint64_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 }                                                               \
    231 uint64_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 }                                                               \
    244 uint64_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 }                                                               \
    254 uint64_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 }
    261 IWMMXT_OP_UNPACK(l, 0, 8, 16, 24)
    262 IWMMXT_OP_UNPACK(h, 32, 40, 48, 56)
    263 
    264 #define IWMMXT_OP_CMP(SUFF, Tb, Tw, Tl, O)                      \
    265 uint64_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 }                                                               \
    280 uint64_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 }                                                               \
    290 uint64_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)
    301 IWMMXT_OP_CMP(cmpeq, uint8_t, uint16_t, uint32_t, ==)
    302 IWMMXT_OP_CMP(cmpgts, int8_t, int16_t, int32_t, >)
    303 IWMMXT_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))
    307 IWMMXT_OP_CMP(mins, int8_t, int16_t, int32_t, <)
    308 IWMMXT_OP_CMP(minu, uint8_t, uint16_t, uint32_t, <)
    309 IWMMXT_OP_CMP(maxs, int8_t, int16_t, int32_t, >)
    310 IWMMXT_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)
    314 IWMMXT_OP_CMP(subn, uint8_t, uint16_t, uint32_t, -)
    315 IWMMXT_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)
    320 IWMMXT_OP_CMP(subu, uint8_t, uint16_t, uint32_t, -)
    321 IWMMXT_OP_CMP(addu, uint8_t, uint16_t, uint32_t, +)
    322 IWMMXT_OP_CMP(subs, int8_t, int16_t, int32_t, -)
    323 IWMMXT_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)                                                 \
    330 uint64_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 }
    346 IWMMXT_OP_AVGB(0)
    347 IWMMXT_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)                                               \
    354 uint64_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 }
    365 IWMMXT_OP_AVGW(0)
    366 IWMMXT_OP_AVGW(1)
    367 #undef IWMMXT_OP_AVGW
    368 #undef AVGW
    369 
    370 uint64_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 
    377 uint64_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 
    384 uint32_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 
    390 uint64_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 
    400 uint64_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 
    408 uint64_t HELPER(iwmmxt_bcstl)(uint32_t arg)
    409 {
    410     return arg | ((uint64_t) arg << 32);
    411 }
    412 
    413 uint64_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 
    422 uint64_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 
    429 uint64_t HELPER(iwmmxt_addcl)(uint64_t x)
    430 {
    431     return (x & 0xffffffff) + (x >> 32);
    432 }
    433 
    434 uint32_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 
    443 uint32_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 
    450 uint32_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.  */
    456 uint64_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 
    468 uint64_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 
    477 uint64_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 
    484 uint64_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 
    496 uint64_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 
    505 uint64_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 
    512 uint64_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 
    524 uint64_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 
    533 uint64_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 
    540 uint64_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 
    556 uint64_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 
    567 uint64_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 
    574 uint64_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 */
    587 uint64_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 
    601 uint64_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 
    611 uint64_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 */
    620 uint64_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 
    634 uint64_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 
    644 uint64_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 
    652 uint64_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 
    657 uint64_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 
    666 uint64_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 }