diff options
-rw-r--r-- | gnu/classpath/math/MPN.java | 757 | ||||
-rw-r--r-- | java/lang/Math.java | 2 | ||||
-rw-r--r-- | java/math/BigInteger.java | 2370 | ||||
-rw-r--r-- | native/Makefile.am | 4 | ||||
-rw-r--r-- | native/cni/.cvsignore (renamed from native/jni/awt/.cvsignore) | 0 | ||||
-rw-r--r-- | native/cni/Makefile.am | 0 | ||||
-rw-r--r-- | native/fdlibm/.cvsignore (renamed from native/lib/.cvsignore) | 0 | ||||
-rw-r--r-- | native/fdlibm/dtoa.c (renamed from native/jni/dtoa.c) | 0 | ||||
-rw-r--r-- | native/fdlibm/e_acos.c (renamed from native/jni/acos.c) | 107 | ||||
-rw-r--r-- | native/fdlibm/e_asin.c (renamed from native/jni/asin.c) | 101 | ||||
-rw-r--r-- | native/fdlibm/e_atan2.c | 131 | ||||
-rw-r--r-- | native/fdlibm/e_exp.c (renamed from native/jni/exp.c) | 139 | ||||
-rw-r--r-- | native/fdlibm/e_fmod.c | 140 | ||||
-rw-r--r-- | native/fdlibm/e_log.c (renamed from native/jni/log.c) | 151 | ||||
-rw-r--r-- | native/fdlibm/e_pow.c | 312 | ||||
-rw-r--r-- | native/fdlibm/e_rem_pio2.c | 185 | ||||
-rw-r--r-- | native/fdlibm/e_remainder.c | 80 | ||||
-rw-r--r-- | native/fdlibm/e_scalb.c | 55 | ||||
-rw-r--r-- | native/fdlibm/e_sqrt.c (renamed from native/jni/sqrt.c) | 278 | ||||
-rw-r--r-- | native/fdlibm/fdlibm.h | 349 | ||||
-rw-r--r-- | native/fdlibm/ieeefp.h (renamed from native/jni/ieeefp.h) | 4 | ||||
-rw-r--r-- | native/fdlibm/java-assert.h (renamed from native/jni/java-assert.h) | 0 | ||||
-rw-r--r-- | native/fdlibm/k_cos.c (renamed from native/jni/k_cos.c) | 82 | ||||
-rw-r--r-- | native/fdlibm/k_rem_pio2.c | 320 | ||||
-rw-r--r-- | native/fdlibm/k_sin.c (renamed from native/jni/k_sin.c) | 57 | ||||
-rw-r--r-- | native/fdlibm/k_tan.c (renamed from native/jni/k_tan.c) | 121 | ||||
-rw-r--r-- | native/fdlibm/mprec.c (renamed from native/jni/mprec.c) | 0 | ||||
-rw-r--r-- | native/fdlibm/mprec.h (renamed from native/jni/mprec.h) | 5 | ||||
-rw-r--r-- | native/fdlibm/s_atan.c | 181 | ||||
-rw-r--r-- | native/fdlibm/s_ceil.c | 80 | ||||
-rw-r--r-- | native/fdlibm/s_copysign.c | 82 | ||||
-rw-r--r-- | native/fdlibm/s_cos.c (renamed from native/jni/cos.c) | 68 | ||||
-rw-r--r-- | native/fdlibm/s_fabs.c | 73 | ||||
-rw-r--r-- | native/fdlibm/s_floor.c | 134 | ||||
-rw-r--r-- | native/fdlibm/s_rint.c | 87 | ||||
-rw-r--r-- | native/fdlibm/s_scalbn.c | 104 | ||||
-rw-r--r-- | native/fdlibm/s_sin.c | 132 | ||||
-rw-r--r-- | native/fdlibm/s_tan.c | 114 | ||||
-rw-r--r-- | native/fdlibm/sf_fabs.c | 47 | ||||
-rw-r--r-- | native/fdlibm/sf_rint.c | 80 | ||||
-rw-r--r-- | native/fdlibm/strtod.c | 719 | ||||
-rw-r--r-- | native/fdlibm/w_acos.c | 118 | ||||
-rw-r--r-- | native/fdlibm/w_asin.c | 121 | ||||
-rw-r--r-- | native/fdlibm/w_atan2.c | 117 | ||||
-rw-r--r-- | native/fdlibm/w_exp.c | 136 | ||||
-rw-r--r-- | native/fdlibm/w_fmod.c | 107 | ||||
-rw-r--r-- | native/fdlibm/w_log.c | 115 | ||||
-rw-r--r-- | native/fdlibm/w_pow.c | 231 | ||||
-rw-r--r-- | native/fdlibm/w_remainder.c | 119 | ||||
-rw-r--r-- | native/fdlibm/w_sqrt.c | 93 | ||||
-rw-r--r-- | native/jni/Makefile.am | 65 | ||||
-rw-r--r-- | native/jni/atan.c | 114 | ||||
-rw-r--r-- | native/jni/atan2.c | 115 | ||||
-rw-r--r-- | native/jni/awt/native_state.c | 238 | ||||
-rw-r--r-- | native/jni/awt/native_state.h | 61 | ||||
-rw-r--r-- | native/jni/ceil.c | 71 | ||||
-rw-r--r-- | native/jni/e_fmod.c | 132 | ||||
-rw-r--r-- | native/jni/fdlibm.h | 83 | ||||
-rw-r--r-- | native/jni/floor.c | 72 | ||||
-rw-r--r-- | native/jni/gtk-peer/.cvsignore (renamed from native/nsa/.cvsignore) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/Makefile.am (renamed from native/jni/awt/Makefile.am) | 19 | ||||
-rw-r--r-- | native/jni/gtk-peer/Makefile.in | 492 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_image_GdkPixbufDecoder.c (renamed from native/jni/awt/gnu_java_awt_image_GdkPixbufDecoder.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GdkFontMetrics.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GdkGraphics.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkButtonPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkCanvasPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkChoicePeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkClipboard.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkComponentPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkEvents.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkImagePainter.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkLabelPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkListPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkMainThread.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkMenuPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkPanelPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkToolkit.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c (renamed from native/jni/awt/gnu_java_awt_peer_gtk_GtkWindowPeer.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gthread-jni.c (renamed from native/jni/awt/gthread-jni.c) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gthread-jni.h (renamed from native/jni/awt/gthread-jni.h) | 0 | ||||
-rw-r--r-- | native/jni/gtk-peer/gtkpeer.h (renamed from native/jni/awt/gtkpeer.h) | 0 | ||||
-rw-r--r-- | native/jni/java-io/.cvsignore | 8 | ||||
-rw-r--r-- | native/jni/java-io/java_io_File.c (renamed from native/jni/java_io_File.c) | 9 | ||||
-rw-r--r-- | native/jni/java-io/java_io_FileDescriptor.c (renamed from native/jni/java_io_FileDescriptor.c) | 3 | ||||
-rw-r--r-- | native/jni/java-io/java_io_FileInputStream.c (renamed from native/jni/java_io_FileInputStream.c) | 2 | ||||
-rw-r--r-- | native/jni/java-io/java_io_FileOutputStream.c (renamed from native/jni/java_io_FileOutputStream.c) | 4 | ||||
-rw-r--r-- | native/jni/java-io/java_io_ObjectInputStream.c (renamed from native/jni/java_io_ObjectInputStream.c) | 44 | ||||
-rw-r--r-- | native/jni/java-io/java_io_ObjectOutputStream.c (renamed from native/jni/java_io_ObjectOutputStream.c) | 49 | ||||
-rw-r--r-- | native/jni/java-io/java_io_RandomAccessFile.c (renamed from native/jni/java_io_RandomAccessFile.c) | 8 | ||||
-rw-r--r-- | native/jni/java-io/javaio.c (renamed from native/jni/javaio.c) | 94 | ||||
-rw-r--r-- | native/jni/java-io/javaio.h (renamed from native/jni/javalang.h) | 35 | ||||
-rw-r--r-- | native/jni/java-lang/.cvsignore | 8 | ||||
-rw-r--r-- | native/jni/java-lang/java_lang_Double.c (renamed from native/jni/java_lang_Double.c) | 1 | ||||
-rw-r--r-- | native/jni/java-lang/java_lang_Float.c (renamed from native/jni/java_lang_Float.c) | 0 | ||||
-rw-r--r-- | native/jni/java-lang/java_lang_Object.c (renamed from native/jni/java_lang_Object.c) | 0 | ||||
-rw-r--r-- | native/jni/java-lang/java_lang_System.c (renamed from native/jni/java_lang_System.c) | 0 | ||||
-rw-r--r-- | native/jni/java-lang/java_lang_reflect_Array.c (renamed from native/jni/java_lang_reflect_Array.c) | 0 | ||||
-rw-r--r-- | native/jni/java-net/.cvsignore | 8 | ||||
-rw-r--r-- | native/jni/java-net/java_net_InetAddress.c (renamed from native/jni/java_net_InetAddress.c) | 55 | ||||
-rw-r--r-- | native/jni/java-net/java_net_PlainDatagramSocketImpl.c (renamed from native/jni/java_net_PlainDatagramSocketImpl.c) | 21 | ||||
-rw-r--r-- | native/jni/java-net/java_net_PlainSocketImpl.c (renamed from native/jni/java_net_PlainSocketImpl.c) | 0 | ||||
-rw-r--r-- | native/jni/java-net/javanet.c (renamed from native/jni/javanet.c) | 156 | ||||
-rw-r--r-- | native/jni/java-net/javanet.h (renamed from native/jni/javanet.h) | 1 | ||||
-rw-r--r-- | native/jni/java-util/.cvsignore | 8 | ||||
-rw-r--r-- | native/jni/java-util/java_util_TimeZone.c (renamed from native/jni/java_util_TimeZone.c) | 0 | ||||
-rw-r--r-- | native/jni/java_math_BigInteger.c | 993 | ||||
-rw-r--r-- | native/jni/javaio.h | 65 | ||||
-rw-r--r-- | native/jni/javalang.c | 93 | ||||
-rw-r--r-- | native/jni/jcl.c | 111 | ||||
-rw-r--r-- | native/jni/jcl.h | 51 | ||||
-rw-r--r-- | native/jni/k_rem_pio2.c | 301 | ||||
-rw-r--r-- | native/jni/pow.c | 296 | ||||
-rw-r--r-- | native/jni/remainder.c | 68 | ||||
-rw-r--r-- | native/jni/rint.c | 76 | ||||
-rw-r--r-- | native/jni/s_fabs.c | 25 | ||||
-rw-r--r-- | native/jni/sin.c | 76 | ||||
-rw-r--r-- | native/jni/tan.c | 69 | ||||
-rwxr-xr-x | native/lib/Makefile.am | 12 | ||||
-rwxr-xr-x | native/lib/jcl.c | 111 | ||||
-rwxr-xr-x | native/lib/jcl.h | 52 | ||||
-rwxr-xr-x | native/lib/jnilink.c | 106 | ||||
-rwxr-xr-x | native/lib/jnilink.h | 75 | ||||
-rwxr-xr-x | native/lib/primlib.c | 452 | ||||
-rw-r--r-- | native/lib/primlib.h | 91 | ||||
-rw-r--r-- | native/nsa/native_state.c | 238 | ||||
-rw-r--r-- | native/nsa/native_state.h | 60 | ||||
-rw-r--r-- | vm/reference/java/lang/Thread.java | 2 |
139 files changed, 8828 insertions, 5379 deletions
diff --git a/gnu/classpath/math/MPN.java b/gnu/classpath/math/MPN.java new file mode 100644 index 000000000..9060c884a --- /dev/null +++ b/gnu/classpath/math/MPN.java @@ -0,0 +1,757 @@ +/* gnu.classpath.math.MPN + Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ + +// Included from Kawa 1.6.62 with permission of the author, +// Per Bothner <per@bothner.com>. + +package gnu.classpath.math; + +/** This contains various low-level routines for unsigned bigints. + * The interfaces match the mpn interfaces in gmp, + * so it should be easy to replace them with fast native functions + * that are trivial wrappers around the mpn_ functions in gmp + * (at least on platforms that use 32-bit "limbs"). + */ + +public class MPN +{ + /** Add x[0:size-1] and y, and write the size least + * significant words of the result to dest. + * Return carry, either 0 or 1. + * All values are unsigned. + * This is basically the same as gmp's mpn_add_1. */ + public static int add_1 (int[] dest, int[] x, int size, int y) + { + long carry = (long) y & 0xffffffffL; + for (int i = 0; i < size; i++) + { + carry += ((long) x[i] & 0xffffffffL); + dest[i] = (int) carry; + carry >>= 32; + } + return (int) carry; + } + + /** Add x[0:len-1] and y[0:len-1] and write the len least + * significant words of the result to dest[0:len-1]. + * All words are treated as unsigned. + * @return the carry, either 0 or 1 + * This function is basically the same as gmp's mpn_add_n. + */ + public static int add_n (int dest[], int[] x, int[] y, int len) + { + long carry = 0; + for (int i = 0; i < len; i++) + { + carry += ((long) x[i] & 0xffffffffL) + + ((long) y[i] & 0xffffffffL); + dest[i] = (int) carry; + carry >>>= 32; + } + return (int) carry; + } + + /** Subtract Y[0:size-1] from X[0:size-1], and write + * the size least significant words of the result to dest[0:size-1]. + * Return borrow, either 0 or 1. + * This is basically the same as gmp's mpn_sub_n function. + */ + + public static int sub_n (int[] dest, int[] X, int[] Y, int size) + { + int cy = 0; + for (int i = 0; i < size; i++) + { + int y = Y[i]; + int x = X[i]; + y += cy; /* add previous carry to subtrahend */ + // Invert the high-order bit, because: (unsigned) X > (unsigned) Y + // iff: (int) (X^0x80000000) > (int) (Y^0x80000000). + cy = (y^0x80000000) < (cy^0x80000000) ? 1 : 0; + y = x - y; + cy += (y^0x80000000) > (x ^ 0x80000000) ? 1 : 0; + dest[i] = y; + } + return cy; + } + + /** Multiply x[0:len-1] by y, and write the len least + * significant words of the product to dest[0:len-1]. + * Return the most significant word of the product. + * All values are treated as if they were unsigned + * (i.e. masked with 0xffffffffL). + * OK if dest==x (not sure if this is guaranteed for mpn_mul_1). + * This function is basically the same as gmp's mpn_mul_1. + */ + + public static int mul_1 (int[] dest, int[] x, int len, int y) + { + long yword = (long) y & 0xffffffffL; + long carry = 0; + for (int j = 0; j < len; j++) + { + carry += ((long) x[j] & 0xffffffffL) * yword; + dest[j] = (int) carry; + carry >>>= 32; + } + return (int) carry; + } + + /** + * Multiply x[0:xlen-1] and y[0:ylen-1], and + * write the result to dest[0:xlen+ylen-1]. + * The destination has to have space for xlen+ylen words, + * even if the result might be one limb smaller. + * This function requires that xlen >= ylen. + * The destination must be distinct from either input operands. + * All operands are unsigned. + * This function is basically the same gmp's mpn_mul. */ + + public static void mul (int[] dest, + int[] x, int xlen, + int[] y, int ylen) + { + dest[xlen] = MPN.mul_1 (dest, x, xlen, y[0]); + + for (int i = 1; i < ylen; i++) + { + long yword = (long) y[i] & 0xffffffffL; + long carry = 0; + for (int j = 0; j < xlen; j++) + { + carry += ((long) x[j] & 0xffffffffL) * yword + + ((long) dest[i+j] & 0xffffffffL); + dest[i+j] = (int) carry; + carry >>>= 32; + } + dest[i+xlen] = (int) carry; + } + } + + /* Divide (unsigned long) N by (unsigned int) D. + * Returns (remainder << 32)+(unsigned int)(quotient). + * Assumes (unsigned int)(N>>32) < (unsigned int)D. + * Code transcribed from gmp-2.0's mpn_udiv_w_sdiv function. + */ + public static long udiv_qrnnd (long N, int D) + { + long q, r; + long a1 = N >>> 32; + long a0 = N & 0xffffffffL; + if (D >= 0) + { + if (a1 < ((D - a1 - (a0 >>> 31)) & 0xffffffffL)) + { + /* dividend, divisor, and quotient are nonnegative */ + q = N / D; + r = N % D; + } + else + { + /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */ + long c = N - ((long) D << 31); + /* Divide (c1*2^32 + c0) by d */ + q = c / D; + r = c % D; + /* Add 2^31 to quotient */ + q += 1 << 31; + } + } + else + { + long b1 = D >>> 1; /* d/2, between 2^30 and 2^31 - 1 */ + //long c1 = (a1 >> 1); /* A/2 */ + //int c0 = (a1 << 31) + (a0 >> 1); + long c = N >>> 1; + if (a1 < b1 || (a1 >> 1) < b1) + { + if (a1 < b1) + { + q = c / b1; + r = c % b1; + } + else /* c1 < b1, so 2^31 <= (A/2)/b1 < 2^32 */ + { + c = ~(c - (b1 << 32)); + q = c / b1; /* (A/2) / (d/2) */ + r = c % b1; + q = (~q) & 0xffffffffL; /* (A/2)/b1 */ + r = (b1 - 1) - r; /* r < b1 => new r >= 0 */ + } + r = 2 * r + (a0 & 1); + if ((D & 1) != 0) + { + if (r >= q) { + r = r - q; + } else if (q - r <= ((long) D & 0xffffffffL)) { + r = r - q + D; + q -= 1; + } else { + r = r - q + D + D; + q -= 2; + } + } + } + else /* Implies c1 = b1 */ + { /* Hence a1 = d - 1 = 2*b1 - 1 */ + if (a0 >= ((long)(-D) & 0xffffffffL)) + { + q = -1; + r = a0 + D; + } + else + { + q = -2; + r = a0 + D + D; + } + } + } + + return (r << 32) | (q & 0xFFFFFFFFl); + } + + /** Divide divident[0:len-1] by (unsigned int)divisor. + * Write result into quotient[0:len-1. + * Return the one-word (unsigned) remainder. + * OK for quotient==dividend. + */ + + public static int divmod_1 (int[] quotient, int[] dividend, + int len, int divisor) + { + int i = len - 1; + long r = dividend[i]; + if ((r & 0xffffffffL) >= ((long)divisor & 0xffffffffL)) + r = 0; + else + { + quotient[i--] = 0; + r <<= 32; + } + + for (; i >= 0; i--) + { + int n0 = dividend[i]; + r = (r & ~0xffffffffL) | (n0 & 0xffffffffL); + r = udiv_qrnnd (r, divisor); + quotient[i] = (int) r; + } + return (int)(r >> 32); + } + + /* Subtract x[0:len-1]*y from dest[offset:offset+len-1]. + * All values are treated as if unsigned. + * @return the most significant word of + * the product, minus borrow-out from the subtraction. + */ + public static int submul_1 (int[] dest, int offset, int[] x, int len, int y) + { + long yl = (long) y & 0xffffffffL; + int carry = 0; + int j = 0; + do + { + long prod = ((long) x[j] & 0xffffffffL) * yl; + int prod_low = (int) prod; + int prod_high = (int) (prod >> 32); + prod_low += carry; + // Invert the high-order bit, because: (unsigned) X > (unsigned) Y + // iff: (int) (X^0x80000000) > (int) (Y^0x80000000). + carry = ((prod_low ^ 0x80000000) < (carry ^ 0x80000000) ? 1 : 0) + + prod_high; + int x_j = dest[offset+j]; + prod_low = x_j - prod_low; + if ((prod_low ^ 0x80000000) > (x_j ^ 0x80000000)) + carry++; + dest[offset+j] = prod_low; + } + while (++j < len); + return carry; + } + + /** Divide zds[0:nx] by y[0:ny-1]. + * The remainder ends up in zds[0:ny-1]. + * The quotient ends up in zds[ny:nx]. + * Assumes: nx>ny. + * (int)y[ny-1] < 0 (i.e. most significant bit set) + */ + + public static void divide (int[] zds, int nx, int[] y, int ny) + { + // This is basically Knuth's formulation of the classical algorithm, + // but translated from in scm_divbigbig in Jaffar's SCM implementation. + + // Correspondance with Knuth's notation: + // Knuth's u[0:m+n] == zds[nx:0]. + // Knuth's v[1:n] == y[ny-1:0] + // Knuth's n == ny. + // Knuth's m == nx-ny. + // Our nx == Knuth's m+n. + + // Could be re-implemented using gmp's mpn_divrem: + // zds[nx] = mpn_divrem (&zds[ny], 0, zds, nx, y, ny). + + int j = nx; + do + { // loop over digits of quotient + // Knuth's j == our nx-j. + // Knuth's u[j:j+n] == our zds[j:j-ny]. + int qhat; // treated as unsigned + if (zds[j]==y[ny-1]) + qhat = -1; // 0xffffffff + else + { + long w = (((long)(zds[j])) << 32) + ((long)zds[j-1] & 0xffffffffL); + qhat = (int) udiv_qrnnd (w, y[ny-1]); + } + if (qhat != 0) + { + int borrow = submul_1 (zds, j - ny, y, ny, qhat); + int save = zds[j]; + long num = ((long)save&0xffffffffL) - ((long)borrow&0xffffffffL); + while (num != 0) + { + qhat--; + long carry = 0; + for (int i = 0; i < ny; i++) + { + carry += ((long) zds[j-ny+i] & 0xffffffffL) + + ((long) y[i] & 0xffffffffL); + zds[j-ny+i] = (int) carry; + carry >>>= 32; + } + zds[j] += carry; + num = carry - 1; + } + } + zds[j] = qhat; + } while (--j >= ny); + } + + /** Number of digits in the conversion base that always fits in a word. + * For example, for base 10 this is 9, since 10**9 is the + * largest number that fits into a words (assuming 32-bit words). + * This is the same as gmp's __mp_bases[radix].chars_per_limb. + * @param radix the base + * @return number of digits */ + public static int chars_per_word (int radix) + { + if (radix < 10) + { + if (radix < 8) + { + if (radix <= 2) + return 32; + else if (radix == 3) + return 20; + else if (radix == 4) + return 16; + else + return 18 - radix; + } + else + return 10; + } + else if (radix < 12) + return 9; + else if (radix <= 16) + return 8; + else if (radix <= 23) + return 7; + else if (radix <= 40) + return 6; + // The following are conservative, but we don't care. + else if (radix <= 256) + return 4; + else + return 1; + } + + /** Count the number of leading zero bits in an int. */ + public static int count_leading_zeros (int i) + { + if (i == 0) + return 32; + int count = 0; + for (int k = 16; k > 0; k = k >> 1) { + int j = i >>> k; + if (j == 0) + count += k; + else + i = j; + } + return count; + } + + public static int set_str (int dest[], byte[] str, int str_len, int base) + { + int size = 0; + if ((base & (base - 1)) == 0) + { + // The base is a power of 2. Read the input string from + // least to most significant character/digit. */ + + int next_bitpos = 0; + int bits_per_indigit = 0; + for (int i = base; (i >>= 1) != 0; ) bits_per_indigit++; + int res_digit = 0; + + for (int i = str_len; --i >= 0; ) + { + int inp_digit = str[i]; + res_digit |= inp_digit << next_bitpos; + next_bitpos += bits_per_indigit; + if (next_bitpos >= 32) + { + dest[size++] = res_digit; + next_bitpos -= 32; + res_digit = inp_digit >> (bits_per_indigit - next_bitpos); + } + } + + if (res_digit != 0) + dest[size++] = res_digit; + } + else + { + // General case. The base is not a power of 2. + int indigits_per_limb = MPN.chars_per_word (base); + int str_pos = 0; + + while (str_pos < str_len) + { + int chunk = str_len - str_pos; + if (chunk > indigits_per_limb) + chunk = indigits_per_limb; + int res_digit = str[str_pos++]; + int big_base = base; + + while (--chunk > 0) + { + res_digit = res_digit * base + str[str_pos++]; + big_base *= base; + } + + int cy_limb; + if (size == 0) + cy_limb = res_digit; + else + { + cy_limb = MPN.mul_1 (dest, dest, size, big_base); + cy_limb += MPN.add_1 (dest, dest, size, res_digit); + } + if (cy_limb != 0) + dest[size++] = cy_limb; + } + } + return size; + } + + /** Compare x[0:size-1] with y[0:size-1], treating them as unsigned integers. + * @result -1, 0, or 1 depending on if x<y, x==y, or x>y. + * This is basically the same as gmp's mpn_cmp function. + */ + public static int cmp (int[] x, int[] y, int size) + { + while (--size >= 0) + { + int x_word = x[size]; + int y_word = y[size]; + if (x_word != y_word) + { + // Invert the high-order bit, because: + // (unsigned) X > (unsigned) Y iff + // (int) (X^0x80000000) > (int) (Y^0x80000000). + return (x_word ^ 0x80000000) > (y_word ^0x80000000) ? 1 : -1; + } + } + return 0; + } + + /** Compare x[0:xlen-1] with y[0:ylen-1], treating them as unsigned integers. + * @result -1, 0, or 1 depending on if x<y, x==y, or x>y. + */ + public static int cmp (int[] x, int xlen, int[] y, int ylen) + { + return xlen > ylen ? 1 : xlen < ylen ? -1 : cmp (x, y, xlen); + } + + /* Shift x[x_start:x_start+len-1] count bits to the "right" + * (i.e. divide by 2**count). + * Store the len least significant words of the result at dest. + * The bits shifted out to the right are returned. + * OK if dest==x. + * Assumes: 0 < count < 32 + */ + + public static int rshift (int[] dest, int[] x, int x_start, + int len, int count) + { + int count_2 = 32 - count; + int low_word = x[x_start]; + int retval = low_word << count_2; + int i = 1; + for (; i < len; i++) + { + int high_word = x[x_start+i]; + dest[i-1] = (low_word >>> count) | (high_word << count_2); + low_word = high_word; + } + dest[i-1] = low_word >>> count; + return retval; + } + + /* Shift x[x_start:x_start+len-1] count bits to the "right" + * (i.e. divide by 2**count). + * Store the len least significant words of the result at dest. + * OK if dest==x. + * Assumes: 0 <= count < 32 + * Same as rshift, but handles count==0 (and has no return value). + */ + public static void rshift0 (int[] dest, int[] x, int x_start, + int len, int count) + { + if (count > 0) + rshift(dest, x, x_start, len, count); + else + for (int i = 0; i < len; i++) + dest[i] = x[i + x_start]; + } + + /** Return the long-truncated value of right shifting. + * @param x a two's-complement "bignum" + * @param len the number of significant words in x + * @param count the shift count + * @return (long)(x[0..len-1] >> count). + */ + public static long rshift_long (int[] x, int len, int count) + { + int wordno = count >> 5; + count &= 31; + int sign = x[len-1] < 0 ? -1 : 0; + int w0 = wordno >= len ? sign : x[wordno]; + wordno++; + int w1 = wordno >= len ? sign : x[wordno]; + if (count != 0) + { + wordno++; + int w2 = wordno >= len ? sign : x[wordno]; + w0 = (w0 >>> count) | (w1 << (32-count)); + w1 = (w1 >>> count) | (w2 << (32-count)); + } + return ((long)w1 << 32) | ((long)w0 & 0xffffffffL); + } + + /* Shift x[0:len-1] left by count bits, and store the len least + * significant words of the result in dest[d_offset:d_offset+len-1]. + * Return the bits shifted out from the most significant digit. + * Assumes 0 < count < 32. + * OK if dest==x. + */ + + public static int lshift (int[] dest, int d_offset, + int[] x, int len, int count) + { + int count_2 = 32 - count; + int i = len - 1; + int high_word = x[i]; + int retval = high_word >>> count_2; + d_offset++; + while (--i >= 0) + { + int low_word = x[i]; + dest[d_offset+i] = (high_word << count) | (low_word >>> count_2); + high_word = low_word; + } + dest[d_offset+i] = high_word << count; + return retval; + } + + /** Return least i such that word&(1<<i). Assumes word!=0. */ + + public static int findLowestBit (int word) + { + int i = 0; + while ((word & 0xF) == 0) + { + word >>= 4; + i += 4; + } + if ((word & 3) == 0) + { + word >>= 2; + i += 2; + } + if ((word & 1) == 0) + i += 1; + return i; + } + + /** Return least i such that words & (1<<i). Assumes there is such an i. */ + + public static int findLowestBit (int[] words) + { + for (int i = 0; ; i++) + { + if (words[i] != 0) + return 32 * i + findLowestBit (words[i]); + } + } + + /** Calculate Greatest Common Divisior of x[0:len-1] and y[0:len-1]. + * Assumes both arguments are non-zero. + * Leaves result in x, and returns len of result. + * Also destroys y (actually sets it to a copy of the result). */ + + public static int gcd (int[] x, int[] y, int len) + { + int i, word; + // Find sh such that both x and y are divisible by 2**sh. + for (i = 0; ; i++) + { + word = x[i] | y[i]; + if (word != 0) + { + // Must terminate, since x and y are non-zero. + break; + } + } + int initShiftWords = i; + int initShiftBits = findLowestBit (word); + // Logically: sh = initShiftWords * 32 + initShiftBits + + // Temporarily devide both x and y by 2**sh. + len -= initShiftWords; + MPN.rshift0 (x, x, initShiftWords, len, initShiftBits); + MPN.rshift0 (y, y, initShiftWords, len, initShiftBits); + + int[] odd_arg; /* One of x or y which is odd. */ + int[] other_arg; /* The other one can be even or odd. */ + if ((x[0] & 1) != 0) + { + odd_arg = x; + other_arg = y; + } + else + { + odd_arg = y; + other_arg = x; + } + + for (;;) + { + // Shift other_arg until it is odd; this doesn't + // affect the gcd, since we divide by 2**k, which does not + // divide odd_arg. + for (i = 0; other_arg[i] == 0; ) i++; + if (i > 0) + { + int j; + for (j = 0; j < len-i; j++) + other_arg[j] = other_arg[j+i]; + for ( ; j < len; j++) + other_arg[j] = 0; + } + i = findLowestBit(other_arg[0]); + if (i > 0) + MPN.rshift (other_arg, other_arg, 0, len, i); + + // Now both odd_arg and other_arg are odd. + + // Subtract the smaller from the larger. + // This does not change the result, since gcd(a-b,b)==gcd(a,b). + i = MPN.cmp(odd_arg, other_arg, len); + if (i == 0) + break; + if (i > 0) + { // odd_arg > other_arg + MPN.sub_n (odd_arg, odd_arg, other_arg, len); + // Now odd_arg is even, so swap with other_arg; + int[] tmp = odd_arg; odd_arg = other_arg; other_arg = tmp; + } + else + { // other_arg > odd_arg + MPN.sub_n (other_arg, other_arg, odd_arg, len); + } + while (odd_arg[len-1] == 0 && other_arg[len-1] == 0) + len--; + } + if (initShiftWords + initShiftBits > 0) + { + if (initShiftBits > 0) + { + int sh_out = MPN.lshift (x, initShiftWords, x, len, initShiftBits); + if (sh_out != 0) + x[(len++)+initShiftWords] = sh_out; + } + else + { + for (i = len; --i >= 0;) + x[i+initShiftWords] = x[i]; + } + for (i = initShiftWords; --i >= 0; ) + x[i] = 0; + len += initShiftWords; + } + return len; + } + + public static int intLength (int i) + { + return 32 - count_leading_zeros (i < 0 ? ~i : i); + } + + /** Calcaulte the Common Lisp "integer-length" function. + * Assumes input is canonicalized: len==BigInteger.wordsNeeded(words,len) */ + public static int intLength (int[] words, int len) + { + len--; + return intLength (words[len]) + 32 * len; + } + + /* DEBUGGING: + public static void dprint (BigInteger x) + { + if (x.words == null) + System.err.print(Long.toString((long) x.ival & 0xffffffffL, 16)); + else + dprint (System.err, x.words, x.ival); + } + public static void dprint (int[] x) { dprint (System.err, x, x.length); } + public static void dprint (int[] x, int len) { dprint (System.err, x, len); } + public static void dprint (java.io.PrintStream ps, int[] x, int len) + { + ps.print('('); + for (int i = 0; i < len; i++) + { + if (i > 0) + ps.print (' '); + ps.print ("#x" + Long.toString ((long) x[i] & 0xffffffffL, 16)); + } + ps.print(')'); + } + */ +} diff --git a/java/lang/Math.java b/java/lang/Math.java index 66e9ebb8c..696108713 100644 --- a/java/lang/Math.java +++ b/java/lang/Math.java @@ -55,7 +55,7 @@ public final class Math { if (Configuration.INIT_LOAD_LIBRARY) { - System.loadLibrary ("javalangmath"); + System.loadLibrary ("javalang"); } } diff --git a/java/math/BigInteger.java b/java/math/BigInteger.java index 185b75b30..065d5fcf2 100644 --- a/java/math/BigInteger.java +++ b/java/math/BigInteger.java @@ -26,277 +26,2231 @@ executable file might be covered by the GNU General Public License. */ package java.math; +import gnu.classpath.math.*; import java.util.Random; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.IOException; -import gnu.classpath.Configuration; +/** + * @author Warren Levy <warrenl@cygnus.com> + * @date December 20, 1999. + */ -public class BigInteger implements Comparable { - final int native_state = System.identityHashCode(this); +/** + * Written using on-line Java Platform 1.2 API Specification, as well + * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998) and + * "Applied Cryptography, Second Edition" by Bruce Schneier (Wiley, 1996). + * + * Based primarily on IntNum.java BitOps.java by Per Bothner <per@bothner.com> + * (found in Kawa 1.6.62). + * + * Status: Believed complete and correct. + */ - public static final BigInteger ZERO; - public static final BigInteger ONE; +public class BigInteger extends Number implements Comparable +{ + /** All integers are stored in 2's-complement form. + * If words == null, the ival is the value of this BigInteger. + * Otherwise, the first ival elements of words make the value + * of this BigInteger, stored in little-endian order, 2's-complement form. */ + transient private int ival; + transient private int[] words; - static + // Serialization fields. + private int bitCount = -1; + private int bitLength = -1; + private int firstNonzeroByteNum = -2; + private int lowestSetBit = -2; + private byte[] magnitude; + private int signum; + private static final long serialVersionUID = -8287574255936472291L; + + + /** We pre-allocate integers in the range minFixNum..maxFixNum. */ + private static final int minFixNum = -100; + private static final int maxFixNum = 1024; + private static final int numFixNum = maxFixNum-minFixNum+1; + private static final BigInteger[] smallFixNums = new BigInteger[numFixNum]; + + static { + for (int i = numFixNum; --i >= 0; ) + smallFixNums[i] = new BigInteger(i + minFixNum); + } + + // JDK1.2 + public static final BigInteger ZERO = smallFixNums[-minFixNum]; + + // JDK1.2 + public static final BigInteger ONE = smallFixNums[1 - minFixNum]; + + /* Rounding modes: */ + private static final int FLOOR = 1; + private static final int CEILING = 2; + private static final int TRUNCATE = 3; + private static final int ROUND = 4; + + /** When checking the probability of primes, it is most efficient to + * first check the factoring of small primes, so we'll use this array. + */ + private static final int[] primes = + { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, + 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, + 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, + 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251 }; + + private BigInteger() + { + } + + /* Create a new (non-shared) BigInteger, and initialize to an int. */ + private BigInteger(int value) + { + ival = value; + } + + public BigInteger(String val, int radix) + { + BigInteger result = valueOf(val, radix); + this.ival = result.ival; + this.words = result.words; + } + + public BigInteger(String val) { - if (Configuration.INIT_LOAD_LIBRARY) + this(val, 10); + } + + /* Create a new (non-shared) BigInteger, and initialize from a byte array. */ + public BigInteger(byte[] val) + { + if (val == null || val.length < 1) + throw new NumberFormatException(); + + words = byteArrayToIntArray(val, val[0] < 0 ? -1 : 0); + BigInteger result = make(words, words.length); + this.ival = result.ival; + this.words = result.words; + } + + public BigInteger(int signum, byte[] magnitude) + { + if (magnitude == null || signum > 1 || signum < -1) + throw new NumberFormatException(); + + if (signum == 0) { - System.loadLibrary ("bigint"); - initNativeState(); + int i; + for (i = magnitude.length - 1; i >= 0 && magnitude[i] == 0; --i) + ; + if (i >= 0) + throw new NumberFormatException(); + return; } - ZERO = new BigInteger(); - ONE = new BigInteger(1L); + + // Magnitude is always positive, so don't ever pass a sign of -1. + words = byteArrayToIntArray(magnitude, 0); + BigInteger result = make(words, words.length); + this.ival = result.ival; + this.words = result.words; + + if (signum < 0) + setNegative(); } - public BigInteger(String val) { - this(val, 10); + public BigInteger(int numBits, Random rnd) + { + if (numBits < 0) + throw new IllegalArgumentException(); + + init(numBits, rnd); } - public BigInteger(String val, int radix) { - if (!initFromString(forEachDigit(val, radix), radix)) - throw new NumberFormatException(val); + private void init(int numBits, Random rnd) + { + int highbits = numBits & 31; + if (highbits > 0) + highbits = rnd.nextInt() >>> (32 - highbits); + int nwords = numBits / 32; + + while (highbits == 0 && nwords > 0) + { + highbits = rnd.nextInt(); + --nwords; + } + if (nwords == 0 && highbits >= 0) + { + ival = highbits; + } + else + { + ival = highbits < 0 ? nwords + 2 : nwords + 1; + words = new int[ival]; + words[nwords] = highbits; + while (--nwords >= 0) + words[nwords] = rnd.nextInt(); + } + } + + public BigInteger(int bitLength, int certainty, Random rnd) + { + this(bitLength, rnd); + + // Keep going until we find a probable prime. + while (true) + { + if (isProbablePrime(certainty)) + return; + + init(bitLength, rnd); + } + } + + /** Return a (possibly-shared) BigInteger with a given long value. */ + private static BigInteger make(long value) + { + if (value >= minFixNum && value <= maxFixNum) + return smallFixNums[(int)value - minFixNum]; + int i = (int) value; + if ((long)i == value) + return new BigInteger(i); + BigInteger result = alloc(2); + result.ival = 2; + result.words[0] = i; + result.words[1] = (int) (value >> 32); + return result; } - /** - * Canonicalizes each char digit in str, keeping a leading minus - * sign if it exists. + // FIXME: Could simply rename 'make' method above as valueOf while + // changing all instances of 'make'. Don't do this until this class + // is done as the Kawa class this is based on has 'make' methods + // with other parameters; wait to see if they are used in BigInteger. + public static BigInteger valueOf(long val) + { + return make(val); + } + + /** Make a canonicalized BigInteger from an array of words. + * The array may be reused (without copying). */ + private static BigInteger make(int[] words, int len) + { + if (words == null) + return make(len); + len = BigInteger.wordsNeeded(words, len); + if (len <= 1) + return len == 0 ? ZERO : make(words[0]); + BigInteger num = new BigInteger(); + num.words = words; + num.ival = len; + return num; + } + + /** Convert a big-endian byte array to a little-endian array of words. */ + private static int[] byteArrayToIntArray(byte[] bytes, int sign) + { + // Determine number of words needed. + int[] words = new int[bytes.length/4 + 1]; + int nwords = words.length; + + // Create a int out of modulo 4 high order bytes. + int bptr = 0; + int word = sign; + for (int i = bytes.length % 4; i > 0; --i, bptr++) + word = (word << 8) | (((int) bytes[bptr]) & 0xff); + words[--nwords] = word; + + // Elements remaining in byte[] are a multiple of 4. + while (nwords > 0) + words[--nwords] = bytes[bptr++] << 24 | + (((int) bytes[bptr++]) & 0xff) << 16 | + (((int) bytes[bptr++]) & 0xff) << 8 | + (((int) bytes[bptr++]) & 0xff); + return words; + } + + /** Allocate a new non-shared BigInteger. + * @param nwords number of words to allocate */ - static String forEachDigit(String str, int radix) { - char buf[] = new char[str.length()]; - int i = 0; - if (str.charAt(0) == '-') - buf[i++] = '-'; + private static BigInteger alloc(int nwords) + { + if (nwords <= 1) + return new BigInteger(); + BigInteger result = new BigInteger(); + result.words = new int[nwords]; + return result; + } + + /** Change words.length to nwords. + * We allow words.length to be upto nwords+2 without reallocating. + */ + private void realloc(int nwords) + { + if (nwords == 0) + { + if (words != null) + { + if (ival > 0) + ival = words[0]; + words = null; + } + } + else if (words == null + || words.length < nwords + || words.length > nwords + 2) + { + int[] new_words = new int [nwords]; + if (words == null) + { + new_words[0] = ival; + ival = 1; + } + else + { + if (nwords < ival) + ival = nwords; + System.arraycopy(words, 0, new_words, 0, ival); + } + words = new_words; + } + } + + private final boolean isNegative() + { + return (words == null ? ival : words[ival - 1]) < 0; + } - for ( ; i < buf.length; i++) - if ((buf[i] = - Character.forDigit(Character.digit(str.charAt(i), radix), radix)) - == '\u0000') - throw new NumberFormatException(str + " not valid in radix " + radix); + public int signum() + { + int top = words == null ? ival : words[ival-1]; + if (top == 0 && words == null) + return 0; + return top < 0 ? -1 : 1; + } + + private static int compareTo(BigInteger x, BigInteger y) + { + if (x.words == null && y.words == null) + return x.ival < y.ival ? -1 : x.ival > y.ival ? 1 : 0; + boolean x_negative = x.isNegative(); + boolean y_negative = y.isNegative(); + if (x_negative != y_negative) + return x_negative ? -1 : 1; + int x_len = x.words == null ? 1 : x.ival; + int y_len = y.words == null ? 1 : y.ival; + if (x_len != y_len) + return (x_len > y_len) != x_negative ? 1 : -1; + return MPN.cmp(x.words, y.words, x_len); + } + + // JDK1.2 + public int compareTo(Object obj) + { + if (obj instanceof BigInteger) + return compareTo(this, (BigInteger) obj); + throw new ClassCastException(); + } - return new String(buf); + public int compareTo(BigInteger val) + { + return compareTo(this, val); } - public BigInteger(int bitLength, int certainty, Random rnd) { - throw new ArithmeticException("unimplemented"); + public BigInteger min(BigInteger val) + { + return compareTo(this, val) < 0 ? this : val; } - public BigInteger(int numBits, Random rnd) { - this(1, getRandomMagnitude(numBits, rnd)); + public BigInteger max(BigInteger val) + { + return compareTo(this, val) > 0 ? this : val; } - private static byte[] getRandomMagnitude(int numBits, Random rnd) { - int array_size = numBits / 8; - int extra_bits = numBits % 8; - if (extra_bits != 0) - array_size++; + private final boolean isOdd() + { + int low = words == null ? ival : words[0]; + return (low & 1) != 0; + } - byte[] data = new byte[array_size]; - rnd.nextBytes(data); - if (extra_bits != 0) - data[0] &= (1 << extra_bits) - 1; // mask off any extra bits + private final boolean isZero() + { + return words == null && ival == 0; + } - return data; + private final boolean isOne() + { + return words == null && ival == 1; } - public BigInteger(byte[] val) { - if (val.length == 0) - throw new NumberFormatException("val.length is 0"); - initFromTwosCompByteArray(val); + private final boolean isMinusOne() + { + return words == null && ival == -1; } - public BigInteger(int signum, byte[] magnitude) { - switch (signum) { - case 0: - for (int i = 0; i < magnitude.length; i++) - if (magnitude[i] != 0) - throw new NumberFormatException("magnitude["+i+"] is non zero"); - initZero(); - break; - case 1: - case -1: - if (magnitude.length == 0) - initZero(); - else - initFromSignedMagnitudeByteArray(signum, magnitude); - break; - default: - throw new NumberFormatException("invalid signum"); - } + /** Calculate how many words are significant in words[0:len-1]. + * Returns the least value x such that x>0 && words[0:x-1]==words[0:len-1], + * when words is viewed as a 2's complement integer. + */ + private static int wordsNeeded(int[] words, int len) + { + int i = len; + if (i > 0) + { + int word = words[--i]; + if (word == -1) + { + while (i > 0 && (word = words[i - 1]) < 0) + { + i--; + if (word != -1) break; + } + } + else + { + while (word == 0 && i > 0 && (word = words[i - 1]) >= 0) i--; + } + } + return i + 1; } - private BigInteger(long l) { - initFromLong(l); + private BigInteger canonicalize() + { + if (words != null + && (ival = BigInteger.wordsNeeded(words, ival)) <= 1) + { + if (ival == 1) + ival = words[0]; + words = null; + } + if (words == null && ival >= minFixNum && ival <= maxFixNum) + return smallFixNums[(int) ival - minFixNum]; + return this; } - private BigInteger() { - initZero(); + /** Add two ints, yielding a BigInteger. */ + private static final BigInteger add(int x, int y) + { + return BigInteger.make((long) x + (long) y); } - static public BigInteger valueOf(long l) { - if (l == 0) + /** Add a BigInteger and an int, yielding a new BigInteger. */ + private static BigInteger add(BigInteger x, int y) + { + if (x.words == null) + return BigInteger.add(x.ival, y); + BigInteger result = new BigInteger(0); + result.setAdd(x, y); + return result.canonicalize(); + } + + /** Set this to the sum of x and y. + * OK if x==this. */ + private void setAdd(BigInteger x, int y) + { + if (x.words == null) + { + set((long) x.ival + (long) y); + return; + } + int len = x.ival; + realloc(len + 1); + long carry = y; + for (int i = 0; i < len; i++) + { + carry += ((long) x.words[i] & 0xffffffffL); + words[i] = (int) carry; + carry >>= 32; + } + if (x.words[len - 1] < 0) + carry--; + words[len] = (int) carry; + ival = wordsNeeded(words, len + 1); + } + + /** Destructively add an int to this. */ + private final void setAdd(int y) + { + setAdd(this, y); + } + + /** Destructively set the value of this to a long. */ + private final void set(long y) + { + int i = (int) y; + if ((long) i == y) + { + ival = i; + words = null; + } + else + { + realloc(2); + words[0] = i; + words[1] = (int) (y >> 32); + ival = 2; + } + } + + /** Destructively set the value of this to the given words. + * The words array is reused, not copied. */ + private final void set(int[] words, int length) + { + this.ival = length; + this.words = words; + } + + /** Destructively set the value of this to that of y. */ + private final void set(BigInteger y) + { + if (y.words == null) + set(y.ival); + else if (this != y) + { + realloc(y.ival); + System.arraycopy(y.words, 0, words, 0, y.ival); + ival = y.ival; + } + } + + /** Add two BigIntegers, yielding their sum as another BigInteger. */ + private static BigInteger add(BigInteger x, BigInteger y, int k) + { + if (x.words == null && y.words == null) + return BigInteger.make((long) k * (long) y.ival + (long) x.ival); + if (k != 1) + { + if (k == -1) + y = BigInteger.neg(y); + else + y = BigInteger.times(y, BigInteger.make(k)); + } + if (x.words == null) + return BigInteger.add(y, x.ival); + if (y.words == null) + return BigInteger.add(x, y.ival); + // Both are big + int len; + if (y.ival > x.ival) + { // Swap so x is longer then y. + BigInteger tmp = x; x = y; y = tmp; + } + BigInteger result = alloc(x.ival + 1); + int i = y.ival; + long carry = MPN.add_n(result.words, x.words, y.words, i); + long y_ext = y.words[i - 1] < 0 ? 0xffffffffL : 0; + for (; i < x.ival; i++) + { + carry += ((long) x.words[i] & 0xffffffffL) + y_ext;; + result.words[i] = (int) carry; + carry >>>= 32; + } + if (x.words[i - 1] < 0) + y_ext--; + result.words[i] = (int) (carry + y_ext); + result.ival = i+1; + return result.canonicalize(); + } + + public BigInteger add(BigInteger val) + { + return add(this, val, 1); + } + + public BigInteger subtract(BigInteger val) + { + return add(this, val, -1); + } + + private static final BigInteger times(BigInteger x, int y) + { + if (y == 0) return ZERO; - if (l == 1) - return ONE; - return new BigInteger(l); - } - - native public BigInteger abs(); - native public BigInteger add(BigInteger val); - native public BigInteger subtact(BigInteger val); - native public BigInteger multiply(BigInteger val); - native public BigInteger divide(BigInteger val) - throws ArithmeticException; - native public BigInteger remainder(BigInteger val) - throws ArithmeticException; - native public BigInteger gcd(BigInteger val); - - public BigInteger[] divideAndRemainder(BigInteger val) - throws ArithmeticException { - BigInteger res[] = new BigInteger[2]; - res[0] = divide(val); - res[1] = remainder(val); - return res; - } - - native public BigInteger pow(int exponent) - throws ArithmeticException; - native public BigInteger modPow(BigInteger exponent, - BigInteger m) - throws ArithmeticException; - native public BigInteger mod(BigInteger m) - throws ArithmeticException; - native public BigInteger modInverse(BigInteger m) - throws ArithmeticException; - - // bitwise operations - native public BigInteger shiftLeft(int n); - native public BigInteger shiftRight(int n); - native public BigInteger and(BigInteger val); - native public BigInteger or(BigInteger val); - native public BigInteger xor(BigInteger val); - native public BigInteger not(); - native public BigInteger andNot(BigInteger val); - native public int getLowestSetBit(); - native public int bitLength(); - native public int bitCount(); - native public boolean testBit(int n); - native public BigInteger setBit(int n); - native public BigInteger clearBit(int n); - native public BigInteger flipBit(int n); - - native public boolean isProbablePrime(int certainty); - - native public BigInteger negate(); - native public BigInteger subtract(BigInteger val); - native public int compareTo(BigInteger val); - public int compareTo(Object o) throws ClassCastException { - return compareTo((BigInteger)o); - } - native public int signum(); - - public boolean equals(Object o) { - return (o instanceof BigInteger && nativeEquals((BigInteger)o)); - } - - public BigInteger min(BigInteger val) { - switch (compareTo(val)) { - case -1: - case 0: + if (y == 1) + return x; + int[] xwords = x.words; + int xlen = x.ival; + if (xwords == null) + return BigInteger.make((long) xlen * (long) y); + boolean negative; + BigInteger result = BigInteger.alloc(xlen + 1); + if (xwords[xlen - 1] < 0) + { + negative = true; + negate(result.words, xwords, xlen); + xwords = result.words; + } + else + negative = false; + if (y < 0) + { + negative = !negative; + y = -y; + } + result.words[xlen] = MPN.mul_1(result.words, xwords, xlen, y); + result.ival = xlen + 1; + if (negative) + result.setNegative(); + return result.canonicalize(); + } + + private static final BigInteger times(BigInteger x, BigInteger y) + { + if (y.words == null) + return times(x, y.ival); + if (x.words == null) + return times(y, x.ival); + boolean negative = false; + int[] xwords; + int[] ywords; + int xlen = x.ival; + int ylen = y.ival; + if (x.isNegative()) + { + negative = true; + xwords = new int[xlen]; + negate(xwords, x.words, xlen); + } + else + { + negative = false; + xwords = x.words; + } + if (y.isNegative()) + { + negative = !negative; + ywords = new int[ylen]; + negate(ywords, y.words, ylen); + } + else + ywords = y.words; + // Swap if x is shorter then y. + if (xlen < ylen) + { + int[] twords = xwords; xwords = ywords; ywords = twords; + int tlen = xlen; xlen = ylen; ylen = tlen; + } + BigInteger result = BigInteger.alloc(xlen+ylen); + MPN.mul(result.words, xwords, xlen, ywords, ylen); + result.ival = xlen+ylen; + if (negative) + result.setNegative(); + return result.canonicalize(); + } + + public BigInteger multiply(BigInteger y) + { + return times(this, y); + } + + private static void divide(long x, long y, + BigInteger quotient, BigInteger remainder, + int rounding_mode) + { + boolean xNegative, yNegative; + if (x < 0) + { + xNegative = true; + if (x == Long.MIN_VALUE) + { + divide(BigInteger.make(x), BigInteger.make(y), + quotient, remainder, rounding_mode); + return; + } + x = -x; + } + else + xNegative = false; + + if (y < 0) + { + yNegative = true; + if (y == Long.MIN_VALUE) + { + if (rounding_mode == TRUNCATE) + { // x != Long.Min_VALUE implies abs(x) < abs(y) + if (quotient != null) + quotient.set(0); + if (remainder != null) + remainder.set(x); + } + else + divide(BigInteger.make(x), BigInteger.make(y), + quotient, remainder, rounding_mode); + return; + } + y = -y; + } + else + yNegative = false; + + long q = x / y; + long r = x % y; + boolean qNegative = xNegative ^ yNegative; + + boolean add_one = false; + if (r != 0) + { + switch (rounding_mode) + { + case TRUNCATE: + break; + case CEILING: + case FLOOR: + if (qNegative == (rounding_mode == FLOOR)) + add_one = true; + break; + case ROUND: + add_one = r > ((y - (q & 1)) >> 1); + break; + } + } + if (quotient != null) + { + if (add_one) + q++; + if (qNegative) + q = -q; + quotient.set(q); + } + if (remainder != null) + { + // The remainder is by definition: X-Q*Y + if (add_one) + { + // Subtract the remainder from Y. + r = y - r; + // In this case, abs(Q*Y) > abs(X). + // So sign(remainder) = -sign(X). + xNegative = ! xNegative; + } + else + { + // If !add_one, then: abs(Q*Y) <= abs(X). + // So sign(remainder) = sign(X). + } + if (xNegative) + r = -r; + remainder.set(r); + } + } + + /** Divide two integers, yielding quotient and remainder. + * @param x the numerator in the division + * @param y the denominator in the division + * @param quotient is set to the quotient of the result (iff quotient!=null) + * @param remainder is set to the remainder of the result + * (iff remainder!=null) + * @param rounding_mode one of FLOOR, CEILING, TRUNCATE, or ROUND. + */ + private static void divide(BigInteger x, BigInteger y, + BigInteger quotient, BigInteger remainder, + int rounding_mode) + { + if ((x.words == null || x.ival <= 2) + && (y.words == null || y.ival <= 2)) + { + long x_l = x.longValue(); + long y_l = y.longValue(); + if (x_l != Long.MIN_VALUE && y_l != Long.MIN_VALUE) + { + divide(x_l, y_l, quotient, remainder, rounding_mode); + return; + } + } + + boolean xNegative = x.isNegative(); + boolean yNegative = y.isNegative(); + boolean qNegative = xNegative ^ yNegative; + + int ylen = y.words == null ? 1 : y.ival; + int[] ywords = new int[ylen]; + y.getAbsolute(ywords); + while (ylen > 1 && ywords[ylen - 1] == 0) ylen--; + + int xlen = x.words == null ? 1 : x.ival; + int[] xwords = new int[xlen+2]; + x.getAbsolute(xwords); + while (xlen > 1 && xwords[xlen-1] == 0) xlen--; + + int qlen, rlen; + + int cmpval = MPN.cmp(xwords, xlen, ywords, ylen); + if (cmpval < 0) // abs(x) < abs(y) + { // quotient = 0; remainder = num. + int[] rwords = xwords; xwords = ywords; ywords = rwords; + rlen = xlen; qlen = 1; xwords[0] = 0; + } + else if (cmpval == 0) // abs(x) == abs(y) + { + xwords[0] = 1; qlen = 1; // quotient = 1 + ywords[0] = 0; rlen = 1; // remainder = 0; + } + else if (ylen == 1) + { + qlen = xlen; + // Need to leave room for a word of leading zeros if dividing by 1 + // and the dividend has the high bit set. It might be safe to + // increment qlen in all cases, but it certainly is only necessary + // in the following case. + if (ywords[0] == 1 && xwords[xlen-1] < 0) + qlen++; + rlen = 1; + ywords[0] = MPN.divmod_1(xwords, xwords, xlen, ywords[0]); + } + else // abs(x) > abs(y) + { + // Normalize the denominator, i.e. make its most significant bit set by + // shifting it normalization_steps bits to the left. Also shift the + // numerator the same number of steps (to keep the quotient the same!). + + int nshift = MPN.count_leading_zeros(ywords[ylen - 1]); + if (nshift != 0) + { + // Shift up the denominator setting the most significant bit of + // the most significant word. + MPN.lshift(ywords, 0, ywords, ylen, nshift); + + // Shift up the numerator, possibly introducing a new most + // significant word. + int x_high = MPN.lshift(xwords, 0, xwords, xlen, nshift); + xwords[xlen++] = x_high; + } + + if (xlen == ylen) + xwords[xlen++] = 0; + MPN.divide(xwords, xlen, ywords, ylen); + rlen = ylen; + MPN.rshift0 (ywords, xwords, 0, rlen, nshift); + + qlen = xlen + 1 - ylen; + if (quotient != null) + { + for (int i = 0; i < qlen; i++) + xwords[i] = xwords[i+ylen]; + } + } + + if (ywords[rlen-1] < 0) + { + ywords[rlen] = 0; + rlen++; + } + + // Now the quotient is in xwords, and the remainder is in ywords. + + boolean add_one = false; + if (rlen > 1 || ywords[0] != 0) + { // Non-zero remainder i.e. in-exact quotient. + switch (rounding_mode) + { + case TRUNCATE: + break; + case CEILING: + case FLOOR: + if (qNegative == (rounding_mode == FLOOR)) + add_one = true; + break; + case ROUND: + // int cmp = compareTo(remainder<<1, abs(y)); + BigInteger tmp = remainder == null ? new BigInteger() : remainder; + tmp.set(ywords, rlen); + tmp = shift(tmp, 1); + if (yNegative) + tmp.setNegative(); + int cmp = compareTo(tmp, y); + // Now cmp == compareTo(sign(y)*(remainder<<1), y) + if (yNegative) + cmp = -cmp; + add_one = (cmp == 1) || (cmp == 0 && (xwords[0]&1) != 0); + } + } + if (quotient != null) + { + quotient.set(xwords, qlen); + if (qNegative) + { + if (add_one) // -(quotient + 1) == ~(quotient) + quotient.setInvert(); + else + quotient.setNegative(); + } + else if (add_one) + quotient.setAdd(1); + } + if (remainder != null) + { + // The remainder is by definition: X-Q*Y + remainder.set(ywords, rlen); + if (add_one) + { + // Subtract the remainder from Y: + // abs(R) = abs(Y) - abs(orig_rem) = -(abs(orig_rem) - abs(Y)). + BigInteger tmp; + if (y.words == null) + { + tmp = remainder; + tmp.set(yNegative ? ywords[0] + y.ival : ywords[0] - y.ival); + } + else + tmp = BigInteger.add(remainder, y, yNegative ? 1 : -1); + // Now tmp <= 0. + // In this case, abs(Q) = 1 + floor(abs(X)/abs(Y)). + // Hence, abs(Q*Y) > abs(X). + // So sign(remainder) = -sign(X). + if (xNegative) + remainder.setNegative(tmp); + else + remainder.set(tmp); + } + else + { + // If !add_one, then: abs(Q*Y) <= abs(X). + // So sign(remainder) = sign(X). + if (xNegative) + remainder.setNegative(); + } + } + } + + public BigInteger divide(BigInteger val) + { + if (val.isZero()) + throw new ArithmeticException("divisor is zero"); + + BigInteger quot = new BigInteger(); + divide(this, val, quot, null, TRUNCATE); + return quot.canonicalize(); + } + + public BigInteger remainder(BigInteger val) + { + if (val.isZero()) + throw new ArithmeticException("divisor is zero"); + + BigInteger rem = new BigInteger(); + divide(this, val, null, rem, TRUNCATE); + return rem.canonicalize(); + } + + public BigInteger[] divideAndRemainder(BigInteger val) + { + if (val.isZero()) + throw new ArithmeticException("divisor is zero"); + + BigInteger[] result = new BigInteger[2]; + result[0] = new BigInteger(); + result[1] = new BigInteger(); + divide(this, val, result[0], result[1], TRUNCATE); + result[0].canonicalize(); + result[1].canonicalize(); + return result; + } + + public BigInteger mod(BigInteger m) + { + if (m.isNegative() || m.isZero()) + throw new ArithmeticException("non-positive modulus"); + + BigInteger rem = new BigInteger(); + divide(this, m, null, rem, FLOOR); + return rem.canonicalize(); + } + + /** Calculate power for BigInteger exponents. + * @param y exponent assumed to be non-negative. */ + private BigInteger pow(BigInteger y) + { + if (isOne()) return this; - default: - return val; - } + if (isMinusOne()) + return y.isOdd () ? this : ONE; + if (y.words == null && y.ival >= 0) + return pow(y.ival); + + // Assume exponent is non-negative. + if (isZero()) + return this; + + // Implemented by repeated squaring and multiplication. + BigInteger pow2 = this; + BigInteger r = null; + for (;;) // for (i = 0; ; i++) + { + // pow2 == x**(2**i) + // prod = x**(sum(j=0..i-1, (y>>j)&1)) + if (y.isOdd()) + r = r == null ? pow2 : times(r, pow2); // r *= pow2 + y = BigInteger.shift(y, -1); + if (y.isZero()) + break; + // pow2 *= pow2; + pow2 = times(pow2, pow2); + } + return r == null ? ONE : r; } - public BigInteger max(BigInteger val) { - switch (compareTo(val)) { - case -1: - case 0: - return val; - default: + /** Calculate the integral power of a BigInteger. + * @param exponent the exponent (must be non-negative) + */ + public BigInteger pow(int exponent) + { + if (exponent <= 0) + { + if (exponent == 0) + return ONE; + else + throw new ArithmeticException("negative exponent"); + } + if (isZero()) return this; - } + int plen = words == null ? 1 : ival; // Length of pow2. + int blen = ((bitLength() * exponent) >> 5) + 2 * plen; + boolean negative = isNegative() && (exponent & 1) != 0; + int[] pow2 = new int [blen]; + int[] rwords = new int [blen]; + int[] work = new int [blen]; + getAbsolute(pow2); // pow2 = abs(this); + int rlen = 1; + rwords[0] = 1; // rwords = 1; + for (;;) // for (i = 0; ; i++) + { + // pow2 == this**(2**i) + // prod = this**(sum(j=0..i-1, (exponent>>j)&1)) + if ((exponent & 1) != 0) + { // r *= pow2 + MPN.mul(work, pow2, plen, rwords, rlen); + int[] temp = work; work = rwords; rwords = temp; + rlen += plen; + while (rwords[rlen - 1] == 0) rlen--; + } + exponent >>= 1; + if (exponent == 0) + break; + // pow2 *= pow2; + MPN.mul(work, pow2, plen, pow2, plen); + int[] temp = work; work = pow2; pow2 = temp; // swap to avoid a copy + plen *= 2; + while (pow2[plen - 1] == 0) plen--; + } + if (rwords[rlen - 1] < 0) + rlen++; + if (negative) + negate(rwords, rwords, rlen); + return BigInteger.make(rwords, rlen); } - public native int hashCode(); + private static final int[] euclidInv(int a, int b, int prevDiv) + { + // Storage for return values, plus one slot for a temp int (see below). + int[] xy; - static native void initNativeState(); - native boolean initFromString(String val, int radix); - native void initFromLong(long l); - native void initFromSignedMagnitudeByteArray(int signum, byte[] magnitude); - native void initFromTwosCompByteArray(byte[] array); - native void initZero(); + if (b == 0) + throw new ArithmeticException("not invertible"); + else if (b == 1) + { + // Success: values are indeed invertible! + // Bottom of the recursion reached; start unwinding. + xy = new int[3]; + xy[0] = -prevDiv; + xy[1] = 1; + return xy; + } - public native void print(); - native boolean nativeEquals(BigInteger val); + xy = euclidInv(b, a % b, a / b); // Recursion happens here. - public native long longValue(); - public int intValue() { - return (int)longValue(); + // xy[2] is just temp storage for intermediate results in the following + // calculation. This saves us a bit of space over having an int + // allocated at every level of this recursive method. + xy[2] = xy[0]; + xy[0] = xy[2] * -prevDiv + xy[1]; + xy[1] = xy[2]; + return xy; } - - public native double doubleValue(); - public float floatValue() { - return (float)doubleValue(); + + private static final BigInteger[] + euclidInv(BigInteger a, BigInteger b, BigInteger prevDiv) + { + // FIXME: This method could be more efficient memory-wise and should be + // modified as such since it is recursive. + + // Storage for return values, plus one slot for a temp int (see below). + BigInteger[] xy; + + if (b.isZero()) + throw new ArithmeticException("not invertible"); + else if (b.isOne()) + { + // Success: values are indeed invertible! + // Bottom of the recursion reached; start unwinding. + xy = new BigInteger[3]; + xy[0] = neg(prevDiv); + xy[1] = ONE; + return xy; + } + + // Recursion happens in the following conditional! + + // If a just contains an int, then use integer math for the rest. + if (a.words == null) + { + int[] xyInt = euclidInv(b.ival, a.ival % b.ival, a.ival / b.ival); + xy = new BigInteger[3]; + xy[0] = new BigInteger(xyInt[0]); + xy[1] = new BigInteger(xyInt[1]); + } + else + { + BigInteger rem = new BigInteger(); + BigInteger quot = new BigInteger(); + divide(a, b, quot, rem, FLOOR); + xy = euclidInv(b, rem, quot); + } + + // xy[2] is just temp storage for intermediate results in the following + // calculation. This saves us a bit of space over having a BigInteger + // allocated at every level of this recursive method. + xy[2] = xy[0]; + xy[0] = add(xy[1], times(xy[2], prevDiv), -1); + xy[1] = xy[2]; + return xy; } - public native String toString(int radix); + public BigInteger modInverse(BigInteger y) + { + if (y.isNegative() || y.isZero()) + throw new ArithmeticException("non-positive modulo"); + + // Degenerate cases. + if (y.isOne()) + return ZERO; + else if (isOne()) + return ONE; + + // Use Euclid's algorithm as in gcd() but do this recursively + // rather than in a loop so we can use the intermediate results as we + // unwind from the recursion. + // Used http://www.math.nmsu.edu/~crypto/EuclideanAlgo.html as reference. + BigInteger result = new BigInteger(); + int xval = ival; + int yval = y.ival; + boolean swapped = false; + + if (y.words == null) + { + // The result is guaranteed to be less than the modulus, y (which is + // an int), so simplify this by working with the int result of this + // modulo y. Also, if this is negative, make it positive via modulo + // math. Note that BigInteger.mod() must be used even if this is + // already an int as the % operator would provide a negative result if + // this is negative, BigInteger.mod() never returns negative values. + if (words != null || isNegative()) + xval = mod(y).ival; + + // Swap values so x > y. + if (yval > xval) + { + int tmp = xval; xval = yval; yval = tmp; + swapped = true; + } + // Normally, the result is in the 2nd element of the array, but + // if originally x < y, then x and y were swapped and the result + // is in the 1st element of the array. + result.ival = + euclidInv(yval, xval % yval, xval / yval)[swapped ? 0 : 1]; + + // Result can't be negative, so make it positive by adding the + // original modulus, y.ival (not the possibly "swapped" yval). + if (result.ival < 0) + result.ival += y.ival; + } + else + { + BigInteger x = this; + + // As above, force this to be a positive value via modulo math. + if (isNegative()) + x = mod(y); + + // Swap values so x > y. + if (x.compareTo(y) < 0) + { + BigInteger tmp = x; x = y; y = tmp; + swapped = true; + } + // As above (for ints), result will be in the 2nd element unless + // the original x and y were swapped. + BigInteger rem = new BigInteger(); + BigInteger quot = new BigInteger(); + divide(x, y, quot, rem, FLOOR); + result = euclidInv(y, rem, quot)[swapped ? 0 : 1]; + + // Result can't be negative, so make it positive by adding the + // original modulus, y (which is now x if they were swapped). + if (result.isNegative()) + result = add(result, swapped ? x : y, 1); + } - public String toString() { + return result; + } + + public BigInteger modPow(BigInteger exponent, BigInteger m) + { + if (m.isNegative() || m.isZero()) + throw new ArithmeticException("non-positive modulo"); + + if (exponent.isNegative()) + return modInverse(m); + if (exponent.isOne()) + return mod(m); + + // To do this naively by first raising this to the power of exponent + // and then performing modulo m would be extremely expensive, especially + // for very large numbers. The solution is found in Number Theory + // where a combination of partial powers and modulos can be done easily. + // + // We'll use the algorithm for Additive Chaining which can be found on + // p. 244 of "Applied Cryptography, Second Edition" by Bruce Schneier. + BigInteger s, t, u; + int i; + + s = ONE; + t = this; + u = exponent; + + while (!u.isZero()) + { + if (u.and(ONE).isOne()) + s = times(s, t).mod(m); + u = u.shiftRight(1); + t = times(t, t).mod(m); + } + + return s; + } + + /** Calculate Greatest Common Divisor for non-negative ints. */ + private static final int gcd(int a, int b) + { + // Euclid's algorithm, copied from libg++. + if (b > a) + { + int tmp = a; a = b; b = tmp; + } + for(;;) + { + if (b == 0) + return a; + else if (b == 1) + return b; + else + { + int tmp = b; + b = a % b; + a = tmp; + } + } + } + + public BigInteger gcd(BigInteger y) + { + int xval = ival; + int yval = y.ival; + if (words == null) + { + if (xval == 0) + return BigInteger.abs(y); + if (y.words == null + && xval != Integer.MIN_VALUE && yval != Integer.MIN_VALUE) + { + if (xval < 0) + xval = -xval; + if (yval < 0) + yval = -yval; + return BigInteger.make(BigInteger.gcd(xval, yval)); + } + xval = 1; + } + if (y.words == null) + { + if (yval == 0) + return BigInteger.abs(this); + yval = 1; + } + int len = (xval > yval ? xval : yval) + 1; + int[] xwords = new int[len]; + int[] ywords = new int[len]; + getAbsolute(xwords); + y.getAbsolute(ywords); + len = MPN.gcd(xwords, ywords, len); + BigInteger result = new BigInteger(0); + result.ival = len; + result.words = xwords; + return result.canonicalize(); + } + + public boolean isProbablePrime(int certainty) + { + /** We'll use the Rabin-Miller algorithm for doing a probabilistic + * primality test. It is fast, easy and has faster decreasing odds of a + * composite passing than with other tests. This means that this + * method will actually have a probability much greater than the + * 1 - .5^certainty specified in the JCL (p. 117), but I don't think + * anyone will complain about better performance with greater certainty. + * + * The Rabin-Miller algorithm can be found on pp. 259-261 of "Applied + * Cryptography, Second Edition" by Bruce Schneier. + */ + + // First rule out small prime factors and assure the number is odd. + for (int i = 0; i < primes.length; i++) + { + if (words == null && ival == primes[i]) + return true; + if (remainder(make(primes[i])).isZero()) + return false; + } + + // Now perform the Rabin-Miller test. + // NB: I know that this can be simplified programatically, but + // I have tried to keep it as close as possible to the algorithm + // as written in the Schneier book for reference purposes. + + // Set b to the number of times 2 evenly divides (this - 1). + // I.e. 2^b is the largest power of 2 that divides (this - 1). + BigInteger pMinus1 = add(this, -1); + int b = pMinus1.getLowestSetBit(); + + // Set m such that this = 1 + 2^b * m. + BigInteger m = pMinus1.divide(make(2L << b - 1)); + + Random rand = new Random(); + while (certainty-- > 0) + { + // Pick a random number greater than 1 and less than this. + // The algorithm says to pick a small number to make the calculations + // go faster, but it doesn't say how small; we'll use 2 to 1024. + int a = rand.nextInt(); + a = (a < 0 ? -a : a) % 1023 + 2; + + BigInteger z = make(a).modPow(m, this); + if (z.isOne() || z.equals(pMinus1)) + continue; // Passes the test; may be prime. + + int i; + for (i = 0; i < b; ) + { + if (z.isOne()) + return false; + i++; + if (z.equals(pMinus1)) + break; // Passes the test; may be prime. + + z = z.modPow(make(2), this); + } + + if (i == b && !z.equals(pMinus1)) + return false; + } + return true; + } + + private void setInvert() + { + if (words == null) + ival = ~ival; + else + { + for (int i = ival; --i >= 0; ) + words[i] = ~words[i]; + } + } + + private void setShiftLeft(BigInteger x, int count) + { + int[] xwords; + int xlen; + if (x.words == null) + { + if (count < 32) + { + set((long) x.ival << count); + return; + } + xwords = new int[1]; + xwords[0] = x.ival; + xlen = 1; + } + else + { + xwords = x.words; + xlen = x.ival; + } + int word_count = count >> 5; + count &= 31; + int new_len = xlen + word_count; + if (count == 0) + { + realloc(new_len); + for (int i = xlen; --i >= 0; ) + words[i+word_count] = xwords[i]; + } + else + { + new_len++; + realloc(new_len); + int shift_out = MPN.lshift(words, word_count, xwords, xlen, count); + count = 32 - count; + words[new_len-1] = (shift_out << count) >> count; // sign-extend. + } + ival = new_len; + for (int i = word_count; --i >= 0; ) + words[i] = 0; + } + + private void setShiftRight(BigInteger x, int count) + { + if (x.words == null) + set(count < 32 ? x.ival >> count : x.ival < 0 ? -1 : 0); + else if (count == 0) + set(x); + else + { + boolean neg = x.isNegative(); + int word_count = count >> 5; + count &= 31; + int d_len = x.ival - word_count; + if (d_len <= 0) + set(neg ? -1 : 0); + else + { + if (words == null || words.length < d_len) + realloc(d_len); + MPN.rshift0 (words, x.words, word_count, d_len, count); + ival = d_len; + if (neg) + words[d_len-1] |= -2 << (31 - count); + } + } + } + + private void setShift(BigInteger x, int count) + { + if (count > 0) + setShiftLeft(x, count); + else + setShiftRight(x, -count); + } + + private static BigInteger shift(BigInteger x, int count) + { + if (x.words == null) + { + if (count <= 0) + return make(count > -32 ? x.ival >> (-count) : x.ival < 0 ? -1 : 0); + if (count < 32) + return make((long) x.ival << count); + } + if (count == 0) + return x; + BigInteger result = new BigInteger(0); + result.setShift(x, count); + return result.canonicalize(); + } + + public BigInteger shiftLeft(int n) + { + return shift(this, n); + } + + public BigInteger shiftRight(int n) + { + return shift(this, -n); + } + + private void format(int radix, StringBuffer buffer) + { + if (words == null) + buffer.append(Integer.toString(ival, radix)); + else if (ival <= 2) + buffer.append(Long.toString(longValue(), radix)); + else + { + boolean neg = isNegative(); + int[] work; + if (neg || radix != 16) + { + work = new int[ival]; + getAbsolute(work); + } + else + work = words; + int len = ival; + + int buf_size = len * (MPN.chars_per_word(radix) + 1); + if (radix == 16) + { + if (neg) + buffer.append('-'); + int buf_start = buffer.length(); + for (int i = len; --i >= 0; ) + { + int word = work[i]; + for (int j = 8; --j >= 0; ) + { + int hex_digit = (word >> (4 * j)) & 0xF; + // Suppress leading zeros: + if (hex_digit > 0 || buffer.length() > buf_start) + buffer.append(Character.forDigit(hex_digit, 16)); + } + } + } + else + { + int i = buffer.length(); + for (;;) + { + int digit = MPN.divmod_1(work, work, len, radix); + buffer.append(Character.forDigit(digit, radix)); + while (len > 0 && work[len-1] == 0) len--; + if (len == 0) + break; + } + if (neg) + buffer.append('-'); + /* Reverse buffer. */ + int j = buffer.length() - 1; + while (i < j) + { + char tmp = buffer.charAt(i); + buffer.setCharAt(i, buffer.charAt(j)); + buffer.setCharAt(j, tmp); + i++; j--; + } + } + } + } + + public String toString() + { return toString(10); } - public native byte[] toByteArray(); + public String toString(int radix) + { + if (words == null) + return Integer.toString(ival, radix); + else if (ival <= 2) + return Long.toString(longValue(), radix); + int buf_size = ival * (MPN.chars_per_word(radix) + 1); + StringBuffer buffer = new StringBuffer(buf_size); + format(radix, buffer); + return buffer.toString(); + } + + public int intValue() + { + if (words == null) + return ival; + return words[0]; + } + + public long longValue() + { + if (words == null) + return ival; + if (ival == 1) + return words[0]; + return ((long)words[1] << 32) + ((long)words[0] & 0xffffffffL); + } + + public int hashCode() + { + // FIXME: May not match hashcode of JDK. + return words == null ? ival : (words[0] + words[ival - 1]); + } + + /* Assumes x and y are both canonicalized. */ + private static boolean equals(BigInteger x, BigInteger y) + { + if (x.words == null && y.words == null) + return x.ival == y.ival; + if (x.words == null || y.words == null || x.ival != y.ival) + return false; + for (int i = x.ival; --i >= 0; ) + { + if (x.words[i] != y.words[i]) + return false; + } + return true; + } + + /* Assumes this and obj are both canonicalized. */ + public boolean equals(Object obj) + { + if (obj == null || ! (obj instanceof BigInteger)) + return false; + return BigInteger.equals(this, (BigInteger) obj); + } + + private static BigInteger valueOf(String s, int radix) + throws NumberFormatException + { + int len = s.length(); + // Testing (len < MPN.chars_per_word(radix)) would be more accurate, + // but slightly more expensive, for little practical gain. + if (len <= 15 && radix <= 16) + return BigInteger.make(Long.parseLong(s, radix)); + + int byte_len = 0; + byte[] bytes = new byte[len]; + boolean negative = false; + for (int i = 0; i < len; i++) + { + char ch = s.charAt(i); + if (ch == '-') + negative = true; + else if (ch == '_' || (byte_len == 0 && (ch == ' ' || ch == '\t'))) + continue; + else + { + int digit = Character.digit(ch, radix); + if (digit < 0) + break; + bytes[byte_len++] = (byte) digit; + } + } + return valueOf(bytes, byte_len, negative, radix); + } + + private static BigInteger valueOf(byte[] digits, int byte_len, + boolean negative, int radix) + { + int chars_per_word = MPN.chars_per_word(radix); + int[] words = new int[byte_len / chars_per_word + 1]; + int size = MPN.set_str(words, digits, byte_len, radix); + if (size == 0) + return ZERO; + if (words[size-1] < 0) + words[size++] = 0; + if (negative) + negate(words, words, size); + return make(words, size); + } + + public double doubleValue() + { + if (words == null) + return (double) ival; + if (ival <= 2) + return (double) longValue(); + if (isNegative()) + return BigInteger.neg(this).roundToDouble(0, true, false); + else + return roundToDouble(0, false, false); + } + + public float floatValue() + { + return (float) doubleValue(); + } + + /** Return true if any of the lowest n bits are one. + * (false if n is negative). */ + private boolean checkBits(int n) + { + if (n <= 0) + return false; + if (words == null) + return n > 31 || ((ival & ((1 << n) - 1)) != 0); + int i; + for (i = 0; i < (n >> 5) ; i++) + if (words[i] != 0) + return true; + return (n & 31) != 0 && (words[i] & ((1 << (n & 31)) - 1)) != 0; + } + + /** Convert a semi-processed BigInteger to double. + * Number must be non-negative. Multiplies by a power of two, applies sign, + * and converts to double, with the usual java rounding. + * @param exp power of two, positive or negative, by which to multiply + * @param neg true if negative + * @param remainder true if the BigInteger is the result of a truncating + * division that had non-zero remainder. To ensure proper rounding in + * this case, the BigInteger must have at least 54 bits. */ + private double roundToDouble(int exp, boolean neg, boolean remainder) + { + // Compute length. + int il = bitLength(); + + // Exponent when normalized to have decimal point directly after + // leading one. This is stored excess 1023 in the exponent bit field. + exp += il - 1; + + // Gross underflow. If exp == -1075, we let the rounding + // computation determine whether it is minval or 0 (which are just + // 0x0000 0000 0000 0001 and 0x0000 0000 0000 0000 as bit + // patterns). + if (exp < -1075) + return neg ? -0.0 : 0.0; + + // gross overflow + if (exp > 1023) + return neg ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; + + // number of bits in mantissa, including the leading one. + // 53 unless it's denormalized + int ml = (exp >= -1022 ? 53 : 53 + exp + 1022); + + // Get top ml + 1 bits. The extra one is for rounding. + long m; + int excess_bits = il - (ml + 1); + if (excess_bits > 0) + m = ((words == null) ? ival >> excess_bits + : MPN.rshift_long(words, ival, excess_bits)); + else + m = longValue() << (- excess_bits); + + // Special rounding for maxval. If the number exceeds maxval by + // any amount, even if it's less than half a step, it overflows. + if (exp == 1023 && ((m >> 1) == (1L << 53) - 1)) + { + if (remainder || checkBits(il - ml)) + return neg ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; + else + return neg ? - Double.MAX_VALUE : Double.MAX_VALUE; + } + + // Normal round-to-even rule: round up if the bit dropped is a one, and + // the bit above it or any of the bits below it is a one. + if ((m & 1) == 1 + && ((m & 2) == 2 || remainder || checkBits(excess_bits))) + { + m += 2; + // Check if we overflowed the mantissa + if ((m & (1L << 54)) != 0) + { + exp++; + // renormalize + m >>= 1; + } + // Check if a denormalized mantissa was just rounded up to a + // normalized one. + else if (ml == 52 && (m & (1L << 53)) != 0) + exp++; + } + + // Discard the rounding bit + m >>= 1; + + long bits_sign = neg ? (1L << 63) : 0; + exp += 1023; + long bits_exp = (exp <= 0) ? 0 : ((long)exp) << 52; + long bits_mant = m & ~(1L << 52); + return Double.longBitsToDouble(bits_sign | bits_exp | bits_mant); + } + + /** Copy the abolute value of this into an array of words. + * Assumes words.length >= (this.words == null ? 1 : this.ival). + * Result is zero-extended, but need not be a valid 2's complement number. + */ + + private void getAbsolute(int[] words) + { + int len; + if (this.words == null) + { + len = 1; + words[0] = this.ival; + } + else + { + len = this.ival; + for (int i = len; --i >= 0; ) + words[i] = this.words[i]; + } + if (words[len - 1] < 0) + negate(words, words, len); + for (int i = words.length; --i > len; ) + words[i] = 0; + } - protected void finalize() throws Throwable { - nativeFinalize(); - super.finalize(); + /** Set dest[0:len-1] to the negation of src[0:len-1]. + * Return true if overflow (i.e. if src is -2**(32*len-1)). + * Ok for src==dest. */ + private static boolean negate(int[] dest, int[] src, int len) + { + long carry = 1; + boolean negative = src[len-1] < 0; + for (int i = 0; i < len; i++) + { + carry += ((long) (~src[i]) & 0xffffffffL); + dest[i] = (int) carry; + carry >>= 32; + } + return (negative && dest[len-1] < 0); } - native void nativeFinalize(); + /** Destructively set this to the negative of x. + * It is OK if x==this.*/ + private void setNegative(BigInteger x) + { + int len = x.ival; + if (x.words == null) + { + if (len == Integer.MIN_VALUE) + set(- (long) len); + else + set(-len); + return; + } + realloc(len + 1); + if (BigInteger.negate(words, x.words, len)) + words[len++] = 0; + ival = len; + } - static public void main(String args[]) { - BigInteger i = new BigInteger(-549755813888L); - BigInteger i2 = new BigInteger ("5"); - BigInteger i3 = new BigInteger ("7"); - byte[] foo = new byte[2]; - foo[0] = 0; - foo[1] = 0; -// BigInteger i4 = new BigInteger(-1, foo); -// System.out.println(i4); - // BigInteger i5 = new BigInteger(20, new Random(5)); + /** Destructively negate this. */ + private final void setNegative() + { + setNegative(this); + } - BigInteger i4 = new BigInteger(-300L); - System.out.println (i4); - byte[] bar = i4.toByteArray(); - for (int z = 0; z < bar.length; z++) - System.out.println(z + ": " + bar[z]); + private static BigInteger abs(BigInteger x) + { + return x.isNegative() ? neg(x) : x; + } - BigInteger i5 = new BigInteger(bar); - System.out.println (i5); + public BigInteger abs() + { + return abs(this); + } - // System.out.println(i5); - // i.modPow(i2, i3).print(); - // System.out.println(i.toString()); + private static BigInteger neg(BigInteger x) + { + if (x.words == null && x.ival != Integer.MIN_VALUE) + return make(- x.ival); + BigInteger result = new BigInteger(0); + result.setNegative(x); + return result.canonicalize(); + } - // i3 = i.modInverse(i2); - // i3.print(); - // System.out.println(i.isProbablePrime(50)); + public BigInteger negate() + { + return BigInteger.neg(this); + } - java.math.BigInteger bi = new java.math.BigInteger("11"); - java.math.BigInteger bi2 = new java.math.BigInteger("-8"); - java.math.BigInteger bi3 = new java.math.BigInteger("7"); -// System.out.println(bi.isProbablePrime(50)); + /** Calculates ceiling(log2(this < 0 ? -this : this+1)) + * See Common Lisp: the Language, 2nd ed, p. 361. + */ + public int bitLength() + { + if (words == null) + return MPN.intLength(ival); + else + return MPN.intLength(words, ival); + } + public byte[] toByteArray() + { + // Determine number of bytes needed. The method bitlength returns + // the size without the sign bit, so add one bit for that and then + // add 7 more to emulate the ceil function using integer math. + byte[] bytes = new byte[(bitLength() + 1 + 7) / 8]; + int nbytes = bytes.length; + + int wptr = 0; + int word; + + // Deal with words array until one word or less is left to process. + // If BigInteger is an int, then it is in ival and nbytes will be <= 4. + while (nbytes > 4) + { + word = words[wptr++]; + for (int i = 4; i > 0; --i, word >>= 8) + bytes[--nbytes] = (byte) word; + } -// BigInteger i = new BigInteger("3"); -// BigInteger i2 = new BigInteger ("4"); -// BigInteger i3 = new BigInteger ("7"); -// // i.print(); -// i.modPow(i2, i3).print(); + // Deal with the last few bytes. If BigInteger is an int, use ival. + word = (words == null) ? ival : words[wptr]; + for ( ; nbytes > 0; word >>= 8) + bytes[--nbytes] = (byte) word; -// java.math.BigInteger bi = new java.math.BigInteger("3"); -// java.math.BigInteger bi2 = new java.math.BigInteger("4"); -// java.math.BigInteger bi3 = new java.math.BigInteger("7"); -// System.out.println(bi.modPow(bi2, bi3)); + return bytes; + } + + /** Return the boolean opcode (for bitOp) for swapped operands. + * I.e. bitOp(swappedOp(op), x, y) == bitOp(op, y, x). + */ + private static int swappedOp(int op) + { + return + "\000\001\004\005\002\003\006\007\010\011\014\015\012\013\016\017" + .charAt(op); + } + + /** Do one the the 16 possible bit-wise operations of two BigIntegers. */ + private static BigInteger bitOp(int op, BigInteger x, BigInteger y) + { + switch (op) + { + case 0: return ZERO; + case 1: return x.and(y); + case 3: return x; + case 5: return y; + case 15: return make(-1); + } + BigInteger result = new BigInteger(); + setBitOp(result, op, x, y); + return result.canonicalize(); + } + + /** Do one the the 16 possible bit-wise operations of two BigIntegers. */ + private static void setBitOp(BigInteger result, int op, + BigInteger x, BigInteger y) + { + if (y.words == null) ; + else if (x.words == null || x.ival < y.ival) + { + BigInteger temp = x; x = y; y = temp; + op = swappedOp(op); + } + int xi; + int yi; + int xlen, ylen; + if (y.words == null) + { + yi = y.ival; + ylen = 1; + } + else + { + yi = y.words[0]; + ylen = y.ival; + } + if (x.words == null) + { + xi = x.ival; + xlen = 1; + } + else + { + xi = x.words[0]; + xlen = x.ival; + } + if (xlen > 1) + result.realloc(xlen); + int[] w = result.words; + int i = 0; + // Code for how to handle the remainder of x. + // 0: Truncate to length of y. + // 1: Copy rest of x. + // 2: Invert rest of x. + int finish = 0; + int ni; + switch (op) + { + case 0: // clr + ni = 0; + break; + case 1: // and + for (;;) + { + ni = xi & yi; + if (i+1 >= ylen) break; + w[i++] = ni; xi = x.words[i]; yi = y.words[i]; + } + if (yi < 0) finish = 1; + break; + case 2: // andc2 + for (;;) + { + ni = xi & ~yi; + if (i+1 >= ylen) break; + w[i++] = ni; xi = x.words[i]; yi = y.words[i]; + } + if (yi >= 0) finish = 1; + break; + case 3: // copy x + ni = xi; + finish = 1; // Copy rest + break; + case 4: // andc1 + for (;;) + { + ni = ~xi & yi; + if (i+1 >= ylen) break; + w[i++] = ni; xi = x.words[i]; yi = y.words[i]; + } + if (yi < 0) finish = 2; + break; + case 5: // copy y + for (;;) + { + ni = yi; + if (i+1 >= ylen) break; + w[i++] = ni; xi = x.words[i]; yi = y.words[i]; + } + break; + case 6: // xor + for (;;) + { + ni = xi ^ yi; + if (i+1 >= ylen) break; + w[i++] = ni; xi = x.words[i]; yi = y.words[i]; + } + finish = yi < 0 ? 2 : 1; + break; + case 7: // ior + for (;;) + { + ni = xi | yi; + if (i+1 >= ylen) break; + w[i++] = ni; xi = x.words[i]; yi = y.words[i]; + } + if (yi >= 0) finish = 1; + break; + case 8: // nor + for (;;) + { + ni = ~(xi | yi); + if (i+1 >= ylen) break; + w[i++] = ni; xi = x.words[i]; yi = y.words[i]; + } + if (yi >= 0) finish = 2; + break; + case 9: // eqv [exclusive nor] + for (;;) + { + ni = ~(xi ^ yi); + if (i+1 >= ylen) break; + w[i++] = ni; xi = x.words[i]; yi = y.words[i]; + } + finish = yi >= 0 ? 2 : 1; + break; + case 10: // c2 + for (;;) + { + ni = ~yi; + if (i+1 >= ylen) break; + w[i++] = ni; xi = x.words[i]; yi = y.words[i]; + } + break; + case 11: // orc2 + for (;;) + { + ni = xi | ~yi; + if (i+1 >= ylen) break; + w[i++] = ni; xi = x.words[i]; yi = y.words[i]; + } + if (yi < 0) finish = 1; + break; + case 12: // c1 + ni = ~xi; + finish = 2; + break; + case 13: // orc1 + for (;;) + { + ni = ~xi | yi; + if (i+1 >= ylen) break; + w[i++] = ni; xi = x.words[i]; yi = y.words[i]; + } + if (yi >= 0) finish = 2; + break; + case 14: // nand + for (;;) + { + ni = ~(xi & yi); + if (i+1 >= ylen) break; + w[i++] = ni; xi = x.words[i]; yi = y.words[i]; + } + if (yi < 0) finish = 2; + break; + default: + case 15: // set + ni = -1; + break; + } + // Here i==ylen-1; w[0]..w[i-1] have the correct result; + // and ni contains the correct result for w[i+1]. + if (i+1 == xlen) + finish = 0; + switch (finish) + { + case 0: + if (i == 0 && w == null) + { + result.ival = ni; + return; + } + w[i++] = ni; + break; + case 1: w[i] = ni; while (++i < xlen) w[i] = x.words[i]; break; + case 2: w[i] = ni; while (++i < xlen) w[i] = ~x.words[i]; break; + } + result.ival = i; + } + + /** Return the logical (bit-wise) "and" of a BigInteger and an int. */ + private static BigInteger and(BigInteger x, int y) + { + if (x.words == null) + return BigInteger.make(x.ival & y); + if (y >= 0) + return BigInteger.make(x.words[0] & y); + int len = x.ival; + int[] words = new int[len]; + words[0] = x.words[0] & y; + while (--len > 0) + words[len] = x.words[len]; + return BigInteger.make(words, x.ival); + } + + /** Return the logical (bit-wise) "and" of two BigIntegers. */ + public BigInteger and(BigInteger y) + { + if (y.words == null) + return and(this, y.ival); + else if (words == null) + return and(y, ival); + + BigInteger x = this; + if (ival < y.ival) + { + BigInteger temp = this; x = y; y = temp; + } + int i; + int len = y.isNegative() ? x.ival : y.ival; + int[] words = new int[len]; + for (i = 0; i < y.ival; i++) + words[i] = x.words[i] & y.words[i]; + for ( ; i < len; i++) + words[i] = x.words[i]; + return BigInteger.make(words, len); + } + + /** Return the logical (bit-wise) "(inclusive) or" of two BigIntegers. */ + public BigInteger or(BigInteger y) + { + return bitOp(7, this, y); + } + + /** Return the logical (bit-wise) "exclusive or" of two BigIntegers. */ + public BigInteger xor(BigInteger y) + { + return bitOp(6, this, y); + } + + /** Return the logical (bit-wise) negation of a BigInteger. */ + public BigInteger not() + { + return bitOp(12, this, ZERO); + } + + public BigInteger andNot(BigInteger val) + { + return and(val.not()); + } + + public BigInteger clearBit(int n) + { + if (n < 0) + throw new ArithmeticException(); + + return and(ONE.shiftLeft(n).not()); + } + + public BigInteger setBit(int n) + { + if (n < 0) + throw new ArithmeticException(); + + return or(ONE.shiftLeft(n)); + } + + public boolean testBit(int n) + { + if (n < 0) + throw new ArithmeticException(); + + return !and(ONE.shiftLeft(n)).isZero(); + } + + public BigInteger flipBit(int n) + { + if (n < 0) + throw new ArithmeticException(); + + return xor(ONE.shiftLeft(n)); + } + + public int getLowestSetBit() + { + if (isZero()) + return -1; + + if (words == null) + return MPN.findLowestBit(ival); + else + return MPN.findLowestBit(words); + } + + // bit4count[I] is number of '1' bits in I. + private static final byte[] bit4_count = { 0, 1, 1, 2, 1, 2, 2, 3, + 1, 2, 2, 3, 2, 3, 3, 4}; + + private static int bitCount(int i) + { + int count = 0; + while (i != 0) + { + count += bit4_count[i & 15]; + i >>>= 4; + } + return count; + } + + private static int bitCount(int[] x, int len) + { + int count = 0; + while (--len >= 0) + count += bitCount(x[len]); + return count; + } + + /** Count one bits in a BigInteger. + * If argument is negative, count zero bits instead. */ + public int bitCount() + { + int i, x_len; + int[] x_words = words; + if (x_words == null) + { + x_len = 1; + i = bitCount(ival); + } + else + { + x_len = ival; + i = bitCount(x_words, x_len); + } + return isNegative() ? x_len * 32 - i : i; + } + + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException + { + s.defaultReadObject(); + words = byteArrayToIntArray(magnitude, signum < 0 ? -1 : 0); + BigInteger result = make(words, words.length); + this.ival = result.ival; + this.words = result.words; + } + + private void writeObject(ObjectOutputStream s) + throws IOException, ClassNotFoundException + { + signum = signum(); + magnitude = toByteArray(); + s.defaultWriteObject(); } } diff --git a/native/Makefile.am b/native/Makefile.am index a459aefb5..ff51ecc9d 100644 --- a/native/Makefile.am +++ b/native/Makefile.am @@ -1,10 +1,10 @@ ## Input file for automake to generate the Makefile.in used by configure if CREATE_JNI_LIBRARIES -SUBDIRS = jni lib vmi +SUBDIRS = fdlibm jni else if CREATE_CNI_LIBRARIES -SUBDIRS = cni +SUBDIRS = fdlibm cni else SUBDIRS = endif diff --git a/native/jni/awt/.cvsignore b/native/cni/.cvsignore index e9f2658a6..e9f2658a6 100644 --- a/native/jni/awt/.cvsignore +++ b/native/cni/.cvsignore diff --git a/native/cni/Makefile.am b/native/cni/Makefile.am new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/native/cni/Makefile.am diff --git a/native/lib/.cvsignore b/native/fdlibm/.cvsignore index e9f2658a6..e9f2658a6 100644 --- a/native/lib/.cvsignore +++ b/native/fdlibm/.cvsignore diff --git a/native/jni/dtoa.c b/native/fdlibm/dtoa.c index 9a398b43d..9a398b43d 100644 --- a/native/jni/dtoa.c +++ b/native/fdlibm/dtoa.c diff --git a/native/jni/acos.c b/native/fdlibm/e_acos.c index 315f90358..ee6b168a1 100644 --- a/native/jni/acos.c +++ b/native/fdlibm/e_acos.c @@ -1,25 +1,25 @@ -/* @(#)e_acos.c 1.3 95/01/18 */ +/* @(#)e_acos.c 5.1 93/09/24 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * - * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice + * software is freely granted, provided that this notice * is preserved. * ==================================================== */ /* __ieee754_acos(x) - * Method : + * Method : * acos(x) = pi/2 - asin(x) * acos(-x) = pi/2 + asin(x) * For |x|<=0.5 * acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c) * For x>0.5 * acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2))) - * = 2asin(sqrt((1-x)/2)) + * = 2asin(sqrt((1-x)/2)) * = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z) * = 2f + (2c + 2s*z*R(z)) * where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term @@ -37,7 +37,13 @@ #include "fdlibm.h" -static const jdouble +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double +#else +static double +#endif one= 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */ pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ @@ -53,46 +59,53 @@ qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ -JNIEXPORT jdouble JNICALL Java_java_lang_Math_acos -(JNIEnv *env, jclass clazz, jdouble x) +#ifdef __STDC__ + double __ieee754_acos(double x) +#else + double __ieee754_acos(x) + double x; +#endif { - jdouble z,p,q,r,w,s,c,df; - jint hx,ix; - - hx = __HI(x); - ix = hx&0x7fffffff; - if(ix>=0x3ff00000) { /* |x| >= 1 */ - if(((ix-0x3ff00000)|__LO(x))==0) { /* |x|==1 */ - if(hx>0) return 0.0; /* acos(1) = 0 */ - else return pi+2.0*pio2_lo; /* acos(-1)= pi */ - } - return (x-x)/(x-x); /* acos(|x|>1) is NaN */ - } - if(ix<0x3fe00000) { /* |x| < 0.5 */ - if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/ - z = x*x; - p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); - q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); - r = p/q; - return pio2_hi - (x - (pio2_lo-x*r)); - } else if (hx<0) { /* x < -0.5 */ - z = (one+x)*0.5; - p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); - q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); - s = sqrt(z); - r = p/q; - w = r*s-pio2_lo; - return pi - 2.0*(s+w); - } else { /* x > 0.5 */ - z = (one-x)*0.5; - s = sqrt(z); - df = s; - __LO(df) = 0; - c = (z-df*df)/(s+df); - p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); - q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); - r = p/q; - w = r*s+c; - return 2.0*(df+w); - } + double z,p,q,r,w,s,c,df; + int32_t hx,ix; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x3ff00000) { /* |x| >= 1 */ + uint32_t lx; + GET_LOW_WORD(lx,x); + if(((ix-0x3ff00000)|lx)==0) { /* |x|==1 */ + if(hx>0) return 0.0; /* acos(1) = 0 */ + else return pi+2.0*pio2_lo; /* acos(-1)= pi */ + } + return (x-x)/(x-x); /* acos(|x|>1) is NaN */ + } + if(ix<0x3fe00000) { /* |x| < 0.5 */ + if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/ + z = x*x; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + r = p/q; + return pio2_hi - (x - (pio2_lo-x*r)); + } else if (hx<0) { /* x < -0.5 */ + z = (one+x)*0.5; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + s = __ieee754_sqrt(z); + r = p/q; + w = r*s-pio2_lo; + return pi - 2.0*(s+w); + } else { /* x > 0.5 */ + z = (one-x)*0.5; + s = __ieee754_sqrt(z); + df = s; + SET_LOW_WORD(df,0); + c = (z-df*df)/(s+df); + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + r = p/q; + w = r*s+c; + return 2.0*(df+w); + } } + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/jni/asin.c b/native/fdlibm/e_asin.c index 6fe107265..6b131e65a 100644 --- a/native/jni/asin.c +++ b/native/fdlibm/e_asin.c @@ -1,10 +1,10 @@ -/* @(#)e_asin.c 1.3 95/01/18 */ +/* @(#)e_asin.c 5.1 93/09/24 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * - * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. @@ -44,7 +44,13 @@ #include "fdlibm.h" -static const jdouble +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double +#else +static double +#endif one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ huge = 1.000e+300, pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ @@ -62,46 +68,53 @@ qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ -JNIEXPORT jdouble JNICALL Java_java_lang_Math_asin -(JNIEnv *env, jclass clazz, jdouble x) +#ifdef __STDC__ + double __ieee754_asin(double x) +#else + double __ieee754_asin(x) + double x; +#endif { - jdouble t,w,p,q,c,r,s; - jint hx,ix; - - hx = __HI(x); - ix = hx&0x7fffffff; - if(ix>= 0x3ff00000) { /* |x|>= 1 */ - if(((ix-0x3ff00000)|__LO(x))==0) - /* asin(1)=+-pi/2 with inexact */ - return x*pio2_hi+x*pio2_lo; - return (x-x)/(x-x); /* asin(|x|>1) is NaN */ - } else if (ix<0x3fe00000) { /* |x|<0.5 */ - if(ix<0x3e400000) { /* if |x| < 2**-27 */ - if(huge+x>one) return x;/* return x with inexact if x!=0*/ - } else - t = x*x; - p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); - q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); - w = p/q; - return x+x*w; - } - /* 1> |x|>= 0.5 */ - w = one-fabs(x); - t = w*0.5; - p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); - q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); - s = sqrt(t); - if(ix>=0x3FEF3333) { /* if |x| > 0.975 */ - w = p/q; - t = pio2_hi-(2.0*(s+s*w)-pio2_lo); - } else { - w = s; - __LO(w) = 0; - c = (t-w*w)/(s+w); - r = p/q; - p = 2.0*s*r-(pio2_lo-2.0*c); - q = pio4_hi-2.0*w; - t = pio4_hi-(p-q); - } - if (hx>0) return t; else return -t; + double t,w,p,q,c,r,s; + int32_t hx,ix; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>= 0x3ff00000) { /* |x|>= 1 */ + uint32_t lx; + GET_LOW_WORD(lx,x); + if(((ix-0x3ff00000)|lx)==0) + /* asin(1)=+-pi/2 with inexact */ + return x*pio2_hi+x*pio2_lo; + return (x-x)/(x-x); /* asin(|x|>1) is NaN */ + } else if (ix<0x3fe00000) { /* |x|<0.5 */ + if(ix<0x3e400000) { /* if |x| < 2**-27 */ + if(huge+x>one) return x;/* return x with inexact if x!=0*/ + } else + t = x*x; + p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); + q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); + w = p/q; + return x+x*w; + } + /* 1> |x|>= 0.5 */ + w = one-fabs(x); + t = w*0.5; + p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); + q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); + s = __ieee754_sqrt(t); + if(ix>=0x3FEF3333) { /* if |x| > 0.975 */ + w = p/q; + t = pio2_hi-(2.0*(s+s*w)-pio2_lo); + } else { + w = s; + SET_LOW_WORD(w,0); + c = (t-w*w)/(s+w); + r = p/q; + p = 2.0*s*r-(pio2_lo-2.0*c); + q = pio4_hi-2.0*w; + t = pio4_hi-(p-q); + } + if(hx>0) return t; else return -t; } + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/fdlibm/e_atan2.c b/native/fdlibm/e_atan2.c new file mode 100644 index 000000000..c75448db2 --- /dev/null +++ b/native/fdlibm/e_atan2.c @@ -0,0 +1,131 @@ + +/* @(#)e_atan2.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_atan2(y,x) + * Method : + * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x). + * 2. Reduce x to positive by (if x and y are unexceptional): + * ARG (x+iy) = arctan(y/x) ... if x > 0, + * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0, + * + * Special cases: + * + * ATAN2((anything), NaN ) is NaN; + * ATAN2(NAN , (anything) ) is NaN; + * ATAN2(+-0, +(anything but NaN)) is +-0 ; + * ATAN2(+-0, -(anything but NaN)) is +-pi ; + * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2; + * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ; + * ATAN2(+-(anything but INF and NaN), -INF) is +-pi; + * ATAN2(+-INF,+INF ) is +-pi/4 ; + * ATAN2(+-INF,-INF ) is +-3pi/4; + * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2; + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double +#else +static double +#endif +tiny = 1.0e-300, +zero = 0.0, +pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */ +pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */ +pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */ +pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ + +#ifdef __STDC__ + double __ieee754_atan2(double y, double x) +#else + double __ieee754_atan2(y,x) + double y,x; +#endif +{ + double z; + int32_t k,m,hx,hy,ix,iy; + uint32_t lx,ly; + + EXTRACT_WORDS(hx,lx,x); + ix = hx&0x7fffffff; + EXTRACT_WORDS(hy,ly,y); + iy = hy&0x7fffffff; + if(((ix|((lx|-lx)>>31))>0x7ff00000)|| + ((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */ + return x+y; + if(((hx-0x3ff00000)|lx)==0) return atan(y); /* x=1.0 */ + m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ + + /* when y = 0 */ + if((iy|ly)==0) { + switch(m) { + case 0: + case 1: return y; /* atan(+-0,+anything)=+-0 */ + case 2: return pi+tiny;/* atan(+0,-anything) = pi */ + case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */ + } + } + /* when x = 0 */ + if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; + + /* when x is INF */ + if(ix==0x7ff00000) { + if(iy==0x7ff00000) { + switch(m) { + case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */ + case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */ + case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/ + case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/ + } + } else { + switch(m) { + case 0: return zero ; /* atan(+...,+INF) */ + case 1: return -zero ; /* atan(-...,+INF) */ + case 2: return pi+tiny ; /* atan(+...,-INF) */ + case 3: return -pi-tiny ; /* atan(-...,-INF) */ + } + } + } + /* when y is INF */ + if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; + + /* compute y/x */ + k = (iy-ix)>>20; + if(k > 60) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**60 */ + else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */ + else z=atan(fabs(y/x)); /* safe to do y/x */ + switch (m) { + case 0: return z ; /* atan(+,+) */ + case 1: { + uint32_t zh; + GET_HIGH_WORD(zh,z); + SET_HIGH_WORD(z,zh ^ 0x80000000); + } + return z ; /* atan(-,+) */ + case 2: return pi-(z-pi_lo);/* atan(+,-) */ + default: /* case 3 */ + return (z-pi_lo)-pi;/* atan(-,-) */ + } +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/jni/exp.c b/native/fdlibm/e_exp.c index f9bbdddd1..e11ca8b38 100644 --- a/native/jni/exp.c +++ b/native/fdlibm/e_exp.c @@ -1,12 +1,12 @@ -/* @(#)e_exp.c 1.3 95/01/18 */ +/* @(#)e_exp.c 5.1 93/09/24 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * - * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice + * software is freely granted, provided that this notice * is preserved. * ==================================================== */ @@ -19,36 +19,36 @@ * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658. * Given x, find r and integer k such that * - * x = k*ln2 + r, |r| <= 0.5*ln2. + * x = k*ln2 + r, |r| <= 0.5*ln2. * - * Here r will be represented as r = hi-lo for better + * Here r will be represented as r = hi-lo for better * accuracy. * * 2. Approximation of exp(r) by a special rational function on * the interval [0,0.34658]: * Write * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ... - * We use a special Reme algorithm on [0,0.34658] to generate - * a polynomial of degree 5 to approximate R. The maximum error + * We use a special Reme algorithm on [0,0.34658] to generate + * a polynomial of degree 5 to approximate R. The maximum error * of this polynomial approximation is bounded by 2**-59. In * other words, * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5 * (where z=r*r, and the values of P1 to P5 are listed below) * and * | 5 | -59 - * | 2.0+P1*z+...+P5*z - R(z) | <= 2 + * | 2.0+P1*z+...+P5*z - R(z) | <= 2 * | | * The computation of exp(r) thus becomes * 2*r * exp(r) = 1 + ------- * R - r - * r*R1(r) + * r*R1(r) * = 1 + r + ----------- (for better accuracy) * 2 - R1(r) * where * 2 4 10 * R1(r) = r - (P1*r + P2*r + ... + P5*r ). - * + * * 3. Scale back to obtain exp(x): * From step 1, we have * exp(x) = 2^k * exp(r) @@ -63,20 +63,26 @@ * 1 ulp (unit in the last place). * * Misc. info. - * For IEEE double + * For IEEE double * if x > 7.09782712893383973096e+02 then exp(x) overflow * if x < -7.45133219101941108420e+02 then exp(x) underflow * * Constants: - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the * compiler will convert from decimal to binary accurately enough * to produce the hexadecimal values shown. */ #include "fdlibm.h" -static const jdouble +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double +#else +static double +#endif one = 1.0, halF[2] = {0.5,-0.5,}, huge = 1.0e+300, @@ -94,55 +100,68 @@ P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ -JNIEXPORT jdouble JNICALL Java_java_lang_Math_exp -(JNIEnv *env, jclass clazz, jdouble x) /* default IEEE jdouble exp */ + +#ifdef __STDC__ + double __ieee754_exp(double x) /* default IEEE double exp */ +#else + double __ieee754_exp(x) /* default IEEE double exp */ + double x; +#endif { - jdouble y,hi,lo,c,t; - jint k,xsb; - unsigned hx; + double y,hi,lo,c,t; + int32_t k,xsb; + uint32_t hx; - hx = __HI(x); /* high word of x */ - xsb = (hx>>31)&1; /* sign bit of x */ - hx &= 0x7fffffff; /* high word of |x| */ + GET_HIGH_WORD(hx,x); + xsb = (hx>>31)&1; /* sign bit of x */ + hx &= 0x7fffffff; /* high word of |x| */ - /* filter out non-finite argument */ - if(hx >= 0x40862E42) { /* if |x|>=709.78... */ - if(hx>=0x7ff00000) { - if(((hx&0xfffff)|__LO(x))!=0) - return x+x; /* NaN */ - else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */ - } - if(x > o_threshold) return huge*huge; /* overflow */ - if(x < u_threshold) return twom1000*twom1000; /* underflow */ - } + /* filter out non-finite argument */ + if(hx >= 0x40862E42) { /* if |x|>=709.78... */ + if(hx>=0x7ff00000) { + uint32_t lx; + GET_LOW_WORD(lx,x); + if(((hx&0xfffff)|lx)!=0) + return x+x; /* NaN */ + else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */ + } + if(x > o_threshold) return huge*huge; /* overflow */ + if(x < u_threshold) return twom1000*twom1000; /* underflow */ + } - /* argument reduction */ - if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ - if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ - hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb; - } else { - k = invln2*x+halF[xsb]; - t = k; - hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */ - lo = t*ln2LO[0]; - } - x = hi - lo; - } - else if(hx < 0x3e300000) { /* when |x|<2**-28 */ - if(huge+x>one) return one+x;/* trigger inexact */ - } - else k = 0; + /* argument reduction */ + if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ + if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ + hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb; + } else { + k = invln2*x+halF[xsb]; + t = k; + hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */ + lo = t*ln2LO[0]; + } + x = hi - lo; + } + else if(hx < 0x3e300000) { /* when |x|<2**-28 */ + if(huge+x>one) return one+x;/* trigger inexact */ + } + else k = 0; - /* x is now in primary range */ - t = x*x; - c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); - if(k==0) return one-((x*c)/(c-2.0)-x); - else y = one-((lo-(x*c)/(2.0-c))-hi); - if(k >= -1021) { - __HI(y) += (k<<20); /* add k to y's exponent */ - return y; - } else { - __HI(y) += ((k+1000)<<20);/* add k to y's exponent */ - return y*twom1000; - } + /* x is now in primary range */ + t = x*x; + c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + if(k==0) return one-((x*c)/(c-2.0)-x); + else y = one-((lo-(x*c)/(2.0-c))-hi); + if(k >= -1021) { + uint32_t hy; + GET_HIGH_WORD(hy,y); + SET_HIGH_WORD(y,hy+(k<<20)); /* add k to y's exponent */ + return y; + } else { + uint32_t hy; + GET_HIGH_WORD(hy,y); + SET_HIGH_WORD(y,hy+((k+1000)<<20)); /* add k to y's exponent */ + return y*twom1000; + } } + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/fdlibm/e_fmod.c b/native/fdlibm/e_fmod.c new file mode 100644 index 000000000..1cf099076 --- /dev/null +++ b/native/fdlibm/e_fmod.c @@ -0,0 +1,140 @@ + +/* @(#)e_fmod.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * __ieee754_fmod(x,y) + * Return x mod y in exact arithmetic + * Method: shift and subtract + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double one = 1.0, Zero[] = {0.0, -0.0,}; +#else +static double one = 1.0, Zero[] = {0.0, -0.0,}; +#endif + +#ifdef __STDC__ + double __ieee754_fmod(double x, double y) +#else + double __ieee754_fmod(x,y) + double x,y ; +#endif +{ + int32_t n,hx,hy,hz,ix,iy,sx,i; + uint32_t lx,ly,lz; + + EXTRACT_WORDS(hx,lx,x); + EXTRACT_WORDS(hy,ly,y); + sx = hx&0x80000000; /* sign of x */ + hx ^=sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ + + /* purge off exception values */ + if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */ + ((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */ + return (x*y)/(x*y); + if(hx<=hy) { + if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */ + if(lx==ly) + return Zero[(uint32_t)sx>>31]; /* |x|=|y| return x*0*/ + } + + /* determine ix = ilogb(x) */ + if(hx<0x00100000) { /* subnormal x */ + if(hx==0) { + for (ix = -1043, i=lx; i>0; i<<=1) ix -=1; + } else { + for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1; + } + } else ix = (hx>>20)-1023; + + /* determine iy = ilogb(y) */ + if(hy<0x00100000) { /* subnormal y */ + if(hy==0) { + for (iy = -1043, i=ly; i>0; i<<=1) iy -=1; + } else { + for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1; + } + } else iy = (hy>>20)-1023; + + /* set up {hx,lx}, {hy,ly} and align y to x */ + if(ix >= -1022) + hx = 0x00100000|(0x000fffff&hx); + else { /* subnormal x, shift x to normal */ + n = -1022-ix; + if(n<=31) { + hx = (hx<<n)|(lx>>(32-n)); + lx <<= n; + } else { + hx = lx<<(n-32); + lx = 0; + } + } + if(iy >= -1022) + hy = 0x00100000|(0x000fffff&hy); + else { /* subnormal y, shift y to normal */ + n = -1022-iy; + if(n<=31) { + hy = (hy<<n)|(ly>>(32-n)); + ly <<= n; + } else { + hy = ly<<(n-32); + ly = 0; + } + } + + /* fix point fmod */ + n = ix - iy; + while(n--) { + hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1; + if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;} + else { + if((hz|lz)==0) /* return sign(x)*0 */ + return Zero[(uint32_t)sx>>31]; + hx = hz+hz+(lz>>31); lx = lz+lz; + } + } + hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1; + if(hz>=0) {hx=hz;lx=lz;} + + /* convert back to floating value and restore the sign */ + if((hx|lx)==0) /* return sign(x)*0 */ + return Zero[(uint32_t)sx>>31]; + while(hx<0x00100000) { /* normalize x */ + hx = hx+hx+(lx>>31); lx = lx+lx; + iy -= 1; + } + if(iy>= -1022) { /* normalize output */ + hx = ((hx-0x00100000)|((iy+1023)<<20)); + INSERT_WORDS(x,hx|sx,lx); + } else { /* subnormal output */ + n = -1022 - iy; + if(n<=20) { + lx = (lx>>n)|((uint32_t)hx<<(32-n)); + hx >>= n; + } else if (n<=31) { + lx = (hx<<(32-n))|(lx>>n); hx = sx; + } else { + lx = hx>>(n-32); hx = sx; + } + INSERT_WORDS(x,hx|sx,lx); + x *= one; /* create necessary signal */ + } + return x; /* exact output */ +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/jni/log.c b/native/fdlibm/e_log.c index 572d81365..093473e10 100644 --- a/native/jni/log.c +++ b/native/fdlibm/e_log.c @@ -1,12 +1,12 @@ -/* @(#)e_log.c 1.3 95/01/18 */ +/* @(#)e_log.c 5.1 93/09/24 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * - * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice + * software is freely granted, provided that this notice * is preserved. * ==================================================== */ @@ -14,17 +14,17 @@ /* __ieee754_log(x) * Return the logrithm of x * - * Method : - * 1. Argument Reduction: find k and f such that - * x = 2^k * (1+f), + * Method : + * 1. Argument Reduction: find k and f such that + * x = 2^k * (1+f), * where sqrt(2)/2 < 1+f < sqrt(2) . * * 2. Approximation of log(1+f). * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) * = 2s + 2/3 s**3 + 2/5 s**5 + ....., * = 2s + s*R - * We use a special Reme algorithm on [0,0.1716] to generate - * a polynomial of degree 14 to approximate R The maximum error + * We use a special Reme algorithm on [0,0.1716] to generate + * a polynomial of degree 14 to approximate R The maximum error * of this polynomial approximation is bounded by 2**-58.45. In * other words, * 2 4 6 8 10 12 14 @@ -32,22 +32,22 @@ * (the values of Lg1 to Lg7 are listed in the program) * and * | 2 14 | -58.45 - * | Lg1*s +...+Lg7*s - R(z) | <= 2 + * | Lg1*s +...+Lg7*s - R(z) | <= 2 * | | * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. * In order to guarantee error in log below 1ulp, we compute log * by * log(1+f) = f - s*(f - R) (if f is not too large) * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy) - * - * 3. Finally, log(x) = k*ln2 + log(1+f). + * + * 3. Finally, log(x) = k*ln2 + log(1+f). * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) - * Here ln2 is split into two floating point number: + * Here ln2 is split into two floating point number: * ln2_hi + ln2_lo, * where n*ln2_hi is always exact for |n| < 2000. * * Special cases: - * log(x) is NaN with signal if x < 0 (including -INF) ; + * log(x) is NaN with signal if x < 0 (including -INF) ; * log(+INF) is +INF; log(0) is -INF with signal; * log(NaN) is that NaN with no signal. * @@ -56,15 +56,21 @@ * 1 ulp (unit in the last place). * * Constants: - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the - * compiler will convert from decimal to binary accurately enough + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough * to produce the hexadecimal values shown. */ #include "fdlibm.h" -static const jdouble +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double +#else +static double +#endif ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ @@ -76,56 +82,71 @@ Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ -static jdouble zero = 0.0; +#ifdef __STDC__ +static const double zero = 0.0; +#else +static double zero = 0.0; +#endif -JNIEXPORT jdouble JNICALL Java_java_lang_Math_log -(JNIEnv *env, jclass clazz, jdouble x) +#ifdef __STDC__ + double __ieee754_log(double x) +#else + double __ieee754_log(x) + double x; +#endif { - jdouble hfsq,f,s,z,R,w,t1,t2,dk; - jint k,hx,i,j; - unsigned lx; + double hfsq,f,s,z,R,w,t1,t2,dk; + int32_t k,hx,i,j; + uint32_t lx; - hx = __HI(x); /* high word of x */ - lx = __LO(x); /* low word of x */ + EXTRACT_WORDS(hx,lx,x); - k=0; - if (hx < 0x00100000) { /* x < 2**-1022 */ - if (((hx&0x7fffffff)|lx)==0) - return -two54/zero; /* log(+-0)=-inf */ - if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ - k -= 54; x *= two54; /* subnormal number, scale up x */ - hx = __HI(x); /* high word of x */ - } - if (hx >= 0x7ff00000) return x+x; - k += (hx>>20)-1023; - hx &= 0x000fffff; - i = (hx+0x95f64)&0x100000; - __HI(x) = hx|(i^0x3ff00000); /* normalize x or x/2 */ - k += (i>>20); - f = x-1.0; - if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */ - if(f==zero) if(k==0) return zero; else {dk=(jdouble)k; - return dk*ln2_hi+dk*ln2_lo;} - R = f*f*(0.5-0.33333333333333333*f); - if(k==0) return f-R; else {dk=(jdouble)k; - return dk*ln2_hi-((R-dk*ln2_lo)-f);} - } - s = f/(2.0+f); - dk = (jdouble)k; - z = s*s; - i = hx-0x6147a; - w = z*z; - j = 0x6b851-hx; - t1= w*(Lg2+w*(Lg4+w*Lg6)); - t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); - i |= j; - R = t2+t1; - if(i>0) { - hfsq=0.5*f*f; - if(k==0) return f-(hfsq-s*(hfsq+R)); else - return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f); - } else { - if(k==0) return f-s*(f-R); else - return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f); - } + k=0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx&0x7fffffff)|lx)==0) + return -two54/zero; /* log(+-0)=-inf */ + if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ + k -= 54; x *= two54; /* subnormal number, scale up x */ + GET_HIGH_WORD(hx,x); + } + if (hx >= 0x7ff00000) return x+x; + k += (hx>>20)-1023; + hx &= 0x000fffff; + i = (hx+0x95f64)&0x100000; + SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */ + k += (i>>20); + f = x-1.0; + if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */ + if(f==zero) { + if(k==0) + return zero; + else { + dk=(double)k; + return dk*ln2_hi+dk*ln2_lo; + } + } + R = f*f*(0.5-0.33333333333333333*f); + if(k==0) return f-R; else {dk=(double)k; + return dk*ln2_hi-((R-dk*ln2_lo)-f);} + } + s = f/(2.0+f); + dk = (double)k; + z = s*s; + i = hx-0x6147a; + w = z*z; + j = 0x6b851-hx; + t1= w*(Lg2+w*(Lg4+w*Lg6)); + t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); + i |= j; + R = t2+t1; + if(i>0) { + hfsq=0.5*f*f; + if(k==0) return f-(hfsq-s*(hfsq+R)); else + return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f); + } else { + if(k==0) return f-s*(f-R); else + return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f); + } } + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/fdlibm/e_pow.c b/native/fdlibm/e_pow.c new file mode 100644 index 000000000..e53a8a287 --- /dev/null +++ b/native/fdlibm/e_pow.c @@ -0,0 +1,312 @@ + +/* @(#)e_pow.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_pow(x,y) return x**y + * + * n + * Method: Let x = 2 * (1+f) + * 1. Compute and return log2(x) in two pieces: + * log2(x) = w1 + w2, + * where w1 has 53-24 = 29 bit trailing zeros. + * 2. Perform y*log2(x) = n+y' by simulating muti-precision + * arithmetic, where |y'|<=0.5. + * 3. Return x**y = 2**n*exp(y'*log2) + * + * Special cases: + * 1. (anything) ** 0 is 1 + * 2. (anything) ** 1 is itself + * 3. (anything) ** NAN is NAN + * 4. NAN ** (anything except 0) is NAN + * 5. +-(|x| > 1) ** +INF is +INF + * 6. +-(|x| > 1) ** -INF is +0 + * 7. +-(|x| < 1) ** +INF is +0 + * 8. +-(|x| < 1) ** -INF is +INF + * 9. +-1 ** +-INF is NAN + * 10. +0 ** (+anything except 0, NAN) is +0 + * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 + * 12. +0 ** (-anything except 0, NAN) is +INF + * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF + * 14. -0 ** (odd integer) = -( +0 ** (odd integer) ) + * 15. +INF ** (+anything except 0,NAN) is +INF + * 16. +INF ** (-anything except 0,NAN) is +0 + * 17. -INF ** (anything) = -0 ** (-anything) + * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) + * 19. (-anything except 0 and inf) ** (non-integer) is NAN + * + * Accuracy: + * pow(x,y) returns x**y nearly rounded. In particular + * pow(integer,integer) + * always returns the correct integer provided it is + * representable. + * + * Constants : + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double +#else +static double +#endif +bp[] = {1.0, 1.5,}, +dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */ +dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */ +zero = 0.0, +one = 1.0, +two = 2.0, +two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */ +huge = 1.0e300, +tiny = 1.0e-300, + /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ +L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */ +L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */ +L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */ +L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */ +L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */ +L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */ +lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ +lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */ +lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */ +ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */ +cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */ +cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */ +cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/ +ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ +ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ +ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ + +#ifdef __STDC__ + double __ieee754_pow(double x, double y) +#else + double __ieee754_pow(x,y) + double x, y; +#endif +{ + double z,ax,z_h,z_l,p_h,p_l; + double y1,t1,t2,r,s,t,u,v,w; + int32_t i,j,k,yisint,n; + int32_t hx,hy,ix,iy; + uint32_t lx,ly; + + EXTRACT_WORDS(hx,lx,x); + EXTRACT_WORDS(hy,ly,y); + ix = hx&0x7fffffff; iy = hy&0x7fffffff; + + /* y==zero: x**0 = 1 */ + if((iy|ly)==0) return one; + + /* +-NaN return x+y */ + if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) || + iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0))) + return x+y; + + /* determine if y is an odd int when x < 0 + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + yisint = 0; + if(hx<0) { + if(iy>=0x43400000) yisint = 2; /* even integer y */ + else if(iy>=0x3ff00000) { + k = (iy>>20)-0x3ff; /* exponent */ + if(k>20) { + j = ly>>(52-k); + if((uint32_t)(j<<(52-k))==ly) yisint = 2-(j&1); + } else if(ly==0) { + j = iy>>(20-k); + if((j<<(20-k))==iy) yisint = 2-(j&1); + } + } + } + + /* special value of y */ + if(ly==0) { + if (iy==0x7ff00000) { /* y is +-inf */ + if(((ix-0x3ff00000)|lx)==0) + return y - y; /* inf**+-1 is NaN */ + else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */ + return (hy>=0)? y: zero; + else /* (|x|<1)**-,+inf = inf,0 */ + return (hy<0)?-y: zero; + } + if(iy==0x3ff00000) { /* y is +-1 */ + if(hy<0) return one/x; else return x; + } + if(hy==0x40000000) return x*x; /* y is 2 */ + if(hy==0x3fe00000) { /* y is 0.5 */ + if(hx>=0) /* x >= +0 */ + return __ieee754_sqrt(x); + } + } + + ax = fabs(x); + /* special value of x */ + if(lx==0) { + if(ix==0x7ff00000||ix==0||ix==0x3ff00000){ + z = ax; /*x is +-0,+-inf,+-1*/ + if(hy<0) z = one/z; /* z = (1/|x|) */ + if(hx<0) { + if(((ix-0x3ff00000)|yisint)==0) { + z = (z-z)/(z-z); /* (-1)**non-int is NaN */ + } else if(yisint==1) + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } + return z; + } + } + + /* (x<0)**(non-int) is NaN */ + /* CYGNUS LOCAL: This used to be + if((((hx>>31)+1)|yisint)==0) return (x-x)/(x-x); + but ANSI C says a right shift of a signed negative quantity is + implementation defined. */ + if(((((uint32_t)hx>>31)-1)|yisint)==0) return (x-x)/(x-x); + + /* |y| is huge */ + if(iy>0x41e00000) { /* if |y| > 2**31 */ + if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */ + if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny; + if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny; + } + /* over/underflow if x is not close to one */ + if(ix<0x3fefffff) return (hy<0)? huge*huge:tiny*tiny; + if(ix>0x3ff00000) return (hy>0)? huge*huge:tiny*tiny; + /* now |1-x| is tiny <= 2**-20, suffice to compute + log(x) by x-x^2/2+x^3/3-x^4/4 */ + t = x-1; /* t has 20 trailing zeros */ + w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25)); + u = ivln2_h*t; /* ivln2_h has 21 sig. bits */ + v = t*ivln2_l-w*ivln2; + t1 = u+v; + SET_LOW_WORD(t1,0); + t2 = v-(t1-u); + } else { + double s2,s_h,s_l,t_h,t_l; + n = 0; + /* take care subnormal number */ + if(ix<0x00100000) + {ax *= two53; n -= 53; GET_HIGH_WORD(ix,ax); } + n += ((ix)>>20)-0x3ff; + j = ix&0x000fffff; + /* determine interval */ + ix = j|0x3ff00000; /* normalize ix */ + if(j<=0x3988E) k=0; /* |x|<sqrt(3/2) */ + else if(j<0xBB67A) k=1; /* |x|<sqrt(3) */ + else {k=0;n+=1;ix -= 0x00100000;} + SET_HIGH_WORD(ax,ix); + + /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */ + u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */ + v = one/(ax+bp[k]); + s = u*v; + s_h = s; + SET_LOW_WORD(s_h,0); + /* t_h=ax+bp[k] High */ + t_h = zero; + SET_HIGH_WORD(t_h,((ix>>1)|0x20000000)+0x00080000+(k<<18)); + t_l = ax - (t_h-bp[k]); + s_l = v*((u-s_h*t_h)-s_h*t_l); + /* compute log(ax) */ + s2 = s*s; + r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); + r += s_l*(s_h+s); + s2 = s_h*s_h; + t_h = 3.0+s2+r; + SET_LOW_WORD(t_h,0); + t_l = r-((t_h-3.0)-s2); + /* u+v = s*(1+...) */ + u = s_h*t_h; + v = s_l*t_h+t_l*s; + /* 2/(3log2)*(s+...) */ + p_h = u+v; + SET_LOW_WORD(p_h,0); + p_l = v-(p_h-u); + z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ + z_l = cp_l*p_h+p_l*cp+dp_l[k]; + /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = (double)n; + t1 = (((z_h+z_l)+dp_h[k])+t); + SET_LOW_WORD(t1,0); + t2 = z_l-(((t1-t)-dp_h[k])-z_h); + } + + s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ + if(((((uint32_t)hx>>31)-1)|(yisint-1))==0) + s = -one;/* (-ve)**(odd int) */ + + /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ + y1 = y; + SET_LOW_WORD(y1,0); + p_l = (y-y1)*t1+y*t2; + p_h = y1*t1; + z = p_l+p_h; + EXTRACT_WORDS(j,i,z); + if (j>=0x40900000) { /* z >= 1024 */ + if(((j-0x40900000)|i)!=0) /* if z > 1024 */ + return s*huge*huge; /* overflow */ + else { + if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */ + } + } else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */ + if(((j-0xc090cc00)|i)!=0) /* z < -1075 */ + return s*tiny*tiny; /* underflow */ + else { + if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */ + } + } + /* + * compute 2**(p_h+p_l) + */ + i = j&0x7fffffff; + k = (i>>20)-0x3ff; + n = 0; + if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ + n = j+(0x00100000>>(k+1)); + k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */ + t = zero; + SET_HIGH_WORD(t,n&~(0x000fffff>>k)); + n = ((n&0x000fffff)|0x00100000)>>(20-k); + if(j<0) n = -n; + p_h -= t; + } + t = p_l+p_h; + SET_LOW_WORD(t,0); + u = t*lg2_h; + v = (p_l-(t-p_h))*lg2+t*lg2_l; + z = u+v; + w = v-(z-u); + t = z*z; + t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + r = (z*t1)/(t1-two)-(w+z*w); + z = one-(r-z); + GET_HIGH_WORD(j,z); + j += (n<<20); + if((j>>20)<=0) z = scalbn(z,(int)n); /* subnormal output */ + else SET_HIGH_WORD(z,j); + return s*z; +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/fdlibm/e_rem_pio2.c b/native/fdlibm/e_rem_pio2.c new file mode 100644 index 000000000..6d3fd19a4 --- /dev/null +++ b/native/fdlibm/e_rem_pio2.c @@ -0,0 +1,185 @@ + +/* @(#)e_rem_pio2.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_rem_pio2(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2() + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +/* + * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi + */ +#ifdef __STDC__ +static const int32_t two_over_pi[] = { +#else +static int32_t two_over_pi[] = { +#endif +0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, +0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, +0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, +0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41, +0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, +0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF, +0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, +0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, +0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, +0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, +0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, +}; + +#ifdef __STDC__ +static const int32_t npio2_hw[] = { +#else +static int32_t npio2_hw[] = { +#endif +0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C, +0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C, +0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A, +0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C, +0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB, +0x404858EB, 0x404921FB, +}; + +/* + * invpio2: 53 bits of 2/pi + * pio2_1: first 33 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 33 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 33 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +#ifdef __STDC__ +static const double +#else +static double +#endif +zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ +half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ +two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ +invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ +pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ +pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ +pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ +pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ +pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ +pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ + +#ifdef __STDC__ + int32_t __ieee754_rem_pio2(double x, double *y) +#else + int32_t __ieee754_rem_pio2(x,y) + double x,y[]; +#endif +{ + double z,w,t,r,fn; + double tx[3]; + int32_t i,j,n,ix,hx; + int e0,nx; + uint32_t low; + + GET_HIGH_WORD(hx,x); /* high word of x */ + ix = hx&0x7fffffff; + if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */ + {y[0] = x; y[1] = 0; return 0;} + if(ix<0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */ + if(hx>0) { + z = x - pio2_1; + if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z - pio2_1t; + y[1] = (z-y[0])-pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z -= pio2_2; + y[0] = z - pio2_2t; + y[1] = (z-y[0])-pio2_2t; + } + return 1; + } else { /* negative x */ + z = x + pio2_1; + if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z + pio2_1t; + y[1] = (z-y[0])+pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z += pio2_2; + y[0] = z + pio2_2t; + y[1] = (z-y[0])+pio2_2t; + } + return -1; + } + } + if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */ + t = fabs(x); + n = (int32_t) (t*invpio2+half); + fn = (double)n; + r = t-fn*pio2_1; + w = fn*pio2_1t; /* 1st round good to 85 bit */ + if(n<32&&ix!=npio2_hw[n-1]) { + y[0] = r-w; /* quick check no cancellation */ + } else { + uint32_t high; + j = ix>>20; + y[0] = r-w; + GET_HIGH_WORD(high,y[0]); + i = j-((high>>20)&0x7ff); + if(i>16) { /* 2nd iteration needed, good to 118 */ + t = r; + w = fn*pio2_2; + r = t-w; + w = fn*pio2_2t-((t-r)-w); + y[0] = r-w; + GET_HIGH_WORD(high,y[0]); + i = j-((high>>20)&0x7ff); + if(i>49) { /* 3rd iteration need, 151 bits acc */ + t = r; /* will cover all possible cases */ + w = fn*pio2_3; + r = t-w; + w = fn*pio2_3t-((t-r)-w); + y[0] = r-w; + } + } + } + y[1] = (r-y[0])-w; + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + else return n; + } + /* + * all other (large) arguments + */ + if(ix>=0x7ff00000) { /* x is inf or NaN */ + y[0]=y[1]=x-x; return 0; + } + /* set z = scalbn(|x|,ilogb(x)-23) */ + GET_LOW_WORD(low,x); + SET_LOW_WORD(z,low); + e0 = (int)((ix>>20)-1046); /* e0 = ilogb(z)-23; */ + SET_HIGH_WORD(z, ix - ((int32_t)e0<<20)); + for(i=0;i<2;i++) { + tx[i] = (double)((int32_t)(z)); + z = (z-tx[i])*two24; + } + tx[2] = z; + nx = 3; + while(tx[nx-1]==zero) nx--; /* skip zero term */ + n = __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi); + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + return n; +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/fdlibm/e_remainder.c b/native/fdlibm/e_remainder.c new file mode 100644 index 000000000..4716d8d05 --- /dev/null +++ b/native/fdlibm/e_remainder.c @@ -0,0 +1,80 @@ + +/* @(#)e_remainder.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_remainder(x,p) + * Return : + * returns x REM p = x - [x/p]*p as if in infinite + * precise arithmetic, where [x/p] is the (infinite bit) + * integer nearest x/p (in half way case choose the even one). + * Method : + * Based on fmod() return x-[x/p]chopped*p exactlp. + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double zero = 0.0; +#else +static double zero = 0.0; +#endif + + +#ifdef __STDC__ + double __ieee754_remainder(double x, double p) +#else + double __ieee754_remainder(x,p) + double x,p; +#endif +{ + int32_t hx,hp; + uint32_t sx,lx,lp; + double p_half; + + EXTRACT_WORDS(hx,lx,x); + EXTRACT_WORDS(hp,lp,p); + sx = hx&0x80000000; + hp &= 0x7fffffff; + hx &= 0x7fffffff; + + /* purge off exception values */ + if((hp|lp)==0) return (x*p)/(x*p); /* p = 0 */ + if((hx>=0x7ff00000)|| /* x not finite */ + ((hp>=0x7ff00000)&& /* p is NaN */ + (((hp-0x7ff00000)|lp)!=0))) + return (x*p)/(x*p); + + + if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */ + if (((hx-hp)|(lx-lp))==0) return zero*x; + x = fabs(x); + p = fabs(p); + if (hp<0x00200000) { + if(x+x>p) { + x-=p; + if(x+x>=p) x -= p; + } + } else { + p_half = 0.5*p; + if(x>p_half) { + x-=p; + if(x>=p_half) x -= p; + } + } + GET_HIGH_WORD(hx,x); + SET_HIGH_WORD(x,hx^sx); + return x; +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/fdlibm/e_scalb.c b/native/fdlibm/e_scalb.c new file mode 100644 index 000000000..0bb924b43 --- /dev/null +++ b/native/fdlibm/e_scalb.c @@ -0,0 +1,55 @@ + +/* @(#)e_scalb.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * __ieee754_scalb(x, fn) is provide for + * passing various standard test suite. One + * should use scalbn() instead. + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef _SCALB_INT +#ifdef __STDC__ + double __ieee754_scalb(double x, int fn) +#else + double __ieee754_scalb(x,fn) + double x; int fn; +#endif +#else +#ifdef __STDC__ + double __ieee754_scalb(double x, double fn) +#else + double __ieee754_scalb(x,fn) + double x, fn; +#endif +#endif +{ +#ifdef _SCALB_INT + return scalbn(x,fn); +#else + if (isnan(x)||isnan(fn)) return x*fn; + if (!finite(fn)) { + if(fn>0.0) return x*fn; + else return x/(-fn); + } + if (rint(fn)!=fn) return (fn-fn)/(fn-fn); + if ( fn > 65000.0) return scalbn(x, 65000); + if (-fn > 65000.0) return scalbn(x,-65000); + return scalbn(x,(int)fn); +#endif +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/jni/sqrt.c b/native/fdlibm/e_sqrt.c index d48013c9f..1d566a084 100644 --- a/native/jni/sqrt.c +++ b/native/fdlibm/e_sqrt.c @@ -1,11 +1,12 @@ -/* @(#)e_sqrt.c 1.3 95/01/18 */ + +/* @(#)e_sqrt.c 5.1 93/09/24 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * - * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice + * software is freely granted, provided that this notice * is preserved. * ==================================================== */ @@ -15,10 +16,10 @@ * ------------------------------------------ * | Use the hardware sqrt if you have one | * ------------------------------------------ - * Method: - * Bit by bit method using integer arithmetic. (Slow, but portable) + * Method: + * Bit by bit method using integer arithmetic. (Slow, but portable) * 1. Normalization - * Scale x to y in [1,4) with even powers of 2: + * Scale x to y in [1,4) with even powers of 2: * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then * sqrt(x) = 2^k * sqrt(y) * 2. Bit by bit computation @@ -27,9 +28,9 @@ * i+1 2 * s = 2*q , and y = 2 * ( y - q ). (1) * i i i i - * - * To compute q from q , one checks whether - * i+1 i + * + * To compute q from q , one checks whether + * i+1 i * * -(i+1) 2 * (q + 2 ) <= y. (2) @@ -39,12 +40,12 @@ * i+1 i i+1 i * * With some algebric manipulation, it is not difficult to see - * that (2) is equivalent to + * that (2) is equivalent to * -(i+1) * s + 2 <= y (3) * i i * - * The advantage of (3) is that s and y can be computed by + * The advantage of (3) is that s and y can be computed by * i i * the following recurrence formula: * if (3) is false @@ -56,10 +57,10 @@ * -i -(i+1) * s = s + 2 , y = y - s - 2 (5) * i+1 i i+1 i i - * - * One may easily use induction to prove (4) and (5). + * + * One may easily use induction to prove (4) and (5). * Note. Since the left hand side of (3) contain only i+2 bits, - * it does not necessary to do a full (53-bit) comparison + * it does not necessary to do a full (53-bit) comparison * in (3). * 3. Final rounding * After generating the 53 bits result, we compute one more bit. @@ -69,7 +70,7 @@ * The rounding mode can be detected by checking whether * huge + tiny is equal to huge, and whether huge - tiny is * equal to huge for some floating point number "huge" and "tiny". - * + * * Special cases: * sqrt(+-0) = +-0 ... exact * sqrt(inf) = inf @@ -82,122 +83,132 @@ #include "fdlibm.h" -static const jdouble one = 1.0, tiny = 1.0e-300; +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double one = 1.0, tiny=1.0e-300; +#else +static double one = 1.0, tiny=1.0e-300; +#endif -JNIEXPORT jdouble JNICALL Java_java_lang_Math_sqrt -(JNIEnv *env, jclass clazz, jdouble x) +#ifdef __STDC__ + double __ieee754_sqrt(double x) +#else + double __ieee754_sqrt(x) + double x; +#endif { - jdouble z; - int sign = (int)0x80000000; - unsigned r,t1,s1,ix1,q1; - int ix0,s0,q,m,t,i; - - ix0 = __HI(x); /* high word of x */ - ix1 = __LO(x); /* low word of x */ - - /* take care of Inf and NaN */ - if((ix0&0x7ff00000)==0x7ff00000) { - return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf - sqrt(-inf)=sNaN */ - } - /* take care of zero */ - if(ix0<=0) { - if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */ - else if(ix0<0) - return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ - } - /* normalize x */ - m = (ix0>>20); - if(m==0) { /* subnormal x */ - while(ix0==0) { - m -= 21; - ix0 |= (ix1>>11); ix1 <<= 21; - } - for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1; - m -= i-1; - ix0 |= (ix1>>(32-i)); - ix1 <<= i; - } - m -= 1023; /* unbias exponent */ - ix0 = (ix0&0x000fffff)|0x00100000; - if(m&1){ /* odd m, double x to make it even */ - ix0 += ix0 + ((ix1&sign)>>31); - ix1 += ix1; - } - m >>= 1; /* m = [m/2] */ - - /* generate sqrt(x) bit by bit */ - ix0 += ix0 + ((ix1&sign)>>31); - ix1 += ix1; - q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */ - r = 0x00200000; /* r = moving bit from right to left */ - - while(r!=0) { - t = s0+r; - if(t<=ix0) { - s0 = t+r; - ix0 -= t; - q += r; - } - ix0 += ix0 + ((ix1&sign)>>31); - ix1 += ix1; - r>>=1; - } - - r = sign; - while(r!=0) { - t1 = s1+r; - t = s0; - if((t<ix0)||((t==ix0)&&(t1<=ix1))) { - s1 = t1+r; - if(((t1&sign)==sign)&&(s1&sign)==0) s0 += 1; - ix0 -= t; - if (ix1 < t1) ix0 -= 1; - ix1 -= t1; - q1 += r; - } - ix0 += ix0 + ((ix1&sign)>>31); - ix1 += ix1; - r>>=1; - } - - /* use floating add to find out rounding direction */ - if((ix0|ix1)!=0) { - z = one-tiny; /* trigger inexact flag */ - if (z>=one) { - z = one+tiny; - if (q1==(unsigned)0xffffffff) { q1=0; q += 1;} - else if (z>one) { - if (q1==(unsigned)0xfffffffe) q+=1; - q1+=2; - } else - q1 += (q1&1); - } - } - ix0 = (q>>1)+0x3fe00000; - ix1 = q1>>1; - if ((q&1)==1) ix1 |= sign; - ix0 += (m <<20); - __HI(z) = ix0; - __LO(z) = ix1; - return z; + double z; + int32_t sign = (int)0x80000000; + uint32_t r,t1,s1,ix1,q1; + int32_t ix0,s0,q,m,t,i; + + EXTRACT_WORDS(ix0,ix1,x); + + /* take care of Inf and NaN */ + if((ix0&0x7ff00000)==0x7ff00000) { + return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf + sqrt(-inf)=sNaN */ + } + /* take care of zero */ + if(ix0<=0) { + if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */ + else if(ix0<0) + return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ + } + /* normalize x */ + m = (ix0>>20); + if(m==0) { /* subnormal x */ + while(ix0==0) { + m -= 21; + ix0 |= (ix1>>11); ix1 <<= 21; + } + for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1; + m -= i-1; + ix0 |= (ix1>>(32-i)); + ix1 <<= i; + } + m -= 1023; /* unbias exponent */ + ix0 = (ix0&0x000fffff)|0x00100000; + if(m&1){ /* odd m, double x to make it even */ + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + } + m >>= 1; /* m = [m/2] */ + + /* generate sqrt(x) bit by bit */ + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */ + r = 0x00200000; /* r = moving bit from right to left */ + + while(r!=0) { + t = s0+r; + if(t<=ix0) { + s0 = t+r; + ix0 -= t; + q += r; + } + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + r>>=1; + } + + r = sign; + while(r!=0) { + t1 = s1+r; + t = s0; + if((t<ix0)||((t==ix0)&&(t1<=ix1))) { + s1 = t1+r; + if(((t1&sign)==(uint32_t)sign)&&(s1&sign)==0) s0 += 1; + ix0 -= t; + if (ix1 < t1) ix0 -= 1; + ix1 -= t1; + q1 += r; + } + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + r>>=1; + } + + /* use floating add to find out rounding direction */ + if((ix0|ix1)!=0) { + z = one-tiny; /* trigger inexact flag */ + if (z>=one) { + z = one+tiny; + if (q1==(uint32_t)0xffffffff) { q1=0; q += 1;} + else if (z>one) { + if (q1==(uint32_t)0xfffffffe) q+=1; + q1+=2; + } else + q1 += (q1&1); + } + } + ix0 = (q>>1)+0x3fe00000; + ix1 = q1>>1; + if ((q&1)==1) ix1 |= sign; + ix0 += (m <<20); + INSERT_WORDS(z,ix0,ix1); + return z; } +#endif /* defined(_DOUBLE_IS_32BITS) */ + /* Other methods (use floating-point arithmetic) ------------- -(This is a copy of a drafted paper by Prof W. Kahan +(This is a copy of a drafted paper by Prof W. Kahan and K.C. Ng, written in May, 1986) - Two algorithms are given here to implement sqrt(x) + Two algorithms are given here to implement sqrt(x) (IEEE double precision arithmetic) in software. Both supply sqrt(x) correctly rounded. The first algorithm (in Section A) uses newton iterations and involves four divisions. The second one uses reciproot iterations to avoid division, but requires more multiplications. Both algorithms need the ability - to chop results of arithmetic operations instead of round them, + to chop results of arithmetic operations instead of round them, and the INEXACT flag to indicate when an arithmetic operation - is executed exactly with no roundoff error, all part of the + is executed exactly with no roundoff error, all part of the standard (IEEE 754-1985). The ability to perform shift, add, subtract and logical AND operations upon 32-bit words is needed too, though not part of the standard. @@ -207,7 +218,7 @@ A. sqrt(x) by Newton Iteration (1) Initial approximation Let x0 and x1 be the leading and the trailing 32-bit words of - a floating point number x (in IEEE double format) respectively + a floating point number x (in IEEE double format) respectively 1 11 52 ...widths ------------------------------------------------------ @@ -215,7 +226,7 @@ A. sqrt(x) by Newton Iteration ------------------------------------------------------ msb lsb msb lsb ...order - + ------------------------ ------------------------ x0: |s| e | f1 | x1: | f2 | ------------------------ ------------------------ @@ -240,7 +251,7 @@ A. sqrt(x) by Newton Iteration (2) Iterative refinement - Apply Heron's rule three times to y, we have y approximates + Apply Heron's rule three times to y, we have y approximates sqrt(x) to within 1 ulp (Unit in the Last Place): y := (y+x/y)/2 ... almost 17 sig. bits @@ -265,12 +276,12 @@ A. sqrt(x) by Newton Iteration it requires more multiplications and additions. Also x must be scaled in advance to avoid spurious overflow in evaluating the expression 3y*y+x. Hence it is not recommended uless division - is slow. If division is very slow, then one should use the + is slow. If division is very slow, then one should use the reciproot algorithm given in section B. (3) Final adjustment - By twiddling y's last bit it is possible to force y to be + By twiddling y's last bit it is possible to force y to be correctly rounded according to the prevailing rounding mode as follows. Let r and i be copies of the rounding mode and inexact flag before entering the square root program. Also we @@ -301,7 +312,7 @@ A. sqrt(x) by Newton Iteration I := i; ... restore inexact flag R := r; ... restore rounded mode return sqrt(x):=y. - + (4) Special cases Square root of +inf, +-0, or NaN is itself; @@ -320,7 +331,7 @@ B. sqrt(x) by Reciproot Iteration k := 0x5fe80000 - (x0>>1); y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits - Here k is a 32-bit integer and T2[] is an integer array + Here k is a 32-bit integer and T2[] is an integer array containing correction terms. Now magically the floating value of y (y's leading 32-bit word is y0, the value of its trailing word y1 is set to zero) approximates 1/sqrt(x) @@ -341,9 +352,9 @@ B. sqrt(x) by Reciproot Iteration Apply Reciproot iteration three times to y and multiply the result by x to get an approximation z that matches sqrt(x) - to about 1 ulp. To be exact, we will have + to about 1 ulp. To be exact, we will have -1ulp < sqrt(x)-z<1.0625ulp. - + ... set rounding mode to Round-to-nearest y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x) y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x) @@ -352,14 +363,14 @@ B. sqrt(x) by Reciproot Iteration z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x) Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that - (a) the term z*y in the final iteration is always less than 1; + (a) the term z*y in the final iteration is always less than 1; (b) the error in the final result is biased upward so that -1 ulp < sqrt(x) - z < 1.0625 ulp instead of |sqrt(x)-z|<1.03125ulp. (3) Final adjustment - By twiddling y's last bit it is possible to force y to be + By twiddling y's last bit it is possible to force y to be correctly rounded according to the prevailing rounding mode as follows. Let r and i be copies of the rounding mode and inexact flag before entering the square root program. Also we @@ -399,27 +410,27 @@ B. sqrt(x) by Reciproot Iteration I := 1; ... Raise Inexact flag: z is not exact else { j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2 - k := z1 >> 26; ... get z's 25-th and 26-th + k := z1 >> 26; ... get z's 25-th and 26-th fraction bits I := i or (k&j) or ((k&(j+j+1))!=(x1&3)); } R:= r ... restore rounded mode return sqrt(x):=z. - If multiplication is cheaper then the foregoing red tape, the + If multiplication is cheaper then the foregoing red tape, the Inexact flag can be evaluated by I := i; I := (z*z!=x) or I. - Note that z*z can overwrite I; this value must be sensed if it is + Note that z*z can overwrite I; this value must be sensed if it is True. Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be zero. -------------------- - z1: | f2 | + z1: | f2 | -------------------- bit 31 bit 0 @@ -436,7 +447,6 @@ B. sqrt(x) by Reciproot Iteration 11 01 even ------------------------------------------------- - (4) Special cases (see (4) of Section A). - + (4) Special cases (see (4) of Section A). + */ - diff --git a/native/fdlibm/fdlibm.h b/native/fdlibm/fdlibm.h new file mode 100644 index 000000000..f50afb983 --- /dev/null +++ b/native/fdlibm/fdlibm.h @@ -0,0 +1,349 @@ + +/* @(#)fdlibm.h 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993, 2000 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#ifndef __CLASSPATH_FDLIBM_H__ +#define __CLASSPATH_FDLIBM_H__ + +#include <config.h> +#include <stdlib.h> + +/* CYGNUS LOCAL: Include files. */ +#include "ieeefp.h" + +#include "mprec.h" + +/* CYGNUS LOCAL: Default to XOPEN_MODE. */ +#define _XOPEN_MODE + +#ifdef __P +#undef __P +#endif + +#ifdef __STDC__ +#define __P(p) p +#else +#define __P(p) () +#endif + +#ifndef HUGE +#define HUGE ((float)3.40282346638528860e+38) +#endif + +/* + * set X_TLOSS = pi*2**52, which is possibly defined in <values.h> + * (one may replace the following line by "#include <values.h>") + */ + +#define X_TLOSS 1.41484755040568800000e+16 + +/* These typedefs are true for the targets running Java. */ + +#define _IEEE_LIBM + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * ANSI/POSIX + */ +extern double acos __P((double)); +extern double asin __P((double)); +extern double atan __P((double)); +extern double atan2 __P((double, double)); +extern double cos __P((double)); +extern double sin __P((double)); +extern double tan __P((double)); + +extern double cosh __P((double)); +extern double sinh __P((double)); +extern double tanh __P((double)); + +extern double exp __P((double)); +extern double frexp __P((double, int *)); +extern double ldexp __P((double, int)); +extern double log __P((double)); +extern double log10 __P((double)); +extern double modf __P((double, double *)); + +extern double pow __P((double, double)); +extern double sqrt __P((double)); + +extern double ceil __P((double)); +extern double fabs __P((double)); +extern double floor __P((double)); +extern double fmod __P((double, double)); + +extern double erf __P((double)); +extern double erfc __P((double)); +extern double gamma __P((double)); +extern double hypot __P((double, double)); +extern int isnan __P((double)); +extern int finite __P((double)); +extern double j0 __P((double)); +extern double j1 __P((double)); +extern double jn __P((int, double)); +extern double lgamma __P((double)); +extern double y0 __P((double)); +extern double y1 __P((double)); +extern double yn __P((int, double)); + +extern double acosh __P((double)); +extern double asinh __P((double)); +extern double atanh __P((double)); +extern double cbrt __P((double)); +extern double logb __P((double)); +extern double nextafter __P((double, double)); +extern double remainder __P((double, double)); + +/* Functions that are not documented, and are not in <math.h>. */ + +extern double logb __P((double)); +#ifdef _SCALB_INT +extern double scalb __P((double, int)); +#else +extern double scalb __P((double, double)); +#endif +extern double significand __P((double)); + +/* ieee style elementary functions */ +extern double __ieee754_sqrt __P((double)); +extern double __ieee754_acos __P((double)); +extern double __ieee754_acosh __P((double)); +extern double __ieee754_log __P((double)); +extern double __ieee754_atanh __P((double)); +extern double __ieee754_asin __P((double)); +extern double __ieee754_atan2 __P((double,double)); +extern double __ieee754_exp __P((double)); +extern double __ieee754_cosh __P((double)); +extern double __ieee754_fmod __P((double,double)); +extern double __ieee754_pow __P((double,double)); +extern double __ieee754_lgamma_r __P((double,int *)); +extern double __ieee754_gamma_r __P((double,int *)); +extern double __ieee754_log10 __P((double)); +extern double __ieee754_sinh __P((double)); +extern double __ieee754_hypot __P((double,double)); +extern double __ieee754_j0 __P((double)); +extern double __ieee754_j1 __P((double)); +extern double __ieee754_y0 __P((double)); +extern double __ieee754_y1 __P((double)); +extern double __ieee754_jn __P((int,double)); +extern double __ieee754_yn __P((int,double)); +extern double __ieee754_remainder __P((double,double)); +extern int32_t __ieee754_rem_pio2 __P((double,double*)); +#ifdef _SCALB_INT +extern double __ieee754_scalb __P((double,int)); +#else +extern double __ieee754_scalb __P((double,double)); +#endif + +/* fdlibm kernel function */ +extern double __kernel_standard __P((double,double,int)); +extern double __kernel_sin __P((double,double,int)); +extern double __kernel_cos __P((double,double)); +extern double __kernel_tan __P((double,double,int)); +extern int __kernel_rem_pio2 __P((double*,double*,int,int,int,const int32_t*)); + +/* Undocumented float functions. */ +extern float logbf __P((float)); +#ifdef _SCALB_INT +extern float scalbf __P((float, int)); +#else +extern float scalbf __P((float, float)); +#endif +extern float significandf __P((float)); + +/* + * Functions callable from C, intended to support IEEE arithmetic. + */ +extern double copysign __P((double, double)); +extern int ilogb __P((double)); +extern double rint __P((double)); +extern float rintf __P((float)); +extern double scalbn __P((double, int)); + +/* ieee style elementary float functions */ +extern float __ieee754_sqrtf __P((float)); +extern float __ieee754_acosf __P((float)); +extern float __ieee754_acoshf __P((float)); +extern float __ieee754_logf __P((float)); +extern float __ieee754_atanhf __P((float)); +extern float __ieee754_asinf __P((float)); +extern float __ieee754_atan2f __P((float,float)); +extern float __ieee754_expf __P((float)); +extern float __ieee754_coshf __P((float)); +extern float __ieee754_fmodf __P((float,float)); +extern float __ieee754_powf __P((float,float)); +extern float __ieee754_lgammaf_r __P((float,int *)); +extern float __ieee754_gammaf_r __P((float,int *)); +extern float __ieee754_log10f __P((float)); +extern float __ieee754_sinhf __P((float)); +extern float __ieee754_hypotf __P((float,float)); +extern float __ieee754_j0f __P((float)); +extern float __ieee754_j1f __P((float)); +extern float __ieee754_y0f __P((float)); +extern float __ieee754_y1f __P((float)); +extern float __ieee754_jnf __P((int,float)); +extern float __ieee754_ynf __P((int,float)); +extern float __ieee754_remainderf __P((float,float)); +extern int32_t __ieee754_rem_pio2f __P((float,float*)); +#ifdef _SCALB_INT +extern float __ieee754_scalbf __P((float,int)); +#else +extern float __ieee754_scalbf __P((float,float)); +#endif + +/* float versions of fdlibm kernel functions */ +extern float __kernel_sinf __P((float,float,int)); +extern float __kernel_cosf __P((float,float)); +extern float __kernel_tanf __P((float,float,int)); +extern int __kernel_rem_pio2f __P((float*,float*,int,int,int,const int32_t*)); + +/* The original code used statements like + n0 = ((*(int*)&one)>>29)^1; * index of high word * + ix0 = *(n0+(int*)&x); * high word of x * + ix1 = *((1-n0)+(int*)&x); * low word of x * + to dig two 32 bit words out of the 64 bit IEEE floating point + value. That is non-ANSI, and, moreover, the gcc instruction + scheduler gets it wrong. We instead use the following macros. + Unlike the original code, we determine the endianness at compile + time, not at run time; I don't see much benefit to selecting + endianness at run time. */ + +#ifndef __IEEE_BIG_ENDIAN +#ifndef __IEEE_LITTLE_ENDIAN + #error Must define endianness +#endif +#endif + +/* A union which permits us to convert between a double and two 32 bit + ints. */ + +#ifdef __IEEE_BIG_ENDIAN + +typedef union +{ + double value; + struct + { + uint32_t msw; + uint32_t lsw; + } parts; +} ieee_double_shape_type; + +#endif + +#ifdef __IEEE_LITTLE_ENDIAN + +typedef union +{ + double value; + struct + { + uint32_t lsw; + uint32_t msw; + } parts; +} ieee_double_shape_type; + +#endif + +/* Get two 32 bit ints from a double. */ + +#define EXTRACT_WORDS(ix0,ix1,d) \ +do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +/* Get the more significant 32 bit int from a double. */ + +#define GET_HIGH_WORD(i,d) \ +do { \ + ieee_double_shape_type gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} while (0) + +/* Get the less significant 32 bit int from a double. */ + +#define GET_LOW_WORD(i,d) \ +do { \ + ieee_double_shape_type gl_u; \ + gl_u.value = (d); \ + (i) = gl_u.parts.lsw; \ +} while (0) + +/* Set a double from two 32 bit ints. */ + +#define INSERT_WORDS(d,ix0,ix1) \ +do { \ + ieee_double_shape_type iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} while (0) + +/* Set the more significant 32 bits of a double from an int. */ + +#define SET_HIGH_WORD(d,v) \ +do { \ + ieee_double_shape_type sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} while (0) + +/* Set the less significant 32 bits of a double from an int. */ + +#define SET_LOW_WORD(d,v) \ +do { \ + ieee_double_shape_type sl_u; \ + sl_u.value = (d); \ + sl_u.parts.lsw = (v); \ + (d) = sl_u.value; \ +} while (0) + +/* A union which permits us to convert between a float and a 32 bit + int. */ + +typedef union +{ + float value; + uint32_t word; +} ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define GET_FLOAT_WORD(i,d) \ +do { \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} while (0) + +/* Set a float from a 32 bit int. */ + +#define SET_FLOAT_WORD(d,i) \ +do { \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} while (0) + +#ifdef __cplusplus +} +#endif + +#endif /* __CLASSPATH_FDLIBM_H__ */ diff --git a/native/jni/ieeefp.h b/native/fdlibm/ieeefp.h index de1f7c6b8..821089aba 100644 --- a/native/jni/ieeefp.h +++ b/native/fdlibm/ieeefp.h @@ -1,3 +1,6 @@ +#ifndef __CLASSPATH_IEEEFP_H__ +#define __CLASSPATH_IEEEFP_H__ + #ifndef __IEEE_BIG_ENDIAN #ifndef __IEEE_LITTLE_ENDIAN @@ -132,3 +135,4 @@ #endif /* not __IEEE_LITTLE_ENDIAN */ #endif /* not __IEEE_BIG_ENDIAN */ +#endif /* __CLASSPATH_IEEEFP_H__ */ diff --git a/native/jni/java-assert.h b/native/fdlibm/java-assert.h index 6f178bd9e..6f178bd9e 100644 --- a/native/jni/java-assert.h +++ b/native/fdlibm/java-assert.h diff --git a/native/jni/k_cos.c b/native/fdlibm/k_cos.c index 4483b4d42..acf50a82e 100644 --- a/native/jni/k_cos.c +++ b/native/fdlibm/k_cos.c @@ -1,12 +1,12 @@ -/* @(#)k_cos.c 1.3 95/01/18 */ +/* @(#)k_cos.c 5.1 93/09/24 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * - * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice + * software is freely granted, provided that this notice * is preserved. * ==================================================== */ @@ -15,7 +15,7 @@ * __kernel_cos( x, y ) * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 * Input x is assumed to be bounded by ~pi/4 in magnitude. - * Input y is the tail of x. + * Input y is the tail of x. * * Algorithm * 1. Since cos(-x) = cos(x), we need only to consider positive x. @@ -25,15 +25,15 @@ * 4 14 * cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x * where the remez error is - * + * * | 2 4 6 8 10 12 14 | -58 * |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2 - * | | - * - * 4 6 8 10 12 14 + * | | + * + * 4 6 8 10 12 14 * 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then * cos(x) = 1 - x*x/2 + r - * since cos(x+y) ~ cos(x) - sin(x)*y + * since cos(x+y) ~ cos(x) - sin(x)*y * ~ cos(x) - x*y, * a correction term is necessary in cos(x) and hence * cos(x+y) = 1 - (x*x/2 - (r - x*y)) @@ -48,7 +48,13 @@ #include "fdlibm.h" -static const jdouble +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double +#else +static double +#endif one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */ C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */ @@ -57,34 +63,34 @@ C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */ C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */ C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */ -jdouble -__kernel_cos (jdouble x, jdouble y) +#ifdef __STDC__ + double __kernel_cos(double x, double y) +#else + double __kernel_cos(x, y) + double x,y; +#endif { - jdouble a,hz,z,r,qx; - jint ix; - - ix = __HI(x)&0x7fffffff; /* ix = |x|'s high word*/ - if (ix<0x3e400000) - { /* if x < 2**27 */ - if (((jint)x)==0) return one; /* generate inexact */ - } - z = x*x; - r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6))))); - if (ix < 0x3FD33333) /* if |x| < 0.3 */ - return one - (0.5*z - (z*r - x*y)); - else - { - if(ix > 0x3fe90000) /* x > 0.78125 */ - { - qx = 0.28125; - } - else - { - __HI(qx) = ix-0x00200000; /* x/4 */ - __LO(qx) = 0; + double a,hz,z,r,qx; + int32_t ix; + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; /* ix = |x|'s high word*/ + if(ix<0x3e400000) { /* if x < 2**27 */ + if(((int)x)==0) return one; /* generate inexact */ + } + z = x*x; + r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6))))); + if(ix < 0x3FD33333) /* if |x| < 0.3 */ + return one - (0.5*z - (z*r - x*y)); + else { + if(ix > 0x3fe90000) { /* x > 0.78125 */ + qx = 0.28125; + } else { + INSERT_WORDS(qx,ix-0x00200000,0); /* x/4 */ + } + hz = 0.5*z-qx; + a = one-qx; + return a - (hz - (z*r-x*y)); } - hz = 0.5*z-qx; - a = one-qx; - return a - (hz - (z*r-x*y)); - } } + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/fdlibm/k_rem_pio2.c b/native/fdlibm/k_rem_pio2.c new file mode 100644 index 000000000..2f4ca1725 --- /dev/null +++ b/native/fdlibm/k_rem_pio2.c @@ -0,0 +1,320 @@ + +/* @(#)k_rem_pio2.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2) + * double x[],y[]; int e0,nx,prec; int ipio2[]; + * + * __kernel_rem_pio2 return the last three digits of N with + * y = x - N*pi/2 + * so that |y| < pi/2. + * + * The method is to compute the integer (mod 8) and fraction parts of + * (2/pi)*x without doing the full multiplication. In general we + * skip the part of the product that are known to be a huge integer ( + * more accurately, = 0 mod 8 ). Thus the number of operations are + * independent of the exponent of the input. + * + * (2/pi) is represented by an array of 24-bit integers in ipio2[]. + * + * Input parameters: + * x[] The input value (must be positive) is broken into nx + * pieces of 24-bit integers in double precision format. + * x[i] will be the i-th 24 bit of x. The scaled exponent + * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0 + * match x's up to 24 bits. + * + * Example of breaking a double positive z into x[0]+x[1]+x[2]: + * e0 = ilogb(z)-23 + * z = scalbn(z,-e0) + * for i = 0,1,2 + * x[i] = floor(z) + * z = (z-x[i])*2**24 + * + * + * y[] ouput result in an array of double precision numbers. + * The dimension of y[] is: + * 24-bit precision 1 + * 53-bit precision 2 + * 64-bit precision 2 + * 113-bit precision 3 + * The actual value is the sum of them. Thus for 113-bit + * precison, one may have to do something like: + * + * long double t,w,r_head, r_tail; + * t = (long double)y[2] + (long double)y[1]; + * w = (long double)y[0]; + * r_head = t+w; + * r_tail = w - (r_head - t); + * + * e0 The exponent of x[0] + * + * nx dimension of x[] + * + * prec an integer indicating the precision: + * 0 24 bits (single) + * 1 53 bits (double) + * 2 64 bits (extended) + * 3 113 bits (quad) + * + * ipio2[] + * integer array, contains the (24*i)-th to (24*i+23)-th + * bit of 2/pi after binary point. The corresponding + * floating value is + * + * ipio2[i] * 2^(-24(i+1)). + * + * External function: + * double scalbn(), floor(); + * + * + * Here is the description of some local variables: + * + * jk jk+1 is the initial number of terms of ipio2[] needed + * in the computation. The recommended value is 2,3,4, + * 6 for single, double, extended,and quad. + * + * jz local integer variable indicating the number of + * terms of ipio2[] used. + * + * jx nx - 1 + * + * jv index for pointing to the suitable ipio2[] for the + * computation. In general, we want + * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8 + * is an integer. Thus + * e0-3-24*jv >= 0 or (e0-3)/24 >= jv + * Hence jv = max(0,(e0-3)/24). + * + * jp jp+1 is the number of terms in PIo2[] needed, jp = jk. + * + * q[] double array with integral value, representing the + * 24-bits chunk of the product of x and 2/pi. + * + * q0 the corresponding exponent of q[0]. Note that the + * exponent for q[i] would be q0-24*i. + * + * PIo2[] double precision array, obtained by cutting pi/2 + * into 24 bits chunks. + * + * f[] ipio2[] in floating point + * + * iq[] integer array by breaking up q[] in 24-bits chunk. + * + * fq[] final product of x*(2/pi) in fq[0],..,fq[jk] + * + * ih integer. If >0 it indicates q[] is >= 0.5, hence + * it also indicates the *sign* of the result. + * + */ + + +/* + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const int init_jk[] = {2,3,4,6}; /* initial value for jk */ +#else +static int init_jk[] = {2,3,4,6}; +#endif + +#ifdef __STDC__ +static const double PIo2[] = { +#else +static double PIo2[] = { +#endif + 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */ + 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */ + 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */ + 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */ + 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */ + 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */ + 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */ + 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */ +}; + +#ifdef __STDC__ +static const double +#else +static double +#endif +zero = 0.0, +one = 1.0, +two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ +twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */ + +#ifdef __STDC__ + int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int32_t *ipio2) +#else + int __kernel_rem_pio2(x,y,e0,nx,prec,ipio2) + double x[], y[]; int e0,nx,prec; int32_t ipio2[]; +#endif +{ + int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; + double z,fw,f[20],fq[20],q[20]; + + /* initialize jk*/ + jk = init_jk[prec]; + jp = jk; + + /* determine jx,jv,q0, note that 3>q0 */ + jx = nx-1; + jv = (e0-3)/24; if(jv<0) jv=0; + q0 = e0-24*(jv+1); + + /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ + j = jv-jx; m = jx+jk; + for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j]; + + /* compute q[0],q[1],...q[jk] */ + for (i=0;i<=jk;i++) { + for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw; + } + + jz = jk; +recompute: + /* distill q[] into iq[] reversingly */ + for(i=0,j=jz,z=q[jz];j>0;i++,j--) { + fw = (double)((int32_t)(twon24* z)); + iq[i] = (int32_t)(z-two24*fw); + z = q[j-1]+fw; + } + + /* compute n */ + z = scalbn(z,(int)q0); /* actual value of z */ + z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */ + n = (int32_t) z; + z -= (double)n; + ih = 0; + if(q0>0) { /* need iq[jz-1] to determine n */ + i = (iq[jz-1]>>(24-q0)); n += i; + iq[jz-1] -= i<<(24-q0); + ih = iq[jz-1]>>(23-q0); + } + else if(q0==0) ih = iq[jz-1]>>23; + else if(z>=0.5) ih=2; + + if(ih>0) { /* q > 0.5 */ + n += 1; carry = 0; + for(i=0;i<jz ;i++) { /* compute 1-q */ + j = iq[i]; + if(carry==0) { + if(j!=0) { + carry = 1; iq[i] = 0x1000000- j; + } + } else iq[i] = 0xffffff - j; + } + if(q0>0) { /* rare case: chance is 1 in 12 */ + switch(q0) { + case 1: + iq[jz-1] &= 0x7fffff; break; + case 2: + iq[jz-1] &= 0x3fffff; break; + } + } + if(ih==2) { + z = one - z; + if(carry!=0) z -= scalbn(one,(int)q0); + } + } + + /* check if recomputation is needed */ + if(z==zero) { + j = 0; + for (i=jz-1;i>=jk;i--) j |= iq[i]; + if(j==0) { /* need recomputation */ + for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */ + + for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */ + f[jx+i] = (double) ipio2[jv+i]; + for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; + q[i] = fw; + } + jz += k; + goto recompute; + } + } + + /* chop off zero terms */ + if(z==0.0) { + jz -= 1; q0 -= 24; + while(iq[jz]==0) { jz--; q0-=24;} + } else { /* break z into 24-bit if necessary */ + z = scalbn(z,-(int)q0); + if(z>=two24) { + fw = (double)((int32_t)(twon24*z)); + iq[jz] = (int32_t)(z-two24*fw); + jz += 1; q0 += 24; + iq[jz] = (int32_t) fw; + } else iq[jz] = (int32_t) z ; + } + + /* convert integer "bit" chunk to floating-point value */ + fw = scalbn(one,(int)q0); + for(i=jz;i>=0;i--) { + q[i] = fw*(double)iq[i]; fw*=twon24; + } + + /* compute PIo2[0,...,jp]*q[jz,...,0] */ + for(i=jz;i>=0;i--) { + for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k]; + fq[jz-i] = fw; + } + + /* compress fq[] into y[] */ + switch(prec) { + case 0: + fw = 0.0; + for (i=jz;i>=0;i--) fw += fq[i]; + y[0] = (ih==0)? fw: -fw; + break; + case 1: + case 2: + fw = 0.0; + for (i=jz;i>=0;i--) fw += fq[i]; + y[0] = (ih==0)? fw: -fw; + fw = fq[0]-fw; + for (i=1;i<=jz;i++) fw += fq[i]; + y[1] = (ih==0)? fw: -fw; + break; + case 3: /* painful */ + for (i=jz;i>0;i--) { + fw = fq[i-1]+fq[i]; + fq[i] += fq[i-1]-fw; + fq[i-1] = fw; + } + for (i=jz;i>1;i--) { + fw = fq[i-1]+fq[i]; + fq[i] += fq[i-1]-fw; + fq[i-1] = fw; + } + for (fw=0.0,i=jz;i>=2;i--) fw += fq[i]; + if(ih==0) { + y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; + } else { + y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; + } + } + return n&7; +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/jni/k_sin.c b/native/fdlibm/k_sin.c index 28cf7c702..b4ad387c5 100644 --- a/native/jni/k_sin.c +++ b/native/fdlibm/k_sin.c @@ -1,12 +1,12 @@ -/* @(#)k_sin.c 1.3 95/01/18 */ +/* @(#)k_sin.c 5.1 93/09/24 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * - * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice + * software is freely granted, provided that this notice * is preserved. * ==================================================== */ @@ -15,24 +15,24 @@ * kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854 * Input x is assumed to be bounded by ~pi/4 in magnitude. * Input y is the tail of x. - * Input iy indicates whether y is 0. (if iy=0, y assume to be 0). + * Input iy indicates whether y is 0. (if iy=0, y assume to be 0). * * Algorithm - * 1. Since sin(-x) = -sin(x), we need only to consider positive x. + * 1. Since sin(-x) = -sin(x), we need only to consider positive x. * 2. if x < 2^-27 (hx<0x3e400000 0), return x with inexact if x!=0. * 3. sin(x) is approximated by a polynomial of degree 13 on * [0,pi/4] * 3 13 * sin(x) ~ x + S1*x + ... + S6*x * where - * + * * |sin(x) 2 4 6 8 10 12 | -58 * |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2 - * | x | - * + * | x | + * * 4. sin(x+y) = sin(x) + sin'(x')*y * ~ sin(x) + (1-x*x/2)*y - * For better accuracy, let + * For better accuracy, let * 3 2 2 2 2 * r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6)))) * then 3 2 @@ -41,7 +41,13 @@ #include "fdlibm.h" -static const jdouble +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double +#else +static double +#endif half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */ S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */ @@ -50,17 +56,24 @@ S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */ S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */ S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */ -jdouble -__kernel_sin (jdouble x, jdouble y, jint iy) /* iy=0 if y is zero */ +#ifdef __STDC__ + double __kernel_sin(double x, double y, int iy) +#else + double __kernel_sin(x, y, iy) + double x,y; int iy; /* iy=0 if y is zero */ +#endif { - jdouble z,r,v; - jint ix; - ix = __HI(x)&0x7fffffff; /* high word of x */ - if (ix<0x3e400000) /* |x| < 2**-27 */ - {if ((jint)x==0) return x;} /* generate inexact */ - z = x*x; - v = z*x; - r = S2+z*(S3+z*(S4+z*(S5+z*S6))); - if (iy==0) return x+v*(S1+z*r); - else return x-((z*(half*y-v*r)-y)-v*S1); + double z,r,v; + int32_t ix; + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; /* high word of x */ + if(ix<0x3e400000) /* |x| < 2**-27 */ + {if((int)x==0) return x;} /* generate inexact */ + z = x*x; + v = z*x; + r = S2+z*(S3+z*(S4+z*(S5+z*S6))); + if(iy==0) return x+v*(S1+z*r); + else return x-((z*(half*y-v*r)-y)-v*S1); } + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/jni/k_tan.c b/native/fdlibm/k_tan.c index 2be0129d2..a1067a70a 100644 --- a/native/jni/k_tan.c +++ b/native/fdlibm/k_tan.c @@ -1,12 +1,12 @@ -/* @(#)k_tan.c 1.3 95/01/18 */ +/* @(#)k_tan.c 5.1 93/09/24 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * - * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice + * software is freely granted, provided that this notice * is preserved. * ==================================================== */ @@ -15,25 +15,25 @@ * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854 * Input x is assumed to be bounded by ~pi/4 in magnitude. * Input y is the tail of x. - * Input k indicates whether tan (if k=1) or + * Input k indicates whether tan (if k=1) or * -1/tan (if k= -1) is returned. * * Algorithm - * 1. Since tan(-x) = -tan(x), we need only to consider positive x. + * 1. Since tan(-x) = -tan(x), we need only to consider positive x. * 2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0. * 3. tan(x) is approximated by a odd polynomial of degree 27 on * [0,0.67434] * 3 27 * tan(x) ~ x + T1*x + ... + T13*x * where - * + * * |tan(x) 2 4 26 | -59.2 * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2 - * | x | - * + * | x | + * * Note: tan(x+y) = tan(x) + tan'(x)*y * ~ tan(x) + (1+x*x)*y - * Therefore, for better accuracy in computing tan(x+y), let + * Therefore, for better accuracy in computing tan(x+y), let * 3 2 2 2 2 * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13)))) * then @@ -47,7 +47,13 @@ #include "fdlibm.h" -static const jdouble +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double +#else +static double +#endif one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ pio4 = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */ pio4lo= 3.06161699786838301793e-17, /* 0x3C81A626, 0x33145C07 */ @@ -67,53 +73,60 @@ T[] = { 2.59073051863633712884e-05, /* 0x3EFB2A70, 0x74BF7AD4 */ }; -jdouble -__kernel_tan (jdouble x, jdouble y, jint iy) +#ifdef __STDC__ + double __kernel_tan(double x, double y, int iy) +#else + double __kernel_tan(x, y, iy) + double x,y; int iy; +#endif { - jdouble z,r,v,w,s; - jint ix,hx; - - hx = __HI(x); /* high word of x */ - ix = hx&0x7fffffff; /* high word of |x| */ - if(ix<0x3e300000) /* x < 2**-28 */ - {if((jint)x==0) { /* generate inexact */ - if(((ix|__LO(x))|(iy+1))==0) return one/fabs(x); - else return (iy==1)? x: -one/x; - } - } - if(ix>=0x3FE59428) { /* |x|>=0.6744 */ - if(hx<0) {x = -x; y = -y;} - z = pio4-x; - w = pio4lo-y; - x = z+w; y = 0.0; - } - z = x*x; - w = z*z; - /* Break x^5*(T[1]+x^2*T[2]+...) into + double z,r,v,w,s; + int32_t ix,hx; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; /* high word of |x| */ + if(ix<0x3e300000) /* x < 2**-28 */ + {if((int)x==0) { /* generate inexact */ + uint32_t low; + GET_LOW_WORD(low,x); + if(((ix|low)|(iy+1))==0) return one/fabs(x); + else return (iy==1)? x: -one/x; + } + } + if(ix>=0x3FE59428) { /* |x|>=0.6744 */ + if(hx<0) {x = -x; y = -y;} + z = pio4-x; + w = pio4lo-y; + x = z+w; y = 0.0; + } + z = x*x; + w = z*z; + /* Break x^5*(T[1]+x^2*T[2]+...) into * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12])) */ - r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11])))); - v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12]))))); - s = z*x; - r = y + z*(s*(r+v)+y); - r += T[0]*s; - w = x+r; - if(ix>=0x3FE59428) { - v = (jdouble)iy; - return (jdouble)(1-((hx>>30)&2))*(v-2.0*(x-(w*w/(w+v)-r))); - } - if(iy==1) return w; - else { /* if allow error up to 2 ulp, + r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11])))); + v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12]))))); + s = z*x; + r = y + z*(s*(r+v)+y); + r += T[0]*s; + w = x+r; + if(ix>=0x3FE59428) { + v = (double)iy; + return (double)(1-((hx>>30)&2))*(v-2.0*(x-(w*w/(w+v)-r))); + } + if(iy==1) return w; + else { /* if allow error up to 2 ulp, simply return -1.0/(x+r) here */ - /* compute -1.0/(x+r) accurately */ - jdouble a,t; - z = w; - __LO(z) = 0; - v = r-(z - x); /* z+v = r+x */ - t = a = -1.0/w; /* a = -1.0/w */ - __LO(t) = 0; - s = 1.0+t*z; - return t+a*(s+t*v); - } + /* compute -1.0/(x+r) accurately */ + double a,t; + z = w; + SET_LOW_WORD(z,0); + v = r-(z - x); /* z+v = r+x */ + t = a = -1.0/w; /* a = -1.0/w */ + SET_LOW_WORD(t,0); + s = 1.0+t*z; + return t+a*(s+t*v); + } } + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/jni/mprec.c b/native/fdlibm/mprec.c index 12dd5d261..12dd5d261 100644 --- a/native/jni/mprec.c +++ b/native/fdlibm/mprec.c diff --git a/native/jni/mprec.h b/native/fdlibm/mprec.h index 1e387d6c3..da45d82aa 100644 --- a/native/jni/mprec.h +++ b/native/fdlibm/mprec.h @@ -26,6 +26,9 @@ dmg@research.att.com or research!dmg */ +#ifndef __CLASSPATH_MPREC_H__ +#define __CLASSPATH_MPREC_H__ + #include <config.h> #include "ieeefp.h" @@ -399,3 +402,5 @@ extern _CONST double tens[]; #ifdef __cplusplus } #endif + +#endif /* __CLASSPATH_MPREC_H__ */ diff --git a/native/fdlibm/s_atan.c b/native/fdlibm/s_atan.c new file mode 100644 index 000000000..2ee745854 --- /dev/null +++ b/native/fdlibm/s_atan.c @@ -0,0 +1,181 @@ + +/* @(#)s_atan.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* +FUNCTION + <<atan>>, <<atanf>>---arc tangent + +INDEX + atan +INDEX + atanf + +ANSI_SYNOPSIS + #include <math.h> + double atan(double <[x]>); + float atanf(float <[x]>); + +TRAD_SYNOPSIS + #include <math.h> + double atan(<[x]>); + double <[x]>; + + float atanf(<[x]>); + float <[x]>; + +DESCRIPTION + +<<atan>> computes the inverse tangent (arc tangent) of the input value. + +<<atanf>> is identical to <<atan>>, save that it operates on <<floats>>. + +RETURNS +@ifinfo +<<atan>> returns a value in radians, in the range of -pi/2 to pi/2. +@end ifinfo +@tex +<<atan>> returns a value in radians, in the range of $-\pi/2$ to $\pi/2$. +@end tex + +PORTABILITY +<<atan>> is ANSI C. <<atanf>> is an extension. + +*/ + +/* atan(x) + * Method + * 1. Reduce x to positive by atan(x) = -atan(-x). + * 2. According to the integer k=4t+0.25 chopped, t=x, the argument + * is further reduced to one of the following intervals and the + * arctangent of t is evaluated by the corresponding formula: + * + * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...) + * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) ) + * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) ) + * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) ) + * [39/16,INF] atan(x) = atan(INF) + atan( -1/t ) + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double atanhi[] = { +#else +static double atanhi[] = { +#endif + 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */ + 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */ + 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */ + 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */ +}; + +#ifdef __STDC__ +static const double atanlo[] = { +#else +static double atanlo[] = { +#endif + 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */ + 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */ + 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */ + 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */ +}; + +#ifdef __STDC__ +static const double aT[] = { +#else +static double aT[] = { +#endif + 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */ + -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */ + 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */ + -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */ + 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */ + -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */ + 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */ + -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */ + 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */ + -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */ + 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */ +}; + +#ifdef __STDC__ + static const double +#else + static double +#endif +one = 1.0, +huge = 1.0e300; + +#ifdef __STDC__ + double atan(double x) +#else + double atan(x) + double x; +#endif +{ + double w,s1,s2,z; + int32_t ix,hx,id; + + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x44100000) { /* if |x| >= 2^66 */ + uint32_t low; + GET_LOW_WORD(low,x); + if(ix>0x7ff00000|| + (ix==0x7ff00000&&(low!=0))) + return x+x; /* NaN */ + if(hx>0) return atanhi[3]+atanlo[3]; + else return -atanhi[3]-atanlo[3]; + } if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ + if (ix < 0x3e200000) { /* |x| < 2^-29 */ + if(huge+x>one) return x; /* raise inexact */ + } + id = -1; + } else { + x = fabs(x); + if (ix < 0x3ff30000) { /* |x| < 1.1875 */ + if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */ + id = 0; x = (2.0*x-one)/(2.0+x); + } else { /* 11/16<=|x|< 19/16 */ + id = 1; x = (x-one)/(x+one); + } + } else { + if (ix < 0x40038000) { /* |x| < 2.4375 */ + id = 2; x = (x-1.5)/(one+1.5*x); + } else { /* 2.4375 <= |x| < 2^66 */ + id = 3; x = -1.0/x; + } + }} + /* end of argument reduction */ + z = x*x; + w = z*z; + /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ + s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10]))))); + s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9])))); + if (id<0) return x - x*(s1+s2); + else { + z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); + return (hx<0)? -z:z; + } +} + +#endif /* _DOUBLE_IS_32BITS */ diff --git a/native/fdlibm/s_ceil.c b/native/fdlibm/s_ceil.c new file mode 100644 index 000000000..250373b40 --- /dev/null +++ b/native/fdlibm/s_ceil.c @@ -0,0 +1,80 @@ + +/* @(#)s_ceil.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * ceil(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to ceil(x). + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double huge = 1.0e300; +#else +static double huge = 1.0e300; +#endif + +#ifdef __STDC__ + double ceil(double x) +#else + double ceil(x) + double x; +#endif +{ + int32_t i0,i1,j0; + uint32_t i,j; + EXTRACT_WORDS(i0,i1,x); + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ + if(i0<0) {i0=0x80000000;i1=0;} + else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;} + } + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0>0) i0 += (0x00100000)>>j0; + i0 &= (~i); i1=0; + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((uint32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0>0) { + if(j0==20) i0+=1; + else { + j = i1 + (1<<(52-j0)); + if(j<(uint32_t)i1) i0+=1; /* got a carry */ + i1 = j; + } + } + i1 &= (~i); + } + } + INSERT_WORDS(x,i0,i1); + return x; +} + +#endif /* _DOUBLE_IS_32BITS */ diff --git a/native/fdlibm/s_copysign.c b/native/fdlibm/s_copysign.c new file mode 100644 index 000000000..4804df130 --- /dev/null +++ b/native/fdlibm/s_copysign.c @@ -0,0 +1,82 @@ + +/* @(#)s_copysign.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* +FUNCTION +<<copysign>>, <<copysignf>>---sign of <[y]>, magnitude of <[x]> + +INDEX + copysign +INDEX + copysignf + +ANSI_SYNOPSIS + #include <math.h> + double copysign (double <[x]>, double <[y]>); + float copysignf (float <[x]>, float <[y]>); + +TRAD_SYNOPSIS + #include <math.h> + double copysign (<[x]>, <[y]>) + double <[x]>; + double <[y]>; + + float copysignf (<[x]>, <[y]>) + float <[x]>; + float <[y]>; + +DESCRIPTION +<<copysign>> constructs a number with the magnitude (absolute value) +of its first argument, <[x]>, and the sign of its second argument, +<[y]>. + +<<copysignf>> does the same thing; the two functions differ only in +the type of their arguments and result. + +RETURNS +<<copysign>> returns a <<double>> with the magnitude of +<[x]> and the sign of <[y]>. +<<copysignf>> returns a <<float>> with the magnitude of +<[x]> and the sign of <[y]>. + +PORTABILITY +<<copysign>> is not required by either ANSI C or the System V Interface +Definition (Issue 2). + +*/ + +/* + * copysign(double x, double y) + * copysign(x,y) returns a value with the magnitude of x and + * with the sign bit of y. + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double copysign(double x, double y) +#else + double copysign(x,y) + double x,y; +#endif +{ + uint32_t hx,hy; + GET_HIGH_WORD(hx,x); + GET_HIGH_WORD(hy,y); + SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000)); + return x; +} + +#endif /* _DOUBLE_IS_32BITS */ diff --git a/native/jni/cos.c b/native/fdlibm/s_cos.c index 70e7f224f..be1538d4c 100644 --- a/native/jni/cos.c +++ b/native/fdlibm/s_cos.c @@ -1,12 +1,12 @@ -/* @(#)s_cos.c 1.3 95/01/18 */ +/* @(#)s_cos.c 5.1 93/09/24 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * - * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice + * software is freely granted, provided that this notice * is preserved. * ==================================================== */ @@ -20,8 +20,8 @@ * __ieee754_rem_pio2 ... argument reduction routine * * Method. - * Let S,C and T denote the sin, cos and tan respectively on - * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 * in [-pi/4 , +pi/4], and let n = k mod 4. * We have * @@ -39,38 +39,44 @@ * trig(NaN) is that NaN; * * Accuracy: - * TRIG(x) returns trig(x) nearly rounded + * TRIG(x) returns trig(x) nearly rounded */ #include "fdlibm.h" -JNIEXPORT jdouble JNICALL Java_java_lang_Math_cos -(JNIEnv *env, jclass clazz, jdouble x) +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double cos(double x) +#else + double cos(x) + double x; +#endif { - jdouble y[2],z=0.0; - jint n, ix; - - /* High word of x. */ - ix = __HI(x); + double y[2],z=0.0; + int32_t n,ix; + + /* High word of x. */ + GET_HIGH_WORD(ix,x); - /* |x| ~< pi/4 */ - ix &= 0x7fffffff; - if (ix <= 0x3fe921fb) return __kernel_cos(x,z); - - /* cos(Inf or NaN) is NaN */ - else if (ix>=0x7ff00000) return x-x; + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3fe921fb) return __kernel_cos(x,z); - /* argument reduction needed */ - else - { - n = __ieee754_rem_pio2(x,y); - switch (n&3) - { - case 0: return __kernel_cos(y[0],y[1]); - case 1: return -__kernel_sin(y[0],y[1],1); - case 2: return -__kernel_cos(y[0],y[1]); - default: - return __kernel_sin(y[0],y[1],1); + /* cos(Inf or NaN) is NaN */ + else if (ix>=0x7ff00000) return x-x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x,y); + switch(n&3) { + case 0: return __kernel_cos(y[0],y[1]); + case 1: return -__kernel_sin(y[0],y[1],1); + case 2: return -__kernel_cos(y[0],y[1]); + default: + return __kernel_sin(y[0],y[1],1); + } } - } } + +#endif /* _DOUBLE_IS_32BITS */ diff --git a/native/fdlibm/s_fabs.c b/native/fdlibm/s_fabs.c new file mode 100644 index 000000000..dfee33fec --- /dev/null +++ b/native/fdlibm/s_fabs.c @@ -0,0 +1,73 @@ + +/* @(#)s_fabs.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* +FUNCTION + <<fabs>>, <<fabsf>>---absolute value (magnitude) +INDEX + fabs +INDEX + fabsf + +ANSI_SYNOPSIS + #include <math.h> + double fabs(double <[x]>); + float fabsf(float <[x]>); + +TRAD_SYNOPSIS + #include <math.h> + double fabs(<[x]>) + double <[x]>; + + float fabsf(<[x]>) + float <[x]>; + +DESCRIPTION +<<fabs>> and <<fabsf>> calculate +@tex +$|x|$, +@end tex +the absolute value (magnitude) of the argument <[x]>, by direct +manipulation of the bit representation of <[x]>. + +RETURNS +The calculated value is returned. No errors are detected. + +PORTABILITY +<<fabs>> is ANSI. +<<fabsf>> is an extension. + +*/ + +/* + * fabs(x) returns the absolute value of x. + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double fabs(double x) +#else + double fabs(x) + double x; +#endif +{ + uint32_t high; + GET_HIGH_WORD(high,x); + SET_HIGH_WORD(x,high&0x7fffffff); + return x; +} + +#endif /* _DOUBLE_IS_32BITS */ diff --git a/native/fdlibm/s_floor.c b/native/fdlibm/s_floor.c new file mode 100644 index 000000000..77e39cb7d --- /dev/null +++ b/native/fdlibm/s_floor.c @@ -0,0 +1,134 @@ + +/* @(#)s_floor.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* +FUNCTION +<<floor>>, <<floorf>>, <<ceil>>, <<ceilf>>---floor and ceiling +INDEX + floor +INDEX + floorf +INDEX + ceil +INDEX + ceilf + +ANSI_SYNOPSIS + #include <math.h> + double floor(double <[x]>); + float floorf(float <[x]>); + double ceil(double <[x]>); + float ceilf(float <[x]>); + +TRAD_SYNOPSIS + #include <math.h> + double floor(<[x]>) + double <[x]>; + float floorf(<[x]>) + float <[x]>; + double ceil(<[x]>) + double <[x]>; + float ceilf(<[x]>) + float <[x]>; + +DESCRIPTION +<<floor>> and <<floorf>> find +@tex +$\lfloor x \rfloor$, +@end tex +the nearest integer less than or equal to <[x]>. +<<ceil>> and <<ceilf>> find +@tex +$\lceil x\rceil$, +@end tex +the nearest integer greater than or equal to <[x]>. + +RETURNS +<<floor>> and <<ceil>> return the integer result as a double. +<<floorf>> and <<ceilf>> return the integer result as a float. + +PORTABILITY +<<floor>> and <<ceil>> are ANSI. +<<floorf>> and <<ceilf>> are extensions. + + +*/ + +/* + * floor(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to floor(x). + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double huge = 1.0e300; +#else +static double huge = 1.0e300; +#endif + +#ifdef __STDC__ + double floor(double x) +#else + double floor(x) + double x; +#endif +{ + int32_t i0,i1,j0; + uint32_t i,j; + EXTRACT_WORDS(i0,i1,x); + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ + if(i0>=0) {i0=i1=0;} + else if(((i0&0x7fffffff)|i1)!=0) + { i0=0xbff00000;i1=0;} + } + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0<0) i0 += (0x00100000)>>j0; + i0 &= (~i); i1=0; + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((uint32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0<0) { + if(j0==20) i0+=1; + else { + j = i1+(1<<(52-j0)); + if(j<(uint32_t)i1) i0 +=1 ; /* got a carry */ + i1=j; + } + } + i1 &= (~i); + } + } + INSERT_WORDS(x,i0,i1); + return x; +} + +#endif /* _DOUBLE_IS_32BITS */ diff --git a/native/fdlibm/s_rint.c b/native/fdlibm/s_rint.c new file mode 100644 index 000000000..5d3f8114e --- /dev/null +++ b/native/fdlibm/s_rint.c @@ -0,0 +1,87 @@ + +/* @(#)s_rint.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * rint(x) + * Return x rounded to integral value according to the prevailing + * rounding mode. + * Method: + * Using floating addition. + * Exception: + * Inexact flag raised if x not equal to rint(x). + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double +#else +static double +#endif +TWO52[2]={ + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +#ifdef __STDC__ + double rint(double x) +#else + double rint(x) + double x; +#endif +{ + int32_t i0,j0,sx; + uint32_t i,i1; + double t; + volatile double w; + EXTRACT_WORDS(i0,i1,x); + sx = (i0>>31)&1; + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { + if(((i0&0x7fffffff)|i1)==0) return x; + i1 |= (i0&0x0fffff); + i0 &= 0xfffe0000; + i0 |= ((i1|-i1)>>12)&0x80000; + SET_HIGH_WORD(x,i0); + w = TWO52[sx]+x; + t = w-TWO52[sx]; + GET_HIGH_WORD(i0,t); + SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + i>>=1; + if(((i0&i)|i1)!=0) { + if(j0==19) i1 = 0x40000000; else + i0 = (i0&(~i))|((0x20000)>>j0); + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((uint32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + i>>=1; + if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20)); + } + INSERT_WORDS(x,i0,i1); + w = TWO52[sx]+x; + return w-TWO52[sx]; +} + +#endif /* _DOUBLE_IS_32BITS */ diff --git a/native/fdlibm/s_scalbn.c b/native/fdlibm/s_scalbn.c new file mode 100644 index 000000000..36ee88981 --- /dev/null +++ b/native/fdlibm/s_scalbn.c @@ -0,0 +1,104 @@ + +/* @(#)s_scalbn.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* +FUNCTION +<<scalbn>>, <<scalbnf>>---scale by integer +INDEX + scalbn +INDEX + scalbnf + +ANSI_SYNOPSIS + #include <math.h> + double scalbn(double <[x]>, int <[y]>); + float scalbnf(float <[x]>, int <[y]>); + +TRAD_SYNOPSIS + #include <math.h> + double scalbn(<[x]>,<[y]>) + double <[x]>; + int <[y]>; + float scalbnf(<[x]>,<[y]>) + float <[x]>; + int <[y]>; + +DESCRIPTION +<<scalbn>> and <<scalbnf>> scale <[x]> by <[n]>, returning <[x]> times +2 to the power <[n]>. The result is computed by manipulating the +exponent, rather than by actually performing an exponentiation or +multiplication. + +RETURNS +<[x]> times 2 to the power <[n]>. + +PORTABILITY +Neither <<scalbn>> nor <<scalbnf>> is required by ANSI C or by the System V +Interface Definition (Issue 2). + +*/ + +/* + * scalbn (double x, int n) + * scalbn(x,n) returns x* 2**n computed by exponent + * manipulation rather than by actually performing an + * exponentiation or a multiplication. + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double +#else +static double +#endif +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ +twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ +huge = 1.0e+300, +tiny = 1.0e-300; + +#ifdef __STDC__ + double scalbn (double x, int n) +#else + double scalbn (x,n) + double x; int n; +#endif +{ + int32_t k,hx,lx; + EXTRACT_WORDS(hx,lx,x); + k = (hx&0x7ff00000)>>20; /* extract exponent */ + if (k==0) { /* 0 or subnormal x */ + if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ + x *= two54; + GET_HIGH_WORD(hx,x); + k = ((hx&0x7ff00000)>>20) - 54; + if (n< -50000) return tiny*x; /*underflow*/ + } + if (k==0x7ff) return x+x; /* NaN or Inf */ + k = k+n; + if (k > 0x7fe) return huge*copysign(huge,x); /* overflow */ + if (k > 0) /* normal result */ + {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;} + if (k <= -54) { + if (n > 50000) /* in case integer overflow in n+k */ + return huge*copysign(huge,x); /*overflow*/ + else return tiny*copysign(tiny,x); /*underflow*/ + } + k += 54; /* subnormal result */ + SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); + return x*twom54; +} + +#endif /* _DOUBLE_IS_32BITS */ diff --git a/native/fdlibm/s_sin.c b/native/fdlibm/s_sin.c new file mode 100644 index 000000000..d31545554 --- /dev/null +++ b/native/fdlibm/s_sin.c @@ -0,0 +1,132 @@ + +/* @(#)s_sin.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* +FUNCTION + <<sin>>, <<sinf>>, <<cos>>, <<cosf>>---sine or cosine +INDEX +sin +INDEX +sinf +INDEX +cos +INDEX +cosf +ANSI_SYNOPSIS + #include <math.h> + double sin(double <[x]>); + float sinf(float <[x]>); + double cos(double <[x]>); + float cosf(float <[x]>); + +TRAD_SYNOPSIS + #include <math.h> + double sin(<[x]>) + double <[x]>; + float sinf(<[x]>) + float <[x]>; + + double cos(<[x]>) + double <[x]>; + float cosf(<[x]>) + float <[x]>; + +DESCRIPTION + <<sin>> and <<cos>> compute (respectively) the sine and cosine + of the argument <[x]>. Angles are specified in radians. + + <<sinf>> and <<cosf>> are identical, save that they take and + return <<float>> values. + + +RETURNS + The sine or cosine of <[x]> is returned. + +PORTABILITY + <<sin>> and <<cos>> are ANSI C. + <<sinf>> and <<cosf>> are extensions. + +QUICKREF + sin ansi pure + sinf - pure +*/ + +/* sin(x) + * Return sine function of x. + * + * kernel function: + * __kernel_sin ... sine function on [-pi/4,pi/4] + * __kernel_cos ... cose function on [-pi/4,pi/4] + * __ieee754_rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double sin(double x) +#else + double sin(x) + double x; +#endif +{ + double y[2],z=0.0; + int32_t n,ix; + + /* High word of x. */ + GET_HIGH_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0); + + /* sin(Inf or NaN) is NaN */ + else if (ix>=0x7ff00000) return x-x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x,y); + switch(n&3) { + case 0: return __kernel_sin(y[0],y[1],1); + case 1: return __kernel_cos(y[0],y[1]); + case 2: return -__kernel_sin(y[0],y[1],1); + default: + return -__kernel_cos(y[0],y[1]); + } + } +} + +#endif /* _DOUBLE_IS_32BITS */ diff --git a/native/fdlibm/s_tan.c b/native/fdlibm/s_tan.c new file mode 100644 index 000000000..20995fcbd --- /dev/null +++ b/native/fdlibm/s_tan.c @@ -0,0 +1,114 @@ + +/* @(#)s_tan.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + + +/* + +FUNCTION + <<tan>>, <<tanf>>---tangent + +INDEX +tan +INDEX +tanf + +ANSI_SYNOPSIS + #include <math.h> + double tan(double <[x]>); + float tanf(float <[x]>); + +TRAD_SYNOPSIS + #include <math.h> + double tan(<[x]>) + double <[x]>; + + float tanf(<[x]>) + float <[x]>; + + +DESCRIPTION +<<tan>> computes the tangent of the argument <[x]>. +Angles are specified in radians. + +<<tanf>> is identical, save that it takes and returns <<float>> values. + +RETURNS +The tangent of <[x]> is returned. + +PORTABILITY +<<tan>> is ANSI. <<tanf>> is an extension. +*/ + +/* tan(x) + * Return tangent function of x. + * + * kernel function: + * __kernel_tan ... tangent function on [-pi/4,pi/4] + * __ieee754_rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "fdlibm.h" + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double tan(double x) +#else + double tan(x) + double x; +#endif +{ + double y[2],z=0.0; + int32_t n,ix; + + /* High word of x. */ + GET_HIGH_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1); + + /* tan(Inf or NaN) is NaN */ + else if (ix>=0x7ff00000) return x-x; /* NaN */ + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x,y); + return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even + -1 -- n odd */ + } +} + +#endif /* _DOUBLE_IS_32BITS */ diff --git a/native/fdlibm/sf_fabs.c b/native/fdlibm/sf_fabs.c new file mode 100644 index 000000000..34f88afc4 --- /dev/null +++ b/native/fdlibm/sf_fabs.c @@ -0,0 +1,47 @@ +/* sf_fabs.c -- float version of s_fabs.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * fabsf(x) returns the absolute value of x. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + float fabsf(float x) +#else + float fabsf(x) + float x; +#endif +{ + uint32_t ix; + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(x,ix&0x7fffffff); + return x; +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double fabs(double x) +#else + double fabs(x) + double x; +#endif +{ + return (double) fabsf((float) x); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/fdlibm/sf_rint.c b/native/fdlibm/sf_rint.c new file mode 100644 index 000000000..f44207287 --- /dev/null +++ b/native/fdlibm/sf_rint.c @@ -0,0 +1,80 @@ +/* sf_rint.c -- float version of s_rint.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const float +#else +static float +#endif +TWO23[2]={ + 8.3886080000e+06, /* 0x4b000000 */ + -8.3886080000e+06, /* 0xcb000000 */ +}; + +#ifdef __STDC__ + float rintf(float x) +#else + float rintf(x) + float x; +#endif +{ + int32_t i0,j0,sx; + uint32_t i,i1; + float w,t; + GET_FLOAT_WORD(i0,x); + sx = (i0>>31)&1; + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { + if((i0&0x7fffffff)==0) return x; + i1 = (i0&0x07fffff); + i0 &= 0xfff00000; + i0 |= ((i1|-i1)>>9)&0x400000; + SET_FLOAT_WORD(x,i0); + w = TWO23[sx]+x; + t = w-TWO23[sx]; + GET_FLOAT_WORD(i0,t); + SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + i>>=1; + if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0); + } + } else { + if(j0==0x80) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x,i0); + w = TWO23[sx]+x; + return w-TWO23[sx]; +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double rint(double x) +#else + double rint(x) + double x; +#endif +{ + return (double) rintf((float) x); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/fdlibm/strtod.c b/native/fdlibm/strtod.c new file mode 100644 index 000000000..1777b1aae --- /dev/null +++ b/native/fdlibm/strtod.c @@ -0,0 +1,719 @@ +/* +FUNCTION + <<strtod>>, <<strtodf>>---string to double or float + +INDEX + strtod +INDEX + _strtod_r +INDEX + strtodf + +ANSI_SYNOPSIS + #include <stdlib.h> + double strtod(const char *<[str]>, char **<[tail]>); + float strtodf(const char *<[str]>, char **<[tail]>); + + double _strtod_r(void *<[reent]>, + const char *<[str]>, char **<[tail]>); + +TRAD_SYNOPSIS + #include <stdlib.h> + double strtod(<[str]>,<[tail]>) + char *<[str]>; + char **<[tail]>; + + float strtodf(<[str]>,<[tail]>) + char *<[str]>; + char **<[tail]>; + + double _strtod_r(<[reent]>,<[str]>,<[tail]>) + char *<[reent]>; + char *<[str]>; + char **<[tail]>; + +DESCRIPTION + The function <<strtod>> parses the character string <[str]>, + producing a substring which can be converted to a double + value. The substring converted is the longest initial + subsequence of <[str]>, beginning with the first + non-whitespace character, that has the format: + .[+|-]<[digits]>[.][<[digits]>][(e|E)[+|-]<[digits]>] + The substring contains no characters if <[str]> is empty, consists + entirely of whitespace, or if the first non-whitespace + character is something other than <<+>>, <<->>, <<.>>, or a + digit. If the substring is empty, no conversion is done, and + the value of <[str]> is stored in <<*<[tail]>>>. Otherwise, + the substring is converted, and a pointer to the final string + (which will contain at least the terminating null character of + <[str]>) is stored in <<*<[tail]>>>. If you want no + assignment to <<*<[tail]>>>, pass a null pointer as <[tail]>. + <<strtodf>> is identical to <<strtod>> except for its return type. + + This implementation returns the nearest machine number to the + input decimal string. Ties are broken by using the IEEE + round-even rule. + + The alternate function <<_strtod_r>> is a reentrant version. + The extra argument <[reent]> is a pointer to a reentrancy structure. + +RETURNS + <<strtod>> returns the converted substring value, if any. If + no conversion could be performed, 0 is returned. If the + correct value is out of the range of representable values, + plus or minus <<HUGE_VAL>> is returned, and <<ERANGE>> is + stored in errno. If the correct value would cause underflow, 0 + is returned and <<ERANGE>> is stored in errno. + +Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, +<<lseek>>, <<read>>, <<sbrk>>, <<write>>. +*/ + +/**************************************************************** + * + * The author of this software is David M. Gay. + * + * Copyright (c) 1991 by AT&T. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + ***************************************************************/ + +/* Please send bug reports to + David M. Gay + AT&T Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-2070 + U.S.A. + dmg@research.att.com or research!dmg + */ + +#include <string.h> +#include <float.h> +#include <errno.h> +#include "mprec.h" + +double +_DEFUN (_strtod_r, (ptr, s00, se), + struct _Jv_reent *ptr _AND + _CONST char *s00 _AND + char **se) +{ + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, e1, esign, i, j, + k, nd, nd0, nf, nz, nz0, sign; + int digits = 0; /* Number of digits found in fraction part. */ + long e; + _CONST char *s, *s0, *s1; + double aadj, aadj1, adj; + long L; + unsigned long y, z; + union double_union rv, rv0; + + _Jv_Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; + sign = nz0 = nz = 0; + rv.d = 0.; + for (s = s00;; s++) + switch (*s) + { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + s = s00; + goto ret; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } +break2: + if (*s == '0') + { + digits++; + nz0 = 1; + while (*++s == '0') + digits++; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + { + digits++; + if (nd < 9) + y = 10 * y + c - '0'; + else if (nd < 16) + z = 10 * z + c - '0'; + } + nd0 = nd; + if (c == '.') + { + c = *++s; + if (!nd) + { + for (; c == '0'; c = *++s) + { + digits++; + nz++; + } + if (c > '0' && c <= '9') + { + digits++; + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for (; c >= '0' && c <= '9'; c = *++s) + { + digits++; + have_dig: + nz++; + if (c -= '0') + { + nf += nz; + for (i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10 * y + c; + else if (nd <= DBL_DIG + 1) + z = 10 * z + c; + nz = 0; + } + } + } +dig_done: + e = 0; + if (c == 'e' || c == 'E') + { + if (!nd && !nz && !nz0) + { + s = s00; + goto ret; + } + s00 = s; + esign = 0; + switch (c = *++s) + { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') + { + while (c == '0') + c = *++s; + if (c > '0' && c <= '9') + { + e = c - '0'; + s1 = s; + while ((c = *++s) >= '0' && c <= '9') + e = 10 * e + c - '0'; + if (s - s1 > 8) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 9999999L; + if (esign) + e = -e; + } + } + else + { + /* No exponent after an 'E' : that's an error. */ + ptr->_errno = EINVAL; + e = 0; + s = s00; + goto ret; + } + } + if (!nd) + { + if (!nz && !nz0) + s = s00; + goto ret; + } + e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + rv.d = y; + if (k > 9) + rv.d = tens[k - 9] * rv.d + z; + bd0 = 0; + if (nd <= DBL_DIG +#ifndef RND_PRODQUOT + && FLT_ROUNDS == 1 +#endif + ) + { + if (!e) + goto ret; + if (e > 0) + { + if (e <= Ten_pmax) + { +#ifdef VAX + goto vax_ovfl_check; +#else + /* rv.d = */ rounded_product (rv.d, tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) + { + /* A fancier test would sometimes let us do + * this for larger i values. + */ + e -= i; + rv.d *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ + vax_ovfl_check: + word0 (rv) -= P * Exp_msk1; + /* rv.d = */ rounded_product (rv.d, tens[e]); + if ((word0 (rv) & Exp_mask) + > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P)) + goto ovfl; + word0 (rv) += P * Exp_msk1; +#else + /* rv.d = */ rounded_product (rv.d, tens[e]); +#endif + goto ret; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) + { + /* rv.d = */ rounded_quotient (rv.d, tens[-e]); + goto ret; + } +#endif + } + e1 += nd - k; + + /* Get starting approximation = rv.d * 10**e1 */ + + if (e1 > 0) + { + if ((i = e1 & 15)) + rv.d *= tens[i]; + + if (e1 &= ~15) + { + if (e1 > DBL_MAX_10_EXP) + { + ovfl: + ptr->_errno = ERANGE; + + /* Force result to IEEE infinity. */ + word0 (rv) = Exp_mask; + word1 (rv) = 0; + + if (bd0) + goto retfree; + goto ret; + } + if (e1 >>= 4) + { + for (j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + rv.d *= bigtens[j]; + /* The last multiplication could overflow. */ + word0 (rv) -= P * Exp_msk1; + rv.d *= bigtens[j]; + if ((z = word0 (rv) & Exp_mask) + > Exp_msk1 * (DBL_MAX_EXP + Bias - P)) + goto ovfl; + if (z > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P)) + { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0 (rv) = Big0; +#ifndef _DOUBLE_IS_32BITS + word1 (rv) = Big1; +#endif + } + else + word0 (rv) += P * Exp_msk1; + } + + } + } + else if (e1 < 0) + { + e1 = -e1; + if ((i = e1 & 15)) + rv.d /= tens[i]; + if (e1 &= ~15) + { + e1 >>= 4; + if (e1 >= 1 << n_bigtens) + goto undfl; + for (j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + rv.d *= tinytens[j]; + /* The last multiplication could underflow. */ + rv0.d = rv.d; + rv.d *= tinytens[j]; + if (!rv.d) + { + rv.d = 2. * rv0.d; + rv.d *= tinytens[j]; + if (!rv.d) + { + undfl: + rv.d = 0.; + ptr->_errno = ERANGE; + if (bd0) + goto retfree; + goto ret; + } +#ifndef _DOUBLE_IS_32BITS + word0 (rv) = Tiny0; + word1 (rv) = Tiny1; +#else + word0 (rv) = Tiny1; +#endif + /* The refinement below will clean + * this approximation up. + */ + } + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bd0 = s2b (ptr, s0, nd0, nd, y); + + for (;;) + { + bd = Balloc (ptr, bd0->_k); + Bcopy (bd, bd0); + bb = d2b (ptr, rv.d, &bbe, &bbbits); /* rv.d = bb * 2^bbe */ + bs = i2b (ptr, 1); + + if (e >= 0) + { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else + { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; +#ifdef Sudden_Underflow +#ifdef IBM + j = 1 + 4 * P - 3 - bbbits + ((bbe + bbbits - 1) & 3); +#else + j = P + 1 - bbbits; +#endif +#else + i = bbe + bbbits - 1; /* logb(rv.d) */ + if (i < Emin) /* denormal */ + j = bbe + (P - Emin); + else + j = P + 1 - bbbits; +#endif + bb2 += j; + bd2 += j; + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) + { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) + { + bs = pow5mult (ptr, bs, bb5); + bb1 = mult (ptr, bs, bb); + Bfree (ptr, bb); + bb = bb1; + } + if (bb2 > 0) + bb = lshift (ptr, bb, bb2); + if (bd5 > 0) + bd = pow5mult (ptr, bd, bd5); + if (bd2 > 0) + bd = lshift (ptr, bd, bd2); + if (bs2 > 0) + bs = lshift (ptr, bs, bs2); + delta = diff (ptr, bb, bd); + dsign = delta->_sign; + delta->_sign = 0; + i = cmp (delta, bs); + if (i < 0) + { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (dsign || word1 (rv) || word0 (rv) & Bndry_mask) + break; + delta = lshift (ptr, delta, Log2P); + if (cmp (delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) + { + /* exactly half-way between */ + if (dsign) + { + if ((word0 (rv) & Bndry_mask1) == Bndry_mask1 + && word1 (rv) == 0xffffffff) + { + /*boundary case -- increment exponent*/ + word0 (rv) = (word0 (rv) & Exp_mask) + + Exp_msk1 +#ifdef IBM + | Exp_msk1 >> 4 +#endif + ; +#ifndef _DOUBLE_IS_32BITS + word1 (rv) = 0; +#endif + break; + } + } + else if (!(word0 (rv) & Bndry_mask) && !word1 (rv)) + { + drop_down: + /* boundary case -- decrement exponent */ +#ifdef Sudden_Underflow + L = word0 (rv) & Exp_mask; +#ifdef IBM + if (L < Exp_msk1) +#else + if (L <= Exp_msk1) +#endif + goto undfl; + L -= Exp_msk1; +#else + L = (word0 (rv) & Exp_mask) - Exp_msk1; +#endif + word0 (rv) = L | Bndry_mask1; +#ifndef _DOUBLE_IS_32BITS + word1 (rv) = 0xffffffff; +#endif +#ifdef IBM + goto cont; +#else + break; +#endif + } +#ifndef ROUND_BIASED + if (!(word1 (rv) & LSB)) + break; +#endif + if (dsign) + rv.d += ulp (rv.d); +#ifndef ROUND_BIASED + else + { + rv.d -= ulp (rv.d); +#ifndef Sudden_Underflow + if (!rv.d) + goto undfl; +#endif + } +#endif + break; + } + if ((aadj = ratio (delta, bs)) <= 2.) + { + if (dsign) + aadj = aadj1 = 1.; + else if (word1 (rv) || word0 (rv) & Bndry_mask) + { +#ifndef Sudden_Underflow + if (word1 (rv) == Tiny1 && !word0 (rv)) + goto undfl; +#endif + aadj = 1.; + aadj1 = -1.; + } + else + { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2. / FLT_RADIX) + aadj = 1. / FLT_RADIX; + else + aadj *= 0.5; + aadj1 = -aadj; + } + } + else + { + aadj *= 0.5; + aadj1 = dsign ? aadj : -aadj; +#ifdef Check_FLT_ROUNDS + switch (FLT_ROUNDS) + { + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; + } +#else + if (FLT_ROUNDS == 0) + aadj1 += 0.5; +#endif + } + y = word0 (rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1 * (DBL_MAX_EXP + Bias - 1)) + { + rv0.d = rv.d; + word0 (rv) -= P * Exp_msk1; + adj = aadj1 * ulp (rv.d); + rv.d += adj; + if ((word0 (rv) & Exp_mask) >= + Exp_msk1 * (DBL_MAX_EXP + Bias - P)) + { + if (word0 (rv0) == Big0 && word1 (rv0) == Big1) + goto ovfl; +#ifdef _DOUBLE_IS_32BITS + word0 (rv) = Big1; +#else + word0 (rv) = Big0; + word1 (rv) = Big1; +#endif + goto cont; + } + else + word0 (rv) += P * Exp_msk1; + } + else + { +#ifdef Sudden_Underflow + if ((word0 (rv) & Exp_mask) <= P * Exp_msk1) + { + rv0.d = rv.d; + word0 (rv) += P * Exp_msk1; + adj = aadj1 * ulp (rv.d); + rv.d += adj; +#ifdef IBM + if ((word0 (rv) & Exp_mask) < P * Exp_msk1) +#else + if ((word0 (rv) & Exp_mask) <= P * Exp_msk1) +#endif + { + if (word0 (rv0) == Tiny0 + && word1 (rv0) == Tiny1) + goto undfl; + word0 (rv) = Tiny0; + word1 (rv) = Tiny1; + goto cont; + } + else + word0 (rv) -= P * Exp_msk1; + } + else + { + adj = aadj1 * ulp (rv.d); + rv.d += adj; + } +#else + /* Compute adj so that the IEEE rounding rules will + * correctly round rv.d + adj in some half-way cases. + * If rv.d * ulp(rv.d) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ + if (y <= (P - 1) * Exp_msk1 && aadj >= 1.) + { + aadj1 = (double) (int) (aadj + 0.5); + if (!dsign) + aadj1 = -aadj1; + } + adj = aadj1 * ulp (rv.d); + rv.d += adj; +#endif + } + z = word0 (rv) & Exp_mask; + if (y == z) + { + /* Can we stop now? */ + L = aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (dsign || word1 (rv) || word0 (rv) & Bndry_mask) + { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999 / FLT_RADIX) + break; + } + cont: + Bfree (ptr, bb); + Bfree (ptr, bd); + Bfree (ptr, bs); + Bfree (ptr, delta); + } +retfree: + Bfree (ptr, bb); + Bfree (ptr, bd); + Bfree (ptr, bs); + Bfree (ptr, bd0); + Bfree (ptr, delta); +ret: + if (se) + *se = (char *) s; + if (digits == 0) + ptr->_errno = EINVAL; + return sign ? -rv.d : rv.d; +} + diff --git a/native/fdlibm/w_acos.c b/native/fdlibm/w_acos.c new file mode 100644 index 000000000..c9ca99c40 --- /dev/null +++ b/native/fdlibm/w_acos.c @@ -0,0 +1,118 @@ + +/* @(#)w_acos.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* +FUNCTION + <<acos>>, <<acosf>>---arc cosine + +INDEX + acos +INDEX + acosf + +ANSI_SYNOPSIS + #include <math.h> + double acos(double <[x]>); + float acosf(float <[x]>); + +TRAD_SYNOPSIS + #include <math.h> + double acos(<[x]>) + double <[x]>; + + float acosf(<[x]>) + float <[x]>; + + + +DESCRIPTION + + <<acos>> computes the inverse cosine (arc cosine) of the input value. + Arguments to <<acos>> must be in the range @minus{}1 to 1. + + <<acosf>> is identical to <<acos>>, except that it performs + its calculations on <<floats>>. + +RETURNS + @ifinfo + <<acos>> and <<acosf>> return values in radians, in the range of 0 to pi. + @end ifinfo + @tex + <<acos>> and <<acosf>> return values in radians, in the range of <<0>> to $\pi$. + @end tex + + If <[x]> is not between @minus{}1 and 1, the returned value is NaN + (not a number) the global variable <<errno>> is set to <<EDOM>>, and a + <<DOMAIN error>> message is sent as standard error output. + + You can modify error handling for these functions using <<matherr>>. + + +QUICKREF ANSI SVID POSIX RENTRANT + acos y,y,y,m + acosf n,n,n,m + +MATHREF + acos, [-1,1], acos(arg),,, + acos, NAN, arg,DOMAIN,EDOM + +MATHREF + acosf, [-1,1], acosf(arg),,, + acosf, NAN, argf,DOMAIN,EDOM + +*/ + +/* + * wrap_acos(x) + */ + +#include "fdlibm.h" +#include <errno.h> + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double acos(double x) /* wrapper acos */ +#else + double acos(x) /* wrapper acos */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_acos(x); +#else + double z; + struct exception exc; + z = __ieee754_acos(x); + if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; + if(fabs(x)>1.0) { + /* acos(|x|>1) */ + exc.type = DOMAIN; + exc.name = "acos"; + exc.err = 0; + exc.arg1 = exc.arg2 = x; + exc.retval = 0.0; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + errno = EDOM; + } + if (exc.err != 0) + errno = exc.err; + return exc.retval; + } else + return z; +#endif +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/fdlibm/w_asin.c b/native/fdlibm/w_asin.c new file mode 100644 index 000000000..f6cb271d3 --- /dev/null +++ b/native/fdlibm/w_asin.c @@ -0,0 +1,121 @@ + +/* @(#)w_asin.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* +FUNCTION + <<asin>>, <<asinf>>---arc sine + +INDEX + asin +INDEX + asinf + +ANSI_SYNOPSIS + #include <math.h> + double asin(double <[x]>); + float asinf(float <[x]>); + +TRAD_SYNOPSIS + #include <math.h> + double asin(<[x]>) + double <[x]>; + + float asinf(<[x]>) + float <[x]>; + + +DESCRIPTION + +<<asin>> computes the inverse sine (arc sine) of the argument <[x]>. +Arguments to <<asin>> must be in the range @minus{}1 to 1. + +<<asinf>> is identical to <<asin>>, other than taking and +returning floats. + +You can modify error handling for these routines using <<matherr>>. + +RETURNS +@ifinfo +<<asin>> returns values in radians, in the range of -pi/2 to pi/2. +@end ifinfo +@tex +<<asin>> returns values in radians, in the range of $-\pi/2$ to $\pi/2$. +@end tex + +If <[x]> is not in the range @minus{}1 to 1, <<asin>> and <<asinf>> +return NaN (not a number), set the global variable <<errno>> to +<<EDOM>>, and issue a <<DOMAIN error>> message. + +You can change this error treatment using <<matherr>>. + +QUICKREF ANSI SVID POSIX RENTRANT + asin y,y,y,m + asinf n,n,n,m + +MATHREF + asin, -1<=arg<=1, asin(arg),,, + asin, NAN, arg,EDOM, DOMAIN + +MATHREF + asinf, -1<=arg<=1, asin(arg),,, + asinf, NAN, arg,EDOM, DOMAIN + + +*/ + +/* + * wrapper asin(x) + */ + + +#include "fdlibm.h" +#include <errno.h> + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double asin(double x) /* wrapper asin */ +#else + double asin(x) /* wrapper asin */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_asin(x); +#else + double z; + struct exception exc; + z = __ieee754_asin(x); + if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; + if(fabs(x)>1.0) { + /* asin(|x|>1) */ + exc.type = DOMAIN; + exc.name = "asin"; + exc.err = 0; + exc.arg1 = exc.arg2 = x; + exc.retval = 0.0; + if(_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + errno = EDOM; + } + if (exc.err != 0) + errno = exc.err; + return exc.retval; + } else + return z; +#endif +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/fdlibm/w_atan2.c b/native/fdlibm/w_atan2.c new file mode 100644 index 000000000..91742c72b --- /dev/null +++ b/native/fdlibm/w_atan2.c @@ -0,0 +1,117 @@ + +/* @(#)w_atan2.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* +FUNCTION + <<atan2>>, <<atan2f>>---arc tangent of y/x + +INDEX + atan2 +INDEX + atan2f + +ANSI_SYNOPSIS + #include <math.h> + double atan2(double <[y]>,double <[x]>); + float atan2f(float <[y]>,float <[x]>); + +TRAD_SYNOPSIS + #include <math.h> + double atan2(<[y]>,<[x]>); + double <[y]>; + double <[x]>; + + float atan2f(<[y]>,<[x]>); + float <[y]>; + float <[x]>; + +DESCRIPTION + +<<atan2>> computes the inverse tangent (arc tangent) of <[y]>/<[x]>. +<<atan2>> produces the correct result even for angles near +@ifinfo +pi/2 or -pi/2 +@end ifinfo +@tex +$\pi/2$ or $-\pi/2$ +@end tex +(that is, when <[x]> is near 0). + +<<atan2f>> is identical to <<atan2>>, save that it takes and returns +<<float>>. + +RETURNS +<<atan2>> and <<atan2f>> return a value in radians, in the range of +@ifinfo +-pi to pi. +@end ifinfo +@tex +$-\pi$ to $\pi$. +@end tex + +If both <[x]> and <[y]> are 0.0, <<atan2>> causes a <<DOMAIN>> error. + +You can modify error handling for these functions using <<matherr>>. + +PORTABILITY +<<atan2>> is ANSI C. <<atan2f>> is an extension. + + +*/ + +/* + * wrapper atan2(y,x) + */ + +#include "fdlibm.h" +#include <errno.h> + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double atan2(double y, double x) /* wrapper atan2 */ +#else + double atan2(y,x) /* wrapper atan2 */ + double y,x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_atan2(y,x); +#else + double z; + struct exception exc; + z = __ieee754_atan2(y,x); + if(_LIB_VERSION == _IEEE_||isnan(x)||isnan(y)) return z; + if(x==0.0&&y==0.0) { + /* atan2(+-0,+-0) */ + exc.arg1 = y; + exc.arg2 = x; + exc.type = DOMAIN; + exc.name = "atan2"; + exc.err = 0; + exc.retval = 0.0; + if(_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + errno = EDOM; + } + if (exc.err != 0) + errno = exc.err; + return exc.retval; + } else + return z; +#endif +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/fdlibm/w_exp.c b/native/fdlibm/w_exp.c new file mode 100644 index 000000000..ae792a846 --- /dev/null +++ b/native/fdlibm/w_exp.c @@ -0,0 +1,136 @@ + +/* @(#)w_exp.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* +FUNCTION + <<exp>>, <<expf>>---exponential +INDEX + exp +INDEX + expf + +ANSI_SYNOPSIS + #include <math.h> + double exp(double <[x]>); + float expf(float <[x]>); + +TRAD_SYNOPSIS + #include <math.h> + double exp(<[x]>); + double <[x]>; + + float expf(<[x]>); + float <[x]>; + +DESCRIPTION + <<exp>> and <<expf>> calculate the exponential of <[x]>, that is, + @ifinfo + e raised to the power <[x]> (where e + @end ifinfo + @tex + $e^x$ (where $e$ + @end tex + is the base of the natural system of logarithms, approximately 2.71828). + + You can use the (non-ANSI) function <<matherr>> to specify + error handling for these functions. + +RETURNS + On success, <<exp>> and <<expf>> return the calculated value. + If the result underflows, the returned value is <<0>>. If the + result overflows, the returned value is <<HUGE_VAL>>. In + either case, <<errno>> is set to <<ERANGE>>. + +PORTABILITY + <<exp>> is ANSI C. <<expf>> is an extension. + +*/ + +/* + * wrapper exp(x) + */ + +#include "fdlibm.h" +#include <errno.h> + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +static const double +#else +static double +#endif +o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ +u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */ + +#ifdef __STDC__ + double exp(double x) /* wrapper exp */ +#else + double exp(x) /* wrapper exp */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_exp(x); +#else + double z; + struct exception exc; + z = __ieee754_exp(x); + if(_LIB_VERSION == _IEEE_) return z; + if(finite(x)) { + if(x>o_threshold) { + /* exp(finite) overflow */ +#ifndef HUGE_VAL +#define HUGE_VAL inf + double inf = 0.0; + + SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ +#endif + exc.type = OVERFLOW; + exc.name = "exp"; + exc.err = 0; + exc.arg1 = exc.arg2 = x; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + if (exc.err != 0) + errno = exc.err; + return exc.retval; + } else if(x<u_threshold) { + /* exp(finite) underflow */ + exc.type = UNDERFLOW; + exc.name = "exp"; + exc.err = 0; + exc.arg1 = exc.arg2 = x; + exc.retval = 0.0; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + if (exc.err != 0) + errno = exc.err; + return exc.retval; + } + } + return z; +#endif +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/fdlibm/w_fmod.c b/native/fdlibm/w_fmod.c new file mode 100644 index 000000000..b6b36cb76 --- /dev/null +++ b/native/fdlibm/w_fmod.c @@ -0,0 +1,107 @@ + +/* @(#)w_fmod.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* +FUNCTION +<<fmod>>, <<fmodf>>---floating-point remainder (modulo) + +INDEX +fmod +INDEX +fmodf + +ANSI_SYNOPSIS +#include <math.h> +double fmod(double <[x]>, double <[y]>) +float fmodf(float <[x]>, float <[y]>) + +TRAD_SYNOPSIS +#include <math.h> +double fmod(<[x]>, <[y]>) +double (<[x]>, <[y]>); + +float fmodf(<[x]>, <[y]>) +float (<[x]>, <[y]>); + +DESCRIPTION +The <<fmod>> and <<fmodf>> functions compute the floating-point +remainder of <[x]>/<[y]> (<[x]> modulo <[y]>). + +RETURNS +The <<fmod>> function returns the value +@ifinfo +<[x]>-<[i]>*<[y]>, +@end ifinfo +@tex +$x-i\times y$, +@end tex +for the largest integer <[i]> such that, if <[y]> is nonzero, the +result has the same sign as <[x]> and magnitude less than the +magnitude of <[y]>. + +<<fmod(<[x]>,0)>> returns NaN, and sets <<errno>> to <<EDOM>>. + +You can modify error treatment for these functions using <<matherr>>. + +PORTABILITY +<<fmod>> is ANSI C. <<fmodf>> is an extension. +*/ + +/* + * wrapper fmod(x,y) + */ + +#include "fdlibm.h" +#include <errno.h> + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double fmod(double x, double y) /* wrapper fmod */ +#else + double fmod(x,y) /* wrapper fmod */ + double x,y; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_fmod(x,y); +#else + double z; + struct exception exc; + z = __ieee754_fmod(x,y); + if(_LIB_VERSION == _IEEE_ ||isnan(y)||isnan(x)) return z; + if(y==0.0) { + /* fmod(x,0) */ + exc.type = DOMAIN; + exc.name = "fmod"; + exc.arg1 = x; + exc.arg2 = y; + exc.err = 0; + if (_LIB_VERSION == _SVID_) + exc.retval = x; + else + exc.retval = 0.0/0.0; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + errno = EDOM; + } + if (exc.err != 0) + errno = exc.err; + return exc.retval; + } else + return z; +#endif +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/fdlibm/w_log.c b/native/fdlibm/w_log.c new file mode 100644 index 000000000..dcc8b9762 --- /dev/null +++ b/native/fdlibm/w_log.c @@ -0,0 +1,115 @@ + +/* @(#)w_log.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* +FUNCTION + <<log>>, <<logf>>---natural logarithms + +INDEX + log +INDEX + logf + +ANSI_SYNOPSIS + #include <math.h> + double log(double <[x]>); + float logf(float <[x]>); + +TRAD_SYNOPSIS + #include <math.h> + double log(<[x]>); + double <[x]>; + + float logf(<[x]>); + float <[x]>; + +DESCRIPTION +Return the natural logarithm of <[x]>, that is, its logarithm base e +(where e is the base of the natural system of logarithms, 2.71828@dots{}). +<<log>> and <<logf>> are identical save for the return and argument types. + +You can use the (non-ANSI) function <<matherr>> to specify error +handling for these functions. + +RETURNS +Normally, returns the calculated value. When <[x]> is zero, the +returned value is <<-HUGE_VAL>> and <<errno>> is set to <<ERANGE>>. +When <[x]> is negative, the returned value is <<-HUGE_VAL>> and +<<errno>> is set to <<EDOM>>. You can control the error behavior via +<<matherr>>. + +PORTABILITY +<<log>> is ANSI, <<logf>> is an extension. +*/ + +/* + * wrapper log(x) + */ + +#include "fdlibm.h" +#include <errno.h> + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double log(double x) /* wrapper log */ +#else + double log(x) /* wrapper log */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_log(x); +#else + double z; + struct exception exc; + z = __ieee754_log(x); + if(_LIB_VERSION == _IEEE_ || isnan(x) || x > 0.0) return z; +#ifndef HUGE_VAL +#define HUGE_VAL inf + double inf = 0.0; + + SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ +#endif + exc.name = "log"; + exc.err = 0; + exc.arg1 = x; + exc.arg2 = x; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if(x==0.0) { + /* log(0) */ + exc.type = SING; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = EDOM; + } + } else { + /* log(x<0) */ + exc.type = DOMAIN; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + errno = EDOM; + } + } + if (exc.err != 0) + errno = exc.err; + return exc.retval; +#endif +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/fdlibm/w_pow.c b/native/fdlibm/w_pow.c new file mode 100644 index 000000000..3df099a17 --- /dev/null +++ b/native/fdlibm/w_pow.c @@ -0,0 +1,231 @@ + + +/* @(#)w_pow.c 5.2 93/10/01 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* +FUNCTION + <<pow>>, <<powf>>---x to the power y +INDEX + pow +INDEX + powf + + +ANSI_SYNOPSIS + #include <math.h> + double pow(double <[x]>, double <[y]>); + float pow(float <[x]>, float <[y]>); + +TRAD_SYNOPSIS + #include <math.h> + double pow(<[x]>, <[y]>); + double <[x]>, <[y]>; + + float pow(<[x]>, <[y]>); + float <[x]>, <[y]>; + +DESCRIPTION + <<pow>> and <<powf>> calculate <[x]> raised to the exp1.0nt <[y]>. + @tex + (That is, $x^y$.) + @end tex + +RETURNS + On success, <<pow>> and <<powf>> return the value calculated. + + When the argument values would produce overflow, <<pow>> + returns <<HUGE_VAL>> and set <<errno>> to <<ERANGE>>. If the + argument <[x]> passed to <<pow>> or <<powf>> is a negative + noninteger, and <[y]> is also not an integer, then <<errno>> + is set to <<EDOM>>. If <[x]> and <[y]> are both 0, then + <<pow>> and <<powf>> return <<1>>. + + You can modify error handling for these functions using <<matherr>>. + +PORTABILITY + <<pow>> is ANSI C. <<powf>> is an extension. */ + +/* + * wrapper pow(x,y) return x**y + */ + +#include "fdlibm.h" +#include <errno.h> + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double pow(double x, double y) /* wrapper pow */ +#else + double pow(x,y) /* wrapper pow */ + double x,y; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_pow(x,y); +#else + double z; +#ifndef HUGE_VAL +#define HUGE_VAL inf + double inf = 0.0; + + SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ +#endif + struct exception exc; + z=__ieee754_pow(x,y); + if(_LIB_VERSION == _IEEE_|| isnan(y)) return z; + if(isnan(x)) { + if(y==0.0) { + /* pow(NaN,0.0) */ + /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */ + exc.type = DOMAIN; + exc.name = "pow"; + exc.err = 0; + exc.arg1 = x; + exc.arg2 = y; + exc.retval = x; + if (_LIB_VERSION == _IEEE_ || + _LIB_VERSION == _POSIX_) exc.retval = 1.0; + else if (!matherr(&exc)) { + errno = EDOM; + } + if (exc.err != 0) + errno = exc.err; + return exc.retval; + } else + return z; + } + if(x==0.0){ + if(y==0.0) { + /* pow(0.0,0.0) */ + /* error only if _LIB_VERSION == _SVID_ */ + exc.type = DOMAIN; + exc.name = "pow"; + exc.err = 0; + exc.arg1 = x; + exc.arg2 = y; + exc.retval = 0.0; + if (_LIB_VERSION != _SVID_) exc.retval = 1.0; + else if (!matherr(&exc)) { + errno = EDOM; + } + if (exc.err != 0) + errno = exc.err; + return exc.retval; + } + if(finite(y)&&y<0.0) { + /* 0**neg */ + exc.type = DOMAIN; + exc.name = "pow"; + exc.err = 0; + exc.arg1 = x; + exc.arg2 = y; + if (_LIB_VERSION == _SVID_) + exc.retval = 0.0; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + errno = EDOM; + } + if (exc.err != 0) + errno = exc.err; + return exc.retval; + } + return z; + } + if(!finite(z)) { + if(finite(x)&&finite(y)) { + if(isnan(z)) { + /* neg**non-integral */ + exc.type = DOMAIN; + exc.name = "pow"; + exc.err = 0; + exc.arg1 = x; + exc.arg2 = y; + if (_LIB_VERSION == _SVID_) + exc.retval = 0.0; + else + exc.retval = 0.0/0.0; /* X/Open allow NaN */ + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + errno = EDOM; + } + if (exc.err != 0) + errno = exc.err; + return exc.retval; + } else { + /* pow(x,y) overflow */ + exc.type = OVERFLOW; + exc.name = "pow"; + exc.err = 0; + exc.arg1 = x; + exc.arg2 = y; + if (_LIB_VERSION == _SVID_) { + exc.retval = HUGE; + y *= 0.5; + if(x<0.0&&rint(y)!=y) exc.retval = -HUGE; + } else { + exc.retval = HUGE_VAL; + y *= 0.5; + if(x<0.0&&rint(y)!=y) exc.retval = -HUGE_VAL; + } + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + if (exc.err != 0) + errno = exc.err; + return exc.retval; + } + } + } + if(z==0.0&&finite(x)&&finite(y)) { + /* pow(x,y) underflow */ + exc.type = UNDERFLOW; + exc.name = "pow"; + exc.err = 0; + exc.arg1 = x; + exc.arg2 = y; + exc.retval = 0.0; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + if (exc.err != 0) + errno = exc.err; + return exc.retval; + } + return z; +#endif +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ + + + + + + + + + + + + + + diff --git a/native/fdlibm/w_remainder.c b/native/fdlibm/w_remainder.c new file mode 100644 index 000000000..a06be0e7b --- /dev/null +++ b/native/fdlibm/w_remainder.c @@ -0,0 +1,119 @@ + +/* @(#)w_remainder.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* +FUNCTION +<<rint>>, <<rintf>>, <<remainder>>, <<remainderf>>---round and remainder +INDEX + rint +INDEX + rintf +INDEX + remainder +INDEX + remainderf + +ANSI_SYNOPSIS + #include <math.h> + double rint(double <[x]>); + float rintf(float <[x]>); + double remainder(double <[x]>, double <[y]>); + float remainderf(float <[x]>, float <[y]>); + +TRAD_SYNOPSIS + #include <math.h> + double rint(<[x]>) + double <[x]>; + float rintf(<[x]>) + float <[x]>; + double remainder(<[x]>,<[y]>) + double <[x]>, <[y]>; + float remainderf(<[x]>,<[y]>) + float <[x]>, <[y]>; + +DESCRIPTION +<<rint>> and <<rintf>> returns their argument rounded to the nearest +integer. <<remainder>> and <<remainderf>> find the remainder of +<[x]>/<[y]>; this value is in the range -<[y]>/2 .. +<[y]>/2. + +RETURNS +<<rint>> and <<remainder>> return the integer result as a double. + +PORTABILITY +<<rint>> and <<remainder>> are System V release 4. <<rintf>> and +<<remainderf>> are extensions. + +*/ + +/* + * wrapper remainder(x,p) + */ + +#include "fdlibm.h" +#include <errno.h> + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double remainder(double x, double y) /* wrapper remainder */ +#else + double remainder(x,y) /* wrapper remainder */ + double x,y; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_remainder(x,y); +#else + double z; + struct exception exc; + z = __ieee754_remainder(x,y); + if(_LIB_VERSION == _IEEE_ || isnan(y)) return z; + if(y==0.0) { + /* remainder(x,0) */ + exc.type = DOMAIN; + exc.name = "remainder"; + exc.err = 0; + exc.arg1 = x; + exc.arg2 = y; + exc.retval = 0.0/0.0; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + errno = EDOM; + } + if (exc.err != 0) + errno = exc.err; + return exc.retval; + } else + return z; +#endif +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ + + + + + + + + + + + + + + + + + diff --git a/native/fdlibm/w_sqrt.c b/native/fdlibm/w_sqrt.c new file mode 100644 index 000000000..23a793ce7 --- /dev/null +++ b/native/fdlibm/w_sqrt.c @@ -0,0 +1,93 @@ + +/* @(#)w_sqrt.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* +FUNCTION + <<sqrt>>, <<sqrtf>>---positive square root + +INDEX + sqrt +INDEX + sqrtf + +ANSI_SYNOPSIS + #include <math.h> + double sqrt(double <[x]>); + float sqrtf(float <[x]>); + +TRAD_SYNOPSIS + #include <math.h> + double sqrt(<[x]>); + float sqrtf(<[x]>); + +DESCRIPTION + <<sqrt>> computes the positive square root of the argument. + You can modify error handling for this function with + <<matherr>>. + +RETURNS + On success, the square root is returned. If <[x]> is real and + positive, then the result is positive. If <[x]> is real and + negative, the global value <<errno>> is set to <<EDOM>> (domain error). + + +PORTABILITY + <<sqrt>> is ANSI C. <<sqrtf>> is an extension. +*/ + +/* + * wrapper sqrt(x) + */ + +#include "fdlibm.h" +#include <errno.h> + +#ifndef _DOUBLE_IS_32BITS + +#ifdef __STDC__ + double sqrt(double x) /* wrapper sqrt */ +#else + double sqrt(x) /* wrapper sqrt */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_sqrt(x); +#else + struct exception exc; + double z; + z = __ieee754_sqrt(x); + if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; + if(x<0.0) { + exc.type = DOMAIN; + exc.name = "sqrt"; + exc.err = 0; + exc.arg1 = exc.arg2 = x; + if (_LIB_VERSION == _SVID_) + exc.retval = 0.0; + else + exc.retval = 0.0/0.0; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + errno = EDOM; + } + if (exc.err != 0) + errno = exc.err; + return exc.retval; + } else + return z; +#endif +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/native/jni/Makefile.am b/native/jni/Makefile.am index 09eb71aa5..efc25f0bf 100644 --- a/native/jni/Makefile.am +++ b/native/jni/Makefile.am @@ -1,64 +1 @@ -SUBDIRS = awt - -pkglib_LTLIBRARIES = \ - libjavaio.la \ - libjavalang.la \ - libjavalangmath.la \ - libjavalangreflect.la \ - libjavanet.la \ - libjavautil.la - -libjavaio_la_SOURCES = \ - javaio.c \ - javaio.h \ - java_io_File.c \ - java_io_FileDescriptor.c \ - java_io_FileInputStream.c \ - java_io_FileOutputStream.c \ - java_io_RandomAccessFile.c \ - java_io_ObjectOutputStream.c \ - java_io_ObjectInputStream.c - -libjavalang_la_SOURCES = \ - mprec.h \ - mprec.c \ - fdlibm.h \ - jcl.h \ - jcl.c \ - java_lang_System.c \ - java_lang_Object.c \ - java_lang_Float.c \ - java_lang_Double.c - -libjavalangmath_la_SOURCES = \ - acos.c asin.c atan.c atan2.c ceil.c \ - cos.c e_fmod.c exp.c floor.c k_cos.c \ - k_rem_pio2.c k_sin.c k_tan.c log.c \ - pow.c remainder.c rint.c s_fabs.c sin.c \ - sqrt.c tan.c fdlibm.h - -libjavalangreflect_la_SOURCES = java_lang_reflect_Array.c - -libjavanet_la_SOURCES = \ - javanet.c \ - javanet.h \ - java_net_InetAddress.c \ - java_net_PlainDatagramSocketImpl.c \ - java_net_PlainSocketImpl.c - -libjavautil_la_SOURCES = \ - java_util_TimeZone.c - -libjavaio_la_LDFLAGS = -version-info @LIBVERSION@ -libjavalang_la_LDFLAGS = -version-info @LIBVERSION@ -libjavalangmath_la_LDFLAGS = -version-info @LIBVERSION@ -libjavalangreflect_la_LDFLAGS = -version-info @LIBVERSION@ -libjavanet_la_LDFLAGS = -version-info @LIBVERSION@ -libjavautil_la_LDFLAGS = -version-info @LIBVERSION@ - -INCLUDES += @EXTRA_INCLUDES@ \ - -I$(top_srcdir)/native/lib/ \ - -I$(top_builddir)/include - -clean-local: - -rm -rf .deps +SUBDIRS = classpath java-io java-lang java-net java-util gtk-peer diff --git a/native/jni/atan.c b/native/jni/atan.c deleted file mode 100644 index f3c7e63cf..000000000 --- a/native/jni/atan.c +++ /dev/null @@ -1,114 +0,0 @@ - -/* @(#)s_atan.c 1.3 95/01/18 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - * - */ - -/* atan(x) - * Method - * 1. Reduce x to positive by atan(x) = -atan(-x). - * 2. According to the integer k=4t+0.25 chopped, t=x, the argument - * is further reduced to one of the following intervals and the - * arctangent of t is evaluated by the corresponding formula: - * - * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...) - * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) ) - * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) ) - * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) ) - * [39/16,INF] atan(x) = atan(INF) + atan( -1/t ) - * - * Constants: - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the - * compiler will convert from decimal to binary accurately enough - * to produce the hexadecimal values shown. - */ - -#include "fdlibm.h" - -static const jdouble atanhi[] = { - 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */ - 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */ - 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */ - 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */ -}; - -static const jdouble atanlo[] = { - 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */ - 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */ - 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */ - 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */ -}; - -static const jdouble aT[] = { - 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */ - -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */ - 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */ - -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */ - 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */ - -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */ - 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */ - -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */ - 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */ - -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */ - 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */ -}; - -static const jdouble -one = 1.0, -huge = 1.0e300; - -JNIEXPORT jdouble JNICALL Java_java_lang_Math_atan -(JNIEnv *env, jclass clazz, jdouble x) -{ - jdouble w,s1,s2,z; - jint ix,hx,id; - - hx = __HI(x); - ix = hx&0x7fffffff; - if(ix>=0x44100000) { /* if |x| >= 2^66 */ - if(ix>0x7ff00000|| - (ix==0x7ff00000&&(__LO(x)!=0))) - return x+x; /* NaN */ - if(hx>0) return atanhi[3]+atanlo[3]; - else return -atanhi[3]-atanlo[3]; - } if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ - if (ix < 0x3e200000) { /* |x| < 2^-29 */ - if(huge+x>one) return x; /* raise inexact */ - } - id = -1; - } else { - x = fabs(x); - if (ix < 0x3ff30000) { /* |x| < 1.1875 */ - if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */ - id = 0; x = (2.0*x-one)/(2.0+x); - } else { /* 11/16<=|x|< 19/16 */ - id = 1; x = (x-one)/(x+one); - } - } else { - if (ix < 0x40038000) { /* |x| < 2.4375 */ - id = 2; x = (x-1.5)/(one+1.5*x); - } else { /* 2.4375 <= |x| < 2^66 */ - id = 3; x = -1.0/x; - } - }} - /* end of argument reduction */ - z = x*x; - w = z*z; - /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ - s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10]))))); - s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9])))); - if (id<0) return x - x*(s1+s2); - else { - z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); - return (hx<0)? -z:z; - } -} diff --git a/native/jni/atan2.c b/native/jni/atan2.c deleted file mode 100644 index 11f5c42d8..000000000 --- a/native/jni/atan2.c +++ /dev/null @@ -1,115 +0,0 @@ - -/* @(#)e_atan2.c 1.3 95/01/18 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - * - */ - -/* __ieee754_atan2(y,x) - * Method : - * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x). - * 2. Reduce x to positive by (if x and y are unexceptional): - * ARG (x+iy) = arctan(y/x) ... if x > 0, - * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0, - * - * Special cases: - * - * ATAN2((anything), NaN ) is NaN; - * ATAN2(NAN , (anything) ) is NaN; - * ATAN2(+-0, +(anything but NaN)) is +-0 ; - * ATAN2(+-0, -(anything but NaN)) is +-pi ; - * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2; - * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ; - * ATAN2(+-(anything but INF and NaN), -INF) is +-pi; - * ATAN2(+-INF,+INF ) is +-pi/4 ; - * ATAN2(+-INF,-INF ) is +-3pi/4; - * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2; - * - * Constants: - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the - * compiler will convert from decimal to binary accurately enough - * to produce the hexadecimal values shown. - */ - -#include "fdlibm.h" - -static const jdouble -tiny = 1.0e-300, -zero = 0.0, -pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */ -pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */ -pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */ -pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ - -JNIEXPORT jdouble JNICALL Java_java_lang_Math_atan2 -(JNIEnv *env, jclass clazz, jdouble y, jdouble x) -{ - jdouble z; - jint k,m,hx,hy,ix,iy; - unsigned lx,ly; - - hx = __HI(x); ix = hx&0x7fffffff; - lx = __LO(x); - hy = __HI(y); iy = hy&0x7fffffff; - ly = __LO(y); - if(((ix|((lx|-lx)>>31))>0x7ff00000)|| - ((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */ - return x+y; - if((hx-0x3ff00000|lx)==0) return atan(y); /* x=1.0 */ - m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ - - /* when y = 0 */ - if((iy|ly)==0) { - switch(m) { - case 0: - case 1: return y; /* atan(+-0,+anything)=+-0 */ - case 2: return pi+tiny;/* atan(+0,-anything) = pi */ - case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */ - } - } - /* when x = 0 */ - if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; - - /* when x is INF */ - if(ix==0x7ff00000) { - if(iy==0x7ff00000) { - switch(m) { - case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */ - case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */ - case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/ - case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/ - } - } else { - switch(m) { - case 0: return zero ; /* atan(+...,+INF) */ - case 1: return -zero ; /* atan(-...,+INF) */ - case 2: return pi+tiny ; /* atan(+...,-INF) */ - case 3: return -pi-tiny ; /* atan(-...,-INF) */ - } - } - } - /* when y is INF */ - if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; - - /* compute y/x */ - k = (iy-ix)>>20; - if(k > 60) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**60 */ - else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */ - else z=atan(fabs(y/x)); /* safe to do y/x */ - switch (m) { - case 0: return z ; /* atan(+,+) */ - case 1: __HI(z) ^= 0x80000000; - return z ; /* atan(-,+) */ - case 2: return pi-(z-pi_lo);/* atan(+,-) */ - default: /* case 3 */ - return (z-pi_lo)-pi;/* atan(-,-) */ - } -} diff --git a/native/jni/awt/native_state.c b/native/jni/awt/native_state.c deleted file mode 100644 index a7bccfb64..000000000 --- a/native/jni/awt/native_state.c +++ /dev/null @@ -1,238 +0,0 @@ -/* Magical NSA API -- Associate a C ptr with an instance of an object - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -As a special exception, if you link this library with other files to -produce an executable, this library does not by itself cause the -resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why the -executable file might be covered by the GNU General Public License. */ - -#include <stdlib.h> -#include <jni.h> -#include "native_state.h" - -#define DEFAULT_TABLE_SIZE 97 - -struct state_table * -init_state_table_with_size (JNIEnv *env, jclass clazz, jint size) -{ - struct state_table *table; - jfieldID hash; - jclass clazz_g; - - hash = (*env)->GetFieldID (env, clazz, "native_state", "I"); - if (hash == NULL) - return NULL; - - clazz_g = (*env)->NewGlobalRef (env, clazz); - if (clazz_g == NULL) - return NULL; - - table = (struct state_table *) malloc (sizeof (struct state_table)); - table->size = size; - table->head = (struct state_node **) calloc (sizeof (struct state_node *), - table->size); - table->hash = hash; - table->clazz = clazz_g; - - return table; -} - -struct state_table * -init_state_table (JNIEnv *env, jclass clazz) -{ - return init_state_table_with_size (env, clazz, DEFAULT_TABLE_SIZE); -} - -static -void * -remove_node (struct state_node **head, jint obj_id) -{ - struct state_node *back_ptr = NULL; - struct state_node *node = *head; - - while (node != NULL) - { - if (node->key == obj_id) - { - void *return_value; - if (back_ptr == NULL) - *head = node->next; - else - back_ptr->next = node->next; - return_value = node->c_state; - free (node); - return return_value; - } - back_ptr = node; - node = node->next; - } - - return NULL; -} - -static -void * -get_node (struct state_node **head, jint obj_id) -{ - struct state_node *back_ptr = NULL; - struct state_node *node = *head; - - while (node != NULL) - { - if (node->key == obj_id) - { - /* move the node we found to the front of the list */ - if (back_ptr != NULL) - { - back_ptr->next = node->next; - node->next = *head; - *head = node; - } - - /* return the match */ - return node->c_state; - } - - back_ptr = node; - node = node->next; - } - - return NULL; -} - -static -void -add_node (struct state_node **head, jint obj_id, void *state) -{ - struct state_node *node = *head; - struct state_node *back_ptr = *head; - - struct state_node *new_node; - new_node = (struct state_node *) malloc (sizeof (struct state_node)); - new_node->key = obj_id; - new_node->c_state = state; - - /* insert into an empty slot */ - if (node == NULL) - { - new_node->next = NULL; - *head = new_node; - return; - } - - /* collision resolution */ - /* try to find the old node, if it exists */ - while (node->next != NULL && obj_id != node->key) - { - back_ptr = node; - node = node->next; - } - - /* if we're updating a node, setup to move it to the front of the list */ - if (node->key == obj_id) - back_ptr->next = node->next; - - /* move node to the beginning */ - new_node->next = *head; - *head = new_node; -} - -void -set_state_oid (JNIEnv *env, jobject lock, struct state_table *table, - jint obj_id, void *state) -{ - jint hash; - - hash = obj_id % table->size; - - (*env)->MonitorEnter (env, lock); - add_node (&table->head[hash], obj_id, state); - (*env)->MonitorExit (env, lock); -} - -void * -get_state_oid (JNIEnv *env, jobject lock, struct state_table *table, - jint obj_id) -{ - jint hash; - void *return_value; - - hash = obj_id % table->size; - - (*env)->MonitorEnter (env, lock); - return_value = get_node (&table->head[hash], obj_id); - (*env)->MonitorExit (env, lock); - - return return_value; -} - -void * -remove_state_oid (JNIEnv *env, jobject lock, struct state_table *table, - jint obj_id) -{ - jint hash; - void *return_value; - - hash = obj_id % table->size; - - (*env)->MonitorEnter (env, lock); - return_value = remove_node (&table->head[hash], obj_id); - (*env)->MonitorExit (env, lock); - - return return_value; -} - -int -set_state (JNIEnv *env, jobject obj, struct state_table *table, void *state) -{ - jint obj_id; - obj_id = (*env)->GetIntField (env, obj, table->hash); - - if ((*env)->ExceptionOccurred (env) != NULL) - return -1; - - set_state_oid (env, table->clazz, table, obj_id, state); - return 0; -} - -void * -get_state (JNIEnv *env, jobject obj, struct state_table *table) -{ - jint obj_id; - obj_id = (*env)->GetIntField (env, obj, table->hash); - - if ((*env)->ExceptionOccurred (env) != NULL) - return NULL; - - return get_state_oid (env, table->clazz, table, obj_id); -} - -void * -remove_state_slot (JNIEnv *env, jobject obj, struct state_table *table) -{ - jint obj_id; - obj_id = (*env)->GetIntField (env, obj, table->hash); - - if ((*env)->ExceptionOccurred (env) != NULL) - return NULL; - - return remove_state_oid (env, table->clazz, table, obj_id); -} diff --git a/native/jni/awt/native_state.h b/native/jni/awt/native_state.h deleted file mode 100644 index 76348705a..000000000 --- a/native/jni/awt/native_state.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Magical NSA API -- Associate a C ptr with an instance of an object - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -As a special exception, if you link this library with other files to -produce an executable, this library does not by itself cause the -resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why the -executable file might be covered by the GNU General Public License. */ - - -#ifndef JCL_NATIVE_STATE -#define JCL_NATIVE_STATE - -#include <jni.h> - -struct state_table -{ - jint size; /* number of slots, should be prime */ - jfieldID hash; /* field containing System.identityHashCode(this) */ - jclass clazz; /* lock aquired for reading/writing nodes */ - struct state_node **head; -}; - -struct state_node -{ - jint key; - void *c_state; - struct state_node *next; -}; - -struct state_table * init_state_table_with_size (JNIEnv *, jclass, jint); -struct state_table * init_state_table (JNIEnv *, jclass); - -/* lowlevel api */ -void set_state_oid (JNIEnv *, jobject, struct state_table *, jint, void *); -void * get_state_oid (JNIEnv *, jobject, struct state_table *, jint); -void * remove_state_oid (JNIEnv *, jobject, struct state_table *, jint); - -/* highlevel api */ -int set_state (JNIEnv *, jobject, struct state_table *, void *); -void * get_state (JNIEnv *, jobject, struct state_table *); -void * remove_state_slot (JNIEnv *, jobject, struct state_table *); - -#endif diff --git a/native/jni/ceil.c b/native/jni/ceil.c deleted file mode 100644 index 7f31f6803..000000000 --- a/native/jni/ceil.c +++ /dev/null @@ -1,71 +0,0 @@ - -/* @(#)s_ceil.c 1.3 95/01/18 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* - * ceil(x) - * Return x rounded toward -inf to integral value - * Method: - * Bit twiddling. - * Exception: - * Inexact flag raised if x not equal to ceil(x). - */ - -#include "fdlibm.h" - -static const jdouble huge = 1.0e300; - -JNIEXPORT jdouble JNICALL Java_java_lang_Math_ceil -(JNIEnv *env, jclass clazz, jdouble x) -{ - jint i0,i1,j0; - unsigned i,j; /* XXX: UNSIGNED MUST BE 32-BITS */ - - i0 = __HI(x); - i1 = __LO(x); - j0 = ((i0>>20)&0x7ff)-0x3ff; - if(j0<20) { - if(j0<0) { /* raise inexact if x != 0 */ - if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ - if(i0<0) {i0=0x80000000;i1=0;} - else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;} - } - } else { - i = (0x000fffff)>>j0; - if(((i0&i)|i1)==0) return x; /* x is integral */ - if(huge+x>0.0) { /* raise inexact flag */ - if(i0>0) i0 += (0x00100000)>>j0; - i0 &= (~i); i1=0; - } - } - } else if (j0>51) { - if(j0==0x400) return x+x; /* inf or NaN */ - else return x; /* x is integral */ - } else { - i = ((unsigned)(0xffffffff))>>(j0-20); - if((i1&i)==0) return x; /* x is integral */ - if(huge+x>0.0) { /* raise inexact flag */ - if(i0>0) { - if(j0==20) i0+=1; - else { - j = i1 + (1<<(52-j0)); - if(j<i1) i0+=1; /* got a carry */ - i1 = j; - } - } - i1 &= (~i); - } - } - __HI(x) = i0; - __LO(x) = i1; - return x; -} diff --git a/native/jni/e_fmod.c b/native/jni/e_fmod.c deleted file mode 100644 index 6bee4c077..000000000 --- a/native/jni/e_fmod.c +++ /dev/null @@ -1,132 +0,0 @@ - -/* @(#)e_fmod.c 1.3 95/01/18 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* - * __ieee754_fmod(x,y) - * Return x mod y in exact arithmetic - * Method: shift and subtract - */ - -#include "fdlibm.h" - -static const jdouble one = 1.0, Zero[] = {0.0, -0.0,}; - -jdouble -__ieee754_fmod (jdouble x, jdouble y) -{ - jint n,hx,hy,hz,ix,iy,sx,i; - unsigned lx,ly,lz; - - hx = __HI(x); /* high word of x */ - lx = __LO(x); /* low word of x */ - hy = __HI(y); /* high word of y */ - ly = __LO(y); /* low word of y */ - sx = hx&0x80000000; /* sign of x */ - hx ^=sx; /* |x| */ - hy &= 0x7fffffff; /* |y| */ - - /* purge off exception values */ - if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */ - ((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */ - return (x*y)/(x*y); - if(hx<=hy) { - if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */ - if(lx==ly) - return Zero[(unsigned)sx>>31]; /* |x|=|y| return x*0*/ - } - - /* determine ix = ilogb(x) */ - if(hx<0x00100000) { /* subnormal x */ - if(hx==0) { - for (ix = -1043, i=lx; i>0; i<<=1) ix -=1; - } else { - for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1; - } - } else ix = (hx>>20)-1023; - - /* determine iy = ilogb(y) */ - if(hy<0x00100000) { /* subnormal y */ - if(hy==0) { - for (iy = -1043, i=ly; i>0; i<<=1) iy -=1; - } else { - for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1; - } - } else iy = (hy>>20)-1023; - - /* set up {hx,lx}, {hy,ly} and align y to x */ - if(ix >= -1022) - hx = 0x00100000|(0x000fffff&hx); - else { /* subnormal x, shift x to normal */ - n = -1022-ix; - if(n<=31) { - hx = (hx<<n)|(lx>>(32-n)); - lx <<= n; - } else { - hx = lx<<(n-32); - lx = 0; - } - } - if(iy >= -1022) - hy = 0x00100000|(0x000fffff&hy); - else { /* subnormal y, shift y to normal */ - n = -1022-iy; - if(n<=31) { - hy = (hy<<n)|(ly>>(32-n)); - ly <<= n; - } else { - hy = ly<<(n-32); - ly = 0; - } - } - - /* fix point fmod */ - n = ix - iy; - while(n--) { - hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1; - if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;} - else { - if((hz|lz)==0) /* return sign(x)*0 */ - return Zero[(unsigned)sx>>31]; - hx = hz+hz+(lz>>31); lx = lz+lz; - } - } - hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1; - if(hz>=0) {hx=hz;lx=lz;} - - /* convert back to floating value and restore the sign */ - if((hx|lx)==0) /* return sign(x)*0 */ - return Zero[(unsigned)sx>>31]; - while(hx<0x00100000) { /* normalize x */ - hx = hx+hx+(lx>>31); lx = lx+lx; - iy -= 1; - } - if(iy>= -1022) { /* normalize output */ - hx = ((hx-0x00100000)|((iy+1023)<<20)); - __HI(x) = hx|sx; - __LO(x) = lx; - } else { /* subnormal output */ - n = -1022 - iy; - if(n<=20) { - lx = (lx>>n)|((unsigned)hx<<(32-n)); - hx >>= n; - } else if (n<=31) { - lx = (hx<<(32-n))|(lx>>n); hx = sx; - } else { - lx = hx>>(n-32); hx = sx; - } - __HI(x) = hx|sx; - __LO(x) = lx; - x *= one; /* create necessary signal */ - } - return x; /* exact output */ -} diff --git a/native/jni/fdlibm.h b/native/jni/fdlibm.h deleted file mode 100644 index 1974f0692..000000000 --- a/native/jni/fdlibm.h +++ /dev/null @@ -1,83 +0,0 @@ -#include <config.h> - -#ifndef __FDLIBM__ -#define __FDLIBM__ - -/* @(#)fdlibm.h 1.5 95/01/18 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * Portions Copyright (c) 1998 Free Software Foundation, Inc. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#include "java_lang_Math.h" -#include <stdlib.h> - -#define sqrt(x) Java_java_lang_Math_sqrt(NULL, NULL, x) - -#ifndef WORDS_BIGENDIAN -#define __HI(x) *(1+(jint*)&x) -#define __LO(x) *(jint*)&x -#define __HIp(x) *(1+(jint*)x) -#define __LOp(x) *(jint*)x -#else -#define __HI(x) *(jint*)&x -#define __LO(x) *(1+(jint*)&x) -#define __HIp(x) *(jint*)x -#define __LOp(x) *(1+(jint*)x) -#endif - -#define MAXFLOAT ((float)3.40282346638528860e+38) - -enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix}; - -#define _LIB_VERSION_TYPE enum fdversion -#define _LIB_VERSION _fdlib_version - -/* if global variable _LIB_VERSION is not desirable, one may - * change the following to be a constant by: - * #define _LIB_VERSION_TYPE const enum version - * In that case, after one initializes the value _LIB_VERSION (see - * s_lib_version.c) during compile time, it cannot be modified - * in the middle of a program - */ -extern _LIB_VERSION_TYPE _LIB_VERSION; - -#define _IEEE_ fdlibm_ieee -#define _SVID_ fdlibm_svid -#define _XOPEN_ fdlibm_xopen -#define _POSIX_ fdlibm_posix - -struct exception { - int type; - char *name; - double arg1; - double arg2; - double retval; -}; - -#define HUGE MAXFLOAT - -#define DOMAIN 1 -#define SING 2 -#define OVERFLOW 3 -#define UNDERFLOW 4 -#define TLOSS 5 -#define PLOSS 6 - -/* ieee style elementary functions */ -extern jdouble __ieee754_fmod (jdouble,jdouble); -extern jdouble fabs (jdouble); - -/* fdlibm kernel function */ -extern jdouble __kernel_sin (jdouble, jdouble, jint); -extern jdouble __kernel_cos (jdouble, jdouble); -extern jdouble __kernel_tan (jdouble, jdouble, jint); -extern jint __kernel_rem_pio2 (jdouble*,jdouble*,jint,jint,jint,const jint*); -#endif diff --git a/native/jni/floor.c b/native/jni/floor.c deleted file mode 100644 index 6e5932c4e..000000000 --- a/native/jni/floor.c +++ /dev/null @@ -1,72 +0,0 @@ - -/* @(#)s_floor.c 1.3 95/01/18 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* - * floor(x) - * Return x rounded toward -inf to integral value - * Method: - * Bit twiddling. - * Exception: - * Inexact flag raised if x not equal to floor(x). - */ - -#include "fdlibm.h" - -static const jdouble huge = 1.0e300; - -JNIEXPORT jdouble JNICALL Java_java_lang_Math_floor -(JNIEnv *env, jclass clazz, jdouble x) -{ - jint i0,i1,j0; - unsigned i,j; /* XXX: UNSIGNED MUST BE 32-BITS */ - - i0 = __HI(x); - i1 = __LO(x); - j0 = ((i0>>20)&0x7ff)-0x3ff; - if(j0<20) { - if(j0<0) { /* raise inexact if x != 0 */ - if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ - if(i0>=0) {i0=i1=0;} - else if(((i0&0x7fffffff)|i1)!=0) - { i0=0xbff00000;i1=0;} - } - } else { - i = (0x000fffff)>>j0; - if(((i0&i)|i1)==0) return x; /* x is integral */ - if(huge+x>0.0) { /* raise inexact flag */ - if(i0<0) i0 += (0x00100000)>>j0; - i0 &= (~i); i1=0; - } - } - } else if (j0>51) { - if(j0==0x400) return x+x; /* inf or NaN */ - else return x; /* x is integral */ - } else { - i = ((unsigned)(0xffffffff))>>(j0-20); - if((i1&i)==0) return x; /* x is integral */ - if(huge+x>0.0) { /* raise inexact flag */ - if(i0<0) { - if(j0==20) i0+=1; - else { - j = i1+(1<<(52-j0)); - if(j<i1) i0 +=1 ; /* got a carry */ - i1=j; - } - } - i1 &= (~i); - } - } - __HI(x) = i0; - __LO(x) = i1; - return x; -} diff --git a/native/nsa/.cvsignore b/native/jni/gtk-peer/.cvsignore index e9f2658a6..e9f2658a6 100644 --- a/native/nsa/.cvsignore +++ b/native/jni/gtk-peer/.cvsignore diff --git a/native/jni/awt/Makefile.am b/native/jni/gtk-peer/Makefile.am index 3122205cc..441a60730 100644 --- a/native/jni/awt/Makefile.am +++ b/native/jni/gtk-peer/Makefile.am @@ -21,7 +21,6 @@ libgtkpeer_la_SOURCES = \ gnu_java_awt_peer_gtk_GtkWindowPeer.c \ gnu_java_awt_peer_gtk_GtkCheckboxPeer.c \ gnu_java_awt_peer_gtk_GtkMenuItemPeer.c \ - native_state.c \ gnu_java_awt_peer_gtk_GtkChoicePeer.c \ gnu_java_awt_peer_gtk_GtkMenuPeer.c \ gnu_java_awt_peer_gtk_GtkClipboard.c \ @@ -31,16 +30,14 @@ libgtkpeer_la_SOURCES = \ gnu_java_awt_peer_gtk_GtkEvents.c \ gnu_java_awt_peer_gtk_GtkScrollBarPeer.c \ gthread-jni.h \ - gtkpeer.h \ - native_state.h + gtkpeer.h -libgtkpeer_la_LDFLAGS = -version-info @LIBVERSION@ @GTK_LIBS@ @GLIB_LIBS@ @LIBART_LIBS@ +libgtkpeer_la_LIBADD = $(top_builddir)/native/jni/classpath/native_state.lo +libgtkpeer_la_LDFLAGS = -module -version-info @LIBVERSION@ @GTK_LIBS@ @GLIB_LIBS@ @LIBART_LIBS@ -INCLUDES += @EXTRA_INCLUDES@ \ - @GTK_CFLAGS@ \ - @LIBART_CFLAGS@ \ - -I$(top_builddir)/include - -clean-local: - -rm -rf .deps +INCLUDES = @EXTRA_INCLUDES@ \ + @GTK_CFLAGS@ \ + @LIBART_CFLAGS@ \ + -I$(top_srcdir)/native/jni/classpath \ + -I$(top_builddir)/include diff --git a/native/jni/gtk-peer/Makefile.in b/native/jni/gtk-peer/Makefile.in new file mode 100644 index 000000000..508dd2944 --- /dev/null +++ b/native/jni/gtk-peer/Makefile.in @@ -0,0 +1,492 @@ +# Makefile.in generated automatically by automake 1.5 from Makefile.am. + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_HEADER = $(INSTALL_DATA) +transform = @program_transform_name@ +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AMTAR = @AMTAR@ +AS = @AS@ +AWK = @AWK@ +CC = @CC@ +CPP = @CPP@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +EXEEXT = @EXEEXT@ +EXTRA_INCLUDES = @EXTRA_INCLUDES@ +FIND = @FIND@ +GCJ = @GCJ@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_CONFIG = @GLIB_CONFIG@ +GLIB_LIBS = @GLIB_LIBS@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_CONFIG = @GTK_CONFIG@ +GTK_LIBS = @GTK_LIBS@ +INIT_LOAD_LIBRARY = @INIT_LOAD_LIBRARY@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JAPHAR_CFLAGS = @JAPHAR_CFLAGS@ +JAPHAR_CLASSLIB = @JAPHAR_CLASSLIB@ +JAPHAR_CONFIG = @JAPHAR_CONFIG@ +JAPHAR_JABBA = @JAPHAR_JABBA@ +JAPHAR_JAVAC = @JAPHAR_JAVAC@ +JAPHAR_JAVAH = @JAPHAR_JAVAH@ +JAPHAR_LIBS = @JAPHAR_LIBS@ +JAPHAR_PREFIX = @JAPHAR_PREFIX@ +JIKES = @JIKES@ +JVM = @JVM@ +JVM_REFERENCE = @JVM_REFERENCE@ +KAFFE_CFLAGS = @KAFFE_CFLAGS@ +KAFFE_CLASSLIB = @KAFFE_CLASSLIB@ +KAFFE_CONFIG = @KAFFE_CONFIG@ +KAFFE_JABBA = @KAFFE_JABBA@ +KAFFE_JAVAH = @KAFFE_JAVAH@ +KAFFE_LIBS = @KAFFE_LIBS@ +KAFFE_PREFIX = @KAFFE_PREFIX@ +KJC_CLASSPATH = @KJC_CLASSPATH@ +LIBART_CFLAGS = @LIBART_CFLAGS@ +LIBART_CONFIG = @LIBART_CONFIG@ +LIBART_LIBS = @LIBART_LIBS@ +LIBDEBUG = @LIBDEBUG@ +LIBTOOL = @LIBTOOL@ +LIBVERSION = @LIBVERSION@ +LN_S = @LN_S@ +MAINT = @MAINT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PERL = @PERL@ +RANLIB = @RANLIB@ +REMOVE = @REMOVE@ +SH = @SH@ +STRIP = @STRIP@ +USER_CLASSLIB = @USER_CLASSLIB@ +USER_JABBA = @USER_JABBA@ +USER_JAVAH = @USER_JAVAH@ +VERSION = @VERSION@ +ZIP = @ZIP@ +am__include = @am__include@ +am__quote = @am__quote@ +install_sh = @install_sh@ + +pkglib_LTLIBRARIES = libgtkpeer.la + +libgtkpeer_la_SOURCES = \ + gnu_java_awt_peer_gtk_GdkFontMetrics.c \ + gnu_java_awt_peer_gtk_GtkFileDialogPeer.c \ + gnu_java_awt_peer_gtk_GtkScrollPanePeer.c \ + gnu_java_awt_peer_gtk_GdkGraphics.c \ + gnu_java_awt_peer_gtk_GtkImagePainter.c \ + gnu_java_awt_peer_gtk_GtkTextAreaPeer.c \ + gthread-jni.c \ + gnu_java_awt_peer_gtk_GtkLabelPeer.c \ + gnu_java_awt_peer_gtk_GtkTextComponentPeer.c \ + gnu_java_awt_peer_gtk_GtkButtonPeer.c \ + gnu_java_awt_peer_gtk_GtkListPeer.c \ + gnu_java_awt_peer_gtk_GtkTextFieldPeer.c \ + gnu_java_awt_peer_gtk_GtkCanvasPeer.c \ + gnu_java_awt_peer_gtk_GtkMainThread.c \ + gnu_java_awt_peer_gtk_GtkToolkit.c \ + gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c \ + gnu_java_awt_peer_gtk_GtkMenuBarPeer.c \ + gnu_java_awt_peer_gtk_GtkWindowPeer.c \ + gnu_java_awt_peer_gtk_GtkCheckboxPeer.c \ + gnu_java_awt_peer_gtk_GtkMenuItemPeer.c \ + gnu_java_awt_peer_gtk_GtkChoicePeer.c \ + gnu_java_awt_peer_gtk_GtkMenuPeer.c \ + gnu_java_awt_peer_gtk_GtkClipboard.c \ + gnu_java_awt_peer_gtk_GtkPanelPeer.c \ + gnu_java_awt_peer_gtk_GtkComponentPeer.c \ + gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c \ + gnu_java_awt_peer_gtk_GtkEvents.c \ + gnu_java_awt_peer_gtk_GtkScrollBarPeer.c \ + gthread-jni.h \ + gtkpeer.h + + +libgtkpeer_la_LIBADD = $(top_builddir)/native/jni/classpath/native_state.lo +libgtkpeer_la_LDFLAGS = -module -version-info @LIBVERSION@ @GTK_LIBS@ @GLIB_LIBS@ @LIBART_LIBS@ + +INCLUDES = @EXTRA_INCLUDES@ \ + @GTK_CFLAGS@ \ + @LIBART_CFLAGS@ \ + -I$(top_srcdir)/native/jni/classpath \ + -I$(top_builddir)/include + +subdir = native/jni/gtk-peer +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(pkglib_LTLIBRARIES) + +libgtkpeer_la_DEPENDENCIES = \ + $(top_builddir)/native/jni/classpath/native_state.lo +am_libgtkpeer_la_OBJECTS = gnu_java_awt_peer_gtk_GdkFontMetrics.lo \ + gnu_java_awt_peer_gtk_GtkFileDialogPeer.lo \ + gnu_java_awt_peer_gtk_GtkScrollPanePeer.lo \ + gnu_java_awt_peer_gtk_GdkGraphics.lo \ + gnu_java_awt_peer_gtk_GtkImagePainter.lo \ + gnu_java_awt_peer_gtk_GtkTextAreaPeer.lo gthread-jni.lo \ + gnu_java_awt_peer_gtk_GtkLabelPeer.lo \ + gnu_java_awt_peer_gtk_GtkTextComponentPeer.lo \ + gnu_java_awt_peer_gtk_GtkButtonPeer.lo \ + gnu_java_awt_peer_gtk_GtkListPeer.lo \ + gnu_java_awt_peer_gtk_GtkTextFieldPeer.lo \ + gnu_java_awt_peer_gtk_GtkCanvasPeer.lo \ + gnu_java_awt_peer_gtk_GtkMainThread.lo \ + gnu_java_awt_peer_gtk_GtkToolkit.lo \ + gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.lo \ + gnu_java_awt_peer_gtk_GtkMenuBarPeer.lo \ + gnu_java_awt_peer_gtk_GtkWindowPeer.lo \ + gnu_java_awt_peer_gtk_GtkCheckboxPeer.lo \ + gnu_java_awt_peer_gtk_GtkMenuItemPeer.lo \ + gnu_java_awt_peer_gtk_GtkChoicePeer.lo \ + gnu_java_awt_peer_gtk_GtkMenuPeer.lo \ + gnu_java_awt_peer_gtk_GtkClipboard.lo \ + gnu_java_awt_peer_gtk_GtkPanelPeer.lo \ + gnu_java_awt_peer_gtk_GtkComponentPeer.lo \ + gnu_java_awt_peer_gtk_GtkPopupMenuPeer.lo \ + gnu_java_awt_peer_gtk_GtkEvents.lo \ + gnu_java_awt_peer_gtk_GtkScrollBarPeer.lo +libgtkpeer_la_OBJECTS = $(am_libgtkpeer_la_OBJECTS) + +DEFS = @DEFS@ +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +@AMDEP_TRUE@DEP_FILES = \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GdkFontMetrics.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GdkGraphics.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkButtonPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkCanvasPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkCheckboxPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkChoicePeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkClipboard.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkComponentPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkEvents.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkFileDialogPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkImagePainter.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkLabelPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkListPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkMainThread.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkMenuBarPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkMenuItemPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkMenuPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkPanelPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkScrollBarPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkScrollPanePeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkTextAreaPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkTextComponentPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkTextFieldPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkToolkit.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gnu_java_awt_peer_gtk_GtkWindowPeer.Plo \ +@AMDEP_TRUE@ $(DEPDIR)/gthread-jni.Plo +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \ + $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +CFLAGS = @CFLAGS@ +DIST_SOURCES = $(libgtkpeer_la_SOURCES) +DIST_COMMON = Makefile.am Makefile.in +SOURCES = $(libgtkpeer_la_SOURCES) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu native/jni/gtk-peer/Makefile +Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && \ + CONFIG_HEADERS= CONFIG_LINKS= \ + CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(pkglibdir) + @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(LIBTOOL) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(pkglibdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(pkglibdir)/$$p; \ + else :; fi; \ + done + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ + echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p"; \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) +libgtkpeer.la: $(libgtkpeer_la_OBJECTS) $(libgtkpeer_la_DEPENDENCIES) + $(LINK) -rpath $(pkglibdir) $(libgtkpeer_la_LDFLAGS) $(libgtkpeer_la_OBJECTS) $(libgtkpeer_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GdkFontMetrics.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GdkGraphics.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkButtonPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkCanvasPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkCheckboxPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkChoicePeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkClipboard.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkComponentPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkEvents.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkFileDialogPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkImagePainter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkLabelPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkListPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkMainThread.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkMenuBarPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkMenuItemPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkMenuPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkPanelPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkScrollBarPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkScrollPanePeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkTextAreaPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkTextComponentPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkTextFieldPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkToolkit.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gnu_java_awt_peer_gtk_GtkWindowPeer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gthread-jni.Plo@am__quote@ + +distclean-depend: + -rm -rf $(DEPDIR) + +.c.o: +@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(COMPILE) -c `test -f $< || echo '$(srcdir)/'`$< + +.c.obj: +@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(COMPILE) -c `cygpath -w $<` + +.c.lo: +@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ + $(LTCOMPILE) -c -o $@ `test -f $< || echo '$(srcdir)/'`$< +CCDEPMODE = @CCDEPMODE@ +uninstall-info-am: + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || etags $(ETAGS_ARGS) $$tags $$unique $(LISP) + +GTAGS: + here=`CDPATH=: && cd $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH + +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = ../../.. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + $(mkinstalldirs) "$(distdir)/$$dir"; \ + fi; \ + if test -d $$d/$$file; then \ + cp -pR $$d/$$file $(distdir) \ + || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) + +installdirs: + $(mkinstalldirs) $(DESTDIR)$(pkglibdir) + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]* + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +uninstall-am: uninstall-info-am uninstall-pkglibLTLIBRARIES + +.PHONY: GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pkglibLTLIBRARIES distclean \ + distclean-compile distclean-depend distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am info \ + info-am install install-am install-data install-data-am \ + install-exec install-exec-am install-info install-info-am \ + install-man install-pkglibLTLIBRARIES install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool tags uninstall \ + uninstall-am uninstall-info-am uninstall-pkglibLTLIBRARIES + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/native/jni/awt/gnu_java_awt_image_GdkPixbufDecoder.c b/native/jni/gtk-peer/gnu_java_awt_image_GdkPixbufDecoder.c index 37a977f81..37a977f81 100644 --- a/native/jni/awt/gnu_java_awt_image_GdkPixbufDecoder.c +++ b/native/jni/gtk-peer/gnu_java_awt_image_GdkPixbufDecoder.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GdkFontMetrics.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c index 282fc60aa..282fc60aa 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GdkFontMetrics.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GdkGraphics.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c index 5acf96841..5acf96841 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GdkGraphics.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkButtonPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c index 7f0a96cc6..7f0a96cc6 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkButtonPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkCanvasPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c index 14dcba6eb..14dcba6eb 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkCanvasPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c index 5ea22801c..5ea22801c 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c index f35e57a09..f35e57a09 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkChoicePeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c index 9bb27616e..9bb27616e 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkChoicePeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkClipboard.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c index c64edb96e..c64edb96e 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkClipboard.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkComponentPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c index f675923ef..f675923ef 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkComponentPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkEvents.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c index dfd8f232a..dfd8f232a 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkEvents.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c index d952aa1fd..d952aa1fd 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkImagePainter.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.c index 2482664a5..2482664a5 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkImagePainter.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkLabelPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c index ad78039e6..ad78039e6 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkLabelPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkListPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c index 31534f5d9..31534f5d9 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkListPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkMainThread.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c index d7e8ffa39..d7e8ffa39 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkMainThread.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c index 40ad3abdf..40ad3abdf 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c index f4956a187..f4956a187 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkMenuPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c index 49c91b611..49c91b611 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkMenuPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkPanelPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c index 6ed2058e3..6ed2058e3 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkPanelPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c index fba683c04..fba683c04 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c index e6d2f073d..e6d2f073d 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c index b69706331..b69706331 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c index 04e6460d4..04e6460d4 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c index 2d292bc91..2d292bc91 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextComponentPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c index 3934cabdb..3934cabdb 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkToolkit.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c index 1a9902726..1a9902726 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkToolkit.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c diff --git a/native/jni/awt/gnu_java_awt_peer_gtk_GtkWindowPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c index 86c99f9c0..86c99f9c0 100644 --- a/native/jni/awt/gnu_java_awt_peer_gtk_GtkWindowPeer.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c diff --git a/native/jni/awt/gthread-jni.c b/native/jni/gtk-peer/gthread-jni.c index bc8aa5292..bc8aa5292 100644 --- a/native/jni/awt/gthread-jni.c +++ b/native/jni/gtk-peer/gthread-jni.c diff --git a/native/jni/awt/gthread-jni.h b/native/jni/gtk-peer/gthread-jni.h index f5cb762a7..f5cb762a7 100644 --- a/native/jni/awt/gthread-jni.h +++ b/native/jni/gtk-peer/gthread-jni.h diff --git a/native/jni/awt/gtkpeer.h b/native/jni/gtk-peer/gtkpeer.h index 33cdd3278..33cdd3278 100644 --- a/native/jni/awt/gtkpeer.h +++ b/native/jni/gtk-peer/gtkpeer.h diff --git a/native/jni/java-io/.cvsignore b/native/jni/java-io/.cvsignore new file mode 100644 index 000000000..e9f2658a6 --- /dev/null +++ b/native/jni/java-io/.cvsignore @@ -0,0 +1,8 @@ +*.o +*.a +*.lo +*.la +.libs +.deps +Makefile +Makefile.in diff --git a/native/jni/java_io_File.c b/native/jni/java-io/java_io_File.c index 98202d257..1c2760327 100644 --- a/native/jni/java_io_File.c +++ b/native/jni/java-io/java_io_File.c @@ -37,6 +37,7 @@ executable file might be covered by the GNU General Public License. */ #include <dirent.h> #include <jni.h> +#include <jcl.h> #include "javaio.h" #include "java_io_File.h" @@ -53,7 +54,7 @@ Java_java_io_File_createInternal(JNIEnv *env, jclass clazz, jstring name) const char *fname; int fd; - fname = _javaio_jstring_to_cstring(env, name); + fname = JCL_jstring_to_cstring(env, name); if (!fname) return(0); @@ -61,7 +62,7 @@ Java_java_io_File_createInternal(JNIEnv *env, jclass clazz, jstring name) if (fd == -1) { if (errno != EEXIST) - _javaio_ThrowException(env, "java/io/IOException", strerror(errno)); + JCL_ThrowException(env, "java/io/IOException", strerror(errno)); return(0); } @@ -473,7 +474,7 @@ Java_java_io_File_listInternal(JNIEnv *env, jobject obj, jstring name) return(0); /* Read the files from the directory */ - filelist = (char **)_javaio_malloc(env, sizeof(char *) * realloc_size); + filelist = (char **)JCL_malloc(env, sizeof(char *) * realloc_size); //filelist = (char **)malloc(sizeof(char *) * realloc_size); dir = opendir(dirname); (*env)->ReleaseStringUTFChars(env, name, dirname); @@ -494,7 +495,7 @@ Java_java_io_File_listInternal(JNIEnv *env, jobject obj, jstring name) { char **newlist; - newlist = _javaio_realloc(env, filelist, ((i + 1) + realloc_size) * + newlist = JCL_realloc(env, filelist, ((i + 1) + realloc_size) * sizeof(char *)); //newlist = realloc(filelist, (i + 1) + realloc_size); if (!filelist) diff --git a/native/jni/java_io_FileDescriptor.c b/native/jni/java-io/java_io_FileDescriptor.c index 4b5f9ffa6..acab74a97 100644 --- a/native/jni/java_io_FileDescriptor.c +++ b/native/jni/java-io/java_io_FileDescriptor.c @@ -33,6 +33,7 @@ executable file might be covered by the GNU General Public License. */ #include <unistd.h> #include <jni.h> +#include <jcl.h> #include "java_io_FileDescriptor.h" #include "javaio.h" @@ -49,7 +50,7 @@ Java_java_io_FileDescriptor_syncInternal(JNIEnv *env, jobject obj, jint fd) rc = fsync(fd); if (rc == -1) - _javaio_ThrowException(env, "java/io/IOException", strerror(errno)); + JCL_ThrowException(env, "java/io/IOException", strerror(errno)); } /*************************************************************************/ diff --git a/native/jni/java_io_FileInputStream.c b/native/jni/java-io/java_io_FileInputStream.c index 6f5f5038f..38c612dd1 100644 --- a/native/jni/java_io_FileInputStream.c +++ b/native/jni/java-io/java_io_FileInputStream.c @@ -33,7 +33,7 @@ executable file might be covered by the GNU General Public License. */ #include <unistd.h> #include <jni.h> - +#include <jcl.h> #include "javaio.h" #include "java_io_FileInputStream.h" diff --git a/native/jni/java_io_FileOutputStream.c b/native/jni/java-io/java_io_FileOutputStream.c index 759bcadce..0cddb3006 100644 --- a/native/jni/java_io_FileOutputStream.c +++ b/native/jni/java-io/java_io_FileOutputStream.c @@ -33,7 +33,7 @@ executable file might be covered by the GNU General Public License. */ #include <unistd.h> #include <jni.h> - +#include <jcl.h> #include "javaio.h" #include "java_io_FileOutputStream.h" @@ -55,7 +55,7 @@ Java_java_io_FileOutputStream_open(JNIEnv *env, jobject obj, jstring name, int rc = lseek(fd, 0, SEEK_END); if (rc == -1) { - _javaio_ThrowException(env, "java/io/IOException", strerror(errno)); + JCL_ThrowException(env, "java/io/IOException", strerror(errno)); close(fd); return(-1); } diff --git a/native/jni/java_io_ObjectInputStream.c b/native/jni/java-io/java_io_ObjectInputStream.c index 0e86c80a9..c5dd5617a 100644 --- a/native/jni/java_io_ObjectInputStream.c +++ b/native/jni/java-io/java_io_ObjectInputStream.c @@ -29,7 +29,7 @@ executable file might be covered by the GNU General Public License. */ /* comments */ #include <jni.h> -#include "javaio.h" +#include <jcl.h> #include "java_io_ObjectInputStream.h" JNIEXPORT jobject JNICALL @@ -99,7 +99,7 @@ Java_java_io_ObjectInputStream_setBooleanField( JNIEnv * env, jboolean val ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) return; @@ -107,7 +107,7 @@ Java_java_io_ObjectInputStream_setBooleanField( JNIEnv * env, id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "Z" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) return; @@ -124,7 +124,7 @@ Java_java_io_ObjectInputStream_setByteField( JNIEnv * env, jbyte val ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) return; @@ -132,7 +132,7 @@ Java_java_io_ObjectInputStream_setByteField( JNIEnv * env, id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "B" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) return; @@ -149,7 +149,7 @@ Java_java_io_ObjectInputStream_setCharField( JNIEnv * env, jchar val ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) return; @@ -157,7 +157,7 @@ Java_java_io_ObjectInputStream_setCharField( JNIEnv * env, id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "C" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) return; @@ -174,7 +174,7 @@ Java_java_io_ObjectInputStream_setDoubleField( JNIEnv * env, jdouble val ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) return; @@ -182,7 +182,7 @@ Java_java_io_ObjectInputStream_setDoubleField( JNIEnv * env, id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "D" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) return; @@ -199,7 +199,7 @@ Java_java_io_ObjectInputStream_setFloatField( JNIEnv * env, jfloat val ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) return; @@ -207,7 +207,7 @@ Java_java_io_ObjectInputStream_setFloatField( JNIEnv * env, id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "F" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) return; @@ -224,7 +224,7 @@ Java_java_io_ObjectInputStream_setIntField( JNIEnv * env, jint val ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) return; @@ -232,7 +232,7 @@ Java_java_io_ObjectInputStream_setIntField( JNIEnv * env, id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "I" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) return; @@ -249,7 +249,7 @@ Java_java_io_ObjectInputStream_setLongField( JNIEnv * env, jlong val ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) return; @@ -257,7 +257,7 @@ Java_java_io_ObjectInputStream_setLongField( JNIEnv * env, id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "J" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) return; @@ -274,7 +274,7 @@ Java_java_io_ObjectInputStream_setShortField( JNIEnv * env, jshort val ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) return; @@ -282,7 +282,7 @@ Java_java_io_ObjectInputStream_setShortField( JNIEnv * env, id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "S" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) return; @@ -303,24 +303,24 @@ Java_java_io_ObjectInputStream_setObjectField( JNIEnv * env, char * name_cstr; char * type_cstr; - name_cstr = _javaio_jstring_to_cstring( env, field_name ); + name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) return; - type_cstr = _javaio_jstring_to_cstring( env, type_code ); + type_cstr = JCL_jstring_to_cstring( env, type_code ); if( type_cstr == NULL ) { - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); return; } id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, type_cstr ); - _javaio_free_cstring( env, field_name, name_cstr ); - _javaio_free_cstring( env, type_code, type_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, type_code, type_cstr ); if( id == NULL ) return; diff --git a/native/jni/java_io_ObjectOutputStream.c b/native/jni/java-io/java_io_ObjectOutputStream.c index bf4238d60..1c6d2c4be 100644 --- a/native/jni/java_io_ObjectOutputStream.c +++ b/native/jni/java-io/java_io_ObjectOutputStream.c @@ -30,8 +30,7 @@ executable file might be covered by the GNU General Public License. */ /* comments */ #include <jni.h> - -#include "javaio.h" +#include <jcl.h> #include "java_io_ObjectOutputStream.h" @@ -69,20 +68,20 @@ Java_java_io_ObjectOutputStream_getBooleanField( JNIEnv * env, jstring field_name ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) /* Exception was thrown, so value is arbitrary */ - return FALSE; + return JNI_FALSE; id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "Z" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) /* Exception was thrown, so value is arbitrary */ - return FALSE; + return JNI_FALSE; return (*env)->GetBooleanField( env, obj, id ); } @@ -95,7 +94,7 @@ Java_java_io_ObjectOutputStream_getByteField( JNIEnv * env, jstring field_name ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) /* Exception was thrown, so value is arbitrary */ @@ -104,7 +103,7 @@ Java_java_io_ObjectOutputStream_getByteField( JNIEnv * env, id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "B" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) /* Exception was thrown, so value is arbitrary */ @@ -121,7 +120,7 @@ Java_java_io_ObjectOutputStream_getCharField( JNIEnv * env, jstring field_name ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) /* Exception was thrown, so value is arbitrary */ @@ -130,7 +129,7 @@ Java_java_io_ObjectOutputStream_getCharField( JNIEnv * env, id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "C" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) /* Exception was thrown, so value is arbitrary */ @@ -147,7 +146,7 @@ Java_java_io_ObjectOutputStream_getDoubleField( JNIEnv * env, jstring field_name ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) /* Exception was thrown, so value is arbitrary */ @@ -156,7 +155,7 @@ Java_java_io_ObjectOutputStream_getDoubleField( JNIEnv * env, id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "D" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) /* Exception was thrown, so value is arbitrary */ @@ -173,7 +172,7 @@ Java_java_io_ObjectOutputStream_getFloatField( JNIEnv * env, jstring field_name ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) /* Exception was thrown, so value is arbitrary */ @@ -182,7 +181,7 @@ Java_java_io_ObjectOutputStream_getFloatField( JNIEnv * env, id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "F" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) /* Exception was thrown, so value is arbitrary */ @@ -199,7 +198,7 @@ Java_java_io_ObjectOutputStream_getIntField( JNIEnv * env, jstring field_name ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) /* Exception was thrown, so value is arbitrary */ @@ -208,7 +207,7 @@ Java_java_io_ObjectOutputStream_getIntField( JNIEnv * env, id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "I" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) /* Exception was thrown, so value is arbitrary */ @@ -225,7 +224,7 @@ Java_java_io_ObjectOutputStream_getLongField( JNIEnv * env, jstring field_name ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) /* Exception was thrown, so value is arbitrary */ @@ -234,7 +233,7 @@ Java_java_io_ObjectOutputStream_getLongField( JNIEnv * env, id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "J" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) /* Exception was thrown, so value is arbitrary */ @@ -251,7 +250,7 @@ Java_java_io_ObjectOutputStream_getShortField( JNIEnv * env, jstring field_name ) { jfieldID id; - char * name_cstr = _javaio_jstring_to_cstring( env, field_name ); + char * name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) /* Exception was thrown, so value is arbitrary */ @@ -260,7 +259,7 @@ Java_java_io_ObjectOutputStream_getShortField( JNIEnv * env, id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, "S" ); - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); if( id == NULL ) /* Exception was thrown, so value is arbitrary */ @@ -281,25 +280,25 @@ Java_java_io_ObjectOutputStream_getObjectField( JNIEnv * env, char * name_cstr; char * type_cstr; - name_cstr = _javaio_jstring_to_cstring( env, field_name ); + name_cstr = JCL_jstring_to_cstring( env, field_name ); if( name_cstr == NULL ) /* Exception was thrown, so value is arbitrary */ return NULL; - type_cstr = _javaio_jstring_to_cstring( env, type_code ); + type_cstr = JCL_jstring_to_cstring( env, type_code ); if( type_cstr == NULL ) { - _javaio_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); return NULL; } id = (*env)->GetFieldID( env, (*env)->GetObjectClass( env, obj ), name_cstr, type_cstr ); - _javaio_free_cstring( env, field_name, name_cstr ); - _javaio_free_cstring( env, type_code, type_cstr ); + JCL_free_cstring( env, field_name, name_cstr ); + JCL_free_cstring( env, type_code, type_cstr ); if( id == NULL ) /* Exception was thrown, so value is arbitrary */ diff --git a/native/jni/java_io_RandomAccessFile.c b/native/jni/java-io/java_io_RandomAccessFile.c index ef028017f..974a81f7c 100644 --- a/native/jni/java_io_RandomAccessFile.c +++ b/native/jni/java-io/java_io_RandomAccessFile.c @@ -33,7 +33,7 @@ executable file might be covered by the GNU General Public License. */ #include <unistd.h> #include <jni.h> - +#include <jcl.h> #include "java_io_RandomAccessFile.h" #include "javaio.h" @@ -129,7 +129,7 @@ Java_java_io_RandomAccessFile_getFilePointerInternal(JNIEnv *env, jobject obj, { int rc = lseek(fd, 0, SEEK_CUR); if (rc == -1) - _javaio_ThrowException(env, "java/io/IOException", strerror(errno)); + JCL_ThrowException(env, "java/io/IOException", strerror(errno)); return(rc); } @@ -146,7 +146,7 @@ Java_java_io_RandomAccessFile_seekInternal(JNIEnv *env, jobject obj, { int rc = lseek(fd, pos, SEEK_SET); if (rc == -1) - _javaio_ThrowException(env, "java/io/IOException", strerror(errno)); + JCL_ThrowException(env, "java/io/IOException", strerror(errno)); } /*************************************************************************/ @@ -175,6 +175,6 @@ Java_java_io_RandomAccessFile_setLengthInternal(JNIEnv *env, jobject obj, return; if (rc == -1) - _javaio_ThrowException(env, "java/io/IOException", strerror(errno)); + JCL_ThrowException(env, "java/io/IOException", strerror(errno)); } diff --git a/native/jni/javaio.c b/native/jni/java-io/javaio.c index 95243bbfb..bc1db7290 100644 --- a/native/jni/javaio.c +++ b/native/jni/java-io/javaio.c @@ -39,100 +39,6 @@ executable file might be covered by the GNU General Public License. */ #include <malloc.h> -static char errstr[4098]; // this way the memory is pre-allocated, so that we do not have to worry if we are out of memory. - -JNIEXPORT void JNICALL _javaio_ThrowException(JNIEnv * env, char * className, char * errMsg) { - jclass excClass; - if((*env)->ExceptionOccurred(env)) { - (*env)->ExceptionClear(env); - } - excClass = (*env)->FindClass(env, className); - if(excClass == NULL) { - jclass errExcClass; - errExcClass = (*env)->FindClass(env, "java/lang/ClassNotFoundException"); - if(errExcClass == NULL) { - errExcClass = (*env)->FindClass(env, "java/lang/InternalError"); - if(errExcClass == NULL) { - sprintf(errstr,"JCL: Utterly failed to throw exeption %s with message %s.",className,errMsg); - fprintf(stderr, errstr); - return; - } - } - sprintf(errstr,"JCL: Failed to throw exception %s with message %s: could not find exception class.", className, errMsg); - (*env)->ThrowNew(env, errExcClass, errstr); - } - (*env)->ThrowNew(env, excClass, errMsg); -} - -JNIEXPORT void * JNICALL _javaio_malloc(JNIEnv * env, size_t size) { - void * mem = malloc(size); - if(mem == NULL) { - _javaio_ThrowException(env, "java/lang/OutOfMemoryError", "malloc() failed."); - return NULL; - } - return mem; -} - -JNIEXPORT void * JNICALL -_javaio_realloc(JNIEnv *env, void *ptr, size_t size) -{ - ptr = realloc(ptr, size); - if (ptr == 0) - { - _javaio_ThrowException(env, "java/lang/OutOfMemoryError", - "malloc() failed."); - return NULL; - } - return(ptr); -} - -JNIEXPORT void JNICALL _javaio_free(JNIEnv * env, void * p) { - if(p != NULL) - free(p); -} - -JNIEXPORT char * JNICALL _javaio_jstring_to_cstring(JNIEnv * env, jstring s) { - char* cstr; - if(s == NULL) { - _javaio_ThrowException(env, "java/lang/NullPointerException","Null string"); - return NULL; - } - cstr = (char*)(*env)->GetStringUTFChars(env, s, NULL); - if(cstr == NULL) { - _javaio_ThrowException(env, "java/lang/InternalError", "GetStringUTFChars() failed."); - return NULL; - } - return cstr; -} - -JNIEXPORT void JNICALL _javaio_free_cstring(JNIEnv * env, jstring s, char * cstr) { - (*env)->ReleaseStringUTFChars(env, s, cstr); -} - -JNIEXPORT jint JNICALL _javaio_MonitorEnter(JNIEnv * env, jobject o) { - jint retval = (*env)->MonitorEnter(env,o); - if(retval != 0) { - _javaio_ThrowException(env, "java/lang/InternalError", "MonitorEnter() failed."); - } - return retval; -} - -JNIEXPORT jint JNICALL _javaio_MonitorExit(JNIEnv * env, jobject o) { - jint retval = (*env)->MonitorExit(env,o); - if(retval != 0) { - _javaio_ThrowException(env, "java/lang/InternalError", "MonitorExit() failed."); - } - return retval; -} - -JNIEXPORT jclass JNICALL _javaio_FindClass(JNIEnv * env, char * className) { - jclass retval = (*env)->FindClass(env,className); - if(retval != NULL) { - _javaio_ThrowException(env, "java/lang/ClassNotFoundException", className); - } - return retval; -} - /* * Function to open a file */ diff --git a/native/jni/javalang.h b/native/jni/java-io/javaio.h index ce7d1f4d3..20deaf13c 100644 --- a/native/jni/javalang.h +++ b/native/jni/java-io/javaio.h @@ -1,4 +1,4 @@ -/* javalang.h - Declaration for common java.lang native functions +/* javaio.h - Declaration for common java.io native functions Copyright (C) 1998 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -25,34 +25,21 @@ This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ -#include <jni.h> +#ifndef JAVAIO_H_INCLUDED +#define JAVAIO_H_INCLUDED -#ifndef JAVALANG_H_INCLUDED -#define JAVALANG_H_INCLUDED +#include <stddef.h> /* * Function Prototypes */ -#ifdef __cplusplus -extern "C" { -#endif -JNIEXPORT void JNICALL _javalang_ThrowException(JNIEnv *, char *, char *); -JNIEXPORT void * JNICALL _javalang_malloc(JNIEnv *, size_t); -JNIEXPORT void * JNICALL _javalang_realloc(JNIEnv *, void *, size_t); -JNIEXPORT void JNICALL _javalang_free(JNIEnv *, void *); +extern jlong _javaio_get_file_length(JNIEnv *, jint); +extern jlong _javaio_skip_bytes(JNIEnv *, jint, jlong); +extern jint _javaio_open(JNIEnv *, jstring, int); +extern void _javaio_close(JNIEnv *, jint fd); +extern jint _javaio_read(JNIEnv *, jobject obj, jint, jarray, jint, jint); +extern jint _javaio_write(JNIEnv *, jobject obj, jint, jarray, jint, jint); -#ifdef __cplusplus -} -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#endif /* JAVALANG_H_INCLUDED */ +#endif /* JAVAIO_H_INCLUDED */ diff --git a/native/jni/java-lang/.cvsignore b/native/jni/java-lang/.cvsignore new file mode 100644 index 000000000..e9f2658a6 --- /dev/null +++ b/native/jni/java-lang/.cvsignore @@ -0,0 +1,8 @@ +*.o +*.a +*.lo +*.la +.libs +.deps +Makefile +Makefile.in diff --git a/native/jni/java_lang_Double.c b/native/jni/java-lang/java_lang_Double.c index c15ae05e7..cc1a702db 100644 --- a/native/jni/java_lang_Double.c +++ b/native/jni/java-lang/java_lang_Double.c @@ -256,4 +256,5 @@ JNIEXPORT jdouble JNICALL Java_java_lang_Double_parseDouble0 return val; } JCL_ThrowException(env, "java/lang/NumberFormatException", "unable to parse double"); + return 0.0; /* NumberFormatException already thrown */ } diff --git a/native/jni/java_lang_Float.c b/native/jni/java-lang/java_lang_Float.c index 3c93d6ce2..3c93d6ce2 100644 --- a/native/jni/java_lang_Float.c +++ b/native/jni/java-lang/java_lang_Float.c diff --git a/native/jni/java_lang_Object.c b/native/jni/java-lang/java_lang_Object.c index 67caa6ca3..67caa6ca3 100644 --- a/native/jni/java_lang_Object.c +++ b/native/jni/java-lang/java_lang_Object.c diff --git a/native/jni/java_lang_System.c b/native/jni/java-lang/java_lang_System.c index cfea6989a..cfea6989a 100644 --- a/native/jni/java_lang_System.c +++ b/native/jni/java-lang/java_lang_System.c diff --git a/native/jni/java_lang_reflect_Array.c b/native/jni/java-lang/java_lang_reflect_Array.c index e72453517..e72453517 100644 --- a/native/jni/java_lang_reflect_Array.c +++ b/native/jni/java-lang/java_lang_reflect_Array.c diff --git a/native/jni/java-net/.cvsignore b/native/jni/java-net/.cvsignore new file mode 100644 index 000000000..e9f2658a6 --- /dev/null +++ b/native/jni/java-net/.cvsignore @@ -0,0 +1,8 @@ +*.o +*.a +*.lo +*.la +.libs +.deps +Makefile +Makefile.in diff --git a/native/jni/java_net_InetAddress.c b/native/jni/java-net/java_net_InetAddress.c index 2304bdb02..a82e0b925 100644 --- a/native/jni/java_net_InetAddress.c +++ b/native/jni/java-net/java_net_InetAddress.c @@ -34,6 +34,7 @@ executable file might be covered by the GNU General Public License. */ #include <netinet/in.h> #include <jni.h> +#include <jcl.h> #include "java_net_InetAddress.h" @@ -72,8 +73,10 @@ Java_java_net_InetAddress_lookupInaddrAny(JNIEnv *env, jclass class) /* Allocate an array for the IP address */ arr = (*env)->NewIntArray(env, 4); if (!arr) - return (jarray) _javanet_throw_exception(env, UNKNOWN_HOST_EXCEPTION, - "Internal Error"); + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + return (jarray)NULL; + } /* Copy in the values */ octets = (*env)->GetIntArrayElements(env, arr, 0); @@ -106,13 +109,17 @@ Java_java_net_InetAddress_getHostByAddr(JNIEnv *env, jclass class, jarray arr) /* Grab the byte[] array with the IP out of the input data */ len = (*env)->GetArrayLength(env, arr); if (len != 4) - return (jstring)_javanet_throw_exception(env, UNKNOWN_HOST_EXCEPTION, - "Bad IP Address"); + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address"); + return (jstring)NULL; + } octets = (*env)->GetIntArrayElements(env, arr, 0); if (!octets) - return (jstring) _javanet_throw_exception(env, UNKNOWN_HOST_EXCEPTION, - "Bad IP Address"); + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address"); + return (jstring)NULL; + } /* Convert it to a 32 bit address */ addr = (octets[0] << 24) + (octets[1] << 16) + (octets[2] << 8) + octets[3]; @@ -124,8 +131,10 @@ Java_java_net_InetAddress_getHostByAddr(JNIEnv *env, jclass class, jarray arr) /* Resolve the address and return the name */ hp = gethostbyaddr((char*)&addr, sizeof(addr), AF_INET); if (!hp) - return (jstring) _javanet_throw_exception(env, UNKNOWN_HOST_EXCEPTION, - "Bad IP Address"); + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address"); + return (jstring)NULL; + } retval = (*env)->NewStringUTF(env, hp->h_name); @@ -148,14 +157,18 @@ Java_java_net_InetAddress_getHostByName(JNIEnv *env, jclass class, jstring host) /* Grab the hostname string */ hostname = (*env)->GetStringUTFChars(env, host, 0); if (!hostname) - return (jobjectArray) _javanet_throw_exception(env, UNKNOWN_HOST_EXCEPTION, - "Null hostname"); + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Null hostname"); + return (jobjectArray)NULL; + } /* Look up the host */ hp = gethostbyname(hostname); if (!hp) - return (jobjectArray) _javanet_throw_exception(env, UNKNOWN_HOST_EXCEPTION, - hostname); + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, hostname); + return (jobjectArray)NULL; + } (*env)->ReleaseStringUTFChars(env, host, hostname); /* Figure out how many addresses there are and allocate a return array */ @@ -164,21 +177,27 @@ Java_java_net_InetAddress_getHostByName(JNIEnv *env, jclass class, jstring host) arr_class = (*env)->FindClass(env,"[I"); if (!arr_class) - return (jobjectArray) _javanet_throw_exception(env, UNKNOWN_HOST_EXCEPTION, - "Internal Error"); + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + return (jobjectArray)NULL; + } addrs = (*env)->NewObjectArray(env, num_addrs, arr_class, 0); if (!addrs) - return (jobjectArray) _javanet_throw_exception(env, UNKNOWN_HOST_EXCEPTION, - "Internal Error"); + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + return (jobjectArray)NULL; + } /* Now loop and copy in each address */ for (i = 0; i < num_addrs; i++) { ret_octets = (*env)->NewIntArray(env, 4); if (!ret_octets) - return (jobjectArray) _javanet_throw_exception(env, UNKNOWN_HOST_EXCEPTION, - "Internal Error"); + { + JCL_ThrowException(env, UNKNOWN_HOST_EXCEPTION, "Internal Error"); + return (jobjectArray)NULL; + } octets = (*env)->GetIntArrayElements(env, ret_octets, 0); diff --git a/native/jni/java_net_PlainDatagramSocketImpl.c b/native/jni/java-net/java_net_PlainDatagramSocketImpl.c index b05043659..4de3661cb 100644 --- a/native/jni/java_net_PlainDatagramSocketImpl.c +++ b/native/jni/java-net/java_net_PlainDatagramSocketImpl.c @@ -34,6 +34,7 @@ executable file might be covered by the GNU General Public License. */ #include <netinet/in.h> #include <jni.h> +#include <jcl.h> #include "java_net_PlainDatagramSocketImpl.h" @@ -126,18 +127,18 @@ Java_java_net_PlainDatagramSocketImpl_receive(JNIEnv *env, jobject this, cls = (*env)->GetObjectClass(env, packet); mid = (*env)->GetMethodID(env, cls, "getData", "()[B"); if (!mid) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } arr = (*env)->CallObjectMethod(env, packet, mid); if (!arr) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } /* Now get the length from the packet */ mid = (*env)->GetMethodID(env, cls, "getLength", "()I"); if (!mid) { (*env)->ReleaseByteArrayElements(env, arr, buf, 0); - _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); + JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } len = (*env)->CallIntMethod(env, packet, mid); @@ -163,13 +164,13 @@ Java_java_net_PlainDatagramSocketImpl_receive(JNIEnv *env, jobject this, addr_cls = (*env)->FindClass(env, "java/net/InetAddress"); if (!addr_cls) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } DBG("Found InetAddress class\n"); mid = (*env)->GetStaticMethodID(env, addr_cls, "getByName", "(Ljava/lang/String;)Ljava/net/InetAddress;"); if (!mid) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } DBG("Found InetAddress.getByName method\n"); addr_obj = (*env)->CallStaticObjectMethod(env, addr_cls, mid, ip_str_obj); @@ -177,7 +178,7 @@ Java_java_net_PlainDatagramSocketImpl_receive(JNIEnv *env, jobject this, mid = (*env)->GetMethodID(env, cls, "setAddress", "(Ljava/net/InetAddress;)V"); if (!mid) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } (*env)->CallVoidMethod(env, packet, mid, addr_obj); DBG("Stored the address\n"); @@ -186,7 +187,7 @@ Java_java_net_PlainDatagramSocketImpl_receive(JNIEnv *env, jobject this, mid = (*env)->GetMethodID(env, cls, "setPort", "(I)V"); if (!mid) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } (*env)->CallVoidMethod(env, packet, mid, port); DBG("Stored the port\n"); @@ -194,7 +195,7 @@ Java_java_net_PlainDatagramSocketImpl_receive(JNIEnv *env, jobject this, /* Store back the length */ mid = (*env)->GetMethodID(env, cls, "setLength", "(I)V"); if (!mid) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } (*env)->CallVoidMethod(env, packet, mid, bytes_read); DBG("Stored the length\n"); @@ -236,7 +237,7 @@ Java_java_net_PlainDatagramSocketImpl_join(JNIEnv *env, jobject this, IPPROTO_IP, IP_ADD_MEMBERSHIP, &ipm, sizeof(ipm)); if (rc == -1) - _javanet_throw_exception(env, IO_EXCEPTION, strerror(errno)); + JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); } /*************************************************************************/ @@ -259,7 +260,7 @@ Java_java_net_PlainDatagramSocketImpl_leave(JNIEnv *env, jobject this, IPPROTO_IP, IP_DROP_MEMBERSHIP, &ipm, sizeof(ipm)); if (rc == -1) - _javanet_throw_exception(env, IO_EXCEPTION, strerror(errno)); + JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); } diff --git a/native/jni/java_net_PlainSocketImpl.c b/native/jni/java-net/java_net_PlainSocketImpl.c index 4575cb086..4575cb086 100644 --- a/native/jni/java_net_PlainSocketImpl.c +++ b/native/jni/java-net/java_net_PlainSocketImpl.c diff --git a/native/jni/javanet.c b/native/jni/java-net/javanet.c index c5cdf90ea..49261edf9 100644 --- a/native/jni/javanet.c +++ b/native/jni/java-net/javanet.c @@ -36,6 +36,7 @@ executable file might be covered by the GNU General Public License. */ #include <netinet/tcp.h> #include <jni.h> +#include <jcl.h> #include "javanet.h" @@ -52,31 +53,6 @@ executable file might be covered by the GNU General Public License. */ /*************************************************************************/ /* - * This is a common function to throw exceptions. - */ -int -_javanet_throw_exception(JNIEnv *env, const char *exception, const char *msg) -{ - jclass ecls; - - /* Find our exception class */ - ecls = (*env)->FindClass(env, exception); - if (!ecls) - return(0); - - /* Clean any pending exceptions */ - if ((*env)->ExceptionOccurred(env)) - (*env)->ExceptionClear(env); - - /* Throw the exception and return */ - (*env)->ThrowNew(env, ecls, msg); - - return(0); -} - -/*************************************************************************/ - -/* * Sets an integer field in the specified object. */ static void @@ -143,26 +119,26 @@ _javanet_create_localfd(JNIEnv *env, jobject this) this_cls = (*env)->FindClass(env, "java/net/SocketImpl"); fid = (*env)->GetFieldID(env, this_cls, "fd", "Ljava/io/FileDescriptor;"); if (!fid) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } DBG("Found fd variable\n"); /* Create a FileDescriptor */ fd_cls = (*env)->FindClass(env, "java/io/FileDescriptor"); if (!fd_cls) { - _javanet_throw_exception(env, IO_EXCEPTION, "Can't load FileDescriptor class"); + JCL_ThrowException(env, IO_EXCEPTION, "Can't load FileDescriptor class"); return; } DBG("Found FileDescriptor class\n"); mid = (*env)->GetMethodID(env, fd_cls, "<init>", "()V"); if (!mid) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } DBG("Found FileDescriptor constructor\n"); fd_obj = (*env)->NewObject(env, fd_cls, mid); if (!fd_obj) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } DBG("Created FileDescriptor\n"); /* Now set the pointer to the new FileDescriptor */ @@ -186,15 +162,15 @@ _javanet_create_boolean(JNIEnv *env, jboolean val) cls = (*env)->FindClass(env, "java/lang/Boolean"); if (!cls) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return(0); } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return(0); } mid = (*env)->GetMethodID(env, cls, "<init>", "(Z)V"); if (!mid) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return(0); } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return(0); } obj = (*env)->NewObject(env, cls, mid, val); if (!obj) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return(0); } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return(0); } return(obj); } @@ -213,15 +189,15 @@ _javanet_create_integer(JNIEnv *env, jint val) cls = (*env)->FindClass(env, "java/lang/Integer"); if (!cls) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return(0); } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return(0); } mid = (*env)->GetMethodID(env, cls, "<init>", "(I)V"); if (!mid) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return(0); } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return(0); } obj = (*env)->NewObject(env, cls, mid, val); if (!obj) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return(0); } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return(0); } return(obj); } @@ -250,7 +226,7 @@ _javanet_create_inetaddress(JNIEnv *env, int netaddr) ia_cls = (*env)->FindClass(env, "java/net/InetAddress"); if (!ia_cls) { - _javanet_throw_exception(env, IO_EXCEPTION, "Can't load InetAddress class"); + JCL_ThrowException(env, IO_EXCEPTION, "Can't load InetAddress class"); return(0); } DBG("Found InetAddress class\n"); @@ -258,16 +234,16 @@ _javanet_create_inetaddress(JNIEnv *env, int netaddr) mid = (*env)->GetStaticMethodID(env, ia_cls, "getByName", "(Ljava/lang/String;)Ljava/net/InetAddress;"); if (!mid) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return(0); } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return(0); } DBG("Found getByName method\n"); ip_str = (*env)->NewStringUTF(env, buf); if (!ip_str) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return(0); } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return(0); } ia = (*env)->CallStaticObjectMethod(env, ia_cls, mid, ip_str); if (!ia) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return(0); } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return(0); } DBG("Called getByName method\n"); return(ia); @@ -297,7 +273,7 @@ _javanet_set_remhost(JNIEnv *env, jobject this, int netaddr) this_cls = (*env)->FindClass(env, "java/net/SocketImpl"); fid = (*env)->GetFieldID(env, this_cls, "address", "Ljava/net/InetAddress;"); if (!fid) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } DBG("Found address field\n"); (*env)->SetObjectField(env, this, fid, ia); @@ -324,23 +300,35 @@ _javanet_get_netaddr(JNIEnv *env, jobject addr) cls = (*env)->GetObjectClass(env, addr); mid = (*env)->GetMethodID(env, cls, "getAddress", "()[B"); if (!mid) - return(_javanet_throw_exception(env, IO_EXCEPTION, "Internal Error")); + { + JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); + return(0); + } DBG("Got getAddress method\n"); arr = (*env)->CallObjectMethod(env, addr, mid); if (!arr) - return(_javanet_throw_exception(env, IO_EXCEPTION, "Internal Error")); + { + JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); + return(0); + } DBG("Got the address\n"); /* Turn the IP address into a 32 bit Internet address in network byte order */ len = (*env)->GetArrayLength(env, arr); if (len != 4) - return(_javanet_throw_exception(env, IO_EXCEPTION, "Internal Error")); + { + JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); + return(0); + } DBG("Length ok\n"); octets = (*env)->GetByteArrayElements(env, arr, 0); if (!octets) - return(_javanet_throw_exception(env, IO_EXCEPTION, "Internal Error")); + { + JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); + return(0); + } DBG("Grabbed bytes\n"); netaddr = (((unsigned char)octets[0]) << 24) + @@ -372,7 +360,7 @@ _javanet_create(JNIEnv *env, jobject this, jboolean stream) fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) - { _javanet_throw_exception(env, IO_EXCEPTION, strerror(errno)); return; } + { JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); return; } if (stream) _javanet_set_int_field(env, this, "java/net/PlainSocketImpl", @@ -432,7 +420,7 @@ _javanet_connect(JNIEnv *env, jobject this, jobject addr, jint port) /* Grab the real socket file descriptor */ fd = _javanet_get_int_field(env, this, "native_fd"); if (fd == -1) - { _javanet_throw_exception(env, IO_EXCEPTION, + { JCL_ThrowException(env, IO_EXCEPTION, "Socket not yet created"); return; } DBG("Got native fd\n"); @@ -444,7 +432,7 @@ _javanet_connect(JNIEnv *env, jobject this, jobject addr, jint port) rc = connect(fd, (struct sockaddr *) &si, sizeof(struct sockaddr_in)); if (rc == -1) - { _javanet_throw_exception(env, IO_EXCEPTION, strerror(errno)); return; } + { JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); return; } DBG("Connected successfully\n"); /* Populate instance variables */ @@ -453,7 +441,7 @@ _javanet_connect(JNIEnv *env, jobject this, jobject addr, jint port) if (rc == -1) { close(fd); - _javanet_throw_exception(env, IO_EXCEPTION, strerror(errno)); + JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); return; } @@ -473,7 +461,7 @@ _javanet_connect(JNIEnv *env, jobject this, jobject addr, jint port) if (rc == -1) { close(fd); - _javanet_throw_exception(env, IO_EXCEPTION, strerror(errno)); + JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); return; } @@ -513,17 +501,17 @@ _javanet_bind(JNIEnv *env, jobject this, jobject addr, jint port, int stream) cls = (*env)->GetObjectClass(env, addr); mid = (*env)->GetMethodID(env, cls, "getAddress", "()[B"); if (!mid) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal error") ; return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal error") ; return; } DBG("Past getAddress method id\n"); arr = (*env)->CallObjectMethod(env, addr, mid); if (!arr || (*env)->ExceptionOccurred(env)) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal error") ; return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal error") ; return; } DBG("Past call object method\n"); octets = (*env)->GetByteArrayElements(env, arr, 0); if (!octets) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal error") ; return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal error") ; return; } DBG("Past grab array\n"); /* Get the native socket file descriptor */ @@ -531,7 +519,7 @@ _javanet_bind(JNIEnv *env, jobject this, jobject addr, jint port, int stream) if (fd == -1) { (*env)->ReleaseByteArrayElements(env, arr, octets, 0); - _javanet_throw_exception(env, IO_EXCEPTION, "Internal error"); + JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } DBG("Past native_fd lookup\n"); @@ -549,7 +537,7 @@ _javanet_bind(JNIEnv *env, jobject this, jobject addr, jint port, int stream) (*env)->ReleaseByteArrayElements(env, arr, octets, 0); if (bind(fd, (struct sockaddr *) &si, sizeof(struct sockaddr_in)) == -1) - { _javanet_throw_exception(env, IO_EXCEPTION, strerror(errno)); return; } + { JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); return; } DBG("Past bind\n"); /* Update instance variables, specifically the local port number */ @@ -581,13 +569,13 @@ _javanet_listen(JNIEnv *env, jobject this, jint queuelen) /* Get the real file descriptor */ fd = _javanet_get_int_field(env, this, "native_fd"); if (fd == -1) - { _javanet_throw_exception(env, IO_EXCEPTION, + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } /* Start listening */ rc = listen(fd, queuelen); if (rc == -1) - { _javanet_throw_exception(env, IO_EXCEPTION, strerror(errno)); return; } + { JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); return; } return; } @@ -607,7 +595,7 @@ _javanet_accept(JNIEnv *env, jobject this, jobject impl) /* Get the real file descriptor */ fd = _javanet_get_int_field(env, this, "native_fd"); if (fd == -1) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } /* Accept the connection */ addrlen = sizeof(struct sockaddr_in); @@ -616,7 +604,7 @@ _javanet_accept(JNIEnv *env, jobject this, jobject impl) /******* Do we need to look for EINTR? */ newfd = accept(fd, (struct sockaddr *) &si, &addrlen); if (newfd == -1) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } /* Populate instance variables */ _javanet_set_int_field(env, impl, "java/net/PlainSocketImpl", "native_fd", @@ -626,7 +614,7 @@ _javanet_accept(JNIEnv *env, jobject this, jobject impl) if (rc == -1) { close(newfd); - _javanet_throw_exception(env, IO_EXCEPTION, strerror(errno)); + JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); return; } @@ -644,7 +632,7 @@ _javanet_accept(JNIEnv *env, jobject this, jobject impl) if (rc == -1) { close(newfd); - _javanet_throw_exception(env, IO_EXCEPTION, strerror(errno)); + JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); return; } @@ -687,13 +675,13 @@ _javanet_recvfrom(JNIEnv *env, jobject this, jarray buf, int offset, int len, /* Get the real file descriptor */ fd = _javanet_get_int_field(env, this, "native_fd"); if (fd == -1) - { return(_javanet_throw_exception(env, IO_EXCEPTION, "No Socket")); } + { JCL_ThrowException(env, IO_EXCEPTION, "No Socket"); return 0; } DBG("Got native_fd\n"); /* Get a pointer to the buffer */ p = (*env)->GetByteArrayElements(env, buf, 0); if (!p) - { return(_javanet_throw_exception(env, IO_EXCEPTION, "Internal Error")); } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return 0; } DBG("Got buffer\n"); /* Read the data */ @@ -717,7 +705,7 @@ _javanet_recvfrom(JNIEnv *env, jobject this, jarray buf, int offset, int len, (*env)->ReleaseByteArrayElements(env, buf, p, 0); if (rc == -1) - { return(_javanet_throw_exception(env, IO_EXCEPTION, strerror(errno))); } + { JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); return 0; } /* Handle return addr case */ if (addr) @@ -752,12 +740,12 @@ _javanet_sendto(JNIEnv *env, jobject this, jarray buf, int offset, int len, /* Get the real file descriptor */ fd = _javanet_get_int_field(env, this, "native_fd"); if (fd == -1) - { _javanet_throw_exception(env, IO_EXCEPTION, "No Socket"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "No Socket"); return; } /* Get a pointer to the buffer */ p = (*env)->GetByteArrayElements(env, buf, 0); if (!p) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } /* Send the data */ if (!addr) @@ -777,7 +765,7 @@ _javanet_sendto(JNIEnv *env, jobject this, jarray buf, int offset, int len, /***** Do we need to check EINTR? */ if (rc == -1) - { _javanet_throw_exception(env, IO_EXCEPTION, strerror(errno)); return; } + { JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); return; } return; } @@ -800,7 +788,7 @@ _javanet_set_option(JNIEnv *env, jobject this, jint option_id, jobject val) /* Get the real file descriptor */ fd = _javanet_get_int_field(env, this, "native_fd"); if (fd == -1) - { _javanet_throw_exception(env, IO_EXCEPTION, "Internal Error"); return; } + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } /* We need a class object for all cases below */ cls = (*env)->GetObjectClass(env, val); @@ -812,7 +800,7 @@ _javanet_set_option(JNIEnv *env, jobject this, jint option_id, jobject val) case SOCKOPT_TCP_NODELAY: mid = (*env)->GetMethodID(env, cls, "booleanValue", "()Z"); if (!mid) - { _javanet_throw_exception(env, IO_EXCEPTION, + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } /* Should be a 0 or a 1 */ @@ -842,7 +830,7 @@ _javanet_set_option(JNIEnv *env, jobject this, jint option_id, jobject val) mid = (*env)->GetMethodID(env, cls, "intValue", "()I"); if (!mid) - { _javanet_throw_exception(env, IO_EXCEPTION, + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } linger.l_linger = (*env)->CallIntMethod(env, val, mid); @@ -857,14 +845,14 @@ _javanet_set_option(JNIEnv *env, jobject this, jint option_id, jobject val) #ifdef SO_TIMEOUT mid = (*env)->GetMethodID(env, cls, "intValue", "()I"); if (!mid) - { _javanet_throw_exception(env, IO_EXCEPTION, + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } optval = (*env)->CallIntMethod(env, val, mid); rc = setsockopt(fd, SOL_SOCKET, SO_TIMEOUT, &optval, sizeof(int)); #else - _javanet_throw_exception(env, SOCKET_EXCEPTION, + JCL_ThrowException(env, SOCKET_EXCEPTION, "SO_TIMEOUT not supported on this platform"); return; #endif @@ -874,7 +862,7 @@ _javanet_set_option(JNIEnv *env, jobject this, jint option_id, jobject val) case SOCKOPT_SO_RCVBUF: mid = (*env)->GetMethodID(env, cls, "intValue", "()I"); if (!mid) - { _javanet_throw_exception(env, IO_EXCEPTION, + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } optval = (*env)->CallIntMethod(env, val, mid); @@ -891,7 +879,7 @@ _javanet_set_option(JNIEnv *env, jobject this, jint option_id, jobject val) case SOCKOPT_IP_TTL: mid = (*env)->GetMethodID(env, cls, "intValue", "()I"); if (!mid) - { _javanet_throw_exception(env, IO_EXCEPTION, + { JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } optval = (*env)->CallIntMethod(env, val, mid); @@ -913,13 +901,13 @@ _javanet_set_option(JNIEnv *env, jobject this, jint option_id, jobject val) break; default: - _javanet_throw_exception(env, SOCKET_EXCEPTION, "Unrecognized option"); + JCL_ThrowException(env, SOCKET_EXCEPTION, "Unrecognized option"); return; } /* Check to see if above operations succeeded */ if (rc == -1) - _javanet_throw_exception(env, SOCKET_EXCEPTION, strerror(errno)); + JCL_ThrowException(env, SOCKET_EXCEPTION, strerror(errno)); return; } @@ -940,7 +928,7 @@ _javanet_get_option(JNIEnv *env, jobject this, jint option_id) /* Get the real file descriptor */ fd = _javanet_get_int_field(env, this, "native_fd"); if (fd == -1) - { _javanet_throw_exception(env, SOCKET_EXCEPTION, "Internal Error"); return(0); } + { JCL_ThrowException(env, SOCKET_EXCEPTION, "Internal Error"); return(0); } /* Process the option requested */ switch (option_id) @@ -951,7 +939,7 @@ _javanet_get_option(JNIEnv *env, jobject this, jint option_id) rc = getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &optval, &optlen); if (rc == -1) { - _javanet_throw_exception(env, SOCKET_EXCEPTION, strerror(errno)); + JCL_ThrowException(env, SOCKET_EXCEPTION, strerror(errno)); return(0); } @@ -971,7 +959,7 @@ _javanet_get_option(JNIEnv *env, jobject this, jint option_id) rc = getsockopt(fd, SOL_SOCKET, SO_LINGER, &linger, &optlen); if (rc == -1) { - _javanet_throw_exception(env, SOCKET_EXCEPTION, strerror(errno)); + JCL_ThrowException(env, SOCKET_EXCEPTION, strerror(errno)); return(0); } @@ -989,14 +977,14 @@ _javanet_get_option(JNIEnv *env, jobject this, jint option_id) rc = getsockopt(fd, SOL_SOCKET, SO_TIMEOUT, &optval, &optlen); #else - _javanet_throw_exception(env, SOCKET_EXCEPTION, + JCL_ThrowException(env, SOCKET_EXCEPTION, "SO_TIMEOUT not supported on this platform"); return(0); #endif /* not SO_TIMEOUT */ if (rc == -1) { - _javanet_throw_exception(env, SOCKET_EXCEPTION, strerror(errno)); + JCL_ThrowException(env, SOCKET_EXCEPTION, strerror(errno)); return(0); } @@ -1015,7 +1003,7 @@ _javanet_get_option(JNIEnv *env, jobject this, jint option_id) if (rc == -1) { - _javanet_throw_exception(env, SOCKET_EXCEPTION, strerror(errno)); + JCL_ThrowException(env, SOCKET_EXCEPTION, strerror(errno)); return(0); } @@ -1029,7 +1017,7 @@ _javanet_get_option(JNIEnv *env, jobject this, jint option_id) rc = getsockopt(fd, IPPROTO_IP, IP_TTL, &optval, &optlen); if (rc == -1) { - _javanet_throw_exception(env, SOCKET_EXCEPTION, strerror(errno)); + JCL_ThrowException(env, SOCKET_EXCEPTION, strerror(errno)); return(0); } @@ -1044,7 +1032,7 @@ _javanet_get_option(JNIEnv *env, jobject this, jint option_id) rc = getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &si, &optlen); if (rc == -1) { - _javanet_throw_exception(env, SOCKET_EXCEPTION, strerror(errno)); + JCL_ThrowException(env, SOCKET_EXCEPTION, strerror(errno)); return(0); } @@ -1052,7 +1040,7 @@ _javanet_get_option(JNIEnv *env, jobject this, jint option_id) break; default: - _javanet_throw_exception(env, SOCKET_EXCEPTION, strerror(errno)); + JCL_ThrowException(env, SOCKET_EXCEPTION, strerror(errno)); return(0); } diff --git a/native/jni/javanet.h b/native/jni/java-net/javanet.h index b4aa2ea9b..9a61f0cd0 100644 --- a/native/jni/javanet.h +++ b/native/jni/java-net/javanet.h @@ -75,7 +75,6 @@ executable file might be covered by the GNU General Public License. */ * Function Prototypes */ -extern int _javanet_throw_exception(JNIEnv *, const char *, const char *); extern int _javanet_get_int_field(JNIEnv *, jobject, const char *); extern int _javanet_get_netaddr(JNIEnv *, jobject); extern void _javanet_create(JNIEnv *, jobject, jboolean); diff --git a/native/jni/java-util/.cvsignore b/native/jni/java-util/.cvsignore new file mode 100644 index 000000000..e9f2658a6 --- /dev/null +++ b/native/jni/java-util/.cvsignore @@ -0,0 +1,8 @@ +*.o +*.a +*.lo +*.la +.libs +.deps +Makefile +Makefile.in diff --git a/native/jni/java_util_TimeZone.c b/native/jni/java-util/java_util_TimeZone.c index 9c9ee1a8b..9c9ee1a8b 100644 --- a/native/jni/java_util_TimeZone.c +++ b/native/jni/java-util/java_util_TimeZone.c diff --git a/native/jni/java_math_BigInteger.c b/native/jni/java_math_BigInteger.c deleted file mode 100644 index bd6dd7e23..000000000 --- a/native/jni/java_math_BigInteger.c +++ /dev/null @@ -1,993 +0,0 @@ -/* BigInterger implementation using libgmp2 - Copyright (C) 1998, 1999 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -As a special exception, if you link this library with other files to -produce an executable, this library does not by itself cause the -resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why the -executable file might be covered by the GNU General Public License. */ - - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <endian.h> -#include <math.h> -#define __USE_GNU -#include <gmp.h> -#include "java_math_BigInteger.h" -#include "native_state.h" - -/* maximum value a jdouble can hold */ -#define JDBL_MAX 1.7976931348623157e+308 - -#define SWAPU32(w) \ - (((w) << 24) | (((w) & 0xff00) << 8) | (((w) >> 8) & 0xff00) | ((w) >> 24)) - -struct state_table *table; -jmethodID constructor; - -JNIEXPORT void JNICALL Java_java_math_BigInteger_initNativeState (JNIEnv * env, - jclass clazz) -{ - table = init_state_table (env, clazz); - constructor = (*env)->GetMethodID (env, clazz, "<init>", "()V"); -} - -JNIEXPORT jboolean JNICALL Java_java_math_BigInteger_initFromString (JNIEnv *env, - jobject obj, - jstring str_obj, - jint radix) -{ - const char *str; - mpz_t *integ; - int ret; - - integ = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*integ); - - str = (*env)->GetStringUTFChars (env, str_obj, NULL); - ret = mpz_set_str (*integ, str, radix); - (*env)->ReleaseStringUTFChars (env, str_obj, str); - - if (ret == -1) /* mpz_set_str signaled failure */ - { - mpz_clear (*integ); - return JNI_FALSE; - } - - set_state (env, obj, table, integ); - return JNI_TRUE; -} - -JNIEXPORT void JNICALL Java_java_math_BigInteger_initZero - (JNIEnv *env, jobject obj) -{ - mpz_t *integ; - - integ = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*integ); - set_state (env, obj, table, integ); -} - -JNIEXPORT jbyteArray JNICALL Java_java_math_BigInteger_toByteArray - (JNIEnv *env, jobject obj) -{ - mpz_t *this, pos; - FILE *out; - int negative, prepend; - jsize array_size; - jbyte *write_loc, *java_array_pointer; - jbyteArray data; - char *bp, *p; - size_t size; - int i; - - this = (mpz_t *) get_state (env, obj, table); - mpz_init_set (pos, *this); - negative = (mpz_sgn (pos) == -1); - - /* if we're negative, we need to take the 2's complement, in order to get - a "usable" signed magnitude output from mpz_out_raw */ - if (negative) - mpz_com (pos, pos); - - out = open_memstream (&bp, &size); - mpz_out_raw (out, pos); - mpz_clear (pos); - fflush (out); - if (size == 4) /* bigint is zero : special case */ - { - rewind (out); - fwrite ("\000\000\000\001\000", 5, 1, out); - } - fclose (out); - - array_size = size - sizeof (jint); - p = bp + sizeof (jint); /* skip past the len header */ - - prepend = ((negative && (~*p) >= 0) || ((!negative) && (*p < 0))); - - data = (*env)->NewByteArray (env, (prepend) ? array_size + 1 : array_size); - write_loc = java_array_pointer = (*env)->GetByteArrayElements (env, - data, NULL); - - if (prepend) - { - *write_loc = (negative) ? -1 : 0; - write_loc++; - } - - for (i = 0; i < array_size; i++) - { - *write_loc = (negative) ? ~*p : *p; - write_loc++; - p++; - } - - (*env)->ReleaseByteArrayElements (env, data, java_array_pointer, 0); - free (bp); - - return data; -} - -JNIEXPORT void JNICALL Java_java_math_BigInteger_nativeFinalize - (JNIEnv *env, jobject obj) -{ - mpz_t *integ; - - integ = remove_state_slot (env, obj, table); - mpz_clear (*integ); -} - -JNIEXPORT void JNICALL Java_java_math_BigInteger_initFromTwosCompByteArray - (JNIEnv *env, jobject obj, jbyteArray array) -{ - mpz_t *integ; - jsize array_len, array_len_to_write; - FILE *stream; - jbyte *data; - char *bp, *p; - size_t size; - int negative; - int i; - - array_len = (*env)->GetArrayLength (env, array); - p = data = (*env)->GetByteArrayElements (env, array, NULL); - - negative = (*p < 0); - /* if we have an explicit sign bit, skip over it */ - if (*p == -1 || *p == 0) - { - p++; - array_len--; - } - - /* make sure we write out the array len in big endian format */ -#ifndef WORDS_BIGENDIAN - array_len_to_write = SWAPU32 ((unsigned)array_len); -#else - array_len_to_write = array_len; -#endif - - stream = open_memstream (&bp, &size); - fwrite (&array_len_to_write, sizeof (array_len_to_write), 1, stream); - - for (i = 0; i < array_len; i++, p++) - putc ((negative) ? ~*p : *p, stream); - - (*env)->ReleaseByteArrayElements (env, array, data, 0); - fflush (stream); - - integ = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*integ); - mpz_inp_raw (*integ, stream); - if (negative) - mpz_com (*integ, *integ); - - fclose (stream); - free (bp); - - set_state (env, obj, table, integ); -} - -JNIEXPORT void JNICALL Java_java_math_BigInteger_initFromSignedMagnitudeByteArray - (JNIEnv *env, jobject obj, jint sign, jbyteArray magnitude) -{ - mpz_t *integ; - FILE *stream; - char *bp; - size_t size; - jsize array_len, array_len_to_write; - jbyte *data; - - array_len = (*env)->GetArrayLength (env, magnitude); - array_len_to_write = (sign < 0) ? -array_len : array_len; - - /* make sure we write out the array len in big endian format */ -#ifndef WORDS_BIGENDIAN - array_len_to_write = SWAPU32 ((unsigned)array_len_to_write); -#endif - - stream = open_memstream (&bp, &size); - fwrite (&array_len_to_write, sizeof (array_len_to_write), 1, stream); - - data = (*env)->GetByteArrayElements (env, magnitude, NULL); - fwrite (data, sizeof (jbyte), array_len, stream); - (*env)->ReleaseByteArrayElements (env, magnitude, data, 0); - fflush (stream); - - integ = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*integ); - mpz_inp_raw (*integ, stream); - - fclose (stream); - free (bp); - - set_state (env, obj, table, integ); -} - -JNIEXPORT void JNICALL Java_java_math_BigInteger_initFromLong (JNIEnv *env, - jobject obj, - jlong num) -{ - mpz_t *integ; - mpz_t msw; - jint msw_int; - - integ = (mpz_t *) malloc (sizeof (mpz_t)); - - /* set the least significant word */ - mpz_init_set_ui (*integ, (jint) num); - - msw_int = (jint)(num >> 32); /* grab the most significant word */ - if (msw_int != 0) - { - mpz_init_set_si (msw, msw_int); - mpz_mul_2exp (msw, msw, 32); /* move it back to the proper slot */ - mpz_ior (*integ, *integ, msw); /* msw | lsw */ - } - - set_state (env, obj, table, integ); -} - - -static -jobject -mpz_t2obj (JNIEnv *env, jobject obj, mpz_t *val) -{ - jobject big_int; - - big_int = (*env)->NewObject (env, (*env)->GetObjectClass (env, obj), - constructor); - - set_state (env, big_int, table, val); - - return big_int; -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_add (JNIEnv *env, jobject obj, - jobject val) -{ - mpz_t *this; - mpz_t *value; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - value = (mpz_t *) get_state (env, val, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_add (*result, *this, *value); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_subtract (JNIEnv *env, jobject obj, - jobject val) -{ - mpz_t *this; - mpz_t *value; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - value = (mpz_t *) get_state (env, val, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_sub (*result, *this, *value); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_multiply (JNIEnv *env, - jobject obj, - jobject val) -{ - mpz_t *this; - mpz_t *value; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - value = (mpz_t *) get_state (env, val, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_mul (*result, *this, *value); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_abs (JNIEnv *env, jobject obj) -{ - mpz_t *this; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_abs (*result, *this); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_not (JNIEnv *env, jobject obj) -{ - mpz_t *this; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_com (*result, *this); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_and (JNIEnv *env, jobject obj, - jobject val) -{ - mpz_t *this; - mpz_t *value; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - value = (mpz_t *) get_state (env, val, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_and (*result, *this, *value); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_andNot (JNIEnv *env, - jobject obj, - jobject val) -{ - mpz_t *this; - mpz_t *value; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - value = (mpz_t *) get_state (env, val, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_com (*result, *value); - mpz_and (*result, *result, *this); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_or (JNIEnv *env, jobject obj, - jobject val) -{ - mpz_t *this; - mpz_t *value; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - value = (mpz_t *) get_state (env, val, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_ior (*result, *this, *value); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_xor (JNIEnv *env, jobject obj, - jobject val) -{ - mpz_t *this; - mpz_t *value; - mpz_t *result; - mpz_t tmp; - - this = (mpz_t *) get_state (env, obj, table); - value = (mpz_t *) get_state (env, val, table); - - mpz_init (tmp); - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - - /* ((this & (~value)) | ((~this) & value)) = (this ^ value) */ - mpz_com (tmp, *value); - mpz_and (tmp, tmp, *this); - - mpz_com (*result, *this); - mpz_and (*result, *result, *value); - - mpz_ior (*result, *result, tmp); - - mpz_clear (tmp); - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jint JNICALL Java_java_math_BigInteger_getLowestSetBit - (JNIEnv *env, jobject obj) -{ - mpz_t *this; - - this = (mpz_t *) get_state (env, obj, table); - - /* return -1, if this is 0 */ - return (mpz_sgn (*this) == 0) ? -1 : mpz_scan1 (*this, 0); -} - -JNIEXPORT jint JNICALL Java_java_math_BigInteger_hashCode - (JNIEnv *env, jobject obj) -{ - mpz_t *this; - - this = (mpz_t *) get_state (env, obj, table); - return (jint) mpz_get_si (*this); -} - -JNIEXPORT jstring JNICALL Java_java_math_BigInteger_toString - (JNIEnv *env, jobject obj, jint radix) -{ - mpz_t *this; - char *str = NULL; - jstring ret; - - this = (mpz_t *) get_state (env, obj, table); - - if (radix < 2 || radix > 36) - radix = 10; - - str = mpz_get_str (NULL, radix, *this); - ret = (*env)->NewStringUTF (env, str); - free (str); - - return ret; -} - -JNIEXPORT jdouble JNICALL Java_java_math_BigInteger_doubleValue - (JNIEnv *env, jobject obj) -{ - mpz_t *this; - mpz_t max_dbl; - int cmp_val; - - this = (mpz_t *) get_state (env, obj, table); - - mpz_init_set_d (max_dbl, JDBL_MAX); - cmp_val = mpz_cmp (*this, max_dbl); - - /* if we're larger than JDBL_MAX, return +infinity */ - if (cmp_val > 0) - { - mpz_clear (max_dbl); - return HUGE_VAL; - } - - mpz_neg (max_dbl, max_dbl); - cmp_val = mpz_cmp (*this, max_dbl); - mpz_clear (max_dbl); - - /* if we're more negative than -JDBL_MAX, return -infinity */ - if (cmp_val < 0) - return -HUGE_VAL; - - return mpz_get_d (*this); -} - -JNIEXPORT jlong JNICALL Java_java_math_BigInteger_longValue - (JNIEnv *env, jobject obj) -{ - mpz_t *this; - mpz_t result,num; - jlong total = 0; - int i, limbs_to_grab; - - this = (mpz_t *) get_state (env, obj, table); - - /* truncate values larger than MAX_LONG and MIN_LONG to MAX_LONG - and MIN_LONG, respectively */ - if (mpz_sizeinbase (*this, 2) >= 64) - return (mpz_sgn (*this) == 1) ? - ~((jlong)1 << 63) : (jlong)1 << 63; - - /* limbs are generally 32 bits, so we probably need to grab 2 limbs - before we'll have enough data to fill up a 64 bit jlong */ - limbs_to_grab = sizeof (jlong) / sizeof (mp_limb_t); - if (limbs_to_grab == 0) /* word size of machine is > 64 bits */ - limbs_to_grab++; - - mpz_init (result); - for (i = 0; i < limbs_to_grab; i++) - { - int bits = i*mp_bits_per_limb; - - mpz_tdiv_q_2exp (result, *this, bits); - total |= ((jlong) mpz_get_ui (result)) << bits; - } - mpz_clear (result); - - return (mpz_sgn (num) == 1) ? total : -total; -} - -JNIEXPORT jint JNICALL Java_java_math_BigInteger_bitLength - (JNIEnv *env, jobject obj) -{ - mpz_t *this; - - this = (mpz_t *) get_state (env, obj, table); - return (mpz_sgn (*this) == 0) ? 0 : mpz_sizeinbase (*this, 2); -} - -JNIEXPORT jint JNICALL Java_java_math_BigInteger_bitCount - (JNIEnv *env, jobject obj) -{ - mpz_t *this; - - this = (mpz_t *) get_state (env, obj, table); - - /* for negative values, flip all the bits */ - if (mpz_sgn (*this) == -1) - { - mpz_t tmp; - int ret_value; - - mpz_init (tmp); - mpz_com (tmp, *this); - ret_value = mpz_popcount (tmp); - mpz_clear (tmp); - return ret_value; - } - - return mpz_popcount (*this); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_setBit - (JNIEnv *env, jobject obj, jint n) -{ - mpz_t *this; - mpz_t *result; - - if (n < 0) - { - (*env)->ThrowNew (env, - (*env)->FindClass(env, - "java/lang/ArithmeticException"), - "attempt to set negative bit"); - return NULL; - } - - this = (mpz_t *) get_state (env, obj, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init_set (*result, *this); - mpz_setbit (*result, n); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_clearBit - (JNIEnv *env, jobject obj, jint n) -{ - mpz_t *this; - mpz_t *result; - - if (n < 0) - { - (*env)->ThrowNew (env, - (*env)->FindClass(env, - "java/lang/ArithmeticException"), - "attempt to clear negative bit"); - return NULL; - } - - this = (mpz_t *) get_state (env, obj, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init_set (*result, *this); - mpz_clrbit (*result, n); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_flipBit - (JNIEnv *env, jobject obj, jint n) -{ - mpz_t *this; - mpz_t *result; - - if (n < 0) - { - (*env)->ThrowNew (env, - (*env)->FindClass(env, - "java/lang/ArithmeticException"), - "attempt to flip negative bit"); - return NULL; - } - - this = (mpz_t *) get_state (env, obj, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init_set (*result, *this); - (mpz_scan0 (*result, n) == n) ? mpz_setbit (*result, n) : - mpz_clrbit (*result, n); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jboolean JNICALL Java_java_math_BigInteger_testBit - (JNIEnv *env, jobject obj, jint n) -{ - mpz_t *this; - - if (n < 0) - { - (*env)->ThrowNew (env, - (*env)->FindClass(env, - "java/lang/ArithmeticException"), - "attempt to test negative bit"); - return JNI_FALSE; - } - - this = (mpz_t *) get_state (env, obj, table); - return (mpz_scan0 (*this, n) == n) ? JNI_FALSE : JNI_TRUE; -} - -JNIEXPORT jboolean JNICALL Java_java_math_BigInteger_nativeEquals - (JNIEnv *env, jobject obj, jobject val) -{ - mpz_t *this; - mpz_t *value; - - this = (mpz_t *) get_state (env, obj, table); - value = (mpz_t *) get_state (env, val, table); - - return (mpz_cmp (*this, *value) == 0) ? JNI_TRUE : JNI_FALSE; -} - -JNIEXPORT jboolean JNICALL Java_java_math_BigInteger_isProbablePrime - (JNIEnv *env, jobject obj, jint certainty) -{ - mpz_t *this; - int conv_certainty; - - this = (mpz_t *) get_state (env, obj, table); - - /* ln(.5) * certainty / ln(.25) */ - /* convert from (1/2 ** certainty) false positive to (1/4 ** certainty) */ - conv_certainty = (int) ceil (-.69314718055994530941 * certainty / - -1.38629436111989061883); - - return (mpz_probab_prime_p (*this, conv_certainty)) ? JNI_TRUE : JNI_FALSE; -} - -JNIEXPORT jint JNICALL Java_java_math_BigInteger_compareTo (JNIEnv *env, - jobject obj, - jobject val) -{ - mpz_t *this; - mpz_t *value; - int result; - - this = (mpz_t *) get_state (env, obj, table); - value = (mpz_t *) get_state (env, val, table); - - result = mpz_cmp (*this, *value); - if (result > 0) return 1; - if (result < 0) return -1; - return 0; -} - -JNIEXPORT jint JNICALL Java_java_math_BigInteger_signum (JNIEnv *env, jobject obj) -{ - mpz_t *this; - - this = (mpz_t *) get_state (env, obj, table); - return mpz_sgn (*this); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_negate (JNIEnv *env, jobject obj) -{ - mpz_t *this; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_neg (*result, *this); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_divide (JNIEnv *env, - jobject obj, - jobject val) -{ - mpz_t *this; - mpz_t *value; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - value = (mpz_t *) get_state (env, val, table); - - if (mpz_sgn (*value) == 0) - { - (*env)->ThrowNew (env, - (*env)->FindClass(env, - "java/lang/ArithmeticException"), - "divide by zero"); - return NULL; - } - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_tdiv_q (*result, *this, *value); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_remainder (JNIEnv *env, - jobject obj, - jobject val) -{ - mpz_t *this; - mpz_t *value; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - value = (mpz_t *) get_state (env, val, table); - - if (mpz_sgn (*value) == 0) - { - (*env)->ThrowNew (env, - (*env)->FindClass(env, - "java/lang/ArithmeticException"), - "divide by zero"); - return NULL; - } - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_tdiv_r (*result, *this, *value); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_pow (JNIEnv *env, - jobject obj, - jint exponent) -{ - mpz_t *this; - mpz_t *result; - - if (exponent < 0) - { - (*env)->ThrowNew (env, - (*env)->FindClass(env, - "java/lang/ArithmeticException"), - "exponent less than zero"); - return NULL; - } - - this = (mpz_t *) get_state (env, obj, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_pow_ui (*result, *this, exponent); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_gcd (JNIEnv *env, - jobject obj, - jobject val) -{ - mpz_t *this; - mpz_t *value; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - value = (mpz_t *) get_state (env, val, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_gcd (*result, *this, *value); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_modPow (JNIEnv *env, - jobject obj, - jobject exp_obj, - jobject m_obj) -{ - mpz_t *this; - mpz_t *exp; - mpz_t *m; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - exp = (mpz_t *) get_state (env, exp_obj, table); - m = (mpz_t *) get_state (env, m_obj, table); - - if (mpz_sgn (*m) <= 0) - { - (*env)->ThrowNew (env, - (*env)->FindClass(env, - "java/lang/ArithmeticException"), - "mod undefined for less than or equals to zero"); - return NULL; - } - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - - if (mpz_sgn (*exp) == -1) /* special negative case */ - { - mpz_t pow; - int ret; - - mpz_init (pow); - mpz_pow_ui (pow, *this, mpz_get_ui (*exp)); /* raise to exponent */ - - /* perform a mod inverse */ - ret = mpz_invert (*result, pow, *m); - mpz_clear (pow); - - if (ret == 0) /* no multiplicative inverse mod m */ - { - mpz_clear (*result); /* result is useless... */ - free (result); /* so get rid of it */ - - (*env)->ThrowNew (env, - (*env)->FindClass(env, - "java/lang/ArithmeticException"), - "no multiplicative inverse mod m"); - return NULL; - } - - /* java doesn't allow negative results */ - if (mpz_sgn (*result) == -1) - mpz_add (*result, *m, *result); - } - else - mpz_powm (*result, *this, *exp, *m); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_modInverse - (JNIEnv *env, jobject obj, jobject m_obj) -{ - mpz_t *this, *m, *result; - int ret; - - this = (mpz_t *) get_state (env, obj, table); - m = (mpz_t *) get_state (env, m_obj, table); - - if (mpz_sgn (*m) <= 0) - { - (*env)->ThrowNew (env, - (*env)->FindClass(env, - "java/lang/ArithmeticException"), - "mod undefined for less than or equals to zero"); - return NULL; - } - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - - ret = mpz_invert (*result, *this, *m); - - if (ret == 0) /* no multiplicative inverse mod m */ - { - mpz_clear (*result); /* result is useless... */ - free (result); /* so get rid of it */ - - (*env)->ThrowNew (env, - (*env)->FindClass(env, - "java/lang/ArithmeticException"), - "no multiplicative inverse mod m"); - return NULL; - } - - if (mpz_sgn (*result) == -1) /* java spec does not allow a negative value */ - mpz_add (*result, *m, *result); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_mod - (JNIEnv *env, jobject obj, jobject val) -{ - mpz_t *this; - mpz_t *value; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - value = (mpz_t *) get_state (env, val, table); - - if (mpz_sgn (*value) <= 0) - { - (*env)->ThrowNew (env, - (*env)->FindClass(env, - "java/lang/ArithmeticException"), - "mod undefined for less than or equals to zero"); - return NULL; - } - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_mod (*result, *this, *value); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_shiftLeft - (JNIEnv *env, jobject obj, jint n) -{ - mpz_t *this; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_mul_2exp (*result, *this, n); - - return mpz_t2obj (env, obj, result); -} - -JNIEXPORT jobject JNICALL Java_java_math_BigInteger_shiftRight - (JNIEnv *env, jobject obj, jint n) -{ - mpz_t *this; - mpz_t *result; - - this = (mpz_t *) get_state (env, obj, table); - - result = (mpz_t *) malloc (sizeof (mpz_t)); - mpz_init (*result); - mpz_tdiv_q_2exp (*result, *this, n); - - return mpz_t2obj (env, obj, result); -} diff --git a/native/jni/javaio.h b/native/jni/javaio.h deleted file mode 100644 index 44dbb63d0..000000000 --- a/native/jni/javaio.h +++ /dev/null @@ -1,65 +0,0 @@ -/* javaio.h - Declaration for common java.io native functions - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -As a special exception, if you link this library with other files to -produce an executable, this library does not by itself cause the -resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why the -executable file might be covered by the GNU General Public License. */ - - -#ifndef JAVAIO_H_INCLUDED -#define JAVAIO_H_INCLUDED - -#include <stddef.h> - -/* - * Function Prototypes - */ - -extern jlong _javaio_get_file_length(JNIEnv *, jint); -extern jlong _javaio_skip_bytes(JNIEnv *, jint, jlong); -extern jint _javaio_open(JNIEnv *, jstring, int); -extern void _javaio_close(JNIEnv *, jint fd); -extern jint _javaio_read(JNIEnv *, jobject obj, jint, jarray, jint, jint); -extern jint _javaio_write(JNIEnv *, jobject obj, jint, jarray, jint, jint); - -JNIEXPORT jclass JNICALL _javaio_FindClass(JNIEnv * env, char * className); -JNIEXPORT void JNICALL _javaio_ThrowException(JNIEnv * env, char * className, char * errMsg); -JNIEXPORT void * JNICALL _javaio_malloc(JNIEnv * env, size_t size); -JNIEXPORT void * JNICALL _javaio_realloc(JNIEnv * env, void *, size_t size); -JNIEXPORT void JNICALL _javaio_free(JNIEnv * env, void * p); -JNIEXPORT char * JNICALL _javaio_jstring_to_cstring(JNIEnv * env, jstring s); -JNIEXPORT void JNICALL _javaio_free_cstring(JNIEnv * env, jstring s, char * cstr); -JNIEXPORT jint JNICALL _javaio_MonitorEnter(JNIEnv * env, jobject o); -JNIEXPORT jint JNICALL _javaio_MonitorExit(JNIEnv * env, jobject o); - -#define _javaio_RETHROW_EXCEPTION(env) if((*(env))->ExceptionOccurred((env)) != NULL) return NULL; - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#endif /* JAVAIO_H_INCLUDED */ - diff --git a/native/jni/javalang.c b/native/jni/javalang.c deleted file mode 100644 index 365290906..000000000 --- a/native/jni/javalang.c +++ /dev/null @@ -1,93 +0,0 @@ -/* javalang.c - Common java.lang native functions (ripped from javaio.c) - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -As a special exception, if you link this library with other files to -produce an executable, this library does not by itself cause the -resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why the -executable file might be covered by the GNU General Public License. */ - - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> - -#include <jni.h> - -#include "javalang.h" - -#include <malloc.h> - -static char errstr[4098]; // this way the memory is pre-allocated, so that we do not have to worry if we are out of memory. - -JNIEXPORT void JNICALL _javalang_ThrowException(JNIEnv * env, char * className, char * errMsg) -{ - jclass excClass; - if((*env)->ExceptionOccurred(env)) { - (*env)->ExceptionClear(env); - } - excClass = (*env)->FindClass(env, className); - if(excClass == NULL) { - jclass errExcClass; - errExcClass = (*env)->FindClass(env, "java/lang/ClassNotFoundException"); - if(errExcClass == NULL) { - errExcClass = (*env)->FindClass(env, "java/lang/InternalError"); - if(errExcClass == NULL) { - sprintf(errstr,"JCL: Utterly failed to throw exeption %s with message %s.",className,errMsg); - fprintf(stderr, errstr); - return; - } - } - sprintf(errstr,"JCL: Failed to throw exception %s with message %s: could not find exception class.", className, errMsg); - (*env)->ThrowNew(env, errExcClass, errstr); - } - (*env)->ThrowNew(env, excClass, errMsg); -} - -JNIEXPORT void * JNICALL _javalang_malloc(JNIEnv * env, size_t size) -{ - void * mem = malloc(size); - if(mem == NULL) { - _javalang_ThrowException(env, "java/lang/OutOfMemoryError", "malloc() failed."); - return NULL; - } - return mem; -} - -JNIEXPORT void * JNICALL - _javalang_realloc(JNIEnv *env, void *ptr, size_t size) -{ - ptr = realloc(ptr, size); - if (ptr == 0) - { - _javalang_ThrowException(env, "java/lang/OutOfMemoryError", - "malloc() failed."); - return NULL; - } - return(ptr); -} - - -JNIEXPORT void JNICALL _javalang_free(JNIEnv * env, void * p) { - if(p != NULL) - free(p); -} diff --git a/native/jni/jcl.c b/native/jni/jcl.c deleted file mode 100644 index 8347be0a3..000000000 --- a/native/jni/jcl.c +++ /dev/null @@ -1,111 +0,0 @@ -/* jcl.c - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -As a special exception, if you link this library with other files to -produce an executable, this library does not by itself cause the -resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why the -executable file might be covered by the GNU General Public License. */ - -#include <stdio.h> -#include <jcl.h> -#include <malloc.h> - -static char errstr[4098]; // this way the memory is pre-allocated, so that we do not have to worry if we are out of memory. - -JNIEXPORT void JNICALL JCL_ThrowException(JNIEnv * env, char * className, char * errMsg) { - jclass excClass; - if((*env)->ExceptionOccurred(env)) { - (*env)->ExceptionClear(env); - } - excClass = (*env)->FindClass(env, className); - if(excClass == NULL) { - jclass errExcClass; - errExcClass = (*env)->FindClass(env, "java/lang/ClassNotFoundException"); - if(errExcClass == NULL) { - errExcClass = (*env)->FindClass(env, "java/lang/InternalError"); - if(errExcClass == NULL) { - sprintf(errstr,"JCL: Utterly failed to throw exeption %s with message %s.",className,errMsg); - fprintf(stderr, errstr); - return; - } - } - sprintf(errstr,"JCL: Failed to throw exception %s with message %s: could not find exception class.", className, errMsg); - (*env)->ThrowNew(env, errExcClass, errstr); - } - (*env)->ThrowNew(env, excClass, errMsg); -} - -JNIEXPORT void * JNICALL JCL_malloc(JNIEnv * env, size_t size) { - void * mem = malloc(size); - if(mem == NULL) { - JCL_ThrowException(env, "java/lang/OutOfMemoryError", "malloc() failed."); - return NULL; - } - return mem; -} - -JNIEXPORT void JNICALL JCL_free(JNIEnv * env, void * p) { - if(p != NULL) { - free(p); - } -} - -JNIEXPORT char * JNICALL JCL_jstring_to_cstring(JNIEnv * env, jstring s) { - char* cstr; - if(s == NULL) { - JCL_ThrowException(env, "java/lang/NullPointerException","Null string"); - return NULL; - } - cstr = (char*)(*env)->GetStringUTFChars(env, s, NULL); - if(cstr == NULL) { - JCL_ThrowException(env, "java/lang/InternalError", "GetStringUTFChars() failed."); - return NULL; - } - return cstr; -} - -JNIEXPORT void JNICALL JCL_free_cstring(JNIEnv * env, jstring s, char * cstr) { - (*env)->ReleaseStringUTFChars(env, s, cstr); -} - -JNIEXPORT jint JNICALL JCL_MonitorEnter(JNIEnv * env, jobject o) { - jint retval = (*env)->MonitorEnter(env,o); - if(retval != 0) { - JCL_ThrowException(env, "java/lang/InternalError", "MonitorEnter() failed."); - } - return retval; -} - -JNIEXPORT jint JNICALL JCL_MonitorExit(JNIEnv * env, jobject o) { - jint retval = (*env)->MonitorExit(env,o); - if(retval != 0) { - JCL_ThrowException(env, "java/lang/InternalError", "MonitorExit() failed."); - } - return retval; -} - -JNIEXPORT jclass JNICALL JCL_FindClass(JNIEnv * env, char * className) { - jclass retval = (*env)->FindClass(env,className); - if(retval == NULL) { - JCL_ThrowException(env, "java/lang/ClassNotFoundException", className); - } - return retval; -} diff --git a/native/jni/jcl.h b/native/jni/jcl.h deleted file mode 100644 index e48c60c4e..000000000 --- a/native/jni/jcl.h +++ /dev/null @@ -1,51 +0,0 @@ -/* jcl.h - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -As a special exception, if you link this library with other files to -produce an executable, this library does not by itself cause the -resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why the -executable file might be covered by the GNU General Public License. */ - -#ifndef __JCL_H__ -#define __JCL_H__ - -#include <stddef.h> -#include <jni.h> - -JNIEXPORT jclass JNICALL JCL_FindClass(JNIEnv * env, char * className); -JNIEXPORT void JNICALL JCL_ThrowException(JNIEnv * env, char * className, char * errMsg); -JNIEXPORT void * JNICALL JCL_malloc(JNIEnv * env, size_t size); -JNIEXPORT void JNICALL JCL_free(JNIEnv * env, void * p); -JNIEXPORT char * JNICALL JCL_jstring_to_cstring(JNIEnv * env, jstring s); -JNIEXPORT void JNICALL JCL_free_cstring(JNIEnv * env, jstring s, char * cstr); -JNIEXPORT jint JNICALL JCL_MonitorEnter(JNIEnv * env, jobject o); -JNIEXPORT jint JNICALL JCL_MonitorExit(JNIEnv * env, jobject o); - -#define JCL_RETHROW_EXCEPTION(env) if((*(env))->ExceptionOccurred((env)) != NULL) return NULL; - -/* Simple debug macro */ -#ifdef DEBUG -#define DBG(x) fprintf(stderr, (x)); -#else -#define DBG(x) -#endif - -#endif diff --git a/native/jni/k_rem_pio2.c b/native/jni/k_rem_pio2.c deleted file mode 100644 index f7ffa63b7..000000000 --- a/native/jni/k_rem_pio2.c +++ /dev/null @@ -1,301 +0,0 @@ - -/* @(#)k_rem_pio2.c 1.3 95/01/18 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* - * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2) - * double x[],y[]; int e0,nx,prec; int ipio2[]; - * - * __kernel_rem_pio2 return the last three digits of N with - * y = x - N*pi/2 - * so that |y| < pi/2. - * - * The method is to compute the integer (mod 8) and fraction parts of - * (2/pi)*x without doing the full multiplication. In general we - * skip the part of the product that are known to be a huge integer ( - * more accurately, = 0 mod 8 ). Thus the number of operations are - * independent of the exponent of the input. - * - * (2/pi) is represented by an array of 24-bit integers in ipio2[]. - * - * Input parameters: - * x[] The input value (must be positive) is broken into nx - * pieces of 24-bit integers in double precision format. - * x[i] will be the i-th 24 bit of x. The scaled exponent - * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0 - * match x's up to 24 bits. - * - * Example of breaking a double positive z into x[0]+x[1]+x[2]: - * e0 = ilogb(z)-23 - * z = scalbn(z,-e0) - * for i = 0,1,2 - * x[i] = floor(z) - * z = (z-x[i])*2**24 - * - * - * y[] ouput result in an array of double precision numbers. - * The dimension of y[] is: - * 24-bit precision 1 - * 53-bit precision 2 - * 64-bit precision 2 - * 113-bit precision 3 - * The actual value is the sum of them. Thus for 113-bit - * precison, one may have to do something like: - * - * long double t,w,r_head, r_tail; - * t = (long double)y[2] + (long double)y[1]; - * w = (long double)y[0]; - * r_head = t+w; - * r_tail = w - (r_head - t); - * - * e0 The exponent of x[0] - * - * nx dimension of x[] - * - * prec an integer indicating the precision: - * 0 24 bits (single) - * 1 53 bits (double) - * 2 64 bits (extended) - * 3 113 bits (quad) - * - * ipio2[] - * integer array, contains the (24*i)-th to (24*i+23)-th - * bit of 2/pi after binary point. The corresponding - * floating value is - * - * ipio2[i] * 2^(-24(i+1)). - * - * External function: - * double scalbn(), floor(); - * - * - * Here is the description of some local variables: - * - * jk jk+1 is the initial number of terms of ipio2[] needed - * in the computation. The recommended value is 2,3,4, - * 6 for single, double, extended,and quad. - * - * jz local integer variable indicating the number of - * terms of ipio2[] used. - * - * jx nx - 1 - * - * jv index for pointing to the suitable ipio2[] for the - * computation. In general, we want - * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8 - * is an integer. Thus - * e0-3-24*jv >= 0 or (e0-3)/24 >= jv - * Hence jv = max(0,(e0-3)/24). - * - * jp jp+1 is the number of terms in PIo2[] needed, jp = jk. - * - * q[] double array with integral value, representing the - * 24-bits chunk of the product of x and 2/pi. - * - * q0 the corresponding exponent of q[0]. Note that the - * exponent for q[i] would be q0-24*i. - * - * PIo2[] double precision array, obtained by cutting pi/2 - * into 24 bits chunks. - * - * f[] ipio2[] in floating point - * - * iq[] integer array by breaking up q[] in 24-bits chunk. - * - * fq[] final product of x*(2/pi) in fq[0],..,fq[jk] - * - * ih integer. If >0 it indicates q[] is >= 0.5, hence - * it also indicates the *sign* of the result. - * - */ - - -/* - * Constants: - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the - * compiler will convert from decimal to binary accurately enough - * to produce the hexadecimal values shown. - */ - -#include "fdlibm.h" - -static const jint init_jk[] = {2,3,4,6}; /* initial value for jk */ - -static const jdouble PIo2[] = { - 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */ - 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */ - 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */ - 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */ - 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */ - 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */ - 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */ - 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */ -}; - -static const jdouble -zero = 0.0, -one = 1.0, -two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ -twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */ - -jint -__kernel_rem_pio2 (jdouble *x, jdouble *y, jint e0, jint nx, jint prec, - const jint *ipio2) -{ - jint jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; - jdouble z,fw,f[20],fq[20],q[20]; - - /* initialize jk*/ - jk = init_jk[prec]; - jp = jk; - - /* determine jx,jv,q0, note that 3>q0 */ - jx = nx-1; - jv = (e0-3)/24; if(jv<0) jv=0; - q0 = e0-24*(jv+1); - - /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ - j = jv-jx; m = jx+jk; - for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (jdouble) ipio2[j]; - - /* compute q[0],q[1],...q[jk] */ - for (i=0;i<=jk;i++) { - for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw; - } - - jz = jk; - recompute: - /* distill q[] into iq[] reversingly */ - for(i=0,j=jz,z=q[jz];j>0;i++,j--) { - fw = (jdouble)((jint)(twon24* z)); - iq[i] = (jint)(z-two24*fw); - z = q[j-1]+fw; - } - - /* compute n */ - z = scalbn(z,q0); /* actual value of z */ - z -= 8.0*floor(z*0.125); /* trim off jinteger >= 8 */ - n = (jint) z; - z -= (jdouble)n; - ih = 0; - if(q0>0) { /* need iq[jz-1] to determine n */ - i = (iq[jz-1]>>(24-q0)); n += i; - iq[jz-1] -= i<<(24-q0); - ih = iq[jz-1]>>(23-q0); - } - else if(q0==0) ih = iq[jz-1]>>23; - else if(z>=0.5) ih=2; - - if(ih>0) { /* q > 0.5 */ - n += 1; carry = 0; - for(i=0;i<jz ;i++) { /* compute 1-q */ - j = iq[i]; - if(carry==0) { - if(j!=0) { - carry = 1; iq[i] = 0x1000000- j; - } - } else iq[i] = 0xffffff - j; - } - if(q0>0) { /* rare case: chance is 1 in 12 */ - switch(q0) { - case 1: - iq[jz-1] &= 0x7fffff; break; - case 2: - iq[jz-1] &= 0x3fffff; break; - } - } - if(ih==2) { - z = one - z; - if(carry!=0) z -= scalbn(one,q0); - } - } - - /* check if recomputation is needed */ - if(z==zero) { - j = 0; - for (i=jz-1;i>=jk;i--) j |= iq[i]; - if(j==0) { /* need recomputation */ - for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */ - - for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */ - f[jx+i] = (jdouble) ipio2[jv+i]; - for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; - q[i] = fw; - } - jz += k; - goto recompute; - } - } - - /* chop off zero terms */ - if(z==0.0) { - jz -= 1; q0 -= 24; - while(iq[jz]==0) { jz--; q0-=24;} - } else { /* break z into 24-bit if necessary */ - z = scalbn(z,-q0); - if(z>=two24) { - fw = (jdouble)((jint)(twon24*z)); - iq[jz] = (jint)(z-two24*fw); - jz += 1; q0 += 24; - iq[jz] = (jint) fw; - } else iq[jz] = (jint) z ; - } - - /* convert jinteger "bit" chunk to floating-pojint value */ - fw = scalbn(one,q0); - for(i=jz;i>=0;i--) { - q[i] = fw*(jdouble)iq[i]; fw*=twon24; - } - - /* compute PIo2[0,...,jp]*q[jz,...,0] */ - for(i=jz;i>=0;i--) { - for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k]; - fq[jz-i] = fw; - } - - /* compress fq[] into y[] */ - switch(prec) { - case 0: - fw = 0.0; - for (i=jz;i>=0;i--) fw += fq[i]; - y[0] = (ih==0)? fw: -fw; - break; - case 1: - case 2: - fw = 0.0; - for (i=jz;i>=0;i--) fw += fq[i]; - y[0] = (ih==0)? fw: -fw; - fw = fq[0]-fw; - for (i=1;i<=jz;i++) fw += fq[i]; - y[1] = (ih==0)? fw: -fw; - break; - case 3: /* painful */ - for (i=jz;i>0;i--) { - fw = fq[i-1]+fq[i]; - fq[i] += fq[i-1]-fw; - fq[i-1] = fw; - } - for (i=jz;i>1;i--) { - fw = fq[i-1]+fq[i]; - fq[i] += fq[i-1]-fw; - fq[i-1] = fw; - } - for (fw=0.0,i=jz;i>=2;i--) fw += fq[i]; - if(ih==0) { - y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; - } else { - y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; - } - } - return n&7; -} diff --git a/native/jni/pow.c b/native/jni/pow.c deleted file mode 100644 index 7bd0e4422..000000000 --- a/native/jni/pow.c +++ /dev/null @@ -1,296 +0,0 @@ - -/* @(#)e_pow.c 1.3 95/01/18 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* __ieee754_pow(x,y) return x**y - * - * n - * Method: Let x = 2 * (1+f) - * 1. Compute and return log2(x) in two pieces: - * log2(x) = w1 + w2, - * where w1 has 53-24 = 29 bit trailing zeros. - * 2. Perform y*log2(x) = n+y' by simulating muti-precision - * arithmetic, where |y'|<=0.5. - * 3. Return x**y = 2**n*exp(y'*log2) - * - * Special cases: - * 1. (anything) ** 0 is 1 - * 2. (anything) ** 1 is itself - * 3. (anything) ** NAN is NAN - * 4. NAN ** (anything except 0) is NAN - * 5. +-(|x| > 1) ** +INF is +INF - * 6. +-(|x| > 1) ** -INF is +0 - * 7. +-(|x| < 1) ** +INF is +0 - * 8. +-(|x| < 1) ** -INF is +INF - * 9. +-1 ** +-INF is NAN - * 10. +0 ** (+anything except 0, NAN) is +0 - * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 - * 12. +0 ** (-anything except 0, NAN) is +INF - * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF - * 14. -0 ** (odd integer) = -( +0 ** (odd integer) ) - * 15. +INF ** (+anything except 0,NAN) is +INF - * 16. +INF ** (-anything except 0,NAN) is +0 - * 17. -INF ** (anything) = -0 ** (-anything) - * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) - * 19. (-anything except 0 and inf) ** (non-integer) is NAN - * - * Accuracy: - * pow(x,y) returns x**y nearly rounded. In particular - * pow(integer,integer) - * always returns the correct integer provided it is - * representable. - * - * Constants : - * The hexadecimal values are the intended ones for the following - * constants. The decimal values may be used, provided that the - * compiler will convert from decimal to binary accurately enough - * to produce the hexadecimal values shown. - */ - -#include "fdlibm.h" - -static const jdouble -bp[] = {1.0, 1.5,}, -dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */ -dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */ -zero = 0.0, -one = 1.0, -two = 2.0, -two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */ -huge = 1.0e300, -tiny = 1.0e-300, - /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ -L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */ -L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */ -L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */ -L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */ -L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */ -L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */ -P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ -P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ -P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ -P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ -P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */ -lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ -lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */ -lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */ -ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */ -cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */ -cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */ -cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/ -ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ -ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ -ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ - -JNIEXPORT jdouble JNICALL Java_java_lang_Math_pow -(JNIEnv *env, jclass clazz, jdouble x, jdouble y) -{ - jdouble z,ax,z_h,z_l,p_h,p_l; - jdouble y1,t1,t2,r,s,t,u,v,w; - jint i,j,k,yisjint,n; - jint hx,hy,ix,iy; - unsigned lx,ly; - - hx = __HI(x); lx = __LO(x); - hy = __HI(y); ly = __LO(y); - ix = hx&0x7fffffff; iy = hy&0x7fffffff; - - /* y==zero: x**0 = 1 */ - if((iy|ly)==0) return one; - - /* +-NaN return x+y */ - if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) || - iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0))) - return x+y; - - /* determine if y is an odd jint when x < 0 - * yisjint = 0 ... y is not an jinteger - * yisjint = 1 ... y is an odd jint - * yisjint = 2 ... y is an even jint - */ - yisjint = 0; - if(hx<0) { - if(iy>=0x43400000) yisjint = 2; /* even jinteger y */ - else if(iy>=0x3ff00000) { - k = (iy>>20)-0x3ff; /* exponent */ - if(k>20) { - j = ly>>(52-k); - if((j<<(52-k))==ly) yisjint = 2-(j&1); - } else if(ly==0) { - j = iy>>(20-k); - if((j<<(20-k))==iy) yisjint = 2-(j&1); - } - } - } - - /* special value of y */ - if(ly==0) { - if (iy==0x7ff00000) { /* y is +-inf */ - if(((ix-0x3ff00000)|lx)==0) - return y - y; /* inf**+-1 is NaN */ - else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */ - return (hy>=0)? y: zero; - else /* (|x|<1)**-,+inf = inf,0 */ - return (hy<0)?-y: zero; - } - if(iy==0x3ff00000) { /* y is +-1 */ - if(hy<0) return one/x; else return x; - } - if(hy==0x40000000) return x*x; /* y is 2 */ - if(hy==0x3fe00000) { /* y is 0.5 */ - if(hx>=0) /* x >= +0 */ - return sqrt(x); - } - } - - ax = fabs(x); - /* special value of x */ - if(lx==0) { - if(ix==0x7ff00000||ix==0||ix==0x3ff00000){ - z = ax; /*x is +-0,+-inf,+-1*/ - if(hy<0) z = one/z; /* z = (1/|x|) */ - if(hx<0) { - if(((ix-0x3ff00000)|yisjint)==0) { - z = (z-z)/(z-z); /* (-1)**non-jint is NaN */ - } else if(yisjint==1) - z = -z; /* (x<0)**odd = -(|x|**odd) */ - } - return z; - } - } - - /* (x<0)**(non-jint) is NaN */ - if((((hx>>31)+1)|yisjint)==0) return (x-x)/(x-x); - - /* |y| is huge */ - if(iy>0x41e00000) { /* if |y| > 2**31 */ - if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */ - if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny; - if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny; - } - /* over/underflow if x is not close to one */ - if(ix<0x3fefffff) return (hy<0)? huge*huge:tiny*tiny; - if(ix>0x3ff00000) return (hy>0)? huge*huge:tiny*tiny; - /* now |1-x| is tiny <= 2**-20, suffice to compute - log(x) by x-x^2/2+x^3/3-x^4/4 */ - t = x-1; /* t has 20 trailing zeros */ - w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25)); - u = ivln2_h*t; /* ivln2_h has 21 sig. bits */ - v = t*ivln2_l-w*ivln2; - t1 = u+v; - __LO(t1) = 0; - t2 = v-(t1-u); - } else { - jdouble s2,s_h,s_l,t_h,t_l; - n = 0; - /* take care subnormal number */ - if(ix<0x00100000) - {ax *= two53; n -= 53; ix = __HI(ax); } - n += ((ix)>>20)-0x3ff; - j = ix&0x000fffff; - /* determine jinterval */ - ix = j|0x3ff00000; /* normalize ix */ - if(j<=0x3988E) k=0; /* |x|<sqrt(3/2) */ - else if(j<0xBB67A) k=1; /* |x|<sqrt(3) */ - else {k=0;n+=1;ix -= 0x00100000;} - __HI(ax) = ix; - - /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */ - u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */ - v = one/(ax+bp[k]); - s = u*v; - s_h = s; - __LO(s_h) = 0; - /* t_h=ax+bp[k] High */ - t_h = zero; - __HI(t_h)=((ix>>1)|0x20000000)+0x00080000+(k<<18); - t_l = ax - (t_h-bp[k]); - s_l = v*((u-s_h*t_h)-s_h*t_l); - /* compute log(ax) */ - s2 = s*s; - r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); - r += s_l*(s_h+s); - s2 = s_h*s_h; - t_h = 3.0+s2+r; - __LO(t_h) = 0; - t_l = r-((t_h-3.0)-s2); - /* u+v = s*(1+...) */ - u = s_h*t_h; - v = s_l*t_h+t_l*s; - /* 2/(3log2)*(s+...) */ - p_h = u+v; - __LO(p_h) = 0; - p_l = v-(p_h-u); - z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ - z_l = cp_l*p_h+p_l*cp+dp_l[k]; - /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ - t = (jdouble)n; - t1 = (((z_h+z_l)+dp_h[k])+t); - __LO(t1) = 0; - t2 = z_l-(((t1-t)-dp_h[k])-z_h); - } - - s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ - if((((hx>>31)+1)|(yisjint-1))==0) s = -one;/* (-ve)**(odd jint) */ - - /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ - y1 = y; - __LO(y1) = 0; - p_l = (y-y1)*t1+y*t2; - p_h = y1*t1; - z = p_l+p_h; - j = __HI(z); - i = __LO(z); - if (j>=0x40900000) { /* z >= 1024 */ - if(((j-0x40900000)|i)!=0) /* if z > 1024 */ - return s*huge*huge; /* overflow */ - else { - if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */ - } - } else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */ - if(((j-0xc090cc00)|i)!=0) /* z < -1075 */ - return s*tiny*tiny; /* underflow */ - else { - if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */ - } - } - /* - * compute 2**(p_h+p_l) - */ - i = j&0x7fffffff; - k = (i>>20)-0x3ff; - n = 0; - if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ - n = j+(0x00100000>>(k+1)); - k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */ - t = zero; - __HI(t) = (n&~(0x000fffff>>k)); - n = ((n&0x000fffff)|0x00100000)>>(20-k); - if(j<0) n = -n; - p_h -= t; - } - t = p_l+p_h; - __LO(t) = 0; - u = t*lg2_h; - v = (p_l-(t-p_h))*lg2+t*lg2_l; - z = u+v; - w = v-(z-u); - t = z*z; - t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); - r = (z*t1)/(t1-two)-(w+z*w); - z = one-(r-z); - j = __HI(z); - j += (n<<20); - if((j>>20)<=0) z = scalbn(z,n); /* subnormal output */ - else __HI(z) += (n<<20); - return s*z; -} diff --git a/native/jni/remainder.c b/native/jni/remainder.c deleted file mode 100644 index 8ce6b955f..000000000 --- a/native/jni/remainder.c +++ /dev/null @@ -1,68 +0,0 @@ - -/* @(#)e_remainder.c 1.3 95/01/18 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* __ieee754_remainder(x,p) - * Return : - * returns x REM p = x - [x/p]*p as if in infinite - * precise arithmetic, where [x/p] is the (infinite bit) - * integer nearest x/p (in half way case choose the even one). - * Method : - * Based on fmod() return x-[x/p]chopped*p exactlp. - */ - -#include "fdlibm.h" - -static const jdouble zero = 0.0; - -JNIEXPORT jdouble JNICALL Java_java_lang_Math_IEEEremainder -(JNIEnv *env, jclass clazz, jdouble x, jdouble p) -{ - jint hx,hp; - unsigned sx,lx,lp; - jdouble p_half; - - hx = __HI(x); /* high word of x */ - lx = __LO(x); /* low word of x */ - hp = __HI(p); /* high word of p */ - lp = __LO(p); /* low word of p */ - sx = hx&0x80000000; - hp &= 0x7fffffff; - hx &= 0x7fffffff; - - /* purge off exception values */ - if((hp|lp)==0) return (x*p)/(x*p); /* p = 0 */ - if((hx>=0x7ff00000)|| /* x not finite */ - ((hp>=0x7ff00000)&& /* p is NaN */ - (((hp-0x7ff00000)|lp)!=0))) - return (x*p)/(x*p); - - - if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */ - if (((hx-hp)|(lx-lp))==0) return zero*x; - x = fabs(x); - p = fabs(p); - if (hp<0x00200000) { - if(x+x>p) { - x-=p; - if(x+x>=p) x -= p; - } - } else { - p_half = 0.5*p; - if(x>p_half) { - x-=p; - if(x>=p_half) x -= p; - } - } - __HI(x) ^= sx; - return x; -} diff --git a/native/jni/rint.c b/native/jni/rint.c deleted file mode 100644 index 16175f685..000000000 --- a/native/jni/rint.c +++ /dev/null @@ -1,76 +0,0 @@ - -/* @(#)s_rint.c 1.3 95/01/18 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* - * rint(x) - * Return x rounded to integral value according to the prevailing - * rounding mode. - * Method: - * Using floating addition. - * Exception: - * Inexact flag raised if x not equal to rint(x). - */ - -#include "fdlibm.h" - -static const jdouble -TWO52[2]={ - 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ - -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ -}; - -JNIEXPORT jdouble JNICALL Java_java_lang_Math_rint -(JNIEnv *env, jclass clazz, jdouble x) -{ - jint i0,j0,sx; - unsigned i,i1; - jdouble w,t; - i0 = __HI(x); - sx = (i0>>31)&1; - i1 = __LO(x); - j0 = ((i0>>20)&0x7ff)-0x3ff; - if(j0<20) { - if(j0<0) { - if(((i0&0x7fffffff)|i1)==0) return x; - i1 |= (i0&0x0fffff); - i0 &= 0xfffe0000; - i0 |= ((i1|-i1)>>12)&0x80000; - __HI(x)=i0; - w = TWO52[sx]+x; - t = w-TWO52[sx]; - i0 = __HI(t); - __HI(t) = (i0&0x7fffffff)|(sx<<31); - return t; - } else { - i = (0x000fffff)>>j0; - if(((i0&i)|i1)==0) return x; /* x is integral */ - i>>=1; - if(((i0&i)|i1)!=0) { - if(j0==19) i1 = 0x40000000; else - i0 = (i0&(~i))|((0x20000)>>j0); - } - } - } else if (j0>51) { - if(j0==0x400) return x+x; /* inf or NaN */ - else return x; /* x is integral */ - } else { - i = ((unsigned)(0xffffffff))>>(j0-20); - if((i1&i)==0) return x; /* x is integral */ - i>>=1; - if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20)); - } - __HI(x) = i0; - __LO(x) = i1; - w = TWO52[sx]+x; - return w-TWO52[sx]; -} diff --git a/native/jni/s_fabs.c b/native/jni/s_fabs.c deleted file mode 100644 index 973d8fdda..000000000 --- a/native/jni/s_fabs.c +++ /dev/null @@ -1,25 +0,0 @@ - -/* @(#)s_fabs.c 1.3 95/01/18 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* - * fabs(x) returns the absolute value of x. - */ - -#include "fdlibm.h" - -jdouble -fabs (jdouble x) -{ - __HI(x) &= 0x7fffffff; - return x; -} diff --git a/native/jni/sin.c b/native/jni/sin.c deleted file mode 100644 index 620759d98..000000000 --- a/native/jni/sin.c +++ /dev/null @@ -1,76 +0,0 @@ - -/* @(#)s_sin.c 1.3 95/01/18 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* sin(x) - * Return sine function of x. - * - * kernel function: - * __kernel_sin ... sine function on [-pi/4,pi/4] - * __kernel_cos ... cose function on [-pi/4,pi/4] - * __ieee754_rem_pio2 ... argument reduction routine - * - * Method. - * Let S,C and T denote the sin, cos and tan respectively on - * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 - * in [-pi/4 , +pi/4], and let n = k mod 4. - * We have - * - * n sin(x) cos(x) tan(x) - * ---------------------------------------------------------- - * 0 S C T - * 1 C -S -1/T - * 2 -S -C T - * 3 -C S -1/T - * ---------------------------------------------------------- - * - * Special cases: - * Let trig be any of sin, cos, or tan. - * trig(+-INF) is NaN, with signals; - * trig(NaN) is that NaN; - * - * Accuracy: - * TRIG(x) returns trig(x) nearly rounded - */ - -#include "fdlibm.h" - -JNIEXPORT jdouble JNICALL Java_java_lang_Math_sin -(JNIEnv *env, jclass clazz, jdouble x) -{ - jdouble y[2],z=0.0; - jint n, ix; - - /* High word of x. */ - ix = __HI(x); - - /* |x| ~< pi/4 */ - ix &= 0x7fffffff; - if(ix <= 0x3fe921fb) return __kernel_sin (x, z, 0); - - /* sin(Inf or NaN) is NaN */ - else if (ix>=0x7ff00000) return x-x; - - /* argument reduction needed */ - else - { - n = __ieee754_rem_pio2 (x, y); - switch(n&3) - { - case 0: return __kernel_sin (y[0], y[1], 1); - case 1: return __kernel_cos (y[0], y[1]); - case 2: return -__kernel_sin (y[0], y[1], 1); - default: - return -__kernel_cos (y[0], y[1]); - } - } -} diff --git a/native/jni/tan.c b/native/jni/tan.c deleted file mode 100644 index b30761c86..000000000 --- a/native/jni/tan.c +++ /dev/null @@ -1,69 +0,0 @@ - -/* @(#)s_tan.c 1.3 95/01/18 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunSoft, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* tan(x) - * Return tangent function of x. - * - * kernel function: - * __kernel_tan ... tangent function on [-pi/4,pi/4] - * __ieee754_rem_pio2 ... argument reduction routine - * - * Method. - * Let S,C and T denote the sin, cos and tan respectively on - * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 - * in [-pi/4 , +pi/4], and let n = k mod 4. - * We have - * - * n sin(x) cos(x) tan(x) - * ---------------------------------------------------------- - * 0 S C T - * 1 C -S -1/T - * 2 -S -C T - * 3 -C S -1/T - * ---------------------------------------------------------- - * - * Special cases: - * Let trig be any of sin, cos, or tan. - * trig(+-INF) is NaN, with signals; - * trig(NaN) is that NaN; - * - * Accuracy: - * TRIG(x) returns trig(x) nearly rounded - */ - -#include "fdlibm.h" - -JNIEXPORT jdouble JNICALL Java_java_lang_Math_tan -(JNIEnv *env, jclass clazz, jdouble x) -{ - jdouble y[2],z=0.0; - jint n, ix; - - /* High word of x. */ - ix = __HI(x); - - /* |x| ~< pi/4 */ - ix &= 0x7fffffff; - if (ix <= 0x3fe921fb) return __kernel_tan(x,z,1); - - /* tan(Inf or NaN) is NaN */ - else if (ix>=0x7ff00000) return x-x; /* NaN */ - - /* argument reduction needed */ - else - { - n = __ieee754_rem_pio2(x,y); - return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even - -1 -- n odd */ - } -} diff --git a/native/lib/Makefile.am b/native/lib/Makefile.am deleted file mode 100755 index 30312eddc..000000000 --- a/native/lib/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -pkglib_LTLIBRARIES = libclasspath.la - -libclasspath_la_SOURCES = jcl.c jcl.h jnilink.c jnilink.h primlib.c primlib.h - -libclasspath_la_LDFLAGS = -version-info @LIBVERSION@ - -INCLUDES += -I../lib -I../nsa -I../vmi -I. -DNO_VMI @EXTRA_INCLUDES@ \ - -I$(top_srcdir)/include - -clean-local: - -rm -rf .deps - diff --git a/native/lib/jcl.c b/native/lib/jcl.c deleted file mode 100755 index 8347be0a3..000000000 --- a/native/lib/jcl.c +++ /dev/null @@ -1,111 +0,0 @@ -/* jcl.c - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -As a special exception, if you link this library with other files to -produce an executable, this library does not by itself cause the -resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why the -executable file might be covered by the GNU General Public License. */ - -#include <stdio.h> -#include <jcl.h> -#include <malloc.h> - -static char errstr[4098]; // this way the memory is pre-allocated, so that we do not have to worry if we are out of memory. - -JNIEXPORT void JNICALL JCL_ThrowException(JNIEnv * env, char * className, char * errMsg) { - jclass excClass; - if((*env)->ExceptionOccurred(env)) { - (*env)->ExceptionClear(env); - } - excClass = (*env)->FindClass(env, className); - if(excClass == NULL) { - jclass errExcClass; - errExcClass = (*env)->FindClass(env, "java/lang/ClassNotFoundException"); - if(errExcClass == NULL) { - errExcClass = (*env)->FindClass(env, "java/lang/InternalError"); - if(errExcClass == NULL) { - sprintf(errstr,"JCL: Utterly failed to throw exeption %s with message %s.",className,errMsg); - fprintf(stderr, errstr); - return; - } - } - sprintf(errstr,"JCL: Failed to throw exception %s with message %s: could not find exception class.", className, errMsg); - (*env)->ThrowNew(env, errExcClass, errstr); - } - (*env)->ThrowNew(env, excClass, errMsg); -} - -JNIEXPORT void * JNICALL JCL_malloc(JNIEnv * env, size_t size) { - void * mem = malloc(size); - if(mem == NULL) { - JCL_ThrowException(env, "java/lang/OutOfMemoryError", "malloc() failed."); - return NULL; - } - return mem; -} - -JNIEXPORT void JNICALL JCL_free(JNIEnv * env, void * p) { - if(p != NULL) { - free(p); - } -} - -JNIEXPORT char * JNICALL JCL_jstring_to_cstring(JNIEnv * env, jstring s) { - char* cstr; - if(s == NULL) { - JCL_ThrowException(env, "java/lang/NullPointerException","Null string"); - return NULL; - } - cstr = (char*)(*env)->GetStringUTFChars(env, s, NULL); - if(cstr == NULL) { - JCL_ThrowException(env, "java/lang/InternalError", "GetStringUTFChars() failed."); - return NULL; - } - return cstr; -} - -JNIEXPORT void JNICALL JCL_free_cstring(JNIEnv * env, jstring s, char * cstr) { - (*env)->ReleaseStringUTFChars(env, s, cstr); -} - -JNIEXPORT jint JNICALL JCL_MonitorEnter(JNIEnv * env, jobject o) { - jint retval = (*env)->MonitorEnter(env,o); - if(retval != 0) { - JCL_ThrowException(env, "java/lang/InternalError", "MonitorEnter() failed."); - } - return retval; -} - -JNIEXPORT jint JNICALL JCL_MonitorExit(JNIEnv * env, jobject o) { - jint retval = (*env)->MonitorExit(env,o); - if(retval != 0) { - JCL_ThrowException(env, "java/lang/InternalError", "MonitorExit() failed."); - } - return retval; -} - -JNIEXPORT jclass JNICALL JCL_FindClass(JNIEnv * env, char * className) { - jclass retval = (*env)->FindClass(env,className); - if(retval == NULL) { - JCL_ThrowException(env, "java/lang/ClassNotFoundException", className); - } - return retval; -} diff --git a/native/lib/jcl.h b/native/lib/jcl.h deleted file mode 100755 index a0ce87f00..000000000 --- a/native/lib/jcl.h +++ /dev/null @@ -1,52 +0,0 @@ -/* jcl.h - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -As a special exception, if you link this library with other files to -produce an executable, this library does not by itself cause the -resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why the -executable file might be covered by the GNU General Public License. */ - -#ifndef __JCL_H__ -#define __JCL_H__ - -#include <stddef.h> -#include <jni.h> - -JNIEXPORT jclass JNICALL JCL_FindClass(JNIEnv * env, char * className); -JNIEXPORT void JNICALL JCL_ThrowException(JNIEnv * env, char * className, char * errMsg); -JNIEXPORT void * JNICALL JCL_malloc(JNIEnv * env, size_t size); -JNIEXPORT void JNICALL JCL_free(JNIEnv * env, void * p); -JNIEXPORT char * JNICALL JCL_jstring_to_cstring(JNIEnv * env, jstring s); -JNIEXPORT void JNICALL JCL_free_cstring(JNIEnv * env, jstring s, char * cstr); -JNIEXPORT jint JNICALL JCL_MonitorEnter(JNIEnv * env, jobject o); -JNIEXPORT jint JNICALL JCL_MonitorExit(JNIEnv * env, jobject o); - -#define JCL_RETHROW_EXCEPTION(env) if((*(env))->ExceptionOccurred((env)) != NULL) return NULL; - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#endif diff --git a/native/lib/jnilink.c b/native/lib/jnilink.c deleted file mode 100755 index 30843ed64..000000000 --- a/native/lib/jnilink.c +++ /dev/null @@ -1,106 +0,0 @@ -/* JNILINK 1.1: JNI version. - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -As a special exception, if you link this library with other files to -produce an executable, this library does not by itself cause the -resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why the -executable file might be covered by the GNU General Public License. */ - - -#include "jnilink.h" -#include <string.h> -#include <jcl.h> - -#include <malloc.h> - -#define GETCLASS(c) *(jclass*)(c) - -JNIEXPORT jclass JNICALL -LINK_RelinkClass (JNIEnv * env, linkedClass * c, char * name) { - jclass found; - LINK_UnlinkClass(env,*c); - - found = (*env)->FindClass(env,name); - if(found == NULL) - return NULL; - - *c = JCL_malloc(env,sizeof(jclass)); - if(*c == NULL) - return NULL; - - GETCLASS(*c) = (*env)->NewGlobalRef(env,found); - return GETCLASS(*c); -} - -JNIEXPORT jclass JNICALL -LINK_RelinkKnownClass(JNIEnv * env, linkedClass * c, jclass newClass) { - LINK_UnlinkClass(env,*c); - - *c = JCL_malloc(env,sizeof(jclass)); - if(*c == NULL) - return NULL; - - GETCLASS(*c) = (*env)->NewGlobalRef(env,newClass); - return newClass; -} - -JNIEXPORT jmethodID JNICALL -LINK_RelinkMethod (JNIEnv * env, jmethodID * m, linkedClass c, - char * name, char * sig) { - *m = (*env)->GetMethodID(env,GETCLASS(c),name,sig); - return *m; -} - -JNIEXPORT jmethodID JNICALL -LINK_RelinkStaticMethod(JNIEnv * env, jmethodID * m, linkedClass c, - char * name, char * sig) { - *m = (*env)->GetStaticMethodID(env,GETCLASS(c),name,sig); - return *m; -} - -JNIEXPORT jfieldID JNICALL -LINK_RelinkField (JNIEnv * env, jfieldID * f, linkedClass c, - char * name, char * sig) { - *f = (*env)->GetFieldID(env,GETCLASS(c),name,sig); - return *f; -} - -JNIEXPORT jfieldID JNICALL -LINK_RelinkStaticField (JNIEnv * env, jfieldID * f, linkedClass c, - char * name, char * sig) { - *f = (*env)->GetStaticFieldID(env,GETCLASS(c),name,sig); - return *f; -} - - -/* These are for when the class referencing the symbols is unloaded; it -destroys any object references - * the linker might have kept around. - */ -JNIEXPORT void JNICALL LINK_UnlinkClass (JNIEnv * env, linkedClass * c) { - if(*c != NULL) { - if(GETCLASS(*c) != NULL) - (*env)->DeleteGlobalRef(env,GETCLASS(*c)); - JCL_free(env,*c); - *c = NULL; - } -} - diff --git a/native/lib/jnilink.h b/native/lib/jnilink.h deleted file mode 100755 index 99dc3dd6f..000000000 --- a/native/lib/jnilink.h +++ /dev/null @@ -1,75 +0,0 @@ -/* JNILINK 1.1: JNI version. - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -As a special exception, if you link this library with other files to -produce an executable, this library does not by itself cause the -resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why the -executable file might be covered by the GNU General Public License. */ - - -#ifndef __JNILINK_H__ -#define __JNILINK_H__ - -#include <jni.h> - -typedef void* linkedClass; - -#define LINK_LinkClass(env,c,name) ((c)==NULL ? LINK_ReallyLinkClass((env),&(c),(name)) : (c)) -#define LINK_LinkKnownClass(env,c,newClass) ((c)==NULL ? LINK_ReallyLinkKnownClass((env),&(c),(newClass)) : (c)) -#define LINK_LinkMethod(env,m,c,name,sig) ((m)==NULL ? LINK_RelinkMethod((env),&(m),(c),(name),(sig)) : (m)) -#define LINK_LinkStaticMethod(env,m,c,name,sig) ((m)==NULL ? LINK_RelinkStaticMethod((env),&(m),(c),(name),(sig)) : (m)) -#define LINK_LinkField(env,f,c,name,sig) ((m)==NULL ? LINK_RelinkField((env),&(f),(c),(name),(sig)) : (f)) -#define LINK_LinkStaticField(env,f,c,name,sig) ((m)==NULL ? LINK_RelinkStaticField((env),&(f),(c),(name),(sig)) : (f)) - -#define LINK_LinkConstructor(env,m,c,sig) ((m)==NULL ? LINK_RelinkMethod((env),&(m),(c),"<init>",(sig)) : (m)) - -JNIEXPORT jclass JNICALL -LINK_ReallyLinkClass (JNIEnv * env, linkedClass * c, - char * name); -JNIEXPORT jclass JNICALL -LINK_ReallyLinkKnownClass(JNIEnv * env, linkedClass * c, - jclass newClass); -JNIEXPORT jclass JNICALL -LINK_RelinkClass (JNIEnv * env, linkedClass * c, - char * name); -JNIEXPORT jclass JNICALL -LINK_RelinkKnownClass (JNIEnv * env, linkedClass * c, - jclass newClass); -JNIEXPORT jmethodID JNICALL -LINK_RelinkMethod (JNIEnv * env, jmethodID * m, linkedClass c, - char * name, char * sig); -JNIEXPORT jmethodID JNICALL -LINK_RelinkStaticMethod(JNIEnv * env, jmethodID * m, linkedClass c, - char * name, char * sig); -JNIEXPORT jfieldID JNICALL -LINK_RelinkField (JNIEnv * env, jfieldID * f, linkedClass c, - char * name, char * sig); -JNIEXPORT jfieldID JNICALL -LINK_RelinkStaticField (JNIEnv * env, jfieldID * f, linkedClass c, - char * name, char * sig); - -/* These are for when the class referencing the symbols is unloaded; it -destroys any object references - * the linker might have kept around. - */ -JNIEXPORT void JNICALL LINK_UnlinkClass (JNIEnv * env, linkedClass * c); - -#endif diff --git a/native/lib/primlib.c b/native/lib/primlib.c deleted file mode 100755 index b688eca76..000000000 --- a/native/lib/primlib.c +++ /dev/null @@ -1,452 +0,0 @@ -/* primlib.c - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -As a special exception, if you link this library with other files to -produce an executable, this library does not by itself cause the -resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why the -executable file might be covered by the GNU General Public License. */ - -#include <jnilink.h> -#include <primlib.h> -#include <jcl.h> - -static jclass nativeWrapClass[PRIMLIB_NUMTYPES] = {NULL,NULL,NULL, NULL,NULL,NULL, - NULL,NULL,NULL, NULL,NULL,NULL}; - -static jclass nativeTypeClass[PRIMLIB_NUMTYPES] = {NULL,NULL,NULL, NULL,NULL,NULL, - NULL,NULL,NULL, NULL,NULL,NULL}; - -static jmethodID nativeWrapClassConstructor[PRIMLIB_NUMTYPES] = {NULL,NULL,NULL, NULL,NULL,NULL, - NULL,NULL,NULL, NULL,NULL,NULL}; - -static jmethodID nativeWrapClassAccessor[PRIMLIB_NUMTYPES] = {NULL,NULL,NULL, NULL,NULL,NULL, - NULL,NULL,NULL, NULL,NULL,NULL}; - -static char * nativeWrapClassName[PRIMLIB_NUMTYPES] = { - NULL, - NULL, - "java/lang/Boolean", - "java/lang/Byte", - "java/lang/Character", - "java/lang/Short", - "java/lang/Integer", - "java/lang/Long", - "java/lang/Float", - "java/lang/Double", - "java/lang/Void", - NULL - }; - -static char * nativeWrapClassConstructorSig[PRIMLIB_NUMTYPES] = { - NULL, - NULL, - "(Z)V", - "(B)V", - "(C)V", - "(S)V", - "(I)V", - "(J)V", - "(F)V", - "(D)V", - "()V", - NULL - }; - -static char * nativeWrapClassAccessorName[PRIMLIB_NUMTYPES] = { - NULL, - NULL, - "booleanValue", - "byteValue", - "charValue", - "shortValue", - "intValue", - "longValue", - "floatValue", - "doubleValue", - NULL, - NULL -}; - -static char * nativeWrapClassAccessorSig[PRIMLIB_NUMTYPES] = { - NULL, - NULL, - "()Z", - "()B", - "()C", - "()S", - "()I", - "()J", - "()F", - "()D", - NULL, - NULL -}; - - -JNIEXPORT jclass JNICALL PRIMLIB_GetNativeWrapClass(JNIEnv * env, int reflectType) { - return LINK_LinkClass(env,nativeWrapClass[reflectType],nativeWrapClassName[reflectType]); -} - -static jclass ActuallyGetNativeTypeClass(JNIEnv * env, int reflectType) { - jclass wrapClass; - jfieldID typeField; - - wrapClass = PRIMLIB_GetNativeWrapClass(env, reflectType); - if(wrapClass == NULL) - return NULL; - typeField = (*env)->GetStaticFieldID(env, wrapClass, "TYPE", "Ljava/lang/Class"); - if(typeField == NULL) - return NULL; - return (*env)->GetStaticObjectField(env, wrapClass, typeField); -} - -JNIEXPORT jclass JNICALL PRIMLIB_GetNativeTypeClass(JNIEnv * env, int reflectType) { - return LINK_LinkKnownClass(env, nativeTypeClass[reflectType], ActuallyGetNativeTypeClass(env,reflectType)); -} - -JNIEXPORT jmethodID JNICALL PRIMLIB_GetNativeWrapClassConstructor(JNIEnv * env, int reflectType) { - PRIMLIB_GetNativeWrapClass(env,reflectType); - return LINK_LinkConstructor(env, nativeWrapClassConstructor[reflectType], nativeWrapClass[reflectType], nativeWrapClassConstructorSig[reflectType]); -} - -JNIEXPORT jmethodID JNICALL PRIMLIB_GetNativeWrapClassAccessor(JNIEnv * env, int reflectType) { - PRIMLIB_GetNativeWrapClass(env,reflectType); - return LINK_LinkMethod(env, nativeWrapClassAccessor[reflectType], nativeWrapClass[reflectType], nativeWrapClassAccessorName[reflectType], nativeWrapClassAccessorSig[reflectType]); -} - - - -JNIEXPORT jobject JNICALL PRIMLIB_WrapBoolean(JNIEnv * env, jboolean b) { - jmethodID construct = PRIMLIB_GetNativeWrapClassConstructor(env, PRIMLIB_BOOLEAN); - JCL_RETHROW_EXCEPTION(env); - return (*env)->NewObject(env, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_BOOLEAN), construct, b); -} - -JNIEXPORT jobject JNICALL PRIMLIB_WrapByte (JNIEnv * env, jbyte b) { - jmethodID construct = PRIMLIB_GetNativeWrapClassConstructor(env, PRIMLIB_BYTE); - JCL_RETHROW_EXCEPTION(env); - return (*env)->NewObject(env, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_BYTE), construct, b); -} - -JNIEXPORT jobject JNICALL PRIMLIB_WrapChar (JNIEnv * env, jchar c) { - jmethodID construct = PRIMLIB_GetNativeWrapClassConstructor(env, PRIMLIB_CHAR); - JCL_RETHROW_EXCEPTION(env); - return (*env)->NewObject(env, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_CHAR), construct, c); -} - -JNIEXPORT jobject JNICALL PRIMLIB_WrapShort (JNIEnv * env, jshort s) { - jmethodID construct = PRIMLIB_GetNativeWrapClassConstructor(env, PRIMLIB_SHORT); - JCL_RETHROW_EXCEPTION(env); - return (*env)->NewObject(env, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_SHORT), construct, s); -} - -JNIEXPORT jobject JNICALL PRIMLIB_WrapInt (JNIEnv * env, jint i) { - jmethodID construct = PRIMLIB_GetNativeWrapClassConstructor(env, PRIMLIB_INT); - JCL_RETHROW_EXCEPTION(env); - return (*env)->NewObject(env, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_INT), construct, i); -} - -JNIEXPORT jobject JNICALL PRIMLIB_WrapLong (JNIEnv * env, jlong l) { - jmethodID construct = PRIMLIB_GetNativeWrapClassConstructor(env, PRIMLIB_LONG); - JCL_RETHROW_EXCEPTION(env); - return (*env)->NewObject(env, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_LONG), construct, l); -} - -JNIEXPORT jobject JNICALL PRIMLIB_WrapFloat (JNIEnv * env, jfloat f) { - jmethodID construct = PRIMLIB_GetNativeWrapClassConstructor(env, PRIMLIB_FLOAT); - JCL_RETHROW_EXCEPTION(env); - return (*env)->NewObject(env, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_FLOAT), construct, f); -} - -JNIEXPORT jobject JNICALL PRIMLIB_WrapDouble (JNIEnv * env, jdouble d) { - jmethodID construct = PRIMLIB_GetNativeWrapClassConstructor(env, PRIMLIB_DOUBLE); - JCL_RETHROW_EXCEPTION(env); - return (*env)->NewObject(env, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_DOUBLE), construct, d); -} - - -JNIEXPORT jboolean JNICALL PRIMLIB_UnwrapBoolean(JNIEnv * env, jobject obj) { - if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_BOOLEAN))) { - return PRIMLIB_GetBooleanObjectValue(env, obj); - } else { - JCL_ThrowException(env, "java/lang/IllegalArgumentException", "Argument not of correct type."); - return JNI_FALSE; - } -} - -JNIEXPORT jbyte JNICALL PRIMLIB_UnwrapByte(JNIEnv * env, jobject obj) { - if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_BYTE))) { - return PRIMLIB_GetByteObjectValue(env, obj); - } else { - JCL_ThrowException(env, "java/lang/IllegalArgumentException", "Argument not of correct type."); - return 0; - } -} - -JNIEXPORT jshort JNICALL PRIMLIB_UnwrapShort(JNIEnv * env, jobject obj) { - if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_SHORT))) { - return PRIMLIB_GetShortObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_BYTE))) { - return (jshort)PRIMLIB_GetByteObjectValue(env, obj); - } else { - JCL_ThrowException(env, "java/lang/IllegalArgumentException", "Argument not of correct type."); - return 0; - } -} - -JNIEXPORT jchar JNICALL PRIMLIB_UnwrapChar(JNIEnv * env, jobject obj) { - if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_CHAR))) { - return PRIMLIB_GetCharObjectValue(env, obj); - } else { - JCL_ThrowException(env, "java/lang/IllegalArgumentException", "Argument not of correct type."); - return 0; - } -} - -JNIEXPORT jint JNICALL PRIMLIB_UnwrapInt(JNIEnv * env, jobject obj) { - if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_INT))) { - return PRIMLIB_GetIntObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_SHORT))) { - return (jint)PRIMLIB_GetShortObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_CHAR))) { - return (jint)PRIMLIB_GetCharObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_BYTE))) { - return (jint)PRIMLIB_GetByteObjectValue(env, obj); - } else { - JCL_ThrowException(env, "java/lang/IllegalArgumentException", "Argument not of correct type."); - return 0; - } -} - -JNIEXPORT jlong JNICALL PRIMLIB_UnwrapLong(JNIEnv * env, jobject obj) { - if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_LONG))) { - return PRIMLIB_GetLongObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_INT))) { - return (jlong)PRIMLIB_GetIntObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_SHORT))) { - return (jlong)PRIMLIB_GetShortObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_CHAR))) { - return (jlong)PRIMLIB_GetCharObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_BYTE))) { - return (jlong)PRIMLIB_GetByteObjectValue(env, obj); - } else { - JCL_ThrowException(env, "java/lang/IllegalArgumentException", "Argument not of correct type."); - return 0; - } -} - -JNIEXPORT jfloat JNICALL PRIMLIB_UnwrapFloat(JNIEnv * env, jobject obj) { - if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_FLOAT))) { - return PRIMLIB_GetFloatObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_LONG))) { - return (jfloat)PRIMLIB_GetLongObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_INT))) { - return (jfloat)PRIMLIB_GetIntObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_SHORT))) { - return (jfloat)PRIMLIB_GetShortObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_CHAR))) { - return (jfloat)PRIMLIB_GetCharObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_BYTE))) { - return (jfloat)PRIMLIB_GetByteObjectValue(env, obj); - } else { - JCL_ThrowException(env, "java/lang/IllegalArgumentException", "Argument not of correct type."); - return 0; - } -} - -JNIEXPORT jdouble JNICALL PRIMLIB_UnwrapDouble(JNIEnv * env, jobject obj) { - if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_DOUBLE))) { - return PRIMLIB_GetDoubleObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_FLOAT))) { - return (jdouble)PRIMLIB_GetFloatObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_LONG))) { - return (jdouble)PRIMLIB_GetLongObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_INT))) { - return (jdouble)PRIMLIB_GetIntObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_SHORT))) { - return (jdouble)PRIMLIB_GetShortObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_CHAR))) { - return (jdouble)PRIMLIB_GetCharObjectValue(env, obj); - } else if((*env)->IsInstanceOf(env, obj, PRIMLIB_GetNativeWrapClass(env, PRIMLIB_BYTE))) { - return (jdouble)PRIMLIB_GetByteObjectValue(env, obj); - } else { - JCL_ThrowException(env, "java/lang/IllegalArgumentException", "Argument not of correct type."); - return 0; - } -} - -JNIEXPORT jint JNICALL PRIMLIB_GetReflectiveWrapperType(JNIEnv * env, jobject obj) { - jclass typeClass; - if(obj == NULL) { - return PRIMLIB_NULL; - } - - typeClass = PRIMLIB_GetNativeWrapClass(env, PRIMLIB_DOUBLE); - if((*env)->IsInstanceOf(env, obj, typeClass)) { - return PRIMLIB_DOUBLE; - } - typeClass = PRIMLIB_GetNativeWrapClass(env, PRIMLIB_FLOAT); - if((*env)->IsInstanceOf(env, obj, typeClass)) { - return PRIMLIB_FLOAT; - } - typeClass = PRIMLIB_GetNativeWrapClass(env, PRIMLIB_LONG); - if((*env)->IsInstanceOf(env, obj, typeClass)) { - return PRIMLIB_LONG; - } - typeClass = PRIMLIB_GetNativeWrapClass(env, PRIMLIB_INT); - if((*env)->IsInstanceOf(env, obj, typeClass)) { - return PRIMLIB_INT; - } - typeClass = PRIMLIB_GetNativeWrapClass(env, PRIMLIB_CHAR); - if((*env)->IsInstanceOf(env, obj, typeClass)) { - return PRIMLIB_CHAR; - } - typeClass = PRIMLIB_GetNativeWrapClass(env, PRIMLIB_SHORT); - if((*env)->IsInstanceOf(env, obj, typeClass)) { - return PRIMLIB_SHORT; - } - typeClass = PRIMLIB_GetNativeWrapClass(env, PRIMLIB_BYTE); - if((*env)->IsInstanceOf(env, obj, typeClass)) { - return PRIMLIB_BYTE; - } - typeClass = PRIMLIB_GetNativeWrapClass(env, PRIMLIB_BOOLEAN); - if((*env)->IsInstanceOf(env, obj, typeClass)) { - return PRIMLIB_BOOLEAN; - } - typeClass = PRIMLIB_GetNativeWrapClass(env, PRIMLIB_VOID); - if((*env)->IsInstanceOf(env, obj, typeClass)) { - return PRIMLIB_VOID; - } - return PRIMLIB_OBJECT; -} - -JNIEXPORT jint JNICALL PRIMLIB_GetReflectiveType(JNIEnv * env, jclass returnType) { - jclass typeClass = PRIMLIB_GetNativeTypeClass(env, PRIMLIB_DOUBLE); - if((*env)->IsAssignableFrom(env, returnType, typeClass)) { - return PRIMLIB_DOUBLE; - } - typeClass = PRIMLIB_GetNativeTypeClass(env, PRIMLIB_FLOAT); - if((*env)->IsAssignableFrom(env, returnType, typeClass)) { - return PRIMLIB_FLOAT; - } - typeClass = PRIMLIB_GetNativeTypeClass(env, PRIMLIB_LONG); - if((*env)->IsAssignableFrom(env, returnType, typeClass)) { - return PRIMLIB_LONG; - } - typeClass = PRIMLIB_GetNativeTypeClass(env, PRIMLIB_INT); - if((*env)->IsAssignableFrom(env, returnType, typeClass)) { - return PRIMLIB_INT; - } - typeClass = PRIMLIB_GetNativeTypeClass(env, PRIMLIB_CHAR); - if((*env)->IsAssignableFrom(env, returnType, typeClass)) { - return PRIMLIB_CHAR; - } - typeClass = PRIMLIB_GetNativeTypeClass(env, PRIMLIB_SHORT); - if((*env)->IsAssignableFrom(env, returnType, typeClass)) { - return PRIMLIB_SHORT; - } - typeClass = PRIMLIB_GetNativeTypeClass(env, PRIMLIB_BYTE); - if((*env)->IsAssignableFrom(env, returnType, typeClass)) { - return PRIMLIB_BYTE; - } - typeClass = PRIMLIB_GetNativeTypeClass(env, PRIMLIB_BOOLEAN); - if((*env)->IsAssignableFrom(env, returnType, typeClass)) { - return PRIMLIB_BOOLEAN; - } - typeClass = PRIMLIB_GetNativeTypeClass(env, PRIMLIB_VOID); - if((*env)->IsAssignableFrom(env, returnType, typeClass)) { - return PRIMLIB_VOID; - } - return PRIMLIB_OBJECT; -} - - -JNIEXPORT jboolean JNICALL PRIMLIB_GetBooleanObjectValue(JNIEnv * env, jobject obj) { - jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor(env, PRIMLIB_BOOLEAN); - return (*env)->CallBooleanMethod(env, obj, acc); -} - -JNIEXPORT jbyte JNICALL PRIMLIB_GetByteObjectValue(JNIEnv * env, jobject obj) { - jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor(env, PRIMLIB_BYTE); - return (*env)->CallByteMethod(env, obj, acc); -} - -JNIEXPORT jshort JNICALL PRIMLIB_GetShortObjectValue(JNIEnv * env, jobject obj) { - jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor(env, PRIMLIB_SHORT); - return (*env)->CallShortMethod(env, obj, acc); -} - -JNIEXPORT jchar JNICALL PRIMLIB_GetCharObjectValue(JNIEnv * env, jobject obj) { - jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor(env, PRIMLIB_CHAR); - return (*env)->CallCharMethod(env, obj, acc); -} - -JNIEXPORT jint JNICALL PRIMLIB_GetIntObjectValue(JNIEnv * env, jobject obj) { - jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor(env, PRIMLIB_INT); - return (*env)->CallIntMethod(env, obj, acc); -} - -JNIEXPORT jlong JNICALL PRIMLIB_GetLongObjectValue(JNIEnv * env, jobject obj) { - jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor(env, PRIMLIB_LONG); - return (*env)->CallLongMethod(env, obj, acc); -} - -JNIEXPORT jfloat JNICALL PRIMLIB_GetFloatObjectValue(JNIEnv * env, jobject obj) { - jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor(env, PRIMLIB_FLOAT); - return (*env)->CallFloatMethod(env, obj, acc); -} - -JNIEXPORT jdouble JNICALL PRIMLIB_GetDoubleObjectValue(JNIEnv * env, jobject obj) { - jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor(env, PRIMLIB_DOUBLE); - return (*env)->CallDoubleMethod(env, obj, acc); -} - - - -JNIEXPORT jvalue JNICALL PRIMLIB_UnwrapJValue(JNIEnv* env, jobject obj, jclass classType) { - jvalue retval; - jint objType = PRIMLIB_GetReflectiveType(env, classType); - if(objType == PRIMLIB_BOOLEAN) { - retval.z = PRIMLIB_UnwrapBoolean(env,obj); - } else if(objType == PRIMLIB_BYTE) { - retval.b = PRIMLIB_UnwrapByte(env,obj); - } else if(objType == PRIMLIB_CHAR) { - retval.c = PRIMLIB_UnwrapChar(env,obj); - } else if(objType == PRIMLIB_SHORT) { - retval.s = PRIMLIB_UnwrapShort(env,obj); - } else if(objType == PRIMLIB_INT) { - retval.i = PRIMLIB_UnwrapInt(env,obj); - } else if(objType == PRIMLIB_LONG) { - retval.j = PRIMLIB_UnwrapLong(env,obj); - } else if(objType == PRIMLIB_FLOAT) { - retval.f = PRIMLIB_UnwrapFloat(env,obj); - } else if(objType == PRIMLIB_DOUBLE) { - retval.d = PRIMLIB_UnwrapDouble(env,obj); - } else { - if(obj != NULL && !(*env)->IsInstanceOf(env, obj, classType)) { - JCL_ThrowException(env, "java/lang/IllegalArgumentException", "Argument not of correct object type."); - return retval; - } - retval.l = obj; - } - return retval; -} - diff --git a/native/lib/primlib.h b/native/lib/primlib.h deleted file mode 100644 index 068f3318e..000000000 --- a/native/lib/primlib.h +++ /dev/null @@ -1,91 +0,0 @@ -/* primlib.h - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -As a special exception, if you link this library with other files to -produce an executable, this library does not by itself cause the -resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why the -executable file might be covered by the GNU General Public License. */ - -#ifndef __PRIMLIB_H__ -#define __PRIMLIB_H__ - -#include <jni.h> - -#define PRIMLIB_UNKNOWN 0 -#define PRIMLIB_OBJECT 1 -#define PRIMLIB_BOOLEAN 2 -#define PRIMLIB_BYTE 3 -#define PRIMLIB_CHAR 4 -#define PRIMLIB_SHORT 5 -#define PRIMLIB_INT 6 -#define PRIMLIB_LONG 7 -#define PRIMLIB_FLOAT 8 -#define PRIMLIB_DOUBLE 9 -#define PRIMLIB_VOID 10 -#define PRIMLIB_NULL 11 -#define PRIMLIB_NUMTYPES 12 - -/* Low-level primitive class accessor functions. */ -JNIEXPORT jclass JNICALL PRIMLIB_GetNativeWrapClass(JNIEnv * env, int reflectType); -JNIEXPORT jclass JNICALL PRIMLIB_GetNativeTypeClass(JNIEnv * env, int reflectType); -JNIEXPORT jmethodID JNICALL PRIMLIB_GetNativeWrapClassConstructor(JNIEnv * env, int reflectType); -JNIEXPORT jmethodID JNICALL PRIMLIB_GetNativeWrapClassAccessor(JNIEnv * env, int reflectType); - -/* Type discovery functions: WrapperType finds out j.l.Boolean/Byte/etc., and - Type finds out j.l.Boolean.TYPE, etc. -*/ -JNIEXPORT jint JNICALL PRIMLIB_GetReflectiveWrapperType(JNIEnv * env, jobject obj); -JNIEXPORT jint JNICALL PRIMLIB_GetReflectiveType(JNIEnv * env, jclass returnType); - -/* Constructor functions. */ -JNIEXPORT jobject JNICALL PRIMLIB_WrapBoolean(JNIEnv * env, jboolean b); -JNIEXPORT jobject JNICALL PRIMLIB_WrapByte (JNIEnv * env, jbyte b); -JNIEXPORT jobject JNICALL PRIMLIB_WrapChar (JNIEnv * env, jchar c); -JNIEXPORT jobject JNICALL PRIMLIB_WrapShort (JNIEnv * env, jshort s); -JNIEXPORT jobject JNICALL PRIMLIB_WrapInt (JNIEnv * env, jint i); -JNIEXPORT jobject JNICALL PRIMLIB_WrapLong (JNIEnv * env, jlong l); -JNIEXPORT jobject JNICALL PRIMLIB_WrapFloat (JNIEnv * env, jfloat f); -JNIEXPORT jobject JNICALL PRIMLIB_WrapDouble (JNIEnv * env, jdouble d); - -/* Widening conversion unwrapping functions. */ -JNIEXPORT jboolean JNICALL PRIMLIB_UnwrapBoolean(JNIEnv * env, jobject obj); -JNIEXPORT jbyte JNICALL PRIMLIB_UnwrapByte (JNIEnv * env, jobject obj); -JNIEXPORT jshort JNICALL PRIMLIB_UnwrapShort (JNIEnv * env, jobject obj); -JNIEXPORT jchar JNICALL PRIMLIB_UnwrapChar (JNIEnv * env, jobject obj); -JNIEXPORT jint JNICALL PRIMLIB_UnwrapInt (JNIEnv * env, jobject obj); -JNIEXPORT jlong JNICALL PRIMLIB_UnwrapLong (JNIEnv * env, jobject obj); -JNIEXPORT jfloat JNICALL PRIMLIB_UnwrapFloat (JNIEnv * env, jobject obj); -JNIEXPORT jdouble JNICALL PRIMLIB_UnwrapDouble (JNIEnv * env, jobject obj); - -/* Simple unwrapping functions. Objects *must* be of correct type. */ -JNIEXPORT jboolean JNICALL PRIMLIB_GetBooleanObjectValue(JNIEnv * env, jobject obj); -JNIEXPORT jbyte JNICALL PRIMLIB_GetByteObjectValue (JNIEnv * env, jobject obj); -JNIEXPORT jshort JNICALL PRIMLIB_GetShortObjectValue (JNIEnv * env, jobject obj); -JNIEXPORT jchar JNICALL PRIMLIB_GetCharObjectValue (JNIEnv * env, jobject obj); -JNIEXPORT jint JNICALL PRIMLIB_GetIntObjectValue (JNIEnv * env, jobject obj); -JNIEXPORT jlong JNICALL PRIMLIB_GetLongObjectValue (JNIEnv * env, jobject obj); -JNIEXPORT jfloat JNICALL PRIMLIB_GetFloatObjectValue (JNIEnv * env, jobject obj); -JNIEXPORT jdouble JNICALL PRIMLIB_GetDoubleObjectValue (JNIEnv * env, jobject obj); - -/* jvalue conversion: Unwrap obj to the type of classType, with widening conversion. */ -JNIEXPORT jvalue JNICALL PRIMLIB_UnwrapJValue(JNIEnv* env, jobject obj, jclass classType); - -#endif diff --git a/native/nsa/native_state.c b/native/nsa/native_state.c deleted file mode 100644 index a7bccfb64..000000000 --- a/native/nsa/native_state.c +++ /dev/null @@ -1,238 +0,0 @@ -/* Magical NSA API -- Associate a C ptr with an instance of an object - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -As a special exception, if you link this library with other files to -produce an executable, this library does not by itself cause the -resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why the -executable file might be covered by the GNU General Public License. */ - -#include <stdlib.h> -#include <jni.h> -#include "native_state.h" - -#define DEFAULT_TABLE_SIZE 97 - -struct state_table * -init_state_table_with_size (JNIEnv *env, jclass clazz, jint size) -{ - struct state_table *table; - jfieldID hash; - jclass clazz_g; - - hash = (*env)->GetFieldID (env, clazz, "native_state", "I"); - if (hash == NULL) - return NULL; - - clazz_g = (*env)->NewGlobalRef (env, clazz); - if (clazz_g == NULL) - return NULL; - - table = (struct state_table *) malloc (sizeof (struct state_table)); - table->size = size; - table->head = (struct state_node **) calloc (sizeof (struct state_node *), - table->size); - table->hash = hash; - table->clazz = clazz_g; - - return table; -} - -struct state_table * -init_state_table (JNIEnv *env, jclass clazz) -{ - return init_state_table_with_size (env, clazz, DEFAULT_TABLE_SIZE); -} - -static -void * -remove_node (struct state_node **head, jint obj_id) -{ - struct state_node *back_ptr = NULL; - struct state_node *node = *head; - - while (node != NULL) - { - if (node->key == obj_id) - { - void *return_value; - if (back_ptr == NULL) - *head = node->next; - else - back_ptr->next = node->next; - return_value = node->c_state; - free (node); - return return_value; - } - back_ptr = node; - node = node->next; - } - - return NULL; -} - -static -void * -get_node (struct state_node **head, jint obj_id) -{ - struct state_node *back_ptr = NULL; - struct state_node *node = *head; - - while (node != NULL) - { - if (node->key == obj_id) - { - /* move the node we found to the front of the list */ - if (back_ptr != NULL) - { - back_ptr->next = node->next; - node->next = *head; - *head = node; - } - - /* return the match */ - return node->c_state; - } - - back_ptr = node; - node = node->next; - } - - return NULL; -} - -static -void -add_node (struct state_node **head, jint obj_id, void *state) -{ - struct state_node *node = *head; - struct state_node *back_ptr = *head; - - struct state_node *new_node; - new_node = (struct state_node *) malloc (sizeof (struct state_node)); - new_node->key = obj_id; - new_node->c_state = state; - - /* insert into an empty slot */ - if (node == NULL) - { - new_node->next = NULL; - *head = new_node; - return; - } - - /* collision resolution */ - /* try to find the old node, if it exists */ - while (node->next != NULL && obj_id != node->key) - { - back_ptr = node; - node = node->next; - } - - /* if we're updating a node, setup to move it to the front of the list */ - if (node->key == obj_id) - back_ptr->next = node->next; - - /* move node to the beginning */ - new_node->next = *head; - *head = new_node; -} - -void -set_state_oid (JNIEnv *env, jobject lock, struct state_table *table, - jint obj_id, void *state) -{ - jint hash; - - hash = obj_id % table->size; - - (*env)->MonitorEnter (env, lock); - add_node (&table->head[hash], obj_id, state); - (*env)->MonitorExit (env, lock); -} - -void * -get_state_oid (JNIEnv *env, jobject lock, struct state_table *table, - jint obj_id) -{ - jint hash; - void *return_value; - - hash = obj_id % table->size; - - (*env)->MonitorEnter (env, lock); - return_value = get_node (&table->head[hash], obj_id); - (*env)->MonitorExit (env, lock); - - return return_value; -} - -void * -remove_state_oid (JNIEnv *env, jobject lock, struct state_table *table, - jint obj_id) -{ - jint hash; - void *return_value; - - hash = obj_id % table->size; - - (*env)->MonitorEnter (env, lock); - return_value = remove_node (&table->head[hash], obj_id); - (*env)->MonitorExit (env, lock); - - return return_value; -} - -int -set_state (JNIEnv *env, jobject obj, struct state_table *table, void *state) -{ - jint obj_id; - obj_id = (*env)->GetIntField (env, obj, table->hash); - - if ((*env)->ExceptionOccurred (env) != NULL) - return -1; - - set_state_oid (env, table->clazz, table, obj_id, state); - return 0; -} - -void * -get_state (JNIEnv *env, jobject obj, struct state_table *table) -{ - jint obj_id; - obj_id = (*env)->GetIntField (env, obj, table->hash); - - if ((*env)->ExceptionOccurred (env) != NULL) - return NULL; - - return get_state_oid (env, table->clazz, table, obj_id); -} - -void * -remove_state_slot (JNIEnv *env, jobject obj, struct state_table *table) -{ - jint obj_id; - obj_id = (*env)->GetIntField (env, obj, table->hash); - - if ((*env)->ExceptionOccurred (env) != NULL) - return NULL; - - return remove_state_oid (env, table->clazz, table, obj_id); -} diff --git a/native/nsa/native_state.h b/native/nsa/native_state.h deleted file mode 100644 index ce04e4f9d..000000000 --- a/native/nsa/native_state.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Magical NSA API -- Associate a C ptr with an instance of an object - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -As a special exception, if you link this library with other files to -produce an executable, this library does not by itself cause the -resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why the -executable file might be covered by the GNU General Public License. */ - -#ifndef JCL_NATIVE_STATE -#define JCL_NATIVE_STATE - -#include <jni.h> - -struct state_table -{ - jint size; /* number of slots, should be prime */ - jfieldID hash; /* field containing System.identityHashCode(this) */ - jclass clazz; /* lock aquired for reading/writing nodes */ - struct state_node **head; -}; - -struct state_node -{ - jint key; - void *c_state; - struct state_node *next; -}; - -struct state_table * init_state_table_with_size (JNIEnv *, jclass, jint); -struct state_table * init_state_table (JNIEnv *, jclass); - -/* lowlevel api */ -void set_state_oid (JNIEnv *, jobject, struct state_table *, jint, void *); -void * get_state_oid (JNIEnv *, jobject, struct state_table *, jint); -void * remove_state_oid (JNIEnv *, jobject, struct state_table *, jint); - -/* highlevel api */ -int set_state (JNIEnv *, jobject, struct state_table *, void *); -void * get_state (JNIEnv *, jobject, struct state_table *); -void * remove_state_slot (JNIEnv *, jobject, struct state_table *); - -#endif diff --git a/vm/reference/java/lang/Thread.java b/vm/reference/java/lang/Thread.java index 437108460..847e32cca 100644 --- a/vm/reference/java/lang/Thread.java +++ b/vm/reference/java/lang/Thread.java @@ -171,7 +171,7 @@ public class Thread implements Runnable { this(null,toRun,name); } - private Thread(ThreadGroup group, String name) { + public Thread(ThreadGroup group, String name) { this(group,null,name); } |