1 /* iwmmxt.c -- Intel(r) Wireless MMX(tm) technology co-processor interface.
2 Copyright (C) 2002, 2007, 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4 Contributed by matthew green (mrg@redhat.com).
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
29 /* Intel(r) Wireless MMX(tm) technology co-processor.
30 It uses co-processor numbers (0 and 1). There are 16 vector registers wRx
31 and 16 control registers wCx. Co-processors 0 and 1 are used in MCR/MRC
32 to access wRx and wCx respectively. */
34 static ARMdword wR
[16];
35 static ARMword wC
[16] = { 0x69051010 };
37 #define SUBSTR(w,t,m,n) ((t)(w << ((sizeof (t) * 8 - 1) - (n))) \
38 >> (((sizeof (t) * 8 - 1) - (n)) + (m)))
39 #define wCBITS(w,x,y) SUBSTR (wC[w], ARMword, x, y)
40 #define wRBITS(w,x,y) SUBSTR (wR[w], ARMdword, x, y)
50 /* Bits in the wCon register. */
51 #define WCON_CUP (1 << 0)
52 #define WCON_MUP (1 << 1)
54 /* Set the SIMD wCASF flags for 8, 16, 32 or 64-bit operations. */
55 #define SIMD8_SET(x, v, n, b) (x) |= ((v != 0) << ((((b) + 1) * 4) + (n)))
56 #define SIMD16_SET(x, v, n, h) (x) |= ((v != 0) << ((((h) + 1) * 8) + (n)))
57 #define SIMD32_SET(x, v, n, w) (x) |= ((v != 0) << ((((w) + 1) * 16) + (n)))
58 #define SIMD64_SET(x, v, n) (x) |= ((v != 0) << (32 + (n)))
60 /* Flags to pass as "n" above. */
66 /* Various status bit macros. */
67 #define NBIT8(x) ((x) & 0x80)
68 #define NBIT16(x) ((x) & 0x8000)
69 #define NBIT32(x) ((x) & 0x80000000)
70 #define NBIT64(x) ((x) & 0x8000000000000000ULL)
71 #define ZBIT8(x) (((x) & 0xff) == 0)
72 #define ZBIT16(x) (((x) & 0xffff) == 0)
73 #define ZBIT32(x) (((x) & 0xffffffff) == 0)
74 #define ZBIT64(x) (x == 0)
76 /* Access byte/half/word "n" of register "x". */
77 #define wRBYTE(x,n) wRBITS ((x), (n) * 8, (n) * 8 + 7)
78 #define wRHALF(x,n) wRBITS ((x), (n) * 16, (n) * 16 + 15)
79 #define wRWORD(x,n) wRBITS ((x), (n) * 32, (n) * 32 + 31)
81 /* Macro to handle how the G bit selects wCGR registers. */
82 #define DECODE_G_BIT(state, instr, shift) \
88 if (BIT (8)) /* G */ \
90 if (reg < wCGR0 || reg > wCGR3) \
92 ARMul_UndefInstr (state, instr); \
103 /* Index calculations for the satrv[] array. */
104 #define BITIDX8(x) (x)
105 #define BITIDX16(x) (((x) + 1) * 2 - 1)
106 #define BITIDX32(x) (((x) + 1) * 4 - 1)
108 /* Sign extension macros. */
109 #define EXTEND8(a) ((a) & 0x80 ? ((a) | 0xffffff00) : (a))
110 #define EXTEND16(a) ((a) & 0x8000 ? ((a) | 0xffff0000) : (a))
111 #define EXTEND32(a) ((a) & 0x80000000ULL ? ((a) | 0xffffffff00000000ULL) : (a))
113 /* Set the wCSSF from 8 values. */
114 #define SET_wCSSF(a,b,c,d,e,f,g,h) \
115 wC[wCSSF] = (((h) != 0) << 7) | (((g) != 0) << 6) \
116 | (((f) != 0) << 5) | (((e) != 0) << 4) \
117 | (((d) != 0) << 3) | (((c) != 0) << 2) \
118 | (((b) != 0) << 1) | (((a) != 0) << 0);
120 /* Set the wCSSR from an array with 8 values. */
121 #define SET_wCSSFvec(v) \
122 SET_wCSSF((v)[0],(v)[1],(v)[2],(v)[3],(v)[4],(v)[5],(v)[6],(v)[7])
124 /* Size qualifiers for vector operations. */
130 /* Saturation qualifiers for vector operations. */
131 #define NoSaturation 0
132 #define UnsignedSaturation 1
133 #define SignedSaturation 3
137 static ARMword
Add32 (ARMword
, ARMword
, int *, int *, ARMword
);
138 static ARMdword
AddS32 (ARMdword
, ARMdword
, int *, int *);
139 static ARMdword
AddU32 (ARMdword
, ARMdword
, int *, int *);
140 static ARMword
AddS16 (ARMword
, ARMword
, int *, int *);
141 static ARMword
AddU16 (ARMword
, ARMword
, int *, int *);
142 static ARMword
AddS8 (ARMword
, ARMword
, int *, int *);
143 static ARMword
AddU8 (ARMword
, ARMword
, int *, int *);
144 static ARMword
Sub32 (ARMword
, ARMword
, int *, int *, ARMword
);
145 static ARMdword
SubS32 (ARMdword
, ARMdword
, int *, int *);
146 static ARMdword
SubU32 (ARMdword
, ARMdword
, int *, int *);
147 static ARMword
SubS16 (ARMword
, ARMword
, int *, int *);
148 static ARMword
SubS8 (ARMword
, ARMword
, int *, int *);
149 static ARMword
SubU16 (ARMword
, ARMword
, int *, int *);
150 static ARMword
SubU8 (ARMword
, ARMword
, int *, int *);
151 static unsigned char IwmmxtSaturateU8 (signed short, int *);
152 static signed char IwmmxtSaturateS8 (signed short, int *);
153 static unsigned short IwmmxtSaturateU16 (signed int, int *);
154 static signed short IwmmxtSaturateS16 (signed int, int *);
155 static unsigned long IwmmxtSaturateU32 (signed long long, int *);
156 static signed long IwmmxtSaturateS32 (signed long long, int *);
157 static ARMword
Compute_Iwmmxt_Address (ARMul_State
*, ARMword
, int *);
158 static ARMdword
Iwmmxt_Load_Double_Word (ARMul_State
*, ARMword
);
159 static ARMword
Iwmmxt_Load_Word (ARMul_State
*, ARMword
);
160 static ARMword
Iwmmxt_Load_Half_Word (ARMul_State
*, ARMword
);
161 static ARMword
Iwmmxt_Load_Byte (ARMul_State
*, ARMword
);
162 static void Iwmmxt_Store_Double_Word (ARMul_State
*, ARMword
, ARMdword
);
163 static void Iwmmxt_Store_Word (ARMul_State
*, ARMword
, ARMword
);
164 static void Iwmmxt_Store_Half_Word (ARMul_State
*, ARMword
, ARMword
);
165 static void Iwmmxt_Store_Byte (ARMul_State
*, ARMword
, ARMword
);
166 static int Process_Instruction (ARMul_State
*, ARMword
);
168 static int TANDC (ARMul_State
*, ARMword
);
169 static int TBCST (ARMul_State
*, ARMword
);
170 static int TEXTRC (ARMul_State
*, ARMword
);
171 static int TEXTRM (ARMul_State
*, ARMword
);
172 static int TINSR (ARMul_State
*, ARMword
);
173 static int TMCR (ARMul_State
*, ARMword
);
174 static int TMCRR (ARMul_State
*, ARMword
);
175 static int TMIA (ARMul_State
*, ARMword
);
176 static int TMIAPH (ARMul_State
*, ARMword
);
177 static int TMIAxy (ARMul_State
*, ARMword
);
178 static int TMOVMSK (ARMul_State
*, ARMword
);
179 static int TMRC (ARMul_State
*, ARMword
);
180 static int TMRRC (ARMul_State
*, ARMword
);
181 static int TORC (ARMul_State
*, ARMword
);
182 static int WACC (ARMul_State
*, ARMword
);
183 static int WADD (ARMul_State
*, ARMword
);
184 static int WALIGNI (ARMword
);
185 static int WALIGNR (ARMul_State
*, ARMword
);
186 static int WAND (ARMword
);
187 static int WANDN (ARMword
);
188 static int WAVG2 (ARMword
);
189 static int WCMPEQ (ARMul_State
*, ARMword
);
190 static int WCMPGT (ARMul_State
*, ARMword
);
191 static int WLDR (ARMul_State
*, ARMword
);
192 static int WMAC (ARMword
);
193 static int WMADD (ARMword
);
194 static int WMAX (ARMul_State
*, ARMword
);
195 static int WMIN (ARMul_State
*, ARMword
);
196 static int WMUL (ARMword
);
197 static int WOR (ARMword
);
198 static int WPACK (ARMul_State
*, ARMword
);
199 static int WROR (ARMul_State
*, ARMword
);
200 static int WSAD (ARMword
);
201 static int WSHUFH (ARMword
);
202 static int WSLL (ARMul_State
*, ARMword
);
203 static int WSRA (ARMul_State
*, ARMword
);
204 static int WSRL (ARMul_State
*, ARMword
);
205 static int WSTR (ARMul_State
*, ARMword
);
206 static int WSUB (ARMul_State
*, ARMword
);
207 static int WUNPCKEH (ARMul_State
*, ARMword
);
208 static int WUNPCKEL (ARMul_State
*, ARMword
);
209 static int WUNPCKIH (ARMul_State
*, ARMword
);
210 static int WUNPCKIL (ARMul_State
*, ARMword
);
211 static int WXOR (ARMword
);
213 /* This function does the work of adding two 32bit values
214 together, and calculating if a carry has occurred. */
223 ARMword result
= (a1
+ a2
);
224 unsigned int uresult
= (unsigned int) result
;
225 unsigned int ua1
= (unsigned int) a1
;
227 /* If (result == a1) and (a2 == 0),
228 or (result > a2) then we have no carry. */
229 * carry_ptr
= ((uresult
== ua1
) ? (a2
!= 0) : (uresult
< ua1
));
231 /* Overflow occurs when both arguments are the
232 same sign, but the result is a different sign. */
233 * overflow_ptr
= ( ( (result
& sign_mask
) && !(a1
& sign_mask
) && !(a2
& sign_mask
))
234 || (!(result
& sign_mask
) && (a1
& sign_mask
) && (a2
& sign_mask
)));
240 AddS32 (ARMdword a1
, ARMdword a2
, int * carry_ptr
, int * overflow_ptr
)
243 unsigned int uresult
;
250 uresult
= (unsigned int) result
;
251 ua1
= (unsigned int) a1
;
253 * carry_ptr
= ((uresult
== a1
) ? (a2
!= 0) : (uresult
< ua1
));
255 * overflow_ptr
= ( ( (result
& 0x80000000ULL
) && !(a1
& 0x80000000ULL
) && !(a2
& 0x80000000ULL
))
256 || (!(result
& 0x80000000ULL
) && (a1
& 0x80000000ULL
) && (a2
& 0x80000000ULL
)));
262 AddU32 (ARMdword a1
, ARMdword a2
, int * carry_ptr
, int * overflow_ptr
)
265 unsigned int uresult
;
272 uresult
= (unsigned int) result
;
273 ua1
= (unsigned int) a1
;
275 * carry_ptr
= ((uresult
== a1
) ? (a2
!= 0) : (uresult
< ua1
));
277 * overflow_ptr
= ( ( (result
& 0x80000000ULL
) && !(a1
& 0x80000000ULL
) && !(a2
& 0x80000000ULL
))
278 || (!(result
& 0x80000000ULL
) && (a1
& 0x80000000ULL
) && (a2
& 0x80000000ULL
)));
284 AddS16 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
289 return Add32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x8000);
293 AddU16 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
298 return Add32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x8000);
302 AddS8 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
307 return Add32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x80);
311 AddU8 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
316 return Add32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x80);
326 ARMword result
= (a1
- a2
);
327 unsigned int ua1
= (unsigned int) a1
;
328 unsigned int ua2
= (unsigned int) a2
;
330 /* A borrow occurs if a2 is (unsigned) larger than a1.
331 However the carry flag is *cleared* if a borrow occurs. */
332 * borrow_ptr
= ! (ua2
> ua1
);
334 /* Overflow occurs when a negative number is subtracted from a
335 positive number and the result is negative or a positive
336 number is subtracted from a negative number and the result is
338 * overflow_ptr
= ( (! (a1
& sign_mask
) && (a2
& sign_mask
) && (result
& sign_mask
))
339 || ((a1
& sign_mask
) && ! (a2
& sign_mask
) && ! (result
& sign_mask
)));
345 SubS32 (ARMdword a1
, ARMdword a2
, int * borrow_ptr
, int * overflow_ptr
)
355 ua1
= (unsigned int) a1
;
356 ua2
= (unsigned int) a2
;
358 * borrow_ptr
= ! (ua2
> ua1
);
360 * overflow_ptr
= ( (! (a1
& 0x80000000ULL
) && (a2
& 0x80000000ULL
) && (result
& 0x80000000ULL
))
361 || ((a1
& 0x80000000ULL
) && ! (a2
& 0x80000000ULL
) && ! (result
& 0x80000000ULL
)));
367 SubS16 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
372 return Sub32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x8000);
376 SubS8 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
381 return Sub32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x80);
385 SubU16 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
390 return Sub32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x8000);
394 SubU8 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
399 return Sub32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x80);
403 SubU32 (ARMdword a1
, ARMdword a2
, int * borrow_ptr
, int * overflow_ptr
)
413 ua1
= (unsigned int) a1
;
414 ua2
= (unsigned int) a2
;
416 * borrow_ptr
= ! (ua2
> ua1
);
418 * overflow_ptr
= ( (! (a1
& 0x80000000ULL
) && (a2
& 0x80000000ULL
) && (result
& 0x80000000ULL
))
419 || ((a1
& 0x80000000ULL
) && ! (a2
& 0x80000000ULL
) && ! (result
& 0x80000000ULL
)));
424 /* For the saturation. */
427 IwmmxtSaturateU8 (signed short val
, int * sat
)
450 IwmmxtSaturateS8 (signed short val
, int * sat
)
472 static unsigned short
473 IwmmxtSaturateU16 (signed int val
, int * sat
)
482 else if (val
> 0xffff)
496 IwmmxtSaturateS16 (signed int val
, int * sat
)
505 else if (val
> 0x7fff)
519 IwmmxtSaturateU32 (signed long long val
, int * sat
)
528 else if (val
> 0xffffffff)
535 rv
= val
& 0xffffffff;
542 IwmmxtSaturateS32 (signed long long val
, int * sat
)
546 if (val
< -0x80000000LL
)
551 else if (val
> 0x7fffffff)
558 rv
= val
& 0xffffffff;
564 /* Intel(r) Wireless MMX(tm) technology Acessor functions. */
567 IwmmxtLDC (ARMul_State
* state ATTRIBUTE_UNUSED
,
568 unsigned type ATTRIBUTE_UNUSED
,
576 IwmmxtSTC (ARMul_State
* state ATTRIBUTE_UNUSED
,
577 unsigned type ATTRIBUTE_UNUSED
,
585 IwmmxtMRC (ARMul_State
* state ATTRIBUTE_UNUSED
,
586 unsigned type ATTRIBUTE_UNUSED
,
594 IwmmxtMCR (ARMul_State
* state ATTRIBUTE_UNUSED
,
595 unsigned type ATTRIBUTE_UNUSED
,
603 IwmmxtCDP (ARMul_State
* state
, unsigned type
, ARMword instr
)
608 /* Intel(r) Wireless MMX(tm) technology instruction implementations. */
611 TANDC (ARMul_State
* state
, ARMword instr
)
615 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
619 fprintf (stderr
, "tandc\n");
622 /* The Rd field must be r15. */
623 if (BITS (12, 15) != 15)
626 /* The CRn field must be r3. */
627 if (BITS (16, 19) != 3)
630 /* The CRm field must be r0. */
631 if (BITS (0, 3) != 0)
634 cpsr
= ARMul_GetCPSR (state
) & 0x0fffffff;
636 switch (BITS (22, 23))
639 cpsr
|= ( (wCBITS (wCASF
, 28, 31) & wCBITS (wCASF
, 24, 27)
640 & wCBITS (wCASF
, 20, 23) & wCBITS (wCASF
, 16, 19)
641 & wCBITS (wCASF
, 12, 15) & wCBITS (wCASF
, 8, 11)
642 & wCBITS (wCASF
, 4, 7) & wCBITS (wCASF
, 0, 3)) << 28);
646 cpsr
|= ( (wCBITS (wCASF
, 28, 31) & wCBITS (wCASF
, 20, 23)
647 & wCBITS (wCASF
, 12, 15) & wCBITS (wCASF
, 4, 7)) << 28);
651 cpsr
|= ((wCBITS (wCASF
, 28, 31) & wCBITS (wCASF
, 12, 15)) << 28);
655 ARMul_UndefInstr (state
, instr
);
659 ARMul_SetCPSR (state
, cpsr
);
665 TBCST (ARMul_State
* state
, ARMword instr
)
670 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
674 fprintf (stderr
, "tbcst\n");
677 Rn
= state
->Reg
[BITS (12, 15)];
678 if (BITS (12, 15) == 15)
687 wR
[wRd
] = (Rn
<< 56) | (Rn
<< 48) | (Rn
<< 40) | (Rn
<< 32)
688 | (Rn
<< 24) | (Rn
<< 16) | (Rn
<< 8) | Rn
;
693 wR
[wRd
] = (Rn
<< 48) | (Rn
<< 32) | (Rn
<< 16) | Rn
;
698 wR
[wRd
] = (Rn
<< 32) | Rn
;
702 ARMul_UndefInstr (state
, instr
);
706 wC
[wCon
] |= WCON_MUP
;
711 TEXTRC (ARMul_State
* state
, ARMword instr
)
716 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
720 fprintf (stderr
, "textrc\n");
723 /* The Rd field must be r15. */
724 if (BITS (12, 15) != 15)
727 /* The CRn field must be r3. */
728 if (BITS (16, 19) != 3)
731 /* The CRm field must be 0xxx. */
735 selector
= BITS (0, 2);
736 cpsr
= ARMul_GetCPSR (state
) & 0x0fffffff;
738 switch (BITS (22, 23))
740 case Bqual
: selector
*= 4; break;
741 case Hqual
: selector
= ((selector
& 3) * 8) + 4; break;
742 case Wqual
: selector
= ((selector
& 1) * 16) + 12; break;
745 ARMul_UndefInstr (state
, instr
);
749 cpsr
|= wCBITS (wCASF
, selector
, selector
+ 3) << 28;
750 ARMul_SetCPSR (state
, cpsr
);
756 TEXTRM (ARMul_State
* state
, ARMword instr
)
763 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
767 fprintf (stderr
, "textrm\n");
772 offset
= BITS (0, 2);
774 switch (BITS (22, 23))
778 Rd
= wRBITS (wRn
, offset
, offset
+ 7);
784 offset
= (offset
& 3) * 16;
785 Rd
= wRBITS (wRn
, offset
, offset
+ 15);
791 offset
= (offset
& 1) * 32;
792 Rd
= wRBITS (wRn
, offset
, offset
+ 31);
796 ARMul_UndefInstr (state
, instr
);
800 if (BITS (12, 15) == 15)
801 ARMul_UndefInstr (state
, instr
);
803 state
->Reg
[BITS (12, 15)] = Rd
;
809 TINSR (ARMul_State
* state
, ARMword instr
)
815 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
819 fprintf (stderr
, "tinsr\n");
823 data
= state
->Reg
[BITS (12, 15)];
824 offset
= BITS (0, 2);
832 case 0: wR
[wRd
] = data
| (wRBITS (wRd
, 8, 63) << 8); break;
833 case 1: wR
[wRd
] = wRBITS (wRd
, 0, 7) | (data
<< 8) | (wRBITS (wRd
, 16, 63) << 16); break;
834 case 2: wR
[wRd
] = wRBITS (wRd
, 0, 15) | (data
<< 16) | (wRBITS (wRd
, 24, 63) << 24); break;
835 case 3: wR
[wRd
] = wRBITS (wRd
, 0, 23) | (data
<< 24) | (wRBITS (wRd
, 32, 63) << 32); break;
836 case 4: wR
[wRd
] = wRBITS (wRd
, 0, 31) | (data
<< 32) | (wRBITS (wRd
, 40, 63) << 40); break;
837 case 5: wR
[wRd
] = wRBITS (wRd
, 0, 39) | (data
<< 40) | (wRBITS (wRd
, 48, 63) << 48); break;
838 case 6: wR
[wRd
] = wRBITS (wRd
, 0, 47) | (data
<< 48) | (wRBITS (wRd
, 56, 63) << 56); break;
839 case 7: wR
[wRd
] = wRBITS (wRd
, 0, 55) | (data
<< 56); break;
848 case 0: wR
[wRd
] = data
| (wRBITS (wRd
, 16, 63) << 16); break;
849 case 1: wR
[wRd
] = wRBITS (wRd
, 0, 15) | (data
<< 16) | (wRBITS (wRd
, 32, 63) << 32); break;
850 case 2: wR
[wRd
] = wRBITS (wRd
, 0, 31) | (data
<< 32) | (wRBITS (wRd
, 48, 63) << 48); break;
851 case 3: wR
[wRd
] = wRBITS (wRd
, 0, 47) | (data
<< 48); break;
857 wR
[wRd
] = wRBITS (wRd
, 0, 31) | (data
<< 32);
859 wR
[wRd
] = (wRBITS (wRd
, 32, 63) << 32) | data
;
863 ARMul_UndefInstr (state
, instr
);
867 wC
[wCon
] |= WCON_MUP
;
872 TMCR (ARMul_State
* state
, ARMword instr
)
877 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
881 fprintf (stderr
, "tmcr\n");
884 if (BITS (0, 3) != 0)
887 val
= state
->Reg
[BITS (12, 15)];
888 if (BITS (12, 15) == 15)
891 wCreg
= BITS (16, 19);
896 /* The wCID register is read only. */
900 /* Writing to the MUP or CUP bits clears them. */
901 wC
[wCon
] &= ~ (val
& 0x3);
905 /* Only the bottom 8 bits can be written to.
906 The higher bits write as zero. */
907 wC
[wCSSF
] = (val
& 0xff);
908 wC
[wCon
] |= WCON_CUP
;
913 wC
[wCon
] |= WCON_CUP
;
921 TMCRR (ARMul_State
* state
, ARMword instr
)
923 ARMdword RdHi
= state
->Reg
[BITS (16, 19)];
924 ARMword RdLo
= state
->Reg
[BITS (12, 15)];
926 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
930 fprintf (stderr
, "tmcrr\n");
933 if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15))
936 wR
[BITS (0, 3)] = (RdHi
<< 32) | RdLo
;
938 wC
[wCon
] |= WCON_MUP
;
944 TMIA (ARMul_State
* state
, ARMword instr
)
946 signed long long a
, b
;
948 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
952 fprintf (stderr
, "tmia\n");
955 if ((BITS (0, 3) == 15) || (BITS (12, 15) == 15))
957 ARMul_UndefInstr (state
, instr
);
961 a
= state
->Reg
[BITS (0, 3)];
962 b
= state
->Reg
[BITS (12, 15)];
967 wR
[BITS (5, 8)] += a
* b
;
968 wC
[wCon
] |= WCON_MUP
;
974 TMIAPH (ARMul_State
* state
, ARMword instr
)
976 signed long a
, b
, result
;
978 ARMword Rm
= state
->Reg
[BITS (0, 3)];
979 ARMword Rs
= state
->Reg
[BITS (12, 15)];
981 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
985 fprintf (stderr
, "tmiaph\n");
988 if (BITS (0, 3) == 15 || BITS (12, 15) == 15)
990 ARMul_UndefInstr (state
, instr
);
994 a
= SUBSTR (Rs
, ARMword
, 16, 31);
995 b
= SUBSTR (Rm
, ARMword
, 16, 31);
1005 wR
[BITS (5, 8)] += r
;
1007 a
= SUBSTR (Rs
, ARMword
, 0, 15);
1008 b
= SUBSTR (Rm
, ARMword
, 0, 15);
1018 wR
[BITS (5, 8)] += r
;
1019 wC
[wCon
] |= WCON_MUP
;
1025 TMIAxy (ARMul_State
* state
, ARMword instr
)
1031 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1035 fprintf (stderr
, "tmiaxy\n");
1038 if (BITS (0, 3) == 15 || BITS (12, 15) == 15)
1040 ARMul_UndefInstr (state
, instr
);
1044 Rm
= state
->Reg
[BITS (0, 3)];
1050 Rs
= state
->Reg
[BITS (12, 15)];
1065 if (temp
& (1 << 31))
1068 wR
[BITS (5, 8)] += temp
;
1069 wC
[wCon
] |= WCON_MUP
;
1075 TMOVMSK (ARMul_State
* state
, ARMword instr
)
1080 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1084 fprintf (stderr
, "tmovmsk\n");
1087 /* The CRm field must be r0. */
1088 if (BITS (0, 3) != 0)
1091 wRn
= BITS (16, 19);
1093 switch (BITS (22, 23))
1096 result
= ( (wRBITS (wRn
, 63, 63) << 7)
1097 | (wRBITS (wRn
, 55, 55) << 6)
1098 | (wRBITS (wRn
, 47, 47) << 5)
1099 | (wRBITS (wRn
, 39, 39) << 4)
1100 | (wRBITS (wRn
, 31, 31) << 3)
1101 | (wRBITS (wRn
, 23, 23) << 2)
1102 | (wRBITS (wRn
, 15, 15) << 1)
1103 | (wRBITS (wRn
, 7, 7) << 0));
1107 result
= ( (wRBITS (wRn
, 63, 63) << 3)
1108 | (wRBITS (wRn
, 47, 47) << 2)
1109 | (wRBITS (wRn
, 31, 31) << 1)
1110 | (wRBITS (wRn
, 15, 15) << 0));
1114 result
= (wRBITS (wRn
, 63, 63) << 1) | wRBITS (wRn
, 31, 31);
1118 ARMul_UndefInstr (state
, instr
);
1122 state
->Reg
[BITS (12, 15)] = result
;
1128 TMRC (ARMul_State
* state
, ARMword instr
)
1130 int reg
= BITS (12, 15);
1132 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1136 fprintf (stderr
, "tmrc\n");
1139 if (BITS (0, 3) != 0)
1143 ARMul_UndefInstr (state
, instr
);
1145 state
->Reg
[reg
] = wC
[BITS (16, 19)];
1151 TMRRC (ARMul_State
* state
, ARMword instr
)
1153 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1157 fprintf (stderr
, "tmrrc\n");
1160 if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15) || (BITS (4, 11) != 0))
1161 ARMul_UndefInstr (state
, instr
);
1164 state
->Reg
[BITS (16, 19)] = wRBITS (BITS (0, 3), 32, 63);
1165 state
->Reg
[BITS (12, 15)] = wRBITS (BITS (0, 3), 0, 31);
1172 TORC (ARMul_State
* state
, ARMword instr
)
1174 ARMword cpsr
= ARMul_GetCPSR (state
);
1176 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1180 fprintf (stderr
, "torc\n");
1183 /* The Rd field must be r15. */
1184 if (BITS (12, 15) != 15)
1187 /* The CRn field must be r3. */
1188 if (BITS (16, 19) != 3)
1191 /* The CRm field must be r0. */
1192 if (BITS (0, 3) != 0)
1197 switch (BITS (22, 23))
1200 cpsr
|= ( (wCBITS (wCASF
, 28, 31) | wCBITS (wCASF
, 24, 27)
1201 | wCBITS (wCASF
, 20, 23) | wCBITS (wCASF
, 16, 19)
1202 | wCBITS (wCASF
, 12, 15) | wCBITS (wCASF
, 8, 11)
1203 | wCBITS (wCASF
, 4, 7) | wCBITS (wCASF
, 0, 3)) << 28);
1207 cpsr
|= ( (wCBITS (wCASF
, 28, 31) | wCBITS (wCASF
, 20, 23)
1208 | wCBITS (wCASF
, 12, 15) | wCBITS (wCASF
, 4, 7)) << 28);
1212 cpsr
|= ((wCBITS (wCASF
, 28, 31) | wCBITS (wCASF
, 12, 15)) << 28);
1216 ARMul_UndefInstr (state
, instr
);
1220 ARMul_SetCPSR (state
, cpsr
);
1226 WACC (ARMul_State
* state
, ARMword instr
)
1230 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1234 fprintf (stderr
, "wacc\n");
1237 wRn
= BITS (16, 19);
1239 switch (BITS (22, 23))
1242 wR
[BITS (12, 15)] =
1243 wRBITS (wRn
, 56, 63) + wRBITS (wRn
, 48, 55)
1244 + wRBITS (wRn
, 40, 47) + wRBITS (wRn
, 32, 39)
1245 + wRBITS (wRn
, 24, 31) + wRBITS (wRn
, 16, 23)
1246 + wRBITS (wRn
, 8, 15) + wRBITS (wRn
, 0, 7);
1250 wR
[BITS (12, 15)] =
1251 wRBITS (wRn
, 48, 63) + wRBITS (wRn
, 32, 47)
1252 + wRBITS (wRn
, 16, 31) + wRBITS (wRn
, 0, 15);
1256 wR
[BITS (12, 15)] = wRBITS (wRn
, 32, 63) + wRBITS (wRn
, 0, 31);
1260 ARMul_UndefInstr (state
, instr
);
1264 wC
[wCon
] |= WCON_MUP
;
1269 WADD (ARMul_State
* state
, ARMword instr
)
1280 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1284 fprintf (stderr
, "wadd\n");
1287 /* Add two numbers using the specified function,
1288 leaving setting the carry bit as required. */
1289 #define ADDx(x, y, m, f) \
1290 (*f) (wRBITS (BITS (16, 19), (x), (y)) & (m), \
1291 wRBITS (BITS ( 0, 3), (x), (y)) & (m), \
1292 & carry, & overflow)
1294 switch (BITS (22, 23))
1297 for (i
= 0; i
< 8; i
++)
1299 switch (BITS (20, 21))
1302 s
= ADDx ((i
* 8), (i
* 8) + 7, 0xff, AddS8
);
1303 satrv
[BITIDX8 (i
)] = 0;
1304 r
|= (s
& 0xff) << (i
* 8);
1305 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
1306 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
1307 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
1308 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
1311 case UnsignedSaturation
:
1312 s
= ADDx ((i
* 8), (i
* 8) + 7, 0xff, AddU8
);
1313 x
= IwmmxtSaturateU8 (s
, satrv
+ BITIDX8 (i
));
1314 r
|= (x
& 0xff) << (i
* 8);
1315 SIMD8_SET (psr
, NBIT8 (x
), SIMD_NBIT
, i
);
1316 SIMD8_SET (psr
, ZBIT8 (x
), SIMD_ZBIT
, i
);
1317 if (! satrv
[BITIDX8 (i
)])
1319 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
1320 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
1324 case SignedSaturation
:
1325 s
= ADDx ((i
* 8), (i
* 8) + 7, 0xff, AddS8
);
1326 x
= IwmmxtSaturateS8 (s
, satrv
+ BITIDX8 (i
));
1327 r
|= (x
& 0xff) << (i
* 8);
1328 SIMD8_SET (psr
, NBIT8 (x
), SIMD_NBIT
, i
);
1329 SIMD8_SET (psr
, ZBIT8 (x
), SIMD_ZBIT
, i
);
1330 if (! satrv
[BITIDX8 (i
)])
1332 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
1333 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
1338 ARMul_UndefInstr (state
, instr
);
1345 satrv
[0] = satrv
[2] = satrv
[4] = satrv
[6] = 0;
1347 for (i
= 0; i
< 4; i
++)
1349 switch (BITS (20, 21))
1352 s
= ADDx ((i
* 16), (i
* 16) + 15, 0xffff, AddS16
);
1353 satrv
[BITIDX16 (i
)] = 0;
1354 r
|= (s
& 0xffff) << (i
* 16);
1355 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
1356 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
1357 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
1358 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
1361 case UnsignedSaturation
:
1362 s
= ADDx ((i
* 16), (i
* 16) + 15, 0xffff, AddU16
);
1363 x
= IwmmxtSaturateU16 (s
, satrv
+ BITIDX16 (i
));
1364 r
|= (x
& 0xffff) << (i
* 16);
1365 SIMD16_SET (psr
, NBIT16 (x
), SIMD_NBIT
, i
);
1366 SIMD16_SET (psr
, ZBIT16 (x
), SIMD_ZBIT
, i
);
1367 if (! satrv
[BITIDX16 (i
)])
1369 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
1370 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
1374 case SignedSaturation
:
1375 s
= ADDx ((i
* 16), (i
* 16) + 15, 0xffff, AddS16
);
1376 x
= IwmmxtSaturateS16 (s
, satrv
+ BITIDX16 (i
));
1377 r
|= (x
& 0xffff) << (i
* 16);
1378 SIMD16_SET (psr
, NBIT16 (x
), SIMD_NBIT
, i
);
1379 SIMD16_SET (psr
, ZBIT16 (x
), SIMD_ZBIT
, i
);
1380 if (! satrv
[BITIDX16 (i
)])
1382 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
1383 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
1388 ARMul_UndefInstr (state
, instr
);
1395 satrv
[0] = satrv
[1] = satrv
[2] = satrv
[4] = satrv
[5] = satrv
[6] = 0;
1397 for (i
= 0; i
< 2; i
++)
1399 switch (BITS (20, 21))
1402 s
= ADDx ((i
* 32), (i
* 32) + 31, 0xffffffff, AddS32
);
1403 satrv
[BITIDX32 (i
)] = 0;
1404 r
|= (s
& 0xffffffff) << (i
* 32);
1405 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
1406 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
1407 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
1408 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
1411 case UnsignedSaturation
:
1412 s
= ADDx ((i
* 32), (i
* 32) + 31, 0xffffffff, AddU32
);
1413 x
= IwmmxtSaturateU32 (s
, satrv
+ BITIDX32 (i
));
1414 r
|= (x
& 0xffffffff) << (i
* 32);
1415 SIMD32_SET (psr
, NBIT32 (x
), SIMD_NBIT
, i
);
1416 SIMD32_SET (psr
, ZBIT32 (x
), SIMD_ZBIT
, i
);
1417 if (! satrv
[BITIDX32 (i
)])
1419 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
1420 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
1424 case SignedSaturation
:
1425 s
= ADDx ((i
* 32), (i
* 32) + 31, 0xffffffff, AddS32
);
1426 x
= IwmmxtSaturateS32 (s
, satrv
+ BITIDX32 (i
));
1427 r
|= (x
& 0xffffffff) << (i
* 32);
1428 SIMD32_SET (psr
, NBIT32 (x
), SIMD_NBIT
, i
);
1429 SIMD32_SET (psr
, ZBIT32 (x
), SIMD_ZBIT
, i
);
1430 if (! satrv
[BITIDX32 (i
)])
1432 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
1433 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
1438 ARMul_UndefInstr (state
, instr
);
1445 ARMul_UndefInstr (state
, instr
);
1450 wR
[BITS (12, 15)] = r
;
1451 wC
[wCon
] |= (WCON_MUP
| WCON_CUP
);
1453 SET_wCSSFvec (satrv
);
1461 WALIGNI (ARMword instr
)
1463 int shift
= BITS (20, 22) * 8;
1465 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1469 fprintf (stderr
, "waligni\n");
1473 wR
[BITS (12, 15)] =
1474 wRBITS (BITS (16, 19), shift
, 63)
1475 | (wRBITS (BITS (0, 3), 0, shift
) << ((64 - shift
)));
1477 wR
[BITS (12, 15)] = wR
[BITS (16, 19)];
1479 wC
[wCon
] |= WCON_MUP
;
1484 WALIGNR (ARMul_State
* state
, ARMword instr
)
1486 int shift
= (wC
[BITS (20, 21) + 8] & 0x7) * 8;
1488 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1492 fprintf (stderr
, "walignr\n");
1496 wR
[BITS (12, 15)] =
1497 wRBITS (BITS (16, 19), shift
, 63)
1498 | (wRBITS (BITS (0, 3), 0, shift
) << ((64 - shift
)));
1500 wR
[BITS (12, 15)] = wR
[BITS (16, 19)];
1502 wC
[wCon
] |= WCON_MUP
;
1507 WAND (ARMword instr
)
1512 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1516 fprintf (stderr
, "wand\n");
1519 result
= wR
[BITS (16, 19)] & wR
[BITS (0, 3)];
1520 wR
[BITS (12, 15)] = result
;
1522 SIMD64_SET (psr
, (result
== 0), SIMD_ZBIT
);
1523 SIMD64_SET (psr
, (result
& (1ULL << 63)), SIMD_NBIT
);
1526 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
1532 WANDN (ARMword instr
)
1537 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1541 fprintf (stderr
, "wandn\n");
1544 result
= wR
[BITS (16, 19)] & ~ wR
[BITS (0, 3)];
1545 wR
[BITS (12, 15)] = result
;
1547 SIMD64_SET (psr
, (result
== 0), SIMD_ZBIT
);
1548 SIMD64_SET (psr
, (result
& (1ULL << 63)), SIMD_NBIT
);
1551 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
1557 WAVG2 (ARMword instr
)
1563 int round
= BIT (20) ? 1 : 0;
1565 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1569 fprintf (stderr
, "wavg2\n");
1572 #define AVG2x(x, y, m) (((wRBITS (BITS (16, 19), (x), (y)) & (m)) \
1573 + (wRBITS (BITS ( 0, 3), (x), (y)) & (m)) \
1578 for (i
= 0; i
< 4; i
++)
1580 s
= AVG2x ((i
* 16), (i
* 16) + 15, 0xffff) & 0xffff;
1581 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
1587 for (i
= 0; i
< 8; i
++)
1589 s
= AVG2x ((i
* 8), (i
* 8) + 7, 0xff) & 0xff;
1590 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
1595 wR
[BITS (12, 15)] = r
;
1597 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
1603 WCMPEQ (ARMul_State
* state
, ARMword instr
)
1610 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1614 fprintf (stderr
, "wcmpeq\n");
1617 switch (BITS (22, 23))
1620 for (i
= 0; i
< 8; i
++)
1622 s
= wRBYTE (BITS (16, 19), i
) == wRBYTE (BITS (0, 3), i
) ? 0xff : 0;
1624 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
1625 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
1630 for (i
= 0; i
< 4; i
++)
1632 s
= wRHALF (BITS (16, 19), i
) == wRHALF (BITS (0, 3), i
) ? 0xffff : 0;
1634 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
1635 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
1640 for (i
= 0; i
< 2; i
++)
1642 s
= wRWORD (BITS (16, 19), i
) == wRWORD (BITS (0, 3), i
) ? 0xffffffff : 0;
1644 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
1645 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
1650 ARMul_UndefInstr (state
, instr
);
1655 wR
[BITS (12, 15)] = r
;
1656 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
1662 WCMPGT (ARMul_State
* state
, ARMword instr
)
1669 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1673 fprintf (stderr
, "wcmpgt\n");
1676 switch (BITS (22, 23))
1681 /* Use a signed comparison. */
1682 for (i
= 0; i
< 8; i
++)
1686 a
= wRBYTE (BITS (16, 19), i
);
1687 b
= wRBYTE (BITS (0, 3), i
);
1689 s
= (a
> b
) ? 0xff : 0;
1691 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
1692 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
1697 for (i
= 0; i
< 8; i
++)
1699 s
= (wRBYTE (BITS (16, 19), i
) > wRBYTE (BITS (0, 3), i
))
1702 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
1703 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
1711 for (i
= 0; i
< 4; i
++)
1715 a
= wRHALF (BITS (16, 19), i
);
1718 b
= wRHALF (BITS (0, 3), i
);
1721 s
= (a
> b
) ? 0xffff : 0;
1723 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
1724 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
1729 for (i
= 0; i
< 4; i
++)
1731 s
= (wRHALF (BITS (16, 19), i
) > wRHALF (BITS (0, 3), i
))
1734 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
1735 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
1743 for (i
= 0; i
< 2; i
++)
1747 a
= EXTEND32 (wRWORD (BITS (16, 19), i
));
1748 b
= EXTEND32 (wRWORD (BITS (0, 3), i
));
1750 s
= (a
> b
) ? 0xffffffff : 0;
1753 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
1754 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
1759 for (i
= 0; i
< 2; i
++)
1761 s
= (wRWORD (BITS (16, 19), i
) > wRWORD (BITS (0, 3), i
))
1764 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
1765 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
1771 ARMul_UndefInstr (state
, instr
);
1776 wR
[BITS (12, 15)] = r
;
1777 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
1783 Compute_Iwmmxt_Address (ARMul_State
* state
, ARMword instr
, int * pFailed
)
1792 addr
= state
->Reg
[Rn
];
1793 offset
= BITS (0, 7);
1794 multiplier
= BIT (8) ? 4 : 1;
1796 if (BIT (24)) /* P */
1798 /* Pre Indexed Addressing. */
1800 addr
+= offset
* multiplier
;
1802 addr
-= offset
* multiplier
;
1804 /* Immediate Pre-Indexed. */
1805 if (BIT (21)) /* W */
1809 /* Writeback into R15 is UNPREDICTABLE. */
1811 fprintf (stderr
, "iWMMXt: writeback into r15\n");
1816 state
->Reg
[Rn
] = addr
;
1821 /* Post Indexed Addressing. */
1822 if (BIT (21)) /* W */
1824 /* Handle the write back of the final address. */
1827 /* Writeback into R15 is UNPREDICTABLE. */
1829 fprintf (stderr
, "iWMMXt: writeback into r15\n");
1838 increment
= offset
* multiplier
;
1840 increment
= - (offset
* multiplier
);
1842 state
->Reg
[Rn
] = addr
+ increment
;
1847 /* P == 0, W == 0, U == 0 is UNPREDICTABLE. */
1851 fprintf (stderr
, "iWMMXt: undefined addressing mode\n");
1862 Iwmmxt_Load_Double_Word (ARMul_State
* state
, ARMword address
)
1866 /* The address must be aligned on a 8 byte boundary. */
1869 fprintf (stderr
, "iWMMXt: At addr 0x%x: Unaligned double word load from 0x%x\n",
1870 (state
->Reg
[15] - 8) & ~0x3, address
);
1873 /* No need to check for alignment traps. An unaligned
1874 double word load with alignment trapping disabled is
1876 ARMul_Abort (state
, ARMul_DataAbortV
);
1879 /* Load the words. */
1880 if (! state
->bigendSig
)
1882 value
= ARMul_LoadWordN (state
, address
+ 4);
1884 value
|= ARMul_LoadWordN (state
, address
);
1888 value
= ARMul_LoadWordN (state
, address
);
1890 value
|= ARMul_LoadWordN (state
, address
+ 4);
1893 /* Check for data aborts. */
1895 ARMul_Abort (state
, ARMul_DataAbortV
);
1897 ARMul_Icycles (state
, 2, 0L);
1903 Iwmmxt_Load_Word (ARMul_State
* state
, ARMword address
)
1907 /* Check for a misaligned address. */
1910 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN
))
1911 ARMul_Abort (state
, ARMul_DataAbortV
);
1916 value
= ARMul_LoadWordN (state
, address
);
1919 ARMul_Abort (state
, ARMul_DataAbortV
);
1921 ARMul_Icycles (state
, 1, 0L);
1927 Iwmmxt_Load_Half_Word (ARMul_State
* state
, ARMword address
)
1931 /* Check for a misaligned address. */
1934 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN
))
1935 ARMul_Abort (state
, ARMul_DataAbortV
);
1940 value
= ARMul_LoadHalfWord (state
, address
);
1943 ARMul_Abort (state
, ARMul_DataAbortV
);
1945 ARMul_Icycles (state
, 1, 0L);
1951 Iwmmxt_Load_Byte (ARMul_State
* state
, ARMword address
)
1955 value
= ARMul_LoadByte (state
, address
);
1958 ARMul_Abort (state
, ARMul_DataAbortV
);
1960 ARMul_Icycles (state
, 1, 0L);
1966 Iwmmxt_Store_Double_Word (ARMul_State
* state
, ARMword address
, ARMdword value
)
1968 /* The address must be aligned on a 8 byte boundary. */
1971 fprintf (stderr
, "iWMMXt: At addr 0x%x: Unaligned double word store to 0x%x\n",
1972 (state
->Reg
[15] - 8) & ~0x3, address
);
1975 /* No need to check for alignment traps. An unaligned
1976 double word store with alignment trapping disabled is
1978 ARMul_Abort (state
, ARMul_DataAbortV
);
1981 /* Store the words. */
1982 if (! state
->bigendSig
)
1984 ARMul_StoreWordN (state
, address
, value
);
1985 ARMul_StoreWordN (state
, address
+ 4, value
>> 32);
1989 ARMul_StoreWordN (state
, address
+ 4, value
);
1990 ARMul_StoreWordN (state
, address
, value
>> 32);
1993 /* Check for data aborts. */
1995 ARMul_Abort (state
, ARMul_DataAbortV
);
1997 ARMul_Icycles (state
, 2, 0L);
2001 Iwmmxt_Store_Word (ARMul_State
* state
, ARMword address
, ARMword value
)
2003 /* Check for a misaligned address. */
2006 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN
))
2007 ARMul_Abort (state
, ARMul_DataAbortV
);
2012 ARMul_StoreWordN (state
, address
, value
);
2015 ARMul_Abort (state
, ARMul_DataAbortV
);
2019 Iwmmxt_Store_Half_Word (ARMul_State
* state
, ARMword address
, ARMword value
)
2021 /* Check for a misaligned address. */
2024 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN
))
2025 ARMul_Abort (state
, ARMul_DataAbortV
);
2030 ARMul_StoreHalfWord (state
, address
, value
);
2033 ARMul_Abort (state
, ARMul_DataAbortV
);
2037 Iwmmxt_Store_Byte (ARMul_State
* state
, ARMword address
, ARMword value
)
2039 ARMul_StoreByte (state
, address
, value
);
2042 ARMul_Abort (state
, ARMul_DataAbortV
);
2046 WLDR (ARMul_State
* state
, ARMword instr
)
2051 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2055 fprintf (stderr
, "wldr\n");
2058 address
= Compute_Iwmmxt_Address (state
, instr
, & failed
);
2062 if (BITS (28, 31) == 0xf)
2065 wC
[BITS (12, 15)] = Iwmmxt_Load_Word (state
, address
);
2067 else if (BIT (8) == 0)
2071 wR
[BITS (12, 15)] = Iwmmxt_Load_Byte (state
, address
);
2074 wR
[BITS (12, 15)] = Iwmmxt_Load_Half_Word (state
, address
);
2080 wR
[BITS (12, 15)] = Iwmmxt_Load_Word (state
, address
);
2083 wR
[BITS (12, 15)] = Iwmmxt_Load_Double_Word (state
, address
);
2086 wC
[wCon
] |= WCON_MUP
;
2092 WMAC (ARMword instr
)
2098 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2102 fprintf (stderr
, "wmac\n");
2105 for (i
= 0; i
< 4; i
++)
2112 a
= wRHALF (BITS (16, 19), i
);
2115 b
= wRHALF (BITS (0, 3), i
);
2118 s
= (signed long) a
* (signed long) b
;
2120 t
= t
+ (ARMdword
) s
;
2125 a
= wRHALF (BITS (16, 19), i
);
2126 b
= wRHALF (BITS ( 0, 3), i
);
2138 wR
[BITS (12, 15)] = t
;
2140 wR
[BITS (12, 15)] += t
;
2142 wC
[wCon
] |= WCON_MUP
;
2148 WMADD (ARMword instr
)
2153 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2157 fprintf (stderr
, "wmadd\n");
2160 for (i
= 0; i
< 2; i
++)
2164 if (BIT (21)) /* Signed. */
2168 a
= wRHALF (BITS (16, 19), i
* 2);
2171 b
= wRHALF (BITS (0, 3), i
* 2);
2174 s1
= (ARMdword
) (a
* b
);
2176 a
= wRHALF (BITS (16, 19), i
* 2 + 1);
2179 b
= wRHALF (BITS (0, 3), i
* 2 + 1);
2182 s2
= (ARMdword
) (a
* b
);
2184 else /* Unsigned. */
2188 a
= wRHALF (BITS (16, 19), i
* 2);
2189 b
= wRHALF (BITS ( 0, 3), i
* 2);
2191 s1
= (ARMdword
) (a
* b
);
2193 a
= wRHALF (BITS (16, 19), i
* 2 + 1);
2194 b
= wRHALF (BITS ( 0, 3), i
* 2 + 1);
2196 s2
= (ARMdword
) a
* b
;
2199 r
|= (ARMdword
) ((s1
+ s2
) & 0xffffffff) << (i
? 32 : 0);
2202 wR
[BITS (12, 15)] = r
;
2203 wC
[wCon
] |= WCON_MUP
;
2209 WMAX (ARMul_State
* state
, ARMword instr
)
2215 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2219 fprintf (stderr
, "wmax\n");
2222 switch (BITS (22, 23))
2225 for (i
= 0; i
< 8; i
++)
2226 if (BIT (21)) /* Signed. */
2230 a
= wRBYTE (BITS (16, 19), i
);
2233 b
= wRBYTE (BITS (0, 3), i
);
2241 r
|= (s
& 0xff) << (i
* 8);
2243 else /* Unsigned. */
2247 a
= wRBYTE (BITS (16, 19), i
);
2248 b
= wRBYTE (BITS (0, 3), i
);
2255 r
|= (s
& 0xff) << (i
* 8);
2260 for (i
= 0; i
< 4; i
++)
2261 if (BIT (21)) /* Signed. */
2265 a
= wRHALF (BITS (16, 19), i
);
2268 b
= wRHALF (BITS (0, 3), i
);
2276 r
|= (s
& 0xffff) << (i
* 16);
2278 else /* Unsigned. */
2282 a
= wRHALF (BITS (16, 19), i
);
2283 b
= wRHALF (BITS (0, 3), i
);
2290 r
|= (s
& 0xffff) << (i
* 16);
2295 for (i
= 0; i
< 2; i
++)
2296 if (BIT (21)) /* Signed. */
2300 a
= wRWORD (BITS (16, 19), i
);
2301 b
= wRWORD (BITS (0, 3), i
);
2308 r
|= (s
& 0xffffffff) << (i
* 32);
2314 a
= wRWORD (BITS (16, 19), i
);
2315 b
= wRWORD (BITS (0, 3), i
);
2322 r
|= (s
& 0xffffffff) << (i
* 32);
2327 ARMul_UndefInstr (state
, instr
);
2331 wR
[BITS (12, 15)] = r
;
2332 wC
[wCon
] |= WCON_MUP
;
2338 WMIN (ARMul_State
* state
, ARMword instr
)
2344 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2348 fprintf (stderr
, "wmin\n");
2351 switch (BITS (22, 23))
2354 for (i
= 0; i
< 8; i
++)
2355 if (BIT (21)) /* Signed. */
2359 a
= wRBYTE (BITS (16, 19), i
);
2362 b
= wRBYTE (BITS (0, 3), i
);
2370 r
|= (s
& 0xff) << (i
* 8);
2372 else /* Unsigned. */
2376 a
= wRBYTE (BITS (16, 19), i
);
2377 b
= wRBYTE (BITS (0, 3), i
);
2384 r
|= (s
& 0xff) << (i
* 8);
2389 for (i
= 0; i
< 4; i
++)
2390 if (BIT (21)) /* Signed. */
2394 a
= wRHALF (BITS (16, 19), i
);
2397 b
= wRHALF (BITS (0, 3), i
);
2405 r
|= (s
& 0xffff) << (i
* 16);
2412 a
= wRHALF (BITS (16, 19), i
);
2413 b
= wRHALF (BITS ( 0, 3), i
);
2420 r
|= (s
& 0xffff) << (i
* 16);
2425 for (i
= 0; i
< 2; i
++)
2426 if (BIT (21)) /* Signed. */
2430 a
= wRWORD (BITS (16, 19), i
);
2431 b
= wRWORD (BITS ( 0, 3), i
);
2438 r
|= (s
& 0xffffffff) << (i
* 32);
2444 a
= wRWORD (BITS (16, 19), i
);
2445 b
= wRWORD (BITS (0, 3), i
);
2452 r
|= (s
& 0xffffffff) << (i
* 32);
2457 ARMul_UndefInstr (state
, instr
);
2461 wR
[BITS (12, 15)] = r
;
2462 wC
[wCon
] |= WCON_MUP
;
2468 WMUL (ARMword instr
)
2474 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2478 fprintf (stderr
, "wmul\n");
2481 for (i
= 0; i
< 4; i
++)
2482 if (BIT (21)) /* Signed. */
2486 a
= wRHALF (BITS (16, 19), i
);
2489 b
= wRHALF (BITS (0, 3), i
);
2495 r
|= ((s
>> 16) & 0xffff) << (i
* 16);
2497 r
|= (s
& 0xffff) << (i
* 16);
2499 else /* Unsigned. */
2503 a
= wRHALF (BITS (16, 19), i
);
2504 b
= wRHALF (BITS (0, 3), i
);
2509 r
|= ((s
>> 16) & 0xffff) << (i
* 16);
2511 r
|= (s
& 0xffff) << (i
* 16);
2514 wR
[BITS (12, 15)] = r
;
2515 wC
[wCon
] |= WCON_MUP
;
2526 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2530 fprintf (stderr
, "wor\n");
2533 result
= wR
[BITS (16, 19)] | wR
[BITS (0, 3)];
2534 wR
[BITS (12, 15)] = result
;
2536 SIMD64_SET (psr
, (result
== 0), SIMD_ZBIT
);
2537 SIMD64_SET (psr
, (result
& (1ULL << 63)), SIMD_NBIT
);
2540 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2546 WPACK (ARMul_State
* state
, ARMword instr
)
2555 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2559 fprintf (stderr
, "wpack\n");
2562 switch (BITS (22, 23))
2565 for (i
= 0; i
< 8; i
++)
2567 x
= wRHALF (i
< 4 ? BITS (16, 19) : BITS (0, 3), i
& 3);
2569 switch (BITS (20, 21))
2571 case UnsignedSaturation
:
2572 s
= IwmmxtSaturateU8 (x
, satrv
+ BITIDX8 (i
));
2575 case SignedSaturation
:
2576 s
= IwmmxtSaturateS8 (x
, satrv
+ BITIDX8 (i
));
2580 ARMul_UndefInstr (state
, instr
);
2584 r
|= (s
& 0xff) << (i
* 8);
2585 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
2586 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
2591 satrv
[0] = satrv
[2] = satrv
[4] = satrv
[6] = 0;
2593 for (i
= 0; i
< 4; i
++)
2595 x
= wRWORD (i
< 2 ? BITS (16, 19) : BITS (0, 3), i
& 1);
2597 switch (BITS (20, 21))
2599 case UnsignedSaturation
:
2600 s
= IwmmxtSaturateU16 (x
, satrv
+ BITIDX16 (i
));
2603 case SignedSaturation
:
2604 s
= IwmmxtSaturateS16 (x
, satrv
+ BITIDX16 (i
));
2608 ARMul_UndefInstr (state
, instr
);
2612 r
|= (s
& 0xffff) << (i
* 16);
2613 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2614 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2619 satrv
[0] = satrv
[1] = satrv
[2] = satrv
[4] = satrv
[5] = satrv
[6] = 0;
2621 for (i
= 0; i
< 2; i
++)
2623 x
= wR
[i
? BITS (0, 3) : BITS (16, 19)];
2625 switch (BITS (20, 21))
2627 case UnsignedSaturation
:
2628 s
= IwmmxtSaturateU32 (x
, satrv
+ BITIDX32 (i
));
2631 case SignedSaturation
:
2632 s
= IwmmxtSaturateS32 (x
, satrv
+ BITIDX32 (i
));
2636 ARMul_UndefInstr (state
, instr
);
2640 r
|= (s
& 0xffffffff) << (i
* 32);
2641 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
2642 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
2647 ARMul_UndefInstr (state
, instr
);
2652 wR
[BITS (12, 15)] = r
;
2653 SET_wCSSFvec (satrv
);
2654 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2660 WROR (ARMul_State
* state
, ARMword instr
)
2668 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2672 fprintf (stderr
, "wror\n");
2675 DECODE_G_BIT (state
, instr
, shift
);
2677 switch (BITS (22, 23))
2681 for (i
= 0; i
< 4; i
++)
2683 s
= ((wRHALF (BITS (16, 19), i
) & 0xffff) << (16 - shift
))
2684 | ((wRHALF (BITS (16, 19), i
) & 0xffff) >> shift
);
2685 r
|= (s
& 0xffff) << (i
* 16);
2686 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2687 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2693 for (i
= 0; i
< 2; i
++)
2695 s
= ((wRWORD (BITS (16, 19), i
) & 0xffffffff) << (32 - shift
))
2696 | ((wRWORD (BITS (16, 19), i
) & 0xffffffff) >> shift
);
2697 r
|= (s
& 0xffffffff) << (i
* 32);
2698 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
2699 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
2705 r
= (wR
[BITS (16, 19)] >> shift
)
2706 | (wR
[BITS (16, 19)] << (64 - shift
));
2708 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
2709 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
2713 ARMul_UndefInstr (state
, instr
);
2718 wR
[BITS (12, 15)] = r
;
2719 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2725 WSAD (ARMword instr
)
2731 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2735 fprintf (stderr
, "wsad\n");
2739 r
= BIT (20) ? 0 : (wR
[BITS (12, 15)] & 0xffffffff);
2743 for (i
= 0; i
< 4; i
++)
2745 s
= (wRHALF (BITS (16, 19), i
) - wRHALF (BITS (0, 3), i
));
2750 for (i
= 0; i
< 8; i
++)
2752 s
= (wRBYTE (BITS (16, 19), i
) - wRBYTE (BITS (0, 3), i
));
2756 wR
[BITS (12, 15)] = r
;
2757 wC
[wCon
] |= WCON_MUP
;
2763 WSHUFH (ARMword instr
)
2771 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2775 fprintf (stderr
, "wshufh\n");
2778 imm8
= (BITS (20, 23) << 4) | BITS (0, 3);
2780 for (i
= 0; i
< 4; i
++)
2782 s
= wRHALF (BITS (16, 19), ((imm8
>> (i
* 2) & 3)) & 0xff);
2783 r
|= (s
& 0xffff) << (i
* 16);
2784 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2785 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2789 wR
[BITS (12, 15)] = r
;
2790 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2796 WSLL (ARMul_State
* state
, ARMword instr
)
2804 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2808 fprintf (stderr
, "wsll\n");
2811 DECODE_G_BIT (state
, instr
, shift
);
2813 switch (BITS (22, 23))
2816 for (i
= 0; i
< 4; i
++)
2821 s
= ((wRHALF (BITS (16, 19), i
) & 0xffff) << shift
);
2822 r
|= (s
& 0xffff) << (i
* 16);
2823 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2824 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2829 for (i
= 0; i
< 2; i
++)
2834 s
= ((wRWORD (BITS (16, 19), i
) & 0xffffffff) << shift
);
2835 r
|= (s
& 0xffffffff) << (i
* 32);
2836 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
2837 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
2845 r
= ((wR
[BITS (16, 19)] & 0xffffffffffffffffULL
) << shift
);
2847 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
2848 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
2852 ARMul_UndefInstr (state
, instr
);
2857 wR
[BITS (12, 15)] = r
;
2858 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2864 WSRA (ARMul_State
* state
, ARMword instr
)
2873 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2877 fprintf (stderr
, "wsra\n");
2880 DECODE_G_BIT (state
, instr
, shift
);
2882 switch (BITS (22, 23))
2885 for (i
= 0; i
< 4; i
++)
2888 t
= (wRHALF (BITS (16, 19), i
) & 0x8000) ? 0xffff : 0;
2891 t
= wRHALF (BITS (16, 19), i
);
2897 r
|= (s
& 0xffff) << (i
* 16);
2898 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2899 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2904 for (i
= 0; i
< 2; i
++)
2907 t
= (wRWORD (BITS (16, 19), i
) & 0x80000000) ? 0xffffffff : 0;
2910 t
= EXTEND32 (wRWORD (BITS (16, 19), i
));
2914 r
|= (s
& 0xffffffff) << (i
* 32);
2915 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
2916 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
2922 r
= (wR
[BITS (16, 19)] & 0x8000000000000000ULL
) ? 0xffffffffffffffffULL
: 0;
2924 r
= ((signed long long) (wR
[BITS (16, 19)] & 0xffffffffffffffffULL
) >> shift
);
2925 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
2926 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
2930 ARMul_UndefInstr (state
, instr
);
2935 wR
[BITS (12, 15)] = r
;
2936 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2942 WSRL (ARMul_State
* state
, ARMword instr
)
2950 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2954 fprintf (stderr
, "wsrl\n");
2957 DECODE_G_BIT (state
, instr
, shift
);
2959 switch (BITS (22, 23))
2962 for (i
= 0; i
< 4; i
++)
2967 s
= ((unsigned) (wRHALF (BITS (16, 19), i
) & 0xffff) >> shift
);
2969 r
|= (s
& 0xffff) << (i
* 16);
2970 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2971 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2976 for (i
= 0; i
< 2; i
++)
2981 s
= ((unsigned long) (wRWORD (BITS (16, 19), i
) & 0xffffffff) >> shift
);
2983 r
|= (s
& 0xffffffff) << (i
* 32);
2984 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
2985 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
2993 r
= (wR
[BITS (16, 19)] & 0xffffffffffffffffULL
) >> shift
;
2995 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
2996 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
3000 ARMul_UndefInstr (state
, instr
);
3005 wR
[BITS (12, 15)] = r
;
3006 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3012 WSTR (ARMul_State
* state
, ARMword instr
)
3018 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3022 fprintf (stderr
, "wstr\n");
3025 address
= Compute_Iwmmxt_Address (state
, instr
, & failed
);
3029 if (BITS (28, 31) == 0xf)
3032 Iwmmxt_Store_Word (state
, address
, wC
[BITS (12, 15)]);
3034 else if (BIT (8) == 0)
3038 Iwmmxt_Store_Byte (state
, address
, wR
[BITS (12, 15)]);
3041 Iwmmxt_Store_Half_Word (state
, address
, wR
[BITS (12, 15)]);
3047 Iwmmxt_Store_Word (state
, address
, wR
[BITS (12, 15)]);
3050 Iwmmxt_Store_Double_Word (state
, address
, wR
[BITS (12, 15)]);
3057 WSUB (ARMul_State
* state
, ARMword instr
)
3068 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3072 fprintf (stderr
, "wsub\n");
3075 /* Subtract two numbers using the specified function,
3076 leaving setting the carry bit as required. */
3077 #define SUBx(x, y, m, f) \
3078 (*f) (wRBITS (BITS (16, 19), (x), (y)) & (m), \
3079 wRBITS (BITS ( 0, 3), (x), (y)) & (m), & carry, & overflow)
3081 switch (BITS (22, 23))
3084 for (i
= 0; i
< 8; i
++)
3086 switch (BITS (20, 21))
3089 s
= SUBx ((i
* 8), (i
* 8) + 7, 0xff, SubS8
);
3090 satrv
[BITIDX8 (i
)] = 0;
3091 r
|= (s
& 0xff) << (i
* 8);
3092 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
3093 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
3094 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
3095 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
3098 case UnsignedSaturation
:
3099 s
= SUBx ((i
* 8), (i
* 8) + 7, 0xff, SubU8
);
3100 x
= IwmmxtSaturateU8 (s
, satrv
+ BITIDX8 (i
));
3101 r
|= (x
& 0xff) << (i
* 8);
3102 SIMD8_SET (psr
, NBIT8 (x
), SIMD_NBIT
, i
);
3103 SIMD8_SET (psr
, ZBIT8 (x
), SIMD_ZBIT
, i
);
3104 if (! satrv
[BITIDX8 (i
)])
3106 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
3107 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
3111 case SignedSaturation
:
3112 s
= SUBx ((i
* 8), (i
* 8) + 7, 0xff, SubS8
);
3113 x
= IwmmxtSaturateS8 (s
, satrv
+ BITIDX8 (i
));
3114 r
|= (x
& 0xff) << (i
* 8);
3115 SIMD8_SET (psr
, NBIT8 (x
), SIMD_NBIT
, i
);
3116 SIMD8_SET (psr
, ZBIT8 (x
), SIMD_ZBIT
, i
);
3117 if (! satrv
[BITIDX8 (i
)])
3119 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
3120 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
3125 ARMul_UndefInstr (state
, instr
);
3132 satrv
[0] = satrv
[2] = satrv
[4] = satrv
[6] = 0;
3134 for (i
= 0; i
< 4; i
++)
3136 switch (BITS (20, 21))
3139 s
= SUBx ((i
* 16), (i
* 16) + 15, 0xffff, SubU16
);
3140 satrv
[BITIDX16 (i
)] = 0;
3141 r
|= (s
& 0xffff) << (i
* 16);
3142 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
3143 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
3144 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
3145 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
3148 case UnsignedSaturation
:
3149 s
= SUBx ((i
* 16), (i
* 16) + 15, 0xffff, SubU16
);
3150 x
= IwmmxtSaturateU16 (s
, satrv
+ BITIDX16 (i
));
3151 r
|= (x
& 0xffff) << (i
* 16);
3152 SIMD16_SET (psr
, NBIT16 (x
& 0xffff), SIMD_NBIT
, i
);
3153 SIMD16_SET (psr
, ZBIT16 (x
), SIMD_ZBIT
, i
);
3154 if (! satrv
[BITIDX16 (i
)])
3156 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
3157 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
3161 case SignedSaturation
:
3162 s
= SUBx ((i
* 16), (i
* 16) + 15, 0xffff, SubS16
);
3163 x
= IwmmxtSaturateS16 (s
, satrv
+ BITIDX16 (i
));
3164 r
|= (x
& 0xffff) << (i
* 16);
3165 SIMD16_SET (psr
, NBIT16 (x
), SIMD_NBIT
, i
);
3166 SIMD16_SET (psr
, ZBIT16 (x
), SIMD_ZBIT
, i
);
3167 if (! satrv
[BITIDX16 (i
)])
3169 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
3170 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
3175 ARMul_UndefInstr (state
, instr
);
3182 satrv
[0] = satrv
[1] = satrv
[2] = satrv
[4] = satrv
[5] = satrv
[6] = 0;
3184 for (i
= 0; i
< 2; i
++)
3186 switch (BITS (20, 21))
3189 s
= SUBx ((i
* 32), (i
* 32) + 31, 0xffffffff, SubU32
);
3190 satrv
[BITIDX32 (i
)] = 0;
3191 r
|= (s
& 0xffffffff) << (i
* 32);
3192 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
3193 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
3194 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
3195 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
3198 case UnsignedSaturation
:
3199 s
= SUBx ((i
* 32), (i
* 32) + 31, 0xffffffff, SubU32
);
3200 x
= IwmmxtSaturateU32 (s
, satrv
+ BITIDX32 (i
));
3201 r
|= (x
& 0xffffffff) << (i
* 32);
3202 SIMD32_SET (psr
, NBIT32 (x
), SIMD_NBIT
, i
);
3203 SIMD32_SET (psr
, ZBIT32 (x
), SIMD_ZBIT
, i
);
3204 if (! satrv
[BITIDX32 (i
)])
3206 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
3207 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
3211 case SignedSaturation
:
3212 s
= SUBx ((i
* 32), (i
* 32) + 31, 0xffffffff, SubS32
);
3213 x
= IwmmxtSaturateS32 (s
, satrv
+ BITIDX32 (i
));
3214 r
|= (x
& 0xffffffff) << (i
* 32);
3215 SIMD32_SET (psr
, NBIT32 (x
), SIMD_NBIT
, i
);
3216 SIMD32_SET (psr
, ZBIT32 (x
), SIMD_ZBIT
, i
);
3217 if (! satrv
[BITIDX32 (i
)])
3219 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
3220 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
3225 ARMul_UndefInstr (state
, instr
);
3232 ARMul_UndefInstr (state
, instr
);
3236 wR
[BITS (12, 15)] = r
;
3238 SET_wCSSFvec (satrv
);
3239 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3247 WUNPCKEH (ARMul_State
* state
, ARMword instr
)
3254 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3258 fprintf (stderr
, "wunpckeh\n");
3261 switch (BITS (22, 23))
3264 for (i
= 0; i
< 4; i
++)
3266 s
= wRBYTE (BITS (16, 19), i
+ 4);
3268 if (BIT (21) && NBIT8 (s
))
3271 r
|= (s
& 0xffff) << (i
* 16);
3272 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
3273 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
3278 for (i
= 0; i
< 2; i
++)
3280 s
= wRHALF (BITS (16, 19), i
+ 2);
3282 if (BIT (21) && NBIT16 (s
))
3285 r
|= (s
& 0xffffffff) << (i
* 32);
3286 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
3287 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
3292 r
= wRWORD (BITS (16, 19), 1);
3294 if (BIT (21) && NBIT32 (r
))
3295 r
|= 0xffffffff00000000ULL
;
3297 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
3298 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
3302 ARMul_UndefInstr (state
, instr
);
3307 wR
[BITS (12, 15)] = r
;
3308 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3314 WUNPCKEL (ARMul_State
* state
, ARMword instr
)
3321 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3325 fprintf (stderr
, "wunpckel\n");
3328 switch (BITS (22, 23))
3331 for (i
= 0; i
< 4; i
++)
3333 s
= wRBYTE (BITS (16, 19), i
);
3335 if (BIT (21) && NBIT8 (s
))
3338 r
|= (s
& 0xffff) << (i
* 16);
3339 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
3340 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
3345 for (i
= 0; i
< 2; i
++)
3347 s
= wRHALF (BITS (16, 19), i
);
3349 if (BIT (21) && NBIT16 (s
))
3352 r
|= (s
& 0xffffffff) << (i
* 32);
3353 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
3354 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
3359 r
= wRWORD (BITS (16, 19), 0);
3361 if (BIT (21) && NBIT32 (r
))
3362 r
|= 0xffffffff00000000ULL
;
3364 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
3365 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
3369 ARMul_UndefInstr (state
, instr
);
3374 wR
[BITS (12, 15)] = r
;
3375 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3381 WUNPCKIH (ARMul_State
* state
, ARMword instr
)
3389 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3393 fprintf (stderr
, "wunpckih\n");
3396 switch (BITS (22, 23))
3399 for (i
= 0; i
< 4; i
++)
3401 a
= wRBYTE (BITS (16, 19), i
+ 4);
3402 b
= wRBYTE (BITS ( 0, 3), i
+ 4);
3404 r
|= (s
& 0xffff) << (i
* 16);
3405 SIMD8_SET (psr
, NBIT8 (a
), SIMD_NBIT
, i
* 2);
3406 SIMD8_SET (psr
, ZBIT8 (a
), SIMD_ZBIT
, i
* 2);
3407 SIMD8_SET (psr
, NBIT8 (b
), SIMD_NBIT
, (i
* 2) + 1);
3408 SIMD8_SET (psr
, ZBIT8 (b
), SIMD_ZBIT
, (i
* 2) + 1);
3413 for (i
= 0; i
< 2; i
++)
3415 a
= wRHALF (BITS (16, 19), i
+ 2);
3416 b
= wRHALF (BITS ( 0, 3), i
+ 2);
3418 r
|= (s
& 0xffffffff) << (i
* 32);
3419 SIMD16_SET (psr
, NBIT16 (a
), SIMD_NBIT
, (i
* 2));
3420 SIMD16_SET (psr
, ZBIT16 (a
), SIMD_ZBIT
, (i
* 2));
3421 SIMD16_SET (psr
, NBIT16 (b
), SIMD_NBIT
, (i
* 2) + 1);
3422 SIMD16_SET (psr
, ZBIT16 (b
), SIMD_ZBIT
, (i
* 2) + 1);
3427 a
= wRWORD (BITS (16, 19), 1);
3428 s
= wRWORD (BITS ( 0, 3), 1);
3431 SIMD32_SET (psr
, NBIT32 (a
), SIMD_NBIT
, 0);
3432 SIMD32_SET (psr
, ZBIT32 (a
), SIMD_ZBIT
, 0);
3433 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, 1);
3434 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, 1);
3438 ARMul_UndefInstr (state
, instr
);
3443 wR
[BITS (12, 15)] = r
;
3444 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3450 WUNPCKIL (ARMul_State
* state
, ARMword instr
)
3458 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3462 fprintf (stderr
, "wunpckil\n");
3465 switch (BITS (22, 23))
3468 for (i
= 0; i
< 4; i
++)
3470 a
= wRBYTE (BITS (16, 19), i
);
3471 b
= wRBYTE (BITS ( 0, 3), i
);
3473 r
|= (s
& 0xffff) << (i
* 16);
3474 SIMD8_SET (psr
, NBIT8 (a
), SIMD_NBIT
, i
* 2);
3475 SIMD8_SET (psr
, ZBIT8 (a
), SIMD_ZBIT
, i
* 2);
3476 SIMD8_SET (psr
, NBIT8 (b
), SIMD_NBIT
, (i
* 2) + 1);
3477 SIMD8_SET (psr
, ZBIT8 (b
), SIMD_ZBIT
, (i
* 2) + 1);
3482 for (i
= 0; i
< 2; i
++)
3484 a
= wRHALF (BITS (16, 19), i
);
3485 b
= wRHALF (BITS ( 0, 3), i
);
3487 r
|= (s
& 0xffffffff) << (i
* 32);
3488 SIMD16_SET (psr
, NBIT16 (a
), SIMD_NBIT
, (i
* 2));
3489 SIMD16_SET (psr
, ZBIT16 (a
), SIMD_ZBIT
, (i
* 2));
3490 SIMD16_SET (psr
, NBIT16 (b
), SIMD_NBIT
, (i
* 2) + 1);
3491 SIMD16_SET (psr
, ZBIT16 (b
), SIMD_ZBIT
, (i
* 2) + 1);
3496 a
= wRWORD (BITS (16, 19), 0);
3497 s
= wRWORD (BITS ( 0, 3), 0);
3500 SIMD32_SET (psr
, NBIT32 (a
), SIMD_NBIT
, 0);
3501 SIMD32_SET (psr
, ZBIT32 (a
), SIMD_ZBIT
, 0);
3502 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, 1);
3503 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, 1);
3507 ARMul_UndefInstr (state
, instr
);
3512 wR
[BITS (12, 15)] = r
;
3513 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3519 WXOR (ARMword instr
)
3524 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3528 fprintf (stderr
, "wxor\n");
3531 result
= wR
[BITS (16, 19)] ^ wR
[BITS (0, 3)];
3532 wR
[BITS (12, 15)] = result
;
3534 SIMD64_SET (psr
, (result
== 0), SIMD_ZBIT
);
3535 SIMD64_SET (psr
, (result
& (1ULL << 63)), SIMD_NBIT
);
3538 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3543 /* This switch table is moved to a seperate function in order
3544 to work around a compiler bug in the host compiler... */
3547 Process_Instruction (ARMul_State
* state
, ARMword instr
)
3549 int status
= ARMul_BUSY
;
3551 switch ((BITS (20, 23) << 8) | BITS (4, 11))
3553 case 0x000: status
= WOR (instr
); break;
3554 case 0x011: status
= TMCR (state
, instr
); break;
3555 case 0x100: status
= WXOR (instr
); break;
3556 case 0x111: status
= TMRC (state
, instr
); break;
3557 case 0x300: status
= WANDN (instr
); break;
3558 case 0x200: status
= WAND (instr
); break;
3560 case 0x810: case 0xa10:
3561 status
= WMADD (instr
); break;
3563 case 0x10e: case 0x50e: case 0x90e: case 0xd0e:
3564 status
= WUNPCKIL (state
, instr
); break;
3565 case 0x10c: case 0x50c: case 0x90c: case 0xd0c:
3566 status
= WUNPCKIH (state
, instr
); break;
3567 case 0x012: case 0x112: case 0x412: case 0x512:
3568 status
= WSAD (instr
); break;
3569 case 0x010: case 0x110: case 0x210: case 0x310:
3570 status
= WMUL (instr
); break;
3571 case 0x410: case 0x510: case 0x610: case 0x710:
3572 status
= WMAC (instr
); break;
3573 case 0x006: case 0x406: case 0x806: case 0xc06:
3574 status
= WCMPEQ (state
, instr
); break;
3575 case 0x800: case 0x900: case 0xc00: case 0xd00:
3576 status
= WAVG2 (instr
); break;
3577 case 0x802: case 0x902: case 0xa02: case 0xb02:
3578 status
= WALIGNR (state
, instr
); break;
3579 case 0x601: case 0x605: case 0x609: case 0x60d:
3580 status
= TINSR (state
, instr
); break;
3581 case 0x107: case 0x507: case 0x907: case 0xd07:
3582 status
= TEXTRM (state
, instr
); break;
3583 case 0x117: case 0x517: case 0x917: case 0xd17:
3584 status
= TEXTRC (state
, instr
); break;
3585 case 0x401: case 0x405: case 0x409: case 0x40d:
3586 status
= TBCST (state
, instr
); break;
3587 case 0x113: case 0x513: case 0x913: case 0xd13:
3588 status
= TANDC (state
, instr
); break;
3589 case 0x01c: case 0x41c: case 0x81c: case 0xc1c:
3590 status
= WACC (state
, instr
); break;
3591 case 0x115: case 0x515: case 0x915: case 0xd15:
3592 status
= TORC (state
, instr
); break;
3593 case 0x103: case 0x503: case 0x903: case 0xd03:
3594 status
= TMOVMSK (state
, instr
); break;
3595 case 0x106: case 0x306: case 0x506: case 0x706:
3596 case 0x906: case 0xb06: case 0xd06: case 0xf06:
3597 status
= WCMPGT (state
, instr
); break;
3598 case 0x00e: case 0x20e: case 0x40e: case 0x60e:
3599 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
3600 status
= WUNPCKEL (state
, instr
); break;
3601 case 0x00c: case 0x20c: case 0x40c: case 0x60c:
3602 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
3603 status
= WUNPCKEH (state
, instr
); break;
3604 case 0x204: case 0x604: case 0xa04: case 0xe04:
3605 case 0x214: case 0x614: case 0xa14: case 0xe14:
3606 status
= WSRL (state
, instr
); break;
3607 case 0x004: case 0x404: case 0x804: case 0xc04:
3608 case 0x014: case 0x414: case 0x814: case 0xc14:
3609 status
= WSRA (state
, instr
); break;
3610 case 0x104: case 0x504: case 0x904: case 0xd04:
3611 case 0x114: case 0x514: case 0x914: case 0xd14:
3612 status
= WSLL (state
, instr
); break;
3613 case 0x304: case 0x704: case 0xb04: case 0xf04:
3614 case 0x314: case 0x714: case 0xb14: case 0xf14:
3615 status
= WROR (state
, instr
); break;
3616 case 0x116: case 0x316: case 0x516: case 0x716:
3617 case 0x916: case 0xb16: case 0xd16: case 0xf16:
3618 status
= WMIN (state
, instr
); break;
3619 case 0x016: case 0x216: case 0x416: case 0x616:
3620 case 0x816: case 0xa16: case 0xc16: case 0xe16:
3621 status
= WMAX (state
, instr
); break;
3622 case 0x002: case 0x102: case 0x202: case 0x302:
3623 case 0x402: case 0x502: case 0x602: case 0x702:
3624 status
= WALIGNI (instr
); break;
3625 case 0x01a: case 0x11a: case 0x21a: case 0x31a:
3626 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
3627 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
3628 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
3629 status
= WSUB (state
, instr
); break;
3630 case 0x01e: case 0x11e: case 0x21e: case 0x31e:
3631 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
3632 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
3633 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
3634 status
= WSHUFH (instr
); break;
3635 case 0x018: case 0x118: case 0x218: case 0x318:
3636 case 0x418: case 0x518: case 0x618: case 0x718:
3637 case 0x818: case 0x918: case 0xa18: case 0xb18:
3638 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
3639 status
= WADD (state
, instr
); break;
3640 case 0x008: case 0x108: case 0x208: case 0x308:
3641 case 0x408: case 0x508: case 0x608: case 0x708:
3642 case 0x808: case 0x908: case 0xa08: case 0xb08:
3643 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
3644 status
= WPACK (state
, instr
); break;
3645 case 0x201: case 0x203: case 0x205: case 0x207:
3646 case 0x209: case 0x20b: case 0x20d: case 0x20f:
3647 case 0x211: case 0x213: case 0x215: case 0x217:
3648 case 0x219: case 0x21b: case 0x21d: case 0x21f:
3649 switch (BITS (16, 19))
3651 case 0x0: status
= TMIA (state
, instr
); break;
3652 case 0x8: status
= TMIAPH (state
, instr
); break;
3656 case 0xf: status
= TMIAxy (state
, instr
); break;
3666 /* Process a possibly Intel(r) Wireless MMX(tm) technology instruction.
3667 Return true if the instruction was handled. */
3670 ARMul_HandleIwmmxt (ARMul_State
* state
, ARMword instr
)
3672 int status
= ARMul_BUSY
;
3674 if (BITS (24, 27) == 0xe)
3676 status
= Process_Instruction (state
, instr
);
3678 else if (BITS (25, 27) == 0x6)
3680 if (BITS (4, 11) == 0x0 && BITS (20, 24) == 0x4)
3681 status
= TMCRR (state
, instr
);
3682 else if (BITS (9, 11) == 0x0)
3684 if (BIT (20) == 0x0)
3685 status
= WSTR (state
, instr
);
3686 else if (BITS (20, 24) == 0x5)
3687 status
= TMRRC (state
, instr
);
3689 status
= WLDR (state
, instr
);
3693 if (status
== ARMul_CANT
)
3695 /* If the instruction was a recognised but illegal,
3696 perform the abort here rather than returning false.
3697 If we return false then ARMul_MRC may be called which
3698 will still abort, but which also perform the register
3700 ARMul_Abort (state
, ARMul_UndefinedInstrV
);
3701 status
= ARMul_DONE
;
3704 return status
== ARMul_DONE
;
3708 Fetch_Iwmmxt_Register (unsigned int regnum
, unsigned char * memory
)
3712 memcpy (memory
, wC
+ (regnum
- 16), sizeof wC
[0]);
3713 return sizeof wC
[0];
3717 memcpy (memory
, wR
+ regnum
, sizeof wR
[0]);
3718 return sizeof wR
[0];
3723 Store_Iwmmxt_Register (unsigned int regnum
, unsigned char * memory
)
3727 memcpy (wC
+ (regnum
- 16), memory
, sizeof wC
[0]);
3728 return sizeof wC
[0];
3732 memcpy (wR
+ regnum
, memory
, sizeof wR
[0]);
3733 return sizeof wR
[0];
This page took 0.112811 seconds and 4 git commands to generate.