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