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