mirror of
https://github.com/kmackay/micro-ecc.git
synced 2026-08-03 17:07:46 +00:00
Add fast ARM asm.
This commit is contained in:
@@ -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.
|
||||
|
||||
|
||||
+1477
File diff suppressed because it is too large
Load Diff
@@ -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()
|
||||
|
||||
|
||||
Executable
+188
@@ -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 ""
|
||||
Executable
+230
@@ -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])
|
||||
Reference in New Issue
Block a user