diff options
| author | 2014-12-23 09:43:46 -0500 | |
|---|---|---|
| committer | 2014-12-23 09:43:46 -0500 | |
| commit | 53447da142e4466fc2e509d19c15423ba7595fac (patch) | |
| tree | ba4f97d9efd0db16d14e49e42f71a6365dd531fe /src | |
| parent | Merge pull request #275 from yuriks/cmake-clean (diff) | |
| parent | armemu: Properly set the Q flag for SSAT16/USAT16 upon saturation. (diff) | |
| download | yuzu-53447da142e4466fc2e509d19c15423ba7595fac.tar.gz yuzu-53447da142e4466fc2e509d19c15423ba7595fac.tar.xz yuzu-53447da142e4466fc2e509d19c15423ba7595fac.zip | |
Merge pull request #335 from lioncash/cpsrcreate
armemu: Emulate the GE and Q flags.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/interpreter/armemu.cpp | 89 | ||||
| -rw-r--r-- | src/core/arm/interpreter/armsupp.cpp | 5 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armdefs.h | 2 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armemu.h | 7 |
4 files changed, 78 insertions, 25 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 | } |
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp index 30519f216..b31c0ea24 100644 --- a/src/core/arm/interpreter/armsupp.cpp +++ b/src/core/arm/interpreter/armsupp.cpp | |||
| @@ -227,8 +227,9 @@ ARMul_CPSRAltered (ARMul_State * state) | |||
| 227 | //state->Cpsr &= ~CBIT; | 227 | //state->Cpsr &= ~CBIT; |
| 228 | ASSIGNV ((state->Cpsr & VBIT) != 0); | 228 | ASSIGNV ((state->Cpsr & VBIT) != 0); |
| 229 | //state->Cpsr &= ~VBIT; | 229 | //state->Cpsr &= ~VBIT; |
| 230 | ASSIGNS ((state->Cpsr & SBIT) != 0); | 230 | ASSIGNQ ((state->Cpsr & QBIT) != 0); |
| 231 | //state->Cpsr &= ~SBIT; | 231 | //state->Cpsr &= ~QBIT; |
| 232 | state->GEFlag = (state->Cpsr & 0x000F0000); | ||
| 232 | #ifdef MODET | 233 | #ifdef MODET |
| 233 | ASSIGNT ((state->Cpsr & TBIT) != 0); | 234 | ASSIGNT ((state->Cpsr & TBIT) != 0); |
| 234 | //state->Cpsr &= ~TBIT; | 235 | //state->Cpsr &= ~TBIT; |
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h index 28a4a0db4..34eb5aaf7 100644 --- a/src/core/arm/skyeye_common/armdefs.h +++ b/src/core/arm/skyeye_common/armdefs.h | |||
| @@ -198,7 +198,7 @@ struct ARMul_State | |||
| 198 | //ARMword translate_pc; | 198 | //ARMword translate_pc; |
| 199 | 199 | ||
| 200 | /* add armv6 flags dyf:2010-08-09 */ | 200 | /* add armv6 flags dyf:2010-08-09 */ |
| 201 | ARMword GEFlag, EFlag, AFlag, QFlags; | 201 | ARMword GEFlag, EFlag, AFlag, QFlag; |
| 202 | //chy:2003-08-19, used in arm v5e|xscale | 202 | //chy:2003-08-19, used in arm v5e|xscale |
| 203 | ARMword SFlag; | 203 | ARMword SFlag; |
| 204 | #ifdef MODET | 204 | #ifdef MODET |
diff --git a/src/core/arm/skyeye_common/armemu.h b/src/core/arm/skyeye_common/armemu.h index 7f7c0e682..e1b286f0f 100644 --- a/src/core/arm/skyeye_common/armemu.h +++ b/src/core/arm/skyeye_common/armemu.h | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | #define ZBIT (1L << 30) | 34 | #define ZBIT (1L << 30) |
| 35 | #define CBIT (1L << 29) | 35 | #define CBIT (1L << 29) |
| 36 | #define VBIT (1L << 28) | 36 | #define VBIT (1L << 28) |
| 37 | #define SBIT (1L << 27) | 37 | #define QBIT (1L << 27) |
| 38 | #define IBIT (1L << 7) | 38 | #define IBIT (1L << 7) |
| 39 | #define FBIT (1L << 6) | 39 | #define FBIT (1L << 6) |
| 40 | #define IFBITS (3L << 6) | 40 | #define IFBITS (3L << 6) |
| @@ -156,13 +156,14 @@ | |||
| 156 | #define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS)) | 156 | #define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS)) |
| 157 | #define R15MODE (state->Reg[15] & R15MODEBITS) | 157 | #define R15MODE (state->Reg[15] & R15MODEBITS) |
| 158 | 158 | ||
| 159 | #define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28) | (SFLAG << 27)) | 159 | #define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28) | (QFLAG << 27)) |
| 160 | #define EINT (IFFLAGS << 6) | 160 | #define EINT (IFFLAGS << 6) |
| 161 | #define ER15INT (IFFLAGS << 26) | 161 | #define ER15INT (IFFLAGS << 26) |
| 162 | #define EMODE (state->Mode) | 162 | #define EMODE (state->Mode) |
| 163 | #define EGEBITS (state->GEFlag & 0x000F0000) | ||
| 163 | 164 | ||
| 164 | #ifdef MODET | 165 | #ifdef MODET |
| 165 | #define CPSR (ECC | EINT | EMODE | (TFLAG << 5)) | 166 | #define CPSR (ECC | EGEBITS | (EFLAG << 9) | (AFLAG << 8) | EINT | (TFLAG << 5) | EMODE) |
| 166 | #else | 167 | #else |
| 167 | #define CPSR (ECC | EINT | EMODE) | 168 | #define CPSR (ECC | EINT | EMODE) |
| 168 | #endif | 169 | #endif |