1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */ 2478b8fecSSam Ravnborg/* csum_copy.S: Checksum+copy code for sparc64 3478b8fecSSam Ravnborg * 4478b8fecSSam Ravnborg * Copyright (C) 2005 David S. Miller <davem@davemloft.net> 5478b8fecSSam Ravnborg */ 6478b8fecSSam Ravnborg 7*4cdb71b6SMasahiro Yamada#include <linux/export.h> 8d3867f04SAl Viro 9478b8fecSSam Ravnborg#ifdef __KERNEL__ 10478b8fecSSam Ravnborg#define GLOBAL_SPARE %g7 11478b8fecSSam Ravnborg#else 12478b8fecSSam Ravnborg#define GLOBAL_SPARE %g5 13478b8fecSSam Ravnborg#endif 14478b8fecSSam Ravnborg 15478b8fecSSam Ravnborg#ifndef EX_LD 16478b8fecSSam Ravnborg#define EX_LD(x) x 17478b8fecSSam Ravnborg#endif 18478b8fecSSam Ravnborg 19478b8fecSSam Ravnborg#ifndef EX_ST 20478b8fecSSam Ravnborg#define EX_ST(x) x 21478b8fecSSam Ravnborg#endif 22478b8fecSSam Ravnborg 23478b8fecSSam Ravnborg#ifndef EX_RETVAL 24478b8fecSSam Ravnborg#define EX_RETVAL(x) x 25478b8fecSSam Ravnborg#endif 26478b8fecSSam Ravnborg 27478b8fecSSam Ravnborg#ifndef LOAD 28478b8fecSSam Ravnborg#define LOAD(type,addr,dest) type [addr], dest 29478b8fecSSam Ravnborg#endif 30478b8fecSSam Ravnborg 31478b8fecSSam Ravnborg#ifndef STORE 32478b8fecSSam Ravnborg#define STORE(type,src,addr) type src, [addr] 33478b8fecSSam Ravnborg#endif 34478b8fecSSam Ravnborg 35478b8fecSSam Ravnborg#ifndef FUNC_NAME 36fdf8bee9SAl Viro#define FUNC_NAME csum_partial_copy_nocheck 37478b8fecSSam Ravnborg#endif 38478b8fecSSam Ravnborg 39478b8fecSSam Ravnborg .register %g2, #scratch 40478b8fecSSam Ravnborg .register %g3, #scratch 41478b8fecSSam Ravnborg 42478b8fecSSam Ravnborg .text 43478b8fecSSam Ravnborg 44478b8fecSSam Ravnborg90: 45478b8fecSSam Ravnborg /* We checked for zero length already, so there must be 46478b8fecSSam Ravnborg * at least one byte. 47478b8fecSSam Ravnborg */ 48478b8fecSSam Ravnborg be,pt %icc, 1f 49478b8fecSSam Ravnborg nop 50478b8fecSSam Ravnborg EX_LD(LOAD(ldub, %o0 + 0x00, %o4)) 51478b8fecSSam Ravnborg add %o0, 1, %o0 52478b8fecSSam Ravnborg sub %o2, 1, %o2 53478b8fecSSam Ravnborg EX_ST(STORE(stb, %o4, %o1 + 0x00)) 54478b8fecSSam Ravnborg add %o1, 1, %o1 55478b8fecSSam Ravnborg1: andcc %o0, 0x2, %g0 56478b8fecSSam Ravnborg be,pn %icc, 80f 57478b8fecSSam Ravnborg cmp %o2, 2 58478b8fecSSam Ravnborg blu,pn %icc, 60f 59478b8fecSSam Ravnborg nop 60478b8fecSSam Ravnborg EX_LD(LOAD(lduh, %o0 + 0x00, %o5)) 61478b8fecSSam Ravnborg add %o0, 2, %o0 62478b8fecSSam Ravnborg sub %o2, 2, %o2 63478b8fecSSam Ravnborg EX_ST(STORE(sth, %o5, %o1 + 0x00)) 64478b8fecSSam Ravnborg add %o1, 2, %o1 65478b8fecSSam Ravnborg ba,pt %xcc, 80f 66478b8fecSSam Ravnborg add %o5, %o4, %o4 67478b8fecSSam Ravnborg 68478b8fecSSam Ravnborg .globl FUNC_NAME 69f5a651f1SNagarathnam Muthusamy .type FUNC_NAME,#function 70d3867f04SAl Viro EXPORT_SYMBOL(FUNC_NAME) 71fdf8bee9SAl ViroFUNC_NAME: /* %o0=src, %o1=dst, %o2=len */ 72478b8fecSSam Ravnborg LOAD(prefetch, %o0 + 0x000, #n_reads) 73478b8fecSSam Ravnborg xor %o0, %o1, %g1 746220e48dSAl Viro mov -1, %o3 75478b8fecSSam Ravnborg clr %o4 76478b8fecSSam Ravnborg andcc %g1, 0x3, %g0 77478b8fecSSam Ravnborg bne,pn %icc, 95f 78478b8fecSSam Ravnborg LOAD(prefetch, %o0 + 0x040, #n_reads) 79478b8fecSSam Ravnborg 80478b8fecSSam Ravnborg brz,pn %o2, 70f 81478b8fecSSam Ravnborg andcc %o0, 0x3, %g0 82478b8fecSSam Ravnborg 83478b8fecSSam Ravnborg /* We "remember" whether the lowest bit in the address 84478b8fecSSam Ravnborg * was set in GLOBAL_SPARE. Because if it is, we have to swap 85478b8fecSSam Ravnborg * upper and lower 8 bit fields of the sum we calculate. 86478b8fecSSam Ravnborg */ 87478b8fecSSam Ravnborg bne,pn %icc, 90b 88478b8fecSSam Ravnborg andcc %o0, 0x1, GLOBAL_SPARE 89478b8fecSSam Ravnborg 90478b8fecSSam Ravnborg80: 91478b8fecSSam Ravnborg LOAD(prefetch, %o0 + 0x080, #n_reads) 92478b8fecSSam Ravnborg andncc %o2, 0x3f, %g3 93478b8fecSSam Ravnborg 94478b8fecSSam Ravnborg LOAD(prefetch, %o0 + 0x0c0, #n_reads) 95478b8fecSSam Ravnborg sub %o2, %g3, %o2 96478b8fecSSam Ravnborg brz,pn %g3, 2f 97478b8fecSSam Ravnborg LOAD(prefetch, %o0 + 0x100, #n_reads) 98478b8fecSSam Ravnborg 99478b8fecSSam Ravnborg /* So that we don't need to use the non-pairing 100478b8fecSSam Ravnborg * add-with-carry instructions we accumulate 32-bit 101478b8fecSSam Ravnborg * values into a 64-bit register. At the end of the 102478b8fecSSam Ravnborg * loop we fold it down to 32-bits and so on. 103478b8fecSSam Ravnborg */ 104478b8fecSSam Ravnborg ba,pt %xcc, 1f 105478b8fecSSam Ravnborg LOAD(prefetch, %o0 + 0x140, #n_reads) 106478b8fecSSam Ravnborg 107478b8fecSSam Ravnborg .align 32 108478b8fecSSam Ravnborg1: EX_LD(LOAD(lduw, %o0 + 0x00, %o5)) 109478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0 + 0x04, %g1)) 110478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0 + 0x08, %g2)) 111478b8fecSSam Ravnborg add %o4, %o5, %o4 112478b8fecSSam Ravnborg EX_ST(STORE(stw, %o5, %o1 + 0x00)) 113478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0 + 0x0c, %o5)) 114478b8fecSSam Ravnborg add %o4, %g1, %o4 115478b8fecSSam Ravnborg EX_ST(STORE(stw, %g1, %o1 + 0x04)) 116478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0 + 0x10, %g1)) 117478b8fecSSam Ravnborg add %o4, %g2, %o4 118478b8fecSSam Ravnborg EX_ST(STORE(stw, %g2, %o1 + 0x08)) 119478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0 + 0x14, %g2)) 120478b8fecSSam Ravnborg add %o4, %o5, %o4 121478b8fecSSam Ravnborg EX_ST(STORE(stw, %o5, %o1 + 0x0c)) 122478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0 + 0x18, %o5)) 123478b8fecSSam Ravnborg add %o4, %g1, %o4 124478b8fecSSam Ravnborg EX_ST(STORE(stw, %g1, %o1 + 0x10)) 125478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0 + 0x1c, %g1)) 126478b8fecSSam Ravnborg add %o4, %g2, %o4 127478b8fecSSam Ravnborg EX_ST(STORE(stw, %g2, %o1 + 0x14)) 128478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0 + 0x20, %g2)) 129478b8fecSSam Ravnborg add %o4, %o5, %o4 130478b8fecSSam Ravnborg EX_ST(STORE(stw, %o5, %o1 + 0x18)) 131478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0 + 0x24, %o5)) 132478b8fecSSam Ravnborg add %o4, %g1, %o4 133478b8fecSSam Ravnborg EX_ST(STORE(stw, %g1, %o1 + 0x1c)) 134478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0 + 0x28, %g1)) 135478b8fecSSam Ravnborg add %o4, %g2, %o4 136478b8fecSSam Ravnborg EX_ST(STORE(stw, %g2, %o1 + 0x20)) 137478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0 + 0x2c, %g2)) 138478b8fecSSam Ravnborg add %o4, %o5, %o4 139478b8fecSSam Ravnborg EX_ST(STORE(stw, %o5, %o1 + 0x24)) 140478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0 + 0x30, %o5)) 141478b8fecSSam Ravnborg add %o4, %g1, %o4 142478b8fecSSam Ravnborg EX_ST(STORE(stw, %g1, %o1 + 0x28)) 143478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0 + 0x34, %g1)) 144478b8fecSSam Ravnborg add %o4, %g2, %o4 145478b8fecSSam Ravnborg EX_ST(STORE(stw, %g2, %o1 + 0x2c)) 146478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0 + 0x38, %g2)) 147478b8fecSSam Ravnborg add %o4, %o5, %o4 148478b8fecSSam Ravnborg EX_ST(STORE(stw, %o5, %o1 + 0x30)) 149478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0 + 0x3c, %o5)) 150478b8fecSSam Ravnborg add %o4, %g1, %o4 151478b8fecSSam Ravnborg EX_ST(STORE(stw, %g1, %o1 + 0x34)) 152478b8fecSSam Ravnborg LOAD(prefetch, %o0 + 0x180, #n_reads) 153478b8fecSSam Ravnborg add %o4, %g2, %o4 154478b8fecSSam Ravnborg EX_ST(STORE(stw, %g2, %o1 + 0x38)) 155478b8fecSSam Ravnborg subcc %g3, 0x40, %g3 156478b8fecSSam Ravnborg add %o0, 0x40, %o0 157478b8fecSSam Ravnborg add %o4, %o5, %o4 158478b8fecSSam Ravnborg EX_ST(STORE(stw, %o5, %o1 + 0x3c)) 159478b8fecSSam Ravnborg bne,pt %icc, 1b 160478b8fecSSam Ravnborg add %o1, 0x40, %o1 161478b8fecSSam Ravnborg 162478b8fecSSam Ravnborg2: and %o2, 0x3c, %g3 163478b8fecSSam Ravnborg brz,pn %g3, 2f 164478b8fecSSam Ravnborg sub %o2, %g3, %o2 165478b8fecSSam Ravnborg1: EX_LD(LOAD(lduw, %o0 + 0x00, %o5)) 166478b8fecSSam Ravnborg subcc %g3, 0x4, %g3 167478b8fecSSam Ravnborg add %o0, 0x4, %o0 168478b8fecSSam Ravnborg add %o4, %o5, %o4 169478b8fecSSam Ravnborg EX_ST(STORE(stw, %o5, %o1 + 0x00)) 170478b8fecSSam Ravnborg bne,pt %icc, 1b 171478b8fecSSam Ravnborg add %o1, 0x4, %o1 172478b8fecSSam Ravnborg 173478b8fecSSam Ravnborg2: 174478b8fecSSam Ravnborg /* fold 64-->32 */ 175478b8fecSSam Ravnborg srlx %o4, 32, %o5 176478b8fecSSam Ravnborg srl %o4, 0, %o4 177478b8fecSSam Ravnborg add %o4, %o5, %o4 178478b8fecSSam Ravnborg srlx %o4, 32, %o5 179478b8fecSSam Ravnborg srl %o4, 0, %o4 180478b8fecSSam Ravnborg add %o4, %o5, %o4 181478b8fecSSam Ravnborg 182478b8fecSSam Ravnborg /* fold 32-->16 */ 183478b8fecSSam Ravnborg sethi %hi(0xffff0000), %g1 184478b8fecSSam Ravnborg srl %o4, 16, %o5 185478b8fecSSam Ravnborg andn %o4, %g1, %g2 186478b8fecSSam Ravnborg add %o5, %g2, %o4 187478b8fecSSam Ravnborg srl %o4, 16, %o5 188478b8fecSSam Ravnborg andn %o4, %g1, %g2 189478b8fecSSam Ravnborg add %o5, %g2, %o4 190478b8fecSSam Ravnborg 191478b8fecSSam Ravnborg60: 192478b8fecSSam Ravnborg /* %o4 has the 16-bit sum we have calculated so-far. */ 193478b8fecSSam Ravnborg cmp %o2, 2 194478b8fecSSam Ravnborg blu,pt %icc, 1f 195478b8fecSSam Ravnborg nop 196478b8fecSSam Ravnborg EX_LD(LOAD(lduh, %o0 + 0x00, %o5)) 197478b8fecSSam Ravnborg sub %o2, 2, %o2 198478b8fecSSam Ravnborg add %o0, 2, %o0 199478b8fecSSam Ravnborg add %o4, %o5, %o4 200478b8fecSSam Ravnborg EX_ST(STORE(sth, %o5, %o1 + 0x00)) 201478b8fecSSam Ravnborg add %o1, 0x2, %o1 202478b8fecSSam Ravnborg1: brz,pt %o2, 1f 203478b8fecSSam Ravnborg nop 204478b8fecSSam Ravnborg EX_LD(LOAD(ldub, %o0 + 0x00, %o5)) 205478b8fecSSam Ravnborg sub %o2, 1, %o2 206478b8fecSSam Ravnborg add %o0, 1, %o0 207478b8fecSSam Ravnborg EX_ST(STORE(stb, %o5, %o1 + 0x00)) 208478b8fecSSam Ravnborg sllx %o5, 8, %o5 209478b8fecSSam Ravnborg add %o1, 1, %o1 210478b8fecSSam Ravnborg add %o4, %o5, %o4 211478b8fecSSam Ravnborg1: 212478b8fecSSam Ravnborg /* fold 32-->16 */ 213478b8fecSSam Ravnborg sethi %hi(0xffff0000), %g1 214478b8fecSSam Ravnborg srl %o4, 16, %o5 215478b8fecSSam Ravnborg andn %o4, %g1, %g2 216478b8fecSSam Ravnborg add %o5, %g2, %o4 217478b8fecSSam Ravnborg srl %o4, 16, %o5 218478b8fecSSam Ravnborg andn %o4, %g1, %g2 219478b8fecSSam Ravnborg add %o5, %g2, %o4 220478b8fecSSam Ravnborg 221478b8fecSSam Ravnborg1: brz,pt GLOBAL_SPARE, 1f 222478b8fecSSam Ravnborg nop 223478b8fecSSam Ravnborg 224478b8fecSSam Ravnborg /* We started with an odd byte, byte-swap the result. */ 225478b8fecSSam Ravnborg srl %o4, 8, %o5 226478b8fecSSam Ravnborg and %o4, 0xff, %g1 227478b8fecSSam Ravnborg sll %g1, 8, %g1 228478b8fecSSam Ravnborg or %o5, %g1, %o4 229478b8fecSSam Ravnborg 230478b8fecSSam Ravnborg1: addcc %o3, %o4, %o3 231478b8fecSSam Ravnborg addc %g0, %o3, %o3 232478b8fecSSam Ravnborg 233478b8fecSSam Ravnborg70: 234478b8fecSSam Ravnborg retl 235478b8fecSSam Ravnborg srl %o3, 0, %o0 236478b8fecSSam Ravnborg 237478b8fecSSam Ravnborg95: mov 0, GLOBAL_SPARE 238478b8fecSSam Ravnborg brlez,pn %o2, 4f 239478b8fecSSam Ravnborg andcc %o0, 1, %o5 240478b8fecSSam Ravnborg be,a,pt %icc, 1f 241478b8fecSSam Ravnborg srl %o2, 1, %g1 242478b8fecSSam Ravnborg sub %o2, 1, %o2 243478b8fecSSam Ravnborg EX_LD(LOAD(ldub, %o0, GLOBAL_SPARE)) 244478b8fecSSam Ravnborg add %o0, 1, %o0 245478b8fecSSam Ravnborg EX_ST(STORE(stb, GLOBAL_SPARE, %o1)) 246478b8fecSSam Ravnborg srl %o2, 1, %g1 247478b8fecSSam Ravnborg add %o1, 1, %o1 248478b8fecSSam Ravnborg1: brz,a,pn %g1, 3f 249478b8fecSSam Ravnborg andcc %o2, 1, %g0 250478b8fecSSam Ravnborg andcc %o0, 2, %g0 251478b8fecSSam Ravnborg be,a,pt %icc, 1f 252478b8fecSSam Ravnborg srl %g1, 1, %g1 253478b8fecSSam Ravnborg EX_LD(LOAD(lduh, %o0, %o4)) 254478b8fecSSam Ravnborg sub %o2, 2, %o2 255478b8fecSSam Ravnborg srl %o4, 8, %g2 256478b8fecSSam Ravnborg sub %g1, 1, %g1 257478b8fecSSam Ravnborg EX_ST(STORE(stb, %g2, %o1)) 258478b8fecSSam Ravnborg add %o4, GLOBAL_SPARE, GLOBAL_SPARE 259478b8fecSSam Ravnborg EX_ST(STORE(stb, %o4, %o1 + 1)) 260478b8fecSSam Ravnborg add %o0, 2, %o0 261478b8fecSSam Ravnborg srl %g1, 1, %g1 262478b8fecSSam Ravnborg add %o1, 2, %o1 263478b8fecSSam Ravnborg1: brz,a,pn %g1, 2f 264478b8fecSSam Ravnborg andcc %o2, 2, %g0 265478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0, %o4)) 266478b8fecSSam Ravnborg5: srl %o4, 24, %g2 267478b8fecSSam Ravnborg srl %o4, 16, %g3 268478b8fecSSam Ravnborg EX_ST(STORE(stb, %g2, %o1)) 269478b8fecSSam Ravnborg srl %o4, 8, %g2 270478b8fecSSam Ravnborg EX_ST(STORE(stb, %g3, %o1 + 1)) 271478b8fecSSam Ravnborg add %o0, 4, %o0 272478b8fecSSam Ravnborg EX_ST(STORE(stb, %g2, %o1 + 2)) 273478b8fecSSam Ravnborg addcc %o4, GLOBAL_SPARE, GLOBAL_SPARE 274478b8fecSSam Ravnborg EX_ST(STORE(stb, %o4, %o1 + 3)) 275478b8fecSSam Ravnborg addc GLOBAL_SPARE, %g0, GLOBAL_SPARE 276478b8fecSSam Ravnborg add %o1, 4, %o1 277478b8fecSSam Ravnborg subcc %g1, 1, %g1 278478b8fecSSam Ravnborg bne,a,pt %icc, 5b 279478b8fecSSam Ravnborg EX_LD(LOAD(lduw, %o0, %o4)) 280478b8fecSSam Ravnborg sll GLOBAL_SPARE, 16, %g2 281478b8fecSSam Ravnborg srl GLOBAL_SPARE, 16, GLOBAL_SPARE 282478b8fecSSam Ravnborg srl %g2, 16, %g2 283478b8fecSSam Ravnborg andcc %o2, 2, %g0 284478b8fecSSam Ravnborg add %g2, GLOBAL_SPARE, GLOBAL_SPARE 285478b8fecSSam Ravnborg2: be,a,pt %icc, 3f 286478b8fecSSam Ravnborg andcc %o2, 1, %g0 287478b8fecSSam Ravnborg EX_LD(LOAD(lduh, %o0, %o4)) 288478b8fecSSam Ravnborg andcc %o2, 1, %g0 289478b8fecSSam Ravnborg srl %o4, 8, %g2 290478b8fecSSam Ravnborg add %o0, 2, %o0 291478b8fecSSam Ravnborg EX_ST(STORE(stb, %g2, %o1)) 292478b8fecSSam Ravnborg add GLOBAL_SPARE, %o4, GLOBAL_SPARE 293478b8fecSSam Ravnborg EX_ST(STORE(stb, %o4, %o1 + 1)) 294478b8fecSSam Ravnborg add %o1, 2, %o1 295478b8fecSSam Ravnborg3: be,a,pt %icc, 1f 296478b8fecSSam Ravnborg sll GLOBAL_SPARE, 16, %o4 297478b8fecSSam Ravnborg EX_LD(LOAD(ldub, %o0, %g2)) 298478b8fecSSam Ravnborg sll %g2, 8, %o4 299478b8fecSSam Ravnborg EX_ST(STORE(stb, %g2, %o1)) 300478b8fecSSam Ravnborg add GLOBAL_SPARE, %o4, GLOBAL_SPARE 301478b8fecSSam Ravnborg sll GLOBAL_SPARE, 16, %o4 302478b8fecSSam Ravnborg1: addcc %o4, GLOBAL_SPARE, GLOBAL_SPARE 303478b8fecSSam Ravnborg srl GLOBAL_SPARE, 16, %o4 304478b8fecSSam Ravnborg addc %g0, %o4, GLOBAL_SPARE 305478b8fecSSam Ravnborg brz,pt %o5, 4f 306478b8fecSSam Ravnborg srl GLOBAL_SPARE, 8, %o4 307478b8fecSSam Ravnborg and GLOBAL_SPARE, 0xff, %g2 308478b8fecSSam Ravnborg and %o4, 0xff, %o4 309478b8fecSSam Ravnborg sll %g2, 8, %g2 310478b8fecSSam Ravnborg or %g2, %o4, GLOBAL_SPARE 311478b8fecSSam Ravnborg4: addcc %o3, GLOBAL_SPARE, %o3 312478b8fecSSam Ravnborg addc %g0, %o3, %o0 313478b8fecSSam Ravnborg retl 314478b8fecSSam Ravnborg srl %o0, 0, %o0 315478b8fecSSam Ravnborg .size FUNC_NAME, .-FUNC_NAME 316