|
|
<% 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<n64; i++) { %> cmp [rsi + <%=i*8%>], rax jnz doNegate <% } %> ; it's zero so just set to zero <% for (let i=0; i<n64; i++) { %> mov [rdi + <%=i*8%>], rax <% } %> ret doNegate: <% for (let i=0; i<n64; i++) { %> mov rax, [q + <%=i*8%>] <%= i==0 ? "sub" : "sbb" %> rax, [rsi + <%=i*8%>] mov [rdi + <%=i*8%>], rax <% } %> ret
|