arnaucube
arnaucube/circomPublic Self-hosted repository
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