...
Run Format

Text file src/sync/atomic/asm_386.s

Documentation: sync/atomic

     1	// Copyright 2011 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// +build !race
     6	
     7	#include "textflag.h"
     8	
     9	TEXT ·SwapInt32(SB),NOSPLIT,$0-12
    10		JMP	·SwapUint32(SB)
    11	
    12	TEXT ·SwapUint32(SB),NOSPLIT,$0-12
    13		MOVL	addr+0(FP), BP
    14		MOVL	new+4(FP), AX
    15		XCHGL	AX, 0(BP)
    16		MOVL	AX, old+8(FP)
    17		RET
    18	
    19	TEXT ·SwapInt64(SB),NOSPLIT,$0-20
    20		JMP	·SwapUint64(SB)
    21	
    22	TEXT ·SwapUint64(SB),NOSPLIT,$0-20
    23		// no XCHGQ so use CMPXCHG8B loop
    24		MOVL	addr+0(FP), BP
    25		TESTL	$7, BP
    26		JZ	2(PC)
    27		MOVL	0, AX // crash with nil ptr deref
    28		// CX:BX = new
    29		MOVL	new_lo+4(FP), BX
    30		MOVL	new_hi+8(FP), CX
    31		// DX:AX = *addr
    32		MOVL	0(BP), AX
    33		MOVL	4(BP), DX
    34	swaploop:
    35		// if *addr == DX:AX
    36		//	*addr = CX:BX
    37		// else
    38		//	DX:AX = *addr
    39		// all in one instruction
    40		LOCK
    41		CMPXCHG8B	0(BP)
    42		JNZ	swaploop
    43	
    44		// success
    45		// return DX:AX
    46		MOVL	AX, old_lo+12(FP)
    47		MOVL	DX, old_hi+16(FP)
    48		RET
    49	
    50	TEXT ·SwapUintptr(SB),NOSPLIT,$0-12
    51		JMP	·SwapUint32(SB)
    52	
    53	TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-13
    54		JMP	·CompareAndSwapUint32(SB)
    55	
    56	TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-13
    57		MOVL	addr+0(FP), BP
    58		MOVL	old+4(FP), AX
    59		MOVL	new+8(FP), CX
    60		// CMPXCHGL was introduced on the 486.
    61		LOCK
    62		CMPXCHGL	CX, 0(BP)
    63		SETEQ	swapped+12(FP)
    64		RET
    65	
    66	TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-13
    67		JMP	·CompareAndSwapUint32(SB)
    68	
    69	TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-21
    70		JMP	·CompareAndSwapUint64(SB)
    71	
    72	TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$0-21
    73		MOVL	addr+0(FP), BP
    74		TESTL	$7, BP
    75		JZ	2(PC)
    76		MOVL	0, AX // crash with nil ptr deref
    77		MOVL	old_lo+4(FP), AX
    78		MOVL	old_hi+8(FP), DX
    79		MOVL	new_lo+12(FP), BX
    80		MOVL	new_hi+16(FP), CX
    81		// CMPXCHG8B was introduced on the Pentium.
    82		LOCK
    83		CMPXCHG8B	0(BP)
    84		SETEQ	swapped+20(FP)
    85		RET
    86	
    87	TEXT ·AddInt32(SB),NOSPLIT,$0-12
    88		JMP	·AddUint32(SB)
    89	
    90	TEXT ·AddUint32(SB),NOSPLIT,$0-12
    91		MOVL	addr+0(FP), BP
    92		MOVL	delta+4(FP), AX
    93		MOVL	AX, CX
    94		// XADD was introduced on the 486.
    95		LOCK
    96		XADDL	AX, 0(BP)
    97		ADDL	AX, CX
    98		MOVL	CX, new+8(FP)
    99		RET
   100	
   101	TEXT ·AddUintptr(SB),NOSPLIT,$0-12
   102		JMP	·AddUint32(SB)
   103	
   104	TEXT ·AddInt64(SB),NOSPLIT,$0-20
   105		JMP	·AddUint64(SB)
   106	
   107	TEXT ·AddUint64(SB),NOSPLIT,$0-20
   108		// no XADDQ so use CMPXCHG8B loop
   109		MOVL	addr+0(FP), BP
   110		TESTL	$7, BP
   111		JZ	2(PC)
   112		MOVL	0, AX // crash with nil ptr deref
   113		// DI:SI = delta
   114		MOVL	delta_lo+4(FP), SI
   115		MOVL	delta_hi+8(FP), DI
   116		// DX:AX = *addr
   117		MOVL	0(BP), AX
   118		MOVL	4(BP), DX
   119	addloop:
   120		// CX:BX = DX:AX (*addr) + DI:SI (delta)
   121		MOVL	AX, BX
   122		MOVL	DX, CX
   123		ADDL	SI, BX
   124		ADCL	DI, CX
   125	
   126		// if *addr == DX:AX {
   127		//	*addr = CX:BX
   128		// } else {
   129		//	DX:AX = *addr
   130		// }
   131		// all in one instruction
   132		LOCK
   133		CMPXCHG8B	0(BP)
   134	
   135		JNZ	addloop
   136	
   137		// success
   138		// return CX:BX
   139		MOVL	BX, new_lo+12(FP)
   140		MOVL	CX, new_hi+16(FP)
   141		RET
   142	
   143	TEXT ·LoadInt32(SB),NOSPLIT,$0-8
   144		JMP	·LoadUint32(SB)
   145	
   146	TEXT ·LoadUint32(SB),NOSPLIT,$0-8
   147		MOVL	addr+0(FP), AX
   148		MOVL	0(AX), AX
   149		MOVL	AX, val+4(FP)
   150		RET
   151	
   152	TEXT ·LoadInt64(SB),NOSPLIT,$0-12
   153		JMP	·LoadUint64(SB)
   154	
   155	TEXT ·LoadUint64(SB),NOSPLIT,$0-12
   156		MOVL	addr+0(FP), AX
   157		TESTL	$7, AX
   158		JZ	2(PC)
   159		MOVL	0, AX // crash with nil ptr deref
   160		// MOVQ and EMMS were introduced on the Pentium MMX.
   161		// MOVQ (%EAX), %MM0
   162		BYTE $0x0f; BYTE $0x6f; BYTE $0x00
   163		// MOVQ %MM0, 0x8(%ESP)
   164		BYTE $0x0f; BYTE $0x7f; BYTE $0x44; BYTE $0x24; BYTE $0x08
   165		EMMS
   166		RET
   167	
   168	TEXT ·LoadUintptr(SB),NOSPLIT,$0-8
   169		JMP	·LoadUint32(SB)
   170	
   171	TEXT ·LoadPointer(SB),NOSPLIT,$0-8
   172		JMP	·LoadUint32(SB)
   173	
   174	TEXT ·StoreInt32(SB),NOSPLIT,$0-8
   175		JMP	·StoreUint32(SB)
   176	
   177	TEXT ·StoreUint32(SB),NOSPLIT,$0-8
   178		MOVL	addr+0(FP), BP
   179		MOVL	val+4(FP), AX
   180		XCHGL	AX, 0(BP)
   181		RET
   182	
   183	TEXT ·StoreInt64(SB),NOSPLIT,$0-12
   184		JMP	·StoreUint64(SB)
   185	
   186	TEXT ·StoreUint64(SB),NOSPLIT,$0-12
   187		MOVL	addr+0(FP), AX
   188		TESTL	$7, AX
   189		JZ	2(PC)
   190		MOVL	0, AX // crash with nil ptr deref
   191		// MOVQ and EMMS were introduced on the Pentium MMX.
   192		// MOVQ 0x8(%ESP), %MM0
   193		BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08
   194		// MOVQ %MM0, (%EAX)
   195		BYTE $0x0f; BYTE $0x7f; BYTE $0x00 
   196		EMMS
   197		// This is essentially a no-op, but it provides required memory fencing.
   198		// It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2).
   199		XORL	AX, AX
   200		LOCK
   201		XADDL	AX, (SP)
   202		RET
   203	
   204	TEXT ·StoreUintptr(SB),NOSPLIT,$0-8
   205		JMP	·StoreUint32(SB)

View as plain text