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