summaryrefslogtreecommitdiff
path: root/mpi/powerpc32/mpih-lshift.S
diff options
context:
space:
mode:
Diffstat (limited to 'mpi/powerpc32/mpih-lshift.S')
-rw-r--r--mpi/powerpc32/mpih-lshift.S199
1 files changed, 199 insertions, 0 deletions
diff --git a/mpi/powerpc32/mpih-lshift.S b/mpi/powerpc32/mpih-lshift.S
new file mode 100644
index 0000000..4e5da5b
--- /dev/null
+++ b/mpi/powerpc32/mpih-lshift.S
@@ -0,0 +1,199 @@
+/* PowerPC-32 lshift
+ *
+ * Copyright (C) 1995, 1998 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * mpihelp_lshift( mpi_ptr_t wp, (r3)
+ * mpi_ptr_t up, (r4)
+ * mpi_size_t usize, (r5)
+ * unsigned cnt) (r6)
+ */
+
+ .toc
+.csect .text[PR]
+ .align 2
+ .globl mpihelp_lshift
+ .globl .mpihelp_lshift
+ .csect mpihelp_lshift[DS]
+mpihelp_lshift:
+ .long .mpihelp_lshift, TOC[tc0], 0
+ .csect .text[PR]
+.mpihelp_lshift:
+ mtctr 5 # copy size into CTR
+ slwi 0,5,2
+ add 7,3,0 # make r7 point at end of res
+ add 4,4,0 # make r4 point at end of s1
+ subfic 8,6,32
+ lwzu 11,-4(4) # load first s1 limb
+ srw 3,11,8 # compute function return value
+ bdz Lend1
+
+Loop: lwzu 10,-4(4)
+ slw 9,11,6
+ srw 12,10,8
+ or 9,9,12
+ stwu 9,-4(7)
+ bdz Lend2
+ lwzu 11,-4(4)
+ slw 9,10,6
+ srw 12,11,8
+ or 9,9,12
+ stwu 9,-4(7)
+ bdnz Loop
+
+Lend1: slw 0,11,6
+ stw 0,-4(7)
+ blr
+
+Lend2: slw 0,10,6
+ stw 0,-4(7)
+ blr
+
+#else
+/* Shift a limb left, low level routine.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
+ unsigned int cnt) */
+
+EALIGN(mpihelp_lshift,3,0)
+ mtctr %r5 # copy size into CTR
+ cmplwi %cr0,%r5,16 # is size < 16
+ slwi %r0,%r5,2
+ add %r7,%r3,%r0 # make r7 point at end of res
+ add %r4,%r4,%r0 # make r4 point at end of s1
+ lwzu %r11,-4(%r4) # load first s1 limb
+ subfic %r8,%r6,32
+ srw %r3,%r11,%r8 # compute function return value
+ bge %cr0,L(big) # branch if size >= 16
+
+ bdz L(end1)
+
+0: lwzu %r10,-4(%r4)
+ slw %r9,%r11,%r6
+ srw %r12,%r10,%r8
+ or %r9,%r9,%r12
+ stwu %r9,-4(%r7)
+ bdz L(end2)
+ lwzu %r11,-4(%r4)
+ slw %r9,%r10,%r6
+ srw %r12,%r11,%r8
+ or %r9,%r9,%r12
+ stwu %r9,-4(%r7)
+ bdnz 0b
+
+L(end1):slw %r0,%r11,%r6
+ stw %r0,-4(%r7)
+ blr
+
+
+/* Guaranteed not to succeed. */
+L(boom): tweq %r0,%r0
+
+/* We imitate a case statement, by using (yuk!) fixed-length code chunks,
+ of size 4*12 bytes. We have to do this (or something) to make this PIC. */
+L(big): mflr %r9
+ bltl- %cr0,L(boom) # Never taken, only used to set LR.
+ slwi %r10,%r6,4
+ mflr %r12
+ add %r10,%r12,%r10
+ slwi %r8,%r6,5
+ add %r10,%r8,%r10
+ mtctr %r10
+ addi %r5,%r5,-1
+ mtlr %r9
+ bctr
+
+L(end2):slw %r0,%r10,%r6
+ stw %r0,-4(%r7)
+ blr
+
+#define DO_LSHIFT(n) \
+ mtctr %r5; \
+0: lwzu %r10,-4(%r4); \
+ slwi %r9,%r11,n; \
+ inslwi %r9,%r10,n,32-n; \
+ stwu %r9,-4(%r7); \
+ bdz- L(end2); \
+ lwzu %r11,-4(%r4); \
+ slwi %r9,%r10,n; \
+ inslwi %r9,%r11,n,32-n; \
+ stwu %r9,-4(%r7); \
+ bdnz 0b; \
+ b L(end1)
+
+ DO_LSHIFT(1)
+ DO_LSHIFT(2)
+ DO_LSHIFT(3)
+ DO_LSHIFT(4)
+ DO_LSHIFT(5)
+ DO_LSHIFT(6)
+ DO_LSHIFT(7)
+ DO_LSHIFT(8)
+ DO_LSHIFT(9)
+ DO_LSHIFT(10)
+ DO_LSHIFT(11)
+ DO_LSHIFT(12)
+ DO_LSHIFT(13)
+ DO_LSHIFT(14)
+ DO_LSHIFT(15)
+ DO_LSHIFT(16)
+ DO_LSHIFT(17)
+ DO_LSHIFT(18)
+ DO_LSHIFT(19)
+ DO_LSHIFT(20)
+ DO_LSHIFT(21)
+ DO_LSHIFT(22)
+ DO_LSHIFT(23)
+ DO_LSHIFT(24)
+ DO_LSHIFT(25)
+ DO_LSHIFT(26)
+ DO_LSHIFT(27)
+ DO_LSHIFT(28)
+ DO_LSHIFT(29)
+ DO_LSHIFT(30)
+ DO_LSHIFT(31)
+
+END(mpihelp_lshift)
+#endif