root/arch/powerpc/lib/string_64.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0-or-later */
   2 /*
   3  *
   4  * Copyright (C) IBM Corporation, 2012
   5  *
   6  * Author: Anton Blanchard <anton@au.ibm.com>
   7  */
   8 
   9 #include <asm/ppc_asm.h>
  10 #include <asm/linkage.h>
  11 #include <asm/asm-offsets.h>
  12 #include <asm/export.h>
  13 
  14         .section        ".toc","aw"
  15 PPC64_CACHES:
  16         .tc             ppc64_caches[TC],ppc64_caches
  17         .section        ".text"
  18 
  19 /**
  20  * __arch_clear_user: - Zero a block of memory in user space, with less checking.
  21  * @to:   Destination address, in user space.
  22  * @n:    Number of bytes to zero.
  23  *
  24  * Zero a block of memory in user space.  Caller must check
  25  * the specified block with access_ok() before calling this function.
  26  *
  27  * Returns number of bytes that could not be cleared.
  28  * On success, this will be zero.
  29  */
  30 
  31         .macro err1
  32 100:
  33         EX_TABLE(100b,.Ldo_err1)
  34         .endm
  35 
  36         .macro err2
  37 200:
  38         EX_TABLE(200b,.Ldo_err2)
  39         .endm
  40 
  41         .macro err3
  42 300:
  43         EX_TABLE(300b,.Ldo_err3)
  44         .endm
  45 
  46 .Ldo_err1:
  47         mr      r3,r8
  48 
  49 .Ldo_err2:
  50         mtctr   r4
  51 1:
  52 err3;   stb     r0,0(r3)
  53         addi    r3,r3,1
  54         addi    r4,r4,-1
  55         bdnz    1b
  56 
  57 .Ldo_err3:
  58         mr      r3,r4
  59         blr
  60 
  61 _GLOBAL_TOC(__arch_clear_user)
  62         cmpdi   r4,32
  63         neg     r6,r3
  64         li      r0,0
  65         blt     .Lshort_clear
  66         mr      r8,r3
  67         mtocrf  0x01,r6
  68         clrldi  r6,r6,(64-3)
  69 
  70         /* Get the destination 8 byte aligned */
  71         bf      cr7*4+3,1f
  72 err1;   stb     r0,0(r3)
  73         addi    r3,r3,1
  74 
  75 1:      bf      cr7*4+2,2f
  76 err1;   sth     r0,0(r3)
  77         addi    r3,r3,2
  78 
  79 2:      bf      cr7*4+1,3f
  80 err1;   stw     r0,0(r3)
  81         addi    r3,r3,4
  82 
  83 3:      sub     r4,r4,r6
  84 
  85         cmpdi   r4,32
  86         cmpdi   cr1,r4,512
  87         blt     .Lshort_clear
  88         bgt     cr1,.Llong_clear
  89 
  90 .Lmedium_clear:
  91         srdi    r6,r4,5
  92         mtctr   r6
  93 
  94         /* Do 32 byte chunks */
  95 4:
  96 err2;   std     r0,0(r3)
  97 err2;   std     r0,8(r3)
  98 err2;   std     r0,16(r3)
  99 err2;   std     r0,24(r3)
 100         addi    r3,r3,32
 101         addi    r4,r4,-32
 102         bdnz    4b
 103 
 104 .Lshort_clear:
 105         /* up to 31 bytes to go */
 106         cmpdi   r4,16
 107         blt     6f
 108 err2;   std     r0,0(r3)
 109 err2;   std     r0,8(r3)
 110         addi    r3,r3,16
 111         addi    r4,r4,-16
 112 
 113         /* Up to 15 bytes to go */
 114 6:      mr      r8,r3
 115         clrldi  r4,r4,(64-4)
 116         mtocrf  0x01,r4
 117         bf      cr7*4+0,7f
 118 err1;   std     r0,0(r3)
 119         addi    r3,r3,8
 120 
 121 7:      bf      cr7*4+1,8f
 122 err1;   stw     r0,0(r3)
 123         addi    r3,r3,4
 124 
 125 8:      bf      cr7*4+2,9f
 126 err1;   sth     r0,0(r3)
 127         addi    r3,r3,2
 128 
 129 9:      bf      cr7*4+3,10f
 130 err1;   stb     r0,0(r3)
 131 
 132 10:     li      r3,0
 133         blr
 134 
 135 .Llong_clear:
 136         ld      r5,PPC64_CACHES@toc(r2)
 137 
 138         bf      cr7*4+0,11f
 139 err2;   std     r0,0(r3)
 140         addi    r3,r3,8
 141         addi    r4,r4,-8
 142 
 143         /* Destination is 16 byte aligned, need to get it cache block aligned */
 144 11:     lwz     r7,DCACHEL1LOGBLOCKSIZE(r5)
 145         lwz     r9,DCACHEL1BLOCKSIZE(r5)
 146 
 147         /*
 148          * With worst case alignment the long clear loop takes a minimum
 149          * of 1 byte less than 2 cachelines.
 150          */
 151         sldi    r10,r9,2
 152         cmpd    r4,r10
 153         blt     .Lmedium_clear
 154 
 155         neg     r6,r3
 156         addi    r10,r9,-1
 157         and.    r5,r6,r10
 158         beq     13f
 159 
 160         srdi    r6,r5,4
 161         mtctr   r6
 162         mr      r8,r3
 163 12:
 164 err1;   std     r0,0(r3)
 165 err1;   std     r0,8(r3)
 166         addi    r3,r3,16
 167         bdnz    12b
 168 
 169         sub     r4,r4,r5
 170 
 171 13:     srd     r6,r4,r7
 172         mtctr   r6
 173         mr      r8,r3
 174 14:
 175 err1;   dcbz    0,r3
 176         add     r3,r3,r9
 177         bdnz    14b
 178 
 179         and     r4,r4,r10
 180 
 181         cmpdi   r4,32
 182         blt     .Lshort_clear
 183         b       .Lmedium_clear
 184 EXPORT_SYMBOL(__arch_clear_user)

/* [<][>][^][v][top][bottom][index][help] */