1 /* iwmmxt.c -- Intel(r) Wireless MMX(tm) technology co-processor interface.
2 Copyright (C) 2002-2024 Free Software Foundation, Inc.
3 Contributed by matthew green (mrg@redhat.com).
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 /* This must come before any other includes. */
32 /* Intel(r) Wireless MMX(tm) technology co-processor.
33 It uses co-processor numbers (0 and 1). There are 16 vector registers wRx
34 and 16 control registers wCx. Co-processors 0 and 1 are used in MCR/MRC
35 to access wRx and wCx respectively. */
37 static ARMdword wR
[16];
38 static ARMword wC
[16] = { 0x69051010 };
40 #define SUBSTR(w,t,m,n) ((t)(w << ((sizeof (t) * 8 - 1) - (n))) \
41 >> (((sizeof (t) * 8 - 1) - (n)) + (m)))
42 #define wCBITS(w,x,y) SUBSTR (wC[w], ARMword, x, y)
43 #define wRBITS(w,x,y) SUBSTR (wR[w], ARMdword, x, y)
53 /* Bits in the wCon register. */
54 #define WCON_CUP (1 << 0)
55 #define WCON_MUP (1 << 1)
57 /* Set the SIMD wCASF flags for 8, 16, 32 or 64-bit operations. */
58 #define SIMD8_SET(x, v, n, b) (x) |= ((v != 0) << ((((b) + 1) * 4) + (n)))
59 #define SIMD16_SET(x, v, n, h) (x) |= ((v != 0) << ((((h) + 1) * 8) + (n)))
60 #define SIMD32_SET(x, v, n, w) (x) |= ((v != 0) << ((((w) + 1) * 16) + (n)))
61 #define SIMD64_SET(x, v, n) (x) |= ((v != 0) << (32 + (n)))
63 /* Flags to pass as "n" above. */
69 /* Various status bit macros. */
70 #define NBIT8(x) ((x) & 0x80)
71 #define NBIT16(x) ((x) & 0x8000)
72 #define NBIT32(x) ((x) & 0x80000000)
73 #define NBIT64(x) ((x) & 0x8000000000000000ULL)
74 #define ZBIT8(x) (((x) & 0xff) == 0)
75 #define ZBIT16(x) (((x) & 0xffff) == 0)
76 #define ZBIT32(x) (((x) & 0xffffffff) == 0)
77 #define ZBIT64(x) (x == 0)
79 /* Access byte/half/word "n" of register "x". */
80 #define wRBYTE(x,n) wRBITS ((x), (n) * 8, (n) * 8 + 7)
81 #define wRHALF(x,n) wRBITS ((x), (n) * 16, (n) * 16 + 15)
82 #define wRWORD(x,n) wRBITS ((x), (n) * 32, (n) * 32 + 31)
84 /* Macro to handle how the G bit selects wCGR registers. */
85 #define DECODE_G_BIT(state, instr, shift) \
91 if (BIT (8)) /* G */ \
93 if (reg < wCGR0 || reg > wCGR3) \
95 ARMul_UndefInstr (state, instr); \
106 /* Index calculations for the satrv[] array. */
107 #define BITIDX8(x) (x)
108 #define BITIDX16(x) (((x) + 1) * 2 - 1)
109 #define BITIDX32(x) (((x) + 1) * 4 - 1)
111 /* Sign extension macros. */
112 #define EXTEND8(a) ((a) & 0x80 ? ((a) | 0xffffff00) : (a))
113 #define EXTEND16(a) ((a) & 0x8000 ? ((a) | 0xffff0000) : (a))
114 #define EXTEND32(a) ((a) & 0x80000000ULL ? ((a) | 0xffffffff00000000ULL) : (a))
116 /* Set the wCSSF from 8 values. */
117 #define SET_wCSSF(a,b,c,d,e,f,g,h) \
118 wC[wCSSF] = (((h) != 0) << 7) | (((g) != 0) << 6) \
119 | (((f) != 0) << 5) | (((e) != 0) << 4) \
120 | (((d) != 0) << 3) | (((c) != 0) << 2) \
121 | (((b) != 0) << 1) | (((a) != 0) << 0);
123 /* Set the wCSSR from an array with 8 values. */
124 #define SET_wCSSFvec(v) \
125 SET_wCSSF((v)[0],(v)[1],(v)[2],(v)[3],(v)[4],(v)[5],(v)[6],(v)[7])
127 /* Size qualifiers for vector operations. */
133 /* Saturation qualifiers for vector operations. */
134 #define NoSaturation 0
135 #define UnsignedSaturation 1
136 #define SignedSaturation 3
140 static ARMword
Add32 (ARMword
, ARMword
, int *, int *, ARMword
);
141 static ARMdword
AddS32 (ARMdword
, ARMdword
, int *, int *);
142 static ARMdword
AddU32 (ARMdword
, ARMdword
, int *, int *);
143 static ARMword
AddS16 (ARMword
, ARMword
, int *, int *);
144 static ARMword
AddU16 (ARMword
, ARMword
, int *, int *);
145 static ARMword
AddS8 (ARMword
, ARMword
, int *, int *);
146 static ARMword
AddU8 (ARMword
, ARMword
, int *, int *);
147 static ARMword
Sub32 (ARMword
, ARMword
, int *, int *, ARMword
);
148 static ARMdword
SubS32 (ARMdword
, ARMdword
, int *, int *);
149 static ARMdword
SubU32 (ARMdword
, ARMdword
, int *, int *);
150 static ARMword
SubS16 (ARMword
, ARMword
, int *, int *);
151 static ARMword
SubS8 (ARMword
, ARMword
, int *, int *);
152 static ARMword
SubU16 (ARMword
, ARMword
, int *, int *);
153 static ARMword
SubU8 (ARMword
, ARMword
, int *, int *);
154 static unsigned char IwmmxtSaturateU8 (signed short, int *);
155 static signed char IwmmxtSaturateS8 (signed short, int *);
156 static unsigned short IwmmxtSaturateU16 (signed int, int *);
157 static signed short IwmmxtSaturateS16 (signed int, int *);
158 static unsigned long IwmmxtSaturateU32 (signed long long, int *);
159 static signed long IwmmxtSaturateS32 (signed long long, int *);
160 static ARMword
Compute_Iwmmxt_Address (ARMul_State
*, ARMword
, int *);
161 static ARMdword
Iwmmxt_Load_Double_Word (ARMul_State
*, ARMword
);
162 static ARMword
Iwmmxt_Load_Word (ARMul_State
*, ARMword
);
163 static ARMword
Iwmmxt_Load_Half_Word (ARMul_State
*, ARMword
);
164 static ARMword
Iwmmxt_Load_Byte (ARMul_State
*, ARMword
);
165 static void Iwmmxt_Store_Double_Word (ARMul_State
*, ARMword
, ARMdword
);
166 static void Iwmmxt_Store_Word (ARMul_State
*, ARMword
, ARMword
);
167 static void Iwmmxt_Store_Half_Word (ARMul_State
*, ARMword
, ARMword
);
168 static void Iwmmxt_Store_Byte (ARMul_State
*, ARMword
, ARMword
);
169 static int Process_Instruction (ARMul_State
*, ARMword
);
171 static int TANDC (ARMul_State
*, ARMword
);
172 static int TBCST (ARMul_State
*, ARMword
);
173 static int TEXTRC (ARMul_State
*, ARMword
);
174 static int TEXTRM (ARMul_State
*, ARMword
);
175 static int TINSR (ARMul_State
*, ARMword
);
176 static int TMCR (ARMul_State
*, ARMword
);
177 static int TMCRR (ARMul_State
*, ARMword
);
178 static int TMIA (ARMul_State
*, ARMword
);
179 static int TMIAPH (ARMul_State
*, ARMword
);
180 static int TMIAxy (ARMul_State
*, ARMword
);
181 static int TMOVMSK (ARMul_State
*, ARMword
);
182 static int TMRC (ARMul_State
*, ARMword
);
183 static int TMRRC (ARMul_State
*, ARMword
);
184 static int TORC (ARMul_State
*, ARMword
);
185 static int WACC (ARMul_State
*, ARMword
);
186 static int WADD (ARMul_State
*, ARMword
);
187 static int WALIGNI (ARMword
);
188 static int WALIGNR (ARMul_State
*, ARMword
);
189 static int WAND (ARMword
);
190 static int WANDN (ARMword
);
191 static int WAVG2 (ARMword
);
192 static int WCMPEQ (ARMul_State
*, ARMword
);
193 static int WCMPGT (ARMul_State
*, ARMword
);
194 static int WLDR (ARMul_State
*, ARMword
);
195 static int WMAC (ARMword
);
196 static int WMADD (ARMword
);
197 static int WMAX (ARMul_State
*, ARMword
);
198 static int WMIN (ARMul_State
*, ARMword
);
199 static int WMUL (ARMword
);
200 static int WOR (ARMword
);
201 static int WPACK (ARMul_State
*, ARMword
);
202 static int WROR (ARMul_State
*, ARMword
);
203 static int WSAD (ARMword
);
204 static int WSHUFH (ARMword
);
205 static int WSLL (ARMul_State
*, ARMword
);
206 static int WSRA (ARMul_State
*, ARMword
);
207 static int WSRL (ARMul_State
*, ARMword
);
208 static int WSTR (ARMul_State
*, ARMword
);
209 static int WSUB (ARMul_State
*, ARMword
);
210 static int WUNPCKEH (ARMul_State
*, ARMword
);
211 static int WUNPCKEL (ARMul_State
*, ARMword
);
212 static int WUNPCKIH (ARMul_State
*, ARMword
);
213 static int WUNPCKIL (ARMul_State
*, ARMword
);
214 static int WXOR (ARMword
);
216 /* This function does the work of adding two 32bit values
217 together, and calculating if a carry has occurred. */
226 ARMword result
= (a1
+ a2
);
227 unsigned int uresult
= (unsigned int) result
;
228 unsigned int ua1
= (unsigned int) a1
;
230 /* If (result == a1) and (a2 == 0),
231 or (result > a2) then we have no carry. */
232 * carry_ptr
= ((uresult
== ua1
) ? (a2
!= 0) : (uresult
< ua1
));
234 /* Overflow occurs when both arguments are the
235 same sign, but the result is a different sign. */
236 * overflow_ptr
= ( ( (result
& sign_mask
) && !(a1
& sign_mask
) && !(a2
& sign_mask
))
237 || (!(result
& sign_mask
) && (a1
& sign_mask
) && (a2
& sign_mask
)));
243 AddS32 (ARMdword a1
, ARMdword a2
, int * carry_ptr
, int * overflow_ptr
)
246 unsigned int uresult
;
253 uresult
= (unsigned int) result
;
254 ua1
= (unsigned int) a1
;
256 * carry_ptr
= ((uresult
== a1
) ? (a2
!= 0) : (uresult
< ua1
));
258 * overflow_ptr
= ( ( (result
& 0x80000000ULL
) && !(a1
& 0x80000000ULL
) && !(a2
& 0x80000000ULL
))
259 || (!(result
& 0x80000000ULL
) && (a1
& 0x80000000ULL
) && (a2
& 0x80000000ULL
)));
265 AddU32 (ARMdword a1
, ARMdword a2
, int * carry_ptr
, int * overflow_ptr
)
268 unsigned int uresult
;
275 uresult
= (unsigned int) result
;
276 ua1
= (unsigned int) a1
;
278 * carry_ptr
= ((uresult
== a1
) ? (a2
!= 0) : (uresult
< ua1
));
280 * overflow_ptr
= ( ( (result
& 0x80000000ULL
) && !(a1
& 0x80000000ULL
) && !(a2
& 0x80000000ULL
))
281 || (!(result
& 0x80000000ULL
) && (a1
& 0x80000000ULL
) && (a2
& 0x80000000ULL
)));
287 AddS16 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
292 return Add32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x8000);
296 AddU16 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
301 return Add32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x8000);
305 AddS8 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
310 return Add32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x80);
314 AddU8 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
319 return Add32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x80);
329 ARMword result
= (a1
- a2
);
330 unsigned int ua1
= (unsigned int) a1
;
331 unsigned int ua2
= (unsigned int) a2
;
333 /* A borrow occurs if a2 is (unsigned) larger than a1.
334 However the carry flag is *cleared* if a borrow occurs. */
335 * borrow_ptr
= ! (ua2
> ua1
);
337 /* Overflow occurs when a negative number is subtracted from a
338 positive number and the result is negative or a positive
339 number is subtracted from a negative number and the result is
341 * overflow_ptr
= ( (! (a1
& sign_mask
) && (a2
& sign_mask
) && (result
& sign_mask
))
342 || ((a1
& sign_mask
) && ! (a2
& sign_mask
) && ! (result
& sign_mask
)));
348 SubS32 (ARMdword a1
, ARMdword a2
, int * borrow_ptr
, int * overflow_ptr
)
358 ua1
= (unsigned int) a1
;
359 ua2
= (unsigned int) a2
;
361 * borrow_ptr
= ! (ua2
> ua1
);
363 * overflow_ptr
= ( (! (a1
& 0x80000000ULL
) && (a2
& 0x80000000ULL
) && (result
& 0x80000000ULL
))
364 || ((a1
& 0x80000000ULL
) && ! (a2
& 0x80000000ULL
) && ! (result
& 0x80000000ULL
)));
370 SubS16 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
375 return Sub32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x8000);
379 SubS8 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
384 return Sub32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x80);
388 SubU16 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
393 return Sub32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x8000);
397 SubU8 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
402 return Sub32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x80);
406 SubU32 (ARMdword a1
, ARMdword a2
, int * borrow_ptr
, int * overflow_ptr
)
416 ua1
= (unsigned int) a1
;
417 ua2
= (unsigned int) a2
;
419 * borrow_ptr
= ! (ua2
> ua1
);
421 * overflow_ptr
= ( (! (a1
& 0x80000000ULL
) && (a2
& 0x80000000ULL
) && (result
& 0x80000000ULL
))
422 || ((a1
& 0x80000000ULL
) && ! (a2
& 0x80000000ULL
) && ! (result
& 0x80000000ULL
)));
427 /* For the saturation. */
430 IwmmxtSaturateU8 (signed short val
, int * sat
)
453 IwmmxtSaturateS8 (signed short val
, int * sat
)
475 static unsigned short
476 IwmmxtSaturateU16 (signed int val
, int * sat
)
485 else if (val
> 0xffff)
499 IwmmxtSaturateS16 (signed int val
, int * sat
)
508 else if (val
> 0x7fff)
522 IwmmxtSaturateU32 (signed long long val
, int * sat
)
531 else if (val
> 0xffffffff)
538 rv
= val
& 0xffffffff;
545 IwmmxtSaturateS32 (signed long long val
, int * sat
)
549 if (val
< -0x80000000LL
)
554 else if (val
> 0x7fffffff)
561 rv
= val
& 0xffffffff;
567 /* Intel(r) Wireless MMX(tm) technology Acessor functions. */
570 IwmmxtLDC (ARMul_State
* state ATTRIBUTE_UNUSED
,
571 unsigned type ATTRIBUTE_UNUSED
,
579 IwmmxtSTC (ARMul_State
* state ATTRIBUTE_UNUSED
,
580 unsigned type ATTRIBUTE_UNUSED
,
588 IwmmxtMRC (ARMul_State
* state ATTRIBUTE_UNUSED
,
589 unsigned type ATTRIBUTE_UNUSED
,
597 IwmmxtMCR (ARMul_State
* state ATTRIBUTE_UNUSED
,
598 unsigned type ATTRIBUTE_UNUSED
,
606 IwmmxtCDP (ARMul_State
* state
, unsigned type
, ARMword instr
)
611 /* Intel(r) Wireless MMX(tm) technology instruction implementations. */
614 TANDC (ARMul_State
* state
, ARMword instr
)
618 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
622 fprintf (stderr
, "tandc\n");
625 /* The Rd field must be r15. */
626 if (BITS (12, 15) != 15)
629 /* The CRn field must be r3. */
630 if (BITS (16, 19) != 3)
633 /* The CRm field must be r0. */
634 if (BITS (0, 3) != 0)
637 cpsr
= ARMul_GetCPSR (state
) & 0x0fffffff;
639 switch (BITS (22, 23))
642 cpsr
|= ( (wCBITS (wCASF
, 28, 31) & wCBITS (wCASF
, 24, 27)
643 & wCBITS (wCASF
, 20, 23) & wCBITS (wCASF
, 16, 19)
644 & wCBITS (wCASF
, 12, 15) & wCBITS (wCASF
, 8, 11)
645 & wCBITS (wCASF
, 4, 7) & wCBITS (wCASF
, 0, 3)) << 28);
649 cpsr
|= ( (wCBITS (wCASF
, 28, 31) & wCBITS (wCASF
, 20, 23)
650 & wCBITS (wCASF
, 12, 15) & wCBITS (wCASF
, 4, 7)) << 28);
654 cpsr
|= ((wCBITS (wCASF
, 28, 31) & wCBITS (wCASF
, 12, 15)) << 28);
658 ARMul_UndefInstr (state
, instr
);
662 ARMul_SetCPSR (state
, cpsr
);
668 TBCST (ARMul_State
* state
, ARMword instr
)
673 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
677 fprintf (stderr
, "tbcst\n");
680 Rn
= state
->Reg
[BITS (12, 15)];
681 if (BITS (12, 15) == 15)
690 wR
[wRd
] = (Rn
<< 56) | (Rn
<< 48) | (Rn
<< 40) | (Rn
<< 32)
691 | (Rn
<< 24) | (Rn
<< 16) | (Rn
<< 8) | Rn
;
696 wR
[wRd
] = (Rn
<< 48) | (Rn
<< 32) | (Rn
<< 16) | Rn
;
701 wR
[wRd
] = (Rn
<< 32) | Rn
;
705 ARMul_UndefInstr (state
, instr
);
709 wC
[wCon
] |= WCON_MUP
;
714 TEXTRC (ARMul_State
* state
, ARMword instr
)
719 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
723 fprintf (stderr
, "textrc\n");
726 /* The Rd field must be r15. */
727 if (BITS (12, 15) != 15)
730 /* The CRn field must be r3. */
731 if (BITS (16, 19) != 3)
734 /* The CRm field must be 0xxx. */
738 selector
= BITS (0, 2);
739 cpsr
= ARMul_GetCPSR (state
) & 0x0fffffff;
741 switch (BITS (22, 23))
743 case Bqual
: selector
*= 4; break;
744 case Hqual
: selector
= ((selector
& 3) * 8) + 4; break;
745 case Wqual
: selector
= ((selector
& 1) * 16) + 12; break;
748 ARMul_UndefInstr (state
, instr
);
752 cpsr
|= wCBITS (wCASF
, selector
, selector
+ 3) << 28;
753 ARMul_SetCPSR (state
, cpsr
);
759 TEXTRM (ARMul_State
* state
, ARMword instr
)
766 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
770 fprintf (stderr
, "textrm\n");
775 offset
= BITS (0, 2);
777 switch (BITS (22, 23))
781 Rd
= wRBITS (wRn
, offset
, offset
+ 7);
787 offset
= (offset
& 3) * 16;
788 Rd
= wRBITS (wRn
, offset
, offset
+ 15);
794 offset
= (offset
& 1) * 32;
795 Rd
= wRBITS (wRn
, offset
, offset
+ 31);
799 ARMul_UndefInstr (state
, instr
);
803 if (BITS (12, 15) == 15)
804 ARMul_UndefInstr (state
, instr
);
806 state
->Reg
[BITS (12, 15)] = Rd
;
812 TINSR (ARMul_State
* state
, ARMword instr
)
818 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
822 fprintf (stderr
, "tinsr\n");
826 data
= state
->Reg
[BITS (12, 15)];
827 offset
= BITS (0, 2);
835 case 0: wR
[wRd
] = data
| (wRBITS (wRd
, 8, 63) << 8); break;
836 case 1: wR
[wRd
] = wRBITS (wRd
, 0, 7) | (data
<< 8) | (wRBITS (wRd
, 16, 63) << 16); break;
837 case 2: wR
[wRd
] = wRBITS (wRd
, 0, 15) | (data
<< 16) | (wRBITS (wRd
, 24, 63) << 24); break;
838 case 3: wR
[wRd
] = wRBITS (wRd
, 0, 23) | (data
<< 24) | (wRBITS (wRd
, 32, 63) << 32); break;
839 case 4: wR
[wRd
] = wRBITS (wRd
, 0, 31) | (data
<< 32) | (wRBITS (wRd
, 40, 63) << 40); break;
840 case 5: wR
[wRd
] = wRBITS (wRd
, 0, 39) | (data
<< 40) | (wRBITS (wRd
, 48, 63) << 48); break;
841 case 6: wR
[wRd
] = wRBITS (wRd
, 0, 47) | (data
<< 48) | (wRBITS (wRd
, 56, 63) << 56); break;
842 case 7: wR
[wRd
] = wRBITS (wRd
, 0, 55) | (data
<< 56); break;
851 case 0: wR
[wRd
] = data
| (wRBITS (wRd
, 16, 63) << 16); break;
852 case 1: wR
[wRd
] = wRBITS (wRd
, 0, 15) | (data
<< 16) | (wRBITS (wRd
, 32, 63) << 32); break;
853 case 2: wR
[wRd
] = wRBITS (wRd
, 0, 31) | (data
<< 32) | (wRBITS (wRd
, 48, 63) << 48); break;
854 case 3: wR
[wRd
] = wRBITS (wRd
, 0, 47) | (data
<< 48); break;
860 wR
[wRd
] = wRBITS (wRd
, 0, 31) | (data
<< 32);
862 wR
[wRd
] = (wRBITS (wRd
, 32, 63) << 32) | data
;
866 ARMul_UndefInstr (state
, instr
);
870 wC
[wCon
] |= WCON_MUP
;
875 TMCR (ARMul_State
* state
, ARMword instr
)
880 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
884 fprintf (stderr
, "tmcr\n");
887 if (BITS (0, 3) != 0)
890 val
= state
->Reg
[BITS (12, 15)];
891 if (BITS (12, 15) == 15)
894 wCreg
= BITS (16, 19);
899 /* The wCID register is read only. */
903 /* Writing to the MUP or CUP bits clears them. */
904 wC
[wCon
] &= ~ (val
& 0x3);
908 /* Only the bottom 8 bits can be written to.
909 The higher bits write as zero. */
910 wC
[wCSSF
] = (val
& 0xff);
911 wC
[wCon
] |= WCON_CUP
;
916 wC
[wCon
] |= WCON_CUP
;
924 TMCRR (ARMul_State
* state
, ARMword instr
)
926 ARMdword RdHi
= state
->Reg
[BITS (16, 19)];
927 ARMword RdLo
= state
->Reg
[BITS (12, 15)];
929 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
933 fprintf (stderr
, "tmcrr\n");
936 if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15))
939 wR
[BITS (0, 3)] = (RdHi
<< 32) | RdLo
;
941 wC
[wCon
] |= WCON_MUP
;
947 TMIA (ARMul_State
* state
, ARMword instr
)
949 signed long long a
, b
;
951 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
955 fprintf (stderr
, "tmia\n");
958 if ((BITS (0, 3) == 15) || (BITS (12, 15) == 15))
960 ARMul_UndefInstr (state
, instr
);
964 a
= state
->Reg
[BITS (0, 3)];
965 b
= state
->Reg
[BITS (12, 15)];
970 wR
[BITS (5, 8)] += a
* b
;
971 wC
[wCon
] |= WCON_MUP
;
977 TMIAPH (ARMul_State
* state
, ARMword instr
)
979 signed long a
, b
, result
;
981 ARMword Rm
= state
->Reg
[BITS (0, 3)];
982 ARMword Rs
= state
->Reg
[BITS (12, 15)];
984 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
988 fprintf (stderr
, "tmiaph\n");
991 if (BITS (0, 3) == 15 || BITS (12, 15) == 15)
993 ARMul_UndefInstr (state
, instr
);
997 a
= SUBSTR (Rs
, ARMword
, 16, 31);
998 b
= SUBSTR (Rm
, ARMword
, 16, 31);
1008 wR
[BITS (5, 8)] += r
;
1010 a
= SUBSTR (Rs
, ARMword
, 0, 15);
1011 b
= SUBSTR (Rm
, ARMword
, 0, 15);
1021 wR
[BITS (5, 8)] += r
;
1022 wC
[wCon
] |= WCON_MUP
;
1028 TMIAxy (ARMul_State
* state
, ARMword instr
)
1034 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1038 fprintf (stderr
, "tmiaxy\n");
1041 if (BITS (0, 3) == 15 || BITS (12, 15) == 15)
1043 ARMul_UndefInstr (state
, instr
);
1047 Rm
= state
->Reg
[BITS (0, 3)];
1053 Rs
= state
->Reg
[BITS (12, 15)];
1068 if (temp
& (1 << 31))
1071 wR
[BITS (5, 8)] += temp
;
1072 wC
[wCon
] |= WCON_MUP
;
1078 TMOVMSK (ARMul_State
* state
, ARMword instr
)
1083 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1087 fprintf (stderr
, "tmovmsk\n");
1090 /* The CRm field must be r0. */
1091 if (BITS (0, 3) != 0)
1094 wRn
= BITS (16, 19);
1096 switch (BITS (22, 23))
1099 result
= ( (wRBITS (wRn
, 63, 63) << 7)
1100 | (wRBITS (wRn
, 55, 55) << 6)
1101 | (wRBITS (wRn
, 47, 47) << 5)
1102 | (wRBITS (wRn
, 39, 39) << 4)
1103 | (wRBITS (wRn
, 31, 31) << 3)
1104 | (wRBITS (wRn
, 23, 23) << 2)
1105 | (wRBITS (wRn
, 15, 15) << 1)
1106 | (wRBITS (wRn
, 7, 7) << 0));
1110 result
= ( (wRBITS (wRn
, 63, 63) << 3)
1111 | (wRBITS (wRn
, 47, 47) << 2)
1112 | (wRBITS (wRn
, 31, 31) << 1)
1113 | (wRBITS (wRn
, 15, 15) << 0));
1117 result
= (wRBITS (wRn
, 63, 63) << 1) | wRBITS (wRn
, 31, 31);
1121 ARMul_UndefInstr (state
, instr
);
1125 state
->Reg
[BITS (12, 15)] = result
;
1131 TMRC (ARMul_State
* state
, ARMword instr
)
1133 int reg
= BITS (12, 15);
1135 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1139 fprintf (stderr
, "tmrc\n");
1142 if (BITS (0, 3) != 0)
1146 ARMul_UndefInstr (state
, instr
);
1148 state
->Reg
[reg
] = wC
[BITS (16, 19)];
1154 TMRRC (ARMul_State
* state
, ARMword instr
)
1156 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1160 fprintf (stderr
, "tmrrc\n");
1163 if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15) || (BITS (4, 11) != 0))
1164 ARMul_UndefInstr (state
, instr
);
1167 state
->Reg
[BITS (16, 19)] = wRBITS (BITS (0, 3), 32, 63);
1168 state
->Reg
[BITS (12, 15)] = wRBITS (BITS (0, 3), 0, 31);
1175 TORC (ARMul_State
* state
, ARMword instr
)
1177 ARMword cpsr
= ARMul_GetCPSR (state
);
1179 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1183 fprintf (stderr
, "torc\n");
1186 /* The Rd field must be r15. */
1187 if (BITS (12, 15) != 15)
1190 /* The CRn field must be r3. */
1191 if (BITS (16, 19) != 3)
1194 /* The CRm field must be r0. */
1195 if (BITS (0, 3) != 0)
1200 switch (BITS (22, 23))
1203 cpsr
|= ( (wCBITS (wCASF
, 28, 31) | wCBITS (wCASF
, 24, 27)
1204 | wCBITS (wCASF
, 20, 23) | wCBITS (wCASF
, 16, 19)
1205 | wCBITS (wCASF
, 12, 15) | wCBITS (wCASF
, 8, 11)
1206 | wCBITS (wCASF
, 4, 7) | wCBITS (wCASF
, 0, 3)) << 28);
1210 cpsr
|= ( (wCBITS (wCASF
, 28, 31) | wCBITS (wCASF
, 20, 23)
1211 | wCBITS (wCASF
, 12, 15) | wCBITS (wCASF
, 4, 7)) << 28);
1215 cpsr
|= ((wCBITS (wCASF
, 28, 31) | wCBITS (wCASF
, 12, 15)) << 28);
1219 ARMul_UndefInstr (state
, instr
);
1223 ARMul_SetCPSR (state
, cpsr
);
1229 WACC (ARMul_State
* state
, ARMword instr
)
1233 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1237 fprintf (stderr
, "wacc\n");
1240 wRn
= BITS (16, 19);
1242 switch (BITS (22, 23))
1245 wR
[BITS (12, 15)] =
1246 wRBITS (wRn
, 56, 63) + wRBITS (wRn
, 48, 55)
1247 + wRBITS (wRn
, 40, 47) + wRBITS (wRn
, 32, 39)
1248 + wRBITS (wRn
, 24, 31) + wRBITS (wRn
, 16, 23)
1249 + wRBITS (wRn
, 8, 15) + wRBITS (wRn
, 0, 7);
1253 wR
[BITS (12, 15)] =
1254 wRBITS (wRn
, 48, 63) + wRBITS (wRn
, 32, 47)
1255 + wRBITS (wRn
, 16, 31) + wRBITS (wRn
, 0, 15);
1259 wR
[BITS (12, 15)] = wRBITS (wRn
, 32, 63) + wRBITS (wRn
, 0, 31);
1263 ARMul_UndefInstr (state
, instr
);
1267 wC
[wCon
] |= WCON_MUP
;
1272 WADD (ARMul_State
* state
, ARMword instr
)
1283 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1287 fprintf (stderr
, "wadd\n");
1290 /* Add two numbers using the specified function,
1291 leaving setting the carry bit as required. */
1292 #define ADDx(x, y, m, f) \
1293 (*f) (wRBITS (BITS (16, 19), (x), (y)) & (m), \
1294 wRBITS (BITS ( 0, 3), (x), (y)) & (m), \
1295 & carry, & overflow)
1297 switch (BITS (22, 23))
1300 for (i
= 0; i
< 8; i
++)
1302 switch (BITS (20, 21))
1305 s
= ADDx ((i
* 8), (i
* 8) + 7, 0xff, AddS8
);
1306 satrv
[BITIDX8 (i
)] = 0;
1307 r
|= (s
& 0xff) << (i
* 8);
1308 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
1309 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
1310 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
1311 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
1314 case UnsignedSaturation
:
1315 s
= ADDx ((i
* 8), (i
* 8) + 7, 0xff, AddU8
);
1316 x
= IwmmxtSaturateU8 (s
, satrv
+ BITIDX8 (i
));
1317 r
|= (x
& 0xff) << (i
* 8);
1318 SIMD8_SET (psr
, NBIT8 (x
), SIMD_NBIT
, i
);
1319 SIMD8_SET (psr
, ZBIT8 (x
), SIMD_ZBIT
, i
);
1320 if (! satrv
[BITIDX8 (i
)])
1322 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
1323 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
1327 case SignedSaturation
:
1328 s
= ADDx ((i
* 8), (i
* 8) + 7, 0xff, AddS8
);
1329 x
= IwmmxtSaturateS8 (s
, satrv
+ BITIDX8 (i
));
1330 r
|= (x
& 0xff) << (i
* 8);
1331 SIMD8_SET (psr
, NBIT8 (x
), SIMD_NBIT
, i
);
1332 SIMD8_SET (psr
, ZBIT8 (x
), SIMD_ZBIT
, i
);
1333 if (! satrv
[BITIDX8 (i
)])
1335 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
1336 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
1341 ARMul_UndefInstr (state
, instr
);
1348 satrv
[0] = satrv
[2] = satrv
[4] = satrv
[6] = 0;
1350 for (i
= 0; i
< 4; i
++)
1352 switch (BITS (20, 21))
1355 s
= ADDx ((i
* 16), (i
* 16) + 15, 0xffff, AddS16
);
1356 satrv
[BITIDX16 (i
)] = 0;
1357 r
|= (s
& 0xffff) << (i
* 16);
1358 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
1359 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
1360 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
1361 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
1364 case UnsignedSaturation
:
1365 s
= ADDx ((i
* 16), (i
* 16) + 15, 0xffff, AddU16
);
1366 x
= IwmmxtSaturateU16 (s
, satrv
+ BITIDX16 (i
));
1367 r
|= (x
& 0xffff) << (i
* 16);
1368 SIMD16_SET (psr
, NBIT16 (x
), SIMD_NBIT
, i
);
1369 SIMD16_SET (psr
, ZBIT16 (x
), SIMD_ZBIT
, i
);
1370 if (! satrv
[BITIDX16 (i
)])
1372 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
1373 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
1377 case SignedSaturation
:
1378 s
= ADDx ((i
* 16), (i
* 16) + 15, 0xffff, AddS16
);
1379 x
= IwmmxtSaturateS16 (s
, satrv
+ BITIDX16 (i
));
1380 r
|= (x
& 0xffff) << (i
* 16);
1381 SIMD16_SET (psr
, NBIT16 (x
), SIMD_NBIT
, i
);
1382 SIMD16_SET (psr
, ZBIT16 (x
), SIMD_ZBIT
, i
);
1383 if (! satrv
[BITIDX16 (i
)])
1385 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
1386 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
1391 ARMul_UndefInstr (state
, instr
);
1398 satrv
[0] = satrv
[1] = satrv
[2] = satrv
[4] = satrv
[5] = satrv
[6] = 0;
1400 for (i
= 0; i
< 2; i
++)
1402 switch (BITS (20, 21))
1405 s
= ADDx ((i
* 32), (i
* 32) + 31, 0xffffffff, AddS32
);
1406 satrv
[BITIDX32 (i
)] = 0;
1407 r
|= (s
& 0xffffffff) << (i
* 32);
1408 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
1409 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
1410 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
1411 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
1414 case UnsignedSaturation
:
1415 s
= ADDx ((i
* 32), (i
* 32) + 31, 0xffffffff, AddU32
);
1416 x
= IwmmxtSaturateU32 (s
, satrv
+ BITIDX32 (i
));
1417 r
|= (x
& 0xffffffff) << (i
* 32);
1418 SIMD32_SET (psr
, NBIT32 (x
), SIMD_NBIT
, i
);
1419 SIMD32_SET (psr
, ZBIT32 (x
), SIMD_ZBIT
, i
);
1420 if (! satrv
[BITIDX32 (i
)])
1422 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
1423 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
1427 case SignedSaturation
:
1428 s
= ADDx ((i
* 32), (i
* 32) + 31, 0xffffffff, AddS32
);
1429 x
= IwmmxtSaturateS32 (s
, satrv
+ BITIDX32 (i
));
1430 r
|= (x
& 0xffffffff) << (i
* 32);
1431 SIMD32_SET (psr
, NBIT32 (x
), SIMD_NBIT
, i
);
1432 SIMD32_SET (psr
, ZBIT32 (x
), SIMD_ZBIT
, i
);
1433 if (! satrv
[BITIDX32 (i
)])
1435 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
1436 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
1441 ARMul_UndefInstr (state
, instr
);
1448 ARMul_UndefInstr (state
, instr
);
1453 wR
[BITS (12, 15)] = r
;
1454 wC
[wCon
] |= (WCON_MUP
| WCON_CUP
);
1456 SET_wCSSFvec (satrv
);
1464 WALIGNI (ARMword instr
)
1466 int shift
= BITS (20, 22) * 8;
1468 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1472 fprintf (stderr
, "waligni\n");
1476 wR
[BITS (12, 15)] =
1477 wRBITS (BITS (16, 19), shift
, 63)
1478 | (wRBITS (BITS (0, 3), 0, shift
) << ((64 - shift
)));
1480 wR
[BITS (12, 15)] = wR
[BITS (16, 19)];
1482 wC
[wCon
] |= WCON_MUP
;
1487 WALIGNR (ARMul_State
* state
, ARMword instr
)
1489 int shift
= (wC
[BITS (20, 21) + 8] & 0x7) * 8;
1491 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1495 fprintf (stderr
, "walignr\n");
1499 wR
[BITS (12, 15)] =
1500 wRBITS (BITS (16, 19), shift
, 63)
1501 | (wRBITS (BITS (0, 3), 0, shift
) << ((64 - shift
)));
1503 wR
[BITS (12, 15)] = wR
[BITS (16, 19)];
1505 wC
[wCon
] |= WCON_MUP
;
1510 WAND (ARMword instr
)
1515 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1519 fprintf (stderr
, "wand\n");
1522 result
= wR
[BITS (16, 19)] & wR
[BITS (0, 3)];
1523 wR
[BITS (12, 15)] = result
;
1525 SIMD64_SET (psr
, (result
== 0), SIMD_ZBIT
);
1526 SIMD64_SET (psr
, (result
& (1ULL << 63)), SIMD_NBIT
);
1529 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
1535 WANDN (ARMword instr
)
1540 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1544 fprintf (stderr
, "wandn\n");
1547 result
= wR
[BITS (16, 19)] & ~ wR
[BITS (0, 3)];
1548 wR
[BITS (12, 15)] = result
;
1550 SIMD64_SET (psr
, (result
== 0), SIMD_ZBIT
);
1551 SIMD64_SET (psr
, (result
& (1ULL << 63)), SIMD_NBIT
);
1554 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
1560 WAVG2 (ARMword instr
)
1566 int round
= BIT (20) ? 1 : 0;
1568 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1572 fprintf (stderr
, "wavg2\n");
1575 #define AVG2x(x, y, m) (((wRBITS (BITS (16, 19), (x), (y)) & (m)) \
1576 + (wRBITS (BITS ( 0, 3), (x), (y)) & (m)) \
1581 for (i
= 0; i
< 4; i
++)
1583 s
= AVG2x ((i
* 16), (i
* 16) + 15, 0xffff) & 0xffff;
1584 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
1590 for (i
= 0; i
< 8; i
++)
1592 s
= AVG2x ((i
* 8), (i
* 8) + 7, 0xff) & 0xff;
1593 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
1598 wR
[BITS (12, 15)] = r
;
1600 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
1606 WCMPEQ (ARMul_State
* state
, ARMword instr
)
1613 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1617 fprintf (stderr
, "wcmpeq\n");
1620 switch (BITS (22, 23))
1623 for (i
= 0; i
< 8; i
++)
1625 s
= wRBYTE (BITS (16, 19), i
) == wRBYTE (BITS (0, 3), i
) ? 0xff : 0;
1627 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
1628 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
1633 for (i
= 0; i
< 4; i
++)
1635 s
= wRHALF (BITS (16, 19), i
) == wRHALF (BITS (0, 3), i
) ? 0xffff : 0;
1637 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
1638 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
1643 for (i
= 0; i
< 2; i
++)
1645 s
= wRWORD (BITS (16, 19), i
) == wRWORD (BITS (0, 3), i
) ? 0xffffffff : 0;
1647 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
1648 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
1653 ARMul_UndefInstr (state
, instr
);
1658 wR
[BITS (12, 15)] = r
;
1659 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
1665 WCMPGT (ARMul_State
* state
, ARMword instr
)
1672 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1676 fprintf (stderr
, "wcmpgt\n");
1679 switch (BITS (22, 23))
1684 /* Use a signed comparison. */
1685 for (i
= 0; i
< 8; i
++)
1689 a
= wRBYTE (BITS (16, 19), i
);
1690 b
= wRBYTE (BITS (0, 3), i
);
1692 s
= (a
> b
) ? 0xff : 0;
1694 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
1695 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
1700 for (i
= 0; i
< 8; i
++)
1702 s
= (wRBYTE (BITS (16, 19), i
) > wRBYTE (BITS (0, 3), i
))
1705 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
1706 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
1714 for (i
= 0; i
< 4; i
++)
1718 a
= wRHALF (BITS (16, 19), i
);
1721 b
= wRHALF (BITS (0, 3), i
);
1724 s
= (a
> b
) ? 0xffff : 0;
1726 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
1727 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
1732 for (i
= 0; i
< 4; i
++)
1734 s
= (wRHALF (BITS (16, 19), i
) > wRHALF (BITS (0, 3), i
))
1737 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
1738 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
1746 for (i
= 0; i
< 2; i
++)
1750 a
= EXTEND32 (wRWORD (BITS (16, 19), i
));
1751 b
= EXTEND32 (wRWORD (BITS (0, 3), i
));
1753 s
= (a
> b
) ? 0xffffffff : 0;
1756 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
1757 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
1762 for (i
= 0; i
< 2; i
++)
1764 s
= (wRWORD (BITS (16, 19), i
) > wRWORD (BITS (0, 3), i
))
1767 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
1768 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
1774 ARMul_UndefInstr (state
, instr
);
1779 wR
[BITS (12, 15)] = r
;
1780 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
1786 Compute_Iwmmxt_Address (ARMul_State
* state
, ARMword instr
, int * pFailed
)
1795 addr
= state
->Reg
[Rn
];
1796 offset
= BITS (0, 7);
1797 multiplier
= BIT (8) ? 4 : 1;
1799 if (BIT (24)) /* P */
1801 /* Pre Indexed Addressing. */
1803 addr
+= offset
* multiplier
;
1805 addr
-= offset
* multiplier
;
1807 /* Immediate Pre-Indexed. */
1808 if (BIT (21)) /* W */
1812 /* Writeback into R15 is UNPREDICTABLE. */
1814 fprintf (stderr
, "iWMMXt: writeback into r15\n");
1819 state
->Reg
[Rn
] = addr
;
1824 /* Post Indexed Addressing. */
1825 if (BIT (21)) /* W */
1827 /* Handle the write back of the final address. */
1830 /* Writeback into R15 is UNPREDICTABLE. */
1832 fprintf (stderr
, "iWMMXt: writeback into r15\n");
1841 increment
= offset
* multiplier
;
1843 increment
= - (offset
* multiplier
);
1845 state
->Reg
[Rn
] = addr
+ increment
;
1850 /* P == 0, W == 0, U == 0 is UNPREDICTABLE. */
1854 fprintf (stderr
, "iWMMXt: undefined addressing mode\n");
1865 Iwmmxt_Load_Double_Word (ARMul_State
* state
, ARMword address
)
1869 /* The address must be aligned on a 8 byte boundary. */
1872 fprintf (stderr
, "iWMMXt: At addr 0x%x: Unaligned double word load from 0x%x\n",
1873 (state
->Reg
[15] - 8) & ~0x3, address
);
1876 /* No need to check for alignment traps. An unaligned
1877 double word load with alignment trapping disabled is
1879 ARMul_Abort (state
, ARMul_DataAbortV
);
1882 /* Load the words. */
1883 if (! state
->bigendSig
)
1885 value
= ARMul_LoadWordN (state
, address
+ 4);
1887 value
|= ARMul_LoadWordN (state
, address
);
1891 value
= ARMul_LoadWordN (state
, address
);
1893 value
|= ARMul_LoadWordN (state
, address
+ 4);
1896 /* Check for data aborts. */
1898 ARMul_Abort (state
, ARMul_DataAbortV
);
1900 ARMul_Icycles (state
, 2, 0L);
1906 Iwmmxt_Load_Word (ARMul_State
* state
, ARMword address
)
1910 /* Check for a misaligned address. */
1913 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN
))
1914 ARMul_Abort (state
, ARMul_DataAbortV
);
1919 value
= ARMul_LoadWordN (state
, address
);
1922 ARMul_Abort (state
, ARMul_DataAbortV
);
1924 ARMul_Icycles (state
, 1, 0L);
1930 Iwmmxt_Load_Half_Word (ARMul_State
* state
, ARMword address
)
1934 /* Check for a misaligned address. */
1937 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN
))
1938 ARMul_Abort (state
, ARMul_DataAbortV
);
1943 value
= ARMul_LoadHalfWord (state
, address
);
1946 ARMul_Abort (state
, ARMul_DataAbortV
);
1948 ARMul_Icycles (state
, 1, 0L);
1954 Iwmmxt_Load_Byte (ARMul_State
* state
, ARMword address
)
1958 value
= ARMul_LoadByte (state
, address
);
1961 ARMul_Abort (state
, ARMul_DataAbortV
);
1963 ARMul_Icycles (state
, 1, 0L);
1969 Iwmmxt_Store_Double_Word (ARMul_State
* state
, ARMword address
, ARMdword value
)
1971 /* The address must be aligned on a 8 byte boundary. */
1974 fprintf (stderr
, "iWMMXt: At addr 0x%x: Unaligned double word store to 0x%x\n",
1975 (state
->Reg
[15] - 8) & ~0x3, address
);
1978 /* No need to check for alignment traps. An unaligned
1979 double word store with alignment trapping disabled is
1981 ARMul_Abort (state
, ARMul_DataAbortV
);
1984 /* Store the words. */
1985 if (! state
->bigendSig
)
1987 ARMul_StoreWordN (state
, address
, value
);
1988 ARMul_StoreWordN (state
, address
+ 4, value
>> 32);
1992 ARMul_StoreWordN (state
, address
+ 4, value
);
1993 ARMul_StoreWordN (state
, address
, value
>> 32);
1996 /* Check for data aborts. */
1998 ARMul_Abort (state
, ARMul_DataAbortV
);
2000 ARMul_Icycles (state
, 2, 0L);
2004 Iwmmxt_Store_Word (ARMul_State
* state
, ARMword address
, ARMword value
)
2006 /* Check for a misaligned address. */
2009 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN
))
2010 ARMul_Abort (state
, ARMul_DataAbortV
);
2015 ARMul_StoreWordN (state
, address
, value
);
2018 ARMul_Abort (state
, ARMul_DataAbortV
);
2022 Iwmmxt_Store_Half_Word (ARMul_State
* state
, ARMword address
, ARMword value
)
2024 /* Check for a misaligned address. */
2027 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN
))
2028 ARMul_Abort (state
, ARMul_DataAbortV
);
2033 ARMul_StoreHalfWord (state
, address
, value
);
2036 ARMul_Abort (state
, ARMul_DataAbortV
);
2040 Iwmmxt_Store_Byte (ARMul_State
* state
, ARMword address
, ARMword value
)
2042 ARMul_StoreByte (state
, address
, value
);
2045 ARMul_Abort (state
, ARMul_DataAbortV
);
2049 WLDR (ARMul_State
* state
, ARMword instr
)
2054 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2058 fprintf (stderr
, "wldr\n");
2061 address
= Compute_Iwmmxt_Address (state
, instr
, & failed
);
2065 if (BITS (28, 31) == 0xf)
2068 wC
[BITS (12, 15)] = Iwmmxt_Load_Word (state
, address
);
2070 else if (BIT (8) == 0)
2074 wR
[BITS (12, 15)] = Iwmmxt_Load_Byte (state
, address
);
2077 wR
[BITS (12, 15)] = Iwmmxt_Load_Half_Word (state
, address
);
2083 wR
[BITS (12, 15)] = Iwmmxt_Load_Word (state
, address
);
2086 wR
[BITS (12, 15)] = Iwmmxt_Load_Double_Word (state
, address
);
2089 wC
[wCon
] |= WCON_MUP
;
2095 WMAC (ARMword instr
)
2101 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2105 fprintf (stderr
, "wmac\n");
2108 for (i
= 0; i
< 4; i
++)
2115 a
= wRHALF (BITS (16, 19), i
);
2118 b
= wRHALF (BITS (0, 3), i
);
2121 s
= (signed long) a
* (signed long) b
;
2123 t
= t
+ (ARMdword
) s
;
2128 a
= wRHALF (BITS (16, 19), i
);
2129 b
= wRHALF (BITS ( 0, 3), i
);
2141 wR
[BITS (12, 15)] = t
;
2143 wR
[BITS (12, 15)] += t
;
2145 wC
[wCon
] |= WCON_MUP
;
2151 WMADD (ARMword instr
)
2156 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2160 fprintf (stderr
, "wmadd\n");
2163 for (i
= 0; i
< 2; i
++)
2167 if (BIT (21)) /* Signed. */
2171 a
= wRHALF (BITS (16, 19), i
* 2);
2174 b
= wRHALF (BITS (0, 3), i
* 2);
2177 s1
= (ARMdword
) (a
* b
);
2179 a
= wRHALF (BITS (16, 19), i
* 2 + 1);
2182 b
= wRHALF (BITS (0, 3), i
* 2 + 1);
2185 s2
= (ARMdword
) (a
* b
);
2187 else /* Unsigned. */
2191 a
= wRHALF (BITS (16, 19), i
* 2);
2192 b
= wRHALF (BITS ( 0, 3), i
* 2);
2194 s1
= (ARMdword
) (a
* b
);
2196 a
= wRHALF (BITS (16, 19), i
* 2 + 1);
2197 b
= wRHALF (BITS ( 0, 3), i
* 2 + 1);
2199 s2
= (ARMdword
) a
* b
;
2202 r
|= (ARMdword
) ((s1
+ s2
) & 0xffffffff) << (i
? 32 : 0);
2205 wR
[BITS (12, 15)] = r
;
2206 wC
[wCon
] |= WCON_MUP
;
2212 WMAX (ARMul_State
* state
, ARMword instr
)
2218 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2222 fprintf (stderr
, "wmax\n");
2225 switch (BITS (22, 23))
2228 for (i
= 0; i
< 8; i
++)
2229 if (BIT (21)) /* Signed. */
2233 a
= wRBYTE (BITS (16, 19), i
);
2236 b
= wRBYTE (BITS (0, 3), i
);
2244 r
|= (s
& 0xff) << (i
* 8);
2246 else /* Unsigned. */
2250 a
= wRBYTE (BITS (16, 19), i
);
2251 b
= wRBYTE (BITS (0, 3), i
);
2258 r
|= (s
& 0xff) << (i
* 8);
2263 for (i
= 0; i
< 4; i
++)
2264 if (BIT (21)) /* Signed. */
2268 a
= wRHALF (BITS (16, 19), i
);
2271 b
= wRHALF (BITS (0, 3), i
);
2279 r
|= (s
& 0xffff) << (i
* 16);
2281 else /* Unsigned. */
2285 a
= wRHALF (BITS (16, 19), i
);
2286 b
= wRHALF (BITS (0, 3), i
);
2293 r
|= (s
& 0xffff) << (i
* 16);
2298 for (i
= 0; i
< 2; i
++)
2299 if (BIT (21)) /* Signed. */
2303 a
= wRWORD (BITS (16, 19), i
);
2304 b
= wRWORD (BITS (0, 3), i
);
2311 r
|= (s
& 0xffffffff) << (i
* 32);
2317 a
= wRWORD (BITS (16, 19), i
);
2318 b
= wRWORD (BITS (0, 3), i
);
2325 r
|= (s
& 0xffffffff) << (i
* 32);
2330 ARMul_UndefInstr (state
, instr
);
2334 wR
[BITS (12, 15)] = r
;
2335 wC
[wCon
] |= WCON_MUP
;
2341 WMIN (ARMul_State
* state
, ARMword instr
)
2347 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2351 fprintf (stderr
, "wmin\n");
2354 switch (BITS (22, 23))
2357 for (i
= 0; i
< 8; i
++)
2358 if (BIT (21)) /* Signed. */
2362 a
= wRBYTE (BITS (16, 19), i
);
2365 b
= wRBYTE (BITS (0, 3), i
);
2373 r
|= (s
& 0xff) << (i
* 8);
2375 else /* Unsigned. */
2379 a
= wRBYTE (BITS (16, 19), i
);
2380 b
= wRBYTE (BITS (0, 3), i
);
2387 r
|= (s
& 0xff) << (i
* 8);
2392 for (i
= 0; i
< 4; i
++)
2393 if (BIT (21)) /* Signed. */
2397 a
= wRHALF (BITS (16, 19), i
);
2400 b
= wRHALF (BITS (0, 3), i
);
2408 r
|= (s
& 0xffff) << (i
* 16);
2415 a
= wRHALF (BITS (16, 19), i
);
2416 b
= wRHALF (BITS ( 0, 3), i
);
2423 r
|= (s
& 0xffff) << (i
* 16);
2428 for (i
= 0; i
< 2; i
++)
2429 if (BIT (21)) /* Signed. */
2433 a
= wRWORD (BITS (16, 19), i
);
2434 b
= wRWORD (BITS ( 0, 3), i
);
2441 r
|= (s
& 0xffffffff) << (i
* 32);
2447 a
= wRWORD (BITS (16, 19), i
);
2448 b
= wRWORD (BITS (0, 3), i
);
2455 r
|= (s
& 0xffffffff) << (i
* 32);
2460 ARMul_UndefInstr (state
, instr
);
2464 wR
[BITS (12, 15)] = r
;
2465 wC
[wCon
] |= WCON_MUP
;
2471 WMUL (ARMword instr
)
2477 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2481 fprintf (stderr
, "wmul\n");
2484 for (i
= 0; i
< 4; i
++)
2485 if (BIT (21)) /* Signed. */
2489 a
= wRHALF (BITS (16, 19), i
);
2492 b
= wRHALF (BITS (0, 3), i
);
2498 r
|= ((s
>> 16) & 0xffff) << (i
* 16);
2500 r
|= (s
& 0xffff) << (i
* 16);
2502 else /* Unsigned. */
2506 a
= wRHALF (BITS (16, 19), i
);
2507 b
= wRHALF (BITS (0, 3), i
);
2512 r
|= ((s
>> 16) & 0xffff) << (i
* 16);
2514 r
|= (s
& 0xffff) << (i
* 16);
2517 wR
[BITS (12, 15)] = r
;
2518 wC
[wCon
] |= WCON_MUP
;
2529 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2533 fprintf (stderr
, "wor\n");
2536 result
= wR
[BITS (16, 19)] | wR
[BITS (0, 3)];
2537 wR
[BITS (12, 15)] = result
;
2539 SIMD64_SET (psr
, (result
== 0), SIMD_ZBIT
);
2540 SIMD64_SET (psr
, (result
& (1ULL << 63)), SIMD_NBIT
);
2543 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2549 WPACK (ARMul_State
* state
, ARMword instr
)
2558 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2562 fprintf (stderr
, "wpack\n");
2565 switch (BITS (22, 23))
2568 for (i
= 0; i
< 8; i
++)
2570 x
= wRHALF (i
< 4 ? BITS (16, 19) : BITS (0, 3), i
& 3);
2572 switch (BITS (20, 21))
2574 case UnsignedSaturation
:
2575 s
= IwmmxtSaturateU8 (x
, satrv
+ BITIDX8 (i
));
2578 case SignedSaturation
:
2579 s
= IwmmxtSaturateS8 (x
, satrv
+ BITIDX8 (i
));
2583 ARMul_UndefInstr (state
, instr
);
2587 r
|= (s
& 0xff) << (i
* 8);
2588 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
2589 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
2594 satrv
[0] = satrv
[2] = satrv
[4] = satrv
[6] = 0;
2596 for (i
= 0; i
< 4; i
++)
2598 x
= wRWORD (i
< 2 ? BITS (16, 19) : BITS (0, 3), i
& 1);
2600 switch (BITS (20, 21))
2602 case UnsignedSaturation
:
2603 s
= IwmmxtSaturateU16 (x
, satrv
+ BITIDX16 (i
));
2606 case SignedSaturation
:
2607 s
= IwmmxtSaturateS16 (x
, satrv
+ BITIDX16 (i
));
2611 ARMul_UndefInstr (state
, instr
);
2615 r
|= (s
& 0xffff) << (i
* 16);
2616 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2617 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2622 satrv
[0] = satrv
[1] = satrv
[2] = satrv
[4] = satrv
[5] = satrv
[6] = 0;
2624 for (i
= 0; i
< 2; i
++)
2626 x
= wR
[i
? BITS (0, 3) : BITS (16, 19)];
2628 switch (BITS (20, 21))
2630 case UnsignedSaturation
:
2631 s
= IwmmxtSaturateU32 (x
, satrv
+ BITIDX32 (i
));
2634 case SignedSaturation
:
2635 s
= IwmmxtSaturateS32 (x
, satrv
+ BITIDX32 (i
));
2639 ARMul_UndefInstr (state
, instr
);
2643 r
|= (s
& 0xffffffff) << (i
* 32);
2644 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
2645 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
2650 ARMul_UndefInstr (state
, instr
);
2655 wR
[BITS (12, 15)] = r
;
2656 SET_wCSSFvec (satrv
);
2657 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2663 WROR (ARMul_State
* state
, ARMword instr
)
2671 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2675 fprintf (stderr
, "wror\n");
2678 DECODE_G_BIT (state
, instr
, shift
);
2680 switch (BITS (22, 23))
2684 for (i
= 0; i
< 4; i
++)
2686 s
= ((wRHALF (BITS (16, 19), i
) & 0xffff) << (16 - shift
))
2687 | ((wRHALF (BITS (16, 19), i
) & 0xffff) >> shift
);
2688 r
|= (s
& 0xffff) << (i
* 16);
2689 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2690 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2696 for (i
= 0; i
< 2; i
++)
2698 s
= ((wRWORD (BITS (16, 19), i
) & 0xffffffff) << (32 - shift
))
2699 | ((wRWORD (BITS (16, 19), i
) & 0xffffffff) >> shift
);
2700 r
|= (s
& 0xffffffff) << (i
* 32);
2701 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
2702 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
2708 r
= (wR
[BITS (16, 19)] >> shift
)
2709 | (wR
[BITS (16, 19)] << (64 - shift
));
2711 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
2712 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
2716 ARMul_UndefInstr (state
, instr
);
2721 wR
[BITS (12, 15)] = r
;
2722 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2728 WSAD (ARMword instr
)
2734 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2738 fprintf (stderr
, "wsad\n");
2742 r
= BIT (20) ? 0 : (wR
[BITS (12, 15)] & 0xffffffff);
2746 for (i
= 0; i
< 4; i
++)
2748 s
= (wRHALF (BITS (16, 19), i
) - wRHALF (BITS (0, 3), i
));
2753 for (i
= 0; i
< 8; i
++)
2755 s
= (wRBYTE (BITS (16, 19), i
) - wRBYTE (BITS (0, 3), i
));
2759 wR
[BITS (12, 15)] = r
;
2760 wC
[wCon
] |= WCON_MUP
;
2766 WSHUFH (ARMword instr
)
2774 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2778 fprintf (stderr
, "wshufh\n");
2781 imm8
= (BITS (20, 23) << 4) | BITS (0, 3);
2783 for (i
= 0; i
< 4; i
++)
2785 s
= wRHALF (BITS (16, 19), ((imm8
>> (i
* 2) & 3)) & 0xff);
2786 r
|= (s
& 0xffff) << (i
* 16);
2787 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2788 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2792 wR
[BITS (12, 15)] = r
;
2793 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2799 WSLL (ARMul_State
* state
, ARMword instr
)
2807 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2811 fprintf (stderr
, "wsll\n");
2814 DECODE_G_BIT (state
, instr
, shift
);
2816 switch (BITS (22, 23))
2819 for (i
= 0; i
< 4; i
++)
2824 s
= ((wRHALF (BITS (16, 19), i
) & 0xffff) << shift
);
2825 r
|= (s
& 0xffff) << (i
* 16);
2826 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2827 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2832 for (i
= 0; i
< 2; i
++)
2837 s
= ((wRWORD (BITS (16, 19), i
) & 0xffffffff) << shift
);
2838 r
|= (s
& 0xffffffff) << (i
* 32);
2839 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
2840 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
2848 r
= ((wR
[BITS (16, 19)] & 0xffffffffffffffffULL
) << shift
);
2850 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
2851 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
2855 ARMul_UndefInstr (state
, instr
);
2860 wR
[BITS (12, 15)] = r
;
2861 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2867 WSRA (ARMul_State
* state
, ARMword instr
)
2876 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2880 fprintf (stderr
, "wsra\n");
2883 DECODE_G_BIT (state
, instr
, shift
);
2885 switch (BITS (22, 23))
2888 for (i
= 0; i
< 4; i
++)
2891 t
= (wRHALF (BITS (16, 19), i
) & 0x8000) ? 0xffff : 0;
2894 t
= wRHALF (BITS (16, 19), i
);
2900 r
|= (s
& 0xffff) << (i
* 16);
2901 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2902 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2907 for (i
= 0; i
< 2; i
++)
2910 t
= (wRWORD (BITS (16, 19), i
) & 0x80000000) ? 0xffffffff : 0;
2913 t
= EXTEND32 (wRWORD (BITS (16, 19), i
));
2917 r
|= (s
& 0xffffffff) << (i
* 32);
2918 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
2919 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
2925 r
= (wR
[BITS (16, 19)] & 0x8000000000000000ULL
) ? 0xffffffffffffffffULL
: 0;
2927 r
= ((signed long long) (wR
[BITS (16, 19)] & 0xffffffffffffffffULL
) >> shift
);
2928 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
2929 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
2933 ARMul_UndefInstr (state
, instr
);
2938 wR
[BITS (12, 15)] = r
;
2939 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2945 WSRL (ARMul_State
* state
, ARMword instr
)
2953 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2957 fprintf (stderr
, "wsrl\n");
2960 DECODE_G_BIT (state
, instr
, shift
);
2962 switch (BITS (22, 23))
2965 for (i
= 0; i
< 4; i
++)
2970 s
= ((unsigned) (wRHALF (BITS (16, 19), i
) & 0xffff) >> shift
);
2972 r
|= (s
& 0xffff) << (i
* 16);
2973 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2974 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2979 for (i
= 0; i
< 2; i
++)
2984 s
= ((unsigned long) (wRWORD (BITS (16, 19), i
) & 0xffffffff) >> shift
);
2986 r
|= (s
& 0xffffffff) << (i
* 32);
2987 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
2988 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
2996 r
= (wR
[BITS (16, 19)] & 0xffffffffffffffffULL
) >> shift
;
2998 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
2999 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
3003 ARMul_UndefInstr (state
, instr
);
3008 wR
[BITS (12, 15)] = r
;
3009 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3015 WSTR (ARMul_State
* state
, ARMword instr
)
3021 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3025 fprintf (stderr
, "wstr\n");
3028 address
= Compute_Iwmmxt_Address (state
, instr
, & failed
);
3032 if (BITS (28, 31) == 0xf)
3035 Iwmmxt_Store_Word (state
, address
, wC
[BITS (12, 15)]);
3037 else if (BIT (8) == 0)
3041 Iwmmxt_Store_Byte (state
, address
, wR
[BITS (12, 15)]);
3044 Iwmmxt_Store_Half_Word (state
, address
, wR
[BITS (12, 15)]);
3050 Iwmmxt_Store_Word (state
, address
, wR
[BITS (12, 15)]);
3053 Iwmmxt_Store_Double_Word (state
, address
, wR
[BITS (12, 15)]);
3060 WSUB (ARMul_State
* state
, ARMword instr
)
3071 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3075 fprintf (stderr
, "wsub\n");
3078 /* Subtract two numbers using the specified function,
3079 leaving setting the carry bit as required. */
3080 #define SUBx(x, y, m, f) \
3081 (*f) (wRBITS (BITS (16, 19), (x), (y)) & (m), \
3082 wRBITS (BITS ( 0, 3), (x), (y)) & (m), & carry, & overflow)
3084 switch (BITS (22, 23))
3087 for (i
= 0; i
< 8; i
++)
3089 switch (BITS (20, 21))
3092 s
= SUBx ((i
* 8), (i
* 8) + 7, 0xff, SubS8
);
3093 satrv
[BITIDX8 (i
)] = 0;
3094 r
|= (s
& 0xff) << (i
* 8);
3095 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
3096 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
3097 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
3098 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
3101 case UnsignedSaturation
:
3102 s
= SUBx ((i
* 8), (i
* 8) + 7, 0xff, SubU8
);
3103 x
= IwmmxtSaturateU8 (s
, satrv
+ BITIDX8 (i
));
3104 r
|= (x
& 0xff) << (i
* 8);
3105 SIMD8_SET (psr
, NBIT8 (x
), SIMD_NBIT
, i
);
3106 SIMD8_SET (psr
, ZBIT8 (x
), SIMD_ZBIT
, i
);
3107 if (! satrv
[BITIDX8 (i
)])
3109 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
3110 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
3114 case SignedSaturation
:
3115 s
= SUBx ((i
* 8), (i
* 8) + 7, 0xff, SubS8
);
3116 x
= IwmmxtSaturateS8 (s
, satrv
+ BITIDX8 (i
));
3117 r
|= (x
& 0xff) << (i
* 8);
3118 SIMD8_SET (psr
, NBIT8 (x
), SIMD_NBIT
, i
);
3119 SIMD8_SET (psr
, ZBIT8 (x
), SIMD_ZBIT
, i
);
3120 if (! satrv
[BITIDX8 (i
)])
3122 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
3123 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
3128 ARMul_UndefInstr (state
, instr
);
3135 satrv
[0] = satrv
[2] = satrv
[4] = satrv
[6] = 0;
3137 for (i
= 0; i
< 4; i
++)
3139 switch (BITS (20, 21))
3142 s
= SUBx ((i
* 16), (i
* 16) + 15, 0xffff, SubU16
);
3143 satrv
[BITIDX16 (i
)] = 0;
3144 r
|= (s
& 0xffff) << (i
* 16);
3145 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
3146 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
3147 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
3148 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
3151 case UnsignedSaturation
:
3152 s
= SUBx ((i
* 16), (i
* 16) + 15, 0xffff, SubU16
);
3153 x
= IwmmxtSaturateU16 (s
, satrv
+ BITIDX16 (i
));
3154 r
|= (x
& 0xffff) << (i
* 16);
3155 SIMD16_SET (psr
, NBIT16 (x
& 0xffff), SIMD_NBIT
, i
);
3156 SIMD16_SET (psr
, ZBIT16 (x
), SIMD_ZBIT
, i
);
3157 if (! satrv
[BITIDX16 (i
)])
3159 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
3160 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
3164 case SignedSaturation
:
3165 s
= SUBx ((i
* 16), (i
* 16) + 15, 0xffff, SubS16
);
3166 x
= IwmmxtSaturateS16 (s
, satrv
+ BITIDX16 (i
));
3167 r
|= (x
& 0xffff) << (i
* 16);
3168 SIMD16_SET (psr
, NBIT16 (x
), SIMD_NBIT
, i
);
3169 SIMD16_SET (psr
, ZBIT16 (x
), SIMD_ZBIT
, i
);
3170 if (! satrv
[BITIDX16 (i
)])
3172 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
3173 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
3178 ARMul_UndefInstr (state
, instr
);
3185 satrv
[0] = satrv
[1] = satrv
[2] = satrv
[4] = satrv
[5] = satrv
[6] = 0;
3187 for (i
= 0; i
< 2; i
++)
3189 switch (BITS (20, 21))
3192 s
= SUBx ((i
* 32), (i
* 32) + 31, 0xffffffff, SubU32
);
3193 satrv
[BITIDX32 (i
)] = 0;
3194 r
|= (s
& 0xffffffff) << (i
* 32);
3195 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
3196 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
3197 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
3198 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
3201 case UnsignedSaturation
:
3202 s
= SUBx ((i
* 32), (i
* 32) + 31, 0xffffffff, SubU32
);
3203 x
= IwmmxtSaturateU32 (s
, satrv
+ BITIDX32 (i
));
3204 r
|= (x
& 0xffffffff) << (i
* 32);
3205 SIMD32_SET (psr
, NBIT32 (x
), SIMD_NBIT
, i
);
3206 SIMD32_SET (psr
, ZBIT32 (x
), SIMD_ZBIT
, i
);
3207 if (! satrv
[BITIDX32 (i
)])
3209 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
3210 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
3214 case SignedSaturation
:
3215 s
= SUBx ((i
* 32), (i
* 32) + 31, 0xffffffff, SubS32
);
3216 x
= IwmmxtSaturateS32 (s
, satrv
+ BITIDX32 (i
));
3217 r
|= (x
& 0xffffffff) << (i
* 32);
3218 SIMD32_SET (psr
, NBIT32 (x
), SIMD_NBIT
, i
);
3219 SIMD32_SET (psr
, ZBIT32 (x
), SIMD_ZBIT
, i
);
3220 if (! satrv
[BITIDX32 (i
)])
3222 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
3223 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
3228 ARMul_UndefInstr (state
, instr
);
3235 ARMul_UndefInstr (state
, instr
);
3239 wR
[BITS (12, 15)] = r
;
3241 SET_wCSSFvec (satrv
);
3242 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3250 WUNPCKEH (ARMul_State
* state
, ARMword instr
)
3257 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3261 fprintf (stderr
, "wunpckeh\n");
3264 switch (BITS (22, 23))
3267 for (i
= 0; i
< 4; i
++)
3269 s
= wRBYTE (BITS (16, 19), i
+ 4);
3271 if (BIT (21) && NBIT8 (s
))
3274 r
|= (s
& 0xffff) << (i
* 16);
3275 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
3276 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
3281 for (i
= 0; i
< 2; i
++)
3283 s
= wRHALF (BITS (16, 19), i
+ 2);
3285 if (BIT (21) && NBIT16 (s
))
3288 r
|= (s
& 0xffffffff) << (i
* 32);
3289 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
3290 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
3295 r
= wRWORD (BITS (16, 19), 1);
3297 if (BIT (21) && NBIT32 (r
))
3298 r
|= 0xffffffff00000000ULL
;
3300 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
3301 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
3305 ARMul_UndefInstr (state
, instr
);
3310 wR
[BITS (12, 15)] = r
;
3311 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3317 WUNPCKEL (ARMul_State
* state
, ARMword instr
)
3324 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3328 fprintf (stderr
, "wunpckel\n");
3331 switch (BITS (22, 23))
3334 for (i
= 0; i
< 4; i
++)
3336 s
= wRBYTE (BITS (16, 19), i
);
3338 if (BIT (21) && NBIT8 (s
))
3341 r
|= (s
& 0xffff) << (i
* 16);
3342 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
3343 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
3348 for (i
= 0; i
< 2; i
++)
3350 s
= wRHALF (BITS (16, 19), i
);
3352 if (BIT (21) && NBIT16 (s
))
3355 r
|= (s
& 0xffffffff) << (i
* 32);
3356 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
3357 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
3362 r
= wRWORD (BITS (16, 19), 0);
3364 if (BIT (21) && NBIT32 (r
))
3365 r
|= 0xffffffff00000000ULL
;
3367 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
3368 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
3372 ARMul_UndefInstr (state
, instr
);
3377 wR
[BITS (12, 15)] = r
;
3378 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3384 WUNPCKIH (ARMul_State
* state
, ARMword instr
)
3392 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3396 fprintf (stderr
, "wunpckih\n");
3399 switch (BITS (22, 23))
3402 for (i
= 0; i
< 4; i
++)
3404 a
= wRBYTE (BITS (16, 19), i
+ 4);
3405 b
= wRBYTE (BITS ( 0, 3), i
+ 4);
3407 r
|= (s
& 0xffff) << (i
* 16);
3408 SIMD8_SET (psr
, NBIT8 (a
), SIMD_NBIT
, i
* 2);
3409 SIMD8_SET (psr
, ZBIT8 (a
), SIMD_ZBIT
, i
* 2);
3410 SIMD8_SET (psr
, NBIT8 (b
), SIMD_NBIT
, (i
* 2) + 1);
3411 SIMD8_SET (psr
, ZBIT8 (b
), SIMD_ZBIT
, (i
* 2) + 1);
3416 for (i
= 0; i
< 2; i
++)
3418 a
= wRHALF (BITS (16, 19), i
+ 2);
3419 b
= wRHALF (BITS ( 0, 3), i
+ 2);
3421 r
|= (s
& 0xffffffff) << (i
* 32);
3422 SIMD16_SET (psr
, NBIT16 (a
), SIMD_NBIT
, (i
* 2));
3423 SIMD16_SET (psr
, ZBIT16 (a
), SIMD_ZBIT
, (i
* 2));
3424 SIMD16_SET (psr
, NBIT16 (b
), SIMD_NBIT
, (i
* 2) + 1);
3425 SIMD16_SET (psr
, ZBIT16 (b
), SIMD_ZBIT
, (i
* 2) + 1);
3430 a
= wRWORD (BITS (16, 19), 1);
3431 s
= wRWORD (BITS ( 0, 3), 1);
3434 SIMD32_SET (psr
, NBIT32 (a
), SIMD_NBIT
, 0);
3435 SIMD32_SET (psr
, ZBIT32 (a
), SIMD_ZBIT
, 0);
3436 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, 1);
3437 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, 1);
3441 ARMul_UndefInstr (state
, instr
);
3446 wR
[BITS (12, 15)] = r
;
3447 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3453 WUNPCKIL (ARMul_State
* state
, ARMword instr
)
3461 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3465 fprintf (stderr
, "wunpckil\n");
3468 switch (BITS (22, 23))
3471 for (i
= 0; i
< 4; i
++)
3473 a
= wRBYTE (BITS (16, 19), i
);
3474 b
= wRBYTE (BITS ( 0, 3), i
);
3476 r
|= (s
& 0xffff) << (i
* 16);
3477 SIMD8_SET (psr
, NBIT8 (a
), SIMD_NBIT
, i
* 2);
3478 SIMD8_SET (psr
, ZBIT8 (a
), SIMD_ZBIT
, i
* 2);
3479 SIMD8_SET (psr
, NBIT8 (b
), SIMD_NBIT
, (i
* 2) + 1);
3480 SIMD8_SET (psr
, ZBIT8 (b
), SIMD_ZBIT
, (i
* 2) + 1);
3485 for (i
= 0; i
< 2; i
++)
3487 a
= wRHALF (BITS (16, 19), i
);
3488 b
= wRHALF (BITS ( 0, 3), i
);
3490 r
|= (s
& 0xffffffff) << (i
* 32);
3491 SIMD16_SET (psr
, NBIT16 (a
), SIMD_NBIT
, (i
* 2));
3492 SIMD16_SET (psr
, ZBIT16 (a
), SIMD_ZBIT
, (i
* 2));
3493 SIMD16_SET (psr
, NBIT16 (b
), SIMD_NBIT
, (i
* 2) + 1);
3494 SIMD16_SET (psr
, ZBIT16 (b
), SIMD_ZBIT
, (i
* 2) + 1);
3499 a
= wRWORD (BITS (16, 19), 0);
3500 s
= wRWORD (BITS ( 0, 3), 0);
3503 SIMD32_SET (psr
, NBIT32 (a
), SIMD_NBIT
, 0);
3504 SIMD32_SET (psr
, ZBIT32 (a
), SIMD_ZBIT
, 0);
3505 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, 1);
3506 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, 1);
3510 ARMul_UndefInstr (state
, instr
);
3515 wR
[BITS (12, 15)] = r
;
3516 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3522 WXOR (ARMword instr
)
3527 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3531 fprintf (stderr
, "wxor\n");
3534 result
= wR
[BITS (16, 19)] ^ wR
[BITS (0, 3)];
3535 wR
[BITS (12, 15)] = result
;
3537 SIMD64_SET (psr
, (result
== 0), SIMD_ZBIT
);
3538 SIMD64_SET (psr
, (result
& (1ULL << 63)), SIMD_NBIT
);
3541 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3546 /* This switch table is moved to a separate function in order
3547 to work around a compiler bug in the host compiler... */
3550 Process_Instruction (ARMul_State
* state
, ARMword instr
)
3552 int status
= ARMul_BUSY
;
3554 switch ((BITS (20, 23) << 8) | BITS (4, 11))
3556 case 0x000: status
= WOR (instr
); break;
3557 case 0x011: status
= TMCR (state
, instr
); break;
3558 case 0x100: status
= WXOR (instr
); break;
3559 case 0x111: status
= TMRC (state
, instr
); break;
3560 case 0x300: status
= WANDN (instr
); break;
3561 case 0x200: status
= WAND (instr
); break;
3563 case 0x810: case 0xa10:
3564 status
= WMADD (instr
); break;
3566 case 0x10e: case 0x50e: case 0x90e: case 0xd0e:
3567 status
= WUNPCKIL (state
, instr
); break;
3568 case 0x10c: case 0x50c: case 0x90c: case 0xd0c:
3569 status
= WUNPCKIH (state
, instr
); break;
3570 case 0x012: case 0x112: case 0x412: case 0x512:
3571 status
= WSAD (instr
); break;
3572 case 0x010: case 0x110: case 0x210: case 0x310:
3573 status
= WMUL (instr
); break;
3574 case 0x410: case 0x510: case 0x610: case 0x710:
3575 status
= WMAC (instr
); break;
3576 case 0x006: case 0x406: case 0x806: case 0xc06:
3577 status
= WCMPEQ (state
, instr
); break;
3578 case 0x800: case 0x900: case 0xc00: case 0xd00:
3579 status
= WAVG2 (instr
); break;
3580 case 0x802: case 0x902: case 0xa02: case 0xb02:
3581 status
= WALIGNR (state
, instr
); break;
3582 case 0x601: case 0x605: case 0x609: case 0x60d:
3583 status
= TINSR (state
, instr
); break;
3584 case 0x107: case 0x507: case 0x907: case 0xd07:
3585 status
= TEXTRM (state
, instr
); break;
3586 case 0x117: case 0x517: case 0x917: case 0xd17:
3587 status
= TEXTRC (state
, instr
); break;
3588 case 0x401: case 0x405: case 0x409: case 0x40d:
3589 status
= TBCST (state
, instr
); break;
3590 case 0x113: case 0x513: case 0x913: case 0xd13:
3591 status
= TANDC (state
, instr
); break;
3592 case 0x01c: case 0x41c: case 0x81c: case 0xc1c:
3593 status
= WACC (state
, instr
); break;
3594 case 0x115: case 0x515: case 0x915: case 0xd15:
3595 status
= TORC (state
, instr
); break;
3596 case 0x103: case 0x503: case 0x903: case 0xd03:
3597 status
= TMOVMSK (state
, instr
); break;
3598 case 0x106: case 0x306: case 0x506: case 0x706:
3599 case 0x906: case 0xb06: case 0xd06: case 0xf06:
3600 status
= WCMPGT (state
, instr
); break;
3601 case 0x00e: case 0x20e: case 0x40e: case 0x60e:
3602 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
3603 status
= WUNPCKEL (state
, instr
); break;
3604 case 0x00c: case 0x20c: case 0x40c: case 0x60c:
3605 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
3606 status
= WUNPCKEH (state
, instr
); break;
3607 case 0x204: case 0x604: case 0xa04: case 0xe04:
3608 case 0x214: case 0x614: case 0xa14: case 0xe14:
3609 status
= WSRL (state
, instr
); break;
3610 case 0x004: case 0x404: case 0x804: case 0xc04:
3611 case 0x014: case 0x414: case 0x814: case 0xc14:
3612 status
= WSRA (state
, instr
); break;
3613 case 0x104: case 0x504: case 0x904: case 0xd04:
3614 case 0x114: case 0x514: case 0x914: case 0xd14:
3615 status
= WSLL (state
, instr
); break;
3616 case 0x304: case 0x704: case 0xb04: case 0xf04:
3617 case 0x314: case 0x714: case 0xb14: case 0xf14:
3618 status
= WROR (state
, instr
); break;
3619 case 0x116: case 0x316: case 0x516: case 0x716:
3620 case 0x916: case 0xb16: case 0xd16: case 0xf16:
3621 status
= WMIN (state
, instr
); break;
3622 case 0x016: case 0x216: case 0x416: case 0x616:
3623 case 0x816: case 0xa16: case 0xc16: case 0xe16:
3624 status
= WMAX (state
, instr
); break;
3625 case 0x002: case 0x102: case 0x202: case 0x302:
3626 case 0x402: case 0x502: case 0x602: case 0x702:
3627 status
= WALIGNI (instr
); break;
3628 case 0x01a: case 0x11a: case 0x21a: case 0x31a:
3629 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
3630 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
3631 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
3632 status
= WSUB (state
, instr
); break;
3633 case 0x01e: case 0x11e: case 0x21e: case 0x31e:
3634 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
3635 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
3636 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
3637 status
= WSHUFH (instr
); break;
3638 case 0x018: case 0x118: case 0x218: case 0x318:
3639 case 0x418: case 0x518: case 0x618: case 0x718:
3640 case 0x818: case 0x918: case 0xa18: case 0xb18:
3641 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
3642 status
= WADD (state
, instr
); break;
3643 case 0x008: case 0x108: case 0x208: case 0x308:
3644 case 0x408: case 0x508: case 0x608: case 0x708:
3645 case 0x808: case 0x908: case 0xa08: case 0xb08:
3646 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
3647 status
= WPACK (state
, instr
); break;
3648 case 0x201: case 0x203: case 0x205: case 0x207:
3649 case 0x209: case 0x20b: case 0x20d: case 0x20f:
3650 case 0x211: case 0x213: case 0x215: case 0x217:
3651 case 0x219: case 0x21b: case 0x21d: case 0x21f:
3652 switch (BITS (16, 19))
3654 case 0x0: status
= TMIA (state
, instr
); break;
3655 case 0x8: status
= TMIAPH (state
, instr
); break;
3659 case 0xf: status
= TMIAxy (state
, instr
); break;
3669 /* Process a possibly Intel(r) Wireless MMX(tm) technology instruction.
3670 Return true if the instruction was handled. */
3673 ARMul_HandleIwmmxt (ARMul_State
* state
, ARMword instr
)
3675 int status
= ARMul_BUSY
;
3677 if (BITS (24, 27) == 0xe)
3679 status
= Process_Instruction (state
, instr
);
3681 else if (BITS (25, 27) == 0x6)
3683 if (BITS (4, 11) == 0x0 && BITS (20, 24) == 0x4)
3684 status
= TMCRR (state
, instr
);
3685 else if (BITS (9, 11) == 0x0)
3687 if (BIT (20) == 0x0)
3688 status
= WSTR (state
, instr
);
3689 else if (BITS (20, 24) == 0x5)
3690 status
= TMRRC (state
, instr
);
3692 status
= WLDR (state
, instr
);
3696 if (status
== ARMul_CANT
)
3698 /* If the instruction was a recognised but illegal,
3699 perform the abort here rather than returning false.
3700 If we return false then ARMul_MRC may be called which
3701 will still abort, but which also perform the register
3703 ARMul_Abort (state
, ARMul_UndefinedInstrV
);
3704 status
= ARMul_DONE
;
3707 return status
== ARMul_DONE
;
3711 Fetch_Iwmmxt_Register (unsigned int regnum
, unsigned char * memory
)
3715 memcpy (memory
, wC
+ (regnum
- 16), sizeof wC
[0]);
3716 return sizeof wC
[0];
3720 memcpy (memory
, wR
+ regnum
, sizeof wR
[0]);
3721 return sizeof wR
[0];
3726 Store_Iwmmxt_Register (unsigned int regnum
, const unsigned char * memory
)
3730 memcpy (wC
+ (regnum
- 16), memory
, sizeof wC
[0]);
3731 return sizeof wC
[0];
3735 memcpy (wR
+ regnum
, memory
, sizeof wR
[0]);
3736 return sizeof wR
[0];