Reorganisation of the source tree
[ghc-hetmet.git] / rts / gmp / mpn / x86 / k6 / diveby3.asm
1 dnl  AMD K6 mpn_divexact_by3 -- mpn division by 3, expecting no remainder.
2 dnl 
3 dnl  K6: 11.0 cycles/limb
4
5
6 dnl  Copyright (C) 2000 Free Software Foundation, Inc.
7 dnl 
8 dnl  This file is part of the GNU MP Library.
9 dnl 
10 dnl  The GNU MP Library is free software; you can redistribute it and/or
11 dnl  modify it under the terms of the GNU Lesser General Public License as
12 dnl  published by the Free Software Foundation; either version 2.1 of the
13 dnl  License, or (at your option) any later version.
14 dnl 
15 dnl  The GNU MP Library is distributed in the hope that it will be useful,
16 dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 dnl  Lesser General Public License for more details.
19 dnl 
20 dnl  You should have received a copy of the GNU Lesser General Public
21 dnl  License along with the GNU MP Library; see the file COPYING.LIB.  If
22 dnl  not, write to the Free Software Foundation, Inc., 59 Temple Place -
23 dnl  Suite 330, Boston, MA 02111-1307, USA.
24
25
26 include(`../config.m4')
27
28
29 C mp_limb_t mpn_divexact_by3c (mp_ptr dst, mp_srcptr src, mp_size_t size,
30 C                              mp_limb_t carry);
31 C
32 C Using %esi in (%esi,%ecx,4) or 0(%esi,%ecx,4) addressing modes doesn't
33 C lead to vector decoding, unlike plain (%esi) does.
34
35 defframe(PARAM_CARRY,16)
36 defframe(PARAM_SIZE, 12)
37 defframe(PARAM_SRC,   8)
38 defframe(PARAM_DST,   4)
39
40 dnl  multiplicative inverse of 3, modulo 2^32
41 deflit(INVERSE_3, 0xAAAAAAAB)
42
43         .text
44         ALIGN(32)
45
46 PROLOGUE(mpn_divexact_by3c)
47 deflit(`FRAME',0)
48
49         movl    PARAM_SIZE, %ecx
50         pushl   %esi            defframe_pushl(SAVE_ESI)
51
52         movl    PARAM_SRC, %esi
53         pushl   %edi            defframe_pushl(SAVE_EDI)
54
55         movl    PARAM_DST, %edi
56         pushl   %ebx            defframe_pushl(SAVE_EBX)
57
58         movl    PARAM_CARRY, %ebx
59         leal    (%esi,%ecx,4), %esi
60
61         pushl   $3              defframe_pushl(VAR_THREE)
62         leal    (%edi,%ecx,4), %edi
63
64         negl    %ecx
65
66
67         C Need 32 alignment for claimed speed, to avoid the movl store
68         C opcode/modrm crossing a cache line boundary
69
70         ALIGN(32)
71 L(top):
72         C eax   scratch, low product
73         C ebx   carry limb (0 to 3)
74         C ecx   counter, limbs, negative
75         C edx   scratch, high product
76         C esi   &src[size]
77         C edi   &dst[size]
78         C ebp
79         C
80         C The 0(%esi,%ecx,4) form pads so the finishup "movl %ebx, %eax"
81         C doesn't cross a 32 byte boundary, saving a couple of cycles
82         C (that's a fixed couple, not per loop).
83
84 Zdisp(  movl,   0,(%esi,%ecx,4), %eax)
85         subl    %ebx, %eax
86
87         setc    %bl
88
89         imull   $INVERSE_3, %eax
90
91         movl    %eax, (%edi,%ecx,4)
92         addl    $2, %ecx
93
94         mull    VAR_THREE
95
96         addl    %edx, %ebx
97         loop    L(top)
98
99
100         movl    SAVE_ESI, %esi
101         movl    %ebx, %eax
102
103         movl    SAVE_EBX, %ebx
104
105         movl    SAVE_EDI, %edi
106         addl    $FRAME, %esp
107
108         ret
109
110 EPILOGUE()