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