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