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