arnaucube
arnaucube/circomPublic Self-hosted repository
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