Home | History | Annotate | Line # | Download | only in x86_64
invert_limb.asm revision 1.1.1.1.8.1
      1 dnl  AMD64 mpn_invert_limb -- Invert a normalized limb.
      2 
      3 dnl  Contributed to the GNU project by Torbjorn Granlund and Niels Mller.
      4 
      5 dnl  Copyright 2004, 2007, 2008, 2009, 2011, 2012 Free Software Foundation,
      6 dnl  Inc.
      7 
      8 dnl  This file is part of the GNU MP Library.
      9 
     10 dnl  The GNU MP Library is free software; you can redistribute it and/or modify
     11 dnl  it under the terms of the GNU Lesser General Public License as published
     12 dnl  by the Free Software Foundation; either version 3 of the License, or (at
     13 dnl  your option) any later version.
     14 
     15 dnl  The GNU MP Library is distributed in the hope that it will be useful, but
     16 dnl  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     17 dnl  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
     18 dnl  License for more details.
     19 
     20 dnl  You should have received a copy of the GNU Lesser General Public License
     21 dnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
     22 
     23 include(`../config.m4')
     24 
     25 
     26 C	     cycles/limb (approx)	div
     27 C AMD K8,K9	 48			 71
     28 C AMD K10	 48			 77
     29 C Intel P4	135			161
     30 C Intel core2	 69			116
     31 C Intel corei	 55			 89
     32 C Intel atom	129			191
     33 C VIA nano	 79			157
     34 
     35 C rax rcx rdx rdi rsi r8
     36 
     37 ABI_SUPPORT(DOS64)
     38 ABI_SUPPORT(STD64)
     39 
     40 PROTECT(`mpn_invert_limb_table')
     41 
     42 ASM_START()
     43 	TEXT
     44 	ALIGN(16)
     45 PROLOGUE(mpn_invert_limb)		C			Kn	C2	Ci
     46 	FUNC_ENTRY(1)
     47 	mov	%rdi, %rax		C			 0	 0	 0
     48 	shr	$55, %rax		C			 1	 1	 1
     49 ifdef(`PIC',`
     50 ifdef(`DARWIN',`
     51 	mov	mpn_invert_limb_table@GOTPCREL(%rip), %r8
     52 	add	$-512, %r8
     53 ',`
     54 	lea	-512+mpn_invert_limb_table(%rip), %r8
     55 ')',`
     56 	movabs	$-512+mpn_invert_limb_table, %r8
     57 ')
     58 	movzwl	(%r8,%rax,2), R32(%rcx)	C	%rcx = v0
     59 
     60 	C v1 = (v0 << 11) - (v0*v0*d40 >> 40) - 1
     61 	mov	%rdi, %rsi		C			 0	 0	 0
     62 	mov	R32(%rcx), R32(%rax)	C			 4	 5	 5
     63 	imul	R32(%rcx), R32(%rcx)	C			 4	 5	 5
     64 	shr	$24, %rsi		C			 1	 1	 1
     65 	inc	%rsi			C	%rsi = d40
     66 	imul	%rsi, %rcx		C			 8	10	 8
     67 	shr	$40, %rcx		C			12	15	11
     68 	sal	$11, R32(%rax)		C			 5	 6	 6
     69 	dec	R32(%rax)
     70 	sub	R32(%rcx), R32(%rax)	C	%rax = v1
     71 
     72 	C v2 = (v1 << 13) + (v1 * (2^60 - v1*d40) >> 47)
     73 	mov	$0x1000000000000000, %rcx
     74 	imul	%rax, %rsi		C			14	17	13
     75 	sub	%rsi, %rcx
     76 	imul	%rax, %rcx
     77 	sal	$13, %rax
     78 	shr	$47, %rcx
     79 	add	%rax, %rcx		C	%rcx = v2
     80 
     81 	C v3 = (v2 << 31) + (v2 * (2^96 - v2 * d63 + ((v2 >> 1) & mask)) >> 65
     82 	mov	%rdi, %rsi		C			 0	 0	 0
     83 	shr	%rsi			C d/2
     84 	sbb	%rax, %rax		C -d0 = -(d mod 2)
     85 	sub	%rax, %rsi		C d63 = ceil(d/2)
     86 	imul	%rcx, %rsi		C v2 * d63
     87 	and	%rcx, %rax		C v2 * d0
     88 	shr	%rax			C (v2>>1) * d0
     89 	sub	%rsi, %rax		C (v2>>1) * d0 - v2 * d63
     90 	mul	%rcx
     91 	sal	$31, %rcx
     92 	shr	%rdx
     93 	add	%rdx, %rcx		C	%rcx = v3
     94 
     95 	mov	%rdi, %rax
     96 	mul	%rcx
     97 	add	%rdi, %rax
     98 	mov	%rcx, %rax
     99 	adc	%rdi, %rdx
    100 	sub	%rdx, %rax
    101 
    102 	FUNC_EXIT()
    103 	ret
    104 EPILOGUE()
    105 ASM_END()
    106