Index: configure.ac =================================================================== RCS file: /home/freeciv/CVS/freeciv/configure.ac,v retrieving revision 1.94 diff -u -u -r1.94 configure.ac --- configure.ac 2 Feb 2005 06:55:06 -0000 1.94 +++ configure.ac 8 Mar 2005 00:03:45 -0000 @@ -454,10 +458,13 @@ dnl Readline library and header files. FC_HAS_READLINE() - AC_CHECK_FUNC(pow) - if test $ac_cv_func_pow = no; then - AC_CHECK_LIB(m, pow, SERVER_LIBS="$SERVER_LIBS -lm", + FC_SOFT_FLOAT + if test "$enable_soft_float" = no; then + AC_CHECK_FUNC(pow) + if test $ac_cv_func_pow = no; then + AC_CHECK_LIB(m, pow, SERVER_LIBS="$SERVER_LIBS -lm", AC_MSG_ERROR(Did not find math lib!)) + fi fi fi AC_SUBST(SERVER_LIBS) --- m4/soft_float.m4 1969-12-31 19:00:00.000000000 -0500 +++ m4/soft_float.m4 2005-03-07 12:47:56.000000000 -0500 @@ -0,0 +1,23 @@ +dnl +dnl FC_SOFT_FLOAT +dnl +AC_DEFUN([FC_SOFT_FLOAT], +[ + AC_ARG_ENABLE(soft-float, + [ --enable-soft-float Disable linking against math library], + [ + case "${enableval}" in + yes|no) + enable_soft_float=${enableval} + ;; + *) + AC_MSG_ERROR(bad value ${enableval} for --enable-soft-float) + ;; + esac + ], [enable_soft_float=no]) + + if test "$enable_soft_float" = "yes"; then + AC_DEFINE(SOFT_FLOAT, 1, + [Enable soft float and disable linking against -lm]) + fi +]) Index: common/Makefile.am =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/Makefile.am,v retrieving revision 1.54 diff -u -r1.54 Makefile.am --- common/Makefile.am 15 Dec 2004 19:28:44 -0000 1.54 +++ common/Makefile.am 8 Mar 2005 21:59:30 -0000 @@ -47,6 +47,7 @@ player.h \ requirements.c \ requirements.h \ + soft_float.c \ spaceship.c \ spaceship.h \ tech.c \ --- common/soft_float.c.orig 1969-12-31 19:00:00.000000000 -0500 +++ common/soft_float.c 2005-03-08 18:30:11.000000000 -0500 @@ -0,0 +1,120 @@ +/* + * This file provides a replacement for every libm.so function called by + * Freeciv. The goal is to allow for cross-compiling Freeciv for a target + * host that uses soft-float emulation, but doing so on a build host with + * libraries compiled without soft-float. (Or more to the point, you want + * to compile civserver for a PDA running OpenEmbedded, and you don't feel + * like recompiling 50MiB worth of libraries in the process.) + * + * These may also offer a performance boost on a PDA lacking a FPU; + * sqrt(), at least, is implemented in integer math. + * + * These replacement functions only kick in if the --enable-soft-float + * option was provided to configure. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef SOFT_FLOAT + +/* + * Since these functions are meant as drop-in replacement for libm, they + * should comply with the prototypes in . + */ +#include + +/************************************************************************* + This pow() algorithm is a cheap as they come; it only works when y is a + positive integer, and doesn't scale well to large values. Fortunately, + the only call to it (via common/combat.c) falls within these + restrictions. + *************************************************************************/ +double pow(double x, double y) +{ + double result = 1; + int i; + + for (i = (int)y; i > 0; i--) + { + result *= x; + } + + return result; +} + + +/************************************************************************* + This clever sqrt() algorithm was copied from + ; I don't + pretend to understand it, but it does work. Of course, the result is an + integer, but this shouldn't pose too much of a problem. + *************************************************************************/ +double sqrt(double x0) +{ + unsigned int x = (int)x0; + unsigned int result = 0, temp; + + #define INNER_SQRT(s) \ + temp = (result << (s)) + (1 << ((s) * 2 - 2)); \ + if (x >= temp) \ + { \ + result += 1 << ((s)-1); \ + x -= temp; \ + } + + INNER_SQRT (16) + INNER_SQRT (15) + INNER_SQRT (14) + INNER_SQRT (13) + INNER_SQRT (12) + INNER_SQRT (11) + INNER_SQRT (10) + INNER_SQRT ( 9) + INNER_SQRT ( 8) + INNER_SQRT ( 7) + INNER_SQRT ( 6) + INNER_SQRT ( 5) + INNER_SQRT ( 4) + INNER_SQRT ( 3) + INNER_SQRT ( 2) + INNER_SQRT ( 1) + + #undef INNER_SQRT + + return result; +} + + +/************************************************************************* + This algorithm for log() was posted to Usenet by Jonathan Dale Kirwan + , and has a good enough accuracy for our needs. See + for an + explanation. + *************************************************************************/ +double log(double x) { + double r; + int s = 0; + + if (x < 1) + { + return - log(1 / x); + } + + while (x >= 2) { + x /= 2; + s++; + } + + r = (x-1) * ( 0.999115 + + (x-1) * ( -0.4899597 + + (x-1) * ( 0.2856751 + + (x-1) * ( -0.1330566 + + (x-1) * 0.03137207 ) ) ) ); + + return (r + (s * 0.693147180559945)); +} + + +#endif /* SOFT_FLOAT */