diff --git a/tinycrypt/ecc.c b/tinycrypt/ecc.c index 40256dc31..edb6e051d 100644 --- a/tinycrypt/ecc.c +++ b/tinycrypt/ecc.c @@ -387,6 +387,68 @@ __asm uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left, POP {r4-r8,pc} #endif } +#elif defined MBEDTLS_HAVE_ASM && defined __GNUC__ && defined __arm__ +uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left, + const uECC_word_t *right) +{ +#if NUM_ECC_WORDS != 8 +#error adjust ARM assembly to handle NUM_ECC_WORDS != 8 +#endif + register uECC_word_t *r0 asm ("r0") = result; + register const uECC_word_t *r1 asm ("r1") = left; + register const uECC_word_t *r2 asm ("r2") = right; + asm volatile ( +#if defined __thumb__ && !defined __thumb2__ + ".syntax unified \n\t" + "LDMIA r1!,{r3,r4} \n\t" + "LDMIA r2!,{r5,r6} \n\t" + "SUBS r3,r5 \n\t" + "SBCS r4,r6 \n\t" + "STMIA r0!,{r3,r4} \n\t" + "LDMIA r1!,{r3,r4} \n\t" + "LDMIA r2!,{r5,r6} \n\t" + "SBCS r3,r5 \n\t" + "SBCS r4,r6 \n\t" + "STMIA r0!,{r3,r4} \n\t" + "LDMIA r1!,{r3,r4} \n\t" + "LDMIA r2!,{r5,r6} \n\t" + "SBCS r3,r5 \n\t" + "SBCS r4,r6 \n\t" + "STMIA r0!,{r3,r4} \n\t" + "LDMIA r1!,{r3,r4} \n\t" + "LDMIA r2!,{r5,r6} \n\t" + "SBCS r3,r5 \n\t" + "SBCS r4,r6 \n\t" + "STMIA r0!,{r3,r4} \n\t" + "SBCS r0,r0 \n\t" // r0 := r0 - r0 - borrow = -borrow + "RSBS r0,r0,#0 \n\t" // r0 := borrow + : "+r" (r0), "+r" (r1), "+r" (r2) + : + : "r3", "r4", "r5", "r6", "cc", "memory" +#else + "LDMIA r1!,{r3-r6} \n\t" + "LDMIA r2!,{r7,r8,r12,lr} \n\t" + "SUBS r3,r7 \n\t" + "SBCS r4,r8 \n\t" + "SBCS r5,r12 \n\t" + "SBCS r6,lr \n\t" + "STMIA r0!,{r3-r6} \n\t" + "LDMIA r1!,{r3-r6} \n\t" + "LDMIA r2!,{r7,r8,r12,lr} \n\t" + "SBCS r3,r7 \n\t" + "SBCS r4,r8 \n\t" + "SBCS r5,r12 \n\t" + "SBCS r6,lr \n\t" + "STMIA r0!,{r3-r6} \n\t" + "SBCS r0,r0 \n\t" // r0 := r0 - r0 - borrow = -borrow + "RSBS r0,r0,#0 \n\t" // r0 := borrow + : "+r" (r0), "+r" (r1), "+r" (r2) + : + : "r3", "r4", "r5", "r6", "r7", "r8", "r12", "lr", "cc", "memory" +#endif + ); + return (uECC_word_t) r0; +} #else uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left, const uECC_word_t *right) @@ -461,6 +523,66 @@ static __asm uECC_word_t uECC_vli_add(uECC_word_t *result, const uECC_word_t *le POP {r4-r8,pc} #endif } +#elif defined MBEDTLS_HAVE_ASM && defined __GNUC__ && defined __arm__ +static uECC_word_t uECC_vli_add(uECC_word_t *result, const uECC_word_t *left, + const uECC_word_t *right) +{ + register uECC_word_t *r0 asm ("r0") = result; + register const uECC_word_t *r1 asm ("r1") = left; + register const uECC_word_t *r2 asm ("r2") = right; + + asm volatile ( +#if defined __thumb__ && !defined __thumb2__ + ".syntax unified \n\t" + "LDMIA r1!,{r3,r4} \n\t" + "LDMIA r2!,{r5,r6} \n\t" + "ADDS r3,r5 \n\t" + "ADCS r4,r6 \n\t" + "STMIA r0!,{r3,r4} \n\t" + "LDMIA r1!,{r3,r4} \n\t" + "LDMIA r2!,{r5,r6} \n\t" + "ADCS r3,r5 \n\t" + "ADCS r4,r6 \n\t" + "STMIA r0!,{r3,r4} \n\t" + "LDMIA r1!,{r3,r4} \n\t" + "LDMIA r2!,{r5,r6} \n\t" + "ADCS r3,r5 \n\t" + "ADCS r4,r6 \n\t" + "STMIA r0!,{r3,r4} \n\t" + "LDMIA r1!,{r3,r4} \n\t" + "LDMIA r2!,{r5,r6} \n\t" + "ADCS r3,r5 \n\t" + "ADCS r4,r6 \n\t" + "STMIA r0!,{r3,r4} \n\t" + "MOVS r0,#0 \n\t" // does not affect C flag + "ADCS r0,r0 \n\t" // r0 := 0 + 0 + C = carry + : "+r" (r0), "+r" (r1), "+r" (r2) + : + : "r3", "r4", "r5", "r6", "cc", "memory" +#else + "LDMIA r1!,{r3-r6} \n\t" + "LDMIA r2!,{r7,r8,r12,lr} \n\t" + "ADDS r3,r7 \n\t" + "ADCS r4,r8 \n\t" + "ADCS r5,r12 \n\t" + "ADCS r6,lr \n\t" + "STMIA r0!,{r3-r6} \n\t" + "LDMIA r1!,{r3-r6} \n\t" + "LDMIA r2!,{r7,r8,r12,lr} \n\t" + "ADCS r3,r7 \n\t" + "ADCS r4,r8 \n\t" + "ADCS r5,r12 \n\t" + "ADCS r6,lr \n\t" + "STMIA r0!,{r3-r6} \n\t" + "MOVS r0,#0 \n\t" // does not affect C flag + "ADCS r0,r0 \n\t" // r0 := 0 + 0 + C = carry + : "+r" (r0), "+r" (r1), "+r" (r2) + : + : "r3", "r4", "r5", "r6", "r7", "r8", "r12", "lr", "cc", "memory" +#endif + ); + return (uECC_word_t) r0; +} #else static uECC_word_t uECC_vli_add(uECC_word_t *result, const uECC_word_t *left, const uECC_word_t *right)