about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-11-14 21:43:02 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-11-14 21:43:02 +0100
commitf85e24dff8c268dca8e2f5240938c28365551537 (patch)
tree5fb0e0886876034c60ab889452475f5e3a8864f0 /src
parent2ea272fcd635685896434844ada57c0f5571e6e2 (diff)
downloadbox64-f85e24dff8c268dca8e2f5240938c28365551537.tar.gz
box64-f85e24dff8c268dca8e2f5240938c28365551537.zip
[DYNAREC] Added some DMB to try help multi-tasked+JIT program (may help #110)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_lock.S25
-rwxr-xr-xsrc/dynarec/dynarec_arm64_00.c4
-rw-r--r--src/dynarec/dynarec_arm64_f0.c26
3 files changed, 52 insertions, 3 deletions
diff --git a/src/dynarec/arm64_lock.S b/src/dynarec/arm64_lock.S
index 0e2e2958..9d097ff5 100755
--- a/src/dynarec/arm64_lock.S
+++ b/src/dynarec/arm64_lock.S
@@ -21,6 +21,7 @@
 
 
 arm64_lock_read_b:
+    dmb     ish
     // address is x0, return is x0
     ldaxrb  w0, [x0]
     ret
@@ -29,9 +30,11 @@ arm64_lock_write_b:
     // address is x0, value is x1, return is x0
     mov     x2, x0
     stlxrb  w0, w1, [x2]
+    dmb     ish
     ret
 
 arm64_lock_read_h:
+    dmb     ish
     // address is x0, return is x0
     ldaxrh  w0, [x0]
     ret
@@ -40,9 +43,11 @@ arm64_lock_write_h:
     // address is x0, value is x1, return is x0
     mov     x2, x0
     stlxrh  w0, w1, [x2]
+    dmb     ish
     ret
 
 arm64_lock_read_d:
+    dmb     ish
     // address is x0, return is x0
     ldaxr    w0, [x0]
     ret
@@ -51,9 +56,11 @@ arm64_lock_write_d:
     // address is x0, value is w1, return is x0
     mov     x2, x0
     stlxr   w0, w1, [x2]
+    dmb     ish
     ret
 
 arm64_lock_read_dd:
+    dmb     ish
     // address is x0, return is x0
     ldaxr   x0, [x0]
     ret
@@ -62,9 +69,11 @@ arm64_lock_write_dd:
     // address is x0, value is x1, return is x0
     mov     x2, x0
     stlxr   w0, x1, [x2]
+    dmb     ish
     ret
 
 arm64_lock_read_dq:
+    dmb     ish
     // address is r2, return is r0, r1
     ldaxp   x4, x3, [x2]
     str     x4, [x0]
@@ -76,37 +85,47 @@ arm64_lock_write_dq:
     // r0 needs to be aligned
     stlxp   w3, x0, x1, [x2]
     mov     w0, w3
+    dmb     ish
     ret
 
 
 arm64_lock_xchg:
+    dmb     ish
+arm64_lock_xchg_0:
     // address is x0, value is x1, return old value in x0
     ldaxr   x2, [x0]
     stlxr   w3, x1, [x0]
-    cbnz    w3, arm64_lock_xchg
+    cbnz    w3, arm64_lock_xchg_0
+    dmb     ish
     mov     x0, x2
     ret
 
 arm64_lock_storeifnull:
+    dmb     ish
+arm64_lock_storeifnull_0:
     // address is x0, value is x1, x1 store to x0 only if [x0] is 0. return new [x0] value (so x1 or old value)
     ldaxr   x2, [x0]
     cbnz    x2, arm64_lock_storeifnull_exit
     mov     x2, x1
     stlxr   w3, x2, [x0]
-    cbnz    w3, arm64_lock_storeifnull
+    cbnz    w3, arm64_lock_storeifnull_0
 arm64_lock_storeifnull_exit:
+    dmb     ish
     mov     x0, x2
     ret
 
 arm64_lock_storeifref:
+    dmb     ish
+arm64_lock_storeifref_0:
     // address is x0, value is x1, x1 store to x0 only if [x0] is x3. return new [x0] value (so x1 or old value)
     ldaxr   x3, [x0]
     cmp     x2, x3
     bne     arm64_lock_storeifref_exit
     stlxr   w4, x1, [x0]
-    cbnz    w4, arm64_lock_storeifref
+    cbnz    w4, arm64_lock_storeifref_0
     mov     x0, x1
     ret
 arm64_lock_storeifref_exit:
+    dmb     ish
     mov     x0, x3
     ret
diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c
index b3a91486..401a30e8 100755
--- a/src/dynarec/dynarec_arm64_00.c
+++ b/src/dynarec/dynarec_arm64_00.c
@@ -844,6 +844,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 BFIx(gb1, x1, gb2*8, 8);
                 BFIx(eb1, x4, eb2*8, 8);
             } else {
+                DMB_ISH();
                 GETGB(x4);
                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, rex, 0, 0);
                 MARKLOCK;
