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 = wRWORD (BITS (16, 19), i);
1748 b = wRWORD (BITS (0, 3), i);
1750 s = (a > b) ? 0xffffffff : 0;
1752 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
1753 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
1758 for (i = 0; i < 2; i++)
1760 s = (wRWORD (BITS (16, 19), i) > wRWORD (BITS (0, 3), i))
1763 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
1764 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
1770 ARMul_UndefInstr (state, instr);
1775 wR [BITS (12, 15)] = r;
1776 wC [wCon] |= (WCON_CUP | WCON_MUP);
1782 Compute_Iwmmxt_Address (ARMul_State * state, ARMword instr, int * pFailed)
1791 addr = state->Reg [Rn];
1792 offset = BITS (0, 7);
1793 multiplier = BIT (8) ? 4 : 1;
1795 if (BIT (24)) /* P */
1797 /* Pre Indexed Addressing. */
1799 addr += offset * multiplier;
1801 addr -= offset * multiplier;
1803 /* Immediate Pre-Indexed. */
1804 if (BIT (21)) /* W */
1808 /* Writeback into R15 is UNPREDICTABLE. */
1810 fprintf (stderr, "iWMMXt: writeback into r15\n");
1815 state->Reg [Rn] = addr;
1820 /* Post Indexed Addressing. */
1821 if (BIT (21)) /* W */
1823 /* Handle the write back of the final address. */
1826 /* Writeback into R15 is UNPREDICTABLE. */
1828 fprintf (stderr, "iWMMXt: writeback into r15\n");
1837 increment = offset * multiplier;
1839 increment = - (offset * multiplier);
1841 state->Reg [Rn] = addr + increment;
1846 /* P == 0, W == 0, U == 0 is UNPREDICTABLE. */
1850 fprintf (stderr, "iWMMXt: undefined addressing mode\n");
1861 Iwmmxt_Load_Double_Word (ARMul_State * state, ARMword address)
1865 /* The address must be aligned on a 8 byte boundary. */
1868 fprintf (stderr, "iWMMXt: At addr 0x%x: Unaligned double word load from 0x%x\n",
1869 (state->Reg[15] - 8) & ~0x3, address);
1872 /* No need to check for alignment traps. An unaligned
1873 double word load with alignment trapping disabled is
1875 ARMul_Abort (state, ARMul_DataAbortV);
1878 /* Load the words. */
1879 if (! state->bigendSig)
1881 value = ARMul_LoadWordN (state, address + 4);
1883 value |= ARMul_LoadWordN (state, address);
1887 value = ARMul_LoadWordN (state, address);
1889 value |= ARMul_LoadWordN (state, address + 4);
1892 /* Check for data aborts. */
1894 ARMul_Abort (state, ARMul_DataAbortV);
1896 ARMul_Icycles (state, 2, 0L);
1902 Iwmmxt_Load_Word (ARMul_State * state, ARMword address)
1906 /* Check for a misaligned address. */
1909 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN))
1910 ARMul_Abort (state, ARMul_DataAbortV);
1915 value = ARMul_LoadWordN (state, address);
1918 ARMul_Abort (state, ARMul_DataAbortV);
1920 ARMul_Icycles (state, 1, 0L);
1926 Iwmmxt_Load_Half_Word (ARMul_State * state, ARMword address)
1930 /* Check for a misaligned address. */
1933 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN))
1934 ARMul_Abort (state, ARMul_DataAbortV);
1939 value = ARMul_LoadHalfWord (state, address);
1942 ARMul_Abort (state, ARMul_DataAbortV);
1944 ARMul_Icycles (state, 1, 0L);
1950 Iwmmxt_Load_Byte (ARMul_State * state, ARMword address)
1954 value = ARMul_LoadByte (state, address);
1957 ARMul_Abort (state, ARMul_DataAbortV);
1959 ARMul_Icycles (state, 1, 0L);
1965 Iwmmxt_Store_Double_Word (ARMul_State * state, ARMword address, ARMdword value)
1967 /* The address must be aligned on a 8 byte boundary. */
1970 fprintf (stderr, "iWMMXt: At addr 0x%x: Unaligned double word store to 0x%x\n",
1971 (state->Reg[15] - 8) & ~0x3, address);
1974 /* No need to check for alignment traps. An unaligned
1975 double word store with alignment trapping disabled is
1977 ARMul_Abort (state, ARMul_DataAbortV);
1980 /* Store the words. */
1981 if (! state->bigendSig)
1983 ARMul_StoreWordN (state, address, value);
1984 ARMul_StoreWordN (state, address + 4, value >> 32);
1988 ARMul_StoreWordN (state, address + 4, value);
1989 ARMul_StoreWordN (state, address, value >> 32);
1992 /* Check for data aborts. */
1994 ARMul_Abort (state, ARMul_DataAbortV);
1996 ARMul_Icycles (state, 2, 0L);
2000 Iwmmxt_Store_Word (ARMul_State * state, ARMword address, ARMword value)
2002 /* Check for a misaligned address. */
2005 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN))
2006 ARMul_Abort (state, ARMul_DataAbortV);
2011 ARMul_StoreWordN (state, address, value);
2014 ARMul_Abort (state, ARMul_DataAbortV);
2018 Iwmmxt_Store_Half_Word (ARMul_State * state, ARMword address, ARMword value)
2020 /* Check for a misaligned address. */
2023 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN))
2024 ARMul_Abort (state, ARMul_DataAbortV);
2029 ARMul_StoreHalfWord (state, address, value);
2032 ARMul_Abort (state, ARMul_DataAbortV);
2036 Iwmmxt_Store_Byte (ARMul_State * state, ARMword address, ARMword value)
2038 ARMul_StoreByte (state, address, value);
2041 ARMul_Abort (state, ARMul_DataAbortV);
2045 WLDR (ARMul_State * state, ARMword instr)
2050 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2054 fprintf (stderr, "wldr\n");
2057 address = Compute_Iwmmxt_Address (state, instr, & failed);
2061 if (BITS (28, 31) == 0xf)
2064 wC [BITS (12, 15)] = Iwmmxt_Load_Word (state, address);
2066 else if (BIT (8) == 0)
2070 wR [BITS (12, 15)] = Iwmmxt_Load_Byte (state, address);
2073 wR [BITS (12, 15)] = Iwmmxt_Load_Half_Word (state, address);
2079 wR [BITS (12, 15)] = Iwmmxt_Load_Word (state, address);
2082 wR [BITS (12, 15)] = Iwmmxt_Load_Double_Word (state, address);
2085 wC [wCon] |= WCON_MUP;
2091 WMAC (ARMword instr)
2097 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2101 fprintf (stderr, "wmac\n");
2104 for (i = 0; i < 4; i++)
2111 a = wRHALF (BITS (16, 19), i);
2114 b = wRHALF (BITS (0, 3), i);
2117 s = (signed long) a * (signed long) b;
2119 t = t + (ARMdword) s;
2124 a = wRHALF (BITS (16, 19), i);
2125 b = wRHALF (BITS ( 0, 3), i);
2132 wR [BITS (12, 15)] = 0;
2134 if (BIT (21)) /* Signed. */
2135 wR[BITS (12, 15)] += t;
2137 wR [BITS (12, 15)] += t;
2139 wC [wCon] |= WCON_MUP;
2145 WMADD (ARMword instr)
2150 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2154 fprintf (stderr, "wmadd\n");
2157 for (i = 0; i < 2; i++)
2161 if (BIT (21)) /* Signed. */
2165 a = wRHALF (BITS (16, 19), i * 2);
2168 b = wRHALF (BITS (0, 3), i * 2);
2171 s1 = (ARMdword) (a * b);
2173 a = wRHALF (BITS (16, 19), i * 2 + 1);
2176 b = wRHALF (BITS (0, 3), i * 2 + 1);
2179 s2 = (ARMdword) (a * b);
2181 else /* Unsigned. */
2185 a = wRHALF (BITS (16, 19), i * 2);
2186 b = wRHALF (BITS ( 0, 3), i * 2);
2188 s1 = (ARMdword) (a * b);
2190 a = wRHALF (BITS (16, 19), i * 2 + 1);
2191 b = wRHALF (BITS ( 0, 3), i * 2 + 1);
2193 s2 = (ARMdword) a * b;
2196 r |= (ARMdword) ((s1 + s2) & 0xffffffff) << (i ? 32 : 0);
2199 wR [BITS (12, 15)] = r;
2200 wC [wCon] |= WCON_MUP;
2206 WMAX (ARMul_State * state, ARMword instr)
2212 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2216 fprintf (stderr, "wmax\n");
2219 switch (BITS (22, 23))
2222 for (i = 0; i < 8; i++)
2223 if (BIT (21)) /* Signed. */
2227 a = wRBYTE (BITS (16, 19), i);
2230 b = wRBYTE (BITS (0, 3), i);
2238 r |= (s & 0xff) << (i * 8);
2240 else /* Unsigned. */
2244 a = wRBYTE (BITS (16, 19), i);
2245 b = wRBYTE (BITS (0, 3), i);
2252 r |= (s & 0xff) << (i * 8);
2257 for (i = 0; i < 4; i++)
2258 if (BIT (21)) /* Signed. */
2262 a = wRHALF (BITS (16, 19), i);
2265 b = wRHALF (BITS (0, 3), i);
2273 r |= (s & 0xffff) << (i * 16);
2275 else /* Unsigned. */
2279 a = wRHALF (BITS (16, 19), i);
2280 b = wRHALF (BITS (0, 3), i);
2287 r |= (s & 0xffff) << (i * 16);
2292 for (i = 0; i < 2; i++)
2293 if (BIT (21)) /* Signed. */
2297 a = wRWORD (BITS (16, 19), i);
2298 b = wRWORD (BITS (0, 3), i);
2305 r |= (s & 0xffffffff) << (i * 32);
2311 a = wRWORD (BITS (16, 19), i);
2312 b = wRWORD (BITS (0, 3), i);
2319 r |= (s & 0xffffffff) << (i * 32);
2324 ARMul_UndefInstr (state, instr);
2328 wR [BITS (12, 15)] = r;
2329 wC [wCon] |= WCON_MUP;
2335 WMIN (ARMul_State * state, ARMword instr)
2341 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2345 fprintf (stderr, "wmin\n");
2348 switch (BITS (22, 23))
2351 for (i = 0; i < 8; i++)
2352 if (BIT (21)) /* Signed. */
2356 a = wRBYTE (BITS (16, 19), i);
2359 b = wRBYTE (BITS (0, 3), i);
2367 r |= (s & 0xff) << (i * 8);
2369 else /* Unsigned. */
2373 a = wRBYTE (BITS (16, 19), i);
2374 b = wRBYTE (BITS (0, 3), i);
2381 r |= (s & 0xff) << (i * 8);
2386 for (i = 0; i < 4; i++)
2387 if (BIT (21)) /* Signed. */
2391 a = wRHALF (BITS (16, 19), i);
2394 b = wRHALF (BITS (0, 3), i);
2402 r |= (s & 0xffff) << (i * 16);
2409 a = wRHALF (BITS (16, 19), i);
2410 b = wRHALF (BITS ( 0, 3), i);
2417 r |= (s & 0xffff) << (i * 16);
2422 for (i = 0; i < 2; i++)
2423 if (BIT (21)) /* Signed. */
2427 a = wRWORD (BITS (16, 19), i);
2428 b = wRWORD (BITS ( 0, 3), i);
2435 r |= (s & 0xffffffff) << (i * 32);
2441 a = wRWORD (BITS (16, 19), i);
2442 b = wRWORD (BITS (0, 3), i);
2449 r |= (s & 0xffffffff) << (i * 32);
2454 ARMul_UndefInstr (state, instr);
2458 wR [BITS (12, 15)] = r;
2459 wC [wCon] |= WCON_MUP;
2465 WMUL (ARMword instr)
2471 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2475 fprintf (stderr, "wmul\n");
2478 for (i = 0; i < 4; i++)
2479 if (BIT (21)) /* Signed. */
2483 a = wRHALF (BITS (16, 19), i);
2486 b = wRHALF (BITS (0, 3), i);
2492 r |= ((s >> 16) & 0xffff) << (i * 16);
2494 r |= (s & 0xffff) << (i * 16);
2496 else /* Unsigned. */
2500 a = wRHALF (BITS (16, 19), i);
2501 b = wRHALF (BITS (0, 3), i);
2506 r |= ((s >> 16) & 0xffff) << (i * 16);
2508 r |= (s & 0xffff) << (i * 16);
2511 wR [BITS (12, 15)] = r;
2512 wC [wCon] |= WCON_MUP;
2523 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2527 fprintf (stderr, "wor\n");
2530 result = wR [BITS (16, 19)] | wR [BITS (0, 3)];
2531 wR [BITS (12, 15)] = result;
2533 SIMD64_SET (psr, (result == 0), SIMD_ZBIT);
2534 SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT);
2537 wC [wCon] |= (WCON_CUP | WCON_MUP);
2543 WPACK (ARMul_State * state, ARMword instr)
2552 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2556 fprintf (stderr, "wpack\n");
2559 switch (BITS (22, 23))
2562 for (i = 0; i < 8; i++)
2564 x = wRHALF (i < 4 ? BITS (16, 19) : BITS (0, 3), i & 3);
2566 switch (BITS (20, 21))
2568 case UnsignedSaturation:
2569 s = IwmmxtSaturateU8 (x, satrv + BITIDX8 (i));
2572 case SignedSaturation:
2573 s = IwmmxtSaturateS8 (x, satrv + BITIDX8 (i));
2577 ARMul_UndefInstr (state, instr);
2581 r |= (s & 0xff) << (i * 8);
2582 SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i);
2583 SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
2588 satrv[0] = satrv[2] = satrv[4] = satrv[6] = 0;
2590 for (i = 0; i < 4; i++)
2592 x = wRWORD (i < 2 ? BITS (16, 19) : BITS (0, 3), i & 1);
2594 switch (BITS (20, 21))
2596 case UnsignedSaturation:
2597 s = IwmmxtSaturateU16 (x, satrv + BITIDX16 (i));
2600 case SignedSaturation:
2601 s = IwmmxtSaturateS16 (x, satrv + BITIDX16 (i));
2605 ARMul_UndefInstr (state, instr);
2609 r |= (s & 0xffff) << (i * 16);
2610 SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2611 SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2616 satrv[0] = satrv[1] = satrv[2] = satrv[4] = satrv[5] = satrv[6] = 0;
2618 for (i = 0; i < 2; i++)
2620 x = wR [i ? BITS (0, 3) : BITS (16, 19)];
2622 switch (BITS (20, 21))
2624 case UnsignedSaturation:
2625 s = IwmmxtSaturateU32 (x, satrv + BITIDX32 (i));
2628 case SignedSaturation:
2629 s = IwmmxtSaturateS32 (x, satrv + BITIDX32 (i));
2633 ARMul_UndefInstr (state, instr);
2637 r |= (s & 0xffffffff) << (i * 32);
2638 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
2639 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
2644 ARMul_UndefInstr (state, instr);
2649 wR [BITS (12, 15)] = r;
2650 SET_wCSSFvec (satrv);
2651 wC [wCon] |= (WCON_CUP | WCON_MUP);
2657 WROR (ARMul_State * state, ARMword instr)
2665 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2669 fprintf (stderr, "wror\n");
2672 DECODE_G_BIT (state, instr, shift);
2674 switch (BITS (22, 23))
2678 for (i = 0; i < 4; i++)
2680 s = ((wRHALF (BITS (16, 19), i) & 0xffff) << (16 - shift))
2681 | ((wRHALF (BITS (16, 19), i) & 0xffff) >> shift);
2682 r |= (s & 0xffff) << (i * 16);
2683 SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2684 SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2690 for (i = 0; i < 2; i++)
2692 s = ((wRWORD (BITS (16, 19), i) & 0xffffffff) << (32 - shift))
2693 | ((wRWORD (BITS (16, 19), i) & 0xffffffff) >> shift);
2694 r |= (s & 0xffffffff) << (i * 32);
2695 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
2696 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
2702 r = (wR [BITS (16, 19)] >> shift)
2703 | (wR [BITS (16, 19)] << (64 - shift));
2705 SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
2706 SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
2710 ARMul_UndefInstr (state, instr);
2715 wR [BITS (12, 15)] = r;
2716 wC [wCon] |= (WCON_CUP | WCON_MUP);
2722 WSAD (ARMword instr)
2728 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2732 fprintf (stderr, "wsad\n");
2736 r = BIT (20) ? 0 : (wR [BITS (12, 15)] & 0xffffffff);
2740 for (i = 0; i < 4; i++)
2742 s = (wRHALF (BITS (16, 19), i) - wRHALF (BITS (0, 3), i));
2747 for (i = 0; i < 8; i++)
2749 s = (wRBYTE (BITS (16, 19), i) - wRBYTE (BITS (0, 3), i));
2753 wR [BITS (12, 15)] = r;
2754 wC [wCon] |= WCON_MUP;
2760 WSHUFH (ARMword instr)
2768 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2772 fprintf (stderr, "wshufh\n");
2775 imm8 = (BITS (20, 23) << 4) | BITS (0, 3);
2777 for (i = 0; i < 4; i++)
2779 s = wRHALF (BITS (16, 19), ((imm8 >> (i * 2) & 3)) & 0xff);
2780 r |= (s & 0xffff) << (i * 16);
2781 SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2782 SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2786 wR [BITS (12, 15)] = r;
2787 wC [wCon] |= (WCON_CUP | WCON_MUP);
2793 WSLL (ARMul_State * state, ARMword instr)
2801 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2805 fprintf (stderr, "wsll\n");
2808 DECODE_G_BIT (state, instr, shift);
2810 switch (BITS (22, 23))
2813 for (i = 0; i < 4; i++)
2818 s = ((wRHALF (BITS (16, 19), i) & 0xffff) << shift);
2819 r |= (s & 0xffff) << (i * 16);
2820 SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2821 SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2826 for (i = 0; i < 2; i++)
2831 s = ((wRWORD (BITS (16, 19), i) & 0xffffffff) << shift);
2832 r |= (s & 0xffffffff) << (i * 32);
2833 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
2834 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
2842 r = ((wR[BITS (16, 19)] & 0xffffffffffffffffULL) << shift);
2844 SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
2845 SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
2849 ARMul_UndefInstr (state, instr);
2854 wR [BITS (12, 15)] = r;
2855 wC [wCon] |= (WCON_CUP | WCON_MUP);
2861 WSRA (ARMul_State * state, ARMword instr)
2870 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2874 fprintf (stderr, "wsra\n");
2877 DECODE_G_BIT (state, instr, shift);
2879 switch (BITS (22, 23))
2882 for (i = 0; i < 4; i++)
2885 t = (wRHALF (BITS (16, 19), i) & 0x8000) ? 0xffff : 0;
2888 t = wRHALF (BITS (16, 19), i);
2894 r |= (s & 0xffff) << (i * 16);
2895 SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2896 SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2901 for (i = 0; i < 2; i++)
2904 t = (wRWORD (BITS (16, 19), i) & 0x80000000) ? 0xffffffff : 0;
2907 t = wRWORD (BITS (16, 19), i);
2911 r |= (s & 0xffffffff) << (i * 32);
2912 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
2913 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
2919 r = (wR [BITS (16, 19)] & 0x8000000000000000ULL) ? 0xffffffffffffffffULL : 0;
2921 r = ((signed long long) (wR[BITS (16, 19)] & 0xffffffffffffffffULL) >> shift);
2922 SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
2923 SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
2927 ARMul_UndefInstr (state, instr);
2932 wR [BITS (12, 15)] = r;
2933 wC [wCon] |= (WCON_CUP | WCON_MUP);
2939 WSRL (ARMul_State * state, ARMword instr)
2947 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
2951 fprintf (stderr, "wsrl\n");
2954 DECODE_G_BIT (state, instr, shift);
2956 switch (BITS (22, 23))
2959 for (i = 0; i < 4; i++)
2964 s = ((unsigned) (wRHALF (BITS (16, 19), i) & 0xffff) >> shift);
2966 r |= (s & 0xffff) << (i * 16);
2967 SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
2968 SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
2973 for (i = 0; i < 2; i++)
2978 s = ((unsigned long) (wRWORD (BITS (16, 19), i) & 0xffffffff) >> shift);
2980 r |= (s & 0xffffffff) << (i * 32);
2981 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
2982 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
2990 r = (wR [BITS (16, 19)] & 0xffffffffffffffffULL) >> shift;
2992 SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
2993 SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
2997 ARMul_UndefInstr (state, instr);
3002 wR [BITS (12, 15)] = r;
3003 wC [wCon] |= (WCON_CUP | WCON_MUP);
3009 WSTR (ARMul_State * state, ARMword instr)
3015 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3019 fprintf (stderr, "wstr\n");
3022 address = Compute_Iwmmxt_Address (state, instr, & failed);
3026 if (BITS (28, 31) == 0xf)
3029 Iwmmxt_Store_Word (state, address, wC [BITS (12, 15)]);
3031 else if (BIT (8) == 0)
3035 Iwmmxt_Store_Byte (state, address, wR [BITS (12, 15)]);
3038 Iwmmxt_Store_Half_Word (state, address, wR [BITS (12, 15)]);
3044 Iwmmxt_Store_Word (state, address, wR [BITS (12, 15)]);
3047 Iwmmxt_Store_Double_Word (state, address, wR [BITS (12, 15)]);
3054 WSUB (ARMul_State * state, ARMword instr)
3065 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3069 fprintf (stderr, "wsub\n");
3072 /* Subtract two numbers using the specified function,
3073 leaving setting the carry bit as required. */
3074 #define SUBx(x, y, m, f) \
3075 (*f) (wRBITS (BITS (16, 19), (x), (y)) & (m), \
3076 wRBITS (BITS ( 0, 3), (x), (y)) & (m), & carry, & overflow)
3078 switch (BITS (22, 23))
3081 for (i = 0; i < 8; i++)
3083 switch (BITS (20, 21))
3086 s = SUBx ((i * 8), (i * 8) + 7, 0xff, SubS8);
3087 satrv [BITIDX8 (i)] = 0;
3088 r |= (s & 0xff) << (i * 8);
3089 SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i);
3090 SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i);
3091 SIMD8_SET (psr, carry, SIMD_CBIT, i);
3092 SIMD8_SET (psr, overflow, SIMD_VBIT, i);
3095 case UnsignedSaturation:
3096 s = SUBx ((i * 8), (i * 8) + 7, 0xff, SubU8);
3097 x = IwmmxtSaturateU8 (s, satrv + BITIDX8 (i));
3098 r |= (x & 0xff) << (i * 8);
3099 SIMD8_SET (psr, NBIT8 (x), SIMD_NBIT, i);
3100 SIMD8_SET (psr, ZBIT8 (x), SIMD_ZBIT, i);
3101 if (! satrv [BITIDX8 (i)])
3103 SIMD8_SET (psr, carry, SIMD_CBIT, i);
3104 SIMD8_SET (psr, overflow, SIMD_VBIT, i);
3108 case SignedSaturation:
3109 s = SUBx ((i * 8), (i * 8) + 7, 0xff, SubS8);
3110 x = IwmmxtSaturateS8 (s, satrv + BITIDX8 (i));
3111 r |= (x & 0xff) << (i * 8);
3112 SIMD8_SET (psr, NBIT8 (x), SIMD_NBIT, i);
3113 SIMD8_SET (psr, ZBIT8 (x), SIMD_ZBIT, i);
3114 if (! satrv [BITIDX8 (i)])
3116 SIMD8_SET (psr, carry, SIMD_CBIT, i);
3117 SIMD8_SET (psr, overflow, SIMD_VBIT, i);
3122 ARMul_UndefInstr (state, instr);
3129 satrv[0] = satrv[2] = satrv[4] = satrv[6] = 0;
3131 for (i = 0; i < 4; i++)
3133 switch (BITS (20, 21))
3136 s = SUBx ((i * 16), (i * 16) + 15, 0xffff, SubU16);
3137 satrv [BITIDX16 (i)] = 0;
3138 r |= (s & 0xffff) << (i * 16);
3139 SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
3140 SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
3141 SIMD16_SET (psr, carry, SIMD_CBIT, i);
3142 SIMD16_SET (psr, overflow, SIMD_VBIT, i);
3145 case UnsignedSaturation:
3146 s = SUBx ((i * 16), (i * 16) + 15, 0xffff, SubU16);
3147 x = IwmmxtSaturateU16 (s, satrv + BITIDX16 (i));
3148 r |= (x & 0xffff) << (i * 16);
3149 SIMD16_SET (psr, NBIT16 (x & 0xffff), SIMD_NBIT, i);
3150 SIMD16_SET (psr, ZBIT16 (x), SIMD_ZBIT, i);
3151 if (! satrv [BITIDX16 (i)])
3153 SIMD16_SET (psr, carry, SIMD_CBIT, i);
3154 SIMD16_SET (psr, overflow, SIMD_VBIT, i);
3158 case SignedSaturation:
3159 s = SUBx ((i * 16), (i * 16) + 15, 0xffff, SubS16);
3160 x = IwmmxtSaturateS16 (s, satrv + BITIDX16 (i));
3161 r |= (x & 0xffff) << (i * 16);
3162 SIMD16_SET (psr, NBIT16 (x), SIMD_NBIT, i);
3163 SIMD16_SET (psr, ZBIT16 (x), SIMD_ZBIT, i);
3164 if (! satrv [BITIDX16 (i)])
3166 SIMD16_SET (psr, carry, SIMD_CBIT, i);
3167 SIMD16_SET (psr, overflow, SIMD_VBIT, i);
3172 ARMul_UndefInstr (state, instr);
3179 satrv[0] = satrv[1] = satrv[2] = satrv[4] = satrv[5] = satrv[6] = 0;
3181 for (i = 0; i < 2; i++)
3183 switch (BITS (20, 21))
3186 s = SUBx ((i * 32), (i * 32) + 31, 0xffffffff, SubU32);
3187 satrv[BITIDX32 (i)] = 0;
3188 r |= (s & 0xffffffff) << (i * 32);
3189 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
3190 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
3191 SIMD32_SET (psr, carry, SIMD_CBIT, i);
3192 SIMD32_SET (psr, overflow, SIMD_VBIT, i);
3195 case UnsignedSaturation:
3196 s = SUBx ((i * 32), (i * 32) + 31, 0xffffffff, SubU32);
3197 x = IwmmxtSaturateU32 (s, satrv + BITIDX32 (i));
3198 r |= (x & 0xffffffff) << (i * 32);
3199 SIMD32_SET (psr, NBIT32 (x), SIMD_NBIT, i);
3200 SIMD32_SET (psr, ZBIT32 (x), SIMD_ZBIT, i);
3201 if (! satrv [BITIDX32 (i)])
3203 SIMD32_SET (psr, carry, SIMD_CBIT, i);
3204 SIMD32_SET (psr, overflow, SIMD_VBIT, i);
3208 case SignedSaturation:
3209 s = SUBx ((i * 32), (i * 32) + 31, 0xffffffff, SubS32);
3210 x = IwmmxtSaturateS32 (s, satrv + BITIDX32 (i));
3211 r |= (x & 0xffffffff) << (i * 32);
3212 SIMD32_SET (psr, NBIT32 (x), SIMD_NBIT, i);
3213 SIMD32_SET (psr, ZBIT32 (x), SIMD_ZBIT, i);
3214 if (! satrv [BITIDX32 (i)])
3216 SIMD32_SET (psr, carry, SIMD_CBIT, i);
3217 SIMD32_SET (psr, overflow, SIMD_VBIT, i);
3222 ARMul_UndefInstr (state, instr);
3229 ARMul_UndefInstr (state, instr);
3233 wR [BITS (12, 15)] = r;
3235 SET_wCSSFvec (satrv);
3236 wC [wCon] |= (WCON_CUP | WCON_MUP);
3244 WUNPCKEH (ARMul_State * state, ARMword instr)
3251 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3255 fprintf (stderr, "wunpckeh\n");
3258 switch (BITS (22, 23))
3261 for (i = 0; i < 4; i++)
3263 s = wRBYTE (BITS (16, 19), i + 4);
3265 if (BIT (21) && NBIT8 (s))
3268 r |= (s & 0xffff) << (i * 16);
3269 SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
3270 SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
3275 for (i = 0; i < 2; i++)
3277 s = wRHALF (BITS (16, 19), i + 2);
3279 if (BIT (21) && NBIT16 (s))
3282 r |= (s & 0xffffffff) << (i * 32);
3283 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
3284 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
3289 r = wRWORD (BITS (16, 19), 1);
3291 if (BIT (21) && NBIT32 (r))
3292 r |= 0xffffffff00000000ULL;
3294 SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
3295 SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
3299 ARMul_UndefInstr (state, instr);
3304 wR [BITS (12, 15)] = r;
3305 wC [wCon] |= (WCON_CUP | WCON_MUP);
3311 WUNPCKEL (ARMul_State * state, ARMword instr)
3318 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3322 fprintf (stderr, "wunpckel\n");
3325 switch (BITS (22, 23))
3328 for (i = 0; i < 4; i++)
3330 s = wRBYTE (BITS (16, 19), i);
3332 if (BIT (21) && NBIT8 (s))
3335 r |= (s & 0xffff) << (i * 16);
3336 SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i);
3337 SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i);
3342 for (i = 0; i < 2; i++)
3344 s = wRHALF (BITS (16, 19), i);
3346 if (BIT (21) && NBIT16 (s))
3349 r |= (s & 0xffffffff) << (i * 32);
3350 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i);
3351 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i);
3356 r = wRWORD (BITS (16, 19), 0);
3358 if (BIT (21) && NBIT32 (r))
3359 r |= 0xffffffff00000000ULL;
3361 SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT);
3362 SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT);
3366 ARMul_UndefInstr (state, instr);
3371 wR [BITS (12, 15)] = r;
3372 wC [wCon] |= (WCON_CUP | WCON_MUP);
3378 WUNPCKIH (ARMul_State * state, ARMword instr)
3386 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3390 fprintf (stderr, "wunpckih\n");
3393 switch (BITS (22, 23))
3396 for (i = 0; i < 4; i++)
3398 a = wRBYTE (BITS (16, 19), i + 4);
3399 b = wRBYTE (BITS ( 0, 3), i + 4);
3401 r |= (s & 0xffff) << (i * 16);
3402 SIMD8_SET (psr, NBIT8 (a), SIMD_NBIT, i * 2);
3403 SIMD8_SET (psr, ZBIT8 (a), SIMD_ZBIT, i * 2);
3404 SIMD8_SET (psr, NBIT8 (b), SIMD_NBIT, (i * 2) + 1);
3405 SIMD8_SET (psr, ZBIT8 (b), SIMD_ZBIT, (i * 2) + 1);
3410 for (i = 0; i < 2; i++)
3412 a = wRHALF (BITS (16, 19), i + 2);
3413 b = wRHALF (BITS ( 0, 3), i + 2);
3415 r |= (s & 0xffffffff) << (i * 32);
3416 SIMD16_SET (psr, NBIT16 (a), SIMD_NBIT, (i * 2));
3417 SIMD16_SET (psr, ZBIT16 (a), SIMD_ZBIT, (i * 2));
3418 SIMD16_SET (psr, NBIT16 (b), SIMD_NBIT, (i * 2) + 1);
3419 SIMD16_SET (psr, ZBIT16 (b), SIMD_ZBIT, (i * 2) + 1);
3424 a = wRWORD (BITS (16, 19), 1);
3425 s = wRWORD (BITS ( 0, 3), 1);
3428 SIMD32_SET (psr, NBIT32 (a), SIMD_NBIT, 0);
3429 SIMD32_SET (psr, ZBIT32 (a), SIMD_ZBIT, 0);
3430 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, 1);
3431 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, 1);
3435 ARMul_UndefInstr (state, instr);
3440 wR [BITS (12, 15)] = r;
3441 wC [wCon] |= (WCON_CUP | WCON_MUP);
3447 WUNPCKIL (ARMul_State * state, ARMword instr)
3455 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3459 fprintf (stderr, "wunpckil\n");
3462 switch (BITS (22, 23))
3465 for (i = 0; i < 4; i++)
3467 a = wRBYTE (BITS (16, 19), i);
3468 b = wRBYTE (BITS ( 0, 3), i);
3470 r |= (s & 0xffff) << (i * 16);
3471 SIMD8_SET (psr, NBIT8 (a), SIMD_NBIT, i * 2);
3472 SIMD8_SET (psr, ZBIT8 (a), SIMD_ZBIT, i * 2);
3473 SIMD8_SET (psr, NBIT8 (b), SIMD_NBIT, (i * 2) + 1);
3474 SIMD8_SET (psr, ZBIT8 (b), SIMD_ZBIT, (i * 2) + 1);
3479 for (i = 0; i < 2; i++)
3481 a = wRHALF (BITS (16, 19), i);
3482 b = wRHALF (BITS ( 0, 3), i);
3484 r |= (s & 0xffffffff) << (i * 32);
3485 SIMD16_SET (psr, NBIT16 (a), SIMD_NBIT, (i * 2));
3486 SIMD16_SET (psr, ZBIT16 (a), SIMD_ZBIT, (i * 2));
3487 SIMD16_SET (psr, NBIT16 (b), SIMD_NBIT, (i * 2) + 1);
3488 SIMD16_SET (psr, ZBIT16 (b), SIMD_ZBIT, (i * 2) + 1);
3493 a = wRWORD (BITS (16, 19), 0);
3494 s = wRWORD (BITS ( 0, 3), 0);
3497 SIMD32_SET (psr, NBIT32 (a), SIMD_NBIT, 0);
3498 SIMD32_SET (psr, ZBIT32 (a), SIMD_ZBIT, 0);
3499 SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, 1);
3500 SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, 1);
3504 ARMul_UndefInstr (state, instr);
3509 wR [BITS (12, 15)] = r;
3510 wC [wCon] |= (WCON_CUP | WCON_MUP);
3516 WXOR (ARMword instr)
3521 if ((read_cp15_reg (15, 0, 1) & 3) != 3)
3525 fprintf (stderr, "wxor\n");
3528 result = wR [BITS (16, 19)] ^ wR [BITS (0, 3)];
3529 wR [BITS (12, 15)] = result;
3531 SIMD64_SET (psr, (result == 0), SIMD_ZBIT);
3532 SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT);
3535 wC [wCon] |= (WCON_CUP | WCON_MUP);
3540 /* This switch table is moved to a seperate function in order
3541 to work around a compiler bug in the host compiler... */
3544 Process_Instruction (ARMul_State * state, ARMword instr)
3546 int status = ARMul_BUSY;
3548 switch ((BITS (20, 23) << 8) | BITS (4, 11))
3550 case 0x000: status = WOR (instr); break;
3551 case 0x011: status = TMCR (state, instr); break;
3552 case 0x100: status = WXOR (instr); break;
3553 case 0x111: status = TMRC (state, instr); break;
3554 case 0x300: status = WANDN (instr); break;
3555 case 0x200: status = WAND (instr); break;
3557 case 0x810: case 0xa10:
3558 status = WMADD (instr); break;
3560 case 0x10e: case 0x50e: case 0x90e: case 0xd0e:
3561 status = WUNPCKIL (state, instr); break;
3562 case 0x10c: case 0x50c: case 0x90c: case 0xd0c:
3563 status = WUNPCKIH (state, instr); break;
3564 case 0x012: case 0x112: case 0x412: case 0x512:
3565 status = WSAD (instr); break;
3566 case 0x010: case 0x110: case 0x210: case 0x310:
3567 status = WMUL (instr); break;
3568 case 0x410: case 0x510: case 0x610: case 0x710:
3569 status = WMAC (instr); break;
3570 case 0x006: case 0x406: case 0x806: case 0xc06:
3571 status = WCMPEQ (state, instr); break;
3572 case 0x800: case 0x900: case 0xc00: case 0xd00:
3573 status = WAVG2 (instr); break;
3574 case 0x802: case 0x902: case 0xa02: case 0xb02:
3575 status = WALIGNR (state, instr); break;
3576 case 0x601: case 0x605: case 0x609: case 0x60d:
3577 status = TINSR (state, instr); break;
3578 case 0x107: case 0x507: case 0x907: case 0xd07:
3579 status = TEXTRM (state, instr); break;
3580 case 0x117: case 0x517: case 0x917: case 0xd17:
3581 status = TEXTRC (state, instr); break;
3582 case 0x401: case 0x405: case 0x409: case 0x40d:
3583 status = TBCST (state, instr); break;
3584 case 0x113: case 0x513: case 0x913: case 0xd13:
3585 status = TANDC (state, instr); break;
3586 case 0x01c: case 0x41c: case 0x81c: case 0xc1c:
3587 status = WACC (state, instr); break;
3588 case 0x115: case 0x515: case 0x915: case 0xd15:
3589 status = TORC (state, instr); break;
3590 case 0x103: case 0x503: case 0x903: case 0xd03:
3591 status = TMOVMSK (state, instr); break;
3592 case 0x106: case 0x306: case 0x506: case 0x706:
3593 case 0x906: case 0xb06: case 0xd06: case 0xf06:
3594 status = WCMPGT (state, instr); break;
3595 case 0x00e: case 0x20e: case 0x40e: case 0x60e:
3596 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
3597 status = WUNPCKEL (state, instr); break;
3598 case 0x00c: case 0x20c: case 0x40c: case 0x60c:
3599 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
3600 status = WUNPCKEH (state, instr); break;
3601 case 0x204: case 0x604: case 0xa04: case 0xe04:
3602 case 0x214: case 0x614: case 0xa14: case 0xe14:
3603 status = WSRL (state, instr); break;
3604 case 0x004: case 0x404: case 0x804: case 0xc04:
3605 case 0x014: case 0x414: case 0x814: case 0xc14:
3606 status = WSRA (state, instr); break;
3607 case 0x104: case 0x504: case 0x904: case 0xd04:
3608 case 0x114: case 0x514: case 0x914: case 0xd14:
3609 status = WSLL (state, instr); break;
3610 case 0x304: case 0x704: case 0xb04: case 0xf04:
3611 case 0x314: case 0x714: case 0xb14: case 0xf14:
3612 status = WROR (state, instr); break;
3613 case 0x116: case 0x316: case 0x516: case 0x716:
3614 case 0x916: case 0xb16: case 0xd16: case 0xf16:
3615 status = WMIN (state, instr); break;
3616 case 0x016: case 0x216: case 0x416: case 0x616:
3617 case 0x816: case 0xa16: case 0xc16: case 0xe16:
3618 status = WMAX (state, instr); break;
3619 case 0x002: case 0x102: case 0x202: case 0x302:
3620 case 0x402: case 0x502: case 0x602: case 0x702:
3621 status = WALIGNI (instr); break;
3622 case 0x01a: case 0x11a: case 0x21a: case 0x31a:
3623 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
3624 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
3625 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
3626 status = WSUB (state, instr); break;
3627 case 0x01e: case 0x11e: case 0x21e: case 0x31e:
3628 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
3629 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
3630 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
3631 status = WSHUFH (instr); break;
3632 case 0x018: case 0x118: case 0x218: case 0x318:
3633 case 0x418: case 0x518: case 0x618: case 0x718:
3634 case 0x818: case 0x918: case 0xa18: case 0xb18:
3635 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
3636 status = WADD (state, instr); break;
3637 case 0x008: case 0x108: case 0x208: case 0x308:
3638 case 0x408: case 0x508: case 0x608: case 0x708:
3639 case 0x808: case 0x908: case 0xa08: case 0xb08:
3640 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
3641 status = WPACK (state, instr); break;
3642 case 0x201: case 0x203: case 0x205: case 0x207:
3643 case 0x209: case 0x20b: case 0x20d: case 0x20f:
3644 case 0x211: case 0x213: case 0x215: case 0x217:
3645 case 0x219: case 0x21b: case 0x21d: case 0x21f:
3646 switch (BITS (16, 19))
3648 case 0x0: status = TMIA (state, instr); break;
3649 case 0x8: status = TMIAPH (state, instr); break;
3653 case 0xf: status = TMIAxy (state, instr); break;
3663 /* Process a possibly Intel(r) Wireless MMX(tm) technology instruction.
3664 Return true if the instruction was handled. */
3667 ARMul_HandleIwmmxt (ARMul_State * state, ARMword instr)
3669 int status = ARMul_BUSY;
3671 if (BITS (24, 27) == 0xe)
3673 status = Process_Instruction (state, instr);
3675 else if (BITS (25, 27) == 0x6)
3677 if (BITS (4, 11) == 0x0 && BITS (20, 24) == 0x4)
3678 status = TMCRR (state, instr);
3679 else if (BITS (9, 11) == 0x0)
3681 if (BIT (20) == 0x0)
3682 status = WSTR (state, instr);
3683 else if (BITS (20, 24) == 0x5)
3684 status = TMRRC (state, instr);
3686 status = WLDR (state, instr);
3690 if (status == ARMul_CANT)
3692 /* If the instruction was a recognised but illegal,
3693 perform the abort here rather than returning false.
3694 If we return false then ARMul_MRC may be called which
3695 will still abort, but which also perform the register
3697 ARMul_Abort (state, ARMul_UndefinedInstrV);
3698 status = ARMul_DONE;
3701 return status == ARMul_DONE;
3705 Fetch_Iwmmxt_Register (unsigned int regnum, unsigned char * memory)
3709 memcpy (memory, wC + (regnum - 16), sizeof wC [0]);
3710 return sizeof wC [0];
3714 memcpy (memory, wR + regnum, sizeof wR [0]);
3715 return sizeof wR [0];
3720 Store_Iwmmxt_Register (unsigned int regnum, unsigned char * memory)
3724 memcpy (wC + (regnum - 16), memory, sizeof wC [0]);
3725 return sizeof wC [0];
3729 memcpy (wR + regnum, memory, sizeof wR [0]);
3730 return sizeof wR [0];