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