Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbedtls by
bn_mul.h
00001 /** 00002 * \file bn_mul.h 00003 * 00004 * \brief Multi-precision integer library 00005 * 00006 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00007 * SPDX-License-Identifier: Apache-2.0 00008 * 00009 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00010 * not use this file except in compliance with the License. 00011 * You may obtain a copy of the License at 00012 * 00013 * http://www.apache.org/licenses/LICENSE-2.0 00014 * 00015 * Unless required by applicable law or agreed to in writing, software 00016 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00017 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00018 * See the License for the specific language governing permissions and 00019 * limitations under the License. 00020 * 00021 * This file is part of mbed TLS (https://tls.mbed.org) 00022 */ 00023 /* 00024 * Multiply source vector [s] with b, add result 00025 * to destination vector [d] and set carry c. 00026 * 00027 * Currently supports: 00028 * 00029 * . IA-32 (386+) . AMD64 / EM64T 00030 * . IA-32 (SSE2) . Motorola 68000 00031 * . PowerPC, 32-bit . MicroBlaze 00032 * . PowerPC, 64-bit . TriCore 00033 * . SPARC v8 . ARM v3+ 00034 * . Alpha . MIPS32 00035 * . C, longlong . C, generic 00036 */ 00037 #ifndef MBEDTLS_BN_MUL_H 00038 #define MBEDTLS_BN_MUL_H 00039 00040 #include "bignum.h" 00041 00042 #if defined(MBEDTLS_HAVE_ASM) 00043 00044 #ifndef asm 00045 #define asm __asm 00046 #endif 00047 00048 /* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ 00049 #if defined(__GNUC__) && \ 00050 ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) 00051 #if defined(__i386__) 00052 00053 #define MULADDC_INIT \ 00054 asm( \ 00055 "movl %%ebx, %0 \n\t" \ 00056 "movl %5, %%esi \n\t" \ 00057 "movl %6, %%edi \n\t" \ 00058 "movl %7, %%ecx \n\t" \ 00059 "movl %8, %%ebx \n\t" 00060 00061 #define MULADDC_CORE \ 00062 "lodsl \n\t" \ 00063 "mull %%ebx \n\t" \ 00064 "addl %%ecx, %%eax \n\t" \ 00065 "adcl $0, %%edx \n\t" \ 00066 "addl (%%edi), %%eax \n\t" \ 00067 "adcl $0, %%edx \n\t" \ 00068 "movl %%edx, %%ecx \n\t" \ 00069 "stosl \n\t" 00070 00071 #if defined(MBEDTLS_HAVE_SSE2) 00072 00073 #define MULADDC_HUIT \ 00074 "movd %%ecx, %%mm1 \n\t" \ 00075 "movd %%ebx, %%mm0 \n\t" \ 00076 "movd (%%edi), %%mm3 \n\t" \ 00077 "paddq %%mm3, %%mm1 \n\t" \ 00078 "movd (%%esi), %%mm2 \n\t" \ 00079 "pmuludq %%mm0, %%mm2 \n\t" \ 00080 "movd 4(%%esi), %%mm4 \n\t" \ 00081 "pmuludq %%mm0, %%mm4 \n\t" \ 00082 "movd 8(%%esi), %%mm6 \n\t" \ 00083 "pmuludq %%mm0, %%mm6 \n\t" \ 00084 "movd 12(%%esi), %%mm7 \n\t" \ 00085 "pmuludq %%mm0, %%mm7 \n\t" \ 00086 "paddq %%mm2, %%mm1 \n\t" \ 00087 "movd 4(%%edi), %%mm3 \n\t" \ 00088 "paddq %%mm4, %%mm3 \n\t" \ 00089 "movd 8(%%edi), %%mm5 \n\t" \ 00090 "paddq %%mm6, %%mm5 \n\t" \ 00091 "movd 12(%%edi), %%mm4 \n\t" \ 00092 "paddq %%mm4, %%mm7 \n\t" \ 00093 "movd %%mm1, (%%edi) \n\t" \ 00094 "movd 16(%%esi), %%mm2 \n\t" \ 00095 "pmuludq %%mm0, %%mm2 \n\t" \ 00096 "psrlq $32, %%mm1 \n\t" \ 00097 "movd 20(%%esi), %%mm4 \n\t" \ 00098 "pmuludq %%mm0, %%mm4 \n\t" \ 00099 "paddq %%mm3, %%mm1 \n\t" \ 00100 "movd 24(%%esi), %%mm6 \n\t" \ 00101 "pmuludq %%mm0, %%mm6 \n\t" \ 00102 "movd %%mm1, 4(%%edi) \n\t" \ 00103 "psrlq $32, %%mm1 \n\t" \ 00104 "movd 28(%%esi), %%mm3 \n\t" \ 00105 "pmuludq %%mm0, %%mm3 \n\t" \ 00106 "paddq %%mm5, %%mm1 \n\t" \ 00107 "movd 16(%%edi), %%mm5 \n\t" \ 00108 "paddq %%mm5, %%mm2 \n\t" \ 00109 "movd %%mm1, 8(%%edi) \n\t" \ 00110 "psrlq $32, %%mm1 \n\t" \ 00111 "paddq %%mm7, %%mm1 \n\t" \ 00112 "movd 20(%%edi), %%mm5 \n\t" \ 00113 "paddq %%mm5, %%mm4 \n\t" \ 00114 "movd %%mm1, 12(%%edi) \n\t" \ 00115 "psrlq $32, %%mm1 \n\t" \ 00116 "paddq %%mm2, %%mm1 \n\t" \ 00117 "movd 24(%%edi), %%mm5 \n\t" \ 00118 "paddq %%mm5, %%mm6 \n\t" \ 00119 "movd %%mm1, 16(%%edi) \n\t" \ 00120 "psrlq $32, %%mm1 \n\t" \ 00121 "paddq %%mm4, %%mm1 \n\t" \ 00122 "movd 28(%%edi), %%mm5 \n\t" \ 00123 "paddq %%mm5, %%mm3 \n\t" \ 00124 "movd %%mm1, 20(%%edi) \n\t" \ 00125 "psrlq $32, %%mm1 \n\t" \ 00126 "paddq %%mm6, %%mm1 \n\t" \ 00127 "movd %%mm1, 24(%%edi) \n\t" \ 00128 "psrlq $32, %%mm1 \n\t" \ 00129 "paddq %%mm3, %%mm1 \n\t" \ 00130 "movd %%mm1, 28(%%edi) \n\t" \ 00131 "addl $32, %%edi \n\t" \ 00132 "addl $32, %%esi \n\t" \ 00133 "psrlq $32, %%mm1 \n\t" \ 00134 "movd %%mm1, %%ecx \n\t" 00135 00136 #define MULADDC_STOP \ 00137 "emms \n\t" \ 00138 "movl %4, %%ebx \n\t" \ 00139 "movl %%ecx, %1 \n\t" \ 00140 "movl %%edi, %2 \n\t" \ 00141 "movl %%esi, %3 \n\t" \ 00142 : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ 00143 : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ 00144 : "eax", "ecx", "edx", "esi", "edi" \ 00145 ); 00146 00147 #else 00148 00149 #define MULADDC_STOP \ 00150 "movl %4, %%ebx \n\t" \ 00151 "movl %%ecx, %1 \n\t" \ 00152 "movl %%edi, %2 \n\t" \ 00153 "movl %%esi, %3 \n\t" \ 00154 : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ 00155 : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ 00156 : "eax", "ecx", "edx", "esi", "edi" \ 00157 ); 00158 #endif /* SSE2 */ 00159 #endif /* i386 */ 00160 00161 #if defined(__amd64__) || defined (__x86_64__) 00162 00163 #define MULADDC_INIT \ 00164 asm( \ 00165 "movq %3, %%rsi \n\t" \ 00166 "movq %4, %%rdi \n\t" \ 00167 "movq %5, %%rcx \n\t" \ 00168 "movq %6, %%rbx \n\t" \ 00169 "xorq %%r8, %%r8 \n\t" 00170 00171 #define MULADDC_CORE \ 00172 "movq (%%rsi), %%rax \n\t" \ 00173 "mulq %%rbx \n\t" \ 00174 "addq $8, %%rsi \n\t" \ 00175 "addq %%rcx, %%rax \n\t" \ 00176 "movq %%r8, %%rcx \n\t" \ 00177 "adcq $0, %%rdx \n\t" \ 00178 "nop \n\t" \ 00179 "addq %%rax, (%%rdi) \n\t" \ 00180 "adcq %%rdx, %%rcx \n\t" \ 00181 "addq $8, %%rdi \n\t" 00182 00183 #define MULADDC_STOP \ 00184 "movq %%rcx, %0 \n\t" \ 00185 "movq %%rdi, %1 \n\t" \ 00186 "movq %%rsi, %2 \n\t" \ 00187 : "=m" (c), "=m" (d), "=m" (s) \ 00188 : "m" (s), "m" (d), "m" (c), "m" (b) \ 00189 : "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" \ 00190 ); 00191 00192 #endif /* AMD64 */ 00193 00194 #if defined(__mc68020__) || defined(__mcpu32__) 00195 00196 #define MULADDC_INIT \ 00197 asm( \ 00198 "movl %3, %%a2 \n\t" \ 00199 "movl %4, %%a3 \n\t" \ 00200 "movl %5, %%d3 \n\t" \ 00201 "movl %6, %%d2 \n\t" \ 00202 "moveq #0, %%d0 \n\t" 00203 00204 #define MULADDC_CORE \ 00205 "movel %%a2@+, %%d1 \n\t" \ 00206 "mulul %%d2, %%d4:%%d1 \n\t" \ 00207 "addl %%d3, %%d1 \n\t" \ 00208 "addxl %%d0, %%d4 \n\t" \ 00209 "moveq #0, %%d3 \n\t" \ 00210 "addl %%d1, %%a3@+ \n\t" \ 00211 "addxl %%d4, %%d3 \n\t" 00212 00213 #define MULADDC_STOP \ 00214 "movl %%d3, %0 \n\t" \ 00215 "movl %%a3, %1 \n\t" \ 00216 "movl %%a2, %2 \n\t" \ 00217 : "=m" (c), "=m" (d), "=m" (s) \ 00218 : "m" (s), "m" (d), "m" (c), "m" (b) \ 00219 : "d0", "d1", "d2", "d3", "d4", "a2", "a3" \ 00220 ); 00221 00222 #define MULADDC_HUIT \ 00223 "movel %%a2@+, %%d1 \n\t" \ 00224 "mulul %%d2, %%d4:%%d1 \n\t" \ 00225 "addxl %%d3, %%d1 \n\t" \ 00226 "addxl %%d0, %%d4 \n\t" \ 00227 "addl %%d1, %%a3@+ \n\t" \ 00228 "movel %%a2@+, %%d1 \n\t" \ 00229 "mulul %%d2, %%d3:%%d1 \n\t" \ 00230 "addxl %%d4, %%d1 \n\t" \ 00231 "addxl %%d0, %%d3 \n\t" \ 00232 "addl %%d1, %%a3@+ \n\t" \ 00233 "movel %%a2@+, %%d1 \n\t" \ 00234 "mulul %%d2, %%d4:%%d1 \n\t" \ 00235 "addxl %%d3, %%d1 \n\t" \ 00236 "addxl %%d0, %%d4 \n\t" \ 00237 "addl %%d1, %%a3@+ \n\t" \ 00238 "movel %%a2@+, %%d1 \n\t" \ 00239 "mulul %%d2, %%d3:%%d1 \n\t" \ 00240 "addxl %%d4, %%d1 \n\t" \ 00241 "addxl %%d0, %%d3 \n\t" \ 00242 "addl %%d1, %%a3@+ \n\t" \ 00243 "movel %%a2@+, %%d1 \n\t" \ 00244 "mulul %%d2, %%d4:%%d1 \n\t" \ 00245 "addxl %%d3, %%d1 \n\t" \ 00246 "addxl %%d0, %%d4 \n\t" \ 00247 "addl %%d1, %%a3@+ \n\t" \ 00248 "movel %%a2@+, %%d1 \n\t" \ 00249 "mulul %%d2, %%d3:%%d1 \n\t" \ 00250 "addxl %%d4, %%d1 \n\t" \ 00251 "addxl %%d0, %%d3 \n\t" \ 00252 "addl %%d1, %%a3@+ \n\t" \ 00253 "movel %%a2@+, %%d1 \n\t" \ 00254 "mulul %%d2, %%d4:%%d1 \n\t" \ 00255 "addxl %%d3, %%d1 \n\t" \ 00256 "addxl %%d0, %%d4 \n\t" \ 00257 "addl %%d1, %%a3@+ \n\t" \ 00258 "movel %%a2@+, %%d1 \n\t" \ 00259 "mulul %%d2, %%d3:%%d1 \n\t" \ 00260 "addxl %%d4, %%d1 \n\t" \ 00261 "addxl %%d0, %%d3 \n\t" \ 00262 "addl %%d1, %%a3@+ \n\t" \ 00263 "addxl %%d0, %%d3 \n\t" 00264 00265 #endif /* MC68000 */ 00266 00267 #if defined(__powerpc64__) || defined(__ppc64__) 00268 00269 #if defined(__MACH__) && defined(__APPLE__) 00270 00271 #define MULADDC_INIT \ 00272 asm( \ 00273 "ld r3, %3 \n\t" \ 00274 "ld r4, %4 \n\t" \ 00275 "ld r5, %5 \n\t" \ 00276 "ld r6, %6 \n\t" \ 00277 "addi r3, r3, -8 \n\t" \ 00278 "addi r4, r4, -8 \n\t" \ 00279 "addic r5, r5, 0 \n\t" 00280 00281 #define MULADDC_CORE \ 00282 "ldu r7, 8(r3) \n\t" \ 00283 "mulld r8, r7, r6 \n\t" \ 00284 "mulhdu r9, r7, r6 \n\t" \ 00285 "adde r8, r8, r5 \n\t" \ 00286 "ld r7, 8(r4) \n\t" \ 00287 "addze r5, r9 \n\t" \ 00288 "addc r8, r8, r7 \n\t" \ 00289 "stdu r8, 8(r4) \n\t" 00290 00291 #define MULADDC_STOP \ 00292 "addze r5, r5 \n\t" \ 00293 "addi r4, r4, 8 \n\t" \ 00294 "addi r3, r3, 8 \n\t" \ 00295 "std r5, %0 \n\t" \ 00296 "std r4, %1 \n\t" \ 00297 "std r3, %2 \n\t" \ 00298 : "=m" (c), "=m" (d), "=m" (s) \ 00299 : "m" (s), "m" (d), "m" (c), "m" (b) \ 00300 : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ 00301 ); 00302 00303 00304 #else /* __MACH__ && __APPLE__ */ 00305 00306 #define MULADDC_INIT \ 00307 asm( \ 00308 "ld %%r3, %3 \n\t" \ 00309 "ld %%r4, %4 \n\t" \ 00310 "ld %%r5, %5 \n\t" \ 00311 "ld %%r6, %6 \n\t" \ 00312 "addi %%r3, %%r3, -8 \n\t" \ 00313 "addi %%r4, %%r4, -8 \n\t" \ 00314 "addic %%r5, %%r5, 0 \n\t" 00315 00316 #define MULADDC_CORE \ 00317 "ldu %%r7, 8(%%r3) \n\t" \ 00318 "mulld %%r8, %%r7, %%r6 \n\t" \ 00319 "mulhdu %%r9, %%r7, %%r6 \n\t" \ 00320 "adde %%r8, %%r8, %%r5 \n\t" \ 00321 "ld %%r7, 8(%%r4) \n\t" \ 00322 "addze %%r5, %%r9 \n\t" \ 00323 "addc %%r8, %%r8, %%r7 \n\t" \ 00324 "stdu %%r8, 8(%%r4) \n\t" 00325 00326 #define MULADDC_STOP \ 00327 "addze %%r5, %%r5 \n\t" \ 00328 "addi %%r4, %%r4, 8 \n\t" \ 00329 "addi %%r3, %%r3, 8 \n\t" \ 00330 "std %%r5, %0 \n\t" \ 00331 "std %%r4, %1 \n\t" \ 00332 "std %%r3, %2 \n\t" \ 00333 : "=m" (c), "=m" (d), "=m" (s) \ 00334 : "m" (s), "m" (d), "m" (c), "m" (b) \ 00335 : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ 00336 ); 00337 00338 #endif /* __MACH__ && __APPLE__ */ 00339 00340 #elif defined(__powerpc__) || defined(__ppc__) /* end PPC64/begin PPC32 */ 00341 00342 #if defined(__MACH__) && defined(__APPLE__) 00343 00344 #define MULADDC_INIT \ 00345 asm( \ 00346 "lwz r3, %3 \n\t" \ 00347 "lwz r4, %4 \n\t" \ 00348 "lwz r5, %5 \n\t" \ 00349 "lwz r6, %6 \n\t" \ 00350 "addi r3, r3, -4 \n\t" \ 00351 "addi r4, r4, -4 \n\t" \ 00352 "addic r5, r5, 0 \n\t" 00353 00354 #define MULADDC_CORE \ 00355 "lwzu r7, 4(r3) \n\t" \ 00356 "mullw r8, r7, r6 \n\t" \ 00357 "mulhwu r9, r7, r6 \n\t" \ 00358 "adde r8, r8, r5 \n\t" \ 00359 "lwz r7, 4(r4) \n\t" \ 00360 "addze r5, r9 \n\t" \ 00361 "addc r8, r8, r7 \n\t" \ 00362 "stwu r8, 4(r4) \n\t" 00363 00364 #define MULADDC_STOP \ 00365 "addze r5, r5 \n\t" \ 00366 "addi r4, r4, 4 \n\t" \ 00367 "addi r3, r3, 4 \n\t" \ 00368 "stw r5, %0 \n\t" \ 00369 "stw r4, %1 \n\t" \ 00370 "stw r3, %2 \n\t" \ 00371 : "=m" (c), "=m" (d), "=m" (s) \ 00372 : "m" (s), "m" (d), "m" (c), "m" (b) \ 00373 : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ 00374 ); 00375 00376 #else /* __MACH__ && __APPLE__ */ 00377 00378 #define MULADDC_INIT \ 00379 asm( \ 00380 "lwz %%r3, %3 \n\t" \ 00381 "lwz %%r4, %4 \n\t" \ 00382 "lwz %%r5, %5 \n\t" \ 00383 "lwz %%r6, %6 \n\t" \ 00384 "addi %%r3, %%r3, -4 \n\t" \ 00385 "addi %%r4, %%r4, -4 \n\t" \ 00386 "addic %%r5, %%r5, 0 \n\t" 00387 00388 #define MULADDC_CORE \ 00389 "lwzu %%r7, 4(%%r3) \n\t" \ 00390 "mullw %%r8, %%r7, %%r6 \n\t" \ 00391 "mulhwu %%r9, %%r7, %%r6 \n\t" \ 00392 "adde %%r8, %%r8, %%r5 \n\t" \ 00393 "lwz %%r7, 4(%%r4) \n\t" \ 00394 "addze %%r5, %%r9 \n\t" \ 00395 "addc %%r8, %%r8, %%r7 \n\t" \ 00396 "stwu %%r8, 4(%%r4) \n\t" 00397 00398 #define MULADDC_STOP \ 00399 "addze %%r5, %%r5 \n\t" \ 00400 "addi %%r4, %%r4, 4 \n\t" \ 00401 "addi %%r3, %%r3, 4 \n\t" \ 00402 "stw %%r5, %0 \n\t" \ 00403 "stw %%r4, %1 \n\t" \ 00404 "stw %%r3, %2 \n\t" \ 00405 : "=m" (c), "=m" (d), "=m" (s) \ 00406 : "m" (s), "m" (d), "m" (c), "m" (b) \ 00407 : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ 00408 ); 00409 00410 #endif /* __MACH__ && __APPLE__ */ 00411 00412 #endif /* PPC32 */ 00413 00414 /* 00415 * The Sparc(64) assembly is reported to be broken. 00416 * Disable it for now, until we're able to fix it. 00417 */ 00418 #if 0 && defined(__sparc__) 00419 #if defined(__sparc64__) 00420 00421 #define MULADDC_INIT \ 00422 asm( \ 00423 "ldx %3, %%o0 \n\t" \ 00424 "ldx %4, %%o1 \n\t" \ 00425 "ld %5, %%o2 \n\t" \ 00426 "ld %6, %%o3 \n\t" 00427 00428 #define MULADDC_CORE \ 00429 "ld [%%o0], %%o4 \n\t" \ 00430 "inc 4, %%o0 \n\t" \ 00431 "ld [%%o1], %%o5 \n\t" \ 00432 "umul %%o3, %%o4, %%o4 \n\t" \ 00433 "addcc %%o4, %%o2, %%o4 \n\t" \ 00434 "rd %%y, %%g1 \n\t" \ 00435 "addx %%g1, 0, %%g1 \n\t" \ 00436 "addcc %%o4, %%o5, %%o4 \n\t" \ 00437 "st %%o4, [%%o1] \n\t" \ 00438 "addx %%g1, 0, %%o2 \n\t" \ 00439 "inc 4, %%o1 \n\t" 00440 00441 #define MULADDC_STOP \ 00442 "st %%o2, %0 \n\t" \ 00443 "stx %%o1, %1 \n\t" \ 00444 "stx %%o0, %2 \n\t" \ 00445 : "=m" (c), "=m" (d), "=m" (s) \ 00446 : "m" (s), "m" (d), "m" (c), "m" (b) \ 00447 : "g1", "o0", "o1", "o2", "o3", "o4", \ 00448 "o5" \ 00449 ); 00450 00451 #else /* __sparc64__ */ 00452 00453 #define MULADDC_INIT \ 00454 asm( \ 00455 "ld %3, %%o0 \n\t" \ 00456 "ld %4, %%o1 \n\t" \ 00457 "ld %5, %%o2 \n\t" \ 00458 "ld %6, %%o3 \n\t" 00459 00460 #define MULADDC_CORE \ 00461 "ld [%%o0], %%o4 \n\t" \ 00462 "inc 4, %%o0 \n\t" \ 00463 "ld [%%o1], %%o5 \n\t" \ 00464 "umul %%o3, %%o4, %%o4 \n\t" \ 00465 "addcc %%o4, %%o2, %%o4 \n\t" \ 00466 "rd %%y, %%g1 \n\t" \ 00467 "addx %%g1, 0, %%g1 \n\t" \ 00468 "addcc %%o4, %%o5, %%o4 \n\t" \ 00469 "st %%o4, [%%o1] \n\t" \ 00470 "addx %%g1, 0, %%o2 \n\t" \ 00471 "inc 4, %%o1 \n\t" 00472 00473 #define MULADDC_STOP \ 00474 "st %%o2, %0 \n\t" \ 00475 "st %%o1, %1 \n\t" \ 00476 "st %%o0, %2 \n\t" \ 00477 : "=m" (c), "=m" (d), "=m" (s) \ 00478 : "m" (s), "m" (d), "m" (c), "m" (b) \ 00479 : "g1", "o0", "o1", "o2", "o3", "o4", \ 00480 "o5" \ 00481 ); 00482 00483 #endif /* __sparc64__ */ 00484 #endif /* __sparc__ */ 00485 00486 #if defined(__microblaze__) || defined(microblaze) 00487 00488 #define MULADDC_INIT \ 00489 asm( \ 00490 "lwi r3, %3 \n\t" \ 00491 "lwi r4, %4 \n\t" \ 00492 "lwi r5, %5 \n\t" \ 00493 "lwi r6, %6 \n\t" \ 00494 "andi r7, r6, 0xffff \n\t" \ 00495 "bsrli r6, r6, 16 \n\t" 00496 00497 #define MULADDC_CORE \ 00498 "lhui r8, r3, 0 \n\t" \ 00499 "addi r3, r3, 2 \n\t" \ 00500 "lhui r9, r3, 0 \n\t" \ 00501 "addi r3, r3, 2 \n\t" \ 00502 "mul r10, r9, r6 \n\t" \ 00503 "mul r11, r8, r7 \n\t" \ 00504 "mul r12, r9, r7 \n\t" \ 00505 "mul r13, r8, r6 \n\t" \ 00506 "bsrli r8, r10, 16 \n\t" \ 00507 "bsrli r9, r11, 16 \n\t" \ 00508 "add r13, r13, r8 \n\t" \ 00509 "add r13, r13, r9 \n\t" \ 00510 "bslli r10, r10, 16 \n\t" \ 00511 "bslli r11, r11, 16 \n\t" \ 00512 "add r12, r12, r10 \n\t" \ 00513 "addc r13, r13, r0 \n\t" \ 00514 "add r12, r12, r11 \n\t" \ 00515 "addc r13, r13, r0 \n\t" \ 00516 "lwi r10, r4, 0 \n\t" \ 00517 "add r12, r12, r10 \n\t" \ 00518 "addc r13, r13, r0 \n\t" \ 00519 "add r12, r12, r5 \n\t" \ 00520 "addc r5, r13, r0 \n\t" \ 00521 "swi r12, r4, 0 \n\t" \ 00522 "addi r4, r4, 4 \n\t" 00523 00524 #define MULADDC_STOP \ 00525 "swi r5, %0 \n\t" \ 00526 "swi r4, %1 \n\t" \ 00527 "swi r3, %2 \n\t" \ 00528 : "=m" (c), "=m" (d), "=m" (s) \ 00529 : "m" (s), "m" (d), "m" (c), "m" (b) \ 00530 : "r3", "r4" "r5", "r6", "r7", "r8", \ 00531 "r9", "r10", "r11", "r12", "r13" \ 00532 ); 00533 00534 #endif /* MicroBlaze */ 00535 00536 #if defined(__tricore__) 00537 00538 #define MULADDC_INIT \ 00539 asm( \ 00540 "ld.a %%a2, %3 \n\t" \ 00541 "ld.a %%a3, %4 \n\t" \ 00542 "ld.w %%d4, %5 \n\t" \ 00543 "ld.w %%d1, %6 \n\t" \ 00544 "xor %%d5, %%d5 \n\t" 00545 00546 #define MULADDC_CORE \ 00547 "ld.w %%d0, [%%a2+] \n\t" \ 00548 "madd.u %%e2, %%e4, %%d0, %%d1 \n\t" \ 00549 "ld.w %%d0, [%%a3] \n\t" \ 00550 "addx %%d2, %%d2, %%d0 \n\t" \ 00551 "addc %%d3, %%d3, 0 \n\t" \ 00552 "mov %%d4, %%d3 \n\t" \ 00553 "st.w [%%a3+], %%d2 \n\t" 00554 00555 #define MULADDC_STOP \ 00556 "st.w %0, %%d4 \n\t" \ 00557 "st.a %1, %%a3 \n\t" \ 00558 "st.a %2, %%a2 \n\t" \ 00559 : "=m" (c), "=m" (d), "=m" (s) \ 00560 : "m" (s), "m" (d), "m" (c), "m" (b) \ 00561 : "d0", "d1", "e2", "d4", "a2", "a3" \ 00562 ); 00563 00564 #endif /* TriCore */ 00565 00566 #if defined(__arm__) 00567 00568 #if defined(__thumb__) && !defined(__thumb2__) 00569 00570 #define MULADDC_INIT \ 00571 asm( \ 00572 "ldr r0, %3 \n\t" \ 00573 "ldr r1, %4 \n\t" \ 00574 "ldr r2, %5 \n\t" \ 00575 "ldr r3, %6 \n\t" \ 00576 "lsr r7, r3, #16 \n\t" \ 00577 "mov r9, r7 \n\t" \ 00578 "lsl r7, r3, #16 \n\t" \ 00579 "lsr r7, r7, #16 \n\t" \ 00580 "mov r8, r7 \n\t" 00581 00582 #define MULADDC_CORE \ 00583 "ldmia r0!, {r6} \n\t" \ 00584 "lsr r7, r6, #16 \n\t" \ 00585 "lsl r6, r6, #16 \n\t" \ 00586 "lsr r6, r6, #16 \n\t" \ 00587 "mov r4, r8 \n\t" \ 00588 "mul r4, r6 \n\t" \ 00589 "mov r3, r9 \n\t" \ 00590 "mul r6, r3 \n\t" \ 00591 "mov r5, r9 \n\t" \ 00592 "mul r5, r7 \n\t" \ 00593 "mov r3, r8 \n\t" \ 00594 "mul r7, r3 \n\t" \ 00595 "lsr r3, r6, #16 \n\t" \ 00596 "add r5, r5, r3 \n\t" \ 00597 "lsr r3, r7, #16 \n\t" \ 00598 "add r5, r5, r3 \n\t" \ 00599 "add r4, r4, r2 \n\t" \ 00600 "mov r2, #0 \n\t" \ 00601 "adc r5, r2 \n\t" \ 00602 "lsl r3, r6, #16 \n\t" \ 00603 "add r4, r4, r3 \n\t" \ 00604 "adc r5, r2 \n\t" \ 00605 "lsl r3, r7, #16 \n\t" \ 00606 "add r4, r4, r3 \n\t" \ 00607 "adc r5, r2 \n\t" \ 00608 "ldr r3, [r1] \n\t" \ 00609 "add r4, r4, r3 \n\t" \ 00610 "adc r2, r5 \n\t" \ 00611 "stmia r1!, {r4} \n\t" 00612 00613 #define MULADDC_STOP \ 00614 "str r2, %0 \n\t" \ 00615 "str r1, %1 \n\t" \ 00616 "str r0, %2 \n\t" \ 00617 : "=m" (c), "=m" (d), "=m" (s) \ 00618 : "m" (s), "m" (d), "m" (c), "m" (b) \ 00619 : "r0", "r1", "r2", "r3", "r4", "r5", \ 00620 "r6", "r7", "r8", "r9", "cc" \ 00621 ); 00622 00623 #else 00624 00625 #define MULADDC_INIT \ 00626 asm( \ 00627 "ldr r0, %3 \n\t" \ 00628 "ldr r1, %4 \n\t" \ 00629 "ldr r2, %5 \n\t" \ 00630 "ldr r3, %6 \n\t" 00631 00632 #define MULADDC_CORE \ 00633 "ldr r4, [r0], #4 \n\t" \ 00634 "mov r5, #0 \n\t" \ 00635 "ldr r6, [r1] \n\t" \ 00636 "umlal r2, r5, r3, r4 \n\t" \ 00637 "adds r7, r6, r2 \n\t" \ 00638 "adc r2, r5, #0 \n\t" \ 00639 "str r7, [r1], #4 \n\t" 00640 00641 #define MULADDC_STOP \ 00642 "str r2, %0 \n\t" \ 00643 "str r1, %1 \n\t" \ 00644 "str r0, %2 \n\t" \ 00645 : "=m" (c), "=m" (d), "=m" (s) \ 00646 : "m" (s), "m" (d), "m" (c), "m" (b) \ 00647 : "r0", "r1", "r2", "r3", "r4", "r5", \ 00648 "r6", "r7", "cc" \ 00649 ); 00650 00651 #endif /* Thumb */ 00652 00653 #endif /* ARMv3 */ 00654 00655 #if defined(__alpha__) 00656 00657 #define MULADDC_INIT \ 00658 asm( \ 00659 "ldq $1, %3 \n\t" \ 00660 "ldq $2, %4 \n\t" \ 00661 "ldq $3, %5 \n\t" \ 00662 "ldq $4, %6 \n\t" 00663 00664 #define MULADDC_CORE \ 00665 "ldq $6, 0($1) \n\t" \ 00666 "addq $1, 8, $1 \n\t" \ 00667 "mulq $6, $4, $7 \n\t" \ 00668 "umulh $6, $4, $6 \n\t" \ 00669 "addq $7, $3, $7 \n\t" \ 00670 "cmpult $7, $3, $3 \n\t" \ 00671 "ldq $5, 0($2) \n\t" \ 00672 "addq $7, $5, $7 \n\t" \ 00673 "cmpult $7, $5, $5 \n\t" \ 00674 "stq $7, 0($2) \n\t" \ 00675 "addq $2, 8, $2 \n\t" \ 00676 "addq $6, $3, $3 \n\t" \ 00677 "addq $5, $3, $3 \n\t" 00678 00679 #define MULADDC_STOP \ 00680 "stq $3, %0 \n\t" \ 00681 "stq $2, %1 \n\t" \ 00682 "stq $1, %2 \n\t" \ 00683 : "=m" (c), "=m" (d), "=m" (s) \ 00684 : "m" (s), "m" (d), "m" (c), "m" (b) \ 00685 : "$1", "$2", "$3", "$4", "$5", "$6", "$7" \ 00686 ); 00687 #endif /* Alpha */ 00688 00689 #if defined(__mips__) && !defined(__mips64) 00690 00691 #define MULADDC_INIT \ 00692 asm( \ 00693 "lw $10, %3 \n\t" \ 00694 "lw $11, %4 \n\t" \ 00695 "lw $12, %5 \n\t" \ 00696 "lw $13, %6 \n\t" 00697 00698 #define MULADDC_CORE \ 00699 "lw $14, 0($10) \n\t" \ 00700 "multu $13, $14 \n\t" \ 00701 "addi $10, $10, 4 \n\t" \ 00702 "mflo $14 \n\t" \ 00703 "mfhi $9 \n\t" \ 00704 "addu $14, $12, $14 \n\t" \ 00705 "lw $15, 0($11) \n\t" \ 00706 "sltu $12, $14, $12 \n\t" \ 00707 "addu $15, $14, $15 \n\t" \ 00708 "sltu $14, $15, $14 \n\t" \ 00709 "addu $12, $12, $9 \n\t" \ 00710 "sw $15, 0($11) \n\t" \ 00711 "addu $12, $12, $14 \n\t" \ 00712 "addi $11, $11, 4 \n\t" 00713 00714 #define MULADDC_STOP \ 00715 "sw $12, %0 \n\t" \ 00716 "sw $11, %1 \n\t" \ 00717 "sw $10, %2 \n\t" \ 00718 : "=m" (c), "=m" (d), "=m" (s) \ 00719 : "m" (s), "m" (d), "m" (c), "m" (b) \ 00720 : "$9", "$10", "$11", "$12", "$13", "$14", "$15" \ 00721 ); 00722 00723 #endif /* MIPS */ 00724 #endif /* GNUC */ 00725 00726 #if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) 00727 00728 #define MULADDC_INIT \ 00729 __asm mov esi, s \ 00730 __asm mov edi, d \ 00731 __asm mov ecx, c \ 00732 __asm mov ebx, b 00733 00734 #define MULADDC_CORE \ 00735 __asm lodsd \ 00736 __asm mul ebx \ 00737 __asm add eax, ecx \ 00738 __asm adc edx, 0 \ 00739 __asm add eax, [edi] \ 00740 __asm adc edx, 0 \ 00741 __asm mov ecx, edx \ 00742 __asm stosd 00743 00744 #if defined(MBEDTLS_HAVE_SSE2) 00745 00746 #define EMIT __asm _emit 00747 00748 #define MULADDC_HUIT \ 00749 EMIT 0x0F EMIT 0x6E EMIT 0xC9 \ 00750 EMIT 0x0F EMIT 0x6E EMIT 0xC3 \ 00751 EMIT 0x0F EMIT 0x6E EMIT 0x1F \ 00752 EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ 00753 EMIT 0x0F EMIT 0x6E EMIT 0x16 \ 00754 EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ 00755 EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \ 00756 EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ 00757 EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \ 00758 EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ 00759 EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \ 00760 EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \ 00761 EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ 00762 EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \ 00763 EMIT 0x0F EMIT 0xD4 EMIT 0xDC \ 00764 EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \ 00765 EMIT 0x0F EMIT 0xD4 EMIT 0xEE \ 00766 EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \ 00767 EMIT 0x0F EMIT 0xD4 EMIT 0xFC \ 00768 EMIT 0x0F EMIT 0x7E EMIT 0x0F \ 00769 EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \ 00770 EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ 00771 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 00772 EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \ 00773 EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ 00774 EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ 00775 EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \ 00776 EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ 00777 EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \ 00778 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 00779 EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \ 00780 EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \ 00781 EMIT 0x0F EMIT 0xD4 EMIT 0xCD \ 00782 EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \ 00783 EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \ 00784 EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \ 00785 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 00786 EMIT 0x0F EMIT 0xD4 EMIT 0xCF \ 00787 EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \ 00788 EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \ 00789 EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \ 00790 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 00791 EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ 00792 EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \ 00793 EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \ 00794 EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \ 00795 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 00796 EMIT 0x0F EMIT 0xD4 EMIT 0xCC \ 00797 EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \ 00798 EMIT 0x0F EMIT 0xD4 EMIT 0xDD \ 00799 EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \ 00800 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 00801 EMIT 0x0F EMIT 0xD4 EMIT 0xCE \ 00802 EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \ 00803 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 00804 EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ 00805 EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \ 00806 EMIT 0x83 EMIT 0xC7 EMIT 0x20 \ 00807 EMIT 0x83 EMIT 0xC6 EMIT 0x20 \ 00808 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ 00809 EMIT 0x0F EMIT 0x7E EMIT 0xC9 00810 00811 #define MULADDC_STOP \ 00812 EMIT 0x0F EMIT 0x77 \ 00813 __asm mov c, ecx \ 00814 __asm mov d, edi \ 00815 __asm mov s, esi \ 00816 00817 #else 00818 00819 #define MULADDC_STOP \ 00820 __asm mov c, ecx \ 00821 __asm mov d, edi \ 00822 __asm mov s, esi \ 00823 00824 #endif /* SSE2 */ 00825 #endif /* MSVC */ 00826 00827 #endif /* MBEDTLS_HAVE_ASM */ 00828 00829 #if !defined(MULADDC_CORE) 00830 #if defined(MBEDTLS_HAVE_UDBL) 00831 00832 #define MULADDC_INIT \ 00833 { \ 00834 mbedtls_t_udbl r; \ 00835 mbedtls_mpi_uint r0, r1; 00836 00837 #define MULADDC_CORE \ 00838 r = *(s++) * (mbedtls_t_udbl) b; \ 00839 r0 = (mbedtls_mpi_uint) r; \ 00840 r1 = (mbedtls_mpi_uint)( r >> biL ); \ 00841 r0 += c; r1 += (r0 < c); \ 00842 r0 += *d; r1 += (r0 < *d); \ 00843 c = r1; *(d++) = r0; 00844 00845 #define MULADDC_STOP \ 00846 } 00847 00848 #else 00849 #define MULADDC_INIT \ 00850 { \ 00851 mbedtls_mpi_uint s0, s1, b0, b1; \ 00852 mbedtls_mpi_uint r0, r1, rx, ry; \ 00853 b0 = ( b << biH ) >> biH; \ 00854 b1 = ( b >> biH ); 00855 00856 #define MULADDC_CORE \ 00857 s0 = ( *s << biH ) >> biH; \ 00858 s1 = ( *s >> biH ); s++; \ 00859 rx = s0 * b1; r0 = s0 * b0; \ 00860 ry = s1 * b0; r1 = s1 * b1; \ 00861 r1 += ( rx >> biH ); \ 00862 r1 += ( ry >> biH ); \ 00863 rx <<= biH; ry <<= biH; \ 00864 r0 += rx; r1 += (r0 < rx); \ 00865 r0 += ry; r1 += (r0 < ry); \ 00866 r0 += c; r1 += (r0 < c); \ 00867 r0 += *d; r1 += (r0 < *d); \ 00868 c = r1; *(d++) = r0; 00869 00870 #define MULADDC_STOP \ 00871 } 00872 00873 #endif /* C (generic) */ 00874 #endif /* C (longlong) */ 00875 00876 #endif /* bn_mul.h */
Generated on Tue Jul 12 2022 12:52:41 by
