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