diff options
Diffstat (limited to 'src/core/arm/interpreter/armemu.cpp')
| -rw-r--r-- | src/core/arm/interpreter/armemu.cpp | 89 |
1 files changed, 70 insertions, 19 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp index 610e04f10..e69789142 100644 --- a/src/core/arm/interpreter/armemu.cpp +++ b/src/core/arm/interpreter/armemu.cpp | |||
| @@ -5877,6 +5877,8 @@ L_stm_s_takeabort: | |||
| 5877 | state->Cpsr &= ~(1 << 18); | 5877 | state->Cpsr &= ~(1 << 18); |
| 5878 | state->Cpsr &= ~(1 << 19); | 5878 | state->Cpsr &= ~(1 << 19); |
| 5879 | } | 5879 | } |
| 5880 | |||
| 5881 | ARMul_CPSRAltered(state); | ||
| 5880 | return 1; | 5882 | return 1; |
| 5881 | } | 5883 | } |
| 5882 | // SADD8/SSUB8 | 5884 | // SADD8/SSUB8 |
| @@ -5948,6 +5950,7 @@ L_stm_s_takeabort: | |||
| 5948 | state->Cpsr &= ~(1 << 19); | 5950 | state->Cpsr &= ~(1 << 19); |
| 5949 | } | 5951 | } |
| 5950 | 5952 | ||
| 5953 | ARMul_CPSRAltered(state); | ||
| 5951 | state->Reg[rd_idx] = (lo_val1 | lo_val2 << 8 | hi_val1 << 16 | hi_val2 << 24); | 5954 | state->Reg[rd_idx] = (lo_val1 | lo_val2 << 8 | hi_val1 << 16 | hi_val2 << 24); |
| 5952 | return 1; | 5955 | return 1; |
| 5953 | } | 5956 | } |
| @@ -6024,15 +6027,33 @@ L_stm_s_takeabort: | |||
| 6024 | if ((instr & 0x0F0) == 0x070) { // USUB16 | 6027 | if ((instr & 0x0F0) == 0x070) { // USUB16 |
| 6025 | h1 = ((u16)from - (u16)to); | 6028 | h1 = ((u16)from - (u16)to); |
| 6026 | h2 = ((u16)(from >> 16) - (u16)(to >> 16)); | 6029 | h2 = ((u16)(from >> 16) - (u16)(to >> 16)); |
| 6027 | if (!(h1 & 0xffff0000)) state->Cpsr |= (3 << 16); | 6030 | |
| 6028 | if (!(h2 & 0xffff0000)) state->Cpsr |= (3 << 18); | 6031 | if (!(h1 & 0xffff0000)) |
| 6032 | state->Cpsr |= (3 << 16); | ||
| 6033 | else | ||
| 6034 | state->Cpsr &= ~(3 << 16); | ||
| 6035 | |||
| 6036 | if (!(h2 & 0xffff0000)) | ||
| 6037 | state->Cpsr |= (3 << 18); | ||
| 6038 | else | ||
| 6039 | state->Cpsr &= ~(3 << 18); | ||
| 6029 | } | 6040 | } |
| 6030 | else { // UADD16 | 6041 | else { // UADD16 |
| 6031 | h1 = ((u16)from + (u16)to); | 6042 | h1 = ((u16)from + (u16)to); |
| 6032 | h2 = ((u16)(from >> 16) + (u16)(to >> 16)); | 6043 | h2 = ((u16)(from >> 16) + (u16)(to >> 16)); |
| 6033 | if (h1 & 0xffff0000) state->Cpsr |= (3 << 16); | 6044 | |
| 6034 | if (h2 & 0xffff0000) state->Cpsr |= (3 << 18); | 6045 | if (h1 & 0xffff0000) |
| 6046 | state->Cpsr |= (3 << 16); | ||
| 6047 | else | ||
| 6048 | state->Cpsr &= ~(3 << 16); | ||
| 6049 | |||
| 6050 | if (h2 & 0xffff0000) | ||
| 6051 | state->Cpsr |= (3 << 18); | ||
| 6052 | else | ||
| 6053 | state->Cpsr &= ~(3 << 18); | ||
| 6035 | } | 6054 | } |
| 6055 | |||
| 6056 | ARMul_CPSRAltered(state); | ||
| 6036 | state->Reg[rd] = (u32)((h1 & 0xffff) | ((h2 & 0xffff) << 16)); | 6057 | state->Reg[rd] = (u32)((h1 & 0xffff) | ((h2 & 0xffff) << 16)); |
| 6037 | return 1; | 6058 | return 1; |
| 6038 | } | 6059 | } |
| @@ -6045,10 +6066,26 @@ L_stm_s_takeabort: | |||
| 6045 | b2 = ((u8)(from >> 8) - (u8)(to >> 8)); | 6066 | b2 = ((u8)(from >> 8) - (u8)(to >> 8)); |
| 6046 | b3 = ((u8)(from >> 16) - (u8)(to >> 16)); | 6067 | b3 = ((u8)(from >> 16) - (u8)(to >> 16)); |
| 6047 | b4 = ((u8)(from >> 24) - (u8)(to >> 24)); | 6068 | b4 = ((u8)(from >> 24) - (u8)(to >> 24)); |
| 6048 | if (!(b1 & 0xffffff00)) state->Cpsr |= (1 << 16); | 6069 | |
| 6049 | if (!(b2 & 0xffffff00)) state->Cpsr |= (1 << 17); | 6070 | if (!(b1 & 0xffffff00)) |
| 6050 | if (!(b3 & 0xffffff00)) state->Cpsr |= (1 << 18); | 6071 | state->Cpsr |= (1 << 16); |
| 6051 | if (!(b4 & 0xffffff00)) state->Cpsr |= (1 << 19); | 6072 | else |
| 6073 | state->Cpsr &= ~(1 << 16); | ||
| 6074 | |||
| 6075 | if (!(b2 & 0xffffff00)) | ||
| 6076 | state->Cpsr |= (1 << 17); | ||
| 6077 | else | ||
| 6078 | state->Cpsr &= ~(1 << 17); | ||
| 6079 | |||
| 6080 | if (!(b3 & 0xffffff00)) | ||
| 6081 | state->Cpsr |= (1 << 18); | ||
| 6082 | else | ||
| 6083 | state->Cpsr &= ~(1 << 18); | ||
| 6084 | |||
| 6085 | if (!(b4 & 0xffffff00)) | ||
| 6086 | state->Cpsr |= (1 << 19); | ||
| 6087 | else | ||
| 6088 | state->Cpsr &= ~(1 << 19); | ||
| 6052 | } | 6089 | } |
| 6053 | else { // UADD8 | 6090 | else { // UADD8 |
| 6054 | b1 = ((u8)from + (u8)to); | 6091 | b1 = ((u8)from + (u8)to); |
| @@ -6071,13 +6108,13 @@ L_stm_s_takeabort: | |||
| 6071 | else | 6108 | else |
| 6072 | state->Cpsr &= ~(1 << 18); | 6109 | state->Cpsr &= ~(1 << 18); |
| 6073 | 6110 | ||
| 6074 | |||
| 6075 | if (b4 & 0xffffff00) | 6111 | if (b4 & 0xffffff00) |
| 6076 | state->Cpsr |= (1 << 19); | 6112 | state->Cpsr |= (1 << 19); |
| 6077 | else | 6113 | else |
| 6078 | state->Cpsr &= ~(1 << 19); | 6114 | state->Cpsr &= ~(1 << 19); |
| 6079 | } | 6115 | } |
| 6080 | 6116 | ||
| 6117 | ARMul_CPSRAltered(state); | ||
| 6081 | state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24); | 6118 | state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24); |
| 6082 | return 1; | 6119 | return 1; |
| 6083 | } | 6120 | } |
| @@ -6116,7 +6153,7 @@ L_stm_s_takeabort: | |||
| 6116 | u32 rm = (instr >> 0) & 0xF; | 6153 | u32 rm = (instr >> 0) & 0xF; |
| 6117 | u32 from = state->Reg[rn]; | 6154 | u32 from = state->Reg[rn]; |
| 6118 | u32 to = state->Reg[rm]; | 6155 | u32 to = state->Reg[rm]; |
| 6119 | u32 cpsr = state->Cpsr; | 6156 | u32 cpsr = ARMul_GetCPSR(state); |
| 6120 | if ((instr & 0xFF0) == 0xFB0) { // SEL | 6157 | if ((instr & 0xFF0) == 0xFB0) { // SEL |
| 6121 | u32 result; | 6158 | u32 result; |
| 6122 | if (cpsr & (1 << 16)) | 6159 | if (cpsr & (1 << 16)) |
| @@ -6172,16 +6209,23 @@ L_stm_s_takeabort: | |||
| 6172 | s16 rn_lo = (state->Reg[rn_idx]); | 6209 | s16 rn_lo = (state->Reg[rn_idx]); |
| 6173 | s16 rn_hi = (state->Reg[rn_idx] >> 16); | 6210 | s16 rn_hi = (state->Reg[rn_idx] >> 16); |
| 6174 | 6211 | ||
| 6175 | if (rn_lo > max) | 6212 | if (rn_lo > max) { |
| 6176 | rn_lo = max; | 6213 | rn_lo = max; |
| 6177 | else if (rn_lo < min) | 6214 | state->Cpsr |= (1 << 27); |
| 6215 | } else if (rn_lo < min) { | ||
| 6178 | rn_lo = min; | 6216 | rn_lo = min; |
| 6217 | state->Cpsr |= (1 << 27); | ||
| 6218 | } | ||
| 6179 | 6219 | ||
| 6180 | if (rn_hi > max) | 6220 | if (rn_hi > max) { |
| 6181 | rn_hi = max; | 6221 | rn_hi = max; |
| 6182 | else if (rn_hi < min) | 6222 | state->Cpsr |= (1 << 27); |
| 6223 | } else if (rn_hi < min) { | ||
| 6183 | rn_hi = min; | 6224 | rn_hi = min; |
| 6225 | state->Cpsr |= (1 << 27); | ||
| 6226 | } | ||
| 6184 | 6227 | ||
| 6228 | ARMul_CPSRAltered(state); | ||
| 6185 | state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16); | 6229 | state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16); |
| 6186 | return 1; | 6230 | return 1; |
| 6187 | } | 6231 | } |
| @@ -6313,16 +6357,23 @@ L_stm_s_takeabort: | |||
| 6313 | s16 rn_lo = (state->Reg[rn_idx]); | 6357 | s16 rn_lo = (state->Reg[rn_idx]); |
| 6314 | s16 rn_hi = (state->Reg[rn_idx] >> 16); | 6358 | s16 rn_hi = (state->Reg[rn_idx] >> 16); |
| 6315 | 6359 | ||
| 6316 | if (max < rn_lo) | 6360 | if (max < rn_lo) { |
| 6317 | rn_lo = max; | 6361 | rn_lo = max; |
| 6318 | else if (rn_lo < 0) | 6362 | state->Cpsr |= (1 << 27); |
| 6363 | } else if (rn_lo < 0) { | ||
| 6319 | rn_lo = 0; | 6364 | rn_lo = 0; |
| 6365 | state->Cpsr |= (1 << 27); | ||
| 6366 | } | ||
| 6320 | 6367 | ||
| 6321 | if (max < rn_hi) | 6368 | if (max < rn_hi) { |
| 6322 | rn_hi = max; | 6369 | rn_hi = max; |
| 6323 | else if (rn_hi < 0) | 6370 | state->Cpsr |= (1 << 27); |
| 6371 | } else if (rn_hi < 0) { | ||
| 6324 | rn_hi = 0; | 6372 | rn_hi = 0; |
| 6325 | 6373 | state->Cpsr |= (1 << 27); | |
| 6374 | } | ||
| 6375 | |||
| 6376 | ARMul_CPSRAltered(state); | ||
| 6326 | state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF); | 6377 | state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF); |
| 6327 | return 1; | 6378 | return 1; |
| 6328 | } | 6379 | } |