mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Committer:
ansond
Date:
Thu Jun 11 03:27:03 2015 +0000
Revision:
0:137634ff4186
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:137634ff4186 1 /**
ansond 0:137634ff4186 2 * \file bn_mul.h
ansond 0:137634ff4186 3 *
ansond 0:137634ff4186 4 * \brief Multi-precision integer library
ansond 0:137634ff4186 5 *
ansond 0:137634ff4186 6 * Copyright (C) 2006-2010, ARM Limited, All Rights Reserved
ansond 0:137634ff4186 7 *
ansond 0:137634ff4186 8 * This file is part of mbed TLS (https://tls.mbed.org)
ansond 0:137634ff4186 9 *
ansond 0:137634ff4186 10 * This program is free software; you can redistribute it and/or modify
ansond 0:137634ff4186 11 * it under the terms of the GNU General Public License as published by
ansond 0:137634ff4186 12 * the Free Software Foundation; either version 2 of the License, or
ansond 0:137634ff4186 13 * (at your option) any later version.
ansond 0:137634ff4186 14 *
ansond 0:137634ff4186 15 * This program is distributed in the hope that it will be useful,
ansond 0:137634ff4186 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ansond 0:137634ff4186 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ansond 0:137634ff4186 18 * GNU General Public License for more details.
ansond 0:137634ff4186 19 *
ansond 0:137634ff4186 20 * You should have received a copy of the GNU General Public License along
ansond 0:137634ff4186 21 * with this program; if not, write to the Free Software Foundation, Inc.,
ansond 0:137634ff4186 22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ansond 0:137634ff4186 23 */
ansond 0:137634ff4186 24 /*
ansond 0:137634ff4186 25 * Multiply source vector [s] with b, add result
ansond 0:137634ff4186 26 * to destination vector [d] and set carry c.
ansond 0:137634ff4186 27 *
ansond 0:137634ff4186 28 * Currently supports:
ansond 0:137634ff4186 29 *
ansond 0:137634ff4186 30 * . IA-32 (386+) . AMD64 / EM64T
ansond 0:137634ff4186 31 * . IA-32 (SSE2) . Motorola 68000
ansond 0:137634ff4186 32 * . PowerPC, 32-bit . MicroBlaze
ansond 0:137634ff4186 33 * . PowerPC, 64-bit . TriCore
ansond 0:137634ff4186 34 * . SPARC v8 . ARM v3+
ansond 0:137634ff4186 35 * . Alpha . MIPS32
ansond 0:137634ff4186 36 * . C, longlong . C, generic
ansond 0:137634ff4186 37 */
ansond 0:137634ff4186 38 #ifndef POLARSSL_BN_MUL_H
ansond 0:137634ff4186 39 #define POLARSSL_BN_MUL_H
ansond 0:137634ff4186 40
ansond 0:137634ff4186 41 #include "bignum.h"
ansond 0:137634ff4186 42
ansond 0:137634ff4186 43 #if defined(POLARSSL_HAVE_ASM)
ansond 0:137634ff4186 44
ansond 0:137634ff4186 45 #if defined(__GNUC__)
ansond 0:137634ff4186 46 #if defined(__i386__)
ansond 0:137634ff4186 47
ansond 0:137634ff4186 48 #define MULADDC_INIT \
ansond 0:137634ff4186 49 asm( \
ansond 0:137634ff4186 50 "movl %%ebx, %0 \n\t" \
ansond 0:137634ff4186 51 "movl %5, %%esi \n\t" \
ansond 0:137634ff4186 52 "movl %6, %%edi \n\t" \
ansond 0:137634ff4186 53 "movl %7, %%ecx \n\t" \
ansond 0:137634ff4186 54 "movl %8, %%ebx \n\t"
ansond 0:137634ff4186 55
ansond 0:137634ff4186 56 #define MULADDC_CORE \
ansond 0:137634ff4186 57 "lodsl \n\t" \
ansond 0:137634ff4186 58 "mull %%ebx \n\t" \
ansond 0:137634ff4186 59 "addl %%ecx, %%eax \n\t" \
ansond 0:137634ff4186 60 "adcl $0, %%edx \n\t" \
ansond 0:137634ff4186 61 "addl (%%edi), %%eax \n\t" \
ansond 0:137634ff4186 62 "adcl $0, %%edx \n\t" \
ansond 0:137634ff4186 63 "movl %%edx, %%ecx \n\t" \
ansond 0:137634ff4186 64 "stosl \n\t"
ansond 0:137634ff4186 65
ansond 0:137634ff4186 66 #if defined(POLARSSL_HAVE_SSE2)
ansond 0:137634ff4186 67
ansond 0:137634ff4186 68 #define MULADDC_HUIT \
ansond 0:137634ff4186 69 "movd %%ecx, %%mm1 \n\t" \
ansond 0:137634ff4186 70 "movd %%ebx, %%mm0 \n\t" \
ansond 0:137634ff4186 71 "movd (%%edi), %%mm3 \n\t" \
ansond 0:137634ff4186 72 "paddq %%mm3, %%mm1 \n\t" \
ansond 0:137634ff4186 73 "movd (%%esi), %%mm2 \n\t" \
ansond 0:137634ff4186 74 "pmuludq %%mm0, %%mm2 \n\t" \
ansond 0:137634ff4186 75 "movd 4(%%esi), %%mm4 \n\t" \
ansond 0:137634ff4186 76 "pmuludq %%mm0, %%mm4 \n\t" \
ansond 0:137634ff4186 77 "movd 8(%%esi), %%mm6 \n\t" \
ansond 0:137634ff4186 78 "pmuludq %%mm0, %%mm6 \n\t" \
ansond 0:137634ff4186 79 "movd 12(%%esi), %%mm7 \n\t" \
ansond 0:137634ff4186 80 "pmuludq %%mm0, %%mm7 \n\t" \
ansond 0:137634ff4186 81 "paddq %%mm2, %%mm1 \n\t" \
ansond 0:137634ff4186 82 "movd 4(%%edi), %%mm3 \n\t" \
ansond 0:137634ff4186 83 "paddq %%mm4, %%mm3 \n\t" \
ansond 0:137634ff4186 84 "movd 8(%%edi), %%mm5 \n\t" \
ansond 0:137634ff4186 85 "paddq %%mm6, %%mm5 \n\t" \
ansond 0:137634ff4186 86 "movd 12(%%edi), %%mm4 \n\t" \
ansond 0:137634ff4186 87 "paddq %%mm4, %%mm7 \n\t" \
ansond 0:137634ff4186 88 "movd %%mm1, (%%edi) \n\t" \
ansond 0:137634ff4186 89 "movd 16(%%esi), %%mm2 \n\t" \
ansond 0:137634ff4186 90 "pmuludq %%mm0, %%mm2 \n\t" \
ansond 0:137634ff4186 91 "psrlq $32, %%mm1 \n\t" \
ansond 0:137634ff4186 92 "movd 20(%%esi), %%mm4 \n\t" \
ansond 0:137634ff4186 93 "pmuludq %%mm0, %%mm4 \n\t" \
ansond 0:137634ff4186 94 "paddq %%mm3, %%mm1 \n\t" \
ansond 0:137634ff4186 95 "movd 24(%%esi), %%mm6 \n\t" \
ansond 0:137634ff4186 96 "pmuludq %%mm0, %%mm6 \n\t" \
ansond 0:137634ff4186 97 "movd %%mm1, 4(%%edi) \n\t" \
ansond 0:137634ff4186 98 "psrlq $32, %%mm1 \n\t" \
ansond 0:137634ff4186 99 "movd 28(%%esi), %%mm3 \n\t" \
ansond 0:137634ff4186 100 "pmuludq %%mm0, %%mm3 \n\t" \
ansond 0:137634ff4186 101 "paddq %%mm5, %%mm1 \n\t" \
ansond 0:137634ff4186 102 "movd 16(%%edi), %%mm5 \n\t" \
ansond 0:137634ff4186 103 "paddq %%mm5, %%mm2 \n\t" \
ansond 0:137634ff4186 104 "movd %%mm1, 8(%%edi) \n\t" \
ansond 0:137634ff4186 105 "psrlq $32, %%mm1 \n\t" \
ansond 0:137634ff4186 106 "paddq %%mm7, %%mm1 \n\t" \
ansond 0:137634ff4186 107 "movd 20(%%edi), %%mm5 \n\t" \
ansond 0:137634ff4186 108 "paddq %%mm5, %%mm4 \n\t" \
ansond 0:137634ff4186 109 "movd %%mm1, 12(%%edi) \n\t" \
ansond 0:137634ff4186 110 "psrlq $32, %%mm1 \n\t" \
ansond 0:137634ff4186 111 "paddq %%mm2, %%mm1 \n\t" \
ansond 0:137634ff4186 112 "movd 24(%%edi), %%mm5 \n\t" \
ansond 0:137634ff4186 113 "paddq %%mm5, %%mm6 \n\t" \
ansond 0:137634ff4186 114 "movd %%mm1, 16(%%edi) \n\t" \
ansond 0:137634ff4186 115 "psrlq $32, %%mm1 \n\t" \
ansond 0:137634ff4186 116 "paddq %%mm4, %%mm1 \n\t" \
ansond 0:137634ff4186 117 "movd 28(%%edi), %%mm5 \n\t" \
ansond 0:137634ff4186 118 "paddq %%mm5, %%mm3 \n\t" \
ansond 0:137634ff4186 119 "movd %%mm1, 20(%%edi) \n\t" \
ansond 0:137634ff4186 120 "psrlq $32, %%mm1 \n\t" \
ansond 0:137634ff4186 121 "paddq %%mm6, %%mm1 \n\t" \
ansond 0:137634ff4186 122 "movd %%mm1, 24(%%edi) \n\t" \
ansond 0:137634ff4186 123 "psrlq $32, %%mm1 \n\t" \
ansond 0:137634ff4186 124 "paddq %%mm3, %%mm1 \n\t" \
ansond 0:137634ff4186 125 "movd %%mm1, 28(%%edi) \n\t" \
ansond 0:137634ff4186 126 "addl $32, %%edi \n\t" \
ansond 0:137634ff4186 127 "addl $32, %%esi \n\t" \
ansond 0:137634ff4186 128 "psrlq $32, %%mm1 \n\t" \
ansond 0:137634ff4186 129 "movd %%mm1, %%ecx \n\t"
ansond 0:137634ff4186 130
ansond 0:137634ff4186 131 #define MULADDC_STOP \
ansond 0:137634ff4186 132 "emms \n\t" \
ansond 0:137634ff4186 133 "movl %4, %%ebx \n\t" \
ansond 0:137634ff4186 134 "movl %%ecx, %1 \n\t" \
ansond 0:137634ff4186 135 "movl %%edi, %2 \n\t" \
ansond 0:137634ff4186 136 "movl %%esi, %3 \n\t" \
ansond 0:137634ff4186 137 : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 138 : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 139 : "eax", "ecx", "edx", "esi", "edi" \
ansond 0:137634ff4186 140 );
ansond 0:137634ff4186 141
ansond 0:137634ff4186 142 #else
ansond 0:137634ff4186 143
ansond 0:137634ff4186 144 #define MULADDC_STOP \
ansond 0:137634ff4186 145 "movl %4, %%ebx \n\t" \
ansond 0:137634ff4186 146 "movl %%ecx, %1 \n\t" \
ansond 0:137634ff4186 147 "movl %%edi, %2 \n\t" \
ansond 0:137634ff4186 148 "movl %%esi, %3 \n\t" \
ansond 0:137634ff4186 149 : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 150 : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 151 : "eax", "ecx", "edx", "esi", "edi" \
ansond 0:137634ff4186 152 );
ansond 0:137634ff4186 153 #endif /* SSE2 */
ansond 0:137634ff4186 154 #endif /* i386 */
ansond 0:137634ff4186 155
ansond 0:137634ff4186 156 #if defined(__amd64__) || defined (__x86_64__)
ansond 0:137634ff4186 157
ansond 0:137634ff4186 158 #define MULADDC_INIT \
ansond 0:137634ff4186 159 asm( \
ansond 0:137634ff4186 160 "movq %3, %%rsi \n\t" \
ansond 0:137634ff4186 161 "movq %4, %%rdi \n\t" \
ansond 0:137634ff4186 162 "movq %5, %%rcx \n\t" \
ansond 0:137634ff4186 163 "movq %6, %%rbx \n\t" \
ansond 0:137634ff4186 164 "xorq %%r8, %%r8 \n\t"
ansond 0:137634ff4186 165
ansond 0:137634ff4186 166 #define MULADDC_CORE \
ansond 0:137634ff4186 167 "movq (%%rsi), %%rax \n\t" \
ansond 0:137634ff4186 168 "mulq %%rbx \n\t" \
ansond 0:137634ff4186 169 "addq $8, %%rsi \n\t" \
ansond 0:137634ff4186 170 "addq %%rcx, %%rax \n\t" \
ansond 0:137634ff4186 171 "movq %%r8, %%rcx \n\t" \
ansond 0:137634ff4186 172 "adcq $0, %%rdx \n\t" \
ansond 0:137634ff4186 173 "nop \n\t" \
ansond 0:137634ff4186 174 "addq %%rax, (%%rdi) \n\t" \
ansond 0:137634ff4186 175 "adcq %%rdx, %%rcx \n\t" \
ansond 0:137634ff4186 176 "addq $8, %%rdi \n\t"
ansond 0:137634ff4186 177
ansond 0:137634ff4186 178 #define MULADDC_STOP \
ansond 0:137634ff4186 179 "movq %%rcx, %0 \n\t" \
ansond 0:137634ff4186 180 "movq %%rdi, %1 \n\t" \
ansond 0:137634ff4186 181 "movq %%rsi, %2 \n\t" \
ansond 0:137634ff4186 182 : "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 183 : "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 184 : "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" \
ansond 0:137634ff4186 185 );
ansond 0:137634ff4186 186
ansond 0:137634ff4186 187 #endif /* AMD64 */
ansond 0:137634ff4186 188
ansond 0:137634ff4186 189 #if defined(__mc68020__) || defined(__mcpu32__)
ansond 0:137634ff4186 190
ansond 0:137634ff4186 191 #define MULADDC_INIT \
ansond 0:137634ff4186 192 asm( \
ansond 0:137634ff4186 193 "movl %3, %%a2 \n\t" \
ansond 0:137634ff4186 194 "movl %4, %%a3 \n\t" \
ansond 0:137634ff4186 195 "movl %5, %%d3 \n\t" \
ansond 0:137634ff4186 196 "movl %6, %%d2 \n\t" \
ansond 0:137634ff4186 197 "moveq #0, %%d0 \n\t"
ansond 0:137634ff4186 198
ansond 0:137634ff4186 199 #define MULADDC_CORE \
ansond 0:137634ff4186 200 "movel %%a2@+, %%d1 \n\t" \
ansond 0:137634ff4186 201 "mulul %%d2, %%d4:%%d1 \n\t" \
ansond 0:137634ff4186 202 "addl %%d3, %%d1 \n\t" \
ansond 0:137634ff4186 203 "addxl %%d0, %%d4 \n\t" \
ansond 0:137634ff4186 204 "moveq #0, %%d3 \n\t" \
ansond 0:137634ff4186 205 "addl %%d1, %%a3@+ \n\t" \
ansond 0:137634ff4186 206 "addxl %%d4, %%d3 \n\t"
ansond 0:137634ff4186 207
ansond 0:137634ff4186 208 #define MULADDC_STOP \
ansond 0:137634ff4186 209 "movl %%d3, %0 \n\t" \
ansond 0:137634ff4186 210 "movl %%a3, %1 \n\t" \
ansond 0:137634ff4186 211 "movl %%a2, %2 \n\t" \
ansond 0:137634ff4186 212 : "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 213 : "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 214 : "d0", "d1", "d2", "d3", "d4", "a2", "a3" \
ansond 0:137634ff4186 215 );
ansond 0:137634ff4186 216
ansond 0:137634ff4186 217 #define MULADDC_HUIT \
ansond 0:137634ff4186 218 "movel %%a2@+, %%d1 \n\t" \
ansond 0:137634ff4186 219 "mulul %%d2, %%d4:%%d1 \n\t" \
ansond 0:137634ff4186 220 "addxl %%d3, %%d1 \n\t" \
ansond 0:137634ff4186 221 "addxl %%d0, %%d4 \n\t" \
ansond 0:137634ff4186 222 "addl %%d1, %%a3@+ \n\t" \
ansond 0:137634ff4186 223 "movel %%a2@+, %%d1 \n\t" \
ansond 0:137634ff4186 224 "mulul %%d2, %%d3:%%d1 \n\t" \
ansond 0:137634ff4186 225 "addxl %%d4, %%d1 \n\t" \
ansond 0:137634ff4186 226 "addxl %%d0, %%d3 \n\t" \
ansond 0:137634ff4186 227 "addl %%d1, %%a3@+ \n\t" \
ansond 0:137634ff4186 228 "movel %%a2@+, %%d1 \n\t" \
ansond 0:137634ff4186 229 "mulul %%d2, %%d4:%%d1 \n\t" \
ansond 0:137634ff4186 230 "addxl %%d3, %%d1 \n\t" \
ansond 0:137634ff4186 231 "addxl %%d0, %%d4 \n\t" \
ansond 0:137634ff4186 232 "addl %%d1, %%a3@+ \n\t" \
ansond 0:137634ff4186 233 "movel %%a2@+, %%d1 \n\t" \
ansond 0:137634ff4186 234 "mulul %%d2, %%d3:%%d1 \n\t" \
ansond 0:137634ff4186 235 "addxl %%d4, %%d1 \n\t" \
ansond 0:137634ff4186 236 "addxl %%d0, %%d3 \n\t" \
ansond 0:137634ff4186 237 "addl %%d1, %%a3@+ \n\t" \
ansond 0:137634ff4186 238 "movel %%a2@+, %%d1 \n\t" \
ansond 0:137634ff4186 239 "mulul %%d2, %%d4:%%d1 \n\t" \
ansond 0:137634ff4186 240 "addxl %%d3, %%d1 \n\t" \
ansond 0:137634ff4186 241 "addxl %%d0, %%d4 \n\t" \
ansond 0:137634ff4186 242 "addl %%d1, %%a3@+ \n\t" \
ansond 0:137634ff4186 243 "movel %%a2@+, %%d1 \n\t" \
ansond 0:137634ff4186 244 "mulul %%d2, %%d3:%%d1 \n\t" \
ansond 0:137634ff4186 245 "addxl %%d4, %%d1 \n\t" \
ansond 0:137634ff4186 246 "addxl %%d0, %%d3 \n\t" \
ansond 0:137634ff4186 247 "addl %%d1, %%a3@+ \n\t" \
ansond 0:137634ff4186 248 "movel %%a2@+, %%d1 \n\t" \
ansond 0:137634ff4186 249 "mulul %%d2, %%d4:%%d1 \n\t" \
ansond 0:137634ff4186 250 "addxl %%d3, %%d1 \n\t" \
ansond 0:137634ff4186 251 "addxl %%d0, %%d4 \n\t" \
ansond 0:137634ff4186 252 "addl %%d1, %%a3@+ \n\t" \
ansond 0:137634ff4186 253 "movel %%a2@+, %%d1 \n\t" \
ansond 0:137634ff4186 254 "mulul %%d2, %%d3:%%d1 \n\t" \
ansond 0:137634ff4186 255 "addxl %%d4, %%d1 \n\t" \
ansond 0:137634ff4186 256 "addxl %%d0, %%d3 \n\t" \
ansond 0:137634ff4186 257 "addl %%d1, %%a3@+ \n\t" \
ansond 0:137634ff4186 258 "addxl %%d0, %%d3 \n\t"
ansond 0:137634ff4186 259
ansond 0:137634ff4186 260 #endif /* MC68000 */
ansond 0:137634ff4186 261
ansond 0:137634ff4186 262 #if defined(__powerpc64__) || defined(__ppc64__)
ansond 0:137634ff4186 263
ansond 0:137634ff4186 264 #if defined(__MACH__) && defined(__APPLE__)
ansond 0:137634ff4186 265
ansond 0:137634ff4186 266 #define MULADDC_INIT \
ansond 0:137634ff4186 267 asm( \
ansond 0:137634ff4186 268 "ld r3, %3 \n\t" \
ansond 0:137634ff4186 269 "ld r4, %4 \n\t" \
ansond 0:137634ff4186 270 "ld r5, %5 \n\t" \
ansond 0:137634ff4186 271 "ld r6, %6 \n\t" \
ansond 0:137634ff4186 272 "addi r3, r3, -8 \n\t" \
ansond 0:137634ff4186 273 "addi r4, r4, -8 \n\t" \
ansond 0:137634ff4186 274 "addic r5, r5, 0 \n\t"
ansond 0:137634ff4186 275
ansond 0:137634ff4186 276 #define MULADDC_CORE \
ansond 0:137634ff4186 277 "ldu r7, 8(r3) \n\t" \
ansond 0:137634ff4186 278 "mulld r8, r7, r6 \n\t" \
ansond 0:137634ff4186 279 "mulhdu r9, r7, r6 \n\t" \
ansond 0:137634ff4186 280 "adde r8, r8, r5 \n\t" \
ansond 0:137634ff4186 281 "ld r7, 8(r4) \n\t" \
ansond 0:137634ff4186 282 "addze r5, r9 \n\t" \
ansond 0:137634ff4186 283 "addc r8, r8, r7 \n\t" \
ansond 0:137634ff4186 284 "stdu r8, 8(r4) \n\t"
ansond 0:137634ff4186 285
ansond 0:137634ff4186 286 #define MULADDC_STOP \
ansond 0:137634ff4186 287 "addze r5, r5 \n\t" \
ansond 0:137634ff4186 288 "addi r4, r4, 8 \n\t" \
ansond 0:137634ff4186 289 "addi r3, r3, 8 \n\t" \
ansond 0:137634ff4186 290 "std r5, %0 \n\t" \
ansond 0:137634ff4186 291 "std r4, %1 \n\t" \
ansond 0:137634ff4186 292 "std r3, %2 \n\t" \
ansond 0:137634ff4186 293 : "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 294 : "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 295 : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
ansond 0:137634ff4186 296 );
ansond 0:137634ff4186 297
ansond 0:137634ff4186 298
ansond 0:137634ff4186 299 #else /* __MACH__ && __APPLE__ */
ansond 0:137634ff4186 300
ansond 0:137634ff4186 301 #define MULADDC_INIT \
ansond 0:137634ff4186 302 asm( \
ansond 0:137634ff4186 303 "ld %%r3, %3 \n\t" \
ansond 0:137634ff4186 304 "ld %%r4, %4 \n\t" \
ansond 0:137634ff4186 305 "ld %%r5, %5 \n\t" \
ansond 0:137634ff4186 306 "ld %%r6, %6 \n\t" \
ansond 0:137634ff4186 307 "addi %%r3, %%r3, -8 \n\t" \
ansond 0:137634ff4186 308 "addi %%r4, %%r4, -8 \n\t" \
ansond 0:137634ff4186 309 "addic %%r5, %%r5, 0 \n\t"
ansond 0:137634ff4186 310
ansond 0:137634ff4186 311 #define MULADDC_CORE \
ansond 0:137634ff4186 312 "ldu %%r7, 8(%%r3) \n\t" \
ansond 0:137634ff4186 313 "mulld %%r8, %%r7, %%r6 \n\t" \
ansond 0:137634ff4186 314 "mulhdu %%r9, %%r7, %%r6 \n\t" \
ansond 0:137634ff4186 315 "adde %%r8, %%r8, %%r5 \n\t" \
ansond 0:137634ff4186 316 "ld %%r7, 8(%%r4) \n\t" \
ansond 0:137634ff4186 317 "addze %%r5, %%r9 \n\t" \
ansond 0:137634ff4186 318 "addc %%r8, %%r8, %%r7 \n\t" \
ansond 0:137634ff4186 319 "stdu %%r8, 8(%%r4) \n\t"
ansond 0:137634ff4186 320
ansond 0:137634ff4186 321 #define MULADDC_STOP \
ansond 0:137634ff4186 322 "addze %%r5, %%r5 \n\t" \
ansond 0:137634ff4186 323 "addi %%r4, %%r4, 8 \n\t" \
ansond 0:137634ff4186 324 "addi %%r3, %%r3, 8 \n\t" \
ansond 0:137634ff4186 325 "std %%r5, %0 \n\t" \
ansond 0:137634ff4186 326 "std %%r4, %1 \n\t" \
ansond 0:137634ff4186 327 "std %%r3, %2 \n\t" \
ansond 0:137634ff4186 328 : "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 329 : "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 330 : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
ansond 0:137634ff4186 331 );
ansond 0:137634ff4186 332
ansond 0:137634ff4186 333 #endif /* __MACH__ && __APPLE__ */
ansond 0:137634ff4186 334
ansond 0:137634ff4186 335 #elif defined(__powerpc__) || defined(__ppc__) /* end PPC64/begin PPC32 */
ansond 0:137634ff4186 336
ansond 0:137634ff4186 337 #if defined(__MACH__) && defined(__APPLE__)
ansond 0:137634ff4186 338
ansond 0:137634ff4186 339 #define MULADDC_INIT \
ansond 0:137634ff4186 340 asm( \
ansond 0:137634ff4186 341 "lwz r3, %3 \n\t" \
ansond 0:137634ff4186 342 "lwz r4, %4 \n\t" \
ansond 0:137634ff4186 343 "lwz r5, %5 \n\t" \
ansond 0:137634ff4186 344 "lwz r6, %6 \n\t" \
ansond 0:137634ff4186 345 "addi r3, r3, -4 \n\t" \
ansond 0:137634ff4186 346 "addi r4, r4, -4 \n\t" \
ansond 0:137634ff4186 347 "addic r5, r5, 0 \n\t"
ansond 0:137634ff4186 348
ansond 0:137634ff4186 349 #define MULADDC_CORE \
ansond 0:137634ff4186 350 "lwzu r7, 4(r3) \n\t" \
ansond 0:137634ff4186 351 "mullw r8, r7, r6 \n\t" \
ansond 0:137634ff4186 352 "mulhwu r9, r7, r6 \n\t" \
ansond 0:137634ff4186 353 "adde r8, r8, r5 \n\t" \
ansond 0:137634ff4186 354 "lwz r7, 4(r4) \n\t" \
ansond 0:137634ff4186 355 "addze r5, r9 \n\t" \
ansond 0:137634ff4186 356 "addc r8, r8, r7 \n\t" \
ansond 0:137634ff4186 357 "stwu r8, 4(r4) \n\t"
ansond 0:137634ff4186 358
ansond 0:137634ff4186 359 #define MULADDC_STOP \
ansond 0:137634ff4186 360 "addze r5, r5 \n\t" \
ansond 0:137634ff4186 361 "addi r4, r4, 4 \n\t" \
ansond 0:137634ff4186 362 "addi r3, r3, 4 \n\t" \
ansond 0:137634ff4186 363 "stw r5, %0 \n\t" \
ansond 0:137634ff4186 364 "stw r4, %1 \n\t" \
ansond 0:137634ff4186 365 "stw r3, %2 \n\t" \
ansond 0:137634ff4186 366 : "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 367 : "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 368 : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
ansond 0:137634ff4186 369 );
ansond 0:137634ff4186 370
ansond 0:137634ff4186 371 #else /* __MACH__ && __APPLE__ */
ansond 0:137634ff4186 372
ansond 0:137634ff4186 373 #define MULADDC_INIT \
ansond 0:137634ff4186 374 asm( \
ansond 0:137634ff4186 375 "lwz %%r3, %3 \n\t" \
ansond 0:137634ff4186 376 "lwz %%r4, %4 \n\t" \
ansond 0:137634ff4186 377 "lwz %%r5, %5 \n\t" \
ansond 0:137634ff4186 378 "lwz %%r6, %6 \n\t" \
ansond 0:137634ff4186 379 "addi %%r3, %%r3, -4 \n\t" \
ansond 0:137634ff4186 380 "addi %%r4, %%r4, -4 \n\t" \
ansond 0:137634ff4186 381 "addic %%r5, %%r5, 0 \n\t"
ansond 0:137634ff4186 382
ansond 0:137634ff4186 383 #define MULADDC_CORE \
ansond 0:137634ff4186 384 "lwzu %%r7, 4(%%r3) \n\t" \
ansond 0:137634ff4186 385 "mullw %%r8, %%r7, %%r6 \n\t" \
ansond 0:137634ff4186 386 "mulhwu %%r9, %%r7, %%r6 \n\t" \
ansond 0:137634ff4186 387 "adde %%r8, %%r8, %%r5 \n\t" \
ansond 0:137634ff4186 388 "lwz %%r7, 4(%%r4) \n\t" \
ansond 0:137634ff4186 389 "addze %%r5, %%r9 \n\t" \
ansond 0:137634ff4186 390 "addc %%r8, %%r8, %%r7 \n\t" \
ansond 0:137634ff4186 391 "stwu %%r8, 4(%%r4) \n\t"
ansond 0:137634ff4186 392
ansond 0:137634ff4186 393 #define MULADDC_STOP \
ansond 0:137634ff4186 394 "addze %%r5, %%r5 \n\t" \
ansond 0:137634ff4186 395 "addi %%r4, %%r4, 4 \n\t" \
ansond 0:137634ff4186 396 "addi %%r3, %%r3, 4 \n\t" \
ansond 0:137634ff4186 397 "stw %%r5, %0 \n\t" \
ansond 0:137634ff4186 398 "stw %%r4, %1 \n\t" \
ansond 0:137634ff4186 399 "stw %%r3, %2 \n\t" \
ansond 0:137634ff4186 400 : "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 401 : "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 402 : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \
ansond 0:137634ff4186 403 );
ansond 0:137634ff4186 404
ansond 0:137634ff4186 405 #endif /* __MACH__ && __APPLE__ */
ansond 0:137634ff4186 406
ansond 0:137634ff4186 407 #endif /* PPC32 */
ansond 0:137634ff4186 408
ansond 0:137634ff4186 409 /*
ansond 0:137634ff4186 410 * The Sparc64 assembly is reported to be broken.
ansond 0:137634ff4186 411 * Disable it for now, until we're able to fix it.
ansond 0:137634ff4186 412 */
ansond 0:137634ff4186 413 #if 0 && defined(__sparc__) && defined(__sparc64__)
ansond 0:137634ff4186 414
ansond 0:137634ff4186 415 #define MULADDC_INIT \
ansond 0:137634ff4186 416 asm( \
ansond 0:137634ff4186 417 "ldx %3, %%o0 \n\t" \
ansond 0:137634ff4186 418 "ldx %4, %%o1 \n\t" \
ansond 0:137634ff4186 419 "ld %5, %%o2 \n\t" \
ansond 0:137634ff4186 420 "ld %6, %%o3 \n\t"
ansond 0:137634ff4186 421
ansond 0:137634ff4186 422 #define MULADDC_CORE \
ansond 0:137634ff4186 423 "ld [%%o0], %%o4 \n\t" \
ansond 0:137634ff4186 424 "inc 4, %%o0 \n\t" \
ansond 0:137634ff4186 425 "ld [%%o1], %%o5 \n\t" \
ansond 0:137634ff4186 426 "umul %%o3, %%o4, %%o4 \n\t" \
ansond 0:137634ff4186 427 "addcc %%o4, %%o2, %%o4 \n\t" \
ansond 0:137634ff4186 428 "rd %%y, %%g1 \n\t" \
ansond 0:137634ff4186 429 "addx %%g1, 0, %%g1 \n\t" \
ansond 0:137634ff4186 430 "addcc %%o4, %%o5, %%o4 \n\t" \
ansond 0:137634ff4186 431 "st %%o4, [%%o1] \n\t" \
ansond 0:137634ff4186 432 "addx %%g1, 0, %%o2 \n\t" \
ansond 0:137634ff4186 433 "inc 4, %%o1 \n\t"
ansond 0:137634ff4186 434
ansond 0:137634ff4186 435 #define MULADDC_STOP \
ansond 0:137634ff4186 436 "st %%o2, %0 \n\t" \
ansond 0:137634ff4186 437 "stx %%o1, %1 \n\t" \
ansond 0:137634ff4186 438 "stx %%o0, %2 \n\t" \
ansond 0:137634ff4186 439 : "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 440 : "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 441 : "g1", "o0", "o1", "o2", "o3", "o4", \
ansond 0:137634ff4186 442 "o5" \
ansond 0:137634ff4186 443 );
ansond 0:137634ff4186 444 #endif /* SPARCv9 */
ansond 0:137634ff4186 445
ansond 0:137634ff4186 446 #if defined(__sparc__) && !defined(__sparc64__)
ansond 0:137634ff4186 447
ansond 0:137634ff4186 448 #define MULADDC_INIT \
ansond 0:137634ff4186 449 asm( \
ansond 0:137634ff4186 450 "ld %3, %%o0 \n\t" \
ansond 0:137634ff4186 451 "ld %4, %%o1 \n\t" \
ansond 0:137634ff4186 452 "ld %5, %%o2 \n\t" \
ansond 0:137634ff4186 453 "ld %6, %%o3 \n\t"
ansond 0:137634ff4186 454
ansond 0:137634ff4186 455 #define MULADDC_CORE \
ansond 0:137634ff4186 456 "ld [%%o0], %%o4 \n\t" \
ansond 0:137634ff4186 457 "inc 4, %%o0 \n\t" \
ansond 0:137634ff4186 458 "ld [%%o1], %%o5 \n\t" \
ansond 0:137634ff4186 459 "umul %%o3, %%o4, %%o4 \n\t" \
ansond 0:137634ff4186 460 "addcc %%o4, %%o2, %%o4 \n\t" \
ansond 0:137634ff4186 461 "rd %%y, %%g1 \n\t" \
ansond 0:137634ff4186 462 "addx %%g1, 0, %%g1 \n\t" \
ansond 0:137634ff4186 463 "addcc %%o4, %%o5, %%o4 \n\t" \
ansond 0:137634ff4186 464 "st %%o4, [%%o1] \n\t" \
ansond 0:137634ff4186 465 "addx %%g1, 0, %%o2 \n\t" \
ansond 0:137634ff4186 466 "inc 4, %%o1 \n\t"
ansond 0:137634ff4186 467
ansond 0:137634ff4186 468 #define MULADDC_STOP \
ansond 0:137634ff4186 469 "st %%o2, %0 \n\t" \
ansond 0:137634ff4186 470 "st %%o1, %1 \n\t" \
ansond 0:137634ff4186 471 "st %%o0, %2 \n\t" \
ansond 0:137634ff4186 472 : "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 473 : "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 474 : "g1", "o0", "o1", "o2", "o3", "o4", \
ansond 0:137634ff4186 475 "o5" \
ansond 0:137634ff4186 476 );
ansond 0:137634ff4186 477
ansond 0:137634ff4186 478 #endif /* SPARCv8 */
ansond 0:137634ff4186 479
ansond 0:137634ff4186 480 #if defined(__microblaze__) || defined(microblaze)
ansond 0:137634ff4186 481
ansond 0:137634ff4186 482 #define MULADDC_INIT \
ansond 0:137634ff4186 483 asm( \
ansond 0:137634ff4186 484 "lwi r3, %3 \n\t" \
ansond 0:137634ff4186 485 "lwi r4, %4 \n\t" \
ansond 0:137634ff4186 486 "lwi r5, %5 \n\t" \
ansond 0:137634ff4186 487 "lwi r6, %6 \n\t" \
ansond 0:137634ff4186 488 "andi r7, r6, 0xffff \n\t" \
ansond 0:137634ff4186 489 "bsrli r6, r6, 16 \n\t"
ansond 0:137634ff4186 490
ansond 0:137634ff4186 491 #define MULADDC_CORE \
ansond 0:137634ff4186 492 "lhui r8, r3, 0 \n\t" \
ansond 0:137634ff4186 493 "addi r3, r3, 2 \n\t" \
ansond 0:137634ff4186 494 "lhui r9, r3, 0 \n\t" \
ansond 0:137634ff4186 495 "addi r3, r3, 2 \n\t" \
ansond 0:137634ff4186 496 "mul r10, r9, r6 \n\t" \
ansond 0:137634ff4186 497 "mul r11, r8, r7 \n\t" \
ansond 0:137634ff4186 498 "mul r12, r9, r7 \n\t" \
ansond 0:137634ff4186 499 "mul r13, r8, r6 \n\t" \
ansond 0:137634ff4186 500 "bsrli r8, r10, 16 \n\t" \
ansond 0:137634ff4186 501 "bsrli r9, r11, 16 \n\t" \
ansond 0:137634ff4186 502 "add r13, r13, r8 \n\t" \
ansond 0:137634ff4186 503 "add r13, r13, r9 \n\t" \
ansond 0:137634ff4186 504 "bslli r10, r10, 16 \n\t" \
ansond 0:137634ff4186 505 "bslli r11, r11, 16 \n\t" \
ansond 0:137634ff4186 506 "add r12, r12, r10 \n\t" \
ansond 0:137634ff4186 507 "addc r13, r13, r0 \n\t" \
ansond 0:137634ff4186 508 "add r12, r12, r11 \n\t" \
ansond 0:137634ff4186 509 "addc r13, r13, r0 \n\t" \
ansond 0:137634ff4186 510 "lwi r10, r4, 0 \n\t" \
ansond 0:137634ff4186 511 "add r12, r12, r10 \n\t" \
ansond 0:137634ff4186 512 "addc r13, r13, r0 \n\t" \
ansond 0:137634ff4186 513 "add r12, r12, r5 \n\t" \
ansond 0:137634ff4186 514 "addc r5, r13, r0 \n\t" \
ansond 0:137634ff4186 515 "swi r12, r4, 0 \n\t" \
ansond 0:137634ff4186 516 "addi r4, r4, 4 \n\t"
ansond 0:137634ff4186 517
ansond 0:137634ff4186 518 #define MULADDC_STOP \
ansond 0:137634ff4186 519 "swi r5, %0 \n\t" \
ansond 0:137634ff4186 520 "swi r4, %1 \n\t" \
ansond 0:137634ff4186 521 "swi r3, %2 \n\t" \
ansond 0:137634ff4186 522 : "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 523 : "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 524 : "r3", "r4" "r5", "r6", "r7", "r8", \
ansond 0:137634ff4186 525 "r9", "r10", "r11", "r12", "r13" \
ansond 0:137634ff4186 526 );
ansond 0:137634ff4186 527
ansond 0:137634ff4186 528 #endif /* MicroBlaze */
ansond 0:137634ff4186 529
ansond 0:137634ff4186 530 #if defined(__tricore__)
ansond 0:137634ff4186 531
ansond 0:137634ff4186 532 #define MULADDC_INIT \
ansond 0:137634ff4186 533 asm( \
ansond 0:137634ff4186 534 "ld.a %%a2, %3 \n\t" \
ansond 0:137634ff4186 535 "ld.a %%a3, %4 \n\t" \
ansond 0:137634ff4186 536 "ld.w %%d4, %5 \n\t" \
ansond 0:137634ff4186 537 "ld.w %%d1, %6 \n\t" \
ansond 0:137634ff4186 538 "xor %%d5, %%d5 \n\t"
ansond 0:137634ff4186 539
ansond 0:137634ff4186 540 #define MULADDC_CORE \
ansond 0:137634ff4186 541 "ld.w %%d0, [%%a2+] \n\t" \
ansond 0:137634ff4186 542 "madd.u %%e2, %%e4, %%d0, %%d1 \n\t" \
ansond 0:137634ff4186 543 "ld.w %%d0, [%%a3] \n\t" \
ansond 0:137634ff4186 544 "addx %%d2, %%d2, %%d0 \n\t" \
ansond 0:137634ff4186 545 "addc %%d3, %%d3, 0 \n\t" \
ansond 0:137634ff4186 546 "mov %%d4, %%d3 \n\t" \
ansond 0:137634ff4186 547 "st.w [%%a3+], %%d2 \n\t"
ansond 0:137634ff4186 548
ansond 0:137634ff4186 549 #define MULADDC_STOP \
ansond 0:137634ff4186 550 "st.w %0, %%d4 \n\t" \
ansond 0:137634ff4186 551 "st.a %1, %%a3 \n\t" \
ansond 0:137634ff4186 552 "st.a %2, %%a2 \n\t" \
ansond 0:137634ff4186 553 : "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 554 : "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 555 : "d0", "d1", "e2", "d4", "a2", "a3" \
ansond 0:137634ff4186 556 );
ansond 0:137634ff4186 557
ansond 0:137634ff4186 558 #endif /* TriCore */
ansond 0:137634ff4186 559
ansond 0:137634ff4186 560 #if defined(__arm__)
ansond 0:137634ff4186 561
ansond 0:137634ff4186 562 #if defined(__thumb__) && !defined(__thumb2__)
ansond 0:137634ff4186 563
ansond 0:137634ff4186 564 #define MULADDC_INIT \
ansond 0:137634ff4186 565 asm( \
ansond 0:137634ff4186 566 "ldr r0, %3 \n\t" \
ansond 0:137634ff4186 567 "ldr r1, %4 \n\t" \
ansond 0:137634ff4186 568 "ldr r2, %5 \n\t" \
ansond 0:137634ff4186 569 "ldr r3, %6 \n\t" \
ansond 0:137634ff4186 570 "lsr r7, r3, #16 \n\t" \
ansond 0:137634ff4186 571 "mov r9, r7 \n\t" \
ansond 0:137634ff4186 572 "lsl r7, r3, #16 \n\t" \
ansond 0:137634ff4186 573 "lsr r7, r7, #16 \n\t" \
ansond 0:137634ff4186 574 "mov r8, r7 \n\t"
ansond 0:137634ff4186 575
ansond 0:137634ff4186 576 #define MULADDC_CORE \
ansond 0:137634ff4186 577 "ldmia r0!, {r6} \n\t" \
ansond 0:137634ff4186 578 "lsr r7, r6, #16 \n\t" \
ansond 0:137634ff4186 579 "lsl r6, r6, #16 \n\t" \
ansond 0:137634ff4186 580 "lsr r6, r6, #16 \n\t" \
ansond 0:137634ff4186 581 "mov r4, r8 \n\t" \
ansond 0:137634ff4186 582 "mul r4, r6 \n\t" \
ansond 0:137634ff4186 583 "mov r3, r9 \n\t" \
ansond 0:137634ff4186 584 "mul r6, r3 \n\t" \
ansond 0:137634ff4186 585 "mov r5, r9 \n\t" \
ansond 0:137634ff4186 586 "mul r5, r7 \n\t" \
ansond 0:137634ff4186 587 "mov r3, r8 \n\t" \
ansond 0:137634ff4186 588 "mul r7, r3 \n\t" \
ansond 0:137634ff4186 589 "lsr r3, r6, #16 \n\t" \
ansond 0:137634ff4186 590 "add r5, r5, r3 \n\t" \
ansond 0:137634ff4186 591 "lsr r3, r7, #16 \n\t" \
ansond 0:137634ff4186 592 "add r5, r5, r3 \n\t" \
ansond 0:137634ff4186 593 "add r4, r4, r2 \n\t" \
ansond 0:137634ff4186 594 "mov r2, #0 \n\t" \
ansond 0:137634ff4186 595 "adc r5, r2 \n\t" \
ansond 0:137634ff4186 596 "lsl r3, r6, #16 \n\t" \
ansond 0:137634ff4186 597 "add r4, r4, r3 \n\t" \
ansond 0:137634ff4186 598 "adc r5, r2 \n\t" \
ansond 0:137634ff4186 599 "lsl r3, r7, #16 \n\t" \
ansond 0:137634ff4186 600 "add r4, r4, r3 \n\t" \
ansond 0:137634ff4186 601 "adc r5, r2 \n\t" \
ansond 0:137634ff4186 602 "ldr r3, [r1] \n\t" \
ansond 0:137634ff4186 603 "add r4, r4, r3 \n\t" \
ansond 0:137634ff4186 604 "adc r2, r5 \n\t" \
ansond 0:137634ff4186 605 "stmia r1!, {r4} \n\t"
ansond 0:137634ff4186 606
ansond 0:137634ff4186 607 #define MULADDC_STOP \
ansond 0:137634ff4186 608 "str r2, %0 \n\t" \
ansond 0:137634ff4186 609 "str r1, %1 \n\t" \
ansond 0:137634ff4186 610 "str r0, %2 \n\t" \
ansond 0:137634ff4186 611 : "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 612 : "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 613 : "r0", "r1", "r2", "r3", "r4", "r5", \
ansond 0:137634ff4186 614 "r6", "r7", "r8", "r9", "cc" \
ansond 0:137634ff4186 615 );
ansond 0:137634ff4186 616
ansond 0:137634ff4186 617 #else
ansond 0:137634ff4186 618
ansond 0:137634ff4186 619 #define MULADDC_INIT \
ansond 0:137634ff4186 620 asm( \
ansond 0:137634ff4186 621 "ldr r0, %3 \n\t" \
ansond 0:137634ff4186 622 "ldr r1, %4 \n\t" \
ansond 0:137634ff4186 623 "ldr r2, %5 \n\t" \
ansond 0:137634ff4186 624 "ldr r3, %6 \n\t"
ansond 0:137634ff4186 625
ansond 0:137634ff4186 626 #define MULADDC_CORE \
ansond 0:137634ff4186 627 "ldr r4, [r0], #4 \n\t" \
ansond 0:137634ff4186 628 "mov r5, #0 \n\t" \
ansond 0:137634ff4186 629 "ldr r6, [r1] \n\t" \
ansond 0:137634ff4186 630 "umlal r2, r5, r3, r4 \n\t" \
ansond 0:137634ff4186 631 "adds r7, r6, r2 \n\t" \
ansond 0:137634ff4186 632 "adc r2, r5, #0 \n\t" \
ansond 0:137634ff4186 633 "str r7, [r1], #4 \n\t"
ansond 0:137634ff4186 634
ansond 0:137634ff4186 635 #define MULADDC_STOP \
ansond 0:137634ff4186 636 "str r2, %0 \n\t" \
ansond 0:137634ff4186 637 "str r1, %1 \n\t" \
ansond 0:137634ff4186 638 "str r0, %2 \n\t" \
ansond 0:137634ff4186 639 : "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 640 : "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 641 : "r0", "r1", "r2", "r3", "r4", "r5", \
ansond 0:137634ff4186 642 "r6", "r7", "cc" \
ansond 0:137634ff4186 643 );
ansond 0:137634ff4186 644
ansond 0:137634ff4186 645 #endif /* Thumb */
ansond 0:137634ff4186 646
ansond 0:137634ff4186 647 #endif /* ARMv3 */
ansond 0:137634ff4186 648
ansond 0:137634ff4186 649 #if defined(__alpha__)
ansond 0:137634ff4186 650
ansond 0:137634ff4186 651 #define MULADDC_INIT \
ansond 0:137634ff4186 652 asm( \
ansond 0:137634ff4186 653 "ldq $1, %3 \n\t" \
ansond 0:137634ff4186 654 "ldq $2, %4 \n\t" \
ansond 0:137634ff4186 655 "ldq $3, %5 \n\t" \
ansond 0:137634ff4186 656 "ldq $4, %6 \n\t"
ansond 0:137634ff4186 657
ansond 0:137634ff4186 658 #define MULADDC_CORE \
ansond 0:137634ff4186 659 "ldq $6, 0($1) \n\t" \
ansond 0:137634ff4186 660 "addq $1, 8, $1 \n\t" \
ansond 0:137634ff4186 661 "mulq $6, $4, $7 \n\t" \
ansond 0:137634ff4186 662 "umulh $6, $4, $6 \n\t" \
ansond 0:137634ff4186 663 "addq $7, $3, $7 \n\t" \
ansond 0:137634ff4186 664 "cmpult $7, $3, $3 \n\t" \
ansond 0:137634ff4186 665 "ldq $5, 0($2) \n\t" \
ansond 0:137634ff4186 666 "addq $7, $5, $7 \n\t" \
ansond 0:137634ff4186 667 "cmpult $7, $5, $5 \n\t" \
ansond 0:137634ff4186 668 "stq $7, 0($2) \n\t" \
ansond 0:137634ff4186 669 "addq $2, 8, $2 \n\t" \
ansond 0:137634ff4186 670 "addq $6, $3, $3 \n\t" \
ansond 0:137634ff4186 671 "addq $5, $3, $3 \n\t"
ansond 0:137634ff4186 672
ansond 0:137634ff4186 673 #define MULADDC_STOP \
ansond 0:137634ff4186 674 "stq $3, %0 \n\t" \
ansond 0:137634ff4186 675 "stq $2, %1 \n\t" \
ansond 0:137634ff4186 676 "stq $1, %2 \n\t" \
ansond 0:137634ff4186 677 : "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 678 : "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 679 : "$1", "$2", "$3", "$4", "$5", "$6", "$7" \
ansond 0:137634ff4186 680 );
ansond 0:137634ff4186 681 #endif /* Alpha */
ansond 0:137634ff4186 682
ansond 0:137634ff4186 683 #if defined(__mips__) && !defined(__mips64)
ansond 0:137634ff4186 684
ansond 0:137634ff4186 685 #define MULADDC_INIT \
ansond 0:137634ff4186 686 asm( \
ansond 0:137634ff4186 687 "lw $10, %3 \n\t" \
ansond 0:137634ff4186 688 "lw $11, %4 \n\t" \
ansond 0:137634ff4186 689 "lw $12, %5 \n\t" \
ansond 0:137634ff4186 690 "lw $13, %6 \n\t"
ansond 0:137634ff4186 691
ansond 0:137634ff4186 692 #define MULADDC_CORE \
ansond 0:137634ff4186 693 "lw $14, 0($10) \n\t" \
ansond 0:137634ff4186 694 "multu $13, $14 \n\t" \
ansond 0:137634ff4186 695 "addi $10, $10, 4 \n\t" \
ansond 0:137634ff4186 696 "mflo $14 \n\t" \
ansond 0:137634ff4186 697 "mfhi $9 \n\t" \
ansond 0:137634ff4186 698 "addu $14, $12, $14 \n\t" \
ansond 0:137634ff4186 699 "lw $15, 0($11) \n\t" \
ansond 0:137634ff4186 700 "sltu $12, $14, $12 \n\t" \
ansond 0:137634ff4186 701 "addu $15, $14, $15 \n\t" \
ansond 0:137634ff4186 702 "sltu $14, $15, $14 \n\t" \
ansond 0:137634ff4186 703 "addu $12, $12, $9 \n\t" \
ansond 0:137634ff4186 704 "sw $15, 0($11) \n\t" \
ansond 0:137634ff4186 705 "addu $12, $12, $14 \n\t" \
ansond 0:137634ff4186 706 "addi $11, $11, 4 \n\t"
ansond 0:137634ff4186 707
ansond 0:137634ff4186 708 #define MULADDC_STOP \
ansond 0:137634ff4186 709 "sw $12, %0 \n\t" \
ansond 0:137634ff4186 710 "sw $11, %1 \n\t" \
ansond 0:137634ff4186 711 "sw $10, %2 \n\t" \
ansond 0:137634ff4186 712 : "=m" (c), "=m" (d), "=m" (s) \
ansond 0:137634ff4186 713 : "m" (s), "m" (d), "m" (c), "m" (b) \
ansond 0:137634ff4186 714 : "$9", "$10", "$11", "$12", "$13", "$14", "$15" \
ansond 0:137634ff4186 715 );
ansond 0:137634ff4186 716
ansond 0:137634ff4186 717 #endif /* MIPS */
ansond 0:137634ff4186 718 #endif /* GNUC */
ansond 0:137634ff4186 719
ansond 0:137634ff4186 720 #if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
ansond 0:137634ff4186 721
ansond 0:137634ff4186 722 #define MULADDC_INIT \
ansond 0:137634ff4186 723 __asm mov esi, s \
ansond 0:137634ff4186 724 __asm mov edi, d \
ansond 0:137634ff4186 725 __asm mov ecx, c \
ansond 0:137634ff4186 726 __asm mov ebx, b
ansond 0:137634ff4186 727
ansond 0:137634ff4186 728 #define MULADDC_CORE \
ansond 0:137634ff4186 729 __asm lodsd \
ansond 0:137634ff4186 730 __asm mul ebx \
ansond 0:137634ff4186 731 __asm add eax, ecx \
ansond 0:137634ff4186 732 __asm adc edx, 0 \
ansond 0:137634ff4186 733 __asm add eax, [edi] \
ansond 0:137634ff4186 734 __asm adc edx, 0 \
ansond 0:137634ff4186 735 __asm mov ecx, edx \
ansond 0:137634ff4186 736 __asm stosd
ansond 0:137634ff4186 737
ansond 0:137634ff4186 738 #if defined(POLARSSL_HAVE_SSE2)
ansond 0:137634ff4186 739
ansond 0:137634ff4186 740 #define EMIT __asm _emit
ansond 0:137634ff4186 741
ansond 0:137634ff4186 742 #define MULADDC_HUIT \
ansond 0:137634ff4186 743 EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
ansond 0:137634ff4186 744 EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
ansond 0:137634ff4186 745 EMIT 0x0F EMIT 0x6E EMIT 0x1F \
ansond 0:137634ff4186 746 EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
ansond 0:137634ff4186 747 EMIT 0x0F EMIT 0x6E EMIT 0x16 \
ansond 0:137634ff4186 748 EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
ansond 0:137634ff4186 749 EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
ansond 0:137634ff4186 750 EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
ansond 0:137634ff4186 751 EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
ansond 0:137634ff4186 752 EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
ansond 0:137634ff4186 753 EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
ansond 0:137634ff4186 754 EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
ansond 0:137634ff4186 755 EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
ansond 0:137634ff4186 756 EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
ansond 0:137634ff4186 757 EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
ansond 0:137634ff4186 758 EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
ansond 0:137634ff4186 759 EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
ansond 0:137634ff4186 760 EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
ansond 0:137634ff4186 761 EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
ansond 0:137634ff4186 762 EMIT 0x0F EMIT 0x7E EMIT 0x0F \
ansond 0:137634ff4186 763 EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
ansond 0:137634ff4186 764 EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
ansond 0:137634ff4186 765 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
ansond 0:137634ff4186 766 EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
ansond 0:137634ff4186 767 EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
ansond 0:137634ff4186 768 EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
ansond 0:137634ff4186 769 EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
ansond 0:137634ff4186 770 EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
ansond 0:137634ff4186 771 EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
ansond 0:137634ff4186 772 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
ansond 0:137634ff4186 773 EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
ansond 0:137634ff4186 774 EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
ansond 0:137634ff4186 775 EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
ansond 0:137634ff4186 776 EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
ansond 0:137634ff4186 777 EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
ansond 0:137634ff4186 778 EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
ansond 0:137634ff4186 779 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
ansond 0:137634ff4186 780 EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
ansond 0:137634ff4186 781 EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
ansond 0:137634ff4186 782 EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
ansond 0:137634ff4186 783 EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
ansond 0:137634ff4186 784 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
ansond 0:137634ff4186 785 EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
ansond 0:137634ff4186 786 EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
ansond 0:137634ff4186 787 EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
ansond 0:137634ff4186 788 EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
ansond 0:137634ff4186 789 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
ansond 0:137634ff4186 790 EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
ansond 0:137634ff4186 791 EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
ansond 0:137634ff4186 792 EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
ansond 0:137634ff4186 793 EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
ansond 0:137634ff4186 794 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
ansond 0:137634ff4186 795 EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
ansond 0:137634ff4186 796 EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
ansond 0:137634ff4186 797 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
ansond 0:137634ff4186 798 EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
ansond 0:137634ff4186 799 EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
ansond 0:137634ff4186 800 EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
ansond 0:137634ff4186 801 EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
ansond 0:137634ff4186 802 EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
ansond 0:137634ff4186 803 EMIT 0x0F EMIT 0x7E EMIT 0xC9
ansond 0:137634ff4186 804
ansond 0:137634ff4186 805 #define MULADDC_STOP \
ansond 0:137634ff4186 806 EMIT 0x0F EMIT 0x77 \
ansond 0:137634ff4186 807 __asm mov c, ecx \
ansond 0:137634ff4186 808 __asm mov d, edi \
ansond 0:137634ff4186 809 __asm mov s, esi \
ansond 0:137634ff4186 810
ansond 0:137634ff4186 811 #else
ansond 0:137634ff4186 812
ansond 0:137634ff4186 813 #define MULADDC_STOP \
ansond 0:137634ff4186 814 __asm mov c, ecx \
ansond 0:137634ff4186 815 __asm mov d, edi \
ansond 0:137634ff4186 816 __asm mov s, esi \
ansond 0:137634ff4186 817
ansond 0:137634ff4186 818 #endif /* SSE2 */
ansond 0:137634ff4186 819 #endif /* MSVC */
ansond 0:137634ff4186 820
ansond 0:137634ff4186 821 #endif /* POLARSSL_HAVE_ASM */
ansond 0:137634ff4186 822
ansond 0:137634ff4186 823 #if !defined(MULADDC_CORE)
ansond 0:137634ff4186 824 #if defined(POLARSSL_HAVE_UDBL)
ansond 0:137634ff4186 825
ansond 0:137634ff4186 826 #define MULADDC_INIT \
ansond 0:137634ff4186 827 { \
ansond 0:137634ff4186 828 t_udbl r; \
ansond 0:137634ff4186 829 t_uint r0, r1;
ansond 0:137634ff4186 830
ansond 0:137634ff4186 831 #define MULADDC_CORE \
ansond 0:137634ff4186 832 r = *(s++) * (t_udbl) b; \
ansond 0:137634ff4186 833 r0 = (t_uint) r; \
ansond 0:137634ff4186 834 r1 = (t_uint)( r >> biL ); \
ansond 0:137634ff4186 835 r0 += c; r1 += (r0 < c); \
ansond 0:137634ff4186 836 r0 += *d; r1 += (r0 < *d); \
ansond 0:137634ff4186 837 c = r1; *(d++) = r0;
ansond 0:137634ff4186 838
ansond 0:137634ff4186 839 #define MULADDC_STOP \
ansond 0:137634ff4186 840 }
ansond 0:137634ff4186 841
ansond 0:137634ff4186 842 #else
ansond 0:137634ff4186 843 #define MULADDC_INIT \
ansond 0:137634ff4186 844 { \
ansond 0:137634ff4186 845 t_uint s0, s1, b0, b1; \
ansond 0:137634ff4186 846 t_uint r0, r1, rx, ry; \
ansond 0:137634ff4186 847 b0 = ( b << biH ) >> biH; \
ansond 0:137634ff4186 848 b1 = ( b >> biH );
ansond 0:137634ff4186 849
ansond 0:137634ff4186 850 #define MULADDC_CORE \
ansond 0:137634ff4186 851 s0 = ( *s << biH ) >> biH; \
ansond 0:137634ff4186 852 s1 = ( *s >> biH ); s++; \
ansond 0:137634ff4186 853 rx = s0 * b1; r0 = s0 * b0; \
ansond 0:137634ff4186 854 ry = s1 * b0; r1 = s1 * b1; \
ansond 0:137634ff4186 855 r1 += ( rx >> biH ); \
ansond 0:137634ff4186 856 r1 += ( ry >> biH ); \
ansond 0:137634ff4186 857 rx <<= biH; ry <<= biH; \
ansond 0:137634ff4186 858 r0 += rx; r1 += (r0 < rx); \
ansond 0:137634ff4186 859 r0 += ry; r1 += (r0 < ry); \
ansond 0:137634ff4186 860 r0 += c; r1 += (r0 < c); \
ansond 0:137634ff4186 861 r0 += *d; r1 += (r0 < *d); \
ansond 0:137634ff4186 862 c = r1; *(d++) = r0;
ansond 0:137634ff4186 863
ansond 0:137634ff4186 864 #define MULADDC_STOP \
ansond 0:137634ff4186 865 }
ansond 0:137634ff4186 866
ansond 0:137634ff4186 867 #endif /* C (generic) */
ansond 0:137634ff4186 868 #endif /* C (longlong) */
ansond 0:137634ff4186 869
ansond 0:137634ff4186 870 #endif /* bn_mul.h */
ansond 0:137634ff4186 871