summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/citra_qt/debugger/disassembler.cpp2
-rw-r--r--src/core/CMakeLists.txt57
-rw-r--r--src/core/arm/dyncom/arm_dyncom.cpp163
-rw-r--r--src/core/arm/dyncom/arm_dyncom.h90
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.cpp402
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.h155
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp6563
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.h7
-rw-r--r--src/core/arm/dyncom/arm_dyncom_run.cpp120
-rw-r--r--src/core/arm/dyncom/arm_dyncom_run.h55
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.cpp521
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.h51
-rw-r--r--src/core/arm/interpreter/arm_interpreter.cpp5
-rw-r--r--src/core/arm/interpreter/arm_interpreter.h6
-rw-r--r--src/core/arm/interpreter/armcopro.cpp1007
-rw-r--r--src/core/arm/interpreter/armemu.cpp9
-rw-r--r--src/core/arm/interpreter/arminit.cpp4
-rw-r--r--src/core/arm/interpreter/armmmu.cpp238
-rw-r--r--src/core/arm/interpreter/armos.cpp742
-rw-r--r--src/core/arm/interpreter/armsupp.cpp15
-rw-r--r--src/core/arm/interpreter/armvirt.cpp685
-rw-r--r--src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.cpp1132
-rw-r--r--src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.h37
-rw-r--r--src/core/arm/interpreter/mmu/cache.cpp370
-rw-r--r--src/core/arm/interpreter/mmu/cache.h168
-rw-r--r--src/core/arm/interpreter/mmu/maverick.cpp1206
-rw-r--r--src/core/arm/interpreter/mmu/rb.cpp126
-rw-r--r--src/core/arm/interpreter/mmu/rb.h55
-rw-r--r--src/core/arm/interpreter/mmu/sa_mmu.cpp864
-rw-r--r--src/core/arm/interpreter/mmu/sa_mmu.h58
-rw-r--r--src/core/arm/interpreter/mmu/tlb.cpp307
-rw-r--r--src/core/arm/interpreter/mmu/tlb.h87
-rw-r--r--src/core/arm/interpreter/mmu/wb.cpp149
-rw-r--r--src/core/arm/interpreter/mmu/wb.h63
-rw-r--r--src/core/arm/interpreter/mmu/xscale_copro.cpp1391
-rw-r--r--src/core/arm/interpreter/thumbemu.cpp8
-rw-r--r--src/core/arm/skyeye_common/arm_regformat.h (renamed from src/core/arm/interpreter/arm_regformat.h)4
-rw-r--r--src/core/arm/skyeye_common/armcpu.h (renamed from src/core/arm/interpreter/armcpu.h)5
-rw-r--r--src/core/arm/skyeye_common/armdefs.h (renamed from src/core/arm/interpreter/armdefs.h)5
-rw-r--r--src/core/arm/skyeye_common/armemu.h (renamed from src/core/arm/interpreter/armemu.h)2
-rw-r--r--src/core/arm/skyeye_common/armmmu.h (renamed from src/core/arm/interpreter/armmmu.h)117
-rw-r--r--src/core/arm/skyeye_common/armos.h (renamed from src/core/arm/interpreter/armos.h)9
-rw-r--r--src/core/arm/skyeye_common/skyeye_defs.h (renamed from src/core/arm/interpreter/skyeye_defs.h)4
-rw-r--r--src/core/arm/skyeye_common/skyeye_types.h55
-rw-r--r--src/core/arm/skyeye_common/vfp/asm_vfp.h (renamed from src/core/arm/interpreter/vfp/asm_vfp.h)0
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.cpp (renamed from src/core/arm/interpreter/vfp/vfp.cpp)32
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.h (renamed from src/core/arm/interpreter/vfp/vfp.h)2
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp_helper.h (renamed from src/core/arm/interpreter/vfp/vfp_helper.h)2
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpdouble.cpp (renamed from src/core/arm/interpreter/vfp/vfpdouble.cpp)6
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpinstr.cpp (renamed from src/core/arm/interpreter/vfp/vfpinstr.cpp)48
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpsingle.cpp (renamed from src/core/arm/interpreter/vfp/vfpsingle.cpp)6
-rw-r--r--src/core/core.h2
-rw-r--r--src/core/hle/coprocessor.h20
53 files changed, 8616 insertions, 8621 deletions
diff --git a/src/citra_qt/debugger/disassembler.cpp b/src/citra_qt/debugger/disassembler.cpp
index 856baf63d..2ee877743 100644
--- a/src/citra_qt/debugger/disassembler.cpp
+++ b/src/citra_qt/debugger/disassembler.cpp
@@ -9,7 +9,7 @@
9#include "core/core.h" 9#include "core/core.h"
10#include "common/break_points.h" 10#include "common/break_points.h"
11#include "common/symbols.h" 11#include "common/symbols.h"
12#include "core/arm/interpreter/armdefs.h" 12#include "core/arm/skyeye_common/armdefs.h"
13#include "core/arm/disassembler/arm_disasm.h" 13#include "core/arm/disassembler/arm_disasm.h"
14 14
15DisassemblerModel::DisassemblerModel(QObject* parent) : QAbstractItemModel(parent), base_address(0), code_size(0), program_counter(0), selection(QModelIndex()) { 15DisassemblerModel::DisassemblerModel(QObject* parent) : QAbstractItemModel(parent), base_address(0), code_size(0), program_counter(0), selection(QModelIndex()) {
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 06df9a677..aefbe3375 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -1,27 +1,22 @@
1set(SRCS 1set(SRCS
2 arm/disassembler/arm_disasm.cpp 2 arm/disassembler/arm_disasm.cpp
3 arm/disassembler/load_symbol_map.cpp 3 arm/disassembler/load_symbol_map.cpp
4 arm/interpreter/mmu/arm1176jzf_s_mmu.cpp 4 arm/dyncom/arm_dyncom.cpp
5 arm/interpreter/mmu/cache.cpp 5 arm/dyncom/arm_dyncom_dec.cpp
6 arm/interpreter/mmu/maverick.cpp 6 arm/dyncom/arm_dyncom_interpreter.cpp
7 arm/interpreter/mmu/rb.cpp 7 arm/dyncom/arm_dyncom_run.cpp
8 arm/interpreter/mmu/sa_mmu.cpp 8 arm/dyncom/arm_dyncom_thumb.cpp
9 arm/interpreter/mmu/tlb.cpp
10 arm/interpreter/mmu/wb.cpp
11 arm/interpreter/mmu/xscale_copro.cpp
12 arm/interpreter/vfp/vfp.cpp
13 arm/interpreter/vfp/vfpdouble.cpp
14 arm/interpreter/vfp/vfpinstr.cpp
15 arm/interpreter/vfp/vfpsingle.cpp
16 arm/interpreter/arm_interpreter.cpp 9 arm/interpreter/arm_interpreter.cpp
17 arm/interpreter/armcopro.cpp 10 arm/interpreter/armcopro.cpp
18 arm/interpreter/armemu.cpp 11 arm/interpreter/armemu.cpp
19 arm/interpreter/arminit.cpp 12 arm/interpreter/arminit.cpp
20 arm/interpreter/armmmu.cpp
21 arm/interpreter/armos.cpp
22 arm/interpreter/armsupp.cpp 13 arm/interpreter/armsupp.cpp
23 arm/interpreter/armvirt.cpp 14 arm/interpreter/armvirt.cpp
24 arm/interpreter/thumbemu.cpp 15 arm/interpreter/thumbemu.cpp
16 arm/skyeye_common/vfp/vfp.cpp
17 arm/skyeye_common/vfp/vfpdouble.cpp
18 arm/skyeye_common/vfp/vfpinstr.cpp
19 arm/skyeye_common/vfp/vfpsingle.cpp
25 file_sys/archive_romfs.cpp 20 file_sys/archive_romfs.cpp
26 file_sys/archive_sdmc.cpp 21 file_sys/archive_sdmc.cpp
27 file_sys/file_romfs.cpp 22 file_sys/file_romfs.cpp
@@ -43,7 +38,6 @@ set(SRCS
43 hle/service/service.cpp 38 hle/service/service.cpp
44 hle/service/srv.cpp 39 hle/service/srv.cpp
45 hle/config_mem.cpp 40 hle/config_mem.cpp
46 hle/coprocessor.cpp
47 hle/hle.cpp 41 hle/hle.cpp
48 hle/svc.cpp 42 hle/svc.cpp
49 hw/gpu.cpp 43 hw/gpu.cpp
@@ -63,23 +57,23 @@ set(SRCS
63set(HEADERS 57set(HEADERS
64 arm/disassembler/arm_disasm.h 58 arm/disassembler/arm_disasm.h
65 arm/disassembler/load_symbol_map.h 59 arm/disassembler/load_symbol_map.h
66 arm/interpreter/mmu/arm1176jzf_s_mmu.h 60 arm/dyncom/arm_dyncom.h
67 arm/interpreter/mmu/cache.h 61 arm/dyncom/arm_dyncom_dec.h
68 arm/interpreter/mmu/rb.h 62 arm/dyncom/arm_dyncom_interpreter.h
69 arm/interpreter/mmu/sa_mmu.h 63 arm/dyncom/arm_dyncom_run.h
70 arm/interpreter/mmu/tlb.h 64 arm/dyncom/arm_dyncom_thumb.h
71 arm/interpreter/mmu/wb.h
72 arm/interpreter/vfp/asm_vfp.h
73 arm/interpreter/vfp/vfp.h
74 arm/interpreter/vfp/vfp_helper.h
75 arm/interpreter/arm_interpreter.h 65 arm/interpreter/arm_interpreter.h
76 arm/interpreter/arm_regformat.h 66 arm/skyeye_common/arm_regformat.h
77 arm/interpreter/armcpu.h 67 arm/skyeye_common/armcpu.h
78 arm/interpreter/armdefs.h 68 arm/skyeye_common/armdefs.h
79 arm/interpreter/armemu.h 69 arm/skyeye_common/armemu.h
80 arm/interpreter/armmmu.h 70 arm/skyeye_common/armmmu.h
81 arm/interpreter/armos.h 71 arm/skyeye_common/armos.h
82 arm/interpreter/skyeye_defs.h 72 arm/skyeye_common/skyeye_defs.h
73 arm/skyeye_common/skyeye_types.h
74 arm/skyeye_common/vfp/asm_vfp.h
75 arm/skyeye_common/vfp/vfp.h
76 arm/skyeye_common/vfp/vfp_helper.h
83 arm/arm_interface.h 77 arm/arm_interface.h
84 file_sys/archive.h 78 file_sys/archive.h
85 file_sys/archive_romfs.h 79 file_sys/archive_romfs.h
@@ -105,7 +99,6 @@ set(HEADERS
105 hle/service/service.h 99 hle/service/service.h
106 hle/service/srv.h 100 hle/service/srv.h
107 hle/config_mem.h 101 hle/config_mem.h
108 hle/coprocessor.h
109 hle/function_wrappers.h 102 hle/function_wrappers.h
110 hle/hle.h 103 hle/hle.h
111 hle/svc.h 104 hle/svc.h
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp
new file mode 100644
index 000000000..669b612fc
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom.cpp
@@ -0,0 +1,163 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#include "core/arm/skyeye_common/armcpu.h"
6#include "core/arm/skyeye_common/armemu.h"
7#include "core/arm/skyeye_common/vfp/vfp.h"
8
9#include "core/arm/dyncom/arm_dyncom.h"
10#include "core/arm/dyncom/arm_dyncom_interpreter.h"
11
12const static cpu_config_t s_arm11_cpu_info = {
13 "armv6", "arm11", 0x0007b000, 0x0007f000, NONCACHE
14};
15
16ARM_DynCom::ARM_DynCom() : ticks(0) {
17 state = std::unique_ptr<ARMul_State>(new ARMul_State);
18
19 ARMul_EmulateInit();
20 memset(state.get(), 0, sizeof(ARMul_State));
21
22 ARMul_NewState((ARMul_State*)state.get());
23
24 state->abort_model = 0;
25 state->cpu = (cpu_config_t*)&s_arm11_cpu_info;
26 state->bigendSig = LOW;
27
28 ARMul_SelectProcessor(state.get(), ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop);
29 state->lateabtSig = LOW;
30
31 // Reset the core to initial state
32 ARMul_CoProInit(state.get());
33 ARMul_Reset(state.get());
34 state->NextInstr = RESUME; // NOTE: This will be overwritten by LoadContext
35 state->Emulate = 3;
36
37 state->pc = state->Reg[15] = 0x00000000;
38 state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
39 state->servaddr = 0xFFFF0000;
40 state->NirqSig = HIGH;
41
42 VFPInit(state.get()); // Initialize the VFP
43
44 ARMul_EmulateInit();
45}
46
47ARM_DynCom::~ARM_DynCom() {
48}
49
50/**
51 * Set the Program Counter to an address
52 * @param addr Address to set PC to
53 */
54void ARM_DynCom::SetPC(u32 pc) {
55 state->pc = state->Reg[15] = pc;
56}
57
58/*
59 * Get the current Program Counter
60 * @return Returns current PC
61 */
62u32 ARM_DynCom::GetPC() const {
63 return state->pc;
64}
65
66/**
67 * Get an ARM register
68 * @param index Register index (0-15)
69 * @return Returns the value in the register
70 */
71u32 ARM_DynCom::GetReg(int index) const {
72 return state->Reg[index];
73}
74
75/**
76 * Set an ARM register
77 * @param index Register index (0-15)
78 * @param value Value to set register to
79 */
80void ARM_DynCom::SetReg(int index, u32 value) {
81 state->Reg[index] = value;
82}
83
84/**
85 * Get the current CPSR register
86 * @return Returns the value of the CPSR register
87 */
88u32 ARM_DynCom::GetCPSR() const {
89 return state->Cpsr;
90}
91
92/**
93 * Set the current CPSR register
94 * @param cpsr Value to set CPSR to
95 */
96void ARM_DynCom::SetCPSR(u32 cpsr) {
97 state->Cpsr = cpsr;
98}
99
100/**
101 * Returns the number of clock ticks since the last reset
102 * @return Returns number of clock ticks
103 */
104u64 ARM_DynCom::GetTicks() const {
105 return ticks;
106}
107
108/**
109 * Executes the given number of instructions
110 * @param num_instructions Number of instructions to executes
111 */
112void ARM_DynCom::ExecuteInstructions(int num_instructions) {
113 ticks += num_instructions;
114 state->NumInstrsToExecute = num_instructions;
115 InterpreterMainLoop(state.get());
116}
117
118/**
119 * Saves the current CPU context
120 * @param ctx Thread context to save
121 * @todo Do we need to save Reg[15] and NextInstr?
122 */
123void ARM_DynCom::SaveContext(ThreadContext& ctx) {
124 memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers));
125 memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers));
126
127 ctx.sp = state->Reg[13];
128 ctx.lr = state->Reg[14];
129 ctx.pc = state->pc;
130 ctx.cpsr = state->Cpsr;
131
132 ctx.fpscr = state->VFP[1];
133 ctx.fpexc = state->VFP[2];
134
135 ctx.reg_15 = state->Reg[15];
136 ctx.mode = state->NextInstr;
137}
138
139/**
140 * Loads a CPU context
141 * @param ctx Thread context to load
142 * @param Do we need to load Reg[15] and NextInstr?
143 */
144void ARM_DynCom::LoadContext(const ThreadContext& ctx) {
145 memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
146 memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
147
148 state->Reg[13] = ctx.sp;
149 state->Reg[14] = ctx.lr;
150 state->pc = ctx.pc;
151 state->Cpsr = ctx.cpsr;
152
153 state->VFP[1] = ctx.fpscr;
154 state->VFP[2] = ctx.fpexc;
155
156 state->Reg[15] = ctx.reg_15;
157 state->NextInstr = ctx.mode;
158}
159
160/// Prepare core for thread reschedule (if needed to correctly handle state)
161void ARM_DynCom::PrepareReschedule() {
162 state->NumInstrsToExecute = 0;
163}
diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h
new file mode 100644
index 000000000..9f88dd139
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom.h
@@ -0,0 +1,90 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8
9#include "common/common_types.h"
10
11#include "core/arm/arm_interface.h"
12#include "core/arm/skyeye_common/armdefs.h"
13
14class ARM_DynCom final : virtual public ARM_Interface {
15public:
16
17 ARM_DynCom();
18 ~ARM_DynCom();
19
20 /**
21 * Set the Program Counter to an address
22 * @param addr Address to set PC to
23 */
24 void SetPC(u32 pc);
25
26 /*
27 * Get the current Program Counter
28 * @return Returns current PC
29 */
30 u32 GetPC() const;
31
32 /**
33 * Get an ARM register
34 * @param index Register index (0-15)
35 * @return Returns the value in the register
36 */
37 u32 GetReg(int index) const;
38
39 /**
40 * Set an ARM register
41 * @param index Register index (0-15)
42 * @param value Value to set register to
43 */
44 void SetReg(int index, u32 value);
45
46 /**
47 * Get the current CPSR register
48 * @return Returns the value of the CPSR register
49 */
50 u32 GetCPSR() const;
51
52 /**
53 * Set the current CPSR register
54 * @param cpsr Value to set CPSR to
55 */
56 void SetCPSR(u32 cpsr);
57
58 /**
59 * Returns the number of clock ticks since the last reset
60 * @return Returns number of clock ticks
61 */
62 u64 GetTicks() const;
63
64 /**
65 * Saves the current CPU context
66 * @param ctx Thread context to save
67 */
68 void SaveContext(ThreadContext& ctx);
69
70 /**
71 * Loads a CPU context
72 * @param ctx Thread context to load
73 */
74 void LoadContext(const ThreadContext& ctx);
75
76 /// Prepare core for thread reschedule (if needed to correctly handle state)
77 void PrepareReschedule();
78
79 /**
80 * Executes the given number of instructions
81 * @param num_instructions Number of instructions to executes
82 */
83 void ExecuteInstructions(int num_instructions);
84
85private:
86
87 std::unique_ptr<ARMul_State> state;
88 u64 ticks;
89
90};
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp
new file mode 100644
index 000000000..5d174a08f
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp
@@ -0,0 +1,402 @@
1/* Copyright (C)
2* 2012 - Michael.Kang blackfin.kang@gmail.com
3* This program is free software; you can redistribute it and/or
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18/**
19* @file arm_dyncom_dec.cpp
20* @brief Some common utility for arm decoder
21* @author Michael.Kang blackfin.kang@gmail.com
22* @version 7849
23* @date 2012-03-15
24*/
25
26#include "core/arm/skyeye_common/arm_regformat.h"
27#include "core/arm/skyeye_common/armdefs.h"
28#include "core/arm/dyncom/arm_dyncom_dec.h"
29
30const ISEITEM arm_instruction[] = {
31 #define VFP_DECODE
32 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
33 #undef VFP_DECODE
34 {"srs" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005},
35 {"rfe" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a},
36 {"bkpt" , 2 , 3 , 20, 31, 0x00000e12, 4, 7, 0x00000007},
37 {"blx" , 1 , 3 , 25, 31, 0x0000007d},
38 {"cps" , 3 , 6 , 20, 31, 0x00000f10, 16, 16, 0x00000000, 5, 5, 0x00000000},
39 {"pld" , 4 , 4 , 26, 31, 0x0000003d, 24, 24, 0x00000001, 20, 22, 0x00000005, 12, 15, 0x0000000f},
40 {"setend" , 2 , 6 , 16, 31, 0x0000f101, 4, 7, 0x00000000},
41 {"clrex" , 1 , 6 , 0, 31, 0xf57ff01f},
42 {"rev16" , 2 , 6 , 16, 27, 0x000006bf, 4, 11, 0x000000fb},
43 {"usad8" , 3 , 6 , 20, 27, 0x00000078, 12, 15, 0x0000000f, 4, 7, 0x00000001},
44 {"sxtb" , 2 , 6 , 16, 27, 0x000006af, 4, 7, 0x00000007},
45 {"uxtb" , 2 , 6 , 16, 27, 0x000006ef, 4, 7, 0x00000007},
46 {"sxth" , 2 , 6 , 16, 27, 0x000006bf, 4, 7, 0x00000007},
47 {"sxtb16" , 2 , 6 , 16, 27, 0x0000068f, 4, 7, 0x00000007},
48 {"uxth" , 2 , 6 , 16, 27, 0x000006ff, 4, 7, 0x00000007},
49 {"uxtb16" , 2 , 6 , 16, 27, 0x000006cf, 4, 7, 0x00000007},
50 {"cpy" , 2 , 6 , 20, 27, 0x0000001a, 4, 11, 0x00000000},
51 {"uxtab" , 2 , 6 , 20, 27, 0x0000006e, 4, 9, 0x00000007},
52 {"ssub8" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x0000000f},
53 {"shsub8" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x0000000f},
54 {"ssubaddx" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000005},
55 {"strex" , 2 , 6 , 20, 27, 0x00000018, 4, 7, 0x00000009},
56 {"strexb" , 2 , 7 , 20, 27, 0x0000001c, 4, 7, 0x00000009},
57 {"swp" , 2 , 0 , 20, 27, 0x00000010, 4, 7, 0x00000009},
58 {"swpb" , 2 , 0 , 20, 27, 0x00000014, 4, 7, 0x00000009},
59 {"ssub16" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000007},
60 {"ssat16" , 2 , 6 , 20, 27, 0x0000006a, 4, 7, 0x00000003},
61 {"shsubaddx" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000005},
62 {"qsubaddx" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000005},
63 {"shaddsubx" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000003},
64 {"shadd8" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000009},
65 {"shadd16" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000001},
66 {"sel" , 2 , 6 , 20, 27, 0x00000068, 4, 7, 0x0000000b},
67 {"saddsubx" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000003},
68 {"sadd8" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000009},
69 {"sadd16" , 2 , 6 , 20, 27, 0x00000061, 4, 7, 0x00000001},
70 {"shsub16" , 2 , 6 , 20, 27, 0x00000063, 4, 7, 0x00000007},
71 {"umaal" , 2 , 6 , 20, 27, 0x00000004, 4, 7, 0x00000009},
72 {"uxtab16" , 2 , 6 , 20, 27, 0x0000006c, 4, 7, 0x00000007},
73 {"usubaddx" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000005},
74 {"usub8" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x0000000f},
75 {"usub16" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000007},
76 {"usat16" , 2 , 6 , 20, 27, 0x0000006e, 4, 7, 0x00000003},
77 {"usada8" , 2 , 6 , 20, 27, 0x00000078, 4, 7, 0x00000001},
78 {"uqsubaddx" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000005},
79 {"uqsub8" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x0000000f},
80 {"uqsub16" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000007},
81 {"uqaddsubx" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000003},
82 {"uqadd8" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000009},
83 {"uqadd16" , 2 , 6 , 20, 27, 0x00000066, 4, 7, 0x00000001},
84 {"sxtab" , 2 , 6 , 20, 27, 0x0000006a, 4, 7, 0x00000007},
85 {"uhsubaddx" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000005},
86 {"uhsub8" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x0000000f},
87 {"uhsub16" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000007},
88 {"uhaddsubx" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000003},
89 {"uhadd8" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000009},
90 {"uhadd16" , 2 , 6 , 20, 27, 0x00000067, 4, 7, 0x00000001},
91 {"uaddsubx" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000003},
92 {"uadd8" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000009},
93 {"uadd16" , 2 , 6 , 20, 27, 0x00000065, 4, 7, 0x00000001},
94 {"sxtah" , 2 , 6 , 20, 27, 0x0000006b, 4, 7, 0x00000007},
95 {"sxtab16" , 2 , 6 , 20, 27, 0x00000068, 4, 7, 0x00000007},
96 {"qadd8" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000009},
97 {"bxj" , 2 , 5 , 20, 27, 0x00000012, 4, 7, 0x00000002},
98 {"clz" , 2 , 3 , 20, 27, 0x00000016, 4, 7, 0x00000001},
99 {"uxtah" , 2 , 6 , 20, 27, 0x0000006f, 4, 7, 0x00000007},
100 {"bx" , 2 , 2 , 20, 27, 0x00000012, 4, 7, 0x00000001},
101 {"rev" , 2 , 6 , 20, 27, 0x0000006b, 4, 7, 0x00000003},
102 {"blx" , 2 , 3 , 20, 27, 0x00000012, 4, 7, 0x00000003},
103 {"revsh" , 2 , 6 , 20, 27, 0x0000006f, 4, 7, 0x0000000b},
104 {"qadd" , 2 , 4 , 20, 27, 0x00000010, 4, 7, 0x00000005},
105 {"qadd16" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000001},
106 {"qaddsubx" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000003},
107 {"ldrex" , 2 , 0 , 20, 27, 0x00000019, 4, 7, 0x00000009},
108 {"qdadd" , 2 , 4 , 20, 27, 0x00000014, 4, 7, 0x00000005},
109 {"qdsub" , 2 , 4 , 20, 27, 0x00000016, 4, 7, 0x00000005},
110 {"qsub" , 2 , 4 , 20, 27, 0x00000012, 4, 7, 0x00000005},
111 {"ldrexb" , 2 , 7 , 20, 27, 0x0000001d, 4, 7, 0x00000009},
112 {"qsub8" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x0000000f},
113 {"qsub16" , 2 , 6 , 20, 27, 0x00000062, 4, 7, 0x00000007},
114 {"smuad" , 4 , 6 , 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001},
115 {"smmul" , 4 , 6 , 20, 27, 0x00000075, 12, 15, 0x0000000f, 6, 7, 0x00000000, 4, 4, 0x00000001},
116 {"smusd" , 4 , 6 , 20, 27, 0x00000070, 12, 15, 0x0000000f, 6, 7, 0x00000001, 4, 4, 0x00000001},
117 {"smlsd" , 3 , 6 , 20, 27, 0x00000070, 6, 7, 0x00000001, 4, 4, 0x00000001},
118 {"smlsld" , 3 , 6 , 20, 27, 0x00000074, 6, 7, 0x00000001, 4, 4, 0x00000001},
119 {"smmla" , 3 , 6 , 20, 27, 0x00000075, 6, 7, 0x00000000, 4, 4, 0x00000001},
120 {"smmls" , 3 , 6 , 20, 27, 0x00000075, 6, 7, 0x00000003, 4, 4, 0x00000001},
121 {"smlald" , 3 , 6 , 20, 27, 0x00000074, 6, 7, 0x00000000, 4, 4, 0x00000001},
122 {"smlad" , 3 , 6 , 20, 27, 0x00000070, 6, 7, 0x00000000, 4, 4, 0x00000001},
123 {"smlaw" , 3 , 4 , 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000000},
124 {"smulw" , 3 , 4 , 20, 27, 0x00000012, 7, 7, 0x00000001, 4, 5, 0x00000002},
125 {"pkhtb" , 2 , 6 , 20, 27, 0x00000068, 4, 6, 0x00000005},
126 {"pkhbt" , 2 , 6 , 20, 27, 0x00000068, 4, 6, 0x00000001},
127 {"smul" , 3 , 4 , 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000},
128 {"smlalxy" , 3 , 4 , 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000},
129// {"smlal" , 2 , 4 , 21, 27, 0x00000007, 4, 7, 0x00000009},
130 {"smla" , 3 , 4 , 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000},
131 {"mcrr" , 1 , 6 , 20, 27, 0x000000c4},
132 {"mrrc" , 1 , 6 , 20, 27, 0x000000c5},
133 {"cmp" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000015},
134 {"tst" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000011},
135 {"teq" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000013},
136 {"cmn" , 2 , 0 , 26, 27, 0x00000000, 20, 24, 0x00000017},
137 {"smull" , 2 , 0 , 21, 27, 0x00000006, 4, 7, 0x00000009},
138 {"umull" , 2 , 0 , 21, 27, 0x00000004, 4, 7, 0x00000009},
139 {"umlal" , 2 , 0 , 21, 27, 0x00000005, 4, 7, 0x00000009},
140 {"smlal" , 2 , 0 , 21, 27, 0x00000007, 4, 7, 0x00000009},
141 {"mul" , 2 , 0 , 21, 27, 0x00000000, 4, 7, 0x00000009},
142 {"mla" , 2 , 0 , 21, 27, 0x00000001, 4, 7, 0x00000009},
143 {"ssat" , 2 , 6 , 21, 27, 0x00000035, 4, 5, 0x00000001},
144 {"usat" , 2 , 6 , 21, 27, 0x00000037, 4, 5, 0x00000001},
145 {"mrs" , 4 , 0 , 23, 27, 0x00000002, 20, 21, 0x00000000, 16, 19, 0x0000000f, 0, 11, 0x00000000},
146 {"msr" , 3 , 0 , 23, 27, 0x00000002, 20, 21, 0x00000002, 4, 7, 0x00000000},
147 {"and" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000000},
148 {"bic" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000e},
149 {"ldm" , 3 , 0 , 25, 27, 0x00000004, 20, 22, 0x00000005, 15, 15, 0x00000000},
150 {"eor" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000001},
151 {"add" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000004},
152 {"rsb" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000003},
153 {"rsc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000007},
154 {"sbc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000006},
155 {"adc" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000005},
156 {"sub" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x00000002},
157 {"orr" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000c},
158 {"mvn" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000f},
159 {"mov" , 2 , 0 , 26, 27, 0x00000000, 21, 24, 0x0000000d},
160 {"stm" , 2 , 0 , 25, 27, 0x00000004, 20, 22, 0x00000004},
161 {"ldm" , 4 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000001, 20, 20, 0x00000001, 15, 15, 0x00000001},
162 {"ldrsh" , 3 , 2 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000f},
163 {"stm" , 3 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000000},
164 {"ldm" , 3 , 0 , 25, 27, 0x00000004, 22, 22, 0x00000000, 20, 20, 0x00000001},
165 {"ldrsb" , 3 , 2 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000d},
166 {"strd" , 3 , 4 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000f},
167 {"ldrh" , 3 , 0 , 25, 27, 0x00000000, 20, 20, 0x00000001, 4, 7, 0x0000000b},
168 {"strh" , 3 , 0 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000b},
169 {"ldrd" , 3 , 4 , 25, 27, 0x00000000, 20, 20, 0x00000000, 4, 7, 0x0000000d},
170 {"strt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000002},
171 {"strbt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000006},
172 {"ldrbt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000007},
173 {"ldrt" , 3 , 0 , 26, 27, 0x00000001, 24, 24, 0x00000000, 20, 22, 0x00000003},
174 {"mrc" , 3 , 6 , 24, 27, 0x0000000e, 20, 20, 0x00000001, 4, 4, 0x00000001},
175 {"mcr" , 3 , 0 , 24, 27, 0x0000000e, 20, 20, 0x00000000, 4, 4, 0x00000001},
176 {"msr" , 2 , 0 , 23, 27, 0x00000006, 20, 21, 0x00000002},
177 {"ldrb" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000001},
178 {"strb" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000001, 20, 20, 0x00000000},
179 {"ldr" , 4 , 0 , 28, 31, 0x0000000e, 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001},
180 {"ldrcond" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000001},
181 {"str" , 3 , 0 , 26, 27, 0x00000001, 22, 22, 0x00000000, 20, 20, 0x00000000},
182 {"cdp" , 2 , 0 , 24, 27, 0x0000000e, 4, 4, 0x00000000},
183 {"stc" , 2 , 0 , 25, 27, 0x00000006, 20, 20, 0x00000000},
184 {"ldc" , 2 , 0 , 25, 27, 0x00000006, 20, 20, 0x00000001},
185 {"swi" , 1 , 0 , 24, 27, 0x0000000f},
186 {"bbl" , 1 , 0 , 25, 27, 0x00000005},
187};
188
189const ISEITEM arm_exclusion_code[] = {
190 #define VFP_DECODE_EXCLUSION
191 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
192 #undef VFP_DECODE_EXCLUSION
193 {"srs" , 0 , 6 , 0},
194 {"rfe" , 0 , 6 , 0},
195 {"bkpt" , 0 , 3 , 0},
196 {"blx" , 0 , 3 , 0},
197 {"cps" , 0 , 6 , 0},
198 {"pld" , 0 , 4 , 0},
199 {"setend" , 0 , 6 , 0},
200 {"clrex" , 0 , 6 , 0},
201 {"rev16" , 0 , 6 , 0},
202 {"usad8" , 0 , 6 , 0},
203 {"sxtb" , 0 , 6 , 0},
204 {"uxtb" , 0 , 6 , 0},
205 {"sxth" , 0 , 6 , 0},
206 {"sxtb16" , 0 , 6 , 0},
207 {"uxth" , 0 , 6 , 0},
208 {"uxtb16" , 0 , 6 , 0},
209 {"cpy" , 0 , 6 , 0},
210 {"uxtab" , 0 , 6 , 0},
211 {"ssub8" , 0 , 6 , 0},
212 {"shsub8" , 0 , 6 , 0},
213 {"ssubaddx" , 0 , 6 , 0},
214 {"strex" , 0 , 6 , 0},
215 {"strexb" , 0 , 7 , 0},
216 {"swp" , 0 , 0 , 0},
217 {"swpb" , 0 , 0 , 0},
218 {"ssub16" , 0 , 6 , 0},
219 {"ssat16" , 0 , 6 , 0},
220 {"shsubaddx" , 0 , 6 , 0},
221 {"qsubaddx" , 0 , 6 , 0},
222 {"shaddsubx" , 0 , 6 , 0},
223 {"shadd8" , 0 , 6 , 0},
224 {"shadd16" , 0 , 6 , 0},
225 {"sel" , 0 , 6 , 0},
226 {"saddsubx" , 0 , 6 , 0},
227 {"sadd8" , 0 , 6 , 0},
228 {"sadd16" , 0 , 6 , 0},
229 {"shsub16" , 0 , 6 , 0},
230 {"umaal" , 0 , 6 , 0},
231 {"uxtab16" , 0 , 6 , 0},
232 {"usubaddx" , 0 , 6 , 0},
233 {"usub8" , 0 , 6 , 0},
234 {"usub16" , 0 , 6 , 0},
235 {"usat16" , 0 , 6 , 0},
236 {"usada8" , 0 , 6 , 0},
237 {"uqsubaddx" , 0 , 6 , 0},
238 {"uqsub8" , 0 , 6 , 0},
239 {"uqsub16" , 0 , 6 , 0},
240 {"uqaddsubx" , 0 , 6 , 0},
241 {"uqadd8" , 0 , 6 , 0},
242 {"uqadd16" , 0 , 6 , 0},
243 {"sxtab" , 0 , 6 , 0},
244 {"uhsubaddx" , 0 , 6 , 0},
245 {"uhsub8" , 0 , 6 , 0},
246 {"uhsub16" , 0 , 6 , 0},
247 {"uhaddsubx" , 0 , 6 , 0},
248 {"uhadd8" , 0 , 6 , 0},
249 {"uhadd16" , 0 , 6 , 0},
250 {"uaddsubx" , 0 , 6 , 0},
251 {"uadd8" , 0 , 6 , 0},
252 {"uadd16" , 0 , 6 , 0},
253 {"sxtah" , 0 , 6 , 0},
254 {"sxtab16" , 0 , 6 , 0},
255 {"qadd8" , 0 , 6 , 0},
256 {"bxj" , 0 , 5 , 0},
257 {"clz" , 0 , 3 , 0},
258 {"uxtah" , 0 , 6 , 0},
259 {"bx" , 0 , 2 , 0},
260 {"rev" , 0 , 6 , 0},
261 {"blx" , 0 , 3 , 0},
262 {"revsh" , 0 , 6 , 0},
263 {"qadd" , 0 , 4 , 0},
264 {"qadd16" , 0 , 6 , 0},
265 {"qaddsubx" , 0 , 6 , 0},
266 {"ldrex" , 0 , 0 , 0},
267 {"qdadd" , 0 , 4 , 0},
268 {"qdsub" , 0 , 4 , 0},
269 {"qsub" , 0 , 4 , 0},
270 {"ldrexb" , 0 , 7 , 0},
271 {"qsub8" , 0 , 6 , 0},
272 {"qsub16" , 0 , 6 , 0},
273 {"smuad" , 0 , 6 , 0},
274 {"smmul" , 0 , 6 , 0},
275 {"smusd" , 0 , 6 , 0},
276 {"smlsd" , 0 , 6 , 0},
277 {"smlsld" , 0 , 6 , 0},
278 {"smmla" , 0 , 6 , 0},
279 {"smmls" , 0 , 6 , 0},
280 {"smlald" , 0 , 6 , 0},
281 {"smlad" , 0 , 6 , 0},
282 {"smlaw" , 0 , 4 , 0},
283 {"smulw" , 0 , 4 , 0},
284 {"pkhtb" , 0 , 6 , 0},
285 {"pkhbt" , 0 , 6 , 0},
286 {"smul" , 0 , 4 , 0},
287 {"smlal" , 0 , 4 , 0},
288 {"smla" , 0 , 4 , 0},
289 {"mcrr" , 0 , 6 , 0},
290 {"mrrc" , 0 , 6 , 0},
291 {"cmp" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
292 {"tst" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
293 {"teq" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
294 {"cmn" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
295 {"smull" , 0 , 0 , 0},
296 {"umull" , 0 , 0 , 0},
297 {"umlal" , 0 , 0 , 0},
298 {"smlal" , 0 , 0 , 0},
299 {"mul" , 0 , 0 , 0},
300 {"mla" , 0 , 0 , 0},
301 {"ssat" , 0 , 6 , 0},
302 {"usat" , 0 , 6 , 0},
303 {"mrs" , 0 , 0 , 0},
304 {"msr" , 0 , 0 , 0},
305 {"and" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
306 {"bic" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
307 {"ldm" , 0 , 0 , 0},
308 {"eor" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
309 {"add" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
310 {"rsb" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
311 {"rsc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
312 {"sbc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
313 {"adc" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
314 {"sub" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
315 {"orr" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
316 {"mvn" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
317 {"mov" , 3 , 0 , 4, 4, 0x00000001, 7, 7, 0x00000001, 25, 25, 0x00000000},
318 {"stm" , 0 , 0 , 0},
319 {"ldm" , 0 , 0 , 0},
320 {"ldrsh" , 0 , 2 , 0},
321 {"stm" , 0 , 0 , 0},
322 {"ldm" , 0 , 0 , 0},
323 {"ldrsb" , 0 , 2 , 0},
324 {"strd" , 0 , 4 , 0},
325 {"ldrh" , 0 , 0 , 0},
326 {"strh" , 0 , 0 , 0},
327 {"ldrd" , 0 , 4 , 0},
328 {"strt" , 0 , 0 , 0},
329 {"strbt" , 0 , 0 , 0},
330 {"ldrbt" , 0 , 0 , 0},
331 {"ldrt" , 0 , 0 , 0},
332 {"mrc" , 0 , 6 , 0},
333 {"mcr" , 0 , 0 , 0},
334 {"msr" , 0 , 0 , 0},
335 {"ldrb" , 0 , 0 , 0},
336 {"strb" , 0 , 0 , 0},
337 {"ldr" , 0 , 0 , 0},
338 {"ldrcond" , 1 , 0 , 28, 31, 0x0000000e},
339 {"str" , 0 , 0 , 0},
340 {"cdp" , 0 , 0 , 0},
341 {"stc" , 0 , 0 , 0},
342 {"ldc" , 0 , 0 , 0},
343 {"swi" , 0 , 0 , 0},
344 {"bbl" , 0 , 0 , 0},
345 {"bl_1_thumb", 0, INVALID, 0},/* should be table[-4] */
346 {"bl_2_thumb", 0, INVALID, 0}, /* should be located at the end of the table[-3] */
347 {"blx_1_thumb", 0, INVALID, 0}, /* should be located at table[-2] */
348 {"invalid", 0, INVALID, 0}
349};
350
351int decode_arm_instr(uint32_t instr, int32_t *idx)
352{
353 int n = 0;
354 int base = 0;
355 int ret = DECODE_FAILURE;
356 int i = 0;
357 int instr_slots = sizeof(arm_instruction)/sizeof(ISEITEM);
358 for (i = 0; i < instr_slots; i++)
359 {
360// ret = DECODE_SUCCESS;
361 n = arm_instruction[i].attribute_value;
362 base = 0;
363 while (n) {
364 if (arm_instruction[i].content[base + 1] == 31 && arm_instruction[i].content[base] == 0) {
365 /* clrex */
366 if (instr != arm_instruction[i].content[base + 2]) {
367 break;
368 }
369 } else if (BITS(arm_instruction[i].content[base], arm_instruction[i].content[base + 1]) != arm_instruction[i].content[base + 2]) {
370 break;
371 }
372 base += 3;
373 n --;
374 }
375 //All conditions is satisfied.
376 if (n == 0)
377 ret = DECODE_SUCCESS;
378
379 if (ret == DECODE_SUCCESS) {
380 n = arm_exclusion_code[i].attribute_value;
381 if (n != 0) {
382 base = 0;
383 while (n) {
384 if (BITS(arm_exclusion_code[i].content[base], arm_exclusion_code[i].content[base + 1]) != arm_exclusion_code[i].content[base + 2]) {
385 break; }
386 base += 3;
387 n --;
388 }
389 //All conditions is satisfied.
390 if (n == 0)
391 ret = DECODE_FAILURE;
392 }
393 }
394
395 if (ret == DECODE_SUCCESS) {
396 *idx = i;
397 return ret;
398 }
399 }
400 return ret;
401}
402
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h
new file mode 100644
index 000000000..19d94f369
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_dec.h
@@ -0,0 +1,155 @@
1/* Copyright (C)
2* 2012 - Michael.Kang blackfin.kang@gmail.com
3* This program is free software; you can redistribute it and/or
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18
19/**
20* @file arm_dyncom_dec.h
21* @brief Some common utility for arm instruction decoder
22* @author Michael.Kang blackfin.kang@gmail.com
23* @version 7849
24* @date 2012-03-15
25*/
26
27#ifndef __ARM_DYNCOM_DEC__
28#define __ARM_DYNCOM_DEC__
29
30#define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1))
31#define BIT(n) ((instr >> (n)) & 1)
32#define BAD do{printf("meet BAD at %s, instr is %x\n", __FUNCTION__, instr ); /*exit(0);*/}while(0);
33#define ptr_N cpu->ptr_N
34#define ptr_Z cpu->ptr_Z
35#define ptr_C cpu->ptr_C
36#define ptr_V cpu->ptr_V
37#define ptr_I cpu->ptr_I
38#define ptr_T cpu->ptr_T
39#define ptr_CPSR cpu->ptr_gpr[16]
40
41/* for MUL instructions */
42/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */
43#define RDHi ((instr >> 16) & 0xF)
44/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */
45#define RDLo ((instr >> 12) & 0xF)
46/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */
47#define MUL_RD ((instr >> 16) & 0xF)
48/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */
49#define MUL_RN ((instr >> 12) & 0xF)
50/*xxxx xxxx xxxx xxxx xxxx 1111 xxxx xxxx */
51#define RS ((instr >> 8) & 0xF)
52
53/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */
54#define RD ((instr >> 12) & 0xF)
55/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */
56#define RN ((instr >> 16) & 0xF)
57/*xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 */
58#define RM (instr & 0xF)
59#define BIT(n) ((instr >> (n)) & 1)
60#define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1))
61
62/* CP15 registers */
63#define OPCODE_1 BITS(21, 23)
64#define CRn BITS(16, 19)
65#define CRm BITS(0, 3)
66#define OPCODE_2 BITS(5, 7)
67
68/*xxxx xx1x xxxx xxxx xxxx xxxx xxxx xxxx */
69#define I BIT(25)
70/*xxxx xxxx xxx1 xxxx xxxx xxxx xxxx xxxx */
71#define S BIT(20)
72
73#define SHIFT BITS(5,6)
74#define SHIFT_IMM BITS(7,11)
75#define IMMH BITS(8,11)
76#define IMML BITS(0,3)
77
78#define LSPBIT BIT(24)
79#define LSUBIT BIT(23)
80#define LSBBIT BIT(22)
81#define LSWBIT BIT(21)
82#define LSLBIT BIT(20)
83#define LSSHBITS BITS(5,6)
84#define OFFSET12 BITS(0,11)
85#define SBIT BIT(20)
86#define DESTReg (BITS (12, 15))
87
88/* they are in unused state, give a corrent value when using */
89#define IS_V5E 0
90#define IS_V5 0
91#define IS_V6 0
92#define LHSReg 0
93
94/* temp define the using the pc reg need implement a flow */
95#define STORE_CHECK_RD_PC ADD(R(RD), CONST(INSTR_SIZE * 2))
96
97#define OPERAND operand(cpu,instr,bb,NULL)
98#define SCO_OPERAND(sco) operand(cpu,instr,bb,sco)
99#define BOPERAND boperand(instr)
100
101#define CHECK_RN_PC (RN==15? ADD(AND(R(RN), CONST(~0x1)), CONST(INSTR_SIZE * 2)):R(RN))
102#define CHECK_RN_PC_WA (RN==15? ADD(AND(R(RN), CONST(~0x3)), CONST(INSTR_SIZE * 2)):R(RN))
103
104#define GET_USER_MODE() (OR(ICMP_EQ(R(MODE_REG), CONST(USER32MODE)), ICMP_EQ(R(MODE_REG), CONST(SYSTEM32MODE))))
105
106int decode_arm_instr(uint32_t instr, int32_t *idx);
107
108enum DECODE_STATUS {
109 DECODE_SUCCESS,
110 DECODE_FAILURE
111};
112
113struct instruction_set_encoding_item {
114 const char *name;
115 int attribute_value;
116 int version;
117 u32 content[21];
118};
119
120typedef struct instruction_set_encoding_item ISEITEM;
121
122#define RECORD_WB(value, flag) {cpu->dyncom_engine->wb_value = value;cpu->dyncom_engine->wb_flag = flag;}
123#define INIT_WB(wb_value, wb_flag) RECORD_WB(wb_value, wb_flag)
124
125#define EXECUTE_WB(base_reg) {if(cpu->dyncom_engine->wb_flag) \
126 LET(base_reg, cpu->dyncom_engine->wb_value);}
127inline int get_reg_count(uint32_t instr){
128 int i = BITS(0,15);
129 int count = 0;
130 while(i){
131 if(i & 1)
132 count ++;
133 i = i >> 1;
134 }
135 return count;
136}
137
138enum ARMVER {
139 INVALID = 0,
140 ARMALL,
141 ARMV4,
142 ARMV4T,
143 ARMV5T,
144 ARMV5TE,
145 ARMV5TEJ,
146 ARMV6,
147 ARM1176JZF_S,
148 ARMVFP2,
149 ARMVFP3
150};
151
152//extern const INSTRACT arm_instruction_action[];
153extern const ISEITEM arm_instruction[];
154
155#endif
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
new file mode 100644
index 000000000..fe1501b59
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -0,0 +1,6563 @@
1/* Copyright (C)
2* 2012 - Michael.Kang blackfin.kang@gmail.com
3* This program is free software; you can redistribute it and/or
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18/**
19* @file arm_dyncom_interpreter.cpp
20* @brief The fast interpreter for arm
21* @author Michael.Kang blackfin.kang@gmail.com
22* @version 7849
23* @date 2012-03-15
24*/
25
26#define CITRA_IGNORE_EXIT(x)
27
28#include <algorithm>
29#include <map>
30#include <stdio.h>
31#include <assert.h>
32#include <cstdio>
33#include <vector>
34
35using namespace std;
36
37#include "core/arm/skyeye_common/armdefs.h"
38#include "core/arm/skyeye_common/armmmu.h"
39#include "arm_dyncom_thumb.h"
40#include "arm_dyncom_run.h"
41#include "core/arm/skyeye_common/vfp/vfp.h"
42/* shenoubang 2012-6-14 */
43#ifdef __WIN32__
44#include "bank_defs.h"
45#endif
46
47#include "core/mem_map.h"
48#include "core/hle/hle.h"
49
50enum {
51 COND = (1 << 0),
52 NON_BRANCH = (1 << 1),
53 DIRECT_BRANCH = (1 << 2),
54 INDIRECT_BRANCH = (1 << 3),
55 CALL = (1 << 4),
56 RET = (1 << 5),
57 END_OF_PAGE = (1 << 6),
58 THUMB = (1 << 7)
59};
60
61#define USER_MODE_OPT 1
62#define HYBRID_MODE 0 // Enable for JIT mode
63
64#define THRESHOLD 1000
65#define DURATION 500
66//#define PRINT_PROFILE_INFO
67
68#define CHECK_RS if(RS == 15) rs += 8
69#define CHECK_RM if(RM == 15) rm += 8
70
71//#define BITS(s, a, b) (((s) >> (a)) & ((1 << (1 + (b) - (a))) - 1))
72#undef BITS
73#define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1))
74#define BIT(s, n) ((s >> (n)) & 1)
75#define RM BITS(sht_oper, 0, 3)
76#define RS BITS(sht_oper, 8, 11)
77
78#define glue(x, y) x ## y
79#define DPO(s) glue(DataProcessingOperands, s)
80#define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i))
81#define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i))
82#define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32)
83#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32)
84
85//#define rotr(x,n) ((((x)>>(n))&((1<<(sizeof(x) * 8)-1))|(x<<(sizeof(x)*8-n))))
86//#define rotl(x,n) ((((x)<<(n))&(-(1<<(n))))|(((x)>>(sizeof(x)*8-n))&((1<<(n))-1)))
87#define rotr(x,n) ( (x >> n) | ((x & ((1 << (n + 1)) - 1)) << (32 - n)) )
88
89extern void switch_mode(arm_core_t *core, uint32_t mode);
90//extern bool InAPrivilegedMode(arm_core_t *core);
91
92typedef arm_core_t arm_processor;
93typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper);
94
95/* exclusive memory access */
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 == 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 //DEBUG_LOG(ARM11, "In %s, add addr 0x%x\n", __func__, addr);
117 return;
118 }
119 }
120 DEBUG_LOG(ARM11, "In %s ,can not monitor the addr, out of array\n", __FUNCTION__);
121 #endif
122 state->exclusive_tag = 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 //DEBUG_LOG(ARM11, "In %s, remove addr 0x%x\n", __func__, addr);
133 return;
134 }
135 }
136 #endif
137 state->exclusive_tag = 0xFFFFFFFF;
138}
139
140
141unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper)
142{
143// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
144 unsigned int immed_8 = BITS(sht_oper, 0, 7);
145 unsigned int rotate_imm = BITS(sht_oper, 8, 11);
146// DEBUG_LOG(ARM11, "immed_8 is %x\n", immed_8);
147// DEBUG_LOG(ARM11, "rotate_imm is %x\n", rotate_imm);
148 unsigned int shifter_operand = ROTATE_RIGHT_32(immed_8, rotate_imm * 2);//ROTATE_RIGHT_32(immed_8, rotate_imm * 2);
149// DEBUG_LOG(ARM11, "shifter_operand : %x\n", shifter_operand);
150 /* set c flag */
151 if (rotate_imm == 0)
152 cpu->shifter_carry_out = cpu->CFlag;
153 else
154 cpu->shifter_carry_out = BIT(shifter_operand, 31);
155 return shifter_operand;
156}
157
158unsigned int DPO(Register)(arm_processor *cpu, unsigned int sht_oper)
159{
160// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
161 unsigned int rm = CHECK_READ_REG15(cpu, RM);
162 //if (RM == 15) rm += 8;
163 unsigned int shifter_operand = rm;
164 cpu->shifter_carry_out = cpu->CFlag;
165 return shifter_operand;
166}
167
168unsigned int DPO(LogicalShiftLeftByImmediate)(arm_processor *cpu, unsigned int sht_oper)
169{
170// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
171 int shift_imm = BITS(sht_oper, 7, 11);
172 unsigned int rm = CHECK_READ_REG15(cpu, RM);
173 //if (RM == 15) rm += 8;
174 unsigned int shifter_operand;
175 if (shift_imm == 0) {
176 shifter_operand = rm;
177 cpu->shifter_carry_out = cpu->CFlag;
178 } else {
179 shifter_operand = rm << shift_imm;
180 cpu->shifter_carry_out = BIT(rm, 32 - shift_imm);
181 }
182 return shifter_operand;
183}
184
185unsigned int DPO(LogicalShiftLeftByRegister)(arm_processor *cpu, unsigned int sht_oper)
186{
187// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
188 int shifter_operand;
189 unsigned int rm = CHECK_READ_REG15(cpu, RM);
190 unsigned int rs = CHECK_READ_REG15(cpu, RS);
191 //if (RM == 15) rm += 8;
192 //if (RS == 15) rs += 8;
193 if (BITS(rs, 0, 7) == 0) {
194 shifter_operand = rm;
195 cpu->shifter_carry_out = cpu->CFlag;
196 } else if (BITS(rs, 0, 7) < 32) {
197 shifter_operand = rm << BITS(rs, 0, 7);
198 cpu->shifter_carry_out = BIT(rm, 32 - BITS(rs, 0, 7));
199 } else if (BITS(rs, 0, 7) == 32) {
200 shifter_operand = 0;
201 cpu->shifter_carry_out = BIT(rm, 0);
202 } else {
203 shifter_operand = 0;
204 cpu->shifter_carry_out = 0;
205 }
206 return shifter_operand;
207}
208
209unsigned int DPO(LogicalShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper)
210{
211// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
212 //unsigned int rm = cpu->Reg[RM];
213 unsigned int rm = CHECK_READ_REG15(cpu, RM);
214 //if (RM == 15) rm += 8;
215 unsigned int shifter_operand;
216 int shift_imm = BITS(sht_oper, 7, 11);
217 if (shift_imm == 0) {
218 shifter_operand = 0;
219 cpu->shifter_carry_out = BIT(rm, 31);
220 } else {
221 shifter_operand = rm >> shift_imm;
222 cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
223 }
224 return shifter_operand;
225}
226
227unsigned int DPO(LogicalShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper)
228{
229// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
230 unsigned int rs = CHECK_READ_REG15(cpu, RS);
231 unsigned int rm = CHECK_READ_REG15(cpu, RM);
232 //if (RS == 15) rs += 8;
233 //if (RM == 15) rm += 8;
234 unsigned int shifter_operand;
235 if (BITS(rs, 0, 7) == 0) {
236 shifter_operand = rm;
237 cpu->shifter_carry_out = cpu->CFlag;
238 } else if (BITS(rs, 0, 7) < 32) {
239 shifter_operand = rm >> BITS(rs, 0, 7);
240 cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
241 } else if (BITS(rs, 0, 7) == 32) {
242 shifter_operand = 0;
243 cpu->shifter_carry_out = BIT(rm, 31);
244 } else {
245 shifter_operand = 0;
246 cpu->shifter_carry_out = 0;
247 }
248 return shifter_operand;
249}
250
251unsigned int DPO(ArithmeticShiftRightByImmediate)(arm_processor *cpu, unsigned int sht_oper)
252{
253// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
254 //unsigned int rm = cpu->Reg[RM];
255 unsigned int rm = CHECK_READ_REG15(cpu, RM);
256 //if (RM == 15) rm += 8;
257 unsigned int shifter_operand;
258 int shift_imm = BITS(sht_oper, 7, 11);
259 if (shift_imm == 0) {
260 if (BIT(rm, 31)) {
261 shifter_operand = 0;
262 cpu->shifter_carry_out = BIT(rm, 31);
263 } else {
264 shifter_operand = 0xFFFFFFFF;
265 cpu->shifter_carry_out = BIT(rm, 31);
266 }
267 } else {
268 shifter_operand = static_cast<int>(rm) >> shift_imm;
269 cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
270 }
271 return shifter_operand;
272}
273
274unsigned int DPO(ArithmeticShiftRightByRegister)(arm_processor *cpu, unsigned int sht_oper)
275{
276// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
277 //unsigned int rs = cpu->Reg[RS];
278 unsigned int rs = CHECK_READ_REG15(cpu, RS);
279 //unsigned int rm = cpu->Reg[RM];
280 unsigned int rm = CHECK_READ_REG15(cpu, RM);
281 //if (RS == 15) rs += 8;
282 //if (RM == 15) rm += 8;
283 unsigned int shifter_operand;
284 if (BITS(rs, 0, 7) == 0) {
285 shifter_operand = rm;
286 cpu->shifter_carry_out = cpu->CFlag;
287 } else if (BITS(rs, 0, 7) < 32) {
288 shifter_operand = static_cast<int>(rm) >> BITS(rs, 0, 7);
289 cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 7) - 1);
290 } else {
291 if (BIT(rm, 31) == 0) {
292 shifter_operand = 0;
293 } else
294 shifter_operand = 0xffffffff;
295 cpu->shifter_carry_out = BIT(rm, 31);
296 }
297 return shifter_operand;
298}
299
300unsigned int DPO(RotateRightByImmediate)(arm_processor *cpu, unsigned int sht_oper)
301{
302// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
303 unsigned int shifter_operand;
304 //unsigned int rm = cpu->Reg[RM];
305 unsigned int rm = CHECK_READ_REG15(cpu, RM);
306 //if (RM == 15) rm += 8;
307 int shift_imm = BITS(sht_oper, 7, 11);
308 if (shift_imm == 0) {
309 shifter_operand = (cpu->CFlag << 31) |
310 (rm >> 1);
311 cpu->shifter_carry_out = BIT(rm, 0);
312 } else {
313 shifter_operand = ROTATE_RIGHT_32(rm, shift_imm);
314 cpu->shifter_carry_out = BIT(rm, shift_imm - 1);
315 }
316 return shifter_operand;
317}
318
319unsigned int DPO(RotateRightByRegister)(arm_processor *cpu, unsigned int sht_oper)
320{
321// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
322 unsigned int rm = CHECK_READ_REG15(cpu, RM);
323 //if (RM == 15) rm += 8;
324 unsigned int rs = CHECK_READ_REG15(cpu, RS);
325 //if (RS == 15) rs += 8;
326 unsigned int shifter_operand;
327 if (BITS(rs, 0, 7) == 0) {
328 shifter_operand = rm;
329 cpu->shifter_carry_out = cpu->CFlag;
330 } else if (BITS(rs, 0, 4) == 0) {
331 shifter_operand = rm;
332 cpu->shifter_carry_out = BIT(rm, 31);
333 } else {
334 shifter_operand = ROTATE_RIGHT_32(rm, BITS(rs, 0, 4));
335 cpu->shifter_carry_out = BIT(rm, BITS(rs, 0, 4) - 1);
336 }
337 #if 0
338 if (cpu->icounter >= 20371544) {
339 DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
340 DEBUG_LOG(ARM11, "RM:%d\nRS:%d\n", RM, RS);
341 DEBUG_LOG(ARM11, "rm:0x%08x\nrs:0x%08x\n", cpu->Reg[RM], cpu->Reg[RS]);
342 }
343 #endif
344 return shifter_operand;
345}
346
347//typedef unsigned int (*get_addr_fp_t)(arm_processor *cpu);
348typedef struct _MiscImmeData {
349 unsigned int U;
350 unsigned int Rn;
351 unsigned int offset_8;
352} MiscLSData;
353
354typedef struct _MiscRegData {
355 unsigned int U;
356 unsigned int Rn;
357 unsigned int Rm;
358} MiscRegData;
359
360typedef struct _MiscImmePreIdx {
361 unsigned int offset_8;
362 unsigned int U;
363 unsigned int Rn;
364} MiscImmePreIdx;
365
366typedef struct _MiscRegPreIdx {
367 unsigned int U;
368 unsigned int Rn;
369 unsigned int Rm;
370} MiscRegPreIdx;
371
372typedef struct _MiscImmePstIdx {
373 unsigned int offset_8;
374 unsigned int U;
375 unsigned int Rn;
376} MIscImmePstIdx;
377
378typedef struct _MiscRegPstIdx {
379 unsigned int Rn;
380 unsigned int Rm;
381 unsigned int U;
382} MiscRegPstIdx;
383
384typedef struct _LSWordorUnsignedByte {
385} LDnST;
386
387#if USER_MODE_OPT
388static inline fault_t interpreter_read_memory(addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size){
389 switch(size) {
390 case 8:
391 value = Memory::Read8(virt_addr);
392 break;
393 case 16:
394 value = Memory::Read16(virt_addr);
395 break;
396 case 32:
397 value = Memory::Read32(virt_addr);
398 break;
399 }
400 return NO_FAULT;
401}
402
403//static inline void interpreter_write_memory(void *mem_ptr, uint32_t offset, uint32_t value, int size)
404static inline fault_t interpreter_write_memory(addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size)
405{
406 switch(size) {
407 case 8:
408 Memory::Write8(virt_addr, value & 0xff);
409 break;
410 case 16:
411 Memory::Write16(virt_addr, value & 0xffff);
412 break;
413 case 32:
414 Memory::Write32(virt_addr, value);
415 break;
416 }
417 return NO_FAULT;
418}
419
420static inline fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw){
421 *phys_addr = virt_addr;
422 return NO_FAULT;
423}
424
425#else
426fault_t interpreter_read_memory(cpu_t *cpu, addr_t virt_addr, addr_t phys_addr, uint32_t &value, uint32_t size);
427fault_t interpreter_write_memory(cpu_t *cpu, addr_t virt_addr, addr_t phys_addr, uint32_t value, uint32_t size);
428fault_t interpreter_fetch(cpu_t *cpu, addr_t virt_addr, uint32_t &value, uint32_t size);
429fault_t check_address_validity(arm_core_t *core, addr_t virt_addr, addr_t *phys_addr, uint32_t rw, tlb_type_t access_type = DATA_TLB);
430#endif
431
432typedef fault_t (*get_addr_fp_t)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw);
433
434typedef struct _ldst_inst {
435 unsigned int inst;
436 get_addr_fp_t get_addr;
437} ldst_inst;
438#define DEBUG_MSG DEBUG_LOG(ARM11, "in %s %d\n", __FUNCTION__, __LINE__); \
439 DEBUG_LOG(ARM11, "inst is %x\n", inst); \
440 CITRA_IGNORE_EXIT(0)
441
442int CondPassed(arm_processor *cpu, unsigned int cond);
443#define LnSWoUB(s) glue(LnSWoUB, s)
444#define MLnS(s) glue(MLnS, s)
445#define LdnStM(s) glue(LdnStM, s)
446
447#define W_BIT BIT(inst, 21)
448#define U_BIT BIT(inst, 23)
449#define I_BIT BIT(inst, 25)
450#define P_BIT BIT(inst, 24)
451#define OFFSET_12 BITS(inst, 0, 11)
452fault_t LnSWoUB(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
453{
454 unsigned int Rn = BITS(inst, 16, 19);
455 unsigned int addr;
456 fault_t fault;
457 if (U_BIT) {
458 addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
459 } else {
460 addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
461 }
462 //if (Rn == 15) rn += 8;
463 virt_addr = addr;
464 fault = check_address_validity(cpu, addr, &phys_addr, rw);
465 return fault;
466// return addr;
467}
468
469fault_t LnSWoUB(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
470{
471 fault_t fault;
472 unsigned int Rn = BITS(inst, 16, 19);
473 unsigned int Rm = BITS(inst, 0, 3);
474 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
475 //if (Rn == 15) rn += 8;
476 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
477 //if (Rm == 15) rm += 8;
478 unsigned int addr;
479 if (U_BIT) {
480 addr = rn + rm;
481 } else {
482 addr = rn - rm;
483 }
484 virt_addr = addr;
485 fault = check_address_validity(cpu, addr, &phys_addr, rw);
486 return fault;
487}
488
489fault_t LnSWoUB(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
490{
491 fault_t fault;
492 unsigned int Rn = BITS(inst, 16, 19);
493 unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn);
494 //if (Rn == 15) addr += 8;
495
496 virt_addr = addr;
497 fault = check_address_validity(cpu, addr, &phys_addr, rw);
498 if (fault) return fault;
499
500 if (U_BIT) {
501 cpu->Reg[Rn] += OFFSET_12;
502 } else {
503 cpu->Reg[Rn] -= OFFSET_12;
504 }
505 return fault;
506}
507
508fault_t LnSWoUB(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
509{
510 fault_t fault;
511 unsigned int Rn = BITS(inst, 16, 19);
512 unsigned int addr;
513 if (U_BIT) {
514 addr = CHECK_READ_REG15_WA(cpu, Rn) + OFFSET_12;
515 } else {
516 addr = CHECK_READ_REG15_WA(cpu, Rn) - OFFSET_12;
517 }
518 #if 0
519 if (Rn == 15) {
520 addr += 8;
521 }
522 #endif
523
524 virt_addr = addr;
525 fault = check_address_validity(cpu, addr, &phys_addr, rw);
526 if (fault) return fault;
527
528 if (CondPassed(cpu, BITS(inst, 28, 31))) {
529 cpu->Reg[Rn] = addr;
530 }
531 return fault;
532}
533
534fault_t MLnS(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
535{
536 fault_t fault;
537 unsigned int addr;
538 unsigned int Rn = BITS(inst, 16, 19);
539 unsigned int Rm = BITS(inst, 0, 3);
540 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
541 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
542 //if (Rn == 15) rn += 8;
543 //if (Rm == 15) rm += 8;
544 if (U_BIT) {
545 addr = rn + rm;
546 } else
547 addr = rn - rm;
548 if(BIT(inst, 20)){ /* L BIT */
549 }
550 if(BIT(inst, 6)){ /* Sign Bit */
551 }
552 if(BIT(inst, 5)){ /* Half Bit */
553 }
554
555 virt_addr = addr;
556 fault = check_address_validity(cpu, addr, &phys_addr, rw);
557 if (fault) return fault;
558
559 if (CondPassed(cpu, BITS(inst, 28, 31))) {
560 cpu->Reg[Rn] = addr;
561 }
562 return fault;
563}
564
565fault_t LnSWoUB(RegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
566{
567 fault_t fault;
568 unsigned int Rn = BITS(inst, 16, 19);
569 unsigned int Rm = BITS(inst, 0, 3);
570 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
571 //if (Rn == 15) rn += 8;
572 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
573 //if (Rm == 15) rm += 8;
574 unsigned int addr;
575 if (U_BIT) {
576 addr = rn + rm;
577 } else {
578 addr = rn - rm;
579 }
580 virt_addr = addr;
581 fault = check_address_validity(cpu, addr, &phys_addr, rw);
582 if(fault)
583 return fault;
584 if (CondPassed(cpu, BITS(inst, 28, 31))) {
585 cpu->Reg[Rn] = addr;
586 }
587 return fault;
588}
589fault_t LnSWoUB(ScaledRegisterPreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
590{
591 fault_t fault;
592 unsigned int shift = BITS(inst, 5, 6);
593 unsigned int shift_imm = BITS(inst, 7, 11);
594 unsigned int Rn = BITS(inst, 16, 19);
595 unsigned int Rm = BITS(inst, 0, 3);
596 unsigned int index;
597 unsigned int addr;
598
599 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
600 //if (Rm == 15) rm += 8;
601 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
602 //if (Rn == 15) rn += 8;
603 switch (shift) {
604 case 0:
605 //DEBUG_MSG;
606 index = rm << shift_imm;
607 break;
608 case 1:
609// DEBUG_MSG;
610 if (shift_imm == 0) {
611 index = 0;
612 } else {
613 index = rm >> shift_imm;
614 }
615 break;
616 case 2:
617 DEBUG_MSG;
618 break;
619 case 3:
620 DEBUG_MSG;
621 break;
622 }
623 if (U_BIT) {
624 addr = rn + index;
625 } else
626 addr = rn - index;
627 virt_addr = addr;
628 fault = check_address_validity(cpu, addr, &phys_addr, rw);
629 if(fault)
630 return fault;
631 if (CondPassed(cpu, BITS(inst, 28, 31))) {
632 cpu->Reg[Rn] = addr;
633 }
634
635 return fault;
636}
637
638fault_t LnSWoUB(ScaledRegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
639{
640 fault_t fault;
641 unsigned int shift = BITS(inst, 5, 6);
642 unsigned int shift_imm = BITS(inst, 7, 11);
643 unsigned int Rn = BITS(inst, 16, 19);
644 unsigned int Rm = BITS(inst, 0, 3);
645 unsigned int index;
646 unsigned int addr;
647
648 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
649 //if (Rm == 15) rm += 8;
650 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
651 //if (Rn == 15) rn += 8;
652 addr = rn;
653 switch (shift) {
654 case 0:
655 //DEBUG_MSG;
656 index = rm << shift_imm;
657 break;
658 case 1:
659// DEBUG_MSG;
660 if (shift_imm == 0) {
661 index = 0;
662 } else {
663 index = rm >> shift_imm;
664 }
665 break;
666 case 2:
667 DEBUG_MSG;
668 break;
669 case 3:
670 DEBUG_MSG;
671 break;
672 }
673 virt_addr = addr;
674 fault = check_address_validity(cpu, addr, &phys_addr, rw);
675 if(fault)
676 return fault;
677 if (CondPassed(cpu, BITS(inst, 28, 31))) {
678 if (U_BIT)
679 cpu->Reg[Rn] += index;
680 else
681 cpu->Reg[Rn] -= index;
682 }
683
684 return fault;
685}
686
687fault_t LnSWoUB(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
688{
689 fault_t fault;
690 unsigned int Rn = BITS(inst, 16, 19);
691 unsigned int Rm = BITS(inst, 0, 3);
692 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
693 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
694
695 unsigned int addr = rn;
696 virt_addr = addr;
697 fault = check_address_validity(cpu, addr, &phys_addr, rw);
698 if (fault) return fault;
699
700 if (CondPassed(cpu, BITS(inst, 28, 31))) {
701 if (U_BIT) {
702 cpu->Reg[Rn] += rm;
703 } else {
704 cpu->Reg[Rn] -= rm;
705 }
706 }
707 return fault;
708}
709
710fault_t MLnS(ImmediateOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
711{
712 fault_t fault;
713 unsigned int immedL = BITS(inst, 0, 3);
714 unsigned int immedH = BITS(inst, 8, 11);
715
716 unsigned int Rn = BITS(inst, 16, 19);
717 unsigned int addr;
718
719 unsigned int offset_8 = (immedH << 4) | immedL;
720 if (U_BIT) {
721 addr = CHECK_READ_REG15_WA(cpu, Rn) + offset_8;
722 } else
723 addr = CHECK_READ_REG15_WA(cpu, Rn) - offset_8;
724 #if 0
725 if (Rn == 15) {
726 addr += 8;
727 }
728 #endif
729 virt_addr = addr;
730 fault = check_address_validity(cpu, addr, &phys_addr, rw);
731 return fault;
732}
733
734fault_t MLnS(RegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
735{
736 fault_t fault;
737 unsigned int addr;
738 unsigned int Rn = BITS(inst, 16, 19);
739 unsigned int Rm = BITS(inst, 0, 3);
740 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
741 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
742 //if (Rn == 15) rn += 8;
743 //if (Rm == 15) rm += 8;
744 if (U_BIT) {
745 addr = rn + rm;
746 } else
747 addr = rn - rm;
748 if(BIT(inst, 20)){ /* L BIT */
749 }
750 if(BIT(inst, 6)){ /* Sign Bit */
751 }
752 if(BIT(inst, 5)){ /* Half Bit */
753 }
754 virt_addr = addr;
755 fault = check_address_validity(cpu, addr, &phys_addr, rw);
756 return fault;
757}
758
759fault_t MLnS(ImmediatePreIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
760{
761 fault_t fault;
762 unsigned int Rn = BITS(inst, 16, 19);
763 unsigned int immedH = BITS(inst, 8, 11);
764 unsigned int immedL = BITS(inst, 0, 3);
765 unsigned int addr;
766 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
767 //if (Rn == 15) rn += 8;
768
769// DEBUG_LOG(ARM11, "in %s\n", __FUNCTION__);
770 unsigned int offset_8 = (immedH << 4) | immedL;
771 if (U_BIT) {
772 addr = rn + offset_8;
773 } else
774 addr = rn - offset_8;
775
776 virt_addr = addr;
777 fault = check_address_validity(cpu, addr, &phys_addr, rw);
778 if (fault) return fault;
779
780 if (CondPassed(cpu, BITS(inst, 28, 31))) {
781 cpu->Reg[Rn] = addr;
782 }
783 return fault;
784}
785
786fault_t MLnS(ImmediatePostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
787{
788 fault_t fault;
789 unsigned int Rn = BITS(inst, 16, 19);
790 unsigned int immedH = BITS(inst, 8, 11);
791 unsigned int immedL = BITS(inst, 0, 3);
792 unsigned int addr;
793 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
794 addr = rn;
795
796 virt_addr = addr;
797 fault = check_address_validity(cpu, addr, &phys_addr, rw);
798 if (fault) return fault;
799
800 if (CondPassed(cpu, BITS(inst, 28, 31))) {
801 unsigned int offset_8 = (immedH << 4) | immedL;
802 if (U_BIT) {
803 rn += offset_8;
804 } else {
805 rn -= offset_8;
806 }
807 cpu->Reg[Rn] = rn;
808 }
809
810 return fault;
811}
812fault_t MLnS(RegisterPostIndexed)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
813{
814 fault_t fault;
815 unsigned int Rn = BITS(inst, 16, 19);
816 unsigned int Rm = BITS(inst, 0, 3);
817 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
818 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
819
820 unsigned int addr = rn;
821 virt_addr = addr;
822 fault = check_address_validity(cpu, addr, &phys_addr, rw);
823 if (fault) return fault;
824
825 if (CondPassed(cpu, BITS(inst, 28, 31))) {
826 if (U_BIT) {
827 cpu->Reg[Rn] += rm;
828 } else {
829 cpu->Reg[Rn] -= rm;
830 }
831 }
832 return fault;
833}
834
835fault_t LdnStM(DecrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
836{
837 fault_t fault;
838 unsigned int Rn = BITS(inst, 16, 19);
839 unsigned int i = BITS(inst, 0, 15);
840 int count = 0;
841 while(i) {
842 if(i & 1) count ++;
843 i = i >> 1;
844 }
845 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
846 //if (Rn == 15) rn += 8;
847 unsigned int start_addr = rn - count * 4;
848 unsigned int end_addr = rn - 4;
849
850 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
851 virt_addr = end_addr;
852 if (fault) return fault;
853
854 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
855 virt_addr = start_addr;
856 if (fault) return fault;
857
858 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
859 cpu->Reg[Rn] -= count * 4;
860 }
861
862 return fault;
863}
864
865fault_t LdnStM(IncrementBefore)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
866{
867 fault_t fault;
868 unsigned int Rn = BITS(inst, 16, 19);
869 unsigned int i = BITS(inst, 0, 15);
870 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
871 //if (Rn == 15) rn += 8;
872 int count = 0;
873 while(i) {
874 if(i & 1) count ++;
875 i = i >> 1;
876 }
877
878 unsigned int start_addr = rn + 4;
879 unsigned int end_addr = rn + count * 4;
880
881 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
882 virt_addr = end_addr;
883 if (fault) return fault;
884
885 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
886 virt_addr = start_addr;
887 if (fault) return fault;
888
889 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
890 cpu->Reg[Rn] += count * 4;
891 }
892 return fault;
893}
894
895fault_t LdnStM(IncrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
896{
897 fault_t fault;
898 unsigned int Rn = BITS(inst, 16, 19);
899 unsigned int i = BITS(inst, 0, 15);
900 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
901 int count = 0;
902 while(i) {
903 if(i & 1) count ++;
904 i = i >> 1;
905 }
906 //if (Rn == 15) rn += 8;
907 unsigned int start_addr = rn;
908 unsigned int end_addr = rn + count * 4 - 4;
909
910 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
911 virt_addr = end_addr;
912 if (fault) return fault;
913
914 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
915 virt_addr = start_addr;
916 if (fault) return fault;
917
918 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
919 cpu->Reg[Rn] += count * 4;
920 }
921 return fault;
922}
923
924fault_t LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
925{
926 fault_t fault;
927 unsigned int Rn = BITS(inst, 16, 19);
928 unsigned int i = BITS(inst, 0, 15);
929 int count = 0;
930 while(i) {
931 if(i & 1) count ++;
932 i = i >> 1;
933 }
934 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
935 //if (Rn == 15) rn += 8;
936 unsigned int start_addr = rn - count * 4 + 4;
937 unsigned int end_addr = rn;
938
939 fault = check_address_validity(cpu, end_addr, &phys_addr, rw);
940 virt_addr = end_addr;
941 if (fault) return fault;
942
943 fault = check_address_validity(cpu, start_addr, &phys_addr, rw);
944 if (fault) return fault;
945 virt_addr = start_addr;
946
947 if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
948 cpu->Reg[Rn] -= count * 4;
949 }
950 return fault;
951}
952
953fault_t LnSWoUB(ScaledRegisterOffset)(arm_processor *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int &phys_addr, unsigned int rw)
954{
955 fault_t fault;
956 unsigned int shift = BITS(inst, 5, 6);
957 unsigned int shift_imm = BITS(inst, 7, 11);
958 unsigned int Rn = BITS(inst, 16, 19);
959 unsigned int Rm = BITS(inst, 0, 3);
960 unsigned int index;
961 unsigned int addr;
962
963 unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm);
964 //if (Rm == 15) rm += 8;
965 unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
966 //if (Rn == 15) rn += 8;
967 switch (shift) {
968 case 0:
969 //DEBUG_MSG;
970 index = rm << shift_imm;
971 break;
972 case 1:
973// DEBUG_MSG;
974 if (shift_imm == 0) {
975 index = 0;
976 } else {
977 index = rm >> shift_imm;
978 }
979 break;
980 case 2:
981 if (shift_imm == 0){ /* ASR #32 */
982 if (rm >> 31)
983 index = 0xFFFFFFFF;
984 else
985 index = 0;
986 }
987 else {
988 index = static_cast<int>(rm) >> shift_imm;
989 }
990 break;
991 case 3:
992 DEBUG_MSG;
993 break;
994 }
995 if (U_BIT) {
996 addr = rn + index;
997 } else
998 addr = rn - index;
999 virt_addr = addr;
1000 fault = check_address_validity(cpu, addr, &phys_addr, rw);
1001 return fault;
1002}
1003
1004#define ISNEG(n) (n < 0)
1005#define ISPOS(n) (n >= 0)
1006
1007//enum {
1008// COND = (1 << 0),
1009// NON_BRANCH = (1 << 1),
1010// DIRECT_BRANCH = (1 << 2),
1011// INDIRECT_BRANCH = (1 << 3),
1012// CALL = (1 << 4),
1013// RET = (1 << 5),
1014// END_OF_PAGE = (1 << 6),
1015// THUMB = (1 << 7)
1016//};
1017
1018typedef struct _arm_inst {
1019 unsigned int idx;
1020 unsigned int cond;
1021 int br;
1022 int load_r15;
1023 char component[0];
1024} arm_inst;
1025
1026typedef struct _adc_inst {
1027 unsigned int I;
1028 unsigned int S;
1029 unsigned int Rn;
1030 unsigned int Rd;
1031 unsigned int shifter_operand;
1032 shtop_fp_t shtop_func;
1033} adc_inst;
1034
1035typedef struct _add_inst {
1036 unsigned int I;
1037 unsigned int S;
1038 unsigned int Rn;
1039 unsigned int Rd;
1040 unsigned int shifter_operand;
1041 shtop_fp_t shtop_func;
1042} add_inst;
1043
1044typedef struct _orr_inst {
1045 unsigned int I;
1046 unsigned int S;
1047 unsigned int Rn;
1048 unsigned int Rd;
1049 unsigned int shifter_operand;
1050 shtop_fp_t shtop_func;
1051} orr_inst;
1052
1053typedef struct _and_inst {
1054 unsigned int I;
1055 unsigned int S;
1056 unsigned int Rn;
1057 unsigned int Rd;
1058 unsigned int shifter_operand;
1059 shtop_fp_t shtop_func;
1060} and_inst;
1061
1062typedef struct _eor_inst {
1063 unsigned int I;
1064 unsigned int S;
1065 unsigned int Rn;
1066 unsigned int Rd;
1067 unsigned int shifter_operand;
1068 shtop_fp_t shtop_func;
1069} eor_inst;
1070
1071typedef struct _bbl_inst {
1072 unsigned int L;
1073 int signed_immed_24;
1074 unsigned int next_addr;
1075 unsigned int jmp_addr;
1076} bbl_inst;
1077
1078typedef struct _bx_inst {
1079 unsigned int Rm;
1080} bx_inst;
1081
1082typedef struct _blx_inst {
1083 union {
1084 int32_t signed_immed_24;
1085 uint32_t Rm;
1086 } val;
1087 unsigned int inst;
1088} blx_inst;
1089
1090typedef struct _clz_inst {
1091 unsigned int Rm;
1092 unsigned int Rd;
1093} clz_inst;
1094
1095typedef struct _cps_inst {
1096 unsigned int imod0;
1097 unsigned int imod1;
1098 unsigned int mmod;
1099 unsigned int A, I, F;
1100 unsigned int mode;
1101} cps_inst;
1102
1103typedef struct _clrex_inst {
1104} clrex_inst;
1105
1106typedef struct _cpy_inst {
1107 unsigned int Rm;
1108 unsigned int Rd;
1109} cpy_inst;
1110
1111typedef struct _bic_inst {
1112 unsigned int I;
1113 unsigned int S;
1114 unsigned int Rn;
1115 unsigned int Rd;
1116 unsigned int shifter_operand;
1117 shtop_fp_t shtop_func;
1118} bic_inst;
1119
1120typedef struct _sub_inst {
1121 unsigned int I;
1122 unsigned int S;
1123 unsigned int Rn;
1124 unsigned int Rd;
1125 unsigned int shifter_operand;
1126 shtop_fp_t shtop_func;
1127} sub_inst;
1128
1129typedef struct _tst_inst {
1130 unsigned int I;
1131 unsigned int S;
1132 unsigned int Rn;
1133 unsigned int Rd;
1134 unsigned int shifter_operand;
1135 shtop_fp_t shtop_func;
1136} tst_inst;
1137
1138typedef struct _cmn_inst {
1139 unsigned int I;
1140 //unsigned int S;
1141 unsigned int Rn;
1142 //unsigned int Rd;
1143 unsigned int shifter_operand;
1144 shtop_fp_t shtop_func;
1145} cmn_inst;
1146
1147typedef struct _teq_inst {
1148 unsigned int I;
1149 unsigned int Rn;
1150 unsigned int shifter_operand;
1151 shtop_fp_t shtop_func;
1152} teq_inst;
1153
1154typedef struct _stm_inst {
1155 unsigned int inst;
1156} stm_inst;
1157
1158struct bkpt_inst {
1159};
1160
1161struct blx1_inst {
1162 unsigned int addr;
1163};
1164
1165struct blx2_inst {
1166 unsigned int Rm;
1167};
1168
1169typedef struct _stc_inst {
1170} stc_inst;
1171
1172typedef struct _ldc_inst {
1173} ldc_inst;
1174
1175typedef struct _swi_inst {
1176 unsigned int num;
1177} swi_inst;
1178
1179typedef struct _cmp_inst {
1180 unsigned int I;
1181 unsigned int Rn;
1182 unsigned int shifter_operand;
1183 shtop_fp_t shtop_func;
1184} cmp_inst;
1185
1186typedef struct _mov_inst {
1187 unsigned int I;
1188 unsigned int S;
1189 unsigned int Rd;
1190 unsigned int shifter_operand;
1191 shtop_fp_t shtop_func;
1192} mov_inst;
1193
1194typedef struct _mvn_inst {
1195 unsigned int I;
1196 unsigned int S;
1197 unsigned int Rd;
1198 unsigned int shifter_operand;
1199 shtop_fp_t shtop_func;
1200} mvn_inst;
1201
1202typedef struct _rev_inst {
1203 unsigned int Rd;
1204 unsigned int Rm;
1205} rev_inst;
1206
1207typedef struct _rsb_inst {
1208 unsigned int I;
1209 unsigned int S;
1210 unsigned int Rn;
1211 unsigned int Rd;
1212 unsigned int shifter_operand;
1213 shtop_fp_t shtop_func;
1214} rsb_inst;
1215
1216typedef struct _rsc_inst {
1217 unsigned int I;
1218 unsigned int S;
1219 unsigned int Rn;
1220 unsigned int Rd;
1221 unsigned int shifter_operand;
1222 shtop_fp_t shtop_func;
1223} rsc_inst;
1224
1225typedef struct _sbc_inst {
1226 unsigned int I;
1227 unsigned int S;
1228 unsigned int Rn;
1229 unsigned int Rd;
1230 unsigned int shifter_operand;
1231 shtop_fp_t shtop_func;
1232} sbc_inst;
1233
1234typedef struct _mul_inst {
1235 unsigned int S;
1236 unsigned int Rd;
1237 unsigned int Rs;
1238 unsigned int Rm;
1239} mul_inst;
1240
1241typedef struct _smul_inst {
1242 unsigned int Rd;
1243 unsigned int Rs;
1244 unsigned int Rm;
1245 unsigned int x;
1246 unsigned int y;
1247} smul_inst;
1248
1249typedef struct _umull_inst {
1250 unsigned int S;
1251 unsigned int RdHi;
1252 unsigned int RdLo;
1253 unsigned int Rs;
1254 unsigned int Rm;
1255} umull_inst;
1256typedef struct _smlad_inst {
1257 unsigned int m;
1258 unsigned int Rm;
1259 unsigned int Rd;
1260 unsigned int Ra;
1261 unsigned int Rn;
1262} smlad_inst;
1263
1264typedef struct _smla_inst {
1265 unsigned int x;
1266 unsigned int y;
1267 unsigned int Rm;
1268 unsigned int Rd;
1269 unsigned int Rs;
1270 unsigned int Rn;
1271} smla_inst;
1272
1273typedef struct _umlal_inst {
1274 unsigned int S;
1275 unsigned int Rm;
1276 unsigned int Rs;
1277 unsigned int RdHi;
1278 unsigned int RdLo;
1279} umlal_inst;
1280
1281typedef struct _smlal_inst {
1282 unsigned int S;
1283 unsigned int Rm;
1284 unsigned int Rs;
1285 unsigned int RdHi;
1286 unsigned int RdLo;
1287} smlal_inst;
1288
1289typedef struct _mla_inst {
1290 unsigned int S;
1291 unsigned int Rn;
1292 unsigned int Rd;
1293 unsigned int Rs;
1294 unsigned int Rm;
1295} mla_inst;
1296
1297typedef struct _mrc_inst {
1298 unsigned int opcode_1;
1299 unsigned int opcode_2;
1300 unsigned int cp_num;
1301 unsigned int crn;
1302 unsigned int crm;
1303 unsigned int Rd;
1304 unsigned int inst;
1305} mrc_inst;
1306
1307typedef struct _mcr_inst {
1308 unsigned int opcode_1;
1309 unsigned int opcode_2;
1310 unsigned int cp_num;
1311 unsigned int crn;
1312 unsigned int crm;
1313 unsigned int Rd;
1314 unsigned int inst;
1315} mcr_inst;
1316
1317typedef struct _mrs_inst {
1318 unsigned int R;
1319 unsigned int Rd;
1320} mrs_inst;
1321
1322typedef struct _msr_inst {
1323 unsigned int field_mask;
1324 unsigned int R;
1325 unsigned int inst;
1326} msr_inst;
1327
1328typedef struct _pld_inst {
1329} pld_inst;
1330
1331typedef struct _sxtb_inst {
1332 unsigned int Rd;
1333 unsigned int Rm;
1334 unsigned int rotate;
1335} sxtb_inst;
1336
1337typedef struct _sxtab_inst {
1338 unsigned int Rd;
1339 unsigned int Rn;
1340 unsigned int Rm;
1341 unsigned rotate;
1342} sxtab_inst;
1343
1344typedef struct _sxtah_inst {
1345 unsigned int Rd;
1346 unsigned int Rn;
1347 unsigned int Rm;
1348 unsigned int rotate;
1349} sxtah_inst;
1350
1351typedef struct _sxth_inst {
1352 unsigned int Rd;
1353 unsigned int Rm;
1354 unsigned int rotate;
1355} sxth_inst;
1356
1357typedef struct _uxtab_inst {
1358 unsigned int Rn;
1359 unsigned int Rd;
1360 unsigned int rotate;
1361 unsigned int Rm;
1362} uxtab_inst;
1363
1364typedef struct _uxtah_inst {
1365 unsigned int Rn;
1366 unsigned int Rd;
1367 unsigned int rotate;
1368 unsigned int Rm;
1369} uxtah_inst;
1370
1371typedef struct _uxth_inst {
1372 unsigned int Rd;
1373 unsigned int Rm;
1374 unsigned int rotate;
1375} uxth_inst;
1376
1377typedef struct _cdp_inst {
1378 unsigned int opcode_1;
1379 unsigned int CRn;
1380 unsigned int CRd;
1381 unsigned int cp_num;
1382 unsigned int opcode_2;
1383 unsigned int CRm;
1384 uint32 inst;
1385}cdp_inst;
1386
1387typedef struct _uxtb_inst {
1388 unsigned int Rd;
1389 unsigned int Rm;
1390 unsigned int rotate;
1391} uxtb_inst;
1392
1393typedef struct _swp_inst {
1394 unsigned int Rn;
1395 unsigned int Rd;
1396 unsigned int Rm;
1397} swp_inst;
1398
1399typedef struct _b_2_thumb {
1400 unsigned int imm;
1401}b_2_thumb;
1402typedef struct _b_cond_thumb {
1403 unsigned int imm;
1404 unsigned int cond;
1405}b_cond_thumb;
1406
1407typedef struct _bl_1_thumb {
1408 unsigned int imm;
1409}bl_1_thumb;
1410typedef struct _bl_2_thumb {
1411 unsigned int imm;
1412}bl_2_thumb;
1413typedef struct _blx_1_thumb {
1414 unsigned int imm;
1415 unsigned int instr;
1416}blx_1_thumb;
1417
1418typedef arm_inst * ARM_INST_PTR;
1419
1420#define CACHE_BUFFER_SIZE (64 * 1024 * 2000)
1421char inst_buf[CACHE_BUFFER_SIZE];
1422int top = 0;
1423inline void *AllocBuffer(unsigned int size)
1424{
1425 int start = top;
1426 top += size;
1427 if (top > CACHE_BUFFER_SIZE) {
1428 DEBUG_LOG(ARM11, "inst_buf is full\n");
1429 CITRA_IGNORE_EXIT(-1);
1430 }
1431 return (void *)&inst_buf[start];
1432}
1433
1434int CondPassed(arm_processor *cpu, unsigned int cond)
1435{
1436 #define NFLAG cpu->NFlag
1437 #define ZFLAG cpu->ZFlag
1438 #define CFLAG cpu->CFlag
1439 #define VFLAG cpu->VFlag
1440 int temp;
1441 switch (cond) {
1442 case 0x0:
1443 temp = ZFLAG;
1444 break;
1445 case 0x1: /* NE */
1446 temp = !ZFLAG;
1447 break;
1448 case 0x6: /* VS */
1449 temp = VFLAG;
1450 break;
1451 case 0x7: /* VC */
1452 temp = !VFLAG;
1453 break;
1454 case 0x4: /* MI */
1455 temp = NFLAG;
1456 break;
1457 case 0x5: /* PL */
1458 temp = !NFLAG;
1459 break;
1460 case 0x2: /* CS */
1461 temp = CFLAG;
1462 break;
1463 case 0x3: /* CC */
1464 temp = !CFLAG;
1465 break;
1466 case 0x8: /* HI */
1467 temp = (CFLAG && !ZFLAG);
1468 break;
1469 case 0x9: /* LS */
1470 temp = (!CFLAG || ZFLAG);
1471 break;
1472 case 0xa: /* GE */
1473 temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
1474 break;
1475 case 0xb: /* LT */
1476 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
1477 break;
1478 case 0xc: /* GT */
1479 temp = ((!NFLAG && !VFLAG && !ZFLAG)
1480 || (NFLAG && VFLAG && !ZFLAG));
1481 break;
1482 case 0xd: /* LE */
1483 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG))
1484 || ZFLAG;
1485 break;
1486 case 0xe: /* AL */
1487 temp = 1;
1488 break;
1489 case 0xf:
1490// DEBUG_LOG(ARM11, "inst is %x\n");
1491// DEBUG_LOG(ARM11, "icounter is %lld\n", cpu->icounter);
1492// CITRA_IGNORE_EXIT(-1);
1493 temp = 1;
1494 break;
1495 }
1496 return temp;
1497}
1498
1499enum DECODE_STATUS {
1500 DECODE_SUCCESS,
1501 DECODE_FAILURE
1502};
1503
1504int decode_arm_instr(uint32_t instr, int32_t *idx);
1505
1506shtop_fp_t get_shtop(unsigned int inst)
1507{
1508 if (BIT(inst, 25)) {
1509 return DPO(Immediate);
1510 } else if (BITS(inst, 4, 11) == 0) {
1511 return DPO(Register);
1512 } else if (BITS(inst, 4, 6) == 0) {
1513 return DPO(LogicalShiftLeftByImmediate);
1514 } else if (BITS(inst, 4, 7) == 1) {
1515 return DPO(LogicalShiftLeftByRegister);
1516 } else if (BITS(inst, 4, 6) == 2) {
1517 return DPO(LogicalShiftRightByImmediate);
1518 } else if (BITS(inst, 4, 7) == 3) {
1519 return DPO(LogicalShiftRightByRegister);
1520 } else if (BITS(inst, 4, 6) == 4) {
1521 return DPO(ArithmeticShiftRightByImmediate);
1522 } else if (BITS(inst, 4, 7) == 5) {
1523 return DPO(ArithmeticShiftRightByRegister);
1524 } else if (BITS(inst, 4, 6) == 6) {
1525 return DPO(RotateRightByImmediate);
1526 } else if (BITS(inst, 4, 7) == 7) {
1527 return DPO(RotateRightByRegister);
1528 }
1529 return NULL;
1530}
1531
1532get_addr_fp_t get_calc_addr_op(unsigned int inst)
1533{
1534 /* 1 */
1535 if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) {
1536// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1537 return LnSWoUB(ImmediateOffset);
1538 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
1539// DEBUG_MSG;
1540// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1541 return LnSWoUB(RegisterOffset);
1542 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
1543// DEBUG_MSG;
1544// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1545 return LnSWoUB(ScaledRegisterOffset);
1546 } else if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 1) {
1547// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1548 return LnSWoUB(ImmediatePreIndexed);
1549 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BITS(inst, 4, 11) == 0) {
1550 return LnSWoUB(RegisterPreIndexed);
1551 } else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 1 && BIT(inst, 4) == 0) {
1552 return LnSWoUB(ScaledRegisterPreIndexed);
1553 } else if (BITS(inst, 24, 27) == 4 && BIT(inst, 21) == 0) {
1554 return LnSWoUB(ImmediatePostIndexed);
1555 } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
1556// DEBUG_MSG;
1557 return LnSWoUB(RegisterPostIndexed);
1558 } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) {
1559 return LnSWoUB(ScaledRegisterPostIndexed);
1560// DEBUG_MSG;
1561 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1562 /* 2 */
1563// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1564 return MLnS(ImmediateOffset);
1565// DEBUG_MSG;
1566 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1567// DEBUG_LOG(ARM11, "line is %d\n", __LINE__);
1568 return MLnS(RegisterOffset);
1569// DEBUG_MSG;
1570 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1571// DEBUG_LOG(ARM11, "line is %d\n", __LINE__);
1572 return MLnS(ImmediatePreIndexed);
1573// DEBUG_MSG;
1574 } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1575 return MLnS(RegisterPreIndexed);
1576 } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1577// DEBUG_MSG;
1578 return MLnS(ImmediatePostIndexed);
1579 } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) {
1580 //DEBUG_MSG;
1581 return MLnS(RegisterPostIndexed);
1582 } else if (BITS(inst, 23, 27) == 0x11) {
1583 /* 3 */
1584// DEBUG_MSG;
1585// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1586 return LdnStM(IncrementAfter);
1587 } else if (BITS(inst, 23, 27) == 0x13) {
1588// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1589 return LdnStM(IncrementBefore);
1590// DEBUG_MSG;
1591 } else if (BITS(inst, 23, 27) == 0x10) {
1592// DEBUG_MSG;
1593// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1594 return LdnStM(DecrementAfter);
1595 } else if (BITS(inst, 23, 27) == 0x12) {
1596// DEBUG_MSG;
1597// DEBUG_LOG(ARM11, "line is %d", __LINE__);
1598 return LdnStM(DecrementBefore);
1599 }
1600 #if 0
1601 DEBUG_LOG(ARM11, "In %s Unknown addressing mode\n", __FUNCTION__);
1602 DEBUG_LOG(ARM11, "inst:%x\n", inst);
1603 CITRA_IGNORE_EXIT(-1);
1604 #endif
1605 return NULL;
1606}
1607
1608#define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s)
1609
1610#define CHECK_RN (inst_cream->Rn == 15)
1611#define CHECK_RM (inst_cream->Rm == 15)
1612#define CHECK_RS (inst_cream->Rs == 15)
1613
1614
1615ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index)
1616{
1617 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst));
1618 adc_inst *inst_cream = (adc_inst *)inst_base->component;
1619
1620 inst_base->cond = BITS(inst, 28, 31);
1621 inst_base->idx = index;
1622 inst_base->br = NON_BRANCH;
1623 inst_base->load_r15 = 0;
1624
1625 inst_cream->I = BIT(inst, 25);
1626 inst_cream->S = BIT(inst, 20);
1627 inst_cream->Rn = BITS(inst, 16, 19);
1628 inst_cream->Rd = BITS(inst, 12, 15);
1629 if (CHECK_RN)
1630 inst_base->load_r15 = 1;
1631 inst_cream->shifter_operand = BITS(inst, 0, 11);
1632 inst_cream->shtop_func = get_shtop(inst);
1633 if (inst_cream->Rd == 15) {
1634 inst_base->br = INDIRECT_BRANCH;
1635 }
1636 return inst_base;
1637}
1638ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index)
1639{
1640 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst));
1641 add_inst *inst_cream = (add_inst *)inst_base->component;
1642
1643 inst_base->cond = BITS(inst, 28, 31);
1644 inst_base->idx = index;
1645 inst_base->br = NON_BRANCH;
1646 inst_base->load_r15 = 0;
1647
1648 inst_cream->I = BIT(inst, 25);
1649 inst_cream->S = BIT(inst, 20);
1650 inst_cream->Rn = BITS(inst, 16, 19);
1651 inst_cream->Rd = BITS(inst, 12, 15);
1652 if (CHECK_RN)
1653 inst_base->load_r15 = 1;
1654 inst_cream->shifter_operand = BITS(inst, 0, 11);
1655 inst_cream->shtop_func = get_shtop(inst);
1656 if (inst_cream->Rd == 15) {
1657 inst_base->br = INDIRECT_BRANCH;
1658 }
1659 return inst_base;
1660}
1661ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index)
1662{
1663 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst));
1664 and_inst *inst_cream = (and_inst *)inst_base->component;
1665
1666 inst_base->cond = BITS(inst, 28, 31);
1667 inst_base->idx = index;
1668 inst_base->br = NON_BRANCH;
1669 inst_base->load_r15 = 0;
1670
1671 inst_cream->I = BIT(inst, 25);
1672 inst_cream->S = BIT(inst, 20);
1673 inst_cream->Rn = BITS(inst, 16, 19);
1674 inst_cream->Rd = BITS(inst, 12, 15);
1675 if (CHECK_RN)
1676 inst_base->load_r15 = 1;
1677 inst_cream->shifter_operand = BITS(inst, 0, 11);
1678 inst_cream->shtop_func = get_shtop(inst);
1679 if (inst_cream->Rd == 15)
1680 inst_base->br = INDIRECT_BRANCH;
1681 return inst_base;
1682}
1683ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index)
1684{
1685 #define POSBRANCH ((inst & 0x7fffff) << 2)
1686 #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2)
1687
1688 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst));
1689 bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
1690
1691 inst_base->cond = BITS(inst, 28, 31);
1692 inst_base->idx = index;
1693 inst_base->br = DIRECT_BRANCH;
1694
1695 if (BIT(inst, 24))
1696 inst_base->br = CALL;
1697 if (BITS(inst, 28, 31) <= 0xe)
1698 inst_base->br |= COND;
1699
1700 inst_cream->L = BIT(inst, 24);
1701 inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH;
1702
1703 return inst_base;
1704}
1705ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index)
1706{
1707 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst));
1708 bic_inst *inst_cream = (bic_inst *)inst_base->component;
1709
1710 inst_base->cond = BITS(inst, 28, 31);
1711 inst_base->idx = index;
1712 inst_base->br = NON_BRANCH;
1713 inst_base->load_r15 = 0;
1714
1715 inst_cream->I = BIT(inst, 25);
1716 inst_cream->S = BIT(inst, 20);
1717 inst_cream->Rn = BITS(inst, 16, 19);
1718 inst_cream->Rd = BITS(inst, 12, 15);
1719 if (CHECK_RN)
1720 inst_base->load_r15 = 1;
1721 inst_cream->shifter_operand = BITS(inst, 0, 11);
1722 inst_cream->shtop_func = get_shtop(inst);
1723
1724 if (inst_cream->Rd == 15)
1725 inst_base->br = INDIRECT_BRANCH;
1726 return inst_base;
1727}
1728ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
1729ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index)
1730{
1731 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst));
1732 blx_inst *inst_cream = (blx_inst *)inst_base->component;
1733
1734 inst_base->cond = BITS(inst, 28, 31);
1735 inst_base->idx = index;
1736 inst_base->br = INDIRECT_BRANCH;
1737
1738 inst_cream->inst = inst;
1739 if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
1740 inst_cream->val.Rm = BITS(inst, 0, 3);
1741 } else {
1742 inst_cream->val.signed_immed_24 = BITS(inst, 0, 23);
1743 //DEBUG_LOG(ARM11, " blx inst is %x\n", inst);
1744 //CITRA_IGNORE_EXIT(-1);
1745// DEBUG_MSG;
1746 }
1747
1748 return inst_base;
1749}
1750ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index)
1751{
1752 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst));
1753 bx_inst *inst_cream = (bx_inst *)inst_base->component;
1754
1755 inst_base->cond = BITS(inst, 28, 31);
1756 inst_base->idx = index;
1757 inst_base->br = INDIRECT_BRANCH;
1758
1759 inst_cream->Rm = BITS(inst, 0, 3);
1760
1761 return inst_base;
1762}
1763ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
1764ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){
1765 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst));
1766 cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
1767 inst_base->cond = BITS(inst, 28, 31);
1768 inst_base->idx = index;
1769 inst_base->br = NON_BRANCH;
1770 inst_base->load_r15 = 0;
1771
1772 inst_cream->CRm = BITS(inst, 0, 3);
1773 inst_cream->CRd = BITS(inst, 12, 15);
1774 inst_cream->CRn = BITS(inst, 16, 19);
1775 inst_cream->cp_num = BITS(inst, 8, 11);
1776 inst_cream->opcode_2 = BITS(inst, 5, 7);
1777 inst_cream->opcode_1 = BITS(inst, 20, 23);
1778 inst_cream->inst = inst;
1779
1780 DEBUG_LOG(ARM11, "in func %s inst %x index %x\n", __FUNCTION__, inst, index);
1781 return inst_base;
1782}
1783ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index)
1784{
1785 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst));
1786 inst_base->cond = BITS(inst, 28, 31);
1787 inst_base->idx = index;
1788 inst_base->br = NON_BRANCH;
1789
1790 return inst_base;
1791}
1792ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index)
1793{
1794 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst));
1795 clz_inst *inst_cream = (clz_inst *)inst_base->component;
1796
1797 inst_base->cond = BITS(inst, 28, 31);
1798 inst_base->idx = index;
1799 inst_base->br = NON_BRANCH;
1800 inst_base->load_r15 = 0;
1801
1802 inst_cream->Rm = BITS(inst, 0, 3);
1803 inst_cream->Rd = BITS(inst, 12, 15);
1804 if (CHECK_RM)
1805 inst_base->load_r15 = 1;
1806
1807 return inst_base;
1808}
1809ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index)
1810{
1811 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst));
1812 cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
1813
1814 inst_base->cond = BITS(inst, 28, 31);
1815 inst_base->idx = index;
1816 inst_base->br = NON_BRANCH;
1817 inst_base->load_r15 = 0;
1818
1819 inst_cream->I = BIT(inst, 25);
1820 //inst_cream->S = BIT(inst, 20);
1821 inst_cream->Rn = BITS(inst, 16, 19);
1822 //inst_cream->Rd = BITS(inst, 12, 15);
1823 if (CHECK_RN)
1824 inst_base->load_r15 = 1;
1825 inst_cream->shifter_operand = BITS(inst, 0, 11);
1826 inst_cream->shtop_func = get_shtop(inst);
1827 return inst_base;
1828}
1829ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index)
1830{
1831 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst));
1832 cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
1833
1834 inst_base->cond = BITS(inst, 28, 31);
1835 inst_base->idx = index;
1836 inst_base->br = NON_BRANCH;
1837 inst_base->load_r15 = 0;
1838
1839 inst_cream->I = BIT(inst, 25);
1840 inst_cream->Rn = BITS(inst, 16, 19);
1841 if (CHECK_RN)
1842 inst_base->load_r15 = 1;
1843 inst_cream->shifter_operand = BITS(inst, 0, 11);
1844 inst_cream->shtop_func = get_shtop(inst);
1845 return inst_base;
1846}
1847ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index)
1848{
1849 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst));
1850 cps_inst *inst_cream = (cps_inst *)inst_base->component;
1851
1852 inst_base->cond = BITS(inst, 28, 31);
1853 inst_base->idx = index;
1854 inst_base->br = NON_BRANCH;
1855
1856 inst_cream->imod0 = BIT(inst, 18);
1857 inst_cream->imod1 = BIT(inst, 19);
1858 inst_cream->mmod = BIT(inst, 17);
1859 inst_cream->A = BIT(inst, 8);
1860 inst_cream->I = BIT(inst, 7);
1861 inst_cream->F = BIT(inst, 6);
1862 inst_cream->mode = BITS(inst, 0, 4);
1863
1864 return inst_base;
1865}
1866ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index)
1867{
1868 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
1869 mov_inst *inst_cream = (mov_inst *)inst_base->component;
1870
1871 inst_base->cond = BITS(inst, 28, 31);
1872 inst_base->idx = index;
1873 inst_base->br = NON_BRANCH;
1874
1875 inst_cream->I = BIT(inst, 25);
1876 inst_cream->S = BIT(inst, 20);
1877 inst_cream->Rd = BITS(inst, 12, 15);
1878 inst_cream->shifter_operand = BITS(inst, 0, 11);
1879 inst_cream->shtop_func = get_shtop(inst);
1880
1881 if (inst_cream->Rd == 15) {
1882 inst_base->br = INDIRECT_BRANCH;
1883 }
1884 return inst_base;
1885}
1886ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index)
1887{
1888 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst));
1889 eor_inst *inst_cream = (eor_inst *)inst_base->component;
1890
1891 inst_base->cond = BITS(inst, 28, 31);
1892 inst_base->idx = index;
1893 inst_base->br = NON_BRANCH;
1894 inst_base->load_r15 = 0;
1895
1896 inst_cream->I = BIT(inst, 25);
1897 inst_cream->S = BIT(inst, 20);
1898 inst_cream->Rn = BITS(inst, 16, 19);
1899 inst_cream->Rd = BITS(inst, 12, 15);
1900 if (CHECK_RN)
1901 inst_base->load_r15 = 1;
1902 inst_cream->shifter_operand = BITS(inst, 0, 11);
1903 inst_cream->shtop_func = get_shtop(inst);
1904 if (inst_cream->Rd == 15) {
1905 inst_base->br = INDIRECT_BRANCH;
1906 }
1907 return inst_base;
1908}
1909ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index)
1910{
1911 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst));
1912 inst_base->cond = BITS(inst, 28, 31);
1913 inst_base->idx = index;
1914 inst_base->br = NON_BRANCH;
1915
1916 return inst_base;
1917}
1918ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index)
1919{
1920 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
1921 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
1922
1923 inst_base->cond = BITS(inst, 28, 31);
1924 inst_base->idx = index;
1925 inst_base->br = NON_BRANCH;
1926
1927 inst_cream->inst = inst;
1928 inst_cream->get_addr = get_calc_addr_op(inst);
1929
1930 if (BIT(inst, 15)) {
1931 inst_base->br = INDIRECT_BRANCH;
1932 }
1933 return inst_base;
1934}
1935ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index)
1936{
1937 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
1938 sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
1939
1940 inst_base->cond = BITS(inst, 28, 31);
1941 inst_base->idx = index;
1942 inst_base->br = NON_BRANCH;
1943 inst_base->load_r15 = 0;
1944
1945 inst_cream->Rd = BITS(inst, 12, 15);
1946 inst_cream->Rm = BITS(inst, 0, 3);
1947 inst_cream->rotate = BITS(inst, 10, 11);
1948 if (CHECK_RM)
1949 inst_base->load_r15 = 1;
1950
1951 return inst_base;
1952}
1953ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index)
1954{
1955 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
1956 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
1957
1958 inst_base->cond = BITS(inst, 28, 31);
1959 inst_base->idx = index;
1960 inst_base->br = NON_BRANCH;
1961 inst_base->load_r15 = 0;
1962
1963 inst_cream->inst = inst;
1964 inst_cream->get_addr = get_calc_addr_op(inst);
1965
1966 if (BITS(inst, 12, 15) == 15) {
1967 inst_base->br = INDIRECT_BRANCH;
1968 }
1969 return inst_base;
1970}
1971
1972ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index)
1973{
1974 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
1975 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
1976
1977 inst_base->cond = BITS(inst, 28, 31);
1978 inst_base->idx = index;
1979 inst_base->br = NON_BRANCH;
1980 inst_base->load_r15 = 0;
1981
1982 inst_cream->inst = inst;
1983 inst_cream->get_addr = get_calc_addr_op(inst);
1984
1985 if (BITS(inst, 12, 15) == 15) {
1986 inst_base->br = INDIRECT_BRANCH;
1987 }
1988 return inst_base;
1989}
1990
1991ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index)
1992{
1993 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
1994 uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
1995
1996 inst_base->cond = BITS(inst, 28, 31);
1997 inst_base->idx = index;
1998 inst_base->br = NON_BRANCH;
1999 inst_base->load_r15 = 0;
2000
2001 inst_cream->Rd = BITS(inst, 12, 15);
2002 inst_cream->rotate = BITS(inst, 10, 11);
2003 inst_cream->Rm = BITS(inst, 0, 3);
2004 if (CHECK_RM)
2005 inst_base->load_r15 = 1;
2006
2007 return inst_base;
2008}
2009ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index)
2010{
2011 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst));
2012 uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
2013
2014 inst_base->cond = BITS(inst, 28, 31);
2015 inst_base->idx = index;
2016 inst_base->br = NON_BRANCH;
2017 inst_base->load_r15 = 0;
2018
2019 inst_cream->Rn = BITS(inst, 16, 19);
2020 inst_cream->Rd = BITS(inst, 12, 15);
2021 inst_cream->rotate = BITS(inst, 10, 11);
2022 inst_cream->Rm = BITS(inst, 0, 3);
2023 if (CHECK_RM || CHECK_RN)
2024 inst_base->load_r15 = 1;
2025
2026 return inst_base;
2027}
2028ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index)
2029{
2030 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2031 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2032
2033 inst_base->cond = BITS(inst, 28, 31);
2034 inst_base->idx = index;
2035 inst_base->br = NON_BRANCH;
2036
2037 inst_cream->inst = inst;
2038 inst_cream->get_addr = get_calc_addr_op(inst);
2039
2040 if (BITS(inst, 12, 15) == 15) {
2041 inst_base->br = INDIRECT_BRANCH;
2042 }
2043 return inst_base;
2044}
2045ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index)
2046{
2047 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2048 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2049
2050 inst_base->cond = BITS(inst, 28, 31);
2051 inst_base->idx = index;
2052 inst_base->br = NON_BRANCH;
2053
2054 inst_cream->inst = inst;
2055 if (I_BIT == 0) {
2056 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
2057 } else {
2058 DEBUG_MSG;
2059 }
2060 #if 0
2061 inst_cream->get_addr = get_calc_addr_op(inst);
2062 if(inst == 0x54f13001) {
2063 DEBUG_LOG(ARM11, "get_calc_addr_op:%llx\n", inst_cream->get_addr);
2064 }
2065 #endif
2066
2067 if (BITS(inst, 12, 15) == 15) {
2068 inst_base->br = INDIRECT_BRANCH;
2069 }
2070 return inst_base;
2071}
2072ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index)
2073{
2074 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2075 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2076
2077 inst_base->cond = BITS(inst, 28, 31);
2078 inst_base->idx = index;
2079 inst_base->br = NON_BRANCH;
2080
2081 inst_cream->inst = inst;
2082 inst_cream->get_addr = get_calc_addr_op(inst);
2083
2084 return inst_base;
2085}
2086
2087ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index)
2088{
2089 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2090 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2091
2092 inst_base->cond = BITS(inst, 28, 31);
2093 inst_base->idx = index;
2094 inst_base->br = NON_BRANCH;
2095
2096 inst_cream->inst = inst;
2097 //inst_cream->get_addr = get_calc_addr_op(inst);
2098
2099 if (BITS(inst, 12, 15) == 15) {
2100 inst_base->br = INDIRECT_BRANCH;
2101 }
2102 return inst_base;
2103}
2104ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index)
2105{
2106 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2107 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2108
2109 inst_base->cond = BITS(inst, 28, 31);
2110 inst_base->idx = index;
2111 inst_base->br = NON_BRANCH;
2112
2113 inst_cream->inst = inst;
2114 inst_cream->get_addr = get_calc_addr_op(inst);
2115
2116 if (BITS(inst, 12, 15) == 15) {
2117 inst_base->br = INDIRECT_BRANCH;
2118 }
2119 return inst_base;
2120}
2121ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index)
2122{
2123 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2124 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2125
2126 inst_base->cond = BITS(inst, 28, 31);
2127 inst_base->idx = index;
2128 inst_base->br = NON_BRANCH;
2129
2130 inst_cream->inst = inst;
2131 inst_cream->get_addr = get_calc_addr_op(inst);
2132
2133 if (BITS(inst, 12, 15) == 15) {
2134 inst_base->br = INDIRECT_BRANCH;
2135 }
2136 return inst_base;
2137}
2138ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index)
2139{
2140 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2141 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2142
2143 inst_base->cond = BITS(inst, 28, 31);
2144 inst_base->idx = index;
2145 inst_base->br = NON_BRANCH;
2146
2147 inst_cream->inst = inst;
2148 inst_cream->get_addr = get_calc_addr_op(inst);
2149
2150 if (BITS(inst, 12, 15) == 15) {
2151 inst_base->br = INDIRECT_BRANCH;
2152 }
2153 return inst_base;
2154}
2155ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index)
2156{
2157 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2158 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2159
2160 inst_base->cond = BITS(inst, 28, 31);
2161 inst_base->idx = index;
2162 inst_base->br = NON_BRANCH;
2163
2164 inst_cream->inst = inst;
2165 inst_cream->get_addr = get_calc_addr_op(inst);
2166
2167 if (BITS(inst, 12, 15) == 15) {
2168 inst_base->br = INDIRECT_BRANCH;
2169 }
2170 return inst_base;
2171}
2172ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index)
2173{
2174 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2175 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2176
2177 inst_base->cond = BITS(inst, 28, 31);
2178 inst_base->idx = index;
2179 inst_base->br = NON_BRANCH;
2180
2181 inst_cream->inst = inst;
2182 if (I_BIT == 0) {
2183 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
2184 } else {
2185 DEBUG_MSG;
2186 }
2187
2188 if (BITS(inst, 12, 15) == 15) {
2189 inst_base->br = INDIRECT_BRANCH;
2190 }
2191 return inst_base;
2192}
2193ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index)
2194{
2195 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst));
2196 mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
2197 inst_base->cond = BITS(inst, 28, 31);
2198 inst_base->idx = index;
2199 inst_base->br = NON_BRANCH;
2200
2201 inst_cream->crn = BITS(inst, 16, 19);
2202 inst_cream->crm = BITS(inst, 0, 3);
2203 inst_cream->opcode_1 = BITS(inst, 21, 23);
2204 inst_cream->opcode_2 = BITS(inst, 5, 7);
2205 inst_cream->Rd = BITS(inst, 12, 15);
2206 inst_cream->cp_num = BITS(inst, 8, 11);
2207 inst_cream->inst = inst;
2208 return inst_base;
2209}
2210ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2211ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index)
2212{
2213 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst));
2214 mla_inst *inst_cream = (mla_inst *)inst_base->component;
2215
2216 inst_base->cond = BITS(inst, 28, 31);
2217 inst_base->idx = index;
2218 inst_base->br = NON_BRANCH;
2219 inst_base->load_r15 = 0;
2220
2221 inst_cream->S = BIT(inst, 20);
2222 inst_cream->Rn = BITS(inst, 12, 15);
2223 inst_cream->Rd = BITS(inst, 16, 19);
2224 inst_cream->Rs = BITS(inst, 8, 11);
2225 inst_cream->Rm = BITS(inst, 0, 3);
2226
2227 if (CHECK_RM || CHECK_RN || CHECK_RS)
2228 inst_base->load_r15 = 1;
2229
2230 return inst_base;
2231}
2232ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index)
2233{
2234 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
2235 mov_inst *inst_cream = (mov_inst *)inst_base->component;
2236
2237 inst_base->cond = BITS(inst, 28, 31);
2238 inst_base->idx = index;
2239 inst_base->br = NON_BRANCH;
2240
2241 inst_cream->I = BIT(inst, 25);
2242 inst_cream->S = BIT(inst, 20);
2243 inst_cream->Rd = BITS(inst, 12, 15);
2244 inst_cream->shifter_operand = BITS(inst, 0, 11);
2245 inst_cream->shtop_func = get_shtop(inst);
2246
2247 if (inst_cream->Rd == 15) {
2248 inst_base->br = INDIRECT_BRANCH;
2249 }
2250 return inst_base;
2251}
2252ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index)
2253{
2254 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst));
2255 mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
2256 inst_base->cond = BITS(inst, 28, 31);
2257 inst_base->idx = index;
2258 inst_base->br = NON_BRANCH;
2259
2260 inst_cream->crn = BITS(inst, 16, 19);
2261 inst_cream->crm = BITS(inst, 0, 3);
2262 inst_cream->opcode_1 = BITS(inst, 21, 23);
2263 inst_cream->opcode_2 = BITS(inst, 5, 7);
2264 inst_cream->Rd = BITS(inst, 12, 15);
2265 inst_cream->cp_num = BITS(inst, 8, 11);
2266 inst_cream->inst = inst;
2267 return inst_base;
2268}
2269ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2270ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index)
2271{
2272 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst));
2273 mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
2274
2275 inst_base->cond = BITS(inst, 28, 31);
2276 inst_base->idx = index;
2277 inst_base->br = NON_BRANCH;
2278
2279 inst_cream->Rd = BITS(inst, 12, 15);
2280 inst_cream->R = BIT(inst, 22);
2281
2282 return inst_base;
2283}
2284ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index)
2285{
2286 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst));
2287 msr_inst *inst_cream = (msr_inst *)inst_base->component;
2288
2289 inst_base->cond = BITS(inst, 28, 31);
2290 inst_base->idx = index;
2291 inst_base->br = NON_BRANCH;
2292
2293 inst_cream->field_mask = BITS(inst, 16, 19);
2294 inst_cream->R = BIT(inst, 22);
2295 inst_cream->inst = inst;
2296
2297 return inst_base;
2298}
2299ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index)
2300{
2301 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst));
2302 mul_inst *inst_cream = (mul_inst *)inst_base->component;
2303
2304 inst_base->cond = BITS(inst, 28, 31);
2305 inst_base->idx = index;
2306 inst_base->br = NON_BRANCH;
2307 inst_base->load_r15 = 0;
2308
2309 inst_cream->S = BIT(inst, 20);
2310 inst_cream->Rm = BITS(inst, 0, 3);
2311 inst_cream->Rs = BITS(inst, 8, 11);
2312 inst_cream->Rd = BITS(inst, 16, 19);
2313
2314 if (CHECK_RM || CHECK_RS)
2315 inst_base->load_r15 = 1;
2316 return inst_base;
2317}
2318ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index)
2319{
2320 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst));
2321 mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
2322
2323 inst_base->cond = BITS(inst, 28, 31);
2324 inst_base->idx = index;
2325 inst_base->br = NON_BRANCH;
2326
2327 inst_cream->I = BIT(inst, 25);
2328 inst_cream->S = BIT(inst, 20);
2329 inst_cream->Rd = BITS(inst, 12, 15);
2330 inst_cream->shifter_operand = BITS(inst, 0, 11);
2331 inst_cream->shtop_func = get_shtop(inst);
2332
2333 if (inst_cream->Rd == 15) {
2334 inst_base->br = INDIRECT_BRANCH;
2335 }
2336 return inst_base;
2337
2338}
2339ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index)
2340{
2341 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst));
2342 orr_inst *inst_cream = (orr_inst *)inst_base->component;
2343
2344 inst_base->cond = BITS(inst, 28, 31);
2345 inst_base->idx = index;
2346 inst_base->br = NON_BRANCH;
2347 inst_base->load_r15 = 0;
2348
2349 inst_cream->I = BIT(inst, 25);
2350 inst_cream->S = BIT(inst, 20);
2351 inst_cream->Rd = BITS(inst, 12, 15);
2352 inst_cream->Rn = BITS(inst, 16, 19);
2353 inst_cream->shifter_operand = BITS(inst, 0, 11);
2354 inst_cream->shtop_func = get_shtop(inst);
2355
2356 if (CHECK_RN)
2357 inst_base->load_r15 = 1;
2358 if (inst_cream->Rd == 15) {
2359 inst_base->br = INDIRECT_BRANCH;
2360 }
2361 return inst_base;
2362}
2363ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2364ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2365ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
2366{
2367 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst));
2368
2369 inst_base->cond = BITS(inst, 28, 31);
2370 inst_base->idx = index;
2371 inst_base->br = NON_BRANCH;
2372 inst_base->load_r15 = 0;
2373
2374 return inst_base;
2375}
2376ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2377ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2378ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2379ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2380ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2381ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2382ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2383ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2384ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2385ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2386ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index)
2387{
2388 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
2389 rev_inst *inst_cream = (rev_inst *)inst_base->component;
2390
2391 inst_base->cond = BITS(inst, 28, 31);
2392 inst_base->idx = index;
2393 inst_base->br = NON_BRANCH;
2394 inst_base->load_r15 = 0;
2395
2396 inst_cream->Rm = BITS(inst, 0, 3);
2397 inst_cream->Rd = BITS(inst, 12, 15);
2398
2399 return inst_base;
2400}
2401ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index){
2402 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
2403 rev_inst *inst_cream = (rev_inst *)inst_base->component;
2404
2405 inst_base->cond = BITS(inst, 28, 31);
2406 inst_base->idx = index;
2407 inst_base->br = NON_BRANCH;
2408 inst_base->load_r15 = 0;
2409
2410 inst_cream->Rm = BITS(inst, 0, 3);
2411 inst_cream->Rd = BITS(inst, 12, 15);
2412
2413 return inst_base;
2414}
2415ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2416ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2417ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index)
2418{
2419 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst));
2420 rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
2421
2422 inst_base->cond = BITS(inst, 28, 31);
2423 inst_base->idx = index;
2424 inst_base->br = NON_BRANCH;
2425 inst_base->load_r15 = 0;
2426
2427 inst_cream->I = BIT(inst, 25);
2428 inst_cream->S = BIT(inst, 20);
2429 inst_cream->Rn = BITS(inst, 16, 19);
2430 inst_cream->Rd = BITS(inst, 12, 15);
2431 inst_cream->shifter_operand = BITS(inst, 0, 11);
2432 inst_cream->shtop_func = get_shtop(inst);
2433 if (CHECK_RN)
2434 inst_base->load_r15 = 1;
2435
2436 if (inst_cream->Rd == 15) {
2437 inst_base->br = INDIRECT_BRANCH;
2438 }
2439 return inst_base;
2440}
2441ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index)
2442{
2443 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst));
2444 rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
2445
2446 inst_base->cond = BITS(inst, 28, 31);
2447 inst_base->idx = index;
2448 inst_base->br = NON_BRANCH;
2449 inst_base->load_r15 = 0;
2450
2451 inst_cream->I = BIT(inst, 25);
2452 inst_cream->S = BIT(inst, 20);
2453 inst_cream->Rn = BITS(inst, 16, 19);
2454 inst_cream->Rd = BITS(inst, 12, 15);
2455 inst_cream->shifter_operand = BITS(inst, 0, 11);
2456 inst_cream->shtop_func = get_shtop(inst);
2457 if (CHECK_RN)
2458 inst_base->load_r15 = 1;
2459
2460 if (inst_cream->Rd == 15) {
2461 inst_base->br = INDIRECT_BRANCH;
2462 }
2463 return inst_base;
2464}
2465ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2466ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2467ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2468ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index)
2469{
2470 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst));
2471 sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
2472
2473 inst_base->cond = BITS(inst, 28, 31);
2474 inst_base->idx = index;
2475 inst_base->br = NON_BRANCH;
2476 inst_base->load_r15 = 0;
2477
2478 inst_cream->I = BIT(inst, 25);
2479 inst_cream->S = BIT(inst, 20);
2480 inst_cream->Rn = BITS(inst, 16, 19);
2481 inst_cream->Rd = BITS(inst, 12, 15);
2482 inst_cream->shifter_operand = BITS(inst, 0, 11);
2483 inst_cream->shtop_func = get_shtop(inst);
2484 if (CHECK_RN)
2485 inst_base->load_r15 = 1;
2486
2487 if (inst_cream->Rd == 15) {
2488 inst_base->br = INDIRECT_BRANCH;
2489 }
2490 return inst_base;
2491}
2492ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2493ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2494ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2495ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2496ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2497ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2498ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2499ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2500ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index)
2501{
2502 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst));
2503 smla_inst *inst_cream = (smla_inst *)inst_base->component;
2504
2505 inst_base->cond = BITS(inst, 28, 31);
2506 inst_base->idx = index;
2507 inst_base->br = NON_BRANCH;
2508 inst_base->load_r15 = 0;
2509
2510 inst_cream->x = BIT(inst, 5);
2511 inst_cream->y = BIT(inst, 6);
2512 inst_cream->Rm = BITS(inst, 0, 3);
2513 inst_cream->Rs = BITS(inst, 8, 11);
2514 inst_cream->Rd = BITS(inst, 16, 19);
2515 inst_cream->Rn = BITS(inst, 12, 15);
2516
2517 return inst_base;
2518}
2519ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index){
2520 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
2521 smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
2522
2523 inst_base->cond = BITS(inst, 28, 31);
2524 inst_base->idx = index;
2525 inst_base->br = NON_BRANCH;
2526 inst_base->load_r15 = 0;
2527
2528 inst_cream->m = BIT(inst, 4);
2529 inst_cream->Rn = BITS(inst, 0, 3);
2530 inst_cream->Rm = BITS(inst, 8, 11);
2531 inst_cream->Rd = BITS(inst, 16, 19);
2532 inst_cream->Ra = BITS(inst, 12, 15);
2533
2534 if (CHECK_RM )
2535 inst_base->load_r15 = 1;
2536 return inst_base;
2537}
2538ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index)
2539{
2540 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
2541 umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
2542
2543 inst_base->cond = BITS(inst, 28, 31);
2544 inst_base->idx = index;
2545 inst_base->br = NON_BRANCH;
2546 inst_base->load_r15 = 0;
2547
2548 inst_cream->S = BIT(inst, 20);
2549 inst_cream->Rm = BITS(inst, 0, 3);
2550 inst_cream->Rs = BITS(inst, 8, 11);
2551 inst_cream->RdHi = BITS(inst, 16, 19);
2552 inst_cream->RdLo = BITS(inst, 12, 15);
2553
2554 if (CHECK_RM || CHECK_RS)
2555 inst_base->load_r15 = 1;
2556 return inst_base;
2557}
2558ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2559ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2560ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2561ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2562ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2563ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2564ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2565ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2566ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2567ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index)
2568{
2569 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst));
2570 smul_inst *inst_cream = (smul_inst *)inst_base->component;
2571
2572 inst_base->cond = BITS(inst, 28, 31);
2573 inst_base->idx = index;
2574 inst_base->br = NON_BRANCH;
2575 inst_base->load_r15 = 0;
2576
2577 inst_cream->Rd = BITS(inst, 16, 19);
2578 inst_cream->Rs = BITS(inst, 8, 11);
2579 inst_cream->Rm = BITS(inst, 0, 3);
2580
2581 inst_cream->x = BIT(inst, 5);
2582 inst_cream->y = BIT(inst, 6);
2583
2584 if (CHECK_RM || CHECK_RS)
2585 inst_base->load_r15 = 1;
2586 return inst_base;
2587
2588}
2589ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index)
2590{
2591 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
2592 umull_inst *inst_cream = (umull_inst *)inst_base->component;
2593
2594 inst_base->cond = BITS(inst, 28, 31);
2595 inst_base->idx = index;
2596 inst_base->br = NON_BRANCH;
2597 inst_base->load_r15 = 0;
2598
2599 inst_cream->S = BIT(inst, 20);
2600 inst_cream->Rm = BITS(inst, 0, 3);
2601 inst_cream->Rs = BITS(inst, 8, 11);
2602 inst_cream->RdHi = BITS(inst, 16, 19);
2603 inst_cream->RdLo = BITS(inst, 12, 15);
2604
2605 if (CHECK_RM || CHECK_RS)
2606 inst_base->load_r15 = 1;
2607 return inst_base;
2608}
2609
2610ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index)
2611{
2612 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
2613 smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
2614
2615 inst_base->cond = BITS(inst, 28, 31);
2616 inst_base->idx = index;
2617 inst_base->br = NON_BRANCH;
2618 inst_base->load_r15 = 0;
2619
2620 inst_cream->m = BIT(inst, 6);
2621 inst_cream->Rm = BITS(inst, 8, 11);
2622 inst_cream->Rn = BITS(inst, 0, 3);
2623 inst_cream->Rd = BITS(inst, 16, 19);
2624
2625 if (CHECK_RM || CHECK_RN)
2626 inst_base->load_r15 = 1;
2627 return inst_base;
2628}
2629ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2630ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2631ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2632ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2633ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2634ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2635ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2636ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index)
2637{
2638 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst));
2639 inst_base->cond = BITS(inst, 28, 31);
2640 inst_base->idx = index;
2641 inst_base->br = NON_BRANCH;
2642
2643 return inst_base;
2644}
2645ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index)
2646{
2647 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2648 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2649
2650 inst_base->cond = BITS(inst, 28, 31);
2651 inst_base->idx = index;
2652 inst_base->br = NON_BRANCH;
2653
2654 inst_cream->inst = inst;
2655 inst_cream->get_addr = get_calc_addr_op(inst);
2656 return inst_base;
2657}
2658ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index)
2659{
2660 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
2661 sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
2662
2663 inst_base->cond = BITS(inst, 28, 31);
2664 inst_base->idx = index;
2665 inst_base->br = NON_BRANCH;
2666 inst_base->load_r15 = 0;
2667
2668 inst_cream->Rd = BITS(inst, 12, 15);
2669 inst_cream->Rm = BITS(inst, 0, 3);
2670 inst_cream->rotate = BITS(inst, 10, 11);
2671
2672 if (CHECK_RM)
2673 inst_base->load_r15 = 1;
2674 return inst_base;
2675}
2676ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index)
2677{
2678 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2679 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2680
2681 inst_base->cond = BITS(inst, 28, 31);
2682 inst_base->idx = index;
2683 inst_base->br = NON_BRANCH;
2684
2685 inst_cream->inst = inst;
2686 inst_cream->get_addr = get_calc_addr_op(inst);
2687
2688 if (BITS(inst, 12, 15) == 15) {
2689 inst_base->br = INDIRECT_BRANCH;
2690 }
2691 return inst_base;
2692}
2693ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index)
2694{
2695 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
2696 uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
2697
2698 inst_base->cond = BITS(inst, 28, 31);
2699 inst_base->idx = index;
2700 inst_base->br = NON_BRANCH;
2701 inst_base->load_r15 = 0;
2702
2703 inst_cream->Rd = BITS(inst, 12, 15);
2704 inst_cream->rotate = BITS(inst, 10, 11);
2705 inst_cream->Rm = BITS(inst, 0, 3);
2706
2707 if (CHECK_RM)
2708 inst_base->load_r15 = 1;
2709 return inst_base;
2710}
2711ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index)
2712{
2713 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
2714 uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
2715
2716 inst_base->cond = BITS(inst, 28, 31);
2717 inst_base->idx = index;
2718 inst_base->br = NON_BRANCH;
2719 inst_base->load_r15 = 0;
2720
2721 inst_cream->Rd = BITS(inst, 12, 15);
2722 inst_cream->rotate = BITS(inst, 10, 11);
2723 inst_cream->Rm = BITS(inst, 0, 3);
2724 inst_cream->Rn = BITS(inst, 16, 19);
2725
2726 return inst_base;
2727}
2728ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index)
2729{
2730 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2731 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2732
2733 inst_base->cond = BITS(inst, 28, 31);
2734 inst_base->idx = index;
2735 inst_base->br = NON_BRANCH;
2736
2737 inst_cream->inst = inst;
2738 inst_cream->get_addr = get_calc_addr_op(inst);
2739
2740 if (BITS(inst, 12, 15) == 15) {
2741 inst_base->br = INDIRECT_BRANCH;
2742 }
2743 return inst_base;
2744}
2745ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index)
2746{
2747 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2748 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2749
2750 inst_base->cond = BITS(inst, 28, 31);
2751 inst_base->idx = index;
2752 inst_base->br = NON_BRANCH;
2753
2754 inst_cream->inst = inst;
2755// inst_cream->get_addr = get_calc_addr_op(inst);
2756 if (I_BIT == 0) {
2757 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
2758 } else {
2759 DEBUG_MSG;
2760 }
2761
2762 if (BITS(inst, 12, 15) == 15) {
2763 inst_base->br = INDIRECT_BRANCH;
2764 }
2765 return inst_base;
2766}
2767ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){
2768 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2769 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2770
2771 inst_base->cond = BITS(inst, 28, 31);
2772 inst_base->idx = index;
2773 inst_base->br = NON_BRANCH;
2774
2775 inst_cream->inst = inst;
2776 inst_cream->get_addr = get_calc_addr_op(inst);
2777
2778 if (BITS(inst, 12, 15) == 15) {
2779 inst_base->br = INDIRECT_BRANCH;
2780 }
2781 return inst_base;
2782}
2783ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index)
2784{
2785 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2786 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2787
2788 inst_base->cond = BITS(inst, 28, 31);
2789 inst_base->idx = index;
2790 inst_base->br = NON_BRANCH;
2791
2792 inst_cream->inst = inst;
2793 inst_cream->get_addr = get_calc_addr_op(inst);
2794
2795 if (BITS(inst, 12, 15) == 15) {
2796 inst_base->br = INDIRECT_BRANCH;
2797 }
2798 return inst_base;
2799}
2800ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index)
2801{
2802 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2803 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2804
2805 inst_base->cond = BITS(inst, 28, 31);
2806 inst_base->idx = index;
2807 inst_base->br = NON_BRANCH;
2808
2809 inst_cream->inst = inst;
2810 inst_cream->get_addr = get_calc_addr_op(inst);
2811
2812 if (BITS(inst, 12, 15) == 15) {
2813 inst_base->br = INDIRECT_BRANCH;
2814 }
2815 return inst_base;
2816}
2817ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index)
2818{
2819 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2820 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2821
2822 inst_base->cond = BITS(inst, 28, 31);
2823 inst_base->idx = index;
2824 inst_base->br = NON_BRANCH;
2825
2826 inst_cream->inst = inst;
2827 inst_cream->get_addr = get_calc_addr_op(inst);
2828
2829 if (BITS(inst, 12, 15) == 15) {
2830 inst_base->br = INDIRECT_BRANCH;
2831 }
2832 return inst_base;
2833}
2834ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index)
2835{
2836 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
2837 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
2838
2839 inst_base->cond = BITS(inst, 28, 31);
2840 inst_base->idx = index;
2841 inst_base->br = NON_BRANCH;
2842
2843 inst_cream->inst = inst;
2844 if (I_BIT == 0) {
2845 inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
2846 } else {
2847 DEBUG_MSG;
2848 }
2849
2850 if (BITS(inst, 12, 15) == 15) {
2851 inst_base->br = INDIRECT_BRANCH;
2852 }
2853 return inst_base;
2854}
2855ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index)
2856{
2857 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst));
2858 sub_inst *inst_cream = (sub_inst *)inst_base->component;
2859
2860 inst_base->cond = BITS(inst, 28, 31);
2861 inst_base->idx = index;
2862 inst_base->br = NON_BRANCH;
2863 inst_base->load_r15 = 0;
2864
2865 inst_cream->I = BIT(inst, 25);
2866 inst_cream->S = BIT(inst, 20);
2867 inst_cream->Rn = BITS(inst, 16, 19);
2868 inst_cream->Rd = BITS(inst, 12, 15);
2869 inst_cream->shifter_operand = BITS(inst, 0, 11);
2870 inst_cream->shtop_func = get_shtop(inst);
2871 if (inst_cream->Rd == 15) {
2872 inst_base->br = INDIRECT_BRANCH;
2873 }
2874 if (CHECK_RN)
2875 inst_base->load_r15 = 1;
2876
2877 return inst_base;
2878}
2879ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index)
2880{
2881 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst));
2882 swi_inst *inst_cream = (swi_inst *)inst_base->component;
2883
2884 inst_base->cond = BITS(inst, 28, 31);
2885 inst_base->idx = index;
2886 inst_base->br = NON_BRANCH;
2887
2888 inst_cream->num = BITS(inst, 0, 23);
2889 return inst_base;
2890}
2891ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index)
2892{
2893 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
2894 swp_inst *inst_cream = (swp_inst *)inst_base->component;
2895
2896 inst_base->cond = BITS(inst, 28, 31);
2897 inst_base->idx = index;
2898 inst_base->br = NON_BRANCH;
2899
2900 inst_cream->Rn = BITS(inst, 16, 19);
2901 inst_cream->Rd = BITS(inst, 12, 15);
2902 inst_cream->Rm = BITS(inst, 0, 3);
2903
2904 if (inst_cream->Rd == 15) {
2905 inst_base->br = INDIRECT_BRANCH;
2906 }
2907 return inst_base;
2908}
2909ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){
2910 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
2911 swp_inst *inst_cream = (swp_inst *)inst_base->component;
2912
2913 inst_base->cond = BITS(inst, 28, 31);
2914 inst_base->idx = index;
2915 inst_base->br = NON_BRANCH;
2916
2917 inst_cream->Rn = BITS(inst, 16, 19);
2918 inst_cream->Rd = BITS(inst, 12, 15);
2919 inst_cream->Rm = BITS(inst, 0, 3);
2920
2921 if (inst_cream->Rd == 15) {
2922 inst_base->br = INDIRECT_BRANCH;
2923 }
2924 return inst_base;
2925}
2926ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){
2927 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
2928 sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
2929
2930 inst_base->cond = BITS(inst, 28, 31);
2931 inst_base->idx = index;
2932 inst_base->br = NON_BRANCH;
2933 inst_base->load_r15 = 0;
2934
2935 inst_cream->Rd = BITS(inst, 12, 15);
2936 inst_cream->rotate = BITS(inst, 10, 11);
2937 inst_cream->Rm = BITS(inst, 0, 3);
2938 inst_cream->Rn = BITS(inst, 16, 19);
2939
2940 return inst_base;
2941}
2942ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2943ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){
2944 DEBUG_LOG(ARM11, "in func %s, SXTAH untested\n", __func__);
2945 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst));
2946 sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
2947
2948 inst_base->cond = BITS(inst, 28, 31);
2949 inst_base->idx = index;
2950 inst_base->br = NON_BRANCH;
2951 inst_base->load_r15 = 0;
2952
2953 inst_cream->Rd = BITS(inst, 12, 15);
2954 inst_cream->rotate = BITS(inst, 10, 11);
2955 inst_cream->Rm = BITS(inst, 0, 3);
2956 inst_cream->Rn = BITS(inst, 16, 19);
2957
2958 return inst_base;
2959}
2960ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
2961ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index)
2962{
2963 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst));
2964 teq_inst *inst_cream = (teq_inst *)inst_base->component;
2965
2966 inst_base->cond = BITS(inst, 28, 31);
2967 inst_base->idx = index;
2968 inst_base->br = NON_BRANCH;
2969 inst_base->load_r15 = 0;
2970
2971 inst_cream->I = BIT(inst, 25);
2972 inst_cream->Rn = BITS(inst, 16, 19);
2973 inst_cream->shifter_operand = BITS(inst, 0, 11);
2974 inst_cream->shtop_func = get_shtop(inst);
2975
2976 if (CHECK_RN)
2977 inst_base->load_r15 = 1;
2978 return inst_base;
2979}
2980ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index)
2981{
2982 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst));
2983 tst_inst *inst_cream = (tst_inst *)inst_base->component;
2984
2985 inst_base->cond = BITS(inst, 28, 31);
2986 inst_base->idx = index;
2987 inst_base->br = NON_BRANCH;
2988 inst_base->load_r15 = 0;
2989
2990 inst_cream->I = BIT(inst, 25);
2991 inst_cream->S = BIT(inst, 20);
2992 inst_cream->Rn = BITS(inst, 16, 19);
2993 inst_cream->Rd = BITS(inst, 12, 15);
2994 inst_cream->shifter_operand = BITS(inst, 0, 11);
2995 inst_cream->shtop_func = get_shtop(inst);
2996 if (inst_cream->Rd == 15) {
2997 inst_base->br = INDIRECT_BRANCH;
2998 }
2999
3000 if (CHECK_RN)
3001 inst_base->load_r15 = 1;
3002 return inst_base;
3003}
3004ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3005ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3006ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3007ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3008ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3009ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3010ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3011ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3012ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3013ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3014ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index)
3015{
3016 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
3017 umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
3018
3019 inst_base->cond = BITS(inst, 28, 31);
3020 inst_base->idx = index;
3021 inst_base->br = NON_BRANCH;
3022 inst_base->load_r15 = 0;
3023
3024 inst_cream->S = BIT(inst, 20);
3025 inst_cream->Rm = BITS(inst, 0, 3);
3026 inst_cream->Rs = BITS(inst, 8, 11);
3027 inst_cream->RdHi = BITS(inst, 16, 19);
3028 inst_cream->RdLo = BITS(inst, 12, 15);
3029
3030 if (CHECK_RM || CHECK_RS)
3031 inst_base->load_r15 = 1;
3032 return inst_base;
3033}
3034ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index)
3035{
3036 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
3037 umull_inst *inst_cream = (umull_inst *)inst_base->component;
3038
3039 inst_base->cond = BITS(inst, 28, 31);
3040 inst_base->idx = index;
3041 inst_base->br = NON_BRANCH;
3042 inst_base->load_r15 = 0;
3043
3044 inst_cream->S = BIT(inst, 20);
3045 inst_cream->Rm = BITS(inst, 0, 3);
3046 inst_cream->Rs = BITS(inst, 8, 11);
3047 inst_cream->RdHi = BITS(inst, 16, 19);
3048 inst_cream->RdLo = BITS(inst, 12, 15);
3049
3050 if (CHECK_RM || CHECK_RS)
3051 inst_base->load_r15 = 1;
3052 return inst_base;
3053}
3054
3055ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index)
3056{
3057 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb));
3058 b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
3059
3060 inst_cream->imm =((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0);
3061 //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
3062 inst_base->idx = index;
3063 inst_base->br = DIRECT_BRANCH;
3064 return inst_base;
3065}
3066
3067ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index)
3068{
3069 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb));
3070 b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
3071
3072 inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0));
3073 inst_cream->cond = ((tinst >> 8) & 0xf);
3074 //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x, cond=0x%x\n", __FUNCTION__, tinst, inst_cream->imm, inst_cream->cond);
3075 inst_base->idx = index;
3076 inst_base->br = DIRECT_BRANCH;
3077 return inst_base;
3078}
3079
3080ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index)
3081{
3082 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb));
3083 bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
3084
3085 inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0));
3086 //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
3087
3088 inst_base->idx = index;
3089 inst_base->br = NON_BRANCH;
3090 return inst_base;
3091}
3092ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index)
3093{
3094 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb));
3095 bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
3096
3097 inst_cream->imm = (tinst & 0x07FF) << 1;
3098 //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
3099 inst_base->idx = index;
3100 inst_base->br = DIRECT_BRANCH;
3101 return inst_base;
3102}
3103ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index)
3104{
3105 arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb));
3106 blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
3107
3108 inst_cream->imm = (tinst & 0x07FF) << 1;
3109 //DEBUG_LOG(ARM11, "In %s, tinst=0x%x, imm=0x%x\n", __FUNCTION__, tinst, inst_cream->imm);
3110 inst_cream->instr = tinst;
3111 inst_base->idx = index;
3112 inst_base->br = DIRECT_BRANCH;
3113 return inst_base;
3114}
3115
3116ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3117ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3118ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3119ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3120ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3121ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3122ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3123ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3124ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3125ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3126ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3127ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3128ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3129ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3130ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index){DEBUG_LOG(ARM11, "in func %s\n", __FUNCTION__);CITRA_IGNORE_EXIT(-1); return nullptr;}
3131
3132
3133
3134/* Floating point VFPv3 structures and instructions */
3135
3136#define VFP_INTERPRETER_STRUCT
3137#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
3138#undef VFP_INTERPRETER_STRUCT
3139
3140#define VFP_INTERPRETER_TRANS
3141#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
3142#undef VFP_INTERPRETER_TRANS
3143
3144
3145
3146typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
3147
3148const transop_fp_t arm_instruction_trans[] = {
3149 #define VFP_INTERPRETER_TABLE
3150 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
3151 #undef VFP_INTERPRETER_TABLE
3152 INTERPRETER_TRANSLATE(srs),
3153 INTERPRETER_TRANSLATE(rfe),
3154 INTERPRETER_TRANSLATE(bkpt),
3155 INTERPRETER_TRANSLATE(blx),
3156 INTERPRETER_TRANSLATE(cps),
3157 INTERPRETER_TRANSLATE(pld),
3158 INTERPRETER_TRANSLATE(setend),
3159 INTERPRETER_TRANSLATE(clrex),
3160 INTERPRETER_TRANSLATE(rev16),
3161 INTERPRETER_TRANSLATE(usad8),
3162 INTERPRETER_TRANSLATE(sxtb),
3163 INTERPRETER_TRANSLATE(uxtb),
3164 INTERPRETER_TRANSLATE(sxth),
3165 INTERPRETER_TRANSLATE(sxtb16),
3166 INTERPRETER_TRANSLATE(uxth),
3167 INTERPRETER_TRANSLATE(uxtb16),
3168 INTERPRETER_TRANSLATE(cpy),
3169 INTERPRETER_TRANSLATE(uxtab),
3170 INTERPRETER_TRANSLATE(ssub8),
3171 INTERPRETER_TRANSLATE(shsub8),
3172 INTERPRETER_TRANSLATE(ssubaddx),
3173 INTERPRETER_TRANSLATE(strex),
3174 INTERPRETER_TRANSLATE(strexb),
3175 INTERPRETER_TRANSLATE(swp),
3176 INTERPRETER_TRANSLATE(swpb),
3177 INTERPRETER_TRANSLATE(ssub16),
3178 INTERPRETER_TRANSLATE(ssat16),
3179 INTERPRETER_TRANSLATE(shsubaddx),
3180 INTERPRETER_TRANSLATE(qsubaddx),
3181 INTERPRETER_TRANSLATE(shaddsubx),
3182 INTERPRETER_TRANSLATE(shadd8),
3183 INTERPRETER_TRANSLATE(shadd16),
3184 INTERPRETER_TRANSLATE(sel),
3185 INTERPRETER_TRANSLATE(saddsubx),
3186 INTERPRETER_TRANSLATE(sadd8),
3187 INTERPRETER_TRANSLATE(sadd16),
3188 INTERPRETER_TRANSLATE(shsub16),
3189 INTERPRETER_TRANSLATE(umaal),
3190 INTERPRETER_TRANSLATE(uxtab16),
3191 INTERPRETER_TRANSLATE(usubaddx),
3192 INTERPRETER_TRANSLATE(usub8),
3193 INTERPRETER_TRANSLATE(usub16),
3194 INTERPRETER_TRANSLATE(usat16),
3195 INTERPRETER_TRANSLATE(usada8),
3196 INTERPRETER_TRANSLATE(uqsubaddx),
3197 INTERPRETER_TRANSLATE(uqsub8),
3198 INTERPRETER_TRANSLATE(uqsub16),
3199 INTERPRETER_TRANSLATE(uqaddsubx),
3200 INTERPRETER_TRANSLATE(uqadd8),
3201 INTERPRETER_TRANSLATE(uqadd16),
3202 INTERPRETER_TRANSLATE(sxtab),
3203 INTERPRETER_TRANSLATE(uhsubaddx),
3204 INTERPRETER_TRANSLATE(uhsub8),
3205 INTERPRETER_TRANSLATE(uhsub16),
3206 INTERPRETER_TRANSLATE(uhaddsubx),
3207 INTERPRETER_TRANSLATE(uhadd8),
3208 INTERPRETER_TRANSLATE(uhadd16),
3209 INTERPRETER_TRANSLATE(uaddsubx),
3210 INTERPRETER_TRANSLATE(uadd8),
3211 INTERPRETER_TRANSLATE(uadd16),
3212 INTERPRETER_TRANSLATE(sxtah),
3213 INTERPRETER_TRANSLATE(sxtab16),
3214 INTERPRETER_TRANSLATE(qadd8),
3215 INTERPRETER_TRANSLATE(bxj),
3216 INTERPRETER_TRANSLATE(clz),
3217 INTERPRETER_TRANSLATE(uxtah),
3218 INTERPRETER_TRANSLATE(bx),
3219 INTERPRETER_TRANSLATE(rev),
3220 INTERPRETER_TRANSLATE(blx),
3221 INTERPRETER_TRANSLATE(revsh),
3222 INTERPRETER_TRANSLATE(qadd),
3223 INTERPRETER_TRANSLATE(qadd16),
3224 INTERPRETER_TRANSLATE(qaddsubx),
3225 INTERPRETER_TRANSLATE(ldrex),
3226 INTERPRETER_TRANSLATE(qdadd),
3227 INTERPRETER_TRANSLATE(qdsub),
3228 INTERPRETER_TRANSLATE(qsub),
3229 INTERPRETER_TRANSLATE(ldrexb),
3230 INTERPRETER_TRANSLATE(qsub8),
3231 INTERPRETER_TRANSLATE(qsub16),
3232 INTERPRETER_TRANSLATE(smuad),
3233 INTERPRETER_TRANSLATE(smmul),
3234 INTERPRETER_TRANSLATE(smusd),
3235 INTERPRETER_TRANSLATE(smlsd),
3236 INTERPRETER_TRANSLATE(smlsld),
3237 INTERPRETER_TRANSLATE(smmla),
3238 INTERPRETER_TRANSLATE(smmls),
3239 INTERPRETER_TRANSLATE(smlald),
3240 INTERPRETER_TRANSLATE(smlad),
3241 INTERPRETER_TRANSLATE(smlaw),
3242 INTERPRETER_TRANSLATE(smulw),
3243 INTERPRETER_TRANSLATE(pkhtb),
3244 INTERPRETER_TRANSLATE(pkhbt),
3245 INTERPRETER_TRANSLATE(smul),
3246 INTERPRETER_TRANSLATE(smlalxy),
3247 INTERPRETER_TRANSLATE(smla),
3248 INTERPRETER_TRANSLATE(mcrr),
3249 INTERPRETER_TRANSLATE(mrrc),
3250 INTERPRETER_TRANSLATE(cmp),
3251 INTERPRETER_TRANSLATE(tst),
3252 INTERPRETER_TRANSLATE(teq),
3253 INTERPRETER_TRANSLATE(cmn),
3254 INTERPRETER_TRANSLATE(smull),
3255 INTERPRETER_TRANSLATE(umull),
3256 INTERPRETER_TRANSLATE(umlal),
3257 INTERPRETER_TRANSLATE(smlal),
3258 INTERPRETER_TRANSLATE(mul),
3259 INTERPRETER_TRANSLATE(mla),
3260 INTERPRETER_TRANSLATE(ssat),
3261 INTERPRETER_TRANSLATE(usat),
3262 INTERPRETER_TRANSLATE(mrs),
3263 INTERPRETER_TRANSLATE(msr),
3264 INTERPRETER_TRANSLATE(and),
3265 INTERPRETER_TRANSLATE(bic),
3266 INTERPRETER_TRANSLATE(ldm),
3267 INTERPRETER_TRANSLATE(eor),
3268 INTERPRETER_TRANSLATE(add),
3269 INTERPRETER_TRANSLATE(rsb),
3270 INTERPRETER_TRANSLATE(rsc),
3271 INTERPRETER_TRANSLATE(sbc),
3272 INTERPRETER_TRANSLATE(adc),
3273 INTERPRETER_TRANSLATE(sub),
3274 INTERPRETER_TRANSLATE(orr),
3275 INTERPRETER_TRANSLATE(mvn),
3276 INTERPRETER_TRANSLATE(mov),
3277 INTERPRETER_TRANSLATE(stm),
3278 INTERPRETER_TRANSLATE(ldm),
3279 INTERPRETER_TRANSLATE(ldrsh),
3280 INTERPRETER_TRANSLATE(stm),
3281 INTERPRETER_TRANSLATE(ldm),
3282 INTERPRETER_TRANSLATE(ldrsb),
3283 INTERPRETER_TRANSLATE(strd),
3284 INTERPRETER_TRANSLATE(ldrh),
3285 INTERPRETER_TRANSLATE(strh),
3286 INTERPRETER_TRANSLATE(ldrd),
3287 INTERPRETER_TRANSLATE(strt),
3288 INTERPRETER_TRANSLATE(strbt),
3289 INTERPRETER_TRANSLATE(ldrbt),
3290 INTERPRETER_TRANSLATE(ldrt),
3291 INTERPRETER_TRANSLATE(mrc),
3292 INTERPRETER_TRANSLATE(mcr),
3293 INTERPRETER_TRANSLATE(msr),
3294 INTERPRETER_TRANSLATE(ldrb),
3295 INTERPRETER_TRANSLATE(strb),
3296 INTERPRETER_TRANSLATE(ldr),
3297 INTERPRETER_TRANSLATE(ldrcond),
3298 INTERPRETER_TRANSLATE(str),
3299 INTERPRETER_TRANSLATE(cdp),
3300 INTERPRETER_TRANSLATE(stc),
3301 INTERPRETER_TRANSLATE(ldc),
3302 INTERPRETER_TRANSLATE(swi),
3303 INTERPRETER_TRANSLATE(bbl),
3304 /* All the thumb instructions should be placed the end of table */
3305 INTERPRETER_TRANSLATE(b_2_thumb),
3306 INTERPRETER_TRANSLATE(b_cond_thumb),
3307 INTERPRETER_TRANSLATE(bl_1_thumb),
3308 INTERPRETER_TRANSLATE(bl_2_thumb),
3309 INTERPRETER_TRANSLATE(blx_1_thumb)
3310};
3311
3312typedef map<unsigned int, int> bb_map;
3313bb_map CreamCache[65536];
3314bb_map ProfileCache[65536];
3315
3316//#define USE_DUMMY_CACHE
3317
3318#ifdef USE_DUMMY_CACHE
3319unsigned int DummyCache[0x100000];
3320#endif
3321
3322#define HASH(x) ((x + (x << 3) + (x >> 6)) % 65536)
3323void insert_bb(unsigned int addr, int start)
3324{
3325#ifdef USE_DUMMY_CACHE
3326 DummyCache[addr] = start;
3327#else
3328// CreamCache[addr] = start;
3329 CreamCache[HASH(addr)][addr] = start;
3330#endif
3331}
3332
3333#define TRANS_THRESHOLD 65000
3334int find_bb(unsigned int addr, int &start)
3335{
3336 int ret = -1;
3337#ifdef USE_DUMMY_CACHE
3338 start = DummyCache[addr];
3339 if (start) {
3340 ret = 0;
3341 } else
3342 ret = -1;
3343#else
3344 bb_map::const_iterator it = CreamCache[HASH(addr)].find(addr);
3345 if (it != CreamCache[HASH(addr)].end()) {
3346 start = static_cast<int>(it->second);
3347 ret = 0;
3348#if HYBRID_MODE
3349#if PROFILE
3350#else
3351 /* increase the bb counter */
3352 if(get_bb_prof(cpu, addr, 1) == TRANS_THRESHOLD){
3353 push_to_compiled(cpu, addr);
3354 }
3355#endif
3356#endif
3357 } else {
3358 ret = -1;
3359 }
3360#endif
3361 return ret;
3362}
3363
3364
3365enum {
3366 FETCH_SUCCESS,
3367 FETCH_FAILURE
3368};
3369static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr, uint32_t *arm_inst, uint32_t* inst_size, ARM_INST_PTR* ptr_inst_base){
3370 /* Check if in Thumb mode. */
3371 tdstate ret;
3372 ret = thumb_translate (addr, inst, arm_inst, inst_size);
3373 if(ret == t_branch){
3374 /* FIXME, endian should be judged */
3375 uint32 tinstr;
3376 if((addr & 0x3) != 0)
3377 tinstr = inst >> 16;
3378 else
3379 tinstr = inst & 0xFFFF;
3380
3381 //tinstr = inst & 0xFFFF;
3382 int inst_index;
3383 /* table_length */
3384 int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
3385
3386 switch((tinstr & 0xF800) >> 11){
3387 /* we will translate the thumb instruction directly here */
3388 /* we will translate the thumb instruction directly here */
3389 case 26:
3390 case 27:
3391 if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){
3392 uint32 cond = (tinstr & 0x0F00) >> 8;
3393 inst_index = table_length - 4;
3394 //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index);
3395 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3396 }
3397 else{
3398 /* something wrong */
3399 DEBUG_LOG(ARM11, "In %s, thumb decoder error\n", __FUNCTION__);
3400 }
3401 break;
3402 case 28:
3403 /* Branch 2, unconditional branch */
3404 inst_index = table_length - 5;
3405 //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d\n", __FUNCTION__, tinstr, inst_index);
3406 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3407 break;
3408
3409 case 8:
3410 case 29:
3411 /* For BLX 1 thumb instruction*/
3412 inst_index = table_length - 1;
3413 //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, blx 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc);
3414 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3415 break;
3416 case 30:
3417 /* For BL 1 thumb instruction*/
3418 inst_index = table_length - 3;
3419 //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 1 thumb index=%d, pc=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc);
3420 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3421 break;
3422 case 31:
3423 /* For BL 2 thumb instruction*/
3424 inst_index = table_length - 2;
3425 //DEBUG_LOG(ARM11, "In %s, tinstr=0x%x, bl 2 thumb index=%d, px=0x%x\n", __FUNCTION__, tinstr, inst_index, cpu->translate_pc);
3426 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3427 break;
3428 default:
3429 ret = t_undefined;
3430 break;
3431 }
3432 }
3433 return ret;
3434}
3435
3436#if 0
3437int FetchInst(cpu_t *core, unsigned int &inst)
3438{
3439 //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
3440 arm_processor *cpu = (arm_processor *)(core->cpu_data->obj);
3441// fault_t fault = interpreter_read_memory(cpu->translate_pc, inst, 32);
3442 fault_t fault = interpreter_fetch(core, cpu->translate_pc, inst, 32);
3443 if (!core->is_user_mode) {
3444 if (fault) {
3445 cpu->abortSig = true;
3446 cpu->Aborted = ARMul_PrefetchAbortV;
3447 cpu->AbortAddr = cpu->translate_pc;
3448 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
3449 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->translate_pc;
3450 return FETCH_FAILURE;
3451 }
3452 }
3453 return FETCH_SUCCESS;
3454}
3455#endif
3456
3457unsigned int *InstLength;
3458
3459enum {
3460 KEEP_GOING,
3461 FETCH_EXCEPTION
3462};
3463
3464typedef struct instruction_set_encoding_item ISEITEM;
3465
3466extern const ISEITEM arm_instruction[];
3467
3468vector<uint64_t> code_page_set;
3469
3470void flush_bb(uint32_t addr)
3471{
3472 bb_map::iterator it;
3473 uint32_t start;
3474
3475 addr &= 0xfffff000;
3476 for (int i = 0; i < 65536; i ++) {
3477 for (it = CreamCache[i].begin(); it != CreamCache[i].end(); ) {
3478 start = static_cast<uint32_t>(it->first);
3479 //start = (start >> 12) << 12;
3480 start &= 0xfffff000;
3481 if (start == addr) {
3482 //DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first));
3483 CreamCache[i].erase(it ++);
3484 } else
3485 ++it;
3486 }
3487 }
3488
3489 for (int i = 0; i < 65536; i ++) {
3490 for (it = ProfileCache[i].begin(); it != ProfileCache[i].end(); ) {
3491 start = static_cast<uint32_t>(it->first);
3492 //start = (start >> 12) << 12;
3493 start &= 0xfffff000;
3494 if (start == addr) {
3495 //DEBUG_LOG(ARM11, "[ERASE][0x%08x]\n", static_cast<int>(it->first));
3496 ProfileCache[i].erase(it ++);
3497 } else
3498 ++it;
3499 }
3500 }
3501
3502 //DEBUG_LOG(ARM11, "flush bb @ %x\n", addr);
3503}
3504
3505//static uint32_t get_bank_addr(void *addr)
3506//{
3507// uint64_t address = (uint64_t)addr;
3508// uint64_t bank0 = get_dma_addr(BANK0_START);
3509// if ((address >= bank0) && (address < (bank0 + BANK0_SIZE))) {
3510// //DEBUG_LOG(ARM11, "1.addr is %llx\n", addr);
3511// return ((uint64_t)addr - bank0) + BANK0_START;
3512// }
3513// return 0;
3514//}
3515
3516/* shenoubang add win32 2012-6-12 */
3517//#ifndef __WIN32__
3518//static void flush_code_cache(int signal_number, siginfo_t *si, void *unused)
3519//{
3520// DEBUG_LOG(ARM11, "in %s, addr=0x%llx\n", __FUNCTION__, si->si_addr);
3521// uint64_t addr = (uint64_t)si->si_addr;
3522// addr = (addr >> 12) << 12;
3523// skyeye_backtrace();
3524// #if 0
3525// if (addr == 0) {
3526// return;
3527// }
3528// const vector<uint64_t>::iterator it = find(code_page_set.begin(),
3529// code_page_set.end(),
3530// (uint64_t)addr);
3531// if (it != code_page_set.end()) {
3532// code_page_set.erase(it);
3533// }
3534// mprotect((void *)addr, 4096, PROT_READ | PROT_WRITE);
3535// //DEBUG_LOG(ARM11, "[flush][ADDR:0x%08llx]\n", addr);
3536// uint32_t phys_addr = get_bank_addr((void *)addr);
3537//// DEBUG_LOG(ARM11, "[PHYSICAL][ADDR:0x%08llx]\n", phys_addr);
3538// flush_bb(phys_addr);
3539// flush_bb(phys_addr + 4096);
3540//#if HYBRID_MODE
3541// /* flush the translated BB of dyncom */
3542// clear_translated_cache(phys_addr);
3543//#endif
3544// #endif
3545//}
3546//#endif /* shenoubang */
3547
3548//void protect_code_page(uint32_t addr)
3549//{
3550// void *mem_ptr = (void *)get_dma_addr(addr);
3551// mem_ptr = (void *)((long long int)mem_ptr & 0xfffffffffffff000LL);
3552//
3553// const vector<uint64_t>::iterator it = find(code_page_set.begin(),
3554// code_page_set.end(),
3555// (uint64_t)mem_ptr);
3556// if (it != code_page_set.end()) {
3557// return;
3558// }
3559// //DEBUG_LOG(ARM11, "[mprotect][ADDR:0x%08llx]\n", mem_ptr);
3560// /* shenoubang add win32 2012-6-12 */
3561//#ifndef __WIN32__
3562// struct sigaction sa;
3563//
3564// memset(&sa, 0, sizeof(sa));
3565// sa.sa_flags = SA_RESTART | SA_SIGINFO;
3566// sa.sa_sigaction = &flush_code_cache;
3567// sigaction(SIGSEGV, &sa, NULL);
3568//
3569// //mprotect(mem_ptr, 4096, PROT_READ);
3570//
3571// code_page_set.push_back((uint64_t)mem_ptr);
3572//#endif /* shenoubang */
3573//}
3574
3575
3576
3577int InterpreterTranslate(arm_processor *cpu, int &bb_start, addr_t addr)
3578{
3579 /* Decode instruction, get index */
3580 /* Allocate memory and init InsCream */
3581 /* Go on next, until terminal instruction */
3582 /* Save start addr of basicblock in CreamCache */
3583 //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
3584 //arm_processor *cpu = (arm_processor *)(core->cpu_data->obj);
3585 ARM_INST_PTR inst_base = NULL;
3586 unsigned int inst, inst_size = 4;
3587 int idx;
3588 int ret = NON_BRANCH;
3589 int thumb = 0;
3590 /* instruction size of basic block */
3591 int size = 0;
3592 /* (R15 - 8) ? */
3593 //cpu->translate_pc = cpu->Reg[15];
3594 bb_start = top;
3595
3596 if (cpu->TFlag)
3597 thumb = THUMB;
3598
3599 addr_t phys_addr;
3600 addr_t pc_start;
3601 fault_t fault = NO_FAULT;
3602 //fault = check_address_validity(cpu, addr, &phys_addr, 1, INSN_TLB);
3603 fault = check_address_validity(cpu, addr, &phys_addr, 1);
3604 if(fault != NO_FAULT){
3605 cpu->abortSig = true;
3606 cpu->Aborted = ARMul_PrefetchAbortV;
3607 cpu->AbortAddr = addr;
3608 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
3609 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr;
3610 return FETCH_EXCEPTION;
3611 }
3612 pc_start = phys_addr;
3613 //phys_addr = get_dma_addr(phys_addr);
3614 while(ret == NON_BRANCH) {
3615 /* shenoubang add win32 2012-6-14 */
3616#ifdef __WIN32__
3617 mem_bank_t* bank;
3618 if (bank = bank_ptr(addr)) {
3619 bank->bank_read(32, phys_addr, &inst);
3620 }
3621 else {
3622 DEBUG_LOG(ARM11, "SKYEYE: Read physical addr 0x%x error!!\n", phys_addr);
3623 return FETCH_FAILURE;
3624 }
3625#else
3626 inst = Memory::Read32(phys_addr & 0xFFFFFFFC);//*(uint32_t *)(phys_addr & 0xFFFFFFFC);
3627#endif
3628 //or_tag(core, phys_addr, TAG_FAST_INTERP);
3629
3630 /*if (ret == FETCH_FAILURE) {
3631 return FETCH_EXCEPTION;
3632 }*/
3633
3634 size ++;
3635 /* If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction */
3636 if (cpu->TFlag){
3637 //if(cpu->Cpsr & (1 << THUMB_BIT)){
3638 uint32_t arm_inst;
3639 tdstate state;
3640 state = decode_thumb_instr(cpu, inst, phys_addr, &arm_inst, &inst_size, &inst_base);
3641 //or_tag(core, phys_addr, TAG_THUMB);
3642 //DEBUG_LOG(ARM11, "In thumb state, arm_inst=0x%x, inst_size=0x%x, pc=0x%x\n", arm_inst, inst_size, cpu->translate_pc);
3643 /* we have translated the branch instruction of thumb in thumb decoder */
3644 if(state == t_branch){
3645 goto translated;
3646 }
3647 inst = arm_inst;
3648 }
3649
3650 ret = decode_arm_instr(inst, &idx);
3651 if (ret == DECODE_FAILURE) {
3652 DEBUG_LOG(ARM11, "[info] : Decode failure.\tPC : [0x%x]\tInstruction : [%x]\n", phys_addr, inst);
3653 DEBUG_LOG(ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x\n", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]);
3654 CITRA_IGNORE_EXIT(-1);
3655 }
3656// DEBUG_LOG(ARM11, "PC : [0x%x] INST : %s\n", cpu->translate_pc, arm_instruction[idx].name);
3657 inst_base = arm_instruction_trans[idx](inst, idx);
3658// DEBUG_LOG(ARM11, "translated @ %x INST : %x\n", cpu->translate_pc, inst);
3659// DEBUG_LOG(ARM11, "inst size is %d\n", InstLength[idx]);
3660translated:
3661 phys_addr += inst_size;
3662
3663 if ((phys_addr & 0xfff) == 0) {
3664 inst_base->br = END_OF_PAGE;
3665 }
3666 ret = inst_base->br;
3667 };
3668
3669 //DEBUG_LOG(ARM11, "In %s,insert_bb pc=0x%x, TFlag=0x%x\n", __FUNCTION__, pc_start, cpu->TFlag);
3670 insert_bb(pc_start, bb_start);
3671 return KEEP_GOING;
3672}
3673
3674#define LOG_IN_CLR skyeye_printf_in_color
3675
3676int cmp(const void *x, const void *y)
3677{
3678 return *(unsigned long long int*)x - *(unsigned long long int *)y;
3679}
3680
3681void InterpreterInitInstLength(unsigned long long int *ptr, size_t size)
3682{
3683 int array_size = size / sizeof(void *);
3684 unsigned long long int *InstLabel = new unsigned long long int[array_size];
3685 memcpy(InstLabel, ptr, size);
3686 qsort(InstLabel, array_size, sizeof(void *), cmp);
3687 InstLength = new unsigned int[array_size - 4];
3688 for (int i = 0; i < array_size - 4; i ++) {
3689 for (int j = 0; j < array_size; j ++) {
3690 if (ptr[i] == InstLabel[j]) {
3691 InstLength[i] = InstLabel[j + 1] - InstLabel[j];
3692 break;
3693 }
3694 }
3695 }
3696 for (int i = 0; i < array_size - 4; i ++)
3697 DEBUG_LOG(ARM11, "[%d]:%d\n", i, InstLength[i]);
3698}
3699
3700int clz(unsigned int x)
3701{
3702 int n;
3703 if (x == 0) return (32);
3704 n = 1;
3705 if ((x >> 16) == 0) { n = n + 16; x = x << 16;}
3706 if ((x >> 24) == 0) { n = n + 8; x = x << 8;}
3707 if ((x >> 28) == 0) { n = n + 4; x = x << 4;}
3708 if ((x >> 30) == 0) { n = n + 2; x = x << 2;}
3709 n = n - (x >> 31);
3710 return n;
3711}
3712
3713unsigned arm_dyncom_SWI (ARMul_State * state, ARMword number);
3714
3715static bool InAPrivilegedMode(arm_core_t *core)
3716{
3717 return (core->Mode != USER32MODE);
3718}
3719
3720/* r15 = r15 + 8 */
3721void InterpreterMainLoop(ARMul_State* state)
3722{
3723 #define CRn inst_cream->crn
3724 #define OPCODE_2 inst_cream->opcode_2
3725 #define CRm inst_cream->crm
3726 #define CP15_REG(n) cpu->CP15[CP15(n)]
3727 #define RD cpu->Reg[inst_cream->Rd]
3728 #define RN cpu->Reg[inst_cream->Rn]
3729 #define RM cpu->Reg[inst_cream->Rm]
3730 #define RS cpu->Reg[inst_cream->Rs]
3731 #define RDHI cpu->Reg[inst_cream->RdHi]
3732 #define RDLO cpu->Reg[inst_cream->RdLo]
3733 #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4)
3734 #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24)
3735 #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand)
3736
3737 #if ENABLE_ICOUNTER
3738 #define INC_ICOUNTER cpu->icounter++; \
3739 if(cpu->Reg[15] > 0xc0000000) \
3740 cpu->kernel_icounter++;
3741 //if (debug_function(core)) \
3742 if (core->check_int_flag) \
3743 goto END
3744 //DEBUG_LOG(ARM11, "icounter is %llx line is %d pc is %x\n", cpu->icounter, __LINE__, cpu->Reg[15])
3745 #else
3746 #define INC_ICOUNTER ;
3747 #endif
3748
3749 #define FETCH_INST if (inst_base->br != NON_BRANCH) \
3750 goto PROFILING; \
3751 inst_base = (arm_inst *)&inst_buf[ptr]
3752#define INC_PC(l) ptr += sizeof(arm_inst) + l
3753
3754// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a
3755// clunky switch statement.
3756#if defined __GNUC__ || defined __clang__
3757#define GOTO_NEXT_INST goto *InstLabel[inst_base->idx]
3758#else
3759#define GOTO_NEXT_INST switch(inst_base->idx) { \
3760 case 0: goto VMLA_INST; \
3761 case 1: goto VMLS_INST; \
3762 case 2: goto VNMLA_INST; \
3763 case 3: goto VNMLA_INST; \
3764 case 4: goto VNMLS_INST; \
3765 case 5: goto VNMUL_INST; \
3766 case 6: goto VMUL_INST; \
3767 case 7: goto VADD_INST; \
3768 case 8: goto VSUB_INST; \
3769 case 9: goto VDIV_INST; \
3770 case 10: goto VMOVI_INST; \
3771 case 11: goto VMOVR_INST; \
3772 case 12: goto VABS_INST; \
3773 case 13: goto VNEG_INST; \
3774 case 14: goto VSQRT_INST; \
3775 case 15: goto VCMP_INST; \
3776 case 16: goto VCMP2_INST; \
3777 case 17: goto VCVTBDS_INST; \
3778 case 18: goto VCVTBFF_INST; \
3779 case 19: goto VCVTBFI_INST; \
3780 case 20: goto VMOVBRS_INST; \
3781 case 21: goto VMSR_INST; \
3782 case 22: goto VMOVBRC_INST; \
3783 case 23: goto VMRS_INST; \
3784 case 24: goto VMOVBCR_INST; \
3785 case 25: goto VMOVBRRSS_INST; \
3786 case 26: goto VMOVBRRD_INST; \
3787 case 27: goto VSTR_INST; \
3788 case 28: goto VPUSH_INST; \
3789 case 29: goto VSTM_INST; \
3790 case 30: goto VPOP_INST; \
3791 case 31: goto VLDR_INST; \
3792 case 32: goto VLDM_INST ; \
3793 case 33: goto SRS_INST; \
3794 case 34: goto RFE_INST; \
3795 case 35: goto BKPT_INST; \
3796 case 36: goto BLX_INST; \
3797 case 37: goto CPS_INST; \
3798 case 38: goto PLD_INST; \
3799 case 39: goto SETEND_INST; \
3800 case 40: goto CLREX_INST; \
3801 case 41: goto REV16_INST; \
3802 case 42: goto USAD8_INST; \
3803 case 43: goto SXTB_INST; \
3804 case 44: goto UXTB_INST; \
3805 case 45: goto SXTH_INST; \
3806 case 46: goto SXTB16_INST; \
3807 case 47: goto UXTH_INST; \
3808 case 48: goto UXTB16_INST; \
3809 case 49: goto CPY_INST; \
3810 case 50: goto UXTAB_INST; \
3811 case 51: goto SSUB8_INST; \
3812 case 52: goto SHSUB8_INST; \
3813 case 53: goto SSUBADDX_INST; \
3814 case 54: goto STREX_INST; \
3815 case 55: goto STREXB_INST; \
3816 case 56: goto SWP_INST; \
3817 case 57: goto SWPB_INST; \
3818 case 58: goto SSUB16_INST; \
3819 case 59: goto SSAT16_INST; \
3820 case 60: goto SHSUBADDX_INST; \
3821 case 61: goto QSUBADDX_INST; \
3822 case 62: goto SHADDSUBX_INST; \
3823 case 63: goto SHADD8_INST; \
3824 case 64: goto SHADD16_INST; \
3825 case 65: goto SEL_INST; \
3826 case 66: goto SADDSUBX_INST; \
3827 case 67: goto SADD8_INST; \
3828 case 68: goto SADD16_INST; \
3829 case 69: goto SHSUB16_INST; \
3830 case 70: goto UMAAL_INST; \
3831 case 71: goto UXTAB16_INST; \
3832 case 72: goto USUBADDX_INST; \
3833 case 73: goto USUB8_INST; \
3834 case 74: goto USUB16_INST; \
3835 case 75: goto USAT16_INST; \
3836 case 76: goto USADA8_INST; \
3837 case 77: goto UQSUBADDX_INST; \
3838 case 78: goto UQSUB8_INST; \
3839 case 79: goto UQSUB16_INST; \
3840 case 80: goto UQADDSUBX_INST; \
3841 case 81: goto UQADD8_INST; \
3842 case 82: goto UQADD16_INST; \
3843 case 83: goto SXTAB_INST; \
3844 case 84: goto UHSUBADDX_INST; \
3845 case 85: goto UHSUB8_INST; \
3846 case 86: goto UHSUB16_INST; \
3847 case 87: goto UHADDSUBX_INST; \
3848 case 88: goto UHADD8_INST; \
3849 case 89: goto UHADD16_INST; \
3850 case 90: goto UADDSUBX_INST; \
3851 case 91: goto UADD8_INST; \
3852 case 92: goto UADD16_INST; \
3853 case 93: goto SXTAH_INST; \
3854 case 94: goto SXTAB16_INST; \
3855 case 95: goto QADD8_INST; \
3856 case 96: goto BXJ_INST; \
3857 case 97: goto CLZ_INST; \
3858 case 98: goto UXTAH_INST; \
3859 case 99: goto BX_INST; \
3860 case 100: goto REV_INST; \
3861 case 101: goto BLX_INST; \
3862 case 102: goto REVSH_INST; \
3863 case 103: goto QADD_INST; \
3864 case 104: goto QADD16_INST; \
3865 case 105: goto QADDSUBX_INST; \
3866 case 106: goto LDREX_INST; \
3867 case 107: goto QDADD_INST; \
3868 case 108: goto QDSUB_INST; \
3869 case 109: goto QSUB_INST; \
3870 case 110: goto LDREXB_INST; \
3871 case 111: goto QSUB8_INST; \
3872 case 112: goto QSUB16_INST; \
3873 case 113: goto SMUAD_INST; \
3874 case 114: goto SMMUL_INST; \
3875 case 115: goto SMUSD_INST; \
3876 case 116: goto SMLSD_INST; \
3877 case 117: goto SMLSLD_INST; \
3878 case 118: goto SMMLA_INST; \
3879 case 119: goto SMMLS_INST; \
3880 case 120: goto SMLALD_INST; \
3881 case 121: goto SMLAD_INST; \
3882 case 122: goto SMLAW_INST; \
3883 case 123: goto SMULW_INST; \
3884 case 124: goto PKHTB_INST; \
3885 case 125: goto PKHBT_INST; \
3886 case 126: goto SMUL_INST; \
3887 case 127: goto SMLAL_INST; \
3888 case 128: goto SMLA_INST; \
3889 case 129: goto MCRR_INST; \
3890 case 130: goto MRRC_INST; \
3891 case 131: goto CMP_INST; \
3892 case 132: goto TST_INST; \
3893 case 133: goto TEQ_INST; \
3894 case 134: goto CMN_INST; \
3895 case 135: goto SMULL_INST; \
3896 case 136: goto UMULL_INST; \
3897 case 137: goto UMLAL_INST; \
3898 case 138: goto SMLAL_INST; \
3899 case 139: goto MUL_INST; \
3900 case 140: goto MLA_INST; \
3901 case 141: goto SSAT_INST; \
3902 case 142: goto USAT_INST; \
3903 case 143: goto MRS_INST; \
3904 case 144: goto MSR_INST; \
3905 case 145: goto AND_INST; \
3906 case 146: goto BIC_INST; \
3907 case 147: goto LDM_INST; \
3908 case 148: goto EOR_INST; \
3909 case 149: goto ADD_INST; \
3910 case 150: goto RSB_INST; \
3911 case 151: goto RSC_INST; \
3912 case 152: goto SBC_INST; \
3913 case 153: goto ADC_INST; \
3914 case 154: goto SUB_INST; \
3915 case 155: goto ORR_INST; \
3916 case 156: goto MVN_INST; \
3917 case 157: goto MOV_INST; \
3918 case 158: goto STM_INST; \
3919 case 159: goto LDM_INST; \
3920 case 160: goto LDRSH_INST; \
3921 case 161: goto STM_INST; \
3922 case 162: goto LDM_INST; \
3923 case 163: goto LDRSB_INST; \
3924 case 164: goto STRD_INST; \
3925 case 165: goto LDRH_INST; \
3926 case 166: goto STRH_INST; \
3927 case 167: goto LDRD_INST; \
3928 case 168: goto STRT_INST; \
3929 case 169: goto STRBT_INST; \
3930 case 170: goto LDRBT_INST; \
3931 case 171: goto LDRT_INST; \
3932 case 172: goto MRC_INST; \
3933 case 173: goto MCR_INST; \
3934 case 174: goto MSR_INST; \
3935 case 175: goto LDRB_INST; \
3936 case 176: goto STRB_INST; \
3937 case 177: goto LDR_INST; \
3938 case 178: goto LDRCOND_INST ; \
3939 case 179: goto STR_INST; \
3940 case 180: goto CDP_INST; \
3941 case 181: goto STC_INST; \
3942 case 182: goto LDC_INST; \
3943 case 183: goto SWI_INST; \
3944 case 184: goto BBL_INST; \
3945 case 185: goto B_2_THUMB ; \
3946 case 186: goto B_COND_THUMB ; \
3947 case 187: goto BL_1_THUMB ; \
3948 case 188: goto BL_2_THUMB ; \
3949 case 189: goto BLX_1_THUMB ; \
3950 case 190: goto DISPATCH; \
3951 case 191: goto INIT_INST_LENGTH; \
3952 case 192: goto END; \
3953 }
3954#endif
3955
3956 #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0)
3957 #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1)
3958// #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((ISNEG(lop) && ISPOS(rop)) || \
3959 (ISNEG(lop) && ISPOS(dst)) || \
3960 (ISPOS(rop) && ISPOS(dst))))
3961 #define UPDATE_CFLAG(dst, lop, rop) (cpu->CFlag = ((dst < lop) || (dst < rop)))
3962 #define UPDATE_CFLAG_CARRY_FROM_ADD(lop, rop, flag) (cpu->CFlag = (((uint64_t) lop + (uint64_t) rop + (uint64_t) flag) > 0xffffffff) )
3963 #define UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(lop, rop, flag) (cpu->CFlag = ((uint64_t) lop >= ((uint64_t) rop + (uint64_t) flag)))
3964 #define UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop) (cpu->CFlag = (lop >= rop))
3965 #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) (cpu->CFlag = !(dst < lop))
3966 #define UPDATE_CFLAG_WITH_SC cpu->CFlag = cpu->shifter_carry_out
3967// #define UPDATE_CFLAG_WITH_NOT(dst, lop, rop) cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || \
3968 (ISNEG(lop) && ISPOS(dst)) || \
3969 (ISPOS(rop) && ISPOS(dst)))
3970 #define UPDATE_VFLAG(dst, lop, rop) (cpu->VFlag = (((lop < 0) && (rop < 0) && (dst >= 0)) || \
3971 ((lop >= 0) && (rop) >= 0 && (dst < 0))))
3972 #define UPDATE_VFLAG_WITH_NOT(dst, lop, rop) (cpu->VFlag = !(((lop < 0) && (rop < 0) && (dst >= 0)) || \
3973 ((lop >= 0) && (rop) >= 0 && (dst < 0))))
3974 #define UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop) (cpu->VFlag = (((lop ^ rop) & (lop ^ dst)) >> 31))
3975
3976 #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \
3977 (cpu->NFlag << 31) | \
3978 (cpu->ZFlag << 30) | \
3979 (cpu->CFlag << 29) | \
3980 (cpu->VFlag << 28) | \
3981 (cpu->TFlag << 5)
3982 #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \
3983 cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \
3984 cpu->CFlag = (cpu->Cpsr >> 29) & 1; \
3985 cpu->VFlag = (cpu->Cpsr >> 28) & 1; \
3986 cpu->TFlag = (cpu->Cpsr >> 5) & 1;
3987
3988 #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE)
3989 #define PC (cpu->Reg[15])
3990 #define CHECK_EXT_INT if (!cpu->NirqSig) { \
3991 if (!(cpu->Cpsr & 0x80)) { \
3992 goto END; \
3993 } \
3994 }
3995
3996
3997
3998 //arm_processor *cpu = (arm_processor *)get_cast_conf_obj(core->cpu_data, "arm_core_t");
3999 arm_processor *cpu = state; //(arm_processor *)(core->cpu_data->obj);
4000
4001 // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback
4002 // to a clunky switch statement.
4003#if defined __GNUC__ || defined __clang__
4004 void *InstLabel[] = {
4005 #define VFP_INTERPRETER_LABEL
4006 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
4007 #undef VFP_INTERPRETER_LABEL
4008 &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST,
4009 &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST,
4010 &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST,
4011 &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST,
4012 &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST,
4013 &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST,
4014 &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST,
4015 &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST,
4016 &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST,
4017 &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLAL_INST,&&SMLA_INST,
4018 &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST,
4019 &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST,
4020 &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST,
4021 &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST,
4022 &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST,&&SWI_INST,&&BBL_INST,&&B_2_THUMB, &&B_COND_THUMB,
4023 &&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,&&INIT_INST_LENGTH,&&END
4024 };
4025#endif
4026 arm_inst * inst_base;
4027 unsigned int lop, rop, dst;
4028 unsigned int addr;
4029 unsigned int phys_addr;
4030 unsigned int last_pc = 0;
4031 fault_t fault;
4032 static unsigned int last_physical_base = 0, last_logical_base = 0;
4033 int ptr;
4034
4035 LOAD_NZCVT;
4036 DISPATCH:
4037 {
4038 if (cpu->NumInstrsToExecute == 0)
4039 return;
4040
4041 cpu->NumInstrsToExecute--;
4042
4043 //NOTICE_LOG(ARM11, "instr!");
4044
4045 if (!cpu->NirqSig) {
4046 if (!(cpu->Cpsr & 0x80)) {
4047 goto END;
4048 }
4049 }
4050
4051 if (cpu->TFlag) {
4052 cpu->Reg[15] &= 0xfffffffe;
4053 } else
4054 cpu->Reg[15] &= 0xfffffffc;
4055#if PROFILE
4056 /* check next instruction address is valid. */
4057 last_pc = cpu->Reg[15];
4058#endif
4059#if USER_MODE_OPT
4060 phys_addr = cpu->Reg[15];
4061#else
4062 {
4063 if (last_logical_base == (cpu->Reg[15] & 0xfffff000))
4064 phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff);
4065 else {
4066 /* check next instruction address is valid. */
4067 fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
4068 if (fault) {
4069 cpu->abortSig = true;
4070 cpu->Aborted = ARMul_PrefetchAbortV;
4071 cpu->AbortAddr = cpu->Reg[15];
4072 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
4073 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
4074 goto END;
4075 }
4076 last_logical_base = cpu->Reg[15] & 0xfffff000;
4077 last_physical_base = phys_addr & 0xfffff000;
4078 }
4079 }
4080#if HYBRID_MODE
4081 /* check if the native code of dyncom is available */
4082 //fast_map hash_map = core->dyncom_engine->fmap;
4083 //void * pfunc = NULL;
4084 //PFUNC(phys_addr);
4085 //if(pfunc){
4086 if(is_translated_entry(core, phys_addr)){
4087 int rc = JIT_RETURN_NOERR;
4088 //DEBUG_LOG(ARM11, "enter jit icounter is %lld, pc=0x%x\n", core->icounter, cpu->Reg[15]);
4089 SAVE_NZCVT;
4090// resume_timing();
4091 rc = cpu_run(core);
4092 LOAD_NZCVT;
4093 //DEBUG_LOG(ARM11, "out of jit ret is %d icounter is %lld, pc=0x%x\n", rc, core->icounter, cpu->Reg[15]);
4094 if((rc == JIT_RETURN_FUNCNOTFOUND) || (rc == JIT_RETURN_FUNC_BLANK)){
4095 /* keep the tflag same with the bit in CPSR */
4096 //cpu->TFlag = cpu->Cpsr & (1 << THUMB_BIT);
4097 //cpu->TFlag = cpu->Cpsr & (1 << 5);
4098 //switch_mode(cpu, cpu->Cpsr & 0x1f);
4099 //DEBUG_LOG(ARM11, "FUNCTION not found , pc=0x%x\n", cpu->Reg[15]);
4100 fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
4101 if (fault) {
4102 cpu->abortSig = true;
4103 cpu->Aborted = ARMul_PrefetchAbortV;
4104 cpu->AbortAddr = cpu->Reg[15];
4105 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
4106 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
4107 goto END;
4108 }
4109 last_logical_base = cpu->Reg[15] & 0xfffff000;
4110 last_physical_base = phys_addr & 0xfffff000;
4111 core->current_page_phys = last_physical_base;
4112 core->current_page_effec = last_logical_base;
4113 //push_to_compiled(core, phys_addr);
4114 }
4115 else{
4116 if((cpu->CP15[CP15(CP15_TLB_FAULT_STATUS)] & 0xf0)){
4117 //DEBUG_LOG(ARM11, "\n\n###############In %s, fsr=0x%x, fault_addr=0x%x, pc=0x%x\n\n", __FUNCTION__, cpu->CP15[CP15(CP15_FAULT_STATUS)], cpu->CP15[CP15(CP15_FAULT_ADDRESS)], cpu->Reg[15]);
4118 //core->Reg[15] -= get_instr_size(cpu_dyncom);
4119 fill_tlb(cpu);
4120 goto END;
4121 }
4122 if (cpu->syscallSig) {
4123 goto END;
4124 }
4125 if (cpu->abortSig) {
4126 cpu->CP15[CP15_TLB_FAULT_STATUS - CP15_BASE] &= 0xFFFFFFF0;
4127 goto END;
4128 }
4129 if (!cpu->NirqSig) {
4130 if (!(cpu->Cpsr & 0x80)) {
4131 goto END;
4132 }
4133 }
4134
4135 /* if regular trap */
4136 cpu->Reg[15] += GET_INST_SIZE(cpu);
4137 /*uint32_t mode = cpu->Cpsr & 0x1f;
4138 if ((mode != cpu->Mode) && (!is_user_mode(core))) {
4139 switch_mode(cpu, mode);
4140 return 1;
4141 }*/
4142
4143 goto END;
4144 }
4145 //phys_addr = cpu->Reg[15];
4146 }
4147 else{
4148 if (last_logical_base == (cpu->Reg[15] & 0xfffff000))
4149 phys_addr = last_physical_base + (cpu->Reg[15] & 0xfff);
4150 else {
4151 /* check next instruction address is valid. */
4152 fault = check_address_validity(cpu, cpu->Reg[15], &phys_addr, 1, INSN_TLB);
4153 if (fault) {
4154 cpu->abortSig = true;
4155 cpu->Aborted = ARMul_PrefetchAbortV;
4156 cpu->AbortAddr = cpu->Reg[15];
4157 cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = fault & 0xff;
4158 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = cpu->Reg[15];
4159 goto END;
4160 }
4161 last_logical_base = cpu->Reg[15] & 0xfffff000;
4162 last_physical_base = phys_addr & 0xfffff000;
4163 }
4164 }
4165#endif /* #if HYBRID_MODE */
4166#endif /* #if USER_MODE_OPT */
4167 if (true){//if(is_fast_interp_code(core, phys_addr)){
4168 if (find_bb(phys_addr, ptr) == -1)
4169 if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
4170 goto END;
4171 }
4172 else{
4173 if (InterpreterTranslate(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION)
4174 goto END;
4175 }
4176#if PROFILE
4177 resume_timing();
4178#endif
4179 inst_base = (arm_inst *)&inst_buf[ptr];
4180 GOTO_NEXT_INST;
4181 }
4182 PROFILING:
4183 {
4184 goto DISPATCH;
4185 }
4186 ADC_INST:
4187 {
4188 INC_ICOUNTER;
4189 adc_inst *inst_cream = (adc_inst *)inst_base->component;
4190 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4191 lop = RN;
4192 unsigned int sht_op = SHIFTER_OPERAND;
4193 rop = SHIFTER_OPERAND + cpu->CFlag;
4194 RD = dst = lop + rop;
4195 if (inst_cream->S && (inst_cream->Rd == 15)) {
4196 /* cpsr = spsr */
4197 if (CurrentModeHasSPSR) {
4198 cpu->Cpsr = cpu->Spsr_copy;
4199 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
4200 LOAD_NZCVT;
4201 }
4202 } else if (inst_cream->S) {
4203 UPDATE_NFLAG(dst);
4204 UPDATE_ZFLAG(dst);
4205 UPDATE_CFLAG_CARRY_FROM_ADD(lop, sht_op, cpu->CFlag);
4206 UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4207 }
4208 if (inst_cream->Rd == 15) {
4209 INC_PC(sizeof(adc_inst));
4210 goto PROFILING;
4211 }
4212 }
4213 cpu->Reg[15] += GET_INST_SIZE(cpu);
4214 INC_PC(sizeof(adc_inst));
4215 FETCH_INST;
4216 GOTO_NEXT_INST;
4217 }
4218 ADD_INST:
4219 {
4220 INC_ICOUNTER;
4221 add_inst *inst_cream = (add_inst *)inst_base->component;
4222 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4223 lop = RN;
4224 if (inst_cream->Rn == 15) {
4225 lop += 2 * GET_INST_SIZE(cpu);
4226 }
4227 rop = SHIFTER_OPERAND;
4228 RD = dst = lop + rop;
4229 if (inst_cream->S && (inst_cream->Rd == 15)) {
4230 /* cpsr = spsr*/
4231 if (CurrentModeHasSPSR) {
4232 cpu->Cpsr = cpu->Spsr_copy;
4233 switch_mode(cpu, cpu->Cpsr & 0x1f);
4234 LOAD_NZCVT;
4235 }
4236 } else if (inst_cream->S) {
4237 UPDATE_NFLAG(dst);
4238 UPDATE_ZFLAG(dst);
4239 UPDATE_CFLAG(dst, lop, rop);
4240 UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4241 }
4242 if (inst_cream->Rd == 15) {
4243 INC_PC(sizeof(add_inst));
4244 goto PROFILING;
4245 }
4246 }
4247 cpu->Reg[15] += GET_INST_SIZE(cpu);
4248 INC_PC(sizeof(add_inst));
4249 FETCH_INST;
4250 GOTO_NEXT_INST;
4251 }
4252 AND_INST:
4253 {
4254 INC_ICOUNTER;
4255 and_inst *inst_cream = (and_inst *)inst_base->component;
4256 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4257 lop = RN;
4258 rop = SHIFTER_OPERAND;
4259 RD = dst = lop & rop;
4260 if (inst_cream->S && (inst_cream->Rd == 15)) {
4261 /* cpsr = spsr*/
4262 if (CurrentModeHasSPSR) {
4263 cpu->Cpsr = cpu->Spsr_copy;
4264 switch_mode(cpu, cpu->Cpsr & 0x1f);
4265 LOAD_NZCVT;
4266 }
4267 } else if (inst_cream->S) {
4268 UPDATE_NFLAG(dst);
4269 UPDATE_ZFLAG(dst);
4270 UPDATE_CFLAG_WITH_SC;
4271 //UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4272 }
4273 if (inst_cream->Rd == 15) {
4274 INC_PC(sizeof(and_inst));
4275 goto PROFILING;
4276 }
4277 }
4278 cpu->Reg[15] += GET_INST_SIZE(cpu);
4279 INC_PC(sizeof(and_inst));
4280 FETCH_INST;
4281 GOTO_NEXT_INST;
4282 }
4283 BBL_INST:
4284 {
4285 INC_ICOUNTER;
4286 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4287 bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
4288 if (inst_cream->L) {
4289 LINK_RTN_ADDR;
4290 }
4291 SET_PC;
4292 INC_PC(sizeof(bbl_inst));
4293 goto PROFILING;
4294 }
4295 cpu->Reg[15] += GET_INST_SIZE(cpu);
4296 INC_PC(sizeof(bbl_inst));
4297 goto PROFILING;
4298 }
4299 BIC_INST:
4300 {
4301 INC_ICOUNTER;
4302 bic_inst *inst_cream = (bic_inst *)inst_base->component;
4303 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4304 lop = RN;
4305 if (inst_cream->Rn == 15) {
4306 lop += 2 * GET_INST_SIZE(cpu);
4307 }
4308 rop = SHIFTER_OPERAND;
4309// RD = dst = lop & (rop ^ 0xffffffff);
4310 RD = dst = lop & (~rop);
4311 if ((inst_cream->S) && (inst_cream->Rd == 15)) {
4312 /* cpsr = spsr */
4313 if (CurrentModeHasSPSR) {
4314 cpu->Cpsr = cpu->Spsr_copy;
4315 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
4316 LOAD_NZCVT;
4317 }
4318 } else if (inst_cream->S) {
4319 UPDATE_NFLAG(dst);
4320 UPDATE_ZFLAG(dst);
4321 UPDATE_CFLAG_WITH_SC;
4322 }
4323 if (inst_cream->Rd == 15) {
4324 INC_PC(sizeof(bic_inst));
4325 goto PROFILING;
4326 }
4327 }
4328 cpu->Reg[15] += GET_INST_SIZE(cpu);
4329 INC_PC(sizeof(bic_inst));
4330 FETCH_INST;
4331 GOTO_NEXT_INST;
4332 }
4333 BKPT_INST:
4334 BLX_INST:
4335 {
4336 INC_ICOUNTER;
4337 blx_inst *inst_cream = (blx_inst *)inst_base->component;
4338 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4339 unsigned int inst = inst_cream->inst;
4340 if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
4341 //LINK_RTN_ADDR;
4342 cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
4343 if(cpu->TFlag)
4344 cpu->Reg[14] |= 0x1;
4345 cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe;
4346 cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1;
4347 //cpu->Reg[15] = cpu->Reg[BITS(inst, 0, 3)] & 0xfffffffe;
4348 //cpu->TFlag = cpu->Reg[BITS(inst, 0, 3)] & 0x1;
4349 } else {
4350 cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu));
4351 cpu->TFlag = 0x1;
4352 int signed_int = inst_cream->val.signed_immed_24;
4353 signed_int = (signed_int) & 0x800000 ? (0x3F000000 | signed_int) : signed_int;
4354 signed_int = signed_int << 2;
4355 // cpu->Reg[15] = cpu->Reg[15] + 2 * GET_INST_SIZE(cpu)
4356 cpu->Reg[15] = cpu->Reg[15] + 8
4357 + signed_int + (BIT(inst, 24) << 1);
4358 //DEBUG_MSG;
4359 }
4360 INC_PC(sizeof(blx_inst));
4361 goto PROFILING;
4362 }
4363 cpu->Reg[15] += GET_INST_SIZE(cpu);
4364// INC_PC(sizeof(bx_inst));
4365 INC_PC(sizeof(blx_inst));
4366 goto PROFILING;
4367 }
4368 BX_INST:
4369 {
4370 INC_ICOUNTER;
4371 bx_inst *inst_cream = (bx_inst *)inst_base->component;
4372 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4373 if (inst_cream->Rm == 15)
4374 DEBUG_LOG(ARM11, "In %s, BX at pc %x: use of Rm = R15 is discouraged\n", __FUNCTION__, cpu->Reg[15]);
4375 cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
4376 cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe;
4377// cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
4378 INC_PC(sizeof(bx_inst));
4379 goto PROFILING;
4380 }
4381 cpu->Reg[15] += GET_INST_SIZE(cpu);
4382// INC_PC(sizeof(bx_inst));
4383 INC_PC(sizeof(bx_inst));
4384 goto PROFILING;
4385 }
4386 BXJ_INST:
4387 CDP_INST:
4388 {
4389 INC_ICOUNTER;
4390 cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
4391 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4392 /* FIXME, check if cp access allowed */
4393 #define CP_ACCESS_ALLOW 0
4394 if(CP_ACCESS_ALLOW){
4395 /* undefined instruction here */
4396 return;
4397 }
4398 ERROR_LOG(ARM11, "CDP insn inst=0x%x, pc=0x%x\n", inst_cream->inst, cpu->Reg[15]);
4399 unsigned cpab = (cpu->CDP[inst_cream->cp_num]) (cpu, ARMul_FIRST, inst_cream->inst);
4400 if(cpab != ARMul_DONE){
4401 ERROR_LOG(ARM11, "CDP insn wrong, inst=0x%x, cp_num=0x%x\n", inst_cream->inst, inst_cream->cp_num);
4402 //CITRA_IGNORE_EXIT(-1);
4403 }
4404 }
4405 cpu->Reg[15] += GET_INST_SIZE(cpu);
4406 INC_PC(sizeof(cdp_inst));
4407 FETCH_INST;
4408 GOTO_NEXT_INST;
4409 }
4410
4411 CLREX_INST:
4412 {
4413 INC_ICOUNTER;
4414 remove_exclusive(cpu, 0);
4415 cpu->exclusive_state = 0;
4416
4417 cpu->Reg[15] += GET_INST_SIZE(cpu);
4418 INC_PC(sizeof(clrex_inst));
4419 FETCH_INST;
4420 GOTO_NEXT_INST;
4421 }
4422 CLZ_INST:
4423 {
4424 INC_ICOUNTER;
4425 clz_inst *inst_cream = (clz_inst *)inst_base->component;
4426 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4427 RD = clz(RM);
4428 }
4429 cpu->Reg[15] += GET_INST_SIZE(cpu);
4430 INC_PC(sizeof(clz_inst));
4431 FETCH_INST;
4432 GOTO_NEXT_INST;
4433 }
4434 CMN_INST:
4435 {
4436 INC_ICOUNTER;
4437 cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
4438 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4439// DEBUG_LOG(ARM11, "RN is %x\n", RN);
4440 lop = RN;
4441 rop = SHIFTER_OPERAND;
4442 dst = lop + rop;
4443 UPDATE_NFLAG(dst);
4444 UPDATE_ZFLAG(dst);
4445 UPDATE_CFLAG(dst, lop, rop);
4446 UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4447 }
4448 cpu->Reg[15] += GET_INST_SIZE(cpu);
4449 INC_PC(sizeof(cmn_inst));
4450 FETCH_INST;
4451 GOTO_NEXT_INST;
4452 }
4453 CMP_INST:
4454 {
4455// DEBUG_LOG(ARM11, "cmp inst\n");
4456// DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]);
4457 INC_ICOUNTER;
4458 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4459// DEBUG_LOG(ARM11, "r0 is %x\n", cpu->Reg[0]);
4460 cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
4461 lop = RN;
4462 if (inst_cream->Rn == 15) {
4463 lop += 2 * GET_INST_SIZE(cpu);
4464 }
4465 rop = SHIFTER_OPERAND;
4466 dst = lop - rop;
4467
4468 UPDATE_NFLAG(dst);
4469 UPDATE_ZFLAG(dst);
4470// UPDATE_CFLAG(dst, lop, rop);
4471 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
4472// UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4473 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
4474// UPDATE_VFLAG_WITH_NOT(dst, lop, rop);
4475 }
4476 cpu->Reg[15] += GET_INST_SIZE(cpu);
4477 INC_PC(sizeof(cmp_inst));
4478 FETCH_INST;
4479 GOTO_NEXT_INST;
4480 }
4481 CPS_INST:
4482 {
4483 INC_ICOUNTER;
4484 cps_inst *inst_cream = (cps_inst *)inst_base->component;
4485 uint32_t aif_val = 0;
4486 uint32_t aif_mask = 0;
4487 if (InAPrivilegedMode(cpu)) {
4488 /* isInAPrivilegedMode */
4489 if (inst_cream->imod1) {
4490 if (inst_cream->A) {
4491 aif_val |= (inst_cream->imod0 << 8);
4492 aif_mask |= 1 << 8;
4493 }
4494 if (inst_cream->I) {
4495 aif_val |= (inst_cream->imod0 << 7);
4496 aif_mask |= 1 << 7;
4497 }
4498 if (inst_cream->F) {
4499 aif_val |= (inst_cream->imod0 << 6);
4500 aif_mask |= 1 << 6;
4501 }
4502 aif_mask = ~aif_mask;
4503 cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val;
4504 }
4505 if (inst_cream->mmod) {
4506 cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode;
4507 switch_mode(cpu, inst_cream->mode);
4508 }
4509 }
4510 cpu->Reg[15] += GET_INST_SIZE(cpu);
4511 INC_PC(sizeof(cps_inst));
4512 FETCH_INST;
4513 GOTO_NEXT_INST;
4514 }
4515 CPY_INST:
4516 {
4517 INC_ICOUNTER;
4518 mov_inst *inst_cream = (mov_inst *)inst_base->component;
4519// cpy_inst *inst_cream = (cpy_inst *)inst_base->component;
4520 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4521 RD = SHIFTER_OPERAND;
4522// RD = RM;
4523 if ((inst_cream->Rd == 15)) {
4524 INC_PC(sizeof(mov_inst));
4525 goto PROFILING;
4526 }
4527 }
4528// DEBUG_LOG(ARM11, "cpy inst %x\n", cpu->Reg[15]);
4529 cpu->Reg[15] += GET_INST_SIZE(cpu);
4530 INC_PC(sizeof(mov_inst));
4531 FETCH_INST;
4532 GOTO_NEXT_INST;
4533 }
4534 EOR_INST:
4535 {
4536 INC_ICOUNTER;
4537 eor_inst *inst_cream = (eor_inst *)inst_base->component;
4538 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4539 lop = RN;
4540 if (inst_cream->Rn == 15) {
4541 lop += 2 * GET_INST_SIZE(cpu);
4542 }
4543 rop = SHIFTER_OPERAND;
4544 RD = dst = lop ^ rop;
4545 if (inst_cream->S && (inst_cream->Rd == 15)) {
4546 /* cpsr = spsr*/
4547 if (CurrentModeHasSPSR) {
4548 cpu->Cpsr = cpu->Spsr_copy;
4549 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
4550 LOAD_NZCVT;
4551 }
4552 } else if (inst_cream->S) {
4553 UPDATE_NFLAG(dst);
4554 UPDATE_ZFLAG(dst);
4555 UPDATE_CFLAG_WITH_SC;
4556// UPDATE_CFLAG(dst, lop, rop);
4557// UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
4558 }
4559 if (inst_cream->Rd == 15) {
4560 INC_PC(sizeof(eor_inst));
4561 goto PROFILING;
4562 }
4563 }
4564 cpu->Reg[15] += GET_INST_SIZE(cpu);
4565 INC_PC(sizeof(eor_inst));
4566 FETCH_INST;
4567 GOTO_NEXT_INST;
4568 }
4569 LDC_INST:
4570 {
4571 INC_ICOUNTER;
4572 /* NOT IMPL */
4573 cpu->Reg[15] += GET_INST_SIZE(cpu);
4574 INC_PC(sizeof(ldc_inst));
4575 FETCH_INST;
4576 GOTO_NEXT_INST;
4577 }
4578 LDM_INST:
4579 {
4580 INC_ICOUNTER;
4581 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4582 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4583 int i;
4584 unsigned int ret;
4585 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4586 if (fault) {
4587 goto MMU_EXCEPTION;
4588 }
4589 unsigned int inst = inst_cream->inst;
4590 if (BIT(inst, 22) && !BIT(inst, 15)) {
4591// DEBUG_MSG;
4592 #if 1
4593 /* LDM (2) user */
4594 for (i = 0; i < 13; i++) {
4595 if(BIT(inst, i)){
4596 #if 0
4597 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4598 if (fault) {
4599 goto MMU_EXCEPTION;
4600 }
4601 #endif
4602 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4603 //if (fault) goto MMU_EXCEPTION;
4604 cpu->Reg[i] = ret;
4605 addr += 4;
4606 if ((addr & 0xfff) == 0) {
4607 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4608 } else {
4609 phys_addr += 4;
4610 }
4611 }
4612 }
4613 if (BIT(inst, 13)) {
4614 #if 0
4615 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4616 if (fault) {
4617 goto MMU_EXCEPTION;
4618 }
4619 #endif
4620 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4621 //if (fault) goto MMU_EXCEPTION;
4622 if (cpu->Mode == USER32MODE)
4623 cpu->Reg[13] = ret;
4624 else
4625 cpu->Reg_usr[0] = ret;
4626 addr += 4;
4627 if ((addr & 0xfff) == 0) {
4628 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4629 } else {
4630 phys_addr += 4;
4631 }
4632 }
4633 if (BIT(inst, 14)) {
4634 #if 0
4635 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4636 if (fault) {
4637 goto MMU_EXCEPTION;
4638 }
4639 #endif
4640 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4641 //if (fault) goto MMU_EXCEPTION;
4642 if (cpu->Mode == USER32MODE)
4643 cpu->Reg[14] = ret;
4644 else
4645 cpu->Reg_usr[1] = ret;
4646 }
4647 #endif
4648 } else if (!BIT(inst, 22)) {
4649 for( i = 0; i < 16; i ++ ){
4650 if(BIT(inst, i)){
4651 //bus_read(32, addr, &ret);
4652 #if 0
4653 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4654 if (fault) {
4655 goto MMU_EXCEPTION;
4656 }
4657 #endif
4658 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4659 if (fault) goto MMU_EXCEPTION;
4660 /* For armv5t, should enter thumb when bits[0] is non-zero. */
4661 if(i == 15){
4662 cpu->TFlag = ret & 0x1;
4663 ret &= 0xFFFFFFFE;
4664 //DEBUG_LOG(ARM11, "In %s, TFlag ret=0x%x\n", __FUNCTION__, ret);
4665 }
4666
4667 cpu->Reg[i] = ret;
4668 addr += 4;
4669 if ((addr & 0xfff) == 0) {
4670 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4671 } else {
4672 phys_addr += 4;
4673 }
4674 }
4675 }
4676 } else if (BIT(inst, 22) && BIT(inst, 15)) {
4677 for( i = 0; i < 15; i ++ ){
4678 if(BIT(inst, i)){
4679 #if 0
4680 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4681 if (fault) {
4682 goto MMU_EXCEPTION;
4683 }
4684 #endif
4685 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4686 //if (fault) goto MMU_EXCEPTION;
4687 cpu->Reg[i] = ret;
4688 addr += 4;
4689 if ((addr & 0xfff) == 0) {
4690 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4691 } else {
4692 phys_addr += 4;
4693 }
4694 }
4695 }
4696
4697 if (CurrentModeHasSPSR) {
4698 cpu->Cpsr = cpu->Spsr_copy;
4699 switch_mode(cpu, cpu->Cpsr & 0x1f);
4700 LOAD_NZCVT;
4701 }
4702 #if 0
4703 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4704 if (fault) {
4705 goto MMU_EXCEPTION;
4706 }
4707 #endif
4708 fault = interpreter_read_memory(addr, phys_addr, ret, 32);
4709 if (fault) {
4710 goto MMU_EXCEPTION;
4711 }
4712 cpu->Reg[15] = ret;
4713 #if 0
4714 addr += 4;
4715 phys_addr += 4;
4716 #endif
4717 }
4718 if (BIT(inst, 15)) {
4719 INC_PC(sizeof(ldst_inst));
4720 goto PROFILING;
4721 }
4722 }
4723 cpu->Reg[15] += GET_INST_SIZE(cpu);
4724 INC_PC(sizeof(ldst_inst));
4725 FETCH_INST;
4726 GOTO_NEXT_INST;
4727 }
4728 SXTH_INST:
4729 {
4730 INC_ICOUNTER;
4731 sxth_inst *inst_cream = (sxth_inst *)inst_base->component;
4732 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4733 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
4734 if (BIT(operand2, 15)) {
4735 operand2 |= 0xffff0000;
4736 } else {
4737 operand2 &= 0xffff;
4738 }
4739 RD = operand2;
4740 }
4741 cpu->Reg[15] += GET_INST_SIZE(cpu);
4742 INC_PC(sizeof(sxth_inst));
4743 FETCH_INST;
4744 GOTO_NEXT_INST;
4745 }
4746 LDR_INST:
4747 {
4748 INC_ICOUNTER;
4749 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4750 //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4751 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4752 if (fault) goto MMU_EXCEPTION;
4753 unsigned int value;
4754 //bus_read(32, addr, &value);
4755 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4756 if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
4757 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4758 else {
4759 value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
4760 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4761 }
4762 if (BITS(inst_cream->inst, 12, 15) == 15) {
4763 /* For armv5t, should enter thumb when bits[0] is non-zero. */
4764 cpu->TFlag = value & 0x1;
4765 cpu->Reg[15] &= 0xFFFFFFFE;
4766 INC_PC(sizeof(ldst_inst));
4767 goto PROFILING;
4768 }
4769 //}
4770 cpu->Reg[15] += GET_INST_SIZE(cpu);
4771 INC_PC(sizeof(ldst_inst));
4772 FETCH_INST;
4773 GOTO_NEXT_INST;
4774 }
4775 LDRCOND_INST:
4776 {
4777 INC_ICOUNTER;
4778 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4779 if (CondPassed(cpu, inst_base->cond)) {
4780 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4781 if (fault) goto MMU_EXCEPTION;
4782 unsigned int value;
4783 //bus_read(32, addr, &value);
4784 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4785 if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
4786 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4787 else {
4788 value = ROTATE_RIGHT_32(value,(8*(addr&0x3)));
4789 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4790 }
4791
4792 if (BITS(inst_cream->inst, 12, 15) == 15) {
4793 /* For armv5t, should enter thumb when bits[0] is non-zero. */
4794 cpu->TFlag = value & 0x1;
4795 cpu->Reg[15] &= 0xFFFFFFFE;
4796 INC_PC(sizeof(ldst_inst));
4797 goto PROFILING;
4798 }
4799 }
4800 cpu->Reg[15] += GET_INST_SIZE(cpu);
4801 INC_PC(sizeof(ldst_inst));
4802 FETCH_INST;
4803 GOTO_NEXT_INST;
4804 }
4805 UXTH_INST:
4806 {
4807 INC_ICOUNTER;
4808 uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
4809 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4810 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
4811 & 0xffff;
4812 RD = operand2;
4813 }
4814 cpu->Reg[15] += GET_INST_SIZE(cpu);
4815 INC_PC(sizeof(uxth_inst));
4816 FETCH_INST;
4817 GOTO_NEXT_INST;
4818 }
4819 UXTAH_INST:
4820 {
4821 INC_ICOUNTER;
4822 uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
4823 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4824 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
4825 & 0xffff;
4826 RD = RN + operand2;
4827 if (inst_cream->Rn == 15 || inst_cream->Rm == 15) {
4828 DEBUG_LOG(ARM11, "in line %d\n", __LINE__);
4829 CITRA_IGNORE_EXIT(-1);
4830 }
4831 }
4832 cpu->Reg[15] += GET_INST_SIZE(cpu);
4833 INC_PC(sizeof(uxtah_inst));
4834 FETCH_INST;
4835 GOTO_NEXT_INST;
4836 }
4837 LDRB_INST:
4838 {
4839 INC_ICOUNTER;
4840 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4841 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4842 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4843 if (fault) goto MMU_EXCEPTION;
4844 unsigned int value;
4845 fault = interpreter_read_memory(addr, phys_addr, value, 8);
4846 if (fault) goto MMU_EXCEPTION;
4847 //bus_read(8, addr, &value);
4848 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4849 if (BITS(inst_cream->inst, 12, 15) == 15) {
4850 INC_PC(sizeof(ldst_inst));
4851 goto PROFILING;
4852 }
4853 }
4854 cpu->Reg[15] += GET_INST_SIZE(cpu);
4855 INC_PC(sizeof(ldst_inst));
4856 FETCH_INST;
4857 GOTO_NEXT_INST;
4858 }
4859 LDRBT_INST:
4860 {
4861 INC_ICOUNTER;
4862 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4863 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4864 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4865 if (fault) goto MMU_EXCEPTION;
4866 unsigned int value;
4867 fault = interpreter_read_memory(addr, phys_addr, value, 8);
4868 if (fault) goto MMU_EXCEPTION;
4869 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4870 if (BITS(inst_cream->inst, 12, 15) == 15) {
4871 INC_PC(sizeof(ldst_inst));
4872 goto PROFILING;
4873 }
4874 }
4875 cpu->Reg[15] += GET_INST_SIZE(cpu);
4876 INC_PC(sizeof(ldst_inst));
4877 FETCH_INST;
4878 GOTO_NEXT_INST;
4879 }
4880 LDRD_INST:
4881 {
4882 INC_ICOUNTER;
4883 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4884 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4885 /* Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) */
4886 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4887 if (fault) goto MMU_EXCEPTION;
4888 uint32_t rear_phys_addr;
4889 fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 1);
4890 if(fault){
4891 ERROR_LOG(ARM11, "mmu fault , should rollback the above get_addr\n");
4892 CITRA_IGNORE_EXIT(-1);
4893 goto MMU_EXCEPTION;
4894 }
4895 unsigned int value;
4896 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4897 if (fault) goto MMU_EXCEPTION;
4898 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4899 fault = interpreter_read_memory(addr + 4, rear_phys_addr, value, 32);
4900 if (fault) goto MMU_EXCEPTION;
4901 cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = value;
4902 /* No dispatch since this operation should not modify R15 */
4903 }
4904 cpu->Reg[15] += 4;
4905 INC_PC(sizeof(ldst_inst));
4906 FETCH_INST;
4907 GOTO_NEXT_INST;
4908 }
4909
4910 LDREX_INST:
4911 {
4912 INC_ICOUNTER;
4913 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4914 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4915 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
4916 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4917 if (fault) goto MMU_EXCEPTION;
4918 unsigned int value;
4919 fault = interpreter_read_memory(addr, phys_addr, value, 32);
4920 if (fault) goto MMU_EXCEPTION;
4921
4922 add_exclusive_addr(cpu, phys_addr);
4923 cpu->exclusive_state = 1;
4924
4925 //bus_read(32, addr, &value);
4926 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4927 if (BITS(inst_cream->inst, 12, 15) == 15) {
4928 INC_PC(sizeof(ldst_inst));
4929 goto PROFILING;
4930 }
4931 }
4932 cpu->Reg[15] += GET_INST_SIZE(cpu);
4933 INC_PC(sizeof(ldst_inst));
4934 FETCH_INST;
4935 GOTO_NEXT_INST;
4936 }
4937 LDREXB_INST:
4938 {
4939 INC_ICOUNTER;
4940 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4941 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4942 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
4943 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4944 if (fault) goto MMU_EXCEPTION;
4945 unsigned int value;
4946 fault = interpreter_read_memory(addr, phys_addr, value, 8);
4947 if (fault) goto MMU_EXCEPTION;
4948
4949 add_exclusive_addr(cpu, phys_addr);
4950 cpu->exclusive_state = 1;
4951
4952 //bus_read(8, addr, &value);
4953 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4954 if (BITS(inst_cream->inst, 12, 15) == 15) {
4955 INC_PC(sizeof(ldst_inst));
4956 goto PROFILING;
4957 }
4958 }
4959 cpu->Reg[15] += GET_INST_SIZE(cpu);
4960 INC_PC(sizeof(ldst_inst));
4961 FETCH_INST;
4962 GOTO_NEXT_INST;
4963 }
4964 LDRH_INST:
4965 {
4966 INC_ICOUNTER;
4967 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4968 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4969 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4970 if (fault) goto MMU_EXCEPTION;
4971 unsigned int value = 0;
4972 fault = interpreter_read_memory(addr, phys_addr, value, 16);
4973// fault = interpreter_read_memory(addr, value, 32);
4974 if (fault) goto MMU_EXCEPTION;
4975 //if (value == 0xffff && cpu->icounter > 190000000 && cpu->icounter < 210000000) {
4976 // value = 0xffffffff;
4977 //}
4978 //bus_read(16, addr, &value);
4979// cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value & 0xffff;
4980 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4981 if (BITS(inst_cream->inst, 12, 15) == 15) {
4982 INC_PC(sizeof(ldst_inst));
4983 goto PROFILING;
4984 }
4985 }
4986 cpu->Reg[15] += GET_INST_SIZE(cpu);
4987 INC_PC(sizeof(ldst_inst));
4988 FETCH_INST;
4989 GOTO_NEXT_INST;
4990 }
4991 LDRSB_INST:
4992 {
4993 INC_ICOUNTER;
4994 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4995 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
4996 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
4997 if (fault) goto MMU_EXCEPTION;
4998 unsigned int value;
4999// DEBUG_LOG(ARM11, "ldrsb addr is %x\n", addr);
5000 fault = interpreter_read_memory(addr, phys_addr, value, 8);
5001 if (fault) goto MMU_EXCEPTION;
5002 //bus_read(8, addr, &value);
5003 if (BIT(value, 7)) {
5004 value |= 0xffffff00;
5005 }
5006 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5007 if (BITS(inst_cream->inst, 12, 15) == 15) {
5008 INC_PC(sizeof(ldst_inst));
5009 goto PROFILING;
5010 }
5011 }
5012 cpu->Reg[15] += GET_INST_SIZE(cpu);
5013 INC_PC(sizeof(ldst_inst));
5014 FETCH_INST;
5015 GOTO_NEXT_INST;
5016 }
5017 LDRSH_INST:
5018 {
5019 INC_ICOUNTER;
5020 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5021 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5022 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
5023 if (fault) goto MMU_EXCEPTION;
5024 unsigned int value;
5025 fault = interpreter_read_memory(addr, phys_addr, value, 16);
5026 if (fault) goto MMU_EXCEPTION;
5027 //bus_read(16, addr, &value);
5028 if (BIT(value, 15)) {
5029 value |= 0xffff0000;
5030 }
5031 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5032 if (BITS(inst_cream->inst, 12, 15) == 15) {
5033 INC_PC(sizeof(ldst_inst));
5034 goto PROFILING;
5035 }
5036 }
5037 cpu->Reg[15] += GET_INST_SIZE(cpu);
5038 INC_PC(sizeof(ldst_inst));
5039 FETCH_INST;
5040 GOTO_NEXT_INST;
5041 }
5042 LDRT_INST:
5043 {
5044 INC_ICOUNTER;
5045 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5046 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5047 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 1);
5048 if (fault) goto MMU_EXCEPTION;
5049 unsigned int value;
5050 fault = interpreter_read_memory(addr, phys_addr, value, 32);
5051 if (fault) goto MMU_EXCEPTION;
5052 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5053
5054 if (BIT(CP15_REG(CP15_CONTROL), 22) == 1)
5055 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
5056 else
5057 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ROTATE_RIGHT_32(value,(8*(addr&0x3))) ;
5058
5059 if (BITS(inst_cream->inst, 12, 15) == 15) {
5060 INC_PC(sizeof(ldst_inst));
5061 goto PROFILING;
5062 }
5063 }
5064 cpu->Reg[15] += GET_INST_SIZE(cpu);
5065 INC_PC(sizeof(ldst_inst));
5066 FETCH_INST;
5067 GOTO_NEXT_INST;
5068 }
5069 MCR_INST:
5070 {
5071 INC_ICOUNTER;
5072 /* NOT IMPL */
5073 mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
5074 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5075 unsigned int inst = inst_cream->inst;
5076 if (inst_cream->Rd == 15) {
5077 DEBUG_MSG;
5078 } else {
5079 if (inst_cream->cp_num == 15) {
5080 if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) {
5081 //LET(RD, CONST(0x0007b000));
5082 //LET(RD, CONST(0x410FB760));
5083 //LET(CP15_MAIN_ID, R(RD));
5084 CP15_REG(CP15_MAIN_ID) = RD;
5085 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
5086 //LET(RD, R(CP15_CONTROL));
5087 CP15_REG(CP15_AUXILIARY_CONTROL) = RD;
5088 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
5089 //LET(RD, R(CP15_CONTROL));
5090 CP15_REG(CP15_COPROCESSOR_ACCESS_CONTROL) = RD;
5091 } else if(CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
5092 //LET(CP15_CONTROL, R(RD));
5093 CP15_REG(CP15_CONTROL) = RD;
5094 } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
5095 //LET(CP15_DOMAIN_ACCESS_CONTROL, R(RD));
5096 CP15_REG(CP15_DOMAIN_ACCESS_CONTROL) = RD;
5097 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
5098 //LET(CP15_TRANSLATION_BASE_TABLE_0, R(RD));
5099 CP15_REG(CP15_TRANSLATION_BASE_TABLE_0) = RD;
5100 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) {
5101 //LET(CP15_TRANSLATION_BASE_TABLE_1, R(RD));
5102 CP15_REG(CP15_TRANSLATION_BASE_TABLE_1) = RD;
5103 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) {
5104 //LET(CP15_TRANSLATION_BASE_CONTROL, R(RD));
5105 CP15_REG(CP15_TRANSLATION_BASE_CONTROL) = RD;
5106 } else if(CRn == MMU_CACHE_OPS){
5107 //SKYEYE_WARNING("cache operation have not implemented.\n");
5108 } else if(CRn == MMU_TLB_OPS){
5109 switch (CRm) {
5110 case 5: /* ITLB */
5111 switch(OPCODE_2){
5112 case 0: /* invalidate all */
5113 //invalidate_all_tlb(state);
5114 DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate all\n");
5115 //remove_tlb(INSN_TLB);
5116 //erase_all(core, INSN_TLB);
5117 break;
5118 case 1: /* invalidate by MVA */
5119 //invalidate_by_mva(state, value);
5120 //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by mva\n");
5121 //remove_tlb_by_mva(RD, INSN_TLB);
5122 //erase_by_mva(core, RD, INSN_TLB);
5123 break;
5124 case 2: /* invalidate by asid */
5125 //invalidate_by_asid(state, value);
5126 //DEBUG_LOG(ARM11, "{TLB} [INSN] invalidate by asid\n");
5127 //erase_by_asid(core, RD, INSN_TLB);
5128 break;
5129 default:
5130 break;
5131 }
5132
5133 break;
5134 case 6: /* DTLB */
5135 switch(OPCODE_2){
5136 case 0: /* invalidate all */
5137 //invalidate_all_tlb(state);
5138 //remove_tlb(DATA_TLB);
5139 //erase_all(core, DATA_TLB);
5140 DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate all\n");
5141 break;
5142 case 1: /* invalidate by MVA */
5143 //invalidate_by_mva(state, value);
5144 //remove_tlb_by_mva(RD, DATA_TLB);
5145 //erase_by_mva(core, RD, DATA_TLB);
5146 //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by mva\n");
5147 break;
5148 case 2: /* invalidate by asid */
5149 //invalidate_by_asid(state, value);
5150 //remove_tlb_by_asid(RD, DATA_TLB);
5151 //erase_by_asid(core, RD, DATA_TLB);
5152 //DEBUG_LOG(ARM11, "{TLB} [DATA] invalidate by asid\n");
5153 break;
5154 default:
5155 break;
5156 }
5157 break;
5158 case 7: /* UNIFILED TLB */
5159 switch(OPCODE_2){
5160 case 0: /* invalidate all */
5161 //invalidate_all_tlb(state);
5162 //erase_all(core, INSN_TLB);
5163 //erase_all(core, DATA_TLB);
5164 //remove_tlb(DATA_TLB);
5165 //remove_tlb(INSN_TLB);
5166 //DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate all\n");
5167 break;
5168 case 1: /* invalidate by MVA */
5169 //invalidate_by_mva(state, value);
5170 //erase_by_mva(core, RD, DATA_TLB);
5171 //erase_by_mva(core, RD, INSN_TLB);
5172 DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate by mva\n");
5173 break;
5174 case 2: /* invalidate by asid */
5175 //invalidate_by_asid(state, value);
5176 //erase_by_asid(core, RD, DATA_TLB);
5177 //erase_by_asid(core, RD, INSN_TLB);
5178 DEBUG_LOG(ARM11, "{TLB} [UNIFILED] invalidate by asid\n");
5179 break;
5180 default:
5181 break;
5182 }
5183 break;
5184 default:
5185 break;
5186 }
5187 } else if(CRn == MMU_PID){
5188 if(OPCODE_2 == 0)
5189 CP15_REG(CP15_PID) = RD;
5190 else if(OPCODE_2 == 1)
5191 CP15_REG(CP15_CONTEXT_ID) = RD;
5192 else if(OPCODE_2 == 3){
5193 CP15_REG(CP15_THREAD_URO) = RD;
5194 }
5195 else{
5196 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", CRn);
5197 }
5198
5199 } else {
5200 DEBUG_LOG(ARM11, "mcr is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2);
5201 }
5202 }
5203 }
5204 }
5205 cpu->Reg[15] += GET_INST_SIZE(cpu);
5206 INC_PC(sizeof(mcr_inst));
5207 FETCH_INST;
5208 GOTO_NEXT_INST;
5209 }
5210 MCRR_INST:
5211 MLA_INST:
5212 {
5213 INC_ICOUNTER;
5214 mla_inst *inst_cream = (mla_inst *)inst_base->component;
5215 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5216 uint64_t rm = RM;
5217 uint64_t rs = RS;
5218 uint64_t rn = RN;
5219 if (inst_cream->Rm == 15 || inst_cream->Rs == 15 || inst_cream->Rn == 15) {
5220 DEBUG_LOG(ARM11, "in __line__\n", __LINE__);
5221 CITRA_IGNORE_EXIT(-1);
5222 }
5223// RD = dst = RM * RS + RN;
5224 RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff);
5225 if (inst_cream->S) {
5226 UPDATE_NFLAG(dst);
5227 UPDATE_ZFLAG(dst);
5228 }
5229 if (inst_cream->Rd == 15) {
5230 INC_PC(sizeof(mla_inst));
5231 goto PROFILING;
5232 }
5233 }
5234 cpu->Reg[15] += GET_INST_SIZE(cpu);
5235 INC_PC(sizeof(mla_inst));
5236 FETCH_INST;
5237 GOTO_NEXT_INST;
5238 }
5239 MOV_INST:
5240 {
5241// DEBUG_LOG(ARM11, "mov inst\n");
5242// DEBUG_LOG(ARM11, "pc: %x\n", cpu->Reg[15]);
5243// debug_function(cpu);
5244// cpu->icount ++;
5245 INC_ICOUNTER;
5246 mov_inst *inst_cream = (mov_inst *)inst_base->component;
5247 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5248 RD = dst = SHIFTER_OPERAND;
5249 if (inst_cream->S && (inst_cream->Rd == 15)) {
5250 /* cpsr = spsr */
5251 if (CurrentModeHasSPSR) {
5252 cpu->Cpsr = cpu->Spsr_copy;
5253 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5254 LOAD_NZCVT;
5255 }
5256 } else if (inst_cream->S) {
5257 UPDATE_NFLAG(dst);
5258 UPDATE_ZFLAG(dst);
5259 UPDATE_CFLAG_WITH_SC;
5260 }
5261 if (inst_cream->Rd == 15) {
5262 INC_PC(sizeof(mov_inst));
5263 goto PROFILING;
5264 }
5265// return;
5266 }
5267 cpu->Reg[15] += GET_INST_SIZE(cpu);
5268 INC_PC(sizeof(mov_inst));
5269 FETCH_INST;
5270 GOTO_NEXT_INST;
5271 }
5272 MRC_INST:
5273 {
5274 INC_ICOUNTER;
5275 /* NOT IMPL */
5276 mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
5277 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5278 unsigned int inst = inst_cream->inst;
5279 if (inst_cream->Rd == 15) {
5280 DEBUG_MSG;
5281 }
5282 if (inst_cream->inst == 0xeef04a10) {
5283 /* undefined instruction fmrx */
5284 RD = 0x20000000;
5285 CITRA_IGNORE_EXIT(-1);
5286 goto END;
5287 } else {
5288 if (inst_cream->cp_num == 15) {
5289 if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) {
5290 //LET(RD, CONST(0x0007b000));
5291 //LET(RD, CONST(0x410FB760));
5292 //LET(RD, R(CP15_MAIN_ID));
5293 RD = cpu->CP15[CP15(CP15_MAIN_ID)];
5294 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
5295 //LET(RD, R(CP15_CONTROL));
5296 RD = cpu->CP15[CP15(CP15_CONTROL)];
5297 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
5298 //LET(RD, R(CP15_CONTROL));
5299 RD = cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)];
5300 } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
5301 //LET(RD, R(CP15_CONTROL));
5302 RD = cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)];
5303 } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
5304 //LET(RD, R(CP15_DOMAIN_ACCESS_CONTROL));
5305 RD = cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)];
5306 } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
5307 //LET(RD, R(CP15_TRANSLATION_BASE_TABLE_0));
5308 RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)];
5309 } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 0) {
5310 //LET(RD, R(CP15_FAULT_STATUS));
5311 RD = cpu->CP15[CP15(CP15_FAULT_STATUS)];
5312 } else if (CRn == 6 && CRm == 0 && OPCODE_2 == 0) {
5313 //LET(RD, R(CP15_FAULT_ADDRESS));
5314 RD = cpu->CP15[CP15(CP15_FAULT_ADDRESS)];
5315 } else if (CRn == 0 && CRm == 0 && OPCODE_2 == 1) {
5316 //LET(RD, R(CP15_CACHE_TYPE));
5317 RD = cpu->CP15[CP15(CP15_CACHE_TYPE)];
5318 } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 1) {
5319 //LET(RD, R(CP15_INSTR_FAULT_STATUS));
5320 RD = cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)];
5321 } else if (CRn == 13) {
5322 if(OPCODE_2 == 0)
5323 RD = CP15_REG(CP15_PID);
5324 else if(OPCODE_2 == 1)
5325 RD = CP15_REG(CP15_CONTEXT_ID);
5326 else if(OPCODE_2 == 3){
5327 RD = Memory::KERNEL_MEMORY_VADDR;
5328 }
5329 else{
5330 printf ("mmu_mrr wrote UNKNOWN - reg %d\n", CRn);
5331 }
5332 }
5333 else {
5334 DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2);
5335 }
5336 }
5337 //DEBUG_LOG(ARM11, "mrc is not implementated. CRn is %d, CRm is %d, OPCODE_2 is %d\n", CRn, CRm, OPCODE_2);
5338 }
5339 }
5340 cpu->Reg[15] += GET_INST_SIZE(cpu);
5341 INC_PC(sizeof(mrc_inst));
5342 FETCH_INST;
5343 GOTO_NEXT_INST;
5344 }
5345 MRRC_INST:
5346 MRS_INST:
5347 {
5348 INC_ICOUNTER;
5349 mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
5350 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5351 if (inst_cream->R) {
5352 RD = cpu->Spsr_copy;
5353 } else {
5354 SAVE_NZCVT;
5355 RD = cpu->Cpsr;
5356 }
5357 }
5358 cpu->Reg[15] += GET_INST_SIZE(cpu);
5359 INC_PC(sizeof(mrs_inst));
5360 FETCH_INST;
5361 GOTO_NEXT_INST;
5362 }
5363 MSR_INST:
5364 {
5365 INC_ICOUNTER;
5366 msr_inst *inst_cream = (msr_inst *)inst_base->component;
5367 const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020;
5368 unsigned int inst = inst_cream->inst;
5369 unsigned int operand;
5370
5371 if (BIT(inst, 25)) {
5372 int rot_imm = BITS(inst, 8, 11) * 2;
5373 //operand = ROTL(CONST(BITS(0, 7)), CONST(32 - rot_imm));
5374 operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm);
5375 } else {
5376 //operand = R(RM);
5377 operand = cpu->Reg[BITS(inst, 0, 3)];
5378 }
5379 uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0)
5380 | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0);
5381 uint32_t mask;
5382 if (!inst_cream->R) {
5383 if (InAPrivilegedMode(cpu)) {
5384 if ((operand & StateMask) != 0) {
5385 /* UNPREDICTABLE */
5386 DEBUG_MSG;
5387 } else
5388 mask = byte_mask & (UserMask | PrivMask);
5389 } else {
5390 mask = byte_mask & UserMask;
5391 }
5392 //LET(CPSR_REG, OR(AND(R(CPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask))));
5393 SAVE_NZCVT;
5394
5395 cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask);
5396 switch_mode(cpu, cpu->Cpsr & 0x1f);
5397 LOAD_NZCVT;
5398 } else {
5399 if (CurrentModeHasSPSR) {
5400 mask = byte_mask & (UserMask | PrivMask | StateMask);
5401 //LET(SPSR_REG, OR(AND(R(SPSR_REG), COM(CONST(mask))), AND(operand, CONST(mask))));
5402 cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask);
5403 }
5404 }
5405 cpu->Reg[15] += GET_INST_SIZE(cpu);
5406 INC_PC(sizeof(msr_inst));
5407 FETCH_INST;
5408 GOTO_NEXT_INST;
5409 }
5410 MUL_INST:
5411 {
5412 INC_ICOUNTER;
5413 mul_inst *inst_cream = (mul_inst *)inst_base->component;
5414 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5415// RD = dst = SHIFTER_OPERAND;
5416 uint64_t rm = RM;
5417 uint64_t rs = RS;
5418 RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff);
5419 if (inst_cream->S) {
5420 UPDATE_NFLAG(dst);
5421 UPDATE_ZFLAG(dst);
5422 }
5423 if (inst_cream->Rd == 15) {
5424 INC_PC(sizeof(mul_inst));
5425 goto PROFILING;
5426 }
5427 }
5428 cpu->Reg[15] += GET_INST_SIZE(cpu);
5429 INC_PC(sizeof(mul_inst));
5430 FETCH_INST;
5431 GOTO_NEXT_INST;
5432 }
5433 MVN_INST:
5434 {
5435 INC_ICOUNTER;
5436 mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
5437 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5438// RD = dst = (SHIFTER_OPERAND ^ 0xffffffff);
5439 RD = dst = ~SHIFTER_OPERAND;
5440 if (inst_cream->S && (inst_cream->Rd == 15)) {
5441 /* cpsr = spsr */
5442 if (CurrentModeHasSPSR) {
5443 cpu->Cpsr = cpu->Spsr_copy;
5444 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5445 LOAD_NZCVT;
5446 }
5447 } else if (inst_cream->S) {
5448 UPDATE_NFLAG(dst);
5449 UPDATE_ZFLAG(dst);
5450 UPDATE_CFLAG_WITH_SC;
5451 }
5452 if (inst_cream->Rd == 15) {
5453 INC_PC(sizeof(mvn_inst));
5454 goto PROFILING;
5455 }
5456 }
5457 cpu->Reg[15] += GET_INST_SIZE(cpu);
5458 INC_PC(sizeof(mvn_inst));
5459 FETCH_INST;
5460 GOTO_NEXT_INST;
5461 }
5462 ORR_INST:
5463 {
5464 INC_ICOUNTER;
5465 orr_inst *inst_cream = (orr_inst *)inst_base->component;
5466 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5467 lop = RN;
5468 rop = SHIFTER_OPERAND;
5469// DEBUG_LOG(ARM11, "lop is %x, rop is %x, r2 is %x, r3 is %x\n", lop, rop, cpu->Reg[2], cpu->Reg[3]);
5470 RD = dst = lop | rop;
5471 if (inst_cream->S && (inst_cream->Rd == 15)) {
5472 /* cpsr = spsr*/
5473 if (CurrentModeHasSPSR) {
5474 cpu->Cpsr = cpu->Spsr_copy;
5475 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5476 LOAD_NZCVT;
5477 }
5478 } else if (inst_cream->S) {
5479 UPDATE_NFLAG(dst);
5480 UPDATE_ZFLAG(dst);
5481 UPDATE_CFLAG_WITH_SC;
5482// UPDATE_CFLAG(dst, lop, rop);
5483 }
5484 if (inst_cream->Rd == 15) {
5485 INC_PC(sizeof(orr_inst));
5486 goto PROFILING;
5487 }
5488 }
5489 cpu->Reg[15] += GET_INST_SIZE(cpu);
5490 INC_PC(sizeof(orr_inst));
5491 FETCH_INST;
5492 GOTO_NEXT_INST;
5493 }
5494 PKHBT_INST:
5495 PKHTB_INST:
5496 PLD_INST:
5497 {
5498 INC_ICOUNTER;
5499 /* NOT IMPL */
5500 cpu->Reg[15] += GET_INST_SIZE(cpu);
5501 INC_PC(sizeof(stc_inst));
5502 FETCH_INST;
5503 GOTO_NEXT_INST;
5504 }
5505 QADD_INST:
5506 QADD16_INST:
5507 QADD8_INST:
5508 QADDSUBX_INST:
5509 QDADD_INST:
5510 QDSUB_INST:
5511 QSUB_INST:
5512 QSUB16_INST:
5513 QSUB8_INST:
5514 QSUBADDX_INST:
5515 REV_INST:
5516 {
5517 INC_ICOUNTER;
5518 rev_inst *inst_cream = (rev_inst *)inst_base->component;
5519 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5520 RD = ((RM & 0xff) << 24) |
5521 (((RM >> 8) & 0xff) << 16) |
5522 (((RM >> 16) & 0xff) << 8) |
5523 ((RM >> 24) & 0xff);
5524 if (inst_cream->Rm == 15) {
5525 DEBUG_LOG(ARM11, "in line %d\n", __LINE__);
5526 CITRA_IGNORE_EXIT(-1);
5527 }
5528 }
5529 cpu->Reg[15] += GET_INST_SIZE(cpu);
5530 INC_PC(sizeof(rev_inst));
5531 FETCH_INST;
5532 GOTO_NEXT_INST;
5533 }
5534 REV16_INST:
5535 {
5536 INC_ICOUNTER;
5537 rev_inst *inst_cream = (rev_inst *)inst_base->component;
5538 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5539 RD = (BITS(RM, 0, 7) << 8) |
5540 BITS(RM, 8, 15) |
5541 (BITS(RM, 16, 23) << 24) |
5542 (BITS(RM, 24, 31) << 16);
5543 }
5544 cpu->Reg[15] += GET_INST_SIZE(cpu);
5545 INC_PC(sizeof(rev_inst));
5546 FETCH_INST;
5547 GOTO_NEXT_INST;
5548 }
5549 REVSH_INST:
5550 RFE_INST:
5551 RSB_INST:
5552 {
5553 INC_ICOUNTER;
5554 rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
5555 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5556 rop = RN;
5557 lop = SHIFTER_OPERAND;
5558 if (inst_cream->Rn == 15) {
5559 rop += 2 * GET_INST_SIZE(cpu);;
5560 }
5561 RD = dst = lop - rop;
5562 if (inst_cream->S && (inst_cream->Rd == 15)) {
5563 /* cpsr = spsr */
5564 if (CurrentModeHasSPSR) {
5565 cpu->Cpsr = cpu->Spsr_copy;
5566 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5567 LOAD_NZCVT;
5568 }
5569 } else if (inst_cream->S) {
5570 UPDATE_NFLAG(dst);
5571 UPDATE_ZFLAG(dst);
5572 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
5573// UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
5574 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
5575 }
5576 if (inst_cream->Rd == 15) {
5577 INC_PC(sizeof(rsb_inst));
5578 goto PROFILING;
5579 }
5580 }
5581 cpu->Reg[15] += GET_INST_SIZE(cpu);
5582 INC_PC(sizeof(rsb_inst));
5583 FETCH_INST;
5584 GOTO_NEXT_INST;
5585 }
5586 RSC_INST:
5587 {
5588 INC_ICOUNTER;
5589 rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
5590 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5591 //lop = RN + !cpu->CFlag;
5592 //rop = SHIFTER_OPERAND;
5593 //RD = dst = rop - lop;
5594 lop = RN;
5595 rop = SHIFTER_OPERAND;
5596 RD = dst = rop - lop - !cpu->CFlag;
5597 if (inst_cream->S && (inst_cream->Rd == 15)) {
5598 /* cpsr = spsr */
5599 if (CurrentModeHasSPSR) {
5600 cpu->Cpsr = cpu->Spsr_copy;
5601 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5602 LOAD_NZCVT;
5603 }
5604 } else if (inst_cream->S) {
5605 UPDATE_NFLAG(dst);
5606 UPDATE_ZFLAG(dst);
5607// UPDATE_CFLAG(dst, lop, rop);
5608// UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop);
5609 UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag);
5610// cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst)));
5611 UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop);
5612 }
5613 if (inst_cream->Rd == 15) {
5614 INC_PC(sizeof(rsc_inst));
5615 goto PROFILING;
5616 }
5617 }
5618 cpu->Reg[15] += GET_INST_SIZE(cpu);
5619 INC_PC(sizeof(rsc_inst));
5620 FETCH_INST;
5621 GOTO_NEXT_INST;
5622 }
5623 SADD16_INST:
5624 SADD8_INST:
5625 SADDSUBX_INST:
5626 SBC_INST:
5627 {
5628 INC_ICOUNTER;
5629 sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
5630 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5631 lop = SHIFTER_OPERAND + !cpu->CFlag;
5632 rop = RN;
5633 RD = dst = rop - lop;
5634 if (inst_cream->S && (inst_cream->Rd == 15)) {
5635 /* cpsr = spsr */
5636 if (CurrentModeHasSPSR) {
5637 cpu->Cpsr = cpu->Spsr_copy;
5638 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
5639 LOAD_NZCVT;
5640 }
5641 } else if (inst_cream->S) {
5642 UPDATE_NFLAG(dst);
5643 UPDATE_ZFLAG(dst);
5644// UPDATE_CFLAG(dst, lop, rop);
5645 //UPDATE_CFLAG_NOT_BORROW_FROM(rop, lop);
5646 //rop = rop - !cpu->CFlag;
5647 if(rop >= !cpu->CFlag)
5648 UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND);
5649 else
5650 UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag);
5651// cpu->CFlag = !((ISNEG(lop) && ISPOS(rop)) || (ISNEG(lop) && ISPOS(dst)) || (ISPOS(rop) && ISPOS(dst)));
5652 UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop);
5653 }
5654 if (inst_cream->Rd == 15) {
5655 INC_PC(sizeof(sbc_inst));
5656 goto PROFILING;
5657 }
5658 }
5659 cpu->Reg[15] += GET_INST_SIZE(cpu);
5660 INC_PC(sizeof(sbc_inst));
5661 FETCH_INST;
5662 GOTO_NEXT_INST;
5663 }
5664 SEL_INST:
5665 SETEND_INST:
5666 SHADD16_INST:
5667 SHADD8_INST:
5668 SHADDSUBX_INST:
5669 SHSUB16_INST:
5670 SHSUB8_INST:
5671 SHSUBADDX_INST:
5672 SMLA_INST:
5673 {
5674 INC_ICOUNTER;
5675 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5676 smla_inst *inst_cream = (smla_inst *)inst_base->component;
5677 int32_t operand1, operand2;
5678 if (inst_cream->x == 0)
5679 operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
5680 else
5681 operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
5682
5683 if (inst_cream->y == 0)
5684 operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
5685 else
5686 operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
5687 RD = operand1 * operand2 + RN;
5688 //FIXME: UPDATE Q FLAGS
5689 }
5690 cpu->Reg[15] += GET_INST_SIZE(cpu);
5691 INC_PC(sizeof(smla_inst));
5692 FETCH_INST;
5693 GOTO_NEXT_INST;
5694 }
5695 SMLAD_INST:
5696 {
5697 INC_ICOUNTER;
5698 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5699 smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
5700 long long int rm = cpu->Reg[inst_cream->Rm];
5701 long long int rn = cpu->Reg[inst_cream->Rn];
5702 long long int ra = cpu->Reg[inst_cream->Ra];
5703 /* see SMUAD */
5704 if(inst_cream->Ra == 15)
5705 CITRA_IGNORE_EXIT(-1);
5706 int operand2 = (inst_cream->m)? ROTATE_RIGHT_32(rm, 16):rm;
5707
5708 int half_rn, half_operand2;
5709 half_rn = rn & 0xFFFF;
5710 half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
5711
5712 half_operand2 = operand2 & 0xFFFF;
5713 half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
5714
5715 long long int product1 = half_rn * half_operand2;
5716
5717 half_rn = (rn & 0xFFFF0000) >> 16;
5718 half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
5719
5720 half_operand2 = (operand2 & 0xFFFF0000) >> 16;
5721 half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
5722
5723 long long int product2 = half_rn * half_operand2;
5724
5725 long long int signed_ra = (ra & 0x80000000)? (0xFFFFFFFF00000000LL) | ra : ra;
5726 long long int result = product1 + product2 + signed_ra;
5727 cpu->Reg[inst_cream->Rd] = result & 0xFFFFFFFF;
5728 /* FIXME , should check Signed overflow */
5729 }
5730 cpu->Reg[15] += GET_INST_SIZE(cpu);
5731 INC_PC(sizeof(umlal_inst));
5732 FETCH_INST;
5733 GOTO_NEXT_INST;
5734 }
5735
5736 SMLAL_INST:
5737 {
5738 INC_ICOUNTER;
5739 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5740 umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
5741 long long int rm = RM;
5742 long long int rs = RS;
5743 if (BIT(rm, 31)) {
5744 rm |= 0xffffffff00000000LL;
5745 }
5746 if (BIT(rs, 31)) {
5747 rs |= 0xffffffff00000000LL;
5748 }
5749 long long int rst = rm * rs;
5750 long long int rdhi32 = RDHI;
5751 long long int hilo = (rdhi32 << 32) + RDLO;
5752 rst += hilo;
5753 RDLO = BITS(rst, 0, 31);
5754 RDHI = BITS(rst, 32, 63);
5755 if (inst_cream->S) {
5756 cpu->NFlag = BIT(RDHI, 31);
5757 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
5758 }
5759 }
5760 cpu->Reg[15] += GET_INST_SIZE(cpu);
5761 INC_PC(sizeof(umlal_inst));
5762 FETCH_INST;
5763 GOTO_NEXT_INST;
5764 }
5765 SMLALXY_INST:
5766 SMLALD_INST:
5767 SMLAW_INST:
5768 SMLSD_INST:
5769 SMLSLD_INST:
5770 SMMLA_INST:
5771 SMMLS_INST:
5772 SMMUL_INST:
5773 SMUAD_INST:
5774 SMUL_INST:
5775 {
5776 INC_ICOUNTER;
5777 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5778 smul_inst *inst_cream = (smul_inst *)inst_base->component;
5779 uint32_t operand1, operand2;
5780 if (inst_cream->x == 0)
5781 operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15);
5782 else
5783 operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31);
5784
5785 if (inst_cream->y == 0)
5786 operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15);
5787 else
5788 operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
5789 RD = operand1 * operand2;
5790 }
5791 cpu->Reg[15] += GET_INST_SIZE(cpu);
5792 INC_PC(sizeof(smul_inst));
5793 FETCH_INST;
5794 GOTO_NEXT_INST;
5795 }
5796 SMULL_INST:
5797 {
5798 INC_ICOUNTER;
5799 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5800 umull_inst *inst_cream = (umull_inst *)inst_base->component;
5801// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst);
5802 int64_t rm = RM;
5803 int64_t rs = RS;
5804 if (BIT(rm, 31)) {
5805 rm |= 0xffffffff00000000LL;
5806 }
5807 if (BIT(rs, 31)) {
5808 rs |= 0xffffffff00000000LL;
5809 }
5810 int64_t rst = rm * rs;
5811 RDHI = BITS(rst, 32, 63);
5812 RDLO = BITS(rst, 0, 31);
5813
5814
5815 if (inst_cream->S) {
5816 cpu->NFlag = BIT(RDHI, 31);
5817 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
5818 }
5819 }
5820 cpu->Reg[15] += GET_INST_SIZE(cpu);
5821 INC_PC(sizeof(umull_inst));
5822 FETCH_INST;
5823 GOTO_NEXT_INST;
5824 }
5825 SMULW_INST:
5826 INC_ICOUNTER;
5827 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5828 smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
5829// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst);
5830 int64_t rm = RM;
5831 int64_t rn = RN;
5832 if (inst_cream->m)
5833 rm = BITS(rm,16 , 31);
5834 else
5835 rm = BITS(rm,0 , 15);
5836 int64_t rst = rm * rn;
5837 RD = BITS(rst, 16, 47);
5838 }
5839 cpu->Reg[15] += GET_INST_SIZE(cpu);
5840 INC_PC(sizeof(smlad_inst));
5841 FETCH_INST;
5842 GOTO_NEXT_INST;
5843
5844 SMUSD_INST:
5845 SRS_INST:
5846 SSAT_INST:
5847 SSAT16_INST:
5848 SSUB16_INST:
5849 SSUB8_INST:
5850 SSUBADDX_INST:
5851 STC_INST:
5852 {
5853 INC_ICOUNTER;
5854 /* NOT IMPL */
5855 cpu->Reg[15] += GET_INST_SIZE(cpu);
5856 INC_PC(sizeof(stc_inst));
5857 FETCH_INST;
5858 GOTO_NEXT_INST;
5859 }
5860 STM_INST:
5861 {
5862 INC_ICOUNTER;
5863 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5864 unsigned int inst = inst_cream->inst;
5865 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5866 int i;
5867 unsigned int Rn = BITS(inst, 16, 19);
5868 unsigned int old_RN = cpu->Reg[Rn];
5869
5870 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
5871 if (fault) goto MMU_EXCEPTION;
5872 if (BIT(inst_cream->inst, 22) == 1) {
5873// DEBUG_MSG;
5874 #if 1
5875 for (i = 0; i < 13; i++) {
5876 if(BIT(inst_cream->inst, i)){
5877 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5878 if (fault) {
5879 goto MMU_EXCEPTION;
5880 }
5881 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
5882 if (fault) goto MMU_EXCEPTION;
5883 addr += 4;
5884 phys_addr += 4;
5885 }
5886 }
5887 if (BIT(inst_cream->inst, 13)) {
5888 if (cpu->Mode == USER32MODE) {
5889 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5890 if (fault) {
5891 goto MMU_EXCEPTION;
5892 }
5893 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
5894 if (fault) goto MMU_EXCEPTION;
5895 addr += 4;
5896 phys_addr += 4;
5897 } else {
5898 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[0], 32);
5899 if (fault) goto MMU_EXCEPTION;
5900 addr += 4;
5901 phys_addr += 4;
5902 }
5903 }
5904 if (BIT(inst_cream->inst, 14)) {
5905 if (cpu->Mode == USER32MODE) {
5906 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5907 if (fault) {
5908 goto MMU_EXCEPTION;
5909 }
5910 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
5911 if (fault) goto MMU_EXCEPTION;
5912 addr += 4;
5913 phys_addr += 4;
5914 } else {
5915 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5916 if (fault) {
5917 goto MMU_EXCEPTION;
5918 }
5919 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg_usr[1], 32);
5920 if (fault) goto MMU_EXCEPTION;
5921 addr += 4;
5922 phys_addr += 4;
5923 }
5924 }
5925 if (BIT(inst_cream->inst, 15)) {
5926 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5927 if (fault) {
5928 goto MMU_EXCEPTION;
5929 }
5930 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32);
5931 if (fault) goto MMU_EXCEPTION;
5932 }
5933 #endif
5934 } else {
5935 for( i = 0; i < 15; i ++ ){
5936 if(BIT(inst_cream->inst, i)){
5937 //arch_write_memory(cpu, bb, Addr, R(i), 32);
5938 //bus_write(32, addr, cpu->Reg[i]);
5939 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5940 if (fault) {
5941 goto MMU_EXCEPTION;
5942 }
5943 if(i == Rn)
5944 fault = interpreter_write_memory(addr, phys_addr, old_RN, 32);
5945 else
5946 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i], 32);
5947 if (fault) goto MMU_EXCEPTION;
5948 addr += 4;
5949 phys_addr += 4;
5950 //Addr = ADD(Addr, CONST(4));
5951 }
5952 }
5953
5954 /* check pc reg*/
5955 if(BIT(inst_cream->inst, i)){
5956 //arch_write_memory(cpu, bb, Addr, STOREM_CHECK_PC, 32);
5957 //bus_write(32, addr, cpu->Reg[i] + 8);
5958 fault = check_address_validity(cpu, addr, &phys_addr, 0);
5959 if (fault) {
5960 goto MMU_EXCEPTION;
5961 }
5962 fault = interpreter_write_memory(addr, phys_addr, cpu->Reg[i] + 8, 32);
5963 if (fault) goto MMU_EXCEPTION;
5964 }
5965 }
5966 }
5967 cpu->Reg[15] += GET_INST_SIZE(cpu);
5968 INC_PC(sizeof(ldst_inst));
5969 FETCH_INST;
5970 GOTO_NEXT_INST;
5971 }
5972 SXTB_INST:
5973 {
5974 INC_ICOUNTER;
5975 sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
5976 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5977 if (inst_cream->Rm == 15) {
5978 DEBUG_LOG(ARM11, "line is %d\n", __LINE__);
5979 CITRA_IGNORE_EXIT(-1);
5980 }
5981 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate);
5982 if (BIT(operand2, 7)) {
5983 operand2 |= 0xffffff00;
5984 } else
5985 operand2 &= 0xff;
5986 RD = operand2;
5987 }
5988 cpu->Reg[15] += GET_INST_SIZE(cpu);
5989 INC_PC(sizeof(sxtb_inst));
5990 FETCH_INST;
5991 GOTO_NEXT_INST;
5992 }
5993 STR_INST:
5994 {
5995 INC_ICOUNTER;
5996 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
5997 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
5998 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
5999 if (fault) goto MMU_EXCEPTION;
6000 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
6001 //bus_write(32, addr, value);
6002 fault = interpreter_write_memory(addr, phys_addr, value, 32);
6003 if (fault) goto MMU_EXCEPTION;
6004 }
6005 cpu->Reg[15] += GET_INST_SIZE(cpu);
6006 INC_PC(sizeof(ldst_inst));
6007 FETCH_INST;
6008 GOTO_NEXT_INST;
6009 }
6010 UXTB_INST:
6011 {
6012 INC_ICOUNTER;
6013 uxtb_inst *inst_cream = (uxtb_inst *)inst_base->component;
6014 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6015 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
6016 & 0xff;
6017 RD = operand2;
6018 }
6019 cpu->Reg[15] += GET_INST_SIZE(cpu);
6020 INC_PC(sizeof(uxtb_inst));
6021 FETCH_INST;
6022 GOTO_NEXT_INST;
6023 }
6024 UXTAB_INST:
6025 {
6026 INC_ICOUNTER;
6027 uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
6028 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6029 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
6030 & 0xff;
6031 RD = RN + operand2;
6032 }
6033 cpu->Reg[15] += GET_INST_SIZE(cpu);
6034 INC_PC(sizeof(uxtab_inst));
6035 FETCH_INST;
6036 GOTO_NEXT_INST;
6037 }
6038 STRB_INST:
6039 {
6040 INC_ICOUNTER;
6041 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6042 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6043 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6044 if (fault) goto MMU_EXCEPTION;
6045 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
6046 //bus_write(8, addr, value);
6047 fault = interpreter_write_memory(addr, phys_addr, value, 8);
6048 if (fault) goto MMU_EXCEPTION;
6049 }
6050 cpu->Reg[15] += GET_INST_SIZE(cpu);
6051 INC_PC(sizeof(ldst_inst));
6052 FETCH_INST;
6053 GOTO_NEXT_INST;
6054 }
6055 STRBT_INST:
6056 {
6057 INC_ICOUNTER;
6058 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6059 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6060 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6061 if (fault) goto MMU_EXCEPTION;
6062 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff;
6063 //bus_write(8, addr, value);
6064 fault = interpreter_write_memory(addr, phys_addr, value, 8);
6065 if (fault) goto MMU_EXCEPTION;
6066 }
6067 cpu->Reg[15] += GET_INST_SIZE(cpu);
6068 //if (BITS(inst_cream->inst, 12, 15) == 15)
6069 // goto PROFILING;
6070 INC_PC(sizeof(ldst_inst));
6071 FETCH_INST;
6072 GOTO_NEXT_INST;
6073 }
6074 STRD_INST:
6075 {
6076 INC_ICOUNTER;
6077 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6078 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6079 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6080 if (fault) goto MMU_EXCEPTION;
6081 uint32_t rear_phys_addr;
6082 fault = check_address_validity(cpu, addr + 4, &rear_phys_addr, 0);
6083 if (fault){
6084 ERROR_LOG(ARM11, "mmu fault , should rollback the above get_addr\n");
6085 CITRA_IGNORE_EXIT(-1);
6086 goto MMU_EXCEPTION;
6087 }
6088
6089 //fault = inst_cream->get_addr(cpu, inst_cream->inst, addr + 4, phys_addr + 4, 0);
6090 //if (fault) goto MMU_EXCEPTION;
6091
6092 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
6093 //bus_write(32, addr, value);
6094 fault = interpreter_write_memory(addr, phys_addr, value, 32);
6095 if (fault) goto MMU_EXCEPTION;
6096 value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1];
6097 //bus_write(32, addr, value);
6098 fault = interpreter_write_memory(addr + 4, rear_phys_addr, value, 32);
6099 if (fault) goto MMU_EXCEPTION;
6100 }
6101 cpu->Reg[15] += GET_INST_SIZE(cpu);
6102 INC_PC(sizeof(ldst_inst));
6103 FETCH_INST;
6104 GOTO_NEXT_INST;
6105 }
6106 STREX_INST:
6107 {
6108 INC_ICOUNTER;
6109 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6110 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6111 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
6112 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)];
6113 fault = check_address_validity(cpu, addr, &phys_addr, 0);
6114 if (fault) goto MMU_EXCEPTION;
6115
6116 int dest_reg = BITS(inst_cream->inst, 12, 15);
6117 if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){
6118 remove_exclusive(cpu, phys_addr);
6119 cpu->Reg[dest_reg] = 0;
6120 cpu->exclusive_state = 0;
6121
6122 // bus_write(32, addr, value);
6123 fault = interpreter_write_memory(addr, phys_addr, value, 32);
6124 if (fault) goto MMU_EXCEPTION;
6125 }
6126 else{
6127 /* Failed to write due to mutex access */
6128 cpu->Reg[dest_reg] = 1;
6129 }
6130 }
6131 cpu->Reg[15] += GET_INST_SIZE(cpu);
6132 INC_PC(sizeof(ldst_inst));
6133 FETCH_INST;
6134 GOTO_NEXT_INST;
6135 }
6136 STREXB_INST:
6137 {
6138 INC_ICOUNTER;
6139 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6140 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6141 addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
6142 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff;
6143 fault = check_address_validity(cpu, addr, &phys_addr, 0);
6144 if (fault) goto MMU_EXCEPTION;
6145 //bus_write(8, addr, value);
6146 int dest_reg = BITS(inst_cream->inst, 12, 15);
6147 if((exclusive_detect(cpu, phys_addr) == 0) && (cpu->exclusive_state == 1)){
6148 remove_exclusive(cpu, phys_addr);
6149 cpu->Reg[dest_reg] = 0;
6150 cpu->exclusive_state = 0;
6151 fault = interpreter_write_memory(addr, phys_addr, value, 8);
6152 if (fault) goto MMU_EXCEPTION;
6153
6154 }
6155 else{
6156 cpu->Reg[dest_reg] = 1;
6157 }
6158 }
6159 cpu->Reg[15] += GET_INST_SIZE(cpu);
6160 INC_PC(sizeof(ldst_inst));
6161 FETCH_INST;
6162 GOTO_NEXT_INST;
6163 }
6164 STRH_INST:
6165 {
6166 INC_ICOUNTER;
6167 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6168 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6169 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6170 if (fault) goto MMU_EXCEPTION;
6171 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
6172 //bus_write(16, addr, value);
6173 fault = interpreter_write_memory(addr, phys_addr, value, 16);
6174 if (fault) goto MMU_EXCEPTION;
6175 }
6176 cpu->Reg[15] += GET_INST_SIZE(cpu);
6177 //if (BITS(inst_cream->inst, 12, 15) == 15)
6178 // goto PROFILING;
6179 INC_PC(sizeof(ldst_inst));
6180 FETCH_INST;
6181 GOTO_NEXT_INST;
6182 }
6183 STRT_INST:
6184 {
6185 INC_ICOUNTER;
6186 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
6187 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6188 fault = inst_cream->get_addr(cpu, inst_cream->inst, addr, phys_addr, 0);
6189 if (fault) goto MMU_EXCEPTION;
6190 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
6191 //bus_write(16, addr, value);
6192 fault = interpreter_write_memory(addr, phys_addr, value, 32);
6193 if (fault) goto MMU_EXCEPTION;
6194 }
6195 cpu->Reg[15] += GET_INST_SIZE(cpu);
6196 INC_PC(sizeof(ldst_inst));
6197 FETCH_INST;
6198 GOTO_NEXT_INST;
6199 }
6200 SUB_INST:
6201 {
6202 INC_ICOUNTER;
6203 sub_inst *inst_cream = (sub_inst *)inst_base->component;
6204 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6205 lop = RN;
6206 if (inst_cream->Rn == 15) {
6207 lop += 8;
6208 }
6209 rop = SHIFTER_OPERAND;
6210 RD = dst = lop - rop;
6211 if (inst_cream->S && (inst_cream->Rd == 15)) {
6212 /* cpsr = spsr */
6213 if (CurrentModeHasSPSR) {
6214 cpu->Cpsr = cpu->Spsr_copy;
6215 switch_mode(cpu, cpu->Spsr_copy & 0x1f);
6216 LOAD_NZCVT;
6217 }
6218 } else if (inst_cream->S) {
6219 UPDATE_NFLAG(dst);
6220 UPDATE_ZFLAG(dst);
6221// UPDATE_CFLAG(dst, lop, rop);
6222 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop);
6223 // UPDATE_VFLAG((int)dst, (int)lop, (int)rop);
6224 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop);
6225 }
6226 if (inst_cream->Rd == 15) {
6227 INC_PC(sizeof(sub_inst));
6228 goto PROFILING;
6229 }
6230 }
6231 cpu->Reg[15] += GET_INST_SIZE(cpu);
6232 INC_PC(sizeof(sub_inst));
6233 FETCH_INST;
6234 GOTO_NEXT_INST;
6235 }
6236 SWI_INST:
6237 {
6238 INC_ICOUNTER;
6239 swi_inst *inst_cream = (swi_inst *)inst_base->component;
6240 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6241 if (true){ //if (core->is_user_mode) { --> Citra only emulates user mode
6242 //arm_dyncom_SWI(cpu, inst_cream->num);
6243 HLE::CallSVC(Memory::Read32(cpu->Reg[15]));
6244 } else {
6245 cpu->syscallSig = 1;
6246 goto END;
6247 }
6248 }
6249 cpu->Reg[15] += GET_INST_SIZE(cpu);
6250 INC_PC(sizeof(swi_inst));
6251 FETCH_INST;
6252 GOTO_NEXT_INST;
6253 }
6254 SWP_INST:
6255 {
6256 INC_ICOUNTER;
6257 swp_inst *inst_cream = (swp_inst *)inst_base->component;
6258 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6259 addr = RN;
6260 fault = check_address_validity(cpu, addr, &phys_addr, 1);
6261 if (fault) goto MMU_EXCEPTION;
6262 unsigned int value;
6263 fault = interpreter_read_memory(addr, phys_addr, value, 32);
6264 if (fault) goto MMU_EXCEPTION;
6265 fault = interpreter_write_memory(addr, phys_addr, RM, 32);
6266 if (fault) goto MMU_EXCEPTION;
6267
6268 /* ROR(data, 8*UInt(address<1:0>)); */
6269 assert((phys_addr & 0x3) == 0);
6270 RD = value;
6271 }
6272 cpu->Reg[15] += GET_INST_SIZE(cpu);
6273 INC_PC(sizeof(swp_inst));
6274 FETCH_INST;
6275 GOTO_NEXT_INST;
6276 }
6277 SWPB_INST:
6278 {
6279 INC_ICOUNTER;
6280 swp_inst *inst_cream = (swp_inst *)inst_base->component;
6281 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6282 addr = RN;
6283 fault = check_address_validity(cpu, addr, &phys_addr, 1);
6284 if (fault) goto MMU_EXCEPTION;
6285 unsigned int value;
6286 fault = interpreter_read_memory(addr, phys_addr, value, 8);
6287 if (fault) goto MMU_EXCEPTION;
6288 fault = interpreter_write_memory(addr, phys_addr, (RM & 0xFF), 8);
6289 if (fault) goto MMU_EXCEPTION;
6290
6291 /* FIXME */
6292 #if 0
6293 if Shared(address) then
6294 /* ARMv6 */
6295 physical_address = TLB(address)
6296 ClearExclusiveByAddress(physical_address,processor_id,1)
6297 /* See Summary of operation on page A2-49 */
6298 #endif
6299 }
6300 cpu->Reg[15] += GET_INST_SIZE(cpu);
6301 INC_PC(sizeof(swp_inst));
6302 FETCH_INST;
6303 GOTO_NEXT_INST;
6304 }
6305 SXTAB_INST:
6306 {
6307 INC_ICOUNTER;
6308 sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
6309 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6310 /* R15 should be check */
6311 if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){
6312 CITRA_IGNORE_EXIT(-1);
6313 }
6314 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate)
6315 & 0xff;
6316 /* sign extend for byte */
6317 operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2;
6318 RD = RN + operand2;
6319 }
6320 cpu->Reg[15] += GET_INST_SIZE(cpu);
6321 INC_PC(sizeof(uxtab_inst));
6322 FETCH_INST;
6323 GOTO_NEXT_INST;
6324 }
6325 SXTAB16_INST:
6326 SXTAH_INST:
6327 {
6328 INC_ICOUNTER;
6329 sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
6330 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6331 /* R15 should be check */
6332 if(inst_cream->Rn == 15 || inst_cream->Rm == 15 || inst_cream->Rd ==15){
6333 CITRA_IGNORE_EXIT(-1);
6334 }
6335 unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff;
6336 /* sign extend for half */
6337 operand2 = (0x8000 & operand2)? (0xFFFF0000 | operand2):operand2;
6338 RD = RN + operand2;
6339 }
6340 cpu->Reg[15] += GET_INST_SIZE(cpu);
6341 INC_PC(sizeof(sxtah_inst));
6342 FETCH_INST;
6343 GOTO_NEXT_INST;
6344 }
6345 SXTB16_INST:
6346 TEQ_INST:
6347 {
6348 INC_ICOUNTER;
6349 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6350 teq_inst *inst_cream = (teq_inst *)inst_base->component;
6351 lop = RN;
6352 if (inst_cream->Rn == 15)
6353 lop += GET_INST_SIZE(cpu) * 2;
6354
6355 rop = SHIFTER_OPERAND;
6356 dst = lop ^ rop;
6357
6358 UPDATE_NFLAG(dst);
6359 UPDATE_ZFLAG(dst);
6360 UPDATE_CFLAG_WITH_SC;
6361 }
6362 cpu->Reg[15] += GET_INST_SIZE(cpu);
6363 INC_PC(sizeof(teq_inst));
6364 FETCH_INST;
6365 GOTO_NEXT_INST;
6366 }
6367 TST_INST:
6368 {
6369 INC_ICOUNTER;
6370 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6371 tst_inst *inst_cream = (tst_inst *)inst_base->component;
6372 lop = RN;
6373 if (inst_cream->Rn == 15)
6374 lop += GET_INST_SIZE(cpu) * 2;
6375 rop = SHIFTER_OPERAND;
6376 dst = lop & rop;
6377
6378 UPDATE_NFLAG(dst);
6379 UPDATE_ZFLAG(dst);
6380 UPDATE_CFLAG_WITH_SC;
6381 }
6382 cpu->Reg[15] += GET_INST_SIZE(cpu);
6383 INC_PC(sizeof(tst_inst));
6384 FETCH_INST;
6385 GOTO_NEXT_INST;
6386 }
6387 UADD16_INST:
6388 UADD8_INST:
6389 UADDSUBX_INST:
6390 UHADD16_INST:
6391 UHADD8_INST:
6392 UHADDSUBX_INST:
6393 UHSUB16_INST:
6394 UHSUB8_INST:
6395 UHSUBADDX_INST:
6396 UMAAL_INST:
6397 UMLAL_INST:
6398 {
6399 INC_ICOUNTER;
6400 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6401 umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
6402 unsigned long long int rm = RM;
6403 unsigned long long int rs = RS;
6404 unsigned long long int rst = rm * rs;
6405 unsigned long long int add = ((unsigned long long) RDHI)<<32;
6406 add += RDLO;
6407 //DEBUG_LOG(ARM11, "rm[%llx] * rs[%llx] = rst[%llx] | add[%llx]\n", RM, RS, rst, add);
6408 rst += add;
6409 RDLO = BITS(rst, 0, 31);
6410 RDHI = BITS(rst, 32, 63);
6411
6412 if (inst_cream->S)
6413 {
6414 cpu->NFlag = BIT(RDHI, 31);
6415 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
6416 }
6417 }
6418 cpu->Reg[15] += GET_INST_SIZE(cpu);
6419 INC_PC(sizeof(umlal_inst));
6420 FETCH_INST;
6421 GOTO_NEXT_INST;
6422 }
6423 UMULL_INST:
6424 {
6425 INC_ICOUNTER;
6426 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
6427 umull_inst *inst_cream = (umull_inst *)inst_base->component;
6428 unsigned long long int rm = RM;
6429 unsigned long long int rs = RS;
6430 unsigned long long int rst = rm * rs;
6431// DEBUG_LOG(ARM11, "rm : [%llx] rs : [%llx] rst [%llx]\n", RM, RS, rst);
6432 RDHI = BITS(rst, 32, 63);
6433 RDLO = BITS(rst, 0, 31);
6434
6435 if (inst_cream->S) {
6436 cpu->NFlag = BIT(RDHI, 31);
6437 cpu->ZFlag = (RDHI == 0 && RDLO == 0);
6438 }
6439 }
6440 cpu->Reg[15] += GET_INST_SIZE(cpu);
6441 INC_PC(sizeof(umull_inst));
6442 FETCH_INST;
6443 GOTO_NEXT_INST;
6444 }
6445 B_2_THUMB:
6446 {
6447 INC_ICOUNTER;
6448 b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
6449 cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
6450 //DEBUG_LOG(ARM11, " BL_1_THUMB: imm=0x%x, r14=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]);
6451 INC_PC(sizeof(b_2_thumb));
6452 goto PROFILING;
6453 }
6454 B_COND_THUMB:
6455 {
6456 INC_ICOUNTER;
6457 b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
6458 if(CondPassed(cpu, inst_cream->cond))
6459 cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm;
6460 else
6461 cpu->Reg[15] += 2;
6462 //DEBUG_LOG(ARM11, " B_COND_THUMB: imm=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[15]);
6463 INC_PC(sizeof(b_cond_thumb));
6464 goto PROFILING;
6465 }
6466 BL_1_THUMB:
6467 {
6468 INC_ICOUNTER;
6469 bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
6470 cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm;
6471 //cpu->Reg[15] += 2;
6472 //DEBUG_LOG(ARM11, " BL_1_THUMB: imm=0x%x, r14=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]);
6473
6474 cpu->Reg[15] += GET_INST_SIZE(cpu);
6475 INC_PC(sizeof(bl_1_thumb));
6476 FETCH_INST;
6477 GOTO_NEXT_INST;
6478
6479 }
6480 BL_2_THUMB:
6481 {
6482 INC_ICOUNTER;
6483 bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
6484 int tmp = ((cpu->Reg[15] + 2) | 1);
6485 cpu->Reg[15] =
6486 (cpu->Reg[14] + inst_cream->imm);
6487 cpu->Reg[14] = tmp;
6488 //DEBUG_LOG(ARM11, " BL_2_THUMB: imm=0x%x, r14=0x%x, r15=0x%x\n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]);
6489 INC_PC(sizeof(bl_2_thumb));
6490 goto PROFILING;
6491 }
6492 BLX_1_THUMB:
6493 {
6494 /* BLX 1 for armv5t and above */
6495 INC_ICOUNTER;
6496 uint32 tmp = cpu->Reg[15];
6497 blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
6498 cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC;
6499 //DEBUG_LOG(ARM11, "In BLX_1_THUMB, BLX(1),imm=0x%x,r14=0x%x, instr=0x%x\n", inst_cream->imm, cpu->Reg[14], inst_cream->instr);
6500 cpu->Reg[14] = ((tmp + 2) | 1);
6501 //(state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC;
6502 /* switch to arm state from thumb state */
6503 cpu->TFlag = 0;
6504 //DEBUG_LOG(ARM11, "In BLX_1_THUMB, BLX(1),imm=0x%x,r14=0x%x, r15=0x%x, \n", inst_cream->imm, cpu->Reg[14], cpu->Reg[15]);
6505 INC_PC(sizeof(blx_1_thumb));
6506 goto PROFILING;
6507 }
6508
6509 UQADD16_INST:
6510 UQADD8_INST:
6511 UQADDSUBX_INST:
6512 UQSUB16_INST:
6513 UQSUB8_INST:
6514 UQSUBADDX_INST:
6515 USAD8_INST:
6516 USADA8_INST:
6517 USAT_INST:
6518 USAT16_INST:
6519 USUB16_INST:
6520 USUB8_INST:
6521 USUBADDX_INST:
6522 UXTAB16_INST:
6523 UXTB16_INST:
6524 #define VFP_INTERPRETER_IMPL
6525 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
6526 #undef VFP_INTERPRETER_IMPL
6527 MMU_EXCEPTION:
6528 {
6529 SAVE_NZCVT;
6530 cpu->abortSig = true;
6531 cpu->Aborted = ARMul_DataAbortV;
6532 cpu->AbortAddr = addr;
6533 cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff;
6534 cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr;
6535 return;
6536 }
6537 END:
6538 {
6539 SAVE_NZCVT;
6540 return;
6541 }
6542 INIT_INST_LENGTH:
6543 {
6544#if 0
6545 DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel));
6546 for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++)
6547 DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]);
6548 DEBUG_LOG(ARM11, "InstLabel:%d\n", sizeof(InstLabel));
6549#endif
6550#if defined __GNUC__ || defined __clang__
6551 InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel));
6552#endif
6553#if 0
6554 for (int i = 0; i < (sizeof(InstLabel) / sizeof(void *)); i ++)
6555 DEBUG_LOG(ARM11, "[%llx]\n", InstLabel[i]);
6556 DEBUG_LOG(ARM11, "%llx\n", InstEndLabel[1]);
6557 DEBUG_LOG(ARM11, "%llx\n", InstLabel[1]);
6558 DEBUG_LOG(ARM11, "%lld\n", (char *)InstEndLabel[1] - (char *)InstLabel[1]);
6559#endif
6560 return;
6561 }
6562}
6563
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.h b/src/core/arm/dyncom/arm_dyncom_interpreter.h
new file mode 100644
index 000000000..d73f8f65f
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.h
@@ -0,0 +1,7 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#pragma once
6
7void InterpreterMainLoop(ARMul_State* state);
diff --git a/src/core/arm/dyncom/arm_dyncom_run.cpp b/src/core/arm/dyncom/arm_dyncom_run.cpp
new file mode 100644
index 000000000..a2026cbf3
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_run.cpp
@@ -0,0 +1,120 @@
1/* Copyright (C)
2* 2011 - Michael.Kang blackfin.kang@gmail.com
3* This program is free software; you can redistribute it and/or
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18/**
19* @file arm_dyncom_run.cpp
20* @brief The dyncom run implementation for arm
21* @author Michael.Kang blackfin.kang@gmail.com
22* @version 78.77
23* @date 2011-11-20
24*/
25
26#include <assert.h>
27
28#include "core/arm/skyeye_common/armdefs.h"
29
30void switch_mode(arm_core_t *core, uint32_t mode)
31{
32 uint32_t tmp1, tmp2;
33 if (core->Mode == mode) {
34 //Mode not changed.
35 //printf("mode not changed\n");
36 return;
37 }
38 //printf("%d --->>> %d\n", core->Mode, mode);
39 //printf("In %s, Cpsr=0x%x, R15=0x%x, last_pc=0x%x, cpsr=0x%x, spsr_copy=0x%x, icounter=%lld\n", __FUNCTION__, core->Cpsr, core->Reg[15], core->last_pc, core->Cpsr, core->Spsr_copy, core->icounter);
40 if (mode != USERBANK) {
41 switch (core->Mode) {
42 case USER32MODE:
43 core->Reg_usr[0] = core->Reg[13];
44 core->Reg_usr[1] = core->Reg[14];
45 break;
46 case IRQ32MODE:
47 core->Reg_irq[0] = core->Reg[13];
48 core->Reg_irq[1] = core->Reg[14];
49 core->Spsr[IRQBANK] = core->Spsr_copy;
50 break;
51 case SVC32MODE:
52 core->Reg_svc[0] = core->Reg[13];
53 core->Reg_svc[1] = core->Reg[14];
54 core->Spsr[SVCBANK] = core->Spsr_copy;
55 break;
56 case ABORT32MODE:
57 core->Reg_abort[0] = core->Reg[13];
58 core->Reg_abort[1] = core->Reg[14];
59 core->Spsr[ABORTBANK] = core->Spsr_copy;
60 break;
61 case UNDEF32MODE:
62 core->Reg_undef[0] = core->Reg[13];
63 core->Reg_undef[1] = core->Reg[14];
64 core->Spsr[UNDEFBANK] = core->Spsr_copy;
65 break;
66 case FIQ32MODE:
67 core->Reg_firq[0] = core->Reg[13];
68 core->Reg_firq[1] = core->Reg[14];
69 core->Spsr[FIQBANK] = core->Spsr_copy;
70 break;
71
72 }
73
74 switch (mode) {
75 case USER32MODE:
76 core->Reg[13] = core->Reg_usr[0];
77 core->Reg[14] = core->Reg_usr[1];
78 core->Bank = USERBANK;
79 break;
80 case IRQ32MODE:
81 core->Reg[13] = core->Reg_irq[0];
82 core->Reg[14] = core->Reg_irq[1];
83 core->Spsr_copy = core->Spsr[IRQBANK];
84 core->Bank = IRQBANK;
85 break;
86 case SVC32MODE:
87 core->Reg[13] = core->Reg_svc[0];
88 core->Reg[14] = core->Reg_svc[1];
89 core->Spsr_copy = core->Spsr[SVCBANK];
90 core->Bank = SVCBANK;
91 break;
92 case ABORT32MODE:
93 core->Reg[13] = core->Reg_abort[0];
94 core->Reg[14] = core->Reg_abort[1];
95 core->Spsr_copy = core->Spsr[ABORTBANK];
96 core->Bank = ABORTBANK;
97 break;
98 case UNDEF32MODE:
99 core->Reg[13] = core->Reg_undef[0];
100 core->Reg[14] = core->Reg_undef[1];
101 core->Spsr_copy = core->Spsr[UNDEFBANK];
102 core->Bank = UNDEFBANK;
103 break;
104 case FIQ32MODE:
105 core->Reg[13] = core->Reg_firq[0];
106 core->Reg[14] = core->Reg_firq[1];
107 core->Spsr_copy = core->Spsr[FIQBANK];
108 core->Bank = FIQBANK;
109 break;
110
111 }
112 core->Mode = mode;
113 //printf("In %si end, Cpsr=0x%x, R15=0x%x, last_pc=0x%x, cpsr=0x%x, spsr_copy=0x%x, icounter=%lld\n", __FUNCTION__, core->Cpsr, core->Reg[15], core->last_pc, core->Cpsr, core->Spsr_copy, core->icounter);
114 //printf("\n--------------------------------------\n");
115 }
116 else {
117 printf("user mode\n");
118 exit(-2);
119 }
120}
diff --git a/src/core/arm/dyncom/arm_dyncom_run.h b/src/core/arm/dyncom/arm_dyncom_run.h
new file mode 100644
index 000000000..aeabeac16
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_run.h
@@ -0,0 +1,55 @@
1/* Copyright (C)
2* 2011 - Michael.Kang blackfin.kang@gmail.com
3* This program is free software; you can redistribute it and/or
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18
19#ifndef __ARM_DYNCOM_RUN__
20#define __ARM_DYNCOM_RUN__
21
22#include "core/arm/skyeye_common/skyeye_types.h"
23
24void switch_mode(arm_core_t *core, uint32_t mode);
25
26/* FIXME, we temporarily think thumb instruction is always 16 bit */
27static inline uint32 GET_INST_SIZE(arm_core_t* core){
28 return core->TFlag? 2 : 4;
29}
30
31/**
32* @brief Read R15 and forced R15 to wold align, used address calculation
33*
34* @param core
35* @param Rn
36*
37* @return
38*/
39static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn){
40 return (Rn == 15)? ((core->Reg[15] & ~0x3) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
41}
42
43/**
44* @brief Read R15, used to data processing with pc
45*
46* @param core
47* @param Rn
48*
49* @return
50*/
51static inline uint32 CHECK_READ_REG15(arm_core_t* core, int Rn){
52 return (Rn == 15)? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
53}
54
55#endif
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
new file mode 100644
index 000000000..e10f2f9ee
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
@@ -0,0 +1,521 @@
1/* Copyright (C)
2* 2011 - Michael.Kang blackfin.kang@gmail.com
3* This program is free software; you can redistribute it and/or
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18/**
19* @file arm_dyncom_thumb.c
20* @brief The thumb dynamic interpreter
21* @author Michael.Kang blackfin.kang@gmail.com
22* @version 78.77
23* @date 2011-11-07
24*/
25
26/* We can provide simple Thumb simulation by decoding the Thumb
27instruction into its corresponding ARM instruction, and using the
28existing ARM simulator. */
29
30#include "core/arm/skyeye_common/skyeye_defs.h"
31
32#ifndef MODET /* required for the Thumb instruction support */
33#if 1
34#error "MODET needs to be defined for the Thumb world to work"
35#else
36#define MODET (1)
37#endif
38#endif
39
40#include "core/arm/skyeye_common/armos.h"
41#include "core/arm/dyncom/arm_dyncom_thumb.h"
42
43/* Decode a 16bit Thumb instruction. The instruction is in the low
44 16-bits of the tinstr field, with the following Thumb instruction
45 held in the high 16-bits. Passing in two Thumb instructions allows
46 easier simulation of the special dual BL instruction. */
47
48tdstate thumb_translate (addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size)
49{
50 tdstate valid = t_uninitialized;
51 ARMword next_instr;
52 ARMword tinstr;
53 tinstr = instr;
54 /* The endian should be judge here */
55 #if 0
56 if (state->bigendSig) {
57 next_instr = tinstr & 0xFFFF;
58 tinstr >>= 16;
59 }
60 else {
61 next_instr = tinstr >> 16;
62 tinstr &= 0xFFFF;
63 }
64 #endif
65 if((addr & 0x3) != 0)
66 tinstr = instr >> 16;
67 else
68 tinstr &= 0xFFFF;
69
70 //printf("In %s, instr=0x%x, tinstr=0x%x, r15=0x%x\n", __FUNCTION__, instr, tinstr, cpu->translate_pc);
71#if 1 /* debugging to catch non updates */
72 *ainstr = 0xDEADC0DE;
73#endif
74
75 switch ((tinstr & 0xF800) >> 11) {
76 case 0: /* LSL */
77 case 1: /* LSR */
78 case 2: /* ASR */
79 /* Format 1 */
80 *ainstr = 0xE1B00000 /* base opcode */
81 | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */
82 |((tinstr & 0x07C0) << (7 - 6)) /* imm5 */
83 |((tinstr & 0x0038) >> 3) /* Rs */
84 |((tinstr & 0x0007) << 12); /* Rd */
85 break;
86 case 3: /* ADD/SUB */
87 /* Format 2 */
88 {
89 ARMword subset[4] = {
90 0xE0900000, /* ADDS Rd,Rs,Rn */
91 0xE0500000, /* SUBS Rd,Rs,Rn */
92 0xE2900000, /* ADDS Rd,Rs,#imm3 */
93 0xE2500000 /* SUBS Rd,Rs,#imm3 */
94 };
95 /* It is quicker indexing into a table, than performing switch
96 or conditionals: */
97 *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */
98 |((tinstr & 0x01C0) >> 6) /* Rn or imm3 */
99 |((tinstr & 0x0038) << (16 - 3)) /* Rs */
100 |((tinstr & 0x0007) << (12 - 0)); /* Rd */
101 }
102 break;
103 case 4: /* MOV */
104 case 5: /* CMP */
105 case 6: /* ADD */
106 case 7: /* SUB */
107 /* Format 3 */
108 {
109 ARMword subset[4] = {
110 0xE3B00000, /* MOVS Rd,#imm8 */
111 0xE3500000, /* CMP Rd,#imm8 */
112 0xE2900000, /* ADDS Rd,Rd,#imm8 */
113 0xE2500000, /* SUBS Rd,Rd,#imm8 */
114 };
115 *ainstr = subset[(tinstr & 0x1800) >> 11] /* base opcode */
116 |((tinstr & 0x00FF) >> 0) /* imm8 */
117 |((tinstr & 0x0700) << (16 - 8)) /* Rn */
118 |((tinstr & 0x0700) << (12 - 8)); /* Rd */
119 }
120 break;
121 case 8: /* Arithmetic and high register transfers */
122 /* TODO: Since the subsets for both Format 4 and Format 5
123 instructions are made up of different ARM encodings, we could
124 save the following conditional, and just have one large
125 subset. */
126 if ((tinstr & (1 << 10)) == 0) {
127 typedef enum
128 { t_norm, t_shift, t_neg, t_mul }otype_t;
129
130 /* Format 4 */
131 struct
132 {
133 ARMword opcode;
134 otype_t otype;
135 }
136 subset[16] = {
137 {
138 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */
139 {
140 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */
141 {
142 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */
143 {
144 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */
145 {
146 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */
147 {
148 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */
149 {
150 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */
151 {
152 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */
153 {
154 0xE1100000, t_norm}, /* TST Rd,Rs */
155 {
156 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */
157 {
158 0xE1500000, t_norm}, /* CMP Rd,Rs */
159 {
160 0xE1700000, t_norm}, /* CMN Rd,Rs */
161 {
162 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */
163 {
164 0xE0100090, t_mul}, /* MULS Rd,Rd,Rs */
165 {
166 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */
167 {
168 0xE1F00000, t_norm} /* MVNS Rd,Rs */
169 };
170 *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
171 switch (subset[(tinstr & 0x03C0) >> 6].otype) {
172 case t_norm:
173 *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */
174 |((tinstr & 0x0007) << 12) /* Rd */
175 |((tinstr & 0x0038) >> 3); /* Rs */
176 break;
177 case t_shift:
178 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
179 |((tinstr & 0x0007) >> 0) /* Rm */
180 |((tinstr & 0x0038) << (8 - 3)); /* Rs */
181 break;
182 case t_neg:
183 *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
184 |((tinstr & 0x0038) << (16 - 3)); /* Rn */
185 break;
186 case t_mul:
187 *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */
188 |((tinstr & 0x0007) << 8) /* Rs */
189 |((tinstr & 0x0038) >> 3); /* Rm */
190 break;
191 }
192 }
193 else {
194 /* Format 5 */
195 ARMword Rd = ((tinstr & 0x0007) >> 0);
196 ARMword Rs = ((tinstr & 0x0038) >> 3);
197 if (tinstr & (1 << 7))
198 Rd += 8;
199 if (tinstr & (1 << 6))
200 Rs += 8;
201 switch ((tinstr & 0x03C0) >> 6) {
202 case 0x1: /* ADD Rd,Rd,Hs */
203 case 0x2: /* ADD Hd,Hd,Rs */
204 case 0x3: /* ADD Hd,Hd,Hs */
205 *ainstr = 0xE0800000 /* base */
206 | (Rd << 16) /* Rn */
207 |(Rd << 12) /* Rd */
208 |(Rs << 0); /* Rm */
209 break;
210 case 0x5: /* CMP Rd,Hs */
211 case 0x6: /* CMP Hd,Rs */
212 case 0x7: /* CMP Hd,Hs */
213 *ainstr = 0xE1500000 /* base */
214 | (Rd << 16) /* Rn */
215 |(Rd << 12) /* Rd */
216 |(Rs << 0); /* Rm */
217 break;
218 case 0x9: /* MOV Rd,Hs */
219 case 0xA: /* MOV Hd,Rs */
220 case 0xB: /* MOV Hd,Hs */
221 *ainstr = 0xE1A00000 /* base */
222 | (Rd << 16) /* Rn */
223 |(Rd << 12) /* Rd */
224 |(Rs << 0); /* Rm */
225 break;
226 case 0xC: /* BX Rs */
227 case 0xD: /* BX Hs */
228 *ainstr = 0xE12FFF10 /* base */
229 | ((tinstr & 0x0078) >> 3); /* Rd */
230 break;
231 case 0x0: /* UNDEFINED */
232 case 0x4: /* UNDEFINED */
233 case 0x8: /* UNDEFINED */
234 valid = t_undefined;
235 break;
236 case 0xE: /* BLX */
237 case 0xF: /* BLX */
238
239 //if (state->is_v5) {
240 if(1){
241 //valid = t_branch;
242 #if 1
243 *ainstr = 0xE1200030 /* base */
244 |(Rs << 0); /* Rm */
245 #endif
246 } else {
247 valid = t_undefined;
248 }
249 break;
250 }
251 }
252 break;
253 case 9: /* LDR Rd,[PC,#imm8] */
254 /* Format 6 */
255 *ainstr = 0xE59F0000 /* base */
256 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
257 |((tinstr & 0x00FF) << (2 - 0)); /* off8 */
258 break;
259 case 10:
260 case 11:
261 /* TODO: Format 7 and Format 8 perform the same ARM encoding, so
262 the following could be merged into a single subset, saving on
263 the following boolean: */
264 if ((tinstr & (1 << 9)) == 0) {
265 /* Format 7 */
266 ARMword subset[4] = {
267 0xE7800000, /* STR Rd,[Rb,Ro] */
268 0xE7C00000, /* STRB Rd,[Rb,Ro] */
269 0xE7900000, /* LDR Rd,[Rb,Ro] */
270 0xE7D00000 /* LDRB Rd,[Rb,Ro] */
271 };
272 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
273 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
274 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
275 |((tinstr & 0x01C0) >> 6); /* Ro */
276 }
277 else {
278 /* Format 8 */
279 ARMword subset[4] = {
280 0xE18000B0, /* STRH Rd,[Rb,Ro] */
281 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */
282 0xE19000B0, /* LDRH Rd,[Rb,Ro] */
283 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */
284 };
285 *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
286 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
287 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
288 |((tinstr & 0x01C0) >> 6); /* Ro */
289 }
290 break;
291 case 12: /* STR Rd,[Rb,#imm5] */
292 case 13: /* LDR Rd,[Rb,#imm5] */
293 case 14: /* STRB Rd,[Rb,#imm5] */
294 case 15: /* LDRB Rd,[Rb,#imm5] */
295 /* Format 9 */
296 {
297 ARMword subset[4] = {
298 0xE5800000, /* STR Rd,[Rb,#imm5] */
299 0xE5900000, /* LDR Rd,[Rb,#imm5] */
300 0xE5C00000, /* STRB Rd,[Rb,#imm5] */
301 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */
302 };
303 /* The offset range defends on whether we are transferring a
304 byte or word value: */
305 *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */
306 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
307 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
308 |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */
309 }
310 break;
311 case 16: /* STRH Rd,[Rb,#imm5] */
312 case 17: /* LDRH Rd,[Rb,#imm5] */
313 /* Format 10 */
314 *ainstr = ((tinstr & (1 << 11)) /* base */
315 ? 0xE1D000B0 /* LDRH */
316 : 0xE1C000B0) /* STRH */
317 |((tinstr & 0x0007) << (12 - 0)) /* Rd */
318 |((tinstr & 0x0038) << (16 - 3)) /* Rb */
319 |((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */
320 |((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */
321 break;
322 case 18: /* STR Rd,[SP,#imm8] */
323 case 19: /* LDR Rd,[SP,#imm8] */
324 /* Format 11 */
325 *ainstr = ((tinstr & (1 << 11)) /* base */
326 ? 0xE59D0000 /* LDR */
327 : 0xE58D0000) /* STR */
328 |((tinstr & 0x0700) << (12 - 8)) /* Rd */
329 |((tinstr & 0x00FF) << 2); /* off8 */
330 break;
331 case 20: /* ADD Rd,PC,#imm8 */
332 case 21: /* ADD Rd,SP,#imm8 */
333 /* Format 12 */
334 if ((tinstr & (1 << 11)) == 0) {
335 /* NOTE: The PC value used here should by word aligned */
336 /* We encode shift-left-by-2 in the rotate immediate field,
337 so no shift of off8 is needed. */
338 *ainstr = 0xE28F0F00 /* base */
339 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
340 |(tinstr & 0x00FF); /* off8 */
341 }
342 else {
343 /* We encode shift-left-by-2 in the rotate immediate field,
344 so no shift of off8 is needed. */
345 *ainstr = 0xE28D0F00 /* base */
346 | ((tinstr & 0x0700) << (12 - 8)) /* Rd */
347 |(tinstr & 0x00FF); /* off8 */
348 }
349 break;
350 case 22:
351 case 23:
352 if ((tinstr & 0x0F00) == 0x0000) {
353 /* Format 13 */
354 /* NOTE: The instruction contains a shift left of 2
355 equivalent (implemented as ROR #30): */
356 *ainstr = ((tinstr & (1 << 7)) /* base */
357 ? 0xE24DDF00 /* SUB */
358 : 0xE28DDF00) /* ADD */
359 |(tinstr & 0x007F); /* off7 */
360 }
361 else if ((tinstr & 0x0F00) == 0x0e00)
362 *ainstr = 0xEF000000 | SWI_Breakpoint;
363 else {
364 /* Format 14 */
365 ARMword subset[4] = {
366 0xE92D0000, /* STMDB sp!,{rlist} */
367 0xE92D4000, /* STMDB sp!,{rlist,lr} */
368 0xE8BD0000, /* LDMIA sp!,{rlist} */
369 0xE8BD8000 /* LDMIA sp!,{rlist,pc} */
370 };
371 *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] /* base */
372 |(tinstr & 0x00FF); /* mask8 */
373 }
374 break;
375 case 24: /* STMIA */
376 case 25: /* LDMIA */
377 /* Format 15 */
378 *ainstr = ((tinstr & (1 << 11)) /* base */
379 ? 0xE8B00000 /* LDMIA */
380 : 0xE8A00000) /* STMIA */
381 |((tinstr & 0x0700) << (16 - 8)) /* Rb */
382 |(tinstr & 0x00FF); /* mask8 */
383 break;
384 case 26: /* Bcc */
385 case 27: /* Bcc/SWI */
386 if ((tinstr & 0x0F00) == 0x0F00) {
387 #if 0
388 if (tinstr == (ARMul_ABORTWORD & 0xffff) &&
389 state->AbortAddr == pc) {
390 *ainstr = ARMul_ABORTWORD;
391 break;
392 }
393 #endif
394 /* Format 17 : SWI */
395 *ainstr = 0xEF000000;
396 /* Breakpoint must be handled specially. */
397 if ((tinstr & 0x00FF) == 0x18)
398 *ainstr |= ((tinstr & 0x00FF) << 16);
399 /* New breakpoint value. See gdb/arm-tdep.c */
400 else if ((tinstr & 0x00FF) == 0xFE)
401 *ainstr |= SWI_Breakpoint;
402 else
403 *ainstr |= (tinstr & 0x00FF);
404 }
405 else if ((tinstr & 0x0F00) != 0x0E00) {
406 /* Format 16 */
407 #if 0
408 int doit = FALSE;
409 /* TODO: Since we are doing a switch here, we could just add
410 the SWI and undefined instruction checks into this
411 switch to same on a couple of conditionals: */
412 switch ((tinstr & 0x0F00) >> 8) {
413 case EQ:
414 doit = ZFLAG;
415 break;
416 case NE:
417 doit = !ZFLAG;
418 break;
419 case VS:
420 doit = VFLAG;
421 break;
422 case VC:
423 doit = !VFLAG;
424 break;
425 case MI:
426 doit = NFLAG;
427 break;
428 case PL:
429 doit = !NFLAG;
430 break;
431 case CS:
432 doit = CFLAG;
433 break;
434 case CC:
435 doit = !CFLAG;
436 break;
437 case HI:
438 doit = (CFLAG && !ZFLAG);
439 break;
440 case LS:
441 doit = (!CFLAG || ZFLAG);
442 break;
443 case GE:
444 doit = ((!NFLAG && !VFLAG)
445 || (NFLAG && VFLAG));
446 break;
447 case LT:
448 doit = ((NFLAG && !VFLAG)
449 || (!NFLAG && VFLAG));
450 break;
451 case GT:
452 doit = ((!NFLAG && !VFLAG && !ZFLAG)
453 || (NFLAG && VFLAG && !ZFLAG));
454 break;
455 case LE:
456 doit = ((NFLAG && !VFLAG)
457 || (!NFLAG && VFLAG)) || ZFLAG;
458 break;
459 }
460 if (doit) {
461 state->Reg[15] = (pc + 4
462 + (((tinstr & 0x7F) << 1)
463 | ((tinstr & (1 << 7)) ?
464 0xFFFFFF00 : 0)));
465 FLUSHPIPE;
466 }
467 #endif
468 valid = t_branch;
469 }
470 else /* UNDEFINED : cc=1110(AL) uses different format */
471 valid = t_undefined;
472 break;
473 case 28: /* B */
474 /* Format 18 */
475 #if 0
476 state->Reg[15] = (pc + 4 + (((tinstr & 0x3FF) << 1)
477 | ((tinstr & (1 << 10)) ?
478 0xFFFFF800 : 0)));
479 #endif
480 //FLUSHPIPE;
481 valid = t_branch;
482 break;
483 case 29:
484 if(tinstr & 0x1)
485 valid = t_undefined;
486 else{
487 /* BLX 1 for armv5t and above */
488 //printf("In %s, After BLX(1),LR=0x%x,PC=0x%x, offset=0x%x\n", __FUNCTION__, state->Reg[14], state->Reg[15], (tinstr &0x7FF) << 1);
489 valid = t_branch;
490 }
491 break;
492 case 30: /* BL instruction 1 */
493 /* Format 19 */
494 /* There is no single ARM instruction equivalent for this Thumb
495 instruction. To keep the simulation simple (from the user
496 perspective) we check if the following instruction is the
497 second half of this BL, and if it is we simulate it
498 immediately. */
499 valid = t_branch;
500 break;
501 case 31: /* BL instruction 2 */
502 /* Format 19 */
503 /* There is no single ARM instruction equivalent for this
504 instruction. Also, it should only ever be matched with the
505 fmt19 "BL instruction 1" instruction. However, we do allow
506 the simulation of it on its own, with undefined results if
507 r14 is not suitably initialised. */
508 {
509 #if 0
510 ARMword tmp = (pc + 2);
511 state->Reg[15] =
512 (state->Reg[14] + ((tinstr & 0x07FF) << 1));
513 state->Reg[14] = (tmp | 1);
514 #endif
515 valid = t_branch;
516 }
517 break;
518 }
519 *inst_size = 2;
520 return valid;
521}
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.h b/src/core/arm/dyncom/arm_dyncom_thumb.h
new file mode 100644
index 000000000..5541de9d1
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.h
@@ -0,0 +1,51 @@
1/* Copyright (C)
2* 2011 - Michael.Kang blackfin.kang@gmail.com
3* This program is free software; you can redistribute it and/or
4* modify it under the terms of the GNU General Public License
5* as published by the Free Software Foundation; either version 2
6* of the License, or (at your option) any later version.
7*
8* This program is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program; if not, write to the Free Software
15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*
17*/
18
19/**
20* @file arm_dyncom_thumb.h
21* @brief The thumb dyncom
22* @author Michael.Kang blackfin.kang@gmail.com
23* @version 78.77
24* @date 2011-11-07
25*/
26
27#ifndef __ARM_DYNCOM_THUMB_H__
28#define __ARM_DYNCOM_THUMB_H__
29
30#include "core/arm/skyeye_common/armdefs.h"
31#include "core/arm/skyeye_common/skyeye_types.h"
32
33enum tdstate {
34 t_undefined, // Undefined Thumb instruction
35 t_decoded, // Instruction decoded to ARM equivalent
36 t_branch, // Thumb branch (already processed)
37 t_uninitialized,
38};
39
40tdstate
41thumb_translate(addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size);
42static inline uint32 get_thumb_instr(uint32 instr, addr_t pc){
43 uint32 tinstr;
44 if ((pc & 0x3) != 0)
45 tinstr = instr >> 16;
46 else
47 tinstr = instr & 0xFFFF;
48 return tinstr;
49}
50
51#endif
diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp
index 0842d2f8e..ed4415082 100644
--- a/src/core/arm/interpreter/arm_interpreter.cpp
+++ b/src/core/arm/interpreter/arm_interpreter.cpp
@@ -4,7 +4,7 @@
4 4
5#include "core/arm/interpreter/arm_interpreter.h" 5#include "core/arm/interpreter/arm_interpreter.h"
6 6
7const static cpu_config_t s_arm11_cpu_info = { 7const static cpu_config_t arm11_cpu_info = {
8 "armv6", "arm11", 0x0007b000, 0x0007f000, NONCACHE 8 "armv6", "arm11", 0x0007b000, 0x0007f000, NONCACHE
9}; 9};
10 10
@@ -17,12 +17,11 @@ ARM_Interpreter::ARM_Interpreter() {
17 ARMul_NewState(state); 17 ARMul_NewState(state);
18 18
19 state->abort_model = 0; 19 state->abort_model = 0;
20 state->cpu = (cpu_config_t*)&s_arm11_cpu_info; 20 state->cpu = (cpu_config_t*)&arm11_cpu_info;
21 state->bigendSig = LOW; 21 state->bigendSig = LOW;
22 22
23 ARMul_SelectProcessor(state, ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop); 23 ARMul_SelectProcessor(state, ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop);
24 state->lateabtSig = LOW; 24 state->lateabtSig = LOW;
25 mmu_init(state);
26 25
27 // Reset the core to initial state 26 // Reset the core to initial state
28 ARMul_CoProInit(state); 27 ARMul_CoProInit(state);
diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h
index 1e82883a2..49ae01a0c 100644
--- a/src/core/arm/interpreter/arm_interpreter.h
+++ b/src/core/arm/interpreter/arm_interpreter.h
@@ -7,10 +7,10 @@
7#include "common/common.h" 7#include "common/common.h"
8 8
9#include "core/arm/arm_interface.h" 9#include "core/arm/arm_interface.h"
10#include "core/arm/interpreter/armdefs.h" 10#include "core/arm/skyeye_common/armdefs.h"
11#include "core/arm/interpreter/armemu.h" 11#include "core/arm/skyeye_common/armemu.h"
12 12
13class ARM_Interpreter : virtual public ARM_Interface { 13class ARM_Interpreter final : virtual public ARM_Interface {
14public: 14public:
15 15
16 ARM_Interpreter(); 16 ARM_Interpreter();
diff --git a/src/core/arm/interpreter/armcopro.cpp b/src/core/arm/interpreter/armcopro.cpp
index 6a75e6601..b4ddc3d96 100644
--- a/src/core/arm/interpreter/armcopro.cpp
+++ b/src/core/arm/interpreter/armcopro.cpp
@@ -15,828 +15,311 @@
15 along with this program; if not, write to the Free Software 15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17 17
18 18#include "core/arm/skyeye_common/armdefs.h"
19#include "core/arm/interpreter/armdefs.h" 19#include "core/arm/skyeye_common/armemu.h"
20#include "core/arm/interpreter/armos.h" 20#include "core/arm/skyeye_common/vfp/vfp.h"
21#include "core/arm/interpreter/armemu.h"
22#include "core/arm/interpreter/vfp/vfp.h"
23 21
24//chy 2005-07-08 22//chy 2005-07-08
25//#include "ansidecl.h" 23//#include "ansidecl.h"
26//chy ------- 24//chy -------
27//#include "iwmmxt.h" 25//#include "iwmmxt.h"
28 26
29
30//chy 2005-09-19 add CP6 MRC support (for get irq number and base)
31extern unsigned xscale_cp6_mrc (ARMul_State * state, unsigned type,
32 ARMword instr, ARMword * data);
33//chy 2005-09-19---------------
34
35extern unsigned xscale_cp13_init (ARMul_State * state);
36extern unsigned xscale_cp13_exit (ARMul_State * state);
37extern unsigned xscale_cp13_ldc (ARMul_State * state, unsigned type,
38 ARMword instr, ARMword data);
39extern unsigned xscale_cp13_stc (ARMul_State * state, unsigned type,
40 ARMword instr, ARMword * data);
41extern unsigned xscale_cp13_mrc (ARMul_State * state, unsigned type,
42 ARMword instr, ARMword * data);
43extern unsigned xscale_cp13_mcr (ARMul_State * state, unsigned type,
44 ARMword instr, ARMword data);
45extern unsigned xscale_cp13_cdp (ARMul_State * state, unsigned type,
46 ARMword instr);
47extern unsigned xscale_cp13_read_reg (ARMul_State * state, unsigned reg,
48 ARMword * data);
49extern unsigned xscale_cp13_write_reg (ARMul_State * state, unsigned reg,
50 ARMword data);
51extern unsigned xscale_cp14_init (ARMul_State * state);
52extern unsigned xscale_cp14_exit (ARMul_State * state);
53extern unsigned xscale_cp14_ldc (ARMul_State * state, unsigned type,
54 ARMword instr, ARMword data);
55extern unsigned xscale_cp14_stc (ARMul_State * state, unsigned type,
56 ARMword instr, ARMword * data);
57extern unsigned xscale_cp14_mrc (ARMul_State * state, unsigned type,
58 ARMword instr, ARMword * data);
59extern unsigned xscale_cp14_mcr (ARMul_State * state, unsigned type,
60 ARMword instr, ARMword data);
61extern unsigned xscale_cp14_cdp (ARMul_State * state, unsigned type,
62 ARMword instr);
63extern unsigned xscale_cp14_read_reg (ARMul_State * state, unsigned reg,
64 ARMword * data);
65extern unsigned xscale_cp14_write_reg (ARMul_State * state, unsigned reg,
66 ARMword data);
67extern unsigned xscale_cp15_init (ARMul_State * state);
68extern unsigned xscale_cp15_exit (ARMul_State * state);
69extern unsigned xscale_cp15_ldc (ARMul_State * state, unsigned type,
70 ARMword instr, ARMword data);
71extern unsigned xscale_cp15_stc (ARMul_State * state, unsigned type,
72 ARMword instr, ARMword * data);
73extern unsigned xscale_cp15_mrc (ARMul_State * state, unsigned type,
74 ARMword instr, ARMword * data);
75extern unsigned xscale_cp15_mcr (ARMul_State * state, unsigned type,
76 ARMword instr, ARMword data);
77extern unsigned xscale_cp15_cdp (ARMul_State * state, unsigned type,
78 ARMword instr);
79extern unsigned xscale_cp15_read_reg (ARMul_State * state, unsigned reg,
80 ARMword * data);
81extern unsigned xscale_cp15_write_reg (ARMul_State * state, unsigned reg,
82 ARMword data);
83extern unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg,
84 unsigned cpnum);
85
86/* Dummy Co-processors. */ 27/* Dummy Co-processors. */
87 28
88static unsigned 29static unsigned
89NoCoPro3R (ARMul_State * state, 30NoCoPro3R(ARMul_State * state,
90 unsigned a, ARMword b) 31unsigned a, ARMword b)
91{ 32{
92 return ARMul_CANT; 33 return ARMul_CANT;
93} 34}
94 35
95static unsigned 36static unsigned
96NoCoPro4R (ARMul_State * state, 37NoCoPro4R(ARMul_State * state,
97 unsigned a, 38unsigned a,
98 ARMword b, ARMword c) 39ARMword b, ARMword c)
99{ 40{
100 return ARMul_CANT; 41 return ARMul_CANT;
101} 42}
102 43
103static unsigned 44static unsigned
104NoCoPro4W (ARMul_State * state, 45NoCoPro4W(ARMul_State * state,
105 unsigned a, 46unsigned a,
106 ARMword b, ARMword * c) 47ARMword b, ARMword * c)
107{ 48{
108 return ARMul_CANT; 49 return ARMul_CANT;
109} 50}
110 51
111static unsigned 52static unsigned
112NoCoPro5R (ARMul_State * state, 53NoCoPro5R(ARMul_State * state,
113 unsigned a, 54unsigned a,
114 ARMword b, 55ARMword b,
115 ARMword c, ARMword d) 56ARMword c, ARMword d)
116{ 57{
117 return ARMul_CANT; 58 return ARMul_CANT;
118} 59}
119 60
120static unsigned 61static unsigned
121NoCoPro5W (ARMul_State * state, 62NoCoPro5W(ARMul_State * state,
122 unsigned a, 63unsigned a,
123 ARMword b, 64ARMword b,
124 ARMword * c, ARMword * d ) 65ARMword * c, ARMword * d)
125{ 66{
126 return ARMul_CANT; 67 return ARMul_CANT;
127} 68}
128 69
129/* The XScale Co-processors. */ 70/* The XScale Co-processors. */
130 71
131/* Coprocessor 15: System Control. */ 72/* Coprocessor 15: System Control. */
132static void write_cp14_reg (unsigned, ARMword); 73static void write_cp14_reg(unsigned, ARMword);
133static ARMword read_cp14_reg (unsigned); 74static ARMword read_cp14_reg(unsigned);
134
135/* There are two sets of registers for copro 15.
136 One set is available when opcode_2 is 0 and
137 the other set when opcode_2 >= 1. */
138static ARMword XScale_cp15_opcode_2_is_0_Regs[16];
139static ARMword XScale_cp15_opcode_2_is_not_0_Regs[16];
140/* There are also a set of breakpoint registers
141 which are accessed via CRm instead of opcode_2. */
142static ARMword XScale_cp15_DBR1;
143static ARMword XScale_cp15_DBCON;
144static ARMword XScale_cp15_IBCR0;
145static ARMword XScale_cp15_IBCR1;
146
147static unsigned
148XScale_cp15_init (ARMul_State * state)
149{
150 int i;
151
152 for (i = 16; i--;) {
153 XScale_cp15_opcode_2_is_0_Regs[i] = 0;
154 XScale_cp15_opcode_2_is_not_0_Regs[i] = 0;
155 }
156
157 /* Initialise the processor ID. */
158 //chy 2003-03-24, is same as cpu id in skyeye_options.c
159 //XScale_cp15_opcode_2_is_0_Regs[0] = 0x69052000;
160 XScale_cp15_opcode_2_is_0_Regs[0] = 0x69050000;
161
162 /* Initialise the cache type. */
163 XScale_cp15_opcode_2_is_not_0_Regs[0] = 0x0B1AA1AA;
164
165 /* Initialise the ARM Control Register. */
166 XScale_cp15_opcode_2_is_0_Regs[1] = 0x00000078;
167
168 return No_exp;
169}
170
171/* Check an access to a register. */
172
173static unsigned
174check_cp15_access (ARMul_State * state,
175 unsigned reg,
176 unsigned CRm, unsigned opcode_1, unsigned opcode_2)
177{
178 /* Do not allow access to these register in USER mode. */
179 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
180 if (state->Mode == USER26MODE || state->Mode == USER32MODE )
181 return ARMul_CANT;
182
183 /* Opcode_1should be zero. */
184 if (opcode_1 != 0)
185 return ARMul_CANT;
186
187 /* Different register have different access requirements. */
188 switch (reg) {
189 case 0:
190 case 1:
191 /* CRm must be 0. Opcode_2 can be anything. */
192 if (CRm != 0)
193 return ARMul_CANT;
194 break;
195 case 2:
196 case 3:
197 /* CRm must be 0. Opcode_2 must be zero. */
198 if ((CRm != 0) || (opcode_2 != 0))
199 return ARMul_CANT;
200 break;
201 case 4:
202 /* Access not allowed. */
203 return ARMul_CANT;
204 case 5:
205 case 6:
206 /* Opcode_2 must be zero. CRm must be 0. */
207 if ((CRm != 0) || (opcode_2 != 0))
208 return ARMul_CANT;
209 break;
210 case 7:
211 /* Permissable combinations:
212 Opcode_2 CRm
213 0 5
214 0 6
215 0 7
216 1 5
217 1 6
218 1 10
219 4 10
220 5 2
221 6 5 */
222 switch (opcode_2) {
223 default:
224 return ARMul_CANT;
225 case 6:
226 if (CRm != 5)
227 return ARMul_CANT;
228 break;
229 case 5:
230 if (CRm != 2)
231 return ARMul_CANT;
232 break;
233 case 4:
234 if (CRm != 10)
235 return ARMul_CANT;
236 break;
237 case 1:
238 if ((CRm != 5) && (CRm != 6) && (CRm != 10))
239 return ARMul_CANT;
240 break;
241 case 0:
242 if ((CRm < 5) || (CRm > 7))
243 return ARMul_CANT;
244 break;
245 }
246 break;
247
248 case 8:
249 /* Permissable combinations:
250 Opcode_2 CRm
251 0 5
252 0 6
253 0 7
254 1 5
255 1 6 */
256 if (opcode_2 > 1)
257 return ARMul_CANT;
258 if ((CRm < 5) || (CRm > 7))
259 return ARMul_CANT;
260 if (opcode_2 == 1 && CRm == 7)
261 return ARMul_CANT;
262 break;
263 case 9:
264 /* Opcode_2 must be zero or one. CRm must be 1 or 2. */
265 if (((CRm != 0) && (CRm != 1))
266 || ((opcode_2 != 1) && (opcode_2 != 2)))
267 return ARMul_CANT;
268 break;
269 case 10:
270 /* Opcode_2 must be zero or one. CRm must be 4 or 8. */
271 if (((CRm != 0) && (CRm != 1))
272 || ((opcode_2 != 4) && (opcode_2 != 8)))
273 return ARMul_CANT;
274 break;
275 case 11:
276 /* Access not allowed. */
277 return ARMul_CANT;
278 case 12:
279 /* Access not allowed. */
280 return ARMul_CANT;
281 case 13:
282 /* Opcode_2 must be zero. CRm must be 0. */
283 if ((CRm != 0) || (opcode_2 != 0))
284 return ARMul_CANT;
285 break;
286 case 14:
287 /* Opcode_2 must be 0. CRm must be 0, 3, 4, 8 or 9. */
288 if (opcode_2 != 0)
289 return ARMul_CANT;
290
291 if ((CRm != 0) && (CRm != 3) && (CRm != 4) && (CRm != 8)
292 && (CRm != 9))
293 return ARMul_CANT;
294 break;
295 case 15:
296 /* Opcode_2 must be zero. CRm must be 1. */
297 if ((CRm != 1) || (opcode_2 != 0))
298 return ARMul_CANT;
299 break;
300 default:
301 /* Should never happen. */
302 return ARMul_CANT;
303 }
304
305 return ARMul_DONE;
306}
307
308/* Coprocessor 13: Interrupt Controller and Bus Controller. */
309
310/* There are two sets of registers for copro 13.
311 One set (of three registers) is available when CRm is 0
312 and the other set (of six registers) when CRm is 1. */
313
314static ARMword XScale_cp13_CR0_Regs[16];
315static ARMword XScale_cp13_CR1_Regs[16];
316
317static unsigned
318XScale_cp13_init (ARMul_State * state)
319{
320 int i;
321
322 for (i = 16; i--;) {
323 XScale_cp13_CR0_Regs[i] = 0;
324 XScale_cp13_CR1_Regs[i] = 0;
325 }
326
327 return No_exp;
328}
329
330/* Check an access to a register. */
331
332static unsigned
333check_cp13_access (ARMul_State * state,
334 unsigned reg,
335 unsigned CRm, unsigned opcode_1, unsigned opcode_2)
336{
337 /* Do not allow access to these registers in USER mode. */
338 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
339 if (state->Mode == USER26MODE || state->Mode == USER32MODE )
340 return ARMul_CANT;
341
342 /* The opcodes should be zero. */
343 if ((opcode_1 != 0) || (opcode_2 != 0))
344 return ARMul_CANT;
345
346 /* Do not allow access to these register if bit
347 13 of coprocessor 15's register 15 is zero. */
348 if (!CP_ACCESS_ALLOWED (state, 13))
349 return ARMul_CANT;
350
351 /* Registers 0, 4 and 8 are defined when CRm == 0.
352 Registers 0, 1, 4, 5, 6, 7, 8 are defined when CRm == 1.
353 For all other CRm values undefined behaviour results. */
354 if (CRm == 0) {
355 if (reg == 0 || reg == 4 || reg == 8)
356 return ARMul_DONE;
357 }
358 else if (CRm == 1) {
359 if (reg == 0 || reg == 1 || (reg >= 4 && reg <= 8))
360 return ARMul_DONE;
361 }
362
363 return ARMul_CANT;
364}
365
366/* Coprocessor 14: Performance Monitoring, Clock and Power management,
367 Software Debug. */
368
369static ARMword XScale_cp14_Regs[16];
370
371static unsigned
372XScale_cp14_init (ARMul_State * state)
373{
374 int i;
375
376 for (i = 16; i--;)
377 XScale_cp14_Regs[i] = 0;
378
379 return No_exp;
380}
381 75
382/* Check an access to a register. */ 76/* Check an access to a register. */
383 77
384static unsigned 78static unsigned
385check_cp14_access (ARMul_State * state, 79check_cp15_access(ARMul_State * state,
386 unsigned reg, 80unsigned reg,
387 unsigned CRm, unsigned opcode1, unsigned opcode2) 81unsigned CRm, unsigned opcode_1, unsigned opcode_2)
388{
389 /* Not allowed to access these register in USER mode. */
390 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
391 if (state->Mode == USER26MODE || state->Mode == USER32MODE )
392 return ARMul_CANT;
393
394 /* CRm should be zero. */
395 if (CRm != 0)
396 return ARMul_CANT;
397
398 /* OPcodes should be zero. */
399 if (opcode1 != 0 || opcode2 != 0)
400 return ARMul_CANT;
401
402 /* Accessing registers 4 or 5 has unpredicatable results. */
403 if (reg >= 4 && reg <= 5)
404 return ARMul_CANT;
405
406 return ARMul_DONE;
407}
408
409/* Here's ARMulator's MMU definition. A few things to note:
410 1) It has eight registers, but only two are defined.
411 2) You can only access its registers with MCR and MRC.
412 3) MMU Register 0 (ID) returns 0x41440110
413 4) Register 1 only has 4 bits defined. Bits 0 to 3 are unused, bit 4
414 controls 32/26 bit program space, bit 5 controls 32/26 bit data space,
415 bit 6 controls late abort timimg and bit 7 controls big/little endian. */
416
417static ARMword MMUReg[8];
418
419static unsigned
420MMUInit (ARMul_State * state)
421{
422/* 2004-05-09 chy
423-------------------------------------------------------------
424read ARM Architecture Reference Manual
4252.6.5 Data Abort
426There are three Abort Model in ARM arch.
427
428Early Abort Model: used in some ARMv3 and earlier implementations. In this
429model, base register wirteback occurred for LDC,LDM,STC,STM instructions, and
430the base register was unchanged for all other instructions. (oldest)
431
432Base Restored Abort Model: If a Data Abort occurs in an instruction which
433specifies base register writeback, the value in the base register is
434unchanged. (strongarm, xscale)
435
436Base Updated Abort Model: If a Data Abort occurs in an instruction which
437specifies base register writeback, the base register writeback still occurs.
438(arm720T)
439
440read PART B
441chap2 The System Control Coprocessor CP15
4422.4 Register1:control register
443L(bit 6): in some ARMv3 and earlier implementations, the abort model of the
444processor could be configured:
4450=early Abort Model Selected(now obsolete)
4461=Late Abort Model selceted(same as Base Updated Abort Model)
447
448on later processors, this bit reads as 1 and ignores writes.
449-------------------------------------------------------------
450So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model)
451 if lateabtSig=0, then it means Base Restored Abort Model
452because the ARMs which skyeye simulates are all belonged to ARMv4,
453so I think MMUReg[1]'s bit 6 should always be 1
454
455*/
456
457 MMUReg[1] = state->prog32Sig << 4 |
458 state->data32Sig << 5 | 1 << 6 | state->bigendSig << 7;
459 //state->data32Sig << 5 | state->lateabtSig << 6 | state->bigendSig << 7;
460
461
462 NOTICE_LOG(ARM11, "ARMul_ConsolePrint: MMU present");
463
464 return TRUE;
465}
466
467static unsigned
468MMUMRC (ARMul_State * state, unsigned type,
469 ARMword instr, ARMword * value)
470{
471 mmu_mrc (state, instr, value);
472 return (ARMul_DONE);
473}
474
475static unsigned
476MMUMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value)
477{
478 mmu_mcr (state, instr, value);
479 return (ARMul_DONE);
480}
481
482/* What follows is the Validation Suite Coprocessor. It uses two
483 co-processor numbers (4 and 5) and has the follwing functionality.
484 Sixteen registers. Both co-processor nuimbers can be used in an MCR
485 and MRC to access these registers. CP 4 can LDC and STC to and from
486 the registers. CP 4 and CP 5 CDP 0 will busy wait for the number of
487 cycles specified by a CP register. CP 5 CDP 1 issues a FIQ after a
488 number of cycles (specified in a CP register), CDP 2 issues an IRQW
489 in the same way, CDP 3 and 4 turn of the FIQ and IRQ source, and CDP 5
490 stores a 32 bit time value in a CP register (actually it's the total
491 number of N, S, I, C and F cyles). */
492
493static ARMword ValReg[16];
494
495static unsigned
496ValLDC (ARMul_State * state,
497 unsigned type, ARMword instr, ARMword data)
498{
499 static unsigned words;
500
501 if (type != ARMul_DATA)
502 words = 0;
503 else {
504 ValReg[BITS (12, 15)] = data;
505
506 if (BIT (22))
507 /* It's a long access, get two words. */
508 if (words++ != 4)
509 return ARMul_INC;
510 }
511
512 return ARMul_DONE;
513}
514
515static unsigned
516ValSTC (ARMul_State * state,
517 unsigned type, ARMword instr, ARMword * data)
518{
519 static unsigned words;
520
521 if (type != ARMul_DATA)
522 words = 0;
523 else {
524 *data = ValReg[BITS (12, 15)];
525
526 if (BIT (22))
527 /* It's a long access, get two words. */
528 if (words++ != 4)
529 return ARMul_INC;
530 }
531
532 return ARMul_DONE;
533}
534
535static unsigned
536ValMRC (ARMul_State * state,
537 unsigned type, ARMword instr, ARMword * value)
538{
539 *value = ValReg[BITS (16, 19)];
540
541 return ARMul_DONE;
542}
543
544static unsigned
545ValMCR (ARMul_State * state,
546 unsigned type, ARMword instr, ARMword value)
547{
548 ValReg[BITS (16, 19)] = value;
549
550 return ARMul_DONE;
551}
552
553static unsigned
554ValCDP (ARMul_State * state, unsigned type, ARMword instr)
555{
556 static unsigned int finish = 0;
557
558 if (BITS (20, 23) != 0)
559 return ARMul_CANT;
560
561 if (type == ARMul_FIRST) {
562 ARMword howlong;
563
564 howlong = ValReg[BITS (0, 3)];
565
566 /* First cycle of a busy wait. */
567 finish = ARMul_Time (state) + howlong;
568
569 return howlong == 0 ? ARMul_DONE : ARMul_BUSY;
570 }
571 else if (type == ARMul_BUSY) {
572 if (ARMul_Time (state) >= finish)
573 return ARMul_DONE;
574 else
575 return ARMul_BUSY;
576 }
577
578 return ARMul_CANT;
579}
580
581static unsigned
582DoAFIQ (ARMul_State * state)
583{
584 state->NfiqSig = LOW;
585 return 0;
586}
587
588static unsigned
589DoAIRQ (ARMul_State * state)
590{
591 state->NirqSig = LOW;
592 return 0;
593}
594
595static unsigned
596IntCDP (ARMul_State * state, unsigned type, ARMword instr)
597{ 82{
598 static unsigned int finish; 83 /* Do not allow access to these register in USER mode. */
599 ARMword howlong; 84 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
600 85 if (state->Mode == USER26MODE || state->Mode == USER32MODE)
601 howlong = ValReg[BITS (0, 3)]; 86 return ARMul_CANT;
602 87
603 switch ((int) BITS (20, 23)) { 88 /* Opcode_1should be zero. */
604 case 0: 89 if (opcode_1 != 0)
605 if (type == ARMul_FIRST) { 90 return ARMul_CANT;
606 /* First cycle of a busy wait. */ 91
607 finish = ARMul_Time (state) + howlong; 92 /* Different register have different access requirements. */
608 93 switch (reg) {
609 return howlong == 0 ? ARMul_DONE : ARMul_BUSY; 94 case 0:
610 } 95 case 1:
611 else if (type == ARMul_BUSY) { 96 /* CRm must be 0. Opcode_2 can be anything. */
612 if (ARMul_Time (state) >= finish) 97 if (CRm != 0)
613 return ARMul_DONE; 98 return ARMul_CANT;
614 else 99 break;
615 return ARMul_BUSY; 100 case 2:
616 } 101 case 3:
617 return ARMul_DONE; 102 /* CRm must be 0. Opcode_2 must be zero. */
618 103 if ((CRm != 0) || (opcode_2 != 0))
619 case 1: 104 return ARMul_CANT;
620 if (howlong == 0) 105 break;
621 ARMul_Abort (state, ARMul_FIQV); 106 case 4:
622 else 107 /* Access not allowed. */
623 ARMul_ScheduleEvent (state, howlong, DoAFIQ); 108 return ARMul_CANT;
624 return ARMul_DONE; 109 case 5:
625 110 case 6:
626 case 2: 111 /* Opcode_2 must be zero. CRm must be 0. */
627 if (howlong == 0) 112 if ((CRm != 0) || (opcode_2 != 0))
628 ARMul_Abort (state, ARMul_IRQV); 113 return ARMul_CANT;
629 else 114 break;
630 ARMul_ScheduleEvent (state, howlong, DoAIRQ); 115 case 7:
631 return ARMul_DONE; 116 /* Permissable combinations:
632 117 Opcode_2 CRm
633 case 3: 118 0 5
634 state->NfiqSig = HIGH; 119 0 6
635 return ARMul_DONE; 120 0 7
636 121 1 5
637 case 4: 122 1 6
638 state->NirqSig = HIGH; 123 1 10
639 return ARMul_DONE; 124 4 10
640 125 5 2
641 case 5: 126 6 5 */
642 ValReg[BITS (0, 3)] = ARMul_Time (state); 127 switch (opcode_2) {
643 return ARMul_DONE; 128 default:
644 } 129 return ARMul_CANT;
645 130 case 6:
646 return ARMul_CANT; 131 if (CRm != 5)
132 return ARMul_CANT;
133 break;
134 case 5:
135 if (CRm != 2)
136 return ARMul_CANT;
137 break;
138 case 4:
139 if (CRm != 10)
140 return ARMul_CANT;
141 break;
142 case 1:
143 if ((CRm != 5) && (CRm != 6) && (CRm != 10))
144 return ARMul_CANT;
145 break;
146 case 0:
147 if ((CRm < 5) || (CRm > 7))
148 return ARMul_CANT;
149 break;
150 }
151 break;
152
153 case 8:
154 /* Permissable combinations:
155 Opcode_2 CRm
156 0 5
157 0 6
158 0 7
159 1 5
160 1 6 */
161 if (opcode_2 > 1)
162 return ARMul_CANT;
163 if ((CRm < 5) || (CRm > 7))
164 return ARMul_CANT;
165 if (opcode_2 == 1 && CRm == 7)
166 return ARMul_CANT;
167 break;
168 case 9:
169 /* Opcode_2 must be zero or one. CRm must be 1 or 2. */
170 if (((CRm != 0) && (CRm != 1))
171 || ((opcode_2 != 1) && (opcode_2 != 2)))
172 return ARMul_CANT;
173 break;
174 case 10:
175 /* Opcode_2 must be zero or one. CRm must be 4 or 8. */
176 if (((CRm != 0) && (CRm != 1))
177 || ((opcode_2 != 4) && (opcode_2 != 8)))
178 return ARMul_CANT;
179 break;
180 case 11:
181 /* Access not allowed. */
182 return ARMul_CANT;
183 case 12:
184 /* Access not allowed. */
185 return ARMul_CANT;
186 case 13:
187 /* Opcode_2 must be zero. CRm must be 0. */
188 if ((CRm != 0) || (opcode_2 != 0))
189 return ARMul_CANT;
190 break;
191 case 14:
192 /* Opcode_2 must be 0. CRm must be 0, 3, 4, 8 or 9. */
193 if (opcode_2 != 0)
194 return ARMul_CANT;
195
196 if ((CRm != 0) && (CRm != 3) && (CRm != 4) && (CRm != 8)
197 && (CRm != 9))
198 return ARMul_CANT;
199 break;
200 case 15:
201 /* Opcode_2 must be zero. CRm must be 1. */
202 if ((CRm != 1) || (opcode_2 != 0))
203 return ARMul_CANT;
204 break;
205 default:
206 /* Should never happen. */
207 return ARMul_CANT;
208 }
209
210 return ARMul_DONE;
647} 211}
648 212
649/* Install co-processor instruction handlers in this routine. */ 213/* Install co-processor instruction handlers in this routine. */
650 214
651unsigned 215unsigned
652ARMul_CoProInit (ARMul_State * state) 216ARMul_CoProInit(ARMul_State * state)
653{ 217{
654 unsigned int i; 218 unsigned int i;
655 219
656 /* Initialise tham all first. */ 220 /* Initialise tham all first. */
657 for (i = 0; i < 16; i++) 221 for (i = 0; i < 16; i++)
658 ARMul_CoProDetach (state, i); 222 ARMul_CoProDetach(state, i);
659 223
660 /* Install CoPro Instruction handlers here. 224 /* Install CoPro Instruction handlers here.
661 The format is: 225 The format is:
662 ARMul_CoProAttach (state, CP Number, Init routine, Exit routine 226 ARMul_CoProAttach (state, CP Number, Init routine, Exit routine
663 LDC routine, STC routine, MRC routine, MCR routine, 227 LDC routine, STC routine, MRC routine, MCR routine,
664 CDP routine, Read Reg routine, Write Reg routine). */ 228 CDP routine, Read Reg routine, Write Reg routine). */
665 if (state->is_ep9312) { 229 if (state->is_v6) {
666 ARMul_CoProAttach (state, 4, NULL, NULL, DSPLDC4, DSPSTC4, 230 ARMul_CoProAttach(state, 10, VFPInit, NULL, VFPLDC, VFPSTC,
667 DSPMRC4, DSPMCR4, NULL, NULL, DSPCDP4, NULL, NULL); 231 VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL);
668 ARMul_CoProAttach (state, 5, NULL, NULL, DSPLDC5, DSPSTC5, 232 ARMul_CoProAttach(state, 11, VFPInit, NULL, VFPLDC, VFPSTC,
669 DSPMRC5, DSPMCR5, NULL, NULL, DSPCDP5, NULL, NULL); 233 VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL);
670 ARMul_CoProAttach (state, 6, NULL, NULL, NULL, NULL, 234
671 DSPMRC6, DSPMCR6, NULL, NULL, DSPCDP6, NULL, NULL); 235 /*ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL,
672 } 236 MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL);*/
673 else { 237 }
674 ARMul_CoProAttach (state, 4, NULL, NULL, ValLDC, ValSTC, 238 //chy 2003-09-03 do it in future!!!!????
675 ValMRC, ValMCR, NULL, NULL, ValCDP, NULL, NULL);
676
677 ARMul_CoProAttach (state, 5, NULL, NULL, NULL, NULL,
678 ValMRC, ValMCR, NULL, NULL, IntCDP, NULL, NULL);
679 }
680
681 if (state->is_XScale) {
682 //chy 2005-09-19, for PXA27x's CP6
683 if (state->is_pxa27x) {
684 ARMul_CoProAttach (state, 6, NULL, NULL,
685 NULL, NULL, xscale_cp6_mrc,
686 NULL, NULL, NULL, NULL, NULL, NULL);
687 }
688 //chy 2005-09-19 end-------------
689 ARMul_CoProAttach (state, 13, xscale_cp13_init,
690 xscale_cp13_exit, xscale_cp13_ldc,
691 xscale_cp13_stc, xscale_cp13_mrc,
692 xscale_cp13_mcr, NULL, NULL, xscale_cp13_cdp,
693 xscale_cp13_read_reg,
694 xscale_cp13_write_reg);
695
696 ARMul_CoProAttach (state, 14, xscale_cp14_init,
697 xscale_cp14_exit, xscale_cp14_ldc,
698 xscale_cp14_stc, xscale_cp14_mrc,
699 xscale_cp14_mcr, NULL, NULL, xscale_cp14_cdp,
700 xscale_cp14_read_reg,
701 xscale_cp14_write_reg);
702 //chy: 2003-08-24.
703 ARMul_CoProAttach (state, 15, xscale_cp15_init,
704 xscale_cp15_exit, xscale_cp15_ldc,
705 xscale_cp15_stc, xscale_cp15_mrc,
706 xscale_cp15_mcr, NULL, NULL, xscale_cp15_cdp,
707 xscale_cp15_read_reg,
708 xscale_cp15_write_reg);
709 }
710 else if (state->is_v6) {
711 ARMul_CoProAttach (state, 10, VFPInit, NULL, VFPLDC, VFPSTC,
712 VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL);
713 ARMul_CoProAttach (state, 11, VFPInit, NULL, VFPLDC, VFPSTC,
714 VFPMRC, VFPMCR, VFPMRRC, VFPMCRR, VFPCDP, NULL, NULL);
715
716 ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL,
717 MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL);
718 }
719 else { //all except xscale
720 ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL,
721 // MMUMRC, MMUMCR, NULL, MMURead, MMUWrite);
722 MMUMRC, MMUMCR, NULL, NULL, NULL, NULL, NULL);
723 }
724//chy 2003-09-03 do it in future!!!!????
725#if 0 239#if 0
726 if (state->is_iWMMXt) { 240 if (state->is_iWMMXt) {
727 ARMul_CoProAttach (state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC, 241 ARMul_CoProAttach(state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC,
728 NULL, NULL, IwmmxtCDP, NULL, NULL); 242 NULL, NULL, IwmmxtCDP, NULL, NULL);
729 243
730 ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL, 244 ARMul_CoProAttach(state, 1, NULL, NULL, NULL, NULL,
731 IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL, 245 IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL,
732 NULL); 246 NULL);
733 } 247 }
734#endif 248#endif
735 //----------------------------------------------------------------------------- 249 /* No handlers below here. */
736 //chy 2004-05-25, found the user/system code visit CP 1,2, so I add below code. 250
737 ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL, 251 /* Call all the initialisation routines. */
738 ValMRC, ValMCR, NULL, NULL, NULL, NULL, NULL); 252 for (i = 0; i < 16; i++)
739 ARMul_CoProAttach (state, 2, NULL, NULL, ValLDC, ValSTC, 253 if (state->CPInit[i])
740 NULL, NULL, NULL, NULL, NULL, NULL, NULL); 254 (state->CPInit[i]) (state);
741 //------------------------------------------------------------------------------ 255
742 /* No handlers below here. */ 256 return TRUE;
743
744 /* Call all the initialisation routines. */
745 for (i = 0; i < 16; i++)
746 if (state->CPInit[i])
747 (state->CPInit[i]) (state);
748
749 return TRUE;
750} 257}
751 258
752/* Install co-processor finalisation routines in this routine. */ 259/* Install co-processor finalisation routines in this routine. */
753 260
754void 261void
755ARMul_CoProExit (ARMul_State * state) 262ARMul_CoProExit(ARMul_State * state)
756{ 263{
757 register unsigned i; 264 register unsigned i;
758 265
759 for (i = 0; i < 16; i++) 266 for (i = 0; i < 16; i++)
760 if (state->CPExit[i]) 267 if (state->CPExit[i])
761 (state->CPExit[i]) (state); 268 (state->CPExit[i]) (state);
762 269
763 for (i = 0; i < 16; i++) /* Detach all handlers. */ 270 for (i = 0; i < 16; i++) /* Detach all handlers. */
764 ARMul_CoProDetach (state, i); 271 ARMul_CoProDetach(state, i);
765} 272}
766 273
767/* Routines to hook Co-processors into ARMulator. */ 274/* Routines to hook Co-processors into ARMulator. */
768 275
769void 276void
770ARMul_CoProAttach (ARMul_State * state, 277ARMul_CoProAttach(ARMul_State * state,
771 unsigned number, 278unsigned number,
772 ARMul_CPInits * init, 279ARMul_CPInits * init,
773 ARMul_CPExits * exit, 280ARMul_CPExits * exit,
774 ARMul_LDCs * ldc, 281ARMul_LDCs * ldc,
775 ARMul_STCs * stc, 282ARMul_STCs * stc,
776 ARMul_MRCs * mrc, 283ARMul_MRCs * mrc,
777 ARMul_MCRs * mcr, 284ARMul_MCRs * mcr,
778 ARMul_MRRCs * mrrc, 285ARMul_MRRCs * mrrc,
779 ARMul_MCRRs * mcrr, 286ARMul_MCRRs * mcrr,
780 ARMul_CDPs * cdp, 287ARMul_CDPs * cdp,
781 ARMul_CPReads * read, ARMul_CPWrites * write) 288ARMul_CPReads * read, ARMul_CPWrites * write)
782{
783 if (init != NULL)
784 state->CPInit[number] = init;
785 if (exit != NULL)
786 state->CPExit[number] = exit;
787 if (ldc != NULL)
788 state->LDC[number] = ldc;
789 if (stc != NULL)
790 state->STC[number] = stc;
791 if (mrc != NULL)
792 state->MRC[number] = mrc;
793 if (mcr != NULL)
794 state->MCR[number] = mcr;
795 if (mrrc != NULL)
796 state->MRRC[number] = mrrc;
797 if (mcrr != NULL)
798 state->MCRR[number] = mcrr;
799 if (cdp != NULL)
800 state->CDP[number] = cdp;
801 if (read != NULL)
802 state->CPRead[number] = read;
803 if (write != NULL)
804 state->CPWrite[number] = write;
805}
806
807void
808ARMul_CoProDetach (ARMul_State * state, unsigned number)
809{ 289{
810 ARMul_CoProAttach (state, number, NULL, NULL, 290 if (init != NULL)
811 NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R, 291 state->CPInit[number] = init;
812 NoCoPro5W, NoCoPro5R, NoCoPro3R, NULL, NULL); 292 if (exit != NULL)
813 293 state->CPExit[number] = exit;
814 state->CPInit[number] = NULL; 294 if (ldc != NULL)
815 state->CPExit[number] = NULL; 295 state->LDC[number] = ldc;
816 state->CPRead[number] = NULL; 296 if (stc != NULL)
817 state->CPWrite[number] = NULL; 297 state->STC[number] = stc;
298 if (mrc != NULL)
299 state->MRC[number] = mrc;
300 if (mcr != NULL)
301 state->MCR[number] = mcr;
302 if (mrrc != NULL)
303 state->MRRC[number] = mrrc;
304 if (mcrr != NULL)
305 state->MCRR[number] = mcrr;
306 if (cdp != NULL)
307 state->CDP[number] = cdp;
308 if (read != NULL)
309 state->CPRead[number] = read;
310 if (write != NULL)
311 state->CPWrite[number] = write;
818} 312}
819 313
820//chy 2003-09-03:below funs just replace the old ones
821
822/* Set the XScale FSR and FAR registers. */
823
824void 314void
825XScale_set_fsr_far (ARMul_State * state, ARMword fsr, ARMword _far) 315ARMul_CoProDetach(ARMul_State * state, unsigned number)
826{
827 //if (!state->is_XScale || (read_cp14_reg (10) & (1UL << 31)) == 0)
828 if (!state->is_XScale)
829 return;
830 //assume opcode2=0 crm =0
831 xscale_cp15_write_reg (state, 5, fsr);
832 xscale_cp15_write_reg (state, 6, _far);
833}
834
835//chy 2003-09-03 seems 0 is CANT, 1 is DONE ????
836int
837XScale_debug_moe (ARMul_State * state, int moe)
838{ 316{
839 //chy 2003-09-03 , W/R CP14 reg, now it's no use ???? 317 ARMul_CoProAttach(state, number, NULL, NULL,
840 printf ("SKYEYE: XScale_debug_moe called !!!!\n"); 318 NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R,
841 return 1; 319 NoCoPro5W, NoCoPro5R, NoCoPro3R, NULL, NULL);
320
321 state->CPInit[number] = NULL;
322 state->CPExit[number] = NULL;
323 state->CPRead[number] = NULL;
324 state->CPWrite[number] = NULL;
842} 325}
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index f9130ef88..cdcf47ee1 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -18,9 +18,9 @@
18 18
19//#include <util.h> // DEBUG() 19//#include <util.h> // DEBUG()
20 20
21#include "arm_regformat.h" 21#include "core/arm/skyeye_common/arm_regformat.h"
22#include "armdefs.h" 22#include "core/arm/skyeye_common/armdefs.h"
23#include "armemu.h" 23#include "core/arm/skyeye_common/armemu.h"
24#include "core/hle/hle.h" 24#include "core/hle/hle.h"
25 25
26//#include "svc.h" 26//#include "svc.h"
@@ -28,9 +28,6 @@
28//ichfly 28//ichfly
29//#define callstacker 1 29//#define callstacker 1
30 30
31
32//#include "armos.h"
33
34//#include "skyeye_callback.h" 31//#include "skyeye_callback.h"
35//#include "skyeye_bus.h" 32//#include "skyeye_bus.h"
36//#include "sim_control.h" 33//#include "sim_control.h"
diff --git a/src/core/arm/interpreter/arminit.cpp b/src/core/arm/interpreter/arminit.cpp
index 6fbab3bfb..03bca2870 100644
--- a/src/core/arm/interpreter/arminit.cpp
+++ b/src/core/arm/interpreter/arminit.cpp
@@ -17,8 +17,8 @@
17 17
18//#include <unistd.h> 18//#include <unistd.h>
19 19
20#include "core/arm/interpreter/armdefs.h" 20#include "core/arm/skyeye_common/armdefs.h"
21#include "core/arm/interpreter/armemu.h" 21#include "core/arm/skyeye_common/armemu.h"
22 22
23/***************************************************************************\ 23/***************************************************************************\
24* Definitions for the emulator architecture * 24* Definitions for the emulator architecture *
diff --git a/src/core/arm/interpreter/armmmu.cpp b/src/core/arm/interpreter/armmmu.cpp
deleted file mode 100644
index 242e6a83c..000000000
--- a/src/core/arm/interpreter/armmmu.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
1/*
2 armmmu.c - Memory Management Unit emulation.
3 ARMulator extensions for the ARM7100 family.
4 Copyright (C) 1999 Ben Williamson
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19*/
20
21#include <assert.h>
22#include <string.h>
23#include "armdefs.h"
24/* two header for arm disassemble */
25//#include "skyeye_arch.h"
26#include "armcpu.h"
27
28
29extern mmu_ops_t xscale_mmu_ops;
30exception_t arm_mmu_write(short size, u32 addr, uint32_t *value);
31exception_t arm_mmu_read(short size, u32 addr, uint32_t *value);
32#define MMU_OPS (state->mmu.ops)
33ARMword skyeye_cachetype = -1;
34
35int
36mmu_init (ARMul_State * state)
37{
38 int ret;
39
40 state->mmu.control = 0x70;
41 state->mmu.translation_table_base = 0xDEADC0DE;
42 state->mmu.domain_access_control = 0xDEADC0DE;
43 state->mmu.fault_status = 0;
44 state->mmu.fault_address = 0;
45 state->mmu.process_id = 0;
46
47 switch (state->cpu->cpu_val & state->cpu->cpu_mask) {
48 //case SA1100:
49 //case SA1110:
50 // NOTICE_LOG(ARM11, "SKYEYE: use sa11xx mmu ops\n");
51 // state->mmu.ops = sa_mmu_ops;
52 // break;
53 //case PXA250:
54 //case PXA270: //xscale
55 // NOTICE_LOG(ARM11, "SKYEYE: use xscale mmu ops\n");
56 // state->mmu.ops = xscale_mmu_ops;
57 // break;
58 //case 0x41807200: //arm720t
59 //case 0x41007700: //arm7tdmi
60 //case 0x41007100: //arm7100
61 // NOTICE_LOG(ARM11, "SKYEYE: use arm7100 mmu ops\n");
62 // state->mmu.ops = arm7100_mmu_ops;
63 // break;
64 //case 0x41009200:
65 // NOTICE_LOG(ARM11, "SKYEYE: use arm920t mmu ops\n");
66 // state->mmu.ops = arm920t_mmu_ops;
67 // break;
68 //case 0x41069260:
69 // NOTICE_LOG(ARM11, "SKYEYE: use arm926ejs mmu ops\n");
70 // state->mmu.ops = arm926ejs_mmu_ops;
71 // break;
72 /* case 0x560f5810: */
73 case 0x0007b000:
74 NOTICE_LOG(ARM11, "SKYEYE: use arm11jzf-s mmu ops\n");
75 state->mmu.ops = arm1176jzf_s_mmu_ops;
76 break;
77
78 default:
79 ERROR_LOG (ARM11,
80 "SKYEYE: armmmu.c : mmu_init: unknown cpu_val&cpu_mask 0x%x\n",
81 state->cpu->cpu_val & state->cpu->cpu_mask);
82 break;
83
84 };
85 ret = state->mmu.ops.init (state);
86 state->mmu_inited = (ret == 0);
87 /* initialize mmu_read and mmu_write for disassemble */
88 //skyeye_config_t *config = get_current_config();
89 //generic_arch_t *arch_instance = get_arch_instance(config->arch->arch_name);
90 //arch_instance->mmu_read = arm_mmu_read;
91 //arch_instance->mmu_write = arm_mmu_write;
92
93 return ret;
94}
95
96int
97mmu_reset (ARMul_State * state)
98{
99 if (state->mmu_inited)
100 mmu_exit (state);
101 return mmu_init (state);
102}
103
104void
105mmu_exit (ARMul_State * state)
106{
107 MMU_OPS.exit (state);
108 state->mmu_inited = 0;
109}
110
111fault_t
112mmu_read_byte (ARMul_State * state, ARMword virt_addr, ARMword * data)
113{
114 return MMU_OPS.read_byte (state, virt_addr, data);
115};
116
117fault_t
118mmu_read_halfword (ARMul_State * state, ARMword virt_addr, ARMword * data)
119{
120 return MMU_OPS.read_halfword (state, virt_addr, data);
121};
122
123fault_t
124mmu_read_word (ARMul_State * state, ARMword virt_addr, ARMword * data)
125{
126 return MMU_OPS.read_word (state, virt_addr, data);
127};
128
129fault_t
130mmu_write_byte (ARMul_State * state, ARMword virt_addr, ARMword data)
131{
132 fault_t fault;
133 //static int count = 0;
134 //count ++;
135 fault = MMU_OPS.write_byte (state, virt_addr, data);
136 return fault;
137}
138
139fault_t
140mmu_write_halfword (ARMul_State * state, ARMword virt_addr, ARMword data)
141{
142 fault_t fault;
143 //static int count = 0;
144 //count ++;
145 fault = MMU_OPS.write_halfword (state, virt_addr, data);
146 return fault;
147}
148
149fault_t
150mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data)
151{
152 fault_t fault;
153 fault = MMU_OPS.write_word (state, virt_addr, data);
154
155 /*used for debug for MMU*
156
157 if (!fault){
158 ARMword tmp;
159
160 if (mmu_read_word(state, virt_addr, &tmp)){
161 err_msg("load back\n");
162 exit(-1);
163 }else{
164 if (tmp != data){
165 err_msg("load back not equal %d %x\n", count, virt_addr);
166 }
167 }
168 }
169 */
170
171 return fault;
172};
173
174fault_t
175mmu_load_instr (ARMul_State * state, ARMword virt_addr, ARMword * instr)
176{
177 return MMU_OPS.load_instr (state, virt_addr, instr);
178}
179
180ARMword
181mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value)
182{
183 return MMU_OPS.mrc (state, instr, value);
184}
185
186void
187mmu_mcr (ARMul_State * state, ARMword instr, ARMword value)
188{
189 MMU_OPS.mcr (state, instr, value);
190}
191
192/*ywc 20050416*/
193int
194mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr, ARMword * phys_addr)
195{
196 return (MMU_OPS.v2p_dbct (state, virt_addr, phys_addr));
197}
198
199//
200//
201///* dis_mmu_read for disassemble */
202//exception_t arm_mmu_read(short size, uint32_t addr, uint32_t * value)
203//{
204// ARMul_State *state;
205// ARM_CPU_State *cpu = get_current_cpu();
206// state = &cpu->core[0];
207// switch(size){
208// case 8:
209// MMU_OPS.read_byte (state, addr, value);
210// break;
211// case 16:
212// case 32:
213// break;
214// default:
215// ERROR_LOG(ARM11, "Error size %d", size);
216// break;
217// }
218// return No_exp;
219//}
220///* dis_mmu_write for disassemble */
221//exception_t arm_mmu_write(short size, uint32_t addr, uint32_t *value)
222//{
223// ARMul_State *state;
224// ARM_CPU_State *cpu = get_current_cpu();
225// state = &cpu->core[0];
226// switch(size){
227// case 8:
228// MMU_OPS.write_byte (state, addr, value);
229// break;
230// case 16:
231// case 32:
232// break;
233// default:
234// printf("In %s error size %d Line %d\n", __func__, size, __LINE__);
235// break;
236// }
237// return No_exp;
238//}
diff --git a/src/core/arm/interpreter/armos.cpp b/src/core/arm/interpreter/armos.cpp
deleted file mode 100644
index 43484ee5f..000000000
--- a/src/core/arm/interpreter/armos.cpp
+++ /dev/null
@@ -1,742 +0,0 @@
1/* armos.c -- ARMulator OS interface: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18/* This file contains a model of Demon, ARM Ltd's Debug Monitor,
19including all the SWI's required to support the C library. The code in
20it is not really for the faint-hearted (especially the abort handling
21code), but it is a complete example. Defining NOOS will disable all the
22fun, and definign VAILDATE will define SWI 1 to enter SVC mode, and SWI
230x11 to halt the emulator. */
24
25//chy 2005-09-12 disable below line
26//#include "config.h"
27
28#include <time.h>
29#include <errno.h>
30#include <string.h>
31#include "skyeye_defs.h"
32#ifndef __USE_LARGEFILE64
33#define __USE_LARGEFILE64 /* When use 64 bit large file need define it! for stat64*/
34#endif
35#include <fcntl.h>
36#include <sys/stat.h>
37
38
39#ifndef O_RDONLY
40#define O_RDONLY 0
41#endif
42#ifndef O_WRONLY
43#define O_WRONLY 1
44#endif
45#ifndef O_RDWR
46#define O_RDWR 2
47#endif
48#ifndef O_BINARY
49#define O_BINARY 0
50#endif
51
52#ifdef __STDC__
53#define unlink(s) remove(s)
54#endif
55
56#ifdef HAVE_UNISTD_H
57#include <unistd.h> /* For SEEK_SET etc */
58#endif
59
60#ifdef __riscos
61extern int _fisatty (FILE *);
62#define isatty_(f) _fisatty(f)
63#else
64#ifdef __ZTC__
65#include <io.h>
66#define isatty_(f) isatty((f)->_file)
67#else
68#ifdef macintosh
69#include <ioctl.h>
70#define isatty_(f) (~ioctl ((f)->_file, FIOINTERACTIVE, NULL))
71#else
72#define isatty_(f) isatty (fileno (f))
73#endif
74#endif
75#endif
76
77#include "armdefs.h"
78#include "armos.h"
79#include "armemu.h"
80
81#ifndef NOOS
82#ifndef VALIDATE
83/* #ifndef ASIM */
84//chy 2005-09-12 disable below line
85//#include "armfpe.h"
86/* #endif */
87#endif
88#endif
89
90#define DUMP_SYSCALL 0
91#define dump(...) do { if (DUMP_SYSCALL) printf(__VA_ARGS__); } while(0)
92//#define debug(...) printf(__VA_ARGS__);
93#define debug(...) ;
94
95extern unsigned ARMul_OSHandleSWI (ARMul_State * state, ARMword number);
96
97#ifndef FOPEN_MAX
98#define FOPEN_MAX 64
99#endif
100
101/***************************************************************************\
102* OS private Information *
103\***************************************************************************/
104
105unsigned arm_dyncom_SWI(ARMul_State * state, ARMword number)
106{
107 return ARMul_OSHandleSWI(state, number);
108}
109
110//mmap_area_t *mmap_global = NULL;
111
112static int translate_open_mode[] = {
113 O_RDONLY, /* "r" */
114 O_RDONLY + O_BINARY, /* "rb" */
115 O_RDWR, /* "r+" */
116 O_RDWR + O_BINARY, /* "r+b" */
117 O_WRONLY + O_CREAT + O_TRUNC, /* "w" */
118 O_WRONLY + O_BINARY + O_CREAT + O_TRUNC, /* "wb" */
119 O_RDWR + O_CREAT + O_TRUNC, /* "w+" */
120 O_RDWR + O_BINARY + O_CREAT + O_TRUNC, /* "w+b" */
121 O_WRONLY + O_APPEND + O_CREAT, /* "a" */
122 O_WRONLY + O_BINARY + O_APPEND + O_CREAT, /* "ab" */
123 O_RDWR + O_APPEND + O_CREAT, /* "a+" */
124 O_RDWR + O_BINARY + O_APPEND + O_CREAT /* "a+b" */
125};
126//
127//static void
128//SWIWrite0 (ARMul_State * state, ARMword addr)
129//{
130// ARMword temp;
131//
132// //while ((temp = ARMul_ReadByte (state, addr++)) != 0)
133// while(1){
134// mem_read(8, addr++, &temp);
135// if(temp != 0)
136// (void) fputc ((char) temp, stdout);
137// else
138// break;
139// }
140//}
141//
142//static void
143//WriteCommandLineTo (ARMul_State * state, ARMword addr)
144//{
145// ARMword temp;
146// char *cptr = state->CommandLine;
147// if (cptr == NULL)
148// cptr = "\0";
149// do {
150// temp = (ARMword) * cptr++;
151// //ARMul_WriteByte (state, addr++, temp);
152// mem_write(8, addr++, temp);
153// }
154// while (temp != 0);
155//}
156//
157//static void
158//SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
159//{
160// char dummy[2000];
161// int flags;
162// int i;
163//
164// for (i = 0; (dummy[i] = ARMul_ReadByte (state, name + i)); i++);
165// assert(SWIflags< (sizeof(translate_open_mode)/ sizeof(translate_open_mode[0])));
166// /* Now we need to decode the Demon open mode */
167// flags = translate_open_mode[SWIflags];
168// flags = SWIflags;
169//
170// /* Filename ":tt" is special: it denotes stdin/out */
171// if (strcmp (dummy, ":tt") == 0) {
172// if (flags == O_RDONLY) /* opening tty "r" */
173// state->Reg[0] = 0; /* stdin */
174// else
175// state->Reg[0] = 1; /* stdout */
176// }
177// else {
178// state->Reg[0] = (int) open (dummy, flags, 0666);
179// }
180//}
181//
182//static void
183//SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
184//{
185// int res;
186// int i;
187// char *local = (char*) malloc (len);
188//
189// if (local == NULL) {
190// fprintf (stderr,
191// "sim: Unable to read 0x%ulx bytes - out of memory\n",
192// len);
193// return;
194// }
195//
196// res = read (f, local, len);
197// if (res > 0)
198// for (i = 0; i < res; i++)
199// //ARMul_WriteByte (state, ptr + i, local[i]);
200// mem_write(8, ptr + i, local[i]);
201// free (local);
202// //state->Reg[0] = res == -1 ? -1 : len - res;
203// state->Reg[0] = res;
204//}
205//
206//static void
207//SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
208//{
209// int res;
210// ARMword i;
211// char *local = malloc (len);
212//
213// if (local == NULL) {
214// fprintf (stderr,
215// "sim: Unable to write 0x%lx bytes - out of memory\n",
216// (long unsigned int) len);
217// return;
218// }
219//
220// for (i = 0; i < len; i++){
221// //local[i] = ARMul_ReadByte (state, ptr + i);
222// ARMword data;
223// mem_read(8, ptr + i, &data);
224// local[i] = data & 0xFF;
225// }
226//
227// res = write (f, local, len);
228// //state->Reg[0] = res == -1 ? -1 : len - res;
229// state->Reg[0] = res;
230// free (local);
231//}
232
233//static void
234//SWIflen (ARMul_State * state, ARMword fh)
235//{
236// ARMword addr;
237//
238// if (fh == 0 || fh > FOPEN_MAX) {
239// state->Reg[0] = -1L;
240// return;
241// }
242//
243// addr = lseek (fh, 0, SEEK_CUR);
244//
245// state->Reg[0] = lseek (fh, 0L, SEEK_END);
246// (void) lseek (fh, addr, SEEK_SET);
247//
248//}
249
250/***************************************************************************\
251* The emulator calls this routine when a SWI instruction is encuntered. The *
252* parameter passed is the SWI number (lower 24 bits of the instruction). *
253\***************************************************************************/
254/* ahe-ykl information is retrieved from elf header and the starting value of
255 brk_static is in sky_info_t */
256
257/* brk static hold the value of brk */
258static uint32_t brk_static = -1;
259
260unsigned
261ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
262{
263 number &= 0xfffff;
264 ARMword addr, temp;
265
266 switch (number) {
267// case SWI_Syscall:
268// if (state->Reg[7] != 0)
269// return ARMul_OSHandleSWI(state, state->Reg[7]);
270// else
271// return FALSE;
272// case SWI_Read:
273// SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
274// return TRUE;
275//
276// case SWI_GetUID32:
277// state->Reg[0] = getuid();
278// return TRUE;
279//
280// case SWI_GetGID32:
281// state->Reg[0] = getgid();
282// return TRUE;
283//
284// case SWI_GetEUID32:
285// state->Reg[0] = geteuid();
286// return TRUE;
287//
288// case SWI_GetEGID32:
289// state->Reg[0] = getegid();
290// return TRUE;
291//
292// case SWI_Write:
293// SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
294// return TRUE;
295//
296// case SWI_Open:
297// SWIopen (state, state->Reg[0], state->Reg[1]);
298// return TRUE;
299//
300// case SWI_Close:
301// state->Reg[0] = close (state->Reg[0]);
302// return TRUE;
303//
304// case SWI_Seek:{
305// /* We must return non-zero for failure */
306// state->Reg[0] =
307// lseek (state->Reg[0], state->Reg[1],
308// SEEK_SET);
309// return TRUE;
310// }
311//
312// case SWI_ExitGroup:
313// case SWI_Exit:
314// {
315// struct timeval tv;
316// //gettimeofday(&tv,NULL);
317// //printf("In %s, %d sec, %d usec\n", __FUNCTION__, tv.tv_sec, tv.tv_usec);
318// printf("passed %d sec, %lld usec\n", get_clock_sec(), get_clock_us());
319//
320// /* quit here */
321// run_command("quit");
322// return TRUE;
323// }
324// case SWI_Times:{
325// uint32_t dest = state->Reg[0];
326// struct tms now;
327// struct target_tms32 nowret;
328//
329// uint32_t ret = times(&now);
330//
331// if (ret == -1){
332// debug("syscall %s error %d\n", "SWI_Times", ret);
333// state->Reg[0] = ret;
334// return FALSE;
335// }
336//
337// nowret.tms_cstime = now.tms_cstime;
338// nowret.tms_cutime = now.tms_cutime;
339// nowret.tms_stime = now.tms_stime;
340// nowret.tms_utime = now.tms_utime;
341//
342// uint32_t offset;
343// for (offset = 0; offset < sizeof(nowret); offset++) {
344// bus_write(8, dest + offset, *((uint8_t *) &nowret + offset));
345// }
346//
347// state->Reg[0] = ret;
348// return TRUE;
349// }
350//
351// case SWI_Gettimeofday: {
352// uint32_t dest1 = state->Reg[0];
353// uint32_t dest2 = state->Reg[1]; // Unsure of this
354// struct timeval val;
355// struct timezone zone;
356// struct target_timeval32 valret;
357// struct target_timezone32 zoneret;
358//
359// uint32_t ret = gettimeofday(&val, &zone);
360// valret.tv_sec = val.tv_sec;
361// valret.tv_usec = val.tv_usec;
362// zoneret.tz_dsttime = zoneret.tz_dsttime;
363// zoneret.tz_minuteswest = zoneret.tz_minuteswest;
364//
365// if (ret == -1){
366// debug("syscall %s error %d\n", "SWI_Gettimeofday", ret);
367// state->Reg[0] = ret;
368// return FALSE;
369// }
370//
371// uint32_t offset;
372// if (dest1) {
373// for (offset = 0; offset < sizeof(valret); offset++) {
374// bus_write(8, dest1 + offset, *((uint8_t *) &valret + offset));
375// }
376// state->Reg[0] = ret;
377// }
378// if (dest2) {
379// for (offset = 0; offset < sizeof(zoneret); offset++) {
380// bus_write(8, dest2 + offset, *((uint8_t *) &zoneret + offset));
381// }
382// state->Reg[0] = ret;
383// }
384//
385// return TRUE;
386// }
387// case SWI_Brk:
388// /* initialize brk value */
389// /* suppose that brk_static doesn't reach 0xffffffff... */
390// if (brk_static == -1) {
391// brk_static = (get_skyeye_pref()->info).brk;
392// }
393//
394// /* FIXME there might be a need to do a mmap */
395//
396// if(state->Reg[0]){
397// if (get_skyeye_exec_info()->mmap_access) {
398// /* if new brk is greater than current brk, allocate memory */
399// if (state->Reg[0] > brk_static) {
400// uint32_t ret = mmap( (void *) brk_static, state->Reg[0] - brk_static,
401// PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0 );
402// if (ret != MAP_FAILED)
403// brk_static = ret;
404// }
405// }
406// brk_static = state->Reg[0];
407// //state->Reg[0] = 0; /* FIXME return value of brk set to be the address on success */
408// } else {
409// state->Reg[0] = brk_static;
410// }
411// return TRUE;
412//
413// case SWI_Break:
414// state->Emulate = FALSE;
415// return TRUE;
416//
417// case SWI_Mmap:{
418// int addr = state->Reg[0];
419// int len = state->Reg[1];
420// int prot = state->Reg[2];
421// int flag = state->Reg[3];
422// int fd = state->Reg[4];
423// int offset = state->Reg[5];
424// mmap_area_t *area = new_mmap_area(addr, len);
425// state->Reg[0] = area->bank.addr;
426// //printf("syscall %d mmap(0x%x,%x,0x%x,0x%x,%d,0x%x) = 0x%x\n",\
427// SWI_Mmap, addr, len, prot, flag, fd, offset, state->Reg[0]);
428// return TRUE;
429// }
430//
431// case SWI_Munmap:
432// state->Reg[0] = 0;
433// return TRUE;
434//
435// case SWI_Mmap2:{
436// int addr = state->Reg[0];
437// int len = state->Reg[1];
438// int prot = state->Reg[2];
439// int flag = state->Reg[3];
440// int fd = state->Reg[4];
441// int offset = state->Reg[5] * 4096; /* page offset */
442// mmap_area_t *area = new_mmap_area(addr, len);
443// state->Reg[0] = area->bank.addr;
444//
445// return TRUE;
446// }
447//
448// case SWI_Breakpoint:
449// //chy 2005-09-12 change below line
450// //state->EndCondition = RDIError_BreakpointReached;
451// //printf ("SKYEYE: in armos.c : should not come here!!!!\n");
452// state->EndCondition = 0;
453// /*modified by ksh to support breakpoiont*/
454// state->Emulate = STOP;
455// return (TRUE);
456// case SWI_Uname:
457// {
458// struct utsname *uts = (uintptr_t) state->Reg[0]; /* uname should write data in this address */
459// struct utsname utsbuf;
460// //printf("Uname size is %x\n", sizeof(utsbuf));
461// char *buf;
462// uintptr_t sp ; /* used as a temporary address */
463//
464//#define COPY_UTS_STRING(addr) \
465// buf = addr; \
466// while(*buf != NULL) { \
467// bus_write(8, sp, *buf); \
468// sp++; \
469// buf++; \
470// }
471//#define COPY_UTS(field) /*printf("%s: %s at %p\n", #field, utsbuf.field, uts->field);*/ \
472// sp = (uintptr_t) uts->field; \
473// COPY_UTS_STRING((&utsbuf)->field);
474//
475// if (uname(&utsbuf) < 0) {
476// printf("syscall uname: utsname error\n");
477// state->Reg[0] = -1;
478// return FALSE;
479// }
480//
481// /* FIXME for now, this is just the host system call
482// Some data should be missing, as it depends on
483// the version of utsname */
484// COPY_UTS(sysname);
485// COPY_UTS(nodename);
486// COPY_UTS(release);
487// COPY_UTS(version);
488// COPY_UTS(machine);
489//
490// state->Reg[0] = 0;
491// return TRUE;
492// }
493// case SWI_Fcntl:
494// {
495// uint32_t fd = state->Reg[0];
496// uint32_t cmd = state->Reg[1];
497// uint32_t arg = state->Reg[2];
498// uint32_t ret;
499//
500// switch(cmd){
501// case (F_GETFD):
502// {
503// ret = fcntl(fd, cmd, arg);
504// //printf("syscall fcntl for getfd not implemented, ret %d\n", ret);
505// state->Reg[0] = ret;
506// return FALSE;
507// }
508// default:
509// break;
510// }
511//
512// printf("syscall fcntl unimplemented fd %x cmd %x\n", fd, cmd);
513// state->Reg[0] = -1;
514// return FALSE;
515//
516// }
517// case SWI_Fstat64:
518// {
519// uint32_t dest = state->Reg[1];
520// uint32_t fd = state->Reg[0];
521// struct stat64 statbuf;
522// struct target_stat64 statret;
523// memset(&statret, 0, sizeof(struct target_stat64));
524// uint32_t ret = fstat64(fd, &statbuf);
525//
526// if (ret == -1){
527// printf("syscall %s returned error\n", "SWI_Fstat");
528// state->Reg[0] = ret;
529// return FALSE;
530// }
531//
532// /* copy statbuf to the process memory space
533// FIXME can't say if endian has an effect here */
534// uint32_t offset;
535// //printf("Fstat system is size %x\n", sizeof(statbuf));
536// //printf("Fstat target is size %x\n", sizeof(statret));
537//
538// /* we copy system structure data stat64 into arm fixed size structure target_stat64 */
539// statret.st_dev = statbuf.st_dev;
540// statret.st_ino = statbuf.st_ino;
541// statret.st_mode = statbuf.st_mode;
542// statret.st_nlink = statbuf.st_nlink;
543// statret.st_uid = statbuf.st_uid;
544// statret.st_gid = statbuf.st_gid;
545// statret.st_rdev = statbuf.st_rdev;
546// statret.st_size = statbuf.st_size;
547// statret.st_blksize = statbuf.st_blksize;
548// statret.st_blocks = statbuf.st_blocks;
549// statret.st32_atime = statbuf.st_atime;
550// statret.st32_mtime = statbuf.st_mtime;
551// statret.st32_ctime = statbuf.st_ctime;
552//
553// for (offset = 0; offset < sizeof(statret); offset++) {
554// bus_write(8, dest + offset, *((uint8_t *) &statret + offset));
555// }
556//
557// state->Reg[0] = ret;
558// return TRUE;
559// }
560// case SWI_Set_tls:
561// {
562// //printf("syscall set_tls unimplemented\n");
563// state->mmu.thread_uro_id = state->Reg[0];
564// state->CP15[CP15_THREAD_URO - CP15_BASE] = state->Reg[0];
565// state->Reg[0] = 0;
566// return FALSE;
567// }
568//#if 0
569// case SWI_Clock:
570// /* return number of centi-seconds... */
571// state->Reg[0] =
572//#ifdef CLOCKS_PER_SEC
573// (CLOCKS_PER_SEC >= 100)
574// ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
575// : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
576//#else
577// /* presume unix... clock() returns microseconds */
578// (ARMword) (clock () / 10000);
579//#endif
580// return (TRUE);
581//
582// case SWI_Time:
583// state->Reg[0] = (ARMword) time (NULL);
584// return (TRUE);
585// case SWI_Flen:
586// SWIflen (state, state->Reg[0]);
587// return (TRUE);
588//
589//#endif
590 default:
591
592 _dbg_assert_msg_(ARM11, false, "ImplementMe: ARMul_OSHandleSWI!");
593
594 return (FALSE);
595 }
596}
597//
598///**
599// * @brief For mmap syscall.A mmap_area is a memory bank. Get from ppc.
600// */
601//static mmap_area_t* new_mmap_area(int sim_addr, int len){
602// mmap_area_t *area = (mmap_area_t *)malloc(sizeof(mmap_area_t));
603// if(area == NULL){
604// printf("error, failed %s\n",__FUNCTION__);
605// exit(0);
606// }
607//#if FAST_MEMORY
608// if (mmap_next_base == -1)
609// {
610// mmap_next_base = get_skyeye_exec_info()->brk;
611// }
612//#endif
613//
614// memset(area, 0x0, sizeof(mmap_area_t));
615// area->bank.addr = mmap_next_base;
616// area->bank.len = len;
617// area->bank.bank_write = mmap_mem_write;
618// area->bank.bank_read = mmap_mem_read;
619// area->bank.type = MEMTYPE_RAM;
620// area->bank.objname = "mmap";
621// addr_mapping(&area->bank);
622//
623//#if FAST_MEMORY
624// if (get_skyeye_exec_info()->mmap_access)
625// {
626// /* FIXME check proper flags */
627// /* FIXME we may delete the need of banks up there */
628// uint32_t ret = mmap(mmap_next_base, len, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
629// mmap_next_base = ret;
630// }
631// area->mmap_addr = (uint8_t*)get_dma_addr(mmap_next_base);
632//#else
633// area->mmap_addr = malloc(len);
634// if(area->mmap_addr == NULL){
635// printf("error mmap malloc\n");
636// exit(0);
637// }
638// memset(area->mmap_addr, 0x0, len);
639//#endif
640//
641// area->next = NULL;
642// if(mmap_global){
643// area->next = mmap_global->next;
644// mmap_global->next = area;
645// }else{
646// mmap_global = area;
647// }
648// mmap_next_base = mmap_next_base + len;
649// return area;
650//}
651//
652//static mmap_area_t *get_mmap_area(int addr){
653// mmap_area_t *tmp = mmap_global;
654// while(tmp){
655// if ((tmp->bank.addr <= addr) && (tmp->bank.addr + tmp->bank.len > addr)){
656// return tmp;
657// }
658// tmp = tmp->next;
659// }
660// printf("cannot get mmap area:addr=0x%x\n", addr);
661// return NULL;
662//}
663//
664///**
665// * @brief the mmap_area bank write function. Get from ppc.
666// *
667// * @param size size to write, 8/16/32
668// * @param addr address to write
669// * @param value value to write
670// *
671// * @return sucess return 1,otherwise 0.
672// */
673//static char mmap_mem_write(short size, int addr, uint32_t value){
674// mmap_area_t *area_tmp = get_mmap_area(addr);
675// mem_bank_t *bank_tmp = &area_tmp->bank;
676// int offset = addr - bank_tmp->addr;
677// switch(size){
678// case 8:{
679// //uint8_t value_endian = value;
680// uint8_t value_endian = (uint8_t)value;
681// *(uint8_t *)&(((char *)area_tmp->mmap_addr)[offset]) = value_endian;
682// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,value_endian);
683// break;
684// }
685// case 16:{
686// //uint16_t value_endian = half_to_BE((uint16_t)value);
687// uint16_t value_endian = ((uint16_t)value);
688// *(uint16_t *)&(((char *)area_tmp->mmap_addr)[offset]) = value_endian;
689// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,value_endian);
690// break;
691// }
692// case 32:{
693// //uint32_t value_endian = word_to_BE((uint32_t)value);
694// uint32_t value_endian = ((uint32_t)value);
695// *(uint32_t *)&(((char *)area_tmp->mmap_addr)[offset]) = value_endian;
696// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,value_endian);
697// break;
698// }
699// default:
700// printf("invalid size %d\n",size);
701// return 0;
702// }
703// return 1;
704//}
705//
706///**
707// * @brief the mmap_area bank read function. Get from ppc.
708// *
709// * @param size size to read, 8/16/32
710// * @param addr address to read
711// * @param value value to read
712// *
713// * @return sucess return 1,otherwise 0.
714// */
715//static char mmap_mem_read(short size, int addr, uint32_t * value){
716// mmap_area_t *area_tmp = get_mmap_area(addr);
717// mem_bank_t *bank_tmp = &area_tmp->bank;
718// int offset = addr - bank_tmp->addr;
719// switch(size){
720// case 8:{
721// //*(uint8_t *)value = *(uint8_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]);
722// *value = *(uint8_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]);
723// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,*(uint32_t*)value);
724// break;
725// }
726// case 16:{
727// //*(uint16_t *)value = half_from_BE(*(uint16_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
728// *value = (*(uint16_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
729// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,*(uint16_t*)value);
730// break;
731// }
732// case 32:
733// //*value = (uint32_t)word_from_BE(*(uint32_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
734// *value = (uint32_t)(*(uint32_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
735// debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,*(uint32_t*)value);
736// break;
737// default:
738// printf("invalid size %d\n",size);
739// return 0;
740// }
741// return 1;
742//}
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index 3d3545c65..2568b93ef 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -15,18 +15,11 @@
15 along with this program; if not, write to the Free Software 15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17 17
18//#include <util.h> 18#include "core/arm/skyeye_common/armdefs.h"
19 19#include "core/arm/skyeye_common/armemu.h"
20#include <string>
21#include "core/arm/interpreter/armdefs.h"
22#include "core/arm/interpreter/armemu.h"
23#include "core/hle/coprocessor.h"
24#include "core/arm/disassembler/arm_disasm.h" 20#include "core/arm/disassembler/arm_disasm.h"
21#include "core/mem_map.h"
25 22
26//#include "ansidecl.h"
27//#include "skyeye.h"
28//extern int skyeye_instr_debug;
29/* Definitions for the support routines. */
30 23
31static ARMword ModeToBank (ARMword); 24static ARMword ModeToBank (ARMword);
32static void EnvokeList (ARMul_State *, unsigned int, unsigned int); 25static void EnvokeList (ARMul_State *, unsigned int, unsigned int);
@@ -751,7 +744,7 @@ ARMword ARMul_MRC (ARMul_State * state, ARMword instr)
751 int cpopc = BITS(21, 23) & 0x7; 744 int cpopc = BITS(21, 23) & 0x7;
752 745
753 if (cn == 13 && cm == 0 && cp == 3) { //c13,c0,3; returns CPU svc buffer 746 if (cn == 13 && cm == 0 && cp == 3) { //c13,c0,3; returns CPU svc buffer
754 ARMword result = HLE::CallMRC(instr); 747 ARMword result = Memory::KERNEL_MEMORY_VADDR;
755 748
756 if (result != -1) { 749 if (result != -1) {
757 return result; 750 return result;
diff --git a/src/core/arm/interpreter/armvirt.cpp b/src/core/arm/interpreter/armvirt.cpp
index a072b73be..7845d1042 100644
--- a/src/core/arm/interpreter/armvirt.cpp
+++ b/src/core/arm/interpreter/armvirt.cpp
@@ -23,658 +23,143 @@ table. The routines PutWord and GetWord implement this. Pages are never
23freed as they might be needed again. A single area of memory may be 23freed as they might be needed again. A single area of memory may be
24defined to generate aborts. */ 24defined to generate aborts. */
25 25
26#include "armdefs.h" 26#include "core/arm/skyeye_common/armdefs.h"
27#include "skyeye_defs.h" 27#include "core/arm/skyeye_common/armemu.h"
28//#include "code_cov.h"
29 28
30#ifdef VALIDATE /* for running the validate suite */ 29#include "core/mem_map.h"
31#define TUBE 48 * 1024 * 1024 /* write a char on the screen */
32#define ABORTS 1
33#endif
34
35/* #define ABORTS */
36
37#ifdef ABORTS /* the memory system will abort */
38/* For the old test suite Abort between 32 Kbytes and 32 Mbytes
39 For the new test suite Abort between 8 Mbytes and 26 Mbytes */
40/* #define LOWABORT 32 * 1024
41#define HIGHABORT 32 * 1024 * 1024 */
42#define LOWABORT 8 * 1024 * 1024
43#define HIGHABORT 26 * 1024 * 1024
44
45#endif
46
47#define NUMPAGES 64 * 1024
48#define PAGESIZE 64 * 1024
49#define PAGEBITS 16
50#define OFFSETBITS 0xffff
51//chy 2003-08-19: seems no use ????
52int SWI_vector_installed = FALSE;
53extern ARMword skyeye_cachetype;
54
55/***************************************************************************\
56* Get a byte into Virtual Memory, maybe allocating the page *
57\***************************************************************************/
58static fault_t
59GetByte (ARMul_State * state, ARMword address, ARMword * data)
60{
61 fault_t fault;
62
63 fault = mmu_read_byte (state, address, data);
64 if (fault) {
65//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
66// printf("SKYEYE: GetByte fault %d \n", fault);
67 }
68 return fault;
69}
70
71/***************************************************************************\
72* Get a halfword into Virtual Memory, maybe allocating the page *
73\***************************************************************************/
74static fault_t
75GetHalfWord (ARMul_State * state, ARMword address, ARMword * data)
76{
77 fault_t fault;
78
79 fault = mmu_read_halfword (state, address, data);
80 if (fault) {
81//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
82// printf("SKYEYE: GetHalfWord fault %d \n", fault);
83 }
84 return fault;
85}
86
87/***************************************************************************\
88* Get a Word from Virtual Memory, maybe allocating the page *
89\***************************************************************************/
90 30
91static fault_t 31#define dumpstack 1
92GetWord (ARMul_State * state, ARMword address, ARMword * data) 32#define dumpstacksize 0x10
93{ 33#define maxdmupaddr 0x0033a850
94 fault_t fault;
95 34
96 fault = mmu_read_word (state, address, data); 35/*ARMword ARMul_GetCPSR (ARMul_State * state) {
97 if (fault) { 36return 0;
98//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
99#if 0
100/* XXX */ extern int hack;
101 hack = 1;
102#endif
103#if 0
104 printf ("mmu_read_word at 0x%08x: ", address);
105 switch (fault) {
106 case ALIGNMENT_FAULT:
107 printf ("ALIGNMENT_FAULT");
108 break;
109 case SECTION_TRANSLATION_FAULT:
110 printf ("SECTION_TRANSLATION_FAULT");
111 break;
112 case PAGE_TRANSLATION_FAULT:
113 printf ("PAGE_TRANSLATION_FAULT");
114 break;
115 case SECTION_DOMAIN_FAULT:
116 printf ("SECTION_DOMAIN_FAULT");
117 break;
118 case SECTION_PERMISSION_FAULT:
119 printf ("SECTION_PERMISSION_FAULT");
120 break;
121 case SUBPAGE_PERMISSION_FAULT:
122 printf ("SUBPAGE_PERMISSION_FAULT");
123 break;
124 default:
125 printf ("Unrecognized fault number!");
126 }
127 printf ("\tpc = 0x%08x\n", state->Reg[15]);
128#endif
129 }
130 return fault;
131} 37}
132 38ARMword ARMul_GetSPSR (ARMul_State * state, ARMword mode) {
133//2003-07-10 chy: lyh change 39return 0;
134/****************************************************************************\
135 * Load a Instrion Word into Virtual Memory *
136\****************************************************************************/
137static fault_t
138LoadInstr (ARMul_State * state, ARMword address, ARMword * instr)
139{
140 fault_t fault;
141 fault = mmu_load_instr (state, address, instr);
142 return fault;
143 //if (fault)
144 // log_msg("load_instr fault = %d, address = %x\n", fault, address);
145} 40}
41void ARMul_SetCPSR (ARMul_State * state, ARMword value) {
146 42
147/***************************************************************************\
148* Put a byte into Virtual Memory, maybe allocating the page *
149\***************************************************************************/
150static fault_t
151PutByte (ARMul_State * state, ARMword address, ARMword data)
152{
153 fault_t fault;
154
155 fault = mmu_write_byte (state, address, data);
156 if (fault) {
157//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
158// printf("SKYEYE: PutByte fault %d \n", fault);
159 }
160 return fault;
161} 43}
44void ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value) {
162 45
163/***************************************************************************\ 46}*/
164* Put a halfword into Virtual Memory, maybe allocating the page *
165\***************************************************************************/
166static fault_t
167PutHalfWord (ARMul_State * state, ARMword address, ARMword data)
168{
169 fault_t fault;
170 47
171 fault = mmu_write_halfword (state, address, data); 48void ARMul_Icycles(ARMul_State * state, unsigned number, ARMword address) {
172 if (fault) {
173//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
174// printf("SKYEYE: PutHalfWord fault %d \n", fault);
175 }
176 return fault;
177} 49}
178 50
179/***************************************************************************\ 51void ARMul_Ccycles(ARMul_State * state, unsigned number, ARMword address) {
180* Put a Word into Virtual Memory, maybe allocating the page *
181\***************************************************************************/
182
183static fault_t
184PutWord (ARMul_State * state, ARMword address, ARMword data)
185{
186 fault_t fault;
187
188 fault = mmu_write_word (state, address, data);
189 if (fault) {
190//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
191#if 0
192/* XXX */ extern int hack;
193 hack = 1;
194#endif
195#if 0
196 printf ("mmu_write_word at 0x%08x: ", address);
197 switch (fault) {
198 case ALIGNMENT_FAULT:
199 printf ("ALIGNMENT_FAULT");
200 break;
201 case SECTION_TRANSLATION_FAULT:
202 printf ("SECTION_TRANSLATION_FAULT");
203 break;
204 case PAGE_TRANSLATION_FAULT:
205 printf ("PAGE_TRANSLATION_FAULT");
206 break;
207 case SECTION_DOMAIN_FAULT:
208 printf ("SECTION_DOMAIN_FAULT");
209 break;
210 case SECTION_PERMISSION_FAULT:
211 printf ("SECTION_PERMISSION_FAULT");
212 break;
213 case SUBPAGE_PERMISSION_FAULT:
214 printf ("SUBPAGE_PERMISSION_FAULT");
215 break;
216 default:
217 printf ("Unrecognized fault number!");
218 }
219 printf ("\tpc = 0x%08x\n", state->Reg[15]);
220#endif
221 }
222 return fault;
223} 52}
224 53
225/***************************************************************************\ 54ARMword ARMul_LoadInstrS(ARMul_State * state, ARMword address, ARMword isize) {
226* Initialise the memory interface * 55 state->NumScycles++;
227\***************************************************************************/
228
229unsigned
230ARMul_MemoryInit (ARMul_State * state, unsigned int initmemsize)
231{
232 return TRUE;
233}
234
235/***************************************************************************\
236* Remove the memory interface *
237\***************************************************************************/
238
239void
240ARMul_MemoryExit (ARMul_State * state)
241{
242}
243
244/***************************************************************************\
245* ReLoad Instruction *
246\***************************************************************************/
247
248ARMword
249ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize)
250{
251 ARMword data;
252 fault_t fault;
253
254#ifdef ABORTS
255 if (address >= LOWABORT && address < HIGHABORT) {
256 ARMul_PREFETCHABORT (address);
257 return ARMul_ABORTWORD;
258 }
259 else {
260 ARMul_CLEARABORT;
261 }
262#endif
263#if 0
264 /* do profiling for code coverage */
265 if (skyeye_config.code_cov.prof_on)
266 cov_prof(EXEC_FLAG, address);
267#endif
268#if 1
269 if ((isize == 2) && (address & 0x2)) {
270 ARMword lo, hi;
271 if (!(skyeye_cachetype == INSTCACHE))
272 fault = GetHalfWord (state, address, &lo);
273 else
274 fault = LoadInstr (state, address, &lo);
275#if 0
276 if (!fault) {
277 if (!(skyeye_cachetype == INSTCACHE))
278 fault = GetHalfWord (state, address + isize, &hi);
279 else
280 fault = LoadInstr (state, address + isize, &hi);
281
282 }
283#endif
284 if (fault) {
285 ARMul_PREFETCHABORT (address);
286 return ARMul_ABORTWORD;
287 }
288 else {
289 ARMul_CLEARABORT;
290 }
291 return lo;
292#if 0
293 if (state->bigendSig == HIGH)
294 return (lo << 16) | (hi >> 16);
295 else
296 return ((hi & 0xFFFF) << 16) | (lo >> 16);
297#endif
298 }
299#endif
300 if (!(skyeye_cachetype == INSTCACHE))
301 fault = GetWord (state, address, &data);
302 else
303 fault = LoadInstr (state, address, &data);
304
305 if (fault) {
306
307 /* dyf add for s3c6410 no instcache temporary 2010.9.17 */
308 if (!(skyeye_cachetype == INSTCACHE)) {
309 /* set translation fault on prefetch abort */
310 state->mmu.fault_statusi = fault & 0xFF;
311 state->mmu.fault_address = address;
312 }
313 /* add end */
314
315 ARMul_PREFETCHABORT (address);
316 return ARMul_ABORTWORD;
317 }
318 else {
319 ARMul_CLEARABORT;
320 }
321
322 return data;
323}
324
325/***************************************************************************\
326* Load Instruction, Sequential Cycle *
327\***************************************************************************/
328
329ARMword
330ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize)
331{
332 state->NumScycles++;
333 56
334#ifdef HOURGLASS 57#ifdef HOURGLASS
335 if ((state->NumScycles & HOURGLASS_RATE) == 0) { 58 if ((state->NumScycles & HOURGLASS_RATE) == 0) {
336 HOURGLASS; 59 HOURGLASS;
337 } 60 }
338#endif 61#endif
339 62 if (isize == 2)
340 return ARMul_ReLoadInstr (state, address, isize); 63 return (u16)Memory::Read16(address);
64 else
65 return (u32)Memory::Read32(address);
341} 66}
342 67
343/***************************************************************************\ 68ARMword ARMul_LoadInstrN(ARMul_State * state, ARMword address, ARMword isize) {
344* Load Instruction, Non Sequential Cycle * 69 state->NumNcycles++;
345\***************************************************************************/
346
347ARMword
348ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
349{
350 state->NumNcycles++;
351 70
352 return ARMul_ReLoadInstr (state, address, isize); 71 if (isize == 2)
72 return (u16)Memory::Read16(address);
73 else
74 return (u32)Memory::Read32(address);
353} 75}
354 76
355/***************************************************************************\ 77ARMword ARMul_ReLoadInstr(ARMul_State * state, ARMword address, ARMword isize) {
356* Read Word (but don't tell anyone!) * 78 ARMword data;
357\***************************************************************************/
358 79
359ARMword 80 if ((isize == 2) && (address & 0x2)) {
360ARMul_ReadWord (ARMul_State * state, ARMword address) 81 ARMword lo;
361{ 82 lo = (u16)Memory::Read16(address);
362 ARMword data; 83 return lo;
363 fault_t fault; 84 }
364
365#ifdef ABORTS
366 if (address >= LOWABORT && address < HIGHABORT) {
367 ARMul_DATAABORT (address);
368 return ARMul_ABORTWORD;
369 }
370 else {
371 ARMul_CLEARABORT;
372 }
373#endif
374 85
375 fault = GetWord (state, address, &data); 86 data = (u32)Memory::Read32(address);
376 if (fault) { 87 return data;
377 state->mmu.fault_status =
378 (fault | (state->mmu.last_domain << 4)) & 0xFF;
379 state->mmu.fault_address = address;
380 ARMul_DATAABORT (address);
381 return ARMul_ABORTWORD;
382 }
383 else {
384 ARMul_CLEARABORT;
385 }
386 return data;
387} 88}
388 89
389/***************************************************************************\ 90ARMword ARMul_ReadWord(ARMul_State * state, ARMword address) {
390* Load Word, Sequential Cycle * 91 ARMword data;
391\***************************************************************************/ 92 data = Memory::Read32(address);
392 93 return data;
393ARMword
394ARMul_LoadWordS (ARMul_State * state, ARMword address)
395{
396 state->NumScycles++;
397
398 return ARMul_ReadWord (state, address);
399} 94}
400 95
401/***************************************************************************\ 96ARMword ARMul_LoadWordS(ARMul_State * state, ARMword address) {
402* Load Word, Non Sequential Cycle * 97 state->NumScycles++;
403\***************************************************************************/ 98 return ARMul_ReadWord(state, address);
404
405ARMword
406ARMul_LoadWordN (ARMul_State * state, ARMword address)
407{
408 state->NumNcycles++;
409
410 return ARMul_ReadWord (state, address);
411} 99}
412 100
413/***************************************************************************\ 101ARMword ARMul_LoadWordN(ARMul_State * state, ARMword address) {
414* Load Halfword, (Non Sequential Cycle) * 102 state->NumNcycles++;
415\***************************************************************************/ 103 return ARMul_ReadWord(state, address);
416
417ARMword
418ARMul_LoadHalfWord (ARMul_State * state, ARMword address)
419{
420 ARMword data;
421 fault_t fault;
422
423 state->NumNcycles++;
424 fault = GetHalfWord (state, address, &data);
425
426 if (fault) {
427 state->mmu.fault_status =
428 (fault | (state->mmu.last_domain << 4)) & 0xFF;
429 state->mmu.fault_address = address;
430 ARMul_DATAABORT (address);
431 return ARMul_ABORTWORD;
432 }
433 else {
434 ARMul_CLEARABORT;
435 }
436
437 return data;
438
439} 104}
440 105
441/***************************************************************************\ 106ARMword ARMul_LoadHalfWord(ARMul_State * state, ARMword address) {
442* Read Byte (but don't tell anyone!) * 107 state->NumNcycles++;
443\***************************************************************************/ 108 return (u16)Memory::Read16(address);;
444int ARMul_ICE_ReadByte(ARMul_State * state, ARMword address, ARMword *presult)
445{
446 ARMword data;
447 fault_t fault;
448 fault = GetByte (state, address, &data);
449 if (fault) {
450 *presult=-1; fault=ALIGNMENT_FAULT; return fault;
451 }else{
452 *(char *)presult=(unsigned char)(data & 0xff); fault=NO_FAULT; return fault;
453 }
454} 109}
455
456
457ARMword
458ARMul_ReadByte (ARMul_State * state, ARMword address)
459{
460 ARMword data;
461 fault_t fault;
462
463 fault = GetByte (state, address, &data);
464
465 if (fault) {
466 state->mmu.fault_status =
467 (fault | (state->mmu.last_domain << 4)) & 0xFF;
468 state->mmu.fault_address = address;
469 ARMul_DATAABORT (address);
470 return ARMul_ABORTWORD;
471 }
472 else {
473 ARMul_CLEARABORT;
474 }
475
476 return data;
477
478}
479
480/***************************************************************************\
481* Load Byte, (Non Sequential Cycle) *
482\***************************************************************************/
483
484ARMword
485ARMul_LoadByte (ARMul_State * state, ARMword address)
486{
487 state->NumNcycles++;
488
489 return ARMul_ReadByte (state, address);
490}
491
492/***************************************************************************\
493* Write Word (but don't tell anyone!) *
494\***************************************************************************/
495
496void
497ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data)
498{
499 fault_t fault;
500
501#ifdef ABORTS
502 if (address >= LOWABORT && address < HIGHABORT) {
503 ARMul_DATAABORT (address);
504 return;
505 }
506 else {
507 ARMul_CLEARABORT;
508 }
509#endif
510 110
511 fault = PutWord (state, address, data); 111ARMword ARMul_ReadByte(ARMul_State * state, ARMword address) {
512 if (fault) { 112 return (u8)Memory::Read8(address);
513 state->mmu.fault_status =
514 (fault | (state->mmu.last_domain << 4)) & 0xFF;
515 state->mmu.fault_address = address;
516 ARMul_DATAABORT (address);
517 return;
518 }
519 else {
520 ARMul_CLEARABORT;
521 }
522} 113}
523 114
524/***************************************************************************\ 115ARMword ARMul_LoadByte(ARMul_State * state, ARMword address) {
525* Store Word, Sequential Cycle * 116 state->NumNcycles++;
526\***************************************************************************/ 117 return ARMul_ReadByte(state, address);
527
528void
529ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data)
530{
531 state->NumScycles++;
532
533 ARMul_WriteWord (state, address, data);
534} 118}
535 119
536/***************************************************************************\ 120void ARMul_StoreHalfWord(ARMul_State * state, ARMword address, ARMword data) {
537* Store Word, Non Sequential Cycle * 121 state->NumNcycles++;
538\***************************************************************************/ 122 Memory::Write16(address, data);
539
540void
541ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data)
542{
543 state->NumNcycles++;
544
545 ARMul_WriteWord (state, address, data);
546} 123}
547 124
548/***************************************************************************\ 125void ARMul_StoreByte(ARMul_State * state, ARMword address, ARMword data) {
549* Store HalfWord, (Non Sequential Cycle) * 126 state->NumNcycles++;
550\***************************************************************************/ 127 ARMul_WriteByte(state, address, data);
551
552void
553ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data)
554{
555 fault_t fault;
556 state->NumNcycles++;
557 fault = PutHalfWord (state, address, data);
558 if (fault) {
559 state->mmu.fault_status =
560 (fault | (state->mmu.last_domain << 4)) & 0xFF;
561 state->mmu.fault_address = address;
562 ARMul_DATAABORT (address);
563 return;
564 }
565 else {
566 ARMul_CLEARABORT;
567 }
568} 128}
569 129
570//chy 2006-04-15 130ARMword ARMul_SwapWord(ARMul_State * state, ARMword address, ARMword data) {
571int ARMul_ICE_WriteByte (ARMul_State * state, ARMword address, ARMword data) 131 ARMword temp;
572{ 132 state->NumNcycles++;
573 fault_t fault; 133 temp = ARMul_ReadWord(state, address);
574 fault = PutByte (state, address, data); 134 state->NumNcycles++;
575 if (fault) 135 Memory::Write32(address, data);
576 return 1; 136 return temp;
577 else
578 return 0;
579}
580/***************************************************************************\
581* Write Byte (but don't tell anyone!) *
582\***************************************************************************/
583//chy 2003-07-10, add real write byte fun
584void
585ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data)
586{
587 fault_t fault;
588 fault = PutByte (state, address, data);
589 if (fault) {
590 state->mmu.fault_status =
591 (fault | (state->mmu.last_domain << 4)) & 0xFF;
592 state->mmu.fault_address = address;
593 ARMul_DATAABORT (address);
594 return;
595 }
596 else {
597 ARMul_CLEARABORT;
598 }
599} 137}
600 138
601/***************************************************************************\ 139ARMword ARMul_SwapByte(ARMul_State * state, ARMword address, ARMword data) {
602* Store Byte, (Non Sequential Cycle) * 140 ARMword temp;
603\***************************************************************************/ 141 temp = ARMul_LoadByte(state, address);
604 142 Memory::Write8(address, data);
605void 143 return temp;
606ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data)
607{
608 state->NumNcycles++;
609
610#ifdef VALIDATE
611 if (address == TUBE) {
612 if (data == 4)
613 state->Emulate = FALSE;
614 else
615 (void) putc ((char) data, stderr); /* Write Char */
616 return;
617 }
618#endif
619
620 ARMul_WriteByte (state, address, data);
621} 144}
622 145
623/***************************************************************************\ 146void ARMul_WriteWord(ARMul_State * state, ARMword address, ARMword data) {
624* Swap Word, (Two Non Sequential Cycles) * 147 Memory::Write32(address, data);
625\***************************************************************************/
626
627ARMword
628ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data)
629{
630 ARMword temp;
631
632 state->NumNcycles++;
633
634 temp = ARMul_ReadWord (state, address);
635
636 state->NumNcycles++;
637
638 PutWord (state, address, data);
639
640 return temp;
641} 148}
642 149
643/***************************************************************************\ 150void ARMul_WriteByte(ARMul_State * state, ARMword address, ARMword data)
644* Swap Byte, (Two Non Sequential Cycles) *
645\***************************************************************************/
646
647ARMword
648ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data)
649{ 151{
650 ARMword temp; 152 Memory::Write8(address, data);
651
652 temp = ARMul_LoadByte (state, address);
653 ARMul_StoreByte (state, address, data);
654
655 return temp;
656} 153}
657 154
658/***************************************************************************\ 155void ARMul_StoreWordS(ARMul_State * state, ARMword address, ARMword data)
659* Count I Cycles *
660\***************************************************************************/
661
662void
663ARMul_Icycles (ARMul_State * state, unsigned number,
664 ARMword address)
665{ 156{
666 state->NumIcycles += number; 157 state->NumScycles++;
667 ARMul_CLEARABORT; 158 ARMul_WriteWord(state, address, data);
668} 159}
669 160
670/***************************************************************************\ 161void ARMul_StoreWordN(ARMul_State * state, ARMword address, ARMword data)
671* Count C Cycles *
672\***************************************************************************/
673
674void
675ARMul_Ccycles (ARMul_State * state, unsigned number,
676 ARMword address)
677{ 162{
678 state->NumCcycles += number; 163 state->NumNcycles++;
679 ARMul_CLEARABORT; 164 ARMul_WriteWord(state, address, data);
680} 165}
diff --git a/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.cpp b/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.cpp
deleted file mode 100644
index a32f076b9..000000000
--- a/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.cpp
+++ /dev/null
@@ -1,1132 +0,0 @@
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
25#include "core/mem_map.h"
26
27#include "core/arm/interpreter/skyeye_defs.h"
28
29#include "core/arm/interpreter/armdefs.h"
30//#include "bank_defs.h"
31#if 0
32#define TLB_SIZE 1024 * 1024
33#define ASID 255
34static uint32_t tlb_entry_array[TLB_SIZE][ASID];
35static inline void invalidate_all_tlb(ARMul_State *state){
36 memset(&tlb_entry_array[0], 0xFF, sizeof(uint32_t) * TLB_SIZE * ASID);
37}
38static inline void invalidate_by_mva(ARMul_State *state, ARMword va){
39 memset(&tlb_entry_array[va >> 12][va & 0xFF], 0xFF, sizeof(uint32_t));
40 return;
41}
42static inline void invalidate_by_asid(ARMul_State *state, ARMword asid){
43 int i;
44 for(i = 0; i < TLB_SIZE; i++)
45 memset(&tlb_entry_array[i][asid & 0xFF], 0xFF, sizeof(uint32_t));
46 return;
47}
48
49static uint32_t get_phys_page(ARMul_State* state, ARMword va){
50 uint32_t phys_page = tlb_entry_array[va >> 12][state->mmu.context_id & 0xFF];
51 //printf("In %s, for va=0x%x, page=0x%x\n", __func__, va, phys_page);
52 return phys_page;
53}
54
55static inline void insert_tlb(ARMul_State* state, ARMword va, ARMword pa){
56 //printf("In %s, insert va=0x%x, pa=0x%x\n", __FUNCTION__, va, pa);
57 //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);
58 tlb_entry_array[va >> 12][state->mmu.context_id & 0xFF] = pa >> 12;
59
60 return;
61}
62#endif
63#define BANK0_START 0x50000000
64static void* mem_ptr = NULL;
65
66static int exclusive_detect(ARMul_State* state, ARMword addr){
67 #if 0
68 for(int i = 0; i < 128; i++){
69 if(state->exclusive_tag_array[i] == addr)
70 return 0;
71 }
72 #endif
73 if(state->exclusive_tag_array[0] == addr)
74 return 0;
75 else
76 return -1;
77}
78
79static void add_exclusive_addr(ARMul_State* state, ARMword addr){
80 #if 0
81 for(int i = 0; i < 128; i++){
82 if(state->exclusive_tag_array[i] == 0xffffffff){
83 state->exclusive_tag_array[i] = addr;
84 //printf("In %s, add addr 0x%x\n", __func__, addr);
85 return;
86 }
87 }
88 printf("In %s ,can not monitor the addr, out of array\n", __FUNCTION__);
89 #endif
90 state->exclusive_tag_array[0] = addr;
91 return;
92}
93
94static void remove_exclusive(ARMul_State* state, ARMword addr){
95 #if 0
96 int i;
97 for(i = 0; i < 128; i++){
98 if(state->exclusive_tag_array[i] == addr){
99 state->exclusive_tag_array[i] = 0xffffffff;
100 //printf("In %s, remove addr 0x%x\n", __func__, addr);
101 return;
102 }
103 }
104 #endif
105 state->exclusive_tag_array[0] = 0xFFFFFFFF;
106}
107
108/* This function encodes table 8-2 Interpreting AP bits,
109 returning non-zero if access is allowed. */
110static int
111check_perms (ARMul_State *state, int ap, int read)
112{
113 int s, r, user;
114
115 s = state->mmu.control & CONTROL_SYSTEM;
116 r = state->mmu.control & CONTROL_ROM;
117 /* chy 2006-02-15 , should consider system mode, don't conside 26bit mode */
118// printf("ap is %x, user is %x, s is %x, read is %x\n", ap, user, s, read);
119// printf("mode is %x\n", state->Mode);
120 user = (state->Mode == USER32MODE) || (state->Mode == USER26MODE) || (state->Mode == SYSTEM32MODE);
121
122 switch (ap) {
123 case 0:
124 return read && ((s && !user) || r);
125 case 1:
126 return !user;
127 case 2:
128 return read || !user;
129 case 3:
130 return 1;
131 }
132 return 0;
133}
134
135#if 0
136fault_t
137check_access (ARMul_State *state, ARMword virt_addr, tlb_entry_t *tlb,
138 int read)
139{
140 int access;
141
142 state->mmu.last_domain = tlb->domain;
143 access = (state->mmu.domain_access_control >> (tlb->domain * 2)) & 3;
144 if ((access == 0) || (access == 2)) {
145 /* It's unclear from the documentation whether this
146 should always raise a section domain fault, or if
147 it should be a page domain fault in the case of an
148 L1 that describes a page table. In the ARM710T
149 datasheets, "Figure 8-9: Sequence for checking faults"
150 seems to indicate the former, while "Table 8-4: Priority
151 encoding of fault status" gives a value for FS[3210] in
152 the event of a domain fault for a page. Hmm. */
153 return SECTION_DOMAIN_FAULT;
154 }
155 if (access == 1) {
156 /* client access - check perms */
157 int subpage, ap;
158#if 0
159 switch (tlb->mapping) {
160 /*ks 2004-05-09
161 * only for XScale
162 * Extend Small Page(ESP) Format
163 * 31-12 bits the base addr of ESP
164 * 11-10 bits SBZ
165 * 9-6 bits TEX
166 * 5-4 bits AP
167 * 3 bit C
168 * 2 bit B
169 * 1-0 bits 11
170 * */
171 case TLB_ESMALLPAGE: /* xj */
172 subpage = 0;
173 /* printf("TLB_ESMALLPAGE virt_addr=0x%x \n",virt_addr ); */
174 break;
175
176 case TLB_TINYPAGE:
177 subpage = 0;
178 /* printf("TLB_TINYPAGE virt_addr=0x%x \n",virt_addr ); */
179 break;
180
181 case TLB_SMALLPAGE:
182 subpage = (virt_addr >> 10) & 3;
183 break;
184 case TLB_LARGEPAGE:
185 subpage = (virt_addr >> 14) & 3;
186 break;
187 case TLB_SECTION:
188 subpage = 3;
189 break;
190 default:
191 assert (0);
192 subpage = 0; /* cleans a warning */
193 }
194 ap = (tlb->perms >> (subpage * 2 + 4)) & 3;
195 if (!check_perms (state, ap, read)) {
196 if (tlb->mapping == TLB_SECTION) {
197 return SECTION_PERMISSION_FAULT;
198 } else {
199 return SUBPAGE_PERMISSION_FAULT;
200 }
201 }
202#endif
203 } else { /* access == 3 */
204 /* manager access - don't check perms */
205 }
206 return NO_FAULT;
207}
208#endif
209
210#if 0
211fault_t
212mmu_translate (ARMul_State *state, ARMword virt_addr, ARMword *phys_addr)
213#endif
214
215/* ap: AP bits value.
216 * sop: section or page description 0:section 1:page
217 */
218fault_t
219mmu_translate (ARMul_State *state, ARMword virt_addr, ARMword *phys_addr, int *ap, int *sop)
220{
221 {
222 /* walk the translation tables */
223 ARMword l1addr, l1desc;
224 if (state->mmu.translation_table_ctrl && virt_addr << state->mmu.translation_table_ctrl >> (32 - state->mmu.translation_table_ctrl - 1)) {
225 l1addr = state->mmu.translation_table_base1;
226 l1addr = (((l1addr >> 14) << 14) | (virt_addr >> 18)) & ~3;
227 } else {
228 l1addr = state->mmu.translation_table_base0;
229 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;
230 }
231
232 /* l1desc = mem_read_word (state, l1addr); */
233 if (state->space.conf_obj != NULL)
234 state->space.read(state->space.conf_obj, l1addr, &l1desc, 4);
235 else
236 l1desc = Memory::Read32(l1addr); //mem_read_raw(32, l1addr, &l1desc);
237
238 #if 0
239 if (virt_addr == 0xc000d2bc) {
240 printf("mmu_control is %x\n", state->mmu.translation_table_ctrl);
241 printf("mmu_table_0 is %x\n", state->mmu.translation_table_base0);
242 printf("mmu_table_1 is %x\n", state->mmu.translation_table_base1);
243 printf("l1addr is %x l1desc is %x\n", l1addr, l1desc);
244 // exit(-1);
245 }
246 #endif
247 switch (l1desc & 3) {
248 case 0:
249 case 3:
250 /*
251 * according to Figure 3-9 Sequence for checking faults in arm manual,
252 * section translation fault should be returned here.
253 */
254 {
255 return SECTION_TRANSLATION_FAULT;
256 }
257 case 1:
258 /* coarse page table */
259 {
260 ARMword l2addr, l2desc;
261
262
263 l2addr = l1desc & 0xFFFFFC00;
264 l2addr = (l2addr |
265 ((virt_addr & 0x000FF000) >> 10)) &
266 ~3;
267 if(state->space.conf_obj != NULL)
268 state->space.read(state->space.conf_obj, l2addr, &l2desc, 4);
269 else
270 l2desc = Memory::Read32(l2addr); //mem_read_raw(32, l2addr, &l2desc);
271
272 /* chy 2003-09-02 for xscale */
273 *ap = (l2desc >> 4) & 0x3;
274 *sop = 1; /* page */
275
276 switch (l2desc & 3) {
277 case 0:
278 return PAGE_TRANSLATION_FAULT;
279 break;
280 case 1:
281 *phys_addr = (l2desc & 0xFFFF0000) | (virt_addr & 0x0000FFFF);
282 break;
283 case 2:
284 case 3:
285 *phys_addr = (l2desc & 0xFFFFF000) | (virt_addr & 0x00000FFF);
286 break;
287
288 }
289 }
290 break;
291 case 2:
292 /* section */
293
294 *ap = (l1desc >> 10) & 3;
295 *sop = 0; /* section */
296 #if 0
297 if (virt_addr == 0xc000d2bc) {
298 printf("mmu_control is %x\n", state->mmu.translation_table_ctrl);
299 printf("mmu_table_0 is %x\n", state->mmu.translation_table_base0);
300 printf("mmu_table_1 is %x\n", state->mmu.translation_table_base1);
301 printf("l1addr is %x l1desc is %x\n", l1addr, l1desc);
302// printf("l2addr is %x l2desc is %x\n", l2addr, l2desc);
303 printf("ap is %x, sop is %x\n", *ap, *sop);
304 printf("mode is %d\n", state->Mode);
305// exit(-1);
306 }
307 #endif
308
309 if (l1desc & 0x30000)
310 *phys_addr = (l1desc & 0xFF000000) | (virt_addr & 0x00FFFFFF);
311 else
312 *phys_addr = (l1desc & 0xFFF00000) | (virt_addr & 0x000FFFFF);
313 break;
314 }
315 }
316 return NO_FAULT;
317}
318
319
320static fault_t arm1176jzf_s_mmu_write (ARMul_State *state, ARMword va,
321 ARMword data, ARMword datatype);
322static fault_t arm1176jzf_s_mmu_read (ARMul_State *state, ARMword va,
323 ARMword *data, ARMword datatype);
324
325int
326arm1176jzf_s_mmu_init (ARMul_State *state)
327{
328 state->mmu.control = 0x50078;
329 state->mmu.translation_table_base = 0xDEADC0DE;
330 state->mmu.domain_access_control = 0xDEADC0DE;
331 state->mmu.fault_status = 0;
332 state->mmu.fault_address = 0;
333 state->mmu.process_id = 0;
334 state->mmu.context_id = 0;
335 state->mmu.thread_uro_id = 0;
336 //invalidate_all_tlb(state);
337
338 return No_exp;
339}
340
341void
342arm1176jzf_s_mmu_exit (ARMul_State *state)
343{
344}
345
346
347static fault_t
348arm1176jzf_s_mmu_load_instr (ARMul_State *state, ARMword va, ARMword *instr)
349{
350 fault_t fault;
351 int c; /* cache bit */
352 ARMword pa; /* physical addr */
353 ARMword perm; /* physical addr access permissions */
354 int ap, sop;
355
356 static int debug_count = 0; /* used for debug */
357
358 //DEBUG_LOG(ARM11, "va = %x\n", va);
359
360 va = mmu_pid_va_map (va);
361 if (MMU_Enabled) {
362// printf("MMU enabled.\n");
363// sleep(1);
364 /* align check */
365 if ((va & (WORD_SIZE - 1)) && MMU_Aligned) {
366 DEBUG_LOG(ARM11, "align\n");
367 return ALIGNMENT_FAULT;
368 } else
369 va &= ~(WORD_SIZE - 1);
370
371 /* translate tlb */
372 fault = mmu_translate (state, va, &pa, &ap, &sop);
373 if (fault) {
374 DEBUG_LOG(ARM11, "translate\n");
375 printf("va=0x%x, icounter=%lld, fault=%d\n", va, state->NumInstrs, fault);
376 return fault;
377 }
378
379
380 /* no tlb, only check permission */
381 if (!check_perms(state, ap, 1)) {
382 if (sop == 0) {
383 return SECTION_PERMISSION_FAULT;
384 } else {
385 return SUBPAGE_PERMISSION_FAULT;
386 }
387 }
388
389#if 0
390 /*check access */
391 fault = check_access (state, va, tlb, 1);
392 if (fault) {
393 DEBUG_LOG(ARM11, "check_fault\n");
394 return fault;
395 }
396#endif
397 }
398
399 /*if MMU disabled or C flag is set alloc cache */
400 if (MMU_Disabled) {
401// printf("MMU disabled.\n");
402// sleep(1);
403 pa = va;
404 }
405 if(state->space.conf_obj == NULL)
406 state->space.read(state->space.conf_obj, pa, instr, 4);
407 else
408 *instr = Memory::Read32(pa); //mem_read_raw(32, pa, instr);
409
410 return NO_FAULT;
411}
412
413static fault_t
414arm1176jzf_s_mmu_read_byte (ARMul_State *state, ARMword virt_addr, ARMword *data)
415{
416 /* ARMword temp,offset; */
417 fault_t fault;
418 fault = arm1176jzf_s_mmu_read (state, virt_addr, data, ARM_BYTE_TYPE);
419 return fault;
420}
421
422static fault_t
423arm1176jzf_s_mmu_read_halfword (ARMul_State *state, ARMword virt_addr,
424 ARMword *data)
425{
426 /* ARMword temp,offset; */
427 fault_t fault;
428 fault = arm1176jzf_s_mmu_read (state, virt_addr, data, ARM_HALFWORD_TYPE);
429 return fault;
430}
431
432static fault_t
433arm1176jzf_s_mmu_read_word (ARMul_State *state, ARMword virt_addr, ARMword *data)
434{
435 return arm1176jzf_s_mmu_read (state, virt_addr, data, ARM_WORD_TYPE);
436}
437
438static fault_t
439arm1176jzf_s_mmu_read (ARMul_State *state, ARMword va, ARMword *data,
440 ARMword datatype)
441{
442 fault_t fault;
443 ARMword pa, real_va, temp, offset;
444 ARMword perm; /* physical addr access permissions */
445 int ap, sop;
446
447 //DEBUG_LOG(ARM11, "va = %x\n", va);
448
449 va = mmu_pid_va_map (va);
450 real_va = va;
451 /* if MMU disabled, memory_read */
452 if (MMU_Disabled) {
453// printf("MMU disabled cpu_id:%x addr:%x.\n", state->mmu.process_id, va);
454// sleep(1);
455
456 /* *data = mem_read_word(state, va); */
457 if (datatype == ARM_BYTE_TYPE)
458 /* *data = mem_read_byte (state, va); */
459 if(state->space.conf_obj != NULL)
460 state->space.read(state->space.conf_obj, va, data, 1);
461 else
462 *data = Memory::Read8(va); //mem_read_raw(8, va, data);
463 else if (datatype == ARM_HALFWORD_TYPE)
464 /* *data = mem_read_halfword (state, va); */
465 if(state->space.conf_obj != NULL)
466 state->space.read(state->space.conf_obj, va, data, 2);
467 else
468 *data = Memory::Read16(va); //mem_read_raw(16, va, data);
469 else if (datatype == ARM_WORD_TYPE)
470 /* *data = mem_read_word (state, va); */
471 if(state->space.conf_obj != NULL)
472 state->space.read(state->space.conf_obj, va, data, 4);
473 else
474 *data = Memory::Read32(va); //mem_read_raw(32, va, data);
475 else {
476 ERROR_LOG(ARM11, "SKYEYE:1 arm1176jzf_s_mmu_read error: unknown data type %d\n", datatype);
477 }
478
479 return NO_FAULT;
480 }
481// printf("MMU enabled.\n");
482// sleep(1);
483
484 /* align check */
485 if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) ||
486 ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) {
487 DEBUG_LOG(ARM11, "align\n");
488 return ALIGNMENT_FAULT;
489 }
490
491 /* va &= ~(WORD_SIZE - 1); */
492 #if 0
493 uint32_t page_base;
494 page_base = get_phys_page(state, va);
495 if((page_base & 0xFFF) == 0){
496 pa = (page_base << 12) | (va & 0xFFF);
497 goto skip_translation;
498 }
499 #endif
500 /*translate va to tlb */
501#if 0
502 fault = mmu_translate (state, va, ARM920T_D_TLB (), &tlb);
503#endif
504 fault = mmu_translate (state, va, &pa, &ap, &sop);
505#if 0
506 if(va ==0xbebb1774 || state->Reg[15] == 0x400ff594){
507 //printf("In %s, current=0x%x. mode is %x, pc=0x%x\n", __FUNCTION__, state->CurrInstr, state->Mode, state->Reg[15]);
508 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);
509 int i;
510 for(i = 0; i < 16; i++)
511 printf("Reg[%d]=0x%x\t", i, state->Reg[i]);
512 printf("\n");
513 }
514#endif
515 if (fault) {
516 DEBUG_LOG(ARM11, "translate\n");
517 //printf("mmu read fault at %x\n", va);
518 //printf("fault is %d\n", fault);
519 return fault;
520 }
521// printf("va is %x pa is %x\n", va, pa);
522
523 /* no tlb, only check permission */
524 if (!check_perms(state, ap, 1)) {
525 if (sop == 0) {
526 return SECTION_PERMISSION_FAULT;
527 } else {
528 return SUBPAGE_PERMISSION_FAULT;
529 }
530 }
531#if 0
532 /*check access permission */
533 fault = check_access (state, va, tlb, 1);
534 if (fault)
535 return fault;
536#endif
537
538 //insert_tlb(state, va, pa);
539skip_translation:
540 /* *data = mem_read_word(state, pa); */
541 if (datatype == ARM_BYTE_TYPE) {
542 /* *data = mem_read_byte (state, pa | (real_va & 3)); */
543 if(state->space.conf_obj != NULL)
544 state->space.read(state->space.conf_obj, pa | (real_va & 3), data, 1);
545 else
546 *data = Memory::Read8(pa | (real_va & 3)); //mem_read_raw(8, pa | (real_va & 3), data);
547 /* mem_read_raw(32, pa | (real_va & 3), data); */
548 } else if (datatype == ARM_HALFWORD_TYPE) {
549 /* *data = mem_read_halfword (state, pa | (real_va & 2)); */
550 if(state->space.conf_obj != NULL)
551 state->space.read(state->space.conf_obj, pa | (real_va & 3), data, 2);
552 else
553 *data = Memory::Read16(pa | (real_va & 3)); //mem_read_raw(16, pa | (real_va & 3), data);
554 /* mem_read_raw(32, pa | (real_va & 2), data); */
555 } else if (datatype == ARM_WORD_TYPE)
556 /* *data = mem_read_word (state, pa); */
557 if(state->space.conf_obj != NULL)
558 state->space.read(state->space.conf_obj, pa , data, 4);
559 else
560 *data = Memory::Read32(pa); //mem_read_raw(32, pa, data);
561 else {
562 ERROR_LOG(ARM11, "SKYEYE:2 arm1176jzf_s_mmu_read error: unknown data type %d\n", datatype);
563 }
564 if(0 && (va == 0x2869c)){
565 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);
566 }
567
568 /* ldrex or ldrexb */
569 if(((state->CurrInstr & 0x0FF000F0) == 0x01900090) ||
570 ((state->CurrInstr & 0x0FF000F0) == 0x01d00090)){
571 int rn = (state->CurrInstr & 0xF0000) >> 16;
572 if(state->Reg[rn] == va){
573 add_exclusive_addr(state, pa | (real_va & 3));
574 state->exclusive_access_state = 1;
575 }
576 }
577#if 0
578 if (state->pc == 0xc011a868) {
579 printf("pa is %x value is %x size is %x\n", pa, data, datatype);
580 printf("icounter is %lld\n", state->NumInstrs);
581// exit(-1);
582 }
583#endif
584
585 return NO_FAULT;
586}
587
588
589static fault_t
590arm1176jzf_s_mmu_write_byte (ARMul_State *state, ARMword virt_addr, ARMword data)
591{
592 return arm1176jzf_s_mmu_write (state, virt_addr, data, ARM_BYTE_TYPE);
593}
594
595static fault_t
596arm1176jzf_s_mmu_write_halfword (ARMul_State *state, ARMword virt_addr,
597 ARMword data)
598{
599 return arm1176jzf_s_mmu_write (state, virt_addr, data, ARM_HALFWORD_TYPE);
600}
601
602static fault_t
603arm1176jzf_s_mmu_write_word (ARMul_State *state, ARMword virt_addr, ARMword data)
604{
605 return arm1176jzf_s_mmu_write (state, virt_addr, data, ARM_WORD_TYPE);
606}
607
608
609
610static fault_t
611arm1176jzf_s_mmu_write (ARMul_State *state, ARMword va, ARMword data,
612 ARMword datatype)
613{
614 int b;
615 ARMword pa, real_va;
616 ARMword perm; /* physical addr access permissions */
617 fault_t fault;
618 int ap, sop;
619
620#if 0
621 /8 for sky_printk debugger.*/
622 if (va == 0xffffffff) {
623 putchar((char)data);
624 return 0;
625 }
626 if (va == 0xBfffffff) {
627 putchar((char)data);
628 return 0;
629 }
630#endif
631
632 //DEBUG_LOG(ARM11, "va = %x, val = %x\n", va, data);
633 va = mmu_pid_va_map (va);
634 real_va = va;
635
636 if (MMU_Disabled) {
637 /* mem_write_word(state, va, data); */
638 if (datatype == ARM_BYTE_TYPE)
639 /* mem_write_byte (state, va, data); */
640 if(state->space.conf_obj != NULL)
641 state->space.write(state->space.conf_obj, va, &data, 1);
642 else
643 Memory::Write8(va, data);
644 else if (datatype == ARM_HALFWORD_TYPE)
645 /* mem_write_halfword (state, va, data); */
646 if(state->space.conf_obj != NULL)
647 state->space.write(state->space.conf_obj, va, &data, 2);
648 else
649 Memory::Write16(va, data);
650 else if (datatype == ARM_WORD_TYPE)
651 /* mem_write_word (state, va, data); */
652 if(state->space.conf_obj != NULL)
653 state->space.write(state->space.conf_obj, va, &data, 4);
654 else
655 Memory::Write32(va, data);
656 else {
657 ERROR_LOG (ARM11, "SKYEYE:1 arm1176jzf_s_mmu_write error: unknown data type %d\n", datatype);
658 }
659 goto finished_write;
660 //return 0;
661 }
662 /*align check */
663 /* if ((va & (WORD_SIZE - 1)) && MMU_Aligned){ */
664 if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) ||
665 ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) {
666 DEBUG_LOG(ARM11, "align\n");
667 return ALIGNMENT_FAULT;
668 }
669 va &= ~(WORD_SIZE - 1);
670 #if 0
671 uint32_t page_base;
672 page_base = get_phys_page(state, va);
673 if((page_base & 0xFFF) == 0){
674 pa = (page_base << 12) | (va & 0xFFF);
675 goto skip_translation;
676 }
677 #endif
678 /*tlb translate */
679 fault = mmu_translate (state, va, &pa, &ap, &sop);
680#if 0
681 if(va ==0xbebb1774 || state->Reg[15] == 0x40102334){
682 //printf("In %s, current=0x%x. mode is %x, pc=0x%x\n", __FUNCTION__, state->CurrInstr, state->Mode, state->Reg[15]);
683 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);
684 int i;
685 for(i = 0; i < 16; i++)
686 printf("Reg[%d]=0x%x\t", i, state->Reg[i]);
687 printf("\n");
688 }
689#endif
690 if (fault) {
691 DEBUG_LOG(ARM11, "translate\n");
692 //printf("mmu write fault at %x\n", va);
693 return fault;
694 }
695// printf("va is %x pa is %x\n", va, pa);
696
697 /* no tlb, only check permission */
698 if (!check_perms(state, ap, 0)) {
699 if (sop == 0) {
700 return SECTION_PERMISSION_FAULT;
701 } else {
702 return SUBPAGE_PERMISSION_FAULT;
703 }
704 }
705
706#if 0
707 /* tlb check access */
708 fault = check_access (state, va, tlb, 0);
709 if (fault) {
710 DEBUG_LOG(ARM11, "check_access\n");
711 return fault;
712 }
713#endif
714#if 0
715 if (pa <= 0x502860ff && (pa + 1 << datatype) > 0x502860ff) {
716 printf("pa is %x value is %x size is %x\n", pa, data, datatype);
717 }
718#endif
719#if 0
720 if (state->pc == 0xc011a878) {
721 printf("write pa is %x value is %x size is %x\n", pa, data, datatype);
722 printf("icounter is %lld\n", state->NumInstrs);
723 exit(-1);
724 }
725#endif
726 //insert_tlb(state, va, pa);
727skip_translation:
728 /* strex */
729 if(((state->CurrInstr & 0x0FF000F0) == 0x01800090) ||
730 ((state->CurrInstr & 0x0FF000F0) == 0x01c00090)){
731 /* failed , the address is monitord now. */
732 int dest_reg = (state->CurrInstr & 0xF000) >> 12;
733 if((exclusive_detect(state, pa | (real_va & 3)) == 0) && (state->exclusive_access_state == 1)){
734 remove_exclusive(state, pa | (real_va & 3));
735 state->Reg[dest_reg] = 0;
736 state->exclusive_access_state = 0;
737 }
738 else{
739 state->Reg[dest_reg] = 1;
740 //printf("In %s, try to strex a monitored address 0x%x\n", __FUNCTION__, pa);
741 return NO_FAULT;
742 }
743 }
744
745 if (datatype == ARM_BYTE_TYPE) {
746 /* mem_write_byte (state,
747 (pa | (real_va & 3)),
748 data);
749 */
750 if(state->space.conf_obj != NULL)
751 state->space.write(state->space.conf_obj, (pa | (real_va & 3)), &data, 1);
752 else
753 Memory::Write8((pa | (real_va & 3)), data);
754
755 } else if (datatype == ARM_HALFWORD_TYPE)
756 /* mem_write_halfword (state,
757 (pa |
758 (real_va & 2)),
759 data);
760 */
761 if(state->space.conf_obj != NULL)
762 state->space.write(state->space.conf_obj, (pa | (real_va & 3)), &data, 2);
763 else
764 Memory::Write16((pa | (real_va & 3)), data);
765 else if (datatype == ARM_WORD_TYPE)
766 /* mem_write_word (state, pa, data); */
767 if(state->space.conf_obj != NULL)
768 state->space.write(state->space.conf_obj, pa, &data, 4);
769 else
770 Memory::Write32(pa, data);
771#if 0
772 if (state->NumInstrs > 236403) {
773 printf("write memory\n");
774 printf("pa is %x value is %x size is %x\n", pa, data, datatype);
775 printf("icounter is %lld\n", state->NumInstrs);
776 }
777#endif
778finished_write:
779#if DIFF_WRITE
780 if(state->icounter > state->debug_icounter){
781 if(state->CurrWrite >= 17 ){
782 printf("Wrong write array, 0x%x", state->CurrWrite);
783 exit(-1);
784 }
785 uint32 record_data = data;
786 if(datatype == ARM_BYTE_TYPE)
787 record_data &= 0xFF;
788 if(datatype == ARM_HALFWORD_TYPE)
789 record_data &= 0xFFFF;
790
791 state->WriteAddr[state->CurrWrite] = pa | (real_va & 3);
792 state->WriteData[state->CurrWrite] = record_data;
793 state->WritePc[state->CurrWrite] = state->Reg[15];
794 state->CurrWrite++;
795 //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);
796 }
797#endif
798
799 return NO_FAULT;
800}
801
802ARMword
803arm1176jzf_s_mmu_mrc (ARMul_State *state, ARMword instr, ARMword *value)
804{
805 int creg = BITS (16, 19) & 0xf;
806 int OPC_1 = BITS (21, 23) & 0x7;
807 int OPC_2 = BITS (5, 7) & 0x7;
808 ARMword data;
809
810 switch (creg) {
811 case MMU_ID:
812 if (OPC_2 == 0) {
813 data = state->cpu->cpu_val;
814 } else if (OPC_2 == 1) {
815 /* Cache type:
816 * 000 0110 1 000 101 110 0 10 000 101 110 0 10
817 * */
818 data = 0x0D172172;
819 }
820 break;
821 case MMU_CONTROL:
822 /*
823 * 6:3 read as 1
824 * 10 read as 0
825 * 18,16 read as 1
826 * */
827 data = (state->mmu.control | 0x50078) & 0xFFFFFBFF;
828 break;
829 case MMU_TRANSLATION_TABLE_BASE:
830#if 0
831 data = state->mmu.translation_table_base;
832#endif
833 switch (OPC_2) {
834 case 0:
835 data = state->mmu.translation_table_base0;
836 break;
837 case 1:
838 data = state->mmu.translation_table_base1;
839 break;
840 case 2:
841 data = state->mmu.translation_table_ctrl;
842 break;
843 default:
844 printf ("mmu_mrc read UNKNOWN - p15 c2 opcode2 %d\n", OPC_2);
845 break;
846 }
847 break;
848 case MMU_DOMAIN_ACCESS_CONTROL:
849 data = state->mmu.domain_access_control;
850 break;
851 case MMU_FAULT_STATUS:
852 /* OPC_2 = 0: data FSR value
853 * */
854 if (OPC_2 == 0)
855 data = state->mmu.fault_status;
856 if (OPC_2 == 1)
857 data = state->mmu.fault_statusi;
858 break;
859 case MMU_FAULT_ADDRESS:
860 data = state->mmu.fault_address;
861 break;
862 case MMU_PID:
863 //data = state->mmu.process_id;
864 if(OPC_2 == 0)
865 data = state->mmu.process_id;
866 else if(OPC_2 == 1)
867 data = state->mmu.context_id;
868 else if(OPC_2 == 3){
869 data = state->mmu.thread_uro_id;
870 }
871 else{
872 printf ("mmu_mcr read UNKNOWN - reg %d\n", creg);
873 }
874 //printf("SKYEYE In %s, read pid 0x%x, OPC_2 %d, instr=0x%x\n", __FUNCTION__, data, OPC_2, instr);
875 //exit(-1);
876 break;
877 default:
878 printf ("mmu_mrc read UNKNOWN - reg %d\n", creg);
879 data = 0;
880 break;
881 }
882/* printf("\t\t\t\t\tpc = 0x%08x\n", state->Reg[15]); */
883 *value = data;
884 return data;
885}
886
887
888static ARMword
889arm1176jzf_s_mmu_mcr (ARMul_State *state, ARMword instr, ARMword value)
890{
891 int creg = BITS (16, 19) & 0xf;
892 int CRm = BITS (0, 3) & 0xf;
893 int OPC_1 = BITS (21, 23) & 0x7;
894 int OPC_2 = BITS (5, 7) & 0x7;
895 if (!strncmp (state->cpu->cpu_arch_name, "armv6", 5)) {
896 switch (creg) {
897 case MMU_CONTROL:
898 /*
899 * 6:3 read as 1
900 * 10 read as 0
901 * 18,16 read as 1
902 * */
903 if(OPC_2 == 0)
904 state->mmu.control = (value | 0x50078) & 0xFFFFFBFF;
905 else if(OPC_2 == 1)
906 state->mmu.auxiliary_control = value;
907 else if(OPC_2 == 2)
908 state->mmu.coprocessor_access_control = value;
909 else
910 fprintf(stderr, "In %s, wrong OPC_2 %d\n", __FUNCTION__, OPC_2);
911 break;
912 case MMU_TRANSLATION_TABLE_BASE:
913 switch (OPC_2) {
914 /* int i; */
915 case 0:
916#if 0
917 /* TTBR0 */
918 if (state->mmu.translation_table_ctrl & 0x7) {
919 for (i = 0; i <= state->mmu.translation_table_ctrl; i++)
920 state->mmu.translation_table_base0 &= ~(1 << (5 + i));
921 }
922#endif
923 state->mmu.translation_table_base0 = (value);
924 break;
925 case 1:
926#if 0
927 /* TTBR1 */
928 if (state->mmu.translation_table_ctrl & 0x7) {
929 for (i = 0; i <= state->mmu.translation_table_ctrl; i++)
930 state->mmu.translation_table_base1 &= 1 << (5 + i);
931 }
932#endif
933 state->mmu.translation_table_base1 = (value);
934 break;
935 case 2:
936 /* TTBC */
937 state->mmu.translation_table_ctrl = value & 0x7;
938 break;
939 default:
940 printf ("mmu_mcr wrote UNKNOWN - cp15 c2 opcode2 %d\n", OPC_2);
941 break;
942 }
943 //printf("SKYEYE In %s, write TLB_BASE 0x%x OPC_2=%d instr=0x%x\n", __FUNCTION__, value, OPC_2, instr);
944 //invalidate_all_tlb(state);
945 break;
946 case MMU_DOMAIN_ACCESS_CONTROL:
947 /* printf("mmu_mcr wrote DACR "); */
948 state->mmu.domain_access_control = value;
949 break;
950
951 case MMU_FAULT_STATUS:
952 if (OPC_2 == 0)
953 state->mmu.fault_status = value & 0xFF;
954 if (OPC_2 == 1) {
955 printf("set fault status instr\n");
956 }
957 break;
958 case MMU_FAULT_ADDRESS:
959 state->mmu.fault_address = value;
960 break;
961
962 case MMU_CACHE_OPS:
963 break;
964 case MMU_TLB_OPS:
965 {
966 switch(CRm){
967 case 5: /* ITLB */
968 {
969 switch(OPC_2){
970 case 0: /* invalidate all */
971 //invalidate_all_tlb(state);
972 break;
973 case 1: /* invalidate by MVA */
974 //invalidate_by_mva(state, value);
975 break;
976 case 2: /* invalidate by asid */
977 //invalidate_by_asid(state, value);
978 break;
979 default:
980 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg);
981 break;
982 }
983 break;
984 }
985 case 6: /* DTLB */
986 {
987 switch(OPC_2){
988 case 0: /* invalidate all */
989 //invalidate_all_tlb(state);
990 break;
991 case 1: /* invalidate by MVA */
992 //invalidate_by_mva(state, value);
993 break;
994 case 2: /* invalidate by asid */
995 //invalidate_by_asid(state, value);
996 break;
997 default:
998 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg);
999 break;
1000 }
1001 break;
1002 }
1003 case 7: /* Unified TLB */
1004 {
1005 switch(OPC_2){
1006 case 0: /* invalidate all */
1007 //invalidate_all_tlb(state);
1008 break;
1009 case 1: /* invalidate by MVA */
1010 //invalidate_by_mva(state, value);
1011 break;
1012 case 2: /* invalidate by asid */
1013 //invalidate_by_asid(state, value);
1014 break;
1015 default:
1016 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg);
1017 break;
1018 }
1019 break;
1020 }
1021
1022 default:
1023 printf ("mmu_mcr wrote UNKNOWN - reg %d, CRm=%d\n", creg, CRm);
1024 break;
1025 }
1026 //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);
1027 }
1028 break;
1029 case MMU_CACHE_LOCKDOWN:
1030 /*
1031 * FIXME: cache lock down*/
1032 break;
1033 case MMU_TLB_LOCKDOWN:
1034 printf("SKYEYE In %s, write TLB_LOCKDOWN 0x%x OPC_2=%d instr=0x%x\n", __FUNCTION__, value, OPC_2, instr);
1035 /* FIXME:tlb lock down */
1036 break;
1037 case MMU_PID:
1038 //printf("SKYEYE In %s, write pid 0x%x OPC_2=%d instr=0x%x\n", __FUNCTION__, value, OPC_2, instr);
1039 //state->mmu.process_id = value;
1040 /*0:24 should be zero. */
1041 //state->mmu.process_id = value & 0xfe000000;
1042 if(OPC_2 == 0)
1043 state->mmu.process_id = value;
1044 else if(OPC_2 == 1)
1045 state->mmu.context_id = value;
1046 else if(OPC_2 == 3){
1047 state->mmu.thread_uro_id = value;
1048 }
1049 else{
1050 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg);
1051 }
1052 break;
1053
1054 default:
1055 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg);
1056 break;
1057 }
1058 }
1059
1060 return No_exp;
1061}
1062
1063///* teawater add for arm2x86 2005.06.19------------------------------------------- */
1064//static int
1065//arm1176jzf_s_mmu_v2p_dbct (ARMul_State *state, ARMword virt_addr,
1066// ARMword *phys_addr)
1067//{
1068// fault_t fault;
1069// int ap, sop;
1070//
1071// ARMword perm; /* physical addr access permissions */
1072// virt_addr = mmu_pid_va_map (virt_addr);
1073// if (MMU_Enabled) {
1074//
1075// /*align check */
1076// if ((virt_addr & (WORD_SIZE - 1)) && MMU_Aligned) {
1077// DEBUG_LOG(ARM11, "align\n");
1078// return ALIGNMENT_FAULT;
1079// } else
1080// virt_addr &= ~(WORD_SIZE - 1);
1081//
1082// /*translate tlb */
1083// fault = mmu_translate (state, virt_addr, phys_addr, &ap, &sop);
1084// if (fault) {
1085// DEBUG_LOG(ARM11, "translate\n");
1086// return fault;
1087// }
1088//
1089// /* permission check */
1090// if (!check_perms(state, ap, 1)) {
1091// if (sop == 0) {
1092// return SECTION_PERMISSION_FAULT;
1093// } else {
1094// return SUBPAGE_PERMISSION_FAULT;
1095// }
1096// }
1097//#if 0
1098// /*check access */
1099// fault = check_access (state, virt_addr, tlb, 1);
1100// if (fault) {
1101// DEBUG_LOG(ARM11, "check_fault\n");
1102// return fault;
1103// }
1104//#endif
1105// }
1106//
1107// if (MMU_Disabled) {
1108// *phys_addr = virt_addr;
1109// }
1110//
1111// return 0;
1112//}
1113
1114/* AJ2D-------------------------------------------------------------------------- */
1115
1116/*arm1176jzf-s mmu_ops_t*/
1117mmu_ops_t arm1176jzf_s_mmu_ops = {
1118 arm1176jzf_s_mmu_init,
1119 arm1176jzf_s_mmu_exit,
1120 arm1176jzf_s_mmu_read_byte,
1121 arm1176jzf_s_mmu_write_byte,
1122 arm1176jzf_s_mmu_read_halfword,
1123 arm1176jzf_s_mmu_write_halfword,
1124 arm1176jzf_s_mmu_read_word,
1125 arm1176jzf_s_mmu_write_word,
1126 arm1176jzf_s_mmu_load_instr,
1127 arm1176jzf_s_mmu_mcr,
1128 arm1176jzf_s_mmu_mrc
1129/* teawater add for arm2x86 2005.06.19------------------------------------------- */
1130/* arm1176jzf_s_mmu_v2p_dbct, */
1131/* AJ2D-------------------------------------------------------------------------- */
1132};
diff --git a/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.h b/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.h
deleted file mode 100644
index 299c6b46b..000000000
--- a/src/core/arm/interpreter/mmu/arm1176jzf_s_mmu.h
+++ /dev/null
@@ -1,37 +0,0 @@
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/arm/interpreter/mmu/cache.cpp b/src/core/arm/interpreter/mmu/cache.cpp
deleted file mode 100644
index f3c4e0531..000000000
--- a/src/core/arm/interpreter/mmu/cache.cpp
+++ /dev/null
@@ -1,370 +0,0 @@
1#include "core/arm/interpreter/armdefs.h"
2
3/* mmu cache init
4 *
5 * @cache_t :cache_t to init
6 * @width :cache line width in byte
7 * @way :way of each cache set
8 * @set :cache set num
9 *
10 * $ -1: error
11 * 0: sucess
12 */
13int
14mmu_cache_init (cache_s * cache_t, int width, int way, int set, int w_mode)
15{
16 int i, j;
17 cache_set_t *sets;
18 cache_line_t *lines;
19
20 /*alloc cache set */
21 sets = NULL;
22 lines = NULL;
23 //fprintf(stderr, "mmu_cache_init: mallloc beg size %d,sets 0x%x\n", sizeof(cache_set_t) * set,sets);
24 //exit(-1);
25 sets = (cache_set_t *) malloc (sizeof (cache_set_t) * set);
26 if (sets == NULL) {
27 ERROR_LOG(ARM11, "set malloc size %d\n", sizeof (cache_set_t) * set);
28 goto sets_error;
29 }
30 //fprintf(stderr, "mmu_cache_init: mallloc end sets 0x%x\n", sets);
31 cache_t->sets = sets;
32
33 /*init cache set */
34 for (i = 0; i < set; i++) {
35 /*alloc cache line */
36 lines = (cache_line_t *) malloc (sizeof (cache_line_t) * way);
37 if (lines == NULL) {
38 ERROR_LOG(ARM11, "line malloc size %d\n",
39 sizeof (cache_line_t) * way);
40 goto lines_error;
41 }
42 /*init cache line */
43 for (j = 0; j < way; j++) {
44 lines[j].tag = 0; //invalid
45 lines[j].data = (ARMword *) malloc (width);
46 if (lines[j].data == NULL) {
47 ERROR_LOG(ARM11, "data alloc size %d\n", width);
48 goto data_error;
49 }
50 }
51
52 sets[i].lines = lines;
53 sets[i].cycle = 0;
54
55 }
56 cache_t->width = width;
57 cache_t->set = set;
58 cache_t->way = way;
59 cache_t->w_mode = w_mode;
60 return 0;
61
62 data_error:
63 /*free data */
64 while (j-- > 0)
65 free (lines[j].data);
66 /*free data error line */
67 free (lines);
68 lines_error:
69 /*free lines already alloced */
70 while (i-- > 0) {
71 for (j = 0; j < way; j++)
72 free (sets[i].lines[j].data);
73 free (sets[i].lines);
74 }
75 /*free sets */
76 free (sets);
77 sets_error:
78 return -1;
79};
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 */
88
89void
90mmu_cache_exit (cache_s * cache_t)
91{
92 int i, j;
93 cache_set_t *sets, *set;
94 cache_line_t *lines, *line;
95
96 /*free all set */
97 sets = cache_t->sets;
98 for (set = sets, i = 0; i < cache_t->set; i++, set++) {
99 /*free all line */
100 lines = set->lines;
101 for (line = lines, j = 0; j < cache_t->way; j++, line++)
102 free (line->data);
103 free (lines);
104 }
105 free (sets);
106}
107
108/* mmu cache search
109 *
110 * @state :ARMul_State
111 * @cache_t :cache_t to search
112 * @va :virtual address
113 *
114 * $ NULL: no cache match
115 * cache :cache matched
116 */
117cache_line_t *
118mmu_cache_search (ARMul_State * state, cache_s * cache_t, ARMword va)
119{
120 int i;
121 int set = va_cache_set (va, cache_t);
122 ARMword tag = va_cache_align (va, cache_t);
123 cache_line_t *cache;
124
125 cache_set_t *cache_set = cache_t->sets + set;
126 for (i = 0, cache = cache_set->lines; i < cache_t->way; i++, cache++) {
127 if ((cache->tag & TAG_VALID_FLAG)
128 && (tag == va_cache_align (cache->tag, cache_t)))
129 return cache;
130 }
131 return NULL;
132}
133
134/* mmu cache search by set/index
135 *
136 * @state :ARMul_State
137 * @cache_t :cache_t to search
138 * @index :set/index value.
139 *
140 * $ NULL: no cache match
141 * cache :cache matched
142 */
143cache_line_t *
144mmu_cache_search_by_index (ARMul_State * state, cache_s * cache_t,
145 ARMword index)
146{
147 int way = cache_t->way;
148 int set_v = index_cache_set (index, cache_t);
149 int i = 0, index_v = 0;
150 cache_set_t *set;
151
152 while ((way >>= 1) >= 1)
153 i++;
154 index_v = index >> (32 - i);
155 set = cache_t->sets + set_v;
156
157 return set->lines + index_v;
158}
159
160
161/* mmu cache alloc
162 *
163 * @state :ARMul_State
164 * @cache_t :cache_t to alloc from
165 * @va :virtual address that require cache alloc, need not cache aligned
166 * @pa :physical address of va
167 *
168 * $ cache_alloced, always alloc OK
169 */
170cache_line_t *
171mmu_cache_alloc (ARMul_State * state, cache_s * cache_t, ARMword va,
172 ARMword pa)
173{
174 cache_line_t *cache;
175 cache_set_t *set;
176 int i;
177
178 va = va_cache_align (va, cache_t);
179 pa = va_cache_align (pa, cache_t);
180
181 set = &cache_t->sets[va_cache_set (va, cache_t)];
182
183 /*robin-round */
184 cache = &set->lines[set->cycle++];
185 if (set->cycle == cache_t->way)
186 set->cycle = 0;
187
188 if (cache_t->w_mode == CACHE_WRITE_BACK) {
189 ARMword t;
190
191 /*if cache valid, try to write back */
192 if (cache->tag & TAG_VALID_FLAG) {
193 mmu_cache_write_back (state, cache_t, cache);
194 }
195 /*read in cache_line */
196 t = pa;
197 for (i = 0; i < (cache_t->width >> WORD_SHT);
198 i++, t += WORD_SIZE) {
199 //cache->data[i] = mem_read_word (state, t);
200 bus_read(32, t, &cache->data[i]);
201 }
202 }
203 /*store tag and pa */
204 cache->tag = va | TAG_VALID_FLAG;
205 cache->pa = pa;
206
207 return cache;
208};
209
210/* mmu_cache_write_back write cache data to memory
211 * @state
212 * @cache_t :cache_t of the cache line
213 * @cache : cache line
214 */
215void
216mmu_cache_write_back (ARMul_State * state, cache_s * cache_t,
217 cache_line_t * cache)
218{
219 ARMword pa = cache->pa;
220 int nw = cache_t->width >> WORD_SHT;
221 ARMword *data = cache->data;
222 int i;
223 int t0, t1, t2;
224
225 if ((cache->tag & 1) == 0)
226 return;
227
228 switch (cache->
229 tag & ~1 & (TAG_FIRST_HALF_DIRTY | TAG_LAST_HALF_DIRTY)) {
230 case 0:
231 return;
232 case TAG_FIRST_HALF_DIRTY:
233 nw /= 2;
234 break;
235 case TAG_LAST_HALF_DIRTY:
236 nw /= 2;
237 pa += nw << WORD_SHT;
238 data += nw;
239 break;
240 case TAG_FIRST_HALF_DIRTY | TAG_LAST_HALF_DIRTY:
241 break;
242 }
243 for (i = 0; i < nw; i++, data++, pa += WORD_SIZE)
244 //mem_write_word (state, pa, *data);
245 bus_write(32, pa, *data);
246
247 cache->tag &= ~(TAG_FIRST_HALF_DIRTY | TAG_LAST_HALF_DIRTY);
248};
249
250
251/* mmu_cache_clean: clean a cache of va in cache_t
252 *
253 * @state :ARMul_State
254 * @cache_t :cache_t to clean
255 * @va :virtaul address
256 */
257void
258mmu_cache_clean (ARMul_State * state, cache_s * cache_t, ARMword va)
259{
260 cache_line_t *cache;
261
262 cache = mmu_cache_search (state, cache_t, va);
263 if (cache)
264 mmu_cache_write_back (state, cache_t, cache);
265}
266
267/* mmu_cache_clean_by_index: clean a cache by set/index format value
268 *
269 * @state :ARMul_State
270 * @cache_t :cache_t to clean
271 * @va :set/index format value
272 */
273void
274mmu_cache_clean_by_index (ARMul_State * state, cache_s * cache_t,
275 ARMword index)
276{
277 cache_line_t *cache;
278
279 cache = mmu_cache_search_by_index (state, cache_t, index);
280 if (cache)
281 mmu_cache_write_back (state, cache_t, cache);
282}
283
284/* mmu_cache_invalidate : invalidate a cache of va
285 *
286 * @state :ARMul_State
287 * @cache_t :cache_t to invalid
288 * @va :virt_addr to invalid
289 */
290void
291mmu_cache_invalidate (ARMul_State * state, cache_s * cache_t, ARMword va)
292{
293 cache_line_t *cache;
294
295 cache = mmu_cache_search (state, cache_t, va);
296 if (cache) {
297 mmu_cache_write_back (state, cache_t, cache);
298 cache->tag = 0;
299 }
300}
301
302/* mmu_cache_invalidate_by_index : invalidate a cache by index format
303 *
304 * @state :ARMul_State
305 * @cache_t :cache_t to invalid
306 * @index :set/index data
307 */
308void
309mmu_cache_invalidate_by_index (ARMul_State * state, cache_s * cache_t,
310 ARMword index)
311{
312 cache_line_t *cache;
313
314 cache = mmu_cache_search_by_index (state, cache_t, index);
315 if (cache) {
316 mmu_cache_write_back (state, cache_t, cache);
317 cache->tag = 0;
318 }
319}
320
321/* mmu_cache_invalidate_all
322 *
323 * @state:
324 * @cache_t
325 * */
326void
327mmu_cache_invalidate_all (ARMul_State * state, cache_s * cache_t)
328{
329 int i, j;
330 cache_set_t *set;
331 cache_line_t *cache;
332
333 set = cache_t->sets;
334 for (i = 0; i < cache_t->set; i++, set++) {
335 cache = set->lines;
336 for (j = 0; j < cache_t->way; j++, cache++) {
337 mmu_cache_write_back (state, cache_t, cache);
338 cache->tag = 0;
339 }
340 }
341};
342
343void
344mmu_cache_soft_flush (ARMul_State * state, cache_s * cache_t, ARMword pa)
345{
346 ARMword set, way;
347 cache_line_t *cache;
348 pa = (pa / cache_t->width);
349 way = pa & (cache_t->way - 1);
350 set = (pa / cache_t->way) & (cache_t->set - 1);
351 cache = &cache_t->sets[set].lines[way];
352
353 mmu_cache_write_back (state, cache_t, cache);
354 cache->tag = 0;
355}
356
357cache_line_t* mmu_cache_dirty_cache(ARMul_State *state,cache_s *cache){
358 int i;
359 int j;
360 cache_line_t *cache_line = NULL;
361 cache_set_t *cache_set = cache->sets;
362 int sets = cache->set;
363 for (i = 0; i < sets; i++){
364 for(j = 0,cache_line = &cache_set[i].lines[0]; j < cache->way; j++,cache_line++){
365 if((cache_line->tag & TAG_FIRST_HALF_DIRTY) || (cache_line->tag & TAG_LAST_HALF_DIRTY))
366 return cache_line;
367 }
368 }
369 return NULL;
370}
diff --git a/src/core/arm/interpreter/mmu/cache.h b/src/core/arm/interpreter/mmu/cache.h
deleted file mode 100644
index d308d9b87..000000000
--- a/src/core/arm/interpreter/mmu/cache.h
+++ /dev/null
@@ -1,168 +0,0 @@
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/arm/interpreter/mmu/maverick.cpp b/src/core/arm/interpreter/mmu/maverick.cpp
deleted file mode 100644
index adcc2efb5..000000000
--- a/src/core/arm/interpreter/mmu/maverick.cpp
+++ /dev/null
@@ -1,1206 +0,0 @@
1/* maverick.c -- Cirrus/DSP co-processor interface.
2 Copyright (C) 2003 Free Software Foundation, Inc.
3 Contributed by Aldy Hernandez (aldyh@redhat.com).
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19#include <assert.h>
20
21#include "core/arm/interpreter/armdefs.h"
22#include "core/arm/interpreter/armemu.h"
23
24
25/*#define CIRRUS_DEBUG 1 */
26#if CIRRUS_DEBUG
27# define printfdbg printf
28#else
29# define printfdbg printf_nothing
30#endif
31
32#define POS64(i) ( (~(i)) >> 63 )
33#define NEG64(i) ( (i) >> 63 )
34
35/* Define Co-Processor instruction handlers here. */
36
37/* Here's ARMulator's DSP definition. A few things to note:
38 1) it has 16 64-bit registers and 4 72-bit accumulators
39 2) you can only access its registers with MCR and MRC. */
40
41/* We can't define these in here because this file might not be linked
42 unless the target is arm9e-*. They are defined in wrapper.c.
43 Eventually the simulator should be made to handle any coprocessor
44 at run time. */
45struct maverick_regs
46{
47 union
48 {
49 int i;
50 float f;
51 } upper;
52
53 union
54 {
55 int i;
56 float f;
57 } lower;
58};
59
60union maverick_acc_regs
61{
62 long double ld; /* Acc registers are 72-bits. */
63};
64
65struct maverick_regs DSPregs[16];
66union maverick_acc_regs DSPacc[4];
67ARMword DSPsc;
68
69#define DEST_REG (BITS (12, 15))
70#define SRC1_REG (BITS (16, 19))
71#define SRC2_REG (BITS (0, 3))
72
73static int lsw_int_index, msw_int_index;
74static int lsw_float_index, msw_float_index;
75
76static double mv_getRegDouble (int);
77static long long mv_getReg64int (int);
78static void mv_setRegDouble (int, double val);
79static void mv_setReg64int (int, long long val);
80
81static union
82{
83 double d;
84 long long ll;
85 int ints[2];
86} reg_conv;
87
88static void
89printf_nothing (const char *foo, ...)
90{
91}
92
93static void
94cirrus_not_implemented (const char *insn)
95{
96 fprintf (stderr, "Cirrus instruction '%s' not implemented.\n", insn);
97 fprintf (stderr, "aborting!\n");
98
99 // skyeye_exit (1);
100}
101
102static unsigned
103DSPInit (ARMul_State * state)
104{
105 NOTICE_LOG(ARM11, "ARMul_ConsolePrint: DSP present");
106 return TRUE;
107}
108
109unsigned
110DSPMRC4 (ARMul_State * state,
111 unsigned type, ARMword instr, ARMword * value)
112{
113 switch (BITS (5, 7)) {
114 case 0: /* cfmvrdl */
115 /* Move lower half of a DF stored in a DSP reg into an Arm reg. */
116 printfdbg ("cfmvrdl\n");
117 printfdbg ("\tlower half=0x%x\n", DSPregs[SRC1_REG].lower.i);
118 printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG));
119
120 *value = (ARMword) DSPregs[SRC1_REG].lower.i;
121 break;
122
123 case 1: /* cfmvrdh */
124 /* Move upper half of a DF stored in a DSP reg into an Arm reg. */
125 printfdbg ("cfmvrdh\n");
126 printfdbg ("\tupper half=0x%x\n", DSPregs[SRC1_REG].upper.i);
127 printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG));
128
129 *value = (ARMword) DSPregs[SRC1_REG].upper.i;
130 break;
131
132 case 2: /* cfmvrs */
133 /* Move SF from upper half of a DSP register to an Arm register. */
134 *value = (ARMword) DSPregs[SRC1_REG].upper.i;
135 printfdbg ("cfmvrs = mvf%d <-- %f\n",
136 SRC1_REG, DSPregs[SRC1_REG].upper.f);
137 break;
138
139#ifdef doesnt_work
140 case 4: /* cfcmps */
141 {
142 float a, b;
143 int n, z, c, v;
144
145 a = DSPregs[SRC1_REG].upper.f;
146 b = DSPregs[SRC2_REG].upper.f;
147
148 printfdbg ("cfcmps\n");
149 printfdbg ("\tcomparing %f and %f\n", a, b);
150
151 z = a == b; /* zero */
152 n = a != b; /* negative */
153 v = a > b; /* overflow */
154 c = 0; /* carry */
155 *value = (n << 31) | (z << 30) | (c << 29) | (v <<
156 28);
157 break;
158 }
159
160 case 5: /* cfcmpd */
161 {
162 double a, b;
163 int n, z, c, v;
164
165 a = mv_getRegDouble (SRC1_REG);
166 b = mv_getRegDouble (SRC2_REG);
167
168 printfdbg ("cfcmpd\n");
169 printfdbg ("\tcomparing %g and %g\n", a, b);
170
171 z = a == b; /* zero */
172 n = a != b; /* negative */
173 v = a > b; /* overflow */
174 c = 0; /* carry */
175 *value = (n << 31) | (z << 30) | (c << 29) | (v <<
176 28);
177 break;
178 }
179#else
180 case 4: /* cfcmps */
181 {
182 float a, b;
183 int n, z, c, v;
184
185 a = DSPregs[SRC1_REG].upper.f;
186 b = DSPregs[SRC2_REG].upper.f;
187
188 printfdbg ("cfcmps\n");
189 printfdbg ("\tcomparing %f and %f\n", a, b);
190
191 z = a == b; /* zero */
192 n = a < b; /* negative */
193 c = a > b; /* carry */
194 v = 0; /* fixme */
195 printfdbg ("\tz = %d, n = %d\n", z, n);
196 *value = (n << 31) | (z << 30) | (c << 29) | (v <<
197 28);
198 break;
199 }
200
201 case 5: /* cfcmpd */
202 {
203 double a, b;
204 int n, z, c, v;
205
206 a = mv_getRegDouble (SRC1_REG);
207 b = mv_getRegDouble (SRC2_REG);
208
209 printfdbg ("cfcmpd\n");
210 printfdbg ("\tcomparing %g and %g\n", a, b);
211
212 z = a == b; /* zero */
213 n = a < b; /* negative */
214 c = a > b; /* carry */
215 v = 0; /* fixme */
216 *value = (n << 31) | (z << 30) | (c << 29) | (v <<
217 28);
218 break;
219 }
220#endif
221 default:
222 fprintf (stderr, "unknown opcode in DSPMRC4 0x%x\n", instr);
223 cirrus_not_implemented ("unknown");
224 break;
225 }
226
227 return ARMul_DONE;
228}
229
230unsigned
231DSPMRC5 (ARMul_State * state,
232 unsigned type, ARMword instr, ARMword * value)
233{
234 switch (BITS (5, 7)) {
235 case 0: /* cfmvr64l */
236 /* Move lower half of 64bit int from Cirrus to Arm. */
237 *value = (ARMword) DSPregs[SRC1_REG].lower.i;
238 printfdbg ("cfmvr64l ARM_REG = mvfx%d <-- %d\n",
239 DEST_REG, (int) *value);
240 break;
241
242 case 1: /* cfmvr64h */
243 /* Move upper half of 64bit int from Cirrus to Arm. */
244 *value = (ARMword) DSPregs[SRC1_REG].upper.i;
245 printfdbg ("cfmvr64h <-- %d\n", (int) *value);
246 break;
247
248 case 4: /* cfcmp32 */
249 {
250 int res;
251 int n, z, c, v;
252 unsigned int a, b;
253
254 printfdbg ("cfcmp32 mvfx%d - mvfx%d\n", SRC1_REG,
255 SRC2_REG);
256
257 /* FIXME: see comment for cfcmps. */
258 a = DSPregs[SRC1_REG].lower.i;
259 b = DSPregs[SRC2_REG].lower.i;
260
261 res = DSPregs[SRC1_REG].lower.i -
262 DSPregs[SRC2_REG].lower.i;
263 /* zero */
264 z = res == 0;
265 /* negative */
266 n = res < 0;
267 /* overflow */
268 v = SubOverflow (DSPregs[SRC1_REG].lower.i,
269 DSPregs[SRC2_REG].lower.i, res);
270 /* carry */
271 c = (NEG (a) && POS (b) ||
272 (NEG (a) && POS (res)) || (POS (b)
273 && POS (res)));
274
275 *value = (n << 31) | (z << 30) | (c << 29) | (v <<
276 28);
277 break;
278 }
279
280 case 5: /* cfcmp64 */
281 {
282 long long res;
283 int n, z, c, v;
284 unsigned long long a, b;
285
286 printfdbg ("cfcmp64 mvdx%d - mvdx%d\n", SRC1_REG,
287 SRC2_REG);
288
289 /* fixme: see comment for cfcmps. */
290
291 a = mv_getReg64int (SRC1_REG);
292 b = mv_getReg64int (SRC2_REG);
293
294 res = mv_getReg64int (SRC1_REG) -
295 mv_getReg64int (SRC2_REG);
296 /* zero */
297 z = res == 0;
298 /* negative */
299 n = res < 0;
300 /* overflow */
301 v = ((NEG64 (a) && POS64 (b) && POS64 (res))
302 || (POS64 (a) && NEG64 (b) && NEG64 (res)));
303 /* carry */
304 c = (NEG64 (a) && POS64 (b) ||
305 (NEG64 (a) && POS64 (res)) || (POS64 (b)
306 && POS64 (res)));
307
308 *value = (n << 31) | (z << 30) | (c << 29) | (v <<
309 28);
310 break;
311 }
312
313 default:
314 fprintf (stderr, "unknown opcode in DSPMRC5 0x%x\n", instr);
315 cirrus_not_implemented ("unknown");
316 break;
317 }
318
319 return ARMul_DONE;
320}
321
322unsigned
323DSPMRC6 (ARMul_State * state,
324 unsigned type, ARMword instr, ARMword * value)
325{
326 switch (BITS (5, 7)) {
327 case 0: /* cfmval32 */
328 cirrus_not_implemented ("cfmval32");
329 break;
330
331 case 1: /* cfmvam32 */
332 cirrus_not_implemented ("cfmvam32");
333 break;
334
335 case 2: /* cfmvah32 */
336 cirrus_not_implemented ("cfmvah32");
337 break;
338
339 case 3: /* cfmva32 */
340 cirrus_not_implemented ("cfmva32");
341 break;
342
343 case 4: /* cfmva64 */
344 cirrus_not_implemented ("cfmva64");
345 break;
346
347 case 5: /* cfmvsc32 */
348 cirrus_not_implemented ("cfmvsc32");
349 break;
350
351 default:
352 fprintf (stderr, "unknown opcode in DSPMRC6 0x%x\n", instr);
353 cirrus_not_implemented ("unknown");
354 break;
355 }
356
357 return ARMul_DONE;
358}
359
360unsigned
361DSPMCR4 (ARMul_State * state,
362 unsigned type, ARMword instr, ARMword value)
363{
364 switch (BITS (5, 7)) {
365 case 0: /* cfmvdlr */
366 /* Move the lower half of a DF value from an Arm register into
367 the lower half of a Cirrus register. */
368 printfdbg ("cfmvdlr <-- 0x%x\n", (int) value);
369 DSPregs[SRC1_REG].lower.i = (int) value;
370 break;
371
372 case 1: /* cfmvdhr */
373 /* Move the upper half of a DF value from an Arm register into
374 the upper half of a Cirrus register. */
375 printfdbg ("cfmvdhr <-- 0x%x\n", (int) value);
376 DSPregs[SRC1_REG].upper.i = (int) value;
377 break;
378
379 case 2: /* cfmvsr */
380 /* Move SF from Arm register into upper half of Cirrus register. */
381 printfdbg ("cfmvsr <-- 0x%x\n", (int) value);
382 DSPregs[SRC1_REG].upper.i = (int) value;
383 break;
384
385 default:
386 fprintf (stderr, "unknown opcode in DSPMCR4 0x%x\n", instr);
387 cirrus_not_implemented ("unknown");
388 break;
389 }
390
391 return ARMul_DONE;
392}
393
394unsigned
395DSPMCR5 (ARMul_State * state,
396 unsigned type, ARMword instr, ARMword value)
397{
398 union
399 {
400 int s;
401 unsigned int us;
402 } val;
403
404 switch (BITS (5, 7)) {
405 case 0: /* cfmv64lr */
406 /* Move lower half of a 64bit int from an ARM register into the
407 lower half of a DSP register and sign extend it. */
408 printfdbg ("cfmv64lr mvdx%d <-- 0x%x\n", SRC1_REG,
409 (int) value);
410 DSPregs[SRC1_REG].lower.i = (int) value;
411 break;
412
413 case 1: /* cfmv64hr */
414 /* Move upper half of a 64bit int from an ARM register into the
415 upper half of a DSP register. */
416 printfdbg ("cfmv64hr ARM_REG = mvfx%d <-- 0x%x\n",
417 SRC1_REG, (int) value);
418 DSPregs[SRC1_REG].upper.i = (int) value;
419 break;
420
421 case 2: /* cfrshl32 */
422 printfdbg ("cfrshl32\n");
423 val.us = value;
424 if (val.s > 0)
425 DSPregs[SRC2_REG].lower.i =
426 DSPregs[SRC1_REG].lower.i << value;
427 else
428 DSPregs[SRC2_REG].lower.i =
429 DSPregs[SRC1_REG].lower.i >> -value;
430 break;
431
432 case 3: /* cfrshl64 */
433 printfdbg ("cfrshl64\n");
434 val.us = value;
435 if (val.s > 0)
436 mv_setReg64int (SRC2_REG,
437 mv_getReg64int (SRC1_REG) << value);
438 else
439 mv_setReg64int (SRC2_REG,
440 mv_getReg64int (SRC1_REG) >> -value);
441 break;
442
443 default:
444 fprintf (stderr, "unknown opcode in DSPMCR5 0x%x\n", instr);
445 cirrus_not_implemented ("unknown");
446 break;
447 }
448
449 return ARMul_DONE;
450}
451
452unsigned
453DSPMCR6 (ARMul_State * state,
454 unsigned type, ARMword instr, ARMword value)
455{
456 switch (BITS (5, 7)) {
457 case 0: /* cfmv32al */
458 cirrus_not_implemented ("cfmv32al");
459 break;
460
461 case 1: /* cfmv32am */
462 cirrus_not_implemented ("cfmv32am");
463 break;
464
465 case 2: /* cfmv32ah */
466 cirrus_not_implemented ("cfmv32ah");
467 break;
468
469 case 3: /* cfmv32a */
470 cirrus_not_implemented ("cfmv32a");
471 break;
472
473 case 4: /* cfmv64a */
474 cirrus_not_implemented ("cfmv64a");
475 break;
476
477 case 5: /* cfmv32sc */
478 cirrus_not_implemented ("cfmv32sc");
479 break;
480
481 default:
482 fprintf (stderr, "unknown opcode in DSPMCR6 0x%x\n", instr);
483 cirrus_not_implemented ("unknown");
484 break;
485 }
486
487 return ARMul_DONE;
488}
489
490unsigned
491DSPLDC4 (ARMul_State * state,
492 unsigned type, ARMword instr, ARMword data)
493{
494 static unsigned words;
495
496 if (type != ARMul_DATA) {
497 words = 0;
498 return ARMul_DONE;
499 }
500
501 if (BIT (22)) { /* it's a long access, get two words */
502 /* cfldrd */
503
504 printfdbg
505 ("cfldrd: %x (words = %d) (bigend = %d) DESTREG = %d\n",
506 data, words, state->bigendSig, DEST_REG);
507
508 if (words == 0) {
509 if (state->bigendSig)
510 DSPregs[DEST_REG].upper.i = (int) data;
511 else
512 DSPregs[DEST_REG].lower.i = (int) data;
513 }
514 else {
515 if (state->bigendSig)
516 DSPregs[DEST_REG].lower.i = (int) data;
517 else
518 DSPregs[DEST_REG].upper.i = (int) data;
519 }
520
521 ++words;
522
523 if (words == 2) {
524 printfdbg ("\tmvd%d <-- mem = %g\n", DEST_REG,
525 mv_getRegDouble (DEST_REG));
526
527 return ARMul_DONE;
528 }
529 else
530 return ARMul_INC;
531 }
532 else {
533 /* Get just one word. */
534
535 /* cfldrs */
536 printfdbg ("cfldrs\n");
537
538 DSPregs[DEST_REG].upper.i = (int) data;
539
540 printfdbg ("\tmvf%d <-- mem = %f\n", DEST_REG,
541 DSPregs[DEST_REG].upper.f);
542
543 return ARMul_DONE;
544 }
545}
546
547unsigned
548DSPLDC5 (ARMul_State * state,
549 unsigned type, ARMword instr, ARMword data)
550{
551 static unsigned words;
552
553 if (type != ARMul_DATA) {
554 words = 0;
555 return ARMul_DONE;
556 }
557
558 if (BIT (22)) {
559 /* It's a long access, get two words. */
560
561 /* cfldr64 */
562 printfdbg ("cfldr64: %d\n", data);
563
564 if (words == 0) {
565 if (state->bigendSig)
566 DSPregs[DEST_REG].upper.i = (int) data;
567 else
568 DSPregs[DEST_REG].lower.i = (int) data;
569 }
570 else {
571 if (state->bigendSig)
572 DSPregs[DEST_REG].lower.i = (int) data;
573 else
574 DSPregs[DEST_REG].upper.i = (int) data;
575 }
576
577 ++words;
578
579 if (words == 2) {
580 printfdbg ("\tmvdx%d <-- mem = %lld\n", DEST_REG,
581 mv_getReg64int (DEST_REG));
582
583 return ARMul_DONE;
584 }
585 else
586 return ARMul_INC;
587 }
588 else {
589 /* Get just one word. */
590
591 /* cfldr32 */
592 printfdbg ("cfldr32 mvfx%d <-- %d\n", DEST_REG, (int) data);
593
594 /* 32bit ints should be sign extended to 64bits when loaded. */
595 mv_setReg64int (DEST_REG, (long long) data);
596
597 return ARMul_DONE;
598 }
599}
600
601unsigned
602DSPSTC4 (ARMul_State * state,
603 unsigned type, ARMword instr, ARMword * data)
604{
605 static unsigned words;
606
607 if (type != ARMul_DATA) {
608 words = 0;
609 return ARMul_DONE;
610 }
611
612 if (BIT (22)) {
613 /* It's a long access, get two words. */
614 /* cfstrd */
615 printfdbg ("cfstrd\n");
616
617 if (words == 0) {
618 if (state->bigendSig)
619 *data = (ARMword) DSPregs[DEST_REG].upper.i;
620 else
621 *data = (ARMword) DSPregs[DEST_REG].lower.i;
622 }
623 else {
624 if (state->bigendSig)
625 *data = (ARMword) DSPregs[DEST_REG].lower.i;
626 else
627 *data = (ARMword) DSPregs[DEST_REG].upper.i;
628 }
629
630 ++words;
631
632 if (words == 2) {
633 printfdbg ("\tmem = mvd%d = %g\n", DEST_REG,
634 mv_getRegDouble (DEST_REG));
635
636 return ARMul_DONE;
637 }
638 else
639 return ARMul_INC;
640 }
641 else {
642 /* Get just one word. */
643 /* cfstrs */
644 printfdbg ("cfstrs mvf%d <-- %f\n", DEST_REG,
645 DSPregs[DEST_REG].upper.f);
646
647 *data = (ARMword) DSPregs[DEST_REG].upper.i;
648
649 return ARMul_DONE;
650 }
651}
652
653unsigned
654DSPSTC5 (ARMul_State * state,
655 unsigned type, ARMword instr, ARMword * data)
656{
657 static unsigned words;
658
659 if (type != ARMul_DATA) {
660 words = 0;
661 return ARMul_DONE;
662 }
663
664 if (BIT (22)) {
665 /* It's a long access, store two words. */
666 /* cfstr64 */
667 printfdbg ("cfstr64\n");
668
669 if (words == 0) {
670 if (state->bigendSig)
671 *data = (ARMword) DSPregs[DEST_REG].upper.i;
672 else
673 *data = (ARMword) DSPregs[DEST_REG].lower.i;
674 }
675 else {
676 if (state->bigendSig)
677 *data = (ARMword) DSPregs[DEST_REG].lower.i;
678 else
679 *data = (ARMword) DSPregs[DEST_REG].upper.i;
680 }
681
682 ++words;
683
684 if (words == 2) {
685 printfdbg ("\tmem = mvd%d = %lld\n", DEST_REG,
686 mv_getReg64int (DEST_REG));
687
688 return ARMul_DONE;
689 }
690 else
691 return ARMul_INC;
692 }
693 else {
694 /* Store just one word. */
695 /* cfstr32 */
696 *data = (ARMword) DSPregs[DEST_REG].lower.i;
697
698 printfdbg ("cfstr32 MEM = %d\n", (int) *data);
699
700 return ARMul_DONE;
701 }
702}
703
704unsigned
705DSPCDP4 (ARMul_State * state, unsigned type, ARMword instr)
706{
707 int opcode2;
708
709 opcode2 = BITS (5, 7);
710
711 switch (BITS (20, 21)) {
712 case 0:
713 switch (opcode2) {
714 case 0: /* cfcpys */
715 printfdbg ("cfcpys mvf%d = mvf%d = %f\n",
716 DEST_REG, SRC1_REG,
717 DSPregs[SRC1_REG].upper.f);
718 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f;
719 break;
720
721 case 1: /* cfcpyd */
722 printfdbg ("cfcpyd mvd%d = mvd%d = %g\n",
723 DEST_REG, SRC1_REG,
724 mv_getRegDouble (SRC1_REG));
725 mv_setRegDouble (DEST_REG,
726 mv_getRegDouble (SRC1_REG));
727 break;
728
729 case 2: /* cfcvtds */
730 printfdbg ("cfcvtds mvf%d = (float) mvd%d = %f\n",
731 DEST_REG, SRC1_REG,
732 (float) mv_getRegDouble (SRC1_REG));
733 DSPregs[DEST_REG].upper.f =
734 (float) mv_getRegDouble (SRC1_REG);
735 break;
736
737 case 3: /* cfcvtsd */
738 printfdbg ("cfcvtsd mvd%d = mvf%d = %g\n",
739 DEST_REG, SRC1_REG,
740 (double) DSPregs[SRC1_REG].upper.f);
741 mv_setRegDouble (DEST_REG,
742 (double) DSPregs[SRC1_REG].upper.f);
743 break;
744
745 case 4: /* cfcvt32s */
746 printfdbg ("cfcvt32s mvf%d = mvfx%d = %f\n",
747 DEST_REG, SRC1_REG,
748 (float) DSPregs[SRC1_REG].lower.i);
749 DSPregs[DEST_REG].upper.f =
750 (float) DSPregs[SRC1_REG].lower.i;
751 break;
752
753 case 5: /* cfcvt32d */
754 printfdbg ("cfcvt32d mvd%d = mvfx%d = %g\n",
755 DEST_REG, SRC1_REG,
756 (double) DSPregs[SRC1_REG].lower.i);
757 mv_setRegDouble (DEST_REG,
758 (double) DSPregs[SRC1_REG].lower.i);
759 break;
760
761 case 6: /* cfcvt64s */
762 printfdbg ("cfcvt64s mvf%d = mvdx%d = %f\n",
763 DEST_REG, SRC1_REG,
764 (float) mv_getReg64int (SRC1_REG));
765 DSPregs[DEST_REG].upper.f =
766 (float) mv_getReg64int (SRC1_REG);
767 break;
768
769 case 7: /* cfcvt64d */
770 printfdbg ("cfcvt64d mvd%d = mvdx%d = %g\n",
771 DEST_REG, SRC1_REG,
772 (double) mv_getReg64int (SRC1_REG));
773 mv_setRegDouble (DEST_REG,
774 (double) mv_getReg64int (SRC1_REG));
775 break;
776 }
777 break;
778
779 case 1:
780 switch (opcode2) {
781 case 0: /* cfmuls */
782 printfdbg ("cfmuls mvf%d = mvf%d = %f\n",
783 DEST_REG,
784 SRC1_REG,
785 DSPregs[SRC1_REG].upper.f *
786 DSPregs[SRC2_REG].upper.f);
787
788 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
789 * DSPregs[SRC2_REG].upper.f;
790 break;
791
792 case 1: /* cfmuld */
793 printfdbg ("cfmuld mvd%d = mvd%d = %g\n",
794 DEST_REG,
795 SRC1_REG,
796 mv_getRegDouble (SRC1_REG) *
797 mv_getRegDouble (SRC2_REG));
798
799 mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG)
800 * mv_getRegDouble (SRC2_REG));
801 break;
802
803 default:
804 fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n",
805 instr);
806 cirrus_not_implemented ("unknown");
807 break;
808 }
809 break;
810
811 case 3:
812 switch (opcode2) {
813 case 0: /* cfabss */
814 DSPregs[DEST_REG].upper.f =
815 (DSPregs[SRC1_REG].upper.f <
816 0.0F ? -DSPregs[SRC1_REG].upper.
817 f : DSPregs[SRC1_REG].upper.f);
818 printfdbg ("cfabss mvf%d = |mvf%d| = %f\n", DEST_REG,
819 SRC1_REG, DSPregs[DEST_REG].upper.f);
820 break;
821
822 case 1: /* cfabsd */
823 mv_setRegDouble (DEST_REG,
824 (mv_getRegDouble (SRC1_REG) < 0.0 ?
825 -mv_getRegDouble (SRC1_REG)
826 : mv_getRegDouble (SRC1_REG)));
827 printfdbg ("cfabsd mvd%d = |mvd%d| = %g\n",
828 DEST_REG, SRC1_REG,
829 mv_getRegDouble (DEST_REG));
830 break;
831
832 case 2: /* cfnegs */
833 DSPregs[DEST_REG].upper.f =
834 -DSPregs[SRC1_REG].upper.f;
835 printfdbg ("cfnegs mvf%d = -mvf%d = %f\n", DEST_REG,
836 SRC1_REG, DSPregs[DEST_REG].upper.f);
837 break;
838
839 case 3: /* cfnegd */
840 mv_setRegDouble (DEST_REG,
841 -mv_getRegDouble (SRC1_REG));
842 printfdbg ("cfnegd mvd%d = -mvd%d = %g\n", DEST_REG,
843 mv_getRegDouble (DEST_REG));
844 break;
845
846 case 4: /* cfadds */
847 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
848 + DSPregs[SRC2_REG].upper.f;
849 printfdbg ("cfadds mvf%d = mvf%d + mvf%d = %f\n",
850 DEST_REG, SRC1_REG, SRC2_REG,
851 DSPregs[DEST_REG].upper.f);
852 break;
853
854 case 5: /* cfaddd */
855 mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG)
856 + mv_getRegDouble (SRC2_REG));
857 printfdbg ("cfaddd: mvd%d = mvd%d + mvd%d = %g\n",
858 DEST_REG,
859 SRC1_REG, SRC2_REG,
860 mv_getRegDouble (DEST_REG));
861 break;
862
863 case 6: /* cfsubs */
864 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
865 - DSPregs[SRC2_REG].upper.f;
866 printfdbg ("cfsubs: mvf%d = mvf%d - mvf%d = %f\n",
867 DEST_REG, SRC1_REG, SRC2_REG,
868 DSPregs[DEST_REG].upper.f);
869 break;
870
871 case 7: /* cfsubd */
872 mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG)
873 - mv_getRegDouble (SRC2_REG));
874 printfdbg ("cfsubd: mvd%d = mvd%d - mvd%d = %g\n",
875 DEST_REG,
876 SRC1_REG, SRC2_REG,
877 mv_getRegDouble (DEST_REG));
878 break;
879 }
880 break;
881
882 default:
883 fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", instr);
884 cirrus_not_implemented ("unknown");
885 break;
886 }
887
888 return ARMul_DONE;
889}
890
891unsigned
892DSPCDP5 (ARMul_State * state, unsigned type, ARMword instr)
893{
894 int opcode2;
895 char shift;
896
897 opcode2 = BITS (5, 7);
898
899 /* Shift constants are 7bit signed numbers in bits 0..3|5..7. */
900 shift = BITS (0, 3) | (BITS (5, 7)) << 4;
901 if (shift & 0x40)
902 shift |= 0xc0;
903
904 switch (BITS (20, 21)) {
905 case 0:
906 /* cfsh32 */
907 printfdbg ("cfsh32 %s amount=%d\n",
908 shift < 0 ? "right" : "left", shift);
909 if (shift < 0)
910 /* Negative shift is a right shift. */
911 DSPregs[DEST_REG].lower.i =
912 DSPregs[SRC1_REG].lower.i >> -shift;
913 else
914 /* Positive shift is a left shift. */
915 DSPregs[DEST_REG].lower.i =
916 DSPregs[SRC1_REG].lower.i << shift;
917 break;
918
919 case 1:
920 switch (opcode2) {
921 case 0: /* cfmul32 */
922 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
923 * DSPregs[SRC2_REG].lower.i;
924 printfdbg ("cfmul32 mvfx%d = mvfx%d * mvfx%d = %d\n",
925 DEST_REG, SRC1_REG, SRC2_REG,
926 DSPregs[DEST_REG].lower.i);
927 break;
928
929 case 1: /* cfmul64 */
930 mv_setReg64int (DEST_REG, mv_getReg64int (SRC1_REG)
931 * mv_getReg64int (SRC2_REG));
932 printfdbg
933 ("cfmul64 mvdx%d = mvdx%d * mvdx%d = %lld\n",
934 DEST_REG, SRC1_REG, SRC2_REG,
935 mv_getReg64int (DEST_REG));
936 break;
937
938 case 2: /* cfmac32 */
939 DSPregs[DEST_REG].lower.i
940 +=
941 DSPregs[SRC1_REG].lower.i *
942 DSPregs[SRC2_REG].lower.i;
943 printfdbg ("cfmac32 mvfx%d += mvfx%d * mvfx%d = %d\n",
944 DEST_REG, SRC1_REG, SRC2_REG,
945 DSPregs[DEST_REG].lower.i);
946 break;
947
948 case 3: /* cfmsc32 */
949 DSPregs[DEST_REG].lower.i
950 -=
951 DSPregs[SRC1_REG].lower.i *
952 DSPregs[SRC2_REG].lower.i;
953 printfdbg ("cfmsc32 mvfx%d -= mvfx%d * mvfx%d = %d\n",
954 DEST_REG, SRC1_REG, SRC2_REG,
955 DSPregs[DEST_REG].lower.i);
956 break;
957
958 case 4: /* cfcvts32 */
959 /* fixme: this should round */
960 DSPregs[DEST_REG].lower.i =
961 (int) DSPregs[SRC1_REG].upper.f;
962 printfdbg ("cfcvts32 mvfx%d = mvf%d = %d\n", DEST_REG,
963 SRC1_REG, DSPregs[DEST_REG].lower.i);
964 break;
965
966 case 5: /* cfcvtd32 */
967 /* fixme: this should round */
968 DSPregs[DEST_REG].lower.i =
969 (int) mv_getRegDouble (SRC1_REG);
970 printfdbg ("cfcvtd32 mvdx%d = mvd%d = %d\n", DEST_REG,
971 SRC1_REG, DSPregs[DEST_REG].lower.i);
972 break;
973
974 case 6: /* cftruncs32 */
975 DSPregs[DEST_REG].lower.i =
976 (int) DSPregs[SRC1_REG].upper.f;
977 printfdbg ("cftruncs32 mvfx%d = mvf%d = %d\n",
978 DEST_REG, SRC1_REG,
979 DSPregs[DEST_REG].lower.i);
980 break;
981
982 case 7: /* cftruncd32 */
983 DSPregs[DEST_REG].lower.i =
984 (int) mv_getRegDouble (SRC1_REG);
985 printfdbg ("cftruncd32 mvfx%d = mvd%d = %d\n",
986 DEST_REG, SRC1_REG,
987 DSPregs[DEST_REG].lower.i);
988 break;
989 }
990 break;
991
992 case 2:
993 /* cfsh64 */
994 printfdbg ("cfsh64\n");
995
996 if (shift < 0)
997 /* Negative shift is a right shift. */
998 mv_setReg64int (DEST_REG,
999 mv_getReg64int (SRC1_REG) >> -shift);
1000 else
1001 /* Positive shift is a left shift. */
1002 mv_setReg64int (DEST_REG,
1003 mv_getReg64int (SRC1_REG) << shift);
1004 printfdbg ("\t%llx\n", mv_getReg64int (DEST_REG));
1005 break;
1006
1007 case 3:
1008 switch (opcode2) {
1009 case 0: /* cfabs32 */
1010 DSPregs[DEST_REG].lower.i =
1011 (DSPregs[SRC1_REG].lower.i <
1012 0 ? -DSPregs[SRC1_REG].lower.
1013 i : DSPregs[SRC1_REG].lower.i);
1014 printfdbg ("cfabs32 mvfx%d = |mvfx%d| = %d\n",
1015 DEST_REG, SRC1_REG, SRC2_REG,
1016 DSPregs[DEST_REG].lower.i);
1017 break;
1018
1019 case 1: /* cfabs64 */
1020 mv_setReg64int (DEST_REG,
1021 (mv_getReg64int (SRC1_REG) < 0
1022 ? -mv_getReg64int (SRC1_REG)
1023 : mv_getReg64int (SRC1_REG)));
1024 printfdbg ("cfabs64 mvdx%d = |mvdx%d| = %lld\n",
1025 DEST_REG, SRC1_REG, SRC2_REG,
1026 mv_getReg64int (DEST_REG));
1027 break;
1028
1029 case 2: /* cfneg32 */
1030 DSPregs[DEST_REG].lower.i =
1031 -DSPregs[SRC1_REG].lower.i;
1032 printfdbg ("cfneg32 mvfx%d = -mvfx%d = %d\n",
1033 DEST_REG, SRC1_REG, SRC2_REG,
1034 DSPregs[DEST_REG].lower.i);
1035 break;
1036
1037 case 3: /* cfneg64 */
1038 mv_setReg64int (DEST_REG, -mv_getReg64int (SRC1_REG));
1039 printfdbg ("cfneg64 mvdx%d = -mvdx%d = %lld\n",
1040 DEST_REG, SRC1_REG, SRC2_REG,
1041 mv_getReg64int (DEST_REG));
1042 break;
1043
1044 case 4: /* cfadd32 */
1045 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
1046 + DSPregs[SRC2_REG].lower.i;
1047 printfdbg ("cfadd32 mvfx%d = mvfx%d + mvfx%d = %d\n",
1048 DEST_REG, SRC1_REG, SRC2_REG,
1049 DSPregs[DEST_REG].lower.i);
1050 break;
1051
1052 case 5: /* cfadd64 */
1053 mv_setReg64int (DEST_REG, mv_getReg64int (SRC1_REG)
1054 + mv_getReg64int (SRC2_REG));
1055 printfdbg
1056 ("cfadd64 mvdx%d = mvdx%d + mvdx%d = %lld\n",
1057 DEST_REG, SRC1_REG, SRC2_REG,
1058 mv_getReg64int (DEST_REG));
1059 break;
1060
1061 case 6: /* cfsub32 */
1062 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
1063 - DSPregs[SRC2_REG].lower.i;
1064 printfdbg ("cfsub32 mvfx%d = mvfx%d - mvfx%d = %d\n",
1065 DEST_REG, SRC1_REG, SRC2_REG,
1066 DSPregs[DEST_REG].lower.i);
1067 break;
1068
1069 case 7: /* cfsub64 */
1070 mv_setReg64int (DEST_REG, mv_getReg64int (SRC1_REG)
1071 - mv_getReg64int (SRC2_REG));
1072 printfdbg ("cfsub64 mvdx%d = mvdx%d - mvdx%d = %d\n",
1073 DEST_REG, SRC1_REG, SRC2_REG,
1074 mv_getReg64int (DEST_REG));
1075 break;
1076 }
1077 break;
1078
1079 default:
1080 fprintf (stderr, "unknown opcode in DSPCDP5 0x%x\n", instr);
1081 cirrus_not_implemented ("unknown");
1082 break;
1083 }
1084
1085 return ARMul_DONE;
1086}
1087
1088unsigned
1089DSPCDP6 (ARMul_State * state, unsigned type, ARMword instr)
1090{
1091 int opcode2;
1092
1093 opcode2 = BITS (5, 7);
1094
1095 switch (BITS (20, 21)) {
1096 case 0:
1097 /* cfmadd32 */
1098 cirrus_not_implemented ("cfmadd32");
1099 break;
1100
1101 case 1:
1102 /* cfmsub32 */
1103 cirrus_not_implemented ("cfmsub32");
1104 break;
1105
1106 case 2:
1107 /* cfmadda32 */
1108 cirrus_not_implemented ("cfmadda32");
1109 break;
1110
1111 case 3:
1112 /* cfmsuba32 */
1113 cirrus_not_implemented ("cfmsuba32");
1114 break;
1115
1116 default:
1117 fprintf (stderr, "unknown opcode in DSPCDP6 0x%x\n", instr);
1118 }
1119
1120 return ARMul_DONE;
1121}
1122
1123/* Conversion functions.
1124
1125 32-bit integers are stored in the LOWER half of a 64-bit physical
1126 register.
1127
1128 Single precision floats are stored in the UPPER half of a 64-bit
1129 physical register. */
1130
1131static double
1132mv_getRegDouble (int regnum)
1133{
1134 reg_conv.ints[lsw_float_index] = DSPregs[regnum].upper.i;
1135 reg_conv.ints[msw_float_index] = DSPregs[regnum].lower.i;
1136 return reg_conv.d;
1137}
1138
1139static void
1140mv_setRegDouble (int regnum, double val)
1141{
1142 reg_conv.d = val;
1143 DSPregs[regnum].upper.i = reg_conv.ints[lsw_float_index];
1144 DSPregs[regnum].lower.i = reg_conv.ints[msw_float_index];
1145}
1146
1147static long long
1148mv_getReg64int (int regnum)
1149{
1150 reg_conv.ints[lsw_int_index] = DSPregs[regnum].lower.i;
1151 reg_conv.ints[msw_int_index] = DSPregs[regnum].upper.i;
1152 return reg_conv.ll;
1153}
1154
1155static void
1156mv_setReg64int (int regnum, long long val)
1157{
1158 reg_conv.ll = val;
1159 DSPregs[regnum].lower.i = reg_conv.ints[lsw_int_index];
1160 DSPregs[regnum].upper.i = reg_conv.ints[msw_int_index];
1161}
1162
1163/* Compute LSW in a double and a long long. */
1164
1165void
1166mv_compute_host_endianness (ARMul_State * state)
1167{
1168 static union
1169 {
1170 long long ll;
1171 int ints[2];
1172 int i;
1173 double d;
1174 float floats[2];
1175 float f;
1176 } conv;
1177
1178 /* Calculate where's the LSW in a 64bit int. */
1179 conv.ll = 45;
1180
1181 if (conv.ints[0] == 0) {
1182 msw_int_index = 0;
1183 lsw_int_index = 1;
1184 }
1185 else {
1186 assert (conv.ints[1] == 0);
1187 msw_int_index = 1;
1188 lsw_int_index = 0;
1189 }
1190
1191 /* Calculate where's the LSW in a double. */
1192 conv.d = 3.0;
1193
1194 if (conv.ints[0] == 0) {
1195 msw_float_index = 0;
1196 lsw_float_index = 1;
1197 }
1198 else {
1199 assert (conv.ints[1] == 0);
1200 msw_float_index = 1;
1201 lsw_float_index = 0;
1202 }
1203
1204 printfdbg ("lsw_int_index %d\n", lsw_int_index);
1205 printfdbg ("lsw_float_index %d\n", lsw_float_index);
1206}
diff --git a/src/core/arm/interpreter/mmu/rb.cpp b/src/core/arm/interpreter/mmu/rb.cpp
deleted file mode 100644
index 07b11e311..000000000
--- a/src/core/arm/interpreter/mmu/rb.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
1#include "core/arm/interpreter/armdefs.h"
2
3/*chy 2004-06-06, fix bug found by wenye@cs.ucsb.edu*/
4ARMword rb_masks[] = {
5 0x0, //RB_INVALID
6 4, //RB_1
7 16, //RB_4
8 32, //RB_8
9};
10
11/*mmu_rb_init
12 * @rb_t :rb_t to init
13 * @num :number of entry
14 * */
15int
16mmu_rb_init (rb_s * rb_t, int num)
17{
18 int i;
19 rb_entry_t *entrys;
20
21 entrys = (rb_entry_t *) malloc (sizeof (*entrys) * num);
22 if (entrys == NULL) {
23 printf ("SKYEYE:mmu_rb_init malloc error\n");
24 return -1;
25 }
26 for (i = 0; i < num; i++) {
27 entrys[i].type = RB_INVALID;
28 entrys[i].fault = NO_FAULT;
29 }
30
31 rb_t->entrys = entrys;
32 rb_t->num = num;
33 return 0;
34}
35
36/*mmu_rb_exit*/
37void
38mmu_rb_exit (rb_s * rb_t)
39{
40 free (rb_t->entrys);
41};
42
43/*mmu_rb_search
44 * @rb_t :rb_t to serach
45 * @va :va address to math
46 *
47 * $ NULL :not match
48 * NO-NULL:
49 * */
50rb_entry_t *
51mmu_rb_search (rb_s * rb_t, ARMword va)
52{
53 int i;
54 rb_entry_t *rb = rb_t->entrys;
55
56 DEBUG_LOG(ARM11, "va = %x\n", va);
57 for (i = 0; i < rb_t->num; i++, rb++) {
58 //2004-06-06 lyh bug from wenye@cs.ucsb.edu
59 if (rb->type) {
60 if ((va >= rb->va)
61 && (va < (rb->va + rb_masks[rb->type])))
62 return rb;
63 }
64 }
65 return NULL;
66};
67
68void
69mmu_rb_invalidate_entry (rb_s * rb_t, int i)
70{
71 rb_t->entrys[i].type = RB_INVALID;
72}
73
74void
75mmu_rb_invalidate_all (rb_s * rb_t)
76{
77 int i;
78
79 for (i = 0; i < rb_t->num; i++)
80 mmu_rb_invalidate_entry (rb_t, i);
81};
82
83void
84mmu_rb_load (ARMul_State * state, rb_s * rb_t, int i_rb, int type, ARMword va)
85{
86 rb_entry_t *rb;
87 int i;
88 ARMword max_start, min_end;
89 fault_t fault;
90 tlb_entry_t *tlb;
91
92 /*align va according to type */
93 va &= ~(rb_masks[type] - 1);
94 /*invalidate all RB match [va, va + rb_masks[type]] */
95 for (rb = rb_t->entrys, i = 0; i < rb_t->num; i++, rb++) {
96 if (rb->type) {
97 max_start = max (va, rb->va);
98 min_end =
99 min (va + rb_masks[type],
100 rb->va + rb_masks[rb->type]);
101 if (max_start < min_end)
102 rb->type = RB_INVALID;
103 }
104 }
105 /*load word */
106 rb = &rb_t->entrys[i_rb];
107 rb->type = type;
108 fault = translate (state, va, D_TLB (), &tlb);
109 if (fault) {
110 rb->fault = fault;
111 return;
112 }
113 fault = check_access (state, va, tlb, 1);
114 if (fault) {
115 rb->fault = fault;
116 return;
117 }
118
119 rb->fault = NO_FAULT;
120 va = tlb_va_to_pa (tlb, va);
121 //2004-06-06 lyh bug from wenye@cs.ucsb.edu
122 for (i = 0; i < (rb_masks[type] / 4); i++, va += WORD_SIZE) {
123 //rb->data[i] = mem_read_word (state, va);
124 bus_read(32, va, &rb->data[i]);
125 };
126}
diff --git a/src/core/arm/interpreter/mmu/rb.h b/src/core/arm/interpreter/mmu/rb.h
deleted file mode 100644
index 7bf0ebb26..000000000
--- a/src/core/arm/interpreter/mmu/rb.h
+++ /dev/null
@@ -1,55 +0,0 @@
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/arm/interpreter/mmu/sa_mmu.cpp b/src/core/arm/interpreter/mmu/sa_mmu.cpp
deleted file mode 100644
index eff5002de..000000000
--- a/src/core/arm/interpreter/mmu/sa_mmu.cpp
+++ /dev/null
@@ -1,864 +0,0 @@
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
24#include "core/arm/interpreter/armdefs.h"
25
26/**
27 * The interface of read data from bus
28 */
29int bus_read(short size, int addr, uint32_t * value) {
30 ERROR_LOG(ARM11, "unimplemented bus_read");
31 return 0;
32}
33
34/**
35 * The interface of write data from bus
36 */
37int bus_write(short size, int addr, uint32_t value) {
38 ERROR_LOG(ARM11, "unimplemented bus_write");
39 return 0;
40}
41
42
43typedef struct sa_mmu_desc_s
44{
45 int i_tlb;
46 cache_desc_t i_cache;
47
48 int d_tlb;
49 cache_desc_t main_d_cache;
50 cache_desc_t mini_d_cache;
51 int rb;
52 wb_desc_t wb;
53} sa_mmu_desc_t;
54
55static sa_mmu_desc_t sa11xx_mmu_desc = {
56 32,
57 {32, 32, 16, CACHE_WRITE_BACK},
58
59 32,
60 {32, 32, 8, CACHE_WRITE_BACK},
61 {32, 2, 8, CACHE_WRITE_BACK},
62 4,
63 //{8, 4}, for word size
64 {8, 16}, //for byte size, chy 2003-07-11
65};
66
67static fault_t sa_mmu_write (ARMul_State * state, ARMword va, ARMword data,
68 ARMword datatype);
69static fault_t sa_mmu_read (ARMul_State * state, ARMword va, ARMword * data,
70 ARMword datatype);
71static fault_t update_cache (ARMul_State * state, ARMword va, ARMword data,
72 ARMword datatype, cache_line_t * cache,
73 cache_s * cache_t, ARMword real_va);
74
75void
76mmu_wb_write_bytes (ARMul_State * state, wb_s * wb_t, ARMword pa,
77 ARMbyte * data, int n);
78int
79sa_mmu_init (ARMul_State * state)
80{
81 sa_mmu_desc_t *desc;
82 cache_desc_t *c_desc;
83
84 state->mmu.control = 0x70;
85 state->mmu.translation_table_base = 0xDEADC0DE;
86 state->mmu.domain_access_control = 0xDEADC0DE;
87 state->mmu.fault_status = 0;
88 state->mmu.fault_address = 0;
89 state->mmu.process_id = 0;
90
91 desc = &sa11xx_mmu_desc;
92 if (mmu_tlb_init (I_TLB (), desc->i_tlb)) {
93 ERROR_LOG(ARM11, "i_tlb init %d\n", -1);
94 goto i_tlb_init_error;
95 }
96
97 c_desc = &desc->i_cache;
98 if (mmu_cache_init (I_CACHE (), c_desc->width, c_desc->way,
99 c_desc->set, c_desc->w_mode)) {
100 ERROR_LOG(ARM11, "i_cache init %d\n", -1);
101 goto i_cache_init_error;
102 }
103
104 if (mmu_tlb_init (D_TLB (), desc->d_tlb)) {
105 ERROR_LOG(ARM11, "d_tlb init %d\n", -1);
106 goto d_tlb_init_error;
107 }
108
109 c_desc = &desc->main_d_cache;
110 if (mmu_cache_init (MAIN_D_CACHE (), c_desc->width, c_desc->way,
111 c_desc->set, c_desc->w_mode)) {
112 ERROR_LOG(ARM11, "main_d_cache init %d\n", -1);
113 goto main_d_cache_init_error;
114 }
115
116 c_desc = &desc->mini_d_cache;
117 if (mmu_cache_init (MINI_D_CACHE (), c_desc->width, c_desc->way,
118 c_desc->set, c_desc->w_mode)) {
119 ERROR_LOG(ARM11, "mini_d_cache init %d\n", -1);
120 goto mini_d_cache_init_error;
121 }
122
123 if (mmu_wb_init (WB (), desc->wb.num, desc->wb.nb)) {
124 ERROR_LOG(ARM11, "wb init %d\n", -1);
125 goto wb_init_error;
126 }
127
128 if (mmu_rb_init (RB (), desc->rb)) {
129 ERROR_LOG(ARM11, "rb init %d\n", -1);
130 goto rb_init_error;
131 }
132 return 0;
133
134 rb_init_error:
135 mmu_wb_exit (WB ());
136 wb_init_error:
137 mmu_cache_exit (MINI_D_CACHE ());
138 mini_d_cache_init_error:
139 mmu_cache_exit (MAIN_D_CACHE ());
140 main_d_cache_init_error:
141 mmu_tlb_exit (D_TLB ());
142 d_tlb_init_error:
143 mmu_cache_exit (I_CACHE ());
144 i_cache_init_error:
145 mmu_tlb_exit (I_TLB ());
146 i_tlb_init_error:
147 return -1;
148}
149
150void
151sa_mmu_exit (ARMul_State * state)
152{
153 mmu_rb_exit (RB ());
154 mmu_wb_exit (WB ());
155 mmu_cache_exit (MINI_D_CACHE ());
156 mmu_cache_exit (MAIN_D_CACHE ());
157 mmu_tlb_exit (D_TLB ());
158 mmu_cache_exit (I_CACHE ());
159 mmu_tlb_exit (I_TLB ());
160};
161
162
163static fault_t
164sa_mmu_load_instr (ARMul_State * state, ARMword va, ARMword * instr)
165{
166 fault_t fault;
167 tlb_entry_t *tlb;
168 cache_line_t *cache;
169 int c; //cache bit
170 ARMword pa; //physical addr
171
172 static int debug_count = 0; //used for debug
173
174 DEBUG_LOG(ARM11, "va = %x\n", va);
175
176 va = mmu_pid_va_map (va);
177 if (MMU_Enabled) {
178 /*align check */
179 if ((va & (WORD_SIZE - 1)) && MMU_Aligned) {
180 DEBUG_LOG(ARM11, "align\n");
181 return ALIGNMENT_FAULT;
182 }
183 else
184 va &= ~(WORD_SIZE - 1);
185
186 /*translate tlb */
187 fault = translate (state, va, I_TLB (), &tlb);
188 if (fault) {
189 DEBUG_LOG(ARM11, "translate\n");
190 return fault;
191 }
192
193 /*check access */
194 fault = check_access (state, va, tlb, 1);
195 if (fault) {
196 DEBUG_LOG(ARM11, "check_fault\n");
197 return fault;
198 }
199 }
200
201 /*search cache no matter MMU enabled/disabled */
202 cache = mmu_cache_search (state, I_CACHE (), va);
203 if (cache) {
204 *instr = cache->data[va_cache_index (va, I_CACHE ())];
205 return NO_FAULT;
206 }
207
208 /*if MMU disabled or C flag is set alloc cache */
209 if (MMU_Disabled) {
210 c = 1;
211 pa = va;
212 }
213 else {
214 c = tlb_c_flag (tlb);
215 pa = tlb_va_to_pa (tlb, va);
216 }
217
218 if (c) {
219 int index;
220
221 debug_count++;
222 cache = mmu_cache_alloc (state, I_CACHE (), va, pa);
223 index = va_cache_index (va, I_CACHE ());
224 *instr = cache->data[va_cache_index (va, I_CACHE ())];
225 }
226 else
227 //*instr = mem_read_word (state, pa);
228 bus_read(32, pa, instr);
229
230 return NO_FAULT;
231};
232
233
234
235static fault_t
236sa_mmu_read_byte (ARMul_State * state, ARMword virt_addr, ARMword * data)
237{
238 //ARMword temp,offset;
239 fault_t fault;
240 fault = sa_mmu_read (state, virt_addr, data, ARM_BYTE_TYPE);
241 return fault;
242}
243
244static fault_t
245sa_mmu_read_halfword (ARMul_State * state, ARMword virt_addr, ARMword * data)
246{
247 //ARMword temp,offset;
248 fault_t fault;
249 fault = sa_mmu_read (state, virt_addr, data, ARM_HALFWORD_TYPE);
250 return fault;
251}
252
253static fault_t
254sa_mmu_read_word (ARMul_State * state, ARMword virt_addr, ARMword * data)
255{
256 return sa_mmu_read (state, virt_addr, data, ARM_WORD_TYPE);
257}
258
259
260
261
262static fault_t
263sa_mmu_read (ARMul_State * state, ARMword va, ARMword * data,
264 ARMword datatype)
265{
266 fault_t fault;
267 rb_entry_t *rb;
268 tlb_entry_t *tlb;
269 cache_line_t *cache;
270 ARMword pa, real_va, temp, offset;
271
272 DEBUG_LOG(ARM11, "va = %x\n", va);
273
274 va = mmu_pid_va_map (va);
275 real_va = va;
276 /*if MMU disabled, memory_read */
277 if (MMU_Disabled) {
278 //*data = mem_read_word(state, va);
279 if (datatype == ARM_BYTE_TYPE)
280 //*data = mem_read_byte (state, va);
281 bus_read(8, va, data);
282 else if (datatype == ARM_HALFWORD_TYPE)
283 //*data = mem_read_halfword (state, va);
284 bus_read(16, va, data);
285 else if (datatype == ARM_WORD_TYPE)
286 //*data = mem_read_word (state, va);
287 bus_read(32, va, data);
288 else {
289 printf ("SKYEYE:1 sa_mmu_read error: unknown data type %d\n", datatype);
290 // skyeye_exit (-1);
291 }
292
293 return NO_FAULT;
294 }
295
296 /*align check */
297 if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) ||
298 ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) {
299 DEBUG_LOG(ARM11, "align\n");
300 return ALIGNMENT_FAULT;
301 } // else
302
303 va &= ~(WORD_SIZE - 1);
304
305 /*translate va to tlb */
306 fault = translate (state, va, D_TLB (), &tlb);
307 if (fault) {
308 DEBUG_LOG(ARM11, "translate\n");
309 return fault;
310 }
311 /*check access permission */
312 fault = check_access (state, va, tlb, 1);
313 if (fault)
314 return fault;
315 /*search in read buffer */
316 rb = mmu_rb_search (RB (), va);
317 if (rb) {
318 if (rb->fault)
319 return rb->fault;
320 *data = rb->data[(va & (rb_masks[rb->type] - 1)) >> WORD_SHT];
321 goto datatrans;
322 //return 0;
323 };
324 /*search main cache */
325 cache = mmu_cache_search (state, MAIN_D_CACHE (), va);
326 if (cache) {
327 *data = cache->data[va_cache_index (va, MAIN_D_CACHE ())];
328 goto datatrans;
329 //return 0;
330 }
331 /*search mini cache */
332 cache = mmu_cache_search (state, MINI_D_CACHE (), va);
333 if (cache) {
334 *data = cache->data[va_cache_index (va, MINI_D_CACHE ())];
335 goto datatrans;
336 //return 0;
337 }
338
339 /*get phy_addr */
340 pa = tlb_va_to_pa (tlb, va);
341 if ((pa >= 0xe0000000) && (pa < 0xe8000000)) {
342 if (tlb_c_flag (tlb)) {
343 if (tlb_b_flag (tlb)) {
344 mmu_cache_soft_flush (state, MAIN_D_CACHE (),
345 pa);
346 }
347 else {
348 mmu_cache_soft_flush (state, MINI_D_CACHE (),
349 pa);
350 }
351 }
352 return NO_FAULT;
353 }
354
355 /*if Buffer, drain Write Buffer first */
356 if (tlb_b_flag (tlb))
357 mmu_wb_drain_all (state, WB ());
358
359 /*alloc cache or mem_read */
360 if (tlb_c_flag (tlb) && MMU_DCacheEnabled) {
361 cache_s *cache_t;
362
363 if (tlb_b_flag (tlb))
364 cache_t = MAIN_D_CACHE ();
365 else
366 cache_t = MINI_D_CACHE ();
367 cache = mmu_cache_alloc (state, cache_t, va, pa);
368 *data = cache->data[va_cache_index (va, cache_t)];
369 }
370 else {
371 //*data = mem_read_word(state, pa);
372 if (datatype == ARM_BYTE_TYPE)
373 //*data = mem_read_byte (state, pa | (real_va & 3));
374 bus_read(8, pa | (real_va & 3), data);
375 else if (datatype == ARM_HALFWORD_TYPE)
376 //*data = mem_read_halfword (state, pa | (real_va & 2));
377 bus_read(16, pa | (real_va & 2), data);
378 else if (datatype == ARM_WORD_TYPE)
379 //*data = mem_read_word (state, pa);
380 bus_read(32, pa, data);
381 else {
382 printf ("SKYEYE:2 sa_mmu_read error: unknown data type %d\n", datatype);
383 // skyeye_exit (-1);
384 }
385 return NO_FAULT;
386 }
387
388
389 datatrans:
390 if (datatype == ARM_HALFWORD_TYPE) {
391 temp = *data;
392 offset = (((ARMword) state->bigendSig * 2) ^ (real_va & 2)) << 3; /* bit offset into the word */
393 *data = (temp >> offset) & 0xffff;
394 }
395 else if (datatype == ARM_BYTE_TYPE) {
396 temp = *data;
397 offset = (((ARMword) state->bigendSig * 3) ^ (real_va & 3)) << 3; /* bit offset into the word */
398 *data = (temp >> offset & 0xffL);
399 }
400 end:
401 return NO_FAULT;
402}
403
404
405static fault_t
406sa_mmu_write_byte (ARMul_State * state, ARMword virt_addr, ARMword data)
407{
408 return sa_mmu_write (state, virt_addr, data, ARM_BYTE_TYPE);
409}
410
411static fault_t
412sa_mmu_write_halfword (ARMul_State * state, ARMword virt_addr, ARMword data)
413{
414 return sa_mmu_write (state, virt_addr, data, ARM_HALFWORD_TYPE);
415}
416
417static fault_t
418sa_mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data)
419{
420 return sa_mmu_write (state, virt_addr, data, ARM_WORD_TYPE);
421}
422
423
424
425static fault_t
426sa_mmu_write (ARMul_State * state, ARMword va, ARMword data, ARMword datatype)
427{
428 tlb_entry_t *tlb;
429 cache_line_t *cache;
430 int b;
431 ARMword pa, real_va;
432 fault_t fault;
433
434 DEBUG_LOG(ARM11, "va = %x, val = %x\n", va, data);
435 va = mmu_pid_va_map (va);
436 real_va = va;
437
438 /*search instruction cache */
439 cache = mmu_cache_search (state, I_CACHE (), va);
440 if (cache) {
441 update_cache (state, va, data, datatype, cache, I_CACHE (),
442 real_va);
443 }
444
445 if (MMU_Disabled) {
446 //mem_write_word(state, va, data);
447 if (datatype == ARM_BYTE_TYPE)
448 //mem_write_byte (state, va, data);
449 bus_write(8, va, data);
450 else if (datatype == ARM_HALFWORD_TYPE)
451 //mem_write_halfword (state, va, data);
452 bus_write(16, va, data);
453 else if (datatype == ARM_WORD_TYPE)
454 //mem_write_word (state, va, data);
455 bus_write(32, va, data);
456 else {
457 printf ("SKYEYE:1 sa_mmu_write error: unknown data type %d\n", datatype);
458 // skyeye_exit (-1);
459 }
460
461 return NO_FAULT;
462 }
463 /*align check */
464 //if ((va & (WORD_SIZE - 1)) && MMU_Aligned){
465 if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) ||
466 ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) {
467 DEBUG_LOG(ARM11, "align\n");
468 return ALIGNMENT_FAULT;
469 } //else
470 va &= ~(WORD_SIZE - 1);
471 /*tlb translate */
472 fault = translate (state, va, D_TLB (), &tlb);
473 if (fault) {
474 DEBUG_LOG(ARM11, "translate\n");
475 return fault;
476 }
477 /*tlb check access */
478 fault = check_access (state, va, tlb, 0);
479 if (fault) {
480 DEBUG_LOG(ARM11, "check_access\n");
481 return fault;
482 }
483 /*search main cache */
484 cache = mmu_cache_search (state, MAIN_D_CACHE (), va);
485 if (cache) {
486 update_cache (state, va, data, datatype, cache,
487 MAIN_D_CACHE (), real_va);
488 }
489 else {
490 /*search mini cache */
491 cache = mmu_cache_search (state, MINI_D_CACHE (), va);
492 if (cache) {
493 update_cache (state, va, data, datatype, cache,
494 MINI_D_CACHE (), real_va);
495 }
496 }
497
498 if (!cache) {
499 b = tlb_b_flag (tlb);
500 pa = tlb_va_to_pa (tlb, va);
501 if (b) {
502 if (MMU_WBEnabled) {
503 if (datatype == ARM_WORD_TYPE)
504 mmu_wb_write_bytes (state, WB (), pa,
505 (ARMbyte*)&data, 4);
506 else if (datatype == ARM_HALFWORD_TYPE)
507 mmu_wb_write_bytes (state, WB (),
508 (pa |
509 (real_va & 2)),
510 (ARMbyte*)&data, 2);
511 else if (datatype == ARM_BYTE_TYPE)
512 mmu_wb_write_bytes (state, WB (),
513 (pa |
514 (real_va & 3)),
515 (ARMbyte*)&data, 1);
516
517 }
518 else {
519 if (datatype == ARM_WORD_TYPE)
520 //mem_write_word (state, pa, data);
521 bus_write(32, pa, data);
522 else if (datatype == ARM_HALFWORD_TYPE)
523 /*
524 mem_write_halfword (state,
525 (pa |
526 (real_va & 2)),
527 data);
528 */
529 bus_write(16, pa | (real_va & 2), data);
530 else if (datatype == ARM_BYTE_TYPE)
531 /*
532 mem_write_byte (state,
533 (pa | (real_va & 3)),
534 data);
535 */
536 bus_write(8, pa | (real_va & 3), data);
537 }
538 }
539 else {
540 mmu_wb_drain_all (state, WB ());
541
542 if (datatype == ARM_WORD_TYPE)
543 //mem_write_word (state, pa, data);
544 bus_write(32, pa, data);
545 else if (datatype == ARM_HALFWORD_TYPE)
546 /*
547 mem_write_halfword (state,
548 (pa | (real_va & 2)),
549 data);
550 */
551 bus_write(16, pa | (real_va & 2), data);
552 else if (datatype == ARM_BYTE_TYPE)
553 /*
554 mem_write_byte (state, (pa | (real_va & 3)),
555 data);
556 */
557 bus_write(8, pa | (real_va & 3), data);
558 }
559 }
560 return NO_FAULT;
561}
562
563static fault_t
564update_cache (ARMul_State * state, ARMword va, ARMword data, ARMword datatype,
565 cache_line_t * cache, cache_s * cache_t, ARMword real_va)
566{
567 ARMword temp, offset;
568
569 ARMword index = va_cache_index (va, cache_t);
570
571 //cache->data[index] = data;
572
573 if (datatype == ARM_WORD_TYPE)
574 cache->data[index] = data;
575 else if (datatype == ARM_HALFWORD_TYPE) {
576 temp = cache->data[index];
577 offset = (((ARMword) state->bigendSig * 2) ^ (real_va & 2)) << 3; /* bit offset into the word */
578 cache->data[index] =
579 (temp & ~(0xffffL << offset)) | ((data & 0xffffL) <<
580 offset);
581 }
582 else if (datatype == ARM_BYTE_TYPE) {
583 temp = cache->data[index];
584 offset = (((ARMword) state->bigendSig * 3) ^ (real_va & 3)) << 3; /* bit offset into the word */
585 cache->data[index] =
586 (temp & ~(0xffL << offset)) | ((data & 0xffL) <<
587 offset);
588 }
589
590 if (index < (cache_t->width >> (WORD_SHT + 1)))
591 cache->tag |= TAG_FIRST_HALF_DIRTY;
592 else
593 cache->tag |= TAG_LAST_HALF_DIRTY;
594
595 return NO_FAULT;
596}
597
598ARMword
599sa_mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value)
600{
601 mmu_regnum_t creg = (mmu_regnum_t)(BITS (16, 19) & 15);
602 ARMword data;
603
604 switch (creg) {
605 case MMU_ID:
606// printf("mmu_mrc read ID ");
607 data = 0x41007100; /* v3 */
608 data = state->cpu->cpu_val;
609 break;
610 case MMU_CONTROL:
611// printf("mmu_mrc read CONTROL");
612 data = state->mmu.control;
613 break;
614 case MMU_TRANSLATION_TABLE_BASE:
615// printf("mmu_mrc read TTB ");
616 data = state->mmu.translation_table_base;
617 break;
618 case MMU_DOMAIN_ACCESS_CONTROL:
619// printf("mmu_mrc read DACR ");
620 data = state->mmu.domain_access_control;
621 break;
622 case MMU_FAULT_STATUS:
623// printf("mmu_mrc read FSR ");
624 data = state->mmu.fault_status;
625 break;
626 case MMU_FAULT_ADDRESS:
627// printf("mmu_mrc read FAR ");
628 data = state->mmu.fault_address;
629 break;
630 case MMU_PID:
631 data = state->mmu.process_id;
632 default:
633 printf ("mmu_mrc read UNKNOWN - reg %d\n", creg);
634 data = 0;
635 break;
636 }
637// printf("\t\t\t\t\tpc = 0x%08x\n", state->Reg[15]);
638 *value = data;
639 return data;
640}
641
642void
643sa_mmu_cache_ops (ARMul_State * state, ARMword instr, ARMword value)
644{
645 int CRm, OPC_2;
646
647 CRm = BITS (0, 3);
648 OPC_2 = BITS (5, 7);
649
650 if (OPC_2 == 0 && CRm == 7) {
651 mmu_cache_invalidate_all (state, I_CACHE ());
652 mmu_cache_invalidate_all (state, MAIN_D_CACHE ());
653 mmu_cache_invalidate_all (state, MINI_D_CACHE ());
654 return;
655 }
656
657 if (OPC_2 == 0 && CRm == 5) {
658 mmu_cache_invalidate_all (state, I_CACHE ());
659 return;
660 }
661
662 if (OPC_2 == 0 && CRm == 6) {
663 mmu_cache_invalidate_all (state, MAIN_D_CACHE ());
664 mmu_cache_invalidate_all (state, MINI_D_CACHE ());
665 return;
666 }
667
668 if (OPC_2 == 1 && CRm == 6) {
669 mmu_cache_invalidate (state, MAIN_D_CACHE (), value);
670 mmu_cache_invalidate (state, MINI_D_CACHE (), value);
671 return;
672 }
673
674 if (OPC_2 == 1 && CRm == 0xa) {
675 mmu_cache_clean (state, MAIN_D_CACHE (), value);
676 mmu_cache_clean (state, MINI_D_CACHE (), value);
677 return;
678 }
679
680 if (OPC_2 == 4 && CRm == 0xa) {
681 mmu_wb_drain_all (state, WB ());
682 return;
683 }
684 ERROR_LOG(ARM11, "Unknow OPC_2 = %x CRm = %x\n", OPC_2, CRm);
685}
686
687static void
688sa_mmu_tlb_ops (ARMul_State * state, ARMword instr, ARMword value)
689{
690 int CRm, OPC_2;
691
692 CRm = BITS (0, 3);
693 OPC_2 = BITS (5, 7);
694
695
696 if (OPC_2 == 0 && CRm == 0x7) {
697 mmu_tlb_invalidate_all (state, I_TLB ());
698 mmu_tlb_invalidate_all (state, D_TLB ());
699 return;
700 }
701
702 if (OPC_2 == 0 && CRm == 0x5) {
703 mmu_tlb_invalidate_all (state, I_TLB ());
704 return;
705 }
706
707 if (OPC_2 == 0 && CRm == 0x6) {
708 mmu_tlb_invalidate_all (state, D_TLB ());
709 return;
710 }
711
712 if (OPC_2 == 1 && CRm == 0x6) {
713 mmu_tlb_invalidate_entry (state, D_TLB (), value);
714 return;
715 }
716
717 ERROR_LOG(ARM11, "Unknow OPC_2 = %x CRm = %x\n", OPC_2, CRm);
718}
719
720static void
721sa_mmu_rb_ops (ARMul_State * state, ARMword instr, ARMword value)
722{
723 int CRm, OPC_2;
724
725 CRm = BITS (0, 3);
726 OPC_2 = BITS (5, 7);
727
728 if (OPC_2 == 0x0 && CRm == 0x0) {
729 mmu_rb_invalidate_all (RB ());
730 return;
731 }
732
733 if (OPC_2 == 0x2) {
734 int idx = CRm & 0x3;
735 int type = ((CRm >> 2) & 0x3) + 1;
736
737 if ((idx < 4) && (type < 4))
738 mmu_rb_load (state, RB (), idx, type, value);
739 return;
740 }
741
742 if ((OPC_2 == 1) && (CRm < 4)) {
743 mmu_rb_invalidate_entry (RB (), CRm);
744 return;
745 }
746
747 ERROR_LOG(ARM11, "Unknow OPC_2 = %x CRm = %x\n", OPC_2, CRm);
748}
749
750static ARMword
751sa_mmu_mcr (ARMul_State * state, ARMword instr, ARMword value)
752{
753 mmu_regnum_t creg = (mmu_regnum_t)(BITS (16, 19) & 15);
754 if (!strncmp (state->cpu->cpu_arch_name, "armv4", 5)) {
755 switch (creg) {
756 case MMU_CONTROL:
757// printf("mmu_mcr wrote CONTROL ");
758 state->mmu.control = (value | 0x70) & 0xFFFD;
759 break;
760 case MMU_TRANSLATION_TABLE_BASE:
761// printf("mmu_mcr wrote TTB ");
762 state->mmu.translation_table_base =
763 value & 0xFFFFC000;
764 break;
765 case MMU_DOMAIN_ACCESS_CONTROL:
766// printf("mmu_mcr wrote DACR ");
767 state->mmu.domain_access_control = value;
768 break;
769
770 case MMU_FAULT_STATUS:
771 state->mmu.fault_status = value & 0xFF;
772 break;
773 case MMU_FAULT_ADDRESS:
774 state->mmu.fault_address = value;
775 break;
776
777 case MMU_CACHE_OPS:
778 sa_mmu_cache_ops (state, instr, value);
779 break;
780 case MMU_TLB_OPS:
781 sa_mmu_tlb_ops (state, instr, value);
782 break;
783 case MMU_SA_RB_OPS:
784 sa_mmu_rb_ops (state, instr, value);
785 break;
786 case MMU_SA_DEBUG:
787 break;
788 case MMU_SA_CP15_R15:
789 break;
790 case MMU_PID:
791 //2004-06-06 lyh, bug provided by wen ye wenye@cs.ucsb.edu
792 state->mmu.process_id = value & 0x7e000000;
793 break;
794
795 default:
796 printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg);
797 break;
798 }
799 }
800 return 0;
801}
802
803//teawater add for arm2x86 2005.06.24-------------------------------------------
804static int
805sa_mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr, ARMword * phys_addr)
806{
807 fault_t fault;
808 tlb_entry_t *tlb;
809
810 virt_addr = mmu_pid_va_map (virt_addr);
811 if (MMU_Enabled) {
812
813 /*align check */
814 if ((virt_addr & (WORD_SIZE - 1)) && MMU_Aligned) {
815 DEBUG_LOG(ARM11, "align\n");
816 return ALIGNMENT_FAULT;
817 }
818 else
819 virt_addr &= ~(WORD_SIZE - 1);
820
821 /*translate tlb */
822 fault = translate (state, virt_addr, I_TLB (), &tlb);
823 if (fault) {
824 DEBUG_LOG(ARM11, "translate\n");
825 return fault;
826 }
827
828 /*check access */
829 fault = check_access (state, virt_addr, tlb, 1);
830 if (fault) {
831 DEBUG_LOG(ARM11, "check_fault\n");
832 return fault;
833 }
834 }
835
836 if (MMU_Disabled) {
837 *phys_addr = virt_addr;
838 }
839 else {
840 *phys_addr = tlb_va_to_pa (tlb, virt_addr);
841 }
842
843 return (0);
844}
845
846//AJ2D--------------------------------------------------------------------------
847
848/*sa mmu_ops_t*/
849mmu_ops_t sa_mmu_ops = {
850 sa_mmu_init,
851 sa_mmu_exit,
852 sa_mmu_read_byte,
853 sa_mmu_write_byte,
854 sa_mmu_read_halfword,
855 sa_mmu_write_halfword,
856 sa_mmu_read_word,
857 sa_mmu_write_word,
858 sa_mmu_load_instr,
859 sa_mmu_mcr,
860 sa_mmu_mrc,
861//teawater add for arm2x86 2005.06.24-------------------------------------------
862 sa_mmu_v2p_dbct,
863//AJ2D--------------------------------------------------------------------------
864};
diff --git a/src/core/arm/interpreter/mmu/sa_mmu.h b/src/core/arm/interpreter/mmu/sa_mmu.h
deleted file mode 100644
index 64b1c5470..000000000
--- a/src/core/arm/interpreter/mmu/sa_mmu.h
+++ /dev/null
@@ -1,58 +0,0 @@
1/*
2 sa_mmu.h - StrongARM Memory Management Unit emulation.
3 ARMulator extensions for SkyEye.
4 <lyhost@263.net>
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 _SA_MMU_H_
22#define _SA_MMU_H_
23
24
25/**
26 * The interface of read data from bus
27 */
28int bus_read(short size, int addr, uint32_t * value);
29
30/**
31 * The interface of write data from bus
32 */
33int bus_write(short size, int addr, uint32_t value);
34
35
36typedef struct sa_mmu_s
37{
38 tlb_s i_tlb;
39 cache_s i_cache;
40
41 tlb_s d_tlb;
42 cache_s main_d_cache;
43 cache_s mini_d_cache;
44 rb_s rb_t;
45 wb_s wb_t;
46} sa_mmu_t;
47
48#define I_TLB() (&state->mmu.u.sa_mmu.i_tlb)
49#define I_CACHE() (&state->mmu.u.sa_mmu.i_cache)
50
51#define D_TLB() (&state->mmu.u.sa_mmu.d_tlb)
52#define MAIN_D_CACHE() (&state->mmu.u.sa_mmu.main_d_cache)
53#define MINI_D_CACHE() (&state->mmu.u.sa_mmu.mini_d_cache)
54#define WB() (&state->mmu.u.sa_mmu.wb_t)
55#define RB() (&state->mmu.u.sa_mmu.rb_t)
56
57extern mmu_ops_t sa_mmu_ops;
58#endif /*_SA_MMU_H_*/
diff --git a/src/core/arm/interpreter/mmu/tlb.cpp b/src/core/arm/interpreter/mmu/tlb.cpp
deleted file mode 100644
index ca60ac1a1..000000000
--- a/src/core/arm/interpreter/mmu/tlb.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
1#include <assert.h>
2
3#include "core/arm/interpreter/armdefs.h"
4
5ARMword tlb_masks[] = {
6 0x00000000, /* TLB_INVALID */
7 0xFFFFF000, /* TLB_SMALLPAGE */
8 0xFFFF0000, /* TLB_LARGEPAGE */
9 0xFFF00000, /* TLB_SECTION */
10 0xFFFFF000, /*TLB_ESMALLPAGE, have TEX attirbute, only for XScale */
11 0xFFFFFC00 /* TLB_TINYPAGE */
12};
13
14/* This function encodes table 8-2 Interpreting AP bits,
15 returning non-zero if access is allowed. */
16static int
17check_perms (ARMul_State * state, int ap, int read)
18{
19 int s, r, user;
20
21 s = state->mmu.control & CONTROL_SYSTEM;
22 r = state->mmu.control & CONTROL_ROM;
23 //chy 2006-02-15 , should consider system mode, don't conside 26bit mode
24 user = (state->Mode == USER32MODE) || (state->Mode == USER26MODE) || (state->Mode == SYSTEM32MODE);
25
26 switch (ap) {
27 case 0:
28 return read && ((s && !user) || r);
29 case 1:
30 return !user;
31 case 2:
32 return read || !user;
33 case 3:
34 return 1;
35 }
36 return 0;
37}
38
39fault_t
40check_access (ARMul_State * state, ARMword virt_addr, tlb_entry_t * tlb,
41 int read)
42{
43 int access;
44
45 state->mmu.last_domain = tlb->domain;
46 access = (state->mmu.domain_access_control >> (tlb->domain * 2)) & 3;
47 if ((access == 0) || (access == 2)) {
48 /* It's unclear from the documentation whether this
49 should always raise a section domain fault, or if
50 it should be a page domain fault in the case of an
51 L1 that describes a page table. In the ARM710T
52 datasheets, "Figure 8-9: Sequence for checking faults"
53 seems to indicate the former, while "Table 8-4: Priority
54 encoding of fault status" gives a value for FS[3210] in
55 the event of a domain fault for a page. Hmm. */
56 return SECTION_DOMAIN_FAULT;
57 }
58 if (access == 1) {
59 /* client access - check perms */
60 int subpage, ap;
61
62 switch (tlb->mapping) {
63 /*ks 2004-05-09
64 * only for XScale
65 * Extend Small Page(ESP) Format
66 * 31-12 bits the base addr of ESP
67 * 11-10 bits SBZ
68 * 9-6 bits TEX
69 * 5-4 bits AP
70 * 3 bit C
71 * 2 bit B
72 * 1-0 bits 11
73 * */
74 case TLB_ESMALLPAGE: //xj
75 subpage = 0;
76 //printf("TLB_ESMALLPAGE virt_addr=0x%x \n",virt_addr );
77 break;
78
79 case TLB_TINYPAGE:
80 subpage = 0;
81 //printf("TLB_TINYPAGE virt_addr=0x%x \n",virt_addr );
82 break;
83
84 case TLB_SMALLPAGE:
85 subpage = (virt_addr >> 10) & 3;
86 break;
87 case TLB_LARGEPAGE:
88 subpage = (virt_addr >> 14) & 3;
89 break;
90 case TLB_SECTION:
91 subpage = 3;
92 break;
93 default:
94 assert (0);
95 subpage = 0; /* cleans a warning */
96 }
97 ap = (tlb->perms >> (subpage * 2 + 4)) & 3;
98 if (!check_perms (state, ap, read)) {
99 if (tlb->mapping == TLB_SECTION) {
100 return SECTION_PERMISSION_FAULT;
101 }
102 else {
103 return SUBPAGE_PERMISSION_FAULT;
104 }
105 }
106 }
107 else { /* access == 3 */
108 /* manager access - don't check perms */
109 }
110 return NO_FAULT;
111}
112
113fault_t
114translate (ARMul_State * state, ARMword virt_addr, tlb_s * tlb_t,
115 tlb_entry_t ** tlb)
116{
117 *tlb = mmu_tlb_search (state, tlb_t, virt_addr);
118 if (!*tlb) {
119 /* walk the translation tables */
120 ARMword l1addr, l1desc;
121 tlb_entry_t entry;
122
123 l1addr = state->mmu.translation_table_base & 0xFFFFC000;
124 l1addr = (l1addr | (virt_addr >> 18)) & ~3;
125 //l1desc = mem_read_word (state, l1addr);
126 bus_read(32, l1addr, &l1desc);
127 switch (l1desc & 3) {
128 case 0:
129 /*
130 * according to Figure 3-9 Sequence for checking faults in arm manual,
131 * section translation fault should be returned here.
132 */
133 {
134 return SECTION_TRANSLATION_FAULT;
135 }
136 case 3:
137 /* fine page table */
138 // dcl 2006-01-08
139 {
140 ARMword l2addr, l2desc;
141
142 l2addr = l1desc & 0xFFFFF000;
143 l2addr = (l2addr |
144 ((virt_addr & 0x000FFC00) >> 8)) &
145 ~3;
146 //l2desc = mem_read_word (state, l2addr);
147 bus_read(32, l2addr, &l2desc);
148
149 entry.virt_addr = virt_addr;
150 entry.phys_addr = l2desc;
151 entry.perms = l2desc & 0x00000FFC;
152 entry.domain = (l1desc >> 5) & 0x0000000F;
153 switch (l2desc & 3) {
154 case 0:
155 state->mmu.last_domain = entry.domain;
156 return PAGE_TRANSLATION_FAULT;
157 case 3:
158 entry.mapping = TLB_TINYPAGE;
159 break;
160 case 1:
161 // this is untested
162 entry.mapping = TLB_LARGEPAGE;
163 break;
164 case 2:
165 // this is untested
166 entry.mapping = TLB_SMALLPAGE;
167 break;
168 }
169 }
170 break;
171 case 1:
172 /* coarse page table */
173 {
174 ARMword l2addr, l2desc;
175
176 l2addr = l1desc & 0xFFFFFC00;
177 l2addr = (l2addr |
178 ((virt_addr & 0x000FF000) >> 10)) &
179 ~3;
180 //l2desc = mem_read_word (state, l2addr);
181 bus_read(32, l2addr, &l2desc);
182
183 entry.virt_addr = virt_addr;
184 entry.phys_addr = l2desc;
185 entry.perms = l2desc & 0x00000FFC;
186 entry.domain = (l1desc >> 5) & 0x0000000F;
187 //printf("SKYEYE:PAGE virt_addr = %x,l1desc=%x,phys_addr=%x\n",virt_addr,l1desc,entry.phys_addr);
188 //chy 2003-09-02 for xscale
189 switch (l2desc & 3) {
190 case 0:
191 state->mmu.last_domain = entry.domain;
192 return PAGE_TRANSLATION_FAULT;
193 case 3:
194 if (!state->is_XScale) {
195 state->mmu.last_domain =
196 entry.domain;
197 return PAGE_TRANSLATION_FAULT;
198 };
199 //ks 2004-05-09 xscale shold use Extend Small Page
200 //entry.mapping = TLB_SMALLPAGE;
201 entry.mapping = TLB_ESMALLPAGE; //xj
202 break;
203 case 1:
204 entry.mapping = TLB_LARGEPAGE;
205 break;
206 case 2:
207 entry.mapping = TLB_SMALLPAGE;
208 break;
209 }
210 }
211 break;
212 case 2:
213 /* section */
214 //printf("SKYEYE:WARNING: not implement section mapping incompletely\n");
215 //printf("SKYEYE:SECTION virt_addr = %x,l1desc=%x\n",virt_addr,l1desc);
216 //return SECTION_DOMAIN_FAULT;
217 //#if 0
218 entry.virt_addr = virt_addr;
219 entry.phys_addr = l1desc;
220 entry.perms = l1desc & 0x00000C0C;
221 entry.domain = (l1desc >> 5) & 0x0000000F;
222 entry.mapping = TLB_SECTION;
223 break;
224 //#endif
225 }
226 entry.virt_addr &= tlb_masks[entry.mapping];
227 entry.phys_addr &= tlb_masks[entry.mapping];
228
229 /* place entry in the tlb */
230 *tlb = &tlb_t->entrys[tlb_t->cycle];
231 tlb_t->cycle = (tlb_t->cycle + 1) % tlb_t->num;
232 **tlb = entry;
233 }
234 state->mmu.last_domain = (*tlb)->domain;
235 return NO_FAULT;
236}
237
238int
239mmu_tlb_init (tlb_s * tlb_t, int num)
240{
241 tlb_entry_t *e;
242 int i;
243
244 e = (tlb_entry_t *) malloc (sizeof (*e) * num);
245 if (e == NULL) {
246 ERROR_LOG(ARM11, "malloc size %d\n", sizeof (*e) * num);
247 goto tlb_malloc_error;
248 }
249 tlb_t->entrys = e;
250 for (i = 0; i < num; i++, e++)
251 e->mapping = TLB_INVALID;
252 tlb_t->cycle = 0;
253 tlb_t->num = num;
254 return 0;
255
256 tlb_malloc_error:
257 return -1;
258}
259
260void
261mmu_tlb_exit (tlb_s * tlb_t)
262{
263 free (tlb_t->entrys);
264};
265
266void
267mmu_tlb_invalidate_all (ARMul_State * state, tlb_s * tlb_t)
268{
269 int entry;
270
271 for (entry = 0; entry < tlb_t->num; entry++) {
272 tlb_t->entrys[entry].mapping = TLB_INVALID;
273 }
274 tlb_t->cycle = 0;
275}
276
277void
278mmu_tlb_invalidate_entry (ARMul_State * state, tlb_s * tlb_t, ARMword addr)
279{
280 tlb_entry_t *tlb;
281
282 tlb = mmu_tlb_search (state, tlb_t, addr);
283 if (tlb) {
284 tlb->mapping = TLB_INVALID;
285 }
286}
287
288tlb_entry_t *
289mmu_tlb_search (ARMul_State * state, tlb_s * tlb_t, ARMword virt_addr)
290{
291 int entry;
292
293 for (entry = 0; entry < tlb_t->num; entry++) {
294 tlb_entry_t *tlb;
295 ARMword mask;
296
297 tlb = &(tlb_t->entrys[entry]);
298 if (tlb->mapping == TLB_INVALID) {
299 continue;
300 }
301 mask = tlb_masks[tlb->mapping];
302 if ((virt_addr & mask) == (tlb->virt_addr & mask)) {
303 return tlb;
304 }
305 }
306 return NULL;
307}
diff --git a/src/core/arm/interpreter/mmu/tlb.h b/src/core/arm/interpreter/mmu/tlb.h
deleted file mode 100644
index 40856567b..000000000
--- a/src/core/arm/interpreter/mmu/tlb.h
+++ /dev/null
@@ -1,87 +0,0 @@
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) ((tlb->phys_addr & tlb_masks[tlb->mapping]) | (va & ~tlb_masks[tlb->mapping]))
67fault_t
68check_access (ARMul_State * state, ARMword virt_addr, tlb_entry_t * tlb,
69 int read);
70
71fault_t
72translate (ARMul_State * state, ARMword virt_addr, tlb_s * tlb_t,
73 tlb_entry_t ** tlb);
74
75int mmu_tlb_init (tlb_s * tlb_t, int num);
76
77void mmu_tlb_exit (tlb_s * tlb_t);
78
79void mmu_tlb_invalidate_all (ARMul_State * state, tlb_s * tlb_t);
80
81void
82mmu_tlb_invalidate_entry (ARMul_State * state, tlb_s * tlb_t, ARMword addr);
83
84tlb_entry_t *mmu_tlb_search (ARMul_State * state, tlb_s * tlb_t,
85 ARMword virt_addr);
86
87#endif /*_MMU_TLB_H_*/
diff --git a/src/core/arm/interpreter/mmu/wb.cpp b/src/core/arm/interpreter/mmu/wb.cpp
deleted file mode 100644
index 82c0cec02..000000000
--- a/src/core/arm/interpreter/mmu/wb.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
1#include "core/arm/interpreter/armdefs.h"
2
3/* wb_init
4 * @wb_t :wb_t to init
5 * @num :num of entrys
6 * @nb :num of byte of each entry
7 *
8 * $ -1:error
9 * 0:ok
10 * */
11int
12mmu_wb_init (wb_s * wb_t, int num, int nb)
13{
14 int i;
15 wb_entry_t *entrys, *wb;
16
17 entrys = (wb_entry_t *) malloc (sizeof (*entrys) * num);
18 if (entrys == NULL) {
19 ERROR_LOG(ARM11, "malloc size %d\n", sizeof (*entrys) * num);
20 goto entrys_malloc_error;
21 }
22
23 for (wb = entrys, i = 0; i < num; i++, wb++) {
24 /*chy 2004-06-06, fix bug found by wenye@cs.ucsb.edu */
25 //wb->data = (ARMword *)malloc(sizeof(ARMword) * nb);
26 wb->data = (ARMbyte *) malloc (nb);
27 if (wb->data == NULL) {
28 ERROR_LOG(ARM11, "malloc size of %d\n", nb);
29 goto data_malloc_error;
30 }
31
32 };
33
34 wb_t->first = wb_t->last = wb_t->used = 0;
35 wb_t->num = num;
36 wb_t->nb = nb;
37 wb_t->entrys = entrys;
38 return 0;
39
40 data_malloc_error:
41 while (--i >= 0)
42 free (entrys[i].data);
43 free (entrys);
44 entrys_malloc_error:
45 return -1;
46};
47
48/* wb_exit
49 * @wb_t :wb_t to exit
50 * */
51void
52mmu_wb_exit (wb_s * wb_t)
53{
54 int i;
55 wb_entry_t *wb;
56
57 wb = wb_t->entrys;
58 for (i = 0; i < wb_t->num; i++, wb++) {
59 free (wb->data);
60 }
61 free (wb_t->entrys);
62};
63
64/* wb_write_words :put words in Write Buffer
65 * @state: ARMul_State
66 * @wb_t: write buffer
67 * @pa: physical address
68 * @data: data ptr
69 * @n number of word to write
70 *
71 * Note: write buffer merge is not implemented, can be done late
72 * */
73void
74mmu_wb_write_bytes (ARMul_State * state, wb_s * wb_t, ARMword pa,
75 ARMbyte * data, int n)
76{
77 int i;
78 wb_entry_t *wb;
79
80 while (n) {
81 if (wb_t->num == wb_t->used) {
82 /*clean the last wb entry */
83 ARMword t;
84
85 wb = &wb_t->entrys[wb_t->last];
86 t = wb->pa;
87 for (i = 0; i < wb->nb; i++) {
88 //mem_write_byte (state, t, wb->data[i]);
89 bus_write(8, t, wb->data[i]);
90 //t += WORD_SIZE;
91 t++;
92 }
93 wb_t->last++;
94 if (wb_t->last == wb_t->num)
95 wb_t->last = 0;
96 wb_t->used--;
97 }
98
99 wb = &wb_t->entrys[wb_t->first];
100 i = (n < wb_t->nb) ? n : wb_t->nb;
101
102 wb->pa = pa;
103 //pa += i << WORD_SHT;
104 pa += i;
105
106 wb->nb = i;
107 //memcpy(wb->data, data, i << WORD_SHT);
108 memcpy (wb->data, data, i);
109 data += i;
110 n -= i;
111 wb_t->first++;
112 if (wb_t->first == wb_t->num)
113 wb_t->first = 0;
114 wb_t->used++;
115 };
116//teawater add for set_dirty fflash cache function 2005.07.18-------------------
117#ifdef DBCT
118 if (!skyeye_config.no_dbct) {
119 tb_setdirty (state, pa, NULL);
120 }
121#endif
122//AJ2D--------------------------------------------------------------------------
123}
124
125/* wb_drain_all
126 * @wb_t wb_t to drain
127 * */
128void
129mmu_wb_drain_all (ARMul_State * state, wb_s * wb_t)
130{
131 ARMword pa;
132 wb_entry_t *wb;
133 int i;
134
135 while (wb_t->used) {
136 wb = &wb_t->entrys[wb_t->last];
137 pa = wb->pa;
138 for (i = 0; i < wb->nb; i++) {
139 //mem_write_byte (state, pa, wb->data[i]);
140 bus_write(8, pa, wb->data[i]);
141 //pa += WORD_SIZE;
142 pa++;
143 }
144 wb_t->last++;
145 if (wb_t->last == wb_t->num)
146 wb_t->last = 0;
147 wb_t->used--;
148 };
149}
diff --git a/src/core/arm/interpreter/mmu/wb.h b/src/core/arm/interpreter/mmu/wb.h
deleted file mode 100644
index 8fb7de946..000000000
--- a/src/core/arm/interpreter/mmu/wb.h
+++ /dev/null
@@ -1,63 +0,0 @@
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/arm/interpreter/mmu/xscale_copro.cpp b/src/core/arm/interpreter/mmu/xscale_copro.cpp
deleted file mode 100644
index 433ce8e02..000000000
--- a/src/core/arm/interpreter/mmu/xscale_copro.cpp
+++ /dev/null
@@ -1,1391 +0,0 @@
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
24#include "core/arm/interpreter/armdefs.h"
25#include "core/arm/interpreter/armemu.h"
26
27/*#include "pxa.h" */
28
29/* chy 2005-09-19 */
30
31/* extern pxa270_io_t pxa270_io; */
32/* chy 2005-09-19 -----end */
33
34typedef struct xscale_mmu_desc_s
35{
36 int i_tlb;
37 cache_desc_t i_cache;
38
39 int d_tlb;
40 cache_desc_t main_d_cache;
41 cache_desc_t mini_d_cache;
42 //int rb; xscale has no read buffer
43 wb_desc_t wb;
44} xscale_mmu_desc_t;
45
46static xscale_mmu_desc_t pxa_mmu_desc = {
47 32,
48 {32, 32, 32, CACHE_WRITE_BACK},
49
50 32,
51 {32, 32, 32, CACHE_WRITE_BACK},
52 {32, 2, 8, CACHE_WRITE_BACK},
53 {8, 16}, //for byte size,
54};
55
56//chy 2005-09-19 for cp6
57#define CR0_ICIP 0
58#define CR1_ICMR 1
59//chy 2005-09-19 ---end
60//----------- for cp14-----------------
61#define CCLKCFG 6
62#define PWRMODE 7
63typedef struct xscale_cp14_reg_s
64{
65 unsigned cclkcfg; //reg6
66 unsigned pwrmode; //reg7
67} xscale_cp14_reg_s;
68
69xscale_cp14_reg_s pxa_cp14_regs;
70
71//--------------------------------------
72
73static fault_t xscale_mmu_write (ARMul_State * state, ARMword va,
74 ARMword data, ARMword datatype);
75static fault_t xscale_mmu_read (ARMul_State * state, ARMword va,
76 ARMword * data, ARMword datatype);
77
78ARMword xscale_mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value);
79ARMword xscale_mmu_mcr (ARMul_State * state, ARMword instr, ARMword value);
80
81
82/* jeff add 2010.9.26 for pxa270 cp6*/
83#define PXA270_ICMR 0x40D00004
84#define PXA270_ICPR 0x40D00010
85#define PXA270_ICLR 0x40D00008
86//chy 2005-09-19 for xscale pxa27x cp6
87unsigned
88xscale_cp6_mrc (ARMul_State * state, unsigned type, ARMword instr,
89 ARMword * data)
90{
91 unsigned opcode_2 = BITS (5, 7);
92 unsigned CRm = BITS (0, 3);
93 unsigned reg = BITS (16, 19);
94 unsigned result;
95
96 //printf("SKYEYE: xscale_cp6_mrc:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,state->Reg[15], instr);
97
98 switch (reg) {
99 case CR0_ICIP: { // cp 6 reg 0
100 //printf("cp6_mrc cr0 ICIP \n");
101 /* *data = (pxa270_io.icmr & pxa270_io.icpr) & ~pxa270_io.iclr; */
102 /* use bus_read get the pxa270 machine registers 2010.9.26 jeff*/
103 int icmr, icpr, iclr;
104 bus_read(32, PXA270_ICMR, (uint32_t*)&icmr);
105 bus_read(32, PXA270_ICPR, (uint32_t*)&icpr);
106 bus_read(32, PXA270_ICLR, (uint32_t*)&iclr);
107 *data = (icmr & icpr) & ~iclr;
108 }
109 break;
110 case CR1_ICMR: { // cp 6 reg 1
111 //printf("cp6_mrc cr1 ICMR\n");
112 /* *data = pxa270_io.icmr; */
113 int icmr;
114 /* use bus_read get the pxa270 machine registers 2010.9.26 jeff*/
115 bus_read(32, PXA270_ICMR, (uint32_t*)&icmr);
116 *data = icmr;
117 }
118 break;
119 default:
120 *data = 0;
121 printf ("SKYEYE:cp6_mrc unknown cp6 regs!!!!!!\n");
122 printf ("SKYEYE: xscale_cp6_mrc:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n", opcode_2, CRm, reg, state->Reg[15], instr);
123 break;
124 }
125 return 0;
126}
127
128//chy 2005-09-19 end
129//xscale cp13 ----------------------------------------------------
130unsigned
131xscale_cp13_init (ARMul_State * state)
132{
133 //printf("SKYEYE: xscale_cp13_init: begin\n");
134 return 0;
135}
136
137unsigned
138xscale_cp13_exit (ARMul_State * state)
139{
140 //printf("SKYEYE: xscale_cp13_exit: begin\n");
141 return 0;
142}
143
144unsigned
145xscale_cp13_ldc (ARMul_State * state, unsigned type, ARMword instr,
146 ARMword data)
147{
148 printf ("SKYEYE: xscale_cp13_ldc: ERROR isn't existed,");
149 SKYEYE_OUTREGS (stderr);
150 fprintf (stderr, "\n");
151 // skyeye_exit (-1);
152 return 0; //No matter return value, only for compiler.
153}
154
155unsigned
156xscale_cp13_stc (ARMul_State * state, unsigned type, ARMword instr,
157 ARMword * data)
158{
159 printf ("SKYEYE: xscale_cp13_stc: ERROR isn't existed,");
160 SKYEYE_OUTREGS (stderr);
161 fprintf (stderr, "\n");
162 // skyeye_exit (-1);
163 return 0; //No matter return value, only for compiler.
164}
165
166unsigned
167xscale_cp13_mrc (ARMul_State * state, unsigned type, ARMword instr,
168 ARMword * data)
169{
170 printf ("SKYEYE: xscale_cp13_mrc: ERROR isn't existed,");
171 SKYEYE_OUTREGS (stderr);
172 fprintf (stderr, "\n");
173 // skyeye_exit (-1);
174 return 0; //No matter return value, only for compiler.
175}
176
177unsigned
178xscale_cp13_mcr (ARMul_State * state, unsigned type, ARMword instr,
179 ARMword data)
180{
181 printf ("SKYEYE: xscale_cp13_mcr: ERROR isn't existed,");
182 SKYEYE_OUTREGS (stderr);
183 fprintf (stderr, "\n");
184 // skyeye_exit (-1);
185 return 0; //No matter return value, only for compiler.
186}
187
188unsigned
189xscale_cp13_cdp (ARMul_State * state, unsigned type, ARMword instr)
190{
191 printf ("SKYEYE: xscale_cp13_cdp: ERROR isn't existed,");
192 SKYEYE_OUTREGS (stderr);
193 fprintf (stderr, "\n");
194 // skyeye_exit (-1);
195 return 0; //No matter return value, only for compiler.
196}
197
198unsigned
199xscale_cp13_read_reg (ARMul_State * state, unsigned reg, ARMword * data)
200{
201 printf ("SKYEYE: xscale_cp13_read_reg: ERROR isn't existed,");
202 SKYEYE_OUTREGS (stderr);
203 fprintf (stderr, "\n");
204 return 0;
205 //exit(-1);
206}
207
208unsigned
209xscale_cp13_write_reg (ARMul_State * state, unsigned reg, ARMword data)
210{
211 printf ("SKYEYE: xscale_cp13_write_reg: ERROR isn't existed,");
212 SKYEYE_OUTREGS (stderr);
213 fprintf (stderr, "\n");
214 // skyeye_exit (-1);
215 return 0; //No matter return value, only for compiler.
216}
217
218//------------------------------------------------------------------
219//xscale cp14 ----------------------------------------------------
220unsigned
221xscale_cp14_init (ARMul_State * state)
222{
223 //printf("SKYEYE: xscale_cp14_init: begin\n");
224 pxa_cp14_regs.cclkcfg = 0;
225 pxa_cp14_regs.pwrmode = 0;
226 return 0;
227}
228
229unsigned
230xscale_cp14_exit (ARMul_State * state)
231{
232 //printf("SKYEYE: xscale_cp14_exit: begin\n");
233 return 0;
234}
235
236unsigned
237xscale_cp14_ldc (ARMul_State * state, unsigned type, ARMword instr,
238 ARMword data)
239{
240 printf ("SKYEYE: xscale_cp14_ldc: ERROR isn't existed, reg15 0x%x\n",
241 state->Reg[15]);
242 SKYEYE_OUTREGS (stderr);
243 // skyeye_exit (-1);
244 return 0; //No matter return value, only for compiler.
245}
246
247unsigned
248xscale_cp14_stc (ARMul_State * state, unsigned type, ARMword instr,
249 ARMword * data)
250{
251 printf ("SKYEYE: xscale_cp14_stc: ERROR isn't existed, reg15 0x%x\n",
252 state->Reg[15]);
253 SKYEYE_OUTREGS (stderr);
254 // skyeye_exit (-1);
255 return 0; //No matter return value, only for compiler.
256}
257
258unsigned
259xscale_cp14_mrc (ARMul_State * state, unsigned type, ARMword instr,
260 ARMword * data)
261{
262 unsigned opcode_2 = BITS (5, 7);
263 unsigned CRm = BITS (0, 3);
264 unsigned reg = BITS (16, 19);
265 unsigned result;
266
267 //printf("SKYEYE: xscale_cp14_mrc:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,\
268 state->Reg[15], instr);
269
270 switch (reg) {
271 case CCLKCFG: // cp 14 reg 6
272 //printf("cp14_mrc cclkcfg \n");
273 *data = pxa_cp14_regs.cclkcfg;
274 break;
275 case PWRMODE: // cp 14 reg 7
276 //printf("cp14_mrc pwrmode \n");
277 *data = pxa_cp14_regs.pwrmode;
278 break;
279 default:
280 *data = 0;
281 printf ("SKYEYE:cp14_mrc unknown cp14 regs!!!!!!\n");
282 break;
283 }
284 return 0;
285}
286unsigned xscale_cp14_mcr (ARMul_State * state, unsigned type, ARMword instr,
287 ARMword data)
288{
289 unsigned opcode_2 = BITS (5, 7);
290 unsigned CRm = BITS (0, 3);
291 unsigned reg = BITS (16, 19);
292 unsigned result;
293
294 //printf("SKYEYE: xscale_cp14_mcr:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,\
295 state->Reg[15], instr);
296
297 switch (reg) {
298 case CCLKCFG: // cp 14 reg 6
299 //printf("cp14_mcr cclkcfg \n");
300 pxa_cp14_regs.cclkcfg = data & 0xf;
301 break;
302 case PWRMODE: // cp 14 reg 7
303 //printf("cp14_mcr pwrmode \n");
304 pxa_cp14_regs.pwrmode = data & 0x3;
305 break;
306 default:printf ("SKYEYE: cp14_mcr unknown cp14 regs!!!!!!\n");
307 break;
308 }
309 return 0;
310}
311unsigned xscale_cp14_cdp (ARMul_State * state, unsigned type, ARMword instr)
312{
313 printf ("SKYEYE: xscale_cp14_cdp: ERROR isn't existed, reg15 0x%x\n",
314 state->Reg[15]);
315 SKYEYE_OUTREGS (stderr);
316 // skyeye_exit (-1);
317 return 0; //No matter return value, only for compiler.
318}
319unsigned xscale_cp14_read_reg (ARMul_State * state, unsigned reg,
320 ARMword * data)
321{
322 printf ("SKYEYE: xscale_cp14_read_reg: ERROR isn't existed, reg15 0x%x\n", state->Reg[15]);
323 SKYEYE_OUTREGS (stderr);
324 // skyeye_exit (-1);
325 return 0; //No matter return value, only for compiler.
326}
327unsigned xscale_cp14_write_reg (ARMul_State * state, unsigned reg,
328 ARMword data)
329{
330 printf ("SKYEYE: xscale_cp14_write_reg: ERROR isn't existed, reg15 0x%x\n", state->Reg[15]);
331 SKYEYE_OUTREGS (stderr);
332 // skyeye_exit (-1);
333
334 return 0; //No matter return value, only for compiler.
335}
336
337//------------------------------------------------------------------
338//cp15 -------------------------------------
339unsigned xscale_cp15_ldc (ARMul_State * state, unsigned type, ARMword instr,
340 ARMword data)
341{
342 printf ("SKYEYE: xscale_cp15_ldc: ERROR isn't existed\n");
343 SKYEYE_OUTREGS (stderr);
344 // skyeye_exit (-1);
345
346 return 0; //No matter return value, only for compiler.
347}
348unsigned xscale_cp15_stc (ARMul_State * state, unsigned type, ARMword instr,
349 ARMword * data)
350{
351 printf ("SKYEYE: xscale_cp15_stc: ERROR isn't existed\n");
352 SKYEYE_OUTREGS (stderr);
353 // skyeye_exit (-1);
354
355 return 0; //No matter return value, only for compiler.
356}
357unsigned xscale_cp15_cdp (ARMul_State * state, unsigned type, ARMword instr)
358{
359 printf ("SKYEYE: xscale_cp15_cdp: ERROR isn't existed\n");
360 SKYEYE_OUTREGS (stderr);
361 // skyeye_exit (-1);
362
363 return 0; //No matter return value, only for compiler.
364}
365unsigned xscale_cp15_read_reg (ARMul_State * state, unsigned reg,
366 ARMword * data)
367{
368//chy 2003-09-03: for xsacle_cp15_cp_access_allowed
369 if (reg == 15) {
370 *data = state->mmu.copro_access;
371 //printf("SKYEYE: xscale_cp15_read_reg: reg 0x%x,data %x\n",reg,*data);
372 return 0;
373 }
374 printf ("SKYEYE: xscale_cp15_read_reg: reg 0x%x, ERROR isn't existed\n", reg);
375 SKYEYE_OUTREGS (stderr);
376 // skyeye_exit (-1);
377
378 return 0; //No matter return value, only for compiler.
379}
380
381//chy 2003-09-03 used by macro CP_ACCESS_ALLOWED in armemu.h
382unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg,
383 unsigned cpnum)
384{
385 unsigned data;
386
387 xscale_cp15_read_reg (state, reg, &data);
388 //printf("SKYEYE: cp15_cp_access_allowed data %x, cpnum %x, result %x\n", data, cpnum, (data & 1<<cpnum));
389 if (data & 1 << cpnum)
390 return 1;
391 else
392 return 0;
393}
394
395unsigned xscale_cp15_write_reg (ARMul_State * state, unsigned reg,
396 ARMword value)
397{
398 switch (reg) {
399 case MMU_FAULT_STATUS:
400 //printf("SKYEYE:cp15_write_reg wrote FS val 0x%x \n",value);
401 state->mmu.fault_status = value & 0x6FF;
402 break;
403 case MMU_FAULT_ADDRESS:
404 //printf("SKYEYE:cp15_write_reg wrote FA val 0x%x \n",value);
405 state->mmu.fault_address = value;
406 break;
407 default:
408 printf ("SKYEYE: xscale_cp15_write_reg: reg 0x%x R15 %x ERROR isn't existed\n", reg, state->Reg[15]);
409 SKYEYE_OUTREGS (stderr);
410 // skyeye_exit (-1);
411 }
412 return 0;
413}
414
415unsigned
416xscale_cp15_init (ARMul_State * state)
417{
418 xscale_mmu_desc_t *desc;
419 cache_desc_t *c_desc;
420
421 state->mmu.control = 0;
422 state->mmu.translation_table_base = 0xDEADC0DE;
423 state->mmu.domain_access_control = 0xDEADC0DE;
424 state->mmu.fault_status = 0;
425 state->mmu.fault_address = 0;
426 state->mmu.process_id = 0;
427 state->mmu.cache_type = 0xB1AA1AA; //0000 1011 0001 1010 1010 0001 1010 1010
428 state->mmu.aux_control = 0;
429
430 desc = &pxa_mmu_desc;
431
432 if (mmu_tlb_init (I_TLB (), desc->i_tlb)) {
433 ERROR_LOG(ARM11, "i_tlb init %d\n", -1);
434 goto i_tlb_init_error;
435 }
436
437 c_desc = &desc->i_cache;
438 if (mmu_cache_init (I_CACHE (), c_desc->width, c_desc->way,
439 c_desc->set, c_desc->w_mode)) {
440 ERROR_LOG(ARM11, "i_cache init %d\n", -1);
441 goto i_cache_init_error;
442 }
443
444 if (mmu_tlb_init (D_TLB (), desc->d_tlb)) {
445 ERROR_LOG(ARM11, "d_tlb init %d\n", -1);
446 goto d_tlb_init_error;
447 }
448
449 c_desc = &desc->main_d_cache;
450 if (mmu_cache_init (MAIN_D_CACHE (), c_desc->width, c_desc->way,
451 c_desc->set, c_desc->w_mode)) {
452 ERROR_LOG(ARM11, "main_d_cache init %d\n", -1);
453 goto main_d_cache_init_error;
454 }
455
456 c_desc = &desc->mini_d_cache;
457 if (mmu_cache_init (MINI_D_CACHE (), c_desc->width, c_desc->way,
458 c_desc->set, c_desc->w_mode)) {
459 ERROR_LOG(ARM11, "mini_d_cache init %d\n", -1);
460 goto mini_d_cache_init_error;
461 }
462
463 if (mmu_wb_init (WB (), desc->wb.num, desc->wb.nb)) {
464 ERROR_LOG(ARM11, "wb init %d\n", -1);
465 goto wb_init_error;
466 }
467#if 0
468 if (mmu_rb_init (RB (), desc->rb)) {
469 ERROR_LOG(ARM11, "rb init %d\n", -1);
470 goto rb_init_error;
471 }
472#endif
473
474 return 0;
475#if 0
476 rb_init_error:
477 mmu_wb_exit (WB ());
478#endif
479 wb_init_error:
480 mmu_cache_exit (MINI_D_CACHE ());
481 mini_d_cache_init_error:
482 mmu_cache_exit (MAIN_D_CACHE ());
483 main_d_cache_init_error:
484 mmu_tlb_exit (D_TLB ());
485 d_tlb_init_error:
486 mmu_cache_exit (I_CACHE ());
487 i_cache_init_error:
488 mmu_tlb_exit (I_TLB ());
489 i_tlb_init_error:
490 return -1;
491}
492
493unsigned
494xscale_cp15_exit (ARMul_State * state)
495{
496 //mmu_rb_exit(RB());
497 mmu_wb_exit (WB ());
498 mmu_cache_exit (MINI_D_CACHE ());
499 mmu_cache_exit (MAIN_D_CACHE ());
500 mmu_tlb_exit (D_TLB ());
501 mmu_cache_exit (I_CACHE ());
502 mmu_tlb_exit (I_TLB ());
503 return 0;
504};
505
506
507static fault_t
508 xscale_mmu_load_instr (ARMul_State * state, ARMword va,
509 ARMword * instr)
510{
511 fault_t fault;
512 tlb_entry_t *tlb;
513 cache_line_t *cache;
514 int c; //cache bit
515 ARMword pa; //physical addr
516
517 static int debug_count = 0; //used for debug
518
519 DEBUG_LOG(ARM11, "va = %x\n", va);
520
521 va = mmu_pid_va_map (va);
522 if (MMU_Enabled) {
523 /*align check */
524 if ((va & (INSN_SIZE - 1)) && MMU_Aligned) {
525 DEBUG_LOG(ARM11, "align\n");
526 return ALIGNMENT_FAULT;
527 }
528 else
529 va &= ~(INSN_SIZE - 1);
530
531 /*translate tlb */
532 fault = translate (state, va, I_TLB (), &tlb);
533 if (fault) {
534 DEBUG_LOG(ARM11, "translate\n");
535 return fault;
536 }
537
538 /*check access */
539 fault = check_access (state, va, tlb, 1);
540 if (fault) {
541 DEBUG_LOG(ARM11, "check_fault\n");
542 return fault;
543 }
544 }
545 //chy 2003-09-02 for test, don't use cache ?????
546#if 0
547 /*search cache no matter MMU enabled/disabled */
548 cache = mmu_cache_search (state, I_CACHE (), va);
549 if (cache) {
550 *instr = cache->data[va_cache_index (va, I_CACHE ())];
551 return 0;
552 }
553#endif
554 /*if MMU disabled or C flag is set alloc cache */
555 if (MMU_Disabled) {
556 c = 1;
557 pa = va;
558 }
559 else {
560 c = tlb_c_flag (tlb);
561 pa = tlb_va_to_pa (tlb, va);
562 }
563
564 //chy 2003-09-03 only read mem, don't use cache now,will change later ????
565 //*instr = mem_read_word (state, pa);
566 bus_read(32, pa, instr);
567#if 0
568//-----------------------------------------------------------
569 //chy 2003-09-02 for test????
570 if (pa >= 0xa01c8000 && pa <= 0xa01c8020) {
571 printf ("SKYEYE:load_instr: pa %x, va %x,instr %x, R15 %x\n",
572 pa, va, *instr, state->Reg[15]);
573 }
574
575//----------------------------------------------------------------------
576#endif
577 return NO_FAULT;
578
579 if (c) {
580 int index;
581
582 debug_count++;
583 cache = mmu_cache_alloc (state, I_CACHE (), va, pa);
584 index = va_cache_index (va, I_CACHE ());
585 *instr = cache->data[va_cache_index (va, I_CACHE ())];
586 }
587 else
588 //*instr = mem_read_word (state, pa);
589 bus_read(32, pa, instr);
590
591 return NO_FAULT;
592};
593
594
595
596static fault_t
597 xscale_mmu_read_byte (ARMul_State * state, ARMword virt_addr,
598 ARMword * data)
599{
600 //ARMword temp,offset;
601 fault_t fault;
602 fault = xscale_mmu_read (state, virt_addr, data, ARM_BYTE_TYPE);
603 return fault;
604}
605
606static fault_t
607 xscale_mmu_read_halfword (ARMul_State * state, ARMword virt_addr,
608 ARMword * data)
609{
610 //ARMword temp,offset;
611 fault_t fault;
612 fault = xscale_mmu_read (state, virt_addr, data, ARM_HALFWORD_TYPE);
613 return fault;
614}
615
616static fault_t
617 xscale_mmu_read_word (ARMul_State * state, ARMword virt_addr,
618 ARMword * data)
619{
620 return xscale_mmu_read (state, virt_addr, data, ARM_WORD_TYPE);
621}
622
623
624
625
626static fault_t
627 xscale_mmu_read (ARMul_State * state, ARMword va, ARMword * data,
628 ARMword datatype)
629{
630 fault_t fault;
631// rb_entry_t *rb;
632 tlb_entry_t *tlb;
633 cache_line_t *cache;
634 ARMword pa, real_va, temp, offset;
635 //chy 2003-09-02 for test ????
636 static unsigned chyst1 = 0, chyst2 = 0;
637
638 DEBUG_LOG(ARM11, "va = %x\n", va);
639
640 va = mmu_pid_va_map (va);
641 real_va = va;
642 /*if MMU disabled, memory_read */
643 if (MMU_Disabled) {
644 //*data = mem_read_word(state, va);
645 if (datatype == ARM_BYTE_TYPE)
646 //*data = mem_read_byte (state, va);
647 bus_read(8, va, data);
648 else if (datatype == ARM_HALFWORD_TYPE)
649 //*data = mem_read_halfword (state, va);
650 bus_read(16, va, data);
651 else if (datatype == ARM_WORD_TYPE)
652 //*data = mem_read_word (state, va);
653 bus_read(32, va, data);
654 else {
655 printf ("SKYEYE:1 xscale_mmu_read error: unknown data type %d\n", datatype);
656 // skyeye_exit (-1);
657 }
658
659 return NO_FAULT;
660 }
661
662 /*align check */
663 if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) ||
664 ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) {
665 DEBUG_LOG(ARM11, "align\n");
666 return ALIGNMENT_FAULT;
667 } // else
668
669 va &= ~(WORD_SIZE - 1);
670
671 /*translate va to tlb */
672 fault = translate (state, va, D_TLB (), &tlb);
673 if (fault) {
674 DEBUG_LOG(ARM11, "translate\n");
675 return fault;
676 }
677 /*check access permission */
678 fault = check_access (state, va, tlb, 1);
679 if (fault)
680 return fault;
681
682#if 0
683//------------------------------------------------
684//chy 2003-09-02 for test only ,should commit ????
685 if (datatype == ARM_WORD_TYPE) {
686 if (real_va >= 0xffff0000 && real_va <= 0xffff0020) {
687 pa = tlb_va_to_pa (tlb, va);
688 *data = mem_read_word (state, pa);
689 chyst1++;
690 printf ("**SKYEYE:mmu_read word %d: pa %x, va %x, data %x, R15 %x\n", chyst1, pa, real_va, *data, state->Reg[15]);
691 /*
692 cache==mmu_cache_search(state,MAIN_D_CACHE(),va);
693 if(cache){
694 *data = cache->data[va_cache_index(va, MAIN_D_CACHE())];
695 printf("cached data %x\n",*data);
696 }else printf("no cached data\n");
697 */
698 }
699 }
700//-------------------------------------------------
701#endif
702#if 0
703 /*search in read buffer */
704 rb = mmu_rb_search (RB (), va);
705 if (rb) {
706 if (rb->fault)
707 return rb->fault;
708 *data = rb->data[(va & (rb_masks[rb->type] - 1)) >> WORD_SHT];
709 goto datatrans;
710 //return 0;
711 };
712#endif
713
714 /*2004-07-19 chy: add support of xscale MMU CacheDisabled option */
715 if (MMU_CacheDisabled) {
716 //if(1){ can be used to test cache error
717 /*get phy_addr */
718 pa = tlb_va_to_pa (tlb, real_va);
719 if (datatype == ARM_BYTE_TYPE)
720 //*data = mem_read_byte (state, pa);
721 bus_read(8, pa, data);
722 else if (datatype == ARM_HALFWORD_TYPE)
723 //*data = mem_read_halfword (state, pa);
724 bus_read(16, pa, data);
725 else if (datatype == ARM_WORD_TYPE)
726 //*data = mem_read_word (state, pa);
727 bus_read(32, pa, data);
728 else {
729 printf ("SKYEYE:MMU_CacheDisabled xscale_mmu_read error: unknown data type %d\n", datatype);
730 // skyeye_exit (-1);
731 }
732 return NO_FAULT;
733 }
734
735
736 /*search main cache */
737 cache = mmu_cache_search (state, MAIN_D_CACHE (), va);
738 if (cache) {
739 *data = cache->data[va_cache_index (va, MAIN_D_CACHE ())];
740#if 0
741//------------------------------------------------------------------------
742//chy 2003-09-02 for test only ,should commit ????
743 if (real_va >= 0xffff0000 && real_va <= 0xffff0020) {
744 pa = tlb_va_to_pa (tlb, va);
745 chyst2++;
746 printf ("**SKYEYE:mmu_read wordk:cache %d: pa %x, va %x, data %x, R15 %x\n", chyst2, pa, real_va, *data, state->Reg[15]);
747 }
748//-------------------------------------------------------------------
749#endif
750 goto datatrans;
751 //return 0;
752 }
753 //chy 2003-08-24, now maybe we don't need minidcache ????
754#if 0
755 /*search mini cache */
756 cache = mmu_cache_search (state, MINI_D_CACHE (), va);
757 if (cache) {
758 *data = cache->data[va_cache_index (va, MINI_D_CACHE ())];
759 goto datatrans;
760 //return 0;
761 }
762#endif
763 /*get phy_addr */
764 pa = tlb_va_to_pa (tlb, va);
765 //chy 2003-08-24 , in xscale it means what ?????
766#if 0
767 if ((pa >= 0xe0000000) && (pa < 0xe8000000)) {
768
769 if (tlb_c_flag (tlb)) {
770 if (tlb_b_flag (tlb)) {
771 mmu_cache_soft_flush (state, MAIN_D_CACHE (),
772 pa);
773 }
774 else {
775 mmu_cache_soft_flush (state, MINI_D_CACHE (),
776 pa);
777 }
778 }
779 return 0;
780 }
781#endif
782 //chy 2003-08-24, check phy addr
783 //ywc 2004-11-30, inactive this check because of using 0xc0000000 as the framebuffer start address
784 /*
785 if(pa >= 0xb0000000){
786 printf("SKYEYE:xscale_mmu_read: phy address 0x%x error,reg[15] 0x%x\n",pa,state->Reg[15]);
787 return 0;
788 }
789 */
790
791 //chy 2003-08-24, now maybe we don't need wb ????
792#if 0
793 /*if Buffer, drain Write Buffer first */
794 if (tlb_b_flag (tlb))
795 mmu_wb_drain_all (state, WB ());
796#endif
797 /*alloc cache or mem_read */
798 if (tlb_c_flag (tlb) && MMU_DCacheEnabled) {
799 cache_s *cache_t;
800
801 if (tlb_b_flag (tlb))
802 cache_t = MAIN_D_CACHE ();
803 else
804 cache_t = MINI_D_CACHE ();
805 cache = mmu_cache_alloc (state, cache_t, va, pa);
806 *data = cache->data[va_cache_index (va, cache_t)];
807 }
808 else {
809 //*data = mem_read_word(state, pa);
810 if (datatype == ARM_BYTE_TYPE)
811 //*data = mem_read_byte (state, pa | (real_va & 3));
812 bus_read(8, pa | (real_va & 3), data);
813 else if (datatype == ARM_HALFWORD_TYPE)
814 //*data = mem_read_halfword (state, pa | (real_va & 2));
815 bus_read(16, pa | (real_va & 2), data);
816 else if (datatype == ARM_WORD_TYPE)
817 //*data = mem_read_word (state, pa);
818 bus_read(32, pa, data);
819 else {
820 printf ("SKYEYE:2 xscale_mmu_read error: unknown data type %d\n", datatype);
821 // skyeye_exit (-1);
822 }
823 return NO_FAULT;
824 }
825
826
827 datatrans:
828 if (datatype == ARM_HALFWORD_TYPE) {
829 temp = *data;
830 offset = (((ARMword) state->bigendSig * 2) ^ (real_va & 2)) << 3; /* bit offset into the word */
831 *data = (temp >> offset) & 0xffff;
832 }
833 else if (datatype == ARM_BYTE_TYPE) {
834 temp = *data;
835 offset = (((ARMword) state->bigendSig * 3) ^ (real_va & 3)) << 3; /* bit offset into the word */
836 *data = (temp >> offset & 0xffL);
837 }
838 end:
839 return NO_FAULT;
840}
841
842
843static fault_t
844 xscale_mmu_write_byte (ARMul_State * state, ARMword virt_addr,
845 ARMword data)
846{
847 return xscale_mmu_write (state, virt_addr, data, ARM_BYTE_TYPE);
848}
849
850static fault_t
851 xscale_mmu_write_halfword (ARMul_State * state, ARMword virt_addr,
852 ARMword data)
853{
854 return xscale_mmu_write (state, virt_addr, data, ARM_HALFWORD_TYPE);
855}
856
857static fault_t
858 xscale_mmu_write_word (ARMul_State * state, ARMword virt_addr,
859 ARMword data)
860{
861 return xscale_mmu_write (state, virt_addr, data, ARM_WORD_TYPE);
862}
863
864
865
866static fault_t
867 xscale_mmu_write (ARMul_State * state, ARMword va, ARMword data,
868 ARMword datatype)
869{
870 tlb_entry_t *tlb;
871 cache_line_t *cache;
872 cache_s *cache_t;
873 int b;
874 ARMword pa, real_va, temp, offset;
875 fault_t fault;
876
877 ARMword index;
878//chy 2003-09-02 for test ????
879// static unsigned chyst1=0,chyst2=0;
880
881 DEBUG_LOG(ARM11, "va = %x, val = %x\n", va, data);
882 va = mmu_pid_va_map (va);
883 real_va = va;
884
885 if (MMU_Disabled) {
886 //mem_write_word(state, va, data);
887 if (datatype == ARM_BYTE_TYPE)
888 //mem_write_byte (state, va, data);
889 bus_write(8, va, data);
890 else if (datatype == ARM_HALFWORD_TYPE)
891 //mem_write_halfword (state, va, data);
892 bus_write(16, va, data);
893 else if (datatype == ARM_WORD_TYPE)
894 //mem_write_word (state, va, data);
895 bus_write(32, va, data);
896 else {
897 printf ("SKYEYE:1 xscale_mmu_write error: unknown data type %d\n", datatype);
898 // skyeye_exit (-1);
899 }
900
901 return NO_FAULT;
902 }
903 /*align check */
904 if (((va & 3) && (datatype == ARM_WORD_TYPE) && MMU_Aligned) ||
905 ((va & 1) && (datatype == ARM_HALFWORD_TYPE) && MMU_Aligned)) {
906 DEBUG_LOG(ARM11, "align\n");
907 return ALIGNMENT_FAULT;
908 } //else
909 va &= ~(WORD_SIZE - 1);
910 /*tlb translate */
911 fault = translate (state, va, D_TLB (), &tlb);
912 if (fault) {
913 DEBUG_LOG(ARM11, "translate\n");
914 return fault;
915 }
916 /*tlb check access */
917 fault = check_access (state, va, tlb, 0);
918 if (fault) {
919 DEBUG_LOG(ARM11, "check_access\n");
920 return fault;
921 }
922
923 /*2004-07-19 chy: add support for xscale MMU_CacheDisabled */
924 if (MMU_CacheDisabled) {
925 //if(1){ can be used to test the cache error
926 /*get phy_addr */
927 pa = tlb_va_to_pa (tlb, real_va);
928 if (datatype == ARM_BYTE_TYPE)
929 //mem_write_byte (state, pa, data);
930 bus_write(8, pa, data);
931 else if (datatype == ARM_HALFWORD_TYPE)
932 //mem_write_halfword (state, pa, data);
933 bus_write(16, pa, data);
934 else if (datatype == ARM_WORD_TYPE)
935 //mem_write_word (state, pa, data);
936 bus_write(32, pa , data);
937 else {
938 printf ("SKYEYE:MMU_CacheDisabled xscale_mmu_write error: unknown data type %d\n", datatype);
939 // skyeye_exit (-1);
940 }
941
942 return NO_FAULT;
943 }
944
945 /*search main cache */
946 b = tlb_b_flag (tlb);
947 pa = tlb_va_to_pa (tlb, va);
948 cache = mmu_cache_search (state, MAIN_D_CACHE (), va);
949 if (cache) {
950 cache_t = MAIN_D_CACHE ();
951 goto has_cache;
952 }
953 //chy 2003-08-24, now maybe we don't need minidcache ????
954#if 0
955 /*search mini cache */
956 cache = mmu_cache_search (state, MINI_D_CACHE (), va);
957 if (cache) {
958 cache_t = MINI_D_CACHE ();
959 goto has_cache;
960 }
961#endif
962 b = tlb_b_flag (tlb);
963 pa = tlb_va_to_pa (tlb, va);
964 //chy 2003-08-24, check phy addr 0xa0000000, size 0x04000000
965 //ywc 2004-11-30, inactive this check because of using 0xc0000000 as the framebuffer start address
966 /*
967 if(pa >= 0xb0000000){
968 printf("SKYEYE:xscale_mmu_write phy address 0x%x error,reg[15] 0x%x\n",pa,state->Reg[15]);
969 return 0;
970 }
971 */
972
973 //chy 2003-08-24, now maybe we don't need WB ????
974#if 0
975 if (b) {
976 if (MMU_WBEnabled) {
977 if (datatype == ARM_WORD_TYPE)
978 mmu_wb_write_bytes (state, WB (), pa, &data,
979 4);
980 else if (datatype == ARM_HALFWORD_TYPE)
981 mmu_wb_write_bytes (state, WB (),
982 (pa | (real_va & 2)),
983 &data, 2);
984 else if (datatype == ARM_BYTE_TYPE)
985 mmu_wb_write_bytes (state, WB (),
986 (pa | (real_va & 3)),
987 &data, 1);
988
989 }
990 else {
991 if (datatype == ARM_WORD_TYPE)
992 mem_write_word (state, pa, data);
993 else if (datatype == ARM_HALFWORD_TYPE)
994 mem_write_halfword (state,
995 (pa | (real_va & 2)),
996 data);
997 else if (datatype == ARM_BYTE_TYPE)
998 mem_write_byte (state, (pa | (real_va & 3)),
999 data);
1000 }
1001 }
1002 else {
1003
1004 mmu_wb_drain_all (state, WB ());
1005
1006 if (datatype == ARM_WORD_TYPE)
1007 mem_write_word (state, pa, data);
1008 else if (datatype == ARM_HALFWORD_TYPE)
1009 mem_write_halfword (state, (pa | (real_va & 2)),
1010 data);
1011 else if (datatype == ARM_BYTE_TYPE)
1012 mem_write_byte (state, (pa | (real_va & 3)), data);
1013 }
1014#endif
1015 //chy 2003-08-24, just write phy addr
1016 if (datatype == ARM_WORD_TYPE)
1017 //mem_write_word (state, pa, data);
1018 bus_write(32, pa, data);
1019 else if (datatype == ARM_HALFWORD_TYPE)
1020 //mem_write_halfword (state, (pa | (real_va & 2)), data);
1021 bus_write(16, pa | (real_va & 2), data);
1022 else if (datatype == ARM_BYTE_TYPE)
1023 //mem_write_byte (state, (pa | (real_va & 3)), data);
1024 bus_write(8, (pa | (real_va & 3)), data);
1025#if 0
1026//-------------------------------------------------------------
1027//chy 2003-09-02 for test ????
1028 if (datatype == ARM_WORD_TYPE) {
1029 if (real_va >= 0xffff0000 && real_va <= 0xffff0020) {
1030 printf ("**SKYEYE:mmu_write word: pa %x, va %x, data %x, R15 %x \n", pa, real_va, data, state->Reg[15]);
1031 }
1032 }
1033//--------------------------------------------------------------
1034#endif
1035 return NO_FAULT;
1036
1037 has_cache:
1038 index = va_cache_index (va, cache_t);
1039 //cache->data[index] = data;
1040
1041 if (datatype == ARM_WORD_TYPE)
1042 cache->data[index] = data;
1043 else if (datatype == ARM_HALFWORD_TYPE) {
1044 temp = cache->data[index];
1045 offset = (((ARMword) state->bigendSig * 2) ^ (real_va & 2)) << 3; /* bit offset into the word */
1046 cache->data[index] =
1047 (temp & ~(0xffffL << offset)) | ((data & 0xffffL) <<
1048 offset);
1049 }
1050 else if (datatype == ARM_BYTE_TYPE) {
1051 temp = cache->data[index];
1052 offset = (((ARMword) state->bigendSig * 3) ^ (real_va & 3)) << 3; /* bit offset into the word */
1053 cache->data[index] =
1054 (temp & ~(0xffL << offset)) | ((data & 0xffL) <<
1055 offset);
1056 }
1057
1058 if (index < (cache_t->width >> (WORD_SHT + 1)))
1059 cache->tag |= TAG_FIRST_HALF_DIRTY;
1060 else
1061 cache->tag |= TAG_LAST_HALF_DIRTY;
1062//-------------------------------------------------------------
1063//chy 2003-09-03 be sure the changed value will be in memory as soon as possible, so I cache can get the newest value
1064#if 0
1065 {
1066 if (datatype == ARM_WORD_TYPE)
1067 mem_write_word (state, pa, data);
1068 else if (datatype == ARM_HALFWORD_TYPE)
1069 mem_write_halfword (state, (pa | (real_va & 2)),
1070 data);
1071 else if (datatype == ARM_BYTE_TYPE)
1072 mem_write_byte (state, (pa | (real_va & 3)), data);
1073 }
1074#endif
1075#if 0
1076//chy 2003-09-02 for test ????
1077 if (datatype == ARM_WORD_TYPE) {
1078 if (real_va >= 0xffff0000 && real_va <= 0xffff0020) {
1079 printf ("**SKYEYE:mmu_write word:cache: pa %x, va %x, data %x, R15 %x\n", pa, real_va, data, state->Reg[15]);
1080 }
1081 }
1082//-------------------------------------------------------------
1083#endif
1084 if (datatype == ARM_WORD_TYPE)
1085 //mem_write_word (state, pa, data);
1086 bus_write(32, pa, data);
1087 else if (datatype == ARM_HALFWORD_TYPE)
1088 //mem_write_halfword (state, (pa | (real_va & 2)), data);
1089 bus_write(16, pa | (real_va & 2), data);
1090 else if (datatype == ARM_BYTE_TYPE)
1091 //mem_write_byte (state, (pa | (real_va & 3)), data);
1092 bus_write(8, (pa | (real_va & 3)), data);
1093 return NO_FAULT;
1094}
1095
1096ARMword xscale_cp15_mrc (ARMul_State * state,
1097 unsigned type, ARMword instr, ARMword * value)
1098{
1099 return xscale_mmu_mrc (state, instr, value);
1100}
1101
1102ARMword xscale_mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value)
1103{
1104 ARMword data;
1105 unsigned opcode_2 = BITS (5, 7);
1106 unsigned CRm = BITS (0, 3);
1107 unsigned reg = BITS (16, 19);
1108 unsigned result;
1109 mmu_regnum_t creg = (mmu_regnum_t)reg;
1110
1111/*
1112 printf("SKYEYE: xscale_cp15_mrc:opcode_2 0x%x, CRm 0x%x, reg 0x%x,reg[15] 0x%x, instr %x\n",opcode_2,CRm,reg,\
1113 state->Reg[15], instr);
1114*/
1115 switch (creg) {
1116 case MMU_ID: //XSCALE_CP15
1117 //printf("mmu_mrc read ID \n");
1118 data = (opcode_2 ? state->mmu.cache_type : state->cpu->
1119 cpu_val);
1120 break;
1121 case MMU_CONTROL: //XSCALE_CP15_AUX_CONTROL
1122 //printf("mmu_mrc read CONTROL \n");
1123 data = (opcode_2 ? state->mmu.aux_control : state->mmu.
1124 control);
1125 break;
1126 case MMU_TRANSLATION_TABLE_BASE:
1127 //printf("mmu_mrc read TTB \n");
1128 data = state->mmu.translation_table_base;
1129 break;
1130 case MMU_DOMAIN_ACCESS_CONTROL:
1131 //printf("mmu_mrc read DACR \n");
1132 data = state->mmu.domain_access_control;
1133 break;
1134 case MMU_FAULT_STATUS:
1135 //printf("mmu_mrc read FSR \n");
1136 data = state->mmu.fault_status;
1137 break;
1138 case MMU_FAULT_ADDRESS:
1139 //printf("mmu_mrc read FAR \n");
1140 data = state->mmu.fault_address;
1141 break;
1142 case MMU_PID:
1143 //printf("mmu_mrc read PID \n");
1144 data = state->mmu.process_id;
1145 case XSCALE_CP15_COPRO_ACCESS:
1146 //printf("xscale cp15 read coprocessor access\n");
1147 data = state->mmu.copro_access;
1148 break;
1149 default:
1150 data = 0;
1151 printf ("SKYEYE: xscale_cp15_mrc read UNKNOWN - reg %d, pc 0x%x\n", creg, state->Reg[15]);
1152 // skyeye_exit (-1);
1153 break;
1154 }
1155 *value = data;
1156 //printf("SKYEYE: xscale_cp15_mrc:end value 0x%x\n",data);
1157 return ARMul_DONE;
1158}
1159
1160void xscale_cp15_cache_ops (ARMul_State * state, ARMword instr, ARMword value)
1161{
1162//chy: 2003-08-24 now, the BTB isn't simualted ....????
1163
1164 unsigned CRm, OPC_2;
1165
1166 CRm = BITS (0, 3);
1167 OPC_2 = BITS (5, 7);
1168 //err_msg("SKYEYE: xscale cp15_cache_ops:OPC_2 = 0x%x CRm = 0x%x, Reg15 0x%x\n", OPC_2, CRm,state->Reg[15]);
1169
1170 if (OPC_2 == 0 && CRm == 7) {
1171 mmu_cache_invalidate_all (state, I_CACHE ());
1172 mmu_cache_invalidate_all (state, MAIN_D_CACHE ());
1173 return;
1174 }
1175
1176 if (OPC_2 == 0 && CRm == 5) {
1177 mmu_cache_invalidate_all (state, I_CACHE ());
1178 return;
1179 }
1180 if (OPC_2 == 1 && CRm == 5) {
1181 mmu_cache_invalidate (state, I_CACHE (), value);
1182 return;
1183 }
1184
1185 if (OPC_2 == 0 && CRm == 6) {
1186 mmu_cache_invalidate_all (state, MAIN_D_CACHE ());
1187 return;
1188 }
1189
1190 if (OPC_2 == 1 && CRm == 6) {
1191 mmu_cache_invalidate (state, MAIN_D_CACHE (), value);
1192 return;
1193 }
1194
1195 if (OPC_2 == 1 && CRm == 0xa) {
1196 mmu_cache_clean (state, MAIN_D_CACHE (), value);
1197 return;
1198 }
1199
1200 if (OPC_2 == 4 && CRm == 0xa) {
1201 mmu_wb_drain_all (state, WB ());
1202 return;
1203 }
1204
1205 if (OPC_2 == 6 && CRm == 5) {
1206 //chy 2004-07-19 shoud fix in the future????!!!!
1207 //printf("SKYEYE: xscale_cp15_cache_ops:invalidate BTB CANT!!!!!!!!!!\n");
1208 //exit(-1);
1209 return;
1210 }
1211
1212 if (OPC_2 == 5 && CRm == 2) {
1213 //printf("SKYEYE: cp15_c_o: A L in D C, value %x, reg15 %x\n",value, state->Reg[15]);
1214 //exit(-1);
1215 //chy 2003-09-01 for test
1216 mmu_cache_invalidate_all (state, MAIN_D_CACHE ());
1217 return;
1218 }
1219
1220 ERROR_LOG(ARM11, "SKYEYE: xscale cp15_cache_ops:Unknown OPC_2 = 0x%x CRm = 0x%x, Reg15 0x%x\n", OPC_2, CRm, state->Reg[15]);
1221 // skyeye_exit (-1);
1222}
1223
1224static void
1225 xscale_cp15_tlb_ops (ARMul_State * state, ARMword instr,
1226 ARMword value)
1227{
1228 int CRm, OPC_2;
1229
1230 CRm = BITS (0, 3);
1231 OPC_2 = BITS (5, 7);
1232
1233
1234 //err_msg("SKYEYE:xscale_cp15_tlb_ops:OPC_2 = 0x%x CRm = 0x%x,Reg[15] 0x%x\n", OPC_2, CRm,state->Reg[15]);
1235 if (OPC_2 == 0 && CRm == 0x7) {
1236 mmu_tlb_invalidate_all (state, I_TLB ());
1237 mmu_tlb_invalidate_all (state, D_TLB ());
1238 return;
1239 }
1240
1241 if (OPC_2 == 0 && CRm == 0x5) {
1242 mmu_tlb_invalidate_all (state, I_TLB ());
1243 return;
1244 }
1245
1246 if (OPC_2 == 1 && CRm == 0x5) {
1247 mmu_tlb_invalidate_entry (state, I_TLB (), value);
1248 return;
1249 }
1250
1251 if (OPC_2 == 0 && CRm == 0x6) {
1252 mmu_tlb_invalidate_all (state, D_TLB ());
1253 return;
1254 }
1255
1256 if (OPC_2 == 1 && CRm == 0x6) {
1257 mmu_tlb_invalidate_entry (state, D_TLB (), value);
1258 return;
1259 }
1260
1261 ERROR_LOG(ARM11, "SKYEYE:xscale_cp15_tlb_ops:Unknow OPC_2 = 0x%x CRm = 0x%x,Reg[15] 0x%x\n", OPC_2, CRm, state->Reg[15]);
1262 // skyeye_exit (-1);
1263}
1264
1265
1266ARMword xscale_cp15_mcr (ARMul_State * state,
1267 unsigned type, ARMword instr, ARMword value)
1268{
1269 return xscale_mmu_mcr (state, instr, value);
1270}
1271
1272ARMword xscale_mmu_mcr (ARMul_State * state, ARMword instr, ARMword value)
1273{
1274 ARMword data;
1275 unsigned opcode_2 = BITS (5, 7);
1276 unsigned CRm = BITS (0, 3);
1277 unsigned reg = BITS (16, 19);
1278 unsigned result;
1279 mmu_regnum_t creg = (mmu_regnum_t)reg;
1280
1281 //printf("SKYEYE: xscale_cp15_mcr: opcode_2 0x%x, CRm 0x%x, reg ox%x, value 0x%x, reg[15] 0x%x, instr 0x%x\n",opcode_2,CRm,reg, value, state->Reg[15], instr);
1282
1283 switch (creg) {
1284 case MMU_CONTROL:
1285 //printf("mmu_mcr wrote CONTROL val 0x%x \n",value);
1286 state->mmu.control =
1287 (opcode_2 ? (value & 0x33) : (value & 0x3FFF));
1288 break;
1289 case MMU_TRANSLATION_TABLE_BASE:
1290 //printf("mmu_mcr wrote TTB val 0x%x \n",value);
1291 state->mmu.translation_table_base = value & 0xFFFFC000;
1292 break;
1293 case MMU_DOMAIN_ACCESS_CONTROL:
1294 //printf("mmu_mcr wrote DACR val 0x%x \n",value);
1295 state->mmu.domain_access_control = value;
1296 break;
1297
1298 case MMU_FAULT_STATUS:
1299 //printf("mmu_mcr wrote FS val 0x%x \n",value);
1300 state->mmu.fault_status = value & 0x6FF;
1301 break;
1302 case MMU_FAULT_ADDRESS:
1303 //printf("mmu_mcr wrote FA val 0x%x \n",value);
1304 state->mmu.fault_address = value;
1305 break;
1306
1307 case MMU_CACHE_OPS:
1308// printf("mmu_mcr wrote CO val 0x%x \n",value);
1309 xscale_cp15_cache_ops (state, instr, value);
1310 break;
1311 case MMU_TLB_OPS:
1312 //printf("mmu_mcr wrote TO val 0x%x \n",value);
1313 xscale_cp15_tlb_ops (state, instr, value);
1314 break;
1315 case MMU_PID:
1316 //printf("mmu_mcr wrote PID val 0x%x \n",value);
1317 state->mmu.process_id = value & 0xfe000000;
1318 break;
1319 case XSCALE_CP15_COPRO_ACCESS:
1320 //printf("xscale cp15 write coprocessor access val 0x %x\n",value);
1321 state->mmu.copro_access = value & 0x3ff;
1322 break;
1323
1324 default:
1325 printf ("SKYEYE: xscale_cp15_mcr wrote UNKNOWN - reg %d, reg15 0x%x\n", creg, state->Reg[15]);
1326 break;
1327 }
1328 //printf("SKYEYE: xscale_cp15_mcr wrote val 0x%x\n", value);
1329 return 0;
1330}
1331
1332//teawater add for arm2x86 2005.06.24-------------------------------------------
1333static int xscale_mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr,
1334 ARMword * phys_addr)
1335{
1336 fault_t fault;
1337 tlb_entry_t *tlb;
1338
1339 virt_addr = mmu_pid_va_map (virt_addr);
1340 if (MMU_Enabled) {
1341
1342 /*align check */
1343 if ((virt_addr & (WORD_SIZE - 1)) && MMU_Aligned) {
1344 DEBUG_LOG(ARM11, "align\n");
1345 return ALIGNMENT_FAULT;
1346 }
1347 else
1348 virt_addr &= ~(WORD_SIZE - 1);
1349
1350 /*translate tlb */
1351 fault = translate (state, virt_addr, I_TLB (), &tlb);
1352 if (fault) {
1353 DEBUG_LOG(ARM11, "translate\n");
1354 return fault;
1355 }
1356
1357 /*check access */
1358 fault = check_access (state, virt_addr, tlb, 1);
1359 if (fault) {
1360 DEBUG_LOG(ARM11, "check_fault\n");
1361 return fault;
1362 }
1363 }
1364
1365 if (MMU_Disabled) {
1366 *phys_addr = virt_addr;
1367 }
1368 else {
1369 *phys_addr = tlb_va_to_pa (tlb, virt_addr);
1370 }
1371
1372 return (0);
1373}
1374
1375//AJ2D--------------------------------------------------------------------------
1376
1377/*xscale mmu_ops_t*/
1378//mmu_ops_t xscale_mmu_ops = {
1379// xscale_cp15_init,
1380// xscale_cp15_exit,
1381// xscale_mmu_read_byte,
1382// xscale_mmu_write_byte,
1383// xscale_mmu_read_halfword,
1384// xscale_mmu_write_halfword,
1385// xscale_mmu_read_word,
1386// xscale_mmu_write_word,
1387// xscale_mmu_load_instr, xscale_mmu_mcr, xscale_mmu_mrc,
1388////teawater add for arm2x86 2005.06.24-------------------------------------------
1389// xscale_mmu_v2p_dbct,
1390////AJ2D--------------------------------------------------------------------------
1391//};
diff --git a/src/core/arm/interpreter/thumbemu.cpp b/src/core/arm/interpreter/thumbemu.cpp
index 032d84b65..f7f11f714 100644
--- a/src/core/arm/interpreter/thumbemu.cpp
+++ b/src/core/arm/interpreter/thumbemu.cpp
@@ -19,7 +19,7 @@
19instruction into its corresponding ARM instruction, and using the 19instruction into its corresponding ARM instruction, and using the
20existing ARM simulator. */ 20existing ARM simulator. */
21 21
22#include "skyeye_defs.h" 22#include "core/arm/skyeye_common/skyeye_defs.h"
23 23
24#ifndef MODET /* required for the Thumb instruction support */ 24#ifndef MODET /* required for the Thumb instruction support */
25#if 1 25#if 1
@@ -29,9 +29,9 @@ existing ARM simulator. */
29#endif 29#endif
30#endif 30#endif
31 31
32#include "armdefs.h" 32#include "core/arm/skyeye_common/armdefs.h"
33#include "armemu.h" 33#include "core/arm/skyeye_common/armemu.h"
34#include "armos.h" 34#include "core/arm/skyeye_common/armos.h"
35 35
36 36
37/* Decode a 16bit Thumb instruction. The instruction is in the low 37/* Decode a 16bit Thumb instruction. The instruction is in the low
diff --git a/src/core/arm/interpreter/arm_regformat.h b/src/core/arm/skyeye_common/arm_regformat.h
index 0ca62780b..4dac1a8bf 100644
--- a/src/core/arm/interpreter/arm_regformat.h
+++ b/src/core/arm/skyeye_common/arm_regformat.h
@@ -99,5 +99,7 @@ enum arm_regno{
99 MAX_REG_NUM, 99 MAX_REG_NUM,
100}; 100};
101 101
102#define VFP_OFFSET(x) (x - VFP_BASE) 102#define CP15(idx) (idx - CP15_BASE)
103#define VFP_OFFSET(x) (x - VFP_BASE)
104
103#endif 105#endif
diff --git a/src/core/arm/interpreter/armcpu.h b/src/core/arm/skyeye_common/armcpu.h
index 6b5ea8566..3a029f0e7 100644
--- a/src/core/arm/interpreter/armcpu.h
+++ b/src/core/arm/skyeye_common/armcpu.h
@@ -20,16 +20,13 @@
20 20
21#ifndef __ARM_CPU_H__ 21#ifndef __ARM_CPU_H__
22#define __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 23
28#include <stddef.h> 24#include <stddef.h>
29#include <stdio.h> 25#include <stdio.h>
30 26
31#include "common/thread.h" 27#include "common/thread.h"
32 28
29#include "core/arm/skyeye_common/armdefs.h"
33 30
34typedef struct ARM_CPU_State_s { 31typedef struct ARM_CPU_State_s {
35 ARMul_State * core; 32 ARMul_State * core;
diff --git a/src/core/arm/interpreter/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
index dd5983be3..8e71948c6 100644
--- a/src/core/arm/interpreter/armdefs.h
+++ b/src/core/arm/skyeye_common/armdefs.h
@@ -31,7 +31,7 @@
31 31
32#include "arm_regformat.h" 32#include "arm_regformat.h"
33#include "common/platform.h" 33#include "common/platform.h"
34#include "skyeye_defs.h" 34#include "core/arm/skyeye_common/skyeye_defs.h"
35 35
36//AJ2D-------------------------------------------------------------------------- 36//AJ2D--------------------------------------------------------------------------
37 37
@@ -130,7 +130,7 @@ typedef unsigned long long uint64_t;
130#endif 130#endif
131*/ 131*/
132 132
133#include "armmmu.h" 133#include "core/arm/skyeye_common/armmmu.h"
134//#include "lcd/skyeye_lcd.h" 134//#include "lcd/skyeye_lcd.h"
135 135
136 136
@@ -367,7 +367,6 @@ So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model)
367 367
368 int verbose; /* non-zero means print various messages like the banner */ 368 int verbose; /* non-zero means print various messages like the banner */
369 369
370 mmu_state_t mmu;
371 int mmu_inited; 370 int mmu_inited;
372 //mem_state_t mem; 371 //mem_state_t mem;
373 /*remove io_state to skyeye_mach_*.c files */ 372 /*remove io_state to skyeye_mach_*.c files */
diff --git a/src/core/arm/interpreter/armemu.h b/src/core/arm/skyeye_common/armemu.h
index 36fb2d09b..c0f0270fe 100644
--- a/src/core/arm/interpreter/armemu.h
+++ b/src/core/arm/skyeye_common/armemu.h
@@ -18,7 +18,7 @@
18#define __ARMEMU_H__ 18#define __ARMEMU_H__
19 19
20 20
21#include "armdefs.h" 21#include "core/arm/skyeye_common/armdefs.h"
22//#include "skyeye.h" 22//#include "skyeye.h"
23 23
24//extern ARMword isize; 24//extern ARMword isize;
diff --git a/src/core/arm/interpreter/armmmu.h b/src/core/arm/skyeye_common/armmmu.h
index 818108c9c..30858f9ba 100644
--- a/src/core/arm/interpreter/armmmu.h
+++ b/src/core/arm/skyeye_common/armmmu.h
@@ -134,121 +134,4 @@ typedef enum fault_t
134 134
135} fault_t; 135} fault_t;
136 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 "core/arm/interpreter/mmu/tlb.h"
176#include "core/arm/interpreter/mmu/rb.h"
177#include "core/arm/interpreter/mmu/wb.h"
178#include "core/arm/interpreter/mmu/cache.h"
179
180/*special process mmu.h*/
181#include "core/arm/interpreter/mmu/sa_mmu.h"
182//#include "core/arm/interpreter/mmu/arm7100_mmu.h"
183//#include "core/arm/interpreter/mmu/arm920t_mmu.h"
184//#include "core/arm/interpreter/mmu/arm926ejs_mmu.h"
185#include "core/arm/interpreter/mmu/arm1176jzf_s_mmu.h"
186//#include "core/arm/interpreter/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_ */ 137#endif /* _ARMMMU_H_ */
diff --git a/src/core/arm/interpreter/armos.h b/src/core/arm/skyeye_common/armos.h
index 4b58801ad..ffdadcd1c 100644
--- a/src/core/arm/interpreter/armos.h
+++ b/src/core/arm/skyeye_common/armos.h
@@ -15,14 +15,7 @@
15 along with this program; if not, write to the Free Software 15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17 17
18//#include "bank_defs.h" 18#include <stdint.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 19
27#if FAST_MEMORY 20#if FAST_MEMORY
28/* in user mode, mmap_base will be on initial brk, 21/* in user mode, mmap_base will be on initial brk,
diff --git a/src/core/arm/interpreter/skyeye_defs.h b/src/core/arm/skyeye_common/skyeye_defs.h
index b6713ebad..d4088383f 100644
--- a/src/core/arm/interpreter/skyeye_defs.h
+++ b/src/core/arm/skyeye_common/skyeye_defs.h
@@ -108,4 +108,6 @@ typedef struct generic_arch_s
108 align_t alignment; 108 align_t alignment;
109} generic_arch_t; 109} generic_arch_t;
110 110
111#endif \ No newline at end of file 111typedef u32 addr_t;
112
113#endif
diff --git a/src/core/arm/skyeye_common/skyeye_types.h b/src/core/arm/skyeye_common/skyeye_types.h
new file mode 100644
index 000000000..e7f022f19
--- /dev/null
+++ b/src/core/arm/skyeye_common/skyeye_types.h
@@ -0,0 +1,55 @@
1/*
2 skyeye_types.h - some data types definition for skyeye debugger
3 Copyright (C) 2003 Skyeye Develop Group
4 for help please send mail to <skyeye-developer@lists.sf.linuxforum.net>
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/*
22 * 12/16/2006 Michael.Kang <blackfin.kang@gmail.com>
23 */
24
25#ifndef __SKYEYE_TYPES_H
26#define __SKYEYE_TYPES_H
27
28#include <stdint.h>
29
30/*default machine word length */
31
32#ifndef __BEOS__
33/* To avoid the type conflict with the qemu */
34#ifndef QEMU
35typedef uint8_t uint8;
36typedef uint16_t uint16;
37typedef uint32_t uint32;
38typedef uint64_t uint64;
39
40typedef int8_t sint8;
41typedef int16_t sint16;
42typedef int32_t sint32;
43typedef int64_t sint64;
44#endif
45
46typedef uint32_t address_t;
47typedef uint32_t uinteger_t;
48typedef int32_t integer_t;
49
50typedef uint32_t physical_address_t;
51typedef uint32_t generic_address_t;
52
53#endif
54
55#endif
diff --git a/src/core/arm/interpreter/vfp/asm_vfp.h b/src/core/arm/skyeye_common/vfp/asm_vfp.h
index f4ab34fd4..f4ab34fd4 100644
--- a/src/core/arm/interpreter/vfp/asm_vfp.h
+++ b/src/core/arm/skyeye_common/vfp/asm_vfp.h
diff --git a/src/core/arm/interpreter/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp
index eea5e24a9..e4fa3c20a 100644
--- a/src/core/arm/interpreter/vfp/vfp.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfp.cpp
@@ -25,8 +25,8 @@
25 25
26#include "common/common.h" 26#include "common/common.h"
27 27
28#include "core/arm/interpreter/armdefs.h" 28#include "core/arm/skyeye_common/armdefs.h"
29#include "core/arm/interpreter/vfp/vfp.h" 29#include "core/arm/skyeye_common/vfp/vfp.h"
30 30
31//ARMul_State* persistent_state; /* function calls from SoftFloat lib don't have an access to ARMul_state. */ 31//ARMul_State* persistent_state; /* function calls from SoftFloat lib don't have an access to ARMul_state. */
32 32
@@ -62,7 +62,7 @@ VFPMRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value)
62 if (CoProc == 10 || CoProc == 11) 62 if (CoProc == 10 || CoProc == 11)
63 { 63 {
64 #define VFP_MRC_TRANS 64 #define VFP_MRC_TRANS
65 #include "core/arm/interpreter/vfp/vfpinstr.cpp" 65 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
66 #undef VFP_MRC_TRANS 66 #undef VFP_MRC_TRANS
67 } 67 }
68 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n", 68 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",
@@ -88,7 +88,7 @@ VFPMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value)
88 if (CoProc == 10 || CoProc == 11) 88 if (CoProc == 10 || CoProc == 11)
89 { 89 {
90 #define VFP_MCR_TRANS 90 #define VFP_MCR_TRANS
91 #include "core/arm/interpreter/vfp/vfpinstr.cpp" 91 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
92 #undef VFP_MCR_TRANS 92 #undef VFP_MCR_TRANS
93 } 93 }
94 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n", 94 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",
@@ -110,7 +110,7 @@ VFPMRRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value1, AR
110 if (CoProc == 10 || CoProc == 11) 110 if (CoProc == 10 || CoProc == 11)
111 { 111 {
112 #define VFP_MRRC_TRANS 112 #define VFP_MRRC_TRANS
113 #include "core/arm/interpreter/vfp/vfpinstr.cpp" 113 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
114 #undef VFP_MRRC_TRANS 114 #undef VFP_MRRC_TRANS
115 } 115 }
116 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n", 116 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
@@ -136,7 +136,7 @@ VFPMCRR (ARMul_State * state, unsigned type, ARMword instr, ARMword value1, ARMw
136 if (CoProc == 11 || CoProc == 10) 136 if (CoProc == 11 || CoProc == 10)
137 { 137 {
138 #define VFP_MCRR_TRANS 138 #define VFP_MCRR_TRANS
139 #include "core/arm/interpreter/vfp/vfpinstr.cpp" 139 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
140 #undef VFP_MCRR_TRANS 140 #undef VFP_MCRR_TRANS
141 } 141 }
142 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n", 142 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
@@ -179,7 +179,7 @@ VFPSTC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value)
179 #endif 179 #endif
180 180
181 #define VFP_STC_TRANS 181 #define VFP_STC_TRANS
182 #include "core/arm/interpreter/vfp/vfpinstr.cpp" 182 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
183 #undef VFP_STC_TRANS 183 #undef VFP_STC_TRANS
184 } 184 }
185 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n", 185 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",
@@ -210,7 +210,7 @@ VFPLDC (ARMul_State * state, unsigned type, ARMword instr, ARMword value)
210 if (CoProc == 10 || CoProc == 11) 210 if (CoProc == 10 || CoProc == 11)
211 { 211 {
212 #define VFP_LDC_TRANS 212 #define VFP_LDC_TRANS
213 #include "core/arm/interpreter/vfp/vfpinstr.cpp" 213 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
214 #undef VFP_LDC_TRANS 214 #undef VFP_LDC_TRANS
215 } 215 }
216 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n", 216 DEBUG_LOG(ARM11, "Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",
@@ -237,7 +237,7 @@ VFPCDP (ARMul_State * state, unsigned type, ARMword instr)
237 if (CoProc == 10 || CoProc == 11) 237 if (CoProc == 10 || CoProc == 11)
238 { 238 {
239 #define VFP_CDP_TRANS 239 #define VFP_CDP_TRANS
240 #include "core/arm/interpreter/vfp/vfpinstr.cpp" 240 #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
241 #undef VFP_CDP_TRANS 241 #undef VFP_CDP_TRANS
242 242
243 int exceptions = 0; 243 int exceptions = 0;
@@ -257,21 +257,21 @@ VFPCDP (ARMul_State * state, unsigned type, ARMword instr)
257 257
258/* ----------- MRC ------------ */ 258/* ----------- MRC ------------ */
259#define VFP_MRC_IMPL 259#define VFP_MRC_IMPL
260#include "core/arm/interpreter/vfp/vfpinstr.cpp" 260#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
261#undef VFP_MRC_IMPL 261#undef VFP_MRC_IMPL
262 262
263#define VFP_MRRC_IMPL 263#define VFP_MRRC_IMPL
264#include "core/arm/interpreter/vfp/vfpinstr.cpp" 264#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
265#undef VFP_MRRC_IMPL 265#undef VFP_MRRC_IMPL
266 266
267 267
268/* ----------- MCR ------------ */ 268/* ----------- MCR ------------ */
269#define VFP_MCR_IMPL 269#define VFP_MCR_IMPL
270#include "core/arm/interpreter/vfp/vfpinstr.cpp" 270#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
271#undef VFP_MCR_IMPL 271#undef VFP_MCR_IMPL
272 272
273#define VFP_MCRR_IMPL 273#define VFP_MCRR_IMPL
274#include "core/arm/interpreter/vfp/vfpinstr.cpp" 274#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
275#undef VFP_MCRR_IMPL 275#undef VFP_MCRR_IMPL
276 276
277/* Memory operation are not inlined, as old Interpreter and Fast interpreter 277/* Memory operation are not inlined, as old Interpreter and Fast interpreter
@@ -283,19 +283,19 @@ VFPCDP (ARMul_State * state, unsigned type, ARMword instr)
283 283
284/* ----------- STC ------------ */ 284/* ----------- STC ------------ */
285#define VFP_STC_IMPL 285#define VFP_STC_IMPL
286#include "core/arm/interpreter/vfp/vfpinstr.cpp" 286#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
287#undef VFP_STC_IMPL 287#undef VFP_STC_IMPL
288 288
289 289
290/* ----------- LDC ------------ */ 290/* ----------- LDC ------------ */
291#define VFP_LDC_IMPL 291#define VFP_LDC_IMPL
292#include "core/arm/interpreter/vfp/vfpinstr.cpp" 292#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
293#undef VFP_LDC_IMPL 293#undef VFP_LDC_IMPL
294 294
295 295
296/* ----------- CDP ------------ */ 296/* ----------- CDP ------------ */
297#define VFP_CDP_IMPL 297#define VFP_CDP_IMPL
298#include "core/arm/interpreter/vfp/vfpinstr.cpp" 298#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
299#undef VFP_CDP_IMPL 299#undef VFP_CDP_IMPL
300 300
301/* Miscellaneous functions */ 301/* Miscellaneous functions */
diff --git a/src/core/arm/interpreter/vfp/vfp.h b/src/core/arm/skyeye_common/vfp/vfp.h
index bbf4caeb0..ed627d41f 100644
--- a/src/core/arm/interpreter/vfp/vfp.h
+++ b/src/core/arm/skyeye_common/vfp/vfp.h
@@ -25,7 +25,7 @@
25 25
26#define vfpdebug //printf 26#define vfpdebug //printf
27 27
28#include "core/arm/interpreter/vfp/vfp_helper.h" /* for references to cdp SoftFloat functions */ 28#include "core/arm/skyeye_common/vfp/vfp_helper.h" /* for references to cdp SoftFloat functions */
29 29
30unsigned VFPInit (ARMul_State *state); 30unsigned VFPInit (ARMul_State *state);
31unsigned VFPMRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value); 31unsigned VFPMRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value);
diff --git a/src/core/arm/interpreter/vfp/vfp_helper.h b/src/core/arm/skyeye_common/vfp/vfp_helper.h
index b222e79f1..a55bf875c 100644
--- a/src/core/arm/interpreter/vfp/vfp_helper.h
+++ b/src/core/arm/skyeye_common/vfp/vfp_helper.h
@@ -38,7 +38,7 @@
38#include <stdint.h> 38#include <stdint.h>
39#include <stdio.h> 39#include <stdio.h>
40 40
41#include "core/arm/interpreter/armdefs.h" 41#include "core/arm/skyeye_common/armdefs.h"
42 42
43#define u16 uint16_t 43#define u16 uint16_t
44#define u32 uint32_t 44#define u32 uint32_t
diff --git a/src/core/arm/interpreter/vfp/vfpdouble.cpp b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp
index 5ae99b88a..13411ad80 100644
--- a/src/core/arm/interpreter/vfp/vfpdouble.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp
@@ -51,9 +51,9 @@
51 * =========================================================================== 51 * ===========================================================================
52 */ 52 */
53 53
54#include "core/arm/interpreter/vfp/vfp.h" 54#include "core/arm/skyeye_common/vfp/vfp.h"
55#include "core/arm/interpreter/vfp/vfp_helper.h" 55#include "core/arm/skyeye_common/vfp/vfp_helper.h"
56#include "core/arm/interpreter/vfp/asm_vfp.h" 56#include "core/arm/skyeye_common/vfp/asm_vfp.h"
57 57
58static struct vfp_double vfp_double_default_qnan = { 58static struct vfp_double vfp_double_default_qnan = {
59 //.exponent = 2047, 59 //.exponent = 2047,
diff --git a/src/core/arm/interpreter/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
index a57047911..45208fb13 100644
--- a/src/core/arm/interpreter/vfp/vfpinstr.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
@@ -3709,7 +3709,7 @@ VFPLABEL_INST:
3709 { 3709 {
3710 fault = check_address_validity(cpu, addr, &phys_addr, 0); 3710 fault = check_address_validity(cpu, addr, &phys_addr, 0);
3711 if (fault) goto MMU_EXCEPTION; 3711 if (fault) goto MMU_EXCEPTION;
3712 fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d], 32); 3712 fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d], 32);
3713 if (fault) goto MMU_EXCEPTION; 3713 if (fault) goto MMU_EXCEPTION;
3714 DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d, cpu->ExtReg[inst_cream->d]); 3714 DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d, cpu->ExtReg[inst_cream->d]);
3715 } 3715 }
@@ -3719,13 +3719,13 @@ VFPLABEL_INST:
3719 if (fault) goto MMU_EXCEPTION; 3719 if (fault) goto MMU_EXCEPTION;
3720 3720
3721 /* Check endianness */ 3721 /* Check endianness */
3722 fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d*2], 32); 3722 fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d*2], 32);
3723 if (fault) goto MMU_EXCEPTION; 3723 if (fault) goto MMU_EXCEPTION;
3724 3724
3725 fault = check_address_validity(cpu, addr + 4, &phys_addr, 0); 3725 fault = check_address_validity(cpu, addr + 4, &phys_addr, 0);
3726 if (fault) goto MMU_EXCEPTION; 3726 if (fault) goto MMU_EXCEPTION;
3727 3727
3728 fault = interpreter_write_memory(core, addr + 4, phys_addr, cpu->ExtReg[inst_cream->d*2+1], 32); 3728 fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[inst_cream->d*2+1], 32);
3729 if (fault) goto MMU_EXCEPTION; 3729 if (fault) goto MMU_EXCEPTION;
3730 DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, inst_cream->d*2+1, inst_cream->d*2, cpu->ExtReg[inst_cream->d*2+1], cpu->ExtReg[inst_cream->d*2]); 3730 DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, inst_cream->d*2+1, inst_cream->d*2, cpu->ExtReg[inst_cream->d*2+1], cpu->ExtReg[inst_cream->d*2]);
3731 } 3731 }
@@ -3926,7 +3926,7 @@ VFPLABEL_INST:
3926 { 3926 {
3927 fault = check_address_validity(cpu, addr, &phys_addr, 0); 3927 fault = check_address_validity(cpu, addr, &phys_addr, 0);
3928 if (fault) goto MMU_EXCEPTION; 3928 if (fault) goto MMU_EXCEPTION;
3929 fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); 3929 fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
3930 if (fault) goto MMU_EXCEPTION; 3930 if (fault) goto MMU_EXCEPTION;
3931 DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); 3931 DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
3932 addr += 4; 3932 addr += 4;
@@ -3936,12 +3936,12 @@ VFPLABEL_INST:
3936 /* Careful of endianness, little by default */ 3936 /* Careful of endianness, little by default */
3937 fault = check_address_validity(cpu, addr, &phys_addr, 0); 3937 fault = check_address_validity(cpu, addr, &phys_addr, 0);
3938 if (fault) goto MMU_EXCEPTION; 3938 if (fault) goto MMU_EXCEPTION;
3939 fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32); 3939 fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
3940 if (fault) goto MMU_EXCEPTION; 3940 if (fault) goto MMU_EXCEPTION;
3941 3941
3942 fault = check_address_validity(cpu, addr + 4, &phys_addr, 0); 3942 fault = check_address_validity(cpu, addr + 4, &phys_addr, 0);
3943 if (fault) goto MMU_EXCEPTION; 3943 if (fault) goto MMU_EXCEPTION;
3944 fault = interpreter_write_memory(core, addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); 3944 fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
3945 if (fault) goto MMU_EXCEPTION; 3945 if (fault) goto MMU_EXCEPTION;
3946 DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]); 3946 DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
3947 addr += 8; 3947 addr += 8;
@@ -4048,7 +4048,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4048 { 4048 {
4049 if (single) 4049 if (single)
4050 { 4050 {
4051 //fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); 4051 //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
4052 #if 0 4052 #if 0
4053 phys_addr = get_phys_addr(cpu, bb, Addr, 0); 4053 phys_addr = get_phys_addr(cpu, bb, Addr, 0);
4054 bb = cpu->dyncom_engine->bb; 4054 bb = cpu->dyncom_engine->bb;
@@ -4166,7 +4166,7 @@ VFPLABEL_INST: /* encoding 1 */
4166 fault = check_address_validity(cpu, addr, &phys_addr, 0); 4166 fault = check_address_validity(cpu, addr, &phys_addr, 0);
4167 if (fault) goto MMU_EXCEPTION; 4167 if (fault) goto MMU_EXCEPTION;
4168 4168
4169 fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); 4169 fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
4170 if (fault) goto MMU_EXCEPTION; 4170 if (fault) goto MMU_EXCEPTION;
4171 DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]); 4171 DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
4172 addr += 4; 4172 addr += 4;
@@ -4177,13 +4177,13 @@ VFPLABEL_INST: /* encoding 1 */
4177 fault = check_address_validity(cpu, addr, &phys_addr, 0); 4177 fault = check_address_validity(cpu, addr, &phys_addr, 0);
4178 if (fault) goto MMU_EXCEPTION; 4178 if (fault) goto MMU_EXCEPTION;
4179 4179
4180 fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32); 4180 fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
4181 if (fault) goto MMU_EXCEPTION; 4181 if (fault) goto MMU_EXCEPTION;
4182 4182
4183 fault = check_address_validity(cpu, addr + 4, &phys_addr, 0); 4183 fault = check_address_validity(cpu, addr + 4, &phys_addr, 0);
4184 if (fault) goto MMU_EXCEPTION; 4184 if (fault) goto MMU_EXCEPTION;
4185 4185
4186 fault = interpreter_write_memory(core, addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); 4186 fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
4187 if (fault) goto MMU_EXCEPTION; 4187 if (fault) goto MMU_EXCEPTION;
4188 DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]); 4188 DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
4189 addr += 8; 4189 addr += 8;
@@ -4304,7 +4304,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4304 if (single) 4304 if (single)
4305 { 4305 {
4306 4306
4307 //fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); 4307 //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
4308 /* if R(i) is R15? */ 4308 /* if R(i) is R15? */
4309 #if 0 4309 #if 0
4310 phys_addr = get_phys_addr(cpu, bb, Addr, 0); 4310 phys_addr = get_phys_addr(cpu, bb, Addr, 0);
@@ -4321,7 +4321,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4321 else 4321 else
4322 { 4322 {
4323 4323
4324 //fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32); 4324 //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
4325 #if 0 4325 #if 0
4326 phys_addr = get_phys_addr(cpu, bb, Addr, 0); 4326 phys_addr = get_phys_addr(cpu, bb, Addr, 0);
4327 bb = cpu->dyncom_engine->bb; 4327 bb = cpu->dyncom_engine->bb;
@@ -4332,7 +4332,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
4332 bb = cpu->dyncom_engine->bb; 4332 bb = cpu->dyncom_engine->bb;
4333 //if (fault) goto MMU_EXCEPTION; 4333 //if (fault) goto MMU_EXCEPTION;
4334 4334
4335 //fault = interpreter_write_memory(core, addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); 4335 //fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
4336 #if 0 4336 #if 0
4337 phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0); 4337 phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0);
4338 bb = cpu->dyncom_engine->bb; 4338 bb = cpu->dyncom_engine->bb;
@@ -4431,7 +4431,7 @@ VFPLABEL_INST:
4431 fault = check_address_validity(cpu, addr, &phys_addr, 1); 4431 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4432 if (fault) goto MMU_EXCEPTION; 4432 if (fault) goto MMU_EXCEPTION;
4433 4433
4434 fault = interpreter_read_memory(core, addr, phys_addr, value1, 32); 4434 fault = interpreter_read_memory(addr, phys_addr, value1, 32);
4435 if (fault) goto MMU_EXCEPTION; 4435 if (fault) goto MMU_EXCEPTION;
4436 DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d+i, value1, addr); 4436 DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d+i, value1, addr);
4437 cpu->ExtReg[inst_cream->d+i] = value1; 4437 cpu->ExtReg[inst_cream->d+i] = value1;
@@ -4443,13 +4443,13 @@ VFPLABEL_INST:
4443 fault = check_address_validity(cpu, addr, &phys_addr, 1); 4443 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4444 if (fault) goto MMU_EXCEPTION; 4444 if (fault) goto MMU_EXCEPTION;
4445 4445
4446 fault = interpreter_read_memory(core, addr, phys_addr, value1, 32); 4446 fault = interpreter_read_memory(addr, phys_addr, value1, 32);
4447 if (fault) goto MMU_EXCEPTION; 4447 if (fault) goto MMU_EXCEPTION;
4448 4448
4449 fault = check_address_validity(cpu, addr + 4, &phys_addr, 1); 4449 fault = check_address_validity(cpu, addr + 4, &phys_addr, 1);
4450 if (fault) goto MMU_EXCEPTION; 4450 if (fault) goto MMU_EXCEPTION;
4451 4451
4452 fault = interpreter_read_memory(core, addr + 4, phys_addr, value2, 32); 4452 fault = interpreter_read_memory(addr + 4, phys_addr, value2, 32);
4453 if (fault) goto MMU_EXCEPTION; 4453 if (fault) goto MMU_EXCEPTION;
4454 DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, value2, value1, addr+4, addr); 4454 DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, value2, value1, addr+4, addr);
4455 cpu->ExtReg[(inst_cream->d+i)*2] = value1; 4455 cpu->ExtReg[(inst_cream->d+i)*2] = value1;
@@ -4682,7 +4682,7 @@ VFPLABEL_INST:
4682 { 4682 {
4683 fault = check_address_validity(cpu, addr, &phys_addr, 1); 4683 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4684 if (fault) goto MMU_EXCEPTION; 4684 if (fault) goto MMU_EXCEPTION;
4685 fault = interpreter_read_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d], 32); 4685 fault = interpreter_read_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d], 32);
4686 if (fault) goto MMU_EXCEPTION; 4686 if (fault) goto MMU_EXCEPTION;
4687 DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d, cpu->ExtReg[inst_cream->d], addr); 4687 DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d, cpu->ExtReg[inst_cream->d], addr);
4688 } 4688 }
@@ -4691,12 +4691,12 @@ VFPLABEL_INST:
4691 unsigned int word1, word2; 4691 unsigned int word1, word2;
4692 fault = check_address_validity(cpu, addr, &phys_addr, 1); 4692 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4693 if (fault) goto MMU_EXCEPTION; 4693 if (fault) goto MMU_EXCEPTION;
4694 fault = interpreter_read_memory(core, addr, phys_addr, word1, 32); 4694 fault = interpreter_read_memory(addr, phys_addr, word1, 32);
4695 if (fault) goto MMU_EXCEPTION; 4695 if (fault) goto MMU_EXCEPTION;
4696 4696
4697 fault = check_address_validity(cpu, addr + 4, &phys_addr, 1); 4697 fault = check_address_validity(cpu, addr + 4, &phys_addr, 1);
4698 if (fault) goto MMU_EXCEPTION; 4698 if (fault) goto MMU_EXCEPTION;
4699 fault = interpreter_read_memory(core, addr + 4, phys_addr, word2, 32); 4699 fault = interpreter_read_memory(addr + 4, phys_addr, word2, 32);
4700 if (fault) goto MMU_EXCEPTION; 4700 if (fault) goto MMU_EXCEPTION;
4701 /* Check endianness */ 4701 /* Check endianness */
4702 cpu->ExtReg[inst_cream->d*2] = word1; 4702 cpu->ExtReg[inst_cream->d*2] = word1;
@@ -4923,7 +4923,7 @@ VFPLABEL_INST:
4923 { 4923 {
4924 fault = check_address_validity(cpu, addr, &phys_addr, 1); 4924 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4925 if (fault) goto MMU_EXCEPTION; 4925 if (fault) goto MMU_EXCEPTION;
4926 fault = interpreter_read_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); 4926 fault = interpreter_read_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
4927 if (fault) goto MMU_EXCEPTION; 4927 if (fault) goto MMU_EXCEPTION;
4928 DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d+i, cpu->ExtReg[inst_cream->d+i], addr); 4928 DBG("\ts%d <= [%x] addr[%x]\n", inst_cream->d+i, cpu->ExtReg[inst_cream->d+i], addr);
4929 addr += 4; 4929 addr += 4;
@@ -4933,12 +4933,12 @@ VFPLABEL_INST:
4933 /* Careful of endianness, little by default */ 4933 /* Careful of endianness, little by default */
4934 fault = check_address_validity(cpu, addr, &phys_addr, 1); 4934 fault = check_address_validity(cpu, addr, &phys_addr, 1);
4935 if (fault) goto MMU_EXCEPTION; 4935 if (fault) goto MMU_EXCEPTION;
4936 fault = interpreter_read_memory(core, addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32); 4936 fault = interpreter_read_memory(addr, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2], 32);
4937 if (fault) goto MMU_EXCEPTION; 4937 if (fault) goto MMU_EXCEPTION;
4938 4938
4939 fault = check_address_validity(cpu, addr + 4, &phys_addr, 1); 4939 fault = check_address_validity(cpu, addr + 4, &phys_addr, 1);
4940 if (fault) goto MMU_EXCEPTION; 4940 if (fault) goto MMU_EXCEPTION;
4941 fault = interpreter_read_memory(core, addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); 4941 fault = interpreter_read_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
4942 if (fault) goto MMU_EXCEPTION; 4942 if (fault) goto MMU_EXCEPTION;
4943 DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2], addr+4, addr); 4943 DBG("\ts[%d-%d] <= [%x-%x] addr[%x-%x]\n", (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2], addr+4, addr);
4944 addr += 8; 4944 addr += 8;
@@ -5058,7 +5058,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
5058 if (single) 5058 if (single)
5059 { 5059 {
5060 5060
5061 //fault = interpreter_write_memory(core, addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32); 5061 //fault = interpreter_write_memory(addr, phys_addr, cpu->ExtReg[inst_cream->d+i], 32);
5062 /* if R(i) is R15? */ 5062 /* if R(i) is R15? */
5063 #if 0 5063 #if 0
5064 phys_addr = get_phys_addr(cpu, bb, Addr, 1); 5064 phys_addr = get_phys_addr(cpu, bb, Addr, 1);
@@ -5095,7 +5095,7 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
5095 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb); 5095 val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
5096 LETFPS((d + i) * 2 + 1, FPBITCAST32(val)); 5096 LETFPS((d + i) * 2 + 1, FPBITCAST32(val));
5097 5097
5098 //fault = interpreter_write_memory(core, addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32); 5098 //fault = interpreter_write_memory(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
5099 //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]); 5099 //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
5100 //addr += 8; 5100 //addr += 8;
5101 Addr = ADD(Addr, CONST(8)); 5101 Addr = ADD(Addr, CONST(8));
diff --git a/src/core/arm/interpreter/vfp/vfpsingle.cpp b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp
index 0fcc85266..8bcbd4fe9 100644
--- a/src/core/arm/interpreter/vfp/vfpsingle.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp
@@ -51,9 +51,9 @@
51 * =========================================================================== 51 * ===========================================================================
52 */ 52 */
53 53
54#include "core/arm/interpreter/vfp/vfp_helper.h" 54#include "core/arm/skyeye_common/vfp/vfp_helper.h"
55#include "core/arm/interpreter/vfp/asm_vfp.h" 55#include "core/arm/skyeye_common/vfp/asm_vfp.h"
56#include "core/arm/interpreter/vfp/vfp.h" 56#include "core/arm/skyeye_common/vfp/vfp.h"
57 57
58static struct vfp_single vfp_single_default_qnan = { 58static struct vfp_single vfp_single_default_qnan = {
59 //.exponent = 255, 59 //.exponent = 255,
diff --git a/src/core/core.h b/src/core/core.h
index 9c72c8b3f..87da252b8 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -5,7 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include "core/arm/arm_interface.h" 7#include "core/arm/arm_interface.h"
8#include "core/arm/interpreter/armdefs.h" 8#include "core/arm/skyeye_common/armdefs.h"
9 9
10//////////////////////////////////////////////////////////////////////////////////////////////////// 10////////////////////////////////////////////////////////////////////////////////////////////////////
11 11
diff --git a/src/core/hle/coprocessor.h b/src/core/hle/coprocessor.h
deleted file mode 100644
index b08d6f3ee..000000000
--- a/src/core/hle/coprocessor.h
+++ /dev/null
@@ -1,20 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8
9namespace HLE {
10
11/// Coprocessor operations
12enum CoprocessorOperation {
13 DATA_SYNCHRONIZATION_BARRIER = 0xE0,
14 CALL_GET_THREAD_COMMAND_BUFFER = 0xE1,
15};
16
17/// Call an MRC (move to ARM register from coprocessor) instruction in HLE
18s32 CallMRC(u32 instruction);
19
20} // namespace