kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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 }