circom/ports/c/buildasm/neg.asm.ejs
ports/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