circom/ports/c/buildasm/cmpops.asm.ejs
ports/c/buildasm/cmpops.asm.ejsRaw
1<% function signL(reg, label_pos, label_neg) { %>
2<% for (let i=n64-1; i>=0; i--) { %>
3 mov rax, [<%=reg%> + <%= 8+(i*8) %>]
4 cmp [half + <%= (i*8) %>], rax ; comare with (q-1)/2
5 jc <%=label_neg%> ; half<rax => e1-e2 is neg => e1 < e2
6<% if (i>0) { %>
7 jnz <%=label_pos%> ; half>rax => e1 -e2 is pos => e1 > e2
8<% } else { %>
9 jmp <%=label_pos%>
10<% } %>
11<% } %>
12<% } %>
13
14
15;;;;;;;;;;;;;;;;;;;;;;
16; rgt - Raw Greater Than
17;;;;;;;;;;;;;;;;;;;;;;
18; returns in ax 1 id *rsi > *rdx
19; Params:
20; rsi <= Pointer to element 1
21; rdx <= Pointer to element 2
22; rax <= Return 1 or 0
23; Modified Registers:
24; r8, r9, rax
25;;;;;;;;;;;;;;;;;;;;;;
26<%=name%>_rgt:
27 mov r8, [rsi]
28 mov r9, [rdx]
29 bt r8, 63 ; Check if is short first operand
30 jc rgt_l1
31 bt r9, 63 ; Check if is short second operand
32 jc rgt_s1l2
33
34rgt_s1s2: ; Both operands are short
35 cmp r8d, r9d
36 jg rgt_ret1
37 jmp rgt_ret0
38
39
40rgt_l1:
41 bt r9, 63 ; Check if is short second operand
42 jc rgt_l1l2
43
44;;;;;;;;
45rgt_l1s2:
46 bt r8, 62 ; check if montgomery first
47 jc rgt_l1ms2
48rgt_l1ns2:
49<%= global.toLong_b() %>
50 jmp rgtL1L2
51
52rgt_l1ms2:
53<%= global.toLong_b() %>
54<%= global.fromMont_a() %>
55 jmp rgtL1L2
56
57
58;;;;;;;;
59rgt_s1l2:
60 bt r9, 62 ; check if montgomery second
61 jc rgt_s1l2m
62rgt_s1l2n:
63<%= global.toLong_a() %>
64 jmp rgtL1L2
65
66rgt_s1l2m:
67<%= global.toLong_a() %>
68<%= global.fromMont_b() %>
69 jmp rgtL1L2
70
71;;;;
72rgt_l1l2:
73 bt r8, 62 ; check if montgomery first
74 jc rgt_l1ml2
75rgt_l1nl2:
76 bt r9, 62 ; check if montgomery second
77 jc rgt_l1nl2m
78rgt_l1nl2n:
79 jmp rgtL1L2
80
81rgt_l1nl2m:
82<%= global.fromMont_b() %>
83 jmp rgtL1L2
84
85rgt_l1ml2:
86 bt r9, 62 ; check if montgomery second
87 jc rgt_l1ml2m
88rgt_l1ml2n:
89<%= global.fromMont_a() %>
90 jmp rgtL1L2
91
92rgt_l1ml2m:
93<%= global.fromMont_a() %>
94<%= global.fromMont_b() %>
95 jmp rgtL1L2
96
97
98;;;;;;
99; rgtL1L2
100;;;;;;
101
102rgtL1L2:
103<%= signL("rsi", "rgtl1l2_p1", "rgtl1l2_n1") %>
104rgtl1l2_p1:
105<%= signL("rdx", "rgtRawL1L2", "rgt_ret1") %>
106
107rgtl1l2_n1:
108<%= signL("rdx", "rgt_ret0", "rgtRawL1L2") %>
109
110
111rgtRawL1L2:
112<% for (let i=n64-1; i>=0; i--) { %>
113 mov rax, [rsi + <%= 8+(i*8) %>]
114 cmp [rdx + <%= 8+(i*8) %>], rax ; comare with (q-1)/2
115 jc rgt_ret1 ; rsi<rdx => 1st > 2nd
116<% if (i>0) { %>
117 jnz rgt_ret0
118<% } %>
119<% } %>
120
121rgt_ret0:
122 xor rax, rax
123 ret
124rgt_ret1:
125 mov rax, 1
126 ret
127
128
129
130;;;;;;;;;;;;;;;;;;;;;;
131; rlt - Raw Less Than
132;;;;;;;;;;;;;;;;;;;;;;
133; returns in ax 1 id *rsi > *rdx
134; Params:
135; rsi <= Pointer to element 1
136; rdx <= Pointer to element 2
137; rax <= Return 1 or 0
138; Modified Registers:
139; r8, r9, rax
140;;;;;;;;;;;;;;;;;;;;;;
141<%=name%>_rlt:
142 mov r8, [rsi]
143 mov r9, [rdx]
144 bt r8, 63 ; Check if is short first operand
145 jc rlt_l1
146 bt r9, 63 ; Check if is short second operand
147 jc rlt_s1l2
148
149rlt_s1s2: ; Both operands are short
150 cmp r8d, r9d
151 jl rlt_ret1
152 jmp rlt_ret0
153
154
155rlt_l1:
156 bt r9, 63 ; Check if is short second operand
157 jc rlt_l1l2
158
159;;;;;;;;
160rlt_l1s2:
161 bt r8, 62 ; check if montgomery first
162 jc rlt_l1ms2
163rlt_l1ns2:
164<%= global.toLong_b() %>
165 jmp rltL1L2
166
167rlt_l1ms2:
168<%= global.toLong_b() %>
169<%= global.fromMont_a() %>
170 jmp rltL1L2
171
172
173;;;;;;;;
174rlt_s1l2:
175 bt r9, 62 ; check if montgomery second
176 jc rlt_s1l2m
177rlt_s1l2n:
178<%= global.toLong_a() %>
179 jmp rltL1L2
180
181rlt_s1l2m:
182<%= global.toLong_a() %>
183<%= global.fromMont_b() %>
184 jmp rltL1L2
185
186;;;;
187rlt_l1l2:
188 bt r8, 62 ; check if montgomery first
189 jc rlt_l1ml2
190rlt_l1nl2:
191 bt r9, 62 ; check if montgomery second
192 jc rlt_l1nl2m
193rlt_l1nl2n:
194 jmp rltL1L2
195
196rlt_l1nl2m:
197<%= global.fromMont_b() %>
198 jmp rltL1L2
199
200rlt_l1ml2:
201 bt r9, 62 ; check if montgomery second
202 jc rlt_l1ml2m
203rlt_l1ml2n:
204<%= global.fromMont_a() %>
205 jmp rltL1L2
206
207rlt_l1ml2m:
208<%= global.fromMont_a() %>
209<%= global.fromMont_b() %>
210 jmp rltL1L2
211
212
213;;;;;;
214; rltL1L2
215;;;;;;
216
217rltL1L2:
218<%= signL("rsi", "rltl1l2_p1", "rltl1l2_n1") %>
219rltl1l2_p1:
220<%= signL("rdx", "rltRawL1L2", "rlt_ret0") %>
221
222rltl1l2_n1:
223<%= signL("rdx", "rlt_ret1", "rltRawL1L2") %>
224
225
226rltRawL1L2:
227<% for (let i=n64-1; i>=0; i--) { %>
228 mov rax, [rsi + <%= 8+(i*8) %>]
229 cmp [rdx + <%= 8+(i*8) %>], rax ; comare with (q-1)/2
230 jc rlt_ret0 ; rsi<rdx => 1st > 2nd
231 jnz rlt_ret1
232<% } %>
233
234rlt_ret0:
235 xor rax, rax
236 ret
237rlt_ret1:
238 mov rax, 1
239 ret
240
241
242
243;;;;;;;;;;;;;;;;;;;;;;
244; req - Raw Eq
245;;;;;;;;;;;;;;;;;;;;;;
246; returns in ax 1 id *rsi == *rdx
247; Params:
248; rsi <= Pointer to element 1
249; rdx <= Pointer to element 2
250; rax <= Return 1 or 0
251; Modified Registers:
252; r8, r9, rax
253;;;;;;;;;;;;;;;;;;;;;;
254<%=name%>_req:
255 mov r8, [rsi]
256 mov r9, [rdx]
257 bt r8, 63 ; Check if is short first operand
258 jc req_l1
259 bt r9, 63 ; Check if is short second operand
260 jc req_s1l2
261
262req_s1s2: ; Both operands are short
263 cmp r8d, r9d
264 je req_ret1
265 jmp req_ret0
266
267
268req_l1:
269 bt r9, 63 ; Check if is short second operand
270 jc req_l1l2
271
272;;;;;;;;
273req_l1s2:
274 bt r8, 62 ; check if montgomery first
275 jc req_l1ms2
276req_l1ns2:
277<%= global.toLong_b() %>
278 jmp reqL1L2
279
280req_l1ms2:
281<%= global.toMont_b() %>
282 jmp reqL1L2
283
284
285;;;;;;;;
286req_s1l2:
287 bt r9, 62 ; check if montgomery second
288 jc req_s1l2m
289req_s1l2n:
290<%= global.toLong_a() %>
291 jmp reqL1L2
292
293req_s1l2m:
294<%= global.toMont_a() %>
295 jmp reqL1L2
296
297;;;;
298req_l1l2:
299 bt r8, 62 ; check if montgomery first
300 jc req_l1ml2
301req_l1nl2:
302 bt r9, 62 ; check if montgomery second
303 jc req_l1nl2m
304req_l1nl2n:
305 jmp reqL1L2
306
307req_l1nl2m:
308<%= global.toMont_a() %>
309 jmp reqL1L2
310
311req_l1ml2:
312 bt r9, 62 ; check if montgomery second
313 jc req_l1ml2m
314req_l1ml2n:
315<%= global.toMont_b() %>
316 jmp reqL1L2
317
318req_l1ml2m:
319 jmp reqL1L2
320
321
322;;;;;;
323; eqL1L2
324;;;;;;
325
326reqL1L2:
327<% for (let i=0; i<n64; i++) { %>
328 mov rax, [rsi + <%= 8+(i*8) %>]
329 cmp [rdx + <%= 8+(i*8) %>], rax
330 jne req_ret0 ; rsi<rdi => 1st > 2nd
331<% } %>
332
333req_ret1:
334 mov rax, 1
335 ret
336
337req_ret0:
338 xor rax, rax
339 ret
340
341
342;;;;;;;;;;;;;;;;;;;;;;
343; gt
344;;;;;;;;;;;;;;;;;;;;;;
345; Compares two elements of any kind
346; Params:
347; rsi <= Pointer to element 1
348; rdx <= Pointer to element 2
349; rdi <= Pointer to result can be zero or one.
350; Modified Registers:
351; rax, rcx
352;;;;;;;;;;;;;;;;;;;;;;
353<%=name%>_gt:
354 call <%=name%>_rgt
355 mov [rdi], rax
356 ret
357
358;;;;;;;;;;;;;;;;;;;;;;
359; lt
360;;;;;;;;;;;;;;;;;;;;;;
361; Compares two elements of any kind
362; Params:
363; rsi <= Pointer to element 1
364; rdx <= Pointer to element 2
365; rdi <= Pointer to result can be zero or one.
366; Modified Registers:
367; rax, rcx
368;;;;;;;;;;;;;;;;;;;;;;
369<%=name%>_lt:
370 call <%=name%>_rlt
371 mov [rdi], rax
372 ret
373
374;;;;;;;;;;;;;;;;;;;;;;
375; eq
376;;;;;;;;;;;;;;;;;;;;;;
377; Compares two elements of any kind
378; Params:
379; rsi <= Pointer to element 1
380; rdx <= Pointer to element 2
381; rdi <= Pointer to result can be zero or one.
382; Modified Registers:
383; rax, rcx
384;;;;;;;;;;;;;;;;;;;;;;
385<%=name%>_eq:
386 call <%=name%>_req
387 mov [rdi], rax
388 ret
389
390;;;;;;;;;;;;;;;;;;;;;;
391; neq
392;;;;;;;;;;;;;;;;;;;;;;
393; Compares two elements of any kind
394; Params:
395; rsi <= Pointer to element 1
396; rdx <= Pointer to element 2
397; rdi <= Pointer to result can be zero or one.
398; Modified Registers:
399; rax, rcx
400;;;;;;;;;;;;;;;;;;;;;;
401<%=name%>_neq:
402 call <%=name%>_req
403 xor rax, 1
404 mov [rdi], rax
405 ret
406
407;;;;;;;;;;;;;;;;;;;;;;
408; geq
409;;;;;;;;;;;;;;;;;;;;;;
410; Compares two elements of any kind
411; Params:
412; rsi <= Pointer to element 1
413; rdx <= Pointer to element 2
414; rdi <= Pointer to result can be zero or one.
415; Modified Registers:
416; rax, rcx
417;;;;;;;;;;;;;;;;;;;;;;
418<%=name%>_geq:
419 call <%=name%>_rlt
420 xor rax, 1
421 mov [rdi], rax
422 ret
423
424;;;;;;;;;;;;;;;;;;;;;;
425; leq
426;;;;;;;;;;;;;;;;;;;;;;
427; Compares two elements of any kind
428; Params:
429; rsi <= Pointer to element 1
430; rdx <= Pointer to element 2
431; rdi <= Pointer to result can be zero or one.
432; Modified Registers:
433; rax, rcx
434;;;;;;;;;;;;;;;;;;;;;;
435<%=name%>_leq:
436 call <%=name%>_rgt
437 xor rax, 1
438 mov [rdi], rax
439 ret