summaryrefslogtreecommitdiff
path: root/src/core/arm/interpreter/armemu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/arm/interpreter/armemu.cpp')
-rw-r--r--src/core/arm/interpreter/armemu.cpp6631
1 files changed, 6631 insertions, 0 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
new file mode 100644
index 000000000..46c51fbe8
--- /dev/null
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -0,0 +1,6631 @@
1/* armemu.c -- Main instruction emulation: ARM7 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3 Modifications to add arch. v4 support by <jsmith@cygnus.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 "arm_regformat.h"
20#include "armdefs.h"
21#include "armemu.h"
22#include "armos.h"
23
24void
25XScale_set_fsr_far(ARMul_State * state, ARMword fsr, ARMword _far)
26{
27 _dbg_assert_msg_(ARM11, false, "ImplementMe: XScale_set_fsr_far!");
28 //if (!state->is_XScale || (read_cp14_reg(10) & (1UL << 31)) == 0)
29 // return;
30 //
31 //write_cp15_reg(state, 5, 0, 0, fsr);
32 //write_cp15_reg(state, 6, 0, 0, _far);
33}
34
35#define ARMul_Debug(x,y,z) 0 // Disabling this /bunnei
36
37//#include "skyeye_callback.h"
38//#include "skyeye_bus.h"
39//#include "sim_control.h"
40//#include "skyeye_pref.h"
41//#include "skyeye.h"
42//#include "skyeye2gdb.h"
43//#include "code_cov.h"
44
45//#include "iwmmxt.h"
46//chy 2003-07-11: for debug instrs
47//extern int skyeye_instr_debug;
48extern FILE *skyeye_logfd;
49
50static ARMword GetDPRegRHS (ARMul_State *, ARMword);
51static ARMword GetDPSRegRHS (ARMul_State *, ARMword);
52static void WriteR15 (ARMul_State *, ARMword);
53static void WriteSR15 (ARMul_State *, ARMword);
54static void WriteR15Branch (ARMul_State *, ARMword);
55static ARMword GetLSRegRHS (ARMul_State *, ARMword);
56static ARMword GetLS7RHS (ARMul_State *, ARMword);
57static unsigned LoadWord (ARMul_State *, ARMword, ARMword);
58static unsigned LoadHalfWord (ARMul_State *, ARMword, ARMword, int);
59static unsigned LoadByte (ARMul_State *, ARMword, ARMword, int);
60static unsigned StoreWord (ARMul_State *, ARMword, ARMword);
61static unsigned StoreHalfWord (ARMul_State *, ARMword, ARMword);
62static unsigned StoreByte (ARMul_State *, ARMword, ARMword);
63static void LoadMult (ARMul_State *, ARMword, ARMword, ARMword);
64static void StoreMult (ARMul_State *, ARMword, ARMword, ARMword);
65static void LoadSMult (ARMul_State *, ARMword, ARMword, ARMword);
66static void StoreSMult (ARMul_State *, ARMword, ARMword, ARMword);
67static unsigned Multiply64 (ARMul_State *, ARMword, int, int);
68static unsigned MultiplyAdd64 (ARMul_State *, ARMword, int, int);
69static void Handle_Load_Double (ARMul_State *, ARMword);
70static void Handle_Store_Double (ARMul_State *, ARMword);
71void
72XScale_set_fsr_far (ARMul_State * state, ARMword fsr, ARMword _far);
73int
74XScale_debug_moe (ARMul_State * state, int moe);
75unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg,
76 unsigned cpnum);
77
78static int
79handle_v6_insn (ARMul_State * state, ARMword instr);
80
81#define LUNSIGNED (0) /* unsigned operation */
82#define LSIGNED (1) /* signed operation */
83#define LDEFAULT (0) /* default : do nothing */
84#define LSCC (1) /* set condition codes on result */
85
86#ifdef NEED_UI_LOOP_HOOK
87/* How often to run the ui_loop update, when in use. */
88#define UI_LOOP_POLL_INTERVAL 0x32000
89
90/* Counter for the ui_loop_hook update. */
91static int ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
92
93/* Actual hook to call to run through gdb's gui event loop. */
94extern int (*ui_loop_hook) (int);
95#endif /* NEED_UI_LOOP_HOOK */
96
97/* Short-hand macros for LDR/STR. */
98
99/* Store post decrement writeback. */
100#define SHDOWNWB() \
101 lhs = LHS ; \
102 if (StoreHalfWord (state, instr, lhs)) \
103 LSBase = lhs - GetLS7RHS (state, instr);
104
105/* Store post increment writeback. */
106#define SHUPWB() \
107 lhs = LHS ; \
108 if (StoreHalfWord (state, instr, lhs)) \
109 LSBase = lhs + GetLS7RHS (state, instr);
110
111/* Store pre decrement. */
112#define SHPREDOWN() \
113 (void)StoreHalfWord (state, instr, LHS - GetLS7RHS (state, instr));
114
115/* Store pre decrement writeback. */
116#define SHPREDOWNWB() \
117 temp = LHS - GetLS7RHS (state, instr); \
118 if (StoreHalfWord (state, instr, temp)) \
119 LSBase = temp;
120
121/* Store pre increment. */
122#define SHPREUP() \
123 (void)StoreHalfWord (state, instr, LHS + GetLS7RHS (state, instr));
124
125/* Store pre increment writeback. */
126#define SHPREUPWB() \
127 temp = LHS + GetLS7RHS (state, instr); \
128 if (StoreHalfWord (state, instr, temp)) \
129 LSBase = temp;
130
131/* Load post decrement writeback. */
132#define LHPOSTDOWN() \
133{ \
134 int done = 1; \
135 lhs = LHS; \
136 temp = lhs - GetLS7RHS (state, instr); \
137 \
138 switch (BITS (5, 6)) \
139 { \
140 case 1: /* H */ \
141 if (LoadHalfWord (state, instr, lhs, LUNSIGNED)) \
142 LSBase = temp; \
143 break; \
144 case 2: /* SB */ \
145 if (LoadByte (state, instr, lhs, LSIGNED)) \
146 LSBase = temp; \
147 break; \
148 case 3: /* SH */ \
149 if (LoadHalfWord (state, instr, lhs, LSIGNED)) \
150 LSBase = temp; \
151 break; \
152 case 0: /* SWP handled elsewhere. */ \
153 default: \
154 done = 0; \
155 break; \
156 } \
157 if (done) \
158 break; \
159}
160
161/* Load post increment writeback. */
162#define LHPOSTUP() \
163{ \
164 int done = 1; \
165 lhs = LHS; \
166 temp = lhs + GetLS7RHS (state, instr); \
167 \
168 switch (BITS (5, 6)) \
169 { \
170 case 1: /* H */ \
171 if (LoadHalfWord (state, instr, lhs, LUNSIGNED)) \
172 LSBase = temp; \
173 break; \
174 case 2: /* SB */ \
175 if (LoadByte (state, instr, lhs, LSIGNED)) \
176 LSBase = temp; \
177 break; \
178 case 3: /* SH */ \
179 if (LoadHalfWord (state, instr, lhs, LSIGNED)) \
180 LSBase = temp; \
181 break; \
182 case 0: /* SWP handled elsewhere. */ \
183 default: \
184 done = 0; \
185 break; \
186 } \
187 if (done) \
188 break; \
189}
190
191/* Load pre decrement. */
192#define LHPREDOWN() \
193{ \
194 int done = 1; \
195 \
196 temp = LHS - GetLS7RHS (state, instr); \
197 switch (BITS (5, 6)) \
198 { \
199 case 1: /* H */ \
200 (void) LoadHalfWord (state, instr, temp, LUNSIGNED); \
201 break; \
202 case 2: /* SB */ \
203 (void) LoadByte (state, instr, temp, LSIGNED); \
204 break; \
205 case 3: /* SH */ \
206 (void) LoadHalfWord (state, instr, temp, LSIGNED); \
207 break; \
208 case 0: \
209 /* SWP handled elsewhere. */ \
210 default: \
211 done = 0; \
212 break; \
213 } \
214 if (done) \
215 break; \
216}
217
218/* Load pre decrement writeback. */
219#define LHPREDOWNWB() \
220{ \
221 int done = 1; \
222 \
223 temp = LHS - GetLS7RHS (state, instr); \
224 switch (BITS (5, 6)) \
225 { \
226 case 1: /* H */ \
227 if (LoadHalfWord (state, instr, temp, LUNSIGNED)) \
228 LSBase = temp; \
229 break; \
230 case 2: /* SB */ \
231 if (LoadByte (state, instr, temp, LSIGNED)) \
232 LSBase = temp; \
233 break; \
234 case 3: /* SH */ \
235 if (LoadHalfWord (state, instr, temp, LSIGNED)) \
236 LSBase = temp; \
237 break; \
238 case 0: \
239 /* SWP handled elsewhere. */ \
240 default: \
241 done = 0; \
242 break; \
243 } \
244 if (done) \
245 break; \
246}
247
248/* Load pre increment. */
249#define LHPREUP() \
250{ \
251 int done = 1; \
252 \
253 temp = LHS + GetLS7RHS (state, instr); \
254 switch (BITS (5, 6)) \
255 { \
256 case 1: /* H */ \
257 (void) LoadHalfWord (state, instr, temp, LUNSIGNED); \
258 break; \
259 case 2: /* SB */ \
260 (void) LoadByte (state, instr, temp, LSIGNED); \
261 break; \
262 case 3: /* SH */ \
263 (void) LoadHalfWord (state, instr, temp, LSIGNED); \
264 break; \
265 case 0: \
266 /* SWP handled elsewhere. */ \
267 default: \
268 done = 0; \
269 break; \
270 } \
271 if (done) \
272 break; \
273}
274
275/* Load pre increment writeback. */
276#define LHPREUPWB() \
277{ \
278 int done = 1; \
279 \
280 temp = LHS + GetLS7RHS (state, instr); \
281 switch (BITS (5, 6)) \
282 { \
283 case 1: /* H */ \
284 if (LoadHalfWord (state, instr, temp, LUNSIGNED)) \
285 LSBase = temp; \
286 break; \
287 case 2: /* SB */ \
288 if (LoadByte (state, instr, temp, LSIGNED)) \
289 LSBase = temp; \
290 break; \
291 case 3: /* SH */ \
292 if (LoadHalfWord (state, instr, temp, LSIGNED)) \
293 LSBase = temp; \
294 break; \
295 case 0: \
296 /* SWP handled elsewhere. */ \
297 default: \
298 done = 0; \
299 break; \
300 } \
301 if (done) \
302 break; \
303}
304
305/*ywc 2005-03-31*/
306//teawater add for arm2x86 2005.02.17-------------------------------------------
307#ifdef DBCT
308#include "dbct/tb.h"
309#include "dbct/arm2x86_self.h"
310#endif
311//AJ2D--------------------------------------------------------------------------
312
313//Diff register
314unsigned int mirror_register_file[39];
315
316/* EMULATION of ARM6. */
317
318/* The PC pipeline value depends on whether ARM
319 or Thumb instructions are being executed. */
320ARMword isize;
321
322extern int debugmode;
323int ARMul_ICE_debug(ARMul_State *state,ARMword instr,ARMword addr);
324#ifdef MODE32
325//chy 2006-04-12, for ICE debug
326int ARMul_ICE_debug(ARMul_State *state,ARMword instr,ARMword addr)
327{
328 int i;
329#if 0
330 if (debugmode) {
331 if (instr == ARMul_ABORTWORD) return 0;
332 for (i = 0; i < skyeye_ice.num_bps; i++) {
333 if (skyeye_ice.bps[i] == addr) {
334 //for test
335 //printf("SKYEYE: ICE_debug bps [%d]== 0x%x\n", i,addr);
336 state->EndCondition = 0;
337 state->Emulate = STOP;
338 return 1;
339 }
340 }
341 if (skyeye_ice.tps_status==TRACE_STARTED)
342 {
343 for (i = 0; i < skyeye_ice.num_tps; i++)
344 {
345 if (((skyeye_ice.tps[i].tp_address==addr)&&(skyeye_ice.tps[i].status==TRACEPOINT_ENABLED))||(skyeye_ice.tps[i].status==TRACEPOINT_STEPPING))
346 {
347 handle_tracepoint(i);
348 }
349 }
350 }
351 }
352 /* do profiling for code coverage */
353 if (skyeye_config.code_cov.prof_on)
354 cov_prof(EXEC_FLAG, addr);
355#endif
356 /* chech if we need to run some callback functions at this time */
357 //generic_arch_t* arch_instance = get_arch_instance("");
358 //exec_callback(Step_callback, arch_instance);
359 //if (!SIM_is_running()) {
360 // if (instr == ARMul_ABORTWORD) return 0;
361 // state->EndCondition = 0;
362 // state->Emulate = STOP;
363 // return 1;
364 //}
365 return 0;
366}
367
368/*
369void chy_debug()
370{
371 printf("SkyEye chy_deubeg begin\n");
372}
373*/
374ARMword
375ARMul_Emulate32 (ARMul_State * state)
376#else
377ARMword
378ARMul_Emulate26 (ARMul_State * state)
379#endif
380{
381 ARMword instr; /* The current instruction. */
382 ARMword dest = 0; /* Almost the DestBus. */
383 ARMword temp; /* Ubiquitous third hand. */
384 ARMword pc = 0; /* The address of the current instruction. */
385 ARMword lhs; /* Almost the ABus and BBus. */
386 ARMword rhs;
387 ARMword decoded = 0; /* Instruction pipeline. */
388 ARMword loaded = 0;
389 ARMword decoded_addr=0;
390 ARMword loaded_addr=0;
391 ARMword have_bp=0;
392
393 /* shenoubang */
394 static int instr_sum = 0;
395 int reg_index = 0;
396#if DIFF_STATE
397//initialize all mirror register for follow mode
398 for (reg_index = 0; reg_index < 16; reg_index ++) {
399 mirror_register_file[reg_index] = state->Reg[reg_index];
400 }
401 mirror_register_file[CPSR_REG] = state->Cpsr;
402 mirror_register_file[R13_SVC] = state->RegBank[SVCBANK][13];
403 mirror_register_file[R14_SVC] = state->RegBank[SVCBANK][14];
404 mirror_register_file[R13_ABORT] = state->RegBank[ABORTBANK][13];
405 mirror_register_file[R14_ABORT] = state->RegBank[ABORTBANK][14];
406 mirror_register_file[R13_UNDEF] = state->RegBank[UNDEFBANK][13];
407 mirror_register_file[R14_UNDEF] = state->RegBank[UNDEFBANK][14];
408 mirror_register_file[R13_IRQ] = state->RegBank[IRQBANK][13];
409 mirror_register_file[R14_IRQ] = state->RegBank[IRQBANK][14];
410 mirror_register_file[R8_FIRQ] = state->RegBank[FIQBANK][8];
411 mirror_register_file[R9_FIRQ] = state->RegBank[FIQBANK][9];
412 mirror_register_file[R10_FIRQ] = state->RegBank[FIQBANK][10];
413 mirror_register_file[R11_FIRQ] = state->RegBank[FIQBANK][11];
414 mirror_register_file[R12_FIRQ] = state->RegBank[FIQBANK][12];
415 mirror_register_file[R13_FIRQ] = state->RegBank[FIQBANK][13];
416 mirror_register_file[R14_FIRQ] = state->RegBank[FIQBANK][14];
417 mirror_register_file[SPSR_SVC] = state->Spsr[SVCBANK];
418 mirror_register_file[SPSR_ABORT] = state->Spsr[ABORTBANK];
419 mirror_register_file[SPSR_UNDEF] = state->Spsr[UNDEFBANK];
420 mirror_register_file[SPSR_IRQ] = state->Spsr[IRQBANK];
421 mirror_register_file[SPSR_FIRQ] = state->Spsr[FIQBANK];
422#endif
423 /* Execute the next instruction. */
424 if (state->NextInstr < PRIMEPIPE) {
425 decoded = state->decoded;
426 loaded = state->loaded;
427 pc = state->pc;
428 //chy 2006-04-12, for ICE debug
429 decoded_addr=state->decoded_addr;
430 loaded_addr=state->loaded_addr;
431 }
432
433 do {
434 //print_func_name(state->pc);
435 /* Just keep going. */
436 isize = INSN_SIZE;
437
438 switch (state->NextInstr) {
439 case SEQ:
440 /* Advance the pipeline, and an S cycle. */
441 state->Reg[15] += isize;
442 pc += isize;
443 instr = decoded;
444 //chy 2006-04-12, for ICE debug
445 have_bp = ARMul_ICE_debug(state,instr,decoded_addr);
446 decoded = loaded;
447 decoded_addr=loaded_addr;
448 //loaded = ARMul_LoadInstrS (state, pc + (isize * 2),
449 // isize);
450 loaded_addr=pc + (isize * 2);
451 if (have_bp) goto TEST_EMULATE;
452 break;
453
454 case NONSEQ:
455 /* Advance the pipeline, and an N cycle. */
456 state->Reg[15] += isize;
457 pc += isize;
458 instr = decoded;
459 //chy 2006-04-12, for ICE debug
460 have_bp=ARMul_ICE_debug(state,instr,decoded_addr);
461 decoded = loaded;
462 decoded_addr=loaded_addr;
463 //loaded = ARMul_LoadInstrN (state, pc + (isize * 2),
464 // isize);
465 loaded_addr=pc + (isize * 2);
466 NORMALCYCLE;
467 if (have_bp) goto TEST_EMULATE;
468 break;
469
470 case PCINCEDSEQ:
471 /* Program counter advanced, and an S cycle. */
472 pc += isize;
473 instr = decoded;
474 //chy 2006-04-12, for ICE debug
475 have_bp=ARMul_ICE_debug(state,instr,decoded_addr);
476 decoded = loaded;
477 decoded_addr=loaded_addr;
478 //loaded = ARMul_LoadInstrS (state, pc + (isize * 2),
479 // isize);
480 loaded_addr=pc + (isize * 2);
481 NORMALCYCLE;
482 if (have_bp) goto TEST_EMULATE;
483 break;
484
485 case PCINCEDNONSEQ:
486 /* Program counter advanced, and an N cycle. */
487 pc += isize;
488 instr = decoded;
489 //chy 2006-04-12, for ICE debug
490 have_bp=ARMul_ICE_debug(state,instr,decoded_addr);
491 decoded = loaded;
492 decoded_addr=loaded_addr;
493 //loaded = ARMul_LoadInstrN (state, pc + (isize * 2),
494 // isize);
495 loaded_addr=pc + (isize * 2);
496 NORMALCYCLE;
497 if (have_bp) goto TEST_EMULATE;
498 break;
499
500 case RESUME:
501 /* The program counter has been changed. */
502 pc = state->Reg[15];
503#ifndef MODE32
504 pc = pc & R15PCBITS;
505#endif
506 state->Reg[15] = pc + (isize * 2);
507 state->Aborted = 0;
508 //chy 2004-05-25, fix bug provided by Carl van Schaik<cvansch@cse.unsw.EDU.AU>
509 state->AbortAddr = 1;
510
511 instr = ARMul_LoadInstrN (state, pc, isize);
512 //instr = ARMul_ReLoadInstr (state, pc, isize);
513 //chy 2006-04-12, for ICE debug
514 have_bp=ARMul_ICE_debug(state,instr,pc);
515 //decoded =
516 // ARMul_ReLoadInstr (state, pc + isize, isize);
517 decoded_addr=pc+isize;
518 //loaded = ARMul_ReLoadInstr (state, pc + isize * 2,
519 // isize);
520 loaded_addr=pc + isize * 2;
521 NORMALCYCLE;
522 if (have_bp) goto TEST_EMULATE;
523 break;
524
525 default:
526 /* The program counter has been changed. */
527 pc = state->Reg[15];
528#ifndef MODE32
529 pc = pc & R15PCBITS;
530#endif
531 state->Reg[15] = pc + (isize * 2);
532 state->Aborted = 0;
533 //chy 2004-05-25, fix bug provided by Carl van Schaik<cvansch@cse.unsw.EDU.AU>
534 state->AbortAddr = 1;
535
536 instr = ARMul_LoadInstrN (state, pc, isize);
537 //chy 2006-04-12, for ICE debug
538 have_bp=ARMul_ICE_debug(state,instr,pc);
539 #if 0
540 decoded =
541 ARMul_LoadInstrS (state, pc + (isize), isize);
542 #endif
543 decoded_addr=pc+isize;
544 #if 0
545 loaded = ARMul_LoadInstrS (state, pc + (isize * 2),
546 isize);
547 #endif
548 loaded_addr=pc + isize * 2;
549 NORMALCYCLE;
550 if (have_bp) goto TEST_EMULATE;
551 break;
552 }
553#if 0
554 int idx = 0;
555 printf("pc:%x\n", pc);
556 for (;idx < 17; idx ++) {
557 printf("R%d:%x\t", idx, state->Reg[idx]);
558 }
559 printf("\n");
560#endif
561 instr = ARMul_LoadInstrN (state, pc, isize);
562 state->last_instr = state->CurrInstr;
563 state->CurrInstr = instr;
564#if 0
565 if((state->NumInstrs % 10000000) == 0)
566 printf("---|%p|--- %lld\n", pc, state->NumInstrs);
567 if(state->NumInstrs > (3000000000)){
568 static int flag = 0;
569 if(pc == 0x8032ccc4){
570 flag = 300;
571 }
572 if(flag){
573 int idx = 0;
574 printf("------------------------------------\n");
575 printf("pc:%x\n", pc);
576 for (;idx < 17; idx ++) {
577 printf("R%d:%x\t", idx, state->Reg[idx]);
578 }
579 printf("\nN:%d\t Z:%d\t C:%d\t V:%d\n", state->NFlag, state->ZFlag, state->CFlag, state->VFlag);
580 printf("\n");
581 printf("------------------------------------\n");
582 flag--;
583 }
584 }
585#endif
586#if DIFF_STATE
587 fprintf(state->state_log, "PC:0x%x\n", pc);
588 if (pc && (pc + 8) != state->Reg[15]) {
589 printf("lucky dog\n");
590 printf("pc is %x, R15 is %x\n", pc, state->Reg[15]);
591 //exit(-1);
592 }
593 for (reg_index = 0; reg_index < 16; reg_index ++) {
594 if (state->Reg[reg_index] != mirror_register_file[reg_index]) {
595 fprintf(state->state_log, "R%d:0x%x\n", reg_index, state->Reg[reg_index]);
596 mirror_register_file[reg_index] = state->Reg[reg_index];
597 }
598 }
599 if (state->Cpsr != mirror_register_file[CPSR_REG]) {
600 fprintf(state->state_log, "Cpsr:0x%x\n", state->Cpsr);
601 mirror_register_file[CPSR_REG] = state->Cpsr;
602 }
603 if (state->RegBank[SVCBANK][13] != mirror_register_file[R13_SVC]) {
604 fprintf(state->state_log, "R13_SVC:0x%x\n", state->RegBank[SVCBANK][13]);
605 mirror_register_file[R13_SVC] = state->RegBank[SVCBANK][13];
606 }
607 if (state->RegBank[SVCBANK][14] != mirror_register_file[R14_SVC]) {
608 fprintf(state->state_log, "R14_SVC:0x%x\n", state->RegBank[SVCBANK][14]);
609 mirror_register_file[R14_SVC] = state->RegBank[SVCBANK][14];
610 }
611 if (state->RegBank[ABORTBANK][13] != mirror_register_file[R13_ABORT]) {
612 fprintf(state->state_log, "R13_ABORT:0x%x\n", state->RegBank[ABORTBANK][13]);
613 mirror_register_file[R13_ABORT] = state->RegBank[ABORTBANK][13];
614 }
615 if (state->RegBank[ABORTBANK][14] != mirror_register_file[R14_ABORT]) {
616 fprintf(state->state_log, "R14_ABORT:0x%x\n", state->RegBank[ABORTBANK][14]);
617 mirror_register_file[R14_ABORT] = state->RegBank[ABORTBANK][14];
618 }
619 if (state->RegBank[UNDEFBANK][13] != mirror_register_file[R13_UNDEF]) {
620 fprintf(state->state_log, "R13_UNDEF:0x%x\n", state->RegBank[UNDEFBANK][13]);
621 mirror_register_file[R13_UNDEF] = state->RegBank[UNDEFBANK][13];
622 }
623 if (state->RegBank[UNDEFBANK][14] != mirror_register_file[R14_UNDEF]) {
624 fprintf(state->state_log, "R14_UNDEF:0x%x\n", state->RegBank[UNDEFBANK][14]);
625 mirror_register_file[R14_UNDEF] = state->RegBank[UNDEFBANK][14];
626 }
627 if (state->RegBank[IRQBANK][13] != mirror_register_file[R13_IRQ]) {
628 fprintf(state->state_log, "R13_IRQ:0x%x\n", state->RegBank[IRQBANK][13]);
629 mirror_register_file[R13_IRQ] = state->RegBank[IRQBANK][13];
630 }
631 if (state->RegBank[IRQBANK][14] != mirror_register_file[R14_IRQ]) {
632 fprintf(state->state_log, "R14_IRQ:0x%x\n", state->RegBank[IRQBANK][14]);
633 mirror_register_file[R14_IRQ] = state->RegBank[IRQBANK][14];
634 }
635 if (state->RegBank[FIQBANK][8] != mirror_register_file[R8_FIRQ]) {
636 fprintf(state->state_log, "R8_FIRQ:0x%x\n", state->RegBank[FIQBANK][8]);
637 mirror_register_file[R8_FIRQ] = state->RegBank[FIQBANK][8];
638 }
639 if (state->RegBank[FIQBANK][9] != mirror_register_file[R9_FIRQ]) {
640 fprintf(state->state_log, "R9_FIRQ:0x%x\n", state->RegBank[FIQBANK][9]);
641 mirror_register_file[R9_FIRQ] = state->RegBank[FIQBANK][9];
642 }
643 if (state->RegBank[FIQBANK][10] != mirror_register_file[R10_FIRQ]) {
644 fprintf(state->state_log, "R10_FIRQ:0x%x\n", state->RegBank[FIQBANK][10]);
645 mirror_register_file[R10_FIRQ] = state->RegBank[FIQBANK][10];
646 }
647 if (state->RegBank[FIQBANK][11] != mirror_register_file[R11_FIRQ]) {
648 fprintf(state->state_log, "R11_FIRQ:0x%x\n", state->RegBank[FIQBANK][11]);
649 mirror_register_file[R11_FIRQ] = state->RegBank[FIQBANK][11];
650 }
651 if (state->RegBank[FIQBANK][12] != mirror_register_file[R12_FIRQ]) {
652 fprintf(state->state_log, "R12_FIRQ:0x%x\n", state->RegBank[FIQBANK][12]);
653 mirror_register_file[R12_FIRQ] = state->RegBank[FIQBANK][12];
654 }
655 if (state->RegBank[FIQBANK][13] != mirror_register_file[R13_FIRQ]) {
656 fprintf(state->state_log, "R13_FIRQ:0x%x\n", state->RegBank[FIQBANK][13]);
657 mirror_register_file[R13_FIRQ] = state->RegBank[FIQBANK][13];
658 }
659 if (state->RegBank[FIQBANK][14] != mirror_register_file[R14_FIRQ]) {
660 fprintf(state->state_log, "R14_FIRQ:0x%x\n", state->RegBank[FIQBANK][14]);
661 mirror_register_file[R14_FIRQ] = state->RegBank[FIQBANK][14];
662 }
663 if (state->Spsr[SVCBANK] != mirror_register_file[SPSR_SVC]) {
664 fprintf(state->state_log, "SPSR_SVC:0x%x\n", state->Spsr[SVCBANK]);
665 mirror_register_file[SPSR_SVC] = state->RegBank[SVCBANK];
666 }
667 if (state->Spsr[ABORTBANK] != mirror_register_file[SPSR_ABORT]) {
668 fprintf(state->state_log, "SPSR_ABORT:0x%x\n", state->Spsr[ABORTBANK]);
669 mirror_register_file[SPSR_ABORT] = state->RegBank[ABORTBANK];
670 }
671 if (state->Spsr[UNDEFBANK] != mirror_register_file[SPSR_UNDEF]) {
672 fprintf(state->state_log, "SPSR_UNDEF:0x%x\n", state->Spsr[UNDEFBANK]);
673 mirror_register_file[SPSR_UNDEF] = state->RegBank[UNDEFBANK];
674 }
675 if (state->Spsr[IRQBANK] != mirror_register_file[SPSR_IRQ]) {
676 fprintf(state->state_log, "SPSR_IRQ:0x%x\n", state->Spsr[IRQBANK]);
677 mirror_register_file[SPSR_IRQ] = state->RegBank[IRQBANK];
678 }
679 if (state->Spsr[FIQBANK] != mirror_register_file[SPSR_FIRQ]) {
680 fprintf(state->state_log, "SPSR_FIRQ:0x%x\n", state->Spsr[FIQBANK]);
681 mirror_register_file[SPSR_FIRQ] = state->RegBank[FIQBANK];
682 }
683#endif
684
685#if 0
686 uint32_t alex = 0;
687 static int flagged = 0;
688 if ((flagged == 0) && (pc == 0xb224))
689 {
690 flagged++;
691 }
692 if ((flagged == 1) && (pc == 0x1a800))
693 {
694 flagged++;
695 }
696 if (flagged == 3) {
697 printf("---|%p|--- %x\n", pc, state->NumInstrs);
698 for (alex = 0; alex < 15; alex++)
699 {
700 printf("R%02d % 8x\n", alex, state->Reg[alex]);
701 }
702 printf("R%02d % 8x\n", alex, state->Reg[alex] - 8);
703 printf("CPS %x%07x\n", (state->NFlag<<3 | state->ZFlag<<2 | state->CFlag<<1 | state->VFlag), state->Cpsr & 0xfffffff);
704 } else {
705 if (state->NumInstrs < 0x400000)
706 {
707 //exit(-1);
708 }
709 }
710#endif
711
712 if (state->EventSet)
713 ARMul_EnvokeEvent (state);
714
715#if 0
716 /* do profiling for code coverage */
717 if (skyeye_config.code_cov.prof_on)
718 cov_prof(EXEC_FLAG, pc);
719#endif
720//2003-07-11 chy: for test
721#if 0
722 if (skyeye_config.log.logon >= 1) {
723 if (state->NumInstrs >= skyeye_config.log.start &&
724 state->NumInstrs <= skyeye_config.log.end) {
725 static int mybegin = 0;
726 static int myinstrnum = 0;
727 if (mybegin == 0)
728 mybegin = 1;
729#if 0
730 if (state->NumInstrs == 3695) {
731 printf ("***********SKYEYE: numinstr = 3695\n");
732 }
733 static int mybeg2 = 0;
734 static int mybeg3 = 0;
735 static int mybeg4 = 0;
736 static int mybeg5 = 0;
737
738 if (pc == 0xa0008000) {
739 //mybegin=1;
740 printf ("************SKYEYE: real vmlinux begin now numinstr is %llu ****************\n", state->NumInstrs);
741 }
742
743 //chy 2003-09-02 test fiq
744 if (state->NumInstrs == 67347000) {
745 printf ("***********SKYEYE: numinstr = 67347000, begin log\n");
746 mybegin = 1;
747 }
748 if (pc == 0xc00087b4) { //numinstr=67348714
749 mybegin = 1;
750 printf ("************SKYEYE: test irq now numinstr is %llu ****************\n", state->NumInstrs);
751 }
752 if (pc == 0xc00087b8) { //in start_kernel::sti()
753 mybeg4 = 1;
754 printf ("************SKYEYE: startkerenl: sti now numinstr is %llu ********\n", state->NumInstrs);
755 }
756 /*if (pc==0xc001e4f4||pc==0xc001e4f8||pc==0xc001e4fc||pc==0xc001e500||pc==0xffff0004) { //MRA instr */
757 if (pc == 0xc001e500) { //MRA instr
758 mybeg5 = 1;
759 printf ("************SKYEYE: MRA instr now numinstr is %llu ********\n", state->NumInstrs);
760 }
761 if (pc >= 0xc0000000 && mybeg2 == 0) {
762 mybeg2 = 1;
763 printf ("************SKYEYE: enable mmu&cache, now numinstr is %llu **************\n", state->NumInstrs);
764 SKYEYE_OUTREGS (stderr);
765 printf ("************************************************************************\n");
766 }
767 //chy 2003-09-01 test after tlb-flush
768 if (pc == 0xc00261ac) {
769 //sleep(2);
770 mybeg3 = 1;
771 printf ("************SKYEYE: after tlb-flush numinstr is %llu ****************\n", state->NumInstrs);
772 }
773 if (mybeg3 == 1) {
774 SKYEYE_OUTREGS (skyeye_logfd);
775 SKYEYE_OUTMOREREGS (skyeye_logfd);
776 fprintf (skyeye_logfd, "\n");
777 }
778#endif
779 if (mybegin == 1) {
780 //fprintf(skyeye_logfd,"p %x,i %x,d %x,l %x,",pc,instr,decoded,loaded);
781 //chy for test 20050729
782 /*if (state->NumInstrs>=3302294) {
783 if (pc==0x100c9d4 && instr==0xe1b0f00e){
784 chy_debug();
785 printf("*********************************************\n");
786 printf("******SKYEYE N %llx :p %x,i %x\n SKYEYE******\n",state->NumInstrs,pc,instr);
787 printf("*********************************************\n");
788 }
789 */
790 if (skyeye_config.log.logon >= 1)
791 /*
792 fprintf (skyeye_logfd,
793 "N %llx :p %x,i %x,",
794 state->NumInstrs, pc,
795#ifdef MODET
796 TFLAG ? instr & 0xffff : instr
797#else
798 instr
799#endif
800 );
801 */
802 fprintf(skyeye_logfd, "pc=0x%x,r3=0x%x\n", pc, state->Reg[3]);
803 if (skyeye_config.log.logon >= 2)
804 SKYEYE_OUTREGS (skyeye_logfd);
805 if (skyeye_config.log.logon >= 3)
806 SKYEYE_OUTMOREREGS
807 (skyeye_logfd);
808 //fprintf (skyeye_logfd, "\n");
809 if (skyeye_config.log.length > 0) {
810 myinstrnum++;
811 if (myinstrnum >=
812 skyeye_config.log.
813 length) {
814 myinstrnum = 0;
815 fflush (skyeye_logfd);
816 fseek (skyeye_logfd,
817 0L, SEEK_SET);
818 }
819 }
820 }
821 //SKYEYE_OUTREGS(skyeye_logfd);
822 //SKYEYE_OUTMOREREGS(skyeye_logfd);
823 }
824 }
825#endif
826#if 0 /* Enable this for a helpful bit of debugging when tracing is needed. */
827 fprintf (stderr, "pc: %x, instr: %x\n", pc & ~1, instr);
828 if (instr == 0)
829 abort ();
830#endif
831#if 0 /* Enable this code to help track down stack alignment bugs. */
832 {
833 static ARMword old_sp = -1;
834
835 if (old_sp != state->Reg[13]) {
836 old_sp = state->Reg[13];
837 fprintf (stderr,
838 "pc: %08x: SP set to %08x%s\n",
839 pc & ~1, old_sp,
840 (old_sp % 8) ? " [UNALIGNED!]" : "");
841 }
842 }
843#endif
844 /* Any exceptions ? */
845 if (state->NresetSig == LOW) {
846 ARMul_Abort (state, ARMul_ResetV);
847
848 /*added energy_prof statement by ksh in 2004-11-26 */
849 //chy 2005-07-28 for standalone
850 //ARMul_do_energy(state,instr,pc);
851 break;
852 }
853 else if (!state->NfiqSig && !FFLAG) {
854 ARMul_Abort (state, ARMul_FIQV);
855 /*added energy_prof statement by ksh in 2004-11-26 */
856 //chy 2005-07-28 for standalone
857 //ARMul_do_energy(state,instr,pc);
858 break;
859 }
860 else if (!state->NirqSig && !IFLAG) {
861 ARMul_Abort (state, ARMul_IRQV);
862 /*added energy_prof statement by ksh in 2004-11-26 */
863 //chy 2005-07-28 for standalone
864 //ARMul_do_energy(state,instr,pc);
865 break;
866 }
867
868//teawater add for arm2x86 2005.04.26-------------------------------------------
869#if 0
870// if (state->pc == 0xc011a868 || state->pc == 0xc011a86c) {
871 if (state->NumInstrs == 1671574 || state->NumInstrs == 1671573 || state->NumInstrs == 1671572
872 || state->NumInstrs == 1671575) {
873 for (reg_index = 0; reg_index < 16; reg_index ++) {
874 printf("R%d:%x\t", reg_index, state->Reg[reg_index]);
875 }
876 printf("\n");
877 }
878#endif
879 if (state->tea_pc) {
880 int i;
881
882 if (state->tea_reg_fd) {
883 fprintf (state->tea_reg_fd, "\n");
884 for (i = 0; i < 15; i++) {
885 fprintf (state->tea_reg_fd, "%x,",
886 state->Reg[i]);
887 }
888 fprintf (state->tea_reg_fd, "%x,", pc);
889 state->Cpsr = ARMul_GetCPSR (state);
890 fprintf (state->tea_reg_fd, "%x\n",
891 state->Cpsr);
892 }
893 else {
894 printf ("\n");
895 for (i = 0; i < 15; i++) {
896 printf ("%x,", state->Reg[i]);
897 }
898 printf ("%x,", pc);
899 state->Cpsr = ARMul_GetCPSR (state);
900 printf ("%x\n", state->Cpsr);
901 }
902 }
903//AJ2D--------------------------------------------------------------------------
904
905 if (state->CallDebug > 0) {
906 instr = ARMul_Debug (state, pc, instr);
907 if (state->Emulate < ONCE) {
908 state->NextInstr = RESUME;
909 break;
910 }
911 if (state->Debug) {
912 fprintf (stderr,
913 "sim: At %08lx Instr %08lx Mode %02lx\n",
914 pc, instr, state->Mode);
915 (void) fgetc (stdin);
916 }
917 }
918 else if (state->Emulate < ONCE) {
919 state->NextInstr = RESUME;
920 break;
921 }
922 //io_do_cycle (state);
923 state->NumInstrs++;
924 #if 0
925 if (state->NumInstrs % 10000000 == 0) {
926 printf("10 MIPS instr have been executed\n");
927 }
928 #endif
929
930#ifdef MODET
931 /* Provide Thumb instruction decoding. If the processor is in Thumb
932 mode, then we can simply decode the Thumb instruction, and map it
933 to the corresponding ARM instruction (by directly loading the
934 instr variable, and letting the normal ARM simulator
935 execute). There are some caveats to ensure that the correct
936 pipelined PC value is used when executing Thumb code, and also for
937 dealing with the BL instruction. */
938 if (TFLAG) {
939 ARMword new_instr;
940
941 /* Check if in Thumb mode. */
942 switch (ARMul_ThumbDecode(state, pc, instr, &new_instr)) {
943 case t_undefined:
944 /* This is a Thumb instruction. */
945 ARMul_UndefInstr (state, instr);
946 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
947
948 case t_branch:
949 /* Already processed. */
950 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
951
952 case t_decoded:
953 /* ARM instruction available. */
954 //printf("t decode %04lx -> %08lx\n", instr & 0xffff, new);
955 instr = new_instr;
956 /* So continue instruction decoding. */
957 break;
958 default:
959 break;
960 }
961 }
962#endif
963
964 /* Check the condition codes. */
965 if ((temp = TOPBITS (28)) == AL) {
966 /* Vile deed in the need for speed. */
967 goto mainswitch;
968 }
969
970 /* Check the condition code. */
971 switch ((int) TOPBITS (28)) {
972 case AL:
973 temp = TRUE;
974 break;
975 case NV:
976
977 /* shenoubang add for armv7 instr dmb 2012-3-11 */
978 if (state->is_v7) {
979 if ((instr & 0x0fffff00) == 0x057ff000) {
980 switch((instr >> 4) & 0xf) {
981 case 4: /* dsb */
982 case 5: /* dmb */
983 case 6: /* isb */
984 // TODO: do no implemented thes instr
985 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
986 }
987 }
988 }
989 /* dyf add for armv6 instruct CPS 2010.9.17 */
990 if (state->is_v6) {
991 /* clrex do nothing here temporary */
992 if (instr == 0xf57ff01f) {
993 //printf("clrex \n");
994 ERROR_LOG(ARM11, "Instr = 0x%x, pc = 0x%x, clrex instr!!\n", instr, pc);
995#if 0
996 int i;
997 for(i = 0; i < 128; i++){
998 state->exclusive_tag_array[i] = 0xffffffff;
999 }
1000#endif
1001 /* shenoubang 2012-3-14 refer the dyncom_interpreter */
1002 state->exclusive_tag_array[0] = 0xFFFFFFFF;
1003 state->exclusive_access_state = 0;
1004 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
1005 }
1006
1007 if (BITS(20, 27) == 0x10) {
1008 if (BIT(19)) {
1009 if (BIT(8)) {
1010 if (BIT(18))
1011 state->Cpsr |= 1<<8;
1012 else
1013 state->Cpsr &= ~(1<<8);
1014 }
1015 if (BIT(7)) {
1016 if (BIT(18))
1017 state->Cpsr |= 1<<7;
1018 else
1019 state->Cpsr &= ~(1<<7);
1020 ASSIGNINT (state->Cpsr & INTBITS);
1021 }
1022 if (BIT(6)) {
1023 if (BIT(18))
1024 state->Cpsr |= 1<<6;
1025 else
1026 state->Cpsr &= ~(1<<6);
1027 ASSIGNINT (state->Cpsr & INTBITS);
1028 }
1029 }
1030 if (BIT(17)) {
1031 state->Cpsr |= BITS(0, 4);
1032 printf("skyeye test state->Mode\n");
1033 if (state->Mode != (state->Cpsr & MODEBITS)) {
1034 state->Mode =
1035 ARMul_SwitchMode (state, state->Mode,
1036 state->Cpsr & MODEBITS);
1037
1038 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
1039 }
1040 }
1041 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
1042 }
1043 }
1044 if (state->is_v5) {
1045 if (BITS (25, 27) == 5) { /* BLX(1) */
1046 ARMword dest;
1047
1048 state->Reg[14] = pc + 4;
1049
1050 /* Force entry into Thumb mode. */
1051 dest = pc + 8 + 1;
1052 if (BIT (23))
1053 dest += (NEGBRANCH +
1054 (BIT (24) << 1));
1055 else
1056 dest += POSBRANCH +
1057 (BIT (24) << 1);
1058
1059 WriteR15Branch (state, dest);
1060 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
1061 }
1062 else if ((instr & 0xFC70F000) == 0xF450F000) {
1063 /* The PLD instruction. Ignored. */
1064 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
1065 }
1066 else if (((instr & 0xfe500f00) == 0xfc100100)
1067 || ((instr & 0xfe500f00) ==
1068 0xfc000100)) {
1069 /* wldrw and wstrw are unconditional. */
1070 goto mainswitch;
1071 }
1072 else {
1073 /* UNDEFINED in v5, UNPREDICTABLE in v3, v4, non executed in v1, v2. */
1074 ARMul_UndefInstr (state, instr);
1075 }
1076 }
1077 temp = FALSE;
1078 break;
1079 case EQ:
1080 temp = ZFLAG;
1081 break;
1082 case NE:
1083 temp = !ZFLAG;
1084 break;
1085 case VS:
1086 temp = VFLAG;
1087 break;
1088 case VC:
1089 temp = !VFLAG;
1090 break;
1091 case MI:
1092 temp = NFLAG;
1093 break;
1094 case PL:
1095 temp = !NFLAG;
1096 break;
1097 case CS:
1098 temp = CFLAG;
1099 break;
1100 case CC:
1101 temp = !CFLAG;
1102 break;
1103 case HI:
1104 temp = (CFLAG && !ZFLAG);
1105 break;
1106 case LS:
1107 temp = (!CFLAG || ZFLAG);
1108 break;
1109 case GE:
1110 temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
1111 break;
1112 case LT:
1113 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
1114 break;
1115 case GT:
1116 temp = ((!NFLAG && !VFLAG && !ZFLAG)
1117 || (NFLAG && VFLAG && !ZFLAG));
1118 break;
1119 case LE:
1120 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG))
1121 || ZFLAG;
1122 break;
1123 } /* cc check */
1124
1125//chy 2003-08-24 now #if 0 .... #endif process cp14, cp15.reg14, I disable it...
1126#if 0
1127 /* Handle the Clock counter here. */
1128 if (state->is_XScale) {
1129 ARMword cp14r0;
1130 int ok;
1131
1132 ok = state->CPRead[14] (state, 0, &cp14r0);
1133
1134 if (ok && (cp14r0 & ARMul_CP14_R0_ENABLE)) {
1135 unsigned int newcycles, nowtime =
1136 ARMul_Time (state);
1137
1138 newcycles = nowtime - state->LastTime;
1139 state->LastTime = nowtime;
1140
1141 if (cp14r0 & ARMul_CP14_R0_CCD) {
1142 if (state->CP14R0_CCD == -1)
1143 state->CP14R0_CCD = newcycles;
1144 else
1145 state->CP14R0_CCD +=
1146 newcycles;
1147
1148 if (state->CP14R0_CCD >= 64) {
1149 newcycles = 0;
1150
1151 while (state->CP14R0_CCD >=
1152 64)
1153 state->CP14R0_CCD -=
1154 64,
1155 newcycles++;
1156
1157 goto check_PMUintr;
1158 }
1159 }
1160 else {
1161 ARMword cp14r1;
1162 int do_int = 0;
1163
1164 state->CP14R0_CCD = -1;
1165 check_PMUintr:
1166 cp14r0 |= ARMul_CP14_R0_FLAG2;
1167 (void) state->CPWrite[14] (state, 0,
1168 cp14r0);
1169
1170 ok = state->CPRead[14] (state, 1,
1171 &cp14r1);
1172
1173 /* Coded like this for portability. */
1174 while (ok && newcycles) {
1175 if (cp14r1 == 0xffffffff) {
1176 cp14r1 = 0;
1177 do_int = 1;
1178 }
1179 else
1180 cp14r1++;
1181
1182 newcycles--;
1183 }
1184
1185 (void) state->CPWrite[14] (state, 1,
1186 cp14r1);
1187
1188 if (do_int
1189 && (cp14r0 &
1190 ARMul_CP14_R0_INTEN2)) {
1191 ARMword temp;
1192
1193 if (state->
1194 CPRead[13] (state, 8,
1195 &temp)
1196 && (temp &
1197 ARMul_CP13_R8_PMUS))
1198 ARMul_Abort (state,
1199 ARMul_FIQV);
1200 else
1201 ARMul_Abort (state,
1202 ARMul_IRQV);
1203 }
1204 }
1205 }
1206 }
1207
1208 /* Handle hardware instructions breakpoints here. */
1209 if (state->is_XScale) {
1210 if ((pc | 3) == (read_cp15_reg (14, 0, 8) | 2)
1211 || (pc | 3) == (read_cp15_reg (14, 0, 9) | 2)) {
1212 if (XScale_debug_moe
1213 (state, ARMul_CP14_R10_MOE_IB))
1214 ARMul_OSHandleSWI (state,
1215 SWI_Breakpoint);
1216 }
1217 }
1218#endif
1219
1220 /* Actual execution of instructions begins here. */
1221 /* If the condition codes don't match, stop here. */
1222 if (temp) {
1223 mainswitch:
1224
1225 if (state->is_XScale) {
1226 if (BIT (20) == 0 && BITS (25, 27) == 0) {
1227 if (BITS (4, 7) == 0xD) {
1228 /* XScale Load Consecutive insn. */
1229 ARMword temp =
1230 GetLS7RHS (state,
1231 instr);
1232 ARMword temp2 =
1233 BIT (23) ? LHS +
1234 temp : LHS - temp;
1235 ARMword addr =
1236 BIT (24) ? temp2 :
1237 LHS;
1238
1239 if (BIT (12))
1240 ARMul_UndefInstr
1241 (state,
1242 instr);
1243 else if (addr & 7)
1244 /* Alignment violation. */
1245 ARMul_Abort (state,
1246 ARMul_DataAbortV);
1247 else {
1248 int wb = BIT (21)
1249 ||
1250 (!BIT (24));
1251
1252 state->Reg[BITS
1253 (12, 15)] =
1254 ARMul_LoadWordN
1255 (state, addr);
1256 state->Reg[BITS
1257 (12,
1258 15) + 1] =
1259 ARMul_LoadWordN
1260 (state,
1261 addr + 4);
1262 if (wb)
1263 LSBase = temp2;
1264 }
1265
1266 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
1267 }
1268 else if (BITS (4, 7) == 0xF) {
1269 /* XScale Store Consecutive insn. */
1270 ARMword temp =
1271 GetLS7RHS (state,
1272 instr);
1273 ARMword temp2 =
1274 BIT (23) ? LHS +
1275 temp : LHS - temp;
1276 ARMword addr =
1277 BIT (24) ? temp2 :
1278 LHS;
1279
1280 if (BIT (12))
1281 ARMul_UndefInstr
1282 (state,
1283 instr);
1284 else if (addr & 7)
1285 /* Alignment violation. */
1286 ARMul_Abort (state,
1287 ARMul_DataAbortV);
1288 else {
1289 ARMul_StoreWordN
1290 (state, addr,
1291 state->
1292 Reg[BITS
1293 (12,
1294 15)]);
1295 ARMul_StoreWordN
1296 (state,
1297 addr + 4,
1298 state->
1299 Reg[BITS
1300 (12,
1301 15) +
1302 1]);
1303
1304 if (BIT (21)
1305 || !BIT (24))
1306 LSBase = temp2;
1307 }
1308
1309 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
1310 }
1311 }
1312 //chy 2003-09-03 TMRRC(iwmmxt.c) and MRA has the same decoded instr????
1313 //Now, I commit iwmmxt process, may be future, I will change it!!!!
1314 //if (ARMul_HandleIwmmxt (state, instr))
1315 // _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
1316 }
1317
1318 /* shenoubang sbfx and ubfx instr 2012-3-16 */
1319 if (state->is_v6) {
1320 unsigned int m, lsb, width, Rd, Rn, data;
1321 Rd = Rn = lsb = width = data = m = 0;
1322
1323 //printf("helloworld\n");
1324 if ((((int) BITS (21, 27)) == 0x3f) && (((int) BITS (4, 6)) == 0x5)) {
1325 m = (unsigned)BITS(7, 11);
1326 width = (unsigned)BITS(16, 20);
1327 Rd = (unsigned)BITS(12, 15);
1328 Rn = (unsigned)BITS(0, 3);
1329 if ((Rd == 15) || (Rn == 15)) {
1330 ARMul_UndefInstr (state, instr);
1331 }
1332 else if ((m + width) < 32) {
1333 data = state->Reg[Rn];
1334 state->Reg[Rd] ^= state->Reg[Rd];
1335 state->Reg[Rd] =
1336 ((ARMword)(data << (31 -(m + width))) >> ((31 - (m + width)) + (m)));
1337 //SKYEYE_LOG_IN_CLR(RED, "UBFX: In %s, line = %d, Reg_src[%d] = 0x%x, Reg_d[%d] = 0x%x, m = %d, width = %d, Rd = %d, Rn = %d\n",
1338 // __FUNCTION__, __LINE__, Rn, data, Rd, state->Reg[Rd], m, width + 1, Rd, Rn);
1339 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
1340 }
1341 } // ubfx instr
1342 else if ((((int) BITS (21, 27)) == 0x3d) && (((int) BITS (4, 6)) == 0x5)) {
1343 int tmp = 0;
1344 Rd = BITS(12, 15); Rn = BITS(0, 3);
1345 lsb = BITS(7, 11); width = BITS(16, 20);
1346 if ((Rd == 15) || (Rn == 15)) {
1347 ARMul_UndefInstr (state, instr);
1348 }
1349 else if ((lsb + width) < 32) {
1350 state->Reg[Rd] ^= state->Reg[Rd];
1351 data = state->Reg[Rn];
1352 tmp = (data << (32 - (lsb + width + 1)));
1353 state->Reg[Rd] = (tmp >> (32 - (lsb + width + 1)));
1354 //SKYEYE_LOG_IN_CLR(RED, "sbfx: In %s, line = %d, pc = 0x%x, instr = 0x%x,Rd = 0x%x, \
1355 Rn = 0x%x, lsb = %d, width = %d, Rs[%d] = 0x%x, Rd[%d] = 0x%x\n",
1356 // __func__, __LINE__, pc, instr, Rd, Rn, lsb, width + 1, Rn, state->Reg[Rn], Rd, state->Reg[Rd]);
1357 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
1358 }
1359 } // sbfx instr
1360 else if ((((int)BITS(21, 27)) == 0x3e) && ((int)BITS(4, 6) == 0x1)) {
1361 //(ARMword)(instr<<(31-(n))) >> ((31-(n))+(m))
1362 unsigned msb ,tmp_rn, tmp_rd, dst;
1363 msb = tmp_rd = tmp_rn = dst = 0;
1364 Rd = BITS(12, 15); Rn = BITS(0, 3);
1365 lsb = BITS(7, 11); msb = BITS(16, 20);
1366 if ((Rd == 15)) {
1367 ARMul_UndefInstr (state, instr);
1368 }
1369 else if ((Rn == 15)) {
1370 data = state->Reg[Rd];
1371 tmp_rd = ((ARMword)(data << (31 - lsb)) >> (31 - lsb));
1372 dst = ((data >> msb) << (msb - lsb));
1373 dst = (dst << lsb) | tmp_rd;
1374 DEBUG_LOG(ARM11, "BFC instr: msb = %d, lsb = %d, Rd[%d] : 0x%x, dst = 0x%x\n",
1375 msb, lsb, Rd, state->Reg[Rd], dst);
1376 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
1377 } // bfc instr
1378 else if (((msb >= lsb) && (msb < 32))) {
1379 data = state->Reg[Rn];
1380 tmp_rn = ((ARMword)(data << (31 - (msb - lsb))) >> (31 - (msb - lsb)));
1381 data = state->Reg[Rd];
1382 tmp_rd = ((ARMword)(data << (31 - lsb)) >> (31 - lsb));
1383 dst = ((data >> msb) << (msb - lsb)) | tmp_rn;
1384 dst = (dst << lsb) | tmp_rd;
1385 DEBUG_LOG(ARM11, "BFI instr:msb = %d, lsb = %d, Rd[%d] : 0x%x, Rn[%d]: 0x%x, dst = 0x%x\n",
1386 msb, lsb, Rd, state->Reg[Rd], Rn, state->Reg[Rn], dst);
1387 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
1388 } // bfi instr
1389 }
1390 }
1391
1392 switch ((int) BITS (20, 27)) {
1393 /* Data Processing Register RHS Instructions. */
1394
1395 case 0x00: /* AND reg and MUL */
1396#ifdef MODET
1397 if (BITS (4, 11) == 0xB) {
1398 /* STRH register offset, no write-back, down, post indexed. */
1399 SHDOWNWB ();
1400 break;
1401 }
1402 if (BITS (4, 7) == 0xD) {
1403 Handle_Load_Double (state, instr);
1404 break;
1405 }
1406 if (BITS (4, 7) == 0xF) {
1407 Handle_Store_Double (state, instr);
1408 break;
1409 }
1410#endif
1411 if (BITS (4, 7) == 9) {
1412 /* MUL */
1413 rhs = state->Reg[MULRHSReg];
1414 //if (MULLHSReg == MULDESTReg) {
1415 if(0){ /* For armv6, the restriction is removed */
1416 UNDEF_MULDestEQOp1;
1417 state->Reg[MULDESTReg] = 0;
1418 }
1419 else if (MULDESTReg != 15)
1420 state->Reg[MULDESTReg] =
1421 state->
1422 Reg[MULLHSReg] * rhs;
1423 else
1424 UNDEF_MULPCDest;
1425
1426 for (dest = 0, temp = 0; dest < 32;
1427 dest++)
1428 if (rhs & (1L << dest))
1429 temp = dest;
1430
1431 /* Mult takes this many/2 I cycles. */
1432 ARMul_Icycles (state,
1433 ARMul_MultTable[temp],
1434 0L);
1435 }
1436 else {
1437 /* AND reg. */
1438 rhs = DPRegRHS;
1439 dest = LHS & rhs;
1440 WRITEDEST (dest);
1441 }
1442 break;
1443
1444 case 0x01: /* ANDS reg and MULS */
1445#ifdef MODET
1446 if ((BITS (4, 11) & 0xF9) == 0x9)
1447 /* LDR register offset, no write-back, down, post indexed. */
1448 LHPOSTDOWN ();
1449 /* Fall through to rest of decoding. */
1450#endif
1451 if (BITS (4, 7) == 9) {
1452 /* MULS */
1453 rhs = state->Reg[MULRHSReg];
1454
1455 //if (MULLHSReg == MULDESTReg) {
1456 if(0){
1457 printf("Something in %d line\n", __LINE__);
1458 UNDEF_WARNING;
1459 UNDEF_MULDestEQOp1;
1460 state->Reg[MULDESTReg] = 0;
1461 CLEARN;
1462 SETZ;
1463 }
1464 else if (MULDESTReg != 15) {
1465 dest = state->Reg[MULLHSReg] *
1466 rhs;
1467 ARMul_NegZero (state, dest);
1468 state->Reg[MULDESTReg] = dest;
1469 }
1470 else
1471 UNDEF_MULPCDest;
1472
1473 for (dest = 0, temp = 0; dest < 32;
1474 dest++)
1475 if (rhs & (1L << dest))
1476 temp = dest;
1477
1478 /* Mult takes this many/2 I cycles. */
1479 ARMul_Icycles (state,
1480 ARMul_MultTable[temp],
1481 0L);
1482 }
1483 else {
1484 /* ANDS reg. */
1485 rhs = DPSRegRHS;
1486 dest = LHS & rhs;
1487 WRITESDEST (dest);
1488 }
1489 break;
1490
1491 case 0x02: /* EOR reg and MLA */
1492#ifdef MODET
1493 if (BITS (4, 11) == 0xB) {
1494 /* STRH register offset, write-back, down, post indexed. */
1495 SHDOWNWB ();
1496 break;
1497 }
1498#endif
1499 if (BITS (4, 7) == 9) { /* MLA */
1500 rhs = state->Reg[MULRHSReg];
1501 #if 0
1502 if (MULLHSReg == MULDESTReg) {
1503 UNDEF_MULDestEQOp1;
1504 state->Reg[MULDESTReg] =
1505 state->Reg[MULACCReg];
1506 }
1507 else if (MULDESTReg != 15){
1508 #endif
1509 if (MULDESTReg != 15){
1510 state->Reg[MULDESTReg] =
1511 state->
1512 Reg[MULLHSReg] * rhs +
1513 state->Reg[MULACCReg];
1514 }
1515 else
1516 UNDEF_MULPCDest;
1517
1518 for (dest = 0, temp = 0; dest < 32;
1519 dest++)
1520 if (rhs & (1L << dest))
1521 temp = dest;
1522
1523 /* Mult takes this many/2 I cycles. */
1524 ARMul_Icycles (state,
1525 ARMul_MultTable[temp],
1526 0L);
1527 }
1528 else {
1529 rhs = DPRegRHS;
1530 dest = LHS ^ rhs;
1531 WRITEDEST (dest);
1532 }
1533 break;
1534
1535 case 0x03: /* EORS reg and MLAS */
1536#ifdef MODET
1537 if ((BITS (4, 11) & 0xF9) == 0x9)
1538 /* LDR register offset, write-back, down, post-indexed. */
1539 LHPOSTDOWN ();
1540 /* Fall through to rest of the decoding. */
1541#endif
1542 if (BITS (4, 7) == 9) {
1543 /* MLAS */
1544 rhs = state->Reg[MULRHSReg];
1545 //if (MULLHSReg == MULDESTReg) {
1546 if (0) {
1547 UNDEF_MULDestEQOp1;
1548 dest = state->Reg[MULACCReg];
1549 ARMul_NegZero (state, dest);
1550 state->Reg[MULDESTReg] = dest;
1551 }
1552 else if (MULDESTReg != 15) {
1553 dest = state->Reg[MULLHSReg] *
1554 rhs +
1555 state->Reg[MULACCReg];
1556 ARMul_NegZero (state, dest);
1557 state->Reg[MULDESTReg] = dest;
1558 }
1559 else
1560 UNDEF_MULPCDest;
1561
1562 for (dest = 0, temp = 0; dest < 32;
1563 dest++)
1564 if (rhs & (1L << dest))
1565 temp = dest;
1566
1567 /* Mult takes this many/2 I cycles. */
1568 ARMul_Icycles (state,
1569 ARMul_MultTable[temp],
1570 0L);
1571 }
1572 else {
1573 /* EORS Reg. */
1574 rhs = DPSRegRHS;
1575 dest = LHS ^ rhs;
1576 WRITESDEST (dest);
1577 }
1578 break;
1579
1580 case 0x04: /* SUB reg */
1581#ifdef MODET
1582 if (BITS (4, 7) == 0xB) {
1583 /* STRH immediate offset, no write-back, down, post indexed. */
1584 SHDOWNWB ();
1585 break;
1586 }
1587 if (BITS (4, 7) == 0xD) {
1588 Handle_Load_Double (state, instr);
1589 break;
1590 }
1591 if (BITS (4, 7) == 0xF) {
1592 Handle_Store_Double (state, instr);
1593 break;
1594 }
1595#endif
1596 rhs = DPRegRHS;
1597 dest = LHS - rhs;
1598 WRITEDEST (dest);
1599 break;
1600
1601 case 0x05: /* SUBS reg */
1602#ifdef MODET
1603 if ((BITS (4, 7) & 0x9) == 0x9)
1604 /* LDR immediate offset, no write-back, down, post indexed. */
1605 LHPOSTDOWN ();
1606 /* Fall through to the rest of the instruction decoding. */
1607#endif
1608 lhs = LHS;
1609 rhs = DPRegRHS;
1610 dest = lhs - rhs;
1611
1612 if ((lhs >= rhs) || ((rhs | lhs) >> 31)) {
1613 ARMul_SubCarry (state, lhs, rhs,
1614 dest);
1615 ARMul_SubOverflow (state, lhs, rhs,
1616 dest);
1617 }
1618 else {
1619 CLEARC;
1620 CLEARV;
1621 }
1622 WRITESDEST (dest);
1623 break;
1624
1625 case 0x06: /* RSB reg */
1626#ifdef MODET
1627 if (BITS (4, 7) == 0xB) {
1628 /* STRH immediate offset, write-back, down, post indexed. */
1629 SHDOWNWB ();
1630 break;
1631 }
1632#endif
1633 rhs = DPRegRHS;
1634 dest = rhs - LHS;
1635 WRITEDEST (dest);
1636 break;
1637
1638 case 0x07: /* RSBS reg */
1639#ifdef MODET
1640 if ((BITS (4, 7) & 0x9) == 0x9)
1641 /* LDR immediate offset, write-back, down, post indexed. */
1642 LHPOSTDOWN ();
1643 /* Fall through to remainder of instruction decoding. */
1644#endif
1645 lhs = LHS;
1646 rhs = DPRegRHS;
1647 dest = rhs - lhs;
1648
1649 if ((rhs >= lhs) || ((rhs | lhs) >> 31)) {
1650 ARMul_SubCarry (state, rhs, lhs,
1651 dest);
1652 ARMul_SubOverflow (state, rhs, lhs,
1653 dest);
1654 }
1655 else {
1656 CLEARC;
1657 CLEARV;
1658 }
1659 WRITESDEST (dest);
1660 break;
1661
1662 case 0x08: /* ADD reg */
1663#ifdef MODET
1664 if (BITS (4, 11) == 0xB) {
1665 /* STRH register offset, no write-back, up, post indexed. */
1666 SHUPWB ();
1667 break;
1668 }
1669 if (BITS (4, 7) == 0xD) {
1670 Handle_Load_Double (state, instr);
1671 break;
1672 }
1673 if (BITS (4, 7) == 0xF) {
1674 Handle_Store_Double (state, instr);
1675 break;
1676 }
1677#endif
1678#ifdef MODET
1679 if (BITS (4, 7) == 0x9) {
1680 /* MULL */
1681 /* 32x32 = 64 */
1682 ARMul_Icycles (state,
1683 Multiply64 (state,
1684 instr,
1685 LUNSIGNED,
1686 LDEFAULT),
1687 0L);
1688 break;
1689 }
1690#endif
1691 rhs = DPRegRHS;
1692 dest = LHS + rhs;
1693 WRITEDEST (dest);
1694 break;
1695
1696 case 0x09: /* ADDS reg */
1697#ifdef MODET
1698 if ((BITS (4, 11) & 0xF9) == 0x9)
1699 /* LDR register offset, no write-back, up, post indexed. */
1700 LHPOSTUP ();
1701 /* Fall through to remaining instruction decoding. */
1702#endif
1703#ifdef MODET
1704 if (BITS (4, 7) == 0x9) {
1705 /* MULL */
1706 /* 32x32=64 */
1707 ARMul_Icycles (state,
1708 Multiply64 (state,
1709 instr,
1710 LUNSIGNED,
1711 LSCC), 0L);
1712 break;
1713 }
1714#endif
1715 lhs = LHS;
1716 rhs = DPRegRHS;
1717 dest = lhs + rhs;
1718 ASSIGNZ (dest == 0);
1719 if ((lhs | rhs) >> 30) {
1720 /* Possible C,V,N to set. */
1721 ASSIGNN (NEG (dest));
1722 ARMul_AddCarry (state, lhs, rhs,
1723 dest);
1724 ARMul_AddOverflow (state, lhs, rhs,
1725 dest);
1726 }
1727 else {
1728 CLEARN;
1729 CLEARC;
1730 CLEARV;
1731 }
1732 WRITESDEST (dest);
1733 break;
1734
1735 case 0x0a: /* ADC reg */
1736#ifdef MODET
1737 if (BITS (4, 11) == 0xB) {
1738 /* STRH register offset, write-back, up, post-indexed. */
1739 SHUPWB ();
1740 break;
1741 }
1742 if (BITS (4, 7) == 0x9) {
1743 /* MULL */
1744 /* 32x32=64 */
1745 ARMul_Icycles (state,
1746 MultiplyAdd64 (state,
1747 instr,
1748 LUNSIGNED,
1749 LDEFAULT),
1750 0L);
1751 break;
1752 }
1753#endif
1754 rhs = DPRegRHS;
1755 dest = LHS + rhs + CFLAG;
1756 WRITEDEST (dest);
1757 break;
1758
1759 case 0x0b: /* ADCS reg */
1760#ifdef MODET
1761 if ((BITS (4, 11) & 0xF9) == 0x9)
1762 /* LDR register offset, write-back, up, post indexed. */
1763 LHPOSTUP ();
1764 /* Fall through to remaining instruction decoding. */
1765 if (BITS (4, 7) == 0x9) {
1766 /* MULL */
1767 /* 32x32=64 */
1768 ARMul_Icycles (state,
1769 MultiplyAdd64 (state,
1770 instr,
1771 LUNSIGNED,
1772 LSCC),
1773 0L);
1774 break;
1775 }
1776#endif
1777 lhs = LHS;
1778 rhs = DPRegRHS;
1779 dest = lhs + rhs + CFLAG;
1780 ASSIGNZ (dest == 0);
1781 if ((lhs | rhs) >> 30) {
1782 /* Possible C,V,N to set. */
1783 ASSIGNN (NEG (dest));
1784 ARMul_AddCarry (state, lhs, rhs,
1785 dest);
1786 ARMul_AddOverflow (state, lhs, rhs,
1787 dest);
1788 }
1789 else {
1790 CLEARN;
1791 CLEARC;
1792 CLEARV;
1793 }
1794 WRITESDEST (dest);
1795 break;
1796
1797 case 0x0c: /* SBC reg */
1798#ifdef MODET
1799 if (BITS (4, 7) == 0xB) {
1800 /* STRH immediate offset, no write-back, up post indexed. */
1801 SHUPWB ();
1802 break;
1803 }
1804 if (BITS (4, 7) == 0xD) {
1805 Handle_Load_Double (state, instr);
1806 break;
1807 }
1808 if (BITS (4, 7) == 0xF) {
1809 Handle_Store_Double (state, instr);
1810 break;
1811 }
1812 if (BITS (4, 7) == 0x9) {
1813 /* MULL */
1814 /* 32x32=64 */
1815 ARMul_Icycles (state,
1816 Multiply64 (state,
1817 instr,
1818 LSIGNED,
1819 LDEFAULT),
1820 0L);
1821 break;
1822 }
1823#endif
1824 rhs = DPRegRHS;
1825 dest = LHS - rhs - !CFLAG;
1826 WRITEDEST (dest);
1827 break;
1828
1829 case 0x0d: /* SBCS reg */
1830#ifdef MODET
1831 if ((BITS (4, 7) & 0x9) == 0x9)
1832 /* LDR immediate offset, no write-back, up, post indexed. */
1833 LHPOSTUP ();
1834
1835 if (BITS (4, 7) == 0x9) {
1836 /* MULL */
1837 /* 32x32=64 */
1838 ARMul_Icycles (state,
1839 Multiply64 (state,
1840 instr,
1841 LSIGNED,
1842 LSCC), 0L);
1843 break;
1844 }
1845#endif
1846 lhs = LHS;
1847 rhs = DPRegRHS;
1848 dest = lhs - rhs - !CFLAG;
1849 if ((lhs >= rhs) || ((rhs | lhs) >> 31)) {
1850 ARMul_SubCarry (state, lhs, rhs,
1851 dest);
1852 ARMul_SubOverflow (state, lhs, rhs,
1853 dest);
1854 }
1855 else {
1856 CLEARC;
1857 CLEARV;
1858 }
1859 WRITESDEST (dest);
1860 break;
1861
1862 case 0x0e: /* RSC reg */
1863#ifdef MODET
1864 if (BITS (4, 7) == 0xB) {
1865 /* STRH immediate offset, write-back, up, post indexed. */
1866 SHUPWB ();
1867 break;
1868 }
1869
1870 if (BITS (4, 7) == 0x9) {
1871 /* MULL */
1872 /* 32x32=64 */
1873 ARMul_Icycles (state,
1874 MultiplyAdd64 (state,
1875 instr,
1876 LSIGNED,
1877 LDEFAULT),
1878 0L);
1879 break;
1880 }
1881#endif
1882 rhs = DPRegRHS;
1883 dest = rhs - LHS - !CFLAG;
1884 WRITEDEST (dest);
1885 break;
1886
1887 case 0x0f: /* RSCS reg */
1888#ifdef MODET
1889 if ((BITS (4, 7) & 0x9) == 0x9)
1890 /* LDR immediate offset, write-back, up, post indexed. */
1891 LHPOSTUP ();
1892 /* Fall through to remaining instruction decoding. */
1893
1894 if (BITS (4, 7) == 0x9) {
1895 /* MULL */
1896 /* 32x32=64 */
1897 ARMul_Icycles (state,
1898 MultiplyAdd64 (state,
1899 instr,
1900 LSIGNED,
1901 LSCC),
1902 0L);
1903 break;
1904 }
1905#endif
1906 lhs = LHS;
1907 rhs = DPRegRHS;
1908 dest = rhs - lhs - !CFLAG;
1909
1910 if ((rhs >= lhs) || ((rhs | lhs) >> 31)) {
1911 ARMul_SubCarry (state, rhs, lhs,
1912 dest);
1913 ARMul_SubOverflow (state, rhs, lhs,
1914 dest);
1915 }
1916 else {
1917 CLEARC;
1918 CLEARV;
1919 }
1920 WRITESDEST (dest);
1921 break;
1922
1923 case 0x10: /* TST reg and MRS CPSR and SWP word. */
1924 if (state->is_v5e) {
1925 if (BIT (4) == 0 && BIT (7) == 1) {
1926 /* ElSegundo SMLAxy insn. */
1927 ARMword op1 =
1928 state->
1929 Reg[BITS (0, 3)];
1930 ARMword op2 =
1931 state->
1932 Reg[BITS (8, 11)];
1933 ARMword Rn =
1934 state->
1935 Reg[BITS (12, 15)];
1936
1937 if (BIT (5))
1938 op1 >>= 16;
1939 if (BIT (6))
1940 op2 >>= 16;
1941 op1 &= 0xFFFF;
1942 op2 &= 0xFFFF;
1943 if (op1 & 0x8000)
1944 op1 -= 65536;
1945 if (op2 & 0x8000)
1946 op2 -= 65536;
1947 op1 *= op2;
1948 //printf("SMLA_INST:BB,op1=0x%x, op2=0x%x. Rn=0x%x\n", op1, op2, Rn);
1949 if (AddOverflow
1950 (op1, Rn, op1 + Rn))
1951 SETS;
1952 state->Reg[BITS (16, 19)] =
1953 op1 + Rn;
1954 break;
1955 }
1956
1957 if (BITS (4, 11) == 5) {
1958 /* ElSegundo QADD insn. */
1959 ARMword op1 =
1960 state->
1961 Reg[BITS (0, 3)];
1962 ARMword op2 =
1963 state->
1964 Reg[BITS (16, 19)];
1965 ARMword result = op1 + op2;
1966 if (AddOverflow
1967 (op1, op2, result)) {
1968 result = POS (result)
1969 ? 0x80000000 :
1970 0x7fffffff;
1971 SETS;
1972 }
1973 state->Reg[BITS (12, 15)] =
1974 result;
1975 break;
1976 }
1977 }
1978#ifdef MODET
1979 if (BITS (4, 11) == 0xB) {
1980 /* STRH register offset, no write-back, down, pre indexed. */
1981 SHPREDOWN ();
1982 break;
1983 }
1984 if (BITS (4, 7) == 0xD) {
1985 Handle_Load_Double (state, instr);
1986 break;
1987 }
1988 if (BITS (4, 7) == 0xF) {
1989 Handle_Store_Double (state, instr);
1990 break;
1991 }
1992#endif
1993 if (BITS (4, 11) == 9) {
1994 /* SWP */
1995 UNDEF_SWPPC;
1996 temp = LHS;
1997 BUSUSEDINCPCS;
1998#ifndef MODE32
1999 if (VECTORACCESS (temp)
2000 || ADDREXCEPT (temp)) {
2001 INTERNALABORT (temp);
2002 (void) ARMul_LoadWordN (state,
2003 temp);
2004 (void) ARMul_LoadWordN (state,
2005 temp);
2006 }
2007 else
2008#endif
2009 dest = ARMul_SwapWord (state,
2010 temp,
2011 state->
2012 Reg
2013 [RHSReg]);
2014 if (temp & 3)
2015 DEST = ARMul_Align (state,
2016 temp,
2017 dest);
2018 else
2019 DEST = dest;
2020 if (state->abortSig || state->Aborted)
2021 TAKEABORT;
2022 }
2023 else if ((BITS (0, 11) == 0) && (LHSReg == 15)) { /* MRS CPSR */
2024 UNDEF_MRSPC;
2025 DEST = ECC | EINT | EMODE;
2026 }
2027 else {
2028 UNDEF_Test;
2029 }
2030 break;
2031
2032 case 0x11: /* TSTP reg */
2033#ifdef MODET
2034 if ((BITS (4, 11) & 0xF9) == 0x9)
2035 /* LDR register offset, no write-back, down, pre indexed. */
2036 LHPREDOWN ();
2037 /* Continue with remaining instruction decode. */
2038#endif
2039 if (DESTReg == 15) {
2040 /* TSTP reg */
2041#ifdef MODE32
2042 //chy 2006-02-15 if in user mode, can not set cpsr 0:23
2043 //from p165 of ARMARM book
2044 state->Cpsr = GETSPSR (state->Bank);
2045 ARMul_CPSRAltered (state);
2046#else
2047 rhs = DPRegRHS;
2048 temp = LHS & rhs;
2049 SETR15PSR (temp);
2050#endif
2051 }
2052 else {
2053 /* TST reg */
2054 rhs = DPSRegRHS;
2055 dest = LHS & rhs;
2056 ARMul_NegZero (state, dest);
2057 }
2058 break;
2059
2060 case 0x12: /* TEQ reg and MSR reg to CPSR (ARM6). */
2061
2062 if (state->is_v5) {
2063 if (BITS (4, 7) == 3) {
2064 /* BLX(2) */
2065 ARMword temp;
2066
2067 if (TFLAG)
2068 temp = (pc + 2) | 1;
2069 else
2070 temp = pc + 4;
2071
2072 WriteR15Branch (state,
2073 state->
2074 Reg[RHSReg]);
2075 state->Reg[14] = temp;
2076 break;
2077 }
2078 }
2079
2080 if (state->is_v5e) {
2081 if (BIT (4) == 0 && BIT (7) == 1
2082 && (BIT (5) == 0
2083 || BITS (12, 15) == 0)) {
2084 /* ElSegundo SMLAWy/SMULWy insn. */
2085 unsigned long long op1 =
2086 state->
2087 Reg[BITS (0, 3)];
2088 unsigned long long op2 =
2089 state->
2090 Reg[BITS (8, 11)];
2091 unsigned long long result;
2092
2093 if (BIT (6))
2094 op2 >>= 16;
2095 if (op1 & 0x80000000)
2096 op1 -= 1ULL << 32;
2097 op2 &= 0xFFFF;
2098 if (op2 & 0x8000)
2099 op2 -= 65536;
2100 result = (op1 * op2) >> 16;
2101
2102 if (BIT (5) == 0) {
2103 ARMword Rn =
2104 state->
2105 Reg[BITS
2106 (12, 15)];
2107
2108 if (AddOverflow
2109 (result, Rn,
2110 result + Rn))
2111 SETS;
2112 result += Rn;
2113 }
2114 state->Reg[BITS (16, 19)] =
2115 result;
2116 break;
2117 }
2118
2119 if (BITS (4, 11) == 5) {
2120 /* ElSegundo QSUB insn. */
2121 ARMword op1 =
2122 state->
2123 Reg[BITS (0, 3)];
2124 ARMword op2 =
2125 state->
2126 Reg[BITS (16, 19)];
2127 ARMword result = op1 - op2;
2128
2129 if (SubOverflow
2130 (op1, op2, result)) {
2131 result = POS (result)
2132 ? 0x80000000 :
2133 0x7fffffff;
2134 SETS;
2135 }
2136
2137 state->Reg[BITS (12, 15)] =
2138 result;
2139 break;
2140 }
2141 }
2142#ifdef MODET
2143 if (BITS (4, 11) == 0xB) {
2144 /* STRH register offset, write-back, down, pre indexed. */
2145 SHPREDOWNWB ();
2146 break;
2147 }
2148 if (BITS (4, 27) == 0x12FFF1) {
2149 /* BX */
2150 WriteR15Branch (state,
2151 state->Reg[RHSReg]);
2152 break;
2153 }
2154 if (BITS (4, 7) == 0xD) {
2155 Handle_Load_Double (state, instr);
2156 break;
2157 }
2158 if (BITS (4, 7) == 0xF) {
2159 Handle_Store_Double (state, instr);
2160 break;
2161 }
2162#endif
2163 if (state->is_v5) {
2164 if (BITS (4, 7) == 0x7) {
2165 ARMword value;
2166 extern int
2167 SWI_vector_installed;
2168
2169 /* Hardware is allowed to optionally override this
2170 instruction and treat it as a breakpoint. Since
2171 this is a simulator not hardware, we take the position
2172 that if a SWI vector was not installed, then an Abort
2173 vector was probably not installed either, and so
2174 normally this instruction would be ignored, even if an
2175 Abort is generated. This is a bad thing, since GDB
2176 uses this instruction for its breakpoints (at least in
2177 Thumb mode it does). So intercept the instruction here
2178 and generate a breakpoint SWI instead. */
2179 if (!SWI_vector_installed)
2180 ARMul_OSHandleSWI
2181 (state,
2182 SWI_Breakpoint);
2183 else {
2184 /* BKPT - normally this will cause an abort, but on the
2185 XScale we must check the DCSR. */
2186 XScale_set_fsr_far
2187 (state,
2188 ARMul_CP15_R5_MMU_EXCPT,
2189 pc);
2190 //if (!XScale_debug_moe
2191 // (state,
2192 // ARMul_CP14_R10_MOE_BT))
2193 // break; // Disabled /bunnei
2194 }
2195
2196 /* Force the next instruction to be refetched. */
2197 state->NextInstr = RESUME;
2198 break;
2199 }
2200 }
2201 if (DESTReg == 15) {
2202 /* MSR reg to CPSR. */
2203 UNDEF_MSRPC;
2204 temp = DPRegRHS;
2205#ifdef MODET
2206 /* Don't allow TBIT to be set by MSR. */
2207 temp &= ~TBIT;
2208#endif
2209 ARMul_FixCPSR (state, instr, temp);
2210 }
2211 else
2212 UNDEF_Test;
2213
2214 break;
2215
2216 case 0x13: /* TEQP reg */
2217#ifdef MODET
2218 if ((BITS (4, 11) & 0xF9) == 0x9)
2219 /* LDR register offset, write-back, down, pre indexed. */
2220 LHPREDOWNWB ();
2221 /* Continue with remaining instruction decode. */
2222#endif
2223 if (DESTReg == 15) {
2224 /* TEQP reg */
2225#ifdef MODE32
2226 state->Cpsr = GETSPSR (state->Bank);
2227 ARMul_CPSRAltered (state);
2228#else
2229 rhs = DPRegRHS;
2230 temp = LHS ^ rhs;
2231 SETR15PSR (temp);
2232#endif
2233 }
2234 else {
2235 /* TEQ Reg. */
2236 rhs = DPSRegRHS;
2237 dest = LHS ^ rhs;
2238 ARMul_NegZero (state, dest);
2239 }
2240 break;
2241
2242 case 0x14: /* CMP reg and MRS SPSR and SWP byte. */
2243 if (state->is_v5e) {
2244 if (BIT (4) == 0 && BIT (7) == 1) {
2245 /* ElSegundo SMLALxy insn. */
2246 unsigned long long op1 =
2247 state->
2248 Reg[BITS (0, 3)];
2249 unsigned long long op2 =
2250 state->
2251 Reg[BITS (8, 11)];
2252 unsigned long long dest;
2253 unsigned long long result;
2254
2255 if (BIT (5))
2256 op1 >>= 16;
2257 if (BIT (6))
2258 op2 >>= 16;
2259 op1 &= 0xFFFF;
2260 if (op1 & 0x8000)
2261 op1 -= 65536;
2262 op2 &= 0xFFFF;
2263 if (op2 & 0x8000)
2264 op2 -= 65536;
2265
2266 dest = (unsigned long long)
2267 state->
2268 Reg[BITS (16, 19)] <<
2269 32;
2270 dest |= state->
2271 Reg[BITS (12, 15)];
2272 dest += op1 * op2;
2273 state->Reg[BITS (12, 15)] =
2274 dest;
2275 state->Reg[BITS (16, 19)] =
2276 dest >> 32;
2277 break;
2278 }
2279
2280 if (BITS (4, 11) == 5) {
2281 /* ElSegundo QDADD insn. */
2282 ARMword op1 =
2283 state->
2284 Reg[BITS (0, 3)];
2285 ARMword op2 =
2286 state->
2287 Reg[BITS (16, 19)];
2288 ARMword op2d = op2 + op2;
2289 ARMword result;
2290
2291 if (AddOverflow
2292 (op2, op2, op2d)) {
2293 SETS;
2294 op2d = POS (op2d) ?
2295 0x80000000 :
2296 0x7fffffff;
2297 }
2298
2299 result = op1 + op2d;
2300 if (AddOverflow
2301 (op1, op2d, result)) {
2302 SETS;
2303 result = POS (result)
2304 ? 0x80000000 :
2305 0x7fffffff;
2306 }
2307
2308 state->Reg[BITS (12, 15)] =
2309 result;
2310 break;
2311 }
2312 }
2313#ifdef MODET
2314 if (BITS (4, 7) == 0xB) {
2315 /* STRH immediate offset, no write-back, down, pre indexed. */
2316 SHPREDOWN ();
2317 break;
2318 }
2319 if (BITS (4, 7) == 0xD) {
2320 Handle_Load_Double (state, instr);
2321 break;
2322 }
2323 if (BITS (4, 7) == 0xF) {
2324 Handle_Store_Double (state, instr);
2325 break;
2326 }
2327#endif
2328 if (BITS (4, 11) == 9) {
2329 /* SWP */
2330 UNDEF_SWPPC;
2331 temp = LHS;
2332 BUSUSEDINCPCS;
2333#ifndef MODE32
2334 if (VECTORACCESS (temp)
2335 || ADDREXCEPT (temp)) {
2336 INTERNALABORT (temp);
2337 (void) ARMul_LoadByte (state,
2338 temp);
2339 (void) ARMul_LoadByte (state,
2340 temp);
2341 }
2342 else
2343#endif
2344 DEST = ARMul_SwapByte (state,
2345 temp,
2346 state->
2347 Reg
2348 [RHSReg]);
2349 if (state->abortSig || state->Aborted)
2350 TAKEABORT;
2351 }
2352 else if ((BITS (0, 11) == 0)
2353 && (LHSReg == 15)) {
2354 /* MRS SPSR */
2355 UNDEF_MRSPC;
2356 DEST = GETSPSR (state->Bank);
2357 }
2358 else
2359 UNDEF_Test;
2360
2361 break;
2362
2363 case 0x15: /* CMPP reg. */
2364#ifdef MODET
2365 if ((BITS (4, 7) & 0x9) == 0x9)
2366 /* LDR immediate offset, no write-back, down, pre indexed. */
2367 LHPREDOWN ();
2368 /* Continue with remaining instruction decode. */
2369#endif
2370 if (DESTReg == 15) {
2371 /* CMPP reg. */
2372#ifdef MODE32
2373 state->Cpsr = GETSPSR (state->Bank);
2374 ARMul_CPSRAltered (state);
2375#else
2376 rhs = DPRegRHS;
2377 temp = LHS - rhs;
2378 SETR15PSR (temp);
2379#endif
2380 }
2381 else {
2382 /* CMP reg. */
2383 lhs = LHS;
2384 rhs = DPRegRHS;
2385 dest = lhs - rhs;
2386 ARMul_NegZero (state, dest);
2387 if ((lhs >= rhs)
2388 || ((rhs | lhs) >> 31)) {
2389 ARMul_SubCarry (state, lhs,
2390 rhs, dest);
2391 ARMul_SubOverflow (state, lhs,
2392 rhs, dest);
2393 }
2394 else {
2395 CLEARC;
2396 CLEARV;
2397 }
2398 }
2399 break;
2400
2401 case 0x16: /* CMN reg and MSR reg to SPSR */
2402 if (state->is_v5e) {
2403 if (BIT (4) == 0 && BIT (7) == 1
2404 && BITS (12, 15) == 0) {
2405 /* ElSegundo SMULxy insn. */
2406 ARMword op1 =
2407 state->
2408 Reg[BITS (0, 3)];
2409 ARMword op2 =
2410 state->
2411 Reg[BITS (8, 11)];
2412 ARMword Rn =
2413 state->
2414 Reg[BITS (12, 15)];
2415
2416 if (BIT (5))
2417 op1 >>= 16;
2418 if (BIT (6))
2419 op2 >>= 16;
2420 op1 &= 0xFFFF;
2421 op2 &= 0xFFFF;
2422 if (op1 & 0x8000)
2423 op1 -= 65536;
2424 if (op2 & 0x8000)
2425 op2 -= 65536;
2426
2427 state->Reg[BITS (16, 19)] =
2428 op1 * op2;
2429 break;
2430 }
2431
2432 if (BITS (4, 11) == 5) {
2433 /* ElSegundo QDSUB insn. */
2434 ARMword op1 =
2435 state->
2436 Reg[BITS (0, 3)];
2437 ARMword op2 =
2438 state->
2439 Reg[BITS (16, 19)];
2440 ARMword op2d = op2 + op2;
2441 ARMword result;
2442
2443 if (AddOverflow
2444 (op2, op2, op2d)) {
2445 SETS;
2446 op2d = POS (op2d) ?
2447 0x80000000 :
2448 0x7fffffff;
2449 }
2450
2451 result = op1 - op2d;
2452 if (SubOverflow
2453 (op1, op2d, result)) {
2454 SETS;
2455 result = POS (result)
2456 ? 0x80000000 :
2457 0x7fffffff;
2458 }
2459
2460 state->Reg[BITS (12, 15)] =
2461 result;
2462 break;
2463 }
2464 }
2465
2466 if (state->is_v5) {
2467 if (BITS (4, 11) == 0xF1
2468 && BITS (16, 19) == 0xF) {
2469 /* ARM5 CLZ insn. */
2470 ARMword op1 =
2471 state->
2472 Reg[BITS (0, 3)];
2473 int result = 32;
2474
2475 if (op1)
2476 for (result = 0;
2477 (op1 &
2478 0x80000000) ==
2479 0; op1 <<= 1)
2480 result++;
2481 state->Reg[BITS (12, 15)] =
2482 result;
2483 break;
2484 }
2485 }
2486
2487#ifdef MODET
2488 if (BITS (4, 7) == 0xB) {
2489 /* STRH immediate offset, write-back, down, pre indexed. */
2490 SHPREDOWNWB ();
2491 break;
2492 }
2493 if (BITS (4, 7) == 0xD) {
2494 Handle_Load_Double (state, instr);
2495 break;
2496 }
2497 if (BITS (4, 7) == 0xF) {
2498 Handle_Store_Double (state, instr);
2499 break;
2500 }
2501#endif
2502 if (DESTReg == 15) {
2503 /* MSR */
2504 UNDEF_MSRPC;
2505 ARMul_FixSPSR (state, instr,
2506 DPRegRHS);
2507 }
2508 else {
2509 UNDEF_Test;
2510 }
2511 break;
2512
2513 case 0x17: /* CMNP reg */
2514#ifdef MODET
2515 if ((BITS (4, 7) & 0x9) == 0x9)
2516 /* LDR immediate offset, write-back, down, pre indexed. */
2517 LHPREDOWNWB ();
2518 /* Continue with remaining instruction decoding. */
2519#endif
2520 if (DESTReg == 15) {
2521#ifdef MODE32
2522 state->Cpsr = GETSPSR (state->Bank);
2523 ARMul_CPSRAltered (state);
2524#else
2525 rhs = DPRegRHS;
2526 temp = LHS + rhs;
2527 SETR15PSR (temp);
2528#endif
2529 break;
2530 }
2531 else {
2532 /* CMN reg. */
2533 lhs = LHS;
2534 rhs = DPRegRHS;
2535 dest = lhs + rhs;
2536 ASSIGNZ (dest == 0);
2537 if ((lhs | rhs) >> 30) {
2538 /* Possible C,V,N to set. */
2539 ASSIGNN (NEG (dest));
2540 ARMul_AddCarry (state, lhs,
2541 rhs, dest);
2542 ARMul_AddOverflow (state, lhs,
2543 rhs, dest);
2544 }
2545 else {
2546 CLEARN;
2547 CLEARC;
2548 CLEARV;
2549 }
2550 }
2551 break;
2552
2553 case 0x18: /* ORR reg */
2554#ifdef MODET
2555 /* dyf add armv6 instr strex 2010.9.17 */
2556 if (state->is_v6) {
2557 if (BITS (4, 7) == 0x9)
2558 if (handle_v6_insn (state, instr))
2559 break;
2560 }
2561
2562 if (BITS (4, 11) == 0xB) {
2563 /* STRH register offset, no write-back, up, pre indexed. */
2564 SHPREUP ();
2565 break;
2566 }
2567 if (BITS (4, 7) == 0xD) {
2568 Handle_Load_Double (state, instr);
2569 break;
2570 }
2571 if (BITS (4, 7) == 0xF) {
2572 Handle_Store_Double (state, instr);
2573 break;
2574 }
2575#endif
2576 rhs = DPRegRHS;
2577 dest = LHS | rhs;
2578 WRITEDEST (dest);
2579 break;
2580
2581 case 0x19: /* ORRS reg */
2582#ifdef MODET
2583 /* dyf add armv6 instr ldrex */
2584 if (state->is_v6) {
2585 if (BITS (4, 7) == 0x9) {
2586 if (handle_v6_insn (state, instr))
2587 break;
2588 }
2589 }
2590 if ((BITS (4, 11) & 0xF9) == 0x9)
2591 /* LDR register offset, no write-back, up, pre indexed. */
2592 LHPREUP ();
2593 /* Continue with remaining instruction decoding. */
2594#endif
2595 rhs = DPSRegRHS;
2596 dest = LHS | rhs;
2597 WRITESDEST (dest);
2598 break;
2599
2600 case 0x1a: /* MOV reg */
2601#ifdef MODET
2602 if (BITS (4, 11) == 0xB) {
2603 /* STRH register offset, write-back, up, pre indexed. */
2604 SHPREUPWB ();
2605 break;
2606 }
2607 if (BITS (4, 7) == 0xD) {
2608 Handle_Load_Double (state, instr);
2609 break;
2610 }
2611 if (BITS (4, 7) == 0xF) {
2612 Handle_Store_Double (state, instr);
2613 break;
2614 }
2615#endif
2616 dest = DPRegRHS;
2617 WRITEDEST (dest);
2618 break;
2619
2620 case 0x1b: /* MOVS reg */
2621#ifdef MODET
2622 if ((BITS (4, 11) & 0xF9) == 0x9)
2623 /* LDR register offset, write-back, up, pre indexed. */
2624 LHPREUPWB ();
2625 /* Continue with remaining instruction decoding. */
2626#endif
2627 dest = DPSRegRHS;
2628 WRITESDEST (dest);
2629 break;
2630
2631 case 0x1c: /* BIC reg */
2632#ifdef MODET
2633 /* dyf add for STREXB */
2634 if (state->is_v6) {
2635 if (BITS (4, 7) == 0x9) {
2636 if (handle_v6_insn (state, instr))
2637 break;
2638 }
2639 }
2640 if (BITS (4, 7) == 0xB) {
2641 /* STRH immediate offset, no write-back, up, pre indexed. */
2642 SHPREUP ();
2643 break;
2644 }
2645 if (BITS (4, 7) == 0xD) {
2646 Handle_Load_Double (state, instr);
2647 break;
2648 }
2649 else if (BITS (4, 7) == 0xF) {
2650 Handle_Store_Double (state, instr);
2651 break;
2652 }
2653#endif
2654 rhs = DPRegRHS;
2655 dest = LHS & ~rhs;
2656 WRITEDEST (dest);
2657 break;
2658
2659 case 0x1d: /* BICS reg */
2660#ifdef MODET
2661 /* ladsh P=1 U=1 W=0 L=1 S=1 H=1 */
2662 if (BITS(4, 7) == 0xF) {
2663 temp = LHS + GetLS7RHS (state, instr);
2664 LoadHalfWord (state, instr, temp, LSIGNED);
2665 break;
2666
2667 }
2668 if (BITS (4, 7) == 0xb) {
2669 /* LDRH immediate offset, no write-back, up, pre indexed. */
2670 temp = LHS + GetLS7RHS (state, instr);
2671 LoadHalfWord (state, instr, temp, LUNSIGNED);
2672 break;
2673 }
2674 if (BITS (4, 7) == 0xd) {
2675 // alex-ykl fix: 2011-07-20 missing ldrsb instruction
2676 temp = LHS + GetLS7RHS (state, instr);
2677 LoadByte (state, instr, temp, LSIGNED);
2678 break;
2679 }
2680
2681 /* Continue with instruction decoding. */
2682 /*if ((BITS (4, 7) & 0x9) == 0x9) */
2683 if ((BITS (4, 7)) == 0x9) {
2684 /* ldrexb */
2685 if (state->is_v6) {
2686 if (handle_v6_insn (state, instr))
2687 break;
2688 }
2689 /* LDR immediate offset, no write-back, up, pre indexed. */
2690 LHPREUP ();
2691
2692 }
2693
2694#endif
2695 rhs = DPSRegRHS;
2696 dest = LHS & ~rhs;
2697 WRITESDEST (dest);
2698 break;
2699
2700 case 0x1e: /* MVN reg */
2701#ifdef MODET
2702 if (BITS (4, 7) == 0xB) {
2703 /* STRH immediate offset, write-back, up, pre indexed. */
2704 SHPREUPWB ();
2705 break;
2706 }
2707 if (BITS (4, 7) == 0xD) {
2708 Handle_Load_Double (state, instr);
2709 break;
2710 }
2711 if (BITS (4, 7) == 0xF) {
2712 Handle_Store_Double (state, instr);
2713 break;
2714 }
2715#endif
2716 dest = ~DPRegRHS;
2717 WRITEDEST (dest);
2718 break;
2719
2720 case 0x1f: /* MVNS reg */
2721#ifdef MODET
2722 if ((BITS (4, 7) & 0x9) == 0x9)
2723 /* LDR immediate offset, write-back, up, pre indexed. */
2724 LHPREUPWB ();
2725 /* Continue instruction decoding. */
2726#endif
2727 dest = ~DPSRegRHS;
2728 WRITESDEST (dest);
2729 break;
2730
2731
2732 /* Data Processing Immediate RHS Instructions. */
2733
2734 case 0x20: /* AND immed */
2735 dest = LHS & DPImmRHS;
2736 WRITEDEST (dest);
2737 break;
2738
2739 case 0x21: /* ANDS immed */
2740 DPSImmRHS;
2741 dest = LHS & rhs;
2742 WRITESDEST (dest);
2743 break;
2744
2745 case 0x22: /* EOR immed */
2746 dest = LHS ^ DPImmRHS;
2747 WRITEDEST (dest);
2748 break;
2749
2750 case 0x23: /* EORS immed */
2751 DPSImmRHS;
2752 dest = LHS ^ rhs;
2753 WRITESDEST (dest);
2754 break;
2755
2756 case 0x24: /* SUB immed */
2757 dest = LHS - DPImmRHS;
2758 WRITEDEST (dest);
2759 break;
2760
2761 case 0x25: /* SUBS immed */
2762 lhs = LHS;
2763 rhs = DPImmRHS;
2764 dest = lhs - rhs;
2765
2766 if ((lhs >= rhs) || ((rhs | lhs) >> 31)) {
2767 ARMul_SubCarry (state, lhs, rhs,
2768 dest);
2769 ARMul_SubOverflow (state, lhs, rhs,
2770 dest);
2771 }
2772 else {
2773 CLEARC;
2774 CLEARV;
2775 }
2776 WRITESDEST (dest);
2777 break;
2778
2779 case 0x26: /* RSB immed */
2780 dest = DPImmRHS - LHS;
2781 WRITEDEST (dest);
2782 break;
2783
2784 case 0x27: /* RSBS immed */
2785 lhs = LHS;
2786 rhs = DPImmRHS;
2787 dest = rhs - lhs;
2788
2789 if ((rhs >= lhs) || ((rhs | lhs) >> 31)) {
2790 ARMul_SubCarry (state, rhs, lhs,
2791 dest);
2792 ARMul_SubOverflow (state, rhs, lhs,
2793 dest);
2794 }
2795 else {
2796 CLEARC;
2797 CLEARV;
2798 }
2799 WRITESDEST (dest);
2800 break;
2801
2802 case 0x28: /* ADD immed */
2803 dest = LHS + DPImmRHS;
2804 WRITEDEST (dest);
2805 break;
2806
2807 case 0x29: /* ADDS immed */
2808 lhs = LHS;
2809 rhs = DPImmRHS;
2810 dest = lhs + rhs;
2811 ASSIGNZ (dest == 0);
2812
2813 if ((lhs | rhs) >> 30) {
2814 /* Possible C,V,N to set. */
2815 ASSIGNN (NEG (dest));
2816 ARMul_AddCarry (state, lhs, rhs,
2817 dest);
2818 ARMul_AddOverflow (state, lhs, rhs,
2819 dest);
2820 }
2821 else {
2822 CLEARN;
2823 CLEARC;
2824 CLEARV;
2825 }
2826 WRITESDEST (dest);
2827 break;
2828
2829 case 0x2a: /* ADC immed */
2830 dest = LHS + DPImmRHS + CFLAG;
2831 WRITEDEST (dest);
2832 break;
2833
2834 case 0x2b: /* ADCS immed */
2835 lhs = LHS;
2836 rhs = DPImmRHS;
2837 dest = lhs + rhs + CFLAG;
2838 ASSIGNZ (dest == 0);
2839 if ((lhs | rhs) >> 30) {
2840 /* Possible C,V,N to set. */
2841 ASSIGNN (NEG (dest));
2842 ARMul_AddCarry (state, lhs, rhs,
2843 dest);
2844 ARMul_AddOverflow (state, lhs, rhs,
2845 dest);
2846 }
2847 else {
2848 CLEARN;
2849 CLEARC;
2850 CLEARV;
2851 }
2852 WRITESDEST (dest);
2853 break;
2854
2855 case 0x2c: /* SBC immed */
2856 dest = LHS - DPImmRHS - !CFLAG;
2857 WRITEDEST (dest);
2858 break;
2859
2860 case 0x2d: /* SBCS immed */
2861 lhs = LHS;
2862 rhs = DPImmRHS;
2863 dest = lhs - rhs - !CFLAG;
2864 if ((lhs >= rhs) || ((rhs | lhs) >> 31)) {
2865 ARMul_SubCarry (state, lhs, rhs,
2866 dest);
2867 ARMul_SubOverflow (state, lhs, rhs,
2868 dest);
2869 }
2870 else {
2871 CLEARC;
2872 CLEARV;
2873 }
2874 WRITESDEST (dest);
2875 break;
2876
2877 case 0x2e: /* RSC immed */
2878 dest = DPImmRHS - LHS - !CFLAG;
2879 WRITEDEST (dest);
2880 break;
2881
2882 case 0x2f: /* RSCS immed */
2883 lhs = LHS;
2884 rhs = DPImmRHS;
2885 dest = rhs - lhs - !CFLAG;
2886 if ((rhs >= lhs) || ((rhs | lhs) >> 31)) {
2887 ARMul_SubCarry (state, rhs, lhs,
2888 dest);
2889 ARMul_SubOverflow (state, rhs, lhs,
2890 dest);
2891 }
2892 else {
2893 CLEARC;
2894 CLEARV;
2895 }
2896 WRITESDEST (dest);
2897 break;
2898
2899 case 0x30: /* TST immed */
2900 /* shenoubang 2012-3-14*/
2901 if (state->is_v6) { /* movw, ARMV6, ARMv7 */
2902 dest ^= dest;
2903 dest = BITS(16, 19);
2904 dest = ((dest<<12) | BITS(0, 11));
2905 WRITEDEST(dest);
2906 //SKYEYE_DBG("In %s, line = %d, pc = 0x%x, instr = 0x%x, R[0:11]: 0x%x, R[16:19]: 0x%x, R[%d]:0x%x\n",
2907 // __func__, __LINE__, pc, instr, BITS(0, 11), BITS(16, 19), DESTReg, state->Reg[DESTReg]);
2908 break;
2909 }
2910 else {
2911 UNDEF_Test;
2912 break;
2913 }
2914
2915 case 0x31: /* TSTP immed */
2916 if (DESTReg == 15) {
2917 /* TSTP immed. */
2918#ifdef MODE32
2919 state->Cpsr = GETSPSR (state->Bank);
2920 ARMul_CPSRAltered (state);
2921#else
2922 temp = LHS & DPImmRHS;
2923 SETR15PSR (temp);
2924#endif
2925 }
2926 else {
2927 /* TST immed. */
2928 DPSImmRHS;
2929 dest = LHS & rhs;
2930 ARMul_NegZero (state, dest);
2931 }
2932 break;
2933
2934 case 0x32: /* TEQ immed and MSR immed to CPSR */
2935 if (DESTReg == 15)
2936 /* MSR immed to CPSR. */
2937 ARMul_FixCPSR (state, instr,
2938 DPImmRHS);
2939 else
2940 UNDEF_Test;
2941 break;
2942
2943 case 0x33: /* TEQP immed */
2944 if (DESTReg == 15) {
2945 /* TEQP immed. */
2946#ifdef MODE32
2947 state->Cpsr = GETSPSR (state->Bank);
2948 ARMul_CPSRAltered (state);
2949#else
2950 temp = LHS ^ DPImmRHS;
2951 SETR15PSR (temp);
2952#endif
2953 }
2954 else {
2955 DPSImmRHS; /* TEQ immed */
2956 dest = LHS ^ rhs;
2957 ARMul_NegZero (state, dest);
2958 }
2959 break;
2960
2961 case 0x34: /* CMP immed */
2962 UNDEF_Test;
2963 break;
2964
2965 case 0x35: /* CMPP immed */
2966 if (DESTReg == 15) {
2967 /* CMPP immed. */
2968#ifdef MODE32
2969 state->Cpsr = GETSPSR (state->Bank);
2970 ARMul_CPSRAltered (state);
2971#else
2972 temp = LHS - DPImmRHS;
2973 SETR15PSR (temp);
2974#endif
2975 break;
2976 }
2977 else {
2978 /* CMP immed. */
2979 lhs = LHS;
2980 rhs = DPImmRHS;
2981 dest = lhs - rhs;
2982 ARMul_NegZero (state, dest);
2983
2984 if ((lhs >= rhs)
2985 || ((rhs | lhs) >> 31)) {
2986 ARMul_SubCarry (state, lhs,
2987 rhs, dest);
2988 ARMul_SubOverflow (state, lhs,
2989 rhs, dest);
2990 }
2991 else {
2992 CLEARC;
2993 CLEARV;
2994 }
2995 }
2996 break;
2997
2998 case 0x36: /* CMN immed and MSR immed to SPSR */
2999 if (DESTReg == 15)
3000 ARMul_FixSPSR (state, instr,
3001 DPImmRHS);
3002 else
3003 UNDEF_Test;
3004 break;
3005
3006 case 0x37: /* CMNP immed. */
3007 if (DESTReg == 15) {
3008 /* CMNP immed. */
3009#ifdef MODE32
3010 state->Cpsr = GETSPSR (state->Bank);
3011 ARMul_CPSRAltered (state);
3012#else
3013 temp = LHS + DPImmRHS;
3014 SETR15PSR (temp);
3015#endif
3016 break;
3017 }
3018 else {
3019 /* CMN immed. */
3020 lhs = LHS;
3021 rhs = DPImmRHS;
3022 dest = lhs + rhs;
3023 ASSIGNZ (dest == 0);
3024 if ((lhs | rhs) >> 30) {
3025 /* Possible C,V,N to set. */
3026 ASSIGNN (NEG (dest));
3027 ARMul_AddCarry (state, lhs,
3028 rhs, dest);
3029 ARMul_AddOverflow (state, lhs,
3030 rhs, dest);
3031 }
3032 else {
3033 CLEARN;
3034 CLEARC;
3035 CLEARV;
3036 }
3037 }
3038 break;
3039
3040 case 0x38: /* ORR immed. */
3041 dest = LHS | DPImmRHS;
3042 WRITEDEST (dest);
3043 break;
3044
3045 case 0x39: /* ORRS immed. */
3046 DPSImmRHS;
3047 dest = LHS | rhs;
3048 WRITESDEST (dest);
3049 break;
3050
3051 case 0x3a: /* MOV immed. */
3052 dest = DPImmRHS;
3053 WRITEDEST (dest);
3054 break;
3055
3056 case 0x3b: /* MOVS immed. */
3057 DPSImmRHS;
3058 WRITESDEST (rhs);
3059 break;
3060
3061 case 0x3c: /* BIC immed. */
3062 dest = LHS & ~DPImmRHS;
3063 WRITEDEST (dest);
3064 break;
3065
3066 case 0x3d: /* BICS immed. */
3067 DPSImmRHS;
3068 dest = LHS & ~rhs;
3069 WRITESDEST (dest);
3070 break;
3071
3072 case 0x3e: /* MVN immed. */
3073 dest = ~DPImmRHS;
3074 WRITEDEST (dest);
3075 break;
3076
3077 case 0x3f: /* MVNS immed. */
3078 DPSImmRHS;
3079 WRITESDEST (~rhs);
3080 break;
3081
3082
3083 /* Single Data Transfer Immediate RHS Instructions. */
3084
3085 case 0x40: /* Store Word, No WriteBack, Post Dec, Immed. */
3086 lhs = LHS;
3087 if (StoreWord (state, instr, lhs))
3088 LSBase = lhs - LSImmRHS;
3089 break;
3090
3091 case 0x41: /* Load Word, No WriteBack, Post Dec, Immed. */
3092 lhs = LHS;
3093 if (LoadWord (state, instr, lhs))
3094 LSBase = lhs - LSImmRHS;
3095 break;
3096
3097 case 0x42: /* Store Word, WriteBack, Post Dec, Immed. */
3098 UNDEF_LSRBaseEQDestWb;
3099 UNDEF_LSRPCBaseWb;
3100 lhs = LHS;
3101 temp = lhs - LSImmRHS;
3102 state->NtransSig = LOW;
3103 if (StoreWord (state, instr, lhs))
3104 LSBase = temp;
3105 state->NtransSig =
3106 (state->Mode & 3) ? HIGH : LOW;
3107 break;
3108
3109 case 0x43: /* Load Word, WriteBack, Post Dec, Immed. */
3110 UNDEF_LSRBaseEQDestWb;
3111 UNDEF_LSRPCBaseWb;
3112 lhs = LHS;
3113 state->NtransSig = LOW;
3114 if (LoadWord (state, instr, lhs))
3115 LSBase = lhs - LSImmRHS;
3116 state->NtransSig =
3117 (state->Mode & 3) ? HIGH : LOW;
3118 break;
3119
3120 case 0x44: /* Store Byte, No WriteBack, Post Dec, Immed. */
3121 lhs = LHS;
3122 if (StoreByte (state, instr, lhs))
3123 LSBase = lhs - LSImmRHS;
3124 break;
3125
3126 case 0x45: /* Load Byte, No WriteBack, Post Dec, Immed. */
3127 lhs = LHS;
3128 if (LoadByte (state, instr, lhs, LUNSIGNED))
3129 LSBase = lhs - LSImmRHS;
3130 break;
3131
3132 case 0x46: /* Store Byte, WriteBack, Post Dec, Immed. */
3133 UNDEF_LSRBaseEQDestWb;
3134 UNDEF_LSRPCBaseWb;
3135 lhs = LHS;
3136 state->NtransSig = LOW;
3137 if (StoreByte (state, instr, lhs))
3138 LSBase = lhs - LSImmRHS;
3139 state->NtransSig =
3140 (state->Mode & 3) ? HIGH : LOW;
3141 break;
3142
3143 case 0x47: /* Load Byte, WriteBack, Post Dec, Immed. */
3144 UNDEF_LSRBaseEQDestWb;
3145 UNDEF_LSRPCBaseWb;
3146 lhs = LHS;
3147 state->NtransSig = LOW;
3148 if (LoadByte (state, instr, lhs, LUNSIGNED))
3149 LSBase = lhs - LSImmRHS;
3150 state->NtransSig =
3151 (state->Mode & 3) ? HIGH : LOW;
3152 break;
3153
3154 case 0x48: /* Store Word, No WriteBack, Post Inc, Immed. */
3155 lhs = LHS;
3156 if (StoreWord (state, instr, lhs))
3157 LSBase = lhs + LSImmRHS;
3158 break;
3159
3160 case 0x49: /* Load Word, No WriteBack, Post Inc, Immed. */
3161 lhs = LHS;
3162 if (LoadWord (state, instr, lhs))
3163 LSBase = lhs + LSImmRHS;
3164 break;
3165
3166 case 0x4a: /* Store Word, WriteBack, Post Inc, Immed. */
3167 UNDEF_LSRBaseEQDestWb;
3168 UNDEF_LSRPCBaseWb;
3169 lhs = LHS;
3170 state->NtransSig = LOW;
3171 if (StoreWord (state, instr, lhs))
3172 LSBase = lhs + LSImmRHS;
3173 state->NtransSig =
3174 (state->Mode & 3) ? HIGH : LOW;
3175 break;
3176
3177 case 0x4b: /* Load Word, WriteBack, Post Inc, Immed. */
3178 UNDEF_LSRBaseEQDestWb;
3179 UNDEF_LSRPCBaseWb;
3180 lhs = LHS;
3181 state->NtransSig = LOW;
3182 if (LoadWord (state, instr, lhs))
3183 LSBase = lhs + LSImmRHS;
3184 state->NtransSig =
3185 (state->Mode & 3) ? HIGH : LOW;
3186 break;
3187
3188 case 0x4c: /* Store Byte, No WriteBack, Post Inc, Immed. */
3189 lhs = LHS;
3190 if (StoreByte (state, instr, lhs))
3191 LSBase = lhs + LSImmRHS;
3192 break;
3193
3194 case 0x4d: /* Load Byte, No WriteBack, Post Inc, Immed. */
3195 lhs = LHS;
3196 if (LoadByte (state, instr, lhs, LUNSIGNED))
3197 LSBase = lhs + LSImmRHS;
3198 break;
3199
3200 case 0x4e: /* Store Byte, WriteBack, Post Inc, Immed. */
3201 UNDEF_LSRBaseEQDestWb;
3202 UNDEF_LSRPCBaseWb;
3203 lhs = LHS;
3204 state->NtransSig = LOW;
3205 if (StoreByte (state, instr, lhs))
3206 LSBase = lhs + LSImmRHS;
3207 state->NtransSig =
3208 (state->Mode & 3) ? HIGH : LOW;
3209 break;
3210
3211 case 0x4f: /* Load Byte, WriteBack, Post Inc, Immed. */
3212 UNDEF_LSRBaseEQDestWb;
3213 UNDEF_LSRPCBaseWb;
3214 lhs = LHS;
3215 state->NtransSig = LOW;
3216 if (LoadByte (state, instr, lhs, LUNSIGNED))
3217 LSBase = lhs + LSImmRHS;
3218 state->NtransSig =
3219 (state->Mode & 3) ? HIGH : LOW;
3220 break;
3221
3222
3223 case 0x50: /* Store Word, No WriteBack, Pre Dec, Immed. */
3224 (void) StoreWord (state, instr,
3225 LHS - LSImmRHS);
3226 break;
3227
3228 case 0x51: /* Load Word, No WriteBack, Pre Dec, Immed. */
3229 (void) LoadWord (state, instr,
3230 LHS - LSImmRHS);
3231 break;
3232
3233 case 0x52: /* Store Word, WriteBack, Pre Dec, Immed. */
3234 UNDEF_LSRBaseEQDestWb;
3235 UNDEF_LSRPCBaseWb;
3236 temp = LHS - LSImmRHS;
3237 if (StoreWord (state, instr, temp))
3238 LSBase = temp;
3239 break;
3240
3241 case 0x53: /* Load Word, WriteBack, Pre Dec, Immed. */
3242 UNDEF_LSRBaseEQDestWb;
3243 UNDEF_LSRPCBaseWb;
3244 temp = LHS - LSImmRHS;
3245 if (LoadWord (state, instr, temp))
3246 LSBase = temp;
3247 break;
3248
3249 case 0x54: /* Store Byte, No WriteBack, Pre Dec, Immed. */
3250 (void) StoreByte (state, instr,
3251 LHS - LSImmRHS);
3252 break;
3253
3254 case 0x55: /* Load Byte, No WriteBack, Pre Dec, Immed. */
3255 (void) LoadByte (state, instr, LHS - LSImmRHS,
3256 LUNSIGNED);
3257 break;
3258
3259 case 0x56: /* Store Byte, WriteBack, Pre Dec, Immed. */
3260 UNDEF_LSRBaseEQDestWb;
3261 UNDEF_LSRPCBaseWb;
3262 temp = LHS - LSImmRHS;
3263 if (StoreByte (state, instr, temp))
3264 LSBase = temp;
3265 break;
3266
3267 case 0x57: /* Load Byte, WriteBack, Pre Dec, Immed. */
3268 UNDEF_LSRBaseEQDestWb;
3269 UNDEF_LSRPCBaseWb;
3270 temp = LHS - LSImmRHS;
3271 if (LoadByte (state, instr, temp, LUNSIGNED))
3272 LSBase = temp;
3273 break;
3274
3275 case 0x58: /* Store Word, No WriteBack, Pre Inc, Immed. */
3276 (void) StoreWord (state, instr,
3277 LHS + LSImmRHS);
3278 break;
3279
3280 case 0x59: /* Load Word, No WriteBack, Pre Inc, Immed. */
3281 (void) LoadWord (state, instr,
3282 LHS + LSImmRHS);
3283 break;
3284
3285 case 0x5a: /* Store Word, WriteBack, Pre Inc, Immed. */
3286 UNDEF_LSRBaseEQDestWb;
3287 UNDEF_LSRPCBaseWb;
3288 temp = LHS + LSImmRHS;
3289 if (StoreWord (state, instr, temp))
3290 LSBase = temp;
3291 break;
3292
3293 case 0x5b: /* Load Word, WriteBack, Pre Inc, Immed. */
3294 UNDEF_LSRBaseEQDestWb;
3295 UNDEF_LSRPCBaseWb;
3296 temp = LHS + LSImmRHS;
3297 if (LoadWord (state, instr, temp))
3298 LSBase = temp;
3299 break;
3300
3301 case 0x5c: /* Store Byte, No WriteBack, Pre Inc, Immed. */
3302 (void) StoreByte (state, instr,
3303 LHS + LSImmRHS);
3304 break;
3305
3306 case 0x5d: /* Load Byte, No WriteBack, Pre Inc, Immed. */
3307 (void) LoadByte (state, instr, LHS + LSImmRHS,
3308 LUNSIGNED);
3309 break;
3310
3311 case 0x5e: /* Store Byte, WriteBack, Pre Inc, Immed. */
3312 UNDEF_LSRBaseEQDestWb;
3313 UNDEF_LSRPCBaseWb;
3314 temp = LHS + LSImmRHS;
3315 if (StoreByte (state, instr, temp))
3316 LSBase = temp;
3317 break;
3318
3319 case 0x5f: /* Load Byte, WriteBack, Pre Inc, Immed. */
3320 UNDEF_LSRBaseEQDestWb;
3321 UNDEF_LSRPCBaseWb;
3322 temp = LHS + LSImmRHS;
3323 if (LoadByte (state, instr, temp, LUNSIGNED))
3324 LSBase = temp;
3325 break;
3326
3327
3328 /* Single Data Transfer Register RHS Instructions. */
3329
3330 case 0x60: /* Store Word, No WriteBack, Post Dec, Reg. */
3331 if (BIT (4)) {
3332 ARMul_UndefInstr (state, instr);
3333 break;
3334 }
3335 UNDEF_LSRBaseEQOffWb;
3336 UNDEF_LSRBaseEQDestWb;
3337 UNDEF_LSRPCBaseWb;
3338 UNDEF_LSRPCOffWb;
3339 lhs = LHS;
3340 if (StoreWord (state, instr, lhs))
3341 LSBase = lhs - LSRegRHS;
3342 break;
3343
3344 case 0x61: /* Load Word, No WriteBack, Post Dec, Reg. */
3345 if (BIT (4)) {
3346#ifdef MODE32
3347 if (state->is_v6
3348 && handle_v6_insn (state, instr))
3349 break;
3350#endif
3351
3352 ARMul_UndefInstr (state, instr);
3353 break;
3354 }
3355 UNDEF_LSRBaseEQOffWb;
3356 UNDEF_LSRBaseEQDestWb;
3357 UNDEF_LSRPCBaseWb;
3358 UNDEF_LSRPCOffWb;
3359 lhs = LHS;
3360 temp = lhs - LSRegRHS;
3361 if (LoadWord (state, instr, lhs))
3362 LSBase = temp;
3363 break;
3364
3365 case 0x62: /* Store Word, WriteBack, Post Dec, Reg. */
3366 if (BIT (4)) {
3367#ifdef MODE32
3368 if (state->is_v6
3369 && handle_v6_insn (state, instr))
3370 break;
3371#endif
3372
3373 ARMul_UndefInstr (state, instr);
3374 break;
3375 }
3376 UNDEF_LSRBaseEQOffWb;
3377 UNDEF_LSRBaseEQDestWb;
3378 UNDEF_LSRPCBaseWb;
3379 UNDEF_LSRPCOffWb;
3380 lhs = LHS;
3381 state->NtransSig = LOW;
3382 if (StoreWord (state, instr, lhs))
3383 LSBase = lhs - LSRegRHS;
3384 state->NtransSig =
3385 (state->Mode & 3) ? HIGH : LOW;
3386 break;
3387
3388 case 0x63: /* Load Word, WriteBack, Post Dec, Reg. */
3389 if (BIT (4)) {
3390#ifdef MODE32
3391 if (state->is_v6
3392 && handle_v6_insn (state, instr))
3393 break;
3394#endif
3395
3396 ARMul_UndefInstr (state, instr);
3397 break;
3398 }
3399 UNDEF_LSRBaseEQOffWb;
3400 UNDEF_LSRBaseEQDestWb;
3401 UNDEF_LSRPCBaseWb;
3402 UNDEF_LSRPCOffWb;
3403 lhs = LHS;
3404 temp = lhs - LSRegRHS;
3405 state->NtransSig = LOW;
3406 if (LoadWord (state, instr, lhs))
3407 LSBase = temp;
3408 state->NtransSig =
3409 (state->Mode & 3) ? HIGH : LOW;
3410 break;
3411
3412 case 0x64: /* Store Byte, No WriteBack, Post Dec, Reg. */
3413 if (BIT (4)) {
3414 ARMul_UndefInstr (state, instr);
3415 break;
3416 }
3417 UNDEF_LSRBaseEQOffWb;
3418 UNDEF_LSRBaseEQDestWb;
3419 UNDEF_LSRPCBaseWb;
3420 UNDEF_LSRPCOffWb;
3421 lhs = LHS;
3422 if (StoreByte (state, instr, lhs))
3423 LSBase = lhs - LSRegRHS;
3424 break;
3425
3426 case 0x65: /* Load Byte, No WriteBack, Post Dec, Reg. */
3427 if (BIT (4)) {
3428#ifdef MODE32
3429 if (state->is_v6
3430 && handle_v6_insn (state, instr))
3431 break;
3432#endif
3433
3434 ARMul_UndefInstr (state, instr);
3435 break;
3436 }
3437 UNDEF_LSRBaseEQOffWb;
3438 UNDEF_LSRBaseEQDestWb;
3439 UNDEF_LSRPCBaseWb;
3440 UNDEF_LSRPCOffWb;
3441 lhs = LHS;
3442 temp = lhs - LSRegRHS;
3443 if (LoadByte (state, instr, lhs, LUNSIGNED))
3444 LSBase = temp;
3445 break;
3446
3447 case 0x66: /* Store Byte, WriteBack, Post Dec, Reg. */
3448 if (BIT (4)) {
3449#ifdef MODE32
3450 if (state->is_v6
3451 && handle_v6_insn (state, instr))
3452 break;
3453#endif
3454
3455 ARMul_UndefInstr (state, instr);
3456 break;
3457 }
3458 UNDEF_LSRBaseEQOffWb;
3459 UNDEF_LSRBaseEQDestWb;
3460 UNDEF_LSRPCBaseWb;
3461 UNDEF_LSRPCOffWb;
3462 lhs = LHS;
3463 state->NtransSig = LOW;
3464 if (StoreByte (state, instr, lhs))
3465 LSBase = lhs - LSRegRHS;
3466 state->NtransSig =
3467 (state->Mode & 3) ? HIGH : LOW;
3468 break;
3469
3470 case 0x67: /* Load Byte, WriteBack, Post Dec, Reg. */
3471 if (BIT (4)) {
3472#ifdef MODE32
3473 if (state->is_v6
3474 && handle_v6_insn (state, instr))
3475 break;
3476#endif
3477
3478 ARMul_UndefInstr (state, instr);
3479 break;
3480 }
3481 UNDEF_LSRBaseEQOffWb;
3482 UNDEF_LSRBaseEQDestWb;
3483 UNDEF_LSRPCBaseWb;
3484 UNDEF_LSRPCOffWb;
3485 lhs = LHS;
3486 temp = lhs - LSRegRHS;
3487 state->NtransSig = LOW;
3488 if (LoadByte (state, instr, lhs, LUNSIGNED))
3489 LSBase = temp;
3490 state->NtransSig =
3491 (state->Mode & 3) ? HIGH : LOW;
3492 break;
3493
3494 case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */
3495 if (BIT (4)) {
3496#ifdef MODE32
3497 if (state->is_v6
3498 && handle_v6_insn (state, instr))
3499 break;
3500#endif
3501
3502 ARMul_UndefInstr (state, instr);
3503 break;
3504 }
3505 UNDEF_LSRBaseEQOffWb;
3506 UNDEF_LSRBaseEQDestWb;
3507 UNDEF_LSRPCBaseWb;
3508 UNDEF_LSRPCOffWb;
3509 lhs = LHS;
3510 if (StoreWord (state, instr, lhs))
3511 LSBase = lhs + LSRegRHS;
3512 break;
3513
3514 case 0x69: /* Load Word, No WriteBack, Post Inc, Reg. */
3515 if (BIT (4)) {
3516 ARMul_UndefInstr (state, instr);
3517 break;
3518 }
3519 UNDEF_LSRBaseEQOffWb;
3520 UNDEF_LSRBaseEQDestWb;
3521 UNDEF_LSRPCBaseWb;
3522 UNDEF_LSRPCOffWb;
3523 lhs = LHS;
3524 temp = lhs + LSRegRHS;
3525 if (LoadWord (state, instr, lhs))
3526 LSBase = temp;
3527 break;
3528
3529 case 0x6a: /* Store Word, WriteBack, Post Inc, Reg. */
3530 if (BIT (4)) {
3531#ifdef MODE32
3532 if (state->is_v6
3533 && handle_v6_insn (state, instr))
3534 break;
3535#endif
3536
3537 ARMul_UndefInstr (state, instr);
3538 break;
3539 }
3540 UNDEF_LSRBaseEQOffWb;
3541 UNDEF_LSRBaseEQDestWb;
3542 UNDEF_LSRPCBaseWb;
3543 UNDEF_LSRPCOffWb;
3544 lhs = LHS;
3545 state->NtransSig = LOW;
3546 if (StoreWord (state, instr, lhs))
3547 LSBase = lhs + LSRegRHS;
3548 state->NtransSig =
3549 (state->Mode & 3) ? HIGH : LOW;
3550 break;
3551
3552 case 0x6b: /* Load Word, WriteBack, Post Inc, Reg. */
3553 if (BIT (4)) {
3554#ifdef MODE32
3555 if (state->is_v6
3556 && handle_v6_insn (state, instr))
3557 break;
3558#endif
3559
3560 ARMul_UndefInstr (state, instr);
3561 break;
3562 }
3563 UNDEF_LSRBaseEQOffWb;
3564 UNDEF_LSRBaseEQDestWb;
3565 UNDEF_LSRPCBaseWb;
3566 UNDEF_LSRPCOffWb;
3567 lhs = LHS;
3568 temp = lhs + LSRegRHS;
3569 state->NtransSig = LOW;
3570 if (LoadWord (state, instr, lhs))
3571 LSBase = temp;
3572 state->NtransSig =
3573 (state->Mode & 3) ? HIGH : LOW;
3574 break;
3575
3576 case 0x6c: /* Store Byte, No WriteBack, Post Inc, Reg. */
3577 if (BIT (4)) {
3578#ifdef MODE32
3579 if (state->is_v6
3580 && handle_v6_insn (state, instr))
3581 break;
3582#endif
3583
3584 ARMul_UndefInstr (state, instr);
3585 break;
3586 }
3587 UNDEF_LSRBaseEQOffWb;
3588 UNDEF_LSRBaseEQDestWb;
3589 UNDEF_LSRPCBaseWb;
3590 UNDEF_LSRPCOffWb;
3591 lhs = LHS;
3592 if (StoreByte (state, instr, lhs))
3593 LSBase = lhs + LSRegRHS;
3594 break;
3595
3596 case 0x6d: /* Load Byte, No WriteBack, Post Inc, Reg. */
3597 if (BIT (4)) {
3598 ARMul_UndefInstr (state, instr);
3599 break;
3600 }
3601 UNDEF_LSRBaseEQOffWb;
3602 UNDEF_LSRBaseEQDestWb;
3603 UNDEF_LSRPCBaseWb;
3604 UNDEF_LSRPCOffWb;
3605 lhs = LHS;
3606 temp = lhs + LSRegRHS;
3607 if (LoadByte (state, instr, lhs, LUNSIGNED))
3608 LSBase = temp;
3609 break;
3610
3611 case 0x6e: /* Store Byte, WriteBack, Post Inc, Reg. */
3612#if 0
3613 if (state->is_v6) {
3614 int Rm = 0;
3615 /* utxb */
3616 if (BITS(15, 19) == 0xf && BITS(4, 7) == 0x7) {
3617
3618 Rm = (RHS >> (8 * BITS(10, 11))) & 0xff;
3619 DEST = Rm;
3620 }
3621
3622 }
3623#endif
3624 if (BIT (4)) {
3625#ifdef MODE32
3626 if (state->is_v6
3627 && handle_v6_insn (state, instr))
3628 break;
3629#endif
3630
3631 ARMul_UndefInstr (state, instr);
3632 break;
3633 }
3634 UNDEF_LSRBaseEQOffWb;
3635 UNDEF_LSRBaseEQDestWb;
3636 UNDEF_LSRPCBaseWb;
3637 UNDEF_LSRPCOffWb;
3638 lhs = LHS;
3639 state->NtransSig = LOW;
3640 if (StoreByte (state, instr, lhs))
3641 LSBase = lhs + LSRegRHS;
3642 state->NtransSig =
3643 (state->Mode & 3) ? HIGH : LOW;
3644 break;
3645
3646 case 0x6f: /* Load Byte, WriteBack, Post Inc, Reg. */
3647 if (BIT (4)) {
3648#ifdef MODE32
3649 if (state->is_v6
3650 && handle_v6_insn (state, instr))
3651 break;
3652#endif
3653
3654 ARMul_UndefInstr (state, instr);
3655 break;
3656 }
3657 UNDEF_LSRBaseEQOffWb;
3658 UNDEF_LSRBaseEQDestWb;
3659 UNDEF_LSRPCBaseWb;
3660 UNDEF_LSRPCOffWb;
3661 lhs = LHS;
3662 temp = lhs + LSRegRHS;
3663 state->NtransSig = LOW;
3664 if (LoadByte (state, instr, lhs, LUNSIGNED))
3665 LSBase = temp;
3666 state->NtransSig =
3667 (state->Mode & 3) ? HIGH : LOW;
3668 break;
3669
3670
3671 case 0x70: /* Store Word, No WriteBack, Pre Dec, Reg. */
3672 if (BIT (4)) {
3673#ifdef MODE32
3674 if (state->is_v6
3675 && handle_v6_insn (state, instr))
3676 break;
3677#endif
3678
3679 ARMul_UndefInstr (state, instr);
3680 break;
3681 }
3682 (void) StoreWord (state, instr,
3683 LHS - LSRegRHS);
3684 break;
3685
3686 case 0x71: /* Load Word, No WriteBack, Pre Dec, Reg. */
3687 if (BIT (4)) {
3688 ARMul_UndefInstr (state, instr);
3689 break;
3690 }
3691 (void) LoadWord (state, instr,
3692 LHS - LSRegRHS);
3693 break;
3694
3695 case 0x72: /* Store Word, WriteBack, Pre Dec, Reg. */
3696 if (BIT (4)) {
3697 ARMul_UndefInstr (state, instr);
3698 break;
3699 }
3700 UNDEF_LSRBaseEQOffWb;
3701 UNDEF_LSRBaseEQDestWb;
3702 UNDEF_LSRPCBaseWb;
3703 UNDEF_LSRPCOffWb;
3704 temp = LHS - LSRegRHS;
3705 if (StoreWord (state, instr, temp))
3706 LSBase = temp;
3707 break;
3708
3709 case 0x73: /* Load Word, WriteBack, Pre Dec, Reg. */
3710 if (BIT (4)) {
3711 ARMul_UndefInstr (state, instr);
3712 break;
3713 }
3714 UNDEF_LSRBaseEQOffWb;
3715 UNDEF_LSRBaseEQDestWb;
3716 UNDEF_LSRPCBaseWb;
3717 UNDEF_LSRPCOffWb;
3718 temp = LHS - LSRegRHS;
3719 if (LoadWord (state, instr, temp))
3720 LSBase = temp;
3721 break;
3722
3723 case 0x74: /* Store Byte, No WriteBack, Pre Dec, Reg. */
3724 if (BIT (4)) {
3725#ifdef MODE32
3726 if (state->is_v6
3727 && handle_v6_insn (state, instr))
3728 break;
3729#endif
3730
3731 ARMul_UndefInstr (state, instr);
3732 break;
3733 }
3734 (void) StoreByte (state, instr,
3735 LHS - LSRegRHS);
3736 break;
3737
3738 case 0x75: /* Load Byte, No WriteBack, Pre Dec, Reg. */
3739 if (BIT (4)) {
3740#ifdef MODE32
3741 if (state->is_v6
3742 && handle_v6_insn (state, instr))
3743 break;
3744#endif
3745
3746 ARMul_UndefInstr (state, instr);
3747 break;
3748 }
3749 (void) LoadByte (state, instr, LHS - LSRegRHS,
3750 LUNSIGNED);
3751 break;
3752
3753 case 0x76: /* Store Byte, WriteBack, Pre Dec, Reg. */
3754 if (BIT (4)) {
3755 ARMul_UndefInstr (state, instr);
3756 break;
3757 }
3758 UNDEF_LSRBaseEQOffWb;
3759 UNDEF_LSRBaseEQDestWb;
3760 UNDEF_LSRPCBaseWb;
3761 UNDEF_LSRPCOffWb;
3762 temp = LHS - LSRegRHS;
3763 if (StoreByte (state, instr, temp))
3764 LSBase = temp;
3765 break;
3766
3767 case 0x77: /* Load Byte, WriteBack, Pre Dec, Reg. */
3768 if (BIT (4)) {
3769 ARMul_UndefInstr (state, instr);
3770 break;
3771 }
3772 UNDEF_LSRBaseEQOffWb;
3773 UNDEF_LSRBaseEQDestWb;
3774 UNDEF_LSRPCBaseWb;
3775 UNDEF_LSRPCOffWb;
3776 temp = LHS - LSRegRHS;
3777 if (LoadByte (state, instr, temp, LUNSIGNED))
3778 LSBase = temp;
3779 break;
3780
3781 case 0x78: /* Store Word, No WriteBack, Pre Inc, Reg. */
3782 if (BIT (4)) {
3783#ifdef MODE32
3784 if (state->is_v6
3785 && handle_v6_insn (state, instr))
3786 break;
3787#endif
3788
3789 ARMul_UndefInstr (state, instr);
3790 break;
3791 }
3792 (void) StoreWord (state, instr,
3793 LHS + LSRegRHS);
3794 break;
3795
3796 case 0x79: /* Load Word, No WriteBack, Pre Inc, Reg. */
3797 if (BIT (4)) {
3798 ARMul_UndefInstr (state, instr);
3799 break;
3800 }
3801 (void) LoadWord (state, instr,
3802 LHS + LSRegRHS);
3803 break;
3804
3805 case 0x7a: /* Store Word, WriteBack, Pre Inc, Reg. */
3806 if (BIT (4)) {
3807#ifdef MODE32
3808 if (state->is_v6
3809 && handle_v6_insn (state, instr))
3810 break;
3811#endif
3812
3813 ARMul_UndefInstr (state, instr);
3814 break;
3815 }
3816 UNDEF_LSRBaseEQOffWb;
3817 UNDEF_LSRBaseEQDestWb;
3818 UNDEF_LSRPCBaseWb;
3819 UNDEF_LSRPCOffWb;
3820 temp = LHS + LSRegRHS;
3821 if (StoreWord (state, instr, temp))
3822 LSBase = temp;
3823 break;
3824
3825 case 0x7b: /* Load Word, WriteBack, Pre Inc, Reg. */
3826 if (BIT (4)) {
3827 ARMul_UndefInstr (state, instr);
3828 break;
3829 }
3830 UNDEF_LSRBaseEQOffWb;
3831 UNDEF_LSRBaseEQDestWb;
3832 UNDEF_LSRPCBaseWb;
3833 UNDEF_LSRPCOffWb;
3834 temp = LHS + LSRegRHS;
3835 if (LoadWord (state, instr, temp))
3836 LSBase = temp;
3837 break;
3838
3839 case 0x7c: /* Store Byte, No WriteBack, Pre Inc, Reg. */
3840 if (BIT (4)) {
3841#ifdef MODE32
3842 if (state->is_v6
3843 && handle_v6_insn (state, instr))
3844 break;
3845#endif
3846
3847 ARMul_UndefInstr (state, instr);
3848 break;
3849 }
3850 (void) StoreByte (state, instr,
3851 LHS + LSRegRHS);
3852 break;
3853
3854 case 0x7d: /* Load Byte, No WriteBack, Pre Inc, Reg. */
3855 if (BIT (4)) {
3856 ARMul_UndefInstr (state, instr);
3857 break;
3858 }
3859 (void) LoadByte (state, instr, LHS + LSRegRHS,
3860 LUNSIGNED);
3861 break;
3862
3863 case 0x7e: /* Store Byte, WriteBack, Pre Inc, Reg. */
3864 if (BIT (4)) {
3865 ARMul_UndefInstr (state, instr);
3866 break;
3867 }
3868 UNDEF_LSRBaseEQOffWb;
3869 UNDEF_LSRBaseEQDestWb;
3870 UNDEF_LSRPCBaseWb;
3871 UNDEF_LSRPCOffWb;
3872 temp = LHS + LSRegRHS;
3873 if (StoreByte (state, instr, temp))
3874 LSBase = temp;
3875 break;
3876
3877 case 0x7f: /* Load Byte, WriteBack, Pre Inc, Reg. */
3878 if (BIT (4)) {
3879 /* Check for the special breakpoint opcode.
3880 This value should correspond to the value defined
3881 as ARM_BE_BREAKPOINT in gdb/arm/tm-arm.h. */
3882 if (BITS (0, 19) == 0xfdefe) {
3883 if (!ARMul_OSHandleSWI
3884 (state, SWI_Breakpoint))
3885 ARMul_Abort (state,
3886 ARMul_SWIV);
3887 }
3888 else
3889 ARMul_UndefInstr (state,
3890 instr);
3891 break;
3892 }
3893 UNDEF_LSRBaseEQOffWb;
3894 UNDEF_LSRBaseEQDestWb;
3895 UNDEF_LSRPCBaseWb;
3896 UNDEF_LSRPCOffWb;
3897 temp = LHS + LSRegRHS;
3898 if (LoadByte (state, instr, temp, LUNSIGNED))
3899 LSBase = temp;
3900 break;
3901
3902
3903 /* Multiple Data Transfer Instructions. */
3904
3905 case 0x80: /* Store, No WriteBack, Post Dec. */
3906 STOREMULT (instr, LSBase - LSMNumRegs + 4L,
3907 0L);
3908 break;
3909
3910 case 0x81: /* Load, No WriteBack, Post Dec. */
3911 LOADMULT (instr, LSBase - LSMNumRegs + 4L,
3912 0L);
3913 break;
3914
3915 case 0x82: /* Store, WriteBack, Post Dec. */
3916 temp = LSBase - LSMNumRegs;
3917 STOREMULT (instr, temp + 4L, temp);
3918 break;
3919
3920 case 0x83: /* Load, WriteBack, Post Dec. */
3921 temp = LSBase - LSMNumRegs;
3922 LOADMULT (instr, temp + 4L, temp);
3923 break;
3924
3925 case 0x84: /* Store, Flags, No WriteBack, Post Dec. */
3926 STORESMULT (instr, LSBase - LSMNumRegs + 4L,
3927 0L);
3928 break;
3929
3930 case 0x85: /* Load, Flags, No WriteBack, Post Dec. */
3931 LOADSMULT (instr, LSBase - LSMNumRegs + 4L,
3932 0L);
3933 break;
3934
3935 case 0x86: /* Store, Flags, WriteBack, Post Dec. */
3936 temp = LSBase - LSMNumRegs;
3937 STORESMULT (instr, temp + 4L, temp);
3938 break;
3939
3940 case 0x87: /* Load, Flags, WriteBack, Post Dec. */
3941 temp = LSBase - LSMNumRegs;
3942 LOADSMULT (instr, temp + 4L, temp);
3943 break;
3944
3945 case 0x88: /* Store, No WriteBack, Post Inc. */
3946 STOREMULT (instr, LSBase, 0L);
3947 break;
3948
3949 case 0x89: /* Load, No WriteBack, Post Inc. */
3950 LOADMULT (instr, LSBase, 0L);
3951 break;
3952
3953 case 0x8a: /* Store, WriteBack, Post Inc. */
3954 temp = LSBase;
3955 STOREMULT (instr, temp, temp + LSMNumRegs);
3956 break;
3957
3958 case 0x8b: /* Load, WriteBack, Post Inc. */
3959 temp = LSBase;
3960 LOADMULT (instr, temp, temp + LSMNumRegs);
3961 break;
3962
3963 case 0x8c: /* Store, Flags, No WriteBack, Post Inc. */
3964 STORESMULT (instr, LSBase, 0L);
3965 break;
3966
3967 case 0x8d: /* Load, Flags, No WriteBack, Post Inc. */
3968 LOADSMULT (instr, LSBase, 0L);
3969 break;
3970
3971 case 0x8e: /* Store, Flags, WriteBack, Post Inc. */
3972 temp = LSBase;
3973 STORESMULT (instr, temp, temp + LSMNumRegs);
3974 break;
3975
3976 case 0x8f: /* Load, Flags, WriteBack, Post Inc. */
3977 temp = LSBase;
3978 LOADSMULT (instr, temp, temp + LSMNumRegs);
3979 break;
3980
3981 case 0x90: /* Store, No WriteBack, Pre Dec. */
3982 STOREMULT (instr, LSBase - LSMNumRegs, 0L);
3983 break;
3984
3985 case 0x91: /* Load, No WriteBack, Pre Dec. */
3986 LOADMULT (instr, LSBase - LSMNumRegs, 0L);
3987 break;
3988
3989 case 0x92: /* Store, WriteBack, Pre Dec. */
3990 temp = LSBase - LSMNumRegs;
3991 STOREMULT (instr, temp, temp);
3992 break;
3993
3994 case 0x93: /* Load, WriteBack, Pre Dec. */
3995 temp = LSBase - LSMNumRegs;
3996 LOADMULT (instr, temp, temp);
3997 break;
3998
3999 case 0x94: /* Store, Flags, No WriteBack, Pre Dec. */
4000 STORESMULT (instr, LSBase - LSMNumRegs, 0L);
4001 break;
4002
4003 case 0x95: /* Load, Flags, No WriteBack, Pre Dec. */
4004 LOADSMULT (instr, LSBase - LSMNumRegs, 0L);
4005 break;
4006
4007 case 0x96: /* Store, Flags, WriteBack, Pre Dec. */
4008 temp = LSBase - LSMNumRegs;
4009 STORESMULT (instr, temp, temp);
4010 break;
4011
4012 case 0x97: /* Load, Flags, WriteBack, Pre Dec. */
4013 temp = LSBase - LSMNumRegs;
4014 LOADSMULT (instr, temp, temp);
4015 break;
4016
4017 case 0x98: /* Store, No WriteBack, Pre Inc. */
4018 STOREMULT (instr, LSBase + 4L, 0L);
4019 break;
4020
4021 case 0x99: /* Load, No WriteBack, Pre Inc. */
4022 LOADMULT (instr, LSBase + 4L, 0L);
4023 break;
4024
4025 case 0x9a: /* Store, WriteBack, Pre Inc. */
4026 temp = LSBase;
4027 STOREMULT (instr, temp + 4L,
4028 temp + LSMNumRegs);
4029 break;
4030
4031 case 0x9b: /* Load, WriteBack, Pre Inc. */
4032 temp = LSBase;
4033 LOADMULT (instr, temp + 4L,
4034 temp + LSMNumRegs);
4035 break;
4036
4037 case 0x9c: /* Store, Flags, No WriteBack, Pre Inc. */
4038 STORESMULT (instr, LSBase + 4L, 0L);
4039 break;
4040
4041 case 0x9d: /* Load, Flags, No WriteBack, Pre Inc. */
4042 LOADSMULT (instr, LSBase + 4L, 0L);
4043 break;
4044
4045 case 0x9e: /* Store, Flags, WriteBack, Pre Inc. */
4046 temp = LSBase;
4047 STORESMULT (instr, temp + 4L,
4048 temp + LSMNumRegs);
4049 break;
4050
4051 case 0x9f: /* Load, Flags, WriteBack, Pre Inc. */
4052 temp = LSBase;
4053 LOADSMULT (instr, temp + 4L,
4054 temp + LSMNumRegs);
4055 break;
4056
4057
4058 /* Branch forward. */
4059 case 0xa0:
4060 case 0xa1:
4061 case 0xa2:
4062 case 0xa3:
4063 case 0xa4:
4064 case 0xa5:
4065 case 0xa6:
4066 case 0xa7:
4067 state->Reg[15] = pc + 8 + POSBRANCH;
4068 FLUSHPIPE;
4069 break;
4070
4071
4072 /* Branch backward. */
4073 case 0xa8:
4074 case 0xa9:
4075 case 0xaa:
4076 case 0xab:
4077 case 0xac:
4078 case 0xad:
4079 case 0xae:
4080 case 0xaf:
4081 state->Reg[15] = pc + 8 + NEGBRANCH;
4082 FLUSHPIPE;
4083 break;
4084
4085
4086 /* Branch and Link forward. */
4087 case 0xb0:
4088 case 0xb1:
4089 case 0xb2:
4090 case 0xb3:
4091 case 0xb4:
4092 case 0xb5:
4093 case 0xb6:
4094 case 0xb7:
4095 /* Put PC into Link. */
4096#ifdef MODE32
4097 state->Reg[14] = pc + 4;
4098#else
4099 state->Reg[14] =
4100 (pc + 4) | ECC | ER15INT | EMODE;
4101#endif
4102 state->Reg[15] = pc + 8 + POSBRANCH;
4103 FLUSHPIPE;
4104 break;
4105
4106
4107 /* Branch and Link backward. */
4108 case 0xb8:
4109 case 0xb9:
4110 case 0xba:
4111 case 0xbb:
4112 case 0xbc:
4113 case 0xbd:
4114 case 0xbe:
4115 case 0xbf:
4116 /* Put PC into Link. */
4117#ifdef MODE32
4118 state->Reg[14] = pc + 4;
4119#else
4120 state->Reg[14] =
4121 (pc + 4) | ECC | ER15INT | EMODE;
4122#endif
4123 state->Reg[15] = pc + 8 + NEGBRANCH;
4124 FLUSHPIPE;
4125 break;
4126
4127
4128 /* Co-Processor Data Transfers. */
4129 case 0xc4:
4130 if (state->is_v5) {
4131 /* Reading from R15 is UNPREDICTABLE. */
4132 if (BITS (12, 15) == 15
4133 || BITS (16, 19) == 15)
4134 ARMul_UndefInstr (state,
4135 instr);
4136 /* Is access to coprocessor 0 allowed ? */
4137 else if (!CP_ACCESS_ALLOWED
4138 (state, CPNum))
4139 ARMul_UndefInstr (state,
4140 instr);
4141 /* Special treatment for XScale coprocessors. */
4142 else if (state->is_XScale) {
4143 /* Only opcode 0 is supported. */
4144 if (BITS (4, 7) != 0x00)
4145 ARMul_UndefInstr
4146 (state,
4147 instr);
4148 /* Only coporcessor 0 is supported. */
4149 else if (CPNum != 0x00)
4150 ARMul_UndefInstr
4151 (state,
4152 instr);
4153 /* Only accumulator 0 is supported. */
4154 else if (BITS (0, 3) != 0x00)
4155 ARMul_UndefInstr
4156 (state,
4157 instr);
4158 else {
4159 /* XScale MAR insn. Move two registers into accumulator. */
4160 state->Accumulator =
4161 state->
4162 Reg[BITS
4163 (12, 15)];
4164 state->Accumulator +=
4165 (ARMdword)
4166 state->
4167 Reg[BITS
4168 (16,
4169 19)] <<
4170 32;
4171 }
4172 }
4173 else
4174 {
4175 /* MCRR, ARMv5TE and up */
4176 ARMul_MCRR (state, instr, DEST, state->Reg[LHSReg]);
4177 break;
4178 }
4179 }
4180 /* Drop through. */
4181
4182 case 0xc0: /* Store , No WriteBack , Post Dec. */
4183 ARMul_STC (state, instr, LHS);
4184 break;
4185
4186 case 0xc5:
4187 if (state->is_v5) {
4188 /* Writes to R15 are UNPREDICATABLE. */
4189 if (DESTReg == 15 || LHSReg == 15)
4190 ARMul_UndefInstr (state,
4191 instr);
4192 /* Is access to the coprocessor allowed ? */
4193 else if (!CP_ACCESS_ALLOWED
4194 (state, CPNum))
4195 ARMul_UndefInstr (state,
4196 instr);
4197 /* Special handling for XScale coprcoessors. */
4198 else if (state->is_XScale) {
4199 /* Only opcode 0 is supported. */
4200 if (BITS (4, 7) != 0x00)
4201 ARMul_UndefInstr
4202 (state,
4203 instr);
4204 /* Only coprocessor 0 is supported. */
4205 else if (CPNum != 0x00)
4206 ARMul_UndefInstr
4207 (state,
4208 instr);
4209 /* Only accumulator 0 is supported. */
4210 else if (BITS (0, 3) != 0x00)
4211 ARMul_UndefInstr
4212 (state,
4213 instr);
4214 else {
4215 /* XScale MRA insn. Move accumulator into two registers. */
4216 ARMword t1 =
4217 (state->
4218 Accumulator
4219 >> 32) & 255;
4220
4221 if (t1 & 128)
4222 t1 -= 256;
4223
4224 state->Reg[BITS
4225 (12, 15)] =
4226 state->
4227 Accumulator;
4228 state->Reg[BITS
4229 (16, 19)] =
4230 t1;
4231 break;
4232 }
4233 }
4234 else
4235 {
4236 /* MRRC, ARMv5TE and up */
4237 ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg]));
4238 break;
4239 }
4240 }
4241 /* Drop through. */
4242
4243 case 0xc1: /* Load , No WriteBack , Post Dec. */
4244 ARMul_LDC (state, instr, LHS);
4245 break;
4246
4247 case 0xc2:
4248 case 0xc6: /* Store , WriteBack , Post Dec. */
4249 lhs = LHS;
4250 state->Base = lhs - LSCOff;
4251 ARMul_STC (state, instr, lhs);
4252 break;
4253
4254 case 0xc3:
4255 case 0xc7: /* Load , WriteBack , Post Dec. */
4256 lhs = LHS;
4257 state->Base = lhs - LSCOff;
4258 ARMul_LDC (state, instr, lhs);
4259 break;
4260
4261 case 0xc8:
4262 case 0xcc: /* Store , No WriteBack , Post Inc. */
4263 ARMul_STC (state, instr, LHS);
4264 break;
4265
4266 case 0xc9:
4267 case 0xcd: /* Load , No WriteBack , Post Inc. */
4268 ARMul_LDC (state, instr, LHS);
4269 break;
4270
4271 case 0xca:
4272 case 0xce: /* Store , WriteBack , Post Inc. */
4273 lhs = LHS;
4274 state->Base = lhs + LSCOff;
4275 ARMul_STC (state, instr, LHS);
4276 break;
4277
4278 case 0xcb:
4279 case 0xcf: /* Load , WriteBack , Post Inc. */
4280 lhs = LHS;
4281 state->Base = lhs + LSCOff;
4282 ARMul_LDC (state, instr, LHS);
4283 break;
4284
4285 case 0xd0:
4286 case 0xd4: /* Store , No WriteBack , Pre Dec. */
4287 ARMul_STC (state, instr, LHS - LSCOff);
4288 break;
4289
4290 case 0xd1:
4291 case 0xd5: /* Load , No WriteBack , Pre Dec. */
4292 ARMul_LDC (state, instr, LHS - LSCOff);
4293 break;
4294
4295 case 0xd2:
4296 case 0xd6: /* Store , WriteBack , Pre Dec. */
4297 lhs = LHS - LSCOff;
4298 state->Base = lhs;
4299 ARMul_STC (state, instr, lhs);
4300 break;
4301
4302 case 0xd3:
4303 case 0xd7: /* Load , WriteBack , Pre Dec. */
4304 lhs = LHS - LSCOff;
4305 state->Base = lhs;
4306 ARMul_LDC (state, instr, lhs);
4307 break;
4308
4309 case 0xd8:
4310 case 0xdc: /* Store , No WriteBack , Pre Inc. */
4311 ARMul_STC (state, instr, LHS + LSCOff);
4312 break;
4313
4314 case 0xd9:
4315 case 0xdd: /* Load , No WriteBack , Pre Inc. */
4316 ARMul_LDC (state, instr, LHS + LSCOff);
4317 break;
4318
4319 case 0xda:
4320 case 0xde: /* Store , WriteBack , Pre Inc. */
4321 lhs = LHS + LSCOff;
4322 state->Base = lhs;
4323 ARMul_STC (state, instr, lhs);
4324 break;
4325
4326 case 0xdb:
4327 case 0xdf: /* Load , WriteBack , Pre Inc. */
4328 lhs = LHS + LSCOff;
4329 state->Base = lhs;
4330 ARMul_LDC (state, instr, lhs);
4331 break;
4332
4333
4334 /* Co-Processor Register Transfers (MCR) and Data Ops. */
4335
4336 case 0xe2:
4337 if (!CP_ACCESS_ALLOWED (state, CPNum)) {
4338 ARMul_UndefInstr (state, instr);
4339 break;
4340 }
4341 if (state->is_XScale)
4342 switch (BITS (18, 19)) {
4343 case 0x0:
4344 if (BITS (4, 11) == 1
4345 && BITS (16, 17) == 0) {
4346 /* XScale MIA instruction. Signed multiplication of
4347 two 32 bit values and addition to 40 bit accumulator. */
4348 long long Rm =
4349 state->
4350 Reg
4351 [MULLHSReg];
4352 long long Rs =
4353 state->
4354 Reg
4355 [MULACCReg];
4356
4357 if (Rm & (1 << 31))
4358 Rm -= 1ULL <<
4359 32;
4360 if (Rs & (1 << 31))
4361 Rs -= 1ULL <<
4362 32;
4363 state->Accumulator +=
4364 Rm * Rs;
4365 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
4366 }
4367 break;
4368
4369 case 0x2:
4370 if (BITS (4, 11) == 1
4371 && BITS (16, 17) == 0) {
4372 /* XScale MIAPH instruction. */
4373 ARMword t1 =
4374 state->
4375 Reg[MULLHSReg]
4376 >> 16;
4377 ARMword t2 =
4378 state->
4379 Reg[MULACCReg]
4380 >> 16;
4381 ARMword t3 =
4382 state->
4383 Reg[MULLHSReg]
4384 & 0xffff;
4385 ARMword t4 =
4386 state->
4387 Reg[MULACCReg]
4388 & 0xffff;
4389 long long t5;
4390
4391 if (t1 & (1 << 15))
4392 t1 -= 1 << 16;
4393 if (t2 & (1 << 15))
4394 t2 -= 1 << 16;
4395 if (t3 & (1 << 15))
4396 t3 -= 1 << 16;
4397 if (t4 & (1 << 15))
4398 t4 -= 1 << 16;
4399 t1 *= t2;
4400 t5 = t1;
4401 if (t5 & (1 << 31))
4402 t5 -= 1ULL <<
4403 32;
4404 state->Accumulator +=
4405 t5;
4406 t3 *= t4;
4407 t5 = t3;
4408 if (t5 & (1 << 31))
4409 t5 -= 1ULL <<
4410 32;
4411 state->Accumulator +=
4412 t5;
4413 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
4414 }
4415 break;
4416
4417 case 0x3:
4418 if (BITS (4, 11) == 1) {
4419 /* XScale MIAxy instruction. */
4420 ARMword t1;
4421 ARMword t2;
4422 long long t5;
4423
4424 if (BIT (17))
4425 t1 = state->
4426 Reg
4427 [MULLHSReg]
4428 >> 16;
4429 else
4430 t1 = state->
4431 Reg
4432 [MULLHSReg]
4433 &
4434 0xffff;
4435
4436 if (BIT (16))
4437 t2 = state->
4438 Reg
4439 [MULACCReg]
4440 >> 16;
4441 else
4442 t2 = state->
4443 Reg
4444 [MULACCReg]
4445 &
4446 0xffff;
4447
4448 if (t1 & (1 << 15))
4449 t1 -= 1 << 16;
4450 if (t2 & (1 << 15))
4451 t2 -= 1 << 16;
4452 t1 *= t2;
4453 t5 = t1;
4454 if (t5 & (1 << 31))
4455 t5 -= 1ULL <<
4456 32;
4457 state->Accumulator +=
4458 t5;
4459 _assert_msg_(ARM11, false, "disabled skyeye code 'goto donext'"); //goto donext;
4460 }
4461 break;
4462
4463 default:
4464 break;
4465 }
4466 /* Drop through. */
4467
4468 case 0xe0:
4469 case 0xe4:
4470 case 0xe6:
4471 case 0xe8:
4472 case 0xea:
4473 case 0xec:
4474 case 0xee:
4475 if (BIT (4)) {
4476 /* MCR. */
4477 if (DESTReg == 15) {
4478 UNDEF_MCRPC;
4479#ifdef MODE32
4480 ARMul_MCR (state, instr,
4481 state->Reg[15] +
4482 isize);
4483#else
4484 ARMul_MCR (state, instr,
4485 ECC | ER15INT |
4486 EMODE |
4487 ((state->Reg[15] +
4488 isize) &
4489 R15PCBITS));
4490#endif
4491 }
4492 else
4493 ARMul_MCR (state, instr,
4494 DEST);
4495 }
4496 else
4497 /* CDP Part 1. */
4498 ARMul_CDP (state, instr);
4499 break;
4500
4501
4502 /* Co-Processor Register Transfers (MRC) and Data Ops. */
4503 case 0xe1:
4504 case 0xe3:
4505 case 0xe5:
4506 case 0xe7:
4507 case 0xe9:
4508 case 0xeb:
4509 case 0xed:
4510 case 0xef:
4511 if (BIT (4)) {
4512 /* MRC */
4513 temp = ARMul_MRC (state, instr);
4514 if (DESTReg == 15) {
4515 ASSIGNN ((temp & NBIT) != 0);
4516 ASSIGNZ ((temp & ZBIT) != 0);
4517 ASSIGNC ((temp & CBIT) != 0);
4518 ASSIGNV ((temp & VBIT) != 0);
4519 }
4520 else
4521 DEST = temp;
4522 }
4523 else
4524 /* CDP Part 2. */
4525 ARMul_CDP (state, instr);
4526 break;
4527
4528
4529 /* SWI instruction. */
4530 case 0xf0:
4531 case 0xf1:
4532 case 0xf2:
4533 case 0xf3:
4534 case 0xf4:
4535 case 0xf5:
4536 case 0xf6:
4537 case 0xf7:
4538 case 0xf8:
4539 case 0xf9:
4540 case 0xfa:
4541 case 0xfb:
4542 case 0xfc:
4543 case 0xfd:
4544 case 0xfe:
4545 case 0xff:
4546 if (instr == ARMul_ABORTWORD
4547 && state->AbortAddr == pc) {
4548 /* A prefetch abort. */
4549 XScale_set_fsr_far (state,
4550 ARMul_CP15_R5_MMU_EXCPT,
4551 pc);
4552 ARMul_Abort (state,
4553 ARMul_PrefetchAbortV);
4554 break;
4555 }
4556 //sky_pref_t* pref = get_skyeye_pref();
4557 //if(pref->user_mode_sim){
4558 // ARMul_OSHandleSWI (state, BITS (0, 23));
4559 // break;
4560 //}
4561 ARMul_Abort (state, ARMul_SWIV);
4562 break;
4563 }
4564 }
4565
4566#ifdef MODET
4567 donext:
4568#endif
4569 state->pc = pc;
4570#if 0
4571 /* shenoubang */
4572 instr_sum++;
4573 int i, j;
4574 i = j = 0;
4575 if (instr_sum >= 7388648) {
4576 //if (pc == 0xc0008ab4) {
4577 // printf("instr_sum: %d\n", instr_sum);
4578 // start_kernel : 0xc000895c
4579 printf("--------------------------------------------------\n");
4580 for (i = 0; i < 16; i++) {
4581 printf("[R%02d]:[0x%08x]\t", i, state->Reg[i]);
4582 if ((i % 3) == 2) {
4583 printf("\n");
4584 }
4585 }
4586 printf("[cpr]:[0x%08x]\t[spr0]:[0x%08x]\n", state->Cpsr, state->Spsr[0]);
4587 for (j = 1; j < 7; j++) {
4588 printf("[spr%d]:[0x%08x]\t", j, state->Spsr[j]);
4589 if ((j % 4) == 3) {
4590 printf("\n");
4591 }
4592 }
4593 printf("\n[PC]:[0x%08x]\t[INST]:[0x%08x]\t[COUNT]:[%d]\n", pc, instr, instr_sum);
4594 printf("--------------------------------------------------\n");
4595 }
4596#endif
4597
4598#if 0
4599 fprintf(state->state_log, "PC:0x%x\n", pc);
4600 for (reg_index = 0; reg_index < 16; reg_index ++) {
4601 if (state->Reg[reg_index] != mirror_register_file[reg_index]) {
4602 fprintf(state->state_log, "R%d:0x%x\n", reg_index, state->Reg[reg_index]);
4603 mirror_register_file[reg_index] = state->Reg[reg_index];
4604 }
4605 }
4606 if (state->Cpsr != mirror_register_file[CPSR_REG]) {
4607 fprintf(state->state_log, "Cpsr:0x%x\n", state->Cpsr);
4608 mirror_register_file[CPSR_REG] = state->Cpsr;
4609 }
4610 if (state->RegBank[SVCBANK][13] != mirror_register_file[R13_SVC]) {
4611 fprintf(state->state_log, "R13_SVC:0x%x\n", state->RegBank[SVCBANK][13]);
4612 mirror_register_file[R13_SVC] = state->RegBank[SVCBANK][13];
4613 }
4614 if (state->RegBank[SVCBANK][14] != mirror_register_file[R14_SVC]) {
4615 fprintf(state->state_log, "R14_SVC:0x%x\n", state->RegBank[SVCBANK][14]);
4616 mirror_register_file[R14_SVC] = state->RegBank[SVCBANK][14];
4617 }
4618 if (state->RegBank[ABORTBANK][13] != mirror_register_file[R13_ABORT]) {
4619 fprintf(state->state_log, "R13_ABORT:0x%x\n", state->RegBank[ABORTBANK][13]);
4620 mirror_register_file[R13_ABORT] = state->RegBank[ABORTBANK][13];
4621 }
4622 if (state->RegBank[ABORTBANK][14] != mirror_register_file[R14_ABORT]) {
4623 fprintf(state->state_log, "R14_ABORT:0x%x\n", state->RegBank[ABORTBANK][14]);
4624 mirror_register_file[R14_ABORT] = state->RegBank[ABORTBANK][14];
4625 }
4626 if (state->RegBank[UNDEFBANK][13] != mirror_register_file[R13_UNDEF]) {
4627 fprintf(state->state_log, "R13_UNDEF:0x%x\n", state->RegBank[UNDEFBANK][13]);
4628 mirror_register_file[R13_UNDEF] = state->RegBank[UNDEFBANK][13];
4629 }
4630 if (state->RegBank[UNDEFBANK][14] != mirror_register_file[R14_UNDEF]) {
4631 fprintf(state->state_log, "R14_UNDEF:0x%x\n", state->RegBank[UNDEFBANK][14]);
4632 mirror_register_file[R14_UNDEF] = state->RegBank[UNDEFBANK][14];
4633 }
4634 if (state->RegBank[IRQBANK][13] != mirror_register_file[R13_IRQ]) {
4635 fprintf(state->state_log, "R13_IRQ:0x%x\n", state->RegBank[IRQBANK][13]);
4636 mirror_register_file[R13_IRQ] = state->RegBank[IRQBANK][13];
4637 }
4638 if (state->RegBank[IRQBANK][14] != mirror_register_file[R14_IRQ]) {
4639 fprintf(state->state_log, "R14_IRQ:0x%x\n", state->RegBank[IRQBANK][14]);
4640 mirror_register_file[R14_IRQ] = state->RegBank[IRQBANK][14];
4641 }
4642 if (state->RegBank[FIQBANK][8] != mirror_register_file[R8_FIRQ]) {
4643 fprintf(state->state_log, "R8_FIRQ:0x%x\n", state->RegBank[FIQBANK][8]);
4644 mirror_register_file[R8_FIRQ] = state->RegBank[FIQBANK][8];
4645 }
4646 if (state->RegBank[FIQBANK][9] != mirror_register_file[R9_FIRQ]) {
4647 fprintf(state->state_log, "R9_FIRQ:0x%x\n", state->RegBank[FIQBANK][9]);
4648 mirror_register_file[R9_FIRQ] = state->RegBank[FIQBANK][9];
4649 }
4650 if (state->RegBank[FIQBANK][10] != mirror_register_file[R10_FIRQ]) {
4651 fprintf(state->state_log, "R10_FIRQ:0x%x\n", state->RegBank[FIQBANK][10]);
4652 mirror_register_file[R10_FIRQ] = state->RegBank[FIQBANK][10];
4653 }
4654 if (state->RegBank[FIQBANK][11] != mirror_register_file[R11_FIRQ]) {
4655 fprintf(state->state_log, "R11_FIRQ:0x%x\n", state->RegBank[FIQBANK][11]);
4656 mirror_register_file[R11_FIRQ] = state->RegBank[FIQBANK][11];
4657 }
4658 if (state->RegBank[FIQBANK][12] != mirror_register_file[R12_FIRQ]) {
4659 fprintf(state->state_log, "R12_FIRQ:0x%x\n", state->RegBank[FIQBANK][12]);
4660 mirror_register_file[R12_FIRQ] = state->RegBank[FIQBANK][12];
4661 }
4662 if (state->RegBank[FIQBANK][13] != mirror_register_file[R13_FIRQ]) {
4663 fprintf(state->state_log, "R13_FIRQ:0x%x\n", state->RegBank[FIQBANK][13]);
4664 mirror_register_file[R13_FIRQ] = state->RegBank[FIQBANK][13];
4665 }
4666 if (state->RegBank[FIQBANK][14] != mirror_register_file[R14_FIRQ]) {
4667 fprintf(state->state_log, "R14_FIRQ:0x%x\n", state->RegBank[FIQBANK][14]);
4668 mirror_register_file[R14_FIRQ] = state->RegBank[FIQBANK][14];
4669 }
4670 if (state->Spsr[SVCBANK] != mirror_register_file[SPSR_SVC]) {
4671 fprintf(state->state_log, "SPSR_SVC:0x%x\n", state->Spsr[SVCBANK]);
4672 mirror_register_file[SPSR_SVC] = state->RegBank[SVCBANK];
4673 }
4674 if (state->Spsr[ABORTBANK] != mirror_register_file[SPSR_ABORT]) {
4675 fprintf(state->state_log, "SPSR_ABORT:0x%x\n", state->Spsr[ABORTBANK]);
4676 mirror_register_file[SPSR_ABORT] = state->RegBank[ABORTBANK];
4677 }
4678 if (state->Spsr[UNDEFBANK] != mirror_register_file[SPSR_UNDEF]) {
4679 fprintf(state->state_log, "SPSR_UNDEF:0x%x\n", state->Spsr[UNDEFBANK]);
4680 mirror_register_file[SPSR_UNDEF] = state->RegBank[UNDEFBANK];
4681 }
4682 if (state->Spsr[IRQBANK] != mirror_register_file[SPSR_IRQ]) {
4683 fprintf(state->state_log, "SPSR_IRQ:0x%x\n", state->Spsr[IRQBANK]);
4684 mirror_register_file[SPSR_IRQ] = state->RegBank[IRQBANK];
4685 }
4686 if (state->Spsr[FIQBANK] != mirror_register_file[SPSR_FIRQ]) {
4687 fprintf(state->state_log, "SPSR_FIRQ:0x%x\n", state->Spsr[FIQBANK]);
4688 mirror_register_file[SPSR_FIRQ] = state->RegBank[FIQBANK];
4689 }
4690
4691#endif
4692
4693#ifdef NEED_UI_LOOP_HOOK
4694 if (ui_loop_hook != NULL && ui_loop_hook_counter-- < 0) {
4695 ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
4696 ui_loop_hook (0);
4697 }
4698#endif /* NEED_UI_LOOP_HOOK */
4699
4700 /*added energy_prof statement by ksh in 2004-11-26 */
4701 //chy 2005-07-28 for standalone
4702 //ARMul_do_energy(state,instr,pc);
4703//teawater add for record reg value to ./reg.txt 2005.07.10---------------------
4704 if (state->tea_break_ok && pc == state->tea_break_addr) {
4705 ARMul_Debug (state, 0, 0);
4706 state->tea_break_ok = 0;
4707 }
4708 else {
4709 state->tea_break_ok = 1;
4710 }
4711//AJ2D--------------------------------------------------------------------------
4712//chy 2006-04-14 for ctrl-c debug
4713#if 0
4714 if (debugmode) {
4715 if (instr != ARMul_ABORTWORD) {
4716 remote_interrupt_test_time++;
4717 //chy 2006-04-14 2000 should be changed in skyeye_conf ???!!!
4718 if (remote_interrupt_test_time >= 2000) {
4719 remote_interrupt_test_time=0;
4720 if (remote_interrupt()) {
4721 //for test
4722 //printf("SKYEYE: ICE_debug recv Ctrl_C\n");
4723 state->EndCondition = 0;
4724 state->Emulate = STOP;
4725 }
4726 }
4727 }
4728 }
4729#endif
4730
4731 /* jump out every time */
4732 //state->EndCondition = 0;
4733 //state->Emulate = STOP;
4734//chy 2006-04-12 for ICE debug
4735TEST_EMULATE:
4736 if (state->Emulate == ONCE)
4737 state->Emulate = STOP;
4738 //chy: 2003-08-23: should not use CHANGEMODE !!!!
4739 /* If we have changed mode, allow the PC to advance before stopping. */
4740 // else if (state->Emulate == CHANGEMODE)
4741 // continue;
4742 else if (state->Emulate != RUN)
4743 break;
4744 }
4745 while (!state->stop_simulator);
4746
4747 state->decoded = decoded;
4748 state->loaded = loaded;
4749 state->pc = pc;
4750 //chy 2006-04-12, for ICE debug
4751 state->decoded_addr=decoded_addr;
4752 state->loaded_addr=loaded_addr;
4753
4754 return pc;
4755}
4756
4757//teawater add for arm2x86 2005.02.17-------------------------------------------
4758/*ywc 2005-04-01*/
4759//#include "tb.h"
4760//#include "arm2x86_self.h"
4761
4762static volatile void (*gen_func) (void);
4763//static volatile ARMul_State *tmp_st;
4764//static volatile ARMul_State *save_st;
4765static volatile uint32_t tmp_st;
4766static volatile uint32_t save_st;
4767static volatile uint32_t save_T0;
4768static volatile uint32_t save_T1;
4769static volatile uint32_t save_T2;
4770
4771#ifdef MODE32
4772#ifdef DBCT
4773//teawater change for debug function 2005.07.09---------------------------------
4774ARMword
4775ARMul_Emulate32_dbct (ARMul_State * state)
4776{
4777 static int init = 0;
4778 static FILE *fd;
4779
4780 /*if (!init) {
4781
4782 fd = fopen("./pc.txt", "w");
4783 if (!fd) {
4784 exit(-1);
4785 }
4786 init = 1;
4787 } */
4788
4789 state->Reg[15] += INSN_SIZE;
4790 do {
4791 /*if (skyeye_config.log.logon>=1) {
4792 if (state->NumInstrs>=skyeye_config.log.start && state->NumInstrs<=skyeye_config.log.end) {
4793 static int mybegin=0;
4794 static int myinstrnum=0;
4795
4796 if (mybegin==0) mybegin=1;
4797 if (mybegin==1) {
4798 state->Reg[15] -= INSN_SIZE;
4799 if (skyeye_config.log.logon>=1) fprintf(skyeye_logfd,"N %llx :p %x,i %x,",state->NumInstrs, (state->Reg[15] - INSN_SIZE), instr);
4800 if (skyeye_config.log.logon>=2) SKYEYE_OUTREGS(skyeye_logfd);
4801 if (skyeye_config.log.logon>=3) SKYEYE_OUTMOREREGS(skyeye_logfd);
4802 fprintf(skyeye_logfd,"\n");
4803 if (skyeye_config.log.length>0) {
4804 myinstrnum++;
4805 if (myinstrnum>=skyeye_config.log.length) {
4806 myinstrnum=0;
4807 fflush(skyeye_logfd);
4808 fseek(skyeye_logfd,0L,SEEK_SET);
4809 }
4810 }
4811 state->Reg[15] += INSN_SIZE;
4812 }
4813 }
4814 } */
4815 state->trap = 0;
4816 gen_func =
4817 (void *) tb_find (state, state->Reg[15] - INSN_SIZE);
4818 if (!gen_func) {
4819 //fprintf(stderr, "SKYEYE: tb_find: Error in find the translate block.\n");
4820 //exit(-1);
4821 //TRAP_INSN_ABORT
4822 //TEA_OUT(printf("\n------------\npc:%x\n", state->Reg[15] - INSN_SIZE));
4823 //TEA_OUT(printf("TRAP_INSN_ABORT\n"));
4824//teawater add for xscale(arm v5) 2005.09.01------------------------------------
4825 /*XScale_set_fsr_far(state, ARMul_CP15_R5_MMU_EXCPT, state->Reg[15] - INSN_SIZE);
4826 state->Reg[15] += INSN_SIZE;
4827 ARMul_Abort(state, ARMul_PrefetchAbortV);
4828 state->Reg[15] += INSN_SIZE;
4829 goto next; */
4830 state->trap = TRAP_INSN_ABORT;
4831 goto check;
4832//AJ2D--------------------------------------------------------------------------
4833 }
4834
4835 save_st = (uint32_t) st;
4836 save_T0 = T0;
4837 save_T1 = T1;
4838 save_T2 = T2;
4839 tmp_st = (uint32_t) state;
4840 wmb ();
4841 st = (ARMul_State *) tmp_st;
4842 gen_func ();
4843 st = (ARMul_State *) save_st;
4844 T0 = save_T0;
4845 T1 = save_T1;
4846 T2 = save_T2;
4847
4848 /*if (state->trap != TRAP_OUT) {
4849 state->tea_break_ok = 1;
4850 }
4851 if (state->trap <= TRAP_SET_R15) {
4852 goto next;
4853 } */
4854 //TEA_OUT(printf("\n------------\npc:%x\n", state->Reg[15] - INSN_SIZE));
4855//teawater add check thumb 2005.07.21-------------------------------------------
4856 /*if (TFLAG) {
4857 state->Reg[15] -= 2;
4858 return(state->Reg[15]);
4859 } */
4860//AJ2D--------------------------------------------------------------------------
4861
4862//teawater add for xscale(arm v5) 2005.09.01------------------------------------
4863 check:
4864//AJ2D--------------------------------------------------------------------------
4865 switch (state->trap) {
4866 case TRAP_RESET:
4867 {
4868 //TEA_OUT(printf("TRAP_RESET\n"));
4869 ARMul_Abort (state, ARMul_ResetV);
4870 state->Reg[15] += INSN_SIZE;
4871 }
4872 break;
4873 case TRAP_UNPREDICTABLE:
4874 {
4875 ARMul_Debug (state, 0, 0);
4876 }
4877 break;
4878 case TRAP_INSN_UNDEF:
4879 {
4880 //TEA_OUT(printf("TRAP_INSN_UNDEF\n"));
4881 state->Reg[15] += INSN_SIZE;
4882 ARMul_UndefInstr (state, 0);
4883 state->Reg[15] += INSN_SIZE;
4884 }
4885 break;
4886 case TRAP_SWI:
4887 {
4888 //TEA_OUT(printf("TRAP_SWI\n"));
4889 state->Reg[15] += INSN_SIZE;
4890 ARMul_Abort (state, ARMul_SWIV);
4891 state->Reg[15] += INSN_SIZE;
4892 }
4893 break;
4894//teawater add for xscale(arm v5) 2005.09.01------------------------------------
4895 case TRAP_INSN_ABORT:
4896 {
4897 XScale_set_fsr_far (state,
4898 ARMul_CP15_R5_MMU_EXCPT,
4899 state->Reg[15] -
4900 INSN_SIZE);
4901 state->Reg[15] += INSN_SIZE;
4902 ARMul_Abort (state, ARMul_PrefetchAbortV);
4903 state->Reg[15] += INSN_SIZE;
4904 }
4905 break;
4906//AJ2D--------------------------------------------------------------------------
4907 case TRAP_DATA_ABORT:
4908 {
4909 //TEA_OUT(printf("TRAP_DATA_ABORT\n"));
4910 state->Reg[15] += INSN_SIZE;
4911 ARMul_Abort (state, ARMul_DataAbortV);
4912 state->Reg[15] += INSN_SIZE;
4913 }
4914 break;
4915 case TRAP_IRQ:
4916 {
4917 //TEA_OUT(printf("TRAP_IRQ\n"));
4918 state->Reg[15] += INSN_SIZE;
4919 ARMul_Abort (state, ARMul_IRQV);
4920 state->Reg[15] += INSN_SIZE;
4921 }
4922 break;
4923 case TRAP_FIQ:
4924 {
4925 //TEA_OUT(printf("TRAP_FIQ\n"));
4926 state->Reg[15] += INSN_SIZE;
4927 ARMul_Abort (state, ARMul_FIQV);
4928 state->Reg[15] += INSN_SIZE;
4929 }
4930 break;
4931 case TRAP_SETS_R15:
4932 {
4933 //TEA_OUT(printf("TRAP_SETS_R15\n"));
4934 /*if (state->Bank > 0) {
4935 state->Cpsr = state->Spsr[state->Bank];
4936 ARMul_CPSRAltered (state);
4937 } */
4938 WriteSR15 (state, state->Reg[15]);
4939 }
4940 break;
4941 case TRAP_SET_CPSR:
4942 {
4943 //TEA_OUT(printf("TRAP_SET_CPSR\n"));
4944 //chy 2006-02-15 USERBANK=SYSTEMBANK=0
4945 //chy 2006-02-16 should use Mode to test
4946 //if (state->Bank > 0) {
4947 if (state->Mode != USER26MODE && state->Mode != USER32MODE){
4948 ARMul_CPSRAltered (state);
4949 }
4950 state->Reg[15] += INSN_SIZE;
4951 }
4952 break;
4953 case TRAP_OUT:
4954 {
4955 //TEA_OUT(printf("TRAP_OUT\n"));
4956 goto out;
4957 }
4958 break;
4959 case TRAP_BREAKPOINT:
4960 {
4961 //TEA_OUT(printf("TRAP_BREAKPOINT\n"));
4962 state->Reg[15] -= INSN_SIZE;
4963 if (!ARMul_OSHandleSWI
4964 (state, SWI_Breakpoint)) {
4965 ARMul_Abort (state, ARMul_SWIV);
4966 }
4967 state->Reg[15] += INSN_SIZE;
4968 }
4969 break;
4970 }
4971
4972 next:
4973 if (state->Emulate == ONCE) {
4974 state->Emulate = STOP;
4975 break;
4976 }
4977 else if (state->Emulate != RUN) {
4978 break;
4979 }
4980 }
4981 while (!state->stop_simulator);
4982
4983 out:
4984 state->Reg[15] -= INSN_SIZE;
4985 return (state->Reg[15]);
4986}
4987#endif
4988//AJ2D--------------------------------------------------------------------------
4989#endif
4990//AJ2D--------------------------------------------------------------------------
4991
4992/* This routine evaluates most Data Processing register RHS's with the S
4993 bit clear. It is intended to be called from the macro DPRegRHS, which
4994 filters the common case of an unshifted register with in line code. */
4995
4996static ARMword
4997GetDPRegRHS (ARMul_State * state, ARMword instr)
4998{
4999 ARMword shamt, base;
5000
5001 base = RHSReg;
5002 if (BIT (4)) {
5003 /* Shift amount in a register. */
5004 UNDEF_Shift;
5005 INCPC;
5006#ifndef MODE32
5007 if (base == 15)
5008 base = ECC | ER15INT | R15PC | EMODE;
5009 else
5010#endif
5011 base = state->Reg[base];
5012 ARMul_Icycles (state, 1, 0L);
5013 shamt = state->Reg[BITS (8, 11)] & 0xff;
5014 switch ((int) BITS (5, 6)) {
5015 case LSL:
5016 if (shamt == 0)
5017 return (base);
5018 else if (shamt >= 32)
5019 return (0);
5020 else
5021 return (base << shamt);
5022 case LSR:
5023 if (shamt == 0)
5024 return (base);
5025 else if (shamt >= 32)
5026 return (0);
5027 else
5028 return (base >> shamt);
5029 case ASR:
5030 if (shamt == 0)
5031 return (base);
5032 else if (shamt >= 32)
5033 return ((ARMword) ((int) base >> 31L));
5034 else
5035 return ((ARMword)
5036 (( int) base >> (int) shamt));
5037 case ROR:
5038 shamt &= 0x1f;
5039 if (shamt == 0)
5040 return (base);
5041 else
5042 return ((base << (32 - shamt)) |
5043 (base >> shamt));
5044 }
5045 }
5046 else {
5047 /* Shift amount is a constant. */
5048#ifndef MODE32
5049 if (base == 15)
5050 base = ECC | ER15INT | R15PC | EMODE;
5051 else
5052#endif
5053 base = state->Reg[base];
5054 shamt = BITS (7, 11);
5055 switch ((int) BITS (5, 6)) {
5056 case LSL:
5057 return (base << shamt);
5058 case LSR:
5059 if (shamt == 0)
5060 return (0);
5061 else
5062 return (base >> shamt);
5063 case ASR:
5064 if (shamt == 0)
5065 return ((ARMword) (( int) base >> 31L));
5066 else
5067 return ((ARMword)
5068 (( int) base >> (int) shamt));
5069 case ROR:
5070 if (shamt == 0)
5071 /* It's an RRX. */
5072 return ((base >> 1) | (CFLAG << 31));
5073 else
5074 return ((base << (32 - shamt)) |
5075 (base >> shamt));
5076 }
5077 }
5078
5079 return 0;
5080}
5081
5082/* This routine evaluates most Logical Data Processing register RHS's
5083 with the S bit set. It is intended to be called from the macro
5084 DPSRegRHS, which filters the common case of an unshifted register
5085 with in line code. */
5086
5087static ARMword
5088GetDPSRegRHS (ARMul_State * state, ARMword instr)
5089{
5090 ARMword shamt, base;
5091
5092 base = RHSReg;
5093 if (BIT (4)) {
5094 /* Shift amount in a register. */
5095 UNDEF_Shift;
5096 INCPC;
5097#ifndef MODE32
5098 if (base == 15)
5099 base = ECC | ER15INT | R15PC | EMODE;
5100 else
5101#endif
5102 base = state->Reg[base];
5103 ARMul_Icycles (state, 1, 0L);
5104 shamt = state->Reg[BITS (8, 11)] & 0xff;
5105 switch ((int) BITS (5, 6)) {
5106 case LSL:
5107 if (shamt == 0)
5108 return (base);
5109 else if (shamt == 32) {
5110 ASSIGNC (base & 1);
5111 return (0);
5112 }
5113 else if (shamt > 32) {
5114 CLEARC;
5115 return (0);
5116 }
5117 else {
5118 ASSIGNC ((base >> (32 - shamt)) & 1);
5119 return (base << shamt);
5120 }
5121 case LSR:
5122 if (shamt == 0)
5123 return (base);
5124 else if (shamt == 32) {
5125 ASSIGNC (base >> 31);
5126 return (0);
5127 }
5128 else if (shamt > 32) {
5129 CLEARC;
5130 return (0);
5131 }
5132 else {
5133 ASSIGNC ((base >> (shamt - 1)) & 1);
5134 return (base >> shamt);
5135 }
5136 case ASR:
5137 if (shamt == 0)
5138 return (base);
5139 else if (shamt >= 32) {
5140 ASSIGNC (base >> 31L);
5141 return ((ARMword) (( int) base >> 31L));
5142 }
5143 else {
5144 ASSIGNC ((ARMword)
5145 (( int) base >>
5146 (int) (shamt - 1)) & 1);
5147 return ((ARMword)
5148 ((int) base >> (int) shamt));
5149 }
5150 case ROR:
5151 if (shamt == 0)
5152 return (base);
5153 shamt &= 0x1f;
5154 if (shamt == 0) {
5155 ASSIGNC (base >> 31);
5156 return (base);
5157 }
5158 else {
5159 ASSIGNC ((base >> (shamt - 1)) & 1);
5160 return ((base << (32 - shamt)) |
5161 (base >> shamt));
5162 }
5163 }
5164 }
5165 else {
5166 /* Shift amount is a constant. */
5167#ifndef MODE32
5168 if (base == 15)
5169 base = ECC | ER15INT | R15PC | EMODE;
5170 else
5171#endif
5172 base = state->Reg[base];
5173 shamt = BITS (7, 11);
5174
5175 switch ((int) BITS (5, 6)) {
5176 case LSL:
5177 ASSIGNC ((base >> (32 - shamt)) & 1);
5178 return (base << shamt);
5179 case LSR:
5180 if (shamt == 0) {
5181 ASSIGNC (base >> 31);
5182 return (0);
5183 }
5184 else {
5185 ASSIGNC ((base >> (shamt - 1)) & 1);
5186 return (base >> shamt);
5187 }
5188 case ASR:
5189 if (shamt == 0) {
5190 ASSIGNC (base >> 31L);
5191 return ((ARMword) ((int) base >> 31L));
5192 }
5193 else {
5194 ASSIGNC ((ARMword)
5195 ((int) base >>
5196 (int) (shamt - 1)) & 1);
5197 return ((ARMword)
5198 (( int) base >> (int) shamt));
5199 }
5200 case ROR:
5201 if (shamt == 0) {
5202 /* It's an RRX. */
5203 shamt = CFLAG;
5204 ASSIGNC (base & 1);
5205 return ((base >> 1) | (shamt << 31));
5206 }
5207 else {
5208 ASSIGNC ((base >> (shamt - 1)) & 1);
5209 return ((base << (32 - shamt)) |
5210 (base >> shamt));
5211 }
5212 }
5213 }
5214
5215 return 0;
5216}
5217
5218/* This routine handles writes to register 15 when the S bit is not set. */
5219
5220static void
5221WriteR15 (ARMul_State * state, ARMword src)
5222{
5223 /* The ARM documentation states that the two least significant bits
5224 are discarded when setting PC, except in the cases handled by
5225 WriteR15Branch() below. It's probably an oversight: in THUMB
5226 mode, the second least significant bit should probably not be
5227 discarded. */
5228#ifdef MODET
5229 if (TFLAG)
5230 src &= 0xfffffffe;
5231 else
5232#endif
5233 src &= 0xfffffffc;
5234
5235#ifdef MODE32
5236 state->Reg[15] = src & PCBITS;
5237#else
5238 state->Reg[15] = (src & R15PCBITS) | ECC | ER15INT | EMODE;
5239 ARMul_R15Altered (state);
5240#endif
5241
5242 FLUSHPIPE;
5243}
5244
5245/* This routine handles writes to register 15 when the S bit is set. */
5246
5247static void
5248WriteSR15 (ARMul_State * state, ARMword src)
5249{
5250#ifdef MODE32
5251 if (state->Bank > 0) {
5252 state->Cpsr = state->Spsr[state->Bank];
5253 ARMul_CPSRAltered (state);
5254 }
5255#ifdef MODET
5256 if (TFLAG)
5257 src &= 0xfffffffe;
5258 else
5259#endif
5260 src &= 0xfffffffc;
5261 state->Reg[15] = src & PCBITS;
5262#else
5263#ifdef MODET
5264 if (TFLAG)
5265 /* ARMul_R15Altered would have to support it. */
5266 abort ();
5267 else
5268#endif
5269 src &= 0xfffffffc;
5270
5271 if (state->Bank == USERBANK)
5272 state->Reg[15] =
5273 (src & (CCBITS | R15PCBITS)) | ER15INT | EMODE;
5274 else
5275 state->Reg[15] = src;
5276
5277 ARMul_R15Altered (state);
5278#endif
5279 FLUSHPIPE;
5280}
5281
5282/* In machines capable of running in Thumb mode, BX, BLX, LDR and LDM
5283 will switch to Thumb mode if the least significant bit is set. */
5284
5285static void
5286WriteR15Branch (ARMul_State * state, ARMword src)
5287{
5288#ifdef MODET
5289 if (src & 1) {
5290 /* Thumb bit. */
5291 SETT;
5292 state->Reg[15] = src & 0xfffffffe;
5293 }
5294 else {
5295 CLEART;
5296 state->Reg[15] = src & 0xfffffffc;
5297 }
5298 state->Cpsr = ARMul_GetCPSR (state);
5299 FLUSHPIPE;
5300#else
5301 WriteR15 (state, src);
5302#endif
5303}
5304
5305/* This routine evaluates most Load and Store register RHS's. It is
5306 intended to be called from the macro LSRegRHS, which filters the
5307 common case of an unshifted register with in line code. */
5308
5309static ARMword
5310GetLSRegRHS (ARMul_State * state, ARMword instr)
5311{
5312 ARMword shamt, base;
5313
5314 base = RHSReg;
5315#ifndef MODE32
5316 if (base == 15)
5317 /* Now forbidden, but ... */
5318 base = ECC | ER15INT | R15PC | EMODE;
5319 else
5320#endif
5321 base = state->Reg[base];
5322
5323 shamt = BITS (7, 11);
5324 switch ((int) BITS (5, 6)) {
5325 case LSL:
5326 return (base << shamt);
5327 case LSR:
5328 if (shamt == 0)
5329 return (0);
5330 else
5331 return (base >> shamt);
5332 case ASR:
5333 if (shamt == 0)
5334 return ((ARMword) (( int) base >> 31L));
5335 else
5336 return ((ARMword) (( int) base >> (int) shamt));
5337 case ROR:
5338 if (shamt == 0)
5339 /* It's an RRX. */
5340 return ((base >> 1) | (CFLAG << 31));
5341 else
5342 return ((base << (32 - shamt)) | (base >> shamt));
5343 default:
5344 break;
5345 }
5346 return 0;
5347}
5348
5349/* This routine evaluates the ARM7T halfword and signed transfer RHS's. */
5350
5351static ARMword
5352GetLS7RHS (ARMul_State * state, ARMword instr)
5353{
5354 if (BIT (22) == 0) {
5355 /* Register. */
5356#ifndef MODE32
5357 if (RHSReg == 15)
5358 /* Now forbidden, but ... */
5359 return ECC | ER15INT | R15PC | EMODE;
5360#endif
5361 return state->Reg[RHSReg];
5362 }
5363
5364 /* Immediate. */
5365 return BITS (0, 3) | (BITS (8, 11) << 4);
5366}
5367
5368/* This function does the work of loading a word for a LDR instruction. */
5369#define MEM_LOAD_LOG(description) if (skyeye_config.log.memlogon >= 1) { \
5370 fprintf(skyeye_logfd, \
5371 "m LOAD %s: N %llx :p %x :i %x :a %x :d %x\n", \
5372 description, state->NumInstrs, state->pc, instr, \
5373 address, dest); \
5374 }
5375
5376#define MEM_STORE_LOG(description) if (skyeye_config.log.memlogon >= 1) { \
5377 fprintf(skyeye_logfd, \
5378 "m STORE %s: N %llx :p %x :i %x :a %x :d %x\n", \
5379 description, state->NumInstrs, state->pc, instr, \
5380 address, DEST); \
5381 }
5382
5383
5384
5385static unsigned
5386LoadWord (ARMul_State * state, ARMword instr, ARMword address)
5387{
5388 ARMword dest;
5389
5390 BUSUSEDINCPCS;
5391#ifndef MODE32
5392 if (ADDREXCEPT (address))
5393 INTERNALABORT (address);
5394#endif
5395
5396 dest = ARMul_LoadWordN (state, address);
5397
5398 if (state->Aborted) {
5399 TAKEABORT;
5400 return state->lateabtSig;
5401 }
5402 if (address & 3)
5403 dest = ARMul_Align (state, address, dest);
5404 WRITEDESTB (dest);
5405 ARMul_Icycles (state, 1, 0L);
5406
5407 //MEM_LOAD_LOG("WORD");
5408
5409 return (DESTReg != LHSReg);
5410}
5411
5412#ifdef MODET
5413/* This function does the work of loading a halfword. */
5414
5415static unsigned
5416LoadHalfWord (ARMul_State * state, ARMword instr, ARMword address,
5417 int signextend)
5418{
5419 ARMword dest;
5420
5421 BUSUSEDINCPCS;
5422#ifndef MODE32
5423 if (ADDREXCEPT (address))
5424 INTERNALABORT (address);
5425#endif
5426 dest = ARMul_LoadHalfWord (state, address);
5427 if (state->Aborted) {
5428 TAKEABORT;
5429 return state->lateabtSig;
5430 }
5431 UNDEF_LSRBPC;
5432 if (signextend)
5433 if (dest & 1 << (16 - 1))
5434 dest = (dest & ((1 << 16) - 1)) - (1 << 16);
5435
5436 WRITEDEST (dest);
5437 ARMul_Icycles (state, 1, 0L);
5438
5439 //MEM_LOAD_LOG("HALFWORD");
5440
5441 return (DESTReg != LHSReg);
5442}
5443
5444#endif /* MODET */
5445
5446/* This function does the work of loading a byte for a LDRB instruction. */
5447
5448static unsigned
5449LoadByte (ARMul_State * state, ARMword instr, ARMword address, int signextend)
5450{
5451 ARMword dest;
5452
5453 BUSUSEDINCPCS;
5454#ifndef MODE32
5455 if (ADDREXCEPT (address))
5456 INTERNALABORT (address);
5457#endif
5458 dest = ARMul_LoadByte (state, address);
5459 if (state->Aborted) {
5460 TAKEABORT;
5461 return state->lateabtSig;
5462 }
5463 UNDEF_LSRBPC;
5464 if (signextend)
5465 if (dest & 1 << (8 - 1))
5466 dest = (dest & ((1 << 8) - 1)) - (1 << 8);
5467
5468 WRITEDEST (dest);
5469 ARMul_Icycles (state, 1, 0L);
5470
5471 //MEM_LOAD_LOG("BYTE");
5472
5473 return (DESTReg != LHSReg);
5474}
5475
5476/* This function does the work of loading two words for a LDRD instruction. */
5477
5478static void
5479Handle_Load_Double (ARMul_State * state, ARMword instr)
5480{
5481 ARMword dest_reg;
5482 ARMword addr_reg;
5483 ARMword write_back = BIT (21);
5484 ARMword immediate = BIT (22);
5485 ARMword add_to_base = BIT (23);
5486 ARMword pre_indexed = BIT (24);
5487 ARMword offset;
5488 ARMword addr;
5489 ARMword sum;
5490 ARMword base;
5491 ARMword value1;
5492 ARMword value2;
5493
5494 BUSUSEDINCPCS;
5495
5496 /* If the writeback bit is set, the pre-index bit must be clear. */
5497 if (write_back && !pre_indexed) {
5498 ARMul_UndefInstr (state, instr);
5499 return;
5500 }
5501
5502 /* Extract the base address register. */
5503 addr_reg = LHSReg;
5504
5505 /* Extract the destination register and check it. */
5506 dest_reg = DESTReg;
5507
5508 /* Destination register must be even. */
5509 if ((dest_reg & 1)
5510 /* Destination register cannot be LR. */
5511 || (dest_reg == 14)) {
5512 ARMul_UndefInstr (state, instr);
5513 return;
5514 }
5515
5516 /* Compute the base address. */
5517 base = state->Reg[addr_reg];
5518
5519 /* Compute the offset. */
5520 offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->
5521 Reg[RHSReg];
5522
5523 /* Compute the sum of the two. */
5524 if (add_to_base)
5525 sum = base + offset;
5526 else
5527 sum = base - offset;
5528
5529 /* If this is a pre-indexed mode use the sum. */
5530 if (pre_indexed)
5531 addr = sum;
5532 else
5533 addr = base;
5534
5535 /* The address must be aligned on a 8 byte boundary. */
5536 if (addr & 0x7) {
5537#ifdef ABORTS
5538 ARMul_DATAABORT (addr);
5539#else
5540 ARMul_UndefInstr (state, instr);
5541#endif
5542 return;
5543 }
5544
5545 /* For pre indexed or post indexed addressing modes,
5546 check that the destination registers do not overlap
5547 the address registers. */
5548 if ((!pre_indexed || write_back)
5549 && (addr_reg == dest_reg || addr_reg == dest_reg + 1)) {
5550 ARMul_UndefInstr (state, instr);
5551 return;
5552 }
5553
5554 /* Load the words. */
5555 value1 = ARMul_LoadWordN (state, addr);
5556 value2 = ARMul_LoadWordN (state, addr + 4);
5557
5558 /* Check for data aborts. */
5559 if (state->Aborted) {
5560 TAKEABORT;
5561 return;
5562 }
5563
5564 ARMul_Icycles (state, 2, 0L);
5565
5566 /* Store the values. */
5567 state->Reg[dest_reg] = value1;
5568 state->Reg[dest_reg + 1] = value2;
5569
5570 /* Do the post addressing and writeback. */
5571 if (!pre_indexed)
5572 addr = sum;
5573
5574 if (!pre_indexed || write_back)
5575 state->Reg[addr_reg] = addr;
5576}
5577
5578/* This function does the work of storing two words for a STRD instruction. */
5579
5580static void
5581Handle_Store_Double (ARMul_State * state, ARMword instr)
5582{
5583 ARMword src_reg;
5584 ARMword addr_reg;
5585 ARMword write_back = BIT (21);
5586 ARMword immediate = BIT (22);
5587 ARMword add_to_base = BIT (23);
5588 ARMword pre_indexed = BIT (24);
5589 ARMword offset;
5590 ARMword addr;
5591 ARMword sum;
5592 ARMword base;
5593
5594 BUSUSEDINCPCS;
5595
5596 /* If the writeback bit is set, the pre-index bit must be clear. */
5597 if (write_back && !pre_indexed) {
5598 ARMul_UndefInstr (state, instr);
5599 return;
5600 }
5601
5602 /* Extract the base address register. */
5603 addr_reg = LHSReg;
5604
5605 /* Base register cannot be PC. */
5606 if (addr_reg == 15) {
5607 ARMul_UndefInstr (state, instr);
5608 return;
5609 }
5610
5611 /* Extract the source register. */
5612 src_reg = DESTReg;
5613
5614 /* Source register must be even. */
5615 if (src_reg & 1) {
5616 ARMul_UndefInstr (state, instr);
5617 return;
5618 }
5619
5620 /* Compute the base address. */
5621 base = state->Reg[addr_reg];
5622
5623 /* Compute the offset. */
5624 offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->
5625 Reg[RHSReg];
5626
5627 /* Compute the sum of the two. */
5628 if (add_to_base)
5629 sum = base + offset;
5630 else
5631 sum = base - offset;
5632
5633 /* If this is a pre-indexed mode use the sum. */
5634 if (pre_indexed)
5635 addr = sum;
5636 else
5637 addr = base;
5638
5639 /* The address must be aligned on a 8 byte boundary. */
5640 if (addr & 0x7) {
5641#ifdef ABORTS
5642 ARMul_DATAABORT (addr);
5643#else
5644 ARMul_UndefInstr (state, instr);
5645#endif
5646 return;
5647 }
5648
5649 /* For pre indexed or post indexed addressing modes,
5650 check that the destination registers do not overlap
5651 the address registers. */
5652 if ((!pre_indexed || write_back)
5653 && (addr_reg == src_reg || addr_reg == src_reg + 1)) {
5654 ARMul_UndefInstr (state, instr);
5655 return;
5656 }
5657
5658 /* Load the words. */
5659 ARMul_StoreWordN (state, addr, state->Reg[src_reg]);
5660 ARMul_StoreWordN (state, addr + 4, state->Reg[src_reg + 1]);
5661
5662 if (state->Aborted) {
5663 TAKEABORT;
5664 return;
5665 }
5666
5667 /* Do the post addressing and writeback. */
5668 if (!pre_indexed)
5669 addr = sum;
5670
5671 if (!pre_indexed || write_back)
5672 state->Reg[addr_reg] = addr;
5673}
5674
5675/* This function does the work of storing a word from a STR instruction. */
5676
5677static unsigned
5678StoreWord (ARMul_State * state, ARMword instr, ARMword address)
5679{
5680 //MEM_STORE_LOG("WORD");
5681
5682 BUSUSEDINCPCN;
5683#ifndef MODE32
5684 if (DESTReg == 15)
5685 state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
5686#endif
5687#ifdef MODE32
5688 ARMul_StoreWordN (state, address, DEST);
5689#else
5690 if (VECTORACCESS (address) || ADDREXCEPT (address)) {
5691 INTERNALABORT (address);
5692 (void) ARMul_LoadWordN (state, address);
5693 }
5694 else
5695 ARMul_StoreWordN (state, address, DEST);
5696#endif
5697 if (state->Aborted) {
5698 TAKEABORT;
5699 return state->lateabtSig;
5700 }
5701
5702 return TRUE;
5703}
5704
5705#ifdef MODET
5706/* This function does the work of storing a byte for a STRH instruction. */
5707
5708static unsigned
5709StoreHalfWord (ARMul_State * state, ARMword instr, ARMword address)
5710{
5711 //MEM_STORE_LOG("HALFWORD");
5712
5713 BUSUSEDINCPCN;
5714
5715#ifndef MODE32
5716 if (DESTReg == 15)
5717 state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
5718#endif
5719
5720#ifdef MODE32
5721 ARMul_StoreHalfWord (state, address, DEST);
5722#else
5723 if (VECTORACCESS (address) || ADDREXCEPT (address)) {
5724 INTERNALABORT (address);
5725 (void) ARMul_LoadHalfWord (state, address);
5726 }
5727 else
5728 ARMul_StoreHalfWord (state, address, DEST);
5729#endif
5730
5731 if (state->Aborted) {
5732 TAKEABORT;
5733 return state->lateabtSig;
5734 }
5735 return TRUE;
5736}
5737
5738#endif /* MODET */
5739
5740/* This function does the work of storing a byte for a STRB instruction. */
5741
5742static unsigned
5743StoreByte (ARMul_State * state, ARMword instr, ARMword address)
5744{
5745 //MEM_STORE_LOG("BYTE");
5746
5747 BUSUSEDINCPCN;
5748#ifndef MODE32
5749 if (DESTReg == 15)
5750 state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
5751#endif
5752#ifdef MODE32
5753 ARMul_StoreByte (state, address, DEST);
5754#else
5755 if (VECTORACCESS (address) || ADDREXCEPT (address)) {
5756 INTERNALABORT (address);
5757 (void) ARMul_LoadByte (state, address);
5758 }
5759 else
5760 ARMul_StoreByte (state, address, DEST);
5761#endif
5762 if (state->Aborted) {
5763 TAKEABORT;
5764 return state->lateabtSig;
5765 }
5766 //UNDEF_LSRBPC;
5767 return TRUE;
5768}
5769
5770/* This function does the work of loading the registers listed in an LDM
5771 instruction, when the S bit is clear. The code here is always increment
5772 after, it's up to the caller to get the input address correct and to
5773 handle base register modification. */
5774
5775static void
5776LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase)
5777{
5778 ARMword dest, temp;
5779
5780 //UNDEF_LSMNoRegs;
5781 //UNDEF_LSMPCBase;
5782 //UNDEF_LSMBaseInListWb;
5783 BUSUSEDINCPCS;
5784#ifndef MODE32
5785 if (ADDREXCEPT (address))
5786 INTERNALABORT (address);
5787#endif
5788/*chy 2004-05-23 may write twice
5789 if (BIT (21) && LHSReg != 15)
5790 LSBase = WBBase;
5791*/
5792 /* N cycle first. */
5793 for (temp = 0; !BIT (temp); temp++);
5794
5795 dest = ARMul_LoadWordN (state, address);
5796
5797 if (!state->abortSig && !state->Aborted)
5798 state->Reg[temp++] = dest;
5799 else if (!state->Aborted) {
5800 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
5801 state->Aborted = ARMul_DataAbortV;
5802 }
5803/*chy 2004-05-23 chy goto end*/
5804 if (state->Aborted)
5805 goto L_ldm_makeabort;
5806 /* S cycles from here on. */
5807 for (; temp < 16; temp++)
5808 if (BIT (temp)) {
5809 /* Load this register. */
5810 address += 4;
5811 dest = ARMul_LoadWordS (state, address);
5812
5813 if (!state->abortSig && !state->Aborted)
5814 state->Reg[temp] = dest;
5815 else if (!state->Aborted) {
5816 XScale_set_fsr_far (state,
5817 ARMul_CP15_R5_ST_ALIGN,
5818 address);
5819 state->Aborted = ARMul_DataAbortV;
5820 }
5821 /*chy 2004-05-23 chy goto end */
5822 if (state->Aborted)
5823 goto L_ldm_makeabort;
5824
5825 }
5826
5827 if (BIT (15) && !state->Aborted)
5828 /* PC is in the reg list. */
5829 WriteR15Branch(state, (state->Reg[15] & PCMASK));
5830
5831 /* To write back the final register. */
5832/* ARMul_Icycles (state, 1, 0L);*/
5833/*chy 2004-05-23, see below
5834 if (state->Aborted)
5835 {
5836 if (BIT (21) && LHSReg != 15)
5837 LSBase = WBBase;
5838
5839 TAKEABORT;
5840 }
5841*/
5842/*chy 2004-05-23 should compare the Abort Models*/
5843 L_ldm_makeabort:
5844 /* To write back the final register. */
5845 ARMul_Icycles (state, 1, 0L);
5846
5847 /* chy 2005-11-24, bug found by benjl@cse.unsw.edu.au, etc */
5848 /*
5849 if (state->Aborted)
5850 {
5851 if (BIT (21) && LHSReg != 15)
5852 if (!(state->abortSig && state->Aborted && state->lateabtSig == LOW))
5853 LSBase = WBBase;
5854 TAKEABORT;
5855 }else if (BIT (21) && LHSReg != 15)
5856 LSBase = WBBase;
5857 */
5858 if (state->Aborted) {
5859 if (BIT (21) && LHSReg != 15) {
5860 if (!(state->abortSig)) {
5861 }
5862 }
5863 TAKEABORT;
5864 }
5865 else if (BIT (21) && LHSReg != 15) {
5866 LSBase = WBBase;
5867 }
5868 /* chy 2005-11-24, over */
5869
5870}
5871
5872/* This function does the work of loading the registers listed in an LDM
5873 instruction, when the S bit is set. The code here is always increment
5874 after, it's up to the caller to get the input address correct and to
5875 handle base register modification. */
5876
5877static void
5878LoadSMult (ARMul_State * state,
5879 ARMword instr, ARMword address, ARMword WBBase)
5880{
5881 ARMword dest, temp;
5882
5883 //UNDEF_LSMNoRegs;
5884 //UNDEF_LSMPCBase;
5885 //UNDEF_LSMBaseInListWb;
5886
5887 BUSUSEDINCPCS;
5888
5889#ifndef MODE32
5890 if (ADDREXCEPT (address))
5891 INTERNALABORT (address);
5892#endif
5893/* chy 2004-05-23, may write twice
5894 if (BIT (21) && LHSReg != 15)
5895 LSBase = WBBase;
5896*/
5897 if (!BIT (15) && state->Bank != USERBANK) {
5898 /* Temporary reg bank switch. */
5899 (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
5900 UNDEF_LSMUserBankWb;
5901 }
5902
5903 /* N cycle first. */
5904 for (temp = 0; !BIT (temp); temp++);
5905
5906 dest = ARMul_LoadWordN (state, address);
5907
5908 if (!state->abortSig)
5909 state->Reg[temp++] = dest;
5910 else if (!state->Aborted) {
5911 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
5912 state->Aborted = ARMul_DataAbortV;
5913 }
5914
5915/*chy 2004-05-23 chy goto end*/
5916 if (state->Aborted)
5917 goto L_ldm_s_makeabort;
5918 /* S cycles from here on. */
5919 for (; temp < 16; temp++)
5920 if (BIT (temp)) {
5921 /* Load this register. */
5922 address += 4;
5923 dest = ARMul_LoadWordS (state, address);
5924
5925 if (!state->abortSig && !state->Aborted)
5926 state->Reg[temp] = dest;
5927 else if (!state->Aborted) {
5928 XScale_set_fsr_far (state,
5929 ARMul_CP15_R5_ST_ALIGN,
5930 address);
5931 state->Aborted = ARMul_DataAbortV;
5932 }
5933 /*chy 2004-05-23 chy goto end */
5934 if (state->Aborted)
5935 goto L_ldm_s_makeabort;
5936 }
5937
5938/*chy 2004-05-23 label of ldm_s_makeabort*/
5939 L_ldm_s_makeabort:
5940/*chy 2004-06-06 LSBase process should be here, not in the end of this function. Because ARMul_CPSRAltered maybe change R13(SP) R14(lr). If not, simulate INSTR ldmia sp!,[....pc]^ error.*/
5941/*chy 2004-05-23 should compare the Abort Models*/
5942 if (state->Aborted) {
5943 if (BIT (21) && LHSReg != 15)
5944 if (!
5945 (state->abortSig && state->Aborted
5946 && state->lateabtSig == LOW))
5947 LSBase = WBBase;
5948 TAKEABORT;
5949 }
5950 else if (BIT (21) && LHSReg != 15)
5951 LSBase = WBBase;
5952
5953 if (BIT (15) && !state->Aborted) {
5954 /* PC is in the reg list. */
5955#ifdef MODE32
5956 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
5957 if (state->Mode != USER26MODE && state->Mode != USER32MODE ){
5958 state->Cpsr = GETSPSR (state->Bank);
5959 ARMul_CPSRAltered (state);
5960 }
5961
5962 WriteR15 (state, (state->Reg[15] & PCMASK));
5963#else
5964 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
5965 if (state->Mode == USER26MODE || state->Mode == USER32MODE ) {
5966 /* Protect bits in user mode. */
5967 ASSIGNN ((state->Reg[15] & NBIT) != 0);
5968 ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
5969 ASSIGNC ((state->Reg[15] & CBIT) != 0);
5970 ASSIGNV ((state->Reg[15] & VBIT) != 0);
5971 }
5972 else
5973 ARMul_R15Altered (state);
5974
5975 FLUSHPIPE;
5976#endif
5977 }
5978
5979 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
5980 if (!BIT (15) && state->Mode != USER26MODE
5981 && state->Mode != USER32MODE )
5982 /* Restore the correct bank. */
5983 (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
5984
5985 /* To write back the final register. */
5986 ARMul_Icycles (state, 1, 0L);
5987/* chy 2004-05-23, see below
5988 if (state->Aborted)
5989 {
5990 if (BIT (21) && LHSReg != 15)
5991 LSBase = WBBase;
5992
5993 TAKEABORT;
5994 }
5995*/
5996}
5997
5998/* This function does the work of storing the registers listed in an STM
5999 instruction, when the S bit is clear. The code here is always increment
6000 after, it's up to the caller to get the input address correct and to
6001 handle base register modification. */
6002
6003static void
6004StoreMult (ARMul_State * state,
6005 ARMword instr, ARMword address, ARMword WBBase)
6006{
6007 ARMword temp;
6008
6009 UNDEF_LSMNoRegs;
6010 UNDEF_LSMPCBase;
6011 UNDEF_LSMBaseInListWb;
6012
6013 if (!TFLAG)
6014 /* N-cycle, increment the PC and update the NextInstr state. */
6015 BUSUSEDINCPCN;
6016
6017#ifndef MODE32
6018 if (VECTORACCESS (address) || ADDREXCEPT (address))
6019 INTERNALABORT (address);
6020
6021 if (BIT (15))
6022 PATCHR15;
6023#endif
6024
6025 /* N cycle first. */
6026 for (temp = 0; !BIT (temp); temp++);
6027
6028#ifdef MODE32
6029 ARMul_StoreWordN (state, address, state->Reg[temp++]);
6030#else
6031 if (state->Aborted) {
6032 (void) ARMul_LoadWordN (state, address);
6033
6034 /* Fake the Stores as Loads. */
6035 for (; temp < 16; temp++)
6036 if (BIT (temp)) {
6037 /* Save this register. */
6038 address += 4;
6039 (void) ARMul_LoadWordS (state, address);
6040 }
6041
6042 if (BIT (21) && LHSReg != 15)
6043 LSBase = WBBase;
6044 TAKEABORT;
6045 return;
6046 }
6047 else
6048 ARMul_StoreWordN (state, address, state->Reg[temp++]);
6049#endif
6050
6051 if (state->abortSig && !state->Aborted) {
6052 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
6053 state->Aborted = ARMul_DataAbortV;
6054 }
6055
6056//chy 2004-05-23, needn't store other when aborted
6057 if (state->Aborted)
6058 goto L_stm_takeabort;
6059
6060 /* S cycles from here on. */
6061 for (; temp < 16; temp++)
6062 if (BIT (temp)) {
6063 /* Save this register. */
6064 address += 4;
6065
6066 ARMul_StoreWordS (state, address, state->Reg[temp]);
6067
6068 if (state->abortSig && !state->Aborted) {
6069 XScale_set_fsr_far (state,
6070 ARMul_CP15_R5_ST_ALIGN,
6071 address);
6072 state->Aborted = ARMul_DataAbortV;
6073 }
6074 //chy 2004-05-23, needn't store other when aborted
6075 if (state->Aborted)
6076 goto L_stm_takeabort;
6077
6078 }
6079
6080//chy 2004-05-23,should compare the Abort Models
6081 L_stm_takeabort:
6082 if (BIT (21) && LHSReg != 15) {
6083 if (!
6084 (state->abortSig && state->Aborted
6085 && state->lateabtSig == LOW))
6086 LSBase = WBBase;
6087 }
6088 if (state->Aborted)
6089 TAKEABORT;
6090}
6091
6092/* This function does the work of storing the registers listed in an STM
6093 instruction when the S bit is set. The code here is always increment
6094 after, it's up to the caller to get the input address correct and to
6095 handle base register modification. */
6096
6097static void
6098StoreSMult (ARMul_State * state,
6099 ARMword instr, ARMword address, ARMword WBBase)
6100{
6101 ARMword temp;
6102
6103 UNDEF_LSMNoRegs;
6104 UNDEF_LSMPCBase;
6105 UNDEF_LSMBaseInListWb;
6106
6107 BUSUSEDINCPCN;
6108
6109#ifndef MODE32
6110 if (VECTORACCESS (address) || ADDREXCEPT (address))
6111 INTERNALABORT (address);
6112
6113 if (BIT (15))
6114 PATCHR15;
6115#endif
6116
6117 if (state->Bank != USERBANK) {
6118 /* Force User Bank. */
6119 (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
6120 UNDEF_LSMUserBankWb;
6121 }
6122
6123 for (temp = 0; !BIT (temp); temp++); /* N cycle first. */
6124
6125#ifdef MODE32
6126 ARMul_StoreWordN (state, address, state->Reg[temp++]);
6127#else
6128 if (state->Aborted) {
6129 (void) ARMul_LoadWordN (state, address);
6130
6131 for (; temp < 16; temp++)
6132 /* Fake the Stores as Loads. */
6133 if (BIT (temp)) {
6134 /* Save this register. */
6135 address += 4;
6136
6137 (void) ARMul_LoadWordS (state, address);
6138 }
6139
6140 if (BIT (21) && LHSReg != 15)
6141 LSBase = WBBase;
6142
6143 TAKEABORT;
6144 return;
6145 }
6146 else
6147 ARMul_StoreWordN (state, address, state->Reg[temp++]);
6148#endif
6149
6150 if (state->abortSig && !state->Aborted) {
6151 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
6152 state->Aborted = ARMul_DataAbortV;
6153 }
6154
6155//chy 2004-05-23, needn't store other when aborted
6156 if (state->Aborted)
6157 goto L_stm_s_takeabort;
6158 /* S cycles from here on. */
6159 for (; temp < 16; temp++)
6160 if (BIT (temp)) {
6161 /* Save this register. */
6162 address += 4;
6163
6164 ARMul_StoreWordS (state, address, state->Reg[temp]);
6165
6166 if (state->abortSig && !state->Aborted) {
6167 XScale_set_fsr_far (state,
6168 ARMul_CP15_R5_ST_ALIGN,
6169 address);
6170 state->Aborted = ARMul_DataAbortV;
6171 }
6172 //chy 2004-05-23, needn't store other when aborted
6173 if (state->Aborted)
6174 goto L_stm_s_takeabort;
6175 }
6176
6177 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
6178 if (state->Mode != USER26MODE && state->Mode != USER32MODE )
6179 /* Restore the correct bank. */
6180 (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
6181
6182
6183//chy 2004-05-23,should compare the Abort Models
6184 L_stm_s_takeabort:
6185 if (BIT (21) && LHSReg != 15) {
6186 if (!
6187 (state->abortSig && state->Aborted
6188 && state->lateabtSig == LOW))
6189 LSBase = WBBase;
6190 }
6191
6192 if (state->Aborted)
6193 TAKEABORT;
6194}
6195
6196/* This function does the work of adding two 32bit values
6197 together, and calculating if a carry has occurred. */
6198
6199static ARMword
6200Add32 (ARMword a1, ARMword a2, int *carry)
6201{
6202 ARMword result = (a1 + a2);
6203 unsigned int uresult = (unsigned int) result;
6204 unsigned int ua1 = (unsigned int) a1;
6205
6206 /* If (result == RdLo) and (state->Reg[nRdLo] == 0),
6207 or (result > RdLo) then we have no carry. */
6208 if ((uresult == ua1) ? (a2 != 0) : (uresult < ua1))
6209 *carry = 1;
6210 else
6211 *carry = 0;
6212
6213 return result;
6214}
6215
6216/* This function does the work of multiplying
6217 two 32bit values to give a 64bit result. */
6218
6219static unsigned
6220Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
6221{
6222 /* Operand register numbers. */
6223 int nRdHi, nRdLo, nRs, nRm;
6224 ARMword RdHi = 0, RdLo = 0, Rm;
6225 /* Cycle count. */
6226 int scount;
6227
6228 nRdHi = BITS (16, 19);
6229 nRdLo = BITS (12, 15);
6230 nRs = BITS (8, 11);
6231 nRm = BITS (0, 3);
6232
6233 /* Needed to calculate the cycle count. */
6234 Rm = state->Reg[nRm];
6235
6236 /* Check for illegal operand combinations first. */
6237 if (nRdHi != 15
6238 && nRdLo != 15
6239 && nRs != 15
6240 //&& nRm != 15 && nRdHi != nRdLo && nRdHi != nRm && nRdLo != nRm) {
6241 && nRm != 15 && nRdHi != nRdLo ) {
6242 /* Intermediate results. */
6243 ARMword lo, mid1, mid2, hi;
6244 int carry;
6245 ARMword Rs = state->Reg[nRs];
6246 int sign = 0;
6247
6248 if (msigned) {
6249 /* Compute sign of result and adjust operands if necessary. */
6250 sign = (Rm ^ Rs) & 0x80000000;
6251
6252 if (((signed int) Rm) < 0)
6253 Rm = -Rm;
6254
6255 if (((signed int) Rs) < 0)
6256 Rs = -Rs;
6257 }
6258
6259 /* We can split the 32x32 into four 16x16 operations. This
6260 ensures that we do not lose precision on 32bit only hosts. */
6261 lo = ((Rs & 0xFFFF) * (Rm & 0xFFFF));
6262 mid1 = ((Rs & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
6263 mid2 = (((Rs >> 16) & 0xFFFF) * (Rm & 0xFFFF));
6264 hi = (((Rs >> 16) & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
6265
6266 /* We now need to add all of these results together, taking
6267 care to propogate the carries from the additions. */
6268 RdLo = Add32 (lo, (mid1 << 16), &carry);
6269 RdHi = carry;
6270 RdLo = Add32 (RdLo, (mid2 << 16), &carry);
6271 RdHi += (carry + ((mid1 >> 16) & 0xFFFF) +
6272 ((mid2 >> 16) & 0xFFFF) + hi);
6273
6274 if (sign) {
6275 /* Negate result if necessary. */
6276 RdLo = ~RdLo;
6277 RdHi = ~RdHi;
6278 if (RdLo == 0xFFFFFFFF) {
6279 RdLo = 0;
6280 RdHi += 1;
6281 }
6282 else
6283 RdLo += 1;
6284 }
6285
6286 state->Reg[nRdLo] = RdLo;
6287 state->Reg[nRdHi] = RdHi;
6288 }
6289 else{
6290 fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS, instr=0x%x\n", instr);
6291 }
6292 if (scc)
6293 /* Ensure that both RdHi and RdLo are used to compute Z,
6294 but don't let RdLo's sign bit make it to N. */
6295 ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
6296
6297 /* The cycle count depends on whether the instruction is a signed or
6298 unsigned multiply, and what bits are clear in the multiplier. */
6299 if (msigned && (Rm & ((unsigned) 1 << 31)))
6300 /* Invert the bits to make the check against zero. */
6301 Rm = ~Rm;
6302
6303 if ((Rm & 0xFFFFFF00) == 0)
6304 scount = 1;
6305 else if ((Rm & 0xFFFF0000) == 0)
6306 scount = 2;
6307 else if ((Rm & 0xFF000000) == 0)
6308 scount = 3;
6309 else
6310 scount = 4;
6311
6312 return 2 + scount;
6313}
6314
6315/* This function does the work of multiplying two 32bit
6316 values and adding a 64bit value to give a 64bit result. */
6317
6318static unsigned
6319MultiplyAdd64 (ARMul_State * state, ARMword instr, int msigned, int scc)
6320{
6321 unsigned scount;
6322 ARMword RdLo, RdHi;
6323 int nRdHi, nRdLo;
6324 int carry = 0;
6325
6326 nRdHi = BITS (16, 19);
6327 nRdLo = BITS (12, 15);
6328
6329 RdHi = state->Reg[nRdHi];
6330 RdLo = state->Reg[nRdLo];
6331
6332 scount = Multiply64 (state, instr, msigned, LDEFAULT);
6333
6334 RdLo = Add32 (RdLo, state->Reg[nRdLo], &carry);
6335 RdHi = (RdHi + state->Reg[nRdHi]) + carry;
6336
6337 state->Reg[nRdLo] = RdLo;
6338 state->Reg[nRdHi] = RdHi;
6339
6340 if (scc)
6341 /* Ensure that both RdHi and RdLo are used to compute Z,
6342 but don't let RdLo's sign bit make it to N. */
6343 ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
6344
6345 /* Extra cycle for addition. */
6346 return scount + 1;
6347}
6348
6349/* Attempt to emulate an ARMv6 instruction.
6350 Returns non-zero upon success. */
6351
6352static int
6353handle_v6_insn (ARMul_State * state, ARMword instr)
6354{
6355 switch (BITS (20, 27))
6356 {
6357#if 0
6358 case 0x03: printf ("Unhandled v6 insn: ldr\n"); break;
6359 case 0x04: printf ("Unhandled v6 insn: umaal\n"); break;
6360 case 0x06: printf ("Unhandled v6 insn: mls/str\n"); break;
6361 case 0x16: printf ("Unhandled v6 insn: smi\n"); break;
6362 case 0x18: printf ("Unhandled v6 insn: strex\n"); break;
6363 case 0x19: printf ("Unhandled v6 insn: ldrex\n"); break;
6364 case 0x1a: printf ("Unhandled v6 insn: strexd\n"); break;
6365 case 0x1b: printf ("Unhandled v6 insn: ldrexd\n"); break;
6366 case 0x1c: printf ("Unhandled v6 insn: strexb\n"); break;
6367 case 0x1d: printf ("Unhandled v6 insn: ldrexb\n"); break;
6368 case 0x1e: printf ("Unhandled v6 insn: strexh\n"); break;
6369 case 0x1f: printf ("Unhandled v6 insn: ldrexh\n"); break;
6370 case 0x30: printf ("Unhandled v6 insn: movw\n"); break;
6371 case 0x32: printf ("Unhandled v6 insn: nop/sev/wfe/wfi/yield\n"); break;
6372 case 0x34: printf ("Unhandled v6 insn: movt\n"); break;
6373 case 0x3f: printf ("Unhandled v6 insn: rbit\n"); break;
6374 case 0x61: printf ("Unhandled v6 insn: sadd/ssub\n"); break;
6375 case 0x62: printf ("Unhandled v6 insn: qadd/qsub\n"); break;
6376 case 0x63: printf ("Unhandled v6 insn: shadd/shsub\n"); break;
6377 case 0x65: printf ("Unhandled v6 insn: uadd/usub\n"); break;
6378 case 0x66: printf ("Unhandled v6 insn: uqadd/uqsub\n"); break;
6379 case 0x67: printf ("Unhandled v6 insn: uhadd/uhsub\n"); break;
6380 case 0x68: printf ("Unhandled v6 insn: pkh/sxtab/selsxtb\n"); break;
6381#endif
6382 case 0x6c: printf ("Unhandled v6 insn: uxtb16/uxtab16\n"); break;
6383 case 0x70: printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); break;
6384 case 0x74: printf ("Unhandled v6 insn: smlald/smlsld\n"); break;
6385 case 0x75: printf ("Unhandled v6 insn: smmla/smmls/smmul\n"); break;
6386 case 0x78: printf ("Unhandled v6 insn: usad/usada8\n"); break;
6387#if 0
6388 case 0x7a: printf ("Unhandled v6 insn: usbfx\n"); break;
6389 case 0x7c: printf ("Unhandled v6 insn: bfc/bfi\n"); break;
6390#endif
6391
6392
6393/* add new instr for arm v6. */
6394 ARMword lhs, temp;
6395 case 0x18: /* ORR reg */
6396 {
6397 /* dyf add armv6 instr strex 2010.9.17 */
6398 if (BITS (4, 7) == 0x9) {
6399 lhs = LHS;
6400 ARMul_StoreWordS(state, lhs, RHS);
6401 //StoreWord(state, lhs, RHS)
6402 if (state->Aborted) {
6403 TAKEABORT;
6404 }
6405
6406 return 1;
6407 }
6408 break;
6409 }
6410
6411 case 0x19: /* orrs reg */
6412 {
6413 /* dyf add armv6 instr ldrex */
6414 if (BITS (4, 7) == 0x9) {
6415 lhs = LHS;
6416 LoadWord (state, instr, lhs);
6417 return 1;
6418 }
6419 break;
6420 }
6421
6422 case 0x1c: /* BIC reg */
6423 {
6424 /* dyf add for STREXB */
6425 if (BITS (4, 7) == 0x9) {
6426 lhs = LHS;
6427 ARMul_StoreByte (state, lhs, RHS);
6428 BUSUSEDINCPCN;
6429 if (state->Aborted) {
6430 TAKEABORT;
6431 }
6432
6433 //printf("In %s, strexb not implemented\n", __FUNCTION__);
6434 UNDEF_LSRBPC;
6435 /* WRITESDEST (dest); */
6436 return 1;
6437 }
6438 break;
6439 }
6440
6441 case 0x1d: /* BICS reg */
6442 {
6443 if ((BITS (4, 7)) == 0x9) {
6444 /* ldrexb */
6445 temp = LHS;
6446 LoadByte (state, instr, temp, LUNSIGNED);
6447 //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]);
6448 //printf("ldrexb\n");
6449 //printf("instr is %x rm is %d\n", instr, BITS(16, 19));
6450 //exit(-1);
6451
6452 //printf("In %s, ldrexb not implemented\n", __FUNCTION__);
6453 return 1;
6454 }
6455 break;
6456 }
6457/* add end */
6458
6459 case 0x6a:
6460 {
6461 ARMword Rm;
6462 int ror = -1;
6463
6464 switch (BITS (4, 11))
6465 {
6466 case 0x07: ror = 0; break;
6467 case 0x47: ror = 8; break;
6468 case 0x87: ror = 16; break;
6469 case 0xc7: ror = 24; break;
6470
6471 case 0x01:
6472 case 0xf3:
6473 printf ("Unhandled v6 insn: ssat\n");
6474 return 0;
6475 default:
6476 break;
6477 }
6478
6479 if (ror == -1)
6480 {
6481 if (BITS (4, 6) == 0x7)
6482 {
6483 printf ("Unhandled v6 insn: ssat\n");
6484 return 0;
6485 }
6486 break;
6487 }
6488
6489 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF);
6490 if (Rm & 0x80)
6491 Rm |= 0xffffff00;
6492
6493 if (BITS (16, 19) == 0xf)
6494 /* SXTB */
6495 state->Reg[BITS (12, 15)] = Rm;
6496 else
6497 /* SXTAB */
6498 state->Reg[BITS (12, 15)] += Rm;
6499 }
6500 return 1;
6501
6502 case 0x6b:
6503 {
6504 ARMword Rm;
6505 int ror = -1;
6506
6507 switch (BITS (4, 11))
6508 {
6509 case 0x07: ror = 0; break;
6510 case 0x47: ror = 8; break;
6511 case 0x87: ror = 16; break;
6512 case 0xc7: ror = 24; break;
6513
6514 case 0xf3:
6515 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24);
6516 return 1;
6517 case 0xfb:
6518 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8);
6519 return 1;
6520 default:
6521 break;
6522 }
6523
6524 if (ror == -1)
6525 break;
6526
6527 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF);
6528 if (Rm & 0x8000)
6529 Rm |= 0xffff0000;
6530
6531 if (BITS (16, 19) == 0xf)
6532 /* SXTH */
6533 state->Reg[BITS (12, 15)] = Rm;
6534 else
6535 /* SXTAH */
6536 state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm;
6537 }
6538 return 1;
6539
6540 case 0x6e:
6541 {
6542 ARMword Rm;
6543 int ror = -1;
6544
6545 switch (BITS (4, 11))
6546 {
6547 case 0x07: ror = 0; break;
6548 case 0x47: ror = 8; break;
6549 case 0x87: ror = 16; break;
6550 case 0xc7: ror = 24; break;
6551
6552 case 0x01:
6553 case 0xf3:
6554 printf ("Unhandled v6 insn: usat\n");
6555 return 0;
6556 default:
6557 break;
6558 }
6559
6560 if (ror == -1)
6561 {
6562 if (BITS (4, 6) == 0x7)
6563 {
6564 printf ("Unhandled v6 insn: usat\n");
6565 return 0;
6566 }
6567 break;
6568 }
6569
6570 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF);
6571
6572 if (BITS (16, 19) == 0xf)
6573 /* UXTB */
6574 state->Reg[BITS (12, 15)] = Rm;
6575 else
6576 /* UXTAB */
6577 state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm;
6578 }
6579 return 1;
6580
6581 case 0x6f:
6582 {
6583 ARMword Rm;
6584 int ror = -1;
6585
6586 switch (BITS (4, 11))
6587 {
6588 case 0x07: ror = 0; break;
6589 case 0x47: ror = 8; break;
6590 case 0x87: ror = 16; break;
6591 case 0xc7: ror = 24; break;
6592
6593 case 0xfb:
6594 printf ("Unhandled v6 insn: revsh\n");
6595 return 0;
6596 default:
6597 break;
6598 }
6599
6600 if (ror == -1)
6601 break;
6602
6603 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF);
6604
6605 /* UXT */
6606 /* state->Reg[BITS (12, 15)] = Rm; */
6607 /* dyf add */
6608 if (BITS (16, 19) == 0xf) {
6609 state->Reg[BITS (12, 15)] = (Rm >> (8 * BITS(10, 11))) & 0x0000FFFF;
6610 } else {
6611 /* UXTAH */
6612 /* state->Reg[BITS (12, 15)] = state->Reg [BITS (16, 19)] + Rm; */
6613// printf("rd is %x rn is %x rm is %x rotate is %x\n", state->Reg[BITS (12, 15)], state->Reg[BITS (16, 19)]
6614// , Rm, BITS(10, 11));
6615// printf("icounter is %lld\n", state->NumInstrs);
6616 state->Reg[BITS (12, 15)] = (state->Reg[BITS (16, 19)] >> (8 * (BITS(10, 11)))) + Rm;
6617// printf("rd is %x\n", state->Reg[BITS (12, 15)]);
6618// exit(-1);
6619 }
6620 }
6621 return 1;
6622
6623#if 0
6624 case 0x84: printf ("Unhandled v6 insn: srs\n"); break;
6625#endif
6626 default:
6627 break;
6628 }
6629 printf ("Unhandled v6 insn: UNKNOWN: %08x\n", instr);
6630 return 0;
6631}