int32.c (3350B)
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 2 // 3 // Consolidated per-op runtime helpers for kit's libkit_rt.a. 4 // The build compiles only this one file per directory; the per-op .c files 5 // are #included as snippets and not directly compiled. 6 // License: Apache-2.0 WITH LLVM-exception (see lib/LICENSE-compiler-rt.txt). 7 8 // ---- ashldi3.c ---- 9 #include "int_lib.h" 10 11 // Returns: a << b 12 13 // Precondition: 0 <= b < bits_in_dword 14 15 COMPILER_RT_ABI di_int __ashldi3(di_int a, int b) { 16 const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT); 17 dwords input; 18 dwords result; 19 input.all = a; 20 if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */ { 21 result.s.low = 0; 22 result.s.high = input.s.low << (b - bits_in_word); 23 } else /* 0 <= b < bits_in_word */ { 24 if (b == 0) return a; 25 result.s.low = input.s.low << b; 26 result.s.high = 27 ((su_int)input.s.high << b) | (input.s.low >> (bits_in_word - b)); 28 } 29 return result.all; 30 } 31 32 // ---- ashrdi3.c ---- 33 #include "int_lib.h" 34 35 // Returns: arithmetic a >> b 36 37 // Precondition: 0 <= b < bits_in_dword 38 39 COMPILER_RT_ABI di_int __ashrdi3(di_int a, int b) { 40 const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT); 41 dwords input; 42 dwords result; 43 input.all = a; 44 if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */ { 45 // result.s.high = input.s.high < 0 ? -1 : 0 46 result.s.high = input.s.high >> (bits_in_word - 1); 47 result.s.low = input.s.high >> (b - bits_in_word); 48 } else /* 0 <= b < bits_in_word */ { 49 if (b == 0) return a; 50 result.s.high = input.s.high >> b; 51 result.s.low = 52 ((su_int)input.s.high << (bits_in_word - b)) | (input.s.low >> b); 53 } 54 return result.all; 55 } 56 57 // ---- lshrdi3.c ---- 58 #include "int_lib.h" 59 60 // Returns: logical a >> b 61 62 // Precondition: 0 <= b < bits_in_dword 63 64 COMPILER_RT_ABI di_int __lshrdi3(di_int a, int b) { 65 const int bits_in_word = (int)(sizeof(si_int) * CHAR_BIT); 66 udwords input; 67 udwords result; 68 input.all = a; 69 if (b & bits_in_word) /* bits_in_word <= b < bits_in_dword */ { 70 result.s.high = 0; 71 result.s.low = input.s.high >> (b - bits_in_word); 72 } else /* 0 <= b < bits_in_word */ { 73 if (b == 0) return a; 74 result.s.high = input.s.high >> b; 75 result.s.low = (input.s.high << (bits_in_word - b)) | (input.s.low >> b); 76 } 77 return result.all; 78 } 79 80 // ---- muldi3.c ---- 81 #include "int_lib.h" 82 83 // Returns: a * b 84 85 static di_int __muldsi3(su_int a, su_int b) { 86 dwords r; 87 const int bits_in_word_2 = (int)(sizeof(si_int) * CHAR_BIT) / 2; 88 const su_int lower_mask = (su_int)~0 >> bits_in_word_2; 89 r.s.low = (a & lower_mask) * (b & lower_mask); 90 su_int t = r.s.low >> bits_in_word_2; 91 r.s.low &= lower_mask; 92 t += (a >> bits_in_word_2) * (b & lower_mask); 93 r.s.low += (t & lower_mask) << bits_in_word_2; 94 r.s.high = t >> bits_in_word_2; 95 t = r.s.low >> bits_in_word_2; 96 r.s.low &= lower_mask; 97 t += (b >> bits_in_word_2) * (a & lower_mask); 98 r.s.low += (t & lower_mask) << bits_in_word_2; 99 r.s.high += t >> bits_in_word_2; 100 r.s.high += (a >> bits_in_word_2) * (b >> bits_in_word_2); 101 return r.all; 102 } 103 104 // Returns: a * b 105 106 COMPILER_RT_ABI di_int __muldi3(di_int a, di_int b) { 107 dwords x; 108 x.all = a; 109 dwords y; 110 y.all = b; 111 dwords r; 112 r.all = __muldsi3(x.s.low, y.s.low); 113 r.s.high += x.s.high * y.s.low + x.s.low * y.s.high; 114 return r.all; 115 }