shithub: gefs

ref: ea50e8ab08f8c76c9bed6169cb2bd6ea2696f44e
dir: gefs/atomic-386.s

View raw version
#define CMPXCHG	/* (CX) */\
	BYTE $0x0F; BYTE $0xB1; BYTE $0x11
#define CMPXCHG64 /* (DI) */\
	BYTE $0x0F; BYTE $0xC7; BYTE $0x0F
#define XADDL /* CX, (AX) */ \
	BYTE $0x67; BYTE $0x0F; BYTE $0xC1; BYTE $0x08
#define MFENCE
	BYTE $0x0F; BYTE $0xAE; BYTE $0xF0

/*  get variants */
TEXT ageti+0(SB),1,$0
TEXT agetl+0(SB),1,$0
TEXT agetp+0(SB),1,$0
	MOVL	p+0(FP), AX
	MOVL	0(AX), AX
	RET

TEXT agetv+0(SB),1,$0
	MOVL	p+0(FP),AX
	MOVL	p+4(FP),BX
	FMOVD	(BX),F0
	FMOVD	F0,(AX)
	RET

/*  set variants */
TEXT aseti+0(SB),1,$0
TEXT asetl+0(SB),1,$0
TEXT asetp+0(SB),1,$0
	MOVL		v+0(FP), AX
	MOVL		0(AX), AX
	MOVL		v+4(FP), BX
	LOCK; XCHGL	(AX), BX
	RET

TEXT asetv+0(SB),1,$0
	MOVL	p+4(FP), DI
	MOVL	nv+8(FP), BX
	MOVL	nv+12(FP), CX
	MOVL	0(DI), AX
	MOVL	4(DI), DX
loop:
	LOCK;	CMPXCHG64
        JNE     loop
	MOVL	p+0(FP),DI
	MOVL	AX, 0(DI)
	MOVL	DX, 4(DI)
	RET

/*  inc variants */
TEXT ainci+0(SB),1,$0
TEXT aincl+0(SB),1,$0
TEXT aincp+0(SB),1,$0
	MOVL		p+0(FP), AX
	MOVL		0(AX), AX
	MOVL		v+4(FP), CX
	LOCK; XADDL //	AX, (DX)
	RET

TEXT aincv+0(SB),1,$0
	MOVL	p+4(FP), DI
retry:
	MOVL	0x0(DI), AX	// ov = *p
	MOVL	0x4(DI), DX
	MOVL	AX, BX		// nv = ov
	MOVL	DX, CX
	ADDL	dv+0x8(FP), BX	// nv += dv
	ADCL	dv+0x12(FP), CX
	LOCK; CMPXCHG64
	JNE	retry
	MOVL	r+0(FP), DI
	MOVL	BX, (DI)
	MOVL	CX, (DI)
	RET

/*  cas variants */
TEXT acasi+0(SB),1,$0
TEXT acasl+0(SB),1,$0
TEXT acasp+0(SB),1,$0
	MOVL	p+0(FP), CX
	MOVL	ov+4(FP), AX
	MOVL	nv+8(FP), DX
	LOCK; CMPXCHG // (CX)
	JNE	fail32
	MOVL	$1,AX
	RET
fail32:
	MOVL	$0,AX
	RET

TEXT acasv+0(SB),1,$0
	MOVL	p+0(FP), DI
	MOVL	ov+0x4(FP), AX
	MOVL	ov+0x8(FP), DX
	MOVL	nv+0xc(FP), BX
	MOVL	nv+0x10(FP), CX
	LOCK; CMPXCHG64 // (DI)
	JNE	fail64
	MOVL	$1,AX
fail64:
	MOVL	$0,AX
	RET

/* barriers (do we want to distinguish types?) */
TEXT coherence+0(SB),1,$0
	MFENCE
	RET