1 /* ===-- lshrti3.c - Implement __lshrti3 -----------------------------------=== 2 * 3 * The LLVM Compiler Infrastructure 4 * 5 * This file is dual licensed under the MIT and the University of Illinois Open 6 * Source Licenses. See LICENSE.TXT for details. 7 * 8 * ===----------------------------------------------------------------------=== 9 * 10 * This file implements __lshrti3 for the compiler_rt library. 11 * 12 * ===----------------------------------------------------------------------=== 13 */ 14 15 /* Returns: logical a >> b */ 16 17 /* Precondition: 0 <= b < bits_in_tword */ 18 19 #include <sys/limits.h> 20 #include <sys/endian.h> 21 22 typedef int si_int; 23 typedef unsigned int su_int; 24 typedef long long di_int; 25 typedef unsigned long long du_int; 26 typedef int ti_int __attribute__ ((mode (TI))); 27 typedef int tu_int __attribute__ ((mode (TI))); 28 29 #if BYTE_ORDER == LITTLE_ENDIAN 30 #define _YUGA_LITTLE_ENDIAN 0 31 #else 32 #define _YUGA_LITTLE_ENDIAN 1 33 #endif 34 35 typedef union 36 { 37 tu_int all; 38 struct 39 { 40 #if _YUGA_LITTLE_ENDIAN 41 du_int low; 42 du_int high; 43 #else 44 du_int high; 45 du_int low; 46 #endif /* _YUGA_LITTLE_ENDIAN */ 47 }s; 48 } utwords; 49 50 51 ti_int 52 __lshrti3(ti_int a, si_int b) 53 { 54 const int bits_in_dword = (int)(sizeof(di_int) * CHAR_BIT); 55 utwords input; 56 utwords result; 57 input.all = a; 58 if (b & bits_in_dword) /* bits_in_dword <= b < bits_in_tword */ 59 { 60 result.s.high = 0; 61 result.s.low = input.s.high >> (b - bits_in_dword); 62 } 63 else /* 0 <= b < bits_in_dword */ 64 { 65 if (b == 0) 66 return a; 67 result.s.high = input.s.high >> b; 68 result.s.low = (input.s.high << (bits_in_dword - b)) | (input.s.low >> b); 69 } 70 return result.all; 71 } 72