diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2017-08-20 11:12:43 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2017-08-20 11:12:43 +0000 |
commit | bafe1ed8d163d3631286a637178cfb7672b6570b (patch) | |
tree | 4b98ece4846a8a5208c8f11d3c871899973dbc3c /sys/lib | |
parent | e05eb9bea441d53356f1bee5c05cd360a1e1d1bf (diff) |
Fix the __sync_* functions to make them work properly
as full memory barriers.
Diffstat (limited to 'sys/lib')
-rw-r--r-- | sys/lib/libkern/arch/mips64/sync.S | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/sys/lib/libkern/arch/mips64/sync.S b/sys/lib/libkern/arch/mips64/sync.S index 64f9b5c6dba..f09cef3a20a 100644 --- a/sys/lib/libkern/arch/mips64/sync.S +++ b/sys/lib/libkern/arch/mips64/sync.S @@ -1,4 +1,4 @@ -/* $OpenBSD: sync.S,v 1.1 2017/05/21 13:00:53 visa Exp $ */ +/* $OpenBSD: sync.S,v 1.2 2017/08/20 11:12:42 visa Exp $ */ /* * Copyright (c) 2015 Visa Hankala @@ -66,12 +66,14 @@ n: #define SYNC_FETCH_AND_OP(op, n, ll, sc, inst, neg) \ LEAF(__sync_fetch_and_##op##_##n); \ + sync; \ 1: ##ll $v0, ($a0); \ ##inst $v1, $v0, $a1; \ ##neg; \ ##sc $v1, ($a0); \ beq $v1, $0, 1b; \ nop; \ + sync; \ j $ra; \ nop; \ END(__sync_fetch_and_##op##_##n) @@ -95,6 +97,7 @@ LEAF(__sync_fetch_and_##op##_##n); \ SYNC_EMUL_INIT(amask, vmask); \ sll $a1, $a1, $t0; /* Align the parameter. */ \ and $a1, $a1, $t1; /* Normalize the parameter. */ \ + sync; \ 1: ll $v0, ($a0); \ ##inst $v1, $v0, $a1; \ ##neg; \ @@ -104,6 +107,7 @@ LEAF(__sync_fetch_and_##op##_##n); \ sc $v1, ($a0); \ beq $v1, $0, 1b; \ nop; \ + sync; \ and $v0, $v0, $t1; /* Get the old value. */ \ j $ra; \ srl $v0, $v0, $t0; /* Remove the shift. */ \ @@ -129,6 +133,7 @@ SYNC_FETCH_AND_OP_EMUL(nand, 1, and, NEG_v1, 3, 0xff) #define SYNC_OP_AND_FETCH(op, n, ll, sc, inst, neg) \ LEAF(__sync_##op##_and_fetch_##n); \ + sync; \ 1: ##ll $v0, ($a0); \ ##inst $v0, $v0, $a1; \ ##neg; \ @@ -136,6 +141,7 @@ LEAF(__sync_##op##_and_fetch_##n); \ ##sc $v1, ($a0); \ beq $v1, $0, 1b; \ nop; \ + sync; \ j $ra; \ nop; \ END(__sync_##op##_and_fetch_##n) @@ -159,6 +165,7 @@ LEAF(__sync_##op##_and_fetch_##n); \ SYNC_EMUL_INIT(amask, vmask); \ sll $a1, $a1, $t0; /* Align the parameter. */ \ and $a1, $a1, $t1; /* Normalize the parameter. */ \ + sync; \ 1: ll $v0, ($a0); \ ##inst $v1, $v0, $a1; \ ##neg; \ @@ -169,6 +176,7 @@ LEAF(__sync_##op##_and_fetch_##n); \ sc $v1, ($a0); \ beq $v1, $0, 1b; \ nop; \ + sync; \ j $ra; \ srl $v0, $t3, $t0; /* Remove the shift. */ \ END(__sync_##op##_and_fetch_##n) @@ -194,12 +202,14 @@ SYNC_OP_AND_FETCH_EMUL(nand, 1, and, NEG_v1, 3, 0xff) #define SYNC_BOOL_COMPARE_AND_SWAP(n, ll, sc, trunc) \ LEAF(__sync_bool_compare_and_swap_##n); \ trunc; \ + sync; \ 1: ##ll $v0, ($a0); \ bne $v0, $a1, 2f; \ move $v1, $a2; \ ##sc $v1, ($a0); \ beq $v1, $0, 1b; \ nop; \ + sync; \ j $ra; \ li $v0, 1; \ 2: j $ra; \ @@ -218,6 +228,7 @@ LEAF(__sync_bool_compare_and_swap_##n); \ sll $a2, $a2, $t0; \ and $a2, $a2, $t1; \ /* Do the update. */ \ + sync; \ 1: ll $v0, ($a0); \ and $v1, $v0, $t1; /* Get the old value. */ \ bne $v1, $a1, 2f; \ @@ -226,6 +237,7 @@ LEAF(__sync_bool_compare_and_swap_##n); \ sc $v1, ($a0); \ beq $v1, $0, 1b; \ nop; \ + sync; \ j $ra; \ li $v0, 1; \ 2: j $ra; \ @@ -242,12 +254,14 @@ SYNC_BOOL_COMPARE_AND_SWAP_EMUL(1, 3, 0xff) #define SYNC_VAL_COMPARE_AND_SWAP(n, ll, sc, trunc) \ LEAF(__sync_val_compare_and_swap_##n); \ trunc; \ + sync; \ 1: ##ll $v0, ($a0); \ bne $v0, $a1, 2f; \ move $v1, $a2; \ ##sc $v1, ($a0); \ beq $v1, $0, 1b; \ nop; \ + sync; \ 2: j $ra; \ nop; \ END(__sync_val_compare_and_swap_##n) @@ -264,6 +278,7 @@ LEAF(__sync_val_compare_and_swap_##n); \ sll $a2, $a2, $t0; \ and $a2, $a2, $t1; \ /* Do the update. */ \ + sync; \ 1: ll $v0, ($a0); \ and $t3, $v0, $t1; /* Get the old value. */ \ bne $t3, $a1, 2f; \ @@ -272,6 +287,7 @@ LEAF(__sync_val_compare_and_swap_##n); \ sc $v1, ($a0); \ beq $v1, $0, 1b; \ nop; \ + sync; \ 2: j $ra; \ srl $v0, $t3, $t0; /* Remove the shift. */ \ END(__sync_val_compare_and_swap_##n) @@ -285,11 +301,13 @@ SYNC_VAL_COMPARE_AND_SWAP_EMUL(1, 3, 0xff) #define SYNC_LOCK_TEST_AND_SET(n, ll, sc) \ LEAF(__sync_lock_test_and_set_##n); \ + sync; \ 1: move $v1, $a1; \ ##ll $v0, ($a0); \ ##sc $v1, ($a0); \ beq $v1, $0, 1b; \ nop; \ + sync; \ j $ra; \ nop; \ END(__sync_lock_test_and_set_##n) @@ -302,12 +320,14 @@ LEAF(__sync_lock_test_and_set_##n); \ SYNC_EMUL_INIT(amask, vmask); \ sll $a1, $a1, $t0; /* Align the parameter. */ \ and $a1, $a1, $t1; /* Normalize the parameter. */ \ + sync; \ 1: ll $v0, ($a0); \ and $v1, $v0, $t2; /* Clear the old value. */ \ or $v1, $v1, $a1; /* Insert the new value. */ \ sc $v1, ($a0); \ beq $v1, $0, 1b; \ nop; \ + sync; \ and $v0, $v0, $t1; /* Get the old value. */ \ j $ra; \ srl $v0, $v0, $t0; /* Remove the shift. */ \ |