about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/dynarec/arm64/dynarec_arm64_f0.c50
-rw-r--r--src/emu/x64runf0.c33
2 files changed, 81 insertions, 2 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c
index c5bce3b7..8bcf3e41 100644
--- a/src/dynarec/arm64/dynarec_arm64_f0.c
+++ b/src/dynarec/arm64/dynarec_arm64_f0.c
@@ -803,6 +803,50 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }
             break;
         
+        case 0xFE:
+            nextop = F8;
+            switch((nextop>>3)&7)
+            {
+                case 0: // INC Eb
+                    INST_NAME("LOCK INC Eb");
+                    SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
+                    SMDMB();
+                    if(MODREG) {
+                        GETEB(x1, 0);
+                        emit_inc8(dyn, ninst, x1, x2, x4);
+                        EBBACK;
+                    } else {
+                        addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, LOCK_LOCK, 0, 0);
+                        MARKLOCK;
+                        LDAXRB(x1, wback);
+                        emit_inc8(dyn, ninst, x1, x3, x4);
+                        STLXRB(x3, x1, wback);
+                        CBNZx_MARKLOCK(x3);
+                        SMDMB();
+                    }
+                    break;
+                case 1: //DEC Ed
+                    INST_NAME("LOCK DEC Ed");
+                    SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING);
+                    SMDMB();
+                    if(MODREG) {
+                        GETEB(x1, 0);
+                        emit_dec8(dyn, ninst, x1, x2, x4);
+                        EBBACK;
+                    } else {
+                        addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, LOCK_LOCK, 0, 0);
+                        MARKLOCK;
+                        LDAXRB(x1, wback);
+                        emit_dec8(dyn, ninst, x1, x3, x4);
+                        STLXRB(x3, x1, wback);
+                        CBNZx_MARKLOCK(x3);
+                        SMDMB();
+                    }
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
         case 0xFF:
             nextop = F8;
             switch((nextop>>3)&7)
@@ -823,6 +867,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         emit_inc32(dyn, ninst, rex, x1, x3, x4);
                         STLXRxw(x3, x1, wback);
                         CBNZx_MARKLOCK(x3);
+                        SMDMB();
                         B_NEXT_nocond;
                         MARK;
                         LDRxw_U12(x1, wback, 0);
@@ -832,8 +877,8 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         STLXRB(x3, x1, wback);
                         CBNZw_MARK(x3);
                         STRxw_U12(x1, wback, 0);
+                        SMDMB();
                     }
-                    SMDMB();
                     break;
                 case 1: //DEC Ed
                     INST_NAME("LOCK DEC Ed");
@@ -851,6 +896,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         emit_dec32(dyn, ninst, rex, x1, x3, x4);
                         STLXRxw(x3, x1, wback);
                         CBNZx_MARKLOCK(x3);
+                        SMDMB();
                         B_NEXT_nocond;
                         MARK;
                         LDRxw_U12(x1, wback, 0);
@@ -860,8 +906,8 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         STLXRB(x3, x1, wback);
                         CBNZw_MARK(x3);
                         STRxw_U12(x1, wback, 0);
+                        SMDMB();
                     }
-                    SMDMB();
                     break;
                 default:
                     DEFAULT;
diff --git a/src/emu/x64runf0.c b/src/emu/x64runf0.c
index 6dd80657..00b524ac 100644
--- a/src/emu/x64runf0.c
+++ b/src/emu/x64runf0.c
@@ -938,6 +938,39 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr)
             }

             break;

 

+        case 0xFE:              /* GRP 5 Eb */

+            nextop = F8;

+            GETED(0);

+            switch((nextop>>3)&7) {

+                case 0:                 /* INC Eb */

+#ifdef DYNAREC

+                    do {

+                        tmp8u = native_lock_read_b(ED);

+                    } while(native_lock_write_b(ED, inc8(emu, tmp8u)));

+#else

+                    pthread_mutex_lock(&emu->context->mutex_lock);

+                    ED->byte[0] = inc8(emu, ED->byte[0]);

+                    pthread_mutex_unlock(&emu->context->mutex_lock);

+#endif

+                    break;

+                case 1:                 /* DEC Ed */

+#ifdef DYNAREC

+                    do {

+                        tmp8u = native_lock_read_b(ED);

+                    } while(native_lock_write_b(ED, dec8(emu, tmp8u)));

+#else

+                    pthread_mutex_lock(&emu->context->mutex_lock);

+                    ED->byte[0] = dec8(emu, ED->byte[0]);

+                    pthread_mutex_unlock(&emu->context->mutex_lock);

+#endif

+                    break;

+                default:

+                    printf_log(LOG_NONE, "Illegal Opcode 0xF0 0xFE 0x%02X 0x%02X\n", nextop, PK(0));

+                    emu->quit=1;

+                    emu->error |= ERR_ILLEGAL;

+                    break;

+            }

+            break;

         case 0xFF:              /* GRP 5 Ed */

             nextop = F8;

             GETED(0);