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