summaryrefslogtreecommitdiff
path: root/src/core/arm/interpreter
diff options
context:
space:
mode:
authorGravatar bunnei2014-04-08 19:25:03 -0400
committerGravatar bunnei2014-04-08 19:25:03 -0400
commit63e46abdb8764bc97e91bae862c8d461e61b1965 (patch)
treee73f4aa25d7b4015a265e7bbfb6004dab7561027 /src/core/arm/interpreter
parentfixed some license headers that I missed (diff)
downloadyuzu-63e46abdb8764bc97e91bae862c8d461e61b1965.tar.gz
yuzu-63e46abdb8764bc97e91bae862c8d461e61b1965.tar.xz
yuzu-63e46abdb8764bc97e91bae862c8d461e61b1965.zip
got rid of 'src' folders in each sub-project
Diffstat (limited to 'src/core/arm/interpreter')
-rw-r--r--src/core/arm/interpreter/arm_interpreter.cpp86
-rw-r--r--src/core/arm/interpreter/arm_interpreter.h57
-rw-r--r--src/core/arm/interpreter/arm_regformat.h103
-rw-r--r--src/core/arm/interpreter/armcpu.h83
-rw-r--r--src/core/arm/interpreter/armdefs.h934
-rw-r--r--src/core/arm/interpreter/armemu.cpp6631
-rw-r--r--src/core/arm/interpreter/armemu.h659
-rw-r--r--src/core/arm/interpreter/arminit.cpp579
-rw-r--r--src/core/arm/interpreter/armmmu.cpp238
-rw-r--r--src/core/arm/interpreter/armmmu.h254
-rw-r--r--src/core/arm/interpreter/armos.cpp742
-rw-r--r--src/core/arm/interpreter/armos.h138
-rw-r--r--src/core/arm/interpreter/armsupp.cpp954
-rw-r--r--src/core/arm/interpreter/armvirt.cpp680
-rw-r--r--src/core/arm/interpreter/skyeye_defs.h111
-rw-r--r--src/core/arm/interpreter/thumbemu.cpp513
16 files changed, 12762 insertions, 0 deletions
diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp
new file mode 100644
index 000000000..a74aa26cc
--- /dev/null
+++ b/src/core/arm/interpreter/arm_interpreter.cpp
@@ -0,0 +1,86 @@
1/**
2 * Copyright (C) 2013 Citrus Emulator
3 *
4 * @file arm_interpreter.h
5 * @author bunnei
6 * @date 2014-04-04
7 * @brief ARM interface instance for SkyEye interprerer
8 *
9 * @section LICENSE
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details at
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * Official project repository can be found at:
22 * http://code.google.com/p/gekko-gc-emu/
23 */
24
25#include "arm_interpreter.h"
26
27const static cpu_config_t s_arm11_cpu_info = {
28 "armv6", "arm11", 0x0007b000, 0x0007f000, NONCACHE
29};
30
31ARM_Interpreter::ARM_Interpreter() {
32
33 state = new ARMul_State;
34
35 ARMul_EmulateInit();
36 ARMul_NewState(state);
37
38 state->abort_model = 0;
39 state->cpu = (cpu_config_t*)&s_arm11_cpu_info;
40 state->bigendSig = LOW;
41
42 ARMul_SelectProcessor(state, ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop);
43 state->lateabtSig = LOW;
44 mmu_init(state);
45
46 // Reset the core to initial state
47 ARMul_Reset(state);
48 state->NextInstr = 0;
49 state->Emulate = 3;
50
51 state->pc = state->Reg[15] = 0x00000000;
52 state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
53}
54
55void ARM_Interpreter::SetPC(u32 pc) {
56 state->pc = state->Reg[15] = pc;
57}
58
59u32 ARM_Interpreter::PC() {
60 return state->pc;
61}
62
63u32 ARM_Interpreter::Reg(int index){
64 return state->Reg[index];
65}
66
67u32 ARM_Interpreter::CPSR() {
68 return state->Cpsr;
69}
70
71ARM_Interpreter::~ARM_Interpreter() {
72 delete state;
73}
74
75void ARM_Interpreter::ExecuteInstruction() {
76 state->step++;
77 state->cycle++;
78 state->EndCondition = 0;
79 state->stop_simulator = 0;
80 state->NextInstr = RESUME;
81 state->last_pc = state->Reg[15];
82 state->Reg[15] = ARMul_DoInstr(state);
83 state->Cpsr = ((state->Cpsr & 0x0fffffdf) | (state->NFlag << 31) | (state->ZFlag << 30) |
84 (state->CFlag << 29) | (state->VFlag << 28) | (state->TFlag << 5));
85 FLUSHPIPE;
86}
diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h
new file mode 100644
index 000000000..074149f1b
--- /dev/null
+++ b/src/core/arm/interpreter/arm_interpreter.h
@@ -0,0 +1,57 @@
1/**
2* Copyright (C) 2013 Citrus Emulator
3*
4* @file arm_interpreter.h
5* @author bunnei
6* @date 2014-04-04
7* @brief ARM interface instance for SkyEye interprerer
8*
9* @section LICENSE
10* This program is free software; you can redistribute it and/or
11* modify it under the terms of the GNU General Public License as
12* published by the Free Software Foundation; either version 2 of
13* the License, or (at your option) any later version.
14*
15* This program is distributed in the hope that it will be useful, but
16* WITHOUT ANY WARRANTY; without even the implied warranty of
17* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18* General Public License for more details at
19* http://www.gnu.org/copyleft/gpl.html
20*
21* Official project repository can be found at:
22* http://code.google.com/p/gekko-gc-emu/
23*/
24
25#pragma once
26
27#include "common.h"
28#include "common_types.h"
29#include "arm/arm_interface.h"
30
31#include "arm/interpreter/armdefs.h"
32#include "arm/interpreter/armemu.h"
33
34class ARM_Interpreter : virtual public ARM_Interface {
35public:
36 ARM_Interpreter();
37 ~ARM_Interpreter();
38
39 void ExecuteInstruction();
40
41 void SetPC(u32 pc);
42
43 u32 PC();
44
45 u32 Reg(int index);
46
47 u32 CPSR();
48
49 u64 GetTicks() {
50 return ARMul_Time(state);
51 }
52
53private:
54 ARMul_State* state;
55
56 DISALLOW_COPY_AND_ASSIGN(ARM_Interpreter);
57};
diff --git a/src/core/arm/interpreter/arm_regformat.h b/src/core/arm/interpreter/arm_regformat.h
new file mode 100644
index 000000000..0ca62780b
--- /dev/null
+++ b/src/core/arm/interpreter/arm_regformat.h
@@ -0,0 +1,103 @@
1#ifndef __ARM_REGFORMAT_H__
2#define __ARM_REGFORMAT_H__
3
4enum arm_regno{
5 R0 = 0,
6 R1,
7 R2,
8 R3,
9 R4,
10 R5,
11 R6,
12 R7,
13 R8,
14 R9,
15 R10,
16 R11,
17 R12,
18 R13,
19 LR,
20 R15, //PC,
21 CPSR_REG,
22 SPSR_REG,
23#if 1
24 PHYS_PC,
25 R13_USR,
26 R14_USR,
27 R13_SVC,
28 R14_SVC,
29 R13_ABORT,
30 R14_ABORT,
31 R13_UNDEF,
32 R14_UNDEF,
33 R13_IRQ,
34 R14_IRQ,
35 R8_FIRQ,
36 R9_FIRQ,
37 R10_FIRQ,
38 R11_FIRQ,
39 R12_FIRQ,
40 R13_FIRQ,
41 R14_FIRQ,
42 SPSR_INVALID1,
43 SPSR_INVALID2,
44 SPSR_SVC,
45 SPSR_ABORT,
46 SPSR_UNDEF,
47 SPSR_IRQ,
48 SPSR_FIRQ,
49 MODE_REG, /* That is the cpsr[4 : 0], just for calculation easily */
50 BANK_REG,
51 EXCLUSIVE_TAG,
52 EXCLUSIVE_STATE,
53 EXCLUSIVE_RESULT,
54 CP15_BASE,
55 CP15_C0 = CP15_BASE,
56 CP15_C0_C0 = CP15_C0,
57 CP15_MAIN_ID = CP15_C0_C0,
58 CP15_CACHE_TYPE,
59 CP15_TCM_STATUS,
60 CP15_TLB_TYPE,
61 CP15_C0_C1,
62 CP15_PROCESSOR_FEATURE_0 = CP15_C0_C1,
63 CP15_PROCESSOR_FEATURE_1,
64 CP15_DEBUG_FEATURE_0,
65 CP15_AUXILIARY_FEATURE_0,
66 CP15_C1_C0,
67 CP15_CONTROL = CP15_C1_C0,
68 CP15_AUXILIARY_CONTROL,
69 CP15_COPROCESSOR_ACCESS_CONTROL,
70 CP15_C2,
71 CP15_C2_C0 = CP15_C2,
72 CP15_TRANSLATION_BASE = CP15_C2_C0,
73 CP15_TRANSLATION_BASE_TABLE_0 = CP15_TRANSLATION_BASE,
74 CP15_TRANSLATION_BASE_TABLE_1,
75 CP15_TRANSLATION_BASE_CONTROL,
76 CP15_DOMAIN_ACCESS_CONTROL,
77 CP15_RESERVED,
78 /* Fault status */
79 CP15_FAULT_STATUS,
80 CP15_INSTR_FAULT_STATUS,
81 CP15_COMBINED_DATA_FSR = CP15_FAULT_STATUS,
82 CP15_INST_FSR,
83 /* Fault Address register */
84 CP15_FAULT_ADDRESS,
85 CP15_COMBINED_DATA_FAR = CP15_FAULT_ADDRESS,
86 CP15_WFAR,
87 CP15_IFAR,
88 CP15_PID,
89 CP15_CONTEXT_ID,
90 CP15_THREAD_URO,
91 CP15_TLB_FAULT_ADDR, /* defined by SkyEye */
92 CP15_TLB_FAULT_STATUS, /* defined by SkyEye */
93 /* VFP registers */
94 VFP_BASE,
95 VFP_FPSID = VFP_BASE,
96 VFP_FPSCR,
97 VFP_FPEXC,
98#endif
99 MAX_REG_NUM,
100};
101
102#define VFP_OFFSET(x) (x - VFP_BASE)
103#endif
diff --git a/src/core/arm/interpreter/armcpu.h b/src/core/arm/interpreter/armcpu.h
new file mode 100644
index 000000000..d7e336b94
--- /dev/null
+++ b/src/core/arm/interpreter/armcpu.h
@@ -0,0 +1,83 @@
1/*
2 * arm
3 * armcpu.h
4 *
5 * Copyright (C) 2003, 2004 Sebastian Biallas (sb@biallas.net)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef __ARM_CPU_H__
22#define __ARM_CPU_H__
23//#include <skyeye_thread.h>
24//#include <skyeye_obj.h>
25//#include <skyeye_mach.h>
26//#include <skyeye_exec.h>
27
28#include <stddef.h>
29#include <stdio.h>
30
31#include "thread.h"
32
33
34typedef struct ARM_CPU_State_s {
35 ARMul_State * core;
36 uint32_t core_num;
37 /* The core id that boot from
38 */
39 uint32_t boot_core_id;
40}ARM_CPU_State;
41
42//static ARM_CPU_State* get_current_cpu(){
43// machine_config_t* mach = get_current_mach();
44// /* Casting a conf_obj_t to ARM_CPU_State type */
45// ARM_CPU_State* cpu = (ARM_CPU_State*)mach->cpu_data->obj;
46//
47// return cpu;
48//}
49
50/**
51* @brief Get the core instance boot from
52*
53* @return
54*/
55//static ARMul_State* get_boot_core(){
56// ARM_CPU_State* cpu = get_current_cpu();
57// return &cpu->core[cpu->boot_core_id];
58//}
59/**
60* @brief Get the instance of running core
61*
62* @return the core instance
63*/
64//static ARMul_State* get_current_core(){
65// /* Casting a conf_obj_t to ARM_CPU_State type */
66// int id = Common::CurrentThreadId();
67// /* If thread is not in running mode, we should give the boot core */
68// if(get_thread_state(id) != Running_state){
69// return get_boot_core();
70// }
71// /* Judge if we are running in paralell or sequenial */
72// if(thread_exist(id)){
73// conf_object_t* conf_obj = get_current_exec_priv(id);
74// return (ARMul_State*)get_cast_conf_obj(conf_obj, "arm_core_t");
75// }
76//
77// return NULL;
78//}
79
80#define CURRENT_CORE get_current_core()
81
82#endif
83
diff --git a/src/core/arm/interpreter/armdefs.h b/src/core/arm/interpreter/armdefs.h
new file mode 100644
index 000000000..0136a52d2
--- /dev/null
+++ b/src/core/arm/interpreter/armdefs.h
@@ -0,0 +1,934 @@
1/* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18#ifndef _ARMDEFS_H_
19#define _ARMDEFS_H_
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <errno.h>
24
25#if EMU_PLATFORM == PLATFORM_WINDOWS
26#include <windows.h>
27#endif
28
29//teawater add for arm2x86 2005.02.14-------------------------------------------
30// koodailar remove it for mingw 2005.12.18----------------
31//anthonylee modify it for portable 2007.01.30
32//#include "portable/mman.h"
33
34#include "arm_regformat.h"
35#include "platform.h"
36#include "skyeye_defs.h"
37
38//AJ2D--------------------------------------------------------------------------
39
40//teawater add for arm2x86 2005.07.03-------------------------------------------
41
42#include <sys/types.h>
43#include <stdio.h>
44#include <stdlib.h>
45#include <string.h>
46#if EMU_PLATFORM == PLATFORM_LINUX
47#include <unistd.h>
48#endif
49#include <errno.h>
50#include <sys/stat.h>
51#include <fcntl.h>
52
53//#include <memory_space.h>
54//AJ2D--------------------------------------------------------------------------
55#if 0
56#if 0
57#define DIFF_STATE 1
58#define __FOLLOW_MODE__ 0
59#else
60#define DIFF_STATE 0
61#define __FOLLOW_MODE__ 1
62#endif
63#endif
64
65#ifndef FALSE
66#define FALSE 0
67#define TRUE 1
68#endif
69
70#define LOW 0
71#define HIGH 1
72#define LOWHIGH 1
73#define HIGHLOW 2
74
75#ifndef u8
76#define u8 unsigned char
77#define u16 unsigned short
78#define u32 unsigned int
79#define u64 unsigned long long
80#endif /*u8 */
81
82//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------
83#include <signal.h>
84
85#include "platform.h"
86
87#if EMU_PLATFORM == PLATFORM_LINUX
88#include <sys/time.h>
89#endif
90
91//#define DBCT_TEST_SPEED
92#define DBCT_TEST_SPEED_SEC 10
93//AJ2D--------------------------------------------------------------------------
94
95//teawater add compile switch for DBCT GDB RSP function 2005.10.21--------------
96//#define DBCT_GDBRSP
97//AJ2D--------------------------------------------------------------------------
98
99//#include <skyeye_defs.h>
100//#include <skyeye_types.h>
101
102#define ARM_BYTE_TYPE 0
103#define ARM_HALFWORD_TYPE 1
104#define ARM_WORD_TYPE 2
105
106//the define of cachetype
107#define NONCACHE 0
108#define DATACACHE 1
109#define INSTCACHE 2
110
111#ifndef __STDC__
112typedef char *VoidStar;
113#endif
114
115typedef unsigned long long ARMdword; /* must be 64 bits wide */
116typedef unsigned int ARMword; /* must be 32 bits wide */
117typedef unsigned char ARMbyte; /* must be 8 bits wide */
118typedef unsigned short ARMhword; /* must be 16 bits wide */
119typedef struct ARMul_State ARMul_State;
120typedef struct ARMul_io ARMul_io;
121typedef struct ARMul_Energy ARMul_Energy;
122
123//teawater add for arm2x86 2005.06.24-------------------------------------------
124#include <stdint.h>
125//AJ2D--------------------------------------------------------------------------
126/*
127//chy 2005-05-11
128#ifndef __CYGWIN__
129//teawater add for arm2x86 2005.02.14-------------------------------------------
130typedef unsigned char uint8_t;
131typedef unsigned short uint16_t;
132typedef unsigned int u32;
133#if defined (__x86_64__)
134typedef unsigned long uint64_t;
135#else
136typedef unsigned long long uint64_t;
137#endif
138////AJ2D--------------------------------------------------------------------------
139#endif
140*/
141
142#include "armmmu.h"
143//#include "lcd/skyeye_lcd.h"
144
145
146//#include "skyeye.h"
147//#include "skyeye_device.h"
148//#include "net/skyeye_net.h"
149//#include "skyeye_config.h"
150
151
152typedef unsigned ARMul_CPInits (ARMul_State * state);
153typedef unsigned ARMul_CPExits (ARMul_State * state);
154typedef unsigned ARMul_LDCs (ARMul_State * state, unsigned type,
155 ARMword instr, ARMword value);
156typedef unsigned ARMul_STCs (ARMul_State * state, unsigned type,
157 ARMword instr, ARMword * value);
158typedef unsigned ARMul_MRCs (ARMul_State * state, unsigned type,
159 ARMword instr, ARMword * value);
160typedef unsigned ARMul_MCRs (ARMul_State * state, unsigned type,
161 ARMword instr, ARMword value);
162typedef unsigned ARMul_MRRCs (ARMul_State * state, unsigned type,
163 ARMword instr, ARMword * value1, ARMword * value2);
164typedef unsigned ARMul_MCRRs (ARMul_State * state, unsigned type,
165 ARMword instr, ARMword value1, ARMword value2);
166typedef unsigned ARMul_CDPs (ARMul_State * state, unsigned type,
167 ARMword instr);
168typedef unsigned ARMul_CPReads (ARMul_State * state, unsigned reg,
169 ARMword * value);
170typedef unsigned ARMul_CPWrites (ARMul_State * state, unsigned reg,
171 ARMword value);
172
173
174//added by ksh,2004-3-5
175struct ARMul_io
176{
177 ARMword *instr; //to display the current interrupt state
178 ARMword *net_flag; //to judge if network is enabled
179 ARMword *net_int; //netcard interrupt
180
181 //ywc,2004-04-01
182 ARMword *ts_int;
183 ARMword *ts_is_enable;
184 ARMword *ts_addr_begin;
185 ARMword *ts_addr_end;
186 ARMword *ts_buffer;
187};
188
189/* added by ksh,2004-11-26,some energy profiling */
190struct ARMul_Energy
191{
192 int energy_prof; /* <tktan> BUG200103282109 : for energy profiling */
193 int enable_func_energy; /* <tktan> BUG200105181702 */
194 char *func_energy;
195 int func_display; /* <tktan> BUG200103311509 : for function call display */
196 int func_disp_start; /* <tktan> BUG200104191428 : to start func profiling */
197 char *start_func; /* <tktan> BUG200104191428 */
198
199 FILE *outfile; /* <tktan> BUG200105201531 : direct console to file */
200 long long tcycle, pcycle;
201 float t_energy;
202 void *cur_task; /* <tktan> BUG200103291737 */
203 long long t_mem_cycle, t_idle_cycle, t_uart_cycle;
204 long long p_mem_cycle, p_idle_cycle, p_uart_cycle;
205 long long p_io_update_tcycle;
206 /*record CCCR,to get current core frequency */
207 ARMword cccr;
208};
209#if 0
210#define MAX_BANK 8
211#define MAX_STR 1024
212
213typedef struct mem_bank
214{
215 ARMword (*read_byte) (ARMul_State * state, ARMword addr);
216 void (*write_byte) (ARMul_State * state, ARMword addr, ARMword data);
217 ARMword (*read_halfword) (ARMul_State * state, ARMword addr);
218 void (*write_halfword) (ARMul_State * state, ARMword addr,
219 ARMword data);
220 ARMword (*read_word) (ARMul_State * state, ARMword addr);
221 void (*write_word) (ARMul_State * state, ARMword addr, ARMword data);
222 unsigned int addr, len;
223 char filename[MAX_STR];
224 unsigned type; //chy 2003-09-21: maybe io,ram,rom
225} mem_bank_t;
226typedef struct
227{
228 int bank_num;
229 int current_num; /*current num of bank */
230 mem_bank_t mem_banks[MAX_BANK];
231} mem_config_t;
232#endif
233#define VFP_REG_NUM 64
234struct ARMul_State
235{
236 ARMword Emulate; /* to start and stop emulation */
237 unsigned EndCondition; /* reason for stopping */
238 unsigned ErrorCode; /* type of illegal instruction */
239
240 /* Order of the following register should not be modified */
241 ARMword Reg[16]; /* the current register file */
242 ARMword Cpsr; /* the current psr */
243 ARMword Spsr_copy;
244 ARMword phys_pc;
245 ARMword Reg_usr[2];
246 ARMword Reg_svc[2]; /* R13_SVC R14_SVC */
247 ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */
248 ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */
249 ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */
250 ARMword Reg_firq[7]; /* R8---R14 FIRQ */
251 ARMword Spsr[7]; /* the exception psr's */
252 ARMword Mode; /* the current mode */
253 ARMword Bank; /* the current register bank */
254 ARMword exclusive_tag;
255 ARMword exclusive_state;
256 ARMword exclusive_result;
257 ARMword CP15[VFP_BASE - CP15_BASE];
258 ARMword VFP[3]; /* FPSID, FPSCR, and FPEXC */
259 /* VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31).
260 VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31),
261 and only 32 singleword registers are accessible (S0-S31). */
262 ARMword ExtReg[VFP_REG_NUM];
263 /* ---- End of the ordered registers ---- */
264
265 ARMword RegBank[7][16]; /* all the registers */
266 //chy:2003-08-19, used in arm xscale
267 /* 40 bit accumulator. We always keep this 64 bits wide,
268 and move only 40 bits out of it in an MRA insn. */
269 ARMdword Accumulator;
270
271 ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags; /* dummy flags for speed */
272 unsigned long long int icounter, debug_icounter, kernel_icounter;
273 unsigned int shifter_carry_out;
274 //ARMword translate_pc;
275
276 /* add armv6 flags dyf:2010-08-09 */
277 ARMword GEFlag, EFlag, AFlag, QFlags;
278 //chy:2003-08-19, used in arm v5e|xscale
279 ARMword SFlag;
280#ifdef MODET
281 ARMword TFlag; /* Thumb state */
282#endif
283 ARMword instr, pc, temp; /* saved register state */
284 ARMword loaded, decoded; /* saved pipeline state */
285 //chy 2006-04-12 for ICE breakpoint
286 ARMword loaded_addr, decoded_addr; /* saved pipeline state addr*/
287 unsigned int NumScycles, NumNcycles, NumIcycles, NumCcycles, NumFcycles; /* emulated cycles used */
288 unsigned long long NumInstrs; /* the number of instructions executed */
289 unsigned NextInstr;
290 unsigned VectorCatch; /* caught exception mask */
291 unsigned CallDebug; /* set to call the debugger */
292 unsigned CanWatch; /* set by memory interface if its willing to suffer the
293 overhead of checking for watchpoints on each memory
294 access */
295 unsigned int StopHandle;
296
297 char *CommandLine; /* Command Line from ARMsd */
298
299 ARMul_CPInits *CPInit[16]; /* coprocessor initialisers */
300 ARMul_CPExits *CPExit[16]; /* coprocessor finalisers */
301 ARMul_LDCs *LDC[16]; /* LDC instruction */
302 ARMul_STCs *STC[16]; /* STC instruction */
303 ARMul_MRCs *MRC[16]; /* MRC instruction */
304 ARMul_MCRs *MCR[16]; /* MCR instruction */
305 ARMul_MRRCs *MRRC[16]; /* MRRC instruction */
306 ARMul_MCRRs *MCRR[16]; /* MCRR instruction */
307 ARMul_CDPs *CDP[16]; /* CDP instruction */
308 ARMul_CPReads *CPRead[16]; /* Read CP register */
309 ARMul_CPWrites *CPWrite[16]; /* Write CP register */
310 unsigned char *CPData[16]; /* Coprocessor data */
311 unsigned char const *CPRegWords[16]; /* map of coprocessor register sizes */
312
313 unsigned EventSet; /* the number of events in the queue */
314 unsigned int Now; /* time to the nearest cycle */
315 struct EventNode **EventPtr; /* the event list */
316
317 unsigned Debug; /* show instructions as they are executed */
318 unsigned NresetSig; /* reset the processor */
319 unsigned NfiqSig;
320 unsigned NirqSig;
321
322 unsigned abortSig;
323 unsigned NtransSig;
324 unsigned bigendSig;
325 unsigned prog32Sig;
326 unsigned data32Sig;
327 unsigned syscallSig;
328
329/* 2004-05-09 chy
330----------------------------------------------------------
331read ARM Architecture Reference Manual
3322.6.5 Data Abort
333There are three Abort Model in ARM arch.
334
335Early Abort Model: used in some ARMv3 and earlier implementations. In this
336model, base register wirteback occurred for LDC,LDM,STC,STM instructions, and
337the base register was unchanged for all other instructions. (oldest)
338
339Base Restored Abort Model: If a Data Abort occurs in an instruction which
340specifies base register writeback, the value in the base register is
341unchanged. (strongarm, xscale)
342
343Base Updated Abort Model: If a Data Abort occurs in an instruction which
344specifies base register writeback, the base register writeback still occurs.
345(arm720T)
346
347read PART B
348chap2 The System Control Coprocessor CP15
3492.4 Register1:control register
350L(bit 6): in some ARMv3 and earlier implementations, the abort model of the
351processor could be configured:
3520=early Abort Model Selected(now obsolete)
3531=Late Abort Model selceted(same as Base Updated Abort Model)
354
355on later processors, this bit reads as 1 and ignores writes.
356-------------------------------------------------------------
357So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model)
358 if lateabtSig=0, then it means Base Restored Abort Model
359*/
360 unsigned lateabtSig;
361
362 ARMword Vector; /* synthesize aborts in cycle modes */
363 ARMword Aborted; /* sticky flag for aborts */
364 ARMword Reseted; /* sticky flag for Reset */
365 ARMword Inted, LastInted; /* sticky flags for interrupts */
366 ARMword Base; /* extra hand for base writeback */
367 ARMword AbortAddr; /* to keep track of Prefetch aborts */
368
369 const struct Dbg_HostosInterface *hostif;
370
371 int verbose; /* non-zero means print various messages like the banner */
372
373 mmu_state_t mmu;
374 int mmu_inited;
375 //mem_state_t mem;
376 /*remove io_state to skyeye_mach_*.c files */
377 //io_state_t io;
378 /* point to a interrupt pending register. now for skyeye-ne2k.c
379 * later should move somewhere. e.g machine_config_t*/
380
381
382 //chy: 2003-08-11, for different arm core type
383 unsigned is_v4; /* Are we emulating a v4 architecture (or higher) ? */
384 unsigned is_v5; /* Are we emulating a v5 architecture ? */
385 unsigned is_v5e; /* Are we emulating a v5e architecture ? */
386 unsigned is_v6; /* Are we emulating a v6 architecture ? */
387 unsigned is_v7; /* Are we emulating a v7 architecture ? */
388 unsigned is_XScale; /* Are we emulating an XScale architecture ? */
389 unsigned is_iWMMXt; /* Are we emulating an iWMMXt co-processor ? */
390 unsigned is_ep9312; /* Are we emulating a Cirrus Maverick co-processor ? */
391 //chy 2005-09-19
392 unsigned is_pxa27x; /* Are we emulating a Intel PXA27x co-processor ? */
393 //chy: seems only used in xscale's CP14
394 unsigned int LastTime; /* Value of last call to ARMul_Time() */
395 ARMword CP14R0_CCD; /* used to count 64 clock cycles with CP14 R0 bit 3 set */
396
397
398//added by ksh:for handle different machs io 2004-3-5
399 ARMul_io mach_io;
400
401/*added by ksh,2004-11-26,some energy profiling*/
402 ARMul_Energy energy;
403
404//teawater add for next_dis 2004.10.27-----------------------
405 int disassemble;
406//AJ2D------------------------------------------
407
408//teawater add for arm2x86 2005.02.15-------------------------------------------
409 u32 trap;
410 u32 tea_break_addr;
411 u32 tea_break_ok;
412 int tea_pc;
413//AJ2D--------------------------------------------------------------------------
414//teawater add for arm2x86 2005.07.03-------------------------------------------
415
416 /*
417 * 2007-01-24 removed the term-io functions by Anthony Lee,
418 * moved to "device/uart/skyeye_uart_stdio.c".
419 */
420
421//AJ2D--------------------------------------------------------------------------
422//teawater add for arm2x86 2005.07.05-------------------------------------------
423 //arm_arm A2-18
424 int abort_model; //0 Base Restored Abort Model, 1 the Early Abort Model, 2 Base Updated Abort Model
425//AJ2D--------------------------------------------------------------------------
426//teawater change for return if running tb dirty 2005.07.09---------------------
427 void *tb_now;
428//AJ2D--------------------------------------------------------------------------
429
430//teawater add for record reg value to ./reg.txt 2005.07.10---------------------
431 FILE *tea_reg_fd;
432//AJ2D--------------------------------------------------------------------------
433
434/*added by ksh in 2005-10-1*/
435 cpu_config_t *cpu;
436 //mem_config_t *mem_bank;
437
438/* added LPC remap function */
439 int vector_remap_flag;
440 u32 vector_remap_addr;
441 u32 vector_remap_size;
442
443 u32 step;
444 u32 cycle;
445 int stop_simulator;
446 conf_object_t *dyncom_cpu;
447//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------
448#ifdef DBCT_TEST_SPEED
449 uint64_t instr_count;
450#endif //DBCT_TEST_SPEED
451// FILE * state_log;
452//diff log
453//#if DIFF_STATE
454 FILE * state_log;
455//#endif
456 /* monitored memory for exclusice access */
457 ARMword exclusive_tag_array[128];
458 /* 1 means exclusive access and 0 means open access */
459 ARMword exclusive_access_state;
460
461 memory_space_intf space;
462 u32 CurrInstr;
463 u32 last_pc; /* the last pc executed */
464 u32 last_instr; /* the last inst executed */
465 u32 WriteAddr[17];
466 u32 WriteData[17];
467 u32 WritePc[17];
468 u32 CurrWrite;
469};
470#define DIFF_WRITE 0
471
472typedef ARMul_State arm_core_t;
473#define ResetPin NresetSig
474#define FIQPin NfiqSig
475#define IRQPin NirqSig
476#define AbortPin abortSig
477#define TransPin NtransSig
478#define BigEndPin bigendSig
479#define Prog32Pin prog32Sig
480#define Data32Pin data32Sig
481#define LateAbortPin lateabtSig
482
483/***************************************************************************\
484* Types of ARM we know about *
485\***************************************************************************/
486
487/* The bitflags */
488#define ARM_Fix26_Prop 0x01
489#define ARM_Nexec_Prop 0x02
490#define ARM_Debug_Prop 0x10
491#define ARM_Isync_Prop ARM_Debug_Prop
492#define ARM_Lock_Prop 0x20
493//chy 2003-08-11
494#define ARM_v4_Prop 0x40
495#define ARM_v5_Prop 0x80
496/*jeff.du 2010-08-05 */
497#define ARM_v6_Prop 0xc0
498
499#define ARM_v5e_Prop 0x100
500#define ARM_XScale_Prop 0x200
501#define ARM_ep9312_Prop 0x400
502#define ARM_iWMMXt_Prop 0x800
503//chy 2005-09-19
504#define ARM_PXA27X_Prop 0x1000
505#define ARM_v7_Prop 0x2000
506
507/* ARM2 family */
508#define ARM2 (ARM_Fix26_Prop)
509#define ARM2as ARM2
510#define ARM61 ARM2
511#define ARM3 ARM2
512
513#ifdef ARM60 /* previous definition in armopts.h */
514#undef ARM60
515#endif
516
517/* ARM6 family */
518#define ARM6 (ARM_Lock_Prop)
519#define ARM60 ARM6
520#define ARM600 ARM6
521#define ARM610 ARM6
522#define ARM620 ARM6
523
524
525/***************************************************************************\
526* Macros to extract instruction fields *
527\***************************************************************************/
528
529#define BIT(n) ( (ARMword)(instr>>(n))&1) /* bit n of instruction */
530#define BITS(m,n) ( (ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) ) /* bits m to n of instr */
531#define TOPBITS(n) (instr >> (n)) /* bits 31 to n of instr */
532
533/***************************************************************************\
534* The hardware vector addresses *
535\***************************************************************************/
536
537#define ARMResetV 0L
538#define ARMUndefinedInstrV 4L
539#define ARMSWIV 8L
540#define ARMPrefetchAbortV 12L
541#define ARMDataAbortV 16L
542#define ARMAddrExceptnV 20L
543#define ARMIRQV 24L
544#define ARMFIQV 28L
545#define ARMErrorV 32L /* This is an offset, not an address ! */
546
547#define ARMul_ResetV ARMResetV
548#define ARMul_UndefinedInstrV ARMUndefinedInstrV
549#define ARMul_SWIV ARMSWIV
550#define ARMul_PrefetchAbortV ARMPrefetchAbortV
551#define ARMul_DataAbortV ARMDataAbortV
552#define ARMul_AddrExceptnV ARMAddrExceptnV
553#define ARMul_IRQV ARMIRQV
554#define ARMul_FIQV ARMFIQV
555
556/***************************************************************************\
557* Mode and Bank Constants *
558\***************************************************************************/
559
560#define USER26MODE 0L
561#define FIQ26MODE 1L
562#define IRQ26MODE 2L
563#define SVC26MODE 3L
564#define USER32MODE 16L
565#define FIQ32MODE 17L
566#define IRQ32MODE 18L
567#define SVC32MODE 19L
568#define ABORT32MODE 23L
569#define UNDEF32MODE 27L
570//chy 2006-02-15 add system32 mode
571#define SYSTEM32MODE 31L
572
573#define ARM32BITMODE (state->Mode > 3)
574#define ARM26BITMODE (state->Mode <= 3)
575#define ARMMODE (state->Mode)
576#define ARMul_MODEBITS 0x1fL
577#define ARMul_MODE32BIT ARM32BITMODE
578#define ARMul_MODE26BIT ARM26BITMODE
579
580#define USERBANK 0
581#define FIQBANK 1
582#define IRQBANK 2
583#define SVCBANK 3
584#define ABORTBANK 4
585#define UNDEFBANK 5
586#define DUMMYBANK 6
587#define SYSTEMBANK USERBANK
588#define BANK_CAN_ACCESS_SPSR(bank) \
589 ((bank) != USERBANK && (bank) != SYSTEMBANK && (bank) != DUMMYBANK)
590
591
592/***************************************************************************\
593* Definitons of things in the emulator *
594\***************************************************************************/
595#ifdef __cplusplus
596extern "C" {
597#endif
598extern void ARMul_EmulateInit (void);
599extern void ARMul_Reset (ARMul_State * state);
600#ifdef __cplusplus
601 }
602#endif
603extern ARMul_State *ARMul_NewState (ARMul_State * state);
604extern ARMword ARMul_DoProg (ARMul_State * state);
605extern ARMword ARMul_DoInstr (ARMul_State * state);
606/***************************************************************************\
607* Definitons of things for event handling *
608\***************************************************************************/
609
610extern void ARMul_ScheduleEvent (ARMul_State * state, unsigned int delay,
611 unsigned (*func) ());
612extern void ARMul_EnvokeEvent (ARMul_State * state);
613extern unsigned int ARMul_Time (ARMul_State * state);
614
615/***************************************************************************\
616* Useful support routines *
617\***************************************************************************/
618
619extern ARMword ARMul_GetReg (ARMul_State * state, unsigned mode,
620 unsigned reg);
621extern void ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg,
622 ARMword value);
623extern ARMword ARMul_GetPC (ARMul_State * state);
624extern ARMword ARMul_GetNextPC (ARMul_State * state);
625extern void ARMul_SetPC (ARMul_State * state, ARMword value);
626extern ARMword ARMul_GetR15 (ARMul_State * state);
627extern void ARMul_SetR15 (ARMul_State * state, ARMword value);
628
629extern ARMword ARMul_GetCPSR (ARMul_State * state);
630extern void ARMul_SetCPSR (ARMul_State * state, ARMword value);
631extern ARMword ARMul_GetSPSR (ARMul_State * state, ARMword mode);
632extern void ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value);
633
634/***************************************************************************\
635* Definitons of things to handle aborts *
636\***************************************************************************/
637
638extern void ARMul_Abort (ARMul_State * state, ARMword address);
639#ifdef MODET
640#define ARMul_ABORTWORD (state->TFlag ? 0xefffdfff : 0xefffffff) /* SWI -1 */
641#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \
642 state->AbortAddr = (address & (state->TFlag ? ~1L : ~3L))
643#else
644#define ARMul_ABORTWORD 0xefffffff /* SWI -1 */
645#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \
646 state->AbortAddr = (address & ~3L)
647#endif
648#define ARMul_DATAABORT(address) state->abortSig = HIGH ; \
649 state->Aborted = ARMul_DataAbortV ;
650#define ARMul_CLEARABORT state->abortSig = LOW
651
652/***************************************************************************\
653* Definitons of things in the memory interface *
654\***************************************************************************/
655
656extern unsigned ARMul_MemoryInit (ARMul_State * state,
657 unsigned int initmemsize);
658extern void ARMul_MemoryExit (ARMul_State * state);
659
660extern ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address,
661 ARMword isize);
662extern ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address,
663 ARMword isize);
664#ifdef __cplusplus
665extern "C" {
666#endif
667extern ARMword ARMul_ReLoadInstr (ARMul_State * state, ARMword address,
668 ARMword isize);
669#ifdef __cplusplus
670 }
671#endif
672extern ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address);
673extern ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address);
674extern ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address);
675extern ARMword ARMul_LoadByte (ARMul_State * state, ARMword address);
676
677extern void ARMul_StoreWordS (ARMul_State * state, ARMword address,
678 ARMword data);
679extern void ARMul_StoreWordN (ARMul_State * state, ARMword address,
680 ARMword data);
681extern void ARMul_StoreHalfWord (ARMul_State * state, ARMword address,
682 ARMword data);
683extern void ARMul_StoreByte (ARMul_State * state, ARMword address,
684 ARMword data);
685
686extern ARMword ARMul_SwapWord (ARMul_State * state, ARMword address,
687 ARMword data);
688extern ARMword ARMul_SwapByte (ARMul_State * state, ARMword address,
689 ARMword data);
690
691extern void ARMul_Icycles (ARMul_State * state, unsigned number,
692 ARMword address);
693extern void ARMul_Ccycles (ARMul_State * state, unsigned number,
694 ARMword address);
695
696extern ARMword ARMul_ReadWord (ARMul_State * state, ARMword address);
697extern ARMword ARMul_ReadByte (ARMul_State * state, ARMword address);
698extern void ARMul_WriteWord (ARMul_State * state, ARMword address,
699 ARMword data);
700extern void ARMul_WriteByte (ARMul_State * state, ARMword address,
701 ARMword data);
702
703extern ARMword ARMul_MemAccess (ARMul_State * state, ARMword, ARMword,
704 ARMword, ARMword, ARMword, ARMword, ARMword,
705 ARMword, ARMword, ARMword);
706
707/***************************************************************************\
708* Definitons of things in the co-processor interface *
709\***************************************************************************/
710
711#define ARMul_FIRST 0
712#define ARMul_TRANSFER 1
713#define ARMul_BUSY 2
714#define ARMul_DATA 3
715#define ARMul_INTERRUPT 4
716#define ARMul_DONE 0
717#define ARMul_CANT 1
718#define ARMul_INC 3
719
720#define ARMul_CP13_R0_FIQ 0x1
721#define ARMul_CP13_R0_IRQ 0x2
722#define ARMul_CP13_R8_PMUS 0x1
723
724#define ARMul_CP14_R0_ENABLE 0x0001
725#define ARMul_CP14_R0_CLKRST 0x0004
726#define ARMul_CP14_R0_CCD 0x0008
727#define ARMul_CP14_R0_INTEN0 0x0010
728#define ARMul_CP14_R0_INTEN1 0x0020
729#define ARMul_CP14_R0_INTEN2 0x0040
730#define ARMul_CP14_R0_FLAG0 0x0100
731#define ARMul_CP14_R0_FLAG1 0x0200
732#define ARMul_CP14_R0_FLAG2 0x0400
733#define ARMul_CP14_R10_MOE_IB 0x0004
734#define ARMul_CP14_R10_MOE_DB 0x0008
735#define ARMul_CP14_R10_MOE_BT 0x000c
736#define ARMul_CP15_R1_ENDIAN 0x0080
737#define ARMul_CP15_R1_ALIGN 0x0002
738#define ARMul_CP15_R5_X 0x0400
739#define ARMul_CP15_R5_ST_ALIGN 0x0001
740#define ARMul_CP15_R5_IMPRE 0x0406
741#define ARMul_CP15_R5_MMU_EXCPT 0x0400
742#define ARMul_CP15_DBCON_M 0x0100
743#define ARMul_CP15_DBCON_E1 0x000c
744#define ARMul_CP15_DBCON_E0 0x0003
745
746extern unsigned ARMul_CoProInit (ARMul_State * state);
747extern void ARMul_CoProExit (ARMul_State * state);
748extern void ARMul_CoProAttach (ARMul_State * state, unsigned number,
749 ARMul_CPInits * init, ARMul_CPExits * exit,
750 ARMul_LDCs * ldc, ARMul_STCs * stc,
751 ARMul_MRCs * mrc, ARMul_MCRs * mcr,
752 ARMul_MRRCs * mrrc, ARMul_MCRRs * mcrr,
753 ARMul_CDPs * cdp,
754 ARMul_CPReads * read, ARMul_CPWrites * write);
755extern void ARMul_CoProDetach (ARMul_State * state, unsigned number);
756
757/***************************************************************************\
758* Definitons of things in the host environment *
759\***************************************************************************/
760
761extern unsigned ARMul_OSInit (ARMul_State * state);
762extern void ARMul_OSExit (ARMul_State * state);
763
764#ifdef __cplusplus
765 extern "C" {
766#endif
767
768extern unsigned ARMul_OSHandleSWI (ARMul_State * state, ARMword number);
769#ifdef __cplusplus
770}
771#endif
772
773
774extern ARMword ARMul_OSLastErrorP (ARMul_State * state);
775
776extern ARMword ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr);
777extern unsigned ARMul_OSException (ARMul_State * state, ARMword vector,
778 ARMword pc);
779extern int rdi_log;
780
781/***************************************************************************\
782* Host-dependent stuff *
783\***************************************************************************/
784
785#ifdef macintosh
786pascal void SpinCursor (short increment); /* copied from CursorCtl.h */
787# define HOURGLASS SpinCursor( 1 )
788# define HOURGLASS_RATE 1023 /* 2^n - 1 */
789#endif
790
791//teawater add for arm2x86 2005.02.14-------------------------------------------
792/*ywc 2005-03-31*/
793/*
794#include "arm2x86.h"
795#include "arm2x86_dp.h"
796#include "arm2x86_movl.h"
797#include "arm2x86_psr.h"
798#include "arm2x86_shift.h"
799#include "arm2x86_mem.h"
800#include "arm2x86_mul.h"
801#include "arm2x86_test.h"
802#include "arm2x86_other.h"
803#include "list.h"
804#include "tb.h"
805*/
806#define EQ 0
807#define NE 1
808#define CS 2
809#define CC 3
810#define MI 4
811#define PL 5
812#define VS 6
813#define VC 7
814#define HI 8
815#define LS 9
816#define GE 10
817#define LT 11
818#define GT 12
819#define LE 13
820#define AL 14
821#define NV 15
822
823#ifndef NFLAG
824#define NFLAG state->NFlag
825#endif //NFLAG
826
827#ifndef ZFLAG
828#define ZFLAG state->ZFlag
829#endif //ZFLAG
830
831#ifndef CFLAG
832#define CFLAG state->CFlag
833#endif //CFLAG
834
835#ifndef VFLAG
836#define VFLAG state->VFlag
837#endif //VFLAG
838
839#ifndef IFLAG
840#define IFLAG (state->IFFlags >> 1)
841#endif //IFLAG
842
843#ifndef FFLAG
844#define FFLAG (state->IFFlags & 1)
845#endif //FFLAG
846
847#ifndef IFFLAGS
848#define IFFLAGS state->IFFlags
849#endif //VFLAG
850
851#define FLAG_MASK 0xf0000000
852#define NBIT_SHIFT 31
853#define ZBIT_SHIFT 30
854#define CBIT_SHIFT 29
855#define VBIT_SHIFT 28
856#ifdef DBCT
857//teawater change for local tb branch directly jump 2005.10.18------------------
858#include "dbct/list.h"
859#include "dbct/arm2x86.h"
860#include "dbct/arm2x86_dp.h"
861#include "dbct/arm2x86_movl.h"
862#include "dbct/arm2x86_psr.h"
863#include "dbct/arm2x86_shift.h"
864#include "dbct/arm2x86_mem.h"
865#include "dbct/arm2x86_mul.h"
866#include "dbct/arm2x86_test.h"
867#include "dbct/arm2x86_other.h"
868#include "dbct/arm2x86_coproc.h"
869#include "dbct/tb.h"
870#endif
871//AJ2D--------------------------------------------------------------------------
872//AJ2D--------------------------------------------------------------------------
873#define SKYEYE_OUTREGS(fd) { fprintf ((fd), "R %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,C %x,S %x,%x,%x,%x,%x,%x,%x,M %x,B %x,E %x,I %x,P %x,T %x,L %x,D %x,",\
874 state->Reg[0],state->Reg[1],state->Reg[2],state->Reg[3], \
875 state->Reg[4],state->Reg[5],state->Reg[6],state->Reg[7], \
876 state->Reg[8],state->Reg[9],state->Reg[10],state->Reg[11], \
877 state->Reg[12],state->Reg[13],state->Reg[14],state->Reg[15], \
878 state->Cpsr, state->Spsr[0], state->Spsr[1], state->Spsr[2],\
879 state->Spsr[3],state->Spsr[4], state->Spsr[5], state->Spsr[6],\
880 state->Mode,state->Bank,state->ErrorCode,state->instr,state->pc,\
881 state->temp,state->loaded,state->decoded);}
882
883#define SKYEYE_OUTMOREREGS(fd) { fprintf ((fd),"\
884RUs %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\
885RF %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\
886RI %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\
887RS %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\
888RA %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\
889RUn %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",\
890 state->RegBank[0][0],state->RegBank[0][1],state->RegBank[0][2],state->RegBank[0][3], \
891 state->RegBank[0][4],state->RegBank[0][5],state->RegBank[0][6],state->RegBank[0][7], \
892 state->RegBank[0][8],state->RegBank[0][9],state->RegBank[0][10],state->RegBank[0][11], \
893 state->RegBank[0][12],state->RegBank[0][13],state->RegBank[0][14],state->RegBank[0][15], \
894 state->RegBank[1][0],state->RegBank[1][1],state->RegBank[1][2],state->RegBank[1][3], \
895 state->RegBank[1][4],state->RegBank[1][5],state->RegBank[1][6],state->RegBank[1][7], \
896 state->RegBank[1][8],state->RegBank[1][9],state->RegBank[1][10],state->RegBank[1][11], \
897 state->RegBank[1][12],state->RegBank[1][13],state->RegBank[1][14],state->RegBank[1][15], \
898 state->RegBank[2][0],state->RegBank[2][1],state->RegBank[2][2],state->RegBank[2][3], \
899 state->RegBank[2][4],state->RegBank[2][5],state->RegBank[2][6],state->RegBank[2][7], \
900 state->RegBank[2][8],state->RegBank[2][9],state->RegBank[2][10],state->RegBank[2][11], \
901 state->RegBank[2][12],state->RegBank[2][13],state->RegBank[2][14],state->RegBank[2][15], \
902 state->RegBank[3][0],state->RegBank[3][1],state->RegBank[3][2],state->RegBank[3][3], \
903 state->RegBank[3][4],state->RegBank[3][5],state->RegBank[3][6],state->RegBank[3][7], \
904 state->RegBank[3][8],state->RegBank[3][9],state->RegBank[3][10],state->RegBank[3][11], \
905 state->RegBank[3][12],state->RegBank[3][13],state->RegBank[3][14],state->RegBank[3][15], \
906 state->RegBank[4][0],state->RegBank[4][1],state->RegBank[4][2],state->RegBank[4][3], \
907 state->RegBank[4][4],state->RegBank[4][5],state->RegBank[4][6],state->RegBank[4][7], \
908 state->RegBank[4][8],state->RegBank[4][9],state->RegBank[4][10],state->RegBank[4][11], \
909 state->RegBank[4][12],state->RegBank[4][13],state->RegBank[4][14],state->RegBank[4][15], \
910 state->RegBank[5][0],state->RegBank[5][1],state->RegBank[5][2],state->RegBank[5][3], \
911 state->RegBank[5][4],state->RegBank[5][5],state->RegBank[5][6],state->RegBank[5][7], \
912 state->RegBank[5][8],state->RegBank[5][9],state->RegBank[5][10],state->RegBank[5][11], \
913 state->RegBank[5][12],state->RegBank[5][13],state->RegBank[5][14],state->RegBank[5][15] \
914 );}
915
916
917#define SA1110 0x6901b110
918#define SA1100 0x4401a100
919#define PXA250 0x69052100
920#define PXA270 0x69054110
921//#define PXA250 0x69052903
922// 0x69052903; //PXA250 B1 from intel 278522-001.pdf
923
924
925extern void ARMul_UndefInstr (ARMul_State *, ARMword);
926extern void ARMul_FixCPSR (ARMul_State *, ARMword, ARMword);
927extern void ARMul_FixSPSR (ARMul_State *, ARMword, ARMword);
928extern void ARMul_ConsolePrint (ARMul_State *, const char *, ...);
929extern void ARMul_SelectProcessor (ARMul_State *, unsigned);
930
931#define DIFF_LOG 0
932#define SAVE_LOG 0
933
934#endif /* _ARMDEFS_H_ */
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}
diff --git a/src/core/arm/interpreter/armemu.h b/src/core/arm/interpreter/armemu.h
new file mode 100644
index 000000000..2ab317fdd
--- /dev/null
+++ b/src/core/arm/interpreter/armemu.h
@@ -0,0 +1,659 @@
1/* armemu.h -- ARMulator emulation macros: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17#ifndef __ARMEMU_H__
18#define __ARMEMU_H__
19
20#include "common.h"
21#include "armdefs.h"
22//#include "skyeye.h"
23
24extern ARMword isize;
25
26/* Condition code values. */
27#define EQ 0
28#define NE 1
29#define CS 2
30#define CC 3
31#define MI 4
32#define PL 5
33#define VS 6
34#define VC 7
35#define HI 8
36#define LS 9
37#define GE 10
38#define LT 11
39#define GT 12
40#define LE 13
41#define AL 14
42#define NV 15
43
44/* Shift Opcodes. */
45#define LSL 0
46#define LSR 1
47#define ASR 2
48#define ROR 3
49
50/* Macros to twiddle the status flags and mode. */
51#define NBIT ((unsigned)1L << 31)
52#define ZBIT (1L << 30)
53#define CBIT (1L << 29)
54#define VBIT (1L << 28)
55#define SBIT (1L << 27)
56#define IBIT (1L << 7)
57#define FBIT (1L << 6)
58#define IFBITS (3L << 6)
59#define R15IBIT (1L << 27)
60#define R15FBIT (1L << 26)
61#define R15IFBITS (3L << 26)
62
63#define POS(i) ( (~(i)) >> 31 )
64#define NEG(i) ( (i) >> 31 )
65
66#ifdef MODET /* Thumb support. */
67/* ??? This bit is actually in the low order bit of the PC in the hardware.
68 It isn't clear if the simulator needs to model that or not. */
69#define TBIT (1L << 5)
70#define TFLAG state->TFlag
71#define SETT state->TFlag = 1
72#define CLEART state->TFlag = 0
73#define ASSIGNT(res) state->TFlag = res
74#define INSN_SIZE (TFLAG ? 2 : 4)
75#else
76#define TBIT (1L << 5)
77#define INSN_SIZE 4
78#define TFLAG 0
79#endif
80
81/*add armv6 CPSR feature*/
82#define EFLAG state->EFlag
83#define SETE state->EFlag = 1
84#define CLEARE state->EFlag = 0
85#define ASSIGNE(res) state->NFlag = res
86
87#define AFLAG state->AFlag
88#define SETA state->AFlag = 1
89#define CLEARA state->AFlag = 0
90#define ASSIGNA(res) state->NFlag = res
91
92#define QFLAG state->QFlag
93#define SETQ state->QFlag = 1
94#define CLEARQ state->AFlag = 0
95#define ASSIGNQ(res) state->QFlag = res
96
97/* add end */
98
99#define NFLAG state->NFlag
100#define SETN state->NFlag = 1
101#define CLEARN state->NFlag = 0
102#define ASSIGNN(res) state->NFlag = res
103
104#define ZFLAG state->ZFlag
105#define SETZ state->ZFlag = 1
106#define CLEARZ state->ZFlag = 0
107#define ASSIGNZ(res) state->ZFlag = res
108
109#define CFLAG state->CFlag
110#define SETC state->CFlag = 1
111#define CLEARC state->CFlag = 0
112#define ASSIGNC(res) state->CFlag = res
113
114#define VFLAG state->VFlag
115#define SETV state->VFlag = 1
116#define CLEARV state->VFlag = 0
117#define ASSIGNV(res) state->VFlag = res
118
119#define SFLAG state->SFlag
120#define SETS state->SFlag = 1
121#define CLEARS state->SFlag = 0
122#define ASSIGNS(res) state->SFlag = res
123
124#define IFLAG (state->IFFlags >> 1)
125#define FFLAG (state->IFFlags & 1)
126#define IFFLAGS state->IFFlags
127#define ASSIGNINT(res) state->IFFlags = (((res) >> 6) & 3)
128#define ASSIGNR15INT(res) state->IFFlags = (((res) >> 26) & 3) ;
129
130#define PSR_FBITS (0xff000000L)
131#define PSR_SBITS (0x00ff0000L)
132#define PSR_XBITS (0x0000ff00L)
133#define PSR_CBITS (0x000000ffL)
134
135#if defined MODE32 || defined MODET
136#define CCBITS (0xf8000000L)
137#else
138#define CCBITS (0xf0000000L)
139#endif
140
141#define INTBITS (0xc0L)
142
143#if defined MODET && defined MODE32
144#define PCBITS (0xffffffffL)
145#else
146#define PCBITS (0xfffffffcL)
147#endif
148
149#define MODEBITS (0x1fL)
150#define R15INTBITS (3L << 26)
151
152#if defined MODET && defined MODE32
153#define R15PCBITS (0x03ffffffL)
154#else
155#define R15PCBITS (0x03fffffcL)
156#endif
157
158#define R15PCMODEBITS (0x03ffffffL)
159#define R15MODEBITS (0x3L)
160
161#ifdef MODE32
162#define PCMASK PCBITS
163#define PCWRAP(pc) (pc)
164#else
165#define PCMASK R15PCBITS
166#define PCWRAP(pc) ((pc) & R15PCBITS)
167#endif
168
169#define R15CCINTMODE (state->Reg[15] & (CCBITS | R15INTBITS | R15MODEBITS))
170#define R15INT (state->Reg[15] & R15INTBITS)
171#define R15INTPC (state->Reg[15] & (R15INTBITS | R15PCBITS))
172#define R15INTPCMODE (state->Reg[15] & (R15INTBITS | R15PCBITS | R15MODEBITS))
173#define R15INTMODE (state->Reg[15] & (R15INTBITS | R15MODEBITS))
174#define R15PC (state->Reg[15] & R15PCBITS)
175#define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS))
176#define R15MODE (state->Reg[15] & R15MODEBITS)
177
178#define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28) | (SFLAG << 27))
179#define EINT (IFFLAGS << 6)
180#define ER15INT (IFFLAGS << 26)
181#define EMODE (state->Mode)
182
183//#ifdef MODET
184//#define CPSR (ECC | EINT | EMODE | (TFLAG << 5))
185//#else
186//#define CPSR (ECC | EINT | EMODE)
187//#endif
188
189#ifdef MODE32
190#define PATCHR15
191#else
192#define PATCHR15 state->Reg[15] = ECC | ER15INT | EMODE | R15PC
193#endif
194
195#define GETSPSR(bank) (ARMul_GetSPSR (state, EMODE))
196#define SETPSR_F(d,s) d = ((d) & ~PSR_FBITS) | ((s) & PSR_FBITS)
197#define SETPSR_S(d,s) d = ((d) & ~PSR_SBITS) | ((s) & PSR_SBITS)
198#define SETPSR_X(d,s) d = ((d) & ~PSR_XBITS) | ((s) & PSR_XBITS)
199#define SETPSR_C(d,s) d = ((d) & ~PSR_CBITS) | ((s) & PSR_CBITS)
200
201#define SETR15PSR(s) \
202 do \
203 { \
204 if (state->Mode == USER26MODE) \
205 { \
206 state->Reg[15] = ((s) & CCBITS) | R15PC | ER15INT | EMODE; \
207 ASSIGNN ((state->Reg[15] & NBIT) != 0); \
208 ASSIGNZ ((state->Reg[15] & ZBIT) != 0); \
209 ASSIGNC ((state->Reg[15] & CBIT) != 0); \
210 ASSIGNV ((state->Reg[15] & VBIT) != 0); \
211 } \
212 else \
213 { \
214 state->Reg[15] = R15PC | ((s) & (CCBITS | R15INTBITS | R15MODEBITS)); \
215 ARMul_R15Altered (state); \
216 } \
217 } \
218 while (0)
219
220#define SETABORT(i, m, d) \
221 do \
222 { \
223 int SETABORT_mode = (m); \
224 \
225 ARMul_SetSPSR (state, SETABORT_mode, ARMul_GetCPSR (state)); \
226 ARMul_SetCPSR (state, ((ARMul_GetCPSR (state) & ~(EMODE | TBIT)) \
227 | (i) | SETABORT_mode)); \
228 state->Reg[14] = temp - (d); \
229 } \
230 while (0)
231
232//#ifndef MODE32
233#define VECTORS 0x20
234#define LEGALADDR 0x03ffffff
235#define VECTORACCESS(address) (address < VECTORS && ARMul_MODE26BIT && state->prog32Sig)
236#define ADDREXCEPT(address) (address > LEGALADDR && !state->data32Sig)
237//#endif
238
239#define INTERNALABORT(address) \
240 do \
241 { \
242 if (address < VECTORS) \
243 state->Aborted = ARMul_DataAbortV; \
244 else \
245 state->Aborted = ARMul_AddrExceptnV; \
246 } \
247 while (0)
248
249#ifdef MODE32
250#define TAKEABORT ARMul_Abort (state, ARMul_DataAbortV)
251#else
252#define TAKEABORT \
253 do \
254 { \
255 if (state->Aborted == ARMul_AddrExceptnV) \
256 ARMul_Abort (state, ARMul_AddrExceptnV); \
257 else \
258 ARMul_Abort (state, ARMul_DataAbortV); \
259 } \
260 while (0)
261#endif
262
263#define CPTAKEABORT \
264 do \
265 { \
266 if (!state->Aborted) \
267 ARMul_Abort (state, ARMul_UndefinedInstrV); \
268 else if (state->Aborted == ARMul_AddrExceptnV) \
269 ARMul_Abort (state, ARMul_AddrExceptnV); \
270 else \
271 ARMul_Abort (state, ARMul_DataAbortV); \
272 } \
273 while (0);
274
275
276/* Different ways to start the next instruction. */
277#define SEQ 0
278#define NONSEQ 1
279#define PCINCEDSEQ 2
280#define PCINCEDNONSEQ 3
281#define PRIMEPIPE 4
282#define RESUME 8
283
284/************************************/
285/* shenoubang 2012-3-11 */
286/* for armv7 DBG DMB DSB instr*/
287/************************************/
288#define MBReqTypes_Writes 0
289#define MBReqTypes_All 1
290
291#define NORMALCYCLE state->NextInstr = 0
292#define BUSUSEDN state->NextInstr |= 1 /* The next fetch will be an N cycle. */
293#define BUSUSEDINCPCS \
294 do \
295 { \
296 if (! state->is_v4) \
297 { \
298 /* A standard PC inc and an S cycle. */ \
299 state->Reg[15] += isize; \
300 state->NextInstr = (state->NextInstr & 0xff) | 2; \
301 } \
302 } \
303 while (0)
304
305#define BUSUSEDINCPCN \
306 do \
307 { \
308 if (state->is_v4) \
309 BUSUSEDN; \
310 else \
311 { \
312 /* A standard PC inc and an N cycle. */ \
313 state->Reg[15] += isize; \
314 state->NextInstr |= 3; \
315 } \
316 } \
317 while (0)
318
319#define INCPC \
320 do \
321 { \
322 /* A standard PC inc. */ \
323 state->Reg[15] += isize; \
324 state->NextInstr |= 2; \
325 } \
326 while (0)
327
328#define FLUSHPIPE state->NextInstr |= PRIMEPIPE
329
330/* Cycle based emulation. */
331
332#define OUTPUTCP(i,a,b)
333#define NCYCLE
334#define SCYCLE
335#define ICYCLE
336#define CCYCLE
337#define NEXTCYCLE(c)
338
339/* Macros to extract parts of instructions. */
340#define DESTReg (BITS (12, 15))
341#define LHSReg (BITS (16, 19))
342#define RHSReg (BITS ( 0, 3))
343
344#define DEST (state->Reg[DESTReg])
345
346#ifdef MODE32
347#ifdef MODET
348#define LHS ((LHSReg == 15) ? (state->Reg[15] & 0xFFFFFFFC) : (state->Reg[LHSReg]))
349#define RHS ((RHSReg == 15) ? (state->Reg[15] & 0xFFFFFFFC) : (state->Reg[RHSReg]))
350#else
351#define LHS (state->Reg[LHSReg])
352#define RHS (state->Reg[RHSReg])
353#endif
354#else
355#define LHS ((LHSReg == 15) ? R15PC : (state->Reg[LHSReg]))
356#define RHS ((RHSReg == 15) ? R15PC : (state->Reg[RHSReg]))
357#endif
358
359#define MULDESTReg (BITS (16, 19))
360#define MULLHSReg (BITS ( 0, 3))
361#define MULRHSReg (BITS ( 8, 11))
362#define MULACCReg (BITS (12, 15))
363
364#define DPImmRHS (ARMul_ImmedTable[BITS(0, 11)])
365#define DPSImmRHS temp = BITS(0,11) ; \
366 rhs = ARMul_ImmedTable[temp] ; \
367 if (temp > 255) /* There was a shift. */ \
368 ASSIGNC (rhs >> 31) ;
369
370#ifdef MODE32
371#define DPRegRHS ((BITS (4,11) == 0) ? state->Reg[RHSReg] \
372 : GetDPRegRHS (state, instr))
373#define DPSRegRHS ((BITS (4,11) == 0) ? state->Reg[RHSReg] \
374 : GetDPSRegRHS (state, instr))
375#else
376#define DPRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \
377 : GetDPRegRHS (state, instr))
378#define DPSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \
379 : GetDPSRegRHS (state, instr))
380#endif
381
382#define LSBase state->Reg[LHSReg]
383#define LSImmRHS (BITS(0,11))
384
385#ifdef MODE32
386#define LSRegRHS ((BITS (4, 11) == 0) ? state->Reg[RHSReg] \
387 : GetLSRegRHS (state, instr))
388#else
389#define LSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \
390 : GetLSRegRHS (state, instr))
391#endif
392
393#define LSMNumRegs ((ARMword) ARMul_BitList[BITS (0, 7)] + \
394 (ARMword) ARMul_BitList[BITS (8, 15)] )
395#define LSMBaseFirst ((LHSReg == 0 && BIT (0)) || \
396 (BIT (LHSReg) && BITS (0, LHSReg - 1) == 0))
397
398#define SWAPSRC (state->Reg[RHSReg])
399
400#define LSCOff (BITS (0, 7) << 2)
401#define CPNum BITS (8, 11)
402
403/* Determine if access to coprocessor CP is permitted.
404 The XScale has a register in CP15 which controls access to CP0 - CP13. */
405//chy 2003-09-03, new CP_ACCESS_ALLOWED
406/*
407#define CP_ACCESS_ALLOWED(STATE, CP) \
408 ( ((CP) >= 14) \
409 || (! (STATE)->is_XScale) \
410 || (read_cp15_reg (15, 0, 1) & (1 << (CP))))
411*/
412//#define CP_ACCESS_ALLOWED(STATE, CP) \
413// (((CP) >= 14) \
414// || (!(STATE)->is_XScale) \
415// || (xscale_cp15_cp_access_allowed(STATE, 15, CP)))
416
417#define CP_ACCESS_ALLOWED(STATE, CP) false // Disabled coprocessor shit /bunnei
418
419/* Macro to rotate n right by b bits. */
420#define ROTATER(n, b) (((n) >> (b)) | ((n) << (32 - (b))))
421
422/* Macros to store results of instructions. */
423#define WRITEDEST(d) \
424 do \
425 { \
426 if (DESTReg == 15) \
427 WriteR15 (state, d); \
428 else \
429 DEST = d; \
430 } \
431 while (0)
432
433#define WRITESDEST(d) \
434 do \
435 { \
436 if (DESTReg == 15) \
437 WriteSR15 (state, d); \
438 else \
439 { \
440 DEST = d; \
441 ARMul_NegZero (state, d); \
442 } \
443 } \
444 while (0)
445
446#define WRITEDESTB(d) \
447 do \
448 { \
449 if (DESTReg == 15){ \
450 WriteR15Branch (state, d); \
451 } \
452 else{ \
453 DEST = d; \
454 } \
455 } \
456 while (0)
457
458#define BYTETOBUS(data) ((data & 0xff) | \
459 ((data & 0xff) << 8) | \
460 ((data & 0xff) << 16) | \
461 ((data & 0xff) << 24))
462
463#define BUSTOBYTE(address, data) \
464 do \
465 { \
466 if (state->bigendSig) \
467 temp = (data >> (((address ^ 3) & 3) << 3)) & 0xff; \
468 else \
469 temp = (data >> ((address & 3) << 3)) & 0xff; \
470 } \
471 while (0)
472
473#define LOADMULT(instr, address, wb) LoadMult (state, instr, address, wb)
474#define LOADSMULT(instr, address, wb) LoadSMult (state, instr, address, wb)
475#define STOREMULT(instr, address, wb) StoreMult (state, instr, address, wb)
476#define STORESMULT(instr, address, wb) StoreSMult (state, instr, address, wb)
477
478#define POSBRANCH ((instr & 0x7fffff) << 2)
479#define NEGBRANCH ((0xff000000 |(instr & 0xffffff)) << 2)
480
481
482/* Values for Emulate. */
483#define STOP 0 /* stop */
484#define CHANGEMODE 1 /* change mode */
485#define ONCE 2 /* execute just one interation */
486#define RUN 3 /* continuous execution */
487
488/* Stuff that is shared across modes. */
489extern unsigned ARMul_MultTable[]; /* Number of I cycles for a mult. */
490extern ARMword ARMul_ImmedTable[]; /* Immediate DP LHS values. */
491extern char ARMul_BitList[]; /* Number of bits in a byte table. */
492
493#define EVENTLISTSIZE 1024L
494
495/* Thumb support. */
496typedef enum
497{
498 t_undefined, /* Undefined Thumb instruction. */
499 t_decoded, /* Instruction decoded to ARM equivalent. */
500 t_branch /* Thumb branch (already processed). */
501}
502tdstate;
503
504/*********************************************************************************
505 * Check all the possible undef or unpredict behavior, Some of them probably is
506 * out-of-updated with the newer ISA.
507 * -- Michael.Kang
508 ********************************************************************************/
509#define UNDEF_WARNING ERROR_LOG(ARM11, "undefined or unpredicted behavior for arm instruction.\n");
510
511/* Macros to scrutinize instructions. */
512#define UNDEF_Test UNDEF_WARNING
513//#define UNDEF_Test
514
515//#define UNDEF_Shift UNDEF_WARNING
516#define UNDEF_Shift
517
518//#define UNDEF_MSRPC UNDEF_WARNING
519#define UNDEF_MSRPC
520
521//#define UNDEF_MRSPC UNDEF_WARNING
522#define UNDEF_MRSPC
523
524#define UNDEF_MULPCDest UNDEF_WARNING
525//#define UNDEF_MULPCDest
526
527#define UNDEF_MULDestEQOp1 UNDEF_WARNING
528//#define UNDEF_MULDestEQOp1
529
530//#define UNDEF_LSRBPC UNDEF_WARNING
531#define UNDEF_LSRBPC
532
533//#define UNDEF_LSRBaseEQOffWb UNDEF_WARNING
534#define UNDEF_LSRBaseEQOffWb
535
536//#define UNDEF_LSRBaseEQDestWb UNDEF_WARNING
537#define UNDEF_LSRBaseEQDestWb
538
539//#define UNDEF_LSRPCBaseWb UNDEF_WARNING
540#define UNDEF_LSRPCBaseWb
541
542//#define UNDEF_LSRPCOffWb UNDEF_WARNING
543#define UNDEF_LSRPCOffWb
544
545//#define UNDEF_LSMNoRegs UNDEF_WARNING
546#define UNDEF_LSMNoRegs
547
548//#define UNDEF_LSMPCBase UNDEF_WARNING
549#define UNDEF_LSMPCBase
550
551//#define UNDEF_LSMUserBankWb UNDEF_WARNING
552#define UNDEF_LSMUserBankWb
553
554//#define UNDEF_LSMBaseInListWb UNDEF_WARNING
555#define UNDEF_LSMBaseInListWb
556
557#define UNDEF_SWPPC UNDEF_WARNING
558//#define UNDEF_SWPPC
559
560#define UNDEF_CoProHS UNDEF_WARNING
561//#define UNDEF_CoProHS
562
563#define UNDEF_MCRPC UNDEF_WARNING
564//#define UNDEF_MCRPC
565
566//#define UNDEF_LSCPCBaseWb UNDEF_WARNING
567#define UNDEF_LSCPCBaseWb
568
569#define UNDEF_UndefNotBounced UNDEF_WARNING
570//#define UNDEF_UndefNotBounced
571
572#define UNDEF_ShortInt UNDEF_WARNING
573//#define UNDEF_ShortInt
574
575#define UNDEF_IllegalMode UNDEF_WARNING
576//#define UNDEF_IllegalMode
577
578#define UNDEF_Prog32SigChange UNDEF_WARNING
579//#define UNDEF_Prog32SigChange
580
581#define UNDEF_Data32SigChange UNDEF_WARNING
582//#define UNDEF_Data32SigChange
583
584/* Prototypes for exported functions. */
585extern unsigned ARMul_NthReg (ARMword, unsigned);
586extern int AddOverflow (ARMword, ARMword, ARMword);
587extern int SubOverflow (ARMword, ARMword, ARMword);
588/* Prototypes for exported functions. */
589#ifdef __cplusplus
590 extern "C" {
591#endif
592extern ARMword ARMul_Emulate26 (ARMul_State *);
593extern ARMword ARMul_Emulate32 (ARMul_State *);
594#ifdef __cplusplus
595 }
596#endif
597extern unsigned IntPending (ARMul_State *);
598extern void ARMul_CPSRAltered (ARMul_State *);
599extern void ARMul_R15Altered (ARMul_State *);
600extern ARMword ARMul_GetPC (ARMul_State *);
601extern ARMword ARMul_GetNextPC (ARMul_State *);
602extern ARMword ARMul_GetR15 (ARMul_State *);
603extern ARMword ARMul_GetCPSR (ARMul_State *);
604extern void ARMul_EnvokeEvent (ARMul_State *);
605extern unsigned int ARMul_Time (ARMul_State *);
606extern void ARMul_NegZero (ARMul_State *, ARMword);
607extern void ARMul_SetPC (ARMul_State *, ARMword);
608extern void ARMul_SetR15 (ARMul_State *, ARMword);
609extern void ARMul_SetCPSR (ARMul_State *, ARMword);
610extern ARMword ARMul_GetSPSR (ARMul_State *, ARMword);
611extern void ARMul_Abort26 (ARMul_State *, ARMword);
612extern void ARMul_Abort32 (ARMul_State *, ARMword);
613extern ARMword ARMul_MRC (ARMul_State *, ARMword);
614extern void ARMul_MRRC (ARMul_State *, ARMword, ARMword *, ARMword *);
615extern void ARMul_CDP (ARMul_State *, ARMword);
616extern void ARMul_LDC (ARMul_State *, ARMword, ARMword);
617extern void ARMul_STC (ARMul_State *, ARMword, ARMword);
618extern void ARMul_MCR (ARMul_State *, ARMword, ARMword);
619extern void ARMul_MCRR (ARMul_State *, ARMword, ARMword, ARMword);
620extern void ARMul_SetSPSR (ARMul_State *, ARMword, ARMword);
621extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword);
622extern ARMword ARMul_Align (ARMul_State *, ARMword, ARMword);
623extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword);
624extern void ARMul_MSRCpsr (ARMul_State *, ARMword, ARMword);
625extern void ARMul_SubOverflow (ARMul_State *, ARMword, ARMword, ARMword);
626extern void ARMul_AddOverflow (ARMul_State *, ARMword, ARMword, ARMword);
627extern void ARMul_SubCarry (ARMul_State *, ARMword, ARMword, ARMword);
628extern void ARMul_AddCarry (ARMul_State *, ARMword, ARMword, ARMword);
629extern tdstate ARMul_ThumbDecode (ARMul_State *, ARMword, ARMword, ARMword *);
630extern ARMword ARMul_GetReg (ARMul_State *, unsigned, unsigned);
631extern void ARMul_SetReg (ARMul_State *, unsigned, unsigned, ARMword);
632extern void ARMul_ScheduleEvent (ARMul_State *, unsigned int,
633 unsigned (*)(ARMul_State *));
634/* Coprocessor support functions. */
635extern unsigned ARMul_CoProInit (ARMul_State *);
636extern void ARMul_CoProExit (ARMul_State *);
637extern void ARMul_CoProAttach (ARMul_State *, unsigned, ARMul_CPInits *,
638 ARMul_CPExits *, ARMul_LDCs *, ARMul_STCs *,
639 ARMul_MRCs *, ARMul_MCRs *, ARMul_MRRCs *, ARMul_MCRRs *,
640 ARMul_CDPs *, ARMul_CPReads *, ARMul_CPWrites *);
641extern void ARMul_CoProDetach (ARMul_State *, unsigned);
642extern ARMword read_cp15_reg (unsigned, unsigned, unsigned);
643
644extern unsigned DSPLDC4 (ARMul_State *, unsigned, ARMword, ARMword);
645extern unsigned DSPMCR4 (ARMul_State *, unsigned, ARMword, ARMword);
646extern unsigned DSPMRC4 (ARMul_State *, unsigned, ARMword, ARMword *);
647extern unsigned DSPSTC4 (ARMul_State *, unsigned, ARMword, ARMword *);
648extern unsigned DSPCDP4 (ARMul_State *, unsigned, ARMword);
649extern unsigned DSPMCR5 (ARMul_State *, unsigned, ARMword, ARMword);
650extern unsigned DSPMRC5 (ARMul_State *, unsigned, ARMword, ARMword *);
651extern unsigned DSPLDC5 (ARMul_State *, unsigned, ARMword, ARMword);
652extern unsigned DSPSTC5 (ARMul_State *, unsigned, ARMword, ARMword *);
653extern unsigned DSPCDP5 (ARMul_State *, unsigned, ARMword);
654extern unsigned DSPMCR6 (ARMul_State *, unsigned, ARMword, ARMword);
655extern unsigned DSPMRC6 (ARMul_State *, unsigned, ARMword, ARMword *);
656extern unsigned DSPCDP6 (ARMul_State *, unsigned, ARMword);
657
658
659#endif
diff --git a/src/core/arm/interpreter/arminit.cpp b/src/core/arm/interpreter/arminit.cpp
new file mode 100644
index 000000000..f48232eec
--- /dev/null
+++ b/src/core/arm/interpreter/arminit.cpp
@@ -0,0 +1,579 @@
1/* arminit.c -- ARMulator initialization: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18
19#include "platform.h"
20#if EMU_PLATFORM == PLATFORM_LINUX
21#include <unistd.h>
22#endif
23
24#include <math.h>
25
26#include "armdefs.h"
27#include "armemu.h"
28
29/***************************************************************************\
30* Definitions for the emulator architecture *
31\***************************************************************************/
32
33void ARMul_EmulateInit (void);
34ARMul_State *ARMul_NewState (ARMul_State * state);
35void ARMul_Reset (ARMul_State * state);
36ARMword ARMul_DoCycle (ARMul_State * state);
37unsigned ARMul_DoCoPro (ARMul_State * state);
38ARMword ARMul_DoProg (ARMul_State * state);
39ARMword ARMul_DoInstr (ARMul_State * state);
40void ARMul_Abort (ARMul_State * state, ARMword address);
41
42unsigned ARMul_MultTable[32] =
43 { 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
44 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16
45};
46ARMword ARMul_ImmedTable[4096]; /* immediate DP LHS values */
47char ARMul_BitList[256]; /* number of bits in a byte table */
48
49//chy 2006-02-22 add test debugmode
50extern int debugmode;
51extern int remote_interrupt( void );
52
53
54void arm_dyncom_Abort(ARMul_State * state, ARMword vector)
55{
56 ARMul_Abort(state, vector);
57}
58
59
60/* ahe-ykl : the following code to initialize user mode
61 code is architecture dependent and probably model dependant. */
62
63//#include "skyeye_arch.h"
64//#include "skyeye_pref.h"
65//#include "skyeye_exec_info.h"
66//#include "bank_defs.h"
67#include "armcpu.h"
68//#include "skyeye_callback.h"
69
70//void arm_user_mode_init(generic_arch_t * arch_instance)
71//{
72// sky_pref_t *pref = get_skyeye_pref();
73//
74// if (pref->user_mode_sim)
75// {
76// sky_exec_info_t *info = get_skyeye_exec_info();
77// info->arch_page_size = 0x1000;
78// info->arch_stack_top = 0x1ffffff0;// + 0x401fe7 - 0xff0; /* arbitrary value */
79// /* stack initial address specific to architecture may be placed here */
80//
81// /* we need to mmap the stack space, if we are using skyeye space */
82// if (info->mmap_access)
83// {
84// /* get system stack size */
85// size_t stacksize = 0;
86// pthread_attr_t attr;
87// pthread_attr_init(&attr);
88// pthread_attr_getstacksize(&attr, &stacksize);
89// if (stacksize > info->arch_stack_top)
90// {
91// printf("arch_stack_top is too low\n");
92// stacksize = info->arch_stack_top;
93// }
94//
95// /* Note: Skyeye is occupating 0x400000 to 0x600000 */
96// /* We do a mmap */
97// void* ret = mmap( (info->arch_stack_top) - stacksize,
98// stacksize + 0x1000 , PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
99// if (ret == MAP_FAILED){
100// /* ideally, we should find an empty space until it works */
101// printf("mmap error, stack couldn't be mapped: errno %d\n", errno);
102// exit(-1);
103// } else {
104// memset(ret, '\0', stacksize);
105// //printf("stack top has been defined at %x size %x\n", (uint32_t) ret + stacksize, stacksize);
106// //info->arch_stack_top = (uint32_t) ret + stacksize;
107// }
108// }
109//
110// exec_stack_init();
111//
112// ARM_CPU_State* cpu = get_current_cpu();
113// arm_core_t* core = &cpu->core[0];
114//
115// uint32_t sp = info->initial_sp;
116//
117// core->Cpsr = 0x10; /* User mode */
118// /* FIXME: may need to add thumb */
119// core->Reg[13] = sp;
120// core->Reg[10] = info->start_data;
121// core->Reg[0] = 0;
122// bus_read(32, sp + 4, &(core->Reg[1]));
123// bus_read(32, sp + 8, &(core->Reg[2]));
124// }
125//
126//}
127
128/***************************************************************************\
129* Call this routine once to set up the emulator's tables. *
130\***************************************************************************/
131
132void
133ARMul_EmulateInit (void)
134{
135 unsigned int i, j;
136
137 for (i = 0; i < 4096; i++) { /* the values of 12 bit dp rhs's */
138 ARMul_ImmedTable[i] = ROTATER (i & 0xffL, (i >> 7L) & 0x1eL);
139 }
140
141 for (i = 0; i < 256; ARMul_BitList[i++] = 0); /* how many bits in LSM */
142 for (j = 1; j < 256; j <<= 1)
143 for (i = 0; i < 256; i++)
144 if ((i & j) > 0)
145 ARMul_BitList[i]++;
146
147 for (i = 0; i < 256; i++)
148 ARMul_BitList[i] *= 4; /* you always need 4 times these values */
149
150}
151
152/***************************************************************************\
153* Returns a new instantiation of the ARMulator's state *
154\***************************************************************************/
155
156ARMul_State *
157ARMul_NewState (ARMul_State *state)
158{
159 unsigned i, j;
160
161 memset (state, 0, sizeof (ARMul_State));
162
163 state->Emulate = RUN;
164 for (i = 0; i < 16; i++) {
165 state->Reg[i] = 0;
166 for (j = 0; j < 7; j++)
167 state->RegBank[j][i] = 0;
168 }
169 for (i = 0; i < 7; i++)
170 state->Spsr[i] = 0;
171 state->Mode = 0;
172
173 state->CallDebug = FALSE;
174 state->Debug = FALSE;
175 state->VectorCatch = 0;
176 state->Aborted = FALSE;
177 state->Reseted = FALSE;
178 state->Inted = 3;
179 state->LastInted = 3;
180
181 state->CommandLine = NULL;
182
183 state->EventSet = 0;
184 state->Now = 0;
185 state->EventPtr =
186 (struct EventNode **) malloc ((unsigned) EVENTLISTSIZE *
187 sizeof (struct EventNode *));
188#if DIFF_STATE
189 state->state_log = fopen("/data/state.log", "w");
190 printf("create pc log file.\n");
191#endif
192 if (state->EventPtr == NULL) {
193 printf ("SKYEYE: ARMul_NewState malloc state->EventPtr error\n");
194 exit(-1);
195 }
196 for (i = 0; i < EVENTLISTSIZE; i++)
197 *(state->EventPtr + i) = NULL;
198#if SAVE_LOG
199 state->state_log = fopen("/tmp/state.log", "w");
200 printf("create pc log file.\n");
201#else
202#if DIFF_LOG
203 state->state_log = fopen("/tmp/state.log", "r");
204 printf("loaded pc log file.\n");
205#endif
206#endif
207
208#ifdef ARM61
209 state->prog32Sig = LOW;
210 state->data32Sig = LOW;
211#else
212 state->prog32Sig = HIGH;
213 state->data32Sig = HIGH;
214#endif
215
216 state->lateabtSig = HIGH;
217 state->bigendSig = LOW;
218
219 //chy:2003-08-19
220 state->LastTime = 0;
221 state->CP14R0_CCD = -1;
222
223 /* ahe-ykl: common function for interpret and dyncom */
224 //sky_pref_t *pref = get_skyeye_pref();
225 //if (pref->user_mode_sim)
226 // register_callback(arm_user_mode_init, Bootmach_callback);
227
228 memset(&state->exclusive_tag_array[0], 0xFF, sizeof(state->exclusive_tag_array[0]) * 128);
229 state->exclusive_access_state = 0;
230 //state->cpu = (cpu_config_t *) malloc (sizeof (cpu_config_t));
231 //state->mem_bank = (mem_config_t *) malloc (sizeof (mem_config_t));
232 return (state);
233}
234
235/***************************************************************************\
236* Call this routine to set ARMulator to model a certain processor *
237\***************************************************************************/
238
239void
240ARMul_SelectProcessor (ARMul_State * state, unsigned properties)
241{
242 if (properties & ARM_Fix26_Prop) {
243 state->prog32Sig = LOW;
244 state->data32Sig = LOW;
245 }
246 else {
247 state->prog32Sig = HIGH;
248 state->data32Sig = HIGH;
249 }
250/* 2004-05-09 chy
251below line sould be in skyeye_mach_XXX.c 's XXX_mach_init function
252*/
253 // state->lateabtSig = HIGH;
254
255
256 state->is_v4 =
257 (properties & (ARM_v4_Prop | ARM_v5_Prop)) ? HIGH : LOW;
258 state->is_v5 = (properties & ARM_v5_Prop) ? HIGH : LOW;
259 state->is_v5e = (properties & ARM_v5e_Prop) ? HIGH : LOW;
260 state->is_XScale = (properties & ARM_XScale_Prop) ? HIGH : LOW;
261 state->is_iWMMXt = (properties & ARM_iWMMXt_Prop) ? HIGH : LOW;
262 /* state->is_v6 = LOW */;
263 /* jeff.du 2010-08-05 */
264 state->is_v6 = (properties & ARM_v6_Prop) ? HIGH : LOW;
265 state->is_ep9312 = (properties & ARM_ep9312_Prop) ? HIGH : LOW;
266 //chy 2005-09-19
267 state->is_pxa27x = (properties & ARM_PXA27X_Prop) ? HIGH : LOW;
268
269 /* shenoubang 2012-3-11 */
270 state->is_v7 = (properties & ARM_v7_Prop) ? HIGH : LOW;
271
272 /* Only initialse the coprocessor support once we
273 know what kind of chip we are dealing with. */
274 //ARMul_CoProInit (state); Commented out /bunnei
275
276}
277
278/***************************************************************************\
279* Call this routine to set up the initial machine state (or perform a RESET *
280\***************************************************************************/
281
282void
283ARMul_Reset (ARMul_State * state)
284{
285 //fprintf(stderr,"armul_reset 0: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
286 state->NextInstr = 0;
287 if (state->prog32Sig) {
288 state->Reg[15] = 0;
289 state->Cpsr = INTBITS | SVC32MODE;
290 state->Mode = SVC32MODE;
291 }
292 else {
293 state->Reg[15] = R15INTBITS | SVC26MODE;
294 state->Cpsr = INTBITS | SVC26MODE;
295 state->Mode = SVC26MODE;
296 }
297 //fprintf(stderr,"armul_reset 1: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
298 ARMul_CPSRAltered (state);
299 state->Bank = SVCBANK;
300 FLUSHPIPE;
301
302 state->EndCondition = 0;
303 state->ErrorCode = 0;
304
305 //fprintf(stderr,"armul_reset 2: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
306 state->NresetSig = HIGH;
307 state->NfiqSig = HIGH;
308 state->NirqSig = HIGH;
309 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
310 state->abortSig = LOW;
311 state->AbortAddr = 1;
312
313 state->NumInstrs = 0;
314 state->NumNcycles = 0;
315 state->NumScycles = 0;
316 state->NumIcycles = 0;
317 state->NumCcycles = 0;
318 state->NumFcycles = 0;
319
320 //fprintf(stderr,"armul_reset 3: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
321 //mmu_reset (state); Commented out /bunnei
322 //fprintf(stderr,"armul_reset 4: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
323
324 //mem_reset (state); /* move to memory/ram.c */
325
326 //fprintf(stderr,"armul_reset 5: state-> Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);
327 /*remove later. walimis 03.7.17 */
328 //io_reset(state);
329 //lcd_disable(state);
330
331 /*ywc 2005-04-07 move from ARMul_NewState , because skyeye_config.no_dbct will
332 *be configured in skyeye_option_init and it is called after ARMul_NewState*/
333 state->tea_break_ok = 0;
334 state->tea_break_addr = 0;
335 state->tea_pc = 0;
336#ifdef DBCT
337 if (!skyeye_config.no_dbct) {
338 //teawater add for arm2x86 2005.02.14-------------------------------------------
339 if (arm2x86_init (state)) {
340 printf ("SKYEYE: arm2x86_init error\n");
341 skyeye_exit (-1);
342 }
343 //AJ2D--------------------------------------------------------------------------
344 }
345#endif
346}
347
348
349/***************************************************************************\
350* Emulate the execution of an entire program. Start the correct emulator *
351* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the *
352* address of the last instruction that is executed. *
353\***************************************************************************/
354
355//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------
356#ifdef DBCT_TEST_SPEED
357static ARMul_State *dbct_test_speed_state = NULL;
358static void
359dbct_test_speed_sig(int signo)
360{
361 printf("\n0x%llx %llu\n", dbct_test_speed_state->instr_count, dbct_test_speed_state->instr_count);
362 skyeye_exit(0);
363}
364#endif //DBCT_TEST_SPEED
365//AJ2D--------------------------------------------------------------------------
366
367ARMword
368ARMul_DoProg (ARMul_State * state)
369{
370 ARMword pc = 0;
371
372 /*
373 * 2007-01-24 removed the term-io functions by Anthony Lee,
374 * moved to "device/uart/skyeye_uart_stdio.c".
375 */
376
377//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------
378#ifdef DBCT_TEST_SPEED
379 {
380 if (!dbct_test_speed_state) {
381 //init timer
382 struct itimerval value;
383 struct sigaction act;
384
385 dbct_test_speed_state = state;
386 state->instr_count = 0;
387 act.sa_handler = dbct_test_speed_sig;
388 act.sa_flags = SA_RESTART;
389 //cygwin don't support ITIMER_VIRTUAL or ITIMER_PROF
390#ifndef __CYGWIN__
391 if (sigaction(SIGVTALRM, &act, NULL) == -1) {
392#else
393 if (sigaction(SIGALRM, &act, NULL) == -1) {
394#endif //__CYGWIN__
395 fprintf(stderr, "init timer error.\n");
396 skyeye_exit(-1);
397 }
398 if (skyeye_config.dbct_test_speed_sec) {
399 value.it_value.tv_sec = skyeye_config.dbct_test_speed_sec;
400 }
401 else {
402 value.it_value.tv_sec = DBCT_TEST_SPEED_SEC;
403 }
404 printf("dbct_test_speed_sec = %ld\n", value.it_value.tv_sec);
405 value.it_value.tv_usec = 0;
406 value.it_interval.tv_sec = 0;
407 value.it_interval.tv_usec = 0;
408#ifndef __CYGWIN__
409 if (setitimer(ITIMER_VIRTUAL, &value, NULL) == -1) {
410#else
411 if (setitimer(ITIMER_REAL, &value, NULL) == -1) {
412#endif //__CYGWIN__
413 fprintf(stderr, "init timer error.\n");
414 skyeye_exit(-1);
415 }
416 }
417 }
418#endif //DBCT_TEST_SPEED
419//AJ2D--------------------------------------------------------------------------
420 state->Emulate = RUN;
421 while (state->Emulate != STOP) {
422 state->Emulate = RUN;
423
424 /*ywc 2005-03-31 */
425 if (state->prog32Sig && ARMul_MODE32BIT) {
426#ifdef DBCT
427 if (skyeye_config.no_dbct) {
428 pc = ARMul_Emulate32 (state);
429 }
430 else {
431 pc = ARMul_Emulate32_dbct (state);
432 }
433#else
434 pc = ARMul_Emulate32 (state);
435#endif
436 }
437
438 else {
439 _dbg_assert_msg_(ARM11, false, "Unsupported ARM 26-bit Mode!");
440 }
441 //chy 2006-02-22, should test debugmode first
442 //chy 2006-04-14, put below codes in ARMul_Emulate
443#if 0
444 if(debugmode)
445 if(remote_interrupt())
446 state->Emulate = STOP;
447#endif
448 }
449
450 /*
451 * 2007-01-24 removed the term-io functions by Anthony Lee,
452 * moved to "device/uart/skyeye_uart_stdio.c".
453 */
454
455 return (pc);
456}
457
458/***************************************************************************\
459* Emulate the execution of one instruction. Start the correct emulator *
460* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the *
461* address of the instruction that is executed. *
462\***************************************************************************/
463
464ARMword
465ARMul_DoInstr (ARMul_State * state)
466{
467 ARMword pc = 0;
468
469 state->Emulate = ONCE;
470
471 /*ywc 2005-03-31 */
472 if (state->prog32Sig && ARMul_MODE32BIT) {
473#ifdef DBCT
474 if (skyeye_config.no_dbct) {
475 pc = ARMul_Emulate32 (state);
476 }
477 else {
478//teawater add compile switch for DBCT GDB RSP function 2005.10.21--------------
479#ifndef DBCT_GDBRSP
480 printf("DBCT GDBRSP function switch is off.\n");
481 printf("To use this function, open \"#define DBCT_GDBRSP\" in arch/arm/common/armdefs.h & recompile skyeye.\n");
482 skyeye_exit(-1);
483#endif //DBCT_GDBRSP
484//AJ2D--------------------------------------------------------------------------
485 pc = ARMul_Emulate32_dbct (state);
486 }
487#else
488 pc = ARMul_Emulate32 (state);
489#endif
490 }
491
492 else {
493 _dbg_assert_msg_(ARM11, false, "Unsupported ARM 26-bit Mode!");
494 }
495
496 return (pc);
497}
498
499/***************************************************************************\
500* This routine causes an Abort to occur, including selecting the correct *
501* mode, register bank, and the saving of registers. Call with the *
502* appropriate vector's memory address (0,4,8 ....) *
503\***************************************************************************/
504
505void
506ARMul_Abort (ARMul_State * state, ARMword vector)
507{
508 ARMword temp;
509 int isize = INSN_SIZE;
510 int esize = (TFLAG ? 0 : 4);
511 int e2size = (TFLAG ? -4 : 0);
512
513 state->Aborted = FALSE;
514
515 if (state->prog32Sig)
516 if (ARMul_MODE26BIT)
517 temp = R15PC;
518 else
519 temp = state->Reg[15];
520 else
521 temp = R15PC | ECC | ER15INT | EMODE;
522
523 switch (vector) {
524 case ARMul_ResetV: /* RESET */
525 SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE,
526 0);
527 break;
528 case ARMul_UndefinedInstrV: /* Undefined Instruction */
529 SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE,
530 isize);
531 break;
532 case ARMul_SWIV: /* Software Interrupt */
533 SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE,
534 isize);
535 break;
536 case ARMul_PrefetchAbortV: /* Prefetch Abort */
537 state->AbortAddr = 1;
538 SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
539 esize);
540 break;
541 case ARMul_DataAbortV: /* Data Abort */
542 SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
543 e2size);
544 break;
545 case ARMul_AddrExceptnV: /* Address Exception */
546 SETABORT (IBIT, SVC26MODE, isize);
547 break;
548 case ARMul_IRQV: /* IRQ */
549 //chy 2003-09-02 the if sentence seems no use
550#if 0
551 if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp)
552 || (temp & ARMul_CP13_R0_IRQ))
553#endif
554 SETABORT (IBIT,
555 state->prog32Sig ? IRQ32MODE : IRQ26MODE,
556 esize);
557 break;
558 case ARMul_FIQV: /* FIQ */
559 //chy 2003-09-02 the if sentence seems no use
560#if 0
561 if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp)
562 || (temp & ARMul_CP13_R0_FIQ))
563#endif
564 SETABORT (INTBITS,
565 state->prog32Sig ? FIQ32MODE : FIQ26MODE,
566 esize);
567 break;
568 }
569
570 if (ARMul_MODE32BIT) {
571 if (state->mmu.control & CONTROL_VECTOR)
572 vector += 0xffff0000; //for v4 high exception address
573 if (state->vector_remap_flag)
574 vector += state->vector_remap_addr; /* support some remap function in LPC processor */
575 ARMul_SetR15 (state, vector);
576 }
577 else
578 ARMul_SetR15 (state, R15CCINTMODE | vector);
579}
diff --git a/src/core/arm/interpreter/armmmu.cpp b/src/core/arm/interpreter/armmmu.cpp
new file mode 100644
index 000000000..242e6a83c
--- /dev/null
+++ b/src/core/arm/interpreter/armmmu.cpp
@@ -0,0 +1,238 @@
1/*
2 armmmu.c - Memory Management Unit emulation.
3 ARMulator extensions for the ARM7100 family.
4 Copyright (C) 1999 Ben Williamson
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19*/
20
21#include <assert.h>
22#include <string.h>
23#include "armdefs.h"
24/* two header for arm disassemble */
25//#include "skyeye_arch.h"
26#include "armcpu.h"
27
28
29extern mmu_ops_t xscale_mmu_ops;
30exception_t arm_mmu_write(short size, u32 addr, uint32_t *value);
31exception_t arm_mmu_read(short size, u32 addr, uint32_t *value);
32#define MMU_OPS (state->mmu.ops)
33ARMword skyeye_cachetype = -1;
34
35int
36mmu_init (ARMul_State * state)
37{
38 int ret;
39
40 state->mmu.control = 0x70;
41 state->mmu.translation_table_base = 0xDEADC0DE;
42 state->mmu.domain_access_control = 0xDEADC0DE;
43 state->mmu.fault_status = 0;
44 state->mmu.fault_address = 0;
45 state->mmu.process_id = 0;
46
47 switch (state->cpu->cpu_val & state->cpu->cpu_mask) {
48 //case SA1100:
49 //case SA1110:
50 // NOTICE_LOG(ARM11, "SKYEYE: use sa11xx mmu ops\n");
51 // state->mmu.ops = sa_mmu_ops;
52 // break;
53 //case PXA250:
54 //case PXA270: //xscale
55 // NOTICE_LOG(ARM11, "SKYEYE: use xscale mmu ops\n");
56 // state->mmu.ops = xscale_mmu_ops;
57 // break;
58 //case 0x41807200: //arm720t
59 //case 0x41007700: //arm7tdmi
60 //case 0x41007100: //arm7100
61 // NOTICE_LOG(ARM11, "SKYEYE: use arm7100 mmu ops\n");
62 // state->mmu.ops = arm7100_mmu_ops;
63 // break;
64 //case 0x41009200:
65 // NOTICE_LOG(ARM11, "SKYEYE: use arm920t mmu ops\n");
66 // state->mmu.ops = arm920t_mmu_ops;
67 // break;
68 //case 0x41069260:
69 // NOTICE_LOG(ARM11, "SKYEYE: use arm926ejs mmu ops\n");
70 // state->mmu.ops = arm926ejs_mmu_ops;
71 // break;
72 /* case 0x560f5810: */
73 case 0x0007b000:
74 NOTICE_LOG(ARM11, "SKYEYE: use arm11jzf-s mmu ops\n");
75 state->mmu.ops = arm1176jzf_s_mmu_ops;
76 break;
77
78 default:
79 ERROR_LOG (ARM11,
80 "SKYEYE: armmmu.c : mmu_init: unknown cpu_val&cpu_mask 0x%x\n",
81 state->cpu->cpu_val & state->cpu->cpu_mask);
82 break;
83
84 };
85 ret = state->mmu.ops.init (state);
86 state->mmu_inited = (ret == 0);
87 /* initialize mmu_read and mmu_write for disassemble */
88 //skyeye_config_t *config = get_current_config();
89 //generic_arch_t *arch_instance = get_arch_instance(config->arch->arch_name);
90 //arch_instance->mmu_read = arm_mmu_read;
91 //arch_instance->mmu_write = arm_mmu_write;
92
93 return ret;
94}
95
96int
97mmu_reset (ARMul_State * state)
98{
99 if (state->mmu_inited)
100 mmu_exit (state);
101 return mmu_init (state);
102}
103
104void
105mmu_exit (ARMul_State * state)
106{
107 MMU_OPS.exit (state);
108 state->mmu_inited = 0;
109}
110
111fault_t
112mmu_read_byte (ARMul_State * state, ARMword virt_addr, ARMword * data)
113{
114 return MMU_OPS.read_byte (state, virt_addr, data);
115};
116
117fault_t
118mmu_read_halfword (ARMul_State * state, ARMword virt_addr, ARMword * data)
119{
120 return MMU_OPS.read_halfword (state, virt_addr, data);
121};
122
123fault_t
124mmu_read_word (ARMul_State * state, ARMword virt_addr, ARMword * data)
125{
126 return MMU_OPS.read_word (state, virt_addr, data);
127};
128
129fault_t
130mmu_write_byte (ARMul_State * state, ARMword virt_addr, ARMword data)
131{
132 fault_t fault;
133 //static int count = 0;
134 //count ++;
135 fault = MMU_OPS.write_byte (state, virt_addr, data);
136 return fault;
137}
138
139fault_t
140mmu_write_halfword (ARMul_State * state, ARMword virt_addr, ARMword data)
141{
142 fault_t fault;
143 //static int count = 0;
144 //count ++;
145 fault = MMU_OPS.write_halfword (state, virt_addr, data);
146 return fault;
147}
148
149fault_t
150mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data)
151{
152 fault_t fault;
153 fault = MMU_OPS.write_word (state, virt_addr, data);
154
155 /*used for debug for MMU*
156
157 if (!fault){
158 ARMword tmp;
159
160 if (mmu_read_word(state, virt_addr, &tmp)){
161 err_msg("load back\n");
162 exit(-1);
163 }else{
164 if (tmp != data){
165 err_msg("load back not equal %d %x\n", count, virt_addr);
166 }
167 }
168 }
169 */
170
171 return fault;
172};
173
174fault_t
175mmu_load_instr (ARMul_State * state, ARMword virt_addr, ARMword * instr)
176{
177 return MMU_OPS.load_instr (state, virt_addr, instr);
178}
179
180ARMword
181mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value)
182{
183 return MMU_OPS.mrc (state, instr, value);
184}
185
186void
187mmu_mcr (ARMul_State * state, ARMword instr, ARMword value)
188{
189 MMU_OPS.mcr (state, instr, value);
190}
191
192/*ywc 20050416*/
193int
194mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr, ARMword * phys_addr)
195{
196 return (MMU_OPS.v2p_dbct (state, virt_addr, phys_addr));
197}
198
199//
200//
201///* dis_mmu_read for disassemble */
202//exception_t arm_mmu_read(short size, uint32_t addr, uint32_t * value)
203//{
204// ARMul_State *state;
205// ARM_CPU_State *cpu = get_current_cpu();
206// state = &cpu->core[0];
207// switch(size){
208// case 8:
209// MMU_OPS.read_byte (state, addr, value);
210// break;
211// case 16:
212// case 32:
213// break;
214// default:
215// ERROR_LOG(ARM11, "Error size %d", size);
216// break;
217// }
218// return No_exp;
219//}
220///* dis_mmu_write for disassemble */
221//exception_t arm_mmu_write(short size, uint32_t addr, uint32_t *value)
222//{
223// ARMul_State *state;
224// ARM_CPU_State *cpu = get_current_cpu();
225// state = &cpu->core[0];
226// switch(size){
227// case 8:
228// MMU_OPS.write_byte (state, addr, value);
229// break;
230// case 16:
231// case 32:
232// break;
233// default:
234// printf("In %s error size %d Line %d\n", __func__, size, __LINE__);
235// break;
236// }
237// return No_exp;
238//}
diff --git a/src/core/arm/interpreter/armmmu.h b/src/core/arm/interpreter/armmmu.h
new file mode 100644
index 000000000..c28d8753e
--- /dev/null
+++ b/src/core/arm/interpreter/armmmu.h
@@ -0,0 +1,254 @@
1/*
2 armmmu.c - Memory Management Unit emulation.
3 ARMulator extensions for the ARM7100 family.
4 Copyright (C) 1999 Ben Williamson
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19*/
20
21#ifndef _ARMMMU_H_
22#define _ARMMMU_H_
23
24
25#define WORD_SHT 2
26#define WORD_SIZE (1<<WORD_SHT)
27/* The MMU is accessible with MCR and MRC operations to copro 15: */
28
29#define MMU_COPRO (15)
30
31/* Register numbers in the MMU: */
32
33typedef enum mmu_regnum_t
34{
35 MMU_ID = 0,
36 MMU_CONTROL = 1,
37 MMU_TRANSLATION_TABLE_BASE = 2,
38 MMU_DOMAIN_ACCESS_CONTROL = 3,
39 MMU_FAULT_STATUS = 5,
40 MMU_FAULT_ADDRESS = 6,
41 MMU_CACHE_OPS = 7,
42 MMU_TLB_OPS = 8,
43 MMU_CACHE_LOCKDOWN = 9,
44 MMU_TLB_LOCKDOWN = 10,
45 MMU_PID = 13,
46
47 /*MMU_V4 */
48 MMU_V4_CACHE_OPS = 7,
49 MMU_V4_TLB_OPS = 8,
50
51 /*MMU_V3 */
52 MMU_V3_FLUSH_TLB = 5,
53 MMU_V3_FLUSH_TLB_ENTRY = 6,
54 MMU_V3_FLUSH_CACHE = 7,
55
56 /*MMU Intel SA-1100 */
57 MMU_SA_RB_OPS = 9,
58 MMU_SA_DEBUG = 14,
59 MMU_SA_CP15_R15 = 15,
60 //chy 2003-08-24
61 /*Intel xscale CP15 */
62 XSCALE_CP15_CACHE_TYPE = 0,
63 XSCALE_CP15_AUX_CONTROL = 1,
64 XSCALE_CP15_COPRO_ACCESS = 15,
65
66} mmu_regnum_t;
67
68/* Bits in the control register */
69
70#define CONTROL_MMU (1<<0)
71#define CONTROL_ALIGN_FAULT (1<<1)
72#define CONTROL_CACHE (1<<2)
73#define CONTROL_DATA_CACHE (1<<2)
74#define CONTROL_WRITE_BUFFER (1<<3)
75#define CONTROL_BIG_ENDIAN (1<<7)
76#define CONTROL_SYSTEM (1<<8)
77#define CONTROL_ROM (1<<9)
78#define CONTROL_UNDEFINED (1<<10)
79#define CONTROL_BRANCH_PREDICT (1<<11)
80#define CONTROL_INSTRUCTION_CACHE (1<<12)
81#define CONTROL_VECTOR (1<<13)
82#define CONTROL_RR (1<<14)
83#define CONTROL_L4 (1<<15)
84#define CONTROL_XP (1<<23)
85#define CONTROL_EE (1<<25)
86
87/*Macro defines for MMU state*/
88#define MMU_CTL (state->mmu.control)
89#define MMU_Enabled (state->mmu.control & CONTROL_MMU)
90#define MMU_Disabled (!(MMU_Enabled))
91#define MMU_Aligned (state->mmu.control & CONTROL_ALIGN_FAULT)
92
93#define MMU_ICacheEnabled (MMU_CTL & CONTROL_INSTRUCTION_CACHE)
94#define MMU_ICacheDisabled (!(MMU_ICacheDisabled))
95
96#define MMU_DCacheEnabled (MMU_CTL & CONTROL_DATA_CACHE)
97#define MMU_DCacheDisabled (!(MMU_DCacheEnabled))
98
99#define MMU_CacheEnabled (MMU_CTL & CONTROL_CACHE)
100#define MMU_CacheDisabled (!(MMU_CacheEnabled))
101
102#define MMU_WBEnabled (MMU_CTL & CONTROL_WRITE_BUFFER)
103#define MMU_WBDisabled (!(MMU_WBEnabled))
104
105/*virt_addr exchange according to CP15.R13(process id virtul mapping)*/
106#define PID_VA_MAP_MASK 0xfe000000
107//#define mmu_pid_va_map(va) ({\
108// ARMword ret; \
109// if ((va) & PID_VA_MAP_MASK)\
110// ret = (va); \
111// else \
112// ret = ((va) | (state->mmu.process_id & PID_VA_MAP_MASK));\
113// ret;\
114//})
115#define mmu_pid_va_map(va) ((va) & PID_VA_MAP_MASK) ? (va) : ((va) | (state->mmu.process_id & PID_VA_MAP_MASK))
116
117/* FS[3:0] in the fault status register: */
118
119typedef enum fault_t
120{
121 NO_FAULT = 0x0,
122 ALIGNMENT_FAULT = 0x1,
123
124 SECTION_TRANSLATION_FAULT = 0x5,
125 PAGE_TRANSLATION_FAULT = 0x7,
126 SECTION_DOMAIN_FAULT = 0x9,
127 PAGE_DOMAIN_FAULT = 0xB,
128 SECTION_PERMISSION_FAULT = 0xD,
129 SUBPAGE_PERMISSION_FAULT = 0xF,
130
131 /* defined by skyeye */
132 TLB_READ_MISS = 0x30,
133 TLB_WRITE_MISS = 0x40,
134
135} fault_t;
136
137typedef struct mmu_ops_s
138{
139 /*initilization */
140 int (*init) (ARMul_State * state);
141 /*free on exit */
142 void (*exit) (ARMul_State * state);
143 /*read byte data */
144 fault_t (*read_byte) (ARMul_State * state, ARMword va,
145 ARMword * data);
146 /*write byte data */
147 fault_t (*write_byte) (ARMul_State * state, ARMword va,
148 ARMword data);
149 /*read halfword data */
150 fault_t (*read_halfword) (ARMul_State * state, ARMword va,
151 ARMword * data);
152 /*write halfword data */
153 fault_t (*write_halfword) (ARMul_State * state, ARMword va,
154 ARMword data);
155 /*read word data */
156 fault_t (*read_word) (ARMul_State * state, ARMword va,
157 ARMword * data);
158 /*write word data */
159 fault_t (*write_word) (ARMul_State * state, ARMword va,
160 ARMword data);
161 /*load instr */
162 fault_t (*load_instr) (ARMul_State * state, ARMword va,
163 ARMword * instr);
164 /*mcr */
165 ARMword (*mcr) (ARMul_State * state, ARMword instr, ARMword val);
166 /*mrc */
167 ARMword (*mrc) (ARMul_State * state, ARMword instr, ARMword * val);
168
169 /*ywc 2005-04-16 convert virtual address to physics address */
170 int (*v2p_dbct) (ARMul_State * state, ARMword virt_addr,
171 ARMword * phys_addr);
172} mmu_ops_t;
173
174
175#include "arm/mmu/tlb.h"
176#include "arm/mmu/rb.h"
177#include "arm/mmu/wb.h"
178#include "arm/mmu/cache.h"
179
180/*special process mmu.h*/
181//#include "arm/mmu/sa_mmu.h"
182//#include "arm/mmu/arm7100_mmu.h"
183//#include "arm/mmu/arm920t_mmu.h"
184//#include "arm/mmu/arm926ejs_mmu.h"
185#include "arm/mmu/arm1176jzf_s_mmu.h"
186//#include "arm/mmu/cortex_a9_mmu.h"
187
188typedef struct mmu_state_t
189{
190 ARMword control;
191 ARMword translation_table_base;
192/* dyf 201-08-11 for arm1176 */
193 ARMword auxiliary_control;
194 ARMword coprocessor_access_control;
195 ARMword translation_table_base0;
196 ARMword translation_table_base1;
197 ARMword translation_table_ctrl;
198/* arm1176 end */
199
200 ARMword domain_access_control;
201 ARMword fault_status;
202 ARMword fault_statusi; /* prefetch fault status */
203 ARMword fault_address;
204 ARMword last_domain;
205 ARMword process_id;
206 ARMword context_id;
207 ARMword thread_uro_id;
208 ARMword cache_locked_down;
209 ARMword tlb_locked_down;
210//chy 2003-08-24 for xscale
211 ARMword cache_type; // 0
212 ARMword aux_control; // 1
213 ARMword copro_access; // 15
214
215 mmu_ops_t ops;
216 //union
217 //{
218 //sa_mmu_t sa_mmu;
219 //arm7100_mmu_t arm7100_mmu;
220 //arm920t_mmu_t arm920t_mmu;
221 //arm926ejs_mmu_t arm926ejs_mmu;
222 //} u;
223} mmu_state_t;
224
225int mmu_init (ARMul_State * state);
226int mmu_reset (ARMul_State * state);
227void mmu_exit (ARMul_State * state);
228
229fault_t mmu_read_word (ARMul_State * state, ARMword virt_addr,
230 ARMword * data);
231fault_t mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data);
232fault_t mmu_load_instr (ARMul_State * state, ARMword virt_addr,
233 ARMword * instr);
234
235ARMword mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value);
236void mmu_mcr (ARMul_State * state, ARMword instr, ARMword value);
237
238/*ywc 20050416*/
239int mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr,
240 ARMword * phys_addr);
241
242fault_t
243mmu_read_byte (ARMul_State * state, ARMword virt_addr, ARMword * data);
244fault_t
245mmu_read_halfword (ARMul_State * state, ARMword virt_addr, ARMword * data);
246fault_t
247mmu_read_word (ARMul_State * state, ARMword virt_addr, ARMword * data);
248fault_t
249mmu_write_byte (ARMul_State * state, ARMword virt_addr, ARMword data);
250fault_t
251mmu_write_halfword (ARMul_State * state, ARMword virt_addr, ARMword data);
252fault_t
253mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data);
254#endif /* _ARMMMU_H_ */
diff --git a/src/core/arm/interpreter/armos.cpp b/src/core/arm/interpreter/armos.cpp
new file mode 100644
index 000000000..43484ee5f
--- /dev/null
+++ b/src/core/arm/interpreter/armos.cpp
@@ -0,0 +1,742 @@
1/* armos.c -- ARMulator OS interface: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18/* This file contains a model of Demon, ARM Ltd's Debug Monitor,
19including all the SWI's required to support the C library. The code in
20it is not really for the faint-hearted (especially the abort handling
21code), but it is a complete example. Defining NOOS will disable all the
22fun, and definign VAILDATE will define SWI 1 to enter SVC mode, and SWI
230x11 to halt the emulator. */
24
25//chy 2005-09-12 disable below line
26//#include "config.h"
27
28#include <time.h>
29#include <errno.h>
30#include <string.h>
31#include "skyeye_defs.h"
32#ifndef __USE_LARGEFILE64
33#define __USE_LARGEFILE64 /* When use 64 bit large file need define it! for stat64*/
34#endif
35#include <fcntl.h>
36#include <sys/stat.h>
37
38
39#ifndef O_RDONLY
40#define O_RDONLY 0
41#endif
42#ifndef O_WRONLY
43#define O_WRONLY 1
44#endif
45#ifndef O_RDWR
46#define O_RDWR 2
47#endif
48#ifndef O_BINARY
49#define O_BINARY 0
50#endif
51
52#ifdef __STDC__
53#define unlink(s) remove(s)
54#endif
55
56#ifdef HAVE_UNISTD_H
57#include <unistd.h> /* For SEEK_SET etc */
58#endif
59
60#ifdef __riscos
61extern int _fisatty (FILE *);
62#define isatty_(f) _fisatty(f)
63#else
64#ifdef __ZTC__
65#include <io.h>
66#define isatty_(f) isatty((f)->_file)
67#else
68#ifdef macintosh
69#include <ioctl.h>
70#define isatty_(f) (~ioctl ((f)->_file, FIOINTERACTIVE, NULL))
71#else
72#define isatty_(f) isatty (fileno (f))
73#endif
74#endif
75#endif
76
77#include "armdefs.h"
78#include "armos.h"
79#include "armemu.h"
80
81#ifndef NOOS
82#ifndef VALIDATE
83/* #ifndef ASIM */
84//chy 2005-09-12 disable below line
85//#include "armfpe.h"
86/* #endif */
87#endif
88#endif
89
90#define DUMP_SYSCALL 0
91#define dump(...) do { if (DUMP_SYSCALL) printf(__VA_ARGS__); } while(0)
92//#define debug(...) printf(__VA_ARGS__);
93#define debug(...) ;
94
95extern unsigned ARMul_OSHandleSWI (ARMul_State * state, ARMword number);
96
97#ifndef FOPEN_MAX
98#define FOPEN_MAX 64
99#endif
100
101/***************************************************************************\
102* OS private Information *
103\***************************************************************************/
104
105unsigned arm_dyncom_SWI(ARMul_State * state, ARMword number)
106{
107 return ARMul_OSHandleSWI(state, number);
108}
109
110//mmap_area_t *mmap_global = NULL;
111
112static int translate_open_mode[] = {
113 O_RDONLY, /* "r" */
114 O_RDONLY + O_BINARY, /* "rb" */
115 O_RDWR, /* "r+" */
116 O_RDWR + O_BINARY, /* "r+b" */
117 O_WRONLY + O_CREAT + O_TRUNC, /* "w" */
118 O_WRONLY + O_BINARY + O_CREAT + O_TRUNC, /* "wb" */
119 O_RDWR + O_CREAT + O_TRUNC, /* "w+" */
120 O_RDWR + O_BINARY + O_CREAT + O_TRUNC, /* "w+b" */
121 O_WRONLY + O_APPEND + O_CREAT, /* "a" */
122 O_WRONLY + O_BINARY + O_APPEND + O_CREAT, /* "ab" */
123 O_RDWR + O_APPEND + O_CREAT, /* "a+" */
124 O_RDWR + O_BINARY + O_APPEND + O_CREAT /* "a+b" */
125};
126//
127//static void
128//SWIWrite0 (ARMul_State * state, ARMword addr)
129//{
130// ARMword temp;
131//
132// //while ((temp = ARMul_ReadByte (state, addr++)) != 0)
133// while(1){
134// mem_read(8, addr++, &temp);
135// if(temp != 0)
136// (void) fputc ((char) temp, stdout);
137// else
138// break;
139// }
140//}
141//
142//static void
143//WriteCommandLineTo (ARMul_State * state, ARMword addr)
144//{
145// ARMword temp;
146// char *cptr = state->CommandLine;
147// if (cptr == NULL)
148// cptr = "\0";
149// do {
150// temp = (ARMword) * cptr++;
151// //ARMul_WriteByte (state, addr++, temp);
152// mem_write(8, addr++, temp);
153// }
154// while (temp != 0);
155//}
156//
157//static void
158//SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
159//{
160// char dummy[2000];
161// int flags;
162// int i;
163//
164// for (i = 0; (dummy[i] = ARMul_ReadByte (state, name + i)); i++);
165// assert(SWIflags< (sizeof(translate_open_mode)/ sizeof(translate_open_mode[0])));
166// /* Now we need to decode the Demon open mode */
167// flags = translate_open_mode[SWIflags];
168// flags = SWIflags;
169//
170// /* Filename ":tt" is special: it denotes stdin/out */
171// if (strcmp (dummy, ":tt") == 0) {
172// if (flags == O_RDONLY) /* opening tty "r" */
173// state->Reg[0] = 0; /* stdin */
174// else
175// state->Reg[0] = 1; /* stdout */
176// }
177// else {
178// state->Reg[0] = (int) open (dummy, flags, 0666);
179// }
180//}
181//
182//static void
183//SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
184//{
185// int res;
186// int i;
187// char *local = (char*) malloc (len);
188//
189// if (local == NULL) {
190// fprintf (stderr,
191// "sim: Unable to read 0x%ulx bytes - out of memory\n",
192// len);
193// return;
194// }
195//
196// res = read (f, local, len);
197// if (res > 0)
198// for (i = 0; i < res; i++)
199// //ARMul_WriteByte (state, ptr + i, local[i]);
200// mem_write(8, ptr + i, local[i]);
201// free (local);
202// //state->Reg[0] = res == -1 ? -1 : len - res;
203// state->Reg[0] = res;
204//}
205//
206//static void
207//SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
208//{
209// int res;
210// ARMword i;
211// char *local = malloc (len);
212//
213// if (local == NULL) {
214// fprintf (stderr,
215// "sim: Unable to write 0x%lx bytes - out of memory\n",
216// (long unsigned int) len);
217// return;
218// }
219//
220// for (i = 0; i < len; i++){
221// //local[i] = ARMul_ReadByte (state, ptr + i);
222// ARMword data;
223// mem_read(8, ptr + i, &data);
224// local[i] = data & 0xFF;
225// }
226//
227// res = write (f, local, len);
228// //state->Reg[0] = res == -1 ? -1 : len - res;
229// state->Reg[0] = res;
230// free (local);
231//}
232
233//static void
234//SWIflen (ARMul_State * state, ARMword fh)
235//{
236// ARMword addr;
237//
238// if (fh == 0 || fh > FOPEN_MAX) {
239// state->Reg[0] = -1L;
240// return;
241// }
242//
243// addr = lseek (fh, 0, SEEK_CUR);
244//
245// state->Reg[0] = lseek (fh, 0L, SEEK_END);
246// (void) lseek (fh, addr, SEEK_SET);
247//
248//}
249
250/***************************************************************************\
251* The emulator calls this routine when a SWI instruction is encuntered. The *
252* parameter passed is the SWI number (lower 24 bits of the instruction). *
253\***************************************************************************/
254/* ahe-ykl information is retrieved from elf header and the starting value of
255 brk_static is in sky_info_t */
256
257/* brk static hold the value of brk */
258static uint32_t brk_static = -1;
259
260unsigned
261ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
262{
263 number &= 0xfffff;
264 ARMword addr, temp;
265
266 switch (number) {
267// case SWI_Syscall:
268// if (state->Reg[7] != 0)
269// return ARMul_OSHandleSWI(state, state->Reg[7]);
270// else
271// return FALSE;
272// case SWI_Read:
273// SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
274// return TRUE;
275//
276// case SWI_GetUID32:
277// state->Reg[0] = getuid();
278// return TRUE;
279//
280// case SWI_GetGID32:
281// state->Reg[0] = getgid();
282// return TRUE;
283//
284// case SWI_GetEUID32:
285// state->Reg[0] = geteuid();
286// return TRUE;
287//
288// case SWI_GetEGID32:
289// state->Reg[0] = getegid();
290// return TRUE;
291//
292// case SWI_Write:
293// SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
294// return TRUE;
295//
296// case SWI_Open:
297// SWIopen (state, state->Reg[0], state->Reg[1]);
298// return TRUE;
299//
300// case SWI_Close:
301// state->Reg[0] = close (state->Reg[0]);
302// return TRUE;
303//
304// case SWI_Seek:{
305// /* We must return non-zero for failure */
306// state->Reg[0] =
307// lseek (state->Reg[0], state->Reg[1],
308// SEEK_SET);
309// return TRUE;
310// }
311//
312// case SWI_ExitGroup:
313// case SWI_Exit:
314// {
315// struct timeval tv;
316// //gettimeofday(&tv,NULL);
317// //printf("In %s, %d sec, %d usec\n", __FUNCTION__, tv.tv_sec, tv.tv_usec);
318// printf("passed %d sec, %lld usec\n", get_clock_sec(), get_clock_us());
319//
320// /* quit here */
321// run_command("quit");
322// return TRUE;
323// }
324// case SWI_Times:{
325// uint32_t dest = state->Reg[0];
326// struct tms now;
327// struct target_tms32 nowret;
328//
329// uint32_t ret = times(&now);
330//
331// if (ret == -1){
332// debug("syscall %s error %d\n", "SWI_Times", ret);
333// state->Reg[0] = ret;
334// return FALSE;
335// }
336//
337// nowret.tms_cstime = now.tms_cstime;
338// nowret.tms_cutime = now.tms_cutime;
339// nowret.tms_stime = now.tms_stime;
340// nowret.tms_utime = now.tms_utime;
341//
342// uint32_t offset;
343// for (offset = 0; offset < sizeof(nowret); offset++) {
344// bus_write(8, dest + offset, *((uint8_t *) &nowret + offset));
345// }
346//
347// state->Reg[0] = ret;
348// return TRUE;
349// }
350//
351// case SWI_Gettimeofday: {
352// uint32_t dest1 = state->Reg[0];
353// uint32_t dest2 = state->Reg[1]; // Unsure of this
354// struct timeval val;
355// struct timezone zone;
356// struct target_timeval32 valret;
357// struct target_timezone32 zoneret;
358//
359// uint32_t ret = gettimeofday(&val, &zone);
360// valret.tv_sec = val.tv_sec;
361// valret.tv_usec = val.tv_usec;
362// zoneret.tz_dsttime = zoneret.tz_dsttime;
363// zoneret.tz_minuteswest = zoneret.tz_minuteswest;
364//
365// if (ret == -1){
366// debug("syscall %s error %d\n", "SWI_Gettimeofday", ret);
367// state->Reg[0] = ret;
368// return FALSE;
369// }
370//
371// uint32_t offset;
372// if (dest1) {
373// for (offset = 0; offset < sizeof(valret); offset++) {
374// bus_write(8, dest1 + offset, *((uint8_t *) &valret + offset));
375// }
376// state->Reg[0] = ret;
377// }
378// if (dest2) {
379// for (offset = 0; offset < sizeof(zoneret); offset++) {
380// bus_write(8, dest2 + offset, *((uint8_t *) &zoneret + offset));
381// }
382// state->Reg[0] = ret;
383// }
384//
385// return TRUE;
386// }
387// case SWI_Brk:
388// /* initialize brk value */
389// /* suppose that brk_static doesn't reach 0xffffffff... */
390// if (brk_static == -1) {
391// brk_static = (get_skyeye_pref()->info).brk;
392// }
393//
394// /* FIXME there might be a need to do a mmap */
395//
396// if(state->Reg[0]){
397// if (get_skyeye_exec_info()->mmap_access) {
398// /* if new brk is greater than current brk, allocate memory */
399// if (state->Reg[0] > brk_static) {
400// uint32_t ret = mmap( (void *) brk_static, state->Reg[0] - brk_static,
401// PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0 );
402// if (ret != MAP_FAILED)
403// brk_static = ret;
404// }
405// }
406// brk_static = state->Reg[0];
407// //state->Reg[0] = 0; /* FIXME return value of brk set to be the address on success */
408// } else {
409// state->Reg[0] = brk_static;
410// }
411// return TRUE;
412//
413// case SWI_Break:
414// state->Emulate = FALSE;
415// return TRUE;
416//
417// case SWI_Mmap:{
418// int addr = state->Reg[0];
419// int len = state->Reg[1];
420// int prot = state->Reg[2];
421// int flag = state->Reg[3];
422// int fd = state->Reg[4];
423// int offset = state->Reg[5];
424// mmap_area_t *area = new_mmap_area(addr, len);
425// state->Reg[0] = area->bank.addr;
426// //printf("syscall %d mmap(0x%x,%x,0x%x,0x%x,%d,0x%x) = 0x%x\n",\
427// SWI_Mmap, addr, len, prot, flag, fd, offset, state->Reg[0]);
428// return TRUE;
429// }
430//
431// case SWI_Munmap:
432// state->Reg[0] = 0;
433// return TRUE;
434//
435// case SWI_Mmap2:{
436// int addr = state->Reg[0];
437// int len = state->Reg[1];
438// int prot = state->Reg[2];
439// int flag = state->Reg[3];
440// int fd = state->Reg[4];
441// int offset = state->Reg[5] * 4096; /* page offset */
442// mmap_area_t *area = new_mmap_area(addr, len);
443// state->Reg[0] = area->bank.addr;
444//
445// return TRUE;
446// }
447//
448// case SWI_Breakpoint:
449// //chy 2005-09-12 change below line
450// //state->EndCondition = RDIError_BreakpointReached;
451// //printf ("SKYEYE: in armos.c : should not come here!!!!\n");
452// state->EndCondition = 0;
453// /*modified by ksh to support breakpoiont*/
454// state->Emulate = STOP;
455// return (TRUE);
456// case SWI_Uname:
457// {
458// struct utsname *uts = (uintptr_t) state->Reg[0]; /* uname should write data in this address */
459// struct utsname utsbuf;
460// //printf("Uname size is %x\n", sizeof(utsbuf));
461// char *buf;
462// uintptr_t sp ; /* used as a temporary address */
463//
464//#define COPY_UTS_STRING(addr) \
465// buf = addr; \
466// while(*buf != NULL) { \
467// bus_write(8, sp, *buf); \
468// sp++; \
469// buf++; \
470// }
471//#define COPY_UTS(field) /*printf("%s: %s at %p\n", #field, utsbuf.field, uts->field);*/ \
472// sp = (uintptr_t) uts->field; \
473// COPY_UTS_STRING((&utsbuf)->field);
474//
475// if (uname(&utsbuf) < 0) {
476// printf("syscall uname: utsname error\n");
477// state->Reg[0] = -1;
478// return FALSE;
479// }
480//
481// /* FIXME for now, this is just the host system call
482// Some data should be missing, as it depends on
483// the version of utsname */
484// COPY_UTS(sysname);
485// COPY_UTS(nodename);
486// COPY_UTS(release);
487// COPY_UTS(version);
488// COPY_UTS(machine);
489//
490// state->Reg[0] = 0;
491// return TRUE;
492// }
493// case SWI_Fcntl:
494// {
495// uint32_t fd = state->Reg[0];
496// uint32_t cmd = state->Reg[1];
497// uint32_t arg = state->Reg[2];
498// uint32_t ret;
499//
500// switch(cmd){
501// case (F_GETFD):
502// {
503// ret = fcntl(fd, cmd, arg);
504// //printf("syscall fcntl for getfd not implemented, ret %d\n", ret);
505// state->Reg[0] = ret;
506// return FALSE;
507// }
508// default:
509// break;
510// }
511//
512// printf("syscall fcntl unimplemented fd %x cmd %x\n", fd, cmd);
513// state->Reg[0] = -1;
514// return FALSE;
515//
516// }
517// case SWI_Fstat64:
518// {
519// uint32_t dest = state->Reg[1];
520// uint32_t fd = state->Reg[0];
521// struct stat64 statbuf;
522// struct target_stat64 statret;
523// memset(&statret, 0, sizeof(struct target_stat64));
524// uint32_t ret = fstat64(fd, &statbuf);
525//
526// if (ret == -1){
527// printf("syscall %s returned error\n", "SWI_Fstat");
528// state->Reg[0] = ret;
529// return FALSE;
530// }
531//
532// /* copy statbuf to the process memory space
533// FIXME can't say if endian has an effect here */
534// uint32_t offset;
535// //printf("Fstat system is size %x\n", sizeof(statbuf));
536// //printf("Fstat target is size %x\n", sizeof(statret));
537//
538// /* we copy system structure data stat64 into arm fixed size structure target_stat64 */
539// statret.st_dev = statbuf.st_dev;
540// statret.st_ino = statbuf.st_ino;
541// statret.st_mode = statbuf.st_mode;
542// statret.st_nlink = statbuf.st_nlink;
543// statret.st_uid = statbuf.st_uid;
544// statret.st_gid = statbuf.st_gid;
545// statret.st_rdev = statbuf.st_rdev;
546// statret.st_size = statbuf.st_size;
547// statret.st_blksize = statbuf.st_blksize;
548// statret.st_blocks = statbuf.st_blocks;
549// statret.st32_atime = statbuf.st_atime;
550// statret.st32_mtime = statbuf.st_mtime;
551// statret.st32_ctime = statbuf.st_ctime;
552//
553// for (offset = 0; offset < sizeof(statret); offset++) {
554// bus_write(8, dest + offset, *((uint8_t *) &statret + offset));
555// }
556//
557// state->Reg[0] = ret;
558// return TRUE;
559// }
560// case SWI_Set_tls:
561// {
562// //printf("syscall set_tls unimplemented\n");
563// state->mmu.thread_uro_id = state->Reg[0];
564// state->CP15[CP15_THREAD_URO - CP15_BASE] = state->Reg[0];
565// state->Reg[0] = 0;
566// return FALSE;
567// }
568//#if 0
569// case SWI_Clock:
570// /* return number of centi-seconds... */
571// state->Reg[0] =
572//#ifdef CLOCKS_PER_SEC
573// (CLOCKS_PER_SEC >= 100)
574// ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
575// : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
576//#else
577// /* presume unix... clock() returns microseconds */
578// (ARMword) (clock () / 10000);
579//#endif
580// return (TRUE);
581//
582// case SWI_Time:
583// state->Reg[0] = (ARMword) time (NULL);
584// return (TRUE);
585// case SWI_Flen:
586// SWIflen (state, state->Reg[0]);
587// return (TRUE);
588//
589//#endif
590 default:
591
592 _dbg_assert_msg_(ARM11, false, "ImplementMe: ARMul_OSHandleSWI!");
593
594 return (FALSE);
595 }
596}
597//
598///**
599// * @brief For mmap syscall.A mmap_area is a memory bank. Get from ppc.
600// */
601//static mmap_area_t* new_mmap_area(int sim_addr, int len){
602// mmap_area_t *area = (mmap_area_t *)malloc(sizeof(mmap_area_t));
603// if(area == NULL){
604// printf("error, failed %s\n",__FUNCTION__);
605// exit(0);
606// }
607//#if FAST_MEMORY
608// if (mmap_next_base == -1)
609// {
610// mmap_next_base = get_skyeye_exec_info()->brk;
611// }
612//#endif
613//
614// memset(area, 0x0, sizeof(mmap_area_t));
615// area->bank.addr = mmap_next_base;
616// area->bank.len = len;
617// area->bank.bank_write = mmap_mem_write;
618// area->bank.bank_read = mmap_mem_read;
619// area->bank.type = MEMTYPE_RAM;
620// area->bank.objname = "mmap";
621// addr_mapping(&area->bank);
622//
623//#if FAST_MEMORY
624// if (get_skyeye_exec_info()->mmap_access)
625// {
626// /* FIXME check proper flags */
627// /* FIXME we may delete the need of banks up there */
628// uint32_t ret = mmap(mmap_next_base, len, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
629// mmap_next_base = ret;
630// }
631// area->mmap_addr = (uint8_t*)get_dma_addr(mmap_next_base);
632//#else
633// area->mmap_addr = malloc(len);
634// if(area->mmap_addr == NULL){
635// printf("error mmap malloc\n");
636// exit(0);
637// }
638// memset(area->mmap_addr, 0x0, len);
639//#endif
640//
641// area->next = NULL;
642// if(mmap_global){
643// area->next = mmap_global->next;
644// mmap_global->next = area;
645// }else{
646// mmap_global = area;
647// }
648// mmap_next_base = mmap_next_base + len;
649// return area;
650//}
651//
652//static mmap_area_t *get_mmap_area(int addr){
653// mmap_area_t *tmp = mmap_global;
654// while(tmp){
655// if ((tmp->bank.addr <= addr) && (tmp->bank.addr + tmp->bank.len > addr)){
656// return tmp;
657// }
658// tmp = tmp->next;
659// }
660// printf("cannot get mmap area:addr=0x%x\n", addr);
661// return NULL;
662//}
663//
664///**
665// * @brief the mmap_area bank write function. Get from ppc.
666// *
667// * @param size size to write, 8/16/32
668// * @param addr address to write
669// * @param value value to write
670// *
671// * @return sucess return 1,otherwise 0.
672// */
673//static char mmap_mem_write(short size, int addr, uint32_t value){
674// mmap_area_t *area_tmp = get_mmap_area(addr);
675// mem_bank_t *bank_tmp = &area_tmp->bank;
676// int offset = addr - bank_tmp->addr;
677// switch(size){
678// case 8:{
679// //uint8_t value_endian = value;
680// uint8_t value_endian = (uint8_t)value;
681// *(uint8_t *)&(((char *)area_tmp->mmap_addr)[offset]) = value_endian;
682// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,value_endian);
683// break;
684// }
685// case 16:{
686// //uint16_t value_endian = half_to_BE((uint16_t)value);
687// uint16_t value_endian = ((uint16_t)value);
688// *(uint16_t *)&(((char *)area_tmp->mmap_addr)[offset]) = value_endian;
689// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,value_endian);
690// break;
691// }
692// case 32:{
693// //uint32_t value_endian = word_to_BE((uint32_t)value);
694// uint32_t value_endian = ((uint32_t)value);
695// *(uint32_t *)&(((char *)area_tmp->mmap_addr)[offset]) = value_endian;
696// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,value_endian);
697// break;
698// }
699// default:
700// printf("invalid size %d\n",size);
701// return 0;
702// }
703// return 1;
704//}
705//
706///**
707// * @brief the mmap_area bank read function. Get from ppc.
708// *
709// * @param size size to read, 8/16/32
710// * @param addr address to read
711// * @param value value to read
712// *
713// * @return sucess return 1,otherwise 0.
714// */
715//static char mmap_mem_read(short size, int addr, uint32_t * value){
716// mmap_area_t *area_tmp = get_mmap_area(addr);
717// mem_bank_t *bank_tmp = &area_tmp->bank;
718// int offset = addr - bank_tmp->addr;
719// switch(size){
720// case 8:{
721// //*(uint8_t *)value = *(uint8_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]);
722// *value = *(uint8_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]);
723// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,*(uint32_t*)value);
724// break;
725// }
726// case 16:{
727// //*(uint16_t *)value = half_from_BE(*(uint16_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
728// *value = (*(uint16_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
729// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,*(uint16_t*)value);
730// break;
731// }
732// case 32:
733// //*value = (uint32_t)word_from_BE(*(uint32_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
734// *value = (uint32_t)(*(uint32_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
735// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,*(uint32_t*)value);
736// break;
737// default:
738// printf("invalid size %d\n",size);
739// return 0;
740// }
741// return 1;
742//}
diff --git a/src/core/arm/interpreter/armos.h b/src/core/arm/interpreter/armos.h
new file mode 100644
index 000000000..4b58801ad
--- /dev/null
+++ b/src/core/arm/interpreter/armos.h
@@ -0,0 +1,138 @@
1/* armos.h -- ARMulator OS definitions: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18//#include "bank_defs.h"
19//#include "dyncom/defines.h"
20
21//typedef struct mmap_area{
22// mem_bank_t bank;
23// void *mmap_addr;
24// struct mmap_area *next;
25//}mmap_area_t;
26
27#if FAST_MEMORY
28/* in user mode, mmap_base will be on initial brk,
29 set at the first mmap request */
30#define mmap_base -1
31#else
32#define mmap_base 0x50000000
33#endif
34static long mmap_next_base = mmap_base;
35
36//static mmap_area_t* new_mmap_area(int sim_addr, int len);
37static char mmap_mem_write(short size, int addr, uint32_t value);
38static char mmap_mem_read(short size, int addr, uint32_t * value);
39
40/***************************************************************************\
41* SWI numbers *
42\***************************************************************************/
43
44#define SWI_Syscall 0x0
45#define SWI_Exit 0x1
46#define SWI_Read 0x3
47#define SWI_Write 0x4
48#define SWI_Open 0x5
49#define SWI_Close 0x6
50#define SWI_Seek 0x13
51#define SWI_Rename 0x26
52#define SWI_Break 0x11
53
54#define SWI_Times 0x2b
55#define SWI_Brk 0x2d
56
57#define SWI_Mmap 0x5a
58#define SWI_Munmap 0x5b
59#define SWI_Mmap2 0xc0
60
61#define SWI_GetUID32 0xc7
62#define SWI_GetGID32 0xc8
63#define SWI_GetEUID32 0xc9
64#define SWI_GetEGID32 0xca
65
66#define SWI_ExitGroup 0xf8
67
68#if 0
69#define SWI_Time 0xd
70#define SWI_Clock 0x61
71#define SWI_Time 0x63
72#define SWI_Remove 0x64
73#define SWI_Rename 0x65
74#define SWI_Flen 0x6c
75#endif
76
77#define SWI_Uname 0x7a
78#define SWI_Fcntl 0xdd
79#define SWI_Fstat64 0xc5
80#define SWI_Gettimeofday 0x4e
81#define SWI_Set_tls 0xf0005
82
83#define SWI_Breakpoint 0x180000 /* see gdb's tm-arm.h */
84
85/***************************************************************************\
86* SWI structures *
87\***************************************************************************/
88
89/* Arm binaries (for now) only support 32 bit, and expect to receive
90 32-bit compliant structure in return of a systen call. Because
91 we use host system calls to emulate system calls, the returned
92 structure can be 32-bit compliant or 64-bit compliant, depending
93 on the OS running skyeye. Therefore, we need a fixed size structure
94 adapted to arm.*/
95
96/* Borrowed from qemu */
97struct target_stat64 {
98 unsigned short st_dev;
99 unsigned char __pad0[10];
100 uint32_t __st_ino;
101 unsigned int st_mode;
102 unsigned int st_nlink;
103 uint32_t st_uid;
104 uint32_t st_gid;
105 unsigned short st_rdev;
106 unsigned char __pad3[10];
107 unsigned char __pad31[4];
108 long long st_size;
109 uint32_t st_blksize;
110 unsigned char __pad32[4];
111 uint32_t st_blocks;
112 uint32_t __pad4;
113 uint32_t st32_atime;
114 uint32_t __pad5;
115 uint32_t st32_mtime;
116 uint32_t __pad6;
117 uint32_t st32_ctime;
118 uint32_t __pad7;
119 unsigned long long st_ino;
120};// __attribute__((packed));
121
122struct target_tms32 {
123 uint32_t tms_utime;
124 uint32_t tms_stime;
125 uint32_t tms_cutime;
126 uint32_t tms_cstime;
127};
128
129struct target_timeval32 {
130 uint32_t tv_sec; /* seconds */
131 uint32_t tv_usec; /* microseconds */
132};
133
134struct target_timezone32 {
135 int32_t tz_minuteswest; /* minutes west of Greenwich */
136 int32_t tz_dsttime; /* type of DST correction */
137};
138
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
new file mode 100644
index 000000000..a0c866c15
--- /dev/null
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -0,0 +1,954 @@
1/* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18#include "armdefs.h"
19#include "armemu.h"
20//#include "ansidecl.h"
21#include "skyeye_defs.h"
22unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg,
23 unsigned cpnum);
24//extern int skyeye_instr_debug;
25/* Definitions for the support routines. */
26
27static ARMword ModeToBank (ARMword);
28static void EnvokeList (ARMul_State *, unsigned int, unsigned int);
29
30struct EventNode
31{ /* An event list node. */
32 unsigned (*func) (ARMul_State *); /* The function to call. */
33 struct EventNode *next;
34};
35
36/* This routine returns the value of a register from a mode. */
37
38ARMword
39ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg)
40{
41 mode &= MODEBITS;
42 if (mode != state->Mode)
43 return (state->RegBank[ModeToBank ((ARMword) mode)][reg]);
44 else
45 return (state->Reg[reg]);
46}
47
48/* This routine sets the value of a register for a mode. */
49
50void
51ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value)
52{
53 mode &= MODEBITS;
54 if (mode != state->Mode)
55 state->RegBank[ModeToBank ((ARMword) mode)][reg] = value;
56 else
57 state->Reg[reg] = value;
58}
59
60/* This routine returns the value of the PC, mode independently. */
61
62ARMword
63ARMul_GetPC (ARMul_State * state)
64{
65 if (state->Mode > SVC26MODE)
66 return state->Reg[15];
67 else
68 return R15PC;
69}
70
71/* This routine returns the value of the PC, mode independently. */
72
73ARMword
74ARMul_GetNextPC (ARMul_State * state)
75{
76 if (state->Mode > SVC26MODE)
77 return state->Reg[15] + isize;
78 else
79 return (state->Reg[15] + isize) & R15PCBITS;
80}
81
82/* This routine sets the value of the PC. */
83
84void
85ARMul_SetPC (ARMul_State * state, ARMword value)
86{
87 if (ARMul_MODE32BIT)
88 state->Reg[15] = value & PCBITS;
89 else
90 state->Reg[15] = R15CCINTMODE | (value & R15PCBITS);
91 FLUSHPIPE;
92}
93
94/* This routine returns the value of register 15, mode independently. */
95
96ARMword
97ARMul_GetR15 (ARMul_State * state)
98{
99 if (state->Mode > SVC26MODE)
100 return (state->Reg[15]);
101 else
102 return (R15PC | ECC | ER15INT | EMODE);
103}
104
105/* This routine sets the value of Register 15. */
106
107void
108ARMul_SetR15 (ARMul_State * state, ARMword value)
109{
110 if (ARMul_MODE32BIT)
111 state->Reg[15] = value & PCBITS;
112 else {
113 state->Reg[15] = value;
114 ARMul_R15Altered (state);
115 }
116 FLUSHPIPE;
117}
118
119/* This routine returns the value of the CPSR. */
120
121ARMword
122ARMul_GetCPSR (ARMul_State * state)
123{
124 //chy 2003-08-20: below is from gdb20030716, maybe isn't suitable for system simulator
125 //return (CPSR | state->Cpsr); for gdb20030716
126 // NOTE(bunnei): Changed this from [now] commented out macro "CPSR"
127 return ((ECC | EINT | EMODE | (TFLAG << 5))); //had be tested in old skyeye with gdb5.0-5.3
128}
129
130/* This routine sets the value of the CPSR. */
131
132void
133ARMul_SetCPSR (ARMul_State * state, ARMword value)
134{
135 state->Cpsr = value;
136 ARMul_CPSRAltered (state);
137}
138
139/* This routine does all the nasty bits involved in a write to the CPSR,
140 including updating the register bank, given a MSR instruction. */
141
142void
143ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs)
144{
145 state->Cpsr = ARMul_GetCPSR (state);
146 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
147 if (state->Mode != USER26MODE && state->Mode != USER32MODE ) {
148 /* In user mode, only write flags. */
149 if (BIT (16))
150 SETPSR_C (state->Cpsr, rhs);
151 if (BIT (17))
152 SETPSR_X (state->Cpsr, rhs);
153 if (BIT (18))
154 SETPSR_S (state->Cpsr, rhs);
155 }
156 if (BIT (19))
157 SETPSR_F (state->Cpsr, rhs);
158 ARMul_CPSRAltered (state);
159}
160
161/* Get an SPSR from the specified mode. */
162
163ARMword
164ARMul_GetSPSR (ARMul_State * state, ARMword mode)
165{
166 ARMword bank = ModeToBank (mode & MODEBITS);
167
168 if (!BANK_CAN_ACCESS_SPSR (bank))
169 return ARMul_GetCPSR (state);
170
171 return state->Spsr[bank];
172}
173
174/* This routine does a write to an SPSR. */
175
176void
177ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
178{
179 ARMword bank = ModeToBank (mode & MODEBITS);
180
181 if (BANK_CAN_ACCESS_SPSR (bank))
182 state->Spsr[bank] = value;
183}
184
185/* This routine does a write to the current SPSR, given an MSR instruction. */
186
187void
188ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs)
189{
190 if (BANK_CAN_ACCESS_SPSR (state->Bank)) {
191 if (BIT (16))
192 SETPSR_C (state->Spsr[state->Bank], rhs);
193 if (BIT (17))
194 SETPSR_X (state->Spsr[state->Bank], rhs);
195 if (BIT (18))
196 SETPSR_S (state->Spsr[state->Bank], rhs);
197 if (BIT (19))
198 SETPSR_F (state->Spsr[state->Bank], rhs);
199 }
200}
201
202/* This routine updates the state of the emulator after the Cpsr has been
203 changed. Both the processor flags and register bank are updated. */
204
205void
206ARMul_CPSRAltered (ARMul_State * state)
207{
208 ARMword oldmode;
209
210 if (state->prog32Sig == LOW)
211 state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS);
212
213 oldmode = state->Mode;
214
215 if (state->Mode != (state->Cpsr & MODEBITS)) {
216 state->Mode =
217 ARMul_SwitchMode (state, state->Mode,
218 state->Cpsr & MODEBITS);
219
220 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
221 }
222 //state->Cpsr &= ~MODEBITS;
223
224 ASSIGNINT (state->Cpsr & INTBITS);
225 //state->Cpsr &= ~INTBITS;
226 ASSIGNN ((state->Cpsr & NBIT) != 0);
227 //state->Cpsr &= ~NBIT;
228 ASSIGNZ ((state->Cpsr & ZBIT) != 0);
229 //state->Cpsr &= ~ZBIT;
230 ASSIGNC ((state->Cpsr & CBIT) != 0);
231 //state->Cpsr &= ~CBIT;
232 ASSIGNV ((state->Cpsr & VBIT) != 0);
233 //state->Cpsr &= ~VBIT;
234 ASSIGNS ((state->Cpsr & SBIT) != 0);
235 //state->Cpsr &= ~SBIT;
236#ifdef MODET
237 ASSIGNT ((state->Cpsr & TBIT) != 0);
238 //state->Cpsr &= ~TBIT;
239#endif
240
241 if (oldmode > SVC26MODE) {
242 if (state->Mode <= SVC26MODE) {
243 state->Emulate = CHANGEMODE;
244 state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
245 }
246 }
247 else {
248 if (state->Mode > SVC26MODE) {
249 state->Emulate = CHANGEMODE;
250 state->Reg[15] = R15PC;
251 }
252 else
253 state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
254 }
255}
256
257/* This routine updates the state of the emulator after register 15 has
258 been changed. Both the processor flags and register bank are updated.
259 This routine should only be called from a 26 bit mode. */
260
261void
262ARMul_R15Altered (ARMul_State * state)
263{
264 if (state->Mode != R15MODE) {
265 state->Mode = ARMul_SwitchMode (state, state->Mode, R15MODE);
266 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
267 }
268
269 if (state->Mode > SVC26MODE)
270 state->Emulate = CHANGEMODE;
271
272 ASSIGNR15INT (R15INT);
273
274 ASSIGNN ((state->Reg[15] & NBIT) != 0);
275 ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
276 ASSIGNC ((state->Reg[15] & CBIT) != 0);
277 ASSIGNV ((state->Reg[15] & VBIT) != 0);
278}
279
280/* This routine controls the saving and restoring of registers across mode
281 changes. The regbank matrix is largely unused, only rows 13 and 14 are
282 used across all modes, 8 to 14 are used for FIQ, all others use the USER
283 column. It's easier this way. old and new parameter are modes numbers.
284 Notice the side effect of changing the Bank variable. */
285
286ARMword
287ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
288{
289 unsigned i;
290 ARMword oldbank;
291 ARMword newbank;
292 static int revision_value = 53;
293
294 oldbank = ModeToBank (oldmode);
295 newbank = state->Bank = ModeToBank (newmode);
296
297 /* Do we really need to do it? */
298 if (oldbank != newbank) {
299 if (oldbank == 3 && newbank == 2) {
300 //printf("icounter is %d PC is %x MODE CHANGED : %d --> %d\n", state->NumInstrs, state->pc, oldbank, newbank);
301 if (state->NumInstrs >= 5832487) {
302// printf("%d, ", state->NumInstrs + revision_value);
303// printf("revision_value : %d\n", revision_value);
304 revision_value ++;
305 }
306 }
307 /* Save away the old registers. */
308 switch (oldbank) {
309 case USERBANK:
310 case IRQBANK:
311 case SVCBANK:
312 case ABORTBANK:
313 case UNDEFBANK:
314 if (newbank == FIQBANK)
315 for (i = 8; i < 13; i++)
316 state->RegBank[USERBANK][i] =
317 state->Reg[i];
318 state->RegBank[oldbank][13] = state->Reg[13];
319 state->RegBank[oldbank][14] = state->Reg[14];
320 break;
321 case FIQBANK:
322 for (i = 8; i < 15; i++)
323 state->RegBank[FIQBANK][i] = state->Reg[i];
324 break;
325 case DUMMYBANK:
326 for (i = 8; i < 15; i++)
327 state->RegBank[DUMMYBANK][i] = 0;
328 break;
329 default:
330 abort ();
331 }
332
333 /* Restore the new registers. */
334 switch (newbank) {
335 case USERBANK:
336 case IRQBANK:
337 case SVCBANK:
338 case ABORTBANK:
339 case UNDEFBANK:
340 if (oldbank == FIQBANK)
341 for (i = 8; i < 13; i++)
342 state->Reg[i] =
343 state->RegBank[USERBANK][i];
344 state->Reg[13] = state->RegBank[newbank][13];
345 state->Reg[14] = state->RegBank[newbank][14];
346 break;
347 case FIQBANK:
348 for (i = 8; i < 15; i++)
349 state->Reg[i] = state->RegBank[FIQBANK][i];
350 break;
351 case DUMMYBANK:
352 for (i = 8; i < 15; i++)
353 state->Reg[i] = 0;
354 break;
355 default:
356 abort ();
357 }
358 }
359
360 return newmode;
361}
362
363/* Given a processor mode, this routine returns the
364 register bank that will be accessed in that mode. */
365
366static ARMword
367ModeToBank (ARMword mode)
368{
369 static ARMword bankofmode[] = {
370 USERBANK, FIQBANK, IRQBANK, SVCBANK,
371 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
372 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
373 DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
374 USERBANK, FIQBANK, IRQBANK, SVCBANK,
375 DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK,
376 DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK,
377 DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK
378 };
379
380 if (mode >= (sizeof (bankofmode) / sizeof (bankofmode[0])))
381 return DUMMYBANK;
382
383 return bankofmode[mode];
384}
385
386/* Returns the register number of the nth register in a reg list. */
387
388unsigned
389ARMul_NthReg (ARMword instr, unsigned number)
390{
391 unsigned bit, upto;
392
393 for (bit = 0, upto = 0; upto <= number; bit++)
394 if (BIT (bit))
395 upto++;
396
397 return (bit - 1);
398}
399
400/* Assigns the N and Z flags depending on the value of result. */
401
402void
403ARMul_NegZero (ARMul_State * state, ARMword result)
404{
405 if (NEG (result)) {
406 SETN;
407 CLEARZ;
408 }
409 else if (result == 0) {
410 CLEARN;
411 SETZ;
412 }
413 else {
414 CLEARN;
415 CLEARZ;
416 }
417}
418
419/* Compute whether an addition of A and B, giving RESULT, overflowed. */
420
421int
422AddOverflow (ARMword a, ARMword b, ARMword result)
423{
424 return ((NEG (a) && NEG (b) && POS (result))
425 || (POS (a) && POS (b) && NEG (result)));
426}
427
428/* Compute whether a subtraction of A and B, giving RESULT, overflowed. */
429
430int
431SubOverflow (ARMword a, ARMword b, ARMword result)
432{
433 return ((NEG (a) && POS (b) && POS (result))
434 || (POS (a) && NEG (b) && NEG (result)));
435}
436
437/* Assigns the C flag after an addition of a and b to give result. */
438
439void
440ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
441{
442 ASSIGNC ((NEG (a) && NEG (b)) ||
443 (NEG (a) && POS (result)) || (NEG (b) && POS (result)));
444}
445
446/* Assigns the V flag after an addition of a and b to give result. */
447
448void
449ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
450{
451 ASSIGNV (AddOverflow (a, b, result));
452}
453
454/* Assigns the C flag after an subtraction of a and b to give result. */
455
456void
457ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
458{
459 ASSIGNC ((NEG (a) && POS (b)) ||
460 (NEG (a) && POS (result)) || (POS (b) && POS (result)));
461}
462
463/* Assigns the V flag after an subtraction of a and b to give result. */
464
465void
466ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
467{
468 ASSIGNV (SubOverflow (a, b, result));
469}
470
471/* This function does the work of generating the addresses used in an
472 LDC instruction. The code here is always post-indexed, it's up to the
473 caller to get the input address correct and to handle base register
474 modification. It also handles the Busy-Waiting. */
475
476void
477ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address)
478{
479 unsigned cpab;
480 ARMword data;
481
482 UNDEF_LSCPCBaseWb;
483 //printf("SKYEYE ARMul_LDC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address);
484/*chy 2004-05-23 should update this function in the future,should concern dataabort*/
485// chy 2004-05-25 , fix it now,so needn't printf
486// printf("SKYEYE ARMul_LDC, should update this function!!!!!\n");
487 //exit(-1);
488
489 if (!CP_ACCESS_ALLOWED (state, CPNum)) {
490 /*
491 printf
492 ("SKYEYE ARMul_LDC,NOT ALLOW, underinstr, CPnum is %x, instr %x, addr %x\n",
493 CPNum, instr, address);
494 */
495 ARMul_UndefInstr (state, instr);
496 return;
497 }
498
499 if (ADDREXCEPT (address))
500 INTERNALABORT (address);
501
502 cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0);
503 while (cpab == ARMul_BUSY) {
504 ARMul_Icycles (state, 1, 0);
505
506 if (IntPending (state)) {
507 cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT,
508 instr, 0);
509 return;
510 }
511 else
512 cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr,
513 0);
514 }
515 if (cpab == ARMul_CANT) {
516 /*
517 printf
518 ("SKYEYE ARMul_LDC,NOT CAN, underinstr, CPnum is %x, instr %x, addr %x\n",
519 CPNum, instr, address);
520 */
521 CPTAKEABORT;
522 return;
523 }
524
525 cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0);
526 data = ARMul_LoadWordN (state, address);
527 //chy 2004-05-25
528 if (state->abortSig || state->Aborted)
529 goto L_ldc_takeabort;
530
531 BUSUSEDINCPCN;
532//chy 2004-05-25
533/*
534 if (BIT (21))
535 LSBase = state->Base;
536*/
537
538 cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
539
540 while (cpab == ARMul_INC) {
541 address += 4;
542 data = ARMul_LoadWordN (state, address);
543 //chy 2004-05-25
544 if (state->abortSig || state->Aborted)
545 goto L_ldc_takeabort;
546
547 cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
548 }
549
550//chy 2004-05-25
551 L_ldc_takeabort:
552 if (BIT (21)) {
553 if (!
554 ((state->abortSig || state->Aborted)
555 && state->lateabtSig == LOW))
556 LSBase = state->Base;
557 }
558
559 if (state->abortSig || state->Aborted)
560 TAKEABORT;
561}
562
563/* This function does the work of generating the addresses used in an
564 STC instruction. The code here is always post-indexed, it's up to the
565 caller to get the input address correct and to handle base register
566 modification. It also handles the Busy-Waiting. */
567
568void
569ARMul_STC (ARMul_State * state, ARMword instr, ARMword address)
570{
571 unsigned cpab;
572 ARMword data;
573
574 UNDEF_LSCPCBaseWb;
575
576 //printf("SKYEYE ARMul_STC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address);
577 /*chy 2004-05-23 should update this function in the future,should concern dataabort */
578// skyeye_instr_debug=0;printf("SKYEYE debug end!!!!\n");
579// chy 2004-05-25 , fix it now,so needn't printf
580// printf("SKYEYE ARMul_STC, should update this function!!!!!\n");
581
582 //exit(-1);
583 if (!CP_ACCESS_ALLOWED (state, CPNum)) {
584 /*
585 printf
586 ("SKYEYE ARMul_STC,NOT ALLOW, undefinstr, CPnum is %x, instr %x, addr %x\n",
587 CPNum, instr, address);
588 */
589 ARMul_UndefInstr (state, instr);
590 return;
591 }
592
593 if (ADDREXCEPT (address) || VECTORACCESS (address))
594 INTERNALABORT (address);
595
596 cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data);
597 while (cpab == ARMul_BUSY) {
598 ARMul_Icycles (state, 1, 0);
599 if (IntPending (state)) {
600 cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT,
601 instr, 0);
602 return;
603 }
604 else
605 cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr,
606 &data);
607 }
608
609 if (cpab == ARMul_CANT) {
610 /*
611 printf
612 ("SKYEYE ARMul_STC,CANT, undefinstr, CPnum is %x, instr %x, addr %x\n",
613 CPNum, instr, address);
614 */
615 CPTAKEABORT;
616 return;
617 }
618#ifndef MODE32
619 if (ADDREXCEPT (address) || VECTORACCESS (address))
620 INTERNALABORT (address);
621#endif
622 BUSUSEDINCPCN;
623//chy 2004-05-25
624/*
625 if (BIT (21))
626 LSBase = state->Base;
627*/
628 cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
629 ARMul_StoreWordN (state, address, data);
630 //chy 2004-05-25
631 if (state->abortSig || state->Aborted)
632 goto L_stc_takeabort;
633
634 while (cpab == ARMul_INC) {
635 address += 4;
636 cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
637 ARMul_StoreWordN (state, address, data);
638 //chy 2004-05-25
639 if (state->abortSig || state->Aborted)
640 goto L_stc_takeabort;
641 }
642//chy 2004-05-25
643 L_stc_takeabort:
644 if (BIT (21)) {
645 if (!
646 ((state->abortSig || state->Aborted)
647 && state->lateabtSig == LOW))
648 LSBase = state->Base;
649 }
650
651 if (state->abortSig || state->Aborted)
652 TAKEABORT;
653}
654
655/* This function does the Busy-Waiting for an MCR instruction. */
656
657void
658ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
659{
660 unsigned cpab;
661
662 //printf("SKYEYE ARMul_MCR, CPnum is %x, source %x\n",CPNum, source);
663 if (!CP_ACCESS_ALLOWED (state, CPNum)) {
664 //chy 2004-07-19 should fix in the future ????!!!!
665 //printf("SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x\n",CPNum, source);
666 ARMul_UndefInstr (state, instr);
667 return;
668 }
669
670 cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source);
671
672 while (cpab == ARMul_BUSY) {
673 ARMul_Icycles (state, 1, 0);
674
675 if (IntPending (state)) {
676 cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT,
677 instr, 0);
678 return;
679 }
680 else
681 cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr,
682 source);
683 }
684
685 if (cpab == ARMul_CANT) {
686 printf ("SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x\n", instr, CPNum, source);
687 ARMul_Abort (state, ARMul_UndefinedInstrV);
688 }
689 else {
690 BUSUSEDINCPCN;
691 ARMul_Ccycles (state, 1, 0);
692 }
693}
694
695/* This function does the Busy-Waiting for an MCRR instruction. */
696
697void
698ARMul_MCRR (ARMul_State * state, ARMword instr, ARMword source1, ARMword source2)
699{
700 unsigned cpab;
701
702 if (!CP_ACCESS_ALLOWED (state, CPNum)) {
703 ARMul_UndefInstr (state, instr);
704 return;
705 }
706
707 cpab = (state->MCRR[CPNum]) (state, ARMul_FIRST, instr, source1, source2);
708
709 while (cpab == ARMul_BUSY) {
710 ARMul_Icycles (state, 1, 0);
711
712 if (IntPending (state)) {
713 cpab = (state->MCRR[CPNum]) (state, ARMul_INTERRUPT,
714 instr, 0, 0);
715 return;
716 }
717 else
718 cpab = (state->MCRR[CPNum]) (state, ARMul_BUSY, instr,
719 source1, source2);
720 }
721 if (cpab == ARMul_CANT) {
722 printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x, source %x %x\n", __FUNCTION__, CPNum, instr, source1, source2);
723 ARMul_Abort (state, ARMul_UndefinedInstrV);
724 }
725 else {
726 BUSUSEDINCPCN;
727 ARMul_Ccycles (state, 1, 0);
728 }
729}
730
731/* This function does the Busy-Waiting for an MRC instruction. */
732
733ARMword
734ARMul_MRC (ARMul_State * state, ARMword instr)
735{
736 unsigned cpab;
737 ARMword result = 0;
738
739 //printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr);
740 if (!CP_ACCESS_ALLOWED (state, CPNum)) {
741 //chy 2004-07-19 should fix in the future????!!!!
742 //printf("SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x\n",CPNum, instr);
743 ARMul_UndefInstr (state, instr);
744 return -1;
745 }
746
747 cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);
748 while (cpab == ARMul_BUSY) {
749 ARMul_Icycles (state, 1, 0);
750 if (IntPending (state)) {
751 cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT,
752 instr, 0);
753 return (0);
754 }
755 else
756 cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr,
757 &result);
758 }
759 if (cpab == ARMul_CANT) {
760 printf ("SKYEYE ARMul_MRC,CANT UndefInstr CPnum is %x, instr %x\n", CPNum, instr);
761 ARMul_Abort (state, ARMul_UndefinedInstrV);
762 /* Parent will destroy the flags otherwise. */
763 result = ECC;
764 }
765 else {
766 BUSUSEDINCPCN;
767 ARMul_Ccycles (state, 1, 0);
768 ARMul_Icycles (state, 1, 0);
769 }
770
771 return result;
772}
773
774/* This function does the Busy-Waiting for an MRRC instruction. (to verify) */
775
776void
777ARMul_MRRC (ARMul_State * state, ARMword instr, ARMword * dest1, ARMword * dest2)
778{
779 unsigned cpab;
780 ARMword result1 = 0;
781 ARMword result2 = 0;
782
783 if (!CP_ACCESS_ALLOWED (state, CPNum)) {
784 ARMul_UndefInstr (state, instr);
785 return;
786 }
787
788 cpab = (state->MRRC[CPNum]) (state, ARMul_FIRST, instr, &result1, &result2);
789 while (cpab == ARMul_BUSY) {
790 ARMul_Icycles (state, 1, 0);
791 if (IntPending (state)) {
792 cpab = (state->MRRC[CPNum]) (state, ARMul_INTERRUPT,
793 instr, 0, 0);
794 return;
795 }
796 else
797 cpab = (state->MRRC[CPNum]) (state, ARMul_BUSY, instr,
798 &result1, &result2);
799 }
800 if (cpab == ARMul_CANT) {
801 printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x\n", __FUNCTION__, CPNum, instr);
802 ARMul_Abort (state, ARMul_UndefinedInstrV);
803 }
804 else {
805 BUSUSEDINCPCN;
806 ARMul_Ccycles (state, 1, 0);
807 ARMul_Icycles (state, 1, 0);
808 }
809
810 *dest1 = result1;
811 *dest2 = result2;
812}
813
814/* This function does the Busy-Waiting for an CDP instruction. */
815
816void
817ARMul_CDP (ARMul_State * state, ARMword instr)
818{
819 unsigned cpab;
820
821 if (!CP_ACCESS_ALLOWED (state, CPNum)) {
822 ARMul_UndefInstr (state, instr);
823 return;
824 }
825 cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr);
826 while (cpab == ARMul_BUSY) {
827 ARMul_Icycles (state, 1, 0);
828 if (IntPending (state)) {
829 cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT,
830 instr);
831 return;
832 }
833 else
834 cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr);
835 }
836 if (cpab == ARMul_CANT)
837 ARMul_Abort (state, ARMul_UndefinedInstrV);
838 else
839 BUSUSEDN;
840}
841
842/* This function handles Undefined instructions, as CP isntruction. */
843
844void
845ARMul_UndefInstr (ARMul_State * state, ARMword instr)
846{
847 ERROR_LOG(ARM11, "Undefined instruction!! Instr: 0x%x", instr);
848 ARMul_Abort (state, ARMul_UndefinedInstrV);
849}
850
851/* Return TRUE if an interrupt is pending, FALSE otherwise. */
852
853unsigned
854IntPending (ARMul_State * state)
855{
856 /* Any exceptions. */
857 if (state->NresetSig == LOW) {
858 ARMul_Abort (state, ARMul_ResetV);
859 return TRUE;
860 }
861 else if (!state->NfiqSig && !FFLAG) {
862 ARMul_Abort (state, ARMul_FIQV);
863 return TRUE;
864 }
865 else if (!state->NirqSig && !IFLAG) {
866 ARMul_Abort (state, ARMul_IRQV);
867 return TRUE;
868 }
869
870 return FALSE;
871}
872
873/* Align a word access to a non word boundary. */
874
875ARMword
876ARMul_Align (ARMul_State *state, ARMword address, ARMword data)
877{
878 /* This code assumes the address is really unaligned,
879 as a shift by 32 is undefined in C. */
880
881 address = (address & 3) << 3; /* Get the word address. */
882 return ((data >> address) | (data << (32 - address))); /* rot right */
883}
884
885/* This routine is used to call another routine after a certain number of
886 cycles have been executed. The first parameter is the number of cycles
887 delay before the function is called, the second argument is a pointer
888 to the function. A delay of zero doesn't work, just call the function. */
889
890void
891ARMul_ScheduleEvent (ARMul_State * state, unsigned int delay,
892 unsigned (*what) (ARMul_State *))
893{
894 unsigned int when;
895 struct EventNode *event;
896
897 if (state->EventSet++ == 0)
898 state->Now = ARMul_Time (state);
899 when = (state->Now + delay) % EVENTLISTSIZE;
900 event = (struct EventNode *) malloc (sizeof (struct EventNode));
901
902 _dbg_assert_msg_(ARM11, event, "SKYEYE:ARMul_ScheduleEvent: malloc event error\n");
903
904 event->func = what;
905 event->next = *(state->EventPtr + when);
906 *(state->EventPtr + when) = event;
907}
908
909/* This routine is called at the beginning of
910 every cycle, to envoke scheduled events. */
911
912void
913ARMul_EnvokeEvent (ARMul_State * state)
914{
915 static unsigned int then;
916
917 then = state->Now;
918 state->Now = ARMul_Time (state) % EVENTLISTSIZE;
919 if (then < state->Now)
920 /* Schedule events. */
921 EnvokeList (state, then, state->Now);
922 else if (then > state->Now) {
923 /* Need to wrap around the list. */
924 EnvokeList (state, then, EVENTLISTSIZE - 1L);
925 EnvokeList (state, 0L, state->Now);
926 }
927}
928
929/* Envokes all the entries in a range. */
930
931static void
932EnvokeList (ARMul_State * state, unsigned int from, unsigned int to)
933{
934 for (; from <= to; from++) {
935 struct EventNode *anevent;
936
937 anevent = *(state->EventPtr + from);
938 while (anevent) {
939 (anevent->func) (state);
940 state->EventSet--;
941 anevent = anevent->next;
942 }
943 *(state->EventPtr + from) = NULL;
944 }
945}
946
947/* This routine is returns the number of clock ticks since the last reset. */
948
949unsigned int
950ARMul_Time (ARMul_State * state)
951{
952 return (state->NumScycles + state->NumNcycles +
953 state->NumIcycles + state->NumCcycles + state->NumFcycles);
954}
diff --git a/src/core/arm/interpreter/armvirt.cpp b/src/core/arm/interpreter/armvirt.cpp
new file mode 100644
index 000000000..a072b73be
--- /dev/null
+++ b/src/core/arm/interpreter/armvirt.cpp
@@ -0,0 +1,680 @@
1/* armvirt.c -- ARMulator virtual memory interace: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18/* This file contains a complete ARMulator memory model, modelling a
19"virtual memory" system. A much simpler model can be found in armfast.c,
20and that model goes faster too, but has a fixed amount of memory. This
21model's memory has 64K pages, allocated on demand from a 64K entry page
22table. The routines PutWord and GetWord implement this. Pages are never
23freed as they might be needed again. A single area of memory may be
24defined to generate aborts. */
25
26#include "armdefs.h"
27#include "skyeye_defs.h"
28//#include "code_cov.h"
29
30#ifdef VALIDATE /* for running the validate suite */
31#define TUBE 48 * 1024 * 1024 /* write a char on the screen */
32#define ABORTS 1
33#endif
34
35/* #define ABORTS */
36
37#ifdef ABORTS /* the memory system will abort */
38/* For the old test suite Abort between 32 Kbytes and 32 Mbytes
39 For the new test suite Abort between 8 Mbytes and 26 Mbytes */
40/* #define LOWABORT 32 * 1024
41#define HIGHABORT 32 * 1024 * 1024 */
42#define LOWABORT 8 * 1024 * 1024
43#define HIGHABORT 26 * 1024 * 1024
44
45#endif
46
47#define NUMPAGES 64 * 1024
48#define PAGESIZE 64 * 1024
49#define PAGEBITS 16
50#define OFFSETBITS 0xffff
51//chy 2003-08-19: seems no use ????
52int SWI_vector_installed = FALSE;
53extern ARMword skyeye_cachetype;
54
55/***************************************************************************\
56* Get a byte into Virtual Memory, maybe allocating the page *
57\***************************************************************************/
58static fault_t
59GetByte (ARMul_State * state, ARMword address, ARMword * data)
60{
61 fault_t fault;
62
63 fault = mmu_read_byte (state, address, data);
64 if (fault) {
65//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
66// printf("SKYEYE: GetByte fault %d \n", fault);
67 }
68 return fault;
69}
70
71/***************************************************************************\
72* Get a halfword into Virtual Memory, maybe allocating the page *
73\***************************************************************************/
74static fault_t
75GetHalfWord (ARMul_State * state, ARMword address, ARMword * data)
76{
77 fault_t fault;
78
79 fault = mmu_read_halfword (state, address, data);
80 if (fault) {
81//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
82// printf("SKYEYE: GetHalfWord fault %d \n", fault);
83 }
84 return fault;
85}
86
87/***************************************************************************\
88* Get a Word from Virtual Memory, maybe allocating the page *
89\***************************************************************************/
90
91static fault_t
92GetWord (ARMul_State * state, ARMword address, ARMword * data)
93{
94 fault_t fault;
95
96 fault = mmu_read_word (state, address, data);
97 if (fault) {
98//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
99#if 0
100/* XXX */ extern int hack;
101 hack = 1;
102#endif
103#if 0
104 printf ("mmu_read_word at 0x%08x: ", address);
105 switch (fault) {
106 case ALIGNMENT_FAULT:
107 printf ("ALIGNMENT_FAULT");
108 break;
109 case SECTION_TRANSLATION_FAULT:
110 printf ("SECTION_TRANSLATION_FAULT");
111 break;
112 case PAGE_TRANSLATION_FAULT:
113 printf ("PAGE_TRANSLATION_FAULT");
114 break;
115 case SECTION_DOMAIN_FAULT:
116 printf ("SECTION_DOMAIN_FAULT");
117 break;
118 case SECTION_PERMISSION_FAULT:
119 printf ("SECTION_PERMISSION_FAULT");
120 break;
121 case SUBPAGE_PERMISSION_FAULT:
122 printf ("SUBPAGE_PERMISSION_FAULT");
123 break;
124 default:
125 printf ("Unrecognized fault number!");
126 }
127 printf ("\tpc = 0x%08x\n", state->Reg[15]);
128#endif
129 }
130 return fault;
131}
132
133//2003-07-10 chy: lyh change
134/****************************************************************************\
135 * Load a Instrion Word into Virtual Memory *
136\****************************************************************************/
137static fault_t
138LoadInstr (ARMul_State * state, ARMword address, ARMword * instr)
139{
140 fault_t fault;
141 fault = mmu_load_instr (state, address, instr);
142 return fault;
143 //if (fault)
144 // log_msg("load_instr fault = %d, address = %x\n", fault, address);
145}
146
147/***************************************************************************\
148* Put a byte into Virtual Memory, maybe allocating the page *
149\***************************************************************************/
150static fault_t
151PutByte (ARMul_State * state, ARMword address, ARMword data)
152{
153 fault_t fault;
154
155 fault = mmu_write_byte (state, address, data);
156 if (fault) {
157//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
158// printf("SKYEYE: PutByte fault %d \n", fault);
159 }
160 return fault;
161}
162
163/***************************************************************************\
164* Put a halfword into Virtual Memory, maybe allocating the page *
165\***************************************************************************/
166static fault_t
167PutHalfWord (ARMul_State * state, ARMword address, ARMword data)
168{
169 fault_t fault;
170
171 fault = mmu_write_halfword (state, address, data);
172 if (fault) {
173//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
174// printf("SKYEYE: PutHalfWord fault %d \n", fault);
175 }
176 return fault;
177}
178
179/***************************************************************************\
180* Put a Word into Virtual Memory, maybe allocating the page *
181\***************************************************************************/
182
183static fault_t
184PutWord (ARMul_State * state, ARMword address, ARMword data)
185{
186 fault_t fault;
187
188 fault = mmu_write_word (state, address, data);
189 if (fault) {
190//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
191#if 0
192/* XXX */ extern int hack;
193 hack = 1;
194#endif
195#if 0
196 printf ("mmu_write_word at 0x%08x: ", address);
197 switch (fault) {
198 case ALIGNMENT_FAULT:
199 printf ("ALIGNMENT_FAULT");
200 break;
201 case SECTION_TRANSLATION_FAULT:
202 printf ("SECTION_TRANSLATION_FAULT");
203 break;
204 case PAGE_TRANSLATION_FAULT:
205 printf ("PAGE_TRANSLATION_FAULT");
206 break;
207 case SECTION_DOMAIN_FAULT:
208 printf ("SECTION_DOMAIN_FAULT");
209 break;
210 case SECTION_PERMISSION_FAULT:
211 printf ("SECTION_PERMISSION_FAULT");
212 break;
213 case SUBPAGE_PERMISSION_FAULT:
214 printf ("SUBPAGE_PERMISSION_FAULT");
215 break;
216 default:
217 printf ("Unrecognized fault number!");
218 }
219 printf ("\tpc = 0x%08x\n", state->Reg[15]);
220#endif
221 }
222 return fault;
223}
224
225/***************************************************************************\
226* Initialise the memory interface *
227\***************************************************************************/
228
229unsigned
230ARMul_MemoryInit (ARMul_State * state, unsigned int initmemsize)
231{
232 return TRUE;
233}
234
235/***************************************************************************\
236* Remove the memory interface *
237\***************************************************************************/
238
239void
240ARMul_MemoryExit (ARMul_State * state)
241{
242}
243
244/***************************************************************************\
245* ReLoad Instruction *
246\***************************************************************************/
247
248ARMword
249ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize)
250{
251 ARMword data;
252 fault_t fault;
253
254#ifdef ABORTS
255 if (address >= LOWABORT && address < HIGHABORT) {
256 ARMul_PREFETCHABORT (address);
257 return ARMul_ABORTWORD;
258 }
259 else {
260 ARMul_CLEARABORT;
261 }
262#endif
263#if 0
264 /* do profiling for code coverage */
265 if (skyeye_config.code_cov.prof_on)
266 cov_prof(EXEC_FLAG, address);
267#endif
268#if 1
269 if ((isize == 2) && (address & 0x2)) {
270 ARMword lo, hi;
271 if (!(skyeye_cachetype == INSTCACHE))
272 fault = GetHalfWord (state, address, &lo);
273 else
274 fault = LoadInstr (state, address, &lo);
275#if 0
276 if (!fault) {
277 if (!(skyeye_cachetype == INSTCACHE))
278 fault = GetHalfWord (state, address + isize, &hi);
279 else
280 fault = LoadInstr (state, address + isize, &hi);
281
282 }
283#endif
284 if (fault) {
285 ARMul_PREFETCHABORT (address);
286 return ARMul_ABORTWORD;
287 }
288 else {
289 ARMul_CLEARABORT;
290 }
291 return lo;
292#if 0
293 if (state->bigendSig == HIGH)
294 return (lo << 16) | (hi >> 16);
295 else
296 return ((hi & 0xFFFF) << 16) | (lo >> 16);
297#endif
298 }
299#endif
300 if (!(skyeye_cachetype == INSTCACHE))
301 fault = GetWord (state, address, &data);
302 else
303 fault = LoadInstr (state, address, &data);
304
305 if (fault) {
306
307 /* dyf add for s3c6410 no instcache temporary 2010.9.17 */
308 if (!(skyeye_cachetype == INSTCACHE)) {
309 /* set translation fault on prefetch abort */
310 state->mmu.fault_statusi = fault & 0xFF;
311 state->mmu.fault_address = address;
312 }
313 /* add end */
314
315 ARMul_PREFETCHABORT (address);
316 return ARMul_ABORTWORD;
317 }
318 else {
319 ARMul_CLEARABORT;
320 }
321
322 return data;
323}
324
325/***************************************************************************\
326* Load Instruction, Sequential Cycle *
327\***************************************************************************/
328
329ARMword
330ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize)
331{
332 state->NumScycles++;
333
334#ifdef HOURGLASS
335 if ((state->NumScycles & HOURGLASS_RATE) == 0) {
336 HOURGLASS;
337 }
338#endif
339
340 return ARMul_ReLoadInstr (state, address, isize);
341}
342
343/***************************************************************************\
344* Load Instruction, Non Sequential Cycle *
345\***************************************************************************/
346
347ARMword
348ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
349{
350 state->NumNcycles++;
351
352 return ARMul_ReLoadInstr (state, address, isize);
353}
354
355/***************************************************************************\
356* Read Word (but don't tell anyone!) *
357\***************************************************************************/
358
359ARMword
360ARMul_ReadWord (ARMul_State * state, ARMword address)
361{
362 ARMword data;
363 fault_t fault;
364
365#ifdef ABORTS
366 if (address >= LOWABORT && address < HIGHABORT) {
367 ARMul_DATAABORT (address);
368 return ARMul_ABORTWORD;
369 }
370 else {
371 ARMul_CLEARABORT;
372 }
373#endif
374
375 fault = GetWord (state, address, &data);
376 if (fault) {
377 state->mmu.fault_status =
378 (fault | (state->mmu.last_domain << 4)) & 0xFF;
379 state->mmu.fault_address = address;
380 ARMul_DATAABORT (address);
381 return ARMul_ABORTWORD;
382 }
383 else {
384 ARMul_CLEARABORT;
385 }
386 return data;
387}
388
389/***************************************************************************\
390* Load Word, Sequential Cycle *
391\***************************************************************************/
392
393ARMword
394ARMul_LoadWordS (ARMul_State * state, ARMword address)
395{
396 state->NumScycles++;
397
398 return ARMul_ReadWord (state, address);
399}
400
401/***************************************************************************\
402* Load Word, Non Sequential Cycle *
403\***************************************************************************/
404
405ARMword
406ARMul_LoadWordN (ARMul_State * state, ARMword address)
407{
408 state->NumNcycles++;
409
410 return ARMul_ReadWord (state, address);
411}
412
413/***************************************************************************\
414* Load Halfword, (Non Sequential Cycle) *
415\***************************************************************************/
416
417ARMword
418ARMul_LoadHalfWord (ARMul_State * state, ARMword address)
419{
420 ARMword data;
421 fault_t fault;
422
423 state->NumNcycles++;
424 fault = GetHalfWord (state, address, &data);
425
426 if (fault) {
427 state->mmu.fault_status =
428 (fault | (state->mmu.last_domain << 4)) & 0xFF;
429 state->mmu.fault_address = address;
430 ARMul_DATAABORT (address);
431 return ARMul_ABORTWORD;
432 }
433 else {
434 ARMul_CLEARABORT;
435 }
436
437 return data;
438
439}
440
441/***************************************************************************\
442* Read Byte (but don't tell anyone!) *
443\***************************************************************************/
444int ARMul_ICE_ReadByte(ARMul_State * state, ARMword address, ARMword *presult)
445{
446 ARMword data;
447 fault_t fault;
448 fault = GetByte (state, address, &data);
449 if (fault) {
450 *presult=-1; fault=ALIGNMENT_FAULT; return fault;
451 }else{
452 *(char *)presult=(unsigned char)(data & 0xff); fault=NO_FAULT; return fault;
453 }
454}
455
456
457ARMword
458ARMul_ReadByte (ARMul_State * state, ARMword address)
459{
460 ARMword data;
461 fault_t fault;
462
463 fault = GetByte (state, address, &data);
464
465 if (fault) {
466 state->mmu.fault_status =
467 (fault | (state->mmu.last_domain << 4)) & 0xFF;
468 state->mmu.fault_address = address;
469 ARMul_DATAABORT (address);
470 return ARMul_ABORTWORD;
471 }
472 else {
473 ARMul_CLEARABORT;
474 }
475
476 return data;
477
478}
479
480/***************************************************************************\
481* Load Byte, (Non Sequential Cycle) *
482\***************************************************************************/
483
484ARMword
485ARMul_LoadByte (ARMul_State * state, ARMword address)
486{
487 state->NumNcycles++;
488
489 return ARMul_ReadByte (state, address);
490}
491
492/***************************************************************************\
493* Write Word (but don't tell anyone!) *
494\***************************************************************************/
495
496void
497ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data)
498{
499 fault_t fault;
500
501#ifdef ABORTS
502 if (address >= LOWABORT && address < HIGHABORT) {
503 ARMul_DATAABORT (address);
504 return;
505 }
506 else {
507 ARMul_CLEARABORT;
508 }
509#endif
510
511 fault = PutWord (state, address, data);
512 if (fault) {
513 state->mmu.fault_status =
514 (fault | (state->mmu.last_domain << 4)) & 0xFF;
515 state->mmu.fault_address = address;
516 ARMul_DATAABORT (address);
517 return;
518 }
519 else {
520 ARMul_CLEARABORT;
521 }
522}
523
524/***************************************************************************\
525* Store Word, Sequential Cycle *
526\***************************************************************************/
527
528void
529ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data)
530{
531 state->NumScycles++;
532
533 ARMul_WriteWord (state, address, data);
534}
535
536/***************************************************************************\
537* Store Word, Non Sequential Cycle *
538\***************************************************************************/
539
540void
541ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data)
542{
543 state->NumNcycles++;
544
545 ARMul_WriteWord (state, address, data);
546}
547
548/***************************************************************************\
549* Store HalfWord, (Non Sequential Cycle) *
550\***************************************************************************/
551
552void
553ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data)
554{
555 fault_t fault;
556 state->NumNcycles++;
557 fault = PutHalfWord (state, address, data);
558 if (fault) {
559 state->mmu.fault_status =
560 (fault | (state->mmu.last_domain << 4)) & 0xFF;
561 state->mmu.fault_address = address;
562 ARMul_DATAABORT (address);
563 return;
564 }
565 else {
566 ARMul_CLEARABORT;
567 }
568}
569
570//chy 2006-04-15
571int ARMul_ICE_WriteByte (ARMul_State * state, ARMword address, ARMword data)
572{
573 fault_t fault;
574 fault = PutByte (state, address, data);
575 if (fault)
576 return 1;
577 else
578 return 0;
579}
580/***************************************************************************\
581* Write Byte (but don't tell anyone!) *
582\***************************************************************************/
583//chy 2003-07-10, add real write byte fun
584void
585ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data)
586{
587 fault_t fault;
588 fault = PutByte (state, address, data);
589 if (fault) {
590 state->mmu.fault_status =
591 (fault | (state->mmu.last_domain << 4)) & 0xFF;
592 state->mmu.fault_address = address;
593 ARMul_DATAABORT (address);
594 return;
595 }
596 else {
597 ARMul_CLEARABORT;
598 }
599}
600
601/***************************************************************************\
602* Store Byte, (Non Sequential Cycle) *
603\***************************************************************************/
604
605void
606ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data)
607{
608 state->NumNcycles++;
609
610#ifdef VALIDATE
611 if (address == TUBE) {
612 if (data == 4)
613 state->Emulate = FALSE;
614 else
615 (void) putc ((char) data, stderr); /* Write Char */
616 return;
617 }
618#endif
619
620 ARMul_WriteByte (state, address, data);
621}
622
623/***************************************************************************\
624* Swap Word, (Two Non Sequential Cycles) *
625\***************************************************************************/
626
627ARMword
628ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data)
629{
630 ARMword temp;
631
632 state->NumNcycles++;
633
634 temp = ARMul_ReadWord (state, address);
635
636 state->NumNcycles++;
637
638 PutWord (state, address, data);
639
640 return temp;
641}
642
643/***************************************************************************\
644* Swap Byte, (Two Non Sequential Cycles) *
645\***************************************************************************/
646
647ARMword
648ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data)
649{
650 ARMword temp;
651
652 temp = ARMul_LoadByte (state, address);
653 ARMul_StoreByte (state, address, data);
654
655 return temp;
656}
657
658/***************************************************************************\
659* Count I Cycles *
660\***************************************************************************/
661
662void
663ARMul_Icycles (ARMul_State * state, unsigned number,
664 ARMword address)
665{
666 state->NumIcycles += number;
667 ARMul_CLEARABORT;
668}
669
670/***************************************************************************\
671* Count C Cycles *
672\***************************************************************************/
673
674void
675ARMul_Ccycles (ARMul_State * state, unsigned number,
676 ARMword address)
677{
678 state->NumCcycles += number;
679 ARMul_CLEARABORT;
680}
diff --git a/src/core/arm/interpreter/skyeye_defs.h b/src/core/arm/interpreter/skyeye_defs.h
new file mode 100644
index 000000000..6562e595a
--- /dev/null
+++ b/src/core/arm/interpreter/skyeye_defs.h
@@ -0,0 +1,111 @@
1#ifndef CORE_ARM_SKYEYE_DEFS_H_
2#define CORE_ARM_SKYEYE_DEFS_H_
3
4#include "common.h"
5
6#define MODE32
7#define MODET
8
9typedef struct
10{
11 const char *cpu_arch_name; /*cpu architecture version name.e.g. armv4t */
12 const char *cpu_name; /*cpu name. e.g. arm7tdmi or arm720t */
13 u32 cpu_val; /*CPU value; also call MMU ID or processor id;see
14 ARM Architecture Reference Manual B2-6 */
15 u32 cpu_mask; /*cpu_val's mask. */
16 u32 cachetype; /*this cpu has what kind of cache */
17} cpu_config_t;
18
19typedef struct conf_object_s{
20 char* objname;
21 void* obj;
22 char* class_name;
23}conf_object_t;
24
25typedef enum{
26 /* No exception */
27 No_exp = 0,
28 /* Memory allocation exception */
29 Malloc_exp,
30 /* File open exception */
31 File_open_exp,
32 /* DLL open exception */
33 Dll_open_exp,
34 /* Invalid argument exception */
35 Invarg_exp,
36 /* Invalid module exception */
37 Invmod_exp,
38 /* wrong format exception for config file parsing */
39 Conf_format_exp,
40 /* some reference excess the predefiend range. Such as the index out of array range */
41 Excess_range_exp,
42 /* Can not find the desirable result */
43 Not_found_exp,
44
45 /* Unknown exception */
46 Unknown_exp
47}exception_t;
48
49typedef enum {
50 Align = 0,
51 UnAlign
52}align_t;
53
54typedef enum {
55 Little_endian = 0,
56 Big_endian
57}endian_t;
58//typedef int exception_t;
59
60typedef enum{
61 Phys_addr = 0,
62 Virt_addr
63}addr_type_t;
64
65typedef exception_t(*read_byte_t)(conf_object_t* target, u32 addr, void *buf, size_t count);
66typedef exception_t(*write_byte_t)(conf_object_t* target, u32 addr, const void *buf, size_t count);
67
68typedef struct memory_space{
69 conf_object_t* conf_obj;
70 read_byte_t read;
71 write_byte_t write;
72}memory_space_intf;
73
74
75/*
76 * a running instance for a specific archteciture.
77 */
78typedef struct generic_arch_s
79{
80 char* arch_name;
81 void (*init) (void);
82 void (*reset) (void);
83 void (*step_once) (void);
84 void (*set_pc)(u32 addr);
85 u32 (*get_pc)(void);
86 u32 (*get_step)(void);
87 //chy 2004-04-15
88 //int (*ICE_write_byte) (u32 addr, uint8_t v);
89 //int (*ICE_read_byte)(u32 addr, uint8_t *pv);
90 u32 (*get_regval_by_id)(int id);
91 u32 (*get_regnum)(void);
92 char* (*get_regname_by_id)(int id);
93 exception_t (*set_regval_by_id)(int id, u32 value);
94 /*
95 * read a data by virtual address.
96 */
97 exception_t (*mmu_read)(short size, u32 addr, u32 * value);
98 /*
99 * write a data by a virtual address.
100 */
101 exception_t (*mmu_write)(short size, u32 addr, u32 value);
102 /**
103 * get a signal from external
104 */
105 //exception_t (*signal)(interrupt_signal_t* signal);
106
107 endian_t endianess;
108 align_t alignment;
109} generic_arch_t;
110
111#endif \ No newline at end of file
diff --git a/src/core/arm/interpreter/thumbemu.cpp b/src/core/arm/interpreter/thumbemu.cpp
new file mode 100644
index 000000000..032d84b65
--- /dev/null
+++ b/src/core/arm/interpreter/thumbemu.cpp
@@ -0,0 +1,513 @@
1/* thumbemu.c -- Thumb instruction emulation.
2 Copyright (C) 1996, Cygnus Software Technologies Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18/* We can provide simple Thumb simulation by decoding the Thumb
19instruction into its corresponding ARM instruction, and using the
20existing ARM simulator. */
21
22#include "skyeye_defs.h"
23
24#ifndef MODET /* required for the Thumb instruction support */
25#if 1
26#error "MODET needs to be defined for the Thumb world to work"
27#else
28#define MODET (1)
29#endif
30#endif
31
32#include "armdefs.h"
33#include "armemu.h"
34#include "armos.h"
35
36
37/* Decode a 16bit Thumb instruction. The instruction is in the low
38 16-bits of the tinstr field, with the following Thumb instruction
39 held in the high 16-bits. Passing in two Thumb instructions allows
40 easier simulation of the special dual BL instruction. */
41
42tdstate
43ARMul_ThumbDecode (
44 ARMul_State *state,
45 ARMword pc,
46 ARMword tinstr,
47 ARMword *ainstr)
48{
49 tdstate valid = t_decoded; /* default assumes a valid instruction */
50 ARMword next_instr;
51
52 if (state->bigendSig) {
53 next_instr = tinstr & 0xFFFF;
54 tinstr >>= 16;
55 }
56 else {
57 next_instr = tinstr >> 16;
58 tinstr &= 0xFFFF;
59 }
60
61#if 1 /* debugging to catch non updates */
62 *ainstr = 0xDEADC0DE;
63#endif
64
65 switch ((tinstr & 0xF800) >> 11) {
66 case 0: /* LSL */
67 case 1: /* LSR */
68 case 2: /* ASR */
69 /* Format 1 */
70 *ainstr = 0xE1B00000 /* base opcode */
71 | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */
72 |((tinstr & 0x07C0) << (7 - 6)) /* imm5 */
73 |((tinstr & 0x0038) >> 3) /* Rs */
74 |((tinstr & 0x0007) << 12); /* Rd */
75 break;
76 case 3: /* ADD/SUB */
77 /* Format 2 */
78 {
79 ARMword subset[4] = {
80 0xE0900000, /* ADDS Rd,Rs,Rn */
81 0xE0500000, /* SUBS Rd,Rs,Rn */
82 0xE2900000, /* ADDS Rd,Rs,#imm3 */
83 0xE2500000 /* SUBS Rd,Rs,#imm3 */
84 };
85 /* It is quicker indexing into a table, than performing switch
86 or conditionals: */
87 *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */
88 |((tinstr & 0x01C0) >> 6) /* Rn or imm3 */
89 |((tinstr & 0x0038) << (16 - 3)) /* Rs */
90 |((tinstr & 0x0007) << (12 - 0)); /* Rd */
91 }
92 break;
93 case 4: /* MOV */
94 case 5: /* CMP */
95 case 6: /* ADD */
96 case 7: /* SUB */
97 /* Format 3 */
98 {
99 ARMword subset[4] = {
100 0xE3B00000, /* MOVS Rd,#imm8 */
101 0xE3500000, /* CMP Rd,#imm8 */
102 0xE2900000, /* ADDS Rd,Rd,#imm8 */
103 0xE2500000, /* SUBS Rd,Rd,#imm8 */
104 };
105 *ainstr = subset[(tinstr & 0x1800) >> 11] /* base opcode */
106 |((tinstr & 0x00FF) >> 0) /* imm8 */
107 |((tinstr & 0x0700) << (16 - 8)) /* Rn */
108 |((tinstr & 0x0700) << (12 - 8)); /* Rd */
109 }
110 break;
111 case 8: /* Arithmetic and high register transfers */
112 /* TODO: Since the subsets for both Format 4 and Format 5
113 instructions are made up of different ARM encodings, we could
114 save the following conditional, and just have one large
115 subset. */
116 if ((tinstr & (1 << 10)) == 0) {
117 /* Format 4 */
118 enum OpcodeType { t_norm, t_shift, t_neg, t_mul };
119 struct ThumbOpcode {
120 ARMword opcode;
121 OpcodeType otype;
122 };
123
124 ThumbOpcode subset[16] = {
125 {
126 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */
127 {
128 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */
129 {
130 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */
131 {
132 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */
133 {
134 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */
135 {
136 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */
137 {
138 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */
139 {
140 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */
141 {
142 0xE1100000, t_norm}, /* TST Rd,Rs */
143 {
144 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */
145 {
146 0xE1500000, t_norm}, /* CMP Rd,Rs */
147 {
148 0xE1700000, t_norm}, /* CMN Rd,Rs */
149 {
150 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */
151 {
152 0xE0100090, t_mul}, /* MULS Rd,Rd,Rs */
153 {
154 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */
155 {
156 0xE1F00000, t_norm} /* MVNS Rd,Rs */
157 };
158 *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
159 switch (subset[(tinstr & 0x03C0) >> 6].otype) {
160 case t_norm:
161 *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */
162 |((tinstr & 0x0007) << 12) /* Rd */
163 |((tinstr & 0x0038) >> 3); /* Rs */
164 break;
165 case t_shift:
166 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
167 |((tinstr & 0x0007) >> 0) /* Rm */
168 |((tinstr & 0x0038) << (8 - 3)); /* Rs */
169 break;
170 case t_neg:
171 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
172 |((tinstr & 0x0038) << (16 - 3)); /* Rn */
173 break;
174 case t_mul:
175 *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */
176 |((tinstr & 0x0007) << 8) /* Rs */
177 |((tinstr & 0x0038) >> 3); /* Rm */
178 break;
179 }
180 }
181 else {
182 /* Format 5 */
183 ARMword Rd = ((tinstr & 0x0007) >> 0);
184 ARMword Rs = ((tinstr & 0x0038) >> 3);
185 if (tinstr & (1 << 7))
186 Rd += 8;
187 if (tinstr & (1 << 6))
188 Rs += 8;
189 switch ((tinstr & 0x03C0) >> 6) {
190 case 0x1: /* ADD Rd,Rd,Hs */
191 case 0x2: /* ADD Hd,Hd,Rs */
192 case 0x3: /* ADD Hd,Hd,Hs */
193 *ainstr = 0xE0800000 /* base */
194 | (Rd << 16) /* Rn */
195 |(Rd << 12) /* Rd */
196 |(Rs << 0); /* Rm */
197 break;
198 case 0x5: /* CMP Rd,Hs */
199 case 0x6: /* CMP Hd,Rs */
200 case 0x7: /* CMP Hd,Hs */
201 *ainstr = 0xE1500000 /* base */
202 | (Rd << 16) /* Rn */
203 |(Rd << 12) /* Rd */
204 |(Rs << 0); /* Rm */
205 break;
206 case 0x9: /* MOV Rd,Hs */
207 case 0xA: /* MOV Hd,Rs */
208 case 0xB: /* MOV Hd,Hs */
209 *ainstr = 0xE1A00000 /* base */
210 | (Rd << 16) /* Rn */
211 |(Rd << 12) /* Rd */
212 |(Rs << 0); /* Rm */
213 break;
214 case 0xC: /* BX Rs */
215 case 0xD: /* BX Hs */
216 *ainstr = 0xE12FFF10 /* base */
217 | ((tinstr & 0x0078) >> 3); /* Rd */
218 break;
219 case 0x0: /* UNDEFINED */
220 case 0x4: /* UNDEFINED */
221 case 0x8: /* UNDEFINED */
222 valid = t_undefined;
223 break;
224 case 0xE: /* BLX */
225 case 0xF: /* BLX */
226 if (state->is_v5) {
227 *ainstr = 0xE1200030 /* base */
228 |(Rs << 0); /* Rm */
229 } else {
230 valid = t_undefined;
231 }
232 break;
233 }
234 }
235 break;
236 case 9: /* LDR Rd,[PC,#imm8] */
237 /* Format 6 */
238 *ainstr = 0xE59F0000 /* base */
239 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
240 |((tinstr & 0x00FF) << (2 - 0)); /* off8 */
241 break;
242 case 10:
243 case 11:
244 /* TODO: Format 7 and Format 8 perform the same ARM encoding, so
245 the following could be merged into a single subset, saving on
246 the following boolean: */
247 if ((tinstr & (1 << 9)) == 0) {
248 /* Format 7 */
249 ARMword subset[4] = {
250 0xE7800000, /* STR Rd,[Rb,Ro] */
251 0xE7C00000, /* STRB Rd,[Rb,Ro] */
252 0xE7900000, /* LDR Rd,[Rb,Ro] */
253 0xE7D00000 /* LDRB Rd,[Rb,Ro] */
254 };
255 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
256 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
257 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
258 |((tinstr & 0x01C0) >> 6); /* Ro */
259 }
260 else {
261 /* Format 8 */
262 ARMword subset[4] = {
263 0xE18000B0, /* STRH Rd,[Rb,Ro] */
264 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */
265 0xE19000B0, /* LDRH Rd,[Rb,Ro] */
266 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */
267 };
268 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
269 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
270 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
271 |((tinstr & 0x01C0) >> 6); /* Ro */
272 }
273 break;
274 case 12: /* STR Rd,[Rb,#imm5] */
275 case 13: /* LDR Rd,[Rb,#imm5] */
276 case 14: /* STRB Rd,[Rb,#imm5] */
277 case 15: /* LDRB Rd,[Rb,#imm5] */
278 /* Format 9 */
279 {
280 ARMword subset[4] = {
281 0xE5800000, /* STR Rd,[Rb,#imm5] */
282 0xE5900000, /* LDR Rd,[Rb,#imm5] */
283 0xE5C00000, /* STRB Rd,[Rb,#imm5] */
284 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */
285 };
286 /* The offset range defends on whether we are transferring a
287 byte or word value: */
288 *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */
289 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
290 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
291 |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */
292 }
293 break;
294 case 16: /* STRH Rd,[Rb,#imm5] */
295 case 17: /* LDRH Rd,[Rb,#imm5] */
296 /* Format 10 */
297 *ainstr = ((tinstr & (1 << 11)) /* base */
298 ? 0xE1D000B0 /* LDRH */
299 : 0xE1C000B0) /* STRH */
300 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
301 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
302 |((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */
303 |((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */
304 break;
305 case 18: /* STR Rd,[SP,#imm8] */
306 case 19: /* LDR Rd,[SP,#imm8] */
307 /* Format 11 */
308 *ainstr = ((tinstr & (1 << 11)) /* base */
309 ? 0xE59D0000 /* LDR */
310 : 0xE58D0000) /* STR */
311 |((tinstr & 0x0700) << (12 - 8)) /* Rd */
312 |((tinstr & 0x00FF) << 2); /* off8 */
313 break;
314 case 20: /* ADD Rd,PC,#imm8 */
315 case 21: /* ADD Rd,SP,#imm8 */
316 /* Format 12 */
317 if ((tinstr & (1 << 11)) == 0) {
318 /* NOTE: The PC value used here should by word aligned */
319 /* We encode shift-left-by-2 in the rotate immediate field,
320 so no shift of off8 is needed. */
321 *ainstr = 0xE28F0F00 /* base */
322 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
323 |(tinstr & 0x00FF); /* off8 */
324 }
325 else {
326 /* We encode shift-left-by-2 in the rotate immediate field,
327 so no shift of off8 is needed. */
328 *ainstr = 0xE28D0F00 /* base */
329 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
330 |(tinstr & 0x00FF); /* off8 */
331 }
332 break;
333 case 22:
334 case 23:
335 if ((tinstr & 0x0F00) == 0x0000) {
336 /* Format 13 */
337 /* NOTE: The instruction contains a shift left of 2
338 equivalent (implemented as ROR #30): */
339 *ainstr = ((tinstr & (1 << 7)) /* base */
340 ? 0xE24DDF00 /* SUB */
341 : 0xE28DDF00) /* ADD */
342 |(tinstr & 0x007F); /* off7 */
343 }
344 else if ((tinstr & 0x0F00) == 0x0e00)
345 *ainstr = 0xEF000000 | SWI_Breakpoint;
346 else {
347 /* Format 14 */
348 ARMword subset[4] = {
349 0xE92D0000, /* STMDB sp!,{rlist} */
350 0xE92D4000, /* STMDB sp!,{rlist,lr} */
351 0xE8BD0000, /* LDMIA sp!,{rlist} */
352 0xE8BD8000 /* LDMIA sp!,{rlist,pc} */
353 };
354 *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] /* base */
355 |(tinstr & 0x00FF); /* mask8 */
356 }
357 break;
358 case 24: /* STMIA */
359 case 25: /* LDMIA */
360 /* Format 15 */
361 *ainstr = ((tinstr & (1 << 11)) /* base */
362 ? 0xE8B00000 /* LDMIA */
363 : 0xE8A00000) /* STMIA */
364 |((tinstr & 0x0700) << (16 - 8)) /* Rb */
365 |(tinstr & 0x00FF); /* mask8 */
366 break;
367 case 26: /* Bcc */
368 case 27: /* Bcc/SWI */
369 if ((tinstr & 0x0F00) == 0x0F00) {
370 if (tinstr == (ARMul_ABORTWORD & 0xffff) &&
371 state->AbortAddr == pc) {
372 *ainstr = ARMul_ABORTWORD;
373 break;
374 }
375 /* Format 17 : SWI */
376 *ainstr = 0xEF000000;
377 /* Breakpoint must be handled specially. */
378 if ((tinstr & 0x00FF) == 0x18)
379 *ainstr |= ((tinstr & 0x00FF) << 16);
380 /* New breakpoint value. See gdb/arm-tdep.c */
381 else if ((tinstr & 0x00FF) == 0xFE)
382 *ainstr |= SWI_Breakpoint;
383 else
384 *ainstr |= (tinstr & 0x00FF);
385 }
386 else if ((tinstr & 0x0F00) != 0x0E00) {
387 /* Format 16 */
388 int doit = FALSE;
389 /* TODO: Since we are doing a switch here, we could just add
390 the SWI and undefined instruction checks into this
391 switch to same on a couple of conditionals: */
392 switch ((tinstr & 0x0F00) >> 8) {
393 case EQ:
394 doit = ZFLAG;
395 break;
396 case NE:
397 doit = !ZFLAG;
398 break;
399 case VS:
400 doit = VFLAG;
401 break;
402 case VC:
403 doit = !VFLAG;
404 break;
405 case MI:
406 doit = NFLAG;
407 break;
408 case PL:
409 doit = !NFLAG;
410 break;
411 case CS:
412 doit = CFLAG;
413 break;
414 case CC:
415 doit = !CFLAG;
416 break;
417 case HI:
418 doit = (CFLAG && !ZFLAG);
419 break;
420 case LS:
421 doit = (!CFLAG || ZFLAG);
422 break;
423 case GE:
424 doit = ((!NFLAG && !VFLAG)
425 || (NFLAG && VFLAG));
426 break;
427 case LT:
428 doit = ((NFLAG && !VFLAG)
429 || (!NFLAG && VFLAG));
430 break;
431 case GT:
432 doit = ((!NFLAG && !VFLAG && !ZFLAG)
433 || (NFLAG && VFLAG && !ZFLAG));
434 break;
435 case LE:
436 doit = ((NFLAG && !VFLAG)
437 || (!NFLAG && VFLAG)) || ZFLAG;
438 break;
439 }
440 if (doit) {
441 state->Reg[15] = (pc + 4
442 + (((tinstr & 0x7F) << 1)
443 | ((tinstr & (1 << 7)) ?
444 0xFFFFFF00 : 0)));
445 FLUSHPIPE;
446 }
447 valid = t_branch;
448 }
449 else /* UNDEFINED : cc=1110(AL) uses different format */
450 valid = t_undefined;
451 break;
452 case 28: /* B */
453 /* Format 18 */
454 state->Reg[15] = (pc + 4 + (((tinstr & 0x3FF) << 1)
455 | ((tinstr & (1 << 10)) ?
456 0xFFFFF800 : 0)));
457 FLUSHPIPE;
458 valid = t_branch;
459 break;
460 case 29:
461 if(tinstr & 0x1)
462 valid = t_undefined;
463 else{
464 /* BLX 1 for armv5t and above */
465 ARMword tmp = (pc + 2);
466 state->Reg[15] =
467 (state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC;
468 state->Reg[14] = (tmp | 1);
469 CLEART;
470 DEBUG_LOG(ARM11, "In %s, After BLX(1),LR=0x%x,PC=0x%x, offset=0x%x\n", __FUNCTION__, state->Reg[14], state->Reg[15], (tinstr &0x7FF) << 1);
471 valid = t_branch;
472 FLUSHPIPE;
473 }
474 break;
475 case 30: /* BL instruction 1 */
476 /* Format 19 */
477 /* There is no single ARM instruction equivalent for this Thumb
478 instruction. To keep the simulation simple (from the user
479 perspective) we check if the following instruction is the
480 second half of this BL, and if it is we simulate it
481 immediately. */
482 state->Reg[14] = state->Reg[15]
483 + (((tinstr & 0x07FF) << 12)
484 | ((tinstr & (1 << 10)) ? 0xFF800000 : 0));
485 valid = t_branch; /* in-case we don't have the 2nd half */
486 //tinstr = next_instr; /* move the instruction down */
487 //if (((tinstr & 0xF800) >> 11) != 31)
488 // break; /* exit, since not correct instruction */
489 /* else we fall through to process the second half of the BL */
490 //pc += 2; /* point the pc at the 2nd half */
491 state->Reg[15] = pc + 2;
492 FLUSHPIPE;
493 break;
494 case 31: /* BL instruction 2 */
495 /* Format 19 */
496 /* There is no single ARM instruction equivalent for this
497 instruction. Also, it should only ever be matched with the
498 fmt19 "BL instruction 1" instruction. However, we do allow
499 the simulation of it on its own, with undefined results if
500 r14 is not suitably initialised. */
501 {
502 ARMword tmp = (pc + 2);
503 state->Reg[15] =
504 (state->Reg[14] + ((tinstr & 0x07FF) << 1));
505 state->Reg[14] = (tmp | 1);
506 valid = t_branch;
507 FLUSHPIPE;
508 }
509 break;
510 }
511
512 return valid;
513}