1075fb85fSLeandro Lupori/*- 2075fb85fSLeandro Lupori * Copyright (c) 2018 Instituto de Pesquisas Eldorado 3075fb85fSLeandro Lupori * All rights reserved. 4075fb85fSLeandro Lupori * 5075fb85fSLeandro Lupori * Redistribution and use in source and binary forms, with or without 6075fb85fSLeandro Lupori * modification, are permitted provided that the following conditions 7075fb85fSLeandro Lupori * are met: 8075fb85fSLeandro Lupori * 1. Redistributions of source code must retain the above copyright 9075fb85fSLeandro Lupori * notice, this list of conditions and the following disclaimer. 10075fb85fSLeandro Lupori * 2. Redistributions in binary form must reproduce the above copyright 11075fb85fSLeandro Lupori * notice, this list of conditions and the following disclaimer in the 12075fb85fSLeandro Lupori * documentation and/or other materials provided with the distribution. 13075fb85fSLeandro Lupori * 3. Neither the name of the author nor the names of its contributors may 14075fb85fSLeandro Lupori * be used to endorse or promote products derived from this software 15075fb85fSLeandro Lupori * 16075fb85fSLeandro Lupori * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17075fb85fSLeandro Lupori * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18075fb85fSLeandro Lupori * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19075fb85fSLeandro Lupori * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20075fb85fSLeandro Lupori * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21075fb85fSLeandro Lupori * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22075fb85fSLeandro Lupori * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23075fb85fSLeandro Lupori * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24075fb85fSLeandro Lupori * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25075fb85fSLeandro Lupori * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26075fb85fSLeandro Lupori * SUCH DAMAGE. 27075fb85fSLeandro Lupori */ 28075fb85fSLeandro Lupori 29075fb85fSLeandro Lupori 30075fb85fSLeandro Lupori#include <machine/asm.h> 31075fb85fSLeandro Lupori#if 0 32075fb85fSLeandro Lupori RCSID("$NetBSD: strcpy.S,v 1.0 2018/05/08 13:00:49 lbianc Exp $") 33075fb85fSLeandro Lupori#endif 34075fb85fSLeandro Lupori 35075fb85fSLeandro LuporiENTRY(__strcpy_arch_2_05) 36075fb85fSLeandro Lupori mr %r8, %r3 37075fb85fSLeandro Lupori 38075fb85fSLeandro Lupori/* 39075fb85fSLeandro Lupori * Aligning the reading address, even if it is already aligned to avoid 40075fb85fSLeandro Lupori * performance degradation with strings with 8 bytes or less. 41075fb85fSLeandro Lupori */ 42075fb85fSLeandro Lupori.Lalignment: 43075fb85fSLeandro Lupori lbz %r0,0(%r4) 44075fb85fSLeandro Lupori cmpdi cr7,%r0,0 45075fb85fSLeandro Lupori stb %r0,0(%r8) 46075fb85fSLeandro Lupori beq cr7,.Lexit 47075fb85fSLeandro Lupori addi %r4,%r4,1 48075fb85fSLeandro Lupori addi %r8,%r8,1 49075fb85fSLeandro Lupori andi. %r0,%r4,0x7 50075fb85fSLeandro Lupori bne .Lalignment 51075fb85fSLeandro Lupori 52075fb85fSLeandro Lupori/* Copy by double word with aligned address. */ 53075fb85fSLeandro Lupori.Lcopy_dw: 54075fb85fSLeandro Lupori ld %r0,0(%r4) 55075fb85fSLeandro Lupori xor %r6,%r6,%r6 56075fb85fSLeandro Lupori cmpb %r5,%r0,%r6 57075fb85fSLeandro Lupori cmpdi cr7,%r5,0 58075fb85fSLeandro Lupori bne cr7,.Lcheck_zero 59075fb85fSLeandro Lupori /* Backward r8 to use stdu instruction in Lcopy_dw_loop */ 60075fb85fSLeandro Lupori addi %r8,%r8,-8 61075fb85fSLeandro Lupori.Lcopy_dw_loop: 62075fb85fSLeandro Lupori stdu %r0,8(%r8) 63075fb85fSLeandro Lupori ldu %r0,8(%r4) 64075fb85fSLeandro Lupori cmpb %r5,%r0,%r6 65075fb85fSLeandro Lupori cmpdi cr7,%r5,0 66075fb85fSLeandro Lupori beq cr7,.Lcopy_dw_loop 67075fb85fSLeandro Lupori 68075fb85fSLeandro Lupori addi %r8,%r8,8 /* Forward r8 to use std instruction. */ 69*9f50aa45SLeandro Lupori#if defined(__BIG_ENDIAN__) 70075fb85fSLeandro Lupori/* Find where the zero is located. */ 71075fb85fSLeandro Lupori.Lcheck_zero: 72075fb85fSLeandro Lupori rldicr. %r5,%r0,0,7 73075fb85fSLeandro Lupori beq .Lfound_on_byte_0 74075fb85fSLeandro Lupori rldicr. %r7,%r0,8,7 75075fb85fSLeandro Lupori beq .Lfound_on_byte_1 76075fb85fSLeandro Lupori rldicr. %r7,%r0,16,7 77075fb85fSLeandro Lupori beq .Lfound_on_byte_2 78075fb85fSLeandro Lupori rldicr. %r7,%r0,24,7 79075fb85fSLeandro Lupori beq .Lfound_on_byte_3 80075fb85fSLeandro Lupori andis. %r7,%r0,0xff00 81075fb85fSLeandro Lupori beq .Lfound_on_byte_4 82075fb85fSLeandro Lupori andis. %r7,%r0,0xff 83075fb85fSLeandro Lupori beq .Lfound_on_byte_5 84075fb85fSLeandro Lupori andi. %r7,%r0,0xff00 85075fb85fSLeandro Lupori beq .Lfound_on_byte_6 86075fb85fSLeandro Lupori 87075fb85fSLeandro Lupori/* Copy the last string bytes according to the string end position. */ 88075fb85fSLeandro Lupori.Lfound_on_byte_7: 89075fb85fSLeandro Lupori std %r0,0(%r8) 90075fb85fSLeandro Lupori b .Lexit 91075fb85fSLeandro Lupori 92075fb85fSLeandro Lupori.Lfound_on_byte_6: 93075fb85fSLeandro Lupori srdi %r6,%r0,32 94075fb85fSLeandro Lupori stw %r6,0(%r8) 95075fb85fSLeandro Lupori srdi %r6,%r0,16 96075fb85fSLeandro Lupori sth %r6,4(%r8) 97075fb85fSLeandro Lupori srdi %r6,%r0,8 98075fb85fSLeandro Lupori stb %r6,6(%r8) 99075fb85fSLeandro Lupori b .Lexit 100075fb85fSLeandro Lupori 101075fb85fSLeandro Lupori.Lfound_on_byte_5: 102075fb85fSLeandro Lupori srdi %r6,%r0,32 103075fb85fSLeandro Lupori stw %r6,0(%r8) 104075fb85fSLeandro Lupori srdi %r6,%r0,16 105075fb85fSLeandro Lupori sth %r6,4(%r8) 106075fb85fSLeandro Lupori b .Lexit 107075fb85fSLeandro Lupori 108075fb85fSLeandro Lupori.Lfound_on_byte_4: 109075fb85fSLeandro Lupori srdi %r6,%r0,32 110075fb85fSLeandro Lupori stw %r6,0(%r8) 111075fb85fSLeandro Lupori srdi %r6,%r0,24 112075fb85fSLeandro Lupori stb %r6,4(%r8) 113075fb85fSLeandro Lupori b .Lexit 114075fb85fSLeandro Lupori 115075fb85fSLeandro Lupori.Lfound_on_byte_3: 116075fb85fSLeandro Lupori srdi %r6,%r0,32 117075fb85fSLeandro Lupori stw %r6,0(%r8) 118075fb85fSLeandro Lupori b .Lexit 119075fb85fSLeandro Lupori 120075fb85fSLeandro Lupori.Lfound_on_byte_2: 121075fb85fSLeandro Lupori srdi %r6,%r0,48 122075fb85fSLeandro Lupori sth %r6,0(%r8) 123075fb85fSLeandro Lupori srdi %r6,%r0,40 124075fb85fSLeandro Lupori stb %r6,2(%r8) 125075fb85fSLeandro Lupori b .Lexit 126075fb85fSLeandro Lupori 127075fb85fSLeandro Lupori.Lfound_on_byte_1: 128075fb85fSLeandro Lupori srdi %r6,%r0,48 129075fb85fSLeandro Lupori sth %r6,0(%r8) 130075fb85fSLeandro Lupori b .Lexit 131075fb85fSLeandro Lupori 132075fb85fSLeandro Lupori.Lfound_on_byte_0: 133075fb85fSLeandro Lupori srdi %r6,%r0,56 134075fb85fSLeandro Lupori stb %r6,0(%r8) 135*9f50aa45SLeandro Lupori#elif defined(__LITTLE_ENDIAN__) 136*9f50aa45SLeandro Lupori/* Find where the zero is located. */ 137*9f50aa45SLeandro Lupori.Lcheck_zero: 138*9f50aa45SLeandro Lupori andi. %r7,%r0,0xff 139*9f50aa45SLeandro Lupori beq .Lfound_on_byte_0 140*9f50aa45SLeandro Lupori andi. %r7,%r0,0xff00 141*9f50aa45SLeandro Lupori beq .Lfound_on_byte_1 142*9f50aa45SLeandro Lupori andis. %r7,%r0,0xff 143*9f50aa45SLeandro Lupori beq .Lfound_on_byte_2 144*9f50aa45SLeandro Lupori andis. %r7,%r0,0xff00 145*9f50aa45SLeandro Lupori beq .Lfound_on_byte_3 146*9f50aa45SLeandro Lupori rldicr. %r7,%r0,24,7 147*9f50aa45SLeandro Lupori beq .Lfound_on_byte_4 148*9f50aa45SLeandro Lupori rldicr. %r7,%r0,16,7 149*9f50aa45SLeandro Lupori beq .Lfound_on_byte_5 150*9f50aa45SLeandro Lupori rldicr. %r7,%r0,8,7 151*9f50aa45SLeandro Lupori beq .Lfound_on_byte_6 152*9f50aa45SLeandro Lupori 153*9f50aa45SLeandro Lupori/* Copy the last string bytes according to the string end position. */ 154*9f50aa45SLeandro Lupori.Lfound_on_byte_7: 155*9f50aa45SLeandro Lupori std %r0,0(%r8) 156*9f50aa45SLeandro Lupori b .Lexit 157*9f50aa45SLeandro Lupori 158*9f50aa45SLeandro Lupori.Lfound_on_byte_6: 159*9f50aa45SLeandro Lupori stw %r0,0(%r8) 160*9f50aa45SLeandro Lupori srdi %r6,%r0,32 161*9f50aa45SLeandro Lupori sth %r6,4(%r8) 162*9f50aa45SLeandro Lupori srdi %r6,%r0,48 163*9f50aa45SLeandro Lupori stb %r6,6(%r8) 164*9f50aa45SLeandro Lupori b .Lexit 165*9f50aa45SLeandro Lupori 166*9f50aa45SLeandro Lupori.Lfound_on_byte_5: 167*9f50aa45SLeandro Lupori stw %r0,0(%r8) 168*9f50aa45SLeandro Lupori srdi %r6,%r0,32 169*9f50aa45SLeandro Lupori sth %r6,4(%r8) 170*9f50aa45SLeandro Lupori b .Lexit 171*9f50aa45SLeandro Lupori 172*9f50aa45SLeandro Lupori.Lfound_on_byte_4: 173*9f50aa45SLeandro Lupori stw %r0,0(%r8) 174*9f50aa45SLeandro Lupori srdi %r6,%r0,32 175*9f50aa45SLeandro Lupori stb %r6,4(%r8) 176*9f50aa45SLeandro Lupori b .Lexit 177*9f50aa45SLeandro Lupori 178*9f50aa45SLeandro Lupori.Lfound_on_byte_3: 179*9f50aa45SLeandro Lupori stw %r0,0(%r8) 180*9f50aa45SLeandro Lupori b .Lexit 181*9f50aa45SLeandro Lupori 182*9f50aa45SLeandro Lupori.Lfound_on_byte_2: 183*9f50aa45SLeandro Lupori sth %r0,0(%r8) 184*9f50aa45SLeandro Lupori srdi %r6,%r0,16 185*9f50aa45SLeandro Lupori stb %r6,2(%r8) 186*9f50aa45SLeandro Lupori b .Lexit 187*9f50aa45SLeandro Lupori 188*9f50aa45SLeandro Lupori.Lfound_on_byte_1: 189*9f50aa45SLeandro Lupori sth %r0,0(%r8) 190*9f50aa45SLeandro Lupori b .Lexit 191*9f50aa45SLeandro Lupori 192*9f50aa45SLeandro Lupori.Lfound_on_byte_0: 193*9f50aa45SLeandro Lupori stb %r0,0(%r8) 194*9f50aa45SLeandro Lupori#else 195*9f50aa45SLeandro Lupori#error "Unable to determine Endianness" 196*9f50aa45SLeandro Lupori#endif 197075fb85fSLeandro Lupori.Lexit: 198075fb85fSLeandro Lupori blr 199075fb85fSLeandro Lupori 200075fb85fSLeandro LuporiEND(__strcpy_arch_2_05) 201075fb85fSLeandro Lupori 202075fb85fSLeandro Lupori .section .note.GNU-stack,"",%progbits 203