You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

317 lines
7.2 KiB

<% 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