diff options
author | Vincent Sanders <vince@netsurf-browser.org> | 2011-03-12 17:46:11 +0000 |
---|---|---|
committer | Vincent Sanders <vince@netsurf-browser.org> | 2011-03-12 17:46:11 +0000 |
commit | 5ca8e29dcfc73b13a3c4c32e58619d9c486df57b (patch) | |
tree | 0327c5f5737addbf6c31d54363ec6587e87aa05f /include | |
parent | bcb95bf5fa2c5cfd2e7c80f211f7fd6db6ce2f9a (diff) | |
download | libcss-5ca8e29dcfc73b13a3c4c32e58619d9c486df57b.tar.gz libcss-5ca8e29dcfc73b13a3c4c32e58619d9c486df57b.tar.bz2 |
Saturated maths in css fixed point
svn path=/trunk/libcss/; revision=11975
Diffstat (limited to 'include')
-rw-r--r-- | include/libcss/fpmath.h | 122 |
1 files changed, 105 insertions, 17 deletions
diff --git a/include/libcss/fpmath.h b/include/libcss/fpmath.h index 3867f3a..36e0ab5 100644 --- a/include/libcss/fpmath.h +++ b/include/libcss/fpmath.h @@ -14,37 +14,120 @@ extern "C" #endif #include <stdint.h> +#include <limits.h> /* 22:10 fixed point math */ +#define CSS_RADIX_POINT 10 + +/* type for fixed point numbers */ typedef int32_t css_fixed; +static inline css_fixed +css_add_fixed(const css_fixed x, const css_fixed y) { + int32_t ux = x; + int32_t uy = y; + int32_t res = ux + uy; + + /* Calculate overflowed result. (Don't change the sign bit of ux) */ + ux = (ux >> 31) + INT_MAX; + + /* Force compiler to use cmovns instruction */ + if ((int32_t) ((ux ^ uy) | ~(uy ^ res)) >= 0) { + res = ux; + } + + return res; +} + +static inline css_fixed +css_subtract_fixed(const css_fixed x, const css_fixed y) { + int32_t ux = x; + int32_t uy = y; + int32_t res = ux - uy; + + ux = (ux >> 31) + INT_MAX; + + /* Force compiler to use cmovns instruction */ + if ((int32_t)((ux ^ uy) & (ux ^ res)) < 0) { + res = ux; + } + + return res; +} + +static inline css_fixed +css_divide_fixed(const css_fixed x, const css_fixed y) { + int64_t xx = ((int64_t)x << CSS_RADIX_POINT) / y; + + if (xx < INT_MIN) + xx = INT_MIN; + + if (xx > INT_MAX) + xx = INT_MAX; + + return xx; +} + +static inline css_fixed +css_multiply_fixed(const css_fixed x, const css_fixed y) { + int64_t xx = ((int64_t)x * (int64_t)y) >> CSS_RADIX_POINT; + + if (xx < INT_MIN) + xx = INT_MIN; + + if (xx > INT_MAX) + xx = INT_MAX; + + return xx; +} + +static inline css_fixed +css_int_to_fixed(const int a) { + int64_t xx = ((int64_t) a) << CSS_RADIX_POINT; + + if (xx < INT_MIN) + xx = INT_MIN; + + if (xx > INT_MAX) + xx = INT_MAX; + + return xx; +} + +static inline css_fixed +css_float_to_fixed(const float a) { + float xx = a * (float) (1 << CSS_RADIX_POINT); + + if (xx < INT_MIN) + xx = INT_MIN; + + if (xx > INT_MAX) + xx = INT_MAX; + + return xx; +} + /* Add two fixed point values */ -#define FADD(a, b) ((a) + (b)) +#define FADD(a, b) (css_add_fixed((a), (b))) /* Subtract two fixed point values */ -#define FSUB(a, b) ((a) - (b)) +#define FSUB(a, b) (css_subtract_fixed((a), (b))) /* Multiply two fixed point values */ -#define FMUL(a, b) ((((int64_t) (a)) * ((int64_t) (b))) >> 10) +#define FMUL(a, b) (css_multiply_fixed((a), (b))) /* Divide two fixed point values */ -#define FDIV(a, b) ((((int64_t) (a)) << 10) / (b)) - -/* Add an integer to a fixed point value */ -#define FADDI(a, b) ((a) + ((b) << 10)) -/* Subtract an integer from a fixed point value */ -#define FSUBI(a, b) ((a) - ((b) << 10)) -/* Multiply a fixed point value by an integer */ -#define FMULI(a, b) ((a) * (b)) -/* Divide a fixed point value by an integer */ -#define FDIVI(a, b) ((a) / (b)) +#define FDIV(a, b) (css_divide_fixed((a), (b))) /* Convert a floating point value to fixed point */ -#define FLTTOFIX(a) ((css_fixed) ((a) * (float) (1 << 10))) +#define FLTTOFIX(a) ((css_fixed) ((a) * (float) (1 << CSS_RADIX_POINT))) /* Convert a fixed point value to floating point */ -#define FIXTOFLT(a) ((float) (a) / (float) (1 << 10)) +#define FIXTOFLT(a) ((float) (a) / (float) (1 << CSS_RADIX_POINT)) /* Convert an integer to a fixed point value */ -#define INTTOFIX(a) ((a) << 10) +#define INTTOFIX(a) (css_int_to_fixed(a)) /* Convert a fixed point value to an integer */ -#define FIXTOINT(a) ((a) >> 10) +#define FIXTOINT(a) ((a) >> CSS_RADIX_POINT) + +/* truncate a fixed point value */ +#define TRUNCATEFIX(a) (a & ~((1 << CSS_RADIX_POINT)- 1 )) /* Useful values */ #define F_PI_2 0x00000648 /* 1.5708 (PI/2) */ @@ -57,8 +140,13 @@ typedef int32_t css_fixed; #define F_270 0x00043800 /* 270 */ #define F_360 0x0005a000 /* 360 */ +#define F_0_5 0x00000200 /* 0.5 */ +#define F_1 0x00000400 /* 1 */ +#define F_10 0x00002800 /* 10 */ +#define F_72 0x00012000 /* 72 */ #define F_100 0x00019000 /* 100 */ #define F_200 0x00032000 /* 200 */ +#define F_255 0x0003FC00 /* 255 */ #define F_300 0x0004b000 /* 300 */ #define F_400 0x00064000 /* 400 */ |