gcd_11.asm revision 1.1 1 1.1 mrg dnl x86 mpn_gcd_11 optimised for processors with slow BSF.
2 1.1 mrg
3 1.1 mrg dnl Based on C version.
4 1.1 mrg
5 1.1 mrg dnl Copyright 2019 Free Software Foundation, Inc.
6 1.1 mrg
7 1.1 mrg dnl This file is part of the GNU MP Library.
8 1.1 mrg dnl
9 1.1 mrg dnl The GNU MP Library is free software; you can redistribute it and/or modify
10 1.1 mrg dnl it under the terms of either:
11 1.1 mrg dnl
12 1.1 mrg dnl * the GNU Lesser General Public License as published by the Free
13 1.1 mrg dnl Software Foundation; either version 3 of the License, or (at your
14 1.1 mrg dnl option) any later version.
15 1.1 mrg dnl
16 1.1 mrg dnl or
17 1.1 mrg dnl
18 1.1 mrg dnl * the GNU General Public License as published by the Free Software
19 1.1 mrg dnl Foundation; either version 2 of the License, or (at your option) any
20 1.1 mrg dnl later version.
21 1.1 mrg dnl
22 1.1 mrg dnl or both in parallel, as here.
23 1.1 mrg dnl
24 1.1 mrg dnl The GNU MP Library is distributed in the hope that it will be useful, but
25 1.1 mrg dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26 1.1 mrg dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 1.1 mrg dnl for more details.
28 1.1 mrg dnl
29 1.1 mrg dnl You should have received copies of the GNU General Public License and the
30 1.1 mrg dnl GNU Lesser General Public License along with the GNU MP Library. If not,
31 1.1 mrg dnl see https://www.gnu.org/licenses/.
32 1.1 mrg
33 1.1 mrg include(`../config.m4')
34 1.1 mrg
35 1.1 mrg dnl Rudimentary code for x86-32, i.e. for CPUs without cmov. Also, the bsf
36 1.1 mrg dnl instruction is assumed to be so slow it is useless. Instead a teble is
37 1.1 mrg dnl used.
38 1.1 mrg dnl
39 1.1 mrg dnl The loop benefits from OoO, in-order CPUs might want a different loop.
40 1.1 mrg dnl The ebx and ecx registers could be combined if the assigment of ecx were
41 1.1 mrg dnl postponed until ebx died, but that would at least hurt in-order CPUs.
42 1.1 mrg
43 1.1 mrg C cycles/bit (approx)
44 1.1 mrg C AMD K7 ?
45 1.1 mrg C AMD K8,K9 ?
46 1.1 mrg C AMD K10 ?
47 1.1 mrg C AMD bd1 ?
48 1.1 mrg C AMD bd2 ?
49 1.1 mrg C AMD bd3 ?
50 1.1 mrg C AMD bd4 ?
51 1.1 mrg C AMD bt1 ?
52 1.1 mrg C AMD bt2 ?
53 1.1 mrg C AMD zn1 ?
54 1.1 mrg C AMD zn2 ?
55 1.1 mrg C Intel P4-2 ?
56 1.1 mrg C Intel P4-3/4 ?
57 1.1 mrg C Intel P6/13 ?
58 1.1 mrg C Intel CNR ?
59 1.1 mrg C Intel NHM ?
60 1.1 mrg C Intel SBR ?
61 1.1 mrg C Intel IBR ?
62 1.1 mrg C Intel HWL ?
63 1.1 mrg C Intel BWL ?
64 1.1 mrg C Intel SKL ?
65 1.1 mrg C Intel atom ?
66 1.1 mrg C Intel SLM ?
67 1.1 mrg C Intel GLM ?
68 1.1 mrg C Intel GLM+ ?
69 1.1 mrg C VIA nano ?
70 1.1 mrg C Numbers measured with: speed -CD -s8-32 -t24 mpn_gcd_1
71 1.1 mrg
72 1.1 mrg deflit(MAXSHIFT, 6)
73 1.1 mrg deflit(MASK, eval((m4_lshift(1,MAXSHIFT))-1))
74 1.1 mrg
75 1.1 mrg DEF_OBJECT(ctz_table,64)
76 1.1 mrg .byte MAXSHIFT
77 1.1 mrg forloop(i,1,MASK,
78 1.1 mrg ` .byte m4_count_trailing_zeros(i)
79 1.1 mrg ')
80 1.1 mrg END_OBJECT(ctz_table)
81 1.1 mrg
82 1.1 mrg define(`u0', `%eax')
83 1.1 mrg define(`v0', `%edx')
84 1.1 mrg
85 1.1 mrg
86 1.1 mrg ASM_START()
87 1.1 mrg TEXT
88 1.1 mrg ALIGN(16)
89 1.1 mrg PROLOGUE(mpn_gcd_11)
90 1.1 mrg push %edi
91 1.1 mrg push %esi
92 1.1 mrg push %ebx
93 1.1 mrg
94 1.1 mrg mov 16(%esp), u0
95 1.1 mrg mov 20(%esp), v0
96 1.1 mrg LEAL( ctz_table, %esi)
97 1.1 mrg sub v0, u0 C u = u - v 0
98 1.1 mrg jz L(end)
99 1.1 mrg
100 1.1 mrg ALIGN(16)
101 1.1 mrg L(top): sbb %ebx, %ebx C mask 1
102 1.1 mrg mov u0, %edi C 1
103 1.1 mrg mov u0, %ecx C 1
104 1.1 mrg and %ebx, %edi C 2
105 1.1 mrg xor %ebx, u0 C 2
106 1.1 mrg add %edi, v0 C v = min(u.v) 3
107 1.1 mrg sub %ebx, u0 C u = |u - v| 3
108 1.1 mrg L(mid): and $MASK, %ecx C 2
109 1.1 mrg movzbl (%esi,%ecx), %ecx C 3
110 1.1 mrg jz L(shift_alot)
111 1.1 mrg shr %cl, u0 C 4
112 1.1 mrg sub v0, u0 C u = u - v 0,5
113 1.1 mrg jnz L(top)
114 1.1 mrg
115 1.1 mrg L(end): mov v0, %eax
116 1.1 mrg pop %ebx
117 1.1 mrg pop %esi
118 1.1 mrg pop %edi
119 1.1 mrg ret
120 1.1 mrg
121 1.1 mrg L(shift_alot):
122 1.1 mrg shr $MAXSHIFT, u0
123 1.1 mrg mov u0, %ecx
124 1.1 mrg jmp L(mid)
125 1.1 mrg EPILOGUE()
126 1.1 mrg ASM_END()
127