<% function binOpS1S2(op) { %>
|
|
cmp r8d, 0
|
|
<% const s1s2_solveNeg = global.tmpLabel() %>
|
|
js <%=s1s2_solveNeg%>
|
|
|
|
cmp r9d, 0
|
|
js <%=s1s2_solveNeg%>
|
|
xor rdx, rdx ; both ops are positive so do the op and return
|
|
mov edx, r8d
|
|
<%=op%> edx, r9d
|
|
mov [rdi], rdx ; not necessary to adjust so just save and return
|
|
ret
|
|
|
|
<%=s1s2_solveNeg%>:
|
|
<%= global.setTypeDest("0x80"); %>
|
|
<%= global.toLong_b() %>
|
|
<%= global.toLong_a() %>
|
|
<%= binOpL1L2(op) %>
|
|
|
|
|
|
<% } %>
|
|
|
|
<% function binOpS1L2(op) { %>
|
|
cmp r8d, 0
|
|
<% const s1l2_solveNeg = global.tmpLabel() %>
|
|
js <%=s1l2_solveNeg%>
|
|
movsx rax, r8d
|
|
<%=op%> rax, [rdx +8]
|
|
mov [rdi+8], rax
|
|
<% for (let i=1; i<n64; i++) { %>
|
|
xor rax, rax
|
|
<%=op%> rax, [rdx + <%= (i*8)+8 %>]
|
|
<% if (i== n64-1) { %>
|
|
and rax, [lboMask]
|
|
<% } %>
|
|
mov [rdi + <%= (i*8)+8 %> ], rax
|
|
<% } %>
|
|
ret
|
|
|
|
<%=s1l2_solveNeg%>:
|
|
<%= global.toLong_a() %>
|
|
<%= global.setTypeDest("0x80"); %>
|
|
<%= binOpL1L2(op) %>
|
|
|
|
<% } %>
|
|
|
|
<% function binOpL1S2(op) { %>
|
|
cmp r9d, 0
|
|
<% const l1s2_solveNeg = global.tmpLabel() %>
|
|
js <%=l1s2_solveNeg%>
|
|
movsx rax, r9d
|
|
<%=op%> rax, [rsi +8]
|
|
mov [rdi+8], rax
|
|
<% for (let i=1; i<n64; i++) { %>
|
|
xor rax, rax
|
|
<%=op%> rax, [rsi + <%= (i*8)+8 %>];
|
|
<% if (i== n64-1) { %>
|
|
and rax, [lboMask] ;
|
|
<% } %>
|
|
mov [rdi + <%= (i*8)+8 %> ], rax;
|
|
<% } %>
|
|
ret
|
|
|
|
<%=l1s2_solveNeg%>:
|
|
<%= global.toLong_b() %>
|
|
<%= global.setTypeDest("0x80"); %>
|
|
<%= binOpL1L2(op) %>
|
|
|
|
<% } %>
|
|
|
|
<% function binOpL1L2(op) { %>
|
|
<% for (let i=0; i<n64; i++) { %>
|
|
mov rax, [rsi + <%= (i*8)+8 %>]
|
|
<%=op%> rax, [rdx + <%= (i*8)+8 %>]
|
|
<% if (i== n64-1) { %>
|
|
and rax, [lboMask]
|
|
<% } %>
|
|
mov [rdi + <%= (i*8)+8 %> ], rax
|
|
<% } %>
|
|
ret
|
|
<% } %>
|
|
|
|
|
|
|
|
|
|
<% function binOp(op) { %>
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; b<%= op %>
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; Adds two elements of any kind
|
|
; Params:
|
|
; rsi <= Pointer to element 1
|
|
; rdx <= Pointer to element 2
|
|
; rdi <= Pointer to result
|
|
; Modified Registers:
|
|
; r8, r9, 10, r11, rax, rcx
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
<%=name%>_b<%=op%>:
|
|
mov r8, [rsi]
|
|
mov r9, [rdx]
|
|
bt r8, 63 ; Check if is short first operand
|
|
jc <%=op%>_l1
|
|
bt r9, 63 ; Check if is short second operand
|
|
jc <%=op%>_s1l2
|
|
|
|
<%=op%>_s1s2:
|
|
<%= binOpS1S2(op) %>
|
|
|
|
|
|
<%=op%>_l1:
|
|
bt r9, 63 ; Check if is short second operand
|
|
jc <%=op%>_l1l2
|
|
|
|
|
|
<%=op%>_l1s2:
|
|
bt r8, 62 ; check if montgomery first
|
|
jc <%=op%>_l1ms2
|
|
<%=op%>_l1ns2:
|
|
<%= global.setTypeDest("0x80"); %>
|
|
<%= binOpL1S2(op) %>
|
|
|
|
<%=op%>_l1ms2:
|
|
<%= global.setTypeDest("0x80"); %>
|
|
push r9 ; r9 is used in montgomery so we need to save it
|
|
<%= global.fromMont_a() %>
|
|
pop r9
|
|
<%= binOpL1S2(op) %>
|
|
|
|
|
|
<%=op%>_s1l2:
|
|
bt r9, 62 ; check if montgomery first
|
|
jc <%=op%>_s1l2m
|
|
<%=op%>_s1l2n:
|
|
<%= global.setTypeDest("0x80"); %>
|
|
<%= binOpS1L2(op) %>
|
|
|
|
<%=op%>_s1l2m:
|
|
<%= global.setTypeDest("0x80"); %>
|
|
push r8 ; r8 is used in montgomery so we need to save it
|
|
<%= global.fromMont_b() %>
|
|
pop r8
|
|
<%= binOpS1L2(op) %>
|
|
|
|
|
|
<%=op%>_l1l2:
|
|
bt r8, 62 ; check if montgomery first
|
|
jc <%=op%>_l1ml2
|
|
bt r9, 62 ; check if montgomery first
|
|
jc <%=op%>_l1nl2m
|
|
<%=op%>_l1nl2n:
|
|
<%= global.setTypeDest("0x80"); %>
|
|
<%= binOpL1L2(op) %>
|
|
|
|
<%=op%>_l1nl2m:
|
|
<%= global.setTypeDest("0x80"); %>
|
|
<%= global.fromMont_b() %>
|
|
<%= binOpL1L2(op) %>
|
|
|
|
<%=op%>_l1ml2:
|
|
bt r9, 62 ; check if montgomery first
|
|
jc <%=op%>_l1ml2m
|
|
<%=op%>_l1ml2n:
|
|
<%= global.setTypeDest("0x80"); %>
|
|
<%= global.fromMont_a() %>
|
|
<%= binOpL1L2(op) %>
|
|
|
|
<%=op%>_l1ml2m:
|
|
<%= global.setTypeDest("0x80"); %>
|
|
<%= global.fromMont_a() %>
|
|
<%= global.fromMont_b() %>
|
|
<%= binOpL1L2(op) %>
|
|
<% } %>
|
|
|
|
<%= binOp("and") %>
|
|
<%= binOp("or") %>
|
|
<%= binOp("xor") %>
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; bnot
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; Adds two elements of any kind
|
|
; Params:
|
|
; rsi <= Pointer to element 1
|
|
; rdi <= Pointer to result
|
|
; Modified Registers:
|
|
; r8, r9, 10, r11, rax, rcx
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
<%=name%>_bnot:
|
|
<%= global.setTypeDest("0x80"); %>
|
|
|
|
mov r8, [rsi]
|
|
bt r8, 63 ; Check if is long operand
|
|
jc bnot_l1
|
|
bnot_s:
|
|
<%= global.toLong_a() %>
|
|
jmp bnot_l1n
|
|
|
|
bnot_l1:
|
|
bt r8, 62 ; check if montgomery first
|
|
jnc bnot_l1n
|
|
|
|
bnot_l1m:
|
|
<%= global.fromMont_a() %>
|
|
|
|
bnot_l1n:
|
|
<% for (let i=0; i<n64; i++) { %>
|
|
mov rax, [rsi + <%= i*8 + 8 %>]
|
|
not rax
|
|
<% if (i== n64-1) { %>
|
|
and rax, [lboMask]
|
|
<% } %>
|
|
mov [rdi + <%= i*8 + 8 %>], rax
|
|
<% } %>
|
|
ret
|
|
|
|
|