aboutsummaryrefslogtreecommitdiff
path: root/src/libmp/386/mpvecadd.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmp/386/mpvecadd.s')
-rw-r--r--src/libmp/386/mpvecadd.s73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/libmp/386/mpvecadd.s b/src/libmp/386/mpvecadd.s
new file mode 100644
index 00000000..1f23dcd7
--- /dev/null
+++ b/src/libmp/386/mpvecadd.s
@@ -0,0 +1,73 @@
+/*
+ * mpvecadd(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *sum)
+ *
+ * sum[0:alen] = a[0:alen-1] + b[0:blen-1]
+ *
+ * prereq: alen >= blen, sum has room for alen+1 digits
+ */
+
+.text
+
+.p2align 2,0x90
+.globl mpvecadd
+ .type mpvecadd, @function
+mpvecadd:
+ /* Prelude */
+ pushl %ebp
+ movl %ebx, -4(%esp) /* save on stack */
+ movl %esi, -8(%esp)
+ movl %edi, -12(%esp)
+
+ movl 12(%esp), %edx /* alen */
+ movl 20(%esp), %ecx /* blen */
+ movl 8(%esp), %esi /* a */
+ movl 16(%esp), %ebx /* b */
+ subl %ecx, %edx
+ movl 24(%esp), %edi /* sum */
+ xorl %ebp, %ebp /* this also sets carry to 0 */
+
+ /* skip addition if b is zero */
+ testl %ecx,%ecx
+ je _add1
+
+ /* sum[0:blen-1],carry = a[0:blen-1] + b[0:blen-1] */
+_addloop1:
+ movl (%esi, %ebp, 4), %eax
+ adcl (%ebx, %ebp, 4), %eax
+ movl %eax, (%edi, %ebp, 4)
+ incl %ebp
+ loop _addloop1
+
+_add1:
+ /* jump if alen > blen */
+ incl %edx
+ movl %edx, %ecx
+ loop _addloop2
+
+ /* sum[alen] = carry */
+_addend:
+ jb _addcarry
+ movl $0, (%edi, %ebp, 4)
+ jmp done
+
+_addcarry:
+ movl $1, (%edi, %ebp, 4)
+ jmp done
+
+ /* sum[blen:alen-1],carry = a[blen:alen-1] + 0 */
+_addloop2:
+ movl (%esi, %ebp, 4),%eax
+ adcl $0, %eax
+ movl %eax, (%edi, %ebp, 4)
+ incl %ebp
+ loop _addloop2
+ jmp _addend
+
+done:
+ /* Postlude */
+ movl -4(%esp), %ebx /* restore from stack */
+ movl -8(%esp), %esi
+ movl -12(%esp), %edi
+ movl %esp, %ebp
+ leave
+ ret