<% 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 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 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 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 mov rax, [rsi + <%= i*8 + 8 %>] not rax <% if (i== n64-1) { %> and rax, [lboMask] <% } %> mov [rdi + <%= i*8 + 8 %>], rax <% } %> ret