10Sstevel@tonic-gate/* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 56812Sraf * Common Development and Distribution License (the "License"). 66812Sraf * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 216812Sraf 220Sstevel@tonic-gate/* 236812Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 246812Sraf * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 27*7298SMark.J.Nelson@Sun.COM .file "__align_cpy_2.s" 280Sstevel@tonic-gate 290Sstevel@tonic-gate/* 300Sstevel@tonic-gate * __align_cpy_2(s1, s2, len) 310Sstevel@tonic-gate * 320Sstevel@tonic-gate * Copy s2 to s1, always copy n bytes. 330Sstevel@tonic-gate * Note: this does not work for overlapped copies, bcopy() does 340Sstevel@tonic-gate * This routine is copied from memcpy.s, with all values doubled. 350Sstevel@tonic-gate * No attempt has been made to improve the comments or performance. 360Sstevel@tonic-gate * 370Sstevel@tonic-gate */ 380Sstevel@tonic-gate 390Sstevel@tonic-gate#include <sys/asm_linkage.h> 400Sstevel@tonic-gate 410Sstevel@tonic-gate ENTRY(__align_cpy_2) 420Sstevel@tonic-gate cmp %o0, %o1 430Sstevel@tonic-gate be,pn %xcc, .done ! Identical addresses--done. 440Sstevel@tonic-gate mov %o0, %g5 ! save des address for return val 450Sstevel@tonic-gate cmp %o2, 18 ! for small counts copy bytes 460Sstevel@tonic-gate ble,pn %xcc, .dbytecp 470Sstevel@tonic-gate andcc %o1, 6, %o5 ! is src 8-byte aligned 480Sstevel@tonic-gate bz,pn %xcc, .aldst 490Sstevel@tonic-gate cmp %o5, 4 ! is src 4-byte aligned 500Sstevel@tonic-gate be,pt %xcc, .s2algn 510Sstevel@tonic-gate cmp %o5, 6 ! src is 2-byte aligned 520Sstevel@tonic-gate.s1algn:lduh [%o1], %o3 ! move 2 or 6 bytes to align it 530Sstevel@tonic-gate inc 2, %o1 540Sstevel@tonic-gate sth %o3, [%g5] ! move 2 bytes to align src 550Sstevel@tonic-gate inc 2, %g5 560Sstevel@tonic-gate bne,pt %xcc, .s2algn 570Sstevel@tonic-gate dec 2, %o2 580Sstevel@tonic-gate b .ald ! now go align dest 590Sstevel@tonic-gate andcc %g5, 6, %o5 600Sstevel@tonic-gate 610Sstevel@tonic-gate.s2algn:lduw [%o1], %o3 ! know src is 4-byte aligned 620Sstevel@tonic-gate inc 4, %o1 630Sstevel@tonic-gate srlx %o3, 16, %o4 640Sstevel@tonic-gate sth %o4, [%g5] ! have to do 2-bytes, 650Sstevel@tonic-gate sth %o3, [%g5 + 2] ! don't know dst alignment 660Sstevel@tonic-gate inc 4, %g5 670Sstevel@tonic-gate dec 4, %o2 680Sstevel@tonic-gate 690Sstevel@tonic-gate.aldst: andcc %g5, 6, %o5 ! align the destination address 700Sstevel@tonic-gate.ald: bz,pn %xcc, .w4cp 710Sstevel@tonic-gate cmp %o5, 4 720Sstevel@tonic-gate bz,pn %xcc, .w2cp 730Sstevel@tonic-gate cmp %o5, 6 740Sstevel@tonic-gate.w3cp: ldx [%o1], %o4 750Sstevel@tonic-gate inc 8, %o1 760Sstevel@tonic-gate srlx %o4, 48, %o5 770Sstevel@tonic-gate sth %o5, [%g5] 780Sstevel@tonic-gate bne,pt %xcc, .w1cp 790Sstevel@tonic-gate inc 2, %g5 800Sstevel@tonic-gate dec 2, %o2 810Sstevel@tonic-gate andn %o2, 6, %o3 ! o3 is aligned word count 820Sstevel@tonic-gate sub %o1, %g5, %o1 ! g5 gets the difference 830Sstevel@tonic-gate 840Sstevel@tonic-gate1: sllx %o4, 16, %g1 ! save residual bytes 850Sstevel@tonic-gate ldx [%o1+%g5], %o4 860Sstevel@tonic-gate deccc 8, %o3 870Sstevel@tonic-gate srlx %o4, 48, %o5 ! merge with residual 880Sstevel@tonic-gate or %o5, %g1, %g1 890Sstevel@tonic-gate stx %g1, [%g5] 900Sstevel@tonic-gate bnz,pt %xcc, 1b 910Sstevel@tonic-gate inc 8, %g5 920Sstevel@tonic-gate sub %o1, 6, %o1 ! used two bytes of last word read 930Sstevel@tonic-gate b 7f 940Sstevel@tonic-gate and %o2, 6, %o2 950Sstevel@tonic-gate 960Sstevel@tonic-gate.w1cp: srlx %o4, 16, %o5 970Sstevel@tonic-gate st %o5, [%g5] 980Sstevel@tonic-gate inc 4, %g5 990Sstevel@tonic-gate dec 6, %o2 1000Sstevel@tonic-gate andn %o2, 6, %o3 1010Sstevel@tonic-gate sub %o1, %g5, %o1 ! g5 gets the difference 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate2: sllx %o4, 48, %g1 ! save residual bytes 1040Sstevel@tonic-gate ldx [%o1+%g5], %o4 1050Sstevel@tonic-gate deccc 8, %o3 1060Sstevel@tonic-gate srlx %o4, 16, %o5 ! merge with residual 1070Sstevel@tonic-gate or %o5, %g1, %g1 1080Sstevel@tonic-gate stx %g1, [%g5] 1090Sstevel@tonic-gate bnz,pt %xcc, 2b 1100Sstevel@tonic-gate inc 8, %g5 1110Sstevel@tonic-gate sub %o1, 2, %o1 ! used six bytes of last word read 1120Sstevel@tonic-gate b 7f 1130Sstevel@tonic-gate and %o2, 6, %o2 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate.w2cp: ldx [%o1], %o4 1160Sstevel@tonic-gate inc 8, %o1 1170Sstevel@tonic-gate srlx %o4, 32, %o5 1180Sstevel@tonic-gate st %o5, [%g5] 1190Sstevel@tonic-gate inc 4, %g5 1200Sstevel@tonic-gate dec 4, %o2 1210Sstevel@tonic-gate andn %o2, 6, %o3 ! o3 is aligned word count 1220Sstevel@tonic-gate sub %o1, %g5, %o1 ! g5 gets the difference 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate3: sllx %o4, 32, %g1 ! save residual bytes 1250Sstevel@tonic-gate ldx [%o1+%g5], %o4 1260Sstevel@tonic-gate deccc 8, %o3 1270Sstevel@tonic-gate srlx %o4, 32, %o5 ! merge with residual 1280Sstevel@tonic-gate or %o5, %g1, %g1 1290Sstevel@tonic-gate stx %g1, [%g5] 1300Sstevel@tonic-gate bnz,pt %xcc, 3b 1310Sstevel@tonic-gate inc 8, %g5 1320Sstevel@tonic-gate sub %o1, 4, %o1 ! used four bytes of last word read 1330Sstevel@tonic-gate b 7f 1340Sstevel@tonic-gate and %o2, 6, %o2 1350Sstevel@tonic-gate 1360Sstevel@tonic-gate.w4cp: andn %o2, 6, %o3 ! o3 is aligned word count 1370Sstevel@tonic-gate sub %o1, %g5, %o1 ! g5 gets the difference 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate1: ldx [%o1+%g5], %o4 ! read from address 1400Sstevel@tonic-gate deccc 8, %o3 ! decrement count 1410Sstevel@tonic-gate stx %o4, [%g5] ! write at destination address 1420Sstevel@tonic-gate bg,pt %xcc, 1b 1430Sstevel@tonic-gate inc 8, %g5 ! increment to address 1440Sstevel@tonic-gate b 7f 1450Sstevel@tonic-gate and %o2, 6, %o2 ! number of leftover bytes, if any 1460Sstevel@tonic-gate 1470Sstevel@tonic-gate ! 1480Sstevel@tonic-gate ! differenced byte copy, works with any alignment 1490Sstevel@tonic-gate ! 1500Sstevel@tonic-gate.dbytecp: 1510Sstevel@tonic-gate b 7f 1520Sstevel@tonic-gate sub %o1, %g5, %o1 ! g5 gets the difference 1530Sstevel@tonic-gate 1540Sstevel@tonic-gate4: sth %o4, [%g5] ! write to address 1550Sstevel@tonic-gate inc 2, %g5 ! inc to address 1560Sstevel@tonic-gate7: deccc 2, %o2 ! decrement count 1570Sstevel@tonic-gate bge,a,pt %xcc,4b ! loop till done 1580Sstevel@tonic-gate lduh [%o1+%g5], %o4 ! read from address 1590Sstevel@tonic-gate.done: 1600Sstevel@tonic-gate retl 1610Sstevel@tonic-gate nop 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate SET_SIZE(__align_cpy_2) 164