2
; AMD64 mpn_add_n/mpn_sub_n -- mpn add or subtract.
4
; Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
6
; This file is part of the GNU MP Library.
8
; The GNU MP Library is free software; you can redistribute it and/or
9
; modify it under the terms of the GNU Lesser General Public License as
10
; published by the Free Software Foundation; either version 2.1 of the
11
; License, or (at your option) any later version.
13
; The GNU MP Library is distributed in the hope that it will be useful,
14
; but WITHOUT ANY WARRANTY; without even the implied warranty of
15
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
; Lesser General Public License for more details.
18
; You should have received a copy of the GNU Lesser General Public
19
; License along with the GNU MP Library; see the file COPYING.LIB. If
20
; not, write to the Free Software Foundation, Inc., 59 Temple Place -
21
; Suite 330, Boston, MA 02111-1307, USA.
23
; Adapted by Brian Gladman AMD64 using the Microsoft VC++ v8 64-bit
24
; compiler and the YASM assembler.
28
; mp_limb_t __gmpn_<op>_n( <op> = add OR sub
35
; mp_limb_t __gmpn_<op>_nc( <op> = add OR sub
40
; mp_limb_t carry [rsp+0x28]
43
; Calculate src1[size] plus(minus) src2[size] and store the result in
44
; dst[size]. The return value is the carry bit from the top of the result
45
; (1 or 0). The _nc version accepts 1 or 0 for an initial carry into the
46
; low limb of the calculation. Note values other than 1 or 0 here will
47
; lead to garbage results.
49
%define dst rcx ; destination pointer
50
%define sr1 rdx ; source 1 pointer
51
%define sr2 r8 ; source 2 pointer
52
%define len r9 ; number of limbs
53
%define cry [rsp+0x28] ; carry value
55
%define r_jmp r10 ; temporary for jump table entry
56
%define r_cnt r11 ; temporary for loop count
59
%define UNROLL_COUNT (1 << UNROLL_LOG2)
60
%define UNROLL_MASK (UNROLL_COUNT - 1)
61
%define UNROLL_BYTES (8 * UNROLL_COUNT)
62
%define UNROLL_THRESHOLD 8
64
%if UNROLL_BYTES >= 256
65
%error unroll count is too large
66
%elif UNROLL_BYTES >= 128
90
cmp len,UNROLL_THRESHOLD
114
shr r_cnt,UNROLL_LOG2
119
lea sr1,[sr1+len*8+off]
120
lea sr2,[sr2+len*8+off]
121
lea dst,[dst+len*8+off]
124
lea r_jmp,[r_jmp+r_jmp*2]
125
lea rax,[%%3 wrt rip]
126
lea r_jmp,[r_jmp+rax]
128
lea r_jmp,[r_jmp+r_jmp*2+%%3]
133
%define CHUNK_COUNT 2
136
%rep UNROLL_COUNT / CHUNK_COUNT
137
%assign disp0 8 * i * CHUNK_COUNT - off
139
mov r_jmp,[byte sr1+disp0] ; len and r_jmp registers
140
mov len,[byte sr1+disp0+8] ; now not needed
141
%2 r_jmp,[byte sr2+disp0]
142
mov [byte dst+disp0],r_jmp
143
%2 len,[byte sr2+disp0+8]
144
mov [byte dst+disp0+8],len
150
lea sr1,[sr1+UNROLL_BYTES]
151
lea sr2,[sr2+UNROLL_BYTES]
152
lea dst,[dst+UNROLL_BYTES]
170
mac_sub __g,adc,mpn_add_n,mpn_add_nc
171
mac_sub __g,sbb,mpn_sub_n,mpn_sub_nc