summaryrefslogtreecommitdiff
path: root/src/core/arm/interpreter/armsupp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/arm/interpreter/armsupp.cpp')
-rw-r--r--src/core/arm/interpreter/armsupp.cpp1220
1 files changed, 622 insertions, 598 deletions
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index 7816c4c42..219ba78ce 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -1,38 +1,39 @@
1/* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator. 1/* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd. 2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3 3
4 This program is free software; you can redistribute it and/or modify 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 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 6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version. 7 (at your option) any later version.
8 8
9 This program is distributed in the hope that it will be useful, 9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details. 12 GNU General Public License for more details.
13 13
14 You should have received a copy of the GNU General Public License 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 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. */ 16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17 17
18//#include <util.h>
19
18#include "core/arm/interpreter/armdefs.h" 20#include "core/arm/interpreter/armdefs.h"
19#include "core/arm/interpreter/armemu.h" 21#include "core/arm/interpreter/armemu.h"
20#include "core/arm/interpreter/skyeye_defs.h"
21#include "core/hle/coprocessor.h" 22#include "core/hle/coprocessor.h"
22#include "core/arm/disassembler/arm_disasm.h" 23#include "core/arm/disassembler/arm_disasm.h"
23 24
24unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg, 25//#include "ansidecl.h"
25 unsigned cpnum); 26//#include "skyeye.h"
26//extern int skyeye_instr_debug; 27//extern int skyeye_instr_debug;
27/* Definitions for the support routines. */ 28/* Definitions for the support routines. */
28 29
29static ARMword ModeToBank (ARMword); 30static ARMword ModeToBank (ARMword);
30static void EnvokeList (ARMul_State *, unsigned int, unsigned int); 31static void EnvokeList (ARMul_State *, unsigned int, unsigned int);
31 32
32struct EventNode 33struct EventNode {
33{ /* An event list node. */ 34 /* An event list node. */
34 unsigned (*func) (ARMul_State *); /* The function to call. */ 35 unsigned (*func) (ARMul_State *); /* The function to call. */
35 struct EventNode *next; 36 struct EventNode *next;
36}; 37};
37 38
38/* This routine returns the value of a register from a mode. */ 39/* This routine returns the value of a register from a mode. */
@@ -40,11 +41,11 @@ struct EventNode
40ARMword 41ARMword
41ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg) 42ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg)
42{ 43{
43 mode &= MODEBITS; 44 mode &= MODEBITS;
44 if (mode != state->Mode) 45 if (mode != state->Mode)
45 return (state->RegBank[ModeToBank ((ARMword) mode)][reg]); 46 return (state->RegBank[ModeToBank ((ARMword) mode)][reg]);
46 else 47 else
47 return (state->Reg[reg]); 48 return (state->Reg[reg]);
48} 49}
49 50
50/* This routine sets the value of a register for a mode. */ 51/* This routine sets the value of a register for a mode. */
@@ -52,11 +53,11 @@ ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg)
52void 53void
53ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value) 54ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value)
54{ 55{
55 mode &= MODEBITS; 56 mode &= MODEBITS;
56 if (mode != state->Mode) 57 if (mode != state->Mode)
57 state->RegBank[ModeToBank ((ARMword) mode)][reg] = value; 58 state->RegBank[ModeToBank ((ARMword) mode)][reg] = value;
58 else 59 else
59 state->Reg[reg] = value; 60 state->Reg[reg] = value;
60} 61}
61 62
62/* This routine returns the value of the PC, mode independently. */ 63/* This routine returns the value of the PC, mode independently. */
@@ -64,10 +65,10 @@ ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value)
64ARMword 65ARMword
65ARMul_GetPC (ARMul_State * state) 66ARMul_GetPC (ARMul_State * state)
66{ 67{
67 if (state->Mode > SVC26MODE) 68 if (state->Mode > SVC26MODE)
68 return state->Reg[15]; 69 return state->Reg[15];
69 else 70 else
70 return R15PC; 71 return R15PC;
71} 72}
72 73
73/* This routine returns the value of the PC, mode independently. */ 74/* This routine returns the value of the PC, mode independently. */
@@ -75,10 +76,10 @@ ARMul_GetPC (ARMul_State * state)
75ARMword 76ARMword
76ARMul_GetNextPC (ARMul_State * state) 77ARMul_GetNextPC (ARMul_State * state)
77{ 78{
78 if (state->Mode > SVC26MODE) 79 if (state->Mode > SVC26MODE)
79 return state->Reg[15] + isize; 80 return state->Reg[15] + INSN_SIZE;
80 else 81 else
81 return (state->Reg[15] + isize) & R15PCBITS; 82 return (state->Reg[15] + INSN_SIZE) & R15PCBITS;
82} 83}
83 84
84/* This routine sets the value of the PC. */ 85/* This routine sets the value of the PC. */
@@ -86,11 +87,11 @@ ARMul_GetNextPC (ARMul_State * state)
86void 87void
87ARMul_SetPC (ARMul_State * state, ARMword value) 88ARMul_SetPC (ARMul_State * state, ARMword value)
88{ 89{
89 if (ARMul_MODE32BIT) 90 if (ARMul_MODE32BIT)
90 state->Reg[15] = value & PCBITS; 91 state->Reg[15] = value & PCBITS;
91 else 92 else
92 state->Reg[15] = R15CCINTMODE | (value & R15PCBITS); 93 state->Reg[15] = R15CCINTMODE | (value & R15PCBITS);
93 FLUSHPIPE; 94 FLUSHPIPE;
94} 95}
95 96
96/* This routine returns the value of register 15, mode independently. */ 97/* This routine returns the value of register 15, mode independently. */
@@ -98,10 +99,10 @@ ARMul_SetPC (ARMul_State * state, ARMword value)
98ARMword 99ARMword
99ARMul_GetR15 (ARMul_State * state) 100ARMul_GetR15 (ARMul_State * state)
100{ 101{
101 if (state->Mode > SVC26MODE) 102 if (state->Mode > SVC26MODE)
102 return (state->Reg[15]); 103 return (state->Reg[15]);
103 else 104 else
104 return (R15PC | ECC | ER15INT | EMODE); 105 return (R15PC | ECC | ER15INT | EMODE);
105} 106}
106 107
107/* This routine sets the value of Register 15. */ 108/* This routine sets the value of Register 15. */
@@ -109,13 +110,13 @@ ARMul_GetR15 (ARMul_State * state)
109void 110void
110ARMul_SetR15 (ARMul_State * state, ARMword value) 111ARMul_SetR15 (ARMul_State * state, ARMword value)
111{ 112{
112 if (ARMul_MODE32BIT) 113 if (ARMul_MODE32BIT)
113 state->Reg[15] = value & PCBITS; 114 state->Reg[15] = value & PCBITS;
114 else { 115 else {
115 state->Reg[15] = value; 116 state->Reg[15] = value;
116 ARMul_R15Altered (state); 117 ARMul_R15Altered (state);
117 } 118 }
118 FLUSHPIPE; 119 FLUSHPIPE;
119} 120}
120 121
121/* This routine returns the value of the CPSR. */ 122/* This routine returns the value of the CPSR. */
@@ -123,9 +124,9 @@ ARMul_SetR15 (ARMul_State * state, ARMword value)
123ARMword 124ARMword
124ARMul_GetCPSR (ARMul_State * state) 125ARMul_GetCPSR (ARMul_State * state)
125{ 126{
126 //chy 2003-08-20: below is from gdb20030716, maybe isn't suitable for system simulator 127 //chy 2003-08-20: below is from gdb20030716, maybe isn't suitable for system simulator
127 //return (CPSR | state->Cpsr); for gdb20030716 128 //return (CPSR | state->Cpsr); for gdb20030716
128 return (CPSR); //had be tested in old skyeye with gdb5.0-5.3 129 return (CPSR); //had be tested in old skyeye with gdb5.0-5.3
129} 130}
130 131
131/* This routine sets the value of the CPSR. */ 132/* This routine sets the value of the CPSR. */
@@ -133,8 +134,8 @@ ARMul_GetCPSR (ARMul_State * state)
133void 134void
134ARMul_SetCPSR (ARMul_State * state, ARMword value) 135ARMul_SetCPSR (ARMul_State * state, ARMword value)
135{ 136{
136 state->Cpsr = value; 137 state->Cpsr = value;
137 ARMul_CPSRAltered (state); 138 ARMul_CPSRAltered (state);
138} 139}
139 140
140/* This routine does all the nasty bits involved in a write to the CPSR, 141/* This routine does all the nasty bits involved in a write to the CPSR,
@@ -143,20 +144,20 @@ ARMul_SetCPSR (ARMul_State * state, ARMword value)
143void 144void
144ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs) 145ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs)
145{ 146{
146 state->Cpsr = ARMul_GetCPSR (state); 147 state->Cpsr = ARMul_GetCPSR (state);
147 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode 148 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
148 if (state->Mode != USER26MODE && state->Mode != USER32MODE ) { 149 if (state->Mode != USER26MODE && state->Mode != USER32MODE ) {
149 /* In user mode, only write flags. */ 150 /* In user mode, only write flags. */
150 if (BIT (16)) 151 if (BIT (16))
151 SETPSR_C (state->Cpsr, rhs); 152 SETPSR_C (state->Cpsr, rhs);
152 if (BIT (17)) 153 if (BIT (17))
153 SETPSR_X (state->Cpsr, rhs); 154 SETPSR_X (state->Cpsr, rhs);
154 if (BIT (18)) 155 if (BIT (18))
155 SETPSR_S (state->Cpsr, rhs); 156 SETPSR_S (state->Cpsr, rhs);
156 } 157 }
157 if (BIT (19)) 158 if (BIT (19))
158 SETPSR_F (state->Cpsr, rhs); 159 SETPSR_F (state->Cpsr, rhs);
159 ARMul_CPSRAltered (state); 160 ARMul_CPSRAltered (state);
160} 161}
161 162
162/* Get an SPSR from the specified mode. */ 163/* Get an SPSR from the specified mode. */
@@ -164,12 +165,12 @@ ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs)
164ARMword 165ARMword
165ARMul_GetSPSR (ARMul_State * state, ARMword mode) 166ARMul_GetSPSR (ARMul_State * state, ARMword mode)
166{ 167{
167 ARMword bank = ModeToBank (mode & MODEBITS); 168 ARMword bank = ModeToBank (mode & MODEBITS);
168 169
169 if (!BANK_CAN_ACCESS_SPSR (bank)) 170 if (!BANK_CAN_ACCESS_SPSR (bank))
170 return ARMul_GetCPSR (state); 171 return ARMul_GetCPSR (state);
171 172
172 return state->Spsr[bank]; 173 return state->Spsr[bank];
173} 174}
174 175
175/* This routine does a write to an SPSR. */ 176/* This routine does a write to an SPSR. */
@@ -177,10 +178,10 @@ ARMul_GetSPSR (ARMul_State * state, ARMword mode)
177void 178void
178ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value) 179ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
179{ 180{
180 ARMword bank = ModeToBank (mode & MODEBITS); 181 ARMword bank = ModeToBank (mode & MODEBITS);
181 182
182 if (BANK_CAN_ACCESS_SPSR (bank)) 183 if (BANK_CAN_ACCESS_SPSR (bank))
183 state->Spsr[bank] = value; 184 state->Spsr[bank] = value;
184} 185}
185 186
186/* This routine does a write to the current SPSR, given an MSR instruction. */ 187/* This routine does a write to the current SPSR, given an MSR instruction. */
@@ -188,16 +189,16 @@ ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
188void 189void
189ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs) 190ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs)
190{ 191{
191 if (BANK_CAN_ACCESS_SPSR (state->Bank)) { 192 if (BANK_CAN_ACCESS_SPSR (state->Bank)) {
192 if (BIT (16)) 193 if (BIT (16))
193 SETPSR_C (state->Spsr[state->Bank], rhs); 194 SETPSR_C (state->Spsr[state->Bank], rhs);
194 if (BIT (17)) 195 if (BIT (17))
195 SETPSR_X (state->Spsr[state->Bank], rhs); 196 SETPSR_X (state->Spsr[state->Bank], rhs);
196 if (BIT (18)) 197 if (BIT (18))
197 SETPSR_S (state->Spsr[state->Bank], rhs); 198 SETPSR_S (state->Spsr[state->Bank], rhs);
198 if (BIT (19)) 199 if (BIT (19))
199 SETPSR_F (state->Spsr[state->Bank], rhs); 200 SETPSR_F (state->Spsr[state->Bank], rhs);
200 } 201 }
201} 202}
202 203
203/* This routine updates the state of the emulator after the Cpsr has been 204/* This routine updates the state of the emulator after the Cpsr has been
@@ -206,53 +207,51 @@ ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs)
206void 207void
207ARMul_CPSRAltered (ARMul_State * state) 208ARMul_CPSRAltered (ARMul_State * state)
208{ 209{
209 ARMword oldmode; 210 ARMword oldmode;
210 211
211 if (state->prog32Sig == LOW) 212 if (state->prog32Sig == LOW)
212 state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS); 213 state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS);
213 214
214 oldmode = state->Mode; 215 oldmode = state->Mode;
215 216
216 if (state->Mode != (state->Cpsr & MODEBITS)) { 217 /*if (state->Mode != (state->Cpsr & MODEBITS)) {
217 state->Mode = 218 state->Mode =
218 ARMul_SwitchMode (state, state->Mode, 219 ARMul_SwitchMode (state, state->Mode,
219 state->Cpsr & MODEBITS); 220 state->Cpsr & MODEBITS);
220 221
221 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 222 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
222 } 223 }*/
223 //state->Cpsr &= ~MODEBITS; 224 //state->Cpsr &= ~MODEBITS;
224 225
225 ASSIGNINT (state->Cpsr & INTBITS); 226 ASSIGNINT (state->Cpsr & INTBITS);
226 //state->Cpsr &= ~INTBITS; 227 //state->Cpsr &= ~INTBITS;
227 ASSIGNN ((state->Cpsr & NBIT) != 0); 228 ASSIGNN ((state->Cpsr & NBIT) != 0);
228 //state->Cpsr &= ~NBIT; 229 //state->Cpsr &= ~NBIT;
229 ASSIGNZ ((state->Cpsr & ZBIT) != 0); 230 ASSIGNZ ((state->Cpsr & ZBIT) != 0);
230 //state->Cpsr &= ~ZBIT; 231 //state->Cpsr &= ~ZBIT;
231 ASSIGNC ((state->Cpsr & CBIT) != 0); 232 ASSIGNC ((state->Cpsr & CBIT) != 0);
232 //state->Cpsr &= ~CBIT; 233 //state->Cpsr &= ~CBIT;
233 ASSIGNV ((state->Cpsr & VBIT) != 0); 234 ASSIGNV ((state->Cpsr & VBIT) != 0);
234 //state->Cpsr &= ~VBIT; 235 //state->Cpsr &= ~VBIT;
235 ASSIGNS ((state->Cpsr & SBIT) != 0); 236 ASSIGNS ((state->Cpsr & SBIT) != 0);
236 //state->Cpsr &= ~SBIT; 237 //state->Cpsr &= ~SBIT;
237#ifdef MODET 238#ifdef MODET
238 ASSIGNT ((state->Cpsr & TBIT) != 0); 239 ASSIGNT ((state->Cpsr & TBIT) != 0);
239 //state->Cpsr &= ~TBIT; 240 //state->Cpsr &= ~TBIT;
240#endif 241#endif
241 242
242 if (oldmode > SVC26MODE) { 243 if (oldmode > SVC26MODE) {
243 if (state->Mode <= SVC26MODE) { 244 if (state->Mode <= SVC26MODE) {
244 state->Emulate = CHANGEMODE; 245 state->Emulate = CHANGEMODE;
245 state->Reg[15] = ECC | ER15INT | EMODE | R15PC; 246 state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
246 } 247 }
247 } 248 } else {
248 else { 249 if (state->Mode > SVC26MODE) {
249 if (state->Mode > SVC26MODE) { 250 state->Emulate = CHANGEMODE;
250 state->Emulate = CHANGEMODE; 251 state->Reg[15] = R15PC;
251 state->Reg[15] = R15PC; 252 } else
252 } 253 state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
253 else 254 }
254 state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
255 }
256} 255}
257 256
258/* This routine updates the state of the emulator after register 15 has 257/* This routine updates the state of the emulator after register 15 has
@@ -262,20 +261,20 @@ ARMul_CPSRAltered (ARMul_State * state)
262void 261void
263ARMul_R15Altered (ARMul_State * state) 262ARMul_R15Altered (ARMul_State * state)
264{ 263{
265 if (state->Mode != R15MODE) { 264 if (state->Mode != R15MODE) {
266 state->Mode = ARMul_SwitchMode (state, state->Mode, R15MODE); 265 state->Mode = ARMul_SwitchMode (state, state->Mode, R15MODE);
267 state->NtransSig = (state->Mode & 3) ? HIGH : LOW; 266 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
268 } 267 }
269 268
270 if (state->Mode > SVC26MODE) 269 if (state->Mode > SVC26MODE)
271 state->Emulate = CHANGEMODE; 270 state->Emulate = CHANGEMODE;
272 271
273 ASSIGNR15INT (R15INT); 272 ASSIGNR15INT (R15INT);
274 273
275 ASSIGNN ((state->Reg[15] & NBIT) != 0); 274 ASSIGNN ((state->Reg[15] & NBIT) != 0);
276 ASSIGNZ ((state->Reg[15] & ZBIT) != 0); 275 ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
277 ASSIGNC ((state->Reg[15] & CBIT) != 0); 276 ASSIGNC ((state->Reg[15] & CBIT) != 0);
278 ASSIGNV ((state->Reg[15] & VBIT) != 0); 277 ASSIGNV ((state->Reg[15] & VBIT) != 0);
279} 278}
280 279
281/* This routine controls the saving and restoring of registers across mode 280/* This routine controls the saving and restoring of registers across mode
@@ -287,78 +286,78 @@ ARMul_R15Altered (ARMul_State * state)
287ARMword 286ARMword
288ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode) 287ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
289{ 288{
290 unsigned i; 289 unsigned i;
291 ARMword oldbank; 290 ARMword oldbank;
292 ARMword newbank; 291 ARMword newbank;
293 static int revision_value = 53; 292 static int revision_value = 53;
294 293
295 oldbank = ModeToBank (oldmode); 294 oldbank = ModeToBank (oldmode);
296 newbank = state->Bank = ModeToBank (newmode); 295 newbank = state->Bank = ModeToBank (newmode);
297 296
298 /* Do we really need to do it? */ 297 /* Do we really need to do it? */
299 if (oldbank != newbank) { 298 if (oldbank != newbank) {
300 if (oldbank == 3 && newbank == 2) { 299 if (oldbank == 3 && newbank == 2) {
301 //printf("icounter is %d PC is %x MODE CHANGED : %d --> %d\n", state->NumInstrs, state->pc, oldbank, newbank); 300 //printf("icounter is %d PC is %x MODE CHANGED : %d --> %d\n", state->NumInstrs, state->pc, oldbank, newbank);
302 if (state->NumInstrs >= 5832487) { 301 if (state->NumInstrs >= 5832487) {
303// printf("%d, ", state->NumInstrs + revision_value); 302// printf("%d, ", state->NumInstrs + revision_value);
304// printf("revision_value : %d\n", revision_value); 303// printf("revision_value : %d\n", revision_value);
305 revision_value ++; 304 revision_value ++;
306 } 305 }
307 } 306 }
308 /* Save away the old registers. */ 307 /* Save away the old registers. */
309 switch (oldbank) { 308 switch (oldbank) {
310 case USERBANK: 309 case USERBANK:
311 case IRQBANK: 310 case IRQBANK:
312 case SVCBANK: 311 case SVCBANK:
313 case ABORTBANK: 312 case ABORTBANK:
314 case UNDEFBANK: 313 case UNDEFBANK:
315 if (newbank == FIQBANK) 314 if (newbank == FIQBANK)
316 for (i = 8; i < 13; i++) 315 for (i = 8; i < 13; i++)
317 state->RegBank[USERBANK][i] = 316 state->RegBank[USERBANK][i] =
318 state->Reg[i]; 317 state->Reg[i];
319 state->RegBank[oldbank][13] = state->Reg[13]; 318 state->RegBank[oldbank][13] = state->Reg[13];
320 state->RegBank[oldbank][14] = state->Reg[14]; 319 state->RegBank[oldbank][14] = state->Reg[14];
321 break; 320 break;
322 case FIQBANK: 321 case FIQBANK:
323 for (i = 8; i < 15; i++) 322 for (i = 8; i < 15; i++)
324 state->RegBank[FIQBANK][i] = state->Reg[i]; 323 state->RegBank[FIQBANK][i] = state->Reg[i];
325 break; 324 break;
326 case DUMMYBANK: 325 case DUMMYBANK:
327 for (i = 8; i < 15; i++) 326 for (i = 8; i < 15; i++)
328 state->RegBank[DUMMYBANK][i] = 0; 327 state->RegBank[DUMMYBANK][i] = 0;
329 break; 328 break;
330 default: 329 default:
331 abort (); 330 abort ();
332 } 331 }
333 332
334 /* Restore the new registers. */ 333 /* Restore the new registers. */
335 switch (newbank) { 334 switch (newbank) {
336 case USERBANK: 335 case USERBANK:
337 case IRQBANK: 336 case IRQBANK:
338 case SVCBANK: 337 case SVCBANK:
339 case ABORTBANK: 338 case ABORTBANK:
340 case UNDEFBANK: 339 case UNDEFBANK:
341 if (oldbank == FIQBANK) 340 if (oldbank == FIQBANK)
342 for (i = 8; i < 13; i++) 341 for (i = 8; i < 13; i++)
343 state->Reg[i] = 342 state->Reg[i] =
344 state->RegBank[USERBANK][i]; 343 state->RegBank[USERBANK][i];
345 state->Reg[13] = state->RegBank[newbank][13]; 344 state->Reg[13] = state->RegBank[newbank][13];
346 state->Reg[14] = state->RegBank[newbank][14]; 345 state->Reg[14] = state->RegBank[newbank][14];
347 break; 346 break;
348 case FIQBANK: 347 case FIQBANK:
349 for (i = 8; i < 15; i++) 348 for (i = 8; i < 15; i++)
350 state->Reg[i] = state->RegBank[FIQBANK][i]; 349 state->Reg[i] = state->RegBank[FIQBANK][i];
351 break; 350 break;
352 case DUMMYBANK: 351 case DUMMYBANK:
353 for (i = 8; i < 15; i++) 352 for (i = 8; i < 15; i++)
354 state->Reg[i] = 0; 353 state->Reg[i] = 0;
355 break; 354 break;
356 default: 355 default:
357 abort (); 356 abort ();
358 } 357 }
359 } 358 }
360 359
361 return newmode; 360 return newmode;
362} 361}
363 362
364/* Given a processor mode, this routine returns the 363/* Given a processor mode, this routine returns the
@@ -367,21 +366,21 @@ ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
367static ARMword 366static ARMword
368ModeToBank (ARMword mode) 367ModeToBank (ARMword mode)
369{ 368{
370 static ARMword bankofmode[] = { 369 static ARMword bankofmode[] = {
371 USERBANK, FIQBANK, IRQBANK, SVCBANK, 370 USERBANK, FIQBANK, IRQBANK, SVCBANK,
372 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK, 371 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
373 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK, 372 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
374 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK, 373 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
375 USERBANK, FIQBANK, IRQBANK, SVCBANK, 374 USERBANK, FIQBANK, IRQBANK, SVCBANK,
376 DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK, 375 DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK,
377 DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK, 376 DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK,
378 DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK 377 DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK
379 }; 378 };
380 379
381 if (mode >= (sizeof (bankofmode) / sizeof (bankofmode[0]))) 380 if (mode >= (sizeof (bankofmode) / sizeof (bankofmode[0])))
382 return DUMMYBANK; 381 return DUMMYBANK;
383 382
384 return bankofmode[mode]; 383 return bankofmode[mode];
385} 384}
386 385
387/* Returns the register number of the nth register in a reg list. */ 386/* Returns the register number of the nth register in a reg list. */
@@ -389,13 +388,13 @@ ModeToBank (ARMword mode)
389unsigned 388unsigned
390ARMul_NthReg (ARMword instr, unsigned number) 389ARMul_NthReg (ARMword instr, unsigned number)
391{ 390{
392 unsigned bit, upto; 391 unsigned bit, upto;
393 392
394 for (bit = 0, upto = 0; upto <= number; bit++) 393 for (bit = 0, upto = 0; upto <= number; bit++)
395 if (BIT (bit)) 394 if (BIT (bit))
396 upto++; 395 upto++;
397 396
398 return (bit - 1); 397 return (bit - 1);
399} 398}
400 399
401/* Assigns the N and Z flags depending on the value of result. */ 400/* Assigns the N and Z flags depending on the value of result. */
@@ -403,18 +402,16 @@ ARMul_NthReg (ARMword instr, unsigned number)
403void 402void
404ARMul_NegZero (ARMul_State * state, ARMword result) 403ARMul_NegZero (ARMul_State * state, ARMword result)
405{ 404{
406 if (NEG (result)) { 405 if (NEG (result)) {
407 SETN; 406 SETN;
408 CLEARZ; 407 CLEARZ;
409 } 408 } else if (result == 0) {
410 else if (result == 0) { 409 CLEARN;
411 CLEARN; 410 SETZ;
412 SETZ; 411 } else {
413 } 412 CLEARN;
414 else { 413 CLEARZ;
415 CLEARN; 414 }
416 CLEARZ;
417 }
418} 415}
419 416
420/* Compute whether an addition of A and B, giving RESULT, overflowed. */ 417/* Compute whether an addition of A and B, giving RESULT, overflowed. */
@@ -422,8 +419,8 @@ ARMul_NegZero (ARMul_State * state, ARMword result)
422int 419int
423AddOverflow (ARMword a, ARMword b, ARMword result) 420AddOverflow (ARMword a, ARMword b, ARMword result)
424{ 421{
425 return ((NEG (a) && NEG (b) && POS (result)) 422 return ((NEG (a) && NEG (b) && POS (result))
426 || (POS (a) && POS (b) && NEG (result))); 423 || (POS (a) && POS (b) && NEG (result)));
427} 424}
428 425
429/* Compute whether a subtraction of A and B, giving RESULT, overflowed. */ 426/* Compute whether a subtraction of A and B, giving RESULT, overflowed. */
@@ -431,8 +428,8 @@ AddOverflow (ARMword a, ARMword b, ARMword result)
431int 428int
432SubOverflow (ARMword a, ARMword b, ARMword result) 429SubOverflow (ARMword a, ARMword b, ARMword result)
433{ 430{
434 return ((NEG (a) && POS (b) && POS (result)) 431 return ((NEG (a) && POS (b) && POS (result))
435 || (POS (a) && NEG (b) && NEG (result))); 432 || (POS (a) && NEG (b) && NEG (result)));
436} 433}
437 434
438/* Assigns the C flag after an addition of a and b to give result. */ 435/* Assigns the C flag after an addition of a and b to give result. */
@@ -440,8 +437,8 @@ SubOverflow (ARMword a, ARMword b, ARMword result)
440void 437void
441ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result) 438ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
442{ 439{
443 ASSIGNC ((NEG (a) && NEG (b)) || 440 ASSIGNC ((NEG (a) && NEG (b)) ||
444 (NEG (a) && POS (result)) || (NEG (b) && POS (result))); 441 (NEG (a) && POS (result)) || (NEG (b) && POS (result)));
445} 442}
446 443
447/* Assigns the V flag after an addition of a and b to give result. */ 444/* Assigns the V flag after an addition of a and b to give result. */
@@ -449,7 +446,7 @@ ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
449void 446void
450ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result) 447ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
451{ 448{
452 ASSIGNV (AddOverflow (a, b, result)); 449 ASSIGNV (AddOverflow (a, b, result));
453} 450}
454 451
455/* Assigns the C flag after an subtraction of a and b to give result. */ 452/* Assigns the C flag after an subtraction of a and b to give result. */
@@ -457,8 +454,8 @@ ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
457void 454void
458ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result) 455ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
459{ 456{
460 ASSIGNC ((NEG (a) && POS (b)) || 457 ASSIGNC ((NEG (a) && POS (b)) ||
461 (NEG (a) && POS (result)) || (POS (b) && POS (result))); 458 (NEG (a) && POS (result)) || (POS (b) && POS (result)));
462} 459}
463 460
464/* Assigns the V flag after an subtraction of a and b to give result. */ 461/* Assigns the V flag after an subtraction of a and b to give result. */
@@ -466,7 +463,7 @@ ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
466void 463void
467ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result) 464ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
468{ 465{
469 ASSIGNV (SubOverflow (a, b, result)); 466 ASSIGNV (SubOverflow (a, b, result));
470} 467}
471 468
472/* This function does the work of generating the addresses used in an 469/* This function does the work of generating the addresses used in an
@@ -477,88 +474,88 @@ ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
477void 474void
478ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address) 475ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address)
479{ 476{
480 unsigned cpab; 477 unsigned cpab;
481 ARMword data; 478 ARMword data;
482 479
483 UNDEF_LSCPCBaseWb; 480 UNDEF_LSCPCBaseWb;
484 //printf("SKYEYE ARMul_LDC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address); 481 //printf("SKYEYE ARMul_LDC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address);
485/*chy 2004-05-23 should update this function in the future,should concern dataabort*/ 482 /*chy 2004-05-23 should update this function in the future,should concern dataabort*/
486// chy 2004-05-25 , fix it now,so needn't printf 483// chy 2004-05-25 , fix it now,so needn't printf
487// printf("SKYEYE ARMul_LDC, should update this function!!!!!\n"); 484// printf("SKYEYE ARMul_LDC, should update this function!!!!!\n");
488 //exit(-1); 485 //exit(-1);
489 486
490 if (!CP_ACCESS_ALLOWED (state, CPNum)) { 487 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
491 /* 488 if (!state->LDC[CPNum]) {
492 printf 489 /*
493 ("SKYEYE ARMul_LDC,NOT ALLOW, underinstr, CPnum is %x, instr %x, addr %x\n", 490 printf
494 CPNum, instr, address); 491 ("SKYEYE ARMul_LDC,NOT ALLOW, underinstr, CPnum is %x, instr %x, addr %x\n",
495 */ 492 CPNum, instr, address);
496 ARMul_UndefInstr (state, instr); 493 */
497 return; 494 ARMul_UndefInstr (state, instr);
498 } 495 return;
499 496 }
500 //if (ADDREXCEPT (address)) 497
501 // INTERNALABORT (address); 498 /*if (ADDREXCEPT (address))
502 499 INTERNALABORT (address);*/
503 cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0); 500
504 while (cpab == ARMul_BUSY) { 501 cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0);
505 ARMul_Icycles (state, 1, 0); 502 while (cpab == ARMul_BUSY) {
506 503 ARMul_Icycles (state, 1, 0);
507 if (IntPending (state)) { 504
508 cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT, 505 if (IntPending (state)) {
509 instr, 0); 506 cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT,
510 return; 507 instr, 0);
511 } 508 return;
512 else 509 } else
513 cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr, 510 cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr,
514 0); 511 0);
515 } 512 }
516 if (cpab == ARMul_CANT) { 513 if (cpab == ARMul_CANT) {
517 /* 514 /*
518 printf 515 printf
519 ("SKYEYE ARMul_LDC,NOT CAN, underinstr, CPnum is %x, instr %x, addr %x\n", 516 ("SKYEYE ARMul_LDC,NOT CAN, underinstr, CPnum is %x, instr %x, addr %x\n",
520 CPNum, instr, address); 517 CPNum, instr, address);
521 */ 518 */
522 CPTAKEABORT; 519 CPTAKEABORT;
523 return; 520 return;
524 } 521 }
525 522
526 cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0); 523 cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0);
527 data = ARMul_LoadWordN (state, address); 524 data = ARMul_LoadWordN (state, address);
528 //chy 2004-05-25 525 //chy 2004-05-25
529 if (state->abortSig || state->Aborted) 526 if (state->abortSig || state->Aborted)
530 goto L_ldc_takeabort; 527 goto L_ldc_takeabort;
531 528
532 BUSUSEDINCPCN; 529 BUSUSEDINCPCN;
533//chy 2004-05-25 530//chy 2004-05-25
534/* 531 /*
535 if (BIT (21)) 532 if (BIT (21))
536 LSBase = state->Base; 533 LSBase = state->Base;
537*/ 534 */
538 535
539 cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data); 536 cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
540 537
541 while (cpab == ARMul_INC) { 538 while (cpab == ARMul_INC) {
542 address += 4; 539 address += 4;
543 data = ARMul_LoadWordN (state, address); 540 data = ARMul_LoadWordN (state, address);
544 //chy 2004-05-25 541 //chy 2004-05-25
545 if (state->abortSig || state->Aborted) 542 if (state->abortSig || state->Aborted)
546 goto L_ldc_takeabort; 543 goto L_ldc_takeabort;
547 544
548 cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data); 545 cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
549 } 546 }
550 547
551//chy 2004-05-25 548//chy 2004-05-25
552 L_ldc_takeabort: 549L_ldc_takeabort:
553 if (BIT (21)) { 550 if (BIT (21)) {
554 if (! 551 if (!
555 ((state->abortSig || state->Aborted) 552 ((state->abortSig || state->Aborted)
556 && state->lateabtSig == LOW)) 553 && state->lateabtSig == LOW))
557 LSBase = state->Base; 554 LSBase = state->Base;
558 } 555 }
559 556
560 if (state->abortSig || state->Aborted) 557 if (state->abortSig || state->Aborted)
561 TAKEABORT; 558 TAKEABORT;
562} 559}
563 560
564/* This function does the work of generating the addresses used in an 561/* This function does the work of generating the addresses used in an
@@ -569,88 +566,88 @@ ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address)
569void 566void
570ARMul_STC (ARMul_State * state, ARMword instr, ARMword address) 567ARMul_STC (ARMul_State * state, ARMword instr, ARMword address)
571{ 568{
572 unsigned cpab; 569 unsigned cpab;
573 ARMword data; 570 ARMword data;
574 571
575 UNDEF_LSCPCBaseWb; 572 UNDEF_LSCPCBaseWb;
576 573
577 //printf("SKYEYE ARMul_STC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address); 574 //printf("SKYEYE ARMul_STC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address);
578 /*chy 2004-05-23 should update this function in the future,should concern dataabort */ 575 /*chy 2004-05-23 should update this function in the future,should concern dataabort */
579// skyeye_instr_debug=0;printf("SKYEYE debug end!!!!\n"); 576// skyeye_instr_debug=0;printf("SKYEYE debug end!!!!\n");
580// chy 2004-05-25 , fix it now,so needn't printf 577// chy 2004-05-25 , fix it now,so needn't printf
581// printf("SKYEYE ARMul_STC, should update this function!!!!!\n"); 578// printf("SKYEYE ARMul_STC, should update this function!!!!!\n");
582 579
583 //exit(-1); 580 //exit(-1);
584 if (!CP_ACCESS_ALLOWED (state, CPNum)) { 581 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
585 /* 582 if (!state->STC[CPNum]) {
586 printf 583 /*
587 ("SKYEYE ARMul_STC,NOT ALLOW, undefinstr, CPnum is %x, instr %x, addr %x\n", 584 printf
588 CPNum, instr, address); 585 ("SKYEYE ARMul_STC,NOT ALLOW, undefinstr, CPnum is %x, instr %x, addr %x\n",
589 */ 586 CPNum, instr, address);
590 ARMul_UndefInstr (state, instr); 587 */
591 return; 588 ARMul_UndefInstr (state, instr);
592 } 589 return;
593 590 }
594 //if (ADDREXCEPT (address) || VECTORACCESS (address)) 591
595 // INTERNALABORT (address); 592 /*if (ADDREXCEPT (address) || VECTORACCESS (address))
596 593 INTERNALABORT (address);*/
597 cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data); 594
598 while (cpab == ARMul_BUSY) { 595 cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data);
599 ARMul_Icycles (state, 1, 0); 596 while (cpab == ARMul_BUSY) {
600 if (IntPending (state)) { 597 ARMul_Icycles (state, 1, 0);
601 cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT, 598 if (IntPending (state)) {
602 instr, 0); 599 cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT,
603 return; 600 instr, 0);
604 } 601 return;
605 else 602 } else
606 cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr, 603 cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr,
607 &data); 604 &data);
608 } 605 }
609 606
610 if (cpab == ARMul_CANT) { 607 if (cpab == ARMul_CANT) {
611 /* 608 /*
612 printf 609 printf
613 ("SKYEYE ARMul_STC,CANT, undefinstr, CPnum is %x, instr %x, addr %x\n", 610 ("SKYEYE ARMul_STC,CANT, undefinstr, CPnum is %x, instr %x, addr %x\n",
614 CPNum, instr, address); 611 CPNum, instr, address);
615 */ 612 */
616 CPTAKEABORT; 613 CPTAKEABORT;
617 return; 614 return;
618 } 615 }
619#ifndef MODE32 616 /*#ifndef MODE32
620 if (ADDREXCEPT (address) || VECTORACCESS (address)) 617 if (ADDREXCEPT (address) || VECTORACCESS (address))
621 INTERNALABORT (address); 618 INTERNALABORT (address);
622#endif 619 #endif*/
623 BUSUSEDINCPCN; 620 BUSUSEDINCPCN;
624//chy 2004-05-25 621//chy 2004-05-25
625/* 622 /*
626 if (BIT (21)) 623 if (BIT (21))
627 LSBase = state->Base; 624 LSBase = state->Base;
628*/ 625 */
629 cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data); 626 cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
630 ARMul_StoreWordN (state, address, data); 627 ARMul_StoreWordN (state, address, data);
631 //chy 2004-05-25 628 //chy 2004-05-25
632 if (state->abortSig || state->Aborted) 629 if (state->abortSig || state->Aborted)
633 goto L_stc_takeabort; 630 goto L_stc_takeabort;
634 631
635 while (cpab == ARMul_INC) { 632 while (cpab == ARMul_INC) {
636 address += 4; 633 address += 4;
637 cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data); 634 cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
638 ARMul_StoreWordN (state, address, data); 635 ARMul_StoreWordN (state, address, data);
639 //chy 2004-05-25 636 //chy 2004-05-25
640 if (state->abortSig || state->Aborted) 637 if (state->abortSig || state->Aborted)
641 goto L_stc_takeabort; 638 goto L_stc_takeabort;
642 } 639 }
643//chy 2004-05-25 640//chy 2004-05-25
644 L_stc_takeabort: 641L_stc_takeabort:
645 if (BIT (21)) { 642 if (BIT (21)) {
646 if (! 643 if (!
647 ((state->abortSig || state->Aborted) 644 ((state->abortSig || state->Aborted)
648 && state->lateabtSig == LOW)) 645 && state->lateabtSig == LOW))
649 LSBase = state->Base; 646 LSBase = state->Base;
650 } 647 }
651 648
652 if (state->abortSig || state->Aborted) 649 if (state->abortSig || state->Aborted)
653 TAKEABORT; 650 TAKEABORT;
654} 651}
655 652
656/* This function does the Busy-Waiting for an MCR instruction. */ 653/* This function does the Busy-Waiting for an MCR instruction. */
@@ -658,39 +655,53 @@ ARMul_STC (ARMul_State * state, ARMword instr, ARMword address)
658void 655void
659ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source) 656ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
660{ 657{
661 unsigned cpab; 658 unsigned cpab;
662 659 int cm = BITS(0, 3) & 0xf;
663 //printf("SKYEYE ARMul_MCR, CPnum is %x, source %x\n",CPNum, source); 660 int cp = BITS(5, 7) & 0x7;
664 if (!CP_ACCESS_ALLOWED (state, CPNum)) { 661 int rd = BITS(12, 15) & 0xf;
665 //chy 2004-07-19 should fix in the future ????!!!! 662 int cn = BITS(16, 19) & 0xf;
666 //printf("SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x\n",CPNum, source); 663 int cpopc = BITS(21, 23) & 0x7;
667 ARMul_UndefInstr (state, instr); 664
668 return; 665 if (CPNum == 15 && source == 0) //Cache flush
669 } 666 {
670 667 return;
671 cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source); 668 }
672 669
673 while (cpab == ARMul_BUSY) { 670 //printf("SKYEYE ARMul_MCR, CPnum is %x, source %x\n",CPNum, source);
674 ARMul_Icycles (state, 1, 0); 671 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
675 672 if (!state->MCR[CPNum]) {
676 if (IntPending (state)) { 673 //chy 2004-07-19 should fix in the future ????!!!!
677 cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT, 674 DEBUG("SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x\n",CPNum, source);
678 instr, 0); 675 ARMul_UndefInstr (state, instr);
679 return; 676 return;
680 } 677 }
681 else 678
682 cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr, 679 //DEBUG("SKYEYE ARMul_MCR p%d, %d, r%d, c%d, c%d, %d\n", CPNum, cpopc, rd, cn, cm, cp);
683 source); 680 //DEBUG("plutoo: MCR not implemented\n");
684 } 681 //exit(1);
685 682 //return;
686 if (cpab == ARMul_CANT) { 683
687 printf ("SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x\n", instr, CPNum, source); 684 cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source);
688 ARMul_Abort (state, ARMul_UndefinedInstrV); 685
689 } 686 while (cpab == ARMul_BUSY) {
690 else { 687 ARMul_Icycles (state, 1, 0);
691 BUSUSEDINCPCN; 688
692 ARMul_Ccycles (state, 1, 0); 689 if (IntPending (state)) {
693 } 690 cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT,
691 instr, 0);
692 return;
693 } else
694 cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr,
695 source);
696 }
697
698 if (cpab == ARMul_CANT) {
699 DEBUG("SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x\n", instr, CPNum, source); //ichfly todo
700 //ARMul_Abort (state, ARMul_UndefinedInstrV);
701 } else {
702 BUSUSEDINCPCN;
703 ARMul_Ccycles (state, 1, 0);
704 }
694} 705}
695 706
696/* This function does the Busy-Waiting for an MCRR instruction. */ 707/* This function does the Busy-Waiting for an MCRR instruction. */
@@ -698,83 +709,93 @@ ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
698void 709void
699ARMul_MCRR (ARMul_State * state, ARMword instr, ARMword source1, ARMword source2) 710ARMul_MCRR (ARMul_State * state, ARMword instr, ARMword source1, ARMword source2)
700{ 711{
701 unsigned cpab; 712 unsigned cpab;
702 713
703 if (!CP_ACCESS_ALLOWED (state, CPNum)) { 714 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
704 ARMul_UndefInstr (state, instr); 715 if (!state->MCRR[CPNum]) {
705 return; 716 ARMul_UndefInstr (state, instr);
706 } 717 return;
718 }
707 719
708 cpab = (state->MCRR[CPNum]) (state, ARMul_FIRST, instr, source1, source2); 720 cpab = (state->MCRR[CPNum]) (state, ARMul_FIRST, instr, source1, source2);
709 721
710 while (cpab == ARMul_BUSY) { 722 while (cpab == ARMul_BUSY) {
711 ARMul_Icycles (state, 1, 0); 723 ARMul_Icycles (state, 1, 0);
712 724
713 if (IntPending (state)) { 725 if (IntPending (state)) {
714 cpab = (state->MCRR[CPNum]) (state, ARMul_INTERRUPT, 726 cpab = (state->MCRR[CPNum]) (state, ARMul_INTERRUPT,
715 instr, 0, 0); 727 instr, 0, 0);
716 return; 728 return;
717 } 729 } else
718 else 730 cpab = (state->MCRR[CPNum]) (state, ARMul_BUSY, instr,
719 cpab = (state->MCRR[CPNum]) (state, ARMul_BUSY, instr, 731 source1, source2);
720 source1, source2); 732 }
721 } 733 if (cpab == ARMul_CANT) {
722 if (cpab == ARMul_CANT) { 734 printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x, source %x %x\n", __FUNCTION__, CPNum, instr, source1, source2);
723 printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x, source %x %x\n", __FUNCTION__, CPNum, instr, source1, source2); 735 ARMul_Abort (state, ARMul_UndefinedInstrV);
724 ARMul_Abort (state, ARMul_UndefinedInstrV); 736 } else {
725 } 737 BUSUSEDINCPCN;
726 else { 738 ARMul_Ccycles (state, 1, 0);
727 BUSUSEDINCPCN; 739 }
728 ARMul_Ccycles (state, 1, 0);
729 }
730} 740}
731 741
732/* This function does the Busy-Waiting for an MRC instruction. */ 742/* This function does the Busy-Waiting for an MRC instruction. */
733 743
734ARMword 744ARMword ARMul_MRC (ARMul_State * state, ARMword instr)
735ARMul_MRC (ARMul_State * state, ARMword instr)
736{ 745{
737 unsigned cpab; 746 int cm = BITS(0, 3) & 0xf;
747 int cp = BITS(5, 7) & 0x7;
748 int rd = BITS(12, 15) & 0xf;
749 int cn = BITS(16, 19) & 0xf;
750 int cpopc = BITS(21, 23) & 0x7;
738 751
752 if (cn == 13 && cm == 0 && cp == 3) { //c13,c0,3; returns CPU svc buffer
739 ARMword result = HLE::CallMRC(instr); 753 ARMword result = HLE::CallMRC(instr);
740 754
741 if (result != -1) { 755 if (result != -1) {
742 return result; 756 return result;
743 } 757 }
744 758 }
745 //printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr); 759
746 if (!CP_ACCESS_ALLOWED (state, CPNum)) { 760 //DEBUG("SKYEYE ARMul_MRC p%d, %d, r%d, c%d, c%d, %d\n", CPNum, cpopc, rd, cn, cm, cp);
747 //chy 2004-07-19 should fix in the future????!!!! 761 //DEBUG("plutoo: MRC not implemented\n");
748 //printf("SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x\n",CPNum, instr); 762 //return;
749 ARMul_UndefInstr (state, instr); 763
750 return -1; 764 unsigned cpab;
751 } 765 ARMword result = 0;
752 766
753 cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result); 767 //printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr);
754 while (cpab == ARMul_BUSY) { 768 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
755 ARMul_Icycles (state, 1, 0); 769 if (!state->MRC[CPNum]) {
756 if (IntPending (state)) { 770 //chy 2004-07-19 should fix in the future????!!!!
757 cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT, 771 DEBUG("SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x\n", CPNum, instr);
758 instr, 0); 772 ARMul_UndefInstr (state, instr);
759 return (0); 773 return -1;
760 } 774 }
761 else 775
762 cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr, 776 cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);
763 &result); 777 while (cpab == ARMul_BUSY) {
764 } 778 ARMul_Icycles (state, 1, 0);
765 if (cpab == ARMul_CANT) { 779 if (IntPending (state)) {
766 printf ("SKYEYE ARMul_MRC,CANT UndefInstr CPnum is %x, instr %x\n", CPNum, instr); 780 cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT,
767 ARMul_Abort (state, ARMul_UndefinedInstrV); 781 instr, 0);
768 /* Parent will destroy the flags otherwise. */ 782 return (0);
769 result = ECC; 783 } else
770 } 784 cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr,
771 else { 785 &result);
772 BUSUSEDINCPCN; 786 }
773 ARMul_Ccycles (state, 1, 0); 787 if (cpab == ARMul_CANT) {
774 ARMul_Icycles (state, 1, 0); 788 printf ("SKYEYE ARMul_MRC,CANT UndefInstr CPnum is %x, instr %x\n", CPNum, instr);
775 } 789 ARMul_Abort (state, ARMul_UndefinedInstrV);
776 790 /* Parent will destroy the flags otherwise. */
777 return result; 791 result = ECC;
792 } else {
793 BUSUSEDINCPCN;
794 ARMul_Ccycles (state, 1, 0);
795 ARMul_Icycles (state, 1, 0);
796 }
797
798 return result;
778} 799}
779 800
780/* This function does the Busy-Waiting for an MRRC instruction. (to verify) */ 801/* This function does the Busy-Waiting for an MRRC instruction. (to verify) */
@@ -782,39 +803,38 @@ ARMul_MRC (ARMul_State * state, ARMword instr)
782void 803void
783ARMul_MRRC (ARMul_State * state, ARMword instr, ARMword * dest1, ARMword * dest2) 804ARMul_MRRC (ARMul_State * state, ARMword instr, ARMword * dest1, ARMword * dest2)
784{ 805{
785 unsigned cpab; 806 unsigned cpab;
786 ARMword result1 = 0; 807 ARMword result1 = 0;
787 ARMword result2 = 0; 808 ARMword result2 = 0;
788 809
789 if (!CP_ACCESS_ALLOWED (state, CPNum)) { 810 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
790 ARMul_UndefInstr (state, instr); 811 if (!state->MRRC[CPNum]) {
791 return; 812 ARMul_UndefInstr (state, instr);
792 } 813 return;
793 814 }
794 cpab = (state->MRRC[CPNum]) (state, ARMul_FIRST, instr, &result1, &result2); 815
795 while (cpab == ARMul_BUSY) { 816 cpab = (state->MRRC[CPNum]) (state, ARMul_FIRST, instr, &result1, &result2);
796 ARMul_Icycles (state, 1, 0); 817 while (cpab == ARMul_BUSY) {
797 if (IntPending (state)) { 818 ARMul_Icycles (state, 1, 0);
798 cpab = (state->MRRC[CPNum]) (state, ARMul_INTERRUPT, 819 if (IntPending (state)) {
799 instr, 0, 0); 820 cpab = (state->MRRC[CPNum]) (state, ARMul_INTERRUPT,
800 return; 821 instr, 0, 0);
801 } 822 return;
802 else 823 } else
803 cpab = (state->MRRC[CPNum]) (state, ARMul_BUSY, instr, 824 cpab = (state->MRRC[CPNum]) (state, ARMul_BUSY, instr,
804 &result1, &result2); 825 &result1, &result2);
805 } 826 }
806 if (cpab == ARMul_CANT) { 827 if (cpab == ARMul_CANT) {
807 printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x\n", __FUNCTION__, CPNum, instr); 828 printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x\n", __FUNCTION__, CPNum, instr);
808 ARMul_Abort (state, ARMul_UndefinedInstrV); 829 ARMul_Abort (state, ARMul_UndefinedInstrV);
809 } 830 } else {
810 else { 831 BUSUSEDINCPCN;
811 BUSUSEDINCPCN; 832 ARMul_Ccycles (state, 1, 0);
812 ARMul_Ccycles (state, 1, 0); 833 ARMul_Icycles (state, 1, 0);
813 ARMul_Icycles (state, 1, 0); 834 }
814 } 835
815 836 *dest1 = result1;
816 *dest1 = result1; 837 *dest2 = result2;
817 *dest2 = result2;
818} 838}
819 839
820/* This function does the Busy-Waiting for an CDP instruction. */ 840/* This function does the Busy-Waiting for an CDP instruction. */
@@ -822,27 +842,27 @@ ARMul_MRRC (ARMul_State * state, ARMword instr, ARMword * dest1, ARMword * dest2
822void 842void
823ARMul_CDP (ARMul_State * state, ARMword instr) 843ARMul_CDP (ARMul_State * state, ARMword instr)
824{ 844{
825 unsigned cpab; 845 unsigned cpab;
826 846
827 if (!CP_ACCESS_ALLOWED (state, CPNum)) { 847 //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
828 ARMul_UndefInstr (state, instr); 848 if (!state->CDP[CPNum]) {
829 return; 849 ARMul_UndefInstr (state, instr);
830 } 850 return;
831 cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr); 851 }
832 while (cpab == ARMul_BUSY) { 852 cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr);
833 ARMul_Icycles (state, 1, 0); 853 while (cpab == ARMul_BUSY) {
834 if (IntPending (state)) { 854 ARMul_Icycles (state, 1, 0);
835 cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT, 855 if (IntPending (state)) {
836 instr); 856 cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT,
837 return; 857 instr);
838 } 858 return;
839 else 859 } else
840 cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr); 860 cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr);
841 } 861 }
842 if (cpab == ARMul_CANT) 862 if (cpab == ARMul_CANT)
843 ARMul_Abort (state, ARMul_UndefinedInstrV); 863 ARMul_Abort (state, ARMul_UndefinedInstrV);
844 else 864 else
845 BUSUSEDN; 865 BUSUSEDN;
846} 866}
847 867
848/* This function handles Undefined instructions, as CP isntruction. */ 868/* This function handles Undefined instructions, as CP isntruction. */
@@ -850,11 +870,13 @@ ARMul_CDP (ARMul_State * state, ARMword instr)
850void 870void
851ARMul_UndefInstr (ARMul_State * state, ARMword instr) 871ARMul_UndefInstr (ARMul_State * state, ARMword instr)
852{ 872{
853 char buff[512]; 873 /*SKYEYE_LOG_IN_CLR(RED, "In %s, line = %d, undef instr: 0x%x\n",
854 ARM_Disasm disasm = ARM_Disasm(); 874 __func__, __LINE__, instr);*/
855 disasm.disasm(state->pc, instr, buff); 875 char buff[512];
856 ERROR_LOG(ARM11, "Undefined instruction!! Disasm: %s Opcode: 0x%x", buff, instr); 876 ARM_Disasm disasm = ARM_Disasm();
857 ARMul_Abort (state, ARMul_UndefinedInstrV); 877 disasm.disasm(state->pc, instr, buff);
878 ERROR_LOG(ARM11, "Undefined instruction!! Disasm: %s Opcode: 0x%x", buff, instr);
879 ARMul_Abort (state, ARMul_UndefinedInstrV);
858} 880}
859 881
860/* Return TRUE if an interrupt is pending, FALSE otherwise. */ 882/* Return TRUE if an interrupt is pending, FALSE otherwise. */
@@ -862,33 +884,31 @@ ARMul_UndefInstr (ARMul_State * state, ARMword instr)
862unsigned 884unsigned
863IntPending (ARMul_State * state) 885IntPending (ARMul_State * state)
864{ 886{
865 /* Any exceptions. */ 887 /* Any exceptions. */
866 if (state->NresetSig == LOW) { 888 if (state->NresetSig == LOW) {
867 ARMul_Abort (state, ARMul_ResetV); 889 ARMul_Abort (state, ARMul_ResetV);
868 return TRUE; 890 return TRUE;
869 } 891 } else if (!state->NfiqSig && !FFLAG) {
870 else if (!state->NfiqSig && !FFLAG) { 892 ARMul_Abort (state, ARMul_FIQV);
871 ARMul_Abort (state, ARMul_FIQV); 893 return TRUE;
872 return TRUE; 894 } else if (!state->NirqSig && !IFLAG) {
873 } 895 ARMul_Abort (state, ARMul_IRQV);
874 else if (!state->NirqSig && !IFLAG) { 896 return TRUE;
875 ARMul_Abort (state, ARMul_IRQV); 897 }
876 return TRUE;
877 }
878 898
879 return FALSE; 899 return FALSE;
880} 900}
881 901
882/* Align a word access to a non word boundary. */ 902/* Align a word access to a non word boundary. */
883 903
884ARMword 904ARMword
885ARMul_Align (ARMul_State *state, ARMword address, ARMword data) 905ARMul_Align (ARMul_State* state, ARMword address, ARMword data)
886{ 906{
887 /* This code assumes the address is really unaligned, 907 /* This code assumes the address is really unaligned,
888 as a shift by 32 is undefined in C. */ 908 as a shift by 32 is undefined in C. */
889 909
890 address = (address & 3) << 3; /* Get the word address. */ 910 address = (address & 3) << 3; /* Get the word address. */
891 return ((data >> address) | (data << (32 - address))); /* rot right */ 911 return ((data >> address) | (data << (32 - address))); /* rot right */
892} 912}
893 913
894/* This routine is used to call another routine after a certain number of 914/* This routine is used to call another routine after a certain number of
@@ -898,19 +918,23 @@ ARMul_Align (ARMul_State *state, ARMword address, ARMword data)
898 918
899void 919void
900ARMul_ScheduleEvent (ARMul_State * state, unsigned int delay, 920ARMul_ScheduleEvent (ARMul_State * state, unsigned int delay,
901 unsigned (*what) (ARMul_State *)) 921 unsigned (*what) (ARMul_State *))
902{ 922{
903 unsigned int when; 923 unsigned int when;
904 struct EventNode *event; 924 struct EventNode *event;
905 925
906 if (state->EventSet++ == 0) 926 if (state->EventSet++ == 0)
907 state->Now = ARMul_Time (state); 927 state->Now = ARMul_Time (state);
908 when = (state->Now + delay) % EVENTLISTSIZE; 928 when = (state->Now + delay) % EVENTLISTSIZE;
909 event = (struct EventNode *) malloc (sizeof (struct EventNode)); 929 event = (struct EventNode *) malloc (sizeof (struct EventNode));
910 _dbg_assert_msg_(ARM11, event, "SKYEYE:ARMul_ScheduleEvent: malloc event error\n"); 930 if (!event) {
911 event->func = what; 931 printf ("SKYEYE:ARMul_ScheduleEvent: malloc event error\n");
912 event->next = *(state->EventPtr + when); 932 exit(-1);
913 *(state->EventPtr + when) = event; 933 //skyeye_exit (-1);
934 }
935 event->func = what;
936 event->next = *(state->EventPtr + when);
937 *(state->EventPtr + when) = event;
914} 938}
915 939
916/* This routine is called at the beginning of 940/* This routine is called at the beginning of
@@ -919,18 +943,18 @@ ARMul_ScheduleEvent (ARMul_State * state, unsigned int delay,
919void 943void
920ARMul_EnvokeEvent (ARMul_State * state) 944ARMul_EnvokeEvent (ARMul_State * state)
921{ 945{
922 static unsigned int then; 946 static unsigned int then;
923 947
924 then = state->Now; 948 then = state->Now;
925 state->Now = ARMul_Time (state) % EVENTLISTSIZE; 949 state->Now = ARMul_Time (state) % EVENTLISTSIZE;
926 if (then < state->Now) 950 if (then < state->Now)
927 /* Schedule events. */ 951 /* Schedule events. */
928 EnvokeList (state, then, state->Now); 952 EnvokeList (state, then, state->Now);
929 else if (then > state->Now) { 953 else if (then > state->Now) {
930 /* Need to wrap around the list. */ 954 /* Need to wrap around the list. */
931 EnvokeList (state, then, EVENTLISTSIZE - 1L); 955 EnvokeList (state, then, EVENTLISTSIZE - 1L);
932 EnvokeList (state, 0L, state->Now); 956 EnvokeList (state, 0L, state->Now);
933 } 957 }
934} 958}
935 959
936/* Envokes all the entries in a range. */ 960/* Envokes all the entries in a range. */
@@ -938,17 +962,17 @@ ARMul_EnvokeEvent (ARMul_State * state)
938static void 962static void
939EnvokeList (ARMul_State * state, unsigned int from, unsigned int to) 963EnvokeList (ARMul_State * state, unsigned int from, unsigned int to)
940{ 964{
941 for (; from <= to; from++) { 965 for (; from <= to; from++) {
942 struct EventNode *anevent; 966 struct EventNode *anevent;
943 967
944 anevent = *(state->EventPtr + from); 968 anevent = *(state->EventPtr + from);
945 while (anevent) { 969 while (anevent) {
946 (anevent->func) (state); 970 (anevent->func) (state);
947 state->EventSet--; 971 state->EventSet--;
948 anevent = anevent->next; 972 anevent = anevent->next;
949 } 973 }
950 *(state->EventPtr + from) = NULL; 974 *(state->EventPtr + from) = NULL;
951 } 975 }
952} 976}
953 977
954/* This routine is returns the number of clock ticks since the last reset. */ 978/* This routine is returns the number of clock ticks since the last reset. */
@@ -956,6 +980,6 @@ EnvokeList (ARMul_State * state, unsigned int from, unsigned int to)
956unsigned int 980unsigned int
957ARMul_Time (ARMul_State * state) 981ARMul_Time (ARMul_State * state)
958{ 982{
959 return (state->NumScycles + state->NumNcycles + 983 return (state->NumScycles + state->NumNcycles +
960 state->NumIcycles + state->NumCcycles + state->NumFcycles); 984 state->NumIcycles + state->NumCcycles + state->NumFcycles);
961} 985}