#include <aarch64/asm.h>
RCSID("$NetBSD: chacha_neon_64.S,v 1.7 2020/09/07 18:05:17 jakllsch Exp $")
#define ROUND(a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r) \
STEP(STEP0,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP1,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP2,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP3,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP4,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP5,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP6,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP7,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP8,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP9,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP10,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP11,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP12,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP13,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP14,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP15,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP16,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP17,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP18,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
STEP(STEP19,a0,b0,c0,d0,a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,t0,t1,t2,t3, r); \
#define STEP(f,a0,a1,a2,a3,b0,b1,b2,b3,c0,c1,c2,c3,d0,d1,d2,d3,t0,t1,t2,t3,r) \
f(a0,b0,c0,d0, t0, r); \
f(a1,b1,c1,d1, t1, r); \
f(a2,b2,c2,d2, t2, r); \
f(a3,b3,c3,d3, t3, r); \
#define STEP0(a,b,c,d, t, r) add a##.4s, a##.4s, b##.4s
#define STEP1(a,b,c,d, t, r) eor d##.16b, d##.16b, a##.16b
#if 0
#define STEP2(a,b,c,d, t, r) shl t##.4s, d##.4s, #16
#define STEP3(a,b,c,d, t, r) ushr d##.4s, d##.4s, #(32 - 16)
#define STEP4(a,b,c,d, t, r) orr d##.16b, d##.16b, t##.16b
#else
#define STEP2(a,b,c,d, t, r) rev32 d##.8h, d##.8h
#define STEP3(a,b,c,d, t, r)
#define STEP4(a,b,c,d, t, r)
#endif
#define STEP5(a,b,c,d, t, r) add c##.4s, c##.4s, d##.4s
#if 0
#define STEP6(a,b,c,d, t, r) eor b##.16b, b##.16b, c##.16b
#define STEP7(a,b,c,d, t, r) shl t##.4s, b##.4s, #12
#define STEP8(a,b,c,d, t, r) ushr b##.4s, b##.4s, #(32 - 12)
#define STEP9(a,b,c,d, t, r) orr b##.16b, b##.16b, t##.16b
#else
#define STEP6(a,b,c,d, t, r) eor t##.16b, b##.16b, c##.16b
#define STEP7(a,b,c,d, t, r) shl b##.4s, t##.4s, #12
#define STEP8(a,b,c,d, t, r) sri b##.4s, t##.4s, #(32 - 12)
#define STEP9(a,b,c,d, t, r)
#endif
#define STEP10(a,b,c,d, t, r) add a##.4s, a##.4s, b##.4s
#define STEP11(a,b,c,d, t, r) eor d##.16b, d##.16b, a##.16b
#if 0
#define STEP12(a,b,c,d, t, r) shl t##.4s, d##.4s, #8
#define STEP13(a,b,c,d, t, r) ushr d##.4s, d##.4s, #(32 - 8)
#define STEP14(a,b,c,d, t, r) orr d##.16b, d##.16b, t##.16b
#else
#define STEP12(a,b,c,d, t, r) tbl d##.16b, {d##.16b}, r##.16b
#define STEP13(a,b,c,d, t, r)
#define STEP14(a,b,c,d, t, r)
#endif
#define STEP15(a,b,c,d, t, r) add c##.4s, c##.4s, d##.4s
#if 0
#define STEP16(a,b,c,d, t, r) eor b##.16b, b##.16b, c##.16b
#define STEP17(a,b,c,d, t, r) shl t##.4s, b##.4s, #7
#define STEP18(a,b,c,d, t, r) ushr b##.4s, b##.4s, #(32 - 7)
#define STEP19(a,b,c,d, t, r) orr b##.16b, b##.16b, t##.16b
#else
#define STEP16(a,b,c,d, t, r) eor t##.16b, b##.16b, c##.16b
#define STEP17(a,b,c,d, t, r) shl b##.4s, t##.4s, #7
#define STEP18(a,b,c,d, t, r) sri b##.4s, t##.4s, #(32 - 7)
#define STEP19(a,b,c,d, t, r)
#endif
#if defined(__AARCH64EB__)
#define HTOLE32(x) rev32 x, x
#define LE32TOH(x) rev32 x, x
#else
#define LE32TOH(x)
#define HTOLE32(x)
#endif
ENTRY(chacha_stream256_neon)
stp fp, lr, [sp, #-0x50]!
mov fp, sp
stp d8, d9, [sp, #0x10]
stp d10, d11, [sp, #0x20]
stp d12, d13, [sp, #0x30]
stp d14, d15, [sp, #0x40]
adrl x9, v0123
mov x10, x4
mov x11, x3
add x12, x3, #16
mov x13, x2
ld1 {v26.4s-v27.4s}, [x9]
dup v12.4s, w1
ld4r {v0.4s-v3.4s}, [x10]
ld4r {v4.4s-v7.4s}, [x11]
ld4r {v8.4s-v11.4s}, [x12]
ld3r {v13.4s-v15.4s}, [x13]
add v12.4s, v12.4s, v26.4s
LE32TOH(v0.16b)
LE32TOH(v1.16b)
LE32TOH(v2.16b)
LE32TOH(v3.16b)
LE32TOH(v4.16b)
LE32TOH(v5.16b)
LE32TOH(v6.16b)
LE32TOH(v7.16b)
LE32TOH(v8.16b)
LE32TOH(v9.16b)
LE32TOH(v10.16b)
LE32TOH(v11.16b)
LE32TOH(v13.16b)
LE32TOH(v14.16b)
LE32TOH(v15.16b)
mov v16.16b, v0.16b
mov v17.16b, v1.16b
mov v18.16b, v2.16b
mov v19.16b, v3.16b
mov v20.16b, v4.16b
mov v21.16b, v5.16b
mov v22.16b, v6.16b
mov v23.16b, v7.16b
mov v24.16b, v8.16b
mov v25.16b, v9.16b
mov v26.16b, v12.16b
mov w8, v10.s[0]
mov w9, v11.s[0]
mov w10, v13.s[0]
mov w11, v14.s[0]
mov w12, v15.s[0]
_ALIGN_TEXT
1: subs w5, w5, #2
ROUND(v0,v1,v2,v3, v4,v5,v6,v7, v8,v9,v10,v11, v12,v13,v14,v15,
v28,v29,v30,v31, v27)
ROUND(v0,v1,v2,v3, v5,v6,v7,v4, v10,v11,v8,v9, v15,v12,v13,v14,
v28,v29,v30,v31, v27)
b.ne 1b
dup v27.4s, w8
dup v28.4s, w9
dup v29.4s, w10
dup v30.4s, w11
dup v31.4s, w12
add v0.4s, v0.4s, v16.4s
add v1.4s, v1.4s, v17.4s
add v2.4s, v2.4s, v18.4s
add v3.4s, v3.4s, v19.4s
add v4.4s, v4.4s, v20.4s
add v5.4s, v5.4s, v21.4s
add v6.4s, v6.4s, v22.4s
add v7.4s, v7.4s, v23.4s
add v8.4s, v8.4s, v24.4s
add v9.4s, v9.4s, v25.4s
add v10.4s, v10.4s, v27.4s
add v11.4s, v11.4s, v28.4s
add v12.4s, v12.4s, v26.4s
add v13.4s, v13.4s, v29.4s
add v14.4s, v14.4s, v30.4s
add v15.4s, v15.4s, v31.4s
HTOLE32(v0.16b)
HTOLE32(v1.16b)
HTOLE32(v2.16b)
HTOLE32(v3.16b)
HTOLE32(v4.16b)
HTOLE32(v5.16b)
HTOLE32(v6.16b)
HTOLE32(v7.16b)
HTOLE32(v8.16b)
HTOLE32(v9.16b)
HTOLE32(v10.16b)
HTOLE32(v11.16b)
HTOLE32(v12.16b)
HTOLE32(v13.16b)
HTOLE32(v14.16b)
HTOLE32(v15.16b)
st4 { v0.s, v1.s, v2.s, v3.s}[0], [x0], #16
st4 { v4.s, v5.s, v6.s, v7.s}[0], [x0], #16
st4 { v8.s, v9.s,v10.s,v11.s}[0], [x0], #16
st4 {v12.s,v13.s,v14.s,v15.s}[0], [x0], #16
st4 { v0.s, v1.s, v2.s, v3.s}[1], [x0], #16
st4 { v4.s, v5.s, v6.s, v7.s}[1], [x0], #16
st4 { v8.s, v9.s,v10.s,v11.s}[1], [x0], #16
st4 {v12.s,v13.s,v14.s,v15.s}[1], [x0], #16
st4 { v0.s, v1.s, v2.s, v3.s}[2], [x0], #16
st4 { v4.s, v5.s, v6.s, v7.s}[2], [x0], #16
st4 { v8.s, v9.s,v10.s,v11.s}[2], [x0], #16
st4 {v12.s,v13.s,v14.s,v15.s}[2], [x0], #16
st4 { v0.s, v1.s, v2.s, v3.s}[3], [x0], #16
st4 { v4.s, v5.s, v6.s, v7.s}[3], [x0], #16
st4 { v8.s, v9.s,v10.s,v11.s}[3], [x0], #16
st4 {v12.s,v13.s,v14.s,v15.s}[3], [x0], #16
ldp d8, d9, [sp, #0x10]
ldp d10, d11, [sp, #0x20]
ldp d12, d13, [sp, #0x30]
ldp d14, d15, [sp, #0x40]
ldp fp, lr, [sp], #0x50
ret
END(chacha_stream256_neon)
ENTRY(chacha_stream_xor256_neon)
stp fp, lr, [sp, #-0x50]!
mov fp, sp
stp d8, d9, [sp, #0x10]
stp d10, d11, [sp, #0x20]
stp d12, d13, [sp, #0x30]
stp d14, d15, [sp, #0x40]
adrl x9, v0123
mov x10, x5
mov x11, x4
add x12, x4, #16
mov x13, x3
ld1 {v26.4s-v27.4s}, [x9]
dup v12.4s, w2
ld4r {v0.4s-v3.4s}, [x10]
ld4r {v4.4s-v7.4s}, [x11]
ld4r {v8.4s-v11.4s}, [x12]
ld3r {v13.4s-v15.4s}, [x13]
add v12.4s, v12.4s, v26.4s
LE32TOH(v0.16b)
LE32TOH(v1.16b)
LE32TOH(v2.16b)
LE32TOH(v3.16b)
LE32TOH(v4.16b)
LE32TOH(v5.16b)
LE32TOH(v6.16b)
LE32TOH(v7.16b)
LE32TOH(v8.16b)
LE32TOH(v9.16b)
LE32TOH(v10.16b)
LE32TOH(v11.16b)
LE32TOH(v13.16b)
LE32TOH(v14.16b)
LE32TOH(v15.16b)
mov v16.16b, v0.16b
mov v17.16b, v1.16b
mov v18.16b, v2.16b
mov v19.16b, v3.16b
mov v20.16b, v4.16b
mov v21.16b, v5.16b
mov v22.16b, v6.16b
mov v23.16b, v7.16b
mov v24.16b, v8.16b
mov v25.16b, v9.16b
mov v26.16b, v12.16b
mov w8, v10.s[0]
mov w9, v11.s[0]
mov w10, v13.s[0]
mov w11, v14.s[0]
mov w12, v15.s[0]
_ALIGN_TEXT
1: subs w6, w6, #2
ROUND(v0,v1,v2,v3, v4,v5,v6,v7, v8,v9,v10,v11, v12,v13,v14,v15,
v28,v29,v30,v31, v27)
ROUND(v0,v1,v2,v3, v5,v6,v7,v4, v10,v11,v8,v9, v15,v12,v13,v14,
v28,v29,v30,v31, v27)
b.ne 1b
dup v27.4s, w8
dup v28.4s, w9
dup v29.4s, w10
dup v30.4s, w11
dup v31.4s, w12
add v0.4s, v0.4s, v16.4s
add v1.4s, v1.4s, v17.4s
add v2.4s, v2.4s, v18.4s
add v3.4s, v3.4s, v19.4s
add v4.4s, v4.4s, v20.4s
add v5.4s, v5.4s, v21.4s
add v6.4s, v6.4s, v22.4s
add v7.4s, v7.4s, v23.4s
add v8.4s, v8.4s, v24.4s
add v9.4s, v9.4s, v25.4s
add v10.4s, v10.4s, v27.4s
add v11.4s, v11.4s, v28.4s
add v12.4s, v12.4s, v26.4s
add v13.4s, v13.4s, v29.4s
add v14.4s, v14.4s, v30.4s
add v15.4s, v15.4s, v31.4s
ld4 {v16.s,v17.s,v18.s,v19.s}[0], [x1], #16
ld4 {v20.s,v21.s,v22.s,v23.s}[0], [x1], #16
ld4 {v24.s,v25.s,v26.s,v27.s}[0], [x1], #16
ld4 {v28.s,v29.s,v30.s,v31.s}[0], [x1], #16
ld4 {v16.s,v17.s,v18.s,v19.s}[1], [x1], #16
ld4 {v20.s,v21.s,v22.s,v23.s}[1], [x1], #16
ld4 {v24.s,v25.s,v26.s,v27.s}[1], [x1], #16
ld4 {v28.s,v29.s,v30.s,v31.s}[1], [x1], #16
ld4 {v16.s,v17.s,v18.s,v19.s}[2], [x1], #16
ld4 {v20.s,v21.s,v22.s,v23.s}[2], [x1], #16
ld4 {v24.s,v25.s,v26.s,v27.s}[2], [x1], #16
ld4 {v28.s,v29.s,v30.s,v31.s}[2], [x1], #16
ld4 {v16.s,v17.s,v18.s,v19.s}[3], [x1], #16
ld4 {v20.s,v21.s,v22.s,v23.s}[3], [x1], #16
ld4 {v24.s,v25.s,v26.s,v27.s}[3], [x1], #16
ld4 {v28.s,v29.s,v30.s,v31.s}[3], [x1], #16
HTOLE32(v0.16b)
HTOLE32(v1.16b)
HTOLE32(v2.16b)
HTOLE32(v3.16b)
HTOLE32(v4.16b)
HTOLE32(v5.16b)
HTOLE32(v6.16b)
HTOLE32(v7.16b)
HTOLE32(v8.16b)
HTOLE32(v9.16b)
HTOLE32(v10.16b)
HTOLE32(v11.16b)
HTOLE32(v12.16b)
HTOLE32(v13.16b)
HTOLE32(v14.16b)
HTOLE32(v15.16b)
eor v16.16b, v16.16b, v0.16b
eor v17.16b, v17.16b, v1.16b
eor v18.16b, v18.16b, v2.16b
eor v19.16b, v19.16b, v3.16b
eor v20.16b, v20.16b, v4.16b
eor v21.16b, v21.16b, v5.16b
eor v22.16b, v22.16b, v6.16b
eor v23.16b, v23.16b, v7.16b
eor v24.16b, v24.16b, v8.16b
eor v25.16b, v25.16b, v9.16b
eor v26.16b, v26.16b, v10.16b
eor v27.16b, v27.16b, v11.16b
eor v28.16b, v28.16b, v12.16b
eor v29.16b, v29.16b, v13.16b
eor v30.16b, v30.16b, v14.16b
eor v31.16b, v31.16b, v15.16b
st4 {v16.s,v17.s,v18.s,v19.s}[0], [x0], #16
st4 {v20.s,v21.s,v22.s,v23.s}[0], [x0], #16
st4 {v24.s,v25.s,v26.s,v27.s}[0], [x0], #16
st4 {v28.s,v29.s,v30.s,v31.s}[0], [x0], #16
st4 {v16.s,v17.s,v18.s,v19.s}[1], [x0], #16
st4 {v20.s,v21.s,v22.s,v23.s}[1], [x0], #16
st4 {v24.s,v25.s,v26.s,v27.s}[1], [x0], #16
st4 {v28.s,v29.s,v30.s,v31.s}[1], [x0], #16
st4 {v16.s,v17.s,v18.s,v19.s}[2], [x0], #16
st4 {v20.s,v21.s,v22.s,v23.s}[2], [x0], #16
st4 {v24.s,v25.s,v26.s,v27.s}[2], [x0], #16
st4 {v28.s,v29.s,v30.s,v31.s}[2], [x0], #16
st4 {v16.s,v17.s,v18.s,v19.s}[3], [x0], #16
st4 {v20.s,v21.s,v22.s,v23.s}[3], [x0], #16
st4 {v24.s,v25.s,v26.s,v27.s}[3], [x0], #16
st4 {v28.s,v29.s,v30.s,v31.s}[3], [x0], #16
ldp d8, d9, [sp, #0x10]
ldp d10, d11, [sp, #0x20]
ldp d12, d13, [sp, #0x30]
ldp d14, d15, [sp, #0x40]
ldp fp, lr, [sp], #0x50
ret
END(chacha_stream_xor256_neon)
.section .rodata
.p2align 4
.type v0123,@object
v0123:
.long 0, 1, 2, 3
END(v0123)
.type rot8,@object
rot8:
.long 0x02010003, 0x06050407, 0x0a09080b, 0x0e0d0c0f
END(rot8)