Mail Archives: djgpp-workers/2003/11/01/07:25:22
Hello.
I've thought of a small optimisation of isfinite().
The current code is (from include/math.h):
#define FP_INFINITE 0
#define FP_NAN 1
#define FP_NORMAL 2
#define FP_SUBNORMAL 3
#define FP_ZERO 4
/* Extended with Unnormals (for long doubles). */
#define FP_UNNORMAL 1024
#define fpclassify(x) ((sizeof(x)==sizeof(float))? __fpclassifyf(x) : \
(sizeof(x)==sizeof(double))? __fpclassifyd(x) : \
__fpclassifyld(x))
#define isfinite(x) (fpclassify(x)==FP_NORMAL || \
fpclassify(x)==FP_SUBNORMAL || \
fpclassify(x)==FP_ZERO)
With this gcc (2.953 and 3.3.1) generates code like this:
call __fpclassifyf
<adjust esp>
cmpl $2, %eax
je L4
cmpl $3, %eax
je L4
cmpl $4, %eax
je L4
I. e. three cmp and three je instructions.
I propose:
#define FP_INFINITE 0x00000001
#define FP_NAN 0x00000002
#define FP_NORMAL 0x00000004
#define FP_SUBNORMAL 0x00000008
#define FP_ZERO 0x00000010
/* Extended with Unnormals (for long doubles). */
#define FP_UNNORMAL 0x00010000
#define fpclassify(x) ((sizeof(x)==sizeof(float))? __fpclassifyf(x) : \
(sizeof(x)==sizeof(double))? __fpclassifyd(x) : \
__fpclassifyld(x))
#define isfinite(x) ((fpclassify(x) & (FP_NORMAL|FP_SUBNORMAL|FP_ZERO)) != 0)
This will make gcc generate this:
call __fpclassifyf
<adjust esp>
testb $28, %al
je L3
I. e. one test and one je.
The second version is much better. Plus the coder that needs some
other combination of the type of numbers can use the same idea.
If nobody complains I'll commit this in a week.
Right,
MartinS
- Raw text -