summaryrefslogtreecommitdiff
path: root/libjava/java/lang
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/lang')
-rw-r--r--libjava/java/lang/AbstractMethodError.java34
-rw-r--r--libjava/java/lang/ArithmeticException.java32
-rw-r--r--libjava/java/lang/ArrayIndexOutOfBoundsException.java37
-rw-r--r--libjava/java/lang/ArrayStoreException.java32
-rw-r--r--libjava/java/lang/Boolean.java95
-rw-r--r--libjava/java/lang/Byte.java144
-rw-r--r--libjava/java/lang/Character.java286
-rw-r--r--libjava/java/lang/Class.h214
-rw-r--r--libjava/java/lang/Class.java155
-rw-r--r--libjava/java/lang/ClassCastException.java32
-rw-r--r--libjava/java/lang/ClassCircularityError.java34
-rw-r--r--libjava/java/lang/ClassFormatError.java34
-rw-r--r--libjava/java/lang/ClassLoader.java94
-rw-r--r--libjava/java/lang/ClassNotFoundException.java57
-rw-r--r--libjava/java/lang/CloneNotSupportedException.java32
-rw-r--r--libjava/java/lang/Cloneable.java23
-rw-r--r--libjava/java/lang/Comparable.java22
-rw-r--r--libjava/java/lang/Compiler.java53
-rw-r--r--libjava/java/lang/Double.java149
-rw-r--r--libjava/java/lang/Error.java34
-rw-r--r--libjava/java/lang/Exception.java32
-rw-r--r--libjava/java/lang/ExceptionInInitializerError.java50
-rw-r--r--libjava/java/lang/FirstThread.java40
-rw-r--r--libjava/java/lang/Float.java149
-rw-r--r--libjava/java/lang/IllegalAccessError.java34
-rw-r--r--libjava/java/lang/IllegalAccessException.java32
-rw-r--r--libjava/java/lang/IllegalArgumentException.java32
-rw-r--r--libjava/java/lang/IllegalMonitorStateException.java32
-rw-r--r--libjava/java/lang/IllegalStateException.java32
-rw-r--r--libjava/java/lang/IllegalThreadStateException.java32
-rw-r--r--libjava/java/lang/IncompatibleClassChangeError.java34
-rw-r--r--libjava/java/lang/IndexOutOfBoundsException.java32
-rw-r--r--libjava/java/lang/InstantiationError.java34
-rw-r--r--libjava/java/lang/InstantiationException.java32
-rw-r--r--libjava/java/lang/Integer.java355
-rw-r--r--libjava/java/lang/InternalError.java34
-rw-r--r--libjava/java/lang/InterruptedException.java32
-rw-r--r--libjava/java/lang/LinkageError.java34
-rw-r--r--libjava/java/lang/Long.java366
-rw-r--r--libjava/java/lang/Math.java118
-rw-r--r--libjava/java/lang/NegativeArraySizeException.java32
-rw-r--r--libjava/java/lang/NoClassDefFoundError.java34
-rw-r--r--libjava/java/lang/NoSuchFieldError.java34
-rw-r--r--libjava/java/lang/NoSuchFieldException.java32
-rw-r--r--libjava/java/lang/NoSuchMethodError.java34
-rw-r--r--libjava/java/lang/NoSuchMethodException.java32
-rw-r--r--libjava/java/lang/NullPointerException.java32
-rw-r--r--libjava/java/lang/Number.java39
-rw-r--r--libjava/java/lang/NumberFormatException.java32
-rw-r--r--libjava/java/lang/Object.h79
-rw-r--r--libjava/java/lang/Object.java86
-rw-r--r--libjava/java/lang/OutOfMemoryError.java34
-rw-r--r--libjava/java/lang/Process.java30
-rw-r--r--libjava/java/lang/Runnable.java27
-rw-r--r--libjava/java/lang/Runtime.java136
-rw-r--r--libjava/java/lang/RuntimeException.java32
-rw-r--r--libjava/java/lang/SecurityException.java31
-rw-r--r--libjava/java/lang/SecurityManager.java263
-rw-r--r--libjava/java/lang/Short.java145
-rw-r--r--libjava/java/lang/StackOverflowError.java34
-rw-r--r--libjava/java/lang/String.java286
-rw-r--r--libjava/java/lang/StringBuffer.java270
-rw-r--r--libjava/java/lang/StringIndexOutOfBoundsException.java37
-rw-r--r--libjava/java/lang/System.java166
-rw-r--r--libjava/java/lang/Thread.java297
-rw-r--r--libjava/java/lang/ThreadDeath.java35
-rw-r--r--libjava/java/lang/ThreadGroup.java406
-rw-r--r--libjava/java/lang/Throwable.java80
-rw-r--r--libjava/java/lang/UnknownError.java34
-rw-r--r--libjava/java/lang/UnsatisfiedLinkError.java34
-rw-r--r--libjava/java/lang/UnsupportedOperationException.java32
-rw-r--r--libjava/java/lang/VerifyError.java34
-rw-r--r--libjava/java/lang/VirtualMachineError.java34
-rw-r--r--libjava/java/lang/Void.java30
-rw-r--r--libjava/java/lang/dtoa.c906
-rw-r--r--libjava/java/lang/e_acos.c111
-rw-r--r--libjava/java/lang/e_asin.c120
-rw-r--r--libjava/java/lang/e_atan2.c131
-rw-r--r--libjava/java/lang/e_exp.c167
-rw-r--r--libjava/java/lang/e_fmod.c140
-rw-r--r--libjava/java/lang/e_log.c152
-rw-r--r--libjava/java/lang/e_pow.c312
-rw-r--r--libjava/java/lang/e_rem_pio2.c185
-rw-r--r--libjava/java/lang/e_remainder.c80
-rw-r--r--libjava/java/lang/e_scalb.c55
-rw-r--r--libjava/java/lang/e_sqrt.c452
-rw-r--r--libjava/java/lang/fdlibm.h343
-rw-r--r--libjava/java/lang/ieeefp.h103
-rw-r--r--libjava/java/lang/k_cos.c96
-rw-r--r--libjava/java/lang/k_rem_pio2.c320
-rw-r--r--libjava/java/lang/k_sin.c79
-rw-r--r--libjava/java/lang/k_tan.c132
-rw-r--r--libjava/java/lang/mprec.c958
-rw-r--r--libjava/java/lang/mprec.h374
-rw-r--r--libjava/java/lang/natCharacter.cc269
-rw-r--r--libjava/java/lang/natClass.cc785
-rw-r--r--libjava/java/lang/natDouble.cc180
-rw-r--r--libjava/java/lang/natFirstThread.cc56
-rw-r--r--libjava/java/lang/natFloat.cc37
-rw-r--r--libjava/java/lang/natMath.cc263
-rw-r--r--libjava/java/lang/natObject.cc241
-rw-r--r--libjava/java/lang/natRuntime.cc68
-rw-r--r--libjava/java/lang/natString.cc800
-rw-r--r--libjava/java/lang/natSystem.cc259
-rw-r--r--libjava/java/lang/natThread.cc295
-rw-r--r--libjava/java/lang/reflect/AccessibleObject.java53
-rw-r--r--libjava/java/lang/reflect/Array.java78
-rw-r--r--libjava/java/lang/reflect/Constructor.java106
-rw-r--r--libjava/java/lang/reflect/Field.java264
-rw-r--r--libjava/java/lang/reflect/InvocationTargetException.java73
-rw-r--r--libjava/java/lang/reflect/Member.java26
-rw-r--r--libjava/java/lang/reflect/Method.java123
-rw-r--r--libjava/java/lang/reflect/Modifier.java130
-rw-r--r--libjava/java/lang/reflect/natArray.cc339
-rw-r--r--libjava/java/lang/reflect/natField.cc435
-rw-r--r--libjava/java/lang/reflect/natMethod.cc386
-rw-r--r--libjava/java/lang/s_atan.c181
-rw-r--r--libjava/java/lang/s_ceil.c80
-rw-r--r--libjava/java/lang/s_copysign.c82
-rw-r--r--libjava/java/lang/s_cos.c82
-rw-r--r--libjava/java/lang/s_fabs.c73
-rw-r--r--libjava/java/lang/s_floor.c134
-rw-r--r--libjava/java/lang/s_rint.c87
-rw-r--r--libjava/java/lang/s_scalbn.c104
-rw-r--r--libjava/java/lang/s_sin.c132
-rw-r--r--libjava/java/lang/s_tan.c114
-rw-r--r--libjava/java/lang/sf_rint.c80
-rw-r--r--libjava/java/lang/strtod.c720
-rw-r--r--libjava/java/lang/w_acos.c118
-rw-r--r--libjava/java/lang/w_asin.c121
-rw-r--r--libjava/java/lang/w_atan2.c117
-rw-r--r--libjava/java/lang/w_exp.c136
-rw-r--r--libjava/java/lang/w_fmod.c107
-rw-r--r--libjava/java/lang/w_log.c115
-rw-r--r--libjava/java/lang/w_pow.c231
-rw-r--r--libjava/java/lang/w_remainder.c119
-rw-r--r--libjava/java/lang/w_sqrt.c93
137 files changed, 19610 insertions, 0 deletions
diff --git a/libjava/java/lang/AbstractMethodError.java b/libjava/java/lang/AbstractMethodError.java
new file mode 100644
index 00000000000..b1751e2e0f1
--- /dev/null
+++ b/libjava/java/lang/AbstractMethodError.java
@@ -0,0 +1,34 @@
+// AbstractMethodError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class AbstractMethodError extends IncompatibleClassChangeError
+{
+ public AbstractMethodError ()
+ {
+ super ();
+ }
+
+ public AbstractMethodError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/ArithmeticException.java b/libjava/java/lang/ArithmeticException.java
new file mode 100644
index 00000000000..def8c82be77
--- /dev/null
+++ b/libjava/java/lang/ArithmeticException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class ArithmeticException extends RuntimeException
+{
+ public ArithmeticException()
+ {
+ super();
+ }
+
+ public ArithmeticException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/ArrayIndexOutOfBoundsException.java b/libjava/java/lang/ArrayIndexOutOfBoundsException.java
new file mode 100644
index 00000000000..e66b6d7189b
--- /dev/null
+++ b/libjava/java/lang/ArrayIndexOutOfBoundsException.java
@@ -0,0 +1,37 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException
+{
+ public ArrayIndexOutOfBoundsException()
+ {
+ super();
+ }
+
+ public ArrayIndexOutOfBoundsException(int index)
+ {
+ this("Array index out of range: " + index);
+ }
+
+ public ArrayIndexOutOfBoundsException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/ArrayStoreException.java b/libjava/java/lang/ArrayStoreException.java
new file mode 100644
index 00000000000..7b9ede6ff25
--- /dev/null
+++ b/libjava/java/lang/ArrayStoreException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class ArrayStoreException extends RuntimeException
+{
+ public ArrayStoreException()
+ {
+ super();
+ }
+
+ public ArrayStoreException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/Boolean.java b/libjava/java/lang/Boolean.java
new file mode 100644
index 00000000000..78ab77ff81a
--- /dev/null
+++ b/libjava/java/lang/Boolean.java
@@ -0,0 +1,95 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+import java.io.Serializable;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 3, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public final class Boolean extends Object implements Serializable
+{
+ public static final Boolean FALSE = new Boolean(false);
+ public static final Boolean TRUE = new Boolean(true);
+
+ // This initialization is seemingly circular, but it is accepted
+ // by javac, and is handled specially by gcc.
+ public static final Class TYPE = boolean.class;
+
+ /* The boolean value of the instance. */
+ private boolean value;
+
+ public Boolean(boolean boolVal)
+ {
+ value = boolVal;
+ }
+
+ public Boolean(String strVal)
+ {
+ value = strVal.equalsIgnoreCase("true");
+ }
+
+ public boolean booleanValue()
+ {
+ return value;
+ }
+
+ public boolean equals(Object obj)
+ {
+ /* Don't need to compare obj to null as instanceof will do this. */
+ if (obj instanceof Boolean)
+ return value == ((Boolean) obj).value;
+ return false;
+ }
+
+ public static boolean getBoolean(String property)
+ {
+ /* TBD: If a security manager exists and it doesn't permit accessing
+ * the property, it will throw an exception. Should we catch it?
+ */
+ try
+ {
+ String val = System.getProperty(property);
+ return val == null ? false : val.equalsIgnoreCase("true");
+ }
+ catch (SecurityException e)
+ {
+ return false;
+ }
+ }
+
+ public int hashCode()
+ {
+ /* These values are from the Java Lang. Spec. (Sec 20.4.7).
+ * TBD: They could be made private static final fields but they're only
+ * used here (and shouldn't be used anywhere else), though it might be
+ * useful to grep on something like JAVA_HASH_* values for us as
+ * developers.
+ */
+ return value ? 1231 : 1237;
+ }
+
+ public String toString()
+ {
+ return value ? "true" : "false";
+ }
+
+ public static Boolean valueOf(String str)
+ {
+ /* This returns a Boolean (big B), not a boolean (little b). */
+ return str.equalsIgnoreCase("true") ? TRUE : FALSE;
+ }
+}
diff --git a/libjava/java/lang/Byte.java b/libjava/java/lang/Byte.java
new file mode 100644
index 00000000000..f3ec4020671
--- /dev/null
+++ b/libjava/java/lang/Byte.java
@@ -0,0 +1,144 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Per Bothner <bothner@cygnus.com>
+ * @date April 17, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, plus online
+ * API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ * Includes JDK 1.2 methods.
+ */
+
+public final class Byte extends Number implements Comparable
+{
+ byte value;
+
+ public final static byte MIN_VALUE = -128;
+ public final static byte MAX_VALUE = 127;
+
+ // This initialization is seemingly circular, but it is accepted
+ // by javac, and is handled specially by gcc.
+ public static final Class TYPE = byte.class;
+
+ public Byte(byte value)
+ {
+ this.value = value;
+ }
+
+ public Byte(String str)
+ throws NumberFormatException
+ {
+ this.value = parseByte(str, 10);
+ }
+
+ public byte byteValue()
+ {
+ return value;
+ }
+
+ public short shortValue()
+ {
+ return value;
+ }
+
+ public int intValue()
+ {
+ return value;
+ }
+
+ public long longValue ()
+ {
+ return value;
+ }
+
+ public float floatValue ()
+ {
+ return (float) value;
+ }
+
+ public double doubleValue ()
+ {
+ return (double) value;
+ }
+
+ public static Byte decode(String str)
+ throws NumberFormatException
+ {
+ int i = (Integer.decode(str)).intValue();
+ if (i < MIN_VALUE || i > MAX_VALUE)
+ throw new NumberFormatException();
+ return new Byte((byte) i);
+ }
+
+ public static byte parseByte(String str, int radix)
+ throws NumberFormatException
+ {
+ int i = Integer.parseInt(str, radix);
+ if (i < MIN_VALUE || i > MAX_VALUE)
+ throw new NumberFormatException();
+ return (byte) i;
+ }
+
+ public static byte parseByte(String str)
+ throws NumberFormatException
+ {
+ return parseByte(str, 10);
+ }
+
+ public static Byte valueOf(String str, int radix)
+ throws NumberFormatException
+ {
+ return new Byte(parseByte(str, radix));
+ }
+
+ public static Byte valueOf(String str)
+ throws NumberFormatException
+ {
+ return valueOf(str, 10);
+ }
+
+ // Added in JDK 1.2
+ public int compareTo(Byte anotherByte)
+ {
+ return this.value - anotherByte.value;
+ }
+
+ // Added in JDK 1.2
+ public int compareTo(Object o) throws ClassCastException
+ {
+ if (o instanceof Byte)
+ return this.value - ((Byte) o).value;
+ else
+ throw new ClassCastException();
+ }
+
+ public boolean equals(Object obj)
+ {
+ return obj != null && (obj instanceof Byte) && ((Byte)obj).value == value;
+ }
+
+ // Verified that hashCode is returns plain value (see Boolean_1 test).
+ public int hashCode()
+ {
+ return value;
+ }
+
+ public String toString()
+ {
+ return Integer.toString((int) value);
+ }
+
+ public static String toString(byte value)
+ {
+ return Integer.toString((int) value);
+ }
+}
diff --git a/libjava/java/lang/Character.java b/libjava/java/lang/Character.java
new file mode 100644
index 00000000000..c7dd052e0c0
--- /dev/null
+++ b/libjava/java/lang/Character.java
@@ -0,0 +1,286 @@
+// Character.java - Character class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+import java.io.Serializable;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date September 10, 1998
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1,
+ * online API docs for JDK 1.2 beta from http://www.javasoft.com,
+ * and The Unicode Standard Version 2.0.
+ * Status: Believed complete and correct for JDK 1.1; 1.2 methods
+ * unimplemented.
+ */
+
+public final class Character implements Serializable, Comparable
+{
+ public static final char MIN_VALUE = '\u0000';
+ public static final char MAX_VALUE = '\uffff';
+
+ public static final int MIN_RADIX = 2;
+ public static final int MAX_RADIX = 36;
+
+ // This initialization is seemingly circular, but it is accepted
+ // by javac, and is handled specially by gcc.
+ public static final Class TYPE = char.class;
+
+ // Space.
+ public static final byte SPACE_SEPARATOR = 12;
+ public static final byte LINE_SEPARATOR = 13;
+ public static final byte PARAGRAPH_SEPARATOR = 14;
+
+ // Letters.
+ public static final byte UPPERCASE_LETTER = 1;
+ public static final byte LOWERCASE_LETTER = 2;
+ public static final byte TITLECASE_LETTER = 3;
+ public static final byte MODIFIER_LETTER = 4;
+ public static final byte OTHER_LETTER = 5;
+
+ // Numbers.
+ public static final byte DECIMAL_DIGIT_NUMBER = 9;
+ public static final byte LETTER_NUMBER = 10;
+ public static final byte OTHER_NUMBER = 11;
+
+ // Marks.
+ public static final byte NON_SPACING_MARK = 6;
+ public static final byte ENCLOSING_MARK = 7;
+ public static final byte COMBINING_SPACING_MARK = 8;
+
+ // Punctuation.
+ public static final byte DASH_PUNCTUATION = 20;
+ public static final byte START_PUNCTUATION = 21;
+ public static final byte END_PUNCTUATION = 22;
+ public static final byte CONNECTOR_PUNCTUATION = 23;
+ public static final byte OTHER_PUNCTUATION = 24;
+
+ // Symbols.
+ public static final byte MATH_SYMBOL = 25;
+ public static final byte CURRENCY_SYMBOL = 26;
+ public static final byte MODIFIER_SYMBOL = 27;
+ public static final byte OTHER_SYMBOL = 28;
+
+ // Format controls.
+ public static final byte CONTROL = 15;
+ // Note: The JCL book says that both FORMAT and PRIVATE_USE are 18.
+ // However, FORMAT is actually 16.
+ public static final byte FORMAT = 16;
+
+ // Others.
+ public static final byte UNASSIGNED = 0;
+ public static final byte PRIVATE_USE = 18;
+ public static final byte SURROGATE = 19;
+
+
+ public Character (char ch)
+ {
+ value = ch;
+ }
+
+ public char charValue ()
+ {
+ return value;
+ }
+
+ // See if a character is a digit. If so, return the corresponding
+ // value. Otherwise return -1.
+ private static native int digit_value (char ch);
+
+ public static int digit (char ch, int radix)
+ {
+ if (radix < MIN_RADIX || radix > MAX_RADIX)
+ return -1;
+
+ int d = digit_value (ch);
+ if (d == -1)
+ {
+ if (ch >= 'A' && ch <= 'Z')
+ d = ch - 'A' + 10;
+ else if (ch >= 'a' && ch <= 'z')
+ d = ch - 'a' + 10;
+ else
+ return -1;
+ }
+ return d >= radix ? -1 : d;
+ }
+
+ public boolean equals (Object obj)
+ {
+ // Don't need to compare OBJ to null as instanceof will do this.
+ if (obj instanceof Character)
+ return value == ((Character) obj).value;
+ return false;
+ }
+
+ public static char forDigit (int d, int rdx)
+ {
+ if (d < 0 || d >= rdx || rdx < MIN_RADIX || rdx > MAX_RADIX)
+ return '\u0000';
+ if (d < 10)
+ return (char) ('0' + d);
+ // The Java Language Spec says to use lowercase, while the JCL
+ // says to use uppercase. We go with the former.
+ return (char) ('a' + d - 10);
+ }
+
+ public static native int getNumericValue (char ch);
+ public static native int getType (char ch);
+
+ public int hashCode ()
+ {
+ return value;
+ }
+
+ public static boolean isDefined (char ch)
+ {
+ return getType (ch) != UNASSIGNED;
+ }
+
+ public static boolean isDigit (char ch)
+ {
+ return digit_value (ch) != -1;
+ }
+
+ // The JCL book says that the argument here is a Character. That is
+ // wrong.
+ public static boolean isIdentifierIgnorable (char ch)
+ {
+ // This information comes from the Unicode Standard. It isn't
+ // auto-generated as it doesn't appear in the unidata table.
+ return ((ch >= '\u0000' && ch <= '\u0008')
+ || (ch >= '\u000e' && ch <= '\u001b')
+ // JDK 1.2 docs say that these are ignorable. The Unicode
+ // Standard is somewhat ambiguous on this issue.
+ || (ch >= '\u007f' && ch <= '\u009f')
+ || (ch >= '\u200c' && ch <= '\u200f')
+ // JCl says 200a through 200e, but that is a typo. The
+ // Unicode standard says the bidi controls are 202a
+ // through 202e.
+ || (ch >= '\u202a' && ch <= '\u202e')
+ || (ch >= '\u206a' && ch <= '\u206f')
+ || ch == '\ufeff');
+ }
+
+ public static boolean isISOControl (char c)
+ {
+ return ((c >= '\u0000' && c <= '\u001f')
+ || (c >= '\u007f' && c <= '\u009f'));
+ }
+
+ public static boolean isJavaIdentifierPart (char ch)
+ {
+ if (isIdentifierIgnorable (ch) || isDigit (ch))
+ return true;
+ int type = getType (ch);
+ return (type == COMBINING_SPACING_MARK || type == NON_SPACING_MARK
+ || type == CURRENCY_SYMBOL || type == CONNECTOR_PUNCTUATION
+ || type == UPPERCASE_LETTER || type == LOWERCASE_LETTER
+ || type == TITLECASE_LETTER || type == MODIFIER_LETTER
+ || type == OTHER_LETTER || type == LETTER_NUMBER);
+ }
+
+ public static boolean isJavaIdentifierStart (char ch)
+ {
+ int type = getType (ch);
+ return (type == CURRENCY_SYMBOL || type == CONNECTOR_PUNCTUATION
+ || type == UPPERCASE_LETTER || type == LOWERCASE_LETTER
+ || type == TITLECASE_LETTER || type == MODIFIER_LETTER
+ || type == OTHER_LETTER);
+ }
+
+ // Deprecated in 1.2.
+ public static boolean isJavaLetter (char ch)
+ {
+ return ch == '$' || ch == '_' || isLetter (ch);
+ }
+
+ // Deprecated in 1.2.
+ public static boolean isJavaLetterOrDigit (char ch)
+ {
+ return ch == '$' || ch == '_' || isLetterOrDigit (ch);
+ }
+
+ public static boolean isLetter (char ch)
+ {
+ int type = getType (ch);
+ return (type == UPPERCASE_LETTER || type == LOWERCASE_LETTER
+ || type == TITLECASE_LETTER || type == MODIFIER_LETTER
+ || type == OTHER_LETTER);
+ }
+
+ public static boolean isLetterOrDigit (char ch)
+ {
+ return isDigit (ch) || isLetter (ch);
+ }
+
+ public static native boolean isLowerCase (char ch);
+
+ // Deprecated in JCL.
+ public static boolean isSpace (char ch)
+ {
+ return ch == '\n' || ch == '\t' || ch == '\f' || ch == '\r' || ch == ' ';
+ }
+
+ public static native boolean isSpaceChar (char ch);
+ public static native boolean isTitleCase (char ch);
+
+ public static boolean isUnicodeIdentifierPart (char ch)
+ {
+ if (isIdentifierIgnorable (ch) || isDigit (ch))
+ return true;
+ int type = getType (ch);
+ return (type == CONNECTOR_PUNCTUATION || type == LETTER_NUMBER
+ || type == COMBINING_SPACING_MARK || type == NON_SPACING_MARK
+ || type == UPPERCASE_LETTER || type == LOWERCASE_LETTER
+ || type == TITLECASE_LETTER || type == MODIFIER_LETTER
+ || type == OTHER_LETTER);
+ }
+
+ public static boolean isUnicodeIdentifierStart (char ch)
+ {
+ return isLetter (ch);
+ }
+
+ public static native boolean isUpperCase (char ch);
+
+ public static boolean isWhitespace (char ch)
+ {
+ return ((ch >= '\u0009' && ch <= '\r')
+ || (ch >= '\u001c' && ch <= '\u001f')
+ || (ch != '\u00a0' && ch != '\ufeff' && isSpaceChar (ch)));
+ }
+
+ public static native char toLowerCase (char ch);
+ public static native char toTitleCase (char ch);
+ public static native char toUpperCase (char ch);
+
+ public String toString ()
+ {
+ return String.valueOf(value);
+ }
+
+ public int compareTo (Character anotherCharacter)
+ {
+ return value - anotherCharacter.value;
+ }
+
+ public int compareTo (Object o)
+ {
+ return compareTo ((Character) o);
+ }
+
+ // Private data.
+ private char value;
+}
diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h
new file mode 100644
index 00000000000..eb0a2f95533
--- /dev/null
+++ b/libjava/java/lang/Class.h
@@ -0,0 +1,214 @@
+// Class.h - Header file for java.lang.Class. -*- c++ -*-
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// Written primary using compiler source and Class.java as guides.
+#ifndef __JAVA_LANG_CLASS_H__
+#define __JAVA_LANG_CLASS_H__
+
+#pragma interface
+
+#include <java/lang/Object.h>
+#include <java/lang/String.h>
+
+// We declare these here to avoid including cni.h.
+extern "C" void _Jv_InitClass (jclass klass);
+extern "C" void _Jv_RegisterClasses (jclass *classes);
+
+struct _Jv_Field;
+struct _Jv_VTable;
+
+#define CONSTANT_Class 7
+#define CONSTANT_Fieldref 9
+#define CONSTANT_Methodref 10
+#define CONSTANT_InterfaceMethodref 11
+#define CONSTANT_String 8
+#define CONSTANT_Integer 3
+#define CONSTANT_Float 4
+#define CONSTANT_Long 5
+#define CONSTANT_Double 6
+#define CONSTANT_NameAndType 12
+#define CONSTANT_Utf8 1
+#define CONSTANT_Unicode 2
+#define CONSTANT_ResolvedFlag 16
+#define CONSTANT_ResolvedString (CONSTANT_String+CONSTANT_ResolvedFlag)
+#define CONSTANT_ResolvedClass (CONSTANT_Class+CONSTANT_ResolvedFlag)
+
+struct _Jv_Constants
+{
+ jint size;
+ jbyte *tags;
+ void **data;
+};
+
+struct _Jv_Method
+{
+ _Jv_Utf8Const *name;
+ _Jv_Utf8Const *signature;
+ unsigned short accflags;
+ void *ncode;
+};
+
+#define JV_PRIMITIVE_VTABLE ((_Jv_VTable *) -1)
+
+class java::lang::Class : public java::lang::Object
+{
+public:
+ static jclass forName (jstring className);
+ JArray<jclass> *getClasses (void);
+
+ java::lang::ClassLoader *getClassLoader (void)
+ {
+ return loader;
+ }
+
+ jclass getComponentType (void)
+ {
+ return isArray () ? (* (jclass *) &methods) : 0;
+ }
+
+ java::lang::reflect::Constructor *getConstructor (JArray<jclass> *);
+ JArray<java::lang::reflect::Constructor *> *getConstructors (void);
+ java::lang::reflect::Constructor *getDeclaredConstructor (JArray<jclass> *);
+ JArray<java::lang::reflect::Constructor *> *getDeclaredConstructors (void);
+ java::lang::reflect::Field *getDeclaredField (jstring);
+ JArray<java::lang::reflect::Field *> *getDeclaredFields (void);
+ java::lang::reflect::Method *getDeclaredMethod (jstring, JArray<jclass> *);
+ JArray<java::lang::reflect::Method *> *getDeclaredMethods (void);
+
+ JArray<jclass> *getDeclaredClasses (void);
+ jclass getDeclaringClass (void);
+
+ java::lang::reflect::Field *getField (jstring);
+private:
+ java::lang::reflect::Field *getField (jstring, jint);
+public:
+ JArray<java::lang::reflect::Field *> *getFields (void);
+
+ JArray<jclass> *getInterfaces (void);
+
+ java::lang::reflect::Method *getMethod (jstring, JArray<jclass> *);
+ JArray<java::lang::reflect::Method *> *getMethods (void);
+
+ jint getModifiers (void)
+ {
+ return accflags;
+ }
+
+ jstring getName (void);
+
+ java::io::InputStream *getResourceAsStream (jstring resourceName);
+ JArray<jobject> *getSigners (void);
+
+ jclass getSuperclass (void)
+ {
+ return superclass;
+ }
+
+ jboolean isArray (void)
+ {
+ return name->data[0] == '[';
+ }
+
+ jboolean isAssignableFrom (jclass cls);
+ jboolean isInstance (jobject obj);
+ jboolean isInterface (void);
+
+ jboolean isPrimitive (void)
+ {
+ return vtable == JV_PRIMITIVE_VTABLE;
+ }
+
+ jobject newInstance (void);
+ jstring toString (void);
+
+ // FIXME: this probably shouldn't be public.
+ jint size (void)
+ {
+ return size_in_bytes;
+ }
+
+private:
+ void checkMemberAccess (jint flags);
+ void resolveConstants (void);
+
+ // Various functions to handle class initialization.
+ java::lang::Throwable *hackTrampoline (jint, java::lang::Throwable *);
+ void hackRunInitializers (void);
+ void initializeClass (void);
+
+ // Friend functions implemented in natClass.cc.
+ friend _Jv_Method *_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature);
+ friend void _Jv_InitClass (jclass klass);
+ friend void _Jv_RegisterClasses (jclass *classes);
+ friend jclass _Jv_FindClassInCache (_Jv_Utf8Const *name,
+ java::lang::ClassLoader *loader);
+ friend jclass _Jv_FindArrayClass (jclass element);
+ friend jclass _Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
+ java::lang::ClassLoader *loader);
+
+ friend jfieldID JvGetFirstInstanceField (jclass);
+ friend jint JvNumInstanceFields (jclass);
+ friend jobject _Jv_AllocObject (jclass, jint);
+ friend jobjectArray _Jv_NewObjectArray (jsize, jclass, jobject);
+ friend jobject _Jv_NewPrimArray (jclass, jint);
+ friend jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv *, jclass, jfieldID);
+ friend jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);
+ friend jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);
+
+ friend class _Jv_PrimClass;
+
+#ifdef JV_MARKOBJ_DECL
+ friend JV_MARKOBJ_DECL;
+#endif
+
+ // Chain for class pool.
+ jclass next;
+ // Name of class.
+ _Jv_Utf8Const *name;
+ // Access flags for class.
+ unsigned short accflags;
+ // The superclass, or null for Object.
+ jclass superclass;
+ // Class constants.
+ _Jv_Constants constants;
+ // Methods. If this is an array class, then this field holds a
+ // pointer to the element type. If this is a primitive class, this
+ // is used to cache a pointer to the appropriate array type.
+ _Jv_Method *methods;
+ // Number of methods. If this class is primitive, this holds the
+ // character used to represent this type in a signature.
+ short method_count;
+ // Number of methods in the vtable.
+ short vtable_method_count;
+ // The fields.
+ _Jv_Field *fields;
+ // Size of instance fields, in bytes.
+ int size_in_bytes;
+ // Total number of fields (instance and static).
+ short field_count;
+ // Number of static fields.
+ short static_field_count;
+ // The vtbl for all objects of this class.
+ _Jv_VTable *vtable;
+ // Interfaces implemented by this class.
+ jclass *interfaces;
+ // The class loader for this class.
+ java::lang::ClassLoader *loader;
+ // Number of interfaces.
+ short interface_count;
+ // State of this class.
+ jbyte state;
+ // The thread which has locked this class. Used during class
+ // initialization.
+ java::lang::Thread *thread;
+};
+
+#endif /* __JAVA_LANG_CLASS_H__ */
diff --git a/libjava/java/lang/Class.java b/libjava/java/lang/Class.java
new file mode 100644
index 00000000000..4ffcceaf675
--- /dev/null
+++ b/libjava/java/lang/Class.java
@@ -0,0 +1,155 @@
+// Class.java - Representation of a Java class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+import java.io.Serializable;
+import java.io.InputStream;
+import java.lang.reflect.*;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * plus gcj compiler sources (to determine object layout)
+ * Status: Sufficient for our purposes, but some methods missing
+ * and some not implemented.
+ */
+
+public final class Class implements Serializable
+{
+ public static native Class forName (String className)
+ throws ClassNotFoundException;
+ public native Class[] getClasses ();
+ public native ClassLoader getClassLoader ();
+ public native Class getComponentType ();
+
+ public native Constructor getConstructor (Class[] parameterTypes)
+ throws NoSuchMethodException, SecurityException;
+ public native Constructor[] getConstructors () throws SecurityException;
+
+ public native Class[] getDeclaredClasses () throws SecurityException;
+
+ public native Constructor getDeclaredConstructor (Class[] parameterTypes)
+ throws NoSuchMethodException, SecurityException;
+ public native Constructor[] getDeclaredConstructors ()
+ throws SecurityException;
+ public native Field getDeclaredField (String fieldName)
+ throws NoSuchFieldException, SecurityException;
+ public native Field[] getDeclaredFields () throws SecurityException;
+ public native Method getDeclaredMethod (String methodName,
+ Class[] parameterTypes)
+ throws NoSuchMethodException, SecurityException;
+ public native Method[] getDeclaredMethods () throws SecurityException;
+
+ // This is marked as unimplemented in the JCL book.
+ public native Class getDeclaringClass ();
+
+ private native Field getField (String fieldName, int hash)
+ throws NoSuchFieldException, SecurityException;
+
+ public Field getField (String fieldName)
+ throws NoSuchFieldException, SecurityException
+ {
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkMemberAccess (this, java.lang.reflect.Member.DECLARED);
+ Field fld = getField(fieldName, fieldName.hashCode());
+ if (fld == null)
+ throw new NoSuchFieldException(fieldName);
+ return fld;
+ }
+ public native Field[] getFields () throws SecurityException;
+
+ public native Class[] getInterfaces ();
+
+ public native Method getMethod (String methodName, Class[] parameterTypes)
+ throws NoSuchMethodException, SecurityException;
+ public native Method[] getMethods () throws SecurityException;
+
+ public native int getModifiers ();
+ public native String getName ();
+
+ // FIXME: can't implement this until we have java.net.
+ // public URL getResource (String resourceName);
+
+ // FIXME: implement.
+ public InputStream getResourceAsStream (String resourceName)
+ {
+ return null;
+ }
+
+ // FIXME: implement. Requires java.security.
+ public Object[] getSigners ()
+ {
+ return null;
+ }
+
+ public native Class getSuperclass ();
+ public native boolean isArray ();
+ public native boolean isAssignableFrom (Class cls);
+ public native boolean isInstance (Object obj);
+ public native boolean isInterface ();
+ public native boolean isPrimitive ();
+ public native Object newInstance ()
+ throws InstantiationException, IllegalAccessException;
+
+ public String toString ()
+ {
+ if (isPrimitive ())
+ return getName ();
+ return (isInterface () ? "interface " : "class ") + getName ();
+ }
+
+ // Don't allow new classes to be made.
+ private Class ()
+ {
+ }
+
+ // Do a security check.
+ private void checkMemberAccess (int flags)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkMemberAccess(this, flags);
+ }
+
+ // FIXME: this method exists only because we cannot catch Java
+ // exceptions from C++ code. This is a helper for initializeClass.
+ private Throwable hackTrampoline (int what, Throwable old_exception)
+ {
+ Throwable new_val = null;
+ try
+ {
+ if (what == 0)
+ initializeClass ();
+ else if (what == 1)
+ hackRunInitializers ();
+ else if (what == 2)
+ new_val = new ExceptionInInitializerError (old_exception);
+ }
+ catch (Throwable t)
+ {
+ new_val = t;
+ }
+ return new_val;
+ }
+
+ // FIXME: this is a hack to let us run the class initializers. We
+ // could do it inline in initializeClass() if we could catch Java
+ // exceptions from C++.
+ private native void hackRunInitializers ();
+
+ // Initialize the class.
+ private native void initializeClass ();
+}
diff --git a/libjava/java/lang/ClassCastException.java b/libjava/java/lang/ClassCastException.java
new file mode 100644
index 00000000000..bd5a2a49b8e
--- /dev/null
+++ b/libjava/java/lang/ClassCastException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class ClassCastException extends RuntimeException
+{
+ public ClassCastException()
+ {
+ super();
+ }
+
+ public ClassCastException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/ClassCircularityError.java b/libjava/java/lang/ClassCircularityError.java
new file mode 100644
index 00000000000..a5e03831805
--- /dev/null
+++ b/libjava/java/lang/ClassCircularityError.java
@@ -0,0 +1,34 @@
+// ClassCircularityError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class ClassCircularityError extends LinkageError
+{
+ public ClassCircularityError ()
+ {
+ super ();
+ }
+
+ public ClassCircularityError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/ClassFormatError.java b/libjava/java/lang/ClassFormatError.java
new file mode 100644
index 00000000000..99b8425c9be
--- /dev/null
+++ b/libjava/java/lang/ClassFormatError.java
@@ -0,0 +1,34 @@
+// ClassFormatError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class ClassFormatError extends LinkageError
+{
+ public ClassFormatError ()
+ {
+ super ();
+ }
+
+ public ClassFormatError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/ClassLoader.java b/libjava/java/lang/ClassLoader.java
new file mode 100644
index 00000000000..048cea7d883
--- /dev/null
+++ b/libjava/java/lang/ClassLoader.java
@@ -0,0 +1,94 @@
+// ClassLoader.java - Define policies for loading Java classes.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+import java.io.InputStream;
+import java.util.Hashtable;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 28, 1998
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * Status: Just a stub; not useful at all.
+ */
+
+public abstract class ClassLoader
+{
+ protected ClassLoader ()
+ {
+ cache = new Hashtable ();
+ }
+
+ protected final Class defineClass (String className, byte[] bytecode,
+ int offset, int length)
+ {
+ throw new ClassFormatError ("defineClass unimplemented");
+ }
+
+ protected final Class defineClass (byte[] bytecodes,
+ int offset, int length)
+ {
+ return defineClass (null, bytecodes, offset, length);
+ }
+
+ protected final Class findLoadedClass (String className)
+ {
+ return (Class) cache.get(className);
+ }
+
+ protected final Class findSystemClass (String className)
+ throws ClassNotFoundException
+ {
+ Class c = system.findLoadedClass(className);
+ system.resolveClass(c);
+ return c;
+ }
+
+ // FIXME: Needs URL.
+ // public URL getResource (String resName);
+
+ public InputStream getResourceAsStream (String resName)
+ {
+ return null;
+ }
+
+ // FIXME: Needs URL.
+ // public static final URL getSystemResource (String resName);
+
+ public static final InputStream getSystemResourceAsStream (String resName)
+ {
+ return null;
+ }
+
+ protected abstract Class loadClass (String className, boolean resolve)
+ throws ClassNotFoundException;
+ public Class loadClass (String name) throws ClassNotFoundException
+ {
+ return loadClass (name, true);
+ }
+
+ protected final void resolveClass (Class c)
+ {
+ // Nothing for now.
+ }
+
+ protected final void setSigners (Class cl, Object[] signers)
+ {
+ // Nothing for now.
+ }
+
+ // Class cache.
+ private Hashtable cache;
+
+ // The system class loader. FIXME: should have an actual value
+ private static final ClassLoader system = null;
+}
diff --git a/libjava/java/lang/ClassNotFoundException.java b/libjava/java/lang/ClassNotFoundException.java
new file mode 100644
index 00000000000..e0ea15e22a2
--- /dev/null
+++ b/libjava/java/lang/ClassNotFoundException.java
@@ -0,0 +1,57 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class ClassNotFoundException extends Exception
+{
+ public ClassNotFoundException()
+ {
+ super();
+ }
+
+ // TODO12:
+ // public ClassNotFoundException(String msg, Throwable ex)
+ // {
+ // }
+
+ public ClassNotFoundException(String msg)
+ {
+ super(msg);
+ }
+
+ // TODO12:
+ // public Throwable getException()
+ // {
+ // }
+
+ // TBD: if this needs to be implemented
+ // public void printStackTrace()
+ // {
+ // }
+
+ // TBD: if this needs to be implemented
+ // public void printStackTrace(PrintStream ps)
+ // {
+ // }
+
+ // TBD: if this needs to be implemented
+ // public void printStackTrace(PrintWriter pw)
+ // {
+ // }
+}
diff --git a/libjava/java/lang/CloneNotSupportedException.java b/libjava/java/lang/CloneNotSupportedException.java
new file mode 100644
index 00000000000..155e80481a9
--- /dev/null
+++ b/libjava/java/lang/CloneNotSupportedException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class CloneNotSupportedException extends Exception
+{
+ public CloneNotSupportedException()
+ {
+ super();
+ }
+
+ public CloneNotSupportedException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/Cloneable.java b/libjava/java/lang/Cloneable.java
new file mode 100644
index 00000000000..730e5c91b5f
--- /dev/null
+++ b/libjava/java/lang/Cloneable.java
@@ -0,0 +1,23 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 2, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public interface Cloneable
+{
+}
diff --git a/libjava/java/lang/Comparable.java b/libjava/java/lang/Comparable.java
new file mode 100644
index 00000000000..e40e6e81ae8
--- /dev/null
+++ b/libjava/java/lang/Comparable.java
@@ -0,0 +1,22 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 8, 1998.
+ */
+/* Written using online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public interface Comparable
+{
+ public int compareTo(Object o) throws ClassCastException;
+}
diff --git a/libjava/java/lang/Compiler.java b/libjava/java/lang/Compiler.java
new file mode 100644
index 00000000000..7feb9f86429
--- /dev/null
+++ b/libjava/java/lang/Compiler.java
@@ -0,0 +1,53 @@
+// Compiler.java - Control byte->machine code compiler.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 23, 1998.
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ */
+
+public final class Compiler
+{
+ public static Object command (Object arg)
+ {
+ // Our implementation defines this to a no-op.
+ return null;
+ }
+
+ public static boolean compileClass (Class oneClass)
+ {
+ // Never succeed.
+ return false;
+ }
+
+ public static boolean compileClasses (String classNames)
+ {
+ // Note the incredibly lame interface. Always fail.
+ return false;
+ }
+
+ public static void disable ()
+ {
+ }
+
+ public static void enable ()
+ {
+ }
+
+ // Don't allow new `Compiler's to be made.
+ private Compiler ()
+ {
+ }
+}
diff --git a/libjava/java/lang/Double.java b/libjava/java/lang/Double.java
new file mode 100644
index 00000000000..850aa5ad979
--- /dev/null
+++ b/libjava/java/lang/Double.java
@@ -0,0 +1,149 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Andrew Haley <aph@cygnus.com>
+ * @date September 25, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public final class Double extends Number
+{
+ public static final double MIN_VALUE = 5e-324;
+ public static final double MAX_VALUE = 1.7976931348623157e+308;
+ public static final double NEGATIVE_INFINITY = -1.0d/0.0d;
+ public static final double POSITIVE_INFINITY = 1.0d/0.0d;
+ public static final double NaN = 0.0d/0.0d;
+
+ // This initialization is seemingly circular, but it is accepted
+ // by javac, and is handled specially by gcc.
+ public static final Class TYPE = double.class;
+
+ private double value;
+
+ private native static double doubleValueOf (String s)
+ throws NumberFormatException;
+
+ public Double (double v)
+ {
+ value = v;
+ }
+
+ public Double (String s) throws NumberFormatException
+ {
+ value = valueOf (s).doubleValue ();
+ }
+
+ public String toString ()
+ {
+ return toString (value);
+ }
+
+ public boolean equals (Object obj)
+ {
+ if (obj == null)
+ return false;
+
+ if (!(obj instanceof Double))
+ return false;
+
+ Double d = (Double) obj;
+
+ return doubleToLongBits (value) == doubleToLongBits (d.doubleValue ());
+ }
+
+ public int hashCode ()
+ {
+ long v = doubleToLongBits (value);
+ return (int) (v ^ (v >>> 32));
+ }
+
+ public int intValue ()
+ {
+ return (int) value;
+ }
+
+ public long longValue ()
+ {
+ return (long) value;
+ }
+
+ public float floatValue ()
+ {
+ return (float) value;
+ }
+
+ public double doubleValue ()
+ {
+ return value;
+ }
+
+ public byte byteValue ()
+ {
+ return (byte) value;
+ }
+
+ public short shortValue ()
+ {
+ return (short) value;
+ }
+
+ native static String toString (double v, boolean isFloat);
+
+ public static String toString (double v)
+ {
+ return toString (v, false);
+ }
+
+ public static Double valueOf (String s) throws NullPointerException,
+ NumberFormatException
+ {
+ if (s == null)
+ throw new NullPointerException ();
+
+ return new Double (doubleValueOf (s));
+ }
+
+ public boolean isNaN ()
+ {
+ return isNaN (value);
+ }
+
+ public static boolean isNaN (double v)
+ {
+ long bits = doubleToLongBits (v);
+ long e = bits & 0x7ff0000000000000L;
+ long f = bits & 0x000fffffffffffffL;
+
+ return e == 0x7ff0000000000000L && f != 0L;
+ }
+
+ public boolean isInfinite ()
+ {
+ return isInfinite (value);
+ }
+
+ public static boolean isInfinite (double v)
+ {
+ long bits = doubleToLongBits (v);
+ long f = bits & 0x7fffffffffffffffL;
+
+ return f == 0x7ff0000000000000L;
+ }
+
+ public static native long doubleToLongBits (double value);
+
+ public static native double longBitsToDouble (long bits);
+}
+
diff --git a/libjava/java/lang/Error.java b/libjava/java/lang/Error.java
new file mode 100644
index 00000000000..ef69f0ea413
--- /dev/null
+++ b/libjava/java/lang/Error.java
@@ -0,0 +1,34 @@
+// Error.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class Error extends Throwable
+{
+ public Error ()
+ {
+ super ();
+ }
+
+ public Error (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/Exception.java b/libjava/java/lang/Exception.java
new file mode 100644
index 00000000000..8eb5e44dc36
--- /dev/null
+++ b/libjava/java/lang/Exception.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class Exception extends Throwable
+{
+ public Exception()
+ {
+ super();
+ }
+
+ public Exception(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/ExceptionInInitializerError.java b/libjava/java/lang/ExceptionInInitializerError.java
new file mode 100644
index 00000000000..deb1213e3b2
--- /dev/null
+++ b/libjava/java/lang/ExceptionInInitializerError.java
@@ -0,0 +1,50 @@
+// ExceptionInInitializerError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class ExceptionInInitializerError extends LinkageError
+{
+ public ExceptionInInitializerError ()
+ {
+ super ();
+ exception = null;
+ }
+
+ public ExceptionInInitializerError (String msg)
+ {
+ super (msg);
+ exception = null;
+ }
+
+ public ExceptionInInitializerError (Throwable e)
+ {
+ super ();
+ exception = e;
+ }
+
+ public Throwable getException ()
+ {
+ return exception;
+ }
+
+ // The exception that caused this error.
+ private Throwable exception;
+}
diff --git a/libjava/java/lang/FirstThread.java b/libjava/java/lang/FirstThread.java
new file mode 100644
index 00000000000..ec0f1db33d5
--- /dev/null
+++ b/libjava/java/lang/FirstThread.java
@@ -0,0 +1,40 @@
+// FirstThread.java - Implementation of very first thread.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date August 24, 1998
+ */
+
+// This is entirely internal to our implementation.
+
+final class FirstThread extends Thread
+{
+ public native void run ();
+
+ public FirstThread (ThreadGroup g, Class k, Object o)
+ {
+ super (g, null, "main");
+ klass = k;
+ args = o;
+ }
+
+ private static void die (String s)
+ {
+ System.err.println(s);
+ System.exit(1);
+ }
+
+ // Private data.
+ private Class klass;
+ private Object args;
+}
diff --git a/libjava/java/lang/Float.java b/libjava/java/lang/Float.java
new file mode 100644
index 00000000000..99cc66bc8e7
--- /dev/null
+++ b/libjava/java/lang/Float.java
@@ -0,0 +1,149 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Andrew Haley <aph@cygnus.com>
+ * @date September 25, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public final class Float extends Number
+{
+ public static final float MAX_VALUE = 3.4028235e+38f;
+ public static final float MIN_VALUE = 1.4e-45f;
+ public static final float NEGATIVE_INFINITY = -1.0f/0.0f;
+ public static final float POSITIVE_INFINITY = 1.0f/0.0f;
+ public static final float NaN = 0.0f/0.0f;
+
+ // This initialization is seemingly circular, but it is accepted
+ // by javac, and is handled specially by gcc.
+ public static final Class TYPE = float.class;
+
+ private float value;
+
+ public Float (float value)
+ {
+ this.value = value;
+ }
+
+ public Float (double value)
+ {
+ this.value = (float)value;
+ }
+
+ public Float (String s) throws NumberFormatException
+ {
+ this.value = valueOf (s).floatValue ();
+ }
+
+ public String toString ()
+ {
+ return toString (value);
+ }
+
+ public boolean equals (Object obj)
+ {
+ if (obj == null)
+ return false;
+
+ if (!(obj instanceof Float))
+ return false;
+
+ Float f = (Float) obj;
+
+ return floatToIntBits (value) == floatToIntBits (f.floatValue ());
+ }
+
+ public int hashCode ()
+ {
+ return floatToIntBits (value);
+ }
+
+ public int intValue ()
+ {
+ return (int) value;
+ }
+
+ public long longValue ()
+ {
+ return (long) value;
+ }
+
+ public float floatValue ()
+ {
+ return (float) value;
+ }
+
+ public double doubleValue ()
+ {
+ return (double) value;
+ }
+
+ public byte byteValue ()
+ {
+ return (byte) value;
+ }
+
+ public short shortValue ()
+ {
+ return (short) value;
+ }
+
+ public static String toString (float v)
+ {
+ return Double.toString ((double) v, true);
+ }
+
+ public static Float valueOf (String s) throws NullPointerException,
+ NumberFormatException
+ {
+ if (s == null)
+ throw new NullPointerException ();
+
+ return new Float (Double.valueOf (s).floatValue ());
+ }
+
+ public boolean isNaN ()
+ {
+ return isNaN (value);
+ }
+
+ public static boolean isNaN (float v)
+ {
+ int bits = floatToIntBits (v);
+ int e = bits & 0x7f800000;
+ int f = bits & 0x007fffff;
+
+ return e == 0x7f800000 && f != 0;
+ }
+
+ public boolean isInfinite ()
+ {
+ return isInfinite (value);
+ }
+
+ public static boolean isInfinite (float v)
+ {
+ int bits = floatToIntBits (v);
+ int f = bits & 0x7fffffff;
+
+ return f == 0x7f800000;
+ }
+
+ public static native int floatToIntBits (float value);
+
+ public static native float intBitsToFloat (int bits);
+
+}
+
diff --git a/libjava/java/lang/IllegalAccessError.java b/libjava/java/lang/IllegalAccessError.java
new file mode 100644
index 00000000000..2d863416eb5
--- /dev/null
+++ b/libjava/java/lang/IllegalAccessError.java
@@ -0,0 +1,34 @@
+// IllegalAccessError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class IllegalAccessError extends IncompatibleClassChangeError
+{
+ public IllegalAccessError ()
+ {
+ super ();
+ }
+
+ public IllegalAccessError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/IllegalAccessException.java b/libjava/java/lang/IllegalAccessException.java
new file mode 100644
index 00000000000..c07a518779a
--- /dev/null
+++ b/libjava/java/lang/IllegalAccessException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class IllegalAccessException extends Exception
+{
+ public IllegalAccessException()
+ {
+ super();
+ }
+
+ public IllegalAccessException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/IllegalArgumentException.java b/libjava/java/lang/IllegalArgumentException.java
new file mode 100644
index 00000000000..6e8f0ed0300
--- /dev/null
+++ b/libjava/java/lang/IllegalArgumentException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class IllegalArgumentException extends RuntimeException
+{
+ public IllegalArgumentException()
+ {
+ super();
+ }
+
+ public IllegalArgumentException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/IllegalMonitorStateException.java b/libjava/java/lang/IllegalMonitorStateException.java
new file mode 100644
index 00000000000..f431749ca5f
--- /dev/null
+++ b/libjava/java/lang/IllegalMonitorStateException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class IllegalMonitorStateException extends RuntimeException
+{
+ public IllegalMonitorStateException()
+ {
+ super();
+ }
+
+ public IllegalMonitorStateException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/IllegalStateException.java b/libjava/java/lang/IllegalStateException.java
new file mode 100644
index 00000000000..2ea0d02b62b
--- /dev/null
+++ b/libjava/java/lang/IllegalStateException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class IllegalStateException extends RuntimeException
+{
+ public IllegalStateException()
+ {
+ super();
+ }
+
+ public IllegalStateException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/IllegalThreadStateException.java b/libjava/java/lang/IllegalThreadStateException.java
new file mode 100644
index 00000000000..72afa771ede
--- /dev/null
+++ b/libjava/java/lang/IllegalThreadStateException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class IllegalThreadStateException extends IllegalArgumentException
+{
+ public IllegalThreadStateException()
+ {
+ super();
+ }
+
+ public IllegalThreadStateException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/IncompatibleClassChangeError.java b/libjava/java/lang/IncompatibleClassChangeError.java
new file mode 100644
index 00000000000..31a22c46175
--- /dev/null
+++ b/libjava/java/lang/IncompatibleClassChangeError.java
@@ -0,0 +1,34 @@
+// IncompatibleClassChangeError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class IncompatibleClassChangeError extends LinkageError
+{
+ public IncompatibleClassChangeError ()
+ {
+ super ();
+ }
+
+ public IncompatibleClassChangeError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/IndexOutOfBoundsException.java b/libjava/java/lang/IndexOutOfBoundsException.java
new file mode 100644
index 00000000000..c8b5878b3d8
--- /dev/null
+++ b/libjava/java/lang/IndexOutOfBoundsException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class IndexOutOfBoundsException extends RuntimeException
+{
+ public IndexOutOfBoundsException()
+ {
+ super();
+ }
+
+ public IndexOutOfBoundsException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/InstantiationError.java b/libjava/java/lang/InstantiationError.java
new file mode 100644
index 00000000000..7982615e8f6
--- /dev/null
+++ b/libjava/java/lang/InstantiationError.java
@@ -0,0 +1,34 @@
+// InstantiationError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class InstantiationError extends IncompatibleClassChangeError
+{
+ public InstantiationError ()
+ {
+ super ();
+ }
+
+ public InstantiationError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/InstantiationException.java b/libjava/java/lang/InstantiationException.java
new file mode 100644
index 00000000000..d5ca893fe02
--- /dev/null
+++ b/libjava/java/lang/InstantiationException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class InstantiationException extends Exception
+{
+ public InstantiationException()
+ {
+ super();
+ }
+
+ public InstantiationException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/Integer.java b/libjava/java/lang/Integer.java
new file mode 100644
index 00000000000..54acc27ed6b
--- /dev/null
+++ b/libjava/java/lang/Integer.java
@@ -0,0 +1,355 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 11, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public final class Integer extends Number implements Comparable
+{
+ public static final int MAX_VALUE = 0x7FFFFFFF;
+ public static final int MIN_VALUE = 0x80000000;
+
+ // This initialization is seemingly circular, but it is accepted
+ // by javac, and is handled specially by gcc.
+ public static final Class TYPE = int.class;
+
+ /* The int value of the instance. */
+ private int value;
+
+ public Integer(int val)
+ {
+ value = val;
+ }
+
+ public Integer(String str) throws NumberFormatException
+ {
+ value = parseInt(str, 10);
+ }
+
+ public byte byteValue()
+ {
+ return (byte) value;
+ }
+
+ public double doubleValue()
+ {
+ return (double) value;
+ }
+
+ public float floatValue()
+ {
+ return (float) value;
+ }
+
+ public int intValue()
+ {
+ return value;
+ }
+
+ public long longValue()
+ {
+ return value;
+ }
+
+ public short shortValue()
+ {
+ return (short) value;
+ }
+
+ // Added in JDK 1.2
+ public int compareTo(Integer anotherInteger)
+ {
+ if (this.value == anotherInteger.value)
+ return 0;
+
+ // Returns just -1 or 1 on inequality; doing math might overflow the int.
+ if (this.value > anotherInteger.value)
+ return 1;
+
+ return -1;
+ }
+
+ // Added in JDK 1.2
+ public int compareTo(Object o) throws ClassCastException
+ {
+ if (!(o instanceof Integer))
+ throw new ClassCastException();
+
+ return this.compareTo((Integer) o);
+ }
+
+ public static Integer decode(String str) throws NumberFormatException
+ {
+ boolean isNeg = false;
+ int index = 0;
+ int radix = 10;
+ final int len;
+
+ if (str == null || (len = str.length()) == 0)
+ throw new NumberFormatException();
+
+ // Negative numbers are always radix 10.
+ if (str.charAt(0) == '-')
+ {
+ radix = 10;
+ index++;
+ isNeg = true;
+ }
+ else if (str.charAt(index) == '#')
+ {
+ radix = 16;
+ index++;
+ }
+ else if (str.charAt(index) == '0')
+ {
+ // Check if str is just "0"
+ if (len == 1)
+ return new Integer(0);
+
+ index++;
+ if (str.charAt(index) == 'x')
+ {
+ radix = 16;
+ index++;
+ }
+ else
+ radix = 8;
+ }
+
+ if (index >= len)
+ throw new NumberFormatException();
+
+ return new Integer(parseInt(str, index, len, isNeg, radix));
+ }
+
+ public boolean equals(Object obj)
+ {
+ return (obj != null && (obj instanceof Integer)
+ && ((Integer) obj).value == value);
+ }
+
+ public static Integer getInteger(String prop)
+ {
+ return getInteger(prop, null);
+ }
+
+ public static Integer getInteger(String prop, int defval)
+ {
+ Integer val = getInteger(prop, null);
+ return val == null ? new Integer(defval) : val;
+ }
+
+ public static Integer getInteger(String prop, Integer defobj)
+ {
+ try
+ {
+ return decode(System.getProperty(prop));
+ }
+ catch (NumberFormatException ex)
+ {
+ return defobj;
+ }
+ }
+
+ public int hashCode()
+ {
+ return value;
+ }
+
+ public static int parseInt(String str) throws NumberFormatException
+ {
+ return parseInt(str, 10);
+ }
+
+ public static int parseInt(String str, int radix) throws NumberFormatException
+ {
+ final int len;
+
+ if (str == null || (len = str.length()) == 0 ||
+ radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
+ throw new NumberFormatException();
+
+ boolean isNeg = false;
+ int index = 0;
+ if (str.charAt(index) == '-')
+ if (len > 1)
+ {
+ isNeg = true;
+ index++;
+ }
+ else
+ throw new NumberFormatException();
+
+ return parseInt(str, index, len, isNeg, radix);
+ }
+
+ private static int parseInt(String str, int index, int len, boolean isNeg,
+ int radix) throws NumberFormatException
+ {
+ int val = 0;
+ int digval;
+
+ for ( ; index < len; index++)
+ {
+ // The the previous loop iteration left us with a negative
+ // value (which can only be the most negative value, but we
+ // don't check that), then having more digits is wrong.
+ if (val == MIN_VALUE)
+ throw new NumberFormatException();
+
+ if ((digval = Character.digit(str.charAt(index), radix)) < 0)
+ throw new NumberFormatException();
+
+ // Throw an exception for overflow if result is negative.
+ // However, we special-case the most negative value.
+ val *= radix;
+ if (val < 0 || val + digval < 0)
+ {
+ if (isNeg && val + digval == MIN_VALUE)
+ {
+ // Ok.
+ }
+ else
+ throw new NumberFormatException();
+ }
+ val += digval;
+ }
+
+ return isNeg ? -(val) : val;
+ }
+
+ public static String toBinaryString(int num)
+ {
+ return toUnsignedString(num, 1);
+ }
+
+ public static String toHexString(int num)
+ {
+ return toUnsignedString(num, 4);
+ }
+
+ public static String toOctalString(int num)
+ {
+ return toUnsignedString(num, 3);
+ }
+
+ private static String toUnsignedString(int num, int exp)
+ {
+ // Use an array large enough for a binary number.
+ int radix = 1 << exp;
+ int mask = radix - 1;
+ char[] buffer = new char[32];
+ int i = 32;
+ do
+ {
+ buffer[--i] = Character.forDigit(num & mask, radix);
+ num = num >>> exp;
+ }
+ while (num != 0);
+
+ return String.valueOf(buffer, i, 32-i);
+ }
+
+ public String toString()
+ {
+ return toString(this.value);
+ }
+
+ public static String toString(int num)
+ {
+ // Use an arrary large enough for "-2147483648"; i.e. 11 chars.
+ char[] buffer = new char[11];
+ int i = 11;
+ boolean isNeg;
+ if (num < 0)
+ {
+ isNeg = true;
+ num = -(num);
+ if (num < 0)
+ {
+ // Must be MIN_VALUE, so handle this special case.
+ buffer[--i] = '8';
+ num = 214748364;
+ }
+ }
+ else
+ isNeg = false;
+
+ do
+ {
+ buffer[--i] = (char) ((int) '0' + (num % 10));
+ num /= 10;
+ }
+ while (num > 0);
+
+ if (isNeg)
+ buffer[--i] = '-';
+
+ return String.valueOf(buffer, i, 11-i);
+ }
+
+ public static String toString(int num, int radix)
+ {
+ // Use optimized method for the typical case.
+ if (radix == 10 ||
+ radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
+ return toString(num);
+
+ // For negative numbers, print out the absolute value w/ a leading '-'.
+ // Use an array large enough for a binary number.
+ char[] buffer = new char[33];
+ int i = 33;
+ boolean isNeg;
+ if (num < 0)
+ {
+ isNeg = true;
+ num = -(num);
+
+ // When the value is MIN_VALUE, it overflows when made positive
+ if (num < 0)
+ {
+ buffer[--i] = Character.forDigit(-(num + radix) % radix, radix);
+ num = -(num / radix);
+ }
+ }
+ else
+ isNeg = false;
+
+ do
+ {
+ buffer[--i] = Character.forDigit(num % radix, radix);
+ num /= radix;
+ }
+ while (num > 0);
+
+ if (isNeg)
+ buffer[--i] = '-';
+
+ return String.valueOf(buffer, i, 33-i);
+ }
+
+ public static Integer valueOf(String str) throws NumberFormatException
+ {
+ return new Integer(parseInt(str, 10));
+ }
+
+ public static Integer valueOf(String str, int radix)
+ throws NumberFormatException
+ {
+ return new Integer(parseInt(str, radix));
+ }
+}
diff --git a/libjava/java/lang/InternalError.java b/libjava/java/lang/InternalError.java
new file mode 100644
index 00000000000..6e484cfa6d0
--- /dev/null
+++ b/libjava/java/lang/InternalError.java
@@ -0,0 +1,34 @@
+// InternalError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class InternalError extends VirtualMachineError
+{
+ public InternalError ()
+ {
+ super ();
+ }
+
+ public InternalError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/InterruptedException.java b/libjava/java/lang/InterruptedException.java
new file mode 100644
index 00000000000..ef2e9b3adaf
--- /dev/null
+++ b/libjava/java/lang/InterruptedException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class InterruptedException extends Exception
+{
+ public InterruptedException()
+ {
+ super();
+ }
+
+ public InterruptedException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/LinkageError.java b/libjava/java/lang/LinkageError.java
new file mode 100644
index 00000000000..c9386a7c3c1
--- /dev/null
+++ b/libjava/java/lang/LinkageError.java
@@ -0,0 +1,34 @@
+// LinkageError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class LinkageError extends Error
+{
+ public LinkageError ()
+ {
+ super ();
+ }
+
+ public LinkageError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/Long.java b/libjava/java/lang/Long.java
new file mode 100644
index 00000000000..1ee8bf36277
--- /dev/null
+++ b/libjava/java/lang/Long.java
@@ -0,0 +1,366 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public final class Long extends Number implements Comparable
+{
+ public static final long MAX_VALUE = 0x7FFFFFFFFFFFFFFFL;
+ public static final long MIN_VALUE = 0x8000000000000000L;
+
+ // This initialization is seemingly circular, but it is accepted
+ // by javac, and is handled specially by gcc.
+ public static final Class TYPE = long.class;
+
+ /* The long value of the instance. */
+ private long value;
+
+ public Long(long val)
+ {
+ value = val;
+ }
+
+ public Long(String str) throws NumberFormatException
+ {
+ value = parseLong(str, 10);
+ }
+
+ public byte byteValue()
+ {
+ return (byte) value;
+ }
+
+ public double doubleValue()
+ {
+ return (double) value;
+ }
+
+ public float floatValue()
+ {
+ return (float) value;
+ }
+
+ public int intValue()
+ {
+ return (int) value;
+ }
+
+ public long longValue()
+ {
+ return value;
+ }
+
+ public short shortValue()
+ {
+ return (short) value;
+ }
+
+ // Added in JDK 1.2
+ public int compareTo(Long anotherLong)
+ {
+ if (this.value == anotherLong.value)
+ return 0;
+
+ // Returns just -1 or 1 on inequality; doing math might overflow the long.
+ if (this.value > anotherLong.value)
+ return 1;
+
+ return -1;
+ }
+
+ // Added in JDK 1.2
+ public int compareTo(Object o) throws ClassCastException
+ {
+ if (!(o instanceof Long))
+ throw new ClassCastException();
+
+ return this.compareTo((Long) o);
+ }
+
+ // Added in JDK 1.2
+ public static Long decode(String str) throws NumberFormatException
+ {
+ boolean isNeg = false;
+ int index = 0;
+ int radix = 10;
+ final int len;
+
+ if (str == null || (len = str.length()) == 0)
+ throw new NumberFormatException();
+
+ // Negative numbers are always radix 10.
+ if (str.charAt(0) == '-')
+ {
+ radix = 10;
+ index++;
+ isNeg = true;
+ }
+ else if (str.charAt(index) == '#')
+ {
+ radix = 16;
+ index++;
+ }
+ else if (str.charAt(index) == '0')
+ {
+ // Check if str is just "0"
+ if (len == 1)
+ return new Long(0L);
+
+ index++;
+ if (str.charAt(index) == 'x')
+ {
+ radix = 16;
+ index++;
+ }
+ else
+ radix = 8;
+ }
+
+ if (index >= len)
+ throw new NumberFormatException();
+
+ return new Long(parseLong(str, index, len, isNeg, radix));
+ }
+
+ public boolean equals(Object obj)
+ {
+ return (obj != null && (obj instanceof Long)
+ && ((Long) obj).value == value);
+ }
+
+ public static Long getLong(String prop)
+ {
+ return getLong(prop, null);
+ }
+
+ public static Long getLong(String prop, long defval)
+ {
+ Long val = getLong(prop, null);
+ return val == null ? new Long(defval) : val;
+ }
+
+ public static Long getLong(String prop, Long defobj)
+ {
+ try
+ {
+ return decode(System.getProperty(prop));
+ }
+ catch (NumberFormatException ex)
+ {
+ return defobj;
+ }
+ }
+
+ public int hashCode()
+ {
+ return (int)(this.longValue()^(this.longValue()>>>32));
+ }
+
+ public static long parseLong(String str) throws NumberFormatException
+ {
+ return parseLong(str, 10);
+ }
+
+ public static long parseLong(String str, int radix)
+ throws NumberFormatException
+ {
+ final int len;
+
+ if (str == null || (len = str.length()) == 0 ||
+ radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
+ throw new NumberFormatException();
+
+ boolean isNeg = false;
+ int index = 0;
+ if (str.charAt(index) == '-')
+ if (len > 1)
+ {
+ isNeg = true;
+ index++;
+ }
+ else
+ throw new NumberFormatException();
+
+ return parseLong(str, index, len, isNeg, radix);
+ }
+
+ private static long parseLong(String str, int index, int len, boolean isNeg,
+ int radix) throws NumberFormatException
+ {
+ long val = 0;
+ int digval;
+
+ for ( ; index < len; index++)
+ {
+ // The the previous loop iteration left us with a negative
+ // value (which can only be the most negative value, but we
+ // don't check that), then having more digits is wrong.
+ if (val == MIN_VALUE)
+ throw new NumberFormatException();
+
+ if ((digval = Character.digit(str.charAt(index), radix)) < 0)
+ throw new NumberFormatException();
+
+ // Throw an exception for overflow if result is negative.
+ // However, we special-case the most negative value.
+ val *= radix;
+ if (val < 0 || val + digval < 0)
+ {
+ if (isNeg && val + digval == MIN_VALUE)
+ {
+ // Ok.
+ }
+ else
+ throw new NumberFormatException();
+ }
+ val += digval;
+ }
+
+ return isNeg ? -(val) : val;
+ }
+
+ public static String toBinaryString(long num)
+ {
+ return toUnsignedString(num, 1);
+ }
+
+ public static String toHexString(long num)
+ {
+ return toUnsignedString(num, 4);
+ }
+
+ public static String toOctalString(long num)
+ {
+ return toUnsignedString(num, 3);
+ }
+
+ private static String toUnsignedString(long num, int exp)
+ {
+ // Use an array large enough for a binary number.
+ int radix = 1 << exp;
+ long mask = radix - 1;
+ char[] buffer = new char[64];
+ int i = 64;
+ do
+ {
+ buffer[--i] = Character.forDigit((int) (num & mask), radix);
+ num = num >>> exp;
+ }
+ while (num != 0);
+
+ return String.valueOf(buffer, i, 64-i);
+ }
+
+ public String toString()
+ {
+ return toString(this.value);
+ }
+
+ public static String toString(long num)
+ {
+ // Use the Integer toString for efficiency if possible.
+ if (num <= Integer.MAX_VALUE && num >= Integer.MIN_VALUE)
+ return Integer.toString((int) num);
+
+ // Use an arrary large enough for "-9223372036854775808"; i.e. 11 chars.
+ char[] buffer = new char[20];
+ int i = 20;
+ boolean isNeg;
+ if (num < 0)
+ {
+ isNeg = true;
+ num = -(num);
+ if (num < 0)
+ {
+ // Must be MIN_VALUE, so handle this special case.
+ buffer[--i] = '8';
+ num = 922337203685477580L;
+ }
+ }
+ else
+ isNeg = false;
+
+ do
+ {
+ buffer[--i] = (char) ((int) '0' + (num % 10));
+ num /= 10;
+ }
+ while (num > 0);
+
+ if (isNeg)
+ buffer[--i] = '-';
+
+ return String.valueOf(buffer, i, 20-i);
+ }
+
+ public static String toString(long num, int radix)
+ {
+ // Use optimized method for the typical case.
+ if (radix == 10 ||
+ radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
+ return toString(num);
+
+ // Use the Integer toString for efficiency if possible.
+ if (num <= Integer.MAX_VALUE && num >= Integer.MIN_VALUE)
+ return Integer.toString((int) num, radix);
+
+ // For negative numbers, print out the absolute value w/ a leading '-'.
+ // Use an array large enough for a binary number.
+ char[] buffer = new char[65];
+ int i = 65;
+ boolean isNeg;
+ if (num < 0)
+ {
+ isNeg = true;
+ num = -(num);
+
+ // When the value is MIN_VALUE, it overflows when made positive
+ if (num < 0)
+ {
+ buffer[--i] = Character.forDigit((int) (-(num + radix) % radix),
+ radix);
+ num = -(num / radix);
+ }
+ }
+ else
+ isNeg = false;
+
+ do
+ {
+ buffer[--i] = Character.forDigit((int) (num % radix), radix);
+ num /= radix;
+ }
+ while (num > 0);
+
+ if (isNeg)
+ buffer[--i] = '-';
+
+ return String.valueOf(buffer, i, 65-i);
+ }
+
+ public static Long valueOf(String str) throws NumberFormatException
+ {
+ return new Long(parseLong(str, 10));
+ }
+
+ public static Long valueOf(String str, int radix)
+ throws NumberFormatException
+ {
+ return new Long(parseLong(str, radix));
+ }
+}
diff --git a/libjava/java/lang/Math.java b/libjava/java/lang/Math.java
new file mode 100644
index 00000000000..77c00bd2fd5
--- /dev/null
+++ b/libjava/java/lang/Math.java
@@ -0,0 +1,118 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/**
+ * @author Andrew Haley <aph@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+package java.lang;
+
+import java.util.Random;
+
+public final class Math
+{
+ private static Random random_;
+
+ public static final double E = 2.7182818284590452354;
+ public static final double PI = 3.14159265358979323846;
+
+ public static native double sin (double x);
+
+ public static native double cos (double x);
+
+ public static native double tan (double x);
+
+ public static native double asin (double x);
+
+ public static native double acos (double x);
+
+ public static native double atan (double x);
+
+ public static native double atan2(double y, double x);
+
+ public static native double exp (double x);
+
+ public static native double log (double x);
+
+ public static native double sqrt (double x);
+
+ public static native double pow (double x, double y);
+
+ public static native double IEEEremainder (double x, double y);
+
+ public static native double ceil (double x);
+
+ public static native double floor (double x);
+
+ public static native double rint (double x);
+
+ public static native int round (float x);
+
+ public static native long round (double x);
+
+ public static synchronized double random ()
+ {
+ if (random_ == null)
+ random_ = new Random ();
+ return random_.nextDouble ();
+ }
+
+ public static int abs (int n)
+ {
+ return (n < 0 ? -n : n);
+ }
+
+ public static long abs (long n)
+ {
+ return (n < 0 ? -n : n);
+ }
+
+ public static native float abs (float x);
+
+ public static native double abs (double x);
+
+ public static int min (int a, int b)
+ {
+ return (a < b ? a : b);
+ }
+
+ public static long min (long a, long b)
+ {
+ return (a < b ? a : b);
+ }
+
+ public static native float min (float a, float b);
+
+ public static native double min (double a, double b);
+
+ public static int max (int a, int b)
+ {
+ return (a < b ? b : a);
+ }
+
+ public static long max (long a, long b)
+ {
+ return (a < b ? b : a);
+ }
+
+ public static native float max (float a, float b);
+
+ public static native double max (double a, double b);
+
+ // Don't allow objects to be made.
+ private Math ()
+ {
+ }
+}
+
diff --git a/libjava/java/lang/NegativeArraySizeException.java b/libjava/java/lang/NegativeArraySizeException.java
new file mode 100644
index 00000000000..838f408e49c
--- /dev/null
+++ b/libjava/java/lang/NegativeArraySizeException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class NegativeArraySizeException extends RuntimeException
+{
+ public NegativeArraySizeException()
+ {
+ super();
+ }
+
+ public NegativeArraySizeException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/NoClassDefFoundError.java b/libjava/java/lang/NoClassDefFoundError.java
new file mode 100644
index 00000000000..4368d35baa4
--- /dev/null
+++ b/libjava/java/lang/NoClassDefFoundError.java
@@ -0,0 +1,34 @@
+// NoClassDefFoundError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class NoClassDefFoundError extends LinkageError
+{
+ public NoClassDefFoundError ()
+ {
+ super ();
+ }
+
+ public NoClassDefFoundError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/NoSuchFieldError.java b/libjava/java/lang/NoSuchFieldError.java
new file mode 100644
index 00000000000..13165e89798
--- /dev/null
+++ b/libjava/java/lang/NoSuchFieldError.java
@@ -0,0 +1,34 @@
+// NoSuchFieldError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class NoSuchFieldError extends IncompatibleClassChangeError
+{
+ public NoSuchFieldError ()
+ {
+ super ();
+ }
+
+ public NoSuchFieldError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/NoSuchFieldException.java b/libjava/java/lang/NoSuchFieldException.java
new file mode 100644
index 00000000000..6e51cdad739
--- /dev/null
+++ b/libjava/java/lang/NoSuchFieldException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class NoSuchFieldException extends Exception
+{
+ public NoSuchFieldException()
+ {
+ super();
+ }
+
+ public NoSuchFieldException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/NoSuchMethodError.java b/libjava/java/lang/NoSuchMethodError.java
new file mode 100644
index 00000000000..2c4c1da9f05
--- /dev/null
+++ b/libjava/java/lang/NoSuchMethodError.java
@@ -0,0 +1,34 @@
+// NoSuchMethodError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class NoSuchMethodError extends IncompatibleClassChangeError
+{
+ public NoSuchMethodError ()
+ {
+ super ();
+ }
+
+ public NoSuchMethodError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/NoSuchMethodException.java b/libjava/java/lang/NoSuchMethodException.java
new file mode 100644
index 00000000000..9861777c77d
--- /dev/null
+++ b/libjava/java/lang/NoSuchMethodException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class NoSuchMethodException extends Exception
+{
+ public NoSuchMethodException()
+ {
+ super();
+ }
+
+ public NoSuchMethodException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/NullPointerException.java b/libjava/java/lang/NullPointerException.java
new file mode 100644
index 00000000000..1d1abdd148c
--- /dev/null
+++ b/libjava/java/lang/NullPointerException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class NullPointerException extends RuntimeException
+{
+ public NullPointerException()
+ {
+ super();
+ }
+
+ public NullPointerException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/Number.java b/libjava/java/lang/Number.java
new file mode 100644
index 00000000000..bf9306b45f3
--- /dev/null
+++ b/libjava/java/lang/Number.java
@@ -0,0 +1,39 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+import java.io.Serializable;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 2, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public abstract class Number implements Serializable
+{
+ public byte byteValue() // Became non-abstract in JDK 1.2
+ {
+ return (byte) intValue();
+ }
+
+ public abstract double doubleValue();
+ public abstract float floatValue();
+ public abstract int intValue();
+ public abstract long longValue();
+
+ public short shortValue() // Became non-abstract in JDK 1.2
+ {
+ return (short) intValue();
+ }
+}
diff --git a/libjava/java/lang/NumberFormatException.java b/libjava/java/lang/NumberFormatException.java
new file mode 100644
index 00000000000..c05a8f172d4
--- /dev/null
+++ b/libjava/java/lang/NumberFormatException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class NumberFormatException extends IllegalArgumentException
+{
+ public NumberFormatException()
+ {
+ super();
+ }
+
+ public NumberFormatException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/Object.h b/libjava/java/lang/Object.h
new file mode 100644
index 00000000000..c5d55f17833
--- /dev/null
+++ b/libjava/java/lang/Object.h
@@ -0,0 +1,79 @@
+// Object.h - Header file for java.lang.Object. -*- c++ -*-
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#ifndef __JAVA_LANG_OBJECT_H__
+#define __JAVA_LANG_OBJECT_H__
+
+#pragma interface
+
+#include <javaprims.h>
+#include <java-assert.h>
+#include <java-threads.h>
+#include <java-gc.h>
+
+// This class is mainly here as a kludge to get G++ to allocate
+// vtable pointer as the *first* word of each Object, instead of
+// the second word (following sync_info). Note that various pieces of
+// code know that finalize() is the first method. For instance,
+// Object.java knows this, as does _Jv_AllocObject.
+
+struct _JvObjectPrefix
+{
+protected:
+ // This is disguised as the C++ vtbl.
+ // _Jv_VTable* vtable;
+
+ virtual void finalize () = 0;
+};
+
+class java::lang::Object : public _JvObjectPrefix
+{
+public:
+ // Order must match order in Object.java.
+ jclass getClass (void);
+ virtual jint hashCode (void);
+ void notify (void);
+ void notifyAll (void);
+ void wait (jlong timeout, jint nanos);
+ virtual jboolean equals (jobject obj);
+ Object (void);
+ virtual jstring toString (void);
+ void wait (void);
+ void wait (jlong timeout);
+
+ friend jint _Jv_MonitorEnter (jobject obj);
+ friend jint _Jv_MonitorExit (jobject obj);
+ friend void _Jv_InitializeSyncMutex (void);
+ friend void _Jv_FinalizeObject (jobject obj);
+
+#ifdef JV_MARKOBJ_DECL
+ friend JV_MARKOBJ_DECL;
+#endif
+#ifdef JV_MARKARRAY_DECL
+ friend JV_MARKARRAY_DECL;
+#endif
+
+protected:
+ virtual jobject clone (void);
+ virtual void finalize (void);
+
+private:
+ // This does not actually refer to a Java object. Instead it is a
+ // placeholder for a piece of internal data (the synchronization
+ // information).
+ jobject sync_info;
+
+ // Initialize the sync_info field.
+ void sync_init (void);
+
+ static void hack12_6 (jobject f);
+};
+
+#endif /* __JAVA_LANG_OBJECT_H__ */
diff --git a/libjava/java/lang/Object.java b/libjava/java/lang/Object.java
new file mode 100644
index 00000000000..2adad290812
--- /dev/null
+++ b/libjava/java/lang/Object.java
@@ -0,0 +1,86 @@
+// Object.java - The root of all evil.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date September 30, 1998
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * plus gcj compiler sources (to determine object layout)
+ * Status: Complete to version 1.1
+ */
+
+public class Object
+{
+ // This must come first. See _JvObjectPrefix in Object.h.
+ protected void finalize () throws Throwable
+ {
+ }
+
+ public final native Class getClass ();
+ public native int hashCode ();
+ public final native void notify ();
+ public final native void notifyAll ();
+ public final native void wait (long timeout, int nanos)
+ throws InterruptedException;
+
+ public boolean equals (Object obj)
+ {
+ return this == obj;
+ }
+
+ public Object ()
+ {
+ }
+
+ public String toString ()
+ {
+ return getClass().getName() + '@' + Integer.toHexString(hashCode());
+ }
+
+ public final void wait () throws InterruptedException
+ {
+ wait (0, 0);
+ }
+
+ public final void wait (long timeout) throws InterruptedException
+ {
+ wait (timeout, 0);
+ }
+
+ protected native Object clone () throws CloneNotSupportedException;
+
+ // This initializes the sync_info member. It is here for
+ // completeness (some day we'll be able to auto-generate Object.h).
+ private final native void sync_init ();
+
+ // This exists as a workaround for the fact that we can't catch a
+ // Java Exception from C++. This is from section 12.6 of the Java
+ // Language Spec. FIXME: remove this once exception processing
+ // works.
+ private static final void hack12_6 (Object f)
+ {
+ try
+ {
+ f.finalize();
+ }
+ catch (Throwable x)
+ {
+ }
+ }
+
+ // Note that we don't mention the sync_info field here. If we do,
+ // jc1 will not work correctly.
+}
diff --git a/libjava/java/lang/OutOfMemoryError.java b/libjava/java/lang/OutOfMemoryError.java
new file mode 100644
index 00000000000..418e13ccbce
--- /dev/null
+++ b/libjava/java/lang/OutOfMemoryError.java
@@ -0,0 +1,34 @@
+// OutOfMemoryError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class OutOfMemoryError extends VirtualMachineError
+{
+ public OutOfMemoryError ()
+ {
+ super ();
+ }
+
+ public OutOfMemoryError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/Process.java b/libjava/java/lang/Process.java
new file mode 100644
index 00000000000..765bc9bb8bd
--- /dev/null
+++ b/libjava/java/lang/Process.java
@@ -0,0 +1,30 @@
+// Process.java - Represent spawned system process.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+import java.io.*;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 23, 1998.
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ */
+
+public abstract class Process
+{
+ abstract public void destroy ();
+ abstract public int exitValue ();
+ abstract public InputStream getErrorStream ();
+ abstract public InputStream getInputStream ();
+ abstract public OutputStream getOutputStream ();
+ abstract public int waitFor () throws InterruptedException;
+}
diff --git a/libjava/java/lang/Runnable.java b/libjava/java/lang/Runnable.java
new file mode 100644
index 00000000000..8e27d91856d
--- /dev/null
+++ b/libjava/java/lang/Runnable.java
@@ -0,0 +1,27 @@
+// Runnable.java - Runnable interface.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date August 25, 1998
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Complete.
+ */
+
+public interface Runnable
+{
+ public abstract void run ();
+}
diff --git a/libjava/java/lang/Runtime.java b/libjava/java/lang/Runtime.java
new file mode 100644
index 00000000000..baf1ae541b7
--- /dev/null
+++ b/libjava/java/lang/Runtime.java
@@ -0,0 +1,136 @@
+// Runtime.java - Runtime class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date August 27, 1998
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: All 1.1 methods exist. exec(), load(), and loadLibrary()
+ * are not fully implemented.
+ */
+
+public class Runtime
+{
+ public Process exec (String prog) throws IOException
+ {
+ String[] a = new String[1];
+ a[0] = prog;
+ return exec (a, null);
+ }
+
+ public Process exec (String prog, String[] envp) throws IOException
+ {
+ String[] a = new String[1];
+ a[0] = prog;
+ return exec (a, envp);
+ }
+
+ public Process exec (String[] progarray) throws IOException
+ {
+ return exec (progarray, null);
+ }
+
+ public Process exec (String[] progarray, String[] envp) throws IOException
+ {
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkExec(progarray[0]);
+ // FIXME.
+ return null;
+ }
+
+ private final static void checkExit (int status)
+ {
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkExit(status);
+ }
+
+ public native void exit (int status);
+
+ public native long freeMemory ();
+ public native void gc ();
+
+ // Deprecated in 1.1. We implement what the JCL book says.
+ public InputStream getLocalizedInputStream (InputStream in)
+ {
+ return in;
+ }
+
+ // Deprecated in 1.1. We implement what the JCL book says.
+ public OutputStream getLocalizedOutputStream (OutputStream out)
+ {
+ return out;
+ }
+
+ public static Runtime getRuntime ()
+ {
+ return self;
+ }
+
+ private final void checkLink (String lib)
+ {
+ if (lib == null)
+ throw new NullPointerException ();
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkLink(lib);
+ }
+
+ public synchronized void load (String pathname)
+ {
+ checkLink (pathname);
+ // FIXME.
+ throw new UnsatisfiedLinkError ("Runtime.load not implemented");
+ }
+ public synchronized void loadLibrary (String libname)
+ {
+ checkLink (libname);
+ // FIXME.
+ throw new UnsatisfiedLinkError ("Runtime.loadLibrary not implemented");
+ }
+
+ public native void runFinalization ();
+
+ // This method is static in JDK 1.1, but isn't listed as static in
+ // the books. It is marked as static in the 1.2 docs.
+ public static void runFinalizersOnExit (boolean run)
+ {
+ // The status we pass to the security check is unspecified.
+ checkExit (0);
+ self.finalize_on_exit = run;
+ }
+
+ public native long totalMemory ();
+ public native void traceInstructions (boolean on);
+ public native void traceMethodCalls (boolean on);
+
+ // The sole constructor.
+ private Runtime ()
+ {
+ finalize_on_exit = false;
+ }
+
+ // Private data.
+ private static Runtime self = new Runtime ();
+ // FIXME: for now this can't be static. If it is, our compiler will
+ // mark it as local, and it will be inaccessible to natRuntime.cc.
+ private boolean finalize_on_exit;
+}
diff --git a/libjava/java/lang/RuntimeException.java b/libjava/java/lang/RuntimeException.java
new file mode 100644
index 00000000000..e0d3f5397d3
--- /dev/null
+++ b/libjava/java/lang/RuntimeException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class RuntimeException extends Exception
+{
+ public RuntimeException()
+ {
+ super();
+ }
+
+ public RuntimeException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/SecurityException.java b/libjava/java/lang/SecurityException.java
new file mode 100644
index 00000000000..8a6a94f7f75
--- /dev/null
+++ b/libjava/java/lang/SecurityException.java
@@ -0,0 +1,31 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998. */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class SecurityException extends RuntimeException
+{
+ public SecurityException()
+ {
+ super();
+ }
+
+ public SecurityException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/SecurityManager.java b/libjava/java/lang/SecurityManager.java
new file mode 100644
index 00000000000..50091f1044e
--- /dev/null
+++ b/libjava/java/lang/SecurityManager.java
@@ -0,0 +1,263 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// SecurityManager
+
+package java.lang;
+
+/**
+ * @author Anthony Green <green@cygnus.com>
+ * @date October 5, 1998.
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ */
+
+import java.io.*;
+import java.net.*;
+
+public abstract class SecurityManager
+{
+ protected boolean inCheck = false;
+
+ public void checkAccept (String host, int port)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkAccess (Thread thrd)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkAccess (ThreadGroup thrdGroup)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkAwtEventQueueAccess ()
+ {
+ throw new SecurityException();
+ }
+
+ public void checkConnect (String host, int prt)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkConnect (String host, int prt, Object ctx)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkCreateClassLoader ()
+ {
+ throw new SecurityException();
+ }
+
+ public void checkDelete (String fileName)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkExec (String prog)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkExit (int stat)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkLink (String lib)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkListen (int lport)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkMemberAccess (Class cl, int mtype)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkMulticast (InetAddress maddr)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkMulticast (InetAddress maddr, byte ttl)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkPackageAccess (String pkg)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkPackageDefinition (String pkg)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkPrintJobAccess ()
+ {
+ throw new SecurityException();
+ }
+
+ public void checkPropertiesAccess ()
+ {
+ throw new SecurityException();
+ }
+
+ public void checkPropertyAccess (String prop)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkPropertyAccess (String prop, String defval)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkRead (FileDescriptor fd)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkRead (String fileName)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkRead (String fileName, Object ctx)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkSecurityAccess (String action)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkSetFactory ()
+ {
+ throw new SecurityException();
+ }
+
+ public void checkSystemClipboardAccess ()
+ {
+ throw new SecurityException();
+ }
+
+ public boolean checkTopLevelWindow (Object window)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkWrite (FileDescriptor fd)
+ {
+ throw new SecurityException();
+ }
+
+ public void checkWrite (String fileName)
+ {
+ throw new SecurityException();
+ }
+
+ // Note: this method is deprecated in JDK 1.2
+ protected /* native */ int classDepth (String className)
+ {
+ Class[] classStack = getClassContext ();
+ for (int i = 0; i < classStack.length; i++)
+ if (classStack[i].getName().compareTo(className) == 0)
+ return i;
+
+ return -1;
+ }
+
+ // Note: this method is deprecated in JDK 1.2
+ protected /* native */ int classLoaderDepth ()
+ {
+ Class[] classStack = getClassContext ();
+ for (int i = 0; i < classStack.length; i++)
+ if (classStack[i].getClassLoader() != null)
+ return i;
+
+ return -1;
+ }
+
+ protected /* native */ ClassLoader currentClassLoader ()
+ {
+ Class[] classStack = getClassContext ();
+ for (int i = 0; i < classStack.length; i++)
+ {
+ ClassLoader loader = classStack[i].getClassLoader();
+ if (loader != null)
+ return loader;
+ }
+
+ return null;
+ }
+
+ protected /* native */ Class currentLoadedClass ()
+ {
+ Class[] classStack = getClassContext ();
+ for (int i = 0; i < classStack.length; i++)
+ {
+ ClassLoader loader = classStack[i].getClassLoader();
+ if (loader != null)
+ return classStack[i];
+ }
+
+ return null;
+ }
+
+ protected /* native */ Class[] getClassContext ()
+ {
+ return new Class[0];
+ }
+
+ // Note: this method is deprecated in JDK 1.2
+ public boolean getInCheck ()
+ {
+ return inCheck;
+ }
+
+ public Object getSecurityContext ()
+ {
+ // FIXME: This has yet to be implemented.
+ return new String("");
+ }
+
+ public ThreadGroup getThreadGroup ()
+ {
+ return Thread.currentThread().getThreadGroup();
+ }
+
+ protected boolean inClass (String className)
+ {
+ return (classDepth (className) != -1);
+ }
+
+ protected boolean inClassLoader ()
+ {
+ return (classLoaderDepth () != -1);
+ }
+
+ protected SecurityManager ()
+ {
+ if (System.getSecurityManager () != null)
+ throw new SecurityException ();
+ }
+}
diff --git a/libjava/java/lang/Short.java b/libjava/java/lang/Short.java
new file mode 100644
index 00000000000..4a17f2d6ea7
--- /dev/null
+++ b/libjava/java/lang/Short.java
@@ -0,0 +1,145 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Per Bothner <bothner@cygnus.com>
+ * @date April 17, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, plus online
+ * API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ * Includes JDK 1.2 methods.
+ */
+
+public final class Short extends Number implements Comparable
+{
+ short value;
+
+ public final static short MIN_VALUE = -32768;
+ public final static short MAX_VALUE = 32767;
+
+ // This initialization is seemingly circular, but it is accepted
+ // by javac, and is handled specially by gcc.
+ public static final Class TYPE = short.class;
+
+ public Short(short value)
+ {
+ this.value = value;
+ }
+
+ public Short(String str)
+ throws NumberFormatException
+ {
+ this.value = parseShort(str, 10);
+ }
+
+ public byte byteValue()
+ {
+ return (byte) value;
+ }
+
+ public short shortValue()
+ {
+ return value;
+ }
+
+ public int intValue()
+ {
+ return value;
+ }
+
+ public long longValue ()
+ {
+ return value;
+ }
+
+ public float floatValue ()
+ {
+ return (float) value;
+ }
+
+ public double doubleValue ()
+ {
+ return (double) value;
+ }
+
+ public static Short decode(String str)
+ throws NumberFormatException
+ {
+ int i = (Integer.decode(str)).intValue();
+ if (i < MIN_VALUE || i > MAX_VALUE)
+ throw new NumberFormatException();
+ return new Short((short) i);
+ }
+
+ public static short parseShort(String str, int radix)
+ throws NumberFormatException
+ {
+ int i = Integer.parseInt(str, radix);
+ if (i < MIN_VALUE || i > MAX_VALUE)
+ throw new NumberFormatException();
+ return (short) i;
+ }
+
+ public static short parseShort(String str)
+ throws NumberFormatException
+ {
+ return parseShort(str, 10);
+ }
+
+ public static Short valueOf(String str, int radix)
+ throws NumberFormatException
+ {
+ return new Short(parseShort(str, radix));
+ }
+
+ public static Short valueOf(String str)
+ throws NumberFormatException
+ {
+ return valueOf(str, 10);
+ }
+
+ // Added in JDK 1.2
+ public int compareTo(Short anotherShort)
+ {
+ return this.value - anotherShort.value;
+ }
+
+ // Added in JDK 1.2
+ public int compareTo(Object o) throws ClassCastException
+ {
+ if (o instanceof Short)
+ return this.value - ((Short) o).value;
+ else
+ throw new ClassCastException();
+ }
+
+ public boolean equals(Object obj)
+ {
+ return (obj != null && (obj instanceof Short)
+ && ((Short) obj).value == value);
+ }
+
+ // Verified that hashCode is returns plain value (see Short_1 test).
+ public int hashCode()
+ {
+ return value;
+ }
+
+ public String toString()
+ {
+ return Integer.toString((int) value);
+ }
+
+ public static String toString(short value)
+ {
+ return Integer.toString((int) value);
+ }
+}
diff --git a/libjava/java/lang/StackOverflowError.java b/libjava/java/lang/StackOverflowError.java
new file mode 100644
index 00000000000..ace8b25c1a0
--- /dev/null
+++ b/libjava/java/lang/StackOverflowError.java
@@ -0,0 +1,34 @@
+// StackOverflowError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class StackOverflowError extends VirtualMachineError
+{
+ public StackOverflowError ()
+ {
+ super ();
+ }
+
+ public StackOverflowError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/String.java b/libjava/java/lang/String.java
new file mode 100644
index 00000000000..1321676d0e5
--- /dev/null
+++ b/libjava/java/lang/String.java
@@ -0,0 +1,286 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * @author Per Bothner <bothner@cygnus.com>
+ * @date September 4, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, plus online
+ * API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Complete to 1.1, but see FIXMEs. Also see testsuite results.
+ */
+
+public final class String
+{
+ private Object data;
+ private int boffset; // Note this is a byte offset - don't use in Java code!
+ private int count;
+
+ public String ()
+ {
+ init();
+ }
+
+ public String (String value)
+ {
+ data = value.data;
+ boffset = value.boffset;
+ count = value.count;
+ }
+
+ public String (StringBuffer buffer)
+ {
+ init (buffer.value, 0, buffer.count, true);
+ }
+
+ public String (char[] data)
+ {
+ init(data, 0, data.length, false);
+ }
+
+ public String (char[] data, int offset, int count)
+ {
+ init(data, offset, count, false);
+ }
+
+ public String (byte[] byteArray)
+ {
+ this (byteArray, 0, byteArray.length);
+ }
+
+ public String (byte[] byteArray, int offset, int count)
+ {
+ try
+ {
+ init (byteArray, offset, count,
+ System.getProperty("file.encoding", "8859_1"));
+ }
+ catch (UnsupportedEncodingException x1)
+ {
+ // Maybe the default encoding is bad.
+ try
+ {
+ init (byteArray, offset, count, "8859_1");
+ }
+ catch (UnsupportedEncodingException x2)
+ {
+ // We know this can't happen.
+ }
+ }
+ }
+
+ public String (byte[] byteArray, String enc)
+ throws UnsupportedEncodingException
+ {
+ this (byteArray, 0, byteArray.length, enc);
+ }
+
+ public String (byte[] byteArray, int offset, int count, String enc)
+ throws UnsupportedEncodingException
+ {
+ init (byteArray, offset, count, enc);
+ }
+
+ public static String copyValueOf(char[] data)
+ {
+ return copyValueOf (data, 0, data.length);
+ }
+
+ public static String copyValueOf(char[] data, int offset, int count)
+ {
+ String r = new String ();
+ r.init(data, offset, count, false);
+ return r;
+ }
+
+ /** @deprecated */
+ public String (byte[] ascii, int hibyte)
+ {
+ init(ascii, hibyte, 0, ascii.length);
+ }
+
+ /** @deprecated */
+ public String (byte[] ascii, int hibyte, int offset, int count)
+ {
+ init(ascii, hibyte, offset, count);
+ }
+
+ public String toString ()
+ {
+ return this;
+ }
+
+ public native boolean equals (Object anObject);
+
+ public native int hashCode ();
+
+ public int length ()
+ {
+ return count;
+ }
+
+ public native char charAt (int index);
+
+ public native void getChars (int srcBegin, int srcEnd,
+ char[] dst, int dstBegin);
+
+ public byte[] getBytes () throws UnsupportedEncodingException
+ {
+ return getBytes (System.getProperty("file.encoding", "8859_1"));
+ }
+
+ public native byte[] getBytes (String enc)
+ throws UnsupportedEncodingException;
+
+ /** @deprecated */
+ public native void getBytes (int srcBegin, int srcEnd,
+ byte[] dst, int dstBegin);
+
+ public native char[] toCharArray ();
+
+ public native boolean equalsIgnoreCase (String anotherString);
+
+ public native int compareTo (String anotherString);
+
+ public native boolean regionMatches (int toffset,
+ String other, int ooffset, int len);
+
+ public native boolean regionMatches (boolean ignoreCase, int toffset,
+ String other, int ooffset, int len);
+
+ public boolean startsWith (String prefix)
+ {
+ return startsWith (prefix, 0);
+ }
+
+ public native boolean startsWith (String prefix, int toffset);
+
+ public boolean endsWith (String suffix)
+ {
+ return regionMatches (this.count - suffix.count, suffix, 0, suffix.count);
+ }
+
+ // No such method specified in the doc, including JDK 1.2.
+ // public boolean endsWith (String suffix, int toffset)
+ // {
+ // return regionMatches (toffset, suffix, 0, suffix.count);
+ // }
+
+ // The Language Specification, and the JDK 1.2 API docs say that
+ // index and lastIndex take an int, while the Class Libraries
+ // say they take a char. The former wins ...
+
+ public int indexOf (int ch)
+ {
+ return indexOf (ch, 0);
+ }
+
+ public native int indexOf (int ch, int fromIndex);
+
+ public int indexOf (String str)
+ {
+ return indexOf (str, 0);
+ }
+
+ public native int indexOf (String str, int fromIndex);
+
+ public int lastIndexOf (int ch)
+ {
+ return lastIndexOf (ch, count - 1);
+ }
+
+ public native int lastIndexOf (int ch, int fromIndex);
+
+ public int lastIndexOf (String str)
+ {
+ return lastIndexOf (str, count - str.count);
+ }
+
+ public int lastIndexOf (String str, int fromIndex)
+ {
+ if (fromIndex >= count)
+ fromIndex = count - str.count;
+ for (;; --fromIndex)
+ {
+ if (fromIndex < 0)
+ return -1;
+ if (startsWith(str, fromIndex))
+ return fromIndex;
+ }
+ }
+
+ public String substring (int beginIndex)
+ {
+ return substring (beginIndex, count);
+ }
+
+ public native String substring (int beginIndex, int endIndex);
+
+ public native String concat (String str);
+
+ public native String replace (char oldChar, char newChar);
+
+ public native String toLowerCase ();
+
+ public native String toUpperCase ();
+
+ public native String trim ();
+
+ public static String valueOf (Object obj)
+ {
+ return obj == null ? "null" : obj.toString();
+ }
+
+ public static String valueOf (char[] data)
+ {
+ return valueOf (data, 0, data.length);
+ }
+
+ public static native String valueOf (char[] data, int offset, int count);
+
+ public static String valueOf (boolean b)
+ {
+ return b ? "true" : "false";
+ }
+
+ public static native String valueOf (char c);
+
+ public static String valueOf (int i)
+ {
+ return Integer.toString(i);
+ }
+
+ public static String valueOf (long l)
+ {
+ return Long.toString(l);
+ }
+
+ public static String valueOf (float f)
+ {
+ return Float.toString(f);
+ }
+
+ public static String valueOf (double d)
+ {
+ return Double.toString(d);
+ }
+
+ public native String intern ();
+
+ private native void init ();
+ private native void init (char[] chars, int offset, int count,
+ boolean dont_copy);
+ private native void init (byte[] chars, int hibyte, int offset, int count);
+ private native void init (byte[] chars, int offset, int count, String enc)
+ throws UnsupportedEncodingException;
+ private native void unintern ();
+ private static native void rehash ();
+}
diff --git a/libjava/java/lang/StringBuffer.java b/libjava/java/lang/StringBuffer.java
new file mode 100644
index 00000000000..4127d54787f
--- /dev/null
+++ b/libjava/java/lang/StringBuffer.java
@@ -0,0 +1,270 @@
+// StringBuffer.java - Growable strings.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+import java.io.Serializable;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 23, 1998.
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ */
+
+public final class StringBuffer implements Serializable
+{
+ public StringBuffer append (boolean bool)
+ {
+ return append (String.valueOf(bool));
+ }
+
+ public synchronized StringBuffer append (char ch)
+ {
+ ensureCapacity (count + 1);
+ value[count++] = ch;
+ return this;
+ }
+
+ public StringBuffer append (int inum)
+ {
+ return append (String.valueOf(inum));
+ }
+
+ public StringBuffer append (long lnum)
+ {
+ return append (String.valueOf(lnum));
+ }
+
+ public StringBuffer append (float fnum)
+ {
+ return append (String.valueOf(fnum));
+ }
+
+ public StringBuffer append (double dnum)
+ {
+ return append (String.valueOf(dnum));
+ }
+
+ public StringBuffer append (Object obj)
+ {
+ return append (String.valueOf(obj));
+ }
+
+ public synchronized StringBuffer append (String str)
+ {
+ if (str == null)
+ str = "null";
+ int len = str.length();
+ ensureCapacity (count + len);
+ str.getChars(0, len, value, count);
+ count += len;
+ return this;
+ }
+
+ public StringBuffer append (char[] data)
+ {
+ return append (data, 0, data.length);
+ }
+
+ public synchronized StringBuffer append (char[] data, int offset, int count)
+ {
+ ensureCapacity (this.count + count);
+ System.arraycopy(data, offset, value, this.count, count);
+ this.count += count;
+ return this;
+ }
+
+ public int capacity ()
+ {
+ return value.length;
+ }
+
+ public synchronized char charAt (int index)
+ {
+ if (index >= count)
+ throw new StringIndexOutOfBoundsException (index);
+ return value[index];
+ }
+
+ public synchronized void ensureCapacity (int minimumCapacity)
+ {
+ if (shared || minimumCapacity > value.length)
+ {
+ minimumCapacity = Math.max(minimumCapacity, value.length*2+2);
+ char[] nb = new char[minimumCapacity];
+ System.arraycopy(value, 0, nb, 0, count);
+ value = nb;
+ shared = false;
+ }
+ }
+
+ public synchronized void getChars (int srcOffset, int srcEnd,
+ char[] dst, int dstOffset)
+ {
+ if (srcOffset < 0 || srcOffset > srcEnd)
+ throw new StringIndexOutOfBoundsException (srcOffset);
+ int todo = srcEnd - srcOffset;
+ if (srcEnd > count || dstOffset + todo > count)
+ throw new StringIndexOutOfBoundsException (srcEnd);
+ System.arraycopy(value, srcOffset, dst, dstOffset, todo);
+ }
+
+ public StringBuffer insert (int offset, boolean bool)
+ {
+ return insert (offset, bool ? "true" : "false");
+ }
+
+ public synchronized StringBuffer insert (int offset, char ch)
+ {
+ if (offset < 0 || offset > count)
+ throw new StringIndexOutOfBoundsException (offset);
+ ensureCapacity (count+1);
+ System.arraycopy(value, offset, value, offset+1, count-offset);
+ value[offset] = ch;
+ count++;
+ return this;
+ }
+
+ public StringBuffer insert (int offset, int inum)
+ {
+ return insert (offset, String.valueOf(inum));
+ }
+
+ public StringBuffer insert (int offset, long lnum)
+ {
+ return insert (offset, String.valueOf(lnum));
+ }
+
+ public StringBuffer insert (int offset, float fnum)
+ {
+ return insert (offset, String.valueOf(fnum));
+ }
+
+ public StringBuffer insert (int offset, double dnum)
+ {
+ return insert (offset, String.valueOf(dnum));
+ }
+
+ public StringBuffer insert (int offset, Object obj)
+ {
+ return insert (offset, String.valueOf(obj));
+ }
+
+ public synchronized StringBuffer insert (int offset, String str)
+ {
+ if (offset < 0 || offset > count)
+ throw new StringIndexOutOfBoundsException (offset);
+ // Note that using `null' is from JDK 1.2.
+ if (str == null)
+ str = "null";
+ int len = str.length();
+ ensureCapacity(count+len);
+ System.arraycopy(value, offset, value, offset+len, count-offset);
+ str.getChars(0, len, value, offset);
+ count += len;
+ return this;
+ }
+
+ public synchronized StringBuffer insert (int offset, char[] data)
+ {
+ if (offset < 0 || offset > count)
+ throw new StringIndexOutOfBoundsException (offset);
+ int len = data.length;
+ ensureCapacity (count+len);
+ System.arraycopy(value, offset, value, offset+len, count-offset);
+ System.arraycopy(data, 0, value, offset, len);
+ count += len;
+ return this;
+ }
+
+ public int length ()
+ {
+ return count;
+ }
+
+ public synchronized StringBuffer reverse ()
+ {
+ for (int i = 0; i < count / 2; ++i)
+ {
+ char c = value[i];
+ value[i] = value[count - i - 1];
+ value[count - i - 1] = c;
+ }
+ return this;
+ }
+
+ public synchronized void setCharAt (int index, char ch)
+ {
+ if (index < 0 || index >= count)
+ throw new StringIndexOutOfBoundsException (index);
+ // Call ensureCapacity to enforce copy-on-write.
+ ensureCapacity (count);
+ value[index] = ch;
+ }
+
+ public synchronized void setLength (int newLength)
+ {
+ if (newLength < 0)
+ throw new StringIndexOutOfBoundsException (newLength);
+
+ ensureCapacity (newLength);
+ for (int i = count; i < newLength; ++i)
+ value[i] = '\0';
+ count = newLength;
+ }
+
+ public StringBuffer ()
+ {
+ this (16);
+ }
+
+ public StringBuffer (int capacity)
+ {
+ count = 0;
+ value = new char[capacity];
+ shared = false;
+ }
+
+ public StringBuffer (String str)
+ {
+ // Note: nowhere does it say that we should handle a null
+ // argument here. In fact, the JCL implies that we should not.
+ // But this leads to an asymmetry: `null + ""' will fail, while
+ // `"" + null' will work.
+ if (str == null)
+ str = "null";
+ count = str.length();
+ // JLS: The initial capacity of the string buffer is 16 plus the
+ // length of the argument string.
+ value = new char[count + 16];
+ str.getChars(0, count, value, 0);
+ shared = false;
+ }
+
+ public String toString ()
+ {
+ shared = true;
+ return new String (this);
+ }
+
+ // The buffer. Note that this has permissions set this way so that
+ // String can get the value.
+ char[] value;
+
+ // Index of next available character. Note that this has
+ // permissions set this way so that String can get the value.
+ int count;
+
+ // True if we need to copy the buffer before writing to it again.
+ // FIXME: JDK 1.2 doesn't specify this. The new buffer-growing
+ // semantics make this less useful in that case, too.
+ private boolean shared;
+}
diff --git a/libjava/java/lang/StringIndexOutOfBoundsException.java b/libjava/java/lang/StringIndexOutOfBoundsException.java
new file mode 100644
index 00000000000..200acb896f0
--- /dev/null
+++ b/libjava/java/lang/StringIndexOutOfBoundsException.java
@@ -0,0 +1,37 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class StringIndexOutOfBoundsException extends IndexOutOfBoundsException
+{
+ public StringIndexOutOfBoundsException()
+ {
+ super();
+ }
+
+ public StringIndexOutOfBoundsException(int index)
+ {
+ this("String index out of range: " + index);
+ }
+
+ public StringIndexOutOfBoundsException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/System.java b/libjava/java/lang/System.java
new file mode 100644
index 00000000000..6f6dee42057
--- /dev/null
+++ b/libjava/java/lang/System.java
@@ -0,0 +1,166 @@
+// System.java - System-specific info.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FilterInputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.util.Properties;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date August 27, 1998
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: 1.1. Some 1.2 methods missing. Properties code not fully
+ * implemented.
+ */
+
+public final class System
+{
+ public static native void arraycopy (Object src, int srcOffset,
+ Object dst, int dstOffset,
+ int count);
+
+ public static native long currentTimeMillis ();
+
+ public static void exit (int status)
+ {
+ Runtime.getRuntime().exit(status);
+ }
+
+ public static void gc ()
+ {
+ Runtime.getRuntime().gc();
+ }
+
+ // Marked deprecated in 1.1. We implement what the JCL book says.
+ public static String getenv (String name)
+ {
+ throw new Error ();
+ }
+
+ private static native void init_properties ();
+
+ public static Properties getProperties ()
+ {
+ if (secman != null)
+ secman.checkPropertiesAccess();
+ init_properties ();
+ return properties;
+ }
+
+ public static String getProperty (String property)
+ {
+ if (secman != null)
+ secman.checkPropertyAccess(property);
+ init_properties ();
+ return properties.getProperty(property);
+ }
+
+ public static String getProperty (String property, String defval)
+ {
+ if (secman != null)
+ secman.checkPropertyAccess(property, defval);
+ init_properties ();
+ return properties.getProperty(property, defval);
+ }
+
+ public static SecurityManager getSecurityManager ()
+ {
+ return secman;
+ }
+
+ public static native int identityHashCode (Object obj);
+
+ public static void load (String pathname)
+ {
+ Runtime.getRuntime().load(pathname);
+ }
+
+ public static void loadLibrary (String libname)
+ {
+ Runtime.getRuntime().loadLibrary(libname);
+ }
+
+ public static void runFinalization ()
+ {
+ Runtime.getRuntime().runFinalization();
+ }
+
+ // Marked as deprecated in 1.2.
+ public static void runFinalizersOnExit (boolean run)
+ {
+ Runtime.getRuntime().runFinalizersOnExit(run);
+ }
+
+ private static void checkSetIO ()
+ {
+ // In 1.1, we are supposed to call checkExec, but the argument is
+ // not specified. In 1.2, we are supposed to use checkPermission,
+ // which doesn't exist in 1.1.
+ if (secman != null)
+ secman.checkExec("");
+ }
+
+ public static native void setErr (PrintStream newErr);
+ public static native void setIn (InputStream newIn);
+ public static native void setOut (PrintStream newOut);
+
+ public static void setProperties (Properties props)
+ {
+ if (secman != null)
+ secman.checkPropertiesAccess();
+ // We might not have initialized yet.
+ prop_init = true;
+ properties = props;
+ }
+
+ // TODO 1.2.
+ // public static String setProperty (String key, String value);
+
+ // TODO 1.2.
+ // public static String mapLibraryName (String libname);
+
+ public static void setSecurityManager (SecurityManager s)
+ {
+ if (secman != null)
+ throw new SecurityException ();
+ secman = s;
+ }
+
+ // Public data.
+ public static final InputStream in = new BufferedInputStream (new FileInputStream (FileDescriptor.in));
+
+ public static final PrintStream out = new PrintStream (new BufferedOutputStream (new FileOutputStream (FileDescriptor.out)), true);
+
+ public static final PrintStream err = new PrintStream (new BufferedOutputStream (new FileOutputStream (FileDescriptor.err)), true);
+
+ // Don't allow System objects to be made.
+ private System ()
+ {
+ }
+
+ // Private data.
+ private static SecurityManager secman = null;
+ private static Properties properties = null;
+ // This boolean is only required for 1.1 and earlier. After 1.1, a
+ // null properties should always be re-initialized.
+ private static boolean prop_init = false;
+}
diff --git a/libjava/java/lang/Thread.java b/libjava/java/lang/Thread.java
new file mode 100644
index 00000000000..f21d3a3fb7d
--- /dev/null
+++ b/libjava/java/lang/Thread.java
@@ -0,0 +1,297 @@
+// Thread.java - Thread class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date August 24, 1998
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Complete to version 1.1, with caveats
+ * Known problems:
+ * No attempt was made to implement suspend/resume
+ * (this could be done in some cases)
+ * Various methods which assume a VM are likewise unimplemented
+ * We do implement stop() even though it is deprecated.
+ */
+
+public class Thread implements Runnable
+{
+ public final static int MAX_PRIORITY = 10;
+ public final static int MIN_PRIORITY = 1;
+ public final static int NORM_PRIORITY = 5;
+
+ public static int activeCount ()
+ {
+ return currentThread().getThreadGroup().activeCount();
+ }
+
+ public void checkAccess ()
+ {
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkAccess(this);
+ }
+
+ public native int countStackFrames ();
+ public static native Thread currentThread ();
+ public native void destroy ();
+ public static native void dumpStack ();
+
+ public static int enumerate (Thread[] threads)
+ {
+ return currentThread().group.enumerate(threads);
+ }
+
+ public final String getName ()
+ {
+ return name;
+ }
+
+ public final int getPriority ()
+ {
+ return priority;
+ }
+
+ public final ThreadGroup getThreadGroup ()
+ {
+ return group;
+ }
+
+ public native void interrupt ();
+
+ public static boolean interrupted ()
+ {
+ return currentThread().isInterrupted();
+ }
+
+ // FIXME: it seems to me that this should be synchronized.
+ public boolean isInterrupted ()
+ {
+ boolean r = interrupt_flag;
+ interrupt_flag = false;
+ return r;
+ }
+
+ public final boolean isAlive ()
+ {
+ return alive_flag;
+ }
+
+ public final boolean isDaemon ()
+ {
+ return daemon_flag;
+ }
+
+ public final void join () throws InterruptedException
+ {
+ join (0, 0);
+ }
+
+ public final void join (long timeout) throws InterruptedException
+ {
+ join (timeout, 0);
+ }
+
+ public final native void join (long timeout, int nanos)
+ throws InterruptedException;
+
+ public final native void resume ();
+
+ // This method exists only to avoid a warning from the C++ compiler.
+ private static final native void run__ (Object obj);
+ private native final void finish_ ();
+ private final void run_ ()
+ {
+ try
+ {
+ run ();
+ }
+ catch (Throwable e)
+ {
+ // Uncaught exceptions are forwarded to the ThreadGroup. If
+ // this results in an uncaught exception, that is ignored.
+ try
+ {
+ group.uncaughtException(this, e);
+ }
+ catch (Throwable f)
+ {
+ // Nothing.
+ }
+ }
+ finish_ ();
+ }
+
+ public void run ()
+ {
+ if (runnable != null)
+ runnable.run();
+ }
+
+ public final void setDaemon (boolean status)
+ {
+ checkAccess ();
+ if (isAlive ())
+ throw new IllegalThreadStateException ();
+ daemon_flag = status;
+ }
+
+ // TODO12:
+ // public ClassLoader getContextClassLoader()
+ // {
+ // }
+
+ // TODO12:
+ // public void setContextClassLoader(ClassLoader cl)
+ // {
+ // }
+
+ public final void setName (String n)
+ {
+ checkAccess ();
+ // The Class Libraries book says ``threadName cannot be null''. I
+ // take this to mean NullPointerException.
+ if (n == null)
+ throw new NullPointerException ();
+ name = n;
+ }
+
+ public final native void setPriority (int newPriority);
+
+ public static void sleep (long timeout) throws InterruptedException
+ {
+ sleep (timeout, 0);
+ }
+
+ public static native void sleep (long timeout, int nanos)
+ throws InterruptedException;
+ public synchronized native void start ();
+
+ public final void stop ()
+ {
+ stop (new ThreadDeath ());
+ }
+
+ public final synchronized native void stop (Throwable e);
+ public final native void suspend ();
+
+ private final native void initialize_native ();
+
+ private final synchronized static String gen_name ()
+ {
+ String n;
+ n = "Thread-" + nextThreadNumber;
+ ++nextThreadNumber;
+ return n;
+ }
+
+ public Thread (ThreadGroup g, Runnable r, String n)
+ {
+ // Note that CURRENT can be null when we are creating the very
+ // first thread. That's why we check it below.
+ Thread current = currentThread ();
+
+ if (g != null)
+ {
+ // If CURRENT is null, then we are creating the first thread.
+ // In this case we don't do the security check.
+ if (current != null)
+ g.checkAccess();
+ }
+ else
+ g = current.getThreadGroup();
+
+ // The Class Libraries book says ``threadName cannot be null''. I
+ // take this to mean NullPointerException.
+ if (n == null)
+ throw new NullPointerException ();
+
+ name = n;
+ group = g;
+ g.add(this);
+ runnable = r;
+
+ data = null;
+ interrupt_flag = false;
+ alive_flag = false;
+ if (current != null)
+ {
+ daemon_flag = current.isDaemon();
+ priority = current.getPriority();
+ }
+ else
+ {
+ daemon_flag = false;
+ priority = NORM_PRIORITY;
+ }
+
+ initialize_native ();
+ }
+
+ public Thread ()
+ {
+ this (null, null, gen_name ());
+ }
+
+ public Thread (Runnable r)
+ {
+ this (null, r, gen_name ());
+ }
+
+ public Thread (String n)
+ {
+ this (null, null, n);
+ }
+
+ public Thread (ThreadGroup g, Runnable r)
+ {
+ this (g, r, gen_name ());
+ }
+
+ public Thread (ThreadGroup g, String n)
+ {
+ this (g, null, n);
+ }
+
+ public Thread (Runnable r, String n)
+ {
+ this (null, r, n);
+ }
+
+ public String toString ()
+ {
+ return "Thread[" + name + "," + priority + "," + group.getName() + "]";
+ }
+
+ public static native void yield ();
+
+ // Private data.
+ private ThreadGroup group;
+ private String name;
+ private Runnable runnable;
+ private int priority;
+ private boolean daemon_flag;
+ private boolean interrupt_flag;
+ private boolean alive_flag;
+
+ // This is a bit odd. We need a way to represent some data that is
+ // manipulated only by the native side of this class. We represent
+ // it as a Java object reference. However, it is not actually a
+ // Java object.
+ private Object data;
+
+ // Next thread number to assign.
+ private static int nextThreadNumber = 0;
+}
diff --git a/libjava/java/lang/ThreadDeath.java b/libjava/java/lang/ThreadDeath.java
new file mode 100644
index 00000000000..caffc936d2e
--- /dev/null
+++ b/libjava/java/lang/ThreadDeath.java
@@ -0,0 +1,35 @@
+// ThreadDeath.java - Special exception registering Thread death.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date August 26, 1998
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Complete to version 1.1
+ */
+
+public class ThreadDeath extends Error
+{
+ public ThreadDeath ()
+ {
+ super ();
+ }
+
+ public ThreadDeath (String message)
+ {
+ super (message);
+ }
+}
diff --git a/libjava/java/lang/ThreadGroup.java b/libjava/java/lang/ThreadGroup.java
new file mode 100644
index 00000000000..1aa1a9a3bed
--- /dev/null
+++ b/libjava/java/lang/ThreadGroup.java
@@ -0,0 +1,406 @@
+// ThreadGroup.java - ThreadGroup class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date August 25, 1998
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Complete for 1.1. Parts from the JDK 1.0 spec only are
+ * not implemented. Parts of the 1.2 spec are also not implemented.
+ */
+
+public class ThreadGroup
+{
+ public int activeCount ()
+ {
+ int ac = threads.size();
+ Enumeration e = groups.elements();
+ while (e.hasMoreElements())
+ {
+ ThreadGroup g = (ThreadGroup) e.nextElement();
+ ac += g.activeCount();
+ }
+ return ac;
+ }
+
+ public int activeGroupCount ()
+ {
+ int ac = groups.size();
+ Enumeration e = groups.elements();
+ while (e.hasMoreElements())
+ {
+ ThreadGroup g = (ThreadGroup) e.nextElement();
+ ac += g.activeGroupCount();
+ }
+ return ac;
+ }
+
+ // Deprecated in 1.2.
+ public boolean allowThreadSuspension (boolean allow)
+ {
+ // There is no way for a Java program to determine whether this
+ // has any effect whatsoever. We don't need it.
+ return true;
+ }
+
+ public final void checkAccess ()
+ {
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkAccess(this);
+ }
+
+ // This is called to remove a ThreadGroup from our internal list.
+ private final void remove (ThreadGroup g)
+ {
+ groups.removeElement(g);
+ if (daemon_flag && groups.size() == 0 && threads.size() == 0)
+ {
+ // We inline destroy to avoid the access check.
+ destroyed_flag = true;
+ if (parent != null)
+ parent.remove(this);
+ }
+ }
+
+ // This is called by the Thread code to remove a Thread from our
+ // internal list. FIXME: currently, it isn't called at all. There
+ // doesn't appear to be any way to remove a Thread from a
+ // ThreadGroup (except the unimplemented destroy method).
+ final void remove (Thread t)
+ {
+ threads.removeElement(t);
+ if (daemon_flag && groups.size() == 0 && threads.size() == 0)
+ {
+ // We inline destroy to avoid the access check.
+ destroyed_flag = true;
+ if (parent != null)
+ parent.remove(this);
+ }
+ }
+
+ // This is called by the Thread code to add a Thread to our internal
+ // list.
+ final void add (Thread t)
+ {
+ if (destroyed_flag)
+ throw new IllegalThreadStateException ();
+
+ threads.addElement(t);
+ }
+
+ // This is a helper that is used to implement the destroy method.
+ private final boolean canDestroy ()
+ {
+ if (! threads.isEmpty())
+ return false;
+ Enumeration e = groups.elements();
+ while (e.hasMoreElements())
+ {
+ ThreadGroup g = (ThreadGroup) e.nextElement();
+ if (! g.canDestroy())
+ return false;
+ }
+ return true;
+ }
+
+ public final void destroy ()
+ {
+ checkAccess ();
+ if (! canDestroy ())
+ throw new IllegalThreadStateException ();
+ destroyed_flag = true;
+ if (parent != null)
+ parent.remove(this);
+ }
+
+ // This actually implements enumerate.
+ private final int enumerate (Thread[] ts, int next_index, boolean recurse)
+ {
+ Enumeration e = threads.elements();
+ while (e.hasMoreElements() && next_index < ts.length)
+ ts[next_index++] = (Thread) e.nextElement();
+ if (recurse && next_index != ts.length)
+ {
+ e = groups.elements();
+ while (e.hasMoreElements() && next_index < ts.length)
+ {
+ ThreadGroup g = (ThreadGroup) e.nextElement();
+ next_index = g.enumerate(ts, next_index, true);
+ }
+ }
+ return next_index;
+ }
+
+ public int enumerate (Thread[] ts)
+ {
+ return enumerate (ts, 0, true);
+ }
+
+ public int enumerate (Thread[] ts, boolean recurse)
+ {
+ return enumerate (ts, 0, recurse);
+ }
+
+ // This actually implements enumerate.
+ private final int enumerate (ThreadGroup[] ts, int next_index,
+ boolean recurse)
+ {
+ Enumeration e = groups.elements();
+ while (e.hasMoreElements() && next_index < ts.length)
+ {
+ ThreadGroup g = (ThreadGroup) e.nextElement();
+ ts[next_index++] = g;
+ if (recurse && next_index != ts.length)
+ next_index = g.enumerate(ts, next_index, true);
+ }
+ return next_index;
+ }
+
+ public int enumerate (ThreadGroup[] gs)
+ {
+ return enumerate (gs, 0, true);
+ }
+
+ public int enumerate (ThreadGroup[] gs, boolean recurse)
+ {
+ return enumerate (gs, 0, recurse);
+ }
+
+ public final int getMaxPriority ()
+ {
+ return maxpri;
+ }
+
+ public final String getName ()
+ {
+ return name;
+ }
+
+ public final ThreadGroup getParent ()
+ {
+ return parent;
+ }
+
+ // JDK 1.2.
+ // public void interrupt ();
+
+ public final boolean isDaemon ()
+ {
+ return daemon_flag;
+ }
+
+ public synchronized boolean isDestroyed ()
+ {
+ return destroyed_flag;
+ }
+
+ private final void list (String indentation)
+ {
+ System.out.print(indentation);
+ System.out.println(toString ());
+ String sub = indentation + " ";
+ Enumeration e = threads.elements();
+ while (e.hasMoreElements())
+ {
+ Thread t = (Thread) e.nextElement();
+ System.out.print(sub);
+ System.out.println(t.toString());
+ }
+ e = groups.elements();
+ while (e.hasMoreElements())
+ {
+ ThreadGroup g = (ThreadGroup) e.nextElement();
+ g.list(sub);
+ }
+ }
+
+ public void list ()
+ {
+ list ("");
+ }
+
+ public final boolean parentOf (ThreadGroup g)
+ {
+ while (g != null)
+ {
+ if (this == g)
+ return true;
+ g = g.parent;
+ }
+ return false;
+ }
+
+ // Deprecated in 1.2.
+ public final void resume ()
+ {
+ checkAccess ();
+ Enumeration e = threads.elements();
+ while (e.hasMoreElements())
+ {
+ Thread t = (Thread) e.nextElement();
+ t.resume();
+ }
+ e = groups.elements();
+ while (e.hasMoreElements())
+ {
+ ThreadGroup g = (ThreadGroup) e.nextElement();
+ g.resume();
+ }
+ }
+
+ public final void setDaemon (boolean daemon)
+ {
+ checkAccess ();
+ daemon_flag = daemon;
+ // FIXME: the docs don't say you are supposed to do this. But
+ // they don't say you aren't, either.
+ if (groups.size() == 0 && threads.size() == 0)
+ destroy ();
+ }
+
+ public final void setMaxPriority (int pri)
+ {
+ checkAccess ();
+
+ // FIXME: JDK 1.2 behaviour is different: if the newMaxPriority
+ // argument is < MIN_PRIORITY or > MAX_PRIORITY an
+ // IllegalArgumentException should be thrown.
+ if (pri >= Thread.MIN_PRIORITY && pri <= maxpri)
+ {
+ maxpri = pri;
+
+ Enumeration e = groups.elements();
+ while (e.hasMoreElements())
+ {
+ ThreadGroup g = (ThreadGroup) e.nextElement();
+ g.setMaxPriority (maxpri);
+ }
+ }
+ }
+
+ // Deprecated in 1.2.
+ public final void stop ()
+ {
+ checkAccess ();
+ Enumeration e = threads.elements();
+ while (e.hasMoreElements())
+ {
+ Thread t = (Thread) e.nextElement();
+ t.stop();
+ }
+ e = groups.elements();
+ while (e.hasMoreElements())
+ {
+ ThreadGroup g = (ThreadGroup) e.nextElement();
+ g.stop();
+ }
+ }
+
+ // Deprecated in 1.2.
+ public final void suspend ()
+ {
+ checkAccess ();
+ Enumeration e = threads.elements();
+ while (e.hasMoreElements())
+ {
+ Thread t = (Thread) e.nextElement();
+ t.suspend();
+ }
+ e = groups.elements();
+ while (e.hasMoreElements())
+ {
+ ThreadGroup g = (ThreadGroup) e.nextElement();
+ g.suspend();
+ }
+ }
+
+ // This constructor appears in the Class Libraries book but in
+ // neither the Language Spec nor the 1.2 docs.
+ public ThreadGroup ()
+ {
+ this (Thread.currentThread().getThreadGroup(), null);
+ }
+
+ public ThreadGroup (String n)
+ {
+ this (Thread.currentThread().getThreadGroup(), n);
+ }
+
+ public ThreadGroup (ThreadGroup p, String n)
+ {
+ checkAccess ();
+ if (p == null)
+ throw new NullPointerException ();
+ if (p.destroyed_flag)
+ throw new IllegalArgumentException ();
+
+ parent = p;
+ name = n;
+ maxpri = p.maxpri;
+ threads = new Vector ();
+ groups = new Vector ();
+ daemon_flag = p.daemon_flag;
+ destroyed_flag = false;
+ p.groups.addElement(this);
+ }
+
+ // This is the constructor that is used when creating the very first
+ // ThreadGroup. We have an arbitrary argument here just to
+ // differentiate this constructor from the others.
+ private ThreadGroup (int dummy)
+ {
+ parent = null;
+ name = "main";
+ maxpri = Thread.MAX_PRIORITY;
+ threads = new Vector ();
+ groups = new Vector ();
+ daemon_flag = false;
+ destroyed_flag = false;
+ }
+
+ public String toString ()
+ {
+ // Language Spec and Class Libraries book disagree a bit here. We
+ // follow the Spec, but add "ThreadGroup" per the book. We
+ // include "java.lang" based on the list() example in the Class
+ // Libraries book.
+ return "java.lang.ThreadGroup[name=" + name + ",maxpri=" + maxpri + "]";
+ }
+
+ public void uncaughtException (Thread thread, Throwable e)
+ {
+ // FIXME: in 1.2, this has different semantics. In particular if
+ // this group has a parent, the exception is passed upwards and
+ // not processed locally.
+ if (! (e instanceof ThreadDeath))
+ {
+ e.printStackTrace();
+ }
+ }
+
+ // Private data.
+ private ThreadGroup parent;
+ private String name;
+ private int maxpri;
+ private Vector threads;
+ private Vector groups;
+ private boolean daemon_flag;
+ private boolean destroyed_flag;
+}
diff --git a/libjava/java/lang/Throwable.java b/libjava/java/lang/Throwable.java
new file mode 100644
index 00000000000..5ae39ae2594
--- /dev/null
+++ b/libjava/java/lang/Throwable.java
@@ -0,0 +1,80 @@
+// Throwable.java - Superclass for all exceptions.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 30, 1998
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * Status: Sufficient for compiled code, but methods applicable to
+ * bytecode not implemented. JDK 1.1.
+ */
+
+public class Throwable implements Serializable
+{
+ public Throwable fillInStackTrace ()
+ {
+ return this;
+ }
+
+ public String getLocalizedMessage ()
+ {
+ return getMessage ();
+ }
+
+ public String getMessage ()
+ {
+ return detailMessage;
+ }
+
+ public void printStackTrace ()
+ {
+ printStackTrace (System.err);
+ }
+
+ public void printStackTrace (PrintStream s)
+ {
+ // No stack trace, but we can still print this object.
+ s.println(toString ());
+ }
+
+ public void printStackTrace (PrintWriter wr)
+ {
+ // No stack trace, but we can still print this object.
+ wr.println(toString ());
+ }
+
+ public Throwable ()
+ {
+ detailMessage = null;
+ }
+
+ public Throwable (String message)
+ {
+ detailMessage = message;
+ }
+
+ public String toString ()
+ {
+ return ((detailMessage == null)
+ ? getClass().getName()
+ : getClass().getName() + ": " + getMessage ());
+ }
+
+ // Name of this field comes from serialization spec.
+ private String detailMessage;
+}
diff --git a/libjava/java/lang/UnknownError.java b/libjava/java/lang/UnknownError.java
new file mode 100644
index 00000000000..edf050c77ec
--- /dev/null
+++ b/libjava/java/lang/UnknownError.java
@@ -0,0 +1,34 @@
+// UnknownError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class UnknownError extends VirtualMachineError
+{
+ public UnknownError ()
+ {
+ super ();
+ }
+
+ public UnknownError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/UnsatisfiedLinkError.java b/libjava/java/lang/UnsatisfiedLinkError.java
new file mode 100644
index 00000000000..63930f5555f
--- /dev/null
+++ b/libjava/java/lang/UnsatisfiedLinkError.java
@@ -0,0 +1,34 @@
+// UnsatisfiedLinkError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class UnsatisfiedLinkError extends LinkageError
+{
+ public UnsatisfiedLinkError ()
+ {
+ super ();
+ }
+
+ public UnsatisfiedLinkError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/UnsupportedOperationException.java b/libjava/java/lang/UnsupportedOperationException.java
new file mode 100644
index 00000000000..d2bee88622a
--- /dev/null
+++ b/libjava/java/lang/UnsupportedOperationException.java
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class UnsupportedOperationException extends RuntimeException
+{
+ public UnsupportedOperationException()
+ {
+ super();
+ }
+
+ public UnsupportedOperationException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/lang/VerifyError.java b/libjava/java/lang/VerifyError.java
new file mode 100644
index 00000000000..69d6a69baf5
--- /dev/null
+++ b/libjava/java/lang/VerifyError.java
@@ -0,0 +1,34 @@
+// VerifyError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public class VerifyError extends LinkageError
+{
+ public VerifyError ()
+ {
+ super ();
+ }
+
+ public VerifyError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/VirtualMachineError.java b/libjava/java/lang/VirtualMachineError.java
new file mode 100644
index 00000000000..dcc907c5d03
--- /dev/null
+++ b/libjava/java/lang/VirtualMachineError.java
@@ -0,0 +1,34 @@
+// VirtualMachineError.java
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+public abstract class VirtualMachineError extends Error
+{
+ public VirtualMachineError ()
+ {
+ super ();
+ }
+
+ public VirtualMachineError (String msg)
+ {
+ super (msg);
+ }
+}
diff --git a/libjava/java/lang/Void.java b/libjava/java/lang/Void.java
new file mode 100644
index 00000000000..5390552a622
--- /dev/null
+++ b/libjava/java/lang/Void.java
@@ -0,0 +1,30 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+/**
+ * @author Per Bothner <bothner@cygnus.com>
+ * @date April 18, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, plus online
+ * API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Complete.
+ */
+
+public final class Void
+{
+ // This initialization is seemingly circular, but it is accepted
+ // by javac, and is handled specially by gcc.
+ public final static Class TYPE = void.class;
+
+ // Don't allow Void objects to be made.
+ private Void ()
+ {
+ }
+}
diff --git a/libjava/java/lang/dtoa.c b/libjava/java/lang/dtoa.c
new file mode 100644
index 00000000000..fae45c5aeb4
--- /dev/null
+++ b/libjava/java/lang/dtoa.c
@@ -0,0 +1,906 @@
+/****************************************************************
+ *
+ * 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 "mprec.h"
+
+static int
+_DEFUN (quorem,
+ (b, S),
+ _Jv_Bigint * b _AND _Jv_Bigint * S)
+{
+ int n;
+ long borrow, y;
+ unsigned long carry, q, ys;
+ unsigned long *bx, *bxe, *sx, *sxe;
+#ifdef Pack_32
+ long z;
+ unsigned long si, zs;
+#endif
+
+ n = S->_wds;
+#ifdef DEBUG
+ /*debug*/ if (b->_wds > n)
+ /*debug*/ Bug ("oversize b in quorem");
+#endif
+ if (b->_wds < n)
+ return 0;
+ sx = S->_x;
+ sxe = sx + --n;
+ bx = b->_x;
+ bxe = bx + n;
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
+#ifdef DEBUG
+ /*debug*/ if (q > 9)
+ /*debug*/ Bug ("oversized quotient in quorem");
+#endif
+ if (q)
+ {
+ borrow = 0;
+ carry = 0;
+ do
+ {
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) * q + carry;
+ zs = (si >> 16) * q + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend (borrow, z);
+ Storeinc (bx, z, y);
+#else
+ ys = *sx++ * q + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ *bx++ = y & 0xffff;
+#endif
+ }
+ while (sx <= sxe);
+ if (!*bxe)
+ {
+ bx = b->_x;
+ while (--bxe > bx && !*bxe)
+ --n;
+ b->_wds = n;
+ }
+ }
+ if (cmp (b, S) >= 0)
+ {
+ q++;
+ borrow = 0;
+ carry = 0;
+ bx = b->_x;
+ sx = S->_x;
+ do
+ {
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) + carry;
+ zs = (si >> 16) + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend (borrow, z);
+ Storeinc (bx, z, y);
+#else
+ ys = *sx++ + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ *bx++ = y & 0xffff;
+#endif
+ }
+ while (sx <= sxe);
+ bx = b->_x;
+ bxe = bx + n;
+ if (!*bxe)
+ {
+ while (--bxe > bx && !*bxe)
+ --n;
+ b->_wds = n;
+ }
+ }
+ return q;
+}
+
+#ifdef DEBUG
+#include <stdio.h>
+
+void
+print (_Jv_Bigint * b)
+{
+ int i, wds;
+ unsigned long *x, y;
+ wds = b->_wds;
+ x = b->_x+wds;
+ i = 0;
+ do
+ {
+ x--;
+ fprintf (stderr, "%08x", *x);
+ }
+ while (++i < wds);
+ fprintf (stderr, "\n");
+}
+#endif
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the long
+ * calculation.
+ */
+
+
+char *
+_DEFUN (_dtoa_r,
+ (ptr, _d, mode, ndigits, decpt, sign, rve, float_type),
+ struct _Jv_reent *ptr _AND
+ double _d _AND
+ int mode _AND
+ int ndigits _AND
+ int *decpt _AND
+ int *sign _AND
+ char **rve _AND
+ int float_type)
+{
+ /*
+ float_type == 0 for double precision, 1 for float.
+
+ Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4-9 should give the same return values as 2-3, i.e.,
+ 4 <= mode <= 9 ==> same return as mode
+ 2 + (mode & 1). These modes are mainly for
+ debugging; often they run slower but sometimes
+ faster than modes 2-3.
+ 4,5,8,9 ==> left-to-right digit generation.
+ 6-9 ==> don't try fast floating-point estimate
+ (if applicable).
+
+ > 16 ==> Floating-point arg is treated as single precision.
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, j, j1, k, k0,
+ k_check, leftright, m2, m5, s2, s5, spec_case, try_quick;
+ union double_union d, d2, eps;
+ long L;
+#ifndef Sudden_Underflow
+ int denorm;
+ unsigned long x;
+#endif
+ _Jv_Bigint *b, *b1, *delta, *mlo, *mhi, *S;
+ double ds;
+ char *s, *s0;
+
+ d.d = _d;
+
+ if (ptr->_result)
+ {
+ ptr->_result->_k = ptr->_result_k;
+ ptr->_result->_maxwds = 1 << ptr->_result_k;
+ Bfree (ptr, ptr->_result);
+ ptr->_result = 0;
+ }
+
+ if (word0 (d) & Sign_bit)
+ {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ word0 (d) &= ~Sign_bit; /* clear sign bit */
+ }
+ else
+ *sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+ if ((word0 (d) & Exp_mask) == Exp_mask)
+#else
+ if (word0 (d) == 0x8000)
+#endif
+ {
+ /* Infinity or NaN */
+ *decpt = 9999;
+ s =
+#ifdef IEEE_Arith
+ !word1 (d) && !(word0 (d) & 0xfffff) ? "Infinity" :
+#endif
+ "NaN";
+ if (rve)
+ *rve =
+#ifdef IEEE_Arith
+ s[3] ? s + 8 :
+#endif
+ s + 3;
+ return s;
+ }
+#endif
+#ifdef IBM
+ d.d += 0; /* normalize */
+#endif
+ if (!d.d)
+ {
+ *decpt = 1;
+ s = "0";
+ if (rve)
+ *rve = s + 1;
+ return s;
+ }
+
+ b = d2b (ptr, d.d, &be, &bbits);
+#ifdef Sudden_Underflow
+ i = (int) (word0 (d) >> Exp_shift1 & (Exp_mask >> Exp_shift1));
+#else
+ if ((i = (int) (word0 (d) >> Exp_shift1 & (Exp_mask >> Exp_shift1))))
+ {
+#endif
+ d2.d = d.d;
+ word0 (d2) &= Frac_mask1;
+ word0 (d2) |= Exp_11;
+#ifdef IBM
+ if (j = 11 - hi0bits (word0 (d2) & Frac_mask))
+ d2.d /= 1 << j;
+#endif
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = (i - Bias)*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+
+ i -= Bias;
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+#ifndef Sudden_Underflow
+ denorm = 0;
+ }
+ else
+ {
+ /* d is denormalized */
+
+ i = bbits + be + (Bias + (P - 1) - 1);
+ x = i > 32 ? word0 (d) << (64 - i) | word1 (d) >> (i - 32)
+ : word1 (d) << (32 - i);
+ d2.d = x;
+ word0 (d2) -= 31 * Exp_msk1; /* adjust exponent */
+ i -= (Bias + (P - 1) - 1) + 1;
+ denorm = 1;
+ }
+#endif
+ ds = (d2.d - 1.5) * 0.289529654602168 + 0.1760912590558 + i * 0.301029995663981;
+ k = (int) ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+ if (k >= 0 && k <= Ten_pmax)
+ {
+ if (d.d < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0)
+ {
+ b2 = 0;
+ s2 = j;
+ }
+ else
+ {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0)
+ {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else
+ {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ if (mode < 0 || mode > 9)
+ mode = 0;
+ try_quick = 1;
+ if (mode > 5)
+ {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ switch (mode)
+ {
+ case 0:
+ case 1:
+ ilim = ilim1 = -1;
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* no break */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* no break */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ j = sizeof (unsigned long);
+ for (ptr->_result_k = 0; (int) (sizeof (_Jv_Bigint) - sizeof (unsigned long)) + j <= i;
+ j <<= 1)
+ ptr->_result_k++;
+ ptr->_result = Balloc (ptr, ptr->_result_k);
+ s = s0 = (char *) ptr->_result;
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick)
+ {
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ d2.d = d.d;
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0)
+ {
+ ds = tens[k & 0xf];
+ j = k >> 4;
+ if (j & Bletch)
+ {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ d.d /= bigtens[n_bigtens - 1];
+ ieps++;
+ }
+ for (; j; j >>= 1, i++)
+ if (j & 1)
+ {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ d.d /= ds;
+ }
+ else if ((j1 = -k))
+ {
+ d.d *= tens[j1 & 0xf];
+ for (j = j1 >> 4; j; j >>= 1, i++)
+ if (j & 1)
+ {
+ ieps++;
+ d.d *= bigtens[i];
+ }
+ }
+ if (k_check && d.d < 1. && ilim > 0)
+ {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ d.d *= 10.;
+ ieps++;
+ }
+ eps.d = ieps * d.d + 7.;
+ word0 (eps) -= (P - 1) * Exp_msk1;
+ if (ilim == 0)
+ {
+ S = mhi = 0;
+ d.d -= 5.;
+ if (d.d > eps.d)
+ goto one_digit;
+ if (d.d < -eps.d)
+ goto no_digits;
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright)
+ {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ eps.d = 0.5 / tens[ilim - 1] - eps.d;
+ for (i = 0;;)
+ {
+ L = d.d;
+ d.d -= L;
+ *s++ = '0' + (int) L;
+ if (d.d < eps.d)
+ goto ret1;
+ if (1. - d.d < eps.d)
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ eps.d *= 10.;
+ d.d *= 10.;
+ }
+ }
+ else
+ {
+#endif
+ /* Generate ilim digits, then fix them up. */
+ eps.d *= tens[ilim - 1];
+ for (i = 1;; i++, d.d *= 10.)
+ {
+ L = d.d;
+ d.d -= L;
+ *s++ = '0' + (int) L;
+ if (i == ilim)
+ {
+ if (d.d > 0.5 + eps.d)
+ goto bump_up;
+ else if (d.d < 0.5 - eps.d)
+ {
+ while (*--s == '0');
+ s++;
+ goto ret1;
+ }
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+ fast_failed:
+ s = s0;
+ d.d = d2.d;
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max)
+ {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0)
+ {
+ S = mhi = 0;
+ if (ilim < 0 || d.d <= 5 * ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for (i = 1;; i++)
+ {
+ L = d.d / ds;
+ d.d -= L * ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (d.d < 0)
+ {
+ L--;
+ d.d += ds;
+ }
+#endif
+ *s++ = '0' + (int) L;
+ if (i == ilim)
+ {
+ d.d += d.d;
+ if (d.d > ds || (d.d == ds && L & 1))
+ {
+ bump_up:
+ while (*--s == '9')
+ if (s == s0)
+ {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ break;
+ }
+ if (!(d.d *= 10.))
+ break;
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ mhi = mlo = 0;
+ if (leftright)
+ {
+ if (mode < 2)
+ {
+ i =
+#ifndef Sudden_Underflow
+ denorm ? be + (Bias + (P - 1) - 1 + 1) :
+#endif
+#ifdef IBM
+ 1 + 4 * P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+ 1 + P - bbits;
+#endif
+ }
+ else
+ {
+ j = ilim - 1;
+ if (m5 >= j)
+ m5 -= j;
+ else
+ {
+ s5 += j -= m5;
+ b5 += j;
+ m5 = 0;
+ }
+ if ((i = ilim) < 0)
+ {
+ m2 -= i;
+ i = 0;
+ }
+ }
+ b2 += i;
+ s2 += i;
+ mhi = i2b (ptr, 1);
+ }
+ if (m2 > 0 && s2 > 0)
+ {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0)
+ {
+ if (leftright)
+ {
+ if (m5 > 0)
+ {
+ mhi = pow5mult (ptr, mhi, m5);
+ b1 = mult (ptr, mhi, b);
+ Bfree (ptr, b);
+ b = b1;
+ }
+ if ((j = b5 - m5))
+ b = pow5mult (ptr, b, j);
+ }
+ else
+ b = pow5mult (ptr, b, b5);
+ }
+ S = i2b (ptr, 1);
+ if (s5 > 0)
+ S = pow5mult (ptr, S, s5);
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ if (mode < 2)
+ {
+ if (!word1 (d) && !(word0 (d) & Bndry_mask)
+#ifndef Sudden_Underflow
+ && word0 (d) & Exp_mask
+#endif
+ )
+ {
+ /* The special case */
+ b2 += Log2P;
+ s2 += Log2P;
+ spec_case = 1;
+ }
+ else
+ spec_case = 0;
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+
+#ifdef Pack_32
+ if ((i = ((s5 ? 32 - hi0bits (S->_x[S->_wds - 1]) : 1) + s2) & 0x1f))
+ i = 32 - i;
+#else
+ if ((i = ((s5 ? 32 - hi0bits (S->_x[S->_wds - 1]) : 1) + s2) & 0xf))
+ i = 16 - i;
+#endif
+ if (i > 4)
+ {
+ i -= 4;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ else if (i < 4)
+ {
+ i += 28;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ if (b2 > 0)
+ b = lshift (ptr, b, b2);
+ if (s2 > 0)
+ S = lshift (ptr, S, s2);
+ if (k_check)
+ {
+ if (cmp (b, S) < 0)
+ {
+ k--;
+ b = multadd (ptr, b, 10, 0); /* we botched the k estimate */
+ if (leftright)
+ mhi = multadd (ptr, mhi, 10, 0);
+ ilim = ilim1;
+ }
+ }
+ if (ilim <= 0 && mode > 2)
+ {
+ if (ilim < 0 || cmp (b, S = multadd (ptr, S, 5, 0)) <= 0)
+ {
+ /* no digits, fcvt style */
+ no_digits:
+ k = -1 - ndigits;
+ goto ret;
+ }
+ one_digit:
+ *s++ = '1';
+ k++;
+ goto ret;
+ }
+ if (leftright)
+ {
+ if (m2 > 0)
+ mhi = lshift (ptr, mhi, m2);
+
+ /* Single precision case, */
+ if (float_type)
+ mhi = lshift (ptr, mhi, 29);
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ mlo = mhi;
+ if (spec_case)
+ {
+ mhi = Balloc (ptr, mhi->_k);
+ Bcopy (mhi, mlo);
+ mhi = lshift (ptr, mhi, Log2P);
+ }
+
+ for (i = 1;; i++)
+ {
+ dig = quorem (b, S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp (b, mlo);
+ delta = diff (ptr, S, mhi);
+ j1 = delta->_sign ? 1 : cmp (b, delta);
+ Bfree (ptr, delta);
+#ifndef ROUND_BIASED
+ if (j1 == 0 && !mode && !(word1 (d) & 1))
+ {
+ if (dig == '9')
+ goto round_9_up;
+ if (j > 0)
+ dig++;
+ *s++ = dig;
+ goto ret;
+ }
+#endif
+ if (j < 0 || (j == 0 && !mode
+#ifndef ROUND_BIASED
+ && !(word1 (d) & 1)
+#endif
+ ))
+ {
+ if (j1 > 0)
+ {
+ b = lshift (ptr, b, 1);
+ j1 = cmp (b, S);
+ if ((j1 > 0 || (j1 == 0 && dig & 1))
+ && dig++ == '9')
+ goto round_9_up;
+ }
+ *s++ = dig;
+ goto ret;
+ }
+ if (j1 > 0)
+ {
+ if (dig == '9')
+ { /* possible if i == 1 */
+ round_9_up:
+ *s++ = '9';
+ goto roundoff;
+ }
+ *s++ = dig + 1;
+ goto ret;
+ }
+ *s++ = dig;
+ if (i == ilim)
+ break;
+ b = multadd (ptr, b, 10, 0);
+ if (mlo == mhi)
+ mlo = mhi = multadd (ptr, mhi, 10, 0);
+ else
+ {
+ mlo = multadd (ptr, mlo, 10, 0);
+ mhi = multadd (ptr, mhi, 10, 0);
+ }
+ }
+ }
+ else
+ for (i = 1;; i++)
+ {
+ *s++ = dig = quorem (b, S) + '0';
+ if (i >= ilim)
+ break;
+ b = multadd (ptr, b, 10, 0);
+ }
+
+ /* Round off last digit */
+
+ b = lshift (ptr, b, 1);
+ j = cmp (b, S);
+ if (j > 0 || (j == 0 && dig & 1))
+ {
+ roundoff:
+ while (*--s == '9')
+ if (s == s0)
+ {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ ++*s++;
+ }
+ else
+ {
+ while (*--s == '0');
+ s++;
+ }
+ret:
+ Bfree (ptr, S);
+ if (mhi)
+ {
+ if (mlo && mlo != mhi)
+ Bfree (ptr, mlo);
+ Bfree (ptr, mhi);
+ }
+ret1:
+ Bfree (ptr, b);
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+ return s0;
+}
+
+
+_VOID
+_DEFUN (_dtoa,
+ (_d, mode, ndigits, decpt, sign, rve, buf, float_type),
+ double _d _AND
+ int mode _AND
+ int ndigits _AND
+ int *decpt _AND
+ int *sign _AND
+ char **rve _AND
+ char *buf _AND
+ int float_type)
+{
+ struct _Jv_reent reent;
+ char *p;
+ memset (&reent, 0, sizeof reent);
+
+ p = _dtoa_r (&reent, _d, mode, ndigits, decpt, sign, rve, float_type);
+ strcpy (buf, p);
+
+ return;
+}
+
+
diff --git a/libjava/java/lang/e_acos.c b/libjava/java/lang/e_acos.c
new file mode 100644
index 00000000000..319b1d56fa0
--- /dev/null
+++ b/libjava/java/lang/e_acos.c
@@ -0,0 +1,111 @@
+
+/* @(#)e_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.
+ * ====================================================
+ */
+
+/* __ieee754_acos(x)
+ * 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))
+ * = 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
+ * for f so that f+c ~ sqrt(z).
+ * For x<-0.5
+ * acos(x) = pi - 2asin(sqrt((1-|x|)/2))
+ * = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN with invalid signal.
+ *
+ * Function needed: sqrt
+ */
+
+#include "fdlibm.h"
+
+#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 */
+pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+#ifdef __STDC__
+ double __ieee754_acos(double x)
+#else
+ double __ieee754_acos(x)
+ double x;
+#endif
+{
+ 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/libjava/java/lang/e_asin.c b/libjava/java/lang/e_asin.c
new file mode 100644
index 00000000000..559f2884a26
--- /dev/null
+++ b/libjava/java/lang/e_asin.c
@@ -0,0 +1,120 @@
+
+/* @(#)e_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.
+ * ====================================================
+ */
+
+/* __ieee754_asin(x)
+ * Method :
+ * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
+ * we approximate asin(x) on [0,0.5] by
+ * asin(x) = x + x*x^2*R(x^2)
+ * where
+ * R(x^2) is a rational approximation of (asin(x)-x)/x^3
+ * and its remez error is bounded by
+ * |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)
+ *
+ * For x in [0.5,1]
+ * asin(x) = pi/2-2*asin(sqrt((1-x)/2))
+ * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
+ * then for x>0.98
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
+ * For x<=0.98, let pio4_hi = pio2_hi/2, then
+ * f = hi part of s;
+ * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z)
+ * and
+ * asin(x) = pi/2 - 2*(s+s*z*R(z))
+ * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
+ * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
+ *
+ * Special cases:
+ * if x is NaN, return x itself;
+ * if |x|>1, return NaN with invalid signal.
+ *
+ */
+
+
+#include "fdlibm.h"
+
+#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 */
+pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+pio4_hi = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
+ /* coefficient for R(x^2) */
+pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+#ifdef __STDC__
+ double __ieee754_asin(double x)
+#else
+ double __ieee754_asin(x)
+ double x;
+#endif
+{
+ 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/libjava/java/lang/e_atan2.c b/libjava/java/lang/e_atan2.c
new file mode 100644
index 00000000000..8e9650f290d
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/e_exp.c b/libjava/java/lang/e_exp.c
new file mode 100644
index 00000000000..ce093c61065
--- /dev/null
+++ b/libjava/java/lang/e_exp.c
@@ -0,0 +1,167 @@
+
+/* @(#)e_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.
+ * ====================================================
+ */
+
+/* __ieee754_exp(x)
+ * Returns the exponential of x.
+ *
+ * Method
+ * 1. Argument reduction:
+ * 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.
+ *
+ * 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
+ * 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
+ * | |
+ * The computation of exp(r) thus becomes
+ * 2*r
+ * exp(r) = 1 + -------
+ * R - 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)
+ *
+ * Special cases:
+ * exp(INF) is INF, exp(NaN) is NaN;
+ * exp(-INF) is 0, and
+ * for finite argument, only exp(0)=1 is exact.
+ *
+ * Accuracy:
+ * according to an error analysis, the error is always less than
+ * 1 ulp (unit in the last place).
+ *
+ * Misc. info.
+ * 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
+ * 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
+one = 1.0,
+halF[2] = {0.5,-0.5,},
+huge = 1.0e+300,
+twom1000= 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/
+o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
+u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */
+ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */
+ -6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */
+ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */
+ -1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */
+invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
+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 */
+
+
+#ifdef __STDC__
+ double __ieee754_exp(double x) /* default IEEE double exp */
+#else
+ double __ieee754_exp(x) /* default IEEE double exp */
+ double x;
+#endif
+{
+ double y,hi,lo,c,t;
+ __int32_t k,xsb;
+ __uint32_t hx;
+
+ 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) {
+ __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;
+
+ /* 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/libjava/java/lang/e_fmod.c b/libjava/java/lang/e_fmod.c
new file mode 100644
index 00000000000..f9739eec25d
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/e_log.c b/libjava/java/lang/e_log.c
new file mode 100644
index 00000000000..ea6c55f6c36
--- /dev/null
+++ b/libjava/java/lang/e_log.c
@@ -0,0 +1,152 @@
+
+/* @(#)e_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.
+ * ====================================================
+ */
+
+/* __ieee754_log(x)
+ * Return the logrithm of x
+ *
+ * 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
+ * of this polynomial approximation is bounded by 2**-58.45. In
+ * other words,
+ * 2 4 6 8 10 12 14
+ * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s
+ * (the values of Lg1 to Lg7 are listed in the program)
+ * and
+ * | 2 14 | -58.45
+ * | 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).
+ * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
+ * 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(+INF) is +INF; log(0) is -INF with signal;
+ * log(NaN) is that NaN with no signal.
+ *
+ * Accuracy:
+ * according to an error analysis, the error is always less than
+ * 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
+ * to produce the hexadecimal values shown.
+ */
+
+#include "fdlibm.h"
+
+#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 */
+Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
+Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
+Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
+Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
+Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
+Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
+Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+#ifdef __STDC__
+ double __ieee754_log(double x)
+#else
+ double __ieee754_log(x)
+ double x;
+#endif
+{
+ double hfsq,f,s,z,R,w,t1,t2,dk;
+ __int32_t k,hx,i,j;
+ __uint32_t lx;
+
+ 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 */
+ 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/libjava/java/lang/e_pow.c b/libjava/java/lang/e_pow.c
new file mode 100644
index 00000000000..f078dff344d
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/e_rem_pio2.c b/libjava/java/lang/e_rem_pio2.c
new file mode 100644
index 00000000000..3e5d0f7a227
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/e_remainder.c b/libjava/java/lang/e_remainder.c
new file mode 100644
index 00000000000..ae7ce649ad5
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/e_scalb.c b/libjava/java/lang/e_scalb.c
new file mode 100644
index 00000000000..0bb924b43ee
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/e_sqrt.c b/libjava/java/lang/e_sqrt.c
new file mode 100644
index 00000000000..b56b1eedc94
--- /dev/null
+++ b/libjava/java/lang/e_sqrt.c
@@ -0,0 +1,452 @@
+
+/* @(#)e_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.
+ * ====================================================
+ */
+
+/* __ieee754_sqrt(x)
+ * Return correctly rounded sqrt.
+ * ------------------------------------------
+ * | Use the hardware sqrt if you have one |
+ * ------------------------------------------
+ * 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:
+ * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
+ * sqrt(x) = 2^k * sqrt(y)
+ * 2. Bit by bit computation
+ * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
+ * i 0
+ * 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
+ *
+ * -(i+1) 2
+ * (q + 2 ) <= y. (2)
+ * i
+ * -(i+1)
+ * If (2) is false, then q = q ; otherwise q = q + 2 .
+ * i+1 i i+1 i
+ *
+ * With some algebric manipulation, it is not difficult to see
+ * 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
+ * i i
+ * the following recurrence formula:
+ * if (3) is false
+ *
+ * s = s , y = y ; (4)
+ * i+1 i i+1 i
+ *
+ * otherwise,
+ * -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).
+ * Note. Since the left hand side of (3) contain only i+2 bits,
+ * 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.
+ * Together with the remainder, we can decide whether the
+ * result is exact, bigger than 1/2ulp, or less than 1/2ulp
+ * (it will never equal to 1/2ulp).
+ * 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
+ * sqrt(-ve) = NaN ... with invalid signal
+ * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
+ *
+ * Other methods : see the appended file at the end of the program below.
+ *---------------
+ */
+
+#include "fdlibm.h"
+
+#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
+
+#ifdef __STDC__
+ double __ieee754_sqrt(double x)
+#else
+ double __ieee754_sqrt(x)
+ double x;
+#endif
+{
+ 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
+and K.C. Ng, written in May, 1986)
+
+ 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,
+ and the INEXACT flag to indicate when an arithmetic operation
+ 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.
+
+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
+
+ 1 11 52 ...widths
+ ------------------------------------------------------
+ x: |s| e | f |
+ ------------------------------------------------------
+ msb lsb msb lsb ...order
+
+
+ ------------------------ ------------------------
+ x0: |s| e | f1 | x1: | f2 |
+ ------------------------ ------------------------
+
+ By performing shifts and subtracts on x0 and x1 (both regarded
+ as integers), we obtain an 8-bit approximation of sqrt(x) as
+ follows.
+
+ k := (x0>>1) + 0x1ff80000;
+ y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits
+ Here k is a 32-bit integer and T1[] 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 is 0)
+ approximates sqrt(x) to almost 8-bit.
+
+ Value of T1:
+ static int T1[32]= {
+ 0, 1024, 3062, 5746, 9193, 13348, 18162, 23592,
+ 29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215,
+ 83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581,
+ 16499, 12183, 8588, 5674, 3403, 1742, 661, 130,};
+
+ (2) Iterative refinement
+
+ 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
+ y := (y+x/y)/2 ... almost 35 sig. bits
+ y := y-(y-x/y)/2 ... within 1 ulp
+
+
+ Remark 1.
+ Another way to improve y to within 1 ulp is:
+
+ y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x)
+ y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x)
+
+ 2
+ (x-y )*y
+ y := y + 2* ---------- ...within 1 ulp
+ 2
+ 3y + x
+
+
+ This formula has one division fewer than the one above; however,
+ 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
+ reciproot algorithm given in section B.
+
+ (3) Final adjustment
+
+ 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
+ use the expression y+-ulp for the next representable floating
+ numbers (up and down) of y. Note that y+-ulp = either fixed
+ point y+-1, or multiply y by nextafter(1,+-inf) in chopped
+ mode.
+
+ I := FALSE; ... reset INEXACT flag I
+ R := RZ; ... set rounding mode to round-toward-zero
+ z := x/y; ... chopped quotient, possibly inexact
+ If(not I) then { ... if the quotient is exact
+ if(z=y) {
+ I := i; ... restore inexact flag
+ R := r; ... restore rounded mode
+ return sqrt(x):=y.
+ } else {
+ z := z - ulp; ... special rounding
+ }
+ }
+ i := TRUE; ... sqrt(x) is inexact
+ If (r=RN) then z=z+ulp ... rounded-to-nearest
+ If (r=RP) then { ... round-toward-+inf
+ y = y+ulp; z=z+ulp;
+ }
+ y := y+z; ... chopped sum
+ y0:=y0-0x00100000; ... y := y/2 is correctly rounded.
+ 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;
+ Square root of a negative number is NaN with invalid signal.
+
+
+B. sqrt(x) by Reciproot 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
+ (see section A). By performing shifs and subtracts on x0 and y0,
+ we obtain a 7.8-bit approximation of 1/sqrt(x) as follows.
+
+ 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
+ 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)
+ to almost 7.8-bit.
+
+ Value of T2:
+ static int T2[64]= {
+ 0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866,
+ 0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f,
+ 0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d,
+ 0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0,
+ 0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989,
+ 0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd,
+ 0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e,
+ 0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,};
+
+ (2) Iterative refinement
+
+ 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
+ -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)
+ ... special arrangement for better accuracy
+ z := x*y ... 29 bits to sqrt(x), with z*y<1
+ 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;
+ (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
+ 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
+ use the expression y+-ulp for the next representable floating
+ numbers (up and down) of y. Note that y+-ulp = either fixed
+ point y+-1, or multiply y by nextafter(1,+-inf) in chopped
+ mode.
+
+ R := RZ; ... set rounding mode to round-toward-zero
+ switch(r) {
+ case RN: ... round-to-nearest
+ if(x<= z*(z-ulp)...chopped) z = z - ulp; else
+ if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp;
+ break;
+ case RZ:case RM: ... round-to-zero or round-to--inf
+ R:=RP; ... reset rounding mod to round-to-+inf
+ if(x<z*z ... rounded up) z = z - ulp; else
+ if(x>=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp;
+ break;
+ case RP: ... round-to-+inf
+ if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else
+ if(x>z*z ...chopped) z = z+ulp;
+ break;
+ }
+
+ Remark 3. The above comparisons can be done in fixed point. For
+ example, to compare x and w=z*z chopped, it suffices to compare
+ x1 and w1 (the trailing parts of x and w), regarding them as
+ two's complement integers.
+
+ ...Is z an exact square root?
+ To determine whether z is an exact square root of x, let z1 be the
+ trailing part of z, and also let x0 and x1 be the leading and
+ trailing parts of x.
+
+ If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0
+ 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
+ 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
+ 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
+ True.
+
+ Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be
+ zero.
+
+ --------------------
+ z1: | f2 |
+ --------------------
+ bit 31 bit 0
+
+ Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd
+ or even of logb(x) have the following relations:
+
+ -------------------------------------------------
+ bit 27,26 of z1 bit 1,0 of x1 logb(x)
+ -------------------------------------------------
+ 00 00 odd and even
+ 01 01 even
+ 10 10 odd
+ 10 00 even
+ 11 01 even
+ -------------------------------------------------
+
+ (4) Special cases (see (4) of Section A).
+
+ */
diff --git a/libjava/java/lang/fdlibm.h b/libjava/java/lang/fdlibm.h
new file mode 100644
index 00000000000..3f72070cf81
--- /dev/null
+++ b/libjava/java/lang/fdlibm.h
@@ -0,0 +1,343 @@
+
+/* @(#)fdlibm.h 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.
+ * ====================================================
+ */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <config.h>
+#include <stdlib.h>
+
+/* CYGNUS LOCAL: Include files. */
+#include "ieeefp.h"
+
+/* CYGNUS LOCAL: Default to XOPEN_MODE. */
+#define _XOPEN_MODE
+
+#ifdef __STDC__
+#define __P(p) p
+#else
+#define __P(p) ()
+#endif
+
+#define HUGE ((float)3.40282346638528860e+38)
+
+/*
+ * 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. */
+
+#ifndef HAVE_INT32_DEFINED
+typedef int __int32_t;
+typedef unsigned int __uint32_t;
+#endif
+
+#define _IEEE_LIBM
+
+/*
+ * 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
+
diff --git a/libjava/java/lang/ieeefp.h b/libjava/java/lang/ieeefp.h
new file mode 100644
index 00000000000..931bafb7d1a
--- /dev/null
+++ b/libjava/java/lang/ieeefp.h
@@ -0,0 +1,103 @@
+#ifndef __IEEE_BIG_ENDIAN
+#ifndef __IEEE_LITTLE_ENDIAN
+
+#ifdef __arm__
+/* ARM always has big-endian words. Within those words the byte ordering
+ appears to be big or little endian. Newlib doesn't seem to care about
+ the byte ordering within words. */
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __hppa__
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#if defined (__sparc) || defined (__sparc__)
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#if defined(__m68k__) || defined(__mc68000__)
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#if defined (__H8300__) || defined (__H8300H__)
+#define __IEEE_BIG_ENDIAN
+#define __SMALL_BITFIELDS
+#define _DOUBLE_IS_32BITS
+#endif
+
+#ifdef __H8500__
+#define __IEEE_BIG_ENDIAN
+#define __SMALL_BITFIELDS
+#define _DOUBLE_IS_32BITS
+#endif
+
+#ifdef __sh__
+#ifdef __LITTLE_ENDIAN__
+#define __IEEE_LITTLE_ENDIAN
+#else
+#define __IEEE_BIG_ENDIAN
+#endif
+#ifdef __SH3E__
+#define _DOUBLE_IS_32BITS
+#endif
+#endif
+
+#ifdef _AM29K
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __i386__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#ifdef __i960__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#ifdef __MIPSEL__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+#ifdef __MIPSEB__
+#define __IEEE_BIG_ENDIAN
+#endif
+
+/* necv70 was __IEEE_LITTLE_ENDIAN. */
+
+#ifdef __W65__
+#define __IEEE_LITTLE_ENDIAN
+#define __SMALL_BITFIELDS
+#define _DOUBLE_IS_32BITS
+#endif
+
+#if defined(__Z8001__) || defined(__Z8002__)
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __m88k__
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __v800
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#ifdef __PPC__
+#if (defined(_BIG_ENDIAN) && _BIG_ENDIAN) || (defined(_AIX) && _AIX)
+#define __IEEE_BIG_ENDIAN
+#else
+#if (defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN) || (defined(__sun__) && __sun__) || (defined(__WIN32__) && __WIN32__)
+#define __IEEE_LITTLE_ENDIAN
+#endif
+#endif
+#endif
+
+#ifndef __IEEE_BIG_ENDIAN
+#ifndef __IEEE_LITTLE_ENDIAN
+#error Endianess not declared!!
+#endif /* not __IEEE_LITTLE_ENDIAN */
+#endif /* not __IEEE_BIG_ENDIAN */
+
+#endif /* not __IEEE_LITTLE_ENDIAN */
+#endif /* not __IEEE_BIG_ENDIAN */
+
diff --git a/libjava/java/lang/k_cos.c b/libjava/java/lang/k_cos.c
new file mode 100644
index 00000000000..6c60c243856
--- /dev/null
+++ b/libjava/java/lang/k_cos.c
@@ -0,0 +1,96 @@
+
+/* @(#)k_cos.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_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.
+ *
+ * Algorithm
+ * 1. Since cos(-x) = cos(x), we need only to consider positive x.
+ * 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
+ * 3. cos(x) is approximated by a polynomial of degree 14 on
+ * [0,pi/4]
+ * 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. 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
+ * ~ cos(x) - x*y,
+ * a correction term is necessary in cos(x) and hence
+ * cos(x+y) = 1 - (x*x/2 - (r - x*y))
+ * For better accuracy when x > 0.3, let qx = |x|/4 with
+ * the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125.
+ * Then
+ * cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)).
+ * Note that 1-qx and (x*x/2-qx) is EXACT here, and the
+ * magnitude of the latter is at least a quarter of x*x/2,
+ * thus, reducing the rounding error in the subtraction.
+ */
+
+#include "fdlibm.h"
+
+#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 */
+C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
+C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
+C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
+C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
+
+#ifdef __STDC__
+ double __kernel_cos(double x, double y)
+#else
+ double __kernel_cos(x, y)
+ double x,y;
+#endif
+{
+ 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));
+ }
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/libjava/java/lang/k_rem_pio2.c b/libjava/java/lang/k_rem_pio2.c
new file mode 100644
index 00000000000..8569256686c
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/k_sin.c b/libjava/java/lang/k_sin.c
new file mode 100644
index 00000000000..f119916dfbc
--- /dev/null
+++ b/libjava/java/lang/k_sin.c
@@ -0,0 +1,79 @@
+
+/* @(#)k_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.
+ * ====================================================
+ */
+
+/* __kernel_sin( x, y, iy)
+ * 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).
+ *
+ * Algorithm
+ * 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 |
+ *
+ * 4. sin(x+y) = sin(x) + sin'(x')*y
+ * ~ sin(x) + (1-x*x/2)*y
+ * For better accuracy, let
+ * 3 2 2 2 2
+ * r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
+ * then 3 2
+ * sin(x) = x + (S1*x + (x *(r-y/2)+y))
+ */
+
+#include "fdlibm.h"
+
+#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 */
+S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
+S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
+S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
+S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
+
+#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
+{
+ 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/libjava/java/lang/k_tan.c b/libjava/java/lang/k_tan.c
new file mode 100644
index 00000000000..9f5b307600c
--- /dev/null
+++ b/libjava/java/lang/k_tan.c
@@ -0,0 +1,132 @@
+
+/* @(#)k_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.
+ * ====================================================
+ */
+
+/* __kernel_tan( x, y, k )
+ * 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
+ * -1/tan (if k= -1) is returned.
+ *
+ * Algorithm
+ * 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 |
+ *
+ * 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
+ * 3 2 2 2 2
+ * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
+ * then
+ * 3 2
+ * tan(x+y) = x + (T1*x + (x *(r+y)+y))
+ *
+ * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then
+ * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
+ * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
+ */
+
+#include "fdlibm.h"
+
+#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 */
+T[] = {
+ 3.33333333333334091986e-01, /* 0x3FD55555, 0x55555563 */
+ 1.33333333333201242699e-01, /* 0x3FC11111, 0x1110FE7A */
+ 5.39682539762260521377e-02, /* 0x3FABA1BA, 0x1BB341FE */
+ 2.18694882948595424599e-02, /* 0x3F9664F4, 0x8406D637 */
+ 8.86323982359930005737e-03, /* 0x3F8226E3, 0xE96E8493 */
+ 3.59207910759131235356e-03, /* 0x3F6D6D22, 0xC9560328 */
+ 1.45620945432529025516e-03, /* 0x3F57DBC8, 0xFEE08315 */
+ 5.88041240820264096874e-04, /* 0x3F4344D8, 0xF2F26501 */
+ 2.46463134818469906812e-04, /* 0x3F3026F7, 0x1A8D1068 */
+ 7.81794442939557092300e-05, /* 0x3F147E88, 0xA03792A6 */
+ 7.14072491382608190305e-05, /* 0x3F12B80F, 0x32F0A7E9 */
+ -1.85586374855275456654e-05, /* 0xBEF375CB, 0xDB605373 */
+ 2.59073051863633712884e-05, /* 0x3EFB2A70, 0x74BF7AD4 */
+};
+
+#ifdef __STDC__
+ double __kernel_tan(double x, double y, int iy)
+#else
+ double __kernel_tan(x, y, iy)
+ double x,y; int iy;
+#endif
+{
+ 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 = (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 */
+ 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/libjava/java/lang/mprec.c b/libjava/java/lang/mprec.c
new file mode 100644
index 00000000000..12dd5d2617a
--- /dev/null
+++ b/libjava/java/lang/mprec.c
@@ -0,0 +1,958 @@
+/****************************************************************
+ *
+ * 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
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule. Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *
+ * 1. We only require IEEE, IBM, or VAX double-precision
+ * arithmetic (not IEEE double-extended).
+ * 2. We get by with floating-point arithmetic in a case that
+ * Clinger missed -- when we're computing d * 10^n
+ * for a small integer d and the integer n is not too
+ * much larger than 22 (the maximum integer k for which
+ * we can represent 10^k exactly), we may be able to
+ * compute (d*10^k) * 10^(e-k) with just one roundoff.
+ * 3. Rather than a bit-at-a-time adjustment of the binary
+ * result in the hard case, we use floating-point
+ * arithmetic to determine the adjustment to within
+ * one bit; only in really hard cases do we need to
+ * compute a second residual.
+ * 4. Because of 3., we don't need a large table of powers of 10
+ * for ten-to-e (just some small tables, e.g. of 10^k
+ * for 0 <= k <= 22).
+ */
+
+/*
+ * #define IEEE_8087 for IEEE-arithmetic machines where the least
+ * significant byte has the lowest address.
+ * #define IEEE_MC68k for IEEE-arithmetic machines where the most
+ * significant byte has the lowest address.
+ * #define Sudden_Underflow for IEEE-format machines without gradual
+ * underflow (i.e., that flush to zero on underflow).
+ * #define IBM for IBM mainframe-style floating-point arithmetic.
+ * #define VAX for VAX-style floating-point arithmetic.
+ * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
+ * #define No_leftright to omit left-right logic in fast floating-point
+ * computation of dtoa.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
+ * that use extended-precision instructions to compute rounded
+ * products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ * products but inaccurate quotients, e.g., for Intel i860.
+ * #define Just_16 to store 16 bits per 32-bit long when doing high-precision
+ * integer arithmetic. Whether this speeds things up or slows things
+ * down depends on the machine and the number being converted.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <java-assert.h>
+#include "mprec.h"
+
+/* reent.c knows this value */
+#define _Kmax 15
+#include <stdio.h>
+
+_Jv_Bigint *
+_DEFUN (Balloc, (ptr, k), struct _Jv_reent *ptr _AND int k)
+{
+ _Jv_Bigint *rv = NULL;
+
+ int i = 0;
+ int j = 1;
+
+ JvAssert ((1 << k) < MAX_BIGNUM_WDS);
+
+ while ((ptr->_allocation_map & j) && i < MAX_BIGNUMS)
+ i++, j <<= 1;
+
+ JvAssert (i < MAX_BIGNUMS);
+
+ if (i >= MAX_BIGNUMS)
+ return NULL;
+
+ ptr->_allocation_map |= j;
+ rv = &ptr->_freelist[i];
+
+ rv->_k = k;
+ rv->_maxwds = 32;
+
+ return rv;
+}
+
+
+void
+_DEFUN (Bfree, (ptr, v), struct _Jv_reent *ptr _AND _Jv_Bigint * v)
+{
+ long i;
+
+ i = v - ptr->_freelist;
+
+ JvAssert (i >= 0 && i < MAX_BIGNUMS);
+
+ if (i >= 0 && i < MAX_BIGNUMS)
+ ptr->_allocation_map &= ~ (1 << i);
+}
+
+
+_Jv_Bigint *
+_DEFUN (multadd, (ptr, b, m, a),
+ struct _Jv_reent *ptr _AND
+ _Jv_Bigint * b _AND
+ int m _AND
+ int a)
+{
+ int i, wds;
+ unsigned long *x, y;
+#ifdef Pack_32
+ unsigned long xi, z;
+#endif
+ _Jv_Bigint *b1;
+
+ wds = b->_wds;
+ x = b->_x;
+ i = 0;
+ do
+ {
+#ifdef Pack_32
+ xi = *x;
+ y = (xi & 0xffff) * m + a;
+ z = (xi >> 16) * m + (y >> 16);
+ a = (int) (z >> 16);
+ *x++ = (z << 16) + (y & 0xffff);
+#else
+ y = *x * m + a;
+ a = (int) (y >> 16);
+ *x++ = y & 0xffff;
+#endif
+ }
+ while (++i < wds);
+ if (a)
+ {
+ if (wds >= b->_maxwds)
+ {
+ b1 = Balloc (ptr, b->_k + 1);
+ Bcopy (b1, b);
+ Bfree (ptr, b);
+ b = b1;
+ }
+ b->_x[wds++] = a;
+ b->_wds = wds;
+ }
+ return b;
+}
+
+_Jv_Bigint *
+_DEFUN (s2b, (ptr, s, nd0, nd, y9),
+ struct _Jv_reent * ptr _AND
+ _CONST char *s _AND
+ int nd0 _AND
+ int nd _AND
+ unsigned long y9)
+{
+ _Jv_Bigint *b;
+ int i, k;
+ long x, y;
+
+ x = (nd + 8) / 9;
+ for (k = 0, y = 1; x > y; y <<= 1, k++);
+#ifdef Pack_32
+ b = Balloc (ptr, k);
+ b->_x[0] = y9;
+ b->_wds = 1;
+#else
+ b = Balloc (ptr, k + 1);
+ b->_x[0] = y9 & 0xffff;
+ b->_wds = (b->_x[1] = y9 >> 16) ? 2 : 1;
+#endif
+
+ i = 9;
+ if (9 < nd0)
+ {
+ s += 9;
+ do
+ b = multadd (ptr, b, 10, *s++ - '0');
+ while (++i < nd0);
+ s++;
+ }
+ else
+ s += 10;
+ for (; i < nd; i++)
+ b = multadd (ptr, b, 10, *s++ - '0');
+ return b;
+}
+
+int
+_DEFUN (hi0bits,
+ (x), register unsigned long x)
+{
+ register int k = 0;
+
+ if (!(x & 0xffff0000))
+ {
+ k = 16;
+ x <<= 16;
+ }
+ if (!(x & 0xff000000))
+ {
+ k += 8;
+ x <<= 8;
+ }
+ if (!(x & 0xf0000000))
+ {
+ k += 4;
+ x <<= 4;
+ }
+ if (!(x & 0xc0000000))
+ {
+ k += 2;
+ x <<= 2;
+ }
+ if (!(x & 0x80000000))
+ {
+ k++;
+ if (!(x & 0x40000000))
+ return 32;
+ }
+ return k;
+}
+
+int
+_DEFUN (lo0bits, (y), unsigned long *y)
+{
+ register int k;
+ register unsigned long x = *y;
+
+ if (x & 7)
+ {
+ if (x & 1)
+ return 0;
+ if (x & 2)
+ {
+ *y = x >> 1;
+ return 1;
+ }
+ *y = x >> 2;
+ return 2;
+ }
+ k = 0;
+ if (!(x & 0xffff))
+ {
+ k = 16;
+ x >>= 16;
+ }
+ if (!(x & 0xff))
+ {
+ k += 8;
+ x >>= 8;
+ }
+ if (!(x & 0xf))
+ {
+ k += 4;
+ x >>= 4;
+ }
+ if (!(x & 0x3))
+ {
+ k += 2;
+ x >>= 2;
+ }
+ if (!(x & 1))
+ {
+ k++;
+ x >>= 1;
+ if (!x & 1)
+ return 32;
+ }
+ *y = x;
+ return k;
+}
+
+_Jv_Bigint *
+_DEFUN (i2b, (ptr, i), struct _Jv_reent * ptr _AND int i)
+{
+ _Jv_Bigint *b;
+
+ b = Balloc (ptr, 1);
+ b->_x[0] = i;
+ b->_wds = 1;
+ return b;
+}
+
+_Jv_Bigint *
+_DEFUN (mult, (ptr, a, b), struct _Jv_reent * ptr _AND _Jv_Bigint * a _AND _Jv_Bigint * b)
+{
+ _Jv_Bigint *c;
+ int k, wa, wb, wc;
+ unsigned long carry, y, z;
+ unsigned long *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+#ifdef Pack_32
+ unsigned long z2;
+#endif
+
+ if (a->_wds < b->_wds)
+ {
+ c = a;
+ a = b;
+ b = c;
+ }
+ k = a->_k;
+ wa = a->_wds;
+ wb = b->_wds;
+ wc = wa + wb;
+ if (wc > a->_maxwds)
+ k++;
+ c = Balloc (ptr, k);
+ for (x = c->_x, xa = x + wc; x < xa; x++)
+ *x = 0;
+ xa = a->_x;
+ xae = xa + wa;
+ xb = b->_x;
+ xbe = xb + wb;
+ xc0 = c->_x;
+#ifdef Pack_32
+ for (; xb < xbe; xb++, xc0++)
+ {
+ if ((y = *xb & 0xffff))
+ {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do
+ {
+ z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+ carry = z >> 16;
+ z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+ carry = z2 >> 16;
+ Storeinc (xc, z2, z);
+ }
+ while (x < xae);
+ *xc = carry;
+ }
+ if ((y = *xb >> 16))
+ {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ z2 = *xc;
+ do
+ {
+ z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+ carry = z >> 16;
+ Storeinc (xc, z, z2);
+ z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+ carry = z2 >> 16;
+ }
+ while (x < xae);
+ *xc = z2;
+ }
+ }
+#else
+ for (; xb < xbe; xc0++)
+ {
+ if (y = *xb++)
+ {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do
+ {
+ z = *x++ * y + *xc + carry;
+ carry = z >> 16;
+ *xc++ = z & 0xffff;
+ }
+ while (x < xae);
+ *xc = carry;
+ }
+ }
+#endif
+ for (xc0 = c->_x, xc = xc0 + wc; wc > 0 && !*--xc; --wc);
+ c->_wds = wc;
+ return c;
+}
+
+_Jv_Bigint *
+_DEFUN (pow5mult,
+ (ptr, b, k), struct _Jv_reent * ptr _AND _Jv_Bigint * b _AND int k)
+{
+ _Jv_Bigint *b1, *p5, *p51;
+ int i;
+ static _CONST int p05[3] = {5, 25, 125};
+
+ if ((i = k & 3))
+ b = multadd (ptr, b, p05[i - 1], 0);
+
+ if (!(k >>= 2))
+ return b;
+ if (!(p5 = ptr->_p5s))
+ {
+ /* first time */
+ p5 = ptr->_p5s = i2b (ptr, 625);
+ p5->_next = 0;
+ }
+ for (;;)
+ {
+ if (k & 1)
+ {
+ b1 = mult (ptr, b, p5);
+ Bfree (ptr, b);
+ b = b1;
+ }
+ if (!(k >>= 1))
+ break;
+ if (!(p51 = p5->_next))
+ {
+ p51 = p5->_next = mult (ptr, p5, p5);
+ p51->_next = 0;
+ }
+ p5 = p51;
+ }
+ return b;
+}
+
+_Jv_Bigint *
+_DEFUN (lshift, (ptr, b, k), struct _Jv_reent * ptr _AND _Jv_Bigint * b _AND int k)
+{
+ int i, k1, n, n1;
+ _Jv_Bigint *b1;
+ unsigned long *x, *x1, *xe, z;
+
+#ifdef Pack_32
+ n = k >> 5;
+#else
+ n = k >> 4;
+#endif
+ k1 = b->_k;
+ n1 = n + b->_wds + 1;
+ for (i = b->_maxwds; n1 > i; i <<= 1)
+ k1++;
+ b1 = Balloc (ptr, k1);
+ x1 = b1->_x;
+ for (i = 0; i < n; i++)
+ *x1++ = 0;
+ x = b->_x;
+ xe = x + b->_wds;
+#ifdef Pack_32
+ if (k &= 0x1f)
+ {
+ k1 = 32 - k;
+ z = 0;
+ do
+ {
+ *x1++ = *x << k | z;
+ z = *x++ >> k1;
+ }
+ while (x < xe);
+ if ((*x1 = z))
+ ++n1;
+ }
+#else
+ if (k &= 0xf)
+ {
+ k1 = 16 - k;
+ z = 0;
+ do
+ {
+ *x1++ = *x << k & 0xffff | z;
+ z = *x++ >> k1;
+ }
+ while (x < xe);
+ if (*x1 = z)
+ ++n1;
+ }
+#endif
+ else
+ do
+ *x1++ = *x++;
+ while (x < xe);
+ b1->_wds = n1 - 1;
+ Bfree (ptr, b);
+ return b1;
+}
+
+int
+_DEFUN (cmp, (a, b), _Jv_Bigint * a _AND _Jv_Bigint * b)
+{
+ unsigned long *xa, *xa0, *xb, *xb0;
+ int i, j;
+
+ i = a->_wds;
+ j = b->_wds;
+#ifdef DEBUG
+ if (i > 1 && !a->_x[i - 1])
+ Bug ("cmp called with a->_x[a->_wds-1] == 0");
+ if (j > 1 && !b->_x[j - 1])
+ Bug ("cmp called with b->_x[b->_wds-1] == 0");
+#endif
+ if (i -= j)
+ return i;
+ xa0 = a->_x;
+ xa = xa0 + j;
+ xb0 = b->_x;
+ xb = xb0 + j;
+ for (;;)
+ {
+ if (*--xa != *--xb)
+ return *xa < *xb ? -1 : 1;
+ if (xa <= xa0)
+ break;
+ }
+ return 0;
+}
+
+_Jv_Bigint *
+_DEFUN (diff, (ptr, a, b), struct _Jv_reent * ptr _AND
+ _Jv_Bigint * a _AND _Jv_Bigint * b)
+{
+ _Jv_Bigint *c;
+ int i, wa, wb;
+ long borrow, y; /* We need signed shifts here. */
+ unsigned long *xa, *xae, *xb, *xbe, *xc;
+#ifdef Pack_32
+ long z;
+#endif
+
+ i = cmp (a, b);
+ if (!i)
+ {
+ c = Balloc (ptr, 0);
+ c->_wds = 1;
+ c->_x[0] = 0;
+ return c;
+ }
+ if (i < 0)
+ {
+ c = a;
+ a = b;
+ b = c;
+ i = 1;
+ }
+ else
+ i = 0;
+ c = Balloc (ptr, a->_k);
+ c->_sign = i;
+ wa = a->_wds;
+ xa = a->_x;
+ xae = xa + wa;
+ wb = b->_wds;
+ xb = b->_x;
+ xbe = xb + wb;
+ xc = c->_x;
+ borrow = 0;
+#ifdef Pack_32
+ do
+ {
+ y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend (borrow, z);
+ Storeinc (xc, z, y);
+ }
+ while (xb < xbe);
+ while (xa < xae)
+ {
+ y = (*xa & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ z = (*xa++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend (borrow, z);
+ Storeinc (xc, z, y);
+ }
+#else
+ do
+ {
+ y = *xa++ - *xb++ + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ *xc++ = y & 0xffff;
+ }
+ while (xb < xbe);
+ while (xa < xae)
+ {
+ y = *xa++ + borrow;
+ borrow = y >> 16;
+ Sign_Extend (borrow, y);
+ *xc++ = y & 0xffff;
+ }
+#endif
+ while (!*--xc)
+ wa--;
+ c->_wds = wa;
+ return c;
+}
+
+double
+_DEFUN (ulp, (_x), double _x)
+{
+ union double_union x, a;
+ register long L;
+
+ x.d = _x;
+
+ L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
+#ifndef Sudden_Underflow
+ if (L > 0)
+ {
+#endif
+#ifdef IBM
+ L |= Exp_msk1 >> 4;
+#endif
+ word0 (a) = L;
+#ifndef _DOUBLE_IS_32BITS
+ word1 (a) = 0;
+#endif
+
+#ifndef Sudden_Underflow
+ }
+ else
+ {
+ L = -L >> Exp_shift;
+ if (L < Exp_shift)
+ {
+ word0 (a) = 0x80000 >> L;
+#ifndef _DOUBLE_IS_32BITS
+ word1 (a) = 0;
+#endif
+ }
+ else
+ {
+ word0 (a) = 0;
+ L -= Exp_shift;
+#ifndef _DOUBLE_IS_32BITS
+ word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+#endif
+ }
+ }
+#endif
+ return a.d;
+}
+
+double
+_DEFUN (b2d, (a, e),
+ _Jv_Bigint * a _AND int *e)
+{
+ unsigned long *xa, *xa0, w, y, z;
+ int k;
+ union double_union d;
+#ifdef VAX
+ unsigned long d0, d1;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+ xa0 = a->_x;
+ xa = xa0 + a->_wds;
+ y = *--xa;
+#ifdef DEBUG
+ if (!y)
+ Bug ("zero y in b2d");
+#endif
+ k = hi0bits (y);
+ *e = 32 - k;
+#ifdef Pack_32
+ if (k < Ebits)
+ {
+ d0 = Exp_1 | y >> (Ebits - k);
+ w = xa > xa0 ? *--xa : 0;
+#ifndef _DOUBLE_IS_32BITS
+ d1 = y << (32 - Ebits + k) | w >> (Ebits - k);
+#endif
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ if (k -= Ebits)
+ {
+ d0 = Exp_1 | y << k | z >> (32 - k);
+ y = xa > xa0 ? *--xa : 0;
+#ifndef _DOUBLE_IS_32BITS
+ d1 = z << k | y >> (32 - k);
+#endif
+ }
+ else
+ {
+ d0 = Exp_1 | y;
+#ifndef _DOUBLE_IS_32BITS
+ d1 = z;
+#endif
+ }
+#else
+ if (k < Ebits + 16)
+ {
+ z = xa > xa0 ? *--xa : 0;
+ d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
+ w = xa > xa0 ? *--xa : 0;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ w = xa > xa0 ? *--xa : 0;
+ k -= Ebits + 16;
+ d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
+ y = xa > xa0 ? *--xa : 0;
+ d1 = w << k + 16 | y << k;
+#endif
+ret_d:
+#ifdef VAX
+ word0 (d) = d0 >> 16 | d0 << 16;
+ word1 (d) = d1 >> 16 | d1 << 16;
+#else
+#undef d0
+#undef d1
+#endif
+ return d.d;
+}
+
+_Jv_Bigint *
+_DEFUN (d2b,
+ (ptr, _d, e, bits),
+ struct _Jv_reent * ptr _AND
+ double _d _AND
+ int *e _AND
+ int *bits)
+
+{
+ union double_union d;
+ _Jv_Bigint *b;
+ int de, i, k;
+ unsigned long *x, y, z;
+#ifdef VAX
+ unsigned long d0, d1;
+ d.d = _d;
+ d0 = word0 (d) >> 16 | word0 (d) << 16;
+ d1 = word1 (d) >> 16 | word1 (d) << 16;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+ d.d = _d;
+#endif
+
+#ifdef Pack_32
+ b = Balloc (ptr, 1);
+#else
+ b = Balloc (ptr, 2);
+#endif
+ x = b->_x;
+
+ z = d0 & Frac_mask;
+ d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
+#ifdef Sudden_Underflow
+ de = (int) (d0 >> Exp_shift);
+#ifndef IBM
+ z |= Exp_msk11;
+#endif
+#else
+ if ((de = (int) (d0 >> Exp_shift)))
+ z |= Exp_msk1;
+#endif
+#ifdef Pack_32
+#ifndef _DOUBLE_IS_32BITS
+ if ((y = d1))
+ {
+ if ((k = lo0bits (&y)))
+ {
+ x[0] = y | z << (32 - k);
+ z >>= k;
+ }
+ else
+ x[0] = y;
+ i = b->_wds = (x[1] = z) ? 2 : 1;
+ }
+ else
+#endif
+ {
+#ifdef DEBUG
+ if (!z)
+ Bug ("Zero passed to d2b");
+#endif
+ k = lo0bits (&z);
+ x[0] = z;
+ i = b->_wds = 1;
+#ifndef _DOUBLE_IS_32BITS
+ k += 32;
+#endif
+ }
+#else
+ if (y = d1)
+ {
+ if (k = lo0bits (&y))
+ if (k >= 16)
+ {
+ x[0] = y | z << 32 - k & 0xffff;
+ x[1] = z >> k - 16 & 0xffff;
+ x[2] = z >> k;
+ i = 2;
+ }
+ else
+ {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16 | z << 16 - k & 0xffff;
+ x[2] = z >> k & 0xffff;
+ x[3] = z >> k + 16;
+ i = 3;
+ }
+ else
+ {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16;
+ x[2] = z & 0xffff;
+ x[3] = z >> 16;
+ i = 3;
+ }
+ }
+ else
+ {
+#ifdef DEBUG
+ if (!z)
+ Bug ("Zero passed to d2b");
+#endif
+ k = lo0bits (&z);
+ if (k >= 16)
+ {
+ x[0] = z;
+ i = 0;
+ }
+ else
+ {
+ x[0] = z & 0xffff;
+ x[1] = z >> 16;
+ i = 1;
+ }
+ k += 32;
+ }
+ while (!x[i])
+ --i;
+ b->_wds = i + 1;
+#endif
+#ifndef Sudden_Underflow
+ if (de)
+ {
+#endif
+#ifdef IBM
+ *e = (de - Bias - (P - 1) << 2) + k;
+ *bits = 4 * P + 8 - k - hi0bits (word0 (d) & Frac_mask);
+#else
+ *e = de - Bias - (P - 1) + k;
+ *bits = P - k;
+#endif
+#ifndef Sudden_Underflow
+ }
+ else
+ {
+ *e = de - Bias - (P - 1) + 1 + k;
+#ifdef Pack_32
+ *bits = 32 * i - hi0bits (x[i - 1]);
+#else
+ *bits = (i + 2) * 16 - hi0bits (x[i]);
+#endif
+ }
+#endif
+ return b;
+}
+#undef d0
+#undef d1
+
+double
+_DEFUN (ratio, (a, b), _Jv_Bigint * a _AND _Jv_Bigint * b)
+
+{
+ union double_union da, db;
+ int k, ka, kb;
+
+ da.d = b2d (a, &ka);
+ db.d = b2d (b, &kb);
+#ifdef Pack_32
+ k = ka - kb + 32 * (a->_wds - b->_wds);
+#else
+ k = ka - kb + 16 * (a->_wds - b->_wds);
+#endif
+#ifdef IBM
+ if (k > 0)
+ {
+ word0 (da) += (k >> 2) * Exp_msk1;
+ if (k &= 3)
+ da.d *= 1 << k;
+ }
+ else
+ {
+ k = -k;
+ word0 (db) += (k >> 2) * Exp_msk1;
+ if (k &= 3)
+ db.d *= 1 << k;
+ }
+#else
+ if (k > 0)
+ word0 (da) += k * Exp_msk1;
+ else
+ {
+ k = -k;
+ word0 (db) += k * Exp_msk1;
+ }
+#endif
+ return da.d / db.d;
+}
+
+
+_CONST double
+ tens[] =
+{
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22, 1e23, 1e24
+
+};
+
+#if !defined(_DOUBLE_IS_32BITS) && !defined(__v800)
+_CONST double bigtens[] =
+{1e16, 1e32, 1e64, 1e128, 1e256};
+
+_CONST double tinytens[] =
+{1e-16, 1e-32, 1e-64, 1e-128, 1e-256};
+#else
+_CONST double bigtens[] =
+{1e16, 1e32};
+
+_CONST double tinytens[] =
+{1e-16, 1e-32};
+#endif
+
+
diff --git a/libjava/java/lang/mprec.h b/libjava/java/lang/mprec.h
new file mode 100644
index 00000000000..192243157df
--- /dev/null
+++ b/libjava/java/lang/mprec.h
@@ -0,0 +1,374 @@
+/****************************************************************
+ *
+ * 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
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <config.h>
+#include "ieeefp.h"
+
+#include <math.h>
+// #include <float.h>
+// #include <errno.h>
+
+/* These typedefs are true for the targets running Java. */
+
+#ifndef HAVE_INT32_DEFINED
+typedef int __int32_t;
+typedef unsigned int __uint32_t;
+#endif
+
+#ifdef __IEEE_LITTLE_ENDIAN
+#define IEEE_8087
+#endif
+
+#ifdef __IEEE_BIG_ENDIAN
+#define IEEE_MC68k
+#endif
+
+#ifdef __Z8000__
+#define Just_16
+#endif
+
+#ifdef DEBUG
+#include "stdio.h"
+#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+#endif
+
+
+#ifdef Unsigned_Shifts
+#define Sign_Extend(a,b) if (b < 0) a |= (__uint32_t)0xffff0000;
+#else
+#define Sign_Extend(a,b) /*no-op*/
+#endif
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
+Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
+#endif
+
+/* If we are going to examine or modify specific bits in a double using
+ the word0 and/or word1 macros, then we must wrap the double inside
+ a union. This is necessary to avoid undefined behavior according to
+ the ANSI C spec. */
+union double_union
+{
+ double d;
+ // FIXME: This should be some well-defined 32 bit type.
+ __uint32_t i[2];
+};
+
+#ifdef IEEE_8087
+#define word0(x) (x.i[1])
+#define word1(x) (x.i[0])
+#else
+#define word0(x) (x.i[0])
+#define word1(x) (x.i[1])
+#endif
+
+/* The following definition of Storeinc is appropriate for MIPS processors.
+ * An alternative that might be better on some machines is
+ * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+ */
+#if defined(IEEE_8087) + defined(VAX)
+#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
+((unsigned short *)a)[0] = (unsigned short)c, a++)
+#else
+#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
+((unsigned short *)a)[1] = (unsigned short)c, a++)
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k)
+#if defined (_DOUBLE_IS_32BITS)
+#define Exp_shift 23
+#define Exp_shift1 23
+#define Exp_msk1 ((__uint32_t)0x00800000L)
+#define Exp_msk11 ((__uint32_t)0x00800000L)
+#define Exp_mask ((__uint32_t)0x7f800000L)
+#define P 24
+#define Bias 127
+#if 0
+#define IEEE_Arith /* it is, but the code doesn't handle IEEE singles yet */
+#endif
+#define Emin (-126)
+#define Exp_1 ((__uint32_t)0x3f800000L)
+#define Exp_11 ((__uint32_t)0x3f800000L)
+#define Ebits 8
+#define Frac_mask ((__uint32_t)0x007fffffL)
+#define Frac_mask1 ((__uint32_t)0x007fffffL)
+#define Ten_pmax 10
+#define Sign_bit ((__uint32_t)0x80000000L)
+#define Ten_pmax 10
+#define Bletch 2
+#define Bndry_mask ((__uint32_t)0x007fffffL)
+#define Bndry_mask1 ((__uint32_t)0x007fffffL)
+#define LSB 1
+#define Sign_bit ((__uint32_t)0x80000000L)
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 5
+#define Int_max 6
+#define Infinite(x) (word0(x) == ((__uint32_t)0x7f800000L))
+#undef word0
+#undef word1
+
+#define word0(x) (x.i[0])
+#define word1(x) 0
+#else
+
+#define Exp_shift 20
+#define Exp_shift1 20
+#define Exp_msk1 ((__uint32_t)0x100000L)
+#define Exp_msk11 ((__uint32_t)0x100000L)
+#define Exp_mask ((__uint32_t)0x7ff00000L)
+#define P 53
+#define Bias 1023
+#define IEEE_Arith
+#define Emin (-1022)
+#define Exp_1 ((__uint32_t)0x3ff00000L)
+#define Exp_11 ((__uint32_t)0x3ff00000L)
+#define Ebits 11
+#define Frac_mask ((__uint32_t)0xfffffL)
+#define Frac_mask1 ((__uint32_t)0xfffffL)
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask ((__uint32_t)0xfffffL)
+#define Bndry_mask1 ((__uint32_t)0xfffffL)
+#define LSB 1
+#define Sign_bit ((__uint32_t)0x80000000L)
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+#define Infinite(x) (word0(x) == ((__uint32_t)0x7ff00000L)) /* sufficient test for here */
+#endif
+
+#else
+#undef Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#define Exp_shift 24
+#define Exp_shift1 24
+#define Exp_msk1 ((__uint32_t)0x1000000L)
+#define Exp_msk11 ((__uint32_t)0x1000000L)
+#define Exp_mask ((__uint32_t)0x7f000000L)
+#define P 14
+#define Bias 65
+#define Exp_1 ((__uint32_t)0x41000000L)
+#define Exp_11 ((__uint32_t)0x41000000L)
+#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask ((__uint32_t)0xffffffL)
+#define Frac_mask1 ((__uint32_t)0xffffffL)
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask ((__uint32_t)0xefffffL)
+#define Bndry_mask1 ((__uint32_t)0xffffffL)
+#define LSB 1
+#define Sign_bit ((__uint32_t)0x80000000L)
+#define Log2P 4
+#define Tiny0 ((__uint32_t)0x100000L)
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#define Exp_shift 23
+#define Exp_shift1 7
+#define Exp_msk1 0x80
+#define Exp_msk11 ((__uint32_t)0x800000L)
+#define Exp_mask ((__uint32_t)0x7f80L)
+#define P 56
+#define Bias 129
+#define Exp_1 ((__uint32_t)0x40800000L)
+#define Exp_11 ((__uint32_t)0x4080L)
+#define Ebits 8
+#define Frac_mask ((__uint32_t)0x7fffffL)
+#define Frac_mask1 ((__uint32_t)0xffff007fL)
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask ((__uint32_t)0xffff007fL)
+#define Bndry_mask1 ((__uint32_t)0xffff007fL)
+#define LSB ((__uint32_t)0x10000L)
+#define Sign_bit ((__uint32_t)0x8000L)
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif
+#endif
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#endif
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+#ifdef KR_headers
+extern double rnd_prod(), rnd_quot();
+#else
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#endif
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 ((__uint32_t)0xffffffffL)
+
+#ifndef Just_16
+/* When Pack_32 is not defined, we store 16 bits per 32-bit long.
+ * This makes some inner loops simpler and sometimes saves work
+ * during multiplications, but it often seems to make things slightly
+ * slower. Hence the default is now to store 32 bits per long.
+ */
+
+#ifndef Pack_32
+#define Pack_32
+#endif
+#endif
+
+
+#define MAX_BIGNUMS 16
+#define MAX_BIGNUM_WDS 32
+
+struct _Jv_Bigint
+{
+ struct _Jv_Bigint *_next;
+ int _k, _maxwds, _sign, _wds;
+ unsigned long _x[MAX_BIGNUM_WDS];
+};
+
+
+#define _PTR void *
+#define _AND ,
+#define _NOARGS void
+#define _CONST const
+#define _VOLATILE volatile
+#define _SIGNED signed
+#define _DOTS , ...
+#define _VOID void
+#define _EXFUN(name, proto) name proto
+#define _DEFUN(name, arglist, args) name(args)
+#define _DEFUN_VOID(name) name(_NOARGS)
+#define _CAST_VOID (void)
+
+
+struct _Jv_reent
+{
+ /* local copy of errno */
+ int _errno;
+
+ /* used by mprec routines */
+ struct _Jv_Bigint *_result;
+ int _result_k;
+ struct _Jv_Bigint *_p5s;
+
+ struct _Jv_Bigint _freelist[MAX_BIGNUMS];
+ int _allocation_map;
+
+ int num;
+};
+
+
+typedef struct _Jv_Bigint _Jv_Bigint;
+
+#define Balloc _Jv_Balloc
+#define Bfree _Jv_Bfree
+#define multadd _Jv_multadd
+#define s2b _Jv_s2b
+#define lo0bits _Jv_lo0bits
+#define hi0bits _Jv_hi0bits
+#define i2b _Jv_i2b
+#define mult _Jv_mult
+#define pow5mult _Jv_pow5mult
+#define lshift _Jv_lshift
+#define cmp _Jv__mcmp
+#define diff _Jv__mdiff
+#define ulp _Jv_ulp
+#define b2d _Jv_b2d
+#define d2b _Jv_d2b
+#define ratio _Jv_ratio
+
+#define tens _Jv__mprec_tens
+#define bigtens _Jv__mprec_bigtens
+#define tinytens _Jv__mprec_tinytens
+
+#define _dtoa _Jv_dtoa
+#define _dtoa_r _Jv_dtoa_r
+#define _strtod_r _Jv_strtod_r
+
+extern double _EXFUN(_strtod_r, (struct _Jv_reent *ptr, const char *s00, char **se));
+extern char* _EXFUN(_dtoa_r, (struct _Jv_reent *ptr, double d,
+ int mode, int ndigits, int *decpt, int *sign,
+ char **rve, int float_type));
+void _EXFUN(_dtoa, (double d, int mode, int ndigits, int *decpt, int *sign,
+ char **rve, char *buf, int float_type));
+
+double _EXFUN(ulp,(double x));
+double _EXFUN(b2d,(_Jv_Bigint *a , int *e));
+_Jv_Bigint * _EXFUN(Balloc,(struct _Jv_reent *p, int k));
+void _EXFUN(Bfree,(struct _Jv_reent *p, _Jv_Bigint *v));
+_Jv_Bigint * _EXFUN(multadd,(struct _Jv_reent *p, _Jv_Bigint *, int, int));
+_Jv_Bigint * _EXFUN(s2b,(struct _Jv_reent *, const char*, int, int, unsigned long));
+_Jv_Bigint * _EXFUN(i2b,(struct _Jv_reent *,int));
+_Jv_Bigint * _EXFUN(mult, (struct _Jv_reent *, _Jv_Bigint *, _Jv_Bigint *));
+_Jv_Bigint * _EXFUN(pow5mult, (struct _Jv_reent *, _Jv_Bigint *, int k));
+int _EXFUN(hi0bits,(unsigned long));
+int _EXFUN(lo0bits,(unsigned long *));
+_Jv_Bigint * _EXFUN(d2b,(struct _Jv_reent *p, double d, int *e, int *bits));
+_Jv_Bigint * _EXFUN(lshift,(struct _Jv_reent *p, _Jv_Bigint *b, int k));
+_Jv_Bigint * _EXFUN(diff,(struct _Jv_reent *p, _Jv_Bigint *a, _Jv_Bigint *b));
+int _EXFUN(cmp,(_Jv_Bigint *a, _Jv_Bigint *b));
+
+double _EXFUN(ratio,(_Jv_Bigint *a, _Jv_Bigint *b));
+#define Bcopy(x,y) memcpy((char *)&x->_sign, (char *)&y->_sign, y->_wds*sizeof(long) + 2*sizeof(int))
+
+#if defined(_DOUBLE_IS_32BITS) && defined(__v800)
+#define n_bigtens 2
+#else
+#define n_bigtens 5
+#endif
+
+extern _CONST double tinytens[];
+extern _CONST double bigtens[];
+extern _CONST double tens[];
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/libjava/java/lang/natCharacter.cc b/libjava/java/lang/natCharacter.cc
new file mode 100644
index 00000000000..36cf5700fe5
--- /dev/null
+++ b/libjava/java/lang/natCharacter.cc
@@ -0,0 +1,269 @@
+// natCharacter.cc - Native part of Character class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <cni.h>
+#include <jvm.h>
+#include <java/lang/Character.h>
+
+#include <java-chartables.h>
+
+
+
+#define asize(x) ((sizeof (x)) / sizeof (x[0]))
+
+static jchar
+to_lower_title (jchar ch)
+{
+ for (unsigned int i = 0; i < asize (title_to_upper_table); ++i)
+ {
+ // We can assume that the entries in the two tables are
+ // parallel. This is checked in the script.
+ if (title_to_upper_table[i][1] == ch
+ || title_to_upper_table[i][0] == ch)
+ return title_to_lower_table[i][1];
+ }
+ return ch;
+}
+
+static jchar
+to_upper_title (jchar ch)
+{
+ for (unsigned int i = 0; i < asize (title_to_lower_table); ++i)
+ {
+ // We can assume that the entries in the two tables are
+ // parallel. This is checked in the script.
+ if (title_to_lower_table[i][1] == ch
+ || title_to_lower_table[i][0] == ch)
+ return title_to_upper_table[i][1];
+ }
+ return ch;
+}
+
+jboolean
+java::lang::Character::isTitleCase (jchar ch)
+{
+ for (unsigned int i = 0; i < asize (title_to_lower_table); ++i)
+ {
+ if (title_to_lower_table[i][0] == ch)
+ return true;
+ }
+ return false;
+}
+
+jchar
+java::lang::Character::toTitleCase (jchar ch)
+{
+ // Both titlecase mapping tables have the same length. This is
+ // checked in the chartables script.
+ for (unsigned int i = 0; i < asize (title_to_lower_table); ++i)
+ {
+ if (title_to_lower_table[i][0] == ch)
+ return ch;
+ if (title_to_lower_table[i][1] == ch)
+ return title_to_lower_table[i][0];
+ if (title_to_upper_table[i][1] == ch)
+ return title_to_upper_table[i][0];
+ }
+ return toUpperCase (ch);
+}
+
+#ifdef COMPACT_CHARACTER
+
+static int
+table_search (const jchar table[][2], int table_len, jchar ch)
+{
+ int low, high, i, old;
+
+ low = 0;
+ high = table_len;
+ i = high / 2;
+
+ while (true)
+ {
+ if (ch < table[i][0])
+ high = i;
+ else if (ch > table[i][1])
+ low = i;
+ else
+ return i;
+
+ old = i;
+ i = (high + low) / 2;
+ if (i == old)
+ break;
+ }
+
+ return -1;
+}
+
+jint
+java::lang::Character::digit_value (jchar ch)
+{
+ int index = table_search (digit_table, asize (digit_table), ch);
+ if (index == -1)
+ return -1;
+
+ jchar base = digit_table[index][0];
+ // Tamil doesn't have a digit `0'. So we special-case it here.
+ if (base == TAMIL_DIGIT_ONE)
+ return ch - base + 1;
+ return ch - base;
+}
+
+jint
+java::lang::Character::getNumericValue (jchar ch)
+{
+ jint d = digit (ch, 36);
+ if (d != -1)
+ return d;
+
+ for (unsigned int i = 0; i < asize (numeric_table); ++i)
+ {
+ if (numeric_table[i] == ch)
+ return numeric_value[i];
+ }
+
+ return -1;
+}
+
+jint
+java::lang::Character::getType (jchar ch)
+{
+ int index = table_search (all_table, asize (all_table), ch);
+ if (index != -1)
+ return category_table[index];
+ return UNASSIGNED;
+}
+
+jboolean
+java::lang::Character::isLowerCase (jchar ch)
+{
+ if (ch >= 0x2000 && ch <= 0x2fff)
+ return false;
+ if (table_search (lower_case_table, asize (lower_case_table), ch) != -1)
+ return true;
+
+ // FIXME: use a binary search.
+ for (unsigned int i = 0; i < asize (lower_anomalous_table); ++i)
+ {
+ if (lower_anomalous_table[i] == ch)
+ return true;
+ }
+ return false;
+}
+
+jboolean
+java::lang::Character::isSpaceChar (jchar ch)
+{
+ return table_search (space_table, asize (space_table), ch) != -1;
+}
+
+jboolean
+java::lang::Character::isUpperCase (jchar ch)
+{
+ if (ch >= 0x2000 && ch <= 0x2fff)
+ return false;
+ return table_search (upper_case_table, asize (upper_case_table), ch) != -1;
+}
+
+jchar
+java::lang::Character::toLowerCase (jchar ch)
+{
+ int index = table_search (upper_case_table, asize (upper_case_table), ch);
+ if (index == -1)
+ return to_lower_title (ch);
+ return (jchar) (ch - upper_case_table[index][0]
+ + upper_case_map_table[index]);
+}
+
+jchar
+java::lang::Character::toUpperCase (jchar ch)
+{
+ int index = table_search (lower_case_table, asize (lower_case_table), ch);
+ if (index == -1)
+ return to_upper_title (ch);
+ return (jchar) (ch - lower_case_table[index][0]
+ + lower_case_map_table[index]);
+}
+
+#else /* COMPACT_CHARACTER */
+
+jint
+java::lang::Character::digit_value (jchar ch)
+{
+ if (type_table[ch] == DECIMAL_DIGIT_NUMBER)
+ return attribute_table[ch];
+ return -1;
+}
+
+jint
+java::lang::Character::getNumericValue (jchar ch)
+{
+ jint d = digit (ch, 36);
+ if (d != -1)
+ return d;
+
+ // Some characters require two attributes. We special-case them here.
+ if (ch >= ROMAN_START && ch <= ROMAN_END)
+ return secondary_attribute_table[ch - ROMAN_START];
+ if (type_table[ch] == LETTER_NUMBER || type_table[ch] == OTHER_NUMBER)
+ return attribute_table[ch];
+ return -1;
+}
+
+jint
+java::lang::Character::getType (jchar ch)
+{
+ return type_table[ch];
+}
+
+jboolean
+java::lang::Character::isLowerCase (jchar ch)
+{
+ if (ch >= 0x2000 && ch <= 0x2fff)
+ return false;
+ return type_table[ch] == LOWERCASE_LETTER;
+}
+
+jboolean
+java::lang::Character::isSpaceChar (jchar ch)
+{
+ return (type_table[ch] == SPACE_SEPARATOR
+ || type_table[ch] == LINE_SEPARATOR
+ || type_table[ch] == PARAGRAPH_SEPARATOR);
+}
+
+jboolean
+java::lang::Character::isUpperCase (jchar ch)
+{
+ if (ch >= 0x2000 && ch <= 0x2fff)
+ return false;
+ return type_table[ch] == UPPERCASE_LETTER;
+}
+
+jchar
+java::lang::Character::toLowerCase (jchar ch)
+{
+ if (type_table[ch] == UPPERCASE_LETTER)
+ return attribute_table[ch];
+ return to_lower_title (ch);
+}
+
+jchar
+java::lang::Character::toUpperCase (jchar ch)
+{
+ if (type_table[ch] == LOWERCASE_LETTER)
+ return attribute_table[ch];
+ return to_upper_title (ch);
+}
+
+#endif /* COMPACT_CHARACTER */
diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc
new file mode 100644
index 00000000000..1768df5ecb2
--- /dev/null
+++ b/libjava/java/lang/natClass.cc
@@ -0,0 +1,785 @@
+// natClass.cc - Implementation of java.lang.Class native methods.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#pragma implementation "Class.h"
+
+#include <cni.h>
+#include <jvm.h>
+#include <java/lang/Class.h>
+#include <java/lang/ClassLoader.h>
+#include <java/lang/String.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/reflect/Member.h>
+#include <java/lang/reflect/Method.h>
+#include <java/lang/reflect/Field.h>
+#include <java/lang/reflect/Constructor.h>
+#include <java/lang/AbstractMethodError.h>
+#include <java/lang/ClassNotFoundException.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/IllegalAccessError.h>
+#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/InstantiationException.h>
+#include <java/lang/NoClassDefFoundError.h>
+#include <java/lang/NoSuchFieldException.h>
+#include <java/lang/NoSuchMethodException.h>
+#include <java/lang/Thread.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/System.h>
+#include <java/lang/SecurityManager.h>
+
+
+
+#define CloneableClass _CL_Q34java4lang9Cloneable
+extern java::lang::Class CloneableClass;
+#define ObjectClass _CL_Q34java4lang6Object
+extern java::lang::Class ObjectClass;
+#define ErrorClass _CL_Q34java4lang5Error
+extern java::lang::Class ErrorClass;
+#define ClassClass _CL_Q34java4lang5Class
+extern java::lang::Class ClassClass;
+#define MethodClass _CL_Q44java4lang7reflect6Method
+extern java::lang::Class MethodClass;
+#define FieldClass _CL_Q44java4lang7reflect5Field
+extern java::lang::Class FieldClass;
+
+// Some constants we use to look up the class initializer.
+static _Jv_Utf8Const *void_signature = _Jv_makeUtf8Const ("()V", 3);
+static _Jv_Utf8Const *clinit_name = _Jv_makeUtf8Const ("<clinit>", 8);
+static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
+
+// These are the possible values for the `state' field. They more or
+// less follow the section numbers in the Java Language Spec. Right
+// now we don't bother to represent other interesting states, e.g. the
+// states a class might inhabit before it is prepared. Note that
+// ordering is important here; in particular `resolved' must come
+// between `nothing' and the other states.
+#define STATE_NOTHING 0
+#define STATE_RESOLVED 1
+#define STATE_IN_PROGRESS 6
+#define STATE_DONE 9
+#define STATE_ERROR 10
+
+// Size of local hash table.
+#define HASH_LEN 256
+
+// Hash function for Utf8Consts.
+#define HASH_UTF(Utf) (((Utf)->hash) % HASH_LEN)
+
+// This is the table we use to keep track of loaded classes. See Spec
+// section 12.2.
+static jclass loaded_classes[HASH_LEN];
+
+
+
+jclass
+java::lang::Class::forName (jstring className)
+{
+ if (! className)
+ JvThrow (new java::lang::NullPointerException);
+
+#if 0
+ // FIXME: should check syntax of CLASSNAME and throw
+ // IllegalArgumentException on failure.
+
+ // FIXME: should use class loader from calling method.
+ jclass klass = _Jv_FindClass (className, NULL);
+#else
+ jsize length = _Jv_GetStringUTFLength (className);
+ char buffer[length];
+ _Jv_GetStringUTFRegion (className, 0, length, buffer);
+
+ // FIXME: should check syntax of CLASSNAME and throw
+ // IllegalArgumentException on failure.
+ _Jv_Utf8Const *name = _Jv_makeUtf8Const (buffer, length);
+
+ // FIXME: should use class loader from calling method.
+ jclass klass = (buffer[0] == '['
+ ? _Jv_FindClassFromSignature (name->data, NULL)
+ : _Jv_FindClass (name, NULL));
+#endif
+ if (! klass)
+ JvThrow (new java::lang::ClassNotFoundException (className));
+ return klass;
+}
+
+java::lang::reflect::Constructor *
+java::lang::Class::getConstructor (JArray<jclass> *)
+{
+ JvFail ("java::lang::Class::getConstructor not implemented");
+}
+
+JArray<java::lang::reflect::Constructor *> *
+java::lang::Class::getConstructors (void)
+{
+ JvFail ("java::lang::Class::getConstructors not implemented");
+}
+
+java::lang::reflect::Constructor *
+java::lang::Class::getDeclaredConstructor (JArray<jclass> *)
+{
+ JvFail ("java::lang::Class::getDeclaredConstructor not implemented");
+}
+
+JArray<java::lang::reflect::Constructor *> *
+java::lang::Class::getDeclaredConstructors (void)
+{
+ JvFail ("java::lang::Class::getDeclaredConstructors not implemented");
+}
+
+java::lang::reflect::Field *
+java::lang::Class::getField (jstring name, jint hash)
+{
+ java::lang::reflect::Field* rfield;
+ for (int i = 0; i < field_count; i++)
+ {
+ _Jv_Field *field = &fields[i];
+ if (! _Jv_equal (field->name, name, hash))
+ continue;
+ if (! (field->getModifiers() & java::lang::reflect::Modifier::PUBLIC))
+ continue;
+ rfield = new java::lang::reflect::Field ();
+ rfield->offset = (char*) field - (char*) fields;
+ rfield->declaringClass = this;
+ rfield->name = name;
+ return rfield;
+ }
+ jclass superclass = getSuperclass();
+ if (superclass == NULL)
+ return NULL;
+ rfield = superclass->getField(name, hash);
+ for (int i = 0; i < interface_count && rfield == NULL; ++i)
+ rfield = interfaces[i]->getField (name, hash);
+ return rfield;
+}
+
+java::lang::reflect::Field *
+java::lang::Class::getDeclaredField (jstring name)
+{
+ java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
+ if (s != NULL)
+ s->checkMemberAccess (this, java::lang::reflect::Member::DECLARED);
+ int hash = name->hashCode();
+ for (int i = 0; i < field_count; i++)
+ {
+ _Jv_Field *field = &fields[i];
+ if (! _Jv_equal (field->name, name, hash))
+ continue;
+ java::lang::reflect::Field* rfield = new java::lang::reflect::Field ();
+ rfield->offset = (char*) field - (char*) fields;
+ rfield->declaringClass = this;
+ rfield->name = name;
+ return rfield;
+ }
+ JvThrow (new java::lang::NoSuchFieldException (name));
+}
+
+JArray<java::lang::reflect::Field *> *
+java::lang::Class::getDeclaredFields (void)
+{
+ java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
+ if (s != NULL)
+ s->checkMemberAccess (this, java::lang::reflect::Member::DECLARED);
+ JArray<java::lang::reflect::Field *> *result
+ = (JArray<java::lang::reflect::Field *> *)
+ JvNewObjectArray (field_count, &FieldClass, NULL);
+ java::lang::reflect::Field** fptr = elements (result);
+ for (int i = 0; i < field_count; i++)
+ {
+ _Jv_Field *field = &fields[i];
+ java::lang::reflect::Field* rfield = new java::lang::reflect::Field ();
+ rfield->offset = (char*) field - (char*) fields;
+ rfield->declaringClass = this;
+ *fptr++ = rfield;
+ }
+ return result;
+}
+
+java::lang::reflect::Method *
+java::lang::Class::getDeclaredMethod (jstring, JArray<jclass> *)
+{
+ JvFail ("java::lang::Class::getDeclaredMethod not implemented");
+}
+
+JArray<java::lang::reflect::Method *> *
+java::lang::Class::getDeclaredMethods (void)
+{
+ int numMethods = 0;
+ int i;
+ for (i = method_count; --i >= 0; )
+ {
+ _Jv_Method *method = &methods[i];
+ if (method->name == NULL
+ || _Jv_equalUtf8Consts (method->name, clinit_name)
+ || _Jv_equalUtf8Consts (method->name, init_name))
+ continue;
+ numMethods++;
+ }
+ JArray<java::lang::reflect::Method *> *result
+ = (JArray<java::lang::reflect::Method *> *)
+ JvNewObjectArray (numMethods, &MethodClass, NULL);
+ java::lang::reflect::Method** mptr = elements (result);
+ for (i = 0; i < method_count; i++)
+ {
+ _Jv_Method *method = &methods[i];
+ if (method->name == NULL
+ || _Jv_equalUtf8Consts (method->name, clinit_name)
+ || _Jv_equalUtf8Consts (method->name, init_name))
+ continue;
+ java::lang::reflect::Method* rmethod = new java::lang::reflect::Method ();
+ rmethod->offset = (char*) mptr - (char*) elements (result);
+ rmethod->declaringClass = this;
+ *mptr++ = rmethod;
+ }
+ return result;
+}
+
+jstring
+java::lang::Class::getName (void)
+{
+ char buffer[name->length + 1];
+ memcpy (buffer, name->data, name->length);
+ buffer[name->length] = '\0';
+ return _Jv_NewStringUTF (buffer);
+}
+
+JArray<jclass> *
+java::lang::Class::getClasses (void)
+{
+ // FIXME: implement.
+ return NULL;
+}
+
+JArray<jclass> *
+java::lang::Class::getDeclaredClasses (void)
+{
+ checkMemberAccess (java::lang::reflect::Member::DECLARED);
+ JvFail ("java::lang::Class::getDeclaredClasses not implemented");
+ return NULL; // Placate compiler.
+}
+
+// This is marked as unimplemented in the JCL book.
+jclass
+java::lang::Class::getDeclaringClass (void)
+{
+ JvFail ("java::lang::Class::getDeclaringClass unimplemented");
+ return NULL; // Placate compiler.
+}
+
+JArray<java::lang::reflect::Field *> *
+java::lang::Class::getFields (void)
+{
+ JvFail ("java::lang::Class::getFields not implemented");
+}
+
+JArray<jclass> *
+java::lang::Class::getInterfaces (void)
+{
+ jobjectArray r = JvNewObjectArray (interface_count, getClass (), NULL);
+ jobject *data = elements (r);
+ for (int i = 0; i < interface_count; ++i)
+ data[i] = interfaces[i];
+ return reinterpret_cast<JArray<jclass> *> (r);
+}
+
+java::lang::reflect::Method *
+java::lang::Class::getMethod (jstring, JArray<jclass> *)
+{
+ JvFail ("java::lang::Class::getMethod not implemented");
+}
+
+JArray<java::lang::reflect::Method *> *
+java::lang::Class::getMethods (void)
+{
+ JvFail ("java::lang::Class::getMethods not implemented");
+}
+
+jboolean
+java::lang::Class::isAssignableFrom (jclass klass)
+{
+ if (this == klass)
+ return true;
+ // Primitive types must be equal, which we just tested for.
+ if (isPrimitive () || ! klass || klass->isPrimitive())
+ return false;
+
+ // If target is array, so must source be.
+ if (isArray ())
+ {
+ if (! klass->isArray())
+ return false;
+ return getComponentType()->isAssignableFrom(klass->getComponentType());
+ }
+
+ if (isAssignableFrom (klass->getSuperclass()))
+ return true;
+
+ if (isInterface())
+ {
+ // See if source implements this interface.
+ for (int i = 0; i < klass->interface_count; ++i)
+ {
+ jclass interface = klass->interfaces[i];
+ // FIXME: ensure that class is prepared here.
+ // See Spec 12.3.2.
+ if (isAssignableFrom (interface))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+jboolean
+java::lang::Class::isInstance (jobject obj)
+{
+ if (! obj || isPrimitive ())
+ return false;
+ return isAssignableFrom (obj->getClass());
+}
+
+jboolean
+java::lang::Class::isInterface (void)
+{
+ return (accflags & java::lang::reflect::Modifier::INTERFACE) != 0;
+}
+
+jobject
+java::lang::Class::newInstance (void)
+{
+ // FIXME: do accessibility checks here. There currently doesn't
+ // seem to be any way to do these.
+ // FIXME: we special-case one check here just to pass a Plum Hall
+ // test. Once access checking is implemented, remove this.
+ if (this == &ClassClass)
+ JvThrow (new java::lang::IllegalAccessException);
+
+ if (isPrimitive ()
+ || isInterface ()
+ || isArray ()
+ || java::lang::reflect::Modifier::isAbstract(accflags))
+ JvThrow (new java::lang::InstantiationException);
+
+ _Jv_Method *meth = _Jv_GetMethodLocal (this, init_name, void_signature);
+ if (! meth)
+ JvThrow (new java::lang::NoSuchMethodException);
+
+ jobject r = JvAllocObject (this);
+ ((void (*) (jobject)) meth->ncode) (r);
+ return r;
+}
+
+// Initialize the constants.
+void
+java::lang::Class::resolveConstants (void)
+{
+ for (int i = 0; i < constants.size; ++i)
+ {
+ if (constants.tags[i] == CONSTANT_String)
+ {
+ jstring str;
+ str = _Jv_NewStringUtf8Const ((_Jv_Utf8Const *) constants.data[i]);
+ constants.data[i] = (void *) str;
+ constants.tags[i] = CONSTANT_ResolvedString;
+ }
+ else if (constants.tags[i] == CONSTANT_Class)
+ {
+ _Jv_Utf8Const *name = (_Jv_Utf8Const *) constants.data[i];
+ jclass klass = _Jv_FindClassFromSignature (name->data, loader);
+ if (! klass)
+ {
+ jstring str = _Jv_NewStringUtf8Const (name);
+ JvThrow (new java::lang::ClassNotFoundException (str));
+ }
+
+ constants.data[i] = (void *) klass;
+ constants.tags[i] = CONSTANT_ResolvedClass;
+ }
+ }
+}
+
+// FIXME.
+void
+java::lang::Class::hackRunInitializers (void)
+{
+ _Jv_Method *meth = _Jv_GetMethodLocal (this, clinit_name, void_signature);
+ if (meth)
+ ((void (*) (void)) meth->ncode) ();
+}
+
+// This implements the initialization process for a class. From Spec
+// section 12.4.2.
+void
+java::lang::Class::initializeClass (void)
+{
+ // Short-circuit to avoid needless locking.
+ if (state == STATE_DONE)
+ return;
+
+ // Step 1.
+ _Jv_MonitorEnter (this);
+
+ // FIXME: This should actually be handled by calling into the class
+ // loader. For now we put it here.
+ if (state < STATE_RESOLVED)
+ {
+ // We set the state before calling resolveConstants to avoid
+ // infinite recursion when processing String or Class.
+ state = STATE_RESOLVED;
+ resolveConstants ();
+ }
+
+ // Step 2.
+ java::lang::Thread *self = java::lang::Thread::currentThread();
+ // FIXME: `self' can be null at startup. Hence this nasty trick.
+ self = (java::lang::Thread *) ((long) self | 1);
+ while (state == STATE_IN_PROGRESS && thread && thread != self)
+ wait ();
+
+ // Steps 3 & 4.
+ if (state == STATE_DONE || state == STATE_IN_PROGRESS || thread == self)
+ {
+ _Jv_MonitorExit (this);
+ return;
+ }
+
+ // Step 5.
+ if (state == STATE_ERROR)
+ {
+ _Jv_MonitorExit (this);
+ JvThrow (new java::lang::NoClassDefFoundError);
+ }
+
+ // Step 6.
+ thread = self;
+ state = STATE_IN_PROGRESS;
+ _Jv_MonitorExit (this);
+
+ // Step 7.
+ if (! isInterface () && superclass)
+ {
+ // FIXME: We can't currently catch a Java exception in C++ code.
+ // So instead we call a Java trampoline. It returns an
+ // exception, or null.
+ jobject except = superclass->hackTrampoline(0, NULL);
+ if (except)
+ {
+ // Caught an exception.
+ _Jv_MonitorEnter (this);
+ state = STATE_ERROR;
+ notify ();
+ _Jv_MonitorExit (this);
+ JvThrow (except);
+ }
+ }
+
+ // Step 8.
+ // FIXME: once again we have to go through a trampoline.
+ java::lang::Throwable *except = hackTrampoline (1, NULL);
+
+ // Steps 9, 10, 11.
+ if (! except)
+ {
+ _Jv_MonitorEnter (this);
+ state = STATE_DONE;
+ }
+ else
+ {
+ if (! ErrorClass.isInstance(except))
+ {
+ // Once again we must use the trampoline. In this case we
+ // have to detect an OutOfMemoryError.
+ except = hackTrampoline(2, except);
+ }
+ _Jv_MonitorEnter (this);
+ state = STATE_ERROR;
+ }
+ notify ();
+ _Jv_MonitorExit (this);
+ if (except)
+ JvThrow (except);
+}
+
+
+
+//
+// Some class-related convenience functions.
+//
+
+_Jv_Method *
+_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature)
+{
+ for (int i = 0; i < klass->method_count; ++i)
+ {
+ if (_Jv_equalUtf8Consts (name, klass->methods[i].name)
+ && _Jv_equalUtf8Consts (signature, klass->methods[i].signature))
+ return &klass->methods[i];
+ }
+ return NULL;
+}
+
+void *
+_Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature)
+{
+ // FIXME: can't do this until we have a working class loader.
+ // This probably isn't the right thing to do anyway, since we can't
+ // call a method of a class until the class is linked. But this
+ // captures the general idea.
+ // klass->getClassLoader()->resolveClass(klass);
+
+ for (; klass; klass = klass->getSuperclass())
+ {
+ _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
+ if (! meth)
+ continue;
+
+ if (java::lang::reflect::Modifier::isStatic(meth->accflags))
+ JvThrow (new java::lang::IncompatibleClassChangeError);
+ if (java::lang::reflect::Modifier::isAbstract(meth->accflags))
+ JvThrow (new java::lang::AbstractMethodError);
+ if (! java::lang::reflect::Modifier::isPublic(meth->accflags))
+ JvThrow (new java::lang::IllegalAccessError);
+
+ return meth->ncode;
+ }
+ JvThrow (new java::lang::IncompatibleClassChangeError);
+ return NULL; // Placate compiler.
+}
+
+void
+_Jv_InitClass (jclass klass)
+{
+ klass->initializeClass();
+}
+
+// This function is called many times during startup, before main() is
+// run. We do our runtime initialization here the very first time we
+// are called. At that point in time we know for certain we are
+// running single-threaded, so we don't need to lock when modifying
+// `init'. CLASSES is NULL-terminated.
+void
+_Jv_RegisterClasses (jclass *classes)
+{
+ static bool init = false;
+
+ if (! init)
+ {
+ init = true;
+ _Jv_InitThreads ();
+ _Jv_InitGC ();
+ _Jv_InitializeSyncMutex ();
+ }
+
+ JvSynchronize sync (&ClassClass);
+ for (; *classes; ++classes)
+ {
+ jclass klass = *classes;
+ jint hash = HASH_UTF (klass->name);
+ klass->next = loaded_classes[hash];
+ loaded_classes[hash] = klass;
+ }
+}
+
+void
+_Jv_RegisterClass (jclass klass)
+{
+ jclass classes[2];
+ classes[0] = klass;
+ classes[1] = NULL;
+ _Jv_RegisterClasses (classes);
+}
+
+jclass
+_Jv_FindClassInCache (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
+{
+ JvSynchronize sync (&ClassClass);
+ jint hash = HASH_UTF (name);
+ jclass klass;
+ for (klass = loaded_classes[hash]; klass; klass = klass->next)
+ {
+ if (loader == klass->loader && _Jv_equalUtf8Consts (name, klass->name))
+ break;
+ }
+ return klass;
+}
+
+#if 0
+jclass
+_Jv_FindClassInCache (jstring name, java::lang::ClassLoader *loader)
+{
+ JvSynchronize sync (&ClassClass);
+ jint hash = name->hashCode();
+ jclass klass = loaded_classes[(_Jv_ushort) hash % HASH_LEN];
+ for ( ; klass; klass = klass->next)
+ {
+ if (loader == klass->loader
+ && _Jv_equalUtf8Consts (klass->name, name, hash))
+ break;
+ }
+ return klass;
+}
+#endif
+
+jclass
+_Jv_FindClass (_Jv_Utf8Const* name, java::lang::ClassLoader *loader)
+{
+ jclass klass = _Jv_FindClassInCache (name, loader);
+ if (loader && ! klass)
+ {
+ klass = loader->loadClass(_Jv_NewStringUtf8Const (name));
+ if (klass)
+ _Jv_RegisterClass (klass);
+ }
+ return klass;
+}
+
+#if 0
+jclass
+_Jv_FindClass (jstring name, java::lang::ClassLoader *loader)
+{
+ jclass klass = _Jv_FindClassInCache (name, loader);
+ if (loader && ! klass)
+ {
+ klass = loader->loadClass(name);
+ if (klass)
+ _Jv_RegisterClass (klass);
+ }
+ return klass;
+}
+#endif
+
+jclass
+_Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
+ java::lang::ClassLoader *loader)
+{
+ jclass ret = (jclass) JvAllocObject (&ClassClass);
+
+ ret->next = NULL;
+ ret->name = name;
+ ret->accflags = 0;
+ ret->superclass = superclass;
+ ret->constants.size = 0;
+ ret->constants.tags = NULL;
+ ret->constants.data = NULL;
+ ret->methods = NULL;
+ ret->method_count = 0;
+ ret->vtable_method_count = 0;
+ ret->fields = NULL;
+ ret->size_in_bytes = 0;
+ ret->field_count = 0;
+ ret->static_field_count = 0;
+ ret->vtable = NULL;
+ ret->interfaces = NULL;
+ ret->loader = loader;
+ ret->interface_count = 0;
+ ret->state = 0;
+ ret->thread = NULL;
+
+ _Jv_RegisterClass (ret);
+
+ return ret;
+}
+
+jclass
+_Jv_FindArrayClass (jclass element)
+{
+ _Jv_Utf8Const *array_name;
+ int len;
+ if (element->isPrimitive())
+ {
+ // For primitive types the array is cached in the class.
+ jclass ret = (jclass) element->methods;
+ if (ret)
+ return ret;
+ len = 3;
+ }
+ else
+ len = element->name->length + 5;
+
+ {
+ char signature[len];
+ int index = 0;
+ signature[index++] = '[';
+ // Compute name of array class to see if we've already cached it.
+ if (element->isPrimitive())
+ {
+ signature[index++] = (char) element->method_count;
+ }
+ else
+ {
+ size_t length = element->name->length;
+ const char *const name = element->name->data;
+ if (name[0] != '[')
+ signature[index++] = 'L';
+ memcpy (&signature[index], name, length);
+ index += length;
+ if (name[0] != '[')
+ signature[index++] = ';';
+ }
+ array_name = _Jv_makeUtf8Const (signature, index);
+ }
+
+ jclass array_class = _Jv_FindClassInCache (array_name, element->loader);
+
+ if (! array_class)
+ {
+ // Create new array class.
+ array_class = _Jv_NewClass (array_name, &ObjectClass, element->loader);
+
+ // Note that `vtable_method_count' doesn't include the initial
+ // NULL slot.
+ int dm_count = ObjectClass.vtable_method_count + 1;
+
+ // Create a new vtable by copying Object's vtable (except the
+ // class pointer, of course). Note that we allocate this as
+ // unscanned memory -- the vtables are handled specially by the
+ // GC.
+ int size = (sizeof (_Jv_VTable) +
+ ((dm_count - 1) * sizeof (void *)));
+ _Jv_VTable *vtable = (_Jv_VTable *) _Jv_AllocBytes (size);
+ vtable->clas = array_class;
+ memcpy (vtable->method, ObjectClass.vtable->method,
+ dm_count * sizeof (void *));
+ array_class->vtable = vtable;
+ array_class->vtable_method_count = ObjectClass.vtable_method_count;
+
+ // Stash the pointer to the element type.
+ array_class->methods = (_Jv_Method *) element;
+
+ // Register our interfaces.
+ // FIXME: for JDK 1.2 we need Serializable.
+ static jclass interfaces[] = { &CloneableClass };
+ array_class->interfaces = interfaces;
+ array_class->interface_count = 1;
+
+ // FIXME: initialize other Class instance variables,
+ // e.g. `fields'.
+
+ array_class->state = STATE_DONE;
+ }
+
+ // For primitive types, point back at this array.
+ if (element->isPrimitive())
+ element->methods = (_Jv_Method *) array_class;
+
+ return array_class;
+}
+
+jboolean
+_Jv_IsInstanceOf(jobject obj, jclass cl)
+{
+ return cl->isInstance(obj);
+}
diff --git a/libjava/java/lang/natDouble.cc b/libjava/java/lang/natDouble.cc
new file mode 100644
index 00000000000..17990884751
--- /dev/null
+++ b/libjava/java/lang/natDouble.cc
@@ -0,0 +1,180 @@
+// natDouble.cc - Implementation of java.lang.Double native methods.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/* AIX requires this to be the first thing in the file. */
+#ifndef __GNUC__
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+#endif
+
+#include <stdlib.h>
+
+#include <cni.h>
+#include <java/lang/String.h>
+#include <java/lang/Double.h>
+#include <java/lang/NumberFormatException.h>
+#include <jvm.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "mprec.h"
+
+union u
+{
+ jlong l;
+ jdouble d;
+};
+
+jlong
+java::lang::Double::doubleToLongBits(jdouble value)
+{
+ union u u;
+ u.d = value;
+ return u.l;
+}
+
+jdouble
+java::lang::Double::longBitsToDouble(jlong bits)
+{
+ union u u;
+ u.l = bits;
+ return u.d;
+}
+
+jstring
+java::lang::Double::toString(jdouble value, jboolean isFloat)
+{
+ if (isNaN (value))
+ return JvNewStringLatin1 ("NaN", sizeof ("NaN") - 1);
+
+ if (value == POSITIVE_INFINITY)
+ return JvNewStringLatin1 ("Infinity", sizeof ("Infinity") - 1);
+
+ if (value == NEGATIVE_INFINITY)
+ return JvNewStringLatin1 ("-Infinity", sizeof ("-Infinity") - 1);
+
+ char buffer[50], result[50];
+ int decpt, sign;
+
+ _dtoa (value, 0, 20, &decpt, &sign, NULL, buffer, (int)isFloat);
+
+ value = fabs (value);
+
+ char *s = buffer;
+ char *d = result;
+
+ if (sign)
+ *d++ = '-';
+
+ if (value >= 1e-3 && value < 1e7 || value == 0)
+ {
+ if (decpt <= 0)
+ *d++ = '0';
+ else
+ {
+ for (int i = 0; i < decpt; i++)
+ if (*s)
+ *d++ = *s++;
+ else
+ *d++ = '0';
+ }
+
+ *d++ = '.';
+
+ if (*s == 0)
+ {
+ *d++ = '0';
+ decpt++;
+ }
+
+ while (decpt++ < 0)
+ *d++ = '0';
+
+ while (*s)
+ *d++ = *s++;
+
+ *d = 0;
+
+ return JvNewStringLatin1 (result, strlen (result));
+ }
+
+ *d++ = *s++;
+ decpt--;
+ *d++ = '.';
+
+ if (*s == 0)
+ *d++ = '0';
+
+ while (*s)
+ *d++ = *s++;
+
+ *d++ = 'E';
+
+ if (decpt < 0)
+ {
+ *d++ = '-';
+ decpt = -decpt;
+ }
+
+ {
+ char exp[4];
+ char *e = exp + sizeof exp;
+
+ *--e = 0;
+ do
+ {
+ *--e = '0' + decpt % 10;
+ decpt /= 10;
+ }
+ while (decpt > 0);
+
+ while (*e)
+ *d++ = *e++;
+ }
+
+ *d = 0;
+
+ return JvNewStringLatin1 (result, strlen (result));
+}
+
+jdouble
+java::lang::Double::doubleValueOf(jstring str)
+{
+ int length = str->length();
+ // Note that UTF can expand 3x.
+
+#ifdef HAVE_ALLOCA
+ char *data = (char *) alloca (3 * length + 1);
+#else
+#error --- need an alternate implementation here ---
+#endif
+
+ data[_Jv_GetStringUTFRegion (str, 0, length, data)] = 0;
+
+ struct _Jv_reent reent;
+ memset (&reent, 0, sizeof reent);
+
+ double val = _strtod_r (&reent, data, NULL);
+
+ if (reent._errno)
+ _Jv_Throw (new NumberFormatException);
+
+ return val;
+}
diff --git a/libjava/java/lang/natFirstThread.cc b/libjava/java/lang/natFirstThread.cc
new file mode 100644
index 00000000000..d47446be4a8
--- /dev/null
+++ b/libjava/java/lang/natFirstThread.cc
@@ -0,0 +1,56 @@
+// natFirstThread.cc - Implementation of FirstThread native methods.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <cni.h>
+#include <jvm.h>
+
+#include <java/lang/FirstThread.h>
+#include <java/lang/Class.h>
+#include <java/lang/String.h>
+#include <java/lang/System.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/io/PrintStream.h>
+
+#define DIE(Message) die (JvNewStringLatin1 (Message))
+
+typedef void main_func (jobject);
+
+void
+java::lang::FirstThread::run (void)
+{
+ Utf8Const* main_signature = _Jv_makeUtf8Const ("([Ljava.lang.String;)V", 22);
+ Utf8Const* main_name = _Jv_makeUtf8Const ("main", 4);
+
+#if 0
+ // Note: this turns out to be more painful than useful. Apparently
+ // many people rely on being able to have main in a non-public
+ // class.
+ // This is based on my reading of 12.3.3.
+ if (! java::lang::reflect::Modifier::isPublic(klass->getModifiers()))
+ DIE ("class must be public");
+#endif
+
+ _Jv_Method *meth = _Jv_GetMethodLocal (klass, main_name, main_signature);
+
+ // Some checks from Java Spec section 12.1.4.
+ if (meth == NULL)
+ DIE ("no suitable method `main' in class");
+ if (! java::lang::reflect::Modifier::isStatic(meth->accflags))
+ DIE ("`main' must be static");
+ if (! java::lang::reflect::Modifier::isPublic(meth->accflags))
+ DIE ("`main' must be public");
+
+ main_func *real_main = (main_func *) meth->ncode;
+ (*real_main) (args);
+}
diff --git a/libjava/java/lang/natFloat.cc b/libjava/java/lang/natFloat.cc
new file mode 100644
index 00000000000..e3189bebc2d
--- /dev/null
+++ b/libjava/java/lang/natFloat.cc
@@ -0,0 +1,37 @@
+// natFloat.cc - Implementation of java.lang.Float native methods.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <java/lang/Float.h>
+#include <jvm.h>
+
+union u
+{
+ jint l;
+ jfloat d;
+};
+
+jint
+java::lang::Float::floatToIntBits(jfloat value)
+{
+ union u u;
+ u.d = value;
+ return u.l;
+}
+
+jfloat
+java::lang::Float::intBitsToFloat(jint bits)
+{
+ union u u;
+ u.l = bits;
+ return u.d;
+}
+
diff --git a/libjava/java/lang/natMath.cc b/libjava/java/lang/natMath.cc
new file mode 100644
index 00000000000..66382473eed
--- /dev/null
+++ b/libjava/java/lang/natMath.cc
@@ -0,0 +1,263 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/**
+ * @author Andrew Haley <aph@cygnus.com>
+ * @date Tue Sep 22 1998 */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+#include <config.h>
+
+#include <java/lang/String.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Math.h>
+#include <java-array.h>
+
+#include "fdlibm.h"
+
+jdouble java::lang::Math::cos(jdouble x)
+{
+ return (jdouble)::cos((double)x);
+}
+
+jdouble java::lang::Math::sin(jdouble x)
+{
+ return (jdouble)::sin((double)x);
+}
+
+jdouble java::lang::Math::tan(jdouble x)
+{
+ return (jdouble)::tan((double)x);
+}
+
+jdouble java::lang::Math::asin(jdouble x)
+{
+ return (jdouble)::asin((double)x);
+}
+
+jdouble java::lang::Math::acos(jdouble x)
+{
+ return (jdouble)::acos((double)x);
+}
+
+jdouble java::lang::Math::atan(jdouble x)
+{
+ return (jdouble)::atan((double)x);
+}
+
+jdouble java::lang::Math::atan2(jdouble y, jdouble x)
+{
+ return (jdouble)::atan2((jdouble)y, (jdouble)x);
+}
+
+jdouble java::lang::Math::log(jdouble x)
+{
+ return (jdouble)::log((double)x);
+}
+
+jdouble java::lang::Math::exp(jdouble x)
+{
+ return (jdouble)::exp((double)x);
+}
+
+jdouble java::lang::Math::sqrt(jdouble x)
+{
+ return (jdouble)::sqrt((double)x);
+}
+
+jdouble java::lang::Math::pow(jdouble y, jdouble x)
+{
+ return (jdouble)::pow((jdouble)y, (jdouble)x);
+}
+
+jdouble java::lang::Math::IEEEremainder(jdouble y, jdouble x)
+{
+ return (jdouble)::__ieee754_remainder((jdouble)y, (jdouble)x);
+}
+
+jdouble java::lang::Math::abs(jdouble x)
+{
+ return (jdouble)::fabs((double)x);
+}
+
+jfloat java::lang::Math::abs(jfloat x)
+{
+ return (jfloat)::fabsf((float)x);
+}
+
+jdouble java::lang::Math::rint(jdouble x)
+{
+ return (jdouble)::rint((double)x);
+}
+
+jint java::lang::Math::round(jfloat x)
+{
+ if (x != x)
+ return 0;
+ if (x <= (jfloat)java::lang::Integer::MIN_VALUE)
+ return java::lang::Integer::MIN_VALUE;
+ if (x >= (jfloat)java::lang::Integer::MAX_VALUE)
+ return java::lang::Integer::MAX_VALUE;
+
+ return (jint)::rintf((float)x);
+}
+
+jlong java::lang::Math::round(jdouble x)
+{
+ if (x != x)
+ return 0;
+ if (x <= (jdouble)java::lang::Long::MIN_VALUE)
+ return java::lang::Long::MIN_VALUE;
+ if (x >= (jdouble)java::lang::Long::MAX_VALUE)
+ return java::lang::Long::MAX_VALUE;
+
+ return (jlong)::rint((double)x);
+}
+
+jdouble java::lang::Math::floor(jdouble x)
+{
+ return (jdouble)::floor((double)x);
+}
+
+jdouble java::lang::Math::ceil(jdouble x)
+{
+ return (jdouble)::ceil((double)x);
+}
+
+static inline int
+floatToIntBits (jfloat value)
+{
+ union {
+ jint l;
+ jfloat d;
+ } u;
+ u.d = value;
+ return u.l;
+}
+
+static inline bool
+isNaN (jint bits)
+{
+ jint e = bits & 0x7f800000;
+ jint f = bits & 0x007fffff;
+
+ return e == 0x7f800000 && f != 0;
+}
+
+jfloat
+java::lang::Math::min(jfloat a, jfloat b)
+{
+ jint abits = floatToIntBits (a);
+ jint bbits = floatToIntBits (b);
+
+ if (isNaN (abits) || isNaN (bbits))
+ return java::lang::Float::NaN;
+
+ if (abits >= 0) // a is +ve
+ return bbits < 0 ? b // a is +ve, b is -ve.
+ // a and b are both +ve, so compare magnitudes: the number with
+ // the smallest magnitude is the smallest
+ : (abits < bbits ? a : b);
+ else // a is -ve
+ return bbits >= 0 ? a // a is -ve, b is +ve.
+ // a and b are both -ve, so compare magnitudes: the number with
+ // the biggest magnitude is the smallest
+ : (abits > bbits ? a : b);
+}
+
+jfloat
+java::lang::Math::max(jfloat a, jfloat b)
+{
+ jint abits = floatToIntBits (a);
+ jint bbits = floatToIntBits (b);
+
+ if (isNaN (abits) || isNaN (bbits))
+ return java::lang::Float::NaN;
+
+ if (abits >= 0) // a is +ve
+ return bbits < 0 ? a // a is +ve, b is -ve.
+ // a and b are both +ve, so compare magnitudes: the number with
+ // the smallest magnitude is the smallest
+ : (abits > bbits ? a : b);
+ else // a is -ve
+ return bbits >= 0 ? b // a is -ve, b is +ve.
+ // a and b are both -ve, so compare magnitudes: the number with
+ // the biggest magnitude is the smallest
+ : (abits < bbits ? a : b);
+}
+
+static inline jlong
+doubleToLongBits (jdouble value)
+{
+ union {
+ jlong l;
+ jdouble d;
+ } u;
+ u.d = value;
+ return u.l;
+}
+
+static inline bool
+isNaN (jlong bits)
+{
+ jlong e = bits & 0x7ff0000000000000LL;
+ jlong f = bits & 0x000fffffffffffffLL;
+
+ return e == 0x7ff0000000000000LL && f != 0LL;
+}
+
+
+jdouble
+java::lang::Math::min(jdouble a, jdouble b)
+{
+ jlong abits = doubleToLongBits (a);
+ jlong bbits = doubleToLongBits (b);
+
+ if (isNaN (abits) || isNaN (bbits))
+ return java::lang::Double::NaN;
+
+ if (abits >= 0LL) // a is +ve
+ return bbits < 0LL ? b // a is +ve, b is -ve.
+ // a and b are both +ve, so compare magnitudes: the number with
+ // the smallest magnitude is the smallest
+ : (abits < bbits ? a : b);
+ else // a is -ve
+ return bbits >= 0LL ? a // a is -ve, b is +ve.
+ // a and b are both -ve, so compare magnitudes: the number with
+ // the biggest magnitude is the smallest
+ : (abits > bbits ? a : b);
+}
+
+jdouble
+java::lang::Math::max(jdouble a, jdouble b)
+{
+ jlong abits = doubleToLongBits (a);
+ jlong bbits = doubleToLongBits (b);
+
+ if (isNaN (abits) || isNaN (bbits))
+ return java::lang::Double::NaN;
+
+ if (abits >= 0LL) // a is +ve
+ return bbits < 0LL ? a // a is +ve, b is -ve.
+ // a and b are both +ve, so compare magnitudes: the number with
+ // the smallest magnitude is the smallest
+ : (abits > bbits ? a : b);
+ else // a is -ve
+ return bbits >= 0LL ? b // a is -ve, b is +ve.
+ // a and b are both -ve, so compare magnitudes: the number with
+ // the biggest magnitude is the smallest
+ : (abits < bbits ? a : b);
+}
+
diff --git a/libjava/java/lang/natObject.cc b/libjava/java/lang/natObject.cc
new file mode 100644
index 00000000000..7b26769e351
--- /dev/null
+++ b/libjava/java/lang/natObject.cc
@@ -0,0 +1,241 @@
+// natObject.cc - Implementation of the Object class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <string.h>
+
+#pragma implementation "Object.h"
+
+#include <cni.h>
+#include <jvm.h>
+#include <java/lang/Object.h>
+#include <java-threads.h>
+#include <java/lang/CloneNotSupportedException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IllegalMonitorStateException.h>
+#include <java/lang/InterruptedException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Class.h>
+#include <java/lang/Cloneable.h>
+#include <java/lang/Thread.h>
+
+#define CloneableClass _CL_Q34java4lang9Cloneable
+extern java::lang::Class CloneableClass;
+
+
+
+// This is used to represent synchronization information.
+struct _Jv_SyncInfo
+{
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+ // We only need to keep track of initialization state if we can
+ // possibly finalize this object.
+ bool init;
+#endif
+ _Jv_ConditionVariable_t condition;
+ _Jv_Mutex_t mutex;
+};
+
+
+
+jclass
+java::lang::Object::getClass (void)
+{
+ _Jv_VTable **dt = (_Jv_VTable **) this;
+ return (*dt)->clas;
+}
+
+jint
+java::lang::Object::hashCode (void)
+{
+ return _Jv_HashCode (this);
+}
+
+jobject
+java::lang::Object::clone (void)
+{
+ jclass klass = getClass ();
+ jobject r;
+ jint size;
+
+ // We also clone arrays here. If we put the array code into
+ // __JArray, then we'd have to figure out a way to find the array
+ // vtbl when creating a new array class. This is easier, if uglier.
+ if (klass->isArray())
+ {
+ __JArray *array = (__JArray *) this;
+ jclass comp = getClass()->getComponentType();
+ jint eltsize;
+ if (comp->isPrimitive())
+ {
+ r = _Jv_NewPrimArray (comp, array->length);
+ eltsize = comp->size();
+ }
+ else
+ {
+ r = _Jv_NewObjectArray (array->length, comp, NULL);
+ eltsize = sizeof (jobject);
+ }
+ size = sizeof (__JArray) + array->length * eltsize;
+ }
+ else
+ {
+ if (! CloneableClass.isAssignableFrom(klass))
+ JvThrow (new CloneNotSupportedException);
+
+ size = klass->size();
+ r = JvAllocObject (klass, size);
+ }
+
+ memcpy ((void *) r, (void *) this, size);
+ return r;
+}
+
+
+//
+// Synchronization code.
+//
+
+// This global is used to make sure that only one thread sets an
+// object's `sync_info' field.
+static _Jv_Mutex_t sync_mutex;
+
+// This macro is used to see if synchronization initialization is
+// needed.
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+# define INIT_NEEDED(Obj) (! (Obj)->sync_info \
+ || ! ((_Jv_SyncInfo *) ((Obj)->sync_info))->init)
+#else
+# define INIT_NEEDED(Obj) (! (Obj)->sync_info)
+#endif
+
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+// If we have to run a destructor for a sync_info member, then this
+// function is registered as a finalizer for the sync_info.
+static void
+finalize_sync_info (jobject obj)
+{
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj;
+#if defined (_Jv_HaveCondDestroy)
+ _Jv_CondDestroy (&si->condition);
+#endif
+#if defined (_Jv_HaveMutexDestroy)
+ _Jv_MutexDestroy (&si->mutex);
+#endif
+ si->init = false;
+}
+#endif
+
+// This is called to initialize the sync_info element of an object.
+void
+java::lang::Object::sync_init (void)
+{
+ _Jv_MutexLock (&sync_mutex);
+ // Check again to see if initialization is needed now that we have
+ // the lock.
+ if (INIT_NEEDED (this))
+ {
+ // We assume there are no pointers in the sync_info
+ // representation.
+ _Jv_SyncInfo *si;
+ // We always create a new sync_info, even if there is already
+ // one available. Any given object can only be finalized once.
+ // If we get here and sync_info is not null, then it has already
+ // been finalized. So if we just reinitialize the old one,
+ // we'll never be able to (re-)destroy the mutex and/or
+ // condition variable.
+ si = (_Jv_SyncInfo *) _Jv_AllocBytes (sizeof (_Jv_SyncInfo));
+ // FIXME: what if si == NULL?
+ _Jv_MutexInit (&si->mutex);
+ _Jv_CondInit (&si->condition);
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+ // Register a finalizer.
+ si->init = true;
+ _Jv_RegisterFinalizer (si, finalize_sync_info);
+#endif
+ sync_info = (jobject) si;
+ }
+ _Jv_MutexUnlock (&sync_mutex);
+}
+
+void
+java::lang::Object::notify (void)
+{
+ if (INIT_NEEDED (this))
+ sync_init ();
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
+ if (_Jv_CondNotify (&si->condition, &si->mutex))
+ JvThrow (new IllegalMonitorStateException);
+}
+
+void
+java::lang::Object::notifyAll (void)
+{
+ if (INIT_NEEDED (this))
+ sync_init ();
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
+ if (_Jv_CondNotifyAll (&si->condition, &si->mutex))
+ JvThrow (new IllegalMonitorStateException);
+}
+
+void
+java::lang::Object::wait (jlong timeout, jint nanos)
+{
+ if (INIT_NEEDED (this))
+ sync_init ();
+ if (timeout < 0 || nanos < 0 || nanos > 999999)
+ JvThrow (new IllegalArgumentException);
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
+ if (_Jv_CondWait (&si->condition, &si->mutex, timeout, nanos))
+ JvThrow (new IllegalMonitorStateException);
+ if (Thread::interrupted())
+ JvThrow (new InterruptedException);
+}
+
+//
+// Some runtime code.
+//
+
+// This function is called at system startup to initialize the
+// `sync_mutex'.
+void
+_Jv_InitializeSyncMutex (void)
+{
+ _Jv_MutexInit (&sync_mutex);
+}
+
+jint
+_Jv_MonitorEnter (jobject obj)
+{
+ if (! obj)
+ JvThrow (new java::lang::NullPointerException);
+ if (INIT_NEEDED (obj))
+ obj->sync_init ();
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
+ return _Jv_MutexLock (&si->mutex);
+}
+
+jint
+_Jv_MonitorExit (jobject obj)
+{
+ JvAssert (obj);
+ JvAssert (! INIT_NEEDED (obj));
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
+ if (_Jv_MutexUnlock (&si->mutex))
+ JvThrow (new java::lang::IllegalMonitorStateException);
+ return 0;
+}
+
+void
+_Jv_FinalizeObject (jobject obj)
+{
+ java::lang::Object::hack12_6(obj);
+}
diff --git a/libjava/java/lang/natRuntime.cc b/libjava/java/lang/natRuntime.cc
new file mode 100644
index 00000000000..d89ab18bd9c
--- /dev/null
+++ b/libjava/java/lang/natRuntime.cc
@@ -0,0 +1,68 @@
+// natRuntime.cc - Implementation of native side of Runtime class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <cni.h>
+#include <jvm.h>
+#include <java/lang/Runtime.h>
+
+void
+java::lang::Runtime::exit (jint status)
+{
+ checkExit (status);
+
+ // Make status right for Unix. This is perhaps strange.
+ if (status < 0 || status > 255)
+ status = 255;
+
+ if (finalize_on_exit)
+ _Jv_RunAllFinalizers ();
+
+ ::exit (status);
+}
+
+jlong
+java::lang::Runtime::freeMemory (void)
+{
+ return _Jv_GCFreeMemory ();
+}
+
+void
+java::lang::Runtime::gc (void)
+{
+ _Jv_RunGC ();
+}
+
+void
+java::lang::Runtime::runFinalization (void)
+{
+ _Jv_RunFinalizers ();
+}
+
+jlong
+java::lang::Runtime::totalMemory (void)
+{
+ return _Jv_GCTotalMemory ();
+}
+
+void
+java::lang::Runtime::traceInstructions (jboolean)
+{
+ // Do nothing.
+}
+
+void
+java::lang::Runtime::traceMethodCalls (jboolean)
+{
+ // Do nothing.
+}
diff --git a/libjava/java/lang/natString.cc b/libjava/java/lang/natString.cc
new file mode 100644
index 00000000000..5cb7b2c72b4
--- /dev/null
+++ b/libjava/java/lang/natString.cc
@@ -0,0 +1,800 @@
+// natString.cc - Implementation of java.lang.String native methods.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <cni.h>
+#include <java/lang/Character.h>
+#include <java/lang/String.h>
+#include <java/lang/IndexOutOfBoundsException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/StringIndexOutOfBoundsException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/io/ByteArrayOutputStream.h>
+#include <java/io/OutputStreamWriter.h>
+#include <java/io/ByteArrayInputStream.h>
+#include <java/io/InputStreamReader.h>
+#include <jvm.h>
+
+static jstring* strhash = NULL;
+static int strhash_count = 0; /* Number of slots used in strhash. */
+static int strhash_size = 0; /* Number of slots available in strhash.
+ * Assumed be power of 2! */
+
+#define DELETED_STRING ((jstring)(~0))
+#define SET_STRING_IS_INTERNED(STR) /* nothing */
+
+/* Find a slot where the string with elements DATA, length LEN,
+ and hash HASH should go in the strhash table of interned strings. */
+jstring*
+_Jv_StringFindSlot (jchar* data, jint len, jint hash)
+{
+ JvSynchronize sync (&StringClass);
+
+ int start_index = hash & (strhash_size - 1);
+ int deleted_index = -1;
+
+ register int index = start_index;
+ /* step must be non-zero, and relatively prime with strhash_size. */
+ int step = 8 * hash + 7;
+ for (;;)
+ {
+ register jstring* ptr = &strhash[index];
+ if (*ptr == NULL)
+ {
+ if (deleted_index >= 0)
+ return (&strhash[deleted_index]);
+ else
+ return ptr;
+ }
+ else if (*ptr == DELETED_STRING)
+ deleted_index = index;
+ else if ((*ptr)->length() == len
+ && memcmp(JvGetStringChars(*ptr), data, 2*len) == 0)
+ return (ptr);
+ index = (index + step) & (strhash_size - 1);
+ JvAssert (index != start_index);
+ }
+}
+
+/* Calculate a hash code for the string starting at PTR at given LENGTH.
+ This uses the same formula as specified for java.lang.String.hash. */
+
+static jint
+hashChars (jchar* ptr, jint length)
+{
+ register jchar* limit = ptr + length;
+ jint hash = 0;
+ // Updated specification from
+ // http://www.javasoft.com/docs/books/jls/clarify.html.
+ while (ptr < limit)
+ hash = (31 * hash) + *ptr++;
+ return hash;
+}
+
+jint
+java::lang::String::hashCode()
+{
+ return hashChars(JvGetStringChars(this), length());
+}
+
+jstring*
+_Jv_StringGetSlot (jstring str)
+{
+ jchar* data = JvGetStringChars(str);
+ int length = str->length();
+ return _Jv_StringFindSlot(data, length, hashChars (data, length));
+}
+
+void
+java::lang::String::rehash()
+{
+ JvSynchronize sync (&StringClass);
+
+ if (strhash == NULL)
+ {
+ strhash_size = 1024;
+ strhash = (jstring *) _Jv_AllocBytes (strhash_size * sizeof (jstring));
+ memset (strhash, 0, strhash_size * sizeof (jstring));
+ }
+ else
+ {
+ register int i = strhash_size;
+ register jstring* ptr = strhash + i;
+ strhash_size *= 2;
+ strhash = (jstring *) _Jv_AllocBytes (strhash_size * sizeof (jstring));
+ memset (strhash, 0, strhash_size * sizeof (jstring));
+
+ while (--i >= 0)
+ {
+ --ptr;
+ if (*ptr == NULL || *ptr == DELETED_STRING)
+ continue;
+
+ /* This is faster equivalent of
+ * *__JvGetInternSlot(*ptr) = *ptr; */
+ jint hash = (*ptr)->hashCode();
+ jint index = hash & (strhash_size - 1);
+ jint step = 8 * hash + 7;
+ for (;;)
+ {
+ if (strhash[index] == NULL)
+ {
+ strhash[index] = *ptr;
+ break;
+ }
+ index = (index + step) & (strhash_size - 1);
+ }
+ }
+ }
+}
+
+jstring
+java::lang::String::intern()
+{
+ JvSynchronize sync (&StringClass);
+ if (4 * strhash_count >= 3 * strhash_size)
+ rehash();
+ jstring* ptr = _Jv_StringGetSlot(this);
+ if (*ptr != NULL && *ptr != DELETED_STRING)
+ return *ptr;
+ SET_STRING_IS_INTERNED(this);
+ strhash_count++;
+ *ptr = this;
+ return this;
+}
+
+/* Called by String fake finalizer. */
+void
+java::lang::String::unintern()
+{
+ JvSynchronize sync (&StringClass);
+ jstring* ptr = _Jv_StringGetSlot(this);
+ if (*ptr == NULL || *ptr == DELETED_STRING)
+ return;
+ *ptr = DELETED_STRING;
+ strhash_count--;
+}
+
+jstring
+_Jv_NewStringUTF (const char *bytes)
+{
+ int size = strlen (bytes);
+ unsigned char *p = (unsigned char *) bytes;
+
+ int length = _Jv_strLengthUtf8 ((char *) p, size);
+ if (length < 0)
+ return NULL;
+
+ jstring jstr = JvAllocString (length);
+ jchar *chrs = JvGetStringChars (jstr);
+
+ p = (unsigned char *) bytes;
+ unsigned char *limit = p + size;
+ while (p < limit)
+ *chrs++ = UTF8_GET (p, limit);
+
+ return jstr;
+}
+
+jstring
+_Jv_NewStringUtf8Const (Utf8Const* str)
+{
+ jchar *chrs;
+ jchar buffer[100];
+ jstring jstr;
+ register unsigned char* data = (unsigned char*) str->data;
+ register unsigned char* limit = data + str->length;
+ int length = _Jv_strLengthUtf8(str->data, str->length);
+
+ if (length <= (int) (sizeof(buffer) / sizeof(jchar)))
+ {
+ jstr = NULL;
+ chrs = buffer;
+ }
+ else
+ {
+ jstr = JvAllocString(length);
+ chrs = JvGetStringChars(jstr);
+ }
+
+ while (data < limit)
+ *chrs++ = UTF8_GET(data, limit);
+ chrs -= length;
+
+ JvSynchronize sync (&StringClass);
+ if (4 * strhash_count >= 3 * strhash_size)
+ java::lang::String::rehash();
+ int hash = str->hash;
+ jstring* ptr = _Jv_StringFindSlot (chrs, length, hash);
+ if (*ptr != NULL && *ptr != DELETED_STRING)
+ return *ptr;
+ strhash_count++;
+ if (jstr == NULL)
+ {
+ jstr = JvAllocString(length);
+ chrs = JvGetStringChars(jstr);
+ memcpy (chrs, buffer, sizeof(jchar)*length);
+ }
+ *ptr = jstr;
+ SET_STRING_IS_INTERNED(jstr);
+ return jstr;
+}
+
+jsize
+_Jv_GetStringUTFLength (jstring string)
+{
+ register jsize len = 0;
+ register jchar *ptr = JvGetStringChars (string);
+ register jsize i = string->length();
+ while (--i >= 0)
+ {
+ register jchar ch = *ptr++;
+ if (ch > 0 && ch <= 0x7F)
+ len += 1;
+ else if (ch <= 0x7FF)
+ len += 2;
+ else
+ len += 3;
+ }
+ return len;
+}
+
+// Not sure this quite matches GetStringUTFRegion.
+// null-termination of result? len? throw exception?
+jsize
+_Jv_GetStringUTFRegion (jstring str, jsize start, jsize len, char *buf)
+{
+ register jchar *sptr = JvGetStringChars (str) + start;
+ register jsize i = len;
+ register char *dptr = buf;
+ while (--i >= 0)
+ {
+ jchar ch = *sptr++;
+ if (ch > 0 && ch <= 0x7F)
+ *dptr++ = (char) ch;
+ else if (ch <= 0x7FF)
+ {
+ *dptr++ = (char) (0xC0 + ((ch >> 6) & 0x1F));
+ *dptr++ = (char) (0x80 + (ch & 0x3F));
+ }
+ else
+ {
+ *dptr++ = (char) (0xE0 + ((ch >> 12) & 0xF));
+ *dptr++ = (char) (0x80 + ((ch >> 6) & 0x3F));
+ *dptr++ = (char) (0x80 + (ch & 0x3F));
+ }
+ }
+ return dptr - buf;
+}
+
+jstring
+_Jv_AllocString(jsize len)
+{
+ jsize sz = sizeof(java::lang::String) + len * sizeof(jchar);
+
+ jstring obj = (jstring) JvAllocObject(&StringClass, sz);
+
+ obj->data = obj;
+ obj->boffset = sizeof(java::lang::String);
+ obj->count = len;
+ return obj;
+}
+
+jstring
+_Jv_NewString(const jchar *chars, jsize len)
+{
+ jstring str = _Jv_AllocString(len);
+ jchar* data = JvGetStringChars (str);
+ while (--len >= 0)
+ *data++ = *chars++;
+ return str;
+}
+
+jstring
+_Jv_NewStringLatin1(const char *bytes, jsize len)
+{
+ jstring str = JvAllocString(len);
+ jchar* data = JvGetStringChars (str);
+ while (--len >= 0)
+ *data++ = *(unsigned char*)bytes++;
+ return str;
+}
+
+void
+java::lang::String::init ()
+{
+ count = 0;
+ boffset = sizeof(java::lang::String);
+ data = this;
+}
+
+void
+java::lang::String::init(jcharArray chars, jint offset, jint count,
+ jboolean dont_copy)
+{
+ if (! chars)
+ JvThrow (new NullPointerException);
+ jsize data_size = JvGetArrayLength (chars);
+ if (offset < 0 || count < 0 || offset + count > data_size)
+ JvThrow (new StringIndexOutOfBoundsException());
+ jcharArray array;
+ jchar *pdst;
+ if (! dont_copy)
+ {
+ array = JvNewCharArray(count);
+ pdst = elements (array);
+ memcpy (pdst, elements (chars) + offset, count * sizeof (jchar));
+ }
+ else
+ {
+ JvAssert (offset == 0);
+ array = chars;
+ pdst = elements (array);
+ }
+
+ data = array;
+ boffset = (char *) pdst - (char *) array;
+ this->count = count;
+}
+
+void
+java::lang::String::init(jbyteArray ascii, jint hibyte, jint offset,
+ jint count)
+{
+ if (! ascii)
+ JvThrow (new NullPointerException);
+ jsize data_size = JvGetArrayLength (ascii);
+ if (offset < 0 || count < 0 || offset + count < 0
+ || offset + count > data_size)
+ JvThrow (new java::lang::StringIndexOutOfBoundsException());
+ jcharArray array = JvNewCharArray(count);
+ jbyte *psrc = elements (ascii) + offset;
+ jchar *pdst = elements (array);
+ data = array;
+ boffset = (char *) pdst - (char *) array;
+ this->count = count;
+ hibyte = (hibyte & 0xff) << 8;
+ while (-- count >= 0)
+ {
+ *pdst++ = hibyte | (*psrc++ & 0xff);
+ }
+}
+
+void
+java::lang::String::init (jbyteArray bytes, jint offset, jint count,
+ jstring encoding)
+{
+ if (! bytes)
+ JvThrow (new NullPointerException);
+ jsize data_size = JvGetArrayLength (bytes);
+ if (offset < 0 || count < 0 || offset + count < 0
+ || offset + count > data_size)
+ JvThrow (new StringIndexOutOfBoundsException);
+
+ java::io::ByteArrayInputStream *b
+ = new java::io::ByteArrayInputStream (bytes, offset, count);
+ java::io::InputStreamReader *ir
+ = new java::io::InputStreamReader (b, encoding);
+ // FIXME: we allocate too much here in some cases.
+ jcharArray array = JvNewCharArray (count);
+ data = array;
+ boffset = (char *) elements (array) - (char *) array;
+ // FIXME: this can throw IOException.
+ this->count = ir->read(array, 0, count);
+}
+
+jboolean
+java::lang::String::equals(jobject anObject)
+{
+ if (anObject == NULL)
+ return false;
+ if (anObject == this)
+ return true;
+ if (anObject->getClass() != &StringClass)
+ return false;
+ jstring other = (jstring) anObject;
+ if (count != other->count)
+ return false;
+ /* if both are interned, return false. */
+ register jint i = count;
+ register jchar *xptr = JvGetStringChars (this);
+ register jchar *yptr = JvGetStringChars (other);
+ while (--i >= 0)
+ {
+ if (*xptr++ != *yptr++)
+ return false;
+ }
+ return true;
+}
+
+jchar
+java::lang::String::charAt(jint i)
+{
+ if (i < 0 || i >= count)
+ JvThrow (new java::lang::StringIndexOutOfBoundsException());
+ return JvGetStringChars(this)[i];
+}
+
+void
+java::lang::String::getChars(jint srcBegin, jint srcEnd,
+ jcharArray dst, jint dstBegin)
+{
+ jint dst_length = JvGetArrayLength (dst);
+ if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count
+ || dstBegin < 0 || dstBegin + (srcEnd-srcBegin) > dst_length)
+ JvThrow (new java::lang::ArrayIndexOutOfBoundsException());
+ register jchar *dPtr = elements (dst) + dstBegin;
+ register jchar *sPtr = JvGetStringChars (this) + srcBegin;
+ register jint i = srcEnd-srcBegin;
+ while (--i >= 0)
+ *dPtr++ = *sPtr++;
+}
+
+jbyteArray
+java::lang::String::getBytes (jstring enc)
+{
+ java::io::ByteArrayOutputStream *os
+ = new java::io::ByteArrayOutputStream(length ());
+ java::io::OutputStreamWriter *ow
+ = new java::io::OutputStreamWriter(os, enc);
+
+ ow->write(this, 0, length ());
+ ow->flush();
+
+ return os->toByteArray();
+}
+
+void
+java::lang::String::getBytes(jint srcBegin, jint srcEnd,
+ jbyteArray dst, jint dstBegin)
+{
+ jint dst_length = JvGetArrayLength (dst);
+ if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count
+ || dstBegin < 0 || dstBegin + (srcEnd-srcBegin) > dst_length)
+ JvThrow (new java::lang::ArrayIndexOutOfBoundsException());
+ register jbyte *dPtr = elements (dst) + dstBegin;
+ register jchar *sPtr = JvGetStringChars (this) + srcBegin;
+ register jint i = srcEnd-srcBegin;
+ while (--i >= 0)
+ *dPtr++ = (jbyte) *sPtr++;
+}
+
+jcharArray
+java::lang::String::toCharArray()
+{
+ jcharArray array = JvNewCharArray(count);
+ register jchar *dPtr = elements (array);
+ register jchar *sPtr = JvGetStringChars (this);
+ register jint i = count;
+ while (--i >= 0)
+ *dPtr++ = *sPtr++;
+ return array;
+}
+
+jboolean
+java::lang::String::equalsIgnoreCase (jstring anotherString)
+{
+ if (count != anotherString->count)
+ return false;
+ register jchar *tptr = JvGetStringChars (this);
+ register jchar *optr = JvGetStringChars (anotherString);
+ register jint i = count;
+ while (--i >= 0)
+ {
+ jchar tch = *tptr++;
+ jchar och = *optr++;
+ if (tch != och
+ && (java::lang::Character::toLowerCase (tch)
+ != java::lang::Character::toLowerCase (och))
+ && (java::lang::Character::toUpperCase (tch)
+ != java::lang::Character::toUpperCase (och)))
+ return false;
+ }
+ return true;
+}
+
+jboolean
+java::lang::String::regionMatches (jint toffset,
+ jstring other, jint ooffset, jint len)
+{
+ if (toffset < 0 || ooffset < 0
+ || toffset + len > count
+ || ooffset + len > other->count)
+ return false;
+ register jchar *tptr = JvGetStringChars (this) + toffset;
+ register jchar *optr = JvGetStringChars (other) + ooffset;
+ register jint i = len;
+ while (--i >= 0)
+ {
+ if (*tptr++ != *optr++)
+ return false;
+ }
+ return true;
+}
+
+jint
+java::lang::String::compareTo (jstring anotherString)
+{
+ register jchar *tptr = JvGetStringChars (this);
+ register jchar *optr = JvGetStringChars (anotherString);
+ jint tlen = this->count;
+ jint olen = anotherString->count;
+ register jint i = tlen > olen ? olen : tlen;
+ while (--i >= 0)
+ {
+ jchar tch = *tptr++;
+ jchar och = *optr++;
+ if (tch != och)
+ return (jint) tch - (jint) och;
+ }
+ return tlen - olen;
+}
+
+jboolean
+java::lang::String::regionMatches (jboolean ignoreCase, jint toffset,
+ jstring other, jint ooffset, jint len)
+{
+ if (toffset < 0 || ooffset < 0
+ || toffset + len > count
+ || ooffset + len > other->count)
+ return false;
+ register jchar *tptr = JvGetStringChars (this) + toffset;
+ register jchar *optr = JvGetStringChars (other) + ooffset;
+ register jint i = len;
+ while (--i >= 0)
+ {
+ jchar tch = *tptr++;
+ jchar och = *optr++;
+ if (tch != och)
+ return false;
+ if (ignoreCase
+ && (java::lang::Character::toLowerCase (tch)
+ != java::lang::Character::toLowerCase (och))
+ && (java::lang::Character::toUpperCase (tch)
+ != java::lang::Character::toUpperCase (och)))
+ return false;
+ }
+ return true;
+}
+
+jboolean
+java::lang::String::startsWith (jstring prefix, jint toffset)
+{
+ register jint i = prefix->count;
+ if (toffset < 0 || toffset + i > count)
+ return false;
+ register jchar *xptr = JvGetStringChars (this) + toffset;
+ register jchar *yptr = JvGetStringChars (prefix);
+ while (--i >= 0)
+ {
+ if (*xptr++ != *yptr++)
+ return false;
+ }
+ return true;
+}
+
+jint
+java::lang::String::indexOf (jint ch, jint fromIndex)
+{
+ if (fromIndex < 0)
+ fromIndex = 0;
+ register jchar *ptr = JvGetStringChars(this);
+ for (;; ++fromIndex)
+ {
+ if (fromIndex >= count)
+ return -1;
+ if (ptr[fromIndex] == ch)
+ return fromIndex;
+ }
+}
+
+jint
+java::lang::String::indexOf (jstring s, jint fromIndex)
+{
+ const jchar *const xchars = JvGetStringChars(s);
+ const jchar *const ychars = JvGetStringChars(this) + fromIndex;
+
+ const int xlength = s->length ();
+ const int ylength = length () - fromIndex;
+
+ int i = 0;
+ int j = 0;
+
+ while (i < ylength && j < xlength)
+ {
+ if (xchars[j] != ychars[i])
+ {
+ i = i - j + 1;
+ j = 0;
+ }
+ else
+ i++, j++;
+ }
+
+ if (j >= xlength)
+ return fromIndex + i - xlength;
+ else
+ return -1;
+}
+
+jint
+java::lang::String::lastIndexOf (jint ch, jint fromIndex)
+{
+ if (fromIndex >= count)
+ fromIndex = count - 1;
+ register jchar *ptr = JvGetStringChars(this);
+ for (;; --fromIndex)
+ {
+ if (fromIndex < 0)
+ return -1;
+ if (ptr[fromIndex] == ch)
+ return fromIndex;
+ }
+}
+
+jstring
+java::lang::String::substring (jint beginIndex, jint endIndex)
+{
+ if (beginIndex < 0 || endIndex > count || beginIndex > endIndex)
+ JvThrow (new StringIndexOutOfBoundsException());
+ jint newCount = endIndex - beginIndex;
+ if (newCount <= 8) // Optimization, mainly for GC.
+ return JvNewString(JvGetStringChars(this) + beginIndex, newCount);
+ jstring s = new String();
+ s->data = data;
+ s->count = newCount;
+ s->boffset = boffset + sizeof(jchar) * beginIndex;
+ return s;
+}
+
+jstring
+java::lang::String::concat(jstring str)
+{
+ jint str_count = str->count;
+ if (str_count == 0)
+ return this;
+ jstring result = JvAllocString(count + str_count);
+ register jchar *dstPtr = JvGetStringChars(result);
+ register jchar *srcPtr = JvGetStringChars(this);
+ register jint i = count;
+ while (--i >= 0)
+ *dstPtr++ = *srcPtr++;
+ srcPtr = JvGetStringChars(str);
+ i = str->count;
+ while (--i >= 0)
+ *dstPtr++ = *srcPtr++;
+ return result;
+}
+
+jstring
+java::lang::String::replace (jchar oldChar, jchar newChar)
+{
+ jint i;
+ jchar* chrs = JvGetStringChars (this);
+ for (i = 0; ; i++)
+ {
+ if (i == count)
+ return this;
+ if (chrs[i] == oldChar)
+ break;
+ }
+ jstring result = JvAllocString (count);
+ jchar *dPtr = JvGetStringChars (result);
+ for (int j = 0; j < i; j++)
+ *dPtr++ = chrs[j];
+ for (; i < count; i++)
+ {
+ jchar ch = chrs[i];
+ if (ch == oldChar)
+ ch = newChar;
+ *dPtr++ = ch;
+ }
+ return result;
+}
+
+jstring
+java::lang::String::toLowerCase ()
+{
+ jint i;
+ jchar* chrs = JvGetStringChars(this);
+ jchar ch;
+ for (i = 0; ; i++)
+ {
+ if (i == count)
+ return this;
+ jchar origChar = chrs[i];
+ ch = java::lang::Character::toLowerCase(origChar);
+ if (ch != origChar)
+ break;
+ }
+ jstring result = JvAllocString(count);
+ jchar *dPtr = JvGetStringChars (result);
+ for (int j = 0; j < i; j++)
+ *dPtr++ = chrs[j];
+ *dPtr++ = ch; i++;
+ for (; i < count; i++)
+ {
+ *dPtr++ = java::lang::Character::toLowerCase(chrs[i]);
+ }
+ return result;
+}
+
+jstring
+java::lang::String::toUpperCase ()
+{
+ jint i;
+ jchar* chrs = JvGetStringChars(this);
+ jchar ch;
+ for (i = 0; ; i++)
+ {
+ if (i == count)
+ return this;
+ jchar origChar = chrs[i];
+ ch = java::lang::Character::toUpperCase(origChar);
+ if (ch != origChar)
+ break;
+ }
+ jstring result = JvAllocString(count);
+ jchar *dPtr = JvGetStringChars (result);
+ for (int j = 0; j < i; j++)
+ *dPtr++ = chrs[j];
+ *dPtr++ = ch; i++;
+ for (; i < count; i++)
+ {
+ *dPtr++ = java::lang::Character::toUpperCase(chrs[i]);
+ }
+ return result;
+}
+
+jstring
+java::lang::String::trim ()
+{
+ jchar* chrs = JvGetStringChars(this);
+ if (count == 0 || (chrs[0] > ' ' && chrs[count-1] > ' '))
+ return this;
+ jint preTrim = 0;
+ for (;; preTrim++)
+ {
+ if (preTrim == count)
+ return new String();
+ if (chrs[preTrim] > ' ')
+ break;
+ }
+ jint endTrim = count;
+ while (chrs[endTrim-1] <= ' ')
+ endTrim--;
+ return substring(preTrim, endTrim);
+}
+
+jstring
+java::lang::String::valueOf(jcharArray data, jint offset, jint count)
+{
+ jint data_length = JvGetArrayLength (data);
+ if (offset < 0 || count < 0 || offset+count > data_length)
+ JvThrow (new java::lang::IndexOutOfBoundsException());
+ register jstring result = JvAllocString(count);
+ register jchar *sPtr = elements (data) + offset;
+ register jchar *dPtr = JvGetStringChars(result);
+ while (--count >= 0)
+ *dPtr++ = *sPtr++;
+ return result;
+}
+
+jstring
+java::lang::String::valueOf(jchar c)
+{
+ register jstring result = JvAllocString(1);
+ JvGetStringChars (result)[0] = c;
+ return result;
+}
diff --git a/libjava/java/lang/natSystem.cc b/libjava/java/lang/natSystem.cc
new file mode 100644
index 00000000000..5f613d53ead
--- /dev/null
+++ b/libjava/java/lang/natSystem.cc
@@ -0,0 +1,259 @@
+// natSystem.cc - Native code implementing System class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#ifdef HAVE_GETPWUID_R
+#define _POSIX_PTHREAD_SEMANTICS
+#ifndef _REENTRANT
+#define _REENTRANT
+#endif
+#endif
+
+#include <string.h>
+#include <time.h>
+#include <stdlib.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#include <errno.h>
+
+#include <cni.h>
+#include <jvm.h>
+#include <java/lang/System.h>
+#include <java/lang/Class.h>
+#include <java/lang/ArrayStoreException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/util/Properties.h>
+#include <java/io/PrintStream.h>
+#include <java/io/InputStream.h>
+
+
+
+#if defined (ECOS)
+extern "C" unsigned long long _clock (void);
+#endif
+
+void
+java::lang::System::setErr (java::io::PrintStream *newErr)
+{
+ checkSetIO ();
+ // This violates `final' semantics. Oh well.
+ err = newErr;
+}
+
+void
+java::lang::System::setIn (java::io::InputStream *newIn)
+{
+ checkSetIO ();
+ // This violates `final' semantics. Oh well.
+ in = newIn;
+}
+
+void
+java::lang::System::setOut (java::io::PrintStream *newOut)
+{
+ checkSetIO ();
+ // This violates `final' semantics. Oh well.
+ out = newOut;
+}
+
+void
+java::lang::System::arraycopy (jobject src, jint src_offset,
+ jobject dst, jint dst_offset,
+ jint count)
+{
+ if (! src || ! dst)
+ _Jv_Throw (new NullPointerException);
+
+ jclass src_c = src->getClass();
+ jclass dst_c = dst->getClass();
+ jclass src_comp = src_c->getComponentType();
+ jclass dst_comp = dst_c->getComponentType();
+
+ if (! src_c->isArray() || ! dst_c->isArray()
+ || src_comp->isPrimitive() != dst_comp->isPrimitive()
+ || (src_comp->isPrimitive() && src_comp != dst_comp))
+ _Jv_Throw (new ArrayStoreException);
+
+ __JArray *src_a = (__JArray *) src;
+ __JArray *dst_a = (__JArray *) dst;
+ if (src_offset < 0 || dst_offset < 0 || count < 0
+ || src_offset + count > src_a->length
+ || dst_offset + count > dst_a->length)
+ _Jv_Throw (new ArrayIndexOutOfBoundsException);
+
+ // Do-nothing cases.
+ if ((src == dst && src_offset == dst_offset)
+ || ! count)
+ return;
+
+ // If both are primitive, we can optimize trivially. If DST
+ // components are always assignable from SRC components, then we
+ // will never need to raise an error, and thus can do the
+ // optimization. If source and destinations are the same, then we
+ // know that the assignability premise always holds.
+ const bool prim = src_comp->isPrimitive();
+ if (prim || dst_comp->isAssignableFrom(src_comp) || src == dst)
+ {
+ const size_t size = prim ? src_comp->size()
+ : sizeof elements((jobjectArray)src)[0];
+
+ // We need a particular type to get the pointer to the data. So
+ // we choose bytes.
+ char *src_elts = (((char *) elements ((jbyteArray) src))
+ + src_offset * size);
+ char *dst_elts = (((char *) elements ((jbyteArray) dst))
+ + dst_offset * size);
+ // We don't bother trying memcpy. It can't be worth the cost of
+ // the check.
+ memmove ((void *) dst_elts, (void *) src_elts, count * size);
+ }
+ else
+ {
+ jobject *src_elts = elements ((jobjectArray) src_a) + src_offset;
+ jobject *dst_elts = elements ((jobjectArray) dst_a) + dst_offset;
+
+ for (int i = 0; i < count; ++i)
+ {
+ if (*src_elts
+ && ! dst_comp->isAssignableFrom((*src_elts)->getClass()))
+ _Jv_Throw (new ArrayStoreException);
+ *dst_elts++ = *src_elts++;
+ }
+ }
+}
+
+jlong
+java::lang::System::currentTimeMillis (void)
+{
+ jlong r;
+
+#if defined (HAVE_GETTIMEOFDAY)
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ r = (jlong) tv.tv_sec * 1000 + tv.tv_usec / 1000;
+#elif defined (HAVE_TIME)
+ r = time (NULL) * 1000;
+#elif defined (HAVE_FTIME)
+ struct timeb t;
+ ftime (&t);
+ r = t.time * 1000 + t.millitm;
+#elif defined (ECOS)
+ r = _clock();
+#else
+ // In the absence of any function, time remains forever fixed.
+ r = 23;
+#endif
+
+ return r;
+}
+
+jint
+java::lang::System::identityHashCode (jobject obj)
+{
+ return _Jv_HashCode (obj);
+}
+
+void
+java::lang::System::init_properties (void)
+{
+ if (prop_init)
+ return;
+ prop_init = true;
+
+ properties = new java::util::Properties ();
+ // A convenience define.
+#define SET(Prop,Val) \
+ properties->put(JvNewStringLatin1 (Prop), JvNewStringLatin1 (Val))
+ SET ("java.version", "FIXME");
+ SET ("java.vendor", "Cygnus Solutions");
+ SET ("java.vendor.url", "http://www.cygnus.com/");
+ // SET ("java.home", "FIXME");
+ // SET ("java.class.version", "FIXME");
+ // SET ("java.class.path", "FIXME");
+ SET ("os.name", "FIXME");
+ SET ("os.arch", "FIXME");
+ SET ("os.version", "FIXME");
+ SET ("file.encoding", "8859_1"); // FIXME
+#ifdef WIN32
+ SET ("file.separator", "\\");
+ SET ("path.separator", ";");
+ SET ("line.separator", "\r\n");
+#else
+ // Unix.
+ SET ("file.separator", "/");
+ SET ("path.separator", ":");
+ SET ("line.separator", "\n");
+#endif
+
+#ifdef HAVE_PWD_H
+ uid_t user_id = getuid ();
+ struct passwd *pwd_entry;
+
+#ifdef HAVE_GETPWUID_R
+ struct passwd pwd_r;
+ size_t len_r = 200;
+ char *buf_r = (char *) _Jv_AllocBytes (len_r);
+
+ while (buf_r != NULL)
+ {
+ int r = getpwuid_r (user_id, &pwd_r, buf_r, len_r, &pwd_entry);
+ if (r == 0)
+ break;
+ else if (r != ERANGE)
+ {
+ pwd_entry = NULL;
+ break;
+ }
+ len_r *= 2;
+ buf_r = (char *) _Jv_AllocBytes (len_r);
+ }
+#else
+ struct passwd *pwd_entry = getpwuid (user_id);
+#endif /* HAVE_GETPWUID_R */
+
+ if (pwd_entry != NULL)
+ {
+ SET ("user.name", pwd_entry->pw_name);
+ SET ("user.home", pwd_entry->pw_dir);
+ }
+#endif /* HAVE_PWD_H */
+
+#ifdef HAVE_UNISTD_H
+ /* Use getcwd to set "user.dir". */
+ int buflen = 250;
+ char *buffer = (char *) malloc (buflen);
+ while (buffer != NULL)
+ {
+ if (getcwd (buffer, buflen) != NULL)
+ {
+ SET ("user.dir", buffer);
+ break;
+ }
+ if (errno != ERANGE)
+ break;
+ buflen = 2 * buflen;
+ buffer = (char *) realloc (buffer, buflen);
+ }
+ if (buffer != NULL)
+ free (buffer);
+#endif
+}
diff --git a/libjava/java/lang/natThread.cc b/libjava/java/lang/natThread.cc
new file mode 100644
index 00000000000..117191133a8
--- /dev/null
+++ b/libjava/java/lang/natThread.cc
@@ -0,0 +1,295 @@
+// natThread.cc - Native part of Thread class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <cni.h>
+#include <jvm.h>
+#include <java/lang/Thread.h>
+#include <java/lang/ThreadGroup.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IllegalThreadStateException.h>
+#include <java/lang/InterruptedException.h>
+#include <java/lang/NullPointerException.h>
+
+
+
+// This structure is used to represent all the data the native side
+// needs. An object of this type is assigned to the `data' member of
+// the Thread class.
+struct natThread
+{
+ // These are used to interrupt sleep and join calls. We can share a
+ // condition variable here since this thread can either be sleeping
+ // or waiting for a thread exit, but not both.
+ _Jv_Mutex_t interrupt_mutex;
+ _Jv_ConditionVariable_t interrupt_cond;
+
+ // This is private data for the thread system layer.
+ _Jv_Thread_t *thread;
+
+ // All threads waiting to join this thread are linked together and
+ // waiting on their respective `interrupt' condition variables.
+ // When this thread exits, it notifies each such thread by
+ // signalling the condition. In this case the `interrupt_flag' is
+ // not set; this is how the waiting thread knows whether the join
+ // has failed or whether it should throw an exception.
+ struct natThread *joiner;
+
+ // Chain for waiters.
+ struct natThread *next;
+};
+
+// This is called from the constructor to initialize the native side
+// of the Thread.
+void
+java::lang::Thread::initialize_native (void)
+{
+ // FIXME: this must interact with the GC in some logical way. At
+ // the very least we must register a finalizer to clean up. This
+ // isn't easy to do. If the Thread object resurrects itself in its
+ // own finalizer then we will need to reinitialize this structure at
+ // any "interesting" point.
+ natThread *nt = (natThread *) _Jv_AllocBytes (sizeof (natThread));
+ data = (jobject) nt;
+ _Jv_MutexInit (&nt->interrupt_mutex);
+ _Jv_CondInit (&nt->interrupt_cond);
+ _Jv_ThreadInitData (&nt->thread, this);
+ nt->joiner = 0;
+ nt->next = 0;
+}
+
+jint
+java::lang::Thread::countStackFrames (void)
+{
+ // NOTE: This is deprecated in JDK 1.2.
+ JvFail ("java::lang::Thread::countStackFrames unimplemented");
+ return 0;
+}
+
+java::lang::Thread *
+java::lang::Thread::currentThread (void)
+{
+ return _Jv_ThreadCurrent ();
+}
+
+// FIXME: this is apparently the only way a thread can be removed from
+// a ThreadGroup. That seems wrong.
+void
+java::lang::Thread::destroy (void)
+{
+ // NOTE: This is marked as unimplemented in the JDK 1.2
+ // documentation.
+ JvFail ("java::lang::Thread::destroy unimplemented");
+}
+
+void
+java::lang::Thread::dumpStack (void)
+{
+ // We don't implement this because it is very hard. Once we have a
+ // VM, this could potentially ask the VM to do the dump in cases
+ // where it makes sense.
+ JvFail ("java::lang::Thread::dumpStack unimplemented");
+}
+
+void
+java::lang::Thread::interrupt (void)
+{
+ interrupt_flag = true;
+
+ // Wake up this thread, whether it is sleeping or waiting for
+ // another thread to exit.
+ natThread *nt = (natThread *) data;
+ _Jv_MutexLock (&nt->interrupt_mutex);
+ _Jv_CondNotify (&nt->interrupt_cond, &nt->interrupt_mutex);
+ _Jv_MutexUnlock (&nt->interrupt_mutex);
+
+ _Jv_ThreadInterrupt (nt->thread);
+}
+
+void
+java::lang::Thread::join (jlong millis, jint nanos)
+{
+ // FIXME: what if we are trying to join ourselves with no timeout?
+
+ if (millis < 0 || nanos < 0 || nanos > 999999)
+ _Jv_Throw (new IllegalArgumentException);
+
+ Thread *current = currentThread ();
+ if (current->isInterrupted ())
+ _Jv_Throw (new InterruptedException);
+
+ // Update the list of all threads waiting for this thread to exit.
+ // We grab a mutex when doing this in order to ensure that the
+ // required state changes are atomic.
+ _Jv_MonitorEnter (this);
+ if (! isAlive ())
+ {
+ _Jv_MonitorExit (this);
+ return;
+ }
+
+ // Here `CURR_NT' is the native structure for the currently
+ // executing thread, while `NT' is the native structure for the
+ // thread we are trying to join.
+ natThread *curr_nt = (natThread *) current->data;
+ natThread *nt = (natThread *) data;
+
+ JvAssert (curr_nt->next == NULL);
+ // Put thread CURR_NT onto NT's list. When NT exits, it will
+ // traverse its list and notify all joiners.
+ curr_nt->next = nt->joiner;
+ nt->joiner = curr_nt;
+ _Jv_MonitorExit (this);
+
+
+ // Now wait for: (1) an interrupt, (2) the thread to exit, or (3)
+ // the timeout to occur.
+ _Jv_MutexLock (&curr_nt->interrupt_mutex);
+ _Jv_CondWait (&curr_nt->interrupt_cond,
+ &curr_nt->interrupt_mutex,
+ millis, nanos);
+ _Jv_MutexUnlock (&curr_nt->interrupt_mutex);
+
+ // Now the join has completed, one way or another. Update the
+ // joiners list to account for this.
+ _Jv_MonitorEnter (this);
+ JvAssert (nt->joiner != NULL);
+ natThread *prev = 0;
+ natThread *t;
+ for (t = nt->joiner; t != NULL; t = t->next)
+ {
+ if (t == curr_nt)
+ {
+ if (prev)
+ prev->next = t->next;
+ else
+ nt->joiner = t->next;
+ t->next = 0;
+ break;
+ }
+ }
+ JvAssert (t != NULL);
+ _Jv_MonitorExit (this);
+
+ if (current->isInterrupted ())
+ _Jv_Throw (new InterruptedException);
+}
+
+void
+java::lang::Thread::resume (void)
+{
+ checkAccess ();
+ JvFail ("java::lang::Thread::resume unimplemented");
+}
+
+void
+java::lang::Thread::setPriority (jint newPriority)
+{
+ checkAccess ();
+ if (newPriority < MIN_PRIORITY || newPriority > MAX_PRIORITY)
+ _Jv_Throw (new IllegalArgumentException);
+
+ jint gmax = group->getMaxPriority();
+ if (newPriority > gmax)
+ newPriority = gmax;
+
+ priority = newPriority;
+ natThread *nt = (natThread *) data;
+ _Jv_ThreadSetPriority (nt->thread, priority);
+}
+
+void
+java::lang::Thread::sleep (jlong millis, jint nanos)
+{
+ if (millis < 0 || nanos < 0 || nanos > 999999)
+ _Jv_Throw (new IllegalArgumentException);
+
+ Thread *current = currentThread ();
+ if (current->isInterrupted ())
+ _Jv_Throw (new InterruptedException);
+
+ // We use a condition variable to implement sleeping so that an
+ // interrupt can wake us up.
+ natThread *nt = (natThread *) current->data;
+ _Jv_MutexLock (&nt->interrupt_mutex);
+ _Jv_CondWait (&nt->interrupt_cond, &nt->interrupt_mutex,
+ millis, nanos);
+ _Jv_MutexUnlock (&nt->interrupt_mutex);
+
+ if (current->isInterrupted ())
+ _Jv_Throw (new InterruptedException);
+}
+
+void
+java::lang::Thread::finish_ (void)
+{
+ // Notify all threads waiting to join this thread.
+ _Jv_MonitorEnter (this);
+ alive_flag = false;
+
+ // Note that we don't bother cleaning up the joiner list here. That
+ // is taken care of when each thread wakes up again.
+ natThread *nt = (natThread *) data;
+ for (natThread *t = nt->joiner; t != NULL; t = t->next)
+ {
+ _Jv_MutexLock (&t->interrupt_mutex);
+ _Jv_CondNotify (&t->interrupt_cond, &t->interrupt_mutex);
+ _Jv_MutexUnlock (&t->interrupt_mutex);
+ }
+
+ _Jv_MonitorExit (this);
+}
+
+void
+java::lang::Thread::run__ (jobject obj)
+{
+ java::lang::Thread *thread = (java::lang::Thread *) obj;
+ thread->run_ ();
+}
+
+void
+java::lang::Thread::start (void)
+{
+ JvSynchronize sync (this);
+
+ if (alive_flag)
+ _Jv_Throw (new IllegalThreadStateException);
+
+ alive_flag = true;
+ natThread *nt = (natThread *) data;
+ _Jv_ThreadStart (this, nt->thread, (_Jv_ThreadStartFunc *) &run__);
+}
+
+void
+java::lang::Thread::stop (java::lang::Throwable *e)
+{
+ JvSynchronize sync (this);
+ checkAccess ();
+ if (! e)
+ _Jv_Throw (new NullPointerException);
+ natThread *nt = (natThread *) data;
+ _Jv_ThreadCancel (nt->thread, e);
+}
+
+void
+java::lang::Thread::suspend (void)
+{
+ checkAccess ();
+ JvFail ("java::lang::Thread::suspend unimplemented");
+}
+
+void
+java::lang::Thread::yield (void)
+{
+ _Jv_ThreadYield ();
+}
diff --git a/libjava/java/lang/reflect/AccessibleObject.java b/libjava/java/lang/reflect/AccessibleObject.java
new file mode 100644
index 00000000000..8c869e167b0
--- /dev/null
+++ b/libjava/java/lang/reflect/AccessibleObject.java
@@ -0,0 +1,53 @@
+// AccessibleObject.java - Base for reflection objects.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang.reflect;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date December 12, 1998
+ */
+/* Written using JDK 1.2 beta docs.
+ * Status: Believed complete and correct.
+ */
+
+public class AccessibleObject
+{
+ protected AccessibleObject ()
+ {
+ flag = false;
+ }
+
+ boolean isAccessible ()
+ {
+ return flag;
+ }
+
+ static void setAccessible (AccessibleObject[] array, boolean flag)
+ {
+ checkPermission ();
+ for (int i = 0; i < array.length; ++i)
+ array[i].flag = flag;
+ }
+
+ void setAccessible (boolean flag)
+ {
+ checkPermission ();
+ this.flag = flag;
+ }
+
+ private static final void checkPermission ()
+ {
+ SecurityManager sm = System.getSecurityManager();
+ // FIXME: sm.checkPermission(ReflectPermission ("suppressAccessChecks"))
+ }
+
+ private boolean flag;
+}
diff --git a/libjava/java/lang/reflect/Array.java b/libjava/java/lang/reflect/Array.java
new file mode 100644
index 00000000000..398f80d5643
--- /dev/null
+++ b/libjava/java/lang/reflect/Array.java
@@ -0,0 +1,78 @@
+// FileDescriptor.java - Open file or device
+
+/* Copyright (C) 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang.reflect;
+
+/**
+ * @author Per Bothner <bothner@cygnus.com>
+ * @date january 12, 1999
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3.
+ * Status: Believe complete and correct.
+ */
+
+public final class Array
+{
+ Array () { }
+
+ public static native Object newInstance(Class componentType, int length);
+ public static native Object newInstance(Class elementType, int[] dimensions);
+ public static native int getLength (Object array);
+
+ public static native Object get (Object array, int index);
+ public static native char getChar (Object array, int index);
+ public static native byte getByte (Object array, int index);
+ public static native short getShort (Object array, int index);
+ public static native int getInt (Object array, int index);
+ public static native long getLong (Object array, int index);
+ public static native float getFloat (Object array, int index);
+ public static native double getDouble (Object array, int index);
+ public static native boolean getBoolean (Object array, int index);
+
+ private static native Class getElementType (Object array, int index);
+
+ private static native void set (Object array, int index,
+ Object value, Class elType);
+
+ public static void set (Object array, int index, Object value)
+ {
+ Class elType = getElementType(array, index);
+ if (! elType.isPrimitive())
+ set(array, index, value, elType);
+ else if (value instanceof Byte)
+ setByte(array, index, ((Byte) value).byteValue());
+ else if (value instanceof Short)
+ setShort (array, index, ((Short) value).shortValue());
+ else if (value instanceof Integer)
+ setInt(array, index, ((Integer) value).intValue());
+ else if (value instanceof Long)
+ setLong(array, index, ((Long) value).longValue());
+ else if (value instanceof Float)
+ setFloat(array, index, ((Float) value).floatValue());
+ else if (value instanceof Double)
+ setDouble(array, index, ((Double) value).doubleValue());
+ else if (value instanceof Character)
+ setChar(array, index, ((Character) value).charValue());
+ else if (value instanceof Boolean)
+ setBoolean(array, index, ((Boolean) value).booleanValue());
+ else
+ throw new IllegalArgumentException();
+ }
+
+ public static native void setByte (Object array, int index, byte value);
+ public static native void setShort (Object array, int index, short value);
+ public static native void setInt (Object array, int index, int value);
+ public static native void setLong (Object array, int index, long value);
+ public static native void setFloat (Object array, int index, float value);
+ public static native void setDouble (Object array, int index, double value);
+ public static native void setChar (Object array, int index, char value);
+ public static native void setBoolean(Object array, int index, boolean value);
+}
diff --git a/libjava/java/lang/reflect/Constructor.java b/libjava/java/lang/reflect/Constructor.java
new file mode 100644
index 00000000000..466c1204bae
--- /dev/null
+++ b/libjava/java/lang/reflect/Constructor.java
@@ -0,0 +1,106 @@
+// Constructor.java - Represents a constructor for a class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang.reflect;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date December 12, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Incomplete: needs a private constructor, and
+ * newInstance() needs to be written.
+ */
+
+public final class Constructor extends AccessibleObject implements Member
+{
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof Constructor))
+ return false;
+ Constructor c = (Constructor) obj;
+ return decl_class == c.decl_class && index == c.index;
+ }
+
+ public Class getDeclaringClass ()
+ {
+ return decl_class;
+ }
+
+ public Class[] getExceptionTypes ()
+ {
+ return (Class[]) exception_types.clone();
+ }
+
+ public int getModifiers ()
+ {
+ return modifiers;
+ }
+
+ public String getName ()
+ {
+ return decl_class.getName();
+ }
+
+ public Class[] getParameterTypes ()
+ {
+ return (Class[]) parameter_types.clone();
+ }
+
+ public int hashCode ()
+ {
+ // FIXME.
+ return getName().hashCode();
+ }
+
+ // FIXME: this must be native. Should share implementation with
+ // Method.invoke.
+ public Object newInstance (Object[] args)
+ throws InstantiationException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException
+ {
+ return null;
+ }
+
+ public String toString ()
+ {
+ StringBuffer b = new StringBuffer ();
+ b.append(Modifier.toString(modifiers));
+ b.append(" ");
+ b.append(getName());
+ b.append("(");
+ for (int i = 0; i < parameter_types.length; ++i)
+ {
+ b.append(parameter_types[i].toString());
+ if (i < parameter_types.length - 1)
+ b.append(",");
+ }
+ b.append(")");
+ return b.toString();
+ }
+
+ // Can't create these. FIXME.
+ private Constructor ()
+ {
+ }
+
+ // Declaring class.
+ private Class decl_class;
+ // Exception types.
+ private Class[] exception_types;
+ // Modifiers.
+ private int modifiers;
+ // Parameter types.
+ private Class[] parameter_types;
+ // Index of this method in declaring class' method table.
+ private int index;
+}
diff --git a/libjava/java/lang/reflect/Field.java b/libjava/java/lang/reflect/Field.java
new file mode 100644
index 00000000000..7c7e690926a
--- /dev/null
+++ b/libjava/java/lang/reflect/Field.java
@@ -0,0 +1,264 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang.reflect;
+
+/**
+ * @author Per Bothner <bothner@cygnus.com>
+ * @date September 1998; February 1999.
+ */
+/* Status: Mostly implemented.
+ * However, access checks are not implemented. See natField.cc for
+ * _Jv_CheckFieldAccessibility as well as the missing getCaller.
+ * Note that the idea is to have to compiler convert calls to
+ * setXXX(...) and getXXX(...) to setXXX(CALLER, ...) and getXXX(CALLER, ...),
+ * where CALLER is reference to the class that contains the calls to
+ * setXXX or getXXX. This is easy for the compiler, and replaces
+ * expensive stack and table searching with a constant.
+ */
+
+public final class Field extends AccessibleObject implements Member
+{
+ private Class declaringClass;
+
+ // This is filled in by getName.
+ private String name;
+
+ // Offset in bytes from the start of declaringClass's fields array.
+ private int offset;
+
+ public boolean equals (Object fld)
+ {
+ if (! (fld instanceof Field))
+ return false;
+ Field f = (Field) fld;
+ return declaringClass == f.declaringClass && offset == f.offset;
+ }
+
+ public Class getDeclaringClass ()
+ {
+ return declaringClass;
+ }
+
+ public native String getName ();
+
+ public native Class getType ();
+
+ public native int getModifiers ();
+
+ public int hashCode()
+ {
+ return (declaringClass.hashCode() ^ offset);
+ }
+
+ // The idea is that the compiler will magically translate
+ // fld.getShort(obj) to fld.getShort(THISCLASS, obj).
+ // This makes checking assessiblity more efficient,
+ // since we don't have to do any stack-walking.
+
+ public boolean getBoolean (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getBoolean(null, obj);
+ }
+ public char getChar (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getChar(null, obj);
+ }
+
+ public byte getByte (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getByte(null, obj);
+ }
+
+ public short getShort (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getShort(null, obj);
+ }
+
+ public int getInt (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getInt(null, obj);
+ }
+
+ public long getLong (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getLong(null, obj);
+ }
+
+ public float getFloat (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getFloat(null, obj);
+ }
+
+ public double getDouble (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return getDouble(null, obj);
+ }
+
+ public Object get (Object obj)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ return get(null, obj);
+ }
+
+ private native boolean getBoolean (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native char getChar (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native byte getByte (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native short getShort (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native int getInt (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native long getLong (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native float getFloat (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native double getDouble (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public native Object get (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public void setByte (Object obj, byte b)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setByte(null, obj, b);
+ }
+
+ public void setShort (Object obj, short s)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setShort(null, obj, s);
+ }
+
+ public void setInt (Object obj, int i)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setInt(null, obj, i);
+ }
+
+ public void setLong (Object obj, long l)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setLong(null, obj, l);
+ }
+
+ public void setFloat (Object obj, float f)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setFloat(null, obj, f);
+ }
+
+ public void setDouble (Object obj, double d)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setDouble(null, obj, d);
+ }
+
+ public void setChar (Object obj, char c)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setChar(null, obj, c);
+ }
+
+ public void setBoolean (Object obj, boolean b)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setBoolean(null, obj, b);
+ }
+
+ public native void setByte (Class caller, Object obj, byte b)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public native void setShort (Class caller, Object obj, short s)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public native void setInt (Class caller, Object obj, int i)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public native void setLong (Class caller, Object obj, long l)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public native void setFloat (Class caller, Object obj, float f)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public native void setDouble (Class caller, Object obj, double d)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public native void setChar (Class caller, Object obj, char c)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public native void setBoolean (Class caller, Object obj, boolean b)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native void set (Class caller, Object obj, Object val, Class type)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ public void set (Object object, Object value)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ set(null, object, value);
+ }
+
+ public void set (Class caller, Object object, Object value)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ Class type = getType();
+ if (! type.isPrimitive())
+ set(caller, object, value, type);
+ else if (value instanceof Byte)
+ setByte(caller, object, ((Byte) value).byteValue());
+ else if (value instanceof Short)
+ setShort (caller, object, ((Short) value).shortValue());
+ else if (value instanceof Integer)
+ setInt(caller, object, ((Integer) value).intValue());
+ else if (value instanceof Long)
+ setLong(caller, object, ((Long) value).longValue());
+ else if (value instanceof Float)
+ setFloat(caller, object, ((Float) value).floatValue());
+ else if (value instanceof Double)
+ setDouble(caller, object, ((Double) value).doubleValue());
+ else if (value instanceof Character)
+ setChar(caller, object, ((Character) value).charValue());
+ else if (value instanceof Boolean)
+ setBoolean(caller, object, ((Boolean) value).booleanValue());
+ else
+ throw new IllegalArgumentException();
+ }
+
+ public String toString ()
+ {
+ StringBuffer sbuf = new StringBuffer ();
+ int mods = getModifiers();
+ if (mods != 0)
+ Modifier.toString(mods, sbuf);
+ sbuf.append(getType());
+ sbuf.append(' ');
+ sbuf.append(getDeclaringClass());
+ sbuf.append('.');
+ sbuf.append(getName());
+ return sbuf.toString();
+ }
+}
diff --git a/libjava/java/lang/reflect/InvocationTargetException.java b/libjava/java/lang/reflect/InvocationTargetException.java
new file mode 100644
index 00000000000..eccd5f7daed
--- /dev/null
+++ b/libjava/java/lang/reflect/InvocationTargetException.java
@@ -0,0 +1,73 @@
+// InvocationTargetException.java - Wrapper exception for reflection.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang.reflect;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date December 12, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * Status: Believed complete and correct.
+ */
+
+public class InvocationTargetException extends Exception
+{
+ public Throwable getTargetException ()
+ {
+ return target;
+ }
+
+ protected InvocationTargetException ()
+ {
+ super ();
+ target = null;
+ }
+
+ public InvocationTargetException (Throwable exception)
+ {
+ super ();
+ target = exception;
+ }
+
+ public InvocationTargetException (Throwable exception, String msg)
+ {
+ super (msg);
+ target = exception;
+ }
+
+ // This is from JDK 1.2.
+ public void printStackTrace ()
+ {
+ if (target != null)
+ target.printStackTrace();
+ }
+
+ // This is from JDK 1.2.
+ public void printStackTrace (PrintStream s)
+ {
+ if (target != null)
+ target.printStackTrace(s);
+ }
+
+ // This is from JDK 1.2.
+ public void printStackTrace (PrintWriter wr)
+ {
+ if (target != null)
+ target.printStackTrace(wr);
+ }
+
+ // The wrapped exception. The name is specified by the
+ // serialization spec.
+ private Throwable target;
+}
diff --git a/libjava/java/lang/reflect/Member.java b/libjava/java/lang/reflect/Member.java
new file mode 100644
index 00000000000..a54f05f689e
--- /dev/null
+++ b/libjava/java/lang/reflect/Member.java
@@ -0,0 +1,26 @@
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang.reflect;
+
+/**
+ * @author Per Bothner <bothner@cygnus.com>
+ * @date September 27, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition.
+ * Status: Believed complete and correct.
+ */
+
+public interface Member
+{
+ public static final int PUBLIC = 0;
+ public static final int DECLARED = 1;
+ public Class getDeclaringClass ();
+ public int getModifiers ();
+ public String getName();
+}
diff --git a/libjava/java/lang/reflect/Method.java b/libjava/java/lang/reflect/Method.java
new file mode 100644
index 00000000000..01e830876e5
--- /dev/null
+++ b/libjava/java/lang/reflect/Method.java
@@ -0,0 +1,123 @@
+// Method.java - Represent method of class or interface.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang.reflect;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date December 12, 1998
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Incomplete: needs a private constructor, and
+ * invoke() needs to be finished.
+ */
+
+public final class Method extends AccessibleObject implements Member
+{
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof Method))
+ return false;
+ Method m = (Method) obj;
+ return declaringClass == m.declaringClass && offset == m.offset;
+ }
+
+ public Class getDeclaringClass ()
+ {
+ return declaringClass;
+ }
+
+ public Class[] getExceptionTypes ()
+ {
+ return (Class[]) exception_types.clone();
+ }
+
+ public native int getModifiers ();
+
+ public native String getName ();
+
+ private native void getType ();
+
+ public Class[] getParameterTypes ()
+ {
+ if (parameter_types == null)
+ getType();
+ return (Class[]) parameter_types.clone();
+ }
+
+ public Class getReturnType ()
+ {
+ if (return_type == null)
+ getType();
+ return return_type;
+ }
+
+ public int hashCode ()
+ {
+ // FIXME.
+ return name.hashCode() + declaringClass.getName().hashCode();
+ }
+
+ public native Object invoke (Object obj, Object[] args)
+ throws IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException;
+
+ public String toString ()
+ {
+ StringBuffer b = new StringBuffer ();
+ b.append(Modifier.toString(getModifiers()));
+ b.append(" ");
+ b.append(return_type.toString());
+ b.append(" ");
+ b.append(declaringClass.toString());
+ b.append(".");
+ b.append(name);
+ b.append("(");
+ for (int i = 0; i < parameter_types.length; ++i)
+ {
+ b.append(parameter_types[i].toString());
+ if (i < parameter_types.length - 1)
+ b.append(",");
+ }
+ b.append(")");
+ if (exception_types.length > 0)
+ {
+ b.append(" throws ");
+ for (int i = 0; i < exception_types.length; ++i)
+ {
+ b.append(exception_types[i].toString());
+ if (i < exception_types.length - 1)
+ b.append(",");
+ }
+ }
+ return b.toString();
+ }
+
+ private Method ()
+ {
+ }
+
+ // Declaring class.
+ private Class declaringClass;
+
+ // Exception types.
+ private Class[] exception_types;
+ // Name cache. (Initially null.)
+ private String name;
+ // Parameter types.
+ private Class[] parameter_types;
+ // Return type.
+ private Class return_type;
+
+ // Offset in bytes from the start of declaringClass's methods array.
+ private int offset;
+}
diff --git a/libjava/java/lang/reflect/Modifier.java b/libjava/java/lang/reflect/Modifier.java
new file mode 100644
index 00000000000..f9df49e80ee
--- /dev/null
+++ b/libjava/java/lang/reflect/Modifier.java
@@ -0,0 +1,130 @@
+// Modifier.java - Process modifier values.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date October 1, 1998
+ */
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct to version 1.1
+ */
+
+package java.lang.reflect;
+
+public class Modifier
+{
+ public static final int PUBLIC = 0x001;
+ public static final int PRIVATE = 0x002;
+ public static final int PROTECTED = 0x004;
+ public static final int STATIC = 0x008;
+ public static final int FINAL = 0x010;
+ public static final int SYNCHRONIZED = 0x020;
+ public static final int VOLATILE = 0x040;
+ public static final int TRANSIENT = 0x080;
+ public static final int NATIVE = 0x100;
+ public static final int INTERFACE = 0x200;
+ public static final int ABSTRACT = 0x400;
+
+ public static boolean isAbstract (int mod)
+ {
+ return (mod & ABSTRACT) != 0;
+ }
+
+ public static boolean isFinal (int mod)
+ {
+ return (mod & FINAL) != 0;
+ }
+
+ public static boolean isInterface (int mod)
+ {
+ return (mod & INTERFACE) != 0;
+ }
+
+ public static boolean isNative (int mod)
+ {
+ return (mod & NATIVE) != 0;
+ }
+
+ public static boolean isPrivate (int mod)
+ {
+ return (mod & PRIVATE) != 0;
+ }
+
+ public static boolean isProtected (int mod)
+ {
+ return (mod & PROTECTED) != 0;
+ }
+
+ public static boolean isPublic (int mod)
+ {
+ return (mod & PUBLIC) != 0;
+ }
+
+ public static boolean isStatic (int mod)
+ {
+ return (mod & STATIC) != 0;
+ }
+
+ public static boolean isSynchronized (int mod)
+ {
+ return (mod & SYNCHRONIZED) != 0;
+ }
+
+ public static boolean isTransient (int mod)
+ {
+ return (mod & TRANSIENT) != 0;
+ }
+
+ public static boolean isVolatile (int mod)
+ {
+ return (mod & VOLATILE) != 0;
+ }
+
+ public static String toString (int mod)
+ {
+ StringBuffer r = new StringBuffer ();
+ toString(mod, r);
+ return r.toString();
+ }
+
+ static void toString (int mod, StringBuffer r)
+ {
+ if (isPublic (mod))
+ r.append("public ");
+ if (isProtected (mod))
+ r.append("protected ");
+ if (isPrivate (mod))
+ r.append("private ");
+ if (isAbstract (mod))
+ r.append("abstract ");
+ if (isStatic (mod))
+ r.append("static ");
+ if (isFinal (mod))
+ r.append("final ");
+ if (isTransient (mod))
+ r.append("transient ");
+ if (isVolatile (mod))
+ r.append("volatile ");
+ if (isNative (mod))
+ r.append("native ");
+ if (isSynchronized (mod))
+ r.append("synchronized ");
+ if (isInterface (mod))
+ r.append("interface ");
+
+ // Trim trailing space.
+ int l = r.length();
+ if (l > 0)
+ r.setLength(l - 1);
+ }
+}
diff --git a/libjava/java/lang/reflect/natArray.cc b/libjava/java/lang/reflect/natArray.cc
new file mode 100644
index 00000000000..3da8b5c01ce
--- /dev/null
+++ b/libjava/java/lang/reflect/natArray.cc
@@ -0,0 +1,339 @@
+// natField.cc - Implementation of java.lang.reflect.Field native methods.
+
+/* Copyright (C) 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <jvm.h>
+#include <cni.h>
+#include <java/lang/reflect/Array.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+
+jobject
+java::lang::reflect::Array::newInstance (jclass componentType, jint length)
+{
+ if (componentType->isPrimitive())
+ return _Jv_NewPrimArray (componentType, length);
+ else
+ return JvNewObjectArray (length, componentType, NULL);
+
+}
+
+jobject
+java::lang::reflect::Array::newInstance (jclass componentType, jintArray dimensions)
+{
+ jint ndims = dimensions->length;
+ if (ndims == 0)
+ return componentType->newInstance ();
+ jint* dims = elements (dimensions);
+ if (ndims == 1)
+ return newInstance (componentType, dims[0]);
+ jclass arrayType = componentType;
+ for (int i = 0; i < ndims; i++)
+ arrayType = _Jv_FindArrayClass (arrayType);
+ return _Jv_NewMultiArray (arrayType, ndims, dims);
+
+}
+
+jint
+java::lang::reflect::Array::getLength (jobject array)
+{
+ jclass arrayType = array->getClass();
+ if (! arrayType->isArray ())
+ JvThrow (new java::lang::IllegalArgumentException());
+ return ((__JArray*) array)->length;
+}
+
+jclass
+java::lang::reflect::Array::getElementType (jobject array, jint index)
+{
+ jclass arrayType = array->getClass();
+ if (! arrayType->isArray ())
+ JvThrow (new java::lang::IllegalArgumentException());
+ jint length = ((__JArray*) array)->length;
+ if ((_Jv_uint) index >= (_Jv_uint) length)
+ _Jv_ThrowBadArrayIndex(index);
+ return arrayType->getComponentType ();
+}
+
+jboolean
+java::lang::reflect::Array::getBoolean (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (boolean))
+ return elements ((jbooleanArray) array) [index];
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+jchar
+java::lang::reflect::Array::getChar (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+jbyte
+java::lang::reflect::Array::getByte (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+jshort
+java::lang::reflect::Array::getShort (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+jint
+java::lang::reflect::Array::getInt (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+jlong
+java::lang::reflect::Array::getLong (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (long))
+ return elements ((jlongArray) array) [index];
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+jfloat
+java::lang::reflect::Array::getFloat (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (float))
+ return elements ((jfloatArray) array) [index];
+ if (elementType == JvPrimClass (long))
+ return elements ((jlongArray) array) [index];
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+jdouble
+java::lang::reflect::Array::getDouble (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (double))
+ return elements ((jdoubleArray) array) [index];
+ if (elementType == JvPrimClass (float))
+ return elements ((jfloatArray) array) [index];
+ if (elementType == JvPrimClass (long))
+ return elements ((jlongArray) array) [index];
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+jobject
+java::lang::reflect::Array::get (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (! elementType->isPrimitive ())
+ return elements ((jobjectArray) array) [index];
+ if (elementType == JvPrimClass (double))
+ return new java::lang::Double (elements ((jdoubleArray) array) [index]);
+ if (elementType == JvPrimClass (float))
+ return new java::lang::Float (elements ((jfloatArray) array) [index]);
+ if (elementType == JvPrimClass (long))
+ return new java::lang::Long (elements ((jlongArray) array) [index]);
+ if (elementType == JvPrimClass (int))
+ return new java::lang::Integer (elements ((jintArray) array) [index]);
+ if (elementType == JvPrimClass (short))
+ return new java::lang::Short (elements ((jshortArray) array) [index]);
+ if (elementType == JvPrimClass (byte))
+ return new java::lang::Byte (elements ((jbyteArray) array) [index]);
+ if (elementType == JvPrimClass (char))
+ return new java::lang::Character (elements ((jcharArray) array) [index]);
+ if (elementType == JvPrimClass (boolean))
+ if (elements ((jbooleanArray) array) [index])
+ return java::lang::Boolean::TRUE;
+ else
+ return java::lang::Boolean::FALSE;
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+void
+java::lang::reflect::Array::setChar (jobject array, jint index, jchar value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (char))
+ elements ((jcharArray) array) [index] = value;
+ else if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+void
+java::lang::reflect::Array::setByte (jobject array, jint index, jbyte value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (byte))
+ elements ((jbyteArray) array) [index] = value;
+ else if (elementType == JvPrimClass (short))
+ elements ((jshortArray) array) [index] = value;
+ else if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+void
+java::lang::reflect::Array::setShort (jobject array, jint index, jshort value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (short))
+ elements ((jshortArray) array) [index] = value;
+ else if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+void
+java::lang::reflect::Array::setInt (jobject array, jint index, jint value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+void
+java::lang::reflect::Array::setLong (jobject array, jint index, jlong value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+void
+java::lang::reflect::Array::setFloat (jobject array, jint index, jfloat value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+void
+java::lang::reflect::Array::setDouble (jobject array, jint index, jdouble value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+void
+java::lang::reflect::Array::setBoolean (jobject array,
+ jint index, jboolean value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (boolean))
+ elements ((jbooleanArray) array) [index] = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+void
+java::lang::reflect::Array::set (jobject array, jint index,
+ jobject value, jclass elType)
+{
+ if (! _Jv_IsInstanceOf (value, elType))
+ JvThrow (new java::lang::IllegalArgumentException ());
+ elements ((jobjectArray) array) [index] = value;
+}
diff --git a/libjava/java/lang/reflect/natField.cc b/libjava/java/lang/reflect/natField.cc
new file mode 100644
index 00000000000..2449b42545c
--- /dev/null
+++ b/libjava/java/lang/reflect/natField.cc
@@ -0,0 +1,435 @@
+// natField.cc - Implementation of java.lang.reflect.Field native methods.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <cni.h>
+#include <jvm.h>
+#include <java/lang/reflect/Field.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+#include <java-field.h>
+
+jint
+java::lang::reflect::Field::getModifiers ()
+{
+ return _Jv_FromReflectedField (this)->getModifiers ();
+}
+
+jstring
+java::lang::reflect::Field::getName ()
+{
+ if (name == NULL)
+ name = _Jv_NewStringUtf8Const (_Jv_FromReflectedField (this)->name);
+ return name;
+}
+
+jclass
+java::lang::reflect::Field::getType ()
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ if (! fld->isResolved())
+ {
+ JvSynchronize sync (declaringClass);
+ if (! fld->isResolved())
+ {
+ fld->type
+ = _Jv_FindClassFromSignature(((Utf8Const*) (fld->type))->data,
+ declaringClass->getClassLoader());
+ fld->flags &= ~_Jv_FIELD_UNRESOLVED_FLAG;
+ }
+ }
+ return fld->type;
+}
+
+static void
+_Jv_CheckFieldAccessibility (jfieldID /*fld*/, jclass /*caller*/)
+{
+#if 0
+ if (caller == NULL)
+ caller = getCaller();
+#endif
+#if 0
+ _Jv_ushort flags = fld->getModifiers();
+ check accesss;
+#endif
+}
+
+static void*
+getAddr (java::lang::reflect::Field* field, jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (field);
+ _Jv_ushort flags = fld->getModifiers();
+ if (! (flags & java::lang::reflect::Modifier::PUBLIC)
+ && ! field->isAccessible ())
+ _Jv_CheckFieldAccessibility (fld, caller);
+ if (flags & java::lang::reflect::Modifier::STATIC)
+ {
+ jclass fldClass = field->getDeclaringClass ();
+ JvInitClass(fldClass);
+ return fld->u.addr;
+ }
+ else
+ {
+ if (obj == NULL)
+ _Jv_Throw (new java::lang::NullPointerException ());
+ if (! _Jv_IsInstanceOf (obj, field->getDeclaringClass()))
+ JvThrow (new java::lang::IllegalArgumentException ());
+ return (void*) ((char*) obj + fld->getOffset ());
+ }
+}
+
+static jboolean
+getBoolean (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (boolean))
+ return * (jboolean *) addr;
+ _Jv_Throw (new java::lang::IllegalArgumentException());
+}
+
+static jchar
+getChar (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (char))
+ return * (jchar *) addr;
+ _Jv_Throw (new java::lang::IllegalArgumentException());
+}
+
+static jbyte
+getByte (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (byte))
+ return * (jbyte *) addr;
+ _Jv_Throw (new java::lang::IllegalArgumentException());
+}
+
+static jshort
+getShort (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (short))
+ return * (jshort *) addr;
+ if (cls == JvPrimClass (byte))
+ return * (jbyte *) addr;
+ _Jv_Throw (new java::lang::IllegalArgumentException());
+}
+
+static jint
+getInt (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (int))
+ return * (jint *) addr;
+ if (cls == JvPrimClass (short))
+ return * (jshort *) addr;
+ if (cls == JvPrimClass (char))
+ return * (jchar *) addr;
+ if (cls == JvPrimClass (byte))
+ return * (jbyte *) addr;
+ _Jv_Throw (new java::lang::IllegalArgumentException());
+}
+
+static jlong
+getLong (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (long))
+ return * (jlong *) addr;
+ return ::getInt(cls, addr);
+}
+
+static jfloat
+getFloat (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (float))
+ return * (jfloat *) addr;
+ if (cls == JvPrimClass (long))
+ return * (jlong *) addr;
+ return ::getInt(cls, addr);
+}
+
+static jdouble
+getDouble (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (double))
+ return * (jdouble *) addr;
+ if (cls == JvPrimClass (float))
+ return * (jfloat *) addr;
+ if (cls == JvPrimClass (long))
+ return * (jlong *) addr;
+ return ::getInt(cls, addr);
+}
+
+jboolean
+java::lang::reflect::Field::getBoolean (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getBoolean (fld->type, getAddr (this, caller, obj));
+}
+
+jchar
+java::lang::reflect::Field::getChar (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getChar (fld->type, getAddr (this, caller, obj));
+}
+
+jbyte
+java::lang::reflect::Field::getByte (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getByte (fld->type, getAddr (this, caller, obj));
+}
+
+jshort
+java::lang::reflect::Field::getShort (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getShort (fld->type, getAddr (this, caller, obj));
+}
+
+jint
+java::lang::reflect::Field::getInt (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getInt (fld->type, getAddr (this, caller, obj));
+}
+
+jlong
+java::lang::reflect::Field::getLong (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getLong (fld->type, getAddr (this, caller, obj));
+}
+
+jfloat
+java::lang::reflect::Field::getFloat (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getFloat (fld->type, getAddr (this, caller, obj));
+}
+
+jdouble
+java::lang::reflect::Field::getDouble (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ return ::getDouble (fld->type, getAddr (this, caller, obj));
+}
+
+jobject
+java::lang::reflect::Field::get (jclass caller, jobject obj)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ void* addr = getAddr (this, caller, obj);
+ if (! fld->type->isPrimitive ())
+ return * (jobject*) addr;
+ if (fld->type == JvPrimClass (double))
+ return new java::lang::Double (* (jdouble*) addr);
+ if (fld->type == JvPrimClass (float))
+ return new java::lang::Float (* (jfloat*) addr);
+ if (fld->type == JvPrimClass (long))
+ return new java::lang::Long (* (jlong*) addr);
+ if (fld->type == JvPrimClass (int))
+ return new java::lang::Integer (* (jint*) addr);
+ if (fld->type == JvPrimClass (short))
+ return new java::lang::Short (* (jshort*) addr);
+ if (fld->type == JvPrimClass (byte))
+ return new java::lang::Byte (* (jbyte*) addr);
+ if (fld->type == JvPrimClass (char))
+ return new java::lang::Character (* (jchar*) addr);
+ if (fld->type == JvPrimClass (boolean))
+ if (* (jboolean*) addr)
+ return java::lang::Boolean::TRUE;
+ else
+ return java::lang::Boolean::FALSE;
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+static void
+setBoolean (jclass type, void *addr, jboolean value)
+{
+ if (type == JvPrimClass (boolean))
+ * (jboolean *) addr = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+static void
+setChar (jclass type, void *addr, jchar value)
+{
+ if (type == JvPrimClass (char))
+ * (jchar *) addr = value;
+ else if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+static void
+setByte (jclass type, void *addr, jbyte value)
+{
+ if (type == JvPrimClass (byte))
+ * (jbyte *) addr = value;
+ else if (type == JvPrimClass (short))
+ * (jshort *) addr = value;
+ else if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+static void
+setShort (jclass type, void *addr, jshort value)
+{
+ if (type == JvPrimClass (short))
+ * (jshort *) addr = value;
+ else if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+static void
+setInt (jclass type, void *addr, jint value)
+{
+ if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+static void
+setLong (jclass type, void *addr, jlong value)
+{
+ if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+static void
+setFloat (jclass type, void *addr, jfloat value)
+{
+ if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+static void
+setDouble (jclass type, void *addr, jdouble value)
+{
+ if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ JvThrow (new java::lang::IllegalArgumentException());
+}
+
+void
+java::lang::reflect::Field::setBoolean (jclass caller, jobject obj, jboolean b)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setBoolean (fld->type, getAddr (this, caller, obj), b);
+}
+
+void
+java::lang::reflect::Field::setChar (jclass caller, jobject obj, jchar c)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setChar (fld->type, getAddr (this, caller, obj), c);
+}
+
+void
+java::lang::reflect::Field::setByte (jclass caller, jobject obj, jbyte b)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setByte (fld->type, getAddr (this, caller, obj), b);
+}
+
+void
+java::lang::reflect::Field::setShort (jclass caller, jobject obj, jshort s)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setShort (fld->type, getAddr (this, caller, obj), s);
+}
+
+void
+java::lang::reflect::Field::setInt (jclass caller, jobject obj, jint i)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setInt (fld->type, getAddr (this, caller, obj), i);
+}
+
+void
+java::lang::reflect::Field::setLong (jclass caller, jobject obj, jlong l)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setLong (fld->type, getAddr (this, caller, obj), l);
+}
+void
+java::lang::reflect::Field::setFloat (jclass caller, jobject obj, jfloat f)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setFloat (fld->type, getAddr (this, caller, obj), f);
+}
+
+void
+java::lang::reflect::Field::setDouble (jclass caller, jobject obj, jdouble d)
+{
+ jfieldID fld = _Jv_FromReflectedField (this);
+ ::setDouble (fld->type, getAddr (this, caller, obj), d);
+}
+
+void
+java::lang::reflect::Field::set (jclass caller, jobject object, jobject value, jclass type)
+{
+ if (! _Jv_IsInstanceOf (value, type))
+ JvThrow (new java::lang::IllegalArgumentException ());
+ void* addr = getAddr (this, caller, object);
+ * (jobject*) addr = value;
+}
diff --git a/libjava/java/lang/reflect/natMethod.cc b/libjava/java/lang/reflect/natMethod.cc
new file mode 100644
index 00000000000..720bbc3d74e
--- /dev/null
+++ b/libjava/java/lang/reflect/natMethod.cc
@@ -0,0 +1,386 @@
+// natMethod.cc - Native code for Method class.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// This is about 90% done. Search for FIXME to see what remains.
+
+#include <config.h>
+
+#include <cni.h>
+#include <jvm.h>
+#include <java-array.h>
+
+#include <java/lang/reflect/Method.h>
+#include <java/lang/reflect/InvocationTargetException.h>
+#include <java/lang/reflect/Modifier.h>
+
+#include <java/lang/Void.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Class.h>
+#include <java-method.h>
+
+#define ClassClass _CL_Q34java4lang5Class
+extern java::lang::Class ClassClass;
+
+#include <stdlib.h>
+
+#if 0
+
+#include <ffi.h>
+
+#define VoidClass _CL_Q34java4lang4Void
+extern java::lang::Class VoidClass;
+#define ByteClass _CL_Q34java4lang4Byte
+extern java::lang::Class ByteClass;
+#define ShortClass _CL_Q34java4lang5Short
+extern java::lang::Class ShortClass;
+#define CharacterClass _CL_Q34java4lang9Character
+extern java::lang::Class CharacterClass;
+#define IntegerClass _CL_Q34java4lang7Integer
+extern java::lang::Class IntegerClass;
+#define LongClass _CL_Q34java4lang4Long
+extern java::lang::Class LongClass;
+#define FloatClass _CL_Q34java4lang5Float
+extern java::lang::Class FloatClass;
+#define DoubleClass _CL_Q34java4lang6Double
+extern java::lang::Class DoubleClass;
+
+struct cpair
+{
+ jclass prim;
+ jclass wrap;
+};
+
+// This is used to determine when a primitive widening conversion is
+// allowed.
+static cpair primitives[] =
+{
+#define VOID 0
+ { JvPrimClass (void), &VoidClass },
+ { JvPrimClass (byte), &ByteClass },
+#define SHORT 2
+ { JvPrimClass (short), &ShortClass },
+#define CHAR 3
+ { JvPrimClass (char), &CharacterClass },
+ { JvPrimClass (int), &IntegerClass },
+ { JvPrimClass (long), &LongClass },
+ { JvPrimClass (float), &FloatClass },
+ { JvPrimClass (double), &DoubleClass },
+ { NULL, NULL }
+};
+
+static jboolean
+can_widen (jclass from, jclass to)
+{
+ int fromx = -1, tox = -1;
+
+ for (int i = 0; primitives[i].prim; ++i)
+ {
+ if (primitives[i].wrap == from)
+ fromx = i;
+ if (primitives[i].prim == to)
+ tox = i;
+ }
+
+ // Can't handle a miss.
+ if (fromx == -1 || tox == -1)
+ return false;
+ // Can't handle Void arguments.
+ if (fromx == VOID || tox == VOID)
+ return false;
+ // Special-case short/char conversions.
+ if ((fromx == SHORT && tox == CHAR) || (fromx == CHAR && tox == SHORT))
+ return false;
+
+ return fromx <= tox;
+}
+
+static ffi_type *
+get_ffi_type (jclass klass)
+{
+ // A special case.
+ if (klass == NULL)
+ return &ffi_type_pointer;
+
+ ffi_type *r;
+ if (klass == JvPrimClass (byte))
+ r = &ffi_type_sint8;
+ else if (klass == JvPrimClass (short))
+ r = &ffi_type_sint16;
+ else if (klass == JvPrimClass (int))
+ r = &ffi_type_sint32;
+ else if (klass == JvPrimClass (long))
+ r = &ffi_type_sint64;
+ else if (klass == JvPrimClass (float))
+ r = &ffi_type_float;
+ else if (klass == JvPrimClass (double))
+ r = &ffi_type_double;
+ else if (klass == JvPrimClass (boolean))
+ {
+ // FIXME.
+ r = &ffi_type_sint8;
+ }
+ else if (klass == JvPrimClass (char))
+ r = &ffi_type_uint16;
+ else
+ {
+ JvAssert (! klass->isPrimitive());
+ r = &ffi_type_pointer;
+ }
+
+ return r;
+}
+
+// FIXME: the body of this method should be a separate function so
+// that Constructor can use it too.
+jobject
+java::lang::reflect::Method::invoke (jobject obj,
+ jobjectArray args)
+{
+ // FIXME: we need to be a friend of Class here.
+ _Jv_Method *meth = decl_class->methods[index];
+ if (! java::lang::reflect::Modifier::isStatic(modifiers))
+ {
+ jclass k = obj ? obj->getClass() : NULL;
+ if (! obj || ! decl_class->isAssignableFrom(k))
+ JvThrow (new java::lang::NullPointerException);
+ // FIXME: access checks.
+ meth = _Jv_LookupMethod (k, meth->name, meth->signature);
+ }
+
+ // FIXME: access checks.
+
+ if (parameter_types->length != args->length)
+ JvThrow (new java::lang::IllegalArgumentException);
+
+ ffi_type *rtype = get_ffi_type (return_type);
+ ffi_type **argtypes = (ffi_type **) alloca (parameter_types->length
+ * sizeof (ffi_type *));
+
+ jobject *paramelts = elements (parameter_types);
+ jobject *argelts = elements (args);
+
+ int size = 0;
+ for (int i = 0; i < parameter_types->length; ++i)
+ {
+ jclass k = argelts[i] ? argelts[i]->getClass() : NULL;
+ argtypes[i] = get_ffi_type (k);
+ if (paramelts[i]->isPrimitive())
+ {
+ if (! argelts[i]
+ || ! k->isPrimitive ()
+ || ! can_widen (k, paramelts[i]))
+ JvThrow (new java::lang::IllegalArgumentException);
+ size += paramelts[i]->size();
+ }
+ else
+ {
+ if (argelts[i] && ! paramelts[i]->isAssignableFrom (k))
+ JvThrow (new java::lang::IllegalArgumentException);
+ size += sizeof (jobject);
+ }
+ }
+
+ ffi_cif cif;
+ if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, parameter_types->length,
+ rtype, argtypes) != FFI_OK)
+ {
+ // FIXME: throw some kind of VirtualMachineError here.
+ }
+
+ char *values = (char *) alloca (size);
+ char *p = values;
+
+#define COPY(Where, What, Type) \
+ do { \
+ Type val = (What); \
+ memcpy ((Where), &val, sizeof (Type)); \
+ Where += sizeof (Type); \
+ } while (0)
+
+ for (int i = 0; i < parameter_types->length; ++i)
+ {
+ java::lang::Number *num = (java::lang::Number *) paramelts[i];
+ if (paramelts[i] == JvPrimClass (byte))
+ COPY (p, num->byteValue(), jbyte);
+ else if (paramelts[i] == JvPrimClass (short))
+ COPY (p, num->shortValue(), jshort);
+ else if (paramelts[i] == JvPrimClass (int))
+ COPY (p, num->intValue(), jint);
+ else if (paramelts[i] == JvPrimClass (long))
+ COPY (p, num->longValue(), jlong);
+ else if (paramelts[i] == JvPrimClass (float))
+ COPY (p, num->floatValue(), jfloat);
+ else if (paramelts[i] == JvPrimClass (double))
+ COPY (p, num->doubleValue(), jdouble);
+ else if (paramelts[i] == JvPrimClass (boolean))
+ COPY (p, ((java::lang::Boolean *) argelts[i])->booleanValue(), jboolean);
+ else if (paramelts[i] == JvPrimClass (char))
+ COPY (p, ((java::lang::Character *) argelts[i])->charValue(), jchar);
+ else
+ {
+ JvAssert (! paramelts[i]->isPrimitive());
+ COPY (p, argelts[i], jobject);
+ }
+ }
+
+ // FIXME: exception handling.
+ java::lang::Throwable *ex;
+ jdouble ret_value; // Largest possible value. Hopefully
+ // it is aligned!
+ ex = TRAMP_CALL (ffi_call (&cif, meth->ncode, &ret_value, (void *) values));
+
+ if (ex)
+ JvThrow (new InvocationTargetException (ex));
+
+ jobject r;
+#define VAL(Wrapper, Type) (new Wrapper (* (Type *) &ret_value))
+ if (return_type == JvPrimClass (byte))
+ r = VAL (java::lang::Byte, jbyte);
+ else if (return_type == JvPrimClass (short))
+ r = VAL (java::lang::Short, jshort);
+ else if (return_type == JvPrimClass (int))
+ r = VAL (java::lang::Integer, jint);
+ else if (return_type == JvPrimClass (long))
+ r = VAL (java::lang::Long, jlong);
+ else if (return_type == JvPrimClass (float))
+ r = VAL (java::lang::Float, jfloat);
+ else if (return_type == JvPrimClass (double))
+ r = VAL (java::lang::Double, jdouble);
+ else if (return_type == JvPrimClass (boolean))
+ r = VAL (java::lang::Boolean, jboolean);
+ else if (return_type == JvPrimClass (char))
+ r = VAL (java::lang::Character, jchar);
+ else if (return_type == JvPrimClass (void))
+ r = NULL;
+ else
+ {
+ JvAssert (! return_type->isPrimitive());
+ r = VAL (java::lang::Object, jobject);
+ }
+
+ return r;
+}
+
+#else /* 0 */
+
+jobject
+java::lang::reflect::Method::invoke (jobject, jobjectArray)
+{
+ JvFail ("not enabled yet");
+}
+
+#endif /* 0 */
+
+jint
+java::lang::reflect::Method::getModifiers ()
+{
+ return _Jv_FromReflectedMethod (this)->accflags;
+}
+
+jstring
+java::lang::reflect::Method::getName ()
+{
+ if (name == NULL)
+ name = _Jv_NewStringUtf8Const (_Jv_FromReflectedMethod (this)->name);
+ return name;
+}
+
+/* Internal method to set return_type and parameter_types fields. */
+
+void
+java::lang::reflect::Method::getType ()
+{
+ _Jv_Utf8Const* sig = _Jv_FromReflectedMethod (this)->signature;
+ java::lang::ClassLoader *loader = declaringClass->getClassLoader();
+ char *ptr = sig->data;
+ int numArgs = 0;
+ /* First just count the number of parameters. */
+ for (; ; ptr++)
+ {
+ switch (*ptr)
+ {
+ case 0:
+ case ')':
+ case 'V':
+ break;
+ case '[':
+ case '(':
+ continue;
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'F':
+ case 'S':
+ case 'I':
+ case 'J':
+ case 'Z':
+ numArgs++;
+ continue;
+ case 'L':
+ numArgs++;
+ do
+ ptr++;
+ while (*ptr != ';' && ptr[1] != '\0');
+ continue;
+ }
+ break;
+ }
+
+ JArray<jclass> *args = (JArray<jclass> *)
+ JvNewObjectArray (numArgs, &ClassClass, NULL);
+ jclass* argPtr = elements (args);
+ for (ptr = sig->data; *ptr != '\0'; ptr++)
+ {
+ int num_arrays = 0;
+ jclass type;
+ for (; *ptr == '['; ptr++)
+ num_arrays++;
+ switch (*ptr)
+ {
+ default:
+ return;
+ case ')':
+ argPtr = &return_type;
+ continue;
+ case '(':
+ continue;
+ case 'V':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'F':
+ case 'S':
+ case 'I':
+ case 'J':
+ case 'Z':
+ type = _Jv_FindClassFromSignature(ptr, loader);
+ break;
+ case 'L':
+ type = _Jv_FindClassFromSignature(ptr, loader);
+ do
+ ptr++;
+ while (*ptr != ';' && ptr[1] != '\0');
+ break;
+ }
+ while (--num_arrays >= 0)
+ type = _Jv_FindArrayClass (type);
+ *argPtr++ = type;
+ }
+ parameter_types = args;
+}
diff --git a/libjava/java/lang/s_atan.c b/libjava/java/lang/s_atan.c
new file mode 100644
index 00000000000..b1410ecca55
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/s_ceil.c b/libjava/java/lang/s_ceil.c
new file mode 100644
index 00000000000..1476ef821be
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/s_copysign.c b/libjava/java/lang/s_copysign.c
new file mode 100644
index 00000000000..bfc546db503
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/s_cos.c b/libjava/java/lang/s_cos.c
new file mode 100644
index 00000000000..c4712330137
--- /dev/null
+++ b/libjava/java/lang/s_cos.c
@@ -0,0 +1,82 @@
+
+/* @(#)s_cos.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.
+ * ====================================================
+ */
+
+/* cos(x)
+ * Return cosine function of x.
+ *
+ * kernel function:
+ * __kernel_sin ... sine function on [-pi/4,pi/4]
+ * __kernel_cos ... cosine 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 cos(double x)
+#else
+ double cos(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_cos(x,z);
+
+ /* 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/libjava/java/lang/s_fabs.c b/libjava/java/lang/s_fabs.c
new file mode 100644
index 00000000000..95b871ca53a
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/s_floor.c b/libjava/java/lang/s_floor.c
new file mode 100644
index 00000000000..86f73e0e136
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/s_rint.c b/libjava/java/lang/s_rint.c
new file mode 100644
index 00000000000..9936a49b801
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/s_scalbn.c b/libjava/java/lang/s_scalbn.c
new file mode 100644
index 00000000000..b06834e913f
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/s_sin.c b/libjava/java/lang/s_sin.c
new file mode 100644
index 00000000000..28259f378fe
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/s_tan.c b/libjava/java/lang/s_tan.c
new file mode 100644
index 00000000000..2959f416e83
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/sf_rint.c b/libjava/java/lang/sf_rint.c
new file mode 100644
index 00000000000..e4769e0dc60
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/strtod.c b/libjava/java/lang/strtod.c
new file mode 100644
index 00000000000..e0e8e74828b
--- /dev/null
+++ b/libjava/java/lang/strtod.c
@@ -0,0 +1,720 @@
+/*
+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;
+ goto ret;
+ }
+ }
+ else
+ s = s00;
+ }
+ 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/libjava/java/lang/w_acos.c b/libjava/java/lang/w_acos.c
new file mode 100644
index 00000000000..c9ca99c4041
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/w_asin.c b/libjava/java/lang/w_asin.c
new file mode 100644
index 00000000000..f6cb271d392
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/w_atan2.c b/libjava/java/lang/w_atan2.c
new file mode 100644
index 00000000000..91742c72b91
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/w_exp.c b/libjava/java/lang/w_exp.c
new file mode 100644
index 00000000000..ae792a84642
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/w_fmod.c b/libjava/java/lang/w_fmod.c
new file mode 100644
index 00000000000..b6b36cb76ab
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/w_log.c b/libjava/java/lang/w_log.c
new file mode 100644
index 00000000000..dcc8b9762ec
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/w_pow.c b/libjava/java/lang/w_pow.c
new file mode 100644
index 00000000000..3df099a1714
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/w_remainder.c b/libjava/java/lang/w_remainder.c
new file mode 100644
index 00000000000..a06be0e7b30
--- /dev/null
+++ b/libjava/java/lang/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/libjava/java/lang/w_sqrt.c b/libjava/java/lang/w_sqrt.c
new file mode 100644
index 00000000000..23a793ce74a
--- /dev/null
+++ b/libjava/java/lang/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) */