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