@@ -852,6 +853,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 // do the swap 14 -> strb(ed), 1 -> gd
                 STLXRB(x3, x4, ed);
                 CBNZx_MARKLOCK(x3);
+                DMB_ISH();
                 BFIx(gb1, x1, gb2*8, 8);
             }
             break;
@@ -867,6 +869,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             } else {
                 GETGD;
                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, rex, 0, 0);
+                DMB_ISH();
                 TSTx_mask(ed, 1, 0, 1+rex.w);    // mask=3 or 7
                 B_MARK(cNE);
                 MARKLOCK;
@@ -878,6 +881,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 LDRxw_U12(x1, ed, 0);
                 STRxw_U12(gd, ed, 0);
                 MARK2;
+                DMB_ISH();
                 MOVxw_REG(gd, x1);
             }
             break;
diff --git a/src/dynarec/dynarec_arm64_f0.c b/src/dynarec/dynarec_arm64_f0.c
index 9a731b81..c071cb39 100644
--- a/src/dynarec/dynarec_arm64_f0.c
+++ b/src/dynarec/dynarec_arm64_f0.c
@@ -56,6 +56,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             INST_NAME("LOCK ADD Eb, Gb");
             SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
+            DMB_ISH();
             GETGB(x2);
             if((nextop&0xC0)==0xC0) {
                 if(rex.rex) {
@@ -77,12 +78,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 STLXRB(x4, x1, wback);
                 CBNZx_MARKLOCK(x4);
             }
+            DMB_ISH();
             break;
         case 0x01:
             INST_NAME("LOCK ADD Ed, Gd");
             SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
             GETGD;
+            DMB_ISH();
             if((nextop&0xC0)==0xC0) {
                 ed = xRAX+(nextop&7)+(rex.b<<3);
                 emit_add32(dyn, ninst, rex, ed, gd, x3, x4);
@@ -94,6 +97,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 STLXRxw(x3, x1, wback);
                 CBNZx_MARKLOCK(x3);
             }
+            DMB_ISH();
             break;
 
         case 0x09:
@@ -101,6 +105,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
             GETGD;
+            DMB_ISH();
             if(MODREG) {
                 ed = xRAX+(nextop&7)+(rex.b<<3);
                 emit_or32(dyn, ninst, rex, ed, gd, x3, x4);
@@ -112,6 +117,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 STLXRxw(x3, x1, wback);
                 CBNZx_MARKLOCK(x3);
             }
+            DMB_ISH();
             break;
 
         case 0x0F:
@@ -123,6 +129,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     SETFLAGS(X_ALL, SF_SET_PENDING);
                     nextop = F8;
                     GETGD;
+                    DMB_ISH();
                     if(MODREG) {
                         ed = xRAX+(nextop&7)+(rex.b<<3);
                         wback = 0;
@@ -163,6 +170,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         UFLAG_IF {emit_cmp32(dyn, ninst, rex, xRAX, x1, x3, x4, x5);}
                         MOVxw_REG(xRAX, x1);    // upper par of RAX will be erase on 32bits, no mater what
                     }
+                    DMB_ISH();
                     break;
 
                 case 0xC1:
@@ -170,6 +178,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     SETFLAGS(X_ALL, SF_SET_PENDING);
                     nextop = F8;
                     GETGD;
+                    DMB_ISH();
                     if(MODREG) {
                         ed = xRAX+(nextop&7)+(rex.b<<3);
                         MOVxw_REG(x1, ed);
@@ -201,6 +210,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         }
                         MOVxw_REG(gd, x1);
                     }
