|
|
|
|
<% function isTrue(resReg, srcPtrReg) { %>
|
|
<% const longIsZero = global.tmpLabel() %>
|
|
<% const retOne = global.tmpLabel("retOne") %>
|
|
<% const retZero = global.tmpLabel("retZero") %>
|
|
<% const done = global.tmpLabel("done") %>
|
|
|
|
mov rax, [<%=srcPtrReg%>]
|
|
bt rax, 63
|
|
jc <%= longIsZero %>
|
|
|
|
test eax, eax
|
|
jz <%= retZero %>
|
|
jmp <%= retOne %>
|
|
|
|
<%= longIsZero %>:
|
|
<% for (let i=0; i<n64; i++) { %>
|
|
mov rax, [<%= srcPtrReg + " + " +(i*8+8) %>]
|
|
test rax, rax
|
|
jnz <%= retOne %>
|
|
<% } %>
|
|
|
|
<%= retZero %>:
|
|
mov qword <%=resReg%>, 0
|
|
jmp <%= done %>
|
|
|
|
<%= retOne %>:
|
|
mov qword <%=resReg%>, 1
|
|
|
|
<%= done %>:
|
|
<% } %>
|
|
|
|
|
|
|
|
|
|
<% function logicalOp(op) { %>
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; l<%= op %>
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; Logical <%= op %> between two elements
|
|
; Params:
|
|
; rsi <= Pointer to element 1
|
|
; rdx <= Pointer to element 2
|
|
; rdi <= Pointer to result zero or one
|
|
; Modified Registers:
|
|
; rax, rcx, r8
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
<%=name%>_l<%=op%>:
|
|
<%= isTrue("r8", "rsi") %>
|
|
<%= isTrue("rcx", "rdx") %>
|
|
<%=op%> rcx, r8
|
|
mov [rdi], rcx
|
|
ret
|
|
<% } %>
|
|
|
|
<% logicalOp("and"); %>
|
|
<% logicalOp("or"); %>
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; lnot
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; Do the logical not of an element
|
|
; Params:
|
|
; rsi <= Pointer to element to be tested
|
|
; rdi <= Pointer to result one if element1 is zero and zero otherwise
|
|
; Modified Registers:
|
|
; rax, rax, r8
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
<%=name%>_lnot:
|
|
<%= isTrue("rcx", "rsi") %>
|
|
test rcx, rcx
|
|
|
|
jz lnot_retOne
|
|
lnot_retZero:
|
|
mov qword [rdi], 0
|
|
ret
|
|
lnot_retOne:
|
|
mov qword [rdi], 1
|
|
ret
|
|
|
|
|