diff --git a/support/tock_intrinsics_arith.h b/support/tock_intrinsics_arith.h new file mode 100644 index 0000000..3bd09bc --- /dev/null +++ b/support/tock_intrinsics_arith.h @@ -0,0 +1,121 @@ +//Note that in the occam 2 manual, there is an error on page 104. +//They say that range is the number of storable values in INTEGER, +//their conceptual infinite type, so range would be infinity! +//However, it is clear from the following lines that range is +//the number of storable values in INT. + +#define occam_unsign(x) ((UINT)(x)) +#define occam_sign(x) ((INT)(x)) + +static inline INT occam_LONGADD (INT, INT, INT, const char *) occam_unused; +static inline INT occam_LONGADD (INT left, INT right, INT carry_in, const char *pos) { + if (left == __MAX(INT)) { + if (right == __MAX(INT)) { + occam_stop(pos, 3, "Overflow in LONGADD: %d + %d", left, right); + } else right += carry_in & 1; + } else left += carry_in & 1; + + if (((right<1)&&(__MIN(INT)-right<=left)) || ((right>=1)&&(__MAX(INT)-right>=left))) { + return left + right; + } else { + occam_stop(pos, 3, "Overflow in LONGADD: %d + %d", left, right); + } +} + +static inline INT occam_LONGSUM (INT, INT, INT, INT*, const char *) occam_unused; +static inline INT occam_LONGSUM (INT left, INT right, INT carry_in, INT* result1, const char *pos) { + UINT leftu = occam_unsign(left); + UINT rightu = occam_unsign(right); + if (leftu == __MAX(UINT)) { + if (rightu == __MAX(UINT)) { + *result1 = -2; + return 1; + } else rightu += carry_in & 1; + } else leftu += carry_in & 1; + + if (__MAX(UINT)-rightu>=leftu) { + *result1 = occam_sign(leftu + rightu); + return 0; + } else { + *result1 = occam_sign(leftu + rightu); + return 1; + } +} + +static inline INT occam_NORMALISE (INT, INT, INT*, INT*,const char *) occam_unused; +static inline INT occam_NORMALISE (INT hi_in, INT lo_in, INT* result1, INT* result2, const char *pos) { + if (hi_in == 0 && lo_in == 0) { + *result1 = *result2 = 0; + return 2*CHAR_BIT*sizeof(INT); + } else { + const INT highest_bit = __MIN(INT); + INT hi = hi_in; + INT lo = lo_in; + INT places = 0; + while ((hi & highest_bit) == 0) { + hi <<= 1; + hi |= (lo & highest_bit) >> ((CHAR_BIT*sizeof(INT))-1); + lo <<= 1; + places++; + } + *result1 = hi; + *result2 = lo; + return places; + } +} + +//////////////////// +//TODO implement, and move into the correct order above: +/////////////////// + +static inline INT occam_LONGSUB (INT, INT, const char *) occam_unused; +static inline INT occam_LONGSUB (INT left, INT right, INT borrow_in, const char *pos) { + return 0; +} + +static inline INT occam_LONGDIFF (INT, INT, INT, INT*, const char *) occam_unused; +static inline INT occam_LONGDIFF (INT left, INT right, INT borrow_in, INT* result1, const char *pos) { + return 0; +} + +static inline INT occam_LONGPROD (INT, INT, INT, INT*, const char *) occam_unused; +static inline INT occam_LONGPROD (INT left, INT right, INT carry_in, INT* result1, const char *pos) { + return 0; +} + +static inline INT occam_LONGDIV (INT, INT, INT, INT*, const char *) occam_unused; +static inline INT occam_LONGDIV (INT dividend_hi, INT dividend_lo, INT divisor, INT* result1, const char *pos) { + return 0; +} + +static inline INT occam_SHIFTRIGHT (INT, INT, INT, INT*, const char *) occam_unused; +static inline INT occam_SHIFTRIGHT (INT hi_in, INT lo_in, INT places, INT* result1, const char *pos) { + return 0; +} + +static inline INT occam_SHIFTLEFT (INT, INT, INT, INT*, const char *) occam_unused; +static inline INT occam_SHIFTLEFT (INT hi_in, INT lo_in, INT places, INT* result1, const char *pos) { + return 0; +} + +static inline INT occam_ASHIFTRIGHT (INT, INT, const char *) occam_unused; +static inline INT occam_ASHIFTRIGHT (INT x, INT places, const char *pos) { + return 0; +} + +static inline INT occam_ASHIFTLEFT (INT, INT, const char *) occam_unused; +static inline INT occam_ASHIFTLEFT (INT x, INT places, const char *pos) { + return 0; +} + +static inline INT occam_ROTATERIGHT (INT, INT, const char *) occam_unused; +static inline INT occam_ROTATERIGHT (INT x, INT places, const char *pos) { + return 0; +} + +static inline INT occam_ROTATELEFT (INT, INT, const char *) occam_unused; +static inline INT occam_ROTATELEFT (INT x, INT places, const char *pos) { + return 0; +} + + diff --git a/support/tock_intrinsics_float.h b/support/tock_intrinsics_float.h new file mode 100644 index 0000000..d467276 --- /dev/null +++ b/support/tock_intrinsics_float.h @@ -0,0 +1,96 @@ +static inline INT ADD_PREFIX(IEEECOMPARE) (REAL, REAL, const char*) occam_unused; +static inline INT ADD_PREFIX(IEEECOMPARE) (REAL X, REAL Y, const char* pos) { + return 0; +} +static inline BOOL SPLICE_SIZE(occam_IEEE,OP) (REAL, INT, INT, REAL, REAL*, const char*) occam_unused; +static inline BOOL SPLICE_SIZE(occam_IEEE,OP) (REAL X, INT Rm, INT Op, REAL Y, REAL* result1, const char* pos) { + return 0; +} +static inline BOOL SPLICE_SIZE(occam_IEEE,REM) (REAL, REAL, REAL*, const char*) occam_unused; +static inline BOOL SPLICE_SIZE(occam_IEEE,REM) (REAL X, REAL Y, REAL* result1, const char* pos) { + return 0; +} +static inline BOOL SPLICE_SIZE(occam_REAL,EQ) (REAL, REAL, const char*) occam_unused; +static inline BOOL SPLICE_SIZE(occam_REAL,EQ) (REAL X, REAL Y, const char* pos) { + return 0; +} +static inline BOOL SPLICE_SIZE(occam_REAL,GT) (REAL, REAL, const char*) occam_unused; +static inline BOOL SPLICE_SIZE(occam_REAL,GT) (REAL X, REAL Y, const char* pos) { + return 0; +} +static inline REAL SPLICE_SIZE(occam_REAL,OP) (REAL, INT, REAL, const char*) occam_unused; +static inline REAL SPLICE_SIZE(occam_REAL,OP) (REAL X, INT Op, REAL Y, const char* pos) { + return 0; +} +static inline REAL SPLICE_SIZE(occam_REAL,REM) (REAL, REAL, const char*) occam_unused; +static inline REAL SPLICE_SIZE(occam_REAL,REM) (REAL X, REAL Y, const char* pos) { + return 0; +} +#if SPLICE_SIZE(4,1) == 4321 +static inline BOOL occam_ARGUMENT_REDUCE (float, float, float, int32_t*, float*, const char*) occam_unused; +static inline BOOL occam_ARGUMENT_REDUCE (float X, float Y, float Y_err, int32_t* result1, float* result2, const char* pos) { + return 0; +} +#else +static inline BOOL occam_DARGUMENT_REDUCE (double, double, double, int32_t*, double*, const char*) occam_unused; +static inline BOOL occam_DARGUMENT_REDUCE (double X, double Y, double Y_err, int32_t* result1, double* result2, const char* pos) { + return 0; +} +#endif +static inline REAL ADD_PREFIX(ABS) (REAL, const char*) occam_unused; +static inline REAL ADD_PREFIX(ABS) (REAL X, const char* pos) { + return 0; +} +static inline REAL ADD_PREFIX(COPYSIGN) (REAL, REAL, const char*) occam_unused; +static inline REAL ADD_PREFIX(COPYSIGN) (REAL X, REAL Y, const char* pos) { + return 0; +} +static inline REAL ADD_PREFIX(DIVBY2) (REAL, const char*) occam_unused; +static inline REAL ADD_PREFIX(DIVBY2) (REAL X, const char* pos) { + return 0; +} +static inline INT ADD_PREFIX(FLOATING_UNPACK) (REAL, REAL*, const char*) occam_unused; +static inline INT ADD_PREFIX(FLOATING_UNPACK) (REAL X, REAL* result1, const char* pos) { + return 0; +} +static inline REAL ADD_PREFIX(FPINT) (REAL, const char*) occam_unused; +static inline REAL ADD_PREFIX(FPINT) (REAL X, const char* pos) { + return 0; +} +static inline BOOL ADD_PREFIX(ISNAN) (REAL, const char*) occam_unused; +static inline BOOL ADD_PREFIX(ISNAN) (REAL X, const char* pos) { + return 0; +} +static inline REAL ADD_PREFIX(LOGB) (REAL, const char*) occam_unused; +static inline REAL ADD_PREFIX(LOGB) (REAL X, const char* pos) { + return 0; +} +static inline REAL ADD_PREFIX(MINUSX) (REAL, const char*) occam_unused; +static inline REAL ADD_PREFIX(MINUSX) (REAL X, const char* pos) { + return 0; +} +static inline REAL ADD_PREFIX(MULBY2) (REAL, const char*) occam_unused; +static inline REAL ADD_PREFIX(MULBY2) (REAL X, const char* pos) { + return 0; +} +static inline REAL ADD_PREFIX(NEXTAFTER) (REAL, REAL, const char*) occam_unused; +static inline REAL ADD_PREFIX(NEXTAFTER) (REAL X, REAL Y, const char* pos) { + return 0; +} +static inline BOOL ADD_PREFIX(NOTFINITE) (REAL, const char*) occam_unused; +static inline BOOL ADD_PREFIX(NOTFINITE) (REAL X, const char* pos) { + return 0; +} +static inline BOOL ADD_PREFIX(ORDERED) (REAL, REAL, const char*) occam_unused; +static inline BOOL ADD_PREFIX(ORDERED) (REAL X, REAL Y, const char* pos) { + return 0; +} +static inline REAL ADD_PREFIX(SCALEB) (REAL, INT, const char*) occam_unused; +static inline REAL ADD_PREFIX(SCALEB) (REAL X, INT n, const char* pos) { + return 0; +} +static inline REAL ADD_PREFIX(SQRT) (REAL, const char*) occam_unused; +static inline REAL ADD_PREFIX(SQRT) (REAL X, const char* pos) { + return F(sqrt)(X); +} + diff --git a/support/tock_support.h b/support/tock_support.h index e5b5864..5afb2ae 100644 --- a/support/tock_support.h +++ b/support/tock_support.h @@ -397,16 +397,6 @@ int64_t occam_convert_double_int64_t_trunc (double v, const char *pos) { //{{{ intrinsics // FIXME These should do range checks. -static inline float occam_SQRT (float, const char *) occam_unused; -static inline float occam_SQRT (float v, const char *pos) { - return sqrtf (v); -} - -static inline double occam_DSQRT (double, const char *) occam_unused; -static inline double occam_DSQRT (double v, const char *pos) { - return sqrt (v); -} - //We use #define so we can #undef afterwards #if occam_INT_size == 4 #define INT int32_t @@ -417,73 +407,40 @@ static inline double occam_DSQRT (double v, const char *pos) { #else #error You must define occam_INT_size when using this header #endif -//Note that in the occam 2 manual, there is an error on page 104. -//They say that range is the number of storable values in INTEGER, -//their conceptual infinite type, so range would be infinity! -//However, it is clear from the following lines that range is -//the number of storable values in INT. -#define occam_unsign(x) ((UINT)(x)) -#define occam_sign(x) ((INT)(x)) +#ifdef __cplusplus +#define BOOL bool +#else +#define BOOL _Bool +#endif -static inline INT occam_LONGADD (INT, INT, INT, const char *) occam_unused; -static inline INT occam_LONGADD (INT left, INT right, INT carry_in, const char *pos) { - if (left == __MAX(INT)) { - if (right == __MAX(INT)) { - occam_stop(pos, 3, "Overflow in LONGADD: %d + %d", left, right); - } else right += carry_in & 1; - } else left += carry_in & 1; +#include "tock_intrinsics_arith.h" +#define REAL float +#define RINT int32_t +#define ADD_PREFIX(a) occam_##a +#define F(func) func##f +#define SPLICE_SIZE(a,b) a##32##b +#include "tock_intrinsics_float.h" +#undef REAL +#undef RINT +#undef ADD_PREFIX +#undef SPLICE_SIZE +#undef F +#define REAL double +#define RINT int64_t +#define ADD_PREFIX(a) occam_D##a +#define SPLICE_SIZE(a,b) a##64##b +#define F(func) func +#include "tock_intrinsics_float.h" - if (((right<1)&&(__MIN(INT)-right<=left)) || ((right>=1)&&(__MAX(INT)-right>=left))) { - return left + right; - } else { - occam_stop(pos, 3, "Overflow in LONGADD: %d + %d", left, right); - } -} - -static inline INT occam_LONGSUM (INT, INT, INT, INT*, const char *) occam_unused; -static inline INT occam_LONGSUM (INT left, INT right, INT carry_in, INT* result1, const char *pos) { - const UINT leftu = occam_unsign(left); - const UINT rightu = occam_unsign(right); - if (leftu == __MAX(UINT)) { - if (rightu == __MAX(UINT)) { - *result1 = -2; - return 1; - } else rightu += carry_in & 1; - } else leftu += carry_in & 1; - - if (__MAX(UINT)-rightu>=leftu) { - *result1 = occam_sign(leftu + rightu); - return 0; - } else { - *result1 = occam_sign(leftu + rightu); - return 1; - } -} - -static inline INT occam_NORMALISE (INT, INT, INT*, INT*,const char *) occam_unused; -static inline INT occam_NORMALISE (INT hi_in, INT lo_in, INT* result1, INT* result2, const char *pos) { - if (hi_in == 0 && lo_in == 0) { - *result1 = *result2 = 0; - return 2*CHAR_BIT*sizeof(INT); - } else { - const INT highest_bit = __MIN(INT); - INT hi = hi_in; - INT lo = lo_in; - INT places = 0; - while ((hi & highest_bit) == 0) { - hi <<= 1; - hi |= (lo & highest_bit) >> ((CHAR_BIT*sizeof(INT))-1); - lo <<= 1; - places++; - } - *result1 = hi; - *result2 = lo; - return places; - } -} #undef INT #undef UINT +#undef REAL +#undef RINT +#undef ADD_PREFIX +#undef SPLICE_SIZE +#undef F + //}}}