| ... | ... |
@@ -16,8 +16,7 @@ |
| 16 | 16 |
along with the this software. If not, see <http://www.gnu.org/licenses/>. |
| 17 | 17 |
*/ |
| 18 | 18 |
|
| 19 |
-#ifndef ARM_CPU |
|
| 20 |
-#define ARM_CPU |
|
| 19 |
+#pragma once |
|
| 21 | 20 |
|
| 22 | 21 |
#include "types.h" |
| 23 | 22 |
#include "bits.h" |
| ... | ... |
@@ -245,5 +244,3 @@ inline void NDS_makeIrq(int PROCNUM, uint32_t num) |
| 245 | 244 |
{
|
| 246 | 245 |
setIF(PROCNUM, 1 << num); |
| 247 | 246 |
} |
| 248 |
- |
|
| 249 |
-#endif |
| ... | ... |
@@ -22,45 +22,45 @@ |
| 22 | 22 |
#include "types.h" |
| 23 | 23 |
#include "bits.h" |
| 24 | 24 |
#include "MMU.h" |
| 25 |
-#include "common.h" |
|
| 25 |
+#include "instructions.h" |
|
| 26 | 26 |
|
| 27 |
-static inline uint32_t CODE(uint32_t i) { return (i >> 25) & 0x7; }
|
|
| 27 |
+inline uint32_t CODE(uint32_t i) { return (i >> 25) & 0x7; }
|
|
| 28 | 28 |
|
| 29 |
-static const uint32_t EXCEPTION_RESET = 0x00; |
|
| 30 |
-static const uint32_t EXCEPTION_UNDEFINED_INSTRUCTION = 0x04; |
|
| 31 |
-static const uint32_t EXCEPTION_SWI = 0x08; |
|
| 32 |
-static const uint32_t EXCEPTION_PREFETCH_ABORT = 0x0C; |
|
| 33 |
-static const uint32_t EXCEPTION_DATA_ABORT = 0x10; |
|
| 34 |
-static const uint32_t EXCEPTION_RESERVED_0x14 = 0x14; |
|
| 35 |
-static const uint32_t EXCEPTION_IRQ = 0x18; |
|
| 36 |
-static const uint32_t EXCEPTION_FAST_IRQ = 0x1C; |
|
| 29 |
+const uint32_t EXCEPTION_RESET = 0x00; |
|
| 30 |
+const uint32_t EXCEPTION_UNDEFINED_INSTRUCTION = 0x04; |
|
| 31 |
+const uint32_t EXCEPTION_SWI = 0x08; |
|
| 32 |
+const uint32_t EXCEPTION_PREFETCH_ABORT = 0x0C; |
|
| 33 |
+const uint32_t EXCEPTION_DATA_ABORT = 0x10; |
|
| 34 |
+const uint32_t EXCEPTION_RESERVED_0x14 = 0x14; |
|
| 35 |
+const uint32_t EXCEPTION_IRQ = 0x18; |
|
| 36 |
+const uint32_t EXCEPTION_FAST_IRQ = 0x1C; |
|
| 37 | 37 |
|
| 38 |
-static inline uint32_t INSTRUCTION_INDEX(uint32_t i) { return ((i >> 16) & 0xFF0) | ((i >> 4) & 0xF); }
|
|
| 38 |
+inline uint32_t INSTRUCTION_INDEX(uint32_t i) { return ((i >> 16) & 0xFF0) | ((i >> 4) & 0xF); }
|
|
| 39 | 39 |
|
| 40 |
-static inline uint32_t ROR(uint32_t i, uint32_t j) { return (i >> j) | (i << (32 - j)); }
|
|
| 40 |
+inline uint32_t ROR(uint32_t i, uint32_t j) { return (i >> j) | (i << (32 - j)); }
|
|
| 41 | 41 |
|
| 42 |
-template<typename T> static inline T UNSIGNED_OVERFLOW(T a, T b, T c) { return BIT31((a & b) | ((a | b) & ~c)); }
|
|
| 42 |
+template<typename T> inline T UNSIGNED_OVERFLOW(T a, T b, T c) { return BIT31((a & b) | ((a | b) & ~c)); }
|
|
| 43 | 43 |
|
| 44 |
-template<typename T> static inline T UNSIGNED_UNDERFLOW(T a, T b, T c) { return BIT31((~a & b) | ((~a | b) & c)); }
|
|
| 44 |
+template<typename T> inline T UNSIGNED_UNDERFLOW(T a, T b, T c) { return BIT31((~a & b) | ((~a | b) & c)); }
|
|
| 45 | 45 |
|
| 46 |
-template<typename T> static inline T SIGNED_OVERFLOW(T a, T b, T c) { return BIT31((a & b & ~c) | (~a & ~b & c)); }
|
|
| 46 |
+template<typename T> inline T SIGNED_OVERFLOW(T a, T b, T c) { return BIT31((a & b & ~c) | (~a & ~b & c)); }
|
|
| 47 | 47 |
|
| 48 |
-template<typename T> static inline T SIGNED_UNDERFLOW(T a, T b, T c) { return BIT31((a & ~b & ~c) | (~a & b & c)); }
|
|
| 48 |
+template<typename T> inline T SIGNED_UNDERFLOW(T a, T b, T c) { return BIT31((a & ~b & ~c) | (~a & b & c)); }
|
|
| 49 | 49 |
|
| 50 | 50 |
// ============================= CPRS flags funcs |
| 51 |
-static inline bool CarryFrom(int32_t left, int32_t right) |
|
| 51 |
+inline bool CarryFrom(int32_t left, int32_t right) |
|
| 52 | 52 |
{
|
| 53 | 53 |
uint32_t res = 0xFFFFFFFFU - static_cast<uint32_t>(left); |
| 54 | 54 |
|
| 55 | 55 |
return static_cast<uint32_t>(right) > res; |
| 56 | 56 |
} |
| 57 | 57 |
|
| 58 |
-static inline bool BorrowFrom(int32_t left, int32_t right) |
|
| 58 |
+inline bool BorrowFrom(int32_t left, int32_t right) |
|
| 59 | 59 |
{
|
| 60 | 60 |
return static_cast<uint32_t>(right) > static_cast<uint32_t>(left); |
| 61 | 61 |
} |
| 62 | 62 |
|
| 63 |
-static inline bool OverflowFromADD(int32_t alu_out, int32_t left, int32_t right) |
|
| 63 |
+inline bool OverflowFromADD(int32_t alu_out, int32_t left, int32_t right) |
|
| 64 | 64 |
{
|
| 65 | 65 |
return ((left >= 0 && right >= 0) || (left < 0 && right < 0)) && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); |
| 66 | 66 |
} |
| ... | ... |
@@ -70,24 +70,57 @@ inline bool OverflowFromSUB(int32_t alu_out, int32_t left, int32_t right) |
| 70 | 70 |
return ((left < 0 && right >= 0) || (left >= 0 && right < 0)) && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); |
| 71 | 71 |
} |
| 72 | 72 |
|
| 73 |
-//zero 15-feb-2009 - these werent getting used and they were getting in my way |
|
| 74 |
-//#define EQ 0x0 |
|
| 75 |
-//#define NE 0x1 |
|
| 76 |
-//#define CS 0x2 |
|
| 77 |
-//#define CC 0x3 |
|
| 78 |
-//#define MI 0x4 |
|
| 79 |
-//#define PL 0x5 |
|
| 80 |
-//#define VS 0x6 |
|
| 81 |
-//#define VC 0x7 |
|
| 82 |
-//#define HI 0x8 |
|
| 83 |
-//#define LS 0x9 |
|
| 84 |
-//#define GE 0xA |
|
| 85 |
-//#define LT 0xB |
|
| 86 |
-//#define GT 0xC |
|
| 87 |
-//#define LE 0xD |
|
| 88 |
-//#define AL 0xE |
|
| 89 |
- |
|
| 90 |
-extern const uint8_t arm_cond_table[16 * 16]; |
|
| 73 |
+const uint8_t arm_cond_table[] = |
|
| 74 |
+{
|
|
| 75 |
+ // N=0, Z=0, C=0, V=0 |
|
| 76 |
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF, // 0x00 |
|
| 77 |
+ 0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20, // 0x00 |
|
| 78 |
+ // N=0, Z=0, C=0, V=1 |
|
| 79 |
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x00, // 0x10 |
|
| 80 |
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20, |
|
| 81 |
+ // N=0, Z=0, C=1, V=0 |
|
| 82 |
+ 0x00,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF, // 0x20 |
|
| 83 |
+ 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20, |
|
| 84 |
+ // N=0, Z=0, C=1, V=1 |
|
| 85 |
+ 0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00, // 0x30 |
|
| 86 |
+ 0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20, |
|
| 87 |
+ // N=0, Z=1, C=0, V=0 |
|
| 88 |
+ 0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF, // 0x40 |
|
| 89 |
+ 0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20, |
|
| 90 |
+ // N=0, Z=1, C=0, V=1 |
|
| 91 |
+ 0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x00, // 0x50 |
|
| 92 |
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20, |
|
| 93 |
+ // N=0, Z=1, C=1, V=0 |
|
| 94 |
+ 0xFF,0x00,0xFF,0x00,0x00,0xFF,0x00,0xFF, // 0x60 |
|
| 95 |
+ 0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20, |
|
| 96 |
+ // N=0, Z=1, C=1, V=1 |
|
| 97 |
+ 0xFF,0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00, // 0x70 |
|
| 98 |
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20, |
|
| 99 |
+ // N=1, Z=0, C=0, V=0 |
|
| 100 |
+ 0x00,0xFF,0x00,0xFF,0xFF,0x00,0x00,0xFF, // 0x80 |
|
| 101 |
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20, |
|
| 102 |
+ // N=1, Z=0, C=0, V=1 |
|
| 103 |
+ 0x00,0xFF,0x00,0xFF,0xFF,0x00,0xFF,0x00, // 0x90 |
|
| 104 |
+ 0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20, |
|
| 105 |
+ // N=1, Z=0, C=1, V=0 |
|
| 106 |
+ 0x00,0xFF,0xFF,0x00,0xFF,0x00,0x00,0xFF, // 0xA0 |
|
| 107 |
+ 0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20, |
|
| 108 |
+ // N=1, Z=0, C=1, V=1 |
|
| 109 |
+ 0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x00, // 0xB0 |
|
| 110 |
+ 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20, |
|
| 111 |
+ // N=1, Z=1, C=0, V=0 |
|
| 112 |
+ 0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF, // 0xC0 |
|
| 113 |
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20, |
|
| 114 |
+ // N=1, Z=1, C=0, V=1 |
|
| 115 |
+ 0xFF,0x00,0x00,0xFF,0xFF,0x00,0xFF,0x00, // 0xD0 |
|
| 116 |
+ 0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20, |
|
| 117 |
+ // N=1, Z=1, C=1, V=0 |
|
| 118 |
+ 0xFF,0x00,0xFF,0x00,0xFF,0x00,0x00,0xFF, // 0xE0 |
|
| 119 |
+ 0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20, |
|
| 120 |
+ // N=1, Z=1, C=1, V=1 |
|
| 121 |
+ 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00, // 0xF0 |
|
| 122 |
+ 0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20 |
|
| 123 |
+}; |
|
| 91 | 124 |
|
| 92 | 125 |
enum Mode |
| 93 | 126 |
{
|
| ... | ... |
@@ -138,34 +171,7 @@ typedef union |
| 138 | 171 |
} Status_Reg; |
| 139 | 172 |
#endif |
| 140 | 173 |
|
| 141 |
-static inline uint8_t TEST_COND(uint32_t cond, uint32_t inst, Status_Reg CPSR) { return arm_cond_table[((CPSR.val >> 24) & 0xf0) | cond] & (1 << inst); }
|
|
| 142 |
- |
|
| 143 |
-/** |
|
| 144 |
- * The control interface to a CPU |
|
| 145 |
- */ |
|
| 146 |
-/*struct armcpu_ctrl_iface |
|
| 147 |
-{*/
|
|
| 148 |
- /** stall the processor */ |
|
| 149 |
- //void (*stall)(void *instance); |
|
| 150 |
- |
|
| 151 |
- /** unstall the processor */ |
|
| 152 |
- //void (*unstall)(void *instance); |
|
| 153 |
- |
|
| 154 |
- /** read a register value */ |
|
| 155 |
- //uint32_t (*read_reg)(void *instance, uint32_t reg_num); |
|
| 156 |
- |
|
| 157 |
- /** set a register value */ |
|
| 158 |
- //void (*set_reg)(void *instance, uint32_t reg_num, uint32_t value); |
|
| 159 |
- |
|
| 160 |
- /** install the post execute function */ |
|
| 161 |
- //void (*install_post_ex_fn)( void *instance, void (*fn)(void *, uint32_t, int), void *fn_data); |
|
| 162 |
- |
|
| 163 |
- /** remove the post execute function */ |
|
| 164 |
- //void (*remove_post_ex_fn)(void *instance); |
|
| 165 |
- |
|
| 166 |
- /** the private data passed to all interface functions */ |
|
| 167 |
- /*void *data; |
|
| 168 |
-};*/ |
|
| 174 |
+inline uint8_t TEST_COND(uint32_t cond, uint32_t inst, Status_Reg CPSR) { return arm_cond_table[((CPSR.val >> 24) & 0xf0) | cond] & (1 << inst); }
|
|
| 169 | 175 |
|
| 170 | 176 |
typedef void *armcp_t; |
| 171 | 177 |
|
| ... | ... |
@@ -190,8 +196,6 @@ struct armcpu_t |
| 190 | 196 |
uint32_t R8_fiq, R9_fiq, R10_fiq, R11_fiq, R12_fiq, R13_fiq, R14_fiq; |
| 191 | 197 |
Status_Reg SPSR_svc, SPSR_abt, SPSR_und, SPSR_irq, SPSR_fiq; |
| 192 | 198 |
|
| 193 |
- armcp_t *coproc[16]; |
|
| 194 |
- |
|
| 195 | 199 |
uint32_t intVector; |
| 196 | 200 |
uint8_t LDTBit; // 1 : ARMv5 style 0 : non ARMv5 |
| 197 | 201 |
bool waitIRQ; |
| ... | ... |
@@ -205,43 +209,28 @@ struct armcpu_t |
| 205 | 209 |
// flag indicating if the processor is stalled (for debugging) |
| 206 | 210 |
int stalled; |
| 207 | 211 |
|
| 208 |
-#ifdef GDB_STUB |
|
| 209 |
- /** there is a pending irq for the cpu */ |
|
| 210 |
- int irq_flag; |
|
| 211 |
- |
|
| 212 |
- /** the post executed function (if installed) */ |
|
| 213 |
- void (*post_ex_fn)(void *, uint32_t adr, int thumb); |
|
| 214 |
- |
|
| 215 |
- /** data for the post executed function */ |
|
| 216 |
- void *post_ex_fn_data; |
|
| 217 |
- |
|
| 218 |
- /** the memory interface */ |
|
| 219 |
- armcpu_memory_iface *mem_if; |
|
| 220 |
- |
|
| 221 |
- /** the ctrl interface */ |
|
| 222 |
- armcpu_ctrl_iface ctrl_iface; |
|
| 212 |
+#if defined(_M_X64) || defined(__x86_64__) |
|
| 213 |
+ u8 cond_table[16 * 16]; |
|
| 223 | 214 |
#endif |
| 224 | 215 |
}; |
| 225 | 216 |
|
| 226 |
-#ifdef GDB_STUB |
|
| 227 |
-int armcpu_new(armcpu_t *armcpu, uint32_t id, armcpu_memory_iface *mem_if, armcpu_ctrl_iface **ctrl_iface_ret); |
|
| 228 |
-#else |
|
| 229 | 217 |
int armcpu_new(armcpu_t *armcpu, uint32_t id); |
| 230 |
-#endif |
|
| 231 | 218 |
void armcpu_init(armcpu_t *armcpu, uint32_t adr); |
| 232 | 219 |
uint32_t armcpu_switchMode(armcpu_t *armcpu, uint8_t mode); |
| 233 | 220 |
|
| 234 |
-template<int PROCNUM> uint32_t armcpu_exec(); |
|
| 235 |
- |
|
| 236 | 221 |
bool armcpu_irqException(armcpu_t *armcpu); |
| 237 |
-//bool armcpu_flagIrq( armcpu_t *armcpu); |
|
| 238 | 222 |
void armcpu_exception(armcpu_t *cpu, uint32_t number); |
| 239 | 223 |
uint32_t TRAPUNDEF(armcpu_t* cpu); |
| 240 | 224 |
uint32_t armcpu_Wait4IRQ(armcpu_t *cpu); |
| 241 | 225 |
|
| 242 | 226 |
extern armcpu_t NDS_ARM7, NDS_ARM9; |
| 243 | 227 |
|
| 244 |
-static inline void setIF(int PROCNUM, uint32_t flag) |
|
| 228 |
+template<int PROCNUM> uint32_t armcpu_exec(); |
|
| 229 |
+#ifdef HAVE_JIT |
|
| 230 |
+template<int PROCNUM, bool jit> uint32_t armcpu_exec(); |
|
| 231 |
+#endif |
|
| 232 |
+ |
|
| 233 |
+inline void setIF(int PROCNUM, uint32_t flag) |
|
| 245 | 234 |
{
|
| 246 | 235 |
// don't set generated bits!!! |
| 247 | 236 |
assert(!(flag&0x00200000)); |
| ... | ... |
@@ -252,26 +241,9 @@ static inline void setIF(int PROCNUM, uint32_t flag) |
| 252 | 241 |
NDS_Reschedule(); |
| 253 | 242 |
} |
| 254 | 243 |
|
| 255 |
-static inline void NDS_makeIrq(int PROCNUM, uint32_t num) |
|
| 244 |
+inline void NDS_makeIrq(int PROCNUM, uint32_t num) |
|
| 256 | 245 |
{
|
| 257 |
- setIF(PROCNUM, 1<<num); |
|
| 246 |
+ setIF(PROCNUM, 1 << num); |
|
| 258 | 247 |
} |
| 259 | 248 |
|
| 260 |
-/*static inline char *decodeIntruction(bool thumb_mode, uint32_t instr) |
|
| 261 |
-{
|
|
| 262 |
- char txt[20] = ""; |
|
| 263 |
- uint32_t tmp = 0; |
|
| 264 |
- if (thumb_mode) |
|
| 265 |
- {
|
|
| 266 |
- tmp = instr >> 6; |
|
| 267 |
- strcpy(txt, intToBin(static_cast<uint16_t>(tmp)) + 6); |
|
| 268 |
- } |
|
| 269 |
- else |
|
| 270 |
- {
|
|
| 271 |
- tmp = ((instr >> 16) & 0x0FF0) | ((instr >> 4) & 0x0F); |
|
| 272 |
- strcpy(txt, intToBin(tmp) + 20); |
|
| 273 |
- } |
|
| 274 |
- return _strdup(txt); |
|
| 275 |
-}*/ |
|
| 276 |
- |
|
| 277 | 249 |
#endif |
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,277 @@ |
| 1 |
+/* |
|
| 2 |
+ Copyright (C) 2006 yopyop |
|
| 3 |
+ Copyright (C) 2006-2012 DeSmuME team |
|
| 4 |
+ |
|
| 5 |
+ This file 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 file 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 the this software. If not, see <http://www.gnu.org/licenses/>. |
|
| 17 |
+*/ |
|
| 18 |
+ |
|
| 19 |
+#ifndef ARM_CPU |
|
| 20 |
+#define ARM_CPU |
|
| 21 |
+ |
|
| 22 |
+#include "types.h" |
|
| 23 |
+#include "bits.h" |
|
| 24 |
+#include "MMU.h" |
|
| 25 |
+#include "common.h" |
|
| 26 |
+ |
|
| 27 |
+static inline uint32_t CODE(uint32_t i) { return (i >> 25) & 0x7; }
|
|
| 28 |
+ |
|
| 29 |
+static const uint32_t EXCEPTION_RESET = 0x00; |
|
| 30 |
+static const uint32_t EXCEPTION_UNDEFINED_INSTRUCTION = 0x04; |
|
| 31 |
+static const uint32_t EXCEPTION_SWI = 0x08; |
|
| 32 |
+static const uint32_t EXCEPTION_PREFETCH_ABORT = 0x0C; |
|
| 33 |
+static const uint32_t EXCEPTION_DATA_ABORT = 0x10; |
|
| 34 |
+static const uint32_t EXCEPTION_RESERVED_0x14 = 0x14; |
|
| 35 |
+static const uint32_t EXCEPTION_IRQ = 0x18; |
|
| 36 |
+static const uint32_t EXCEPTION_FAST_IRQ = 0x1C; |
|
| 37 |
+ |
|
| 38 |
+static inline uint32_t INSTRUCTION_INDEX(uint32_t i) { return ((i >> 16) & 0xFF0) | ((i >> 4) & 0xF); }
|
|
| 39 |
+ |
|
| 40 |
+static inline uint32_t ROR(uint32_t i, uint32_t j) { return (i >> j) | (i << (32 - j)); }
|
|
| 41 |
+ |
|
| 42 |
+template<typename T> static inline T UNSIGNED_OVERFLOW(T a, T b, T c) { return BIT31((a & b) | ((a | b) & ~c)); }
|
|
| 43 |
+ |
|
| 44 |
+template<typename T> static inline T UNSIGNED_UNDERFLOW(T a, T b, T c) { return BIT31((~a & b) | ((~a | b) & c)); }
|
|
| 45 |
+ |
|
| 46 |
+template<typename T> static inline T SIGNED_OVERFLOW(T a, T b, T c) { return BIT31((a & b & ~c) | (~a & ~b & c)); }
|
|
| 47 |
+ |
|
| 48 |
+template<typename T> static inline T SIGNED_UNDERFLOW(T a, T b, T c) { return BIT31((a & ~b & ~c) | (~a & b & c)); }
|
|
| 49 |
+ |
|
| 50 |
+// ============================= CPRS flags funcs |
|
| 51 |
+static inline bool CarryFrom(int32_t left, int32_t right) |
|
| 52 |
+{
|
|
| 53 |
+ uint32_t res = 0xFFFFFFFFU - static_cast<uint32_t>(left); |
|
| 54 |
+ |
|
| 55 |
+ return static_cast<uint32_t>(right) > res; |
|
| 56 |
+} |
|
| 57 |
+ |
|
| 58 |
+static inline bool BorrowFrom(int32_t left, int32_t right) |
|
| 59 |
+{
|
|
| 60 |
+ return static_cast<uint32_t>(right) > static_cast<uint32_t>(left); |
|
| 61 |
+} |
|
| 62 |
+ |
|
| 63 |
+static inline bool OverflowFromADD(int32_t alu_out, int32_t left, int32_t right) |
|
| 64 |
+{
|
|
| 65 |
+ return ((left >= 0 && right >= 0) || (left < 0 && right < 0)) && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); |
|
| 66 |
+} |
|
| 67 |
+ |
|
| 68 |
+inline bool OverflowFromSUB(int32_t alu_out, int32_t left, int32_t right) |
|
| 69 |
+{
|
|
| 70 |
+ return ((left < 0 && right >= 0) || (left >= 0 && right < 0)) && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); |
|
| 71 |
+} |
|
| 72 |
+ |
|
| 73 |
+//zero 15-feb-2009 - these werent getting used and they were getting in my way |
|
| 74 |
+//#define EQ 0x0 |
|
| 75 |
+//#define NE 0x1 |
|
| 76 |
+//#define CS 0x2 |
|
| 77 |
+//#define CC 0x3 |
|
| 78 |
+//#define MI 0x4 |
|
| 79 |
+//#define PL 0x5 |
|
| 80 |
+//#define VS 0x6 |
|
| 81 |
+//#define VC 0x7 |
|
| 82 |
+//#define HI 0x8 |
|
| 83 |
+//#define LS 0x9 |
|
| 84 |
+//#define GE 0xA |
|
| 85 |
+//#define LT 0xB |
|
| 86 |
+//#define GT 0xC |
|
| 87 |
+//#define LE 0xD |
|
| 88 |
+//#define AL 0xE |
|
| 89 |
+ |
|
| 90 |
+extern const uint8_t arm_cond_table[16 * 16]; |
|
| 91 |
+ |
|
| 92 |
+enum Mode |
|
| 93 |
+{
|
|
| 94 |
+ USR = 0x10, |
|
| 95 |
+ FIQ = 0x11, |
|
| 96 |
+ IRQ = 0x12, |
|
| 97 |
+ SVC = 0x13, |
|
| 98 |
+ ABT = 0x17, |
|
| 99 |
+ UND = 0x1B, |
|
| 100 |
+ SYS = 0x1F |
|
| 101 |
+}; |
|
| 102 |
+ |
|
| 103 |
+#ifdef WORDS_BIGENDIAN |
|
| 104 |
+typedef union |
|
| 105 |
+{
|
|
| 106 |
+ struct |
|
| 107 |
+ {
|
|
| 108 |
+ uint32_t N : 1, |
|
| 109 |
+ Z : 1, |
|
| 110 |
+ C : 1, |
|
| 111 |
+ V : 1, |
|
| 112 |
+ Q : 1, |
|
| 113 |
+ RAZ : 19, |
|
| 114 |
+ I : 1, |
|
| 115 |
+ F : 1, |
|
| 116 |
+ T : 1, |
|
| 117 |
+ mode : 5; |
|
| 118 |
+ } bits; |
|
| 119 |
+ uint32_t val; |
|
| 120 |
+} Status_Reg; |
|
| 121 |
+#else |
|
| 122 |
+typedef union |
|
| 123 |
+{
|
|
| 124 |
+ struct |
|
| 125 |
+ {
|
|
| 126 |
+ uint32_t mode : 5, |
|
| 127 |
+ T : 1, |
|
| 128 |
+ F : 1, |
|
| 129 |
+ I : 1, |
|
| 130 |
+ RAZ : 19, |
|
| 131 |
+ Q : 1, |
|
| 132 |
+ V : 1, |
|
| 133 |
+ C : 1, |
|
| 134 |
+ Z : 1, |
|
| 135 |
+ N : 1; |
|
| 136 |
+ } bits; |
|
| 137 |
+ uint32_t val; |
|
| 138 |
+} Status_Reg; |
|
| 139 |
+#endif |
|
| 140 |
+ |
|
| 141 |
+static inline uint8_t TEST_COND(uint32_t cond, uint32_t inst, Status_Reg CPSR) { return arm_cond_table[((CPSR.val >> 24) & 0xf0) | cond] & (1 << inst); }
|
|
| 142 |
+ |
|
| 143 |
+/** |
|
| 144 |
+ * The control interface to a CPU |
|
| 145 |
+ */ |
|
| 146 |
+/*struct armcpu_ctrl_iface |
|
| 147 |
+{*/
|
|
| 148 |
+ /** stall the processor */ |
|
| 149 |
+ //void (*stall)(void *instance); |
|
| 150 |
+ |
|
| 151 |
+ /** unstall the processor */ |
|
| 152 |
+ //void (*unstall)(void *instance); |
|
| 153 |
+ |
|
| 154 |
+ /** read a register value */ |
|
| 155 |
+ //uint32_t (*read_reg)(void *instance, uint32_t reg_num); |
|
| 156 |
+ |
|
| 157 |
+ /** set a register value */ |
|
| 158 |
+ //void (*set_reg)(void *instance, uint32_t reg_num, uint32_t value); |
|
| 159 |
+ |
|
| 160 |
+ /** install the post execute function */ |
|
| 161 |
+ //void (*install_post_ex_fn)( void *instance, void (*fn)(void *, uint32_t, int), void *fn_data); |
|
| 162 |
+ |
|
| 163 |
+ /** remove the post execute function */ |
|
| 164 |
+ //void (*remove_post_ex_fn)(void *instance); |
|
| 165 |
+ |
|
| 166 |
+ /** the private data passed to all interface functions */ |
|
| 167 |
+ /*void *data; |
|
| 168 |
+};*/ |
|
| 169 |
+ |
|
| 170 |
+typedef void *armcp_t; |
|
| 171 |
+ |
|
| 172 |
+struct armcpu_t |
|
| 173 |
+{
|
|
| 174 |
+ uint32_t proc_ID; |
|
| 175 |
+ uint32_t instruction; //4 |
|
| 176 |
+ uint32_t instruct_adr; //8 |
|
| 177 |
+ uint32_t next_instruction; //12 |
|
| 178 |
+ |
|
| 179 |
+ uint32_t R[16]; //16 |
|
| 180 |
+ Status_Reg CPSR; //80 |
|
| 181 |
+ Status_Reg SPSR; |
|
| 182 |
+ |
|
| 183 |
+ void changeCPSR(); |
|
| 184 |
+ |
|
| 185 |
+ uint32_t R13_usr, R14_usr; |
|
| 186 |
+ uint32_t R13_svc, R14_svc; |
|
| 187 |
+ uint32_t R13_abt, R14_abt; |
|
| 188 |
+ uint32_t R13_und, R14_und; |
|
| 189 |
+ uint32_t R13_irq, R14_irq; |
|
| 190 |
+ uint32_t R8_fiq, R9_fiq, R10_fiq, R11_fiq, R12_fiq, R13_fiq, R14_fiq; |
|
| 191 |
+ Status_Reg SPSR_svc, SPSR_abt, SPSR_und, SPSR_irq, SPSR_fiq; |
|
| 192 |
+ |
|
| 193 |
+ armcp_t *coproc[16]; |
|
| 194 |
+ |
|
| 195 |
+ uint32_t intVector; |
|
| 196 |
+ uint8_t LDTBit; // 1 : ARMv5 style 0 : non ARMv5 |
|
| 197 |
+ bool waitIRQ; |
|
| 198 |
+ bool halt_IE_and_IF; //the cpu is halted, waiting for IE&IF to signal something |
|
| 199 |
+ uint8_t intrWaitARM_state; |
|
| 200 |
+ |
|
| 201 |
+ bool BIOS_loaded; |
|
| 202 |
+ |
|
| 203 |
+ uint32_t (**swi_tab)(); |
|
| 204 |
+ |
|
| 205 |
+ // flag indicating if the processor is stalled (for debugging) |
|
| 206 |
+ int stalled; |
|
| 207 |
+ |
|
| 208 |
+#ifdef GDB_STUB |
|
| 209 |
+ /** there is a pending irq for the cpu */ |
|
| 210 |
+ int irq_flag; |
|
| 211 |
+ |
|
| 212 |
+ /** the post executed function (if installed) */ |
|
| 213 |
+ void (*post_ex_fn)(void *, uint32_t adr, int thumb); |
|
| 214 |
+ |
|
| 215 |
+ /** data for the post executed function */ |
|
| 216 |
+ void *post_ex_fn_data; |
|
| 217 |
+ |
|
| 218 |
+ /** the memory interface */ |
|
| 219 |
+ armcpu_memory_iface *mem_if; |
|
| 220 |
+ |
|
| 221 |
+ /** the ctrl interface */ |
|
| 222 |
+ armcpu_ctrl_iface ctrl_iface; |
|
| 223 |
+#endif |
|
| 224 |
+}; |
|
| 225 |
+ |
|
| 226 |
+#ifdef GDB_STUB |
|
| 227 |
+int armcpu_new(armcpu_t *armcpu, uint32_t id, armcpu_memory_iface *mem_if, armcpu_ctrl_iface **ctrl_iface_ret); |
|
| 228 |
+#else |
|
| 229 |
+int armcpu_new(armcpu_t *armcpu, uint32_t id); |
|
| 230 |
+#endif |
|
| 231 |
+void armcpu_init(armcpu_t *armcpu, uint32_t adr); |
|
| 232 |
+uint32_t armcpu_switchMode(armcpu_t *armcpu, uint8_t mode); |
|
| 233 |
+ |
|
| 234 |
+template<int PROCNUM> uint32_t armcpu_exec(); |
|
| 235 |
+ |
|
| 236 |
+bool armcpu_irqException(armcpu_t *armcpu); |
|
| 237 |
+//bool armcpu_flagIrq( armcpu_t *armcpu); |
|
| 238 |
+void armcpu_exception(armcpu_t *cpu, uint32_t number); |
|
| 239 |
+uint32_t TRAPUNDEF(armcpu_t* cpu); |
|
| 240 |
+uint32_t armcpu_Wait4IRQ(armcpu_t *cpu); |
|
| 241 |
+ |
|
| 242 |
+extern armcpu_t NDS_ARM7, NDS_ARM9; |
|
| 243 |
+ |
|
| 244 |
+static inline void setIF(int PROCNUM, uint32_t flag) |
|
| 245 |
+{
|
|
| 246 |
+ // don't set generated bits!!! |
|
| 247 |
+ assert(!(flag&0x00200000)); |
|
| 248 |
+ |
|
| 249 |
+ MMU.reg_IF_bits[PROCNUM] |= flag; |
|
| 250 |
+ |
|
| 251 |
+ extern void NDS_Reschedule(); |
|
| 252 |
+ NDS_Reschedule(); |
|
| 253 |
+} |
|
| 254 |
+ |
|
| 255 |
+static inline void NDS_makeIrq(int PROCNUM, uint32_t num) |
|
| 256 |
+{
|
|
| 257 |
+ setIF(PROCNUM, 1<<num); |
|
| 258 |
+} |
|
| 259 |
+ |
|
| 260 |
+/*static inline char *decodeIntruction(bool thumb_mode, uint32_t instr) |
|
| 261 |
+{
|
|
| 262 |
+ char txt[20] = ""; |
|
| 263 |
+ uint32_t tmp = 0; |
|
| 264 |
+ if (thumb_mode) |
|
| 265 |
+ {
|
|
| 266 |
+ tmp = instr >> 6; |
|
| 267 |
+ strcpy(txt, intToBin(static_cast<uint16_t>(tmp)) + 6); |
|
| 268 |
+ } |
|
| 269 |
+ else |
|
| 270 |
+ {
|
|
| 271 |
+ tmp = ((instr >> 16) & 0x0FF0) | ((instr >> 4) & 0x0F); |
|
| 272 |
+ strcpy(txt, intToBin(tmp) + 20); |
|
| 273 |
+ } |
|
| 274 |
+ return _strdup(txt); |
|
| 275 |
+}*/ |
|
| 276 |
+ |
|
| 277 |
+#endif |