~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/x86/lib/memmove_64.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 /*
  3  * Normally compiler builtins are used, but sometimes the compiler calls out
  4  * of line code. Based on asm-i386/string.h.
  5  *
  6  * This assembly file is re-written from memmove_64.c file.
  7  *      - Copyright 2011 Fenghua Yu <fenghua.yu@intel.com>
  8  */
  9 #include <linux/export.h>
 10 #include <linux/linkage.h>
 11 #include <asm/cpufeatures.h>
 12 #include <asm/alternative.h>
 13 
 14 #undef memmove
 15 
 16 .section .noinstr.text, "ax"
 17 
 18 /*
 19  * Implement memmove(). This can handle overlap between src and dst.
 20  *
 21  * Input:
 22  * rdi: dest
 23  * rsi: src
 24  * rdx: count
 25  *
 26  * Output:
 27  * rax: dest
 28  */
 29 SYM_FUNC_START(__memmove)
 30 
 31         mov %rdi, %rax
 32 
 33         /* Decide forward/backward copy mode */
 34         cmp %rdi, %rsi
 35         jge .Lmemmove_begin_forward
 36         mov %rsi, %r8
 37         add %rdx, %r8
 38         cmp %rdi, %r8
 39         jg 2f
 40 
 41 #define CHECK_LEN       cmp $0x20, %rdx; jb 1f
 42 #define MEMMOVE_BYTES   movq %rdx, %rcx; rep movsb; RET
 43 .Lmemmove_begin_forward:
 44         ALTERNATIVE_2 __stringify(CHECK_LEN), \
 45                       __stringify(CHECK_LEN; MEMMOVE_BYTES), X86_FEATURE_ERMS, \
 46                       __stringify(MEMMOVE_BYTES), X86_FEATURE_FSRM
 47 
 48         /*
 49          * movsq instruction have many startup latency
 50          * so we handle small size by general register.
 51          */
 52         cmp  $680, %rdx
 53         jb      3f
 54         /*
 55          * movsq instruction is only good for aligned case.
 56          */
 57 
 58         cmpb %dil, %sil
 59         je 4f
 60 3:
 61         sub $0x20, %rdx
 62         /*
 63          * We gobble 32 bytes forward in each loop.
 64          */
 65 5:
 66         sub $0x20, %rdx
 67         movq 0*8(%rsi), %r11
 68         movq 1*8(%rsi), %r10
 69         movq 2*8(%rsi), %r9
 70         movq 3*8(%rsi), %r8
 71         leaq 4*8(%rsi), %rsi
 72 
 73         movq %r11, 0*8(%rdi)
 74         movq %r10, 1*8(%rdi)
 75         movq %r9, 2*8(%rdi)
 76         movq %r8, 3*8(%rdi)
 77         leaq 4*8(%rdi), %rdi
 78         jae 5b
 79         addq $0x20, %rdx
 80         jmp 1f
 81         /*
 82          * Handle data forward by movsq.
 83          */
 84         .p2align 4
 85 4:
 86         movq %rdx, %rcx
 87         movq -8(%rsi, %rdx), %r11
 88         lea -8(%rdi, %rdx), %r10
 89         shrq $3, %rcx
 90         rep movsq
 91         movq %r11, (%r10)
 92         jmp 13f
 93 .Lmemmove_end_forward:
 94 
 95         /*
 96          * Handle data backward by movsq.
 97          */
 98         .p2align 4
 99 7:
100         movq %rdx, %rcx
101         movq (%rsi), %r11
102         movq %rdi, %r10
103         leaq -8(%rsi, %rdx), %rsi
104         leaq -8(%rdi, %rdx), %rdi
105         shrq $3, %rcx
106         std
107         rep movsq
108         cld
109         movq %r11, (%r10)
110         jmp 13f
111 
112         /*
113          * Start to prepare for backward copy.
114          */
115         .p2align 4
116 2:
117         cmp $0x20, %rdx
118         jb 1f
119         cmp $680, %rdx
120         jb 6f
121         cmp %dil, %sil
122         je 7b
123 6:
124         /*
125          * Calculate copy position to tail.
126          */
127         addq %rdx, %rsi
128         addq %rdx, %rdi
129         subq $0x20, %rdx
130         /*
131          * We gobble 32 bytes backward in each loop.
132          */
133 8:
134         subq $0x20, %rdx
135         movq -1*8(%rsi), %r11
136         movq -2*8(%rsi), %r10
137         movq -3*8(%rsi), %r9
138         movq -4*8(%rsi), %r8
139         leaq -4*8(%rsi), %rsi
140 
141         movq %r11, -1*8(%rdi)
142         movq %r10, -2*8(%rdi)
143         movq %r9, -3*8(%rdi)
144         movq %r8, -4*8(%rdi)
145         leaq -4*8(%rdi), %rdi
146         jae 8b
147         /*
148          * Calculate copy position to head.
149          */
150         addq $0x20, %rdx
151         subq %rdx, %rsi
152         subq %rdx, %rdi
153 1:
154         cmpq $16, %rdx
155         jb 9f
156         /*
157          * Move data from 16 bytes to 31 bytes.
158          */
159         movq 0*8(%rsi), %r11
160         movq 1*8(%rsi), %r10
161         movq -2*8(%rsi, %rdx), %r9
162         movq -1*8(%rsi, %rdx), %r8
163         movq %r11, 0*8(%rdi)
164         movq %r10, 1*8(%rdi)
165         movq %r9, -2*8(%rdi, %rdx)
166         movq %r8, -1*8(%rdi, %rdx)
167         jmp 13f
168         .p2align 4
169 9:
170         cmpq $8, %rdx
171         jb 10f
172         /*
173          * Move data from 8 bytes to 15 bytes.
174          */
175         movq 0*8(%rsi), %r11
176         movq -1*8(%rsi, %rdx), %r10
177         movq %r11, 0*8(%rdi)
178         movq %r10, -1*8(%rdi, %rdx)
179         jmp 13f
180 10:
181         cmpq $4, %rdx
182         jb 11f
183         /*
184          * Move data from 4 bytes to 7 bytes.
185          */
186         movl (%rsi), %r11d
187         movl -4(%rsi, %rdx), %r10d
188         movl %r11d, (%rdi)
189         movl %r10d, -4(%rdi, %rdx)
190         jmp 13f
191 11:
192         cmp $2, %rdx
193         jb 12f
194         /*
195          * Move data from 2 bytes to 3 bytes.
196          */
197         movw (%rsi), %r11w
198         movw -2(%rsi, %rdx), %r10w
199         movw %r11w, (%rdi)
200         movw %r10w, -2(%rdi, %rdx)
201         jmp 13f
202 12:
203         cmp $1, %rdx
204         jb 13f
205         /*
206          * Move data for 1 byte.
207          */
208         movb (%rsi), %r11b
209         movb %r11b, (%rdi)
210 13:
211         RET
212 SYM_FUNC_END(__memmove)
213 EXPORT_SYMBOL(__memmove)
214 
215 SYM_FUNC_ALIAS_MEMFUNC(memmove, __memmove)
216 EXPORT_SYMBOL(memmove)

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php