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