Implemented much more of the support functions, and renamed some of the uglier types
This commit is contained in:
parent
c4f625b1ba
commit
6e4e9c1808
|
@ -4,30 +4,30 @@
|
|||
//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))
|
||||
#define occam_unsign(x) ((OCCAM_UINT)(x))
|
||||
#define occam_sign(x) ((OCCAM_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)) {
|
||||
static inline OCCAM_INT occam_LONGADD (OCCAM_INT, OCCAM_INT, OCCAM_INT, const char *) occam_unused;
|
||||
static inline OCCAM_INT occam_LONGADD (OCCAM_INT left, OCCAM_INT right, OCCAM_INT carry_in, const char *pos) {
|
||||
if (left == __MAX(OCCAM_INT)) {
|
||||
if (right == __MAX(OCCAM_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))) {
|
||||
if (((right<1)&&(__MIN(OCCAM_INT)-right<=left)) || ((right>=1)&&(__MAX(OCCAM_INT)-right>=left))) {
|
||||
return left + right;
|
||||
} else {
|
||||
occam_stop(pos, 3, "Overflow in LONGADD: %d + %d", left, right);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
UINT leftu = occam_unsign(left);
|
||||
UINT rightu = occam_unsign(right);
|
||||
static inline OCCAM_INT occam_LONGDIFF (OCCAM_INT, OCCAM_INT, OCCAM_INT, OCCAM_INT*, const char *) occam_unused;
|
||||
static inline OCCAM_INT occam_LONGDIFF (OCCAM_INT left, OCCAM_INT right, OCCAM_INT borrow_in, OCCAM_INT* result1, const char *pos) {
|
||||
OCCAM_UINT leftu = occam_unsign(left);
|
||||
OCCAM_UINT rightu = occam_unsign(right);
|
||||
if (leftu == 0) {
|
||||
if (rightu == __MAX(UINT)) {
|
||||
if (rightu == __MAX(OCCAM_UINT)) {
|
||||
*result1 = 1 - (borrow_in & 1);
|
||||
return 1;
|
||||
} else rightu += borrow_in & 1;
|
||||
|
@ -43,23 +43,23 @@ static inline INT occam_LONGDIFF (INT left, INT right, INT borrow_in, INT* resul
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
const UINT leftu = occam_unsign(left);
|
||||
const UINT rightu = occam_unsign(right);
|
||||
const UINT carryu = occam_unsign(carry_in);
|
||||
#define HI_HALF(x) (x >> (CHAR_BIT*sizeof(INT)/2))
|
||||
#define LO_HALF(x) (x & ((1<<(CHAR_BIT*sizeof(INT)/2))-1))
|
||||
#define MAKE_HI(x) (x << (CHAR_BIT*sizeof(INT)/2))
|
||||
const UINT leftu_hi = HI_HALF(leftu);
|
||||
const UINT rightu_hi = HI_HALF(rightu);
|
||||
const UINT leftu_lo = LO_HALF(leftu);
|
||||
const UINT rightu_lo = LO_HALF(rightu);
|
||||
static inline OCCAM_INT occam_LONGPROD (OCCAM_INT, OCCAM_INT, OCCAM_INT, OCCAM_INT*, const char *) occam_unused;
|
||||
static inline OCCAM_INT occam_LONGPROD (OCCAM_INT left, OCCAM_INT right, OCCAM_INT carry_in, OCCAM_INT* result1, const char *pos) {
|
||||
const OCCAM_UINT leftu = occam_unsign(left);
|
||||
const OCCAM_UINT rightu = occam_unsign(right);
|
||||
const OCCAM_UINT carryu = occam_unsign(carry_in);
|
||||
#define HI_HALF(x) (x >> (CHAR_BIT*sizeof(OCCAM_INT)/2))
|
||||
#define LO_HALF(x) (x & ((1<<(CHAR_BIT*sizeof(OCCAM_INT)/2))-1))
|
||||
#define MAKE_HI(x) (x << (CHAR_BIT*sizeof(OCCAM_INT)/2))
|
||||
const OCCAM_UINT leftu_hi = HI_HALF(leftu);
|
||||
const OCCAM_UINT rightu_hi = HI_HALF(rightu);
|
||||
const OCCAM_UINT leftu_lo = LO_HALF(leftu);
|
||||
const OCCAM_UINT rightu_lo = LO_HALF(rightu);
|
||||
|
||||
UINT prod_lo = leftu_lo * rightu_lo;
|
||||
UINT prod_hi = leftu_hi * rightu_hi;
|
||||
const UINT prod_med0 = leftu_lo * rightu_hi;
|
||||
const UINT prod_med1 = leftu_hi * rightu_lo;
|
||||
OCCAM_UINT prod_lo = leftu_lo * rightu_lo;
|
||||
OCCAM_UINT prod_hi = leftu_hi * rightu_hi;
|
||||
const OCCAM_UINT prod_med0 = leftu_lo * rightu_hi;
|
||||
const OCCAM_UINT prod_med1 = leftu_hi * rightu_lo;
|
||||
//E.g.s given for 8-bit, L=15,M=255:
|
||||
//prod_hi has max value 225 (L*L)
|
||||
//HI_HALF(prod_med0|1) has max value 14 (L*L)/(L+1)
|
||||
|
@ -68,13 +68,13 @@ static inline INT occam_LONGPROD (INT left, INT right, INT carry_in, INT* result
|
|||
//prod_hi cannot overflow from these carries,
|
||||
//As mathematically, (M*M)+M < ((M+1)*(M+1)) - 1
|
||||
|
||||
prod_hi += (__MAX(UINT) - prod_lo >= MAKE_HI(LO_HALF(prod_med0))) ? 0 : 1;
|
||||
prod_hi += (__MAX(OCCAM_UINT) - prod_lo >= MAKE_HI(LO_HALF(prod_med0))) ? 0 : 1;
|
||||
prod_lo += MAKE_HI(LO_HALF(prod_med0));
|
||||
|
||||
prod_hi += (__MAX(UINT) - prod_lo >= MAKE_HI(LO_HALF(prod_med1))) ? 0 : 1;
|
||||
prod_hi += (__MAX(OCCAM_UINT) - prod_lo >= MAKE_HI(LO_HALF(prod_med1))) ? 0 : 1;
|
||||
prod_lo += MAKE_HI(LO_HALF(prod_med1));
|
||||
|
||||
prod_hi += (__MAX(UINT) - prod_lo >= carryu) ? 0 : 1;
|
||||
prod_hi += (__MAX(OCCAM_UINT) - prod_lo >= carryu) ? 0 : 1;
|
||||
prod_lo += carryu;
|
||||
|
||||
*result1 = occam_sign(prod_lo);
|
||||
|
@ -84,33 +84,33 @@ static inline INT occam_LONGPROD (INT left, INT right, INT carry_in, INT* result
|
|||
#undef MAKE_HI
|
||||
}
|
||||
|
||||
static inline INT occam_LONGSUB (INT, INT, INT, const char *) occam_unused;
|
||||
static inline INT occam_LONGSUB (INT left, INT right, INT borrow_in, const char *pos) {
|
||||
if (left == __MIN(INT)) {
|
||||
if (right == __MIN(INT)) {
|
||||
static inline OCCAM_INT occam_LONGSUB (OCCAM_INT, OCCAM_INT, OCCAM_INT, const char *) occam_unused;
|
||||
static inline OCCAM_INT occam_LONGSUB (OCCAM_INT left, OCCAM_INT right, OCCAM_INT borrow_in, const char *pos) {
|
||||
if (left == __MIN(OCCAM_INT)) {
|
||||
if (right == __MIN(OCCAM_INT)) {
|
||||
occam_stop(pos, 3, "Overflow in LONGSUB: %d - %d", left, right);
|
||||
} else right -= borrow_in & 1;
|
||||
} else left -= borrow_in & 1;
|
||||
|
||||
if (((right<1)&&(__MAX(INT)+right>=left)) || ((right>=1)&&(__MIN(INT)+right<=left))) {
|
||||
if (((right<1)&&(__MAX(OCCAM_INT)+right>=left)) || ((right>=1)&&(__MIN(OCCAM_INT)+right<=left))) {
|
||||
return left - right;
|
||||
} else {
|
||||
occam_stop(pos, 3, "Overflow in LONGSUB: %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)) {
|
||||
static inline OCCAM_INT occam_LONGSUM (OCCAM_INT, OCCAM_INT, OCCAM_INT, OCCAM_INT*, const char *) occam_unused;
|
||||
static inline OCCAM_INT occam_LONGSUM (OCCAM_INT left, OCCAM_INT right, OCCAM_INT carry_in, OCCAM_INT* result1, const char *pos) {
|
||||
OCCAM_UINT leftu = occam_unsign(left);
|
||||
OCCAM_UINT rightu = occam_unsign(right);
|
||||
if (leftu == __MAX(OCCAM_UINT)) {
|
||||
if (rightu == __MAX(OCCAM_UINT)) {
|
||||
*result1 = -2 + (carry_in & 1);
|
||||
return 1;
|
||||
} else rightu += carry_in & 1;
|
||||
} else leftu += carry_in & 1;
|
||||
|
||||
if (__MAX(UINT)-rightu>=leftu) {
|
||||
if (__MAX(OCCAM_UINT)-rightu>=leftu) {
|
||||
*result1 = occam_sign(leftu + rightu);
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -120,19 +120,19 @@ static inline INT occam_LONGSUM (INT left, INT right, INT carry_in, INT* result1
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
static inline OCCAM_INT occam_NORMALISE (OCCAM_INT, OCCAM_INT, OCCAM_INT*, OCCAM_INT*,const char *) occam_unused;
|
||||
static inline OCCAM_INT occam_NORMALISE (OCCAM_INT hi_in, OCCAM_INT lo_in, OCCAM_INT* result1, OCCAM_INT* result2, const char *pos) {
|
||||
if (hi_in == 0 && lo_in == 0) {
|
||||
*result1 = *result2 = 0;
|
||||
return 2*CHAR_BIT*sizeof(INT);
|
||||
return 2*CHAR_BIT*sizeof(OCCAM_INT);
|
||||
} else {
|
||||
const INT highest_bit = __MIN(INT);
|
||||
INT hi = hi_in;
|
||||
INT lo = lo_in;
|
||||
INT places = 0;
|
||||
const OCCAM_INT highest_bit = __MIN(OCCAM_INT);
|
||||
OCCAM_INT hi = hi_in;
|
||||
OCCAM_INT lo = lo_in;
|
||||
OCCAM_INT places = 0;
|
||||
while ((hi & highest_bit) == 0) {
|
||||
hi <<= 1;
|
||||
hi |= (lo & highest_bit) >> ((CHAR_BIT*sizeof(INT))-1);
|
||||
hi |= (lo & highest_bit) >> ((CHAR_BIT*sizeof(OCCAM_INT))-1);
|
||||
lo <<= 1;
|
||||
places++;
|
||||
}
|
||||
|
@ -144,11 +144,11 @@ static inline INT occam_NORMALISE (INT hi_in, INT lo_in, INT* result1, INT* resu
|
|||
|
||||
//Has to go late on due to its function re-use:
|
||||
|
||||
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) {
|
||||
UINT top_hi = occam_unsign(dividend_hi);
|
||||
UINT top_lo = occam_unsign(dividend_lo);
|
||||
const UINT bottom = occam_unsign(divisor);
|
||||
static inline OCCAM_INT occam_LONGDIV (OCCAM_INT, OCCAM_INT, OCCAM_INT, OCCAM_INT*, const char *) occam_unused;
|
||||
static inline OCCAM_INT occam_LONGDIV (OCCAM_INT dividend_hi, OCCAM_INT dividend_lo, OCCAM_INT divisor, OCCAM_INT* result1, const char *pos) {
|
||||
OCCAM_UINT top_hi = occam_unsign(dividend_hi);
|
||||
OCCAM_UINT top_lo = occam_unsign(dividend_lo);
|
||||
const OCCAM_UINT bottom = occam_unsign(divisor);
|
||||
|
||||
//Intuititively, the algorithm works as follows:
|
||||
//We work out how many Hi there are remaining in the
|
||||
|
@ -162,16 +162,16 @@ static inline INT occam_LONGDIV (INT dividend_hi, INT dividend_lo, INT divisor,
|
|||
if (bottom == 0) {
|
||||
occam_stop(pos, 1, "Division by zero in LONGDIV");
|
||||
} else {
|
||||
UINT r_hi = 0;
|
||||
UINT r_lo = 0;
|
||||
OCCAM_UINT r_hi = 0;
|
||||
OCCAM_UINT r_lo = 0;
|
||||
|
||||
UINT amount_extra_R_over_bot = 0;
|
||||
OCCAM_UINT amount_extra_R_over_bot = 0;
|
||||
|
||||
//We can work R/bot out by doing:
|
||||
// (R/2)/bot + ((R/2)%bot + (R/2)/bot
|
||||
const UINT halfR = occam_unsign(__MIN(INT));
|
||||
UINT R_over_bot = bottom >= halfR ? 1 : (halfR/bottom + ((halfR % bottom) + halfR) / bottom);
|
||||
UINT R_mod_bot = (__MAX(UINT)%bottom) == bottom - 1 ? 0 : 1+(__MAX(UINT)%bottom);
|
||||
const OCCAM_UINT halfR = occam_unsign(__MIN(OCCAM_INT));
|
||||
OCCAM_UINT R_over_bot = bottom >= halfR ? 1 : (halfR/bottom + ((halfR % bottom) + halfR) / bottom);
|
||||
OCCAM_UINT R_mod_bot = (__MAX(OCCAM_UINT)%bottom) == bottom - 1 ? 0 : 1+(__MAX(OCCAM_UINT)%bottom);
|
||||
|
||||
while (top_hi != 0) {
|
||||
r_hi += top_hi / bottom;
|
||||
|
@ -179,17 +179,17 @@ static inline INT occam_LONGDIV (INT dividend_hi, INT dividend_lo, INT divisor,
|
|||
top_lo %= bottom;
|
||||
top_hi %= bottom;
|
||||
amount_extra_R_over_bot += top_hi;
|
||||
top_hi = occam_unsign(occam_LONGPROD(occam_sign(top_hi),occam_sign(R_mod_bot),occam_sign(top_lo),(INT*)&top_lo,pos));
|
||||
top_hi = occam_unsign(occam_LONGPROD(occam_sign(top_hi),occam_sign(R_mod_bot),occam_sign(top_lo),(OCCAM_INT*)&top_lo,pos));
|
||||
}
|
||||
|
||||
//long-add the results from top_lo/bottom to r_hi,r_lo:
|
||||
r_hi += occam_unsign(occam_LONGSUM(occam_sign(r_lo),occam_sign(top_lo/bottom),0,(INT*)&r_lo,pos));
|
||||
r_hi += occam_unsign(occam_LONGSUM(occam_sign(r_lo),occam_sign(top_lo/bottom),0,(OCCAM_INT*)&r_lo,pos));
|
||||
//Save the remainder for later:
|
||||
const UINT rem = top_lo%bottom;
|
||||
const OCCAM_UINT rem = top_lo%bottom;
|
||||
|
||||
//Finally, add on R_over_bot * amount_extra_R_over_bot
|
||||
top_hi = occam_unsign(occam_LONGPROD(occam_sign(R_over_bot), occam_sign(amount_extra_R_over_bot), 0, (INT*)&top_lo,pos));
|
||||
r_hi += top_hi + occam_unsign(occam_LONGSUM(occam_sign(r_lo), occam_sign(top_lo), 0, (INT*)&r_lo, pos));
|
||||
top_hi = occam_unsign(occam_LONGPROD(occam_sign(R_over_bot), occam_sign(amount_extra_R_over_bot), 0, (OCCAM_INT*)&top_lo,pos));
|
||||
r_hi += top_hi + occam_unsign(occam_LONGSUM(occam_sign(r_lo), occam_sign(top_lo), 0, (OCCAM_INT*)&r_lo, pos));
|
||||
|
||||
if (r_hi == 0) {
|
||||
*result1 = occam_sign(rem);
|
||||
|
@ -200,63 +200,63 @@ static inline INT occam_LONGDIV (INT dividend_hi, INT dividend_lo, INT divisor,
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
if (places >= (INT)(CHAR_BIT*sizeof(INT))) {
|
||||
static inline OCCAM_INT occam_SHIFTLEFT (OCCAM_INT, OCCAM_INT, OCCAM_INT, OCCAM_INT*, const char *) occam_unused;
|
||||
static inline OCCAM_INT occam_SHIFTLEFT (OCCAM_INT hi_in, OCCAM_INT lo_in, OCCAM_INT places, OCCAM_INT* result1, const char *pos) {
|
||||
if (places >= (OCCAM_INT)(CHAR_BIT*sizeof(OCCAM_INT))) {
|
||||
*result1 = 0;
|
||||
return occam_sign(occam_unsign(lo_in) << (places - CHAR_BIT*sizeof(INT)));
|
||||
return occam_sign(occam_unsign(lo_in) << (places - CHAR_BIT*sizeof(OCCAM_INT)));
|
||||
} else {
|
||||
const UINT r_lo = occam_unsign(lo_in) << places;
|
||||
const UINT r_hi = (occam_unsign(hi_in) << places) | (occam_unsign(lo_in) >> (CHAR_BIT*sizeof(INT)-places));
|
||||
const OCCAM_UINT r_lo = occam_unsign(lo_in) << places;
|
||||
const OCCAM_UINT r_hi = (occam_unsign(hi_in) << places) | (occam_unsign(lo_in) >> (CHAR_BIT*sizeof(OCCAM_INT)-places));
|
||||
*result1 = occam_sign(r_lo);
|
||||
return r_hi;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
if (places >= (INT)(CHAR_BIT*sizeof(INT))) {
|
||||
*result1 = occam_sign(occam_unsign(hi_in) >> (places - CHAR_BIT*sizeof(INT)));
|
||||
static inline OCCAM_INT occam_SHIFTRIGHT (OCCAM_INT, OCCAM_INT, OCCAM_INT, OCCAM_INT*, const char *) occam_unused;
|
||||
static inline OCCAM_INT occam_SHIFTRIGHT (OCCAM_INT hi_in, OCCAM_INT lo_in, OCCAM_INT places, OCCAM_INT* result1, const char *pos) {
|
||||
if (places >= (OCCAM_INT)(CHAR_BIT*sizeof(OCCAM_INT))) {
|
||||
*result1 = occam_sign(occam_unsign(hi_in) >> (places - CHAR_BIT*sizeof(OCCAM_INT)));
|
||||
return 0;
|
||||
} else {
|
||||
const UINT r_hi = occam_unsign(hi_in) >> places;
|
||||
const UINT r_lo = (occam_unsign(lo_in) >> places) | (occam_unsign(hi_in) << (CHAR_BIT*sizeof(INT)-places));
|
||||
const OCCAM_UINT r_hi = occam_unsign(hi_in) >> places;
|
||||
const OCCAM_UINT r_lo = (occam_unsign(lo_in) >> places) | (occam_unsign(hi_in) << (CHAR_BIT*sizeof(OCCAM_INT)-places));
|
||||
*result1 = occam_sign(r_lo);
|
||||
return r_hi;
|
||||
}
|
||||
}
|
||||
|
||||
static inline INT occam_ASHIFTRIGHT (INT, INT, const char *) occam_unused;
|
||||
static inline INT occam_ASHIFTRIGHT (INT x, INT places, const char *pos) {
|
||||
static inline OCCAM_INT occam_ASHIFTRIGHT (OCCAM_INT, OCCAM_INT, const char *) occam_unused;
|
||||
static inline OCCAM_INT occam_ASHIFTRIGHT (OCCAM_INT x, OCCAM_INT places, const char *pos) {
|
||||
return x >> places;
|
||||
}
|
||||
|
||||
static inline INT occam_ASHIFTLEFT (INT, INT, const char *) occam_unused;
|
||||
static inline INT occam_ASHIFTLEFT (INT x, INT places, const char *pos) {
|
||||
static inline OCCAM_INT occam_ASHIFTLEFT (OCCAM_INT, OCCAM_INT, const char *) occam_unused;
|
||||
static inline OCCAM_INT occam_ASHIFTLEFT (OCCAM_INT x, OCCAM_INT places, const char *pos) {
|
||||
//Overflows if positive and 1 bits are shifted out or highest bit ends as 1,
|
||||
//or negative and 0 bits are shifted out or highest bit ends as 0
|
||||
if (places > (INT)(CHAR_BIT*sizeof(INT))
|
||||
if (places > (OCCAM_INT)(CHAR_BIT*sizeof(OCCAM_INT))
|
||||
|| places < 0
|
||||
|| (places == (INT)(CHAR_BIT*sizeof(INT)) && x != 0)) {
|
||||
|| (places == (OCCAM_INT)(CHAR_BIT*sizeof(OCCAM_INT)) && x != 0)) {
|
||||
occam_stop(pos,3,"Overflow in ASHIFTLEFT(%d,%d)",x,places);
|
||||
}
|
||||
else if (places != (INT)(CHAR_BIT*sizeof(INT)) && places != 0 &&
|
||||
(occam_unsign(x) >> (CHAR_BIT*sizeof(INT)-places-1) !=
|
||||
occam_unsign(x < 0 ? (INT)-1 : (INT)0) >> (CHAR_BIT*sizeof(INT)-places-1))) {
|
||||
else if (places != (OCCAM_INT)(CHAR_BIT*sizeof(OCCAM_INT)) && places != 0 &&
|
||||
(occam_unsign(x) >> (CHAR_BIT*sizeof(OCCAM_INT)-places-1) !=
|
||||
occam_unsign(x < 0 ? (OCCAM_INT)-1 : (OCCAM_INT)0) >> (CHAR_BIT*sizeof(OCCAM_INT)-places-1))) {
|
||||
occam_stop(pos,3,"Overflow in ASHIFTLEFT(%d,%d)",x,places);
|
||||
} else {
|
||||
return (x << places);
|
||||
}
|
||||
}
|
||||
|
||||
static inline INT occam_ROTATERIGHT (INT, INT, const char *) occam_unused;
|
||||
static inline INT occam_ROTATERIGHT (INT x, INT places, const char *pos) {
|
||||
return (INT)((UINT)x >> places) | (x << (CHAR_BIT*sizeof(INT) - places));
|
||||
static inline OCCAM_INT occam_ROTATERIGHT (OCCAM_INT, OCCAM_INT, const char *) occam_unused;
|
||||
static inline OCCAM_INT occam_ROTATERIGHT (OCCAM_INT x, OCCAM_INT places, const char *pos) {
|
||||
return (OCCAM_INT)((OCCAM_UINT)x >> places) | (x << (CHAR_BIT*sizeof(OCCAM_INT) - places));
|
||||
}
|
||||
|
||||
static inline INT occam_ROTATELEFT (INT, INT, const char *) occam_unused;
|
||||
static inline INT occam_ROTATELEFT (INT x, INT places, const char *pos) {
|
||||
return (x << places) | (INT)((UINT)x >> (CHAR_BIT*sizeof(INT) - places));
|
||||
static inline OCCAM_INT occam_ROTATELEFT (OCCAM_INT, OCCAM_INT, const char *) occam_unused;
|
||||
static inline OCCAM_INT occam_ROTATELEFT (OCCAM_INT x, OCCAM_INT places, const char *pos) {
|
||||
return (x << places) | (OCCAM_INT)((OCCAM_UINT)x >> (CHAR_BIT*sizeof(OCCAM_INT) - places));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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) {
|
||||
static inline OCCAM_INT ADD_PREFIX(IEEECOMPARE) (REAL, REAL, const char*) occam_unused;
|
||||
static inline OCCAM_INT ADD_PREFIX(IEEECOMPARE) (REAL X, REAL Y, const char* pos) {
|
||||
if (isunordered(X,Y)) {
|
||||
return 2;
|
||||
} else if (isgreater(X,Y)) {
|
||||
|
@ -10,8 +10,8 @@ static inline INT ADD_PREFIX(IEEECOMPARE) (REAL X, REAL Y, const char* pos) {
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
static inline OCCAM_BOOL SPLICE_SIZE(occam_IEEE,OP) (REAL, INT, INT, REAL, REAL*, const char*) occam_unused;
|
||||
static inline OCCAM_BOOL SPLICE_SIZE(occam_IEEE,OP) (REAL X, INT Rm, INT Op, REAL Y, REAL* result1, const char* pos) {
|
||||
static inline OCCAM_BOOL SPLICE_SIZE(occam_IEEE,OP) (REAL, OCCAM_INT, OCCAM_INT, REAL, REAL*, const char*) occam_unused;
|
||||
static inline OCCAM_BOOL SPLICE_SIZE(occam_IEEE,OP) (REAL X, OCCAM_INT Rm, OCCAM_INT Op, REAL Y, REAL* result1, const char* pos) {
|
||||
REAL R;
|
||||
int prevRm = fegetround();
|
||||
switch (Rm) {
|
||||
|
@ -43,8 +43,8 @@ static inline OCCAM_BOOL SPLICE_SIZE(occam_REAL,GT) (REAL, REAL, const char*) oc
|
|||
static inline OCCAM_BOOL SPLICE_SIZE(occam_REAL,GT) (REAL X, REAL Y, const char* pos) {
|
||||
return isgreater(X,Y);
|
||||
}
|
||||
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) {
|
||||
static inline REAL SPLICE_SIZE(occam_REAL,OP) (REAL, OCCAM_INT, REAL, const char*) occam_unused;
|
||||
static inline REAL SPLICE_SIZE(occam_REAL,OP) (REAL X, OCCAM_INT Op, REAL Y, const char* pos) {
|
||||
switch (Op) {
|
||||
case 0: return X+Y;
|
||||
case 1: return X-Y;
|
||||
|
@ -60,11 +60,11 @@ static inline REAL SPLICE_SIZE(occam_REAL,REM) (REAL X, REAL Y, const char* pos)
|
|||
#if SPLICE_SIZE(4,1) == 4321
|
||||
static inline OCCAM_BOOL occam_ARGUMENT_REDUCE (float, float, float, int32_t*, float*, const char*) occam_unused;
|
||||
static inline OCCAM_BOOL occam_ARGUMENT_REDUCE (float X, float Y, float Y_err, int32_t* result1, float* result2, const char* pos) {
|
||||
const INT maxexpdiff = 20;
|
||||
const OCCAM_INT maxexpdiff = 20;
|
||||
#else
|
||||
static inline OCCAM_BOOL occam_DARGUMENT_REDUCE (double, double, double, int32_t*, double*, const char*) occam_unused;
|
||||
static inline OCCAM_BOOL occam_DARGUMENT_REDUCE (double X, double Y, double Y_err, int32_t* result1, double* result2, const char* pos) {
|
||||
const INT maxexpdiff = 30;
|
||||
const OCCAM_INT maxexpdiff = 30;
|
||||
#endif
|
||||
int EX;
|
||||
int EY;
|
||||
|
@ -101,8 +101,8 @@ static inline REAL ADD_PREFIX(DIVBY2) (REAL X, const char* pos) {
|
|||
occam_stop(pos,2,"Called (D)DIVBY2 on non-finite value: %f", X);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
static inline OCCAM_INT ADD_PREFIX(FLOATING_UNPACK) (REAL, REAL*, const char*) occam_unused;
|
||||
static inline OCCAM_INT ADD_PREFIX(FLOATING_UNPACK) (REAL X, REAL* result1, const char* pos) {
|
||||
if (isnan(X) || X == 0) {
|
||||
//Finding the max exponent is a hack,
|
||||
//but frexp doesn't set the exponent when you pass
|
||||
|
@ -173,8 +173,8 @@ static inline OCCAM_BOOL ADD_PREFIX(ORDERED) (REAL, REAL, const char*) occam_unu
|
|||
static inline OCCAM_BOOL ADD_PREFIX(ORDERED) (REAL X, REAL Y, const char* pos) {
|
||||
return !(isunordered(X,Y));
|
||||
}
|
||||
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) {
|
||||
static inline REAL ADD_PREFIX(SCALEB) (REAL, OCCAM_INT, const char*) occam_unused;
|
||||
static inline REAL ADD_PREFIX(SCALEB) (REAL X, OCCAM_INT n, const char* pos) {
|
||||
if (isfinite(X)) {
|
||||
return F(scalbln)(X,n);
|
||||
} else {
|
||||
|
|
|
@ -64,15 +64,6 @@
|
|||
#endif
|
||||
//}}}
|
||||
|
||||
#ifdef INT
|
||||
#define tock_old_INT INT
|
||||
#endif
|
||||
#ifdef UINT
|
||||
#define tock_old_UINT UINT
|
||||
#endif
|
||||
#ifdef OCCAM_BOOL
|
||||
#define tock_old_OCCAM_BOOL OCCAM_BOOL
|
||||
#endif
|
||||
#ifdef REAL
|
||||
#define tock_old_REAL REAL
|
||||
#endif
|
||||
|
@ -82,11 +73,11 @@
|
|||
|
||||
//We use #define so we can #undef afterwards
|
||||
#if occam_INT_size == 4
|
||||
#define INT int32_t
|
||||
#define UINT uint32_t
|
||||
#define OCCAM_INT int32_t
|
||||
#define OCCAM_UINT uint32_t
|
||||
#elif occam_INT_size == 8
|
||||
#define INT int64_t
|
||||
#define UINT uint64_t
|
||||
#define OCCAM_INT int64_t
|
||||
#define OCCAM_UINT uint64_t
|
||||
#else
|
||||
#error You must define occam_INT_size when using this header
|
||||
#endif
|
||||
|
@ -312,14 +303,21 @@ static inline int occam_check_retype (int src, int dest, const char *pos) {
|
|||
static inline type occam_##name##_##otypes (occam_extra_param type a, type b, const char *pos) { \
|
||||
return a op b; \
|
||||
}
|
||||
#define MAKE_SIMPLE_UNARY(name, op, type, otype) \
|
||||
static inline type occam_##name##_##otype (occam_extra_param type, const char *) occam_unused; \
|
||||
static inline type occam_##name##_##otype (occam_extra_param type a, const char *pos) { \
|
||||
return op a; \
|
||||
}
|
||||
|
||||
#define MAKE_ALL_BITWISE(type, otypes) \
|
||||
MAKE_SIMPLE(and,&,type,otypes) \
|
||||
MAKE_SIMPLE(or,|,type,otypes) \
|
||||
#define MAKE_ALL_BITWISE(type, otype) \
|
||||
MAKE_SIMPLE(and,&,type,otype##_##otype) \
|
||||
MAKE_SIMPLE(or,|,type,otype##_##otype) \
|
||||
MAKE_SIMPLE(xor,^,type,otype##_##otype) \
|
||||
MAKE_SIMPLE_UNARY(not,~,type,otype)
|
||||
|
||||
#define MAKE_TOSTRING(type, occname, flag) \
|
||||
static inline void occam_##occname##TOSTRING(INT*, unsigned char*, const type) occam_unused; \
|
||||
static inline void occam_##occname##TOSTRING(INT* len, unsigned char* string, const type n) { \
|
||||
static inline void occam_##occname##TOSTRING(OCCAM_INT*, unsigned char*, const type) occam_unused; \
|
||||
static inline void occam_##occname##TOSTRING(OCCAM_INT* len, unsigned char* string, const type n) { \
|
||||
/* Must use buffer to avoid writing trailing zero: */ char buf[32]; \
|
||||
int chars_written = snprintf(buf, 32, flag, n); \
|
||||
memcpy(string, buf, chars_written * sizeof(char)); \
|
||||
|
@ -346,8 +344,8 @@ static inline int occam_check_retype (int src, int dest, const char *pos) {
|
|||
#define MAKE_STRINGTO_32 MAKE_STRINGTO
|
||||
#define MAKE_STRINGTO_64 MAKE_STRINGTO
|
||||
|
||||
static inline void occam_BOOLTOSTRING(occam_extra_param INT*, unsigned char*, const OCCAM_BOOL) occam_unused;
|
||||
static inline void occam_BOOLTOSTRING(occam_extra_param INT* len, unsigned char* str, const OCCAM_BOOL b) {
|
||||
static inline void occam_BOOLTOSTRING(occam_extra_param OCCAM_INT*, unsigned char*, const OCCAM_BOOL) occam_unused;
|
||||
static inline void occam_BOOLTOSTRING(occam_extra_param OCCAM_INT* len, unsigned char* str, const OCCAM_BOOL b) {
|
||||
if (b) {
|
||||
memcpy(str,"TRUE",4*sizeof(char));
|
||||
*len = 4;
|
||||
|
@ -391,6 +389,9 @@ static inline void occam_STRINGTOBOOL(occam_extra_param OCCAM_BOOL* error, OCCAM
|
|||
MAKE_STRINGTO_##bits(type, HEX##bits, hflag)
|
||||
|
||||
MAKE_ALL_COMP(OCCAM_BOOL,BOOL_BOOL)
|
||||
MAKE_SIMPLE(and,&&,OCCAM_BOOL,BOOL_BOOL)
|
||||
MAKE_SIMPLE(or,||,OCCAM_BOOL,BOOL_BOOL)
|
||||
MAKE_SIMPLE_UNARY(not,!,OCCAM_BOOL,BOOL)
|
||||
|
||||
//{{{ uint8_t
|
||||
MAKE_RANGE_CHECK(uint8_t, "%d")
|
||||
|
@ -402,6 +403,8 @@ MAKE_SHIFT(uint8_t,uint8_t,BYTE_BYTE)
|
|||
MAKE_PLUS(uint8_t,BYTE_BYTE)
|
||||
MAKE_MINUS(uint8_t,BYTE_BYTE)
|
||||
MAKE_TIMES(uint8_t,BYTE_BYTE)
|
||||
MAKE_ALL_COMP(uint8_t,BYTE_BYTE)
|
||||
MAKE_ALL_BITWISE(uint8_t,BYTE_BYTE)
|
||||
|
||||
// occam's only unsigned type, so we can use % directly.
|
||||
static inline uint8_t occam_rem_BYTE_BYTE (uint8_t, uint8_t, const char *) occam_unused;
|
||||
|
@ -425,37 +428,31 @@ MAKE_ALL_SIGNED(int16_t, 16, "%d", "%x", uint16_t, INT16)
|
|||
//{{{ int
|
||||
//MAKE_ALL_SIGNED(int, "%d", unsigned int)
|
||||
|
||||
MAKE_TOSTRING(INT, INT, "%d")
|
||||
MAKE_TOSTRING(INT, HEX, "%x")
|
||||
MAKE_STRINGTO(INT, INT, "%d")
|
||||
MAKE_STRINGTO(INT, HEX, "%x")
|
||||
MAKE_TOSTRING(OCCAM_INT, INT, "%d")
|
||||
MAKE_TOSTRING(OCCAM_INT, HEX, "%x")
|
||||
MAKE_STRINGTO(OCCAM_INT, INT, "%d")
|
||||
MAKE_STRINGTO(OCCAM_INT, HEX, "%x")
|
||||
|
||||
#if occam_INT_size == 4
|
||||
#define TOCK_TMP_INT int32_t
|
||||
#define TOCK_TMP_INT_FLAG "%d"
|
||||
#define TOCK_TMP_UINT uint32_t
|
||||
#elif occam_INT_size == 8
|
||||
#define TOCK_TMP_INT int64_t
|
||||
#define TOCK_TMP_INT_FLAG "%lld"
|
||||
#define TOCK_TMP_UINT uint64_t
|
||||
#endif
|
||||
|
||||
MAKE_ADD(TOCK_TMP_INT,INT_INT,TOCK_TMP_INT_FLAG)
|
||||
MAKE_SUBTR(TOCK_TMP_INT,INT_INT,TOCK_TMP_INT_FLAG)
|
||||
MAKE_MUL(TOCK_TMP_INT,INT_INT,TOCK_TMP_INT_FLAG)
|
||||
MAKE_DIV(TOCK_TMP_INT,INT_INT)
|
||||
MAKE_REM(TOCK_TMP_INT,INT_INT)
|
||||
MAKE_NEGATE(TOCK_TMP_INT,INT)
|
||||
MAKE_SHIFT(TOCK_TMP_UINT, TOCK_TMP_INT,INT_INT)
|
||||
MAKE_PLUS(TOCK_TMP_INT,INT_INT)
|
||||
MAKE_MINUS(TOCK_TMP_INT,INT_INT)
|
||||
MAKE_TIMES(TOCK_TMP_INT,INT_INT)
|
||||
MAKE_ALL_COMP(TOCK_TMP_INT,INT_INT)
|
||||
MAKE_ALL_BITWISE(TOCK_TMP_INT,INT_INT)
|
||||
MAKE_ADD(OCCAM_INT,INT_INT,TOCK_TMP_INT_FLAG)
|
||||
MAKE_SUBTR(OCCAM_INT,INT_INT,TOCK_TMP_INT_FLAG)
|
||||
MAKE_MUL(OCCAM_INT,INT_INT,TOCK_TMP_INT_FLAG)
|
||||
MAKE_DIV(OCCAM_INT,INT_INT)
|
||||
MAKE_REM(OCCAM_INT,INT_INT)
|
||||
MAKE_NEGATE(OCCAM_INT,INT)
|
||||
MAKE_SHIFT(OCCAM_UINT, OCCAM_INT,INT_INT)
|
||||
MAKE_PLUS(OCCAM_INT,INT_INT)
|
||||
MAKE_MINUS(OCCAM_INT,INT_INT)
|
||||
MAKE_TIMES(OCCAM_INT,INT_INT)
|
||||
MAKE_ALL_COMP(OCCAM_INT,INT_INT)
|
||||
MAKE_ALL_BITWISE(OCCAM_INT,INT)
|
||||
|
||||
#undef TOCK_TMP_INT
|
||||
#undef TOCK_TMP_INT_FLAG
|
||||
#undef TOCK_TMP_UINT
|
||||
|
||||
//}}}
|
||||
//{{{ int32_t
|
||||
|
@ -578,23 +575,12 @@ static int64_t occam_convert_double_int64_t_trunc (double v, const char *pos) {
|
|||
#define F(func) func
|
||||
#include "tock_intrinsics_float.h"
|
||||
|
||||
#undef INT
|
||||
#undef UINT
|
||||
#undef REAL
|
||||
#undef RINT
|
||||
#undef ADD_PREFIX
|
||||
#undef SPLICE_SIZE
|
||||
#undef F
|
||||
|
||||
#ifdef tock_old_INT
|
||||
#define INT tock_old_INT
|
||||
#endif
|
||||
#ifdef tock_old_UINT
|
||||
#define UINT tock_old_UINT
|
||||
#endif
|
||||
#ifdef tock_old_OCCAM_BOOL
|
||||
#define OCCAM_BOOL tock_old_OCCAM_BOOL
|
||||
#endif
|
||||
#ifdef tock_old_REAL
|
||||
#define REAL tock_old_REAL
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue
Block a user