diff options
| author | 2015-07-25 23:12:34 -0400 | |
|---|---|---|
| committer | 2015-07-25 23:12:34 -0400 | |
| commit | 392c7feba0cd152e46ffbe6089def35082fa2692 (patch) | |
| tree | d959d1751d99a6f5307b45d04e46c19c53d5efc2 /src/core/arm/skyeye_common | |
| parent | Merge pull request #989 from lioncash/extern (diff) | |
| parent | dyncom: Remove unnecessary initialization code. (diff) | |
| download | yuzu-392c7feba0cd152e46ffbe6089def35082fa2692.tar.gz yuzu-392c7feba0cd152e46ffbe6089def35082fa2692.tar.xz yuzu-392c7feba0cd152e46ffbe6089def35082fa2692.zip | |
Merge pull request #990 from lioncash/arm
dyncom: General cleanup
Diffstat (limited to 'src/core/arm/skyeye_common')
| -rw-r--r-- | src/core/arm/skyeye_common/armdefs.h | 318 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/arminit.cpp | 100 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armmmu.h | 3 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armstate.h | 215 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armsupp.cpp | 638 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armsupp.h | 40 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfp.cpp | 12 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfp.h | 10 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfp_helper.h | 4 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpdouble.cpp | 12 |
10 files changed, 1014 insertions, 338 deletions
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h deleted file mode 100644 index a0ec108c7..000000000 --- a/src/core/arm/skyeye_common/armdefs.h +++ /dev/null | |||
| @@ -1,318 +0,0 @@ | |||
| 1 | /* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator. | ||
| 2 | Copyright (C) 1994 Advanced RISC Machines Ltd. | ||
| 3 | |||
| 4 | This program is free software; you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program; if not, write to the Free Software | ||
| 16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <unordered_map> | ||
| 21 | |||
| 22 | #include "common/common_types.h" | ||
| 23 | #include "core/arm/skyeye_common/arm_regformat.h" | ||
| 24 | |||
| 25 | #define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1)) | ||
| 26 | #define BIT(s, n) ((s >> (n)) & 1) | ||
| 27 | |||
| 28 | // Signal levels | ||
| 29 | enum { | ||
| 30 | LOW = 0, | ||
| 31 | HIGH = 1, | ||
| 32 | LOWHIGH = 1, | ||
| 33 | HIGHLOW = 2 | ||
| 34 | }; | ||
| 35 | |||
| 36 | // Cache types | ||
| 37 | enum { | ||
| 38 | NONCACHE = 0, | ||
| 39 | DATACACHE = 1, | ||
| 40 | INSTCACHE = 2, | ||
| 41 | }; | ||
| 42 | |||
| 43 | // Abort models | ||
| 44 | enum { | ||
| 45 | ABORT_BASE_RESTORED = 0, | ||
| 46 | ABORT_EARLY = 1, | ||
| 47 | ABORT_BASE_UPDATED = 2 | ||
| 48 | }; | ||
| 49 | |||
| 50 | #define POS(i) ( (~(i)) >> 31 ) | ||
| 51 | #define NEG(i) ( (i) >> 31 ) | ||
| 52 | |||
| 53 | typedef u64 ARMdword; // must be 64 bits wide | ||
| 54 | typedef u32 ARMword; // must be 32 bits wide | ||
| 55 | typedef u16 ARMhword; // must be 16 bits wide | ||
| 56 | typedef u8 ARMbyte; // must be 8 bits wide | ||
| 57 | |||
| 58 | #define VFP_REG_NUM 64 | ||
| 59 | struct ARMul_State | ||
| 60 | { | ||
| 61 | ARMword Emulate; // To start and stop emulation | ||
| 62 | |||
| 63 | // Order of the following register should not be modified | ||
| 64 | ARMword Reg[16]; // The current register file | ||
| 65 | ARMword Cpsr; // The current PSR | ||
| 66 | ARMword Spsr_copy; | ||
| 67 | ARMword phys_pc; | ||
| 68 | ARMword Reg_usr[2]; | ||
| 69 | ARMword Reg_svc[2]; // R13_SVC R14_SVC | ||
| 70 | ARMword Reg_abort[2]; // R13_ABORT R14_ABORT | ||
| 71 | ARMword Reg_undef[2]; // R13 UNDEF R14 UNDEF | ||
| 72 | ARMword Reg_irq[2]; // R13_IRQ R14_IRQ | ||
| 73 | ARMword Reg_firq[7]; // R8---R14 FIRQ | ||
| 74 | ARMword Spsr[7]; // The exception psr's | ||
| 75 | ARMword Mode; // The current mode | ||
| 76 | ARMword Bank; // The current register bank | ||
| 77 | ARMword exclusive_tag; // The address for which the local monitor is in exclusive access mode | ||
| 78 | ARMword exclusive_state; | ||
| 79 | ARMword exclusive_result; | ||
| 80 | ARMword CP15[CP15_REGISTER_COUNT]; | ||
| 81 | |||
| 82 | // FPSID, FPSCR, and FPEXC | ||
| 83 | ARMword VFP[VFP_SYSTEM_REGISTER_COUNT]; | ||
| 84 | // VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31). | ||
| 85 | // VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31), | ||
| 86 | // and only 32 singleword registers are accessible (S0-S31). | ||
| 87 | ARMword ExtReg[VFP_REG_NUM]; | ||
| 88 | /* ---- End of the ordered registers ---- */ | ||
| 89 | |||
| 90 | ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed | ||
| 91 | unsigned int shifter_carry_out; | ||
| 92 | |||
| 93 | // Add armv6 flags dyf:2010-08-09 | ||
| 94 | ARMword GEFlag, EFlag, AFlag, QFlag; | ||
| 95 | |||
| 96 | ARMword TFlag; // Thumb state | ||
| 97 | |||
| 98 | unsigned long long NumInstrs; // The number of instructions executed | ||
| 99 | unsigned NumInstrsToExecute; | ||
| 100 | |||
| 101 | unsigned NresetSig; // Reset the processor | ||
| 102 | unsigned NfiqSig; | ||
| 103 | unsigned NirqSig; | ||
| 104 | |||
| 105 | unsigned abortSig; | ||
| 106 | unsigned NtransSig; | ||
| 107 | unsigned bigendSig; | ||
| 108 | unsigned syscallSig; | ||
| 109 | |||
| 110 | /* 2004-05-09 chy | ||
| 111 | ---------------------------------------------------------- | ||
| 112 | read ARM Architecture Reference Manual | ||
| 113 | 2.6.5 Data Abort | ||
| 114 | There are three Abort Model in ARM arch. | ||
| 115 | |||
| 116 | Early Abort Model: used in some ARMv3 and earlier implementations. In this | ||
| 117 | model, base register wirteback occurred for LDC,LDM,STC,STM instructions, and | ||
| 118 | the base register was unchanged for all other instructions. (oldest) | ||
| 119 | |||
| 120 | Base Restored Abort Model: If a Data Abort occurs in an instruction which | ||
| 121 | specifies base register writeback, the value in the base register is | ||
| 122 | unchanged. (strongarm, xscale) | ||
| 123 | |||
| 124 | Base Updated Abort Model: If a Data Abort occurs in an instruction which | ||
| 125 | specifies base register writeback, the base register writeback still occurs. | ||
| 126 | (arm720T) | ||
| 127 | |||
| 128 | read PART B | ||
| 129 | chap2 The System Control Coprocessor CP15 | ||
| 130 | 2.4 Register1:control register | ||
| 131 | L(bit 6): in some ARMv3 and earlier implementations, the abort model of the | ||
| 132 | processor could be configured: | ||
| 133 | 0=early Abort Model Selected(now obsolete) | ||
| 134 | 1=Late Abort Model selceted(same as Base Updated Abort Model) | ||
| 135 | |||
| 136 | on later processors, this bit reads as 1 and ignores writes. | ||
| 137 | ------------------------------------------------------------- | ||
| 138 | So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model) | ||
| 139 | if lateabtSig=0, then it means Base Restored Abort Model | ||
| 140 | */ | ||
| 141 | unsigned lateabtSig; | ||
| 142 | |||
| 143 | // For differentiating ARM core emulaiton. | ||
| 144 | bool is_v4; // Are we emulating a v4 architecture (or higher)? | ||
| 145 | bool is_v5; // Are we emulating a v5 architecture? | ||
| 146 | bool is_v5e; // Are we emulating a v5e architecture? | ||
| 147 | bool is_v6; // Are we emulating a v6 architecture? | ||
| 148 | bool is_v7; // Are we emulating a v7 architecture? | ||
| 149 | |||
| 150 | // ARM_ARM A2-18 | ||
| 151 | // 0 Base Restored Abort Model, 1 the Early Abort Model, 2 Base Updated Abort Model | ||
| 152 | int abort_model; | ||
| 153 | |||
| 154 | // TODO(bunnei): Move this cache to a better place - it should be per codeset (likely per | ||
| 155 | // process for our purposes), not per ARMul_State (which tracks CPU core state). | ||
| 156 | std::unordered_map<u32, int> instruction_cache; | ||
| 157 | }; | ||
| 158 | |||
| 159 | /***************************************************************************\ | ||
| 160 | * Types of ARM we know about * | ||
| 161 | \***************************************************************************/ | ||
| 162 | |||
| 163 | enum { | ||
| 164 | ARM_v4_Prop = 0x01, | ||
| 165 | ARM_v5_Prop = 0x02, | ||
| 166 | ARM_v5e_Prop = 0x04, | ||
| 167 | ARM_v6_Prop = 0x08, | ||
| 168 | ARM_v7_Prop = 0x10, | ||
| 169 | }; | ||
| 170 | |||
| 171 | /***************************************************************************\ | ||
| 172 | * The hardware vector addresses * | ||
| 173 | \***************************************************************************/ | ||
| 174 | |||
| 175 | enum { | ||
| 176 | ARMResetV = 0, | ||
| 177 | ARMUndefinedInstrV = 4, | ||
| 178 | ARMSWIV = 8, | ||
| 179 | ARMPrefetchAbortV = 12, | ||
| 180 | ARMDataAbortV = 16, | ||
| 181 | ARMAddrExceptnV = 20, | ||
| 182 | ARMIRQV = 24, | ||
| 183 | ARMFIQV = 28, | ||
| 184 | ARMErrorV = 32, // This is an offset, not an address! | ||
| 185 | |||
| 186 | ARMul_ResetV = ARMResetV, | ||
| 187 | ARMul_UndefinedInstrV = ARMUndefinedInstrV, | ||
| 188 | ARMul_SWIV = ARMSWIV, | ||
| 189 | ARMul_PrefetchAbortV = ARMPrefetchAbortV, | ||
| 190 | ARMul_DataAbortV = ARMDataAbortV, | ||
| 191 | ARMul_AddrExceptnV = ARMAddrExceptnV, | ||
| 192 | ARMul_IRQV = ARMIRQV, | ||
| 193 | ARMul_FIQV = ARMFIQV | ||
| 194 | }; | ||
| 195 | |||
| 196 | /***************************************************************************\ | ||
| 197 | * Mode and Bank Constants * | ||
| 198 | \***************************************************************************/ | ||
| 199 | |||
| 200 | enum PrivilegeMode { | ||
| 201 | USER32MODE = 16, | ||
| 202 | FIQ32MODE = 17, | ||
| 203 | IRQ32MODE = 18, | ||
| 204 | SVC32MODE = 19, | ||
| 205 | ABORT32MODE = 23, | ||
| 206 | UNDEF32MODE = 27, | ||
| 207 | SYSTEM32MODE = 31 | ||
| 208 | }; | ||
| 209 | |||
| 210 | enum { | ||
| 211 | USERBANK = 0, | ||
| 212 | FIQBANK = 1, | ||
| 213 | IRQBANK = 2, | ||
| 214 | SVCBANK = 3, | ||
| 215 | ABORTBANK = 4, | ||
| 216 | UNDEFBANK = 5, | ||
| 217 | DUMMYBANK = 6, | ||
| 218 | SYSTEMBANK = 7 | ||
| 219 | }; | ||
| 220 | |||
| 221 | /***************************************************************************\ | ||
| 222 | * Definitions of things in the emulator * | ||
| 223 | \***************************************************************************/ | ||
| 224 | void ARMul_Reset(ARMul_State* state); | ||
| 225 | ARMul_State* ARMul_NewState(ARMul_State* state); | ||
| 226 | |||
| 227 | /***************************************************************************\ | ||
| 228 | * Definitions of things in the co-processor interface * | ||
| 229 | \***************************************************************************/ | ||
| 230 | |||
| 231 | enum { | ||
| 232 | ARMul_FIRST = 0, | ||
| 233 | ARMul_TRANSFER = 1, | ||
| 234 | ARMul_BUSY = 2, | ||
| 235 | ARMul_DATA = 3, | ||
| 236 | ARMul_INTERRUPT = 4, | ||
| 237 | ARMul_DONE = 0, | ||
| 238 | ARMul_CANT = 1, | ||
| 239 | ARMul_INC = 3 | ||
| 240 | }; | ||
| 241 | |||
| 242 | /***************************************************************************\ | ||
| 243 | * Definitions of things in the host environment * | ||
| 244 | \***************************************************************************/ | ||
| 245 | |||
| 246 | enum ConditionCode { | ||
| 247 | EQ = 0, | ||
| 248 | NE = 1, | ||
| 249 | CS = 2, | ||
| 250 | CC = 3, | ||
| 251 | MI = 4, | ||
| 252 | PL = 5, | ||
| 253 | VS = 6, | ||
| 254 | VC = 7, | ||
| 255 | HI = 8, | ||
| 256 | LS = 9, | ||
| 257 | GE = 10, | ||
| 258 | LT = 11, | ||
| 259 | GT = 12, | ||
| 260 | LE = 13, | ||
| 261 | AL = 14, | ||
| 262 | NV = 15, | ||
| 263 | }; | ||
| 264 | |||
| 265 | // Flags for use with the APSR. | ||
| 266 | enum : u32 { | ||
| 267 | NBIT = (1U << 31U), | ||
| 268 | ZBIT = (1 << 30), | ||
| 269 | CBIT = (1 << 29), | ||
| 270 | VBIT = (1 << 28), | ||
| 271 | QBIT = (1 << 27), | ||
| 272 | JBIT = (1 << 24), | ||
| 273 | EBIT = (1 << 9), | ||
| 274 | ABIT = (1 << 8), | ||
| 275 | IBIT = (1 << 7), | ||
| 276 | FBIT = (1 << 6), | ||
| 277 | TBIT = (1 << 5), | ||
| 278 | |||
| 279 | // Masks for groups of bits in the APSR. | ||
| 280 | MODEBITS = 0x1F, | ||
| 281 | INTBITS = 0x1C0, | ||
| 282 | }; | ||
| 283 | |||
| 284 | // Values for Emulate. | ||
| 285 | enum { | ||
| 286 | STOP = 0, // Stop | ||
| 287 | CHANGEMODE = 1, // Change mode | ||
| 288 | ONCE = 2, // Execute just one iteration | ||
| 289 | RUN = 3 // Continuous execution | ||
| 290 | }; | ||
| 291 | |||
| 292 | |||
| 293 | bool AddOverflow(ARMword, ARMword, ARMword); | ||
| 294 | bool SubOverflow(ARMword, ARMword, ARMword); | ||
| 295 | |||
| 296 | void ARMul_SelectProcessor(ARMul_State*, unsigned); | ||
| 297 | |||
| 298 | u32 AddWithCarry(u32, u32, u32, bool*, bool*); | ||
| 299 | bool ARMul_AddOverflowQ(ARMword, ARMword); | ||
| 300 | |||
| 301 | u8 ARMul_SignedSaturatedAdd8(u8, u8); | ||
| 302 | u8 ARMul_SignedSaturatedSub8(u8, u8); | ||
| 303 | u16 ARMul_SignedSaturatedAdd16(u16, u16); | ||
| 304 | u16 ARMul_SignedSaturatedSub16(u16, u16); | ||
| 305 | |||
| 306 | u8 ARMul_UnsignedSaturatedAdd8(u8, u8); | ||
| 307 | u16 ARMul_UnsignedSaturatedAdd16(u16, u16); | ||
| 308 | u8 ARMul_UnsignedSaturatedSub8(u8, u8); | ||
| 309 | u16 ARMul_UnsignedSaturatedSub16(u16, u16); | ||
| 310 | u8 ARMul_UnsignedAbsoluteDifference(u8, u8); | ||
| 311 | u32 ARMul_SignedSatQ(s32, u8, bool*); | ||
| 312 | u32 ARMul_UnsignedSatQ(s32, u8, bool*); | ||
| 313 | |||
| 314 | bool InBigEndianMode(ARMul_State*); | ||
| 315 | bool InAPrivilegedMode(ARMul_State*); | ||
| 316 | |||
| 317 | u32 ReadCP15Register(ARMul_State* cpu, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2); | ||
| 318 | void WriteCP15Register(ARMul_State* cpu, u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2); | ||
diff --git a/src/core/arm/skyeye_common/arminit.cpp b/src/core/arm/skyeye_common/arminit.cpp new file mode 100644 index 000000000..b7c508d75 --- /dev/null +++ b/src/core/arm/skyeye_common/arminit.cpp | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | /* arminit.c -- ARMulator initialization: ARM6 Instruction Emulator. | ||
| 2 | Copyright (C) 1994 Advanced RISC Machines Ltd. | ||
| 3 | |||
| 4 | This program is free software; you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program; if not, write to the Free Software | ||
| 16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 17 | |||
| 18 | #include <cstring> | ||
| 19 | #include "core/arm/skyeye_common/armstate.h" | ||
| 20 | #include "core/arm/skyeye_common/vfp/vfp.h" | ||
| 21 | |||
| 22 | // Resets certain MPCore CP15 values to their ARM-defined reset values. | ||
| 23 | static void ResetMPCoreCP15Registers(ARMul_State* cpu) | ||
| 24 | { | ||
| 25 | // c0 | ||
| 26 | cpu->CP15[CP15_MAIN_ID] = 0x410FB024; | ||
| 27 | cpu->CP15[CP15_TLB_TYPE] = 0x00000800; | ||
| 28 | cpu->CP15[CP15_PROCESSOR_FEATURE_0] = 0x00000111; | ||
| 29 | cpu->CP15[CP15_PROCESSOR_FEATURE_1] = 0x00000001; | ||
| 30 | cpu->CP15[CP15_DEBUG_FEATURE_0] = 0x00000002; | ||
| 31 | cpu->CP15[CP15_MEMORY_MODEL_FEATURE_0] = 0x01100103; | ||
| 32 | cpu->CP15[CP15_MEMORY_MODEL_FEATURE_1] = 0x10020302; | ||
| 33 | cpu->CP15[CP15_MEMORY_MODEL_FEATURE_2] = 0x01222000; | ||
| 34 | cpu->CP15[CP15_MEMORY_MODEL_FEATURE_3] = 0x00000000; | ||
| 35 | cpu->CP15[CP15_ISA_FEATURE_0] = 0x00100011; | ||
| 36 | cpu->CP15[CP15_ISA_FEATURE_1] = 0x12002111; | ||
| 37 | cpu->CP15[CP15_ISA_FEATURE_2] = 0x11221011; | ||
| 38 | cpu->CP15[CP15_ISA_FEATURE_3] = 0x01102131; | ||
| 39 | cpu->CP15[CP15_ISA_FEATURE_4] = 0x00000141; | ||
| 40 | |||
| 41 | // c1 | ||
| 42 | cpu->CP15[CP15_CONTROL] = 0x00054078; | ||
| 43 | cpu->CP15[CP15_AUXILIARY_CONTROL] = 0x0000000F; | ||
| 44 | cpu->CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = 0x00000000; | ||
| 45 | |||
| 46 | // c2 | ||
| 47 | cpu->CP15[CP15_TRANSLATION_BASE_TABLE_0] = 0x00000000; | ||
| 48 | cpu->CP15[CP15_TRANSLATION_BASE_TABLE_1] = 0x00000000; | ||
| 49 | cpu->CP15[CP15_TRANSLATION_BASE_CONTROL] = 0x00000000; | ||
| 50 | |||
| 51 | // c3 | ||
| 52 | cpu->CP15[CP15_DOMAIN_ACCESS_CONTROL] = 0x00000000; | ||
| 53 | |||
| 54 | // c7 | ||
| 55 | cpu->CP15[CP15_PHYS_ADDRESS] = 0x00000000; | ||
| 56 | |||
| 57 | // c9 | ||
| 58 | cpu->CP15[CP15_DATA_CACHE_LOCKDOWN] = 0xFFFFFFF0; | ||
| 59 | |||
| 60 | // c10 | ||
| 61 | cpu->CP15[CP15_TLB_LOCKDOWN] = 0x00000000; | ||
| 62 | cpu->CP15[CP15_PRIMARY_REGION_REMAP] = 0x00098AA4; | ||
| 63 | cpu->CP15[CP15_NORMAL_REGION_REMAP] = 0x44E048E0; | ||
| 64 | |||
| 65 | // c13 | ||
| 66 | cpu->CP15[CP15_PID] = 0x00000000; | ||
| 67 | cpu->CP15[CP15_CONTEXT_ID] = 0x00000000; | ||
| 68 | cpu->CP15[CP15_THREAD_UPRW] = 0x00000000; | ||
| 69 | cpu->CP15[CP15_THREAD_URO] = 0x00000000; | ||
| 70 | cpu->CP15[CP15_THREAD_PRW] = 0x00000000; | ||
| 71 | |||
| 72 | // c15 | ||
| 73 | cpu->CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = 0x00000000; | ||
| 74 | cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = 0x00000000; | ||
| 75 | cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = 0x00000000; | ||
| 76 | cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = 0x00000000; | ||
| 77 | cpu->CP15[CP15_TLB_DEBUG_CONTROL] = 0x00000000; | ||
| 78 | } | ||
| 79 | |||
| 80 | // Performs a reset | ||
| 81 | void ARMul_Reset(ARMul_State* state) | ||
| 82 | { | ||
| 83 | VFPInit(state); | ||
| 84 | |||
| 85 | state->Reg[15] = 0; | ||
| 86 | state->Cpsr = INTBITS | SVC32MODE; | ||
| 87 | state->Mode = SVC32MODE; | ||
| 88 | state->Bank = SVCBANK; | ||
| 89 | |||
| 90 | ResetMPCoreCP15Registers(state); | ||
| 91 | |||
| 92 | state->NresetSig = HIGH; | ||
| 93 | state->NfiqSig = HIGH; | ||
| 94 | state->NirqSig = HIGH; | ||
| 95 | state->NtransSig = (state->Mode & 3) ? HIGH : LOW; | ||
| 96 | state->abortSig = LOW; | ||
| 97 | |||
| 98 | state->NumInstrs = 0; | ||
| 99 | state->Emulate = RUN; | ||
| 100 | } | ||
diff --git a/src/core/arm/skyeye_common/armmmu.h b/src/core/arm/skyeye_common/armmmu.h index c67d7209b..5423588c0 100644 --- a/src/core/arm/skyeye_common/armmmu.h +++ b/src/core/arm/skyeye_common/armmmu.h | |||
| @@ -23,7 +23,8 @@ | |||
| 23 | #include "common/swap.h" | 23 | #include "common/swap.h" |
| 24 | 24 | ||
| 25 | #include "core/memory.h" | 25 | #include "core/memory.h" |
| 26 | #include "core/arm/skyeye_common/armdefs.h" | 26 | #include "core/arm/skyeye_common/armstate.h" |
| 27 | #include "core/arm/skyeye_common/armsupp.h" | ||
| 27 | 28 | ||
| 28 | // Register numbers in the MMU | 29 | // Register numbers in the MMU |
| 29 | enum | 30 | enum |
diff --git a/src/core/arm/skyeye_common/armstate.h b/src/core/arm/skyeye_common/armstate.h new file mode 100644 index 000000000..3ba0ba5cd --- /dev/null +++ b/src/core/arm/skyeye_common/armstate.h | |||
| @@ -0,0 +1,215 @@ | |||
| 1 | /* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator. | ||
| 2 | Copyright (C) 1994 Advanced RISC Machines Ltd. | ||
| 3 | |||
| 4 | This program is free software; you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program; if not, write to the Free Software | ||
| 16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <unordered_map> | ||
| 21 | |||
| 22 | #include "common/common_types.h" | ||
| 23 | #include "core/arm/skyeye_common/arm_regformat.h" | ||
| 24 | |||
| 25 | // Signal levels | ||
| 26 | enum { | ||
| 27 | LOW = 0, | ||
| 28 | HIGH = 1, | ||
| 29 | LOWHIGH = 1, | ||
| 30 | HIGHLOW = 2 | ||
| 31 | }; | ||
| 32 | |||
| 33 | // Cache types | ||
| 34 | enum { | ||
| 35 | NONCACHE = 0, | ||
| 36 | DATACACHE = 1, | ||
| 37 | INSTCACHE = 2, | ||
| 38 | }; | ||
| 39 | |||
| 40 | #define VFP_REG_NUM 64 | ||
| 41 | struct ARMul_State | ||
| 42 | { | ||
| 43 | u32 Emulate; // To start and stop emulation | ||
| 44 | |||
| 45 | // Order of the following register should not be modified | ||
| 46 | u32 Reg[16]; // The current register file | ||
| 47 | u32 Cpsr; // The current PSR | ||
| 48 | u32 Spsr_copy; | ||
| 49 | u32 phys_pc; | ||
| 50 | u32 Reg_usr[2]; | ||
| 51 | u32 Reg_svc[2]; // R13_SVC R14_SVC | ||
| 52 | u32 Reg_abort[2]; // R13_ABORT R14_ABORT | ||
| 53 | u32 Reg_undef[2]; // R13 UNDEF R14 UNDEF | ||
| 54 | u32 Reg_irq[2]; // R13_IRQ R14_IRQ | ||
| 55 | u32 Reg_firq[7]; // R8---R14 FIRQ | ||
| 56 | u32 Spsr[7]; // The exception psr's | ||
| 57 | u32 Mode; // The current mode | ||
| 58 | u32 Bank; // The current register bank | ||
| 59 | u32 exclusive_tag; // The address for which the local monitor is in exclusive access mode | ||
| 60 | u32 exclusive_state; | ||
| 61 | u32 exclusive_result; | ||
| 62 | u32 CP15[CP15_REGISTER_COUNT]; | ||
| 63 | |||
| 64 | // FPSID, FPSCR, and FPEXC | ||
| 65 | u32 VFP[VFP_SYSTEM_REGISTER_COUNT]; | ||
| 66 | // VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31). | ||
| 67 | // VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31), | ||
| 68 | // and only 32 singleword registers are accessible (S0-S31). | ||
| 69 | u32 ExtReg[VFP_REG_NUM]; | ||
| 70 | /* ---- End of the ordered registers ---- */ | ||
| 71 | |||
| 72 | u32 NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed | ||
| 73 | unsigned int shifter_carry_out; | ||
| 74 | |||
| 75 | // Add armv6 flags dyf:2010-08-09 | ||
| 76 | u32 GEFlag, EFlag, AFlag, QFlag; | ||
| 77 | |||
| 78 | u32 TFlag; // Thumb state | ||
| 79 | |||
| 80 | unsigned long long NumInstrs; // The number of instructions executed | ||
| 81 | unsigned NumInstrsToExecute; | ||
| 82 | |||
| 83 | unsigned NresetSig; // Reset the processor | ||
| 84 | unsigned NfiqSig; | ||
| 85 | unsigned NirqSig; | ||
| 86 | |||
| 87 | unsigned abortSig; | ||
| 88 | unsigned NtransSig; | ||
| 89 | unsigned bigendSig; | ||
| 90 | unsigned syscallSig; | ||
| 91 | |||
| 92 | // TODO(bunnei): Move this cache to a better place - it should be per codeset (likely per | ||
| 93 | // process for our purposes), not per ARMul_State (which tracks CPU core state). | ||
| 94 | std::unordered_map<u32, int> instruction_cache; | ||
| 95 | }; | ||
| 96 | |||
| 97 | /***************************************************************************\ | ||
| 98 | * The hardware vector addresses * | ||
| 99 | \***************************************************************************/ | ||
| 100 | |||
| 101 | enum { | ||
| 102 | ARMResetV = 0, | ||
| 103 | ARMUndefinedInstrV = 4, | ||
| 104 | ARMSWIV = 8, | ||
| 105 | ARMPrefetchAbortV = 12, | ||
| 106 | ARMDataAbortV = 16, | ||
| 107 | ARMAddrExceptnV = 20, | ||
| 108 | ARMIRQV = 24, | ||
| 109 | ARMFIQV = 28, | ||
| 110 | ARMErrorV = 32, // This is an offset, not an address! | ||
| 111 | |||
| 112 | ARMul_ResetV = ARMResetV, | ||
| 113 | ARMul_UndefinedInstrV = ARMUndefinedInstrV, | ||
| 114 | ARMul_SWIV = ARMSWIV, | ||
| 115 | ARMul_PrefetchAbortV = ARMPrefetchAbortV, | ||
| 116 | ARMul_DataAbortV = ARMDataAbortV, | ||
| 117 | ARMul_AddrExceptnV = ARMAddrExceptnV, | ||
| 118 | ARMul_IRQV = ARMIRQV, | ||
| 119 | ARMul_FIQV = ARMFIQV | ||
| 120 | }; | ||
| 121 | |||
| 122 | /***************************************************************************\ | ||
| 123 | * Mode and Bank Constants * | ||
| 124 | \***************************************************************************/ | ||
| 125 | |||
| 126 | enum PrivilegeMode { | ||
| 127 | USER32MODE = 16, | ||
| 128 | FIQ32MODE = 17, | ||
| 129 | IRQ32MODE = 18, | ||
| 130 | SVC32MODE = 19, | ||
| 131 | ABORT32MODE = 23, | ||
| 132 | UNDEF32MODE = 27, | ||
| 133 | SYSTEM32MODE = 31 | ||
| 134 | }; | ||
| 135 | |||
| 136 | enum { | ||
| 137 | USERBANK = 0, | ||
| 138 | FIQBANK = 1, | ||
| 139 | IRQBANK = 2, | ||
| 140 | SVCBANK = 3, | ||
| 141 | ABORTBANK = 4, | ||
| 142 | UNDEFBANK = 5, | ||
| 143 | DUMMYBANK = 6, | ||
| 144 | SYSTEMBANK = 7 | ||
| 145 | }; | ||
| 146 | |||
| 147 | /***************************************************************************\ | ||
| 148 | * Definitions of things in the emulator * | ||
| 149 | \***************************************************************************/ | ||
| 150 | void ARMul_Reset(ARMul_State* state); | ||
| 151 | |||
| 152 | /***************************************************************************\ | ||
| 153 | * Definitions of things in the co-processor interface * | ||
| 154 | \***************************************************************************/ | ||
| 155 | |||
| 156 | enum { | ||
| 157 | ARMul_FIRST = 0, | ||
| 158 | ARMul_TRANSFER = 1, | ||
| 159 | ARMul_BUSY = 2, | ||
| 160 | ARMul_DATA = 3, | ||
| 161 | ARMul_INTERRUPT = 4, | ||
| 162 | ARMul_DONE = 0, | ||
| 163 | ARMul_CANT = 1, | ||
| 164 | ARMul_INC = 3 | ||
| 165 | }; | ||
| 166 | |||
| 167 | /***************************************************************************\ | ||
| 168 | * Definitions of things in the host environment * | ||
| 169 | \***************************************************************************/ | ||
| 170 | |||
| 171 | enum ConditionCode { | ||
| 172 | EQ = 0, | ||
| 173 | NE = 1, | ||
| 174 | CS = 2, | ||
| 175 | CC = 3, | ||
| 176 | MI = 4, | ||
| 177 | PL = 5, | ||
| 178 | VS = 6, | ||
| 179 | VC = 7, | ||
| 180 | HI = 8, | ||
| 181 | LS = 9, | ||
| 182 | GE = 10, | ||
| 183 | LT = 11, | ||
| 184 | GT = 12, | ||
| 185 | LE = 13, | ||
| 186 | AL = 14, | ||
| 187 | NV = 15, | ||
| 188 | }; | ||
| 189 | |||
| 190 | // Flags for use with the APSR. | ||
| 191 | enum : u32 { | ||
| 192 | NBIT = (1U << 31U), | ||
| 193 | ZBIT = (1 << 30), | ||
| 194 | CBIT = (1 << 29), | ||
| 195 | VBIT = (1 << 28), | ||
| 196 | QBIT = (1 << 27), | ||
| 197 | JBIT = (1 << 24), | ||
| 198 | EBIT = (1 << 9), | ||
| 199 | ABIT = (1 << 8), | ||
| 200 | IBIT = (1 << 7), | ||
| 201 | FBIT = (1 << 6), | ||
| 202 | TBIT = (1 << 5), | ||
| 203 | |||
| 204 | // Masks for groups of bits in the APSR. | ||
| 205 | MODEBITS = 0x1F, | ||
| 206 | INTBITS = 0x1C0, | ||
| 207 | }; | ||
| 208 | |||
| 209 | // Values for Emulate. | ||
| 210 | enum { | ||
| 211 | STOP = 0, // Stop | ||
| 212 | CHANGEMODE = 1, // Change mode | ||
| 213 | ONCE = 2, // Execute just one iteration | ||
| 214 | RUN = 3 // Continuous execution | ||
| 215 | }; | ||
diff --git a/src/core/arm/skyeye_common/armsupp.cpp b/src/core/arm/skyeye_common/armsupp.cpp new file mode 100644 index 000000000..affbf193a --- /dev/null +++ b/src/core/arm/skyeye_common/armsupp.cpp | |||
| @@ -0,0 +1,638 @@ | |||
| 1 | /* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator. | ||
| 2 | Copyright (C) 1994 Advanced RISC Machines Ltd. | ||
| 3 | |||
| 4 | This program is free software; you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program; if not, write to the Free Software | ||
| 16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 17 | |||
| 18 | #include "common/logging/log.h" | ||
| 19 | |||
| 20 | #include "core/mem_map.h" | ||
| 21 | #include "core/arm/skyeye_common/arm_regformat.h" | ||
| 22 | #include "core/arm/skyeye_common/armstate.h" | ||
| 23 | #include "core/arm/skyeye_common/armsupp.h" | ||
| 24 | |||
| 25 | // Unsigned sum of absolute difference | ||
| 26 | u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right) | ||
| 27 | { | ||
| 28 | if (left > right) | ||
| 29 | return left - right; | ||
| 30 | |||
| 31 | return right - left; | ||
| 32 | } | ||
| 33 | |||
| 34 | // Add with carry, indicates if a carry-out or signed overflow occurred. | ||
| 35 | u32 AddWithCarry(u32 left, u32 right, u32 carry_in, bool* carry_out_occurred, bool* overflow_occurred) | ||
| 36 | { | ||
| 37 | u64 unsigned_sum = (u64)left + (u64)right + (u64)carry_in; | ||
| 38 | s64 signed_sum = (s64)(s32)left + (s64)(s32)right + (s64)carry_in; | ||
| 39 | u64 result = (unsigned_sum & 0xFFFFFFFF); | ||
| 40 | |||
| 41 | if (carry_out_occurred) | ||
| 42 | *carry_out_occurred = (result != unsigned_sum); | ||
| 43 | |||
| 44 | if (overflow_occurred) | ||
| 45 | *overflow_occurred = ((s64)(s32)result != signed_sum); | ||
| 46 | |||
| 47 | return (u32)result; | ||
| 48 | } | ||
| 49 | |||
| 50 | // Compute whether an addition of A and B, giving RESULT, overflowed. | ||
| 51 | bool AddOverflow(u32 a, u32 b, u32 result) | ||
| 52 | { | ||
| 53 | return ((NEG(a) && NEG(b) && POS(result)) || | ||
| 54 | (POS(a) && POS(b) && NEG(result))); | ||
| 55 | } | ||
| 56 | |||
| 57 | // Compute whether a subtraction of A and B, giving RESULT, overflowed. | ||
| 58 | bool SubOverflow(u32 a, u32 b, u32 result) | ||
| 59 | { | ||
| 60 | return ((NEG(a) && POS(b) && POS(result)) || | ||
| 61 | (POS(a) && NEG(b) && NEG(result))); | ||
| 62 | } | ||
| 63 | |||
| 64 | // Returns true if the Q flag should be set as a result of overflow. | ||
| 65 | bool ARMul_AddOverflowQ(u32 a, u32 b) | ||
| 66 | { | ||
| 67 | u32 result = a + b; | ||
| 68 | if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0) | ||
| 69 | return true; | ||
| 70 | |||
| 71 | return false; | ||
| 72 | } | ||
| 73 | |||
| 74 | // 8-bit signed saturated addition | ||
| 75 | u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right) | ||
| 76 | { | ||
| 77 | u8 result = left + right; | ||
| 78 | |||
| 79 | if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) == 0) { | ||
| 80 | if (left & 0x80) | ||
| 81 | result = 0x80; | ||
| 82 | else | ||
| 83 | result = 0x7F; | ||
| 84 | } | ||
| 85 | |||
| 86 | return result; | ||
| 87 | } | ||
| 88 | |||
| 89 | // 8-bit signed saturated subtraction | ||
| 90 | u8 ARMul_SignedSaturatedSub8(u8 left, u8 right) | ||
| 91 | { | ||
| 92 | u8 result = left - right; | ||
| 93 | |||
| 94 | if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) != 0) { | ||
| 95 | if (left & 0x80) | ||
| 96 | result = 0x80; | ||
| 97 | else | ||
| 98 | result = 0x7F; | ||
| 99 | } | ||
| 100 | |||
| 101 | return result; | ||
| 102 | } | ||
| 103 | |||
| 104 | // 16-bit signed saturated addition | ||
| 105 | u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right) | ||
| 106 | { | ||
| 107 | u16 result = left + right; | ||
| 108 | |||
| 109 | if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) == 0) { | ||
| 110 | if (left & 0x8000) | ||
| 111 | result = 0x8000; | ||
| 112 | else | ||
| 113 | result = 0x7FFF; | ||
| 114 | } | ||
| 115 | |||
| 116 | return result; | ||
| 117 | } | ||
| 118 | |||
| 119 | // 16-bit signed saturated subtraction | ||
| 120 | u16 ARMul_SignedSaturatedSub16(u16 left, u16 right) | ||
| 121 | { | ||
| 122 | u16 result = left - right; | ||
| 123 | |||
| 124 | if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) != 0) { | ||
| 125 | if (left & 0x8000) | ||
| 126 | result = 0x8000; | ||
| 127 | else | ||
| 128 | result = 0x7FFF; | ||
| 129 | } | ||
| 130 | |||
| 131 | return result; | ||
| 132 | } | ||
| 133 | |||
| 134 | // 8-bit unsigned saturated addition | ||
| 135 | u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right) | ||
| 136 | { | ||
| 137 | u8 result = left + right; | ||
| 138 | |||
| 139 | if (result < left) | ||
| 140 | result = 0xFF; | ||
| 141 | |||
| 142 | return result; | ||
| 143 | } | ||
| 144 | |||
| 145 | // 16-bit unsigned saturated addition | ||
| 146 | u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right) | ||
| 147 | { | ||
| 148 | u16 result = left + right; | ||
| 149 | |||
| 150 | if (result < left) | ||
| 151 | result = 0xFFFF; | ||
| 152 | |||
| 153 | return result; | ||
| 154 | } | ||
| 155 | |||
| 156 | // 8-bit unsigned saturated subtraction | ||
| 157 | u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right) | ||
| 158 | { | ||
| 159 | if (left <= right) | ||
| 160 | return 0; | ||
| 161 | |||
| 162 | return left - right; | ||
| 163 | } | ||
| 164 | |||
| 165 | // 16-bit unsigned saturated subtraction | ||
| 166 | u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right) | ||
| 167 | { | ||
| 168 | if (left <= right) | ||
| 169 | return 0; | ||
| 170 | |||
| 171 | return left - right; | ||
| 172 | } | ||
| 173 | |||
| 174 | // Signed saturation. | ||
| 175 | u32 ARMul_SignedSatQ(s32 value, u8 shift, bool* saturation_occurred) | ||
| 176 | { | ||
| 177 | const u32 max = (1 << shift) - 1; | ||
| 178 | const s32 top = (value >> shift); | ||
| 179 | |||
| 180 | if (top > 0) { | ||
| 181 | *saturation_occurred = true; | ||
| 182 | return max; | ||
| 183 | } | ||
| 184 | else if (top < -1) { | ||
| 185 | *saturation_occurred = true; | ||
| 186 | return ~max; | ||
| 187 | } | ||
| 188 | |||
| 189 | *saturation_occurred = false; | ||
| 190 | return (u32)value; | ||
| 191 | } | ||
| 192 | |||
| 193 | // Unsigned saturation | ||
| 194 | u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred) | ||
| 195 | { | ||
| 196 | const u32 max = (1 << shift) - 1; | ||
| 197 | |||
| 198 | if (value < 0) { | ||
| 199 | *saturation_occurred = true; | ||
| 200 | return 0; | ||
| 201 | } else if ((u32)value > max) { | ||
| 202 | *saturation_occurred = true; | ||
| 203 | return max; | ||
| 204 | } | ||
| 205 | |||
| 206 | *saturation_occurred = false; | ||
| 207 | return (u32)value; | ||
| 208 | } | ||
| 209 | |||
| 210 | // Whether or not the given CPU is in big endian mode (E bit is set) | ||
| 211 | bool InBigEndianMode(ARMul_State* cpu) | ||
| 212 | { | ||
| 213 | return (cpu->Cpsr & (1 << 9)) != 0; | ||
| 214 | } | ||
| 215 | |||
| 216 | // Whether or not the given CPU is in a mode other than user mode. | ||
| 217 | bool InAPrivilegedMode(ARMul_State* cpu) | ||
| 218 | { | ||
| 219 | return (cpu->Mode != USER32MODE); | ||
| 220 | } | ||
| 221 | |||
| 222 | // Reads from the CP15 registers. Used with implementation of the MRC instruction. | ||
| 223 | // Note that since the 3DS does not have the hypervisor extensions, these registers | ||
| 224 | // are not implemented. | ||
| 225 | u32 ReadCP15Register(ARMul_State* cpu, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) | ||
| 226 | { | ||
| 227 | // Unprivileged registers | ||
| 228 | if (crn == 13 && opcode_1 == 0 && crm == 0) | ||
| 229 | { | ||
| 230 | if (opcode_2 == 2) | ||
| 231 | return cpu->CP15[CP15_THREAD_UPRW]; | ||
| 232 | |||
| 233 | if (opcode_2 == 3) | ||
| 234 | return cpu->CP15[CP15_THREAD_URO]; | ||
| 235 | } | ||
| 236 | |||
| 237 | if (InAPrivilegedMode(cpu)) | ||
| 238 | { | ||
| 239 | if (crn == 0 && opcode_1 == 0) | ||
| 240 | { | ||
| 241 | if (crm == 0) | ||
| 242 | { | ||
| 243 | if (opcode_2 == 0) | ||
| 244 | return cpu->CP15[CP15_MAIN_ID]; | ||
| 245 | |||
| 246 | if (opcode_2 == 1) | ||
| 247 | return cpu->CP15[CP15_CACHE_TYPE]; | ||
| 248 | |||
| 249 | if (opcode_2 == 3) | ||
| 250 | return cpu->CP15[CP15_TLB_TYPE]; | ||
| 251 | |||
| 252 | if (opcode_2 == 5) | ||
| 253 | return cpu->CP15[CP15_CPU_ID]; | ||
| 254 | } | ||
| 255 | else if (crm == 1) | ||
| 256 | { | ||
| 257 | if (opcode_2 == 0) | ||
| 258 | return cpu->CP15[CP15_PROCESSOR_FEATURE_0]; | ||
| 259 | |||
| 260 | if (opcode_2 == 1) | ||
| 261 | return cpu->CP15[CP15_PROCESSOR_FEATURE_1]; | ||
| 262 | |||
| 263 | if (opcode_2 == 2) | ||
| 264 | return cpu->CP15[CP15_DEBUG_FEATURE_0]; | ||
| 265 | |||
| 266 | if (opcode_2 == 4) | ||
| 267 | return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_0]; | ||
| 268 | |||
| 269 | if (opcode_2 == 5) | ||
| 270 | return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_1]; | ||
| 271 | |||
| 272 | if (opcode_2 == 6) | ||
| 273 | return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_2]; | ||
| 274 | |||
| 275 | if (opcode_2 == 7) | ||
| 276 | return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_3]; | ||
| 277 | } | ||
| 278 | else if (crm == 2) | ||
| 279 | { | ||
| 280 | if (opcode_2 == 0) | ||
| 281 | return cpu->CP15[CP15_ISA_FEATURE_0]; | ||
| 282 | |||
| 283 | if (opcode_2 == 1) | ||
| 284 | return cpu->CP15[CP15_ISA_FEATURE_1]; | ||
| 285 | |||
| 286 | if (opcode_2 == 2) | ||
| 287 | return cpu->CP15[CP15_ISA_FEATURE_2]; | ||
| 288 | |||
| 289 | if (opcode_2 == 3) | ||
| 290 | return cpu->CP15[CP15_ISA_FEATURE_3]; | ||
| 291 | |||
| 292 | if (opcode_2 == 4) | ||
| 293 | return cpu->CP15[CP15_ISA_FEATURE_4]; | ||
| 294 | } | ||
| 295 | } | ||
| 296 | |||
| 297 | if (crn == 1 && opcode_1 == 0 && crm == 0) | ||
| 298 | { | ||
| 299 | if (opcode_2 == 0) | ||
| 300 | return cpu->CP15[CP15_CONTROL]; | ||
| 301 | |||
| 302 | if (opcode_2 == 1) | ||
| 303 | return cpu->CP15[CP15_AUXILIARY_CONTROL]; | ||
| 304 | |||
| 305 | if (opcode_2 == 2) | ||
| 306 | return cpu->CP15[CP15_COPROCESSOR_ACCESS_CONTROL]; | ||
| 307 | } | ||
| 308 | |||
| 309 | if (crn == 2 && opcode_1 == 0 && crm == 0) | ||
| 310 | { | ||
| 311 | if (opcode_2 == 0) | ||
| 312 | return cpu->CP15[CP15_TRANSLATION_BASE_TABLE_0]; | ||
| 313 | |||
| 314 | if (opcode_2 == 1) | ||
| 315 | return cpu->CP15[CP15_TRANSLATION_BASE_TABLE_1]; | ||
| 316 | |||
| 317 | if (opcode_2 == 2) | ||
| 318 | return cpu->CP15[CP15_TRANSLATION_BASE_CONTROL]; | ||
| 319 | } | ||
| 320 | |||
| 321 | if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) | ||
| 322 | return cpu->CP15[CP15_DOMAIN_ACCESS_CONTROL]; | ||
| 323 | |||
| 324 | if (crn == 5 && opcode_1 == 0 && crm == 0) | ||
| 325 | { | ||
| 326 | if (opcode_2 == 0) | ||
| 327 | return cpu->CP15[CP15_FAULT_STATUS]; | ||
| 328 | |||
| 329 | if (opcode_2 == 1) | ||
| 330 | return cpu->CP15[CP15_INSTR_FAULT_STATUS]; | ||
| 331 | } | ||
| 332 | |||
| 333 | if (crn == 6 && opcode_1 == 0 && crm == 0) | ||
| 334 | { | ||
| 335 | if (opcode_2 == 0) | ||
| 336 | return cpu->CP15[CP15_FAULT_ADDRESS]; | ||
| 337 | |||
| 338 | if (opcode_2 == 1) | ||
| 339 | return cpu->CP15[CP15_WFAR]; | ||
| 340 | } | ||
| 341 | |||
| 342 | if (crn == 7 && opcode_1 == 0 && crm == 4 && opcode_2 == 0) | ||
| 343 | return cpu->CP15[CP15_PHYS_ADDRESS]; | ||
| 344 | |||
| 345 | if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) | ||
| 346 | return cpu->CP15[CP15_DATA_CACHE_LOCKDOWN]; | ||
| 347 | |||
| 348 | if (crn == 10 && opcode_1 == 0) | ||
| 349 | { | ||
| 350 | if (crm == 0 && opcode_2 == 0) | ||
| 351 | return cpu->CP15[CP15_TLB_LOCKDOWN]; | ||
| 352 | |||
| 353 | if (crm == 2) | ||
| 354 | { | ||
| 355 | if (opcode_2 == 0) | ||
| 356 | return cpu->CP15[CP15_PRIMARY_REGION_REMAP]; | ||
| 357 | |||
| 358 | if (opcode_2 == 1) | ||
| 359 | return cpu->CP15[CP15_NORMAL_REGION_REMAP]; | ||
| 360 | } | ||
| 361 | } | ||
| 362 | |||
| 363 | if (crn == 13 && crm == 0) | ||
| 364 | { | ||
| 365 | if (opcode_2 == 0) | ||
| 366 | return cpu->CP15[CP15_PID]; | ||
| 367 | |||
| 368 | if (opcode_2 == 1) | ||
| 369 | return cpu->CP15[CP15_CONTEXT_ID]; | ||
| 370 | |||
| 371 | if (opcode_2 == 4) | ||
| 372 | return cpu->CP15[CP15_THREAD_PRW]; | ||
| 373 | } | ||
| 374 | |||
| 375 | if (crn == 15) | ||
| 376 | { | ||
| 377 | if (opcode_1 == 0 && crm == 12) | ||
| 378 | { | ||
| 379 | if (opcode_2 == 0) | ||
| 380 | return cpu->CP15[CP15_PERFORMANCE_MONITOR_CONTROL]; | ||
| 381 | |||
| 382 | if (opcode_2 == 1) | ||
| 383 | return cpu->CP15[CP15_CYCLE_COUNTER]; | ||
| 384 | |||
| 385 | if (opcode_2 == 2) | ||
| 386 | return cpu->CP15[CP15_COUNT_0]; | ||
| 387 | |||
| 388 | if (opcode_2 == 3) | ||
| 389 | return cpu->CP15[CP15_COUNT_1]; | ||
| 390 | } | ||
| 391 | |||
| 392 | if (opcode_1 == 5 && opcode_2 == 2) | ||
| 393 | { | ||
| 394 | if (crm == 5) | ||
| 395 | return cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS]; | ||
| 396 | |||
| 397 | if (crm == 6) | ||
| 398 | return cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS]; | ||
| 399 | |||
| 400 | if (crm == 7) | ||
| 401 | return cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE]; | ||
| 402 | } | ||
| 403 | |||
| 404 | if (opcode_1 == 7 && crm == 1 && opcode_2 == 0) | ||
| 405 | return cpu->CP15[CP15_TLB_DEBUG_CONTROL]; | ||
| 406 | } | ||
| 407 | } | ||
| 408 | |||
| 409 | LOG_ERROR(Core_ARM11, "MRC CRn=%u, CRm=%u, OP1=%u OP2=%u is not implemented. Returning zero.", crn, crm, opcode_1, opcode_2); | ||
| 410 | return 0; | ||
| 411 | } | ||
| 412 | |||
| 413 | // Write to the CP15 registers. Used with implementation of the MCR instruction. | ||
| 414 | // Note that since the 3DS does not have the hypervisor extensions, these registers | ||
| 415 | // are not implemented. | ||
| 416 | void WriteCP15Register(ARMul_State* cpu, u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) | ||
| 417 | { | ||
| 418 | if (InAPrivilegedMode(cpu)) | ||
| 419 | { | ||
| 420 | if (crn == 1 && opcode_1 == 0 && crm == 0) | ||
| 421 | { | ||
| 422 | if (opcode_2 == 0) | ||
| 423 | cpu->CP15[CP15_CONTROL] = value; | ||
| 424 | else if (opcode_2 == 1) | ||
| 425 | cpu->CP15[CP15_AUXILIARY_CONTROL] = value; | ||
| 426 | else if (opcode_2 == 2) | ||
| 427 | cpu->CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = value; | ||
| 428 | } | ||
| 429 | else if (crn == 2 && opcode_1 == 0 && crm == 0) | ||
| 430 | { | ||
| 431 | if (opcode_2 == 0) | ||
| 432 | cpu->CP15[CP15_TRANSLATION_BASE_TABLE_0] = value; | ||
| 433 | else if (opcode_2 == 1) | ||
| 434 | cpu->CP15[CP15_TRANSLATION_BASE_TABLE_1] = value; | ||
| 435 | else if (opcode_2 == 2) | ||
| 436 | cpu->CP15[CP15_TRANSLATION_BASE_CONTROL] = value; | ||
| 437 | } | ||
| 438 | else if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) | ||
| 439 | { | ||
| 440 | cpu->CP15[CP15_DOMAIN_ACCESS_CONTROL] = value; | ||
| 441 | } | ||
| 442 | else if (crn == 5 && opcode_1 == 0 && crm == 0) | ||
| 443 | { | ||
| 444 | if (opcode_2 == 0) | ||
| 445 | cpu->CP15[CP15_FAULT_STATUS] = value; | ||
| 446 | else if (opcode_2 == 1) | ||
| 447 | cpu->CP15[CP15_INSTR_FAULT_STATUS] = value; | ||
| 448 | } | ||
| 449 | else if (crn == 6 && opcode_1 == 0 && crm == 0) | ||
| 450 | { | ||
| 451 | if (opcode_2 == 0) | ||
| 452 | cpu->CP15[CP15_FAULT_ADDRESS] = value; | ||
| 453 | else if (opcode_2 == 1) | ||
| 454 | cpu->CP15[CP15_WFAR] = value; | ||
| 455 | } | ||
| 456 | else if (crn == 7 && opcode_1 == 0) | ||
| 457 | { | ||
| 458 | if (crm == 0 && opcode_2 == 4) | ||
| 459 | { | ||
| 460 | cpu->CP15[CP15_WAIT_FOR_INTERRUPT] = value; | ||
| 461 | } | ||
| 462 | else if (crm == 4 && opcode_2 == 0) | ||
| 463 | { | ||
| 464 | // NOTE: Not entirely accurate. This should do permission checks. | ||
| 465 | cpu->CP15[CP15_PHYS_ADDRESS] = Memory::VirtualToPhysicalAddress(value); | ||
| 466 | } | ||
| 467 | else if (crm == 5) | ||
| 468 | { | ||
| 469 | if (opcode_2 == 0) | ||
| 470 | cpu->CP15[CP15_INVALIDATE_INSTR_CACHE] = value; | ||
| 471 | else if (opcode_2 == 1) | ||
| 472 | cpu->CP15[CP15_INVALIDATE_INSTR_CACHE_USING_MVA] = value; | ||
| 473 | else if (opcode_2 == 2) | ||
| 474 | cpu->CP15[CP15_INVALIDATE_INSTR_CACHE_USING_INDEX] = value; | ||
| 475 | else if (opcode_2 == 6) | ||
| 476 | cpu->CP15[CP15_FLUSH_BRANCH_TARGET_CACHE] = value; | ||
| 477 | else if (opcode_2 == 7) | ||
| 478 | cpu->CP15[CP15_FLUSH_BRANCH_TARGET_CACHE_ENTRY] = value; | ||
| 479 | } | ||
| 480 | else if (crm == 6) | ||
| 481 | { | ||
| 482 | if (opcode_2 == 0) | ||
| 483 | cpu->CP15[CP15_INVALIDATE_DATA_CACHE] = value; | ||
| 484 | else if (opcode_2 == 1) | ||
| 485 | cpu->CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value; | ||
| 486 | else if (opcode_2 == 2) | ||
| 487 | cpu->CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value; | ||
| 488 | } | ||
| 489 | else if (crm == 7 && opcode_2 == 0) | ||
| 490 | { | ||
| 491 | cpu->CP15[CP15_INVALIDATE_DATA_AND_INSTR_CACHE] = value; | ||
| 492 | } | ||
| 493 | else if (crm == 10) | ||
| 494 | { | ||
| 495 | if (opcode_2 == 0) | ||
| 496 | cpu->CP15[CP15_CLEAN_DATA_CACHE] = value; | ||
| 497 | else if (opcode_2 == 1) | ||
| 498 | cpu->CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_MVA] = value; | ||
| 499 | else if (opcode_2 == 2) | ||
| 500 | cpu->CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_INDEX] = value; | ||
| 501 | } | ||
| 502 | else if (crm == 14) | ||
| 503 | { | ||
| 504 | if (opcode_2 == 0) | ||
| 505 | cpu->CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE] = value; | ||
| 506 | else if (opcode_2 == 1) | ||
| 507 | cpu->CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value; | ||
| 508 | else if (opcode_2 == 2) | ||
| 509 | cpu->CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value; | ||
| 510 | } | ||
| 511 | } | ||
| 512 | else if (crn == 8 && opcode_1 == 0) | ||
| 513 | { | ||
| 514 | LOG_WARNING(Core_ARM11, "TLB operations not fully implemented."); | ||
| 515 | |||
| 516 | if (crm == 5) | ||
| 517 | { | ||
| 518 | if (opcode_2 == 0) | ||
| 519 | cpu->CP15[CP15_INVALIDATE_ITLB] = value; | ||
| 520 | else if (opcode_2 == 1) | ||
| 521 | cpu->CP15[CP15_INVALIDATE_ITLB_SINGLE_ENTRY] = value; | ||
| 522 | else if (opcode_2 == 2) | ||
| 523 | cpu->CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_ASID_MATCH] = value; | ||
| 524 | else if (opcode_2 == 3) | ||
| 525 | cpu->CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_MVA] = value; | ||
| 526 | } | ||
| 527 | else if (crm == 6) | ||
| 528 | { | ||
| 529 | if (opcode_2 == 0) | ||
| 530 | cpu->CP15[CP15_INVALIDATE_DTLB] = value; | ||
| 531 | else if (opcode_2 == 1) | ||
| 532 | cpu->CP15[CP15_INVALIDATE_DTLB_SINGLE_ENTRY] = value; | ||
| 533 | else if (opcode_2 == 2) | ||
| 534 | cpu->CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_ASID_MATCH] = value; | ||
| 535 | else if (opcode_2 == 3) | ||
| 536 | cpu->CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_MVA] = value; | ||
| 537 | } | ||
| 538 | else if (crm == 7) | ||
| 539 | { | ||
| 540 | if (opcode_2 == 0) | ||
| 541 | cpu->CP15[CP15_INVALIDATE_UTLB] = value; | ||
| 542 | else if (opcode_2 == 1) | ||
| 543 | cpu->CP15[CP15_INVALIDATE_UTLB_SINGLE_ENTRY] = value; | ||
| 544 | else if (opcode_2 == 2) | ||
| 545 | cpu->CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_ASID_MATCH] = value; | ||
| 546 | else if (opcode_2 == 3) | ||
| 547 | cpu->CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_MVA] = value; | ||
| 548 | } | ||
| 549 | } | ||
| 550 | else if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) | ||
| 551 | { | ||
| 552 | cpu->CP15[CP15_DATA_CACHE_LOCKDOWN] = value; | ||
| 553 | } | ||
| 554 | else if (crn == 10 && opcode_1 == 0) | ||
| 555 | { | ||
| 556 | if (crm == 0 && opcode_2 == 0) | ||
| 557 | { | ||
| 558 | cpu->CP15[CP15_TLB_LOCKDOWN] = value; | ||
| 559 | } | ||
| 560 | else if (crm == 2) | ||
| 561 | { | ||
| 562 | if (opcode_2 == 0) | ||
| 563 | cpu->CP15[CP15_PRIMARY_REGION_REMAP] = value; | ||
| 564 | else if (opcode_2 == 1) | ||
| 565 | cpu->CP15[CP15_NORMAL_REGION_REMAP] = value; | ||
| 566 | } | ||
| 567 | } | ||
| 568 | else if (crn == 13 && opcode_1 == 0 && crm == 0) | ||
| 569 | { | ||
| 570 | if (opcode_2 == 0) | ||
| 571 | cpu->CP15[CP15_PID] = value; | ||
| 572 | else if (opcode_2 == 1) | ||
| 573 | cpu->CP15[CP15_CONTEXT_ID] = value; | ||
| 574 | else if (opcode_2 == 3) | ||
| 575 | cpu->CP15[CP15_THREAD_URO] = value; | ||
| 576 | else if (opcode_2 == 4) | ||
| 577 | cpu->CP15[CP15_THREAD_PRW] = value; | ||
| 578 | } | ||
| 579 | else if (crn == 15) | ||
| 580 | { | ||
| 581 | if (opcode_1 == 0 && crm == 12) | ||
| 582 | { | ||
| 583 | if (opcode_2 == 0) | ||
| 584 | cpu->CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = value; | ||
| 585 | else if (opcode_2 == 1) | ||
| 586 | cpu->CP15[CP15_CYCLE_COUNTER] = value; | ||
| 587 | else if (opcode_2 == 2) | ||
| 588 | cpu->CP15[CP15_COUNT_0] = value; | ||
| 589 | else if (opcode_2 == 3) | ||
| 590 | cpu->CP15[CP15_COUNT_1] = value; | ||
| 591 | } | ||
| 592 | else if (opcode_1 == 5) | ||
| 593 | { | ||
| 594 | if (crm == 4) | ||
| 595 | { | ||
| 596 | if (opcode_2 == 2) | ||
| 597 | cpu->CP15[CP15_READ_MAIN_TLB_LOCKDOWN_ENTRY] = value; | ||
| 598 | else if (opcode_2 == 4) | ||
| 599 | cpu->CP15[CP15_WRITE_MAIN_TLB_LOCKDOWN_ENTRY] = value; | ||
| 600 | } | ||
| 601 | else if (crm == 5 && opcode_2 == 2) | ||
| 602 | { | ||
| 603 | cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = value; | ||
| 604 | } | ||
| 605 | else if (crm == 6 && opcode_2 == 2) | ||
| 606 | { | ||
| 607 | cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = value; | ||
| 608 | } | ||
| 609 | else if (crm == 7 && opcode_2 == 2) | ||
| 610 | { | ||
| 611 | cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = value; | ||
| 612 | } | ||
| 613 | } | ||
| 614 | else if (opcode_1 == 7 && crm == 1 && opcode_2 == 0) | ||
| 615 | { | ||
| 616 | cpu->CP15[CP15_TLB_DEBUG_CONTROL] = value; | ||
| 617 | } | ||
| 618 | } | ||
| 619 | } | ||
| 620 | |||
| 621 | // Unprivileged registers | ||
| 622 | if (crn == 7 && opcode_1 == 0 && crm == 5 && opcode_2 == 4) | ||
| 623 | { | ||
| 624 | cpu->CP15[CP15_FLUSH_PREFETCH_BUFFER] = value; | ||
| 625 | } | ||
| 626 | else if (crn == 7 && opcode_1 == 0 && crm == 10) | ||
| 627 | { | ||
| 628 | if (opcode_2 == 4) | ||
| 629 | cpu->CP15[CP15_DATA_SYNC_BARRIER] = value; | ||
| 630 | else if (opcode_2 == 5) | ||
| 631 | cpu->CP15[CP15_DATA_MEMORY_BARRIER] = value; | ||
| 632 | |||
| 633 | } | ||
| 634 | else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2) | ||
| 635 | { | ||
| 636 | cpu->CP15[CP15_THREAD_UPRW] = value; | ||
| 637 | } | ||
| 638 | } | ||
diff --git a/src/core/arm/skyeye_common/armsupp.h b/src/core/arm/skyeye_common/armsupp.h new file mode 100644 index 000000000..5cf1cd1d3 --- /dev/null +++ b/src/core/arm/skyeye_common/armsupp.h | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | |||
| 9 | struct ARMul_State; | ||
| 10 | |||
| 11 | #define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1)) | ||
| 12 | #define BIT(s, n) ((s >> (n)) & 1) | ||
| 13 | |||
| 14 | #define POS(i) ( (~(i)) >> 31 ) | ||
| 15 | #define NEG(i) ( (i) >> 31 ) | ||
| 16 | |||
| 17 | bool AddOverflow(u32, u32, u32); | ||
| 18 | bool SubOverflow(u32, u32, u32); | ||
| 19 | |||
| 20 | u32 AddWithCarry(u32, u32, u32, bool*, bool*); | ||
| 21 | bool ARMul_AddOverflowQ(u32, u32); | ||
| 22 | |||
| 23 | u8 ARMul_SignedSaturatedAdd8(u8, u8); | ||
| 24 | u8 ARMul_SignedSaturatedSub8(u8, u8); | ||
| 25 | u16 ARMul_SignedSaturatedAdd16(u16, u16); | ||
| 26 | u16 ARMul_SignedSaturatedSub16(u16, u16); | ||
| 27 | |||
| 28 | u8 ARMul_UnsignedSaturatedAdd8(u8, u8); | ||
| 29 | u16 ARMul_UnsignedSaturatedAdd16(u16, u16); | ||
| 30 | u8 ARMul_UnsignedSaturatedSub8(u8, u8); | ||
| 31 | u16 ARMul_UnsignedSaturatedSub16(u16, u16); | ||
| 32 | u8 ARMul_UnsignedAbsoluteDifference(u8, u8); | ||
| 33 | u32 ARMul_SignedSatQ(s32, u8, bool*); | ||
| 34 | u32 ARMul_UnsignedSatQ(s32, u8, bool*); | ||
| 35 | |||
| 36 | bool InBigEndianMode(ARMul_State*); | ||
| 37 | bool InAPrivilegedMode(ARMul_State*); | ||
| 38 | |||
| 39 | u32 ReadCP15Register(ARMul_State* cpu, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2); | ||
| 40 | void WriteCP15Register(ARMul_State* cpu, u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2); | ||
diff --git a/src/core/arm/skyeye_common/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp index 1ffc1f9af..26f303de4 100644 --- a/src/core/arm/skyeye_common/vfp/vfp.cpp +++ b/src/core/arm/skyeye_common/vfp/vfp.cpp | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #include "common/common_funcs.h" | 23 | #include "common/common_funcs.h" |
| 24 | #include "common/logging/log.h" | 24 | #include "common/logging/log.h" |
| 25 | 25 | ||
| 26 | #include "core/arm/skyeye_common/armdefs.h" | 26 | #include "core/arm/skyeye_common/armstate.h" |
| 27 | #include "core/arm/skyeye_common/vfp/asm_vfp.h" | 27 | #include "core/arm/skyeye_common/vfp/asm_vfp.h" |
| 28 | #include "core/arm/skyeye_common/vfp/vfp.h" | 28 | #include "core/arm/skyeye_common/vfp/vfp.h" |
| 29 | 29 | ||
| @@ -43,7 +43,7 @@ void VFPInit(ARMul_State* state) | |||
| 43 | state->VFP[VFP_MVFR1] = 0; | 43 | state->VFP[VFP_MVFR1] = 0; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value) | 46 | void VMOVBRS(ARMul_State* state, u32 to_arm, u32 t, u32 n, u32* value) |
| 47 | { | 47 | { |
| 48 | if (to_arm) | 48 | if (to_arm) |
| 49 | { | 49 | { |
| @@ -55,7 +55,7 @@ void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* | |||
| 55 | } | 55 | } |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2) | 58 | void VMOVBRRD(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2) |
| 59 | { | 59 | { |
| 60 | if (to_arm) | 60 | if (to_arm) |
| 61 | { | 61 | { |
| @@ -68,7 +68,7 @@ void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword | |||
| 68 | state->ExtReg[n*2] = *value1; | 68 | state->ExtReg[n*2] = *value1; |
| 69 | } | 69 | } |
| 70 | } | 70 | } |
| 71 | void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2) | 71 | void VMOVBRRSS(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2) |
| 72 | { | 72 | { |
| 73 | if (to_arm) | 73 | if (to_arm) |
| 74 | { | 74 | { |
| @@ -82,7 +82,7 @@ void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMwor | |||
| 82 | } | 82 | } |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm) | 85 | void VMOVI(ARMul_State* state, u32 single, u32 d, u32 imm) |
| 86 | { | 86 | { |
| 87 | if (single) | 87 | if (single) |
| 88 | { | 88 | { |
| @@ -95,7 +95,7 @@ void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm) | |||
| 95 | state->ExtReg[d*2] = 0; | 95 | state->ExtReg[d*2] = 0; |
| 96 | } | 96 | } |
| 97 | } | 97 | } |
| 98 | void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword m) | 98 | void VMOVR(ARMul_State* state, u32 single, u32 d, u32 m) |
| 99 | { | 99 | { |
| 100 | if (single) | 100 | if (single) |
| 101 | { | 101 | { |
diff --git a/src/core/arm/skyeye_common/vfp/vfp.h b/src/core/arm/skyeye_common/vfp/vfp.h index 80ca93ccd..88908da9f 100644 --- a/src/core/arm/skyeye_common/vfp/vfp.h +++ b/src/core/arm/skyeye_common/vfp/vfp.h | |||
| @@ -36,8 +36,8 @@ void vfp_raise_exceptions(ARMul_State* state, u32 exceptions, u32 inst, u32 fpsc | |||
| 36 | u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr); | 36 | u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr); |
| 37 | u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr); | 37 | u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr); |
| 38 | 38 | ||
| 39 | void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value); | 39 | void VMOVBRS(ARMul_State* state, u32 to_arm, u32 t, u32 n, u32* value); |
| 40 | void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2); | 40 | void VMOVBRRD(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2); |
| 41 | void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2); | 41 | void VMOVBRRSS(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2); |
| 42 | void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm); | 42 | void VMOVI(ARMul_State* state, u32 single, u32 d, u32 imm); |
| 43 | void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword imm); | 43 | void VMOVR(ARMul_State* state, u32 single, u32 d, u32 imm); |
diff --git a/src/core/arm/skyeye_common/vfp/vfp_helper.h b/src/core/arm/skyeye_common/vfp/vfp_helper.h index 2007d6dc4..91a8d4d57 100644 --- a/src/core/arm/skyeye_common/vfp/vfp_helper.h +++ b/src/core/arm/skyeye_common/vfp/vfp_helper.h | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | #include <cstdio> | 35 | #include <cstdio> |
| 36 | #include "common/common_types.h" | 36 | #include "common/common_types.h" |
| 37 | #include "core/arm/skyeye_common/armdefs.h" | 37 | #include "core/arm/skyeye_common/armstate.h" |
| 38 | #include "core/arm/skyeye_common/vfp/asm_vfp.h" | 38 | #include "core/arm/skyeye_common/vfp/asm_vfp.h" |
| 39 | 39 | ||
| 40 | #define do_div(n, base) {n/=base;} | 40 | #define do_div(n, base) {n/=base;} |
| @@ -415,7 +415,7 @@ struct op { | |||
| 415 | u32 flags; | 415 | u32 flags; |
| 416 | }; | 416 | }; |
| 417 | 417 | ||
| 418 | static inline u32 fls(ARMword x) | 418 | static inline u32 fls(u32 x) |
| 419 | { | 419 | { |
| 420 | int r = 32; | 420 | int r = 32; |
| 421 | 421 | ||
diff --git a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp index f91049585..1d844a66e 100644 --- a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp | |||
| @@ -70,9 +70,9 @@ static void vfp_double_dump(const char *str, struct vfp_double *d) | |||
| 70 | 70 | ||
| 71 | static void vfp_double_normalise_denormal(struct vfp_double *vd) | 71 | static void vfp_double_normalise_denormal(struct vfp_double *vd) |
| 72 | { | 72 | { |
| 73 | int bits = 31 - fls((ARMword)(vd->significand >> 32)); | 73 | int bits = 31 - fls((u32)(vd->significand >> 32)); |
| 74 | if (bits == 31) | 74 | if (bits == 31) |
| 75 | bits = 63 - fls((ARMword)vd->significand); | 75 | bits = 63 - fls((u32)vd->significand); |
| 76 | 76 | ||
| 77 | vfp_double_dump("normalise_denormal: in", vd); | 77 | vfp_double_dump("normalise_denormal: in", vd); |
| 78 | 78 | ||
| @@ -109,9 +109,9 @@ u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd, | |||
| 109 | exponent = vd->exponent; | 109 | exponent = vd->exponent; |
| 110 | significand = vd->significand; | 110 | significand = vd->significand; |
| 111 | 111 | ||
| 112 | shift = 32 - fls((ARMword)(significand >> 32)); | 112 | shift = 32 - fls((u32)(significand >> 32)); |
| 113 | if (shift == 32) | 113 | if (shift == 32) |
| 114 | shift = 64 - fls((ARMword)significand); | 114 | shift = 64 - fls((u32)significand); |
| 115 | if (shift) { | 115 | if (shift) { |
| 116 | exponent -= shift; | 116 | exponent -= shift; |
| 117 | significand <<= shift; | 117 | significand <<= shift; |
| @@ -566,7 +566,7 @@ static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32 | |||
| 566 | /* | 566 | /* |
| 567 | * 2^0 <= m < 2^32-2^8 | 567 | * 2^0 <= m < 2^32-2^8 |
| 568 | */ | 568 | */ |
| 569 | d = (ARMword)((vdm.significand << 1) >> shift); | 569 | d = (u32)((vdm.significand << 1) >> shift); |
| 570 | rem = vdm.significand << (65 - shift); | 570 | rem = vdm.significand << (65 - shift); |
| 571 | 571 | ||
| 572 | if (rmode == FPSCR_ROUND_NEAREST) { | 572 | if (rmode == FPSCR_ROUND_NEAREST) { |
| @@ -647,7 +647,7 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 | |||
| 647 | int shift = 1023 + 63 - vdm.exponent; /* 58 */ | 647 | int shift = 1023 + 63 - vdm.exponent; /* 58 */ |
| 648 | u64 rem, incr = 0; | 648 | u64 rem, incr = 0; |
| 649 | 649 | ||
| 650 | d = (ARMword)((vdm.significand << 1) >> shift); | 650 | d = (u32)((vdm.significand << 1) >> shift); |
| 651 | rem = vdm.significand << (65 - shift); | 651 | rem = vdm.significand << (65 - shift); |
| 652 | 652 | ||
| 653 | if (rmode == FPSCR_ROUND_NEAREST) { | 653 | if (rmode == FPSCR_ROUND_NEAREST) { |