summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2022-10-04 15:52:39 -0700
committerGravatar GitHub2022-10-04 15:52:39 -0700
commit92c0ad23eb3336d7f395968ace9aa4cd18e1d1b5 (patch)
tree856d7ba1596ec74c173ae33564ee05b67010a856 /src
parentMerge pull request #8955 from german77/amiibo-rewrite (diff)
parentmacro_jit_x64: fix miscompilation of bit extraction operations (diff)
downloadyuzu-92c0ad23eb3336d7f395968ace9aa4cd18e1d1b5.tar.gz
yuzu-92c0ad23eb3336d7f395968ace9aa4cd18e1d1b5.tar.xz
yuzu-92c0ad23eb3336d7f395968ace9aa4cd18e1d1b5.zip
Merge pull request #9010 from liamwhite/buttwise
macro_jit_x64: fix miscompilation of bit extraction operations
Diffstat (limited to 'src')
-rw-r--r--src/video_core/macro/macro_jit_x64.cpp46
1 files changed, 9 insertions, 37 deletions
diff --git a/src/video_core/macro/macro_jit_x64.cpp b/src/video_core/macro/macro_jit_x64.cpp
index aca25d902..3b55228b9 100644
--- a/src/video_core/macro/macro_jit_x64.cpp
+++ b/src/video_core/macro/macro_jit_x64.cpp
@@ -279,28 +279,13 @@ void MacroJITx64Impl::Compile_ExtractInsert(Macro::Opcode opcode) {
279 auto dst = Compile_GetRegister(opcode.src_a, RESULT); 279 auto dst = Compile_GetRegister(opcode.src_a, RESULT);
280 auto src = Compile_GetRegister(opcode.src_b, eax); 280 auto src = Compile_GetRegister(opcode.src_b, eax);
281 281
282 if (opcode.bf_src_bit != 0 && opcode.bf_src_bit != 31) {
283 shr(src, opcode.bf_src_bit);
284 } else if (opcode.bf_src_bit == 31) {
285 xor_(src, src);
286 }
287 // Don't bother masking the whole register since we're using a 32 bit register
288 if (opcode.bf_size != 31 && opcode.bf_size != 0) {
289 and_(src, opcode.GetBitfieldMask());
290 } else if (opcode.bf_size == 0) {
291 xor_(src, src);
292 }
293 if (opcode.bf_dst_bit != 31 && opcode.bf_dst_bit != 0) {
294 shl(src, opcode.bf_dst_bit);
295 } else if (opcode.bf_dst_bit == 31) {
296 xor_(src, src);
297 }
298
299 const u32 mask = ~(opcode.GetBitfieldMask() << opcode.bf_dst_bit); 282 const u32 mask = ~(opcode.GetBitfieldMask() << opcode.bf_dst_bit);
300 if (mask != 0xffffffff) { 283 and_(dst, mask);
301 and_(dst, mask); 284 shr(src, opcode.bf_src_bit);
302 } 285 and_(src, opcode.GetBitfieldMask());
286 shl(src, opcode.bf_dst_bit);
303 or_(dst, src); 287 or_(dst, src);
288
304 Compile_ProcessResult(opcode.result_operation, opcode.dst); 289 Compile_ProcessResult(opcode.result_operation, opcode.dst);
305} 290}
306 291
@@ -309,17 +294,9 @@ void MacroJITx64Impl::Compile_ExtractShiftLeftImmediate(Macro::Opcode opcode) {
309 const auto src = Compile_GetRegister(opcode.src_b, RESULT); 294 const auto src = Compile_GetRegister(opcode.src_b, RESULT);
310 295
311 shr(src, dst.cvt8()); 296 shr(src, dst.cvt8());
312 if (opcode.bf_size != 0 && opcode.bf_size != 31) { 297 and_(src, opcode.GetBitfieldMask());
313 and_(src, opcode.GetBitfieldMask()); 298 shl(src, opcode.bf_dst_bit);
314 } else if (opcode.bf_size == 0) {
315 xor_(src, src);
316 }
317 299
318 if (opcode.bf_dst_bit != 0 && opcode.bf_dst_bit != 31) {
319 shl(src, opcode.bf_dst_bit);
320 } else if (opcode.bf_dst_bit == 31) {
321 xor_(src, src);
322 }
323 Compile_ProcessResult(opcode.result_operation, opcode.dst); 300 Compile_ProcessResult(opcode.result_operation, opcode.dst);
324} 301}
325 302
@@ -327,13 +304,8 @@ void MacroJITx64Impl::Compile_ExtractShiftLeftRegister(Macro::Opcode opcode) {
327 const auto dst = Compile_GetRegister(opcode.src_a, ecx); 304 const auto dst = Compile_GetRegister(opcode.src_a, ecx);
328 const auto src = Compile_GetRegister(opcode.src_b, RESULT); 305 const auto src = Compile_GetRegister(opcode.src_b, RESULT);
329 306
330 if (opcode.bf_src_bit != 0) { 307 shr(src, opcode.bf_src_bit);
331 shr(src, opcode.bf_src_bit); 308 and_(src, opcode.GetBitfieldMask());
332 }
333
334 if (opcode.bf_size != 31) {
335 and_(src, opcode.GetBitfieldMask());
336 }
337 shl(src, dst.cvt8()); 309 shl(src, dst.cvt8());
338 310
339 Compile_ProcessResult(opcode.result_operation, opcode.dst); 311 Compile_ProcessResult(opcode.result_operation, opcode.dst);