circom/c/buildasm/logicalops.asm.ejs
c/buildasm/logicalops.asm.ejsRaw
1
2
3<% function isTrue(resReg, srcPtrReg) { %>
4<% const longIsZero = global.tmpLabel() %>
5<% const retOne = global.tmpLabel("retOne") %>
6<% const retZero = global.tmpLabel("retZero") %>
7<% const done = global.tmpLabel("done") %>
8
9 mov rax, [<%=srcPtrReg%>]
10 bt rax, 63
11 jc <%= longIsZero %>
12
13 test eax, eax
14 jz <%= retZero %>
15 jmp <%= retOne %>
16
17<%= longIsZero %>:
18<% for (let i=0; i<n64; i++) { %>
19 mov rax, [<%= srcPtrReg + " + " +(i*8+8) %>]
20 test rax, rax
21 jnz <%= retOne %>
22<% } %>
23
24<%= retZero %>:
25 mov qword <%=resReg%>, 0
26 jmp <%= done %>
27
28<%= retOne %>:
29 mov qword <%=resReg%>, 1
30
31<%= done %>:
32<% } %>
33
34
35
36
37<% function logicalOp(op) { %>
38;;;;;;;;;;;;;;;;;;;;;;
39; l<%= op %>
40;;;;;;;;;;;;;;;;;;;;;;
41; Logical <%= op %> between two elements
42; Params:
43; rsi <= Pointer to element 1
44; rdx <= Pointer to element 2
45; rdi <= Pointer to result zero or one
46; Modified Registers:
47; rax, rcx, r8
48;;;;;;;;;;;;;;;;;;;;;;
49<%=name%>_l<%=op%>:
50<%= isTrue("r8", "rsi") %>
51<%= isTrue("rcx", "rdx") %>
52 <%=op%> rcx, r8
53 mov [rdi], rcx
54 ret
55<% } %>
56
57<% logicalOp("and"); %>
58<% logicalOp("or"); %>
59
60;;;;;;;;;;;;;;;;;;;;;;
61; lnot
62;;;;;;;;;;;;;;;;;;;;;;
63; Do the logical not of an element
64; Params:
65; rsi <= Pointer to element to be tested
66; rdi <= Pointer to result one if element1 is zero and zero otherwise
67; Modified Registers:
68; rax, rax, r8
69;;;;;;;;;;;;;;;;;;;;;;
70<%=name%>_lnot:
71<%= isTrue("rcx", "rsi") %>
72 test rcx, rcx
73
74 jz lnot_retOne
75lnot_retZero:
76 mov qword [rdi], 0
77 ret
78lnot_retOne:
79 mov qword [rdi], 1
80 ret
81
82
83;;;;;;;;;;;;;;;;;;;;;;
84; isTrue
85;;;;;;;;;;;;;;;;;;;;;;
86; Convert a 64 bit integer to a long format field element
87; Params:
88; rsi <= Pointer to the element
89; Returs:
90; rax <= 1 if true 0 if false
91;;;;;;;;;;;;;;;;;;;;;;;
92<%=name%>_isTrue:
93 <%= isTrue("rax", "rdi") %>
94 ret
95
96
97