arnaucube
arnaucube/circomPublic Self-hosted repository
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 first
120        jc     add_s1l2m
121add_s1l2n:
122<%=     global.setTypeDest("0x80"); %>
123<%=     addS1L2(); %>
124
125add_s1l2m:
126        bt     rax, 62          ; check if montgomery second
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