Annotation of qemu/target-arm/iwmmxt_helper.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.