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