1/*- 2 * Copyright (c) 2018 Instituto de Pesquisas Eldorado 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the author nor the names of its contributors may 14 * be used to endorse or promote products derived from this software 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 30#include <machine/asm.h> 31__FBSDID("$FreeBSD$"); 32 33#if 0 34 RCSID("$NetBSD: strcpy.S,v 1.0 2018/05/08 13:00:49 lbianc Exp $") 35#endif 36 37ENTRY(__strcpy_arch_2_05) 38 mr %r8, %r3 39 40/* 41 * Aligning the reading address, even if it is already aligned to avoid 42 * performance degradation with strings with 8 bytes or less. 43 */ 44.Lalignment: 45 lbz %r0,0(%r4) 46 cmpdi cr7,%r0,0 47 stb %r0,0(%r8) 48 beq cr7,.Lexit 49 addi %r4,%r4,1 50 addi %r8,%r8,1 51 andi. %r0,%r4,0x7 52 bne .Lalignment 53 54/* Copy by double word with aligned address. */ 55.Lcopy_dw: 56 ld %r0,0(%r4) 57 xor %r6,%r6,%r6 58 cmpb %r5,%r0,%r6 59 cmpdi cr7,%r5,0 60 bne cr7,.Lcheck_zero 61 /* Backward r8 to use stdu instruction in Lcopy_dw_loop */ 62 addi %r8,%r8,-8 63.Lcopy_dw_loop: 64 stdu %r0,8(%r8) 65 ldu %r0,8(%r4) 66 cmpb %r5,%r0,%r6 67 cmpdi cr7,%r5,0 68 beq cr7,.Lcopy_dw_loop 69 70 addi %r8,%r8,8 /* Forward r8 to use std instruction. */ 71#if defined(__BIG_ENDIAN__) 72/* Find where the zero is located. */ 73.Lcheck_zero: 74 rldicr. %r5,%r0,0,7 75 beq .Lfound_on_byte_0 76 rldicr. %r7,%r0,8,7 77 beq .Lfound_on_byte_1 78 rldicr. %r7,%r0,16,7 79 beq .Lfound_on_byte_2 80 rldicr. %r7,%r0,24,7 81 beq .Lfound_on_byte_3 82 andis. %r7,%r0,0xff00 83 beq .Lfound_on_byte_4 84 andis. %r7,%r0,0xff 85 beq .Lfound_on_byte_5 86 andi. %r7,%r0,0xff00 87 beq .Lfound_on_byte_6 88 89/* Copy the last string bytes according to the string end position. */ 90.Lfound_on_byte_7: 91 std %r0,0(%r8) 92 b .Lexit 93 94.Lfound_on_byte_6: 95 srdi %r6,%r0,32 96 stw %r6,0(%r8) 97 srdi %r6,%r0,16 98 sth %r6,4(%r8) 99 srdi %r6,%r0,8 100 stb %r6,6(%r8) 101 b .Lexit 102 103.Lfound_on_byte_5: 104 srdi %r6,%r0,32 105 stw %r6,0(%r8) 106 srdi %r6,%r0,16 107 sth %r6,4(%r8) 108 b .Lexit 109 110.Lfound_on_byte_4: 111 srdi %r6,%r0,32 112 stw %r6,0(%r8) 113 srdi %r6,%r0,24 114 stb %r6,4(%r8) 115 b .Lexit 116 117.Lfound_on_byte_3: 118 srdi %r6,%r0,32 119 stw %r6,0(%r8) 120 b .Lexit 121 122.Lfound_on_byte_2: 123 srdi %r6,%r0,48 124 sth %r6,0(%r8) 125 srdi %r6,%r0,40 126 stb %r6,2(%r8) 127 b .Lexit 128 129.Lfound_on_byte_1: 130 srdi %r6,%r0,48 131 sth %r6,0(%r8) 132 b .Lexit 133 134.Lfound_on_byte_0: 135 srdi %r6,%r0,56 136 stb %r6,0(%r8) 137#elif defined(__LITTLE_ENDIAN__) 138/* Find where the zero is located. */ 139.Lcheck_zero: 140 andi. %r7,%r0,0xff 141 beq .Lfound_on_byte_0 142 andi. %r7,%r0,0xff00 143 beq .Lfound_on_byte_1 144 andis. %r7,%r0,0xff 145 beq .Lfound_on_byte_2 146 andis. %r7,%r0,0xff00 147 beq .Lfound_on_byte_3 148 rldicr. %r7,%r0,24,7 149 beq .Lfound_on_byte_4 150 rldicr. %r7,%r0,16,7 151 beq .Lfound_on_byte_5 152 rldicr. %r7,%r0,8,7 153 beq .Lfound_on_byte_6 154 155/* Copy the last string bytes according to the string end position. */ 156.Lfound_on_byte_7: 157 std %r0,0(%r8) 158 b .Lexit 159 160.Lfound_on_byte_6: 161 stw %r0,0(%r8) 162 srdi %r6,%r0,32 163 sth %r6,4(%r8) 164 srdi %r6,%r0,48 165 stb %r6,6(%r8) 166 b .Lexit 167 168.Lfound_on_byte_5: 169 stw %r0,0(%r8) 170 srdi %r6,%r0,32 171 sth %r6,4(%r8) 172 b .Lexit 173 174.Lfound_on_byte_4: 175 stw %r0,0(%r8) 176 srdi %r6,%r0,32 177 stb %r6,4(%r8) 178 b .Lexit 179 180.Lfound_on_byte_3: 181 stw %r0,0(%r8) 182 b .Lexit 183 184.Lfound_on_byte_2: 185 sth %r0,0(%r8) 186 srdi %r6,%r0,16 187 stb %r6,2(%r8) 188 b .Lexit 189 190.Lfound_on_byte_1: 191 sth %r0,0(%r8) 192 b .Lexit 193 194.Lfound_on_byte_0: 195 stb %r0,0(%r8) 196#else 197#error "Unable to determine Endianness" 198#endif 199.Lexit: 200 blr 201 202END(__strcpy_arch_2_05) 203 204 .section .note.GNU-stack,"",%progbits 205