1*dd68e9e8SFrançois Revol/* mc68020 __mpn_lshift -- Shift left a low-level natural-number integer. 2*dd68e9e8SFrançois Revol 3*dd68e9e8SFrançois RevolCopyright (C) 1996, 1998 Free Software Foundation, Inc. 4*dd68e9e8SFrançois Revol 5*dd68e9e8SFrançois RevolThis file is part of the GNU MP Library. 6*dd68e9e8SFrançois Revol 7*dd68e9e8SFrançois RevolThe GNU MP Library is free software; you can redistribute it and/or modify 8*dd68e9e8SFrançois Revolit under the terms of the GNU Lesser General Public License as published by 9*dd68e9e8SFrançois Revolthe Free Software Foundation; either version 2.1 of the License, or (at your 10*dd68e9e8SFrançois Revoloption) any later version. 11*dd68e9e8SFrançois Revol 12*dd68e9e8SFrançois RevolThe GNU MP Library is distributed in the hope that it will be useful, but 13*dd68e9e8SFrançois RevolWITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14*dd68e9e8SFrançois Revolor FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15*dd68e9e8SFrançois RevolLicense for more details. 16*dd68e9e8SFrançois Revol 17*dd68e9e8SFrançois RevolYou should have received a copy of the GNU Lesser General Public License 18*dd68e9e8SFrançois Revolalong with the GNU MP Library; see the file COPYING.LIB. If not, write to 19*dd68e9e8SFrançois Revolthe Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 20*dd68e9e8SFrançois RevolMA 02111-1307, USA. */ 21*dd68e9e8SFrançois Revol 22*dd68e9e8SFrançois Revol/* 23*dd68e9e8SFrançois Revol INPUT PARAMETERS 24*dd68e9e8SFrançois Revol res_ptr (sp + 4) 25*dd68e9e8SFrançois Revol s_ptr (sp + 8) 26*dd68e9e8SFrançois Revol s_size (sp + 16) 27*dd68e9e8SFrançois Revol cnt (sp + 12) 28*dd68e9e8SFrançois Revol*/ 29*dd68e9e8SFrançois Revol 30*dd68e9e8SFrançois Revol#include "sysdep.h" 31*dd68e9e8SFrançois Revol#include "asm-syntax.h" 32*dd68e9e8SFrançois Revol 33*dd68e9e8SFrançois Revol#define res_ptr a1 34*dd68e9e8SFrançois Revol#define s_ptr a0 35*dd68e9e8SFrançois Revol#define s_size d6 36*dd68e9e8SFrançois Revol#define cnt d4 37*dd68e9e8SFrançois Revol 38*dd68e9e8SFrançois Revol TEXT 39*dd68e9e8SFrançois RevolENTRY(__mpn_lshift) 40*dd68e9e8SFrançois Revol 41*dd68e9e8SFrançois Revol/* Save used registers on the stack. */ 42*dd68e9e8SFrançois Revol moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp) 43*dd68e9e8SFrançois Revol 44*dd68e9e8SFrançois Revol/* Copy the arguments to registers. */ 45*dd68e9e8SFrançois Revol movel MEM_DISP(sp,28),R(res_ptr) 46*dd68e9e8SFrançois Revol movel MEM_DISP(sp,32),R(s_ptr) 47*dd68e9e8SFrançois Revol movel MEM_DISP(sp,36),R(s_size) 48*dd68e9e8SFrançois Revol movel MEM_DISP(sp,40),R(cnt) 49*dd68e9e8SFrançois Revol 50*dd68e9e8SFrançois Revol moveql #1,R(d5) 51*dd68e9e8SFrançois Revol cmpl R(d5),R(cnt) 52*dd68e9e8SFrançois Revol bne L(Lnormal) 53*dd68e9e8SFrançois Revol cmpl R(s_ptr),R(res_ptr) 54*dd68e9e8SFrançois Revol bls L(Lspecial) /* jump if s_ptr >= res_ptr */ 55*dd68e9e8SFrançois Revol#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) 56*dd68e9e8SFrançois Revol lea MEM_INDX1(s_ptr,s_size,l,4),R(a2) 57*dd68e9e8SFrançois Revol#else /* not mc68020 */ 58*dd68e9e8SFrançois Revol movel R(s_size),R(d0) 59*dd68e9e8SFrançois Revol asll #2,R(d0) 60*dd68e9e8SFrançois Revol lea MEM_INDX(s_ptr,d0,l),R(a2) 61*dd68e9e8SFrançois Revol#endif 62*dd68e9e8SFrançois Revol cmpl R(res_ptr),R(a2) 63*dd68e9e8SFrançois Revol bls L(Lspecial) /* jump if res_ptr >= s_ptr + s_size */ 64*dd68e9e8SFrançois Revol 65*dd68e9e8SFrançois RevolL(Lnormal:) 66*dd68e9e8SFrançois Revol moveql #32,R(d5) 67*dd68e9e8SFrançois Revol subl R(cnt),R(d5) 68*dd68e9e8SFrançois Revol 69*dd68e9e8SFrançois Revol#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) 70*dd68e9e8SFrançois Revol lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr) 71*dd68e9e8SFrançois Revol lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr) 72*dd68e9e8SFrançois Revol#else /* not mc68000 */ 73*dd68e9e8SFrançois Revol movel R(s_size),R(d0) 74*dd68e9e8SFrançois Revol asll #2,R(d0) 75*dd68e9e8SFrançois Revol addl R(s_size),R(s_ptr) 76*dd68e9e8SFrançois Revol addl R(s_size),R(res_ptr) 77*dd68e9e8SFrançois Revol#endif 78*dd68e9e8SFrançois Revol movel MEM_PREDEC(s_ptr),R(d2) 79*dd68e9e8SFrançois Revol movel R(d2),R(d0) 80*dd68e9e8SFrançois Revol lsrl R(d5),R(d0) /* compute carry limb */ 81*dd68e9e8SFrançois Revol 82*dd68e9e8SFrançois Revol lsll R(cnt),R(d2) 83*dd68e9e8SFrançois Revol movel R(d2),R(d1) 84*dd68e9e8SFrançois Revol subql #1,R(s_size) 85*dd68e9e8SFrançois Revol beq L(Lend) 86*dd68e9e8SFrançois Revol lsrl #1,R(s_size) 87*dd68e9e8SFrançois Revol bcs L(L1) 88*dd68e9e8SFrançois Revol subql #1,R(s_size) 89*dd68e9e8SFrançois Revol 90*dd68e9e8SFrançois RevolL(Loop:) 91*dd68e9e8SFrançois Revol movel MEM_PREDEC(s_ptr),R(d2) 92*dd68e9e8SFrançois Revol movel R(d2),R(d3) 93*dd68e9e8SFrançois Revol lsrl R(d5),R(d3) 94*dd68e9e8SFrançois Revol orl R(d3),R(d1) 95*dd68e9e8SFrançois Revol movel R(d1),MEM_PREDEC(res_ptr) 96*dd68e9e8SFrançois Revol lsll R(cnt),R(d2) 97*dd68e9e8SFrançois RevolL(L1:) 98*dd68e9e8SFrançois Revol movel MEM_PREDEC(s_ptr),R(d1) 99*dd68e9e8SFrançois Revol movel R(d1),R(d3) 100*dd68e9e8SFrançois Revol lsrl R(d5),R(d3) 101*dd68e9e8SFrançois Revol orl R(d3),R(d2) 102*dd68e9e8SFrançois Revol movel R(d2),MEM_PREDEC(res_ptr) 103*dd68e9e8SFrançois Revol lsll R(cnt),R(d1) 104*dd68e9e8SFrançois Revol 105*dd68e9e8SFrançois Revol dbf R(s_size),L(Loop) 106*dd68e9e8SFrançois Revol subl #0x10000,R(s_size) 107*dd68e9e8SFrançois Revol bcc L(Loop) 108*dd68e9e8SFrançois Revol 109*dd68e9e8SFrançois RevolL(Lend:) 110*dd68e9e8SFrançois Revol movel R(d1),MEM_PREDEC(res_ptr) /* store least significant limb */ 111*dd68e9e8SFrançois Revol 112*dd68e9e8SFrançois Revol/* Restore used registers from stack frame. */ 113*dd68e9e8SFrançois Revol moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) 114*dd68e9e8SFrançois Revol rts 115*dd68e9e8SFrançois Revol 116*dd68e9e8SFrançois Revol/* We loop from least significant end of the arrays, which is only 117*dd68e9e8SFrançois Revol permissible if the source and destination don't overlap, since the 118*dd68e9e8SFrançois Revol function is documented to work for overlapping source and destination. */ 119*dd68e9e8SFrançois Revol 120*dd68e9e8SFrançois RevolL(Lspecial:) 121*dd68e9e8SFrançois Revol clrl R(d0) /* initialize carry */ 122*dd68e9e8SFrançois Revol eorw #1,R(s_size) 123*dd68e9e8SFrançois Revol lsrl #1,R(s_size) 124*dd68e9e8SFrançois Revol bcc L(LL1) 125*dd68e9e8SFrançois Revol subql #1,R(s_size) 126*dd68e9e8SFrançois Revol 127*dd68e9e8SFrançois RevolL(LLoop:) 128*dd68e9e8SFrançois Revol movel MEM_POSTINC(s_ptr),R(d2) 129*dd68e9e8SFrançois Revol addxl R(d2),R(d2) 130*dd68e9e8SFrançois Revol movel R(d2),MEM_POSTINC(res_ptr) 131*dd68e9e8SFrançois RevolL(LL1:) 132*dd68e9e8SFrançois Revol movel MEM_POSTINC(s_ptr),R(d2) 133*dd68e9e8SFrançois Revol addxl R(d2),R(d2) 134*dd68e9e8SFrançois Revol movel R(d2),MEM_POSTINC(res_ptr) 135*dd68e9e8SFrançois Revol 136*dd68e9e8SFrançois Revol dbf R(s_size),L(LLoop) 137*dd68e9e8SFrançois Revol addxl R(d0),R(d0) /* save cy in lsb */ 138*dd68e9e8SFrançois Revol subl #0x10000,R(s_size) 139*dd68e9e8SFrançois Revol bcs L(LLend) 140*dd68e9e8SFrançois Revol lsrl #1,R(d0) /* restore cy */ 141*dd68e9e8SFrançois Revol bra L(LLoop) 142*dd68e9e8SFrançois Revol 143*dd68e9e8SFrançois RevolL(LLend:) 144*dd68e9e8SFrançois Revol/* Restore used registers from stack frame. */ 145*dd68e9e8SFrançois Revol moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) 146*dd68e9e8SFrançois Revol rts 147*dd68e9e8SFrançois RevolEND(__mpn_lshift) 148