diff --git a/miner.h b/miner.h index 9adca62..0134927 100644 --- a/miner.h +++ b/miner.h @@ -124,7 +124,7 @@ static inline void le32enc(void *pp, uint32_t x) void sha256_init(uint32_t *state); void sha256_transform(uint32_t *state, const uint32_t *block, int swap); -#if defined(__i386__) || defined(__x86_64__) +#if defined(__ARM_NEON__) || defined(__i386__) || defined(__x86_64__) #define HAVE_SHA256_4WAY 1 int sha256_use_4way(); void sha256_init_4way(uint32_t *state); diff --git a/scrypt-arm.S b/scrypt-arm.S index 537de3c..5e2e29c 100644 --- a/scrypt-arm.S +++ b/scrypt-arm.S @@ -471,7 +471,10 @@ scrypt_core: _scrypt_core: stmfd sp!, {r4-r11, lr} - sub sp, sp, #20*4 + mov r12, sp + sub sp, sp, #21*4 + bic sp, sp, #63 + str r12, [sp, #20*4] scrypt_shuffle @@ -569,7 +572,7 @@ scrypt_core_loop2: scrypt_shuffle - add sp, sp, #20*4 + ldr sp, [sp, #20*4] #ifdef __thumb__ ldmfd sp!, {r4-r11, lr} bx lr @@ -577,4 +580,594 @@ scrypt_core_loop2: ldmfd sp!, {r4-r11, pc} #endif + +#ifdef __ARM_NEON__ + +.macro salsa8_core_3way_doubleround + ldrd r6, [sp, #6*4] + vadd.u32 q4, q0, q1 + add r6, r2, r6 + vadd.u32 q6, q8, q9 + add r7, r3, r7 + vshl.u32 q5, q4, #7 + eor r10, r10, r6, ror #25 + vshl.u32 q7, q6, #7 + add r6, r0, r4 + vshr.u32 q4, q4, #32-7 + eor r11, r11, r7, ror #25 + vshr.u32 q6, q6, #32-7 + add r7, r1, r5 + veor.u32 q3, q3, q5 + strd r10, [sp, #14*4] + veor.u32 q11, q11, q7 + eor r12, r12, r6, ror #25 + veor.u32 q3, q3, q4 + eor lr, lr, r7, ror #25 + veor.u32 q11, q11, q6 + + ldrd r6, [sp, #10*4] + vadd.u32 q4, q3, q0 + add r2, r10, r2 + vadd.u32 q6, q11, q8 + add r3, r11, r3 + vshl.u32 q5, q4, #9 + eor r6, r6, r2, ror #23 + vshl.u32 q7, q6, #9 + add r2, r12, r0 + vshr.u32 q4, q4, #32-9 + eor r7, r7, r3, ror #23 + vshr.u32 q6, q6, #32-9 + add r3, lr, r1 + veor.u32 q2, q2, q5 + strd r6, [sp, #10*4] + veor.u32 q10, q10, q7 + eor r8, r8, r2, ror #23 + veor.u32 q2, q2, q4 + eor r9, r9, r3, ror #23 + veor.u32 q10, q10, q6 + + ldrd r2, [sp, #6*4] + vadd.u32 q4, q2, q3 + add r10, r6, r10 + vadd.u32 q6, q10, q11 + add r11, r7, r11 + vext.u32 q3, q3, q3, #3 + eor r2, r2, r10, ror #19 + vshl.u32 q5, q4, #13 + add r10, r8, r12 + vext.u32 q11, q11, q11, #3 + eor r3, r3, r11, ror #19 + vshl.u32 q7, q6, #13 + add r11, r9, lr + vshr.u32 q4, q4, #32-13 + eor r4, r4, r10, ror #19 + vshr.u32 q6, q6, #32-13 + eor r5, r5, r11, ror #19 + veor.u32 q1, q1, q5 + veor.u32 q9, q9, q7 + veor.u32 q1, q1, q4 + veor.u32 q9, q9, q6 + + ldrd r10, [sp, #2*4] + vadd.u32 q4, q1, q2 + add r6, r2, r6 + vadd.u32 q6, q9, q10 + add r7, r3, r7 + vswp.u32 d4, d5 + eor r10, r10, r6, ror #14 + vshl.u32 q5, q4, #18 + add r6, r4, r8 + vswp.u32 d20, d21 + eor r11, r11, r7, ror #14 + vshl.u32 q7, q6, #18 + add r7, r5, r9 + vshr.u32 q4, q4, #32-18 + eor r0, r0, r6, ror #14 + vshr.u32 q6, q6, #32-18 + eor r1, r1, r7, ror #14 + veor.u32 q0, q0, q5 + ldrd r6, [sp, #14*4] + veor.u32 q8, q8, q7 + veor.u32 q0, q0, q4 + veor.u32 q8, q8, q6 + + + strd r2, [sp, #6*4] + vadd.u32 q4, q0, q3 + strd r10, [sp, #2*4] + vadd.u32 q6, q8, q11 + add r6, r11, r6 + vext.u32 q1, q1, q1, #1 + add r7, r0, r7 + vshl.u32 q5, q4, #7 + eor r4, r4, r6, ror #25 + vext.u32 q9, q9, q9, #1 + add r6, r1, r12 + vshl.u32 q7, q6, #7 + eor r5, r5, r7, ror #25 + vshr.u32 q4, q4, #32-7 + add r7, r10, lr + vshr.u32 q6, q6, #32-7 + eor r2, r2, r6, ror #25 + veor.u32 q1, q1, q5 + eor r3, r3, r7, ror #25 + veor.u32 q9, q9, q7 + strd r2, [sp, #6*4] + veor.u32 q1, q1, q4 + veor.u32 q9, q9, q6 + + add r10, r3, r10 + vadd.u32 q4, q1, q0 + ldrd r6, [sp, #10*4] + vadd.u32 q6, q9, q8 + add r11, r4, r11 + vshl.u32 q5, q4, #9 + eor r8, r8, r10, ror #23 + vshl.u32 q7, q6, #9 + add r10, r5, r0 + vshr.u32 q4, q4, #32-9 + eor r9, r9, r11, ror #23 + vshr.u32 q6, q6, #32-9 + add r11, r2, r1 + veor.u32 q2, q2, q5 + eor r6, r6, r10, ror #23 + veor.u32 q10, q10, q7 + eor r7, r7, r11, ror #23 + veor.u32 q2, q2, q4 + strd r6, [sp, #10*4] + veor.u32 q10, q10, q6 + + add r2, r7, r2 + vadd.u32 q4, q2, q1 + ldrd r10, [sp, #14*4] + vadd.u32 q6, q10, q9 + add r3, r8, r3 + vext.u32 q1, q1, q1, #3 + eor r12, r12, r2, ror #19 + vshl.u32 q5, q4, #13 + add r2, r9, r4 + vext.u32 q9, q9, q9, #3 + eor lr, lr, r3, ror #19 + vshl.u32 q7, q6, #13 + add r3, r6, r5 + vshr.u32 q4, q4, #32-13 + eor r10, r10, r2, ror #19 + vshr.u32 q6, q6, #32-13 + eor r11, r11, r3, ror #19 + veor.u32 q3, q3, q5 + veor.u32 q11, q11, q7 + veor.u32 q3, q3, q4 + veor.u32 q11, q11, q6 + + ldrd r2, [sp, #2*4] + vadd.u32 q4, q3, q2 + add r6, r11, r6 + vadd.u32 q6, q11, q10 + add r7, r12, r7 + vswp.u32 d4, d5 + eor r0, r0, r6, ror #14 + vshl.u32 q5, q4, #18 + add r6, lr, r8 + vswp.u32 d20, d21 + eor r1, r1, r7, ror #14 + vshl.u32 q7, q6, #18 + add r7, r10, r9 + vext.u32 q3, q3, q3, #1 + eor r2, r2, r6, ror #14 + vshr.u32 q4, q4, #32-18 + eor r3, r3, r7, ror #14 + vshr.u32 q6, q6, #32-18 + strd r2, [sp, #2*4] + vext.u32 q11, q11, q11, #1 + strd r10, [sp, #14*4] + veor.u32 q0, q0, q5 + veor.u32 q8, q8, q7 + veor.u32 q0, q0, q4 + veor.u32 q8, q8, q6 +.endm + +.macro salsa8_core_3way + ldmia sp, {r0-r12, lr} + ldrd r10, [sp, #14*4] + salsa8_core_3way_doubleround + salsa8_core_3way_doubleround + salsa8_core_3way_doubleround + salsa8_core_3way_doubleround + stmia sp, {r0-r5} + strd r8, [sp, #8*4] + str r12, [sp, #12*4] + str lr, [sp, #13*4] +.endm + + .text + .code 32 + .align 2 + .globl scrypt_core_3way + .globl _scrypt_core_3way +#ifdef __ELF__ + .type scrypt_core_3way, %function +#endif +scrypt_core_3way: +_scrypt_core_3way: + stmfd sp!, {r4-r11, lr} + vpush {q4-q7} + mov r12, sp + sub sp, sp, #24*16 + bic sp, sp, #63 + str r12, [sp, #4*16+3*4] + + mov r2, r0 + vldmia r2!, {q8-q15} + vmov.u64 q0, #0xffffffff + vmov.u32 q1, q8 + vmov.u32 q2, q12 + vbif.u32 q8, q9, q0 + vbif.u32 q12, q13, q0 + vbif.u32 q9, q10, q0 + vbif.u32 q13, q14, q0 + vbif.u32 q10, q11, q0 + vbif.u32 q14, q15, q0 + vbif.u32 q11, q1, q0 + vbif.u32 q15, q2, q0 + vldmia r2!, {q0-q7} + vswp.u32 d17, d21 + vswp.u32 d25, d29 + vswp.u32 d18, d22 + vswp.u32 d26, d30 + vstmia r0, {q8-q15} + vmov.u64 q8, #0xffffffff + vmov.u32 q9, q0 + vmov.u32 q10, q4 + vbif.u32 q0, q1, q8 + vbif.u32 q4, q5, q8 + vbif.u32 q1, q2, q8 + vbif.u32 q5, q6, q8 + vbif.u32 q2, q3, q8 + vbif.u32 q6, q7, q8 + vbif.u32 q3, q9, q8 + vbif.u32 q7, q10, q8 + vldmia r2, {q8-q15} + vswp.u32 d1, d5 + vswp.u32 d9, d13 + vswp.u32 d2, d6 + vswp.u32 d10, d14 + add r12, sp, #8*16 + vstmia r12!, {q0-q7} + vmov.u64 q0, #0xffffffff + vmov.u32 q1, q8 + vmov.u32 q2, q12 + vbif.u32 q8, q9, q0 + vbif.u32 q12, q13, q0 + vbif.u32 q9, q10, q0 + vbif.u32 q13, q14, q0 + vbif.u32 q10, q11, q0 + vbif.u32 q14, q15, q0 + vbif.u32 q11, q1, q0 + vbif.u32 q15, q2, q0 + vswp.u32 d17, d21 + vswp.u32 d25, d29 + vswp.u32 d18, d22 + vswp.u32 d26, d30 + vstmia r12, {q8-q15} + + add lr, sp, #128 + vldmia lr, {q0-q7} + add r2, r1, #1024*32*4 + str r0, [sp, #4*16+0*4] + str r2, [sp, #4*16+2*4] +scrypt_core_3way_loop1: + add lr, r0, #16*4 + add r3, r1, #16*4 + str r1, [sp, #4*16+1*4] + mov r12, sp + scrypt_core_macro1a_x4 + scrypt_core_macro1a_x4 + scrypt_core_macro1a_x4 + scrypt_core_macro1a_x4 + sub r1, r1, #4*16 + + add r1, r1, #1024*32*4 + vstmia r1, {q0-q7} + add r3, r1, #1024*32*4 + vstmia r3, {q8-q15} + + add lr, sp, #128 + veor.u32 q0, q0, q4 + veor.u32 q1, q1, q5 + veor.u32 q2, q2, q6 + veor.u32 q3, q3, q7 + vstmia lr, {q0-q3} + veor.u32 q8, q8, q12 + veor.u32 q9, q9, q13 + veor.u32 q10, q10, q14 + veor.u32 q11, q11, q15 + add r12, sp, #256 + vstmia r12, {q8-q11} + + salsa8_core_3way + + ldr r0, [sp, #4*16+0*4] + mov r12, sp + add r2, r0, #16*4 + scrypt_core_macro2_x4 + scrypt_core_macro2_x4 + scrypt_core_macro2_x4 + scrypt_core_macro2_x4 + + add lr, sp, #128 + vldmia lr, {q4-q7} + vadd.u32 q4, q4, q0 + vadd.u32 q5, q5, q1 + vadd.u32 q6, q6, q2 + vadd.u32 q7, q7, q3 + add r12, sp, #256 + vldmia r12, {q0-q3} + vstmia lr, {q4-q7} + vadd.u32 q8, q8, q0 + vadd.u32 q9, q9, q1 + vadd.u32 q10, q10, q2 + vadd.u32 q11, q11, q3 + + add r4, sp, #128+4*16 + vldmia r4, {q0-q3} + vstmia r12, {q8-q11} + veor.u32 q0, q0, q4 + veor.u32 q1, q1, q5 + veor.u32 q2, q2, q6 + veor.u32 q3, q3, q7 + vstmia r4, {q0-q3} + veor.u32 q8, q8, q12 + veor.u32 q9, q9, q13 + veor.u32 q10, q10, q14 + veor.u32 q11, q11, q15 + vmov q12, q8 + vmov q13, q9 + vmov q14, q10 + vmov q15, q11 + + salsa8_core_3way + + ldr r0, [sp, #4*16+0*4] + mov r1, sp + add r0, r0, #16*4 + scrypt_core_macro3_x6 + scrypt_core_macro3_x6 + scrypt_core_macro3_x4 + sub r0, r0, #8*16 + + ldr r1, [sp, #4*16+1*4] + ldr r2, [sp, #4*16+2*4] + add lr, sp, #128 + add r4, sp, #128+4*16 + vldmia r4, {q4-q7} + vadd.u32 q4, q4, q0 + vadd.u32 q5, q5, q1 + vadd.u32 q6, q6, q2 + vadd.u32 q7, q7, q3 + vstmia r4, {q4-q7} + vldmia lr, {q0-q3} + vadd.u32 q12, q12, q8 + vadd.u32 q13, q13, q9 + vadd.u32 q14, q14, q10 + vadd.u32 q15, q15, q11 + add r12, sp, #256 + vldmia r12, {q8-q11} + + add r1, r1, #8*16 + cmp r1, r2 + bne scrypt_core_3way_loop1 + + add r5, sp, #256+4*16 + vstmia r5, {q12-q15} + + sub r1, r1, #1024*32*4 + str r1, [sp, #4*16+1*4] + mov r2, #1024 +scrypt_core_3way_loop2: + str r2, [sp, #4*16+2*4] + + ldr r0, [sp, #4*16+0*4] + ldr r1, [sp, #4*16+1*4] + ldr r4, [r0, #16*4] + mov r4, r4, lsl #32-10 + add r1, r1, r4, lsr #32-10-7 + add r2, r0, #16*4 + add r3, r1, #16*4 + mov r12, sp + scrypt_core_macro1b_x4 + scrypt_core_macro1b_x4 + scrypt_core_macro1b_x4 + scrypt_core_macro1b_x4 + + ldr r1, [sp, #4*16+1*4] + add r1, r1, #1024*32*4 + add r3, r1, #1024*32*4 + vmov r6, r7, d8 + mov r6, r6, lsl #32-10 + add r6, r1, r6, lsr #32-10-7 + vmov r7, r8, d24 + add lr, sp, #128 + vldmia lr, {q0-q3} + pld [r6] + pld [r6, #8*4] + pld [r6, #16*4] + pld [r6, #24*4] + vldmia r6, {q8-q15} + mov r7, r7, lsl #32-10 + add r7, r3, r7, lsr #32-10-7 + veor.u32 q8, q8, q0 + veor.u32 q9, q9, q1 + veor.u32 q10, q10, q2 + veor.u32 q11, q11, q3 + pld [r7] + pld [r7, #8*4] + pld [r7, #16*4] + pld [r7, #24*4] + veor.u32 q12, q12, q4 + veor.u32 q13, q13, q5 + veor.u32 q14, q14, q6 + veor.u32 q15, q15, q7 + vldmia r7, {q0-q7} + vstmia lr, {q8-q15} + add r12, sp, #256 + vldmia r12, {q8-q15} + veor.u32 q8, q8, q0 + veor.u32 q9, q9, q1 + veor.u32 q10, q10, q2 + veor.u32 q11, q11, q3 + veor.u32 q12, q12, q4 + veor.u32 q13, q13, q5 + veor.u32 q14, q14, q6 + veor.u32 q15, q15, q7 + + vldmia lr, {q0-q7} + veor.u32 q0, q0, q4 + veor.u32 q1, q1, q5 + veor.u32 q2, q2, q6 + veor.u32 q3, q3, q7 + vstmia lr, {q0-q3} + veor.u32 q8, q8, q12 + veor.u32 q9, q9, q13 + veor.u32 q10, q10, q14 + veor.u32 q11, q11, q15 + vstmia r12, {q8-q15} + + salsa8_core_3way + + ldr r0, [sp, #4*16+0*4] + mov r12, sp + add r2, r0, #16*4 + scrypt_core_macro2_x4 + scrypt_core_macro2_x4 + scrypt_core_macro2_x4 + scrypt_core_macro2_x4 + + add lr, sp, #128 + vldmia lr, {q4-q7} + vadd.u32 q4, q4, q0 + vadd.u32 q5, q5, q1 + vadd.u32 q6, q6, q2 + vadd.u32 q7, q7, q3 + add r12, sp, #256 + vldmia r12, {q12-q15} + vstmia lr, {q4-q7} + vadd.u32 q12, q12, q8 + vadd.u32 q13, q13, q9 + vadd.u32 q14, q14, q10 + vadd.u32 q15, q15, q11 + + add r4, sp, #128+4*16 + vldmia r4, {q0-q3} + vstmia r12, {q12-q15} + veor.u32 q0, q0, q4 + veor.u32 q1, q1, q5 + veor.u32 q2, q2, q6 + veor.u32 q3, q3, q7 + add r5, sp, #256+4*16 + vldmia r5, {q8-q11} + vstmia r4, {q0-q3} + veor.u32 q8, q8, q12 + veor.u32 q9, q9, q13 + veor.u32 q10, q10, q14 + veor.u32 q11, q11, q15 + vmov q12, q8 + vmov q13, q9 + vmov q14, q10 + vmov q15, q11 + + salsa8_core_3way + + ldr r0, [sp, #4*16+0*4] + ldr r3, [sp, #4*16+1*4] + mov r1, sp + add r0, r0, #16*4 + scrypt_core_macro3_x4 + mov r4, r4, lsl #32-10 + add r3, r3, r4, lsr #32-10-7 + pld [r3, #16*4] + pld [r3] + pld [r3, #24*4] + pld [r3, #8*4] + scrypt_core_macro3_x6 + scrypt_core_macro3_x6 + + add lr, sp, #128 + add r4, sp, #128+4*16 + vldmia r4, {q4-q7} + vadd.u32 q4, q4, q0 + vadd.u32 q5, q5, q1 + vadd.u32 q6, q6, q2 + vadd.u32 q7, q7, q3 + vstmia r4, {q4-q7} + vadd.u32 q12, q12, q8 + vadd.u32 q13, q13, q9 + vadd.u32 q14, q14, q10 + vadd.u32 q15, q15, q11 + add r5, sp, #256+4*16 + vstmia r5, {q12-q15} + + ldr r2, [sp, #4*16+2*4] + subs r2, r2, #1 + bne scrypt_core_3way_loop2 + + ldr r0, [sp, #4*16+0*4] + vldmia r0, {q8-q15} + vmov.u64 q0, #0xffffffff + vmov.u32 q1, q8 + vmov.u32 q2, q12 + vbif.u32 q8, q9, q0 + vbif.u32 q12, q13, q0 + vbif.u32 q9, q10, q0 + vbif.u32 q13, q14, q0 + vbif.u32 q10, q11, q0 + vbif.u32 q14, q15, q0 + vbif.u32 q11, q1, q0 + vbif.u32 q15, q2, q0 + add r12, sp, #8*16 + vldmia r12!, {q0-q7} + vswp.u32 d17, d21 + vswp.u32 d25, d29 + vswp.u32 d18, d22 + vswp.u32 d26, d30 + vstmia r0!, {q8-q15} + vmov.u64 q8, #0xffffffff + vmov.u32 q9, q0 + vmov.u32 q10, q4 + vbif.u32 q0, q1, q8 + vbif.u32 q4, q5, q8 + vbif.u32 q1, q2, q8 + vbif.u32 q5, q6, q8 + vbif.u32 q2, q3, q8 + vbif.u32 q6, q7, q8 + vbif.u32 q3, q9, q8 + vbif.u32 q7, q10, q8 + vldmia r12, {q8-q15} + vswp.u32 d1, d5 + vswp.u32 d9, d13 + vswp.u32 d2, d6 + vswp.u32 d10, d14 + vstmia r0!, {q0-q7} + vmov.u64 q0, #0xffffffff + vmov.u32 q1, q8 + vmov.u32 q2, q12 + vbif.u32 q8, q9, q0 + vbif.u32 q12, q13, q0 + vbif.u32 q9, q10, q0 + vbif.u32 q13, q14, q0 + vbif.u32 q10, q11, q0 + vbif.u32 q14, q15, q0 + vbif.u32 q11, q1, q0 + vbif.u32 q15, q2, q0 + vswp.u32 d17, d21 + vswp.u32 d25, d29 + vswp.u32 d18, d22 + vswp.u32 d26, d30 + vstmia r0, {q8-q15} + + ldr sp, [sp, #4*16+3*4] + vpop {q4-q7} + ldmfd sp!, {r4-r11, pc} + +#endif /* __ARM_NEON__ */ + #endif diff --git a/scrypt.c b/scrypt.c index aa7a8f8..bc4f512 100644 --- a/scrypt.c +++ b/scrypt.c @@ -273,6 +273,13 @@ void scrypt_core(uint32_t *X, uint32_t *V); #elif defined(__arm__) && defined(__APCS_32__) void scrypt_core(uint32_t *X, uint32_t *V); +#if defined(__ARM_NEON__) +#undef HAVE_SHA256_4WAY +#define SCRYPT_MAX_WAYS 3 +#define HAVE_SCRYPT_3WAY 1 +#define scrypt_best_throughput() 3 +void scrypt_core_3way(uint32_t *X, uint32_t *V); +#endif #else @@ -448,6 +455,34 @@ static void scrypt_1024_1_1_256_4way(const uint32_t *input, #endif /* HAVE_SHA256_4WAY */ #ifdef HAVE_SCRYPT_3WAY + +static void scrypt_1024_1_1_256_3way(const uint32_t *input, + uint32_t *output, uint32_t *midstate, unsigned char *scratchpad) +{ + uint32_t tstate[3 * 8], ostate[3 * 8]; + uint32_t X[3 * 32] __attribute__((aligned(64))); + uint32_t *V; + + V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); + + memcpy(tstate + 0, midstate, 32); + memcpy(tstate + 8, midstate, 32); + memcpy(tstate + 16, midstate, 32); + HMAC_SHA256_80_init(input + 0, tstate + 0, ostate + 0); + HMAC_SHA256_80_init(input + 20, tstate + 8, ostate + 8); + HMAC_SHA256_80_init(input + 40, tstate + 16, ostate + 16); + PBKDF2_SHA256_80_128(tstate + 0, ostate + 0, input + 0, X + 0); + PBKDF2_SHA256_80_128(tstate + 8, ostate + 8, input + 20, X + 32); + PBKDF2_SHA256_80_128(tstate + 16, ostate + 16, input + 40, X + 64); + + scrypt_core_3way(X, V); + + PBKDF2_SHA256_128_32(tstate + 0, ostate + 0, X + 0, output + 0); + PBKDF2_SHA256_128_32(tstate + 8, ostate + 8, X + 32, output + 8); + PBKDF2_SHA256_128_32(tstate + 16, ostate + 16, X + 64, output + 16); +} + +#ifdef HAVE_SHA256_4WAY static void scrypt_1024_1_1_256_12way(const uint32_t *input, uint32_t *output, uint32_t *midstate, unsigned char *scratchpad) { @@ -514,6 +549,8 @@ static void scrypt_1024_1_1_256_12way(const uint32_t *input, } } } +#endif /* HAVE_SHA256_4WAY */ + #endif /* HAVE_SCRYPT_3WAY */ int scanhash_scrypt(int thr_id, uint32_t *pdata, @@ -542,15 +579,20 @@ int scanhash_scrypt(int thr_id, uint32_t *pdata, for (i = 0; i < throughput; i++) data[i * 20 + 19] = ++n; -#ifdef HAVE_SHA256_4WAY +#if defined(HAVE_SHA256_4WAY) if (throughput == 4) scrypt_1024_1_1_256_4way(data, hash, midstate, scratchbuf); else #endif -#ifdef HAVE_SCRYPT_3WAY +#if defined(HAVE_SCRYPT_3WAY) && defined(HAVE_SHA256_4WAY) if (throughput == 12) scrypt_1024_1_1_256_12way(data, hash, midstate, scratchbuf); else +#endif +#if defined(HAVE_SCRYPT_3WAY) + if (throughput == 3) + scrypt_1024_1_1_256_3way(data, hash, midstate, scratchbuf); + else #endif scrypt_1024_1_1_256(data, hash, midstate, scratchbuf); diff --git a/sha2-arm.S b/sha2-arm.S index 873ecba..7ea307c 100644 --- a/sha2-arm.S +++ b/sha2-arm.S @@ -627,4 +627,957 @@ sha256d_ms_finish: ldmfd sp!, {r4-r11, pc} #endif + +#ifdef __ARM_NEON__ + + .text + .code 32 + .align 2 + .globl sha256_init_4way + .globl _sha256_init_4way +#ifdef __ELF__ + .type sha256_init_4way, %function +#endif +sha256_init_4way: +_sha256_init_4way: + adr r12, sha256_4h + vldmia r12, {q8-q15} + vstmia r0, {q8-q15} + bx lr + .align 4 +sha256_4h: + .long 0x6a09e667, 0x6a09e667, 0x6a09e667, 0x6a09e667 + .long 0xbb67ae85, 0xbb67ae85, 0xbb67ae85, 0xbb67ae85 + .long 0x3c6ef372, 0x3c6ef372, 0x3c6ef372, 0x3c6ef372 + .long 0xa54ff53a, 0xa54ff53a, 0xa54ff53a, 0xa54ff53a + .long 0x510e527f, 0x510e527f, 0x510e527f, 0x510e527f + .long 0x9b05688c, 0x9b05688c, 0x9b05688c, 0x9b05688c + .long 0x1f83d9ab, 0x1f83d9ab, 0x1f83d9ab, 0x1f83d9ab + .long 0x5be0cd19, 0x5be0cd19, 0x5be0cd19, 0x5be0cd19 + +.macro sha256_4k + .long 0x428a2f98, 0x428a2f98, 0x428a2f98, 0x428a2f98 + .long 0x71374491, 0x71374491, 0x71374491, 0x71374491 + .long 0xb5c0fbcf, 0xb5c0fbcf, 0xb5c0fbcf, 0xb5c0fbcf + .long 0xe9b5dba5, 0xe9b5dba5, 0xe9b5dba5, 0xe9b5dba5 + .long 0x3956c25b, 0x3956c25b, 0x3956c25b, 0x3956c25b + .long 0x59f111f1, 0x59f111f1, 0x59f111f1, 0x59f111f1 + .long 0x923f82a4, 0x923f82a4, 0x923f82a4, 0x923f82a4 + .long 0xab1c5ed5, 0xab1c5ed5, 0xab1c5ed5, 0xab1c5ed5 + .long 0xd807aa98, 0xd807aa98, 0xd807aa98, 0xd807aa98 + .long 0x12835b01, 0x12835b01, 0x12835b01, 0x12835b01 + .long 0x243185be, 0x243185be, 0x243185be, 0x243185be + .long 0x550c7dc3, 0x550c7dc3, 0x550c7dc3, 0x550c7dc3 + .long 0x72be5d74, 0x72be5d74, 0x72be5d74, 0x72be5d74 + .long 0x80deb1fe, 0x80deb1fe, 0x80deb1fe, 0x80deb1fe + .long 0x9bdc06a7, 0x9bdc06a7, 0x9bdc06a7, 0x9bdc06a7 + .long 0xc19bf174, 0xc19bf174, 0xc19bf174, 0xc19bf174 + .long 0xe49b69c1, 0xe49b69c1, 0xe49b69c1, 0xe49b69c1 + .long 0xefbe4786, 0xefbe4786, 0xefbe4786, 0xefbe4786 + .long 0x0fc19dc6, 0x0fc19dc6, 0x0fc19dc6, 0x0fc19dc6 + .long 0x240ca1cc, 0x240ca1cc, 0x240ca1cc, 0x240ca1cc + .long 0x2de92c6f, 0x2de92c6f, 0x2de92c6f, 0x2de92c6f + .long 0x4a7484aa, 0x4a7484aa, 0x4a7484aa, 0x4a7484aa + .long 0x5cb0a9dc, 0x5cb0a9dc, 0x5cb0a9dc, 0x5cb0a9dc + .long 0x76f988da, 0x76f988da, 0x76f988da, 0x76f988da + .long 0x983e5152, 0x983e5152, 0x983e5152, 0x983e5152 + .long 0xa831c66d, 0xa831c66d, 0xa831c66d, 0xa831c66d + .long 0xb00327c8, 0xb00327c8, 0xb00327c8, 0xb00327c8 + .long 0xbf597fc7, 0xbf597fc7, 0xbf597fc7, 0xbf597fc7 + .long 0xc6e00bf3, 0xc6e00bf3, 0xc6e00bf3, 0xc6e00bf3 + .long 0xd5a79147, 0xd5a79147, 0xd5a79147, 0xd5a79147 + .long 0x06ca6351, 0x06ca6351, 0x06ca6351, 0x06ca6351 + .long 0x14292967, 0x14292967, 0x14292967, 0x14292967 + .long 0x27b70a85, 0x27b70a85, 0x27b70a85, 0x27b70a85 + .long 0x2e1b2138, 0x2e1b2138, 0x2e1b2138, 0x2e1b2138 + .long 0x4d2c6dfc, 0x4d2c6dfc, 0x4d2c6dfc, 0x4d2c6dfc + .long 0x53380d13, 0x53380d13, 0x53380d13, 0x53380d13 + .long 0x650a7354, 0x650a7354, 0x650a7354, 0x650a7354 + .long 0x766a0abb, 0x766a0abb, 0x766a0abb, 0x766a0abb + .long 0x81c2c92e, 0x81c2c92e, 0x81c2c92e, 0x81c2c92e + .long 0x92722c85, 0x92722c85, 0x92722c85, 0x92722c85 + .long 0xa2bfe8a1, 0xa2bfe8a1, 0xa2bfe8a1, 0xa2bfe8a1 + .long 0xa81a664b, 0xa81a664b, 0xa81a664b, 0xa81a664b + .long 0xc24b8b70, 0xc24b8b70, 0xc24b8b70, 0xc24b8b70 + .long 0xc76c51a3, 0xc76c51a3, 0xc76c51a3, 0xc76c51a3 + .long 0xd192e819, 0xd192e819, 0xd192e819, 0xd192e819 + .long 0xd6990624, 0xd6990624, 0xd6990624, 0xd6990624 + .long 0xf40e3585, 0xf40e3585, 0xf40e3585, 0xf40e3585 + .long 0x106aa070, 0x106aa070, 0x106aa070, 0x106aa070 + .long 0x19a4c116, 0x19a4c116, 0x19a4c116, 0x19a4c116 + .long 0x1e376c08, 0x1e376c08, 0x1e376c08, 0x1e376c08 + .long 0x2748774c, 0x2748774c, 0x2748774c, 0x2748774c + .long 0x34b0bcb5, 0x34b0bcb5, 0x34b0bcb5, 0x34b0bcb5 + .long 0x391c0cb3, 0x391c0cb3, 0x391c0cb3, 0x391c0cb3 + .long 0x4ed8aa4a, 0x4ed8aa4a, 0x4ed8aa4a, 0x4ed8aa4a + .long 0x5b9cca4f, 0x5b9cca4f, 0x5b9cca4f, 0x5b9cca4f + .long 0x682e6ff3, 0x682e6ff3, 0x682e6ff3, 0x682e6ff3 + .long 0x748f82ee, 0x748f82ee, 0x748f82ee, 0x748f82ee + .long 0x78a5636f, 0x78a5636f, 0x78a5636f, 0x78a5636f + .long 0x84c87814, 0x84c87814, 0x84c87814, 0x84c87814 + .long 0x8cc70208, 0x8cc70208, 0x8cc70208, 0x8cc70208 + .long 0x90befffa, 0x90befffa, 0x90befffa, 0x90befffa + .long 0xa4506ceb, 0xa4506ceb, 0xa4506ceb, 0xa4506ceb + .long 0xbef9a3f7, 0xbef9a3f7, 0xbef9a3f7, 0xbef9a3f7 + .long 0xc67178f2, 0xc67178f2, 0xc67178f2, 0xc67178f2 +.endm + +.macro sha256_4way_extend_doubleround_core i, rr, rw, ra, rb, ry, rz + vadd.u32 q5, q5, \ra + veor.u32 q4, q4, q0 + vshr.u32 q0, \ry, #19 + vshl.u32 q1, \ry, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 \ra, q6, #7 + vshl.u32 q0, q6, #32-7 + veor.u32 q4, q4, q1 + veor.u32 \ra, \ra, q0 + vshr.u32 q1, \ry, #10 + vshr.u32 q0, q6, #18 + veor.u32 q4, q4, q1 + veor.u32 \ra, \ra, q0 + vshl.u32 q1, q6, #32-18 + vshr.u32 q0, q6, #3 + veor.u32 \ra, \ra, q1 + vadd.u32 q4, q4, q5 + veor.u32 \ra, \ra, q0 + vld1.u32 {q5}, [\rr]! + vadd.u32 \ra, \ra, q4 + + vshr.u32 q4, \rz, #17 + vshl.u32 q0, \rz, #32-17 + vadd.u32 q6, q6, \rb + vst1.u32 {\ra}, [\rw]! + veor.u32 q4, q4, q0 + vshr.u32 q0, \rz, #19 + vshl.u32 q1, \rz, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 \rb, q5, #7 + veor.u32 q4, q4, q1 + vshl.u32 q0, q5, #32-7 + vshr.u32 q1, \rz, #10 + veor.u32 \rb, \rb, q0 + vshr.u32 q0, q5, #18 + veor.u32 q4, q4, q1 + veor.u32 \rb, \rb, q0 + vshl.u32 q1, q5, #32-18 + vshr.u32 q0, q5, #3 + veor.u32 \rb, \rb, q1 + vadd.u32 q1, q6, q4 + veor.u32 \rb, \rb, q0 +.endm + +.macro sha256_4way_extend_doubleround_head i, rr, rw, ra, rb, ry, rz + vld1.u32 {q6}, [\rr]! + vshr.u32 q4, \ry, #17 + vshl.u32 q0, \ry, #32-17 + sha256_4way_extend_doubleround_core \i, \rr, \rw, \ra, \rb, \ry, \rz + vld1.u32 {q6}, [\rr]! + vadd.u32 \rb, \rb, q1 +.endm + +.macro sha256_4way_extend_doubleround_body i, rr, rw, ra, rb, ry, rz + vshr.u32 q4, \ry, #17 + vshl.u32 q0, \ry, #32-17 + vst1.u32 {\rz}, [\rw]! + sha256_4way_extend_doubleround_core \i, \rr, \rw, \ra, \rb, \ry, \rz + vld1.u32 {q6}, [\rr]! + vadd.u32 \rb, \rb, q1 +.endm + +.macro sha256_4way_extend_doubleround_foot i, rr, rw, ra, rb, ry, rz + vshr.u32 q4, \ry, #17 + vshl.u32 q0, \ry, #32-17 + vst1.u32 {\rz}, [\rw]! + sha256_4way_extend_doubleround_core \i, \rr, \rw, \ra, \rb, \ry, \rz + vadd.u32 \rb, \rb, q1 + vst1.u32 {\rb}, [\rw]! +.endm + +.macro sha256_4way_main_round i, rk, rw, ra, rb, rc, rd, re, rf, rg, rh + vld1.u32 {q8}, [\rw]! + vand.u32 q9, \rf, \re + vbic.u32 q10, \rg, \re + vshr.u32 q11, \re, #5 + vorr.u32 q10, q10, q9 + vld1.u32 {q9}, [\rk]! + vadd.u32 \rh, \rh, q10 + vshl.u32 q12, \re, #32-5 + veor.u32 q10, \re, q11 + vshr.u32 q11, \re, #19 + veor.u32 q10, q10, q12 + vshl.u32 q12, \re, #32-19 + veor.u32 q10, q10, q11 + vadd.u32 \rh, \rh, q8 + veor.u32 q10, q10, q12 + vadd.u32 \rh, \rh, q9 + veor.u32 q9, \ra, \rb + vshr.u32 q11, q10, #6 + vshl.u32 q13, q10, #32-6 + vadd.u32 \rh, \rh, q11 + + vshr.u32 q11, \ra, #11 + vshl.u32 q12, \ra, #32-11 + veor.u32 q8, \ra, q11 + vand.u32 q10, \ra, \rb + veor.u32 q8, q8, q12 + vshr.u32 q11, \ra, #20 + vshl.u32 q12, \ra, #32-20 + veor.u32 q8, q8, q11 + vand.u32 q9, q9, \rc + veor.u32 q8, q8, q12 + vadd.u32 \rh, \rh, q13 + veor.u32 q10, q10, q9 + vshr.u32 q11, q8, #2 + vshl.u32 q12, q8, #32-2 + vadd.u32 q9, \rh, q10 + vadd.u32 q12, q12, q11 + vadd.u32 \rh, \rh, \rd + vadd.u32 \rd, q9, q12 +.endm + +.macro sha256_4way_main_quadround i, rk, rw + sha256_4way_main_round \i+0, \rk, \rw, q0, q1, q2, q3, q4, q5, q6, q7 + sha256_4way_main_round \i+1, \rk, \rw, q3, q0, q1, q2, q7, q4, q5, q6 + sha256_4way_main_round \i+2, \rk, \rw, q2, q3, q0, q1, q6, q7, q4, q5 + sha256_4way_main_round \i+3, \rk, \rw, q1, q2, q3, q0, q5, q6, q7, q4 +.endm + + + .text + .code 32 + .align 2 + .globl sha256_transform_4way + .globl _sha256_transform_4way +#ifdef __ELF__ + .type sha256_transform_4way, %function +#endif +sha256_transform_4way: +_sha256_transform_4way: + stmfd sp!, {r4, lr} + vpush {q4-q7} + mov r12, sp + sub sp, sp, #64*16 + bic sp, sp, #63 + cmp r2, #0 + bne sha256_transform_4way_swap + + vldmia r1!, {q0-q7} + vstmia sp, {q0-q7} + add r3, sp, #8*16 + vldmia r1, {q8-q15} + vstmia r3, {q8-q15} + b sha256_transform_4way_extend + +sha256_transform_4way_swap: + vldmia r1!, {q0-q7} + vrev32.8 q0, q0 + vrev32.8 q1, q1 + vrev32.8 q2, q2 + vrev32.8 q3, q3 + vldmia r1, {q8-q15} + vrev32.8 q4, q4 + vrev32.8 q5, q5 + vrev32.8 q6, q6 + vrev32.8 q7, q7 + vstmia sp, {q0-q7} + vrev32.8 q8, q8 + vrev32.8 q9, q9 + vrev32.8 q10, q10 + vrev32.8 q11, q11 + vrev32.8 q12, q12 + vrev32.8 q13, q13 + vrev32.8 q14, q14 + vrev32.8 q15, q15 + add r3, sp, #8*16 + vstmia r3, {q8-q15} + +sha256_transform_4way_extend: + add r1, sp, #1*16 + add r2, sp, #16*16 + vmov.u32 q5, q0 + sha256_4way_extend_doubleround_head 0, r1, r2, q9, q10, q14, q15 + sha256_4way_extend_doubleround_body 2, r1, r2, q11, q12, q9, q10 + sha256_4way_extend_doubleround_body 4, r1, r2, q13, q14, q11, q12 + sha256_4way_extend_doubleround_body 6, r1, r2, q15, q9, q13, q14 + sha256_4way_extend_doubleround_body 8, r1, r2, q10, q11, q15, q9 + sha256_4way_extend_doubleround_body 10, r1, r2, q12, q13, q10, q11 + sha256_4way_extend_doubleround_body 12, r1, r2, q14, q15, q12, q13 + sha256_4way_extend_doubleround_body 14, r1, r2, q9, q10, q14, q15 + sha256_4way_extend_doubleround_body 16, r1, r2, q11, q12, q9, q10 + sha256_4way_extend_doubleround_body 18, r1, r2, q13, q14, q11, q12 + sha256_4way_extend_doubleround_body 20, r1, r2, q15, q9, q13, q14 + sha256_4way_extend_doubleround_body 22, r1, r2, q10, q11, q15, q9 + sha256_4way_extend_doubleround_body 24, r1, r2, q12, q13, q10, q11 + sha256_4way_extend_doubleround_body 26, r1, r2, q14, q15, q12, q13 + sha256_4way_extend_doubleround_body 28, r1, r2, q9, q10, q14, q15 + sha256_4way_extend_doubleround_body 30, r1, r2, q11, q12, q9, q10 + sha256_4way_extend_doubleround_body 32, r1, r2, q13, q14, q11, q12 + sha256_4way_extend_doubleround_body 34, r1, r2, q15, q9, q13, q14 + sha256_4way_extend_doubleround_body 36, r1, r2, q10, q11, q15, q9 + sha256_4way_extend_doubleround_body 38, r1, r2, q12, q13, q10, q11 + sha256_4way_extend_doubleround_body 40, r1, r2, q14, q15, q12, q13 + sha256_4way_extend_doubleround_body 42, r1, r2, q9, q10, q14, q15 + sha256_4way_extend_doubleround_body 44, r1, r2, q11, q12, q9, q10 + sha256_4way_extend_doubleround_foot 46, r1, r2, q13, q14, q11, q12 + + vldmia r0, {q0-q7} + adr r4, sha256_transform_4way_4k + b sha256_transform_4way_4k_over + .align 4 +sha256_transform_4way_4k: + sha256_4k +sha256_transform_4way_4k_over: + sha256_4way_main_quadround 0, r4, sp + sha256_4way_main_quadround 4, r4, sp + sha256_4way_main_quadround 8, r4, sp + sha256_4way_main_quadround 12, r4, sp + sha256_4way_main_quadround 16, r4, sp + sha256_4way_main_quadround 20, r4, sp + sha256_4way_main_quadround 24, r4, sp + sha256_4way_main_quadround 28, r4, sp + sha256_4way_main_quadround 32, r4, sp + sha256_4way_main_quadround 36, r4, sp + sha256_4way_main_quadround 40, r4, sp + sha256_4way_main_quadround 44, r4, sp + sha256_4way_main_quadround 48, r4, sp + sha256_4way_main_quadround 52, r4, sp + sha256_4way_main_quadround 56, r4, sp + sha256_4way_main_quadround 60, r4, sp + + vldmia r0, {q8-q15} + vadd.u32 q0, q0, q8 + vadd.u32 q1, q1, q9 + vadd.u32 q2, q2, q10 + vadd.u32 q3, q3, q11 + vadd.u32 q4, q4, q12 + vadd.u32 q5, q5, q13 + vadd.u32 q6, q6, q14 + vadd.u32 q7, q7, q15 + vstmia r0, {q0-q7} + + mov sp, r12 + vpop {q4-q7} + ldmfd sp!, {r4, pc} + + + .text + .code 32 + .align 2 + .globl sha256d_ms_4way + .globl _sha256d_ms_4way +#ifdef __ELF__ + .type sha256d_ms_4way, %function +#endif +sha256d_ms_4way: +_sha256d_ms_4way: + stmfd sp!, {r4, lr} + vpush {q4-q7} + mov r12, sp + sub sp, sp, #64*16 + bic sp, sp, #63 + + add r4, r1, #3*16 + vld1.u32 {q6}, [r4]! + add r1, r1, #18*16 + vldmia r1, {q11-q13} + cmp r0, r0 + + vshr.u32 q10, q6, #7 + vshl.u32 q0, q6, #32-7 + vshr.u32 q1, q6, #18 + veor.u32 q10, q10, q0 + vshl.u32 q0, q6, #32-18 + veor.u32 q10, q10, q1 + vshr.u32 q1, q6, #3 + veor.u32 q10, q10, q0 + vstmia sp!, {q11-q13} + veor.u32 q4, q10, q1 + vadd.u32 q12, q12, q6 + vadd.u32 q11, q11, q4 + + vshr.u32 q14, q12, #17 + vshr.u32 q4, q11, #17 + vshl.u32 q0, q11, #32-17 + vst1.u32 {q11}, [r1]! + veor.u32 q4, q4, q0 + vshr.u32 q0, q11, #19 + vshl.u32 q1, q11, #32-19 + veor.u32 q4, q4, q0 + vst1.u32 {q12}, [r1]! + veor.u32 q4, q4, q1 + vshr.u32 q1, q11, #10 + vshl.u32 q0, q12, #32-17 + veor.u32 q4, q4, q1 + veor.u32 q14, q14, q0 + vadd.u32 q13, q13, q4 + vshr.u32 q0, q12, #19 + vshl.u32 q1, q12, #32-19 + veor.u32 q14, q14, q0 + vst1.u32 {q13}, [r1]! + veor.u32 q14, q14, q1 + vshr.u32 q1, q12, #10 + + vshr.u32 q4, q13, #17 + vshl.u32 q0, q13, #32-17 + veor.u32 q14, q14, q1 + veor.u32 q4, q4, q0 + vshr.u32 q0, q13, #19 + vshl.u32 q1, q13, #32-19 + veor.u32 q4, q4, q0 + vst1.u32 {q14}, [r1]! + veor.u32 q4, q4, q1 + vshr.u32 q1, q13, #10 + vld1.u32 {q15}, [r1] + veor.u32 q4, q4, q1 + vst1.u32 {q15}, [sp]! + vadd.u32 q15, q15, q4 + vshr.u32 q4, q14, #17 + vshl.u32 q0, q14, #32-17 + vshl.u32 q1, q14, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 q0, q14, #19 + vst1.u32 {q15}, [r1]! + veor.u32 q4, q4, q0 + vld1.u32 {q9}, [r1] + veor.u32 q4, q4, q1 + vshr.u32 q1, q14, #10 + vst1.u32 {q9}, [sp]! + veor.u32 q5, q4, q1 + + vshr.u32 q4, q15, #17 + vadd.u32 q9, q9, q5 + vshl.u32 q0, q15, #32-17 + vshl.u32 q1, q15, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 q0, q15, #19 + vst1.u32 {q9}, [r1]! + veor.u32 q4, q4, q0 + vld1.u32 {q10}, [r1] + veor.u32 q4, q4, q1 + vshr.u32 q1, q15, #10 + vst1.u32 {q10}, [sp]! + veor.u32 q4, q4, q1 + vshl.u32 q0, q9, #32-17 + vadd.u32 q10, q10, q4 + vshr.u32 q4, q9, #17 + vshl.u32 q1, q9, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 q0, q9, #19 + veor.u32 q4, q4, q1 + vshr.u32 q1, q9, #10 + veor.u32 q4, q4, q0 + vst1.u32 {q10}, [r1]! + veor.u32 q5, q4, q1 + + vshr.u32 q4, q10, #17 + vshl.u32 q0, q10, #32-17 + vadd.u32 q11, q11, q5 + veor.u32 q4, q4, q0 + vshr.u32 q0, q10, #19 + vshl.u32 q1, q10, #32-19 + veor.u32 q4, q4, q0 + vst1.u32 {q11}, [r1]! + veor.u32 q4, q4, q1 + vshr.u32 q1, q10, #10 + vshl.u32 q0, q11, #32-17 + veor.u32 q2, q4, q1 + vshr.u32 q4, q11, #17 + vadd.u32 q12, q12, q2 + vshl.u32 q1, q11, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 q0, q11, #19 + veor.u32 q4, q4, q1 + vshr.u32 q1, q11, #10 + veor.u32 q4, q4, q0 + vst1.u32 {q12}, [r1]! + veor.u32 q5, q4, q1 + + vshr.u32 q4, q12, #17 + vshl.u32 q0, q12, #32-17 + vadd.u32 q13, q13, q5 + veor.u32 q4, q4, q0 + vshr.u32 q0, q12, #19 + vshl.u32 q1, q12, #32-19 + veor.u32 q4, q4, q0 + vst1.u32 {q13}, [r1]! + veor.u32 q4, q4, q1 + vshr.u32 q1, q12, #10 + vshl.u32 q0, q13, #32-17 + veor.u32 q2, q4, q1 + vshr.u32 q4, q13, #17 + vadd.u32 q14, q14, q2 + vshl.u32 q1, q13, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 q0, q13, #19 + veor.u32 q4, q4, q1 + vshr.u32 q1, q13, #10 + veor.u32 q4, q4, q0 + vst1.u32 {q14}, [r1]! + veor.u32 q5, q4, q1 + add r4, r4, #12*16 + + vshr.u32 q4, q14, #17 + vshl.u32 q0, q14, #32-17 + vadd.u32 q15, q15, q5 + veor.u32 q4, q4, q0 + vshr.u32 q0, q14, #19 + vshl.u32 q1, q14, #32-19 + veor.u32 q4, q4, q0 + vst1.u32 {q15}, [r1]! + veor.u32 q4, q4, q1 + vshr.u32 q1, q14, #10 + vld1.u32 {q2}, [r1] + veor.u32 q4, q4, q1 + vshl.u32 q0, q15, #32-17 + vadd.u32 q9, q9, q4 + vst1.u32 {q2}, [sp]! + vadd.u32 q9, q9, q2 + vshr.u32 q4, q15, #17 + vshr.u32 q2, q15, #19 + veor.u32 q4, q4, q0 + vst1.u32 {q9}, [r1]! + vshl.u32 q1, q15, #32-19 + veor.u32 q4, q4, q2 + vshr.u32 q0, q15, #10 + veor.u32 q4, q4, q1 + vld1.u32 {q5-q6}, [r4]! + veor.u32 q4, q4, q0 + vld1.u32 {q2}, [r1] + vadd.u32 q10, q10, q4 + vst1.u32 {q2}, [sp]! + vadd.u32 q10, q10, q2 + + sub sp, sp, #8*16 + +sha256d_ms_4way_extend_loop2: + sha256_4way_extend_doubleround_body 16, r4, r1, q11, q12, q9, q10 + sha256_4way_extend_doubleround_body 18, r4, r1, q13, q14, q11, q12 + sha256_4way_extend_doubleround_body 20, r4, r1, q15, q9, q13, q14 + sha256_4way_extend_doubleround_body 22, r4, r1, q10, q11, q15, q9 + sha256_4way_extend_doubleround_body 24, r4, r1, q12, q13, q10, q11 + sha256_4way_extend_doubleround_body 26, r4, r1, q14, q15, q12, q13 + sha256_4way_extend_doubleround_body 28, r4, r1, q9, q10, q14, q15 + sha256_4way_extend_doubleround_body 30, r4, r1, q11, q12, q9, q10 + sha256_4way_extend_doubleround_body 32, r4, r1, q13, q14, q11, q12 + sha256_4way_extend_doubleround_body 34, r4, r1, q15, q9, q13, q14 + sha256_4way_extend_doubleround_body 36, r4, r1, q10, q11, q15, q9 + sha256_4way_extend_doubleround_body 38, r4, r1, q12, q13, q10, q11 + sha256_4way_extend_doubleround_body 40, r4, r1, q14, q15, q12, q13 + sha256_4way_extend_doubleround_body 42, r4, r1, q9, q10, q14, q15 + sha256_4way_extend_doubleround_body 44, r4, r1, q11, q12, q9, q10 + sha256_4way_extend_doubleround_foot 46, r4, r1, q13, q14, q11, q12 + bne sha256d_ms_4way_extend_coda2 + + vldmia r3!, {q4-q7} + vldmia r3, {q0-q3} + vswp q0, q4 + adr r3, sha256d_ms_4way_4k+3*16 + sub r1, r1, #(64-3)*16 + b sha256d_ms_4way_main_loop1 + + .align 4 +sha256d_ms_4way_4k: + sha256_4k + +sha256d_ms_4way_main_loop2: + sha256_4way_main_round 0, r3, r1, q0, q1, q2, q3, q4, q5, q6, q7 + sha256_4way_main_round 1, r3, r1, q3, q0, q1, q2, q7, q4, q5, q6 + sha256_4way_main_round 2, r3, r1, q2, q3, q0, q1, q6, q7, q4, q5 +sha256d_ms_4way_main_loop1: + sha256_4way_main_round 3, r3, r1, q1, q2, q3, q0, q5, q6, q7, q4 + sha256_4way_main_quadround 4, r3, r1 + sha256_4way_main_quadround 8, r3, r1 + sha256_4way_main_quadround 12, r3, r1 + sha256_4way_main_quadround 16, r3, r1 + sha256_4way_main_quadround 20, r3, r1 + sha256_4way_main_quadround 24, r3, r1 + sha256_4way_main_quadround 28, r3, r1 + sha256_4way_main_quadround 32, r3, r1 + sha256_4way_main_quadround 36, r3, r1 + sha256_4way_main_quadround 40, r3, r1 + sha256_4way_main_quadround 44, r3, r1 + sha256_4way_main_quadround 48, r3, r1 + sha256_4way_main_quadround 52, r3, r1 + sha256_4way_main_round 56, r3, r1, q0, q1, q2, q3, q4, q5, q6, q7 + bne sha256d_ms_4way_finish + sha256_4way_main_round 57, r3, r1, q3, q0, q1, q2, q7, q4, q5, q6 + sha256_4way_main_round 58, r3, r1, q2, q3, q0, q1, q6, q7, q4, q5 + sha256_4way_main_round 59, r3, r1, q1, q2, q3, q0, q5, q6, q7, q4 + sha256_4way_main_quadround 60, r3, r1 + + vldmia r2, {q8-q15} + vadd.u32 q0, q0, q8 + vadd.u32 q1, q1, q9 + vadd.u32 q2, q2, q10 + vadd.u32 q3, q3, q11 + vadd.u32 q4, q4, q12 + vadd.u32 q5, q5, q13 + vadd.u32 q6, q6, q14 + vadd.u32 q7, q7, q15 + + vldmia sp, {q8-q15} + sub r1, r1, #(64-18)*16 + vstmia r1, {q8-q10} + add r1, r1, #4*16 + vstmia r1, {q11-q13} + add r1, r1, #8*16 + vstmia r1, {q14-q15} + + vstmia sp, {q0-q7} + vmov.u32 q8, #0x80000000 + vmov.u32 q9, #0 + vmov.u32 q10, #0 + vmov.u32 q11, #0 + vmov.u32 q12, #0 + vmov.u32 q13, #0 + vmov.u32 q14, #0 + vmov.u32 q15, #0x00000100 + add r1, sp, #8*16 + vstmia r1!, {q8-q15} + adds r4, sp, #2*16 + + vshr.u32 q9, q1, #7 + vshl.u32 q2, q1, #32-7 + vshr.u32 q4, q1, #18 + veor.u32 q9, q9, q2 + vshl.u32 q3, q1, #32-18 + veor.u32 q9, q9, q4 + vshr.u32 q2, q1, #3 + veor.u32 q9, q9, q3 + vld1.u32 {q5}, [r4]! + veor.u32 q9, q9, q2 + vmov.u32 q7, #0x00a00000 + vadd.u32 q9, q9, q0 + vshr.u32 q10, q5, #7 + vshl.u32 q0, q5, #32-7 + vshl.u32 q3, q5, #32-18 + veor.u32 q10, q10, q0 + vshr.u32 q0, q5, #18 + veor.u32 q10, q10, q3 + vst1.u32 {q9}, [r1]! + vadd.u32 q3, q1, q7 + veor.u32 q10, q10, q0 + vshr.u32 q0, q5, #3 + vld1.u32 {q6}, [r4]! + veor.u32 q10, q10, q0 + + vshr.u32 q4, q9, #17 + vshl.u32 q0, q9, #32-17 + vadd.u32 q10, q10, q3 + veor.u32 q4, q4, q0 + vshr.u32 q0, q9, #19 + vshl.u32 q1, q9, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 q11, q6, #7 + vshl.u32 q0, q6, #32-7 + veor.u32 q4, q4, q1 + veor.u32 q11, q11, q0 + vshr.u32 q1, q9, #10 + vshr.u32 q0, q6, #18 + veor.u32 q4, q4, q1 + veor.u32 q11, q11, q0 + vshl.u32 q1, q6, #32-18 + vshr.u32 q0, q6, #3 + veor.u32 q11, q11, q1 + vadd.u32 q4, q4, q5 + veor.u32 q11, q11, q0 + vld1.u32 {q5}, [r4]! + vadd.u32 q11, q11, q4 + vshr.u32 q4, q10, #17 + vshl.u32 q0, q10, #32-17 + vst1.u32 {q10}, [r1]! + veor.u32 q4, q4, q0 + vshr.u32 q0, q10, #19 + vshl.u32 q1, q10, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 q12, q5, #7 + veor.u32 q4, q4, q1 + vshl.u32 q0, q5, #32-7 + vshr.u32 q1, q10, #10 + veor.u32 q12, q12, q0 + vshr.u32 q0, q5, #18 + veor.u32 q4, q4, q1 + veor.u32 q12, q12, q0 + vshl.u32 q1, q5, #32-18 + vst1.u32 {q11}, [r1]! + veor.u32 q12, q12, q1 + vshr.u32 q0, q5, #3 + vadd.u32 q1, q6, q4 + veor.u32 q12, q12, q0 + + vshr.u32 q4, q11, #17 + vshl.u32 q0, q11, #32-17 + vadd.u32 q12, q12, q1 + vld1.u32 {q6}, [r4]! + veor.u32 q4, q4, q0 + vshr.u32 q0, q11, #19 + vshl.u32 q1, q11, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 q13, q6, #7 + vshl.u32 q0, q6, #32-7 + veor.u32 q4, q4, q1 + veor.u32 q13, q13, q0 + vshr.u32 q1, q11, #10 + vshr.u32 q0, q6, #18 + veor.u32 q4, q4, q1 + veor.u32 q13, q13, q0 + vshl.u32 q1, q6, #32-18 + vshr.u32 q0, q6, #3 + veor.u32 q13, q13, q1 + vadd.u32 q4, q4, q5 + veor.u32 q13, q13, q0 + vld1.u32 {q5}, [r4]! + vadd.u32 q13, q13, q4 + vshr.u32 q4, q12, #17 + vshl.u32 q0, q12, #32-17 + vst1.u32 {q12}, [r1]! + veor.u32 q4, q4, q0 + vshr.u32 q0, q12, #19 + vshl.u32 q1, q12, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 q14, q5, #7 + veor.u32 q4, q4, q1 + vshl.u32 q0, q5, #32-7 + vshr.u32 q1, q12, #10 + veor.u32 q14, q14, q0 + vshr.u32 q0, q5, #18 + veor.u32 q4, q4, q1 + veor.u32 q14, q14, q0 + vshl.u32 q1, q5, #32-18 + vst1.u32 {q13}, [r1]! + veor.u32 q14, q14, q1 + vshr.u32 q0, q5, #3 + vadd.u32 q1, q6, q4 + veor.u32 q14, q14, q0 + + vshr.u32 q4, q13, #17 + vshl.u32 q0, q13, #32-17 + vadd.u32 q14, q14, q1 + vld1.u32 {q6}, [r4]! + vadd.u32 q5, q5, q15 + veor.u32 q4, q4, q0 + vshr.u32 q0, q13, #19 + vshl.u32 q1, q13, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 q15, q6, #7 + vshl.u32 q0, q6, #32-7 + veor.u32 q4, q4, q1 + veor.u32 q15, q15, q0 + vshr.u32 q1, q13, #10 + vshr.u32 q0, q6, #18 + veor.u32 q4, q4, q1 + veor.u32 q15, q15, q0 + vshl.u32 q1, q6, #32-18 + vshr.u32 q0, q6, #3 + veor.u32 q15, q15, q1 + vadd.u32 q4, q4, q5 + veor.u32 q15, q15, q0 + vmov.u32 q5, #0x80000000 + vadd.u32 q15, q15, q4 + vshr.u32 q4, q14, #17 + vshl.u32 q0, q14, #32-17 + vadd.u32 q6, q6, q9 + vst1.u32 {q14}, [r1]! + vmov.u32 q7, #0x11000000 + veor.u32 q4, q4, q0 + vshr.u32 q0, q14, #19 + vshl.u32 q1, q14, #32-19 + vadd.u32 q6, q6, q7 + vmov.u32 q2, #0x00002000 + veor.u32 q4, q4, q0 + vst1.u32 {q15}, [r1]! + veor.u32 q4, q4, q1 + vshr.u32 q1, q14, #10 + vadd.u32 q6, q6, q2 + veor.u32 q1, q4, q1 + add r4, r4, #8*16 + + vshr.u32 q4, q15, #17 + vshl.u32 q0, q15, #32-17 + vadd.u32 q9, q6, q1 + veor.u32 q4, q4, q0 + vshr.u32 q0, q15, #19 + vshl.u32 q1, q15, #32-19 + veor.u32 q4, q4, q0 + vst1.u32 {q9}, [r1]! + vadd.u32 q5, q5, q10 + veor.u32 q4, q4, q1 + vshr.u32 q1, q15, #10 + vshl.u32 q0, q9, #32-17 + veor.u32 q10, q4, q1 + vshr.u32 q4, q9, #17 + vadd.u32 q10, q10, q5 + veor.u32 q4, q4, q0 + vshr.u32 q0, q9, #19 + vshl.u32 q1, q9, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 q0, q9, #10 + veor.u32 q4, q4, q1 + vst1.u32 {q10}, [r1]! + veor.u32 q1, q4, q0 + + vshr.u32 q4, q10, #17 + vshl.u32 q0, q10, #32-17 + vadd.u32 q11, q11, q1 + veor.u32 q4, q4, q0 + vshr.u32 q0, q10, #19 + vshl.u32 q1, q10, #32-19 + veor.u32 q4, q4, q0 + vst1.u32 {q11}, [r1]! + veor.u32 q4, q4, q1 + vshr.u32 q1, q10, #10 + vshl.u32 q0, q11, #32-17 + veor.u32 q1, q4, q1 + vshr.u32 q4, q11, #17 + vadd.u32 q12, q12, q1 + veor.u32 q4, q4, q0 + vshr.u32 q0, q11, #19 + vshl.u32 q1, q11, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 q0, q11, #10 + veor.u32 q4, q4, q1 + vst1.u32 {q12}, [r1]! + veor.u32 q1, q4, q0 + + vshr.u32 q4, q12, #17 + vshl.u32 q0, q12, #32-17 + vadd.u32 q13, q13, q1 + veor.u32 q4, q4, q0 + vshr.u32 q0, q12, #19 + vshl.u32 q1, q12, #32-19 + veor.u32 q4, q4, q0 + vst1.u32 {q13}, [r1]! + veor.u32 q4, q4, q1 + vshr.u32 q1, q12, #10 + vshl.u32 q0, q13, #32-17 + veor.u32 q1, q4, q1 + vshr.u32 q4, q13, #17 + vadd.u32 q14, q14, q1 + veor.u32 q4, q4, q0 + vshr.u32 q0, q13, #19 + vshl.u32 q1, q13, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 q0, q13, #10 + veor.u32 q4, q4, q1 + vst1.u32 {q14}, [r1]! + veor.u32 q4, q4, q0 + vmov.u32 q6, #0x00000100 + vadd.u32 q15, q15, q4 + + vshr.u32 q4, q14, #17 + vshl.u32 q0, q14, #32-17 + vmov.u32 q7, #0x00400000 + vst1.u32 {q15}, [r1]! + veor.u32 q4, q4, q0 + vshr.u32 q0, q14, #19 + vshl.u32 q1, q14, #32-19 + veor.u32 q4, q4, q0 + vadd.u32 q9, q9, q7 + veor.u32 q4, q4, q1 + vshr.u32 q1, q14, #10 + vmov.u32 q2, #0x00000022 + veor.u32 q4, q4, q1 + vadd.u32 q9, q9, q2 + vld1.u32 {q5}, [r4]! + vadd.u32 q9, q9, q4 + vshr.u32 q4, q15, #17 + vshl.u32 q0, q15, #32-17 + vadd.u32 q6, q6, q10 + vst1.u32 {q9}, [r1]! + veor.u32 q4, q4, q0 + vshr.u32 q0, q15, #19 + vshl.u32 q1, q15, #32-19 + veor.u32 q4, q4, q0 + vshr.u32 q10, q5, #7 + veor.u32 q4, q4, q1 + vshl.u32 q0, q5, #32-7 + vshr.u32 q1, q15, #10 + veor.u32 q10, q10, q0 + vshr.u32 q0, q5, #18 + veor.u32 q4, q4, q1 + veor.u32 q10, q10, q0 + vshl.u32 q1, q5, #32-18 + vshr.u32 q0, q5, #3 + veor.u32 q10, q10, q1 + vadd.u32 q1, q6, q4 + veor.u32 q10, q10, q0 + vld1.u32 {q6}, [r4]! + vadd.u32 q10, q10, q1 + + b sha256d_ms_4way_extend_loop2 + + .align 4 +sha256d_ms_4way_4h: + .long 0x6a09e667, 0x6a09e667, 0x6a09e667, 0x6a09e667 + .long 0xbb67ae85, 0xbb67ae85, 0xbb67ae85, 0xbb67ae85 + .long 0x3c6ef372, 0x3c6ef372, 0x3c6ef372, 0x3c6ef372 + .long 0xa54ff53a, 0xa54ff53a, 0xa54ff53a, 0xa54ff53a + .long 0x510e527f, 0x510e527f, 0x510e527f, 0x510e527f + .long 0x9b05688c, 0x9b05688c, 0x9b05688c, 0x9b05688c + .long 0x1f83d9ab, 0x1f83d9ab, 0x1f83d9ab, 0x1f83d9ab + .long 0x5be0cd19, 0x5be0cd19, 0x5be0cd19, 0x5be0cd19 + +sha256d_ms_4way_extend_coda2: + adr r4, sha256d_ms_4way_4h + mov r1, sp + vldmia r4, {q0-q7} + vmov.u32 q15, q7 + sub r3, r3, #64*16 + b sha256d_ms_4way_main_loop2 + +.macro sha256_4way_main_round_red i, rk, rw, rd, re, rf, rg, rh + vld1.u32 {q8}, [\rw]! + vand.u32 q9, \rf, \re + vbic.u32 q10, \rg, \re + vshr.u32 q11, \re, #5 + vorr.u32 q10, q10, q9 + vshl.u32 q12, \re, #32-5 + vadd.u32 \rh, \rh, q10 + veor.u32 q10, \re, q11 + vshr.u32 q11, \re, #19 + veor.u32 q10, q10, q12 + vshl.u32 q12, \re, #32-19 + veor.u32 q10, q10, q11 + vadd.u32 \rh, \rh, q8 + veor.u32 q10, q10, q12 + vld1.u32 {q9}, [\rk]! + vadd.u32 \rh, \rh, \rd + vshr.u32 q11, q10, #6 + vadd.u32 \rh, \rh, q9 + vshl.u32 q13, q10, #32-6 + vadd.u32 \rh, \rh, q11 + vadd.u32 \rh, \rh, q13 +.endm + +sha256d_ms_4way_finish: + sha256_4way_main_round_red 57, r3, r1, q2, q7, q4, q5, q6 + sha256_4way_main_round_red 58, r3, r1, q1, q6, q7, q4, q5 + sha256_4way_main_round_red 59, r3, r1, q0, q5, q6, q7, q4 + sha256_4way_main_round_red 60, r3, r1, q3, q4, q5, q6, q7 + + vadd.u32 q7, q7, q15 + add r0, r0, #7*16 + vst1.u32 {q7}, [r0] + + mov sp, r12 + vpop {q4-q7} + ldmfd sp!, {r4, pc} + + + .text + .code 32 + .align 2 + .globl sha256_use_4way + .globl _sha256_use_4way +#ifdef __ELF__ + .type sha256_use_4way, %function +#endif +sha256_use_4way: +_sha256_use_4way: + mov r0, #1 + bx lr + +#endif /* __ARM_NEON__ */ + #endif