(root)/
coreutils-9.4/
lib/
u64.h
       1  /* uint64_t-like operations that work even on hosts lacking uint64_t
       2  
       3     Copyright (C) 2006, 2009-2023 Free Software Foundation, Inc.
       4  
       5     This file is free software: you can redistribute it and/or modify
       6     it under the terms of the GNU Lesser General Public License as
       7     published by the Free Software Foundation; either version 2.1 of the
       8     License, or (at your option) any later version.
       9  
      10     This file is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13     GNU Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public License
      16     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      17  
      18  /* Written by Paul Eggert.  */
      19  
      20  /* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE.  */
      21  #if !_GL_CONFIG_H_INCLUDED
      22   #error "Please include config.h first."
      23  #endif
      24  
      25  #include <stdint.h>
      26  
      27  _GL_INLINE_HEADER_BEGIN
      28  #ifndef _GL_U64_INLINE
      29  # define _GL_U64_INLINE _GL_INLINE
      30  #endif
      31  
      32  /* Return X rotated left by N bits, where 0 < N < 64.  */
      33  #define u64rol(x, n) u64or (u64shl (x, n), u64shr (x, 64 - n))
      34  
      35  #ifdef UINT64_MAX
      36  
      37  /* Native implementations are trivial.  See below for comments on what
      38     these operations do.  */
      39  typedef uint64_t u64;
      40  # define u64hilo(hi, lo) ((u64) (((u64) (hi) << 32) + (lo)))
      41  # define u64init(hi, lo) u64hilo (hi, lo)
      42  # define u64lo(x) ((u64) (x))
      43  # define u64size(x) u64lo (x)
      44  # define u64lt(x, y) ((x) < (y))
      45  # define u64and(x, y) ((x) & (y))
      46  # define u64or(x, y) ((x) | (y))
      47  # define u64xor(x, y) ((x) ^ (y))
      48  # define u64plus(x, y) ((x) + (y))
      49  # define u64shl(x, n) ((x) << (n))
      50  # define u64shr(x, n) ((x) >> (n))
      51  
      52  #else
      53  
      54  /* u64 is a 64-bit unsigned integer value.
      55     u64init (HI, LO), is like u64hilo (HI, LO), but for use in
      56     initializer contexts.  */
      57  # ifdef WORDS_BIGENDIAN
      58  typedef struct { uint32_t hi, lo; } u64;
      59  #  define u64init(hi, lo) { hi, lo }
      60  # else
      61  typedef struct { uint32_t lo, hi; } u64;
      62  #  define u64init(hi, lo) { lo, hi }
      63  # endif
      64  
      65  /* Given the high and low-order 32-bit quantities HI and LO, return a u64
      66     value representing (HI << 32) + LO.  */
      67  _GL_U64_INLINE u64
      68  u64hilo (uint32_t hi, uint32_t lo)
      69  {
      70    u64 r;
      71    r.hi = hi;
      72    r.lo = lo;
      73    return r;
      74  }
      75  
      76  /* Return a u64 value representing LO.  */
      77  _GL_U64_INLINE u64
      78  u64lo (uint32_t lo)
      79  {
      80    u64 r;
      81    r.hi = 0;
      82    r.lo = lo;
      83    return r;
      84  }
      85  
      86  /* Return a u64 value representing SIZE.  */
      87  _GL_U64_INLINE u64
      88  u64size (size_t size)
      89  {
      90    u64 r;
      91    r.hi = size >> 31 >> 1;
      92    r.lo = size;
      93    return r;
      94  }
      95  
      96  /* Return X < Y.  */
      97  _GL_U64_INLINE int
      98  u64lt (u64 x, u64 y)
      99  {
     100    return x.hi < y.hi || (x.hi == y.hi && x.lo < y.lo);
     101  }
     102  
     103  /* Return X & Y.  */
     104  _GL_U64_INLINE u64
     105  u64and (u64 x, u64 y)
     106  {
     107    u64 r;
     108    r.hi = x.hi & y.hi;
     109    r.lo = x.lo & y.lo;
     110    return r;
     111  }
     112  
     113  /* Return X | Y.  */
     114  _GL_U64_INLINE u64
     115  u64or (u64 x, u64 y)
     116  {
     117    u64 r;
     118    r.hi = x.hi | y.hi;
     119    r.lo = x.lo | y.lo;
     120    return r;
     121  }
     122  
     123  /* Return X ^ Y.  */
     124  _GL_U64_INLINE u64
     125  u64xor (u64 x, u64 y)
     126  {
     127    u64 r;
     128    r.hi = x.hi ^ y.hi;
     129    r.lo = x.lo ^ y.lo;
     130    return r;
     131  }
     132  
     133  /* Return X + Y.  */
     134  _GL_U64_INLINE u64
     135  u64plus (u64 x, u64 y)
     136  {
     137    u64 r;
     138    r.lo = x.lo + y.lo;
     139    r.hi = x.hi + y.hi + (r.lo < x.lo);
     140    return r;
     141  }
     142  
     143  /* Return X << N.  */
     144  _GL_U64_INLINE u64
     145  u64shl (u64 x, int n)
     146  {
     147    u64 r;
     148    if (n < 32)
     149      {
     150        r.hi = (x.hi << n) | (x.lo >> (32 - n));
     151        r.lo = x.lo << n;
     152      }
     153    else
     154      {
     155        r.hi = x.lo << (n - 32);
     156        r.lo = 0;
     157      }
     158    return r;
     159  }
     160  
     161  /* Return X >> N.  */
     162  _GL_U64_INLINE u64
     163  u64shr (u64 x, int n)
     164  {
     165    u64 r;
     166    if (n < 32)
     167      {
     168        r.hi = x.hi >> n;
     169        r.lo = (x.hi << (32 - n)) | (x.lo >> n);
     170      }
     171    else
     172      {
     173        r.hi = 0;
     174        r.lo = x.hi >> (n - 32);
     175      }
     176    return r;
     177  }
     178  
     179  #endif
     180  
     181  _GL_INLINE_HEADER_END