1 /*  iwmmxt.c -- Intel(r) Wireless MMX(tm) technology co-processor interface.
2     Copyright (C) 2002-2024 Free Software Foundation, Inc.
3     Contributed by matthew green (mrg@redhat.com).
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 3 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>. */
17 
18 /* This must come before any other includes.  */
19 #include "defs.h"
20 
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "armdefs.h"
25 #include "armos.h"
26 #include "armemu.h"
27 #include "ansidecl.h"
28 #include "iwmmxt.h"
29 
30 /* #define DEBUG 1 */
31 
32 /* Intel(r) Wireless MMX(tm) technology co-processor.
33    It uses co-processor numbers (0 and 1).  There are 16 vector registers wRx
34    and 16 control registers wCx.  Co-processors 0 and 1 are used in MCR/MRC
35    to access wRx and wCx respectively.  */
36 
37 static ARMdword wR[16];
38 static ARMword  wC[16] = { 0x69051010 };
39 
40 #define SUBSTR(w,t,m,n) ((t)(w <<  ((sizeof (t) * 8 - 1) - (n))) \
41                                >> (((sizeof (t) * 8 - 1) - (n)) + (m)))
42 #define wCBITS(w,x,y)   SUBSTR (wC[w], ARMword, x, y)
43 #define wRBITS(w,x,y)   SUBSTR (wR[w], ARMdword, x, y)
44 #define wCID   0
45 #define wCon   1
46 #define wCSSF  2
47 #define wCASF  3
48 #define wCGR0  8
49 #define wCGR1  9
50 #define wCGR2 10
51 #define wCGR3 11
52 
53 /* Bits in the wCon register.  */
54 #define WCON_CUP    (1 << 0)
55 #define WCON_MUP    (1 << 1)
56 
57 /* Set the SIMD wCASF flags for 8, 16, 32 or 64-bit operations.  */
58 #define SIMD8_SET(x,  v, n, b)          (x) |= ((v != 0) << ((((b) + 1) * 4) + (n)))
59 #define SIMD16_SET(x, v, n, h)          (x) |= ((v != 0) << ((((h) + 1) * 8) + (n)))
60 #define SIMD32_SET(x, v, n, w)          (x) |= ((v != 0) << ((((w) + 1) * 16) + (n)))
61 #define SIMD64_SET(x, v, n)   (x) |= ((v != 0) << (32 + (n)))
62 
63 /* Flags to pass as "n" above.  */
64 #define SIMD_NBIT   -1
65 #define SIMD_ZBIT   -2
66 #define SIMD_CBIT   -3
67 #define SIMD_VBIT   -4
68 
69 /* Various status bit macros.  */
70 #define NBIT8(x)    ((x) & 0x80)
71 #define NBIT16(x)   ((x) & 0x8000)
72 #define NBIT32(x)   ((x) & 0x80000000)
73 #define NBIT64(x)   ((x) & 0x8000000000000000ULL)
74 #define ZBIT8(x)    (((x) & 0xff) == 0)
75 #define ZBIT16(x)   (((x) & 0xffff) == 0)
76 #define ZBIT32(x)   (((x) & 0xffffffff) == 0)
77 #define ZBIT64(x)   (x == 0)
78 
79 /* Access byte/half/word "n" of register "x".  */
80 #define wRBYTE(x,n) wRBITS ((x), (n) * 8, (n) * 8 + 7)
81 #define wRHALF(x,n) wRBITS ((x), (n) * 16, (n) * 16 + 15)
82 #define wRWORD(x,n) wRBITS ((x), (n) * 32, (n) * 32 + 31)
83 
84 /* Macro to handle how the G bit selects wCGR registers.  */
85 #define DECODE_G_BIT(state, instr, shift)         \
86 {                                                           \
87   unsigned int reg;                               \
88                                                             \
89   reg = BITS (0, 3);                                        \
90                                                             \
91   if (BIT (8))      /* G */                                 \
92     {                                                       \
93       if (reg < wCGR0 || reg > wCGR3)             \
94           {                                                 \
95             ARMul_UndefInstr (state, instr);      \
96             return ARMul_DONE;                              \
97           }                                                 \
98       shift = wC [reg];                                     \
99     }                                                       \
100   else                                                      \
101     shift = wR [reg];                                       \
102                                                             \
103   shift &= 0xff;                                  \
104 }
105 
106 /* Index calculations for the satrv[] array.  */
107 #define BITIDX8(x)  (x)
108 #define BITIDX16(x) (((x) + 1) * 2 - 1)
109 #define BITIDX32(x) (((x) + 1) * 4 - 1)
110 
111 /* Sign extension macros.  */
112 #define EXTEND8(a)  ((a) & 0x80 ? ((a) | 0xffffff00) : (a))
113 #define EXTEND16(a) ((a) & 0x8000 ? ((a) | 0xffff0000) : (a))
114 #define EXTEND32(a) ((a) & 0x80000000ULL ? ((a) | 0xffffffff00000000ULL) : (a))
115 
116 /* Set the wCSSF from 8 values.  */
117 #define SET_wCSSF(a,b,c,d,e,f,g,h) \
118   wC[wCSSF] = (((h) != 0) << 7) | (((g) != 0) << 6) \
119             | (((f) != 0) << 5) | (((e) != 0) << 4) \
120             | (((d) != 0) << 3) | (((c) != 0) << 2) \
121             | (((b) != 0) << 1) | (((a) != 0) << 0);
122 
123 /* Set the wCSSR from an array with 8 values.  */
124 #define SET_wCSSFvec(v) \
125   SET_wCSSF((v)[0],(v)[1],(v)[2],(v)[3],(v)[4],(v)[5],(v)[6],(v)[7])
126 
127 /* Size qualifiers for vector operations.  */
128 #define Bqual                           0
129 #define Hqual                           1
130 #define Wqual                           2
131 #define Dqual                           3
132 
133 /* Saturation qualifiers for vector operations.  */
134 #define NoSaturation                    0
135 #define UnsignedSaturation    1
136 #define SignedSaturation      3
137 
138 
139 /* Prototypes.  */
140 static ARMword         Add32  (ARMword,  ARMword,  int *, int *, ARMword);
141 static ARMdword        AddS32 (ARMdword, ARMdword, int *, int *);
142 static ARMdword        AddU32 (ARMdword, ARMdword, int *, int *);
143 static ARMword         AddS16 (ARMword,  ARMword,  int *, int *);
144 static ARMword         AddU16 (ARMword,  ARMword,  int *, int *);
145 static ARMword         AddS8  (ARMword,  ARMword,  int *, int *);
146 static ARMword         AddU8  (ARMword,  ARMword,  int *, int *);
147 static ARMword         Sub32  (ARMword,  ARMword,  int *, int *, ARMword);
148 static ARMdword        SubS32 (ARMdword, ARMdword, int *, int *);
149 static ARMdword        SubU32 (ARMdword, ARMdword, int *, int *);
150 static ARMword         SubS16 (ARMword,  ARMword,  int *, int *);
151 static ARMword         SubS8  (ARMword,  ARMword,  int *, int *);
152 static ARMword         SubU16 (ARMword,  ARMword,  int *, int *);
153 static ARMword         SubU8  (ARMword,  ARMword,  int *, int *);
154 static unsigned char   IwmmxtSaturateU8  (signed short, int *);
155 static signed char     IwmmxtSaturateS8  (signed short, int *);
156 static unsigned short  IwmmxtSaturateU16 (signed int, int *);
157 static signed short    IwmmxtSaturateS16 (signed int, int *);
158 static unsigned long   IwmmxtSaturateU32 (signed long long, int *);
159 static signed long     IwmmxtSaturateS32 (signed long long, int *);
160 static ARMword         Compute_Iwmmxt_Address   (ARMul_State *, ARMword, int *);
161 static ARMdword        Iwmmxt_Load_Double_Word  (ARMul_State *, ARMword);
162 static ARMword         Iwmmxt_Load_Word         (ARMul_State *, ARMword);
163 static ARMword         Iwmmxt_Load_Half_Word    (ARMul_State *, ARMword);
164 static ARMword         Iwmmxt_Load_Byte         (ARMul_State *, ARMword);
165 static void            Iwmmxt_Store_Double_Word (ARMul_State *, ARMword, ARMdword);
166 static void            Iwmmxt_Store_Word        (ARMul_State *, ARMword, ARMword);
167 static void            Iwmmxt_Store_Half_Word   (ARMul_State *, ARMword, ARMword);
168 static void            Iwmmxt_Store_Byte        (ARMul_State *, ARMword, ARMword);
169 static int             Process_Instruction      (ARMul_State *, ARMword);
170 
171 static int TANDC    (ARMul_State *, ARMword);
172 static int TBCST    (ARMul_State *, ARMword);
173 static int TEXTRC   (ARMul_State *, ARMword);
174 static int TEXTRM   (ARMul_State *, ARMword);
175 static int TINSR    (ARMul_State *, ARMword);
176 static int TMCR     (ARMul_State *, ARMword);
177 static int TMCRR    (ARMul_State *, ARMword);
178 static int TMIA     (ARMul_State *, ARMword);
179 static int TMIAPH   (ARMul_State *, ARMword);
180 static int TMIAxy   (ARMul_State *, ARMword);
181 static int TMOVMSK  (ARMul_State *, ARMword);
182 static int TMRC     (ARMul_State *, ARMword);
183 static int TMRRC    (ARMul_State *, ARMword);
184 static int TORC     (ARMul_State *, ARMword);
185 static int WACC     (ARMul_State *, ARMword);
186 static int WADD     (ARMul_State *, ARMword);
187 static int WALIGNI  (ARMword);
188 static int WALIGNR  (ARMul_State *, ARMword);
189 static int WAND     (ARMword);
190 static int WANDN    (ARMword);
191 static int WAVG2    (ARMword);
192 static int WCMPEQ   (ARMul_State *, ARMword);
193 static int WCMPGT   (ARMul_State *, ARMword);
194 static int WLDR     (ARMul_State *, ARMword);
195 static int WMAC     (ARMword);
196 static int WMADD    (ARMword);
197 static int WMAX     (ARMul_State *, ARMword);
198 static int WMIN     (ARMul_State *, ARMword);
199 static int WMUL     (ARMword);
200 static int WOR      (ARMword);
201 static int WPACK    (ARMul_State *, ARMword);
202 static int WROR     (ARMul_State *, ARMword);
203 static int WSAD     (ARMword);
204 static int WSHUFH   (ARMword);
205 static int WSLL     (ARMul_State *, ARMword);
206 static int WSRA     (ARMul_State *, ARMword);
207 static int WSRL     (ARMul_State *, ARMword);
208 static int WSTR     (ARMul_State *, ARMword);
209 static int WSUB     (ARMul_State *, ARMword);
210 static int WUNPCKEH (ARMul_State *, ARMword);
211 static int WUNPCKEL (ARMul_State *, ARMword);
212 static int WUNPCKIH (ARMul_State *, ARMword);
213 static int WUNPCKIL (ARMul_State *, ARMword);
214 static int WXOR     (ARMword);
215 
216 /* This function does the work of adding two 32bit values
217    together, and calculating if a carry has occurred.  */
218 
219 static ARMword
Add32(ARMword a1,ARMword a2,int * carry_ptr,int * overflow_ptr,ARMword sign_mask)220 Add32 (ARMword a1,
221        ARMword a2,
222        int * carry_ptr,
223        int * overflow_ptr,
224        ARMword sign_mask)
225 {
226   ARMword result = (a1 + a2);
227   unsigned int uresult = (unsigned int) result;
228   unsigned int ua1 = (unsigned int) a1;
229 
230   /* If (result == a1) and (a2 == 0),
231      or (result > a2) then we have no carry.  */
232   * carry_ptr = ((uresult == ua1) ? (a2 != 0) : (uresult < ua1));
233 
234   /* Overflow occurs when both arguments are the
235      same sign, but the result is a different sign.  */
236   * overflow_ptr = (   ( (result & sign_mask) && !(a1 & sign_mask) && !(a2 & sign_mask))
237                         || (!(result & sign_mask) &&  (a1 & sign_mask) &&  (a2 & sign_mask)));
238 
239   return result;
240 }
241 
242 static ARMdword
AddS32(ARMdword a1,ARMdword a2,int * carry_ptr,int * overflow_ptr)243 AddS32 (ARMdword a1, ARMdword a2, int * carry_ptr, int * overflow_ptr)
244 {
245   ARMdword     result;
246   unsigned int uresult;
247   unsigned int ua1;
248 
249   a1 = EXTEND32 (a1);
250   a2 = EXTEND32 (a2);
251 
252   result  = a1 + a2;
253   uresult = (unsigned int) result;
254   ua1     = (unsigned int) a1;
255 
256   * carry_ptr = ((uresult == a1) ? (a2 != 0) : (uresult < ua1));
257 
258   * overflow_ptr = (   ( (result & 0x80000000ULL) && !(a1 & 0x80000000ULL) && !(a2 & 0x80000000ULL))
259                         || (!(result & 0x80000000ULL) &&  (a1 & 0x80000000ULL) &&  (a2 & 0x80000000ULL)));
260 
261   return result;
262 }
263 
264 static ARMdword
AddU32(ARMdword a1,ARMdword a2,int * carry_ptr,int * overflow_ptr)265 AddU32 (ARMdword a1, ARMdword a2, int * carry_ptr, int * overflow_ptr)
266 {
267   ARMdword     result;
268   unsigned int uresult;
269   unsigned int ua1;
270 
271   a1 &= 0xffffffff;
272   a2 &= 0xffffffff;
273 
274   result  = a1 + a2;
275   uresult = (unsigned int) result;
276   ua1     = (unsigned int) a1;
277 
278   * carry_ptr = ((uresult == a1) ? (a2 != 0) : (uresult < ua1));
279 
280   * overflow_ptr = (   ( (result & 0x80000000ULL) && !(a1 & 0x80000000ULL) && !(a2 & 0x80000000ULL))
281                         || (!(result & 0x80000000ULL) &&  (a1 & 0x80000000ULL) &&  (a2 & 0x80000000ULL)));
282 
283   return result;
284 }
285 
286 static ARMword
AddS16(ARMword a1,ARMword a2,int * carry_ptr,int * overflow_ptr)287 AddS16 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
288 {
289   a1 = EXTEND16 (a1);
290   a2 = EXTEND16 (a2);
291 
292   return Add32 (a1, a2, carry_ptr, overflow_ptr, 0x8000);
293 }
294 
295 static ARMword
AddU16(ARMword a1,ARMword a2,int * carry_ptr,int * overflow_ptr)296 AddU16 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
297 {
298   a1 &= 0xffff;
299   a2 &= 0xffff;
300 
301   return Add32 (a1, a2, carry_ptr, overflow_ptr, 0x8000);
302 }
303 
304 static ARMword
AddS8(ARMword a1,ARMword a2,int * carry_ptr,int * overflow_ptr)305 AddS8 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
306 {
307   a1 = EXTEND8 (a1);
308   a2 = EXTEND8 (a2);
309 
310   return Add32 (a1, a2, carry_ptr, overflow_ptr, 0x80);
311 }
312 
313 static ARMword
AddU8(ARMword a1,ARMword a2,int * carry_ptr,int * overflow_ptr)314 AddU8 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
315 {
316   a1 &= 0xff;
317   a2 &= 0xff;
318 
319   return Add32 (a1, a2, carry_ptr, overflow_ptr, 0x80);
320 }
321 
322 static ARMword
Sub32(ARMword a1,ARMword a2,int * borrow_ptr,int * overflow_ptr,ARMword sign_mask)323 Sub32 (ARMword a1,
324        ARMword a2,
325        int * borrow_ptr,
326        int * overflow_ptr,
327        ARMword sign_mask)
328 {
329   ARMword result = (a1 - a2);
330   unsigned int ua1 = (unsigned int) a1;
331   unsigned int ua2 = (unsigned int) a2;
332 
333   /* A borrow occurs if a2 is (unsigned) larger than a1.
334      However the carry flag is *cleared* if a borrow occurs.  */
335   * borrow_ptr = ! (ua2 > ua1);
336 
337   /* Overflow occurs when a negative number is subtracted from a
338      positive number and the result is negative or a positive
339      number is subtracted from a negative number and the result is
340      positive.  */
341   * overflow_ptr = ( (! (a1 & sign_mask) &&   (a2 & sign_mask) &&   (result & sign_mask))
342                         || ((a1 & sign_mask) && ! (a2 & sign_mask) && ! (result & sign_mask)));
343 
344   return result;
345 }
346 
347 static ARMdword
SubS32(ARMdword a1,ARMdword a2,int * borrow_ptr,int * overflow_ptr)348 SubS32 (ARMdword a1, ARMdword a2, int * borrow_ptr, int * overflow_ptr)
349 {
350   ARMdword     result;
351   unsigned int ua1;
352   unsigned int ua2;
353 
354   a1 = EXTEND32 (a1);
355   a2 = EXTEND32 (a2);
356 
357   result = a1 - a2;
358   ua1    = (unsigned int) a1;
359   ua2    = (unsigned int) a2;
360 
361   * borrow_ptr = ! (ua2 > ua1);
362 
363   * overflow_ptr = ( (! (a1 & 0x80000000ULL) &&   (a2 & 0x80000000ULL) &&   (result & 0x80000000ULL))
364                         || ((a1 & 0x80000000ULL) && ! (a2 & 0x80000000ULL) && ! (result & 0x80000000ULL)));
365 
366   return result;
367 }
368 
369 static ARMword
SubS16(ARMword a1,ARMword a2,int * carry_ptr,int * overflow_ptr)370 SubS16 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
371 {
372   a1 = EXTEND16 (a1);
373   a2 = EXTEND16 (a2);
374 
375   return Sub32 (a1, a2, carry_ptr, overflow_ptr, 0x8000);
376 }
377 
378 static ARMword
SubS8(ARMword a1,ARMword a2,int * carry_ptr,int * overflow_ptr)379 SubS8 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
380 {
381   a1 = EXTEND8 (a1);
382   a2 = EXTEND8 (a2);
383 
384   return Sub32 (a1, a2, carry_ptr, overflow_ptr, 0x80);
385 }
386 
387 static ARMword
SubU16(ARMword a1,ARMword a2,int * carry_ptr,int * overflow_ptr)388 SubU16 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
389 {
390   a1 &= 0xffff;
391   a2 &= 0xffff;
392 
393   return Sub32 (a1, a2, carry_ptr, overflow_ptr, 0x8000);
394 }
395 
396 static ARMword
SubU8(ARMword a1,ARMword a2,int * carry_ptr,int * overflow_ptr)397 SubU8 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr)
398 {
399   a1 &= 0xff;
400   a2 &= 0xff;
401 
402   return Sub32 (a1, a2, carry_ptr, overflow_ptr, 0x80);
403 }
404 
405 static ARMdword
SubU32(ARMdword a1,ARMdword a2,int * borrow_ptr,int * overflow_ptr)406 SubU32 (ARMdword a1, ARMdword a2, int * borrow_ptr, int * overflow_ptr)
407 {
408   ARMdword     result;
409   unsigned int ua1;
410   unsigned int ua2;
411 
412   a1 &= 0xffffffff;
413   a2 &= 0xffffffff;
414 
415   result = a1 - a2;
416   ua1    = (unsigned int) a1;
417   ua2    = (unsigned int) a2;
418 
419   * borrow_ptr = ! (ua2 > ua1);
420 
421   * overflow_ptr = ( (! (a1 & 0x80000000ULL) &&   (a2 & 0x80000000ULL) &&   (result & 0x80000000ULL))
422                         || ((a1 & 0x80000000ULL) && ! (a2 & 0x80000000ULL) && ! (result & 0x80000000ULL)));
423 
424   return result;
425 }
426 
427 /* For the saturation.  */
428 
429 static unsigned char
IwmmxtSaturateU8(signed short val,int * sat)430 IwmmxtSaturateU8 (signed short val, int * sat)
431 {
432   unsigned char rv;
433 
434   if (val < 0)
435     {
436       rv = 0;
437       *sat = 1;
438     }
439   else if (val > 0xff)
440     {
441       rv = 0xff;
442       *sat = 1;
443     }
444   else
445     {
446       rv = val & 0xff;
447       *sat = 0;
448     }
449   return rv;
450 }
451 
452 static signed char
IwmmxtSaturateS8(signed short val,int * sat)453 IwmmxtSaturateS8 (signed short val, int * sat)
454 {
455   signed char rv;
456 
457   if (val < -0x80)
458     {
459       rv = -0x80;
460       *sat = 1;
461     }
462   else if (val > 0x7f)
463     {
464       rv = 0x7f;
465       *sat = 1;
466     }
467   else
468     {
469       rv = val & 0xff;
470       *sat = 0;
471     }
472   return rv;
473 }
474 
475 static unsigned short
IwmmxtSaturateU16(signed int val,int * sat)476 IwmmxtSaturateU16 (signed int val, int * sat)
477 {
478   unsigned short rv;
479 
480   if (val < 0)
481     {
482       rv = 0;
483       *sat = 1;
484     }
485   else if (val > 0xffff)
486     {
487       rv = 0xffff;
488       *sat = 1;
489     }
490   else
491     {
492       rv = val & 0xffff;
493       *sat = 0;
494     }
495   return rv;
496 }
497 
498 static signed short
IwmmxtSaturateS16(signed int val,int * sat)499 IwmmxtSaturateS16 (signed int val, int * sat)
500 {
501   signed short rv;
502 
503   if (val < -0x8000)
504     {
505       rv = - 0x8000;
506       *sat = 1;
507     }
508   else if (val > 0x7fff)
509     {
510       rv = 0x7fff;
511       *sat = 1;
512     }
513   else
514     {
515       rv = val & 0xffff;
516       *sat = 0;
517     }
518   return rv;
519 }
520 
521 static unsigned long
IwmmxtSaturateU32(signed long long val,int * sat)522 IwmmxtSaturateU32 (signed long long val, int * sat)
523 {
524   unsigned long rv;
525 
526   if (val < 0)
527     {
528       rv = 0;
529       *sat = 1;
530     }
531   else if (val > 0xffffffff)
532     {
533       rv = 0xffffffff;
534       *sat = 1;
535     }
536   else
537     {
538       rv = val & 0xffffffff;
539       *sat = 0;
540     }
541   return rv;
542 }
543 
544 static signed long
IwmmxtSaturateS32(signed long long val,int * sat)545 IwmmxtSaturateS32 (signed long long val, int * sat)
546 {
547   signed long rv;
548 
549   if (val < -0x80000000LL)
550     {
551       rv = -0x80000000;
552       *sat = 1;
553     }
554   else if (val > 0x7fffffff)
555     {
556       rv = 0x7fffffff;
557       *sat = 1;
558     }
559   else
560     {
561       rv = val & 0xffffffff;
562       *sat = 0;
563     }
564   return rv;
565 }
566 
567 /* Intel(r) Wireless MMX(tm) technology Acessor functions.  */
568 
569 unsigned
IwmmxtLDC(ARMul_State * state ATTRIBUTE_UNUSED,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword data)570 IwmmxtLDC (ARMul_State * state ATTRIBUTE_UNUSED,
571              unsigned      type  ATTRIBUTE_UNUSED,
572              ARMword       instr,
573              ARMword       data)
574 {
575   return ARMul_CANT;
576 }
577 
578 unsigned
IwmmxtSTC(ARMul_State * state ATTRIBUTE_UNUSED,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword * data)579 IwmmxtSTC (ARMul_State * state ATTRIBUTE_UNUSED,
580              unsigned      type  ATTRIBUTE_UNUSED,
581              ARMword       instr,
582              ARMword *     data)
583 {
584   return ARMul_CANT;
585 }
586 
587 unsigned
IwmmxtMRC(ARMul_State * state ATTRIBUTE_UNUSED,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword * value)588 IwmmxtMRC (ARMul_State * state ATTRIBUTE_UNUSED,
589              unsigned      type  ATTRIBUTE_UNUSED,
590              ARMword       instr,
591              ARMword *     value)
592 {
593   return ARMul_CANT;
594 }
595 
596 unsigned
IwmmxtMCR(ARMul_State * state ATTRIBUTE_UNUSED,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword value)597 IwmmxtMCR (ARMul_State * state ATTRIBUTE_UNUSED,
598              unsigned      type  ATTRIBUTE_UNUSED,
599              ARMword       instr,
600              ARMword       value)
601 {
602   return ARMul_CANT;
603 }
604 
605 unsigned
IwmmxtCDP(ARMul_State * state,unsigned type,ARMword instr)606 IwmmxtCDP (ARMul_State * state, unsigned type, ARMword instr)
607 {
608   return ARMul_CANT;
609 }
610 
611 /* Intel(r) Wireless MMX(tm) technology instruction implementations.  */
612 
613 static int
TANDC(ARMul_State * state,ARMword instr)614 TANDC (ARMul_State * state, ARMword instr)
615 {
616   ARMword cpsr;
617 
618   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
619     return ARMul_CANT;
620 
621 #ifdef DEBUG
622   fprintf (stderr, "tandc\n");
623 #endif
624 
625   /* The Rd field must be r15.  */
626   if (BITS (12, 15) != 15)
627     return ARMul_CANT;
628 
629   /* The CRn field must be r3.  */
630   if (BITS (16, 19) != 3)
631     return ARMul_CANT;
632 
633   /* The CRm field must be r0.  */
634   if (BITS (0, 3) != 0)
635     return ARMul_CANT;
636 
637   cpsr = ARMul_GetCPSR (state) & 0x0fffffff;
638 
639   switch (BITS (22, 23))
640     {
641     case Bqual:
642       cpsr |= (  (wCBITS (wCASF, 28, 31) & wCBITS (wCASF, 24, 27)
643                     & wCBITS (wCASF, 20, 23) & wCBITS (wCASF, 16, 19)
644                     & wCBITS (wCASF, 12, 15) & wCBITS (wCASF,  8, 11)
645                     & wCBITS (wCASF,  4,  7) & wCBITS (wCASF,  0,  3)) << 28);
646       break;
647 
648     case Hqual:
649       cpsr |= (  (wCBITS (wCASF, 28, 31) & wCBITS (wCASF, 20, 23)
650                     & wCBITS (wCASF, 12, 15) & wCBITS (wCASF,  4, 7)) << 28);
651       break;
652 
653     case Wqual:
654       cpsr |= ((wCBITS (wCASF, 28, 31) & wCBITS (wCASF, 12, 15)) << 28);
655       break;
656 
657     default:
658       ARMul_UndefInstr (state, instr);
659       return ARMul_DONE;
660     }
661 
662   ARMul_SetCPSR (state, cpsr);
663 
664   return ARMul_DONE;
665 }
666 
667 static int
TBCST(ARMul_State * state,ARMword instr)668 TBCST (ARMul_State * state, ARMword instr)
669 {
670   ARMdword Rn;
671   int wRd;
672 
673   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
674     return ARMul_CANT;
675 
676 #ifdef DEBUG
677   fprintf (stderr, "tbcst\n");
678 #endif
679 
680   Rn  = state->Reg [BITS (12, 15)];
681   if (BITS (12, 15) == 15)
682     Rn &= 0xfffffffc;
683 
684   wRd = BITS (16, 19);
685 
686   switch (BITS (6, 7))
687     {
688     case Bqual:
689       Rn &= 0xff;
690       wR [wRd] = (Rn << 56) | (Rn << 48) | (Rn << 40) | (Rn << 32)
691                  | (Rn << 24) | (Rn << 16) | (Rn << 8) | Rn;
692       break;
693 
694     case Hqual:
695       Rn &= 0xffff;
696       wR [wRd] = (Rn << 48) | (Rn << 32) | (Rn << 16) | Rn;
697       break;
698 
699     case Wqual:
700       Rn &= 0xffffffff;
701       wR [wRd] = (Rn << 32) | Rn;
702       break;
703 
704     default:
705       ARMul_UndefInstr (state, instr);
706       break;
707     }
708 
709   wC [wCon] |= WCON_MUP;
710   return ARMul_DONE;
711 }
712 
713 static int
TEXTRC(ARMul_State * state,ARMword instr)714 TEXTRC (ARMul_State * state, ARMword instr)
715 {
716   ARMword cpsr;
717   ARMword selector;
718 
719   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
720     return ARMul_CANT;
721 
722 #ifdef DEBUG
723   fprintf (stderr, "textrc\n");
724 #endif
725 
726   /* The Rd field must be r15.  */
727   if (BITS (12, 15) != 15)
728     return ARMul_CANT;
729 
730   /* The CRn field must be r3.  */
731   if (BITS (16, 19) != 3)
732     return ARMul_CANT;
733 
734   /* The CRm field must be 0xxx.  */
735   if (BIT (3) != 0)
736     return ARMul_CANT;
737 
738   selector = BITS (0, 2);
739   cpsr = ARMul_GetCPSR (state) & 0x0fffffff;
740 
741   switch (BITS (22, 23))
742     {
743     case Bqual: selector *= 4; break;
744     case Hqual: selector = ((selector & 3) * 8) + 4; break;
745     case Wqual: selector = ((selector & 1) * 16) + 12; break;
746 
747     default:
748       ARMul_UndefInstr (state, instr);
749       return ARMul_DONE;
750     }
751 
752   cpsr |= wCBITS (wCASF, selector, selector + 3) << 28;
753   ARMul_SetCPSR (state, cpsr);
754 
755   return ARMul_DONE;
756 }
757 
758 static int
TEXTRM(ARMul_State * state,ARMword instr)759 TEXTRM (ARMul_State * state, ARMword instr)
760 {
761   ARMword Rd;
762   int     offset;
763   int     wRn;
764   int     sign;
765 
766   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
767     return ARMul_CANT;
768 
769 #ifdef DEBUG
770   fprintf (stderr, "textrm\n");
771 #endif
772 
773   wRn    = BITS (16, 19);
774   sign   = BIT (3);
775   offset = BITS (0, 2);
776 
777   switch (BITS (22, 23))
778     {
779     case Bqual:
780       offset *= 8;
781       Rd = wRBITS (wRn, offset, offset + 7);
782       if (sign)
783           Rd = EXTEND8 (Rd);
784       break;
785 
786     case Hqual:
787       offset = (offset & 3) * 16;
788       Rd = wRBITS (wRn, offset, offset + 15);
789       if (sign)
790           Rd = EXTEND16 (Rd);
791       break;
792 
793     case Wqual:
794       offset = (offset & 1) * 32;
795       Rd = wRBITS (wRn, offset, offset + 31);
796       break;
797 
798     default:
799       ARMul_UndefInstr (state, instr);
800       return ARMul_DONE;
801     }
802 
803   if (BITS (12, 15) == 15)
804     ARMul_UndefInstr (state, instr);
805   else
806     state->Reg [BITS (12, 15)] = Rd;
807 
808   return ARMul_DONE;
809 }
810 
811 static int
TINSR(ARMul_State * state,ARMword instr)812 TINSR (ARMul_State * state, ARMword instr)
813 {
814   ARMdword data;
815   ARMword  offset;
816   int      wRd;
817 
818   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
819     return ARMul_CANT;
820 
821 #ifdef DEBUG
822   fprintf (stderr, "tinsr\n");
823 #endif
824 
825   wRd = BITS (16, 19);
826   data = state->Reg [BITS (12, 15)];
827   offset = BITS (0, 2);
828 
829   switch (BITS (6, 7))
830     {
831     case Bqual:
832       data &= 0xff;
833       switch (offset)
834           {
835           case 0: wR [wRd] = data | (wRBITS (wRd, 8, 63) << 8); break;
836           case 1: wR [wRd] = wRBITS (wRd, 0,  7) | (data <<  8) | (wRBITS (wRd, 16, 63) << 16); break;
837           case 2: wR [wRd] = wRBITS (wRd, 0, 15) | (data << 16) | (wRBITS (wRd, 24, 63) << 24); break;
838           case 3: wR [wRd] = wRBITS (wRd, 0, 23) | (data << 24) | (wRBITS (wRd, 32, 63) << 32); break;
839           case 4: wR [wRd] = wRBITS (wRd, 0, 31) | (data << 32) | (wRBITS (wRd, 40, 63) << 40); break;
840           case 5: wR [wRd] = wRBITS (wRd, 0, 39) | (data << 40) | (wRBITS (wRd, 48, 63) << 48); break;
841           case 6: wR [wRd] = wRBITS (wRd, 0, 47) | (data << 48) | (wRBITS (wRd, 56, 63) << 56); break;
842           case 7: wR [wRd] = wRBITS (wRd, 0, 55) | (data << 56); break;
843           }
844       break;
845 
846     case Hqual:
847       data &= 0xffff;
848 
849       switch (offset & 3)
850           {
851           case 0: wR [wRd] = data | (wRBITS (wRd, 16, 63) << 16); break;
852           case 1: wR [wRd] = wRBITS (wRd, 0, 15) | (data << 16) | (wRBITS (wRd, 32, 63) << 32); break;
853           case 2: wR [wRd] = wRBITS (wRd, 0, 31) | (data << 32) | (wRBITS (wRd, 48, 63) << 48); break;
854           case 3: wR [wRd] = wRBITS (wRd, 0, 47) | (data << 48); break;
855           }
856       break;
857 
858     case Wqual:
859       if (offset & 1)
860           wR [wRd] = wRBITS (wRd, 0, 31) | (data << 32);
861       else
862           wR [wRd] = (wRBITS (wRd, 32, 63) << 32) | data;
863       break;
864 
865     default:
866       ARMul_UndefInstr (state, instr);
867       break;
868     }
869 
870   wC [wCon] |= WCON_MUP;
871   return ARMul_DONE;
872 }
873 
874 static int
TMCR(ARMul_State * state,ARMword instr)875 TMCR (ARMul_State * state, ARMword instr)
876 {
877   ARMword val;
878   int     wCreg;
879 
880   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
881     return ARMul_CANT;
882 
883 #ifdef DEBUG
884   fprintf (stderr, "tmcr\n");
885 #endif
886 
887   if (BITS (0, 3) != 0)
888     return ARMul_CANT;
889 
890   val = state->Reg [BITS (12, 15)];
891   if (BITS (12, 15) == 15)
892     val &= 0xfffffffc;
893 
894   wCreg = BITS (16, 19);
895 
896   switch (wCreg)
897     {
898     case wCID:
899       /* The wCID register is read only.  */
900       break;
901 
902     case wCon:
903       /* Writing to the MUP or CUP bits clears them.  */
904       wC [wCon] &= ~ (val & 0x3);
905       break;
906 
907     case wCSSF:
908       /* Only the bottom 8 bits can be written to.
909           The higher bits write as zero.  */
910       wC [wCSSF] = (val & 0xff);
911       wC [wCon] |= WCON_CUP;
912       break;
913 
914     default:
915       wC [wCreg] = val;
916       wC [wCon] |= WCON_CUP;
917       break;
918     }
919 
920   return ARMul_DONE;
921 }
922 
923 static int
TMCRR(ARMul_State * state,ARMword instr)924 TMCRR (ARMul_State * state, ARMword instr)
925 {
926   ARMdword RdHi = state->Reg [BITS (16, 19)];
927   ARMword  RdLo = state->Reg [BITS (12, 15)];
928 
929   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
930     return ARMul_CANT;
931 
932 #ifdef DEBUG
933   fprintf (stderr, "tmcrr\n");
934 #endif
935 
936   if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15))
937     return ARMul_CANT;
938 
939   wR [BITS (0, 3)] = (RdHi << 32) | RdLo;
940 
941   wC [wCon] |= WCON_MUP;
942 
943   return ARMul_DONE;
944 }
945 
946 static int
TMIA(ARMul_State * state,ARMword instr)947 TMIA (ARMul_State * state, ARMword instr)
948 {
949   signed long long a, b;
950 
951   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
952     return ARMul_CANT;
953 
954 #ifdef DEBUG
955   fprintf (stderr, "tmia\n");
956 #endif
957 
958   if ((BITS (0, 3) == 15) || (BITS (12, 15) == 15))
959     {
960       ARMul_UndefInstr (state, instr);
961       return ARMul_DONE;
962     }
963 
964   a = state->Reg [BITS (0, 3)];
965   b = state->Reg [BITS (12, 15)];
966 
967   a = EXTEND32 (a);
968   b = EXTEND32 (b);
969 
970   wR [BITS (5, 8)] += a * b;
971   wC [wCon] |= WCON_MUP;
972 
973   return ARMul_DONE;
974 }
975 
976 static int
TMIAPH(ARMul_State * state,ARMword instr)977 TMIAPH (ARMul_State * state, ARMword instr)
978 {
979   signed long a, b, result;
980   signed long long r;
981   ARMword Rm = state->Reg [BITS (0, 3)];
982   ARMword Rs = state->Reg [BITS (12, 15)];
983 
984   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
985     return ARMul_CANT;
986 
987 #ifdef DEBUG
988   fprintf (stderr, "tmiaph\n");
989 #endif
990 
991   if (BITS (0, 3) == 15 || BITS (12, 15) == 15)
992     {
993       ARMul_UndefInstr (state, instr);
994       return ARMul_DONE;
995     }
996 
997   a = SUBSTR (Rs, ARMword, 16, 31);
998   b = SUBSTR (Rm, ARMword, 16, 31);
999 
1000   a = EXTEND16 (a);
1001   b = EXTEND16 (b);
1002 
1003   result = a * b;
1004 
1005   r = result;
1006   r = EXTEND32 (r);
1007 
1008   wR [BITS (5, 8)] += r;
1009 
1010   a = SUBSTR (Rs, ARMword,  0, 15);
1011   b = SUBSTR (Rm, ARMword,  0, 15);
1012 
1013   a = EXTEND16 (a);
1014   b = EXTEND16 (b);
1015 
1016   result = a * b;
1017 
1018   r = result;
1019   r = EXTEND32 (r);
1020 
1021   wR [BITS (5, 8)] += r;
1022   wC [wCon] |= WCON_MUP;
1023 
1024   return ARMul_DONE;
1025 }
1026 
1027 static int
TMIAxy(ARMul_State * state,ARMword instr)1028 TMIAxy (ARMul_State * state, ARMword instr)
1029 {
1030   ARMword Rm;
1031   ARMword Rs;
1032   long long temp;
1033 
1034   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1035     return ARMul_CANT;
1036 
1037 #ifdef DEBUG
1038   fprintf (stderr, "tmiaxy\n");
1039 #endif
1040 
1041   if (BITS (0, 3) == 15 || BITS (12, 15) == 15)
1042     {
1043       ARMul_UndefInstr (state, instr);
1044       return ARMul_DONE;
1045     }
1046 
1047   Rm = state->Reg [BITS (0, 3)];
1048   if (BIT (17))
1049     Rm >>= 16;
1050   else
1051     Rm &= 0xffff;
1052 
1053   Rs = state->Reg [BITS (12, 15)];
1054   if (BIT (16))
1055     Rs >>= 16;
1056   else
1057     Rs &= 0xffff;
1058 
1059   if (Rm & (1 << 15))
1060     Rm -= 1 << 16;
1061 
1062   if (Rs & (1 << 15))
1063     Rs -= 1 << 16;
1064 
1065   Rm *= Rs;
1066   temp = Rm;
1067 
1068   if (temp & (1 << 31))
1069     temp -= 1ULL << 32;
1070 
1071   wR [BITS (5, 8)] += temp;
1072   wC [wCon] |= WCON_MUP;
1073 
1074   return ARMul_DONE;
1075 }
1076 
1077 static int
TMOVMSK(ARMul_State * state,ARMword instr)1078 TMOVMSK (ARMul_State * state, ARMword instr)
1079 {
1080   ARMdword result;
1081   int      wRn;
1082 
1083   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1084     return ARMul_CANT;
1085 
1086 #ifdef DEBUG
1087   fprintf (stderr, "tmovmsk\n");
1088 #endif
1089 
1090   /* The CRm field must be r0.  */
1091   if (BITS (0, 3) != 0)
1092     return ARMul_CANT;
1093 
1094   wRn = BITS (16, 19);
1095 
1096   switch (BITS (22, 23))
1097     {
1098     case Bqual:
1099       result = (  (wRBITS (wRn, 63, 63) << 7)
1100                     | (wRBITS (wRn, 55, 55) << 6)
1101                     | (wRBITS (wRn, 47, 47) << 5)
1102                     | (wRBITS (wRn, 39, 39) << 4)
1103                     | (wRBITS (wRn, 31, 31) << 3)
1104                     | (wRBITS (wRn, 23, 23) << 2)
1105                     | (wRBITS (wRn, 15, 15) << 1)
1106                     | (wRBITS (wRn,  7,  7) << 0));
1107       break;
1108 
1109     case Hqual:
1110       result = (  (wRBITS (wRn, 63, 63) << 3)
1111                     | (wRBITS (wRn, 47, 47) << 2)
1112                     | (wRBITS (wRn, 31, 31) << 1)
1113                     | (wRBITS (wRn, 15, 15) << 0));
1114       break;
1115 
1116     case Wqual:
1117       result = (wRBITS (wRn, 63, 63) << 1) | wRBITS (wRn, 31, 31);
1118       break;
1119 
1120     default:
1121       ARMul_UndefInstr (state, instr);
1122       return ARMul_DONE;
1123     }
1124 
1125   state->Reg [BITS (12, 15)] = result;
1126 
1127   return ARMul_DONE;
1128 }
1129 
1130 static int
TMRC(ARMul_State * state,ARMword instr)1131 TMRC (ARMul_State * state, ARMword instr)
1132 {
1133   int reg = BITS (12, 15);
1134 
1135   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1136     return ARMul_CANT;
1137 
1138 #ifdef DEBUG
1139   fprintf (stderr, "tmrc\n");
1140 #endif
1141 
1142   if (BITS (0, 3) != 0)
1143     return ARMul_CANT;
1144 
1145   if (reg == 15)
1146     ARMul_UndefInstr (state, instr);
1147   else
1148     state->Reg [reg] = wC [BITS (16, 19)];
1149 
1150   return ARMul_DONE;
1151 }
1152 
1153 static int
TMRRC(ARMul_State * state,ARMword instr)1154 TMRRC (ARMul_State * state, ARMword instr)
1155 {
1156   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1157     return ARMul_CANT;
1158 
1159 #ifdef DEBUG
1160   fprintf (stderr, "tmrrc\n");
1161 #endif
1162 
1163   if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15) || (BITS (4, 11) != 0))
1164     ARMul_UndefInstr (state, instr);
1165   else
1166     {
1167       state->Reg [BITS (16, 19)] = wRBITS (BITS (0, 3), 32, 63);
1168       state->Reg [BITS (12, 15)] = wRBITS (BITS (0, 3),  0, 31);
1169     }
1170 
1171   return ARMul_DONE;
1172 }
1173 
1174 static int
TORC(ARMul_State * state,ARMword instr)1175 TORC (ARMul_State * state, ARMword instr)
1176 {
1177   ARMword cpsr = ARMul_GetCPSR (state);
1178 
1179   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1180     return ARMul_CANT;
1181 
1182 #ifdef DEBUG
1183   fprintf (stderr, "torc\n");
1184 #endif
1185 
1186   /* The Rd field must be r15.  */
1187   if (BITS (12, 15) != 15)
1188     return ARMul_CANT;
1189 
1190   /* The CRn field must be r3.  */
1191   if (BITS (16, 19) != 3)
1192     return ARMul_CANT;
1193 
1194   /* The CRm field must be r0.  */
1195   if (BITS (0, 3) != 0)
1196     return ARMul_CANT;
1197 
1198   cpsr &= 0x0fffffff;
1199 
1200   switch (BITS (22, 23))
1201     {
1202     case Bqual:
1203       cpsr |= (  (wCBITS (wCASF, 28, 31) | wCBITS (wCASF, 24, 27)
1204                     | wCBITS (wCASF, 20, 23) | wCBITS (wCASF, 16, 19)
1205                     | wCBITS (wCASF, 12, 15) | wCBITS (wCASF,  8, 11)
1206                     | wCBITS (wCASF,  4,  7) | wCBITS (wCASF,  0,  3)) << 28);
1207       break;
1208 
1209     case Hqual:
1210       cpsr |= (  (wCBITS (wCASF, 28, 31) | wCBITS (wCASF, 20, 23)
1211                     | wCBITS (wCASF, 12, 15) | wCBITS (wCASF,  4,  7)) << 28);
1212       break;
1213 
1214     case Wqual:
1215       cpsr |= ((wCBITS (wCASF, 28, 31) | wCBITS (wCASF, 12, 15)) << 28);
1216       break;
1217 
1218     default:
1219       ARMul_UndefInstr (state, instr);
1220       return ARMul_DONE;
1221     }
1222 
1223   ARMul_SetCPSR (state, cpsr);
1224 
1225   return ARMul_DONE;
1226 }
1227 
1228 static int
WACC(ARMul_State * state,ARMword instr)1229 WACC (ARMul_State * state, ARMword instr)
1230 {
1231   int wRn;
1232 
1233   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1234     return ARMul_CANT;
1235 
1236 #ifdef DEBUG
1237   fprintf (stderr, "wacc\n");
1238 #endif
1239 
1240   wRn = BITS (16, 19);
1241 
1242   switch (BITS (22, 23))
1243     {
1244     case Bqual:
1245       wR [BITS (12, 15)] =
1246             wRBITS (wRn, 56, 63) + wRBITS (wRn, 48, 55)
1247           + wRBITS (wRn, 40, 47) + wRBITS (wRn, 32, 39)
1248           + wRBITS (wRn, 24, 31) + wRBITS (wRn, 16, 23)
1249           + wRBITS (wRn,  8, 15) + wRBITS (wRn,  0,  7);
1250       break;
1251 
1252     case Hqual:
1253       wR [BITS (12, 15)] =
1254             wRBITS (wRn, 48, 63) + wRBITS (wRn, 32, 47)
1255           + wRBITS (wRn, 16, 31) + wRBITS (wRn,  0, 15);
1256       break;
1257 
1258     case Wqual:
1259       wR [BITS (12, 15)] = wRBITS (wRn, 32, 63) + wRBITS (wRn, 0, 31);
1260       break;
1261 
1262     default:
1263       ARMul_UndefInstr (state, instr);
1264       break;
1265     }
1266 
1267   wC [wCon] |= WCON_MUP;
1268   return ARMul_DONE;
1269 }
1270 
1271 static int
WADD(ARMul_State * state,ARMword instr)1272 WADD (ARMul_State * state, ARMword instr)
1273 {
1274   ARMdword r = 0;
1275   ARMdword x;
1276   ARMdword s;
1277   ARMword  psr = 0;
1278   int      i;
1279   int      carry;
1280   int      overflow;
1281   int      satrv[8];
1282 
1283   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1284     return ARMul_CANT;
1285 
1286 #ifdef DEBUG
1287   fprintf (stderr, "wadd\n");
1288 #endif
1289 
1290   /* Add two numbers using the specified function,
1291      leaving setting the carry bit as required.  */
1292 #define ADDx(x, y, m, f) \
1293    (*f) (wRBITS (BITS (16, 19), (x), (y)) & (m), \
1294          wRBITS (BITS ( 0,  3), (x), (y)) & (m), \
1295         & carry, & overflow)
1296 
1297   switch (BITS (22, 23))
1298     {
1299     case Bqual:
1300       for (i = 0; i < 8; i++)
1301         {
1302             switch (BITS (20, 21))
1303               {
1304               case NoSaturation:
1305                 s = ADDx ((i * 8), (i * 8) + 7, 0xff, AddS8);
1306                 satrv [BITIDX8 (i)] = 0;
1307                 r |= (s & 0xff) << (i * 8);
1308                 SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i);
1309                 SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
1310                 SIMD8_SET (psr, carry,     SIMD_CBIT, i);
1311                 SIMD8_SET (psr, overflow,  SIMD_VBIT, i);
1312                 break;
1313 
1314               case UnsignedSaturation:
1315                 s = ADDx ((i * 8), (i * 8) + 7, 0xff, AddU8);
1316                 x = IwmmxtSaturateU8 (s, satrv + BITIDX8 (i));
1317                 r |= (x & 0xff) << (i * 8);
1318                 SIMD8_SET (psr, NBIT8 (x), SIMD_NBIT, i);
1319                 SIMD8_SET (psr, ZBIT8 (x), SIMD_ZBIT, i);
1320                 if (! satrv [BITIDX8 (i)])
1321                     {
1322                       SIMD8_SET (psr, carry,    SIMD_CBIT, i);
1323                       SIMD8_SET (psr, overflow, SIMD_VBIT, i);
1324                     }
1325                 break;
1326 
1327               case SignedSaturation:
1328                 s = ADDx ((i * 8), (i * 8) + 7, 0xff, AddS8);
1329                 x = IwmmxtSaturateS8 (s, satrv + BITIDX8 (i));
1330                 r |= (x & 0xff) << (i * 8);
1331                 SIMD8_SET (psr, NBIT8 (x), SIMD_NBIT, i);
1332                 SIMD8_SET (psr, ZBIT8 (x), SIMD_ZBIT, i);
1333                 if (! satrv [BITIDX8 (i)])
1334                     {
1335                       SIMD8_SET (psr, carry,    SIMD_CBIT, i);
1336                       SIMD8_SET (psr, overflow, SIMD_VBIT, i);
1337                     }
1338                 break;
1339 
1340               default:
1341                 ARMul_UndefInstr (state, instr);
1342                 return ARMul_DONE;
1343               }
1344           }
1345       break;
1346 
1347     case Hqual:
1348       satrv[0] = satrv[2] = satrv[4] = satrv[6] = 0;
1349 
1350       for (i = 0; i < 4; i++)
1351           {
1352             switch (BITS (20, 21))
1353               {
1354               case NoSaturation:
1355                 s = ADDx ((i * 16), (i * 16) + 15, 0xffff, AddS16);
1356                 satrv [BITIDX16 (i)] = 0;
1357                 r |= (s & 0xffff) << (i * 16);
1358                 SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
1359                 SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
1360                 SIMD16_SET (psr, carry,      SIMD_CBIT, i);
1361                 SIMD16_SET (psr, overflow,   SIMD_VBIT, i);
1362                 break;
1363 
1364               case UnsignedSaturation:
1365                 s = ADDx ((i * 16), (i * 16) + 15, 0xffff, AddU16);
1366                 x = IwmmxtSaturateU16 (s, satrv + BITIDX16 (i));
1367                 r |= (x & 0xffff) << (i * 16);
1368                 SIMD16_SET (psr, NBIT16 (x), SIMD_NBIT, i);
1369                 SIMD16_SET (psr, ZBIT16 (x), SIMD_ZBIT, i);
1370                 if (! satrv [BITIDX16 (i)])
1371                     {
1372                       SIMD16_SET (psr, carry,    SIMD_CBIT, i);
1373                       SIMD16_SET (psr, overflow, SIMD_VBIT, i);
1374                     }
1375                 break;
1376 
1377               case SignedSaturation:
1378                 s = ADDx ((i * 16), (i * 16) + 15, 0xffff, AddS16);
1379                 x = IwmmxtSaturateS16 (s, satrv + BITIDX16 (i));
1380                 r |= (x & 0xffff) << (i * 16);
1381                 SIMD16_SET (psr, NBIT16 (x), SIMD_NBIT, i);
1382                 SIMD16_SET (psr, ZBIT16 (x), SIMD_ZBIT, i);
1383                 if (! satrv [BITIDX16 (i)])
1384                     {
1385                       SIMD16_SET (psr, carry,    SIMD_CBIT, i);
1386                       SIMD16_SET (psr, overflow, SIMD_VBIT, i);
1387                     }
1388                 break;
1389 
1390               default:
1391                 ARMul_UndefInstr (state, instr);
1392                 return ARMul_DONE;
1393               }
1394           }
1395       break;
1396 
1397     case Wqual:
1398       satrv[0] = satrv[1] = satrv[2] = satrv[4] = satrv[5] = satrv[6] = 0;
1399 
1400       for (i = 0; i < 2; i++)
1401           {
1402             switch (BITS (20, 21))
1403               {
1404               case NoSaturation:
1405                 s = ADDx ((i * 32), (i * 32) + 31, 0xffffffff, AddS32);
1406                 satrv [BITIDX32 (i)] = 0;
1407                 r |= (s & 0xffffffff) << (i * 32);
1408                 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
1409                 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
1410                 SIMD32_SET (psr, carry,      SIMD_CBIT, i);
1411                 SIMD32_SET (psr, overflow,   SIMD_VBIT, i);
1412                 break;
1413 
1414               case UnsignedSaturation:
1415                 s = ADDx ((i * 32), (i * 32) + 31, 0xffffffff, AddU32);
1416                 x = IwmmxtSaturateU32 (s, satrv + BITIDX32 (i));
1417                 r |= (x & 0xffffffff) << (i * 32);
1418                 SIMD32_SET (psr, NBIT32 (x), SIMD_NBIT, i);
1419                 SIMD32_SET (psr, ZBIT32 (x), SIMD_ZBIT, i);
1420                 if (! satrv [BITIDX32 (i)])
1421                     {
1422                       SIMD32_SET (psr, carry,    SIMD_CBIT, i);
1423                       SIMD32_SET (psr, overflow, SIMD_VBIT, i);
1424                     }
1425                 break;
1426 
1427               case SignedSaturation:
1428                 s = ADDx ((i * 32), (i * 32) + 31, 0xffffffff, AddS32);
1429                 x = IwmmxtSaturateS32 (s, satrv + BITIDX32 (i));
1430                 r |= (x & 0xffffffff) << (i * 32);
1431                 SIMD32_SET (psr, NBIT32 (x), SIMD_NBIT, i);
1432                 SIMD32_SET (psr, ZBIT32 (x), SIMD_ZBIT, i);
1433                 if (! satrv [BITIDX32 (i)])
1434                     {
1435                       SIMD32_SET (psr, carry,    SIMD_CBIT, i);
1436                       SIMD32_SET (psr, overflow, SIMD_VBIT, i);
1437                     }
1438                 break;
1439 
1440               default:
1441                 ARMul_UndefInstr (state, instr);
1442                 return ARMul_DONE;
1443               }
1444           }
1445       break;
1446 
1447     default:
1448       ARMul_UndefInstr (state, instr);
1449       return ARMul_DONE;
1450     }
1451 
1452   wC [wCASF] = psr;
1453   wR [BITS (12, 15)] = r;
1454   wC [wCon] |= (WCON_MUP | WCON_CUP);
1455 
1456   SET_wCSSFvec (satrv);
1457 
1458 #undef ADDx
1459 
1460   return ARMul_DONE;
1461 }
1462 
1463 static int
WALIGNI(ARMword instr)1464 WALIGNI (ARMword instr)
1465 {
1466   int shift = BITS (20, 22) * 8;
1467 
1468   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1469     return ARMul_CANT;
1470 
1471 #ifdef DEBUG
1472   fprintf (stderr, "waligni\n");
1473 #endif
1474 
1475   if (shift)
1476     wR [BITS (12, 15)] =
1477       wRBITS (BITS (16, 19), shift, 63)
1478       | (wRBITS (BITS (0, 3), 0, shift) << ((64 - shift)));
1479   else
1480     wR [BITS (12, 15)] = wR [BITS (16, 19)];
1481 
1482   wC [wCon] |= WCON_MUP;
1483   return ARMul_DONE;
1484 }
1485 
1486 static int
WALIGNR(ARMul_State * state,ARMword instr)1487 WALIGNR (ARMul_State * state, ARMword instr)
1488 {
1489   int shift = (wC [BITS (20, 21) + 8] & 0x7) * 8;
1490 
1491   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1492     return ARMul_CANT;
1493 
1494 #ifdef DEBUG
1495   fprintf (stderr, "walignr\n");
1496 #endif
1497 
1498   if (shift)
1499     wR [BITS (12, 15)] =
1500       wRBITS (BITS (16, 19), shift, 63)
1501       | (wRBITS (BITS (0, 3), 0, shift) << ((64 - shift)));
1502   else
1503     wR [BITS (12, 15)] = wR [BITS (16, 19)];
1504 
1505   wC [wCon] |= WCON_MUP;
1506   return ARMul_DONE;
1507 }
1508 
1509 static int
WAND(ARMword instr)1510 WAND (ARMword instr)
1511 {
1512   ARMdword result;
1513   ARMword  psr = 0;
1514 
1515   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1516     return ARMul_CANT;
1517 
1518 #ifdef DEBUG
1519   fprintf (stderr, "wand\n");
1520 #endif
1521 
1522   result = wR [BITS (16, 19)] & wR [BITS (0, 3)];
1523   wR [BITS (12, 15)] = result;
1524 
1525   SIMD64_SET (psr, (result == 0), SIMD_ZBIT);
1526   SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT);
1527 
1528   wC [wCASF] = psr;
1529   wC [wCon] |= (WCON_CUP | WCON_MUP);
1530 
1531   return ARMul_DONE;
1532 }
1533 
1534 static int
WANDN(ARMword instr)1535 WANDN (ARMword instr)
1536 {
1537   ARMdword result;
1538   ARMword  psr = 0;
1539 
1540   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1541     return ARMul_CANT;
1542 
1543 #ifdef DEBUG
1544   fprintf (stderr, "wandn\n");
1545 #endif
1546 
1547   result = wR [BITS (16, 19)] & ~ wR [BITS (0, 3)];
1548   wR [BITS (12, 15)] = result;
1549 
1550   SIMD64_SET (psr, (result == 0), SIMD_ZBIT);
1551   SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT);
1552 
1553   wC [wCASF] = psr;
1554   wC [wCon] |= (WCON_CUP | WCON_MUP);
1555 
1556   return ARMul_DONE;
1557 }
1558 
1559 static int
WAVG2(ARMword instr)1560 WAVG2 (ARMword instr)
1561 {
1562   ARMdword r = 0;
1563   ARMword  psr = 0;
1564   ARMdword s;
1565   int      i;
1566   int      round = BIT (20) ? 1 : 0;
1567 
1568   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1569     return ARMul_CANT;
1570 
1571 #ifdef DEBUG
1572   fprintf (stderr, "wavg2\n");
1573 #endif
1574 
1575 #define AVG2x(x, y, m) (((wRBITS (BITS (16, 19), (x), (y)) & (m)) \
1576                            + (wRBITS (BITS ( 0,  3), (x), (y)) & (m)) \
1577                            + round) / 2)
1578 
1579   if (BIT (22))
1580     {
1581       for (i = 0; i < 4; i++)
1582           {
1583             s = AVG2x ((i * 16), (i * 16) + 15, 0xffff) & 0xffff;
1584             SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
1585             r |= s << (i * 16);
1586           }
1587     }
1588   else
1589     {
1590       for (i = 0; i < 8; i++)
1591           {
1592             s = AVG2x ((i * 8), (i * 8) + 7, 0xff) & 0xff;
1593             SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
1594             r |= s << (i * 8);
1595           }
1596     }
1597 
1598   wR [BITS (12, 15)] = r;
1599   wC [wCASF] = psr;
1600   wC [wCon] |= (WCON_CUP | WCON_MUP);
1601 
1602   return ARMul_DONE;
1603 }
1604 
1605 static int
WCMPEQ(ARMul_State * state,ARMword instr)1606 WCMPEQ (ARMul_State * state, ARMword instr)
1607 {
1608   ARMdword r = 0;
1609   ARMword  psr = 0;
1610   ARMdword s;
1611   int      i;
1612 
1613   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1614     return ARMul_CANT;
1615 
1616 #ifdef DEBUG
1617   fprintf (stderr, "wcmpeq\n");
1618 #endif
1619 
1620   switch (BITS (22, 23))
1621     {
1622     case Bqual:
1623       for (i = 0; i < 8; i++)
1624           {
1625             s = wRBYTE (BITS (16, 19), i) == wRBYTE (BITS (0, 3), i) ? 0xff : 0;
1626             r |= s << (i * 8);
1627             SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i);
1628             SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
1629           }
1630       break;
1631 
1632     case Hqual:
1633       for (i = 0; i < 4; i++)
1634           {
1635             s = wRHALF (BITS (16, 19), i) == wRHALF (BITS (0, 3), i) ? 0xffff : 0;
1636             r |= s << (i * 16);
1637             SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
1638             SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
1639           }
1640       break;
1641 
1642     case Wqual:
1643       for (i = 0; i < 2; i++)
1644           {
1645             s = wRWORD (BITS (16, 19), i) == wRWORD (BITS (0, 3), i) ? 0xffffffff : 0;
1646             r |= s << (i * 32);
1647             SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
1648             SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
1649           }
1650       break;
1651 
1652     default:
1653       ARMul_UndefInstr (state, instr);
1654       return ARMul_DONE;
1655     }
1656 
1657   wC [wCASF] = psr;
1658   wR [BITS (12, 15)] = r;
1659   wC [wCon] |= (WCON_CUP | WCON_MUP);
1660 
1661   return ARMul_DONE;
1662 }
1663 
1664 static int
WCMPGT(ARMul_State * state,ARMword instr)1665 WCMPGT (ARMul_State * state, ARMword instr)
1666 {
1667   ARMdword r = 0;
1668   ARMword  psr = 0;
1669   ARMdword s;
1670   int      i;
1671 
1672   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1673     return ARMul_CANT;
1674 
1675 #ifdef DEBUG
1676   fprintf (stderr, "wcmpgt\n");
1677 #endif
1678 
1679   switch (BITS (22, 23))
1680     {
1681     case Bqual:
1682       if (BIT (21))
1683           {
1684             /* Use a signed comparison.  */
1685             for (i = 0; i < 8; i++)
1686               {
1687                 signed char a, b;
1688 
1689                 a = wRBYTE (BITS (16, 19), i);
1690                 b = wRBYTE (BITS (0, 3), i);
1691 
1692                 s = (a > b) ? 0xff : 0;
1693                 r |= s << (i * 8);
1694                 SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i);
1695                 SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
1696               }
1697           }
1698       else
1699           {
1700             for (i = 0; i < 8; i++)
1701               {
1702                 s = (wRBYTE (BITS (16, 19), i) > wRBYTE (BITS (0, 3), i))
1703                     ? 0xff : 0;
1704                 r |= s << (i * 8);
1705                 SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i);
1706                 SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
1707               }
1708           }
1709       break;
1710 
1711     case Hqual:
1712       if (BIT (21))
1713           {
1714             for (i = 0; i < 4; i++)
1715               {
1716                 signed int a, b;
1717 
1718                 a = wRHALF (BITS (16, 19), i);
1719                 a = EXTEND16 (a);
1720 
1721                 b = wRHALF (BITS (0, 3), i);
1722                 b = EXTEND16 (b);
1723 
1724                 s = (a > b) ? 0xffff : 0;
1725                 r |= s << (i * 16);
1726                 SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
1727                 SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
1728               }
1729           }
1730       else
1731           {
1732             for (i = 0; i < 4; i++)
1733               {
1734                 s = (wRHALF (BITS (16, 19), i) > wRHALF (BITS (0, 3), i))
1735                     ? 0xffff : 0;
1736                 r |= s << (i * 16);
1737                 SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
1738                 SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
1739               }
1740           }
1741       break;
1742 
1743     case Wqual:
1744       if (BIT (21))
1745           {
1746             for (i = 0; i < 2; i++)
1747               {
1748                 signed long a, b;
1749 
1750                 a = EXTEND32 (wRWORD (BITS (16, 19), i));
1751                 b = EXTEND32 (wRWORD (BITS (0, 3), i));
1752 
1753                 s = (a > b) ? 0xffffffff : 0;
1754                 r |= s << (i * 32);
1755 
1756                 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
1757                 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
1758               }
1759           }
1760       else
1761           {
1762             for (i = 0; i < 2; i++)
1763               {
1764                 s = (wRWORD (BITS (16, 19), i) > wRWORD (BITS (0, 3), i))
1765                     ? 0xffffffff : 0;
1766                 r |= s << (i * 32);
1767                 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
1768                 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
1769               }
1770           }
1771       break;
1772 
1773     default:
1774       ARMul_UndefInstr (state, instr);
1775       return ARMul_DONE;
1776     }
1777 
1778   wC [wCASF] = psr;
1779   wR [BITS (12, 15)] = r;
1780   wC [wCon] |= (WCON_CUP | WCON_MUP);
1781 
1782   return ARMul_DONE;
1783 }
1784 
1785 static ARMword
Compute_Iwmmxt_Address(ARMul_State * state,ARMword instr,int * pFailed)1786 Compute_Iwmmxt_Address (ARMul_State * state, ARMword instr, int * pFailed)
1787 {
1788   ARMword  Rn;
1789   ARMword  addr;
1790   ARMword  offset;
1791   ARMword  multiplier;
1792 
1793   * pFailed  = 0;
1794   Rn         = BITS (16, 19);
1795   addr       = state->Reg [Rn];
1796   offset     = BITS (0, 7);
1797   multiplier = BIT (8) ? 4 : 1;
1798 
1799   if (BIT (24)) /* P */
1800     {
1801       /* Pre Indexed Addressing.  */
1802       if (BIT (23))
1803           addr += offset * multiplier;
1804       else
1805           addr -= offset * multiplier;
1806 
1807       /* Immediate Pre-Indexed.  */
1808       if (BIT (21)) /* W */
1809           {
1810             if (Rn == 15)
1811               {
1812                 /* Writeback into R15 is UNPREDICTABLE.  */
1813 #ifdef DEBUG
1814                 fprintf (stderr, "iWMMXt: writeback into r15\n");
1815 #endif
1816                 * pFailed = 1;
1817               }
1818             else
1819               state->Reg [Rn] = addr;
1820           }
1821     }
1822   else
1823     {
1824       /* Post Indexed Addressing.  */
1825       if (BIT (21)) /* W */
1826           {
1827             /* Handle the write back of the final address.  */
1828             if (Rn == 15)
1829               {
1830                 /* Writeback into R15 is UNPREDICTABLE.  */
1831 #ifdef DEBUG
1832                 fprintf (stderr, "iWMMXt: writeback into r15\n");
1833 #endif
1834                 * pFailed = 1;
1835               }
1836             else
1837               {
1838                 ARMword  increment;
1839 
1840                 if (BIT (23))
1841                     increment = offset * multiplier;
1842                 else
1843                     increment = - (offset * multiplier);
1844 
1845                 state->Reg [Rn] = addr + increment;
1846               }
1847           }
1848       else
1849           {
1850             /* P == 0, W == 0, U == 0 is UNPREDICTABLE.  */
1851             if (BIT (23) == 0)
1852               {
1853 #ifdef DEBUG
1854                 fprintf (stderr, "iWMMXt: undefined addressing mode\n");
1855 #endif
1856                 * pFailed = 1;
1857               }
1858           }
1859     }
1860 
1861   return addr;
1862 }
1863 
1864 static ARMdword
Iwmmxt_Load_Double_Word(ARMul_State * state,ARMword address)1865 Iwmmxt_Load_Double_Word (ARMul_State * state, ARMword address)
1866 {
1867   ARMdword value;
1868 
1869   /* The address must be aligned on a 8 byte boundary.  */
1870   if (address & 0x7)
1871     {
1872       fprintf (stderr, "iWMMXt: At addr 0x%x: Unaligned double word load from 0x%x\n",
1873                  (state->Reg[15] - 8) & ~0x3, address);
1874 #ifdef DEBUG
1875 #endif
1876       /* No need to check for alignment traps.  An unaligned
1877            double word load with alignment trapping disabled is
1878            UNPREDICTABLE.  */
1879       ARMul_Abort (state, ARMul_DataAbortV);
1880     }
1881 
1882   /* Load the words.  */
1883   if (! state->bigendSig)
1884     {
1885       value = ARMul_LoadWordN (state, address + 4);
1886       value <<= 32;
1887       value |= ARMul_LoadWordN (state, address);
1888     }
1889   else
1890     {
1891       value = ARMul_LoadWordN (state, address);
1892       value <<= 32;
1893       value |= ARMul_LoadWordN (state, address + 4);
1894     }
1895 
1896   /* Check for data aborts.  */
1897   if (state->Aborted)
1898     ARMul_Abort (state, ARMul_DataAbortV);
1899   else
1900     ARMul_Icycles (state, 2, 0L);
1901 
1902   return value;
1903 }
1904 
1905 static ARMword
Iwmmxt_Load_Word(ARMul_State * state,ARMword address)1906 Iwmmxt_Load_Word (ARMul_State * state, ARMword address)
1907 {
1908   ARMword value;
1909 
1910   /* Check for a misaligned address.  */
1911   if (address & 3)
1912     {
1913       if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN))
1914           ARMul_Abort (state, ARMul_DataAbortV);
1915       else
1916           address &= ~ 3;
1917     }
1918 
1919   value = ARMul_LoadWordN (state, address);
1920 
1921   if (state->Aborted)
1922     ARMul_Abort (state, ARMul_DataAbortV);
1923   else
1924     ARMul_Icycles (state, 1, 0L);
1925 
1926   return value;
1927 }
1928 
1929 static ARMword
Iwmmxt_Load_Half_Word(ARMul_State * state,ARMword address)1930 Iwmmxt_Load_Half_Word (ARMul_State * state, ARMword address)
1931 {
1932   ARMword value;
1933 
1934   /* Check for a misaligned address.  */
1935   if (address & 1)
1936     {
1937       if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN))
1938           ARMul_Abort (state, ARMul_DataAbortV);
1939       else
1940           address &= ~ 1;
1941     }
1942 
1943   value = ARMul_LoadHalfWord (state, address);
1944 
1945   if (state->Aborted)
1946     ARMul_Abort (state, ARMul_DataAbortV);
1947   else
1948     ARMul_Icycles (state, 1, 0L);
1949 
1950   return value;
1951 }
1952 
1953 static ARMword
Iwmmxt_Load_Byte(ARMul_State * state,ARMword address)1954 Iwmmxt_Load_Byte (ARMul_State * state, ARMword address)
1955 {
1956   ARMword value;
1957 
1958   value = ARMul_LoadByte (state, address);
1959 
1960   if (state->Aborted)
1961     ARMul_Abort (state, ARMul_DataAbortV);
1962   else
1963     ARMul_Icycles (state, 1, 0L);
1964 
1965   return value;
1966 }
1967 
1968 static void
Iwmmxt_Store_Double_Word(ARMul_State * state,ARMword address,ARMdword value)1969 Iwmmxt_Store_Double_Word (ARMul_State * state, ARMword address, ARMdword value)
1970 {
1971   /* The address must be aligned on a 8 byte boundary.  */
1972   if (address & 0x7)
1973     {
1974       fprintf (stderr, "iWMMXt: At addr 0x%x: Unaligned double word store to 0x%x\n",
1975                  (state->Reg[15] - 8) & ~0x3, address);
1976 #ifdef DEBUG
1977 #endif
1978       /* No need to check for alignment traps.  An unaligned
1979            double word store with alignment trapping disabled is
1980            UNPREDICTABLE.  */
1981       ARMul_Abort (state, ARMul_DataAbortV);
1982     }
1983 
1984   /* Store the words.  */
1985   if (! state->bigendSig)
1986     {
1987       ARMul_StoreWordN (state, address, value);
1988       ARMul_StoreWordN (state, address + 4, value >> 32);
1989     }
1990   else
1991     {
1992       ARMul_StoreWordN (state, address + 4, value);
1993       ARMul_StoreWordN (state, address, value >> 32);
1994     }
1995 
1996   /* Check for data aborts.  */
1997   if (state->Aborted)
1998     ARMul_Abort (state, ARMul_DataAbortV);
1999   else
2000     ARMul_Icycles (state, 2, 0L);
2001 }
2002 
2003 static void
Iwmmxt_Store_Word(ARMul_State * state,ARMword address,ARMword value)2004 Iwmmxt_Store_Word (ARMul_State * state, ARMword address, ARMword value)
2005 {
2006   /* Check for a misaligned address.  */
2007   if (address & 3)
2008     {
2009       if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN))
2010           ARMul_Abort (state, ARMul_DataAbortV);
2011       else
2012           address &= ~ 3;
2013     }
2014 
2015   ARMul_StoreWordN (state, address, value);
2016 
2017   if (state->Aborted)
2018     ARMul_Abort (state, ARMul_DataAbortV);
2019 }
2020 
2021 static void
Iwmmxt_Store_Half_Word(ARMul_State * state,ARMword address,ARMword value)2022 Iwmmxt_Store_Half_Word (ARMul_State * state, ARMword address, ARMword value)
2023 {
2024   /* Check for a misaligned address.  */
2025   if (address & 1)
2026     {
2027       if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN))
2028           ARMul_Abort (state, ARMul_DataAbortV);
2029       else
2030           address &= ~ 1;
2031     }
2032 
2033   ARMul_StoreHalfWord (state, address, value);
2034 
2035   if (state->Aborted)
2036     ARMul_Abort (state, ARMul_DataAbortV);
2037 }
2038 
2039 static void
Iwmmxt_Store_Byte(ARMul_State * state,ARMword address,ARMword value)2040 Iwmmxt_Store_Byte (ARMul_State * state, ARMword address, ARMword value)
2041 {
2042   ARMul_StoreByte (state, address, value);
2043 
2044   if (state->Aborted)
2045     ARMul_Abort (state, ARMul_DataAbortV);
2046 }
2047 
2048 static int
WLDR(ARMul_State * state,ARMword instr)2049 WLDR (ARMul_State * state, ARMword instr)
2050 {
2051   ARMword address;
2052   int failed;
2053 
2054   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2055     return ARMul_CANT;
2056 
2057 #ifdef DEBUG
2058   fprintf (stderr, "wldr\n");
2059 #endif
2060 
2061   address = Compute_Iwmmxt_Address (state, instr, & failed);
2062   if (failed)
2063     return ARMul_CANT;
2064 
2065   if (BITS (28, 31) == 0xf)
2066     {
2067       /* WLDRW wCx */
2068       wC [BITS (12, 15)] = Iwmmxt_Load_Word (state, address);
2069     }
2070   else if (BIT (8) == 0)
2071     {
2072       if (BIT (22) == 0)
2073           /* WLDRB */
2074           wR [BITS (12, 15)] = Iwmmxt_Load_Byte (state, address);
2075       else
2076           /* WLDRH */
2077           wR [BITS (12, 15)] = Iwmmxt_Load_Half_Word (state, address);
2078     }
2079   else
2080     {
2081       if (BIT (22) == 0)
2082           /* WLDRW wRd */
2083           wR [BITS (12, 15)] = Iwmmxt_Load_Word (state, address);
2084       else
2085           /* WLDRD */
2086           wR [BITS (12, 15)] = Iwmmxt_Load_Double_Word (state, address);
2087     }
2088 
2089   wC [wCon] |= WCON_MUP;
2090 
2091   return ARMul_DONE;
2092 }
2093 
2094 static int
WMAC(ARMword instr)2095 WMAC (ARMword instr)
2096 {
2097   int      i;
2098   ARMdword t = 0;
2099   ARMword  a, b;
2100 
2101   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2102     return ARMul_CANT;
2103 
2104 #ifdef DEBUG
2105   fprintf (stderr, "wmac\n");
2106 #endif
2107 
2108   for (i = 0; i < 4; i++)
2109     {
2110       if (BIT (21))
2111         {
2112             /* Signed.  */
2113             signed long s;
2114 
2115             a = wRHALF (BITS (16, 19), i);
2116             a = EXTEND16 (a);
2117 
2118             b = wRHALF (BITS (0, 3), i);
2119             b = EXTEND16 (b);
2120 
2121             s = (signed long) a * (signed long) b;
2122 
2123             t = t + (ARMdword) s;
2124         }
2125       else
2126         {
2127             /* Unsigned.  */
2128             a = wRHALF (BITS (16, 19), i);
2129             b = wRHALF (BITS ( 0,  3), i);
2130 
2131             t += a * b;
2132         }
2133     }
2134 
2135   if (BIT (21))
2136     t = EXTEND32 (t);
2137   else
2138     t &= 0xffffffff;
2139 
2140   if (BIT (20))
2141     wR [BITS (12, 15)] = t;
2142   else
2143     wR[BITS (12, 15)] += t;
2144 
2145   wC [wCon] |= WCON_MUP;
2146 
2147   return ARMul_DONE;
2148 }
2149 
2150 static int
WMADD(ARMword instr)2151 WMADD (ARMword instr)
2152 {
2153   ARMdword r = 0;
2154   int i;
2155 
2156   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2157     return ARMul_CANT;
2158 
2159 #ifdef DEBUG
2160   fprintf (stderr, "wmadd\n");
2161 #endif
2162 
2163   for (i = 0; i < 2; i++)
2164     {
2165       ARMdword s1, s2;
2166 
2167       if (BIT (21)) /* Signed.  */
2168         {
2169             signed long a, b;
2170 
2171             a = wRHALF (BITS (16, 19), i * 2);
2172             a = EXTEND16 (a);
2173 
2174             b = wRHALF (BITS (0, 3), i * 2);
2175             b = EXTEND16 (b);
2176 
2177             s1 = (ARMdword) (a * b);
2178 
2179             a = wRHALF (BITS (16, 19), i * 2 + 1);
2180             a = EXTEND16 (a);
2181 
2182             b = wRHALF (BITS (0, 3), i * 2 + 1);
2183             b = EXTEND16 (b);
2184 
2185             s2 = (ARMdword) (a * b);
2186         }
2187       else                              /* Unsigned.  */
2188         {
2189             unsigned long a, b;
2190 
2191             a = wRHALF (BITS (16, 19), i * 2);
2192             b = wRHALF (BITS ( 0,  3), i * 2);
2193 
2194             s1 = (ARMdword) (a * b);
2195 
2196             a = wRHALF (BITS (16, 19), i * 2 + 1);
2197             b = wRHALF (BITS ( 0,  3), i * 2 + 1);
2198 
2199             s2 = (ARMdword) a * b;
2200         }
2201 
2202       r |= (ARMdword) ((s1 + s2) & 0xffffffff) << (i ? 32 : 0);
2203     }
2204 
2205   wR [BITS (12, 15)] = r;
2206   wC [wCon] |= WCON_MUP;
2207 
2208   return ARMul_DONE;
2209 }
2210 
2211 static int
WMAX(ARMul_State * state,ARMword instr)2212 WMAX (ARMul_State * state, ARMword instr)
2213 {
2214   ARMdword r = 0;
2215   ARMdword s;
2216   int      i;
2217 
2218   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2219     return ARMul_CANT;
2220 
2221 #ifdef DEBUG
2222   fprintf (stderr, "wmax\n");
2223 #endif
2224 
2225   switch (BITS (22, 23))
2226     {
2227     case Bqual:
2228       for (i = 0; i < 8; i++)
2229           if (BIT (21))       /* Signed.  */
2230             {
2231               int a, b;
2232 
2233               a = wRBYTE (BITS (16, 19), i);
2234               a = EXTEND8 (a);
2235 
2236               b = wRBYTE (BITS (0, 3), i);
2237               b = EXTEND8 (b);
2238 
2239               if (a > b)
2240                 s = a;
2241               else
2242                 s = b;
2243 
2244               r |= (s & 0xff) << (i * 8);
2245             }
2246           else                /* Unsigned.  */
2247             {
2248               unsigned int a, b;
2249 
2250               a = wRBYTE (BITS (16, 19), i);
2251               b = wRBYTE (BITS (0, 3), i);
2252 
2253               if (a > b)
2254                 s = a;
2255               else
2256                 s = b;
2257 
2258               r |= (s & 0xff) << (i * 8);
2259           }
2260       break;
2261 
2262     case Hqual:
2263       for (i = 0; i < 4; i++)
2264           if (BIT (21))       /* Signed.  */
2265             {
2266               int a, b;
2267 
2268               a = wRHALF (BITS (16, 19), i);
2269               a = EXTEND16 (a);
2270 
2271               b = wRHALF (BITS (0, 3), i);
2272               b = EXTEND16 (b);
2273 
2274               if (a > b)
2275                 s = a;
2276               else
2277                 s = b;
2278 
2279               r |= (s & 0xffff) << (i * 16);
2280             }
2281           else                /* Unsigned.  */
2282             {
2283               unsigned int a, b;
2284 
2285               a = wRHALF (BITS (16, 19), i);
2286               b = wRHALF (BITS (0, 3), i);
2287 
2288               if (a > b)
2289                 s = a;
2290               else
2291                 s = b;
2292 
2293               r |= (s & 0xffff) << (i * 16);
2294           }
2295       break;
2296 
2297     case Wqual:
2298       for (i = 0; i < 2; i++)
2299           if (BIT (21))       /* Signed.  */
2300             {
2301               int a, b;
2302 
2303               a = wRWORD (BITS (16, 19), i);
2304               b = wRWORD (BITS (0, 3), i);
2305 
2306               if (a > b)
2307                 s = a;
2308               else
2309                 s = b;
2310 
2311               r |= (s & 0xffffffff) << (i * 32);
2312             }
2313           else
2314             {
2315               unsigned int a, b;
2316 
2317               a = wRWORD (BITS (16, 19), i);
2318               b = wRWORD (BITS (0, 3), i);
2319 
2320               if (a > b)
2321                 s = a;
2322               else
2323                 s = b;
2324 
2325               r |= (s & 0xffffffff) << (i * 32);
2326           }
2327       break;
2328 
2329     default:
2330       ARMul_UndefInstr (state, instr);
2331       return ARMul_DONE;
2332     }
2333 
2334   wR [BITS (12, 15)] = r;
2335   wC [wCon] |= WCON_MUP;
2336 
2337   return ARMul_DONE;
2338 }
2339 
2340 static int
WMIN(ARMul_State * state,ARMword instr)2341 WMIN (ARMul_State * state, ARMword instr)
2342 {
2343   ARMdword r = 0;
2344   ARMdword s;
2345   int      i;
2346 
2347   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2348     return ARMul_CANT;
2349 
2350 #ifdef DEBUG
2351   fprintf (stderr, "wmin\n");
2352 #endif
2353 
2354   switch (BITS (22, 23))
2355     {
2356     case Bqual:
2357       for (i = 0; i < 8; i++)
2358           if (BIT (21))       /* Signed.  */
2359             {
2360               int a, b;
2361 
2362               a = wRBYTE (BITS (16, 19), i);
2363               a = EXTEND8 (a);
2364 
2365               b = wRBYTE (BITS (0, 3), i);
2366               b = EXTEND8 (b);
2367 
2368               if (a < b)
2369                 s = a;
2370               else
2371                 s = b;
2372 
2373               r |= (s & 0xff) << (i * 8);
2374             }
2375           else                /* Unsigned.  */
2376             {
2377               unsigned int a, b;
2378 
2379               a = wRBYTE (BITS (16, 19), i);
2380               b = wRBYTE (BITS (0, 3), i);
2381 
2382               if (a < b)
2383                 s = a;
2384               else
2385                 s = b;
2386 
2387               r |= (s & 0xff) << (i * 8);
2388           }
2389       break;
2390 
2391     case Hqual:
2392       for (i = 0; i < 4; i++)
2393           if (BIT (21))       /* Signed.  */
2394             {
2395               int a, b;
2396 
2397               a = wRHALF (BITS (16, 19), i);
2398               a = EXTEND16 (a);
2399 
2400               b = wRHALF (BITS (0, 3), i);
2401               b = EXTEND16 (b);
2402 
2403               if (a < b)
2404                 s = a;
2405               else
2406                 s = b;
2407 
2408               r |= (s & 0xffff) << (i * 16);
2409             }
2410           else
2411             {
2412               /* Unsigned.  */
2413               unsigned int a, b;
2414 
2415               a = wRHALF (BITS (16, 19), i);
2416               b = wRHALF (BITS ( 0,  3), i);
2417 
2418               if (a < b)
2419                 s = a;
2420               else
2421                 s = b;
2422 
2423               r |= (s & 0xffff) << (i * 16);
2424           }
2425       break;
2426 
2427     case Wqual:
2428       for (i = 0; i < 2; i++)
2429           if (BIT (21))       /* Signed.  */
2430             {
2431               int a, b;
2432 
2433               a = wRWORD (BITS (16, 19), i);
2434               b = wRWORD (BITS ( 0,  3), i);
2435 
2436               if (a < b)
2437                 s = a;
2438               else
2439                 s = b;
2440 
2441               r |= (s & 0xffffffff) << (i * 32);
2442             }
2443           else
2444             {
2445               unsigned int a, b;
2446 
2447               a = wRWORD (BITS (16, 19), i);
2448               b = wRWORD (BITS (0, 3), i);
2449 
2450               if (a < b)
2451                 s = a;
2452               else
2453                 s = b;
2454 
2455               r |= (s & 0xffffffff) << (i * 32);
2456           }
2457       break;
2458 
2459     default:
2460       ARMul_UndefInstr (state, instr);
2461       return ARMul_DONE;
2462     }
2463 
2464   wR [BITS (12, 15)] = r;
2465   wC [wCon] |= WCON_MUP;
2466 
2467   return ARMul_DONE;
2468 }
2469 
2470 static int
WMUL(ARMword instr)2471 WMUL (ARMword instr)
2472 {
2473   ARMdword r = 0;
2474   ARMdword s;
2475   int      i;
2476 
2477   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2478     return ARMul_CANT;
2479 
2480 #ifdef DEBUG
2481   fprintf (stderr, "wmul\n");
2482 #endif
2483 
2484   for (i = 0; i < 4; i++)
2485     if (BIT (21))   /* Signed.  */
2486       {
2487           long a, b;
2488 
2489           a = wRHALF (BITS (16, 19), i);
2490           a = EXTEND16 (a);
2491 
2492           b = wRHALF (BITS (0, 3), i);
2493           b = EXTEND16 (b);
2494 
2495           s = a * b;
2496 
2497           if (BIT (20))
2498             r |= ((s >> 16) & 0xffff) << (i * 16);
2499           else
2500             r |= (s & 0xffff) << (i * 16);
2501       }
2502     else            /* Unsigned.  */
2503       {
2504           unsigned long a, b;
2505 
2506           a = wRHALF (BITS (16, 19), i);
2507           b = wRHALF (BITS (0, 3), i);
2508 
2509           s = a * b;
2510 
2511           if (BIT (20))
2512             r |= ((s >> 16) & 0xffff) << (i * 16);
2513           else
2514             r |= (s & 0xffff) << (i * 16);
2515       }
2516 
2517   wR [BITS (12, 15)] = r;
2518   wC [wCon] |= WCON_MUP;
2519 
2520   return ARMul_DONE;
2521 }
2522 
2523 static int
WOR(ARMword instr)2524 WOR (ARMword instr)
2525 {
2526   ARMword psr = 0;
2527   ARMdword result;
2528 
2529   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2530     return ARMul_CANT;
2531 
2532 #ifdef DEBUG
2533   fprintf (stderr, "wor\n");
2534 #endif
2535 
2536   result = wR [BITS (16, 19)] | wR [BITS (0, 3)];
2537   wR [BITS (12, 15)] = result;
2538 
2539   SIMD64_SET (psr, (result == 0), SIMD_ZBIT);
2540   SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT);
2541 
2542   wC [wCASF] = psr;
2543   wC [wCon] |= (WCON_CUP | WCON_MUP);
2544 
2545   return ARMul_DONE;
2546 }
2547 
2548 static int
WPACK(ARMul_State * state,ARMword instr)2549 WPACK (ARMul_State * state, ARMword instr)
2550 {
2551   ARMdword r = 0;
2552   ARMword  psr = 0;
2553   ARMdword x;
2554   ARMdword s;
2555   int      i;
2556   int      satrv[8];
2557 
2558   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2559     return ARMul_CANT;
2560 
2561 #ifdef DEBUG
2562   fprintf (stderr, "wpack\n");
2563 #endif
2564 
2565   switch (BITS (22, 23))
2566     {
2567     case Hqual:
2568       for (i = 0; i < 8; i++)
2569           {
2570             x = wRHALF (i < 4 ? BITS (16, 19) : BITS (0, 3), i & 3);
2571 
2572             switch (BITS (20, 21))
2573               {
2574               case UnsignedSaturation:
2575                 s = IwmmxtSaturateU8 (x, satrv + BITIDX8 (i));
2576                 break;
2577 
2578               case SignedSaturation:
2579                 s = IwmmxtSaturateS8 (x, satrv + BITIDX8 (i));
2580                 break;
2581 
2582               default:
2583                 ARMul_UndefInstr (state, instr);
2584                 return ARMul_DONE;
2585               }
2586 
2587             r |= (s & 0xff) << (i * 8);
2588             SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i);
2589             SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
2590           }
2591       break;
2592 
2593     case Wqual:
2594       satrv[0] = satrv[2] = satrv[4] = satrv[6] = 0;
2595 
2596       for (i = 0; i < 4; i++)
2597           {
2598             x = wRWORD (i < 2 ? BITS (16, 19) : BITS (0, 3), i & 1);
2599 
2600             switch (BITS (20, 21))
2601               {
2602               case UnsignedSaturation:
2603                 s = IwmmxtSaturateU16 (x, satrv + BITIDX16 (i));
2604                 break;
2605 
2606               case SignedSaturation:
2607                 s = IwmmxtSaturateS16 (x, satrv + BITIDX16 (i));
2608                 break;
2609 
2610               default:
2611                 ARMul_UndefInstr (state, instr);
2612                 return ARMul_DONE;
2613               }
2614 
2615             r |= (s & 0xffff) << (i * 16);
2616             SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2617             SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2618           }
2619       break;
2620 
2621     case Dqual:
2622       satrv[0] = satrv[1] = satrv[2] = satrv[4] = satrv[5] = satrv[6] = 0;
2623 
2624       for (i = 0; i < 2; i++)
2625           {
2626             x = wR [i ? BITS (0, 3) : BITS (16, 19)];
2627 
2628             switch (BITS (20, 21))
2629               {
2630               case UnsignedSaturation:
2631                 s = IwmmxtSaturateU32 (x, satrv + BITIDX32 (i));
2632                 break;
2633 
2634               case SignedSaturation:
2635                 s = IwmmxtSaturateS32 (x, satrv + BITIDX32 (i));
2636                 break;
2637 
2638               default:
2639                 ARMul_UndefInstr (state, instr);
2640                 return ARMul_DONE;
2641               }
2642 
2643             r |= (s & 0xffffffff) << (i * 32);
2644             SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
2645             SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
2646           }
2647       break;
2648 
2649     default:
2650       ARMul_UndefInstr (state, instr);
2651       return ARMul_DONE;
2652     }
2653 
2654   wC [wCASF] = psr;
2655   wR [BITS (12, 15)] = r;
2656   SET_wCSSFvec (satrv);
2657   wC [wCon] |= (WCON_CUP | WCON_MUP);
2658 
2659   return ARMul_DONE;
2660 }
2661 
2662 static int
WROR(ARMul_State * state,ARMword instr)2663 WROR (ARMul_State * state, ARMword instr)
2664 {
2665   ARMdword r = 0;
2666   ARMdword s;
2667   ARMword  psr = 0;
2668   int      i;
2669   int      shift;
2670 
2671   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2672     return ARMul_CANT;
2673 
2674 #ifdef DEBUG
2675   fprintf (stderr, "wror\n");
2676 #endif
2677 
2678   DECODE_G_BIT (state, instr, shift);
2679 
2680   switch (BITS (22, 23))
2681     {
2682     case Hqual:
2683       shift &= 0xf;
2684       for (i = 0; i < 4; i++)
2685           {
2686             s = ((wRHALF (BITS (16, 19), i) & 0xffff) << (16 - shift))
2687               | ((wRHALF (BITS (16, 19), i) & 0xffff) >> shift);
2688             r |= (s & 0xffff) << (i * 16);
2689             SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2690             SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2691           }
2692       break;
2693 
2694     case Wqual:
2695       shift &= 0x1f;
2696       for (i = 0; i < 2; i++)
2697           {
2698             s = ((wRWORD (BITS (16, 19), i) & 0xffffffff) << (32 - shift))
2699               | ((wRWORD (BITS (16, 19), i) & 0xffffffff) >> shift);
2700             r |= (s & 0xffffffff) << (i * 32);
2701             SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
2702             SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
2703           }
2704       break;
2705 
2706     case Dqual:
2707       shift &= 0x3f;
2708       r = (wR [BITS (16, 19)] >> shift)
2709           | (wR [BITS (16, 19)] << (64 - shift));
2710 
2711       SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
2712       SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
2713       break;
2714 
2715     default:
2716       ARMul_UndefInstr (state, instr);
2717       return ARMul_DONE;
2718     }
2719 
2720   wC [wCASF] = psr;
2721   wR [BITS (12, 15)] = r;
2722   wC [wCon] |= (WCON_CUP | WCON_MUP);
2723 
2724   return ARMul_DONE;
2725 }
2726 
2727 static int
WSAD(ARMword instr)2728 WSAD (ARMword instr)
2729 {
2730   ARMdword r;
2731   int      s;
2732   int      i;
2733 
2734   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2735     return ARMul_CANT;
2736 
2737 #ifdef DEBUG
2738   fprintf (stderr, "wsad\n");
2739 #endif
2740 
2741   /* Z bit.  */
2742   r = BIT (20) ? 0 : (wR [BITS (12, 15)] & 0xffffffff);
2743 
2744   if (BIT (22))
2745     /* Half.  */
2746     for (i = 0; i < 4; i++)
2747       {
2748           s = (wRHALF (BITS (16, 19), i) - wRHALF (BITS (0, 3), i));
2749           r += abs (s);
2750       }
2751   else
2752     /* Byte.  */
2753     for (i = 0; i < 8; i++)
2754       {
2755           s = (wRBYTE (BITS (16, 19), i) - wRBYTE (BITS (0, 3), i));
2756           r += abs (s);
2757       }
2758 
2759   wR [BITS (12, 15)] = r;
2760   wC [wCon] |= WCON_MUP;
2761 
2762   return ARMul_DONE;
2763 }
2764 
2765 static int
WSHUFH(ARMword instr)2766 WSHUFH (ARMword instr)
2767 {
2768   ARMdword r = 0;
2769   ARMword  psr = 0;
2770   ARMdword s;
2771   int      i;
2772   int      imm8;
2773 
2774   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2775     return ARMul_CANT;
2776 
2777 #ifdef DEBUG
2778   fprintf (stderr, "wshufh\n");
2779 #endif
2780 
2781   imm8 = (BITS (20, 23) << 4) | BITS (0, 3);
2782 
2783   for (i = 0; i < 4; i++)
2784     {
2785       s = wRHALF (BITS (16, 19), ((imm8 >> (i * 2) & 3)) & 0xff);
2786       r |= (s & 0xffff) << (i * 16);
2787       SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2788       SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2789     }
2790 
2791   wC [wCASF] = psr;
2792   wR [BITS (12, 15)] = r;
2793   wC [wCon] |= (WCON_CUP | WCON_MUP);
2794 
2795   return ARMul_DONE;
2796 }
2797 
2798 static int
WSLL(ARMul_State * state,ARMword instr)2799 WSLL (ARMul_State * state, ARMword instr)
2800 {
2801   ARMdword r = 0;
2802   ARMdword s;
2803   ARMword  psr = 0;
2804   int      i;
2805   unsigned shift;
2806 
2807   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2808     return ARMul_CANT;
2809 
2810 #ifdef DEBUG
2811   fprintf (stderr, "wsll\n");
2812 #endif
2813 
2814   DECODE_G_BIT (state, instr, shift);
2815 
2816   switch (BITS (22, 23))
2817     {
2818     case Hqual:
2819       for (i = 0; i < 4; i++)
2820           {
2821             if (shift > 15)
2822               s = 0;
2823             else
2824               s = ((wRHALF (BITS (16, 19), i) & 0xffff) << shift);
2825             r |= (s & 0xffff) << (i * 16);
2826             SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2827             SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2828           }
2829       break;
2830 
2831     case Wqual:
2832       for (i = 0; i < 2; i++)
2833           {
2834             if (shift > 31)
2835               s = 0;
2836             else
2837               s = ((wRWORD (BITS (16, 19), i) & 0xffffffff) << shift);
2838             r |= (s & 0xffffffff) << (i * 32);
2839             SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
2840             SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
2841           }
2842       break;
2843 
2844     case Dqual:
2845       if (shift > 63)
2846           r = 0;
2847       else
2848           r = ((wR[BITS (16, 19)] & 0xffffffffffffffffULL) << shift);
2849 
2850       SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
2851       SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
2852       break;
2853 
2854     default:
2855       ARMul_UndefInstr (state, instr);
2856       return ARMul_DONE;
2857     }
2858 
2859   wC [wCASF] = psr;
2860   wR [BITS (12, 15)] = r;
2861   wC [wCon] |= (WCON_CUP | WCON_MUP);
2862 
2863   return ARMul_DONE;
2864 }
2865 
2866 static int
WSRA(ARMul_State * state,ARMword instr)2867 WSRA (ARMul_State * state, ARMword instr)
2868 {
2869   ARMdword     r = 0;
2870   ARMdword     s;
2871   ARMword      psr = 0;
2872   int          i;
2873   unsigned     shift;
2874   signed long  t;
2875 
2876   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2877     return ARMul_CANT;
2878 
2879 #ifdef DEBUG
2880   fprintf (stderr, "wsra\n");
2881 #endif
2882 
2883   DECODE_G_BIT (state, instr, shift);
2884 
2885   switch (BITS (22, 23))
2886     {
2887     case Hqual:
2888       for (i = 0; i < 4; i++)
2889           {
2890             if (shift > 15)
2891               t = (wRHALF (BITS (16, 19), i) & 0x8000) ? 0xffff : 0;
2892             else
2893               {
2894                 t = wRHALF (BITS (16, 19), i);
2895                 t = EXTEND16 (t);
2896                 t >>= shift;
2897               }
2898 
2899             s = t;
2900             r |= (s & 0xffff) << (i * 16);
2901             SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2902             SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2903           }
2904       break;
2905 
2906     case Wqual:
2907       for (i = 0; i < 2; i++)
2908           {
2909             if (shift > 31)
2910               t = (wRWORD (BITS (16, 19), i) & 0x80000000) ? 0xffffffff : 0;
2911             else
2912               {
2913                 t = EXTEND32 (wRWORD (BITS (16, 19), i));
2914                 t >>= shift;
2915               }
2916             s = t;
2917             r |= (s & 0xffffffff) << (i * 32);
2918             SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
2919             SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
2920           }
2921       break;
2922 
2923     case Dqual:
2924       if (shift > 63)
2925           r = (wR [BITS (16, 19)] & 0x8000000000000000ULL) ? 0xffffffffffffffffULL : 0;
2926       else
2927           r = ((signed long long) (wR[BITS (16, 19)] & 0xffffffffffffffffULL) >> shift);
2928       SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
2929       SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
2930       break;
2931 
2932     default:
2933       ARMul_UndefInstr (state, instr);
2934       return ARMul_DONE;
2935     }
2936 
2937   wC [wCASF] = psr;
2938   wR [BITS (12, 15)] = r;
2939   wC [wCon] |= (WCON_CUP | WCON_MUP);
2940 
2941   return ARMul_DONE;
2942 }
2943 
2944 static int
WSRL(ARMul_State * state,ARMword instr)2945 WSRL (ARMul_State * state, ARMword instr)
2946 {
2947   ARMdword     r = 0;
2948   ARMdword     s;
2949   ARMword      psr = 0;
2950   int          i;
2951   unsigned int shift;
2952 
2953   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2954     return ARMul_CANT;
2955 
2956 #ifdef DEBUG
2957   fprintf (stderr, "wsrl\n");
2958 #endif
2959 
2960   DECODE_G_BIT (state, instr, shift);
2961 
2962   switch (BITS (22, 23))
2963     {
2964     case Hqual:
2965       for (i = 0; i < 4; i++)
2966           {
2967             if (shift > 15)
2968               s = 0;
2969             else
2970               s = ((unsigned) (wRHALF (BITS (16, 19), i) & 0xffff) >> shift);
2971 
2972             r |= (s & 0xffff) << (i * 16);
2973             SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2974             SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2975           }
2976       break;
2977 
2978     case Wqual:
2979       for (i = 0; i < 2; i++)
2980           {
2981             if (shift > 31)
2982               s = 0;
2983             else
2984               s = ((unsigned long) (wRWORD (BITS (16, 19), i) & 0xffffffff) >> shift);
2985 
2986             r |= (s & 0xffffffff) << (i * 32);
2987             SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
2988             SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
2989           }
2990       break;
2991 
2992     case Dqual:
2993       if (shift > 63)
2994           r = 0;
2995       else
2996           r = (wR [BITS (16, 19)] & 0xffffffffffffffffULL) >> shift;
2997 
2998       SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
2999       SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
3000       break;
3001 
3002     default:
3003       ARMul_UndefInstr (state, instr);
3004       return ARMul_DONE;
3005     }
3006 
3007   wC [wCASF] = psr;
3008   wR [BITS (12, 15)] = r;
3009   wC [wCon] |= (WCON_CUP | WCON_MUP);
3010 
3011   return ARMul_DONE;
3012 }
3013 
3014 static int
WSTR(ARMul_State * state,ARMword instr)3015 WSTR (ARMul_State * state, ARMword instr)
3016 {
3017   ARMword address;
3018   int failed;
3019 
3020 
3021   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3022     return ARMul_CANT;
3023 
3024 #ifdef DEBUG
3025   fprintf (stderr, "wstr\n");
3026 #endif
3027 
3028   address = Compute_Iwmmxt_Address (state, instr, & failed);
3029   if (failed)
3030     return ARMul_CANT;
3031 
3032   if (BITS (28, 31) == 0xf)
3033     {
3034       /* WSTRW wCx */
3035       Iwmmxt_Store_Word (state, address, wC [BITS (12, 15)]);
3036     }
3037   else if (BIT (8) == 0)
3038     {
3039       if (BIT (22) == 0)
3040           /* WSTRB */
3041           Iwmmxt_Store_Byte (state, address, wR [BITS (12, 15)]);
3042       else
3043           /* WSTRH */
3044           Iwmmxt_Store_Half_Word (state, address, wR [BITS (12, 15)]);
3045     }
3046   else
3047     {
3048       if (BIT (22) == 0)
3049           /* WSTRW wRd */
3050           Iwmmxt_Store_Word (state, address, wR [BITS (12, 15)]);
3051       else
3052           /* WSTRD */
3053           Iwmmxt_Store_Double_Word (state, address, wR [BITS (12, 15)]);
3054     }
3055 
3056   return ARMul_DONE;
3057 }
3058 
3059 static int
WSUB(ARMul_State * state,ARMword instr)3060 WSUB (ARMul_State * state, ARMword instr)
3061 {
3062   ARMdword r = 0;
3063   ARMword  psr = 0;
3064   ARMdword x;
3065   ARMdword s;
3066   int      i;
3067   int      carry;
3068   int      overflow;
3069   int      satrv[8];
3070 
3071   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3072     return ARMul_CANT;
3073 
3074 #ifdef DEBUG
3075   fprintf (stderr, "wsub\n");
3076 #endif
3077 
3078 /* Subtract two numbers using the specified function,
3079    leaving setting the carry bit as required.  */
3080 #define SUBx(x, y, m, f) \
3081    (*f) (wRBITS (BITS (16, 19), (x), (y)) & (m), \
3082          wRBITS (BITS ( 0,  3), (x), (y)) & (m), & carry, & overflow)
3083 
3084   switch (BITS (22, 23))
3085     {
3086     case Bqual:
3087       for (i = 0; i < 8; i++)
3088         {
3089             switch (BITS (20, 21))
3090               {
3091               case NoSaturation:
3092                 s = SUBx ((i * 8), (i * 8) + 7, 0xff, SubS8);
3093                 satrv [BITIDX8 (i)] = 0;
3094                 r |= (s & 0xff) << (i * 8);
3095                 SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i);
3096                 SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
3097                 SIMD8_SET (psr, carry, SIMD_CBIT, i);
3098                 SIMD8_SET (psr, overflow, SIMD_VBIT, i);
3099                 break;
3100 
3101               case UnsignedSaturation:
3102                 s = SUBx ((i * 8), (i * 8) + 7, 0xff, SubU8);
3103                 x = IwmmxtSaturateU8 (s, satrv + BITIDX8 (i));
3104                 r |= (x & 0xff) << (i * 8);
3105                 SIMD8_SET (psr, NBIT8 (x), SIMD_NBIT, i);
3106                 SIMD8_SET (psr, ZBIT8 (x), SIMD_ZBIT, i);
3107                 if (! satrv [BITIDX8 (i)])
3108                     {
3109                       SIMD8_SET (psr, carry,     SIMD_CBIT, i);
3110                       SIMD8_SET (psr, overflow, SIMD_VBIT, i);
3111                     }
3112                 break;
3113 
3114               case SignedSaturation:
3115                 s = SUBx ((i * 8), (i * 8) + 7, 0xff, SubS8);
3116                 x = IwmmxtSaturateS8 (s, satrv + BITIDX8 (i));
3117                 r |= (x & 0xff) << (i * 8);
3118                 SIMD8_SET (psr, NBIT8 (x), SIMD_NBIT, i);
3119                 SIMD8_SET (psr, ZBIT8 (x), SIMD_ZBIT, i);
3120                 if (! satrv [BITIDX8 (i)])
3121                     {
3122                       SIMD8_SET (psr, carry,     SIMD_CBIT, i);
3123                       SIMD8_SET (psr, overflow, SIMD_VBIT, i);
3124                     }
3125                 break;
3126 
3127               default:
3128                 ARMul_UndefInstr (state, instr);
3129                 return ARMul_DONE;
3130               }
3131           }
3132       break;
3133 
3134     case Hqual:
3135       satrv[0] = satrv[2] = satrv[4] = satrv[6] = 0;
3136 
3137       for (i = 0; i < 4; i++)
3138           {
3139             switch (BITS (20, 21))
3140               {
3141               case NoSaturation:
3142                 s = SUBx ((i * 16), (i * 16) + 15, 0xffff, SubU16);
3143                 satrv [BITIDX16 (i)] = 0;
3144                 r |= (s & 0xffff) << (i * 16);
3145                 SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
3146                 SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
3147                 SIMD16_SET (psr, carry,      SIMD_CBIT, i);
3148                 SIMD16_SET (psr, overflow,   SIMD_VBIT, i);
3149                 break;
3150 
3151               case UnsignedSaturation:
3152                 s = SUBx ((i * 16), (i * 16) + 15, 0xffff, SubU16);
3153                 x = IwmmxtSaturateU16 (s, satrv + BITIDX16 (i));
3154                 r |= (x & 0xffff) << (i * 16);
3155                 SIMD16_SET (psr, NBIT16 (x & 0xffff), SIMD_NBIT, i);
3156                 SIMD16_SET (psr, ZBIT16 (x), SIMD_ZBIT, i);
3157                 if (! satrv [BITIDX16 (i)])
3158                     {
3159                       SIMD16_SET (psr, carry,    SIMD_CBIT, i);
3160                       SIMD16_SET (psr, overflow, SIMD_VBIT, i);
3161                     }
3162                 break;
3163 
3164               case SignedSaturation:
3165                 s = SUBx ((i * 16), (i * 16) + 15, 0xffff, SubS16);
3166                 x = IwmmxtSaturateS16 (s, satrv + BITIDX16 (i));
3167                 r |= (x & 0xffff) << (i * 16);
3168                 SIMD16_SET (psr, NBIT16 (x), SIMD_NBIT, i);
3169                 SIMD16_SET (psr, ZBIT16 (x), SIMD_ZBIT, i);
3170                 if (! satrv [BITIDX16 (i)])
3171                     {
3172                       SIMD16_SET (psr, carry,    SIMD_CBIT, i);
3173                       SIMD16_SET (psr, overflow, SIMD_VBIT, i);
3174                     }
3175                 break;
3176 
3177               default:
3178                 ARMul_UndefInstr (state, instr);
3179                 return ARMul_DONE;
3180               }
3181           }
3182       break;
3183 
3184     case Wqual:
3185       satrv[0] = satrv[1] = satrv[2] = satrv[4] = satrv[5] = satrv[6] = 0;
3186 
3187       for (i = 0; i < 2; i++)
3188           {
3189             switch (BITS (20, 21))
3190               {
3191               case NoSaturation:
3192                 s = SUBx ((i * 32), (i * 32) + 31, 0xffffffff, SubU32);
3193                 satrv[BITIDX32 (i)] = 0;
3194                 r |= (s & 0xffffffff) << (i * 32);
3195                 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
3196                 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
3197                 SIMD32_SET (psr, carry,      SIMD_CBIT, i);
3198                 SIMD32_SET (psr, overflow,   SIMD_VBIT, i);
3199                 break;
3200 
3201               case UnsignedSaturation:
3202                 s = SUBx ((i * 32), (i * 32) + 31, 0xffffffff, SubU32);
3203                 x = IwmmxtSaturateU32 (s, satrv + BITIDX32 (i));
3204                 r |= (x & 0xffffffff) << (i * 32);
3205                 SIMD32_SET (psr, NBIT32 (x), SIMD_NBIT, i);
3206                 SIMD32_SET (psr, ZBIT32 (x), SIMD_ZBIT, i);
3207                 if (! satrv [BITIDX32 (i)])
3208                     {
3209                       SIMD32_SET (psr, carry,    SIMD_CBIT, i);
3210                       SIMD32_SET (psr, overflow, SIMD_VBIT, i);
3211                     }
3212                 break;
3213 
3214               case SignedSaturation:
3215                 s = SUBx ((i * 32), (i * 32) + 31, 0xffffffff, SubS32);
3216                 x = IwmmxtSaturateS32 (s, satrv + BITIDX32 (i));
3217                 r |= (x & 0xffffffff) << (i * 32);
3218                 SIMD32_SET (psr, NBIT32 (x), SIMD_NBIT, i);
3219                 SIMD32_SET (psr, ZBIT32 (x), SIMD_ZBIT, i);
3220                 if (! satrv [BITIDX32 (i)])
3221                     {
3222                       SIMD32_SET (psr, carry,    SIMD_CBIT, i);
3223                       SIMD32_SET (psr, overflow, SIMD_VBIT, i);
3224                     }
3225                 break;
3226 
3227               default:
3228                 ARMul_UndefInstr (state, instr);
3229                 return ARMul_DONE;
3230               }
3231           }
3232       break;
3233 
3234     default:
3235       ARMul_UndefInstr (state, instr);
3236       return ARMul_DONE;
3237     }
3238 
3239   wR [BITS (12, 15)] = r;
3240   wC [wCASF] = psr;
3241   SET_wCSSFvec (satrv);
3242   wC [wCon] |= (WCON_CUP | WCON_MUP);
3243 
3244 #undef SUBx
3245 
3246   return ARMul_DONE;
3247 }
3248 
3249 static int
WUNPCKEH(ARMul_State * state,ARMword instr)3250 WUNPCKEH (ARMul_State * state, ARMword instr)
3251 {
3252   ARMdword r = 0;
3253   ARMword  psr = 0;
3254   ARMdword s;
3255   int      i;
3256 
3257   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3258     return ARMul_CANT;
3259 
3260 #ifdef DEBUG
3261   fprintf (stderr, "wunpckeh\n");
3262 #endif
3263 
3264   switch (BITS (22, 23))
3265     {
3266     case Bqual:
3267       for (i = 0; i < 4; i++)
3268           {
3269             s = wRBYTE (BITS (16, 19), i + 4);
3270 
3271             if (BIT (21) && NBIT8 (s))
3272               s |= 0xff00;
3273 
3274             r |= (s & 0xffff) << (i * 16);
3275             SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
3276             SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
3277           }
3278       break;
3279 
3280     case Hqual:
3281       for (i = 0; i < 2; i++)
3282           {
3283             s = wRHALF (BITS (16, 19), i + 2);
3284 
3285             if (BIT (21) && NBIT16 (s))
3286               s |= 0xffff0000;
3287 
3288             r |= (s & 0xffffffff) << (i * 32);
3289             SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
3290             SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
3291           }
3292       break;
3293 
3294     case Wqual:
3295       r = wRWORD (BITS (16, 19), 1);
3296 
3297       if (BIT (21) && NBIT32 (r))
3298           r |= 0xffffffff00000000ULL;
3299 
3300       SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
3301       SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
3302       break;
3303 
3304     default:
3305       ARMul_UndefInstr (state, instr);
3306       return ARMul_DONE;
3307     }
3308 
3309   wC [wCASF] = psr;
3310   wR [BITS (12, 15)] = r;
3311   wC [wCon] |= (WCON_CUP | WCON_MUP);
3312 
3313   return ARMul_DONE;
3314 }
3315 
3316 static int
WUNPCKEL(ARMul_State * state,ARMword instr)3317 WUNPCKEL (ARMul_State * state, ARMword instr)
3318 {
3319   ARMdword r = 0;
3320   ARMword  psr = 0;
3321   ARMdword s;
3322   int      i;
3323 
3324   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3325     return ARMul_CANT;
3326 
3327 #ifdef DEBUG
3328   fprintf (stderr, "wunpckel\n");
3329 #endif
3330 
3331   switch (BITS (22, 23))
3332     {
3333     case Bqual:
3334       for (i = 0; i < 4; i++)
3335           {
3336             s = wRBYTE (BITS (16, 19), i);
3337 
3338             if (BIT (21) && NBIT8 (s))
3339               s |= 0xff00;
3340 
3341             r |= (s & 0xffff) << (i * 16);
3342             SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
3343             SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
3344           }
3345       break;
3346 
3347     case Hqual:
3348       for (i = 0; i < 2; i++)
3349           {
3350             s = wRHALF (BITS (16, 19), i);
3351 
3352             if (BIT (21) && NBIT16 (s))
3353               s |= 0xffff0000;
3354 
3355             r |= (s & 0xffffffff) << (i * 32);
3356             SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
3357             SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
3358           }
3359       break;
3360 
3361     case Wqual:
3362       r = wRWORD (BITS (16, 19), 0);
3363 
3364       if (BIT (21) && NBIT32 (r))
3365           r |= 0xffffffff00000000ULL;
3366 
3367       SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
3368       SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
3369       break;
3370 
3371     default:
3372       ARMul_UndefInstr (state, instr);
3373       return ARMul_DONE;
3374     }
3375 
3376   wC [wCASF] = psr;
3377   wR [BITS (12, 15)] = r;
3378   wC [wCon] |= (WCON_CUP | WCON_MUP);
3379 
3380   return ARMul_DONE;
3381 }
3382 
3383 static int
WUNPCKIH(ARMul_State * state,ARMword instr)3384 WUNPCKIH (ARMul_State * state, ARMword instr)
3385 {
3386   ARMword  a, b;
3387   ARMdword r = 0;
3388   ARMword  psr = 0;
3389   ARMdword s;
3390   int      i;
3391 
3392   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3393     return ARMul_CANT;
3394 
3395 #ifdef DEBUG
3396   fprintf (stderr, "wunpckih\n");
3397 #endif
3398 
3399   switch (BITS (22, 23))
3400     {
3401     case Bqual:
3402       for (i = 0; i < 4; i++)
3403           {
3404             a = wRBYTE (BITS (16, 19), i + 4);
3405             b = wRBYTE (BITS ( 0,  3), i + 4);
3406             s = a | (b << 8);
3407             r |= (s & 0xffff) << (i * 16);
3408             SIMD8_SET (psr, NBIT8 (a), SIMD_NBIT, i * 2);
3409             SIMD8_SET (psr, ZBIT8 (a), SIMD_ZBIT, i * 2);
3410             SIMD8_SET (psr, NBIT8 (b), SIMD_NBIT, (i * 2) + 1);
3411             SIMD8_SET (psr, ZBIT8 (b), SIMD_ZBIT, (i * 2) + 1);
3412           }
3413       break;
3414 
3415     case Hqual:
3416       for (i = 0; i < 2; i++)
3417           {
3418             a = wRHALF (BITS (16, 19), i + 2);
3419             b = wRHALF (BITS ( 0,  3), i + 2);
3420             s = a | (b << 16);
3421             r |= (s & 0xffffffff) << (i * 32);
3422             SIMD16_SET (psr, NBIT16 (a), SIMD_NBIT, (i * 2));
3423             SIMD16_SET (psr, ZBIT16 (a), SIMD_ZBIT, (i * 2));
3424             SIMD16_SET (psr, NBIT16 (b), SIMD_NBIT, (i * 2) + 1);
3425             SIMD16_SET (psr, ZBIT16 (b), SIMD_ZBIT, (i * 2) + 1);
3426           }
3427       break;
3428 
3429     case Wqual:
3430       a = wRWORD (BITS (16, 19), 1);
3431       s = wRWORD (BITS ( 0,  3), 1);
3432       r = a | (s << 32);
3433 
3434       SIMD32_SET (psr, NBIT32 (a), SIMD_NBIT, 0);
3435       SIMD32_SET (psr, ZBIT32 (a), SIMD_ZBIT, 0);
3436       SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, 1);
3437       SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, 1);
3438       break;
3439 
3440     default:
3441       ARMul_UndefInstr (state, instr);
3442       return ARMul_DONE;
3443     }
3444 
3445   wC [wCASF] = psr;
3446   wR [BITS (12, 15)] = r;
3447   wC [wCon] |= (WCON_CUP | WCON_MUP);
3448 
3449   return ARMul_DONE;
3450 }
3451 
3452 static int
WUNPCKIL(ARMul_State * state,ARMword instr)3453 WUNPCKIL (ARMul_State * state, ARMword instr)
3454 {
3455   ARMword  a, b;
3456   ARMdword r = 0;
3457   ARMword  psr = 0;
3458   ARMdword s;
3459   int      i;
3460 
3461   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3462     return ARMul_CANT;
3463 
3464 #ifdef DEBUG
3465   fprintf (stderr, "wunpckil\n");
3466 #endif
3467 
3468   switch (BITS (22, 23))
3469     {
3470     case Bqual:
3471       for (i = 0; i < 4; i++)
3472           {
3473             a = wRBYTE (BITS (16, 19), i);
3474             b = wRBYTE (BITS ( 0,  3), i);
3475             s = a | (b << 8);
3476             r |= (s & 0xffff) << (i * 16);
3477             SIMD8_SET (psr, NBIT8 (a), SIMD_NBIT, i * 2);
3478             SIMD8_SET (psr, ZBIT8 (a), SIMD_ZBIT, i * 2);
3479             SIMD8_SET (psr, NBIT8 (b), SIMD_NBIT, (i * 2) + 1);
3480             SIMD8_SET (psr, ZBIT8 (b), SIMD_ZBIT, (i * 2) + 1);
3481           }
3482       break;
3483 
3484     case Hqual:
3485       for (i = 0; i < 2; i++)
3486           {
3487             a = wRHALF (BITS (16, 19), i);
3488             b = wRHALF (BITS ( 0,  3), i);
3489             s = a | (b << 16);
3490             r |= (s & 0xffffffff) << (i * 32);
3491             SIMD16_SET (psr, NBIT16 (a), SIMD_NBIT, (i * 2));
3492             SIMD16_SET (psr, ZBIT16 (a), SIMD_ZBIT, (i * 2));
3493             SIMD16_SET (psr, NBIT16 (b), SIMD_NBIT, (i * 2) + 1);
3494             SIMD16_SET (psr, ZBIT16 (b), SIMD_ZBIT, (i * 2) + 1);
3495           }
3496       break;
3497 
3498     case Wqual:
3499       a = wRWORD (BITS (16, 19), 0);
3500       s = wRWORD (BITS ( 0,  3), 0);
3501       r = a | (s << 32);
3502 
3503       SIMD32_SET (psr, NBIT32 (a), SIMD_NBIT, 0);
3504       SIMD32_SET (psr, ZBIT32 (a), SIMD_ZBIT, 0);
3505       SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, 1);
3506       SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, 1);
3507       break;
3508 
3509     default:
3510       ARMul_UndefInstr (state, instr);
3511       return ARMul_DONE;
3512     }
3513 
3514   wC [wCASF] = psr;
3515   wR [BITS (12, 15)] = r;
3516   wC [wCon] |= (WCON_CUP | WCON_MUP);
3517 
3518   return ARMul_DONE;
3519 }
3520 
3521 static int
WXOR(ARMword instr)3522 WXOR (ARMword instr)
3523 {
3524   ARMword psr = 0;
3525   ARMdword result;
3526 
3527   if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3528     return ARMul_CANT;
3529 
3530 #ifdef DEBUG
3531   fprintf (stderr, "wxor\n");
3532 #endif
3533 
3534   result = wR [BITS (16, 19)] ^ wR [BITS (0, 3)];
3535   wR [BITS (12, 15)] = result;
3536 
3537   SIMD64_SET (psr, (result == 0), SIMD_ZBIT);
3538   SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT);
3539 
3540   wC [wCASF] = psr;
3541   wC [wCon] |= (WCON_CUP | WCON_MUP);
3542 
3543   return ARMul_DONE;
3544 }
3545 
3546 /* This switch table is moved to a separate function in order
3547    to work around a compiler bug in the host compiler...  */
3548 
3549 static int
Process_Instruction(ARMul_State * state,ARMword instr)3550 Process_Instruction (ARMul_State * state, ARMword instr)
3551 {
3552   int status = ARMul_BUSY;
3553 
3554   switch ((BITS (20, 23) << 8) | BITS (4, 11))
3555     {
3556     case 0x000: status = WOR (instr); break;
3557     case 0x011: status = TMCR (state, instr); break;
3558     case 0x100: status = WXOR (instr); break;
3559     case 0x111: status = TMRC (state, instr); break;
3560     case 0x300: status = WANDN (instr); break;
3561     case 0x200: status = WAND (instr); break;
3562 
3563     case 0x810: case 0xa10:
3564       status = WMADD (instr); break;
3565 
3566     case 0x10e: case 0x50e: case 0x90e: case 0xd0e:
3567       status = WUNPCKIL (state, instr); break;
3568     case 0x10c: case 0x50c: case 0x90c: case 0xd0c:
3569       status = WUNPCKIH (state, instr); break;
3570     case 0x012: case 0x112: case 0x412: case 0x512:
3571       status = WSAD (instr); break;
3572     case 0x010: case 0x110: case 0x210: case 0x310:
3573       status = WMUL (instr); break;
3574     case 0x410: case 0x510: case 0x610: case 0x710:
3575       status = WMAC (instr); break;
3576     case 0x006: case 0x406: case 0x806: case 0xc06:
3577       status = WCMPEQ (state, instr); break;
3578     case 0x800: case 0x900: case 0xc00: case 0xd00:
3579       status = WAVG2 (instr); break;
3580     case 0x802: case 0x902: case 0xa02: case 0xb02:
3581       status = WALIGNR (state, instr); break;
3582     case 0x601: case 0x605: case 0x609: case 0x60d:
3583       status = TINSR (state, instr); break;
3584     case 0x107: case 0x507: case 0x907: case 0xd07:
3585       status = TEXTRM (state, instr); break;
3586     case 0x117: case 0x517: case 0x917: case 0xd17:
3587       status = TEXTRC (state, instr); break;
3588     case 0x401: case 0x405: case 0x409: case 0x40d:
3589       status = TBCST (state, instr); break;
3590     case 0x113: case 0x513: case 0x913: case 0xd13:
3591       status = TANDC (state, instr); break;
3592     case 0x01c: case 0x41c: case 0x81c: case 0xc1c:
3593       status = WACC (state, instr); break;
3594     case 0x115: case 0x515: case 0x915: case 0xd15:
3595       status = TORC (state, instr); break;
3596     case 0x103: case 0x503: case 0x903: case 0xd03:
3597       status = TMOVMSK (state, instr); break;
3598     case 0x106: case 0x306: case 0x506: case 0x706:
3599     case 0x906: case 0xb06: case 0xd06: case 0xf06:
3600       status = WCMPGT (state, instr); break;
3601     case 0x00e: case 0x20e: case 0x40e: case 0x60e:
3602     case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
3603       status = WUNPCKEL (state, instr); break;
3604     case 0x00c: case 0x20c: case 0x40c: case 0x60c:
3605     case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
3606       status = WUNPCKEH (state, instr); break;
3607     case 0x204: case 0x604: case 0xa04: case 0xe04:
3608     case 0x214: case 0x614: case 0xa14: case 0xe14:
3609       status = WSRL (state, instr); break;
3610     case 0x004: case 0x404: case 0x804: case 0xc04:
3611     case 0x014: case 0x414: case 0x814: case 0xc14:
3612       status = WSRA (state, instr); break;
3613     case 0x104: case 0x504: case 0x904: case 0xd04:
3614     case 0x114: case 0x514: case 0x914: case 0xd14:
3615       status = WSLL (state, instr); break;
3616     case 0x304: case 0x704: case 0xb04: case 0xf04:
3617     case 0x314: case 0x714: case 0xb14: case 0xf14:
3618       status = WROR (state, instr); break;
3619     case 0x116: case 0x316: case 0x516: case 0x716:
3620     case 0x916: case 0xb16: case 0xd16: case 0xf16:
3621       status = WMIN (state, instr); break;
3622     case 0x016: case 0x216: case 0x416: case 0x616:
3623     case 0x816: case 0xa16: case 0xc16: case 0xe16:
3624       status = WMAX (state, instr); break;
3625     case 0x002: case 0x102: case 0x202: case 0x302:
3626     case 0x402: case 0x502: case 0x602: case 0x702:
3627       status = WALIGNI (instr); break;
3628     case 0x01a: case 0x11a: case 0x21a: case 0x31a:
3629     case 0x41a: case 0x51a: case 0x61a: case 0x71a:
3630     case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
3631     case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
3632       status = WSUB (state, instr); break;
3633     case 0x01e: case 0x11e: case 0x21e: case 0x31e:
3634     case 0x41e: case 0x51e: case 0x61e: case 0x71e:
3635     case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
3636     case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
3637       status = WSHUFH (instr); break;
3638     case 0x018: case 0x118: case 0x218: case 0x318:
3639     case 0x418: case 0x518: case 0x618: case 0x718:
3640     case 0x818: case 0x918: case 0xa18: case 0xb18:
3641     case 0xc18: case 0xd18: case 0xe18: case 0xf18:
3642       status = WADD (state, instr); break;
3643     case 0x008: case 0x108: case 0x208: case 0x308:
3644     case 0x408: case 0x508: case 0x608: case 0x708:
3645     case 0x808: case 0x908: case 0xa08: case 0xb08:
3646     case 0xc08: case 0xd08: case 0xe08: case 0xf08:
3647       status = WPACK (state, instr); break;
3648     case 0x201: case 0x203: case 0x205: case 0x207:
3649     case 0x209: case 0x20b: case 0x20d: case 0x20f:
3650     case 0x211: case 0x213: case 0x215: case 0x217:
3651     case 0x219: case 0x21b: case 0x21d: case 0x21f:
3652       switch (BITS (16, 19))
3653           {
3654           case 0x0: status = TMIA (state, instr); break;
3655           case 0x8: status = TMIAPH (state, instr); break;
3656           case 0xc:
3657           case 0xd:
3658           case 0xe:
3659           case 0xf: status = TMIAxy (state, instr); break;
3660           default: break;
3661           }
3662       break;
3663     default:
3664       break;
3665     }
3666   return status;
3667 }
3668 
3669 /* Process a possibly Intel(r) Wireless MMX(tm) technology instruction.
3670    Return true if the instruction was handled.  */
3671 
3672 int
ARMul_HandleIwmmxt(ARMul_State * state,ARMword instr)3673 ARMul_HandleIwmmxt (ARMul_State * state, ARMword instr)
3674 {
3675   int status = ARMul_BUSY;
3676 
3677   if (BITS (24, 27) == 0xe)
3678     {
3679       status = Process_Instruction (state, instr);
3680     }
3681   else if (BITS (25, 27) == 0x6)
3682     {
3683       if (BITS (4, 11) == 0x0 && BITS (20, 24) == 0x4)
3684           status = TMCRR (state, instr);
3685       else if (BITS (9, 11) == 0x0)
3686           {
3687             if (BIT (20) == 0x0)
3688               status = WSTR (state, instr);
3689             else if (BITS (20, 24) == 0x5)
3690               status = TMRRC (state, instr);
3691             else
3692               status = WLDR (state, instr);
3693           }
3694     }
3695 
3696   if (status == ARMul_CANT)
3697     {
3698       /* If the instruction was a recognised but illegal,
3699            perform the abort here rather than returning false.
3700            If we return false then ARMul_MRC may be called which
3701            will still abort, but which also perform the register
3702            transfer...  */
3703       ARMul_Abort (state, ARMul_UndefinedInstrV);
3704       status = ARMul_DONE;
3705     }
3706 
3707   return status == ARMul_DONE;
3708 }
3709 
3710 int
Fetch_Iwmmxt_Register(unsigned int regnum,unsigned char * memory)3711 Fetch_Iwmmxt_Register (unsigned int regnum, unsigned char * memory)
3712 {
3713   if (regnum >= 16)
3714     {
3715       memcpy (memory, wC + (regnum - 16), sizeof wC [0]);
3716       return sizeof wC [0];
3717     }
3718   else
3719     {
3720       memcpy (memory, wR + regnum, sizeof wR [0]);
3721       return sizeof wR [0];
3722     }
3723 }
3724 
3725 int
Store_Iwmmxt_Register(unsigned int regnum,const unsigned char * memory)3726 Store_Iwmmxt_Register (unsigned int regnum, const unsigned char * memory)
3727 {
3728   if (regnum >= 16)
3729     {
3730       memcpy (wC + (regnum - 16), memory, sizeof wC [0]);
3731       return sizeof wC [0];
3732     }
3733   else
3734     {
3735       memcpy (wR + regnum, memory, sizeof wR [0]);
3736       return sizeof wR [0];
3737     }
3738 }
3739