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