arnaucube
arnaucube/circomPublic Self-hosted repository
circom/c/buildasm/neg.asm.ejs
c/buildasm/neg.asm.ejsRaw
 1<% function negS() { %>
 2        neg    eax
 3        jo     neg_manageOverflow   ; Check if overflow. (0x80000000 is the only case)
 4
 5        mov    [rdi], rax           ; not necessary to adjust so just save and return
 6        ret
 7
 8neg_manageOverflow:                 ; Do the operation in 64 bits
 9        push   rsi
10        movsx  rsi, eax
11        neg    rsi
12        call   rawCopyS2L
13        pop    rsi
14        ret
15<% } %>
16
17<% function negL() { %>
18        add rdi, 8
19        add rsi, 8
20        call rawNegL
21        sub rdi, 8
22        sub rsi, 8
23        ret
24<% } %>
25
26;;;;;;;;;;;;;;;;;;;;;;
27; neg
28;;;;;;;;;;;;;;;;;;;;;;
29; Adds two elements of any kind
30; Params:
31;   rsi <= Pointer to element to be negated
32;   rdi <= Pointer to result
33;   [rdi] = -[rsi]
34;;;;;;;;;;;;;;;;;;;;;;
35<%=name%>_neg:
36        mov    rax, [rsi]
37        bt     rax, 63          ; Check if is short first operand
38        jc     neg_l
39
40neg_s:                          ; Operand is short
41<%=     negS()       %>
42
43
44neg_l:
45        mov [rdi], rax          ; Copy the type
46<%=     negL()       %>
47
48
49;;;;;;;;;;;;;;;;;;;;;;
50; rawNeg
51;;;;;;;;;;;;;;;;;;;;;;
52; Negates a value
53; Params:
54;   rdi <= Pointer to the long data of result
55;   rsi <= Pointer to the long data of element 1
56;
57;   [rdi] = - [rsi]
58;;;;;;;;;;;;;;;;;;;;;;
59rawNegL:
60        ; Compare is zero
61
62        xor rax, rax
63<% for (let i=0; i<n64; i++) { %>
64        cmp [rsi + <%=i*8%>], rax
65        jnz doNegate
66<% } %>
67        ; it's zero so just set to zero
68<% for (let i=0; i<n64; i++) { %>
69        mov [rdi + <%=i*8%>], rax
70<% } %>
71        ret
72doNegate:
73<% for (let i=0; i<n64; i++) { %>
74        mov rax, [q + <%=i*8%>]
75        <%= i==0 ? "sub" : "sbb" %> rax, [rsi + <%=i*8%>]
76        mov [rdi + <%=i*8%>], rax
77<% } %>
78        ret