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