<% function negS() { %> neg eax jo neg_manageOverflow ; Check if overflow. (0x80000000 is the only case) mov [rdi], rax ; not necessary to adjust so just save and return ret neg_manageOverflow: ; Do the operation in 64 bits push rsi movsx rsi, eax neg rsi call rawCopyS2L pop rsi ret <% } %> <% function negL() { %> add rdi, 8 add rsi, 8 call rawNegL sub rdi, 8 sub rsi, 8 ret <% } %> ;;;;;;;;;;;;;;;;;;;;;; ; neg ;;;;;;;;;;;;;;;;;;;;;; ; Adds two elements of any kind ; Params: ; rsi <= Pointer to element to be negated ; rdi <= Pointer to result ; [rdi] = -[rsi] ;;;;;;;;;;;;;;;;;;;;;; <%=name%>_neg: mov rax, [rsi] bt rax, 63 ; Check if is short first operand jc neg_l neg_s: ; Operand is short <%= negS() %> neg_l: mov [rdi], rax ; Copy the type <%= negL() %> ;;;;;;;;;;;;;;;;;;;;;; ; rawNeg ;;;;;;;;;;;;;;;;;;;;;; ; Negates a value ; Params: ; rdi <= Pointer to the long data of result ; rsi <= Pointer to the long data of element 1 ; ; [rdi] = - [rsi] ;;;;;;;;;;;;;;;;;;;;;; rawNegL: ; Compare is zero xor rax, rax <% for (let i=0; i cmp [rsi + <%=i*8%>], rax jnz doNegate <% } %> ; it's zero so just set to zero <% for (let i=0; i mov [rdi + <%=i*8%>], rax <% } %> ret doNegate: <% for (let i=0; i mov rax, [q + <%=i*8%>] <%= i==0 ? "sub" : "sbb" %> rax, [rsi + <%=i*8%>] mov [rdi + <%=i*8%>], rax <% } %> ret