xref: /openbmc/linux/arch/m68k/lib/lshrdi3.c (revision d6410efad2e49e2cefc2a0e7236824fd12d5bd6e)
11da177e4SLinus Torvalds /* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */
21da177e4SLinus Torvalds /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
31da177e4SLinus Torvalds 
41da177e4SLinus Torvalds This file is part of GNU CC.
51da177e4SLinus Torvalds 
61da177e4SLinus Torvalds GNU CC is free software; you can redistribute it and/or modify
71da177e4SLinus Torvalds it under the terms of the GNU General Public License as published by
81da177e4SLinus Torvalds the Free Software Foundation; either version 2, or (at your option)
91da177e4SLinus Torvalds any later version.
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds GNU CC is distributed in the hope that it will be useful,
121da177e4SLinus Torvalds but WITHOUT ANY WARRANTY; without even the implied warranty of
131da177e4SLinus Torvalds MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*d6410efaSGeert Uytterhoeven GNU General Public License for more details. */
151da177e4SLinus Torvalds 
161da177e4SLinus Torvalds #define BITS_PER_UNIT 8
171da177e4SLinus Torvalds 
181da177e4SLinus Torvalds typedef		 int SItype	__attribute__ ((mode (SI)));
191da177e4SLinus Torvalds typedef unsigned int USItype	__attribute__ ((mode (SI)));
201da177e4SLinus Torvalds typedef		 int DItype	__attribute__ ((mode (DI)));
211da177e4SLinus Torvalds typedef int word_type __attribute__ ((mode (__word__)));
221da177e4SLinus Torvalds 
231da177e4SLinus Torvalds struct DIstruct {SItype high, low;};
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds typedef union
261da177e4SLinus Torvalds {
271da177e4SLinus Torvalds   struct DIstruct s;
281da177e4SLinus Torvalds   DItype ll;
291da177e4SLinus Torvalds } DIunion;
301da177e4SLinus Torvalds 
311da177e4SLinus Torvalds DItype
321da177e4SLinus Torvalds __lshrdi3 (DItype u, word_type b)
331da177e4SLinus Torvalds {
341da177e4SLinus Torvalds   DIunion w;
351da177e4SLinus Torvalds   word_type bm;
361da177e4SLinus Torvalds   DIunion uu;
371da177e4SLinus Torvalds 
381da177e4SLinus Torvalds   if (b == 0)
391da177e4SLinus Torvalds     return u;
401da177e4SLinus Torvalds 
411da177e4SLinus Torvalds   uu.ll = u;
421da177e4SLinus Torvalds 
431da177e4SLinus Torvalds   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
441da177e4SLinus Torvalds   if (bm <= 0)
451da177e4SLinus Torvalds     {
461da177e4SLinus Torvalds       w.s.high = 0;
471da177e4SLinus Torvalds       w.s.low = (USItype)uu.s.high >> -bm;
481da177e4SLinus Torvalds     }
491da177e4SLinus Torvalds   else
501da177e4SLinus Torvalds     {
511da177e4SLinus Torvalds       USItype carries = (USItype)uu.s.high << bm;
521da177e4SLinus Torvalds       w.s.high = (USItype)uu.s.high >> b;
531da177e4SLinus Torvalds       w.s.low = ((USItype)uu.s.low >> b) | carries;
541da177e4SLinus Torvalds     }
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds   return w.ll;
571da177e4SLinus Torvalds }
58