| ... | ... |
@@ -928,7 +928,7 @@ TEMPLATE static uint32_t FASTCALL OP_STMIA_THUMB(uint32_t i) |
| 928 | 928 |
// ------ * If <Rn> is the lowest-numbered register specified in <registers>, the original value of <Rn> is stored. |
| 929 | 929 |
// ------ * Otherwise, the stored value of <Rn> is UNPREDICTABLE. |
| 930 | 930 |
if (BIT_N(i, REG_NUM(i, 8))) |
| 931 |
- printf("STMIA with Rb in Rlist\n");
|
|
| 931 |
+ fprintf(stderr, "STMIA with Rb in Rlist\n"); |
|
| 932 | 932 |
|
| 933 | 933 |
for (uint32_t j = 0; j < 8; ++j) |
| 934 | 934 |
if (BIT_N(i, j)) |
| ... | ... |
@@ -940,7 +940,7 @@ TEMPLATE static uint32_t FASTCALL OP_STMIA_THUMB(uint32_t i) |
| 940 | 940 |
} |
| 941 | 941 |
|
| 942 | 942 |
if (erList) |
| 943 |
- printf("STMIA with Empty Rlist\n");
|
|
| 943 |
+ fprintf(stderr, "STMIA with Empty Rlist\n"); |
|
| 944 | 944 |
|
| 945 | 945 |
cpu->R[REG_NUM(i, 8)] = adr; |
| 946 | 946 |
return MMU_aluMemCycles<PROCNUM>(2, c); |
| ... | ... |
@@ -954,7 +954,7 @@ TEMPLATE static uint32_t FASTCALL OP_LDMIA_THUMB(uint32_t i) |
| 954 | 954 |
bool erList = true; //Empty Register List |
| 955 | 955 |
|
| 956 | 956 |
//if (BIT_N(i, regIndex)) |
| 957 |
- // printf("LDMIA with Rb in Rlist at %08X\n",cpu->instruct_adr);
|
|
| 957 |
+ // fprintf(stderr, "LDMIA with Rb in Rlist at %08X\n",cpu->instruct_adr); |
|
| 958 | 958 |
|
| 959 | 959 |
for (uint32_t j = 0; j < 8; ++j) |
| 960 | 960 |
if (BIT_N(i, j)) |
| ... | ... |
@@ -966,7 +966,7 @@ TEMPLATE static uint32_t FASTCALL OP_LDMIA_THUMB(uint32_t i) |
| 966 | 966 |
} |
| 967 | 967 |
|
| 968 | 968 |
if (erList) |
| 969 |
- printf("LDMIA with Empty Rlist\n");
|
|
| 969 |
+ fprintf(stderr, "LDMIA with Empty Rlist\n"); |
|
| 970 | 970 |
|
| 971 | 971 |
// ARM_REF: THUMB: Causes base register write-back, and is not optional |
| 972 | 972 |
// ARM_REF: If the base register <Rn> is specified in <registers>, the final value of <Rn> is the loaded value |
| ... | ... |
@@ -983,7 +983,7 @@ TEMPLATE static uint32_t FASTCALL OP_LDMIA_THUMB(uint32_t i) |
| 983 | 983 |
|
| 984 | 984 |
TEMPLATE static uint32_t FASTCALL OP_BKPT_THUMB(uint32_t) |
| 985 | 985 |
{
|
| 986 |
- printf("THUMB%c: OP_BKPT triggered\n", PROCNUM?'7':'9');
|
|
| 986 |
+ fprintf(stderr, "THUMB%c: OP_BKPT triggered\n", PROCNUM?'7':'9'); |
|
| 987 | 987 |
Status_Reg tmp = cpu->CPSR; |
| 988 | 988 |
armcpu_switchMode(cpu, ABT); // enter abt mode |
| 989 | 989 |
cpu->R[14] = cpu->instruct_adr + 4; |
| ... | ... |
@@ -1023,7 +1023,7 @@ TEMPLATE static uint32_t FASTCALL OP_SWI_THUMB(uint32_t i) |
| 1023 | 1023 |
//zero 30-jun-2009 - but they say that the ideas 0xFF should crash the device... |
| 1024 | 1024 |
//uint32_t swinum = cpu->instruction & 0xFF; |
| 1025 | 1025 |
swinum &= 0x1F; |
| 1026 |
- //printf("%d ARM SWI %d\n",PROCNUM,swinum);
|
|
| 1026 |
+ //fprintf(stderr, "%d ARM SWI %d\n",PROCNUM,swinum); |
|
| 1027 | 1027 |
return cpu->swi_tab[swinum]() + 3; |
| 1028 | 1028 |
} |
| 1029 | 1029 |
else |
| ... | ... |
@@ -1120,7 +1120,7 @@ TEMPLATE static uint32_t FASTCALL OP_BX_THUMB(uint32_t i) |
| 1120 | 1120 |
//----- the instruction are UNPREDICTABLE (because the value read for R15 has bits[1:0]==0b10). |
| 1121 | 1121 |
if (Rm == 15) |
| 1122 | 1122 |
{
|
| 1123 |
- printf("THUMB%c: BX using PC as operand\n", PROCNUM?'7':'9');
|
|
| 1123 |
+ fprintf(stderr, "THUMB%c: BX using PC as operand\n", PROCNUM?'7':'9'); |
|
| 1124 | 1124 |
//emu_halt(); |
| 1125 | 1125 |
} |
| 1126 | 1126 |
cpu->CPSR.bits.T = BIT0(Rm); |
| ... | ... |
@@ -1,7 +1,7 @@ |
| 1 | 1 |
/* |
| 2 | 2 |
Copyright (C) 2006 yopyop |
| 3 | 3 |
Copyright (C) 2008 shash |
| 4 |
- Copyright (C) 2008-2012 DeSmuME team |
|
| 4 |
+ Copyright (C) 2008-2013 DeSmuME team |
|
| 5 | 5 |
|
| 6 | 6 |
This file is free software: you can redistribute it and/or modify |
| 7 | 7 |
it under the terms of the GNU General Public License as published by |
| ... | ... |
@@ -20,22 +20,19 @@ |
| 20 | 20 |
#include <cassert> |
| 21 | 21 |
|
| 22 | 22 |
#include "bios.h" |
| 23 |
-//#include "debug.h" |
|
| 24 | 23 |
#include "MMU.h" |
| 25 | 24 |
#include "NDSSystem.h" |
| 26 |
-#include "thumb_instructions.h" |
|
| 27 | 25 |
#include "MMU_timing.h" |
| 28 | 26 |
|
| 29 | 27 |
#define cpu (&ARMPROC) |
| 30 | 28 |
#define TEMPLATE template<int PROCNUM> |
| 31 | 29 |
|
| 32 |
-//#define REG_NUM(i, n) (((i)>>n)&0x7) |
|
| 33 | 30 |
static inline uint32_t REG_NUM(uint32_t i, uint32_t n) { return (i >> n) & 0x7; }
|
| 34 | 31 |
|
| 35 | 32 |
//----------------------------------------------------------------------------- |
| 36 | 33 |
// Undefined instruction |
| 37 | 34 |
//----------------------------------------------------------------------------- |
| 38 |
-TEMPLATE static uint32_t FASTCALL OP_UND_THUMB(const uint32_t) |
|
| 35 |
+TEMPLATE static uint32_t FASTCALL OP_UND_THUMB(uint32_t) |
|
| 39 | 36 |
{
|
| 40 | 37 |
//INFO("THUMB%c: Undefined instruction: 0x%08X (%s) PC=0x%08X\n", cpu->proc_ID?'7':'9', cpu->instruction, decodeIntruction(true, cpu->instruction), cpu->instruct_adr);
|
| 41 | 38 |
TRAPUNDEF(cpu); |
| ... | ... |
@@ -46,45 +43,45 @@ TEMPLATE static uint32_t FASTCALL OP_UND_THUMB(const uint32_t) |
| 46 | 43 |
// LSL |
| 47 | 44 |
//----------------------------------------------------------------------------- |
| 48 | 45 |
|
| 49 |
-TEMPLATE static uint32_t FASTCALL OP_LSL_0(const uint32_t i) |
|
| 46 |
+TEMPLATE static uint32_t FASTCALL OP_LSL_0(uint32_t i) |
|
| 50 | 47 |
{
|
| 51 | 48 |
cpu->R[REG_NUM(i, 0)] = cpu->R[REG_NUM(i, 3)]; |
| 52 | 49 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 53 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 50 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 54 | 51 |
|
| 55 | 52 |
return 1; |
| 56 | 53 |
} |
| 57 | 54 |
|
| 58 |
-TEMPLATE static uint32_t FASTCALL OP_LSL(const uint32_t i) |
|
| 55 |
+TEMPLATE static uint32_t FASTCALL OP_LSL(uint32_t i) |
|
| 59 | 56 |
{
|
| 60 |
- uint32_t v = (i>>6) & 0x1F; |
|
| 61 |
- cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], 32-v); |
|
| 62 |
- cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] << v); |
|
| 57 |
+ uint32_t v = (i >> 6) & 0x1F; |
|
| 58 |
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], 32 - v); |
|
| 59 |
+ cpu->R[REG_NUM(i, 0)] = cpu->R[REG_NUM(i, 3)] << v; |
|
| 63 | 60 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 64 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 61 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 65 | 62 |
|
| 66 | 63 |
return 1; |
| 67 | 64 |
} |
| 68 | 65 |
|
| 69 |
-TEMPLATE static uint32_t FASTCALL OP_LSL_REG(const uint32_t i) |
|
| 66 |
+TEMPLATE static uint32_t FASTCALL OP_LSL_REG(uint32_t i) |
|
| 70 | 67 |
{
|
| 71 | 68 |
uint32_t v = cpu->R[REG_NUM(i, 3)] & 0xFF; |
| 72 | 69 |
|
| 73 |
- if(v == 0) |
|
| 70 |
+ if (!v) |
|
| 74 | 71 |
{
|
| 75 | 72 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 76 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 73 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 77 | 74 |
return 2; |
| 78 | 75 |
} |
| 79 |
- if(v<32) |
|
| 76 |
+ if (v < 32) |
|
| 80 | 77 |
{
|
| 81 |
- cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], 32-v); |
|
| 78 |
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], 32 - v); |
|
| 82 | 79 |
cpu->R[REG_NUM(i, 0)] <<= v; |
| 83 | 80 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 84 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 81 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 85 | 82 |
return 2; |
| 86 | 83 |
} |
| 87 |
- if(v==32) |
|
| 84 |
+ if (v == 32) |
|
| 88 | 85 |
cpu->CPSR.bits.C = BIT0(cpu->R[REG_NUM(i, 0)]); |
| 89 | 86 |
else |
| 90 | 87 |
cpu->CPSR.bits.C = 0; |
| ... | ... |
@@ -100,7 +97,7 @@ TEMPLATE static uint32_t FASTCALL OP_LSL_REG(const uint32_t i) |
| 100 | 97 |
// LSR |
| 101 | 98 |
//----------------------------------------------------------------------------- |
| 102 | 99 |
|
| 103 |
-TEMPLATE static uint32_t FASTCALL OP_LSR_0(const uint32_t i) |
|
| 100 |
+TEMPLATE static uint32_t FASTCALL OP_LSR_0(uint32_t i) |
|
| 104 | 101 |
{
|
| 105 | 102 |
cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]); |
| 106 | 103 |
cpu->R[REG_NUM(i, 0)] = 0; |
| ... | ... |
@@ -110,39 +107,40 @@ TEMPLATE static uint32_t FASTCALL OP_LSR_0(const uint32_t i) |
| 110 | 107 |
return 1; |
| 111 | 108 |
} |
| 112 | 109 |
|
| 113 |
-TEMPLATE static uint32_t FASTCALL OP_LSR(const uint32_t i) |
|
| 110 |
+TEMPLATE static uint32_t FASTCALL OP_LSR(uint32_t i) |
|
| 114 | 111 |
{
|
| 115 |
- uint32_t v = (i>>6) & 0x1F; |
|
| 116 |
- cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], v-1); |
|
| 117 |
- cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] >> v); |
|
| 112 |
+ uint32_t v = (i >> 6) & 0x1F; |
|
| 113 |
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], v - 1); |
|
| 114 |
+ cpu->R[REG_NUM(i, 0)] = cpu->R[REG_NUM(i, 3)] >> v; |
|
| 118 | 115 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 119 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 116 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 120 | 117 |
|
| 121 | 118 |
return 1; |
| 122 | 119 |
} |
| 123 | 120 |
|
| 124 |
-TEMPLATE static uint32_t FASTCALL OP_LSR_REG(const uint32_t i) |
|
| 121 |
+TEMPLATE static uint32_t FASTCALL OP_LSR_REG(uint32_t i) |
|
| 125 | 122 |
{
|
| 126 | 123 |
uint32_t v = cpu->R[REG_NUM(i, 3)] & 0xFF; |
| 127 | 124 |
|
| 128 |
- if(v == 0) |
|
| 125 |
+ if (!v) |
|
| 129 | 126 |
{
|
| 130 | 127 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 131 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 128 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 132 | 129 |
return 2; |
| 133 | 130 |
} |
| 134 |
- if(v<32) |
|
| 131 |
+ if (v < 32) |
|
| 135 | 132 |
{
|
| 136 |
- cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); |
|
| 133 |
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v - 1); |
|
| 137 | 134 |
cpu->R[REG_NUM(i, 0)] >>= v; |
| 138 | 135 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 139 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 136 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 140 | 137 |
return 2; |
| 141 | 138 |
} |
| 142 |
- if(v==32) |
|
| 139 |
+ if (v == 32) |
|
| 143 | 140 |
cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 144 | 141 |
else |
| 145 | 142 |
cpu->CPSR.bits.C = 0; |
| 143 |
+ |
|
| 146 | 144 |
cpu->R[REG_NUM(i, 0)] = 0; |
| 147 | 145 |
cpu->CPSR.bits.N = 0; |
| 148 | 146 |
cpu->CPSR.bits.Z = 1; |
| ... | ... |
@@ -154,50 +152,50 @@ TEMPLATE static uint32_t FASTCALL OP_LSR_REG(const uint32_t i) |
| 154 | 152 |
// ASR |
| 155 | 153 |
//----------------------------------------------------------------------------- |
| 156 | 154 |
|
| 157 |
-TEMPLATE static uint32_t FASTCALL OP_ASR_0(const uint32_t i) |
|
| 155 |
+TEMPLATE static uint32_t FASTCALL OP_ASR_0(uint32_t i) |
|
| 158 | 156 |
{
|
| 159 | 157 |
cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]); |
| 160 |
- cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 3)])*0xFFFFFFFF; |
|
| 158 |
+ cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 3)]) * 0xFFFFFFFF; |
|
| 161 | 159 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 162 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 160 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 163 | 161 |
|
| 164 | 162 |
return 1; |
| 165 | 163 |
} |
| 166 | 164 |
|
| 167 |
-TEMPLATE static uint32_t FASTCALL OP_ASR(const uint32_t i) |
|
| 165 |
+TEMPLATE static uint32_t FASTCALL OP_ASR(uint32_t i) |
|
| 168 | 166 |
{
|
| 169 |
- uint32_t v = (i>>6) & 0x1F; |
|
| 167 |
+ uint32_t v = (i >> 6) & 0x1F; |
|
| 170 | 168 |
cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], v-1); |
| 171 |
- cpu->R[REG_NUM(i, 0)] = (uint32_t)(((int32_t)cpu->R[REG_NUM(i, 3)]) >> v); |
|
| 169 |
+ cpu->R[REG_NUM(i, 0)] = static_cast<uint32_t>(static_cast<int32_t>(cpu->R[REG_NUM(i, 3)]) >> v); |
|
| 172 | 170 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 173 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 171 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 174 | 172 |
|
| 175 | 173 |
return 1; |
| 176 | 174 |
} |
| 177 | 175 |
|
| 178 |
-TEMPLATE static uint32_t FASTCALL OP_ASR_REG(const uint32_t i) |
|
| 176 |
+TEMPLATE static uint32_t FASTCALL OP_ASR_REG(uint32_t i) |
|
| 179 | 177 |
{
|
| 180 | 178 |
uint32_t v = cpu->R[REG_NUM(i, 3)] & 0xFF; |
| 181 | 179 |
|
| 182 |
- if(v == 0) |
|
| 180 |
+ if (!v) |
|
| 183 | 181 |
{
|
| 184 | 182 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 185 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 183 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 186 | 184 |
return 2; |
| 187 | 185 |
} |
| 188 |
- if(v<32) |
|
| 186 |
+ if (v < 32) |
|
| 189 | 187 |
{
|
| 190 |
- cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); |
|
| 191 |
- cpu->R[REG_NUM(i, 0)] = (uint32_t)(((int32_t)cpu->R[REG_NUM(i, 0)]) >> v); |
|
| 188 |
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v - 1); |
|
| 189 |
+ cpu->R[REG_NUM(i, 0)] = static_cast<uint32_t>(static_cast<int32_t>(cpu->R[REG_NUM(i, 0)]) >> v); |
|
| 192 | 190 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 193 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 191 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 194 | 192 |
return 2; |
| 195 | 193 |
} |
| 196 | 194 |
|
| 197 | 195 |
cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 198 |
- cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 0)])*0xFFFFFFFF; |
|
| 196 |
+ cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 0)]) * 0xFFFFFFFF; |
|
| 199 | 197 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 200 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 198 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 201 | 199 |
|
| 202 | 200 |
return 2; |
| 203 | 201 |
} |
| ... | ... |
@@ -206,66 +204,65 @@ TEMPLATE static uint32_t FASTCALL OP_ASR_REG(const uint32_t i) |
| 206 | 204 |
// ADD |
| 207 | 205 |
//----------------------------------------------------------------------------- |
| 208 | 206 |
|
| 209 |
-TEMPLATE static uint32_t FASTCALL OP_ADD_IMM3(const uint32_t i) |
|
| 207 |
+TEMPLATE static uint32_t FASTCALL OP_ADD_IMM3(uint32_t i) |
|
| 210 | 208 |
{
|
| 211 | 209 |
uint32_t imm3 = (i >> 6) & 0x07; |
| 212 | 210 |
uint32_t Rn = cpu->R[REG_NUM(i, 3)]; |
| 213 | 211 |
|
| 214 |
- if (imm3 == 0) // mov 2 |
|
| 212 |
+ if (!imm3) // mov 2 |
|
| 215 | 213 |
{
|
| 216 | 214 |
cpu->R[REG_NUM(i, 0)] = Rn; |
| 217 | 215 |
|
| 218 | 216 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 219 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 220 |
- cpu->CPSR.bits.C = 0; |
|
| 221 |
- cpu->CPSR.bits.V = 0; |
|
| 217 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 218 |
+ cpu->CPSR.bits.C = cpu->CPSR.bits.V = 0; |
|
| 222 | 219 |
return 1; |
| 223 | 220 |
} |
| 224 | 221 |
|
| 225 | 222 |
cpu->R[REG_NUM(i, 0)] = Rn + imm3; |
| 226 | 223 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 227 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 224 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 228 | 225 |
cpu->CPSR.bits.C = CarryFrom(Rn, imm3); |
| 229 | 226 |
cpu->CPSR.bits.V = OverflowFromADD(cpu->R[REG_NUM(i, 0)], Rn, imm3); |
| 230 | 227 |
|
| 231 | 228 |
return 1; |
| 232 | 229 |
} |
| 233 | 230 |
|
| 234 |
-TEMPLATE static uint32_t FASTCALL OP_ADD_IMM8(const uint32_t i) |
|
| 231 |
+TEMPLATE static uint32_t FASTCALL OP_ADD_IMM8(uint32_t i) |
|
| 235 | 232 |
{
|
| 236 |
- uint32_t imm8 = (i & 0xFF); |
|
| 233 |
+ uint32_t imm8 = i & 0xFF; |
|
| 237 | 234 |
uint32_t Rd = cpu->R[REG_NUM(i, 8)]; |
| 238 | 235 |
|
| 239 | 236 |
cpu->R[REG_NUM(i, 8)] = Rd + imm8; |
| 240 | 237 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 8)]); |
| 241 |
- cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 8)] == 0); |
|
| 238 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 8)]; |
|
| 242 | 239 |
cpu->CPSR.bits.C = CarryFrom(Rd, imm8); |
| 243 | 240 |
cpu->CPSR.bits.V = OverflowFromADD(cpu->R[REG_NUM(i, 8)], Rd, imm8); |
| 244 | 241 |
|
| 245 | 242 |
return 1; |
| 246 | 243 |
} |
| 247 | 244 |
|
| 248 |
-TEMPLATE static uint32_t FASTCALL OP_ADD_REG(const uint32_t i) |
|
| 245 |
+TEMPLATE static uint32_t FASTCALL OP_ADD_REG(uint32_t i) |
|
| 249 | 246 |
{
|
| 250 | 247 |
uint32_t Rn = cpu->R[REG_NUM(i, 3)]; |
| 251 | 248 |
uint32_t Rm = cpu->R[REG_NUM(i, 6)]; |
| 252 | 249 |
|
| 253 | 250 |
cpu->R[REG_NUM(i, 0)] = Rn + Rm; |
| 254 | 251 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 255 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 252 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 256 | 253 |
cpu->CPSR.bits.C = CarryFrom(Rn, Rm); |
| 257 | 254 |
cpu->CPSR.bits.V = OverflowFromADD(cpu->R[REG_NUM(i, 0)], Rn, Rm); |
| 258 | 255 |
|
| 259 | 256 |
return 1; |
| 260 | 257 |
} |
| 261 | 258 |
|
| 262 |
-TEMPLATE static uint32_t FASTCALL OP_ADD_SPE(const uint32_t i) |
|
| 259 |
+TEMPLATE static uint32_t FASTCALL OP_ADD_SPE(uint32_t i) |
|
| 263 | 260 |
{
|
| 264 |
- uint32_t Rd = REG_NUM(i, 0) | ((i>>4)&8); |
|
| 261 |
+ uint32_t Rd = REG_NUM(i, 0) | ((i >> 4) & 8); |
|
| 265 | 262 |
|
| 266 | 263 |
cpu->R[Rd] += cpu->R[REG_POS(i, 3)]; |
| 267 | 264 |
|
| 268 |
- if(Rd==15) |
|
| 265 |
+ if (Rd == 15) |
|
| 269 | 266 |
{
|
| 270 | 267 |
cpu->next_instruction = cpu->R[15]; |
| 271 | 268 |
return 3; |
| ... | ... |
@@ -274,16 +271,16 @@ TEMPLATE static uint32_t FASTCALL OP_ADD_SPE(const uint32_t i) |
| 274 | 271 |
return 1; |
| 275 | 272 |
} |
| 276 | 273 |
|
| 277 |
-TEMPLATE static uint32_t FASTCALL OP_ADD_2PC(const uint32_t i) |
|
| 274 |
+TEMPLATE static uint32_t FASTCALL OP_ADD_2PC(uint32_t i) |
|
| 278 | 275 |
{
|
| 279 |
- cpu->R[REG_NUM(i, 8)] = (cpu->R[15]&0xFFFFFFFC) + ((i&0xFF)<<2); |
|
| 276 |
+ cpu->R[REG_NUM(i, 8)] = (cpu->R[15] & 0xFFFFFFFC) + ((i & 0xFF) << 2); |
|
| 280 | 277 |
|
| 281 | 278 |
return 1; |
| 282 | 279 |
} |
| 283 | 280 |
|
| 284 |
-TEMPLATE static uint32_t FASTCALL OP_ADD_2SP(const uint32_t i) |
|
| 281 |
+TEMPLATE static uint32_t FASTCALL OP_ADD_2SP(uint32_t i) |
|
| 285 | 282 |
{
|
| 286 |
- cpu->R[REG_NUM(i, 8)] = cpu->R[13] + ((i&0xFF)<<2); |
|
| 283 |
+ cpu->R[REG_NUM(i, 8)] = cpu->R[13] + ((i & 0xFF) << 2); |
|
| 287 | 284 |
|
| 288 | 285 |
return 1; |
| 289 | 286 |
} |
| ... | ... |
@@ -292,37 +289,37 @@ TEMPLATE static uint32_t FASTCALL OP_ADD_2SP(const uint32_t i) |
| 292 | 289 |
// SUB |
| 293 | 290 |
//----------------------------------------------------------------------------- |
| 294 | 291 |
|
| 295 |
-TEMPLATE static uint32_t FASTCALL OP_SUB_IMM3(const uint32_t i) |
|
| 292 |
+TEMPLATE static uint32_t FASTCALL OP_SUB_IMM3(uint32_t i) |
|
| 296 | 293 |
{
|
| 297 |
- uint32_t imm3 = (i>>6) & 0x07; |
|
| 294 |
+ uint32_t imm3 = (i >> 6) & 0x07; |
|
| 298 | 295 |
uint32_t Rn = cpu->R[REG_NUM(i, 3)]; |
| 299 | 296 |
uint32_t tmp = Rn - imm3; |
| 300 | 297 |
|
| 301 | 298 |
cpu->R[REG_NUM(i, 0)] = tmp; |
| 302 | 299 |
cpu->CPSR.bits.N = BIT31(tmp); |
| 303 |
- cpu->CPSR.bits.Z = (tmp == 0); |
|
| 300 |
+ cpu->CPSR.bits.Z = !tmp; |
|
| 304 | 301 |
cpu->CPSR.bits.C = !BorrowFrom(Rn, imm3); |
| 305 | 302 |
cpu->CPSR.bits.V = OverflowFromSUB(tmp, Rn, imm3); |
| 306 | 303 |
|
| 307 | 304 |
return 1; |
| 308 | 305 |
} |
| 309 | 306 |
|
| 310 |
-TEMPLATE static uint32_t FASTCALL OP_SUB_IMM8(const uint32_t i) |
|
| 307 |
+TEMPLATE static uint32_t FASTCALL OP_SUB_IMM8(uint32_t i) |
|
| 311 | 308 |
{
|
| 312 |
- uint32_t imm8 = (i & 0xFF); |
|
| 309 |
+ uint32_t imm8 = i & 0xFF; |
|
| 313 | 310 |
uint32_t Rd = cpu->R[REG_NUM(i, 8)]; |
| 314 | 311 |
uint32_t tmp = Rd - imm8; |
| 315 | 312 |
|
| 316 | 313 |
cpu->R[REG_NUM(i, 8)] = tmp; |
| 317 | 314 |
cpu->CPSR.bits.N = BIT31(tmp); |
| 318 |
- cpu->CPSR.bits.Z = (tmp == 0); |
|
| 315 |
+ cpu->CPSR.bits.Z = !tmp; |
|
| 319 | 316 |
cpu->CPSR.bits.C = !BorrowFrom(Rd, imm8); |
| 320 | 317 |
cpu->CPSR.bits.V = OverflowFromSUB(tmp, Rd, imm8); |
| 321 | 318 |
|
| 322 | 319 |
return 1; |
| 323 | 320 |
} |
| 324 | 321 |
|
| 325 |
-TEMPLATE static uint32_t FASTCALL OP_SUB_REG(const uint32_t i) |
|
| 322 |
+TEMPLATE static uint32_t FASTCALL OP_SUB_REG(uint32_t i) |
|
| 326 | 323 |
{
|
| 327 | 324 |
uint32_t Rn = cpu->R[REG_NUM(i, 3)]; |
| 328 | 325 |
uint32_t Rm = cpu->R[REG_NUM(i, 6)]; |
| ... | ... |
@@ -330,7 +327,7 @@ TEMPLATE static uint32_t FASTCALL OP_SUB_REG(const uint32_t i) |
| 330 | 327 |
|
| 331 | 328 |
cpu->R[REG_NUM(i, 0)] = tmp; |
| 332 | 329 |
cpu->CPSR.bits.N = BIT31(tmp); |
| 333 |
- cpu->CPSR.bits.Z = (tmp == 0); |
|
| 330 |
+ cpu->CPSR.bits.Z = !tmp; |
|
| 334 | 331 |
cpu->CPSR.bits.C = !BorrowFrom(Rn, Rm); |
| 335 | 332 |
cpu->CPSR.bits.V = OverflowFromSUB(tmp, Rn, Rm); |
| 336 | 333 |
|
| ... | ... |
@@ -341,22 +338,22 @@ TEMPLATE static uint32_t FASTCALL OP_SUB_REG(const uint32_t i) |
| 341 | 338 |
// MOV |
| 342 | 339 |
//----------------------------------------------------------------------------- |
| 343 | 340 |
|
| 344 |
-TEMPLATE static uint32_t FASTCALL OP_MOV_IMM8(const uint32_t i) |
|
| 341 |
+TEMPLATE static uint32_t FASTCALL OP_MOV_IMM8(uint32_t i) |
|
| 345 | 342 |
{
|
| 346 |
- cpu->R[REG_NUM(i, 8)] = (i & 0xFF); |
|
| 343 |
+ cpu->R[REG_NUM(i, 8)] = i & 0xFF; |
|
| 347 | 344 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 8)]); |
| 348 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 8)] == 0; |
|
| 345 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 8)]; |
|
| 349 | 346 |
|
| 350 | 347 |
return 1; |
| 351 | 348 |
} |
| 352 | 349 |
|
| 353 |
-TEMPLATE static uint32_t FASTCALL OP_MOV_SPE(const uint32_t i) |
|
| 350 |
+TEMPLATE static uint32_t FASTCALL OP_MOV_SPE(uint32_t i) |
|
| 354 | 351 |
{
|
| 355 |
- uint32_t Rd = REG_NUM(i, 0) | ((i>>4)&8); |
|
| 352 |
+ uint32_t Rd = REG_NUM(i, 0) | ((i >> 4) & 8); |
|
| 356 | 353 |
|
| 357 | 354 |
cpu->R[Rd] = cpu->R[REG_POS(i, 3)]; |
| 358 | 355 |
|
| 359 |
- if(Rd==15) |
|
| 356 |
+ if (Rd == 15) |
|
| 360 | 357 |
{
|
| 361 | 358 |
cpu->next_instruction = cpu->R[15]; |
| 362 | 359 |
return 3; |
| ... | ... |
@@ -368,38 +365,38 @@ TEMPLATE static uint32_t FASTCALL OP_MOV_SPE(const uint32_t i) |
| 368 | 365 |
//----------------------------------------------------------------------------- |
| 369 | 366 |
// CMP |
| 370 | 367 |
//----------------------------------------------------------------------------- |
| 371 |
-TEMPLATE static uint32_t FASTCALL OP_CMP_IMM8(const uint32_t i) |
|
| 368 |
+TEMPLATE static uint32_t FASTCALL OP_CMP_IMM8(uint32_t i) |
|
| 372 | 369 |
{
|
| 373 | 370 |
uint32_t tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF); |
| 374 | 371 |
|
| 375 | 372 |
cpu->CPSR.bits.N = BIT31(tmp); |
| 376 |
- cpu->CPSR.bits.Z = tmp == 0; |
|
| 377 |
- cpu->CPSR.bits.C = !BorrowFrom(cpu->R[REG_NUM(i, 8)], (i & 0xFF)); |
|
| 378 |
- cpu->CPSR.bits.V = OverflowFromSUB(tmp, cpu->R[REG_NUM(i, 8)], (i & 0xFF)); |
|
| 373 |
+ cpu->CPSR.bits.Z = !tmp; |
|
| 374 |
+ cpu->CPSR.bits.C = !BorrowFrom(cpu->R[REG_NUM(i, 8)], i & 0xFF); |
|
| 375 |
+ cpu->CPSR.bits.V = OverflowFromSUB(tmp, cpu->R[REG_NUM(i, 8)], i & 0xFF); |
|
| 379 | 376 |
|
| 380 | 377 |
return 1; |
| 381 | 378 |
} |
| 382 | 379 |
|
| 383 |
-TEMPLATE static uint32_t FASTCALL OP_CMP(const uint32_t i) |
|
| 380 |
+TEMPLATE static uint32_t FASTCALL OP_CMP(uint32_t i) |
|
| 384 | 381 |
{
|
| 385 | 382 |
uint32_t tmp = cpu->R[REG_NUM(i, 0)] - cpu->R[REG_NUM(i, 3)]; |
| 386 | 383 |
|
| 387 | 384 |
cpu->CPSR.bits.N = BIT31(tmp); |
| 388 |
- cpu->CPSR.bits.Z = tmp == 0; |
|
| 385 |
+ cpu->CPSR.bits.Z = !tmp; |
|
| 389 | 386 |
cpu->CPSR.bits.C = !BorrowFrom(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)]); |
| 390 | 387 |
cpu->CPSR.bits.V = OverflowFromSUB(tmp, cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)]); |
| 391 | 388 |
|
| 392 | 389 |
return 1; |
| 393 | 390 |
} |
| 394 | 391 |
|
| 395 |
-TEMPLATE static uint32_t FASTCALL OP_CMP_SPE(const uint32_t i) |
|
| 392 |
+TEMPLATE static uint32_t FASTCALL OP_CMP_SPE(uint32_t i) |
|
| 396 | 393 |
{
|
| 397 |
- uint32_t Rn = (i&7) | ((i>>4)&8); |
|
| 394 |
+ uint32_t Rn = (i & 7) | ((i >> 4) & 8); |
|
| 398 | 395 |
|
| 399 | 396 |
uint32_t tmp = cpu->R[Rn] - cpu->R[REG_POS(i, 3)]; |
| 400 | 397 |
|
| 401 | 398 |
cpu->CPSR.bits.N = BIT31(tmp); |
| 402 |
- cpu->CPSR.bits.Z = tmp == 0; |
|
| 399 |
+ cpu->CPSR.bits.Z = !tmp; |
|
| 403 | 400 |
cpu->CPSR.bits.C = !BorrowFrom(cpu->R[Rn], cpu->R[REG_POS(i, 3)]); |
| 404 | 401 |
cpu->CPSR.bits.V = OverflowFromSUB(tmp, cpu->R[Rn], cpu->R[REG_POS(i, 3)]); |
| 405 | 402 |
|
| ... | ... |
@@ -410,11 +407,11 @@ TEMPLATE static uint32_t FASTCALL OP_CMP_SPE(const uint32_t i) |
| 410 | 407 |
// AND |
| 411 | 408 |
//----------------------------------------------------------------------------- |
| 412 | 409 |
|
| 413 |
-TEMPLATE static uint32_t FASTCALL OP_AND(const uint32_t i) |
|
| 410 |
+TEMPLATE static uint32_t FASTCALL OP_AND(uint32_t i) |
|
| 414 | 411 |
{
|
| 415 | 412 |
cpu->R[REG_NUM(i, 0)] &= cpu->R[REG_NUM(i, 3)]; |
| 416 | 413 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 417 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 414 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 418 | 415 |
return 1; |
| 419 | 416 |
} |
| 420 | 417 |
|
| ... | ... |
@@ -422,11 +419,11 @@ TEMPLATE static uint32_t FASTCALL OP_AND(const uint32_t i) |
| 422 | 419 |
// EOR |
| 423 | 420 |
//----------------------------------------------------------------------------- |
| 424 | 421 |
|
| 425 |
-TEMPLATE static uint32_t FASTCALL OP_EOR(const uint32_t i) |
|
| 422 |
+TEMPLATE static uint32_t FASTCALL OP_EOR(uint32_t i) |
|
| 426 | 423 |
{
|
| 427 | 424 |
cpu->R[REG_NUM(i, 0)] ^= cpu->R[REG_NUM(i, 3)]; |
| 428 | 425 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 429 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 426 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 430 | 427 |
|
| 431 | 428 |
return 1; |
| 432 | 429 |
} |
| ... | ... |
@@ -435,7 +432,7 @@ TEMPLATE static uint32_t FASTCALL OP_EOR(const uint32_t i) |
| 435 | 432 |
// ADC |
| 436 | 433 |
//----------------------------------------------------------------------------- |
| 437 | 434 |
|
| 438 |
-TEMPLATE static uint32_t FASTCALL OP_ADC_REG(const uint32_t i) |
|
| 435 |
+TEMPLATE static uint32_t FASTCALL OP_ADC_REG(uint32_t i) |
|
| 439 | 436 |
{
|
| 440 | 437 |
uint32_t Rd = cpu->R[REG_NUM(i, 0)]; |
| 441 | 438 |
uint32_t Rm = cpu->R[REG_NUM(i, 3)]; |
| ... | ... |
@@ -451,7 +448,7 @@ TEMPLATE static uint32_t FASTCALL OP_ADC_REG(const uint32_t i) |
| 451 | 448 |
cpu->CPSR.bits.C = cpu->R[REG_NUM(i, 0)] <= Rm; |
| 452 | 449 |
} |
| 453 | 450 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 454 |
- cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 0)] == 0); |
|
| 451 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 455 | 452 |
cpu->CPSR.bits.V = BIT31((Rd ^ Rm ^ -1) & (Rd ^ cpu->R[REG_NUM(i, 0)])); |
| 456 | 453 |
|
| 457 | 454 |
return 1; |
| ... | ... |
@@ -460,7 +457,8 @@ TEMPLATE static uint32_t FASTCALL OP_ADC_REG(const uint32_t i) |
| 460 | 457 |
//----------------------------------------------------------------------------- |
| 461 | 458 |
// SBC |
| 462 | 459 |
//----------------------------------------------------------------------------- |
| 463 |
-TEMPLATE static uint32_t FASTCALL OP_SBC_REG(const uint32_t i) |
|
| 460 |
+ |
|
| 461 |
+TEMPLATE static uint32_t FASTCALL OP_SBC_REG(uint32_t i) |
|
| 464 | 462 |
{
|
| 465 | 463 |
uint32_t Rd = cpu->R[REG_NUM(i, 0)]; |
| 466 | 464 |
uint32_t Rm = cpu->R[REG_NUM(i, 3)]; |
| ... | ... |
@@ -477,7 +475,7 @@ TEMPLATE static uint32_t FASTCALL OP_SBC_REG(const uint32_t i) |
| 477 | 475 |
} |
| 478 | 476 |
|
| 479 | 477 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 480 |
- cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 0)] == 0); |
|
| 478 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 481 | 479 |
cpu->CPSR.bits.V = BIT31((Rd ^ Rm) & (Rd ^ cpu->R[REG_NUM(i, 0)])); |
| 482 | 480 |
|
| 483 | 481 |
return 1; |
| ... | ... |
@@ -487,29 +485,30 @@ TEMPLATE static uint32_t FASTCALL OP_SBC_REG(const uint32_t i) |
| 487 | 485 |
// ROR |
| 488 | 486 |
//----------------------------------------------------------------------------- |
| 489 | 487 |
|
| 490 |
-TEMPLATE static uint32_t FASTCALL OP_ROR_REG(const uint32_t i) |
|
| 488 |
+TEMPLATE static uint32_t FASTCALL OP_ROR_REG(uint32_t i) |
|
| 491 | 489 |
{
|
| 492 | 490 |
uint32_t v = cpu->R[REG_NUM(i, 3)] & 0xFF; |
| 493 | 491 |
|
| 494 |
- if(v == 0) |
|
| 492 |
+ if (!v) |
|
| 495 | 493 |
{
|
| 496 |
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 497 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 498 |
- return 2; |
|
| 494 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 495 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 496 |
+ return 2; |
|
| 499 | 497 |
} |
| 500 | 498 |
|
| 501 | 499 |
v &= 0x1F; |
| 502 |
- if(v == 0) |
|
| 500 |
+ if (!v) |
|
| 503 | 501 |
{
|
| 504 |
- cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 505 |
- cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 506 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 507 |
- return 2; |
|
| 502 |
+ cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 503 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 504 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 505 |
+ return 2; |
|
| 508 | 506 |
} |
| 509 |
- cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); |
|
| 507 |
+ |
|
| 508 |
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v - 1); |
|
| 510 | 509 |
cpu->R[REG_NUM(i, 0)] = ROR(cpu->R[REG_NUM(i, 0)], v); |
| 511 | 510 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 512 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 511 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 513 | 512 |
|
| 514 | 513 |
return 2; |
| 515 | 514 |
} |
| ... | ... |
@@ -518,11 +517,11 @@ TEMPLATE static uint32_t FASTCALL OP_ROR_REG(const uint32_t i) |
| 518 | 517 |
// TST |
| 519 | 518 |
//----------------------------------------------------------------------------- |
| 520 | 519 |
|
| 521 |
-TEMPLATE static uint32_t FASTCALL OP_TST(const uint32_t i) |
|
| 520 |
+TEMPLATE static uint32_t FASTCALL OP_TST(uint32_t i) |
|
| 522 | 521 |
{
|
| 523 | 522 |
uint32_t tmp = cpu->R[REG_NUM(i, 0)] & cpu->R[REG_NUM(i, 3)]; |
| 524 | 523 |
cpu->CPSR.bits.N = BIT31(tmp); |
| 525 |
- cpu->CPSR.bits.Z = (tmp == 0); |
|
| 524 |
+ cpu->CPSR.bits.Z = !tmp; |
|
| 526 | 525 |
|
| 527 | 526 |
return 1; |
| 528 | 527 |
} |
| ... | ... |
@@ -531,14 +530,14 @@ TEMPLATE static uint32_t FASTCALL OP_TST(const uint32_t i) |
| 531 | 530 |
// NEG |
| 532 | 531 |
//----------------------------------------------------------------------------- |
| 533 | 532 |
|
| 534 |
-TEMPLATE static uint32_t FASTCALL OP_NEG(const uint32_t i) |
|
| 533 |
+TEMPLATE static uint32_t FASTCALL OP_NEG(uint32_t i) |
|
| 535 | 534 |
{
|
| 536 | 535 |
uint32_t Rm = cpu->R[REG_NUM(i, 3)]; |
| 537 | 536 |
|
| 538 |
- cpu->R[REG_NUM(i, 0)] = (uint32_t)((int32_t)0 - (int32_t)Rm); |
|
| 537 |
+ cpu->R[REG_NUM(i, 0)] = static_cast<uint32_t>(-static_cast<int32_t>(Rm)); |
|
| 539 | 538 |
|
| 540 | 539 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 541 |
- cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 0)] == 0); |
|
| 540 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 542 | 541 |
cpu->CPSR.bits.C = !BorrowFrom(0, Rm); |
| 543 | 542 |
cpu->CPSR.bits.V = OverflowFromSUB(cpu->R[REG_NUM(i, 0)], 0, Rm); |
| 544 | 543 |
|
| ... | ... |
@@ -549,12 +548,12 @@ TEMPLATE static uint32_t FASTCALL OP_NEG(const uint32_t i) |
| 549 | 548 |
// CMN |
| 550 | 549 |
//----------------------------------------------------------------------------- |
| 551 | 550 |
|
| 552 |
-TEMPLATE static uint32_t FASTCALL OP_CMN(const uint32_t i) |
|
| 551 |
+TEMPLATE static uint32_t FASTCALL OP_CMN(uint32_t i) |
|
| 553 | 552 |
{
|
| 554 | 553 |
uint32_t tmp = cpu->R[REG_NUM(i, 0)] + cpu->R[REG_NUM(i, 3)]; |
| 555 | 554 |
|
| 556 | 555 |
cpu->CPSR.bits.N = BIT31(tmp); |
| 557 |
- cpu->CPSR.bits.Z = tmp == 0; |
|
| 556 |
+ cpu->CPSR.bits.Z = !tmp; |
|
| 558 | 557 |
cpu->CPSR.bits.C = CarryFrom(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)]); |
| 559 | 558 |
cpu->CPSR.bits.V = OverflowFromADD(tmp, cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)]); |
| 560 | 559 |
|
| ... | ... |
@@ -565,12 +564,12 @@ TEMPLATE static uint32_t FASTCALL OP_CMN(const uint32_t i) |
| 565 | 564 |
// ORR |
| 566 | 565 |
//----------------------------------------------------------------------------- |
| 567 | 566 |
|
| 568 |
-TEMPLATE static uint32_t FASTCALL OP_ORR(const uint32_t i) |
|
| 567 |
+TEMPLATE static uint32_t FASTCALL OP_ORR(uint32_t i) |
|
| 569 | 568 |
{
|
| 570 | 569 |
cpu->R[REG_NUM(i, 0)] |= cpu->R[REG_NUM(i, 3)]; |
| 571 | 570 |
|
| 572 | 571 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 573 |
- cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 0)] == 0); |
|
| 572 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 574 | 573 |
|
| 575 | 574 |
return 1; |
| 576 | 575 |
} |
| ... | ... |
@@ -579,12 +578,12 @@ TEMPLATE static uint32_t FASTCALL OP_ORR(const uint32_t i) |
| 579 | 578 |
// BIC |
| 580 | 579 |
//----------------------------------------------------------------------------- |
| 581 | 580 |
|
| 582 |
-TEMPLATE static uint32_t FASTCALL OP_BIC(const uint32_t i) |
|
| 581 |
+TEMPLATE static uint32_t FASTCALL OP_BIC(uint32_t i) |
|
| 583 | 582 |
{
|
| 584 |
- cpu->R[REG_NUM(i, 0)] &= (~cpu->R[REG_NUM(i, 3)]); |
|
| 583 |
+ cpu->R[REG_NUM(i, 0)] &= ~cpu->R[REG_NUM(i, 3)]; |
|
| 585 | 584 |
|
| 586 | 585 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 587 |
- cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 0)] == 0); |
|
| 586 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 588 | 587 |
|
| 589 | 588 |
return 1; |
| 590 | 589 |
} |
| ... | ... |
@@ -593,12 +592,12 @@ TEMPLATE static uint32_t FASTCALL OP_BIC(const uint32_t i) |
| 593 | 592 |
// MVN |
| 594 | 593 |
//----------------------------------------------------------------------------- |
| 595 | 594 |
|
| 596 |
-TEMPLATE static uint32_t FASTCALL OP_MVN(const uint32_t i) |
|
| 595 |
+TEMPLATE static uint32_t FASTCALL OP_MVN(uint32_t i) |
|
| 597 | 596 |
{
|
| 598 |
- cpu->R[REG_NUM(i, 0)] = (~cpu->R[REG_NUM(i, 3)]); |
|
| 597 |
+ cpu->R[REG_NUM(i, 0)] = ~cpu->R[REG_NUM(i, 3)]; |
|
| 599 | 598 |
|
| 600 | 599 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 601 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 600 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 602 | 601 |
|
| 603 | 602 |
return 1; |
| 604 | 603 |
} |
| ... | ... |
@@ -609,17 +608,17 @@ TEMPLATE static uint32_t FASTCALL OP_MVN(const uint32_t i) |
| 609 | 608 |
|
| 610 | 609 |
#define MUL_Mxx_END_THUMB(c) \ |
| 611 | 610 |
v >>= 8; \ |
| 612 |
- if((v==0)||(v==0xFFFFFF)) \ |
|
| 613 |
- return c+1; \ |
|
| 611 |
+ if (!v || v == 0xFFFFFF) \ |
|
| 612 |
+ return c + 1; \ |
|
| 614 | 613 |
v >>= 8; \ |
| 615 |
- if((v==0)||(v==0xFFFF)) \ |
|
| 616 |
- return c+2; \ |
|
| 614 |
+ if (!v || v == 0xFFFF) \ |
|
| 615 |
+ return c + 2; \ |
|
| 617 | 616 |
v >>= 8; \ |
| 618 |
- if((v==0)||(v==0xFF)) \ |
|
| 619 |
- return c+3; \ |
|
| 620 |
- return c+4; \ |
|
| 617 |
+ if (!v || v == 0xFF) \ |
|
| 618 |
+ return c + 3; \ |
|
| 619 |
+ return c + 4; |
|
| 621 | 620 |
|
| 622 |
-TEMPLATE static uint32_t FASTCALL OP_MUL_REG(const uint32_t i) |
|
| 621 |
+TEMPLATE static uint32_t FASTCALL OP_MUL_REG(uint32_t i) |
|
| 623 | 622 |
{
|
| 624 | 623 |
uint32_t v = cpu->R[REG_NUM(i, 3)]; |
| 625 | 624 |
|
| ... | ... |
@@ -631,12 +630,12 @@ TEMPLATE static uint32_t FASTCALL OP_MUL_REG(const uint32_t i) |
| 631 | 630 |
|
| 632 | 631 |
cpu->R[REG_NUM(i, 0)] *= v; |
| 633 | 632 |
cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
| 634 |
- cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 633 |
+ cpu->CPSR.bits.Z = !cpu->R[REG_NUM(i, 0)]; |
|
| 635 | 634 |
//The MUL instruction is defined to leave the C flag unchanged in ARMv5 and above. |
| 636 | 635 |
//In earlier versions of the architecture, the value of the C flag was UNPREDICTABLE |
| 637 | 636 |
//after a MUL instruction. |
| 638 | 637 |
|
| 639 |
- if (!cpu->LDTBit) // ARM4T 1S + mI, m = 3 |
|
| 638 |
+ if (PROCNUM == 1) // ARM4T 1S + mI, m = 3 |
|
| 640 | 639 |
return 4; |
| 641 | 640 |
|
| 642 | 641 |
MUL_Mxx_END_THUMB(1); |
| ... | ... |
@@ -646,182 +645,179 @@ TEMPLATE static uint32_t FASTCALL OP_MUL_REG(const uint32_t i) |
| 646 | 645 |
// STRB / LDRB |
| 647 | 646 |
//----------------------------------------------------------------------------- |
| 648 | 647 |
|
| 649 |
-TEMPLATE static uint32_t FASTCALL OP_STRB_IMM_OFF(const uint32_t i) |
|
| 648 |
+TEMPLATE static uint32_t FASTCALL OP_STRB_IMM_OFF(uint32_t i) |
|
| 650 | 649 |
{
|
| 651 |
- uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F); |
|
| 652 |
- WRITE8(cpu->mem_if->data, adr, (uint8_t)cpu->R[REG_NUM(i, 0)]); |
|
| 650 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i >> 6) & 0x1F); |
|
| 651 |
+ WRITE8(cpu->mem_if->data, adr, static_cast<uint8_t>(cpu->R[REG_NUM(i, 0)])); |
|
| 653 | 652 |
|
| 654 |
- return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_WRITE>(2, adr); |
|
| 653 |
+ return MMU_aluMemAccessCycles<PROCNUM, 8, MMU_AD_WRITE>(2, adr); |
|
| 655 | 654 |
} |
| 656 | 655 |
|
| 657 |
-TEMPLATE static uint32_t FASTCALL OP_LDRB_IMM_OFF(const uint32_t i) |
|
| 656 |
+TEMPLATE static uint32_t FASTCALL OP_LDRB_IMM_OFF(uint32_t i) |
|
| 658 | 657 |
{
|
| 659 | 658 |
uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F); |
| 660 |
- cpu->R[REG_NUM(i, 0)] = (uint32_t)READ8(cpu->mem_if->data, adr); |
|
| 659 |
+ cpu->R[REG_NUM(i, 0)] = static_cast<uint32_t>(READ8(cpu->mem_if->data, adr)); |
|
| 661 | 660 |
|
| 662 |
- return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_READ>(3, adr); |
|
| 661 |
+ return MMU_aluMemAccessCycles<PROCNUM, 8, MMU_AD_READ>(3, adr); |
|
| 663 | 662 |
} |
| 664 | 663 |
|
| 665 |
- |
|
| 666 |
-TEMPLATE static uint32_t FASTCALL OP_STRB_REG_OFF(const uint32_t i) |
|
| 664 |
+TEMPLATE static uint32_t FASTCALL OP_STRB_REG_OFF(uint32_t i) |
|
| 667 | 665 |
{
|
| 668 | 666 |
uint32_t adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; |
| 669 |
- WRITE8(cpu->mem_if->data, adr, (uint8_t)cpu->R[REG_NUM(i, 0)]); |
|
| 667 |
+ WRITE8(cpu->mem_if->data, adr, static_cast<uint8_t>(cpu->R[REG_NUM(i, 0)])); |
|
| 670 | 668 |
|
| 671 |
- return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_WRITE>(2, adr); |
|
| 669 |
+ return MMU_aluMemAccessCycles<PROCNUM, 8, MMU_AD_WRITE>(2, adr); |
|
| 672 | 670 |
} |
| 673 | 671 |
|
| 674 |
-TEMPLATE static uint32_t FASTCALL OP_LDRB_REG_OFF(const uint32_t i) |
|
| 672 |
+TEMPLATE static uint32_t FASTCALL OP_LDRB_REG_OFF(uint32_t i) |
|
| 675 | 673 |
{
|
| 676 | 674 |
uint32_t adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; |
| 677 |
- cpu->R[REG_NUM(i, 0)] = (uint32_t)READ8(cpu->mem_if->data, adr); |
|
| 675 |
+ cpu->R[REG_NUM(i, 0)] = static_cast<uint32_t>(READ8(cpu->mem_if->data, adr)); |
|
| 678 | 676 |
|
| 679 |
- return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_READ>(3, adr); |
|
| 677 |
+ return MMU_aluMemAccessCycles<PROCNUM, 8, MMU_AD_READ>(3, adr); |
|
| 680 | 678 |
} |
| 681 | 679 |
|
| 682 | 680 |
//----------------------------------------------------------------------------- |
| 683 | 681 |
// LDRSB |
| 684 | 682 |
//----------------------------------------------------------------------------- |
| 685 | 683 |
|
| 686 |
-TEMPLATE static uint32_t FASTCALL OP_LDRSB_REG_OFF(const uint32_t i) |
|
| 684 |
+TEMPLATE static uint32_t FASTCALL OP_LDRSB_REG_OFF(uint32_t i) |
|
| 687 | 685 |
{
|
| 688 | 686 |
uint32_t adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; |
| 689 |
- cpu->R[REG_NUM(i, 0)] = (uint32_t)((int8_t)READ8(cpu->mem_if->data, adr)); |
|
| 687 |
+ cpu->R[REG_NUM(i, 0)] = static_cast<uint32_t>(static_cast<int8_t>(READ8(cpu->mem_if->data, adr))); |
|
| 690 | 688 |
|
| 691 |
- return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_READ>(3, adr); |
|
| 689 |
+ return MMU_aluMemAccessCycles<PROCNUM, 8, MMU_AD_READ>(3, adr); |
|
| 692 | 690 |
} |
| 693 | 691 |
|
| 694 | 692 |
//----------------------------------------------------------------------------- |
| 695 | 693 |
// STRH / LDRH |
| 696 | 694 |
//----------------------------------------------------------------------------- |
| 697 | 695 |
|
| 698 |
-TEMPLATE static uint32_t FASTCALL OP_STRH_IMM_OFF(const uint32_t i) |
|
| 696 |
+TEMPLATE static uint32_t FASTCALL OP_STRH_IMM_OFF(uint32_t i) |
|
| 699 | 697 |
{
|
| 700 |
- uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E); |
|
| 701 |
- WRITE16(cpu->mem_if->data, adr, (uint16_t)cpu->R[REG_NUM(i, 0)]); |
|
| 698 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i >> 5) & 0x3E); |
|
| 699 |
+ WRITE16(cpu->mem_if->data, adr, static_cast<uint16_t>(cpu->R[REG_NUM(i, 0)])); |
|
| 702 | 700 |
|
| 703 |
- return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_WRITE>(2, adr); |
|
| 701 |
+ return MMU_aluMemAccessCycles<PROCNUM, 16, MMU_AD_WRITE>(2, adr); |
|
| 704 | 702 |
} |
| 705 | 703 |
|
| 706 |
-TEMPLATE static uint32_t FASTCALL OP_LDRH_IMM_OFF(const uint32_t i) |
|
| 704 |
+TEMPLATE static uint32_t FASTCALL OP_LDRH_IMM_OFF(uint32_t i) |
|
| 707 | 705 |
{
|
| 708 |
- uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E); |
|
| 709 |
- cpu->R[REG_NUM(i, 0)] = (uint32_t)READ16(cpu->mem_if->data, adr); |
|
| 706 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i >> 5) & 0x3E); |
|
| 707 |
+ cpu->R[REG_NUM(i, 0)] = static_cast<uint32_t>(READ16(cpu->mem_if->data, adr)); |
|
| 710 | 708 |
|
| 711 |
- return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_READ>(3, adr); |
|
| 709 |
+ return MMU_aluMemAccessCycles<PROCNUM, 16, MMU_AD_READ>(3, adr); |
|
| 712 | 710 |
} |
| 713 | 711 |
|
| 714 |
- |
|
| 715 |
-TEMPLATE static uint32_t FASTCALL OP_STRH_REG_OFF(const uint32_t i) |
|
| 712 |
+TEMPLATE static uint32_t FASTCALL OP_STRH_REG_OFF(uint32_t i) |
|
| 716 | 713 |
{
|
| 717 | 714 |
uint32_t adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; |
| 718 |
- WRITE16(cpu->mem_if->data, adr, ((uint16_t)cpu->R[REG_NUM(i, 0)])); |
|
| 715 |
+ WRITE16(cpu->mem_if->data, adr, static_cast<uint16_t>(cpu->R[REG_NUM(i, 0)])); |
|
| 719 | 716 |
|
| 720 |
- return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_WRITE>(2, adr); |
|
| 717 |
+ return MMU_aluMemAccessCycles<PROCNUM, 16, MMU_AD_WRITE>(2, adr); |
|
| 721 | 718 |
} |
| 722 | 719 |
|
| 723 |
-TEMPLATE static uint32_t FASTCALL OP_LDRH_REG_OFF(const uint32_t i) |
|
| 720 |
+TEMPLATE static uint32_t FASTCALL OP_LDRH_REG_OFF(uint32_t i) |
|
| 724 | 721 |
{
|
| 725 | 722 |
uint32_t adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; |
| 726 |
- cpu->R[REG_NUM(i, 0)] = (uint32_t)READ16(cpu->mem_if->data, adr); |
|
| 723 |
+ cpu->R[REG_NUM(i, 0)] = static_cast<uint32_t>(READ16(cpu->mem_if->data, adr)); |
|
| 727 | 724 |
|
| 728 |
- return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_READ>(3, adr); |
|
| 725 |
+ return MMU_aluMemAccessCycles<PROCNUM, 16, MMU_AD_READ>(3, adr); |
|
| 729 | 726 |
} |
| 730 | 727 |
|
| 731 | 728 |
//----------------------------------------------------------------------------- |
| 732 | 729 |
// LDRSH |
| 733 | 730 |
//----------------------------------------------------------------------------- |
| 734 | 731 |
|
| 735 |
-TEMPLATE static uint32_t FASTCALL OP_LDRSH_REG_OFF(const uint32_t i) |
|
| 732 |
+TEMPLATE static uint32_t FASTCALL OP_LDRSH_REG_OFF(uint32_t i) |
|
| 736 | 733 |
{
|
| 737 | 734 |
uint32_t adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; |
| 738 |
- cpu->R[REG_NUM(i, 0)] = (uint32_t)((int16_t)READ16(cpu->mem_if->data, adr)); |
|
| 735 |
+ cpu->R[REG_NUM(i, 0)] = static_cast<uint32_t>(static_cast<int16_t>(READ16(cpu->mem_if->data, adr))); |
|
| 739 | 736 |
|
| 740 |
- return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_READ>(3, adr); |
|
| 737 |
+ return MMU_aluMemAccessCycles<PROCNUM, 16, MMU_AD_READ>(3, adr); |
|
| 741 | 738 |
} |
| 742 | 739 |
|
| 743 | 740 |
//----------------------------------------------------------------------------- |
| 744 | 741 |
// STR / LDR |
| 745 | 742 |
//----------------------------------------------------------------------------- |
| 746 | 743 |
|
| 747 |
-TEMPLATE static uint32_t FASTCALL OP_STR_IMM_OFF(const uint32_t i) |
|
| 744 |
+TEMPLATE static uint32_t FASTCALL OP_STR_IMM_OFF(uint32_t i) |
|
| 748 | 745 |
{
|
| 749 |
- uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C); |
|
| 746 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i >> 4) & 0x7C); |
|
| 750 | 747 |
WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]); |
| 751 | 748 |
|
| 752 |
- return MMU_aluMemAccessCycles<PROCNUM,32,MMU_AD_WRITE>(2, adr); |
|
| 749 |
+ return MMU_aluMemAccessCycles<PROCNUM, 32, MMU_AD_WRITE>(2, adr); |
|
| 753 | 750 |
} |
| 754 | 751 |
|
| 755 |
-TEMPLATE static uint32_t FASTCALL OP_LDR_IMM_OFF(const uint32_t i) |
|
| 752 |
+TEMPLATE static uint32_t FASTCALL OP_LDR_IMM_OFF(uint32_t i) |
|
| 756 | 753 |
{
|
| 757 |
- uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C); |
|
| 754 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i >> 4) & 0x7C); |
|
| 758 | 755 |
uint32_t tempValue = READ32(cpu->mem_if->data, adr); |
| 759 |
- adr = (adr&3)*8; |
|
| 760 |
- tempValue = (tempValue>>adr) | (tempValue<<(32-adr)); |
|
| 756 |
+ adr = (adr & 3) * 8; |
|
| 757 |
+ tempValue = (tempValue >> adr) | (tempValue << (32 - adr)); |
|
| 761 | 758 |
cpu->R[REG_NUM(i, 0)] = tempValue; |
| 762 | 759 |
|
| 763 |
- return MMU_aluMemAccessCycles<PROCNUM,32,MMU_AD_READ>(3, adr); |
|
| 760 |
+ return MMU_aluMemAccessCycles<PROCNUM, 32, MMU_AD_READ>(3, adr); |
|
| 764 | 761 |
} |
| 765 | 762 |
|
| 766 |
- |
|
| 767 |
-TEMPLATE static uint32_t FASTCALL OP_STR_REG_OFF(const uint32_t i) |
|
| 763 |
+TEMPLATE static uint32_t FASTCALL OP_STR_REG_OFF(uint32_t i) |
|
| 768 | 764 |
{
|
| 769 | 765 |
uint32_t adr = cpu->R[REG_NUM(i, 6)] + cpu->R[REG_NUM(i, 3)]; |
| 770 | 766 |
WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]); |
| 771 | 767 |
|
| 772 |
- return MMU_aluMemAccessCycles<PROCNUM,32,MMU_AD_WRITE>(2, adr); |
|
| 768 |
+ return MMU_aluMemAccessCycles<PROCNUM, 32, MMU_AD_WRITE>(2, adr); |
|
| 773 | 769 |
} |
| 774 | 770 |
|
| 775 |
-TEMPLATE static uint32_t FASTCALL OP_LDR_REG_OFF(const uint32_t i) |
|
| 771 |
+TEMPLATE static uint32_t FASTCALL OP_LDR_REG_OFF(uint32_t i) |
|
| 776 | 772 |
{
|
| 777 |
- uint32_t adr = (cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]); |
|
| 773 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; |
|
| 778 | 774 |
uint32_t tempValue = READ32(cpu->mem_if->data, adr); |
| 779 |
- adr = (adr&3)*8; |
|
| 780 |
- tempValue = (tempValue>>adr) | (tempValue<<(32-adr)); |
|
| 775 |
+ adr = (adr & 3) * 8; |
|
| 776 |
+ tempValue = (tempValue >> adr) | (tempValue << (32 - adr)); |
|
| 781 | 777 |
cpu->R[REG_NUM(i, 0)] = tempValue; |
| 782 | 778 |
|
| 783 |
- return MMU_aluMemAccessCycles<PROCNUM,32,MMU_AD_READ>(3, adr); |
|
| 779 |
+ return MMU_aluMemAccessCycles<PROCNUM, 32, MMU_AD_READ>(3, adr); |
|
| 784 | 780 |
} |
| 785 | 781 |
|
| 786 |
-TEMPLATE static uint32_t FASTCALL OP_STR_SPREL(const uint32_t i) |
|
| 782 |
+TEMPLATE static uint32_t FASTCALL OP_STR_SPREL(uint32_t i) |
|
| 787 | 783 |
{
|
| 788 |
- uint32_t adr = cpu->R[13] + ((i&0xFF)<<2); |
|
| 784 |
+ uint32_t adr = cpu->R[13] + ((i & 0xFF) << 2); |
|
| 789 | 785 |
WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 8)]); |
| 790 | 786 |
|
| 791 |
- return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_WRITE>(2, adr); |
|
| 787 |
+ return MMU_aluMemAccessCycles<PROCNUM, 32, MMU_AD_WRITE>(2, adr); |
|
| 792 | 788 |
} |
| 793 | 789 |
|
| 794 |
-TEMPLATE static uint32_t FASTCALL OP_LDR_SPREL(const uint32_t i) |
|
| 790 |
+TEMPLATE static uint32_t FASTCALL OP_LDR_SPREL(uint32_t i) |
|
| 795 | 791 |
{
|
| 796 |
- uint32_t adr = cpu->R[13] + ((i&0xFF)<<2); |
|
| 792 |
+ uint32_t adr = cpu->R[13] + ((i & 0xFF) << 2); |
|
| 797 | 793 |
cpu->R[REG_NUM(i, 8)] = READ32(cpu->mem_if->data, adr); |
| 798 | 794 |
|
| 799 |
- return MMU_aluMemAccessCycles<PROCNUM,32,MMU_AD_READ>(3, adr); |
|
| 795 |
+ return MMU_aluMemAccessCycles<PROCNUM, 32, MMU_AD_READ>(3, adr); |
|
| 800 | 796 |
} |
| 801 | 797 |
|
| 802 |
-TEMPLATE static uint32_t FASTCALL OP_LDR_PCREL(const uint32_t i) |
|
| 798 |
+TEMPLATE static uint32_t FASTCALL OP_LDR_PCREL(uint32_t i) |
|
| 803 | 799 |
{
|
| 804 |
- uint32_t adr = (cpu->R[15]&0xFFFFFFFC) + ((i&0xFF)<<2); |
|
| 800 |
+ uint32_t adr = (cpu->R[15] & 0xFFFFFFFC) + ((i & 0xFF) << 2); |
|
| 805 | 801 |
|
| 806 | 802 |
cpu->R[REG_NUM(i, 8)] = READ32(cpu->mem_if->data, adr); |
| 807 | 803 |
|
| 808 |
- return MMU_aluMemAccessCycles<PROCNUM,32,MMU_AD_READ>(3, adr); |
|
| 804 |
+ return MMU_aluMemAccessCycles<PROCNUM, 32, MMU_AD_READ>(3, adr); |
|
| 809 | 805 |
} |
| 810 | 806 |
|
| 811 | 807 |
//----------------------------------------------------------------------------- |
| 812 | 808 |
// Adjust SP |
| 813 | 809 |
//----------------------------------------------------------------------------- |
| 814 | 810 |
|
| 815 |
-TEMPLATE static uint32_t FASTCALL OP_ADJUST_P_SP(const uint32_t i) |
|
| 811 |
+TEMPLATE static uint32_t FASTCALL OP_ADJUST_P_SP(uint32_t i) |
|
| 816 | 812 |
{
|
| 817 |
- cpu->R[13] += ((i&0x7F)<<2); |
|
| 813 |
+ cpu->R[13] += (i & 0x7F) << 2; |
|
| 818 | 814 |
|
| 819 | 815 |
return 1; |
| 820 | 816 |
} |
| 821 | 817 |
|
| 822 |
-TEMPLATE static uint32_t FASTCALL OP_ADJUST_M_SP(const uint32_t i) |
|
| 818 |
+TEMPLATE static uint32_t FASTCALL OP_ADJUST_M_SP(uint32_t i) |
|
| 823 | 819 |
{
|
| 824 |
- cpu->R[13] -= ((i&0x7F)<<2); |
|
| 820 |
+ cpu->R[13] -= (i & 0x7F) << 2; |
|
| 825 | 821 |
|
| 826 | 822 |
return 1; |
| 827 | 823 |
} |
| ... | ... |
@@ -830,59 +826,59 @@ TEMPLATE static uint32_t FASTCALL OP_ADJUST_M_SP(const uint32_t i) |
| 830 | 826 |
// PUSH / POP |
| 831 | 827 |
//----------------------------------------------------------------------------- |
| 832 | 828 |
|
| 833 |
-TEMPLATE static uint32_t FASTCALL OP_PUSH(const uint32_t i) |
|
| 829 |
+TEMPLATE static uint32_t FASTCALL OP_PUSH(uint32_t i) |
|
| 834 | 830 |
{
|
| 835 | 831 |
uint32_t adr = cpu->R[13] - 4; |
| 836 |
- uint32_t c = 0, j; |
|
| 832 |
+ uint32_t c = 0; |
|
| 837 | 833 |
|
| 838 |
- for(j = 0; j<8; j++) |
|
| 839 |
- if(BIT_N(i, 7-j)) |
|
| 834 |
+ for (uint32_t j = 0; j < 8; ++j) |
|
| 835 |
+ if (BIT_N(i, 7 - j)) |
|
| 840 | 836 |
{
|
| 841 |
- WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]); |
|
| 842 |
- c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_WRITE>(adr); |
|
| 837 |
+ WRITE32(cpu->mem_if->data, adr, cpu->R[7 - j]); |
|
| 838 |
+ c += MMU_memAccessCycles<PROCNUM, 32, MMU_AD_WRITE>(adr); |
|
| 843 | 839 |
adr -= 4; |
| 844 | 840 |
} |
| 845 | 841 |
cpu->R[13] = adr + 4; |
| 846 | 842 |
|
| 847 |
- return MMU_aluMemCycles<PROCNUM>(3, c); |
|
| 843 |
+ return MMU_aluMemCycles<PROCNUM>(3, c); |
|
| 848 | 844 |
} |
| 849 | 845 |
|
| 850 |
-TEMPLATE static uint32_t FASTCALL OP_PUSH_LR(const uint32_t i) |
|
| 846 |
+TEMPLATE static uint32_t FASTCALL OP_PUSH_LR(uint32_t i) |
|
| 851 | 847 |
{
|
| 852 | 848 |
uint32_t adr = cpu->R[13] - 4; |
| 853 |
- uint32_t c = 0, j; |
|
| 849 |
+ uint32_t c = 0; |
|
| 854 | 850 |
|
| 855 | 851 |
WRITE32(cpu->mem_if->data, adr, cpu->R[14]); |
| 856 | 852 |
c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_WRITE>(adr); |
| 857 | 853 |
adr -= 4; |
| 858 | 854 |
|
| 859 |
- for(j = 0; j<8; j++) |
|
| 860 |
- if(BIT_N(i, 7-j)) |
|
| 855 |
+ for (uint32_t j = 0; j < 8; ++j) |
|
| 856 |
+ if (BIT_N(i, 7 - j)) |
|
| 861 | 857 |
{
|
| 862 |
- WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]); |
|
| 863 |
- c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_WRITE>(adr); |
|
| 858 |
+ WRITE32(cpu->mem_if->data, adr, cpu->R[7 - j]); |
|
| 859 |
+ c += MMU_memAccessCycles<PROCNUM, 32, MMU_AD_WRITE>(adr); |
|
| 864 | 860 |
adr -= 4; |
| 865 | 861 |
} |
| 866 | 862 |
cpu->R[13] = adr + 4; |
| 867 | 863 |
|
| 868 |
- return MMU_aluMemCycles<PROCNUM>(4, c); |
|
| 864 |
+ return MMU_aluMemCycles<PROCNUM>(4, c); |
|
| 869 | 865 |
} |
| 870 | 866 |
|
| 871 |
-TEMPLATE static uint32_t FASTCALL OP_POP(const uint32_t i) |
|
| 867 |
+TEMPLATE static uint32_t FASTCALL OP_POP(uint32_t i) |
|
| 872 | 868 |
{
|
| 873 | 869 |
uint32_t adr = cpu->R[13]; |
| 874 |
- uint32_t c = 0, j; |
|
| 870 |
+ uint32_t c = 0; |
|
| 875 | 871 |
|
| 876 |
- for(j = 0; j<8; j++) |
|
| 877 |
- if(BIT_N(i, j)) |
|
| 872 |
+ for (uint32_t j = 0; j < 8; ++j) |
|
| 873 |
+ if (BIT_N(i, j)) |
|
| 878 | 874 |
{
|
| 879 | 875 |
cpu->R[j] = READ32(cpu->mem_if->data, adr); |
| 880 |
- c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_READ>(adr); |
|
| 876 |
+ c += MMU_memAccessCycles<PROCNUM, 32, MMU_AD_READ>(adr); |
|
| 881 | 877 |
adr += 4; |
| 882 | 878 |
} |
| 883 | 879 |
cpu->R[13] = adr; |
| 884 | 880 |
|
| 885 |
- return MMU_aluMemCycles<PROCNUM>(2, c); |
|
| 881 |
+ return MMU_aluMemCycles<PROCNUM>(2, c); |
|
| 886 | 882 |
} |
| 887 | 883 |
|
| 888 | 884 |
// In ARMv5 and above, bit[0] of the loaded value |
| ... | ... |
@@ -892,41 +888,40 @@ TEMPLATE static uint32_t FASTCALL OP_POP(const uint32_t i) |
| 892 | 888 |
// In T variants of ARMv4, bit[0] of the loaded value is ignored and execution continues in Thumb state, as |
| 893 | 889 |
// though the following instruction had been executed: |
| 894 | 890 |
// MOV PC,(loaded_value) |
| 895 |
-TEMPLATE static uint32_t FASTCALL OP_POP_PC(const uint32_t i) |
|
| 891 |
+TEMPLATE static uint32_t FASTCALL OP_POP_PC(uint32_t i) |
|
| 896 | 892 |
{
|
| 897 | 893 |
uint32_t adr = cpu->R[13]; |
| 898 |
- uint32_t c = 0, j; |
|
| 899 |
- uint32_t v = 0; |
|
| 894 |
+ uint32_t c = 0; |
|
| 900 | 895 |
|
| 901 |
- for(j = 0; j<8; j++) |
|
| 902 |
- if(BIT_N(i, j)) |
|
| 896 |
+ for (uint32_t j = 0; j < 8; ++j) |
|
| 897 |
+ if (BIT_N(i, j)) |
|
| 903 | 898 |
{
|
| 904 | 899 |
cpu->R[j] = READ32(cpu->mem_if->data, adr); |
| 905 |
- c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_READ>(adr); |
|
| 900 |
+ c += MMU_memAccessCycles<PROCNUM, 32, MMU_AD_READ>(adr); |
|
| 906 | 901 |
adr += 4; |
| 907 | 902 |
} |
| 908 | 903 |
|
| 909 |
- v = READ32(cpu->mem_if->data, adr); |
|
| 910 |
- c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_READ>(adr); |
|
| 911 |
- if(cpu->LDTBit) |
|
| 904 |
+ uint32_t v = READ32(cpu->mem_if->data, adr); |
|
| 905 |
+ c += MMU_memAccessCycles<PROCNUM, 32, MMU_AD_READ>(adr); |
|
| 906 |
+ if (!PROCNUM) |
|
| 912 | 907 |
cpu->CPSR.bits.T = BIT0(v); |
| 913 | 908 |
|
| 914 | 909 |
cpu->R[15] = v & 0xFFFFFFFE; |
| 915 | 910 |
cpu->next_instruction = cpu->R[15]; |
| 916 | 911 |
|
| 917 | 912 |
cpu->R[13] = adr + 4; |
| 918 |
- return MMU_aluMemCycles<PROCNUM>(5, c); |
|
| 913 |
+ return MMU_aluMemCycles<PROCNUM>(5, c); |
|
| 919 | 914 |
} |
| 920 | 915 |
|
| 921 | 916 |
//----------------------------------------------------------------------------- |
| 922 | 917 |
// STMIA / LDMIA |
| 923 | 918 |
//----------------------------------------------------------------------------- |
| 924 | 919 |
|
| 925 |
-TEMPLATE static uint32_t FASTCALL OP_STMIA_THUMB(const uint32_t i) |
|
| 920 |
+TEMPLATE static uint32_t FASTCALL OP_STMIA_THUMB(uint32_t i) |
|
| 926 | 921 |
{
|
| 927 | 922 |
uint32_t adr = cpu->R[REG_NUM(i, 8)]; |
| 928 |
- uint32_t c = 0, j; |
|
| 929 |
- uint32_t erList = 1; //Empty Register List |
|
| 923 |
+ uint32_t c = 0; |
|
| 924 |
+ bool erList = true; //Empty Register List |
|
| 930 | 925 |
|
| 931 | 926 |
// ------ ARM_REF: |
| 932 | 927 |
// ------ If <Rn> is specified in <registers>: |
| ... | ... |
@@ -935,16 +930,14 @@ TEMPLATE static uint32_t FASTCALL OP_STMIA_THUMB(const uint32_t i) |
| 935 | 930 |
if (BIT_N(i, REG_NUM(i, 8))) |
| 936 | 931 |
printf("STMIA with Rb in Rlist\n");
|
| 937 | 932 |
|
| 938 |
- for(j = 0; j<8; j++) |
|
| 939 |
- {
|
|
| 940 |
- if(BIT_N(i, j)) |
|
| 933 |
+ for (uint32_t j = 0; j < 8; ++j) |
|
| 934 |
+ if (BIT_N(i, j)) |
|
| 941 | 935 |
{
|
| 942 | 936 |
WRITE32(cpu->mem_if->data, adr, cpu->R[j]); |
| 943 |
- c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_WRITE>(adr); |
|
| 937 |
+ c += MMU_memAccessCycles<PROCNUM, 32, MMU_AD_WRITE>(adr); |
|
| 944 | 938 |
adr += 4; |
| 945 |
- erList = 0; //Register List isnt empty |
|
| 939 |
+ erList = false; //Register List isnt empty |
|
| 946 | 940 |
} |
| 947 |
- } |
|
| 948 | 941 |
|
| 949 | 942 |
if (erList) |
| 950 | 943 |
printf("STMIA with Empty Rlist\n");
|
| ... | ... |
@@ -953,26 +946,24 @@ TEMPLATE static uint32_t FASTCALL OP_STMIA_THUMB(const uint32_t i) |
| 953 | 946 |
return MMU_aluMemCycles<PROCNUM>(2, c); |
| 954 | 947 |
} |
| 955 | 948 |
|
| 956 |
-TEMPLATE static uint32_t FASTCALL OP_LDMIA_THUMB(const uint32_t i) |
|
| 949 |
+TEMPLATE static uint32_t FASTCALL OP_LDMIA_THUMB(uint32_t i) |
|
| 957 | 950 |
{
|
| 958 | 951 |
uint32_t regIndex = REG_NUM(i, 8); |
| 959 | 952 |
uint32_t adr = cpu->R[regIndex]; |
| 960 |
- uint32_t c = 0, j; |
|
| 961 |
- uint32_t erList = 1; //Empty Register List |
|
| 953 |
+ uint32_t c = 0; |
|
| 954 |
+ bool erList = true; //Empty Register List |
|
| 962 | 955 |
|
| 963 | 956 |
//if (BIT_N(i, regIndex)) |
| 964 | 957 |
// printf("LDMIA with Rb in Rlist at %08X\n",cpu->instruct_adr);
|
| 965 | 958 |
|
| 966 |
- for(j = 0; j<8; j++) |
|
| 967 |
- {
|
|
| 968 |
- if(BIT_N(i, j)) |
|
| 959 |
+ for (uint32_t j = 0; j < 8; ++j) |
|
| 960 |
+ if (BIT_N(i, j)) |
|
| 969 | 961 |
{
|
| 970 | 962 |
cpu->R[j] = READ32(cpu->mem_if->data, adr); |
| 971 |
- c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_READ>(adr); |
|
| 963 |
+ c += MMU_memAccessCycles<PROCNUM, 32, MMU_AD_READ>(adr); |
|
| 972 | 964 |
adr += 4; |
| 973 |
- erList = 0; //Register List isnt empty |
|
| 965 |
+ erList = false; //Register List isnt empty |
|
| 974 | 966 |
} |
| 975 |
- } |
|
| 976 | 967 |
|
| 977 | 968 |
if (erList) |
| 978 | 969 |
printf("LDMIA with Empty Rlist\n");
|
| ... | ... |
@@ -990,10 +981,18 @@ TEMPLATE static uint32_t FASTCALL OP_LDMIA_THUMB(const uint32_t i) |
| 990 | 981 |
// BKPT |
| 991 | 982 |
//----------------------------------------------------------------------------- |
| 992 | 983 |
|
| 993 |
-TEMPLATE static uint32_t FASTCALL OP_BKPT_THUMB(const uint32_t) |
|
| 984 |
+TEMPLATE static uint32_t FASTCALL OP_BKPT_THUMB(uint32_t) |
|
| 994 | 985 |
{
|
| 995 |
- // TODO |
|
| 996 |
- printf("THUMB%c: Unimplemented opcode BKPT\n", PROCNUM?'7':'9');
|
|
| 986 |
+ printf("THUMB%c: OP_BKPT triggered\n", PROCNUM?'7':'9');
|
|
| 987 |
+ Status_Reg tmp = cpu->CPSR; |
|
| 988 |
+ armcpu_switchMode(cpu, ABT); // enter abt mode |
|
| 989 |
+ cpu->R[14] = cpu->instruct_adr + 4; |
|
| 990 |
+ cpu->SPSR = tmp; // save old CPSR as new SPSR |
|
| 991 |
+ cpu->CPSR.bits.T = 0; // handle as ARM32 code |
|
| 992 |
+ cpu->CPSR.bits.I = 1; |
|
| 993 |
+ cpu->changeCPSR(); |
|
| 994 |
+ cpu->R[15] = cpu->intVector + 0x0C; |
|
| 995 |
+ cpu->next_instruction = cpu->R[15]; |
|
| 997 | 996 |
return 1; |
| 998 | 997 |
} |
| 999 | 998 |
|
| ... | ... |
@@ -1001,12 +1000,13 @@ TEMPLATE static uint32_t FASTCALL OP_BKPT_THUMB(const uint32_t) |
| 1001 | 1000 |
// SWI |
| 1002 | 1001 |
//----------------------------------------------------------------------------- |
| 1003 | 1002 |
|
| 1004 |
-TEMPLATE static uint32_t FASTCALL OP_SWI_THUMB(const uint32_t i) |
|
| 1003 |
+TEMPLATE static uint32_t FASTCALL OP_SWI_THUMB(uint32_t i) |
|
| 1005 | 1004 |
{
|
| 1006 | 1005 |
uint32_t swinum = i & 0xFF; |
| 1007 | 1006 |
|
| 1008 | 1007 |
//ideas-style debug prints (execute this SWI with the null terminated string address in R0) |
| 1009 |
- if(swinum==0xFC) {
|
|
| 1008 |
+ if (swinum == 0xFC) |
|
| 1009 |
+ {
|
|
| 1010 | 1010 |
//IdeasLog(cpu); |
| 1011 | 1011 |
return 0; |
| 1012 | 1012 |
} |
| ... | ... |
@@ -1014,32 +1014,32 @@ TEMPLATE static uint32_t FASTCALL OP_SWI_THUMB(const uint32_t i) |
| 1014 | 1014 |
//if the user has changed the intVector to point away from the nds bioses, |
| 1015 | 1015 |
//then it doesn't really make any sense to use the builtin SWI's since |
| 1016 | 1016 |
//the bios ones aren't getting called anyway |
| 1017 |
- bool bypassBuiltinSWI = |
|
| 1018 |
- (cpu->intVector == 0x00000000 && PROCNUM==0) |
|
| 1019 |
- || (cpu->intVector == 0xFFFF0000 && PROCNUM==1); |
|
| 1020 |
- |
|
| 1021 |
- if(cpu->swi_tab && !bypassBuiltinSWI) {
|
|
| 1022 |
- //zero 25-dec-2008 - in arm, we were masking to 0x1F. |
|
| 1023 |
- //this is probably safer since an invalid opcode could crash the emu |
|
| 1024 |
- //zero 30-jun-2009 - but they say that the ideas 0xFF should crash the device... |
|
| 1025 |
- //uint32_t swinum = cpu->instruction & 0xFF; |
|
| 1017 |
+ bool bypassBuiltinSWI = (cpu->intVector == 0x00000000 && !PROCNUM) || (cpu->intVector == 0xFFFF0000 && PROCNUM == 1); |
|
| 1018 |
+ |
|
| 1019 |
+ if (cpu->swi_tab && !bypassBuiltinSWI) |
|
| 1020 |
+ {
|
|
| 1021 |
+ //zero 25-dec-2008 - in arm, we were masking to 0x1F. |
|
| 1022 |
+ //this is probably safer since an invalid opcode could crash the emu |
|
| 1023 |
+ //zero 30-jun-2009 - but they say that the ideas 0xFF should crash the device... |
|
| 1024 |
+ //uint32_t swinum = cpu->instruction & 0xFF; |
|
| 1026 | 1025 |
swinum &= 0x1F; |
| 1027 | 1026 |
//printf("%d ARM SWI %d\n",PROCNUM,swinum);
|
| 1028 |
- return cpu->swi_tab[swinum]() + 3; |
|
| 1027 |
+ return cpu->swi_tab[swinum]() + 3; |
|
| 1029 | 1028 |
} |
| 1030 |
- else {
|
|
| 1031 |
- /* we use an irq thats not in the irq tab, as |
|
| 1032 |
- it was replaced due to a changed intVector */ |
|
| 1033 |
- Status_Reg tmp = cpu->CPSR; |
|
| 1034 |
- armcpu_switchMode(cpu, SVC); /* enter svc mode */ |
|
| 1035 |
- cpu->R[14] = cpu->next_instruction; /* jump to swi Vector */ |
|
| 1036 |
- cpu->SPSR = tmp; /* save old CPSR as new SPSR */ |
|
| 1037 |
- cpu->CPSR.bits.T = 0; /* handle as ARM32 code */ |
|
| 1038 |
- cpu->CPSR.bits.I = 1; |
|
| 1039 |
- cpu->changeCPSR(); |
|
| 1040 |
- cpu->R[15] = cpu->intVector + 0x08; |
|
| 1041 |
- cpu->next_instruction = cpu->R[15]; |
|
| 1042 |
- return 3; |
|
| 1029 |
+ else |
|
| 1030 |
+ {
|
|
| 1031 |
+ /* we use an irq thats not in the irq tab, as |
|
| 1032 |
+ it was replaced due to a changed intVector */ |
|
| 1033 |
+ Status_Reg tmp = cpu->CPSR; |
|
| 1034 |
+ armcpu_switchMode(cpu, SVC); /* enter svc mode */ |
|
| 1035 |
+ cpu->R[14] = cpu->next_instruction; /* jump to swi Vector */ |
|
| 1036 |
+ cpu->SPSR = tmp; /* save old CPSR as new SPSR */ |
|
| 1037 |
+ cpu->CPSR.bits.T = 0; /* handle as ARM32 code */ |
|
| 1038 |
+ cpu->CPSR.bits.I = 1; |
|
| 1039 |
+ cpu->changeCPSR(); |
|
| 1040 |
+ cpu->R[15] = cpu->intVector + 0x08; |
|
| 1041 |
+ cpu->next_instruction = cpu->R[15]; |
|
| 1042 |
+ return 3; |
|
| 1043 | 1043 |
} |
| 1044 | 1044 |
} |
| 1045 | 1045 |
|
| ... | ... |
@@ -1047,49 +1047,50 @@ TEMPLATE static uint32_t FASTCALL OP_SWI_THUMB(const uint32_t i) |
| 1047 | 1047 |
// Branch |
| 1048 | 1048 |
//----------------------------------------------------------------------------- |
| 1049 | 1049 |
|
| 1050 |
-#define SIGNEEXT_IMM11(i) (((i)&0x7FF) | (BIT10(i) * 0xFFFFF800)) |
|
| 1050 |
+static inline uint32_t SIGNEEXT_IMM11(uint32_t i) { return (i & 0x7FF) | (BIT10(i) * 0xFFFFF800); }
|
|
| 1051 |
+static inline uint32_t SIGNEXTEND_11(uint32_t i) { return static_cast<uint32_t>((static_cast<int32_t>(i) << 21) >> 21); }
|
|
| 1051 | 1052 |
|
| 1052 |
-TEMPLATE static uint32_t FASTCALL OP_B_COND(const uint32_t i) |
|
| 1053 |
+TEMPLATE static uint32_t FASTCALL OP_B_COND(uint32_t i) |
|
| 1053 | 1054 |
{
|
| 1054 |
- if(!TEST_COND((i>>8)&0xF, 0, cpu->CPSR)) |
|
| 1055 |
+ if (!TEST_COND((i >> 8) & 0xF, 0, cpu->CPSR)) |
|
| 1055 | 1056 |
return 1; |
| 1056 | 1057 |
|
| 1057 |
- cpu->R[15] += (uint32_t)((int8_t)(i&0xFF))<<1; |
|
| 1058 |
+ cpu->R[15] += static_cast<uint32_t>(static_cast<int8_t>(i & 0xFF)) << 1; |
|
| 1058 | 1059 |
cpu->next_instruction = cpu->R[15]; |
| 1059 | 1060 |
return 3; |
| 1060 | 1061 |
} |
| 1061 | 1062 |
|
| 1062 |
-TEMPLATE static uint32_t FASTCALL OP_B_UNCOND(const uint32_t i) |
|
| 1063 |
+TEMPLATE static uint32_t FASTCALL OP_B_UNCOND(uint32_t i) |
|
| 1063 | 1064 |
{
|
| 1064 |
- cpu->R[15] += (SIGNEEXT_IMM11(i)<<1); |
|
| 1065 |
+ cpu->R[15] += SIGNEEXT_IMM11(i) << 1; |
|
| 1065 | 1066 |
cpu->next_instruction = cpu->R[15]; |
| 1066 | 1067 |
return 1; |
| 1067 | 1068 |
} |
| 1068 | 1069 |
|
| 1069 |
-TEMPLATE static uint32_t FASTCALL OP_BLX(const uint32_t i) |
|
| 1070 |
+TEMPLATE static uint32_t FASTCALL OP_BLX(uint32_t i) |
|
| 1070 | 1071 |
{
|
| 1071 |
- cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1))&0xFFFFFFFC; |
|
| 1072 |
+ cpu->R[15] = (cpu->R[14] + ((i & 0x7FF) << 1)) & 0xFFFFFFFC; |
|
| 1072 | 1073 |
cpu->R[14] = cpu->next_instruction | 1; |
| 1073 | 1074 |
cpu->next_instruction = cpu->R[15]; |
| 1074 | 1075 |
cpu->CPSR.bits.T = 0; |
| 1075 | 1076 |
return 3; |
| 1076 | 1077 |
} |
| 1077 | 1078 |
|
| 1078 |
-TEMPLATE static uint32_t FASTCALL OP_BL_10(const uint32_t i) |
|
| 1079 |
+TEMPLATE static uint32_t FASTCALL OP_BL_10(uint32_t i) |
|
| 1079 | 1080 |
{
|
| 1080 |
- cpu->R[14] = cpu->R[15] + (SIGNEEXT_IMM11(i)<<12); |
|
| 1081 |
+ cpu->R[14] = cpu->R[15] + (SIGNEXTEND_11(i) << 12); |
|
| 1081 | 1082 |
return 1; |
| 1082 | 1083 |
} |
| 1083 | 1084 |
|
| 1084 |
-TEMPLATE static uint32_t FASTCALL OP_BL_11(const uint32_t i) |
|
| 1085 |
+TEMPLATE static uint32_t FASTCALL OP_BL_11(uint32_t i) |
|
| 1085 | 1086 |
{
|
| 1086 |
- cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1)); |
|
| 1087 |
+ cpu->R[15] = (cpu->R[14] + ((i & 0x7FF) << 1)); |
|
| 1087 | 1088 |
cpu->R[14] = cpu->next_instruction | 1; |
| 1088 | 1089 |
cpu->next_instruction = cpu->R[15]; |
| 1089 | 1090 |
return 4; |
| 1090 | 1091 |
} |
| 1091 | 1092 |
|
| 1092 |
-TEMPLATE static uint32_t FASTCALL OP_BX_THUMB(const uint32_t i) |
|
| 1093 |
+TEMPLATE static uint32_t FASTCALL OP_BX_THUMB(uint32_t i) |
|
| 1093 | 1094 |
{
|
| 1094 | 1095 |
// When using PC as operand with BX opcode, switch to ARM state and jump to (instruct_adr+4) |
| 1095 | 1096 |
// Reference: http://nocash.emubase.de/gbatek.htm#thumb5hiregisteroperationsbranchexchange |
| ... | ... |
@@ -1097,9 +1098,9 @@ TEMPLATE static uint32_t FASTCALL OP_BX_THUMB(const uint32_t i) |
| 1097 | 1098 |
#if 0 |
| 1098 | 1099 |
if (REG_POS(i, 3) == 15) |
| 1099 | 1100 |
{
|
| 1100 |
- cpu->CPSR.bits.T = 0; |
|
| 1101 |
- cpu->R[15] &= 0xFFFFFFFC; |
|
| 1102 |
- cpu->next_instruction = cpu->R[15]; |
|
| 1101 |
+ cpu->CPSR.bits.T = 0; |
|
| 1102 |
+ cpu->R[15] &= 0xFFFFFFFC; |
|
| 1103 |
+ cpu->next_instruction = cpu->R[15]; |
|
| 1103 | 1104 |
} |
| 1104 | 1105 |
else |
| 1105 | 1106 |
{
|
| ... | ... |
@@ -1123,18 +1124,16 @@ TEMPLATE static uint32_t FASTCALL OP_BX_THUMB(const uint32_t i) |
| 1123 | 1124 |
//emu_halt(); |
| 1124 | 1125 |
} |
| 1125 | 1126 |
cpu->CPSR.bits.T = BIT0(Rm); |
| 1126 |
- cpu->R[15] = (Rm & (0xFFFFFFFC|(1<<cpu->CPSR.bits.T))); |
|
| 1127 |
+ cpu->R[15] = Rm & (0xFFFFFFFC | (1 << cpu->CPSR.bits.T)); |
|
| 1127 | 1128 |
cpu->next_instruction = cpu->R[15]; |
| 1128 | 1129 |
#endif |
| 1129 | 1130 |
return 3; |
| 1130 | 1131 |
} |
| 1131 | 1132 |
|
| 1132 |
-TEMPLATE static uint32_t FASTCALL OP_BLX_THUMB(const uint32_t i) |
|
| 1133 |
+TEMPLATE static uint32_t FASTCALL OP_BLX_THUMB(uint32_t i) |
|
| 1133 | 1134 |
{
|
| 1134 | 1135 |
uint32_t Rm = cpu->R[REG_POS(i, 3)]; |
| 1135 |
- |
|
| 1136 | 1136 |
cpu->CPSR.bits.T = BIT0(Rm); |
| 1137 |
- //cpu->R[15] = (Rm & (0xFFFFFFFC|(1<<cpu->CPSR.bits.T))); |
|
| 1138 | 1137 |
cpu->R[15] = Rm & 0xFFFFFFFE; |
| 1139 | 1138 |
cpu->R[14] = cpu->next_instruction | 1; |
| 1140 | 1139 |
cpu->next_instruction = cpu->R[15]; |
| ... | ... |
@@ -1146,20 +1145,15 @@ TEMPLATE static uint32_t FASTCALL OP_BLX_THUMB(const uint32_t i) |
| 1146 | 1145 |
// The End |
| 1147 | 1146 |
//----------------------------------------------------------------------------- |
| 1148 | 1147 |
|
| 1148 |
+const OpFunc thumb_instructions_set[2][1024] = |
|
| 1149 |
+{
|
|
| 1150 |
+ {
|
|
| 1149 | 1151 |
#define TABDECL(x) x<0> |
| 1150 |
-const ThumbOpFunc thumb_instructions_set_0[1024] = {
|
|
| 1151 | 1152 |
#include "thumb_tabdef.inc" |
| 1152 |
-}; |
|
| 1153 | 1153 |
#undef TABDECL |
| 1154 |
- |
|
| 1154 |
+ }, {
|
|
| 1155 | 1155 |
#define TABDECL(x) x<1> |
| 1156 |
-const ThumbOpFunc thumb_instructions_set_1[1024] = {
|
|
| 1157 | 1156 |
#include "thumb_tabdef.inc" |
| 1158 |
-}; |
|
| 1159 | 1157 |
#undef TABDECL |
| 1160 |
- |
|
| 1161 |
-/*#define TABDECL(x) #x |
|
| 1162 |
-const char* thumb_instruction_names[1024] = {
|
|
| 1163 |
-#include "thumb_tabdef.inc" |
|
| 1158 |
+ } |
|
| 1164 | 1159 |
}; |
| 1165 |
-#undef TABDECL*/ |
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,1165 @@ |
| 1 |
+/* |
|
| 2 |
+ Copyright (C) 2006 yopyop |
|
| 3 |
+ Copyright (C) 2008 shash |
|
| 4 |
+ Copyright (C) 2008-2012 DeSmuME team |
|
| 5 |
+ |
|
| 6 |
+ This file 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 file 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 the this software. If not, see <http://www.gnu.org/licenses/>. |
|
| 18 |
+*/ |
|
| 19 |
+ |
|
| 20 |
+#include <cassert> |
|
| 21 |
+ |
|
| 22 |
+#include "bios.h" |
|
| 23 |
+//#include "debug.h" |
|
| 24 |
+#include "MMU.h" |
|
| 25 |
+#include "NDSSystem.h" |
|
| 26 |
+#include "thumb_instructions.h" |
|
| 27 |
+#include "MMU_timing.h" |
|
| 28 |
+ |
|
| 29 |
+#define cpu (&ARMPROC) |
|
| 30 |
+#define TEMPLATE template<int PROCNUM> |
|
| 31 |
+ |
|
| 32 |
+//#define REG_NUM(i, n) (((i)>>n)&0x7) |
|
| 33 |
+static inline uint32_t REG_NUM(uint32_t i, uint32_t n) { return (i >> n) & 0x7; }
|
|
| 34 |
+ |
|
| 35 |
+//----------------------------------------------------------------------------- |
|
| 36 |
+// Undefined instruction |
|
| 37 |
+//----------------------------------------------------------------------------- |
|
| 38 |
+TEMPLATE static uint32_t FASTCALL OP_UND_THUMB(const uint32_t) |
|
| 39 |
+{
|
|
| 40 |
+ //INFO("THUMB%c: Undefined instruction: 0x%08X (%s) PC=0x%08X\n", cpu->proc_ID?'7':'9', cpu->instruction, decodeIntruction(true, cpu->instruction), cpu->instruct_adr);
|
|
| 41 |
+ TRAPUNDEF(cpu); |
|
| 42 |
+ return 1; |
|
| 43 |
+} |
|
| 44 |
+ |
|
| 45 |
+//----------------------------------------------------------------------------- |
|
| 46 |
+// LSL |
|
| 47 |
+//----------------------------------------------------------------------------- |
|
| 48 |
+ |
|
| 49 |
+TEMPLATE static uint32_t FASTCALL OP_LSL_0(const uint32_t i) |
|
| 50 |
+{
|
|
| 51 |
+ cpu->R[REG_NUM(i, 0)] = cpu->R[REG_NUM(i, 3)]; |
|
| 52 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 53 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 54 |
+ |
|
| 55 |
+ return 1; |
|
| 56 |
+} |
|
| 57 |
+ |
|
| 58 |
+TEMPLATE static uint32_t FASTCALL OP_LSL(const uint32_t i) |
|
| 59 |
+{
|
|
| 60 |
+ uint32_t v = (i>>6) & 0x1F; |
|
| 61 |
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], 32-v); |
|
| 62 |
+ cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] << v); |
|
| 63 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 64 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 65 |
+ |
|
| 66 |
+ return 1; |
|
| 67 |
+} |
|
| 68 |
+ |
|
| 69 |
+TEMPLATE static uint32_t FASTCALL OP_LSL_REG(const uint32_t i) |
|
| 70 |
+{
|
|
| 71 |
+ uint32_t v = cpu->R[REG_NUM(i, 3)] & 0xFF; |
|
| 72 |
+ |
|
| 73 |
+ if(v == 0) |
|
| 74 |
+ {
|
|
| 75 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 76 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 77 |
+ return 2; |
|
| 78 |
+ } |
|
| 79 |
+ if(v<32) |
|
| 80 |
+ {
|
|
| 81 |
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], 32-v); |
|
| 82 |
+ cpu->R[REG_NUM(i, 0)] <<= v; |
|
| 83 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 84 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 85 |
+ return 2; |
|
| 86 |
+ } |
|
| 87 |
+ if(v==32) |
|
| 88 |
+ cpu->CPSR.bits.C = BIT0(cpu->R[REG_NUM(i, 0)]); |
|
| 89 |
+ else |
|
| 90 |
+ cpu->CPSR.bits.C = 0; |
|
| 91 |
+ |
|
| 92 |
+ cpu->R[REG_NUM(i, 0)] = 0; |
|
| 93 |
+ cpu->CPSR.bits.N = 0; |
|
| 94 |
+ cpu->CPSR.bits.Z = 1; |
|
| 95 |
+ |
|
| 96 |
+ return 2; |
|
| 97 |
+} |
|
| 98 |
+ |
|
| 99 |
+//----------------------------------------------------------------------------- |
|
| 100 |
+// LSR |
|
| 101 |
+//----------------------------------------------------------------------------- |
|
| 102 |
+ |
|
| 103 |
+TEMPLATE static uint32_t FASTCALL OP_LSR_0(const uint32_t i) |
|
| 104 |
+{
|
|
| 105 |
+ cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]); |
|
| 106 |
+ cpu->R[REG_NUM(i, 0)] = 0; |
|
| 107 |
+ cpu->CPSR.bits.N = 0; |
|
| 108 |
+ cpu->CPSR.bits.Z = 1; |
|
| 109 |
+ |
|
| 110 |
+ return 1; |
|
| 111 |
+} |
|
| 112 |
+ |
|
| 113 |
+TEMPLATE static uint32_t FASTCALL OP_LSR(const uint32_t i) |
|
| 114 |
+{
|
|
| 115 |
+ uint32_t v = (i>>6) & 0x1F; |
|
| 116 |
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], v-1); |
|
| 117 |
+ cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] >> v); |
|
| 118 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 119 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 120 |
+ |
|
| 121 |
+ return 1; |
|
| 122 |
+} |
|
| 123 |
+ |
|
| 124 |
+TEMPLATE static uint32_t FASTCALL OP_LSR_REG(const uint32_t i) |
|
| 125 |
+{
|
|
| 126 |
+ uint32_t v = cpu->R[REG_NUM(i, 3)] & 0xFF; |
|
| 127 |
+ |
|
| 128 |
+ if(v == 0) |
|
| 129 |
+ {
|
|
| 130 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 131 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 132 |
+ return 2; |
|
| 133 |
+ } |
|
| 134 |
+ if(v<32) |
|
| 135 |
+ {
|
|
| 136 |
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); |
|
| 137 |
+ cpu->R[REG_NUM(i, 0)] >>= v; |
|
| 138 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 139 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 140 |
+ return 2; |
|
| 141 |
+ } |
|
| 142 |
+ if(v==32) |
|
| 143 |
+ cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 144 |
+ else |
|
| 145 |
+ cpu->CPSR.bits.C = 0; |
|
| 146 |
+ cpu->R[REG_NUM(i, 0)] = 0; |
|
| 147 |
+ cpu->CPSR.bits.N = 0; |
|
| 148 |
+ cpu->CPSR.bits.Z = 1; |
|
| 149 |
+ |
|
| 150 |
+ return 2; |
|
| 151 |
+} |
|
| 152 |
+ |
|
| 153 |
+//----------------------------------------------------------------------------- |
|
| 154 |
+// ASR |
|
| 155 |
+//----------------------------------------------------------------------------- |
|
| 156 |
+ |
|
| 157 |
+TEMPLATE static uint32_t FASTCALL OP_ASR_0(const uint32_t i) |
|
| 158 |
+{
|
|
| 159 |
+ cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]); |
|
| 160 |
+ cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 3)])*0xFFFFFFFF; |
|
| 161 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 162 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 163 |
+ |
|
| 164 |
+ return 1; |
|
| 165 |
+} |
|
| 166 |
+ |
|
| 167 |
+TEMPLATE static uint32_t FASTCALL OP_ASR(const uint32_t i) |
|
| 168 |
+{
|
|
| 169 |
+ uint32_t v = (i>>6) & 0x1F; |
|
| 170 |
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], v-1); |
|
| 171 |
+ cpu->R[REG_NUM(i, 0)] = (uint32_t)(((int32_t)cpu->R[REG_NUM(i, 3)]) >> v); |
|
| 172 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 173 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 174 |
+ |
|
| 175 |
+ return 1; |
|
| 176 |
+} |
|
| 177 |
+ |
|
| 178 |
+TEMPLATE static uint32_t FASTCALL OP_ASR_REG(const uint32_t i) |
|
| 179 |
+{
|
|
| 180 |
+ uint32_t v = cpu->R[REG_NUM(i, 3)] & 0xFF; |
|
| 181 |
+ |
|
| 182 |
+ if(v == 0) |
|
| 183 |
+ {
|
|
| 184 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 185 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 186 |
+ return 2; |
|
| 187 |
+ } |
|
| 188 |
+ if(v<32) |
|
| 189 |
+ {
|
|
| 190 |
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); |
|
| 191 |
+ cpu->R[REG_NUM(i, 0)] = (uint32_t)(((int32_t)cpu->R[REG_NUM(i, 0)]) >> v); |
|
| 192 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 193 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 194 |
+ return 2; |
|
| 195 |
+ } |
|
| 196 |
+ |
|
| 197 |
+ cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 198 |
+ cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 0)])*0xFFFFFFFF; |
|
| 199 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 200 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 201 |
+ |
|
| 202 |
+ return 2; |
|
| 203 |
+} |
|
| 204 |
+ |
|
| 205 |
+//----------------------------------------------------------------------------- |
|
| 206 |
+// ADD |
|
| 207 |
+//----------------------------------------------------------------------------- |
|
| 208 |
+ |
|
| 209 |
+TEMPLATE static uint32_t FASTCALL OP_ADD_IMM3(const uint32_t i) |
|
| 210 |
+{
|
|
| 211 |
+ uint32_t imm3 = (i >> 6) & 0x07; |
|
| 212 |
+ uint32_t Rn = cpu->R[REG_NUM(i, 3)]; |
|
| 213 |
+ |
|
| 214 |
+ if (imm3 == 0) // mov 2 |
|
| 215 |
+ {
|
|
| 216 |
+ cpu->R[REG_NUM(i, 0)] = Rn; |
|
| 217 |
+ |
|
| 218 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 219 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 220 |
+ cpu->CPSR.bits.C = 0; |
|
| 221 |
+ cpu->CPSR.bits.V = 0; |
|
| 222 |
+ return 1; |
|
| 223 |
+ } |
|
| 224 |
+ |
|
| 225 |
+ cpu->R[REG_NUM(i, 0)] = Rn + imm3; |
|
| 226 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 227 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 228 |
+ cpu->CPSR.bits.C = CarryFrom(Rn, imm3); |
|
| 229 |
+ cpu->CPSR.bits.V = OverflowFromADD(cpu->R[REG_NUM(i, 0)], Rn, imm3); |
|
| 230 |
+ |
|
| 231 |
+ return 1; |
|
| 232 |
+} |
|
| 233 |
+ |
|
| 234 |
+TEMPLATE static uint32_t FASTCALL OP_ADD_IMM8(const uint32_t i) |
|
| 235 |
+{
|
|
| 236 |
+ uint32_t imm8 = (i & 0xFF); |
|
| 237 |
+ uint32_t Rd = cpu->R[REG_NUM(i, 8)]; |
|
| 238 |
+ |
|
| 239 |
+ cpu->R[REG_NUM(i, 8)] = Rd + imm8; |
|
| 240 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 8)]); |
|
| 241 |
+ cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 8)] == 0); |
|
| 242 |
+ cpu->CPSR.bits.C = CarryFrom(Rd, imm8); |
|
| 243 |
+ cpu->CPSR.bits.V = OverflowFromADD(cpu->R[REG_NUM(i, 8)], Rd, imm8); |
|
| 244 |
+ |
|
| 245 |
+ return 1; |
|
| 246 |
+} |
|
| 247 |
+ |
|
| 248 |
+TEMPLATE static uint32_t FASTCALL OP_ADD_REG(const uint32_t i) |
|
| 249 |
+{
|
|
| 250 |
+ uint32_t Rn = cpu->R[REG_NUM(i, 3)]; |
|
| 251 |
+ uint32_t Rm = cpu->R[REG_NUM(i, 6)]; |
|
| 252 |
+ |
|
| 253 |
+ cpu->R[REG_NUM(i, 0)] = Rn + Rm; |
|
| 254 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 255 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 256 |
+ cpu->CPSR.bits.C = CarryFrom(Rn, Rm); |
|
| 257 |
+ cpu->CPSR.bits.V = OverflowFromADD(cpu->R[REG_NUM(i, 0)], Rn, Rm); |
|
| 258 |
+ |
|
| 259 |
+ return 1; |
|
| 260 |
+} |
|
| 261 |
+ |
|
| 262 |
+TEMPLATE static uint32_t FASTCALL OP_ADD_SPE(const uint32_t i) |
|
| 263 |
+{
|
|
| 264 |
+ uint32_t Rd = REG_NUM(i, 0) | ((i>>4)&8); |
|
| 265 |
+ |
|
| 266 |
+ cpu->R[Rd] += cpu->R[REG_POS(i, 3)]; |
|
| 267 |
+ |
|
| 268 |
+ if(Rd==15) |
|
| 269 |
+ {
|
|
| 270 |
+ cpu->next_instruction = cpu->R[15]; |
|
| 271 |
+ return 3; |
|
| 272 |
+ } |
|
| 273 |
+ |
|
| 274 |
+ return 1; |
|
| 275 |
+} |
|
| 276 |
+ |
|
| 277 |
+TEMPLATE static uint32_t FASTCALL OP_ADD_2PC(const uint32_t i) |
|
| 278 |
+{
|
|
| 279 |
+ cpu->R[REG_NUM(i, 8)] = (cpu->R[15]&0xFFFFFFFC) + ((i&0xFF)<<2); |
|
| 280 |
+ |
|
| 281 |
+ return 1; |
|
| 282 |
+} |
|
| 283 |
+ |
|
| 284 |
+TEMPLATE static uint32_t FASTCALL OP_ADD_2SP(const uint32_t i) |
|
| 285 |
+{
|
|
| 286 |
+ cpu->R[REG_NUM(i, 8)] = cpu->R[13] + ((i&0xFF)<<2); |
|
| 287 |
+ |
|
| 288 |
+ return 1; |
|
| 289 |
+} |
|
| 290 |
+ |
|
| 291 |
+//----------------------------------------------------------------------------- |
|
| 292 |
+// SUB |
|
| 293 |
+//----------------------------------------------------------------------------- |
|
| 294 |
+ |
|
| 295 |
+TEMPLATE static uint32_t FASTCALL OP_SUB_IMM3(const uint32_t i) |
|
| 296 |
+{
|
|
| 297 |
+ uint32_t imm3 = (i>>6) & 0x07; |
|
| 298 |
+ uint32_t Rn = cpu->R[REG_NUM(i, 3)]; |
|
| 299 |
+ uint32_t tmp = Rn - imm3; |
|
| 300 |
+ |
|
| 301 |
+ cpu->R[REG_NUM(i, 0)] = tmp; |
|
| 302 |
+ cpu->CPSR.bits.N = BIT31(tmp); |
|
| 303 |
+ cpu->CPSR.bits.Z = (tmp == 0); |
|
| 304 |
+ cpu->CPSR.bits.C = !BorrowFrom(Rn, imm3); |
|
| 305 |
+ cpu->CPSR.bits.V = OverflowFromSUB(tmp, Rn, imm3); |
|
| 306 |
+ |
|
| 307 |
+ return 1; |
|
| 308 |
+} |
|
| 309 |
+ |
|
| 310 |
+TEMPLATE static uint32_t FASTCALL OP_SUB_IMM8(const uint32_t i) |
|
| 311 |
+{
|
|
| 312 |
+ uint32_t imm8 = (i & 0xFF); |
|
| 313 |
+ uint32_t Rd = cpu->R[REG_NUM(i, 8)]; |
|
| 314 |
+ uint32_t tmp = Rd - imm8; |
|
| 315 |
+ |
|
| 316 |
+ cpu->R[REG_NUM(i, 8)] = tmp; |
|
| 317 |
+ cpu->CPSR.bits.N = BIT31(tmp); |
|
| 318 |
+ cpu->CPSR.bits.Z = (tmp == 0); |
|
| 319 |
+ cpu->CPSR.bits.C = !BorrowFrom(Rd, imm8); |
|
| 320 |
+ cpu->CPSR.bits.V = OverflowFromSUB(tmp, Rd, imm8); |
|
| 321 |
+ |
|
| 322 |
+ return 1; |
|
| 323 |
+} |
|
| 324 |
+ |
|
| 325 |
+TEMPLATE static uint32_t FASTCALL OP_SUB_REG(const uint32_t i) |
|
| 326 |
+{
|
|
| 327 |
+ uint32_t Rn = cpu->R[REG_NUM(i, 3)]; |
|
| 328 |
+ uint32_t Rm = cpu->R[REG_NUM(i, 6)]; |
|
| 329 |
+ uint32_t tmp = Rn - Rm; |
|
| 330 |
+ |
|
| 331 |
+ cpu->R[REG_NUM(i, 0)] = tmp; |
|
| 332 |
+ cpu->CPSR.bits.N = BIT31(tmp); |
|
| 333 |
+ cpu->CPSR.bits.Z = (tmp == 0); |
|
| 334 |
+ cpu->CPSR.bits.C = !BorrowFrom(Rn, Rm); |
|
| 335 |
+ cpu->CPSR.bits.V = OverflowFromSUB(tmp, Rn, Rm); |
|
| 336 |
+ |
|
| 337 |
+ return 1; |
|
| 338 |
+} |
|
| 339 |
+ |
|
| 340 |
+//----------------------------------------------------------------------------- |
|
| 341 |
+// MOV |
|
| 342 |
+//----------------------------------------------------------------------------- |
|
| 343 |
+ |
|
| 344 |
+TEMPLATE static uint32_t FASTCALL OP_MOV_IMM8(const uint32_t i) |
|
| 345 |
+{
|
|
| 346 |
+ cpu->R[REG_NUM(i, 8)] = (i & 0xFF); |
|
| 347 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 8)]); |
|
| 348 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 8)] == 0; |
|
| 349 |
+ |
|
| 350 |
+ return 1; |
|
| 351 |
+} |
|
| 352 |
+ |
|
| 353 |
+TEMPLATE static uint32_t FASTCALL OP_MOV_SPE(const uint32_t i) |
|
| 354 |
+{
|
|
| 355 |
+ uint32_t Rd = REG_NUM(i, 0) | ((i>>4)&8); |
|
| 356 |
+ |
|
| 357 |
+ cpu->R[Rd] = cpu->R[REG_POS(i, 3)]; |
|
| 358 |
+ |
|
| 359 |
+ if(Rd==15) |
|
| 360 |
+ {
|
|
| 361 |
+ cpu->next_instruction = cpu->R[15]; |
|
| 362 |
+ return 3; |
|
| 363 |
+ } |
|
| 364 |
+ |
|
| 365 |
+ return 1; |
|
| 366 |
+} |
|
| 367 |
+ |
|
| 368 |
+//----------------------------------------------------------------------------- |
|
| 369 |
+// CMP |
|
| 370 |
+//----------------------------------------------------------------------------- |
|
| 371 |
+TEMPLATE static uint32_t FASTCALL OP_CMP_IMM8(const uint32_t i) |
|
| 372 |
+{
|
|
| 373 |
+ uint32_t tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF); |
|
| 374 |
+ |
|
| 375 |
+ cpu->CPSR.bits.N = BIT31(tmp); |
|
| 376 |
+ cpu->CPSR.bits.Z = tmp == 0; |
|
| 377 |
+ cpu->CPSR.bits.C = !BorrowFrom(cpu->R[REG_NUM(i, 8)], (i & 0xFF)); |
|
| 378 |
+ cpu->CPSR.bits.V = OverflowFromSUB(tmp, cpu->R[REG_NUM(i, 8)], (i & 0xFF)); |
|
| 379 |
+ |
|
| 380 |
+ return 1; |
|
| 381 |
+} |
|
| 382 |
+ |
|
| 383 |
+TEMPLATE static uint32_t FASTCALL OP_CMP(const uint32_t i) |
|
| 384 |
+{
|
|
| 385 |
+ uint32_t tmp = cpu->R[REG_NUM(i, 0)] - cpu->R[REG_NUM(i, 3)]; |
|
| 386 |
+ |
|
| 387 |
+ cpu->CPSR.bits.N = BIT31(tmp); |
|
| 388 |
+ cpu->CPSR.bits.Z = tmp == 0; |
|
| 389 |
+ cpu->CPSR.bits.C = !BorrowFrom(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)]); |
|
| 390 |
+ cpu->CPSR.bits.V = OverflowFromSUB(tmp, cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)]); |
|
| 391 |
+ |
|
| 392 |
+ return 1; |
|
| 393 |
+} |
|
| 394 |
+ |
|
| 395 |
+TEMPLATE static uint32_t FASTCALL OP_CMP_SPE(const uint32_t i) |
|
| 396 |
+{
|
|
| 397 |
+ uint32_t Rn = (i&7) | ((i>>4)&8); |
|
| 398 |
+ |
|
| 399 |
+ uint32_t tmp = cpu->R[Rn] - cpu->R[REG_POS(i, 3)]; |
|
| 400 |
+ |
|
| 401 |
+ cpu->CPSR.bits.N = BIT31(tmp); |
|
| 402 |
+ cpu->CPSR.bits.Z = tmp == 0; |
|
| 403 |
+ cpu->CPSR.bits.C = !BorrowFrom(cpu->R[Rn], cpu->R[REG_POS(i, 3)]); |
|
| 404 |
+ cpu->CPSR.bits.V = OverflowFromSUB(tmp, cpu->R[Rn], cpu->R[REG_POS(i, 3)]); |
|
| 405 |
+ |
|
| 406 |
+ return 1; |
|
| 407 |
+} |
|
| 408 |
+ |
|
| 409 |
+//----------------------------------------------------------------------------- |
|
| 410 |
+// AND |
|
| 411 |
+//----------------------------------------------------------------------------- |
|
| 412 |
+ |
|
| 413 |
+TEMPLATE static uint32_t FASTCALL OP_AND(const uint32_t i) |
|
| 414 |
+{
|
|
| 415 |
+ cpu->R[REG_NUM(i, 0)] &= cpu->R[REG_NUM(i, 3)]; |
|
| 416 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 417 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 418 |
+ return 1; |
|
| 419 |
+} |
|
| 420 |
+ |
|
| 421 |
+//----------------------------------------------------------------------------- |
|
| 422 |
+// EOR |
|
| 423 |
+//----------------------------------------------------------------------------- |
|
| 424 |
+ |
|
| 425 |
+TEMPLATE static uint32_t FASTCALL OP_EOR(const uint32_t i) |
|
| 426 |
+{
|
|
| 427 |
+ cpu->R[REG_NUM(i, 0)] ^= cpu->R[REG_NUM(i, 3)]; |
|
| 428 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 429 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 430 |
+ |
|
| 431 |
+ return 1; |
|
| 432 |
+} |
|
| 433 |
+ |
|
| 434 |
+//----------------------------------------------------------------------------- |
|
| 435 |
+// ADC |
|
| 436 |
+//----------------------------------------------------------------------------- |
|
| 437 |
+ |
|
| 438 |
+TEMPLATE static uint32_t FASTCALL OP_ADC_REG(const uint32_t i) |
|
| 439 |
+{
|
|
| 440 |
+ uint32_t Rd = cpu->R[REG_NUM(i, 0)]; |
|
| 441 |
+ uint32_t Rm = cpu->R[REG_NUM(i, 3)]; |
|
| 442 |
+ |
|
| 443 |
+ if (!cpu->CPSR.bits.C) |
|
| 444 |
+ {
|
|
| 445 |
+ cpu->R[REG_NUM(i, 0)] = Rd + Rm; |
|
| 446 |
+ cpu->CPSR.bits.C = cpu->R[REG_NUM(i, 0)] < Rm; |
|
| 447 |
+ } |
|
| 448 |
+ else |
|
| 449 |
+ {
|
|
| 450 |
+ cpu->R[REG_NUM(i, 0)] = Rd + Rm + 1; |
|
| 451 |
+ cpu->CPSR.bits.C = cpu->R[REG_NUM(i, 0)] <= Rm; |
|
| 452 |
+ } |
|
| 453 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 454 |
+ cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 0)] == 0); |
|
| 455 |
+ cpu->CPSR.bits.V = BIT31((Rd ^ Rm ^ -1) & (Rd ^ cpu->R[REG_NUM(i, 0)])); |
|
| 456 |
+ |
|
| 457 |
+ return 1; |
|
| 458 |
+} |
|
| 459 |
+ |
|
| 460 |
+//----------------------------------------------------------------------------- |
|
| 461 |
+// SBC |
|
| 462 |
+//----------------------------------------------------------------------------- |
|
| 463 |
+TEMPLATE static uint32_t FASTCALL OP_SBC_REG(const uint32_t i) |
|
| 464 |
+{
|
|
| 465 |
+ uint32_t Rd = cpu->R[REG_NUM(i, 0)]; |
|
| 466 |
+ uint32_t Rm = cpu->R[REG_NUM(i, 3)]; |
|
| 467 |
+ |
|
| 468 |
+ if (!cpu->CPSR.bits.C) |
|
| 469 |
+ {
|
|
| 470 |
+ cpu->R[REG_NUM(i, 0)] = Rd - Rm - 1; |
|
| 471 |
+ cpu->CPSR.bits.C = Rd > Rm; |
|
| 472 |
+ } |
|
| 473 |
+ else |
|
| 474 |
+ {
|
|
| 475 |
+ cpu->R[REG_NUM(i, 0)] = Rd - Rm; |
|
| 476 |
+ cpu->CPSR.bits.C = Rd >= Rm; |
|
| 477 |
+ } |
|
| 478 |
+ |
|
| 479 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 480 |
+ cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 0)] == 0); |
|
| 481 |
+ cpu->CPSR.bits.V = BIT31((Rd ^ Rm) & (Rd ^ cpu->R[REG_NUM(i, 0)])); |
|
| 482 |
+ |
|
| 483 |
+ return 1; |
|
| 484 |
+} |
|
| 485 |
+ |
|
| 486 |
+//----------------------------------------------------------------------------- |
|
| 487 |
+// ROR |
|
| 488 |
+//----------------------------------------------------------------------------- |
|
| 489 |
+ |
|
| 490 |
+TEMPLATE static uint32_t FASTCALL OP_ROR_REG(const uint32_t i) |
|
| 491 |
+{
|
|
| 492 |
+ uint32_t v = cpu->R[REG_NUM(i, 3)] & 0xFF; |
|
| 493 |
+ |
|
| 494 |
+ if(v == 0) |
|
| 495 |
+ {
|
|
| 496 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 497 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 498 |
+ return 2; |
|
| 499 |
+ } |
|
| 500 |
+ |
|
| 501 |
+ v &= 0x1F; |
|
| 502 |
+ if(v == 0) |
|
| 503 |
+ {
|
|
| 504 |
+ cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 505 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 506 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 507 |
+ return 2; |
|
| 508 |
+ } |
|
| 509 |
+ cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); |
|
| 510 |
+ cpu->R[REG_NUM(i, 0)] = ROR(cpu->R[REG_NUM(i, 0)], v); |
|
| 511 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 512 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 513 |
+ |
|
| 514 |
+ return 2; |
|
| 515 |
+} |
|
| 516 |
+ |
|
| 517 |
+//----------------------------------------------------------------------------- |
|
| 518 |
+// TST |
|
| 519 |
+//----------------------------------------------------------------------------- |
|
| 520 |
+ |
|
| 521 |
+TEMPLATE static uint32_t FASTCALL OP_TST(const uint32_t i) |
|
| 522 |
+{
|
|
| 523 |
+ uint32_t tmp = cpu->R[REG_NUM(i, 0)] & cpu->R[REG_NUM(i, 3)]; |
|
| 524 |
+ cpu->CPSR.bits.N = BIT31(tmp); |
|
| 525 |
+ cpu->CPSR.bits.Z = (tmp == 0); |
|
| 526 |
+ |
|
| 527 |
+ return 1; |
|
| 528 |
+} |
|
| 529 |
+ |
|
| 530 |
+//----------------------------------------------------------------------------- |
|
| 531 |
+// NEG |
|
| 532 |
+//----------------------------------------------------------------------------- |
|
| 533 |
+ |
|
| 534 |
+TEMPLATE static uint32_t FASTCALL OP_NEG(const uint32_t i) |
|
| 535 |
+{
|
|
| 536 |
+ uint32_t Rm = cpu->R[REG_NUM(i, 3)]; |
|
| 537 |
+ |
|
| 538 |
+ cpu->R[REG_NUM(i, 0)] = (uint32_t)((int32_t)0 - (int32_t)Rm); |
|
| 539 |
+ |
|
| 540 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 541 |
+ cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 0)] == 0); |
|
| 542 |
+ cpu->CPSR.bits.C = !BorrowFrom(0, Rm); |
|
| 543 |
+ cpu->CPSR.bits.V = OverflowFromSUB(cpu->R[REG_NUM(i, 0)], 0, Rm); |
|
| 544 |
+ |
|
| 545 |
+ return 1; |
|
| 546 |
+} |
|
| 547 |
+ |
|
| 548 |
+//----------------------------------------------------------------------------- |
|
| 549 |
+// CMN |
|
| 550 |
+//----------------------------------------------------------------------------- |
|
| 551 |
+ |
|
| 552 |
+TEMPLATE static uint32_t FASTCALL OP_CMN(const uint32_t i) |
|
| 553 |
+{
|
|
| 554 |
+ uint32_t tmp = cpu->R[REG_NUM(i, 0)] + cpu->R[REG_NUM(i, 3)]; |
|
| 555 |
+ |
|
| 556 |
+ cpu->CPSR.bits.N = BIT31(tmp); |
|
| 557 |
+ cpu->CPSR.bits.Z = tmp == 0; |
|
| 558 |
+ cpu->CPSR.bits.C = CarryFrom(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)]); |
|
| 559 |
+ cpu->CPSR.bits.V = OverflowFromADD(tmp, cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)]); |
|
| 560 |
+ |
|
| 561 |
+ return 1; |
|
| 562 |
+} |
|
| 563 |
+ |
|
| 564 |
+//----------------------------------------------------------------------------- |
|
| 565 |
+// ORR |
|
| 566 |
+//----------------------------------------------------------------------------- |
|
| 567 |
+ |
|
| 568 |
+TEMPLATE static uint32_t FASTCALL OP_ORR(const uint32_t i) |
|
| 569 |
+{
|
|
| 570 |
+ cpu->R[REG_NUM(i, 0)] |= cpu->R[REG_NUM(i, 3)]; |
|
| 571 |
+ |
|
| 572 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 573 |
+ cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 0)] == 0); |
|
| 574 |
+ |
|
| 575 |
+ return 1; |
|
| 576 |
+} |
|
| 577 |
+ |
|
| 578 |
+//----------------------------------------------------------------------------- |
|
| 579 |
+// BIC |
|
| 580 |
+//----------------------------------------------------------------------------- |
|
| 581 |
+ |
|
| 582 |
+TEMPLATE static uint32_t FASTCALL OP_BIC(const uint32_t i) |
|
| 583 |
+{
|
|
| 584 |
+ cpu->R[REG_NUM(i, 0)] &= (~cpu->R[REG_NUM(i, 3)]); |
|
| 585 |
+ |
|
| 586 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 587 |
+ cpu->CPSR.bits.Z = (cpu->R[REG_NUM(i, 0)] == 0); |
|
| 588 |
+ |
|
| 589 |
+ return 1; |
|
| 590 |
+} |
|
| 591 |
+ |
|
| 592 |
+//----------------------------------------------------------------------------- |
|
| 593 |
+// MVN |
|
| 594 |
+//----------------------------------------------------------------------------- |
|
| 595 |
+ |
|
| 596 |
+TEMPLATE static uint32_t FASTCALL OP_MVN(const uint32_t i) |
|
| 597 |
+{
|
|
| 598 |
+ cpu->R[REG_NUM(i, 0)] = (~cpu->R[REG_NUM(i, 3)]); |
|
| 599 |
+ |
|
| 600 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 601 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 602 |
+ |
|
| 603 |
+ return 1; |
|
| 604 |
+} |
|
| 605 |
+ |
|
| 606 |
+//----------------------------------------------------------------------------- |
|
| 607 |
+// MUL |
|
| 608 |
+//----------------------------------------------------------------------------- |
|
| 609 |
+ |
|
| 610 |
+#define MUL_Mxx_END_THUMB(c) \ |
|
| 611 |
+ v >>= 8; \ |
|
| 612 |
+ if((v==0)||(v==0xFFFFFF)) \ |
|
| 613 |
+ return c+1; \ |
|
| 614 |
+ v >>= 8; \ |
|
| 615 |
+ if((v==0)||(v==0xFFFF)) \ |
|
| 616 |
+ return c+2; \ |
|
| 617 |
+ v >>= 8; \ |
|
| 618 |
+ if((v==0)||(v==0xFF)) \ |
|
| 619 |
+ return c+3; \ |
|
| 620 |
+ return c+4; \ |
|
| 621 |
+ |
|
| 622 |
+TEMPLATE static uint32_t FASTCALL OP_MUL_REG(const uint32_t i) |
|
| 623 |
+{
|
|
| 624 |
+ uint32_t v = cpu->R[REG_NUM(i, 3)]; |
|
| 625 |
+ |
|
| 626 |
+ // FIXME: |
|
| 627 |
+ //------ Rd = (Rm * Rd)[31:0] |
|
| 628 |
+ //------ u64 res = ((u64)cpu->R[REG_NUM(i, 0)] * (u64)v)); |
|
| 629 |
+ //------ cpu->R[REG_NUM(i, 0)] = (uint32_t)(res & 0xFFFFFFFF); |
|
| 630 |
+ //------ |
|
| 631 |
+ |
|
| 632 |
+ cpu->R[REG_NUM(i, 0)] *= v; |
|
| 633 |
+ cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); |
|
| 634 |
+ cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; |
|
| 635 |
+ //The MUL instruction is defined to leave the C flag unchanged in ARMv5 and above. |
|
| 636 |
+ //In earlier versions of the architecture, the value of the C flag was UNPREDICTABLE |
|
| 637 |
+ //after a MUL instruction. |
|
| 638 |
+ |
|
| 639 |
+ if (!cpu->LDTBit) // ARM4T 1S + mI, m = 3 |
|
| 640 |
+ return 4; |
|
| 641 |
+ |
|
| 642 |
+ MUL_Mxx_END_THUMB(1); |
|
| 643 |
+} |
|
| 644 |
+ |
|
| 645 |
+//----------------------------------------------------------------------------- |
|
| 646 |
+// STRB / LDRB |
|
| 647 |
+//----------------------------------------------------------------------------- |
|
| 648 |
+ |
|
| 649 |
+TEMPLATE static uint32_t FASTCALL OP_STRB_IMM_OFF(const uint32_t i) |
|
| 650 |
+{
|
|
| 651 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F); |
|
| 652 |
+ WRITE8(cpu->mem_if->data, adr, (uint8_t)cpu->R[REG_NUM(i, 0)]); |
|
| 653 |
+ |
|
| 654 |
+ return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_WRITE>(2, adr); |
|
| 655 |
+} |
|
| 656 |
+ |
|
| 657 |
+TEMPLATE static uint32_t FASTCALL OP_LDRB_IMM_OFF(const uint32_t i) |
|
| 658 |
+{
|
|
| 659 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F); |
|
| 660 |
+ cpu->R[REG_NUM(i, 0)] = (uint32_t)READ8(cpu->mem_if->data, adr); |
|
| 661 |
+ |
|
| 662 |
+ return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_READ>(3, adr); |
|
| 663 |
+} |
|
| 664 |
+ |
|
| 665 |
+ |
|
| 666 |
+TEMPLATE static uint32_t FASTCALL OP_STRB_REG_OFF(const uint32_t i) |
|
| 667 |
+{
|
|
| 668 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; |
|
| 669 |
+ WRITE8(cpu->mem_if->data, adr, (uint8_t)cpu->R[REG_NUM(i, 0)]); |
|
| 670 |
+ |
|
| 671 |
+ return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_WRITE>(2, adr); |
|
| 672 |
+} |
|
| 673 |
+ |
|
| 674 |
+TEMPLATE static uint32_t FASTCALL OP_LDRB_REG_OFF(const uint32_t i) |
|
| 675 |
+{
|
|
| 676 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; |
|
| 677 |
+ cpu->R[REG_NUM(i, 0)] = (uint32_t)READ8(cpu->mem_if->data, adr); |
|
| 678 |
+ |
|
| 679 |
+ return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_READ>(3, adr); |
|
| 680 |
+} |
|
| 681 |
+ |
|
| 682 |
+//----------------------------------------------------------------------------- |
|
| 683 |
+// LDRSB |
|
| 684 |
+//----------------------------------------------------------------------------- |
|
| 685 |
+ |
|
| 686 |
+TEMPLATE static uint32_t FASTCALL OP_LDRSB_REG_OFF(const uint32_t i) |
|
| 687 |
+{
|
|
| 688 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; |
|
| 689 |
+ cpu->R[REG_NUM(i, 0)] = (uint32_t)((int8_t)READ8(cpu->mem_if->data, adr)); |
|
| 690 |
+ |
|
| 691 |
+ return MMU_aluMemAccessCycles<PROCNUM,8,MMU_AD_READ>(3, adr); |
|
| 692 |
+} |
|
| 693 |
+ |
|
| 694 |
+//----------------------------------------------------------------------------- |
|
| 695 |
+// STRH / LDRH |
|
| 696 |
+//----------------------------------------------------------------------------- |
|
| 697 |
+ |
|
| 698 |
+TEMPLATE static uint32_t FASTCALL OP_STRH_IMM_OFF(const uint32_t i) |
|
| 699 |
+{
|
|
| 700 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E); |
|
| 701 |
+ WRITE16(cpu->mem_if->data, adr, (uint16_t)cpu->R[REG_NUM(i, 0)]); |
|
| 702 |
+ |
|
| 703 |
+ return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_WRITE>(2, adr); |
|
| 704 |
+} |
|
| 705 |
+ |
|
| 706 |
+TEMPLATE static uint32_t FASTCALL OP_LDRH_IMM_OFF(const uint32_t i) |
|
| 707 |
+{
|
|
| 708 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E); |
|
| 709 |
+ cpu->R[REG_NUM(i, 0)] = (uint32_t)READ16(cpu->mem_if->data, adr); |
|
| 710 |
+ |
|
| 711 |
+ return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_READ>(3, adr); |
|
| 712 |
+} |
|
| 713 |
+ |
|
| 714 |
+ |
|
| 715 |
+TEMPLATE static uint32_t FASTCALL OP_STRH_REG_OFF(const uint32_t i) |
|
| 716 |
+{
|
|
| 717 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; |
|
| 718 |
+ WRITE16(cpu->mem_if->data, adr, ((uint16_t)cpu->R[REG_NUM(i, 0)])); |
|
| 719 |
+ |
|
| 720 |
+ return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_WRITE>(2, adr); |
|
| 721 |
+} |
|
| 722 |
+ |
|
| 723 |
+TEMPLATE static uint32_t FASTCALL OP_LDRH_REG_OFF(const uint32_t i) |
|
| 724 |
+{
|
|
| 725 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; |
|
| 726 |
+ cpu->R[REG_NUM(i, 0)] = (uint32_t)READ16(cpu->mem_if->data, adr); |
|
| 727 |
+ |
|
| 728 |
+ return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_READ>(3, adr); |
|
| 729 |
+} |
|
| 730 |
+ |
|
| 731 |
+//----------------------------------------------------------------------------- |
|
| 732 |
+// LDRSH |
|
| 733 |
+//----------------------------------------------------------------------------- |
|
| 734 |
+ |
|
| 735 |
+TEMPLATE static uint32_t FASTCALL OP_LDRSH_REG_OFF(const uint32_t i) |
|
| 736 |
+{
|
|
| 737 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; |
|
| 738 |
+ cpu->R[REG_NUM(i, 0)] = (uint32_t)((int16_t)READ16(cpu->mem_if->data, adr)); |
|
| 739 |
+ |
|
| 740 |
+ return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_READ>(3, adr); |
|
| 741 |
+} |
|
| 742 |
+ |
|
| 743 |
+//----------------------------------------------------------------------------- |
|
| 744 |
+// STR / LDR |
|
| 745 |
+//----------------------------------------------------------------------------- |
|
| 746 |
+ |
|
| 747 |
+TEMPLATE static uint32_t FASTCALL OP_STR_IMM_OFF(const uint32_t i) |
|
| 748 |
+{
|
|
| 749 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C); |
|
| 750 |
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]); |
|
| 751 |
+ |
|
| 752 |
+ return MMU_aluMemAccessCycles<PROCNUM,32,MMU_AD_WRITE>(2, adr); |
|
| 753 |
+} |
|
| 754 |
+ |
|
| 755 |
+TEMPLATE static uint32_t FASTCALL OP_LDR_IMM_OFF(const uint32_t i) |
|
| 756 |
+{
|
|
| 757 |
+ uint32_t adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C); |
|
| 758 |
+ uint32_t tempValue = READ32(cpu->mem_if->data, adr); |
|
| 759 |
+ adr = (adr&3)*8; |
|
| 760 |
+ tempValue = (tempValue>>adr) | (tempValue<<(32-adr)); |
|
| 761 |
+ cpu->R[REG_NUM(i, 0)] = tempValue; |
|
| 762 |
+ |
|
| 763 |
+ return MMU_aluMemAccessCycles<PROCNUM,32,MMU_AD_READ>(3, adr); |
|
| 764 |
+} |
|
| 765 |
+ |
|
| 766 |
+ |
|
| 767 |
+TEMPLATE static uint32_t FASTCALL OP_STR_REG_OFF(const uint32_t i) |
|
| 768 |
+{
|
|
| 769 |
+ uint32_t adr = cpu->R[REG_NUM(i, 6)] + cpu->R[REG_NUM(i, 3)]; |
|
| 770 |
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]); |
|
| 771 |
+ |
|
| 772 |
+ return MMU_aluMemAccessCycles<PROCNUM,32,MMU_AD_WRITE>(2, adr); |
|
| 773 |
+} |
|
| 774 |
+ |
|
| 775 |
+TEMPLATE static uint32_t FASTCALL OP_LDR_REG_OFF(const uint32_t i) |
|
| 776 |
+{
|
|
| 777 |
+ uint32_t adr = (cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]); |
|
| 778 |
+ uint32_t tempValue = READ32(cpu->mem_if->data, adr); |
|
| 779 |
+ adr = (adr&3)*8; |
|
| 780 |
+ tempValue = (tempValue>>adr) | (tempValue<<(32-adr)); |
|
| 781 |
+ cpu->R[REG_NUM(i, 0)] = tempValue; |
|
| 782 |
+ |
|
| 783 |
+ return MMU_aluMemAccessCycles<PROCNUM,32,MMU_AD_READ>(3, adr); |
|
| 784 |
+} |
|
| 785 |
+ |
|
| 786 |
+TEMPLATE static uint32_t FASTCALL OP_STR_SPREL(const uint32_t i) |
|
| 787 |
+{
|
|
| 788 |
+ uint32_t adr = cpu->R[13] + ((i&0xFF)<<2); |
|
| 789 |
+ WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 8)]); |
|
| 790 |
+ |
|
| 791 |
+ return MMU_aluMemAccessCycles<PROCNUM,16,MMU_AD_WRITE>(2, adr); |
|
| 792 |
+} |
|
| 793 |
+ |
|
| 794 |
+TEMPLATE static uint32_t FASTCALL OP_LDR_SPREL(const uint32_t i) |
|
| 795 |
+{
|
|
| 796 |
+ uint32_t adr = cpu->R[13] + ((i&0xFF)<<2); |
|
| 797 |
+ cpu->R[REG_NUM(i, 8)] = READ32(cpu->mem_if->data, adr); |
|
| 798 |
+ |
|
| 799 |
+ return MMU_aluMemAccessCycles<PROCNUM,32,MMU_AD_READ>(3, adr); |
|
| 800 |
+} |
|
| 801 |
+ |
|
| 802 |
+TEMPLATE static uint32_t FASTCALL OP_LDR_PCREL(const uint32_t i) |
|
| 803 |
+{
|
|
| 804 |
+ uint32_t adr = (cpu->R[15]&0xFFFFFFFC) + ((i&0xFF)<<2); |
|
| 805 |
+ |
|
| 806 |
+ cpu->R[REG_NUM(i, 8)] = READ32(cpu->mem_if->data, adr); |
|
| 807 |
+ |
|
| 808 |
+ return MMU_aluMemAccessCycles<PROCNUM,32,MMU_AD_READ>(3, adr); |
|
| 809 |
+} |
|
| 810 |
+ |
|
| 811 |
+//----------------------------------------------------------------------------- |
|
| 812 |
+// Adjust SP |
|
| 813 |
+//----------------------------------------------------------------------------- |
|
| 814 |
+ |
|
| 815 |
+TEMPLATE static uint32_t FASTCALL OP_ADJUST_P_SP(const uint32_t i) |
|
| 816 |
+{
|
|
| 817 |
+ cpu->R[13] += ((i&0x7F)<<2); |
|
| 818 |
+ |
|
| 819 |
+ return 1; |
|
| 820 |
+} |
|
| 821 |
+ |
|
| 822 |
+TEMPLATE static uint32_t FASTCALL OP_ADJUST_M_SP(const uint32_t i) |
|
| 823 |
+{
|
|
| 824 |
+ cpu->R[13] -= ((i&0x7F)<<2); |
|
| 825 |
+ |
|
| 826 |
+ return 1; |
|
| 827 |
+} |
|
| 828 |
+ |
|
| 829 |
+//----------------------------------------------------------------------------- |
|
| 830 |
+// PUSH / POP |
|
| 831 |
+//----------------------------------------------------------------------------- |
|
| 832 |
+ |
|
| 833 |
+TEMPLATE static uint32_t FASTCALL OP_PUSH(const uint32_t i) |
|
| 834 |
+{
|
|
| 835 |
+ uint32_t adr = cpu->R[13] - 4; |
|
| 836 |
+ uint32_t c = 0, j; |
|
| 837 |
+ |
|
| 838 |
+ for(j = 0; j<8; j++) |
|
| 839 |
+ if(BIT_N(i, 7-j)) |
|
| 840 |
+ {
|
|
| 841 |
+ WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]); |
|
| 842 |
+ c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_WRITE>(adr); |
|
| 843 |
+ adr -= 4; |
|
| 844 |
+ } |
|
| 845 |
+ cpu->R[13] = adr + 4; |
|
| 846 |
+ |
|
| 847 |
+ return MMU_aluMemCycles<PROCNUM>(3, c); |
|
| 848 |
+} |
|
| 849 |
+ |
|
| 850 |
+TEMPLATE static uint32_t FASTCALL OP_PUSH_LR(const uint32_t i) |
|
| 851 |
+{
|
|
| 852 |
+ uint32_t adr = cpu->R[13] - 4; |
|
| 853 |
+ uint32_t c = 0, j; |
|
| 854 |
+ |
|
| 855 |
+ WRITE32(cpu->mem_if->data, adr, cpu->R[14]); |
|
| 856 |
+ c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_WRITE>(adr); |
|
| 857 |
+ adr -= 4; |
|
| 858 |
+ |
|
| 859 |
+ for(j = 0; j<8; j++) |
|
| 860 |
+ if(BIT_N(i, 7-j)) |
|
| 861 |
+ {
|
|
| 862 |
+ WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]); |
|
| 863 |
+ c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_WRITE>(adr); |
|
| 864 |
+ adr -= 4; |
|
| 865 |
+ } |
|
| 866 |
+ cpu->R[13] = adr + 4; |
|
| 867 |
+ |
|
| 868 |
+ return MMU_aluMemCycles<PROCNUM>(4, c); |
|
| 869 |
+} |
|
| 870 |
+ |
|
| 871 |
+TEMPLATE static uint32_t FASTCALL OP_POP(const uint32_t i) |
|
| 872 |
+{
|
|
| 873 |
+ uint32_t adr = cpu->R[13]; |
|
| 874 |
+ uint32_t c = 0, j; |
|
| 875 |
+ |
|
| 876 |
+ for(j = 0; j<8; j++) |
|
| 877 |
+ if(BIT_N(i, j)) |
|
| 878 |
+ {
|
|
| 879 |
+ cpu->R[j] = READ32(cpu->mem_if->data, adr); |
|
| 880 |
+ c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_READ>(adr); |
|
| 881 |
+ adr += 4; |
|
| 882 |
+ } |
|
| 883 |
+ cpu->R[13] = adr; |
|
| 884 |
+ |
|
| 885 |
+ return MMU_aluMemCycles<PROCNUM>(2, c); |
|
| 886 |
+} |
|
| 887 |
+ |
|
| 888 |
+// In ARMv5 and above, bit[0] of the loaded value |
|
| 889 |
+// determines whether execution continues after this branch in ARM state or in Thumb state, as though the |
|
| 890 |
+// following instruction had been executed: |
|
| 891 |
+// BX (loaded_value) |
|
| 892 |
+// In T variants of ARMv4, bit[0] of the loaded value is ignored and execution continues in Thumb state, as |
|
| 893 |
+// though the following instruction had been executed: |
|
| 894 |
+// MOV PC,(loaded_value) |
|
| 895 |
+TEMPLATE static uint32_t FASTCALL OP_POP_PC(const uint32_t i) |
|
| 896 |
+{
|
|
| 897 |
+ uint32_t adr = cpu->R[13]; |
|
| 898 |
+ uint32_t c = 0, j; |
|
| 899 |
+ uint32_t v = 0; |
|
| 900 |
+ |
|
| 901 |
+ for(j = 0; j<8; j++) |
|
| 902 |
+ if(BIT_N(i, j)) |
|
| 903 |
+ {
|
|
| 904 |
+ cpu->R[j] = READ32(cpu->mem_if->data, adr); |
|
| 905 |
+ c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_READ>(adr); |
|
| 906 |
+ adr += 4; |
|
| 907 |
+ } |
|
| 908 |
+ |
|
| 909 |
+ v = READ32(cpu->mem_if->data, adr); |
|
| 910 |
+ c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_READ>(adr); |
|
| 911 |
+ if(cpu->LDTBit) |
|
| 912 |
+ cpu->CPSR.bits.T = BIT0(v); |
|
| 913 |
+ |
|
| 914 |
+ cpu->R[15] = v & 0xFFFFFFFE; |
|
| 915 |
+ cpu->next_instruction = cpu->R[15]; |
|
| 916 |
+ |
|
| 917 |
+ cpu->R[13] = adr + 4; |
|
| 918 |
+ return MMU_aluMemCycles<PROCNUM>(5, c); |
|
| 919 |
+} |
|
| 920 |
+ |
|
| 921 |
+//----------------------------------------------------------------------------- |
|
| 922 |
+// STMIA / LDMIA |
|
| 923 |
+//----------------------------------------------------------------------------- |
|
| 924 |
+ |
|
| 925 |
+TEMPLATE static uint32_t FASTCALL OP_STMIA_THUMB(const uint32_t i) |
|
| 926 |
+{
|
|
| 927 |
+ uint32_t adr = cpu->R[REG_NUM(i, 8)]; |
|
| 928 |
+ uint32_t c = 0, j; |
|
| 929 |
+ uint32_t erList = 1; //Empty Register List |
|
| 930 |
+ |
|
| 931 |
+ // ------ ARM_REF: |
|
| 932 |
+ // ------ If <Rn> is specified in <registers>: |
|
| 933 |
+ // ------ * If <Rn> is the lowest-numbered register specified in <registers>, the original value of <Rn> is stored. |
|
| 934 |
+ // ------ * Otherwise, the stored value of <Rn> is UNPREDICTABLE. |
|
| 935 |
+ if (BIT_N(i, REG_NUM(i, 8))) |
|
| 936 |
+ printf("STMIA with Rb in Rlist\n");
|
|
| 937 |
+ |
|
| 938 |
+ for(j = 0; j<8; j++) |
|
| 939 |
+ {
|
|
| 940 |
+ if(BIT_N(i, j)) |
|
| 941 |
+ {
|
|
| 942 |
+ WRITE32(cpu->mem_if->data, adr, cpu->R[j]); |
|
| 943 |
+ c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_WRITE>(adr); |
|
| 944 |
+ adr += 4; |
|
| 945 |
+ erList = 0; //Register List isnt empty |
|
| 946 |
+ } |
|
| 947 |
+ } |
|
| 948 |
+ |
|
| 949 |
+ if (erList) |
|
| 950 |
+ printf("STMIA with Empty Rlist\n");
|
|
| 951 |
+ |
|
| 952 |
+ cpu->R[REG_NUM(i, 8)] = adr; |
|
| 953 |
+ return MMU_aluMemCycles<PROCNUM>(2, c); |
|
| 954 |
+} |
|
| 955 |
+ |
|
| 956 |
+TEMPLATE static uint32_t FASTCALL OP_LDMIA_THUMB(const uint32_t i) |
|
| 957 |
+{
|
|
| 958 |
+ uint32_t regIndex = REG_NUM(i, 8); |
|
| 959 |
+ uint32_t adr = cpu->R[regIndex]; |
|
| 960 |
+ uint32_t c = 0, j; |
|
| 961 |
+ uint32_t erList = 1; //Empty Register List |
|
| 962 |
+ |
|
| 963 |
+ //if (BIT_N(i, regIndex)) |
|
| 964 |
+ // printf("LDMIA with Rb in Rlist at %08X\n",cpu->instruct_adr);
|
|
| 965 |
+ |
|
| 966 |
+ for(j = 0; j<8; j++) |
|
| 967 |
+ {
|
|
| 968 |
+ if(BIT_N(i, j)) |
|
| 969 |
+ {
|
|
| 970 |
+ cpu->R[j] = READ32(cpu->mem_if->data, adr); |
|
| 971 |
+ c += MMU_memAccessCycles<PROCNUM,32,MMU_AD_READ>(adr); |
|
| 972 |
+ adr += 4; |
|
| 973 |
+ erList = 0; //Register List isnt empty |
|
| 974 |
+ } |
|
| 975 |
+ } |
|
| 976 |
+ |
|
| 977 |
+ if (erList) |
|
| 978 |
+ printf("LDMIA with Empty Rlist\n");
|
|
| 979 |
+ |
|
| 980 |
+ // ARM_REF: THUMB: Causes base register write-back, and is not optional |
|
| 981 |
+ // ARM_REF: If the base register <Rn> is specified in <registers>, the final value of <Rn> is the loaded value |
|
| 982 |
+ // (not the written-back value). |
|
| 983 |
+ if (!BIT_N(i, regIndex)) |
|
| 984 |
+ cpu->R[regIndex] = adr; |
|
| 985 |
+ |
|
| 986 |
+ return MMU_aluMemCycles<PROCNUM>(3, c); |
|
| 987 |
+} |
|
| 988 |
+ |
|
| 989 |
+//----------------------------------------------------------------------------- |
|
| 990 |
+// BKPT |
|
| 991 |
+//----------------------------------------------------------------------------- |
|
| 992 |
+ |
|
| 993 |
+TEMPLATE static uint32_t FASTCALL OP_BKPT_THUMB(const uint32_t) |
|
| 994 |
+{
|
|
| 995 |
+ // TODO |
|
| 996 |
+ printf("THUMB%c: Unimplemented opcode BKPT\n", PROCNUM?'7':'9');
|
|
| 997 |
+ return 1; |
|
| 998 |
+} |
|
| 999 |
+ |
|
| 1000 |
+//----------------------------------------------------------------------------- |
|
| 1001 |
+// SWI |
|
| 1002 |
+//----------------------------------------------------------------------------- |
|
| 1003 |
+ |
|
| 1004 |
+TEMPLATE static uint32_t FASTCALL OP_SWI_THUMB(const uint32_t i) |
|
| 1005 |
+{
|
|
| 1006 |
+ uint32_t swinum = i & 0xFF; |
|
| 1007 |
+ |
|
| 1008 |
+ //ideas-style debug prints (execute this SWI with the null terminated string address in R0) |
|
| 1009 |
+ if(swinum==0xFC) {
|
|
| 1010 |
+ //IdeasLog(cpu); |
|
| 1011 |
+ return 0; |
|
| 1012 |
+ } |
|
| 1013 |
+ |
|
| 1014 |
+ //if the user has changed the intVector to point away from the nds bioses, |
|
| 1015 |
+ //then it doesn't really make any sense to use the builtin SWI's since |
|
| 1016 |
+ //the bios ones aren't getting called anyway |
|
| 1017 |
+ bool bypassBuiltinSWI = |
|
| 1018 |
+ (cpu->intVector == 0x00000000 && PROCNUM==0) |
|
| 1019 |
+ || (cpu->intVector == 0xFFFF0000 && PROCNUM==1); |
|
| 1020 |
+ |
|
| 1021 |
+ if(cpu->swi_tab && !bypassBuiltinSWI) {
|
|
| 1022 |
+ //zero 25-dec-2008 - in arm, we were masking to 0x1F. |
|
| 1023 |
+ //this is probably safer since an invalid opcode could crash the emu |
|
| 1024 |
+ //zero 30-jun-2009 - but they say that the ideas 0xFF should crash the device... |
|
| 1025 |
+ //uint32_t swinum = cpu->instruction & 0xFF; |
|
| 1026 |
+ swinum &= 0x1F; |
|
| 1027 |
+ //printf("%d ARM SWI %d\n",PROCNUM,swinum);
|
|
| 1028 |
+ return cpu->swi_tab[swinum]() + 3; |
|
| 1029 |
+ } |
|
| 1030 |
+ else {
|
|
| 1031 |
+ /* we use an irq thats not in the irq tab, as |
|
| 1032 |
+ it was replaced due to a changed intVector */ |
|
| 1033 |
+ Status_Reg tmp = cpu->CPSR; |
|
| 1034 |
+ armcpu_switchMode(cpu, SVC); /* enter svc mode */ |
|
| 1035 |
+ cpu->R[14] = cpu->next_instruction; /* jump to swi Vector */ |
|
| 1036 |
+ cpu->SPSR = tmp; /* save old CPSR as new SPSR */ |
|
| 1037 |
+ cpu->CPSR.bits.T = 0; /* handle as ARM32 code */ |
|
| 1038 |
+ cpu->CPSR.bits.I = 1; |
|
| 1039 |
+ cpu->changeCPSR(); |
|
| 1040 |
+ cpu->R[15] = cpu->intVector + 0x08; |
|
| 1041 |
+ cpu->next_instruction = cpu->R[15]; |
|
| 1042 |
+ return 3; |
|
| 1043 |
+ } |
|
| 1044 |
+} |
|
| 1045 |
+ |
|
| 1046 |
+//----------------------------------------------------------------------------- |
|
| 1047 |
+// Branch |
|
| 1048 |
+//----------------------------------------------------------------------------- |
|
| 1049 |
+ |
|
| 1050 |
+#define SIGNEEXT_IMM11(i) (((i)&0x7FF) | (BIT10(i) * 0xFFFFF800)) |
|
| 1051 |
+ |
|
| 1052 |
+TEMPLATE static uint32_t FASTCALL OP_B_COND(const uint32_t i) |
|
| 1053 |
+{
|
|
| 1054 |
+ if(!TEST_COND((i>>8)&0xF, 0, cpu->CPSR)) |
|
| 1055 |
+ return 1; |
|
| 1056 |
+ |
|
| 1057 |
+ cpu->R[15] += (uint32_t)((int8_t)(i&0xFF))<<1; |
|
| 1058 |
+ cpu->next_instruction = cpu->R[15]; |
|
| 1059 |
+ return 3; |
|
| 1060 |
+} |
|
| 1061 |
+ |
|
| 1062 |
+TEMPLATE static uint32_t FASTCALL OP_B_UNCOND(const uint32_t i) |
|
| 1063 |
+{
|
|
| 1064 |
+ cpu->R[15] += (SIGNEEXT_IMM11(i)<<1); |
|
| 1065 |
+ cpu->next_instruction = cpu->R[15]; |
|
| 1066 |
+ return 1; |
|
| 1067 |
+} |
|
| 1068 |
+ |
|
| 1069 |
+TEMPLATE static uint32_t FASTCALL OP_BLX(const uint32_t i) |
|
| 1070 |
+{
|
|
| 1071 |
+ cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1))&0xFFFFFFFC; |
|
| 1072 |
+ cpu->R[14] = cpu->next_instruction | 1; |
|
| 1073 |
+ cpu->next_instruction = cpu->R[15]; |
|
| 1074 |
+ cpu->CPSR.bits.T = 0; |
|
| 1075 |
+ return 3; |
|
| 1076 |
+} |
|
| 1077 |
+ |
|
| 1078 |
+TEMPLATE static uint32_t FASTCALL OP_BL_10(const uint32_t i) |
|
| 1079 |
+{
|
|
| 1080 |
+ cpu->R[14] = cpu->R[15] + (SIGNEEXT_IMM11(i)<<12); |
|
| 1081 |
+ return 1; |
|
| 1082 |
+} |
|
| 1083 |
+ |
|
| 1084 |
+TEMPLATE static uint32_t FASTCALL OP_BL_11(const uint32_t i) |
|
| 1085 |
+{
|
|
| 1086 |
+ cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1)); |
|
| 1087 |
+ cpu->R[14] = cpu->next_instruction | 1; |
|
| 1088 |
+ cpu->next_instruction = cpu->R[15]; |
|
| 1089 |
+ return 4; |
|
| 1090 |
+} |
|
| 1091 |
+ |
|
| 1092 |
+TEMPLATE static uint32_t FASTCALL OP_BX_THUMB(const uint32_t i) |
|
| 1093 |
+{
|
|
| 1094 |
+ // When using PC as operand with BX opcode, switch to ARM state and jump to (instruct_adr+4) |
|
| 1095 |
+ // Reference: http://nocash.emubase.de/gbatek.htm#thumb5hiregisteroperationsbranchexchange |
|
| 1096 |
+ |
|
| 1097 |
+#if 0 |
|
| 1098 |
+ if (REG_POS(i, 3) == 15) |
|
| 1099 |
+ {
|
|
| 1100 |
+ cpu->CPSR.bits.T = 0; |
|
| 1101 |
+ cpu->R[15] &= 0xFFFFFFFC; |
|
| 1102 |
+ cpu->next_instruction = cpu->R[15]; |
|
| 1103 |
+ } |
|
| 1104 |
+ else |
|
| 1105 |
+ {
|
|
| 1106 |
+ uint32_t Rm = cpu->R[REG_POS(i, 3)]; |
|
| 1107 |
+ |
|
| 1108 |
+ cpu->CPSR.bits.T = BIT0(Rm); |
|
| 1109 |
+ cpu->R[15] = (Rm & 0xFFFFFFFE); |
|
| 1110 |
+ cpu->next_instruction = cpu->R[15]; |
|
| 1111 |
+ } |
|
| 1112 |
+#else |
|
| 1113 |
+ uint32_t Rm = cpu->R[REG_POS(i, 3)]; |
|
| 1114 |
+ //----- ARM_REF: |
|
| 1115 |
+ //----- Register 15 can be specified for <Rm>. If this is done, R15 is read as normal for Thumb code, |
|
| 1116 |
+ //----- that is, it is the address of the BX instruction itself plus 4. If the BX instruction is at a |
|
| 1117 |
+ //----- word-aligned address, this results in a branch to the next word, executing in ARM state. |
|
| 1118 |
+ //----- However, if the BX instruction is not at a word-aligned address, this means that the results of |
|
| 1119 |
+ //----- the instruction are UNPREDICTABLE (because the value read for R15 has bits[1:0]==0b10). |
|
| 1120 |
+ if (Rm == 15) |
|
| 1121 |
+ {
|
|
| 1122 |
+ printf("THUMB%c: BX using PC as operand\n", PROCNUM?'7':'9');
|
|
| 1123 |
+ //emu_halt(); |
|
| 1124 |
+ } |
|
| 1125 |
+ cpu->CPSR.bits.T = BIT0(Rm); |
|
| 1126 |
+ cpu->R[15] = (Rm & (0xFFFFFFFC|(1<<cpu->CPSR.bits.T))); |
|
| 1127 |
+ cpu->next_instruction = cpu->R[15]; |
|
| 1128 |
+#endif |
|
| 1129 |
+ return 3; |
|
| 1130 |
+} |
|
| 1131 |
+ |
|
| 1132 |
+TEMPLATE static uint32_t FASTCALL OP_BLX_THUMB(const uint32_t i) |
|
| 1133 |
+{
|
|
| 1134 |
+ uint32_t Rm = cpu->R[REG_POS(i, 3)]; |
|
| 1135 |
+ |
|
| 1136 |
+ cpu->CPSR.bits.T = BIT0(Rm); |
|
| 1137 |
+ //cpu->R[15] = (Rm & (0xFFFFFFFC|(1<<cpu->CPSR.bits.T))); |
|
| 1138 |
+ cpu->R[15] = Rm & 0xFFFFFFFE; |
|
| 1139 |
+ cpu->R[14] = cpu->next_instruction | 1; |
|
| 1140 |
+ cpu->next_instruction = cpu->R[15]; |
|
| 1141 |
+ |
|
| 1142 |
+ return 4; |
|
| 1143 |
+} |
|
| 1144 |
+ |
|
| 1145 |
+//----------------------------------------------------------------------------- |
|
| 1146 |
+// The End |
|
| 1147 |
+//----------------------------------------------------------------------------- |
|
| 1148 |
+ |
|
| 1149 |
+#define TABDECL(x) x<0> |
|
| 1150 |
+const ThumbOpFunc thumb_instructions_set_0[1024] = {
|
|
| 1151 |
+#include "thumb_tabdef.inc" |
|
| 1152 |
+}; |
|
| 1153 |
+#undef TABDECL |
|
| 1154 |
+ |
|
| 1155 |
+#define TABDECL(x) x<1> |
|
| 1156 |
+const ThumbOpFunc thumb_instructions_set_1[1024] = {
|
|
| 1157 |
+#include "thumb_tabdef.inc" |
|
| 1158 |
+}; |
|
| 1159 |
+#undef TABDECL |
|
| 1160 |
+ |
|
| 1161 |
+/*#define TABDECL(x) #x |
|
| 1162 |
+const char* thumb_instruction_names[1024] = {
|
|
| 1163 |
+#include "thumb_tabdef.inc" |
|
| 1164 |
+}; |
|
| 1165 |
+#undef TABDECL*/ |