1dnl mc68020 mpn_lshift -- mpn left 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: 5 12 27 28 29C mp_limb_t mpn_lshift (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_lshift) 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 s_ptr, res_ptr 70 bls L(Lspecial) C jump if s_ptr >= res_ptr 71 72ifelse(scale_available_p,1,` 73 lea M(s_ptr,s_size,l,4), a2 74',` 75 movel s_size, d0 76 asll #2, d0 77 lea M(s_ptr,d0,l), a2 78') 79 cmpl res_ptr, a2 80 bls L(Lspecial) C jump if res_ptr >= s_ptr + s_size 81 82L(Lnormal): 83 moveql #32, d5 84 subl cnt, d5 85 86ifelse(scale_available_p,1,` 87 lea M(s_ptr,s_size,l,4), s_ptr 88 lea M(res_ptr,s_size,l,4), res_ptr 89',` 90 movel s_size, d0 91 asll #2, d0 92 addl d0, s_ptr 93 addl d0, res_ptr 94') 95 movel M(-,s_ptr), d2 96 movel d2, d0 97 lsrl d5, d0 C compute carry limb 98 99 lsll cnt, d2 100 movel d2, d1 101 subql #1, s_size 102 beq L(Lend) 103 lsrl #1, s_size 104 bcs L(L1) 105 subql #1, s_size 106 107L(Loop:) 108 movel M(-,s_ptr), d2 109 movel d2, d3 110 lsrl d5, d3 111 orl d3, d1 112 movel d1, M(-,res_ptr) 113 lsll cnt, d2 114L(L1:) 115 movel M(-,s_ptr), d1 116 movel d1, d3 117 lsrl d5, d3 118 orl d3, d2 119 movel d2, M(-,res_ptr) 120 lsll cnt, d1 121 122 dbf s_size, L(Loop) 123 subl #0x10000, s_size 124 bcc L(Loop) 125 126L(Lend:) 127 movel d1, M(-,res_ptr) C store least significant limb 128 129C Restore used registers from stack frame. 130 moveml M(sp,+), d2-d6/a2 131 rts 132 133C We loop from least significant end of the arrays, which is only 134C permissable if the source and destination don't overlap, since the 135C function is documented to work for overlapping source and destination. 136 137L(Lspecial): 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 addxl d2, d2 147 movel d2, M(res_ptr,+) 148L(LL1): 149 movel M(s_ptr,+), d2 150 addxl d2, d2 151 movel d2, M(res_ptr,+) 152 153 dbf s_size, L(LLoop) 154 addxl d0, d0 C save cy in lsb 155 subl #0x10000, s_size 156 bcs L(LLend) 157 lsrl #1, 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_lshift) 166