circom/c/buildasm/mul.asm.ejs
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 mulL1S2(t) { %>
20 push rsi
21 add rsi, 8
22 movsx rdx, r9d
23 add rdi, 8
24 cmp rdx, 0
25 <% const rawPositiveLabel = global.tmpLabel() %>
26 jns <%= rawPositiveLabel %>
27 neg rdx
28 call rawMontgomeryMul1
29 mov rsi, rdi
30 call rawNegL
31 sub rdi, 8
32 pop rsi
33 <% const done = global.tmpLabel() %>
34 jmp <%= done %>
35<%= rawPositiveLabel %>:
36 call rawMontgomeryMul1
37 sub rdi, 8
38 pop rsi
39<%= done %>:
40
41<% } %>
42
43<% function mulS1L2() { %>
44 push rsi
45 lea rsi, [rdx + 8]
46 movsx rdx, r8d
47 add rdi, 8
48 cmp rdx, 0
49 <% const rawPositiveLabel = global.tmpLabel() %>
50 jns <%= rawPositiveLabel %>
51 neg rdx
52 call rawMontgomeryMul1
53 mov rsi, rdi
54 call rawNegL
55 sub rdi, 8
56 pop rsi
57 <% const done = global.tmpLabel() %>
58 jmp <%= done %>
59<%= rawPositiveLabel %>:
60 call rawMontgomeryMul1
61 sub rdi, 8
62 pop rsi
63<%= done %>:
64
65<% } %>
66
67<% function mulL1L2() { %>
68 add rdi, 8
69 add rsi, 8
70 add rdx, 8
71 call rawMontgomeryMul
72 sub rdi, 8
73 sub rsi, 8
74<% } %>
75
76<% function mulR3() { %>
77 push rsi
78 add rdi, 8
79 mov rsi, rdi
80 lea rdx, [R3]
81 call rawMontgomeryMul
82 sub rdi, 8
83 pop rsi
84<% } %>
85
86
87;;;;;;;;;;;;;;;;;;;;;;
88; mul
89;;;;;;;;;;;;;;;;;;;;;;
90; Multiplies two elements of any kind
91; Params:
92; rsi <= Pointer to element 1
93; rdx <= Pointer to element 2
94; rdi <= Pointer to result
95; [rdi] = [rsi] * [rdi]
96; Modified Registers:
97; r8, r9, 10, r11, rax, rcx
98;;;;;;;;;;;;;;;;;;;;;;
99<%=name%>_mul:
100 mov r8, [rsi]
101 mov r9, [rdx]
102 bt r8, 63 ; Check if is short first operand
103 jc mul_l1
104 bt r9, 63 ; Check if is short second operand
105 jc mul_s1l2
106
107mul_s1s2: ; Both operands are short
108<%= mulS1S2() %>
109 ret
110
111mul_l1:
112 bt r9, 63 ; Check if is short second operand
113 jc mul_l1l2
114
115;;;;;;;;
116mul_l1s2:
117 bt r8, 62 ; check if montgomery first
118 jc mul_l1ms2
119mul_l1ns2:
120 bt r9, 62 ; check if montgomery first
121 jc mul_l1ns2m
122mul_l1ns2n:
123<%= global.setTypeDest("0xC0"); %>
124<%= mulL1S2() %>
125<%= mulR3() %>
126 ret
127
128
129mul_l1ns2m:
130<%= global.setTypeDest("0x80"); %>
131<%= mulL1L2() %>
132 ret
133
134
135mul_l1ms2:
136 bt r9, 62 ; check if montgomery second
137 jc mul_l1ms2m
138mul_l1ms2n:
139<%= global.setTypeDest("0x80"); %>
140<%= mulL1S2() %>
141 ret
142
143mul_l1ms2m:
144<%= global.setTypeDest("0xC0"); %>
145<%= mulL1L2() %>
146 ret
147
148
149;;;;;;;;
150mul_s1l2:
151 bt r8, 62 ; check if montgomery first
152 jc mul_s1ml2
153mul_s1nl2:
154 bt r9, 62 ; check if montgomery first
155 jc mul_s1nl2m
156mul_s1nl2n:
157<%= global.setTypeDest("0xC0"); %>
158<%= mulS1L2() %>
159<%= mulR3() %>
160 ret
161
162mul_s1nl2m:
163<%= global.setTypeDest("0x80"); %>
164<%= mulS1L2(); %>
165 ret
166
167mul_s1ml2:
168 bt r9, 62 ; check if montgomery first
169 jc mul_s1ml2m
170mul_s1ml2n:
171<%= global.setTypeDest("0x80"); %>
172<%= mulL1L2() %>
173 ret
174
175mul_s1ml2m:
176<%= global.setTypeDest("0xC0"); %>
177<%= mulL1L2() %>
178 ret
179
180;;;;
181mul_l1l2:
182 bt r8, 62 ; check if montgomery first
183 jc mul_l1ml2
184mul_l1nl2:
185 bt r9, 62 ; check if montgomery second
186 jc mul_l1nl2m
187mul_l1nl2n:
188<%= global.setTypeDest("0xC0"); %>
189<%= mulL1L2() %>
190<%= mulR3() %>
191 ret
192
193mul_l1nl2m:
194<%= global.setTypeDest("0x80"); %>
195<%= mulL1L2() %>
196 ret
197
198mul_l1ml2:
199 bt r9, 62 ; check if montgomery seconf
200 jc mul_l1ml2m
201mul_l1ml2n:
202<%= global.setTypeDest("0x80"); %>
203<%= mulL1L2() %>
204 ret
205
206mul_l1ml2m:
207<%= global.setTypeDest("0xC0"); %>
208<%= mulL1L2() %>
209 ret
210
211