mpi_arm.c (3926B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 /* This inlined version is for 32-bit ARM platform only */ 6 7 #if !defined(__arm__) 8 #error "This is for ARM only" 9 #endif 10 11 /* 16-bit thumb doesn't work inlined assember version */ 12 #if (!defined(__thumb__) || defined(__thumb2__)) && !defined(__ARM_ARCH_3__) 13 14 #include "mpi-priv.h" 15 16 #ifdef MP_ASSEMBLY_MULTIPLY 17 void 18 s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) 19 { 20 __asm__ __volatile__( 21 "mov r5, #0\n" 22 #ifdef __thumb2__ 23 "cbz %1, 2f\n" 24 #else 25 "cmp %1, r5\n" /* r5 is 0 now */ 26 "beq 2f\n" 27 #endif 28 29 "1:\n" 30 "mov r4, #0\n" 31 "ldr r6, [%0], #4\n" 32 "umlal r5, r4, r6, %3\n" 33 "str r5, [%2], #4\n" 34 "mov r5, r4\n" 35 36 "subs %1, #1\n" 37 "bne 1b\n" 38 39 "2:\n" 40 "str r5, [%2]\n" 41 : "+r"(a), "+l"(a_len), "+r"(c) 42 : "r"(b) 43 : "memory", "cc", "%r4", "%r5", "%r6"); 44 } 45 46 void 47 s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) 48 { 49 __asm__ __volatile__( 50 "mov r5, #0\n" 51 #ifdef __thumb2__ 52 "cbz %1, 2f\n" 53 #else 54 "cmp %1, r5\n" /* r5 is 0 now */ 55 "beq 2f\n" 56 #endif 57 58 "1:\n" 59 "mov r4, #0\n" 60 "ldr r6, [%2]\n" 61 "adds r5, r6\n" 62 "adc r4, r4, #0\n" 63 64 "ldr r6, [%0], #4\n" 65 "umlal r5, r4, r6, %3\n" 66 "str r5, [%2], #4\n" 67 "mov r5, r4\n" 68 69 "subs %1, #1\n" 70 "bne 1b\n" 71 72 "2:\n" 73 "str r5, [%2]\n" 74 : "+r"(a), "+l"(a_len), "+r"(c) 75 : "r"(b) 76 : "memory", "cc", "%r4", "%r5", "%r6"); 77 } 78 79 void 80 s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) 81 { 82 if (!a_len) 83 return; 84 85 __asm__ __volatile__( 86 "mov r5, #0\n" 87 88 "1:\n" 89 "mov r4, #0\n" 90 "ldr r6, [%2]\n" 91 "adds r5, r6\n" 92 "adc r4, r4, #0\n" 93 "ldr r6, [%0], #4\n" 94 "umlal r5, r4, r6, %3\n" 95 "str r5, [%2], #4\n" 96 "mov r5, r4\n" 97 98 "subs %1, #1\n" 99 "bne 1b\n" 100 101 #ifdef __thumb2__ 102 "cbz r4, 3f\n" 103 #else 104 "cmp r4, #0\n" 105 "beq 3f\n" 106 #endif 107 108 "2:\n" 109 "mov r4, #0\n" 110 "ldr r6, [%2]\n" 111 "adds r5, r6\n" 112 "adc r4, r4, #0\n" 113 "str r5, [%2], #4\n" 114 "movs r5, r4\n" 115 "bne 2b\n" 116 117 "3:\n" 118 : "+r"(a), "+l"(a_len), "+r"(c) 119 : "r"(b) 120 : "memory", "cc", "%r4", "%r5", "%r6"); 121 } 122 #endif 123 124 #ifdef MP_ASSEMBLY_SQUARE 125 void 126 s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps) 127 { 128 if (!a_len) 129 return; 130 131 __asm__ __volatile__( 132 "mov r3, #0\n" 133 134 "1:\n" 135 "mov r4, #0\n" 136 "ldr r6, [%0], #4\n" 137 "ldr r5, [%2]\n" 138 "adds r3, r5\n" 139 "adc r4, r4, #0\n" 140 "umlal r3, r4, r6, r6\n" /* w = r3:r4 */ 141 "str r3, [%2], #4\n" 142 143 "ldr r5, [%2]\n" 144 "adds r3, r4, r5\n" 145 "mov r4, #0\n" 146 "adc r4, r4, #0\n" 147 "str r3, [%2], #4\n" 148 "mov r3, r4\n" 149 150 "subs %1, #1\n" 151 "bne 1b\n" 152 153 #ifdef __thumb2__ 154 "cbz r3, 3f\n" 155 #else 156 "cmp r3, #0\n" 157 "beq 3f\n" 158 #endif 159 160 "2:\n" 161 "mov r4, #0\n" 162 "ldr r5, [%2]\n" 163 "adds r3, r5\n" 164 "adc r4, r4, #0\n" 165 "str r3, [%2], #4\n" 166 "movs r3, r4\n" 167 "bne 2b\n" 168 169 "3:" 170 : "+r"(pa), "+r"(a_len), "+r"(ps) 171 : 172 : "memory", "cc", "%r3", "%r4", "%r5", "%r6"); 173 } 174 #endif 175 #endif