...

Text file src/runtime/internal/atomic/asm_386.s

     1	// Copyright 2015 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	#include "textflag.h"
     6	
     7	// bool Cas(int32 *val, int32 old, int32 new)
     8	// Atomically:
     9	//	if(*val == old){
    10	//		*val = new;
    11	//		return 1;
    12	//	}else
    13	//		return 0;
    14	TEXT runtime∕internal∕atomic·Cas(SB), NOSPLIT, $0-13
    15		MOVL	ptr+0(FP), BX
    16		MOVL	old+4(FP), AX
    17		MOVL	new+8(FP), CX
    18		LOCK
    19		CMPXCHGL	CX, 0(BX)
    20		SETEQ	ret+12(FP)
    21		RET
    22	
    23	TEXT runtime∕internal∕atomic·Casuintptr(SB), NOSPLIT, $0-13
    24		JMP	runtime∕internal∕atomic·Cas(SB)
    25	
    26	TEXT runtime∕internal∕atomic·CasRel(SB), NOSPLIT, $0-13
    27		JMP	runtime∕internal∕atomic·Cas(SB)
    28	
    29	TEXT runtime∕internal∕atomic·Loaduintptr(SB), NOSPLIT, $0-8
    30		JMP	runtime∕internal∕atomic·Load(SB)
    31	
    32	TEXT runtime∕internal∕atomic·Loaduint(SB), NOSPLIT, $0-8
    33		JMP	runtime∕internal∕atomic·Load(SB)
    34	
    35	TEXT runtime∕internal∕atomic·Storeuintptr(SB), NOSPLIT, $0-8
    36		JMP	runtime∕internal∕atomic·Store(SB)
    37	
    38	TEXT runtime∕internal∕atomic·Xadduintptr(SB), NOSPLIT, $0-12
    39		JMP runtime∕internal∕atomic·Xadd(SB)
    40	
    41	TEXT runtime∕internal∕atomic·Loadint64(SB), NOSPLIT, $0-12
    42		JMP runtime∕internal∕atomic·Load64(SB)
    43	
    44	TEXT runtime∕internal∕atomic·Xaddint64(SB), NOSPLIT, $0-20
    45		JMP runtime∕internal∕atomic·Xadd64(SB)
    46	
    47	
    48	// bool runtime∕internal∕atomic·Cas64(uint64 *val, uint64 old, uint64 new)
    49	// Atomically:
    50	//	if(*val == *old){
    51	//		*val = new;
    52	//		return 1;
    53	//	} else {
    54	//		return 0;
    55	//	}
    56	TEXT runtime∕internal∕atomic·Cas64(SB), NOSPLIT, $0-21
    57		MOVL	ptr+0(FP), BP
    58		TESTL	$7, BP
    59		JZ	2(PC)
    60		MOVL	0, BP // crash with nil ptr deref
    61		MOVL	old_lo+4(FP), AX
    62		MOVL	old_hi+8(FP), DX
    63		MOVL	new_lo+12(FP), BX
    64		MOVL	new_hi+16(FP), CX
    65		LOCK
    66		CMPXCHG8B	0(BP)
    67		SETEQ	ret+20(FP)
    68		RET
    69	
    70	// bool Casp1(void **p, void *old, void *new)
    71	// Atomically:
    72	//	if(*p == old){
    73	//		*p = new;
    74	//		return 1;
    75	//	}else
    76	//		return 0;
    77	TEXT runtime∕internal∕atomic·Casp1(SB), NOSPLIT, $0-13
    78		MOVL	ptr+0(FP), BX
    79		MOVL	old+4(FP), AX
    80		MOVL	new+8(FP), CX
    81		LOCK
    82		CMPXCHGL	CX, 0(BX)
    83		SETEQ	ret+12(FP)
    84		RET
    85	
    86	// uint32 Xadd(uint32 volatile *val, int32 delta)
    87	// Atomically:
    88	//	*val += delta;
    89	//	return *val;
    90	TEXT runtime∕internal∕atomic·Xadd(SB), NOSPLIT, $0-12
    91		MOVL	ptr+0(FP), BX
    92		MOVL	delta+4(FP), AX
    93		MOVL	AX, CX
    94		LOCK
    95		XADDL	AX, 0(BX)
    96		ADDL	CX, AX
    97		MOVL	AX, ret+8(FP)
    98		RET
    99	
   100	TEXT runtime∕internal∕atomic·Xadd64(SB), NOSPLIT, $0-20
   101		// no XADDQ so use CMPXCHG8B loop
   102		MOVL	ptr+0(FP), BP
   103		TESTL	$7, BP
   104		JZ	2(PC)
   105		MOVL	0, AX // crash when unaligned
   106		// DI:SI = delta
   107		MOVL	delta_lo+4(FP), SI
   108		MOVL	delta_hi+8(FP), DI
   109		// DX:AX = *addr
   110		MOVL	0(BP), AX
   111		MOVL	4(BP), DX
   112	addloop:
   113		// CX:BX = DX:AX (*addr) + DI:SI (delta)
   114		MOVL	AX, BX
   115		MOVL	DX, CX
   116		ADDL	SI, BX
   117		ADCL	DI, CX
   118	
   119		// if *addr == DX:AX {
   120		//	*addr = CX:BX
   121		// } else {
   122		//	DX:AX = *addr
   123		// }
   124		// all in one instruction
   125		LOCK
   126		CMPXCHG8B	0(BP)
   127	
   128		JNZ	addloop
   129	
   130		// success
   131		// return CX:BX
   132		MOVL	BX, ret_lo+12(FP)
   133		MOVL	CX, ret_hi+16(FP)
   134		RET
   135	
   136	TEXT runtime∕internal∕atomic·Xchg(SB), NOSPLIT, $0-12
   137		MOVL	ptr+0(FP), BX
   138		MOVL	new+4(FP), AX
   139		XCHGL	AX, 0(BX)
   140		MOVL	AX, ret+8(FP)
   141		RET
   142	
   143	TEXT runtime∕internal∕atomic·Xchguintptr(SB), NOSPLIT, $0-12
   144		JMP	runtime∕internal∕atomic·Xchg(SB)
   145	
   146	TEXT  runtime∕internal∕atomic·Xchg64(SB),NOSPLIT,$0-20
   147		// no XCHGQ so use CMPXCHG8B loop
   148		MOVL	ptr+0(FP), BP
   149		TESTL	$7, BP
   150		JZ	2(PC)
   151		MOVL	0, AX // crash when unaligned
   152		// CX:BX = new
   153		MOVL	new_lo+4(FP), BX
   154		MOVL	new_hi+8(FP), CX
   155		// DX:AX = *addr
   156		MOVL	0(BP), AX
   157		MOVL	4(BP), DX
   158	swaploop:
   159		// if *addr == DX:AX
   160		//	*addr = CX:BX
   161		// else
   162		//	DX:AX = *addr
   163		// all in one instruction
   164		LOCK
   165		CMPXCHG8B	0(BP)
   166		JNZ	swaploop
   167	
   168		// success
   169		// return DX:AX
   170		MOVL	AX, ret_lo+12(FP)
   171		MOVL	DX, ret_hi+16(FP)
   172		RET
   173	
   174	TEXT runtime∕internal∕atomic·StorepNoWB(SB), NOSPLIT, $0-8
   175		MOVL	ptr+0(FP), BX
   176		MOVL	val+4(FP), AX
   177		XCHGL	AX, 0(BX)
   178		RET
   179	
   180	TEXT runtime∕internal∕atomic·Store(SB), NOSPLIT, $0-8
   181		MOVL	ptr+0(FP), BX
   182		MOVL	val+4(FP), AX
   183		XCHGL	AX, 0(BX)
   184		RET
   185	
   186	TEXT runtime∕internal∕atomic·StoreRel(SB), NOSPLIT, $0-8
   187		JMP	runtime∕internal∕atomic·Store(SB)
   188	
   189	// uint64 atomicload64(uint64 volatile* addr);
   190	TEXT runtime∕internal∕atomic·Load64(SB), NOSPLIT, $0-12
   191		MOVL	ptr+0(FP), AX
   192		TESTL	$7, AX
   193		JZ	2(PC)
   194		MOVL	0, AX // crash with nil ptr deref
   195		MOVQ	(AX), M0
   196		MOVQ	M0, ret+4(FP)
   197		EMMS
   198		RET
   199	
   200	// void runtime∕internal∕atomic·Store64(uint64 volatile* addr, uint64 v);
   201	TEXT runtime∕internal∕atomic·Store64(SB), NOSPLIT, $0-12
   202		MOVL	ptr+0(FP), AX
   203		TESTL	$7, AX
   204		JZ	2(PC)
   205		MOVL	0, AX // crash with nil ptr deref
   206		// MOVQ and EMMS were introduced on the Pentium MMX.
   207		MOVQ	val+4(FP), M0
   208		MOVQ	M0, (AX)
   209		EMMS
   210		// This is essentially a no-op, but it provides required memory fencing.
   211		// It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2).
   212		XORL	AX, AX
   213		LOCK
   214		XADDL	AX, (SP)
   215		RET
   216	
   217	// void	runtime∕internal∕atomic·Or8(byte volatile*, byte);
   218	TEXT runtime∕internal∕atomic·Or8(SB), NOSPLIT, $0-5
   219		MOVL	ptr+0(FP), AX
   220		MOVB	val+4(FP), BX
   221		LOCK
   222		ORB	BX, (AX)
   223		RET
   224	
   225	// void	runtime∕internal∕atomic·And8(byte volatile*, byte);
   226	TEXT runtime∕internal∕atomic·And8(SB), NOSPLIT, $0-5
   227		MOVL	ptr+0(FP), AX
   228		MOVB	val+4(FP), BX
   229		LOCK
   230		ANDB	BX, (AX)
   231		RET

View as plain text