Annotation of qemu/target-arm/iwmmxt_helper.c, revision 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.