diff --git a/README.md b/README.md index 8d1f4c4..8402e88 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ See uECC.h for documentation for each function. * Should compile with any C/C++ compiler that supports stdint.h (this includes Visual Studio 2013). * If you want to change the defaults for `uECC_CURVE` and `uECC_ASM`, you must change them in your Makefile or similar so that uECC.c is compiled with the desired values (ie, compile uECC.c with `-DuECC_CURVE=uECC_secp256r1` or whatever). * When compiling for a Thumb-1 platform with inline assembly enabled (ie, `uECC_ASM` is defined to `uECC_asm_small` or `uECC_asm_fast`), you must use the `-fomit-frame-pointer` GCC option (this is enabled by default when compiling with `-O1` or higher). + * When compiling for an ARM/Thumb-2 platform with fast inline assembly enabled (ie, `uECC_ASM` is defined to `uECC_asm_fast`), you must use the `-fomit-frame-pointer` GCC option (this is enabled by default when compiling with `-O1` or higher). * When compiling for AVR with inline assembly enabled, you must have optimizations enabled (compile with `-O1` or higher). * When building for Windows, you will need to link in the `advapi32.lib` system library. diff --git a/asm_arm.inc b/asm_arm.inc index ed306bb..9792407 100644 --- a/asm_arm.inc +++ b/asm_arm.inc @@ -1,3 +1,1480 @@ +#define DEC_5 4 +#define DEC_6 5 +#define DEC_8 7 + +#define DEC(N) uECC_CONCAT(DEC_, N) + +#define REPEAT_1(stuff) stuff +#define REPEAT_2(stuff) REPEAT_1(stuff) stuff +#define REPEAT_3(stuff) REPEAT_2(stuff) stuff +#define REPEAT_4(stuff) REPEAT_3(stuff) stuff +#define REPEAT_5(stuff) REPEAT_4(stuff) stuff +#define REPEAT_6(stuff) REPEAT_5(stuff) stuff +#define REPEAT_7(stuff) REPEAT_6(stuff) stuff +#define REPEAT_8(stuff) REPEAT_7(stuff) stuff + +#define REPEAT(N, stuff) uECC_CONCAT(REPEAT_, N)(stuff) + +#define STR2(thing) #thing +#define STR(thing) STR2(thing) + +#if (uECC_ASM == uECC_asm_fast) + +static uint32_t vli_add(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right) +{ + uint32_t l_carry = 0; + uint32_t l_left; + uint32_t l_right; + + __asm__ volatile ( + ".syntax unified \n\t" + "ldmia %[lptr]!, {%[left]} \n\t" /* Load left word. */ + "ldmia %[rptr]!, {%[right]} \n\t" /* Load right word. */ + "adds %[left], %[right] \n\t" /* Add first word. */ + "stmia %[dptr]!, {%[left]} \n\t" /* Store result word. */ + + /* Now we just do the remaining words with the carry bit (using ADC) */ + REPEAT(DEC(uECC_WORDS), "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "adcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t") + + "adcs %[carry], %[carry] \n\t" /* Store carry bit in l_carry. */ + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + #if (uECC_PLATFORM == uECC_arm_thumb) + : [dptr] "+l" (p_result), [lptr] "+l" (p_left), [rptr] "+l" (p_right), + [carry] "+l" (l_carry), [left] "=l" (l_left), [right] "=l" (l_right) + #else + : [dptr] "+r" (p_result), [lptr] "+r" (p_left), [rptr] "+r" (p_right), + [carry] "+r" (l_carry), [left] "=r" (l_left), [right] "=r" (l_right) + #endif + : + : "cc", "memory" + ); + return l_carry; +} +#define asm_add 1 + +static uint32_t vli_sub(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right) +{ + uint32_t l_carry = 0; + uint32_t l_left; + uint32_t l_right; + + __asm__ volatile ( + ".syntax unified \n\t" + "ldmia %[lptr]!, {%[left]} \n\t" /* Load left word. */ + "ldmia %[rptr]!, {%[right]} \n\t" /* Load right word. */ + "subs %[left], %[right] \n\t" /* Subtract. */ + "stmia %[dptr]!, {%[left]} \n\t" /* Store result word. */ + + /* Now we just do the remaining words with the carry bit (using SBC) */ + REPEAT(DEC(uECC_WORDS), "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "sbcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t") + + "adcs %[carry], %[carry] \n\t" /* Store carry bit in l_carry. */ + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + #if (uECC_PLATFORM == uECC_arm_thumb) + : [dptr] "+l" (p_result), [lptr] "+l" (p_left), [rptr] "+l" (p_right), + [carry] "+l" (l_carry), [left] "=l" (l_left), [right] "=l" (l_right) + #else + : [dptr] "+r" (p_result), [lptr] "+r" (p_left), [rptr] "+r" (p_right), + [carry] "+r" (l_carry), [left] "=r" (l_left), [right] "=r" (l_right) + #endif + : + : "cc", "memory" + ); + return !l_carry; // note that on ARM, carry flag set means "no borrow" when subtracting (for some reason...) +} +#define asm_sub 1 + +#if (uECC_PLATFORM != uECC_arm_thumb) +#if (uECC_WORDS == 5) +static void vli_mult(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right) +{ + register uint32_t *r0 __asm__("r0") = p_result; + register uint32_t *r1 __asm__("r1") = p_left; + register uint32_t *r2 __asm__("r2") = p_right; + + __asm__ volatile ( + ".syntax unified \n\t" + "add r0, 12 \n\t" + "add r2, 12 \n\t" + "ldmia r1!, {r3,r4} \n\t" + "ldmia r2!, {r6,r7} \n\t" + + "umull r11, r12, r3, r6 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r9, r3, r7 \n\t" + "adds r12, r11 \n\t" + "adc r9, #0 \n\t" + "umull r11, r14, r4, r6 \n\t" + "adds r12, r11 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "umull r12, r14, r4, r7 \n\t" + "adds r9, r12 \n\t" + "adc r10, r14 \n\t" + "stmia r0!, {r9, r10} \n\t" + + "sub r0, 28 \n\t" + "sub r2, 20 \n\t" + "ldmia r2!, {r6,r7,r8} \n\t" + "ldmia r1!, {r5} \n\t" + + "umull r11, r12, r3, r6 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r9, r3, r7 \n\t" + "adds r12, r11 \n\t" + "adc r9, #0 \n\t" + "umull r11, r14, r4, r6 \n\t" + "adds r12, r11 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r11, #0 \n\t" + "umull r12, r14, r3, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r5, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "ldmia r1!, {r3} \n\t" + "mov r12, #0 \n\t" + "umull r14, r9, r4, r8 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r5, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r3, r6 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r10, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "ldmia r1!, {r4} \n\t" + "mov r14, #0 \n\t" + "umull r9, r10, r5, r8 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r3, r7 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r4, r6 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "ldr r9, [r0] \n\t" + "adds r11, r9 \n\t" + "adcs r12, #0 \n\t" + "adc r14, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "ldmia r2!, {r6} \n\t" + "mov r9, #0 \n\t" + "umull r10, r11, r5, r6 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r3, r8 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r4, r7 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "ldr r10, [r0] \n\t" + "adds r12, r10 \n\t" + "adcs r14, #0 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "ldmia r2!, {r7} \n\t" + "mov r10, #0 \n\t" + "umull r11, r12, r5, r7 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r3, r6 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r4, r8 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "ldr r11, [r0] \n\t" + "adds r14, r11 \n\t" + "adcs r9, #0 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r14} \n\t" + + "mov r11, #0 \n\t" + "umull r12, r14, r3, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "umull r14, r9, r4, r7 \n\t" + "adds r10, r14 \n\t" + "adc r11, r9 \n\t" + "stmia r0!, {r10, r11} \n\t" + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + : "+r" (r0), "+r" (r1), "+r" (r2) + : + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_mult 1 +#endif /* (uECC_WORDS == 5) */ + +#if (uECC_WORDS == 6) +static void vli_mult(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right) +{ + register uint32_t *r0 __asm__("r0") = p_result; + register uint32_t *r1 __asm__("r1") = p_left; + register uint32_t *r2 __asm__("r2") = p_right; + + __asm__ volatile ( + ".syntax unified \n\t" + "add r0, 12 \n\t" + "add r2, 12 \n\t" + "ldmia r1!, {r3,r4,r5} \n\t" + "ldmia r2!, {r6,r7,r8} \n\t" + + "umull r11, r12, r3, r6 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r9, r3, r7 \n\t" + "adds r12, r11 \n\t" + "adc r9, #0 \n\t" + "umull r11, r14, r4, r6 \n\t" + "adds r12, r11 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r11, #0 \n\t" + "umull r12, r14, r3, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r5, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "mov r12, #0 \n\t" + "umull r14, r9, r4, r8 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r5, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "umull r9, r10, r5, r8 \n\t" + "adds r11, r9 \n\t" + "adc r12, r10 \n\t" + "stmia r0!, {r11, r12} \n\t" + + "sub r0, 36 \n\t" + "sub r2, 24 \n\t" + "ldmia r2!, {r6,r7,r8} \n\t" + + "umull r11, r12, r3, r6 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r9, r3, r7 \n\t" + "adds r12, r11 \n\t" + "adc r9, #0 \n\t" + "umull r11, r14, r4, r6 \n\t" + "adds r12, r11 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r11, #0 \n\t" + "umull r12, r14, r3, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r5, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "ldmia r1!, {r3} \n\t" + "mov r12, #0 \n\t" + "umull r14, r9, r4, r8 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r5, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r3, r6 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r10, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "ldmia r1!, {r4} \n\t" + "mov r14, #0 \n\t" + "umull r9, r10, r5, r8 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r3, r7 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r4, r6 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "ldr r9, [r0] \n\t" + "adds r11, r9 \n\t" + "adcs r12, #0 \n\t" + "adc r14, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "ldmia r1!, {r5} \n\t" + "mov r9, #0 \n\t" + "umull r10, r11, r3, r8 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r4, r7 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r5, r6 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "ldr r10, [r0] \n\t" + "adds r12, r10 \n\t" + "adcs r14, #0 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "ldmia r2!, {r6} \n\t" + "mov r10, #0 \n\t" + "umull r11, r12, r3, r6 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r4, r8 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r5, r7 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "ldr r11, [r0] \n\t" + "adds r14, r11 \n\t" + "adcs r9, #0 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r14} \n\t" + + "ldmia r2!, {r7} \n\t" + "mov r11, #0 \n\t" + "umull r12, r14, r3, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r5, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "ldr r12, [r0] \n\t" + "adds r9, r12 \n\t" + "adcs r10, #0 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "ldmia r2!, {r8} \n\t" + "mov r12, #0 \n\t" + "umull r14, r9, r3, r8 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r4, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r5, r6 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r10, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "mov r14, #0 \n\t" + "umull r9, r10, r4, r8 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r5, r7 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "umull r10, r11, r5, r8 \n\t" + "adds r12, r10 \n\t" + "adc r14, r11 \n\t" + "stmia r0!, {r12, r14} \n\t" + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + : "+r" (r0), "+r" (r1), "+r" (r2) + : + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_mult 1 +#endif /* (uECC_WORDS == 6) */ + +#if (uECC_WORDS == 8) +static void vli_mult(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right) +{ + register uint32_t *r0 __asm__("r0") = p_result; + register uint32_t *r1 __asm__("r1") = p_left; + register uint32_t *r2 __asm__("r2") = p_right; + + __asm__ volatile ( + ".syntax unified \n\t" + "add r0, 24 \n\t" + "add r2, 24 \n\t" + "ldmia r1!, {r3,r4} \n\t" + "ldmia r2!, {r6,r7} \n\t" + + "umull r11, r12, r3, r6 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r9, r3, r7 \n\t" + "adds r12, r11 \n\t" + "adc r9, #0 \n\t" + "umull r11, r14, r4, r6 \n\t" + "adds r12, r11 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "umull r12, r14, r4, r7 \n\t" + "adds r9, r12 \n\t" + "adc r10, r14 \n\t" + "stmia r0!, {r9, r10} \n\t" + + "sub r0, 28 \n\t" + "sub r2, 20 \n\t" + "ldmia r2!, {r6,r7,r8} \n\t" + "ldmia r1!, {r5} \n\t" + + "umull r11, r12, r3, r6 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r9, r3, r7 \n\t" + "adds r12, r11 \n\t" + "adc r9, #0 \n\t" + "umull r11, r14, r4, r6 \n\t" + "adds r12, r11 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r11, #0 \n\t" + "umull r12, r14, r3, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r5, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "ldmia r1!, {r3} \n\t" + "mov r12, #0 \n\t" + "umull r14, r9, r4, r8 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r5, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r3, r6 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r10, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "ldmia r1!, {r4} \n\t" + "mov r14, #0 \n\t" + "umull r9, r10, r5, r8 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r3, r7 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r4, r6 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "ldr r9, [r0] \n\t" + "adds r11, r9 \n\t" + "adcs r12, #0 \n\t" + "adc r14, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "ldmia r2!, {r6} \n\t" + "mov r9, #0 \n\t" + "umull r10, r11, r5, r6 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r3, r8 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r4, r7 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "ldr r10, [r0] \n\t" + "adds r12, r10 \n\t" + "adcs r14, #0 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "ldmia r2!, {r7} \n\t" + "mov r10, #0 \n\t" + "umull r11, r12, r5, r7 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r3, r6 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r4, r8 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "ldr r11, [r0] \n\t" + "adds r14, r11 \n\t" + "adcs r9, #0 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r14} \n\t" + + "mov r11, #0 \n\t" + "umull r12, r14, r3, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "umull r14, r9, r4, r7 \n\t" + "adds r10, r14 \n\t" + "adc r11, r9 \n\t" + "stmia r0!, {r10, r11} \n\t" + + "sub r0, 52 \n\t" + "sub r1, 20 \n\t" + "sub r2, 32 \n\t" + "ldmia r1!, {r3,r4,r5} \n\t" + "ldmia r2!, {r6,r7,r8} \n\t" + + "umull r11, r12, r3, r6 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r9, r3, r7 \n\t" + "adds r12, r11 \n\t" + "adc r9, #0 \n\t" + "umull r11, r14, r4, r6 \n\t" + "adds r12, r11 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r11, #0 \n\t" + "umull r12, r14, r3, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r5, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "ldmia r1!, {r3} \n\t" + "mov r12, #0 \n\t" + "umull r14, r9, r4, r8 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r5, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r3, r6 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r10, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "ldmia r1!, {r4} \n\t" + "mov r14, #0 \n\t" + "umull r9, r10, r5, r8 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r3, r7 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r4, r6 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "ldr r9, [r0] \n\t" + "adds r11, r9 \n\t" + "adcs r12, #0 \n\t" + "adc r14, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "ldmia r1!, {r5} \n\t" + "mov r9, #0 \n\t" + "umull r10, r11, r3, r8 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r4, r7 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r5, r6 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "ldr r10, [r0] \n\t" + "adds r12, r10 \n\t" + "adcs r14, #0 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "ldmia r1!, {r3} \n\t" + "mov r10, #0 \n\t" + "umull r11, r12, r4, r8 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r5, r7 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r3, r6 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "ldr r11, [r0] \n\t" + "adds r14, r11 \n\t" + "adcs r9, #0 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r14} \n\t" + + "ldmia r1!, {r4} \n\t" + "mov r11, #0 \n\t" + "umull r12, r14, r5, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r3, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "ldr r12, [r0] \n\t" + "adds r9, r12 \n\t" + "adcs r10, #0 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "ldmia r2!, {r6} \n\t" + "mov r12, #0 \n\t" + "umull r14, r9, r5, r6 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r3, r8 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r4, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r10, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "ldmia r2!, {r7} \n\t" + "mov r14, #0 \n\t" + "umull r9, r10, r5, r7 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r3, r6 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r4, r8 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "ldr r9, [r0] \n\t" + "adds r11, r9 \n\t" + "adcs r12, #0 \n\t" + "adc r14, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "ldmia r2!, {r8} \n\t" + "mov r9, #0 \n\t" + "umull r10, r11, r5, r8 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r3, r7 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r4, r6 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "ldr r10, [r0] \n\t" + "adds r12, r10 \n\t" + "adcs r14, #0 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "ldmia r2!, {r6} \n\t" + "mov r10, #0 \n\t" + "umull r11, r12, r5, r6 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r3, r8 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r4, r7 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "ldr r11, [r0] \n\t" + "adds r14, r11 \n\t" + "adcs r9, #0 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r14} \n\t" + + "ldmia r2!, {r7} \n\t" + "mov r11, #0 \n\t" + "umull r12, r14, r5, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r3, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "ldr r12, [r0] \n\t" + "adds r9, r12 \n\t" + "adcs r10, #0 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "mov r12, #0 \n\t" + "umull r14, r9, r3, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r4, r6 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "umull r9, r10, r4, r7 \n\t" + "adds r11, r9 \n\t" + "adc r12, r10 \n\t" + "stmia r0!, {r11, r12} \n\t" + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + : "+r" (r0), "+r" (r1), "+r" (r2) + : + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_mult 1 +#endif /* (uECC_WORDS == 8) */ + +#if (uECC_WORDS == 5) +static void vli_square(uint32_t *p_result, uint32_t *p_left) +{ + register uint32_t *r0 __asm__("r0") = p_result; + register uint32_t *r1 __asm__("r1") = p_left; + + __asm__ volatile ( + ".syntax unified \n\t" + "ldmia r1!, {r2,r3,r4,r5,r6} \n\t" + + "umull r11, r12, r2, r2 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r9, #0 \n\t" + "umull r10, r11, r2, r3 \n\t" + "adds r12, r10 \n\t" + "adcs r8, r11, #0 \n\t" + "adc r9, #0 \n\t" + "adds r12, r10 \n\t" + "adcs r8, r11 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r12, r2, r4 \n\t" + "adds r11, r11 \n\t" + "adcs r12, r12 \n\t" + "adc r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r3, r3 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r2, r5 \n\t" + "umull r1, r14, r3, r4 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r14 \n\t" + "adc r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r10, #0 \n\t" + "umull r8, r9, r2, r6 \n\t" + "umull r1, r14, r3, r5 \n\t" + "adds r8, r1 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r9, r9 \n\t" + "adc r10, r10 \n\t" + "umull r1, r14, r4, r4 \n\t" + "adds r8, r1 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r3, r6 \n\t" + "umull r1, r14, r4, r5 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r14 \n\t" + "adc r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r8, #0 \n\t" + "umull r1, r10, r4, r6 \n\t" + "adds r1, r1 \n\t" + "adcs r10, r10 \n\t" + "adc r8, #0 \n\t" + "adds r11, r1 \n\t" + "adcs r12, r10 \n\t" + "adc r8, #0 \n\t" + "umull r1, r10, r5, r5 \n\t" + "adds r11, r1 \n\t" + "adcs r12, r10 \n\t" + "adc r8, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r11, #0 \n\t" + "umull r1, r10, r5, r6 \n\t" + "adds r1, r1 \n\t" + "adcs r10, r10 \n\t" + "adc r11, #0 \n\t" + "adds r12, r1 \n\t" + "adcs r8, r10 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "umull r1, r10, r6, r6 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r10 \n\t" + "stmia r0!, {r8, r11} \n\t" + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + : "+r" (r0), "+r" (r1) + : + : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_square 1 +#endif /* (uECC_WORDS == 5) */ + +#if (uECC_WORDS == 6) +static void vli_square(uint32_t *p_result, uint32_t *p_left) +{ + register uint32_t *r0 __asm__("r0") = p_result; + register uint32_t *r1 __asm__("r1") = p_left; + + __asm__ volatile ( + ".syntax unified \n\t" + "ldmia r1!, {r2,r3,r4,r5,r6,r7} \n\t" + + "umull r11, r12, r2, r2 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r9, #0 \n\t" + "umull r10, r11, r2, r3 \n\t" + "adds r12, r10 \n\t" + "adcs r8, r11, #0 \n\t" + "adc r9, #0 \n\t" + "adds r12, r10 \n\t" + "adcs r8, r11 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r12, r2, r4 \n\t" + "adds r11, r11 \n\t" + "adcs r12, r12 \n\t" + "adc r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r3, r3 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r2, r5 \n\t" + "umull r1, r14, r3, r4 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r14 \n\t" + "adc r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r10, #0 \n\t" + "umull r8, r9, r2, r6 \n\t" + "umull r1, r14, r3, r5 \n\t" + "adds r8, r1 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r9, r9 \n\t" + "adc r10, r10 \n\t" + "umull r1, r14, r4, r4 \n\t" + "adds r8, r1 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r2, r7 \n\t" + "umull r1, r14, r3, r6 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r14 \n\t" + "adc r12, #0 \n\t" + "umull r1, r14, r4, r5 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r14 \n\t" + "adc r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r10, #0 \n\t" + "umull r8, r9, r3, r7 \n\t" + "umull r1, r14, r4, r6 \n\t" + "adds r8, r1 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r9, r9 \n\t" + "adc r10, r10 \n\t" + "umull r1, r14, r5, r5 \n\t" + "adds r8, r1 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r4, r7 \n\t" + "umull r1, r14, r5, r6 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r14 \n\t" + "adc r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r8, #0 \n\t" + "umull r1, r10, r5, r7 \n\t" + "adds r1, r1 \n\t" + "adcs r10, r10 \n\t" + "adc r8, #0 \n\t" + "adds r11, r1 \n\t" + "adcs r12, r10 \n\t" + "adc r8, #0 \n\t" + "umull r1, r10, r6, r6 \n\t" + "adds r11, r1 \n\t" + "adcs r12, r10 \n\t" + "adc r8, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r11, #0 \n\t" + "umull r1, r10, r6, r7 \n\t" + "adds r1, r1 \n\t" + "adcs r10, r10 \n\t" + "adc r11, #0 \n\t" + "adds r12, r1 \n\t" + "adcs r8, r10 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "umull r1, r10, r7, r7 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r10 \n\t" + "stmia r0!, {r8, r11} \n\t" + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + : "+r" (r0), "+r" (r1) + : + : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_square 1 +#endif /* (uECC_WORDS == 6) */ + +#if (uECC_WORDS == 8) +static void vli_square(uint32_t *p_result, uint32_t *p_left) +{ + register uint32_t *r0 __asm__("r0") = p_result; + register uint32_t *r1 __asm__("r1") = p_left; + + __asm__ volatile ( + ".syntax unified \n\t" + "ldmia r1!, {r2, r3} \n\t" + "add r1, 16 \n\t" + "ldmia r1!, {r5, r6} \n\t" + "add r0, 24 \n\t" + + "umull r8, r9, r2, r5 \n\t" + "stmia r0!, {r8} \n\t" + + "umull r12, r10, r2, r6 \n\t" + "adds r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "umull r8, r9, r3, r6 \n\t" + "adds r10, r8 \n\t" + "adc r11, r9, #0 \n\t" + "stmia r0!, {r10, r11} \n\t" + + "sub r0, 40 \n\t" + "sub r1, 32 \n\t" + "ldmia r1!, {r2,r3,r4,r5,r6,r7} \n\t" + + "umull r11, r12, r2, r2 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r9, #0 \n\t" + "umull r10, r11, r2, r3 \n\t" + "adds r12, r10 \n\t" + "adcs r8, r11, #0 \n\t" + "adc r9, #0 \n\t" + "adds r12, r10 \n\t" + "adcs r8, r11 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r12, r2, r4 \n\t" + "adds r11, r11 \n\t" + "adcs r12, r12 \n\t" + "adc r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r3, r3 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r2, r5 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r3, r4 \n\t" + "cmp r14, r11 \n\t" + "adchi r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r10, #0 \n\t" + "umull r8, r9, r2, r6 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r3, r5 \n\t" + "cmp r14, r9 \n\t" + "adchi r10, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r9, r9 \n\t" + "adc r10, r10 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r4, r4 \n\t" + "cmp r14, r9 \n\t" + "adchi r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r2, r7 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r3, r6 \n\t" + "cmp r14, r11 \n\t" + "adchi r12, #0 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r4, r5 \n\t" + "cmp r14, r11 \n\t" + "adchi r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "ldmia r1!, {r2} \n\t" + "mov r10, #0 \n\t" + "umull r8, r9, r3, r7 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r4, r6 \n\t" + "cmp r14, r9 \n\t" + "adchi r10, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r8, r14 \n\t" + "adcs r9, #0 \n\t" + "adc r10, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r9, r9 \n\t" + "adc r10, r10 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r5, r5 \n\t" + "cmp r14, r9 \n\t" + "adchi r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r3, r2 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r4, r7 \n\t" + "cmp r14, r11 \n\t" + "adchi r12, #0 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r5, r6 \n\t" + "cmp r14, r11 \n\t" + "adchi r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r8, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "ldmia r1!, {r3} \n\t" + "mov r10, #0 \n\t" + "umull r8, r9, r4, r2 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r5, r7 \n\t" + "cmp r14, r9 \n\t" + "adchi r10, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r8, r14 \n\t" + "adcs r9, #0 \n\t" + "adc r10, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r9, r9 \n\t" + "adc r10, r10 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r6, r6 \n\t" + "cmp r14, r9 \n\t" + "adchi r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r4, r3 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r5, r2 \n\t" + "cmp r14, r11 \n\t" + "adchi r12, #0 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r6, r7 \n\t" + "cmp r14, r11 \n\t" + "adchi r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r8, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r10, #0 \n\t" + "umull r8, r9, r5, r3 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r6, r2 \n\t" + "cmp r14, r9 \n\t" + "adchi r10, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r9, r9 \n\t" + "adc r10, r10 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r7, r7 \n\t" + "cmp r14, r9 \n\t" + "adchi r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r6, r3 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r7, r2 \n\t" + "cmp r14, r11 \n\t" + "adchi r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r8, #0 \n\t" + "umull r1, r10, r7, r3 \n\t" + "adds r1, r1 \n\t" + "adcs r10, r10 \n\t" + "adc r8, #0 \n\t" + "adds r11, r1 \n\t" + "adcs r12, r10 \n\t" + "adc r8, #0 \n\t" + "umull r1, r10, r2, r2 \n\t" + "adds r11, r1 \n\t" + "adcs r12, r10 \n\t" + "adc r8, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r11, #0 \n\t" + "umull r1, r10, r2, r3 \n\t" + "adds r1, r1 \n\t" + "adcs r10, r10 \n\t" + "adc r11, #0 \n\t" + "adds r12, r1 \n\t" + "adcs r8, r10 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "umull r1, r10, r3, r3 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r10 \n\t" + "stmia r0!, {r8, r11} \n\t" + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + : "+r" (r0), "+r" (r1) + : + : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_square 1 +#endif /* (uECC_WORDS == 8) */ + +#endif /* (uECC_PLATFORM != uECC_arm_thumb) */ + +#endif /* (uECC_ASM == uECC_asm_fast) */ + #if !asm_add static uint32_t vli_add(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right) { diff --git a/emk_project.py b/emk_project.py index e401e84..940fadc 100644 --- a/emk_project.py +++ b/emk_project.py @@ -97,6 +97,8 @@ def setup_linux_rpi(): c.compiler = c.GccCompiler("/Volumes/xtools/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-") link.linker = link.GccLinker("/Volumes/xtools/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-") + + c.flags.extend(["-fomit-frame-pointer"]) setup_build_dir() diff --git a/scripts/mult_arm.py b/scripts/mult_arm.py new file mode 100755 index 0000000..344fd3e --- /dev/null +++ b/scripts/mult_arm.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python + +import sys + +if len(sys.argv) < 2: + print "Provide the integer size in 32-bit words" + sys.exit(1) + +size = int(sys.argv[1]) + +full_rows = size // 3 +init_size = size % 3 + +if init_size == 0: + full_rows = full_rows - 1 + init_size = 3 + +def emit(line, *args): + s = '"' + line + r' \n\t"' + print s % args + +rx = [3, 4, 5] +ry = [6, 7, 8] + +#### set up registers +emit("add r0, %s", (size - init_size) * 4) # move z +emit("add r2, %s", (size - init_size) * 4) # move y + +emit("ldmia r1!, {%s}", ",".join(["r%s" % (rx[i]) for i in xrange(init_size)])) +emit("ldmia r2!, {%s}", ",".join(["r%s" % (ry[i]) for i in xrange(init_size)])) + +print "" +if init_size == 1: + emit("umull r9, r10, r3, r6") + emit("stmia r0!, {r9, r10}") +else: + #### first two multiplications of initial block + emit("umull r11, r12, r3, r6") + emit("stmia r0!, {r11}") + print "" + emit("mov r10, #0") + emit("umull r11, r9, r3, r7") + emit("adds r12, r11") + emit("adc r9, #0") + emit("umull r11, r14, r4, r6") + emit("adds r12, r11") + emit("adcs r9, r14") + emit("adc r10, #0") + emit("stmia r0!, {r12}") + print "" + + #### rest of initial block, with moving accumulator registers + acc = [9, 10, 11, 12, 14] + if init_size == 3: + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 3): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], rx[i], ry[2 - i]) + emit("adds r%s, r%s", acc[0], acc[3]) + emit("adcs r%s, r%s", acc[1], acc[4]) + emit("adc r%s, #0", acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 2): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], rx[i + 1], ry[2 - i]) + emit("adds r%s, r%s", acc[0], acc[3]) + emit("adcs r%s, r%s", acc[1], acc[4]) + emit("adc r%s, #0", acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], rx[init_size-1], ry[init_size-1]) + emit("adds r%s, r%s", acc[0], acc[3]) + emit("adc r%s, r%s", acc[1], acc[4]) + emit("stmia r0!, {r%s}", acc[0]) + emit("stmia r0!, {r%s}", acc[1]) +print "" + +#### reset y and z pointers +emit("sub r0, %s", (2 * init_size + 3) * 4) +emit("sub r2, %s", (init_size + 3) * 4) + +#### load y registers +emit("ldmia r2!, {%s}", ",".join(["r%s" % (ry[i]) for i in xrange(3)])) + +#### load additional x registers +if init_size != 3: + emit("ldmia r1!, {%s}", ",".join(["r%s" % (rx[i]) for i in xrange(init_size, 3)])) +print "" + +prev_size = init_size +for row in xrange(full_rows): + emit("umull r11, r12, r3, r6") + emit("stmia r0!, {r11}") + print "" + emit("mov r10, #0") + emit("umull r11, r9, r3, r7") + emit("adds r12, r11") + emit("adc r9, #0") + emit("umull r11, r14, r4, r6") + emit("adds r12, r11") + emit("adcs r9, r14") + emit("adc r10, #0") + emit("stmia r0!, {r12}") + print "" + + acc = [9, 10, 11, 12, 14] + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 3): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], rx[i], ry[2 - i]) + emit("adds r%s, r%s", acc[0], acc[3]) + emit("adcs r%s, r%s", acc[1], acc[4]) + emit("adc r%s, #0", acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + #### now we need to start shifting x and loading from z + x_regs = [3, 4, 5] + for r in xrange(0, prev_size): + x_regs = x_regs[1:] + x_regs[:1] + emit("ldmia r1!, {r%s}", x_regs[2]) + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 3): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], x_regs[i], ry[2 - i]) + emit("adds r%s, r%s", acc[0], acc[3]) + emit("adcs r%s, r%s", acc[1], acc[4]) + emit("adc r%s, #0", acc[2]) + emit("ldr r%s, [r0]", acc[3]) # load stored value from initial block, and add to accumulator + emit("adds r%s, r%s", acc[0], acc[3]) + emit("adcs r%s, #0", acc[1]) + emit("adc r%s, #0", acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + # done shifting x, start shifting y + y_regs = [6, 7, 8] + for r in xrange(0, prev_size): + y_regs = y_regs[1:] + y_regs[:1] + emit("ldmia r2!, {r%s}", y_regs[2]) + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 3): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], x_regs[i], y_regs[2 - i]) + emit("adds r%s, r%s", acc[0], acc[3]) + emit("adcs r%s, r%s", acc[1], acc[4]) + emit("adc r%s, #0", acc[2]) + emit("ldr r%s, [r0]", acc[3]) # load stored value from initial block, and add to accumulator + emit("adds r%s, r%s", acc[0], acc[3]) + emit("adcs r%s, #0", acc[1]) + emit("adc r%s, #0", acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + # done both shifts, do remaining corner + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 2): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], x_regs[i + 1], y_regs[2 - i]) + emit("adds r%s, r%s", acc[0], acc[3]) + emit("adcs r%s, r%s", acc[1], acc[4]) + emit("adc r%s, #0", acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], x_regs[2], y_regs[2]) + emit("adds r%s, r%s", acc[0], acc[3]) + emit("adc r%s, r%s", acc[1], acc[4]) + emit("stmia r0!, {r%s}", acc[0]) + emit("stmia r0!, {r%s}", acc[1]) + print "" + + prev_size = prev_size + 3 + if row < full_rows - 1: + #### reset x, y and z pointers + emit("sub r0, %s", (2 * prev_size + 3) * 4) + emit("sub r1, %s", prev_size * 4) + emit("sub r2, %s", (prev_size + 3) * 4) + + #### load x and y registers + emit("ldmia r1!, {%s}", ",".join(["r%s" % (rx[i]) for i in xrange(3)])) + emit("ldmia r2!, {%s}", ",".join(["r%s" % (ry[i]) for i in xrange(3)])) + + print "" diff --git a/scripts/square_arm.py b/scripts/square_arm.py new file mode 100755 index 0000000..cb6fa26 --- /dev/null +++ b/scripts/square_arm.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python + +import sys + +if len(sys.argv) < 2: + print "Provide the integer size in 32-bit words" + sys.exit(1) + +size = int(sys.argv[1]) + +if size > 6 and size != 8: + print "This script doesn't work with integer size %s due to laziness" % (size) + sys.exit(1) + +init_size = 0 +if size > 6: + init_size = size - 6 + +def emit(line, *args): + s = '"' + line + r' \n\t"' + print s % args + +def mulacc(acc, r1, r2): + if size <= 6: + emit("umull r1, r14, r%s, r%s", r1, r2) + emit("adds r%s, r1", acc[0]) + emit("adcs r%s, r14", acc[1]) + emit("adc r%s, #0", acc[2]) + else: + emit("mov r14, r%s", acc[1]) + emit("umlal r%s, r%s, r%s, r%s", acc[0], acc[1], r1, r2) + emit("cmp r14, r%s", acc[1]) + emit("adchi r%s, #0", acc[2]) + +r = [2, 3, 4, 5, 6, 7] + +s = size - init_size + +# Note that I just implemented the init_size = 2 case directly +if init_size > 0: + emit("ldmia r1!, {r2, r3}") + emit("add r1, %s", (size - init_size * 2) * 4) + emit("ldmia r1!, {r5, r6}") + + emit("add r0, %s", (size - init_size) * 4) + print "" + + emit("umull r8, r9, r2, r5") + emit("stmia r0!, {r8}") + print "" + + emit("umull r12, r10, r2, r6") + emit("adds r9, r12") + emit("adc r10, #0") + emit("stmia r0!, {r9}") + print "" + + emit("umull r8, r9, r3, r6") + emit("adds r10, r8") + emit("adc r11, r9, #0") + emit("stmia r0!, {r10, r11}") + print "" + + emit("sub r0, %s", (size + init_size) * 4) + emit("sub r1, %s", (size) * 4) + +# load input words +emit("ldmia r1!, {%s}", ",".join(["r%s" % (r[i]) for i in xrange(s)])) +print "" + +emit("umull r11, r12, r2, r2") +emit("stmia r0!, {r11}") +print "" +emit("mov r9, #0") +emit("umull r10, r11, r2, r3") +emit("adds r12, r10") +emit("adcs r8, r11, #0") +emit("adc r9, #0") +emit("adds r12, r10") +emit("adcs r8, r11") +emit("adc r9, #0") +emit("stmia r0!, {r12}") +print "" +emit("mov r10, #0") +emit("umull r11, r12, r2, r4") +emit("adds r11, r11") +emit("adcs r12, r12") +emit("adc r10, #0") +emit("adds r8, r11") +emit("adcs r9, r12") +emit("adc r10, #0") +emit("umull r11, r12, r3, r3") +emit("adds r8, r11") +emit("adcs r9, r12") +emit("adc r10, #0") +emit("stmia r0!, {r8}") +print "" + +acc = [8, 9, 10] +old_acc = [11, 12] +for i in xrange(3, s): + emit("mov r%s, #0", old_acc[1]) + tmp = [acc[1], acc[2]] + acc = [acc[0], old_acc[0], old_acc[1]] + old_acc = tmp + + # gather non-equal words + emit("umull r%s, r%s, r%s, r%s", acc[0], acc[1], r[0], r[i]) + for j in xrange(1, (i+1)//2): + mulacc(acc, r[j], r[i-j]) + # multiply by 2 + emit("adds r%s, r%s", acc[0], acc[0]) + emit("adcs r%s, r%s", acc[1], acc[1]) + emit("adc r%s, r%s", acc[2], acc[2]) + + # add equal word (if any) + if ((i+1) % 2) != 0: + mulacc(acc, r[i//2], r[i//2]) + + # add old accumulator + emit("adds r%s, r%s", acc[0], old_acc[0]) + emit("adcs r%s, r%s", acc[1], old_acc[1]) + emit("adc r%s, #0", acc[2]) + + # store + emit("stmia r0!, {r%s}", acc[0]) + print "" + +regs = list(r) +for i in xrange(init_size): + regs = regs[1:] + regs[:1] + emit("ldmia r1!, {r%s}", regs[5]) + + for limit in [4, 5]: + emit("mov r%s, #0", old_acc[1]) + tmp = [acc[1], acc[2]] + acc = [acc[0], old_acc[0], old_acc[1]] + old_acc = tmp + + # gather non-equal words + emit("umull r%s, r%s, r%s, r%s", acc[0], acc[1], regs[0], regs[limit]) + for j in xrange(1, (limit+1)//2): + mulacc(acc, regs[j], regs[limit-j]) + + emit("ldr r14, [r0]") # load stored value from initial block, and add to accumulator + emit("adds r%s, r14", acc[0]) + emit("adcs r%s, #0", acc[1]) + emit("adc r%s, #0", acc[2]) + + # multiply by 2 + emit("adds r%s, r%s", acc[0], acc[0]) + emit("adcs r%s, r%s", acc[1], acc[1]) + emit("adc r%s, r%s", acc[2], acc[2]) + + # add equal word + if limit == 4: + mulacc(acc, regs[2], regs[2]) + + # add old accumulator + emit("adds r%s, r%s", acc[0], old_acc[0]) + emit("adcs r%s, r%s", acc[1], old_acc[1]) + emit("adc r%s, #0", acc[2]) + + # store + emit("stmia r0!, {r%s}", acc[0]) + print "" + +for i in xrange(1, s-3): + emit("mov r%s, #0", old_acc[1]) + tmp = [acc[1], acc[2]] + acc = [acc[0], old_acc[0], old_acc[1]] + old_acc = tmp + + # gather non-equal words + emit("umull r%s, r%s, r%s, r%s", acc[0], acc[1], regs[i], regs[s - 1]) + for j in xrange(1, (s-i)//2): + mulacc(acc, regs[i+j], regs[s - 1 - j]) + + # multiply by 2 + emit("adds r%s, r%s", acc[0], acc[0]) + emit("adcs r%s, r%s", acc[1], acc[1]) + emit("adc r%s, r%s", acc[2], acc[2]) + + # add equal word (if any) + if ((s-i) % 2) != 0: + mulacc(acc, regs[i + (s-i)//2], regs[i + (s-i)//2]) + + # add old accumulator + emit("adds r%s, r%s", acc[0], old_acc[0]) + emit("adcs r%s, r%s", acc[1], old_acc[1]) + emit("adc r%s, #0", acc[2]) + + # store + emit("stmia r0!, {r%s}", acc[0]) + print "" + +acc = acc[1:] + acc[:1] +emit("mov r%s, #0", acc[2]) +emit("umull r1, r%s, r%s, r%s", old_acc[1], regs[s - 3], regs[s - 1]) +emit("adds r1, r1") +emit("adcs r%s, r%s", old_acc[1], old_acc[1]) +emit("adc r%s, #0", acc[2]) +emit("adds r%s, r1", acc[0]) +emit("adcs r%s, r%s", acc[1], old_acc[1]) +emit("adc r%s, #0", acc[2]) +emit("umull r1, r%s, r%s, r%s", old_acc[1], regs[s - 2], regs[s - 2]) +emit("adds r%s, r1", acc[0]) +emit("adcs r%s, r%s", acc[1], old_acc[1]) +emit("adc r%s, #0", acc[2]) +emit("stmia r0!, {r%s}", acc[0]) +print "" + +acc = acc[1:] + acc[:1] +emit("mov r%s, #0", acc[2]) +emit("umull r1, r%s, r%s, r%s", old_acc[1], regs[s - 2], regs[s - 1]) +emit("adds r1, r1") +emit("adcs r%s, r%s", old_acc[1], old_acc[1]) +emit("adc r%s, #0", acc[2]) +emit("adds r%s, r1", acc[0]) +emit("adcs r%s, r%s", acc[1], old_acc[1]) +emit("adc r%s, #0", acc[2]) +emit("stmia r0!, {r%s}", acc[0]) +print "" + +acc = acc[1:] + acc[:1] +emit("umull r1, r%s, r%s, r%s", old_acc[1], regs[s - 1], regs[s - 1]) +emit("adds r%s, r1", acc[0]) +emit("adcs r%s, r%s", acc[1], old_acc[1]) +emit("stmia r0!, {r%s}", acc[0]) +emit("stmia r0!, {r%s}", acc[1])