| ! |
| ! |
| ! |
| ! Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. |
| ! DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| ! |
| ! This code is free software; you can redistribute it and/or modify it |
| ! under the terms of the GNU General Public License version 2 only, as |
| ! published by the Free Software Foundation. Oracle designates this |
| ! particular file as subject to the "Classpath" exception as provided |
| ! by Oracle in the LICENSE file that accompanied this code. |
| ! |
| ! This code is distributed in the hope that it will be useful, but WITHOUT |
| ! ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| ! FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| ! version 2 for more details (a copy is included in the LICENSE file that |
| ! accompanied this code). |
| ! |
| ! You should have received a copy of the GNU General Public License version |
| ! 2 along with this work; if not, write to the Free Software Foundation, |
| ! Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| ! |
| ! Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| ! or visit www.oracle.com if you need additional information or have any |
| ! questions. |
| ! |
| |
| |
| ! FUNCTION |
| ! mlib_v_ImageCopy_blk - Copy an image into another |
| ! (with Block Load/Store) |
| ! |
| ! SYNOPSIS |
| ! void mlib_v_ImageCopy_blk(void *src, |
| ! void *dst, |
| ! int size); |
| ! |
| ! ARGUMENT |
| ! src source image data |
| ! dst destination image data |
| ! size image size in bytes |
| ! |
| ! NOTES |
| ! src and dst must point to 64-byte aligned addresses |
| ! size must be multiple of 64 |
| ! |
| ! DESCRIPTION |
| ! dst = src |
| ! |
| |
| #include "vis_asi.h" |
| |
| ! Minimum size of stack frame according to SPARC ABI |
| #define MINFRAME 96 |
| |
| ! ENTRY provides the standard procedure entry code |
| #define ENTRY(x) \ |
| .align 4; \ |
| .global x; \ |
| x: |
| |
| ! SET_SIZE trails a function and sets the size for the ELF symbol table |
| #define SET_SIZE(x) \ |
| .size x, (.-x) |
| |
| ! SPARC have four integer register groups. i-registers %i0 to %i7 |
| ! hold input data. o-registers %o0 to %o7 hold output data. l-registers |
| ! %l0 to %l7 hold local data. g-registers %g0 to %g7 hold global data. |
| ! Note that %g0 is alway zero, write to it has no program-visible effect. |
| |
| ! When calling an assembly function, the first 6 arguments are stored |
| ! in i-registers from %i0 to %i5. The rest arguments are stored in stack. |
| ! Note that %i6 is reserved for stack pointer and %i7 for return address. |
| |
| ! Only the first 32 f-registers can be used as 32-bit registers. |
| ! The last 32 f-registers can only be used as 16 64-bit registers. |
| |
| #define src %i0 |
| #define dst %i1 |
| #define sz %i2 |
| |
| !frame pointer %i6 |
| !return addr %i7 |
| |
| !stack pointer %o6 |
| !call link %o7 |
| |
| #define sa %l0 |
| #define da %l1 |
| #define se %l2 |
| #define ns %l3 |
| |
| #define O0 %f16 |
| #define O1 %f18 |
| #define O2 %f20 |
| #define O3 %f22 |
| #define O4 %f24 |
| #define O5 %f26 |
| #define O6 %f28 |
| #define O7 %f30 |
| |
| #define A0 %f32 |
| #define A1 %f34 |
| #define A2 %f36 |
| #define A3 %f38 |
| #define A4 %f40 |
| #define A5 %f42 |
| #define A6 %f44 |
| #define A7 %f46 |
| |
| #define B0 %f48 |
| #define B1 %f50 |
| #define B2 %f52 |
| #define B3 %f54 |
| #define B4 %f56 |
| #define B5 %f58 |
| #define B6 %f60 |
| #define B7 %f62 |
| |
| #define USE_BLD |
| #define USE_BST |
| |
| #define MEMBAR_BEFORE_BLD membar #StoreLoad |
| #define MEMBAR_AFTER_BLD membar #StoreLoad |
| |
| #ifdef USE_BLD |
| #define BLD_A0 \ |
| ldda [sa]ASI_BLK_P,A0; \ |
| cmp sa,se; \ |
| blu,pt %icc,1f; \ |
| inc 64,sa; \ |
| dec 64,sa; \ |
| 1: |
| #else |
| #define BLD_A0 \ |
| ldd [sa + 0],A0; \ |
| ldd [sa + 8],A1; \ |
| ldd [sa + 16],A2; \ |
| ldd [sa + 24],A3; \ |
| ldd [sa + 32],A4; \ |
| ldd [sa + 40],A5; \ |
| ldd [sa + 48],A6; \ |
| ldd [sa + 56],A7; \ |
| cmp sa,se; \ |
| blu,pt %icc,1f; \ |
| inc 64,sa; \ |
| dec 64,sa; \ |
| 1: |
| #endif |
| |
| #ifdef USE_BLD |
| #define BLD_B0 \ |
| ldda [sa]ASI_BLK_P,B0; \ |
| cmp sa,se; \ |
| blu,pt %icc,1f; \ |
| inc 64,sa; \ |
| dec 64,sa; \ |
| 1: |
| #else |
| #define BLD_B0 \ |
| ldd [sa + 0],B0; \ |
| ldd [sa + 8],B1; \ |
| ldd [sa + 16],B2; \ |
| ldd [sa + 24],B3; \ |
| ldd [sa + 32],B4; \ |
| ldd [sa + 40],B5; \ |
| ldd [sa + 48],B6; \ |
| ldd [sa + 56],B7; \ |
| cmp sa,se; \ |
| blu,pt %icc,1f; \ |
| inc 64,sa; \ |
| dec 64,sa; \ |
| 1: |
| #endif |
| |
| #ifdef USE_BST |
| #define BST \ |
| stda O0,[da]ASI_BLK_P; \ |
| inc 64,da; \ |
| deccc ns; \ |
| ble,pn %icc,mlib_v_ImageCopy_end; \ |
| nop |
| #else |
| #define BST \ |
| std O0,[da + 0]; \ |
| std O1,[da + 8]; \ |
| std O2,[da + 16]; \ |
| std O3,[da + 24]; \ |
| std O4,[da + 32]; \ |
| std O5,[da + 40]; \ |
| std O6,[da + 48]; \ |
| std O7,[da + 56]; \ |
| inc 64,da; \ |
| deccc ns; \ |
| ble,pn %icc,mlib_v_ImageCopy_end; \ |
| nop |
| #endif |
| |
| #define COPY_A0 \ |
| fmovd A0, O0; \ |
| fmovd A1, O1; \ |
| fmovd A2, O2; \ |
| fmovd A3, O3; \ |
| fmovd A4, O4; \ |
| fmovd A5, O5; \ |
| fmovd A6, O6; \ |
| fmovd A7, O7; |
| |
| #define COPY_B0 \ |
| fmovd B0, O0; \ |
| fmovd B1, O1; \ |
| fmovd B2, O2; \ |
| fmovd B3, O3; \ |
| fmovd B4, O4; \ |
| fmovd B5, O5; \ |
| fmovd B6, O6; \ |
| fmovd B7, O7; |
| |
| .section ".text",#alloc,#execinstr |
| |
| ENTRY(mlib_v_ImageCopy_blk) ! function name |
| |
| save %sp,-MINFRAME,%sp ! reserve space for stack |
| ! and adjust register window |
| ! do some error checking |
| tst sz ! size > 0 |
| ble,pn %icc,mlib_v_ImageCopy_ret |
| |
| ! calculate loop count |
| sra sz,6,ns ! 64 bytes per loop |
| |
| add src,sz,se ! end address of source |
| mov src,sa |
| mov dst,da |
| ! issue memory barrier instruction |
| MEMBAR_BEFORE_BLD ! to ensure all previous memory load |
| ! and store has completed |
| |
| BLD_A0 |
| BLD_B0 ! issue the 2nd block load instruction |
| ! to synchronize with returning data |
| mlib_v_ImageCopy_bgn: |
| |
| COPY_A0 ! process data returned by BLD_A0 |
| BLD_A0 ! block load and sync data from BLD_B0 |
| BST ! block store data from BLD_A0 |
| |
| COPY_B0 ! process data returned by BLD_B0 |
| BLD_B0 ! block load and sync data from BLD_A0 |
| BST ! block store data from BLD_B0 |
| |
| bg,pt %icc,mlib_v_ImageCopy_bgn |
| |
| mlib_v_ImageCopy_end: |
| ! issue memory barrier instruction |
| MEMBAR_AFTER_BLD ! to ensure all previous memory load |
| ! and store has completed. |
| mlib_v_ImageCopy_ret: |
| ret ! return |
| restore ! restore register window |
| |
| SET_SIZE(mlib_v_ImageCopy_blk) |