Add Chromium-only Blender WebEngine parity work

This commit is contained in:
mes123456
2026-08-12 04:47:48 -04:00
commit 9fd26010f6
18225 changed files with 11622124 additions and 0 deletions

View File

@@ -0,0 +1,525 @@
Copyright 1999-2002 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/.
X86 MPN SUBROUTINES
This directory contains mpn functions for various 80x86 chips.
CODE ORGANIZATION
x86 i386, generic
x86/i486 i486
x86/pentium Intel Pentium (P5, P54)
x86/pentium/mmx Intel Pentium with MMX (P55)
x86/p6 Intel Pentium Pro
x86/p6/mmx Intel Pentium II, III
x86/p6/p3mmx Intel Pentium III
x86/k6 \ AMD K6
x86/k6/mmx /
x86/k6/k62mmx AMD K6-2
x86/k7 \ AMD Athlon
x86/k7/mmx /
x86/pentium4 \
x86/pentium4/mmx | Intel Pentium 4
x86/pentium4/sse2 /
The top-level x86 directory contains blended style code, meant to be
reasonable on all x86s.
STATUS
The code is well-optimized for AMD and Intel chips, but there's nothing
specific for Cyrix chips, nor for actual 80386 and 80486 chips.
ASM FILES
The x86 .asm files are BSD style assembler code, first put through m4 for
macro processing. The generic mpn/asm-defs.m4 is used, together with
mpn/x86/x86-defs.m4. See comments in those files.
The code is meant for use with GNU "gas" or a system "as". There's no
support for assemblers that demand Intel style code.
STACK FRAME
m4 macros are used to define the parameters passed on the stack, and these
act like comments on what the stack frame looks like too. For example,
mpn_mul_1() has the following.
defframe(PARAM_MULTIPLIER, 16)
defframe(PARAM_SIZE, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
PARAM_MULTIPLIER becomes `FRAME+16(%esp)', and the others similarly. The
return address is at offset 0, but there's not normally any need to access
that.
FRAME is redefined as necessary through the code so it's the number of bytes
pushed on the stack, and hence the offsets in the parameter macros stay
correct. At the start of a routine FRAME should be zero.
deflit(`FRAME',0)
...
deflit(`FRAME',4)
...
deflit(`FRAME',8)
...
Helper macros FRAME_pushl(), FRAME_popl(), FRAME_addl_esp() and
FRAME_subl_esp() exist to adjust FRAME for the effect of those instructions,
and can be used instead of explicit definitions if preferred.
defframe_pushl() is a combination FRAME_pushl() and defframe().
There's generally some slackness in redefining FRAME. If new values aren't
going to get used then the redefinitions are omitted to keep from cluttering
up the code. This happens for instance at the end of a routine, where there
might be just four pops and then a ret, so FRAME isn't getting used.
Local variables and saved registers can be similarly defined, with negative
offsets representing stack space below the initial stack pointer. For
example,
defframe(SAVE_ESI, -4)
defframe(SAVE_EDI, -8)
defframe(VAR_COUNTER,-12)
deflit(STACK_SPACE, 12)
Here STACK_SPACE gets used in a "subl $STACK_SPACE, %esp" to allocate the
space, and that instruction must be followed by a redefinition of FRAME
(setting it equal to STACK_SPACE) to reflect the change in %esp.
Definitions for pushed registers are only put in when they're going to be
used. If registers are just saved and restored with pushes and pops then
definitions aren't made.
ASSEMBLER EXPRESSIONS
Only addition and subtraction seem to be universally available, certainly
that's all the Solaris 8 "as" seems to accept. If expressions are wanted
then m4 eval() should be used.
In particular note that a "/" anywhere in a line starts a comment in Solaris
"as", and in some configurations of gas too.
addl $32/2, %eax <-- wrong
addl $eval(32/2), %eax <-- right
Binutils gas/config/tc-i386.c has a choice between "/" being a comment
anywhere in a line, or only at the start. FreeBSD patches 2.9.1 to select
the latter, and from 2.9.5 it's the default for GNU/Linux too.
ASSEMBLER COMMENTS
Solaris "as" doesn't support "#" commenting, using /* */ instead. For that
reason "C" commenting is used (see asm-defs.m4) and the intermediate ".s"
files have no comments.
Any comments before include(`../config.m4') must use m4 "dnl", since it's
only after the include that "C" is available. By convention "dnl" is also
used for comments about m4 macros.
TEMPORARY LABELS
Temporary numbered labels like "1:" used as "1f" or "1b" are available in
"gas" and Solaris "as", but not in SCO "as". Normal L() labels should be
used instead, possibly with a counter to make them unique, see jadcl0() in
x86-defs.m4 for instance. A separate counter for each macro makes it
possible to nest them, for instance movl_text_address() can be used within
an ASSERT().
"1:" etc must be avoided in gcc __asm__ blocks too. "%=" for generating a
unique number looks like a good alternative, but is that actually a
documented feature? In any case this problem doesn't currently arise.
ZERO DISPLACEMENTS
In a couple of places addressing modes like 0(%ebx) with a byte-sized zero
displacement are wanted, rather than (%ebx) with no displacement. These are
either for computed jumps or to get desirable code alignment. Explicit
.byte sequences are used to ensure the assembler doesn't turn 0(%ebx) into
(%ebx). The Zdisp() macro in x86-defs.m4 is used for this.
Current gas 2.9.5 or recent 2.9.1 leave 0(%ebx) as written, but old gas
1.92.3 changes it. In general changing would be the sort of "optimization"
an assembler might perform, hence explicit ".byte"s are used where
necessary.
SHLD/SHRD INSTRUCTIONS
The %cl count forms of double shift instructions like "shldl %cl,%eax,%ebx"
must be written "shldl %eax,%ebx" for some assemblers. gas takes either,
Solaris "as" doesn't allow %cl, gcc generates %cl for gas and NeXT (which is
gas), and omits %cl elsewhere.
For GMP an autoconf test GMP_ASM_X86_SHLDL_CL is used to determine whether
%cl should be used, and the macros shldl, shrdl, shldw and shrdw in
mpn/x86/x86-defs.m4 pass through or omit %cl as necessary. See the comments
with those macros for usage.
IMUL INSTRUCTION
GCC config/i386/i386.md (cvs rev 1.187, 21 Oct 00) under *mulsi3_1 notes
that the following two forms produce identical object code
imul $12, %eax
imul $12, %eax, %eax
but that the former isn't accepted by some assemblers, in particular the SCO
OSR5 COFF assembler. GMP follows GCC and uses only the latter form.
(This applies only to immediate operands, the three operand form is only
valid with an immediate.)
DIRECTION FLAG
The x86 calling conventions say that the direction flag should be clear at
function entry and exit. (See iBCS2 and SVR4 ABI books, references below.)
Although this has been so since the year dot, it's not absolutely clear
whether it's universally respected. Since it's better to be safe than
sorry, GMP follows glibc and does a "cld" if it depends on the direction
flag being clear. This happens only in a few places.
POSITION INDEPENDENT CODE
Coding Style
Defining the symbol PIC in m4 processing selects SVR4 / ELF style
position independent code. This is necessary for shared libraries
because they can be mapped into different processes at different virtual
addresses. Actually, relocations are allowed but text pages with
relocations aren't shared, defeating the purpose of a shared library.
The GOT is used to access global data, and the PLT is used for
functions. The use of the PLT adds a fixed cost to every function call,
and the GOT adds a cost to any function accessing global variables.
These are small but might be noticeable when working with small
operands.
Scope
It's intended, as a matter of policy, that references within libgmp are
resolved within libgmp. Certainly there's no need for an application to
replace any internals, and we take the view that there's no value in an
application subverting anything documented either.
Resolving references within libgmp in theory means calls can be made with a
plain PC-relative call instruction, which is faster and smaller than going
through the PLT, and data references can be similarly PC-relative, saving a
GOT entry and fetch from there. Unfortunately the normal linker behaviour
doesn't allow us to do this.
By default an R_386_PC32 PC-relative reference, either for a call or for
data, is left in libgmp.so by the linker so that it can be resolved at
runtime to a location in the application or another shared library. This
means a text segment relocation which we don't want.
-Bsymbolic
Under the "-Bsymbolic" option, the linker resolves references to symbols
within libgmp.so. This gives us the desired effect for R_386_PC32,
ie. it's resolved at link time. It also resolves R_386_PLT32 calls
directly to their target without creating a PLT entry (though if this is
done to normal compiler-generated code it still leaves a setup of %ebx
to _GLOBAL_OFFSET_TABLE_ which may then be unnecessary).
Unfortunately -Bsymbolic does bad things to global variables defined in
a shared library but accessed by non-PIC code from the mainline (or a
static library).
The problem is that the mainline needs a fixed data address to avoid
text segment relocations, so space is allocated in its data segment and
the value from the variable is copied from the shared library's data
segment when the library is loaded. Under -Bsymbolic, however,
references in the shared library are then resolved still to the shared
library data area. Not surprisingly it bombs badly to have mainline
code and library code accessing different locations for what should be
one variable.
Note that this -Bsymbolic effect for the shared library is not just for
R_386_PC32 offsets which might have been cooked up in assembler, but is
done also for the contents of GOT entries. -Bsymbolic simply applies a
general rule that symbols are resolved first from the local module.
Visibility Attributes
GCC __attribute__ ((visibility ("protected"))), which is available in
recent versions, eg. 3.3, is probably what we'd like to use. It makes
gcc generate plain PC-relative calls to indicated functions, and directs
the linker to resolve references to the given function within the link
module.
Unfortunately, as of debian binutils 2.13.90.0.16 at least, the
resulting libgmp.so comes out with text segment relocations, references
are not resolved at link time. If the gcc description is to be believed
this is this not how it should work. If a symbol cannot be overridden
by another module then surely references within that module can be
resolved immediately (ie. at link time).
Present
In any case, all this means that we have no optimizations we can
usefully make to function or variable usages, neither for assembler nor
C code. Perhaps in the future the visibility attribute will work as
we'd like.
GLOBAL OFFSET TABLE
The magic _GLOBAL_OFFSET_TABLE_ used by code establishing the address of the
GOT sometimes requires an extra underscore prefix. SVR4 systems and NetBSD
don't need a prefix, OpenBSD does need one. Note that NetBSD and OpenBSD
are both a.out underscore systems, so the prefix for _GLOBAL_OFFSET_TABLE_
is not simply the same as the prefix for ordinary globals.
In any case in the asm code we write _GLOBAL_OFFSET_TABLE_ and let a macro
in x86-defs.m4 add an extra underscore if required (according to a configure
test).
Old gas 1.92.3 which comes with FreeBSD 2.2.8 gets a segmentation fault when
asked to assemble the following,
L1:
addl $_GLOBAL_OFFSET_TABLE_+[.-L1], %ebx
It seems that using the label in the same instruction it refers to is the
problem, since a nop in between works. But the simplest workaround is to
follow gcc and omit the +[.-L1] since it does nothing,
addl $_GLOBAL_OFFSET_TABLE_, %ebx
Current gas 2.10 generates incorrect object code when %eax is used in such a
construction (with or without +[.-L1]),
addl $_GLOBAL_OFFSET_TABLE_, %eax
The R_386_GOTPC gets a displacement of 2 rather than the 1 appropriate for
the 1 byte opcode of "addl $n,%eax". The best workaround is just to use any
other register, since then it's a two byte opcode+mod/rm. GCC for example
always uses %ebx (which is needed for calls through the PLT).
A similar problem occurs in an leal (again with or without a +[.-L1]),
leal _GLOBAL_OFFSET_TABLE_(%edi), %ebx
This time the R_386_GOTPC gets a displacement of 0 rather than the 2
appropriate for the opcode and mod/rm, making this form unusable.
SIMPLE LOOPS
The overheads in setting up for an unrolled loop can mean that at small
sizes a simple loop is faster. Making small sizes go fast is important,
even if it adds a cycle or two to bigger sizes. To this end various
routines choose between a simple loop and an unrolled loop according to
operand size. The path to the simple loop, or to special case code for
small sizes, is always as fast as possible.
Adding a simple loop requires a conditional jump to choose between the
simple and unrolled code. The size of a branch misprediction penalty
affects whether a simple loop is worthwhile.
The convention is for an m4 definition UNROLL_THRESHOLD to set the crossover
point, with sizes < UNROLL_THRESHOLD using the simple loop, sizes >=
UNROLL_THRESHOLD using the unrolled loop. If position independent code adds
a couple of cycles to an unrolled loop setup, the threshold will vary with
PIC or non-PIC. Something like the following is typical.
deflit(UNROLL_THRESHOLD, ifdef(`PIC',10,8))
There's no automated way to determine the threshold. Setting it to a small
value and then to a big value makes it possible to measure the simple and
unrolled loops each over a range of sizes, from which the crossover point
can be determined. Alternately, just adjust the threshold up or down until
there's no more speedups.
UNROLLED LOOP CODING
The x86 addressing modes allow a byte displacement of -128 to +127, making
it possible to access 256 bytes, which is 64 limbs, without adjusting
pointer registers within the loop. Dword sized displacements can be used
too, but they increase code size, and unrolling to 64 ought to be enough.
When unrolling to the full 64 limbs/loop, the limb at the top of the loop
will have a displacement of -128, so pointers have to have a corresponding
+128 added before entering the loop. When unrolling to 32 limbs/loop
displacements 0 to 127 can be used with 0 at the top of the loop and no
adjustment needed to the pointers.
Where 64 limbs/loop is supported, the +128 adjustment is done only when 64
limbs/loop is selected. Usually the gain in speed using 64 instead of 32 or
16 is small, so support for 64 limbs/loop is generally only for comparison.
COMPUTED JUMPS
When working from least significant limb to most significant limb (most
routines) the computed jump and pointer calculations in preparation for an
unrolled loop are as follows.
S = operand size in limbs
N = number of limbs per loop (UNROLL_COUNT)
L = log2 of unrolling (UNROLL_LOG2)
M = mask for unrolling (UNROLL_MASK)
C = code bytes per limb in the loop
B = bytes per limb (4 for x86)
computed jump (-S & M) * C + entrypoint
subtract from pointers (-S & M) * B
initial loop counter (S-1) >> L
displacements 0 to B*(N-1)
The loop counter is decremented at the end of each loop, and the looping
stops when the decrement takes the counter to -1. The displacements are for
the addressing accessing each limb, eg. a load with "movl disp(%ebx), %eax".
Usually the multiply by "C" can be handled without an imul, using instead an
leal, or a shift and subtract.
When working from most significant to least significant limb (eg. mpn_lshift
and mpn_copyd), the calculations change as follows.
add to pointers (-S & M) * B
displacements 0 to -B*(N-1)
OLD GAS 1.92.3
This version comes with FreeBSD 2.2.8 and has a couple of gremlins that
affect GMP code.
Firstly, an expression involving two forward references to labels comes out
as zero. For example,
addl $bar-foo, %eax
foo:
nop
bar:
This should lead to "addl $1, %eax", but it comes out as "addl $0, %eax".
When only one forward reference is involved, it works correctly, as for
example,
foo:
addl $bar-foo, %eax
nop
bar:
Secondly, an expression involving two labels can't be used as the
displacement for an leal. For example,
foo:
nop
bar:
leal bar-foo(%eax,%ebx,8), %ecx
A slightly cryptic error is given, "Unimplemented segment type 0 in
parse_operand". When only one label is used it's ok, and the label can be a
forward reference too, as for example,
leal foo(%eax,%ebx,8), %ecx
nop
foo:
These problems only affect PIC computed jump calculations. The workarounds
are just to do an leal without a displacement and then an addl, and to make
sure the code is placed so that there's at most one forward reference in the
addl.
REFERENCES
"Intel Architecture Software Developer's Manual", volumes 1, 2a, 2b, 3a, 3b,
2006, order numbers 253665 through 253669. Available on-line,
ftp://download.intel.com/design/Pentium4/manuals/25366518.pdf
ftp://download.intel.com/design/Pentium4/manuals/25366618.pdf
ftp://download.intel.com/design/Pentium4/manuals/25366718.pdf
ftp://download.intel.com/design/Pentium4/manuals/25366818.pdf
ftp://download.intel.com/design/Pentium4/manuals/25366918.pdf
"System V Application Binary Interface", Unix System Laboratories Inc, 1992,
published by Prentice Hall, ISBN 0-13-880410-9. And the "Intel386 Processor
Supplement", AT&T, 1991, ISBN 0-13-877689-X. These have details of calling
conventions and ELF shared library PIC coding. Versions of both available
on-line,
http://www.sco.com/developer/devspecs
"Intel386 Family Binary Compatibility Specification 2", Intel Corporation,
published by McGraw-Hill, 1991, ISBN 0-07-031219-2. (Same as the above 386
ABI supplement.)
----------------
Local variables:
mode: text
fill-column: 76
End:

View File

@@ -0,0 +1,202 @@
dnl x86 mpn_add_n/mpn_sub_n -- mpn addition and subtraction.
dnl Copyright 1992, 1994-1996, 1999-2002 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C P5 3.375
C P6 3.125
C K6 3.5
C K7 2.25
C P4 8.75
ifdef(`OPERATION_add_n',`
define(M4_inst, adcl)
define(M4_function_n, mpn_add_n)
define(M4_function_nc, mpn_add_nc)
',`ifdef(`OPERATION_sub_n',`
define(M4_inst, sbbl)
define(M4_function_n, mpn_sub_n)
define(M4_function_nc, mpn_sub_nc)
',`m4_error(`Need OPERATION_add_n or OPERATION_sub_n
')')')
MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
C mp_limb_t M4_function_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size);
C mp_limb_t M4_function_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size, mp_limb_t carry);
defframe(PARAM_CARRY,20)
defframe(PARAM_SIZE, 16)
defframe(PARAM_SRC2, 12)
defframe(PARAM_SRC1, 8)
defframe(PARAM_DST, 4)
TEXT
ALIGN(8)
PROLOGUE(M4_function_nc)
deflit(`FRAME',0)
pushl %edi FRAME_pushl()
pushl %esi FRAME_pushl()
movl PARAM_DST,%edi
movl PARAM_SRC1,%esi
movl PARAM_SRC2,%edx
movl PARAM_SIZE,%ecx
movl %ecx,%eax
shrl $3,%ecx C compute count for unrolled loop
negl %eax
andl $7,%eax C get index where to start loop
jz L(oopgo) C necessary special case for 0
incl %ecx C adjust loop count
shll $2,%eax C adjustment for pointers...
subl %eax,%edi C ... since they are offset ...
subl %eax,%esi C ... by a constant when we ...
subl %eax,%edx C ... enter the loop
shrl $2,%eax C restore previous value
ifdef(`PIC',`
C Calculate start address in loop for PIC. Due to limitations in
C old gas, LF(M4_function_n,oop)-L(0a)-3 cannot be put into the leal
call L(0a)
L(0a): leal (%eax,%eax,8),%eax
addl (%esp),%eax
addl $L(oop)-L(0a)-3,%eax
addl $4,%esp
',`
C Calculate start address in loop for non-PIC.
leal L(oop)-3(%eax,%eax,8),%eax
')
C These lines initialize carry from the 5th parameter. Should be
C possible to simplify.
pushl %ebp FRAME_pushl()
movl PARAM_CARRY,%ebp
shrl %ebp C shift bit 0 into carry
popl %ebp FRAME_popl()
jmp *%eax C jump into loop
EPILOGUE()
ALIGN(16)
PROLOGUE(M4_function_n)
deflit(`FRAME',0)
pushl %edi FRAME_pushl()
pushl %esi FRAME_pushl()
movl PARAM_DST,%edi
movl PARAM_SRC1,%esi
movl PARAM_SRC2,%edx
movl PARAM_SIZE,%ecx
movl %ecx,%eax
shrl $3,%ecx C compute count for unrolled loop
negl %eax
andl $7,%eax C get index where to start loop
jz L(oop) C necessary special case for 0
incl %ecx C adjust loop count
shll $2,%eax C adjustment for pointers...
subl %eax,%edi C ... since they are offset ...
subl %eax,%esi C ... by a constant when we ...
subl %eax,%edx C ... enter the loop
shrl $2,%eax C restore previous value
ifdef(`PIC',`
C Calculate start address in loop for PIC. Due to limitations in
C some assemblers, L(oop)-L(0b)-3 cannot be put into the leal
call L(0b)
L(0b): leal (%eax,%eax,8),%eax
addl (%esp),%eax
addl $L(oop)-L(0b)-3,%eax
addl $4,%esp
',`
C Calculate start address in loop for non-PIC.
leal L(oop)-3(%eax,%eax,8),%eax
')
jmp *%eax C jump into loop
L(oopgo):
pushl %ebp FRAME_pushl()
movl PARAM_CARRY,%ebp
shrl %ebp C shift bit 0 into carry
popl %ebp FRAME_popl()
ALIGN(16)
L(oop): movl (%esi),%eax
M4_inst (%edx),%eax
movl %eax,(%edi)
movl 4(%esi),%eax
M4_inst 4(%edx),%eax
movl %eax,4(%edi)
movl 8(%esi),%eax
M4_inst 8(%edx),%eax
movl %eax,8(%edi)
movl 12(%esi),%eax
M4_inst 12(%edx),%eax
movl %eax,12(%edi)
movl 16(%esi),%eax
M4_inst 16(%edx),%eax
movl %eax,16(%edi)
movl 20(%esi),%eax
M4_inst 20(%edx),%eax
movl %eax,20(%edi)
movl 24(%esi),%eax
M4_inst 24(%edx),%eax
movl %eax,24(%edi)
movl 28(%esi),%eax
M4_inst 28(%edx),%eax
movl %eax,28(%edi)
leal 32(%edi),%edi
leal 32(%esi),%esi
leal 32(%edx),%edx
decl %ecx
jnz L(oop)
sbbl %eax,%eax
negl %eax
popl %esi
popl %edi
ret
EPILOGUE()

View File

@@ -0,0 +1,214 @@
dnl x86 __gmpn_addmul_1 (for 386 and 486) -- Multiply a limb vector with a
dnl limb and add the result to a second limb vector.
dnl Copyright 1992, 1994, 1997, 1999-2002, 2005 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C P5
C P6 model 0-8,10-12
C P6 model 9 (Banias)
C P6 model 13 (Dothan)
C P4 model 0 (Willamette)
C P4 model 1 (?)
C P4 model 2 (Northwood)
C P4 model 3 (Prescott)
C P4 model 4 (Nocona)
C Intel Atom
C AMD K6
C AMD K7
C AMD K8 3.875
C AMD K10
ifdef(`OPERATION_addmul_1',`
define(ADDSUB, addl)
define(M4_function_1, mpn_addmul_1)
define(M4_function_1c, mpn_addmul_1c)
',`ifdef(`OPERATION_submul_1',`
define(ADDSUB, subl)
define(M4_function_1, mpn_submul_1)
',`m4_error(`Need OPERATION_addmul_1 or OPERATION_submul_1
')')')
MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1 mpn_addmul_1c)
C mp_limb_t M4_function_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
C mp_limb_t mult);
define(PARAM_CARRY, `FRAME+20(%esp)')
define(PARAM_MULTIPLIER, `FRAME+16(%esp)')
define(PARAM_SIZE, `FRAME+12(%esp)')
define(PARAM_SRC, `FRAME+8(%esp)')
define(PARAM_DST, `FRAME+4(%esp)')
TEXT
ALIGN(32)
PROLOGUE(M4_function_1)
deflit(`FRAME',0)
pushl %edi
pushl %esi
pushl %ebx
pushl %ebp
deflit(`FRAME',16)
movl PARAM_SRC, %esi
movl PARAM_SIZE, %ecx
movl PARAM_DST, %edi
movl (%esi), %eax
mull PARAM_MULTIPLIER
testb $1, %cl
jnz L(bx1)
L(bx0): movl %eax, %ebx
movl %edx, %ebp
shrl $2, %ecx
jnc L(lo0)
L(b10): leal -8(%esi), %esi
leal -8(%edi), %edi
incl %ecx
jmp L(lo2)
L(bx1): movl %eax, %ebp
movl %edx, %ebx
shrl $2, %ecx
jc L(b11)
L(b01): leal 4(%edi), %edi
jz L(end)
leal 4(%esi), %esi
jmp L(top)
L(b11): leal -4(%esi), %esi
leal -4(%edi), %edi
incl %ecx
jmp L(lo3)
ALIGN(16)
L(top): movl (%esi), %eax
mull PARAM_MULTIPLIER
ADDSUB %ebp, -4(%edi)
adcl %eax, %ebx
movl $0, %ebp
adcl %edx, %ebp
L(lo0): movl 4(%esi), %eax
mull PARAM_MULTIPLIER
ADDSUB %ebx, (%edi)
adcl %eax, %ebp
movl $0, %ebx
adcl %edx, %ebx
L(lo3): movl 8(%esi), %eax
mull PARAM_MULTIPLIER
ADDSUB %ebp, 4(%edi)
adcl %eax, %ebx
movl $0, %ebp
adcl %edx, %ebp
L(lo2): movl 12(%esi), %eax
mull PARAM_MULTIPLIER
ADDSUB %ebx, 8(%edi)
adcl %eax, %ebp
movl $0, %ebx
adcl %edx, %ebx
leal 16(%esi), %esi
leal 16(%edi), %edi
decl %ecx
jnz L(top)
L(end): xor %eax, %eax
ADDSUB %ebp, -4(%edi)
adcl %ebx, %eax
popl %ebp
popl %ebx
popl %esi
popl %edi
ret
EPILOGUE()
ifdef(`OPERATION_addmul_1',`
ALIGN(32)
PROLOGUE(M4_function_1c)
deflit(`FRAME',0)
pushl %edi
pushl %esi
pushl %ebx
pushl %ebp
deflit(`FRAME',16)
movl PARAM_SRC, %esi
movl PARAM_SIZE, %ecx
movl PARAM_DST, %edi
movl (%esi), %eax
mull PARAM_MULTIPLIER
testb $1, %cl
jnz L(cx1)
movl PARAM_CARRY, %ebx
xorl %ebp, %ebp
L(cx0): addl %eax, %ebx
adcl %edx, %ebp
shrl $2, %ecx
jnc L(lo0)
L(c10): leal -8(%esi), %esi
leal -8(%edi), %edi
incl %ecx
jmp L(lo2)
L(cx1): movl PARAM_CARRY, %ebp
xorl %ebx, %ebx
addl %eax, %ebp
adcl %edx, %ebx
shrl $2, %ecx
jc L(c11)
L(c01): leal 4(%edi), %edi
jz L(end)
leal 4(%esi), %esi
jmp L(top)
L(c11): leal -4(%esi), %esi
leal -4(%edi), %edi
incl %ecx
jmp L(lo3)
EPILOGUE()
')

View File

@@ -0,0 +1,53 @@
dnl Intel Atom mpn_rsblsh1_n -- rp[] = (vp[] << 1) - up[]
dnl Contributed to the GNU project by Marco Bodrato.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
define(LSH, 1)
define(RSH, 31)
ifdef(`OPERATION_addlsh1_n', `
define(M4_inst, adc)
define(M4_opp, sub)
define(M4_function, mpn_addlsh1_n)
define(M4_function_c, mpn_addlsh1_nc)
',`ifdef(`OPERATION_rsblsh1_n', `
define(M4_inst, sbb)
define(M4_opp, add)
define(M4_function, mpn_rsblsh1_n)
define(M4_function_c, mpn_rsblsh1_nc)
',`m4_error(`Need OPERATION_addlsh1_n or OPERATION_rsblsh1_n
')')')
MULFUNC_PROLOGUE(mpn_addlsh1_n mpn_addlsh1_nc mpn_rsblsh1_n mpn_rsblsh1_nc)
include_mpn(`x86/atom/aorrlshC_n.asm')

View File

@@ -0,0 +1,53 @@
dnl Intel Atom mpn_addlsh2_n/mpn_rsblsh2_n -- rp[] = (vp[] << 2) +- up[]
dnl Contributed to the GNU project by Marco Bodrato.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
define(LSH, 2)
define(RSH, 30)
ifdef(`OPERATION_addlsh2_n', `
define(M4_inst, adcl)
define(M4_opp, subl)
define(M4_function, mpn_addlsh2_n)
define(M4_function_c, mpn_addlsh2_nc)
',`ifdef(`OPERATION_rsblsh2_n', `
define(M4_inst, sbbl)
define(M4_opp, addl)
define(M4_function, mpn_rsblsh2_n)
define(M4_function_c, mpn_rsblsh2_nc)
',`m4_error(`Need OPERATION_addlsh2_n or OPERATION_rsblsh2_n
')')')
MULFUNC_PROLOGUE(mpn_addlsh2_n mpn_addlsh2_nc mpn_rsblsh2_n mpn_rsblsh2_nc)
include_mpn(`x86/atom/aorrlshC_n.asm')

View File

@@ -0,0 +1,156 @@
dnl Intel Atom mpn_addlshC_n/mpn_rsblshC_n -- rp[] = (vp[] << C) +- up[]
dnl Contributed to the GNU project by Marco Bodrato.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C mp_limb_t mpn_addlshC_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size);
C mp_limb_t mpn_addlshC_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size, mp_limb_t carry);
C mp_limb_t mpn_rsblshC_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size);
C mp_limb_t mpn_rsblshC_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size, mp_signed_limb_t carry);
C cycles/limb
C P5
C P6 model 0-8,10-12
C P6 model 9 (Banias)
C P6 model 13 (Dothan)
C P4 model 0 (Willamette)
C P4 model 1 (?)
C P4 model 2 (Northwood)
C P4 model 3 (Prescott)
C P4 model 4 (Nocona)
C Intel Atom 6
C AMD K6
C AMD K7
C AMD K8
C AMD K10
defframe(PARAM_CORB, 20)
defframe(PARAM_SIZE, 16)
defframe(PARAM_DBLD, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
dnl re-use parameter space
define(VAR_COUNT,`PARAM_SIZE')
define(SAVE_EBP,`PARAM_DBLD')
define(SAVE_VP,`PARAM_SRC')
define(SAVE_UP,`PARAM_DST')
define(M, eval(m4_lshift(1,LSH)))
define(`rp', `%edi')
define(`up', `%esi')
define(`vp', `%ebx')
ASM_START()
TEXT
ALIGN(8)
PROLOGUE(M4_function_c)
deflit(`FRAME',0)
movl PARAM_CORB, %eax
movl %eax, %edx
shr $LSH, %edx
andl $1, %edx
M4_opp %edx, %eax
jmp L(start_nc)
EPILOGUE()
PROLOGUE(M4_function)
deflit(`FRAME',0)
xor %eax, %eax
xor %edx, %edx
L(start_nc):
push rp FRAME_pushl()
mov PARAM_SIZE, %ecx C size
mov PARAM_DST, rp
mov up, SAVE_UP
incl %ecx C size + 1
mov PARAM_SRC, up
mov vp, SAVE_VP
shr %ecx C (size+1)\2
mov PARAM_DBLD, vp
mov %ebp, SAVE_EBP
mov %ecx, VAR_COUNT
jnc L(entry) C size odd
shr %edx C size even
mov (vp), %ecx
lea 4(vp), vp
lea (%eax,%ecx,M), %edx
mov %ecx, %eax
lea -4(up), up
lea -4(rp), rp
jmp L(enteven)
ALIGN(16)
L(oop):
lea (%eax,%ecx,M), %ebp
shr $RSH, %ecx
mov 4(vp), %eax
shr %edx
lea 8(vp), vp
M4_inst (up), %ebp
lea (%ecx,%eax,M), %edx
mov %ebp, (rp)
L(enteven):
M4_inst 4(up), %edx
lea 8(up), up
mov %edx, 4(rp)
adc %edx, %edx
shr $RSH, %eax
lea 8(rp), rp
L(entry):
mov (vp), %ecx
decl VAR_COUNT
jnz L(oop)
lea (%eax,%ecx,M), %ebp
shr $RSH, %ecx
shr %edx
mov SAVE_VP, vp
M4_inst (up), %ebp
mov %ecx, %eax
mov SAVE_UP, up
M4_inst $0, %eax
mov %ebp, (rp)
mov SAVE_EBP, %ebp
pop rp FRAME_popl()
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,159 @@
dnl Intel Atom mpn_add_n/mpn_sub_n -- rp[] = up[] +- vp[].
dnl Copyright 2011 Free Software Foundation, Inc.
dnl Contributed to the GNU project by Marco Bodrato.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C P5
C P6 model 0-8,10-12
C P6 model 9 (Banias)
C P6 model 13 (Dothan)
C P4 model 0 (Willamette)
C P4 model 1 (?)
C P4 model 2 (Northwood)
C P4 model 3 (Prescott)
C P4 model 4 (Nocona)
C Intel Atom 3
C AMD K6
C AMD K7
C AMD K8
C AMD K10
ifdef(`OPERATION_add_n', `
define(M4_inst, adcl)
define(M4_function_n, mpn_add_n)
define(M4_function_nc, mpn_add_nc)
define(M4_description, add)
',`ifdef(`OPERATION_sub_n', `
define(M4_inst, sbbl)
define(M4_function_n, mpn_sub_n)
define(M4_function_nc, mpn_sub_nc)
define(M4_description, subtract)
',`m4_error(`Need OPERATION_add_n or OPERATION_sub_n
')')')
MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
C mp_limb_t M4_function_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size);
C mp_limb_t M4_function_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size, mp_limb_t carry);
C
C Calculate src1,size M4_description src2,size, and store the result in
C dst,size. The return value is the carry bit from the top of the result (1
C or 0).
C
C The _nc version accepts 1 or 0 for an initial carry into the low limb of
C the calculation. Note values other than 1 or 0 here will lead to garbage
C results.
defframe(PARAM_CARRY,20)
defframe(PARAM_SIZE, 16)
defframe(PARAM_SRC2, 12)
defframe(PARAM_SRC1, 8)
defframe(PARAM_DST, 4)
dnl re-use parameter space
define(SAVE_RP,`PARAM_SIZE')
define(SAVE_VP,`PARAM_SRC1')
define(SAVE_UP,`PARAM_DST')
define(`rp', `%edi')
define(`up', `%esi')
define(`vp', `%ebx')
define(`cy', `%ecx')
define(`r1', `%ecx')
define(`r2', `%edx')
ASM_START()
TEXT
ALIGN(16)
deflit(`FRAME',0)
PROLOGUE(M4_function_n)
xor cy, cy C carry
L(start):
mov PARAM_SIZE, %eax C size
mov rp, SAVE_RP
mov PARAM_DST, rp
mov up, SAVE_UP
mov PARAM_SRC1, up
shr %eax C size >> 1
mov vp, SAVE_VP
mov PARAM_SRC2, vp
jz L(one) C size == 1
jc L(three) C size % 2 == 1
shr cy
mov (up), r2
lea 4(up), up
lea 4(vp), vp
lea -4(rp), rp
jmp L(entry)
L(one):
shr cy
mov (up), r1
jmp L(end)
L(three):
shr cy
mov (up), r1
ALIGN(16)
L(oop):
M4_inst (vp), r1
lea 8(up), up
mov -4(up), r2
lea 8(vp), vp
mov r1, (rp)
L(entry):
M4_inst -4(vp), r2
lea 8(rp), rp
dec %eax
mov (up), r1
mov r2, -4(rp)
jnz L(oop)
L(end): C %eax is zero here
mov SAVE_UP, up
M4_inst (vp), r1
mov SAVE_VP, vp
mov r1, (rp)
adc %eax, %eax
mov SAVE_RP, rp
ret
EPILOGUE()
PROLOGUE(M4_function_nc)
mov PARAM_CARRY, cy C carry
jmp L(start)
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,247 @@
dnl Intel Atom mpn_addlshC_n/mpn_sublshC_n -- rp[] = up[] +- (vp[] << C)
dnl Contributed to the GNU project by Marco Bodrato.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C mp_limb_t mpn_addlshC_n_ip1 (mp_ptr dst, mp_srcptr src, mp_size_t size);
C mp_limb_t mpn_addlshC_nc_ip1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
C mp_limb_t carry);
C mp_limb_t mpn_sublshC_n_ip1 (mp_ptr dst, mp_srcptr src, mp_size_t size,);
C mp_limb_t mpn_sublshC_nc_ip1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
C mp_signed_limb_t borrow);
defframe(PARAM_CORB, 16)
defframe(PARAM_SIZE, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
C mp_limb_t mpn_addlshC_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size,);
C mp_limb_t mpn_addlshC_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size, mp_limb_t carry);
C mp_limb_t mpn_sublshC_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size,);
C mp_limb_t mpn_sublshC_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size, mp_limb_t borrow);
C if src1 == dst, _ip1 is used
C cycles/limb
C dst!=src1,src2 dst==src1
C P5
C P6 model 0-8,10-12
C P6 model 9 (Banias)
C P6 model 13 (Dothan)
C P4 model 0 (Willamette)
C P4 model 1 (?)
C P4 model 2 (Northwood)
C P4 model 3 (Prescott)
C P4 model 4 (Nocona)
C Intel Atom 7 6
C AMD K6
C AMD K7
C AMD K8
C AMD K10
defframe(GPARAM_CORB, 20)
defframe(GPARAM_SIZE, 16)
defframe(GPARAM_SRC2, 12)
dnl re-use parameter space
define(SAVE_EBP,`PARAM_SIZE')
define(SAVE_EBX,`PARAM_SRC')
define(SAVE_UP,`PARAM_DST')
define(M, eval(m4_lshift(1,LSH)))
define(`rp', `%edi')
define(`up', `%esi')
ASM_START()
TEXT
ALIGN(8)
PROLOGUE(M4_ip_function_c)
deflit(`FRAME',0)
movl PARAM_CORB, %ecx
movl %ecx, %edx
shr $LSH, %edx
andl $1, %edx
M4_opp %edx, %ecx
jmp L(start_nc)
EPILOGUE()
PROLOGUE(M4_ip_function)
deflit(`FRAME',0)
xor %ecx, %ecx
xor %edx, %edx
L(start_nc):
push rp FRAME_pushl()
mov PARAM_DST, rp
mov up, SAVE_UP
mov PARAM_SRC, up
mov %ebx, SAVE_EBX
mov PARAM_SIZE, %ebx C size
L(inplace):
incl %ebx C size + 1
shr %ebx C (size+1)\2
mov %ebp, SAVE_EBP
jnc L(entry) C size odd
add %edx, %edx C size even
mov %ecx, %ebp
mov (up), %ecx
lea -4(rp), rp
lea (%ebp,%ecx,M), %eax
lea 4(up), up
jmp L(enteven)
ALIGN(16)
L(oop):
lea (%ecx,%eax,M), %ebp
shr $RSH, %eax
mov 4(up), %ecx
add %edx, %edx
lea 8(up), up
M4_inst %ebp, (rp)
lea (%eax,%ecx,M), %eax
L(enteven):
M4_inst %eax, 4(rp)
lea 8(rp), rp
sbb %edx, %edx
shr $RSH, %ecx
L(entry):
mov (up), %eax
decl %ebx
jnz L(oop)
lea (%ecx,%eax,M), %ebp
shr $RSH, %eax
shr %edx
M4_inst %ebp, (rp)
mov SAVE_UP, up
adc $0, %eax
mov SAVE_EBP, %ebp
mov SAVE_EBX, %ebx
pop rp FRAME_popl()
ret
EPILOGUE()
PROLOGUE(M4_function_c)
deflit(`FRAME',0)
movl GPARAM_CORB, %ecx
movl %ecx, %edx
shr $LSH, %edx
andl $1, %edx
M4_opp %edx, %ecx
jmp L(generic_nc)
EPILOGUE()
PROLOGUE(M4_function)
deflit(`FRAME',0)
xor %ecx, %ecx
xor %edx, %edx
L(generic_nc):
push rp FRAME_pushl()
mov PARAM_DST, rp
mov up, SAVE_UP
mov PARAM_SRC, up
cmp rp, up
mov %ebx, SAVE_EBX
jne L(general)
mov GPARAM_SIZE, %ebx C size
mov GPARAM_SRC2, up
jmp L(inplace)
L(general):
mov GPARAM_SIZE, %eax C size
mov %ebx, SAVE_EBX
incl %eax C size + 1
mov up, %ebx C vp
mov GPARAM_SRC2, up C up
shr %eax C (size+1)\2
mov %ebp, SAVE_EBP
mov %eax, GPARAM_SIZE
jnc L(entry2) C size odd
add %edx, %edx C size even
mov %ecx, %ebp
mov (up), %ecx
lea -4(rp), rp
lea -4(%ebx), %ebx
lea (%ebp,%ecx,M), %eax
lea 4(up), up
jmp L(enteven2)
ALIGN(16)
L(oop2):
lea (%ecx,%eax,M), %ebp
shr $RSH, %eax
mov 4(up), %ecx
add %edx, %edx
lea 8(up), up
mov (%ebx), %edx
M4_inst %ebp, %edx
lea (%eax,%ecx,M), %eax
mov %edx, (rp)
L(enteven2):
mov 4(%ebx), %edx
lea 8(%ebx), %ebx
M4_inst %eax, %edx
mov %edx, 4(rp)
sbb %edx, %edx
shr $RSH, %ecx
lea 8(rp), rp
L(entry2):
mov (up), %eax
decl GPARAM_SIZE
jnz L(oop2)
lea (%ecx,%eax,M), %ebp
shr $RSH, %eax
shr %edx
mov (%ebx), %edx
M4_inst %ebp, %edx
mov %edx, (rp)
mov SAVE_UP, up
adc $0, %eax
mov SAVE_EBP, %ebp
mov SAVE_EBX, %ebx
pop rp FRAME_popl()
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,35 @@
dnl Intel Atom mpn_bdiv_q_1, mpn_pi1_bdiv_q_1 -- schoolbook Hensel
dnl division by 1-limb divisor, returning quotient only.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
MULFUNC_PROLOGUE(mpn_bdiv_q_1 mpn_pi1_bdiv_q_1)
include_mpn(`x86/pentium/bdiv_q_1.asm')

View File

@@ -0,0 +1,113 @@
dnl X86 mpn_cnd_add_n optimised for Intel Atom.
dnl Copyright 2013 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C P5 ?
C P6 model 0-8,10-12 ?
C P6 model 9 (Banias) ?
C P6 model 13 (Dothan) ?
C P4 model 0-1 (Willamette) ?
C P4 model 2 (Northwood) ?
C P4 model 3-4 (Prescott) ?
C Intel atom 4.67
C AMD K6 ?
C AMD K7 ?
C AMD K8 ?
define(`rp', `%edi')
define(`up', `%esi')
define(`vp', `%ebp')
define(`n', `%ecx')
define(`cnd', `20(%esp)')
ASM_START()
TEXT
ALIGN(16)
PROLOGUE(mpn_cnd_add_n)
push %edi
push %esi
push %ebx
push %ebp
mov cnd, %eax C make cnd into a mask (1)
mov 24(%esp), rp
neg %eax C make cnd into a mask (1)
mov 28(%esp), up
sbb %eax, %eax C make cnd into a mask (1)
mov 32(%esp), vp
mov %eax, cnd C make cnd into a mask (1)
mov 36(%esp), n
xor %edx, %edx
shr $1, n
jnc L(top)
mov 0(vp), %eax
and cnd, %eax
lea 4(vp), vp
add 0(up), %eax
lea 4(rp), rp
lea 4(up), up
sbb %edx, %edx
mov %eax, -4(rp)
inc n
dec n
je L(end)
L(top): sbb %edx, %edx
mov 0(vp), %eax
and cnd, %eax
lea 8(vp), vp
lea 8(rp), rp
mov -4(vp), %ebx
and cnd, %ebx
add %edx, %edx
adc 0(up), %eax
lea 8(up), up
mov %eax, -8(rp)
adc -4(up), %ebx
dec n
mov %ebx, -4(rp)
jne L(top)
L(end): mov $0, %eax
adc %eax, %eax
pop %ebp
pop %ebx
pop %esi
pop %edi
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,124 @@
dnl X86 mpn_cnd_sub_n optimised for Intel Atom.
dnl Copyright 2013 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C P5 ?
C P6 model 0-8,10-12 ?
C P6 model 9 (Banias) ?
C P6 model 13 (Dothan) ?
C P4 model 0-1 (Willamette) ?
C P4 model 2 (Northwood) ?
C P4 model 3-4 (Prescott) ?
C Intel atom 5.67
C AMD K6 ?
C AMD K7 ?
C AMD K8 ?
define(`rp', `%edi')
define(`up', `%esi')
define(`vp', `%ebp')
define(`n', `%ecx')
define(`cnd', `20(%esp)')
ASM_START()
TEXT
ALIGN(16)
PROLOGUE(mpn_cnd_sub_n)
push %edi
push %esi
push %ebx
push %ebp
mov cnd, %eax C make cnd into a mask (1)
mov 24(%esp), rp
neg %eax C make cnd into a mask (1)
mov 28(%esp), up
sbb %eax, %eax C make cnd into a mask (1)
mov 32(%esp), vp
mov %eax, cnd C make cnd into a mask (1)
mov 36(%esp), n
xor %edx, %edx
inc n
shr n
jnc L(ent)
mov 0(vp), %eax
and cnd, %eax
lea 4(vp), vp
mov 0(up), %edx
sub %eax, %edx
lea 4(rp), rp
lea 4(up), up
mov %edx, -4(rp)
sbb %edx, %edx C save cy
L(ent): mov 0(vp), %ebx
and cnd, %ebx
add %edx, %edx C restore cy
mov 0(up), %edx
dec n
je L(end)
L(top): sbb %ebx, %edx
mov 4(vp), %eax
mov %edx, 0(rp)
sbb %edx, %edx C save cy
mov 8(vp), %ebx
lea 8(up), up
and cnd, %ebx
and cnd, %eax
add %edx, %edx C restore cy
mov -4(up), %edx
lea 8(rp), rp
sbb %eax, %edx
mov %edx, -4(rp)
dec n
mov 0(up), %edx
lea 8(vp), vp
jne L(top)
L(end): sbb %ebx, %edx
mov %edx, 0(rp)
mov $0, %eax
adc %eax, %eax
pop %ebp
pop %ebx
pop %esi
pop %edi
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,34 @@
dnl Intel Atom mpn_divexact_1 -- mpn by limb exact division.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
MULFUNC_PROLOGUE(mpn_divexact_1)
include_mpn(`x86/pentium/dive_1.asm')

View File

@@ -0,0 +1,214 @@
/* Intel Atom/32 gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 2019 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* 1600 MHz Diamondville (Atom 330) */
/* FFT tuning limit = 67,000,000 */
/* Generated by tuneup.c, 2019-10-18, gcc 8.3 */
#define MOD_1_NORM_THRESHOLD 3
#define MOD_1_UNNORM_THRESHOLD 5
#define MOD_1N_TO_MOD_1_1_THRESHOLD 11
#define MOD_1U_TO_MOD_1_1_THRESHOLD 5
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 10
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 17
#define USE_PREINV_DIVREM_1 1 /* native */
#define DIV_QR_1N_PI1_METHOD 1 /* 72.60% faster than 2 */
#define DIV_QR_1_NORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD 35
#define DIV_1_VS_MUL_1_PERCENT 236
#define MUL_TOOM22_THRESHOLD 22
#define MUL_TOOM33_THRESHOLD 81
#define MUL_TOOM44_THRESHOLD 178
#define MUL_TOOM6H_THRESHOLD 270
#define MUL_TOOM8H_THRESHOLD 399
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 97
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 126
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 115
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 129
#define MUL_TOOM43_TO_TOOM54_THRESHOLD 115
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 32
#define SQR_TOOM3_THRESHOLD 117
#define SQR_TOOM4_THRESHOLD 178
#define SQR_TOOM6_THRESHOLD 366
#define SQR_TOOM8_THRESHOLD 527
#define MULMID_TOOM42_THRESHOLD 50
#define MULMOD_BNM1_THRESHOLD 13
#define SQRMOD_BNM1_THRESHOLD 17
#define MUL_FFT_MODF_THRESHOLD 404 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 404, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
{ 12, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
{ 21, 7}, { 11, 6}, { 25, 7}, { 13, 6}, \
{ 27, 7}, { 15, 6}, { 31, 7}, { 21, 8}, \
{ 11, 7}, { 27, 8}, { 15, 7}, { 35, 8}, \
{ 19, 7}, { 39, 8}, { 23, 7}, { 47, 8}, \
{ 27, 9}, { 15, 8}, { 39, 9}, { 23, 8}, \
{ 51,10}, { 15, 9}, { 31, 8}, { 67, 9}, \
{ 39, 8}, { 79, 9}, { 47, 8}, { 95,10}, \
{ 31, 9}, { 79,10}, { 47, 9}, { 95,11}, \
{ 31,10}, { 63, 9}, { 135,10}, { 79, 9}, \
{ 159,10}, { 95, 9}, { 191,10}, { 111,11}, \
{ 63,10}, { 127, 9}, { 255, 8}, { 511,10}, \
{ 143, 9}, { 287, 8}, { 575, 9}, { 303,10}, \
{ 159,11}, { 95,10}, { 191, 9}, { 383,12}, \
{ 63,11}, { 127,10}, { 255, 9}, { 511,10}, \
{ 271, 9}, { 543,10}, { 287, 9}, { 575,10}, \
{ 303,11}, { 159,10}, { 351, 9}, { 703,10}, \
{ 367, 9}, { 735,11}, { 191,10}, { 383, 9}, \
{ 767,10}, { 415,11}, { 223,10}, { 447,12}, \
{ 127,11}, { 255,10}, { 543,11}, { 287,10}, \
{ 607,11}, { 319,10}, { 671,11}, { 351,10}, \
{ 735,12}, { 191,11}, { 383,10}, { 767,11}, \
{ 415,10}, { 831,11}, { 447,13}, { 127,12}, \
{ 255,11}, { 543,10}, { 1087,11}, { 607,12}, \
{ 319,11}, { 735,12}, { 383,11}, { 831,12}, \
{ 447,11}, { 959,13}, { 255,12}, { 511,11}, \
{ 1087,12}, { 575,11}, { 1215,12}, { 639,11}, \
{ 1279,12}, { 703,11}, { 1407,13}, { 383,12}, \
{ 831,11}, { 1663,12}, { 959,14}, { 255,13}, \
{ 511,12}, { 1215,13}, { 639,12}, { 1471,13}, \
{ 767,12}, { 1599,13}, { 895,12}, { 1791,14}, \
{ 511,13}, { 1023,12}, { 2111,13}, { 1151,12}, \
{ 2431,13}, { 1407,14}, { 767,13}, { 1663,12}, \
{ 3455,13}, { 1791,15}, { 511,14}, { 1023,13}, \
{ 2431,14}, { 1279,13}, { 2943,12}, { 5887,14}, \
{ 1535,13}, { 3455,14}, { 1791,13}, { 3839,15}, \
{ 1023,14}, { 2047,13}, { 4223,14}, { 2303,13}, \
{ 4991,12}, { 9983,14}, { 2815,13}, { 5887,15}, \
{ 1535,14}, { 3839,16} }
#define MUL_FFT_TABLE3_SIZE 158
#define MUL_FFT_THRESHOLD 4544
#define SQR_FFT_MODF_THRESHOLD 368 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 368, 5}, { 23, 6}, { 12, 5}, { 25, 6}, \
{ 13, 5}, { 27, 6}, { 25, 7}, { 13, 6}, \
{ 28, 7}, { 15, 6}, { 31, 7}, { 17, 6}, \
{ 35, 7}, { 21, 8}, { 11, 7}, { 27, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
{ 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
{ 39, 9}, { 23, 8}, { 51,10}, { 15, 9}, \
{ 31, 8}, { 63, 9}, { 39, 8}, { 79, 9}, \
{ 47,10}, { 31, 9}, { 79,10}, { 47, 9}, \
{ 95,11}, { 31,10}, { 63, 9}, { 127, 8}, \
{ 255, 9}, { 135,10}, { 79, 9}, { 159, 8}, \
{ 319,10}, { 95, 9}, { 191,11}, { 63,10}, \
{ 127, 9}, { 255, 8}, { 511, 9}, { 271,10}, \
{ 143, 9}, { 287, 8}, { 575, 9}, { 303,10}, \
{ 159, 9}, { 319,11}, { 95,10}, { 191, 9}, \
{ 383,12}, { 63,11}, { 127,10}, { 255, 9}, \
{ 511,10}, { 271, 9}, { 543,10}, { 287, 9}, \
{ 575,10}, { 303, 9}, { 607,11}, { 159,10}, \
{ 319, 9}, { 639,10}, { 335, 9}, { 671,10}, \
{ 351, 9}, { 703,11}, { 191,10}, { 383, 9}, \
{ 767,10}, { 415,11}, { 223,10}, { 447,12}, \
{ 127,11}, { 255,10}, { 543,11}, { 287,10}, \
{ 607,11}, { 319,10}, { 671,11}, { 351,10}, \
{ 703,12}, { 191,11}, { 383,10}, { 767,11}, \
{ 415,10}, { 831,11}, { 447,13}, { 127,12}, \
{ 255,11}, { 543,10}, { 1087,11}, { 607,12}, \
{ 319,11}, { 671,10}, { 1343,11}, { 735,12}, \
{ 383,11}, { 831,12}, { 447,11}, { 959,13}, \
{ 255,12}, { 511,11}, { 1087,12}, { 575,11}, \
{ 1215,12}, { 639,11}, { 1343,12}, { 703,13}, \
{ 383,12}, { 959,14}, { 255,13}, { 511,12}, \
{ 1215,13}, { 639,12}, { 1471,13}, { 767,12}, \
{ 1599,13}, { 895,14}, { 511,13}, { 1023,12}, \
{ 2111,13}, { 1151,12}, { 2431,13}, { 1407,14}, \
{ 767,13}, { 1663,12}, { 3455,15}, { 511,14}, \
{ 1023,13}, { 2175,12}, { 4351,13}, { 2431,14}, \
{ 1279,13}, { 2943,12}, { 5887,14}, { 1535,13}, \
{ 3455,14}, { 1791,13}, { 3839,15}, { 1023,14}, \
{ 2047,13}, { 4351,14}, { 2303,13}, { 4991,12}, \
{ 9983,14}, { 2815,13}, { 5887,15}, { 1535,14}, \
{ 3839,16} }
#define SQR_FFT_TABLE3_SIZE 161
#define SQR_FFT_THRESHOLD 3712
#define MULLO_BASECASE_THRESHOLD 0 /* always */
#define MULLO_DC_THRESHOLD 56
#define MULLO_MUL_N_THRESHOLD 8907
#define SQRLO_BASECASE_THRESHOLD 6
#define SQRLO_DC_THRESHOLD 111
#define SQRLO_SQR_THRESHOLD 6654
#define DC_DIV_QR_THRESHOLD 67
#define DC_DIVAPPR_Q_THRESHOLD 252
#define DC_BDIV_QR_THRESHOLD 63
#define DC_BDIV_Q_THRESHOLD 172
#define INV_MULMOD_BNM1_THRESHOLD 42
#define INV_NEWTON_THRESHOLD 250
#define INV_APPR_THRESHOLD 250
#define BINV_NEWTON_THRESHOLD 276
#define REDC_1_TO_REDC_N_THRESHOLD 68
#define MU_DIV_QR_THRESHOLD 1334
#define MU_DIVAPPR_Q_THRESHOLD 1442
#define MUPI_DIV_QR_THRESHOLD 116
#define MU_BDIV_QR_THRESHOLD 1142
#define MU_BDIV_Q_THRESHOLD 1341
#define POWM_SEC_TABLE 1,16,98,376,1259
#define GET_STR_DC_THRESHOLD 12
#define GET_STR_PRECOMPUTE_THRESHOLD 23
#define SET_STR_DC_THRESHOLD 298
#define SET_STR_PRECOMPUTE_THRESHOLD 1037
#define FAC_DSC_THRESHOLD 171
#define FAC_ODD_THRESHOLD 34
#define MATRIX22_STRASSEN_THRESHOLD 17
#define HGCD2_DIV1_METHOD 3 /* 3.71% faster than 1 */
#define HGCD_THRESHOLD 128
#define HGCD_APPR_THRESHOLD 186
#define HGCD_REDUCE_THRESHOLD 2479
#define GCD_DC_THRESHOLD 465
#define GCDEXT_DC_THRESHOLD 339
#define JACOBI_BASE_METHOD 3 /* 2.58% faster than 2 */
/* Tuneup completed successfully, took 214190 seconds */

View File

@@ -0,0 +1,151 @@
dnl Intel Atom mpn_and_n,...,mpn_xnor_n -- bitwise logical operations.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl Contributed to the GNU project by Marco Bodrato.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C op nop opn
C P5
C P6 model 0-8,10-12
C P6 model 9 (Banias)
C P6 model 13 (Dothan)
C P4 model 0 (Willamette)
C P4 model 1 (?)
C P4 model 2 (Northwood)
C P4 model 3 (Prescott)
C P4 model 4 (Nocona)
C Intel Atom 3 3.5 3.5
C AMD K6
C AMD K7
C AMD K8
C AMD K10
define(M4_choose_op,
`ifdef(`OPERATION_$1',`
define(`M4_function', `mpn_$1')
define(`M4_want_pre', `$4')
define(`M4_inst', `$3')
define(`M4_want_post',`$2')
')')
define(M4pre, `ifelse(M4_want_pre, yes,`$1')')
define(M4post,`ifelse(M4_want_post,yes,`$1')')
M4_choose_op( and_n, , andl, )
M4_choose_op( andn_n, , andl, yes)
M4_choose_op( nand_n, yes, andl, )
M4_choose_op( ior_n, , orl, )
M4_choose_op( iorn_n, , orl, yes)
M4_choose_op( nior_n, yes, orl, )
M4_choose_op( xor_n, , xorl, )
M4_choose_op( xnor_n, yes, xorl, )
ifdef(`M4_function',,
`m4_error(`Unrecognised or undefined OPERATION symbol
')')
MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
C void M4_function (mp_ptr dst, mp_srcptr src2, mp_srcptr src1, mp_size_t size);
C
defframe(PARAM_SIZE, 16)
defframe(PARAM_SRC1, 12)
defframe(PARAM_SRC2, 8)
defframe(PARAM_DST, 4)
dnl re-use parameter space
define(SAVE_RP,`PARAM_SIZE')
define(SAVE_VP,`PARAM_SRC1')
define(SAVE_UP,`PARAM_DST')
define(`rp', `%edi')
define(`up', `%esi')
define(`vp', `%ebx')
define(`cnt', `%eax')
define(`r1', `%ecx')
define(`r2', `%edx')
ASM_START()
TEXT
ALIGN(16)
deflit(`FRAME',0)
PROLOGUE(M4_function)
mov PARAM_SIZE, cnt C size
mov rp, SAVE_RP
mov PARAM_DST, rp
mov up, SAVE_UP
mov PARAM_SRC1, up
shr cnt C size >> 1
mov vp, SAVE_VP
mov PARAM_SRC2, vp
mov (up), r1
jz L(end) C size == 1
jnc L(even) C size % 2 == 0
ALIGN(16)
L(oop):
M4pre(` notl_or_xorl_GMP_NUMB_MASK(r1)')
M4_inst (vp), r1
lea 8(up), up
mov -4(up), r2
M4post(` notl_or_xorl_GMP_NUMB_MASK(r1)')
lea 8(vp), vp
mov r1, (rp)
L(entry):
M4pre(` notl_or_xorl_GMP_NUMB_MASK(r2)')
M4_inst -4(vp), r2
lea 8(rp), rp
M4post(` notl_or_xorl_GMP_NUMB_MASK(r2)')
dec cnt
mov (up), r1
mov r2, -4(rp)
jnz L(oop)
L(end):
M4pre(` notl_or_xorl_GMP_NUMB_MASK(r1)')
mov SAVE_UP, up
M4_inst (vp), r1
M4post(`notl_or_xorl_GMP_NUMB_MASK(r1)')
mov SAVE_VP, vp
mov r1, (rp)
mov SAVE_RP, rp
ret
L(even):
mov r1, r2
lea 4(up), up
lea 4(vp), vp
lea -4(rp), rp
jmp L(entry)
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,218 @@
dnl Intel Atom mpn_lshift -- mpn left shift.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C mp_limb_t mpn_lshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
C unsigned cnt);
C cycles/limb
C cnt!=1 cnt==1
C P5
C P6 model 0-8,10-12
C P6 model 9 (Banias)
C P6 model 13 (Dothan)
C P4 model 0 (Willamette)
C P4 model 1 (?)
C P4 model 2 (Northwood)
C P4 model 3 (Prescott)
C P4 model 4 (Nocona)
C Intel Atom 5 2.5
C AMD K6
C AMD K7
C AMD K8
C AMD K10
defframe(PARAM_CNT, 16)
defframe(PARAM_SIZE,12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
dnl re-use parameter space
define(SAVE_UP,`PARAM_CNT')
define(VAR_COUNT,`PARAM_SIZE')
define(SAVE_EBX,`PARAM_SRC')
define(SAVE_EBP,`PARAM_DST')
define(`rp', `%edi')
define(`up', `%esi')
define(`cnt', `%ecx')
ASM_START()
TEXT
ALIGN(8)
deflit(`FRAME',0)
PROLOGUE(mpn_lshift)
mov PARAM_CNT, cnt
mov PARAM_SIZE, %edx
mov up, SAVE_UP
mov PARAM_SRC, up
push rp FRAME_pushl()
mov PARAM_DST, rp
C We can use faster code for shift-by-1 under certain conditions.
cmp $1,cnt
jne L(normal)
cmpl rp, up
jnc L(special) C jump if s_ptr + 1 >= res_ptr
leal (up,%edx,4),%eax
cmpl %eax,rp
jnc L(special) C jump if res_ptr >= s_ptr + size
L(normal):
lea -4(up,%edx,4), up
mov %ebx, SAVE_EBX
lea -4(rp,%edx,4), rp
shr %edx
mov (up), %eax
mov %edx, VAR_COUNT
jnc L(evn)
mov %eax, %ebx
shl %cl, %ebx
neg cnt
shr %cl, %eax
test %edx, %edx
jnz L(gt1)
mov %ebx, (rp)
jmp L(quit)
L(gt1): mov %ebp, SAVE_EBP
push %eax
mov -4(up), %eax
mov %eax, %ebp
shr %cl, %eax
jmp L(lo1)
L(evn): mov %ebp, SAVE_EBP
neg cnt
mov %eax, %ebp
mov -4(up), %edx
shr %cl, %eax
mov %edx, %ebx
shr %cl, %edx
neg cnt
decl VAR_COUNT
lea 4(rp), rp
lea -4(up), up
jz L(end)
push %eax FRAME_pushl()
ALIGN(8)
L(top): shl %cl, %ebp
or %ebp, %edx
shl %cl, %ebx
neg cnt
mov -4(up), %eax
mov %eax, %ebp
mov %edx, -4(rp)
shr %cl, %eax
lea -8(rp), rp
L(lo1): mov -8(up), %edx
or %ebx, %eax
mov %edx, %ebx
shr %cl, %edx
lea -8(up), up
neg cnt
mov %eax, (rp)
decl VAR_COUNT
jg L(top)
pop %eax FRAME_popl()
L(end):
shl %cl, %ebp
shl %cl, %ebx
or %ebp, %edx
mov SAVE_EBP, %ebp
mov %edx, -4(rp)
mov %ebx, -8(rp)
L(quit):
mov SAVE_UP, up
mov SAVE_EBX, %ebx
pop rp FRAME_popl()
ret
L(special):
deflit(`FRAME',4)
lea 3(%edx), %eax C size + 3
dec %edx C size - 1
mov (up), %ecx
shr $2, %eax C (size + 3) / 4
and $3, %edx C (size - 1) % 4
jz L(goloop) C jmp if size == 1 (mod 4)
shr %edx
jnc L(odd) C jum if size == 3 (mod 4)
add %ecx, %ecx
lea 4(up), up
mov %ecx, (rp)
mov (up), %ecx
lea 4(rp), rp
dec %edx
jnz L(goloop) C jump if size == 0 (mod 4)
L(odd): lea -8(up), up
lea -8(rp), rp
jmp L(sentry) C reached if size == 2 or 3 (mod 4)
L(sloop):
adc %ecx, %ecx
mov 4(up), %edx
mov %ecx, (rp)
adc %edx, %edx
mov 8(up), %ecx
mov %edx, 4(rp)
L(sentry):
adc %ecx, %ecx
mov 12(up), %edx
mov %ecx, 8(rp)
adc %edx, %edx
lea 16(up), up
mov %edx, 12(rp)
lea 16(rp), rp
mov (up), %ecx
L(goloop):
decl %eax
jnz L(sloop)
L(squit):
adc %ecx, %ecx
mov %ecx, (rp)
adc %eax, %eax
mov SAVE_UP, up
pop rp FRAME_popl()
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,159 @@
dnl Intel Atom mpn_lshiftc -- mpn left shift with complement.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C mp_limb_t mpn_lshiftc (mp_ptr dst, mp_srcptr src, mp_size_t size,
C unsigned cnt);
C cycles/limb
C P5
C P6 model 0-8,10-12
C P6 model 9 (Banias)
C P6 model 13 (Dothan)
C P4 model 0 (Willamette)
C P4 model 1 (?)
C P4 model 2 (Northwood)
C P4 model 3 (Prescott)
C P4 model 4 (Nocona)
C Intel Atom 5.5
C AMD K6
C AMD K7
C AMD K8
C AMD K10
defframe(PARAM_CNT, 16)
defframe(PARAM_SIZE,12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
dnl re-use parameter space
define(SAVE_UP,`PARAM_CNT')
define(VAR_COUNT,`PARAM_SIZE')
define(SAVE_EBX,`PARAM_SRC')
define(SAVE_EBP,`PARAM_DST')
define(`rp', `%edi')
define(`up', `%esi')
define(`cnt', `%ecx')
ASM_START()
TEXT
PROLOGUE(mpn_lshiftc)
deflit(`FRAME',0)
mov PARAM_CNT, cnt
mov PARAM_SIZE, %edx
mov up, SAVE_UP
mov PARAM_SRC, up
push rp FRAME_pushl()
mov PARAM_DST, rp
lea -4(up,%edx,4), up
mov %ebx, SAVE_EBX
lea -4(rp,%edx,4), rp
shr %edx
mov (up), %eax
mov %edx, VAR_COUNT
jnc L(evn)
mov %eax, %ebx
shl %cl, %ebx
neg cnt
shr %cl, %eax
test %edx, %edx
jnz L(gt1)
not %ebx
mov %ebx, (rp)
jmp L(quit)
L(gt1): mov %ebp, SAVE_EBP
push %eax
mov -4(up), %eax
mov %eax, %ebp
shr %cl, %eax
jmp L(lo1)
L(evn): mov %ebp, SAVE_EBP
neg cnt
mov %eax, %ebp
mov -4(up), %edx
shr %cl, %eax
mov %edx, %ebx
shr %cl, %edx
neg cnt
decl VAR_COUNT
lea 4(rp), rp
lea -4(up), up
jz L(end)
push %eax FRAME_pushl()
L(top): shl %cl, %ebp
or %ebp, %edx
shl %cl, %ebx
neg cnt
not %edx
mov -4(up), %eax
mov %eax, %ebp
mov %edx, -4(rp)
shr %cl, %eax
lea -8(rp), rp
L(lo1): mov -8(up), %edx
or %ebx, %eax
mov %edx, %ebx
shr %cl, %edx
not %eax
lea -8(up), up
neg cnt
mov %eax, (rp)
decl VAR_COUNT
jg L(top)
pop %eax FRAME_popl()
L(end):
shl %cl, %ebp
shl %cl, %ebx
or %ebp, %edx
mov SAVE_EBP, %ebp
not %edx
not %ebx
mov %edx, -4(rp)
mov %ebx, -8(rp)
L(quit):
mov SAVE_UP, up
mov SAVE_EBX, %ebx
pop rp FRAME_popl()
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,34 @@
dnl Intel Atom mpn_copyd -- copy limb vector, decrementing.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
MULFUNC_PROLOGUE(mpn_copyd)
include_mpn(`x86/k7/mmx/copyd.asm')

View File

@@ -0,0 +1,34 @@
dnl Intel Atom mpn_copyi -- copy limb vector, incrementing.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
MULFUNC_PROLOGUE(mpn_copyi)
include_mpn(`x86/k7/mmx/copyi.asm')

View File

@@ -0,0 +1,34 @@
dnl Intel Atom mpn_hamdist -- hamming distance.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
MULFUNC_PROLOGUE(mpn_hamdist)
include_mpn(`x86/k7/mmx/popham.asm')

View File

@@ -0,0 +1,34 @@
dnl Intel Atom mpn_mod_34lsub1 -- remainder modulo 2^24-1.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
MULFUNC_PROLOGUE(mpn_mod_34lsub1)
include_mpn(`x86/p6/mod_34lsub1.asm')

View File

@@ -0,0 +1,34 @@
dnl Intel Atom mpn_modexact_1_odd -- exact division style remainder.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
MULFUNC_PROLOGUE(mpn_modexact_1_odd mpn_modexact_1c_odd)
include_mpn(`x86/pentium/mode1o.asm')

View File

@@ -0,0 +1,152 @@
dnl Intel Atom mpn_rshift -- mpn right shift.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl Converted from AMD64 by Marco Bodrato.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C mp_limb_t mpn_rshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
C unsigned cnt);
C cycles/limb
C P5
C P6 model 0-8,10-12
C P6 model 9 (Banias)
C P6 model 13 (Dothan)
C P4 model 0 (Willamette)
C P4 model 1 (?)
C P4 model 2 (Northwood)
C P4 model 3 (Prescott)
C P4 model 4 (Nocona)
C Intel Atom 5
C AMD K6
C AMD K7
C AMD K8
C AMD K10
defframe(PARAM_CNT, 16)
defframe(PARAM_SIZE,12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
dnl re-use parameter space
define(SAVE_UP,`PARAM_CNT')
define(VAR_COUNT,`PARAM_SIZE')
define(SAVE_EBX,`PARAM_SRC')
define(SAVE_EBP,`PARAM_DST')
define(`rp', `%edi')
define(`up', `%esi')
define(`cnt', `%ecx')
ASM_START()
TEXT
ALIGN(8)
deflit(`FRAME',0)
PROLOGUE(mpn_rshift)
mov PARAM_CNT, cnt
mov PARAM_SIZE, %edx
mov up, SAVE_UP
mov PARAM_SRC, up
push rp FRAME_pushl()
mov PARAM_DST, rp
mov %ebx, SAVE_EBX
shr %edx
mov (up), %eax
mov %edx, VAR_COUNT
jnc L(evn)
mov %eax, %ebx
shr %cl, %ebx
neg cnt
shl %cl, %eax
test %edx, %edx
jnz L(gt1)
mov %ebx, (rp)
jmp L(quit)
L(gt1): mov %ebp, SAVE_EBP
push %eax
mov 4(up), %eax
mov %eax, %ebp
shl %cl, %eax
jmp L(lo1)
L(evn): mov %ebp, SAVE_EBP
neg cnt
mov %eax, %ebp
mov 4(up), %edx
shl %cl, %eax
mov %edx, %ebx
shl %cl, %edx
neg cnt
decl VAR_COUNT
lea -4(rp), rp
lea 4(up), up
jz L(end)
push %eax FRAME_pushl()
ALIGN(8)
L(top): shr %cl, %ebp
or %ebp, %edx
shr %cl, %ebx
neg cnt
mov 4(up), %eax
mov %eax, %ebp
mov %edx, 4(rp)
shl %cl, %eax
lea 8(rp), rp
L(lo1): mov 8(up), %edx
or %ebx, %eax
mov %edx, %ebx
shl %cl, %edx
lea 8(up), up
neg cnt
mov %eax, (rp)
decl VAR_COUNT
jg L(top)
pop %eax FRAME_popl()
L(end):
shr %cl, %ebp
shr %cl, %ebx
or %ebp, %edx
mov SAVE_EBP, %ebp
mov %edx, 4(rp)
mov %ebx, 8(rp)
L(quit):
mov SAVE_UP, up
mov SAVE_EBX, %ebx
pop rp FRAME_popl()
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,174 @@
dnl x86-32 mpn_addmul_1 and mpn_submul_1 optimised for Intel Atom.
dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C cycles/limb
C P5 -
C P6 model 0-8,10-12 -
C P6 model 9 (Banias)
C P6 model 13 (Dothan)
C P4 model 0 (Willamette)
C P4 model 1 (?)
C P4 model 2 (Northwood)
C P4 model 3 (Prescott)
C P4 model 4 (Nocona)
C Intel Atom 8
C AMD K6
C AMD K7 -
C AMD K8
C AMD K10
define(`rp', `%edi')
define(`up', `%esi')
define(`n', `%ecx')
ifdef(`OPERATION_addmul_1',`
define(ADDSUB, add)
define(func_1, mpn_addmul_1)
define(func_1c, mpn_addmul_1c)')
ifdef(`OPERATION_submul_1',`
define(ADDSUB, sub)
define(func_1, mpn_submul_1)
define(func_1c, mpn_submul_1c)')
MULFUNC_PROLOGUE(mpn_addmul_1 mpn_addmul_1c mpn_submul_1 mpn_submul_1c)
TEXT
ALIGN(16)
PROLOGUE(func_1)
xor %edx, %edx
L(ent): push %edi
push %esi
push %ebx
mov 16(%esp), rp
mov 20(%esp), up
mov 24(%esp), n
movd 28(%esp), %mm7
test $1, n
jz L(fi0or2)
movd (up), %mm0
pmuludq %mm7, %mm0
shr $2, n
jnc L(fi1)
L(fi3): lea -8(up), up
lea -8(rp), rp
movd 12(up), %mm1
movd %mm0, %ebx
pmuludq %mm7, %mm1
add $1, n C increment and clear carry
jmp L(lo3)
L(fi1): movd %mm0, %ebx
jz L(wd1)
movd 4(up), %mm1
pmuludq %mm7, %mm1
jmp L(lo1)
L(fi0or2):
movd (up), %mm1
pmuludq %mm7, %mm1
shr $2, n
movd 4(up), %mm0
jc L(fi2)
lea -4(up), up
lea -4(rp), rp
movd %mm1, %eax
pmuludq %mm7, %mm0
jmp L(lo0)
L(fi2): lea 4(up), up
add $1, n C increment and clear carry
movd %mm1, %eax
lea -12(rp), rp
jmp L(lo2)
C ALIGN(16) C alignment seems irrelevant
L(top): movd 4(up), %mm1
adc $0, %edx
ADDSUB %eax, 12(rp)
movd %mm0, %ebx
pmuludq %mm7, %mm1
lea 16(rp), rp
L(lo1): psrlq $32, %mm0
adc %edx, %ebx
movd %mm0, %edx
movd %mm1, %eax
movd 8(up), %mm0
pmuludq %mm7, %mm0
adc $0, %edx
ADDSUB %ebx, (rp)
L(lo0): psrlq $32, %mm1
adc %edx, %eax
movd %mm1, %edx
movd %mm0, %ebx
movd 12(up), %mm1
pmuludq %mm7, %mm1
adc $0, %edx
ADDSUB %eax, 4(rp)
L(lo3): psrlq $32, %mm0
adc %edx, %ebx
movd %mm0, %edx
movd %mm1, %eax
lea 16(up), up
movd (up), %mm0
adc $0, %edx
ADDSUB %ebx, 8(rp)
L(lo2): psrlq $32, %mm1
adc %edx, %eax
movd %mm1, %edx
pmuludq %mm7, %mm0
dec n
jnz L(top)
L(end): adc n, %edx C n is zero here
ADDSUB %eax, 12(rp)
movd %mm0, %ebx
lea 16(rp), rp
L(wd1): psrlq $32, %mm0
adc %edx, %ebx
movd %mm0, %eax
adc n, %eax
ADDSUB %ebx, (rp)
emms
adc n, %eax
pop %ebx
pop %esi
pop %edi
ret
EPILOGUE()
PROLOGUE(func_1c)
mov 20(%esp), %edx C carry
jmp L(ent)
EPILOGUE()

View File

@@ -0,0 +1,34 @@
dnl Intel Atom mpn_bdiv_dbm1.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
MULFUNC_PROLOGUE(mpn_bdiv_dbm1c)
include_mpn(`x86/pentium4/sse2/bdiv_dbm1c.asm')

View File

@@ -0,0 +1,34 @@
dnl Intel Atom mpn_divrem_1 -- mpn by limb division.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
MULFUNC_PROLOGUE(mpn_preinv_divrem_1 mpn_divrem_1c mpn_divrem_1)
include_mpn(`x86/pentium4/sse2/divrem_1.asm')

View File

@@ -0,0 +1,34 @@
dnl Intel Atom/SSE2 mpn_mod_1_1.
dnl Copyright 2009, 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
MULFUNC_PROLOGUE(mpn_mod_1_1p)
include_mpn(`x86/pentium4/sse2/mod_1_1.asm')

View File

@@ -0,0 +1,34 @@
dnl Intel Atom/SSE2 mpn_mod_1_4.
dnl Copyright 2009, 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
MULFUNC_PROLOGUE(mpn_mod_1s_4p)
include_mpn(`x86/pentium4/sse2/mod_1_4.asm')

View File

@@ -0,0 +1,124 @@
dnl Intel Atom mpn_mul_1.
dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C cycles/limb
C P5 -
C P6 model 0-8,10-12 -
C P6 model 9 (Banias)
C P6 model 13 (Dothan)
C P4 model 0 (Willamette)
C P4 model 1 (?)
C P4 model 2 (Northwood)
C P4 model 3 (Prescott)
C P4 model 4 (Nocona)
C Intel Atom 7.5
C AMD K6 -
C AMD K7 -
C AMD K8
C AMD K10
defframe(PARAM_CARRY,20)
defframe(PARAM_MUL, 16)
defframe(PARAM_SIZE, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
define(`rp', `%edx')
define(`up', `%esi')
define(`n', `%ecx')
ASM_START()
TEXT
ALIGN(16)
deflit(`FRAME',0)
PROLOGUE(mpn_mul_1c)
movd PARAM_CARRY, %mm6 C carry
jmp L(ent)
EPILOGUE()
ALIGN(8) C for compact code
PROLOGUE(mpn_mul_1)
pxor %mm6, %mm6
L(ent): push %esi FRAME_pushl()
mov PARAM_SRC, up
mov PARAM_SIZE, %eax C size
movd PARAM_MUL, %mm7
movd (up), %mm0
mov %eax, n
and $3, %eax
pmuludq %mm7, %mm0
mov PARAM_DST, rp
jz L(lo0)
cmp $2, %eax
lea -16(up,%eax,4),up
lea -16(rp,%eax,4),rp
jc L(lo1)
jz L(lo2)
jmp L(lo3)
ALIGN(16)
L(top): movd (up), %mm0
pmuludq %mm7, %mm0
psrlq $32, %mm6
lea 16(rp), rp
L(lo0): paddq %mm0, %mm6
movd 4(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, (rp)
psrlq $32, %mm6
L(lo3): paddq %mm0, %mm6
movd 8(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, 4(rp)
psrlq $32, %mm6
L(lo2): paddq %mm0, %mm6
movd 12(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, 8(rp)
psrlq $32, %mm6
L(lo1): paddq %mm0, %mm6
sub $4, n
movd %mm6, 12(rp)
lea 16(up), up
ja L(top)
psrlq $32, %mm6
movd %mm6, %eax
emms
pop %esi FRAME_popl()
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,501 @@
dnl x86 mpn_mul_basecase -- Multiply two limb vectors and store the result in
dnl a third limb vector.
dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C TODO
C * Check if 'jmp N(%esp)' is well-predicted enough to allow us to combine the
C 4 large loops into one; we could use it for the outer loop branch.
C * Optimise code outside of inner loops.
C * Write combined addmul_1 feed-in a wind-down code, and use when iterating
C outer each loop. ("Overlapping software pipelining")
C * Postpone push of ebx until we know vn > 1. Perhaps use caller-saves regs
C for inlined mul_1, allowing us to postpone all pushes.
C * Perhaps write special code for vn <= un < M, for some small M.
C void mpn_mul_basecase (mp_ptr wp,
C mp_srcptr xp, mp_size_t xn,
C mp_srcptr yp, mp_size_t yn);
C
define(`rp', `%edi')
define(`up', `%esi')
define(`un', `%ecx')
define(`vp', `%ebp')
define(`vn', `36(%esp)')
TEXT
ALIGN(16)
PROLOGUE(mpn_mul_basecase)
push %edi
push %esi
push %ebx
push %ebp
mov 20(%esp), rp
mov 24(%esp), up
mov 28(%esp), un
mov 32(%esp), vp
movd (up), %mm0
movd (vp), %mm7
pmuludq %mm7, %mm0
pxor %mm6, %mm6
mov un, %eax
and $3, %eax
jz L(of0)
cmp $2, %eax
jc L(of1)
jz L(of2)
C ================================================================
jmp L(m3)
ALIGN(16)
L(lm3): movd -4(up), %mm0
pmuludq %mm7, %mm0
psrlq $32, %mm6
lea 16(rp), rp
paddq %mm0, %mm6
movd (up), %mm0
pmuludq %mm7, %mm0
movd %mm6, -4(rp)
psrlq $32, %mm6
L(m3): paddq %mm0, %mm6
movd 4(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, (rp)
psrlq $32, %mm6
paddq %mm0, %mm6
movd 8(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, 4(rp)
psrlq $32, %mm6
paddq %mm0, %mm6
sub $4, un
movd %mm6, 8(rp)
lea 16(up), up
ja L(lm3)
psrlq $32, %mm6
movd %mm6, 12(rp)
decl vn
jz L(done)
lea -8(rp), rp
L(ol3): mov 28(%esp), un
neg un
lea 4(vp), vp
movd (vp), %mm7 C read next V limb
mov 24(%esp), up
lea 16(rp,un,4), rp
movd (up), %mm0
pmuludq %mm7, %mm0
sar $2, un
movd 4(up), %mm1
movd %mm0, %ebx
pmuludq %mm7, %mm1
lea -8(up), up
xor %edx, %edx C zero edx and CF
jmp L(a3)
L(la3): movd 4(up), %mm1
adc $0, %edx
add %eax, 12(rp)
movd %mm0, %ebx
pmuludq %mm7, %mm1
lea 16(rp), rp
psrlq $32, %mm0
adc %edx, %ebx
movd %mm0, %edx
movd %mm1, %eax
movd 8(up), %mm0
pmuludq %mm7, %mm0
adc $0, %edx
add %ebx, (rp)
psrlq $32, %mm1
adc %edx, %eax
movd %mm1, %edx
movd %mm0, %ebx
movd 12(up), %mm1
pmuludq %mm7, %mm1
adc $0, %edx
add %eax, 4(rp)
L(a3): psrlq $32, %mm0
adc %edx, %ebx
movd %mm0, %edx
movd %mm1, %eax
lea 16(up), up
movd (up), %mm0
adc $0, %edx
add %ebx, 8(rp)
psrlq $32, %mm1
adc %edx, %eax
movd %mm1, %edx
pmuludq %mm7, %mm0
inc un
jnz L(la3)
adc un, %edx C un is zero here
add %eax, 12(rp)
movd %mm0, %ebx
psrlq $32, %mm0
adc %edx, %ebx
movd %mm0, %eax
adc un, %eax
add %ebx, 16(rp)
adc un, %eax
mov %eax, 20(rp)
decl vn
jnz L(ol3)
jmp L(done)
C ================================================================
ALIGN(16)
L(lm0): movd (up), %mm0
pmuludq %mm7, %mm0
psrlq $32, %mm6
lea 16(rp), rp
L(of0): paddq %mm0, %mm6
movd 4(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, (rp)
psrlq $32, %mm6
paddq %mm0, %mm6
movd 8(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, 4(rp)
psrlq $32, %mm6
paddq %mm0, %mm6
movd 12(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, 8(rp)
psrlq $32, %mm6
paddq %mm0, %mm6
sub $4, un
movd %mm6, 12(rp)
lea 16(up), up
ja L(lm0)
psrlq $32, %mm6
movd %mm6, 16(rp)
decl vn
jz L(done)
lea -4(rp), rp
L(ol0): mov 28(%esp), un
neg un
lea 4(vp), vp
movd (vp), %mm7 C read next V limb
mov 24(%esp), up
lea 20(rp,un,4), rp
movd (up), %mm1
pmuludq %mm7, %mm1
sar $2, un
movd 4(up), %mm0
lea -4(up), up
movd %mm1, %eax
pmuludq %mm7, %mm0
xor %edx, %edx C zero edx and CF
jmp L(a0)
L(la0): movd 4(up), %mm1
adc $0, %edx
add %eax, 12(rp)
movd %mm0, %ebx
pmuludq %mm7, %mm1
lea 16(rp), rp
psrlq $32, %mm0
adc %edx, %ebx
movd %mm0, %edx
movd %mm1, %eax
movd 8(up), %mm0
pmuludq %mm7, %mm0
adc $0, %edx
add %ebx, (rp)
L(a0): psrlq $32, %mm1
adc %edx, %eax
movd %mm1, %edx
movd %mm0, %ebx
movd 12(up), %mm1
pmuludq %mm7, %mm1
adc $0, %edx
add %eax, 4(rp)
psrlq $32, %mm0
adc %edx, %ebx
movd %mm0, %edx
movd %mm1, %eax
lea 16(up), up
movd (up), %mm0
adc $0, %edx
add %ebx, 8(rp)
psrlq $32, %mm1
adc %edx, %eax
movd %mm1, %edx
pmuludq %mm7, %mm0
inc un
jnz L(la0)
adc un, %edx C un is zero here
add %eax, 12(rp)
movd %mm0, %ebx
psrlq $32, %mm0
adc %edx, %ebx
movd %mm0, %eax
adc un, %eax
add %ebx, 16(rp)
adc un, %eax
mov %eax, 20(rp)
decl vn
jnz L(ol0)
jmp L(done)
C ================================================================
ALIGN(16)
L(lm1): movd -12(up), %mm0
pmuludq %mm7, %mm0
psrlq $32, %mm6
lea 16(rp), rp
paddq %mm0, %mm6
movd -8(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, -12(rp)
psrlq $32, %mm6
paddq %mm0, %mm6
movd -4(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, -8(rp)
psrlq $32, %mm6
paddq %mm0, %mm6
movd (up), %mm0
pmuludq %mm7, %mm0
movd %mm6, -4(rp)
psrlq $32, %mm6
L(of1): paddq %mm0, %mm6
sub $4, un
movd %mm6, (rp)
lea 16(up), up
ja L(lm1)
psrlq $32, %mm6
movd %mm6, 4(rp)
decl vn
jz L(done)
lea -16(rp), rp
L(ol1): mov 28(%esp), un
neg un
lea 4(vp), vp
movd (vp), %mm7 C read next V limb
mov 24(%esp), up
lea 24(rp,un,4), rp
movd (up), %mm0
pmuludq %mm7, %mm0
sar $2, un
movd %mm0, %ebx
movd 4(up), %mm1
pmuludq %mm7, %mm1
xor %edx, %edx C zero edx and CF
inc un
jmp L(a1)
L(la1): movd 4(up), %mm1
adc $0, %edx
add %eax, 12(rp)
movd %mm0, %ebx
pmuludq %mm7, %mm1
lea 16(rp), rp
L(a1): psrlq $32, %mm0
adc %edx, %ebx
movd %mm0, %edx
movd %mm1, %eax
movd 8(up), %mm0
pmuludq %mm7, %mm0
adc $0, %edx
add %ebx, (rp)
psrlq $32, %mm1
adc %edx, %eax
movd %mm1, %edx
movd %mm0, %ebx
movd 12(up), %mm1
pmuludq %mm7, %mm1
adc $0, %edx
add %eax, 4(rp)
psrlq $32, %mm0
adc %edx, %ebx
movd %mm0, %edx
movd %mm1, %eax
lea 16(up), up
movd (up), %mm0
adc $0, %edx
add %ebx, 8(rp)
psrlq $32, %mm1
adc %edx, %eax
movd %mm1, %edx
pmuludq %mm7, %mm0
inc un
jnz L(la1)
adc un, %edx C un is zero here
add %eax, 12(rp)
movd %mm0, %ebx
psrlq $32, %mm0
adc %edx, %ebx
movd %mm0, %eax
adc un, %eax
add %ebx, 16(rp)
adc un, %eax
mov %eax, 20(rp)
decl vn
jnz L(ol1)
jmp L(done)
C ================================================================
ALIGN(16)
L(lm2): movd -8(up), %mm0
pmuludq %mm7, %mm0
psrlq $32, %mm6
lea 16(rp), rp
paddq %mm0, %mm6
movd -4(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, -8(rp)
psrlq $32, %mm6
paddq %mm0, %mm6
movd (up), %mm0
pmuludq %mm7, %mm0
movd %mm6, -4(rp)
psrlq $32, %mm6
L(of2): paddq %mm0, %mm6
movd 4(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, (rp)
psrlq $32, %mm6
paddq %mm0, %mm6
sub $4, un
movd %mm6, 4(rp)
lea 16(up), up
ja L(lm2)
psrlq $32, %mm6
movd %mm6, 8(rp)
decl vn
jz L(done)
lea -12(rp), rp
L(ol2): mov 28(%esp), un
neg un
lea 4(vp), vp
movd (vp), %mm7 C read next V limb
mov 24(%esp), up
lea 12(rp,un,4), rp
movd (up), %mm1
pmuludq %mm7, %mm1
sar $2, un
movd 4(up), %mm0
lea 4(up), up
movd %mm1, %eax
xor %edx, %edx C zero edx and CF
jmp L(lo2)
L(la2): movd 4(up), %mm1
adc $0, %edx
add %eax, 12(rp)
movd %mm0, %ebx
pmuludq %mm7, %mm1
lea 16(rp), rp
psrlq $32, %mm0
adc %edx, %ebx
movd %mm0, %edx
movd %mm1, %eax
movd 8(up), %mm0
pmuludq %mm7, %mm0
adc $0, %edx
add %ebx, (rp)
psrlq $32, %mm1
adc %edx, %eax
movd %mm1, %edx
movd %mm0, %ebx
movd 12(up), %mm1
pmuludq %mm7, %mm1
adc $0, %edx
add %eax, 4(rp)
psrlq $32, %mm0
adc %edx, %ebx
movd %mm0, %edx
movd %mm1, %eax
lea 16(up), up
movd (up), %mm0
adc $0, %edx
add %ebx, 8(rp)
L(lo2): psrlq $32, %mm1
adc %edx, %eax
movd %mm1, %edx
pmuludq %mm7, %mm0
inc un
jnz L(la2)
adc un, %edx C un is zero here
add %eax, 12(rp)
movd %mm0, %ebx
psrlq $32, %mm0
adc %edx, %ebx
movd %mm0, %eax
adc un, %eax
add %ebx, 16(rp)
adc un, %eax
mov %eax, 20(rp)
decl vn
jnz L(ol2)
C jmp L(done)
C ================================================================
L(done):
emms
pop %ebp
pop %ebx
pop %esi
pop %edi
ret
EPILOGUE()

View File

@@ -0,0 +1,35 @@
dnl Intel Atom mpn_popcount -- population count.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
MULFUNC_PROLOGUE(mpn_popcount)
include_mpn(`x86/pentium4/sse2/popcount.asm')

View File

@@ -0,0 +1,634 @@
dnl x86 mpn_sqr_basecase -- square an mpn number, optimised for atom.
dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C TODO
C * Check if 'jmp N(%esp)' is well-predicted enough to allow us to combine the
C 4 large loops into one; we could use it for the outer loop branch.
C * Optimise code outside of inner loops.
C * Write combined addmul_1 feed-in a wind-down code, and use when iterating
C outer each loop. ("Overlapping software pipelining")
C * Perhaps use caller-saves regs for inlined mul_1, allowing us to postpone
C all pushes.
C * Perhaps write special code for n < M, for some small M.
C * Replace inlined addmul_1 with smaller code from aorsmul_1.asm, or perhaps
C with even less pipelined code.
C * We run the outer loop until we have a 2-limb by 1-limb addmul_1 left.
C Consider breaking out earlier, saving high the cost of short loops.
C void mpn_sqr_basecase (mp_ptr wp,
C mp_srcptr xp, mp_size_t xn);
define(`rp', `%edi')
define(`up', `%esi')
define(`n', `%ecx')
define(`un', `%ebp')
TEXT
ALIGN(16)
PROLOGUE(mpn_sqr_basecase)
push %edi
push %esi
mov 12(%esp), rp
mov 16(%esp), up
mov 20(%esp), n
lea 4(rp), rp C write triangular product starting at rp[1]
dec n
movd (up), %mm7
jz L(one)
lea 4(up), up
push %ebx
push %ebp
mov n, %eax
movd (up), %mm0
neg n
pmuludq %mm7, %mm0
pxor %mm6, %mm6
mov n, un
and $3, %eax
jz L(of0)
cmp $2, %eax
jc L(of1)
jz L(of2)
C ================================================================
jmp L(m3)
ALIGN(16)
L(lm3): movd -4(up), %mm0
pmuludq %mm7, %mm0
psrlq $32, %mm6
lea 16(rp), rp
paddq %mm0, %mm6
movd (up), %mm0
pmuludq %mm7, %mm0
movd %mm6, -4(rp)
psrlq $32, %mm6
L(m3): paddq %mm0, %mm6
movd 4(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, (rp)
psrlq $32, %mm6
paddq %mm0, %mm6
movd 8(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, 4(rp)
psrlq $32, %mm6
paddq %mm0, %mm6
add $4, un
movd %mm6, 8(rp)
lea 16(up), up
js L(lm3)
psrlq $32, %mm6
movd %mm6, 12(rp)
inc n
C jz L(done)
lea -12(up), up
lea 4(rp), rp
jmp L(ol2)
C ================================================================
ALIGN(16)
L(lm0): movd (up), %mm0
pmuludq %mm7, %mm0
psrlq $32, %mm6
lea 16(rp), rp
L(of0): paddq %mm0, %mm6
movd 4(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, (rp)
psrlq $32, %mm6
paddq %mm0, %mm6
movd 8(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, 4(rp)
psrlq $32, %mm6
paddq %mm0, %mm6
movd 12(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, 8(rp)
psrlq $32, %mm6
paddq %mm0, %mm6
add $4, un
movd %mm6, 12(rp)
lea 16(up), up
js L(lm0)
psrlq $32, %mm6
movd %mm6, 16(rp)
inc n
C jz L(done)
lea -8(up), up
lea 8(rp), rp
jmp L(ol3)
C ================================================================
ALIGN(16)
L(lm1): movd -12(up), %mm0
pmuludq %mm7, %mm0
psrlq $32, %mm6
lea 16(rp), rp
paddq %mm0, %mm6
movd -8(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, -12(rp)
psrlq $32, %mm6
paddq %mm0, %mm6
movd -4(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, -8(rp)
psrlq $32, %mm6
paddq %mm0, %mm6
movd (up), %mm0
pmuludq %mm7, %mm0
movd %mm6, -4(rp)
psrlq $32, %mm6
L(of1): paddq %mm0, %mm6
add $4, un
movd %mm6, (rp)
lea 16(up), up
js L(lm1)
psrlq $32, %mm6
movd %mm6, 4(rp)
inc n
jz L(done) C goes away when we add special n=2 code
lea -20(up), up
lea -4(rp), rp
jmp L(ol0)
C ================================================================
ALIGN(16)
L(lm2): movd -8(up), %mm0
pmuludq %mm7, %mm0
psrlq $32, %mm6
lea 16(rp), rp
paddq %mm0, %mm6
movd -4(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, -8(rp)
psrlq $32, %mm6
paddq %mm0, %mm6
movd (up), %mm0
pmuludq %mm7, %mm0
movd %mm6, -4(rp)
psrlq $32, %mm6
L(of2): paddq %mm0, %mm6
movd 4(up), %mm0
pmuludq %mm7, %mm0
movd %mm6, (rp)
psrlq $32, %mm6
paddq %mm0, %mm6
add $4, un
movd %mm6, 4(rp)
lea 16(up), up
js L(lm2)
psrlq $32, %mm6
movd %mm6, 8(rp)
inc n
C jz L(done)
lea -16(up), up
C lea (rp), rp
C jmp L(ol1)
C ================================================================
L(ol1): lea 4(up,n,4), up
movd (up), %mm7 C read next U invariant limb
lea 8(rp,n,4), rp
mov n, un
movd 4(up), %mm1
pmuludq %mm7, %mm1
sar $2, un
movd %mm1, %ebx
inc un
jz L(re1)
movd 8(up), %mm0
pmuludq %mm7, %mm0
xor %edx, %edx C zero edx and CF
jmp L(a1)
L(la1): adc $0, %edx
add %ebx, 12(rp)
movd %mm0, %eax
pmuludq %mm7, %mm1
lea 16(rp), rp
psrlq $32, %mm0
adc %edx, %eax
movd %mm0, %edx
movd %mm1, %ebx
movd 8(up), %mm0
pmuludq %mm7, %mm0
adc $0, %edx
add %eax, (rp)
L(a1): psrlq $32, %mm1
adc %edx, %ebx
movd %mm1, %edx
movd %mm0, %eax
movd 12(up), %mm1
pmuludq %mm7, %mm1
adc $0, %edx
add %ebx, 4(rp)
psrlq $32, %mm0
adc %edx, %eax
movd %mm0, %edx
movd %mm1, %ebx
lea 16(up), up
movd (up), %mm0
adc $0, %edx
add %eax, 8(rp)
psrlq $32, %mm1
adc %edx, %ebx
movd %mm1, %edx
pmuludq %mm7, %mm0
inc un
movd 4(up), %mm1
jnz L(la1)
adc un, %edx C un is zero here
add %ebx, 12(rp)
movd %mm0, %eax
pmuludq %mm7, %mm1
lea 16(rp), rp
psrlq $32, %mm0
adc %edx, %eax
movd %mm0, %edx
movd %mm1, %ebx
adc un, %edx
add %eax, (rp)
psrlq $32, %mm1
adc %edx, %ebx
movd %mm1, %eax
adc un, %eax
add %ebx, 4(rp)
adc un, %eax
mov %eax, 8(rp)
inc n
C ================================================================
L(ol0): lea (up,n,4), up
movd 4(up), %mm7 C read next U invariant limb
lea 4(rp,n,4), rp
mov n, un
movd 8(up), %mm0
pmuludq %mm7, %mm0
sar $2, un
movd 12(up), %mm1
movd %mm0, %eax
pmuludq %mm7, %mm1
xor %edx, %edx C zero edx and CF
jmp L(a0)
L(la0): adc $0, %edx
add %ebx, 12(rp)
movd %mm0, %eax
pmuludq %mm7, %mm1
lea 16(rp), rp
psrlq $32, %mm0
adc %edx, %eax
movd %mm0, %edx
movd %mm1, %ebx
movd 8(up), %mm0
pmuludq %mm7, %mm0
adc $0, %edx
add %eax, (rp)
psrlq $32, %mm1
adc %edx, %ebx
movd %mm1, %edx
movd %mm0, %eax
movd 12(up), %mm1
pmuludq %mm7, %mm1
adc $0, %edx
add %ebx, 4(rp)
L(a0): psrlq $32, %mm0
adc %edx, %eax
movd %mm0, %edx
movd %mm1, %ebx
lea 16(up), up
movd (up), %mm0
adc $0, %edx
add %eax, 8(rp)
psrlq $32, %mm1
adc %edx, %ebx
movd %mm1, %edx
pmuludq %mm7, %mm0
inc un
movd 4(up), %mm1
jnz L(la0)
adc un, %edx C un is zero here
add %ebx, 12(rp)
movd %mm0, %eax
pmuludq %mm7, %mm1
lea 16(rp), rp
psrlq $32, %mm0
adc %edx, %eax
movd %mm0, %edx
movd %mm1, %ebx
adc un, %edx
add %eax, (rp)
psrlq $32, %mm1
adc %edx, %ebx
movd %mm1, %eax
adc un, %eax
add %ebx, 4(rp)
adc un, %eax
mov %eax, 8(rp)
inc n
C ================================================================
L(ol3): lea 12(up,n,4), up
movd -8(up), %mm7 C read next U invariant limb
lea (rp,n,4), rp C put rp back
mov n, un
movd -4(up), %mm1
pmuludq %mm7, %mm1
sar $2, un
movd %mm1, %ebx
movd (up), %mm0
xor %edx, %edx C zero edx and CF
jmp L(a3)
L(la3): adc $0, %edx
add %ebx, 12(rp)
movd %mm0, %eax
pmuludq %mm7, %mm1
lea 16(rp), rp
psrlq $32, %mm0
adc %edx, %eax
movd %mm0, %edx
movd %mm1, %ebx
movd 8(up), %mm0
pmuludq %mm7, %mm0
adc $0, %edx
add %eax, (rp)
psrlq $32, %mm1
adc %edx, %ebx
movd %mm1, %edx
movd %mm0, %eax
movd 12(up), %mm1
pmuludq %mm7, %mm1
adc $0, %edx
add %ebx, 4(rp)
psrlq $32, %mm0
adc %edx, %eax
movd %mm0, %edx
movd %mm1, %ebx
lea 16(up), up
movd (up), %mm0
adc $0, %edx
add %eax, 8(rp)
L(a3): psrlq $32, %mm1
adc %edx, %ebx
movd %mm1, %edx
pmuludq %mm7, %mm0
inc un
movd 4(up), %mm1
jnz L(la3)
adc un, %edx C un is zero here
add %ebx, 12(rp)
movd %mm0, %eax
pmuludq %mm7, %mm1
lea 16(rp), rp
psrlq $32, %mm0
adc %edx, %eax
movd %mm0, %edx
movd %mm1, %ebx
adc un, %edx
add %eax, (rp)
psrlq $32, %mm1
adc %edx, %ebx
movd %mm1, %eax
adc un, %eax
add %ebx, 4(rp)
adc un, %eax
mov %eax, 8(rp)
inc n
C ================================================================
L(ol2): lea 8(up,n,4), up
movd -4(up), %mm7 C read next U invariant limb
lea 12(rp,n,4), rp
mov n, un
movd (up), %mm0
pmuludq %mm7, %mm0
xor %edx, %edx
sar $2, un
movd 4(up), %mm1
test un, un C clear carry
movd %mm0, %eax
pmuludq %mm7, %mm1
inc un
jnz L(a2)
jmp L(re2)
L(la2): adc $0, %edx
add %ebx, 12(rp)
movd %mm0, %eax
pmuludq %mm7, %mm1
lea 16(rp), rp
L(a2): psrlq $32, %mm0
adc %edx, %eax
movd %mm0, %edx
movd %mm1, %ebx
movd 8(up), %mm0
pmuludq %mm7, %mm0
adc $0, %edx
add %eax, (rp)
psrlq $32, %mm1
adc %edx, %ebx
movd %mm1, %edx
movd %mm0, %eax
movd 12(up), %mm1
pmuludq %mm7, %mm1
adc $0, %edx
add %ebx, 4(rp)
psrlq $32, %mm0
adc %edx, %eax
movd %mm0, %edx
movd %mm1, %ebx
lea 16(up), up
movd (up), %mm0
adc $0, %edx
add %eax, 8(rp)
psrlq $32, %mm1
adc %edx, %ebx
movd %mm1, %edx
pmuludq %mm7, %mm0
inc un
movd 4(up), %mm1
jnz L(la2)
adc un, %edx C un is zero here
add %ebx, 12(rp)
movd %mm0, %eax
pmuludq %mm7, %mm1
lea 16(rp), rp
psrlq $32, %mm0
adc %edx, %eax
movd %mm0, %edx
movd %mm1, %ebx
adc un, %edx
add %eax, (rp)
psrlq $32, %mm1
adc %edx, %ebx
movd %mm1, %eax
adc un, %eax
add %ebx, 4(rp)
adc un, %eax
mov %eax, 8(rp)
inc n
jmp L(ol1)
C ================================================================
L(re2): psrlq $32, %mm0
movd (up), %mm7 C read next U invariant limb
adc %edx, %eax
movd %mm0, %edx
movd %mm1, %ebx
adc un, %edx
add %eax, (rp)
lea 4(rp), rp
psrlq $32, %mm1
adc %edx, %ebx
movd %mm1, %eax
movd 4(up), %mm1
adc un, %eax
add %ebx, (rp)
pmuludq %mm7, %mm1
adc un, %eax
mov %eax, 4(rp)
movd %mm1, %ebx
L(re1): psrlq $32, %mm1
add %ebx, 4(rp)
movd %mm1, %eax
adc un, %eax
xor n, n C make n zeroness assumption below true
mov %eax, 8(rp)
L(done): C n is zero here
mov 24(%esp), up
mov 28(%esp), %eax
movd (up), %mm0
inc %eax
pmuludq %mm0, %mm0
lea 4(up), up
mov 20(%esp), rp
shr %eax
movd %mm0, (rp)
psrlq $32, %mm0
lea -12(rp), rp
mov %eax, 28(%esp)
jnc L(odd)
movd %mm0, %ebp
movd (up), %mm0
lea 8(rp), rp
pmuludq %mm0, %mm0
lea -4(up), up
add 8(rp), %ebp
movd %mm0, %edx
adc 12(rp), %edx
rcr n
jmp L(ent)
C ALIGN(16) C alignment seems irrelevant
L(top): movd (up), %mm1
adc n, n
movd %mm0, %eax
pmuludq %mm1, %mm1
movd 4(up), %mm0
adc (rp), %eax
movd %mm1, %ebx
pmuludq %mm0, %mm0
psrlq $32, %mm1
adc 4(rp), %ebx
movd %mm1, %ebp
movd %mm0, %edx
adc 8(rp), %ebp
adc 12(rp), %edx
rcr n C FIXME: isn't this awfully slow on atom???
adc %eax, (rp)
adc %ebx, 4(rp)
L(ent): lea 8(up), up
adc %ebp, 8(rp)
psrlq $32, %mm0
adc %edx, 12(rp)
L(odd): decl 28(%esp)
lea 16(rp), rp
jnz L(top)
L(end): adc n, n
movd %mm0, %eax
adc n, %eax
mov %eax, (rp)
L(rtn): emms
pop %ebp
pop %ebx
pop %esi
pop %edi
ret
L(one): pmuludq %mm7, %mm7
movq %mm7, -4(rp)
emms
pop %esi
pop %edi
ret
EPILOGUE()

View File

@@ -0,0 +1,34 @@
dnl Intel Atom mpn_sublsh1_n -- rp[] = up[] - (vp[] << 1)
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
MULFUNC_PROLOGUE(mpn_sublsh1_n_ip1)
include_mpn(`x86/k7/sublsh1_n.asm')

View File

@@ -0,0 +1,57 @@
dnl Intel Atom mpn_addlsh2_n/mpn_sublsh2_n -- rp[] = up[] +- (vp[] << 2).
dnl Contributed to the GNU project by Marco Bodrato.
dnl Copyright 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
define(LSH, 2)
define(RSH, 30)
ifdef(`OPERATION_addlsh2_n', `
define(M4_inst, adcl)
define(M4_opp, subl)
define(M4_function, mpn_addlsh2_n)
define(M4_function_c, mpn_addlsh2_nc)
define(M4_ip_function_c, mpn_addlsh2_nc_ip1)
define(M4_ip_function, mpn_addlsh2_n_ip1)
',`ifdef(`OPERATION_sublsh2_n', `
define(M4_inst, sbbl)
define(M4_opp, addl)
define(M4_function, mpn_sublsh2_n)
define(M4_function_c, mpn_sublsh2_nc)
define(M4_ip_function_c, mpn_sublsh2_nc_ip1)
define(M4_ip_function, mpn_sublsh2_n_ip1)
',`m4_error(`Need OPERATION_addlsh2_n or OPERATION_sublsh2_n
')')')
MULFUNC_PROLOGUE(mpn_sublsh2_n mpn_sublsh2_nc mpn_sublsh2_n_ip1 mpn_sublsh2_nc_ip1)
include_mpn(`x86/atom/aorslshC_n.asm')

View File

@@ -0,0 +1,211 @@
/* AMD bd1 gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 2019 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* 3600-3800 MHz Bulldozer Zambezi */
/* FFT tuning limit = 67,000,000 */
/* Generated by tuneup.c, 2019-10-27, gcc 8.3 */
#define MOD_1_NORM_THRESHOLD 0 /* always */
#define MOD_1_UNNORM_THRESHOLD 0 /* always */
#define MOD_1N_TO_MOD_1_1_THRESHOLD 7
#define MOD_1U_TO_MOD_1_1_THRESHOLD 4
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 15
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 13
#define USE_PREINV_DIVREM_1 1 /* native */
#define DIV_QR_1N_PI1_METHOD 1 /* 59.59% faster than 2 */
#define DIV_QR_1_NORM_THRESHOLD 5
#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD 27
#define DIV_1_VS_MUL_1_PERCENT 245
#define MUL_TOOM22_THRESHOLD 32
#define MUL_TOOM33_THRESHOLD 89
#define MUL_TOOM44_THRESHOLD 154
#define MUL_TOOM6H_THRESHOLD 230
#define MUL_TOOM8H_THRESHOLD 351
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 89
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 110
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 101
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 111
#define MUL_TOOM43_TO_TOOM54_THRESHOLD 130
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 46
#define SQR_TOOM3_THRESHOLD 87
#define SQR_TOOM4_THRESHOLD 216
#define SQR_TOOM6_THRESHOLD 294
#define SQR_TOOM8_THRESHOLD 442
#define MULMID_TOOM42_THRESHOLD 50
#define MULMOD_BNM1_THRESHOLD 22
#define SQRMOD_BNM1_THRESHOLD 26
#define MUL_FFT_MODF_THRESHOLD 636 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 636, 5}, { 28, 6}, { 15, 5}, { 31, 6}, \
{ 28, 7}, { 15, 6}, { 33, 7}, { 17, 6}, \
{ 35, 7}, { 19, 6}, { 39, 7}, { 23, 6}, \
{ 47, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
{ 19, 7}, { 41, 8}, { 23, 7}, { 47, 8}, \
{ 27, 7}, { 55, 8}, { 31, 7}, { 63, 8}, \
{ 43, 9}, { 23, 8}, { 55, 9}, { 31, 8}, \
{ 67, 9}, { 39, 8}, { 79, 9}, { 47, 8}, \
{ 95, 9}, { 55,10}, { 31, 9}, { 79,10}, \
{ 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
{ 135,10}, { 79, 9}, { 159,10}, { 95, 9}, \
{ 191,11}, { 63, 7}, { 1023, 8}, { 543,11}, \
{ 95,10}, { 191,12}, { 63,11}, { 127,10}, \
{ 255, 9}, { 511,10}, { 271,11}, { 159,10}, \
{ 319, 9}, { 639,10}, { 335,11}, { 191,10}, \
{ 399,11}, { 223,12}, { 127,11}, { 255,10}, \
{ 543,11}, { 287,10}, { 607,11}, { 319,10}, \
{ 639,12}, { 191,11}, { 383,10}, { 799,11}, \
{ 415,13}, { 127,12}, { 255,11}, { 543,10}, \
{ 1087,11}, { 607,12}, { 319,11}, { 671,10}, \
{ 1343,11}, { 735,12}, { 383,11}, { 799,10}, \
{ 1599,11}, { 863,12}, { 447,11}, { 895,13}, \
{ 255,12}, { 511,11}, { 1087,12}, { 575,11}, \
{ 1215,12}, { 639,11}, { 1343,12}, { 703,11}, \
{ 1471,13}, { 383,12}, { 767,11}, { 1599,12}, \
{ 831,11}, { 1727,12}, { 895,14}, { 255,13}, \
{ 511,12}, { 1087,11}, { 2239,10}, { 4479,12}, \
{ 1215,13}, { 639,12}, { 1471,11}, { 2943,13}, \
{ 767,12}, { 1727,11}, { 3455,13}, { 895,12}, \
{ 1919,14}, { 511,13}, { 1023,12}, { 2239,11}, \
{ 4479,13}, { 1151,12}, { 2495,11}, { 4991,13}, \
{ 1279,12}, { 2623,13}, { 1407,12}, { 2943,14}, \
{ 767,13}, { 1663,12}, { 3455,13}, { 1919,15}, \
{ 511,14}, { 1023,13}, { 2175,12}, { 4479,13}, \
{ 2431,12}, { 4991,14}, { 1279,13}, { 2943,12}, \
{ 5887,14}, { 1535,13}, { 3455,14}, { 1791,13}, \
{ 3967,12}, { 7935,15}, { 1023,14}, { 2047,13}, \
{ 4479,14}, { 2303,13}, { 4991,12}, { 9983,14}, \
{ 2815,13}, { 5887,15}, { 1535,14}, { 3327,13}, \
{ 6911,14}, { 3839,13}, { 7935,16} }
#define MUL_FFT_TABLE3_SIZE 159
#define MUL_FFT_THRESHOLD 6784
#define SQR_FFT_MODF_THRESHOLD 565 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 565, 5}, { 29, 6}, { 15, 5}, { 32, 6}, \
{ 17, 5}, { 35, 6}, { 29, 7}, { 15, 6}, \
{ 33, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
{ 39, 7}, { 23, 6}, { 47, 7}, { 35, 8}, \
{ 19, 7}, { 41, 8}, { 23, 7}, { 49, 8}, \
{ 27, 7}, { 55, 8}, { 43, 9}, { 23, 8}, \
{ 55, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
{ 79, 9}, { 47, 8}, { 95, 9}, { 55,10}, \
{ 31, 9}, { 79,10}, { 47, 9}, { 95,11}, \
{ 31,10}, { 63, 9}, { 135,10}, { 79, 9}, \
{ 159,10}, { 95,11}, { 63,10}, { 159,11}, \
{ 127,10}, { 255, 9}, { 511,10}, { 271, 9}, \
{ 543,11}, { 159,10}, { 319, 9}, { 639,10}, \
{ 335, 9}, { 671,11}, { 191,10}, { 415,11}, \
{ 223,12}, { 127,11}, { 255,10}, { 543,11}, \
{ 287,10}, { 607,11}, { 319,10}, { 671,12}, \
{ 191,11}, { 383,10}, { 799,11}, { 415,10}, \
{ 831,13}, { 127,12}, { 255,11}, { 543,10}, \
{ 1087,11}, { 607,12}, { 319,11}, { 671,10}, \
{ 1343,11}, { 735,12}, { 383,11}, { 863,12}, \
{ 447,11}, { 959,13}, { 255,12}, { 511,11}, \
{ 1087,12}, { 575,11}, { 1215,12}, { 639,11}, \
{ 1343,12}, { 703,13}, { 383,12}, { 767,11}, \
{ 1535,12}, { 831,11}, { 1727,12}, { 895,11}, \
{ 1791,12}, { 959,14}, { 255,13}, { 511,12}, \
{ 1087,11}, { 2239,10}, { 4479,12}, { 1215,13}, \
{ 639,12}, { 1471,11}, { 2943,13}, { 767,12}, \
{ 1727,13}, { 895,12}, { 1919,14}, { 511,13}, \
{ 1023,12}, { 2239,11}, { 4479,13}, { 1151,12}, \
{ 2495,11}, { 4991,13}, { 1279,12}, { 2623,13}, \
{ 1407,12}, { 2943,14}, { 767,13}, { 1663,12}, \
{ 3455,13}, { 1919,15}, { 511,14}, { 1023,13}, \
{ 2175,12}, { 4479,13}, { 2431,12}, { 4991,14}, \
{ 1279,13}, { 2943,12}, { 5887,14}, { 1535,13}, \
{ 3455,14}, { 1791,13}, { 3967,15}, { 1023,14}, \
{ 2047,13}, { 4479,14}, { 2303,13}, { 4991,12}, \
{ 9983,14}, { 2815,13}, { 5887,15}, { 1535,14}, \
{ 3327,13}, { 6783,14}, { 3839,13}, { 7679,16} }
#define SQR_FFT_TABLE3_SIZE 152
#define SQR_FFT_THRESHOLD 5760
#define MULLO_BASECASE_THRESHOLD 3
#define MULLO_DC_THRESHOLD 31
#define MULLO_MUL_N_THRESHOLD 13463
#define SQRLO_BASECASE_THRESHOLD 0 /* always */
#define SQRLO_DC_THRESHOLD 33
#define SQRLO_SQR_THRESHOLD 11278
#define DC_DIV_QR_THRESHOLD 52
#define DC_DIVAPPR_Q_THRESHOLD 198
#define DC_BDIV_QR_THRESHOLD 48
#define DC_BDIV_Q_THRESHOLD 126
#define INV_MULMOD_BNM1_THRESHOLD 82
#define INV_NEWTON_THRESHOLD 212
#define INV_APPR_THRESHOLD 202
#define BINV_NEWTON_THRESHOLD 238
#define REDC_1_TO_REDC_N_THRESHOLD 55
#define MU_DIV_QR_THRESHOLD 1652
#define MU_DIVAPPR_Q_THRESHOLD 1528
#define MUPI_DIV_QR_THRESHOLD 110
#define MU_BDIV_QR_THRESHOLD 1442
#define MU_BDIV_Q_THRESHOLD 1528
#define POWM_SEC_TABLE 1,20,96,386,1221,2698
#define GET_STR_DC_THRESHOLD 11
#define GET_STR_PRECOMPUTE_THRESHOLD 21
#define SET_STR_DC_THRESHOLD 100
#define SET_STR_PRECOMPUTE_THRESHOLD 762
#define FAC_DSC_THRESHOLD 118
#define FAC_ODD_THRESHOLD 34
#define MATRIX22_STRASSEN_THRESHOLD 16
#define HGCD2_DIV1_METHOD 4 /* 1.22% faster than 3 */
#define HGCD_THRESHOLD 67
#define HGCD_APPR_THRESHOLD 150
#define HGCD_REDUCE_THRESHOLD 3389
#define GCD_DC_THRESHOLD 483
#define GCDEXT_DC_THRESHOLD 345
#define JACOBI_BASE_METHOD 4 /* 5.07% faster than 1 */
/* Tuneup completed successfully, took 65358 seconds */

View File

@@ -0,0 +1,214 @@
/* AMD bd2 gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 2019 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* 4000-4200 MHz Piledriver Vishera */
/* FFT tuning limit = 67,000,000 */
/* Generated by tuneup.c, 2019-10-23, gcc 8.3 */
#define MOD_1_NORM_THRESHOLD 3
#define MOD_1_UNNORM_THRESHOLD 4
#define MOD_1N_TO_MOD_1_1_THRESHOLD 6
#define MOD_1U_TO_MOD_1_1_THRESHOLD 4
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 18
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 12
#define USE_PREINV_DIVREM_1 1 /* native */
#define DIV_QR_1N_PI1_METHOD 1 /* 40.87% faster than 2 */
#define DIV_QR_1_NORM_THRESHOLD 5
#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD 24
#define DIV_1_VS_MUL_1_PERCENT 254
#define MUL_TOOM22_THRESHOLD 32
#define MUL_TOOM33_THRESHOLD 73
#define MUL_TOOM44_THRESHOLD 151
#define MUL_TOOM6H_THRESHOLD 222
#define MUL_TOOM8H_THRESHOLD 351
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 85
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 110
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 100
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 110
#define MUL_TOOM43_TO_TOOM54_THRESHOLD 130
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 44
#define SQR_TOOM3_THRESHOLD 93
#define SQR_TOOM4_THRESHOLD 212
#define SQR_TOOM6_THRESHOLD 318
#define SQR_TOOM8_THRESHOLD 466
#define MULMID_TOOM42_THRESHOLD 66
#define MULMOD_BNM1_THRESHOLD 20
#define SQRMOD_BNM1_THRESHOLD 23
#define MUL_FFT_MODF_THRESHOLD 595 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 595, 5}, { 27, 6}, { 29, 7}, { 15, 6}, \
{ 33, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
{ 39, 7}, { 23, 6}, { 47, 7}, { 29, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
{ 23, 7}, { 49, 8}, { 31, 7}, { 63, 8}, \
{ 39, 9}, { 23, 8}, { 55, 9}, { 31, 8}, \
{ 67, 9}, { 39, 8}, { 83, 9}, { 47, 8}, \
{ 95, 9}, { 55,10}, { 31, 9}, { 79,10}, \
{ 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
{ 135,10}, { 79, 9}, { 159,10}, { 95, 9}, \
{ 191,11}, { 63,10}, { 143, 7}, { 1215, 9}, \
{ 319, 8}, { 639, 9}, { 335, 8}, { 671, 9}, \
{ 351,10}, { 191,12}, { 63,11}, { 127,10}, \
{ 271,11}, { 159,10}, { 319, 9}, { 639,10}, \
{ 335,11}, { 191,10}, { 399,11}, { 223,12}, \
{ 127,11}, { 255,10}, { 543,11}, { 287,10}, \
{ 607,11}, { 319,10}, { 671,12}, { 191,11}, \
{ 383,10}, { 799,11}, { 415,13}, { 127,12}, \
{ 255,11}, { 543,10}, { 1087,11}, { 607,12}, \
{ 319,11}, { 671,10}, { 1343,11}, { 735,10}, \
{ 1471,12}, { 383,11}, { 799,10}, { 1599,11}, \
{ 863,12}, { 447,11}, { 895,13}, { 255,12}, \
{ 511,11}, { 1087,12}, { 575,11}, { 1215,12}, \
{ 639,11}, { 1343,12}, { 703,11}, { 1471,13}, \
{ 383,12}, { 767,11}, { 1599,12}, { 831,11}, \
{ 1727,12}, { 895,14}, { 255,13}, { 511,12}, \
{ 1087,11}, { 2239,12}, { 1215,13}, { 639,12}, \
{ 1471,11}, { 2943,13}, { 767,12}, { 1727,13}, \
{ 895,12}, { 1919,14}, { 511,13}, { 1023,12}, \
{ 2239,13}, { 1151,12}, { 2431,13}, { 1279,12}, \
{ 2623,13}, { 1407,12}, { 2943,14}, { 767,13}, \
{ 1535,12}, { 3135,13}, { 1663,12}, { 3455,13}, \
{ 1919,15}, { 511,14}, { 1023,13}, { 2175,12}, \
{ 4479,13}, { 2431,14}, { 1279,13}, { 2943,12}, \
{ 5887,14}, { 1535,13}, { 3455,14}, { 1791,13}, \
{ 3967,12}, { 7935,11}, { 15871,15}, { 1023,14}, \
{ 2047,13}, { 4479,14}, { 2303,13}, { 4991,12}, \
{ 9983,14}, { 2815,13}, { 5887,15}, { 1535,14}, \
{ 3839,13}, { 7935,12}, { 15871,16} }
#define MUL_FFT_TABLE3_SIZE 155
#define MUL_FFT_THRESHOLD 6784
#define SQR_FFT_MODF_THRESHOLD 555 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 555, 5}, { 28, 6}, { 15, 5}, { 31, 6}, \
{ 16, 5}, { 33, 6}, { 29, 7}, { 15, 6}, \
{ 33, 7}, { 17, 6}, { 36, 7}, { 19, 6}, \
{ 39, 7}, { 23, 6}, { 47, 7}, { 29, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 43, 8}, \
{ 23, 7}, { 49, 8}, { 31, 7}, { 63, 8}, \
{ 43, 9}, { 23, 8}, { 55, 9}, { 31, 8}, \
{ 67, 9}, { 39, 8}, { 79, 9}, { 47, 8}, \
{ 95, 9}, { 55,10}, { 31, 9}, { 79,10}, \
{ 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
{ 135,10}, { 79, 9}, { 159,10}, { 95,11}, \
{ 63,10}, { 143, 9}, { 287,10}, { 159,11}, \
{ 95,10}, { 191, 6}, { 3071, 5}, { 6399, 6}, \
{ 3455, 7}, { 1791, 8}, { 959,10}, { 255, 9}, \
{ 511,10}, { 271,11}, { 159,10}, { 319, 9}, \
{ 639,10}, { 335, 9}, { 671,10}, { 351,11}, \
{ 191,10}, { 399, 9}, { 799,10}, { 415,11}, \
{ 223,12}, { 127,11}, { 255,10}, { 543,11}, \
{ 287,10}, { 607,11}, { 319,10}, { 671,11}, \
{ 351,12}, { 191,11}, { 383,10}, { 799,11}, \
{ 415,13}, { 127,12}, { 255,11}, { 543,10}, \
{ 1087,11}, { 607,12}, { 319,11}, { 671,10}, \
{ 1343,11}, { 735,12}, { 383,11}, { 799,10}, \
{ 1599,11}, { 863,12}, { 447,11}, { 927,13}, \
{ 255,12}, { 511,11}, { 1055,10}, { 2111,11}, \
{ 1087,12}, { 575,11}, { 1215,12}, { 639,11}, \
{ 1343,12}, { 703,13}, { 383,12}, { 767,11}, \
{ 1599,12}, { 831,11}, { 1727,10}, { 3455,12}, \
{ 959,14}, { 255,13}, { 511,12}, { 1023,11}, \
{ 2111,12}, { 1087,11}, { 2239,10}, { 4479,12}, \
{ 1215,13}, { 639,12}, { 1471,11}, { 2943,13}, \
{ 767,12}, { 1727,11}, { 3455,13}, { 895,12}, \
{ 1855,14}, { 511,13}, { 1023,12}, { 2239,13}, \
{ 1151,12}, { 2495,13}, { 1279,12}, { 2623,13}, \
{ 1407,12}, { 2943,14}, { 767,13}, { 1663,12}, \
{ 3455,13}, { 1791,15}, { 511,14}, { 1023,13}, \
{ 2175,12}, { 4479,13}, { 2431,14}, { 1279,13}, \
{ 2943,12}, { 5887,14}, { 1535,13}, { 3455,14}, \
{ 1791,13}, { 3967,12}, { 7935,15}, { 1023,14}, \
{ 2047,13}, { 4479,14}, { 2303,13}, { 4991,12}, \
{ 9983,14}, { 2815,13}, { 5887,15}, { 1535,14}, \
{ 3839,13}, { 7935,16} }
#define SQR_FFT_TABLE3_SIZE 166
#define SQR_FFT_THRESHOLD 5760
#define MULLO_BASECASE_THRESHOLD 3
#define MULLO_DC_THRESHOLD 34
#define MULLO_MUL_N_THRESHOLD 13463
#define SQRLO_BASECASE_THRESHOLD 8
#define SQRLO_DC_THRESHOLD 43
#define SQRLO_SQR_THRESHOLD 11278
#define DC_DIV_QR_THRESHOLD 75
#define DC_DIVAPPR_Q_THRESHOLD 200
#define DC_BDIV_QR_THRESHOLD 71
#define DC_BDIV_Q_THRESHOLD 119
#define INV_MULMOD_BNM1_THRESHOLD 74
#define INV_NEWTON_THRESHOLD 266
#define INV_APPR_THRESHOLD 214
#define BINV_NEWTON_THRESHOLD 278
#define REDC_1_TO_REDC_N_THRESHOLD 71
#define MU_DIV_QR_THRESHOLD 1652
#define MU_DIVAPPR_Q_THRESHOLD 1589
#define MUPI_DIV_QR_THRESHOLD 122
#define MU_BDIV_QR_THRESHOLD 1442
#define MU_BDIV_Q_THRESHOLD 1597
#define POWM_SEC_TABLE 1,22,96,289,1259
#define GET_STR_DC_THRESHOLD 11
#define GET_STR_PRECOMPUTE_THRESHOLD 20
#define SET_STR_DC_THRESHOLD 173
#define SET_STR_PRECOMPUTE_THRESHOLD 454
#define FAC_DSC_THRESHOLD 90
#define FAC_ODD_THRESHOLD 34
#define MATRIX22_STRASSEN_THRESHOLD 19
#define HGCD2_DIV1_METHOD 1 /* 5.80% faster than 3 */
#define HGCD_THRESHOLD 74
#define HGCD_APPR_THRESHOLD 50
#define HGCD_REDUCE_THRESHOLD 3389
#define GCD_DC_THRESHOLD 456
#define GCDEXT_DC_THRESHOLD 345
#define JACOBI_BASE_METHOD 4 /* 17.07% faster than 1 */
/* Tuneup completed successfully, took 53914 seconds */

View File

@@ -0,0 +1,225 @@
/* AMD bd4 gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 2019 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* 3800-4200 MHz Excavator/Bristol Ridge */
/* FFT tuning limit = 67,000,000 */
/* Generated by tuneup.c, 2019-10-23, gcc 8.3 */
#define MOD_1_NORM_THRESHOLD 0 /* always */
#define MOD_1_UNNORM_THRESHOLD 0 /* always */
#define MOD_1N_TO_MOD_1_1_THRESHOLD 8
#define MOD_1U_TO_MOD_1_1_THRESHOLD 6
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 27
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 50
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 13
#define USE_PREINV_DIVREM_1 1 /* native */
#define DIV_QR_1N_PI1_METHOD 1 /* 28.45% faster than 2 */
#define DIV_QR_1_NORM_THRESHOLD 4
#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_2_PI2_THRESHOLD 13
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD 28
#define DIV_1_VS_MUL_1_PERCENT 314
#define MUL_TOOM22_THRESHOLD 32
#define MUL_TOOM33_THRESHOLD 73
#define MUL_TOOM44_THRESHOLD 166
#define MUL_TOOM6H_THRESHOLD 270
#define MUL_TOOM8H_THRESHOLD 357
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 69
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 114
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 103
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 121
#define MUL_TOOM43_TO_TOOM54_THRESHOLD 154
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 42
#define SQR_TOOM3_THRESHOLD 89
#define SQR_TOOM4_THRESHOLD 208
#define SQR_TOOM6_THRESHOLD 306
#define SQR_TOOM8_THRESHOLD 454
#define MULMID_TOOM42_THRESHOLD 68
#define MULMOD_BNM1_THRESHOLD 19
#define SQRMOD_BNM1_THRESHOLD 18
#define MUL_FFT_MODF_THRESHOLD 570 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 570, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
{ 25, 7}, { 13, 6}, { 27, 7}, { 15, 6}, \
{ 32, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
{ 39, 7}, { 27, 8}, { 15, 7}, { 35, 8}, \
{ 19, 7}, { 41, 8}, { 23, 7}, { 47, 8}, \
{ 27, 9}, { 15, 8}, { 31, 7}, { 63, 8}, \
{ 39, 9}, { 23, 8}, { 51,10}, { 15, 9}, \
{ 31, 8}, { 67, 9}, { 39, 8}, { 79, 9}, \
{ 47, 8}, { 95,10}, { 31, 9}, { 79,10}, \
{ 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
{ 135,10}, { 79, 9}, { 159,10}, { 95, 9}, \
{ 191,11}, { 63,10}, { 143, 6}, { 2303, 5}, \
{ 4735, 4}, { 9471, 5}, { 4863, 7}, { 1279, 9}, \
{ 335, 8}, { 671, 9}, { 351, 8}, { 703,10}, \
{ 191,12}, { 63,11}, { 127,10}, { 255, 9}, \
{ 511,10}, { 271, 9}, { 543,11}, { 159,10}, \
{ 319, 9}, { 639,10}, { 335, 9}, { 671, 8}, \
{ 1343,10}, { 351, 9}, { 703,10}, { 367, 9}, \
{ 735,11}, { 191,10}, { 383, 9}, { 767,10}, \
{ 399, 9}, { 799, 8}, { 1599,10}, { 415,11}, \
{ 223,12}, { 127,11}, { 255,10}, { 543, 9}, \
{ 1087,11}, { 287,10}, { 607, 9}, { 1215,11}, \
{ 319,10}, { 671, 9}, { 1343,11}, { 351,12}, \
{ 191,11}, { 383,10}, { 799,11}, { 415,10}, \
{ 863,13}, { 127,12}, { 255,11}, { 543,10}, \
{ 1087,11}, { 607,10}, { 1215, 9}, { 2431,12}, \
{ 319,11}, { 671,10}, { 1343,11}, { 735,10}, \
{ 1471, 9}, { 2943,12}, { 383,11}, { 799,10}, \
{ 1599,11}, { 863,10}, { 1727,12}, { 447,11}, \
{ 959,10}, { 1919,13}, { 255,12}, { 511,11}, \
{ 1087,12}, { 575,11}, { 1215,10}, { 2431,12}, \
{ 639,11}, { 1343,12}, { 703,11}, { 1471,10}, \
{ 2943,13}, { 383,12}, { 767,11}, { 1599,12}, \
{ 831,11}, { 1727,10}, { 3455,12}, { 959,11}, \
{ 1919,10}, { 3839,13}, { 511,12}, { 1087,11}, \
{ 2239,12}, { 1215,11}, { 2431,13}, { 639,12}, \
{ 1471,11}, { 2943,10}, { 5887,13}, { 767,12}, \
{ 1727,11}, { 3455,13}, { 895,12}, { 1919,11}, \
{ 3839,14}, { 511,13}, { 1023,12}, { 2239,13}, \
{ 1151,12}, { 2431,13}, { 1279,12}, { 2559,13}, \
{ 1407,12}, { 2943,11}, { 5887,14}, { 767,13}, \
{ 1663,12}, { 3455,13}, { 1919,12}, { 3839,15}, \
{ 511,14}, { 1023,13}, { 2175,12}, { 4479,13}, \
{ 2431,14}, { 1279,13}, { 2943,12}, { 5887,14}, \
{ 1535,13}, { 3455,14}, { 1791,13}, { 3967,12}, \
{ 7935,15}, { 1023,14}, { 2047,13}, { 4479,14}, \
{ 2303,13}, { 4991,12}, { 9983,14}, { 2815,13}, \
{ 5887,15}, { 1535,14}, { 3839,13}, { 7935,16} }
#define MUL_FFT_TABLE3_SIZE 192
#define MUL_FFT_THRESHOLD 5760
#define SQR_FFT_MODF_THRESHOLD 476 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 476, 5}, { 28, 6}, { 15, 5}, { 31, 6}, \
{ 16, 5}, { 33, 6}, { 29, 7}, { 15, 6}, \
{ 33, 7}, { 17, 6}, { 36, 7}, { 19, 6}, \
{ 39, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
{ 19, 7}, { 41, 8}, { 23, 7}, { 47, 8}, \
{ 27, 9}, { 15, 8}, { 39, 9}, { 23, 8}, \
{ 51, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
{ 79, 9}, { 47, 8}, { 95,10}, { 31, 9}, \
{ 79,10}, { 47, 9}, { 95,11}, { 31,10}, \
{ 63, 9}, { 135,10}, { 95, 9}, { 191,10}, \
{ 111,11}, { 63,10}, { 127, 9}, { 255,10}, \
{ 143, 9}, { 287, 8}, { 575,10}, { 159,11}, \
{ 95,10}, { 191,12}, { 63,10}, { 255, 9}, \
{ 511,10}, { 271, 9}, { 543,10}, { 287, 9}, \
{ 575,11}, { 159,10}, { 319, 9}, { 639,10}, \
{ 335, 9}, { 671,10}, { 351, 9}, { 735,11}, \
{ 191,10}, { 383, 9}, { 767,10}, { 399, 9}, \
{ 799,10}, { 415, 9}, { 863,12}, { 127,11}, \
{ 255,10}, { 511, 9}, { 1023,10}, { 543,11}, \
{ 287,10}, { 607, 9}, { 1215,11}, { 319,10}, \
{ 671, 9}, { 1343,11}, { 351,10}, { 735,12}, \
{ 191,11}, { 383,10}, { 799,11}, { 415,10}, \
{ 863,13}, { 127,12}, { 255,11}, { 511,10}, \
{ 1055,11}, { 543,10}, { 1087,11}, { 607,10}, \
{ 1215,12}, { 319,11}, { 671,10}, { 1343,11}, \
{ 735,10}, { 1471,12}, { 383,11}, { 799,10}, \
{ 1599,11}, { 863,10}, { 1727,12}, { 447,11}, \
{ 959,13}, { 255,12}, { 511,11}, { 1087,12}, \
{ 575,11}, { 1215,12}, { 639,11}, { 1343,12}, \
{ 703,11}, { 1471,13}, { 383,12}, { 767,11}, \
{ 1599,12}, { 831,11}, { 1727,12}, { 959,11}, \
{ 1919,14}, { 255,13}, { 511,12}, { 1023,11}, \
{ 2047,12}, { 1087,11}, { 2239,12}, { 1215,11}, \
{ 2431,13}, { 639,12}, { 1471,11}, { 2943,13}, \
{ 767,12}, { 1727,13}, { 895,12}, { 1983,14}, \
{ 511,13}, { 1023,12}, { 2239,13}, { 1151,12}, \
{ 2431,13}, { 1279,12}, { 2559,13}, { 1407,12}, \
{ 2943,14}, { 767,13}, { 1663,12}, { 3455,13}, \
{ 1919,12}, { 3839,15}, { 511,14}, { 1023,13}, \
{ 2175,12}, { 4479,13}, { 2431,14}, { 1279,13}, \
{ 2943,12}, { 5887,14}, { 1535,13}, { 3455,14}, \
{ 1791,13}, { 3967,15}, { 1023,14}, { 2047,13}, \
{ 4479,14}, { 2303,13}, { 4991,12}, { 9983,14}, \
{ 2815,13}, { 5887,15}, { 1535,14}, { 3839,16} }
#define SQR_FFT_TABLE3_SIZE 176
#define SQR_FFT_THRESHOLD 4736
#define MULLO_BASECASE_THRESHOLD 3
#define MULLO_DC_THRESHOLD 54
#define MULLO_MUL_N_THRESHOLD 10950
#define SQRLO_BASECASE_THRESHOLD 10
#define SQRLO_DC_THRESHOLD 77
#define SQRLO_SQR_THRESHOLD 9449
#define DC_DIV_QR_THRESHOLD 84
#define DC_DIVAPPR_Q_THRESHOLD 252
#define DC_BDIV_QR_THRESHOLD 79
#define DC_BDIV_Q_THRESHOLD 80
#define INV_MULMOD_BNM1_THRESHOLD 71
#define INV_NEWTON_THRESHOLD 254
#define INV_APPR_THRESHOLD 266
#define BINV_NEWTON_THRESHOLD 294
#define REDC_1_TO_REDC_N_THRESHOLD 79
#define MU_DIV_QR_THRESHOLD 1652
#define MU_DIVAPPR_Q_THRESHOLD 1528
#define MUPI_DIV_QR_THRESHOLD 122
#define MU_BDIV_QR_THRESHOLD 1387
#define MU_BDIV_Q_THRESHOLD 1528
#define POWM_SEC_TABLE 1,16,96,480,960
#define GET_STR_DC_THRESHOLD 12
#define GET_STR_PRECOMPUTE_THRESHOLD 19
#define SET_STR_DC_THRESHOLD 264
#define SET_STR_PRECOMPUTE_THRESHOLD 542
#define FAC_DSC_THRESHOLD 91
#define FAC_ODD_THRESHOLD 29
#define MATRIX22_STRASSEN_THRESHOLD 19
#define HGCD2_DIV1_METHOD 1 /* 9.73% faster than 3 */
#define HGCD_THRESHOLD 55
#define HGCD_APPR_THRESHOLD 50
#define HGCD_REDUCE_THRESHOLD 3389
#define GCD_DC_THRESHOLD 562
#define GCDEXT_DC_THRESHOLD 416
#define JACOBI_BASE_METHOD 4 /* 16.50% faster than 1 */
/* Tuneup completed successfully, took 49179 seconds */

View File

@@ -0,0 +1,129 @@
dnl x86 mpn_bdiv_dbm1.
dnl Copyright 2008, 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C P5
C P6 model 0-8,10-12)
C P6 model 9 (Banias)
C P6 model 13 (Dothan) 5.1
C P4 model 0 (Willamette)
C P4 model 1 (?)
C P4 model 2 (Northwood) 13.67
C P4 model 3 (Prescott)
C P4 model 4 (Nocona)
C Intel Atom
C AMD K6
C AMD K7 3.5
C AMD K8
C AMD K10
C TODO
C * Optimize for more x86 processors
ASM_START()
TEXT
ALIGN(16)
PROLOGUE(mpn_bdiv_dbm1c)
mov 16(%esp), %ecx C d
push %esi
mov 12(%esp), %esi C ap
push %edi
mov 12(%esp), %edi C qp
push %ebp
mov 24(%esp), %ebp C n
push %ebx
mov (%esi), %eax
mul %ecx
mov 36(%esp), %ebx
sub %eax, %ebx
mov %ebx, (%edi)
sbb %edx, %ebx
mov %ebp, %eax
and $3, %eax
jz L(b0)
cmp $2, %eax
jc L(b1)
jz L(b2)
L(b3): lea -8(%esi), %esi
lea 8(%edi), %edi
add $-3, %ebp
jmp L(3)
L(b0): mov 4(%esi), %eax
lea -4(%esi), %esi
lea 12(%edi), %edi
add $-4, %ebp
jmp L(0)
L(b2): mov 4(%esi), %eax
lea 4(%esi), %esi
lea 4(%edi), %edi
add $-2, %ebp
jmp L(2)
ALIGN(8)
L(top): mov 4(%esi), %eax
mul %ecx
lea 16(%edi), %edi
sub %eax, %ebx
mov 8(%esi), %eax
mov %ebx, -12(%edi)
sbb %edx, %ebx
L(0): mul %ecx
sub %eax, %ebx
mov %ebx, -8(%edi)
sbb %edx, %ebx
L(3): mov 12(%esi), %eax
mul %ecx
sub %eax, %ebx
mov %ebx, -4(%edi)
mov 16(%esi), %eax
lea 16(%esi), %esi
sbb %edx, %ebx
L(2): mul %ecx
sub %eax, %ebx
mov %ebx, 0(%edi)
sbb %edx, %ebx
L(b1): add $-4, %ebp
jns L(top)
mov %ebx, %eax
pop %ebx
pop %ebp
pop %edi
pop %esi
ret
EPILOGUE()

View File

@@ -0,0 +1,208 @@
dnl x86 mpn_bdiv_q_1 -- mpn by limb exact division.
dnl Rearranged from mpn/x86/dive_1.asm by Marco Bodrato.
dnl Copyright 2001, 2002, 2007, 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C P54 30.0
C P55 29.0
C P6 13.0 odd divisor, 12.0 even (strangely)
C K6 14.0
C K7 12.0
C P4 42.0
MULFUNC_PROLOGUE(mpn_bdiv_q_1 mpn_pi1_bdiv_q_1)
defframe(PARAM_SHIFT, 24)
defframe(PARAM_INVERSE,20)
defframe(PARAM_DIVISOR,16)
defframe(PARAM_SIZE, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
dnl re-use parameter space
define(VAR_INVERSE,`PARAM_SRC')
TEXT
C mp_limb_t
C mpn_pi1_bdiv_q_1 (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor,
C mp_limb_t inverse, int shift)
ALIGN(16)
PROLOGUE(mpn_pi1_bdiv_q_1)
deflit(`FRAME',0)
movl PARAM_SHIFT, %ecx
pushl %ebp FRAME_pushl()
movl PARAM_INVERSE, %eax
movl PARAM_SIZE, %ebp
pushl %ebx FRAME_pushl()
L(common):
pushl %edi FRAME_pushl()
pushl %esi FRAME_pushl()
movl PARAM_SRC, %esi
movl PARAM_DST, %edi
leal (%esi,%ebp,4), %esi C src end
leal (%edi,%ebp,4), %edi C dst end
negl %ebp C -size
movl %eax, VAR_INVERSE
movl (%esi,%ebp,4), %eax C src[0]
xorl %ebx, %ebx
xorl %edx, %edx
incl %ebp
jz L(one)
movl (%esi,%ebp,4), %edx C src[1]
shrdl( %cl, %edx, %eax)
movl VAR_INVERSE, %edx
jmp L(entry)
ALIGN(8)
nop C k6 code alignment
nop
L(top):
C eax q
C ebx carry bit, 0 or -1
C ecx shift
C edx carry limb
C esi src end
C edi dst end
C ebp counter, limbs, negative
movl -4(%esi,%ebp,4), %eax
subl %ebx, %edx C accumulate carry bit
movl (%esi,%ebp,4), %ebx
shrdl( %cl, %ebx, %eax)
subl %edx, %eax C apply carry limb
movl VAR_INVERSE, %edx
sbbl %ebx, %ebx
L(entry):
imull %edx, %eax
movl %eax, -4(%edi,%ebp,4)
movl PARAM_DIVISOR, %edx
mull %edx
incl %ebp
jnz L(top)
movl -4(%esi), %eax C src high limb
L(one):
shrl %cl, %eax
popl %esi FRAME_popl()
addl %ebx, %eax C apply carry bit
subl %edx, %eax C apply carry limb
imull VAR_INVERSE, %eax
movl %eax, -4(%edi)
popl %edi
popl %ebx
popl %ebp
ret
EPILOGUE()
C mp_limb_t mpn_bdiv_q_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
C mp_limb_t divisor);
C
ALIGN(16)
PROLOGUE(mpn_bdiv_q_1)
deflit(`FRAME',0)
movl PARAM_DIVISOR, %eax
pushl %ebp FRAME_pushl()
movl $-1, %ecx C shift count
movl PARAM_SIZE, %ebp
pushl %ebx FRAME_pushl()
L(strip_twos):
incl %ecx
shrl %eax
jnc L(strip_twos)
leal 1(%eax,%eax), %ebx C d without twos
andl $127, %eax C d/2, 7 bits
ifdef(`PIC',`
LEA( binvert_limb_table, %edx)
movzbl (%eax,%edx), %eax C inv 8 bits
',`
movzbl binvert_limb_table(%eax), %eax C inv 8 bits
')
leal (%eax,%eax), %edx C 2*inv
movl %ebx, PARAM_DIVISOR C d without twos
imull %eax, %eax C inv*inv
imull %ebx, %eax C inv*inv*d
subl %eax, %edx C inv = 2*inv - inv*inv*d
leal (%edx,%edx), %eax C 2*inv
imull %edx, %edx C inv*inv
imull %ebx, %edx C inv*inv*d
subl %edx, %eax C inv = 2*inv - inv*inv*d
ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
pushl %eax FRAME_pushl()
imull PARAM_DIVISOR, %eax
cmpl $1, %eax
popl %eax FRAME_popl()')
jmp L(common)
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,218 @@
/* x86/bobcat gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 2019 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* NOTE: In a fat binary build SQR_TOOM2_THRESHOLD here cannot be greater than
the value in mpn/x86/k7/gmp-mparam.h. The latter is used as a hard limit in
k7/sqr_basecase.asm. */
/* 1600 MHz AMD Bobcat Zacate E-350 */
/* FFT tuning limit = 67,000,000 */
/* Generated by tuneup.c, 2019-10-17, gcc 8.3 */
#define MOD_1_NORM_THRESHOLD 0 /* always */
#define MOD_1_UNNORM_THRESHOLD 0 /* always */
#define MOD_1N_TO_MOD_1_1_THRESHOLD 10
#define MOD_1U_TO_MOD_1_1_THRESHOLD 6
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 16
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 21
#define USE_PREINV_DIVREM_1 1 /* native */
#define DIV_QR_1N_PI1_METHOD 1 /* 57.16% faster than 2 */
#define DIV_QR_1_NORM_THRESHOLD 3
#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD 36
#define DIV_1_VS_MUL_1_PERCENT 199
#define MUL_TOOM22_THRESHOLD 28
#define MUL_TOOM33_THRESHOLD 93
#define MUL_TOOM44_THRESHOLD 166
#define MUL_TOOM6H_THRESHOLD 270
#define MUL_TOOM8H_THRESHOLD 478
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 102
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 177
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 169
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 113
#define MUL_TOOM43_TO_TOOM54_THRESHOLD 143
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 50
#define SQR_TOOM3_THRESHOLD 89
#define SQR_TOOM4_THRESHOLD 248
#define SQR_TOOM6_THRESHOLD 342
#define SQR_TOOM8_THRESHOLD 470
#define MULMID_TOOM42_THRESHOLD 72
#define MULMOD_BNM1_THRESHOLD 20
#define SQRMOD_BNM1_THRESHOLD 21
#define MUL_FFT_MODF_THRESHOLD 630 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 630, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
{ 15, 5}, { 31, 6}, { 27, 7}, { 15, 6}, \
{ 33, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
{ 39, 7}, { 23, 6}, { 47, 7}, { 29, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
{ 23, 7}, { 49, 8}, { 27, 7}, { 55, 9}, \
{ 15, 8}, { 31, 7}, { 63, 8}, { 43, 9}, \
{ 23, 8}, { 55, 9}, { 31, 8}, { 67, 9}, \
{ 39, 8}, { 79, 9}, { 47, 8}, { 95, 9}, \
{ 55,10}, { 31, 9}, { 79,10}, { 47, 6}, \
{ 767, 7}, { 399, 6}, { 799, 7}, { 415, 8}, \
{ 235, 7}, { 479, 9}, { 135,10}, { 79, 9}, \
{ 159,10}, { 95, 9}, { 191,11}, { 63,10}, \
{ 159,11}, { 95,10}, { 191,12}, { 63,11}, \
{ 127,10}, { 255, 9}, { 511,10}, { 271, 9}, \
{ 543,11}, { 159,10}, { 319, 9}, { 639,10}, \
{ 335, 9}, { 671,11}, { 191,10}, { 383, 9}, \
{ 767,10}, { 399, 9}, { 799,11}, { 223,12}, \
{ 127,11}, { 255,10}, { 543, 9}, { 1087,11}, \
{ 287,10}, { 607, 9}, { 1215,11}, { 319,10}, \
{ 671,11}, { 351,12}, { 191,11}, { 383,10}, \
{ 799,11}, { 415,13}, { 127,12}, { 255,11}, \
{ 543,10}, { 1087,11}, { 607,10}, { 1215,12}, \
{ 319,11}, { 671,10}, { 1343,11}, { 735,10}, \
{ 1471,12}, { 383,11}, { 799,10}, { 1599,11}, \
{ 863,12}, { 447,11}, { 991,13}, { 255,12}, \
{ 511,11}, { 1087,12}, { 575,11}, { 1215,12}, \
{ 639,11}, { 1343,12}, { 703,11}, { 1471,13}, \
{ 383,12}, { 767,11}, { 1599,12}, { 831,11}, \
{ 1727,12}, { 959,14}, { 255,13}, { 511,12}, \
{ 1215,13}, { 639,12}, { 1471,13}, { 767,12}, \
{ 1727,13}, { 895,12}, { 1919,14}, { 511,13}, \
{ 1023,12}, { 2111,13}, { 1151,12}, { 2431,13}, \
{ 1407,14}, { 767,13}, { 1663,12}, { 3455,13}, \
{ 1919,15}, { 511,14}, { 1023,13}, { 2175,12}, \
{ 4479,13}, { 2431,14}, { 1279,13}, { 2943,12}, \
{ 5887,14}, { 1535,13}, { 3455,14}, { 1791,13}, \
{ 3967,15}, { 1023,14}, { 2047,13}, { 4479,14}, \
{ 2303,13}, { 4991,12}, { 9983,14}, { 2815,13}, \
{ 5887,15}, { 1535,14}, { 3839,16} }
#define MUL_FFT_TABLE3_SIZE 159
#define MUL_FFT_THRESHOLD 7424
#define SQR_FFT_MODF_THRESHOLD 500 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 500, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
{ 28, 7}, { 15, 6}, { 32, 7}, { 17, 6}, \
{ 35, 7}, { 19, 6}, { 39, 7}, { 23, 6}, \
{ 47, 7}, { 27, 8}, { 15, 7}, { 35, 8}, \
{ 19, 7}, { 41, 8}, { 23, 7}, { 47, 8}, \
{ 27, 9}, { 15, 8}, { 31, 7}, { 63, 8}, \
{ 39, 9}, { 23, 8}, { 51, 9}, { 31, 8}, \
{ 67, 9}, { 39, 8}, { 79, 9}, { 47, 8}, \
{ 95, 9}, { 55,10}, { 31, 9}, { 79,10}, \
{ 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
{ 127, 6}, { 1087, 7}, { 575, 8}, { 303, 9}, \
{ 159,10}, { 95,11}, { 63,10}, { 127, 9}, \
{ 255,10}, { 143, 9}, { 287,10}, { 159,11}, \
{ 95,10}, { 191,12}, { 63,11}, { 127,10}, \
{ 255, 9}, { 511,10}, { 271, 9}, { 543,10}, \
{ 287, 9}, { 575,11}, { 159,10}, { 319, 9}, \
{ 639,10}, { 335, 9}, { 671,10}, { 351,11}, \
{ 191,10}, { 383, 9}, { 767,10}, { 399, 9}, \
{ 799,10}, { 415, 9}, { 831,12}, { 127,11}, \
{ 255,10}, { 543,11}, { 287,10}, { 607,11}, \
{ 319,10}, { 671,11}, { 351,10}, { 703,12}, \
{ 191,11}, { 383,10}, { 799,11}, { 415,10}, \
{ 831,13}, { 127,12}, { 255,11}, { 543,10}, \
{ 1087,11}, { 607,12}, { 319,11}, { 671,10}, \
{ 1343,11}, { 735,10}, { 1471,12}, { 383,11}, \
{ 799,10}, { 1599,11}, { 863,12}, { 447,11}, \
{ 959,13}, { 255,12}, { 511,11}, { 1087,12}, \
{ 575,11}, { 1215,12}, { 639,11}, { 1343,12}, \
{ 703,11}, { 1471,13}, { 383,12}, { 767,11}, \
{ 1599,12}, { 831,11}, { 1727,12}, { 959,14}, \
{ 255,13}, { 511,12}, { 1215,13}, { 639,12}, \
{ 1471,13}, { 767,12}, { 1727,13}, { 895,12}, \
{ 1919,14}, { 511,13}, { 1023,12}, { 2111,13}, \
{ 1151,12}, { 2431,13}, { 1407,14}, { 767,13}, \
{ 1663,12}, { 3455,13}, { 1919,15}, { 511,14}, \
{ 1023,13}, { 2175,12}, { 4479,13}, { 2431,14}, \
{ 1279,13}, { 2943,12}, { 5887,14}, { 1535,13}, \
{ 3455,14}, { 1791,13}, { 3839,15}, { 1023,14}, \
{ 2047,13}, { 4479,14}, { 2303,13}, { 4991,12}, \
{ 9983,14}, { 2815,13}, { 5887,15}, { 1535,14}, \
{ 3839,16} }
#define SQR_FFT_TABLE3_SIZE 161
#define SQR_FFT_THRESHOLD 5760
#define MULLO_BASECASE_THRESHOLD 9
#define MULLO_DC_THRESHOLD 48
#define MULLO_MUL_N_THRESHOLD 14281
#define SQRLO_BASECASE_THRESHOLD 7
#define SQRLO_DC_THRESHOLD 146
#define SQRLO_SQR_THRESHOLD 11278
#define DC_DIV_QR_THRESHOLD 77
#define DC_DIVAPPR_Q_THRESHOLD 240
#define DC_BDIV_QR_THRESHOLD 83
#define DC_BDIV_Q_THRESHOLD 182
#define INV_MULMOD_BNM1_THRESHOLD 74
#define INV_NEWTON_THRESHOLD 252
#define INV_APPR_THRESHOLD 252
#define BINV_NEWTON_THRESHOLD 252
#define REDC_1_TO_REDC_N_THRESHOLD 79
#define MU_DIV_QR_THRESHOLD 1787
#define MU_DIVAPPR_Q_THRESHOLD 1718
#define MUPI_DIV_QR_THRESHOLD 122
#define MU_BDIV_QR_THRESHOLD 1470
#define MU_BDIV_Q_THRESHOLD 1713
#define POWM_SEC_TABLE 1,16,96,563,1317,1867
#define GET_STR_DC_THRESHOLD 19
#define GET_STR_PRECOMPUTE_THRESHOLD 32
#define SET_STR_DC_THRESHOLD 254
#define SET_STR_PRECOMPUTE_THRESHOLD 907
#define FAC_DSC_THRESHOLD 224
#define FAC_ODD_THRESHOLD 55
#define MATRIX22_STRASSEN_THRESHOLD 23
#define HGCD2_DIV1_METHOD 3 /* 3.59% faster than 5 */
#define HGCD_THRESHOLD 85
#define HGCD_APPR_THRESHOLD 152
#define HGCD_REDUCE_THRESHOLD 3389
#define GCD_DC_THRESHOLD 531
#define GCDEXT_DC_THRESHOLD 386
#define JACOBI_BASE_METHOD 3 /* 0.92% faster than 1 */
/* Tuneup completed successfully, took 159946 seconds */

View File

@@ -0,0 +1,214 @@
/* x86/bobcat gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 2019 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* NOTE: In a fat binary build SQR_TOOM2_THRESHOLD here cannot be greater than
the value in mpn/x86/k7/gmp-mparam.h. The latter is used as a hard limit in
k7/sqr_basecase.asm. */
/* 2050 MHz AMD Jaguar/Kabini */
/* FFT tuning limit = 67,000,000 */
/* Generated by tuneup.c, 2019-10-24, gcc 8.3 */
#define MOD_1_NORM_THRESHOLD 4
#define MOD_1_UNNORM_THRESHOLD 6
#define MOD_1N_TO_MOD_1_1_THRESHOLD 4
#define MOD_1U_TO_MOD_1_1_THRESHOLD 4
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 18
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 9
#define USE_PREINV_DIVREM_1 1 /* native */
#define DIV_QR_1N_PI1_METHOD 1 /* 47.53% faster than 2 */
#define DIV_QR_1_NORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD 27
#define DIV_1_VS_MUL_1_PERCENT 243
#define MUL_TOOM22_THRESHOLD 32
#define MUL_TOOM33_THRESHOLD 90
#define MUL_TOOM44_THRESHOLD 154
#define MUL_TOOM6H_THRESHOLD 286
#define MUL_TOOM8H_THRESHOLD 478
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 97
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 152
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 103
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 113
#define MUL_TOOM43_TO_TOOM54_THRESHOLD 154
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 38
#define SQR_TOOM3_THRESHOLD 126
#define SQR_TOOM4_THRESHOLD 220
#define SQR_TOOM6_THRESHOLD 318
#define SQR_TOOM8_THRESHOLD 502
#define MULMID_TOOM42_THRESHOLD 68
#define MULMOD_BNM1_THRESHOLD 19
#define SQRMOD_BNM1_THRESHOLD 25
#define MUL_FFT_MODF_THRESHOLD 570 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 570, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
{ 15, 5}, { 31, 6}, { 28, 7}, { 15, 6}, \
{ 33, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
{ 39, 7}, { 23, 6}, { 47, 7}, { 27, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
{ 23, 7}, { 49, 8}, { 31, 7}, { 63, 8}, \
{ 39, 9}, { 23, 8}, { 55, 9}, { 31, 8}, \
{ 67, 9}, { 39, 8}, { 79, 9}, { 47, 8}, \
{ 95, 9}, { 55,10}, { 31, 9}, { 79,10}, \
{ 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
{ 135,10}, { 79, 9}, { 159,10}, { 95,11}, \
{ 63,10}, { 159,11}, { 95,10}, { 191,12}, \
{ 63,11}, { 127,10}, { 255, 9}, { 511,10}, \
{ 271, 9}, { 543,10}, { 287,11}, { 159,10}, \
{ 319, 9}, { 639,10}, { 335, 9}, { 671,11}, \
{ 191,10}, { 383, 9}, { 767,10}, { 399, 9}, \
{ 799,10}, { 415,11}, { 223,12}, { 127,11}, \
{ 255,10}, { 543,11}, { 287,10}, { 607, 9}, \
{ 1215,11}, { 319,10}, { 671,11}, { 351,12}, \
{ 191,11}, { 383,10}, { 799,11}, { 415,13}, \
{ 127,12}, { 255,11}, { 543,10}, { 1087,11}, \
{ 607,10}, { 1215,12}, { 319,11}, { 671,10}, \
{ 1343,11}, { 735,10}, { 1471,12}, { 383,11}, \
{ 799,10}, { 1599,11}, { 863,12}, { 447,11}, \
{ 991,13}, { 255,12}, { 511,11}, { 1087,12}, \
{ 575,11}, { 1215,12}, { 639,11}, { 1343,12}, \
{ 703,11}, { 1471,13}, { 383,12}, { 767,11}, \
{ 1599,12}, { 831,11}, { 1727,12}, { 959,14}, \
{ 255,13}, { 511,12}, { 1215,13}, { 639,12}, \
{ 1471,13}, { 767,12}, { 1727,13}, { 895,12}, \
{ 1919,14}, { 511,13}, { 1023,12}, { 2111,13}, \
{ 1151,12}, { 2431,13}, { 1407,14}, { 767,13}, \
{ 1663,12}, { 3455,13}, { 1919,15}, { 511,14}, \
{ 1023,13}, { 2175,12}, { 4479,13}, { 2431,14}, \
{ 1279,13}, { 2943,12}, { 5887,14}, { 1535,13}, \
{ 3455,14}, { 1791,13}, { 3967,15}, { 1023,14}, \
{ 2047,13}, { 4479,14}, { 2303,13}, { 4991,12}, \
{ 9983,14}, { 2815,13}, { 5887,15}, { 1535,14}, \
{ 3839,16} }
#define MUL_FFT_TABLE3_SIZE 153
#define MUL_FFT_THRESHOLD 5760
#define SQR_FFT_MODF_THRESHOLD 530 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 530, 5}, { 27, 6}, { 15, 5}, { 31, 6}, \
{ 28, 7}, { 15, 6}, { 33, 7}, { 17, 6}, \
{ 35, 7}, { 19, 6}, { 39, 7}, { 23, 6}, \
{ 47, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
{ 19, 7}, { 41, 8}, { 23, 7}, { 49, 8}, \
{ 31, 7}, { 63, 8}, { 39, 9}, { 23, 8}, \
{ 55, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
{ 79, 9}, { 47, 8}, { 95, 9}, { 55,10}, \
{ 31, 9}, { 79,10}, { 47, 9}, { 95,11}, \
{ 31,10}, { 63, 9}, { 135,10}, { 95,11}, \
{ 63,10}, { 143, 9}, { 287,10}, { 159,11}, \
{ 95,12}, { 63,11}, { 127,10}, { 255, 9}, \
{ 511,10}, { 271, 9}, { 543,10}, { 287,11}, \
{ 159,10}, { 319, 9}, { 639,10}, { 335, 9}, \
{ 671,10}, { 351,11}, { 191,10}, { 383, 9}, \
{ 767,10}, { 399, 9}, { 799,12}, { 127,11}, \
{ 255,10}, { 543,11}, { 287,10}, { 607, 9}, \
{ 1215,11}, { 319,10}, { 671,11}, { 351,12}, \
{ 191,11}, { 383,10}, { 799,11}, { 415,10}, \
{ 831,13}, { 127,12}, { 255,11}, { 543,10}, \
{ 1087,11}, { 607,10}, { 1215,12}, { 319,11}, \
{ 671,10}, { 1343,11}, { 735,10}, { 1471,12}, \
{ 383,11}, { 799,10}, { 1599,11}, { 863,12}, \
{ 447,11}, { 991,13}, { 255,12}, { 511,11}, \
{ 1087,12}, { 575,11}, { 1215,12}, { 639,11}, \
{ 1343,12}, { 703,11}, { 1471,13}, { 383,12}, \
{ 767,11}, { 1599,12}, { 831,11}, { 1727,12}, \
{ 959,11}, { 1919,14}, { 255,13}, { 511,12}, \
{ 1215,13}, { 639,12}, { 1471,13}, { 767,12}, \
{ 1727,13}, { 895,12}, { 1919,14}, { 511,13}, \
{ 1023,12}, { 2111,13}, { 1151,12}, { 2495,13}, \
{ 1407,14}, { 767,13}, { 1663,12}, { 3455,13}, \
{ 1919,15}, { 511,14}, { 1023,13}, { 2175,12}, \
{ 4479,13}, { 2431,14}, { 1279,13}, { 2943,12}, \
{ 5887,14}, { 1535,13}, { 3455,14}, { 1791,13}, \
{ 3967,15}, { 1023,14}, { 2047,13}, { 4479,14}, \
{ 2303,13}, { 4991,12}, { 9983,14}, { 2815,13}, \
{ 5887,15}, { 1535,14}, { 3839,16} }
#define SQR_FFT_TABLE3_SIZE 151
#define SQR_FFT_THRESHOLD 4736
#define MULLO_BASECASE_THRESHOLD 8
#define MULLO_DC_THRESHOLD 44
#define MULLO_MUL_N_THRESHOLD 11278
#define SQRLO_BASECASE_THRESHOLD 13
#define SQRLO_DC_THRESHOLD 62
#define SQRLO_SQR_THRESHOLD 8907
#define DC_DIV_QR_THRESHOLD 79
#define DC_DIVAPPR_Q_THRESHOLD 228
#define DC_BDIV_QR_THRESHOLD 75
#define DC_BDIV_Q_THRESHOLD 136
#define INV_MULMOD_BNM1_THRESHOLD 90
#define INV_NEWTON_THRESHOLD 260
#define INV_APPR_THRESHOLD 236
#define BINV_NEWTON_THRESHOLD 294
#define REDC_1_TO_REDC_N_THRESHOLD 80
#define MU_DIV_QR_THRESHOLD 1787
#define MU_DIVAPPR_Q_THRESHOLD 1718
#define MUPI_DIV_QR_THRESHOLD 118
#define MU_BDIV_QR_THRESHOLD 1442
#define MU_BDIV_Q_THRESHOLD 1652
#define POWM_SEC_TABLE 1,16,96,615,865,1442
#define GET_STR_DC_THRESHOLD 16
#define GET_STR_PRECOMPUTE_THRESHOLD 27
#define SET_STR_DC_THRESHOLD 252
#define SET_STR_PRECOMPUTE_THRESHOLD 638
#define FAC_DSC_THRESHOLD 141
#define FAC_ODD_THRESHOLD 39
#define MATRIX22_STRASSEN_THRESHOLD 19
#define HGCD2_DIV1_METHOD 1 /* 13.65% faster than 3 */
#define HGCD_THRESHOLD 81
#define HGCD_APPR_THRESHOLD 66
#define HGCD_REDUCE_THRESHOLD 3389
#define GCD_DC_THRESHOLD 531
#define GCDEXT_DC_THRESHOLD 345
#define JACOBI_BASE_METHOD 1 /* 0.84% faster than 4 */
/* Tuneup completed successfully, took 103818 seconds */

View File

@@ -0,0 +1,124 @@
dnl X86 mpn_cnd_add_n, mpn_cnd_sub_n
dnl Copyright 2013 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C P5 ?
C P6 model 0-8,10-12 ?
C P6 model 9 (Banias) ?
C P6 model 13 (Dothan) 5.4
C P4 model 0-1 (Willamette) ?
C P4 model 2 (Northwood) 14.5
C P4 model 3-4 (Prescott) 21
C Intel atom 11
C AMD K6 ?
C AMD K7 3.4
C AMD K8 ?
define(`rp', `%edi')
define(`up', `%esi')
define(`vp', `%ebp')
define(`n', `%ecx')
define(`cnd', `20(%esp)')
define(`cy', `%edx')
ifdef(`OPERATION_cnd_add_n', `
define(ADDSUB, add)
define(ADCSBB, adc)
define(func, mpn_cnd_add_n)')
ifdef(`OPERATION_cnd_sub_n', `
define(ADDSUB, sub)
define(ADCSBB, sbb)
define(func, mpn_cnd_sub_n)')
MULFUNC_PROLOGUE(mpn_cnd_add_n mpn_cnd_sub_n)
ASM_START()
TEXT
ALIGN(16)
PROLOGUE(func)
add $-16, %esp
mov %ebp, (%esp)
mov %ebx, 4(%esp)
mov %esi, 8(%esp)
mov %edi, 12(%esp)
C make cnd into a full mask
mov cnd, %eax
neg %eax
sbb %eax, %eax
mov %eax, cnd
C load parameters into registers
mov 24(%esp), rp
mov 28(%esp), up
mov 32(%esp), vp
mov 36(%esp), n
mov (vp), %eax
mov (up), %ebx
C put operand pointers just beyond their last limb
lea (vp,n,4), vp
lea (up,n,4), up
lea -4(rp,n,4), rp
neg n
and cnd, %eax
ADDSUB %eax, %ebx
sbb cy, cy
inc n
je L(end)
ALIGN(16)
L(top): mov (vp,n,4), %eax
and cnd, %eax
mov %ebx, (rp,n,4)
mov (up,n,4), %ebx
add cy, cy
ADCSBB %eax, %ebx
sbb cy, cy
inc n
jne L(top)
L(end): mov %ebx, (rp)
xor %eax, %eax
sub cy, %eax
mov (%esp), %ebp
mov 4(%esp), %ebx
mov 8(%esp), %esi
mov 12(%esp), %edi
add $16, %esp
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,91 @@
dnl x86 mpn_copyd -- copy limb vector, decrementing.
dnl Copyright 1999-2002 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb startup (approx)
C P5 1.0 40
C P6 2.4 70
C K6 1.0 55
C K7 1.3 75
C P4 2.6 175
C
C (Startup time includes some function call overheads.)
C void mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t size);
C
C Copy src,size to dst,size, working from high to low addresses.
C
C The code here is very generic and can be expected to be reasonable on all
C the x86 family.
defframe(PARAM_SIZE,12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
deflit(`FRAME',0)
TEXT
ALIGN(32)
PROLOGUE(mpn_copyd)
C eax saved esi
C ebx
C ecx counter
C edx saved edi
C esi src
C edi dst
C ebp
movl PARAM_SIZE, %ecx
movl %esi, %eax
movl PARAM_SRC, %esi
movl %edi, %edx
movl PARAM_DST, %edi
leal -4(%esi,%ecx,4), %esi
leal -4(%edi,%ecx,4), %edi
std
rep
movsl
cld
movl %eax, %esi
movl %edx, %edi
ret
EPILOGUE()

View File

@@ -0,0 +1,99 @@
dnl x86 mpn_copyi -- copy limb vector, incrementing.
dnl Copyright 1999-2002 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb startup (approx)
C P5 1.0 35
C P6 0.75 45
C K6 1.0 30
C K7 1.3 65
C P4 1.0 120
C
C (Startup time includes some function call overheads.)
C void mpn_copyi (mp_ptr dst, mp_srcptr src, mp_size_t size);
C
C Copy src,size to dst,size, working from low to high addresses.
C
C The code here is very generic and can be expected to be reasonable on all
C the x86 family.
C
C P6 - An MMX based copy was tried, but was found to be slower than a rep
C movs in all cases. The fastest MMX found was 0.8 cycles/limb (when
C fully aligned). A rep movs seems to have a startup time of about 15
C cycles, but doing something special for small sizes could lead to a
C branch misprediction that would destroy any saving. For now a plain
C rep movs seems ok.
C
C K62 - We used to have a big chunk of code doing an MMX copy at 0.56 c/l if
C aligned or a 1.0 rep movs if not. But that seemed excessive since
C it only got an advantage half the time, and even then only showed it
C above 50 limbs or so.
defframe(PARAM_SIZE,12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
deflit(`FRAME',0)
TEXT
ALIGN(32)
C eax saved esi
C ebx
C ecx counter
C edx saved edi
C esi src
C edi dst
C ebp
PROLOGUE(mpn_copyi)
movl PARAM_SIZE, %ecx
movl %esi, %eax
movl PARAM_SRC, %esi
movl %edi, %edx
movl PARAM_DST, %edi
cld C better safe than sorry, see mpn/x86/README
rep
movsl
movl %eax, %esi
movl %edx, %edi
ret
EPILOGUE()

View File

@@ -0,0 +1,210 @@
/* x86/core2 gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 2019 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* 3000 MHz Penryn */
/* FFT tuning limit = 67,000,000 */
/* Generated by tuneup.c, 2019-10-20, gcc 8.3 */
#define MOD_1_NORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define MOD_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define MOD_1N_TO_MOD_1_1_THRESHOLD 9
#define MOD_1U_TO_MOD_1_1_THRESHOLD 8
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 9
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 3
#define USE_PREINV_DIVREM_1 1 /* native */
#define DIV_QR_1N_PI1_METHOD 2 /* 22.20% faster than 1 */
#define DIV_QR_1_NORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_2_PI2_THRESHOLD 9
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD 18
#define DIV_1_VS_MUL_1_PERCENT 277
#define MUL_TOOM22_THRESHOLD 24
#define MUL_TOOM33_THRESHOLD 93
#define MUL_TOOM44_THRESHOLD 136
#define MUL_TOOM6H_THRESHOLD 300
#define MUL_TOOM8H_THRESHOLD 478
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 91
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 153
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 93
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 94
#define MUL_TOOM43_TO_TOOM54_THRESHOLD 130
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 34
#define SQR_TOOM3_THRESHOLD 117
#define SQR_TOOM4_THRESHOLD 184
#define SQR_TOOM6_THRESHOLD 262
#define SQR_TOOM8_THRESHOLD 597
#define MULMID_TOOM42_THRESHOLD 70
#define MULMOD_BNM1_THRESHOLD 17
#define SQRMOD_BNM1_THRESHOLD 25
#define MUL_FFT_MODF_THRESHOLD 505 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 505, 5}, { 28, 6}, { 15, 5}, { 31, 6}, \
{ 29, 7}, { 15, 6}, { 32, 7}, { 17, 6}, \
{ 35, 7}, { 19, 6}, { 39, 7}, { 29, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 43, 8}, \
{ 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
{ 31, 7}, { 63, 8}, { 43, 9}, { 23, 8}, \
{ 55, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
{ 79, 9}, { 55,10}, { 31, 9}, { 79,10}, \
{ 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
{ 135,10}, { 79, 9}, { 159,10}, { 95,11}, \
{ 63, 9}, { 255,10}, { 159,11}, { 95,10}, \
{ 191,12}, { 63,11}, { 127,10}, { 271, 9}, \
{ 543,10}, { 287,11}, { 159,10}, { 335, 9}, \
{ 671,10}, { 351,11}, { 191,10}, { 399, 9}, \
{ 799,11}, { 223,12}, { 127,11}, { 255,10}, \
{ 543,11}, { 287,10}, { 607,11}, { 319,10}, \
{ 671,11}, { 351,12}, { 191,11}, { 383,10}, \
{ 799,11}, { 415,13}, { 127,12}, { 255,11}, \
{ 543,10}, { 1087,11}, { 607,12}, { 319,11}, \
{ 671,10}, { 1343,11}, { 735,10}, { 1471,12}, \
{ 383,11}, { 799,10}, { 1599,11}, { 863,12}, \
{ 447,11}, { 959,13}, { 255,12}, { 511,11}, \
{ 1087,12}, { 575,11}, { 1215,12}, { 639,11}, \
{ 1343,12}, { 703,11}, { 1471,13}, { 383,12}, \
{ 767,11}, { 1599,12}, { 831,11}, { 1727,12}, \
{ 959,14}, { 255,13}, { 511,12}, { 1087,11}, \
{ 2239,12}, { 1215,13}, { 639,12}, { 1471,11}, \
{ 2943,13}, { 767,12}, { 1727,13}, { 895,12}, \
{ 1919,14}, { 511,13}, { 1023,12}, { 2239,13}, \
{ 1151,12}, { 2431,13}, { 1407,12}, { 2943,14}, \
{ 767,13}, { 1663,12}, { 3455,13}, { 1919,15}, \
{ 511,14}, { 1023,13}, { 2175,12}, { 4479,13}, \
{ 2431,14}, { 1279,13}, { 2943,12}, { 5887,14}, \
{ 1535,13}, { 3455,14}, { 1791,13}, { 3967,12}, \
{ 7935,15}, { 1023,14}, { 2047,13}, { 4479,14}, \
{ 2303,13}, { 4991,12}, { 9983,14}, { 2815,13}, \
{ 5887,15}, { 1535,14}, { 3839,16} }
#define MUL_FFT_TABLE3_SIZE 147
#define MUL_FFT_THRESHOLD 6784
#define SQR_FFT_MODF_THRESHOLD 464 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 464, 5}, { 28, 6}, { 15, 5}, { 31, 6}, \
{ 29, 7}, { 15, 6}, { 32, 7}, { 17, 6}, \
{ 35, 7}, { 19, 6}, { 39, 7}, { 29, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
{ 23, 7}, { 49, 8}, { 27, 9}, { 15, 8}, \
{ 39, 9}, { 23, 8}, { 51,10}, { 15, 9}, \
{ 31, 8}, { 67, 9}, { 39, 8}, { 79, 9}, \
{ 47, 8}, { 95, 9}, { 55,10}, { 31, 9}, \
{ 79,10}, { 47, 9}, { 95,11}, { 31,10}, \
{ 63, 9}, { 127,10}, { 79, 9}, { 159,10}, \
{ 95,11}, { 63,10}, { 127, 9}, { 255,10}, \
{ 143, 9}, { 287, 5}, { 4863, 6}, { 2495, 7}, \
{ 1343, 8}, { 703, 9}, { 367,12}, { 63,11}, \
{ 127,10}, { 303,11}, { 159,10}, { 319, 9}, \
{ 639,10}, { 335, 9}, { 671,10}, { 351, 9}, \
{ 703,10}, { 367,11}, { 191,10}, { 383, 9}, \
{ 767,10}, { 399, 9}, { 799,10}, { 415, 9}, \
{ 831,12}, { 127,11}, { 255,10}, { 543,11}, \
{ 287,10}, { 607,11}, { 319,10}, { 671,11}, \
{ 351,10}, { 703,12}, { 191,11}, { 383,10}, \
{ 799,11}, { 415,10}, { 863,13}, { 127,12}, \
{ 255,11}, { 543,10}, { 1087,11}, { 607,12}, \
{ 319,11}, { 671,10}, { 1343,11}, { 735,10}, \
{ 1471,12}, { 383,11}, { 799,10}, { 1599,11}, \
{ 863,12}, { 447,11}, { 959,13}, { 255,12}, \
{ 511,11}, { 1087,12}, { 575,11}, { 1215,12}, \
{ 639,11}, { 1343,12}, { 703,11}, { 1407,13}, \
{ 383,12}, { 767,11}, { 1599,12}, { 831,11}, \
{ 1727,12}, { 959,14}, { 255,13}, { 511,12}, \
{ 1215,13}, { 639,12}, { 1471,11}, { 2943,13}, \
{ 767,12}, { 1727,13}, { 895,12}, { 1919,14}, \
{ 511,13}, { 1023,12}, { 2111,13}, { 1151,12}, \
{ 2431,13}, { 1407,12}, { 2943,14}, { 767,13}, \
{ 1663,12}, { 3455,13}, { 1919,15}, { 511,14}, \
{ 1023,13}, { 2175,12}, { 4479,13}, { 2431,14}, \
{ 1279,13}, { 2943,12}, { 5887,14}, { 1535,13}, \
{ 3455,14}, { 1791,13}, { 3967,15}, { 1023,14}, \
{ 2047,13}, { 4479,14}, { 2303,13}, { 4991,12}, \
{ 9983,14}, { 2815,13}, { 5887,15}, { 1535,14}, \
{ 3839,16} }
#define SQR_FFT_TABLE3_SIZE 157
#define SQR_FFT_THRESHOLD 5312
#define MULLO_BASECASE_THRESHOLD 0 /* always */
#define MULLO_DC_THRESHOLD 36
#define MULLO_MUL_N_THRESHOLD 13463
#define SQRLO_BASECASE_THRESHOLD 0 /* always */
#define SQRLO_DC_THRESHOLD 140
#define SQRLO_SQR_THRESHOLD 10393
#define DC_DIV_QR_THRESHOLD 32
#define DC_DIVAPPR_Q_THRESHOLD 116
#define DC_BDIV_QR_THRESHOLD 76
#define DC_BDIV_Q_THRESHOLD 180
#define INV_MULMOD_BNM1_THRESHOLD 46
#define INV_NEWTON_THRESHOLD 138
#define INV_APPR_THRESHOLD 123
#define BINV_NEWTON_THRESHOLD 306
#define REDC_1_TO_REDC_N_THRESHOLD 82
#define MU_DIV_QR_THRESHOLD 1499
#define MU_DIVAPPR_Q_THRESHOLD 1442
#define MUPI_DIV_QR_THRESHOLD 63
#define MU_BDIV_QR_THRESHOLD 1442
#define MU_BDIV_Q_THRESHOLD 1589
#define POWM_SEC_TABLE 1,22,66,428,1035
#define GET_STR_DC_THRESHOLD 13
#define GET_STR_PRECOMPUTE_THRESHOLD 18
#define SET_STR_DC_THRESHOLD 732
#define SET_STR_PRECOMPUTE_THRESHOLD 1118
#define FAC_DSC_THRESHOLD 115
#define FAC_ODD_THRESHOLD 50
#define MATRIX22_STRASSEN_THRESHOLD 25
#define HGCD2_DIV1_METHOD 1 /* 5.78% faster than 3 */
#define HGCD_THRESHOLD 121
#define HGCD_APPR_THRESHOLD 151
#define HGCD_REDUCE_THRESHOLD 3259
#define GCD_DC_THRESHOLD 368
#define GCDEXT_DC_THRESHOLD 306
#define JACOBI_BASE_METHOD 4 /* 14.19% faster than 1 */
/* Tuneup completed successfully, took 67142 seconds */

View File

@@ -0,0 +1,216 @@
/* x86/coreibwl gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 2019 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* 3400-3800 MHz Intel Xeon E3-1285Lv4 Broadwell */
/* FFT tuning limit = 67,000,000 */
/* Generated by tuneup.c, 2019-10-20, gcc 8.3 */
#define MOD_1_NORM_THRESHOLD 15
#define MOD_1_UNNORM_THRESHOLD 16
#define MOD_1N_TO_MOD_1_1_THRESHOLD 10
#define MOD_1U_TO_MOD_1_1_THRESHOLD 8
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 10
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 11
#define USE_PREINV_DIVREM_1 1 /* native */
#define DIV_QR_1N_PI1_METHOD 1 /* 21.34% faster than 2 */
#define DIV_QR_1_NORM_THRESHOLD 14
#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_2_PI2_THRESHOLD 29
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD 19
#define DIV_1_VS_MUL_1_PERCENT 295
#define MUL_TOOM22_THRESHOLD 26
#define MUL_TOOM33_THRESHOLD 97
#define MUL_TOOM44_THRESHOLD 220
#define MUL_TOOM6H_THRESHOLD 306
#define MUL_TOOM8H_THRESHOLD 454
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 93
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 153
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 154
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 169
#define MUL_TOOM43_TO_TOOM54_THRESHOLD 136
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 44
#define SQR_TOOM3_THRESHOLD 134
#define SQR_TOOM4_THRESHOLD 242
#define SQR_TOOM6_THRESHOLD 342
#define SQR_TOOM8_THRESHOLD 502
#define MULMID_TOOM42_THRESHOLD 98
#define MULMOD_BNM1_THRESHOLD 20
#define SQRMOD_BNM1_THRESHOLD 23
#define MUL_FFT_MODF_THRESHOLD 540 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 540, 5}, { 29, 6}, { 15, 5}, { 31, 6}, \
{ 16, 5}, { 33, 6}, { 17, 5}, { 36, 6}, \
{ 25, 7}, { 13, 6}, { 29, 7}, { 15, 6}, \
{ 33, 7}, { 17, 6}, { 36, 7}, { 19, 6}, \
{ 39, 7}, { 21, 6}, { 43, 7}, { 23, 6}, \
{ 47, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
{ 19, 7}, { 43, 8}, { 23, 7}, { 49, 8}, \
{ 27, 7}, { 55, 9}, { 15, 8}, { 31, 7}, \
{ 63, 8}, { 43, 9}, { 23, 8}, { 55,10}, \
{ 15, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
{ 83, 9}, { 47, 8}, { 95, 9}, { 55,10}, \
{ 31, 9}, { 79,10}, { 47, 9}, { 95,11}, \
{ 31,10}, { 63, 9}, { 135,10}, { 79, 9}, \
{ 159,10}, { 95, 9}, { 191,10}, { 111,11}, \
{ 63,10}, { 143, 9}, { 287,10}, { 159,11}, \
{ 95, 7}, { 1599, 8}, { 831, 9}, { 431, 8}, \
{ 863, 9}, { 447,10}, { 239, 9}, { 479,10}, \
{ 255, 9}, { 511,10}, { 287,11}, { 159,10}, \
{ 319, 9}, { 639,10}, { 335, 9}, { 671,11}, \
{ 191,10}, { 383, 9}, { 767,10}, { 399,11}, \
{ 223,12}, { 127,11}, { 255,10}, { 511, 9}, \
{ 1023,11}, { 287,10}, { 607,11}, { 319,10}, \
{ 671,11}, { 351,12}, { 191,11}, { 383,10}, \
{ 799,11}, { 415,13}, { 127,12}, { 255,11}, \
{ 543,10}, { 1119,11}, { 607,12}, { 319,11}, \
{ 671,10}, { 1343,11}, { 735,12}, { 383,11}, \
{ 799,10}, { 1599,11}, { 863,12}, { 447,11}, \
{ 959,13}, { 255,12}, { 511,11}, { 1119,12}, \
{ 575,11}, { 1215,12}, { 639,11}, { 1343,12}, \
{ 703,11}, { 1407,13}, { 383,12}, { 767,11}, \
{ 1599,12}, { 831,11}, { 1727,12}, { 959,14}, \
{ 255,13}, { 511,12}, { 1215,13}, { 639,12}, \
{ 1471,13}, { 767,12}, { 1727,13}, { 895,12}, \
{ 1919,14}, { 511,13}, { 1023,12}, { 2239,13}, \
{ 1151,12}, { 2431,13}, { 1279,12}, { 2623,13}, \
{ 1407,12}, { 2815,14}, { 767,13}, { 1535,12}, \
{ 3135,13}, { 1663,12}, { 3455,13}, { 1919,15}, \
{ 511,14}, { 1023,13}, { 2175,12}, { 4479,13}, \
{ 2431,14}, { 1279,13}, { 2943,12}, { 5887,14}, \
{ 1535,13}, { 3455,14}, { 1791,13}, { 3839,15}, \
{ 1023,14}, { 2047,13}, { 4479,14}, { 2303,13}, \
{ 4991,12}, { 9983,14}, { 2559,13}, { 5247,14}, \
{ 2815,13}, { 5887,15}, { 1535,14}, { 3839,16} }
#define MUL_FFT_TABLE3_SIZE 172
#define MUL_FFT_THRESHOLD 7424
#define SQR_FFT_MODF_THRESHOLD 472 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 472, 5}, { 29, 6}, { 15, 5}, { 33, 6}, \
{ 37, 7}, { 19, 6}, { 40, 7}, { 29, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 43, 8}, \
{ 23, 7}, { 49, 8}, { 27, 9}, { 15, 8}, \
{ 31, 7}, { 63, 8}, { 43, 9}, { 23, 8}, \
{ 55,10}, { 15, 9}, { 31, 8}, { 67, 9}, \
{ 39, 8}, { 83, 9}, { 47, 8}, { 95, 9}, \
{ 55,10}, { 31, 9}, { 79,10}, { 47, 9}, \
{ 95,11}, { 31,10}, { 63, 9}, { 135,10}, \
{ 79, 9}, { 159,10}, { 95,11}, { 63,10}, \
{ 127, 9}, { 255,10}, { 143, 9}, { 287,10}, \
{ 159,11}, { 95,12}, { 63,11}, { 127,10}, \
{ 271, 9}, { 543, 6}, { 4479, 7}, { 2431, 8}, \
{ 1247, 7}, { 2495, 8}, { 1279,10}, { 351,11}, \
{ 191,10}, { 399, 9}, { 799,10}, { 415,12}, \
{ 127,11}, { 255,10}, { 543,11}, { 287,10}, \
{ 607,11}, { 319,10}, { 639,11}, { 351,12}, \
{ 191,11}, { 383,10}, { 799,11}, { 415,10}, \
{ 831,13}, { 127,12}, { 255,11}, { 511,10}, \
{ 1023,11}, { 543,10}, { 1087,11}, { 607,12}, \
{ 319,11}, { 671,10}, { 1343,11}, { 735,12}, \
{ 383,11}, { 799,10}, { 1599,11}, { 863,12}, \
{ 447,11}, { 927,13}, { 255,12}, { 511,11}, \
{ 1087,12}, { 575,11}, { 1215,12}, { 639,11}, \
{ 1343,12}, { 703,11}, { 1471,13}, { 383,12}, \
{ 767,11}, { 1599,12}, { 831,11}, { 1663,12}, \
{ 895,11}, { 1855,14}, { 255,13}, { 511,12}, \
{ 1023,11}, { 2047,12}, { 1087,11}, { 2239,12}, \
{ 1215,13}, { 639,12}, { 1471,13}, { 767,12}, \
{ 1663,13}, { 895,12}, { 1983,14}, { 511,13}, \
{ 1023,12}, { 2239,13}, { 1151,12}, { 2495,13}, \
{ 1279,12}, { 2623,13}, { 1407,14}, { 767,13}, \
{ 1535,12}, { 3135,13}, { 1663,12}, { 3455,13}, \
{ 1919,15}, { 511,14}, { 1023,13}, { 2175,12}, \
{ 4479,13}, { 2431,14}, { 1279,13}, { 2943,12}, \
{ 5887,14}, { 1535,13}, { 3455,14}, { 1791,13}, \
{ 3839,15}, { 1023,14}, { 2047,13}, { 4479,14}, \
{ 2303,13}, { 4991,12}, { 9983,14}, { 2815,13}, \
{ 5887,15}, { 1535,14}, { 3327,13}, { 6783,14}, \
{ 3839,16} }
#define SQR_FFT_TABLE3_SIZE 157
#define SQR_FFT_THRESHOLD 5568
#define MULLO_BASECASE_THRESHOLD 16
#define MULLO_DC_THRESHOLD 37
#define MULLO_MUL_N_THRESHOLD 14281
#define SQRLO_BASECASE_THRESHOLD 0 /* always */
#define SQRLO_DC_THRESHOLD 137
#define SQRLO_SQR_THRESHOLD 10821
#define DC_DIV_QR_THRESHOLD 54
#define DC_DIVAPPR_Q_THRESHOLD 146
#define DC_BDIV_QR_THRESHOLD 98
#define DC_BDIV_Q_THRESHOLD 218
#define INV_MULMOD_BNM1_THRESHOLD 50
#define INV_NEWTON_THRESHOLD 173
#define INV_APPR_THRESHOLD 165
#define BINV_NEWTON_THRESHOLD 278
#define REDC_1_TO_REDC_N_THRESHOLD 79
#define MU_DIV_QR_THRESHOLD 1787
#define MU_DIVAPPR_Q_THRESHOLD 1787
#define MUPI_DIV_QR_THRESHOLD 78
#define MU_BDIV_QR_THRESHOLD 1589
#define MU_BDIV_Q_THRESHOLD 1830
#define POWM_SEC_TABLE 1,16,126,416,932
#define GET_STR_DC_THRESHOLD 11
#define GET_STR_PRECOMPUTE_THRESHOLD 17
#define SET_STR_DC_THRESHOLD 306
#define SET_STR_PRECOMPUTE_THRESHOLD 894
#define FAC_DSC_THRESHOLD 141
#define FAC_ODD_THRESHOLD 34
#define MATRIX22_STRASSEN_THRESHOLD 20
#define HGCD2_DIV1_METHOD 3 /* 5.97% faster than 1 */
#define HGCD_THRESHOLD 73
#define HGCD_APPR_THRESHOLD 123
#define HGCD_REDUCE_THRESHOLD 3664
#define GCD_DC_THRESHOLD 562
#define GCDEXT_DC_THRESHOLD 465
#define JACOBI_BASE_METHOD 1 /* 31.16% faster than 3 */
/* Tuneup completed successfully, took 35114 seconds */

View File

@@ -0,0 +1,216 @@
/* x86/coreihwl gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 2019 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* 3600-4000 MHz Intel Xeon E3-1271v3 Haswell */
/* FFT tuning limit = 67,000,000 */
/* Generated by tuneup.c, 2019-10-21, gcc 8.3 */
#define MOD_1_NORM_THRESHOLD 17
#define MOD_1_UNNORM_THRESHOLD 17
#define MOD_1N_TO_MOD_1_1_THRESHOLD 10
#define MOD_1U_TO_MOD_1_1_THRESHOLD 9
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 10
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 5
#define USE_PREINV_DIVREM_1 1 /* native */
/* From sky.gmplib.org, 2023-07-20 */
#define DIV_QR_1N_PI1_METHOD 3 /* 5.86% faster than 1 */
#define DIV_QR_1_NORM_THRESHOLD 13
#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD 21
#define DIV_1_VS_MUL_1_PERCENT 296
#define MUL_TOOM22_THRESHOLD 28
#define MUL_TOOM33_THRESHOLD 108
#define MUL_TOOM44_THRESHOLD 232
#define MUL_TOOM6H_THRESHOLD 306
#define MUL_TOOM8H_THRESHOLD 478
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 109
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 183
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 113
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 113
#define MUL_TOOM43_TO_TOOM54_THRESHOLD 136
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 44
#define SQR_TOOM3_THRESHOLD 141
#define SQR_TOOM4_THRESHOLD 384
#define SQR_TOOM6_THRESHOLD 517
#define SQR_TOOM8_THRESHOLD 698
#define MULMID_TOOM42_THRESHOLD 98
#define MULMOD_BNM1_THRESHOLD 20
#define SQRMOD_BNM1_THRESHOLD 23
#define MUL_FFT_MODF_THRESHOLD 565 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 565, 5}, { 28, 6}, { 15, 5}, { 31, 6}, \
{ 16, 5}, { 33, 6}, { 29, 7}, { 15, 6}, \
{ 33, 7}, { 17, 6}, { 36, 7}, { 19, 6}, \
{ 39, 7}, { 21, 6}, { 43, 7}, { 23, 6}, \
{ 47, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
{ 19, 7}, { 43, 8}, { 23, 7}, { 47, 8}, \
{ 27, 7}, { 55, 9}, { 15, 8}, { 31, 7}, \
{ 63, 8}, { 43, 9}, { 23, 8}, { 55, 9}, \
{ 31, 8}, { 71, 9}, { 39, 8}, { 83, 9}, \
{ 47, 8}, { 95, 9}, { 55,10}, { 31, 9}, \
{ 79,10}, { 47, 9}, { 95,11}, { 31,10}, \
{ 63, 9}, { 135,10}, { 79, 9}, { 159,10}, \
{ 95, 9}, { 191,10}, { 111,11}, { 63,10}, \
{ 143, 9}, { 287,10}, { 159,11}, { 95,10}, \
{ 191, 6}, { 3199, 7}, { 1727, 9}, { 447,10}, \
{ 239, 9}, { 479,10}, { 287,11}, { 159,10}, \
{ 319, 9}, { 639,10}, { 335, 9}, { 671,11}, \
{ 191,10}, { 399, 9}, { 799,10}, { 415,11}, \
{ 223,12}, { 127,11}, { 255,10}, { 511, 9}, \
{ 1023,10}, { 527,11}, { 287,10}, { 607,11}, \
{ 319,10}, { 671,12}, { 191,11}, { 383,10}, \
{ 799,11}, { 415,13}, { 127,12}, { 255,11}, \
{ 511,10}, { 1023,11}, { 543,10}, { 1087,11}, \
{ 607,12}, { 319,11}, { 671,10}, { 1343,11}, \
{ 735,12}, { 383,11}, { 799,10}, { 1599,11}, \
{ 863,12}, { 447,11}, { 991,13}, { 255,12}, \
{ 511,11}, { 1087,12}, { 575,11}, { 1215,12}, \
{ 639,11}, { 1343,12}, { 703,11}, { 1407,13}, \
{ 383,12}, { 767,11}, { 1599,12}, { 831,11}, \
{ 1727,12}, { 959,11}, { 1919,14}, { 255,13}, \
{ 511,12}, { 1087,11}, { 2239,12}, { 1215,13}, \
{ 639,12}, { 1471,13}, { 767,12}, { 1727,13}, \
{ 895,12}, { 1919,14}, { 511,13}, { 1023,12}, \
{ 2239,13}, { 1151,12}, { 2431,13}, { 1279,12}, \
{ 2623,13}, { 1407,14}, { 767,13}, { 1663,12}, \
{ 3455,13}, { 1919,15}, { 511,14}, { 1023,13}, \
{ 2175,12}, { 4479,13}, { 2431,14}, { 1279,13}, \
{ 2943,12}, { 5887,14}, { 1535,13}, { 3455,14}, \
{ 1791,13}, { 3967,15}, { 1023,14}, { 2047,13}, \
{ 4479,14}, { 2303,13}, { 4991,14}, { 2559,13}, \
{ 5375,14}, { 2815,13}, { 5887,15}, { 1535,14}, \
{ 3839,16} }
#define MUL_FFT_TABLE3_SIZE 165
#define MUL_FFT_THRESHOLD 7808
#define SQR_FFT_MODF_THRESHOLD 560 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 560, 5}, { 29, 6}, { 15, 5}, { 31, 6}, \
{ 16, 5}, { 33, 6}, { 17, 5}, { 36, 6}, \
{ 29, 7}, { 15, 6}, { 33, 7}, { 17, 6}, \
{ 36, 7}, { 19, 6}, { 40, 7}, { 21, 6}, \
{ 43, 7}, { 23, 6}, { 47, 7}, { 29, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 43, 8}, \
{ 23, 7}, { 49, 8}, { 27, 7}, { 55, 9}, \
{ 15, 8}, { 31, 7}, { 63, 8}, { 43, 9}, \
{ 23, 8}, { 55,10}, { 15, 9}, { 31, 8}, \
{ 67, 9}, { 39, 8}, { 79, 9}, { 47, 8}, \
{ 95, 9}, { 55,10}, { 31, 9}, { 79,10}, \
{ 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
{ 135,10}, { 79, 9}, { 159,10}, { 95,11}, \
{ 63,10}, { 143, 9}, { 287,10}, { 159,11}, \
{ 95,12}, { 63,11}, { 127, 9}, { 511, 5}, \
{ 8959, 7}, { 2431, 8}, { 1247, 7}, { 2495, 8}, \
{ 1279, 9}, { 671,10}, { 367,11}, { 191,10}, \
{ 399, 9}, { 799,10}, { 415,12}, { 127,11}, \
{ 255,10}, { 527,11}, { 287,10}, { 607,11}, \
{ 319,10}, { 671,11}, { 351,10}, { 703,12}, \
{ 191,11}, { 383,10}, { 799,11}, { 415,10}, \
{ 831,13}, { 127,11}, { 543,10}, { 1119,11}, \
{ 607,12}, { 319,11}, { 671,10}, { 1343,11}, \
{ 735,12}, { 383,11}, { 863,12}, { 447,11}, \
{ 991,12}, { 511,11}, { 1119,12}, { 575,11}, \
{ 1215,12}, { 639,11}, { 1343,12}, { 703,13}, \
{ 383,12}, { 767,11}, { 1599,12}, { 831,11}, \
{ 1727,12}, { 959,11}, { 1983,13}, { 511,12}, \
{ 1087,11}, { 2239,12}, { 1215,13}, { 639,12}, \
{ 1471,13}, { 767,12}, { 1727,13}, { 895,12}, \
{ 1983,14}, { 511,13}, { 1023,12}, { 2239,13}, \
{ 1151,12}, { 2495,13}, { 1279,12}, { 2623,13}, \
{ 1407,14}, { 767,13}, { 1663,12}, { 3455,13}, \
{ 1919,15}, { 511,14}, { 1023,13}, { 2175,12}, \
{ 4479,13}, { 2431,14}, { 1279,13}, { 2943,12}, \
{ 5887,14}, { 1535,13}, { 3455,14}, { 1791,13}, \
{ 3967,15}, { 1023,14}, { 2047,13}, { 4479,14}, \
{ 2303,13}, { 4991,12}, { 9983,14}, { 2559,13}, \
{ 5119,14}, { 2815,13}, { 5887,15}, { 1535,14}, \
{ 3327,13}, { 6911,14}, { 3839,16} }
#define SQR_FFT_TABLE3_SIZE 159
#define SQR_FFT_THRESHOLD 5568
#define MULLO_BASECASE_THRESHOLD 17
#define MULLO_DC_THRESHOLD 40
#define MULLO_MUL_N_THRESHOLD 14281
#define SQRLO_BASECASE_THRESHOLD 0 /* always */
#define SQRLO_DC_THRESHOLD 141
#define SQRLO_SQR_THRESHOLD 10821
#define DC_DIV_QR_THRESHOLD 30
#define DC_DIVAPPR_Q_THRESHOLD 190
#define DC_BDIV_QR_THRESHOLD 67
#define DC_BDIV_Q_THRESHOLD 254
#define INV_MULMOD_BNM1_THRESHOLD 54
#define INV_NEWTON_THRESHOLD 157
#define INV_APPR_THRESHOLD 163
#define BINV_NEWTON_THRESHOLD 236
#define REDC_1_TO_REDC_N_THRESHOLD 79
#define MU_DIV_QR_THRESHOLD 1895
#define MU_DIVAPPR_Q_THRESHOLD 1718
#define MUPI_DIV_QR_THRESHOLD 54
#define MU_BDIV_QR_THRESHOLD 1589
#define MU_BDIV_Q_THRESHOLD 1898
#define POWM_SEC_TABLE 1,16,95,480,1442
#define GET_STR_DC_THRESHOLD 10
#define GET_STR_PRECOMPUTE_THRESHOLD 16
#define SET_STR_DC_THRESHOLD 372
#define SET_STR_PRECOMPUTE_THRESHOLD 1037
#define FAC_DSC_THRESHOLD 141
#define FAC_ODD_THRESHOLD 34
#define MATRIX22_STRASSEN_THRESHOLD 21
#define HGCD2_DIV1_METHOD 3 /* 6.26% faster than 1 */
#define HGCD_THRESHOLD 70
#define HGCD_APPR_THRESHOLD 129
#define HGCD_REDUCE_THRESHOLD 3664
#define GCD_DC_THRESHOLD 573
#define GCDEXT_DC_THRESHOLD 483
#define JACOBI_BASE_METHOD 1 /* 27.01% faster than 3 */
/* Tuneup completed successfully, took 35232 seconds */

View File

@@ -0,0 +1,223 @@
/* x86/coreinhm gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 2019 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* 2933-3200 MHz Intel Xeon X3470 Nehalem */
/* FFT tuning limit = 67,000,000 */
/* Generated by tuneup.c, 2019-10-23, gcc 8.3 */
#define MOD_1_NORM_THRESHOLD 36
#define MOD_1_UNNORM_THRESHOLD 40
#define MOD_1N_TO_MOD_1_1_THRESHOLD 8
#define MOD_1U_TO_MOD_1_1_THRESHOLD 7
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 12
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 3
#define USE_PREINV_DIVREM_1 1 /* native */
#define DIV_QR_1N_PI1_METHOD 1 /* 42.59% faster than 2 */
#define DIV_QR_1_NORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_2_PI2_THRESHOLD 9
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD 17
#define DIV_1_VS_MUL_1_PERCENT 288
#define MUL_TOOM22_THRESHOLD 24
#define MUL_TOOM33_THRESHOLD 93
#define MUL_TOOM44_THRESHOLD 214
#define MUL_TOOM6H_THRESHOLD 306
#define MUL_TOOM8H_THRESHOLD 430
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 93
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 134
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 145
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 94
#define MUL_TOOM43_TO_TOOM54_THRESHOLD 118
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 38
#define SQR_TOOM3_THRESHOLD 133
#define SQR_TOOM4_THRESHOLD 212
#define SQR_TOOM6_THRESHOLD 318
#define SQR_TOOM8_THRESHOLD 620
#define MULMID_TOOM42_THRESHOLD 68
#define MULMOD_BNM1_THRESHOLD 17
#define SQRMOD_BNM1_THRESHOLD 23
#define MUL_FFT_MODF_THRESHOLD 595 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 595, 5}, { 28, 6}, { 15, 5}, { 31, 6}, \
{ 17, 5}, { 35, 6}, { 28, 7}, { 15, 6}, \
{ 33, 7}, { 17, 6}, { 36, 7}, { 19, 6}, \
{ 39, 7}, { 23, 6}, { 47, 7}, { 27, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 43, 8}, \
{ 23, 7}, { 49, 8}, { 27, 9}, { 15, 8}, \
{ 31, 7}, { 63, 8}, { 43, 9}, { 23, 8}, \
{ 51, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
{ 79, 9}, { 47, 8}, { 99, 9}, { 55,10}, \
{ 31, 9}, { 63, 8}, { 127, 9}, { 79,10}, \
{ 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
{ 135,10}, { 79, 9}, { 159,10}, { 95, 9}, \
{ 191,11}, { 63, 9}, { 255,10}, { 159,11}, \
{ 95,10}, { 191,12}, { 63,11}, { 127,10}, \
{ 255, 9}, { 511,10}, { 271, 9}, { 543,11}, \
{ 159,10}, { 335,11}, { 191,10}, { 383, 9}, \
{ 767,10}, { 399,12}, { 127,11}, { 255,10}, \
{ 511, 9}, { 1023,10}, { 543, 9}, { 1087,11}, \
{ 287,10}, { 607,11}, { 319,10}, { 671,12}, \
{ 191,11}, { 383,10}, { 767,13}, { 127,12}, \
{ 255,11}, { 511,10}, { 1023,11}, { 543,10}, \
{ 1119,11}, { 607,12}, { 319,11}, { 671,10}, \
{ 1343,11}, { 735,10}, { 1471,12}, { 383,11}, \
{ 799,10}, { 1599,11}, { 863,10}, { 1727,12}, \
{ 447,11}, { 959,13}, { 255,12}, { 511,11}, \
{ 1119,12}, { 575,11}, { 1215,10}, { 2431,12}, \
{ 639,11}, { 1343,12}, { 703,11}, { 1471,10}, \
{ 2943,13}, { 383,12}, { 767,11}, { 1599,12}, \
{ 831,11}, { 1727,10}, { 3455,12}, { 959,14}, \
{ 255,13}, { 511,12}, { 1087,11}, { 2239,10}, \
{ 4479,12}, { 1215,11}, { 2431,13}, { 639,12}, \
{ 1471,11}, { 2943,13}, { 767,12}, { 1727,11}, \
{ 3455,13}, { 895,12}, { 1983,14}, { 511,13}, \
{ 1023,12}, { 2239,11}, { 4479,13}, { 1151,12}, \
{ 2431,13}, { 1279,12}, { 2559,13}, { 1407,12}, \
{ 2943,11}, { 5887,14}, { 767,13}, { 1663,12}, \
{ 3455,13}, { 1919,12}, { 3839,15}, { 511,14}, \
{ 1023,13}, { 2175,12}, { 4479,13}, { 2431,14}, \
{ 1279,13}, { 2943,12}, { 5887,14}, { 1535,13}, \
{ 3455,14}, { 1791,13}, { 3967,15}, { 1023,14}, \
{ 2047,13}, { 4479,14}, { 2303,13}, { 4991,12}, \
{ 9983,14}, { 2815,13}, { 6015,15}, { 1535,14}, \
{ 3839,13}, { 7679,16} }
#define MUL_FFT_TABLE3_SIZE 170
#define MUL_FFT_THRESHOLD 6784
#define SQR_FFT_MODF_THRESHOLD 525 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 525, 5}, { 29, 6}, { 15, 5}, { 33, 6}, \
{ 17, 5}, { 35, 6}, { 29, 7}, { 15, 6}, \
{ 33, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
{ 39, 7}, { 23, 6}, { 47, 7}, { 29, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
{ 23, 7}, { 49, 8}, { 27, 7}, { 55, 9}, \
{ 15, 8}, { 31, 7}, { 63, 8}, { 39, 9}, \
{ 23, 8}, { 55, 9}, { 31, 8}, { 67, 9}, \
{ 39, 8}, { 79, 9}, { 47, 8}, { 95, 9}, \
{ 55,10}, { 31, 9}, { 79,10}, { 47, 9}, \
{ 95,11}, { 31,10}, { 63, 9}, { 135,10}, \
{ 79, 9}, { 159,10}, { 95,11}, { 63,10}, \
{ 143, 9}, { 287,10}, { 159, 6}, { 2687, 7}, \
{ 1407, 9}, { 367, 8}, { 735, 9}, { 383,10}, \
{ 207, 9}, { 415,11}, { 127,10}, { 271, 9}, \
{ 543,10}, { 287,11}, { 159,10}, { 319, 9}, \
{ 639,10}, { 335, 9}, { 671,10}, { 351,11}, \
{ 191,10}, { 383, 9}, { 767,10}, { 399, 9}, \
{ 799,10}, { 415,12}, { 127,11}, { 255,10}, \
{ 511, 9}, { 1023,10}, { 543,11}, { 287,10}, \
{ 607,11}, { 319,10}, { 671,11}, { 351,12}, \
{ 191,11}, { 383,10}, { 799,11}, { 415,13}, \
{ 127,12}, { 255,11}, { 511,10}, { 1023,11}, \
{ 543,10}, { 1087,11}, { 607,10}, { 1215,12}, \
{ 319,11}, { 671,10}, { 1343,11}, { 735,10}, \
{ 1471,12}, { 383,11}, { 799,10}, { 1599,11}, \
{ 863,10}, { 1727,12}, { 447,11}, { 991,10}, \
{ 1983,13}, { 255,12}, { 511,11}, { 1119,12}, \
{ 575,11}, { 1215,10}, { 2431,12}, { 639,11}, \
{ 1343,12}, { 703,11}, { 1471,13}, { 383,12}, \
{ 767,11}, { 1599,12}, { 831,11}, { 1727,10}, \
{ 3455,12}, { 895,11}, { 1791,12}, { 959,11}, \
{ 1983,14}, { 255,13}, { 511,12}, { 1023,11}, \
{ 2047,12}, { 1087,11}, { 2239,12}, { 1215,11}, \
{ 2431,13}, { 639,12}, { 1471,11}, { 2943,13}, \
{ 767,12}, { 1727,11}, { 3455,13}, { 895,12}, \
{ 1983,11}, { 3967,14}, { 511,13}, { 1023,12}, \
{ 2239,13}, { 1151,12}, { 2495,13}, { 1279,12}, \
{ 2623,13}, { 1407,12}, { 2943,14}, { 767,13}, \
{ 1663,12}, { 3455,13}, { 1919,12}, { 3967,15}, \
{ 511,14}, { 1023,13}, { 2175,12}, { 4479,13}, \
{ 2431,12}, { 4863,14}, { 1279,13}, { 2943,12}, \
{ 5887,14}, { 1535,13}, { 3455,14}, { 1791,13}, \
{ 3967,12}, { 7935,15}, { 1023,14}, { 2047,13}, \
{ 4479,14}, { 2303,13}, { 4991,12}, { 9983,14}, \
{ 2815,13}, { 5887,15}, { 1535,14}, { 3327,13}, \
{ 6655,14}, { 3839,13}, { 7935,16} }
#define SQR_FFT_TABLE3_SIZE 187
#define SQR_FFT_THRESHOLD 5312
#define MULLO_BASECASE_THRESHOLD 0 /* always */
#define MULLO_DC_THRESHOLD 43
#define MULLO_MUL_N_THRESHOLD 13463
#define SQRLO_BASECASE_THRESHOLD 9
#define SQRLO_DC_THRESHOLD 42
#define SQRLO_SQR_THRESHOLD 10323
#define DC_DIV_QR_THRESHOLD 43
#define DC_DIVAPPR_Q_THRESHOLD 132
#define DC_BDIV_QR_THRESHOLD 83
#define DC_BDIV_Q_THRESHOLD 130
#define INV_MULMOD_BNM1_THRESHOLD 46
#define INV_NEWTON_THRESHOLD 189
#define INV_APPR_THRESHOLD 167
#define BINV_NEWTON_THRESHOLD 372
#define REDC_1_TO_REDC_N_THRESHOLD 83
#define MU_DIV_QR_THRESHOLD 1589
#define MU_DIVAPPR_Q_THRESHOLD 1589
#define MUPI_DIV_QR_THRESHOLD 97
#define MU_BDIV_QR_THRESHOLD 1589
#define MU_BDIV_Q_THRESHOLD 1718
#define POWM_SEC_TABLE 1,28,96,473,803
#define GET_STR_DC_THRESHOLD 12
#define GET_STR_PRECOMPUTE_THRESHOLD 16
#define SET_STR_DC_THRESHOLD 145
#define SET_STR_PRECOMPUTE_THRESHOLD 419
#define FAC_DSC_THRESHOLD 114
#define FAC_ODD_THRESHOLD 57
#define MATRIX22_STRASSEN_THRESHOLD 20
#define HGCD2_DIV1_METHOD 1 /* 1.03% faster than 3 */
#define HGCD_THRESHOLD 117
#define HGCD_APPR_THRESHOLD 137
#define HGCD_REDUCE_THRESHOLD 3524
#define GCD_DC_THRESHOLD 389
#define GCDEXT_DC_THRESHOLD 318
#define JACOBI_BASE_METHOD 4 /* 6.10% faster than 1 */
/* Tuneup completed successfully, took 67994 seconds */

View File

@@ -0,0 +1,215 @@
/* x86/coreisbr gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 2019 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* 3400-3800 MHz Intel Xeon E3-1270 Sandy Bridge */
/* FFT tuning limit = 67,000,000 */
/* Generated by tuneup.c, 2019-10-24, gcc 8.3 */
#define MOD_1_NORM_THRESHOLD 28
#define MOD_1_UNNORM_THRESHOLD 26
#define MOD_1N_TO_MOD_1_1_THRESHOLD 9
#define MOD_1U_TO_MOD_1_1_THRESHOLD 7
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 11
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 4
#define USE_PREINV_DIVREM_1 1 /* native */
#define DIV_QR_1N_PI1_METHOD 2 /* 88.29% faster than 1 */
#define DIV_QR_1_NORM_THRESHOLD 21
#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_2_PI2_THRESHOLD 14
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD 20
#define DIV_1_VS_MUL_1_PERCENT 297
#define MUL_TOOM22_THRESHOLD 32
#define MUL_TOOM33_THRESHOLD 105
#define MUL_TOOM44_THRESHOLD 190
#define MUL_TOOM6H_THRESHOLD 294
#define MUL_TOOM8H_THRESHOLD 478
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 109
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 144
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 116
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 129
#define MUL_TOOM43_TO_TOOM54_THRESHOLD 160
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 48
#define SQR_TOOM3_THRESHOLD 163
#define SQR_TOOM4_THRESHOLD 250
#define SQR_TOOM6_THRESHOLD 354
#define SQR_TOOM8_THRESHOLD 502
#define MULMID_TOOM42_THRESHOLD 98
#define MULMOD_BNM1_THRESHOLD 19
#define SQRMOD_BNM1_THRESHOLD 23
#define MUL_FFT_MODF_THRESHOLD 666 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 666, 5}, { 28, 6}, { 15, 5}, { 31, 6}, \
{ 28, 7}, { 15, 6}, { 33, 7}, { 17, 6}, \
{ 36, 7}, { 19, 6}, { 39, 7}, { 23, 6}, \
{ 47, 7}, { 29, 8}, { 15, 7}, { 35, 8}, \
{ 19, 7}, { 41, 8}, { 23, 7}, { 49, 8}, \
{ 27, 7}, { 55, 8}, { 31, 7}, { 63, 8}, \
{ 43, 9}, { 23, 8}, { 55, 9}, { 31, 8}, \
{ 71, 9}, { 39, 8}, { 79, 9}, { 47, 8}, \
{ 99, 9}, { 55,10}, { 31, 9}, { 79,10}, \
{ 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
{ 135,10}, { 79, 9}, { 159,10}, { 95, 9}, \
{ 191,11}, { 63,10}, { 159, 7}, { 1343, 8}, \
{ 703, 9}, { 367, 8}, { 735, 9}, { 383,10}, \
{ 207,11}, { 127,10}, { 255, 9}, { 511,10}, \
{ 271, 9}, { 543,10}, { 287,11}, { 159,10}, \
{ 319, 9}, { 639,10}, { 335,11}, { 191,10}, \
{ 383, 9}, { 767,11}, { 223,12}, { 127,11}, \
{ 255,10}, { 543,11}, { 287,10}, { 607, 9}, \
{ 1215,11}, { 319,10}, { 671,12}, { 191,11}, \
{ 383,10}, { 799,13}, { 127,12}, { 255,11}, \
{ 511,10}, { 1023,11}, { 543,10}, { 1087,11}, \
{ 607,10}, { 1215,12}, { 319,11}, { 671,10}, \
{ 1343,11}, { 735,10}, { 1471,12}, { 383,11}, \
{ 799,10}, { 1599,11}, { 863,12}, { 447,11}, \
{ 959,13}, { 255,12}, { 511,11}, { 1087,12}, \
{ 575,11}, { 1215,12}, { 639,11}, { 1343,12}, \
{ 703,11}, { 1471,13}, { 383,12}, { 767,11}, \
{ 1599,12}, { 831,11}, { 1727,12}, { 959,14}, \
{ 255,13}, { 511,12}, { 1087,11}, { 2239,12}, \
{ 1215,13}, { 639,12}, { 1471,11}, { 2943,13}, \
{ 767,12}, { 1727,11}, { 3455,13}, { 895,12}, \
{ 1983,14}, { 511,13}, { 1023,12}, { 2239,13}, \
{ 1151,12}, { 2495,13}, { 1279,12}, { 2623,13}, \
{ 1407,12}, { 2943,14}, { 767,13}, { 1535,12}, \
{ 3071,13}, { 1663,12}, { 3455,13}, { 1919,15}, \
{ 511,14}, { 1023,13}, { 2175,12}, { 4479,13}, \
{ 2431,14}, { 1279,13}, { 2943,12}, { 5887,14}, \
{ 1535,13}, { 3455,14}, { 1791,13}, { 3967,15}, \
{ 1023,14}, { 2047,13}, { 4479,14}, { 2303,13}, \
{ 4991,12}, { 9983,14}, { 2815,13}, { 5887,15}, \
{ 1535,14}, { 3839,13}, { 7679,16} }
#define MUL_FFT_TABLE3_SIZE 163
#define MUL_FFT_THRESHOLD 7552
#define SQR_FFT_MODF_THRESHOLD 570 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 570, 5}, { 28, 6}, { 15, 5}, { 32, 6}, \
{ 17, 5}, { 35, 6}, { 29, 7}, { 15, 6}, \
{ 33, 7}, { 17, 6}, { 36, 7}, { 19, 6}, \
{ 40, 7}, { 23, 6}, { 47, 7}, { 29, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 43, 8}, \
{ 23, 7}, { 49, 8}, { 27, 7}, { 55, 8}, \
{ 31, 7}, { 63, 8}, { 43, 9}, { 23, 8}, \
{ 55, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
{ 79, 9}, { 47, 8}, { 95, 9}, { 55,10}, \
{ 31, 9}, { 79,10}, { 47, 9}, { 95,11}, \
{ 31,10}, { 63, 9}, { 135,10}, { 79, 9}, \
{ 159,10}, { 95,11}, { 63,10}, { 159,11}, \
{ 95,10}, { 191,12}, { 63, 8}, { 1023, 9}, \
{ 543,11}, { 159,10}, { 319, 9}, { 639,10}, \
{ 335,11}, { 191,10}, { 383, 9}, { 767,10}, \
{ 399, 9}, { 799,12}, { 127,11}, { 255,10}, \
{ 511, 9}, { 1023,10}, { 543,11}, { 287,10}, \
{ 607,11}, { 319,10}, { 671,11}, { 351,12}, \
{ 191,11}, { 383,10}, { 799,13}, { 127,12}, \
{ 255,11}, { 511,10}, { 1023,11}, { 543,10}, \
{ 1087,11}, { 607,12}, { 319,11}, { 671,10}, \
{ 1343,11}, { 735,10}, { 1471,12}, { 383,11}, \
{ 799,10}, { 1599,11}, { 863,12}, { 447,11}, \
{ 991,13}, { 255,12}, { 511,11}, { 1087,12}, \
{ 575,11}, { 1215,12}, { 639,11}, { 1343,12}, \
{ 703,11}, { 1471,13}, { 383,12}, { 767,11}, \
{ 1599,12}, { 831,11}, { 1727,12}, { 959,11}, \
{ 1919,14}, { 255,13}, { 511,12}, { 1023,11}, \
{ 2047,12}, { 1087,11}, { 2239,12}, { 1215,11}, \
{ 2431,13}, { 639,12}, { 1471,13}, { 767,12}, \
{ 1727,13}, { 895,12}, { 1983,14}, { 511,13}, \
{ 1023,12}, { 2239,13}, { 1151,12}, { 2495,13}, \
{ 1279,12}, { 2623,13}, { 1407,12}, { 2943,14}, \
{ 767,13}, { 1663,12}, { 3455,13}, { 1919,12}, \
{ 3967,15}, { 511,14}, { 1023,13}, { 2175,12}, \
{ 4479,13}, { 2431,12}, { 4863,14}, { 1279,13}, \
{ 2943,12}, { 5887,14}, { 1535,13}, { 3455,14}, \
{ 1791,13}, { 3967,15}, { 1023,14}, { 2047,13}, \
{ 4479,14}, { 2303,13}, { 4991,12}, { 9983,14}, \
{ 2559,13}, { 5119,14}, { 2815,13}, { 5887,15}, \
{ 1535,14}, { 3839,13}, { 7679,16} }
#define SQR_FFT_TABLE3_SIZE 163
#define SQR_FFT_THRESHOLD 5760
#define MULLO_BASECASE_THRESHOLD 16
#define MULLO_DC_THRESHOLD 46
#define MULLO_MUL_N_THRESHOLD 14281
#define SQRLO_BASECASE_THRESHOLD 0 /* always */
#define SQRLO_DC_THRESHOLD 159
#define SQRLO_SQR_THRESHOLD 11317
#define DC_DIV_QR_THRESHOLD 47
#define DC_DIVAPPR_Q_THRESHOLD 191
#define DC_BDIV_QR_THRESHOLD 107
#define DC_BDIV_Q_THRESHOLD 232
#define INV_MULMOD_BNM1_THRESHOLD 62
#define INV_NEWTON_THRESHOLD 181
#define INV_APPR_THRESHOLD 182
#define BINV_NEWTON_THRESHOLD 378
#define REDC_1_TO_REDC_N_THRESHOLD 91
#define MU_DIV_QR_THRESHOLD 1858
#define MU_DIVAPPR_Q_THRESHOLD 1858
#define MUPI_DIV_QR_THRESHOLD 77
#define MU_BDIV_QR_THRESHOLD 1830
#define MU_BDIV_Q_THRESHOLD 2166
#define POWM_SEC_TABLE 1,16,126,428,1442
#define GET_STR_DC_THRESHOLD 10
#define GET_STR_PRECOMPUTE_THRESHOLD 16
#define SET_STR_DC_THRESHOLD 418
#define SET_STR_PRECOMPUTE_THRESHOLD 1104
#define FAC_DSC_THRESHOLD 149
#define FAC_ODD_THRESHOLD 34
#define MATRIX22_STRASSEN_THRESHOLD 21
#define HGCD2_DIV1_METHOD 1 /* 5.54% faster than 4 */
#define HGCD_THRESHOLD 66
#define HGCD_APPR_THRESHOLD 135
#define HGCD_REDUCE_THRESHOLD 4284
#define GCD_DC_THRESHOLD 642
#define GCDEXT_DC_THRESHOLD 465
#define JACOBI_BASE_METHOD 3 /* 14.76% faster than 4 */
/* Tuneup completed successfully, took 44241 seconds */

View File

@@ -0,0 +1,102 @@
divert(-1)
dnl Copyright 2007, 2011, 2012, 2014 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
define(`DARWIN')
dnl Usage LEA(symbol,reg)
dnl Usage LEAL(symbol_local_to_file,reg)
dnl
dnl We maintain lists of stuff to append in load_eip and darwin_bd. The
dnl `index' stuff is needed to suppress repeated definitions. To avoid
dnl getting fooled by "var" and "var1", we add 'bol ' (the end of
dnl 'indirect_symbol') at the beginning and and a newline at the end. This
dnl might be a bit fragile.
define(`LEA',
m4_assert_numargs(2)
`ifdef(`PIC',`
ifelse(index(defn(`load_eip'), `$2'),-1,
`m4append(`load_eip',
` TEXT
ALIGN(16)
L(movl_eip_`'substr($2,1)):
movl (%esp), $2
ret_internal
')')
ifelse(index(defn(`darwin_bd'), `bol $1
'),-1,
`m4append(`darwin_bd',
` .section __IMPORT,__pointers,non_lazy_symbol_pointers
L($1`'$non_lazy_ptr):
.indirect_symbol $1
.long 0
')')
call L(movl_eip_`'substr($2,1))
movl L($1`'$non_lazy_ptr)-.($2), $2
',`
movl `$'$1, $2
')')
define(`LEAL',
m4_assert_numargs(2)
`ifdef(`PIC',`
ifelse(index(defn(`load_eip'), `$2'),-1,
`m4append(`load_eip',
` TEXT
ALIGN(16)
L(movl_eip_`'substr($2,1)):
movl (%esp), $2
ret_internal
')')
call L(movl_eip_`'substr($2,1))
leal $1-.($2), $2
',`
movl `$'$1, $2
')')
dnl ASM_END
define(`ASM_END',`load_eip`'darwin_bd')
define(`load_eip', `') dnl updated in LEA
define(`darwin_bd', `') dnl updated in LEA
dnl Usage: CALL(funcname)
dnl
define(`CALL',
m4_assert_numargs(1)
`call GSYM_PREFIX`'$1')
undefine(`PIC_WITH_EBX')
divert`'dnl

View File

@@ -0,0 +1,190 @@
dnl x86 mpn_divexact_1 -- mpn by limb exact division.
dnl Copyright 2001, 2002, 2007 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C P54 30.0
C P55 29.0
C P6 13.0 odd divisor, 12.0 even (strangely)
C K6 14.0
C K7 12.0
C P4 42.0
C mp_limb_t mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
C mp_limb_t divisor);
C
defframe(PARAM_DIVISOR,16)
defframe(PARAM_SIZE, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
dnl re-use parameter space
define(VAR_INVERSE,`PARAM_SRC')
TEXT
ALIGN(16)
PROLOGUE(mpn_divexact_1)
deflit(`FRAME',0)
movl PARAM_DIVISOR, %eax
pushl %ebp FRAME_pushl()
movl PARAM_SIZE, %ebp
pushl %edi FRAME_pushl()
pushl %ebx FRAME_pushl()
movl $-1, %ecx C shift count
pushl %esi FRAME_pushl()
L(strip_twos):
incl %ecx
shrl %eax
jnc L(strip_twos)
leal 1(%eax,%eax), %ebx C d without twos
andl $127, %eax C d/2, 7 bits
ifdef(`PIC',`
LEA( binvert_limb_table, %edx)
movzbl (%eax,%edx), %eax C inv 8 bits
',`
movzbl binvert_limb_table(%eax), %eax C inv 8 bits
')
leal (%eax,%eax), %edx C 2*inv
movl %ebx, PARAM_DIVISOR C d without twos
imull %eax, %eax C inv*inv
movl PARAM_SRC, %esi
movl PARAM_DST, %edi
imull %ebx, %eax C inv*inv*d
subl %eax, %edx C inv = 2*inv - inv*inv*d
leal (%edx,%edx), %eax C 2*inv
imull %edx, %edx C inv*inv
leal (%esi,%ebp,4), %esi C src end
leal (%edi,%ebp,4), %edi C dst end
negl %ebp C -size
imull %ebx, %edx C inv*inv*d
subl %edx, %eax C inv = 2*inv - inv*inv*d
ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
pushl %eax FRAME_pushl()
imull PARAM_DIVISOR, %eax
cmpl $1, %eax
popl %eax FRAME_popl()')
movl %eax, VAR_INVERSE
movl (%esi,%ebp,4), %eax C src[0]
xorl %ebx, %ebx
xorl %edx, %edx
incl %ebp
jz L(one)
movl (%esi,%ebp,4), %edx C src[1]
shrdl( %cl, %edx, %eax)
movl VAR_INVERSE, %edx
jmp L(entry)
ALIGN(8)
nop C k6 code alignment
nop
L(top):
C eax q
C ebx carry bit, 0 or -1
C ecx shift
C edx carry limb
C esi src end
C edi dst end
C ebp counter, limbs, negative
movl -4(%esi,%ebp,4), %eax
subl %ebx, %edx C accumulate carry bit
movl (%esi,%ebp,4), %ebx
shrdl( %cl, %ebx, %eax)
subl %edx, %eax C apply carry limb
movl VAR_INVERSE, %edx
sbbl %ebx, %ebx
L(entry):
imull %edx, %eax
movl %eax, -4(%edi,%ebp,4)
movl PARAM_DIVISOR, %edx
mull %edx
incl %ebp
jnz L(top)
movl -4(%esi), %eax C src high limb
L(one):
shrl %cl, %eax
popl %esi FRAME_popl()
addl %ebx, %eax C apply carry bit
popl %ebx FRAME_popl()
subl %edx, %eax C apply carry limb
imull VAR_INVERSE, %eax
movl %eax, -4(%edi)
popl %edi
popl %ebp
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,233 @@
dnl x86 mpn_divrem_1 -- mpn by limb division extending to fractional quotient.
dnl Copyright 1999-2003, 2007 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C 486 approx 43 maybe
C P5 44
C P6 39
C P6MMX 39
C K6 22
C K7 42
C P4 58
C mp_limb_t mpn_divrem_1 (mp_ptr dst, mp_size_t xsize,
C mp_srcptr src, mp_size_t size, mp_limb_t divisor);
C mp_limb_t mpn_divrem_1c (mp_ptr dst, mp_size_t xsize,
C mp_srcptr src, mp_size_t size, mp_limb_t divisor,
C mp_limb_t carry);
C
C Divide src,size by divisor and store the quotient in dst+xsize,size.
C Extend the division to fractional quotient limbs in dst,xsize. Return the
C remainder. Either or both xsize and size can be 0.
C
C mpn_divrem_1c takes a carry parameter which is an initial high limb,
C effectively one extra limb at the top of src,size. Must have
C carry<divisor.
C
C
C Essentially the code is the same as the division based part of
C mpn/generic/divrem_1.c, but has the advantage that we get the desired divl
C instruction even when gcc is not being used (when longlong.h only has the
C rather slow generic C udiv_qrnnd().
C
C A test is done to see if the high limb is less than the divisor, and if so
C one less div is done. A div is between 20 and 40 cycles on the various
C x86s, so assuming high<divisor about half the time, then this test saves
C half that amount. The branch misprediction penalty on each chip is less
C than half a div.
C
C
C Notes for P5:
C
C It might be thought that moving the load down to pair with the store would
C save 1 cycle, but that doesn't seem to happen in practice, and in any case
C would be a mere 2.2% saving, so it's hardly worth bothering about.
C
C A mul-by-inverse might be a possibility for P5, as done in
C mpn/x86/pentium/mod_1.asm. The number of auxiliary instructions required
C is a hinderance, but there could be a 10-15% speedup available.
C
C
C Notes for K6:
C
C K6 has its own version of this code, using loop and paying attention to
C cache line boundary crossings. The target 20 c/l can be had with the
C decl+jnz of the present code by pairing up the load and store in the
C loops. But it's considered easier not to introduce complexity just for
C that, but instead let k6 have its own code.
C
defframe(PARAM_CARRY, 24)
defframe(PARAM_DIVISOR,20)
defframe(PARAM_SIZE, 16)
defframe(PARAM_SRC, 12)
defframe(PARAM_XSIZE, 8)
defframe(PARAM_DST, 4)
TEXT
ALIGN(16)
PROLOGUE(mpn_divrem_1c)
deflit(`FRAME',0)
movl PARAM_SIZE, %ecx
pushl %edi FRAME_pushl()
movl PARAM_SRC, %edi
pushl %esi FRAME_pushl()
movl PARAM_DIVISOR, %esi
pushl %ebx FRAME_pushl()
movl PARAM_DST, %ebx
pushl %ebp FRAME_pushl()
movl PARAM_XSIZE, %ebp
orl %ecx, %ecx
movl PARAM_CARRY, %edx
jz L(fraction)
leal -4(%ebx,%ebp,4), %ebx C dst one limb below integer part
jmp L(integer_top)
EPILOGUE()
PROLOGUE(mpn_divrem_1)
deflit(`FRAME',0)
movl PARAM_SIZE, %ecx
pushl %edi FRAME_pushl()
movl PARAM_SRC, %edi
pushl %esi FRAME_pushl()
movl PARAM_DIVISOR, %esi
orl %ecx,%ecx
jz L(size_zero)
pushl %ebx FRAME_pushl()
movl -4(%edi,%ecx,4), %eax C src high limb
xorl %edx, %edx
movl PARAM_DST, %ebx
pushl %ebp FRAME_pushl()
movl PARAM_XSIZE, %ebp
cmpl %esi, %eax
leal -4(%ebx,%ebp,4), %ebx C dst one limb below integer part
jae L(integer_entry)
C high<divisor, so high of dst is zero, and avoid one div
movl %edx, (%ebx,%ecx,4)
decl %ecx
movl %eax, %edx
jz L(fraction)
L(integer_top):
C eax scratch (quotient)
C ebx dst+4*xsize-4
C ecx counter
C edx scratch (remainder)
C esi divisor
C edi src
C ebp xsize
movl -4(%edi,%ecx,4), %eax
L(integer_entry):
divl %esi
movl %eax, (%ebx,%ecx,4)
decl %ecx
jnz L(integer_top)
L(fraction):
orl %ebp, %ecx
jz L(done)
movl PARAM_DST, %ebx
L(fraction_top):
C eax scratch (quotient)
C ebx dst
C ecx counter
C edx scratch (remainder)
C esi divisor
C edi
C ebp
xorl %eax, %eax
divl %esi
movl %eax, -4(%ebx,%ecx,4)
decl %ecx
jnz L(fraction_top)
L(done):
popl %ebp
movl %edx, %eax
popl %ebx
popl %esi
popl %edi
ret
L(size_zero):
deflit(`FRAME',8)
movl PARAM_XSIZE, %ecx
xorl %eax, %eax
movl PARAM_DST, %edi
cld C better safe than sorry, see mpn/x86/README
rep
stosl
popl %esi
popl %edi
ret
EPILOGUE()

View File

@@ -0,0 +1,199 @@
dnl x86 mpn_divrem_2 -- Divide an mpn number by a normalized 2-limb number.
dnl Copyright 2007, 2008 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C norm frac
C 486
C P5
C P6-13 29.2
C P6-15 *26
C K6
C K7 22
C K8 *19
C P4-f1
C P4-f2 *65
C P4-f3
C P4-f4 *72
C A star means numbers not updated for the latest version of the code.
C TODO
C * Perhaps keep ecx or esi in stack slot, freeing up a reg for q0.
C * The loop has not been carefully tuned. We should at the very least do
C some local insn swapping.
C * The code outside the main loop is what gcc generated. Clean up!
C * Clean up stack slot usage.
C INPUT PARAMETERS
C qp
C fn
C up_param
C un_param
C dp
C eax ebx ecx edx esi edi ebp
C cnt qp
ASM_START()
TEXT
ALIGN(16)
PROLOGUE(mpn_divrem_2)
push %ebp
push %edi
push %esi
push %ebx
sub $36, %esp
mov 68(%esp), %ecx C un
mov 72(%esp), %esi C dp
movl $0, 32(%esp)
lea 0(,%ecx,4), %edi
add 64(%esp), %edi C up
mov (%esi), %ebx
mov 4(%esi), %eax
mov %ebx, 20(%esp)
sub $12, %edi
mov %eax, 24(%esp)
mov %edi, 12(%esp)
mov 8(%edi), %ebx
mov 4(%edi), %ebp
cmp %eax, %ebx
jb L(8)
seta %dl
cmp 20(%esp), %ebp
setae %al
orb %dl, %al C "orb" form to placate Sun tools
jne L(35)
L(8):
mov 60(%esp), %esi C fn
lea -3(%esi,%ecx), %edi
test %edi, %edi
js L(9)
mov 24(%esp), %edx
mov $-1, %esi
mov %esi, %eax
mov %esi, %ecx
not %edx
divl 24(%esp)
mov %eax, %esi
imul 24(%esp), %eax
mov %eax, (%esp)
mov %esi, %eax
mull 20(%esp)
mov (%esp), %eax
add 20(%esp), %eax
adc $0, %ecx
add %eax, %edx
adc $0, %ecx
mov %ecx, %eax
js L(32)
L(36): dec %esi
sub 24(%esp), %edx
sbb $0, %eax
jns L(36)
L(32):
mov %esi, 16(%esp) C di
mov %edi, %ecx C un
mov 12(%esp), %esi C up
mov 24(%esp), %eax
neg %eax
mov %eax, 4(%esp) C -d1
ALIGN(16)
nop
C eax ebx ecx edx esi edi ebp 0 4 8 12 16 20 24 28 32 56 60
C n2 un up n1 q0 -d1 di d0 d1 msl qp fn
L(loop):
mov 16(%esp), %eax C di
mul %ebx
add %ebp, %eax
mov %eax, (%esp) C q0
adc %ebx, %edx
mov %edx, %edi C q
imul 4(%esp), %edx
mov 20(%esp), %eax
lea (%edx, %ebp), %ebx C n1 -= ...
mul %edi
xor %ebp, %ebp
cmp 60(%esp), %ecx
jl L(19)
mov (%esi), %ebp
sub $4, %esi
L(19): sub 20(%esp), %ebp
sbb 24(%esp), %ebx
sub %eax, %ebp
sbb %edx, %ebx
mov 20(%esp), %eax C d1
inc %edi
xor %edx, %edx
cmp (%esp), %ebx
adc $-1, %edx C mask
add %edx, %edi C q--
and %edx, %eax C d0 or 0
and 24(%esp), %edx C d1 or 0
add %eax, %ebp
adc %edx, %ebx
cmp 24(%esp), %ebx
jae L(fix)
L(bck): mov 56(%esp), %edx
mov %edi, (%edx, %ecx, 4)
dec %ecx
jns L(loop)
L(9): mov 64(%esp), %esi C up
mov %ebp, (%esi)
mov %ebx, 4(%esi)
mov 32(%esp), %eax
add $36, %esp
pop %ebx
pop %esi
pop %edi
pop %ebp
ret
L(fix): seta %dl
cmp 20(%esp), %ebp
setae %al
orb %dl, %al C "orb" form to placate Sun tools
je L(bck)
inc %edi
sub 20(%esp), %ebp
sbb 24(%esp), %ebx
jmp L(bck)
L(35): sub 20(%esp), %ebp
sbb 24(%esp), %ebx
movl $1, 32(%esp)
jmp L(8)
EPILOGUE()

View File

@@ -0,0 +1,32 @@
/* Fat binary fallback mpn_com.
Copyright 2003, 2009, 2011 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#include "mpn/generic/com.c"

View File

@@ -0,0 +1,530 @@
/* x86 fat binary initializers.
THE FUNCTIONS AND VARIABLES IN THIS FILE ARE FOR INTERNAL USE ONLY.
THEY'RE ALMOST CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR
COMPLETELY IN FUTURE GNU MP RELEASES.
Copyright 2003, 2004, 2011-2013, 2015, 2017, 2018 Free Software Foundation,
Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#include <stdio.h> /* for printf */
#include <stdlib.h> /* for getenv */
#include <string.h>
#include "gmp-impl.h"
/* Change this to "#define TRACE(x) x" for some traces. */
#define TRACE(x)
/* fat_entry.asm */
long __gmpn_cpuid (char [12], int);
int __gmpn_cpuid_available (void);
#if WANT_FAKE_CPUID
/* The "name"s in the table are values for the GMP_CPU_TYPE environment
variable. Anything can be used, but for now it's the canonical cpu types
as per config.guess/config.sub. */
#define __gmpn_cpuid fake_cpuid
#define __gmpn_cpuid_available fake_cpuid_available
#define MAKE_FMS(family, model) \
((((family) & 0xf) << 8) + (((family) & 0xff0) << 20) \
+ (((model) & 0xf) << 4) + (((model) & 0xf0) << 12))
static struct {
const char *name;
const char *vendor;
unsigned fms;
} fake_cpuid_table[] = {
{ "i386", "" },
{ "i486", "GenuineIntel", MAKE_FMS (4, 0) },
{ "pentium", "GenuineIntel", MAKE_FMS (5, 0) },
{ "pentiummmx", "GenuineIntel", MAKE_FMS (5, 4) },
{ "pentiumpro", "GenuineIntel", MAKE_FMS (6, 0) },
{ "pentium2", "GenuineIntel", MAKE_FMS (6, 2) },
{ "pentium3", "GenuineIntel", MAKE_FMS (6, 7) },
{ "pentium4", "GenuineIntel", MAKE_FMS (15, 2) },
{ "prescott", "GenuineIntel", MAKE_FMS (15, 3) },
{ "nocona", "GenuineIntel", MAKE_FMS (15, 4) },
{ "core2", "GenuineIntel", MAKE_FMS (6, 0xf) },
{ "nehalem", "GenuineIntel", MAKE_FMS (6, 0x1a) },
{ "nhm", "GenuineIntel", MAKE_FMS (6, 0x1a) },
{ "atom", "GenuineIntel", MAKE_FMS (6, 0x1c) },
{ "westmere", "GenuineIntel", MAKE_FMS (6, 0x25) },
{ "wsm", "GenuineIntel", MAKE_FMS (6, 0x25) },
{ "sandybridge","GenuineIntel", MAKE_FMS (6, 0x2a) },
{ "sbr", "GenuineIntel", MAKE_FMS (6, 0x2a) },
{ "silvermont", "GenuineIntel", MAKE_FMS (6, 0x37) },
{ "slm", "GenuineIntel", MAKE_FMS (6, 0x37) },
{ "haswell", "GenuineIntel", MAKE_FMS (6, 0x3c) },
{ "hwl", "GenuineIntel", MAKE_FMS (6, 0x3c) },
{ "broadwell", "GenuineIntel", MAKE_FMS (6, 0x3d) },
{ "bwl", "GenuineIntel", MAKE_FMS (6, 0x3d) },
{ "skylake", "GenuineIntel", MAKE_FMS (6, 0x5e) },
{ "sky", "GenuineIntel", MAKE_FMS (6, 0x5e) },
{ "k5", "AuthenticAMD", MAKE_FMS (5, 0) },
{ "k6", "AuthenticAMD", MAKE_FMS (5, 3) },
{ "k62", "AuthenticAMD", MAKE_FMS (5, 8) },
{ "k63", "AuthenticAMD", MAKE_FMS (5, 9) },
{ "athlon", "AuthenticAMD", MAKE_FMS (6, 0) },
{ "k8", "AuthenticAMD", MAKE_FMS (15, 0) },
{ "k10", "AuthenticAMD", MAKE_FMS (16, 0) },
{ "bobcat", "AuthenticAMD", MAKE_FMS (20, 1) },
{ "bulldozer", "AuthenticAMD", MAKE_FMS (21, 1) },
{ "piledriver", "AuthenticAMD", MAKE_FMS (21, 2) },
{ "steamroller","AuthenticAMD", MAKE_FMS (21, 0x30) },
{ "excavator", "AuthenticAMD", MAKE_FMS (21, 0x60) },
{ "jaguar", "AuthenticAMD", MAKE_FMS (22, 1) },
{ "zen", "AuthenticAMD", MAKE_FMS (23, 1) },
{ "viac3", "CentaurHauls", MAKE_FMS (6, 0) },
{ "viac32", "CentaurHauls", MAKE_FMS (6, 9) },
{ "nano", "CentaurHauls", MAKE_FMS (6, 15) },
};
static int
fake_cpuid_lookup (void)
{
char *s;
int i;
s = getenv ("GMP_CPU_TYPE");
if (s == NULL)
{
printf ("Need GMP_CPU_TYPE environment variable for fake cpuid\n");
abort ();
}
for (i = 0; i < numberof (fake_cpuid_table); i++)
if (strcmp (s, fake_cpuid_table[i].name) == 0)
return i;
printf ("GMP_CPU_TYPE=%s unknown\n", s);
abort ();
}
static int
fake_cpuid_available (void)
{
return fake_cpuid_table[fake_cpuid_lookup()].vendor[0] != '\0';
}
static long
fake_cpuid (char dst[12], int id)
{
int i = fake_cpuid_lookup();
switch (id) {
case 0:
memcpy (dst, fake_cpuid_table[i].vendor, 12);
return 0;
case 1:
return fake_cpuid_table[i].fms;
default:
printf ("fake_cpuid(): oops, unknown id %d\n", id);
abort ();
}
}
#endif
typedef DECL_preinv_divrem_1 ((*preinv_divrem_1_t));
typedef DECL_preinv_mod_1 ((*preinv_mod_1_t));
struct cpuvec_t __gmpn_cpuvec = {
__MPN(add_n_init),
0,
0,
__MPN(addmul_1_init),
0,
__MPN(bdiv_dbm1c_init),
__MPN(cnd_add_n_init),
__MPN(cnd_sub_n_init),
__MPN(com_init),
__MPN(copyd_init),
__MPN(copyi_init),
__MPN(divexact_1_init),
__MPN(divrem_1_init),
__MPN(gcd_11_init),
__MPN(lshift_init),
__MPN(lshiftc_init),
__MPN(mod_1_init),
__MPN(mod_1_1p_init),
__MPN(mod_1_1p_cps_init),
__MPN(mod_1s_2p_init),
__MPN(mod_1s_2p_cps_init),
__MPN(mod_1s_4p_init),
__MPN(mod_1s_4p_cps_init),
__MPN(mod_34lsub1_init),
__MPN(modexact_1c_odd_init),
__MPN(mul_1_init),
__MPN(mul_basecase_init),
__MPN(mullo_basecase_init),
__MPN(preinv_divrem_1_init),
__MPN(preinv_mod_1_init),
__MPN(redc_1_init),
__MPN(redc_2_init),
__MPN(rshift_init),
__MPN(sqr_basecase_init),
__MPN(sub_n_init),
0,
__MPN(submul_1_init),
0
};
int __gmpn_cpuvec_initialized = 0;
/* The following setups start with generic x86, then overwrite with
specifics for a chip, and higher versions of that chip.
The arrangement of the setups here will normally be the same as the $path
selections in configure.in for the respective chips.
This code is reentrant and thread safe. We always calculate the same
decided_cpuvec, so if two copies of the code are running it doesn't
matter which completes first, both write the same to __gmpn_cpuvec.
We need to go via decided_cpuvec because if one thread has completed
__gmpn_cpuvec then it may be making use of the threshold values in that
vector. If another thread is still running __gmpn_cpuvec_init then we
don't want it to write different values to those fields since some of the
asm routines only operate correctly up to their own defined threshold,
not an arbitrary value. */
void
__gmpn_cpuvec_init (void)
{
struct cpuvec_t decided_cpuvec;
TRACE (printf ("__gmpn_cpuvec_init:\n"));
memset (&decided_cpuvec, '\0', sizeof (decided_cpuvec));
CPUVEC_SETUP_x86;
CPUVEC_SETUP_fat;
if (! __gmpn_cpuid_available ())
{
TRACE (printf (" 80386, or early 80486 without cpuid\n"));
}
else
{
char vendor_string[13];
char dummy_string[12];
long fms;
int family, model;
__gmpn_cpuid (vendor_string, 0);
vendor_string[12] = 0;
fms = __gmpn_cpuid (dummy_string, 1);
family = ((fms >> 8) & 0xf) + ((fms >> 20) & 0xff);
model = ((fms >> 4) & 0xf) + ((fms >> 12) & 0xf0);
if (strcmp (vendor_string, "GenuineIntel") == 0)
{
switch (family)
{
case 4:
TRACE (printf (" 80486 with cpuid\n"));
break;
case 5:
TRACE (printf (" pentium\n"));
CPUVEC_SETUP_pentium;
if (model == 4 || model == 8)
{
TRACE (printf (" pentiummmx\n"));
CPUVEC_SETUP_pentium_mmx;
}
break;
case 6:
TRACE (printf (" p6\n"));
CPUVEC_SETUP_p6;
switch (model)
{
case 0x00:
case 0x01:
TRACE (printf (" pentiumpro\n"));
break;
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
TRACE (printf (" pentium2\n"));
CPUVEC_SETUP_p6_mmx;
break;
case 0x07:
case 0x08:
case 0x0a:
case 0x0b:
case 0x0c:
TRACE (printf (" pentium3\n"));
CPUVEC_SETUP_p6_mmx;
CPUVEC_SETUP_p6_p3mmx;
break;
case 0x09: /* Banias */
case 0x0d: /* Dothan */
case 0x0e: /* Yonah */
TRACE (printf (" Banias/Dothan/Yonah\n"));
CPUVEC_SETUP_p6_mmx;
CPUVEC_SETUP_p6_p3mmx;
CPUVEC_SETUP_p6_sse2;
break;
case 0x0f: /* Conroe Merom Kentsfield Allendale */
case 0x10:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
case 0x15:
case 0x16:
case 0x17: /* PNR Wolfdale Yorkfield */
case 0x18:
case 0x19:
case 0x1d: /* PNR Dunnington */
TRACE (printf (" Conroe\n"));
CPUVEC_SETUP_p6_mmx;
CPUVEC_SETUP_p6_p3mmx;
CPUVEC_SETUP_p6_sse2;
CPUVEC_SETUP_core2;
break;
case 0x1c: /* Atom Silverthorne */
case 0x26: /* Atom Lincroft */
case 0x27: /* Atom Saltwell */
case 0x36: /* Atom Cedarview/Saltwell */
TRACE (printf (" atom\n"));
CPUVEC_SETUP_atom;
CPUVEC_SETUP_atom_mmx;
CPUVEC_SETUP_atom_sse2;
break;
case 0x37: /* Silvermont */
case 0x4a: /* Silvermont */
case 0x4c: /* Airmont */
case 0x4d: /* Silvermont/Avoton */
case 0x5a: /* Silvermont */
TRACE (printf (" silvermont\n"));
CPUVEC_SETUP_atom;
CPUVEC_SETUP_atom_mmx;
CPUVEC_SETUP_atom_sse2;
CPUVEC_SETUP_silvermont;
break;
case 0x5c: /* Goldmont */
case 0x5f: /* Goldmont */
case 0x7a: /* Goldmont Plus */
TRACE (printf (" goldmont\n"));
CPUVEC_SETUP_atom;
CPUVEC_SETUP_atom_mmx;
CPUVEC_SETUP_atom_sse2;
CPUVEC_SETUP_goldmont;
break;
case 0x1a: /* NHM Gainestown */
case 0x1b:
case 0x1e: /* NHM Lynnfield/Jasper */
case 0x1f:
case 0x20:
case 0x21:
case 0x22:
case 0x23:
case 0x24:
case 0x25: /* WSM Clarkdale/Arrandale */
case 0x28:
case 0x29:
case 0x2b:
case 0x2c: /* WSM Gulftown */
case 0x2e: /* NHM Beckton */
case 0x2f: /* WSM Eagleton */
TRACE (printf (" nehalem/westmere\n"));
CPUVEC_SETUP_p6_mmx;
CPUVEC_SETUP_p6_p3mmx;
CPUVEC_SETUP_p6_sse2;
CPUVEC_SETUP_core2;
CPUVEC_SETUP_coreinhm;
break;
case 0x2a: /* SBR */
case 0x2d: /* SBR-EP */
case 0x3a: /* IBR */
case 0x3e: /* IBR Ivytown */
case 0x3c: /* Haswell client */
case 0x3f: /* Haswell server */
case 0x45: /* Haswell ULT */
case 0x46: /* Crystal Well */
case 0x3d: /* Broadwell */
case 0x47: /* Broadwell */
case 0x4f: /* Broadwell server */
case 0x56: /* Broadwell microserver */
case 0x4e: /* Skylake client */
case 0x55: /* Skylake server */
case 0x5e: /* Skylake */
case 0x8e: /* Kabylake */
case 0x9e: /* Kabylake */
TRACE (printf (" sandybridge\n"));
CPUVEC_SETUP_p6_mmx;
CPUVEC_SETUP_p6_p3mmx;
CPUVEC_SETUP_p6_sse2;
CPUVEC_SETUP_core2;
CPUVEC_SETUP_coreinhm;
CPUVEC_SETUP_coreisbr;
break;
}
break;
case 15:
TRACE (printf (" pentium4\n"));
CPUVEC_SETUP_pentium4;
CPUVEC_SETUP_pentium4_mmx;
CPUVEC_SETUP_pentium4_sse2;
break;
}
}
else if (strcmp (vendor_string, "AuthenticAMD") == 0)
{
switch (family)
{
case 5:
if (model <= 3)
{
TRACE (printf (" k5\n"));
}
else
{
TRACE (printf (" k6\n"));
CPUVEC_SETUP_k6;
CPUVEC_SETUP_k6_mmx;
if (model >= 8)
{
TRACE (printf (" k62\n"));
CPUVEC_SETUP_k6_k62mmx;
}
if (model >= 9)
{
TRACE (printf (" k63\n"));
}
}
break;
case 6:
TRACE (printf (" athlon\n"));
CPUVEC_SETUP_k7;
CPUVEC_SETUP_k7_mmx;
break;
case 0x0f: /* k8 */
case 0x11: /* "fam 11h", mix of k8 and k10 */
case 0x13: /* unknown, conservatively assume k8 */
TRACE (printf (" k8\n"));
CPUVEC_SETUP_k7;
CPUVEC_SETUP_k7_mmx;
CPUVEC_SETUP_k8;
break;
case 0x10: /* k10 */
case 0x12: /* k10 (llano) */
TRACE (printf (" k10\n"));
CPUVEC_SETUP_k7;
CPUVEC_SETUP_k7_mmx;
break;
case 0x14: /* bobcat */
case 0x16: /* jaguar */
TRACE (printf (" bobcat\n"));
CPUVEC_SETUP_k7;
CPUVEC_SETUP_k7_mmx;
CPUVEC_SETUP_bt1;
break;
case 0x15: /* bulldozer */
TRACE (printf (" bulldozer\n"));
CPUVEC_SETUP_k7;
CPUVEC_SETUP_k7_mmx;
CPUVEC_SETUP_bd1;
break;
case 0x17: /* zen */
case 0x19: /* zen3 */
TRACE (printf (" zen\n"));
CPUVEC_SETUP_k7;
CPUVEC_SETUP_k7_mmx;
break;
}
}
else if (strcmp (vendor_string, "CentaurHauls") == 0)
{
switch (family)
{
case 6:
TRACE (printf (" viac3\n"));
if (model >= 9)
{
TRACE (printf (" viac32\n"));
}
if (model >= 15)
{
TRACE (printf (" nano\n"));
CPUVEC_SETUP_nano;
}
break;
}
}
else if (strcmp (vendor_string, "CyrixInstead") == 0)
{
/* Should recognize Cyrix' processors too. */
TRACE (printf (" cyrix something\n"));
}
}
/* There's no x86 generic mpn_preinv_divrem_1 or mpn_preinv_mod_1.
Instead default to the plain versions from whichever CPU we detected.
The function arguments are compatible, no need for any glue code. */
if (decided_cpuvec.preinv_divrem_1 == NULL)
decided_cpuvec.preinv_divrem_1 =(preinv_divrem_1_t)decided_cpuvec.divrem_1;
if (decided_cpuvec.preinv_mod_1 == NULL)
decided_cpuvec.preinv_mod_1 =(preinv_mod_1_t) decided_cpuvec.mod_1;
ASSERT_CPUVEC (decided_cpuvec);
CPUVEC_INSTALL (decided_cpuvec);
/* Set this once the threshold fields are ready.
Use volatile to prevent it getting moved. */
*((volatile int *) &__gmpn_cpuvec_initialized) = 1;
}

View File

@@ -0,0 +1,243 @@
dnl x86 fat binary entrypoints.
dnl Copyright 2003, 2012, 2014 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
dnl Forcibly disable profiling.
dnl
dnl The entrypoints and inits are small enough not to worry about, the real
dnl routines arrived at will have any profiling. Also, the way the code
dnl here ends with a jump means we won't work properly with the
dnl "instrument" profiling scheme anyway.
define(`WANT_PROFILING',no)
TEXT
dnl Usage: FAT_ENTRY(name, offset)
dnl
dnl Emit a fat binary entrypoint function of the given name. This is the
dnl normal entry for applications, eg. __gmpn_add_n.
dnl
dnl The code simply jumps through the function pointer in __gmpn_cpuvec at
dnl the given "offset" (in bytes).
dnl
dnl For non-PIC, the jumps are 5 bytes each, aligning them to 8 should be
dnl fine for all x86s.
dnl
dnl For PIC, the jumps are 20 bytes each, and are best aligned to 16 to
dnl ensure at least the first two instructions don't cross a cache line
dnl boundary.
dnl
dnl Note the extra `' ahead of PROLOGUE obscures it from the HAVE_NATIVE
dnl grepping in configure, stopping that code trying to eval something with
dnl $1 in it.
define(FAT_ENTRY,
m4_assert_numargs(2)
` ALIGN(ifdef(`PIC',16,8))
`'PROLOGUE($1)dnl
ifdef(`PIC',`dnl
ifdef(`DARWIN',`
call L(movl_eip_edx)
movl L(___gmpn_cpuvec)$non_lazy_ptr-.(%edx), %edx
jmp *m4_empty_if_zero($2)(%edx)
',`dnl
call L(movl_eip_edx)
L(entry_here$2):
addl $_GLOBAL_OFFSET_TABLE_+[.-L(entry_here$2)], %edx
movl GSYM_PREFIX`'__gmpn_cpuvec@GOT(%edx), %edx
jmp *m4_empty_if_zero($2)(%edx)
')
',`dnl non-PIC
jmp *GSYM_PREFIX`'__gmpn_cpuvec+$2
')
EPILOGUE()
')
dnl FAT_ENTRY for each CPUVEC_FUNCS_LIST
dnl
define(`CPUVEC_offset',0)
foreach(i,
`FAT_ENTRY(MPN(i),CPUVEC_offset)
define(`CPUVEC_offset',eval(CPUVEC_offset + 4))',
CPUVEC_FUNCS_LIST)
ifdef(`PIC',`
ALIGN(8)
L(movl_eip_edx):
movl (%esp), %edx
ret_internal
ifdef(`DARWIN',`
.section __IMPORT,__pointers,non_lazy_symbol_pointers
L(___gmpn_cpuvec)$non_lazy_ptr:
.indirect_symbol ___gmpn_cpuvec
.long 0
TEXT
')
')
dnl Usage: FAT_INIT(name, offset)
dnl
dnl Emit a fat binary initializer function of the given name. These
dnl functions are the initial values for the pointers in __gmpn_cpuvec.
dnl
dnl The code simply calls __gmpn_cpuvec_init, and then jumps back through
dnl the __gmpn_cpuvec pointer, at the given "offset" (in bytes).
dnl __gmpn_cpuvec_init will have stored the address of the selected
dnl implementation there.
dnl
dnl Only one of these routines will be executed, and only once, since after
dnl that all the __gmpn_cpuvec pointers go to real routines. So there's no
dnl need for anything special here, just something small and simple. To
dnl keep code size down, "fat_init" is a shared bit of code, arrived at
dnl with the offset in %al. %al is used since the movb instruction is 2
dnl bytes where %eax would be 4.
dnl
dnl Note having `PROLOGUE in FAT_INIT obscures that PROLOGUE from the
dnl HAVE_NATIVE grepping in configure, preventing that code trying to eval
dnl something with $1 in it.
define(FAT_INIT,
m4_assert_numargs(2)
`PROLOGUE($1)dnl
movb $`'$2, %al
jmp L(fat_init)
EPILOGUE()
')
L(fat_init):
C al __gmpn_cpuvec byte offset
movzbl %al, %eax
pushl %eax
ifdef(`PIC',`dnl
ifdef(`DARWIN',`
sub $8, %esp
CALL( __gmpn_cpuvec_init)
add $8, %esp
call L(movl_eip_edx)
movl L(___gmpn_cpuvec)$non_lazy_ptr-.(%edx), %edx
',`dnl
pushl %ebx
call L(movl_eip_ebx)
L(init_here):
addl $_GLOBAL_OFFSET_TABLE_+[.-L(init_here)], %ebx
CALL( __gmpn_cpuvec_init)
movl GSYM_PREFIX`'__gmpn_cpuvec@GOT(%ebx), %edx
popl %ebx
')
popl %eax
jmp *(%edx,%eax)
L(movl_eip_ebx):
movl (%esp), %ebx
ret_internal
',`dnl non-PIC
sub $8, %esp C needed on Darwin, harmless elsewhere
CALL( __gmpn_cpuvec_init)
add $8, %esp C needed on Darwin, harmless elsewhere
popl %eax
jmp *GSYM_PREFIX`'__gmpn_cpuvec(%eax)
')
dnl FAT_INIT for each CPUVEC_FUNCS_LIST
dnl
define(`CPUVEC_offset',0)
foreach(i,
`FAT_INIT(MPN(i`'_init),CPUVEC_offset)
define(`CPUVEC_offset',eval(CPUVEC_offset + 4))',
CPUVEC_FUNCS_LIST)
C long __gmpn_cpuid (char dst[12], int id);
C
C This is called only once, so just something simple and compact is fine.
defframe(PARAM_ID, 8)
defframe(PARAM_DST, 4)
deflit(`FRAME',0)
PROLOGUE(__gmpn_cpuid)
pushl %esi FRAME_pushl()
pushl %ebx FRAME_pushl()
movl PARAM_ID, %eax
cpuid
movl PARAM_DST, %esi
movl %ebx, (%esi)
movl %edx, 4(%esi)
movl %ecx, 8(%esi)
popl %ebx
popl %esi
ret
EPILOGUE()
C int __gmpn_cpuid_available (void);
C
C Return non-zero if the cpuid instruction is available, which means late
C model 80486 and higher. 80386 and early 80486 don't have cpuid.
C
C The test follows Intel AP-485 application note, namely that if bit 21 is
C modifiable then cpuid is supported. This test is reentrant and thread
C safe, since of course any interrupt or context switch will preserve the
C flags while we're tinkering with them.
C
C This is called only once, so just something simple and compact is fine.
PROLOGUE(__gmpn_cpuid_available)
pushf
popl %ecx C old flags
movl %ecx, %edx
xorl $0x200000, %edx
pushl %edx
popf
pushf
popl %edx C tweaked flags
movl $1, %eax
cmpl %ecx, %edx
jne L(available)
xorl %eax, %eax C not changed, so cpuid not available
L(available):
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,71 @@
/* Fat binary x86 gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 1991, 1993, 1994, 2000-2003, 2011 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* mpn_divexact_1 is faster than mpn_divrem_1 at all sizes. The only time
this might not be true currently is for actual 80386 and 80486 chips,
where mpn/x86/dive_1.asm might be slower than mpn/x86/divrem_1.asm, but
that's not worth worrying about. */
#define DIVEXACT_1_THRESHOLD 0
/* Only some of the x86s have an mpn_preinv_divrem_1, but we set
USE_PREINV_DIVREM_1 so that all callers use it, and then let the
__gmpn_cpuvec pointer go to plain mpn_divrem_1 if there's not an actual
preinv. */
#define USE_PREINV_DIVREM_1 1
#define BMOD_1_TO_MOD_1_THRESHOLD 20
/* mpn_sqr_basecase is faster than mpn_mul_basecase at all sizes, no need
for mpn_sqr to call the latter. */
#define SQR_BASECASE_THRESHOLD 0
/* Sensible fallbacks for these, when not taken from a cpu-specific
gmp-mparam.h. */
#define MUL_TOOM22_THRESHOLD 20
#define MUL_TOOM33_THRESHOLD 130
#define SQR_TOOM2_THRESHOLD 30
#define SQR_TOOM3_THRESHOLD 200
/* These are values more or less in the middle of what the typical x86 chips
come out as. For a fat binary it's necessary to have values for these,
since the defaults for MUL_FFT_TABLE and SQR_FFT_TABLE otherwise come out
as non-constant array initializers. FIXME: Perhaps these should be done
in the cpuvec structure like other thresholds. */
#define MUL_FFT_TABLE { 464, 928, 1920, 3584, 10240, 40960, 0 }
#define MUL_FFT_MODF_THRESHOLD 400
#define MUL_FFT_THRESHOLD 2000
#define SQR_FFT_TABLE { 528, 1184, 1920, 4608, 14336, 40960, 0 }
#define SQR_FFT_MODF_THRESHOLD 500
#define SQR_FFT_THRESHOLD 3000

View File

@@ -0,0 +1,32 @@
/* Fat binary fallback mpn_lshiftc.
Copyright 2003, 2009, 2011 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#include "mpn/generic/lshiftc.c"

View File

@@ -0,0 +1,32 @@
/* Fat binary fallback mpn_mod_1.
Copyright 2003, 2009 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#include "mpn/generic/mod_1.c"

View File

@@ -0,0 +1,36 @@
/* Fat binary fallback mpn_mod_1_1p.
Copyright 2003, 2009, 2011 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
/*
PROLOGUE(mpn_mod_1_1p_cps)
*/
#define OPERATION_mod_1_1_cps 1
#include "mpn/generic/mod_1_1.c"

View File

@@ -0,0 +1,36 @@
/* Fat binary fallback mpn_mod_1s_2p.
Copyright 2003, 2009, 2011 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
/*
PROLOGUE(mpn_mod_1s_2p_cps)
*/
#define OPERATION_mod_1_2_cps 1
#include "mpn/generic/mod_1_2.c"

View File

@@ -0,0 +1,36 @@
/* Fat binary fallback mpn_mod_1s_4p.
Copyright 2003, 2009, 2011 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
/*
PROLOGUE(mpn_mod_1s_4p_cps)
*/
#define OPERATION_mod_1_4_cps 1
#include "mpn/generic/mod_1_4.c"

View File

@@ -0,0 +1,32 @@
/* Fat binary fallback mpn_modexact_1c_odd.
Copyright 2003 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#include "mpn/generic/mode1o.c"

View File

@@ -0,0 +1,32 @@
/* Fat binary fallback mpn_mullo_basecase.
Copyright 2012 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#include "mpn/generic/mullo_basecase.c"

View File

@@ -0,0 +1,32 @@
/* Fat binary fallback mpn_redc_1.
Copyright 2012 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#include "mpn/generic/redc_1.c"

View File

@@ -0,0 +1,32 @@
/* Fat binary fallback mpn_redc_2.
Copyright 2012 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#include "mpn/generic/redc_2.c"

View File

@@ -0,0 +1,126 @@
dnl x86 mpn_gcd_11 optimised for processors with slow BSF.
dnl Based on C version.
dnl Copyright 2019 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
dnl Rudimentary code for x86-32, i.e. for CPUs without cmov. Also, the bsf
dnl instruction is assumed to be so slow it is useless. Instead a teble is
dnl used.
dnl
dnl The loop benefits from OoO, in-order CPUs might want a different loop.
dnl The ebx and ecx registers could be combined if the assigment of ecx were
dnl postponed until ebx died, but that would at least hurt in-order CPUs.
C cycles/bit (approx)
C AMD K7 ?
C AMD K8,K9 ?
C AMD K10 ?
C AMD bd1 ?
C AMD bd2 ?
C AMD bd3 ?
C AMD bd4 ?
C AMD bt1 ?
C AMD bt2 ?
C AMD zn1 ?
C AMD zn2 ?
C Intel P4-2 ?
C Intel P4-3/4 ?
C Intel P6/13 ?
C Intel CNR ?
C Intel NHM ?
C Intel SBR ?
C Intel IBR ?
C Intel HWL ?
C Intel BWL ?
C Intel SKL ?
C Intel atom ?
C Intel SLM ?
C Intel GLM ?
C Intel GLM+ ?
C VIA nano ?
C Numbers measured with: speed -CD -s8-32 -t24 mpn_gcd_1
deflit(MAXSHIFT, 6)
deflit(MASK, eval((m4_lshift(1,MAXSHIFT))-1))
DEF_OBJECT(ctz_table,64)
.byte MAXSHIFT
forloop(i,1,MASK,
` .byte m4_count_trailing_zeros(i)
')
END_OBJECT(ctz_table)
define(`u0', `%eax')
define(`v0', `%edx')
ASM_START()
TEXT
ALIGN(16)
PROLOGUE(mpn_gcd_11)
push %edi
push %esi
push %ebx
mov 16(%esp), u0
mov 20(%esp), v0
LEAL( ctz_table, %esi)
sub v0, u0 C u = u - v 0
jz L(end)
ALIGN(16)
L(top): sbb %ebx, %ebx C mask 1
mov u0, %edi C 1
mov u0, %ecx C 1
and %ebx, %edi C 2
xor %ebx, u0 C 2
add %edi, v0 C v = min(u.v) 3
sub %ebx, u0 C u = |u - v| 3
L(mid): and $MASK, %ecx C 2
movzbl (%esi,%ecx), %ecx C 3
jz L(shift_alot)
shr %cl, u0 C 4
sub v0, u0 C u = u - v 0,5
jnz L(top)
L(end): mov v0, %eax
pop %ebx
pop %esi
pop %edi
ret
L(shift_alot):
shr $MAXSHIFT, u0
mov u0, %ecx
jmp L(mid)
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,141 @@
/* Generic x86 gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 1991, 1993, 1994, 2000-2002, 2011 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* Generated by tuneup.c, 2011-01-30, gcc 3.4 */
#define MOD_1_NORM_THRESHOLD 6
#define MOD_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define MOD_1N_TO_MOD_1_1_THRESHOLD 17
#define MOD_1U_TO_MOD_1_1_THRESHOLD 9
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 14
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
#define USE_PREINV_DIVREM_1 0
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD 42
#define MUL_TOOM22_THRESHOLD 18
#define MUL_TOOM33_THRESHOLD 66
#define MUL_TOOM44_THRESHOLD 105
#define MUL_TOOM6H_THRESHOLD 141
#define MUL_TOOM8H_THRESHOLD 212
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 62
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 69
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 65
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 67
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 33
#define SQR_TOOM3_THRESHOLD 60
#define SQR_TOOM4_THRESHOLD 136
#define SQR_TOOM6_THRESHOLD 196
#define SQR_TOOM8_THRESHOLD 292
#define MULMOD_BNM1_THRESHOLD 14
#define SQRMOD_BNM1_THRESHOLD 16
#define MUL_FFT_MODF_THRESHOLD 468 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 468, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
{ 11, 5}, { 23, 6}, { 21, 7}, { 11, 6}, \
{ 25, 7}, { 13, 6}, { 27, 7}, { 15, 6}, \
{ 31, 7}, { 21, 8}, { 11, 7}, { 27, 8}, \
{ 15, 7}, { 33, 8}, { 19, 7}, { 39, 8}, \
{ 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
{ 39, 9}, { 23, 8}, { 47,10}, { 15, 9}, \
{ 31, 8}, { 67, 9}, { 39, 8}, { 79, 9}, \
{ 47, 8}, { 95, 9}, { 55,10}, { 31, 9}, \
{ 63, 8}, { 127, 9}, { 79,10}, { 47, 9}, \
{ 95,11}, { 31,10}, { 63, 9}, { 135,10}, \
{ 79, 9}, { 159,10}, { 95, 9}, { 191,11}, \
{ 63,10}, { 127, 9}, { 255,10}, { 143, 9}, \
{ 287,10}, { 159,11}, { 95,10}, { 191, 9}, \
{ 383,12}, { 4096,13}, { 8192,14}, { 16384,15}, \
{ 32768,16} }
#define MUL_FFT_TABLE3_SIZE 61
#define MUL_FFT_THRESHOLD 5504
#define SQR_FFT_MODF_THRESHOLD 396 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 396, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
{ 21, 7}, { 11, 6}, { 24, 7}, { 13, 6}, \
{ 27, 7}, { 15, 6}, { 31, 7}, { 21, 8}, \
{ 11, 7}, { 27, 8}, { 15, 7}, { 33, 8}, \
{ 19, 7}, { 39, 8}, { 23, 7}, { 47, 8}, \
{ 27, 9}, { 15, 8}, { 39, 9}, { 23, 8}, \
{ 51,10}, { 15, 9}, { 31, 8}, { 67, 9}, \
{ 39, 8}, { 79, 9}, { 47, 8}, { 95, 9}, \
{ 55,10}, { 31, 9}, { 79,10}, { 47, 9}, \
{ 95,11}, { 31,10}, { 63, 9}, { 127, 8}, \
{ 255, 9}, { 135,10}, { 79, 9}, { 159, 8}, \
{ 319,10}, { 95, 9}, { 191,11}, { 63,10}, \
{ 127, 9}, { 255, 8}, { 511,10}, { 143, 9}, \
{ 287, 8}, { 575,10}, { 159,11}, { 95,10}, \
{ 191,12}, { 4096,13}, { 8192,14}, { 16384,15}, \
{ 32768,16} }
#define SQR_FFT_TABLE3_SIZE 61
#define SQR_FFT_THRESHOLD 3712
#define MULLO_BASECASE_THRESHOLD 3
#define MULLO_DC_THRESHOLD 37
#define MULLO_MUL_N_THRESHOLD 10950
#define DC_DIV_QR_THRESHOLD 59
#define DC_DIVAPPR_Q_THRESHOLD 189
#define DC_BDIV_QR_THRESHOLD 55
#define DC_BDIV_Q_THRESHOLD 136
#define INV_MULMOD_BNM1_THRESHOLD 50
#define INV_NEWTON_THRESHOLD 183
#define INV_APPR_THRESHOLD 181
#define BINV_NEWTON_THRESHOLD 204
#define REDC_1_TO_REDC_N_THRESHOLD 54
#define MU_DIV_QR_THRESHOLD 1142
#define MU_DIVAPPR_Q_THRESHOLD 1142
#define MUPI_DIV_QR_THRESHOLD 81
#define MU_BDIV_QR_THRESHOLD 889
#define MU_BDIV_Q_THRESHOLD 998
#define MATRIX22_STRASSEN_THRESHOLD 13
#define HGCD_THRESHOLD 133
#define GCD_DC_THRESHOLD 451
#define GCDEXT_DC_THRESHOLD 318
#define JACOBI_BASE_METHOD 1
#define GET_STR_DC_THRESHOLD 15
#define GET_STR_PRECOMPUTE_THRESHOLD 30
#define SET_STR_DC_THRESHOLD 547
#define SET_STR_PRECOMPUTE_THRESHOLD 1049

View File

@@ -0,0 +1,38 @@
/* Generic x86 gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 1991, 1993, 1994, 2000-2002 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* Generic x86 mpn_divexact_1 is faster than generic x86 mpn_divrem_1 on all
of p5, p6, k6 and k7, so use it always. It's probably slower on 386 and
486, but that's too bad. */
#define DIVEXACT_1_THRESHOLD 0

View File

@@ -0,0 +1,219 @@
/* Intel Goldmont/32 gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 2019 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* 2200 MHz Intel Atom C3758 Goldmont/Denverton */
/* FFT tuning limit = 67,000,000 */
/* Generated by tuneup.c, 2019-10-22, gcc 8.3 */
#define MOD_1_NORM_THRESHOLD 7
#define MOD_1_UNNORM_THRESHOLD 12
#define MOD_1N_TO_MOD_1_1_THRESHOLD 9
#define MOD_1U_TO_MOD_1_1_THRESHOLD 7
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 10
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 12
#define USE_PREINV_DIVREM_1 1 /* native */
#define DIV_QR_1N_PI1_METHOD 1 /* 32.79% faster than 2 */
#define DIV_QR_1_NORM_THRESHOLD 32
#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD 23
#define DIV_1_VS_MUL_1_PERCENT 228
#define MUL_TOOM22_THRESHOLD 18
#define MUL_TOOM33_THRESHOLD 81
#define MUL_TOOM44_THRESHOLD 193
#define MUL_TOOM6H_THRESHOLD 286
#define MUL_TOOM8H_THRESHOLD 399
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 81
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 138
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 125
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 137
#define MUL_TOOM43_TO_TOOM54_THRESHOLD 185
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 32
#define SQR_TOOM3_THRESHOLD 113
#define SQR_TOOM4_THRESHOLD 280
#define SQR_TOOM6_THRESHOLD 399
#define SQR_TOOM8_THRESHOLD 547
#define MULMID_TOOM42_THRESHOLD 60
#define MULMOD_BNM1_THRESHOLD 13
#define SQRMOD_BNM1_THRESHOLD 15
#define MUL_FFT_MODF_THRESHOLD 368 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 368, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
{ 21, 7}, { 11, 6}, { 25, 7}, { 13, 6}, \
{ 27, 7}, { 15, 6}, { 31, 7}, { 21, 8}, \
{ 11, 7}, { 27, 8}, { 15, 7}, { 33, 8}, \
{ 19, 7}, { 39, 8}, { 23, 7}, { 47, 8}, \
{ 27, 9}, { 15, 8}, { 39, 9}, { 23, 8}, \
{ 47,10}, { 15, 9}, { 31, 8}, { 63, 9}, \
{ 39, 8}, { 79, 9}, { 47,10}, { 31, 9}, \
{ 79,10}, { 47, 9}, { 95,11}, { 31,10}, \
{ 63, 9}, { 127, 8}, { 255, 9}, { 135,10}, \
{ 79, 9}, { 159,10}, { 95, 9}, { 191,11}, \
{ 63,10}, { 127, 9}, { 255, 8}, { 511,10}, \
{ 143, 9}, { 287, 8}, { 575, 9}, { 303,10}, \
{ 159,11}, { 95,10}, { 191,12}, { 63,11}, \
{ 127,10}, { 255, 9}, { 511,10}, { 271, 9}, \
{ 543,10}, { 287, 9}, { 575,10}, { 303, 9}, \
{ 607,11}, { 159,10}, { 319, 9}, { 639,10}, \
{ 351, 9}, { 703,11}, { 191,10}, { 383, 9}, \
{ 767,10}, { 415, 9}, { 831,11}, { 223,10}, \
{ 447,12}, { 127,11}, { 255,10}, { 543, 9}, \
{ 1087,11}, { 287,10}, { 607, 9}, { 1215,11}, \
{ 319,10}, { 671,11}, { 351,10}, { 703,12}, \
{ 191,11}, { 383,10}, { 767,11}, { 415,10}, \
{ 831,11}, { 447,13}, { 127,12}, { 255,11}, \
{ 543,10}, { 1087,11}, { 607,10}, { 1215,12}, \
{ 319,11}, { 671,10}, { 1343,11}, { 703,10}, \
{ 1407,11}, { 735,12}, { 383,11}, { 831,12}, \
{ 447,11}, { 959,13}, { 255,12}, { 511,11}, \
{ 1087,12}, { 575,11}, { 1215,10}, { 2431,12}, \
{ 639,11}, { 1343,12}, { 703,11}, { 1407,13}, \
{ 383,12}, { 831,11}, { 1663,12}, { 959,11}, \
{ 1919,14}, { 255,13}, { 511,12}, { 1215,11}, \
{ 2431,13}, { 639,12}, { 1471,11}, { 2943,13}, \
{ 767,12}, { 1727,13}, { 895,12}, { 1919,11}, \
{ 3839,14}, { 511,13}, { 1023,12}, { 2111,13}, \
{ 1151,12}, { 2431,13}, { 1407,12}, { 2943,14}, \
{ 767,13}, { 1663,12}, { 3455,13}, { 1919,12}, \
{ 3839,15}, { 511,14}, { 1023,13}, { 2431,14}, \
{ 1279,13}, { 2943,12}, { 5887,14}, { 1535,13}, \
{ 3455,14}, { 1791,13}, { 3839,12}, { 7679,15}, \
{ 1023,14}, { 2303,13}, { 4991,12}, { 9983,14}, \
{ 2559,13}, { 5119,14}, { 2815,13}, { 5887,15}, \
{ 1535,14}, { 3839,13}, { 7679,16} }
#define MUL_FFT_TABLE3_SIZE 171
#define MUL_FFT_THRESHOLD 3712
#define SQR_FFT_MODF_THRESHOLD 340 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 340, 5}, { 21, 6}, { 11, 5}, { 23, 6}, \
{ 12, 5}, { 25, 6}, { 21, 7}, { 11, 6}, \
{ 25, 7}, { 13, 6}, { 27, 7}, { 15, 6}, \
{ 31, 7}, { 21, 8}, { 11, 7}, { 27, 8}, \
{ 15, 7}, { 33, 8}, { 19, 7}, { 39, 8}, \
{ 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
{ 39, 9}, { 23, 8}, { 47,10}, { 15, 9}, \
{ 31, 8}, { 67, 9}, { 39, 8}, { 79, 9}, \
{ 47,10}, { 31, 9}, { 79,10}, { 47,11}, \
{ 31,10}, { 63, 9}, { 127, 8}, { 255,10}, \
{ 79, 9}, { 159, 8}, { 319,10}, { 95, 9}, \
{ 191,11}, { 63,10}, { 127, 9}, { 255, 8}, \
{ 511, 9}, { 271,10}, { 143, 9}, { 287, 8}, \
{ 575, 9}, { 303, 8}, { 607, 9}, { 319,11}, \
{ 95,10}, { 191,12}, { 63,11}, { 127,10}, \
{ 255, 9}, { 511,10}, { 271, 9}, { 543,10}, \
{ 287, 9}, { 575,10}, { 303, 9}, { 607,11}, \
{ 159,10}, { 319, 9}, { 639,10}, { 335, 9}, \
{ 671,10}, { 351, 9}, { 703,11}, { 191,10}, \
{ 383, 9}, { 767,10}, { 415, 9}, { 831,11}, \
{ 223,10}, { 479,12}, { 127,11}, { 255,10}, \
{ 543, 9}, { 1087,11}, { 287,10}, { 607, 9}, \
{ 1215,11}, { 319,10}, { 671,11}, { 351,10}, \
{ 703,12}, { 191,11}, { 383,10}, { 767,11}, \
{ 415,10}, { 831,11}, { 479,13}, { 127,12}, \
{ 255,11}, { 543,10}, { 1087,11}, { 607,10}, \
{ 1215,12}, { 319,11}, { 671,10}, { 1343,11}, \
{ 735,12}, { 383,11}, { 831,12}, { 447,11}, \
{ 959,13}, { 255,12}, { 511,11}, { 1087,12}, \
{ 575,11}, { 1215,12}, { 639,11}, { 1343,12}, \
{ 703,11}, { 1471,13}, { 383,12}, { 831,11}, \
{ 1663,12}, { 959,11}, { 1919,14}, { 255,13}, \
{ 511,12}, { 1215,13}, { 639,12}, { 1471,11}, \
{ 2943,13}, { 767,12}, { 1727,13}, { 895,12}, \
{ 1919,14}, { 511,13}, { 1023,12}, { 2111,13}, \
{ 1151,12}, { 2431,13}, { 1407,12}, { 2943,14}, \
{ 767,13}, { 1663,12}, { 3455,13}, { 1919,15}, \
{ 511,14}, { 1023,13}, { 2431,14}, { 1279,13}, \
{ 2943,12}, { 5887,14}, { 1535,13}, { 3455,14}, \
{ 1791,13}, { 3839,12}, { 7679,15}, { 1023,14}, \
{ 2047,13}, { 4095,14}, { 2303,13}, { 4991,12}, \
{ 9983,14}, { 2815,13}, { 5887,15}, { 1535,14}, \
{ 3839,13}, { 7679,16} }
#define SQR_FFT_TABLE3_SIZE 170
#define SQR_FFT_THRESHOLD 3520
#define MULLO_BASECASE_THRESHOLD 5
#define MULLO_DC_THRESHOLD 50
#define MULLO_MUL_N_THRESHOLD 6633
#define SQRLO_BASECASE_THRESHOLD 0 /* always */
#define SQRLO_DC_THRESHOLD 95
#define SQRLO_SQR_THRESHOLD 6633
#define DC_DIV_QR_THRESHOLD 68
#define DC_DIVAPPR_Q_THRESHOLD 204
#define DC_BDIV_QR_THRESHOLD 64
#define DC_BDIV_Q_THRESHOLD 108
#define INV_MULMOD_BNM1_THRESHOLD 34
#define INV_NEWTON_THRESHOLD 276
#define INV_APPR_THRESHOLD 226
#define BINV_NEWTON_THRESHOLD 298
#define REDC_1_TO_REDC_N_THRESHOLD 65
#define MU_DIV_QR_THRESHOLD 1528
#define MU_DIVAPPR_Q_THRESHOLD 1589
#define MUPI_DIV_QR_THRESHOLD 140
#define MU_BDIV_QR_THRESHOLD 1334
#define MU_BDIV_Q_THRESHOLD 1499
#define POWM_SEC_TABLE 3,16,96,428,1317
#define GET_STR_DC_THRESHOLD 13
#define GET_STR_PRECOMPUTE_THRESHOLD 18
#define SET_STR_DC_THRESHOLD 704
#define SET_STR_PRECOMPUTE_THRESHOLD 1358
#define FAC_DSC_THRESHOLD 95
#define FAC_ODD_THRESHOLD 29
#define MATRIX22_STRASSEN_THRESHOLD 15
#define HGCD2_DIV1_METHOD 1 /* 5.53% faster than 3 */
#define HGCD_THRESHOLD 172
#define HGCD_APPR_THRESHOLD 204
#define HGCD_REDUCE_THRESHOLD 2479
#define GCD_DC_THRESHOLD 610
#define GCDEXT_DC_THRESHOLD 443
#define JACOBI_BASE_METHOD 4 /* 6.53% faster than 3 */
/* Tuneup completed successfully, took 101563 seconds */

View File

@@ -0,0 +1,69 @@
/* 80486 gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 2001-2003 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* 100MHz DX4 */
/* Generated by tuneup.c, 2003-02-13, gcc 2.95 */
#define MUL_TOOM22_THRESHOLD 18
#define MUL_TOOM33_THRESHOLD 228
#define SQR_BASECASE_THRESHOLD 13
#define SQR_TOOM2_THRESHOLD 49
#define SQR_TOOM3_THRESHOLD 238
#define DIV_SB_PREINV_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_DC_THRESHOLD 72
#define POWM_THRESHOLD 38
#define GCD_ACCEL_THRESHOLD 3
#define JACOBI_BASE_METHOD 2
#define USE_PREINV_DIVREM_1 0
#define USE_PREINV_MOD_1 0
#define DIVREM_2_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define MODEXACT_1_ODD_THRESHOLD 17
#define GET_STR_DC_THRESHOLD 32
#define GET_STR_PRECOMPUTE_THRESHOLD 82
#define SET_STR_THRESHOLD 3524
#define MUL_FFT_TABLE { 464, 928, 1920, 4608, 10240, 40960, 0 }
#define MUL_FFT_MODF_THRESHOLD 392
#define MUL_FFT_THRESHOLD 2816
#define SQR_FFT_TABLE { 432, 928, 1920, 4608, 14336, 40960, 0 }
#define SQR_FFT_MODF_THRESHOLD 392
#define SQR_FFT_THRESHOLD 2816

View File

@@ -0,0 +1,217 @@
/* x86/k10 gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 1991, 1993, 1994, 2000-2011, 2014-2015 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* 3200-3600 MHz K10 Thuban */
/* FFT tuning limit = 67,000,000 */
/* Generated by tuneup.c, 2019-10-19, gcc 8.3 */
#define MOD_1_NORM_THRESHOLD 0 /* always */
#define MOD_1_UNNORM_THRESHOLD 0 /* always */
#define MOD_1N_TO_MOD_1_1_THRESHOLD 14
#define MOD_1U_TO_MOD_1_1_THRESHOLD 7
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 0 /* never mpn_mod_1_1p */
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 18
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 22
#define USE_PREINV_DIVREM_1 1 /* native */
#define DIV_QR_1N_PI1_METHOD 1 /* 29.33% faster than 2 */
#define DIV_QR_1_NORM_THRESHOLD 2
#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD 35
#define DIV_1_VS_MUL_1_PERCENT 258
#define MUL_TOOM22_THRESHOLD 22
#define MUL_TOOM33_THRESHOLD 73
#define MUL_TOOM44_THRESHOLD 124
#define MUL_TOOM6H_THRESHOLD 274
#define MUL_TOOM8H_THRESHOLD 430
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 81
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 99
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 85
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 88
#define MUL_TOOM43_TO_TOOM54_THRESHOLD 113
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 26
#define SQR_TOOM3_THRESHOLD 105
#define SQR_TOOM4_THRESHOLD 154
#define SQR_TOOM6_THRESHOLD 238
#define SQR_TOOM8_THRESHOLD 309
#define MULMID_TOOM42_THRESHOLD 50
#define MULMOD_BNM1_THRESHOLD 15
#define SQRMOD_BNM1_THRESHOLD 18
#define MUL_FFT_MODF_THRESHOLD 570 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 570, 5}, { 21, 6}, { 11, 5}, { 25, 6}, \
{ 13, 5}, { 27, 6}, { 15, 5}, { 31, 6}, \
{ 25, 7}, { 13, 6}, { 27, 7}, { 15, 6}, \
{ 32, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
{ 39, 7}, { 27, 8}, { 15, 7}, { 35, 8}, \
{ 19, 7}, { 41, 8}, { 23, 7}, { 47, 8}, \
{ 27, 9}, { 15, 8}, { 31, 7}, { 63, 8}, \
{ 39, 9}, { 23, 8}, { 55, 9}, { 31, 8}, \
{ 67, 9}, { 39, 8}, { 79, 9}, { 47, 8}, \
{ 95, 9}, { 55,10}, { 31, 9}, { 79,10}, \
{ 47, 9}, { 95,11}, { 31,10}, { 63, 9}, \
{ 135,10}, { 79, 9}, { 159,10}, { 95, 9}, \
{ 191,11}, { 63,10}, { 143, 9}, { 287,10}, \
{ 159,11}, { 95,10}, { 191,12}, { 63,11}, \
{ 127,10}, { 255, 9}, { 511,10}, { 271, 9}, \
{ 543,10}, { 287,11}, { 159,10}, { 319, 9}, \
{ 639,10}, { 335, 9}, { 671,11}, { 191,10}, \
{ 383, 9}, { 767,10}, { 399, 9}, { 799,11}, \
{ 223,12}, { 127,11}, { 255,10}, { 543,11}, \
{ 287,10}, { 607, 9}, { 1215,11}, { 319,10}, \
{ 671,12}, { 191,11}, { 383,10}, { 799,11}, \
{ 415,13}, { 127,12}, { 255,11}, { 543,10}, \
{ 1087,11}, { 607,10}, { 1215,12}, { 319,11}, \
{ 671,10}, { 1343,11}, { 735,10}, { 1471, 9}, \
{ 2943,12}, { 383,11}, { 799,10}, { 1599,11}, \
{ 863,12}, { 447,11}, { 959,13}, { 255,12}, \
{ 511,11}, { 1087,12}, { 575,11}, { 1215,10}, \
{ 2431,12}, { 639,11}, { 1343,12}, { 703,11}, \
{ 1471,10}, { 2943,13}, { 383,12}, { 767,11}, \
{ 1599,12}, { 831,11}, { 1727,10}, { 3455,12}, \
{ 959,11}, { 1919,14}, { 255,13}, { 511,12}, \
{ 1087,11}, { 2239,12}, { 1215,11}, { 2431,13}, \
{ 639,12}, { 1471,11}, { 2943,13}, { 767,12}, \
{ 1727,11}, { 3455,13}, { 895,12}, { 1983,14}, \
{ 511,13}, { 1023,12}, { 2239,13}, { 1151,12}, \
{ 2431,13}, { 1407,12}, { 2943,14}, { 767,13}, \
{ 1663,12}, { 3455,13}, { 1919,15}, { 511,14}, \
{ 1023,13}, { 2175,12}, { 4479,13}, { 2431,14}, \
{ 1279,13}, { 2943,12}, { 5887,14}, { 1535,13}, \
{ 3455,14}, { 1791,13}, { 3967,15}, { 1023,14}, \
{ 2047,13}, { 4479,14}, { 2303,13}, { 4991,14}, \
{ 2815,13}, { 5887,15}, { 1535,14}, { 3839,16} }
#define MUL_FFT_TABLE3_SIZE 168
#define MUL_FFT_THRESHOLD 7424
#define SQR_FFT_MODF_THRESHOLD 525 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 525, 5}, { 25, 6}, { 13, 5}, { 28, 6}, \
{ 25, 7}, { 13, 6}, { 27, 7}, { 15, 6}, \
{ 31, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
{ 39, 7}, { 27, 8}, { 15, 7}, { 35, 8}, \
{ 19, 7}, { 41, 8}, { 23, 7}, { 47, 8}, \
{ 27, 9}, { 15, 8}, { 31, 7}, { 63, 8}, \
{ 39, 9}, { 23, 8}, { 51, 9}, { 31, 8}, \
{ 67, 9}, { 39, 8}, { 79, 9}, { 55,10}, \
{ 31, 9}, { 79,10}, { 47, 9}, { 95,11}, \
{ 31,10}, { 63, 9}, { 127,10}, { 79, 9}, \
{ 159,10}, { 95,11}, { 63,10}, { 143, 9}, \
{ 287,10}, { 159,11}, { 95,10}, { 191,12}, \
{ 63,11}, { 127,10}, { 255, 9}, { 511,10}, \
{ 271, 9}, { 543,10}, { 287,11}, { 159,10}, \
{ 319, 9}, { 639,10}, { 335, 9}, { 671,10}, \
{ 351,11}, { 191,10}, { 383, 9}, { 767,10}, \
{ 399, 9}, { 799,10}, { 415,12}, { 127,11}, \
{ 255,10}, { 543,11}, { 287,10}, { 607,11}, \
{ 319,10}, { 671, 9}, { 1343,11}, { 351,10}, \
{ 703,12}, { 191,11}, { 383,10}, { 799, 9}, \
{ 1599,11}, { 415,10}, { 831,13}, { 127,12}, \
{ 255,11}, { 543,10}, { 1087,11}, { 607,12}, \
{ 319,11}, { 671,10}, { 1343,11}, { 735,10}, \
{ 1471,12}, { 383,11}, { 799,10}, { 1599,11}, \
{ 863,10}, { 1727,12}, { 447,11}, { 959,10}, \
{ 1919,11}, { 991,12}, { 511,11}, { 1087,12}, \
{ 575,11}, { 1215,10}, { 2431,12}, { 639,11}, \
{ 1343,12}, { 703,11}, { 1471,13}, { 383,12}, \
{ 767,11}, { 1599,12}, { 831,11}, { 1727,10}, \
{ 3455,12}, { 959,11}, { 1919,13}, { 511,12}, \
{ 1087,11}, { 2239,12}, { 1215,11}, { 2431,13}, \
{ 639,12}, { 1471,11}, { 2943,13}, { 767,12}, \
{ 1727,11}, { 3455,13}, { 895,12}, { 1919,14}, \
{ 511,13}, { 1023,12}, { 2239,13}, { 1151,12}, \
{ 2495,13}, { 1279,12}, { 2623,13}, { 1407,12}, \
{ 2943,14}, { 767,13}, { 1663,12}, { 3455,13}, \
{ 1919,15}, { 511,14}, { 1023,13}, { 2175,12}, \
{ 4351,13}, { 2431,14}, { 1279,13}, { 2943,12}, \
{ 5887,14}, { 1535,13}, { 3455,14}, { 1791,13}, \
{ 3967,15}, { 1023,14}, { 2047,13}, { 4351,14}, \
{ 2303,13}, { 4991,14}, { 2815,13}, { 5887,15}, \
{ 1535,14}, { 3839,16} }
#define SQR_FFT_TABLE3_SIZE 166
#define SQR_FFT_THRESHOLD 5312
#define MULLO_BASECASE_THRESHOLD 6
#define MULLO_DC_THRESHOLD 40
#define MULLO_MUL_N_THRESHOLD 14281
#define SQRLO_BASECASE_THRESHOLD 8
#define SQRLO_DC_THRESHOLD 113
#define SQRLO_SQR_THRESHOLD 10323
#define DC_DIV_QR_THRESHOLD 56
#define DC_DIVAPPR_Q_THRESHOLD 248
#define DC_BDIV_QR_THRESHOLD 55
#define DC_BDIV_Q_THRESHOLD 158
#define INV_MULMOD_BNM1_THRESHOLD 42
#define INV_NEWTON_THRESHOLD 254
#define INV_APPR_THRESHOLD 252
#define BINV_NEWTON_THRESHOLD 292
#define REDC_1_TO_REDC_N_THRESHOLD 67
#define MU_DIV_QR_THRESHOLD 1589
#define MU_DIVAPPR_Q_THRESHOLD 1558
#define MUPI_DIV_QR_THRESHOLD 114
#define MU_BDIV_QR_THRESHOLD 1442
#define MU_BDIV_Q_THRESHOLD 1524
#define POWM_SEC_TABLE 1,16,102,416,1378
#define GET_STR_DC_THRESHOLD 13
#define GET_STR_PRECOMPUTE_THRESHOLD 21
#define SET_STR_DC_THRESHOLD 270
#define SET_STR_PRECOMPUTE_THRESHOLD 1105
#define FAC_DSC_THRESHOLD 159
#define FAC_ODD_THRESHOLD 34
#define MATRIX22_STRASSEN_THRESHOLD 17
#define HGCD2_DIV1_METHOD 3 /* 0.70% faster than 4 */
#define HGCD_THRESHOLD 130
#define HGCD_APPR_THRESHOLD 163
#define HGCD_REDUCE_THRESHOLD 3389
#define GCD_DC_THRESHOLD 573
#define GCDEXT_DC_THRESHOLD 393
#define JACOBI_BASE_METHOD 4 /* 9.13% faster than 1 */
/* Tuneup completed successfully, took 52901 seconds */

View File

@@ -0,0 +1,251 @@
Copyright 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/.
AMD K6 MPN SUBROUTINES
This directory contains code optimized for AMD K6 CPUs, meaning K6, K6-2 and
K6-3.
The mmx subdirectory has MMX code suiting plain K6, the k62mmx subdirectory
has MMX code suiting K6-2 and K6-3. All chips in the K6 family have MMX,
the separate directories are just so that ./configure can omit them if the
assembler doesn't support MMX.
STATUS
Times for the loops, with all code and data in L1 cache, are as follows.
cycles/limb
mpn_add_n/sub_n 3.25 normal, 2.75 in-place
mpn_mul_1 6.25
mpn_add/submul_1 7.65-8.4 (varying with data values)
mpn_mul_basecase 9.25 cycles/crossproduct (approx)
mpn_sqr_basecase 4.7 cycles/crossproduct (approx)
or 9.2 cycles/triangleproduct (approx)
mpn_l/rshift 3.0
mpn_divrem_1 20.0
mpn_mod_1 20.0
mpn_divexact_by3 11.0
mpn_copyi 1.0
mpn_copyd 1.0
K6-2 and K6-3 have dual-issue MMX and get the following improvements.
mpn_l/rshift 1.75
Prefetching of sources hasn't yet given any joy. With the 3DNow "prefetch"
instruction, code seems to run slower, and with just "mov" loads it doesn't
seem faster. Results so far are inconsistent. The K6 does a hardware
prefetch of the second cache line in a sector, so the penalty for not
prefetching in software is reduced.
NOTES
All K6 family chips have MMX, but only K6-2 and K6-3 have 3DNow.
Plain K6 executes MMX instructions only in the X pipe, but K6-2 and K6-3 can
execute them in both X and Y (and in both together).
Branch misprediction penalty is 1 to 4 cycles (Optimization Manual
chapter 6 table 12).
Write-allocate L1 data cache means prefetching of destinations is unnecessary.
Store queue is 7 entries of 64 bits each.
Floating point multiplications can be done in parallel with integer
multiplications, but there doesn't seem to be any way to make use of this.
OPTIMIZATIONS
Unrolled loops are used to reduce looping overhead. The unrolling is
configurable up to 32 limbs/loop for most routines, up to 64 for some.
Sometimes computed jumps into the unrolling are used to handle sizes not a
multiple of the unrolling. An attractive feature of this is that times
smoothly increase with operand size, but an indirect jump is about 6 cycles
and the setups about another 6, so it depends on how much the unrolled code
is faster than a simple loop as to whether a computed jump ought to be used.
Position independent code is implemented using a call to get eip for
computed jumps and a ret is always done, rather than an addl $4,%esp or a
popl, so the CPU return address branch prediction stack stays synchronised
with the actual stack in memory. Such a call however still costs 4 to 7
cycles.
Branch prediction, in absence of any history, will guess forward jumps are
not taken and backward jumps are taken. Where possible it's arranged that
the less likely or less important case is under a taken forward jump.
MMX
Putting emms or femms as late as possible in a routine seems to be fastest.
Perhaps an emms or femms stalls until all outstanding MMX instructions have
completed, so putting it later gives them a chance to complete on their own,
in parallel with other operations (like register popping).
The Optimization Manual chapter 5 recommends using a femms on K6-2 and K6-3
at the start of a routine, in case it's been preceded by x87 floating point
operations. This isn't done because in gmp programs it's expected that x87
floating point won't be much used and that chances are an mpn routine won't
have been preceded by any x87 code.
CODING
Instructions in general code are shown paired if they can decode and execute
together, meaning two short decode instructions with the second not
depending on the first, only the first using the shifter, no more than one
load, and no more than one store.
K6 does some out of order execution so the pairings aren't essential, they
just show what slots might be available. When decoding is the limiting
factor things can be scheduled that might not execute until later.
NOTES
Code alignment
- if an opcode/modrm or 0Fh/opcode/modrm crosses a cache line boundary,
short decode is inhibited. The cross.pl script detects this.
- loops and branch targets should be aligned to 16 bytes, or ensure at least
2 instructions before a 32 byte boundary. This makes use of the 16 byte
cache in the BTB.
Addressing modes
- (%esi) degrades decoding from short to vector. 0(%esi) doesn't have this
problem, and can be used as an equivalent, or easier is just to use a
different register, like %ebx.
- K6 and pre-CXT core K6-2 have the following problem. (K6-2 CXT and K6-3
have it fixed, these being cpuid function 1 signatures 0x588 to 0x58F).
If more than 3 bytes are needed to determine instruction length then
decoding degrades from direct to long, or from long to vector. This
happens with forms like "0F opcode mod/rm" with mod/rm=00-xxx-100 since
with mod=00 the sib determines whether there's a displacement.
This affects all MMX and 3DNow instructions, and others with an 0F prefix,
like movzbl. The modes affected are anything with an index and no
displacement, or an index but no base, and this includes (%esp) which is
really (,%esp,1).
The cross.pl script detects problem cases. The workaround is to always
use a displacement, and to do this with Zdisp if it's zero so the
assembler doesn't discard it.
See Optimization Manual rev D page 67 and 3DNow Porting Guide rev B pages
13-14 and 36-37.
Calls
- indirect jumps and calls are not branch predicted, they measure about 6
cycles.
Various
- adcl 2 cycles of decode, maybe 2 cycles executing in the X pipe
- bsf 12-27 cycles
- emms 5 cycles
- femms 3 cycles
- jecxz 2 cycles taken, 13 not taken (optimization manual says 7 not taken)
- divl 20 cycles back-to-back
- imull 2 decode, 3 execute
- mull 2 decode, 3 execute (optimization manual decoding sample)
- prefetch 2 cycles
- rcll/rcrl implicit by one bit: 2 cycles
immediate or %cl count: 11 + 2 per bit for dword
13 + 4 per bit for byte
- setCC 2 cycles
- xchgl %eax,reg 1.5 cycles, back-to-back (strange)
reg,reg 2 cycles, back-to-back
REFERENCES
"AMD-K6 Processor Code Optimization Application Note", AMD publication
number 21924, revision D amendment 0, January 2000. This describes K6-2 and
K6-3. Available on-line,
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/21924.pdf
"AMD-K6 MMX Enhanced Processor x86 Code Optimization Application Note", AMD
publication number 21828, revision A amendment 0, August 1997. This is an
older edition of the above document, describing plain K6. Available
on-line,
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/21828.pdf
"3DNow Technology Manual", AMD publication number 21928G/0-March 2000.
This describes the femms and prefetch instructions, but nothing else from
3DNow has been used. Available on-line,
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/21928.pdf
"3DNow Instruction Porting Guide", AMD publication number 22621, revision B,
August 1999. This has some notes on general K6 optimizations as well as
3DNow. Available on-line,
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/22621.pdf
----------------
Local variables:
mode: text
fill-column: 76
End:

View File

@@ -0,0 +1,337 @@
dnl AMD K6 mpn_add/sub_n -- mpn addition or subtraction.
dnl Copyright 1999-2002 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C K6: normal 3.25 cycles/limb, in-place 2.75 cycles/limb.
ifdef(`OPERATION_add_n', `
define(M4_inst, adcl)
define(M4_function_n, mpn_add_n)
define(M4_function_nc, mpn_add_nc)
define(M4_description, add)
',`ifdef(`OPERATION_sub_n', `
define(M4_inst, sbbl)
define(M4_function_n, mpn_sub_n)
define(M4_function_nc, mpn_sub_nc)
define(M4_description, subtract)
',`m4_error(`Need OPERATION_add_n or OPERATION_sub_n
')')')
MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
C mp_limb_t M4_function_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size);
C mp_limb_t M4_function_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size, mp_limb_t carry);
C
C Calculate src1,size M4_description src2,size, and store the result in
C dst,size. The return value is the carry bit from the top of the result
C (1 or 0).
C
C The _nc version accepts 1 or 0 for an initial carry into the low limb of
C the calculation. Note values other than 1 or 0 here will lead to garbage
C results.
C
C Instruction decoding limits a normal dst=src1+src2 operation to 3 c/l, and
C an in-place dst+=src to 2.5 c/l. The unrolled loops have 1 cycle/loop of
C loop control, which with 4 limbs/loop means an extra 0.25 c/l.
define(PARAM_CARRY, `FRAME+20(%esp)')
define(PARAM_SIZE, `FRAME+16(%esp)')
define(PARAM_SRC2, `FRAME+12(%esp)')
define(PARAM_SRC1, `FRAME+8(%esp)')
define(PARAM_DST, `FRAME+4(%esp)')
deflit(`FRAME',0)
dnl minimum 5 because the unrolled code can't handle less
deflit(UNROLL_THRESHOLD, 5)
TEXT
ALIGN(32)
PROLOGUE(M4_function_nc)
movl PARAM_CARRY, %eax
jmp L(start)
EPILOGUE()
PROLOGUE(M4_function_n)
xorl %eax, %eax
L(start):
movl PARAM_SIZE, %ecx
pushl %ebx
FRAME_pushl()
movl PARAM_SRC1, %ebx
pushl %edi
FRAME_pushl()
movl PARAM_SRC2, %edx
cmpl $UNROLL_THRESHOLD, %ecx
movl PARAM_DST, %edi
jae L(unroll)
shrl %eax C initial carry flag
C offset 0x21 here, close enough to aligned
L(simple):
C eax scratch
C ebx src1
C ecx counter
C edx src2
C esi
C edi dst
C ebp
C
C The store to (%edi) could be done with a stosl; it'd be smaller
C code, but there's no speed gain and a cld would have to be added
C (per mpn/x86/README).
movl (%ebx), %eax
leal 4(%ebx), %ebx
M4_inst (%edx), %eax
movl %eax, (%edi)
leal 4(%edi), %edi
leal 4(%edx), %edx
loop L(simple)
movl $0, %eax
popl %edi
setc %al
popl %ebx
ret
C -----------------------------------------------------------------------------
L(unroll):
C eax carry
C ebx src1
C ecx counter
C edx src2
C esi
C edi dst
C ebp
cmpl %edi, %ebx
pushl %esi
je L(inplace)
ifdef(`OPERATION_add_n',`
cmpl %edi, %edx
je L(inplace_reverse)
')
movl %ecx, %esi
andl $-4, %ecx
andl $3, %esi
leal (%ebx,%ecx,4), %ebx
leal (%edx,%ecx,4), %edx
leal (%edi,%ecx,4), %edi
negl %ecx
shrl %eax
ALIGN(32)
L(normal_top):
C eax counter, qwords, negative
C ebx src1
C ecx scratch
C edx src2
C esi
C edi dst
C ebp
movl (%ebx,%ecx,4), %eax
leal 5(%ecx), %ecx
M4_inst -20(%edx,%ecx,4), %eax
movl %eax, -20(%edi,%ecx,4)
movl 4-20(%ebx,%ecx,4), %eax
M4_inst 4-20(%edx,%ecx,4), %eax
movl %eax, 4-20(%edi,%ecx,4)
movl 8-20(%ebx,%ecx,4), %eax
M4_inst 8-20(%edx,%ecx,4), %eax
movl %eax, 8-20(%edi,%ecx,4)
movl 12-20(%ebx,%ecx,4), %eax
M4_inst 12-20(%edx,%ecx,4), %eax
movl %eax, 12-20(%edi,%ecx,4)
loop L(normal_top)
decl %esi
jz L(normal_finish_one)
js L(normal_done)
C two or three more limbs
movl (%ebx), %eax
M4_inst (%edx), %eax
movl %eax, (%edi)
movl 4(%ebx), %eax
M4_inst 4(%edx), %eax
decl %esi
movl %eax, 4(%edi)
jz L(normal_done)
movl $2, %ecx
L(normal_finish_one):
movl (%ebx,%ecx,4), %eax
M4_inst (%edx,%ecx,4), %eax
movl %eax, (%edi,%ecx,4)
L(normal_done):
popl %esi
popl %edi
movl $0, %eax
popl %ebx
setc %al
ret
C -----------------------------------------------------------------------------
ifdef(`OPERATION_add_n',`
L(inplace_reverse):
C dst==src2
movl %ebx, %edx
')
L(inplace):
C eax initial carry
C ebx
C ecx size
C edx src
C esi
C edi dst
C ebp
leal -1(%ecx), %esi
decl %ecx
andl $-4, %ecx
andl $3, %esi
movl (%edx), %ebx C src low limb
leal (%edx,%ecx,4), %edx
leal (%edi,%ecx,4), %edi
negl %ecx
shrl %eax
ALIGN(32)
L(inplace_top):
C eax
C ebx next src limb
C ecx size
C edx src
C esi
C edi dst
C ebp
M4_inst %ebx, (%edi,%ecx,4)
movl 4(%edx,%ecx,4), %eax
leal 5(%ecx), %ecx
M4_inst %eax, 4-20(%edi,%ecx,4)
movl 8-20(%edx,%ecx,4), %eax
movl 12-20(%edx,%ecx,4), %ebx
M4_inst %eax, 8-20(%edi,%ecx,4)
M4_inst %ebx, 12-20(%edi,%ecx,4)
movl 16-20(%edx,%ecx,4), %ebx
loop L(inplace_top)
C now %esi is 0 to 3 representing respectively 1 to 4 limbs more
M4_inst %ebx, (%edi)
decl %esi
jz L(inplace_finish_one)
js L(inplace_done)
C two or three more limbs
movl 4(%edx), %eax
movl 8(%edx), %ebx
M4_inst %eax, 4(%edi)
M4_inst %ebx, 8(%edi)
decl %esi
movl $2, %ecx
jz L(normal_done)
L(inplace_finish_one):
movl 4(%edx,%ecx,4), %eax
M4_inst %eax, 4(%edi,%ecx,4)
L(inplace_done):
popl %esi
popl %edi
movl $0, %eax
popl %ebx
setc %al
ret
EPILOGUE()

View File

@@ -0,0 +1,391 @@
dnl AMD K6 mpn_addmul_1/mpn_submul_1 -- add or subtract mpn multiple.
dnl Copyright 1999-2003, 2005 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C P5
C P6 model 0-8,10-12 5.94
C P6 model 9 (Banias) 5.51
C P6 model 13 (Dothan) 5.57
C P4 model 0 (Willamette)
C P4 model 1 (?)
C P4 model 2 (Northwood)
C P4 model 3 (Prescott)
C P4 model 4 (Nocona)
C AMD K6 7.65-8.5 (data dependent)
C AMD K7
C AMD K8
dnl K6: large multipliers small multipliers
dnl UNROLL_COUNT cycles/limb cycles/limb
dnl 4 9.5 7.78
dnl 8 9.0 7.78
dnl 16 8.4 7.65
dnl 32 8.4 8.2
dnl
dnl Maximum possible unrolling with the current code is 32.
dnl
dnl Unrolling to 16 limbs/loop makes the unrolled loop fit exactly in a 256
dnl byte block, which might explain the good speed at that unrolling.
deflit(UNROLL_COUNT, 16)
ifdef(`OPERATION_addmul_1', `
define(M4_inst, addl)
define(M4_function_1, mpn_addmul_1)
define(M4_function_1c, mpn_addmul_1c)
',`ifdef(`OPERATION_submul_1', `
define(M4_inst, subl)
define(M4_function_1, mpn_submul_1)
define(M4_function_1c, mpn_submul_1c)
',`m4_error(`Need OPERATION_addmul_1 or OPERATION_submul_1
')')')
MULFUNC_PROLOGUE(mpn_addmul_1 mpn_addmul_1c mpn_submul_1 mpn_submul_1c)
C mp_limb_t mpn_addmul_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
C mp_limb_t mult);
C mp_limb_t mpn_addmul_1c (mp_ptr dst, mp_srcptr src, mp_size_t size,
C mp_limb_t mult, mp_limb_t carry);
C mp_limb_t mpn_submul_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
C mp_limb_t mult);
C mp_limb_t mpn_submul_1c (mp_ptr dst, mp_srcptr src, mp_size_t size,
C mp_limb_t mult, mp_limb_t carry);
C
C The jadcl0()s in the unrolled loop makes the speed data dependent. Small
C multipliers (most significant few bits clear) result in few carry bits and
C speeds up to 7.65 cycles/limb are attained. Large multipliers (most
C significant few bits set) make the carry bits 50/50 and lead to something
C more like 8.4 c/l. With adcl's both of these would be 9.3 c/l.
C
C It's important that the gains for jadcl0 on small multipliers don't come
C at the cost of slowing down other data. Tests on uniformly distributed
C random data, designed to confound branch prediction, show about a 7%
C speed-up using jadcl0 over adcl (8.93 versus 9.57 cycles/limb, with all
C overheads included).
C
C In the simple loop, jadcl0() measures slower than adcl (11.9-14.7 versus
C 11.0 cycles/limb), and hence isn't used.
C
C In the simple loop, note that running ecx from negative to zero and using
C it as an index in the two movs wouldn't help. It would save one
C instruction (2*addl+loop becoming incl+jnz), but there's nothing unpaired
C that would be collapsed by this.
C
C Attempts at a simpler main loop, with less unrolling, haven't yielded much
C success, generally running over 9 c/l.
C
C
C jadcl0
C ------
C
C jadcl0() being faster than adcl $0 seems to be an artifact of two things,
C firstly the instruction decoding and secondly the fact that there's a
C carry bit for the jadcl0 only on average about 1/4 of the time.
C
C The code in the unrolled loop decodes something like the following.
C
C decode cycles
C mull %ebp 2
C M4_inst %esi, disp(%edi) 1
C adcl %eax, %ecx 2
C movl %edx, %esi \ 1
C jnc 1f /
C incl %esi \ 1
C 1: movl disp(%ebx), %eax /
C ---
C 7
C
C In a back-to-back style test this measures 7 with the jnc not taken, or 8
C with it taken (both when correctly predicted). This is opposite to the
C measurements showing small multipliers running faster than large ones.
C Don't really know why.
C
C It's not clear how much branch misprediction might be costing. The K6
C doco says it will be 1 to 4 cycles, but presumably it's near the low end
C of that range to get the measured results.
C
C
C In the code the two carries are more or less the preceding mul product and
C the calculation is roughly
C
C x*y + u*b+v
C
C where b=2^32 is the size of a limb, x*y is the two carry limbs, and u and
C v are the two limbs it's added to (being the low of the next mul, and a
C limb from the destination).
C
C To get a carry requires x*y+u*b+v >= b^2, which is u*b+v >= b^2-x*y, and
C there are b^2-(b^2-x*y) = x*y many such values, giving a probability of
C x*y/b^2. If x, y, u and v are random and uniformly distributed between 0
C and b-1, then the total probability can be summed over x and y,
C
C 1 b-1 b-1 x*y 1 b*(b-1) b*(b-1)
C --- * sum sum --- = --- * ------- * ------- = 1/4
C b^2 x=0 y=1 b^2 b^4 2 2
C
C Actually it's a very tiny bit less than 1/4 of course. If y is fixed,
C then the probability is 1/2*y/b thus varying linearly between 0 and 1/2.
ifdef(`PIC',`
deflit(UNROLL_THRESHOLD, 9)
',`
deflit(UNROLL_THRESHOLD, 6)
')
defframe(PARAM_CARRY, 20)
defframe(PARAM_MULTIPLIER,16)
defframe(PARAM_SIZE, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
TEXT
ALIGN(32)
PROLOGUE(M4_function_1c)
pushl %esi
deflit(`FRAME',4)
movl PARAM_CARRY, %esi
jmp L(start_nc)
EPILOGUE()
PROLOGUE(M4_function_1)
push %esi
deflit(`FRAME',4)
xorl %esi, %esi C initial carry
L(start_nc):
movl PARAM_SIZE, %ecx
pushl %ebx
deflit(`FRAME',8)
movl PARAM_SRC, %ebx
pushl %edi
deflit(`FRAME',12)
cmpl $UNROLL_THRESHOLD, %ecx
movl PARAM_DST, %edi
pushl %ebp
deflit(`FRAME',16)
jae L(unroll)
C simple loop
movl PARAM_MULTIPLIER, %ebp
L(simple):
C eax scratch
C ebx src
C ecx counter
C edx scratch
C esi carry
C edi dst
C ebp multiplier
movl (%ebx), %eax
addl $4, %ebx
mull %ebp
addl $4, %edi
addl %esi, %eax
adcl $0, %edx
M4_inst %eax, -4(%edi)
adcl $0, %edx
movl %edx, %esi
loop L(simple)
popl %ebp
popl %edi
popl %ebx
movl %esi, %eax
popl %esi
ret
C -----------------------------------------------------------------------------
C The unrolled loop uses a "two carry limbs" scheme. At the top of the loop
C the carries are ecx=lo, esi=hi, then they swap for each limb processed.
C For the computed jump an odd size means they start one way around, an even
C size the other.
C
C VAR_JUMP holds the computed jump temporarily because there's not enough
C registers at the point of doing the mul for the initial two carry limbs.
C
C The add/adc for the initial carry in %esi is necessary only for the
C mpn_addmul/submul_1c entry points. Duplicating the startup code to
C eliminate this for the plain mpn_add/submul_1 doesn't seem like a good
C idea.
dnl overlapping with parameters already fetched
define(VAR_COUNTER, `PARAM_SIZE')
define(VAR_JUMP, `PARAM_DST')
L(unroll):
C eax
C ebx src
C ecx size
C edx
C esi initial carry
C edi dst
C ebp
movl %ecx, %edx
decl %ecx
subl $2, %edx
negl %ecx
shrl $UNROLL_LOG2, %edx
andl $UNROLL_MASK, %ecx
movl %edx, VAR_COUNTER
movl %ecx, %edx
shll $4, %edx
negl %ecx
C 15 code bytes per limb
ifdef(`PIC',`
call L(pic_calc)
L(here):
',`
leal L(entry) (%edx,%ecx,1), %edx
')
movl (%ebx), %eax C src low limb
movl PARAM_MULTIPLIER, %ebp
movl %edx, VAR_JUMP
mull %ebp
addl %esi, %eax C initial carry (from _1c)
jadcl0( %edx)
leal 4(%ebx,%ecx,4), %ebx
movl %edx, %esi C high carry
movl VAR_JUMP, %edx
leal (%edi,%ecx,4), %edi
testl $1, %ecx
movl %eax, %ecx C low carry
jz L(noswap)
movl %esi, %ecx C high,low carry other way around
movl %eax, %esi
L(noswap):
jmp *%edx
ifdef(`PIC',`
L(pic_calc):
C See mpn/x86/README about old gas bugs
leal (%edx,%ecx,1), %edx
addl $L(entry)-L(here), %edx
addl (%esp), %edx
ret_internal
')
C -----------------------------------------------------------
ALIGN(32)
L(top):
deflit(`FRAME',16)
C eax scratch
C ebx src
C ecx carry lo
C edx scratch
C esi carry hi
C edi dst
C ebp multiplier
C
C 15 code bytes per limb
leal UNROLL_BYTES(%edi), %edi
L(entry):
forloop(`i', 0, UNROLL_COUNT/2-1, `
deflit(`disp0', eval(2*i*4))
deflit(`disp1', eval(disp0 + 4))
Zdisp( movl, disp0,(%ebx), %eax)
mull %ebp
Zdisp( M4_inst,%ecx, disp0,(%edi))
adcl %eax, %esi
movl %edx, %ecx
jadcl0( %ecx)
movl disp1(%ebx), %eax
mull %ebp
M4_inst %esi, disp1(%edi)
adcl %eax, %ecx
movl %edx, %esi
jadcl0( %esi)
')
decl VAR_COUNTER
leal UNROLL_BYTES(%ebx), %ebx
jns L(top)
popl %ebp
M4_inst %ecx, UNROLL_BYTES(%edi)
popl %edi
movl %esi, %eax
popl %ebx
jadcl0( %eax)
popl %esi
ret
EPILOGUE()

View File

@@ -0,0 +1,182 @@
#! /usr/bin/perl
# Copyright 2000, 2001 Free Software Foundation, Inc.
#
# This file is part of the GNU MP Library.
#
# The GNU MP Library is free software; you can redistribute it and/or modify
# it under the terms of either:
#
# * the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your
# option) any later version.
#
# or
#
# * the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any
# later version.
#
# or both in parallel, as here.
#
# The GNU MP Library is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received copies of the GNU General Public License and the
# GNU Lesser General Public License along with the GNU MP Library. If not,
# see https://www.gnu.org/licenses/.
# Usage: cross.pl [filename.o]...
#
# Produce an annotated disassembly of the given object files, indicating
# certain code alignment and addressing mode problems afflicting K6 chips.
# "ZZ" is used on all annotations, so this can be searched for.
#
# With no arguments, all .o files corresponding to .asm files are processed.
# This is good in the mpn object directory of a k6*-*-* build.
#
# Code alignments of 8 bytes or more are handled. When 32 is used, cache
# line boundaries will fall in at offsets 0x20,0x40,etc and problems are
# flagged at those locations. When 16 is used, the line boundaries can also
# fall at offsets 0x10,0x30,0x50,etc, depending where the file is loaded, so
# problems are identified there too. Likewise when 8 byte alignment is used
# problems are flagged additionally at 0x08,0x18,0x28,etc.
#
# Usually 32 byte alignment is used for k6 routines, but less is certainly
# possible if through good luck, or a little tweaking, cache line crossing
# problems can be avoided at the extra locations.
#
# Bugs:
#
# Instructions without mod/rm bytes or which are already vector decoded are
# unaffected by cache line boundary crossing, but not all of these have yet
# been put in as exceptions. All that occur in practice in GMP are present
# though.
#
# There's no messages for using the vector decoded addressing mode (%esi),
# but that's easy to avoid when coding.
#
# Future:
#
# Warn about jump targets that are poorly aligned (less than 2 instructions
# before a cache line boundary).
use strict;
sub disassemble {
my ($file) = @_;
my ($addr,$b1,$b2,$b3, $prefix,$opcode,$modrm);
my $align;
open (IN, "objdump -Srfh $file |")
|| die "Cannot open pipe from objdump\n";
while (<IN>) {
print;
if (/^[ \t]*[0-9]+[ \t]+\.text[ \t]/ && /2\*\*([0-9]+)$/) {
$align = 1 << $1;
if ($align < 8) {
print "ZZ cross.pl cannot handle alignment < 2**3\n";
$align = 8
}
}
if (/^[ \t]*([0-9a-f]*):[ \t]*([0-9a-f]+)[ \t]+([0-9a-f]+)[ \t]+([0-9a-f]+)/) {
($addr,$b1,$b2,$b3) = ($1,$2,$3,$4);
} elsif (/^[ \t]*([0-9a-f]*):[ \t]*([0-9a-f]+)[ \t]+([0-9a-f]+)/) {
($addr,$b1,$b2,$b3) = ($1,$2,$3,'');
} elsif (/^[ \t]*([0-9a-f]*):[ \t]*([0-9a-f]+)/) {
($addr,$b1,$b2,$b3) = ($1,$2,'','');
} else {
next;
}
if ($b1 =~ /0f/) {
$prefix = $b1;
$opcode = $b2;
$modrm = $b3;
} else {
$prefix = '';
$opcode = $b1;
$modrm = $b2;
}
# modrm of the form 00-xxx-100 with an 0F prefix is the problem case
# for K6 and pre-CXT K6-2
if ($prefix =~ /0f/
&& $opcode !~ /^8/ # jcond disp32
&& $modrm =~ /^[0-3][4c]/) {
print "ZZ ($file) >3 bytes to determine instruction length [K6]\n";
}
# with just an opcode, starting 1f mod 20h
if (($align==32 && $addr =~ /[13579bdf]f$/
|| $align==16 && $addr =~ /f$/
|| $align==8 && $addr =~ /[7f]$/)
&& $prefix !~ /0f/
&& $opcode !~ /1[012345]/ # adc
&& $opcode !~ /1[89abcd]/ # sbb
&& $opcode !~ /^4/ # inc/dec reg
&& $opcode !~ /^5/ # push/pop reg
&& $opcode !~ /68/ # push $imm32
&& $opcode !~ /^7/ # jcond disp8
&& $opcode !~ /a[89]/ # test+imm
&& $opcode !~ /a[a-f]/ # stos/lods/scas
&& $opcode !~ /b8/ # movl $imm32,%eax
&& $opcode !~ /d[0123]/ # rcl
&& $opcode !~ /e[0123]/ # loop/loopz/loopnz/jcxz
&& $opcode !~ /e8/ # call disp32
&& $opcode !~ /e[9b]/ # jmp disp32/disp8
&& $opcode !~ /f[89abcd]/ # clc,stc,cli,sti,cld,std
&& !($opcode =~ /f[67]/ # grp 1
&& $modrm =~ /^[2367abef]/) # mul, imul, div, idiv
&& $modrm !~ /^$/) {
print "ZZ ($file) opcode/modrm cross 32-byte boundary\n";
}
# with an 0F prefix, anything starting at 1f mod 20h
if (($align==32 && $addr =~ /[13579bdf][f]$/
|| $align==16 && $addr =~ /f$/
|| $align==8 && $addr =~ /[7f]$/)
&& $prefix =~ /0f/
&& $opcode !~ /af/ # imul
&& $opcode !~ /a[45]/ # shldl
&& $opcode !~ /a[cd]/ # shrdl
) {
print "ZZ ($file) prefix/opcode cross 32-byte boundary\n";
}
# with an 0F prefix, anything with mod/rm starting at 1e mod 20h
if (($align==32 && $addr =~ /[13579bdf][e]$/
|| $align==16 && $addr =~ /[e]$/
|| $align==8 && $addr =~ /[6e]$/)
&& $prefix =~ /0f/
&& $opcode !~ /^8/ # jcond disp32
&& $opcode !~ /af/ # imull reg,reg
&& $opcode !~ /a[45]/ # shldl
&& $opcode !~ /a[cd]/ # shrdl
&& $modrm !~ /^$/) {
print "ZZ ($file) prefix/opcode/modrm cross 32-byte boundary\n";
}
}
close IN || die "Error from objdump (or objdump not available)\n";
}
my @files;
if ($#ARGV >= 0) {
@files = @ARGV;
} else {
@files = glob "*.asm";
map {s/.asm/.o/} @files;
}
foreach (@files) {
disassemble($_);
}

View File

@@ -0,0 +1,203 @@
dnl AMD K6 mpn_divrem_1 -- mpn by limb division.
dnl Copyright 1999-2003, 2007 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C K6: 20 cycles/limb
C mp_limb_t mpn_divrem_1 (mp_ptr dst, mp_size_t xsize,
C mp_srcptr src, mp_size_t size, mp_limb_t divisor);
C mp_limb_t mpn_divrem_1c (mp_ptr dst, mp_size_t xsize,
C mp_srcptr src, mp_size_t size, mp_limb_t divisor,
C mp_limb_t carry);
C
C The code here is basically the same as mpn/x86/divrem_1.asm, but uses loop
C instead of decl+jnz, since it comes out 2 cycles/limb faster.
C
C A test is done to see if the high limb is less than the divisor, and if so
C one less div is done. A div is 20 cycles, so assuming high<divisor about
C half the time, then this test saves half that amount. The branch
C misprediction penalty is less than that.
C
C Back-to-back div instructions run at 20 cycles, the same as the loop here,
C so it seems there's nothing to gain by rearranging the loop. Pairing the
C mov and loop instructions was found to gain nothing.
C
C Enhancements:
C
C The low-latency K6 multiply might be thought to suit a mul-by-inverse, but
C that algorithm has been found to suffer from the relatively poor carry
C handling on K6 and too many auxiliary instructions. The fractional part
C however could be done at about 13 c/l, if it mattered enough.
defframe(PARAM_CARRY, 24)
defframe(PARAM_DIVISOR,20)
defframe(PARAM_SIZE, 16)
defframe(PARAM_SRC, 12)
defframe(PARAM_XSIZE, 8)
defframe(PARAM_DST, 4)
TEXT
ALIGN(32)
PROLOGUE(mpn_divrem_1c)
deflit(`FRAME',0)
movl PARAM_SIZE, %ecx
pushl %edi FRAME_pushl()
movl PARAM_SRC, %edi
pushl %esi FRAME_pushl()
movl PARAM_DIVISOR, %esi
pushl %ebx FRAME_pushl()
movl PARAM_DST, %ebx
pushl %ebp FRAME_pushl()
movl PARAM_XSIZE, %ebp
orl %ecx, %ecx C size
movl PARAM_CARRY, %edx
jz L(fraction) C if size==0
leal -4(%ebx,%ebp,4), %ebx C dst one limb below integer part
jmp L(integer_top)
EPILOGUE()
ALIGN(16)
PROLOGUE(mpn_divrem_1)
deflit(`FRAME',0)
movl PARAM_SIZE, %ecx
pushl %edi FRAME_pushl()
movl PARAM_SRC, %edi
pushl %esi FRAME_pushl()
movl PARAM_DIVISOR, %esi
orl %ecx,%ecx C size
jz L(size_zero)
pushl %ebx FRAME_pushl()
movl -4(%edi,%ecx,4), %eax C src high limb
xorl %edx, %edx
movl PARAM_DST, %ebx
pushl %ebp FRAME_pushl()
movl PARAM_XSIZE, %ebp
cmpl %esi, %eax
leal -4(%ebx,%ebp,4), %ebx C dst one limb below integer part
jae L(integer_entry)
C high<divisor, so high of dst is zero, and avoid one div
movl %edx, (%ebx,%ecx,4)
decl %ecx
movl %eax, %edx
jz L(fraction)
L(integer_top):
C eax scratch (quotient)
C ebx dst+4*xsize-4
C ecx counter
C edx scratch (remainder)
C esi divisor
C edi src
C ebp xsize
movl -4(%edi,%ecx,4), %eax
L(integer_entry):
divl %esi
movl %eax, (%ebx,%ecx,4)
loop L(integer_top)
L(fraction):
orl %ebp, %ecx
jz L(done)
movl PARAM_DST, %ebx
L(fraction_top):
C eax scratch (quotient)
C ebx dst
C ecx counter
C edx scratch (remainder)
C esi divisor
C edi
C ebp
xorl %eax, %eax
divl %esi
movl %eax, -4(%ebx,%ecx,4)
loop L(fraction_top)
L(done):
popl %ebp
movl %edx, %eax
popl %ebx
popl %esi
popl %edi
ret
L(size_zero):
deflit(`FRAME',8)
movl PARAM_XSIZE, %ecx
xorl %eax, %eax
movl PARAM_DST, %edi
cld C better safe than sorry, see mpn/x86/README
rep
stosl
popl %esi
popl %edi
ret
EPILOGUE()

View File

@@ -0,0 +1,166 @@
/* AMD K6 gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 1991, 1993, 1994, 2000-2004, 2009, 2010 Free Software Foundation,
Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* 450MHz K6-2 */
#define MOD_1_NORM_THRESHOLD 12
#define MOD_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define MOD_1N_TO_MOD_1_1_THRESHOLD 41
#define MOD_1U_TO_MOD_1_1_THRESHOLD 32
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 3
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 128
#define USE_PREINV_DIVREM_1 0
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD MP_SIZE_T_MAX /* never */
#define MUL_TOOM22_THRESHOLD 20
#define MUL_TOOM33_THRESHOLD 69
#define MUL_TOOM44_THRESHOLD 106
#define MUL_TOOM6H_THRESHOLD 157
#define MUL_TOOM8H_THRESHOLD 199
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 73
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 69
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 65
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 64
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 32
#define SQR_TOOM3_THRESHOLD 97
#define SQR_TOOM4_THRESHOLD 143
#define SQR_TOOM6_THRESHOLD 222
#define SQR_TOOM8_THRESHOLD 272
#define MULMOD_BNM1_THRESHOLD 13
#define SQRMOD_BNM1_THRESHOLD 17
#define MUL_FFT_MODF_THRESHOLD 476 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 476, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
{ 11, 5}, { 23, 6}, { 17, 7}, { 9, 6}, \
{ 19, 7}, { 11, 6}, { 23, 7}, { 13, 6}, \
{ 27, 7}, { 15, 6}, { 31, 7}, { 17, 6}, \
{ 35, 7}, { 21, 8}, { 11, 7}, { 27, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 39, 8}, \
{ 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
{ 31, 7}, { 63, 8}, { 39, 9}, { 23, 8}, \
{ 51,10}, { 15, 9}, { 31, 8}, { 67, 9}, \
{ 47,10}, { 31, 9}, { 79,10}, { 47, 9}, \
{ 95,11}, { 31,10}, { 63, 9}, { 135,10}, \
{ 79, 9}, { 167,10}, { 95, 9}, { 191,10}, \
{ 111,11}, { 63,10}, { 127, 9}, { 255,10}, \
{ 143, 9}, { 287,10}, { 159,11}, { 95,10}, \
{ 191, 9}, { 383,12}, { 63,11}, { 127,10}, \
{ 255, 9}, { 511,10}, { 271, 9}, { 543,10}, \
{ 287,11}, { 159,10}, { 351,11}, { 191,10}, \
{ 415, 9}, { 831,11}, { 223,12}, { 127,11}, \
{ 255,10}, { 543,11}, { 287,10}, { 575,11}, \
{ 351,10}, { 703,12}, { 191,11}, { 415,10}, \
{ 831,13}, { 127,12}, { 255,11}, { 543,10}, \
{ 1087,11}, { 575,12}, { 319,11}, { 703,12}, \
{ 383,11}, { 831,12}, { 447,11}, { 895,13}, \
{ 255,12}, { 511,11}, { 1087,12}, { 575,11}, \
{ 1151,12}, { 703,13}, { 383,12}, { 959,14}, \
{ 255,13}, { 511,12}, { 1215,13}, { 8192,14}, \
{ 16384,15}, { 32768,16} }
#define MUL_FFT_TABLE3_SIZE 106
#define MUL_FFT_THRESHOLD 7424
#define SQR_FFT_MODF_THRESHOLD 432 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 432, 5}, { 17, 6}, { 9, 5}, { 19, 6}, \
{ 11, 5}, { 23, 6}, { 21, 7}, { 11, 6}, \
{ 24, 7}, { 13, 6}, { 27, 7}, { 15, 6}, \
{ 31, 7}, { 21, 8}, { 11, 7}, { 29, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 39, 8}, \
{ 23, 7}, { 49, 8}, { 27, 9}, { 15, 8}, \
{ 39, 9}, { 23, 7}, { 93, 8}, { 47, 7}, \
{ 95, 8}, { 51,10}, { 15, 9}, { 31, 8}, \
{ 67, 9}, { 39, 8}, { 79, 9}, { 47, 8}, \
{ 95, 9}, { 55,10}, { 31, 9}, { 71, 8}, \
{ 143, 9}, { 79,10}, { 47, 9}, { 95,11}, \
{ 31,10}, { 63, 9}, { 135,10}, { 79, 9}, \
{ 167,10}, { 95, 9}, { 191,11}, { 63,10}, \
{ 127, 9}, { 255,10}, { 143, 9}, { 287, 8}, \
{ 575,10}, { 159, 9}, { 319,11}, { 95,10}, \
{ 191,12}, { 63,11}, { 127,10}, { 255, 9}, \
{ 511,10}, { 271, 9}, { 543,10}, { 287,11}, \
{ 159,10}, { 319, 9}, { 639,10}, { 351, 9}, \
{ 703,11}, { 191,10}, { 415,11}, { 223,12}, \
{ 127,11}, { 255,10}, { 543,11}, { 287,10}, \
{ 607,11}, { 319,10}, { 639,11}, { 351,10}, \
{ 703,12}, { 191,11}, { 415,10}, { 831,13}, \
{ 127,12}, { 255,11}, { 543,10}, { 1087,11}, \
{ 607,12}, { 319,11}, { 703,12}, { 383,11}, \
{ 831,12}, { 447,13}, { 255,12}, { 511,11}, \
{ 1087,12}, { 575,11}, { 1215,12}, { 703,13}, \
{ 383,12}, { 895,14}, { 255,13}, { 511,12}, \
{ 1215,13}, { 8192,14}, { 16384,15}, { 32768,16} }
#define SQR_FFT_TABLE3_SIZE 112
#define SQR_FFT_THRESHOLD 7040
#define MULLO_BASECASE_THRESHOLD 3
#define MULLO_DC_THRESHOLD 60
#define MULLO_MUL_N_THRESHOLD 13463
#define DC_DIV_QR_THRESHOLD 78
#define DC_DIVAPPR_Q_THRESHOLD 252
#define DC_BDIV_QR_THRESHOLD 84
#define DC_BDIV_Q_THRESHOLD 171
#define INV_MULMOD_BNM1_THRESHOLD 55
#define INV_NEWTON_THRESHOLD 234
#define INV_APPR_THRESHOLD 236
#define BINV_NEWTON_THRESHOLD 268
#define REDC_1_TO_REDC_N_THRESHOLD 67
#define MU_DIV_QR_THRESHOLD 1308
#define MU_DIVAPPR_Q_THRESHOLD 1142
#define MUPI_DIV_QR_THRESHOLD 134
#define MU_BDIV_QR_THRESHOLD 1164
#define MU_BDIV_Q_THRESHOLD 1164
#define MATRIX22_STRASSEN_THRESHOLD 15
#define HGCD_THRESHOLD 182
#define GCD_DC_THRESHOLD 591
#define GCDEXT_DC_THRESHOLD 472
#define JACOBI_BASE_METHOD 2
#define GET_STR_DC_THRESHOLD 24
#define GET_STR_PRECOMPUTE_THRESHOLD 40
#define SET_STR_DC_THRESHOLD 834
#define SET_STR_PRECOMPUTE_THRESHOLD 2042

View File

@@ -0,0 +1,118 @@
dnl AMD K6-2 mpn_copyd -- copy limb vector, decrementing.
dnl Copyright 2001, 2002 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C K6-2: 1.0 cycles/limb
C void mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t size);
C
C The loop here is no faster than a rep movsl at 1.0 c/l, but it avoids a 30
C cycle startup time, which amounts for instance to a 2x speedup at 15
C limbs.
C
C If dst is 4mod8 the loop would be 1.17 c/l, but that's avoided by
C processing one limb separately to make it aligned. This and a final odd
C limb are handled in a branch-free fashion, ending up re-copying if the
C special case isn't needed.
C
C Alternatives:
C
C There used to be a big unrolled version of this, running at 0.56 c/l if
C the destination was aligned, but that seemed rather excessive for the
C relative importance of copyd.
C
C If the destination alignment is ignored and just left to run at 1.17 c/l
C some code size and a fixed few cycles can be saved. Considering how few
C uses copyd finds perhaps that should be favoured. The current code has
C the attraction of being no slower than a basic rep movsl though.
defframe(PARAM_SIZE,12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
dnl re-using parameter space
define(SAVE_EBX,`PARAM_SIZE')
TEXT
ALIGN(16)
PROLOGUE(mpn_copyd)
deflit(`FRAME',0)
movl PARAM_SIZE, %ecx
movl %ebx, SAVE_EBX
movl PARAM_SRC, %eax
movl PARAM_DST, %edx
subl $1, %ecx C better code alignment than decl
jb L(zero)
jz L(one_more)
leal 4(%edx,%ecx,4), %ebx
Zdisp( movd, 0,(%eax,%ecx,4), %mm0) C high limb
Zdisp( movd, %mm0, 0,(%edx,%ecx,4)) C Zdisp for good code alignment
cmpl $1, %ecx
je L(one_more)
shrl $2, %ebx
andl $1, %ebx C 1 if dst[size-2] unaligned
subl %ebx, %ecx
nop C code alignment
L(top):
C eax src
C ebx
C ecx counter
C edx dst
movq -4(%eax,%ecx,4), %mm0
subl $2, %ecx
movq %mm0, 4(%edx,%ecx,4)
ja L(top)
L(one_more):
movd (%eax), %mm0
movd %mm0, (%edx)
movl SAVE_EBX, %ebx
emms_or_femms
L(zero):
ret
EPILOGUE()

View File

@@ -0,0 +1,294 @@
dnl AMD K6-2 mpn_lshift -- mpn left shift.
dnl Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C K6-2: 1.75 cycles/limb
C mp_limb_t mpn_lshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
C unsigned shift);
C
defframe(PARAM_SHIFT,16)
defframe(PARAM_SIZE, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
deflit(`FRAME',0)
dnl used after src has been fetched
define(VAR_RETVAL,`PARAM_SRC')
dnl minimum 9, because unrolled loop can't handle less
deflit(UNROLL_THRESHOLD, 9)
TEXT
ALIGN(32)
PROLOGUE(mpn_lshift)
deflit(`FRAME',0)
C The 1 limb case can be done without the push %ebx, but it's then
C still the same speed. The push is left as a free helping hand for
C the two_or_more code.
movl PARAM_SIZE, %eax
pushl %ebx FRAME_pushl()
movl PARAM_SRC, %ebx
decl %eax
movl PARAM_SHIFT, %ecx
jnz L(two_or_more)
movl (%ebx), %edx C src limb
movl PARAM_DST, %ebx
shldl( %cl, %edx, %eax) C return value
shll %cl, %edx
movl %edx, (%ebx) C dst limb
popl %ebx
ret
C -----------------------------------------------------------------------------
ALIGN(16) C avoid offset 0x1f
L(two_or_more):
C eax size-1
C ebx src
C ecx shift
C edx
movl (%ebx,%eax,4), %edx C src high limb
negl %ecx
movd PARAM_SHIFT, %mm6
addl $32, %ecx C 32-shift
shrl %cl, %edx
cmpl $UNROLL_THRESHOLD-1, %eax
movl %edx, VAR_RETVAL
jae L(unroll)
movd %ecx, %mm7
movl %eax, %ecx
movl PARAM_DST, %eax
L(simple):
C eax dst
C ebx src
C ecx counter, size-1 to 1
C edx retval
C
C mm0 scratch
C mm6 shift
C mm7 32-shift
movq -4(%ebx,%ecx,4), %mm0
psrlq %mm7, %mm0
Zdisp( movd, %mm0, 0,(%eax,%ecx,4))
loop L(simple)
movd (%ebx), %mm0
popl %ebx
psllq %mm6, %mm0
movd %mm0, (%eax)
movl %edx, %eax
femms
ret
C -----------------------------------------------------------------------------
ALIGN(16)
L(unroll):
C eax size-1
C ebx src
C ecx 32-shift
C edx retval (but instead VAR_RETVAL is used)
C
C mm6 shift
addl $32, %ecx
movl PARAM_DST, %edx
movd %ecx, %mm7
subl $7, %eax C size-8
leal (%edx,%eax,4), %ecx C alignment of dst
movq 32-8(%ebx,%eax,4), %mm2 C src high qword
testb $4, %cl
jz L(dst_aligned)
psllq %mm6, %mm2
psrlq $32, %mm2
decl %eax
movd %mm2, 32(%edx,%eax,4) C dst high limb
movq 32-8(%ebx,%eax,4), %mm2 C new src high qword
L(dst_aligned):
movq 32-16(%ebx,%eax,4), %mm0 C src second highest qword
C This loop is the important bit, the rest is just support for it.
C Four src limbs are held at the start, and four more will be read.
C Four dst limbs will be written. This schedule seems necessary for
C full speed.
C
C The use of size-8 lets the loop stop when %eax goes negative and
C leaves -4 to -1 which can be tested with test $1 and $2.
L(top):
C eax counter, size-8 step by -4 until <0
C ebx src
C ecx
C edx dst
C
C mm0 src next qword
C mm1 scratch
C mm2 src prev qword
C mm6 shift
C mm7 64-shift
psllq %mm6, %mm2
subl $4, %eax
movq %mm0, %mm1
psrlq %mm7, %mm0
por %mm0, %mm2
movq 24(%ebx,%eax,4), %mm0
psllq %mm6, %mm1
movq %mm2, 40(%edx,%eax,4)
movq %mm0, %mm2
psrlq %mm7, %mm0
por %mm0, %mm1
movq 16(%ebx,%eax,4), %mm0
movq %mm1, 32(%edx,%eax,4)
jnc L(top)
C Now have four limbs in mm2 (prev) and mm0 (next), plus eax mod 4.
C
C 8(%ebx) is the next source, and 24(%edx) is the next destination.
C %eax is between -4 and -1, representing respectively 0 to 3 extra
C limbs that must be read.
testl $2, %eax C testl to avoid bad cache line crossing
jz L(finish_nottwo)
C Two more limbs: lshift mm2, OR it with rshifted mm0, mm0 becomes
C new mm2 and a new mm0 is loaded.
psllq %mm6, %mm2
movq %mm0, %mm1
psrlq %mm7, %mm0
subl $2, %eax
por %mm0, %mm2
movq 16(%ebx,%eax,4), %mm0
movq %mm2, 32(%edx,%eax,4)
movq %mm1, %mm2
L(finish_nottwo):
C lshift mm2, OR with rshifted mm0, mm1 becomes lshifted mm0
testb $1, %al
psllq %mm6, %mm2
movq %mm0, %mm1
psrlq %mm7, %mm0
por %mm0, %mm2
psllq %mm6, %mm1
movq %mm2, 24(%edx,%eax,4)
jz L(finish_even)
C Size is odd, so mm1 and one extra limb to process.
movd (%ebx), %mm0 C src[0]
popl %ebx
deflit(`FRAME',0)
movq %mm0, %mm2
psllq $32, %mm0
psrlq %mm7, %mm0
psllq %mm6, %mm2
por %mm0, %mm1
movq %mm1, 4(%edx) C dst[1,2]
movd %mm2, (%edx) C dst[0]
movl VAR_RETVAL, %eax
femms
ret
nop C avoid bad cache line crossing
L(finish_even):
deflit(`FRAME',4)
C Size is even, so only mm1 left to process.
movq %mm1, (%edx) C dst[0,1]
movl VAR_RETVAL, %eax
popl %ebx
femms
ret
EPILOGUE()

View File

@@ -0,0 +1,293 @@
dnl AMD K6-2 mpn_rshift -- mpn right shift.
dnl Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C K6-2: 1.75 cycles/limb
C mp_limb_t mpn_rshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
C unsigned shift);
C
defframe(PARAM_SHIFT,16)
defframe(PARAM_SIZE, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
deflit(`FRAME',0)
dnl Minimum 9, because the unrolled loop can't handle less.
dnl
deflit(UNROLL_THRESHOLD, 9)
TEXT
ALIGN(32)
PROLOGUE(mpn_rshift)
deflit(`FRAME',0)
C The 1 limb case can be done without the push %ebx, but it's then
C still the same speed. The push is left as a free helping hand for
C the two_or_more code.
movl PARAM_SIZE, %eax
pushl %ebx FRAME_pushl()
movl PARAM_SRC, %ebx
decl %eax
movl PARAM_SHIFT, %ecx
jnz L(two_or_more)
movl (%ebx), %edx C src limb
movl PARAM_DST, %ebx
shrdl( %cl, %edx, %eax) C return value
shrl %cl, %edx
movl %edx, (%ebx) C dst limb
popl %ebx
ret
C -----------------------------------------------------------------------------
ALIGN(16) C avoid offset 0x1f
L(two_or_more):
C eax size-1
C ebx src
C ecx shift
C edx
movl (%ebx), %edx C src low limb
negl %ecx
addl $32, %ecx
movd PARAM_SHIFT, %mm6
shll %cl, %edx
cmpl $UNROLL_THRESHOLD-1, %eax
jae L(unroll)
C eax size-1
C ebx src
C ecx 32-shift
C edx retval
C
C mm6 shift
movl PARAM_DST, %ecx
leal (%ebx,%eax,4), %ebx
leal -4(%ecx,%eax,4), %ecx
negl %eax
C This loop runs at about 3 cycles/limb, which is the amount of
C decoding, and this is despite every second access being unaligned.
L(simple):
C eax counter, -(size-1) to -1
C ebx &src[size-1]
C ecx &dst[size-1]
C edx retval
C
C mm0 scratch
C mm6 shift
Zdisp( movq, 0,(%ebx,%eax,4), %mm0)
incl %eax
psrlq %mm6, %mm0
Zdisp( movd, %mm0, 0,(%ecx,%eax,4))
jnz L(simple)
movq %mm0, (%ecx)
movl %edx, %eax
popl %ebx
femms
ret
C -----------------------------------------------------------------------------
ALIGN(16)
L(unroll):
C eax size-1
C ebx src
C ecx 32-shift
C edx retval
C
C mm6 shift
addl $32, %ecx
subl $7, %eax C size-8
movd %ecx, %mm7
movl PARAM_DST, %ecx
movq (%ebx), %mm2 C src low qword
leal (%ebx,%eax,4), %ebx C src end - 32
testb $4, %cl
leal (%ecx,%eax,4), %ecx C dst end - 32
notl %eax C -(size-7)
jz L(dst_aligned)
psrlq %mm6, %mm2
incl %eax
Zdisp( movd, %mm2, 0,(%ecx,%eax,4)) C dst low limb
movq 4(%ebx,%eax,4), %mm2 C new src low qword
L(dst_aligned):
movq 12(%ebx,%eax,4), %mm0 C src second lowest qword
nop C avoid bad cache line crossing
C This loop is the important bit, the rest is just support for it.
C Four src limbs are held at the start, and four more will be read.
C Four dst limbs will be written. This schedule seems necessary for
C full speed.
C
C The use of -(size-7) lets the loop stop when %eax becomes >= 0 and
C and leaves 0 to 3 which can be tested with test $1 and $2.
L(top):
C eax counter, -(size-7) step by +4 until >=0
C ebx src end - 32
C ecx dst end - 32
C edx retval
C
C mm0 src next qword
C mm1 scratch
C mm2 src prev qword
C mm6 shift
C mm7 64-shift
psrlq %mm6, %mm2
addl $4, %eax
movq %mm0, %mm1
psllq %mm7, %mm0
por %mm0, %mm2
movq 4(%ebx,%eax,4), %mm0
psrlq %mm6, %mm1
movq %mm2, -12(%ecx,%eax,4)
movq %mm0, %mm2
psllq %mm7, %mm0
por %mm0, %mm1
movq 12(%ebx,%eax,4), %mm0
movq %mm1, -4(%ecx,%eax,4)
ja L(top) C jump if no carry and not zero
C Now have the four limbs in mm2 (low) and mm0 (high), and %eax is 0
C to 3 representing respectively 3 to 0 further limbs.
testl $2, %eax C testl to avoid bad cache line crossings
jnz L(finish_nottwo)
C Two or three extra limbs: rshift mm2, OR it with lshifted mm0, mm0
C becomes new mm2 and a new mm0 is loaded.
psrlq %mm6, %mm2
movq %mm0, %mm1
psllq %mm7, %mm0
addl $2, %eax
por %mm0, %mm2
movq 12(%ebx,%eax,4), %mm0
movq %mm2, -4(%ecx,%eax,4)
movq %mm1, %mm2
L(finish_nottwo):
testb $1, %al
psrlq %mm6, %mm2
movq %mm0, %mm1
psllq %mm7, %mm0
por %mm0, %mm2
psrlq %mm6, %mm1
movq %mm2, 4(%ecx,%eax,4)
jnz L(finish_even)
C one further extra limb to process
movd 32-4(%ebx), %mm0 C src[size-1], most significant limb
popl %ebx
movq %mm0, %mm2
psllq %mm7, %mm0
por %mm0, %mm1
psrlq %mm6, %mm2
movq %mm1, 32-12(%ecx) C dst[size-3,size-2]
movd %mm2, 32-4(%ecx) C dst[size-1]
movl %edx, %eax C retval
femms
ret
nop C avoid bad cache line crossing
L(finish_even):
C no further extra limbs
movq %mm1, 32-8(%ecx) C dst[size-2,size-1]
movl %edx, %eax C retval
popl %ebx
femms
ret
EPILOGUE()

View File

@@ -0,0 +1,103 @@
dnl AMD K6-2 mpn_com -- mpn bitwise one's complement.
dnl Copyright 1999-2002 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
NAILS_SUPPORT(0-31)
C alignment dst/src, A=0mod8 N=4mod8
C A/A A/N N/A N/N
C K6-2 1.0 1.18 1.18 1.18 cycles/limb
C K6 1.5 1.85 1.75 1.85
C void mpn_com (mp_ptr dst, mp_srcptr src, mp_size_t size);
C
C Take the bitwise ones-complement of src,size and write it to dst,size.
defframe(PARAM_SIZE,12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
TEXT
ALIGN(16)
PROLOGUE(mpn_com)
deflit(`FRAME',0)
movl PARAM_SIZE, %ecx
movl PARAM_SRC, %eax
movl PARAM_DST, %edx
shrl %ecx
jnz L(two_or_more)
movl (%eax), %eax
notl_or_xorl_GMP_NUMB_MASK( %eax)
movl %eax, (%edx)
ret
L(two_or_more):
pushl %ebx FRAME_pushl()
pcmpeqd %mm7, %mm7 C all ones
movl %ecx, %ebx
ifelse(GMP_NAIL_BITS,0,,
` psrld $GMP_NAIL_BITS, %mm7') C clear nails
ALIGN(8)
L(top):
C eax src
C ebx floor(size/2)
C ecx counter
C edx dst
C
C mm0 scratch
C mm7 mask
movq -8(%eax,%ecx,8), %mm0
pxor %mm7, %mm0
movq %mm0, -8(%edx,%ecx,8)
loop L(top)
jnc L(no_extra)
movl (%eax,%ebx,8), %eax
notl_or_xorl_GMP_NUMB_MASK( %eax)
movl %eax, (%edx,%ebx,8)
L(no_extra):
popl %ebx
emms_or_femms
ret
EPILOGUE()

View File

@@ -0,0 +1,282 @@
dnl AMD K6 mpn_divexact_1 -- mpn by limb exact division.
dnl Copyright 2000-2002, 2007 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C divisor
C odd even
C K6: 10.0 12.0 cycles/limb
C K6-2: 10.0 11.5
C void mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
C mp_limb_t divisor);
C
C A simple divl is used for size==1. This is about 10 cycles faster for an
C odd divisor or 20 cycles for an even divisor.
C
C The loops are quite sensitive to code alignment, speeds should be
C rechecked (odd and even divisor, pic and non-pic) if contemplating
C changing anything.
defframe(PARAM_DIVISOR,16)
defframe(PARAM_SIZE, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
dnl re-use parameter space
define(VAR_INVERSE,`PARAM_DST')
TEXT
ALIGN(32)
PROLOGUE(mpn_divexact_1)
deflit(`FRAME',0)
movl PARAM_SIZE, %ecx
movl PARAM_SRC, %eax
xorl %edx, %edx
cmpl $1, %ecx
jnz L(two_or_more)
movl (%eax), %eax
divl PARAM_DIVISOR
movl PARAM_DST, %ecx
movl %eax, (%ecx)
ret
L(two_or_more):
movl PARAM_DIVISOR, %eax
pushl %ebx FRAME_pushl()
movl PARAM_SRC, %ebx
pushl %ebp FRAME_pushl()
L(strip_twos):
shrl %eax
incl %edx C will get shift+1
jnc L(strip_twos)
pushl %esi FRAME_pushl()
leal 1(%eax,%eax), %esi C d without twos
andl $127, %eax C d/2, 7 bits
ifdef(`PIC',`
LEA( binvert_limb_table, %ebp)
Zdisp( movzbl, 0,(%eax,%ebp), %eax)
',`
movzbl binvert_limb_table(%eax), %eax C inv 8 bits
')
pushl %edi FRAME_pushl()
leal (%eax,%eax), %ebp C 2*inv
imull %eax, %eax C inv*inv
movl PARAM_DST, %edi
imull %esi, %eax C inv*inv*d
subl %eax, %ebp C inv = 2*inv - inv*inv*d
leal (%ebp,%ebp), %eax C 2*inv
imull %ebp, %ebp C inv*inv
movl %esi, PARAM_DIVISOR C d without twos
leal (%ebx,%ecx,4), %ebx C src end
imull %esi, %ebp C inv*inv*d
leal (%edi,%ecx,4), %edi C dst end
negl %ecx C -size
subl %ebp, %eax C inv = 2*inv - inv*inv*d
subl $1, %edx C shift amount, and clear carry
ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
pushl %eax FRAME_pushl()
imull PARAM_DIVISOR, %eax
cmpl $1, %eax
popl %eax FRAME_popl()')
movl %eax, VAR_INVERSE
jnz L(even)
movl (%ebx,%ecx,4), %esi C src low limb
jmp L(odd_entry)
ALIGN(16)
nop C code alignment
L(odd_top):
C eax scratch
C ebx src end
C ecx counter, limbs, negative
C edx inverse
C esi next limb, adjusted for carry
C edi dst end
C ebp carry bit, 0 or -1
imull %edx, %esi
movl PARAM_DIVISOR, %eax
movl %esi, -4(%edi,%ecx,4)
mull %esi C carry limb in edx
subl %ebp, %edx C apply carry bit
movl (%ebx,%ecx,4), %esi
L(odd_entry):
subl %edx, %esi C apply carry limb
movl VAR_INVERSE, %edx
sbbl %ebp, %ebp C 0 or -1
incl %ecx
jnz L(odd_top)
imull %edx, %esi
movl %esi, -4(%edi,%ecx,4)
popl %edi
popl %esi
popl %ebp
popl %ebx
ret
L(even):
C eax
C ebx src end
C ecx -size
C edx twos
C esi
C edi dst end
C ebp
xorl %ebp, %ebp
Zdisp( movq, 0,(%ebx,%ecx,4), %mm0) C src[0,1]
movd %edx, %mm7
movl VAR_INVERSE, %edx
addl $2, %ecx
psrlq %mm7, %mm0
movd %mm0, %esi
jz L(even_two) C if only two limbs
C Out-of-order execution is good enough to hide the load/rshift/movd
C latency. Having imul at the top of the loop gives 11.5 c/l instead of 12,
C on K6-2. In fact there's only 11 of decode, but nothing running at 11 has
C been found. Maybe the fact every second movq is unaligned costs the extra
C 0.5.
L(even_top):
C eax scratch
C ebx src end
C ecx counter, limbs, negative
C edx inverse
C esi next limb, adjusted for carry
C edi dst end
C ebp carry bit, 0 or -1
C
C mm0 scratch, source limbs
C mm7 twos
imull %edx, %esi
movl %esi, -8(%edi,%ecx,4)
movl PARAM_DIVISOR, %eax
mull %esi C carry limb in edx
movq -4(%ebx,%ecx,4), %mm0
psrlq %mm7, %mm0
movd %mm0, %esi
subl %ebp, %edx C apply carry bit
subl %edx, %esi C apply carry limb
movl VAR_INVERSE, %edx
sbbl %ebp, %ebp C 0 or -1
incl %ecx
jnz L(even_top)
L(even_two):
movd -4(%ebx), %mm0 C src high limb
psrlq %mm7, %mm0
imull %edx, %esi
movl %esi, -8(%edi)
movl PARAM_DIVISOR, %eax
mull %esi C carry limb in edx
movd %mm0, %esi
subl %ebp, %edx C apply carry bit
movl VAR_INVERSE, %eax
subl %edx, %esi C apply carry limb
imull %eax, %esi
movl %esi, -4(%edi)
popl %edi
popl %esi
popl %ebp
popl %ebx
emms_or_femms
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,226 @@
dnl AMD K6-2 mpn_and_n, mpn_andn_n, mpn_nand_n, mpn_ior_n, mpn_iorn_n,
dnl mpn_nior_n, mpn_xor_n, mpn_xnor_n -- mpn bitwise logical operations.
dnl Copyright 1999-2002 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
NAILS_SUPPORT(0-31)
C alignment dst/src1/src2, A=0mod8, N=4mod8
C A/A/A A/A/N A/N/A A/N/N N/A/A N/A/N N/N/A N/N/N
C
C K6-2 1.2 1.5 1.5 1.2 1.2 1.5 1.5 1.2 and,andn,ior,xor
C K6-2 1.5 1.75 2.0 1.75 1.75 2.0 1.75 1.5 iorn,xnor
C K6-2 1.75 2.0 2.0 2.0 2.0 2.0 2.0 1.75 nand,nior
C
C K6 1.5 1.68 1.75 1.2 1.75 1.75 1.68 1.5 and,andn,ior,xor
C K6 2.0 2.0 2.25 2.25 2.25 2.25 2.0 2.0 iorn,xnor
C K6 2.0 2.25 2.25 2.25 2.25 2.25 2.25 2.0 nand,nior
dnl M4_p and M4_i are the MMX and integer instructions
dnl M4_*_neg_dst means whether to negate the final result before writing
dnl M4_*_neg_src2 means whether to negate the src2 values before using them
define(M4_choose_op,
m4_assert_numargs(7)
`ifdef(`OPERATION_$1',`
define(`M4_function', `mpn_$1')
define(`M4_operation', `$1')
define(`M4_p', `$2')
define(`M4_p_neg_dst', `$3')
define(`M4_p_neg_src2',`$4')
define(`M4_i', `$5')
define(`M4_i_neg_dst', `$6')
define(`M4_i_neg_src2',`$7')
')')
dnl xnor is done in "iorn" style because it's a touch faster than "nior"
dnl style (the two are equivalent for xor).
dnl
dnl pandn can't be used with nails.
M4_choose_op( and_n, pand,0,0, andl,0,0)
ifelse(GMP_NAIL_BITS,0,
`M4_choose_op(andn_n, pandn,0,0, andl,0,1)',
`M4_choose_op(andn_n, pand,0,1, andl,0,1)')
M4_choose_op( nand_n, pand,1,0, andl,1,0)
M4_choose_op( ior_n, por,0,0, orl,0,0)
M4_choose_op( iorn_n, por,0,1, orl,0,1)
M4_choose_op( nior_n, por,1,0, orl,1,0)
M4_choose_op( xor_n, pxor,0,0, xorl,0,0)
M4_choose_op( xnor_n, pxor,0,1, xorl,0,1)
ifdef(`M4_function',,
`m4_error(`Unrecognised or undefined OPERATION symbol
')')
MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
C void M4_function (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size);
C
C Do src1,size M4_operation src2,size, storing the result in dst,size.
C
C Unaligned movq loads and stores are a bit slower than aligned ones. The
C test at the start of the routine checks the alignment of src1 and if
C necessary processes one limb separately at the low end to make it aligned.
C
C The raw speeds without this alignment switch are as follows.
C
C alignment dst/src1/src2, A=0mod8, N=4mod8
C A/A/A A/A/N A/N/A A/N/N N/A/A N/A/N N/N/A N/N/N
C
C K6 1.5 2.0 1.5 2.0 and,andn,ior,xor
C K6 1.75 2.2 2.0 2.28 iorn,xnor
C K6 2.0 2.25 2.35 2.28 nand,nior
C
C
C Future:
C
C K6 can do one 64-bit load per cycle so each of these routines should be
C able to approach 1.0 c/l, if aligned. The basic and/andn/ior/xor might be
C able to get 1.0 with just a 4 limb loop, being 3 instructions per 2 limbs.
C The others are 4 instructions per 2 limbs, and so can only approach 1.0
C because there's nowhere to hide some loop control.
defframe(PARAM_SIZE,16)
defframe(PARAM_SRC2,12)
defframe(PARAM_SRC1,8)
defframe(PARAM_DST, 4)
deflit(`FRAME',0)
TEXT
ALIGN(32)
PROLOGUE(M4_function)
movl PARAM_SIZE, %ecx
pushl %ebx FRAME_pushl()
movl PARAM_SRC1, %eax
movl PARAM_SRC2, %ebx
cmpl $1, %ecx
movl PARAM_DST, %edx
ja L(two_or_more)
movl (%ebx), %ecx
popl %ebx
ifelse(M4_i_neg_src2,1,`notl_or_xorl_GMP_NUMB_MASK( %ecx)')
M4_i (%eax), %ecx
ifelse(M4_i_neg_dst,1,` notl_or_xorl_GMP_NUMB_MASK( %ecx)')
movl %ecx, (%edx)
ret
L(two_or_more):
C eax src1
C ebx src2
C ecx size
C edx dst
C esi
C edi
C ebp
pushl %esi FRAME_pushl()
testl $4, %eax
jz L(alignment_ok)
movl (%ebx), %esi
addl $4, %ebx
ifelse(M4_i_neg_src2,1,`notl_or_xorl_GMP_NUMB_MASK( %esi)')
M4_i (%eax), %esi
addl $4, %eax
ifelse(M4_i_neg_dst,1,` notl_or_xorl_GMP_NUMB_MASK( %esi)')
movl %esi, (%edx)
addl $4, %edx
decl %ecx
L(alignment_ok):
movl %ecx, %esi
shrl %ecx
jnz L(still_two_or_more)
movl (%ebx), %ecx
popl %esi
ifelse(M4_i_neg_src2,1,`notl_or_xorl_GMP_NUMB_MASK( %ecx)')
M4_i (%eax), %ecx
ifelse(M4_i_neg_dst,1,` notl_or_xorl_GMP_NUMB_MASK( %ecx)')
popl %ebx
movl %ecx, (%edx)
ret
L(still_two_or_more):
ifelse(eval(M4_p_neg_src2 || M4_p_neg_dst),1,`
pcmpeqd %mm7, %mm7 C all ones
ifelse(GMP_NAIL_BITS,0,,`psrld $GMP_NAIL_BITS, %mm7') C clear nails
')
ALIGN(16)
L(top):
C eax src1
C ebx src2
C ecx counter
C edx dst
C esi
C edi
C ebp
C
C carry bit is low of size
movq -8(%ebx,%ecx,8), %mm0
ifelse(M4_p_neg_src2,1,`pxor %mm7, %mm0')
M4_p -8(%eax,%ecx,8), %mm0
ifelse(M4_p_neg_dst,1,` pxor %mm7, %mm0')
movq %mm0, -8(%edx,%ecx,8)
loop L(top)
jnc L(no_extra)
movl -4(%ebx,%esi,4), %ebx
ifelse(M4_i_neg_src2,1,`notl_or_xorl_GMP_NUMB_MASK( %ebx)')
M4_i -4(%eax,%esi,4), %ebx
ifelse(M4_i_neg_dst,1,` notl_or_xorl_GMP_NUMB_MASK( %ebx)')
movl %ebx, -4(%edx,%esi,4)
L(no_extra):
popl %esi
popl %ebx
emms_or_femms
ret
EPILOGUE()

View File

@@ -0,0 +1,130 @@
dnl AMD K6 mpn_lshift -- mpn left shift.
dnl Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C K6: 3.0 cycles/limb
C mp_limb_t mpn_lshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
C unsigned shift);
C
C The loop runs at 3 cycles/limb, limited by decoding and by having 3 mmx
C instructions. This is despite every second fetch being unaligned.
defframe(PARAM_SHIFT,16)
defframe(PARAM_SIZE, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
TEXT
ALIGN(32)
PROLOGUE(mpn_lshift)
deflit(`FRAME',0)
C The 1 limb case can be done without the push %ebx, but it's then
C still the same speed. The push is left as a free helping hand for
C the two_or_more code.
movl PARAM_SIZE, %eax
pushl %ebx FRAME_pushl()
movl PARAM_SRC, %ebx
decl %eax
movl PARAM_SHIFT, %ecx
jnz L(two_or_more)
movl (%ebx), %edx C src limb
movl PARAM_DST, %ebx
shldl( %cl, %edx, %eax) C return value
shll %cl, %edx
movl %edx, (%ebx) C dst limb
popl %ebx
ret
ALIGN(16) C avoid offset 0x1f
nop C avoid bad cache line crossing
L(two_or_more):
C eax size-1
C ebx src
C ecx shift
C edx
movl (%ebx,%eax,4), %edx C src high limb
negl %ecx
movd PARAM_SHIFT, %mm6
addl $32, %ecx C 32-shift
shrl %cl, %edx
movd %ecx, %mm7
movl PARAM_DST, %ecx
L(top):
C eax counter, size-1 to 1
C ebx src
C ecx dst
C edx retval
C
C mm0 scratch
C mm6 shift
C mm7 32-shift
movq -4(%ebx,%eax,4), %mm0
decl %eax
psrlq %mm7, %mm0
movd %mm0, 4(%ecx,%eax,4)
jnz L(top)
movd (%ebx), %mm0
popl %ebx
psllq %mm6, %mm0
movl %edx, %eax
movd %mm0, (%ecx)
emms
ret
EPILOGUE()

View File

@@ -0,0 +1,236 @@
dnl AMD K6-2 mpn_popcount, mpn_hamdist -- mpn bit population count and
dnl hamming distance.
dnl Copyright 2000-2002 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C popcount hamdist
C K6-2: 9.0 11.5 cycles/limb
C K6: 12.5 13.0
C unsigned long mpn_popcount (mp_srcptr src, mp_size_t size);
C unsigned long mpn_hamdist (mp_srcptr src, mp_srcptr src2, mp_size_t size);
C
C The code here isn't optimal, but it's already a 2x speedup over the plain
C integer mpn/generic/popcount.c,hamdist.c.
ifdef(`OPERATION_popcount',,
`ifdef(`OPERATION_hamdist',,
`m4_error(`Need OPERATION_popcount or OPERATION_hamdist
')m4exit(1)')')
define(HAM,
m4_assert_numargs(1)
`ifdef(`OPERATION_hamdist',`$1')')
define(POP,
m4_assert_numargs(1)
`ifdef(`OPERATION_popcount',`$1')')
HAM(`
defframe(PARAM_SIZE, 12)
defframe(PARAM_SRC2, 8)
defframe(PARAM_SRC, 4)
define(M4_function,mpn_hamdist)
')
POP(`
defframe(PARAM_SIZE, 8)
defframe(PARAM_SRC, 4)
define(M4_function,mpn_popcount)
')
MULFUNC_PROLOGUE(mpn_popcount mpn_hamdist)
ifdef(`PIC',,`
dnl non-PIC
RODATA
ALIGN(8)
L(rodata_AAAAAAAAAAAAAAAA):
.long 0xAAAAAAAA
.long 0xAAAAAAAA
L(rodata_3333333333333333):
.long 0x33333333
.long 0x33333333
L(rodata_0F0F0F0F0F0F0F0F):
.long 0x0F0F0F0F
.long 0x0F0F0F0F
L(rodata_000000FF000000FF):
.long 0x000000FF
.long 0x000000FF
')
TEXT
ALIGN(32)
POP(`ifdef(`PIC', `
C avoid shrl crossing a 32-byte boundary
nop')')
PROLOGUE(M4_function)
deflit(`FRAME',0)
movl PARAM_SIZE, %ecx
ifdef(`PIC',`
movl $0xAAAAAAAA, %eax
movl $0x33333333, %edx
movd %eax, %mm7
movd %edx, %mm6
movl $0x0F0F0F0F, %eax
movl $0x000000FF, %edx
punpckldq %mm7, %mm7
punpckldq %mm6, %mm6
movd %eax, %mm5
movd %edx, %mm4
punpckldq %mm5, %mm5
punpckldq %mm4, %mm4
',`
movq L(rodata_AAAAAAAAAAAAAAAA), %mm7
movq L(rodata_3333333333333333), %mm6
movq L(rodata_0F0F0F0F0F0F0F0F), %mm5
movq L(rodata_000000FF000000FF), %mm4
')
define(REG_AAAAAAAAAAAAAAAA, %mm7)
define(REG_3333333333333333, %mm6)
define(REG_0F0F0F0F0F0F0F0F, %mm5)
define(REG_000000FF000000FF, %mm4)
movl PARAM_SRC, %eax
HAM(` movl PARAM_SRC2, %edx')
pxor %mm2, %mm2 C total
shrl %ecx
jnc L(top)
Zdisp( movd, 0,(%eax,%ecx,8), %mm1)
HAM(`
Zdisp( movd, 0,(%edx,%ecx,8), %mm0)
pxor %mm0, %mm1
')
incl %ecx
jmp L(loaded)
ALIGN(16)
POP(` nop C alignment to avoid crossing 32-byte boundaries')
L(top):
C eax src
C ebx
C ecx counter, qwords, decrementing
C edx [hamdist] src2
C
C mm0 (scratch)
C mm1 (scratch)
C mm2 total (low dword)
C mm3
C mm4 \
C mm5 | special constants
C mm6 |
C mm7 /
movq -8(%eax,%ecx,8), %mm1
HAM(` pxor -8(%edx,%ecx,8), %mm1')
L(loaded):
movq %mm1, %mm0
pand REG_AAAAAAAAAAAAAAAA, %mm1
psrlq $1, %mm1
HAM(` nop C code alignment')
psubd %mm1, %mm0 C bit pairs
HAM(` nop C code alignment')
movq %mm0, %mm1
psrlq $2, %mm0
pand REG_3333333333333333, %mm0
pand REG_3333333333333333, %mm1
paddd %mm1, %mm0 C nibbles
movq %mm0, %mm1
psrlq $4, %mm0
pand REG_0F0F0F0F0F0F0F0F, %mm0
pand REG_0F0F0F0F0F0F0F0F, %mm1
paddd %mm1, %mm0 C bytes
movq %mm0, %mm1
psrlq $8, %mm0
paddb %mm1, %mm0 C words
movq %mm0, %mm1
psrlq $16, %mm0
paddd %mm1, %mm0 C dwords
pand REG_000000FF000000FF, %mm0
paddd %mm0, %mm2 C low to total
psrlq $32, %mm0
paddd %mm0, %mm2 C high to total
loop L(top)
movd %mm2, %eax
emms_or_femms
ret
EPILOGUE()

View File

@@ -0,0 +1,130 @@
dnl AMD K6 mpn_rshift -- mpn right shift.
dnl Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C K6: 3.0 cycles/limb
C mp_limb_t mpn_rshift (mp_ptr dst, mp_srcptr src, mp_size_t size,
C unsigned shift);
C
C The loop runs at 3 cycles/limb, limited by decoding and by having 3 mmx
C instructions. This is despite every second fetch being unaligned.
defframe(PARAM_SHIFT,16)
defframe(PARAM_SIZE, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
deflit(`FRAME',0)
TEXT
ALIGN(32)
PROLOGUE(mpn_rshift)
deflit(`FRAME',0)
C The 1 limb case can be done without the push %ebx, but it's then
C still the same speed. The push is left as a free helping hand for
C the two_or_more code.
movl PARAM_SIZE, %eax
pushl %ebx FRAME_pushl()
movl PARAM_SRC, %ebx
decl %eax
movl PARAM_SHIFT, %ecx
jnz L(two_or_more)
movl (%ebx), %edx C src limb
movl PARAM_DST, %ebx
shrdl( %cl, %edx, %eax) C return value
shrl %cl, %edx
movl %edx, (%ebx) C dst limb
popl %ebx
ret
ALIGN(16) C avoid offset 0x1f
L(two_or_more):
C eax size-1
C ebx src
C ecx shift
C edx
movl (%ebx), %edx C src low limb
negl %ecx
addl $32, %ecx C 32-shift
movd PARAM_SHIFT, %mm6
shll %cl, %edx C retval
movl PARAM_DST, %ecx
leal (%ebx,%eax,4), %ebx
leal -4(%ecx,%eax,4), %ecx
negl %eax
L(simple):
C eax counter (negative)
C ebx &src[size-1]
C ecx &dst[size-1]
C edx retval
C
C mm0 scratch
C mm6 shift
Zdisp( movq, 0,(%ebx,%eax,4), %mm0)
incl %eax
psrlq %mm6, %mm0
Zdisp( movd, %mm0, 0,(%ecx,%eax,4))
jnz L(simple)
movq %mm0, (%ecx)
movl %edx, %eax
popl %ebx
emms
ret
EPILOGUE()

View File

@@ -0,0 +1,190 @@
dnl AMD K6 mpn_mod_34lsub1 -- mpn remainder modulo 2**24-1.
dnl Copyright 2000-2002 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C K6: 2.66 cycles/limb
C mp_limb_t mpn_mod_34lsub1 (mp_srcptr src, mp_size_t size)
C
C An attempt was made to use a loop like
C
C L(top):
C adcl (%edx), %eax
C adcl 4(%edx), %ebx
C adcl 8(%edx), %esi
C leal 12(%edx), %edx
C loop L(top)
C
C with %ecx starting from floor(size/3), but it still measured 2.66 c/l.
C The form used instead can save about 6 cycles by not dividing by 3.
C
C In the code used, putting the "leal"s at the top of the loop is necessary
C for the claimed speed, anywhere else costs an extra cycle per loop.
C Perhaps a tight loop like this needs short decode instructions at the
C branch target, which would explain the leal/loop form above taking 8
C cycles instead of 7 too.
defframe(PARAM_SIZE, 8)
defframe(PARAM_SRC, 4)
dnl re-use parameter space
define(SAVE_EBX, `PARAM_SIZE')
define(SAVE_ESI, `PARAM_SRC')
TEXT
ALIGN(16)
PROLOGUE(mpn_mod_34lsub1)
deflit(`FRAME',0)
movl PARAM_SIZE, %eax
movl PARAM_SRC, %edx
subl $2, %eax
ja L(three_or_more)
Zdisp( movl, 0,(%edx), %eax) C avoid code cache line boundary
jne L(one)
movl %eax, %ecx
movl 4(%edx), %edx
shrl $24, %eax C src[0] high
andl $0x00FFFFFF, %ecx C src[0] low
addl %ecx, %eax
movl %edx, %ecx
shll $8, %edx
andl $0x00FFFF00, %edx C src[1] high
shrl $16, %ecx C src[1] low
addl %ecx, %eax
addl %edx, %eax
L(one):
ret
L(three_or_more):
C eax size-2
C ebx
C ecx
C edx src
movl %ebx, SAVE_EBX
xorl %ebx, %ebx
movl %esi, SAVE_ESI
pushl %edi FRAME_pushl()
xorl %esi, %esi
xorl %edi, %edi C and clear carry flag
L(top):
C eax counter, limbs
C ebx acc 0mod3
C ecx
C edx src, incrementing
C esi acc 1mod3
C edi acc 2mod3
C ebp
leal -2(%eax), %eax
leal 12(%edx), %edx
adcl -12(%edx), %ebx
adcl -8(%edx), %esi
adcl -4(%edx), %edi
decl %eax
jg L(top)
C ecx is -3, -2 or -1 representing 0, 1 or 2 more limbs, respectively
movb $0, %cl
incl %eax
js L(combine) C 0 more
Zdisp( adcl, 0,(%edx), %ebx) C avoid code cache line crossings
movb $8, %cl
decl %eax
js L(combine) C 1 more
adcl 4(%edx), %esi
movb $16, %cl
L(combine):
sbbl %edx, %edx
shll %cl, %edx C carry
movl %ebx, %eax C 0mod3
shrl $24, %eax C 0mod3 high
andl $0x00FFFFFF, %ebx C 0mod3 low
subl %edx, %eax C apply carry
movl %esi, %ecx C 1mod3
shrl $16, %esi C 1mod3 high
addl %ebx, %eax C apply 0mod3 low
andl $0x0000FFFF, %ecx
addl %esi, %eax C apply 1mod3 high
shll $8, %ecx C 1mod3 low
movl %edi, %edx C 2mod3
shrl $8, %edx C 2mod3 high
addl %ecx, %eax C apply 1mod3 low
addl %edx, %eax C apply 2mod3 high
andl $0x000000FF, %edi
shll $16, %edi C 2mod3 low
movl SAVE_EBX, %ebx
addl %edi, %eax C apply 2mod3 low
movl SAVE_ESI, %esi
popl %edi
ret
EPILOGUE()

View File

@@ -0,0 +1,176 @@
dnl AMD K6 mpn_modexact_1_odd -- exact division style remainder.
dnl Copyright 2000-2003, 2007 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C K6: 10.0 cycles/limb
C mp_limb_t mpn_modexact_1_odd (mp_srcptr src, mp_size_t size,
C mp_limb_t divisor);
C mp_limb_t mpn_modexact_1c_odd (mp_srcptr src, mp_size_t size,
C mp_limb_t divisor, mp_limb_t carry);
C
C A special case for high<divisor at the end measured only about 4 cycles
C faster, and so isn't used.
C
C A special case for size==1 using a divl rather than the inverse measured
C only about 5 cycles faster, and so isn't used. When size==1 and
C high<divisor it can skip a division and be a full 24 cycles faster, but
C this isn't an important case.
defframe(PARAM_CARRY, 16)
defframe(PARAM_DIVISOR,12)
defframe(PARAM_SIZE, 8)
defframe(PARAM_SRC, 4)
TEXT
ALIGN(32)
PROLOGUE(mpn_modexact_1c_odd)
deflit(`FRAME',0)
movl PARAM_DIVISOR, %ecx
pushl %esi FRAME_pushl()
movl PARAM_CARRY, %edx
jmp L(start_1c)
EPILOGUE()
ALIGN(16)
PROLOGUE(mpn_modexact_1_odd)
deflit(`FRAME',0)
movl PARAM_DIVISOR, %ecx
pushl %esi FRAME_pushl()
xorl %edx, %edx
L(start_1c):
pushl %edi FRAME_pushl()
shrl %ecx C d/2
movl PARAM_DIVISOR, %esi
andl $127, %ecx C d/2, 7 bits
pushl %ebp FRAME_pushl()
ifdef(`PIC',`
LEA( binvert_limb_table, %edi)
Zdisp( movzbl, 0,(%ecx,%edi), %edi) C inv 8 bits
',`
movzbl binvert_limb_table(%ecx), %edi C inv 8 bits
')
leal (%edi,%edi), %ecx C 2*inv
imull %edi, %edi C inv*inv
movl PARAM_SRC, %eax
movl PARAM_SIZE, %ebp
imull %esi, %edi C inv*inv*d
pushl %ebx FRAME_pushl()
leal (%eax,%ebp,4), %ebx C src end
subl %edi, %ecx C inv = 2*inv - inv*inv*d
leal (%ecx,%ecx), %edi C 2*inv
imull %ecx, %ecx C inv*inv
movl (%eax), %eax C src low limb
negl %ebp C -size
imull %esi, %ecx C inv*inv*d
subl %ecx, %edi C inv = 2*inv - inv*inv*d
ASSERT(e,` C d*inv == 1 mod 2^GMP_LIMB_BITS
pushl %eax
movl %esi, %eax
imull %edi, %eax
cmpl $1, %eax
popl %eax')
jmp L(entry)
C Rotating the mul to the top of the loop saves 1 cycle, presumably by
C hiding the loop control under the imul latency.
C
C The run time is 10 cycles, but decoding is only 9 (and the dependent chain
C only 8). It's not clear how to get down to 9 cycles.
C
C The xor and rcl to handle the carry bit could be an sbb instead, with the
C the carry bit add becoming a sub, but that doesn't save anything.
L(top):
C eax (low product)
C ebx src end
C ecx carry bit, 0 or 1
C edx (high product, being carry limb)
C esi divisor
C edi inverse
C ebp counter, limbs, negative
mull %esi
movl (%ebx,%ebp,4), %eax
addl %ecx, %edx C apply carry bit to carry limb
L(entry):
xorl %ecx, %ecx
subl %edx, %eax C apply carry limb
rcll %ecx
imull %edi, %eax
incl %ebp
jnz L(top)
popl %ebx
popl %ebp
mull %esi
popl %edi
popl %esi
leal (%ecx,%edx), %eax
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,292 @@
dnl AMD K6 mpn_mul_1 -- mpn by limb multiply.
dnl Copyright 1999, 2000, 2002, 2005 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C P5
C P6 model 0-8,10-12 5.5
C P6 model 9 (Banias)
C P6 model 13 (Dothan) 4.87
C P4 model 0 (Willamette)
C P4 model 1 (?)
C P4 model 2 (Northwood)
C P4 model 3 (Prescott)
C P4 model 4 (Nocona)
C AMD K6 6.25
C AMD K7
C AMD K8
C mp_limb_t mpn_mul_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
C mp_limb_t multiplier);
C mp_limb_t mpn_mul_1c (mp_ptr dst, mp_srcptr src, mp_size_t size,
C mp_limb_t multiplier, mp_limb_t carry);
C
C Multiply src,size by mult and store the result in dst,size.
C Return the carry limb from the top of the result.
C
C mpn_mul_1c() accepts an initial carry for the calculation, it's added into
C the low limb of the result.
defframe(PARAM_CARRY, 20)
defframe(PARAM_MULTIPLIER,16)
defframe(PARAM_SIZE, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
dnl minimum 5 because the unrolled code can't handle less
deflit(UNROLL_THRESHOLD, 5)
TEXT
ALIGN(32)
PROLOGUE(mpn_mul_1c)
pushl %esi
deflit(`FRAME',4)
movl PARAM_CARRY, %esi
jmp L(start_nc)
EPILOGUE()
PROLOGUE(mpn_mul_1)
push %esi
deflit(`FRAME',4)
xorl %esi, %esi C initial carry
L(start_nc):
mov PARAM_SIZE, %ecx
push %ebx
FRAME_pushl()
movl PARAM_SRC, %ebx
push %edi
FRAME_pushl()
movl PARAM_DST, %edi
pushl %ebp
FRAME_pushl()
cmpl $UNROLL_THRESHOLD, %ecx
movl PARAM_MULTIPLIER, %ebp
jae L(unroll)
C code offset 0x22 here, close enough to aligned
L(simple):
C eax scratch
C ebx src
C ecx counter
C edx scratch
C esi carry
C edi dst
C ebp multiplier
C
C this loop 8 cycles/limb
movl (%ebx), %eax
addl $4, %ebx
mull %ebp
addl %esi, %eax
movl $0, %esi
adcl %edx, %esi
movl %eax, (%edi)
addl $4, %edi
loop L(simple)
popl %ebp
popl %edi
popl %ebx
movl %esi, %eax
popl %esi
ret
C -----------------------------------------------------------------------------
C The code for each limb is 6 cycles, with instruction decoding being the
C limiting factor. At 4 limbs/loop and 1 cycle/loop of overhead it's 6.25
C cycles/limb in total.
C
C The secret ingredient to get 6.25 is to start the loop with the mul and
C have the load/store pair at the end. Rotating the load/store to the top
C is an 0.5 c/l slowdown. (Some address generation effect probably.)
C
C The whole unrolled loop fits nicely in exactly 80 bytes.
ALIGN(16) C already aligned to 16 here actually
L(unroll):
movl (%ebx), %eax
leal -16(%ebx,%ecx,4), %ebx
leal -16(%edi,%ecx,4), %edi
subl $4, %ecx
negl %ecx
ALIGN(16) C one byte nop for this alignment
L(top):
C eax scratch
C ebx &src[size-4]
C ecx counter
C edx scratch
C esi carry
C edi &dst[size-4]
C ebp multiplier
mull %ebp
addl %esi, %eax
movl $0, %esi
adcl %edx, %esi
movl %eax, (%edi,%ecx,4)
movl 4(%ebx,%ecx,4), %eax
mull %ebp
addl %esi, %eax
movl $0, %esi
adcl %edx, %esi
movl %eax, 4(%edi,%ecx,4)
movl 8(%ebx,%ecx,4), %eax
mull %ebp
addl %esi, %eax
movl $0, %esi
adcl %edx, %esi
movl %eax, 8(%edi,%ecx,4)
movl 12(%ebx,%ecx,4), %eax
mull %ebp
addl %esi, %eax
movl $0, %esi
adcl %edx, %esi
movl %eax, 12(%edi,%ecx,4)
movl 16(%ebx,%ecx,4), %eax
addl $4, %ecx
js L(top)
C eax next src limb
C ebx &src[size-4]
C ecx 0 to 3 representing respectively 4 to 1 further limbs
C edx
C esi carry
C edi &dst[size-4]
testb $2, %cl
jnz L(finish_not_two)
mull %ebp
addl %esi, %eax
movl $0, %esi
adcl %edx, %esi
movl %eax, (%edi,%ecx,4)
movl 4(%ebx,%ecx,4), %eax
mull %ebp
addl %esi, %eax
movl $0, %esi
adcl %edx, %esi
movl %eax, 4(%edi,%ecx,4)
movl 8(%ebx,%ecx,4), %eax
addl $2, %ecx
L(finish_not_two):
testb $1, %cl
jnz L(finish_not_one)
mull %ebp
addl %esi, %eax
movl $0, %esi
adcl %edx, %esi
movl %eax, 8(%edi)
movl 12(%ebx), %eax
L(finish_not_one):
mull %ebp
addl %esi, %eax
popl %ebp
adcl $0, %edx
movl %eax, 12(%edi)
popl %edi
popl %ebx
movl %edx, %eax
popl %esi
ret
EPILOGUE()

View File

@@ -0,0 +1,612 @@
dnl AMD K6 mpn_mul_basecase -- multiply two mpn numbers.
dnl Copyright 1999-2003 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C K6: approx 9.0 cycles per cross product on 30x30 limbs (with 16 limbs/loop
C unrolling).
dnl K6: UNROLL_COUNT cycles/product (approx)
dnl 8 9.75
dnl 16 9.3
dnl 32 9.3
dnl Maximum possible with the current code is 32.
dnl
dnl With 16 the inner unrolled loop fits exactly in a 256 byte block, which
dnl might explain it's good performance.
deflit(UNROLL_COUNT, 16)
C void mpn_mul_basecase (mp_ptr wp,
C mp_srcptr xp, mp_size_t xsize,
C mp_srcptr yp, mp_size_t ysize);
C
C Calculate xp,xsize multiplied by yp,ysize, storing the result in
C wp,xsize+ysize.
C
C This routine is essentially the same as mpn/generic/mul_basecase.c, but
C it's faster because it does most of the mpn_addmul_1() entry code only
C once. The saving is about 10-20% on typical sizes coming from the
C Karatsuba multiply code.
C
C Enhancements:
C
C The mul_1 loop is about 8.5 c/l, which is slower than mpn_mul_1 at 6.25
C c/l. Could call mpn_mul_1 when ysize is big enough to make it worthwhile.
C
C The main unrolled addmul loop could be shared by mpn_addmul_1, using some
C extra stack setups and maybe 2 or 3 wasted cycles at the end. Code saving
C would be 256 bytes.
ifdef(`PIC',`
deflit(UNROLL_THRESHOLD, 8)
',`
deflit(UNROLL_THRESHOLD, 8)
')
defframe(PARAM_YSIZE,20)
defframe(PARAM_YP, 16)
defframe(PARAM_XSIZE,12)
defframe(PARAM_XP, 8)
defframe(PARAM_WP, 4)
TEXT
ALIGN(32)
PROLOGUE(mpn_mul_basecase)
deflit(`FRAME',0)
movl PARAM_XSIZE, %ecx
movl PARAM_YP, %eax
movl PARAM_XP, %edx
movl (%eax), %eax C yp low limb
cmpl $2, %ecx
ja L(xsize_more_than_two_limbs)
je L(two_by_something)
C one limb by one limb
movl (%edx), %edx C xp low limb
movl PARAM_WP, %ecx
mull %edx
movl %eax, (%ecx)
movl %edx, 4(%ecx)
ret
C -----------------------------------------------------------------------------
L(two_by_something):
decl PARAM_YSIZE
pushl %ebx
deflit(`FRAME',4)
movl PARAM_WP, %ebx
pushl %esi
deflit(`FRAME',8)
movl %eax, %ecx C yp low limb
movl (%edx), %eax C xp low limb
movl %edx, %esi C xp
jnz L(two_by_two)
C two limbs by one limb
mull %ecx
movl %eax, (%ebx)
movl 4(%esi), %eax
movl %edx, %esi C carry
mull %ecx
addl %eax, %esi
movl %esi, 4(%ebx)
adcl $0, %edx
movl %edx, 8(%ebx)
popl %esi
popl %ebx
ret
C -----------------------------------------------------------------------------
ALIGN(16)
L(two_by_two):
C eax xp low limb
C ebx wp
C ecx yp low limb
C edx
C esi xp
C edi
C ebp
deflit(`FRAME',8)
mull %ecx C xp[0] * yp[0]
push %edi
deflit(`FRAME',12)
movl %eax, (%ebx)
movl 4(%esi), %eax
movl %edx, %edi C carry, for wp[1]
mull %ecx C xp[1] * yp[0]
addl %eax, %edi
movl PARAM_YP, %ecx
adcl $0, %edx
movl %edi, 4(%ebx)
movl 4(%ecx), %ecx C yp[1]
movl 4(%esi), %eax C xp[1]
movl %edx, %edi C carry, for wp[2]
mull %ecx C xp[1] * yp[1]
addl %eax, %edi
adcl $0, %edx
movl (%esi), %eax C xp[0]
movl %edx, %esi C carry, for wp[3]
mull %ecx C xp[0] * yp[1]
addl %eax, 4(%ebx)
adcl %edx, %edi
adcl $0, %esi
movl %edi, 8(%ebx)
popl %edi
movl %esi, 12(%ebx)
popl %esi
popl %ebx
ret
C -----------------------------------------------------------------------------
ALIGN(16)
L(xsize_more_than_two_limbs):
C The first limb of yp is processed with a simple mpn_mul_1 style loop
C inline. Unrolling this doesn't seem worthwhile since it's only run once
C (whereas the addmul below is run ysize-1 many times). A call to the
C actual mpn_mul_1 will be slowed down by the call and parameter pushing and
C popping, and doesn't seem likely to be worthwhile on the typical 10-20
C limb operations the Karatsuba code calls here with.
C eax yp[0]
C ebx
C ecx xsize
C edx xp
C esi
C edi
C ebp
deflit(`FRAME',0)
pushl %edi defframe_pushl(SAVE_EDI)
pushl %ebp defframe_pushl(SAVE_EBP)
movl PARAM_WP, %edi
pushl %esi defframe_pushl(SAVE_ESI)
movl %eax, %ebp
pushl %ebx defframe_pushl(SAVE_EBX)
leal (%edx,%ecx,4), %ebx C xp end
xorl %esi, %esi
leal (%edi,%ecx,4), %edi C wp end of mul1
negl %ecx
L(mul1):
C eax scratch
C ebx xp end
C ecx counter, negative
C edx scratch
C esi carry
C edi wp end of mul1
C ebp multiplier
movl (%ebx,%ecx,4), %eax
mull %ebp
addl %esi, %eax
movl $0, %esi
adcl %edx, %esi
movl %eax, (%edi,%ecx,4)
incl %ecx
jnz L(mul1)
movl PARAM_YSIZE, %edx
movl %esi, (%edi) C final carry
movl PARAM_XSIZE, %ecx
decl %edx
jnz L(ysize_more_than_one_limb)
popl %ebx
popl %esi
popl %ebp
popl %edi
ret
L(ysize_more_than_one_limb):
cmpl $UNROLL_THRESHOLD, %ecx
movl PARAM_YP, %eax
jae L(unroll)
C -----------------------------------------------------------------------------
C Simple addmul loop.
C
C Using ebx and edi pointing at the ends of their respective locations saves
C a couple of instructions in the outer loop. The inner loop is still 11
C cycles, the same as the simple loop in aorsmul_1.asm.
C eax yp
C ebx xp end
C ecx xsize
C edx ysize-1
C esi
C edi wp end of mul1
C ebp
movl 4(%eax), %ebp C multiplier
negl %ecx
movl %ecx, PARAM_XSIZE C -xsize
xorl %esi, %esi C initial carry
leal 4(%eax,%edx,4), %eax C yp end
negl %edx
movl %eax, PARAM_YP
movl %edx, PARAM_YSIZE
jmp L(simple_outer_entry)
C aligning here saves a couple of cycles
ALIGN(16)
L(simple_outer_top):
C edx ysize counter, negative
movl PARAM_YP, %eax C yp end
xorl %esi, %esi C carry
movl PARAM_XSIZE, %ecx C -xsize
movl %edx, PARAM_YSIZE
movl (%eax,%edx,4), %ebp C yp limb multiplier
L(simple_outer_entry):
addl $4, %edi
L(simple_inner):
C eax scratch
C ebx xp end
C ecx counter, negative
C edx scratch
C esi carry
C edi wp end of this addmul
C ebp multiplier
movl (%ebx,%ecx,4), %eax
mull %ebp
addl %esi, %eax
movl $0, %esi
adcl $0, %edx
addl %eax, (%edi,%ecx,4)
adcl %edx, %esi
incl %ecx
jnz L(simple_inner)
movl PARAM_YSIZE, %edx
movl %esi, (%edi)
incl %edx
jnz L(simple_outer_top)
popl %ebx
popl %esi
popl %ebp
popl %edi
ret
C -----------------------------------------------------------------------------
C Unrolled loop.
C
C The unrolled inner loop is the same as in aorsmul_1.asm, see that code for
C some comments.
C
C VAR_COUNTER is for the inner loop, running from VAR_COUNTER_INIT down to
C 0, inclusive.
C
C VAR_JMP is the computed jump into the unrolled loop.
C
C PARAM_XP and PARAM_WP get offset appropriately for where the unrolled loop
C is entered.
C
C VAR_XP_LOW is the least significant limb of xp, which is needed at the
C start of the unrolled loop. This can't just be fetched through the xp
C pointer because of the offset applied to it.
C
C PARAM_YSIZE is the outer loop counter, going from -(ysize-1) up to -1,
C inclusive.
C
C PARAM_YP is offset appropriately so that the PARAM_YSIZE counter can be
C added to give the location of the next limb of yp, which is the multiplier
C in the unrolled loop.
C
C PARAM_WP is similarly offset so that the PARAM_YSIZE counter can be added
C to give the starting point in the destination for each unrolled loop (this
C point is one limb upwards for each limb of yp processed).
C
C Having PARAM_YSIZE count negative to zero means it's not necessary to
C store new values of PARAM_YP and PARAM_WP on each loop. Those values on
C the stack remain constant and on each loop an leal adjusts them with the
C PARAM_YSIZE counter value.
defframe(VAR_COUNTER, -20)
defframe(VAR_COUNTER_INIT, -24)
defframe(VAR_JMP, -28)
defframe(VAR_XP_LOW, -32)
deflit(VAR_STACK_SPACE, 16)
dnl For some strange reason using (%esp) instead of 0(%esp) is a touch
dnl slower in this code, hence the defframe empty-if-zero feature is
dnl disabled.
dnl
dnl If VAR_COUNTER is at (%esp), the effect is worse. In this case the
dnl unrolled loop is 255 instead of 256 bytes, but quite how this affects
dnl anything isn't clear.
dnl
define(`defframe_empty_if_zero_disabled',1)
L(unroll):
C eax yp (not used)
C ebx xp end (not used)
C ecx xsize
C edx ysize-1
C esi
C edi wp end of mul1 (not used)
C ebp
deflit(`FRAME', 16)
leal -2(%ecx), %ebp C one limb processed at start,
decl %ecx C and ebp is one less
shrl $UNROLL_LOG2, %ebp
negl %ecx
subl $VAR_STACK_SPACE, %esp
deflit(`FRAME', 16+VAR_STACK_SPACE)
andl $UNROLL_MASK, %ecx
movl %ecx, %esi
shll $4, %ecx
movl %ebp, VAR_COUNTER_INIT
negl %esi
C 15 code bytes per limb
ifdef(`PIC',`
call L(pic_calc)
L(unroll_here):
',`
leal L(unroll_entry) (%ecx,%esi,1), %ecx
')
movl PARAM_XP, %ebx
movl %ebp, VAR_COUNTER
movl PARAM_WP, %edi
movl %ecx, VAR_JMP
movl (%ebx), %eax
leal 4(%edi,%esi,4), %edi C wp adjust for unrolling and mul1
leal (%ebx,%esi,4), %ebx C xp adjust for unrolling
movl %eax, VAR_XP_LOW
movl %ebx, PARAM_XP
movl PARAM_YP, %ebx
leal (%edi,%edx,4), %ecx C wp adjust for ysize indexing
movl 4(%ebx), %ebp C multiplier (yp second limb)
leal 4(%ebx,%edx,4), %ebx C yp adjust for ysize indexing
movl %ecx, PARAM_WP
leal 1(%esi), %ecx C adjust parity for decl %ecx above
movl %ebx, PARAM_YP
negl %edx
movl %edx, PARAM_YSIZE
jmp L(unroll_outer_entry)
ifdef(`PIC',`
L(pic_calc):
C See mpn/x86/README about old gas bugs
leal (%ecx,%esi,1), %ecx
addl $L(unroll_entry)-L(unroll_here), %ecx
addl (%esp), %ecx
ret_internal
')
C -----------------------------------------------------------------------------
C Aligning here saves a couple of cycles per loop. Using 32 doesn't
C cost any extra space, since the inner unrolled loop below is
C aligned to 32.
ALIGN(32)
L(unroll_outer_top):
C edx ysize
movl PARAM_YP, %eax
movl %edx, PARAM_YSIZE C incremented ysize counter
movl PARAM_WP, %edi
movl VAR_COUNTER_INIT, %ebx
movl (%eax,%edx,4), %ebp C next multiplier
movl PARAM_XSIZE, %ecx
leal (%edi,%edx,4), %edi C adjust wp for where we are in yp
movl VAR_XP_LOW, %eax
movl %ebx, VAR_COUNTER
L(unroll_outer_entry):
mull %ebp
C using testb is a tiny bit faster than testl
testb $1, %cl
movl %eax, %ecx C low carry
movl VAR_JMP, %eax
movl %edx, %esi C high carry
movl PARAM_XP, %ebx
jnz L(unroll_noswap)
movl %ecx, %esi C high,low carry other way around
movl %edx, %ecx
L(unroll_noswap):
jmp *%eax
C -----------------------------------------------------------------------------
ALIGN(32)
L(unroll_top):
C eax scratch
C ebx xp
C ecx carry low
C edx scratch
C esi carry high
C edi wp
C ebp multiplier
C VAR_COUNTER loop counter
C
C 15 code bytes each limb
leal UNROLL_BYTES(%edi), %edi
L(unroll_entry):
deflit(CHUNK_COUNT,2)
forloop(`i', 0, UNROLL_COUNT/CHUNK_COUNT-1, `
deflit(`disp0', eval(i*CHUNK_COUNT*4))
deflit(`disp1', eval(disp0 + 4))
deflit(`disp2', eval(disp1 + 4))
movl disp1(%ebx), %eax
mull %ebp
Zdisp( addl, %ecx, disp0,(%edi))
adcl %eax, %esi
movl %edx, %ecx
jadcl0( %ecx)
movl disp2(%ebx), %eax
mull %ebp
addl %esi, disp1(%edi)
adcl %eax, %ecx
movl %edx, %esi
jadcl0( %esi)
')
decl VAR_COUNTER
leal UNROLL_BYTES(%ebx), %ebx
jns L(unroll_top)
movl PARAM_YSIZE, %edx
addl %ecx, UNROLL_BYTES(%edi)
adcl $0, %esi
incl %edx
movl %esi, UNROLL_BYTES+4(%edi)
jnz L(unroll_outer_top)
movl SAVE_ESI, %esi
movl SAVE_EBP, %ebp
movl SAVE_EDI, %edi
movl SAVE_EBX, %ebx
addl $FRAME, %esp
ret
EPILOGUE()

View File

@@ -0,0 +1,146 @@
dnl AMD K6 mpn_preinv_mod_1 -- mpn by 1 remainder, with pre-inverted divisor.
dnl Copyright 2000, 2002, 2003 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C K6: 18.0 cycles/limb
C mp_limb_t mpn_preinv_mod_1 (mp_srcptr src, mp_size_t size, mp_limb_t divisor,
C mp_limb_t inverse);
C
C This code is only 2 c/l faster than a simple divl, but that's 10% so it's
C considered worthwhile (just).
defframe(PARAM_INVERSE,16)
defframe(PARAM_DIVISOR,12)
defframe(PARAM_SIZE, 8)
defframe(PARAM_SRC, 4)
TEXT
ALIGN(32)
PROLOGUE(mpn_preinv_mod_1)
deflit(`FRAME',0)
ASSERT(ae,`cmpl $1, PARAM_SIZE')
ASSERT(nz,`testl $0x80000000, PARAM_DIVISOR')
movl PARAM_SIZE, %ecx
pushl %ebp FRAME_pushl()
movl PARAM_SRC, %ebp
pushl %edi FRAME_pushl()
movl PARAM_DIVISOR, %eax
pushl %esi FRAME_pushl()
movl -4(%ebp,%ecx,4), %esi C src high limb
pushl %ebx FRAME_pushl()
movl %edx, %edi C first n2 to cancel
subl %eax, %esi C first n1 = high-divisor
decl %ecx
jz L(done_sbbl)
L(top):
C eax scratch
C ebx n10, nadj, q1
C ecx counter, size to 1
C edx scratch
C esi n2
C edi old high, for underflow test
C ebp src
sbbl %edx, %edi C high n-(q1+1)*d, 0 or -1
L(entry):
andl PARAM_DIVISOR, %edi
L(q1_ff_top):
movl -4(%ebp,%ecx,4), %ebx
addl %esi, %edi C possible addback
movl %ebx, %esi C n10
sarl $31, %ebx C -n1 = 0 or -1
movl %edi, %eax C n2
movl PARAM_INVERSE, %edx
subl %ebx, %eax C n2+n1
mull %edx C m*(n2+n1)
andl PARAM_DIVISOR, %ebx C -n1 & d
addl %esi, %ebx C nadj = n10 + (-n1&d), ignoring overflow
addl %ebx, %eax C low m*(n2+n1) + nadj, giving carry flag
leal 1(%edi), %ebx C n2+1
adcl %ebx, %edx C 1+high(n2<<32+m*(n2+n1)+nadj) = q1+1
movl PARAM_DIVISOR, %eax C d
jz L(q1_ff)
mull %edx C (q1+1)*d
subl %eax, %esi C low n-(q1+1)*d
loop L(top)
L(done_sbbl):
sbbl %edx, %edi C high n-(q1+1)*d, 0 or -1
andl PARAM_DIVISOR, %edi
L(done_esi_edi):
popl %ebx
leal (%esi,%edi), %eax
popl %esi
popl %edi
popl %ebp
ret
C Special case for q1=0xFFFFFFFF, giving q=0xFFFFFFFF meaning the low dword
C of q*d is simply -d and the remainder n-q*d = n10+d. This is rarely
C reached.
L(q1_ff):
movl PARAM_DIVISOR, %edi
loop L(q1_ff_top)
jmp L(done_esi_edi)
EPILOGUE()

View File

@@ -0,0 +1,680 @@
dnl AMD K6 mpn_sqr_basecase -- square an mpn number.
dnl Copyright 1999-2002 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C K6: approx 4.7 cycles per cross product, or 9.2 cycles per triangular
C product (measured on the speed difference between 17 and 33 limbs,
C which is roughly the Karatsuba recursing range).
dnl SQR_TOOM2_THRESHOLD_MAX is the maximum SQR_TOOM2_THRESHOLD this
dnl code supports. This value is used only by the tune program to know
dnl what it can go up to. (An attempt to compile with a bigger value will
dnl trigger some m4_assert()s in the code, making the build fail.)
dnl
dnl The value is determined by requiring the displacements in the unrolled
dnl addmul to fit in single bytes. This means a maximum UNROLL_COUNT of
dnl 63, giving a maximum SQR_TOOM2_THRESHOLD of 66.
deflit(SQR_TOOM2_THRESHOLD_MAX, 66)
dnl Allow a value from the tune program to override config.m4.
ifdef(`SQR_TOOM2_THRESHOLD_OVERRIDE',
`define(`SQR_TOOM2_THRESHOLD',SQR_TOOM2_THRESHOLD_OVERRIDE)')
dnl UNROLL_COUNT is the number of code chunks in the unrolled addmul. The
dnl number required is determined by SQR_TOOM2_THRESHOLD, since
dnl mpn_sqr_basecase only needs to handle sizes < SQR_TOOM2_THRESHOLD.
dnl
dnl The first addmul is the biggest, and this takes the second least
dnl significant limb and multiplies it by the third least significant and
dnl up. Hence for a maximum operand size of SQR_TOOM2_THRESHOLD-1
dnl limbs, UNROLL_COUNT needs to be SQR_TOOM2_THRESHOLD-3.
m4_config_gmp_mparam(`SQR_TOOM2_THRESHOLD')
deflit(UNROLL_COUNT, eval(SQR_TOOM2_THRESHOLD-3))
C void mpn_sqr_basecase (mp_ptr dst, mp_srcptr src, mp_size_t size);
C
C The algorithm is essentially the same as mpn/generic/sqr_basecase.c, but a
C lot of function call overheads are avoided, especially when the given size
C is small.
C
C The code size might look a bit excessive, but not all of it is executed
C and so won't fill up the code cache. The 1x1, 2x2 and 3x3 special cases
C clearly apply only to those sizes; mid sizes like 10x10 only need part of
C the unrolled addmul; and big sizes like 35x35 that do need all of it will
C at least be getting value for money, because 35x35 spends something like
C 5780 cycles here.
C
C Different values of UNROLL_COUNT give slightly different speeds, between
C 9.0 and 9.2 c/tri-prod measured on the difference between 17 and 33 limbs.
C This isn't a big difference, but it's presumably some alignment effect
C which if understood could give a simple speedup.
defframe(PARAM_SIZE,12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
TEXT
ALIGN(32)
PROLOGUE(mpn_sqr_basecase)
deflit(`FRAME',0)
movl PARAM_SIZE, %ecx
movl PARAM_SRC, %eax
cmpl $2, %ecx
je L(two_limbs)
movl PARAM_DST, %edx
ja L(three_or_more)
C -----------------------------------------------------------------------------
C one limb only
C eax src
C ebx
C ecx size
C edx dst
movl (%eax), %eax
movl %edx, %ecx
mull %eax
movl %eax, (%ecx)
movl %edx, 4(%ecx)
ret
C -----------------------------------------------------------------------------
ALIGN(16)
L(two_limbs):
C eax src
C ebx
C ecx size
C edx dst
pushl %ebx
movl %eax, %ebx C src
deflit(`FRAME',4)
movl (%ebx), %eax
movl PARAM_DST, %ecx
mull %eax C src[0]^2
movl %eax, (%ecx)
movl 4(%ebx), %eax
movl %edx, 4(%ecx)
mull %eax C src[1]^2
movl %eax, 8(%ecx)
movl (%ebx), %eax
movl %edx, 12(%ecx)
movl 4(%ebx), %edx
mull %edx C src[0]*src[1]
addl %eax, 4(%ecx)
adcl %edx, 8(%ecx)
adcl $0, 12(%ecx)
popl %ebx
addl %eax, 4(%ecx)
adcl %edx, 8(%ecx)
adcl $0, 12(%ecx)
ret
C -----------------------------------------------------------------------------
L(three_or_more):
deflit(`FRAME',0)
cmpl $4, %ecx
jae L(four_or_more)
C -----------------------------------------------------------------------------
C three limbs
C eax src
C ecx size
C edx dst
pushl %ebx
movl %eax, %ebx C src
movl (%ebx), %eax
movl %edx, %ecx C dst
mull %eax C src[0] ^ 2
movl %eax, (%ecx)
movl 4(%ebx), %eax
movl %edx, 4(%ecx)
pushl %esi
mull %eax C src[1] ^ 2
movl %eax, 8(%ecx)
movl 8(%ebx), %eax
movl %edx, 12(%ecx)
pushl %edi
mull %eax C src[2] ^ 2
movl %eax, 16(%ecx)
movl (%ebx), %eax
movl %edx, 20(%ecx)
movl 4(%ebx), %edx
mull %edx C src[0] * src[1]
movl %eax, %esi
movl (%ebx), %eax
movl %edx, %edi
movl 8(%ebx), %edx
pushl %ebp
xorl %ebp, %ebp
mull %edx C src[0] * src[2]
addl %eax, %edi
movl 4(%ebx), %eax
adcl %edx, %ebp
movl 8(%ebx), %edx
mull %edx C src[1] * src[2]
addl %eax, %ebp
adcl $0, %edx
C eax will be dst[5]
C ebx
C ecx dst
C edx dst[4]
C esi dst[1]
C edi dst[2]
C ebp dst[3]
xorl %eax, %eax
addl %esi, %esi
adcl %edi, %edi
adcl %ebp, %ebp
adcl %edx, %edx
adcl $0, %eax
addl %esi, 4(%ecx)
adcl %edi, 8(%ecx)
adcl %ebp, 12(%ecx)
popl %ebp
popl %edi
adcl %edx, 16(%ecx)
popl %esi
popl %ebx
adcl %eax, 20(%ecx)
ASSERT(nc)
ret
C -----------------------------------------------------------------------------
defframe(SAVE_EBX, -4)
defframe(SAVE_ESI, -8)
defframe(SAVE_EDI, -12)
defframe(SAVE_EBP, -16)
defframe(VAR_COUNTER,-20)
defframe(VAR_JMP, -24)
deflit(STACK_SPACE, 24)
ALIGN(16)
L(four_or_more):
C eax src
C ebx
C ecx size
C edx dst
C esi
C edi
C ebp
C First multiply src[0]*src[1..size-1] and store at dst[1..size].
C
C A test was done calling mpn_mul_1 here to get the benefit of its unrolled
C loop, but this was only a tiny speedup; at 35 limbs it took 24 cycles off
C a 5780 cycle operation, which is not surprising since the loop here is 8
C c/l and mpn_mul_1 is 6.25 c/l.
subl $STACK_SPACE, %esp deflit(`FRAME',STACK_SPACE)
movl %edi, SAVE_EDI
leal 4(%edx), %edi
movl %ebx, SAVE_EBX
leal 4(%eax), %ebx
movl %esi, SAVE_ESI
xorl %esi, %esi
movl %ebp, SAVE_EBP
C eax
C ebx src+4
C ecx size
C edx
C esi
C edi dst+4
C ebp
movl (%eax), %ebp C multiplier
leal -1(%ecx), %ecx C size-1, and pad to a 16 byte boundary
ALIGN(16)
L(mul_1):
C eax scratch
C ebx src ptr
C ecx counter
C edx scratch
C esi carry
C edi dst ptr
C ebp multiplier
movl (%ebx), %eax
addl $4, %ebx
mull %ebp
addl %esi, %eax
movl $0, %esi
adcl %edx, %esi
movl %eax, (%edi)
addl $4, %edi
loop L(mul_1)
C Addmul src[n]*src[n+1..size-1] at dst[2*n-1...], for each n=1..size-2.
C
C The last two addmuls, which are the bottom right corner of the product
C triangle, are left to the end. These are src[size-3]*src[size-2,size-1]
C and src[size-2]*src[size-1]. If size is 4 then it's only these corner
C cases that need to be done.
C
C The unrolled code is the same as mpn_addmul_1(), see that routine for some
C comments.
C
C VAR_COUNTER is the outer loop, running from -(size-4) to -1, inclusive.
C
C VAR_JMP is the computed jump into the unrolled code, stepped by one code
C chunk each outer loop.
C
C K6 doesn't do any branch prediction on indirect jumps, which is good
C actually because it's a different target each time. The unrolled addmul
C is about 3 cycles/limb faster than a simple loop, so the 6 cycle cost of
C the indirect jump is quickly recovered.
dnl This value is also implicitly encoded in a shift and add.
dnl
deflit(CODE_BYTES_PER_LIMB, 15)
dnl With the unmodified &src[size] and &dst[size] pointers, the
dnl displacements in the unrolled code fit in a byte for UNROLL_COUNT
dnl values up to 31. Above that an offset must be added to them.
dnl
deflit(OFFSET,
ifelse(eval(UNROLL_COUNT>31),1,
eval((UNROLL_COUNT-31)*4),
0))
C eax
C ebx &src[size]
C ecx
C edx
C esi carry
C edi &dst[size]
C ebp
movl PARAM_SIZE, %ecx
movl %esi, (%edi)
subl $4, %ecx
jz L(corner)
movl %ecx, %edx
ifelse(OFFSET,0,,
` subl $OFFSET, %ebx')
shll $4, %ecx
ifelse(OFFSET,0,,
` subl $OFFSET, %edi')
negl %ecx
ifdef(`PIC',`
call L(pic_calc)
L(here):
',`
leal L(unroll_inner_end)-eval(2*CODE_BYTES_PER_LIMB)(%ecx,%edx), %ecx
')
negl %edx
C The calculated jump mustn't be before the start of the available
C code. This is the limitation UNROLL_COUNT puts on the src operand
C size, but checked here using the jump address directly.
C
ASSERT(ae,`
movl_text_address( L(unroll_inner_start), %eax)
cmpl %eax, %ecx
')
C -----------------------------------------------------------------------------
ALIGN(16)
L(unroll_outer_top):
C eax
C ebx &src[size], constant
C ecx VAR_JMP
C edx VAR_COUNTER, limbs, negative
C esi high limb to store
C edi dst ptr, high of last addmul
C ebp
movl -12+OFFSET(%ebx,%edx,4), %ebp C multiplier
movl %edx, VAR_COUNTER
movl -8+OFFSET(%ebx,%edx,4), %eax C first limb of multiplicand
mull %ebp
testb $1, %cl
movl %edx, %esi C high carry
movl %ecx, %edx C jump
movl %eax, %ecx C low carry
leal CODE_BYTES_PER_LIMB(%edx), %edx
movl %edx, VAR_JMP
leal 4(%edi), %edi
C A branch-free version of this using some xors was found to be a
C touch slower than just a conditional jump, despite the jump
C switching between taken and not taken on every loop.
ifelse(eval(UNROLL_COUNT%2),0,
jz,jnz) L(unroll_noswap)
movl %esi, %eax C high,low carry other way around
movl %ecx, %esi
movl %eax, %ecx
L(unroll_noswap):
jmp *%edx
C Must be on an even address here so the low bit of the jump address
C will indicate which way around ecx/esi should start.
C
C An attempt was made at padding here to get the end of the unrolled
C code to come out on a good alignment, to save padding before
C L(corner). This worked, but turned out to run slower than just an
C ALIGN(2). The reason for this is not clear, it might be related
C to the different speeds on different UNROLL_COUNTs noted above.
ALIGN(2)
L(unroll_inner_start):
C eax scratch
C ebx src
C ecx carry low
C edx scratch
C esi carry high
C edi dst
C ebp multiplier
C
C 15 code bytes each limb
C ecx/esi swapped on each chunk
forloop(`i', UNROLL_COUNT, 1, `
deflit(`disp_src', eval(-i*4 + OFFSET))
deflit(`disp_dst', eval(disp_src - 4))
m4_assert(`disp_src>=-128 && disp_src<128')
m4_assert(`disp_dst>=-128 && disp_dst<128')
ifelse(eval(i%2),0,`
Zdisp( movl, disp_src,(%ebx), %eax)
mull %ebp
Zdisp( addl, %esi, disp_dst,(%edi))
adcl %eax, %ecx
movl %edx, %esi
jadcl0( %esi)
',`
dnl this one comes out last
Zdisp( movl, disp_src,(%ebx), %eax)
mull %ebp
Zdisp( addl, %ecx, disp_dst,(%edi))
adcl %eax, %esi
movl %edx, %ecx
jadcl0( %ecx)
')
')
L(unroll_inner_end):
addl %esi, -4+OFFSET(%edi)
movl VAR_COUNTER, %edx
jadcl0( %ecx)
movl %ecx, m4_empty_if_zero(OFFSET)(%edi)
movl VAR_JMP, %ecx
incl %edx
jnz L(unroll_outer_top)
ifelse(OFFSET,0,,`
addl $OFFSET, %ebx
addl $OFFSET, %edi
')
C -----------------------------------------------------------------------------
ALIGN(16)
L(corner):
C ebx &src[size]
C edi &dst[2*size-5]
movl -12(%ebx), %ebp
movl -8(%ebx), %eax
movl %eax, %ecx
mull %ebp
addl %eax, -4(%edi)
adcl $0, %edx
movl -4(%ebx), %eax
movl %edx, %esi
movl %eax, %ebx
mull %ebp
addl %esi, %eax
adcl $0, %edx
addl %eax, (%edi)
adcl $0, %edx
movl %edx, %esi
movl %ebx, %eax
mull %ecx
addl %esi, %eax
movl %eax, 4(%edi)
adcl $0, %edx
movl %edx, 8(%edi)
C -----------------------------------------------------------------------------
C Left shift of dst[1..2*size-2], the bit shifted out becomes dst[2*size-1].
C The loop measures about 6 cycles/iteration, though it looks like it should
C decode in 5.
L(lshift_start):
movl PARAM_SIZE, %ecx
movl PARAM_DST, %edi
subl $1, %ecx C size-1 and clear carry
movl PARAM_SRC, %ebx
movl %ecx, %edx
xorl %eax, %eax C ready for adcl
ALIGN(16)
L(lshift):
C eax
C ebx src (for later use)
C ecx counter, decrementing
C edx size-1 (for later use)
C esi
C edi dst, incrementing
C ebp
rcll 4(%edi)
rcll 8(%edi)
leal 8(%edi), %edi
loop L(lshift)
adcl %eax, %eax
movl %eax, 4(%edi) C dst most significant limb
movl (%ebx), %eax C src[0]
leal 4(%ebx,%edx,4), %ebx C &src[size]
subl %edx, %ecx C -(size-1)
C -----------------------------------------------------------------------------
C Now add in the squares on the diagonal, src[0]^2, src[1]^2, ...,
C src[size-1]^2. dst[0] hasn't yet been set at all yet, and just gets the
C low limb of src[0]^2.
mull %eax
movl %eax, (%edi,%ecx,8) C dst[0]
ALIGN(16)
L(diag):
C eax scratch
C ebx &src[size]
C ecx counter, negative
C edx carry
C esi scratch
C edi dst[2*size-2]
C ebp
movl (%ebx,%ecx,4), %eax
movl %edx, %esi
mull %eax
addl %esi, 4(%edi,%ecx,8)
adcl %eax, 8(%edi,%ecx,8)
adcl $0, %edx
incl %ecx
jnz L(diag)
movl SAVE_EBX, %ebx
movl SAVE_ESI, %esi
addl %edx, 4(%edi) C dst most significant limb
movl SAVE_EDI, %edi
movl SAVE_EBP, %ebp
addl $FRAME, %esp
ret
C -----------------------------------------------------------------------------
ifdef(`PIC',`
L(pic_calc):
C See mpn/x86/README about old gas bugs
addl (%esp), %ecx
addl $L(unroll_inner_end)-L(here)-eval(2*CODE_BYTES_PER_LIMB), %ecx
addl %edx, %ecx
ret_internal
')
EPILOGUE()

View File

@@ -0,0 +1,174 @@
Copyright 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/.
AMD K7 MPN SUBROUTINES
This directory contains code optimized for the AMD Athlon CPU.
The mmx subdirectory has routines using MMX instructions. All Athlons have
MMX, the separate directory is just so that configure can omit it if the
assembler doesn't support MMX.
STATUS
Times for the loops, with all code and data in L1 cache.
cycles/limb
mpn_add/sub_n 1.6
mpn_copyi 0.75 or 1.0 \ varying with data alignment
mpn_copyd 0.75 or 1.0 /
mpn_divrem_1 17.0 integer part, 15.0 fractional part
mpn_mod_1 17.0
mpn_divexact_by3 8.0
mpn_l/rshift 1.2
mpn_mul_1 3.4
mpn_addmul/submul_1 3.9
mpn_mul_basecase 4.42 cycles/crossproduct (approx)
mpn_sqr_basecase 2.3 cycles/crossproduct (approx)
or 4.55 cycles/triangleproduct (approx)
Prefetching of sources hasn't yet been tried.
NOTES
cmov, MMX, 3DNow and some extensions to MMX and 3DNow are available.
Write-allocate L1 data cache means prefetching of destinations is unnecessary.
Floating point multiplications can be done in parallel with integer
multiplications, but there doesn't seem to be any way to make use of this.
Unsigned "mul"s can be issued every 3 cycles. This suggests 3 is a limit on
the speed of the multiplication routines. The documentation shows mul
executing in IEU0 (or maybe in IEU0 and IEU1 together), so it might be that,
to get near 3 cycles code has to be arranged so that nothing else is issued
to IEU0. A busy IEU0 could explain why some code takes 4 cycles and other
apparently equivalent code takes 5.
OPTIMIZATIONS
Unrolled loops are used to reduce looping overhead. The unrolling is
configurable up to 32 limbs/loop for most routines and up to 64 for some.
The K7 has 64k L1 code cache so quite big unrolling is allowable.
Computed jumps into the unrolling are used to handle sizes not a multiple of
the unrolling. An attractive feature of this is that times increase
smoothly with operand size, but it may be that some routines should just
have simple loops to finish up, especially when PIC adds between 2 and 16
cycles to get %eip.
Position independent code is implemented using a call to get %eip for the
computed jumps and a ret is always done, rather than an addl $4,%esp or a
popl, so the CPU return address branch prediction stack stays synchronised
with the actual stack in memory.
Branch prediction, in absence of any history, will guess forward jumps are
not taken and backward jumps are taken. Where possible it's arranged that
the less likely or less important case is under a taken forward jump.
CODING
Instructions in general code have been shown grouped if they can execute
together, which means up to three direct-path instructions which have no
successive dependencies. K7 always decodes three and has out-of-order
execution, but the groupings show what slots might be available and what
dependency chains exist.
When there's vector-path instructions an effort is made to get triplets of
direct-path instructions in between them, even if there's dependencies,
since this maximizes decoding throughput and might save a cycle or two if
decoding is the limiting factor.
INSTRUCTIONS
adcl direct
divl 39 cycles back-to-back
lodsl,etc vector
loop 1 cycle vector (decl/jnz opens up one decode slot)
movd reg vector
movd mem direct
mull issue every 3 cycles, latency 4 cycles low word, 6 cycles high word
popl vector (use movl for more than one pop)
pushl direct, will pair with a load
shrdl %cl vector, 3 cycles, seems to be 3 decode too
xorl r,r false read dependency recognised
REFERENCES
"AMD Athlon Processor X86 Code Optimization Guide", AMD publication number
22007, revision K, February 2002. Available on-line,
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/22007.pdf
"3DNow Technology Manual", AMD publication number 21928G/0-March 2000.
This describes the femms and prefetch instructions. Available on-line,
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/21928.pdf
"AMD Extensions to the 3DNow and MMX Instruction Sets Manual", AMD
publication number 22466, revision D, March 2000. This describes
instructions added in the Athlon processor, such as pswapd and the extra
prefetch forms. Available on-line,
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/22466.pdf
"3DNow Instruction Porting Guide", AMD publication number 22621, revision B,
August 1999. This has some notes on general Athlon optimizations as well as
3DNow. Available on-line,
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/22621.pdf
----------------
Local variables:
mode: text
fill-column: 76
End:

View File

@@ -0,0 +1,196 @@
dnl AMD K7 mpn_addlsh1_n -- rp[] = up[] + (vp[] << 1)
dnl Copyright 2011 Free Software Foundation, Inc.
dnl Contributed to the GNU project by Torbjorn Granlund and Marco Bodrato.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C This is an attempt at an addlsh1_n for x86-32, not relying on sse2 insns.
C The innerloop is 2*3-way unrolled, which is best we can do with the available
C registers. It seems tricky to use the same structure for rsblsh1_n, since we
C cannot feed carry between operations there.
C cycles/limb
C P5
C P6 model 0-8,10-12
C P6 model 9 (Banias)
C P6 model 13 (Dothan) 5.4 (worse than add_n + lshift)
C P4 model 0 (Willamette)
C P4 model 1 (?)
C P4 model 2 (Northwood)
C P4 model 3 (Prescott)
C P4 model 4 (Nocona)
C Intel Atom 6
C AMD K6 ?
C AMD K7 2.5
C AMD K8
C This is a basic addlsh1_n for k7, atom, and perhaps some other x86-32
C processors. It uses 2*3-way unrolling, for good reasons. Unfortunately,
C that means we need an initial magic multiply.
C
C It is not clear how to do sublsh1_n or rsblsh1_n using the same pattern. We
C cannot do rsblsh1_n since we feed carry from the shift blocks to the
C add/subtract blocks, which is right for addition but reversed for
C subtraction. We could perhaps do sublsh1_n, with some extra move insns,
C without losing any time, since we're not issue limited but carry recurrency
C latency.
C
C Breaking carry recurrency might be a good idea. We would then need separate
C registers for the shift carry and add/subtract carry, which in turn would
C force us to 2*2-way unrolling.
defframe(PARAM_SIZE, 16)
defframe(PARAM_DBLD, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
dnl re-use parameter space
define(VAR_COUNT,`PARAM_DST')
define(VAR_TMP,`PARAM_DBLD')
ASM_START()
TEXT
ALIGN(8)
PROLOGUE(mpn_addlsh1_n)
deflit(`FRAME',0)
define(`rp', `%edi')
define(`up', `%esi')
define(`vp', `%ebp')
mov $0x2aaaaaab, %eax
push %ebx FRAME_pushl()
mov PARAM_SIZE, %ebx C size
push rp FRAME_pushl()
mov PARAM_DST, rp
mul %ebx
push up FRAME_pushl()
mov PARAM_SRC, up
not %edx C count = -(size\8)-1
mov %edx, VAR_COUNT
push vp FRAME_pushl()
mov PARAM_DBLD, vp
lea 3(%edx,%edx,2), %ecx C count*3+3 = -(size\6)*3
xor %edx, %edx
lea (%ebx,%ecx,2), %ebx C size + (count*3+3)*2 = size % 6
or %ebx, %ebx
jz L(exact)
L(oop):
ifdef(`CPU_P6',`
shr %edx ') C restore 2nd saved carry bit
mov (vp), %eax
adc %eax, %eax
rcr %edx C restore 1st saved carry bit
lea 4(vp), vp
adc (up), %eax
lea 4(up), up
adc %edx, %edx C save a carry bit in edx
ifdef(`CPU_P6',`
adc %edx, %edx ') C save another carry bit in edx
dec %ebx
mov %eax, (rp)
lea 4(rp), rp
jnz L(oop)
mov vp, VAR_TMP
L(exact):
incl VAR_COUNT
jz L(end)
ALIGN(16)
L(top):
ifdef(`CPU_P6',`
shr %edx ') C restore 2nd saved carry bit
mov (vp), %eax
adc %eax, %eax
mov 4(vp), %ebx
adc %ebx, %ebx
mov 8(vp), %ecx
adc %ecx, %ecx
rcr %edx C restore 1st saved carry bit
adc (up), %eax
mov %eax, (rp)
adc 4(up), %ebx
mov %ebx, 4(rp)
adc 8(up), %ecx
mov %ecx, 8(rp)
mov 12(vp), %eax
adc %eax, %eax
mov 16(vp), %ebx
adc %ebx, %ebx
mov 20(vp), %ecx
adc %ecx, %ecx
lea 24(vp), vp
adc %edx, %edx C save a carry bit in edx
adc 12(up), %eax
mov %eax, 12(rp)
adc 16(up), %ebx
mov %ebx, 16(rp)
adc 20(up), %ecx
lea 24(up), up
ifdef(`CPU_P6',`
adc %edx, %edx ') C save another carry bit in edx
mov %ecx, 20(rp)
incl VAR_COUNT
lea 24(rp), rp
jne L(top)
L(end):
pop vp FRAME_popl()
pop up FRAME_popl()
ifdef(`CPU_P6',`
xor %eax, %eax
shr $1, %edx
adc %edx, %eax
',`
adc $0, %edx
mov %edx, %eax
')
pop rp FRAME_popl()
pop %ebx FRAME_popl()
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,258 @@
dnl AMD K7 mpn_add_n/mpn_sub_n -- mpn add or subtract.
dnl Copyright 1999-2003 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C K7: 1.64 cycles/limb (at 16 limbs/loop).
dnl K7: UNROLL_COUNT cycles/limb
dnl 8 1.9
dnl 16 1.64
dnl 32 1.7
dnl 64 2.0
dnl Maximum possible with the current code is 64.
deflit(UNROLL_COUNT, 16)
ifdef(`OPERATION_add_n', `
define(M4_inst, adcl)
define(M4_function_n, mpn_add_n)
define(M4_function_nc, mpn_add_nc)
define(M4_description, add)
',`ifdef(`OPERATION_sub_n', `
define(M4_inst, sbbl)
define(M4_function_n, mpn_sub_n)
define(M4_function_nc, mpn_sub_nc)
define(M4_description, subtract)
',`m4_error(`Need OPERATION_add_n or OPERATION_sub_n
')')')
MULFUNC_PROLOGUE(mpn_add_n mpn_add_nc mpn_sub_n mpn_sub_nc)
C mp_limb_t M4_function_n (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size);
C mp_limb_t M4_function_nc (mp_ptr dst, mp_srcptr src1, mp_srcptr src2,
C mp_size_t size, mp_limb_t carry);
C
C Calculate src1,size M4_description src2,size, and store the result in
C dst,size. The return value is the carry bit from the top of the result (1
C or 0).
C
C The _nc version accepts 1 or 0 for an initial carry into the low limb of
C the calculation. Note values other than 1 or 0 here will lead to garbage
C results.
C
C This code runs at 1.64 cycles/limb, which might be the best possible with
C plain integer operations. Each limb is 2 loads and 1 store, any 2 of
C which can be done each cycle, leading to 1.5 c/l.
dnl Must have UNROLL_THRESHOLD >= 2, since the unrolled loop can't handle 1.
ifdef(`PIC',`
deflit(UNROLL_THRESHOLD, 8)
',`
deflit(UNROLL_THRESHOLD, 8)
')
defframe(PARAM_CARRY,20)
defframe(PARAM_SIZE, 16)
defframe(PARAM_SRC2, 12)
defframe(PARAM_SRC1, 8)
defframe(PARAM_DST, 4)
defframe(SAVE_EBP, -4)
defframe(SAVE_ESI, -8)
defframe(SAVE_EBX, -12)
defframe(SAVE_EDI, -16)
deflit(STACK_SPACE, 16)
TEXT
ALIGN(32)
deflit(`FRAME',0)
PROLOGUE(M4_function_nc)
movl PARAM_CARRY, %eax
jmp L(start)
EPILOGUE()
PROLOGUE(M4_function_n)
xorl %eax, %eax C carry
L(start):
movl PARAM_SIZE, %ecx
subl $STACK_SPACE, %esp
deflit(`FRAME',STACK_SPACE)
movl %edi, SAVE_EDI
movl %ebx, SAVE_EBX
cmpl $UNROLL_THRESHOLD, %ecx
movl PARAM_SRC2, %edx
movl PARAM_SRC1, %ebx
jae L(unroll)
movl PARAM_DST, %edi
leal (%ebx,%ecx,4), %ebx
leal (%edx,%ecx,4), %edx
leal (%edi,%ecx,4), %edi
negl %ecx
shrl %eax
C This loop in in a single 16 byte code block already, so no
C alignment necessary.
L(simple):
C eax scratch
C ebx src1
C ecx counter
C edx src2
C esi
C edi dst
C ebp
movl (%ebx,%ecx,4), %eax
M4_inst (%edx,%ecx,4), %eax
movl %eax, (%edi,%ecx,4)
incl %ecx
jnz L(simple)
movl $0, %eax
movl SAVE_EDI, %edi
movl SAVE_EBX, %ebx
setc %al
addl $STACK_SPACE, %esp
ret
C -----------------------------------------------------------------------------
C This is at 0x55, close enough to aligned.
L(unroll):
deflit(`FRAME',STACK_SPACE)
movl %ebp, SAVE_EBP
andl $-2, %ecx C size low bit masked out
andl $1, PARAM_SIZE C size low bit kept
movl %ecx, %edi
decl %ecx
movl PARAM_DST, %ebp
shrl $UNROLL_LOG2, %ecx
negl %edi
movl %esi, SAVE_ESI
andl $UNROLL_MASK, %edi
ifdef(`PIC',`
call L(pic_calc)
L(here):
',`
leal L(entry) (%edi,%edi,8), %esi C 9 bytes per
')
negl %edi
shrl %eax
leal ifelse(UNROLL_BYTES,256,128) (%ebx,%edi,4), %ebx
leal ifelse(UNROLL_BYTES,256,128) (%edx,%edi,4), %edx
leal ifelse(UNROLL_BYTES,256,128) (%ebp,%edi,4), %edi
jmp *%esi
ifdef(`PIC',`
L(pic_calc):
C See mpn/x86/README about old gas bugs
leal (%edi,%edi,8), %esi
addl $L(entry)-L(here), %esi
addl (%esp), %esi
ret_internal
')
C -----------------------------------------------------------------------------
ALIGN(32)
L(top):
C eax zero
C ebx src1
C ecx counter
C edx src2
C esi scratch (was computed jump)
C edi dst
C ebp scratch
leal UNROLL_BYTES(%edx), %edx
L(entry):
deflit(CHUNK_COUNT, 2)
forloop(i, 0, UNROLL_COUNT/CHUNK_COUNT-1, `
deflit(`disp0', eval(i*CHUNK_COUNT*4 ifelse(UNROLL_BYTES,256,-128)))
deflit(`disp1', eval(disp0 + 4))
Zdisp( movl, disp0,(%ebx), %esi)
movl disp1(%ebx), %ebp
Zdisp( M4_inst,disp0,(%edx), %esi)
Zdisp( movl, %esi, disp0,(%edi))
M4_inst disp1(%edx), %ebp
movl %ebp, disp1(%edi)
')
decl %ecx
leal UNROLL_BYTES(%ebx), %ebx
leal UNROLL_BYTES(%edi), %edi
jns L(top)
mov PARAM_SIZE, %esi
movl SAVE_EBP, %ebp
movl $0, %eax
decl %esi
js L(even)
movl (%ebx), %ecx
M4_inst UNROLL_BYTES(%edx), %ecx
movl %ecx, (%edi)
L(even):
movl SAVE_EDI, %edi
movl SAVE_EBX, %ebx
setc %al
movl SAVE_ESI, %esi
addl $STACK_SPACE, %esp
ret
EPILOGUE()

View File

@@ -0,0 +1,167 @@
dnl AMD K7 mpn_addmul_1/mpn_submul_1 -- add or subtract mpn multiple.
dnl Copyright 1999-2002, 2005, 2008 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C P5
C P6 model 0-8,10-12
C P6 model 9 (Banias) 6.5
C P6 model 13 (Dothan)
C P4 model 0 (Willamette)
C P4 model 1 (?)
C P4 model 2 (Northwood)
C P4 model 3 (Prescott)
C P4 model 4 (Nocona)
C AMD K6
C AMD K7 3.75
C AMD K8
C TODO
C * Improve feed-in and wind-down code. We beat the old code for all n != 1,
C but lose by 2x for n == 1.
ifdef(`OPERATION_addmul_1',`
define(`ADDSUB', `add')
define(`func', `mpn_addmul_1')
')
ifdef(`OPERATION_submul_1',`
define(`ADDSUB', `sub')
define(`func', `mpn_submul_1')
')
MULFUNC_PROLOGUE(mpn_addmul_1 mpn_submul_1)
ASM_START()
TEXT
ALIGN(16)
PROLOGUE(func)
add $-16, %esp
mov %ebp, (%esp)
mov %ebx, 4(%esp)
mov %esi, 8(%esp)
mov %edi, 12(%esp)
mov 20(%esp), %edi
mov 24(%esp), %esi
mov 28(%esp), %eax
mov 32(%esp), %ecx
mov %eax, %ebx
shr $2, %eax
mov %eax, 28(%esp)
mov (%esi), %eax
and $3, %ebx
jz L(b0)
cmp $2, %ebx
jz L(b2)
jg L(b3)
L(b1): lea -4(%esi), %esi
lea -4(%edi), %edi
mul %ecx
mov %eax, %ebx
mov %edx, %ebp
cmpl $0, 28(%esp)
jz L(cj1)
mov 8(%esi), %eax
jmp L(1)
L(b2): mul %ecx
mov %eax, %ebp
mov 4(%esi), %eax
mov %edx, %ebx
cmpl $0, 28(%esp)
jne L(2)
jmp L(cj2)
L(b3): lea -12(%esi), %esi
lea -12(%edi), %edi
mul %ecx
mov %eax, %ebx
mov %edx, %ebp
mov 16(%esi), %eax
incl 28(%esp)
jmp L(3)
L(b0): lea -8(%esi), %esi
lea -8(%edi), %edi
mul %ecx
mov %eax, %ebp
mov 12(%esi), %eax
mov %edx, %ebx
jmp L(0)
ALIGN(16)
L(top): lea 16(%edi), %edi
L(2): mul %ecx
ADDSUB %ebp, 0(%edi)
mov $0, %ebp
adc %eax, %ebx
mov 8(%esi), %eax
adc %edx, %ebp
L(1): mul %ecx
ADDSUB %ebx, 4(%edi)
mov $0, %ebx
adc %eax, %ebp
mov 12(%esi), %eax
adc %edx, %ebx
L(0): mul %ecx
ADDSUB %ebp, 8(%edi)
mov $0, %ebp
adc %eax, %ebx
adc %edx, %ebp
mov 16(%esi), %eax
L(3): mul %ecx
ADDSUB %ebx, 12(%edi)
adc %eax, %ebp
mov 20(%esi), %eax
lea 16(%esi), %esi
mov $0, %ebx
adc %edx, %ebx
decl 28(%esp)
jnz L(top)
L(end): lea 16(%edi), %edi
L(cj2): mul %ecx
ADDSUB %ebp, (%edi)
adc %eax, %ebx
adc $0, %edx
L(cj1): ADDSUB %ebx, 4(%edi)
adc $0, %edx
mov %edx, %eax
mov (%esp), %ebp
mov 4(%esp), %ebx
mov 8(%esp), %esi
mov 12(%esp), %edi
add $16, %esp
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,245 @@
dnl AMD K7 mpn_bdiv_q_1 -- mpn by limb exact division.
dnl Rearranged from mpn/x86/k7/dive_1.asm by Marco Bodrato.
dnl Copyright 2001, 2002, 2004, 2007, 2011 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C Athlon: 11.0
C Hammer: 9.0
C void mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
C mp_limb_t divisor);
C
C The dependent chain is mul+imul+sub for 11 cycles and that speed is
C achieved with no special effort. The load and shrld latencies are hidden
C by out of order execution.
C
C It's a touch faster on size==1 to use the mul-by-inverse than divl.
defframe(PARAM_SHIFT, 24)
defframe(PARAM_INVERSE,20)
defframe(PARAM_DIVISOR,16)
defframe(PARAM_SIZE, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
defframe(SAVE_EBX, -4)
defframe(SAVE_ESI, -8)
defframe(SAVE_EDI, -12)
defframe(SAVE_EBP, -16)
defframe(VAR_INVERSE, -20)
defframe(VAR_DST_END, -24)
deflit(STACK_SPACE, 24)
TEXT
C mp_limb_t
C mpn_pi1_bdiv_q_1 (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor,
C mp_limb_t inverse, int shift)
ALIGN(16)
PROLOGUE(mpn_pi1_bdiv_q_1)
deflit(`FRAME',0)
subl $STACK_SPACE, %esp deflit(`FRAME',STACK_SPACE)
movl PARAM_SHIFT, %ecx C shift count
movl %ebp, SAVE_EBP
movl PARAM_SIZE, %ebp
movl %esi, SAVE_ESI
movl PARAM_SRC, %esi
movl %edi, SAVE_EDI
movl PARAM_DST, %edi
movl %ebx, SAVE_EBX
leal (%esi,%ebp,4), %esi C src end
leal (%edi,%ebp,4), %edi C dst end
negl %ebp C -size
movl PARAM_INVERSE, %eax C inv
L(common):
movl %eax, VAR_INVERSE
movl (%esi,%ebp,4), %eax C src[0]
incl %ebp
jz L(one)
movl (%esi,%ebp,4), %edx C src[1]
shrdl( %cl, %edx, %eax)
movl %edi, VAR_DST_END
xorl %ebx, %ebx
jmp L(entry)
ALIGN(8)
L(top):
C eax q
C ebx carry bit, 0 or 1
C ecx shift
C edx
C esi src end
C edi dst end
C ebp counter, limbs, negative
mull PARAM_DIVISOR C carry limb in edx
movl -4(%esi,%ebp,4), %eax
movl (%esi,%ebp,4), %edi
shrdl( %cl, %edi, %eax)
subl %ebx, %eax C apply carry bit
setc %bl
movl VAR_DST_END, %edi
subl %edx, %eax C apply carry limb
adcl $0, %ebx
L(entry):
imull VAR_INVERSE, %eax
movl %eax, -4(%edi,%ebp,4)
incl %ebp
jnz L(top)
mull PARAM_DIVISOR C carry limb in edx
movl -4(%esi), %eax C src high limb
shrl %cl, %eax
movl SAVE_ESI, %esi
subl %ebx, %eax C apply carry bit
movl SAVE_EBX, %ebx
movl SAVE_EBP, %ebp
subl %edx, %eax C apply carry limb
imull VAR_INVERSE, %eax
movl %eax, -4(%edi)
movl SAVE_EDI, %edi
addl $STACK_SPACE, %esp
ret
L(one):
shrl %cl, %eax
movl SAVE_ESI, %esi
movl SAVE_EBX, %ebx
imull VAR_INVERSE, %eax
movl SAVE_EBP, %ebp
movl %eax, -4(%edi)
movl SAVE_EDI, %edi
addl $STACK_SPACE, %esp
ret
EPILOGUE()
C mp_limb_t mpn_bdiv_q_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
C mp_limb_t divisor);
C
ALIGN(16)
PROLOGUE(mpn_bdiv_q_1)
deflit(`FRAME',0)
movl PARAM_DIVISOR, %eax
subl $STACK_SPACE, %esp deflit(`FRAME',STACK_SPACE)
movl $-1, %ecx C shift count
movl %ebp, SAVE_EBP
movl PARAM_SIZE, %ebp
movl %esi, SAVE_ESI
movl %edi, SAVE_EDI
C If there's usually only one or two trailing zero bits then this
C should be faster than bsfl.
L(strip_twos):
incl %ecx
shrl %eax
jnc L(strip_twos)
movl %ebx, SAVE_EBX
leal 1(%eax,%eax), %ebx C d without twos
andl $127, %eax C d/2, 7 bits
ifdef(`PIC',`
LEA( binvert_limb_table, %edx)
movzbl (%eax,%edx), %eax C inv 8 bits
',`
movzbl binvert_limb_table(%eax), %eax C inv 8 bits
')
leal (%eax,%eax), %edx C 2*inv
movl %ebx, PARAM_DIVISOR C d without twos
imull %eax, %eax C inv*inv
movl PARAM_SRC, %esi
movl PARAM_DST, %edi
imull %ebx, %eax C inv*inv*d
subl %eax, %edx C inv = 2*inv - inv*inv*d
leal (%edx,%edx), %eax C 2*inv
imull %edx, %edx C inv*inv
leal (%esi,%ebp,4), %esi C src end
leal (%edi,%ebp,4), %edi C dst end
negl %ebp C -size
imull %ebx, %edx C inv*inv*d
subl %edx, %eax C inv = 2*inv - inv*inv*d
ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
pushl %eax FRAME_pushl()
imull PARAM_DIVISOR, %eax
cmpl $1, %eax
popl %eax FRAME_popl()')
jmp L(common)
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,208 @@
dnl AMD K7 mpn_divexact_1 -- mpn by limb exact division.
dnl Copyright 2001, 2002, 2004, 2007 Free Software Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/limb
C Athlon: 11.0
C Hammer: 9.0
C void mpn_divexact_1 (mp_ptr dst, mp_srcptr src, mp_size_t size,
C mp_limb_t divisor);
C
C The dependent chain is mul+imul+sub for 11 cycles and that speed is
C achieved with no special effort. The load and shrld latencies are hidden
C by out of order execution.
C
C It's a touch faster on size==1 to use the mul-by-inverse than divl.
defframe(PARAM_DIVISOR,16)
defframe(PARAM_SIZE, 12)
defframe(PARAM_SRC, 8)
defframe(PARAM_DST, 4)
defframe(SAVE_EBX, -4)
defframe(SAVE_ESI, -8)
defframe(SAVE_EDI, -12)
defframe(SAVE_EBP, -16)
defframe(VAR_INVERSE, -20)
defframe(VAR_DST_END, -24)
deflit(STACK_SPACE, 24)
TEXT
ALIGN(16)
PROLOGUE(mpn_divexact_1)
deflit(`FRAME',0)
movl PARAM_DIVISOR, %eax
subl $STACK_SPACE, %esp deflit(`FRAME',STACK_SPACE)
movl $-1, %ecx C shift count
movl %ebp, SAVE_EBP
movl PARAM_SIZE, %ebp
movl %esi, SAVE_ESI
movl %edi, SAVE_EDI
C If there's usually only one or two trailing zero bits then this
C should be faster than bsfl.
L(strip_twos):
incl %ecx
shrl %eax
jnc L(strip_twos)
movl %ebx, SAVE_EBX
leal 1(%eax,%eax), %ebx C d without twos
andl $127, %eax C d/2, 7 bits
ifdef(`PIC',`
LEA( binvert_limb_table, %edx)
movzbl (%eax,%edx), %eax C inv 8 bits
',`
movzbl binvert_limb_table(%eax), %eax C inv 8 bits
')
leal (%eax,%eax), %edx C 2*inv
movl %ebx, PARAM_DIVISOR C d without twos
imull %eax, %eax C inv*inv
movl PARAM_SRC, %esi
movl PARAM_DST, %edi
imull %ebx, %eax C inv*inv*d
subl %eax, %edx C inv = 2*inv - inv*inv*d
leal (%edx,%edx), %eax C 2*inv
imull %edx, %edx C inv*inv
leal (%esi,%ebp,4), %esi C src end
leal (%edi,%ebp,4), %edi C dst end
negl %ebp C -size
imull %ebx, %edx C inv*inv*d
subl %edx, %eax C inv = 2*inv - inv*inv*d
ASSERT(e,` C expect d*inv == 1 mod 2^GMP_LIMB_BITS
pushl %eax FRAME_pushl()
imull PARAM_DIVISOR, %eax
cmpl $1, %eax
popl %eax FRAME_popl()')
movl %eax, VAR_INVERSE
movl (%esi,%ebp,4), %eax C src[0]
incl %ebp
jz L(one)
movl (%esi,%ebp,4), %edx C src[1]
shrdl( %cl, %edx, %eax)
movl %edi, VAR_DST_END
xorl %ebx, %ebx
jmp L(entry)
ALIGN(8)
L(top):
C eax q
C ebx carry bit, 0 or 1
C ecx shift
C edx
C esi src end
C edi dst end
C ebp counter, limbs, negative
mull PARAM_DIVISOR C carry limb in edx
movl -4(%esi,%ebp,4), %eax
movl (%esi,%ebp,4), %edi
shrdl( %cl, %edi, %eax)
subl %ebx, %eax C apply carry bit
setc %bl
movl VAR_DST_END, %edi
subl %edx, %eax C apply carry limb
adcl $0, %ebx
L(entry):
imull VAR_INVERSE, %eax
movl %eax, -4(%edi,%ebp,4)
incl %ebp
jnz L(top)
mull PARAM_DIVISOR C carry limb in edx
movl -4(%esi), %eax C src high limb
shrl %cl, %eax
movl SAVE_ESI, %esi
subl %ebx, %eax C apply carry bit
movl SAVE_EBX, %ebx
movl SAVE_EBP, %ebp
subl %edx, %eax C apply carry limb
imull VAR_INVERSE, %eax
movl %eax, -4(%edi)
movl SAVE_EDI, %edi
addl $STACK_SPACE, %esp
ret
L(one):
shrl %cl, %eax
movl SAVE_ESI, %esi
movl SAVE_EBX, %ebx
imull VAR_INVERSE, %eax
movl SAVE_EBP, %ebp
movl %eax, -4(%edi)
movl SAVE_EDI, %edi
addl $STACK_SPACE, %esp
ret
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,107 @@
dnl x86 mpn_gcd_11 optimised for AMD K7.
dnl Contributed to the GNU project by by Kevin Ryde. Rehacked by Torbjorn
dnl Granlund.
dnl Copyright 2000-2002, 2005, 2009, 2011, 2012, 2014, 2015 Free Software
dnl Foundation, Inc.
dnl This file is part of the GNU MP Library.
dnl
dnl The GNU MP Library is free software; you can redistribute it and/or modify
dnl it under the terms of either:
dnl
dnl * the GNU Lesser General Public License as published by the Free
dnl Software Foundation; either version 3 of the License, or (at your
dnl option) any later version.
dnl
dnl or
dnl
dnl * the GNU General Public License as published by the Free Software
dnl Foundation; either version 2 of the License, or (at your option) any
dnl later version.
dnl
dnl or both in parallel, as here.
dnl
dnl The GNU MP Library is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
dnl for more details.
dnl
dnl You should have received copies of the GNU General Public License and the
dnl GNU Lesser General Public License along with the GNU MP Library. If not,
dnl see https://www.gnu.org/licenses/.
include(`../config.m4')
C cycles/bit (approx)
C AMD K7 5.31
C AMD K8,K9 5.33
C AMD K10 5.30
C AMD bd1 ?
C AMD bobcat 7.02
C Intel P4-2 10.1
C Intel P4-3/4 10.0
C Intel P6/13 5.88
C Intel core2 6.26
C Intel NHM 6.83
C Intel SBR 8.50
C Intel atom 8.90
C VIA nano ?
C Numbers measured with: speed -CD -s16-32 -t16 mpn_gcd_1
C ctz_table[n] is the number of trailing zeros on n, or MAXSHIFT if n==0.
deflit(MAXSHIFT, 6)
deflit(MASK, eval((m4_lshift(1,MAXSHIFT))-1))
DEF_OBJECT(ctz_table,64)
.byte MAXSHIFT
forloop(i,1,MASK,
` .byte m4_count_trailing_zeros(i)
')
END_OBJECT(ctz_table)
define(`u0', `%eax')
define(`v0', `%edx')
ASM_START()
TEXT
ALIGN(16)
PROLOGUE(mpn_gcd_11)
push %edi
push %esi
mov 12(%esp), %eax
mov 16(%esp), %edx
LEAL( ctz_table, %esi)
jmp L(odd)
ALIGN(16) C
L(top): cmovc( %ecx, %eax) C u = |v - u|
cmovc( %edi, %edx) C v = min(u,v)
L(mid): and $MASK, %ecx C
movzbl (%esi,%ecx), %ecx C
jz L(shift_alot) C
shr %cl, %eax C
L(odd): mov %eax, %edi C
mov %edx, %ecx C
sub %eax, %ecx C
sub %edx, %eax C
jnz L(top) C
L(end): mov %edx, %eax
pop %esi
pop %edi
ret
L(shift_alot):
shr $MAXSHIFT, %eax
mov %eax, %ecx
jmp L(mid)
EPILOGUE()
ASM_END()

View File

@@ -0,0 +1,263 @@
/* AMD K7 gmp-mparam.h -- Compiler/machine parameter header file.
Copyright 2019 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
or both in parallel, as here.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received copies of the GNU General Public License and the
GNU Lesser General Public License along with the GNU MP Library. If not,
see https://www.gnu.org/licenses/. */
#define GMP_LIMB_BITS 32
#define GMP_LIMB_BYTES 4
/* 2083 MHz K7 Barton */
/* FFT tuning limit = 49,770,069 */
/* Generated by tuneup.c, 2019-11-09, gcc 8.3 */
#define MOD_1_NORM_THRESHOLD 0 /* always */
#define MOD_1_UNNORM_THRESHOLD 3
#define MOD_1N_TO_MOD_1_1_THRESHOLD 8
#define MOD_1U_TO_MOD_1_1_THRESHOLD 4
#define MOD_1_1_TO_MOD_1_2_THRESHOLD 24
#define MOD_1_2_TO_MOD_1_4_THRESHOLD 0 /* never mpn_mod_1s_2p */
#define PREINV_MOD_1_TO_MOD_1_THRESHOLD 13
#define USE_PREINV_DIVREM_1 1 /* native */
/* From mati.gmplib.org, 2023-07-21 */
#define DIV_QR_1N_PI1_METHOD 3 /* 9.52% faster than 1 */
#define DIV_QR_1_NORM_THRESHOLD 4
#define DIV_QR_1_UNNORM_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIV_QR_2_PI2_THRESHOLD MP_SIZE_T_MAX /* never */
#define DIVEXACT_1_THRESHOLD 0 /* always (native) */
#define BMOD_1_TO_MOD_1_THRESHOLD 26
#define DIV_1_VS_MUL_1_PERCENT 182
#define MUL_TOOM22_THRESHOLD 28
#define MUL_TOOM33_THRESHOLD 85
#define MUL_TOOM44_THRESHOLD 154
#define MUL_TOOM6H_THRESHOLD 208
#define MUL_TOOM8H_THRESHOLD 309
#define MUL_TOOM32_TO_TOOM43_THRESHOLD 97
#define MUL_TOOM32_TO_TOOM53_THRESHOLD 99
#define MUL_TOOM42_TO_TOOM53_THRESHOLD 97
#define MUL_TOOM42_TO_TOOM63_THRESHOLD 102
#define MUL_TOOM43_TO_TOOM54_THRESHOLD 121
#define SQR_BASECASE_THRESHOLD 0 /* always (native) */
#define SQR_TOOM2_THRESHOLD 50
#define SQR_TOOM3_THRESHOLD 86
#define SQR_TOOM4_THRESHOLD 220
#define SQR_TOOM6_THRESHOLD 270
#define SQR_TOOM8_THRESHOLD 446
#define MULMID_TOOM42_THRESHOLD 50
#define MULMOD_BNM1_THRESHOLD 18
#define SQRMOD_BNM1_THRESHOLD 19
#define MUL_FFT_MODF_THRESHOLD 606 /* k = 5 */
#define MUL_FFT_TABLE3 \
{ { 606, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
{ 15, 5}, { 31, 6}, { 28, 7}, { 15, 6}, \
{ 32, 7}, { 17, 6}, { 35, 7}, { 19, 6}, \
{ 39, 7}, { 23, 6}, { 47, 7}, { 29, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
{ 23, 7}, { 49, 8}, { 31, 7}, { 63, 8}, \
{ 39, 9}, { 23, 8}, { 55, 9}, { 31, 8}, \
{ 63, 7}, { 127, 8}, { 71, 9}, { 39, 6}, \
{ 319, 9}, { 47, 8}, { 99, 6}, { 399, 9}, \
{ 55,10}, { 31, 9}, { 63, 8}, { 127, 9}, \
{ 79,10}, { 47, 9}, { 95, 8}, { 191, 4}, \
{ 3135, 5}, { 1599, 4}, { 3455, 6}, { 959, 8}, \
{ 247,10}, { 79, 9}, { 167,10}, { 95, 9}, \
{ 199,10}, { 111,11}, { 63,10}, { 127, 9}, \
{ 255,10}, { 143, 9}, { 287, 8}, { 575,10}, \
{ 159, 9}, { 319, 8}, { 639, 7}, { 1279,11}, \
{ 95,10}, { 191, 9}, { 383, 8}, { 799,10}, \
{ 207,12}, { 63,11}, { 127,10}, { 255, 9}, \
{ 511, 8}, { 1023,10}, { 271, 9}, { 543, 8}, \
{ 1087, 9}, { 575,11}, { 159, 9}, { 639,10}, \
{ 335, 9}, { 671, 8}, { 1343,10}, { 351, 9}, \
{ 703,11}, { 191,10}, { 383, 9}, { 799, 8}, \
{ 1599,11}, { 223,10}, { 447,12}, { 127,11}, \
{ 255,10}, { 511, 9}, { 1023,10}, { 543, 9}, \
{ 1087,10}, { 575, 9}, { 1151,10}, { 607, 9}, \
{ 1215,11}, { 319,10}, { 639, 9}, { 1343,10}, \
{ 703, 9}, { 1407,12}, { 191,11}, { 383,10}, \
{ 767, 9}, { 1535,10}, { 799, 9}, { 1599,10}, \
{ 831, 9}, { 1727, 8}, { 3455,11}, { 447,13}, \
{ 127,12}, { 255,11}, { 511,10}, { 1023, 9}, \
{ 2047,11}, { 543,10}, { 1087,11}, { 575,10}, \
{ 1151, 9}, { 2303,11}, { 607,10}, { 1215,12}, \
{ 319,11}, { 639,10}, { 1279,11}, { 671,10}, \
{ 1343,11}, { 703,10}, { 1407,11}, { 735,10}, \
{ 1471, 9}, { 2943,12}, { 383,11}, { 767,10}, \
{ 1535,11}, { 799,10}, { 1599,11}, { 831,10}, \
{ 1663,11}, { 863,10}, { 1727,12}, { 447,11}, \
{ 895,10}, { 1791,11}, { 959,10}, { 1919,13}, \
{ 255,12}, { 511,11}, { 1023,10}, { 2111,11}, \
{ 1087,10}, { 2175,12}, { 575,11}, { 1151,10}, \
{ 2303,11}, { 1215,10}, { 2431,12}, { 639,11}, \
{ 1343,12}, { 703,11}, { 1407,10}, { 2815,11}, \
{ 1471,10}, { 2943,13}, { 383,12}, { 767,11}, \
{ 1599,12}, { 831,11}, { 1663,10}, { 3327,11}, \
{ 1727,10}, { 3455,12}, { 895,11}, { 1855,12}, \
{ 959,11}, { 1919,10}, { 3839,14}, { 255,13}, \
{ 511,12}, { 1023,11}, { 2111,12}, { 1087,11}, \
{ 2239,12}, { 1151,11}, { 2303,12}, { 1215,11}, \
{ 2431,13}, { 639,12}, { 1343,11}, { 2687,12}, \
{ 1407,11}, { 2815,12}, { 1471,11}, { 2943,13}, \
{ 767,12}, { 1663,11}, { 3327,12}, { 1727,11}, \
{ 3455,13}, { 895,12}, { 1919,11}, { 3839,12}, \
{ 1983,14}, { 511,13}, { 1023,12}, { 2239,13}, \
{ 1151,12}, { 2495,13}, { 1279,12}, { 2687,13}, \
{ 1407,12}, { 2943,14}, { 767,13}, { 1535,12}, \
{ 3135,13}, { 1663,12}, { 3455,13}, { 1791,12}, \
{ 3583,13}, { 1919,12}, { 3967,15}, { 511,14}, \
{ 1023,13}, { 2047,12}, { 4095,13}, { 2175,12}, \
{ 4479,13}, { 2431,12}, { 4863,14}, { 1279,13}, \
{ 2559,12}, { 5119,13}, { 2943,12}, { 5887,14}, \
{ 1535,13}, { 3455,14}, { 1791,13}, { 3967,15}, \
{ 1023,14}, { 2047,13}, { 4479,14}, { 2303,13}, \
{ 4991,14}, { 2559,13}, { 5119,14}, { 2815,13}, \
{ 5887,15}, { 32768,16} }
#define MUL_FFT_TABLE3_SIZE 254
#define MUL_FFT_THRESHOLD 7552
#define SQR_FFT_MODF_THRESHOLD 492 /* k = 5 */
#define SQR_FFT_TABLE3 \
{ { 492, 5}, { 25, 6}, { 13, 5}, { 27, 6}, \
{ 28, 7}, { 15, 6}, { 32, 7}, { 17, 6}, \
{ 35, 7}, { 19, 6}, { 39, 7}, { 27, 8}, \
{ 15, 7}, { 35, 8}, { 19, 7}, { 41, 8}, \
{ 23, 7}, { 47, 8}, { 27, 9}, { 15, 8}, \
{ 31, 7}, { 63, 8}, { 39, 9}, { 23, 8}, \
{ 51, 9}, { 31, 8}, { 67, 9}, { 39, 8}, \
{ 79, 9}, { 47, 8}, { 95, 9}, { 55,10}, \
{ 31, 9}, { 79,10}, { 47, 9}, { 103,11}, \
{ 31,10}, { 63, 9}, { 135, 8}, { 271, 9}, \
{ 143,10}, { 79, 9}, { 167,10}, { 95, 9}, \
{ 191, 8}, { 383,10}, { 111,11}, { 63,10}, \
{ 127, 9}, { 255, 8}, { 511,10}, { 143, 9}, \
{ 303,10}, { 159, 9}, { 319, 8}, { 639,11}, \
{ 95,10}, { 191, 9}, { 383, 8}, { 767, 9}, \
{ 399,10}, { 207,12}, { 63,11}, { 127,10}, \
{ 255, 9}, { 511,10}, { 271, 9}, { 543, 8}, \
{ 1087,10}, { 287, 9}, { 575,10}, { 303,11}, \
{ 159,10}, { 319, 9}, { 639,10}, { 335, 9}, \
{ 671, 8}, { 1343, 9}, { 703,11}, { 191,10}, \
{ 383, 9}, { 767, 8}, { 1535,10}, { 399, 9}, \
{ 799, 8}, { 1599, 9}, { 863,11}, { 223,10}, \
{ 447,12}, { 127,11}, { 255,10}, { 511, 9}, \
{ 1087,10}, { 575, 9}, { 1215,10}, { 639, 9}, \
{ 1279,10}, { 671, 9}, { 1343,11}, { 351,10}, \
{ 703, 9}, { 1407,10}, { 735, 9}, { 1471,12}, \
{ 191,11}, { 383,10}, { 767, 9}, { 1535,10}, \
{ 799, 9}, { 1599,11}, { 415,10}, { 831, 9}, \
{ 1663,10}, { 863, 9}, { 1727, 8}, { 3455,11}, \
{ 447,10}, { 895,13}, { 127,12}, { 255,11}, \
{ 511,10}, { 1023, 9}, { 2047,11}, { 543,10}, \
{ 1087, 9}, { 2175,11}, { 575,10}, { 1151, 9}, \
{ 2303,11}, { 607,10}, { 1215, 9}, { 2431,12}, \
{ 319,11}, { 639,10}, { 1279,11}, { 671,10}, \
{ 1343,11}, { 703,10}, { 1407, 9}, { 2815,11}, \
{ 735,10}, { 1471, 9}, { 2943,12}, { 383,11}, \
{ 767,10}, { 1599,11}, { 831,10}, { 1663, 9}, \
{ 3327,10}, { 1727,12}, { 447,11}, { 895,10}, \
{ 1791,11}, { 959,10}, { 1919,13}, { 255,12}, \
{ 511,11}, { 1023,10}, { 2111,11}, { 1087,10}, \
{ 2175,12}, { 575,11}, { 1151,10}, { 2303,11}, \
{ 1215,10}, { 2431,12}, { 639,11}, { 1343,12}, \
{ 703,11}, { 1407,10}, { 2815,11}, { 1471,10}, \
{ 2943,13}, { 383,12}, { 767,11}, { 1599,12}, \
{ 831,11}, { 1663,10}, { 3327,11}, { 1727,10}, \
{ 3455,12}, { 895,11}, { 1791,12}, { 959,11}, \
{ 1919,10}, { 3839,14}, { 255,13}, { 511,12}, \
{ 1023,11}, { 2111,12}, { 1087,11}, { 2239,12}, \
{ 1151,11}, { 2303,12}, { 1215,11}, { 2431,13}, \
{ 639,12}, { 1343,11}, { 2687,12}, { 1407,11}, \
{ 2815,12}, { 1471,11}, { 2943,13}, { 767,12}, \
{ 1599,11}, { 3199,12}, { 1663,11}, { 3327,12}, \
{ 1727,11}, { 3455,13}, { 895,12}, { 1791,11}, \
{ 3583,12}, { 1919,11}, { 3839,12}, { 1983,14}, \
{ 511,13}, { 1023,12}, { 2239,13}, { 1151,12}, \
{ 2431,13}, { 1279,12}, { 2687,13}, { 1407,12}, \
{ 2943,14}, { 767,13}, { 1535,12}, { 3199,13}, \
{ 1663,12}, { 3455,13}, { 1791,12}, { 3583,13}, \
{ 1919,12}, { 3967,15}, { 511,14}, { 1023,13}, \
{ 2047,12}, { 4095,13}, { 2175,12}, { 4351,13}, \
{ 2431,14}, { 1279,13}, { 2943,12}, { 5887,14}, \
{ 1535,13}, { 3455,14}, { 1791,13}, { 3967,15}, \
{ 1023,14}, { 2047,13}, { 4351,14}, { 2303,13}, \
{ 4991,14}, { 2559,13}, { 5119,14}, { 2815,13}, \
{ 5887,15}, { 32768,16} }
#define SQR_FFT_TABLE3_SIZE 258
#define SQR_FFT_THRESHOLD 5504
#define MULLO_BASECASE_THRESHOLD 3
#define MULLO_DC_THRESHOLD 34
#define MULLO_MUL_N_THRESHOLD 14281
#define SQRLO_BASECASE_THRESHOLD 6
#define SQRLO_DC_THRESHOLD 137
#define SQRLO_SQR_THRESHOLD 10821
#define DC_DIV_QR_THRESHOLD 45
#define DC_DIVAPPR_Q_THRESHOLD 206
#define DC_BDIV_QR_THRESHOLD 39
#define DC_BDIV_Q_THRESHOLD 144
#define INV_MULMOD_BNM1_THRESHOLD 54
#define INV_NEWTON_THRESHOLD 202
#define INV_APPR_THRESHOLD 206
#define BINV_NEWTON_THRESHOLD 224
#define REDC_1_TO_REDC_N_THRESHOLD 63
#define MU_DIV_QR_THRESHOLD 1442
#define MU_DIVAPPR_Q_THRESHOLD 1387
#define MUPI_DIV_QR_THRESHOLD 82
#define MU_BDIV_QR_THRESHOLD 1308
#define MU_BDIV_Q_THRESHOLD 1387
#define POWM_SEC_TABLE 1,16,102,428,1221
#define GET_STR_DC_THRESHOLD 14
#define GET_STR_PRECOMPUTE_THRESHOLD 28
#define SET_STR_DC_THRESHOLD 254
#define SET_STR_PRECOMPUTE_THRESHOLD 890
#define FAC_DSC_THRESHOLD 206
#define FAC_ODD_THRESHOLD 29
#define MATRIX22_STRASSEN_THRESHOLD 17
#define HGCD2_DIV1_METHOD 3 /* 3.84% faster than 4 */
#define HGCD_THRESHOLD 123
#define HGCD_APPR_THRESHOLD 151
#define HGCD_REDUCE_THRESHOLD 3389
#define GCD_DC_THRESHOLD 435
#define GCDEXT_DC_THRESHOLD 318
#define JACOBI_BASE_METHOD 4 /* 8.04% faster than 3 */
/* Tuneup completed successfully, took 175382 seconds */

Some files were not shown because too many files have changed in this diff Show More