; Copyright 2005 Chris Thomasson


.686
.XMM
.MODEL FLAT, C
.CODE




align 16
np_ac_i686_atomic_dwcas_fence PROC 
  push esi
  push ebx
  mov esi, [esp + 16]
  mov eax, [esi]
  mov edx, [esi + 4]
  mov esi, [esp + 20]
  mov ebx, [esi]
  mov ecx, [esi + 4]
  mov esi, [esp + 12]
  lock cmpxchg8b qword ptr [esi]
  jne np_ac_i686_atomic_dwcas_fence_fail
  xor eax, eax
  pop ebx
  pop esi
  ret

np_ac_i686_atomic_dwcas_fence_fail:
  mov esi, [esp + 16]
  mov [esi + 0],  eax;
  mov [esi + 4],  edx;
  mov eax, 1
  pop ebx
  pop esi
  ret
np_ac_i686_atomic_dwcas_fence ENDP




align 16
ac_i686_stack_mpmc_push_cas PROC
  mov edx, [esp + 4]
  mov eax, [edx]
  mov ecx, [esp + 8]

ac_i686_stack_mpmc_push_cas_retry:
  mov [ecx], eax
  lock cmpxchg [edx], ecx
  jne ac_i686_stack_mpmc_push_cas_retry
  ret
ac_i686_stack_mpmc_push_cas ENDP




align 16
np_ac_i686_lfgc_smr_stack_mpmc_pop_dwcas PROC
  push esi
  push ebx

np_ac_i686_lfgc_smr_stack_mpmc_pop_dwcas_reload:
  mov esi, [esp + 12]
  mov edx, [esi + 4]
  mov eax, [esi]

np_ac_i686_lfgc_smr_stack_mpmc_pop_dwcas_retry:
  mov ebx, [esp + 16]
  mov [ebx], eax
  mfence
  cmp eax, [esi]
  jne np_ac_i686_lfgc_smr_stack_mpmc_pop_dwcas_reload
  test eax, eax
  je np_ac_i686_lfgc_smr_stack_mpmc_pop_dwcas_fail
  mov ebx, [eax]
  lea ecx, [edx + 1]
  lock cmpxchg8b qword ptr [esi]
  jne np_ac_i686_lfgc_smr_stack_mpmc_pop_dwcas_retry

np_ac_i686_lfgc_smr_stack_mpmc_pop_dwcas_fail:
  mov esi, [esp + 16]
  xor ebx, ebx
  mov [esi], ebx
  pop ebx
  pop esi
  ret
np_ac_i686_lfgc_smr_stack_mpmc_pop_dwcas ENDP




align 16
np_ac_i686_stack_mpmc_pop_dwcas PROC
  push esi
  push ebx
  mov esi, [esp + 12]
  mov edx, [esi + 4]
  mov eax, [esi]

np_ac_i686_stack_mpmc_pop_dwcas_retry:
  test eax, eax
  je np_ac_i686_stack_mpmc_pop_dwcas_fail
  mov ebx, [eax]
  lea ecx, [edx + 1]
  lock cmpxchg8b qword ptr [esi]
  jne np_ac_i686_stack_mpmc_pop_dwcas_retry

np_ac_i686_stack_mpmc_pop_dwcas_fail:
  pop ebx
  pop esi
  ret
np_ac_i686_stack_mpmc_pop_dwcas ENDP




align 16
ac_i686_queue_spsc_push PROC
  mov eax, [esp + 4]
  mov ecx, [esp + 8]
  mov edx, [eax + 4]
  ; sfence may be needed on future x86
  mov [edx], ecx
  mov [eax + 4], ecx
  ret
ac_i686_queue_spsc_push ENDP




align 16
ac_i686_queue_spsc_pop PROC
  push ebx
  mov ecx, [esp + 8]
  mov eax, [ecx]
  cmp eax, [ecx + 4]
  je ac_i686_queue_spsc_pop_failed
  mov edx, [eax]
  ; lfence may be needed on future x86
  mov ebx, [edx + 12]
  mov [ecx], edx
  mov [eax + 12], ebx
  pop ebx
  ret

ac_i686_queue_spsc_pop_failed:
  xor eax, eax
  pop ebx
  ret
ac_i686_queue_spsc_pop ENDP




align 16
ac_i686_lfgc_smr_activate PROC
  mov edx, [esp + 4]
  mov ecx, [esp + 8]

ac_i686_lfgc_smr_activate_reload:
  mov eax, [ecx]
  mov [edx], eax
  mfence
  cmp eax, [ecx]
  jne ac_i686_lfgc_smr_activate_reload
  ret
ac_i686_lfgc_smr_activate ENDP




align 16
ac_i686_lfgc_smr_deactivate PROC
  mov ecx, [esp + 4]
  xor eax, eax
  mov [ecx], eax
  ret
ac_i686_lfgc_smr_deactivate ENDP




align 16
ac_i686_mb_fence PROC
  mfence
  ret
ac_i686_mb_fence ENDP




align 16
ac_i686_mb_naked PROC
  ret
ac_i686_mb_naked ENDP




align 16
ac_i686_mb_store_fence PROC
  mov ecx, [esp + 4]
  mov eax, [esp + 8]
  mfence
  mov [ecx], eax
  ret
ac_i686_mb_store_fence ENDP




align 16
ac_i686_mb_load_fence PROC
  mov ecx, [esp + 4]
  mov eax, [ecx]
  mfence
  ret
ac_i686_mb_load_fence ENDP




align 16
ac_i686_mb_store_naked PROC
  mov ecx, [esp + 4]
  mov eax, [esp + 8]
  mov [ecx], eax
  ret
ac_i686_mb_store_naked ENDP




align 16
ac_i686_mb_load_naked PROC
  mov ecx, [esp + 4]
  mov eax, [ecx]
  ret
ac_i686_mb_load_naked ENDP




align 16
ac_i686_atomic_xchg_fence PROC 
  mov ecx, [esp + 4]
  mov eax, [esp + 8]
  xchg [ecx], eax
  ret
ac_i686_atomic_xchg_fence ENDP




align 16
ac_i686_atomic_xadd_fence PROC 
  mov ecx, [esp + 4]
  mov eax, [esp + 8]
  lock xadd [ecx], eax
  ret
ac_i686_atomic_xadd_fence ENDP




align 16
ac_i686_atomic_inc_fence PROC 
  mov ecx, [esp + 4]
  mov eax, 1
  lock xadd [ecx], eax
  inc eax
  ret
ac_i686_atomic_inc_fence ENDP




align 16
ac_i686_atomic_dec_fence PROC 
  mov ecx, [esp + 4]
  mov eax, -1
  lock xadd [ecx], eax
  dec eax
  ret
ac_i686_atomic_dec_fence ENDP




align 16
ac_i686_atomic_cas_fence PROC
  mov ecx, [esp + 4]
  mov eax, [esp + 8]
  mov edx, [esp + 12]
  lock cmpxchg [ecx],	edx
  ret
ac_i686_atomic_cas_fence ENDP




END