+                    DMB_ISH();
                     break;
 
                 case 0xC7:
@@ -208,6 +218,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     SETFLAGS(X_ZF, SF_SUBSET);
                     nextop = F8;
                     addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, 0, 0, rex, 0, 0);
+                    DMB_ISH();
                     MARKLOCK;
                     LDAXPxw(x2, x3, wback);
                     CMPSxw_REG(xRAX, x2);
@@ -223,6 +234,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     MOVxw_REG(xRDX, x3);
                     MOV32w(x1, 0);
                     MARK3;
+                    DMB_ISH();
                     BFIw(xFlags, x1, F_ZF, 1);
                     break;
 
@@ -236,6 +248,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             SETFLAGS(X_ALL, SF_SET_PENDING);
             nextop = F8;
             GETGD;
+            DMB_ISH();
             if(MODREG) {
                 ed = xRAX+(nextop&7)+(rex.b<<3);
                 emit_sub32(dyn, ninst, rex, ed, gd, x3, x4);
@@ -247,6 +260,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 STLXRxw(x3, x1, wback);
                 CBNZx_MARKLOCK(x3);
             }
+            DMB_ISH();
             break;
 
         case 0x66:
@@ -255,6 +269,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 0x81:
                 case 0x83:
                     nextop = F8;
+                    DMB_ISH();
                     switch((nextop>>3)&7) {
                         case 0: //ADD
                             if(opcode==0x81) {
@@ -448,6 +463,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             }
                             break;
                     }
+                    DMB_ISH();
                     break;
                 default:
                     DEFAULT;
@@ -456,6 +472,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
 
         case 0x80:
             nextop = F8;
+            DMB_ISH();
             switch((nextop>>3)&7) {
                 case 0: //ADD
                     INST_NAME("ADD Eb, Ib");
@@ -614,10 +631,12 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 default:
                     DEFAULT;
             }
+            DMB_ISH();
             break;
         case 0x81:
         case 0x83:
             nextop = F8;
+            DMB_ISH();
             switch((nextop>>3)&7) {
                 case 0: //ADD
                     if(opcode==0x81) {
@@ -794,6 +813,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
             }
+            DMB_ISH();
             break;
             
         case 0x87:
@@ -807,6 +827,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 MOVxw_REG(ed, x1);
             } else {
                 GETGD;
+                DMB_ISH();
                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, rex, 0, 0);
                 TSTx_mask(ed, 1, 0, 1+rex.w);    // mask=3 or 7
                 B_MARK(cNE);
@@ -819,6 +840,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 LDRxw_U12(x1, ed, 0);
                 STRxw_U12(gd, ed, 0);
                 MARK2;
+                DMB_ISH();
                 MOVxw_REG(gd, x1);
             }
             break;
@@ -830,6 +852,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 case 0: // INC Ed
                     INST_NAME("LOCK INC Ed");
                     SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
+                    DMB_ISH();
                     if(MODREG) {
                         ed = xRAX+(nextop&7)+(rex.b<<3);
                         emit_inc32(dyn, ninst, rex, ed, x3, x4);
@@ -852,10 +875,12 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         CBNZw_MARK(x3);
                         STRxw_U12(x1, wback, 0);
                     }
+                    DMB_ISH();
                     break;
                 case 1: //DEC Ed
                     INST_NAME("LOCK DEC Ed");
                     SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
+                    DMB_ISH();
                     if(MODREG) {
                         ed = xRAX+(nextop&7)+(rex.b<<3);
                         emit_dec32(dyn, ninst, rex, ed, x3, x4);
@@ -878,6 +903,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         CBNZw_MARK(x3);
                         STRxw_U12(x1, wback, 0);
                     }
+                    DMB_ISH();
                     break;
                 default:
                     DEFAULT;