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