1/* i80586 lshift 2 * 3 * Copyright (C) 1992, 1994, 1998, 4 * 2001, 2002 Free Software Foundation, Inc. 5 * 6 * This file is part of Libgcrypt. 7 * 8 * Libgcrypt is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU Lesser General Public License as 10 * published by the Free Software Foundation; either version 2.1 of 11 * the License, or (at your option) any later version. 12 * 13 * Libgcrypt is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 21 * 22 * Note: This code is heavily based on the GNU MP Library. 23 * Actually it's the same code with only minor changes in the 24 * way the data is stored; this is to support the abstraction 25 * of an optional secure memory allocation which may be used 26 * to avoid revealing of sensitive data due to paging etc. 27 */ 28 29 30#include "sysdep.h" 31#include "asm-syntax.h" 32 33 34/******************* 35 * mpi_limb_t 36 * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4) 37 * mpi_ptr_t up, (sp + 8) 38 * mpi_size_t usize, (sp + 12) 39 * unsigned cnt) (sp + 16) 40 */ 41 42.text 43 ALIGN (3) 44 .globl C_SYMBOL_NAME(_gcry_mpih_lshift) 45C_SYMBOL_NAME(_gcry_mpih_lshift:) 46 47 pushl %edi 48 pushl %esi 49 pushl %ebx 50 pushl %ebp 51 52 movl 20(%esp),%edi /* res_ptr */ 53 movl 24(%esp),%esi /* s_ptr */ 54 movl 28(%esp),%ebp /* size */ 55 movl 32(%esp),%ecx /* cnt */ 56 57/* We can use faster code for shift-by-1 under certain conditions. */ 58 cmp $1,%ecx 59 jne Lnormal 60 leal 4(%esi),%eax 61 cmpl %edi,%eax 62 jnc Lspecial /* jump if s_ptr + 1 >= res_ptr */ 63 leal (%esi,%ebp,4),%eax 64 cmpl %eax,%edi 65 jnc Lspecial /* jump if res_ptr >= s_ptr + size */ 66 67Lnormal: 68 leal -4(%edi,%ebp,4),%edi 69 leal -4(%esi,%ebp,4),%esi 70 71 movl (%esi),%edx 72 subl $4,%esi 73 xorl %eax,%eax 74 shldl %cl,%edx,%eax /* compute carry limb */ 75 pushl %eax /* push carry limb onto stack */ 76 77 decl %ebp 78 pushl %ebp 79 shrl $3,%ebp 80 jz Lend 81 82 movl (%edi),%eax /* fetch destination cache line */ 83 84 ALIGN (2) 85Loop: movl -28(%edi),%eax /* fetch destination cache line */ 86 movl %edx,%ebx 87 88 movl (%esi),%eax 89 movl -4(%esi),%edx 90 shldl %cl,%eax,%ebx 91 shldl %cl,%edx,%eax 92 movl %ebx,(%edi) 93 movl %eax,-4(%edi) 94 95 movl -8(%esi),%ebx 96 movl -12(%esi),%eax 97 shldl %cl,%ebx,%edx 98 shldl %cl,%eax,%ebx 99 movl %edx,-8(%edi) 100 movl %ebx,-12(%edi) 101 102 movl -16(%esi),%edx 103 movl -20(%esi),%ebx 104 shldl %cl,%edx,%eax 105 shldl %cl,%ebx,%edx 106 movl %eax,-16(%edi) 107 movl %edx,-20(%edi) 108 109 movl -24(%esi),%eax 110 movl -28(%esi),%edx 111 shldl %cl,%eax,%ebx 112 shldl %cl,%edx,%eax 113 movl %ebx,-24(%edi) 114 movl %eax,-28(%edi) 115 116 subl $32,%esi 117 subl $32,%edi 118 decl %ebp 119 jnz Loop 120 121Lend: popl %ebp 122 andl $7,%ebp 123 jz Lend2 124Loop2: movl (%esi),%eax 125 shldl %cl,%eax,%edx 126 movl %edx,(%edi) 127 movl %eax,%edx 128 subl $4,%esi 129 subl $4,%edi 130 decl %ebp 131 jnz Loop2 132 133Lend2: shll %cl,%edx /* compute least significant limb */ 134 movl %edx,(%edi) /* store it */ 135 136 popl %eax /* pop carry limb */ 137 138 popl %ebp 139 popl %ebx 140 popl %esi 141 popl %edi 142 ret 143 144/* We loop from least significant end of the arrays, which is only 145 permissable if the source and destination don't overlap, since the 146 function is documented to work for overlapping source and destination. 147*/ 148 149Lspecial: 150 movl (%esi),%edx 151 addl $4,%esi 152 153 decl %ebp 154 pushl %ebp 155 shrl $3,%ebp 156 157 addl %edx,%edx 158 incl %ebp 159 decl %ebp 160 jz LLend 161 162 movl (%edi),%eax /* fetch destination cache line */ 163 164 ALIGN (2) 165LLoop: movl 28(%edi),%eax /* fetch destination cache line */ 166 movl %edx,%ebx 167 168 movl (%esi),%eax 169 movl 4(%esi),%edx 170 adcl %eax,%eax 171 movl %ebx,(%edi) 172 adcl %edx,%edx 173 movl %eax,4(%edi) 174 175 movl 8(%esi),%ebx 176 movl 12(%esi),%eax 177 adcl %ebx,%ebx 178 movl %edx,8(%edi) 179 adcl %eax,%eax 180 movl %ebx,12(%edi) 181 182 movl 16(%esi),%edx 183 movl 20(%esi),%ebx 184 adcl %edx,%edx 185 movl %eax,16(%edi) 186 adcl %ebx,%ebx 187 movl %edx,20(%edi) 188 189 movl 24(%esi),%eax 190 movl 28(%esi),%edx 191 adcl %eax,%eax 192 movl %ebx,24(%edi) 193 adcl %edx,%edx 194 movl %eax,28(%edi) 195 196 leal 32(%esi),%esi /* use leal not to clobber carry */ 197 leal 32(%edi),%edi 198 decl %ebp 199 jnz LLoop 200 201LLend: popl %ebp 202 sbbl %eax,%eax /* save carry in %eax */ 203 andl $7,%ebp 204 jz LLend2 205 addl %eax,%eax /* restore carry from eax */ 206LLoop2: movl %edx,%ebx 207 movl (%esi),%edx 208 adcl %edx,%edx 209 movl %ebx,(%edi) 210 211 leal 4(%esi),%esi /* use leal not to clobber carry */ 212 leal 4(%edi),%edi 213 decl %ebp 214 jnz LLoop2 215 216 jmp LL1 217LLend2: addl %eax,%eax /* restore carry from eax */ 218LL1: movl %edx,(%edi) /* store last limb */ 219 220 sbbl %eax,%eax 221 negl %eax 222 223 popl %ebp 224 popl %ebx 225 popl %esi 226 popl %edi 227 ret 228 229 230