bcompiler.h (9899B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 */ 7 #ifndef BCOMPILER_COMPILER_H 8 #define BCOMPILER_COMPILER_H 9 10 /* 11 * The following macro is to satidfy compiler unused variable warnings. 12 */ 13 #define BCOMPILER_COMPILER_SATISFY(v) (void)(v) 14 15 # ifdef BE_HOST 16 # define b_u64_MSW 0 17 # define b_u64_LSW 1 18 # else /* LE_HOST */ 19 # define b_u64_MSW 1 20 # define b_u64_LSW 0 21 # endif /* LE_HOST */ 22 23 #ifdef LONGS_ARE_64BITS 24 25 #define BCOMPILER_COMPILER_64BIT 26 #define BCOMPILER_COMPILER_UINT64 unsigned long 27 #define BCOMPILER_COMPILER_INT64 long 28 #define bu64_H(v) (((buint32_t *) &(v))[b_u64_MSW]) 29 #define bu64_L(v) (((buint32_t *) &(v))[b_u64_LSW]) 30 31 #else /* !LONGS_ARE_64BITS */ 32 33 #ifdef COMPILER_HAS_LONGLONG 34 35 #define BCOMPILER_COMPILER_64BIT 36 #define BCOMPILER_COMPILER_UINT64 unsigned long long 37 #define BCOMPILER_COMPILER_INT64 long long 38 #define bu64_H(v) (((buint32_t *) &(v))[b_u64_MSW]) 39 #define bu64_L(v) (((buint32_t *) &(v))[b_u64_LSW]) 40 41 #else /* !COMPILER_HAS_LONGLONG */ 42 43 #define BCOMPILER_COMPILER_UINT64 struct { unsigned int u64_w[2]; } 44 #define BCOMPILER_COMPILER_INT64 struct { int u64_w[2]; } 45 #define bu64_H(v) ((v).u64_w[b_u64_MSW]) 46 #define bu64_L(v) ((v).u64_w[b_u64_LSW]) 47 48 #endif /* !COMPILER_HAS_LONGLONG */ 49 #endif /* LONGS_ARE_64BITS */ 50 51 /* 52 * 32-/64-bit type conversions 53 */ 54 55 #ifdef COMPILER_HAS_LONGLONG_SHIFT 56 57 #define BCOMPILER_COMPILER_64_TO_32_LO(dst, src) ((dst) = (buint32_t) (src)) 58 #define BCOMPILER_COMPILER_64_TO_32_HI(dst, src) ((dst) = (buint32_t) ((src) >> 32)) 59 #define BCOMPILER_COMPILER_64_HI(src) ((buint32_t) ((src) >> 32)) 60 #define BCOMPILER_COMPILER_64_LO(src) ((buint32_t) (src)) 61 #define BCOMPILER_COMPILER_64_ZERO(dst) ((dst) = 0) 62 #define BCOMPILER_COMPILER_64_IS_ZERO(src) ((src) == 0) 63 64 65 #define BCOMPILER_COMPILER_64_SET(dst, src_hi, src_lo) \ 66 ((dst) = (((buint64_t) (src_hi)) << 32) | ((buint64_t) (src_lo))) 67 68 #else /* !COMPILER_HAS_LONGLONG_SHIFT */ 69 70 #define BCOMPILER_COMPILER_64_TO_32_LO(dst, src) ((dst) = bu64_L(src)) 71 #define BCOMPILER_COMPILER_64_TO_32_HI(dst, src) ((dst) = bu64_H(src)) 72 #define BCOMPILER_COMPILER_64_HI(src) bu64_H(src) 73 #define BCOMPILER_COMPILER_64_LO(src) bu64_L(src) 74 #define BCOMPILER_COMPILER_64_ZERO(dst) (bu64_H(dst) = bu64_L(dst) = 0) 75 #define BCOMPILER_COMPILER_64_IS_ZERO(src) (bu64_H(src) == 0 && bu64_L(src) == 0) 76 77 #define BCOMPILER_COMPILER_64_SET(dst, src_hi, src_lo) \ 78 do { \ 79 bu64_H(dst) = (src_hi); \ 80 bu64_L(dst) = (src_lo); \ 81 } while (0) 82 83 #endif /* !COMPILER_HAS_LONGLONG_SHIFT */ 84 85 /* 86 * 64-bit addition and subtraction 87 */ 88 89 #ifdef COMPILER_HAS_LONGLONG_ADDSUB 90 91 #define BCOMPILER_COMPILER_64_ADD_64(dst, src) ((dst) += (src)) 92 #define BCOMPILER_COMPILER_64_ADD_32(dst, src) ((dst) += (src)) 93 #define BCOMPILER_COMPILER_64_SUB_64(dst, src) ((dst) -= (src)) 94 #define BCOMPILER_COMPILER_64_SUB_32(dst, src) ((dst) -= (src)) 95 96 #else /* !COMPILER_HAS_LONGLONG_ADDSUB */ 97 98 #define BCOMPILER_COMPILER_64_ADD_64(dst, src) \ 99 do { \ 100 buint32_t __t = bu64_L(dst); \ 101 bu64_L(dst) += bu64_L(src); \ 102 if (bu64_L(dst) < __t) { \ 103 bu64_H(dst) += bu64_H(src) + 1; \ 104 } else { \ 105 bu64_H(dst) += bu64_H(src); \ 106 } \ 107 } while (0) 108 #define BCOMPILER_COMPILER_64_ADD_32(dst, src) \ 109 do { \ 110 buint32_t __t = bu64_L(dst); \ 111 bu64_L(dst) += (src); \ 112 if (bu64_L(dst) < __t) { \ 113 bu64_H(dst)++; \ 114 } \ 115 } while (0) 116 #define BCOMPILER_COMPILER_64_SUB_64(dst, src) \ 117 do { \ 118 buint32_t __t = bu64_L(dst); \ 119 bu64_L(dst) -= bu64_L(src); \ 120 if (bu64_L(dst) > __t) { \ 121 bu64_H(dst) -= bu64_H(src) + 1; \ 122 } else { \ 123 bu64_H(dst) -= bu64_H(src); \ 124 } \ 125 } while (0) 126 #define BCOMPILER_COMPILER_64_SUB_32(dst, src) \ 127 do { \ 128 buint32_t __t = bu64_L(dst); \ 129 bu64_L(dst) -= (src); \ 130 if (bu64_L(dst) > __t) { \ 131 bu64_H(dst)--; \ 132 } \ 133 } while (0) 134 135 #endif /* !COMPILER_HAS_LONGLONG_ADDSUB */ 136 137 /* 138 * 64-bit logical operations 139 */ 140 141 #ifdef COMPILER_HAS_LONGLONG_ANDOR 142 143 #define BCOMPILER_COMPILER_64_AND(dst, src) ((dst) &= (src)) 144 #define BCOMPILER_COMPILER_64_OR(dst, src) ((dst) |= (src)) 145 #define BCOMPILER_COMPILER_64_XOR(dst, src) ((dst) ^= (src)) 146 #define BCOMPILER_COMPILER_64_NOT(dst) ((dst) = ~(dst)) 147 148 #else /* !COMPILER_HAS_LONGLONG_ANDOR */ 149 150 #define BCOMPILER_COMPILER_64_AND(dst, src) \ 151 do { \ 152 bu64_H(dst) &= bu64_H(src); \ 153 bu64_L(dst) &= bu64_L(src); \ 154 } while (0) 155 #define BCOMPILER_COMPILER_64_OR(dst, src) \ 156 do { \ 157 bu64_H(dst) |= bu64_H(src); \ 158 bu64_L(dst) |= bu64_L(src); \ 159 } while (0) 160 #define BCOMPILER_COMPILER_64_XOR(dst, src) \ 161 do { \ 162 bu64_H(dst) ^= bu64_H(src); \ 163 bu64_L(dst) ^= bu64_L(src); \ 164 } while (0) 165 #define BCOMPILER_COMPILER_64_NOT(dst) \ 166 do { \ 167 bu64_H(dst) = ~bu64_H(dst); \ 168 bu64_L(dst) = ~bu64_L(dst); \ 169 } while (0) 170 171 #endif /* !COMPILER_HAS_LONGLONG_ANDOR */ 172 173 #define BCOMPILER_COMPILER_64_ALLONES(dst) \ 174 BCOMPILER_COMPILER_64_ZERO(dst);\ 175 BCOMPILER_COMPILER_64_NOT(dst) 176 177 /* 178 * 64-bit shift 179 */ 180 181 #ifdef COMPILER_HAS_LONGLONG_SHIFT 182 183 #define BCOMPILER_COMPILER_64_SHL(dst, bits) ((dst) <<= (bits)) 184 #define BCOMPILER_COMPILER_64_SHR(dst, bits) ((dst) >>= (bits)) 185 186 #define BCOMPILER_COMPILER_64_BITTEST(val, n) \ 187 (!BCOMPILER_COMPILER_64_IS_ZERO(BCOMPILER_COMPILER_64_AND(val, ((buint64_t) 1) << (n))))) 188 189 #else /* COMPILER_HAS_LONGLONG_SHIFT */ 190 191 #define BCOMPILER_COMPILER_64_SHL(dst, bits) \ 192 do { \ 193 int __b = (bits); \ 194 if (__b >= 32) { \ 195 bu64_H(dst) = bu64_L(dst); \ 196 bu64_L(dst) = 0; \ 197 __b -= 32; \ 198 } \ 199 bu64_H(dst) = (bu64_H(dst) << __b) | \ 200 (__b ? bu64_L(dst) >> (32 - __b) : 0); \ 201 bu64_L(dst) <<= __b; \ 202 } while (0) 203 204 #define BCOMPILER_COMPILER_64_SHR(dst, bits) \ 205 do { \ 206 int __b = (bits); \ 207 if (__b >= 32) { \ 208 bu64_L(dst) = bu64_H(dst); \ 209 bu64_H(dst) = 0; \ 210 __b -= 32; \ 211 } \ 212 bu64_L(dst) = (bu64_L(dst) >> __b) | \ 213 (__b ? bu64_H(dst) << (32 - __b) : 0); \ 214 bu64_H(dst) >>= __b; \ 215 } while (0) 216 217 #define BCOMPILER_COMPILER_64_BITTEST(val, n) \ 218 ( (((n) < 32) && (bu64_L(val) & (1 << (n)))) || \ 219 (((n) >= 32) && (bu64_H(val) & (1 << ((n) - 32)))) ) 220 221 #endif /* !COMPILER_HAS_LONGLONG_SHIFT */ 222 223 /* 224 * 64-bit compare operations 225 */ 226 227 #ifdef COMPILER_HAS_LONGLONG_COMPARE 228 229 #define BCOMPILER_COMPILER_64_EQ(src1, src2) ((src1) == (src2)) 230 #define BCOMPILER_COMPILER_64_NE(src1, src2) ((src1) != (src2)) 231 #define BCOMPILER_COMPILER_64_LT(src1, src2) ((src1) < (src2)) 232 #define BCOMPILER_COMPILER_64_LE(src1, src2) ((src1) <= (src2)) 233 #define BCOMPILER_COMPILER_64_GT(src1, src2) ((src1) > (src2)) 234 #define BCOMPILER_COMPILER_64_GE(src1, src2) ((src1) >= (src2)) 235 236 #else /* !COMPILER_HAS_LONGLONG_COMPARE */ 237 238 #define BCOMPILER_COMPILER_64_EQ(src1, src2) (bu64_H(src1) == bu64_H(src2) && \ 239 bu64_L(src1) == bu64_L(src2)) 240 #define BCOMPILER_COMPILER_64_NE(src1, src2) (bu64_H(src1) != bu64_H(src2) || \ 241 bu64_L(src1) != bu64_L(src2)) 242 #define BCOMPILER_COMPILER_64_LT(src1, src2) (bu64_H(src1) < bu64_H(src2) || \ 243 ((bu64_H(src1) == bu64_H(src2) && \ 244 bu64_L(src1) < bu64_L(src2)))) 245 #define BCOMPILER_COMPILER_64_LE(src1, src2) (bu64_H(src1) < bu64_H(src2) || \ 246 ((bu64_H(src1) == bu64_H(src2) && \ 247 bu64_L(src1) <= bu64_L(src2)))) 248 #define BCOMPILER_COMPILER_64_GT(src1, src2) (bu64_H(src1) > bu64_H(src2) || \ 249 ((bu64_H(src1) == bu64_H(src2) && \ 250 bu64_L(src1) > bu64_L(src2)))) 251 #define BCOMPILER_COMPILER_64_GE(src1, src2) (bu64_H(src1) > bu64_H(src2) || \ 252 ((bu64_H(src1) == bu64_H(src2) && \ 253 bu64_L(src1) >= bu64_L(src2)))) 254 255 #endif /* !COMPILER_HAS_LONGLONG_COMPARE */ 256 257 /* Set up a mask of width bits offset lft_shft. No error checking */ 258 #define BCOMPILER_COMPILER_64_MASK_CREATE(dst, width, lft_shift) \ 259 do { \ 260 BCOMPILER_COMPILER_64_ALLONES(dst); \ 261 BCOMPILER_COMPILER_64_SHR((dst), (64 - (width))); \ 262 BCOMPILER_COMPILER_64_SHL((dst), (lft_shift)); \ 263 } while (0) 264 265 #define BCOMPILER_COMPILER_64_DELTA(src, last, new)\ 266 do { \ 267 BCOMPILER_COMPILER_64_ZERO(src);\ 268 BCOMPILER_COMPILER_64_ADD_64(src, new);\ 269 BCOMPILER_COMPILER_64_SUB_64(src, last);\ 270 } while(0) 271 272 /* 273 * Some macros for double support 274 * 275 * You can use the COMPILER_DOUBLE macro 276 * if you would prefer double precision, but it is not necessary. 277 * If you need more control (or you need to print :), then 278 * then you should use the COMPILER_HAS_DOUBLE macro explicitly. 279 */ 280 #ifdef COMPILER_HAS_DOUBLE 281 #define BCOMPILER_COMPILER_DOUBLE double 282 #define BCOMPILER_COMPILER_DOUBLE_FORMAT "f" 283 #define BCOMPILER_COMPILER_64_TO_DOUBLE(f, i64) \ 284 ((f) = BCOMPILER_COMPILER_64_HI(i64) * 4294967296.0 + BCOMPILER_COMPILER_64_LO(i64)) 285 #define BCOMPILER_COMPILER_32_TO_DOUBLE(f, i32) \ 286 ((f) = (double) (i32)) 287 #else 288 #define BCOMPILER_COMPILER_DOUBLE buint32_t 289 #define BCOMPILER_COMPILER_DOUBLE_FORMAT "u" 290 #define BCOMPILER_COMPILER_64_TO_DOUBLE(f, i64) ((f) = BCOMPILER_COMPILER_64_LO(i64)) 291 #define BCOMPILER_COMPILER_32_TO_DOUBLE(f, i32) ((f) = (i32)) 292 #endif 293 294 295 #endif /* BCOMPILER_COMPILER_H */ 296