1 /* SPDX-License-Identifier: GPL-2.0 */ !! 1 /* memmove.S: Simple memmove implementation. 2 /* << 3 * arch/alpha/lib/memmove.S << 4 * 2 * 5 * Barely optimized memmove routine for Alpha !! 3 * Copyright (C) 1997, 2004 David S. Miller (davem@redhat.com) 6 * !! 4 * Copyright (C) 1996, 1997, 1998, 1999 Jakub Jelinek (jj@ultra.linux.cz) 7 * This is hand-massaged output from the origi << 8 * memcpy whenever possible; the backwards cop << 9 */ 5 */ 10 #include <linux/export.h> << 11 .set noat << 12 .set noreorder << 13 .text << 14 6 15 .align 4 !! 7 #include <linux/linkage.h> 16 .globl memmove !! 8 #include <asm/export.h> 17 .ent memmove << 18 memmove: << 19 ldgp $29, 0($27) << 20 unop << 21 nop << 22 .prologue 1 << 23 << 24 addq $16,$18,$4 << 25 addq $17,$18,$5 << 26 cmpule $4,$17,$1 /* de << 27 cmpule $5,$16,$2 /* de << 28 << 29 bis $1,$2,$1 << 30 mov $16,$0 << 31 xor $16,$17,$2 << 32 bne $1,memcpy !sameg << 33 << 34 and $2,7,$2 /* Tes << 35 and $16,7,$1 << 36 cmpule $16,$17,$3 << 37 bne $3,$memmove_up /* des << 38 << 39 and $4,7,$1 << 40 bne $2,$misaligned_dn << 41 unop << 42 beq $1,$skip_aligned_byte_loop_head_dn << 43 << 44 $aligned_byte_loop_head_dn: << 45 lda $4,-1($4) << 46 lda $5,-1($5) << 47 unop << 48 ble $18,$egress << 49 << 50 ldq_u $3,0($5) << 51 ldq_u $2,0($4) << 52 lda $18,-1($18) << 53 extbl $3,$5,$1 << 54 << 55 insbl $1,$4,$1 << 56 mskbl $2,$4,$2 << 57 bis $1,$2,$1 << 58 and $4,7,$6 << 59 << 60 stq_u $1,0($4) << 61 bne $6,$aligned_byte_loop_head_dn << 62 << 63 $skip_aligned_byte_loop_head_dn: << 64 lda $18,-8($18) << 65 blt $18,$skip_aligned_word_loop_dn << 66 << 67 $aligned_word_loop_dn: << 68 ldq $1,-8($5) << 69 nop << 70 lda $5,-8($5) << 71 lda $18,-8($18) << 72 << 73 stq $1,-8($4) << 74 nop << 75 lda $4,-8($4) << 76 bge $18,$aligned_word_loop_dn << 77 << 78 $skip_aligned_word_loop_dn: << 79 lda $18,8($18) << 80 bgt $18,$byte_loop_tail_dn << 81 unop << 82 ret $31,($26),1 << 83 << 84 .align 4 << 85 $misaligned_dn: << 86 nop << 87 fnop << 88 unop << 89 beq $18,$egress << 90 << 91 $byte_loop_tail_dn: << 92 ldq_u $3,-1($5) << 93 ldq_u $2,-1($4) << 94 lda $5,-1($5) << 95 lda $4,-1($4) << 96 << 97 lda $18,-1($18) << 98 extbl $3,$5,$1 << 99 insbl $1,$4,$1 << 100 mskbl $2,$4,$2 << 101 << 102 bis $1,$2,$1 << 103 stq_u $1,0($4) << 104 bgt $18,$byte_loop_tail_dn << 105 br $egress << 106 << 107 $memmove_up: << 108 mov $16,$4 << 109 mov $17,$5 << 110 bne $2,$misaligned_up << 111 beq $1,$skip_aligned_byte_loop_head_up << 112 << 113 $aligned_byte_loop_head_up: << 114 unop << 115 ble $18,$egress << 116 ldq_u $3,0($5) << 117 ldq_u $2,0($4) << 118 << 119 lda $18,-1($18) << 120 extbl $3,$5,$1 << 121 insbl $1,$4,$1 << 122 mskbl $2,$4,$2 << 123 << 124 bis $1,$2,$1 << 125 lda $5,1($5) << 126 stq_u $1,0($4) << 127 lda $4,1($4) << 128 << 129 and $4,7,$6 << 130 bne $6,$aligned_byte_loop_head_up << 131 << 132 $skip_aligned_byte_loop_head_up: << 133 lda $18,-8($18) << 134 blt $18,$skip_aligned_word_loop_up << 135 << 136 $aligned_word_loop_up: << 137 ldq $1,0($5) << 138 nop << 139 lda $5,8($5) << 140 lda $18,-8($18) << 141 << 142 stq $1,0($4) << 143 nop << 144 lda $4,8($4) << 145 bge $18,$aligned_word_loop_up << 146 << 147 $skip_aligned_word_loop_up: << 148 lda $18,8($18) << 149 bgt $18,$byte_loop_tail_up << 150 unop << 151 ret $31,($26),1 << 152 << 153 .align 4 << 154 $misaligned_up: << 155 nop << 156 fnop << 157 unop << 158 beq $18,$egress << 159 << 160 $byte_loop_tail_up: << 161 ldq_u $3,0($5) << 162 ldq_u $2,0($4) << 163 lda $18,-1($18) << 164 extbl $3,$5,$1 << 165 << 166 insbl $1,$4,$1 << 167 mskbl $2,$4,$2 << 168 bis $1,$2,$1 << 169 stq_u $1,0($4) << 170 << 171 lda $5,1($5) << 172 lda $4,1($4) << 173 nop << 174 bgt $18,$byte_loop_tail_up << 175 << 176 $egress: << 177 ret $31,($26),1 << 178 nop << 179 nop << 180 nop << 181 9 182 .end memmove !! 10 .text 183 EXPORT_SYMBOL(memmove) !! 11 ENTRY(memmove) /* o0=dst o1=src o2=len */ >> 12 brz,pn %o2, 99f >> 13 mov %o0, %g1 >> 14 >> 15 cmp %o0, %o1 >> 16 bleu,pt %xcc, 2f >> 17 add %o1, %o2, %g7 >> 18 cmp %g7, %o0 >> 19 bleu,pt %xcc, memcpy >> 20 add %o0, %o2, %o5 >> 21 sub %g7, 1, %o1 >> 22 >> 23 sub %o5, 1, %o0 >> 24 1: ldub [%o1], %g7 >> 25 subcc %o2, 1, %o2 >> 26 sub %o1, 1, %o1 >> 27 stb %g7, [%o0] >> 28 bne,pt %icc, 1b >> 29 sub %o0, 1, %o0 >> 30 99: >> 31 retl >> 32 mov %g1, %o0 >> 33 >> 34 /* We can't just call memcpy for these memmove cases. On some >> 35 * chips the memcpy uses cache initializing stores and when dst >> 36 * and src are close enough, those can clobber the source data >> 37 * before we've loaded it in. >> 38 */ >> 39 2: or %o0, %o1, %g7 >> 40 or %o2, %g7, %g7 >> 41 andcc %g7, 0x7, %g0 >> 42 bne,pn %xcc, 4f >> 43 nop >> 44 >> 45 3: ldx [%o1], %g7 >> 46 add %o1, 8, %o1 >> 47 subcc %o2, 8, %o2 >> 48 add %o0, 8, %o0 >> 49 bne,pt %icc, 3b >> 50 stx %g7, [%o0 - 0x8] >> 51 ba,a,pt %xcc, 99b >> 52 >> 53 4: ldub [%o1], %g7 >> 54 add %o1, 1, %o1 >> 55 subcc %o2, 1, %o2 >> 56 add %o0, 1, %o0 >> 57 bne,pt %icc, 4b >> 58 stb %g7, [%o0 - 0x1] >> 59 ba,a,pt %xcc, 99b >> 60 ENDPROC(memmove) >> 61 EXPORT_SYMBOL(memmove)
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.