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