1dnl mc68020 mpn_rshift -- mpn right shift. 2 3dnl Copyright 1996, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, 4dnl Inc. 5dnl 6dnl This file is part of the GNU MP Library. 7dnl 8dnl The GNU MP Library is free software; you can redistribute it and/or 9dnl modify it under the terms of the GNU Lesser General Public License as 10dnl published by the Free Software Foundation; either version 3 of the 11dnl License, or (at your option) any later version. 12dnl 13dnl The GNU MP Library is distributed in the hope that it will be useful, 14dnl but WITHOUT ANY WARRANTY; without even the implied warranty of 15dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16dnl Lesser General Public License for more details. 17dnl 18dnl You should have received a copy of the GNU Lesser General Public License 19dnl along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. 20 21include(`../config.m4') 22 23 24C cycles/limb 25C shift==1 shift>1 26C 68040: 9 12 27 28 29C mp_limb_t mpn_rshift (mp_ptr res_ptr, mp_srcptr s_ptr, mp_size_t s_size, 30C unsigned cnt); 31C 32C The "cnt" parameter is either 16 bits or 32 bits depending on 33C SIZEOF_UNSIGNED (see ABI notes in mpn/m68k/README). The value is of 34C course only 1 to 31. When loaded as 16 bits there's garbage in the upper 35C half, hence the use of cmpw. The shift instructions take the their count 36C modulo 64, so the upper part doesn't matter to them either. 37C 38 39C INPUT PARAMETERS 40C res_ptr (sp + 4) 41C s_ptr (sp + 8) 42C s_size (sp + 12) 43C cnt (sp + 16) 44 45define(res_ptr, `a1') 46define(s_ptr, `a0') 47define(s_size, `d6') 48define(cnt, `d4') 49 50ifdef(`SIZEOF_UNSIGNED',, 51`m4_error(`SIZEOF_UNSIGNED not defined, should be in config.m4 52')') 53 54PROLOGUE(mpn_rshift) 55C Save used registers on the stack. 56 moveml d2-d6/a2, M(-,sp) 57 58C Copy the arguments to registers. 59 movel M(sp,28), res_ptr 60 movel M(sp,32), s_ptr 61 movel M(sp,36), s_size 62ifelse(SIZEOF_UNSIGNED,2, 63` movew M(sp,40), cnt', 64` movel M(sp,40), cnt') 65 66 moveql #1, d5 67 cmpw d5, cnt 68 bne L(Lnormal) 69 cmpl res_ptr, s_ptr 70 bls L(Lspecial) C jump if res_ptr >= s_ptr 71 72ifelse(scale_available_p,1,` 73 lea M(res_ptr,s_size,l,4), a2 74',` 75 movel s_size, d0 76 asll #2, d0 77 lea M(res_ptr,d0,l), a2 78') 79 cmpl s_ptr, a2 80 bls L(Lspecial) C jump if s_ptr >= res_ptr + s_size 81 82L(Lnormal:) 83 moveql #32, d5 84 subl cnt, d5 85 movel M(s_ptr,+), d2 86 movel d2, d0 87 lsll d5, d0 C compute carry limb 88 89 lsrl cnt, d2 90 movel d2, d1 91 subql #1, s_size 92 beq L(Lend) 93 lsrl #1, s_size 94 bcs L(L1) 95 subql #1, s_size 96 97L(Loop:) 98 movel M(s_ptr,+), d2 99 movel d2, d3 100 lsll d5, d3 101 orl d3, d1 102 movel d1, M(res_ptr,+) 103 lsrl cnt, d2 104L(L1:) 105 movel M(s_ptr,+), d1 106 movel d1, d3 107 lsll d5, d3 108 orl d3, d2 109 movel d2, M(res_ptr,+) 110 lsrl cnt, d1 111 112 dbf s_size, L(Loop) 113 subl #0x10000, s_size 114 bcc L(Loop) 115 116L(Lend:) 117 movel d1, M(res_ptr) C store most significant limb 118 119C Restore used registers from stack frame. 120 moveml M(sp,+), d2-d6/a2 121 rts 122 123C We loop from most significant end of the arrays, which is only permissable 124C if the source and destination don't overlap, since the function is 125C documented to work for overlapping source and destination. 126 127L(Lspecial:) 128ifelse(scale_available_p,1,` 129 lea M(s_ptr,s_size,l,4), s_ptr 130 lea M(res_ptr,s_size,l,4), res_ptr 131',` 132 movel s_size, d0 133 asll #2, d0 134 addl d0, s_ptr 135 addl d0, res_ptr 136') 137 138 clrl d0 C initialize carry 139 eorw #1, s_size 140 lsrl #1, s_size 141 bcc L(LL1) 142 subql #1, s_size 143 144L(LLoop:) 145 movel M(-,s_ptr), d2 146 roxrl #1, d2 147 movel d2, M(-,res_ptr) 148L(LL1:) 149 movel M(-,s_ptr), d2 150 roxrl #1, d2 151 movel d2, M(-,res_ptr) 152 153 dbf s_size, L(LLoop) 154 roxrl #1, d0 C save cy in msb 155 subl #0x10000, s_size 156 bcs L(LLend) 157 addl d0, d0 C restore cy 158 bra L(LLoop) 159 160L(LLend:) 161C Restore used registers from stack frame. 162 moveml M(sp,+), d2-d6/a2 163 rts 164 165EPILOGUE(mpn_rshift) 166