first and last commit

This commit is contained in:
Chris Nutter committed 2023-07-08 13:03:17 -07:00
commit 1bf4efd552
2612 files changed
+636500

No files matched your search

+81
View File
@@ -0,0 +1,81 @@
/*
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2007-2012 Apple Inc. All rights reserved.
*
* This document is the property of Apple Computer, Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#include <sys.h>
#include <arch.h>
#include <sys/types.h>
#include <lib/cksum.h>
#if (ARCH_ARMv7 && WITH_VFP) || defined(__arm64__)
extern uint32_t adler32_vec(uint32_t, uint32_t, const uint8_t *, long);
#endif
#define BASE 65521L /* largest prime smaller than 65536 */
#define NMAX 5000
// NMAX (was 5521) the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8);
uint32_t adler32(const uint8_t *buf, long len)
{
uint32_t s1 = 1; // adler & 0xffff;
uint32_t s2 = 0; // (adler >> 16) & 0xffff;
int k;
#if (ARCH_ARMv7 && WITH_VFP) || defined(__arm64__)
/* align buf to 16-byte boundary */
while ((int)buf & 15) { /* not on a 16-byte boundary */
len--;
s1 += *buf++;
s2 += s1;
s1 %= BASE;
s2 %= BASE;
}
if (len > 16) {
#if WITH_VFP_ALWAYS_ON
return adler32_vec(s1, s2, buf, len);
#else
bool fp_enabled;
uint32_t result;
fp_enabled = arch_task_fp_enable(true);
result = adler32_vec(s1, s2, buf, len);
arch_task_fp_enable(fp_enabled);
return result;
#endif // WITH_VFP_ALWAYS_ON
}
#endif
while (len > 0) {
k = len < NMAX ? len : NMAX;
len -= k;
while (k >= 16) {
DO16(buf);
buf += 16;
k -= 16;
}
if (k != 0) do {
s1 += *buf++;
s2 += s1;
} while (--k);
s1 %= BASE;
s2 %= BASE;
}
return (s2 << 16) | s1;
}
+341
View File
@@ -0,0 +1,341 @@
/*
* Copyright (C) 2012-2014 Apple Inc. All rights reserved.
*
* This document is the property of Apple Computer, Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#if defined(__arm__)
#define BASE 65521 /* largest prime smaller than 65536 */
#define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
// Note: buf should have been 16-byte aligned in the caller function,
// uLong adler32_vec(unsigned int adler, unsigned int sum2, const Bytef* buf, int len) {
// unsigned n;
// while (len >= NMAX) {
// len -= NMAX;
// n = NMAX / 16; /* NMAX is divisible by 16 */
// do {
// DO16(buf); /* 16 sums unrolled */
// buf += 16;
// } while (--n);
// MOD(adler);
// MOD(sum2);
// }
// if (len) { /* avoid modulos if none remaining */
// while (len >= 16) {
// len -= 16;
// DO16(buf);
// buf += 16;
// }
// while (len--) {
// adler += *buf++;
// sum2 += adler;
// }
// MOD(adler);
// MOD(sum2);
// }
// return adler | (sum2 << 16); /* return recombined sums */
// }
/*
DO16 vectorization:
given initial unsigned int sum2 and adler, and a new set of 16 input bytes (x[0:15]), it can be shown that
sum2 += (16*adler + 16*x[0] + 15*x[1] + ... + 1*x[15]);
adler += (x[0] + x[1] + ... + x[15]);
therefore, this is what can be done to vectorize the above computation
1. 16-byte aligned vector load into q2 (x[0:x15])
2. sum2 += (adler<<4);
3. vmull.u8 (q9,q8),q2,d2 where d2 = (1,1,1,1...,1), (q9,q8) + 16 16-bit elements x[0:15]
4. vmull.u8 (q11,q10),q2,q0 where q0 = (1,2,3,4...,16), (q11,q10) + 16 16-bit elements (16:1)*x[0:15]
5. parallel add (with once expansion to 32-bit) (q9,q8) and (q11,q10) all the way to accumulate to adler and sum2
In this revision, whenever possible, 2 DO16 loops are combined into a DO32 loop.
1. 32-byte aligned vector load into q2,q14 (x[0:x31])
2. sum2 += (adler<<5);
3. vmull.u8 (4 q registers),(q2,q14),d2 where d2 = (1,1,1,1...,1), (4 q registers) : 32 16-bit elements x[0:31]
4. vmull.u8 (4 q registers),(q2,q14),(q0,q15) where q0 = (1,...,32), (4 q regs) : 32 16-bit elements (32:1)*x[0:31]
5. parallel add (with once expansion to 32-bit) the pair of (4 q regs) all the way to accumulate to adler and sum2
This change improves the performance by ~ 0.55 cycle/uncompress byte on ARM Cortex-A8.
*/
/*
MOD implementation:
adler%BASE = adler - floor(adler*(1/BASE))*BASE; where (1/BASE) = 0x80078071 in Q47
1. vmull.u32 q2,(adler,sum2),(1/BASE) // *(1/BASE) in Q47
2. vshr.u64 q2,q2,#47 // floor function
3. vpadd.u32 d4,d4,d5 // merge into a double word in d4
4. vmls.u32 (adler,sum2),d4,d3[0] // (adler,sum2) -= floor[(adler,sum2)/BASE]*BASE
*/
.text
.align 2
.globl _adler32_vec
_adler32_vec:
#define adler r0
#define sum2 r1
#define buf r2
#define len r3
#define nmax r4
#define vecs lr // vecs = NMAX/16
#define n r5
#define t r12
#define sum2_coeff q0
#define sum2_coeff0 d0
#define sum2_coeff1 d1
#define alder_coeff q1
#define ones d2
#define x0_x15 q2
#define x0_x7 d4
#define x8_x15 d5
#define adlersum2 d6
#define adler16 d25
adr t, vec_table // address to vec_table[]
stmfd sp!, {r4, r5, lr}
vld1.32 {q0-q1},[t,:128]! // loading up coefficients for adler/sum2 computation
vld1.32 {q15},[t,:128]! // for sum2 computation
ldr nmax, [t] // NMAX
vmov adlersum2, sum2, adler // pack up adler/sum2 into a double register
cmp len, nmax // len vs NMAX
lsr vecs, nmax, #4 // vecs = NMAX/16;
blt L_len_lessthan_NMAX // if (len < NMAX) skip the while loop
sub len, nmax // pre-decrement len by NMAX
L_while_len_ge_NMAX_loop: // while (len>=NMAX) {
mov n, vecs, lsr #1 // n = NMAX/16;
L_do_loop: // do {
vshll.u32 q12, adlersum2, #5 // d25 = (0,32*adler) to be added into (adler,sum2)
vld1.32 {x0_x15},[buf,:128]! // 16-byte input x0:x15
vmull.u8 q8, x0_x7, ones // 16-bit x0-x7
vld1.32 {q14}, [buf,:128]! // x16:x31
vmull.u8 q9, x8_x15, ones // 16-bit x8-x15
vadd.u32 adlersum2,adler16 // sum2 += old adler*32;
vmull.u8 q12, d28, ones // 16-bit x16-x23
vmull.u8 q13, d29, ones // 16-bit x24-x31
vmull.u8 q10, d28, sum2_coeff0 // 16-bit x16*16, x17*15, ..., x23*9
vmull.u8 q11, d29, sum2_coeff1 // 16-bit x24*8, x25*7, ..., x31*1
vadd.u16 q8, q8, q9 // q8 = (x0+x8):(x7+x15) 8 16-bit elements for adler
vmull.u8 q9, x0_x7, d30 // 16-bit x0*32,...,x7*25
vmull.u8 q14, x8_x15, d31 // 16-bit x8*24,...,x15*17
vadd.u16 q12, q12, q13 // q12 = (x16+x24):(x23+x31) 8 16-bit elements for adler
vadd.u16 q10, q11 // 8 16-bit elements for sum2
vadd.u16 q8, q12 // 8 16-bit elements for adler
vadd.u16 q9, q14 // 8 16-bit elements for sum2
vadd.u16 q10, q9 // 8 16-bit elements for sum2
#if 0
vpaddl.u16 q8, q8 // 4 32-bit elements for adler
vpaddl.u16 q10, q10 // 4 32-bit elements for sum2
vpadd.u32 d16,d16,d17 // 2 32-bit elements for adler
vpadd.u32 d17,d20,d21 // 2 32-bit elements for sum2
#else
vadd.u16 d16, d17
vadd.u16 d20, d21
vpaddl.u16 d16, d16
vpaddl.u16 d17, d20
#endif
vpadd.u32 d4,d17,d16 // s8 : 32-bit elements for sum2, s9 : 32-bit element for adler
vadd.u32 adlersum2,d4 // update adler/sum2 with the new 16 bytes input
subs n, #1 // --n
bgt L_do_loop // } while (--n);
vshll.u32 q12, adlersum2, #4 // d25 = (0,16*adler) to be added into (adler,sum2)
vld1.32 {x0_x15},[buf,:128]! // 16-byte input
vmull.u8 q8, x0_x7, ones // 16-bit x0-x7
vmull.u8 q9, x8_x15, ones // 16-bit x8-x15
vmull.u8 q10, x0_x7, sum2_coeff0 // 16-bit x0*16, x1*15, ..., x7*9
vmull.u8 q11, x8_x15, sum2_coeff1 // 16-bit x8*8, x9*7, ..., x15*1
vadd.u16 q8, q8, q9 // 8 16-bit elements for adler
vadd.u16 q10, q10, q11 // 8 16-bit elements for sum2
#if 0
vpaddl.u16 q8, q8 // 4 32-bit elements for adler
vpaddl.u16 q10, q10 // 4 32-bit elements for sum2
vpadd.u32 d16,d16,d17 // 2 32-bit elements for adler
vpadd.u32 d17,d20,d21 // 2 32-bit elements for sum2
#else
vadd.u16 d16, d17
vadd.u16 d20, d21
vpaddl.u16 d16, d16
vpaddl.u16 d17, d20
#endif
vadd.u32 adlersum2,adler16 // sum2 += old adler;
vpadd.u32 d4,d17,d16 // s8 : 32-bit elements for sum2, s9 : 32-bit element for adler
vadd.u32 adlersum2,d4 // update adler/sum2 with the new 16 bytes input
// mod(alder,BASE); mod(sum2,BASE);
vmull.u32 q2,adlersum2,d3[1] // alder/BASE, sum2/BASE in Q47
vshr.u64 q2,q2,#47 // take the integer part
vpadd.u32 d4,d4,d5 // merge into a double word in d4
vmls.u32 adlersum2,d4,d3[0] // (adler,sum2) -= floor[(adler,sum2)/BASE]*BASE
subs len, nmax // len -= NMAX;
bge L_while_len_ge_NMAX_loop // repeat while len >= NMAX
add len, nmax // post-increment len by NMAX
L_len_lessthan_NMAX:
cmp len, #0
beq L_len_is_zero // if len==0, branch to skip the following
subs len, #32 // pre-decrement len by 32
blt L_len_lessthan_32 // if len < 32, branch to L_len16_loop
L_len32_loop:
vshll.u32 q12, adlersum2, #5 // d25 = (0,32*adler) to be added into (adler,sum2)
vld1.32 {x0_x15},[buf,:128]! // 16-byte input x0:x15
vmull.u8 q8, x0_x7, ones // 16-bit x0-x7
vld1.32 {q14}, [buf,:128]! // x16:x31
vmull.u8 q9, x8_x15, ones // 16-bit x8-x15
vadd.u32 adlersum2,adler16 // sum2 += old adler*32;
vmull.u8 q12, d28, ones // 16-bit x16-x23
vmull.u8 q13, d29, ones // 16-bit x24-x31
vmull.u8 q10, d28, sum2_coeff0 // 16-bit x16*16, x17*15, ..., x23*9
vmull.u8 q11, d29, sum2_coeff1 // 16-bit x24*8, x25*7, ..., x31*1
vadd.u16 q8, q8, q9 // q8 = (x0+x8):(x7+x15) 8 16-bit elements for adler
vmull.u8 q9, x0_x7, d30 // 16-bit x0*32,...,x7*25
vmull.u8 q14, x8_x15, d31 // 16-bit x8*24,...,x15*17
vadd.u16 q12, q12, q13 // q12 = (x16+x24):(x23+x31) 8 16-bit elements for adler
vadd.u16 q10, q11 // 8 16-bit elements for sum2
vadd.u16 q8, q12 // 8 16-bit elements for adler
vadd.u16 q9, q14 // 8 16-bit elements for sum2
vadd.u16 q10, q9 // 8 16-bit elements for sum2
#if 0
vpaddl.u16 q8, q8 // 4 32-bit elements for adler
vpaddl.u16 q10, q10 // 4 32-bit elements for sum2
vpadd.u32 d16,d16,d17 // 2 32-bit elements for adler
vpadd.u32 d17,d20,d21 // 2 32-bit elements for sum2
#else
vadd.u16 d16, d17
vadd.u16 d20, d21
vpaddl.u16 d16, d16
vpaddl.u16 d17, d20
#endif
vpadd.u32 d4,d17,d16 // s8 : 32-bit elements for sum2, s9 : 32-bit element for adler
vadd.u32 adlersum2,d4 // update adler/sum2 with the new 16 bytes input
subs len, #32 // len -= 32;
bge L_len32_loop
L_len_lessthan_32:
adds len, #(32-16) // post-increment len by 32, then pre-decrement by 16
blt L_len_lessthan_16 // if len < 16, branch to L_len_lessthan_16
vshll.u32 q12, adlersum2, #4 // d25 = (0,16*adler) to be added into (adler,sum2)
vld1.32 {x0_x15},[buf,:128]! // 16-byte input
vmull.u8 q8, x0_x7, ones // 16-bit x0-x7
vmull.u8 q9, x8_x15, ones // 16-bit x8-x15
vmull.u8 q10, x0_x7, sum2_coeff0 // 16-bit x0*16, x1*15, ..., x7*9
vmull.u8 q11, x8_x15, sum2_coeff1 // 16-bit x8*8, x9*7, ..., x15*1
vadd.u16 q8, q8, q9 // 8 16-bit elements for adler
vadd.u16 q10, q10, q11 // 8 16-bit elements for sum2
#if 0
vpaddl.u16 q8, q8 // 4 32-bit elements for adler
vpaddl.u16 q10, q10 // 4 32-bit elements for sum2
vpadd.u32 d16,d16,d17 // 2 32-bit elements for adler
vpadd.u32 d17,d20,d21 // 2 32-bit elements for sum2
#else
vadd.u16 d16, d17
vadd.u16 d20, d21
vpaddl.u16 d16, d16
vpaddl.u16 d17, d20
#endif
subs len, #16 // decrement len by 16
vadd.u32 adlersum2,adler16 // sum2 += old adler;
vpadd.u32 d4,d17,d16 // s8 : 32-bit elements for sum2, s9 : 32-bit element for adler
vadd.u32 adlersum2,d4 // update adler/sum2 with the new 16 bytes input
L_len_lessthan_16:
adds len, #16 // post-increment len by 16
beq L_len_is_zero_internal // if len==0, branch to len_is_zero_internal
// restore adler/sum2 into general registers for remaining (<16) bytes
vmov sum2, adler, adlersum2
L_remaining_len_loop:
ldrb t, [buf], #1 // *buf++;
subs len, #1 // len--;
add adler,t // adler += *buf
add sum2,adler // sum2 += adler
bgt L_remaining_len_loop // break if len<=0
vmov adlersum2, sum2, adler // move to double register for modulo operation
L_len_is_zero_internal:
// mod(alder,BASE); mod(sum2,BASE);
vmull.u32 q2,adlersum2,d3[1] // alder/BASE, sum2/BASE in Q47
vshr.u64 q2,q2,#47 // take the integer part
vpadd.u32 d4,d4,d5 // merge into a double word in d4
vmls.u32 adlersum2,d4,d3[0] // (adler,sum2) -= floor[(adler,sum2)/BASE]*BASE
L_len_is_zero:
vmov sum2, adler, adlersum2 // restore adler/sum2 from (s12=sum2, s13=adler)
add r0, adler, sum2, lsl #16 // to return adler | (sum2 << 16);
ldmfd sp!, {r4, r5, pc} // restore registers and return
// constants to be loaded into q registers
.align 4 // 16 byte aligned
vec_table:
// coefficients for computing sum2
.long 0x0d0e0f10 // s0
.long 0x090a0b0c // s1
.long 0x05060708 // s2
.long 0x01020304 // s3
// coefficients for computing adler
.long 0x01010101 // s4/d2
.long 0x01010101 // s5
.long BASE // s6 : BASE
.long 0x80078071 // s7 : 1/BASE in Q47
// q15 : d30.d31
.long 0x1d1e1f20 // s0
.long 0x191a1b1c // s1
.long 0x15161718 // s2
.long 0x11121314 // s3
NMAX_loc:
.long NMAX // NMAX
#endif // defined(__arm__)
+318
View File
@@ -0,0 +1,318 @@
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* This document is the property of Apple Computer, Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#if defined(__arm64__)
#define BASE 65521 /* largest prime smaller than 65536 */
#define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
// Note: buf should have been 16-byte aligned in the caller function,
// uLong adler32_vec(unsigned int adler, unsigned int sum2, const Bytef* buf, int len) {
// unsigned n;
// while (len >= NMAX) {
// len -= NMAX;
// n = NMAX / 16; /* NMAX is divisible by 16 */
// do {
// DO16(buf); /* 16 sums unrolled */
// buf += 16;
// } while (--n);
// MOD(adler);
// MOD(sum2);
// }
// if (len) { /* avoid modulos if none remaining */
// while (len >= 16) {
// len -= 16;
// DO16(buf);
// buf += 16;
// }
// while (len--) {
// adler += *buf++;
// sum2 += adler;
// }
// MOD(adler);
// MOD(sum2);
// }
// return adler | (sum2 << 16); /* return recombined sums */
// }
/*
DO16 vectorization:
given initial unsigned int sum2 and adler, and a new set of 16 input bytes (x[0:15]), it can be shown that
sum2 += (16*adler + 16*x[0] + 15*x[1] + ... + 1*x[15]);
adler += (x[0] + x[1] + ... + x[15]);
similarly, 2 DO16 = DO32 vectorization:
given initial unsigned int sum2 and adler, and a new set of 32 input bytes (x[0:31]), it can be shown that
sum2 += (32*adler + 32*x[0] + 31*x[1] + ... + 1*x[31]);
adler += (x[0] + x[1] + ... + x[31]);
NMAX = 5552
NMAX/16 = 347 = 173*2 + 1
therefore, for a block of 5552 bytes
n = 173;
do {
DO32(buf); buf+=32;
} while (n--);
DO16(buf); buf+=16;
MOD(adler);
MOD(sum2);
for a residual remaining len bytes,
while (len >= 32) {
DO32(buf); buf += 32; len -= 32;
}
if (len>=16) {
DO16(buf); buf += 16; len -= 16;
}
while (len--) {
adler += *buf++;
sum2 += adler;
}
MOD(adler);
MOD(sum2);
DO32:
pack sum2:adler in a 64-bit register
0. sum2 += adler*32;
sum2:adler += (sum2:adler) << (32+5);
1. (32, 31, ..., 1) * ( x0, x1, ..., x31) (v2, v3) * (v0, v1)
umull.8h v4, v2, v0
umull2.8h v5, v2, v0
umull.8h v6, v3, v1
umull2.8h v7, v3, v1
add.8h v4, v4, v5
add.8h v6, v6, v7
add.8h v4, v4, v6
uaddlv s4, v4.8h
add sum2, sum2, s4
2. adler += (x0 + x1 + x2 + ... + x31)
uaddlp v0.8h, v0.16b
uaddlp v1.8h, v1.16b
uaddlv s0, v0.8h
uaddlv s1, v1.8h
add s0, s0, s1
add adler, adler, s0
therefore, this is what can be done to vectorize the above computation
1. 16-byte aligned vector load into q2 (x[0:x15])
2. sum2 += (adler<<32); // pack adler/sum2 into a 64-bit word
3. vmull.u8 (q9,q8),q2,d2 where d2 = (1,1,1,1...,1), (q9,q8) + 16 16-bit elements x[0:15]
4. vmull.u8 (q11,q10),q2,q0 where q0 = (1,2,3,4...,16), (q11,q10) + 16 16-bit elements (16:1)*x[0:15]
5. parallel add (with once expansion to 32-bit) (q9,q8) and (q11,q10) all the way to accumulate to adler and sum2
In this revision, whenever possible, 2 DO16 loops are combined into a DO32 loop.
1. 32-byte aligned vector load into q2,q14 (x[0:x31])
2. sum2 += (adler<<32);
3. vmull.u8 (4 q registers),(q2,q14),d2 where d2 = (1,1,1,1...,1), (4 q registers) : 32 16-bit elements x[0:31]
4. vmull.u8 (4 q registers),(q2,q14),(q0,q15) where q0 = (1,...,32), (4 q regs) : 32 16-bit elements (32:1)*x[0:31]
5. parallel add (with once expansion to 32-bit) the pair of (4 q regs) all the way to accumulate to adler and sum2
This change improves the performance by ~ 0.55 cycle/uncompress byte on ARM Cortex-A8.
*/
/*
MOD implementation:
adler%BASE = adler - floor(adler*(1/BASE))*BASE; where (1/BASE) = 0x80078071 in Q47
1. vmull.u32 q2,(adler,sum2),(1/BASE) // *(1/BASE) in Q47
2. vshr.u64 q2,q2,#47 // floor function
3. vpadd.u32 d4,d4,d5 // merge into a double word in d4
4. vmls.u32 (adler,sum2),d4,d3[0] // (adler,sum2) -= floor[(adler,sum2)/BASE]*BASE
*/
.text
.align 2
.globl _adler32_vec
_adler32_vec:
#define adler w0
#define sum2 w1
#define buf x2
#define len w3
#define nmax w4
#define nvec w6 // vecs = NMAX/16
#define t x7
#define vadlersum2 v5 // only lower part
#define adlersum2 d5 // only lower part
add x0, x0, x1, lsl #32
adrp t, vec_table@PAGE
mov nmax, #NMAX // NMAX
add t, t, vec_table@PAGEOFF
ins vadlersum2.d[0], x0
#if KERNEL
sub x6, sp, #8*16
sub sp, sp, #8*16
st1.4s {v0,v1,v2,v3},[x6],#4*16
st1.4s {v4,v5,v6,v7},[x6],#4*16
#endif
cmp len, nmax // len vs NMAX
ld1.4s {v0, v1}, [t], #2*16 // loading up coefficients for adler/sum2 computation
ldr d7, [t] // for MOD operation
b.lt L_len_lessthan_NMAX // if (len < NMAX) skip the while loop
sub len, len, nmax // pre-decrement len by NMAX
L_while_len_ge_NMAX_loop: // while (len>=NMAX) {
// 5552/16 = 173*2 + 1, need 1 DO16 + 173 DO32
.macro DO16
ld1.4s {v2},[buf] // 16 bytes input
shl d6, adlersum2, #(4+32) // adler * 16
umull.8h v4, v2, v1 // 16*x0, 15*x1, ..., 9*x7
add adlersum2, adlersum2, d6 // sum2 += adler * 16
umlal2.8h v4, v2, v1 // 8*x8, 7*x9, ..., 1*x15
uaddlv h2, v2.16b // x0+x1+x2+...+x15
uaddlv s4, v4.8h // 16*x0 + 15*x1 + ... + 1*x15
zip1.2s v4, v2, v4
add buf, buf, #16
add.2s vadlersum2, vadlersum2, v4
.endm
.macro DO32
ld1.4s {v2,v3},[buf] // 32 bytes input
shl d6, adlersum2, #(5+32) // adler * 32
umull.8h v4, v2, v0 // 32*x0, 31*x1, ..., 25*x7
add adlersum2, adlersum2, d6 // sum2 += adler * 32
umlal2.8h v4, v2, v0 // accumulate 24*x8, 23*x9, ..., 17*x15
uaddlv h2, v2.16b // x0+x1+x2+...+x15 and extend from byte to short
umlal.8h v4, v3, v1 // accumulate 16*x16, 15*x17, ..., 9*x23
uaddlv h6, v3.16b // x16+x17+x18+...+x31 and extend from byte to short
umlal2.8h v4, v3, v1 // accumulate 8*x24, 7*x25, ..., 1*x31
uaddl.4s v2, v2, v6 // x0+x1+...+x31 and extend from short to int
uaddlv s4, v4.8h // 32*x0 + 31*x1 + ... + 1*x31
zip1.2s v4, v2, v4
add buf, buf, #32
add.2s vadlersum2, vadlersum2, v4
.endm
.macro MOD_BASE
umull.2d v2,vadlersum2,v7[1]
ushr.2d v2, v2, #47
ins v2.s[1], v2.s[2]
mls.2s vadlersum2,v2,v7[0]
.endm
DO16
mov nvec, #173 // number of DO32 loops
0:
DO32
subs nvec, nvec, #1
b.gt 0b
MOD_BASE // MOD(adler,sum2);
subs len, len, nmax // pre-decrement len by NMAX
b.ge L_while_len_ge_NMAX_loop // repeat while len >= NMAX
adds len, len, nmax // post-increment len by NMAX
L_len_lessthan_NMAX:
subs len, len, #32 // pre-decrement len by 32
b.lt L_len_lessthan_32 // if len < 32, branch to len16_loop
L_len32_loop:
DO32
subs len, len, #32 // len -= 32;
b.ge L_len32_loop
L_len_lessthan_32:
tst len, #16
b.eq 1f
DO16
1:
ands len, len, #15
b.eq L_len_is_zero
L_remaining_len_loop:
ldrb w0, [buf], #1 // *buf++;
sub len, len, #1
ins v2.d[0], x0
add adlersum2, adlersum2, d2 // adler += *buf
shl d6, adlersum2, #32 // shift adler up to sum2 position
add adlersum2, adlersum2, d6 // sum2 += adler
cbnz len, L_remaining_len_loop // break if len<=0
L_len_is_zero:
MOD_BASE // mod(alder,BASE); mod(sum2,BASE);
umov w0, vadlersum2.s[0] // adler
umov w1, vadlersum2.s[1] // sum2
add w0, w0, w1, lsl #16 // to return adler | (sum2 << 16);
#if KERNEL
ld1.4s {v0,v1,v2,v3},[sp],#4*16
ld1.4s {v4,v5,v6,v7},[sp],#4*16
#endif
ret lr
// constants to be loaded into q registers
.align 4 // 16 byte aligned
vec_table:
// coefficients for computing sum2
.long 0x1d1e1f20 // s0
.long 0x191a1b1c // s1
.long 0x15161718 // s2
.long 0x11121314 // s3
.long 0x0d0e0f10 // s0
.long 0x090a0b0c // s1
.long 0x05060708 // s2
.long 0x01020304 // s3
.long BASE // s6 : BASE
.long 0x80078071 // s7 : 1/BASE in Q47
#endif // __arm64__
+121
View File
@@ -0,0 +1,121 @@
/* $NetBSD: crc.c,v 1.18 2006/09/04 20:01:10 dsl Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* James W. Williams of NASA Goddard Space Flight Center.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdint.h>
#include <sys/types.h>
#include <lib/cksum.h>
static const uint32_t crctab[] = {
0x0,
0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
};
#define COMPUTE(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
/*
* Compute a POSIX 1003.2 checksum. Length is included in the checksum.
*/
uint32_t
crc(const void *buf, size_t len)
{
const uint8_t *p = buf;
size_t nr = len;
uint32_t thecrc = INITIAL_CRC;
for (p = buf; nr; p++, nr--)
COMPUTE(thecrc, *p);
/* Include the length of the buffer. */
for (; len != 0; len >>= 8) {
COMPUTE(thecrc, len & 0xff);
}
return ~thecrc;
}
uint32_t
crc_byte(uint32_t thecrc, unsigned int byte_val)
{
COMPUTE(thecrc, byte_val & 0xff);
return thecrc;
}
+53
View File
@@ -0,0 +1,53 @@
#include <lib/cksum.h>
#include <sys/types.h>
#include <stdint.h>
/* Table of CRCs of all 8-bit messages. */
static uint32_t crc32_table[256];
/* Flag: has the table been computed? Initially false. */
static int crc32_table_computed = 0;
/* Make the table for a fast CRC. */
static void make_crc32_table(void)
{
uint32_t c;
int n, k;
for (n = 0; n < 256; n++) {
c = (uint32_t) n;
for (k = 0; k < 8; k++) {
if (c & 1)
c = 0xedb88320L ^ (c >> 1);
else
c = c >> 1;
}
crc32_table[n] = c;
}
crc32_table_computed = 1;
}
/* Update a running CRC with the bytes buf[0..len-1]--the CRC
should be initialized to all 1's, and the transmitted value
is the 1's complement of the final running CRC (see the
crc32() routine below). */
uint32_t update_crc32(uint32_t crc, const uint8_t *buf,
int len)
{
uint32_t c = crc;
int n;
if (!crc32_table_computed)
make_crc32_table();
for (n = 0; n < len; n++) {
c = crc32_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
}
return c;
}
/* Return the CRC of the bytes buf[0..len-1]. */
uint32_t crc32(const uint8_t *buf, int len)
{
return update_crc32(0xffffffffL, buf, len) ^ 0xffffffffL;
}
+35
View File
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2007-2009, 2013-2014 Apple Inc. All rights reserved.
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
#include <debug.h>
#include <lib/cksum.h>
#include <sys/menu.h>
#include <drivers/sha1.h>
int do_crc(int argc, struct cmd_arg *args)
{
if (argc < 3) {
printf("not enough arguments.\n");
printf("%s <address> <len>\n", args[0].str);
return -1;
}
if (!security_allow_memory((void *)args[1].u, args[2].u)) {
printf("Permission Denied\n");
return -1;
}
uint32_t crc32 = crc((void *)args[1].u, args[2].u);
printf("crc %u (length %zu)\n", crc32, args[2].u);
return 0;
}
+33
View File
@@ -0,0 +1,33 @@
# Copyright (C) 2014 Apple Inc. All rights reserved.
#
# This document is the property of Apple Inc.
# It is considered confidential and proprietary.
#
# This document may not be reproduced or transmitted in any form,
# in whole or in part, without the express written permission of
# Apple Inc.
#
LIBCKSUM_DIR := $(GET_LOCAL_DIR)
LIBCKSUM_BUILD := $(call TOLIBDIR,$(LIBCKSUM_DIR)/LIBCKSUM.a)
COMMONLIBS += LIBCKSUM
# Only process the remainder of the makefile if we are building libraries
#
ifeq ($(MAKEPHASE),libraries)
LIBCKSUM_OBJS := \
$(LIBCKSUM_DIR)/adler32.o \
$(LIBCKSUM_DIR)/$(ARCH)/adler32vec.o \
$(LIBCKSUM_DIR)/crc.o \
$(LIBCKSUM_DIR)/crc32.o \
$(LIBCKSUM_DIR)/debug.o \
$(LIBCKSUM_DIR)/siphash.o
LIBCKSUM_OBJS := $(call TOLIBOBJDIR,$(LIBCKSUM_OBJS))
ALL_DEPS += $(LIBCKSUM_OBJS:%o=%d)
$(LIBCKSUM_BUILD): $(LIBCKSUM_OBJS)
endif
+13
View File
@@ -0,0 +1,13 @@
# Copyright (C) 2007-2014 Apple Inc. All rights reserved.
# Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
#
# This document is the property of Apple Computer, Inc.
# It is considered confidential and proprietary.
#
# This document may not be reproduced or transmitted in any form,
# in whole or in part, without the express written permission of
# Apple Inc.
#
OPTIONS += WITH_CKSUM=1
LIBRARY_MODULES += lib/cksum
+220
View File
@@ -0,0 +1,220 @@
/*
SipHash reference C implementation
Copyright (c) 2012 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
Copyright (c) 2012 Daniel J. Bernstein <djb@cr.yp.to>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <debug.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint8_t u8;
#define cROUNDS 2
#define dROUNDS 4
#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) )
#define U32TO8_LE(p, v) \
(p)[0] = (u8)((v) ); (p)[1] = (u8)((v) >> 8); \
(p)[2] = (u8)((v) >> 16); (p)[3] = (u8)((v) >> 24);
#define U64TO8_LE(p, v) \
U32TO8_LE((p), (u32)((v) )); \
U32TO8_LE((p) + 4, (u32)((v) >> 32));
#define U8TO64_LE(p) \
(((u64)((p)[0]) ) | \
((u64)((p)[1]) << 8) | \
((u64)((p)[2]) << 16) | \
((u64)((p)[3]) << 24) | \
((u64)((p)[4]) << 32) | \
((u64)((p)[5]) << 40) | \
((u64)((p)[6]) << 48) | \
((u64)((p)[7]) << 56))
#define SIPROUND \
do { \
v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \
v2 += v3; v3=ROTL(v3,16); v3 ^= v2; \
v0 += v3; v3=ROTL(v3,21); v3 ^= v0; \
v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \
} while(0)
/* SipHash-2-4 */
void siphash( uint8_t *out, const uint8_t *in, size_t inlen, const uint8_t *k )
{
/* "somepseudorandomlygeneratedbytes" */
u64 v0 = 0x736f6d6570736575ULL;
u64 v1 = 0x646f72616e646f6dULL;
u64 v2 = 0x6c7967656e657261ULL;
u64 v3 = 0x7465646279746573ULL;
u64 b;
u64 k0 = U8TO64_LE( k );
u64 k1 = U8TO64_LE( k + 8 );
u64 m;
int i;
const u8 *end = in + inlen - ( inlen % sizeof( u64 ) );
const int left = inlen & 7;
b = ( ( u64 )inlen ) << 56;
v3 ^= k1;
v2 ^= k0;
v1 ^= k1;
v0 ^= k0;
for ( ; in != end; in += 8 )
{
m = U8TO64_LE( in );
#ifdef SIPHASH_DEBUG
printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 );
printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 );
printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 );
printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 );
printf( "(%3d) compress %08x %08x\n", ( int )inlen, ( u32 )( m >> 32 ), ( u32 )m );
#endif
v3 ^= m;
for( i=0; i<cROUNDS; ++i ) SIPROUND;
v0 ^= m;
}
switch( left )
{
case 7: b |= ( ( u64 )in[ 6] ) << 48;
case 6: b |= ( ( u64 )in[ 5] ) << 40;
case 5: b |= ( ( u64 )in[ 4] ) << 32;
case 4: b |= ( ( u64 )in[ 3] ) << 24;
case 3: b |= ( ( u64 )in[ 2] ) << 16;
case 2: b |= ( ( u64 )in[ 1] ) << 8;
case 1: b |= ( ( u64 )in[ 0] ); break;
case 0: break;
}
#ifdef SIPHASH_DEBUG
printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 );
printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 );
printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 );
printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 );
printf( "(%3d) padding %08x %08x\n", ( int )inlen, ( u32 )( b >> 32 ), ( u32 )b );
#endif
v3 ^= b;
for( i=0; i<cROUNDS; ++i ) SIPROUND;
v0 ^= b;
#ifdef SIPHASH_DEBUG
printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 );
printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 );
printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 );
printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 );
#endif
v2 ^= 0xff;
for( i=0; i<dROUNDS; ++i ) SIPROUND;
b = v0 ^ v1 ^ v2 ^ v3;
U64TO8_LE( out, b );
}
void siphash_aligned(uint64_t *out, const uint64_t *in_aligned, size_t inlen, const uint64_t *k)
{
/* "somepseudorandomlygeneratedbytes" */
u64 v0 = 0x736f6d6570736575ULL;
u64 v1 = 0x646f72616e646f6dULL;
u64 v2 = 0x6c7967656e657261ULL;
u64 v3 = 0x7465646279746573ULL;
u64 b;
u64 k0 = k[0];
u64 k1 = k[1];
u64 m;
int i;
const u8 *in = (const u8 *)in_aligned;
const u8 *end = in + inlen - ( inlen % sizeof( u64 ) );
const int left = inlen & 7;
b = ( ( u64 )inlen ) << 56;
v3 ^= k1;
v2 ^= k0;
v1 ^= k1;
v0 ^= k0;
ASSERT(((uintptr_t)in_aligned & (sizeof(u64) - 1)) == 0);
for ( ; in != end; in += 8 )
{
m = *(u64 *)in;
#ifdef SIPHASH_DEBUG
printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 );
printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 );
printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 );
printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 );
printf( "(%3d) compress %08x %08x\n", ( int )inlen, ( u32 )( m >> 32 ), ( u32 )m );
#endif
v3 ^= m;
for( i=0; i<cROUNDS; ++i ) SIPROUND;
v0 ^= m;
}
switch( left )
{
case 7: b |= ( ( u64 )in[ 6] ) << 48;
case 6: b |= ( ( u64 )in[ 5] ) << 40;
case 5: b |= ( ( u64 )in[ 4] ) << 32;
case 4: b |= ( ( u64 )in[ 3] ) << 24;
case 3: b |= ( ( u64 )in[ 2] ) << 16;
case 2: b |= ( ( u64 )in[ 1] ) << 8;
case 1: b |= ( ( u64 )in[ 0] ); break;
case 0: break;
}
#ifdef SIPHASH_DEBUG
printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 );
printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 );
printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 );
printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 );
printf( "(%3d) padding %08x %08x\n", ( int )inlen, ( u32 )( b >> 32 ), ( u32 )b );
#endif
v3 ^= b;
for( i=0; i<cROUNDS; ++i ) SIPROUND;
v0 ^= b;
#ifdef SIPHASH_DEBUG
printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 );
printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 );
printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 );
printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 );
#endif
v2 ^= 0xff;
for( i=0; i<dROUNDS; ++i ) SIPROUND;
b = v0 ^ v1 ^ v2 ^ v3;
*out = b;
}
+230
View File
@@ -0,0 +1,230 @@
#include <unittest.h>
#include <lib/cksum.h>
struct crc_test {
const char *data;
uint32_t len;
uint32_t expected;
};
static struct crc_test crc32_tests[] = {
{ "", 0, 0x00000000 },
{ "a", 1, 0xe8b7be43 },
{ "abc", 3, 0x352441c2 },
{ "aaaa", 4, 0xad98e545 },
{ "abcdefghijklmnopqrstuvwxyz", 26, 0x4c2750bd }
};
void test_crc32(uintptr_t param)
{
for (unsigned i = 0; i < sizeof crc32_tests / sizeof(crc32_tests[0]); i++) {
struct crc_test *test = &crc32_tests[i];
uint32_t calculated = crc32((const uint8_t *)test->data, test->len);
TEST_ASSERT_EQ(calculated, test->expected);
}
}
void test_update_crc32(uintptr_t param)
{
for (unsigned i = 0; i < sizeof crc32_tests / sizeof(crc32_tests[0]); i++) {
struct crc_test *test = &crc32_tests[i];
uint32_t calculated = 0xffffffff;
const uint8_t *data = (const uint8_t *)test->data;
if (test->len != 0) {
calculated = update_crc32(calculated, data, 1);
calculated = update_crc32(calculated, data + 1, test->len - 1);
} else {
calculated = update_crc32(calculated, data, test->len);
}
calculated ^= 0xffffffff;
TEST_ASSERT_EQ(calculated, test->expected);
// updating with data of length 0 shouldn't have an effect
calculated = update_crc32(calculated, (const uint8_t *)"a", 0);
TEST_ASSERT_EQ(calculated, test->expected);
}
}
// generated with the "cksum" commandline tool
static struct crc_test crc_tests[] = {
{ "", 0, 4294967295 },
{ "a", 1, 1220704766 },
{ "abc", 3, 1219131554 },
{ "aaaa", 4, 3100911197 },
{ "abcdefghijklmnopqrstuvwxyz", 26, 2713270184 },
{ "\0\0\0\0", 4, 3975907619 },
};
void test_crc(uintptr_t data)
{
for (unsigned i = 0; i < sizeof crc_tests / sizeof(crc_tests[0]); i++) {
struct crc_test *test = &crc_tests[i];
uint32_t calculated = crc((const uint8_t *)test->data, test->len);
TEST_ASSERT_EQ(calculated, test->expected);
}
}
void test_crc_byte(uintptr_t data)
{
for (unsigned i = 0; i < sizeof crc_tests / sizeof(crc_tests[0]); i++) {
struct crc_test *test = &crc_tests[i];
uint32_t calculated = INITIAL_CRC;
for (uint32_t j = 0; j < test->len; j++)
calculated = crc_byte(calculated, ((const uint8_t *)test->data)[j]);
for (uint32_t n = test->len; n != 0; n >>= 8)
calculated = crc_byte(calculated, n & 0xff);
calculated = ~calculated;
TEST_ASSERT_EQ(calculated, test->expected);
}
}
static struct crc_test adler32_tests[] = {
{ "", 0, 0x00000001 },
{ "a", 1, 0x00620062 },
{ "abc", 3, 0x024d0127 },
{ "message digest", 14, 0x29750586 },
{ "abcdefghijklmnopqrstuvwxyz", 26, 0x90860b20 },
};
void test_adler32(uintptr_t data)
{
for (unsigned i = 0; i < sizeof adler32_tests / sizeof(adler32_tests[0]); i++) {
struct crc_test *test = &adler32_tests[i];
uint32_t calculated = adler32((const uint8_t *)test->data, test->len);
TEST_ASSERT_EQ(calculated, test->expected);
}
}
const uint8_t siphash_vectors[64][SIPHASH_HASH_SIZE] =
{
{ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
{ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
{ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
{ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
{ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
{ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
{ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
{ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
{ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
{ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
{ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
{ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
{ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
{ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
{ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
{ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
{ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
{ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
{ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
{ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
{ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
{ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
{ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
{ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
{ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
{ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
{ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
{ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
{ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
{ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
{ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
{ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
{ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
{ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
{ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
{ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
{ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
{ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
{ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
{ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
{ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
{ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
{ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
{ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
{ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
{ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
{ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
{ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
{ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
{ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
{ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
{ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
{ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
{ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
{ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
{ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
{ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
{ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
{ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
{ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
{ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
{ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
{ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
{ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
};
void test_siphash(uintptr_t context)
{
uint8_t in[64], out[SIPHASH_HASH_SIZE], k[SIPHASH_KEY_SIZE];
unsigned i;
for(i = 0; i < 16; ++i)
k[i] = i;
for(i = 0; i < sizeof(in); ++i)
{
in[i] = i;
siphash(out, in, i, k);
TEST_ASSERT_MEM_EQ(out, siphash_vectors[i], sizeof(out));
}
}
void test_siphash_aligned(uintptr_t context)
{
uint64_t in_aligned[64 / 8];
uint64_t out[SIPHASH_HASH_SIZE / 8];
uint64_t key_aligned[SIPHASH_KEY_SIZE / 8];
uint8_t *in = (uint8_t *)&in_aligned[0];
uint8_t *key = (uint8_t *)&key_aligned[0];
unsigned i;
for(i = 0; i < 16; ++i)
key[i] = i;
for(i = 0; i < sizeof(in); ++i)
{
in[i] = i;
siphash_aligned(out, in_aligned, i, key_aligned);
TEST_ASSERT_MEM_EQ(out, siphash_vectors[i], sizeof(out));
}
}
struct test_suite cksum_suite = {
.name = "cksum",
.test_cases = {
{ "crc32", test_crc32, 0, "Tests the crc32 checksum function" },
{ "update_crc32", test_update_crc32, 0, "Tests the update_crc32 checksum function" },
{ "crc", test_crc, 0, "Tests the crc POSIX 1003.2 checksum function" },
{ "crc_byte", test_crc_byte, 0, "Tests the crc_byte bytewise POSIX 1003.2 checksum function" },
{ "adler32", test_adler32, 0, "Tests the adler32 checksum function" },
{ "siphash", test_siphash, 0, "Tests the siphash checksum function" },
{ "siphash_aligned", test_siphash_aligned, 0, "Tests the siphash_aligned checksum function" },
TEST_CASE_LAST
}
};
TEST_SUITE(cksum_suite);
+39
View File
@@ -0,0 +1,39 @@
# Copyright (C) 2014 Apple Inc. All rights reserved.
#
# This document is the property of Apple Inc.
# It is considered confidential and proprietary.
#
# This document may not be reproduced or transmitted in any form,
# in whole or in part, without the express written permission of
# Apple Inc.
#
LOCAL_DIR := $(GET_LOCAL_DIR)
TEST_NAME := cksum
TEST_OBJS := \
$(LOCAL_DIR)/adler32.o \
$(LOCAL_DIR)/crc.o \
$(LOCAL_DIR)/crc32.o \
$(LOCAL_DIR)/siphash.o
TEST_SUPPORT_OBJS := \
tests/unittest-main.o \
$(LOCAL_DIR)/tests.o
ifeq ($(ARM_ARCH),armv7)
TEST_OBJS += \
$(LOCAL_DIR)/arm/adler32vec.o
endif
ifeq ($(ARM_ARCH),armv7k)
TEST_OBJS += \
$(LOCAL_DIR)/arm/adler32vec.o
endif
ifeq ($(ARM_ARCH),arm64)
TEST_OBJS += \
$(LOCAL_DIR)/arm64/adler32vec.o
endif