Add a bad-case test for the key generation.
[libgcrypt.git] / mpi / m68k / mpih-lshift.S
1 /* mc68020 lshift -- Shift left a low-level natural-number integer.
2  *
3  *      Copyright (C) 1996, 1998, 2001, 2002 Free Software Foundation, Inc.
4  *       
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  *
21  * Note: This code is heavily based on the GNU MP Library.
22  *       Actually it's the same code with only minor changes in the
23  *       way the data is stored; this is to support the abstraction
24  *       of an optional secure memory allocation which may be used
25  *       to avoid revealing of sensitive data due to paging etc.
26  */
27
28
29 #include "sysdep.h"
30 #include "asm-syntax.h"
31
32
33 /*******************
34  * mpi_limb_t
35  * _gcry_mpih_lshift( mpi_ptr_t wp,     (sp + 4)
36  *                 mpi_ptr_t up,        (sp + 8)
37  *                 mpi_size_t usize,    (sp + 12)
38  *                 unsigned cnt)        (sp + 16)
39  */
40
41 #define res_ptr a1
42 #define s_ptr a0
43 #define s_size d6
44 #define cnt d4
45
46         TEXT
47         ALIGN
48         GLOBL   C_SYMBOL_NAME(_gcry_mpih_lshift)
49
50 C_SYMBOL_NAME(_gcry_mpih_lshift:)
51 PROLOG(_gcry_mpih_lshift)
52
53         /* Save used registers on the stack.  */
54         moveml  R(d2)-R(d6)/R(a2),MEM_PREDEC(sp)
55
56         /* Copy the arguments to registers.  */
57         movel   MEM_DISP(sp,28),R(res_ptr)
58         movel   MEM_DISP(sp,32),R(s_ptr)
59         movel   MEM_DISP(sp,36),R(s_size)
60         movel   MEM_DISP(sp,40),R(cnt)
61
62         moveql  #1,R(d5)
63         cmpl    R(d5),R(cnt)
64         bne     L(Lnormal)
65         cmpl    R(s_ptr),R(res_ptr)
66         bls     L(Lspecial)             /* jump if s_ptr >= res_ptr */
67 #if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
68         lea     MEM_INDX1(s_ptr,s_size,l,4),R(a2)
69 #else /* not mc68020 */
70         movel   R(s_size),R(d0)
71         asll    #2,R(d0)
72         lea     MEM_INDX(s_ptr,d0,l),R(a2)
73 #endif
74         cmpl    R(res_ptr),R(a2)
75         bls     L(Lspecial)             /* jump if res_ptr >= s_ptr + s_size */
76
77 L(Lnormal:)
78         moveql  #32,R(d5)
79         subl    R(cnt),R(d5)
80
81 #if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
82         lea     MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr)
83         lea     MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr)
84 #else /* not mc68000 */
85         movel   R(s_size),R(d0)
86         asll    #2,R(d0)
87         addl    R(s_size),R(s_ptr)
88         addl    R(s_size),R(res_ptr)
89 #endif
90         movel   MEM_PREDEC(s_ptr),R(d2)
91         movel   R(d2),R(d0)
92         lsrl    R(d5),R(d0)             /* compute carry limb */
93
94         lsll    R(cnt),R(d2)
95         movel   R(d2),R(d1)
96         subql   #1,R(s_size)
97         beq     L(Lend)
98         lsrl    #1,R(s_size)
99         bcs     L(L1)
100         subql   #1,R(s_size)
101
102 L(Loop:)
103         movel   MEM_PREDEC(s_ptr),R(d2)
104         movel   R(d2),R(d3)
105         lsrl    R(d5),R(d3)
106         orl     R(d3),R(d1)
107         movel   R(d1),MEM_PREDEC(res_ptr)
108         lsll    R(cnt),R(d2)
109 L(L1:)
110         movel   MEM_PREDEC(s_ptr),R(d1)
111         movel   R(d1),R(d3)
112         lsrl    R(d5),R(d3)
113         orl     R(d3),R(d2)
114         movel   R(d2),MEM_PREDEC(res_ptr)
115         lsll    R(cnt),R(d1)
116
117         dbf     R(s_size),L(Loop)
118         subl    #0x10000,R(s_size)
119         bcc     L(Loop)
120
121 L(Lend:)
122         movel   R(d1),MEM_PREDEC(res_ptr) /* store least significant limb */
123
124 /* Restore used registers from stack frame.  */
125         moveml  MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
126         rts
127
128 /* We loop from least significant end of the arrays, which is only
129    permissable if the source and destination don't overlap, since the
130    function is documented to work for overlapping source and destination.  */
131
132 L(Lspecial:)
133         clrl    R(d0)                   /* initialize carry */
134         eorw    #1,R(s_size)
135         lsrl    #1,R(s_size)
136         bcc     L(LL1)
137         subql   #1,R(s_size)
138
139 L(LLoop:)
140         movel   MEM_POSTINC(s_ptr),R(d2)
141         addxl   R(d2),R(d2)
142         movel   R(d2),MEM_POSTINC(res_ptr)
143 L(LL1:)
144         movel   MEM_POSTINC(s_ptr),R(d2)
145         addxl   R(d2),R(d2)
146         movel   R(d2),MEM_POSTINC(res_ptr)
147
148         dbf     R(s_size),L(LLoop)
149         addxl   R(d0),R(d0)             /* save cy in lsb */
150         subl    #0x10000,R(s_size)
151         bcs     L(LLend)
152         lsrl    #1,R(d0)                /* restore cy */
153         bra     L(LLoop)
154
155 L(LLend:)
156 /* Restore used registers from stack frame.  */
157         moveml  MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
158         rts
159 EPILOG(_gcry_mpih_lshift)
160
161
162
163
164