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