ref: f9ba748e3856172c4b5e0026bf1049706a83a520
dir: /atomic-386.s/
#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