about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64run66f0.c117
1 files changed, 65 insertions, 52 deletions
diff --git a/src/emu/x64run66f0.c b/src/emu/x64run66f0.c
index 305b450b..8ae4e6a3 100644
--- a/src/emu/x64run66f0.c
+++ b/src/emu/x64run66f0.c
@@ -27,10 +27,11 @@ int Run66F0(x64emu_t *emu, rex_t rex)
 {
     uint8_t opcode;
     uint8_t nextop;
-    uint16_t tmp16u2;
+    uint16_t tmp16u, tmp16u2;
+    int32_t tmp32s;
     int64_t tmp64s;
     uint64_t tmp64u, tmp64u2;
-    reg64_t *oped;
+    reg64_t *oped, *opgd;
 
     opcode = F8;
     // REX prefix before the F0 are ignored
@@ -40,7 +41,45 @@ int Run66F0(x64emu_t *emu, rex_t rex)
         opcode = F8;
     }
 
+    if(rex.w) return RunF0(emu, rex);
+
     switch(opcode) {
+        
+        case 0x0F:
+            nextop = F8;
+            switch(nextop) {
+
+                case 0xB1:                      /* CMPXCHG Ew,Gw */
+                    nextop = F8;
+                    GETEW(0);
+                    GETGW;
+#ifdef DYNAREC
+                    do {
+                        tmp16u = arm64_lock_read_h(EW);
+                        cmp16(emu, R_AX, tmp16u);
+                        if(ACCESS_FLAG(F_ZF)) {
+                            tmp32s = arm64_lock_write_h(EW, GW->word[0]);
+                        } else {
+                            R_AX = tmp16u;
+                            tmp32s = 0;
+                        }
+                    } while(tmp32s);
+#else
+                    pthread_mutex_lock(&emu->context->mutex_lock);
+                    cmp16(emu, R_AX, EW->word[0]);
+                    if(ACCESS_FLAG(F_ZF)) {
+                        EW->word[0] = GW->word[0];
+                    } else {
+                        R_AX = EW->word[0];
+                    }
+                    pthread_mutex_unlock(&emu->context->mutex_lock);
+#endif
+                    break;
+
+                default:
+                    return 1;
+            }
+            break;
 
         case 0x81:              /* GRP Ew,Iw */
         case 0x83:              /* GRP Ew,Ib */
@@ -49,55 +88,7 @@ int Run66F0(x64emu_t *emu, rex_t rex)
             tmp64s = (opcode==0x83)?(F8S):(F16S);
             tmp64u = (uint64_t)tmp64s;
 #ifdef DYNAREC
-            if(rex.w) {
-                switch((nextop>>3)&7) {
-                    case 0: do { tmp64u2 = arm64_lock_read_dd(ED); tmp64u2 = add64(emu, tmp64u2, tmp64u);} while(arm64_lock_write_dd(ED, tmp64u2)); break;
-                    case 1: do { tmp64u2 = arm64_lock_read_dd(ED); tmp64u2 =  or64(emu, tmp64u2, tmp64u);} while(arm64_lock_write_dd(ED, tmp64u2)); break;
-                    case 2: do { tmp64u2 = arm64_lock_read_dd(ED); tmp64u2 = adc64(emu, tmp64u2, tmp64u);} while(arm64_lock_write_dd(ED, tmp64u2)); break;
-                    case 3: do { tmp64u2 = arm64_lock_read_dd(ED); tmp64u2 = sbb64(emu, tmp64u2, tmp64u);} while(arm64_lock_write_dd(ED, tmp64u2)); break;
-                    case 4: do { tmp64u2 = arm64_lock_read_dd(ED); tmp64u2 = and64(emu, tmp64u2, tmp64u);} while(arm64_lock_write_dd(ED, tmp64u2)); break;
-                    case 5: do { tmp64u2 = arm64_lock_read_dd(ED); tmp64u2 = sub64(emu, tmp64u2, tmp64u);} while(arm64_lock_write_dd(ED, tmp64u2)); break;
-                    case 6: do { tmp64u2 = arm64_lock_read_dd(ED); tmp64u2 = xor64(emu, tmp64u2, tmp64u);} while(arm64_lock_write_dd(ED, tmp64u2)); break;
-                    case 7:                cmp64(emu, ED->q[0], tmp64u); break;
-                }
-            } else {
-                if(MODREG)
-                    switch((nextop>>3)&7) {
-                        case 0: ED->word[0] = add16(emu, ED->word[0], tmp64u); break;
-                        case 1: ED->word[0] =  or16(emu, ED->word[0], tmp64u); break;
-                        case 2: ED->word[0] = adc16(emu, ED->word[0], tmp64u); break;
-                        case 3: ED->word[0] = sbb16(emu, ED->word[0], tmp64u); break;
-                        case 4: ED->word[0] = and16(emu, ED->word[0], tmp64u); break;
-                        case 5: ED->word[0] = sub16(emu, ED->word[0], tmp64u); break;
-                        case 6: ED->word[0] = xor16(emu, ED->word[0], tmp64u); break;
-                        case 7:            cmp16(emu, ED->word[0], tmp64u); break;
-                    }
-                else
-                    switch((nextop>>3)&7) {
-                        case 0: do { tmp16u2 = arm64_lock_read_h(ED); tmp16u2 = add16(emu, tmp16u2, tmp64u);} while(arm64_lock_write_h(ED, tmp16u2)); break;
-                        case 1: do { tmp16u2 = arm64_lock_read_h(ED); tmp16u2 =  or16(emu, tmp16u2, tmp64u);} while(arm64_lock_write_h(ED, tmp16u2)); break;
-                        case 2: do { tmp16u2 = arm64_lock_read_h(ED); tmp16u2 = adc16(emu, tmp16u2, tmp64u);} while(arm64_lock_write_h(ED, tmp16u2)); break;
-                        case 3: do { tmp16u2 = arm64_lock_read_h(ED); tmp16u2 = sbb16(emu, tmp16u2, tmp64u);} while(arm64_lock_write_h(ED, tmp16u2)); break;
-                        case 4: do { tmp16u2 = arm64_lock_read_h(ED); tmp16u2 = and16(emu, tmp16u2, tmp64u);} while(arm64_lock_write_h(ED, tmp16u2)); break;
-                        case 5: do { tmp16u2 = arm64_lock_read_h(ED); tmp16u2 = sub16(emu, tmp16u2, tmp64u);} while(arm64_lock_write_h(ED, tmp16u2)); break;
-                        case 6: do { tmp16u2 = arm64_lock_read_h(ED); tmp16u2 = xor16(emu, tmp16u2, tmp64u);} while(arm64_lock_write_h(ED, tmp16u2)); break;
-                        case 7:                                                 cmp16(emu, ED->word[0], tmp64u); break;
-                    }
-            }
-#else
-            pthread_mutex_lock(&emu->context->mutex_lock);
-            if(rex.w) {
-                switch((nextop>>3)&7) {
-                    case 0: ED->q[0] = add64(emu, ED->q[0], tmp64u); break;
-                    case 1: ED->q[0] =  or64(emu, ED->q[0], tmp64u); break;
-                    case 2: ED->q[0] = adc64(emu, ED->q[0], tmp64u); break;
-                    case 3: ED->q[0] = sbb64(emu, ED->q[0], tmp64u); break;
-                    case 4: ED->q[0] = and64(emu, ED->q[0], tmp64u); break;
-                    case 5: ED->q[0] = sub64(emu, ED->q[0], tmp64u); break;
-                    case 6: ED->q[0] = xor64(emu, ED->q[0], tmp64u); break;
-                    case 7:            cmp64(emu, ED->q[0], tmp64u); break;
-                }
-            } else {
+            if(MODREG)
                 switch((nextop>>3)&7) {
                     case 0: ED->word[0] = add16(emu, ED->word[0], tmp64u); break;
                     case 1: ED->word[0] =  or16(emu, ED->word[0], tmp64u); break;
@@ -106,8 +97,30 @@ int Run66F0(x64emu_t *emu, rex_t rex)
                     case 4: ED->word[0] = and16(emu, ED->word[0], tmp64u); break;
                     case 5: ED->word[0] = sub16(emu, ED->word[0], tmp64u); break;
                     case 6: ED->word[0] = xor16(emu, ED->word[0], tmp64u); break;
-                    case 7:               cmp16(emu, ED->word[0], tmp64u); break;
+                    case 7:            cmp16(emu, ED->word[0], tmp64u); break;
+                }
+            else
+                switch((nextop>>3)&7) {
+                    case 0: do { tmp16u2 = arm64_lock_read_h(ED); tmp16u2 = add16(emu, tmp16u2, tmp64u);} while(arm64_lock_write_h(ED, tmp16u2)); break;
+                    case 1: do { tmp16u2 = arm64_lock_read_h(ED); tmp16u2 =  or16(emu, tmp16u2, tmp64u);} while(arm64_lock_write_h(ED, tmp16u2)); break;
+                    case 2: do { tmp16u2 = arm64_lock_read_h(ED); tmp16u2 = adc16(emu, tmp16u2, tmp64u);} while(arm64_lock_write_h(ED, tmp16u2)); break;
+                    case 3: do { tmp16u2 = arm64_lock_read_h(ED); tmp16u2 = sbb16(emu, tmp16u2, tmp64u);} while(arm64_lock_write_h(ED, tmp16u2)); break;
+                    case 4: do { tmp16u2 = arm64_lock_read_h(ED); tmp16u2 = and16(emu, tmp16u2, tmp64u);} while(arm64_lock_write_h(ED, tmp16u2)); break;
+                    case 5: do { tmp16u2 = arm64_lock_read_h(ED); tmp16u2 = sub16(emu, tmp16u2, tmp64u);} while(arm64_lock_write_h(ED, tmp16u2)); break;
+                    case 6: do { tmp16u2 = arm64_lock_read_h(ED); tmp16u2 = xor16(emu, tmp16u2, tmp64u);} while(arm64_lock_write_h(ED, tmp16u2)); break;
+                    case 7:                                                 cmp16(emu, ED->word[0], tmp64u); break;
                 }
+#else
+            pthread_mutex_lock(&emu->context->mutex_lock);
+            switch((nextop>>3)&7) {
+                case 0: ED->word[0] = add16(emu, ED->word[0], tmp64u); break;
+                case 1: ED->word[0] =  or16(emu, ED->word[0], tmp64u); break;
+                case 2: ED->word[0] = adc16(emu, ED->word[0], tmp64u); break;
+                case 3: ED->word[0] = sbb16(emu, ED->word[0], tmp64u); break;
+                case 4: ED->word[0] = and16(emu, ED->word[0], tmp64u); break;
+                case 5: ED->word[0] = sub16(emu, ED->word[0], tmp64u); break;
+                case 6: ED->word[0] = xor16(emu, ED->word[0], tmp64u); break;
+                case 7:               cmp16(emu, ED->word[0], tmp64u); break;
             }
             pthread_mutex_unlock(&emu->context->mutex_lock);
 #endif