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 56515Sraf * Common Development and Distribution License (the "License"). 66515Sraf * 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 */ 216515Sraf 220Sstevel@tonic-gate/* 23*10931SSudheer.Abdul-Salam@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 277298SMark.J.Nelson@Sun.COM .file "memcpy.s" 280Sstevel@tonic-gate 290Sstevel@tonic-gate#include <sys/asm_linkage.h> 300Sstevel@tonic-gate 310Sstevel@tonic-gate ANSI_PRAGMA_WEAK(memmove,function) 320Sstevel@tonic-gate ANSI_PRAGMA_WEAK(memcpy,function) 330Sstevel@tonic-gate 340Sstevel@tonic-gate#include "SYS.h" 350Sstevel@tonic-gate 360Sstevel@tonic-gate ENTRY(memcpy) 370Sstevel@tonic-gate movl %edi,%edx / save register variables 380Sstevel@tonic-gate pushl %esi 390Sstevel@tonic-gate movl 8(%esp),%edi / %edi = dest address 400Sstevel@tonic-gate movl 12(%esp),%esi / %esi = source address 410Sstevel@tonic-gate movl 16(%esp),%ecx / %ecx = length of string 420Sstevel@tonic-gate movl %edi,%eax / return value from the call 430Sstevel@tonic-gate 440Sstevel@tonic-gate shrl $2,%ecx / %ecx = number of words to move 450Sstevel@tonic-gate rep ; smovl / move the words 460Sstevel@tonic-gate 470Sstevel@tonic-gate movl 16(%esp),%ecx / %ecx = number of bytes to move 480Sstevel@tonic-gate andl $0x3,%ecx / %ecx = number of bytes left to move 490Sstevel@tonic-gate rep ; smovb / move the bytes 500Sstevel@tonic-gate 510Sstevel@tonic-gate popl %esi / restore register variables 520Sstevel@tonic-gate movl %edx,%edi 530Sstevel@tonic-gate ret 540Sstevel@tonic-gate SET_SIZE(memcpy) 550Sstevel@tonic-gate 560Sstevel@tonic-gate 570Sstevel@tonic-gate ENTRY(memmove) 580Sstevel@tonic-gate pushl %edi / save off %edi, %esi and move destination 590Sstevel@tonic-gate movl 4+12(%esp),%ecx / get number of bytes to move 600Sstevel@tonic-gate pushl %esi 610Sstevel@tonic-gate testl %ecx,%ecx / if (n == 0) 620Sstevel@tonic-gate je .CleanupReturn / return(s); 630Sstevel@tonic-gate movl 8+ 4(%esp),%edi / destination buffer address 640Sstevel@tonic-gate movl 8+ 8(%esp),%esi / source buffer address 650Sstevel@tonic-gate.Common: 660Sstevel@tonic-gate movl $3,%eax / heavily used constant 670Sstevel@tonic-gate cmpl %esi,%edi / if (source addr > dest addr) 680Sstevel@tonic-gate leal -1(%esi,%ecx),%edx 69*10931SSudheer.Abdul-Salam@Sun.COM jbe .CopyRight / 700Sstevel@tonic-gate cmpl %edx,%edi 71*10931SSudheer.Abdul-Salam@Sun.COM jbe .CopyLeft 720Sstevel@tonic-gate.CopyRight: 730Sstevel@tonic-gate cmpl $8,%ecx / if (size < 8 bytes) 740Sstevel@tonic-gate jbe .OneByteCopy / goto fast short copy loop 750Sstevel@tonic-gate.FourByteCopy: 760Sstevel@tonic-gate movl %ecx,%edx / save count 770Sstevel@tonic-gate movl %esi,%ecx / get source buffer 4 byte aligned 780Sstevel@tonic-gate andl %eax,%ecx 790Sstevel@tonic-gate jz .SkipAlignRight 800Sstevel@tonic-gate subl %ecx,%edx 810Sstevel@tonic-gate rep; smovb / do the byte part of copy 820Sstevel@tonic-gate.SkipAlignRight: 830Sstevel@tonic-gate movl %edx,%ecx 840Sstevel@tonic-gate shrl $2,%ecx 850Sstevel@tonic-gate rep; smovl / do the long word part 860Sstevel@tonic-gate movl %edx,%ecx / compute bytes left to move 870Sstevel@tonic-gate andl %eax,%ecx / complete copy of remaining bytes 880Sstevel@tonic-gate jz .CleanupReturn 890Sstevel@tonic-gate.OneByteCopy: 900Sstevel@tonic-gate rep; smovb / do the byte part of copy 910Sstevel@tonic-gate.CleanupReturn: 920Sstevel@tonic-gate popl %esi / } 930Sstevel@tonic-gate popl %edi / restore registers 940Sstevel@tonic-gate movl 4(%esp),%eax / set up return value 950Sstevel@tonic-gate.Return: 960Sstevel@tonic-gate ret / return(dba); 970Sstevel@tonic-gate 980Sstevel@tonic-gate.CopyLeft: 990Sstevel@tonic-gate std / reverse direction bit (RtoL) 1000Sstevel@tonic-gate cmpl $12,%ecx / if (size < 12) 1010Sstevel@tonic-gate ja .BigCopyLeft / { 1020Sstevel@tonic-gate movl %edx,%esi / src = src + size - 1 1030Sstevel@tonic-gate leal -1(%ecx,%edi),%edi / dst = dst + size - 1 1040Sstevel@tonic-gate rep; smovb / do the byte copy 1050Sstevel@tonic-gate cld / reset direction flag to LtoR 1060Sstevel@tonic-gate popl %esi / } 1070Sstevel@tonic-gate popl %edi / restore registers 1080Sstevel@tonic-gate movl 4(%esp),%eax / set up return value 1090Sstevel@tonic-gate ret / return(dba); 1100Sstevel@tonic-gate.BigCopyLeft: / } else { 1110Sstevel@tonic-gate xchgl %edx,%ecx 1120Sstevel@tonic-gate movl %ecx,%esi / align source w/byte copy 1130Sstevel@tonic-gate leal -1(%edx,%edi),%edi 1140Sstevel@tonic-gate andl %eax,%ecx 1150Sstevel@tonic-gate jz .SkipAlignLeft 1160Sstevel@tonic-gate addl $1, %ecx / we need to insure that future 1170Sstevel@tonic-gate subl %ecx,%edx / copy is done on aligned boundary 1180Sstevel@tonic-gate rep; smovb 1190Sstevel@tonic-gate.SkipAlignLeft: 1200Sstevel@tonic-gate movl %edx,%ecx 1210Sstevel@tonic-gate subl %eax,%esi 1220Sstevel@tonic-gate shrl $2,%ecx / do 4 byte copy RtoL 1230Sstevel@tonic-gate subl %eax,%edi 1240Sstevel@tonic-gate rep; smovl 1250Sstevel@tonic-gate andl %eax,%edx / do 1 byte copy whats left 1260Sstevel@tonic-gate jz .CleanupReturnLeft 1270Sstevel@tonic-gate movl %edx,%ecx 1280Sstevel@tonic-gate addl %eax,%esi / rep; smovl instruction will decrement 1290Sstevel@tonic-gate addl %eax,%edi / %edi, %esi by four after each copy 1300Sstevel@tonic-gate / adding 3 will restore pointers to byte 1310Sstevel@tonic-gate / before last double word copied 1320Sstevel@tonic-gate / which is where they are expected to 1330Sstevel@tonic-gate / be for the single byte copy code 1340Sstevel@tonic-gate rep; smovb 1350Sstevel@tonic-gate.CleanupReturnLeft: 1360Sstevel@tonic-gate cld / reset direction flag to LtoR 1370Sstevel@tonic-gate popl %esi 1380Sstevel@tonic-gate popl %edi / restore registers 1390Sstevel@tonic-gate movl 4(%esp),%eax / set up return value 1400Sstevel@tonic-gate ret / return(dba); 1410Sstevel@tonic-gate SET_SIZE(memmove) 142