The main issue with supporting these instructions is the fact that the
instructions want 64-bit values fed into the instructions which need
to be 32-bit transposed when we go in and out of these routines due
to conflicts with the BN layout used by OpenSSL on sparc.
We attempt to hide the overhead of this by hiding the bit twiddling in
the latency of the loads.
Secondarily, since we can end up having to retry (deep window spill on
32-bit and register ECC errors on 32-bit and 64-bit) we have to store
the result initially to a temporary buffer. Otherwise we could
overwrite an input if it is the same as the result, and therefore
not be able to retry the operation properly.
It seems that the A==B case does not trigger for the build as-is, so
the montsqr paths currently do not get hit, but the code is there for
if and when it does. I suspect we should be setting the CPP macro
OPENSSL_BN_ASM_MONT on sparc, and that would make this path start
triggering.
Longer term the best thing to do with this facility is to override the
entire montgomery sequence and use it to emit "scripts". This would
minimize the cost of loading and storing in and out of the registers
when chaining montgomery operations together. So something like:
LOAD Nprime
LOAD A
LOAD N
MONTSQR
STORE A
LOAD A
LOAD N
LOAD B
MONTMUL
STORE A
LOAD N
LOAD B
MONTMUL
STORE A
...
LOAD A
LOAD N
MONTSQR
STORE A
...
You get the idea. By chaining, we can make use of inputs already in
the registers, rather than have to reload them every time.
Also, playing into the BN layout issue, we can minimize the number of
times we have to translate between the layout OpenSSL uses internally
and what these instructions want.
Without crypto opcodes enabled on a SPARC T4-2:
rsa 1024 bits 0.001399s 0.000078s 714.9 12765.3
rsa 2048 bits 0.009390s 0.000310s 106.5 3227.4
and with crypto opcodes turned on:
rsa 1024 bits 0.000786s 0.000025s 1272.6 40080.4
rsa 2048 bits 0.002111s 0.000049s 473.8 20273.7
Signed-off-by: David S. Miller <[email protected]>
---
Configure | 2 +-
crypto/bn/Makefile | 2 +
crypto/bn/asm/sparcv9hw-mont.S | 1480 ++++++++++++++++++++++++++++++++++++++++
crypto/sparcv9cap.c | 129 ++++
4 files changed, 1612 insertions(+), 1 deletion(-)
create mode 100644 crypto/bn/asm/sparcv9hw-mont.S
diff --git a/Configure b/Configure
index 1a3d855..0903941 100755
--- a/Configure
+++ b/Configure
@@ -130,7 +130,7 @@ my $x86_elf_asm="$x86_asm:elf";
my $x86_64_asm="x86_64cpuid.o:x86_64-gcc.o x86_64-mont.o x86_64-mont5.o
x86_64-gf2m.o modexp512-x86_64.o::aes-x86_64.o vpaes-x86_64.o bsaes-x86_64.o
aesni-x86_64.o aesni-sha1-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o
sha512-x86_64.o::rc4-x86_64.o rc4-md5-x86_64.o:::wp-x86_64.o:cmll-x86_64.o
cmll_misc.o:ghash-x86_64.o:e_padlock-x86_64.o";
my $ia64_asm="ia64cpuid.o:bn-ia64.o ia64-mont.o::aes_core.o aes_cbc.o
aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o::rc4-ia64.o
rc4_skey.o:::::ghash-ia64.o::void";
-my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o
sparcv9a-mont.o:des_enc-sparc.o des_sparccore.o fcrypt_b.o:aes_sparccore.o
aes-sparcv9.o::md5-sparcv9.o:sha1-sparcv9.o sha256-sparcv9.o
sha512-sparcv9.o::::::cmll-sparcv9.o cmll_sparccore.o:ghash-sparcv9.o::void";
+my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o
sparcv9a-mont.o sparcv9hw-mont.o:des_enc-sparc.o des_sparccore.o
fcrypt_b.o:aes_sparccore.o aes-sparcv9.o::md5-sparcv9.o:sha1-sparcv9.o
sha256-sparcv9.o sha512-sparcv9.o::::::cmll-sparcv9.o
cmll_sparccore.o:ghash-sparcv9.o::void";
my $sparcv8_asm=":sparcv8.o:des_enc-sparc.o des_sparccore.o
fcrypt_b.o:::::::::::::void";
my $alpha_asm="alphacpuid.o:bn_asm.o
alpha-mont.o:::::sha1-alpha.o:::::::ghash-alpha.o::void";
my $mips64_asm=":bn-mips.o mips-mont.o::aes_cbc.o aes-mips.o:::sha1-mips.o
sha256-mips.o sha512-mips.o::::::::";
diff --git a/crypto/bn/Makefile b/crypto/bn/Makefile
index c823a6b..97b1686 100644
--- a/crypto/bn/Makefile
+++ b/crypto/bn/Makefile
@@ -77,6 +77,8 @@ sparcv9a-mont.s: asm/sparcv9a-mont.pl
$(PERL) asm/sparcv9a-mont.pl $(CFLAGS) > $@
sparcv9-mont.s: asm/sparcv9-mont.pl
$(PERL) asm/sparcv9-mont.pl $(CFLAGS) > $@
+sparcv9hw-mont.o: asm/sparcv9hw-mont.S
+ $(CC) $(CFLAGS) -c -o $@ asm/sparcv9hw-mont.S
bn-mips3.o: asm/mips3.s
@if [ "$(CC)" = "gcc" ]; then \
diff --git a/crypto/bn/asm/sparcv9hw-mont.S b/crypto/bn/asm/sparcv9hw-mont.S
new file mode 100644
index 0000000..a004d21
--- /dev/null
+++ b/crypto/bn/asm/sparcv9hw-mont.S
@@ -0,0 +1,1480 @@
+ .text
+
+#ifdef __arch64__
+#define FRAME_SIZE 176
+#else
+#define FRAME_SIZE 96
+#endif
+
+ /* LOAD N0 %f60
+ * LOAD A %l0, %l1, %l2, %l3, %l4, %l5, %l6, %l7 (CWP i-5)
+ * %o0, %o1, %o2, %o3, %o4, %o5 (CWP i-5)
+ * %f24, %f26, %f28, %f30, %f32, %f34, %f36
+ * %f38, %f40, %f42, %f44, %f46, %f48, %f50
+ * %f52, %f54, %f56, %f58
+ * LOAD N %l0, %l1, %l2, %l3, %l4, %l5, %l6, %l7 (CWP i-4)
+ * %o0, %o1, %o2, %o3, %o4, %o5 (CWP i-4)
+ * %l0, %l1, %l2, %l3, %l4, %l5, %l6, %l7 (CWP i-3)
+ * %o0, %o1, %o2, %o3, %o4, %o5 (CWP i-3)
+ * %l0, %l1, %l2, %l3 (CWP i-2)
+ * LOAD B %o0, %o1, %o2, %o3, %o4, %o5 (CWP i-2)
+ * %l0, %l1, %l2, %l3, %l4, %l5, %l6, %l7 (CWP i-1)
+ * %o0, %o1, %o2, %o3, %o4, %o5 (CWP i-1)
+ * %l0, %l1, %l2, %l3, %l4, %l5, %l6, %l7 (CWP i-0)
+ * %o0, %o1, %o2, %o3 (CWP i-0)
+ * STORE RSLT %l0, %l1, %l2, %l3, %l4, %l5, %l6, %l7 (CWP i-5)
+ * %o0, %o1, %o2, %o3, %o4, %o5 (CWP i-5)
+ * %f24, %f26, %f28, %f30, %f32, %f34, %f36
+ * %f38, %f40, %f42, %f44, %f46, %f48, %f50
+ * %f52, %f54, %f56, %f58
+ *
+ * The instruction uses the following registers as temporaries
+ * during the computation:
+ *
+ * %i0, %i1, %i2, %i3, %i4, %i5 (CWP i-6)
+ * %l0, %l1, %l2, %l3, %l4, %l5, %l6, %l7 (CWP i-6)
+ * %o0, %o1, %o2, %o3, %o4, %o5 (CWP i-6)
+ * %f0, %f2, %f4, %f6, %f8, %f10, %f12
+ * %f14, %f16, %f18, %f20, %f22
+ */
+#define __LD_A_64(A_PTR) \
+ lduw [%A_PTR + 0x00], %l0; \
+ lduw [%A_PTR + 0x04], %o7; \
+ sllx %o7, 32, %o7; \
+ or %l0, %o7, %l0;
+
+#define __LD_A_128(A_PTR) \
+ lduw [%A_PTR + 0x00], %l0; \
+ lduw [%A_PTR + 0x04], %o7; \
+ lduw [%A_PTR + 0x08], %l1; \
+ lduw [%A_PTR + 0x0c], %l2; \
+ sllx %o7, 32, %o7; \
+ or %l0, %o7, %l0; \
+ sllx %l2, 32, %l2; \
+ or %l1, %l2, %l1;
+
+#define __LD_A_192(A_PTR) \
+ lduw [%A_PTR + 0x00], %l0; \
+ lduw [%A_PTR + 0x04], %o7; \
+ lduw [%A_PTR + 0x08], %l1; \
+ lduw [%A_PTR + 0x0c], %l3; \
+ lduw [%A_PTR + 0x10], %l2; \
+ lduw [%A_PTR + 0x14], %l4; \
+ sllx %o7, 32, %o7; \
+ or %l0, %o7, %l0; \
+ sllx %l3, 32, %l3; \
+ or %l1, %l3, %l1; \
+ sllx %l4, 32, %l4; \
+ or %l2, %l4, %l2;
+
+#define __LD_A_256(A_PTR) \
+ lduw [%A_PTR + 0x00], %l0; \
+ lduw [%A_PTR + 0x04], %o7; \
+ lduw [%A_PTR + 0x08], %l1; \
+ lduw [%A_PTR + 0x0c], %l5; \
+ lduw [%A_PTR + 0x10], %l2; \
+ lduw [%A_PTR + 0x14], %l4; \
+ lduw [%A_PTR + 0x18], %l3; \
+ sllx %o7, 32, %o7; \
+ or %l0, %o7, %l0; \
+ lduw [%A_PTR + 0x1c], %o7; \
+ sllx %l5, 32, %l5; \
+ or %l1, %l5, %l1; \
+ sllx %l4, 32, %l4; \
+ or %l2, %l4, %l2; \
+ sllx %o7, 32, %o7; \
+ or %l3, %o7, %l3;
+
+#define __LD_A_320(A_PTR) \
+ lduw [%A_PTR + 0x00], %l0; \
+ lduw [%A_PTR + 0x04], %o7; \
+ lduw [%A_PTR + 0x08], %l1; \
+ lduw [%A_PTR + 0x0c], %l5; \
+ lduw [%A_PTR + 0x10], %l2; \
+ lduw [%A_PTR + 0x14], %l6; \
+ lduw [%A_PTR + 0x18], %l3; \
+ sllx %o7, 32, %o7; \
+ or %l0, %o7, %l0; \
+ lduw [%A_PTR + 0x1c], %o7; \
+ lduw [%A_PTR + 0x20], %l4; \
+ sllx %l5, 32, %l5; \
+ lduw [%A_PTR + 0x24], %l7; \
+ or %l1, %l5, %l1; \
+ sllx %l6, 32, %l6; \
+ or %l2, %l6, %l2; \
+ sllx %o7, 32, %o7; \
+ or %l3, %o7, %l3; \
+ sllx %l7, 32, %l7; \
+ or %l4, %l7, %l4;
+
+#define __LD_A_384(A_PTR) \
+ lduw [%A_PTR + 0x00], %l0; \
+ lduw [%A_PTR + 0x04], %o7; \
+ lduw [%A_PTR + 0x08], %l1; \
+ lduw [%A_PTR + 0x0c], %o0; \
+ lduw [%A_PTR + 0x10], %l2; \
+ lduw [%A_PTR + 0x14], %o2; \
+ lduw [%A_PTR + 0x18], %l3; \
+ sllx %o7, 32, %o7; \
+ or %l0, %o7, %l0; \
+ lduw [%A_PTR + 0x1c], %o7; \
+ lduw [%A_PTR + 0x20], %l4; \
+ sllx %o0, 32, %o0; \
+ lduw [%A_PTR + 0x24], %l7; \
+ or %l1, %o0, %l1; \
+ lduw [%A_PTR + 0x28], %l5; \
+ sllx %o2, 32, %o2; \
+ lduw [%A_PTR + 0x2c], %o1; \
+ or %l2, %o2, %l2; \
+ sllx %o7, 32, %o7; \
+ or %l3, %o7, %l3; \
+ sllx %l7, 32, %l7; \
+ or %l4, %l7, %l4; \
+ sllx %o1, 32, %o1; \
+ or %l5, %o1, %l5;
+
+#define __LD_A_448(A_PTR) \
+ lduw [%A_PTR + 0x00], %l0; \
+ lduw [%A_PTR + 0x04], %o7; \
+ lduw [%A_PTR + 0x08], %l1; \
+ lduw [%A_PTR + 0x0c], %o0; \
+ lduw [%A_PTR + 0x10], %l2; \
+ lduw [%A_PTR + 0x14], %o2; \
+ lduw [%A_PTR + 0x18], %l3; \
+ sllx %o7, 32, %o7; \
+ or %l0, %o7, %l0; \
+ lduw [%A_PTR + 0x1c], %o7; \
+ lduw [%A_PTR + 0x20], %l4; \
+ sllx %o0, 32, %o0; \
+ lduw [%A_PTR + 0x24], %l7; \
+ or %l1, %o0, %l1; \
+ lduw [%A_PTR + 0x28], %l5; \
+ sllx %o2, 32, %o2; \
+ lduw [%A_PTR + 0x2c], %o1; \
+ or %l2, %o2, %l2; \
+ lduw [%A_PTR + 0x30], %l6; \
+ sllx %o7, 32, %o7; \
+ lduw [%A_PTR + 0x34], %o3; \
+ or %l3, %o7, %l3; \
+ sllx %l7, 32, %l7; \
+ or %l4, %l7, %l4; \
+ sllx %o1, 32, %o1; \
+ or %l5, %o1, %l5; \
+ sllx %o3, 32, %o3; \
+ or %l6, %o3, %l6;
+
+#define __LD_A_512(A_PTR) \
+ lduw [%A_PTR + 0x00], %l0; \
+ lduw [%A_PTR + 0x04], %o7; \
+ lduw [%A_PTR + 0x08], %l1; \
+ lduw [%A_PTR + 0x0c], %o0; \
+ lduw [%A_PTR + 0x10], %l2; \
+ lduw [%A_PTR + 0x14], %o2; \
+ lduw [%A_PTR + 0x18], %l3; \
+ sllx %o7, 32, %o7; \
+ or %l0, %o7, %l0; \
+ lduw [%A_PTR + 0x1c], %o7; \
+ lduw [%A_PTR + 0x20], %l4; \
+ sllx %o0, 32, %o0; \
+ lduw [%A_PTR + 0x24], %o4; \
+ or %l1, %o0, %l1; \
+ lduw [%A_PTR + 0x28], %l5; \
+ sllx %o2, 32, %o2; \
+ lduw [%A_PTR + 0x2c], %o1; \
+ or %l2, %o2, %l2; \
+ lduw [%A_PTR + 0x30], %l6; \
+ sllx %o7, 32, %o7; \
+ lduw [%A_PTR + 0x34], %o3; \
+ or %l3, %o7, %l3; \
+ lduw [%A_PTR + 0x38], %l7; \
+ sllx %o4, 32, %o4; \
+ lduw [%A_PTR + 0x3c], %o5; \
+ or %l4, %o4, %l4; \
+ sllx %o1, 32, %o1; \
+ or %l5, %o1, %l5; \
+ sllx %o3, 32, %o3; \
+ or %l6, %o3, %l6; \
+ sllx %o5, 32, %o5; \
+ or %l7, %o5, %l7;
+
+#define __LD_A_576(A_PTR) \
+ lduw [%A_PTR + 0x00], %l0; \
+ lduw [%A_PTR + 0x04], %o7; \
+ lduw [%A_PTR + 0x08], %l1; \
+ lduw [%A_PTR + 0x0c], %o0; \
+ lduw [%A_PTR + 0x10], %l2; \
+ lduw [%A_PTR + 0x14], %o2; \
+ lduw [%A_PTR + 0x18], %l3; \
+ sllx %o7, 32, %o7; \
+ or %l0, %o7, %l0; \
+ lduw [%A_PTR + 0x1c], %o7; \
+ lduw [%A_PTR + 0x20], %l4; \
+ sllx %o0, 32, %o0; \
+ lduw [%A_PTR + 0x24], %o4; \
+ or %l1, %o0, %l1; \
+ lduw [%A_PTR + 0x28], %l5; \
+ sllx %o2, 32, %o2; \
+ lduw [%A_PTR + 0x2c], %o1; \
+ or %l2, %o2, %l2; \
+ lduw [%A_PTR + 0x30], %l6; \
+ sllx %o7, 32, %o7; \
+ lduw [%A_PTR + 0x34], %o3; \
+ or %l3, %o7, %l3; \
+ lduw [%A_PTR + 0x38], %l7; \
+ sllx %o4, 32, %o4; \
+ lduw [%A_PTR + 0x3c], %o5; \
+ or %l4, %o4, %l4; \
+ lduw [%A_PTR + 0x40], %o0; \
+ sllx %o1, 32, %o1; \
+ lduw [%A_PTR + 0x44], %o7; \
+ or %l5, %o1, %l5; \
+ sllx %o3, 32, %o3; \
+ or %l6, %o3, %l6; \
+ sllx %o5, 32, %o5; \
+ or %l7, %o5, %l7; \
+ sllx %o7, 32, %o7; \
+ or %o0, %o7, %o0;
+
+#define __LD_A_640(A_PTR) \
+ lduw [%A_PTR + 0x00], %l0; \
+ lduw [%A_PTR + 0x04], %o7; \
+ lduw [%A_PTR + 0x08], %l1; \
+ lduw [%A_PTR + 0x0c], %o0; \
+ lduw [%A_PTR + 0x10], %l2; \
+ lduw [%A_PTR + 0x14], %o2; \
+ lduw [%A_PTR + 0x18], %l3; \
+ sllx %o7, 32, %o7; \
+ or %l0, %o7, %l0; \
+ lduw [%A_PTR + 0x1c], %o7; \
+ lduw [%A_PTR + 0x20], %l4; \
+ sllx %o0, 32, %o0; \
+ lduw [%A_PTR + 0x24], %o4; \
+ or %l1, %o0, %l1; \
+ lduw [%A_PTR + 0x28], %l5; \
+ sllx %o2, 32, %o2; \
+ lduw [%A_PTR + 0x2c], %o1; \
+ or %l2, %o2, %l2; \
+ lduw [%A_PTR + 0x30], %l6; \
+ sllx %o7, 32, %o7; \
+ lduw [%A_PTR + 0x34], %o3; \
+ or %l3, %o7, %l3; \
+ lduw [%A_PTR + 0x38], %l7; \
+ sllx %o4, 32, %o4; \
+ lduw [%A_PTR + 0x3c], %o5; \
+ or %l4, %o4, %l4; \
+ lduw [%A_PTR + 0x40], %o0; \
+ sllx %o1, 32, %o1; \
+ lduw [%A_PTR + 0x44], %o7; \
+ or %l5, %o1, %l5; \
+ lduw [%A_PTR + 0x48], %o1; \
+ sllx %o3, 32, %o3; \
+ lduw [%A_PTR + 0x4c], %o2; \
+ or %l6, %o3, %l6; \
+ sllx %o5, 32, %o5; \
+ or %l7, %o5, %l7; \
+ sllx %o7, 32, %o7; \
+ or %o0, %o7, %o0; \
+ sllx %o2, 32, %o2; \
+ or %o1, %o2, %o1;
+
+#define __LD_A_704(A_PTR) \
+ __LD_A_640(A_PTR); \
+ lduw [%A_PTR + 0x50], %o2; \
+ lduw [%A_PTR + 0x54], %o3; \
+ sllx %o3, 32, %o3; \
+ or %o2, %o3, %o2;
+
+#define __LD_A_768(A_PTR) \
+ __LD_A_704(A_PTR); \
+ lduw [%A_PTR + 0x58], %o3; \
+ lduw [%A_PTR + 0x5c], %o4; \
+ sllx %o4, 32, %o4; \
+ or %o3, %o4, %o3;
+
+#define __LD_A_832(A_PTR) \
+ __LD_A_768(A_PTR); \
+ lduw [%A_PTR + 0x60], %o4; \
+ lduw [%A_PTR + 0x64], %o5; \
+ sllx %o5, 32, %o5; \
+ or %o4, %o5, %o4;
+
+#define __LD_A_896(A_PTR) \
+ __LD_A_832(A_PTR); \
+ lduw [%A_PTR + 0x68], %o5; \
+ lduw [%A_PTR + 0x6c], %o7; \
+ sllx %o7, 32, %o7; \
+ or %o5, %o7, %o5;
+
+#define __LD_A_960(A_PTR) \
+ __LD_A_896(A_PTR); \
+ ld [%A_PTR + 0x70], %f1; \
+ ld [%A_PTR + 0x74], %f0; \
+ fsrc2 %f0, %f24;
+
+#define __LD_A_1024(A_PTR) \
+ __LD_A_896(A_PTR); \
+ ld [%A_PTR + 0x70], %f1; \
+ ld [%A_PTR + 0x74], %f0; \
+ ld [%A_PTR + 0x78], %f3; \
+ ld [%A_PTR + 0x7c], %f2; \
+ fsrc2 %f0, %f24; \
+ fsrc2 %f2, %f26;
+
+#define __LD_A_1088(A_PTR) \
+ __LD_A_896(A_PTR); \
+ ld [%A_PTR + 0x70], %f1; \
+ ld [%A_PTR + 0x74], %f0; \
+ ld [%A_PTR + 0x78], %f3; \
+ ld [%A_PTR + 0x7c], %f2; \
+ ld [%A_PTR + 0x80], %f5; \
+ ld [%A_PTR + 0x84], %f4; \
+ fsrc2 %f0, %f24; \
+ fsrc2 %f2, %f26; \
+ fsrc2 %f4, %f28;
+
+#define __LD_A_1152(A_PTR) \
+ __LD_A_896(A_PTR); \
+ ld [%A_PTR + 0x70], %f1; \
+ ld [%A_PTR + 0x74], %f0; \
+ ld [%A_PTR + 0x78], %f3; \
+ ld [%A_PTR + 0x7c], %f2; \
+ ld [%A_PTR + 0x80], %f5; \
+ ld [%A_PTR + 0x84], %f4; \
+ fsrc2 %f0, %f24; \
+ ld [%A_PTR + 0x88], %f7; \
+ ld [%A_PTR + 0x8c], %f6; \
+ fsrc2 %f2, %f26; \
+ fsrc2 %f4, %f28; \
+ fsrc2 %f6, %f30;
+
+#define __LD_A_1216(A_PTR) \
+ __LD_A_896(A_PTR); \
+ ld [%A_PTR + 0x70], %f1; \
+ ld [%A_PTR + 0x74], %f0; \
+ ld [%A_PTR + 0x78], %f3; \
+ ld [%A_PTR + 0x7c], %f2; \
+ ld [%A_PTR + 0x80], %f5; \
+ ld [%A_PTR + 0x84], %f4; \
+ fsrc2 %f0, %f24; \
+ ld [%A_PTR + 0x88], %f7; \
+ ld [%A_PTR + 0x8c], %f6; \
+ fsrc2 %f2, %f26; \
+ ld [%A_PTR + 0x90], %f9; \
+ ld [%A_PTR + 0x94], %f8; \
+ fsrc2 %f4, %f28; \
+ fsrc2 %f6, %f30; \
+ fsrc2 %f8, %f32;
+
+#define __LD_A_1280(A_PTR) \
+ __LD_A_896(A_PTR); \
+ ld [%A_PTR + 0x70], %f1; \
+ ld [%A_PTR + 0x74], %f0; \
+ ld [%A_PTR + 0x78], %f3; \
+ ld [%A_PTR + 0x7c], %f2; \
+ ld [%A_PTR + 0x80], %f5; \
+ ld [%A_PTR + 0x84], %f4; \
+ fsrc2 %f0, %f24; \
+ ld [%A_PTR + 0x88], %f7; \
+ ld [%A_PTR + 0x8c], %f6; \
+ fsrc2 %f2, %f26; \
+ ld [%A_PTR + 0x90], %f9; \
+ ld [%A_PTR + 0x94], %f8; \
+ fsrc2 %f4, %f28; \
+ ld [%A_PTR + 0x98], %f11; \
+ ld [%A_PTR + 0x9c], %f10; \
+ fsrc2 %f6, %f30; \
+ fsrc2 %f8, %f32; \
+ fsrc2 %f10, %f34;
+
+#define __LD_A_1344(A_PTR) \
+ __LD_A_896(A_PTR); \
+ ld [%A_PTR + 0x70], %f1; \
+ ld [%A_PTR + 0x74], %f0; \
+ ld [%A_PTR + 0x78], %f3; \
+ ld [%A_PTR + 0x7c], %f2; \
+ ld [%A_PTR + 0x80], %f5; \
+ ld [%A_PTR + 0x84], %f4; \
+ fsrc2 %f0, %f24; \
+ ld [%A_PTR + 0x88], %f7; \
+ ld [%A_PTR + 0x8c], %f6; \
+ fsrc2 %f2, %f26; \
+ ld [%A_PTR + 0x90], %f9; \
+ ld [%A_PTR + 0x94], %f8; \
+ fsrc2 %f4, %f28; \
+ ld [%A_PTR + 0x98], %f11; \
+ ld [%A_PTR + 0x9c], %f10; \
+ fsrc2 %f6, %f30; \
+ ld [%A_PTR + 0xa0], %f13; \
+ ld [%A_PTR + 0xa4], %f12; \
+ fsrc2 %f8, %f32; \
+ fsrc2 %f10, %f34; \
+ fsrc2 %f12, %f36;
+
+#define __LD_A_1408(A_PTR) \
+ __LD_A_896(A_PTR); \
+ ld [%A_PTR + 0x70], %f1; \
+ ld [%A_PTR + 0x74], %f0; \
+ ld [%A_PTR + 0x78], %f3; \
+ ld [%A_PTR + 0x7c], %f2; \
+ ld [%A_PTR + 0x80], %f5; \
+ ld [%A_PTR + 0x84], %f4; \
+ fsrc2 %f0, %f24; \
+ ld [%A_PTR + 0x88], %f7; \
+ ld [%A_PTR + 0x8c], %f6; \
+ fsrc2 %f2, %f26; \
+ ld [%A_PTR + 0x90], %f9; \
+ ld [%A_PTR + 0x94], %f8; \
+ fsrc2 %f4, %f28; \
+ ld [%A_PTR + 0x98], %f11; \
+ ld [%A_PTR + 0x9c], %f10; \
+ fsrc2 %f6, %f30; \
+ ld [%A_PTR + 0xa0], %f13; \
+ ld [%A_PTR + 0xa4], %f12; \
+ fsrc2 %f8, %f32; \
+ ld [%A_PTR + 0xa8], %f15; \
+ ld [%A_PTR + 0xac], %f14; \
+ fsrc2 %f10, %f34; \
+ fsrc2 %f12, %f36; \
+ fsrc2 %f14, %f38;
+
+#define __LD_A_1472(A_PTR) \
+ __LD_A_896(A_PTR); \
+ ld [%A_PTR + 0x70], %f1; \
+ ld [%A_PTR + 0x74], %f0; \
+ ld [%A_PTR + 0x78], %f3; \
+ ld [%A_PTR + 0x7c], %f2; \
+ ld [%A_PTR + 0x80], %f5; \
+ ld [%A_PTR + 0x84], %f4; \
+ fsrc2 %f0, %f24; \
+ ld [%A_PTR + 0x88], %f7; \
+ ld [%A_PTR + 0x8c], %f6; \
+ fsrc2 %f2, %f26; \
+ ld [%A_PTR + 0x90], %f9; \
+ ld [%A_PTR + 0x94], %f8; \
+ fsrc2 %f4, %f28; \
+ ld [%A_PTR + 0x98], %f11; \
+ ld [%A_PTR + 0x9c], %f10; \
+ fsrc2 %f6, %f30; \
+ ld [%A_PTR + 0xa0], %f13; \
+ ld [%A_PTR + 0xa4], %f12; \
+ fsrc2 %f8, %f32; \
+ ld [%A_PTR + 0xa8], %f15; \
+ ld [%A_PTR + 0xac], %f14; \
+ fsrc2 %f10, %f34; \
+ ld [%A_PTR + 0xb0], %f17; \
+ ld [%A_PTR + 0xb4], %f16; \
+ fsrc2 %f12, %f36; \
+ fsrc2 %f14, %f38; \
+ fsrc2 %f16, %f40;
+
+#define __LD_A_1536(A_PTR) \
+ __LD_A_896(A_PTR); \
+ ld [%A_PTR + 0x70], %f1; \
+ ld [%A_PTR + 0x74], %f0; \
+ ld [%A_PTR + 0x78], %f3; \
+ ld [%A_PTR + 0x7c], %f2; \
+ ld [%A_PTR + 0x80], %f5; \
+ ld [%A_PTR + 0x84], %f4; \
+ fsrc2 %f0, %f24; \
+ ld [%A_PTR + 0x88], %f7; \
+ ld [%A_PTR + 0x8c], %f6; \
+ fsrc2 %f2, %f26; \
+ ld [%A_PTR + 0x90], %f9; \
+ ld [%A_PTR + 0x94], %f8; \
+ fsrc2 %f4, %f28; \
+ ld [%A_PTR + 0x98], %f11; \
+ ld [%A_PTR + 0x9c], %f10; \
+ fsrc2 %f6, %f30; \
+ ld [%A_PTR + 0xa0], %f13; \
+ ld [%A_PTR + 0xa4], %f12; \
+ fsrc2 %f8, %f32; \
+ ld [%A_PTR + 0xa8], %f15; \
+ ld [%A_PTR + 0xac], %f14; \
+ fsrc2 %f10, %f34; \
+ ld [%A_PTR + 0xb0], %f17; \
+ ld [%A_PTR + 0xb4], %f16; \
+ fsrc2 %f12, %f36; \
+ ld [%A_PTR + 0xb8], %f19; \
+ ld [%A_PTR + 0xbc], %f18; \
+ fsrc2 %f14, %f38; \
+ fsrc2 %f16, %f40; \
+ fsrc2 %f18, %f42;
+
+#define __LD_A_1600(A_PTR) \
+ __LD_A_896(A_PTR); \
+ ld [%A_PTR + 0x70], %f1; \
+ ld [%A_PTR + 0x74], %f0; \
+ ld [%A_PTR + 0x78], %f3; \
+ ld [%A_PTR + 0x7c], %f2; \
+ ld [%A_PTR + 0x80], %f5; \
+ ld [%A_PTR + 0x84], %f4; \
+ fsrc2 %f0, %f24; \
+ ld [%A_PTR + 0x88], %f7; \
+ ld [%A_PTR + 0x8c], %f6; \
+ fsrc2 %f2, %f26; \
+ ld [%A_PTR + 0x90], %f9; \
+ ld [%A_PTR + 0x94], %f8; \
+ fsrc2 %f4, %f28; \
+ ld [%A_PTR + 0x98], %f11; \
+ ld [%A_PTR + 0x9c], %f10; \
+ fsrc2 %f6, %f30; \
+ ld [%A_PTR + 0xa0], %f13; \
+ ld [%A_PTR + 0xa4], %f12; \
+ fsrc2 %f8, %f32; \
+ ld [%A_PTR + 0xa8], %f15; \
+ ld [%A_PTR + 0xac], %f14; \
+ fsrc2 %f10, %f34; \
+ ld [%A_PTR + 0xb0], %f17; \
+ ld [%A_PTR + 0xb4], %f16; \
+ fsrc2 %f12, %f36; \
+ ld [%A_PTR + 0xb8], %f19; \
+ ld [%A_PTR + 0xbc], %f18; \
+ fsrc2 %f14, %f38; \
+ ld [%A_PTR + 0xc0], %f21; \
+ ld [%A_PTR + 0xc4], %f20; \
+ fsrc2 %f16, %f40; \
+ fsrc2 %f18, %f42; \
+ fsrc2 %f20, %f44;
+
+#define __LD_A_1664(A_PTR) \
+ __LD_A_896(A_PTR); \
+ ld [%A_PTR + 0x70], %f1; \
+ ld [%A_PTR + 0x74], %f0; \
+ ld [%A_PTR + 0x78], %f3; \
+ ld [%A_PTR + 0x7c], %f2; \
+ ld [%A_PTR + 0x80], %f5; \
+ ld [%A_PTR + 0x84], %f4; \
+ fsrc2 %f0, %f24; \
+ ld [%A_PTR + 0x88], %f7; \
+ ld [%A_PTR + 0x8c], %f6; \
+ fsrc2 %f2, %f26; \
+ ld [%A_PTR + 0x90], %f9; \
+ ld [%A_PTR + 0x94], %f8; \
+ fsrc2 %f4, %f28; \
+ ld [%A_PTR + 0x98], %f11; \
+ ld [%A_PTR + 0x9c], %f10; \
+ fsrc2 %f6, %f30; \
+ ld [%A_PTR + 0xa0], %f13; \
+ ld [%A_PTR + 0xa4], %f12; \
+ fsrc2 %f8, %f32; \
+ ld [%A_PTR + 0xa8], %f15; \
+ ld [%A_PTR + 0xac], %f14; \
+ fsrc2 %f10, %f34; \
+ ld [%A_PTR + 0xb0], %f17; \
+ ld [%A_PTR + 0xb4], %f16; \
+ fsrc2 %f12, %f36; \
+ ld [%A_PTR + 0xb8], %f19; \
+ ld [%A_PTR + 0xbc], %f18; \
+ fsrc2 %f14, %f38; \
+ ld [%A_PTR + 0xc0], %f21; \
+ ld [%A_PTR + 0xc4], %f20; \
+ fsrc2 %f16, %f40; \
+ ld [%A_PTR + 0xc8], %f23; \
+ ld [%A_PTR + 0xcc], %f22; \
+ fsrc2 %f18, %f42; \
+ fsrc2 %f20, %f44; \
+ fsrc2 %f22, %f46;
+
+#define __LD_A_1728(A_PTR) \
+ __LD_A_1664(A_PTR); \
+ ld [%A_PTR + 0xd0], %f1; \
+ ld [%A_PTR + 0xd4], %f0; \
+ fsrc2 %f0, %f48;
+
+#define __LD_A_1792(A_PTR) \
+ __LD_A_1664(A_PTR); \
+ ld [%A_PTR + 0xd0], %f1; \
+ ld [%A_PTR + 0xd4], %f0; \
+ ld [%A_PTR + 0xd8], %f3; \
+ ld [%A_PTR + 0xdc], %f2; \
+ fsrc2 %f0, %f48; \
+ fsrc2 %f2, %f50;
+
+#define __LD_A_1856(A_PTR) \
+ __LD_A_1664(A_PTR); \
+ ld [%A_PTR + 0xd0], %f1; \
+ ld [%A_PTR + 0xd4], %f0; \
+ ld [%A_PTR + 0xd8], %f3; \
+ ld [%A_PTR + 0xdc], %f2; \
+ ld [%A_PTR + 0xe0], %f5; \
+ ld [%A_PTR + 0xe4], %f4; \
+ fsrc2 %f0, %f48; \
+ fsrc2 %f2, %f50; \
+ fsrc2 %f4, %f52;
+
+#define __LD_A_1920(A_PTR) \
+ __LD_A_1664(A_PTR); \
+ ld [%A_PTR + 0xd0], %f1; \
+ ld [%A_PTR + 0xd4], %f0; \
+ ld [%A_PTR + 0xd8], %f3; \
+ ld [%A_PTR + 0xdc], %f2; \
+ ld [%A_PTR + 0xe0], %f5; \
+ ld [%A_PTR + 0xe4], %f4; \
+ fsrc2 %f0, %f48; \
+ ld [%A_PTR + 0xe8], %f7; \
+ ld [%A_PTR + 0xec], %f6; \
+ fsrc2 %f2, %f50; \
+ fsrc2 %f4, %f52; \
+ fsrc2 %f6, %f54;
+
+#define __LD_A_1984(A_PTR) \
+ __LD_A_1664(A_PTR); \
+ ld [%A_PTR + 0xd0], %f1; \
+ ld [%A_PTR + 0xd4], %f0; \
+ ld [%A_PTR + 0xd8], %f3; \
+ ld [%A_PTR + 0xdc], %f2; \
+ ld [%A_PTR + 0xe0], %f5; \
+ ld [%A_PTR + 0xe4], %f4; \
+ fsrc2 %f0, %f48; \
+ ld [%A_PTR + 0xe8], %f7; \
+ ld [%A_PTR + 0xec], %f6; \
+ fsrc2 %f2, %f50; \
+ ld [%A_PTR + 0xf0], %f9; \
+ ld [%A_PTR + 0xf4], %f8; \
+ fsrc2 %f4, %f52; \
+ fsrc2 %f6, %f54; \
+ fsrc2 %f8, %f56;
+
+#define __LD_A_2048(A_PTR) \
+ __LD_A_1664(A_PTR); \
+ ld [%A_PTR + 0xd0], %f1; \
+ ld [%A_PTR + 0xd4], %f0; \
+ ld [%A_PTR + 0xd8], %f3; \
+ ld [%A_PTR + 0xdc], %f2; \
+ ld [%A_PTR + 0xe0], %f5; \
+ ld [%A_PTR + 0xe4], %f4; \
+ fsrc2 %f0, %f48; \
+ ld [%A_PTR + 0xe8], %f7; \
+ ld [%A_PTR + 0xec], %f6; \
+ fsrc2 %f2, %f50; \
+ ld [%A_PTR + 0xf0], %f9; \
+ ld [%A_PTR + 0xf4], %f8; \
+ fsrc2 %f4, %f52; \
+ ld [%A_PTR + 0xf8], %f11; \
+ ld [%A_PTR + 0xfc], %f10; \
+ fsrc2 %f6, %f54; \
+ fsrc2 %f8, %f56; \
+ fsrc2 %f10, %f58;
+
+#define SAVE1 \
+ save %sp, -FRAME_SIZE, %sp;
+#define SAVE2 \
+ save %sp, -FRAME_SIZE, %sp; \
+ save %sp, -FRAME_SIZE, %sp;
+
+#define LD_A(A_PTR, BITS) \
+ __LD_A_##BITS##(A_PTR); \
+ SAVE1;
+
+/* "NS" stands for 'no-save' */
+#define __LD_N_64_NS(N_PTR) __LD_A_64(N_PTR)
+#define __LD_N_64(N_PTR) __LD_N_64_NS(N_PTR); SAVE2;
+#define __LD_N_128_NS(N_PTR) __LD_A_128(N_PTR)
+#define __LD_N_128(N_PTR) __LD_N_128_NS(N_PTR); SAVE2;
+#define __LD_N_192_NS(N_PTR) __LD_A_192(N_PTR)
+#define __LD_N_192(N_PTR) __LD_N_192_NS(N_PTR); SAVE2;
+#define __LD_N_256_NS(N_PTR) __LD_A_256(N_PTR)
+#define __LD_N_256(N_PTR) __LD_N_256_NS(N_PTR); SAVE2;
+#define __LD_N_320_NS(N_PTR) __LD_A_320(N_PTR)
+#define __LD_N_320(N_PTR) __LD_N_320_NS(N_PTR); SAVE2;
+#define __LD_N_384_NS(N_PTR) __LD_A_384(N_PTR)
+#define __LD_N_384(N_PTR) __LD_N_384_NS(N_PTR); SAVE2;
+#define __LD_N_448_NS(N_PTR) __LD_A_448(N_PTR)
+#define __LD_N_448(N_PTR) __LD_N_448_NS(N_PTR); SAVE2;
+#define __LD_N_512_NS(N_PTR) __LD_A_512(N_PTR)
+#define __LD_N_512(N_PTR) __LD_N_512_NS(N_PTR); SAVE2;
+#define __LD_N_576_NS(N_PTR) __LD_A_576(N_PTR)
+#define __LD_N_576(N_PTR) __LD_N_576_NS(N_PTR); SAVE2;
+#define __LD_N_640_NS(N_PTR) __LD_A_640(N_PTR)
+#define __LD_N_640(N_PTR) __LD_N_640_NS(N_PTR); SAVE2;
+#define __LD_N_704_NS(N_PTR) __LD_A_704(N_PTR)
+#define __LD_N_704(N_PTR) __LD_N_704_NS(N_PTR); SAVE2;
+#define __LD_N_768_NS(N_PTR) __LD_A_768(N_PTR)
+#define __LD_N_768(N_PTR) __LD_N_768_NS(N_PTR); SAVE2;
+#define __LD_N_832_NS(N_PTR) __LD_A_832(N_PTR)
+#define __LD_N_832(N_PTR) __LD_N_832_NS(N_PTR); SAVE2;
+#define __LD_N_896_NS(N_PTR) __LD_A_896(N_PTR)
+#define __LD_N_896(N_PTR) __LD_N_896_NS(N_PTR); SAVE2;
+
+#define __LD_N_960_NS(N_PTR) \
+ __LD_N_896_NS(N_PTR); \
+ SAVE1; \
+ __LD_A_64(N_PTR + 0x70);
+#define __LD_N_960(N_PTR) __LD_N_960_NS(N_PTR); SAVE1;
+
+#define __LD_N_1024_NS(N_PTR) \
+ __LD_N_896_NS(N_PTR); \
+ SAVE1; \
+ __LD_A_128(N_PTR + 0x70);
+#define __LD_N_1024(N_PTR) __LD_N_1024_NS(N_PTR); SAVE1;
+
+#define __LD_N_1088_NS(N_PTR) \
+ __LD_N_896_NS(N_PTR); \
+ SAVE1; \
+ __LD_A_192(N_PTR + 0x70);
+#define __LD_N_1088(N_PTR) __LD_N_1088_NS(N_PTR); SAVE1;
+
+#define __LD_N_1152_NS(N_PTR) \
+ __LD_N_896_NS(N_PTR); \
+ SAVE1; \
+ __LD_A_256(N_PTR + 0x70);
+#define __LD_N_1152(N_PTR) __LD_N_1152_NS(N_PTR); SAVE1;
+
+#define __LD_N_1216_NS(N_PTR) \
+ __LD_N_896_NS(N_PTR); \
+ SAVE1; \
+ __LD_A_320(N_PTR + 0x70);
+#define __LD_N_1216(N_PTR) __LD_N_1216_NS(N_PTR); SAVE1;
+
+#define __LD_N_1280_NS(N_PTR) \
+ __LD_N_896_NS(N_PTR); \
+ SAVE1; \
+ __LD_A_384(N_PTR + 0x70);
+#define __LD_N_1280(N_PTR) __LD_N_1280_NS(N_PTR); SAVE1;
+
+#define __LD_N_1344_NS(N_PTR) \
+ __LD_N_896_NS(N_PTR); \
+ SAVE1; \
+ __LD_A_448(N_PTR + 0x70);
+#define __LD_N_1344(N_PTR) __LD_N_1344_NS(N_PTR); SAVE1;
+
+#define __LD_N_1408_NS(N_PTR) \
+ __LD_N_896_NS(N_PTR); \
+ SAVE1; \
+ __LD_A_512(N_PTR + 0x70);
+#define __LD_N_1408(N_PTR) __LD_N_1408_NS(N_PTR); SAVE1;
+
+#define __LD_N_1472_NS(N_PTR) \
+ __LD_N_896_NS(N_PTR); \
+ SAVE1; \
+ __LD_A_576(N_PTR + 0x70);
+#define __LD_N_1472(N_PTR) __LD_N_1472_NS(N_PTR); SAVE1;
+
+#define __LD_N_1536_NS(N_PTR) \
+ __LD_N_896_NS(N_PTR); \
+ SAVE1; \
+ __LD_A_640(N_PTR + 0x70);
+#define __LD_N_1536(N_PTR) __LD_N_1536_NS(N_PTR); SAVE1;
+
+#define __LD_N_1600_NS(N_PTR) \
+ __LD_N_896_NS(N_PTR); \
+ SAVE1; \
+ __LD_A_704(N_PTR + 0x70);
+#define __LD_N_1600(N_PTR) __LD_N_1600_NS(N_PTR); SAVE1;
+
+#define __LD_N_1664_NS(N_PTR) \
+ __LD_N_896_NS(N_PTR); \
+ SAVE1; \
+ __LD_A_768(N_PTR + 0x70);
+#define __LD_N_1664(N_PTR) __LD_N_1664_NS(N_PTR); SAVE1;
+
+#define __LD_N_1728_NS(N_PTR) \
+ __LD_N_896_NS(N_PTR); \
+ SAVE1; \
+ __LD_A_832(N_PTR + 0x70);
+#define __LD_N_1728(N_PTR) __LD_N_1728_NS(N_PTR); SAVE1;
+
+#define __LD_N_1792_NS(N_PTR) \
+ __LD_N_896_NS(N_PTR); \
+ SAVE1; \
+ __LD_A_896(N_PTR + 0x70);
+#define __LD_N_1792(N_PTR) __LD_N_1792_NS(N_PTR); SAVE1;
+
+#define __LD_N_1856(N_PTR) \
+ __LD_N_1792(N_PTR); \
+ __LD_A_64(N_PTR + 0xe0);
+#define __LD_N_1920(N_PTR) \
+ __LD_N_1792(N_PTR); \
+ __LD_A_128(N_PTR + 0xe0);
+#define __LD_N_1984(N_PTR) \
+ __LD_N_1792(N_PTR); \
+ __LD_A_192(N_PTR + 0xe0);
+#define __LD_N_2048(N_PTR) \
+ __LD_N_1792(N_PTR); \
+ __LD_A_256(N_PTR + 0xe0);
+
+#define LD_N(N_PTR, BITS) \
+ __LD_N_##BITS##(N_PTR); \
+
+#define __LD_B_64_NS(B_PTR) \
+ SAVE1; \
+ lduw [%B_PTR + 0x00], %i0; \
+ lduw [%B_PTR + 0x04], %o7; \
+ sllx %o7, 32, %o7; \
+ or %i0, %o7, %i0;
+#define __LD_B_64(B_PTR) __LD_B_64_NS(B_PTR); SAVE1;
+
+#define __LD_B_128_NS(B_PTR) \
+ SAVE1; \
+ lduw [%B_PTR + 0x00], %i0; \
+ lduw [%B_PTR + 0x04], %o7; \
+ lduw [%B_PTR + 0x08], %i1; \
+ lduw [%B_PTR + 0x0c], %i2; \
+ sllx %o7, 32, %o7; \
+ or %i0, %o7, %i0; \
+ sllx %i2, 32, %i2; \
+ or %i1, %i2, %i1;
+#define __LD_B_128(B_PTR) __LD_B_128_NS(B_PTR); SAVE1;
+
+#define __LD_B_192_NS(B_PTR) \
+ SAVE1; \
+ lduw [%B_PTR + 0x00], %i0; \
+ lduw [%B_PTR + 0x04], %o7; \
+ lduw [%B_PTR + 0x08], %i1; \
+ lduw [%B_PTR + 0x0c], %i3; \
+ lduw [%B_PTR + 0x10], %i2; \
+ lduw [%B_PTR + 0x14], %i4; \
+ sllx %o7, 32, %o7; \
+ or %i0, %o7, %i0; \
+ sllx %i3, 32, %i3; \
+ or %i1, %i3, %i1; \
+ sllx %i4, 32, %i4; \
+ or %i2, %i4, %i2;
+#define __LD_B_192(B_PTR) __LD_B_192_NS(B_PTR); SAVE1;
+
+#define __LD_B_256_NS(B_PTR) \
+ SAVE1; \
+ lduw [%B_PTR + 0x00], %i0; \
+ lduw [%B_PTR + 0x04], %o7; \
+ lduw [%B_PTR + 0x08], %i1; \
+ lduw [%B_PTR + 0x0c], %i5; \
+ lduw [%B_PTR + 0x10], %i2; \
+ lduw [%B_PTR + 0x14], %i4; \
+ lduw [%B_PTR + 0x18], %i3; \
+ sllx %o7, 32, %o7; \
+ or %i0, %o7, %i0; \
+ lduw [%B_PTR + 0x1c], %o7; \
+ sllx %i5, 32, %i5; \
+ or %i1, %i5, %i1; \
+ sllx %i4, 32, %i4; \
+ or %i2, %i4, %i2; \
+ sllx %o7, 32, %o7; \
+ or %i3, %o7, %i3;
+#define __LD_B_256(B_PTR) __LD_B_256_NS(B_PTR); SAVE1;
+
+#define __LD_B_320_NS(B_PTR) \
+ SAVE1; \
+ lduw [%B_PTR + 0x00], %i0; \
+ lduw [%B_PTR + 0x04], %o7; \
+ lduw [%B_PTR + 0x08], %i1; \
+ lduw [%B_PTR + 0x0c], %i5; \
+ lduw [%B_PTR + 0x10], %i2; \
+ lduw [%B_PTR + 0x14], %l0; \
+ lduw [%B_PTR + 0x18], %i3; \
+ sllx %o7, 32, %o7; \
+ or %i0, %o7, %i0; \
+ lduw [%B_PTR + 0x1c], %o7; \
+ lduw [%B_PTR + 0x20], %i4; \
+ sllx %i5, 32, %i5; \
+ lduw [%B_PTR + 0x24], %l1; \
+ or %i1, %i5, %i1; \
+ sllx %l0, 32, %l0; \
+ or %i2, %l0, %i2; \
+ sllx %o7, 32, %o7; \
+ or %i3, %o7, %i3; \
+ sllx %l1, 32, %l1; \
+ or %i4, %l1, %i4;
+#define __LD_B_320(B_PTR) __LD_B_320_NS(B_PTR); SAVE1;
+
+#define __LD_B_384_NS(B_PTR) \
+ SAVE1; \
+ lduw [%B_PTR + 0x00], %i0; \
+ lduw [%B_PTR + 0x04], %o7; \
+ lduw [%B_PTR + 0x08], %i1; \
+ lduw [%B_PTR + 0x0c], %i5; \
+ lduw [%B_PTR + 0x10], %i2; \
+ lduw [%B_PTR + 0x14], %l0; \
+ lduw [%B_PTR + 0x18], %i3; \
+ sllx %o7, 32, %o7; \
+ or %i0, %o7, %i0; \
+ lduw [%B_PTR + 0x1c], %o7; \
+ lduw [%B_PTR + 0x20], %i4; \
+ sllx %i5, 32, %i5; \
+ lduw [%B_PTR + 0x24], %l1; \
+ or %i1, %i5, %i1; \
+ lduw [%B_PTR + 0x28], %i5; \
+ sllx %l0, 32, %l0; \
+ lduw [%B_PTR + 0x2c], %l2; \
+ or %i2, %l0, %i2; \
+ sllx %o7, 32, %o7; \
+ or %i3, %o7, %i3; \
+ sllx %l1, 32, %l1; \
+ or %i4, %l1, %i4; \
+ sllx %l2, 32, %l2; \
+ or %i5, %l2, %i5;
+#define __LD_B_384(B_PTR) __LD_B_384_NS(B_PTR); SAVE1;
+
+#define __LD_B_448_NS(B_PTR) \
+ SAVE1; \
+ lduw [%B_PTR + 0x00], %i0; \
+ lduw [%B_PTR + 0x04], %o7; \
+ lduw [%B_PTR + 0x08], %i1; \
+ lduw [%B_PTR + 0x0c], %i5; \
+ lduw [%B_PTR + 0x10], %i2; \
+ lduw [%B_PTR + 0x14], %l0; \
+ lduw [%B_PTR + 0x18], %i3; \
+ sllx %o7, 32, %o7; \
+ or %i0, %o7, %i0; \
+ lduw [%B_PTR + 0x1c], %o7; \
+ lduw [%B_PTR + 0x20], %i4; \
+ sllx %i5, 32, %i5; \
+ lduw [%B_PTR + 0x24], %l1; \
+ or %i1, %i5, %i1; \
+ lduw [%B_PTR + 0x28], %i5; \
+ sllx %l0, 32, %l0; \
+ lduw [%B_PTR + 0x2c], %l2; \
+ or %i2, %l0, %i2; \
+ lduw [%B_PTR + 0x30], %l0; \
+ sllx %o7, 32, %o7; \
+ lduw [%B_PTR + 0x34], %o0; \
+ or %i3, %o7, %i3; \
+ sllx %l1, 32, %l1; \
+ or %i4, %l1, %i4; \
+ sllx %l2, 32, %l2; \
+ or %i5, %l2, %i5; \
+ sllx %o0, 32, %o0; \
+ or %l0, %o0, %l0;
+#define __LD_B_448(B_PTR) __LD_B_448_NS(B_PTR); SAVE1;
+
+#define __LD_B_512_NS(B_PTR) \
+ SAVE1; \
+ lduw [%B_PTR + 0x00], %i0; \
+ lduw [%B_PTR + 0x04], %o7; \
+ lduw [%B_PTR + 0x08], %i1; \
+ lduw [%B_PTR + 0x0c], %i5; \
+ lduw [%B_PTR + 0x10], %i2; \
+ lduw [%B_PTR + 0x14], %l0; \
+ lduw [%B_PTR + 0x18], %i3; \
+ sllx %o7, 32, %o7; \
+ or %i0, %o7, %i0; \
+ lduw [%B_PTR + 0x1c], %o7; \
+ lduw [%B_PTR + 0x20], %i4; \
+ sllx %i5, 32, %i5; \
+ lduw [%B_PTR + 0x24], %l1; \
+ or %i1, %i5, %i1; \
+ lduw [%B_PTR + 0x28], %i5; \
+ sllx %l0, 32, %l0; \
+ lduw [%B_PTR + 0x2c], %l2; \
+ or %i2, %l0, %i2; \
+ lduw [%B_PTR + 0x30], %l0; \
+ sllx %o7, 32, %o7; \
+ lduw [%B_PTR + 0x34], %o0; \
+ or %i3, %o7, %i3; \
+ sllx %l1, 32, %l1; \
+ or %i4, %l1, %i4; \
+ lduw [%B_PTR + 0x38], %l1; \
+ lduw [%B_PTR + 0x3c], %o1; \
+ sllx %l2, 32, %l2; \
+ or %i5, %l2, %i5; \
+ sllx %o0, 32, %o0; \
+ or %l0, %o0, %l0; \
+ sllx %o1, 32, %o1; \
+ or %l1, %o1, %l1;
+#define __LD_B_512(B_PTR) __LD_B_512_NS(B_PTR); SAVE1;
+
+#define __LD_B_576_NS(B_PTR) \
+ SAVE1; \
+ lduw [%B_PTR + 0x00], %i0; \
+ lduw [%B_PTR + 0x04], %o7; \
+ lduw [%B_PTR + 0x08], %i1; \
+ lduw [%B_PTR + 0x0c], %i5; \
+ lduw [%B_PTR + 0x10], %i2; \
+ lduw [%B_PTR + 0x14], %l0; \
+ lduw [%B_PTR + 0x18], %i3; \
+ sllx %o7, 32, %o7; \
+ or %i0, %o7, %i0; \
+ lduw [%B_PTR + 0x1c], %o7; \
+ lduw [%B_PTR + 0x20], %i4; \
+ sllx %i5, 32, %i5; \
+ lduw [%B_PTR + 0x24], %l1; \
+ or %i1, %i5, %i1; \
+ lduw [%B_PTR + 0x28], %i5; \
+ sllx %l0, 32, %l0; \
+ lduw [%B_PTR + 0x2c], %l2; \
+ or %i2, %l0, %i2; \
+ lduw [%B_PTR + 0x30], %l0; \
+ sllx %o7, 32, %o7; \
+ lduw [%B_PTR + 0x34], %o0; \
+ or %i3, %o7, %i3; \
+ sllx %l1, 32, %l1; \
+ or %i4, %l1, %i4; \
+ lduw [%B_PTR + 0x38], %l1; \
+ lduw [%B_PTR + 0x3c], %o1; \
+ sllx %l2, 32, %l2; \
+ or %i5, %l2, %i5; \
+ lduw [%B_PTR + 0x40], %l2; \
+ sllx %o0, 32, %o0; \
+ lduw [%B_PTR + 0x44], %o2; \
+ or %l0, %o0, %l0; \
+ sllx %o1, 32, %o1; \
+ or %l1, %o1, %l1; \
+ sllx %o2, 32, %o2; \
+ or %l2, %o2, %l2;
+#define __LD_B_576(B_PTR) __LD_B_576_NS(B_PTR); SAVE1;
+
+#define __LD_B_640_NS(B_PTR) \
+ SAVE1; \
+ lduw [%B_PTR + 0x00], %i0; \
+ lduw [%B_PTR + 0x04], %o7; \
+ lduw [%B_PTR + 0x08], %i1; \
+ lduw [%B_PTR + 0x0c], %i5; \
+ lduw [%B_PTR + 0x10], %i2; \
+ lduw [%B_PTR + 0x14], %l0; \
+ lduw [%B_PTR + 0x18], %i3; \
+ sllx %o7, 32, %o7; \
+ or %i0, %o7, %i0; \
+ lduw [%B_PTR + 0x1c], %o7; \
+ lduw [%B_PTR + 0x20], %i4; \
+ sllx %i5, 32, %i5; \
+ lduw [%B_PTR + 0x24], %l1; \
+ or %i1, %i5, %i1; \
+ lduw [%B_PTR + 0x28], %i5; \
+ sllx %l0, 32, %l0; \
+ lduw [%B_PTR + 0x2c], %l2; \
+ or %i2, %l0, %i2; \
+ lduw [%B_PTR + 0x30], %l0; \
+ sllx %o7, 32, %o7; \
+ lduw [%B_PTR + 0x34], %o0; \
+ or %i3, %o7, %i3; \
+ sllx %l1, 32, %l1; \
+ or %i4, %l1, %i4; \
+ lduw [%B_PTR + 0x38], %l1; \
+ lduw [%B_PTR + 0x3c], %o1; \
+ sllx %l2, 32, %l2; \
+ or %i5, %l2, %i5; \
+ lduw [%B_PTR + 0x40], %l2; \
+ sllx %o0, 32, %o0; \
+ lduw [%B_PTR + 0x44], %o2; \
+ or %l0, %o0, %l0; \
+ lduw [%B_PTR + 0x48], %l3; \
+ sllx %o1, 32, %o1; \
+ lduw [%B_PTR + 0x4c], %o3; \
+ or %l1, %o1, %l1; \
+ sllx %o2, 32, %o2; \
+ or %l2, %o2, %l2; \
+ sllx %o3, 32, %o3; \
+ or %l3, %o3, %l3;
+#define __LD_B_640(B_PTR) __LD_B_640_NS(B_PTR); SAVE1;
+
+#define __LD_B_704_NS(B_PTR) \
+ SAVE1; \
+ lduw [%B_PTR + 0x00], %i0; \
+ lduw [%B_PTR + 0x04], %o7; \
+ lduw [%B_PTR + 0x08], %i1; \
+ lduw [%B_PTR + 0x0c], %i5; \
+ lduw [%B_PTR + 0x10], %i2; \
+ lduw [%B_PTR + 0x14], %l0; \
+ lduw [%B_PTR + 0x18], %i3; \
+ sllx %o7, 32, %o7; \
+ or %i0, %o7, %i0; \
+ lduw [%B_PTR + 0x1c], %o7; \
+ lduw [%B_PTR + 0x20], %i4; \
+ sllx %i5, 32, %i5; \
+ lduw [%B_PTR + 0x24], %l1; \
+ or %i1, %i5, %i1; \
+ lduw [%B_PTR + 0x28], %i5; \
+ sllx %l0, 32, %l0; \
+ lduw [%B_PTR + 0x2c], %l2; \
+ or %i2, %l0, %i2; \
+ lduw [%B_PTR + 0x30], %l0; \
+ sllx %o7, 32, %o7; \
+ lduw [%B_PTR + 0x34], %o0; \
+ or %i3, %o7, %i3; \
+ sllx %l1, 32, %l1; \
+ or %i4, %l1, %i4; \
+ lduw [%B_PTR + 0x38], %l1; \
+ lduw [%B_PTR + 0x3c], %o1; \
+ sllx %l2, 32, %l2; \
+ or %i5, %l2, %i5; \
+ lduw [%B_PTR + 0x40], %l2; \
+ sllx %o0, 32, %o0; \
+ lduw [%B_PTR + 0x44], %o2; \
+ or %l0, %o0, %l0; \
+ lduw [%B_PTR + 0x48], %l3; \
+ sllx %o1, 32, %o1; \
+ lduw [%B_PTR + 0x4c], %o3; \
+ or %l1, %o1, %l1; \
+ lduw [%B_PTR + 0x50], %l4; \
+ sllx %o2, 32, %o2; \
+ lduw [%B_PTR + 0x54], %o4; \
+ or %l2, %o2, %l2; \
+ sllx %o3, 32, %o3; \
+ or %l3, %o3, %l3; \
+ sllx %o4, 32, %o4; \
+ or %l4, %o4, %l4;
+#define __LD_B_704(B_PTR) __LD_B_704_NS(B_PTR); SAVE1;
+
+#define __LD_B_768_NS(B_PTR) \
+ SAVE1; \
+ lduw [%B_PTR + 0x00], %i0; \
+ lduw [%B_PTR + 0x04], %o7; \
+ lduw [%B_PTR + 0x08], %i1; \
+ lduw [%B_PTR + 0x0c], %i5; \
+ lduw [%B_PTR + 0x10], %i2; \
+ lduw [%B_PTR + 0x14], %l0; \
+ lduw [%B_PTR + 0x18], %i3; \
+ sllx %o7, 32, %o7; \
+ or %i0, %o7, %i0; \
+ lduw [%B_PTR + 0x1c], %o7; \
+ lduw [%B_PTR + 0x20], %i4; \
+ sllx %i5, 32, %i5; \
+ lduw [%B_PTR + 0x24], %l1; \
+ or %i1, %i5, %i1; \
+ lduw [%B_PTR + 0x28], %i5; \
+ sllx %l0, 32, %l0; \
+ lduw [%B_PTR + 0x2c], %l2; \
+ or %i2, %l0, %i2; \
+ lduw [%B_PTR + 0x30], %l0; \
+ sllx %o7, 32, %o7; \
+ lduw [%B_PTR + 0x34], %o0; \
+ or %i3, %o7, %i3; \
+ sllx %l1, 32, %l1; \
+ or %i4, %l1, %i4; \
+ lduw [%B_PTR + 0x38], %l1; \
+ lduw [%B_PTR + 0x3c], %o1; \
+ sllx %l2, 32, %l2; \
+ or %i5, %l2, %i5; \
+ lduw [%B_PTR + 0x40], %l2; \
+ sllx %o0, 32, %o0; \
+ lduw [%B_PTR + 0x44], %o2; \
+ or %l0, %o0, %l0; \
+ lduw [%B_PTR + 0x48], %l3; \
+ sllx %o1, 32, %o1; \
+ lduw [%B_PTR + 0x4c], %o3; \
+ or %l1, %o1, %l1; \
+ lduw [%B_PTR + 0x50], %l4; \
+ sllx %o2, 32, %o2; \
+ lduw [%B_PTR + 0x54], %o4; \
+ or %l2, %o2, %l2; \
+ lduw [%B_PTR + 0x58], %l5; \
+ sllx %o3, 32, %o3; \
+ lduw [%B_PTR + 0x5c], %o5; \
+ or %l3, %o3, %l3; \
+ sllx %o4, 32, %o4; \
+ or %l4, %o4, %l4; \
+ sllx %o5, 32, %o5; \
+ or %l5, %o5, %l5;
+#define __LD_B_768(B_PTR) __LD_B_768_NS(B_PTR); SAVE1;
+
+#define __LD_B_832_NS(B_PTR) \
+ __LD_B_768_NS(B_PTR) \
+ lduw [%B_PTR + 0x60], %l6; \
+ lduw [%B_PTR + 0x64], %o7; \
+ sllx %o7, 32, %o7; \
+ or %l6, %o7, %l6;
+#define __LD_B_832(B_PTR) __LD_B_832_NS(B_PTR); SAVE1;
+
+#define __LD_B_896_NS(B_PTR) \
+ __LD_B_768_NS(B_PTR) \
+ lduw [%B_PTR + 0x60], %l6; \
+ lduw [%B_PTR + 0x64], %o7; \
+ lduw [%B_PTR + 0x68], %l7; \
+ lduw [%B_PTR + 0x6c], %o5; \
+ sllx %o7, 32, %o7; \
+ or %l6, %o7, %l6; \
+ sllx %o5, 32, %o5; \
+ or %l7, %o5, %l7;
+#define __LD_B_896(B_PTR) __LD_B_896_NS(B_PTR); SAVE1;
+
+#define __LD_B_960_NS(B_PTR) \
+ __LD_B_768_NS(B_PTR) \
+ lduw [%B_PTR + 0x60], %l6; \
+ lduw [%B_PTR + 0x64], %o7; \
+ lduw [%B_PTR + 0x68], %l7; \
+ lduw [%B_PTR + 0x6c], %o5; \
+ lduw [%B_PTR + 0x70], %o0; \
+ lduw [%B_PTR + 0x74], %o4; \
+ sllx %o7, 32, %o7; \
+ or %l6, %o7, %l6; \
+ sllx %o5, 32, %o5; \
+ or %l7, %o5, %l7; \
+ sllx %o4, 32, %o4; \
+ or %o0, %o4, %o0;
+#define __LD_B_960(B_PTR) __LD_B_960_NS(B_PTR); SAVE1;
+
+#define __LD_B_1024_NS(B_PTR) \
+ __LD_B_768_NS(B_PTR) \
+ lduw [%B_PTR + 0x60], %l6; \
+ lduw [%B_PTR + 0x64], %o7; \
+ lduw [%B_PTR + 0x68], %l7; \
+ lduw [%B_PTR + 0x6c], %o5; \
+ lduw [%B_PTR + 0x70], %o0; \
+ lduw [%B_PTR + 0x74], %o4; \
+ sllx %o7, 32, %o7; \
+ lduw [%B_PTR + 0x78], %o1; \
+ or %l6, %o7, %l6; \
+ lduw [%B_PTR + 0x7c], %o7; \
+ sllx %o5, 32, %o5; \
+ or %l7, %o5, %l7; \
+ sllx %o4, 32, %o4; \
+ or %o0, %o4, %o0; \
+ sllx %o7, 32, %o7; \
+ or %o1, %o7, %o1;
+#define __LD_B_1024(B_PTR) __LD_B_1024_NS(B_PTR); SAVE1;
+
+#define __LD_B_1088_NS(B_PTR) \
+ __LD_B_768_NS(B_PTR) \
+ lduw [%B_PTR + 0x60], %l6; \
+ lduw [%B_PTR + 0x64], %o7; \
+ lduw [%B_PTR + 0x68], %l7; \
+ lduw [%B_PTR + 0x6c], %o5; \
+ lduw [%B_PTR + 0x70], %o0; \
+ lduw [%B_PTR + 0x74], %o4; \
+ sllx %o7, 32, %o7; \
+ lduw [%B_PTR + 0x78], %o1; \
+ or %l6, %o7, %l6; \
+ lduw [%B_PTR + 0x7c], %o7; \
+ sllx %o5, 32, %o5; \
+ lduw [%B_PTR + 0x80], %o2; \
+ or %l7, %o5, %l7; \
+ lduw [%B_PTR + 0x84], %o5; \
+ sllx %o4, 32, %o4; \
+ or %o0, %o4, %o0; \
+ sllx %o7, 32, %o7; \
+ or %o1, %o7, %o1; \
+ sllx %o5, 32, %o5; \
+ or %o2, %o5, %o2;
+#define __LD_B_1088(B_PTR) __LD_B_1088_NS(B_PTR); SAVE1;
+
+#define __LD_B_1152_NS(B_PTR) \
+ __LD_B_768_NS(B_PTR) \
+ lduw [%B_PTR + 0x60], %l6; \
+ lduw [%B_PTR + 0x64], %o7; \
+ lduw [%B_PTR + 0x68], %l7; \
+ lduw [%B_PTR + 0x6c], %o5; \
+ lduw [%B_PTR + 0x70], %o0; \
+ lduw [%B_PTR + 0x74], %o4; \
+ sllx %o7, 32, %o7; \
+ lduw [%B_PTR + 0x78], %o1; \
+ or %l6, %o7, %l6; \
+ lduw [%B_PTR + 0x7c], %o7; \
+ sllx %o5, 32, %o5; \
+ lduw [%B_PTR + 0x80], %o2; \
+ or %l7, %o5, %l7; \
+ lduw [%B_PTR + 0x84], %o5; \
+ sllx %o4, 32, %o4; \
+ lduw [%B_PTR + 0x88], %o3; \
+ or %o0, %o4, %o0; \
+ lduw [%B_PTR + 0x8c], %o4; \
+ sllx %o7, 32, %o7; \
+ or %o1, %o7, %o1; \
+ sllx %o5, 32, %o5; \
+ or %o2, %o5, %o2; \
+ sllx %o4, 32, %o4; \
+ or %o3, %o4, %o3;
+#define __LD_B_1152(B_PTR) __LD_B_1152_NS(B_PTR); SAVE1;
+
+#define __LD_B_1216_NS(B_PTR) \
+ __LD_B_1152_NS(B_PTR) \
+ lduw [%B_PTR + 0x90], %o4; \
+ lduw [%B_PTR + 0x94], %o5; \
+ sllx %o5, 32, %o5; \
+ or %o4, %o5, %o4;
+#define __LD_B_1216(B_PTR) __LD_B_1216_NS(B_PTR); SAVE1;
+
+#define __LD_B_1280_NS(B_PTR) \
+ __LD_B_1216_NS(B_PTR) \
+ lduw [%B_PTR + 0x98], %o5; \
+ lduw [%B_PTR + 0x9c], %o7; \
+ sllx %o7, 32, %o7; \
+ or %o5, %o7, %o5;
+#define __LD_B_1280(B_PTR) __LD_B_1280_NS(B_PTR); SAVE1;
+
+#define __LD_B_1344(B_PTR) \
+ __LD_B_1280(B_PTR); \
+ __LD_A_64(B_PTR + 0xa0);
+#define __LD_B_1408(B_PTR) \
+ __LD_B_1280(B_PTR); \
+ __LD_A_128(B_PTR + 0xa0);
+#define __LD_B_1472(B_PTR) \
+ __LD_B_1280(B_PTR); \
+ __LD_A_192(B_PTR + 0xa0);
+#define __LD_B_1536(B_PTR) \
+ __LD_B_1280(B_PTR); \
+ __LD_A_256(B_PTR + 0xa0);
+#define __LD_B_1600(B_PTR) \
+ __LD_B_1280(B_PTR); \
+ __LD_A_320(B_PTR + 0xa0);
+#define __LD_B_1664(B_PTR) \
+ __LD_B_1280(B_PTR); \
+ __LD_A_384(B_PTR + 0xa0);
+#define __LD_B_1728(B_PTR) \
+ __LD_B_1280(B_PTR); \
+ __LD_A_448(B_PTR + 0xa0);
+#define __LD_B_1792(B_PTR) \
+ __LD_B_1280(B_PTR); \
+ __LD_A_512(B_PTR + 0xa0);
+#define __LD_B_1856(B_PTR) \
+ __LD_B_1280(B_PTR); \
+ __LD_A_576(B_PTR + 0xa0);
+#define __LD_B_1920(B_PTR) \
+ __LD_B_1280(B_PTR); \
+ __LD_A_640(B_PTR + 0xa0);
+#define __LD_B_1984(B_PTR) \
+ __LD_B_1280(B_PTR); \
+ __LD_A_704(B_PTR + 0xa0);
+#define __LD_B_2048(B_PTR) \
+ __LD_B_1280(B_PTR); \
+ __LD_A_768(B_PTR + 0xa0);
+
+#define LD_B(B_PTR, BITS) \
+ __LD_B_##BITS##(B_PTR); \
+
+#define __ST_RES_64(R_PTR) \
+ restore; \
+ restore; \
+ restore; \
+ restore; \
+ restore; \
+ stx %l0, [%R_PTR + 0x00];
+
+#define __ST_RES_128(R_PTR) __ST_RES_64(R_PTR); stx %l1, [%R_PTR + 0x08];
+#define __ST_RES_192(R_PTR) __ST_RES_128(R_PTR); stx %l2, [%R_PTR + 0x10];
+#define __ST_RES_256(R_PTR) __ST_RES_192(R_PTR); stx %l3, [%R_PTR + 0x18];
+#define __ST_RES_320(R_PTR) __ST_RES_256(R_PTR); stx %l4, [%R_PTR + 0x20];
+#define __ST_RES_384(R_PTR) __ST_RES_320(R_PTR); stx %l5, [%R_PTR + 0x28];
+#define __ST_RES_448(R_PTR) __ST_RES_384(R_PTR); stx %l6, [%R_PTR + 0x30];
+#define __ST_RES_512(R_PTR) __ST_RES_448(R_PTR); stx %l7, [%R_PTR + 0x38];
+#define __ST_RES_576(R_PTR) __ST_RES_512(R_PTR); stx %o0, [%R_PTR + 0x40];
+#define __ST_RES_640(R_PTR) __ST_RES_576(R_PTR); stx %o1, [%R_PTR + 0x48];
+#define __ST_RES_704(R_PTR) __ST_RES_640(R_PTR); stx %o2, [%R_PTR + 0x50];
+#define __ST_RES_768(R_PTR) __ST_RES_704(R_PTR); stx %o3, [%R_PTR + 0x58];
+#define __ST_RES_832(R_PTR) __ST_RES_768(R_PTR); stx %o4, [%R_PTR + 0x60];
+#define __ST_RES_896(R_PTR) __ST_RES_832(R_PTR); stx %o5, [%R_PTR + 0x68];
+#define __ST_RES_960(R_PTR) __ST_RES_896(R_PTR); std %f24, [%R_PTR + 0x70];
+#define __ST_RES_1024(R_PTR) __ST_RES_960(R_PTR); std %f26, [%R_PTR + 0x78];
+#define __ST_RES_1088(R_PTR) __ST_RES_1024(R_PTR); std %f28, [%R_PTR + 0x80];
+#define __ST_RES_1152(R_PTR) __ST_RES_1088(R_PTR); std %f30, [%R_PTR + 0x88];
+#define __ST_RES_1216(R_PTR) __ST_RES_1152(R_PTR); std %f32, [%R_PTR + 0x90];
+#define __ST_RES_1280(R_PTR) __ST_RES_1216(R_PTR); std %f34, [%R_PTR + 0x98];
+#define __ST_RES_1344(R_PTR) __ST_RES_1280(R_PTR); std %f36, [%R_PTR + 0xa0];
+#define __ST_RES_1408(R_PTR) __ST_RES_1344(R_PTR); std %f38, [%R_PTR + 0xa8];
+#define __ST_RES_1472(R_PTR) __ST_RES_1408(R_PTR); std %f40, [%R_PTR + 0xb0];
+#define __ST_RES_1536(R_PTR) __ST_RES_1472(R_PTR); std %f42, [%R_PTR + 0xb8];
+#define __ST_RES_1600(R_PTR) __ST_RES_1536(R_PTR); std %f44, [%R_PTR + 0xc0];
+#define __ST_RES_1664(R_PTR) __ST_RES_1600(R_PTR); std %f46, [%R_PTR + 0xc8];
+#define __ST_RES_1728(R_PTR) __ST_RES_1664(R_PTR); std %f48, [%R_PTR + 0xd0];
+#define __ST_RES_1792(R_PTR) __ST_RES_1728(R_PTR); std %f50, [%R_PTR + 0xd8];
+#define __ST_RES_1856(R_PTR) __ST_RES_1792(R_PTR); std %f52, [%R_PTR + 0xe0];
+#define __ST_RES_1920(R_PTR) __ST_RES_1856(R_PTR); std %f54, [%R_PTR + 0xe8];
+#define __ST_RES_1984(R_PTR) __ST_RES_1920(R_PTR); std %f56, [%R_PTR + 0xf0];
+#define __ST_RES_2048(R_PTR) __ST_RES_1984(R_PTR); std %f58, [%R_PTR + 0xf8];
+
+#define STORE_RES(R_PTR, BITS) \
+ __ST_RES_##BITS##(R_PTR);
+
+#define MONTMUL_INSN(BITS) \
+ .word 0x81b02920 + ((BITS / 64) - 1);
+#define MONTSQR_INSN(BITS) \
+ .word 0x81b02940 + ((BITS / 64) - 1);
+
+#ifdef __arch64__
+#define STORE_SENTINEL
+#define CHECK_SENTINEL
+#else
+ /* One of the only registers unused by the crypto engine during
+ * execution of montmul and montsqr is %o6, so we "corrupt"
+ * the upper 32-bits of the stack pointer which will be ignored
+ * by the cpu when executing with address masking enabled which
+ * all 32-bit apps do.
+ */
+#define STORE_SENTINEL \
+ mov -1, %o5; \
+ sllx %o5, 32, %o5; \
+ add %o5, %o6, %o6;
+#define CHECK_SENTINEL \
+ srax %o6, 32, %i0; \
+ add %i0, 1, %i0;
+#endif
+
+ /* %o0=RES_PTR, %o1=A_PTR, %o2=B_PTR, %o3=%N_PTR, %o4=%N0_PTR */
+#define MONTMUL_FUNC(BITS) \
+ .align 32; \
+ .globl sparc_hw_montmul_##BITS##; \
+sparc_hw_montmul_##BITS##: \
+ SAVE1; \
+ /* CWP i-6 */ \
+ STORE_SENTINEL; \
+ mov %i0, %g1; \
+ mov %i1, %g2; \
+ mov %i2, %g3; \
+ mov %i3, %g5; \
+ ld [%i4 + 0], %f1; \
+ ld [%i4 + 4], %f0; \
+ fsrc2 %f0, %f60; \
+ SAVE1; \
+ /* CWP i-5 */ \
+ LD_A(g2, BITS); \
+ LD_N(g5, BITS); \
+ cmp %g2, %g3; \
+ be .Ldo_montsqr_##BITS##; \
+ nop; \
+ LD_B(g3, BITS); \
+ /* CWP i-0 */ \
+ MONTMUL_INSN(BITS); \
+.Ldo_store_res_##BITS##: \
+ STORE_RES(g1, BITS); \
+ /* CWP i-5 */ \
+ restore; \
+ /* CWP i-6 */ \
+ clr %i0; \
+ CHECK_SENTINEL; \
+ movu %fcc3, 1, %i0; \
+ ret; \
+ restore; \
+.Ldo_montsqr_##BITS##: \
+ SAVE2; \
+ MONTSQR_INSN(BITS); \
+ ba,a,pt %icc, .Ldo_store_res_##BITS##; \
+ .size sparc_hw_montmul_##BITS##,.-sparc_hw_montmul_##BITS##;
+
+ .register %g2,#scratch
+ .register %g3,#scratch
+
+MONTMUL_FUNC(64)
+MONTMUL_FUNC(128)
+MONTMUL_FUNC(192)
+MONTMUL_FUNC(256)
+MONTMUL_FUNC(320)
+MONTMUL_FUNC(384)
+MONTMUL_FUNC(448)
+MONTMUL_FUNC(512)
+MONTMUL_FUNC(576)
+MONTMUL_FUNC(640)
+MONTMUL_FUNC(704)
+MONTMUL_FUNC(768)
+MONTMUL_FUNC(832)
+MONTMUL_FUNC(896)
+MONTMUL_FUNC(960)
+MONTMUL_FUNC(1024)
+MONTMUL_FUNC(1088)
+MONTMUL_FUNC(1152)
+MONTMUL_FUNC(1216)
+MONTMUL_FUNC(1280)
+MONTMUL_FUNC(1344)
+MONTMUL_FUNC(1408)
+MONTMUL_FUNC(1472)
+MONTMUL_FUNC(1536)
+MONTMUL_FUNC(1600)
+MONTMUL_FUNC(1664)
+MONTMUL_FUNC(1728)
+MONTMUL_FUNC(1792)
+MONTMUL_FUNC(1856)
+MONTMUL_FUNC(1920)
+MONTMUL_FUNC(1984)
+MONTMUL_FUNC(2048)
+
+ .align 32
+ .globl sparc_hw_montmul_resconvert
+sparc_hw_montmul_resconvert:
+ /* %o0=dst, %o1=src, %o2=num */
+1: ldd [%o1 + 0x00], %f0
+ subcc %o2, 2, %o2
+ add %o1, 8, %o1
+ add %o0, 8, %o0
+ st %f1, [%o0 - 0x08]
+ bne,pt %icc, 1b
+ st %f0, [%o0 - 0x04]
+ retl
+ nop
+ .size sparc_hw_montmul_resconvert,.-sparc_hw_montmul_resconvert
\ No newline at end of file
diff --git a/crypto/sparcv9cap.c b/crypto/sparcv9cap.c
index d809c56..74738b2 100644
--- a/crypto/sparcv9cap.c
+++ b/crypto/sparcv9cap.c
@@ -10,11 +10,140 @@
int OPENSSL_sparcv9cap_P=SPARCV9_TICK_PRIVILEGED;
+extern int sparc_hw_montmul_64(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_128(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_192(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_256(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_320(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_384(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_448(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_512(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_576(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_640(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_704(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_768(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_832(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_896(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_960(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1024(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1088(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1152(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1216(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1280(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1344(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1408(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1472(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1536(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1600(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1664(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1728(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1792(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1856(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1920(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_1984(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+extern int sparc_hw_montmul_2048(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0);
+
+typedef int (*sparc_hw_mmfunc)(BN_ULLONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0);
+
+static sparc_hw_mmfunc sparc_hw_mmtab[] = {
+ sparc_hw_montmul_64,
+ sparc_hw_montmul_128,
+ sparc_hw_montmul_192,
+ sparc_hw_montmul_256,
+ sparc_hw_montmul_320,
+ sparc_hw_montmul_384,
+ sparc_hw_montmul_448,
+ sparc_hw_montmul_512,
+ sparc_hw_montmul_576,
+ sparc_hw_montmul_640,
+ sparc_hw_montmul_704,
+ sparc_hw_montmul_768,
+ sparc_hw_montmul_832,
+ sparc_hw_montmul_896,
+ sparc_hw_montmul_960,
+ sparc_hw_montmul_1024,
+ sparc_hw_montmul_1088,
+ sparc_hw_montmul_1152,
+ sparc_hw_montmul_1216,
+ sparc_hw_montmul_1280,
+ sparc_hw_montmul_1344,
+ sparc_hw_montmul_1408,
+ sparc_hw_montmul_1472,
+ sparc_hw_montmul_1536,
+ sparc_hw_montmul_1600,
+ sparc_hw_montmul_1664,
+ sparc_hw_montmul_1728,
+ sparc_hw_montmul_1792,
+ sparc_hw_montmul_1856,
+ sparc_hw_montmul_1920,
+ sparc_hw_montmul_1984,
+ sparc_hw_montmul_2048,
+};
+
+extern void sparc_hw_montmul_resconvert(BN_ULONG *bp, const BN_ULLONG *tp, int
num);
+
+static int sparc_do_hw_montmul(BN_ULONG *rp, const BN_ULONG *ap, const
BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num)
+{
+ BN_ULLONG tbuf[64];
+ int limit;
+
+ limit = 10;
+ while (limit) {
+ int res = sparc_hw_mmtab[(num>>1)-1](tbuf, ap, bp, np, n0);
+ if (!res)
+ break;
+ limit -= 1;
+ }
+ if (!limit)
+ return 0;
+
+ sparc_hw_montmul_resconvert(rp, &tbuf[64 * 0], num);
+
+ return 1;
+}
+
int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const
BN_ULONG *np,const BN_ULONG *n0, int num)
{
int bn_mul_mont_fpu(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG
*bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG
*bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
+ if (!(num & 1) && num && num <= 64 &&
+ (OPENSSL_sparcv9cap_P&SPARCV9_MONTMUL)) {
+ if (sparc_do_hw_montmul(rp, ap, bp, np, n0, num))
+ return 1;
+ }
if (num>=8 && !(num&1) &&
(OPENSSL_sparcv9cap_P&(SPARCV9_PREFER_FPU|SPARCV9_VIS1)) ==
(SPARCV9_PREFER_FPU|SPARCV9_VIS1))
--
1.7.10.4
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [email protected]
Automated List Manager [email protected]