chiark / gitweb /
base/asm-common.h, symm/*.S: New macros for register name decoration.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 5 Nov 2016 21:28:22 +0000 (21:28 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 3 Apr 2017 08:59:54 +0000 (09:59 +0100)
Enhance `base/asm-common.h' with new macros for translating between
various ways of describing pieces of machine registers.

The x86/AMD64 general-purpose registers are a complicated mess of
overlapping pieces, and trying to write code which works on both just
makes everything even more interesting.

The ARM NEON registers are somewhat complicated, and GNU as isn't as
good as it should be at coping with alternative ways of denoting pieces
of them.  (For example, it ought to allow {q0-q7} instead of {d0-d15},
but doesn't; and it ought to allow q2[2] instead of d5[0], but doesn't.)

Use these macros tastefully in the various pieces of assembler code.

base/asm-common.h
symm/chacha-arm-neon.S
symm/rijndael-arm-crypto.S
symm/rijndael-x86ish-aesni.S
symm/salsa20-arm-neon.S

index 77dd6a72d0a17c2abc35be7c49e94c8f44682c2d..4a0a420988ebe7d5a9787ccff2055bc13aa06f1c 100644 (file)
@@ -203,6 +203,218 @@ name:
 // element 2, element B to element 1, and element A to element 0.
 #define SHUF(d, c, b, a) (64*(d) + 16*(c) + 4*(b) + (a))
 
+// Map register names to their individual pieces.
+
+// Apply decoration decor to (internal) register name reg of type ty.
+//
+// See `R_...' for internal register names.  Decorations are as follows.
+//
+//     b       low byte (e.g., `al', `r8b')
+//     h       high byte (e.g., `ah')
+//     w       word (e.g., `ax', `r8w')
+//     d       doubleword (e.g., `eax', `r8d')
+//     q       quadword (e.g., `rax', `r8')
+//     r       whole register (doubleword on x86, quadword on amd64)
+//
+// And types are as follows.
+//
+//     abcd    the four traditional registers `a', `b', `c', `d'
+//     xp      the four pointer registers `si', `di', `bp', `sp'
+//     ip      the instruction pointer `ip'
+//     rn      the AMD64 numbered registers `r8'--`r15'
+#define _DECOR(ty, decor, reg) _DECOR_##ty##_##decor(reg)
+
+// Internal macros: _DECOR_ty_decor(reg) applies decoration decor to
+// (internal) register name reg of type ty.
+
+#define _DECOR_abcd_b(reg) reg##l
+#define _DECOR_abcd_h(reg) reg##h
+#define _DECOR_abcd_w(reg) reg##x
+#define _DECOR_abcd_d(reg) e##reg##x
+#if CPUFAM_AMD64
+#  define _DECOR_abcd_q(reg) r##reg##x
+#endif
+
+#define _DECOR_xp_b(reg) reg##l
+#define _DECOR_xp_w(reg) reg
+#define _DECOR_xp_d(reg) e##reg
+#if CPUFAM_AMD64
+#  define _DECOR_xp_q(reg) r##reg
+#endif
+
+#define _DECOR_ip_w(reg) reg
+#define _DECOR_ip_d(reg) e##reg
+#if CPUFAM_AMD64
+#  define _DECOR_ip_q(reg) r##reg
+#endif
+
+#if CPUFAM_AMD64
+#  define _DECOR_rn_b(reg) reg##b
+#  define _DECOR_rn_w(reg) reg##w
+#  define _DECOR_rn_d(reg) reg##d
+#  define _DECOR_rn_q(reg) reg
+#  define _DECOR_rn_r(reg) reg
+#endif
+
+#if CPUFAM_X86
+#  define _DECOR_abcd_r(reg) e##reg##x
+#  define _DECOR_xp_r(reg) e##reg
+#  define _DECOR_ip_r(reg) e##reg
+#endif
+#if CPUFAM_AMD64
+#  define _DECOR_abcd_r(reg) r##reg##x
+#  define _DECOR_xp_r(reg) r##reg
+#  define _DECOR_ip_r(reg) r##reg
+#endif
+
+#define _DECOR_mem_b(addr) byte ptr addr
+#define _DECOR_mem_w(addr) word ptr addr
+#define _DECOR_mem_d(addr) dword ptr addr
+#if CPUFAM_AMD64
+#  define _DECOR_mem_q(addr) qword ptr addr
+#endif
+
+// R_r(decor) applies decoration decor to register r, which is an internal
+// register name.  The internal register names are: `ip', `a', `b', `c', `d',
+// `si', `di', `bp', `sp', `r8'--`r15'.
+#define R_ip(decor) _DECOR(ip, decor, ip)
+#define R_a(decor) _DECOR(abcd, decor, a)
+#define R_b(decor) _DECOR(abcd, decor, b)
+#define R_c(decor) _DECOR(abcd, decor, c)
+#define R_d(decor) _DECOR(abcd, decor, d)
+#define R_si(decor) _DECOR(xp, decor, si)
+#define R_di(decor) _DECOR(xp, decor, di)
+#define R_bp(decor) _DECOR(xp, decor, bp)
+#define R_sp(decor) _DECOR(xp, decor, sp)
+#if CPUFAM_AMD64
+#  define R_r8(decor) _DECOR(rn, decor, r8)
+#  define R_r9(decor) _DECOR(rn, decor, r9)
+#  define R_r10(decor) _DECOR(rn, decor, r10)
+#  define R_r11(decor) _DECOR(rn, decor, r11)
+#  define R_r12(decor) _DECOR(rn, decor, r12)
+#  define R_r13(decor) _DECOR(rn, decor, r13)
+#  define R_r14(decor) _DECOR(rn, decor, r14)
+#  define R_r15(decor) _DECOR(rn, decor, r15)
+#endif
+
+// Refer to an in-memory datum of the type implied by decor residing at
+// address addr (which should supply its own square-brackets).
+#define MEM(decor, addr) _DECOR(mem, decor, addr)
+
+// Applies decoration decor to assembler-level register name reg.
+#define _REGFORM(reg, decor) _GLUE(_REGFORM_, reg)(decor)
+
+// Internal macros: _REGFORM_r(decor) applies decoration decor to an
+// assembler-level register name, in place of any decoration that register
+// name has already.
+
+#define _REGFORM_ip(decor) R_ip(decor)
+#define _REGFORM_eip(decor) R_ip(decor)
+
+#define _REGFORM_a(decor) R_a(decor)
+#define _REGFORM_al(decor) R_a(decor)
+#define _REGFORM_ah(decor) R_a(decor)
+#define _REGFORM_ax(decor) R_a(decor)
+#define _REGFORM_eax(decor) R_a(decor)
+
+#define _REGFORM_b(decor) R_b(decor)
+#define _REGFORM_bl(decor) R_b(decor)
+#define _REGFORM_bh(decor) R_b(decor)
+#define _REGFORM_bx(decor) R_b(decor)
+#define _REGFORM_ebx(decor) R_b(decor)
+
+#define _REGFORM_c(decor) R_c(decor)
+#define _REGFORM_cl(decor) R_c(decor)
+#define _REGFORM_ch(decor) R_c(decor)
+#define _REGFORM_cx(decor) R_c(decor)
+#define _REGFORM_ecx(decor) R_c(decor)
+
+#define _REGFORM_d(decor) R_d(decor)
+#define _REGFORM_dl(decor) R_d(decor)
+#define _REGFORM_dh(decor) R_d(decor)
+#define _REGFORM_dx(decor) R_d(decor)
+#define _REGFORM_edx(decor) R_d(decor)
+
+#define _REGFORM_si(decor) R_si(decor)
+#define _REGFORM_sil(decor) R_si(decor)
+#define _REGFORM_esi(decor) R_si(decor)
+
+#define _REGFORM_di(decor) R_di(decor)
+#define _REGFORM_dil(decor) R_di(decor)
+#define _REGFORM_edi(decor) R_di(decor)
+
+#define _REGFORM_bp(decor) R_bp(decor)
+#define _REGFORM_bpl(decor) R_bp(decor)
+#define _REGFORM_ebp(decor) R_bp(decor)
+
+#define _REGFORM_sp(decor) R_sp(decor)
+#define _REGFORM_spl(decor) R_sp(decor)
+#define _REGFORM_esp(decor) R_sp(decor)
+
+#if CPUFAM_AMD64
+
+#  define _REGFORM_rip(decor) R_ip(decor)
+#  define _REGFORM_rsp(decor) R_sp(decor)
+#  define _REGFORM_rbp(decor) R_bp(decor)
+#  define _REGFORM_rdi(decor) R_di(decor)
+#  define _REGFORM_rsi(decor) R_si(decor)
+#  define _REGFORM_rdx(decor) R_d(decor)
+#  define _REGFORM_rcx(decor) R_c(decor)
+#  define _REGFORM_rbx(decor) R_b(decor)
+#  define _REGFORM_rax(decor) R_a(decor)
+
+#  define _REGFORM_r8(decor) R_r8(decor)
+#  define _REGFORM_r8b(decor) R_r8(decor)
+#  define _REGFORM_r8w(decor) R_r8(decor)
+#  define _REGFORM_r8d(decor) R_r8(decor)
+
+#  define _REGFORM_r9(decor) R_r9(decor)
+#  define _REGFORM_r9b(decor) R_r9(decor)
+#  define _REGFORM_r9w(decor) R_r9(decor)
+#  define _REGFORM_r9d(decor) R_r9(decor)
+
+#  define _REGFORM_r10(decor) R_r10(decor)
+#  define _REGFORM_r10b(decor) R_r10(decor)
+#  define _REGFORM_r10w(decor) R_r10(decor)
+#  define _REGFORM_r10d(decor) R_r10(decor)
+
+#  define _REGFORM_r11(decor) R_r11(decor)
+#  define _REGFORM_r11b(decor) R_r11(decor)
+#  define _REGFORM_r11w(decor) R_r11(decor)
+#  define _REGFORM_r11d(decor) R_r11(decor)
+
+#  define _REGFORM_r12(decor) R_r12(decor)
+#  define _REGFORM_r12b(decor) R_r12(decor)
+#  define _REGFORM_r12w(decor) R_r12(decor)
+#  define _REGFORM_r12d(decor) R_r12(decor)
+
+#  define _REGFORM_r13(decor) R_r13(decor)
+#  define _REGFORM_r13b(decor) R_r13(decor)
+#  define _REGFORM_r13w(decor) R_r13(decor)
+#  define _REGFORM_r13d(decor) R_r13(decor)
+
+#  define _REGFORM_r14(decor) R_r14(decor)
+#  define _REGFORM_r14b(decor) R_r14(decor)
+#  define _REGFORM_r14w(decor) R_r14(decor)
+#  define _REGFORM_r14d(decor) R_r14(decor)
+
+#  define _REGFORM_r15(decor) R_r15(decor)
+#  define _REGFORM_r15b(decor) R_r15(decor)
+#  define _REGFORM_r15w(decor) R_r15(decor)
+#  define _REGFORM_r15d(decor) R_r15(decor)
+
+#endif
+
+// Macros for converting register names.
+#define BYTE(reg) _REGFORM(reg, b)
+#define HIBYTE(reg) _REGFORM(reg, h)
+#define WORD(reg) _REGFORM(reg, w)
+#define DWORD(reg) _REGFORM(reg, d)
+#if CPUFAM_AMD64
+#  define QWORD(reg) _REGFORM(reg, q)
+#endif
+#define WHOLE(reg) _REGFORM(reg, r)
+
 #endif
 
 #if CPUFAM_X86
@@ -395,6 +607,255 @@ name:
 #endif
 .endm
 
+// Apply decoration decor to register name reg.
+#define _REGFORM(reg, decor) _GLUE(_REGFORM_, reg)(decor)
+
+// Internal macros: `_REGFORM_r(decor)' applies decoration decor to register
+// name r.
+
+#define _REGFORM_s0(decor) _DECOR(s, decor, 0)
+#define _REGFORM_s1(decor) _DECOR(s, decor, 1)
+#define _REGFORM_s2(decor) _DECOR(s, decor, 2)
+#define _REGFORM_s3(decor) _DECOR(s, decor, 3)
+#define _REGFORM_s4(decor) _DECOR(s, decor, 4)
+#define _REGFORM_s5(decor) _DECOR(s, decor, 5)
+#define _REGFORM_s6(decor) _DECOR(s, decor, 6)
+#define _REGFORM_s7(decor) _DECOR(s, decor, 7)
+#define _REGFORM_s8(decor) _DECOR(s, decor, 8)
+#define _REGFORM_s9(decor) _DECOR(s, decor, 9)
+#define _REGFORM_s10(decor) _DECOR(s, decor, 10)
+#define _REGFORM_s11(decor) _DECOR(s, decor, 11)
+#define _REGFORM_s12(decor) _DECOR(s, decor, 12)
+#define _REGFORM_s13(decor) _DECOR(s, decor, 13)
+#define _REGFORM_s14(decor) _DECOR(s, decor, 14)
+#define _REGFORM_s15(decor) _DECOR(s, decor, 15)
+#define _REGFORM_s16(decor) _DECOR(s, decor, 16)
+#define _REGFORM_s17(decor) _DECOR(s, decor, 17)
+#define _REGFORM_s18(decor) _DECOR(s, decor, 18)
+#define _REGFORM_s19(decor) _DECOR(s, decor, 19)
+#define _REGFORM_s20(decor) _DECOR(s, decor, 20)
+#define _REGFORM_s21(decor) _DECOR(s, decor, 21)
+#define _REGFORM_s22(decor) _DECOR(s, decor, 22)
+#define _REGFORM_s23(decor) _DECOR(s, decor, 23)
+#define _REGFORM_s24(decor) _DECOR(s, decor, 24)
+#define _REGFORM_s25(decor) _DECOR(s, decor, 25)
+#define _REGFORM_s26(decor) _DECOR(s, decor, 26)
+#define _REGFORM_s27(decor) _DECOR(s, decor, 27)
+#define _REGFORM_s28(decor) _DECOR(s, decor, 28)
+#define _REGFORM_s29(decor) _DECOR(s, decor, 29)
+#define _REGFORM_s30(decor) _DECOR(s, decor, 30)
+#define _REGFORM_s31(decor) _DECOR(s, decor, 31)
+
+#define _REGFORM_d0(decor) _DECOR(d, decor, 0)
+#define _REGFORM_d1(decor) _DECOR(d, decor, 1)
+#define _REGFORM_d2(decor) _DECOR(d, decor, 2)
+#define _REGFORM_d3(decor) _DECOR(d, decor, 3)
+#define _REGFORM_d4(decor) _DECOR(d, decor, 4)
+#define _REGFORM_d5(decor) _DECOR(d, decor, 5)
+#define _REGFORM_d6(decor) _DECOR(d, decor, 6)
+#define _REGFORM_d7(decor) _DECOR(d, decor, 7)
+#define _REGFORM_d8(decor) _DECOR(d, decor, 8)
+#define _REGFORM_d9(decor) _DECOR(d, decor, 9)
+#define _REGFORM_d10(decor) _DECOR(d, decor, 10)
+#define _REGFORM_d11(decor) _DECOR(d, decor, 11)
+#define _REGFORM_d12(decor) _DECOR(d, decor, 12)
+#define _REGFORM_d13(decor) _DECOR(d, decor, 13)
+#define _REGFORM_d14(decor) _DECOR(d, decor, 14)
+#define _REGFORM_d15(decor) _DECOR(d, decor, 15)
+#define _REGFORM_d16(decor) _DECOR(d, decor, 16)
+#define _REGFORM_d17(decor) _DECOR(d, decor, 17)
+#define _REGFORM_d18(decor) _DECOR(d, decor, 18)
+#define _REGFORM_d19(decor) _DECOR(d, decor, 19)
+#define _REGFORM_d20(decor) _DECOR(d, decor, 20)
+#define _REGFORM_d21(decor) _DECOR(d, decor, 21)
+#define _REGFORM_d22(decor) _DECOR(d, decor, 22)
+#define _REGFORM_d23(decor) _DECOR(d, decor, 23)
+#define _REGFORM_d24(decor) _DECOR(d, decor, 24)
+#define _REGFORM_d25(decor) _DECOR(d, decor, 25)
+#define _REGFORM_d26(decor) _DECOR(d, decor, 26)
+#define _REGFORM_d27(decor) _DECOR(d, decor, 27)
+#define _REGFORM_d28(decor) _DECOR(d, decor, 28)
+#define _REGFORM_d29(decor) _DECOR(d, decor, 29)
+#define _REGFORM_d30(decor) _DECOR(d, decor, 30)
+#define _REGFORM_d31(decor) _DECOR(d, decor, 31)
+
+#define _REGFORM_q0(decor) _DECOR(q, decor, 0)
+#define _REGFORM_q1(decor) _DECOR(q, decor, 1)
+#define _REGFORM_q2(decor) _DECOR(q, decor, 2)
+#define _REGFORM_q3(decor) _DECOR(q, decor, 3)
+#define _REGFORM_q4(decor) _DECOR(q, decor, 4)
+#define _REGFORM_q5(decor) _DECOR(q, decor, 5)
+#define _REGFORM_q6(decor) _DECOR(q, decor, 6)
+#define _REGFORM_q7(decor) _DECOR(q, decor, 7)
+#define _REGFORM_q8(decor) _DECOR(q, decor, 8)
+#define _REGFORM_q9(decor) _DECOR(q, decor, 9)
+#define _REGFORM_q10(decor) _DECOR(q, decor, 10)
+#define _REGFORM_q11(decor) _DECOR(q, decor, 11)
+#define _REGFORM_q12(decor) _DECOR(q, decor, 12)
+#define _REGFORM_q13(decor) _DECOR(q, decor, 13)
+#define _REGFORM_q14(decor) _DECOR(q, decor, 14)
+#define _REGFORM_q15(decor) _DECOR(q, decor, 15)
+
+// `_LOPART(n)' and `_HIPART(n)' return the numbers of the register halves of
+// register n, i.e., 2*n and 2*n + 1 respectively.
+#define _LOPART(n) _GLUE(_LOPART_, n)
+#define _HIPART(n) _GLUE(_HIPART_, n)
+
+// Internal macros: `_LOPART_n' and `_HIPART_n' return the numbers of the
+// register halves of register n, i.e., 2*n and 2*n + 1 respectively.
+
+#define _LOPART_0 0
+#define _HIPART_0 1
+#define _LOPART_1 2
+#define _HIPART_1 3
+#define _LOPART_2 4
+#define _HIPART_2 5
+#define _LOPART_3 6
+#define _HIPART_3 7
+#define _LOPART_4 8
+#define _HIPART_4 9
+#define _LOPART_5 10
+#define _HIPART_5 11
+#define _LOPART_6 12
+#define _HIPART_6 13
+#define _LOPART_7 14
+#define _HIPART_7 15
+#define _LOPART_8 16
+#define _HIPART_8 17
+#define _LOPART_9 18
+#define _HIPART_9 19
+#define _LOPART_10 20
+#define _HIPART_10 21
+#define _LOPART_11 22
+#define _HIPART_11 23
+#define _LOPART_12 24
+#define _HIPART_12 25
+#define _LOPART_13 26
+#define _HIPART_13 27
+#define _LOPART_14 28
+#define _HIPART_14 29
+#define _LOPART_15 30
+#define _HIPART_15 31
+
+// Return the register number of the pair containing register n, i.e.,
+// floor(n/2).
+#define _PAIR(n) _GLUE(_PAIR_, n)
+
+// Internal macros: `_PAIR_n' returns the register number of the pair
+// containing register n, i.e., floor(n/2).
+#define _PAIR_0 0
+#define _PAIR_1 0
+#define _PAIR_2 1
+#define _PAIR_3 1
+#define _PAIR_4 2
+#define _PAIR_5 2
+#define _PAIR_6 3
+#define _PAIR_7 3
+#define _PAIR_8 4
+#define _PAIR_9 4
+#define _PAIR_10 5
+#define _PAIR_11 5
+#define _PAIR_12 6
+#define _PAIR_13 6
+#define _PAIR_14 7
+#define _PAIR_15 7
+#define _PAIR_16 8
+#define _PAIR_17 8
+#define _PAIR_18 9
+#define _PAIR_19 9
+#define _PAIR_20 10
+#define _PAIR_21 10
+#define _PAIR_22 11
+#define _PAIR_23 11
+#define _PAIR_24 12
+#define _PAIR_25 12
+#define _PAIR_26 13
+#define _PAIR_27 13
+#define _PAIR_28 14
+#define _PAIR_29 14
+#define _PAIR_30 15
+#define _PAIR_31 15
+
+// Apply decoration decor to register number n of type ty.  Decorations are
+// as follows.
+//
+//     decor   types   meaning
+//     Q       s, d    the NEON qN register containing this one
+//     D       s       the NEON dN register containing this one
+//     D0      q       the low 64-bit half of this one
+//     D1      q       the high 64-bit half of this one
+//     S0      d, q    the first 32-bit piece of this one
+//     S1      d, q    the second 32-bit piece of this one
+//     S2      q       the third 32-bit piece of this one
+//     S3      q       the fourth 32-bit piece of this one
+//     Bn      q       the nth byte of this register, as a scalar
+//     Hn      q       the nth halfword of this register, as a scalar
+//     Wn      q       the nth word of this register, as a scalar
+#define _DECOR(ty, decor, n) _DECOR_##ty##_##decor(n)
+
+// Internal macros: `_DECOR_ty_decor(n)' applies decoration decor to register
+// number n of type ty.
+
+#define _DECOR_s_Q(n) GLUE(q, _PAIR(_PAIR(n)))
+#define _DECOR_s_D(n) GLUE(d, _PAIR(n))
+
+#define _DECOR_d_Q(n) GLUE(q, _PAIR(n))
+#define _DECOR_d_S0(n) GLUE(s, _LOPART(n))
+#define _DECOR_d_S1(n) GLUE(s, _LOPART(n))
+
+#define _DECOR_q_D0(n) GLUE(d, _LOPART(n))
+#define _DECOR_q_D1(n) GLUE(d, _HIPART(n))
+#define _DECOR_q_S0(n) GLUE(s, _LOPART(_LOPART(n)))
+#define _DECOR_q_S1(n) GLUE(s, _HIPART(_LOPART(n)))
+#define _DECOR_q_S2(n) GLUE(s, _LOPART(_HIPART(n)))
+#define _DECOR_q_S3(n) GLUE(s, _HIPART(_HIPART(n)))
+#define _DECOR_q_W0(n) GLUE(d, _LOPART(n))[0]
+#define _DECOR_q_W1(n) GLUE(d, _LOPART(n))[1]
+#define _DECOR_q_W2(n) GLUE(d, _HIPART(n))[0]
+#define _DECOR_q_W3(n) GLUE(d, _HIPART(n))[1]
+#define _DECOR_q_H0(n) GLUE(d, _LOPART(n))[0]
+#define _DECOR_q_H1(n) GLUE(d, _LOPART(n))[1]
+#define _DECOR_q_H2(n) GLUE(d, _LOPART(n))[2]
+#define _DECOR_q_H3(n) GLUE(d, _LOPART(n))[3]
+#define _DECOR_q_H4(n) GLUE(d, _HIPART(n))[0]
+#define _DECOR_q_H5(n) GLUE(d, _HIPART(n))[1]
+#define _DECOR_q_H6(n) GLUE(d, _HIPART(n))[2]
+#define _DECOR_q_H7(n) GLUE(d, _HIPART(n))[3]
+#define _DECOR_q_B0(n) GLUE(d, _LOPART(n))[0]
+#define _DECOR_q_B1(n) GLUE(d, _LOPART(n))[1]
+#define _DECOR_q_B2(n) GLUE(d, _LOPART(n))[2]
+#define _DECOR_q_B3(n) GLUE(d, _LOPART(n))[3]
+#define _DECOR_q_B4(n) GLUE(d, _LOPART(n))[4]
+#define _DECOR_q_B5(n) GLUE(d, _LOPART(n))[5]
+#define _DECOR_q_B6(n) GLUE(d, _LOPART(n))[6]
+#define _DECOR_q_B7(n) GLUE(d, _LOPART(n))[7]
+#define _DECOR_q_B8(n) GLUE(d, _HIPART(n))[0]
+#define _DECOR_q_B9(n) GLUE(d, _HIPART(n))[1]
+#define _DECOR_q_B10(n) GLUE(d, _HIPART(n))[2]
+#define _DECOR_q_B11(n) GLUE(d, _HIPART(n))[3]
+#define _DECOR_q_B12(n) GLUE(d, _HIPART(n))[4]
+#define _DECOR_q_B13(n) GLUE(d, _HIPART(n))[5]
+#define _DECOR_q_B14(n) GLUE(d, _HIPART(n))[6]
+#define _DECOR_q_B15(n) GLUE(d, _HIPART(n))[7]
+
+// Macros for navigating the NEON register hierarchy.
+#define S0(reg) _REGFORM(reg, S0)
+#define S1(reg) _REGFORM(reg, S1)
+#define S2(reg) _REGFORM(reg, S2)
+#define S3(reg) _REGFORM(reg, S3)
+#define D(reg) _REGFORM(reg, D)
+#define D0(reg) _REGFORM(reg, D0)
+#define D1(reg) _REGFORM(reg, D1)
+#define Q(reg) _REGFORM(reg, Q)
+
+// Macros for indexing quadword registers.
+#define QB(reg, i) _REGFORM(reg, B##i)
+#define QH(reg, i) _REGFORM(reg, H##i)
+#define QW(reg, i) _REGFORM(reg, W##i)
+
+// Macros for converting vldm/vstm ranges.
+#define QQ(qlo, qhi) D0(qlo)-D1(qhi)
+
 #endif
 
 ///--------------------------------------------------------------------------
index 4c72791ec32d0ee135422a4981eeae9142489064..af53cfd38dff936a81fef2759659bd366a990873 100644 (file)
@@ -55,7 +55,7 @@ FUNC(chacha_core_arm_neon)
        // We need a copy for later.  Rather than waste time copying them by
        // hand, we'll use the three-address nature of the instruction set.
        // But this means that the main loop is offset by a bit.
-       vldmia  r1, {d24-d31}
+       vldmia  r1, {QQ(q12, q15)}
 
        // a += b; d ^= a; d <<<= 16
        vadd.u32 q8, q12, q13
@@ -173,7 +173,7 @@ FUNC(chacha_core_arm_neon)
        vadd.u32 q11, q11, q15
 
        // And now we write out the result.
-       vstmia  r2, {d16-d23}
+       vstmia  r2, {QQ(q8, q11)}
 
        // And with that, we're done.
        bx      r14
index 49aa0166c147f6481d90ebbcee022f9592c5e916..5ca516e331ba2975502c5808d1eaeb444d2aa3b6 100644 (file)
@@ -52,7 +52,7 @@
        // Useful constants.
        .equ    maxrounds, 16           // maximum number of rounds
        .equ    maxblksz, 32            // maximum block size, in bytes
-       .equ    kbufsz, maxblksz*(maxrounds + 1) // size of a key-schedule buffer
+       .equ    kbufsz, maxblksz*(maxrounds + 1) // size of key-sched buffer
 
        // Context structure.
        .equ    nr, 0                   // number of rounds
index 3cca50f7df5bb2888c74d85ce988a964d96f8832..8090bca675a6332ab17100798f73f2e2cc5357e9 100644 (file)
@@ -63,6 +63,9 @@
 
 FUNC(rijndael_setup_x86ish_aesni)
 
+#define SI WHOLE(si)
+#define DI WHOLE(di)
+
 #if CPUFAM_X86
        // Arguments are on the stack.  We'll need to stack the caller's
        // register veriables, but we'll manage.
@@ -70,23 +73,16 @@ FUNC(rijndael_setup_x86ish_aesni)
 #  define CTX ebp                      // context pointer
 #  define BLKSZ [esp + 24]             // block size
 
-#  define SI esi                       // source pointer
-#  define DI edi                       // destination pointer
-
 #  define KSZ ebx                      // key size
-#  define KSZo ebx                     // ... as address offset
 #  define NKW edx                      // total number of key words
 #  define NKW_NEEDS_REFRESH 1          // ... needs recalculating
 #  define RCON ecx                     // round constants table
 #  define LIM edx                      // limit pointer
-#  define LIMn edx                     // ... as integer offset from base
 #  define CYIX edi                     // index in shift-register cycle
 
 #  define NR ecx                       // number of rounds
 #  define LRK eax                      // distance to last key
-#  define LRKo eax                     // ... as address offset
 #  define BLKOFF edx                   // block size in bytes
-#  define BLKOFFo edx                  // ... as address offset
 
        // Stack the caller's registers.
        push    ebp
@@ -107,22 +103,15 @@ FUNC(rijndael_setup_x86ish_aesni)
 #  define CTX r8                       // context pointer
 #  define BLKSZ r9d                    // block size
 
-#  define SI rsi                       // source pointer
-#  define DI rdi                       // destination pointer
-
 #  define KSZ edx                      // key size
-#  define KSZo rdx                     // ... as address offset
 #  define NKW r10d                     // total number of key words
 #  define RCON rdi                     // round constants table
-#  define LIMn ecx                     // limit pointer
-#  define LIM rcx                      // ... as integer offset from base
+#  define LIM rcx                      // limit pointer
 #  define CYIX r11d                    // index in shift-register cycle
 
 #  define NR ecx                       // number of rounds
 #  define LRK eax                      // distance to last key
-#  define LRKo rax                     // ... as address offset
 #  define BLKOFF r9d                   // block size in bytes
-#  define BLKOFFo r9                   // ... as address offset
 
        // Move arguments to more useful places.
        mov     CTX, rdi                // context base pointer
@@ -137,22 +126,15 @@ FUNC(rijndael_setup_x86ish_aesni)
 #  define CTX r8                       // context pointer
 #  define BLKSZ edx                    // block size
 
-#  define SI rsi                       // source pointer
-#  define DI rdi                       // destination pointer
-
 #  define KSZ r9d                      // key size
-#  define KSZo r9                      // ... as address offset
 #  define NKW r10d                     // total number of key words
 #  define RCON rdi                     // round constants table
-#  define LIMn ecx                     // limit pointer
-#  define LIM rcx                      // ... as integer offset from base
+#  define LIM rcx                      // limit pointer
 #  define CYIX r11d                    // index in shift-register cycle
 
 #  define NR ecx                       // number of rounds
 #  define LRK eax                      // distance to last key
-#  define LRKo rax                     // ... as address offset
 #  define BLKOFF edx                   // block size in bytes
-#  define BLKOFFo rdx                  // ... as address offset
 
        // We'll need the index registers, which belong to the caller in this
        // ABI.
@@ -163,7 +145,7 @@ FUNC(rijndael_setup_x86ish_aesni)
   .seh_endprologue
 
        // Move arguments to more useful places.
-       mov     SI, r8                  // key material
+       mov     rsi, r8                 // key material
        mov     CTX, rcx                // context base pointer
 #endif
 
@@ -172,7 +154,7 @@ FUNC(rijndael_setup_x86ish_aesni)
 #if CPUFAM_AMD64 && ABI_SYSV
        // We've been lucky.  We already have a copy of the context pointer
        // in rdi, and the key size in ecx.
-       add     DI, w
+       add     rdi, w
 #else
        lea     DI, [CTX + w]
        mov     ecx, KSZ
@@ -186,17 +168,17 @@ FUNC(rijndael_setup_x86ish_aesni)
 #if !NKW_NEEDS_REFRESH
        // If we can't keep NKW for later, then we use the same register for
        // it and LIM, so this move is unnecessary.
-       mov     LIMn, NKW
+       mov     DWORD(LIM), NKW
 #endif
-       sub     LIMn, KSZ               // offset by the key size
+       sub     DWORD(LIM), KSZ         // offset by the key size
 
        // Find the round constants.
-       ldgot   ecx
-       leaext  RCON, F(rijndael_rcon), ecx
+       ldgot   WHOLE(c)
+       leaext  RCON, F(rijndael_rcon), WHOLE(c)
 
        // Prepare for the main loop.
        lea     SI, [CTX + w]
-       mov     eax, [SI + 4*KSZo - 4]  // most recent key word
+       mov     eax, [SI + 4*WHOLE(KSZ) - 4] // most recent key word
        lea     LIM, [SI + 4*LIM]       // limit, offset by one key expansion
        xor     CYIX, CYIX              // start of new cycle
 
@@ -241,7 +223,7 @@ FUNC(rijndael_setup_x86ish_aesni)
        // Common tail.  Mix in the corresponding word from the previous
        // cycle and prepare for the next loop.
 2:     xor     eax, [SI]
-       mov     [SI + 4*KSZo], eax
+       mov     [SI + 4*WHOLE(KSZ)], eax
        add     SI, 4
        inc     CYIX
        cmp     SI, LIM
@@ -276,7 +258,7 @@ FUNC(rijndael_setup_x86ish_aesni)
        sub     LRK, BLKSZ
 #endif
        lea     DI, [CTX + wi]
-       lea     SI, [CTX + w + 4*LRKo]  // last round's keys
+       lea     SI, [CTX + w + 4*WHOLE(LRK)] // last round's keys
        shl     BLKOFF, 2               // block size (in bytes now)
 
        // Copy the last encryption round's keys.
@@ -288,8 +270,8 @@ FUNC(rijndael_setup_x86ish_aesni)
        movdqu  [DI + 16], xmm0
 
        // Update the loop variables and stop if we've finished.
-0:     add     DI, BLKOFFo
-       sub     SI, BLKOFFo
+0:     add     DI, WHOLE(BLKOFF)
+       sub     SI, WHOLE(BLKOFF)
        sub     NR, 1
        jbe     9f
 
@@ -368,15 +350,11 @@ endswap_block:
 #undef SI
 #undef DI
 #undef KSZ
-#undef KSZo
 #undef RCON
-#undef LIMn
 #undef LIM
 #undef NR
 #undef LRK
-#undef LRKo
 #undef BLKOFF
-#undef BLKOFFo
 
 ENDFUNC
 
index 9cb4047233d4c683cea9b83aaee4a9ac26a69765..9d553d3a25c9d20a9164053fbd02c84e48269ac5 100644 (file)
@@ -79,7 +79,7 @@ FUNC(salsa20_core_arm_neon)
        // We need a copy for later.  Rather than waste time copying them by
        // hand, we'll use the three-address nature of the instruction set.
        // But this means that the main loop is offset by a bit.
-       vldmia  r1, {d24-d31}
+       vldmia  r1, {QQ(q12, q15)}
 
        // Apply a column quarterround to each of the columns simultaneously,
        // moving the results to their working registers.  Alas, there
@@ -234,7 +234,7 @@ FUNC(salsa20_core_arm_neon)
        vext.32 q3, q9, q9, #1                  // 12, 13, 14, 15
 
        // And with that, we're done.
-       vstmia  r2, {d0-d7}
+       vstmia  r2, {QQ(q0, q3)}
        bx      r14
 
 ENDFUNC