divrem_2.asm
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:6k
- dnl IA-64 mpn_divrem_2 -- Divide an n-limb number by a 2-limb number.
- dnl Copyright 2004, 2005 Free Software Foundation, Inc.
- dnl This file is part of the GNU MP Library.
- dnl The GNU MP Library is free software; you can redistribute it and/or modify
- dnl it under the terms of the GNU Lesser General Public License as published
- dnl by the Free Software Foundation; either version 3 of the License, or (at
- dnl your option) any later version.
- 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 Lesser General Public
- dnl License for more details.
- dnl You should have received a copy of the GNU Lesser General Public License
- dnl along with the GNU MP Library. If not, see http://www.gnu.org/licenses/.
- include(`../config.m4')
- C cycles/limb
- C Itanium: 63
- C Itanium 2: 46
- C TODO
- C * Further optimize the loop. We could probably do some more trickery with
- C arithmetic in the FPU, or perhaps use a non-zero addend of xma in more
- C places.
- C * Software pipeline for perhaps 5 saved cycles, around the end and start of
- C the loop.
- C * Schedule code outside of loop better.
- C * Update the comments. They are now using the same name for the same
- C logical quantity.
- C * Handle conditional zeroing of r31 in loop more cleanly.
- C * Inline mpn_invert_limb and schedule its insns across the entire init code.
- C * Ultimately, use 2-limb, or perhaps 3-limb or 4-limb inverse.
- define(`qp',`r32')
- define(`qxn',`r33')
- define(`np',`r34')
- define(`nn',`r35')
- define(`dp',`r36')
- define(`fnh',`f11')
- define(`fminus1',`f10')
- define(`fd0',`f13')
- define(`fd1',`f14')
- define(`d0',`r39')
- define(`d1',`r36')
- define(`fnl',`f32')
- define(`fdinv',`f12')
- define(`R1',`r38') define(`R0',`r37')
- define(`P1',`r28') define(`P0',`r27')
- ASM_START()
- C HP's assembler requires these declarations for importing mpn_invert_limb
- .global mpn_invert_limb
- .type mpn_invert_limb,@function
- PROLOGUE(mpn_divrem_2)
- .prologue
- .save ar.pfs, r42
- .save ar.lc, r44
- .save rp, r41
- ifdef(`HAVE_ABI_32',
- ` addp4 qp = 0, qp C M I
- addp4 np = 0, np C M I
- addp4 dp = 0, dp C M I
- zxt4 nn = nn C I
- zxt4 qxn = qxn C I
- ;;
- ')
- alloc r42 = ar.pfs, 5,8,1,0 C M2
- ld8 d0 = [dp], 8 C M0M1 d0
- mov r44 = ar.lc C I0
- shladd np = nn, 3, np C M I
- ;;
- ld8 d1 = [dp] C M0M1 d1
- mov r41 = b0 C I0
- add r15 = -8, np C M I
- add np = -16, np C M I
- mov r40 = r0 C M I
- ;;
- ld8 R1 = [r15] C M0M1 n1
- ld8 R0 = [r34], -8 C M0M1 n0
- ;;
- cmp.ltu p6, p0 = d1, R1 C M I
- cmp.eq p8, p0 = d1, R1 C M I
- ;;
- (p8) cmp.leu p6, p0 = d0, R0
- cmp.ltu p8, p9 = R0, d0
- (p6) br.cond.dpnt .L_high_limb_1 C FIXME: inline!
- .L8:
- mov r45 = d1
- br.call.sptk.many b0 = mpn_invert_limb C FIXME: inline+schedule
- ;;
- setf.sig fd1 = d1 C d1
- setf.sig fd0 = d0 C d0
- add r14 = r33, r35 C nn + qxn
- ;;
- setf.sig fdinv = r8 C dinv
- mov r9 = -1
- add r35 = -3, r14
- ;;
- setf.sig fminus1 = r9
- cmp.gt p6, p0 = r0, r35
- shladd qp = r35, 3, qp
- mov ar.lc = r35
- mov r31 = 0 C n0
- (p6) br.cond.dpnt .Ldone
- ;;
- ALIGN(16)
- C *** MAIN LOOP START ***
- .Loop: C 00
- mov r15 = R0 C nadj = n10
- cmp.le p14, p15 = 0, R0 C check high bit of R0
- cmp.le p8, p0 = r33, r35 C dividend limbs remaining?
- ;; C 01
- .pred.rel "mutex", p14, p15
- (p8) ld8 r31 = [r34], -8 C n0
- (p15) add r15 = d1, R0 C nadj = n10 + d1
- (p15) add r14 = 1, R1 C nh + (nl:63)
- (p14) mov r14 = R1 C nh
- cmp.eq p6, p0 = d1, R1 C nh == d1
- (p6) br.cond.spnt .L_R1_eq_d1
- ;; C 02
- setf.sig f8 = r14 C n2 + (nl:63)
- setf.sig f15 = r15 C nadj
- sub r23 = -1, R1 C r23 = ~nh
- ;; C 03
- setf.sig fnh = r23
- setf.sig fnl = R0
- ;; C 08
- xma.hu f7 = fdinv, f8, f15 C xh = HI(dinv*(nh-nmask)+nadj)
- ;; C 12
- xma.l f7 = f7, fminus1, fnh C nh + xh
- ;; C 16
- getf.sig r14 = f7
- xma.hu f9 = f7, fd1, fnl C xh = HI(q1*d1+nl)
- xma.l f33 = f7, fd1, fnl C xh = LO(q1*d1+nl)
- ;; C 20
- getf.sig r16 = f9
- sub r24 = d1, R1
- C 21
- getf.sig r17 = f33
- ;; C 25
- cmp.eq p6, p7 = r16, r24
- ;; C 26
- .pred.rel "mutex", p6, p7
- (p6) xma.l f8 = f7, fminus1, f0 C f8 = -f7
- (p7) xma.l f8 = f7,fminus1,fminus1 C f8 = -f7-1
- ;; C 27
- .pred.rel "mutex", p6, p7
- (p6) sub r18 = 0, r14 C q = -q1
- (p7) sub r18 = -1, r14 C q = -q1-1
- (p6) add r14 = 0, r17 C n1 = xl
- (p7) add r14 = d1, r17 C n1 = xl + d1
- ;; C 30
- xma.hu f9 = fd0, f8, f0 C d0*(-f7-1) = -d0*f7-d0
- xma.l f35 = fd0, f8, f0
- ;; C 34
- getf.sig P1 = f9 C P1
- C 35
- getf.sig P0 = f35 C P0
- ;;
- .L_adj: C 40
- cmp.ltu p8, p0 = r31, P0 C p8 = cy from low limb
- cmp.ltu p6, p0 = r14, P1 C p6 = prel cy from high limb
- sub R0 = r31, P0
- sub R1 = r14, P1
- ;; C 41
- (p8) cmp.eq.or p6, p0 = 0, R1 C p6 = final cy from high limb
- (p8) add R1 = -1, R1
- cmp.ne p10, p0 = r0, r0 C clear p10 FIXME: use unc below!
- cmp.ne p13, p0 = r0, r0 C clear p13 FIXME: use unc below!
- ;; C 42
- (p6) add R0 = R0, d0
- (p6) add R1 = R1, d1
- (p6) add r18 = -1, r18 C q--
- ;; C 43
- (p6) cmp.ltu p10, p0 = R0, d0
- (p6) cmp.ltu p0, p13 = R1, d1
- ;; C 44
- (p10) cmp.ne.and p0, p13 = -1, R1 C p13 = !cy
- (p10) add R1 = 1, R1
- (p13) br.cond.spnt .L_two_too_big C jump if not cy
- ;; C 45
- st8 [qp] = r18, -8
- add r35 = -1, r35
- mov r31 = 0 C n0, next iteration
- br.cloop.sptk .Loop
- C *** MAIN LOOP END ***
- ;;
- .Ldone:
- mov r8 = r40
- mov b0 = r41
- add r21 = 8, r34
- add r22 = 16, r34
- ;;
- st8 [r21] = R0
- st8 [r22] = R1
- mov ar.pfs = r42
- mov ar.lc = r44
- br.ret.sptk.many b0
- .L_high_limb_1:
- .pred.rel "mutex", p8, p9
- sub R0 = R0, d0
- (p8) sub R1 = R1, d1, 1
- (p9) sub R1 = R1, d1
- mov r40 = 1
- br.sptk .L8
- ;;
- .L_two_too_big:
- add R0 = R0, d0
- add R1 = R1, d1
- ;;
- add r18 = -1, r18 C q--
- cmp.ltu p10, p0 = R0, d0
- ;;
- (p10) add R1 = 1, R1
- st8 [qp] = r18, -8
- add r35 = -1, r35
- mov r31 = 0 C n0, next iteration
- br.cloop.sptk .Loop
- br.sptk .Ldone
- .L_R1_eq_d1:
- add r14 = R0, d1 C r = R0 + d1
- mov r18 = -1 C q = -1
- ;;
- cmp.leu p6, p0 = R0, r14
- (p6) br.cond.spnt .L20 C jump unless cy
- ;;
- sub P1 = r14, d0
- add R0 = r31, d0
- ;;
- cmp.ltu p8, p9 = R0, r31
- ;;
- .pred.rel "mutex", p8, p9
- st8 [qp] = r18, -8
- (p8) add R1 = r0, P1, 1 C R1 = n1 - P1 - cy
- (p9) add R1 = r0, P1 C R1 = n1 - P1
- add r35 = -1, r35
- mov r31 = 0 C n0, next iteration
- br.cloop.sptk .Loop
- br.sptk .Ldone
- ;;
- .L20: cmp.ne p6, p7 = 0, d0
- ;;
- .pred.rel "mutex", p6, p7
- (p6) add P1 = -1, d0
- (p7) mov P1 = d0
- sub P0 = r0, d0
- br.sptk .L_adj
- EPILOGUE()
- ASM_END()