1*3e4fc0a4Schristos/* $NetBSD: memcpy.S,v 1.2 2013/03/17 02:13:10 christos Exp $ */ 2ca8f29b6Schristos 3ca8f29b6Schristos/* 4ca8f29b6Schristos * Copyright (c) 1996-2002 Eduardo Horvath 5ca8f29b6Schristos * All rights reserved. 6ca8f29b6Schristos * 7ca8f29b6Schristos * Redistribution and use in source and binary forms, with or without 8ca8f29b6Schristos * modification, are permitted provided that the following conditions 9ca8f29b6Schristos * are met: 10ca8f29b6Schristos * 1. Redistributions of source code must retain the above copyright 11ca8f29b6Schristos * notice, this list of conditions and the following disclaimer. 12ca8f29b6Schristos * 13ca8f29b6Schristos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 14ca8f29b6Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15ca8f29b6Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16ca8f29b6Schristos * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 17ca8f29b6Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18ca8f29b6Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19ca8f29b6Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20ca8f29b6Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21ca8f29b6Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22ca8f29b6Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23ca8f29b6Schristos * SUCH DAMAGE. 24ca8f29b6Schristos * 25ca8f29b6Schristos */ 26ca8f29b6Schristos#include "strmacros.h" 27*3e4fc0a4Schristos#if defined(LIBC_SCCS) && !defined(lint) 28*3e4fc0a4SchristosRCSID("$NetBSD: memcpy.S,v 1.2 2013/03/17 02:13:10 christos Exp $") 29*3e4fc0a4Schristos#endif /* LIBC_SCCS and not lint */ 30ca8f29b6Schristos 31ca8f29b6Schristos/* 32*3e4fc0a4Schristos * memcpy 33*3e4fc0a4Schristos * Assumes regions do not overlap; 34ca8f29b6Schristos * 35ca8f29b6Schristos * Must not use %g7 (see copyin/copyout above). 36ca8f29b6Schristos */ 37ca8f29b6SchristosENTRY(memcpy) /* dest, src, size */ 38ca8f29b6Schristos /* 39ca8f29b6Schristos * Swap args for bcopy. Gcc generates calls to memcpy for 40ca8f29b6Schristos * structure assignments. 41ca8f29b6Schristos */ 42ca8f29b6Schristos mov %o0, %o3 43ca8f29b6Schristos mov %o1, %o0 44ca8f29b6Schristos mov %o3, %o1 45ca8f29b6Schristos#if !defined(_KERNEL) || defined(_RUMPKERNEL) 46ca8f29b6SchristosENTRY(bcopy) /* src, dest, size */ 47ca8f29b6Schristos#endif 48ca8f29b6Schristos#ifdef DEBUG 49ca8f29b6Schristos#if defined(_KERNEL) && !defined(_RUMPKERNEL) 50ca8f29b6Schristos set pmapdebug, %o4 51ca8f29b6Schristos ld [%o4], %o4 52ca8f29b6Schristos btst 0x80, %o4 ! PDB_COPY 53ca8f29b6Schristos bz,pt %icc, 3f 54ca8f29b6Schristos nop 55ca8f29b6Schristos#endif 56ca8f29b6Schristos save %sp, -CC64FSZ, %sp 57ca8f29b6Schristos mov %i0, %o1 58ca8f29b6Schristos set 2f, %o0 59ca8f29b6Schristos mov %i1, %o2 60ca8f29b6Schristos call printf 61ca8f29b6Schristos mov %i2, %o3 62ca8f29b6Schristos! ta 1; nop 63ca8f29b6Schristos restore 64ca8f29b6Schristos .data 65ca8f29b6Schristos2: .asciz "memcpy(%p<-%p,%x)\n" 66ca8f29b6Schristos _ALIGN 67ca8f29b6Schristos .text 68ca8f29b6Schristos3: 69ca8f29b6Schristos#endif 70ca8f29b6Schristos 71ca8f29b6Schristos cmp %o2, BCOPY_SMALL 72ca8f29b6Schristos 73ca8f29b6SchristosLmemcpy_start: 74ca8f29b6Schristos bge,pt CCCR, 2f ! if >= this many, go be fancy. 75ca8f29b6Schristos cmp %o2, 256 76ca8f29b6Schristos 77ca8f29b6Schristos mov %o1, %o5 ! Save memcpy return value 78ca8f29b6Schristos /* 79ca8f29b6Schristos * Not much to copy, just do it a byte at a time. 80ca8f29b6Schristos */ 81ca8f29b6Schristos deccc %o2 ! while (--len >= 0) 82ca8f29b6Schristos bl 1f 83ca8f29b6Schristos .empty 84ca8f29b6Schristos0: 85ca8f29b6Schristos inc %o0 86ca8f29b6Schristos ldsb [%o0 - 1], %o4 ! (++dst)[-1] = *src++; 87ca8f29b6Schristos stb %o4, [%o1] 88ca8f29b6Schristos deccc %o2 89ca8f29b6Schristos bge 0b 90ca8f29b6Schristos inc %o1 91ca8f29b6Schristos1: 92ca8f29b6Schristos retl 93ca8f29b6Schristos mov %o5, %o0 94ca8f29b6Schristos NOTREACHED 95ca8f29b6Schristos 96ca8f29b6Schristos /* 97ca8f29b6Schristos * Plenty of data to copy, so try to do it optimally. 98ca8f29b6Schristos */ 99ca8f29b6Schristos2: 100ca8f29b6Schristos#ifdef USE_BLOCK_STORE_LOAD 101ca8f29b6Schristos ! If it is big enough, use VIS instructions 102ca8f29b6Schristos bge Lmemcpy_block 103ca8f29b6Schristos nop 104ca8f29b6Schristos#endif /* USE_BLOCK_STORE_LOAD */ 105ca8f29b6SchristosLmemcpy_fancy: 106ca8f29b6Schristos 107ca8f29b6Schristos !! 108ca8f29b6Schristos !! First align the output to a 8-byte entity 109ca8f29b6Schristos !! 110ca8f29b6Schristos 111ca8f29b6Schristos save %sp, -CC64FSZ, %sp 112ca8f29b6Schristos 113ca8f29b6Schristos mov %i0, %l0 114ca8f29b6Schristos mov %i1, %l1 115ca8f29b6Schristos 116ca8f29b6Schristos mov %i2, %l2 117ca8f29b6Schristos btst 1, %l1 118ca8f29b6Schristos 119ca8f29b6Schristos bz,pt %icc, 4f 120ca8f29b6Schristos btst 2, %l1 121ca8f29b6Schristos ldub [%l0], %l4 ! Load 1st byte 122ca8f29b6Schristos 123ca8f29b6Schristos deccc 1, %l2 124ca8f29b6Schristos ble,pn CCCR, Lmemcpy_finish ! XXXX 125ca8f29b6Schristos inc 1, %l0 126ca8f29b6Schristos 127ca8f29b6Schristos stb %l4, [%l1] ! Store 1st byte 128ca8f29b6Schristos inc 1, %l1 ! Update address 129ca8f29b6Schristos btst 2, %l1 130ca8f29b6Schristos4: 131ca8f29b6Schristos bz,pt %icc, 4f 132ca8f29b6Schristos 133ca8f29b6Schristos btst 1, %l0 134ca8f29b6Schristos bz,a 1f 135ca8f29b6Schristos lduh [%l0], %l4 ! Load short 136ca8f29b6Schristos 137ca8f29b6Schristos ldub [%l0], %l4 ! Load bytes 138ca8f29b6Schristos 139ca8f29b6Schristos ldub [%l0+1], %l3 140ca8f29b6Schristos sllx %l4, 8, %l4 141ca8f29b6Schristos or %l3, %l4, %l4 142ca8f29b6Schristos 143ca8f29b6Schristos1: 144ca8f29b6Schristos deccc 2, %l2 145ca8f29b6Schristos ble,pn CCCR, Lmemcpy_finish ! XXXX 146ca8f29b6Schristos inc 2, %l0 147ca8f29b6Schristos sth %l4, [%l1] ! Store 1st short 148ca8f29b6Schristos 149ca8f29b6Schristos inc 2, %l1 150ca8f29b6Schristos4: 151ca8f29b6Schristos btst 4, %l1 152ca8f29b6Schristos bz,pt CCCR, 4f 153ca8f29b6Schristos 154ca8f29b6Schristos btst 3, %l0 155ca8f29b6Schristos bz,a,pt CCCR, 1f 156ca8f29b6Schristos lduw [%l0], %l4 ! Load word -1 157ca8f29b6Schristos 158ca8f29b6Schristos btst 1, %l0 159ca8f29b6Schristos bz,a,pt %icc, 2f 160ca8f29b6Schristos lduh [%l0], %l4 161ca8f29b6Schristos 162ca8f29b6Schristos ldub [%l0], %l4 163ca8f29b6Schristos 164ca8f29b6Schristos lduh [%l0+1], %l3 165ca8f29b6Schristos sllx %l4, 16, %l4 166ca8f29b6Schristos or %l4, %l3, %l4 167ca8f29b6Schristos 168ca8f29b6Schristos ldub [%l0+3], %l3 169ca8f29b6Schristos sllx %l4, 8, %l4 170ca8f29b6Schristos ba,pt %icc, 1f 171ca8f29b6Schristos or %l4, %l3, %l4 172ca8f29b6Schristos 173ca8f29b6Schristos2: 174ca8f29b6Schristos lduh [%l0+2], %l3 175ca8f29b6Schristos sllx %l4, 16, %l4 176ca8f29b6Schristos or %l4, %l3, %l4 177ca8f29b6Schristos 178ca8f29b6Schristos1: 179ca8f29b6Schristos deccc 4, %l2 180ca8f29b6Schristos ble,pn CCCR, Lmemcpy_finish ! XXXX 181ca8f29b6Schristos inc 4, %l0 182ca8f29b6Schristos 183ca8f29b6Schristos st %l4, [%l1] ! Store word 184ca8f29b6Schristos inc 4, %l1 185ca8f29b6Schristos4: 186ca8f29b6Schristos !! 187ca8f29b6Schristos !! We are now 32-bit aligned in the dest. 188ca8f29b6Schristos !! 189ca8f29b6SchristosLmemcpy_common: 190ca8f29b6Schristos 191ca8f29b6Schristos and %l0, 7, %l4 ! Shift amount 192ca8f29b6Schristos andn %l0, 7, %l0 ! Source addr 193ca8f29b6Schristos 194ca8f29b6Schristos brz,pt %l4, Lmemcpy_noshift8 ! No shift version... 195ca8f29b6Schristos 196ca8f29b6Schristos sllx %l4, 3, %l4 ! In bits 197ca8f29b6Schristos mov 8<<3, %l3 198ca8f29b6Schristos 199ca8f29b6Schristos ldx [%l0], %o0 ! Load word -1 200ca8f29b6Schristos sub %l3, %l4, %l3 ! Reverse shift 201ca8f29b6Schristos deccc 12*8, %l2 ! Have enough room? 202ca8f29b6Schristos 203ca8f29b6Schristos sllx %o0, %l4, %o0 204ca8f29b6Schristos bl,pn CCCR, 2f 205ca8f29b6Schristos and %l3, 0x38, %l3 206ca8f29b6SchristosLmemcpy_unrolled8: 207ca8f29b6Schristos 208ca8f29b6Schristos /* 209ca8f29b6Schristos * This is about as close to optimal as you can get, since 210ca8f29b6Schristos * the shifts require EU0 and cannot be paired, and you have 211ca8f29b6Schristos * 3 dependent operations on the data. 212ca8f29b6Schristos */ 213ca8f29b6Schristos 214ca8f29b6Schristos! ldx [%l0+0*8], %o0 ! Already done 215ca8f29b6Schristos! sllx %o0, %l4, %o0 ! Already done 216ca8f29b6Schristos ldx [%l0+1*8], %o1 217ca8f29b6Schristos ldx [%l0+2*8], %o2 218ca8f29b6Schristos ldx [%l0+3*8], %o3 219ca8f29b6Schristos ldx [%l0+4*8], %o4 220ca8f29b6Schristos ba,pt %icc, 1f 221ca8f29b6Schristos ldx [%l0+5*8], %o5 222ca8f29b6Schristos .align 8 223ca8f29b6Schristos1: 224ca8f29b6Schristos srlx %o1, %l3, %g1 225ca8f29b6Schristos inc 6*8, %l0 226ca8f29b6Schristos 227ca8f29b6Schristos sllx %o1, %l4, %o1 228ca8f29b6Schristos or %g1, %o0, %g6 229ca8f29b6Schristos ldx [%l0+0*8], %o0 230ca8f29b6Schristos 231ca8f29b6Schristos stx %g6, [%l1+0*8] 232ca8f29b6Schristos srlx %o2, %l3, %g1 233ca8f29b6Schristos 234ca8f29b6Schristos sllx %o2, %l4, %o2 235ca8f29b6Schristos or %g1, %o1, %g6 236ca8f29b6Schristos ldx [%l0+1*8], %o1 237ca8f29b6Schristos 238ca8f29b6Schristos stx %g6, [%l1+1*8] 239ca8f29b6Schristos srlx %o3, %l3, %g1 240ca8f29b6Schristos 241ca8f29b6Schristos sllx %o3, %l4, %o3 242ca8f29b6Schristos or %g1, %o2, %g6 243ca8f29b6Schristos ldx [%l0+2*8], %o2 244ca8f29b6Schristos 245ca8f29b6Schristos stx %g6, [%l1+2*8] 246ca8f29b6Schristos srlx %o4, %l3, %g1 247ca8f29b6Schristos 248ca8f29b6Schristos sllx %o4, %l4, %o4 249ca8f29b6Schristos or %g1, %o3, %g6 250ca8f29b6Schristos ldx [%l0+3*8], %o3 251ca8f29b6Schristos 252ca8f29b6Schristos stx %g6, [%l1+3*8] 253ca8f29b6Schristos srlx %o5, %l3, %g1 254ca8f29b6Schristos 255ca8f29b6Schristos sllx %o5, %l4, %o5 256ca8f29b6Schristos or %g1, %o4, %g6 257ca8f29b6Schristos ldx [%l0+4*8], %o4 258ca8f29b6Schristos 259ca8f29b6Schristos stx %g6, [%l1+4*8] 260ca8f29b6Schristos srlx %o0, %l3, %g1 261ca8f29b6Schristos deccc 6*8, %l2 ! Have enough room? 262ca8f29b6Schristos 263ca8f29b6Schristos sllx %o0, %l4, %o0 ! Next loop 264ca8f29b6Schristos or %g1, %o5, %g6 265ca8f29b6Schristos ldx [%l0+5*8], %o5 266ca8f29b6Schristos 267ca8f29b6Schristos stx %g6, [%l1+5*8] 268ca8f29b6Schristos bge,pt CCCR, 1b 269ca8f29b6Schristos inc 6*8, %l1 270ca8f29b6Schristos 271ca8f29b6SchristosLmemcpy_unrolled8_cleanup: 272ca8f29b6Schristos !! 273ca8f29b6Schristos !! Finished 8 byte block, unload the regs. 274ca8f29b6Schristos !! 275ca8f29b6Schristos srlx %o1, %l3, %g1 276ca8f29b6Schristos inc 5*8, %l0 277ca8f29b6Schristos 278ca8f29b6Schristos sllx %o1, %l4, %o1 279ca8f29b6Schristos or %g1, %o0, %g6 280ca8f29b6Schristos 281ca8f29b6Schristos stx %g6, [%l1+0*8] 282ca8f29b6Schristos srlx %o2, %l3, %g1 283ca8f29b6Schristos 284ca8f29b6Schristos sllx %o2, %l4, %o2 285ca8f29b6Schristos or %g1, %o1, %g6 286ca8f29b6Schristos 287ca8f29b6Schristos stx %g6, [%l1+1*8] 288ca8f29b6Schristos srlx %o3, %l3, %g1 289ca8f29b6Schristos 290ca8f29b6Schristos sllx %o3, %l4, %o3 291ca8f29b6Schristos or %g1, %o2, %g6 292ca8f29b6Schristos 293ca8f29b6Schristos stx %g6, [%l1+2*8] 294ca8f29b6Schristos srlx %o4, %l3, %g1 295ca8f29b6Schristos 296ca8f29b6Schristos sllx %o4, %l4, %o4 297ca8f29b6Schristos or %g1, %o3, %g6 298ca8f29b6Schristos 299ca8f29b6Schristos stx %g6, [%l1+3*8] 300ca8f29b6Schristos srlx %o5, %l3, %g1 301ca8f29b6Schristos 302ca8f29b6Schristos sllx %o5, %l4, %o5 303ca8f29b6Schristos or %g1, %o4, %g6 304ca8f29b6Schristos 305ca8f29b6Schristos stx %g6, [%l1+4*8] 306ca8f29b6Schristos inc 5*8, %l1 307ca8f29b6Schristos 308ca8f29b6Schristos mov %o5, %o0 ! Save our unused data 309ca8f29b6Schristos dec 5*8, %l2 310ca8f29b6Schristos2: 311ca8f29b6Schristos inccc 12*8, %l2 312ca8f29b6Schristos bz,pn %icc, Lmemcpy_complete 313ca8f29b6Schristos 314ca8f29b6Schristos !! Unrolled 8 times 315ca8f29b6SchristosLmemcpy_aligned8: 316ca8f29b6Schristos! ldx [%l0], %o0 ! Already done 317ca8f29b6Schristos! sllx %o0, %l4, %o0 ! Shift high word 318ca8f29b6Schristos 319ca8f29b6Schristos deccc 8, %l2 ! Pre-decrement 320ca8f29b6Schristos bl,pn CCCR, Lmemcpy_finish 321ca8f29b6Schristos1: 322ca8f29b6Schristos ldx [%l0+8], %o1 ! Load word 0 323ca8f29b6Schristos inc 8, %l0 324ca8f29b6Schristos 325ca8f29b6Schristos srlx %o1, %l3, %g6 326ca8f29b6Schristos or %g6, %o0, %g6 ! Combine 327ca8f29b6Schristos 328ca8f29b6Schristos stx %g6, [%l1] ! Store result 329ca8f29b6Schristos inc 8, %l1 330ca8f29b6Schristos 331ca8f29b6Schristos deccc 8, %l2 332ca8f29b6Schristos bge,pn CCCR, 1b 333ca8f29b6Schristos sllx %o1, %l4, %o0 334ca8f29b6Schristos 335ca8f29b6Schristos btst 7, %l2 ! Done? 336ca8f29b6Schristos bz,pt CCCR, Lmemcpy_complete 337ca8f29b6Schristos 338ca8f29b6Schristos !! 339ca8f29b6Schristos !! Loadup the last dregs into %o0 and shift it into place 340ca8f29b6Schristos !! 341ca8f29b6Schristos srlx %l3, 3, %g6 ! # bytes in %o0 342ca8f29b6Schristos dec 8, %g6 ! - 8 343ca8f29b6Schristos !! n-8 - (by - 8) -> n - by 344ca8f29b6Schristos subcc %l2, %g6, %g0 ! # bytes we need 345ca8f29b6Schristos ble,pt %icc, Lmemcpy_finish 346ca8f29b6Schristos nop 347ca8f29b6Schristos ldx [%l0+8], %o1 ! Need another word 348ca8f29b6Schristos srlx %o1, %l3, %o1 349ca8f29b6Schristos ba,pt %icc, Lmemcpy_finish 350ca8f29b6Schristos or %o0, %o1, %o0 ! All loaded up. 351ca8f29b6Schristos 352ca8f29b6SchristosLmemcpy_noshift8: 353ca8f29b6Schristos deccc 6*8, %l2 ! Have enough room? 354ca8f29b6Schristos bl,pn CCCR, 2f 355ca8f29b6Schristos nop 356ca8f29b6Schristos ba,pt %icc, 1f 357ca8f29b6Schristos nop 358ca8f29b6Schristos .align 32 359ca8f29b6Schristos1: 360ca8f29b6Schristos ldx [%l0+0*8], %o0 361ca8f29b6Schristos ldx [%l0+1*8], %o1 362ca8f29b6Schristos ldx [%l0+2*8], %o2 363ca8f29b6Schristos stx %o0, [%l1+0*8] 364ca8f29b6Schristos stx %o1, [%l1+1*8] 365ca8f29b6Schristos stx %o2, [%l1+2*8] 366ca8f29b6Schristos 367ca8f29b6Schristos 368ca8f29b6Schristos ldx [%l0+3*8], %o3 369ca8f29b6Schristos ldx [%l0+4*8], %o4 370ca8f29b6Schristos ldx [%l0+5*8], %o5 371ca8f29b6Schristos inc 6*8, %l0 372ca8f29b6Schristos stx %o3, [%l1+3*8] 373ca8f29b6Schristos deccc 6*8, %l2 374ca8f29b6Schristos stx %o4, [%l1+4*8] 375ca8f29b6Schristos stx %o5, [%l1+5*8] 376ca8f29b6Schristos bge,pt CCCR, 1b 377ca8f29b6Schristos inc 6*8, %l1 378ca8f29b6Schristos2: 379ca8f29b6Schristos inc 6*8, %l2 380ca8f29b6Schristos1: 381ca8f29b6Schristos deccc 8, %l2 382ca8f29b6Schristos bl,pn %icc, 1f ! < 0 --> sub word 383ca8f29b6Schristos nop 384ca8f29b6Schristos ldx [%l0], %g6 385ca8f29b6Schristos inc 8, %l0 386ca8f29b6Schristos stx %g6, [%l1] 387ca8f29b6Schristos bg,pt %icc, 1b ! Exactly 0 --> done 388ca8f29b6Schristos inc 8, %l1 389ca8f29b6Schristos1: 390ca8f29b6Schristos btst 7, %l2 ! Done? 391ca8f29b6Schristos bz,pt CCCR, Lmemcpy_complete 392ca8f29b6Schristos clr %l4 393ca8f29b6Schristos ldx [%l0], %o0 394ca8f29b6SchristosLmemcpy_finish: 395ca8f29b6Schristos 396ca8f29b6Schristos brz,pn %l2, 2f ! 100% complete? 397ca8f29b6Schristos cmp %l2, 8 ! Exactly 8 bytes? 398ca8f29b6Schristos bz,a,pn CCCR, 2f 399ca8f29b6Schristos stx %o0, [%l1] 400ca8f29b6Schristos 401ca8f29b6Schristos btst 4, %l2 ! Word store? 402ca8f29b6Schristos bz CCCR, 1f 403ca8f29b6Schristos srlx %o0, 32, %g6 ! Shift high word down 404ca8f29b6Schristos stw %g6, [%l1] 405ca8f29b6Schristos inc 4, %l1 406ca8f29b6Schristos mov %o0, %g6 ! Operate on the low bits 407ca8f29b6Schristos1: 408ca8f29b6Schristos btst 2, %l2 409ca8f29b6Schristos mov %g6, %o0 410ca8f29b6Schristos bz 1f 411ca8f29b6Schristos srlx %o0, 16, %g6 412ca8f29b6Schristos 413ca8f29b6Schristos sth %g6, [%l1] ! Store short 414ca8f29b6Schristos inc 2, %l1 415ca8f29b6Schristos mov %o0, %g6 ! Operate on low bytes 416ca8f29b6Schristos1: 417ca8f29b6Schristos mov %g6, %o0 418ca8f29b6Schristos btst 1, %l2 ! Byte aligned? 419ca8f29b6Schristos bz 2f 420ca8f29b6Schristos srlx %o0, 8, %g6 421ca8f29b6Schristos 422ca8f29b6Schristos stb %g6, [%l1] ! Store last byte 423ca8f29b6Schristos inc 1, %l1 ! Update address 424ca8f29b6Schristos2: 425ca8f29b6SchristosLmemcpy_complete: 426ca8f29b6Schristos#if 0 427ca8f29b6Schristos !! 428ca8f29b6Schristos !! verify copy success. 429ca8f29b6Schristos !! 430ca8f29b6Schristos 431ca8f29b6Schristos mov %i0, %o2 432ca8f29b6Schristos mov %i1, %o4 433ca8f29b6Schristos mov %i2, %l4 434ca8f29b6Schristos0: 435ca8f29b6Schristos ldub [%o2], %o1 436ca8f29b6Schristos inc %o2 437ca8f29b6Schristos ldub [%o4], %o3 438ca8f29b6Schristos inc %o4 439ca8f29b6Schristos cmp %o3, %o1 440ca8f29b6Schristos bnz 1f 441ca8f29b6Schristos dec %l4 442ca8f29b6Schristos brnz %l4, 0b 443ca8f29b6Schristos nop 444ca8f29b6Schristos ba 2f 445ca8f29b6Schristos nop 446ca8f29b6Schristos 447ca8f29b6Schristos1: 448ca8f29b6Schristos set 0f, %o0 449ca8f29b6Schristos call printf 450ca8f29b6Schristos sub %i2, %l4, %o5 451ca8f29b6Schristos set 1f, %o0 452ca8f29b6Schristos mov %i0, %o2 453ca8f29b6Schristos mov %i1, %o1 454ca8f29b6Schristos call printf 455ca8f29b6Schristos mov %i2, %o3 456ca8f29b6Schristos ta 1 457ca8f29b6Schristos .data 458ca8f29b6Schristos0: .asciz "memcpy failed: %x@%p != %x@%p byte %d\n" 459ca8f29b6Schristos1: .asciz "memcpy(%p, %p, %lx)\n" 460ca8f29b6Schristos .align 8 461ca8f29b6Schristos .text 462ca8f29b6Schristos2: 463ca8f29b6Schristos#endif 464ca8f29b6Schristos ret 465ca8f29b6Schristos restore %i1, %g0, %o0 466ca8f29b6Schristos 467ca8f29b6Schristos#ifdef USE_BLOCK_STORE_LOAD 468ca8f29b6Schristos 469ca8f29b6Schristos/* 470ca8f29b6Schristos * Block copy. Useful for >256 byte copies. 471ca8f29b6Schristos * 472ca8f29b6Schristos * Benchmarking has shown this always seems to be slower than 473ca8f29b6Schristos * the integer version, so this is disabled. Maybe someone will 474ca8f29b6Schristos * figure out why sometime. 475ca8f29b6Schristos */ 476ca8f29b6Schristos 477ca8f29b6SchristosLmemcpy_block: 478ca8f29b6Schristos sethi %hi(block_disable), %o3 479ca8f29b6Schristos ldx [ %o3 + %lo(block_disable) ], %o3 480ca8f29b6Schristos brnz,pn %o3, Lmemcpy_fancy 481ca8f29b6Schristos !! Make sure our trap table is installed 482ca8f29b6Schristos set _C_LABEL(trapbase), %o5 483ca8f29b6Schristos rdpr %tba, %o3 484ca8f29b6Schristos sub %o3, %o5, %o3 485ca8f29b6Schristos brnz,pn %o3, Lmemcpy_fancy ! No, then don't use block load/store 486ca8f29b6Schristos nop 487ca8f29b6Schristos#if defined(_KERNEL) && !defined(_RUMPKERNEL) 488ca8f29b6Schristos/* 489ca8f29b6Schristos * Kernel: 490ca8f29b6Schristos * 491ca8f29b6Schristos * Here we use VIS instructions to do a block clear of a page. 492ca8f29b6Schristos * But before we can do that we need to save and enable the FPU. 493ca8f29b6Schristos * The last owner of the FPU registers is fplwp, and 494ca8f29b6Schristos * fplwp->l_md.md_fpstate is the current fpstate. If that's not 495ca8f29b6Schristos * null, call savefpstate() with it to store our current fp state. 496ca8f29b6Schristos * 497ca8f29b6Schristos * Next, allocate an aligned fpstate on the stack. We will properly 498ca8f29b6Schristos * nest calls on a particular stack so this should not be a problem. 499ca8f29b6Schristos * 500ca8f29b6Schristos * Now we grab either curlwp (or if we're on the interrupt stack 501ca8f29b6Schristos * lwp0). We stash its existing fpstate in a local register and 502ca8f29b6Schristos * put our new fpstate in curlwp->p_md.md_fpstate. We point 503ca8f29b6Schristos * fplwp at curlwp (or lwp0) and enable the FPU. 504ca8f29b6Schristos * 505ca8f29b6Schristos * If we are ever preempted, our FPU state will be saved in our 506ca8f29b6Schristos * fpstate. Then, when we're resumed and we take an FPDISABLED 507ca8f29b6Schristos * trap, the trap handler will be able to fish our FPU state out 508ca8f29b6Schristos * of curlwp (or lwp0). 509ca8f29b6Schristos * 510ca8f29b6Schristos * On exiting this routine we undo the damage: restore the original 511ca8f29b6Schristos * pointer to curlwp->p_md.md_fpstate, clear our fplwp, and disable 512ca8f29b6Schristos * the MMU. 513ca8f29b6Schristos * 514ca8f29b6Schristos * 515ca8f29b6Schristos * Register usage, Kernel only (after save): 516ca8f29b6Schristos * 517ca8f29b6Schristos * %i0 src 518ca8f29b6Schristos * %i1 dest 519ca8f29b6Schristos * %i2 size 520ca8f29b6Schristos * 521ca8f29b6Schristos * %l0 XXXX DEBUG old fpstate 522ca8f29b6Schristos * %l1 fplwp (hi bits only) 523ca8f29b6Schristos * %l2 orig fplwp 524ca8f29b6Schristos * %l3 orig fpstate 525ca8f29b6Schristos * %l5 curlwp 526ca8f29b6Schristos * %l6 old fpstate 527ca8f29b6Schristos * 528ca8f29b6Schristos * Register ussage, Kernel and user: 529ca8f29b6Schristos * 530ca8f29b6Schristos * %g1 src (retval for memcpy) 531ca8f29b6Schristos * 532ca8f29b6Schristos * %o0 src 533ca8f29b6Schristos * %o1 dest 534ca8f29b6Schristos * %o2 end dest 535ca8f29b6Schristos * %o5 last safe fetchable address 536ca8f29b6Schristos */ 537ca8f29b6Schristos 538ca8f29b6Schristos ENABLE_FPU(0) 539ca8f29b6Schristos 540ca8f29b6Schristos mov %i0, %o0 ! Src addr. 541ca8f29b6Schristos mov %i1, %o1 ! Store our dest ptr here. 542ca8f29b6Schristos mov %i2, %o2 ! Len counter 543ca8f29b6Schristos#endif /* _KERNEL */ 544ca8f29b6Schristos 545ca8f29b6Schristos !! 546ca8f29b6Schristos !! First align the output to a 64-bit entity 547ca8f29b6Schristos !! 548ca8f29b6Schristos 549ca8f29b6Schristos mov %o1, %g1 ! memcpy retval 550ca8f29b6Schristos add %o0, %o2, %o5 ! End of source block 551ca8f29b6Schristos 552ca8f29b6Schristos andn %o0, 7, %o3 ! Start of block 553ca8f29b6Schristos dec %o5 554ca8f29b6Schristos fzero %f0 555ca8f29b6Schristos 556ca8f29b6Schristos andn %o5, BLOCK_ALIGN, %o5 ! Last safe addr. 557ca8f29b6Schristos ldd [%o3], %f2 ! Load 1st word 558ca8f29b6Schristos 559ca8f29b6Schristos dec 8, %o3 ! Move %o3 1 word back 560ca8f29b6Schristos btst 1, %o1 561ca8f29b6Schristos bz 4f 562ca8f29b6Schristos 563ca8f29b6Schristos mov -7, %o4 ! Lowest src addr possible 564ca8f29b6Schristos alignaddr %o0, %o4, %o4 ! Base addr for load. 565ca8f29b6Schristos 566ca8f29b6Schristos cmp %o3, %o4 567ca8f29b6Schristos be,pt CCCR, 1f ! Already loaded? 568ca8f29b6Schristos mov %o4, %o3 569ca8f29b6Schristos fmovd %f2, %f0 ! No. Shift 570ca8f29b6Schristos ldd [%o3+8], %f2 ! And load 571ca8f29b6Schristos1: 572ca8f29b6Schristos 573ca8f29b6Schristos faligndata %f0, %f2, %f4 ! Isolate 1st byte 574ca8f29b6Schristos 575ca8f29b6Schristos stda %f4, [%o1] ASI_FL8_P ! Store 1st byte 576ca8f29b6Schristos inc 1, %o1 ! Update address 577ca8f29b6Schristos inc 1, %o0 578ca8f29b6Schristos dec 1, %o2 579ca8f29b6Schristos4: 580ca8f29b6Schristos btst 2, %o1 581ca8f29b6Schristos bz 4f 582ca8f29b6Schristos 583ca8f29b6Schristos mov -6, %o4 ! Calculate src - 6 584ca8f29b6Schristos alignaddr %o0, %o4, %o4 ! calculate shift mask and dest. 585ca8f29b6Schristos 586ca8f29b6Schristos cmp %o3, %o4 ! Addresses same? 587ca8f29b6Schristos be,pt CCCR, 1f 588ca8f29b6Schristos mov %o4, %o3 589ca8f29b6Schristos fmovd %f2, %f0 ! Shuffle data 590ca8f29b6Schristos ldd [%o3+8], %f2 ! Load word 0 591ca8f29b6Schristos1: 592ca8f29b6Schristos faligndata %f0, %f2, %f4 ! Move 1st short low part of f8 593ca8f29b6Schristos 594ca8f29b6Schristos stda %f4, [%o1] ASI_FL16_P ! Store 1st short 595ca8f29b6Schristos dec 2, %o2 596ca8f29b6Schristos inc 2, %o1 597ca8f29b6Schristos inc 2, %o0 598ca8f29b6Schristos4: 599ca8f29b6Schristos brz,pn %o2, Lmemcpy_blockfinish ! XXXX 600ca8f29b6Schristos 601ca8f29b6Schristos btst 4, %o1 602ca8f29b6Schristos bz 4f 603ca8f29b6Schristos 604ca8f29b6Schristos mov -4, %o4 605ca8f29b6Schristos alignaddr %o0, %o4, %o4 ! calculate shift mask and dest. 606ca8f29b6Schristos 607ca8f29b6Schristos cmp %o3, %o4 ! Addresses same? 608ca8f29b6Schristos beq,pt CCCR, 1f 609ca8f29b6Schristos mov %o4, %o3 610ca8f29b6Schristos fmovd %f2, %f0 ! Shuffle data 611ca8f29b6Schristos ldd [%o3+8], %f2 ! Load word 0 612ca8f29b6Schristos1: 613ca8f29b6Schristos faligndata %f0, %f2, %f4 ! Move 1st short low part of f8 614ca8f29b6Schristos 615ca8f29b6Schristos st %f5, [%o1] ! Store word 616ca8f29b6Schristos dec 4, %o2 617ca8f29b6Schristos inc 4, %o1 618ca8f29b6Schristos inc 4, %o0 619ca8f29b6Schristos4: 620ca8f29b6Schristos brz,pn %o2, Lmemcpy_blockfinish ! XXXX 621ca8f29b6Schristos !! 622ca8f29b6Schristos !! We are now 32-bit aligned in the dest. 623ca8f29b6Schristos !! 624ca8f29b6SchristosLmemcpy_block_common: 625ca8f29b6Schristos 626ca8f29b6Schristos mov -0, %o4 627ca8f29b6Schristos alignaddr %o0, %o4, %o4 ! base - shift 628ca8f29b6Schristos 629ca8f29b6Schristos cmp %o3, %o4 ! Addresses same? 630ca8f29b6Schristos beq,pt CCCR, 1f 631ca8f29b6Schristos mov %o4, %o3 632ca8f29b6Schristos fmovd %f2, %f0 ! Shuffle data 633ca8f29b6Schristos ldd [%o3+8], %f2 ! Load word 0 634ca8f29b6Schristos1: 635ca8f29b6Schristos add %o3, 8, %o0 ! now use %o0 for src 636ca8f29b6Schristos 637ca8f29b6Schristos !! 638ca8f29b6Schristos !! Continue until our dest is block aligned 639ca8f29b6Schristos !! 640ca8f29b6SchristosLmemcpy_block_aligned8: 641ca8f29b6Schristos1: 642ca8f29b6Schristos brz %o2, Lmemcpy_blockfinish 643ca8f29b6Schristos btst BLOCK_ALIGN, %o1 ! Block aligned? 644ca8f29b6Schristos bz 1f 645ca8f29b6Schristos 646ca8f29b6Schristos faligndata %f0, %f2, %f4 ! Generate result 647ca8f29b6Schristos deccc 8, %o2 648ca8f29b6Schristos ble,pn %icc, Lmemcpy_blockfinish ! Should never happen 649ca8f29b6Schristos fmovd %f4, %f48 650ca8f29b6Schristos 651ca8f29b6Schristos std %f4, [%o1] ! Store result 652ca8f29b6Schristos inc 8, %o1 653ca8f29b6Schristos 654ca8f29b6Schristos fmovd %f2, %f0 655ca8f29b6Schristos inc 8, %o0 656ca8f29b6Schristos ba,pt %xcc, 1b ! Not yet. 657ca8f29b6Schristos ldd [%o0], %f2 ! Load next part 658ca8f29b6SchristosLmemcpy_block_aligned64: 659ca8f29b6Schristos1: 660ca8f29b6Schristos 661ca8f29b6Schristos/* 662ca8f29b6Schristos * 64-byte aligned -- ready for block operations. 663ca8f29b6Schristos * 664ca8f29b6Schristos * Here we have the destination block aligned, but the 665ca8f29b6Schristos * source pointer may not be. Sub-word alignment will 666ca8f29b6Schristos * be handled by faligndata instructions. But the source 667ca8f29b6Schristos * can still be potentially aligned to 8 different words 668ca8f29b6Schristos * in our 64-bit block, so we have 8 different copy routines. 669ca8f29b6Schristos * 670ca8f29b6Schristos * Once we figure out our source alignment, we branch 671ca8f29b6Schristos * to the appropriate copy routine, which sets up the 672ca8f29b6Schristos * alignment for faligndata and loads (sets) the values 673ca8f29b6Schristos * into the source registers and does the copy loop. 674ca8f29b6Schristos * 675ca8f29b6Schristos * When were down to less than 1 block to store, we 676ca8f29b6Schristos * exit the copy loop and execute cleanup code. 677ca8f29b6Schristos * 678ca8f29b6Schristos * Block loads and stores are not properly interlocked. 679ca8f29b6Schristos * Stores save one reg/cycle, so you can start overwriting 680ca8f29b6Schristos * registers the cycle after the store is issued. 681ca8f29b6Schristos * 682ca8f29b6Schristos * Block loads require a block load to a different register 683ca8f29b6Schristos * block or a membar #Sync before accessing the loaded 684ca8f29b6Schristos * data. 685ca8f29b6Schristos * 686ca8f29b6Schristos * Since the faligndata instructions may be offset as far 687ca8f29b6Schristos * as 7 registers into a block (if you are shifting source 688ca8f29b6Schristos * 7 -> dest 0), you need 3 source register blocks for full 689ca8f29b6Schristos * performance: one you are copying, one you are loading, 690ca8f29b6Schristos * and one for interlocking. Otherwise, we would need to 691ca8f29b6Schristos * sprinkle the code with membar #Sync and lose the advantage 692ca8f29b6Schristos * of running faligndata in parallel with block stores. This 693ca8f29b6Schristos * means we are fetching a full 128 bytes ahead of the stores. 694ca8f29b6Schristos * We need to make sure the prefetch does not inadvertently 695ca8f29b6Schristos * cross a page boundary and fault on data that we will never 696ca8f29b6Schristos * store. 697ca8f29b6Schristos * 698ca8f29b6Schristos */ 699ca8f29b6Schristos#if 1 700ca8f29b6Schristos and %o0, BLOCK_ALIGN, %o3 701ca8f29b6Schristos srax %o3, 3, %o3 ! Isolate the offset 702ca8f29b6Schristos 703ca8f29b6Schristos brz %o3, L100 ! 0->0 704ca8f29b6Schristos btst 4, %o3 705ca8f29b6Schristos bnz %xcc, 4f 706ca8f29b6Schristos btst 2, %o3 707ca8f29b6Schristos bnz %xcc, 2f 708ca8f29b6Schristos btst 1, %o3 709ca8f29b6Schristos ba,pt %xcc, L101 ! 0->1 710ca8f29b6Schristos nop /* XXX spitfire bug */ 711ca8f29b6Schristos2: 712ca8f29b6Schristos bz %xcc, L102 ! 0->2 713ca8f29b6Schristos nop 714ca8f29b6Schristos ba,pt %xcc, L103 ! 0->3 715ca8f29b6Schristos nop /* XXX spitfire bug */ 716ca8f29b6Schristos4: 717ca8f29b6Schristos bnz %xcc, 2f 718ca8f29b6Schristos btst 1, %o3 719ca8f29b6Schristos bz %xcc, L104 ! 0->4 720ca8f29b6Schristos nop 721ca8f29b6Schristos ba,pt %xcc, L105 ! 0->5 722ca8f29b6Schristos nop /* XXX spitfire bug */ 723ca8f29b6Schristos2: 724ca8f29b6Schristos bz %xcc, L106 ! 0->6 725ca8f29b6Schristos nop 726ca8f29b6Schristos ba,pt %xcc, L107 ! 0->7 727ca8f29b6Schristos nop /* XXX spitfire bug */ 728ca8f29b6Schristos#else 729ca8f29b6Schristos 730ca8f29b6Schristos !! 731ca8f29b6Schristos !! Isolate the word offset, which just happens to be 732ca8f29b6Schristos !! the slot in our jump table. 733ca8f29b6Schristos !! 734ca8f29b6Schristos !! This is 6 insns, most of which cannot be paired, 735ca8f29b6Schristos !! which is about the same as the above version. 736ca8f29b6Schristos !! 737ca8f29b6Schristos rd %pc, %o4 738ca8f29b6Schristos1: 739ca8f29b6Schristos and %o0, 0x31, %o3 740ca8f29b6Schristos add %o3, (Lmemcpy_block_jmp - 1b), %o3 741ca8f29b6Schristos jmpl %o4 + %o3, %g0 742ca8f29b6Schristos nop 743ca8f29b6Schristos 744ca8f29b6Schristos !! 745ca8f29b6Schristos !! Jump table 746ca8f29b6Schristos !! 747ca8f29b6Schristos 748ca8f29b6SchristosLmemcpy_block_jmp: 749ca8f29b6Schristos ba,a,pt %xcc, L100 750ca8f29b6Schristos nop 751ca8f29b6Schristos ba,a,pt %xcc, L101 752ca8f29b6Schristos nop 753ca8f29b6Schristos ba,a,pt %xcc, L102 754ca8f29b6Schristos nop 755ca8f29b6Schristos ba,a,pt %xcc, L103 756ca8f29b6Schristos nop 757ca8f29b6Schristos ba,a,pt %xcc, L104 758ca8f29b6Schristos nop 759ca8f29b6Schristos ba,a,pt %xcc, L105 760ca8f29b6Schristos nop 761ca8f29b6Schristos ba,a,pt %xcc, L106 762ca8f29b6Schristos nop 763ca8f29b6Schristos ba,a,pt %xcc, L107 764ca8f29b6Schristos nop 765ca8f29b6Schristos#endif 766ca8f29b6Schristos 767ca8f29b6Schristos !! 768ca8f29b6Schristos !! Source is block aligned. 769ca8f29b6Schristos !! 770ca8f29b6Schristos !! Just load a block and go. 771ca8f29b6Schristos !! 772ca8f29b6SchristosL100: 773ca8f29b6Schristos#ifdef RETURN_NAME 774ca8f29b6Schristos sethi %hi(1f), %g1 775ca8f29b6Schristos ba,pt %icc, 2f 776ca8f29b6Schristos or %g1, %lo(1f), %g1 777ca8f29b6Schristos1: 778ca8f29b6Schristos .asciz "L100" 779ca8f29b6Schristos .align 8 780ca8f29b6Schristos2: 781ca8f29b6Schristos#endif 782ca8f29b6Schristos fmovd %f0 , %f62 783ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f0 784ca8f29b6Schristos inc BLOCK_SIZE, %o0 785ca8f29b6Schristos cmp %o0, %o5 786ca8f29b6Schristos bleu,a,pn %icc, 3f 787ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 788ca8f29b6Schristos ba,pt %icc, 3f 789ca8f29b6Schristos membar #Sync 790ca8f29b6Schristos 791ca8f29b6Schristos .align 32 ! ICache align. 792ca8f29b6Schristos3: 793ca8f29b6Schristos faligndata %f62, %f0, %f32 794ca8f29b6Schristos inc BLOCK_SIZE, %o0 795ca8f29b6Schristos faligndata %f0, %f2, %f34 796ca8f29b6Schristos dec BLOCK_SIZE, %o2 797ca8f29b6Schristos faligndata %f2, %f4, %f36 798ca8f29b6Schristos cmp %o0, %o5 799ca8f29b6Schristos faligndata %f4, %f6, %f38 800ca8f29b6Schristos faligndata %f6, %f8, %f40 801ca8f29b6Schristos faligndata %f8, %f10, %f42 802ca8f29b6Schristos faligndata %f10, %f12, %f44 803ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 804ca8f29b6Schristos faligndata %f12, %f14, %f46 805ca8f29b6Schristos 806ca8f29b6Schristos bleu,a,pn %icc, 2f 807ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f48 808ca8f29b6Schristos membar #Sync 809ca8f29b6Schristos2: 810ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 811ca8f29b6Schristos faligndata %f14, %f16, %f32 812ca8f29b6Schristos inc BLOCK_SIZE, %o0 813ca8f29b6Schristos faligndata %f16, %f18, %f34 814ca8f29b6Schristos inc BLOCK_SIZE, %o1 815ca8f29b6Schristos faligndata %f18, %f20, %f36 816ca8f29b6Schristos dec BLOCK_SIZE, %o2 817ca8f29b6Schristos faligndata %f20, %f22, %f38 818ca8f29b6Schristos cmp %o0, %o5 819ca8f29b6Schristos faligndata %f22, %f24, %f40 820ca8f29b6Schristos faligndata %f24, %f26, %f42 821ca8f29b6Schristos faligndata %f26, %f28, %f44 822ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 823ca8f29b6Schristos faligndata %f28, %f30, %f46 824ca8f29b6Schristos 825ca8f29b6Schristos bleu,a,pn %icc, 2f 826ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f0 827ca8f29b6Schristos membar #Sync 828ca8f29b6Schristos2: 829ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 830ca8f29b6Schristos faligndata %f30, %f48, %f32 831ca8f29b6Schristos inc BLOCK_SIZE, %o0 832ca8f29b6Schristos faligndata %f48, %f50, %f34 833ca8f29b6Schristos inc BLOCK_SIZE, %o1 834ca8f29b6Schristos faligndata %f50, %f52, %f36 835ca8f29b6Schristos dec BLOCK_SIZE, %o2 836ca8f29b6Schristos faligndata %f52, %f54, %f38 837ca8f29b6Schristos cmp %o0, %o5 838ca8f29b6Schristos faligndata %f54, %f56, %f40 839ca8f29b6Schristos faligndata %f56, %f58, %f42 840ca8f29b6Schristos faligndata %f58, %f60, %f44 841ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 842ca8f29b6Schristos faligndata %f60, %f62, %f46 843ca8f29b6Schristos bleu,a,pn %icc, 2f 844ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 ! Increment is at top 845ca8f29b6Schristos membar #Sync 846ca8f29b6Schristos2: 847ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 848ca8f29b6Schristos ba 3b 849ca8f29b6Schristos inc BLOCK_SIZE, %o1 850ca8f29b6Schristos 851ca8f29b6Schristos !! 852ca8f29b6Schristos !! Source at BLOCK_ALIGN+8 853ca8f29b6Schristos !! 854ca8f29b6Schristos !! We need to load almost 1 complete block by hand. 855ca8f29b6Schristos !! 856ca8f29b6SchristosL101: 857ca8f29b6Schristos#ifdef RETURN_NAME 858ca8f29b6Schristos sethi %hi(1f), %g1 859ca8f29b6Schristos ba,pt %icc, 2f 860ca8f29b6Schristos or %g1, %lo(1f), %g1 861ca8f29b6Schristos1: 862ca8f29b6Schristos .asciz "L101" 863ca8f29b6Schristos .align 8 864ca8f29b6Schristos2: 865ca8f29b6Schristos#endif 866ca8f29b6Schristos! fmovd %f0, %f0 ! Hoist fmovd 867ca8f29b6Schristos ldd [%o0], %f2 868ca8f29b6Schristos inc 8, %o0 869ca8f29b6Schristos ldd [%o0], %f4 870ca8f29b6Schristos inc 8, %o0 871ca8f29b6Schristos ldd [%o0], %f6 872ca8f29b6Schristos inc 8, %o0 873ca8f29b6Schristos ldd [%o0], %f8 874ca8f29b6Schristos inc 8, %o0 875ca8f29b6Schristos ldd [%o0], %f10 876ca8f29b6Schristos inc 8, %o0 877ca8f29b6Schristos ldd [%o0], %f12 878ca8f29b6Schristos inc 8, %o0 879ca8f29b6Schristos ldd [%o0], %f14 880ca8f29b6Schristos inc 8, %o0 881ca8f29b6Schristos 882ca8f29b6Schristos cmp %o0, %o5 883ca8f29b6Schristos bleu,a,pn %icc, 3f 884ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 885ca8f29b6Schristos membar #Sync 886ca8f29b6Schristos3: 887ca8f29b6Schristos faligndata %f0, %f2, %f32 888ca8f29b6Schristos inc BLOCK_SIZE, %o0 889ca8f29b6Schristos faligndata %f2, %f4, %f34 890ca8f29b6Schristos cmp %o0, %o5 891ca8f29b6Schristos faligndata %f4, %f6, %f36 892ca8f29b6Schristos dec BLOCK_SIZE, %o2 893ca8f29b6Schristos faligndata %f6, %f8, %f38 894ca8f29b6Schristos faligndata %f8, %f10, %f40 895ca8f29b6Schristos faligndata %f10, %f12, %f42 896ca8f29b6Schristos faligndata %f12, %f14, %f44 897ca8f29b6Schristos bleu,a,pn %icc, 2f 898ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f48 899ca8f29b6Schristos membar #Sync 900ca8f29b6Schristos2: 901ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 902ca8f29b6Schristos faligndata %f14, %f16, %f46 903ca8f29b6Schristos 904ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 905ca8f29b6Schristos 906ca8f29b6Schristos faligndata %f16, %f18, %f32 907ca8f29b6Schristos inc BLOCK_SIZE, %o0 908ca8f29b6Schristos faligndata %f18, %f20, %f34 909ca8f29b6Schristos inc BLOCK_SIZE, %o1 910ca8f29b6Schristos faligndata %f20, %f22, %f36 911ca8f29b6Schristos cmp %o0, %o5 912ca8f29b6Schristos faligndata %f22, %f24, %f38 913ca8f29b6Schristos dec BLOCK_SIZE, %o2 914ca8f29b6Schristos faligndata %f24, %f26, %f40 915ca8f29b6Schristos faligndata %f26, %f28, %f42 916ca8f29b6Schristos faligndata %f28, %f30, %f44 917ca8f29b6Schristos bleu,a,pn %icc, 2f 918ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f0 919ca8f29b6Schristos membar #Sync 920ca8f29b6Schristos2: 921ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 922ca8f29b6Schristos faligndata %f30, %f48, %f46 923ca8f29b6Schristos 924ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 925ca8f29b6Schristos 926ca8f29b6Schristos faligndata %f48, %f50, %f32 927ca8f29b6Schristos inc BLOCK_SIZE, %o0 928ca8f29b6Schristos faligndata %f50, %f52, %f34 929ca8f29b6Schristos inc BLOCK_SIZE, %o1 930ca8f29b6Schristos faligndata %f52, %f54, %f36 931ca8f29b6Schristos cmp %o0, %o5 932ca8f29b6Schristos faligndata %f54, %f56, %f38 933ca8f29b6Schristos dec BLOCK_SIZE, %o2 934ca8f29b6Schristos faligndata %f56, %f58, %f40 935ca8f29b6Schristos faligndata %f58, %f60, %f42 936ca8f29b6Schristos faligndata %f60, %f62, %f44 937ca8f29b6Schristos bleu,a,pn %icc, 2f 938ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 939ca8f29b6Schristos membar #Sync 940ca8f29b6Schristos2: 941ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 942ca8f29b6Schristos faligndata %f62, %f0, %f46 943ca8f29b6Schristos 944ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 945ca8f29b6Schristos ba 3b 946ca8f29b6Schristos inc BLOCK_SIZE, %o1 947ca8f29b6Schristos 948ca8f29b6Schristos !! 949ca8f29b6Schristos !! Source at BLOCK_ALIGN+16 950ca8f29b6Schristos !! 951ca8f29b6Schristos !! We need to load 6 doubles by hand. 952ca8f29b6Schristos !! 953ca8f29b6SchristosL102: 954ca8f29b6Schristos#ifdef RETURN_NAME 955ca8f29b6Schristos sethi %hi(1f), %g1 956ca8f29b6Schristos ba,pt %icc, 2f 957ca8f29b6Schristos or %g1, %lo(1f), %g1 958ca8f29b6Schristos1: 959ca8f29b6Schristos .asciz "L102" 960ca8f29b6Schristos .align 8 961ca8f29b6Schristos2: 962ca8f29b6Schristos#endif 963ca8f29b6Schristos ldd [%o0], %f4 964ca8f29b6Schristos inc 8, %o0 965ca8f29b6Schristos fmovd %f0, %f2 ! Hoist fmovd 966ca8f29b6Schristos ldd [%o0], %f6 967ca8f29b6Schristos inc 8, %o0 968ca8f29b6Schristos 969ca8f29b6Schristos ldd [%o0], %f8 970ca8f29b6Schristos inc 8, %o0 971ca8f29b6Schristos ldd [%o0], %f10 972ca8f29b6Schristos inc 8, %o0 973ca8f29b6Schristos ldd [%o0], %f12 974ca8f29b6Schristos inc 8, %o0 975ca8f29b6Schristos ldd [%o0], %f14 976ca8f29b6Schristos inc 8, %o0 977ca8f29b6Schristos 978ca8f29b6Schristos cmp %o0, %o5 979ca8f29b6Schristos bleu,a,pn %icc, 3f 980ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 981ca8f29b6Schristos membar #Sync 982ca8f29b6Schristos3: 983ca8f29b6Schristos faligndata %f2, %f4, %f32 984ca8f29b6Schristos inc BLOCK_SIZE, %o0 985ca8f29b6Schristos faligndata %f4, %f6, %f34 986ca8f29b6Schristos cmp %o0, %o5 987ca8f29b6Schristos faligndata %f6, %f8, %f36 988ca8f29b6Schristos dec BLOCK_SIZE, %o2 989ca8f29b6Schristos faligndata %f8, %f10, %f38 990ca8f29b6Schristos faligndata %f10, %f12, %f40 991ca8f29b6Schristos faligndata %f12, %f14, %f42 992ca8f29b6Schristos bleu,a,pn %icc, 2f 993ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f48 994ca8f29b6Schristos membar #Sync 995ca8f29b6Schristos2: 996ca8f29b6Schristos faligndata %f14, %f16, %f44 997ca8f29b6Schristos 998ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 999ca8f29b6Schristos faligndata %f16, %f18, %f46 1000ca8f29b6Schristos 1001ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1002ca8f29b6Schristos 1003ca8f29b6Schristos faligndata %f18, %f20, %f32 1004ca8f29b6Schristos inc BLOCK_SIZE, %o0 1005ca8f29b6Schristos faligndata %f20, %f22, %f34 1006ca8f29b6Schristos inc BLOCK_SIZE, %o1 1007ca8f29b6Schristos faligndata %f22, %f24, %f36 1008ca8f29b6Schristos cmp %o0, %o5 1009ca8f29b6Schristos faligndata %f24, %f26, %f38 1010ca8f29b6Schristos dec BLOCK_SIZE, %o2 1011ca8f29b6Schristos faligndata %f26, %f28, %f40 1012ca8f29b6Schristos faligndata %f28, %f30, %f42 1013ca8f29b6Schristos bleu,a,pn %icc, 2f 1014ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f0 1015ca8f29b6Schristos membar #Sync 1016ca8f29b6Schristos2: 1017ca8f29b6Schristos faligndata %f30, %f48, %f44 1018ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1019ca8f29b6Schristos faligndata %f48, %f50, %f46 1020ca8f29b6Schristos 1021ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1022ca8f29b6Schristos 1023ca8f29b6Schristos faligndata %f50, %f52, %f32 1024ca8f29b6Schristos inc BLOCK_SIZE, %o0 1025ca8f29b6Schristos faligndata %f52, %f54, %f34 1026ca8f29b6Schristos inc BLOCK_SIZE, %o1 1027ca8f29b6Schristos faligndata %f54, %f56, %f36 1028ca8f29b6Schristos cmp %o0, %o5 1029ca8f29b6Schristos faligndata %f56, %f58, %f38 1030ca8f29b6Schristos dec BLOCK_SIZE, %o2 1031ca8f29b6Schristos faligndata %f58, %f60, %f40 1032ca8f29b6Schristos faligndata %f60, %f62, %f42 1033ca8f29b6Schristos bleu,a,pn %icc, 2f 1034ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 1035ca8f29b6Schristos membar #Sync 1036ca8f29b6Schristos2: 1037ca8f29b6Schristos faligndata %f62, %f0, %f44 1038ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1039ca8f29b6Schristos faligndata %f0, %f2, %f46 1040ca8f29b6Schristos 1041ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1042ca8f29b6Schristos ba 3b 1043ca8f29b6Schristos inc BLOCK_SIZE, %o1 1044ca8f29b6Schristos 1045ca8f29b6Schristos !! 1046ca8f29b6Schristos !! Source at BLOCK_ALIGN+24 1047ca8f29b6Schristos !! 1048ca8f29b6Schristos !! We need to load 5 doubles by hand. 1049ca8f29b6Schristos !! 1050ca8f29b6SchristosL103: 1051ca8f29b6Schristos#ifdef RETURN_NAME 1052ca8f29b6Schristos sethi %hi(1f), %g1 1053ca8f29b6Schristos ba,pt %icc, 2f 1054ca8f29b6Schristos or %g1, %lo(1f), %g1 1055ca8f29b6Schristos1: 1056ca8f29b6Schristos .asciz "L103" 1057ca8f29b6Schristos .align 8 1058ca8f29b6Schristos2: 1059ca8f29b6Schristos#endif 1060ca8f29b6Schristos fmovd %f0, %f4 1061ca8f29b6Schristos ldd [%o0], %f6 1062ca8f29b6Schristos inc 8, %o0 1063ca8f29b6Schristos ldd [%o0], %f8 1064ca8f29b6Schristos inc 8, %o0 1065ca8f29b6Schristos ldd [%o0], %f10 1066ca8f29b6Schristos inc 8, %o0 1067ca8f29b6Schristos ldd [%o0], %f12 1068ca8f29b6Schristos inc 8, %o0 1069ca8f29b6Schristos ldd [%o0], %f14 1070ca8f29b6Schristos inc 8, %o0 1071ca8f29b6Schristos 1072ca8f29b6Schristos cmp %o0, %o5 1073ca8f29b6Schristos bleu,a,pn %icc, 2f 1074ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 1075ca8f29b6Schristos membar #Sync 1076ca8f29b6Schristos2: 1077ca8f29b6Schristos inc BLOCK_SIZE, %o0 1078ca8f29b6Schristos3: 1079ca8f29b6Schristos faligndata %f4, %f6, %f32 1080ca8f29b6Schristos cmp %o0, %o5 1081ca8f29b6Schristos faligndata %f6, %f8, %f34 1082ca8f29b6Schristos dec BLOCK_SIZE, %o2 1083ca8f29b6Schristos faligndata %f8, %f10, %f36 1084ca8f29b6Schristos faligndata %f10, %f12, %f38 1085ca8f29b6Schristos faligndata %f12, %f14, %f40 1086ca8f29b6Schristos bleu,a,pn %icc, 2f 1087ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f48 1088ca8f29b6Schristos membar #Sync 1089ca8f29b6Schristos2: 1090ca8f29b6Schristos faligndata %f14, %f16, %f42 1091ca8f29b6Schristos inc BLOCK_SIZE, %o0 1092ca8f29b6Schristos faligndata %f16, %f18, %f44 1093ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1094ca8f29b6Schristos faligndata %f18, %f20, %f46 1095ca8f29b6Schristos 1096ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1097ca8f29b6Schristos 1098ca8f29b6Schristos faligndata %f20, %f22, %f32 1099ca8f29b6Schristos cmp %o0, %o5 1100ca8f29b6Schristos faligndata %f22, %f24, %f34 1101ca8f29b6Schristos dec BLOCK_SIZE, %o2 1102ca8f29b6Schristos faligndata %f24, %f26, %f36 1103ca8f29b6Schristos inc BLOCK_SIZE, %o1 1104ca8f29b6Schristos faligndata %f26, %f28, %f38 1105ca8f29b6Schristos faligndata %f28, %f30, %f40 1106ca8f29b6Schristos ble,a,pn %icc, 2f 1107ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f0 1108ca8f29b6Schristos membar #Sync 1109ca8f29b6Schristos2: 1110ca8f29b6Schristos faligndata %f30, %f48, %f42 1111ca8f29b6Schristos inc BLOCK_SIZE, %o0 1112ca8f29b6Schristos faligndata %f48, %f50, %f44 1113ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1114ca8f29b6Schristos faligndata %f50, %f52, %f46 1115ca8f29b6Schristos 1116ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1117ca8f29b6Schristos 1118ca8f29b6Schristos faligndata %f52, %f54, %f32 1119ca8f29b6Schristos cmp %o0, %o5 1120ca8f29b6Schristos faligndata %f54, %f56, %f34 1121ca8f29b6Schristos dec BLOCK_SIZE, %o2 1122ca8f29b6Schristos faligndata %f56, %f58, %f36 1123ca8f29b6Schristos faligndata %f58, %f60, %f38 1124ca8f29b6Schristos inc BLOCK_SIZE, %o1 1125ca8f29b6Schristos faligndata %f60, %f62, %f40 1126ca8f29b6Schristos bleu,a,pn %icc, 2f 1127ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 1128ca8f29b6Schristos membar #Sync 1129ca8f29b6Schristos2: 1130ca8f29b6Schristos faligndata %f62, %f0, %f42 1131ca8f29b6Schristos inc BLOCK_SIZE, %o0 1132ca8f29b6Schristos faligndata %f0, %f2, %f44 1133ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1134ca8f29b6Schristos faligndata %f2, %f4, %f46 1135ca8f29b6Schristos 1136ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1137ca8f29b6Schristos ba 3b 1138ca8f29b6Schristos inc BLOCK_SIZE, %o1 1139ca8f29b6Schristos 1140ca8f29b6Schristos !! 1141ca8f29b6Schristos !! Source at BLOCK_ALIGN+32 1142ca8f29b6Schristos !! 1143ca8f29b6Schristos !! We need to load 4 doubles by hand. 1144ca8f29b6Schristos !! 1145ca8f29b6SchristosL104: 1146ca8f29b6Schristos#ifdef RETURN_NAME 1147ca8f29b6Schristos sethi %hi(1f), %g1 1148ca8f29b6Schristos ba,pt %icc, 2f 1149ca8f29b6Schristos or %g1, %lo(1f), %g1 1150ca8f29b6Schristos1: 1151ca8f29b6Schristos .asciz "L104" 1152ca8f29b6Schristos .align 8 1153ca8f29b6Schristos2: 1154ca8f29b6Schristos#endif 1155ca8f29b6Schristos fmovd %f0, %f6 1156ca8f29b6Schristos ldd [%o0], %f8 1157ca8f29b6Schristos inc 8, %o0 1158ca8f29b6Schristos ldd [%o0], %f10 1159ca8f29b6Schristos inc 8, %o0 1160ca8f29b6Schristos ldd [%o0], %f12 1161ca8f29b6Schristos inc 8, %o0 1162ca8f29b6Schristos ldd [%o0], %f14 1163ca8f29b6Schristos inc 8, %o0 1164ca8f29b6Schristos 1165ca8f29b6Schristos cmp %o0, %o5 1166ca8f29b6Schristos bleu,a,pn %icc, 2f 1167ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 1168ca8f29b6Schristos membar #Sync 1169ca8f29b6Schristos2: 1170ca8f29b6Schristos inc BLOCK_SIZE, %o0 1171ca8f29b6Schristos3: 1172ca8f29b6Schristos faligndata %f6, %f8, %f32 1173ca8f29b6Schristos cmp %o0, %o5 1174ca8f29b6Schristos faligndata %f8, %f10, %f34 1175ca8f29b6Schristos dec BLOCK_SIZE, %o2 1176ca8f29b6Schristos faligndata %f10, %f12, %f36 1177ca8f29b6Schristos faligndata %f12, %f14, %f38 1178ca8f29b6Schristos bleu,a,pn %icc, 2f 1179ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f48 1180ca8f29b6Schristos membar #Sync 1181ca8f29b6Schristos2: 1182ca8f29b6Schristos faligndata %f14, %f16, %f40 1183ca8f29b6Schristos faligndata %f16, %f18, %f42 1184ca8f29b6Schristos inc BLOCK_SIZE, %o0 1185ca8f29b6Schristos faligndata %f18, %f20, %f44 1186ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1187ca8f29b6Schristos faligndata %f20, %f22, %f46 1188ca8f29b6Schristos 1189ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1190ca8f29b6Schristos 1191ca8f29b6Schristos faligndata %f22, %f24, %f32 1192ca8f29b6Schristos cmp %o0, %o5 1193ca8f29b6Schristos faligndata %f24, %f26, %f34 1194ca8f29b6Schristos faligndata %f26, %f28, %f36 1195ca8f29b6Schristos inc BLOCK_SIZE, %o1 1196ca8f29b6Schristos faligndata %f28, %f30, %f38 1197ca8f29b6Schristos bleu,a,pn %icc, 2f 1198ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f0 1199ca8f29b6Schristos membar #Sync 1200ca8f29b6Schristos2: 1201ca8f29b6Schristos faligndata %f30, %f48, %f40 1202ca8f29b6Schristos dec BLOCK_SIZE, %o2 1203ca8f29b6Schristos faligndata %f48, %f50, %f42 1204ca8f29b6Schristos inc BLOCK_SIZE, %o0 1205ca8f29b6Schristos faligndata %f50, %f52, %f44 1206ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1207ca8f29b6Schristos faligndata %f52, %f54, %f46 1208ca8f29b6Schristos 1209ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1210ca8f29b6Schristos 1211ca8f29b6Schristos faligndata %f54, %f56, %f32 1212ca8f29b6Schristos cmp %o0, %o5 1213ca8f29b6Schristos faligndata %f56, %f58, %f34 1214ca8f29b6Schristos faligndata %f58, %f60, %f36 1215ca8f29b6Schristos inc BLOCK_SIZE, %o1 1216ca8f29b6Schristos faligndata %f60, %f62, %f38 1217ca8f29b6Schristos bleu,a,pn %icc, 2f 1218ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 1219ca8f29b6Schristos membar #Sync 1220ca8f29b6Schristos2: 1221ca8f29b6Schristos faligndata %f62, %f0, %f40 1222ca8f29b6Schristos dec BLOCK_SIZE, %o2 1223ca8f29b6Schristos faligndata %f0, %f2, %f42 1224ca8f29b6Schristos inc BLOCK_SIZE, %o0 1225ca8f29b6Schristos faligndata %f2, %f4, %f44 1226ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1227ca8f29b6Schristos faligndata %f4, %f6, %f46 1228ca8f29b6Schristos 1229ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1230ca8f29b6Schristos ba 3b 1231ca8f29b6Schristos inc BLOCK_SIZE, %o1 1232ca8f29b6Schristos 1233ca8f29b6Schristos !! 1234ca8f29b6Schristos !! Source at BLOCK_ALIGN+40 1235ca8f29b6Schristos !! 1236ca8f29b6Schristos !! We need to load 3 doubles by hand. 1237ca8f29b6Schristos !! 1238ca8f29b6SchristosL105: 1239ca8f29b6Schristos#ifdef RETURN_NAME 1240ca8f29b6Schristos sethi %hi(1f), %g1 1241ca8f29b6Schristos ba,pt %icc, 2f 1242ca8f29b6Schristos or %g1, %lo(1f), %g1 1243ca8f29b6Schristos1: 1244ca8f29b6Schristos .asciz "L105" 1245ca8f29b6Schristos .align 8 1246ca8f29b6Schristos2: 1247ca8f29b6Schristos#endif 1248ca8f29b6Schristos fmovd %f0, %f8 1249ca8f29b6Schristos ldd [%o0], %f10 1250ca8f29b6Schristos inc 8, %o0 1251ca8f29b6Schristos ldd [%o0], %f12 1252ca8f29b6Schristos inc 8, %o0 1253ca8f29b6Schristos ldd [%o0], %f14 1254ca8f29b6Schristos inc 8, %o0 1255ca8f29b6Schristos 1256ca8f29b6Schristos cmp %o0, %o5 1257ca8f29b6Schristos bleu,a,pn %icc, 2f 1258ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 1259ca8f29b6Schristos membar #Sync 1260ca8f29b6Schristos2: 1261ca8f29b6Schristos inc BLOCK_SIZE, %o0 1262ca8f29b6Schristos3: 1263ca8f29b6Schristos faligndata %f8, %f10, %f32 1264ca8f29b6Schristos cmp %o0, %o5 1265ca8f29b6Schristos faligndata %f10, %f12, %f34 1266ca8f29b6Schristos faligndata %f12, %f14, %f36 1267ca8f29b6Schristos bleu,a,pn %icc, 2f 1268ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f48 1269ca8f29b6Schristos membar #Sync 1270ca8f29b6Schristos2: 1271ca8f29b6Schristos faligndata %f14, %f16, %f38 1272ca8f29b6Schristos dec BLOCK_SIZE, %o2 1273ca8f29b6Schristos faligndata %f16, %f18, %f40 1274ca8f29b6Schristos inc BLOCK_SIZE, %o0 1275ca8f29b6Schristos faligndata %f18, %f20, %f42 1276ca8f29b6Schristos faligndata %f20, %f22, %f44 1277ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1278ca8f29b6Schristos faligndata %f22, %f24, %f46 1279ca8f29b6Schristos 1280ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1281ca8f29b6Schristos 1282ca8f29b6Schristos faligndata %f24, %f26, %f32 1283ca8f29b6Schristos cmp %o0, %o5 1284ca8f29b6Schristos faligndata %f26, %f28, %f34 1285ca8f29b6Schristos dec BLOCK_SIZE, %o2 1286ca8f29b6Schristos faligndata %f28, %f30, %f36 1287ca8f29b6Schristos bleu,a,pn %icc, 2f 1288ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f0 1289ca8f29b6Schristos membar #Sync 1290ca8f29b6Schristos2: 1291ca8f29b6Schristos faligndata %f30, %f48, %f38 1292ca8f29b6Schristos inc BLOCK_SIZE, %o1 1293ca8f29b6Schristos faligndata %f48, %f50, %f40 1294ca8f29b6Schristos inc BLOCK_SIZE, %o0 1295ca8f29b6Schristos faligndata %f50, %f52, %f42 1296ca8f29b6Schristos faligndata %f52, %f54, %f44 1297ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1298ca8f29b6Schristos faligndata %f54, %f56, %f46 1299ca8f29b6Schristos 1300ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1301ca8f29b6Schristos 1302ca8f29b6Schristos faligndata %f56, %f58, %f32 1303ca8f29b6Schristos cmp %o0, %o5 1304ca8f29b6Schristos faligndata %f58, %f60, %f34 1305ca8f29b6Schristos dec BLOCK_SIZE, %o2 1306ca8f29b6Schristos faligndata %f60, %f62, %f36 1307ca8f29b6Schristos bleu,a,pn %icc, 2f 1308ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 1309ca8f29b6Schristos membar #Sync 1310ca8f29b6Schristos2: 1311ca8f29b6Schristos faligndata %f62, %f0, %f38 1312ca8f29b6Schristos inc BLOCK_SIZE, %o1 1313ca8f29b6Schristos faligndata %f0, %f2, %f40 1314ca8f29b6Schristos inc BLOCK_SIZE, %o0 1315ca8f29b6Schristos faligndata %f2, %f4, %f42 1316ca8f29b6Schristos faligndata %f4, %f6, %f44 1317ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1318ca8f29b6Schristos faligndata %f6, %f8, %f46 1319ca8f29b6Schristos 1320ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1321ca8f29b6Schristos ba 3b 1322ca8f29b6Schristos inc BLOCK_SIZE, %o1 1323ca8f29b6Schristos 1324ca8f29b6Schristos 1325ca8f29b6Schristos !! 1326ca8f29b6Schristos !! Source at BLOCK_ALIGN+48 1327ca8f29b6Schristos !! 1328ca8f29b6Schristos !! We need to load 2 doubles by hand. 1329ca8f29b6Schristos !! 1330ca8f29b6SchristosL106: 1331ca8f29b6Schristos#ifdef RETURN_NAME 1332ca8f29b6Schristos sethi %hi(1f), %g1 1333ca8f29b6Schristos ba,pt %icc, 2f 1334ca8f29b6Schristos or %g1, %lo(1f), %g1 1335ca8f29b6Schristos1: 1336ca8f29b6Schristos .asciz "L106" 1337ca8f29b6Schristos .align 8 1338ca8f29b6Schristos2: 1339ca8f29b6Schristos#endif 1340ca8f29b6Schristos fmovd %f0, %f10 1341ca8f29b6Schristos ldd [%o0], %f12 1342ca8f29b6Schristos inc 8, %o0 1343ca8f29b6Schristos ldd [%o0], %f14 1344ca8f29b6Schristos inc 8, %o0 1345ca8f29b6Schristos 1346ca8f29b6Schristos cmp %o0, %o5 1347ca8f29b6Schristos bleu,a,pn %icc, 2f 1348ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 1349ca8f29b6Schristos membar #Sync 1350ca8f29b6Schristos2: 1351ca8f29b6Schristos inc BLOCK_SIZE, %o0 1352ca8f29b6Schristos3: 1353ca8f29b6Schristos faligndata %f10, %f12, %f32 1354ca8f29b6Schristos cmp %o0, %o5 1355ca8f29b6Schristos faligndata %f12, %f14, %f34 1356ca8f29b6Schristos bleu,a,pn %icc, 2f 1357ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f48 1358ca8f29b6Schristos membar #Sync 1359ca8f29b6Schristos2: 1360ca8f29b6Schristos faligndata %f14, %f16, %f36 1361ca8f29b6Schristos dec BLOCK_SIZE, %o2 1362ca8f29b6Schristos faligndata %f16, %f18, %f38 1363ca8f29b6Schristos inc BLOCK_SIZE, %o0 1364ca8f29b6Schristos faligndata %f18, %f20, %f40 1365ca8f29b6Schristos faligndata %f20, %f22, %f42 1366ca8f29b6Schristos faligndata %f22, %f24, %f44 1367ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1368ca8f29b6Schristos faligndata %f24, %f26, %f46 1369ca8f29b6Schristos 1370ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1371ca8f29b6Schristos 1372ca8f29b6Schristos faligndata %f26, %f28, %f32 1373ca8f29b6Schristos cmp %o0, %o5 1374ca8f29b6Schristos faligndata %f28, %f30, %f34 1375ca8f29b6Schristos bleu,a,pn %icc, 2f 1376ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f0 1377ca8f29b6Schristos membar #Sync 1378ca8f29b6Schristos2: 1379ca8f29b6Schristos faligndata %f30, %f48, %f36 1380ca8f29b6Schristos dec BLOCK_SIZE, %o2 1381ca8f29b6Schristos faligndata %f48, %f50, %f38 1382ca8f29b6Schristos inc BLOCK_SIZE, %o1 1383ca8f29b6Schristos faligndata %f50, %f52, %f40 1384ca8f29b6Schristos faligndata %f52, %f54, %f42 1385ca8f29b6Schristos inc BLOCK_SIZE, %o0 1386ca8f29b6Schristos faligndata %f54, %f56, %f44 1387ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1388ca8f29b6Schristos faligndata %f56, %f58, %f46 1389ca8f29b6Schristos 1390ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1391ca8f29b6Schristos 1392ca8f29b6Schristos faligndata %f58, %f60, %f32 1393ca8f29b6Schristos cmp %o0, %o5 1394ca8f29b6Schristos faligndata %f60, %f62, %f34 1395ca8f29b6Schristos bleu,a,pn %icc, 2f 1396ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 1397ca8f29b6Schristos membar #Sync 1398ca8f29b6Schristos2: 1399ca8f29b6Schristos faligndata %f62, %f0, %f36 1400ca8f29b6Schristos dec BLOCK_SIZE, %o2 1401ca8f29b6Schristos faligndata %f0, %f2, %f38 1402ca8f29b6Schristos inc BLOCK_SIZE, %o1 1403ca8f29b6Schristos faligndata %f2, %f4, %f40 1404ca8f29b6Schristos faligndata %f4, %f6, %f42 1405ca8f29b6Schristos inc BLOCK_SIZE, %o0 1406ca8f29b6Schristos faligndata %f6, %f8, %f44 1407ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1408ca8f29b6Schristos faligndata %f8, %f10, %f46 1409ca8f29b6Schristos 1410ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1411ca8f29b6Schristos ba 3b 1412ca8f29b6Schristos inc BLOCK_SIZE, %o1 1413ca8f29b6Schristos 1414ca8f29b6Schristos 1415ca8f29b6Schristos !! 1416ca8f29b6Schristos !! Source at BLOCK_ALIGN+56 1417ca8f29b6Schristos !! 1418ca8f29b6Schristos !! We need to load 1 double by hand. 1419ca8f29b6Schristos !! 1420ca8f29b6SchristosL107: 1421ca8f29b6Schristos#ifdef RETURN_NAME 1422ca8f29b6Schristos sethi %hi(1f), %g1 1423ca8f29b6Schristos ba,pt %icc, 2f 1424ca8f29b6Schristos or %g1, %lo(1f), %g1 1425ca8f29b6Schristos1: 1426ca8f29b6Schristos .asciz "L107" 1427ca8f29b6Schristos .align 8 1428ca8f29b6Schristos2: 1429ca8f29b6Schristos#endif 1430ca8f29b6Schristos fmovd %f0, %f12 1431ca8f29b6Schristos ldd [%o0], %f14 1432ca8f29b6Schristos inc 8, %o0 1433ca8f29b6Schristos 1434ca8f29b6Schristos cmp %o0, %o5 1435ca8f29b6Schristos bleu,a,pn %icc, 2f 1436ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 1437ca8f29b6Schristos membar #Sync 1438ca8f29b6Schristos2: 1439ca8f29b6Schristos inc BLOCK_SIZE, %o0 1440ca8f29b6Schristos3: 1441ca8f29b6Schristos faligndata %f12, %f14, %f32 1442ca8f29b6Schristos cmp %o0, %o5 1443ca8f29b6Schristos bleu,a,pn %icc, 2f 1444ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f48 1445ca8f29b6Schristos membar #Sync 1446ca8f29b6Schristos2: 1447ca8f29b6Schristos faligndata %f14, %f16, %f34 1448ca8f29b6Schristos dec BLOCK_SIZE, %o2 1449ca8f29b6Schristos faligndata %f16, %f18, %f36 1450ca8f29b6Schristos inc BLOCK_SIZE, %o0 1451ca8f29b6Schristos faligndata %f18, %f20, %f38 1452ca8f29b6Schristos faligndata %f20, %f22, %f40 1453ca8f29b6Schristos faligndata %f22, %f24, %f42 1454ca8f29b6Schristos faligndata %f24, %f26, %f44 1455ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1456ca8f29b6Schristos faligndata %f26, %f28, %f46 1457ca8f29b6Schristos 1458ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1459ca8f29b6Schristos 1460ca8f29b6Schristos faligndata %f28, %f30, %f32 1461ca8f29b6Schristos cmp %o0, %o5 1462ca8f29b6Schristos bleu,a,pn %icc, 2f 1463ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f0 1464ca8f29b6Schristos membar #Sync 1465ca8f29b6Schristos2: 1466ca8f29b6Schristos faligndata %f30, %f48, %f34 1467ca8f29b6Schristos dec BLOCK_SIZE, %o2 1468ca8f29b6Schristos faligndata %f48, %f50, %f36 1469ca8f29b6Schristos inc BLOCK_SIZE, %o1 1470ca8f29b6Schristos faligndata %f50, %f52, %f38 1471ca8f29b6Schristos faligndata %f52, %f54, %f40 1472ca8f29b6Schristos inc BLOCK_SIZE, %o0 1473ca8f29b6Schristos faligndata %f54, %f56, %f42 1474ca8f29b6Schristos faligndata %f56, %f58, %f44 1475ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1476ca8f29b6Schristos faligndata %f58, %f60, %f46 1477ca8f29b6Schristos 1478ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1479ca8f29b6Schristos 1480ca8f29b6Schristos faligndata %f60, %f62, %f32 1481ca8f29b6Schristos cmp %o0, %o5 1482ca8f29b6Schristos bleu,a,pn %icc, 2f 1483ca8f29b6Schristos ldda [%o0] ASI_BLK_P, %f16 1484ca8f29b6Schristos membar #Sync 1485ca8f29b6Schristos2: 1486ca8f29b6Schristos faligndata %f62, %f0, %f34 1487ca8f29b6Schristos dec BLOCK_SIZE, %o2 1488ca8f29b6Schristos faligndata %f0, %f2, %f36 1489ca8f29b6Schristos inc BLOCK_SIZE, %o1 1490ca8f29b6Schristos faligndata %f2, %f4, %f38 1491ca8f29b6Schristos faligndata %f4, %f6, %f40 1492ca8f29b6Schristos inc BLOCK_SIZE, %o0 1493ca8f29b6Schristos faligndata %f6, %f8, %f42 1494ca8f29b6Schristos faligndata %f8, %f10, %f44 1495ca8f29b6Schristos 1496ca8f29b6Schristos brlez,pn %o2, Lmemcpy_blockdone 1497ca8f29b6Schristos faligndata %f10, %f12, %f46 1498ca8f29b6Schristos 1499ca8f29b6Schristos stda %f32, [%o1] ASI_STORE 1500ca8f29b6Schristos ba 3b 1501ca8f29b6Schristos inc BLOCK_SIZE, %o1 1502ca8f29b6Schristos 1503ca8f29b6SchristosLmemcpy_blockdone: 1504ca8f29b6Schristos inc BLOCK_SIZE, %o2 ! Fixup our overcommit 1505ca8f29b6Schristos membar #Sync ! Finish any pending loads 1506ca8f29b6Schristos#define FINISH_REG(f) \ 1507ca8f29b6Schristos deccc 8, %o2; \ 1508ca8f29b6Schristos bl,a Lmemcpy_blockfinish; \ 1509ca8f29b6Schristos fmovd f, %f48; \ 1510ca8f29b6Schristos std f, [%o1]; \ 1511ca8f29b6Schristos inc 8, %o1 1512ca8f29b6Schristos 1513ca8f29b6Schristos FINISH_REG(%f32) 1514ca8f29b6Schristos FINISH_REG(%f34) 1515ca8f29b6Schristos FINISH_REG(%f36) 1516ca8f29b6Schristos FINISH_REG(%f38) 1517ca8f29b6Schristos FINISH_REG(%f40) 1518ca8f29b6Schristos FINISH_REG(%f42) 1519ca8f29b6Schristos FINISH_REG(%f44) 1520ca8f29b6Schristos FINISH_REG(%f46) 1521ca8f29b6Schristos FINISH_REG(%f48) 1522ca8f29b6Schristos#undef FINISH_REG 1523ca8f29b6Schristos !! 1524ca8f29b6Schristos !! The low 3 bits have the sub-word bits needed to be 1525ca8f29b6Schristos !! stored [because (x-8)&0x7 == x]. 1526ca8f29b6Schristos !! 1527ca8f29b6SchristosLmemcpy_blockfinish: 1528ca8f29b6Schristos brz,pn %o2, 2f ! 100% complete? 1529ca8f29b6Schristos fmovd %f48, %f4 1530ca8f29b6Schristos cmp %o2, 8 ! Exactly 8 bytes? 1531ca8f29b6Schristos bz,a,pn CCCR, 2f 1532ca8f29b6Schristos std %f4, [%o1] 1533ca8f29b6Schristos 1534ca8f29b6Schristos btst 4, %o2 ! Word store? 1535ca8f29b6Schristos bz CCCR, 1f 1536ca8f29b6Schristos nop 1537ca8f29b6Schristos st %f4, [%o1] 1538ca8f29b6Schristos inc 4, %o1 1539ca8f29b6Schristos1: 1540ca8f29b6Schristos btst 2, %o2 1541ca8f29b6Schristos fzero %f0 1542ca8f29b6Schristos bz 1f 1543ca8f29b6Schristos 1544ca8f29b6Schristos mov -6, %o4 1545ca8f29b6Schristos alignaddr %o1, %o4, %g0 1546ca8f29b6Schristos 1547ca8f29b6Schristos faligndata %f0, %f4, %f8 1548ca8f29b6Schristos 1549ca8f29b6Schristos stda %f8, [%o1] ASI_FL16_P ! Store short 1550ca8f29b6Schristos inc 2, %o1 1551ca8f29b6Schristos1: 1552ca8f29b6Schristos btst 1, %o2 ! Byte aligned? 1553ca8f29b6Schristos bz 2f 1554ca8f29b6Schristos 1555ca8f29b6Schristos mov -7, %o0 ! Calculate dest - 7 1556ca8f29b6Schristos alignaddr %o1, %o0, %g0 ! Calculate shift mask and dest. 1557ca8f29b6Schristos 1558ca8f29b6Schristos faligndata %f0, %f4, %f8 ! Move 1st byte to low part of f8 1559ca8f29b6Schristos 1560ca8f29b6Schristos stda %f8, [%o1] ASI_FL8_P ! Store 1st byte 1561ca8f29b6Schristos inc 1, %o1 ! Update address 1562ca8f29b6Schristos2: 1563ca8f29b6Schristos membar #Sync 1564ca8f29b6Schristos#if 0 1565ca8f29b6Schristos !! 1566ca8f29b6Schristos !! verify copy success. 1567ca8f29b6Schristos !! 1568ca8f29b6Schristos 1569ca8f29b6Schristos mov %i0, %o2 1570ca8f29b6Schristos mov %i1, %o4 1571ca8f29b6Schristos mov %i2, %l4 1572ca8f29b6Schristos0: 1573ca8f29b6Schristos ldub [%o2], %o1 1574ca8f29b6Schristos inc %o2 1575ca8f29b6Schristos ldub [%o4], %o3 1576ca8f29b6Schristos inc %o4 1577ca8f29b6Schristos cmp %o3, %o1 1578ca8f29b6Schristos bnz 1f 1579ca8f29b6Schristos dec %l4 1580ca8f29b6Schristos brnz %l4, 0b 1581ca8f29b6Schristos nop 1582ca8f29b6Schristos ba 2f 1583ca8f29b6Schristos nop 1584ca8f29b6Schristos 1585ca8f29b6Schristos1: 1586ca8f29b6Schristos set block_disable, %o0 1587ca8f29b6Schristos stx %o0, [%o0] 1588ca8f29b6Schristos 1589ca8f29b6Schristos set 0f, %o0 1590ca8f29b6Schristos call prom_printf 1591ca8f29b6Schristos sub %i2, %l4, %o5 1592ca8f29b6Schristos set 1f, %o0 1593ca8f29b6Schristos mov %i0, %o2 1594ca8f29b6Schristos mov %i1, %o1 1595ca8f29b6Schristos call prom_printf 1596ca8f29b6Schristos mov %i2, %o3 1597ca8f29b6Schristos ta 1 1598ca8f29b6Schristos .data 1599ca8f29b6Schristos _ALIGN 1600ca8f29b6Schristos0: .asciz "block memcpy failed: %x@%p != %x@%p byte %d\r\n" 1601ca8f29b6Schristos1: .asciz "memcpy(%p, %p, %lx)\r\n" 1602ca8f29b6Schristos _ALIGN 1603ca8f29b6Schristos .text 1604ca8f29b6Schristos2: 1605ca8f29b6Schristos#endif 1606ca8f29b6Schristos#if defined(_KERNEL) && !defined(_RUMPKERNEL) 1607ca8f29b6Schristos 1608ca8f29b6Schristos/* 1609ca8f29b6Schristos * Weve saved our possible fpstate, now disable the fpu 1610ca8f29b6Schristos * and continue with life. 1611ca8f29b6Schristos */ 1612ca8f29b6Schristos RESTORE_FPU 1613ca8f29b6Schristos ret 1614ca8f29b6Schristos restore %g1, 0, %o0 ! Return DEST for memcpy 1615ca8f29b6Schristos#endif 1616ca8f29b6Schristos retl 1617ca8f29b6Schristos mov %g1, %o0 1618ca8f29b6Schristos/* 1619ca8f29b6Schristos * Use block_disable to turn off block insns for 1620ca8f29b6Schristos * memcpy/memset 1621ca8f29b6Schristos */ 1622ca8f29b6Schristos .data 1623ca8f29b6Schristos .align 8 1624ca8f29b6Schristos .globl block_disable 1625ca8f29b6Schristosblock_disable: .xword 1 1626ca8f29b6Schristos .text 1627ca8f29b6Schristos#endif /* USE_BLOCK_STORE_LOAD */ 1628