/* MIT License * * Copyright (c) 2016-2017 INRIA and Microsoft Corporation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef __KREMLIB_BASE_H #define __KREMLIB_BASE_H #include #include #include #include #include #include /******************************************************************************/ /* Some macros to ease compatibility */ /******************************************************************************/ /* Define __cdecl and friends when using GCC, so that we can safely compile code * that contains __cdecl on all platforms. Note that this is in a separate * header so that Dafny-generated code can include just this file. */ #ifndef _MSC_VER /* Use the gcc predefined macros if on a platform/architectures that set them. * Otherwise define them to be empty. */ #ifndef __cdecl #define __cdecl #endif #ifndef __stdcall #define __stdcall #endif #ifndef __fastcall #define __fastcall #endif #endif #ifdef __GNUC__ # define inline __inline__ #endif /* GCC-specific attribute syntax; everyone else gets the standard C inline * attribute. */ #ifdef __GNU_C__ # ifndef __clang__ # define force_inline inline __attribute__((always_inline)) # else # define force_inline inline # endif #else # define force_inline inline #endif /******************************************************************************/ /* Implementing C.fst */ /******************************************************************************/ /* Uppercase issue; we have to define lowercase versions of the C macros (as we * have no way to refer to an uppercase *variable* in F*). */ extern int exit_success; extern int exit_failure; /* This one allows the user to write C.EXIT_SUCCESS. */ typedef int exit_code; void print_string(const char *s); void print_bytes(uint8_t *b, uint32_t len); /* The universal null pointer defined in C.Nullity.fst */ #define C_Nullity_null(X) 0 /* If some globals need to be initialized before the main, then kremlin will * generate and try to link last a function with this type: */ void kremlinit_globals(void); /******************************************************************************/ /* Implementation of machine integers (possibly of 128-bit integers) */ /******************************************************************************/ /* Integer types */ typedef uint64_t FStar_UInt64_t, FStar_UInt64_t_; typedef int64_t FStar_Int64_t, FStar_Int64_t_; typedef uint32_t FStar_UInt32_t, FStar_UInt32_t_; typedef int32_t FStar_Int32_t, FStar_Int32_t_; typedef uint16_t FStar_UInt16_t, FStar_UInt16_t_; typedef int16_t FStar_Int16_t, FStar_Int16_t_; typedef uint8_t FStar_UInt8_t, FStar_UInt8_t_; typedef int8_t FStar_Int8_t, FStar_Int8_t_; static inline uint32_t rotate32_left(uint32_t x, uint32_t n) { /* assert (n<32); */ return (x << n) | (x >> (32 - n)); } static inline uint32_t rotate32_right(uint32_t x, uint32_t n) { /* assert (n<32); */ return (x >> n) | (x << (32 - n)); } /* Constant time comparisons */ static inline uint8_t FStar_UInt8_eq_mask(uint8_t x, uint8_t y) { x = ~(x ^ y); x &= x << 4; x &= x << 2; x &= x << 1; return (int8_t)x >> 7; } static inline uint8_t FStar_UInt8_gte_mask(uint8_t x, uint8_t y) { return ~(uint8_t)(((int32_t)x - y) >> 31); } static inline uint16_t FStar_UInt16_eq_mask(uint16_t x, uint16_t y) { x = ~(x ^ y); x &= x << 8; x &= x << 4; x &= x << 2; x &= x << 1; return (int16_t)x >> 15; } static inline uint16_t FStar_UInt16_gte_mask(uint16_t x, uint16_t y) { return ~(uint16_t)(((int32_t)x - y) >> 31); } static inline uint32_t FStar_UInt32_eq_mask(uint32_t x, uint32_t y) { x = ~(x ^ y); x &= x << 16; x &= x << 8; x &= x << 4; x &= x << 2; x &= x << 1; return ((int32_t)x) >> 31; } static inline uint32_t FStar_UInt32_gte_mask(uint32_t x, uint32_t y) { return ~((uint32_t)(((int64_t)x - y) >> 63)); } static inline uint64_t FStar_UInt64_eq_mask(uint64_t x, uint64_t y) { x = ~(x ^ y); x &= x << 32; x &= x << 16; x &= x << 8; x &= x << 4; x &= x << 2; x &= x << 1; return ((int64_t)x) >> 63; } static inline uint64_t FStar_UInt64_gte_mask(uint64_t x, uint64_t y) { uint64_t low63 = ~((uint64_t)((int64_t)((int64_t)(x & UINT64_C(0x7fffffffffffffff)) - (int64_t)(y & UINT64_C(0x7fffffffffffffff))) >> 63)); uint64_t high_bit = ~((uint64_t)((int64_t)((int64_t)(x & UINT64_C(0x8000000000000000)) - (int64_t)(y & UINT64_C(0x8000000000000000))) >> 63)); return low63 & high_bit; } #endif