circom/ports/c/buildasm/sub.asm.ejs
ports/c/buildasm/sub.asm.ejsRaw
1<% function subS1S2() { %>
2 xor rdx, rdx
3 mov edx, eax
4 sub edx, ecx
5 jo sub_manageOverflow ; rsi already is the 64bits result
6
7 mov [rdi], rdx ; not necessary to adjust so just save and return
8 ret
9
10sub_manageOverflow: ; Do the operation in 64 bits
11 push rsi
12 movsx rsi, eax
13 movsx rdx, ecx
14 sub rsi, rdx
15 call rawCopyS2L
16 pop rsi
17 ret
18<% } %>
19
20<% function subL1S2(t) { %>
21 add rsi, 8
22 movsx rdx, ecx
23 add rdi, 8
24 cmp rdx, 0
25 <% const rawSubLabel = global.tmpLabel() %>
26 jns <%= rawSubLabel %>
27 neg rdx
28 call rawAddLS
29 sub rdi, 8
30 sub rsi, 8
31 ret
32<%= rawSubLabel %>:
33 call rawSubLS
34 sub rdi, 8
35 sub rsi, 8
36 ret
37<% } %>
38
39
40<% function subS1L2(t) { %>
41 cmp eax, 0
42 <% const s1NegLabel = global.tmpLabel() %>
43 js <%= s1NegLabel %>
44
45 ; First Operand is positive
46 push rsi
47 add rdi, 8
48 movsx rsi, eax
49 add rdx, 8
50 call rawSubSL
51 sub rdi, 8
52 pop rsi
53 ret
54
55<%= s1NegLabel %>: ; First operand is negative
56 push rsi
57 lea rsi, [rdx + 8]
58 movsx rdx, eax
59 add rdi, 8
60 neg rdx
61 call rawNegLS
62 sub rdi, 8
63 pop rsi
64 ret
65<% } %>
66
67
68<% function subL1L2(t) { %>
69 add rdi, 8
70 add rsi, 8
71 add rdx, 8
72 call rawSubLL
73 sub rdi, 8
74 sub rsi, 8
75 ret
76<% } %>
77
78;;;;;;;;;;;;;;;;;;;;;;
79; sub
80;;;;;;;;;;;;;;;;;;;;;;
81; Substracts two elements of any kind
82; Params:
83; rsi <= Pointer to element 1
84; rdx <= Pointer to element 2
85; rdi <= Pointer to result
86; Modified Registers:
87; r8, r9, 10, r11, rax, rcx
88;;;;;;;;;;;;;;;;;;;;;;
89<%=name%>_sub:
90 mov rax, [rsi]
91 mov rcx, [rdx]
92 bt rax, 63 ; Check if is long first operand
93 jc sub_l1
94 bt rcx, 63 ; Check if is long second operand
95 jc sub_s1l2
96
97sub_s1s2: ; Both operands are short
98<%= subS1S2() %>
99sub_l1:
100 bt rcx, 63 ; Check if is short second operand
101 jc sub_l1l2
102
103;;;;;;;;
104sub_l1s2:
105 bt rax, 62 ; check if montgomery first
106 jc sub_l1ms2
107sub_l1ns2:
108<%= global.setTypeDest("0x80"); %>
109<%= subL1S2(); %>
110
111sub_l1ms2:
112 bt rcx, 62 ; check if montgomery second
113 jc sub_l1ms2m
114sub_l1ms2n:
115<%= global.setTypeDest("0xC0"); %>
116<%= global.toMont_b() %>
117<%= subL1L2() %>
118
119sub_l1ms2m:
120<%= global.setTypeDest("0xC0"); %>
121<%= subL1L2() %>
122
123
124;;;;;;;;
125sub_s1l2:
126 bt rcx, 62 ; check if montgomery first
127 jc sub_s1l2m
128sub_s1l2n:
129<%= global.setTypeDest("0x80"); %>
130<%= subS1L2(); %>
131
132sub_s1l2m:
133 bt rax, 62 ; check if montgomery second
134 jc sub_s1ml2m
135sub_s1nl2m:
136<%= global.setTypeDest("0xC0"); %>
137<%= global.toMont_a() %>
138<%= subL1L2() %>
139
140sub_s1ml2m:
141<%= global.setTypeDest("0xC0"); %>
142<%= subL1L2() %>
143
144;;;;
145sub_l1l2:
146 bt rax, 62 ; check if montgomery first
147 jc sub_l1ml2
148sub_l1nl2:
149 bt rcx, 62 ; check if montgomery second
150 jc sub_l1nl2m
151sub_l1nl2n:
152<%= global.setTypeDest("0x80"); %>
153<%= subL1L2() %>
154
155sub_l1nl2m:
156<%= global.setTypeDest("0xC0"); %>
157<%= global.toMont_a(); %>
158<%= subL1L2() %>
159
160sub_l1ml2:
161 bt rcx, 62 ; check if montgomery seconf
162 jc sub_l1ml2m
163sub_l1ml2n:
164<%= global.setTypeDest("0xC0"); %>
165<%= global.toMont_b(); %>
166<%= subL1L2() %>
167
168sub_l1ml2m:
169<%= global.setTypeDest("0xC0"); %>
170<%= subL1L2() %>
171
172
173;;;;;;;;;;;;;;;;;;;;;;
174; rawSubLS
175;;;;;;;;;;;;;;;;;;;;;;
176; Substracts a short element from the long element
177; Params:
178; rdi <= Pointer to the long data of result
179; rsi <= Pointer to the long data of element 1 where will be substracted
180; rdx <= Value to be substracted
181; [rdi] = [rsi] - rdx
182; Modified Registers:
183; rax
184;;;;;;;;;;;;;;;;;;;;;;
185rawSubLS:
186 ; Substract first digit
187
188 mov rax, [rsi]
189 sub rax, rdx
190 mov [rdi] ,rax
191 mov rdx, 0
192<% for (let i=1; i<n64; i++) { %>
193 mov rax, [rsi + <%=i*8%>]
194 sbb rax, rdx
195 mov [rdi + <%=i*8%>], rax
196<% } %>
197 jnc rawSubLS_done ; if overflow, add q
198
199 ; Add q
200rawSubLS_aq:
201<% for (let i=0; i<n64; i++) { %>
202 mov rax, [q + <%=i*8%>]
203 <%= i==0 ? "add" : "adc" %> [rdi + <%=i*8%>], rax
204<% } %>
205rawSubLS_done:
206 ret
207
208
209;;;;;;;;;;;;;;;;;;;;;;
210; rawSubSL
211;;;;;;;;;;;;;;;;;;;;;;
212; Substracts a long element from a short element
213; Params:
214; rdi <= Pointer to the long data of result
215; rsi <= Value from where will bo substracted
216; rdx <= Pointer to long of the value to be substracted
217;
218; [rdi] = rsi - [rdx]
219; Modified Registers:
220; rax
221;;;;;;;;;;;;;;;;;;;;;;
222rawSubSL:
223 ; Substract first digit
224 sub rsi, [rdx]
225 mov [rdi] ,rsi
226
227<% for (let i=1; i<n64; i++) { %>
228 mov rax, 0
229 sbb rax, [rdx + <%=i*8%>]
230 mov [rdi + <%=i*8%>], rax
231<% } %>
232 jnc rawSubSL_done ; if overflow, add q
233
234 ; Add q
235rawSubSL_aq:
236<% for (let i=0; i<n64; i++) { %>
237 mov rax, [q + <%=i*8%>]
238 <%= i==0 ? "add" : "adc" %> [rdi + <%=i*8%>], rax
239<% } %>
240rawSubSL_done:
241 ret
242
243;;;;;;;;;;;;;;;;;;;;;;
244; rawSubLL
245;;;;;;;;;;;;;;;;;;;;;;
246; Substracts a long element from a short element
247; Params:
248; rdi <= Pointer to the long data of result
249; rsi <= Pointer to long from where substracted
250; rdx <= Pointer to long of the value to be substracted
251;
252; [rdi] = [rsi] - [rdx]
253; Modified Registers:
254; rax
255;;;;;;;;;;;;;;;;;;;;;;
256rawSubLL:
257 ; Substract first digit
258<% for (let i=0; i<n64; i++) { %>
259 mov rax, [rsi + <%=i*8%>]
260 <%= i==0 ? "sub" : "sbb" %> rax, [rdx + <%=i*8%>]
261 mov [rdi + <%=i*8%>], rax
262<% } %>
263 jnc rawSubLL_done ; if overflow, add q
264
265 ; Add q
266rawSubLL_aq:
267<% for (let i=0; i<n64; i++) { %>
268 mov rax, [q + <%=i*8%>]
269 <%= i==0 ? "add" : "adc" %> [rdi + <%=i*8%>], rax
270<% } %>
271rawSubLL_done:
272 ret
273
274;;;;;;;;;;;;;;;;;;;;;;
275; rawNegLS
276;;;;;;;;;;;;;;;;;;;;;;
277; Substracts a long element and a short element form 0
278; Params:
279; rdi <= Pointer to the long data of result
280; rsi <= Pointer to long from where substracted
281; rdx <= short value to be substracted too
282;
283; [rdi] = -[rsi] - rdx
284; Modified Registers:
285; rax
286;;;;;;;;;;;;;;;;;;;;;;
287rawNegLS:
288 mov rax, [q]
289 sub rax, rdx
290 mov [rdi], rax
291<% for (let i=1; i<n64; i++) { %>
292 mov rax, [q + <%=i*8%> ]
293 sbb rax, 0
294 mov [rdi + <%=i*8%>], rax
295<% } %>
296 setc dl
297
298<% for (let i=0; i<n64; i++) { %>
299 mov rax, [rdi + <%=i*8%> ]
300 <%= i==0 ? "sub" : "sbb" %> rax, [rsi + <%=i*8%>]
301 mov [rdi + <%=i*8%>], rax
302<% } %>
303
304 setc dh
305 or dl, dh
306 jz rawNegSL_done
307
308 ; it is a negative value, so add q
309<% for (let i=0; i<n64; i++) { %>
310 mov rax, [q + <%=i*8%>]
311 <%= i==0 ? "add" : "adc" %> [rdi + <%=i*8%>], rax
312<% } %>
313
314rawNegSL_done:
315 ret
316
317