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