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