arnaucube
arnaucube/circomPublic Self-hosted repository
circom/ports/c/buildasm/mul.asm.ejs
ports/c/buildasm/mul.asm.ejsRaw
  1<% function mulS1S2() { %>
  2        xor    rax, rax
  3        mov    eax, r8d
  4        imul   r9d
  5        jo     mul_manageOverflow   ; rsi already is the 64bits result
  6
  7        mov    [rdi], rax       ; not necessary to adjust so just save and return
  8
  9mul_manageOverflow:                 ; Do the operation in 64 bits
 10        push   rsi
 11        movsx  rax, r8d
 12        movsx  rcx, r9d
 13        imul   rcx
 14        mov    rsi, rax
 15        call   rawCopyS2L
 16        pop    rsi
 17<% } %>
 18
 19<% function squareS1() { %>
 20        xor    rax, rax
 21        mov    eax, r8d
 22        imul   eax
 23        jo     square_manageOverflow   ; rsi already is the 64bits result
 24
 25        mov    [rdi], rax       ; not necessary to adjust so just save and return
 26
 27square_manageOverflow:                 ; Do the operation in 64 bits
 28        push   rsi
 29        movsx  rax, r8d
 30        imul   rax
 31        mov    rsi, rax
 32        call   rawCopyS2L
 33        pop    rsi
 34<% } %>
 35
 36
 37<% function mulL1S2(t) { %>
 38        push rsi
 39        add rsi, 8
 40        movsx rdx, r9d
 41        add rdi, 8
 42        cmp rdx, 0
 43        <% const rawPositiveLabel = global.tmpLabel() %>
 44        jns <%= rawPositiveLabel %>
 45        neg rdx
 46        call rawMontgomeryMul1
 47        mov rsi, rdi
 48        call rawNegL
 49        sub rdi, 8
 50        pop rsi
 51        <% const done = global.tmpLabel() %>
 52        jmp <%= done %>
 53<%= rawPositiveLabel %>:
 54        call rawMontgomeryMul1
 55        sub rdi, 8
 56        pop rsi
 57<%= done %>:
 58
 59<% } %>
 60
 61<% function mulS1L2() { %>
 62        push rsi
 63        lea rsi, [rdx + 8]
 64        movsx rdx, r8d
 65        add rdi, 8
 66        cmp rdx, 0
 67        <% const rawPositiveLabel = global.tmpLabel() %>
 68        jns <%= rawPositiveLabel %>
 69        neg rdx
 70        call rawMontgomeryMul1
 71        mov rsi, rdi
 72        call rawNegL
 73        sub rdi, 8
 74        pop rsi
 75        <% const done = global.tmpLabel() %>
 76        jmp <%= done %>
 77<%= rawPositiveLabel %>:
 78        call rawMontgomeryMul1
 79        sub rdi, 8
 80        pop rsi
 81<%= done %>:
 82
 83<% } %>
 84
 85<% function mulL1L2() { %>
 86        add rdi, 8
 87        add rsi, 8
 88        add rdx, 8
 89        call rawMontgomeryMul
 90        sub rdi, 8
 91        sub rsi, 8
 92<% } %>
 93
 94
 95<% function squareL1() { %>
 96        add rdi, 8
 97        add rsi, 8
 98        call rawMontgomerySquare
 99        sub rdi, 8
100        sub rsi, 8
101<% } %>
102
103<% function mulR3() { %>
104        push rsi
105        add rdi, 8
106        mov rsi, rdi
107        lea rdx, [R3]
108        call rawMontgomeryMul
109        sub rdi, 8
110        pop rsi
111<% } %>
112
113
114
115;;;;;;;;;;;;;;;;;;;;;;
116; square
117;;;;;;;;;;;;;;;;;;;;;;
118; Squares a field element
119; Params:
120;   rsi <= Pointer to element 1
121;   rdi <= Pointer to result
122;   [rdi] = [rsi] * [rsi]
123; Modified Registers:
124;    r8, r9, 10, r11, rax, rcx
125;;;;;;;;;;;;;;;;;;;;;;
126<%=name%>_square:
127        mov    r8, [rsi]
128        bt     r8, 63          ; Check if is short first operand
129        jc     square_l1
130
131square_s1:                       ; Both operands are short
132<%=     squareS1()       %>
133        ret
134
135square_l1:
136        bt     r8, 62          ; check if montgomery first
137        jc     square_l1m
138square_l1n:
139<%=     global.setTypeDest("0xC0"); %>
140<%=     squareL1()         %>
141<%=     mulR3()         %>
142        ret
143
144square_l1m:
145<%=     global.setTypeDest("0xC0"); %>
146<%=     squareL1()         %>
147        ret
148
149
150
151;;;;;;;;;;;;;;;;;;;;;;
152; mul
153;;;;;;;;;;;;;;;;;;;;;;
154; Multiplies two elements of any kind
155; Params:
156;   rsi <= Pointer to element 1
157;   rdx <= Pointer to element 2
158;   rdi <= Pointer to result
159;   [rdi] = [rsi] * [rdi]
160; Modified Registers:
161;    r8, r9, 10, r11, rax, rcx
162;;;;;;;;;;;;;;;;;;;;;;
163<%=name%>_mul:
164        mov    r8, [rsi]
165        mov    r9, [rdx]
166        bt     r8, 63          ; Check if is short first operand
167        jc     mul_l1
168        bt     r9, 63          ; Check if is short second operand
169        jc     mul_s1l2
170
171mul_s1s2:                       ; Both operands are short
172<%=     mulS1S2()       %>
173        ret
174
175mul_l1:
176        bt     r9, 63          ; Check if is short second operand
177        jc     mul_l1l2
178
179;;;;;;;;
180mul_l1s2:
181        bt     r8, 62          ; check if montgomery first
182        jc     mul_l1ms2
183mul_l1ns2:
184        bt     r9, 62          ; check if montgomery first
185        jc     mul_l1ns2m
186mul_l1ns2n:
187<%=     global.setTypeDest("0xC0"); %>
188<%=     mulL1S2()       %>
189<%=     mulR3()         %>
190        ret
191
192
193mul_l1ns2m:
194<%=     global.setTypeDest("0x80"); %>
195<%=     mulL1L2()       %>
196        ret
197
198
199mul_l1ms2:
200        bt     r9, 62          ; check if montgomery second
201        jc     mul_l1ms2m
202mul_l1ms2n:
203<%=     global.setTypeDest("0x80"); %>
204<%=     mulL1S2()       %>
205        ret
206
207mul_l1ms2m:
208<%=     global.setTypeDest("0xC0"); %>
209<%=     mulL1L2()         %>
210        ret
211
212
213;;;;;;;;
214mul_s1l2:
215        bt     r8, 62          ; check if montgomery first
216        jc     mul_s1ml2
217mul_s1nl2:
218        bt     r9, 62          ; check if montgomery first
219        jc     mul_s1nl2m
220mul_s1nl2n:
221<%=     global.setTypeDest("0xC0"); %>
222<%=     mulS1L2()       %>
223<%=     mulR3()         %>
224        ret
225
226mul_s1nl2m:
227<%=     global.setTypeDest("0x80"); %>
228<%=     mulS1L2(); %>
229        ret
230
231mul_s1ml2:
232        bt     r9, 62          ; check if montgomery first
233        jc     mul_s1ml2m
234mul_s1ml2n:
235<%=     global.setTypeDest("0x80"); %>
236<%=     mulL1L2()         %>
237        ret
238
239mul_s1ml2m:
240<%=     global.setTypeDest("0xC0"); %>
241<%=     mulL1L2()         %>
242        ret
243
244;;;;
245mul_l1l2:
246        bt     r8, 62          ; check if montgomery first
247        jc     mul_l1ml2
248mul_l1nl2:
249        bt     r9, 62          ; check if montgomery second
250        jc     mul_l1nl2m
251mul_l1nl2n:
252<%=     global.setTypeDest("0xC0"); %>
253<%=     mulL1L2()         %>
254<%=     mulR3()         %>
255        ret
256
257mul_l1nl2m:
258<%=     global.setTypeDest("0x80"); %>
259<%=     mulL1L2()         %>
260        ret
261
262mul_l1ml2:
263        bt     r9, 62          ; check if montgomery seconf
264        jc     mul_l1ml2m
265mul_l1ml2n:
266<%=     global.setTypeDest("0x80"); %>
267<%=     mulL1L2()         %>
268        ret
269
270mul_l1ml2m:
271<%=     global.setTypeDest("0xC0"); %>
272<%=     mulL1L2()         %>
273        ret
274
275