github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/sync/atomic/asm_386.s (about)

     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  TEXT ·CompareAndSwapInt32(SB),7,$0
     8  	JMP	·CompareAndSwapUint32(SB)
     9  
    10  TEXT ·CompareAndSwapUint32(SB),7,$0
    11  	MOVL	addr+0(FP), BP
    12  	MOVL	old+4(FP), AX
    13  	MOVL	new+8(FP), CX
    14  	// CMPXCHGL was introduced on the 486.
    15  	LOCK
    16  	CMPXCHGL	CX, 0(BP)
    17  	SETEQ	swapped+12(FP)
    18  	RET
    19  
    20  TEXT ·CompareAndSwapUintptr(SB),7,$0
    21  	JMP	·CompareAndSwapUint32(SB)
    22  
    23  TEXT ·CompareAndSwapPointer(SB),7,$0
    24  	JMP	·CompareAndSwapUint32(SB)
    25  
    26  TEXT ·CompareAndSwapInt64(SB),7,$0
    27  	JMP	·CompareAndSwapUint64(SB)
    28  
    29  TEXT ·CompareAndSwapUint64(SB),7,$0
    30  	MOVL	addr+0(FP), BP
    31  	TESTL	$7, BP
    32  	JZ	2(PC)
    33  	MOVL	0, AX // crash with nil ptr deref
    34  	MOVL	old_lo+4(FP), AX
    35  	MOVL	old_hi+8(FP), DX
    36  	MOVL	new_lo+12(FP), BX
    37  	MOVL	new_hi+16(FP), CX
    38  	// CMPXCHG8B was introduced on the Pentium.
    39  	LOCK
    40  	CMPXCHG8B	0(BP)
    41  	SETEQ	swapped+20(FP)
    42  	RET
    43  
    44  TEXT ·AddInt32(SB),7,$0
    45  	JMP	·AddUint32(SB)
    46  
    47  TEXT ·AddUint32(SB),7,$0
    48  	MOVL	addr+0(FP), BP
    49  	MOVL	delta+4(FP), AX
    50  	MOVL	AX, CX
    51  	// XADD was introduced on the 486.
    52  	LOCK
    53  	XADDL	AX, 0(BP)
    54  	ADDL	AX, CX
    55  	MOVL	CX, new+8(FP)
    56  	RET
    57  
    58  TEXT ·AddUintptr(SB),7,$0
    59  	JMP	·AddUint32(SB)
    60  
    61  TEXT ·AddInt64(SB),7,$0
    62  	JMP	·AddUint64(SB)
    63  
    64  TEXT ·AddUint64(SB),7,$0
    65  	// no XADDQ so use CMPXCHG8B loop
    66  	MOVL	addr+0(FP), BP
    67  	TESTL	$7, BP
    68  	JZ	2(PC)
    69  	MOVL	0, AX // crash with nil ptr deref
    70  	// DI:SI = delta
    71  	MOVL	delta_lo+4(FP), SI
    72  	MOVL	delta_hi+8(FP), DI
    73  	// DX:AX = *addr
    74  	MOVL	0(BP), AX
    75  	MOVL	4(BP), DX
    76  addloop:
    77  	// CX:BX = DX:AX (*addr) + DI:SI (delta)
    78  	MOVL	AX, BX
    79  	MOVL	DX, CX
    80  	ADDL	SI, BX
    81  	ADCL	DI, CX
    82  
    83  	// if *addr == DX:AX {
    84  	//	*addr = CX:BX
    85  	// } else {
    86  	//	DX:AX = *addr
    87  	// }
    88  	// all in one instruction
    89  	LOCK
    90  	CMPXCHG8B	0(BP)
    91  
    92  	JNZ	addloop
    93  
    94  	// success
    95  	// return CX:BX
    96  	MOVL	BX, new_lo+12(FP)
    97  	MOVL	CX, new_hi+16(FP)
    98  	RET
    99  
   100  TEXT ·LoadInt32(SB),7,$0
   101  	JMP	·LoadUint32(SB)
   102  
   103  TEXT ·LoadUint32(SB),7,$0
   104  	MOVL	addr+0(FP), AX
   105  	MOVL	0(AX), AX
   106  	MOVL	AX, val+4(FP)
   107  	RET
   108  
   109  TEXT ·LoadInt64(SB),7,$0
   110  	JMP	·LoadUint64(SB)
   111  
   112  TEXT ·LoadUint64(SB),7,$0
   113  	MOVL	addr+0(FP), AX
   114  	TESTL	$7, AX
   115  	JZ	2(PC)
   116  	MOVL	0, AX // crash with nil ptr deref
   117  	// MOVQ and EMMS were introduced on the Pentium MMX.
   118  	// MOVQ (%EAX), %MM0
   119  	BYTE $0x0f; BYTE $0x6f; BYTE $0x00
   120  	// MOVQ %MM0, 0x8(%ESP)
   121  	BYTE $0x0f; BYTE $0x7f; BYTE $0x44; BYTE $0x24; BYTE $0x08
   122  	EMMS
   123  	RET
   124  
   125  TEXT ·LoadUintptr(SB),7,$0
   126  	JMP	·LoadUint32(SB)
   127  
   128  TEXT ·LoadPointer(SB),7,$0
   129  	JMP	·LoadUint32(SB)
   130  
   131  TEXT ·StoreInt32(SB),7,$0
   132  	JMP	·StoreUint32(SB)
   133  
   134  TEXT ·StoreUint32(SB),7,$0
   135  	MOVL	addr+0(FP), BP
   136  	MOVL	val+4(FP), AX
   137  	XCHGL	AX, 0(BP)
   138  	RET
   139  
   140  TEXT ·StoreInt64(SB),7,$0
   141  	JMP	·StoreUint64(SB)
   142  
   143  TEXT ·StoreUint64(SB),7,$0
   144  	MOVL	addr+0(FP), AX
   145  	TESTL	$7, AX
   146  	JZ	2(PC)
   147  	MOVL	0, AX // crash with nil ptr deref
   148  	// MOVQ and EMMS were introduced on the Pentium MMX.
   149  	// MOVQ 0x8(%ESP), %MM0
   150  	BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08
   151  	// MOVQ %MM0, (%EAX)
   152  	BYTE $0x0f; BYTE $0x7f; BYTE $0x00 
   153  	EMMS
   154  	// This is essentially a no-op, but it provides required memory fencing.
   155  	// It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2).
   156  	XORL	AX, AX
   157  	LOCK
   158  	XADDL	AX, (SP)
   159  	RET
   160  
   161  TEXT ·StoreUintptr(SB),7,$0
   162  	JMP	·StoreUint32(SB)
   163  
   164  TEXT ·StorePointer(SB),7,$0
   165  	JMP	·StoreUint32(SB)