diff options
| author | 2014-12-24 07:56:57 -0500 | |
|---|---|---|
| committer | 2014-12-24 07:56:57 -0500 | |
| commit | 6b7808e412ca9db41ac194a0a0e35d515cb1d38a (patch) | |
| tree | 8ba98498ae50836a01ddaea65182160c702c8a51 /src | |
| parent | Merge pull request #328 from archshift/writeable (diff) | |
| download | yuzu-6b7808e412ca9db41ac194a0a0e35d515cb1d38a.tar.gz yuzu-6b7808e412ca9db41ac194a0a0e35d515cb1d38a.tar.xz yuzu-6b7808e412ca9db41ac194a0a0e35d515cb1d38a.zip | |
armemu: Fix GE/Q flag setting semantics
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/interpreter/armemu.cpp | 118 |
1 files changed, 56 insertions, 62 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp index b2f671f94..c4c09d1fb 100644 --- a/src/core/arm/interpreter/armemu.cpp +++ b/src/core/arm/interpreter/armemu.cpp | |||
| @@ -5863,22 +5863,21 @@ L_stm_s_takeabort: | |||
| 5863 | state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); | 5863 | state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); |
| 5864 | 5864 | ||
| 5865 | if (lo_result >= 0) { | 5865 | if (lo_result >= 0) { |
| 5866 | state->Cpsr |= (1 << 16); | 5866 | state->GEFlag |= (1 << 16); |
| 5867 | state->Cpsr |= (1 << 17); | 5867 | state->GEFlag |= (1 << 17); |
| 5868 | } else { | 5868 | } else { |
| 5869 | state->Cpsr &= ~(1 << 16); | 5869 | state->GEFlag &= ~(1 << 16); |
| 5870 | state->Cpsr &= ~(1 << 17); | 5870 | state->GEFlag &= ~(1 << 17); |
| 5871 | } | 5871 | } |
| 5872 | 5872 | ||
| 5873 | if (hi_result >= 0) { | 5873 | if (hi_result >= 0) { |
| 5874 | state->Cpsr |= (1 << 18); | 5874 | state->GEFlag |= (1 << 18); |
| 5875 | state->Cpsr |= (1 << 19); | 5875 | state->GEFlag |= (1 << 19); |
| 5876 | } else { | 5876 | } else { |
| 5877 | state->Cpsr &= ~(1 << 18); | 5877 | state->GEFlag &= ~(1 << 18); |
| 5878 | state->Cpsr &= ~(1 << 19); | 5878 | state->GEFlag &= ~(1 << 19); |
| 5879 | } | 5879 | } |
| 5880 | 5880 | ||
| 5881 | ARMul_CPSRAltered(state); | ||
| 5882 | return 1; | 5881 | return 1; |
| 5883 | } | 5882 | } |
| 5884 | // SADD8/SSUB8 | 5883 | // SADD8/SSUB8 |
| @@ -5903,24 +5902,24 @@ L_stm_s_takeabort: | |||
| 5903 | hi_val2 = (u8)(((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF)); | 5902 | hi_val2 = (u8)(((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF)); |
| 5904 | 5903 | ||
| 5905 | if (lo_val1 & 0x80) | 5904 | if (lo_val1 & 0x80) |
| 5906 | state->Cpsr |= (1 << 16); | 5905 | state->GEFlag |= (1 << 16); |
| 5907 | else | 5906 | else |
| 5908 | state->Cpsr &= ~(1 << 16); | 5907 | state->GEFlag &= ~(1 << 16); |
| 5909 | 5908 | ||
| 5910 | if (lo_val2 & 0x80) | 5909 | if (lo_val2 & 0x80) |
| 5911 | state->Cpsr |= (1 << 17); | 5910 | state->GEFlag |= (1 << 17); |
| 5912 | else | 5911 | else |
| 5913 | state->Cpsr &= ~(1 << 17); | 5912 | state->GEFlag &= ~(1 << 17); |
| 5914 | 5913 | ||
| 5915 | if (hi_val1 & 0x80) | 5914 | if (hi_val1 & 0x80) |
| 5916 | state->Cpsr |= (1 << 18); | 5915 | state->GEFlag |= (1 << 18); |
| 5917 | else | 5916 | else |
| 5918 | state->Cpsr &= ~(1 << 18); | 5917 | state->GEFlag &= ~(1 << 18); |
| 5919 | 5918 | ||
| 5920 | if (hi_val2 & 0x80) | 5919 | if (hi_val2 & 0x80) |
| 5921 | state->Cpsr |= (1 << 19); | 5920 | state->GEFlag |= (1 << 19); |
| 5922 | else | 5921 | else |
| 5923 | state->Cpsr &= ~(1 << 19); | 5922 | state->GEFlag &= ~(1 << 19); |
| 5924 | } | 5923 | } |
| 5925 | // SSUB8 | 5924 | // SSUB8 |
| 5926 | else { | 5925 | else { |
| @@ -5930,27 +5929,26 @@ L_stm_s_takeabort: | |||
| 5930 | hi_val2 = (u8)(((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF)); | 5929 | hi_val2 = (u8)(((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF)); |
| 5931 | 5930 | ||
| 5932 | if (!(lo_val1 & 0x80)) | 5931 | if (!(lo_val1 & 0x80)) |
| 5933 | state->Cpsr |= (1 << 16); | 5932 | state->GEFlag |= (1 << 16); |
| 5934 | else | 5933 | else |
| 5935 | state->Cpsr &= ~(1 << 16); | 5934 | state->GEFlag &= ~(1 << 16); |
| 5936 | 5935 | ||
| 5937 | if (!(lo_val2 & 0x80)) | 5936 | if (!(lo_val2 & 0x80)) |
| 5938 | state->Cpsr |= (1 << 17); | 5937 | state->GEFlag |= (1 << 17); |
| 5939 | else | 5938 | else |
| 5940 | state->Cpsr &= ~(1 << 17); | 5939 | state->GEFlag &= ~(1 << 17); |
| 5941 | 5940 | ||
| 5942 | if (!(hi_val1 & 0x80)) | 5941 | if (!(hi_val1 & 0x80)) |
| 5943 | state->Cpsr |= (1 << 18); | 5942 | state->GEFlag |= (1 << 18); |
| 5944 | else | 5943 | else |
| 5945 | state->Cpsr &= ~(1 << 18); | 5944 | state->GEFlag &= ~(1 << 18); |
| 5946 | 5945 | ||
| 5947 | if (!(hi_val2 & 0x80)) | 5946 | if (!(hi_val2 & 0x80)) |
| 5948 | state->Cpsr |= (1 << 19); | 5947 | state->GEFlag |= (1 << 19); |
| 5949 | else | 5948 | else |
| 5950 | state->Cpsr &= ~(1 << 19); | 5949 | state->GEFlag &= ~(1 << 19); |
| 5951 | } | 5950 | } |
| 5952 | 5951 | ||
| 5953 | ARMul_CPSRAltered(state); | ||
| 5954 | state->Reg[rd_idx] = (lo_val1 | lo_val2 << 8 | hi_val1 << 16 | hi_val2 << 24); | 5952 | state->Reg[rd_idx] = (lo_val1 | lo_val2 << 8 | hi_val1 << 16 | hi_val2 << 24); |
| 5955 | return 1; | 5953 | return 1; |
| 5956 | } | 5954 | } |
| @@ -6029,31 +6027,30 @@ L_stm_s_takeabort: | |||
| 6029 | h2 = ((u16)(from >> 16) - (u16)(to >> 16)); | 6027 | h2 = ((u16)(from >> 16) - (u16)(to >> 16)); |
| 6030 | 6028 | ||
| 6031 | if (!(h1 & 0xffff0000)) | 6029 | if (!(h1 & 0xffff0000)) |
| 6032 | state->Cpsr |= (3 << 16); | 6030 | state->GEFlag |= (3 << 16); |
| 6033 | else | 6031 | else |
| 6034 | state->Cpsr &= ~(3 << 16); | 6032 | state->GEFlag &= ~(3 << 16); |
| 6035 | 6033 | ||
| 6036 | if (!(h2 & 0xffff0000)) | 6034 | if (!(h2 & 0xffff0000)) |
| 6037 | state->Cpsr |= (3 << 18); | 6035 | state->GEFlag |= (3 << 18); |
| 6038 | else | 6036 | else |
| 6039 | state->Cpsr &= ~(3 << 18); | 6037 | state->GEFlag &= ~(3 << 18); |
| 6040 | } | 6038 | } |
| 6041 | else { // UADD16 | 6039 | else { // UADD16 |
| 6042 | h1 = ((u16)from + (u16)to); | 6040 | h1 = ((u16)from + (u16)to); |
| 6043 | h2 = ((u16)(from >> 16) + (u16)(to >> 16)); | 6041 | h2 = ((u16)(from >> 16) + (u16)(to >> 16)); |
| 6044 | 6042 | ||
| 6045 | if (h1 & 0xffff0000) | 6043 | if (h1 & 0xffff0000) |
| 6046 | state->Cpsr |= (3 << 16); | 6044 | state->GEFlag |= (3 << 16); |
| 6047 | else | 6045 | else |
| 6048 | state->Cpsr &= ~(3 << 16); | 6046 | state->GEFlag &= ~(3 << 16); |
| 6049 | 6047 | ||
| 6050 | if (h2 & 0xffff0000) | 6048 | if (h2 & 0xffff0000) |
| 6051 | state->Cpsr |= (3 << 18); | 6049 | state->GEFlag |= (3 << 18); |
| 6052 | else | 6050 | else |
| 6053 | state->Cpsr &= ~(3 << 18); | 6051 | state->GEFlag &= ~(3 << 18); |
| 6054 | } | 6052 | } |
| 6055 | 6053 | ||
| 6056 | ARMul_CPSRAltered(state); | ||
| 6057 | state->Reg[rd] = (u32)((h1 & 0xffff) | ((h2 & 0xffff) << 16)); | 6054 | state->Reg[rd] = (u32)((h1 & 0xffff) | ((h2 & 0xffff) << 16)); |
| 6058 | return 1; | 6055 | return 1; |
| 6059 | } | 6056 | } |
| @@ -6068,24 +6065,24 @@ L_stm_s_takeabort: | |||
| 6068 | b4 = ((u8)(from >> 24) - (u8)(to >> 24)); | 6065 | b4 = ((u8)(from >> 24) - (u8)(to >> 24)); |
| 6069 | 6066 | ||
| 6070 | if (!(b1 & 0xffffff00)) | 6067 | if (!(b1 & 0xffffff00)) |
| 6071 | state->Cpsr |= (1 << 16); | 6068 | state->GEFlag |= (1 << 16); |
| 6072 | else | 6069 | else |
| 6073 | state->Cpsr &= ~(1 << 16); | 6070 | state->GEFlag &= ~(1 << 16); |
| 6074 | 6071 | ||
| 6075 | if (!(b2 & 0xffffff00)) | 6072 | if (!(b2 & 0xffffff00)) |
| 6076 | state->Cpsr |= (1 << 17); | 6073 | state->GEFlag |= (1 << 17); |
| 6077 | else | 6074 | else |
| 6078 | state->Cpsr &= ~(1 << 17); | 6075 | state->GEFlag &= ~(1 << 17); |
| 6079 | 6076 | ||
| 6080 | if (!(b3 & 0xffffff00)) | 6077 | if (!(b3 & 0xffffff00)) |
| 6081 | state->Cpsr |= (1 << 18); | 6078 | state->GEFlag |= (1 << 18); |
| 6082 | else | 6079 | else |
| 6083 | state->Cpsr &= ~(1 << 18); | 6080 | state->GEFlag &= ~(1 << 18); |
| 6084 | 6081 | ||
| 6085 | if (!(b4 & 0xffffff00)) | 6082 | if (!(b4 & 0xffffff00)) |
| 6086 | state->Cpsr |= (1 << 19); | 6083 | state->GEFlag |= (1 << 19); |
| 6087 | else | 6084 | else |
| 6088 | state->Cpsr &= ~(1 << 19); | 6085 | state->GEFlag &= ~(1 << 19); |
| 6089 | } | 6086 | } |
| 6090 | else { // UADD8 | 6087 | else { // UADD8 |
| 6091 | b1 = ((u8)from + (u8)to); | 6088 | b1 = ((u8)from + (u8)to); |
| @@ -6094,27 +6091,26 @@ L_stm_s_takeabort: | |||
| 6094 | b4 = ((u8)(from >> 24) + (u8)(to >> 24)); | 6091 | b4 = ((u8)(from >> 24) + (u8)(to >> 24)); |
| 6095 | 6092 | ||
| 6096 | if (b1 & 0xffffff00) | 6093 | if (b1 & 0xffffff00) |
| 6097 | state->Cpsr |= (1 << 16); | 6094 | state->GEFlag |= (1 << 16); |
| 6098 | else | 6095 | else |
| 6099 | state->Cpsr &= ~(1 << 16); | 6096 | state->GEFlag &= ~(1 << 16); |
| 6100 | 6097 | ||
| 6101 | if (b2 & 0xffffff00) | 6098 | if (b2 & 0xffffff00) |
| 6102 | state->Cpsr |= (1 << 17); | 6099 | state->GEFlag |= (1 << 17); |
| 6103 | else | 6100 | else |
| 6104 | state->Cpsr &= ~(1 << 17); | 6101 | state->GEFlag &= ~(1 << 17); |
| 6105 | 6102 | ||
| 6106 | if (b3 & 0xffffff00) | 6103 | if (b3 & 0xffffff00) |
| 6107 | state->Cpsr |= (1 << 18); | 6104 | state->GEFlag |= (1 << 18); |
| 6108 | else | 6105 | else |
| 6109 | state->Cpsr &= ~(1 << 18); | 6106 | state->GEFlag &= ~(1 << 18); |
| 6110 | 6107 | ||
| 6111 | if (b4 & 0xffffff00) | 6108 | if (b4 & 0xffffff00) |
| 6112 | state->Cpsr |= (1 << 19); | 6109 | state->GEFlag |= (1 << 19); |
| 6113 | else | 6110 | else |
| 6114 | state->Cpsr &= ~(1 << 19); | 6111 | state->GEFlag &= ~(1 << 19); |
| 6115 | } | 6112 | } |
| 6116 | 6113 | ||
| 6117 | ARMul_CPSRAltered(state); | ||
| 6118 | state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24); | 6114 | state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24); |
| 6119 | return 1; | 6115 | return 1; |
| 6120 | } | 6116 | } |
| @@ -6211,21 +6207,20 @@ L_stm_s_takeabort: | |||
| 6211 | 6207 | ||
| 6212 | if (rn_lo > max) { | 6208 | if (rn_lo > max) { |
| 6213 | rn_lo = max; | 6209 | rn_lo = max; |
| 6214 | state->Cpsr |= (1 << 27); | 6210 | SETQ; |
| 6215 | } else if (rn_lo < min) { | 6211 | } else if (rn_lo < min) { |
| 6216 | rn_lo = min; | 6212 | rn_lo = min; |
| 6217 | state->Cpsr |= (1 << 27); | 6213 | SETQ; |
| 6218 | } | 6214 | } |
| 6219 | 6215 | ||
| 6220 | if (rn_hi > max) { | 6216 | if (rn_hi > max) { |
| 6221 | rn_hi = max; | 6217 | rn_hi = max; |
| 6222 | state->Cpsr |= (1 << 27); | 6218 | SETQ; |
| 6223 | } else if (rn_hi < min) { | 6219 | } else if (rn_hi < min) { |
| 6224 | rn_hi = min; | 6220 | rn_hi = min; |
| 6225 | state->Cpsr |= (1 << 27); | 6221 | SETQ; |
| 6226 | } | 6222 | } |
| 6227 | 6223 | ||
| 6228 | ARMul_CPSRAltered(state); | ||
| 6229 | state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16); | 6224 | state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16); |
| 6230 | return 1; | 6225 | return 1; |
| 6231 | } | 6226 | } |
| @@ -6359,21 +6354,20 @@ L_stm_s_takeabort: | |||
| 6359 | 6354 | ||
| 6360 | if (max < rn_lo) { | 6355 | if (max < rn_lo) { |
| 6361 | rn_lo = max; | 6356 | rn_lo = max; |
| 6362 | state->Cpsr |= (1 << 27); | 6357 | SETQ; |
| 6363 | } else if (rn_lo < 0) { | 6358 | } else if (rn_lo < 0) { |
| 6364 | rn_lo = 0; | 6359 | rn_lo = 0; |
| 6365 | state->Cpsr |= (1 << 27); | 6360 | SETQ; |
| 6366 | } | 6361 | } |
| 6367 | 6362 | ||
| 6368 | if (max < rn_hi) { | 6363 | if (max < rn_hi) { |
| 6369 | rn_hi = max; | 6364 | rn_hi = max; |
| 6370 | state->Cpsr |= (1 << 27); | 6365 | SETQ; |
| 6371 | } else if (rn_hi < 0) { | 6366 | } else if (rn_hi < 0) { |
| 6372 | rn_hi = 0; | 6367 | rn_hi = 0; |
| 6373 | state->Cpsr |= (1 << 27); | 6368 | SETQ; |
| 6374 | } | 6369 | } |
| 6375 | 6370 | ||
| 6376 | ARMul_CPSRAltered(state); | ||
| 6377 | state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF); | 6371 | state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF); |
| 6378 | return 1; | 6372 | return 1; |
| 6379 | } | 6373 | } |