/* * linux/arch/arm/lib/crc32.S * * Copyright (C) 2005 Rick Bronson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * ASM optimised crc32 function */ #include #include .extern crc_table .text #define ENTER \ mov ip, sp ;\ stmfd sp!, {r4-r9, sl, fp, ip, lr, pc} ;\ sub fp, ip, #4 #define EXIT \ LOADREGS(ea, fp, {r4 - r9, sl, fp, sp, pc}) /* * Prototype: ulong crc32 (ulong crc, const unsigned char *, uint size); registers: pc = r15, lr = r14, sp = r13, ip = r12, fp = r11, sl = r10 */ ENTRY(crc32asm) ENTER ldr r3, crctab /* let r3 point to the crc table */ odd: ands r4, r1, #3 /* on an odd boundry? */ beq even subs r2, r2, #1 blt out ldrb r4, [r1], #1 /* do up to 3 bytes here */ eor r4, r0, r4 and r4, r4, #255 /* 0xff */ ldr r4, [r3, r4, lsl #2] eor r0, r4, r0, lsr #8 b odd evenlp: ldmia r1!,{r4 - r9, sl, ip} /* grab 8 longs, 32 bytes */ /* crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) */ eor lr, r0 ,r4 /* do 1st byte of r4 */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r4, lsr #8 /* do 2nd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r4, lsr #16 /* do 3rd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r4, lsr #24 /* do 4th byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r5 /* do 1st byte of r5 */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r5, lsr #8 /* do 2nd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r5, lsr #16 /* do 3rd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r5, lsr #24 /* do 4th byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r6 /* do 1st byte of r6 */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r6, lsr #8 /* do 2nd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r6, lsr #16 /* do 3rd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r6, lsr #24 /* do 4th byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r7 /* do 1st byte of r7 */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r7, lsr #8 /* do 2nd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r7, lsr #16 /* do 3rd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r7, lsr #24 /* do 4th byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r8 /* do 1st byte of r8 */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r8, lsr #8 /* do 2nd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r8, lsr #16 /* do 3rd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r8, lsr #24 /* do 4th byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r9 /* do 1st byte of r9 */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r9, lsr #8 /* do 2nd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r9, lsr #16 /* do 3rd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0 ,r9, lsr #24 /* do 4th byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0, sl /* do 1st byte of sl */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0, sl, lsr #8 /* do 2nd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0, sl, lsr #16 /* do 3rd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0, sl, lsr #24 /* do 4th byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0, ip /* do 1st byte of ip */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0, ip, lsr #8 /* do 2nd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0, ip, lsr #16 /* do 3rd byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 eor lr, r0, ip, lsr #24 /* do 4th byte */ and lr, lr, #255 /* 0xff */ ldr lr, [r3, lr, lsl #2] eor r0, lr, r0, lsr #8 even: subs r2, r2, #32 /* can we do 32 bytes at a time? */ bge evenlp /* keep going if we have 32 */ adds r2, r2, #32 /* add back 32 to get remainder */ ble out /* any left? */ /* ; do one byte at a time */ one: ldrb r4, [r1], #1 /* */ eor r4, r0, r4 and r4, r4, #255 /* 0xff */ ldr r4, [r3, r4, lsl #2] eor r0, r4, r0, lsr #8 subs r2, r2, #1 /* 0x1 */ bne one out: EXIT crctab: .long SYMBOL_NAME(crc_table) .align