circom/ports/c/buildasm/old/mul.asm.ejs
ports/c/buildasm/old/mul.asm.ejsRaw
1
2;;;;;;;;;;;;;;;;;;;;;;
3; mul Montgomery
4;;;;;;;;;;;;;;;;;;;;;;
5mulM:
6<%
7let r0, r1, r2;
8function setR(step) {
9 if ((step % 3) == 0) {
10 r0 = "r8";
11 r1 = "r9";
12 r2 = "r10";
13 } else if ((step % 3) == 1) {
14 r0 = "r9";
15 r1 = "r10";
16 r2 = "r8";
17 } else {
18 r0 = "r10";
19 r1 = "r8";
20 r2 = "r9";
21 }
22}
23
24const base = bigInt.one.shiftLeft(64);
25const np64 = base.minus(q.modInv(base));
26%>
27 sub rsp, <%= n64*8 %> ; Reserve space for ms
28 mov rcx, rdx ; rdx is needed for multiplications so keep it in cx
29 mov r11, 0x<%= np64.toString(16) %> ; np
30 xor r8,r8
31 xor r9,r9
32 xor r10,r10
33<%
34// Main loop
35for (let i=0; i<n64*2; i++) {
36 setR(i);
37%>
38<%
39 // Same Digit
40 for (let o1=Math.max(0, i-n64+1); (o1<=i)&&(o1<n64); o1++) {
41 const o2= i-o1;
42%>
43 mov rax, [rsi + <%= 8*o1 %>]
44 mul qword [rcx + <%= 8*o2 %>]
45 add <%= r0 %>, rax
46 adc <%= r1 %>, rdx
47 adc <%= r2 %>, 0x0
48<%
49 } // Same digit
50%>
51
52
53<%
54 for (let j=i-1; j>=0; j--) { // All ms
55 if (((i-j)<n64)&&(j<n64)) {
56%>
57 mov rax, [rsp + <%= j*8 %>]
58 mul qword [q + <%= (i-j)*8 %>]
59 add <%= r0 %>, rax
60 adc <%= r1 %>, rdx
61 adc <%= r2 %>, 0x0
62<%
63 }
64 } // ms
65%>
66
67<%
68 if (i<n64) {
69%>
70 mov rax, <%= r0 %>
71 mul r11
72 mov [rsp + <%= i*8 %>], rax
73 mul qword [q]
74 add <%= r0 %>, rax
75 adc <%= r1 %>, rdx
76 adc <%= r2 %>, 0x0
77<%
78 } else {
79%>
80 mov [rdi + <%= (i-n64)*8 %> ], <%= r0 %>
81 xor <%= r0 %>,<%= r0 %>
82<%
83 }
84%>
85
86<%
87} // Main Loop
88%>
89 cmp <%= r1 %>, 0x0
90 jne mulM_sq
91 ; Compare with q
92<%
93for (let i=0; i<n64; i++) {
94%>
95 mov rax, [rdi + <%= (n64-i-1)*8 %>]
96 cmp rax, [q + <%= (n64-i-1)*8 %>]
97 jg mulM_sq
98 jl mulM_done
99<%
100}
101%>
102 ; If equal substract q
103
104mulM_sq:
105<%
106for (let i=0; i<n64; i++) {
107%>
108 mov rax, [q + <%= i*8 %>]
109 <%= i==0 ? "sub" : "sbb" %> [rdi + <%= i*8 %>], rax
110<%
111}
112%>
113
114mulM_done:
115 add rsp, <%= n64*8 %> ; recover rsp
116 ret
117
118;;;;;;;;;;;;;;;;;;;;;;
119; mul MontgomeryShort
120;;;;;;;;;;;;;;;;;;;;;;
121mulSM:
122
123;;;;;;;;;;;;;;;;;;;;;;
124; mul
125;;;;;;;;;;;;;;;;;;;;;;
126<%=name%>_mul:
127 mov rax, [rsi]
128 bt rax, 63
129 jc l1
130 mov rcx, [rdx]
131 bt rcx, 63
132 jc s1l2
133s1s2: ; short first and second
134 mul ecx
135 jc rs2l ; If if doesn't feed in 32 bits convert the result to long
136
137 ; The shorts multiplication is done. copy the val to destination and return
138 mov [rdi], rax
139 ret
140
141rs2l: ; The result in the multiplication doen't feed
142 ; we have the result in edx:eax we need to convert it to long
143 shl rdx, 32
144 mov edx, eax ; pack edx:eax to rdx
145
146 xor rax, rax ; Set the format to long
147 bts rax, 63
148 mov [rdi], rax ; move the first digit
149
150 cmp rdx, 0 ; check if redx is negative.
151 jl rs2ln
152
153 ; edx is positive.
154 mov [rdi + 8], rdx ; Set the firs digit
155
156 xor rax, rax ; Set the remaining digits to 0
157<% for (let i=1; i<n64; i++) { %>
158 mov [rdi + <%= (i+1)*8 %>], rax
159<% } %>
160 ret
161
162 ; edx is negative.
163rs2ln:
164
165 add rdx, [q] ; Set the firs digit
166 mov [rdi + 8], rdx ;
167
168 mov rdx, -1 ; all ones
169<% for (let i=1; i<n64; i++) { %>
170 mov rax, rdx ; Add to q
171 adc rax, [q + <%= i*8 %> ]
172 mov [rdi + <%= (i+1)*8 %>], rax
173<% } %>
174 ret
175
176l1:
177 mov rcx, [rdx]
178 bt rcx, 63
179 jc ll
180
181l1s2:
182 xor rdx, rdx
183 mov edx, ecx
184 bt rax, 62
185 jc lsM
186 jmp lsN
187
188s1l2:
189 mov rsi, rdx
190 xor rdx, rdx
191 mov edx, eax
192 bt rcx, 62
193 jc lsM
194 jmp lsN
195
196
197lsN:
198 mov byte [rdi + 7], 0xC0 ; set the result to montgomery
199 add rsi, 8
200 add rdi, 8
201 call mulSM
202 mov rsi, rdi
203 lea rdx, [R3]
204 call mulM
205 ret
206
207lsM:
208 mov byte [rdi + 7], 0x80 ; set the result to long normal
209 add rsi, 8
210 add rdi, 8
211 call mulSM
212 ret
213
214
215ll:
216
217 bt rax, 62
218 jc lml
219 bt rcx, 62
220 jc lnlm
221
222lnln:
223 mov byte [rdi + 7], 0xC0 ; set the result to long montgomery
224 add rsi, 8
225 add rdi, 8
226 add rdx, 8
227 call mulM
228 mov rsi, rdi
229 lea rdx, [R3]
230 call mulM
231 ret
232
233lml:
234 bt rcx, 62
235 jc lmlm
236
237lnlm:
238 mov byte [rdi + 7], 0x80 ; set the result to long normal
239 add rsi, 8
240 add rdi, 8
241 add rdx, 8
242 call mulM
243 ret
244
245lmlm:
246 mov byte [rdi + 7], 0xC0 ; set the result to long montgomery
247 add rsi, 8
248 add rdi, 8
249 add rdx, 8
250 call mulM
251 ret