From 4aea62569be7060bd3be42f31cc47b2f13ab9a42 Mon Sep 17 00:00:00 2001
From: Kevin Bracey <kevin.bracey@arm.com>
Date: Fri, 9 Oct 2020 12:54:28 +0300
Subject: [PATCH] More GCC assembly

Signed-off-by: Kevin Bracey <kevin.bracey@arm.com>
---
 tinycrypt/ecc.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 122 insertions(+)

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)