1 /* iwmmxt.c -- Intel(r) Wireless MMX(tm) technology co-processor interface.
2 Copyright (C) 2002 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 2 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, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
27 /* Intel(r) Wireless MMX(tm) technology co-processor.
28 It uses co-processor numbers (0 and 1). There are 16 vector registers wRx
29 and 16 control registers wCx. Co-processors 0 and 1 are used in MCR/MRC
30 to access wRx and wCx respectively. */
32 static ARMdword wR
[16];
33 static ARMword wC
[16] = { 0x69051010 };
35 #define SUBSTR(w,t,m,n) ((t)(w << ((sizeof (t) * 8 - 1) - (n))) \
36 >> (((sizeof (t) * 8 - 1) - (n)) + (m)))
37 #define wCBITS(w,x,y) SUBSTR (wC[w], ARMword, x, y)
38 #define wRBITS(w,x,y) SUBSTR (wR[w], ARMdword, x, y)
48 /* Bits in the wCon register. */
49 #define WCON_CUP (1 << 0)
50 #define WCON_MUP (1 << 1)
52 /* Set the SIMD wCASF flags for 8, 16, 32 or 64-bit operations. */
53 #define SIMD8_SET(x, v, n, b) (x) |= ((v != 0) << ((((b) + 1) * 4) + (n)))
54 #define SIMD16_SET(x, v, n, h) (x) |= ((v != 0) << ((((h) + 1) * 8) + (n)))
55 #define SIMD32_SET(x, v, n, w) (x) |= ((v != 0) << ((((w) + 1) * 16) + (n)))
56 #define SIMD64_SET(x, v, n) (x) |= ((v != 0) << (32 + (n)))
58 /* Flags to pass as "n" above. */
64 /* Various status bit macros. */
65 #define NBIT8(x) ((x) & 0x80)
66 #define NBIT16(x) ((x) & 0x8000)
67 #define NBIT32(x) ((x) & 0x80000000)
68 #define NBIT64(x) ((x) & 0x8000000000000000ULL)
69 #define ZBIT8(x) (((x) & 0xff) == 0)
70 #define ZBIT16(x) (((x) & 0xffff) == 0)
71 #define ZBIT32(x) (((x) & 0xffffffff) == 0)
72 #define ZBIT64(x) (x == 0)
74 /* Access byte/half/word "n" of register "x". */
75 #define wRBYTE(x,n) wRBITS ((x), (n) * 8, (n) * 8 + 7)
76 #define wRHALF(x,n) wRBITS ((x), (n) * 16, (n) * 16 + 15)
77 #define wRWORD(x,n) wRBITS ((x), (n) * 32, (n) * 32 + 31)
79 /* Macro to handle how the G bit selects wCGR registers. */
80 #define DECODE_G_BIT(state, instr, shift) \
86 if (BIT (8)) /* G */ \
88 if (reg < wCGR0 || reg > wCGR3) \
90 ARMul_UndefInstr (state, instr); \
101 /* Index calculations for the satrv[] array. */
102 #define BITIDX8(x) (x)
103 #define BITIDX16(x) (((x) + 1) * 2 - 1)
104 #define BITIDX32(x) (((x) + 1) * 4 - 1)
106 /* Sign extension macros. */
107 #define EXTEND8(a) ((a) & 0x80 ? ((a) | 0xffffff00) : (a))
108 #define EXTEND16(a) ((a) & 0x8000 ? ((a) | 0xffff0000) : (a))
109 #define EXTEND32(a) ((a) & 0x80000000ULL ? ((a) | 0xffffffff00000000ULL) : (a))
111 /* Set the wCSSF from 8 values. */
112 #define SET_wCSSF(a,b,c,d,e,f,g,h) \
113 wC[wCSSF] = (((h) != 0) << 7) | (((g) != 0) << 6) \
114 | (((f) != 0) << 5) | (((e) != 0) << 4) \
115 | (((d) != 0) << 3) | (((c) != 0) << 2) \
116 | (((b) != 0) << 1) | (((a) != 0) << 0);
118 /* Set the wCSSR from an array with 8 values. */
119 #define SET_wCSSFvec(v) \
120 SET_wCSSF((v)[0],(v)[1],(v)[2],(v)[3],(v)[4],(v)[5],(v)[6],(v)[7])
122 /* Size qualifiers for vector operations. */
128 /* Saturation qualifiers for vector operations. */
129 #define NoSaturation 0
130 #define UnsignedSaturation 1
131 #define SignedSaturation 3
135 static ARMword
Add32 (ARMword
, ARMword
, int *, int *, ARMword
);
136 static ARMdword
AddS32 (ARMdword
, ARMdword
, int *, int *);
137 static ARMdword
AddU32 (ARMdword
, ARMdword
, int *, int *);
138 static ARMword
AddS16 (ARMword
, ARMword
, int *, int *);
139 static ARMword
AddU16 (ARMword
, ARMword
, int *, int *);
140 static ARMword
AddS8 (ARMword
, ARMword
, int *, int *);
141 static ARMword
AddU8 (ARMword
, ARMword
, int *, int *);
142 static ARMword
Sub32 (ARMword
, ARMword
, int *, int *, ARMword
);
143 static ARMdword
SubS32 (ARMdword
, ARMdword
, int *, int *);
144 static ARMdword
SubU32 (ARMdword
, ARMdword
, int *, int *);
145 static ARMword
SubS16 (ARMword
, ARMword
, int *, int *);
146 static ARMword
SubS8 (ARMword
, ARMword
, int *, int *);
147 static ARMword
SubU16 (ARMword
, ARMword
, int *, int *);
148 static ARMword
SubU8 (ARMword
, ARMword
, int *, int *);
149 static unsigned char IwmmxtSaturateU8 (signed short, int *);
150 static signed char IwmmxtSaturateS8 (signed short, int *);
151 static unsigned short IwmmxtSaturateU16 (signed int, int *);
152 static signed short IwmmxtSaturateS16 (signed int, int *);
153 static unsigned long IwmmxtSaturateU32 (signed long long, int *);
154 static signed long IwmmxtSaturateS32 (signed long long, int *);
155 static ARMword
Compute_Iwmmxt_Address (ARMul_State
*, ARMword
, int *);
156 static ARMdword
Iwmmxt_Load_Double_Word (ARMul_State
*, ARMword
);
157 static ARMword
Iwmmxt_Load_Word (ARMul_State
*, ARMword
);
158 static ARMword
Iwmmxt_Load_Half_Word (ARMul_State
*, ARMword
);
159 static ARMword
Iwmmxt_Load_Byte (ARMul_State
*, ARMword
);
160 static void Iwmmxt_Store_Double_Word (ARMul_State
*, ARMword
, ARMdword
);
161 static void Iwmmxt_Store_Word (ARMul_State
*, ARMword
, ARMword
);
162 static void Iwmmxt_Store_Half_Word (ARMul_State
*, ARMword
, ARMword
);
163 static void Iwmmxt_Store_Byte (ARMul_State
*, ARMword
, ARMword
);
164 static int Process_Instruction (ARMul_State
*, ARMword
);
166 static int TANDC (ARMul_State
*, ARMword
);
167 static int TBCST (ARMul_State
*, ARMword
);
168 static int TEXTRC (ARMul_State
*, ARMword
);
169 static int TEXTRM (ARMul_State
*, ARMword
);
170 static int TINSR (ARMul_State
*, ARMword
);
171 static int TMCR (ARMul_State
*, ARMword
);
172 static int TMCRR (ARMul_State
*, ARMword
);
173 static int TMIA (ARMul_State
*, ARMword
);
174 static int TMIAPH (ARMul_State
*, ARMword
);
175 static int TMIAxy (ARMul_State
*, ARMword
);
176 static int TMOVMSK (ARMul_State
*, ARMword
);
177 static int TMRC (ARMul_State
*, ARMword
);
178 static int TMRRC (ARMul_State
*, ARMword
);
179 static int TORC (ARMul_State
*, ARMword
);
180 static int WACC (ARMul_State
*, ARMword
);
181 static int WADD (ARMul_State
*, ARMword
);
182 static int WALIGNI (ARMword
);
183 static int WALIGNR (ARMul_State
*, ARMword
);
184 static int WAND (ARMword
);
185 static int WANDN (ARMword
);
186 static int WAVG2 (ARMword
);
187 static int WCMPEQ (ARMul_State
*, ARMword
);
188 static int WCMPGT (ARMul_State
*, ARMword
);
189 static int WLDR (ARMul_State
*, ARMword
);
190 static int WMAC (ARMword
);
191 static int WMADD (ARMword
);
192 static int WMAX (ARMul_State
*, ARMword
);
193 static int WMIN (ARMul_State
*, ARMword
);
194 static int WMUL (ARMword
);
195 static int WOR (ARMword
);
196 static int WPACK (ARMul_State
*, ARMword
);
197 static int WROR (ARMul_State
*, ARMword
);
198 static int WSAD (ARMword
);
199 static int WSHUFH (ARMword
);
200 static int WSLL (ARMul_State
*, ARMword
);
201 static int WSRA (ARMul_State
*, ARMword
);
202 static int WSRL (ARMul_State
*, ARMword
);
203 static int WSTR (ARMul_State
*, ARMword
);
204 static int WSUB (ARMul_State
*, ARMword
);
205 static int WUNPCKEH (ARMul_State
*, ARMword
);
206 static int WUNPCKEL (ARMul_State
*, ARMword
);
207 static int WUNPCKIH (ARMul_State
*, ARMword
);
208 static int WUNPCKIL (ARMul_State
*, ARMword
);
209 static int WXOR (ARMword
);
211 /* This function does the work of adding two 32bit values
212 together, and calculating if a carry has occurred. */
221 ARMword result
= (a1
+ a2
);
222 unsigned int uresult
= (unsigned int) result
;
223 unsigned int ua1
= (unsigned int) a1
;
225 /* If (result == a1) and (a2 == 0),
226 or (result > a2) then we have no carry. */
227 * carry_ptr
= ((uresult
== ua1
) ? (a2
!= 0) : (uresult
< ua1
));
229 /* Overflow occurs when both arguments are the
230 same sign, but the result is a different sign. */
231 * overflow_ptr
= ( ( (result
& sign_mask
) && !(a1
& sign_mask
) && !(a2
& sign_mask
))
232 || (!(result
& sign_mask
) && (a1
& sign_mask
) && (a2
& sign_mask
)));
238 AddS32 (ARMdword a1
, ARMdword a2
, int * carry_ptr
, int * overflow_ptr
)
241 unsigned int uresult
;
248 uresult
= (unsigned int) result
;
249 ua1
= (unsigned int) a1
;
251 * carry_ptr
= ((uresult
== a1
) ? (a2
!= 0) : (uresult
< ua1
));
253 * overflow_ptr
= ( ( (result
& 0x80000000ULL
) && !(a1
& 0x80000000ULL
) && !(a2
& 0x80000000ULL
))
254 || (!(result
& 0x80000000ULL
) && (a1
& 0x80000000ULL
) && (a2
& 0x80000000ULL
)));
260 AddU32 (ARMdword a1
, ARMdword a2
, int * carry_ptr
, int * overflow_ptr
)
263 unsigned int uresult
;
270 uresult
= (unsigned int) result
;
271 ua1
= (unsigned int) a1
;
273 * carry_ptr
= ((uresult
== a1
) ? (a2
!= 0) : (uresult
< ua1
));
275 * overflow_ptr
= ( ( (result
& 0x80000000ULL
) && !(a1
& 0x80000000ULL
) && !(a2
& 0x80000000ULL
))
276 || (!(result
& 0x80000000ULL
) && (a1
& 0x80000000ULL
) && (a2
& 0x80000000ULL
)));
282 AddS16 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
287 return Add32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x8000);
291 AddU16 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
296 return Add32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x8000);
300 AddS8 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
305 return Add32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x80);
309 AddU8 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
314 return Add32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x80);
324 ARMword result
= (a1
- a2
);
325 unsigned int ua1
= (unsigned int) a1
;
326 unsigned int ua2
= (unsigned int) a2
;
328 /* A borrow occurs if a2 is (unsigned) larger than a1.
329 However the carry flag is *cleared* if a borrow occurs. */
330 * borrow_ptr
= ! (ua2
> ua1
);
332 /* Overflow occurs when a negative number is subtracted from a
333 positive number and the result is negative or a positive
334 number is subtracted from a negative number and the result is
336 * overflow_ptr
= ( (! (a1
& sign_mask
) && (a2
& sign_mask
) && (result
& sign_mask
))
337 || ((a1
& sign_mask
) && ! (a2
& sign_mask
) && ! (result
& sign_mask
)));
343 SubS32 (ARMdword a1
, ARMdword a2
, int * borrow_ptr
, int * overflow_ptr
)
353 ua1
= (unsigned int) a1
;
354 ua2
= (unsigned int) a2
;
356 * borrow_ptr
= ! (ua2
> ua1
);
358 * overflow_ptr
= ( (! (a1
& 0x80000000ULL
) && (a2
& 0x80000000ULL
) && (result
& 0x80000000ULL
))
359 || ((a1
& 0x80000000ULL
) && ! (a2
& 0x80000000ULL
) && ! (result
& 0x80000000ULL
)));
365 SubS16 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
370 return Sub32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x8000);
374 SubS8 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
379 return Sub32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x80);
383 SubU16 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
388 return Sub32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x8000);
392 SubU8 (ARMword a1
, ARMword a2
, int * carry_ptr
, int * overflow_ptr
)
397 return Sub32 (a1
, a2
, carry_ptr
, overflow_ptr
, 0x80);
401 SubU32 (ARMdword a1
, ARMdword a2
, int * borrow_ptr
, int * overflow_ptr
)
411 ua1
= (unsigned int) a1
;
412 ua2
= (unsigned int) a2
;
414 * borrow_ptr
= ! (ua2
> ua1
);
416 * overflow_ptr
= ( (! (a1
& 0x80000000ULL
) && (a2
& 0x80000000ULL
) && (result
& 0x80000000ULL
))
417 || ((a1
& 0x80000000ULL
) && ! (a2
& 0x80000000ULL
) && ! (result
& 0x80000000ULL
)));
422 /* For the saturation. */
425 IwmmxtSaturateU8 (signed short val
, int * sat
)
448 IwmmxtSaturateS8 (signed short val
, int * sat
)
470 static unsigned short
471 IwmmxtSaturateU16 (signed int val
, int * sat
)
480 else if (val
> 0xffff)
494 IwmmxtSaturateS16 (signed int val
, int * sat
)
503 else if (val
> 0x7fff)
517 IwmmxtSaturateU32 (signed long long val
, int * sat
)
526 else if (val
> 0xffffffff)
533 rv
= val
& 0xffffffff;
540 IwmmxtSaturateS32 (signed long long val
, int * sat
)
544 if (val
< -0x80000000LL
)
549 else if (val
> 0x7fffffff)
556 rv
= val
& 0xffffffff;
562 /* Intel(r) Wireless MMX(tm) technology Acessor functions. */
565 IwmmxtLDC (ARMul_State
* state ATTRIBUTE_UNUSED
,
566 unsigned type ATTRIBUTE_UNUSED
,
574 IwmmxtSTC (ARMul_State
* state ATTRIBUTE_UNUSED
,
575 unsigned type ATTRIBUTE_UNUSED
,
583 IwmmxtMRC (ARMul_State
* state ATTRIBUTE_UNUSED
,
584 unsigned type ATTRIBUTE_UNUSED
,
592 IwmmxtMCR (ARMul_State
* state ATTRIBUTE_UNUSED
,
593 unsigned type ATTRIBUTE_UNUSED
,
601 IwmmxtCDP (ARMul_State
* state
, unsigned type
, ARMword instr
)
606 /* Intel(r) Wireless MMX(tm) technology instruction implementations. */
609 TANDC (ARMul_State
* state
, ARMword instr
)
613 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
617 fprintf (stderr
, "tandc\n");
620 /* The Rd field must be r15. */
621 if (BITS (12, 15) != 15)
624 /* The CRn field must be r3. */
625 if (BITS (16, 19) != 3)
628 /* The CRm field must be r0. */
629 if (BITS (0, 3) != 0)
632 cpsr
= ARMul_GetCPSR (state
) & 0x0fffffff;
634 switch (BITS (22, 23))
637 cpsr
|= ( (wCBITS (wCASF
, 28, 31) & wCBITS (wCASF
, 24, 27)
638 & wCBITS (wCASF
, 20, 23) & wCBITS (wCASF
, 16, 19)
639 & wCBITS (wCASF
, 12, 15) & wCBITS (wCASF
, 8, 11)
640 & wCBITS (wCASF
, 4, 7) & wCBITS (wCASF
, 0, 3)) << 28);
644 cpsr
|= ( (wCBITS (wCASF
, 28, 31) & wCBITS (wCASF
, 20, 23)
645 & wCBITS (wCASF
, 12, 15) & wCBITS (wCASF
, 4, 7)) << 28);
649 cpsr
|= ((wCBITS (wCASF
, 28, 31) & wCBITS (wCASF
, 12, 15)) << 28);
653 ARMul_UndefInstr (state
, instr
);
657 ARMul_SetCPSR (state
, cpsr
);
663 TBCST (ARMul_State
* state
, ARMword instr
)
668 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
672 fprintf (stderr
, "tbcst\n");
675 Rn
= state
->Reg
[BITS (12, 15)];
676 if (BITS (12, 15) == 15)
685 wR
[wRd
] = (Rn
<< 56) | (Rn
<< 48) | (Rn
<< 40) | (Rn
<< 32)
686 | (Rn
<< 24) | (Rn
<< 16) | (Rn
<< 8) | Rn
;
691 wR
[wRd
] = (Rn
<< 48) | (Rn
<< 32) | (Rn
<< 16) | Rn
;
696 wR
[wRd
] = (Rn
<< 32) | Rn
;
700 ARMul_UndefInstr (state
, instr
);
704 wC
[wCon
] |= WCON_MUP
;
709 TEXTRC (ARMul_State
* state
, ARMword instr
)
714 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
718 fprintf (stderr
, "textrc\n");
721 /* The Rd field must be r15. */
722 if (BITS (12, 15) != 15)
725 /* The CRn field must be r3. */
726 if (BITS (16, 19) != 3)
729 /* The CRm field must be 0xxx. */
733 selector
= BITS (0, 2);
734 cpsr
= ARMul_GetCPSR (state
) & 0x0fffffff;
736 switch (BITS (22, 23))
738 case Bqual
: selector
*= 4; break;
739 case Hqual
: selector
= ((selector
& 3) * 8) + 4; break;
740 case Wqual
: selector
= ((selector
& 1) * 16) + 12; break;
743 ARMul_UndefInstr (state
, instr
);
747 cpsr
|= wCBITS (wCASF
, selector
, selector
+ 3) << 28;
748 ARMul_SetCPSR (state
, cpsr
);
754 TEXTRM (ARMul_State
* state
, ARMword instr
)
761 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
765 fprintf (stderr
, "textrm\n");
770 offset
= BITS (0, 2);
772 switch (BITS (22, 23))
776 Rd
= wRBITS (wRn
, offset
, offset
+ 7);
782 offset
= (offset
& 3) * 16;
783 Rd
= wRBITS (wRn
, offset
, offset
+ 15);
789 offset
= (offset
& 1) * 32;
790 Rd
= wRBITS (wRn
, offset
, offset
+ 31);
794 ARMul_UndefInstr (state
, instr
);
798 if (BITS (12, 15) == 15)
799 ARMul_UndefInstr (state
, instr
);
801 state
->Reg
[BITS (12, 15)] = Rd
;
807 TINSR (ARMul_State
* state
, ARMword instr
)
813 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
817 fprintf (stderr
, "tinsr\n");
821 data
= state
->Reg
[BITS (12, 15)];
822 offset
= BITS (0, 2);
830 case 0: wR
[wRd
] = data
| (wRBITS (wRd
, 8, 63) << 8); break;
831 case 1: wR
[wRd
] = wRBITS (wRd
, 0, 7) | (data
<< 8) | (wRBITS (wRd
, 16, 63) << 16); break;
832 case 2: wR
[wRd
] = wRBITS (wRd
, 0, 15) | (data
<< 16) | (wRBITS (wRd
, 24, 63) << 24); break;
833 case 3: wR
[wRd
] = wRBITS (wRd
, 0, 23) | (data
<< 24) | (wRBITS (wRd
, 32, 63) << 32); break;
834 case 4: wR
[wRd
] = wRBITS (wRd
, 0, 31) | (data
<< 32) | (wRBITS (wRd
, 40, 63) << 40); break;
835 case 5: wR
[wRd
] = wRBITS (wRd
, 0, 39) | (data
<< 40) | (wRBITS (wRd
, 48, 63) << 48); break;
836 case 6: wR
[wRd
] = wRBITS (wRd
, 0, 47) | (data
<< 48) | (wRBITS (wRd
, 56, 63) << 56); break;
837 case 7: wR
[wRd
] = wRBITS (wRd
, 0, 55) | (data
<< 56); break;
846 case 0: wR
[wRd
] = data
| (wRBITS (wRd
, 16, 63) << 16); break;
847 case 1: wR
[wRd
] = wRBITS (wRd
, 0, 15) | (data
<< 16) | (wRBITS (wRd
, 32, 63) << 32); break;
848 case 2: wR
[wRd
] = wRBITS (wRd
, 0, 31) | (data
<< 32) | (wRBITS (wRd
, 48, 63) << 48); break;
849 case 3: wR
[wRd
] = wRBITS (wRd
, 0, 47) | (data
<< 48); break;
855 wR
[wRd
] = wRBITS (wRd
, 0, 31) | (data
<< 32);
857 wR
[wRd
] = (wRBITS (wRd
, 32, 63) << 32) | data
;
861 ARMul_UndefInstr (state
, instr
);
865 wC
[wCon
] |= WCON_MUP
;
870 TMCR (ARMul_State
* state
, ARMword instr
)
875 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
879 fprintf (stderr
, "tmcr\n");
882 if (BITS (0, 3) != 0)
885 val
= state
->Reg
[BITS (12, 15)];
886 if (BITS (12, 15) == 15)
889 wCreg
= BITS (16, 19);
894 /* The wCID register is read only. */
898 /* Writing to the MUP or CUP bits clears them. */
899 wC
[wCon
] &= ~ (val
& 0x3);
903 /* Only the bottom 8 bits can be written to.
904 The higher bits write as zero. */
905 wC
[wCSSF
] = (val
& 0xff);
906 wC
[wCon
] |= WCON_CUP
;
911 wC
[wCon
] |= WCON_CUP
;
919 TMCRR (ARMul_State
* state
, ARMword instr
)
921 ARMdword RdHi
= state
->Reg
[BITS (16, 19)];
922 ARMword RdLo
= state
->Reg
[BITS (12, 15)];
924 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
928 fprintf (stderr
, "tmcrr\n");
931 if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15))
934 wR
[BITS (0, 3)] = (RdHi
<< 32) | RdLo
;
936 wC
[wCon
] |= WCON_MUP
;
942 TMIA (ARMul_State
* state
, ARMword instr
)
944 signed long long a
, b
;
946 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
950 fprintf (stderr
, "tmia\n");
953 if ((BITS (0, 3) == 15) || (BITS (12, 15) == 15))
955 ARMul_UndefInstr (state
, instr
);
959 a
= state
->Reg
[BITS (0, 3)];
960 b
= state
->Reg
[BITS (12, 15)];
965 wR
[BITS (5, 8)] += a
* b
;
966 wC
[wCon
] |= WCON_MUP
;
972 TMIAPH (ARMul_State
* state
, ARMword instr
)
974 signed long a
, b
, result
;
976 ARMword Rm
= state
->Reg
[BITS (0, 3)];
977 ARMword Rs
= state
->Reg
[BITS (12, 15)];
979 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
983 fprintf (stderr
, "tmiaph\n");
986 if (BITS (0, 3) == 15 || BITS (12, 15) == 15)
988 ARMul_UndefInstr (state
, instr
);
992 a
= SUBSTR (Rs
, ARMword
, 16, 31);
993 b
= SUBSTR (Rm
, ARMword
, 16, 31);
1003 wR
[BITS (5, 8)] += r
;
1005 a
= SUBSTR (Rs
, ARMword
, 0, 15);
1006 b
= SUBSTR (Rm
, ARMword
, 0, 15);
1016 wR
[BITS (5, 8)] += r
;
1017 wC
[wCon
] |= WCON_MUP
;
1023 TMIAxy (ARMul_State
* state
, ARMword instr
)
1029 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1033 fprintf (stderr
, "tmiaxy\n");
1036 if (BITS (0, 3) == 15 || BITS (12, 15) == 15)
1038 ARMul_UndefInstr (state
, instr
);
1042 Rm
= state
->Reg
[BITS (0, 3)];
1048 Rs
= state
->Reg
[BITS (12, 15)];
1063 if (temp
& (1 << 31))
1066 wR
[BITS (5, 8)] += temp
;
1067 wC
[wCon
] |= WCON_MUP
;
1073 TMOVMSK (ARMul_State
* state
, ARMword instr
)
1078 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1082 fprintf (stderr
, "tmovmsk\n");
1085 /* The CRm field must be r0. */
1086 if (BITS (0, 3) != 0)
1089 wRn
= BITS (16, 19);
1091 switch (BITS (22, 23))
1094 result
= ( (wRBITS (wRn
, 63, 63) << 7)
1095 | (wRBITS (wRn
, 55, 55) << 6)
1096 | (wRBITS (wRn
, 47, 47) << 5)
1097 | (wRBITS (wRn
, 39, 39) << 4)
1098 | (wRBITS (wRn
, 31, 31) << 3)
1099 | (wRBITS (wRn
, 23, 23) << 2)
1100 | (wRBITS (wRn
, 15, 15) << 1)
1101 | (wRBITS (wRn
, 7, 7) << 0));
1105 result
= ( (wRBITS (wRn
, 63, 63) << 3)
1106 | (wRBITS (wRn
, 47, 47) << 2)
1107 | (wRBITS (wRn
, 31, 31) << 1)
1108 | (wRBITS (wRn
, 15, 15) << 0));
1112 result
= (wRBITS (wRn
, 63, 63) << 1) | wRBITS (wRn
, 31, 31);
1116 ARMul_UndefInstr (state
, instr
);
1120 state
->Reg
[BITS (12, 15)] = result
;
1126 TMRC (ARMul_State
* state
, ARMword instr
)
1128 int reg
= BITS (12, 15);
1130 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1134 fprintf (stderr
, "tmrc\n");
1137 if (BITS (0, 3) != 0)
1141 ARMul_UndefInstr (state
, instr
);
1143 state
->Reg
[reg
] = wC
[BITS (16, 19)];
1149 TMRRC (ARMul_State
* state
, ARMword instr
)
1151 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1155 fprintf (stderr
, "tmrrc\n");
1158 if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15) || (BITS (4, 11) != 0))
1159 ARMul_UndefInstr (state
, instr
);
1162 state
->Reg
[BITS (16, 19)] = wRBITS (BITS (0, 3), 32, 63);
1163 state
->Reg
[BITS (12, 15)] = wRBITS (BITS (0, 3), 0, 31);
1170 TORC (ARMul_State
* state
, ARMword instr
)
1172 ARMword cpsr
= ARMul_GetCPSR (state
);
1174 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1178 fprintf (stderr
, "torc\n");
1181 /* The Rd field must be r15. */
1182 if (BITS (12, 15) != 15)
1185 /* The CRn field must be r3. */
1186 if (BITS (16, 19) != 3)
1189 /* The CRm field must be r0. */
1190 if (BITS (0, 3) != 0)
1195 switch (BITS (22, 23))
1198 cpsr
|= ( (wCBITS (wCASF
, 28, 31) | wCBITS (wCASF
, 24, 27)
1199 | wCBITS (wCASF
, 20, 23) | wCBITS (wCASF
, 16, 19)
1200 | wCBITS (wCASF
, 12, 15) | wCBITS (wCASF
, 8, 11)
1201 | wCBITS (wCASF
, 4, 7) | wCBITS (wCASF
, 0, 3)) << 28);
1205 cpsr
|= ( (wCBITS (wCASF
, 28, 31) | wCBITS (wCASF
, 20, 23)
1206 | wCBITS (wCASF
, 12, 15) | wCBITS (wCASF
, 4, 7)) << 28);
1210 cpsr
|= ((wCBITS (wCASF
, 28, 31) | wCBITS (wCASF
, 12, 15)) << 28);
1214 ARMul_UndefInstr (state
, instr
);
1218 ARMul_SetCPSR (state
, cpsr
);
1224 WACC (ARMul_State
* state
, ARMword instr
)
1228 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1232 fprintf (stderr
, "wacc\n");
1235 wRn
= BITS (16, 19);
1237 switch (BITS (22, 23))
1240 wR
[BITS (12, 15)] =
1241 wRBITS (wRn
, 56, 63) + wRBITS (wRn
, 48, 55)
1242 + wRBITS (wRn
, 40, 47) + wRBITS (wRn
, 32, 39)
1243 + wRBITS (wRn
, 24, 31) + wRBITS (wRn
, 16, 23)
1244 + wRBITS (wRn
, 8, 15) + wRBITS (wRn
, 0, 7);
1248 wR
[BITS (12, 15)] =
1249 wRBITS (wRn
, 48, 63) + wRBITS (wRn
, 32, 47)
1250 + wRBITS (wRn
, 16, 31) + wRBITS (wRn
, 0, 15);
1254 wR
[BITS (12, 15)] = wRBITS (wRn
, 32, 63) + wRBITS (wRn
, 0, 31);
1258 ARMul_UndefInstr (state
, instr
);
1262 wC
[wCon
] |= WCON_MUP
;
1267 WADD (ARMul_State
* state
, ARMword instr
)
1278 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1282 fprintf (stderr
, "wadd\n");
1285 /* Add two numbers using the specified function,
1286 leaving setting the carry bit as required. */
1287 #define ADDx(x, y, m, f) \
1288 (*f) (wRBITS (BITS (16, 19), (x), (y)) & (m), \
1289 wRBITS (BITS ( 0, 3), (x), (y)) & (m), \
1290 & carry, & overflow)
1292 switch (BITS (22, 23))
1295 for (i
= 0; i
< 8; i
++)
1297 switch (BITS (20, 21))
1300 s
= ADDx ((i
* 8), (i
* 8) + 7, 0xff, AddS8
);
1301 satrv
[BITIDX8 (i
)] = 0;
1302 r
|= (s
& 0xff) << (i
* 8);
1303 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
1304 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
1305 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
1306 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
1309 case UnsignedSaturation
:
1310 s
= ADDx ((i
* 8), (i
* 8) + 7, 0xff, AddU8
);
1311 x
= IwmmxtSaturateU8 (s
, satrv
+ BITIDX8 (i
));
1312 r
|= (x
& 0xff) << (i
* 8);
1313 SIMD8_SET (psr
, NBIT8 (x
), SIMD_NBIT
, i
);
1314 SIMD8_SET (psr
, ZBIT8 (x
), SIMD_ZBIT
, i
);
1315 if (! satrv
[BITIDX8 (i
)])
1317 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
1318 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
1322 case SignedSaturation
:
1323 s
= ADDx ((i
* 8), (i
* 8) + 7, 0xff, AddS8
);
1324 x
= IwmmxtSaturateS8 (s
, satrv
+ BITIDX8 (i
));
1325 r
|= (x
& 0xff) << (i
* 8);
1326 SIMD8_SET (psr
, NBIT8 (x
), SIMD_NBIT
, i
);
1327 SIMD8_SET (psr
, ZBIT8 (x
), SIMD_ZBIT
, i
);
1328 if (! satrv
[BITIDX8 (i
)])
1330 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
1331 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
1336 ARMul_UndefInstr (state
, instr
);
1343 satrv
[0] = satrv
[2] = satrv
[4] = satrv
[6] = 0;
1345 for (i
= 0; i
< 4; i
++)
1347 switch (BITS (20, 21))
1350 s
= ADDx ((i
* 16), (i
* 16) + 15, 0xffff, AddS16
);
1351 satrv
[BITIDX16 (i
)] = 0;
1352 r
|= (s
& 0xffff) << (i
* 16);
1353 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
1354 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
1355 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
1356 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
1359 case UnsignedSaturation
:
1360 s
= ADDx ((i
* 16), (i
* 16) + 15, 0xffff, AddU16
);
1361 x
= IwmmxtSaturateU16 (s
, satrv
+ BITIDX16 (i
));
1362 r
|= (x
& 0xffff) << (i
* 16);
1363 SIMD16_SET (psr
, NBIT16 (x
), SIMD_NBIT
, i
);
1364 SIMD16_SET (psr
, ZBIT16 (x
), SIMD_ZBIT
, i
);
1365 if (! satrv
[BITIDX16 (i
)])
1367 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
1368 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
1372 case SignedSaturation
:
1373 s
= ADDx ((i
* 16), (i
* 16) + 15, 0xffff, AddS16
);
1374 x
= IwmmxtSaturateS16 (s
, satrv
+ BITIDX16 (i
));
1375 r
|= (x
& 0xffff) << (i
* 16);
1376 SIMD16_SET (psr
, NBIT16 (x
), SIMD_NBIT
, i
);
1377 SIMD16_SET (psr
, ZBIT16 (x
), SIMD_ZBIT
, i
);
1378 if (! satrv
[BITIDX16 (i
)])
1380 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
1381 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
1386 ARMul_UndefInstr (state
, instr
);
1393 satrv
[0] = satrv
[1] = satrv
[2] = satrv
[4] = satrv
[5] = satrv
[6] = 0;
1395 for (i
= 0; i
< 2; i
++)
1397 switch (BITS (20, 21))
1400 s
= ADDx ((i
* 32), (i
* 32) + 31, 0xffffffff, AddS32
);
1401 satrv
[BITIDX32 (i
)] = 0;
1402 r
|= (s
& 0xffffffff) << (i
* 32);
1403 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
1404 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
1405 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
1406 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
1409 case UnsignedSaturation
:
1410 s
= ADDx ((i
* 32), (i
* 32) + 31, 0xffffffff, AddU32
);
1411 x
= IwmmxtSaturateU32 (s
, satrv
+ BITIDX32 (i
));
1412 r
|= (x
& 0xffffffff) << (i
* 32);
1413 SIMD32_SET (psr
, NBIT32 (x
), SIMD_NBIT
, i
);
1414 SIMD32_SET (psr
, ZBIT32 (x
), SIMD_ZBIT
, i
);
1415 if (! satrv
[BITIDX32 (i
)])
1417 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
1418 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
1422 case SignedSaturation
:
1423 s
= ADDx ((i
* 32), (i
* 32) + 31, 0xffffffff, AddS32
);
1424 x
= IwmmxtSaturateS32 (s
, satrv
+ BITIDX32 (i
));
1425 r
|= (x
& 0xffffffff) << (i
* 32);
1426 SIMD32_SET (psr
, NBIT32 (x
), SIMD_NBIT
, i
);
1427 SIMD32_SET (psr
, ZBIT32 (x
), SIMD_ZBIT
, i
);
1428 if (! satrv
[BITIDX32 (i
)])
1430 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
1431 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
1436 ARMul_UndefInstr (state
, instr
);
1443 ARMul_UndefInstr (state
, instr
);
1448 wR
[BITS (12, 15)] = r
;
1449 wC
[wCon
] |= (WCON_MUP
| WCON_CUP
);
1451 SET_wCSSFvec (satrv
);
1459 WALIGNI (ARMword instr
)
1461 int shift
= BITS (20, 22) * 8;
1463 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1467 fprintf (stderr
, "waligni\n");
1471 wR
[BITS (12, 15)] =
1472 wRBITS (BITS (16, 19), shift
, 63)
1473 | (wRBITS (BITS (0, 3), 0, shift
) << ((64 - shift
)));
1475 wR
[BITS (12, 15)] = wR
[BITS (16, 19)];
1477 wC
[wCon
] |= WCON_MUP
;
1482 WALIGNR (ARMul_State
* state
, ARMword instr
)
1484 int shift
= (wC
[BITS (20, 21) + 8] & 0x7) * 8;
1486 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1490 fprintf (stderr
, "walignr\n");
1494 wR
[BITS (12, 15)] =
1495 wRBITS (BITS (16, 19), shift
, 63)
1496 | (wRBITS (BITS (0, 3), 0, shift
) << ((64 - shift
)));
1498 wR
[BITS (12, 15)] = wR
[BITS (16, 19)];
1500 wC
[wCon
] |= WCON_MUP
;
1505 WAND (ARMword instr
)
1510 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1514 fprintf (stderr
, "wand\n");
1517 result
= wR
[BITS (16, 19)] & wR
[BITS (0, 3)];
1518 wR
[BITS (12, 15)] = result
;
1520 SIMD64_SET (psr
, (result
== 0), SIMD_ZBIT
);
1521 SIMD64_SET (psr
, (result
& (1ULL << 63)), SIMD_NBIT
);
1524 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
1530 WANDN (ARMword instr
)
1535 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1539 fprintf (stderr
, "wandn\n");
1542 result
= wR
[BITS (16, 19)] & ~ wR
[BITS (0, 3)];
1543 wR
[BITS (12, 15)] = result
;
1545 SIMD64_SET (psr
, (result
== 0), SIMD_ZBIT
);
1546 SIMD64_SET (psr
, (result
& (1ULL << 63)), SIMD_NBIT
);
1549 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
1555 WAVG2 (ARMword instr
)
1561 int round
= BIT (20) ? 1 : 0;
1563 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1567 fprintf (stderr
, "wavg2\n");
1570 #define AVG2x(x, y, m) (((wRBITS (BITS (16, 19), (x), (y)) & (m)) \
1571 + (wRBITS (BITS ( 0, 3), (x), (y)) & (m)) \
1576 for (i
= 0; i
< 4; i
++)
1578 s
= AVG2x ((i
* 16), (i
* 16) + 15, 0xffff) & 0xffff;
1579 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
1585 for (i
= 0; i
< 8; i
++)
1587 s
= AVG2x ((i
* 8), (i
* 8) + 7, 0xff) & 0xff;
1588 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
1593 wR
[BITS (12, 15)] = r
;
1595 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
1601 WCMPEQ (ARMul_State
* state
, ARMword instr
)
1608 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1612 fprintf (stderr
, "wcmpeq\n");
1615 switch (BITS (22, 23))
1618 for (i
= 0; i
< 8; i
++)
1620 s
= wRBYTE (BITS (16, 19), i
) == wRBYTE (BITS (0, 3), i
) ? 0xff : 0;
1622 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
1623 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
1628 for (i
= 0; i
< 4; i
++)
1630 s
= wRHALF (BITS (16, 19), i
) == wRHALF (BITS (0, 3), i
) ? 0xffff : 0;
1632 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
1633 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
1638 for (i
= 0; i
< 2; i
++)
1640 s
= wRWORD (BITS (16, 19), i
) == wRWORD (BITS (0, 3), i
) ? 0xffffffff : 0;
1642 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
1643 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
1648 ARMul_UndefInstr (state
, instr
);
1653 wR
[BITS (12, 15)] = r
;
1654 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
1660 WCMPGT (ARMul_State
* state
, ARMword instr
)
1667 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
1671 fprintf (stderr
, "wcmpgt\n");
1674 switch (BITS (22, 23))
1679 /* Use a signed comparison. */
1680 for (i
= 0; i
< 8; i
++)
1684 a
= wRBYTE (BITS (16, 19), i
);
1685 b
= wRBYTE (BITS (0, 3), i
);
1687 s
= (a
> b
) ? 0xff : 0;
1689 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
1690 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
1695 for (i
= 0; i
< 8; i
++)
1697 s
= (wRBYTE (BITS (16, 19), i
) > wRBYTE (BITS (0, 3), i
))
1700 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
1701 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
1709 for (i
= 0; i
< 4; i
++)
1713 a
= wRHALF (BITS (16, 19), i
);
1716 b
= wRHALF (BITS (0, 3), i
);
1719 s
= (a
> b
) ? 0xffff : 0;
1721 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
1722 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
1727 for (i
= 0; i
< 4; i
++)
1729 s
= (wRHALF (BITS (16, 19), i
) > wRHALF (BITS (0, 3), i
))
1732 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
1733 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
1741 for (i
= 0; i
< 2; i
++)
1745 a
= wRWORD (BITS (16, 19), i
);
1746 b
= wRWORD (BITS (0, 3), i
);
1748 s
= (a
> b
) ? 0xffffffff : 0;
1750 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
1751 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
1756 for (i
= 0; i
< 2; i
++)
1758 s
= (wRWORD (BITS (16, 19), i
) > wRWORD (BITS (0, 3), i
))
1761 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
1762 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
1768 ARMul_UndefInstr (state
, instr
);
1773 wR
[BITS (12, 15)] = r
;
1774 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
1780 Compute_Iwmmxt_Address (ARMul_State
* state
, ARMword instr
, int * pFailed
)
1789 addr
= state
->Reg
[Rn
];
1790 offset
= BITS (0, 7);
1791 multiplier
= BIT (8) ? 4 : 1;
1793 if (BIT (24)) /* P */
1795 /* Pre Indexed Addressing. */
1797 addr
+= offset
* multiplier
;
1799 addr
-= offset
* multiplier
;
1801 /* Immediate Pre-Indexed. */
1802 if (BIT (21)) /* W */
1806 /* Writeback into R15 is UNPREDICTABLE. */
1808 fprintf (stderr
, "iWMMXt: writeback into r15\n");
1813 state
->Reg
[Rn
] = addr
;
1818 /* Post Indexed Addressing. */
1819 if (BIT (21)) /* W */
1821 /* Handle the write back of the final address. */
1824 /* Writeback into R15 is UNPREDICTABLE. */
1826 fprintf (stderr
, "iWMMXt: writeback into r15\n");
1835 increment
= offset
* multiplier
;
1837 increment
= - (offset
* multiplier
);
1839 state
->Reg
[Rn
] = addr
+ increment
;
1844 /* P == 0, W == 0, U == 0 is UNPREDICTABLE. */
1848 fprintf (stderr
, "iWMMXt: undefined addressing mode\n");
1859 Iwmmxt_Load_Double_Word (ARMul_State
* state
, ARMword address
)
1863 /* The address must be aligned on a 8 byte boundary. */
1866 fprintf (stderr
, "iWMMXt: At addr 0x%x: Unaligned double word load from 0x%x\n",
1867 (state
->Reg
[15] - 8) & ~0x3, address
);
1870 /* No need to check for alignment traps. An unaligned
1871 double word load with alignment trapping disabled is
1873 ARMul_Abort (state
, ARMul_DataAbortV
);
1876 /* Load the words. */
1877 if (! state
->bigendSig
)
1879 value
= ARMul_LoadWordN (state
, address
+ 4);
1881 value
|= ARMul_LoadWordN (state
, address
);
1885 value
= ARMul_LoadWordN (state
, address
);
1887 value
|= ARMul_LoadWordN (state
, address
+ 4);
1890 /* Check for data aborts. */
1892 ARMul_Abort (state
, ARMul_DataAbortV
);
1894 ARMul_Icycles (state
, 2, 0L);
1900 Iwmmxt_Load_Word (ARMul_State
* state
, ARMword address
)
1904 /* Check for a misaligned address. */
1907 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN
))
1908 ARMul_Abort (state
, ARMul_DataAbortV
);
1913 value
= ARMul_LoadWordN (state
, address
);
1916 ARMul_Abort (state
, ARMul_DataAbortV
);
1918 ARMul_Icycles (state
, 1, 0L);
1924 Iwmmxt_Load_Half_Word (ARMul_State
* state
, ARMword address
)
1928 /* Check for a misaligned address. */
1931 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN
))
1932 ARMul_Abort (state
, ARMul_DataAbortV
);
1937 value
= ARMul_LoadHalfWord (state
, address
);
1940 ARMul_Abort (state
, ARMul_DataAbortV
);
1942 ARMul_Icycles (state
, 1, 0L);
1948 Iwmmxt_Load_Byte (ARMul_State
* state
, ARMword address
)
1952 value
= ARMul_LoadByte (state
, address
);
1955 ARMul_Abort (state
, ARMul_DataAbortV
);
1957 ARMul_Icycles (state
, 1, 0L);
1963 Iwmmxt_Store_Double_Word (ARMul_State
* state
, ARMword address
, ARMdword value
)
1965 /* The address must be aligned on a 8 byte boundary. */
1968 fprintf (stderr
, "iWMMXt: At addr 0x%x: Unaligned double word store to 0x%x\n",
1969 (state
->Reg
[15] - 8) & ~0x3, address
);
1972 /* No need to check for alignment traps. An unaligned
1973 double word store with alignment trapping disabled is
1975 ARMul_Abort (state
, ARMul_DataAbortV
);
1978 /* Store the words. */
1979 if (! state
->bigendSig
)
1981 ARMul_StoreWordN (state
, address
, value
);
1982 ARMul_StoreWordN (state
, address
+ 4, value
>> 32);
1986 ARMul_StoreWordN (state
, address
+ 4, value
);
1987 ARMul_StoreWordN (state
, address
, value
>> 32);
1990 /* Check for data aborts. */
1992 ARMul_Abort (state
, ARMul_DataAbortV
);
1994 ARMul_Icycles (state
, 2, 0L);
1998 Iwmmxt_Store_Word (ARMul_State
* state
, ARMword address
, ARMword value
)
2000 /* Check for a misaligned address. */
2003 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN
))
2004 ARMul_Abort (state
, ARMul_DataAbortV
);
2009 ARMul_StoreWordN (state
, address
, value
);
2012 ARMul_Abort (state
, ARMul_DataAbortV
);
2016 Iwmmxt_Store_Half_Word (ARMul_State
* state
, ARMword address
, ARMword value
)
2018 /* Check for a misaligned address. */
2021 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN
))
2022 ARMul_Abort (state
, ARMul_DataAbortV
);
2027 ARMul_StoreHalfWord (state
, address
, value
);
2030 ARMul_Abort (state
, ARMul_DataAbortV
);
2034 Iwmmxt_Store_Byte (ARMul_State
* state
, ARMword address
, ARMword value
)
2036 ARMul_StoreByte (state
, address
, value
);
2039 ARMul_Abort (state
, ARMul_DataAbortV
);
2043 WLDR (ARMul_State
* state
, ARMword instr
)
2048 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2052 fprintf (stderr
, "wldr\n");
2055 address
= Compute_Iwmmxt_Address (state
, instr
, & failed
);
2059 if (BITS (28, 31) == 0xf)
2062 wC
[BITS (12, 15)] = Iwmmxt_Load_Word (state
, address
);
2064 else if (BIT (8) == 0)
2068 wR
[BITS (12, 15)] = Iwmmxt_Load_Byte (state
, address
);
2071 wR
[BITS (12, 15)] = Iwmmxt_Load_Half_Word (state
, address
);
2077 wR
[BITS (12, 15)] = Iwmmxt_Load_Word (state
, address
);
2080 wR
[BITS (12, 15)] = Iwmmxt_Load_Double_Word (state
, address
);
2083 wC
[wCon
] |= WCON_MUP
;
2089 WMAC (ARMword instr
)
2095 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2099 fprintf (stderr
, "wmac\n");
2102 for (i
= 0; i
< 4; i
++)
2109 a
= wRHALF (BITS (16, 19), i
);
2112 b
= wRHALF (BITS (0, 3), i
);
2115 s
= (signed long) a
* (signed long) b
;
2117 (signed long long) t
+= s
;
2122 a
= wRHALF (BITS (16, 19), i
);
2123 b
= wRHALF (BITS ( 0, 3), i
);
2130 wR
[BITS (12, 15)] = 0;
2132 if (BIT (21)) /* Signed. */
2133 (signed long long) wR
[BITS (12, 15)] += (signed long long) t
;
2135 wR
[BITS (12, 15)] += t
;
2137 wC
[wCon
] |= WCON_MUP
;
2143 WMADD (ARMword instr
)
2148 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2152 fprintf (stderr
, "wmadd\n");
2155 for (i
= 0; i
< 2; i
++)
2159 if (BIT (21)) /* Signed. */
2163 a
= wRHALF (BITS (16, 19), i
* 2);
2166 b
= wRHALF (BITS (0, 3), i
* 2);
2169 (signed long) s1
= a
* b
;
2171 a
= wRHALF (BITS (16, 19), i
* 2 + 1);
2174 b
= wRHALF (BITS (0, 3), i
* 2 + 1);
2177 (signed long) s2
= a
* b
;
2179 else /* Unsigned. */
2183 a
= wRHALF (BITS (16, 19), i
* 2);
2184 b
= wRHALF (BITS ( 0, 3), i
* 2);
2186 (unsigned long) s1
= a
* b
;
2188 a
= wRHALF (BITS (16, 19), i
* 2 + 1);
2189 b
= wRHALF (BITS ( 0, 3), i
* 2 + 1);
2191 (signed long) s2
= a
* b
;
2194 r
|= (ARMdword
) ((s1
+ s2
) & 0xffffffff) << (i
? 32 : 0);
2197 wR
[BITS (12, 15)] = r
;
2198 wC
[wCon
] |= WCON_MUP
;
2204 WMAX (ARMul_State
* state
, ARMword instr
)
2210 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2214 fprintf (stderr
, "wmax\n");
2217 switch (BITS (22, 23))
2220 for (i
= 0; i
< 8; i
++)
2221 if (BIT (21)) /* Signed. */
2225 a
= wRBYTE (BITS (16, 19), i
);
2228 b
= wRBYTE (BITS (0, 3), i
);
2236 r
|= (s
& 0xff) << (i
* 8);
2238 else /* Unsigned. */
2242 a
= wRBYTE (BITS (16, 19), i
);
2243 b
= wRBYTE (BITS (0, 3), i
);
2250 r
|= (s
& 0xff) << (i
* 8);
2255 for (i
= 0; i
< 4; i
++)
2256 if (BIT (21)) /* Signed. */
2260 a
= wRHALF (BITS (16, 19), i
);
2263 b
= wRHALF (BITS (0, 3), i
);
2271 r
|= (s
& 0xffff) << (i
* 16);
2273 else /* Unsigned. */
2277 a
= wRHALF (BITS (16, 19), i
);
2278 b
= wRHALF (BITS (0, 3), i
);
2285 r
|= (s
& 0xffff) << (i
* 16);
2290 for (i
= 0; i
< 2; i
++)
2291 if (BIT (21)) /* Signed. */
2295 a
= wRWORD (BITS (16, 19), i
);
2296 b
= wRWORD (BITS (0, 3), i
);
2303 r
|= (s
& 0xffffffff) << (i
* 32);
2309 a
= wRWORD (BITS (16, 19), i
);
2310 b
= wRWORD (BITS (0, 3), i
);
2317 r
|= (s
& 0xffffffff) << (i
* 32);
2322 ARMul_UndefInstr (state
, instr
);
2326 wR
[BITS (12, 15)] = r
;
2327 wC
[wCon
] |= WCON_MUP
;
2333 WMIN (ARMul_State
* state
, ARMword instr
)
2339 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2343 fprintf (stderr
, "wmin\n");
2346 switch (BITS (22, 23))
2349 for (i
= 0; i
< 8; i
++)
2350 if (BIT (21)) /* Signed. */
2354 a
= wRBYTE (BITS (16, 19), i
);
2357 b
= wRBYTE (BITS (0, 3), i
);
2365 r
|= (s
& 0xff) << (i
* 8);
2367 else /* Unsigned. */
2371 a
= wRBYTE (BITS (16, 19), i
);
2372 b
= wRBYTE (BITS (0, 3), i
);
2379 r
|= (s
& 0xff) << (i
* 8);
2384 for (i
= 0; i
< 4; i
++)
2385 if (BIT (21)) /* Signed. */
2389 a
= wRHALF (BITS (16, 19), i
);
2392 b
= wRHALF (BITS (0, 3), i
);
2400 r
|= (s
& 0xffff) << (i
* 16);
2407 a
= wRHALF (BITS (16, 19), i
);
2408 b
= wRHALF (BITS ( 0, 3), i
);
2415 r
|= (s
& 0xffff) << (i
* 16);
2420 for (i
= 0; i
< 2; i
++)
2421 if (BIT (21)) /* Signed. */
2425 a
= wRWORD (BITS (16, 19), i
);
2426 b
= wRWORD (BITS ( 0, 3), i
);
2433 r
|= (s
& 0xffffffff) << (i
* 32);
2439 a
= wRWORD (BITS (16, 19), i
);
2440 b
= wRWORD (BITS (0, 3), i
);
2447 r
|= (s
& 0xffffffff) << (i
* 32);
2452 ARMul_UndefInstr (state
, instr
);
2456 wR
[BITS (12, 15)] = r
;
2457 wC
[wCon
] |= WCON_MUP
;
2463 WMUL (ARMword instr
)
2469 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2473 fprintf (stderr
, "wmul\n");
2476 for (i
= 0; i
< 4; i
++)
2477 if (BIT (21)) /* Signed. */
2481 a
= wRHALF (BITS (16, 19), i
);
2484 b
= wRHALF (BITS (0, 3), i
);
2490 r
|= ((s
>> 16) & 0xffff) << (i
* 16);
2492 r
|= (s
& 0xffff) << (i
* 16);
2494 else /* Unsigned. */
2498 a
= wRHALF (BITS (16, 19), i
);
2499 b
= wRHALF (BITS (0, 3), i
);
2504 r
|= ((s
>> 16) & 0xffff) << (i
* 16);
2506 r
|= (s
& 0xffff) << (i
* 16);
2509 wR
[BITS (12, 15)] = r
;
2510 wC
[wCon
] |= WCON_MUP
;
2521 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2525 fprintf (stderr
, "wor\n");
2528 result
= wR
[BITS (16, 19)] | wR
[BITS (0, 3)];
2529 wR
[BITS (12, 15)] = result
;
2531 SIMD64_SET (psr
, (result
== 0), SIMD_ZBIT
);
2532 SIMD64_SET (psr
, (result
& (1ULL << 63)), SIMD_NBIT
);
2535 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2541 WPACK (ARMul_State
* state
, ARMword instr
)
2550 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2554 fprintf (stderr
, "wpack\n");
2557 switch (BITS (22, 23))
2560 for (i
= 0; i
< 8; i
++)
2562 x
= wRHALF (i
< 4 ? BITS (16, 19) : BITS (0, 3), i
& 3);
2564 switch (BITS (20, 21))
2566 case UnsignedSaturation
:
2567 s
= IwmmxtSaturateU8 (x
, satrv
+ BITIDX8 (i
));
2570 case SignedSaturation
:
2571 s
= IwmmxtSaturateS8 (x
, satrv
+ BITIDX8 (i
));
2575 ARMul_UndefInstr (state
, instr
);
2579 r
|= (s
& 0xff) << (i
* 8);
2580 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
2581 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
2586 satrv
[0] = satrv
[2] = satrv
[4] = satrv
[6] = 0;
2588 for (i
= 0; i
< 4; i
++)
2590 x
= wRWORD (i
< 2 ? BITS (16, 19) : BITS (0, 3), i
& 1);
2592 switch (BITS (20, 21))
2594 case UnsignedSaturation
:
2595 s
= IwmmxtSaturateU16 (x
, satrv
+ BITIDX16 (i
));
2598 case SignedSaturation
:
2599 s
= IwmmxtSaturateS16 (x
, satrv
+ BITIDX16 (i
));
2603 ARMul_UndefInstr (state
, instr
);
2607 r
|= (s
& 0xffff) << (i
* 16);
2608 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2609 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2614 satrv
[0] = satrv
[1] = satrv
[2] = satrv
[4] = satrv
[5] = satrv
[6] = 0;
2616 for (i
= 0; i
< 2; i
++)
2618 x
= wR
[i
? BITS (0, 3) : BITS (16, 19)];
2620 switch (BITS (20, 21))
2622 case UnsignedSaturation
:
2623 s
= IwmmxtSaturateU32 (x
, satrv
+ BITIDX32 (i
));
2626 case SignedSaturation
:
2627 s
= IwmmxtSaturateS32 (x
, satrv
+ BITIDX32 (i
));
2631 ARMul_UndefInstr (state
, instr
);
2635 r
|= (s
& 0xffffffff) << (i
* 32);
2636 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
2637 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
2642 ARMul_UndefInstr (state
, instr
);
2647 wR
[BITS (12, 15)] = r
;
2648 SET_wCSSFvec (satrv
);
2649 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2655 WROR (ARMul_State
* state
, ARMword instr
)
2663 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2667 fprintf (stderr
, "wror\n");
2670 DECODE_G_BIT (state
, instr
, shift
);
2672 switch (BITS (22, 23))
2676 for (i
= 0; i
< 4; i
++)
2678 s
= ((wRHALF (BITS (16, 19), i
) & 0xffff) << (16 - shift
))
2679 | ((wRHALF (BITS (16, 19), i
) & 0xffff) >> shift
);
2680 r
|= (s
& 0xffff) << (i
* 16);
2681 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2682 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2688 for (i
= 0; i
< 2; i
++)
2690 s
= ((wRWORD (BITS (16, 19), i
) & 0xffffffff) << (32 - shift
))
2691 | ((wRWORD (BITS (16, 19), i
) & 0xffffffff) >> shift
);
2692 r
|= (s
& 0xffffffff) << (i
* 32);
2693 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
2694 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
2700 r
= (wR
[BITS (16, 19)] >> shift
)
2701 | (wR
[BITS (16, 19)] << (64 - shift
));
2703 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
2704 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
2708 ARMul_UndefInstr (state
, instr
);
2713 wR
[BITS (12, 15)] = r
;
2714 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2720 WSAD (ARMword instr
)
2726 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2730 fprintf (stderr
, "wsad\n");
2734 r
= BIT (20) ? 0 : (wR
[BITS (12, 15)] & 0xffffffff);
2738 for (i
= 0; i
< 4; i
++)
2740 s
= (wRHALF (BITS (16, 19), i
) - wRHALF (BITS (0, 3), i
));
2745 for (i
= 0; i
< 8; i
++)
2747 s
= (wRBYTE (BITS (16, 19), i
) - wRBYTE (BITS (0, 3), i
));
2751 wR
[BITS (12, 15)] = r
;
2752 wC
[wCon
] |= WCON_MUP
;
2758 WSHUFH (ARMword instr
)
2766 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2770 fprintf (stderr
, "wshufh\n");
2773 imm8
= (BITS (20, 23) << 4) | BITS (0, 3);
2775 for (i
= 0; i
< 4; i
++)
2777 s
= wRHALF (BITS (16, 19), ((imm8
>> (i
* 2) & 3)) & 0xff);
2778 r
|= (s
& 0xffff) << (i
* 16);
2779 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2780 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2784 wR
[BITS (12, 15)] = r
;
2785 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2791 WSLL (ARMul_State
* state
, ARMword instr
)
2799 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2803 fprintf (stderr
, "wsll\n");
2806 DECODE_G_BIT (state
, instr
, shift
);
2808 switch (BITS (22, 23))
2811 for (i
= 0; i
< 4; i
++)
2816 s
= ((wRHALF (BITS (16, 19), i
) & 0xffff) << shift
);
2817 r
|= (s
& 0xffff) << (i
* 16);
2818 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2819 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2824 for (i
= 0; i
< 2; i
++)
2829 s
= ((wRWORD (BITS (16, 19), i
) & 0xffffffff) << shift
);
2830 r
|= (s
& 0xffffffff) << (i
* 32);
2831 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
2832 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
2840 r
= ((wR
[BITS (16, 19)] & 0xffffffffffffffff) << shift
);
2842 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
2843 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
2847 ARMul_UndefInstr (state
, instr
);
2852 wR
[BITS (12, 15)] = r
;
2853 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2859 WSRA (ARMul_State
* state
, ARMword instr
)
2868 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2872 fprintf (stderr
, "wsra\n");
2875 DECODE_G_BIT (state
, instr
, shift
);
2877 switch (BITS (22, 23))
2880 for (i
= 0; i
< 4; i
++)
2883 t
= (wRHALF (BITS (16, 19), i
) & 0x8000) ? 0xffff : 0;
2886 t
= wRHALF (BITS (16, 19), i
);
2892 r
|= (s
& 0xffff) << (i
* 16);
2893 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2894 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2899 for (i
= 0; i
< 2; i
++)
2902 t
= (wRWORD (BITS (16, 19), i
) & 0x80000000) ? 0xffffffff : 0;
2905 t
= wRWORD (BITS (16, 19), i
);
2909 r
|= (s
& 0xffffffff) << (i
* 32);
2910 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
2911 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
2917 r
= (wR
[BITS (16, 19)] & 0x8000000000000000) ? 0xffffffffffffffff : 0;
2919 r
= ((signed long long) (wR
[BITS (16, 19)] & 0xffffffffffffffff) >> shift
);
2920 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
2921 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
2925 ARMul_UndefInstr (state
, instr
);
2930 wR
[BITS (12, 15)] = r
;
2931 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
2937 WSRL (ARMul_State
* state
, ARMword instr
)
2945 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2949 fprintf (stderr
, "wsrl\n");
2952 DECODE_G_BIT (state
, instr
, shift
);
2954 switch (BITS (22, 23))
2957 for (i
= 0; i
< 4; i
++)
2962 s
= ((unsigned) (wRHALF (BITS (16, 19), i
) & 0xffff) >> shift
);
2964 r
|= (s
& 0xffff) << (i
* 16);
2965 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
2966 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
2971 for (i
= 0; i
< 2; i
++)
2976 s
= ((unsigned long) (wRWORD (BITS (16, 19), i
) & 0xffffffff) >> shift
);
2978 r
|= (s
& 0xffffffff) << (i
* 32);
2979 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
2980 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
2988 r
= (wR
[BITS (16, 19)] & 0xffffffffffffffff) >> shift
;
2990 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
2991 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
2995 ARMul_UndefInstr (state
, instr
);
3000 wR
[BITS (12, 15)] = r
;
3001 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3007 WSTR (ARMul_State
* state
, ARMword instr
)
3013 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3017 fprintf (stderr
, "wstr\n");
3020 address
= Compute_Iwmmxt_Address (state
, instr
, & failed
);
3024 if (BITS (28, 31) == 0xf)
3027 Iwmmxt_Store_Word (state
, address
, wC
[BITS (12, 15)]);
3029 else if (BIT (8) == 0)
3033 Iwmmxt_Store_Byte (state
, address
, wR
[BITS (12, 15)]);
3036 Iwmmxt_Store_Half_Word (state
, address
, wR
[BITS (12, 15)]);
3042 Iwmmxt_Store_Word (state
, address
, wR
[BITS (12, 15)]);
3045 Iwmmxt_Store_Double_Word (state
, address
, wR
[BITS (12, 15)]);
3052 WSUB (ARMul_State
* state
, ARMword instr
)
3063 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3067 fprintf (stderr
, "wsub\n");
3070 /* Subtract two numbers using the specified function,
3071 leaving setting the carry bit as required. */
3072 #define SUBx(x, y, m, f) \
3073 (*f) (wRBITS (BITS (16, 19), (x), (y)) & (m), \
3074 wRBITS (BITS ( 0, 3), (x), (y)) & (m), & carry, & overflow)
3076 switch (BITS (22, 23))
3079 for (i
= 0; i
< 8; i
++)
3081 switch (BITS (20, 21))
3084 s
= SUBx ((i
* 8), (i
* 8) + 7, 0xff, SubS8
);
3085 satrv
[BITIDX8 (i
)] = 0;
3086 r
|= (s
& 0xff) << (i
* 8);
3087 SIMD8_SET (psr
, NBIT8 (s
), SIMD_NBIT
, i
);
3088 SIMD8_SET (psr
, ZBIT8 (s
), SIMD_ZBIT
, i
);
3089 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
3090 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
3093 case UnsignedSaturation
:
3094 s
= SUBx ((i
* 8), (i
* 8) + 7, 0xff, SubU8
);
3095 x
= IwmmxtSaturateU8 (s
, satrv
+ BITIDX8 (i
));
3096 r
|= (x
& 0xff) << (i
* 8);
3097 SIMD8_SET (psr
, NBIT8 (x
), SIMD_NBIT
, i
);
3098 SIMD8_SET (psr
, ZBIT8 (x
), SIMD_ZBIT
, i
);
3099 if (! satrv
[BITIDX8 (i
)])
3101 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
3102 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
3106 case SignedSaturation
:
3107 s
= SUBx ((i
* 8), (i
* 8) + 7, 0xff, SubS8
);
3108 x
= IwmmxtSaturateS8 (s
, satrv
+ BITIDX8 (i
));
3109 r
|= (x
& 0xff) << (i
* 8);
3110 SIMD8_SET (psr
, NBIT8 (x
), SIMD_NBIT
, i
);
3111 SIMD8_SET (psr
, ZBIT8 (x
), SIMD_ZBIT
, i
);
3112 if (! satrv
[BITIDX8 (i
)])
3114 SIMD8_SET (psr
, carry
, SIMD_CBIT
, i
);
3115 SIMD8_SET (psr
, overflow
, SIMD_VBIT
, i
);
3120 ARMul_UndefInstr (state
, instr
);
3127 satrv
[0] = satrv
[2] = satrv
[4] = satrv
[6] = 0;
3129 for (i
= 0; i
< 4; i
++)
3131 switch (BITS (20, 21))
3134 s
= SUBx ((i
* 16), (i
* 16) + 15, 0xffff, SubU16
);
3135 satrv
[BITIDX16 (i
)] = 0;
3136 r
|= (s
& 0xffff) << (i
* 16);
3137 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
3138 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
3139 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
3140 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
3143 case UnsignedSaturation
:
3144 s
= SUBx ((i
* 16), (i
* 16) + 15, 0xffff, SubU16
);
3145 x
= IwmmxtSaturateU16 (s
, satrv
+ BITIDX16 (i
));
3146 r
|= (x
& 0xffff) << (i
* 16);
3147 SIMD16_SET (psr
, NBIT16 (x
& 0xffff), SIMD_NBIT
, i
);
3148 SIMD16_SET (psr
, ZBIT16 (x
), SIMD_ZBIT
, i
);
3149 if (! satrv
[BITIDX16 (i
)])
3151 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
3152 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
3156 case SignedSaturation
:
3157 s
= SUBx ((i
* 16), (i
* 16) + 15, 0xffff, SubS16
);
3158 x
= IwmmxtSaturateS16 (s
, satrv
+ BITIDX16 (i
));
3159 r
|= (x
& 0xffff) << (i
* 16);
3160 SIMD16_SET (psr
, NBIT16 (x
), SIMD_NBIT
, i
);
3161 SIMD16_SET (psr
, ZBIT16 (x
), SIMD_ZBIT
, i
);
3162 if (! satrv
[BITIDX16 (i
)])
3164 SIMD16_SET (psr
, carry
, SIMD_CBIT
, i
);
3165 SIMD16_SET (psr
, overflow
, SIMD_VBIT
, i
);
3170 ARMul_UndefInstr (state
, instr
);
3177 satrv
[0] = satrv
[1] = satrv
[2] = satrv
[4] = satrv
[5] = satrv
[6] = 0;
3179 for (i
= 0; i
< 2; i
++)
3181 switch (BITS (20, 21))
3184 s
= SUBx ((i
* 32), (i
* 32) + 31, 0xffffffff, SubU32
);
3185 satrv
[BITIDX32 (i
)] = 0;
3186 r
|= (s
& 0xffffffff) << (i
* 32);
3187 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
3188 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
3189 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
3190 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
3193 case UnsignedSaturation
:
3194 s
= SUBx ((i
* 32), (i
* 32) + 31, 0xffffffff, SubU32
);
3195 x
= IwmmxtSaturateU32 (s
, satrv
+ BITIDX32 (i
));
3196 r
|= (x
& 0xffffffff) << (i
* 32);
3197 SIMD32_SET (psr
, NBIT32 (x
), SIMD_NBIT
, i
);
3198 SIMD32_SET (psr
, ZBIT32 (x
), SIMD_ZBIT
, i
);
3199 if (! satrv
[BITIDX32 (i
)])
3201 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
3202 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
3206 case SignedSaturation
:
3207 s
= SUBx ((i
* 32), (i
* 32) + 31, 0xffffffff, SubS32
);
3208 x
= IwmmxtSaturateS32 (s
, satrv
+ BITIDX32 (i
));
3209 r
|= (x
& 0xffffffff) << (i
* 32);
3210 SIMD32_SET (psr
, NBIT32 (x
), SIMD_NBIT
, i
);
3211 SIMD32_SET (psr
, ZBIT32 (x
), SIMD_ZBIT
, i
);
3212 if (! satrv
[BITIDX32 (i
)])
3214 SIMD32_SET (psr
, carry
, SIMD_CBIT
, i
);
3215 SIMD32_SET (psr
, overflow
, SIMD_VBIT
, i
);
3220 ARMul_UndefInstr (state
, instr
);
3227 ARMul_UndefInstr (state
, instr
);
3231 wR
[BITS (12, 15)] = r
;
3233 SET_wCSSFvec (satrv
);
3234 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3242 WUNPCKEH (ARMul_State
* state
, ARMword instr
)
3249 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3253 fprintf (stderr
, "wunpckeh\n");
3256 switch (BITS (22, 23))
3259 for (i
= 0; i
< 4; i
++)
3261 s
= wRBYTE (BITS (16, 19), i
+ 4);
3263 if (BIT (21) && NBIT8 (s
))
3266 r
|= (s
& 0xffff) << (i
* 16);
3267 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
3268 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
3273 for (i
= 0; i
< 2; i
++)
3275 s
= wRHALF (BITS (16, 19), i
+ 2);
3277 if (BIT (21) && NBIT16 (s
))
3280 r
|= (s
& 0xffffffff) << (i
* 32);
3281 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
3282 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
3287 r
= wRWORD (BITS (16, 19), 1);
3289 if (BIT (21) && NBIT32 (r
))
3290 r
|= 0xffffffff00000000;
3292 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
3293 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
3297 ARMul_UndefInstr (state
, instr
);
3302 wR
[BITS (12, 15)] = r
;
3303 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3309 WUNPCKEL (ARMul_State
* state
, ARMword instr
)
3316 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3320 fprintf (stderr
, "wunpckel\n");
3323 switch (BITS (22, 23))
3326 for (i
= 0; i
< 4; i
++)
3328 s
= wRBYTE (BITS (16, 19), i
);
3330 if (BIT (21) && NBIT8 (s
))
3333 r
|= (s
& 0xffff) << (i
* 16);
3334 SIMD16_SET (psr
, NBIT16 (s
), SIMD_NBIT
, i
);
3335 SIMD16_SET (psr
, ZBIT16 (s
), SIMD_ZBIT
, i
);
3340 for (i
= 0; i
< 2; i
++)
3342 s
= wRHALF (BITS (16, 19), i
);
3344 if (BIT (21) && NBIT16 (s
))
3347 r
|= (s
& 0xffffffff) << (i
* 32);
3348 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, i
);
3349 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, i
);
3354 r
= wRWORD (BITS (16, 19), 0);
3356 if (BIT (21) && NBIT32 (r
))
3357 r
|= 0xffffffff00000000;
3359 SIMD64_SET (psr
, NBIT64 (r
), SIMD_NBIT
);
3360 SIMD64_SET (psr
, ZBIT64 (r
), SIMD_ZBIT
);
3364 ARMul_UndefInstr (state
, instr
);
3369 wR
[BITS (12, 15)] = r
;
3370 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3376 WUNPCKIH (ARMul_State
* state
, ARMword instr
)
3384 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3388 fprintf (stderr
, "wunpckih\n");
3391 switch (BITS (22, 23))
3394 for (i
= 0; i
< 4; i
++)
3396 a
= wRBYTE (BITS (16, 19), i
+ 4);
3397 b
= wRBYTE (BITS ( 0, 3), i
+ 4);
3399 r
|= (s
& 0xffff) << (i
* 16);
3400 SIMD8_SET (psr
, NBIT8 (a
), SIMD_NBIT
, i
* 2);
3401 SIMD8_SET (psr
, ZBIT8 (a
), SIMD_ZBIT
, i
* 2);
3402 SIMD8_SET (psr
, NBIT8 (b
), SIMD_NBIT
, (i
* 2) + 1);
3403 SIMD8_SET (psr
, ZBIT8 (b
), SIMD_ZBIT
, (i
* 2) + 1);
3408 for (i
= 0; i
< 2; i
++)
3410 a
= wRHALF (BITS (16, 19), i
+ 2);
3411 b
= wRHALF (BITS ( 0, 3), i
+ 2);
3413 r
|= (s
& 0xffffffff) << (i
* 32);
3414 SIMD16_SET (psr
, NBIT16 (a
), SIMD_NBIT
, (i
* 2));
3415 SIMD16_SET (psr
, ZBIT16 (a
), SIMD_ZBIT
, (i
* 2));
3416 SIMD16_SET (psr
, NBIT16 (b
), SIMD_NBIT
, (i
* 2) + 1);
3417 SIMD16_SET (psr
, ZBIT16 (b
), SIMD_ZBIT
, (i
* 2) + 1);
3422 a
= wRWORD (BITS (16, 19), 1);
3423 s
= wRWORD (BITS ( 0, 3), 1);
3426 SIMD32_SET (psr
, NBIT32 (a
), SIMD_NBIT
, 0);
3427 SIMD32_SET (psr
, ZBIT32 (a
), SIMD_ZBIT
, 0);
3428 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, 1);
3429 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, 1);
3433 ARMul_UndefInstr (state
, instr
);
3438 wR
[BITS (12, 15)] = r
;
3439 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3445 WUNPCKIL (ARMul_State
* state
, ARMword instr
)
3453 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3457 fprintf (stderr
, "wunpckil\n");
3460 switch (BITS (22, 23))
3463 for (i
= 0; i
< 4; i
++)
3465 a
= wRBYTE (BITS (16, 19), i
);
3466 b
= wRBYTE (BITS ( 0, 3), i
);
3468 r
|= (s
& 0xffff) << (i
* 16);
3469 SIMD8_SET (psr
, NBIT8 (a
), SIMD_NBIT
, i
* 2);
3470 SIMD8_SET (psr
, ZBIT8 (a
), SIMD_ZBIT
, i
* 2);
3471 SIMD8_SET (psr
, NBIT8 (b
), SIMD_NBIT
, (i
* 2) + 1);
3472 SIMD8_SET (psr
, ZBIT8 (b
), SIMD_ZBIT
, (i
* 2) + 1);
3477 for (i
= 0; i
< 2; i
++)
3479 a
= wRHALF (BITS (16, 19), i
);
3480 b
= wRHALF (BITS ( 0, 3), i
);
3482 r
|= (s
& 0xffffffff) << (i
* 32);
3483 SIMD16_SET (psr
, NBIT16 (a
), SIMD_NBIT
, (i
* 2));
3484 SIMD16_SET (psr
, ZBIT16 (a
), SIMD_ZBIT
, (i
* 2));
3485 SIMD16_SET (psr
, NBIT16 (b
), SIMD_NBIT
, (i
* 2) + 1);
3486 SIMD16_SET (psr
, ZBIT16 (b
), SIMD_ZBIT
, (i
* 2) + 1);
3491 a
= wRWORD (BITS (16, 19), 0);
3492 s
= wRWORD (BITS ( 0, 3), 0);
3495 SIMD32_SET (psr
, NBIT32 (a
), SIMD_NBIT
, 0);
3496 SIMD32_SET (psr
, ZBIT32 (a
), SIMD_ZBIT
, 0);
3497 SIMD32_SET (psr
, NBIT32 (s
), SIMD_NBIT
, 1);
3498 SIMD32_SET (psr
, ZBIT32 (s
), SIMD_ZBIT
, 1);
3502 ARMul_UndefInstr (state
, instr
);
3507 wR
[BITS (12, 15)] = r
;
3508 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3514 WXOR (ARMword instr
)
3519 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3523 fprintf (stderr
, "wxor\n");
3526 result
= wR
[BITS (16, 19)] ^ wR
[BITS (0, 3)];
3527 wR
[BITS (12, 15)] = result
;
3529 SIMD64_SET (psr
, (result
== 0), SIMD_ZBIT
);
3530 SIMD64_SET (psr
, (result
& (1ULL << 63)), SIMD_NBIT
);
3533 wC
[wCon
] |= (WCON_CUP
| WCON_MUP
);
3538 /* This switch table is moved to a seperate function in order
3539 to work around a compiler bug in the host compiler... */
3542 Process_Instruction (ARMul_State
* state
, ARMword instr
)
3544 int status
= ARMul_BUSY
;
3546 switch ((BITS (20, 23) << 8) | BITS (4, 11))
3548 case 0x000: status
= WOR (instr
); break;
3549 case 0x011: status
= TMCR (state
, instr
); break;
3550 case 0x100: status
= WXOR (instr
); break;
3551 case 0x111: status
= TMRC (state
, instr
); break;
3552 case 0x300: status
= WANDN (instr
); break;
3553 case 0x200: status
= WAND (instr
); break;
3555 case 0x810: case 0xa10:
3556 status
= WMADD (instr
); break;
3558 case 0x10e: case 0x50e: case 0x90e: case 0xd0e:
3559 status
= WUNPCKIL (state
, instr
); break;
3560 case 0x10c: case 0x50c: case 0x90c: case 0xd0c:
3561 status
= WUNPCKIH (state
, instr
); break;
3562 case 0x012: case 0x112: case 0x412: case 0x512:
3563 status
= WSAD (instr
); break;
3564 case 0x010: case 0x110: case 0x210: case 0x310:
3565 status
= WMUL (instr
); break;
3566 case 0x410: case 0x510: case 0x610: case 0x710:
3567 status
= WMAC (instr
); break;
3568 case 0x006: case 0x406: case 0x806: case 0xc06:
3569 status
= WCMPEQ (state
, instr
); break;
3570 case 0x800: case 0x900: case 0xc00: case 0xd00:
3571 status
= WAVG2 (instr
); break;
3572 case 0x802: case 0x902: case 0xa02: case 0xb02:
3573 status
= WALIGNR (state
, instr
); break;
3574 case 0x601: case 0x605: case 0x609: case 0x60d:
3575 status
= TINSR (state
, instr
); break;
3576 case 0x107: case 0x507: case 0x907: case 0xd07:
3577 status
= TEXTRM (state
, instr
); break;
3578 case 0x117: case 0x517: case 0x917: case 0xd17:
3579 status
= TEXTRC (state
, instr
); break;
3580 case 0x401: case 0x405: case 0x409: case 0x40d:
3581 status
= TBCST (state
, instr
); break;
3582 case 0x113: case 0x513: case 0x913: case 0xd13:
3583 status
= TANDC (state
, instr
); break;
3584 case 0x01c: case 0x41c: case 0x81c: case 0xc1c:
3585 status
= WACC (state
, instr
); break;
3586 case 0x115: case 0x515: case 0x915: case 0xd15:
3587 status
= TORC (state
, instr
); break;
3588 case 0x103: case 0x503: case 0x903: case 0xd03:
3589 status
= TMOVMSK (state
, instr
); break;
3590 case 0x106: case 0x306: case 0x506: case 0x706:
3591 case 0x906: case 0xb06: case 0xd06: case 0xf06:
3592 status
= WCMPGT (state
, instr
); break;
3593 case 0x00e: case 0x20e: case 0x40e: case 0x60e:
3594 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
3595 status
= WUNPCKEL (state
, instr
); break;
3596 case 0x00c: case 0x20c: case 0x40c: case 0x60c:
3597 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
3598 status
= WUNPCKEH (state
, instr
); break;
3599 case 0x204: case 0x604: case 0xa04: case 0xe04:
3600 case 0x214: case 0x614: case 0xa14: case 0xe14:
3601 status
= WSRL (state
, instr
); break;
3602 case 0x004: case 0x404: case 0x804: case 0xc04:
3603 case 0x014: case 0x414: case 0x814: case 0xc14:
3604 status
= WSRA (state
, instr
); break;
3605 case 0x104: case 0x504: case 0x904: case 0xd04:
3606 case 0x114: case 0x514: case 0x914: case 0xd14:
3607 status
= WSLL (state
, instr
); break;
3608 case 0x304: case 0x704: case 0xb04: case 0xf04:
3609 case 0x314: case 0x714: case 0xb14: case 0xf14:
3610 status
= WROR (state
, instr
); break;
3611 case 0x116: case 0x316: case 0x516: case 0x716:
3612 case 0x916: case 0xb16: case 0xd16: case 0xf16:
3613 status
= WMIN (state
, instr
); break;
3614 case 0x016: case 0x216: case 0x416: case 0x616:
3615 case 0x816: case 0xa16: case 0xc16: case 0xe16:
3616 status
= WMAX (state
, instr
); break;
3617 case 0x002: case 0x102: case 0x202: case 0x302:
3618 case 0x402: case 0x502: case 0x602: case 0x702:
3619 status
= WALIGNI (instr
); break;
3620 case 0x01a: case 0x11a: case 0x21a: case 0x31a:
3621 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
3622 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
3623 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
3624 status
= WSUB (state
, instr
); break;
3625 case 0x01e: case 0x11e: case 0x21e: case 0x31e:
3626 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
3627 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
3628 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
3629 status
= WSHUFH (instr
); break;
3630 case 0x018: case 0x118: case 0x218: case 0x318:
3631 case 0x418: case 0x518: case 0x618: case 0x718:
3632 case 0x818: case 0x918: case 0xa18: case 0xb18:
3633 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
3634 status
= WADD (state
, instr
); break;
3635 case 0x008: case 0x108: case 0x208: case 0x308:
3636 case 0x408: case 0x508: case 0x608: case 0x708:
3637 case 0x808: case 0x908: case 0xa08: case 0xb08:
3638 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
3639 status
= WPACK (state
, instr
); break;
3640 case 0x201: case 0x203: case 0x205: case 0x207:
3641 case 0x209: case 0x20b: case 0x20d: case 0x20f:
3642 case 0x211: case 0x213: case 0x215: case 0x217:
3643 case 0x219: case 0x21b: case 0x21d: case 0x21f:
3644 switch (BITS (16, 19))
3646 case 0x0: status
= TMIA (state
, instr
); break;
3647 case 0x8: status
= TMIAPH (state
, instr
); break;
3651 case 0xf: status
= TMIAxy (state
, instr
); break;
3661 /* Process a possibly Intel(r) Wireless MMX(tm) technology instruction.
3662 Return true if the instruction was handled. */
3665 ARMul_HandleIwmmxt (ARMul_State
* state
, ARMword instr
)
3667 int status
= ARMul_BUSY
;
3669 if (BITS (24, 27) == 0xe)
3671 status
= Process_Instruction (state
, instr
);
3673 else if (BITS (25, 27) == 0x6)
3675 if (BITS (4, 11) == 0x0 && BITS (20, 24) == 0x4)
3676 status
= TMCRR (state
, instr
);
3677 else if (BITS (9, 11) == 0x0)
3679 if (BIT (20) == 0x0)
3680 status
= WSTR (state
, instr
);
3681 else if (BITS (20, 24) == 0x5)
3682 status
= TMRRC (state
, instr
);
3684 status
= WLDR (state
, instr
);
3688 if (status
== ARMul_CANT
)
3690 /* If the instruction was a recognised but illegal,
3691 perform the abort here rather than returning false.
3692 If we return false then ARMul_MRC may be called which
3693 will still abort, but which also perform the register
3695 ARMul_Abort (state
, ARMul_UndefinedInstrV
);
3696 status
= ARMul_DONE
;
3699 return status
== ARMul_DONE
;
3703 Fetch_Iwmmxt_Register (unsigned int regnum
, unsigned char * memory
)
3707 memcpy (memory
, wC
+ (regnum
- 16), sizeof wC
[0]);
3708 return sizeof wC
[0];
3712 memcpy (memory
, wR
+ regnum
, sizeof wR
[0]);
3713 return sizeof wR
[0];
3718 Store_Iwmmxt_Register (unsigned int regnum
, unsigned char * memory
)
3722 memcpy (wC
+ (regnum
- 16), memory
, sizeof wC
[0]);
3723 return sizeof wC
[0];
3727 memcpy (wR
+ regnum
, memory
, sizeof wR
[0]);
3728 return sizeof wR
[0];
This page took 0.115315 seconds and 4 git commands to generate.