Path: blob/master/arch/arm/lib/csumpartialcopygeneric.S
26292 views
/* SPDX-License-Identifier: GPL-2.0-only */1/*2* linux/arch/arm/lib/csumpartialcopygeneric.S3*4* Copyright (C) 1995-2001 Russell King5*/6#include <asm/assembler.h>78/*9* unsigned int10* csum_partial_copy_xxx(const char *src, char *dst, int len, int sum, )11* r0 = src, r1 = dst, r2 = len, r3 = sum12* Returns : r0 = checksum13*14* Note that 'tst' and 'teq' preserve the carry flag.15*/1617src .req r018dst .req r119len .req r220sum .req r32122.Lzero: mov r0, sum23load_regs2425/*26* Align an unaligned destination pointer. We know that27* we have >= 8 bytes here, so we don't need to check28* the length. Note that the source pointer hasn't been29* aligned yet.30*/31.Ldst_unaligned:32tst dst, #133beq .Ldst_16bit3435load1b ip36sub len, len, #137adcs sum, sum, ip, put_byte_1 @ update checksum38strb ip, [dst], #139tst dst, #240reteq lr @ dst is now 32bit aligned4142.Ldst_16bit: load2b r8, ip43sub len, len, #244adcs sum, sum, r8, put_byte_045strb r8, [dst], #146adcs sum, sum, ip, put_byte_147strb ip, [dst], #148ret lr @ dst is now 32bit aligned4950/*51* Handle 0 to 7 bytes, with any alignment of source and52* destination pointers. Note that when we get here, C = 053*/54.Lless8: teq len, #0 @ check for zero count55beq .Lzero5657/* we must have at least one byte. */58tst dst, #1 @ dst 16-bit aligned59beq .Lless8_aligned6061/* Align dst */62load1b ip63sub len, len, #164adcs sum, sum, ip, put_byte_1 @ update checksum65strb ip, [dst], #166tst len, #667beq .Lless8_byteonly68691: load2b r8, ip70sub len, len, #271adcs sum, sum, r8, put_byte_072strb r8, [dst], #173adcs sum, sum, ip, put_byte_174strb ip, [dst], #175.Lless8_aligned:76tst len, #677bne 1b78.Lless8_byteonly:79tst len, #180beq .Ldone81load1b r882adcs sum, sum, r8, put_byte_0 @ update checksum83strb r8, [dst], #184b .Ldone8586FN_ENTRY87save_regs88mov sum, #-18990cmp len, #8 @ Ensure that we have at least91blo .Lless8 @ 8 bytes to copy.9293adds sum, sum, #0 @ C = 094tst dst, #3 @ Test destination alignment95blne .Ldst_unaligned @ align destination, return here9697/*98* Ok, the dst pointer is now 32bit aligned, and we know99* that we must have more than 4 bytes to copy. Note100* that C contains the carry from the dst alignment above.101*/102103tst src, #3 @ Test source alignment104bne .Lsrc_not_aligned105106/* Routine for src & dst aligned */107108bics ip, len, #15109beq 2f1101111: load4l r4, r5, r6, r7112stmia dst!, {r4, r5, r6, r7}113adcs sum, sum, r4114adcs sum, sum, r5115adcs sum, sum, r6116adcs sum, sum, r7117sub ip, ip, #16118teq ip, #0119bne 1b1201212: ands ip, len, #12122beq 4f123tst ip, #8124beq 3f125load2l r4, r5126stmia dst!, {r4, r5}127adcs sum, sum, r4128adcs sum, sum, r5129tst ip, #4130beq 4f1311323: load1l r4133str r4, [dst], #4134adcs sum, sum, r41351364: ands len, len, #3137beq .Ldone138load1l r4139tst len, #2140mov r5, r4, get_byte_0141beq .Lexit142adcs sum, sum, r4, lspush #16143strb r5, [dst], #1144mov r5, r4, get_byte_1145strb r5, [dst], #1146mov r5, r4, get_byte_2147.Lexit: tst len, #1148strbne r5, [dst], #1149andne r5, r5, #255150adcsne sum, sum, r5, put_byte_0151152/*153* If the dst pointer was not 16-bit aligned, we154* need to rotate the checksum here to get around155* the inefficient byte manipulations in the156* architecture independent code.157*/158.Ldone: adc r0, sum, #0159ldr sum, [sp, #0] @ dst160tst sum, #1161movne r0, r0, ror #8162load_regs163164.Lsrc_not_aligned:165adc sum, sum, #0 @ include C from dst alignment166and ip, src, #3167bic src, src, #3168load1l r5169cmp ip, #2170beq .Lsrc2_aligned171bhi .Lsrc3_aligned172mov r4, r5, lspull #8 @ C = 0173bics ip, len, #15174beq 2f1751: load4l r5, r6, r7, r8176orr r4, r4, r5, lspush #24177mov r5, r5, lspull #8178orr r5, r5, r6, lspush #24179mov r6, r6, lspull #8180orr r6, r6, r7, lspush #24181mov r7, r7, lspull #8182orr r7, r7, r8, lspush #24183stmia dst!, {r4, r5, r6, r7}184adcs sum, sum, r4185adcs sum, sum, r5186adcs sum, sum, r6187adcs sum, sum, r7188mov r4, r8, lspull #8189sub ip, ip, #16190teq ip, #0191bne 1b1922: ands ip, len, #12193beq 4f194tst ip, #8195beq 3f196load2l r5, r6197orr r4, r4, r5, lspush #24198mov r5, r5, lspull #8199orr r5, r5, r6, lspush #24200stmia dst!, {r4, r5}201adcs sum, sum, r4202adcs sum, sum, r5203mov r4, r6, lspull #8204tst ip, #4205beq 4f2063: load1l r5207orr r4, r4, r5, lspush #24208str r4, [dst], #4209adcs sum, sum, r4210mov r4, r5, lspull #82114: ands len, len, #3212beq .Ldone213mov r5, r4, get_byte_0214tst len, #2215beq .Lexit216adcs sum, sum, r4, lspush #16217strb r5, [dst], #1218mov r5, r4, get_byte_1219strb r5, [dst], #1220mov r5, r4, get_byte_2221b .Lexit222223.Lsrc2_aligned: mov r4, r5, lspull #16224adds sum, sum, #0225bics ip, len, #15226beq 2f2271: load4l r5, r6, r7, r8228orr r4, r4, r5, lspush #16229mov r5, r5, lspull #16230orr r5, r5, r6, lspush #16231mov r6, r6, lspull #16232orr r6, r6, r7, lspush #16233mov r7, r7, lspull #16234orr r7, r7, r8, lspush #16235stmia dst!, {r4, r5, r6, r7}236adcs sum, sum, r4237adcs sum, sum, r5238adcs sum, sum, r6239adcs sum, sum, r7240mov r4, r8, lspull #16241sub ip, ip, #16242teq ip, #0243bne 1b2442: ands ip, len, #12245beq 4f246tst ip, #8247beq 3f248load2l r5, r6249orr r4, r4, r5, lspush #16250mov r5, r5, lspull #16251orr r5, r5, r6, lspush #16252stmia dst!, {r4, r5}253adcs sum, sum, r4254adcs sum, sum, r5255mov r4, r6, lspull #16256tst ip, #4257beq 4f2583: load1l r5259orr r4, r4, r5, lspush #16260str r4, [dst], #4261adcs sum, sum, r4262mov r4, r5, lspull #162634: ands len, len, #3264beq .Ldone265mov r5, r4, get_byte_0266tst len, #2267beq .Lexit268adcs sum, sum, r4269strb r5, [dst], #1270mov r5, r4, get_byte_1271strb r5, [dst], #1272tst len, #1273beq .Ldone274load1b r5275b .Lexit276277.Lsrc3_aligned: mov r4, r5, lspull #24278adds sum, sum, #0279bics ip, len, #15280beq 2f2811: load4l r5, r6, r7, r8282orr r4, r4, r5, lspush #8283mov r5, r5, lspull #24284orr r5, r5, r6, lspush #8285mov r6, r6, lspull #24286orr r6, r6, r7, lspush #8287mov r7, r7, lspull #24288orr r7, r7, r8, lspush #8289stmia dst!, {r4, r5, r6, r7}290adcs sum, sum, r4291adcs sum, sum, r5292adcs sum, sum, r6293adcs sum, sum, r7294mov r4, r8, lspull #24295sub ip, ip, #16296teq ip, #0297bne 1b2982: ands ip, len, #12299beq 4f300tst ip, #8301beq 3f302load2l r5, r6303orr r4, r4, r5, lspush #8304mov r5, r5, lspull #24305orr r5, r5, r6, lspush #8306stmia dst!, {r4, r5}307adcs sum, sum, r4308adcs sum, sum, r5309mov r4, r6, lspull #24310tst ip, #4311beq 4f3123: load1l r5313orr r4, r4, r5, lspush #8314str r4, [dst], #4315adcs sum, sum, r4316mov r4, r5, lspull #243174: ands len, len, #3318beq .Ldone319mov r5, r4, get_byte_0320tst len, #2321beq .Lexit322strb r5, [dst], #1323adcs sum, sum, r4324load1l r4325mov r5, r4, get_byte_0326strb r5, [dst], #1327adcs sum, sum, r4, lspush #24328mov r5, r4, get_byte_1329b .Lexit330FN_EXIT331332333