github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/safecopy/memclr_amd64.s (about)

     1  // Copyright 2014 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  // handleMemclrFault returns (the value stored in AX, the value stored in DI).
     8  // Control is transferred to it when memclr below receives SIGSEGV or SIGBUS,
     9  // with the faulting address stored in AX and the signal number stored in DI.
    10  //
    11  // It must have the same frame configuration as memclr so that it can undo any
    12  // potential call frame set up by the assembler.
    13  TEXT handleMemclrFault(SB), NOSPLIT, $0-28
    14  	MOVQ	AX, addr+16(FP)
    15  	MOVL	DI, sig+24(FP)
    16  	RET
    17  
    18  // memclr sets the n bytes following ptr to zeroes. If a SIGSEGV or SIGBUS
    19  // signal is received during the write, it returns the address that caused the
    20  // fault and the number of the signal that was received. Otherwise, it returns
    21  // an unspecified address and a signal number of 0.
    22  //
    23  // Data is written in order, such that if a fault happens at address p, it is
    24  // safe to assume that all data before p-maxRegisterSize has already been
    25  // successfully written.
    26  //
    27  // The code is derived from runtime.memclrNoHeapPointers.
    28  //
    29  // func memclr(ptr unsafe.Pointer, n uintptr) (fault unsafe.Pointer, sig int32)
    30  TEXT ·memclr(SB), NOSPLIT, $0-28
    31  	// Store 0 as the returned signal number. If we run to completion,
    32  	// this is the value the caller will see; if a signal is received,
    33  	// handleMemclrFault will store a different value in this address.
    34  	MOVL	$0, sig+24(FP)
    35  
    36  	MOVQ	ptr+0(FP), DI
    37  	MOVQ	n+8(FP), BX
    38  	XORQ	AX, AX
    39  
    40  	// MOVOU seems always faster than REP STOSQ.
    41  tail:
    42  	TESTQ	BX, BX
    43  	JEQ	_0
    44  	CMPQ	BX, $2
    45  	JBE	_1or2
    46  	CMPQ	BX, $4
    47  	JBE	_3or4
    48  	CMPQ	BX, $8
    49  	JB	_5through7
    50  	JE	_8
    51  	CMPQ	BX, $16
    52  	JBE	_9through16
    53  	PXOR	X0, X0
    54  	CMPQ	BX, $32
    55  	JBE	_17through32
    56  	CMPQ	BX, $64
    57  	JBE	_33through64
    58  	CMPQ	BX, $128
    59  	JBE	_65through128
    60  	CMPQ	BX, $256
    61  	JBE	_129through256
    62  	// TODO: use branch table and BSR to make this just a single dispatch
    63  	// TODO: for really big clears, use MOVNTDQ, even without AVX2.
    64  
    65  loop:
    66  	MOVOU	X0, 0(DI)
    67  	MOVOU	X0, 16(DI)
    68  	MOVOU	X0, 32(DI)
    69  	MOVOU	X0, 48(DI)
    70  	MOVOU	X0, 64(DI)
    71  	MOVOU	X0, 80(DI)
    72  	MOVOU	X0, 96(DI)
    73  	MOVOU	X0, 112(DI)
    74  	MOVOU	X0, 128(DI)
    75  	MOVOU	X0, 144(DI)
    76  	MOVOU	X0, 160(DI)
    77  	MOVOU	X0, 176(DI)
    78  	MOVOU	X0, 192(DI)
    79  	MOVOU	X0, 208(DI)
    80  	MOVOU	X0, 224(DI)
    81  	MOVOU	X0, 240(DI)
    82  	SUBQ	$256, BX
    83  	ADDQ	$256, DI
    84  	CMPQ	BX, $256
    85  	JAE	loop
    86  	JMP	tail
    87  
    88  _1or2:
    89  	MOVB	AX, (DI)
    90  	MOVB	AX, -1(DI)(BX*1)
    91  	RET
    92  _0:
    93  	RET
    94  _3or4:
    95  	MOVW	AX, (DI)
    96  	MOVW	AX, -2(DI)(BX*1)
    97  	RET
    98  _5through7:
    99  	MOVL	AX, (DI)
   100  	MOVL	AX, -4(DI)(BX*1)
   101  	RET
   102  _8:
   103  	// We need a separate case for 8 to make sure we clear pointers atomically.
   104  	MOVQ	AX, (DI)
   105  	RET
   106  _9through16:
   107  	MOVQ	AX, (DI)
   108  	MOVQ	AX, -8(DI)(BX*1)
   109  	RET
   110  _17through32:
   111  	MOVOU	X0, (DI)
   112  	MOVOU	X0, -16(DI)(BX*1)
   113  	RET
   114  _33through64:
   115  	MOVOU	X0, (DI)
   116  	MOVOU	X0, 16(DI)
   117  	MOVOU	X0, -32(DI)(BX*1)
   118  	MOVOU	X0, -16(DI)(BX*1)
   119  	RET
   120  _65through128:
   121  	MOVOU	X0, (DI)
   122  	MOVOU	X0, 16(DI)
   123  	MOVOU	X0, 32(DI)
   124  	MOVOU	X0, 48(DI)
   125  	MOVOU	X0, -64(DI)(BX*1)
   126  	MOVOU	X0, -48(DI)(BX*1)
   127  	MOVOU	X0, -32(DI)(BX*1)
   128  	MOVOU	X0, -16(DI)(BX*1)
   129  	RET
   130  _129through256:
   131  	MOVOU	X0, (DI)
   132  	MOVOU	X0, 16(DI)
   133  	MOVOU	X0, 32(DI)
   134  	MOVOU	X0, 48(DI)
   135  	MOVOU	X0, 64(DI)
   136  	MOVOU	X0, 80(DI)
   137  	MOVOU	X0, 96(DI)
   138  	MOVOU	X0, 112(DI)
   139  	MOVOU	X0, -128(DI)(BX*1)
   140  	MOVOU	X0, -112(DI)(BX*1)
   141  	MOVOU	X0, -96(DI)(BX*1)
   142  	MOVOU	X0, -80(DI)(BX*1)
   143  	MOVOU	X0, -64(DI)(BX*1)
   144  	MOVOU	X0, -48(DI)(BX*1)
   145  	MOVOU	X0, -32(DI)(BX*1)
   146  	MOVOU	X0, -16(DI)(BX*1)
   147  	RET
   148  
   149  // func addrOfMemclr() uintptr
   150  TEXT ·addrOfMemclr(SB), $0-8
   151  	MOVQ	$·memclr(SB), AX
   152  	MOVQ	AX, ret+0(FP)
   153  	RET