• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

修订版d355127720dea14eef250e2e2c3db273d97f0c0c (tree)
时间2003-03-30 08:29:48
作者nobody <>
Commiternobody <>

Log Message

This commit was manufactured by cvs2svn to create branch
'cagney_framebase-20030326-branch'.

Cherrypick from master 2003-03-29 23:29:47 UTC Andrew Cagney <cagney@redhat.com> '2003-03-29 Andrew Cagney <cagney@redhat.com>':

gdb/infttrace.h
gdb/testsuite/gdb.base/gdb1090.c
gdb/testsuite/gdb.base/gdb1090.exp
gdb/testsuite/gdb.gdb/observer.exp
sim/arm/iwmmxt.c
sim/arm/iwmmxt.h

更改概述

差异

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