github.com/primecitizens/pcz/std@v0.2.1/core/gc/wb_386.s (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright 2023 The Prime Citizens
     3  //
     4  // Copyright 2009 The Go Authors. All rights reserved.
     5  // Use of this source code is governed by a BSD-style
     6  // license that can be found in the LICENSE file.
     7  
     8  //go:build 386
     9  
    10  #include "textflag.h"
    11  
    12  // gcWriteBarrier informs the GC about heap pointer writes.
    13  //
    14  // gcWriteBarrier returns space in a write barrier buffer which
    15  // should be filled in by the caller.
    16  // gcWriteBarrier does NOT follow the Go ABI. It accepts the
    17  // number of bytes of buffer needed in DI, and returns a pointer
    18  // to the buffer space in DI.
    19  // It clobbers FLAGS. It does not clobber any general-purpose registers,
    20  // but may clobber others (e.g., SSE registers).
    21  // Typical use would be, when doing *(CX+88) = AX
    22  //     CMPL    $0, runtime.writeBarrier(SB)
    23  //     JEQ     dowrite
    24  //     CALL    runtime.gcBatchBarrier2(SB)
    25  //     MOVL    AX, (DI)
    26  //     MOVL    88(CX), DX
    27  //     MOVL    DX, 4(DI)
    28  // dowrite:
    29  //     MOVL    AX, 88(CX)
    30  TEXT gcWriteBarrier<>(SB),NOSPLIT,$28
    31  	// Save the registers clobbered by the fast path. This is slightly
    32  	// faster than having the caller spill these.
    33  	MOVL CX, 20(SP)
    34  	MOVL BX, 24(SP)
    35  retry:
    36  	// TODO: Consider passing g.m.p in as an argument so they can be shared
    37  	// across a sequence of write barriers.
    38  	get_tls(BX)
    39  	MOVL g(BX), BX
    40  	MOVL g_m(BX), BX
    41  	MOVL m_p(BX), BX
    42  	// Get current buffer write position.
    43  	MOVL (p_wbBuf+wbBuf_next)(BX), CX // original next position
    44  	ADDL DI, CX // new next position
    45  	// Is the buffer full?
    46  	CMPL CX, (p_wbBuf+wbBuf_end)(BX)
    47  	JA flush
    48  	// Commit to the larger buffer.
    49  	MOVL CX, (p_wbBuf+wbBuf_next)(BX)
    50  	// Make return value (the original next position)
    51  	SUBL DI, CX
    52  	MOVL CX, DI
    53  	// Restore registers.
    54  	MOVL 20(SP), CX
    55  	MOVL 24(SP), BX
    56  	RET
    57  
    58  flush:
    59  	// Save all general purpose registers since these could be
    60  	// clobbered by wbBufFlush and were not saved by the caller.
    61  	MOVL DI, 0(SP)
    62  	MOVL AX, 4(SP)
    63  	// BX already saved
    64  	// CX already saved
    65  	MOVL DX, 8(SP)
    66  	MOVL BP, 12(SP)
    67  	MOVL SI, 16(SP)
    68  	// DI already saved
    69  
    70  	CALL runtime·wbBufFlush(SB)
    71  
    72  	MOVL 0(SP), DI
    73  	MOVL 4(SP), AX
    74  	MOVL 8(SP), DX
    75  	MOVL 12(SP), BP
    76  	MOVL 16(SP), SI
    77  	JMP retry
    78  
    79  TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
    80  	MOVL $4, DI
    81  	JMP gcWriteBarrier<>(SB)
    82  TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
    83  	MOVL $8, DI
    84  	JMP gcWriteBarrier<>(SB)
    85  TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
    86  	MOVL $12, DI
    87  	JMP gcWriteBarrier<>(SB)
    88  TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
    89  	MOVL $16, DI
    90  	JMP gcWriteBarrier<>(SB)
    91  TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
    92  	MOVL $20, DI
    93  	JMP gcWriteBarrier<>(SB)
    94  TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
    95  	MOVL $24, DI
    96  	JMP gcWriteBarrier<>(SB)
    97  TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
    98  	MOVL $28, DI
    99  	JMP gcWriteBarrier<>(SB)
   100  TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
   101  	MOVL $32, DI
   102  	JMP gcWriteBarrier<>(SB)