Home | History | Annotate | Download | only in lib
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright (C) 1989-2013 Free Software Foundation, Inc.
      4  */
      5 
      6 #include "libgcc2.h"
      7 
      8 DWtype
      9 __ashldi3(DWtype u, shift_count_type b)
     10 {
     11 	if (b == 0)
     12 		return u;
     13 
     14 	const DWunion uu = {.ll = u};
     15 	const shift_count_type bm = W_TYPE_SIZE - b;
     16 	DWunion w;
     17 
     18 	if (bm <= 0) {
     19 		w.s.low = 0;
     20 		w.s.high = (UWtype)uu.s.low << -bm;
     21 	} else {
     22 		const UWtype carries = (UWtype) uu.s.low >> bm;
     23 
     24 		w.s.low = (UWtype)uu.s.low << b;
     25 		w.s.high = ((UWtype)uu.s.high << b) | carries;
     26 	}
     27 
     28 	return w.ll;
     29 }
     30 
     31 DWtype
     32 __ashrdi3(DWtype u, shift_count_type b)
     33 {
     34 	if (b == 0)
     35 		return u;
     36 
     37 	const DWunion uu = {.ll = u};
     38 	const shift_count_type bm = W_TYPE_SIZE - b;
     39 	DWunion w;
     40 
     41 	if (bm <= 0) {
     42 		/* w.s.high = 1..1 or 0..0 */
     43 		w.s.high = uu.s.high >> (W_TYPE_SIZE - 1);
     44 		w.s.low = uu.s.high >> -bm;
     45 	} else {
     46 		const UWtype carries = (UWtype) uu.s.high << bm;
     47 
     48 		w.s.high = uu.s.high >> b;
     49 		w.s.low = ((UWtype)uu.s.low >> b) | carries;
     50 	}
     51 
     52 	return w.ll;
     53 }
     54 
     55 DWtype
     56 __lshrdi3(DWtype u, shift_count_type b)
     57 {
     58 	if (b == 0)
     59 		return u;
     60 
     61 	const DWunion uu = {.ll = u};
     62 	const shift_count_type bm = W_TYPE_SIZE - b;
     63 	DWunion w;
     64 
     65 	if (bm <= 0) {
     66 		w.s.high = 0;
     67 		w.s.low = (UWtype)uu.s.high >> -bm;
     68 	} else {
     69 		const UWtype carries = (UWtype)uu.s.high << bm;
     70 
     71 		w.s.high = (UWtype)uu.s.high >> b;
     72 		w.s.low = ((UWtype)uu.s.low >> b) | carries;
     73 	}
     74 
     75 	return w.ll;
     76 }
     77 
     78 unsigned long
     79 udivmodsi4(unsigned long num, unsigned long den, int modwanted)
     80 {
     81 	unsigned long bit = 1;
     82 	unsigned long res = 0;
     83 
     84 	while (den < num && bit && !(den & (1L<<31))) {
     85 		den <<= 1;
     86 		bit <<= 1;
     87 	}
     88 
     89 	while (bit) {
     90 		if (num >= den) {
     91 			num -= den;
     92 			res |= bit;
     93 		}
     94 		bit >>= 1;
     95 		den >>= 1;
     96 	}
     97 
     98 	if (modwanted)
     99 		return num;
    100 
    101 	return res;
    102 }
    103 
    104 long
    105 __divsi3(long a, long b)
    106 {
    107 	int neg = 0;
    108 	long res;
    109 
    110 	if (a < 0) {
    111 		a = -a;
    112 		neg = !neg;
    113 	}
    114 
    115 	if (b < 0) {
    116 		b = -b;
    117 		neg = !neg;
    118 	}
    119 
    120 	res = udivmodsi4(a, b, 0);
    121 
    122 	if (neg)
    123 		res = -res;
    124 
    125 	return res;
    126 }
    127 
    128 long
    129 __modsi3(long a, long b)
    130 {
    131 	int neg = 0;
    132 	long res;
    133 
    134 	if (a < 0) {
    135 		a = -a;
    136 		neg = 1;
    137 	}
    138 
    139 	if (b < 0)
    140 		b = -b;
    141 
    142 	res = udivmodsi4(a, b, 1);
    143 
    144 	if (neg)
    145 		res = -res;
    146 
    147 	return res;
    148 }
    149 
    150 long
    151 __udivsi3(long a, long b)
    152 {
    153 	return udivmodsi4(a, b, 0);
    154 }
    155 
    156 long
    157 __umodsi3(long a, long b)
    158 {
    159 	return udivmodsi4(a, b, 1);
    160 }
    161