]> git.cryptolib.org Git - avr-crypto-lib.git/blob - dsa/bigint_add_u.S
7c34f1a8705655a07773453ad3f0d0ab82cb96f7
[avr-crypto-lib.git] / dsa / bigint_add_u.S
1 /* bigint_add_u.S */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
5
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 /**
21  * \file     bigint_add_u.S
22  * \email    daniel.otte@rub.de
23  * \author   Daniel Otte
24  * \date     2010-03-01
25  * \license  GPLv3 or later
26  *
27  */
28
29 #include "avr-asm-macros.S"
30
31 /*
32  param dest: r24:r25
33  param a:    r22:r23
34  param b:    r20:r21
35 */
36 LEN_A_0 = 22
37 LEN_A_1 = 23
38 LEN_B_0 = 20
39 LEN_B_1 = 21
40
41
42 .global bigint_add_u
43 bigint_add_u:
44         push_range 28, 29
45         push_range 24, 25
46         movw r26, r24 ; X is our destination pointer
47         movw r30, r22 ; Z = a
48         movw r28, r20 ; Y = b
49         ldd LEN_A_0, Z+0
50         ldd LEN_A_1, Z+1
51         ldd LEN_B_0, Y+0
52         ldd LEN_B_1, Y+1
53         cp LEN_A_0, LEN_B_0
54         cpc LEN_A_1, LEN_B_1
55         brsh 3f
56         movw r18, LEN_A_0    ; swap length values
57         movw LEN_A_0, LEN_B_0
58         movw LEN_B_0, r18
59         movw r18, r30        ; swap pointers
60         movw r30, r28
61         movw r28, r18
62 3:      ; now a is the longer integer
63     movw r24, LEN_A_0
64     adiw r24, 0
65     brne 4f
66     st X+, r1 ; store length
67     st X+, r1
68     st X+, r1 ; store 0 in info field
69     rjmp 9f
70 4:
71     adiw r24, 1
72     st X+, r24 ; store length
73     st X+, r25
74     st X+, r1 ; store 0 in info field
75     ld r18, X+
76     ld r19, X+
77     movw r26, r18
78     adiw r30, 3 ; adjust pointers to point at wordv
79     ld r18, Z+
80     ld r19, Z+
81     movw r30, r18
82     adiw r28, 3
83     ld r18, Y+
84     ld r19, Y+
85     movw r28, r18
86
87     sub LEN_A_0, LEN_B_0
88     sbc LEN_A_1, LEN_B_1
89     movw r24, LEN_B_0
90     clr r0
91     adiw r24, 0
92     breq 6f
93     clc
94 5:
95     ld r0, Z+
96     ld r1, Y+
97     adc r0, r1
98     st X+, r0
99     dec r24
100         brne 5b
101         rol r0 ; store carry bit
102         tst r25
103         breq 6f
104         dec r25
105         dec r24
106         ror r0 ; write carry back
107         rjmp 5b
108 6: /* the main part is done */
109         movw r24, LEN_A_0
110         clr r1
111         adiw r24, 0
112         breq 8f
113 62:
114         ror r0 ; write carry back
115 7:
116     ld r0, Z+
117     adc r0, r1
118     st X+, r0
119     dec r24
120         brne 7b
121         rol r0 ; store carry bit
122         tst r25
123         breq 8f
124         dec r25
125         dec r24
126         rjmp 62b
127 8:
128         ror r0
129         clr r0
130         rol r0
131         st X+, r0
132 9:
133         pop_range 24, 25
134         pop_range 28, 29
135         jmp bigint_adjust
136
137