]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bigint/bigint_add_u.S
5c758993b36db6e506a2352bdea718f771022b1b
[avr-crypto-lib.git] / bigint / 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
30 /*
31  param dest: r24:r25
32  param a:    r22:r23
33  param b:    r20:r21
34 */
35 LEN_A_0 = 22
36 LEN_A_1 = 23
37 LEN_B_0 = 20
38 LEN_B_1 = 21
39
40
41 .global bigint_add_u
42 bigint_add_u:
43         push_range 28, 29
44         push_range 24, 25
45         movw r26, r24 ; X is our destination pointer
46         movw r30, r22 ; Z = a
47         movw r28, r20 ; Y = b
48         ldd LEN_A_0, Z+0
49         ldd LEN_A_1, Z+1
50         ldd LEN_B_0, Y+0
51         ldd LEN_B_1, Y+1
52         cp LEN_A_0, LEN_B_0
53         cpc LEN_A_1, LEN_B_1
54         brsh 3f
55         movw r18, LEN_A_0    ; swap length values
56         movw LEN_A_0, LEN_B_0
57         movw LEN_B_0, r18
58         movw r18, r30        ; swap pointers
59         movw r30, r28
60         movw r28, r18
61 3:      ; now a is the longer integer
62     movw r24, LEN_A_0
63     adiw r24, 0
64     brne 4f
65     st X+, r1 ; store length
66     st X+, r1
67     st X+, r1 ; store 0 in info field
68     rjmp 9f
69 4:
70     adiw r24, 1
71     st X+, r24 ; store length
72     st X+, r25
73     st X+, r1 ; store 0 in info field
74     ld r18, X+
75     ld r19, X+
76     movw r26, r18
77     adiw r30, 3 ; adjust pointers to point at wordv
78     ld r18, Z+
79     ld r19, Z+
80     movw r30, r18
81     adiw r28, 3
82     ld r18, Y+
83     ld r19, Y+
84     movw r28, r18
85
86     sub LEN_A_0, LEN_B_0
87     sbc LEN_A_1, LEN_B_1
88     movw r24, LEN_B_0
89     clr r0
90     adiw r24, 0
91     breq 6f
92     clc
93 5:
94     ld r0, Z+
95     ld r1, Y+
96     adc r0, r1
97     st X+, r0
98     dec r24
99         brne 5b
100         rol r0 ; store carry bit
101         tst r25
102         breq 6f
103         dec r25
104         dec r24
105         ror r0 ; write carry back
106         rjmp 5b
107 6: /* the main part is done */
108         movw r24, LEN_A_0
109         clr r1
110         adiw r24, 0
111         breq 8f
112 62:
113         ror r0 ; write carry back
114 7:
115     ld r0, Z+
116     adc r0, r1
117     st X+, r0
118     dec r24
119         brne 7b
120         rol r0 ; store carry bit
121         tst r25
122         breq 8f
123         dec r25
124         dec r24
125         rjmp 62b
126 8:
127         ror r0
128         clr r0
129         rol r0
130         st X+, r0
131 9:
132         pop_range 24, 25
133         pop_range 28, 29
134         rjmp bigint_adjust
135
136