1/* uint64_t-like operations that work even on hosts lacking uint64_t 2 3 Copyright (C) 2006, 2009, 2010 Free Software Foundation, Inc. 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 3 of the License, or 8 (at your option) any later version. 9 10 This program 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 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18/* Written by Paul Eggert. */ 19 20#include <stddef.h> 21#include <stdint.h> 22 23/* Return X rotated left by N bits, where 0 < N < 64. */ 24#define u64rol(x, n) u64or (u64shl (x, n), u64shr (x, 64 - n)) 25 26#ifdef UINT64_MAX 27 28/* Native implementations are trivial. See below for comments on what 29 these operations do. */ 30typedef uint64_t u64; 31# define u64hilo(hi, lo) ((u64) (((u64) (hi) << 32) + (lo))) 32# define u64init(hi, lo) u64hilo (hi, lo) 33# define u64lo(x) ((u64) (x)) 34# define u64lt(x, y) ((x) < (y)) 35# define u64and(x, y) ((x) & (y)) 36# define u64or(x, y) ((x) | (y)) 37# define u64xor(x, y) ((x) ^ (y)) 38# define u64plus(x, y) ((x) + (y)) 39# define u64shl(x, n) ((x) << (n)) 40# define u64shr(x, n) ((x) >> (n)) 41 42#else 43 44/* u64 is a 64-bit unsigned integer value. 45 u64init (HI, LO), is like u64hilo (HI, LO), but for use in 46 initializer contexts. */ 47# ifdef WORDS_BIGENDIAN 48typedef struct { uint32_t hi, lo; } u64; 49# define u64init(hi, lo) { hi, lo } 50# else 51typedef struct { uint32_t lo, hi; } u64; 52# define u64init(hi, lo) { lo, hi } 53# endif 54 55/* Given the high and low-order 32-bit quantities HI and LO, return a u64 56 value representing (HI << 32) + LO. */ 57static inline u64 58u64hilo (uint32_t hi, uint32_t lo) 59{ 60 u64 r; 61 r.hi = hi; 62 r.lo = lo; 63 return r; 64} 65 66/* Return a u64 value representing LO. */ 67static inline u64 68u64lo (uint32_t lo) 69{ 70 u64 r; 71 r.hi = 0; 72 r.lo = lo; 73 return r; 74} 75 76/* Return X < Y. */ 77static inline int 78u64lt (u64 x, u64 y) 79{ 80 return x.hi < y.hi || (x.hi == y.hi && x.lo < y.lo); 81} 82 83/* Return X & Y. */ 84static inline u64 85u64and (u64 x, u64 y) 86{ 87 u64 r; 88 r.hi = x.hi & y.hi; 89 r.lo = x.lo & y.lo; 90 return r; 91} 92 93/* Return X | Y. */ 94static inline u64 95u64or (u64 x, u64 y) 96{ 97 u64 r; 98 r.hi = x.hi | y.hi; 99 r.lo = x.lo | y.lo; 100 return r; 101} 102 103/* Return X ^ Y. */ 104static inline u64 105u64xor (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. */ 114static inline u64 115u64plus (u64 x, u64 y) 116{ 117 u64 r; 118 r.lo = x.lo + y.lo; 119 r.hi = x.hi + y.hi + (r.lo < x.lo); 120 return r; 121} 122 123/* Return X << N. */ 124static inline u64 125u64shl (u64 x, int n) 126{ 127 u64 r; 128 if (n < 32) 129 { 130 r.hi = (x.hi << n) | (x.lo >> (32 - n)); 131 r.lo = x.lo << n; 132 } 133 else 134 { 135 r.hi = x.lo << (n - 32); 136 r.lo = 0; 137 } 138 return r; 139} 140 141/* Return X >> N. */ 142static inline u64 143u64shr (u64 x, int n) 144{ 145 u64 r; 146 if (n < 32) 147 { 148 r.hi = x.hi >> n; 149 r.lo = (x.hi << (32 - n)) | (x.lo >> n); 150 } 151 else 152 { 153 r.hi = 0; 154 r.lo = x.hi >> (n - 32); 155 } 156 return r; 157} 158 159#endif 160