1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */ 2478b8fecSSam Ravnborg/* NGmemcpy.S: Niagara optimized memcpy. 3478b8fecSSam Ravnborg * 4478b8fecSSam Ravnborg * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net) 5478b8fecSSam Ravnborg */ 6478b8fecSSam Ravnborg 7478b8fecSSam Ravnborg#ifdef __KERNEL__ 87ae3aaf5SDavid S. Miller#include <linux/linkage.h> 9478b8fecSSam Ravnborg#include <asm/asi.h> 10478b8fecSSam Ravnborg#include <asm/thread_info.h> 11478b8fecSSam Ravnborg#define GLOBAL_SPARE %g7 12478b8fecSSam Ravnborg#define RESTORE_ASI(TMP) \ 13*a5ad8378SArnd Bergmann wr %g0, ASI_AIUS, %asi 14478b8fecSSam Ravnborg#else 15478b8fecSSam Ravnborg#define GLOBAL_SPARE %g5 16478b8fecSSam Ravnborg#define RESTORE_ASI(TMP) \ 17478b8fecSSam Ravnborg wr %g0, ASI_PNF, %asi 18478b8fecSSam Ravnborg#endif 19478b8fecSSam Ravnborg 20478b8fecSSam Ravnborg#ifdef __sparc_v9__ 21478b8fecSSam Ravnborg#define SAVE_AMOUNT 128 22478b8fecSSam Ravnborg#else 23478b8fecSSam Ravnborg#define SAVE_AMOUNT 64 24478b8fecSSam Ravnborg#endif 25478b8fecSSam Ravnborg 26478b8fecSSam Ravnborg#ifndef STORE_ASI 27478b8fecSSam Ravnborg#define STORE_ASI ASI_BLK_INIT_QUAD_LDD_P 28478b8fecSSam Ravnborg#endif 29478b8fecSSam Ravnborg 30478b8fecSSam Ravnborg#ifndef EX_LD 317ae3aaf5SDavid S. Miller#define EX_LD(x,y) x 32478b8fecSSam Ravnborg#endif 33478b8fecSSam Ravnborg 34478b8fecSSam Ravnborg#ifndef EX_ST 357ae3aaf5SDavid S. Miller#define EX_ST(x,y) x 36478b8fecSSam Ravnborg#endif 37478b8fecSSam Ravnborg 38478b8fecSSam Ravnborg#ifndef LOAD 39478b8fecSSam Ravnborg#ifndef MEMCPY_DEBUG 40478b8fecSSam Ravnborg#define LOAD(type,addr,dest) type [addr], dest 41478b8fecSSam Ravnborg#else 42478b8fecSSam Ravnborg#define LOAD(type,addr,dest) type##a [addr] 0x80, dest 43478b8fecSSam Ravnborg#endif 44478b8fecSSam Ravnborg#endif 45478b8fecSSam Ravnborg 46478b8fecSSam Ravnborg#ifndef LOAD_TWIN 47478b8fecSSam Ravnborg#define LOAD_TWIN(addr_reg,dest0,dest1) \ 48478b8fecSSam Ravnborg ldda [addr_reg] ASI_BLK_INIT_QUAD_LDD_P, dest0 49478b8fecSSam Ravnborg#endif 50478b8fecSSam Ravnborg 51478b8fecSSam Ravnborg#ifndef STORE 52478b8fecSSam Ravnborg#define STORE(type,src,addr) type src, [addr] 53478b8fecSSam Ravnborg#endif 54478b8fecSSam Ravnborg 55478b8fecSSam Ravnborg#ifndef STORE_INIT 56478b8fecSSam Ravnborg#ifndef SIMULATE_NIAGARA_ON_NON_NIAGARA 57478b8fecSSam Ravnborg#define STORE_INIT(src,addr) stxa src, [addr] %asi 58478b8fecSSam Ravnborg#else 59478b8fecSSam Ravnborg#define STORE_INIT(src,addr) stx src, [addr + 0x00] 60478b8fecSSam Ravnborg#endif 61478b8fecSSam Ravnborg#endif 62478b8fecSSam Ravnborg 63478b8fecSSam Ravnborg#ifndef FUNC_NAME 64478b8fecSSam Ravnborg#define FUNC_NAME NGmemcpy 65478b8fecSSam Ravnborg#endif 66478b8fecSSam Ravnborg 67478b8fecSSam Ravnborg#ifndef PREAMBLE 68478b8fecSSam Ravnborg#define PREAMBLE 69478b8fecSSam Ravnborg#endif 70478b8fecSSam Ravnborg 71478b8fecSSam Ravnborg#ifndef XCC 72478b8fecSSam Ravnborg#define XCC xcc 73478b8fecSSam Ravnborg#endif 74478b8fecSSam Ravnborg 75478b8fecSSam Ravnborg .register %g2,#scratch 76478b8fecSSam Ravnborg .register %g3,#scratch 77478b8fecSSam Ravnborg 78478b8fecSSam Ravnborg .text 797ae3aaf5SDavid S. Miller#ifndef EX_RETVAL 807ae3aaf5SDavid S. Miller#define EX_RETVAL(x) x 817ae3aaf5SDavid S. Miller__restore_asi: 827ae3aaf5SDavid S. Miller ret 837ae3aaf5SDavid S. Miller wr %g0, ASI_AIUS, %asi 847ae3aaf5SDavid S. Miller restore 857ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_plus_i4_plus_1) 867ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 877ae3aaf5SDavid S. Miller add %i2, %i5, %i0 887ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_plus_i4_plus_1) 897ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_plus_g1) 907ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 917ae3aaf5SDavid S. Miller add %i2, %g1, %i0 927ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_plus_g1) 937ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_plus_g1_minus_8) 947ae3aaf5SDavid S. Miller sub %g1, 8, %g1 957ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 967ae3aaf5SDavid S. Miller add %i2, %g1, %i0 977ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_plus_g1_minus_8) 987ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_plus_g1_minus_16) 997ae3aaf5SDavid S. Miller sub %g1, 16, %g1 1007ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 1017ae3aaf5SDavid S. Miller add %i2, %g1, %i0 1027ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_plus_g1_minus_16) 1037ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_plus_g1_minus_24) 1047ae3aaf5SDavid S. Miller sub %g1, 24, %g1 1057ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 1067ae3aaf5SDavid S. Miller add %i2, %g1, %i0 1077ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_plus_g1_minus_24) 1087ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_plus_g1_minus_32) 1097ae3aaf5SDavid S. Miller sub %g1, 32, %g1 1107ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 1117ae3aaf5SDavid S. Miller add %i2, %g1, %i0 1127ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_plus_g1_minus_32) 1137ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_plus_g1_minus_40) 1147ae3aaf5SDavid S. Miller sub %g1, 40, %g1 1157ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 1167ae3aaf5SDavid S. Miller add %i2, %g1, %i0 1177ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_plus_g1_minus_40) 1187ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_plus_g1_minus_48) 1197ae3aaf5SDavid S. Miller sub %g1, 48, %g1 1207ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 1217ae3aaf5SDavid S. Miller add %i2, %g1, %i0 1227ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_plus_g1_minus_48) 1237ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_plus_g1_minus_56) 1247ae3aaf5SDavid S. Miller sub %g1, 56, %g1 1257ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 1267ae3aaf5SDavid S. Miller add %i2, %g1, %i0 1277ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_plus_g1_minus_56) 1287ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_plus_i4) 1297ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 1307ae3aaf5SDavid S. Miller add %i2, %i4, %i0 1317ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_plus_i4) 1327ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_plus_i4_minus_8) 1337ae3aaf5SDavid S. Miller sub %i4, 8, %i4 1347ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 1357ae3aaf5SDavid S. Miller add %i2, %i4, %i0 1367ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_plus_i4_minus_8) 1377ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_plus_8) 1387ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 1397ae3aaf5SDavid S. Miller add %i2, 8, %i0 1407ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_plus_8) 1417ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_plus_4) 1427ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 1437ae3aaf5SDavid S. Miller add %i2, 4, %i0 1447ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_plus_4) 1457ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_plus_1) 1467ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 1477ae3aaf5SDavid S. Miller add %i2, 1, %i0 1487ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_plus_1) 1497ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_plus_g1_plus_1) 1507ae3aaf5SDavid S. Miller add %g1, 1, %g1 1517ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 1527ae3aaf5SDavid S. Miller add %i2, %g1, %i0 1537ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_plus_g1_plus_1) 1547ae3aaf5SDavid S. MillerENTRY(NG_ret_i2) 1557ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 1567ae3aaf5SDavid S. Miller mov %i2, %i0 1577ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2) 1587ae3aaf5SDavid S. MillerENTRY(NG_ret_i2_and_7_plus_i4) 1597ae3aaf5SDavid S. Miller and %i2, 7, %i2 1607ae3aaf5SDavid S. Miller ba,pt %xcc, __restore_asi 1617ae3aaf5SDavid S. Miller add %i2, %i4, %i0 1627ae3aaf5SDavid S. MillerENDPROC(NG_ret_i2_and_7_plus_i4) 1637ae3aaf5SDavid S. Miller#endif 1647ae3aaf5SDavid S. Miller 165478b8fecSSam Ravnborg .align 64 166478b8fecSSam Ravnborg 167478b8fecSSam Ravnborg .globl FUNC_NAME 168478b8fecSSam Ravnborg .type FUNC_NAME,#function 169478b8fecSSam RavnborgFUNC_NAME: /* %i0=dst, %i1=src, %i2=len */ 170478b8fecSSam Ravnborg PREAMBLE 171478b8fecSSam Ravnborg save %sp, -SAVE_AMOUNT, %sp 172478b8fecSSam Ravnborg srlx %i2, 31, %g2 173478b8fecSSam Ravnborg cmp %g2, 0 174478b8fecSSam Ravnborg tne %xcc, 5 175478b8fecSSam Ravnborg mov %i0, %o0 176478b8fecSSam Ravnborg cmp %i2, 0 177478b8fecSSam Ravnborg be,pn %XCC, 85f 178478b8fecSSam Ravnborg or %o0, %i1, %i3 179478b8fecSSam Ravnborg cmp %i2, 16 180478b8fecSSam Ravnborg blu,a,pn %XCC, 80f 181478b8fecSSam Ravnborg or %i3, %i2, %i3 182478b8fecSSam Ravnborg 183478b8fecSSam Ravnborg /* 2 blocks (128 bytes) is the minimum we can do the block 184478b8fecSSam Ravnborg * copy with. We need to ensure that we'll iterate at least 185478b8fecSSam Ravnborg * once in the block copy loop. At worst we'll need to align 186478b8fecSSam Ravnborg * the destination to a 64-byte boundary which can chew up 187478b8fecSSam Ravnborg * to (64 - 1) bytes from the length before we perform the 188478b8fecSSam Ravnborg * block copy loop. 189478b8fecSSam Ravnborg */ 190478b8fecSSam Ravnborg cmp %i2, (2 * 64) 191478b8fecSSam Ravnborg blu,pt %XCC, 70f 192478b8fecSSam Ravnborg andcc %i3, 0x7, %g0 193478b8fecSSam Ravnborg 194478b8fecSSam Ravnborg /* %o0: dst 195478b8fecSSam Ravnborg * %i1: src 196478b8fecSSam Ravnborg * %i2: len (known to be >= 128) 197478b8fecSSam Ravnborg * 198478b8fecSSam Ravnborg * The block copy loops will use %i4/%i5,%g2/%g3 as 199478b8fecSSam Ravnborg * temporaries while copying the data. 200478b8fecSSam Ravnborg */ 201478b8fecSSam Ravnborg 202478b8fecSSam Ravnborg LOAD(prefetch, %i1, #one_read) 203478b8fecSSam Ravnborg wr %g0, STORE_ASI, %asi 204478b8fecSSam Ravnborg 205478b8fecSSam Ravnborg /* Align destination on 64-byte boundary. */ 206478b8fecSSam Ravnborg andcc %o0, (64 - 1), %i4 207478b8fecSSam Ravnborg be,pt %XCC, 2f 208478b8fecSSam Ravnborg sub %i4, 64, %i4 209478b8fecSSam Ravnborg sub %g0, %i4, %i4 ! bytes to align dst 210478b8fecSSam Ravnborg sub %i2, %i4, %i2 211478b8fecSSam Ravnborg1: subcc %i4, 1, %i4 2127ae3aaf5SDavid S. Miller EX_LD(LOAD(ldub, %i1, %g1), NG_ret_i2_plus_i4_plus_1) 2137ae3aaf5SDavid S. Miller EX_ST(STORE(stb, %g1, %o0), NG_ret_i2_plus_i4_plus_1) 214478b8fecSSam Ravnborg add %i1, 1, %i1 215478b8fecSSam Ravnborg bne,pt %XCC, 1b 216478b8fecSSam Ravnborg add %o0, 1, %o0 217478b8fecSSam Ravnborg 218478b8fecSSam Ravnborg /* If the source is on a 16-byte boundary we can do 219478b8fecSSam Ravnborg * the direct block copy loop. If it is 8-byte aligned 220478b8fecSSam Ravnborg * we can do the 16-byte loads offset by -8 bytes and the 221478b8fecSSam Ravnborg * init stores offset by one register. 222478b8fecSSam Ravnborg * 223478b8fecSSam Ravnborg * If the source is not even 8-byte aligned, we need to do 224478b8fecSSam Ravnborg * shifting and masking (basically integer faligndata). 225478b8fecSSam Ravnborg * 226478b8fecSSam Ravnborg * The careful bit with init stores is that if we store 227478b8fecSSam Ravnborg * to any part of the cache line we have to store the whole 228478b8fecSSam Ravnborg * cacheline else we can end up with corrupt L2 cache line 229478b8fecSSam Ravnborg * contents. Since the loop works on 64-bytes of 64-byte 230478b8fecSSam Ravnborg * aligned store data at a time, this is easy to ensure. 231478b8fecSSam Ravnborg */ 232478b8fecSSam Ravnborg2: 233478b8fecSSam Ravnborg andcc %i1, (16 - 1), %i4 234478b8fecSSam Ravnborg andn %i2, (64 - 1), %g1 ! block copy loop iterator 235478b8fecSSam Ravnborg be,pt %XCC, 50f 236478b8fecSSam Ravnborg sub %i2, %g1, %i2 ! final sub-block copy bytes 237478b8fecSSam Ravnborg 238478b8fecSSam Ravnborg cmp %i4, 8 239478b8fecSSam Ravnborg be,pt %XCC, 10f 240478b8fecSSam Ravnborg sub %i1, %i4, %i1 241478b8fecSSam Ravnborg 242478b8fecSSam Ravnborg /* Neither 8-byte nor 16-byte aligned, shift and mask. */ 243478b8fecSSam Ravnborg and %i4, 0x7, GLOBAL_SPARE 244478b8fecSSam Ravnborg sll GLOBAL_SPARE, 3, GLOBAL_SPARE 245478b8fecSSam Ravnborg mov 64, %i5 2467ae3aaf5SDavid S. Miller EX_LD(LOAD_TWIN(%i1, %g2, %g3), NG_ret_i2_plus_g1) 247478b8fecSSam Ravnborg sub %i5, GLOBAL_SPARE, %i5 248478b8fecSSam Ravnborg mov 16, %o4 249478b8fecSSam Ravnborg mov 32, %o5 250478b8fecSSam Ravnborg mov 48, %o7 251478b8fecSSam Ravnborg mov 64, %i3 252478b8fecSSam Ravnborg 253478b8fecSSam Ravnborg bg,pn %XCC, 9f 254478b8fecSSam Ravnborg nop 255478b8fecSSam Ravnborg 256478b8fecSSam Ravnborg#define MIX_THREE_WORDS(WORD1, WORD2, WORD3, PRE_SHIFT, POST_SHIFT, TMP) \ 257478b8fecSSam Ravnborg sllx WORD1, POST_SHIFT, WORD1; \ 258478b8fecSSam Ravnborg srlx WORD2, PRE_SHIFT, TMP; \ 259478b8fecSSam Ravnborg sllx WORD2, POST_SHIFT, WORD2; \ 260478b8fecSSam Ravnborg or WORD1, TMP, WORD1; \ 261478b8fecSSam Ravnborg srlx WORD3, PRE_SHIFT, TMP; \ 262478b8fecSSam Ravnborg or WORD2, TMP, WORD2; 263478b8fecSSam Ravnborg 2647ae3aaf5SDavid S. Miller8: EX_LD(LOAD_TWIN(%i1 + %o4, %o2, %o3), NG_ret_i2_plus_g1) 265478b8fecSSam Ravnborg MIX_THREE_WORDS(%g2, %g3, %o2, %i5, GLOBAL_SPARE, %o1) 266478b8fecSSam Ravnborg LOAD(prefetch, %i1 + %i3, #one_read) 267478b8fecSSam Ravnborg 2687ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%g2, %o0 + 0x00), NG_ret_i2_plus_g1) 2697ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%g3, %o0 + 0x08), NG_ret_i2_plus_g1_minus_8) 270478b8fecSSam Ravnborg 2717ae3aaf5SDavid S. Miller EX_LD(LOAD_TWIN(%i1 + %o5, %g2, %g3), NG_ret_i2_plus_g1_minus_16) 272478b8fecSSam Ravnborg MIX_THREE_WORDS(%o2, %o3, %g2, %i5, GLOBAL_SPARE, %o1) 273478b8fecSSam Ravnborg 2747ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o2, %o0 + 0x10), NG_ret_i2_plus_g1_minus_16) 2757ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o3, %o0 + 0x18), NG_ret_i2_plus_g1_minus_24) 276478b8fecSSam Ravnborg 2777ae3aaf5SDavid S. Miller EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3), NG_ret_i2_plus_g1_minus_32) 278478b8fecSSam Ravnborg MIX_THREE_WORDS(%g2, %g3, %o2, %i5, GLOBAL_SPARE, %o1) 279478b8fecSSam Ravnborg 2807ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%g2, %o0 + 0x20), NG_ret_i2_plus_g1_minus_32) 2817ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%g3, %o0 + 0x28), NG_ret_i2_plus_g1_minus_40) 282478b8fecSSam Ravnborg 2837ae3aaf5SDavid S. Miller EX_LD(LOAD_TWIN(%i1 + %i3, %g2, %g3), NG_ret_i2_plus_g1_minus_48) 284478b8fecSSam Ravnborg add %i1, 64, %i1 285478b8fecSSam Ravnborg MIX_THREE_WORDS(%o2, %o3, %g2, %i5, GLOBAL_SPARE, %o1) 286478b8fecSSam Ravnborg 2877ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o2, %o0 + 0x30), NG_ret_i2_plus_g1_minus_48) 2887ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o3, %o0 + 0x38), NG_ret_i2_plus_g1_minus_56) 289478b8fecSSam Ravnborg 290478b8fecSSam Ravnborg subcc %g1, 64, %g1 291478b8fecSSam Ravnborg bne,pt %XCC, 8b 292478b8fecSSam Ravnborg add %o0, 64, %o0 293478b8fecSSam Ravnborg 294478b8fecSSam Ravnborg ba,pt %XCC, 60f 295478b8fecSSam Ravnborg add %i1, %i4, %i1 296478b8fecSSam Ravnborg 2977ae3aaf5SDavid S. Miller9: EX_LD(LOAD_TWIN(%i1 + %o4, %o2, %o3), NG_ret_i2_plus_g1) 298478b8fecSSam Ravnborg MIX_THREE_WORDS(%g3, %o2, %o3, %i5, GLOBAL_SPARE, %o1) 299478b8fecSSam Ravnborg LOAD(prefetch, %i1 + %i3, #one_read) 300478b8fecSSam Ravnborg 3017ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%g3, %o0 + 0x00), NG_ret_i2_plus_g1) 3027ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o2, %o0 + 0x08), NG_ret_i2_plus_g1_minus_8) 303478b8fecSSam Ravnborg 3047ae3aaf5SDavid S. Miller EX_LD(LOAD_TWIN(%i1 + %o5, %g2, %g3), NG_ret_i2_plus_g1_minus_16) 305478b8fecSSam Ravnborg MIX_THREE_WORDS(%o3, %g2, %g3, %i5, GLOBAL_SPARE, %o1) 306478b8fecSSam Ravnborg 3077ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o3, %o0 + 0x10), NG_ret_i2_plus_g1_minus_16) 3087ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%g2, %o0 + 0x18), NG_ret_i2_plus_g1_minus_24) 309478b8fecSSam Ravnborg 3107ae3aaf5SDavid S. Miller EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3), NG_ret_i2_plus_g1_minus_32) 311478b8fecSSam Ravnborg MIX_THREE_WORDS(%g3, %o2, %o3, %i5, GLOBAL_SPARE, %o1) 312478b8fecSSam Ravnborg 3137ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%g3, %o0 + 0x20), NG_ret_i2_plus_g1_minus_32) 3147ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o2, %o0 + 0x28), NG_ret_i2_plus_g1_minus_40) 315478b8fecSSam Ravnborg 3167ae3aaf5SDavid S. Miller EX_LD(LOAD_TWIN(%i1 + %i3, %g2, %g3), NG_ret_i2_plus_g1_minus_48) 317478b8fecSSam Ravnborg add %i1, 64, %i1 318478b8fecSSam Ravnborg MIX_THREE_WORDS(%o3, %g2, %g3, %i5, GLOBAL_SPARE, %o1) 319478b8fecSSam Ravnborg 3207ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o3, %o0 + 0x30), NG_ret_i2_plus_g1_minus_48) 3217ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%g2, %o0 + 0x38), NG_ret_i2_plus_g1_minus_56) 322478b8fecSSam Ravnborg 323478b8fecSSam Ravnborg subcc %g1, 64, %g1 324478b8fecSSam Ravnborg bne,pt %XCC, 9b 325478b8fecSSam Ravnborg add %o0, 64, %o0 326478b8fecSSam Ravnborg 327478b8fecSSam Ravnborg ba,pt %XCC, 60f 328478b8fecSSam Ravnborg add %i1, %i4, %i1 329478b8fecSSam Ravnborg 330478b8fecSSam Ravnborg10: /* Destination is 64-byte aligned, source was only 8-byte 331478b8fecSSam Ravnborg * aligned but it has been subtracted by 8 and we perform 332478b8fecSSam Ravnborg * one twin load ahead, then add 8 back into source when 333478b8fecSSam Ravnborg * we finish the loop. 334478b8fecSSam Ravnborg */ 3357ae3aaf5SDavid S. Miller EX_LD(LOAD_TWIN(%i1, %o4, %o5), NG_ret_i2_plus_g1) 336478b8fecSSam Ravnborg mov 16, %o7 337478b8fecSSam Ravnborg mov 32, %g2 338478b8fecSSam Ravnborg mov 48, %g3 339478b8fecSSam Ravnborg mov 64, %o1 3407ae3aaf5SDavid S. Miller1: EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3), NG_ret_i2_plus_g1) 341478b8fecSSam Ravnborg LOAD(prefetch, %i1 + %o1, #one_read) 3427ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o5, %o0 + 0x00), NG_ret_i2_plus_g1) ! initializes cache line 3437ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o2, %o0 + 0x08), NG_ret_i2_plus_g1_minus_8) 3447ae3aaf5SDavid S. Miller EX_LD(LOAD_TWIN(%i1 + %g2, %o4, %o5), NG_ret_i2_plus_g1_minus_16) 3457ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o3, %o0 + 0x10), NG_ret_i2_plus_g1_minus_16) 3467ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o4, %o0 + 0x18), NG_ret_i2_plus_g1_minus_24) 3477ae3aaf5SDavid S. Miller EX_LD(LOAD_TWIN(%i1 + %g3, %o2, %o3), NG_ret_i2_plus_g1_minus_32) 3487ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o5, %o0 + 0x20), NG_ret_i2_plus_g1_minus_32) 3497ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o2, %o0 + 0x28), NG_ret_i2_plus_g1_minus_40) 3507ae3aaf5SDavid S. Miller EX_LD(LOAD_TWIN(%i1 + %o1, %o4, %o5), NG_ret_i2_plus_g1_minus_48) 351478b8fecSSam Ravnborg add %i1, 64, %i1 3527ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o3, %o0 + 0x30), NG_ret_i2_plus_g1_minus_48) 3537ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o4, %o0 + 0x38), NG_ret_i2_plus_g1_minus_56) 354478b8fecSSam Ravnborg subcc %g1, 64, %g1 355478b8fecSSam Ravnborg bne,pt %XCC, 1b 356478b8fecSSam Ravnborg add %o0, 64, %o0 357478b8fecSSam Ravnborg 358478b8fecSSam Ravnborg ba,pt %XCC, 60f 359478b8fecSSam Ravnborg add %i1, 0x8, %i1 360478b8fecSSam Ravnborg 361478b8fecSSam Ravnborg50: /* Destination is 64-byte aligned, and source is 16-byte 362478b8fecSSam Ravnborg * aligned. 363478b8fecSSam Ravnborg */ 364478b8fecSSam Ravnborg mov 16, %o7 365478b8fecSSam Ravnborg mov 32, %g2 366478b8fecSSam Ravnborg mov 48, %g3 367478b8fecSSam Ravnborg mov 64, %o1 3687ae3aaf5SDavid S. Miller1: EX_LD(LOAD_TWIN(%i1 + %g0, %o4, %o5), NG_ret_i2_plus_g1) 3697ae3aaf5SDavid S. Miller EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3), NG_ret_i2_plus_g1) 370478b8fecSSam Ravnborg LOAD(prefetch, %i1 + %o1, #one_read) 3717ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o4, %o0 + 0x00), NG_ret_i2_plus_g1) ! initializes cache line 3727ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o5, %o0 + 0x08), NG_ret_i2_plus_g1_minus_8) 3737ae3aaf5SDavid S. Miller EX_LD(LOAD_TWIN(%i1 + %g2, %o4, %o5), NG_ret_i2_plus_g1_minus_16) 3747ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o2, %o0 + 0x10), NG_ret_i2_plus_g1_minus_16) 3757ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o3, %o0 + 0x18), NG_ret_i2_plus_g1_minus_24) 3767ae3aaf5SDavid S. Miller EX_LD(LOAD_TWIN(%i1 + %g3, %o2, %o3), NG_ret_i2_plus_g1_minus_32) 377478b8fecSSam Ravnborg add %i1, 64, %i1 3787ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o4, %o0 + 0x20), NG_ret_i2_plus_g1_minus_32) 3797ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o5, %o0 + 0x28), NG_ret_i2_plus_g1_minus_40) 3807ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o2, %o0 + 0x30), NG_ret_i2_plus_g1_minus_48) 3817ae3aaf5SDavid S. Miller EX_ST(STORE_INIT(%o3, %o0 + 0x38), NG_ret_i2_plus_g1_minus_56) 382478b8fecSSam Ravnborg subcc %g1, 64, %g1 383478b8fecSSam Ravnborg bne,pt %XCC, 1b 384478b8fecSSam Ravnborg add %o0, 64, %o0 385478b8fecSSam Ravnborg /* fall through */ 386478b8fecSSam Ravnborg 387478b8fecSSam Ravnborg60: 388478b8fecSSam Ravnborg membar #Sync 389478b8fecSSam Ravnborg 390478b8fecSSam Ravnborg /* %i2 contains any final bytes still needed to be copied 391478b8fecSSam Ravnborg * over. If anything is left, we copy it one byte at a time. 392478b8fecSSam Ravnborg */ 393478b8fecSSam Ravnborg RESTORE_ASI(%i3) 394478b8fecSSam Ravnborg brz,pt %i2, 85f 395478b8fecSSam Ravnborg sub %o0, %i1, %i3 396478b8fecSSam Ravnborg ba,a,pt %XCC, 90f 3970ae2d26fSBabu Moger nop 398478b8fecSSam Ravnborg 399478b8fecSSam Ravnborg .align 64 400478b8fecSSam Ravnborg70: /* 16 < len <= 64 */ 401478b8fecSSam Ravnborg bne,pn %XCC, 75f 402478b8fecSSam Ravnborg sub %o0, %i1, %i3 403478b8fecSSam Ravnborg 404478b8fecSSam Ravnborg72: 405478b8fecSSam Ravnborg andn %i2, 0xf, %i4 406478b8fecSSam Ravnborg and %i2, 0xf, %i2 407478b8fecSSam Ravnborg1: subcc %i4, 0x10, %i4 4087ae3aaf5SDavid S. Miller EX_LD(LOAD(ldx, %i1, %o4), NG_ret_i2_plus_i4) 409478b8fecSSam Ravnborg add %i1, 0x08, %i1 4107ae3aaf5SDavid S. Miller EX_LD(LOAD(ldx, %i1, %g1), NG_ret_i2_plus_i4) 411478b8fecSSam Ravnborg sub %i1, 0x08, %i1 4127ae3aaf5SDavid S. Miller EX_ST(STORE(stx, %o4, %i1 + %i3), NG_ret_i2_plus_i4) 413478b8fecSSam Ravnborg add %i1, 0x8, %i1 4147ae3aaf5SDavid S. Miller EX_ST(STORE(stx, %g1, %i1 + %i3), NG_ret_i2_plus_i4_minus_8) 415478b8fecSSam Ravnborg bgu,pt %XCC, 1b 416478b8fecSSam Ravnborg add %i1, 0x8, %i1 417478b8fecSSam Ravnborg73: andcc %i2, 0x8, %g0 418478b8fecSSam Ravnborg be,pt %XCC, 1f 419478b8fecSSam Ravnborg nop 420478b8fecSSam Ravnborg sub %i2, 0x8, %i2 4217ae3aaf5SDavid S. Miller EX_LD(LOAD(ldx, %i1, %o4), NG_ret_i2_plus_8) 4227ae3aaf5SDavid S. Miller EX_ST(STORE(stx, %o4, %i1 + %i3), NG_ret_i2_plus_8) 423478b8fecSSam Ravnborg add %i1, 0x8, %i1 424478b8fecSSam Ravnborg1: andcc %i2, 0x4, %g0 425478b8fecSSam Ravnborg be,pt %XCC, 1f 426478b8fecSSam Ravnborg nop 427478b8fecSSam Ravnborg sub %i2, 0x4, %i2 4287ae3aaf5SDavid S. Miller EX_LD(LOAD(lduw, %i1, %i5), NG_ret_i2_plus_4) 4297ae3aaf5SDavid S. Miller EX_ST(STORE(stw, %i5, %i1 + %i3), NG_ret_i2_plus_4) 430478b8fecSSam Ravnborg add %i1, 0x4, %i1 431478b8fecSSam Ravnborg1: cmp %i2, 0 432478b8fecSSam Ravnborg be,pt %XCC, 85f 433478b8fecSSam Ravnborg nop 434478b8fecSSam Ravnborg ba,pt %xcc, 90f 435478b8fecSSam Ravnborg nop 436478b8fecSSam Ravnborg 437478b8fecSSam Ravnborg75: 438478b8fecSSam Ravnborg andcc %o0, 0x7, %g1 439478b8fecSSam Ravnborg sub %g1, 0x8, %g1 440478b8fecSSam Ravnborg be,pn %icc, 2f 441478b8fecSSam Ravnborg sub %g0, %g1, %g1 442478b8fecSSam Ravnborg sub %i2, %g1, %i2 443478b8fecSSam Ravnborg 444478b8fecSSam Ravnborg1: subcc %g1, 1, %g1 4457ae3aaf5SDavid S. Miller EX_LD(LOAD(ldub, %i1, %i5), NG_ret_i2_plus_g1_plus_1) 4467ae3aaf5SDavid S. Miller EX_ST(STORE(stb, %i5, %i1 + %i3), NG_ret_i2_plus_g1_plus_1) 447478b8fecSSam Ravnborg bgu,pt %icc, 1b 448478b8fecSSam Ravnborg add %i1, 1, %i1 449478b8fecSSam Ravnborg 450478b8fecSSam Ravnborg2: add %i1, %i3, %o0 451478b8fecSSam Ravnborg andcc %i1, 0x7, %g1 452478b8fecSSam Ravnborg bne,pt %icc, 8f 453478b8fecSSam Ravnborg sll %g1, 3, %g1 454478b8fecSSam Ravnborg 455478b8fecSSam Ravnborg cmp %i2, 16 456478b8fecSSam Ravnborg bgeu,pt %icc, 72b 457478b8fecSSam Ravnborg nop 458478b8fecSSam Ravnborg ba,a,pt %xcc, 73b 459478b8fecSSam Ravnborg 460478b8fecSSam Ravnborg8: mov 64, %i3 461478b8fecSSam Ravnborg andn %i1, 0x7, %i1 4627ae3aaf5SDavid S. Miller EX_LD(LOAD(ldx, %i1, %g2), NG_ret_i2) 463478b8fecSSam Ravnborg sub %i3, %g1, %i3 464478b8fecSSam Ravnborg andn %i2, 0x7, %i4 465478b8fecSSam Ravnborg sllx %g2, %g1, %g2 466478b8fecSSam Ravnborg1: add %i1, 0x8, %i1 4677ae3aaf5SDavid S. Miller EX_LD(LOAD(ldx, %i1, %g3), NG_ret_i2_and_7_plus_i4) 468478b8fecSSam Ravnborg subcc %i4, 0x8, %i4 469478b8fecSSam Ravnborg srlx %g3, %i3, %i5 470478b8fecSSam Ravnborg or %i5, %g2, %i5 4717ae3aaf5SDavid S. Miller EX_ST(STORE(stx, %i5, %o0), NG_ret_i2_and_7_plus_i4) 472478b8fecSSam Ravnborg add %o0, 0x8, %o0 473478b8fecSSam Ravnborg bgu,pt %icc, 1b 474478b8fecSSam Ravnborg sllx %g3, %g1, %g2 475478b8fecSSam Ravnborg 476478b8fecSSam Ravnborg srl %g1, 3, %g1 477478b8fecSSam Ravnborg andcc %i2, 0x7, %i2 478478b8fecSSam Ravnborg be,pn %icc, 85f 479478b8fecSSam Ravnborg add %i1, %g1, %i1 480478b8fecSSam Ravnborg ba,pt %xcc, 90f 481478b8fecSSam Ravnborg sub %o0, %i1, %i3 482478b8fecSSam Ravnborg 483478b8fecSSam Ravnborg .align 64 484478b8fecSSam Ravnborg80: /* 0 < len <= 16 */ 485478b8fecSSam Ravnborg andcc %i3, 0x3, %g0 486478b8fecSSam Ravnborg bne,pn %XCC, 90f 487478b8fecSSam Ravnborg sub %o0, %i1, %i3 488478b8fecSSam Ravnborg 489478b8fecSSam Ravnborg1: 490478b8fecSSam Ravnborg subcc %i2, 4, %i2 4917ae3aaf5SDavid S. Miller EX_LD(LOAD(lduw, %i1, %g1), NG_ret_i2_plus_4) 4927ae3aaf5SDavid S. Miller EX_ST(STORE(stw, %g1, %i1 + %i3), NG_ret_i2_plus_4) 493478b8fecSSam Ravnborg bgu,pt %XCC, 1b 494478b8fecSSam Ravnborg add %i1, 4, %i1 495478b8fecSSam Ravnborg 496478b8fecSSam Ravnborg85: ret 497478b8fecSSam Ravnborg restore EX_RETVAL(%i0), %g0, %o0 498478b8fecSSam Ravnborg 499478b8fecSSam Ravnborg .align 32 500478b8fecSSam Ravnborg90: 501478b8fecSSam Ravnborg subcc %i2, 1, %i2 5027ae3aaf5SDavid S. Miller EX_LD(LOAD(ldub, %i1, %g1), NG_ret_i2_plus_1) 5037ae3aaf5SDavid S. Miller EX_ST(STORE(stb, %g1, %i1 + %i3), NG_ret_i2_plus_1) 504478b8fecSSam Ravnborg bgu,pt %XCC, 90b 505478b8fecSSam Ravnborg add %i1, 1, %i1 506478b8fecSSam Ravnborg ret 507478b8fecSSam Ravnborg restore EX_RETVAL(%i0), %g0, %o0 508478b8fecSSam Ravnborg 509478b8fecSSam Ravnborg .size FUNC_NAME, .-FUNC_NAME 510