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