<% function subS1S2() { %>
|
|
xor rdx, rdx
|
|
mov edx, eax
|
|
sub edx, ecx
|
|
jo sub_manageOverflow ; rsi already is the 64bits result
|
|
|
|
mov [rdi], rdx ; not necessary to adjust so just save and return
|
|
ret
|
|
|
|
sub_manageOverflow: ; Do the operation in 64 bits
|
|
push rsi
|
|
movsx rsi, eax
|
|
movsx rdx, ecx
|
|
sub rsi, rdx
|
|
call rawCopyS2L
|
|
pop rsi
|
|
ret
|
|
<% } %>
|
|
|
|
<% function subL1S2(t) { %>
|
|
add rsi, 8
|
|
movsx rdx, ecx
|
|
add rdi, 8
|
|
cmp rdx, 0
|
|
<% const rawSubLabel = global.tmpLabel() %>
|
|
jns <%= rawSubLabel %>
|
|
neg rdx
|
|
call rawAddLS
|
|
sub rdi, 8
|
|
sub rsi, 8
|
|
ret
|
|
<%= rawSubLabel %>:
|
|
call rawSubLS
|
|
sub rdi, 8
|
|
sub rsi, 8
|
|
ret
|
|
<% } %>
|
|
|
|
|
|
<% function subS1L2(t) { %>
|
|
cmp eax, 0
|
|
<% const s1NegLabel = global.tmpLabel() %>
|
|
js <%= s1NegLabel %>
|
|
|
|
; First Operand is positive
|
|
push rsi
|
|
add rdi, 8
|
|
movsx rsi, eax
|
|
add rdx, 8
|
|
call rawSubSL
|
|
sub rdi, 8
|
|
pop rsi
|
|
ret
|
|
|
|
<%= s1NegLabel %>: ; First operand is negative
|
|
push rsi
|
|
lea rsi, [rdx + 8]
|
|
movsx rdx, eax
|
|
add rdi, 8
|
|
neg rdx
|
|
call rawNegLS
|
|
sub rdi, 8
|
|
pop rsi
|
|
ret
|
|
<% } %>
|
|
|
|
|
|
<% function subL1L2(t) { %>
|
|
add rdi, 8
|
|
add rsi, 8
|
|
add rdx, 8
|
|
call rawSubLL
|
|
sub rdi, 8
|
|
sub rsi, 8
|
|
ret
|
|
<% } %>
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; sub
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; Substracts 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%>_sub:
|
|
mov rax, [rsi]
|
|
mov rcx, [rdx]
|
|
bt rax, 63 ; Check if is long first operand
|
|
jc sub_l1
|
|
bt rcx, 63 ; Check if is long second operand
|
|
jc sub_s1l2
|
|
|
|
sub_s1s2: ; Both operands are short
|
|
<%= subS1S2() %>
|
|
sub_l1:
|
|
bt rcx, 63 ; Check if is short second operand
|
|
jc sub_l1l2
|
|
|
|
;;;;;;;;
|
|
sub_l1s2:
|
|
bt rax, 62 ; check if montgomery first
|
|
jc sub_l1ms2
|
|
sub_l1ns2:
|
|
<%= global.setTypeDest("0x80"); %>
|
|
<%= subL1S2(); %>
|
|
|
|
sub_l1ms2:
|
|
bt rcx, 62 ; check if montgomery second
|
|
jc sub_l1ms2m
|
|
sub_l1ms2n:
|
|
<%= global.setTypeDest("0xC0"); %>
|
|
<%= global.toMont_b() %>
|
|
<%= subL1L2() %>
|
|
|
|
sub_l1ms2m:
|
|
<%= global.setTypeDest("0xC0"); %>
|
|
<%= subL1L2() %>
|
|
|
|
|
|
;;;;;;;;
|
|
sub_s1l2:
|
|
bt rcx, 62 ; check if montgomery first
|
|
jc sub_s1l2m
|
|
sub_s1l2n:
|
|
<%= global.setTypeDest("0x80"); %>
|
|
<%= subS1L2(); %>
|
|
|
|
sub_s1l2m:
|
|
bt rax, 62 ; check if montgomery second
|
|
jc sub_s1ml2m
|
|
sub_s1nl2m:
|
|
<%= global.setTypeDest("0xC0"); %>
|
|
<%= global.toMont_a() %>
|
|
<%= subL1L2() %>
|
|
|
|
sub_s1ml2m:
|
|
<%= global.setTypeDest("0xC0"); %>
|
|
<%= subL1L2() %>
|
|
|
|
;;;;
|
|
sub_l1l2:
|
|
bt rax, 62 ; check if montgomery first
|
|
jc sub_l1ml2
|
|
sub_l1nl2:
|
|
bt rcx, 62 ; check if montgomery second
|
|
jc sub_l1nl2m
|
|
sub_l1nl2n:
|
|
<%= global.setTypeDest("0x80"); %>
|
|
<%= subL1L2() %>
|
|
|
|
sub_l1nl2m:
|
|
<%= global.setTypeDest("0xC0"); %>
|
|
<%= global.toMont_a(); %>
|
|
<%= subL1L2() %>
|
|
|
|
sub_l1ml2:
|
|
bt rcx, 62 ; check if montgomery seconf
|
|
jc sub_l1ml2m
|
|
sub_l1ml2n:
|
|
<%= global.setTypeDest("0xC0"); %>
|
|
<%= global.toMont_b(); %>
|
|
<%= subL1L2() %>
|
|
|
|
sub_l1ml2m:
|
|
<%= global.setTypeDest("0xC0"); %>
|
|
<%= subL1L2() %>
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; rawSubLS
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; Substracts a short element from the long element
|
|
; Params:
|
|
; rdi <= Pointer to the long data of result
|
|
; rsi <= Pointer to the long data of element 1 where will be substracted
|
|
; rdx <= Value to be substracted
|
|
; [rdi] = [rsi] - rdx
|
|
; Modified Registers:
|
|
; rax
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
rawSubLS:
|
|
; Substract first digit
|
|
|
|
mov rax, [rsi]
|
|
sub rax, rdx
|
|
mov [rdi] ,rax
|
|
mov rdx, 0
|
|
<% for (let i=1; i<n64; i++) { %>
|
|
mov rax, [rsi + <%=i*8%>]
|
|
sbb rax, rdx
|
|
mov [rdi + <%=i*8%>], rax
|
|
<% } %>
|
|
jnc rawSubLS_done ; if overflow, add q
|
|
|
|
; Add q
|
|
rawSubLS_aq:
|
|
<% for (let i=0; i<n64; i++) { %>
|
|
mov rax, [q + <%=i*8%>]
|
|
<%= i==0 ? "add" : "adc" %> [rdi + <%=i*8%>], rax
|
|
<% } %>
|
|
rawSubLS_done:
|
|
ret
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; rawSubSL
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; Substracts a long element from a short element
|
|
; Params:
|
|
; rdi <= Pointer to the long data of result
|
|
; rsi <= Value from where will bo substracted
|
|
; rdx <= Pointer to long of the value to be substracted
|
|
;
|
|
; [rdi] = rsi - [rdx]
|
|
; Modified Registers:
|
|
; rax
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
rawSubSL:
|
|
; Substract first digit
|
|
sub rsi, [rdx]
|
|
mov [rdi] ,rsi
|
|
|
|
<% for (let i=1; i<n64; i++) { %>
|
|
mov rax, 0
|
|
sbb rax, [rdx + <%=i*8%>]
|
|
mov [rdi + <%=i*8%>], rax
|
|
<% } %>
|
|
jnc rawSubSL_done ; if overflow, add q
|
|
|
|
; Add q
|
|
rawSubSL_aq:
|
|
<% for (let i=0; i<n64; i++) { %>
|
|
mov rax, [q + <%=i*8%>]
|
|
<%= i==0 ? "add" : "adc" %> [rdi + <%=i*8%>], rax
|
|
<% } %>
|
|
rawSubSL_done:
|
|
ret
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; rawSubLL
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; Substracts a long element from a short element
|
|
; Params:
|
|
; rdi <= Pointer to the long data of result
|
|
; rsi <= Pointer to long from where substracted
|
|
; rdx <= Pointer to long of the value to be substracted
|
|
;
|
|
; [rdi] = [rsi] - [rdx]
|
|
; Modified Registers:
|
|
; rax
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
rawSubLL:
|
|
; Substract first digit
|
|
<% for (let i=0; i<n64; i++) { %>
|
|
mov rax, [rsi + <%=i*8%>]
|
|
<%= i==0 ? "sub" : "sbb" %> rax, [rdx + <%=i*8%>]
|
|
mov [rdi + <%=i*8%>], rax
|
|
<% } %>
|
|
jnc rawSubLL_done ; if overflow, add q
|
|
|
|
; Add q
|
|
rawSubLL_aq:
|
|
<% for (let i=0; i<n64; i++) { %>
|
|
mov rax, [q + <%=i*8%>]
|
|
<%= i==0 ? "add" : "adc" %> [rdi + <%=i*8%>], rax
|
|
<% } %>
|
|
rawSubLL_done:
|
|
ret
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; rawNegLS
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; Substracts a long element and a short element form 0
|
|
; Params:
|
|
; rdi <= Pointer to the long data of result
|
|
; rsi <= Pointer to long from where substracted
|
|
; rdx <= short value to be substracted too
|
|
;
|
|
; [rdi] = -[rsi] - rdx
|
|
; Modified Registers:
|
|
; rax
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
rawNegLS:
|
|
mov rax, [q]
|
|
sub rax, rdx
|
|
mov [rdi], rax
|
|
<% for (let i=1; i<n64; i++) { %>
|
|
mov rax, [q + <%=i*8%> ]
|
|
sbb rax, 0
|
|
mov [rdi + <%=i*8%>], rax
|
|
<% } %>
|
|
setc dl
|
|
|
|
<% for (let i=0; i<n64; i++) { %>
|
|
mov rax, [rdi + <%=i*8%> ]
|
|
<%= i==0 ? "sub" : "sbb" %> rax, [rsi + <%=i*8%>]
|
|
mov [rdi + <%=i*8%>], rax
|
|
<% } %>
|
|
|
|
setc dh
|
|
or dl, dh
|
|
jz rawNegSL_done
|
|
|
|
; it is a negative value, so add q
|
|
<% for (let i=0; i<n64; i++) { %>
|
|
mov rax, [q + <%=i*8%>]
|
|
<%= i==0 ? "add" : "adc" %> [rdi + <%=i*8%>], rax
|
|
<% } %>
|
|
|
|
rawNegSL_done:
|
|
ret
|
|
|
|
|