circom/ports/c/buildasm/add.asm.ejs
ports/c/buildasm/add.asm.ejsRaw
1<% function addS1S2() { %>
2 xor rdx, rdx
3 mov edx, eax
4 add edx, ecx
5 jo add_manageOverflow ; rsi already is the 64bits result
6
7 mov [rdi], rdx ; not necessary to adjust so just save and return
8 ret
9
10add_manageOverflow: ; Do the operation in 64 bits
11 push rsi
12 movsx rsi, eax
13 movsx rdx, ecx
14 add rsi, rdx
15 call rawCopyS2L
16 pop rsi
17 ret
18<% } %>
19
20
21
22<% function addL1S2() { %>
23 add rsi, 8
24 movsx rdx, ecx
25 add rdi, 8
26 cmp rdx, 0
27 <% const rawAddLabel = global.tmpLabel() %>
28 jns <%= rawAddLabel %>
29 neg rdx
30 call rawSubLS
31 sub rdi, 8
32 sub rsi, 8
33 ret
34<%= rawAddLabel %>:
35 call rawAddLS
36 sub rdi, 8
37 sub rsi, 8
38 ret
39
40<% } %>
41
42<% function addS1L2() { %>
43 lea rsi, [rdx + 8]
44 movsx rdx, eax
45 add rdi, 8
46 cmp rdx, 0
47 <% const rawAddLabel = global.tmpLabel() %>
48 jns <%= rawAddLabel %>
49 neg rdx
50 call rawSubLS
51 sub rdi, 8
52 sub rsi, 8
53 ret
54<%= rawAddLabel %>:
55 call rawAddLS
56 sub rdi, 8
57 sub rsi, 8
58 ret
59<% } %>
60
61<% function addL1L2() { %>
62 add rdi, 8
63 add rsi, 8
64 add rdx, 8
65 call rawAddLL
66 sub rdi, 8
67 sub rsi, 8
68 ret
69<% } %>
70
71;;;;;;;;;;;;;;;;;;;;;;
72; add
73;;;;;;;;;;;;;;;;;;;;;;
74; Adds two elements of any kind
75; Params:
76; rsi <= Pointer to element 1
77; rdx <= Pointer to element 2
78; rdi <= Pointer to result
79; Modified Registers:
80; r8, r9, 10, r11, rax, rcx
81;;;;;;;;;;;;;;;;;;;;;;
82<%=name%>_add:
83 mov rax, [rsi]
84 mov rcx, [rdx]
85 bt rax, 63 ; Check if is short first operand
86 jc add_l1
87 bt rcx, 63 ; Check if is short second operand
88 jc add_s1l2
89
90add_s1s2: ; Both operands are short
91<%= addS1S2() %>
92add_l1:
93 bt rcx, 63 ; Check if is short second operand
94 jc add_l1l2
95
96;;;;;;;;
97add_l1s2:
98 bt rax, 62 ; check if montgomery first
99 jc add_l1ms2
100add_l1ns2:
101<%= global.setTypeDest("0x80"); %>
102<%= addL1S2(); %>
103
104add_l1ms2:
105 bt rcx, 62 ; check if montgomery second
106 jc add_l1ms2m
107add_l1ms2n:
108<%= global.setTypeDest("0xC0"); %>
109<%= global.toMont_b() %>
110<%= addL1L2() %>
111
112add_l1ms2m:
113<%= global.setTypeDest("0xC0"); %>
114<%= addL1L2() %>
115
116
117;;;;;;;;
118add_s1l2:
119 bt rcx, 62 ; check if montgomery second
120 jc add_s1l2m
121add_s1l2n:
122<%= global.setTypeDest("0x80"); %>
123<%= addS1L2(); %>
124
125add_s1l2m:
126 bt rax, 62 ; check if montgomery first
127 jc add_s1ml2m
128add_s1nl2m:
129<%= global.setTypeDest("0xC0"); %>
130<%= global.toMont_a() %>
131<%= addL1L2() %>
132
133add_s1ml2m:
134<%= global.setTypeDest("0xC0"); %>
135<%= addL1L2() %>
136
137;;;;
138add_l1l2:
139 bt rax, 62 ; check if montgomery first
140 jc add_l1ml2
141add_l1nl2:
142 bt rcx, 62 ; check if montgomery second
143 jc add_l1nl2m
144add_l1nl2n:
145<%= global.setTypeDest("0x80"); %>
146<%= addL1L2() %>
147
148add_l1nl2m:
149<%= global.setTypeDest("0xC0"); %>
150<%= global.toMont_a(); %>
151<%= addL1L2() %>
152
153add_l1ml2:
154 bt rcx, 62 ; check if montgomery seconf
155 jc add_l1ml2m
156add_l1ml2n:
157<%= global.setTypeDest("0xC0"); %>
158<%= global.toMont_b(); %>
159<%= addL1L2() %>
160
161add_l1ml2m:
162<%= global.setTypeDest("0xC0"); %>
163<%= addL1L2() %>
164
165
166
167;;;;;;;;;;;;;;;;;;;;;;
168; rawAddLL
169;;;;;;;;;;;;;;;;;;;;;;
170; Adds two elements of type long
171; Params:
172; rsi <= Pointer to the long data of element 1
173; rdx <= Pointer to the long data of element 2
174; rdi <= Pointer to the long data of result
175; Modified Registers:
176; rax
177;;;;;;;;;;;;;;;;;;;;;;
178rawAddLL:
179 ; Add component by component with carry
180<% for (let i=0; i<n64; i++) { %>
181 mov rax, [rsi + <%=i*8%>]
182 <%= i==0 ? "add" : "adc" %> rax, [rdx + <%=i*8%>]
183 mov [rdi + <%=i*8%>], rax
184<% } %>
185 jc rawAddLL_sq ; if overflow, substract q
186
187 ; Compare with q
188<% for (let i=0; i<n64; i++) { %>
189<% if (i>0) { %>
190 mov rax, [rdi + <%= (n64-i-1)*8 %>]
191<% } %>
192 cmp rax, [q + <%= (n64-i-1)*8 %>]
193 jc rawAddLL_done ; q is bigget so done.
194 jnz rawAddLL_sq ; q is lower
195<% } %>
196 ; If equal substract q
197rawAddLL_sq:
198<% for (let i=0; i<n64; i++) { %>
199 mov rax, [q + <%=i*8%>]
200 <%= i==0 ? "sub" : "sbb" %> [rdi + <%=i*8%>], rax
201<% } %>
202rawAddLL_done:
203 ret
204
205
206;;;;;;;;;;;;;;;;;;;;;;
207; rawAddLS
208;;;;;;;;;;;;;;;;;;;;;;
209; Adds two elements of type long
210; Params:
211; rdi <= Pointer to the long data of result
212; rsi <= Pointer to the long data of element 1
213; rdx <= Value to be added
214;;;;;;;;;;;;;;;;;;;;;;
215rawAddLS:
216 ; Add component by component with carry
217
218 add rdx, [rsi]
219 mov [rdi] ,rdx
220<% for (let i=1; i<n64; i++) { %>
221 mov rdx, 0
222 adc rdx, [rsi + <%=i*8%>]
223 mov [rdi + <%=i*8%>], rdx
224<% } %>
225 jc rawAddLS_sq ; if overflow, substract q
226
227 ; Compare with q
228<% for (let i=0; i<n64; i++) { %>
229 mov rax, [rdi + <%= (n64-i-1)*8 %>]
230 cmp rax, [q + <%= (n64-i-1)*8 %>]
231 jc rawAddLS_done ; q is bigget so done.
232 jnz rawAddLS_sq ; q is lower
233<% } %>
234 ; If equal substract q
235rawAddLS_sq:
236<% for (let i=0; i<n64; i++) { %>
237 mov rax, [q + <%=i*8%>]
238 <%= i==0 ? "sub" : "sbb" %> [rdi + <%=i*8%>], rax
239<% } %>
240rawAddLS_done:
241 ret
242
243
244
245