|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.