--- /dev/null
+#
+# What to build
+#
+
+doc/nestedvm.ivme04.pdf: doc/nestedvm.ivme04.tex doc/acmconf.cls
+ cd doc; pdflatex nestedvm.ivme04.tex
+
+pdf: doc/nestedvm.ivme04.pdf
+ open doc/nestedvm.ivme04.pdf
+
+# Java sources that are part of the compiler/interpreter
+java_sources = $(wildcard src/org/xwt/mips/*.java) $(wildcard src/org/xwt/mips/util/*.java)
+
+# Java sources that are part of the compiler/interpreter that are
+# generated from other sources
+java_gen_sources = $(patsubst %,build/org/xwt/mips/%.java, UsermodeConstants)
+
+# C sources that are part of the compiler/interpreter
+mips_sources = crt0.c support_aux.c
+mips_asm_sources = support.s
+
+mips2java_root = $(shell pwd)
+build = $(mips2java_root)/build
+tasks = upstream/tasks
+
+#
+# MIPS Settings (don't change these)
+#
+flags = -march=mips1
+MIPS_CC = mips-unknown-elf-gcc
+MIPS_CXX = mips-unknown-elf-g++
+
+# Be VERY careful about changing any of these as they can break binary
+# compatibility and create hard to find bugs
+mips_optflags = -O3 -g \
+ -fno-rename-registers -freduce-all-givs \
+ -fno-peephole -fno-peephole2 -fmove-all-movables -fno-schedule-insns \
+ -fno-delayed-branch \
+ -mmemcpy \
+ -ffunction-sections -fdata-sections \
+ -falign-functions=512
+
+MIPS_CFLAGS = $(mips_optflags) $(flags) -I. -Wall -Wno-unused -Werror
+MIPS_LD = mips-unknown-elf-gcc
+MIPS_LDFLAGS= \
+ $(flags) -L$(build)/org/xwt/mips --static \
+ -T $(mips2java_root)/src/org/xwt/mips/linker.ld -Wl,--gc-sections
+MIPS_STRIP = mips-unknown-elf-strip
+
+# Java compiler/VM settings
+JAVAC = javac
+JAVA = java
+ifeq ($(firstword $(JAVAC)),gcj)
+ JAVAC_NODEBUG_FLAGS = -g0
+else
+ JAVAC_NODEBUG_FLAGS = -g:none
+endif
+
+CLASSPATH = build:upstream/build/bcel/bcel-5.1.jar
+
+GCJ = gcj
+EXE_EXT =
+
+#####
+
+java_classes = \
+ $(java_sources:src/%.java=build/%.class) \
+ $(java_gen_sources:%.java=%.class)
+
+mips_objects = $(mips_sources:%.c=build/org/xwt/mips/%.o) $(mips_asm_sources:%.s=build/org/xwt/mips/%.o)
+
+.SECONDARY:
+
+PATH := $(mips2java_root)/upstream/install/bin:$(PATH)
+export PATH
+
+#
+# General Build Stuff
+#
+all: $(java_classes) $(mips_objects)
+ifdef NATIVE_MIPS2JAVA_COMPILER
+all: build/mips2java$(EXE_EXT) $(mips_objects)
+endif
+
+$(tasks)/%:
+ $(MAKE) -C upstream tasks/$* MIPS_LDFLAGS="$(MIPS_LDFLAGS)" MIPS_CFLAGS="$(flags) $(mips_optflags)"
+
+upstream_clean_%:
+ $(MAKE) -C upstream clean_$*
+
+errno_h = upstream/install/mips-unknown-elf/include/sys/errno.h
+$(errno_h): $(tasks)/build_newlib
+
+unistd_h = upstream/install/mips-unknown-elf/include/sys/unistd.h
+$(unistd_h): $(tasks)/build_newlib
+
+#
+# Interpreter/Compiler/Runtime Java Compilation
+#
+
+# This works around a gcj -C bug
+ifeq ($(firstword $(JAVAC)),gcj)
+build/org/xwt/mips/util/.Dummy.class:
+ mkdir -p `dirname $@`
+ touch $@
+$(java_classes): build/org/xwt/mips/util/.Dummy.class
+endif
+
+$(java_classes): $(tasks)/unpack_bcel $(java_sources) $(java_gen_sources)
+ $(JAVAC) -classpath $(CLASSPATH) -d build $(java_sources) $(java_gen_sources)
+
+build/org/xwt/mips/UsermodeConstants.java: src/org/xwt/mips/syscalls.h $(errno_h) $(unistd_h)
+ @mkdir -p `dirname $@`
+ cat $^ |\
+ (FILE=org.xwt.mips.UsermodeConstants;\
+ C="`echo $$FILE | sed 's/.*\.\([^\.]*\)$$/\1/;'`";\
+ P="`echo $$FILE | sed -n 's/\(.*\)\..*/\1/p;'`";\
+ [ -n "$$P" ] && echo "package $$P;";\
+ echo "public interface $$C {";\
+ tr '\t' ' ' | sed -n ';\
+ s/ */ /g;\
+ s/ *\# *define \([A-Z_][A-Za-z0-9_]*\) \([0-9][0-9x]*\)/ public static final int \1 = \2;/p';\
+ echo "}") > $@
+
+
+# FIXME: We're cramming more than we need into the binary here
+build/mips2java$(EXE_EXT): $(java_sources) $(java_gen_sources)
+ @mkdir -p `dirname $@`
+ $(GCJ) -s -o $@ --main=org.xwt.mips.Compiler $(java_sources) $(java_gen_sources)
+
+#
+# MIPS Binary compilation
+#
+build/%.o: src/%.c $(tasks)/full_toolchain
+ @mkdir -p `dirname $@`
+ $(MIPS_CC) $(MIPS_CFLAGS) $($(notdir $*)_CFLAGS) -c -o $@ $<
+
+build/%.o: src/%.s $(tasks)/full_toolchain
+ @mkdir -p `dirname $@`
+ $(MIPS_CC) -x assembler-with-cpp -c -o $@ $<
+
+%.s: %.c $(tasks)/full_toolchain
+ $(MIPS_CC) $(MIPS_CFLAGS) $($(notdir $*)_CFLAGS) -c -S -o $@ $<
+
+build/%.mips: build/%.o $(mips_objects)
+ $(MIPS_LD) -o $@ $< $(MIPS_LDFLAGS) $($(notdir $*)_LDFLAGS)
+
+build/%.mips: src/%.cc $(tasks)/full_toolchain $(mips_objects)
+ @mkdir -p `dirname $@`
+ $(MIPS_CXX) $(MIPS_CFLAGS) $($(notdir $*)_CFLAGS) $(MIPS_LDFLAGS) $($(notdir $*)_LDFLAGS) -o $@ $<
+
+build/%.mips.stripped: build/%.mips
+ cp $< $@
+ $(MIPS_STRIP) -s $@
+
+# MIPS Compiler generated class compilation
+ifdef DO_JAVASOURCE
+
+build/%.java: build/%.mips build/org/xwt/mips/JavaSourceCompiler.class $(tasks)/unpack_bcel
+ $(JAVA) -cp $(CLASSPATH) org.xwt.mips.Compiler -outformat javasource $(compiler_flags) $($(notdir $*)_COMPILERFLAGS) $(subst /,.,$*) $< > build/$*.java
+
+build/%.class: build/%.java build/org/xwt/mips/Runtime.class
+ $(JAVAC) $(JAVAC_NODEBUG_FLAGS) -classpath build -d build $<
+else
+
+build/%.class: build/%.mips build/org/xwt/mips/ClassFileCompiler.class $(tasks)/unpack_bcel
+ $(JAVA) -cp $(CLASSPATH) org.xwt.mips.Compiler -outformat class -outfile $@ $(compiler_flags) $($(notdir $*)_COMPILERFLAGS) $(subst /,.,$*) $<
+
+
+endif
+
+# General Java Class compilation
+build/%.class: src/%.java
+ $(JAVAC) -classpath build -d build $<
+
+clean:
+ rm -rf build/tests build/org/xwt/mips *.jar build/mips2java$(EXE_EXT)
+
+#
+# env.sh
+#
+env.sh: Makefile $(tasks)/full_toolchain build/org/xwt/mips/Compiler.class $(tasks)/unpack_bcel
+ @rm -f "$@~"
+ @echo 'PATH="$(mips2java_root)/build:$(mips2java_root)/upstream/install/bin:$$PATH"; export PATH' >> $@~
+ @echo 'CC=mips-unknown-elf-gcc; export CC' >> $@~
+ @echo 'CXX=mips-unknown-elf-g++; export CXX' >> $@~
+ @echo 'AS=mips-unknown-elf-as; export AS' >> $@~
+ @echo 'LD=mips-unknown-elf-ar; export LD' >> $@~
+ @echo 'RANLIB=mips-unknown-elf-ranlib; export RANLIB' >> $@~
+ @echo 'CFLAGS="$(mips_optflags)"; export CFLAGS' >> $@~
+ @echo 'CXXFLAGS="$(mips_optflags)"; export CXXFLAGS' >> $@~
+ @echo 'LDFLAGS="$(MIPS_LDFLAGS)"; export LDFLAGS' >> $@~
+ @echo 'CLASSPATH=$(mips2java_root)/build:$(mips2java_root)/upstream/build/bcel/bcel-5.1.jar:.; export CLASSPATH' >> $@~
+ @mv "$@~" "$@"
+ @echo "$@ created successfully"
+
+#
+# Runtime.jar
+#
+
+runtime_util_classes = SeekableData SeekableByteArray SeekableFile SeekableInputStream
+runtime_classes = Runtime Registers UsermodeConstants $(runtime_util_classes:%=util/%)
+unixruntime_classes = $(runtime_classes) UnixRuntime
+
+runtime.jar: $(runtime_classes:%=build/org/xwt/mips/%.class)
+ cd build && jar cf ../$@ $(runtime_classes:%=org/xwt/mips/%*.class)
+
+unixruntime.jar: $(unixruntime_classes:%=build/org/xwt/mips/%.class)
+ cd build && jar cf ../$@ $(unixruntime_classes:%=org/xwt/mips/%*.class)
+
+
+
+#
+# Tests
+# These are simply here for convenience. They aren't required
+# to build or run mips2java
+#
+
+build/tests/Env.class: build/org/xwt/mips/Runtime.class build/org/xwt/mips/Interpreter.class
+
+# Generic Hello Worldish test
+test: build/tests/Test.class
+ $(JAVA) -cp build tests.Test "arg 1" "arg 2" "arg 3"
+inttest: build/tests/Test.mips build/org/xwt/mips/Interpreter.class
+ $(JAVA) -cp build org.xwt.mips.Interpreter build/tests/Test.mips "arg 1" "arg 2" "arg 3"
+cxxtest: build/tests/CXXTest.class
+ $(JAVA) -cp build tests.CXXTest
+
+# CallTest
+build/tests/CallTest.class: build/tests/Test.class
+calltest: build/tests/CallTest.class
+ $(JAVA) -cp build tests.CallTest `date|perl -pe 's/\D+/ /g;'` `id -u`
+
+# FDTest
+build/tests/FDTest.class: build/tests/Test.class
+fdtest: build/tests/FDTest.class
+ $(JAVA) -cp build tests.FDTest
+
+
+# Simple
+Simple_LDFLAGS = -nostdlib
+simpletest: build/tests/Simple.class
+ $(JAVA) -cp build tests.Simple
+
+# Paranoia
+Paranoia_CFLAGS = "-Wno-error"
+Paranoia_LDFLAGS = -lm
+paranoiatest: build/tests/Paranoia.class
+ $(JAVA) -cp build tests.Paranoia
+
+#
+# Freetype Stuff
+#
+FreeType_CFLAGS = -Iupstream/build/freetype/include
+FreeType_LDFLAGS = -Lupstream/build/freetype/objs -lfreetype
+
+FreeTypeDemoHelper_CFLAGS = $(FreeType_CFLAGS)
+FreeTypeDemoHelper_LDFLAGS = $(FreeType_LDFLAGS)
+build/tests/FreeTypeDemoHelper.o: $(mips_objects) $(tasks)/build_freetype
+build/tests/FreeTypeDemoHelper.mips:
+build/tests/FreeTypeDemo.class: build/tests/FreeTypeDemoHelper.class
+
+FTBench_CFLAGS = $(FreeType_CFLAGS)
+FTBench_LDFLAGS = $(FreeType_LDFLAGS)
+build/tests/FTBench.o: $(tasks)/build_freetype
+
+#
+# MSPack Stuff
+#
+MSPackHelper_CFLAGS = -Iupstream/build/libmspack/mspack
+MSPackHelper_LDFLAGS = -Lupstream/build/libmspack/mspack -lmspack
+build/tests/MSPackHelper.o: $(mips_objects) $(tasks)/build_libmspack
+build/tests/MSPack.class: build/tests/MSPackHelper.class
+
+MSPackBench_CFLAGS = -Iupstream/build/libmspack/mspack
+MSPackBench_LDFLAGS = -Lupstream/build/libmspack/mspack -lmspack
+build/tests/MSPackBench.o: $(tasks)/build_libmspack
+
+#
+# Echo
+#
+build/tests/Echo.class: build/tests/EchoHelper.class
+
+#
+# Libjpeg
+#
+DJpeg_COMPILERFLAGS = -o onepage,pagesize=8m
+build/tests/DJpeg.mips: $(mips_objects) $(tasks)/build_libjpeg
+ @mkdir -p `dirname $@`
+ cp upstream/build/libjpeg/djpeg $@
+
+#
+# Busybox
+#
+BusyBox_COMPILERFLAGS = -o unixruntime
+build/tests/BusyBox.mips: $(mips_object) $(tasks)/build_busybox
+ @mkdir -p `dirname $@`
+ cp upstream/build/busybox/busybox $@
+
+busyboxtest: build/tests/BusyBox.class
+ $(JAVA) -cp build tests.BusyBox ash
+
+#
+# Boehm GC
+#
+build/tests/GCTest.mips: $(mips_objects) $(tasks)/build_boehmgc
+ @mkdir -p `dirname $@`
+ cp upstream/build/boehmgc/gctest $@
+
+boehmgctest: build/tests/Env.class build/tests/GCTest.class
+ $(JAVA) -cp build tests.Env GC_PRINT_STATS=1 tests.GCTest
+
+
+#
+# Speed tests
+#
+
+build/tests/SpeedTest.class: build/org/xwt/mips/Runtime.class
+
+tmp/thebride_1280.jpg:
+ @mkdir -p tmp
+ cd tmp && wget http://www.kill-bill.com/images/wallpaper/thebride_1280.jpg
+
+oldspeedtest: build/tests/DJpeg.class tmp/thebride_1280.jpg
+ bash -c "time $(JAVA) -cp build tests.DJpeg -targa -outfile tmp/thebride_1280.tga tmp/thebride_1280.jpg"
+ @echo "e90f6b915aee2fc0d2eb9fc60ace6203 tmp/thebride_1280.tga" | md5sum -c && echo "MD5 is OK"
+
+speedtest: build/tests/SpeedTest.class build/tests/DJpeg.class build/tests/FTBench.class tmp/thebride_1280.jpg build/tests/MSPackBench.class
+ @echo "Running DJpeg test..."
+ @$(JAVA) -cp build tests.SpeedTest tests.DJpeg 10 -targa -outfile tmp/thebride_1280.tga tmp/thebride_1280.jpg
+ @if [ -e tmp/mspack/Comic.TTF ]; then \
+ echo "Running FTBench test..."; \
+ $(JAVA) -cp build tests.SpeedTest tests.FTBench 10 tmp/mspack/Comic.TTF tmp/mspack/Comic.TTF.render; \
+ else \
+ echo "Run \"make check\" to get Arial.TTF for the FTBench test"; \
+ fi
+ @if [ -e tmp/mspack/comic32.exe ]; then \
+ echo "Running MSPackBench test..."; \
+ cd tmp/mspack && $(JAVA) -cp ../../build tests.SpeedTest tests.MSPackBench 10 *32.exe; \
+ else \
+ echo "Run \"make check\" to get the MS True Type fonts for the MSPackBench test"; \
+ fi
+
+intspeed: build/tests/DJpeg.mips build/org/xwt/mips/Interpreter.class tmp/thebride_1280.jpg
+ time $(JAVA) -cp build org.xwt.mips.Interpreter build/tests/DJpeg.mips -targa -outfile tmp/thebride_1280.tga tmp/thebride_1280.jpg
+ @echo "e90f6b915aee2fc0d2eb9fc60ace6203 tmp/thebride_1280.tga" | md5sum -c && echo "MD5 is OK"
+
+#
+# Verification checks
+#
+
+check: $(patsubst %,build/tests/%.class, FTBench MSPackBench DJpeg GCTest) tmp/thebride_1280.jpg
+ @/bin/bash ./src/tests/check.sh running_from_make
+
+compiletests: $(patsubst %,build/tests/%.class,FTBench MSPackBench DJpeg Test FreeTypeDemoHelper MSPackHelper EchoHelper BusyBox GCTest Fork)
+ @true
+
--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+January 11, 2003
+ * [brian] Added Unistd.h as an interface so we can use its constants in
+ Runtime
+ * [brian] -o lessconstants option to compiler to emit all constants as
+ an addition of a field value and a small constant. This
+ prevents the classfile constant pool from overflowing on large
+ applications. This has a small performance impact.
+ * [brian] Added stubs for the rmdir syscall and a minimal implementation
+ of sysconf
+ * [brian] Emit data segments as a series of <32k strings to avoid
+ hitting classfile limits
+January 10, 2003
+ * [brian] The compiler now outputs data segments as Strings rather than
+ huge int arrays.
+ * [brian] Cleaned up Makefile and upstream/Makefile to separate the
+ required mips2java stuff from the tests. Ideally the tests
+ should be completelly separate from the main makefile but
+ keeping them integrated allows for better dependency checking
+ and faster builds.
+January 8, 2003
+ * Much thanks goes to Mohan Embar for discovering and fixing most
+ of the issues below.
+ * [brian] Updated Makefile to allow bulding with gcj
+ (make JAVAC="gcj -C" JAVA="gij")
+ * [brian] Updated Runtime.java to silently ignore SecurityExceptions
+ thrown from System.getProperty()
+ * [brian] Compiler now uses a PrintWriter for output rather than
+ PrintStream and properly closes the file on exit
+ * [brian] Made the htojava script a bourne shell script rather than a
+ perl script to remove the dependency on perl.
+December 29, 2003
+ * [brian] Changed build process to use -ffunction-sections,
+ -fdata-sections, and --gc-sections
+ * [brian] Update support.s to use function sections
+ * [brian] Make the interpreter report the pc/sourceline of
+ exceptions.
+ * [brian] Remove stdio calls from FreeTypeHelper
+ * [brian] Added gcc patch to fix -fdata-sections bug
+ * [brian] Added freetype patch to avoid stdio
+December 2, 2003
+ * [brian] Cleaned up a bunch of //FEATUREs and //FIXMEs. No major
+ changes, just cleanup.
+November 30, 2003
+ * [brian] Added crude support for O_APPEND and O_TRUNC
+
+November 29, 2003
+ * [brian] Moved all sources under org/xwt/mips - modified Makefiles
+ accordingly.
+ * [brian] Added org.xwt.mips.util tree containing SeekableData,
+ SeekableByteArray, SeekableFile, and SeekableInputStream.
+ * [brian] Made ELF.java use SeekableData rather than RandomAccessFile
+ * [brian] Made Runtime.java use org.xwt.mips.util.Seekable* for most
+ file operations.
+ * [brian] Added construtors to Interpreter.java that accept an InputStream
+ or SeekableData.
+ * [brian] Added support for the /dev/fd/n namespace and /dev/{null,zero}
+ * [brian] Added test/FDTest.java example and updated tests/Test.c
+ * [brian] Fixed absolute pathame bug on Win32
+
\ No newline at end of file
--- /dev/null
+package org.xwt.mips;
+
+import java.io.*;
+import org.xwt.mips.util.*;
+
+import org.apache.bcel.generic.*;
+
+// FEATURE: Use BCEL to do peephole optimization
+// FEATURE: Special mode to support single-precision only - regs are floats not ints
+
+/* FEATURE: Span large binaries across several classfiles
+ * We should be able to do this with no performance penalty
+ * Every method in the inner classes is static and takes the main class as an arg
+ * This makes them look just like methods in the main class because arg1 gets loaded into
+ * local register 0
+ */
+
+/* FEATURE: smarter with local regs
+ * Be even smarter with the use of local registers. We need to only load fields into
+ * local regs when they are actually used and only write to fields if the regs could have
+ * changed. This should allow us to put more regs in local vars. Right now putting all used
+ * regs local vars makes code like this slower.
+ *
+ * void work(int a, int b) {
+ * if(a == b) {
+ * fast path
+ * return;
+ * }
+ * real work
+ * }
+ * Because all the regs used in "real work" are loaded/restored even for fast path
+ */
+
+
+public class ClassFileCompiler extends Compiler implements org.apache.bcel.Constants {
+ /** The stream to write the compiled output to */
+ private OutputStream os;
+ private PrintStream warn = System.err;
+
+ private ClassGen cl;
+ private ConstantPoolGen cp;
+ private InstructionList clinitExtras = new InstructionList();
+ private InstructionList initExtras = new InstructionList();
+ private InstructionFactory fac;
+
+ // Handy wrappers around the BCEL functions
+ private InstructionList insnList;
+ private void selectMethod(MethodGen m) { insnList = m.getInstructionList(); }
+ private void selectList(InstructionList l) { insnList = l; }
+ private InstructionHandle a(Instruction i) { return insnList.append(i); }
+ private BranchHandle a(BranchInstruction i) { return insnList.append(i); }
+ private InstructionHandle a(InstructionList l) { return insnList.append(l); }
+ private InstructionHandle a(CompoundInstruction c) { return insnList.append(c); }
+
+ // This works around a bug in InstructionList
+ // FEATURE: fix this in bcel, send them a patch, etc
+ private static class FixedInstructionList extends InstructionList {
+ public void move(InstructionHandle start, InstructionHandle end, InstructionHandle target) {
+ InstructionHandle extra = target != null && target == getEnd() ? append(InstructionConstants.NOP) : null;
+ super.move(start,end,target);
+ if(extra != null) try { delete(extra); } catch (TargetLostException e) { /* won't happen */ }
+ }
+ }
+
+ private MethodGen newMethod(int flags, Type ret, Type[] args, String name) {
+ return new MethodGen(flags,ret,args,null,name,fullClassName,new FixedInstructionList(),cp);
+ }
+
+ public ClassFileCompiler(String path, String className, OutputStream os) throws IOException { this(new SeekableFile(path),className,os); }
+ public ClassFileCompiler(SeekableData binary, String className, OutputStream os) throws IOException {
+ super(binary,className);
+ this.os = os;
+ }
+
+ public void setWarnWriter(PrintStream warn) { this.warn = warn; }
+
+ protected void _go() throws Exn, IOException {
+ if(lessConstants) throw new Exn("ClassFileCompiler doesn't support -o lessconstants");
+ if(!pruneCases) throw new Exn("-o prunecases MUST be enabled for ClassFileCompiler");
+
+ // Class
+ cl = new ClassGen(fullClassName,runtimeClass,source,ACC_SUPER|ACC_PUBLIC,null);
+ cp = cl.getConstantPool();
+ fac = new InstructionFactory(cl,cp);
+
+ // Fields
+ cl.addField(new FieldGen(ACC_PRIVATE,Type.INT,"pc",cp).getField());
+ for(int i=1;i<32;i++)
+ cl.addField(new FieldGen(ACC_PRIVATE,Type.INT,"r"+i,cp).getField());
+ for(int i=0;i<32;i++)
+ cl.addField(new FieldGen(ACC_PRIVATE,Type.INT,"f"+i,cp).getField());
+
+ cl.addField(new FieldGen(ACC_PRIVATE,Type.INT,"hi",cp).getField());
+ cl.addField(new FieldGen(ACC_PRIVATE,Type.INT,"lo",cp).getField());
+ cl.addField(new FieldGen(ACC_PRIVATE,Type.INT,"fcsr",cp).getField());
+
+ if(onePage) {
+ cl.addField(new FieldGen(ACC_PRIVATE|ACC_FINAL,new ArrayType(Type.INT,1),"page",cp).getField());
+
+ selectList(initExtras);
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.DUP);
+ a(fac.createFieldAccess(fullClassName,"readPages",new ArrayType(Type.INT, 2), GETFIELD));
+ pushConst(0);
+ a(InstructionConstants.AALOAD);
+ a(fac.createFieldAccess(fullClassName,"page",new ArrayType(Type.INT,1), PUTFIELD));
+ }
+
+ if(supportCall)
+ cl.addField(new FieldGen(ACC_PRIVATE|ACC_STATIC|ACC_FINAL,Type.getType("L"+hashClass.replace('.','/')+";"),"symbols",cp).getField());
+
+ int highestAddr = 0;
+
+ for(int i=0;i<elf.sheaders.length;i++) {
+ ELF.SHeader sheader = elf.sheaders[i];
+ String name = sheader.name;
+ // if this section doesn't get loaded into our address space don't worry about it
+ if(sheader.addr == 0x0) continue;
+
+ highestAddr = Math.max(highestAddr, sheader.addr + sheader.size);
+
+ if(name.equals(".text"))
+ emitText(sheader.addr, new DataInputStream(sheader.getInputStream()),sheader.size);
+ else if(name.equals(".data") || name.equals(".sdata") || name.equals(".rodata") || name.equals(".ctors") || name.equals(".dtors"))
+ emitData(sheader.addr, new DataInputStream(sheader.getInputStream()), sheader.size,name.equals(".rodata"));
+ else if(name.equals(".bss") || name.equals(".sbss"))
+ emitBSS(sheader.addr,sheader.size);
+ else
+ throw new Exn("Unknown segment: " + name);
+ }
+
+ ELF.SHeader text = elf.sectionWithName(".text");
+
+ // Trampoline
+ MethodGen tramp = newMethod(ACC_PRIVATE,Type.VOID, Type.NO_ARGS, "trampoline");
+ tramp.addException("org.xwt.mips.Runtime$ExecutionException");
+ selectMethod(tramp);
+
+ InstructionHandle start = a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"state",Type.INT, GETFIELD));
+ pushConst(Runtime.RUNNING);
+ BranchInstruction stateCheck = InstructionFactory.createBranchInstruction(IF_ICMPNE,null);
+ a(stateCheck);
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"pc",Type.INT, GETFIELD));
+ pushConst(methodShift);
+ a(InstructionConstants.IUSHR);
+
+ int beg = text.addr >>> methodShift;
+ int end = ((text.addr + text.size) >>> methodShift) + 1;
+
+ // This data is redundant but BCEL wants it
+ int[] matches = new int[end-beg];
+ for(int i=beg;i<end;i++) matches[i-beg] = i;
+ TABLESWITCH ts = new TABLESWITCH(matches,new InstructionHandle[matches.length],null);
+ a(ts);
+ for(int n=beg;n<end;n++){
+ InstructionHandle h = a(fac.createInvoke(fullClassName,"run_"+toHex(n<<methodShift),Type.VOID,Type.NO_ARGS,INVOKESPECIAL));
+ a(InstructionFactory.createBranchInstruction(GOTO,start));
+ ts.setTarget(n-beg,h);
+ }
+
+ ts.setTarget(a(InstructionConstants.POP)); // default case
+ a(fac.createNew("org.xwt.mips.Runtime$ExecutionException"));
+ a(InstructionConstants.DUP);
+ a(fac.createNew("java.lang.StringBuffer"));
+ a(InstructionConstants.DUP);
+ a(new PUSH(cp,"Jumped to invalid address in trampoline (r2: "));
+ a(fac.createInvoke("java.lang.StringBuffer","<init>",Type.VOID,new Type[]{Type.STRING},INVOKESPECIAL));
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"r2",Type.INT, GETFIELD));
+ a(fac.createInvoke("java.lang.StringBuffer","append",Type.STRINGBUFFER,new Type[]{Type.INT},INVOKEVIRTUAL));
+ a(new PUSH(cp," pc:"));
+ a(fac.createInvoke("java.lang.StringBuffer","append",Type.STRINGBUFFER,new Type[]{Type.STRING},INVOKEVIRTUAL));
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"pc",Type.INT, GETFIELD));
+ a(fac.createInvoke("java.lang.StringBuffer","append",Type.STRINGBUFFER,new Type[]{Type.INT},INVOKEVIRTUAL));
+ a(new PUSH(cp,')'));
+ a(fac.createInvoke("java.lang.StringBuffer","append",Type.STRINGBUFFER,new Type[]{Type.CHAR},INVOKEVIRTUAL));
+ a(fac.createInvoke("java.lang.StringBuffer","toString",Type.STRING,Type.NO_ARGS,INVOKEVIRTUAL));
+ a(fac.createInvoke("org.xwt.mips.Runtime$ExecutionException","<init>",Type.VOID,new Type[]{Type.STRING},INVOKESPECIAL));
+ a(InstructionConstants.ATHROW);
+
+ stateCheck.setTarget(a(InstructionConstants.RETURN));
+
+ tramp.setMaxStack();
+ tramp.setMaxLocals();
+ try {
+ cl.addMethod(tramp.getMethod());
+ } catch(ClassGenException e) {
+ e.printStackTrace(warn);
+ throw new Exn("Generation of the trampoline method failed. Try increasing maxInsnPerMethod");
+ }
+
+ MethodGen init = newMethod(ACC_PUBLIC,Type.VOID, Type.NO_ARGS, "<init>");
+ selectMethod(init);
+ // Constructor
+ a(InstructionConstants.ALOAD_0);
+ pushConst(pageSize);
+ pushConst(totalPages);
+ pushConst(fastMem ? 0 : 1);
+ a(fac.createInvoke(runtimeClass,"<init>",Type.VOID,new Type[]{Type.INT,Type.INT,Type.BOOLEAN},INVOKESPECIAL));
+ a(InstructionConstants.ALOAD_0);
+ pushConst(gp.addr);
+ a(fac.createFieldAccess(fullClassName,"gp",Type.INT, PUTFIELD));
+
+ a(InstructionConstants.ALOAD_0);
+ pushConst(elf.header.entry);
+ a(fac.createFieldAccess(fullClassName,"entryPoint",Type.INT, PUTFIELD));
+
+ a(InstructionConstants.ALOAD_0);
+ pushConst(onePage ? ((highestAddr+4095)&~4095) : ((highestAddr+pageSize-1)&~(pageSize-1)));
+ a(fac.createFieldAccess(fullClassName,"brkAddr",Type.INT, PUTFIELD));
+
+ if(userInfo != null) {
+ a(InstructionConstants.ALOAD_0);
+ pushConst(userInfo.addr);
+ a(fac.createFieldAccess(fullClassName,"userInfoBase",Type.INT, PUTFIELD));
+ a(InstructionConstants.ALOAD_0);
+ pushConst(userInfo.size);
+ a(fac.createFieldAccess(fullClassName,"userInfoSize",Type.INT, PUTFIELD));
+ }
+ a(initExtras);
+ a(InstructionConstants.ALOAD_0);
+ pushConst(Runtime.INITIALIZED);
+ a(fac.createFieldAccess(fullClassName,"state",Type.INT, PUTFIELD));
+ a(InstructionConstants.RETURN);
+ init.setMaxLocals();
+ init.setMaxStack();
+ cl.addMethod(init.getMethod());
+
+ MethodGen clinit = newMethod(ACC_PRIVATE|ACC_STATIC,Type.VOID, Type.NO_ARGS, "<clinit>");
+ selectMethod(clinit);
+ a(clinitExtras);
+
+ if(supportCall) {
+ a(fac.createNew(hashClass));
+ a(InstructionConstants.DUP);
+ a(InstructionConstants.DUP);
+ a(fac.createInvoke(hashClass,"<init>",Type.VOID,Type.NO_ARGS,INVOKESPECIAL));
+ a(fac.createFieldAccess(fullClassName,"symbols",Type.getType("L"+hashClass.replace('.','/')+";"), PUTSTATIC));
+ ELF.Symbol[] symbols = elf.getSymtab().symbols;
+ for(int i=0;i<symbols.length;i++) {
+ ELF.Symbol s = symbols[i];
+ if(s.type == ELF.Symbol.STT_FUNC && s.binding == ELF.Symbol.STB_GLOBAL && (s.name.equals("_call_helper") || !s.name.startsWith("_"))) {
+ a(InstructionConstants.DUP);
+ a(new PUSH(cp,s.name));
+ a(fac.createNew("java.lang.Integer"));
+ a(InstructionConstants.DUP);
+ a(new PUSH(cp,s.addr));
+ a(fac.createInvoke("java.lang.Integer","<init>",Type.VOID,new Type[]{Type.INT},INVOKESPECIAL));
+ a(fac.createInvoke(hashClass,"put",Type.OBJECT,new Type[]{Type.OBJECT,Type.OBJECT},INVOKEVIRTUAL));
+ a(InstructionConstants.POP);
+ }
+ }
+ a(InstructionConstants.POP);
+ }
+
+ a(InstructionConstants.RETURN);
+ clinit.setMaxLocals();
+ clinit.setMaxStack();
+ cl.addMethod(clinit.getMethod());
+
+ if(supportCall) {
+ MethodGen lookupSymbol = newMethod(ACC_PROTECTED,Type.INT,new Type[]{Type.STRING},"lookupSymbol");
+ selectMethod(lookupSymbol);
+ a(fac.createFieldAccess(fullClassName,"symbols",Type.getType("L"+hashClass.replace('.','/')+";"), GETSTATIC));
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createInvoke(hashClass,"get",Type.OBJECT,new Type[]{Type.OBJECT},INVOKEVIRTUAL));
+ a(InstructionConstants.DUP);
+ BranchHandle bh = a(InstructionFactory.createBranchInstruction(IFNULL,null));
+ a(fac.createCheckCast(new ObjectType("java.lang.Integer")));
+ a(fac.createInvoke("java.lang.Integer","intValue",Type.INT,Type.NO_ARGS,INVOKEVIRTUAL));
+ a(InstructionConstants.IRETURN);
+ bh.setTarget(a(InstructionConstants.ICONST_M1));
+ a(InstructionConstants.IRETURN);
+ lookupSymbol.setMaxLocals();
+ lookupSymbol.setMaxStack();
+ cl.addMethod(lookupSymbol.getMethod());
+ }
+
+ MethodGen setCPUState = newMethod(ACC_PROTECTED,Type.VOID,new Type[]{Type.getType("Lorg/xwt/mips/Runtime$CPUState;")},"setCPUState");
+ selectMethod(setCPUState);
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","r",new ArrayType(Type.INT,1),GETFIELD));
+ a(InstructionConstants.ASTORE_2);
+ for(int i=1;i<32;i++) {
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.ALOAD_2);
+ pushConst(i);
+ a(InstructionConstants.IALOAD);
+ a(fac.createFieldAccess(fullClassName,"r"+i,Type.INT, PUTFIELD));
+ }
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","f",new ArrayType(Type.INT,1),GETFIELD));
+ a(InstructionConstants.ASTORE_2);
+ for(int i=0;i<32;i++) {
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.ALOAD_2);
+ pushConst(i);
+ a(InstructionConstants.IALOAD);
+ a(fac.createFieldAccess(fullClassName,"f"+i,Type.INT, PUTFIELD));
+ }
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","hi",Type.INT,GETFIELD));
+ a(fac.createFieldAccess(fullClassName,"hi",Type.INT, PUTFIELD));
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","lo",Type.INT,GETFIELD));
+ a(fac.createFieldAccess(fullClassName,"lo",Type.INT, PUTFIELD));
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","fcsr",Type.INT,GETFIELD));
+ a(fac.createFieldAccess(fullClassName,"fcsr",Type.INT, PUTFIELD));
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","pc",Type.INT,GETFIELD));
+ a(fac.createFieldAccess(fullClassName,"pc",Type.INT, PUTFIELD));
+ a(InstructionConstants.RETURN);
+ setCPUState.setMaxLocals();
+ setCPUState.setMaxStack();
+ cl.addMethod(setCPUState.getMethod());
+
+ MethodGen getCPUState = newMethod(ACC_PROTECTED,Type.getType("Lorg/xwt/mips/Runtime$CPUState;"),Type.NO_ARGS,"getCPUState");
+ selectMethod(getCPUState);
+ a(fac.createNew("org.xwt.mips.Runtime$CPUState"));
+ a(InstructionConstants.DUP);
+ a(fac.createInvoke("org.xwt.mips.Runtime$CPUState","<init>",Type.VOID,Type.NO_ARGS,INVOKESPECIAL));
+ a(InstructionConstants.ASTORE_1);
+
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","r",new ArrayType(Type.INT,1),GETFIELD));
+ a(InstructionConstants.ASTORE_2);
+ for(int i=1;i<32;i++) {
+ a(InstructionConstants.ALOAD_2);
+ pushConst(i);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"r"+i,Type.INT, GETFIELD));
+ a(InstructionConstants.IASTORE);
+ }
+
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","f",new ArrayType(Type.INT,1),GETFIELD));
+ a(InstructionConstants.ASTORE_2);
+ for(int i=0;i<32;i++) {
+ a(InstructionConstants.ALOAD_2);
+ pushConst(i);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"f"+i,Type.INT, GETFIELD));
+ a(InstructionConstants.IASTORE);
+ }
+ a(InstructionConstants.ALOAD_1);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"hi",Type.INT, GETFIELD));
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","hi",Type.INT,PUTFIELD));
+ a(InstructionConstants.ALOAD_1);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"lo",Type.INT, GETFIELD));
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","lo",Type.INT,PUTFIELD));
+ a(InstructionConstants.ALOAD_1);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"fcsr",Type.INT, GETFIELD));
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","fcsr",Type.INT,PUTFIELD));
+ a(InstructionConstants.ALOAD_1);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"pc",Type.INT, GETFIELD));
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","pc",Type.INT,PUTFIELD));
+
+ a(InstructionConstants.ALOAD_1);
+ a(InstructionConstants.ARETURN);
+ getCPUState.setMaxLocals();
+ getCPUState.setMaxStack();
+ cl.addMethod(getCPUState.getMethod());
+
+
+ MethodGen execute = newMethod(ACC_PROTECTED,Type.VOID,Type.NO_ARGS,"_execute");
+ selectMethod(execute);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createInvoke(fullClassName,"trampoline",Type.VOID,Type.NO_ARGS,INVOKESPECIAL));
+ a(InstructionConstants.RETURN);
+ execute.setMaxLocals();
+ execute.setMaxStack();
+ cl.addMethod(execute.getMethod());
+
+
+ MethodGen main = newMethod(ACC_STATIC|ACC_PUBLIC,Type.VOID,new Type[]{new ArrayType(Type.STRING,1)},"main");
+ selectMethod(main);
+ a(fac.createNew(fullClassName));
+ a(InstructionConstants.DUP);
+ a(fac.createInvoke(fullClassName,"<init>",Type.VOID,Type.NO_ARGS,INVOKESPECIAL));
+ a(new PUSH(cp,fullClassName));
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createInvoke(fullClassName,"run",Type.INT,new Type[]{Type.STRING,new ArrayType(Type.STRING,1)},INVOKEVIRTUAL));
+ a(fac.createInvoke("java.lang.System","exit",Type.VOID,new Type[]{Type.INT},INVOKESTATIC));
+ a(InstructionConstants.RETURN);
+ main.setMaxLocals();
+ main.setMaxStack();
+ cl.addMethod(main.getMethod());
+
+ cl.getJavaClass().dump(os);
+ }
+
+ private static int initDataCount;
+ private void emitData(int addr, DataInputStream dis, int size, boolean readOnly) throws Exn,IOException {
+ if((addr&3)!=0 || (size&3)!=0) throw new Exn("Data section on weird boundaries");
+ int last = addr + size;
+ while(addr < last) {
+ int segSize = Math.min(size,28000); // must be a multiple of 56
+ StringBuffer sb = new StringBuffer();
+ for(int i=0;i<segSize;i+=7) {
+ long l = 0;
+ for(int j=0;j<7;j++) {
+ l <<= 8;
+ byte b = (i+j < size) ? dis.readByte() : 1;
+ l |= (b & 0xffL);
+ }
+ for(int j=0;j<8;j++)
+ sb.append((char) ((l>>>(7*(7-j)))&0x7f));
+ }
+ String fieldname = "_data" + (++initDataCount);
+ cl.addField(new FieldGen(ACC_PRIVATE|ACC_STATIC|ACC_FINAL,new ArrayType(Type.INT,1),fieldname,cp).getField());
+
+ selectList(clinitExtras);
+ a(new PUSH(cp,sb.toString()));
+ a(new PUSH(cp,segSize/4));
+ a(fac.createInvoke("org.xwt.mips.Runtime","decodeData",new ArrayType(Type.INT,1),new Type[]{Type.STRING,Type.INT},INVOKESTATIC));
+ a(fac.createPutStatic(fullClassName,fieldname,new ArrayType(Type.INT,1)));
+
+ selectList(initExtras);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createGetStatic(fullClassName,fieldname,new ArrayType(Type.INT,1)));
+ a(new PUSH(cp,addr));
+ a(new PUSH(cp,readOnly));
+ a(fac.createInvoke(fullClassName,"initPages",Type.VOID,new Type[]{new ArrayType(Type.INT,1),Type.INT,Type.BOOLEAN},INVOKEVIRTUAL));
+
+ addr += segSize;
+ size -= segSize;
+ }
+ dis.close();
+ }
+
+ private void emitBSS(int addr, int size) throws Exn {
+ if((addr&3)!=0) throw new Exn("BSS section on weird boundaries");
+ size = (size+3)&~3;
+ int count = size/4;
+ selectList(initExtras);
+ a(InstructionConstants.ALOAD_0);
+ a(new PUSH(cp,addr));
+ a(new PUSH(cp,count));
+ a(fac.createInvoke(fullClassName,"clearPages",Type.VOID,new Type[]{Type.INT,Type.INT},INVOKEVIRTUAL));
+ }
+
+ // method state info
+ private boolean textDone;
+ private int startOfMethod = 0;
+ private int endOfMethod = 0;
+ private boolean unreachable = false;
+ private InstructionHandle[] jumpHandles;
+ private InstructionHandle defaultHandle;
+ private InstructionHandle returnHandle;
+ private InstructionHandle realStart;
+ private MethodGen curMethod;
+
+ private boolean jumpable(int addr) { return jumpableAddresses.contains(new Integer(addr)); }
+
+ private void emitText(int addr, DataInputStream dis, int size) throws Exn,IOException {
+ if(textDone) throw new Exn("Multiple text segments");
+ textDone = true;
+
+ if((addr&3)!=0 || (size&3)!=0) throw new Exn("Section on weird boundaries");
+ int count = size/4;
+ int insn,nextInsn=-1;
+ boolean skipNext = true;
+
+ for(int i=0;i<count;i++,addr+=4) {
+ insn = skipNext ? dis.readInt() : nextInsn;
+ nextInsn = (i == count-1) ? -1 : dis.readInt();
+ if(addr >= endOfMethod) { endMethod(addr); startMethod(addr); }
+ if(jumpHandles[(addr-startOfMethod)/4] != null) {
+ // Move the fake jump target to the current location
+ insnList.move(jumpHandles[(addr-startOfMethod)/4],insnList.getEnd());
+ unreachable = false;
+ } else if(unreachable) {
+ continue;
+ }
+ try {
+ skipNext = emitInstruction(addr,insn,nextInsn);
+ } catch(RuntimeException e) {
+ warn.println("Exception at " + toHex(addr));
+ throw e;
+ }
+ if(skipNext) { addr+=4; i++; }
+ }
+ endMethod(0);
+ dis.close();
+ }
+
+ private void startMethod(int first) {
+ startOfMethod = first & methodMask;
+ endOfMethod = startOfMethod + maxBytesPerMethod;
+ curMethod = newMethod(ACC_PRIVATE,Type.VOID,Type.NO_ARGS,"run_" + toHex(startOfMethod));
+ selectMethod(curMethod);
+
+ int[] buf = new int[maxBytesPerMethod/4];
+ jumpHandles = new InstructionHandle[maxBytesPerMethod/4];
+ int n=0;
+ for(int addr=first;addr<endOfMethod;addr+=4) {
+ if(jumpable(addr)) {
+ buf[n++] = addr;
+ // append NOPs for GOTO jumps (these will be moved to the correct location later)
+ jumpHandles[(addr-startOfMethod)/4] = a(InstructionConstants.NOP);
+ }
+ }
+
+ // append NOP for default case (throw exn) (this will be moved later)
+ defaultHandle = a(InstructionConstants.NOP);
+ returnHandle = a(InstructionConstants.NOP);
+
+ int[] matches = new int[n];
+ System.arraycopy(buf,0,matches,0,n);
+ InstructionHandle[] targets = new InstructionHandle[n];
+ for(int i=0;i<matches.length;i++)
+ targets[i] = jumpHandles[(matches[i]-startOfMethod)/4];
+
+
+ // First instruction of the actual method - everything above this should be removed
+ // before we get to the end
+ realStart = a(InstructionConstants.NOP);
+
+ if(onePage) {
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"page",new ArrayType(Type.INT,1), GETFIELD));
+ a(InstructionConstants.ASTORE_2);
+ } else {
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"readPages",new ArrayType(Type.INT,2), GETFIELD));
+ a(InstructionConstants.ASTORE_2);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"writePages",new ArrayType(Type.INT,2), GETFIELD));
+ a(InstructionFactory.createStore(Type.OBJECT,3));
+ }
+
+ LOOKUPSWITCH initialSwitch = new LOOKUPSWITCH(matches,targets,defaultHandle);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"pc",Type.INT, GETFIELD));
+ a(initialSwitch);
+ }
+
+ private void endMethod(int firstAddrOfNext) {
+ if(startOfMethod == 0) return;
+
+ if(!unreachable) {
+ preSetPC();
+ pushConst(firstAddrOfNext);
+ setPC();
+ // mark the start of the next method as jumpable
+ jumpableAddresses.add(new Integer(firstAddrOfNext));
+ }
+
+ insnList.move(returnHandle,insnList.getEnd());
+ fixupRegs();
+ a(InstructionConstants.RETURN);
+
+ // move the default jump target (lookupswitch) to before the throw
+ insnList.move(defaultHandle,insnList.getEnd());
+ if(debugCompiler) {
+ a(fac.createNew("org.xwt.mips.Runtime$ExecutionException"));
+ a(InstructionConstants.DUP);
+ a(fac.createNew("java.lang.StringBuffer"));
+ a(InstructionConstants.DUP);
+ a(new PUSH(cp,"Jumped to invalid address: "));
+ a(fac.createInvoke("java.lang.StringBuffer","<init>",Type.VOID,new Type[]{Type.STRING},INVOKESPECIAL));
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"pc",Type.INT, GETFIELD));
+ a(fac.createInvoke("java.lang.StringBuffer","append",Type.STRINGBUFFER,new Type[]{Type.INT},INVOKEVIRTUAL));
+ a(fac.createInvoke("java.lang.StringBuffer","toString",Type.STRING,Type.NO_ARGS,INVOKEVIRTUAL));
+ a(fac.createInvoke("org.xwt.mips.Runtime$ExecutionException","<init>",Type.VOID,new Type[]{Type.STRING},INVOKESPECIAL));
+ a(InstructionConstants.ATHROW);
+ } else {
+ a(fac.createNew("org.xwt.mips.Runtime$ExecutionException"));
+ a(InstructionConstants.DUP);
+ a(new PUSH(cp,"Jumped to invalid address"));
+ a(fac.createInvoke("org.xwt.mips.Runtime$ExecutionException","<init>",Type.VOID,new Type[]{Type.STRING},INVOKESPECIAL));
+ a(InstructionConstants.ATHROW);
+ }
+
+ if(insnList.getStart() != realStart) {
+ System.err.println(insnList);
+ throw new Error("A jumpHandle wasn't moved into place");
+ }
+
+ curMethod.removeNOPs();
+ curMethod.setMaxLocals();
+ curMethod.setMaxStack();
+
+ cl.addMethod(curMethod.getMethod());
+
+ endOfMethod = startOfMethod = 0;
+ }
+
+
+ private void leaveMethod() {
+ a(InstructionFactory.createBranchInstruction(GOTO,returnHandle));
+ }
+
+ private void branch(int pc, int target) {
+ if((pc&methodMask) == (target&methodMask)) {
+ a(InstructionFactory.createBranchInstruction(GOTO,jumpHandles[(target-startOfMethod)/4]));
+ } else {
+ preSetPC();
+ pushConst(target);
+ setPC();
+ leaveMethod();
+ }
+ }
+
+ // This assumes everything needed by ifInsn is already on the stack
+ private boolean doIfInstruction(short op, int pc, int target, int nextInsn) throws Exn {
+ emitInstruction(-1,nextInsn,-1); // delay slot
+ BranchHandle h;
+ IfInstruction ifInsn = (IfInstruction) InstructionFactory.createBranchInstruction(op,null);
+ if((target&methodMask) == (pc&methodMask)) {
+ h = a(ifInsn);
+ h.setTarget(jumpHandles[(target-startOfMethod)/4]);
+ } else {
+ h = a(ifInsn.negate());
+ branch(pc,target);
+ h.setTarget(a(InstructionConstants.NOP));
+ }
+ if(!jumpable(pc+4)) return true; // done - skip it
+
+ //System.err.println("Delay slot is jumpable - This code is untested + " + toHex(nextInsn));
+ if(pc+4==endOfMethod) {
+ // the delay slot is at the start of the next method
+ jumpableAddresses.add(new Integer(pc+8)); // make the 2nd insn of the next method jumpable
+ branch(pc,pc+8); // jump over it
+ //System.err.println("delay slot: " + toHex(pc+8));
+ unreachable = true;
+ return false; // we still need to output it
+ } else {
+ //System.err.println("jumped over delay slot: " + toHex(pc+4));
+ // add another copy and jump over
+ h = a(InstructionFactory.createBranchInstruction(GOTO,null));
+ insnList.move(jumpHandles[(pc+4-startOfMethod)/4],insnList.getEnd());
+ emitInstruction(-1,nextInsn,-1); // delay slot
+ h.setTarget(a(InstructionConstants.NOP));
+ return true;
+ }
+ }
+
+ private boolean emitInstruction(int pc, int insn, int nextInsn) throws Exn {
+ if(insn == -1) throw new Exn("insn is -1");
+
+ int op = (insn >>> 26) & 0xff; // bits 26-31
+ int rs = (insn >>> 21) & 0x1f; // bits 21-25
+ int rt = (insn >>> 16) & 0x1f; // bits 16-20
+ int ft = (insn >>> 16) & 0x1f;
+ int rd = (insn >>> 11) & 0x1f; // bits 11-15
+ int fs = (insn >>> 11) & 0x1f;
+ int shamt = (insn >>> 6) & 0x1f; // bits 6-10
+ int fd = (insn >>> 6) & 0x1f;
+ int subcode = insn & 0x3f; // bits 0-5
+ int breakCode = (insn >>> 6) & 0xfffff; // bits 6-20
+
+ int jumpTarget = (insn & 0x03ffffff); // bits 0-25
+ int unsignedImmediate = insn & 0xffff;
+ int signedImmediate = (insn << 16) >> 16;
+ int branchTarget = signedImmediate;
+
+ // temporaries
+ BranchHandle b1,b2;
+
+ switch(op) {
+ case 0: {
+ switch(subcode) {
+ case 0: // SLL
+ if(insn == 0) break;
+ preSetReg(R+rd);
+ pushRegWZ(R+rt);
+ pushConst(shamt);
+ a(InstructionConstants.ISHL);
+ setReg();
+ break;
+ case 2: // SRL
+ preSetReg(R+rd);
+ pushRegWZ(R+rt);
+ pushConst(shamt);
+ a(InstructionConstants.IUSHR);
+ setReg();
+ break;
+ case 3: // SRA
+ preSetReg(R+rd);
+ pushRegWZ(R+rt);
+ pushConst(shamt);
+ a(InstructionConstants.ISHR);
+ setReg();
+ break;
+ case 4: // SLLV
+ preSetReg(R+rd);
+ pushRegWZ(R+rt);
+ pushRegWZ(R+rs);
+ a(InstructionConstants.ISHL);
+ setReg();
+ break;
+ case 6: // SRLV
+ preSetReg(R+rd);
+ pushRegWZ(R+rt);
+ pushRegWZ(R+rs);
+ a(InstructionConstants.IUSHR);
+ setReg();
+ break;
+ case 7: // SRAV
+ preSetReg(R+rd);
+ pushRegWZ(R+rt);
+ pushRegWZ(R+rs);
+ a(InstructionConstants.ISHR);
+ setReg();
+ break;
+ case 8: // JR
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ emitInstruction(-1,nextInsn,-1);
+ preSetPC();
+ pushRegWZ(R+rs);
+ setPC();
+ leaveMethod();
+ unreachable = true;
+ break;
+ case 9: // JALR
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ emitInstruction(-1,nextInsn,-1);
+ preSetPC();
+ pushRegWZ(R+rs);
+ setPC();
+
+ preSetReg(R+RA);
+ pushConst(pc+8);
+ setReg();
+ leaveMethod();
+ unreachable = true;
+ break;
+ case 12: // SYSCALL
+ preSetPC();
+ pushConst(pc);
+ setPC();
+
+ restoreChangedRegs();
+
+ preSetReg(R+V0);
+ a(InstructionConstants.ALOAD_0);
+ pushRegZ(R+V0);
+ pushRegZ(R+A0);
+ pushRegZ(R+A1);
+ pushRegZ(R+A2);
+ pushRegZ(R+A3);
+ a(fac.createInvoke(fullClassName,"syscall",Type.INT,new Type[]{Type.INT,Type.INT,Type.INT,Type.INT,Type.INT},INVOKEVIRTUAL));
+ setReg();
+
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"state",Type.INT, GETFIELD));
+ pushConst(Runtime.RUNNING);
+ b1 = a(InstructionFactory.createBranchInstruction(IF_ICMPEQ,null));
+ preSetPC();
+ pushConst(pc+4);
+ setPC();
+ leaveMethod();
+ b1.setTarget(a(InstructionConstants.NOP));
+
+ break;
+ case 13: // BREAK
+ a(fac.createNew("org.xwt.mips.Runtime$ExecutionException"));
+ a(InstructionConstants.DUP);
+ a(new PUSH(cp,"BREAK Code " + toHex(breakCode)));
+ a(fac.createInvoke("org.xwt.mips.Runtime$ExecutionException","<init>",Type.VOID,new Type[]{Type.STRING},INVOKESPECIAL));
+ a(InstructionConstants.ATHROW);
+ unreachable = true;
+ break;
+ case 16: // MFHI
+ preSetReg(R+rd);
+ pushReg(HI);
+ setReg();
+ break;
+ case 17: // MTHI
+ preSetReg(HI);
+ pushRegZ(R+rs);
+ setReg();
+ break;
+ case 18: // MFLO
+ preSetReg(R+rd);
+ pushReg(LO);
+ setReg();
+ break;
+ case 19: // MTLO
+ preSetReg(LO);
+ pushRegZ(R+rs);
+ setReg();
+ break;
+ case 24: // MULT
+ pushRegWZ(R+rs);
+ a(InstructionConstants.I2L);
+ pushRegWZ(R+rt);
+ a(InstructionConstants.I2L);
+ a(InstructionConstants.LMUL);
+ a(InstructionConstants.DUP2);
+
+ a(InstructionConstants.L2I);
+ if(preSetReg(LO))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ pushConst(32);
+ a(InstructionConstants.LUSHR);
+ a(InstructionConstants.L2I);
+ if(preSetReg(HI))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ break;
+ case 25: // MULTU
+ pushRegWZ(R+rs);
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+ a(InstructionConstants.LAND);
+ pushRegWZ(R+rt);
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+ a(InstructionConstants.LAND);
+ a(InstructionConstants.LMUL);
+ a(InstructionConstants.DUP2);
+
+ a(InstructionConstants.L2I);
+ if(preSetReg(LO))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ pushConst(32);
+ a(InstructionConstants.LUSHR);
+ a(InstructionConstants.L2I);
+ if(preSetReg(HI))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ break;
+ case 26: // DIV
+ pushRegWZ(R+rs);
+ pushRegWZ(R+rt);
+ a(InstructionConstants.DUP2);
+
+ a(InstructionConstants.IDIV);
+ if(preSetReg(LO))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ a(InstructionConstants.IREM);
+ if(preSetReg(HI))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ break;
+ case 27: { // DIVU
+ pushRegWZ(R+rt);
+ a(InstructionConstants.DUP);
+ setTmp();
+ b1 = a(InstructionFactory.createBranchInstruction(IFEQ,null));
+
+ pushRegWZ(R+rs);
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+ a(InstructionConstants.LAND);
+ a(InstructionConstants.DUP2);
+ pushTmp();
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+
+ a(InstructionConstants.LAND);
+ a(InstructionConstants.DUP2_X2);
+ a(InstructionConstants.LDIV);
+
+ a(InstructionConstants.L2I);
+ if(preSetReg(LO))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ a(InstructionConstants.LREM);
+ a(InstructionConstants.L2I);
+ if(preSetReg(HI))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ b1.setTarget(a(InstructionConstants.NOP));
+
+ break;
+ }
+ case 32: // ADD
+ throw new Exn("ADD (add with oveflow trap) not suported");
+ case 33: // ADDU
+ preSetReg(R+rd);
+ if(rt != 0 && rs != 0) {
+ pushReg(R+rs);
+ pushReg(R+rt);
+ a(InstructionConstants.IADD);
+ } else if(rs != 0) {
+ pushReg(R+rs);
+ } else {
+ pushRegZ(R+rt);
+ }
+ setReg();
+ break;
+ case 34: // SUB
+ throw new Exn("SUB (add with oveflow trap) not suported");
+ case 35: // SUBU
+ preSetReg(R+rd);
+ if(rt != 0 && rs != 0) {
+ pushReg(R+rs);
+ pushReg(R+rt);
+ a(InstructionConstants.ISUB);
+ } else if(rt != 0) {
+ pushReg(R+rt);
+ a(InstructionConstants.INEG);
+ } else {
+ pushRegZ(R+rs);
+ }
+ setReg();
+ break;
+ case 36: // AND
+ preSetReg(R+rd);
+ pushRegWZ(R+rs);
+ pushRegWZ(R+rt);
+ a(InstructionConstants.IAND);
+ setReg();
+ break;
+ case 37: // OR
+ preSetReg(R+rd);
+ pushRegWZ(R+rs);
+ pushRegWZ(R+rt);
+ a(InstructionConstants.IOR);
+ setReg();
+ break;
+ case 38: // XOR
+ preSetReg(R+rd);
+ pushRegWZ(R+rs);
+ pushRegWZ(R+rt);
+ a(InstructionConstants.IXOR);
+ setReg();
+ break;
+ case 39: // NOR
+ preSetReg(R+rd);
+ if(rs != 0 || rt != 0) {
+ if(rs != 0 && rt != 0) {
+ pushReg(R+rs);
+ pushReg(R+rt);
+ a(InstructionConstants.IOR);
+ } else if(rs != 0) {
+ pushReg(R+rs);
+ } else {
+ pushReg(R+rt);
+ }
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ } else {
+ pushConst(-1);
+ }
+ setReg();
+ break;
+ case 42: // SLT
+ preSetReg(R+rd);
+ if(rs != rt) {
+ pushRegZ(R+rs);
+ pushRegZ(R+rt);
+ b1 = a(InstructionFactory.createBranchInstruction(IF_ICMPLT,null));
+ a(InstructionConstants.ICONST_0);
+ b2 = a(InstructionFactory.createBranchInstruction(GOTO,null));
+ b1.setTarget(a(InstructionConstants.ICONST_1));
+ b2.setTarget(a(InstructionConstants.NOP));
+ } else {
+ pushConst(0);
+ }
+ setReg();
+ break;
+ case 43: // SLTU
+ preSetReg(R+rd);
+ if(rs != rt) {
+ if(rs != 0) {
+ pushReg(R+rs);
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+ a(InstructionConstants.LAND);
+ pushReg(R+rt);
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+ a(InstructionConstants.LAND);
+ a(InstructionConstants.LCMP);
+ b1 = a(InstructionFactory.createBranchInstruction(IFLT,null));
+ } else {
+ pushReg(R+rt);
+ b1 = a(InstructionFactory.createBranchInstruction(IFNE,null));
+ }
+ a(InstructionConstants.ICONST_0);
+ b2 = a(InstructionFactory.createBranchInstruction(GOTO,null));
+ b1.setTarget(a(InstructionConstants.ICONST_1));
+ b2.setTarget(a(InstructionConstants.NOP));
+ } else {
+ pushConst(0);
+ }
+ setReg();
+ break;
+ default:
+ throw new RuntimeException("Illegal instruction 0/" + subcode);
+ }
+ break;
+ }
+ case 1: {
+ switch(rt) {
+ case 0: // BLTZ
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ pushRegWZ(R+rs);
+ return doIfInstruction(IFLT,pc,pc+branchTarget*4+4,nextInsn);
+ case 1: // BGEZ
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ pushRegWZ(R+rs);
+ return doIfInstruction(IFGE,pc,pc+branchTarget*4+4,nextInsn);
+ case 16: // BLTZAL
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ pushRegWZ(R+rs);
+ b1 = a(InstructionFactory.createBranchInstruction(IFGE,null));
+ emitInstruction(-1,nextInsn,-1);
+ preSetReg(R+RA);
+ pushConst(pc+8);
+ setReg();
+ branch(pc,pc+branchTarget*4+4);
+ b1.setTarget(a(InstructionConstants.NOP));
+ break;
+ case 17: // BGEZAL
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ b1 = null;
+ if(rs != 0) { // r0 is always >= 0
+ pushRegWZ(R+rs);
+ b1 = a(InstructionFactory.createBranchInstruction(IFLT,null));
+ }
+ emitInstruction(-1,nextInsn,-1);
+ preSetReg(R+RA);
+ pushConst(pc+8);
+ setReg();
+ branch(pc,pc+branchTarget*4+4);
+ if(b1 != null) b1.setTarget(a(InstructionConstants.NOP));
+ if(b1 == null) unreachable = true;
+ break;
+ default:
+ throw new RuntimeException("Illegal Instruction 1/" + rt);
+ }
+ break;
+ }
+ case 2: { // J
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,(pc&0xf0000000)|(jumpTarget << 2));
+ unreachable = true;
+ break;
+ }
+ case 3: { // JAL
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ int target = (pc&0xf0000000)|(jumpTarget << 2);
+ emitInstruction(-1,nextInsn,-1);
+ if(optimizedMemcpy && (target == memcpy || target == memset)) {
+ a(InstructionConstants.ALOAD_0);
+ pushRegZ(R+4);
+ pushRegZ(R+5);
+ pushRegZ(R+6);
+ a(fac.createInvoke(fullClassName,target==memcpy ? "memcpy" : "memset", Type.VOID, new Type[]{Type.INT,Type.INT,Type.INT},INVOKEVIRTUAL));
+ preSetReg(R+2);
+ pushReg(R+4);
+ setReg();
+ branch(pc,pc+8);
+ } else {
+ preSetReg(R+RA);
+ pushConst(pc+8);
+ setReg();
+ branch(pc, target);
+ }
+ unreachable = true;
+ break;
+ }
+ case 4: // BEQ
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ if(rs == rt) {
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ unreachable = true;
+ } else if(rs == 0 || rt == 0) {
+ pushReg(rt == 0 ? R+rs : R+rt);
+ return doIfInstruction(IFEQ,pc,pc+branchTarget*4+4,nextInsn);
+ } else {
+ pushReg(R+rs);
+ pushReg(R+rt);
+ return doIfInstruction(IF_ICMPEQ,pc,pc+branchTarget*4+4,nextInsn);
+ }
+ break;
+ case 5: // BNE
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ pushRegWZ(R+rs);
+ if(rt == 0) {
+ return doIfInstruction(IFNE,pc,pc+branchTarget*4+4,nextInsn);
+ } else {
+ pushReg(R+rt);
+ return doIfInstruction(IF_ICMPNE,pc,pc+branchTarget*4+4,nextInsn);
+ }
+ case 6: //BLEZ
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ pushRegWZ(R+rs);
+ return doIfInstruction(IFLE,pc,pc+branchTarget*4+4,nextInsn);
+ case 7: //BGTZ
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ pushRegWZ(R+rs);
+ return doIfInstruction(IFGT,pc,pc+branchTarget*4+4,nextInsn);
+ case 8: // ADDI
+ throw new Exn("ADDI (add immediate with oveflow trap) not suported");
+ case 9: // ADDIU
+ preSetReg(R+rt);
+ addiu(rs,signedImmediate);
+ setReg();
+ break;
+ case 10: // SLTI
+ preSetReg(R+rt);
+ pushRegWZ(R+rs);
+ pushConst(signedImmediate);
+ b1 = a(InstructionFactory.createBranchInstruction(IF_ICMPLT,null));
+ a(InstructionConstants.ICONST_0);
+ b2 = a(InstructionFactory.createBranchInstruction(GOTO,null));
+ b1.setTarget(a(InstructionConstants.ICONST_1));
+ b2.setTarget(a(InstructionConstants.NOP));
+ setReg();
+ break;
+ case 11: // SLTIU
+ preSetReg(R+rt);
+ pushRegWZ(R+rs);
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+ a(InstructionConstants.LAND);
+ pushConst((long)unsignedImmediate);
+ a(InstructionConstants.LCMP);
+
+ b1 = a(InstructionFactory.createBranchInstruction(IFLT,null));
+ a(InstructionConstants.ICONST_0);
+ b2 = a(InstructionFactory.createBranchInstruction(GOTO,null));
+ b1.setTarget(a(InstructionConstants.ICONST_1));
+ b2.setTarget(a(InstructionConstants.NOP));
+
+ setReg();
+ break;
+ case 12: // ANDI
+ preSetReg(R+rt);
+ pushRegWZ(R+rs);
+ pushConst(unsignedImmediate);
+ a(InstructionConstants.IAND);
+ setReg();
+ break;
+ case 13: // ORI
+ preSetReg(R+rt);
+ if(rs != 0 && unsignedImmediate != 0) {
+ pushReg(R+rs);
+ pushConst(unsignedImmediate);
+ a(InstructionConstants.IOR);
+ } else if(rs != 0){
+ pushReg(R+rs);
+ } else {
+ pushConst(unsignedImmediate);
+ }
+ setReg();
+ break;
+ case 14: // XORI
+ preSetReg(R+rt);
+ pushRegWZ(R+rs);
+ pushConst(unsignedImmediate);
+ a(InstructionConstants.IXOR);
+ setReg();
+ break;
+ case 15: // LUI
+ preSetReg(R+rt);
+ pushConst(unsignedImmediate << 16);
+ setReg();
+ break;
+ case 16:
+ throw new Exn("TLB/Exception support not implemented");
+ case 17: { // FPU
+ switch(rs) {
+ case 0: // MFC.1
+ preSetReg(R+rt);
+ pushReg(F+rd);
+ setReg();
+ break;
+ case 2: // CFC.1
+ if(fs != 31) throw new Exn("FCR " + fs + " unavailable");
+ preSetReg(R+rt);
+ pushReg(FCSR);
+ setReg();
+ break;
+ case 4: // MTC.1
+ preSetReg(F+rd);
+ if(rt != 0)
+ pushReg(R+rt);
+ else
+ pushConst(0);
+ setReg();
+ break;
+ case 6: // CTC.1
+ if(fs != 31) throw new Exn("FCR " + fs + " unavailable");
+ preSetReg(FCSR);
+ pushReg(R+rt);
+ setReg();
+ break;
+ case 8: {// BC1F, BC1T
+ pushReg(FCSR);
+ pushConst(0x800000);
+ a(InstructionConstants.IAND);
+ return doIfInstruction(((insn>>>16)&1) == 0 ? IFEQ : IFNE,pc,pc+branchTarget*4+4,nextInsn);
+ }
+ case 16:
+ case 17:
+ { // Single/Double math
+ boolean d = rs == 17;
+ switch(subcode) {
+ case 0: // ADD.X
+ preSetDouble(F+fd,d);
+ pushDouble(F+fs,d);
+ pushDouble(F+ft,d);
+ a(d ? InstructionConstants.DADD : InstructionConstants.FADD);
+ setDouble(d);
+ break;
+ case 1: // SUB.X
+ preSetDouble(F+fd,d);
+ pushDouble(F+fs,d);
+ pushDouble(F+ft,d);
+ a(d ? InstructionConstants.DSUB : InstructionConstants.FSUB);
+ setDouble(d);
+ break;
+ case 2: // MUL.X
+ preSetDouble(F+fd,d);
+ pushDouble(F+fs,d);
+ pushDouble(F+ft,d);
+ a(d ? InstructionConstants.DMUL : InstructionConstants.FMUL);
+ setDouble(d);
+ break;
+ case 3: // DIV.X
+ preSetDouble(F+fd,d);
+ pushDouble(F+fs,d);
+ pushDouble(F+ft,d);
+ a(d ? InstructionConstants.DDIV : InstructionConstants.FDIV);
+ setDouble(d);
+ break;
+ case 5: // ABS.X
+ preSetDouble(F+fd,d);
+ // NOTE: We can't use fneg/dneg here since they'll turn +0.0 into -0.0
+
+ pushDouble(F+fs,d);
+ a(d ? InstructionConstants.DUP2 : InstructionConstants.DUP);
+ a(d ? InstructionConstants.DCONST_0 : InstructionConstants.FCONST_0);
+ a(d ? InstructionConstants.DCMPG : InstructionConstants.FCMPG);
+
+ b1 = a(InstructionFactory.createBranchInstruction(IFGT,null));
+ a(d ? InstructionConstants.DCONST_0 : InstructionConstants.FCONST_0);
+ if(d) {
+ a(InstructionConstants.DUP2_X2);
+ a(InstructionConstants.POP2);
+ } else {
+ a(InstructionConstants.POP);
+ }
+ a(InstructionConstants.DSUB);
+
+ b1.setTarget(setDouble(d));
+
+ break;
+ case 6: // MOV.X
+ preSetReg(F+fd);
+ pushReg(F+fs);
+ setReg();
+
+ preSetReg(F+fd+1);
+ pushReg(F+fs+1);
+ setReg();
+
+ break;
+ case 7: // NEG.X
+ preSetDouble(F+fd,d);
+ pushDouble(F+fs,d);
+ a(d ? InstructionConstants.DNEG : InstructionConstants.FNEG);
+ setDouble(d);
+ break;
+ case 32: // CVT.S.X
+ preSetFloat(F+fd);
+ pushDouble(F+fd,d);
+ if(d) a(InstructionConstants.D2F);
+ setFloat();
+ break;
+ case 33: // CVT.D.X
+ preSetDouble(F+fd);
+ pushDouble(F+fd,d);
+ if(!d) a(InstructionConstants.F2D);
+ setDouble();
+ break;
+ case 36: { // CVT.W.D
+ int[] matches = new int[4];
+ for(int i=0;i<4;i++) matches[i] = i;
+
+ TABLESWITCH ts = new TABLESWITCH(matches,new InstructionHandle[4], null);
+
+ preSetReg(F+fd);
+ pushDouble(F+fs,d);
+ pushReg(FCSR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(ts);
+
+ // Round towards plus infinity
+ ts.setTarget(2,a(InstructionConstants.NOP));
+ if(!d) a(InstructionConstants.F2D); // Ugh.. java.lang.Math doesn't have a float ceil/floor
+ a(fac.createInvoke("java.lang.Math","ceil",Type.DOUBLE,new Type[]{Type.DOUBLE},INVOKESTATIC));
+ if(!d) a(InstructionConstants.D2F);
+ b1 = a(InstructionFactory.createBranchInstruction(GOTO,null));
+
+ // Round to nearest
+ ts.setTarget(0,d ? pushConst(0.5d) : pushConst(0.5f));
+ a(d ? InstructionConstants.DADD : InstructionConstants.FADD);
+ // fall through
+
+ // Round towards minus infinity
+ ts.setTarget(3,a(InstructionConstants.NOP));
+ if(!d) a(InstructionConstants.F2D);
+ a(fac.createInvoke("java.lang.Math","floor",Type.DOUBLE,new Type[]{Type.DOUBLE},INVOKESTATIC));
+ if(!d) a(InstructionConstants.D2F);
+
+ InstructionHandle h = a(d ? InstructionConstants.D2I : InstructionConstants.F2I);
+ setReg();
+
+ ts.setTarget(1,h);
+ ts.setTarget(h);
+ b1.setTarget(h);
+
+ break;
+ }
+ case 50: // C.EQ.D
+ case 60: // C.LT.D
+ case 62: // C.LE.D
+ preSetReg(FCSR);
+ pushReg(FCSR);
+ pushConst(~0x800000);
+ a(InstructionConstants.IAND);
+ pushDouble(F+fs,d);
+ pushDouble(F+ft,d);
+ a(d ? InstructionConstants.DCMPG : InstructionConstants.FCMPG);
+ switch(subcode) {
+ case 50: b1 = a(InstructionFactory.createBranchInstruction(IFEQ,null)); break;
+ case 60: b1 = a(InstructionFactory.createBranchInstruction(IFLT,null)); break;
+ case 62: b1 = a(InstructionFactory.createBranchInstruction(IFLE,null)); break;
+ default: b1 = null;
+ }
+
+ pushConst(0x000000);
+ b2 = a(InstructionFactory.createBranchInstruction(GOTO,null));
+ b1.setTarget(pushConst(0x800000));
+ b2.setTarget(a(InstructionConstants.IOR));
+ setReg();
+ break;
+ default: throw new Exn("Invalid Instruction 17/" + rs + "/" + subcode);
+ }
+ break;
+ }
+ case 20: { // Integer
+ switch(subcode) {
+ case 32: // CVT.S.W
+ preSetFloat(F+fd);
+ pushReg(F+fs);
+ a(InstructionConstants.I2F);
+ setFloat();
+ break;
+ case 33: // CVT.D.W
+ preSetDouble(F+fd);
+ pushReg(F+fs);
+ a(InstructionConstants.I2D);
+ setDouble();
+ break;
+ default: throw new Exn("Invalid Instruction 17/" + rs + "/" + subcode);
+ }
+ break;
+ }
+ default:
+ throw new Exn("Invalid Instruction 17/" + rs);
+ }
+ break;
+ }
+ case 18: case 19:
+ throw new Exn("coprocessor 2 and 3 instructions not available");
+ case 32: { // LB
+ preSetReg(R+rt);
+ addiu(R+rs,signedImmediate);
+ setTmp();
+ preMemRead();
+ pushTmp();
+ memRead(true);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.I2B);
+ setReg();
+ break;
+ }
+ case 33: { // LH
+ preSetReg(R+rt);
+ addiu(R+rs,signedImmediate);
+ setTmp();
+ preMemRead();
+ pushTmp();
+ memRead(true);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.I2S);
+ setReg();
+ break;
+ }
+ case 34: { // LWL;
+ preSetReg(R+rt);
+ addiu(R+rs,signedImmediate);
+ setTmp(); // addr
+
+ pushRegWZ(R+rt);
+ pushConst(0x00ffffff);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.IAND);
+
+ preMemRead();
+ pushTmp();
+ memRead(true);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IOR);
+
+ setReg();
+
+ break;
+
+ }
+ case 35: // LW
+ preSetReg(R+rt);
+ memRead(R+rs,signedImmediate);
+ setReg();
+ break;
+ case 36: { // LBU
+ preSetReg(R+rt);
+ addiu(R+rs,signedImmediate);
+ setTmp();
+ preMemRead();
+ pushTmp();
+ memRead(true);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ pushConst(0xff);
+ a(InstructionConstants.IAND);
+ setReg();
+ break;
+ }
+ case 37: { // LHU
+ preSetReg(R+rt);
+ addiu(R+rs,signedImmediate);
+ setTmp();
+ preMemRead();
+ pushTmp();
+ memRead(true);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+
+ // chars are unsigend so this works
+ a(InstructionConstants.I2C);
+ setReg();
+ break;
+ }
+ case 38: { // LWR
+ preSetReg(R+rt);
+ addiu(R+rs,signedImmediate);
+ setTmp(); // addr
+
+ pushRegWZ(R+rt);
+ pushConst(0xffffff00);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IAND);
+
+ preMemRead();
+ pushTmp();
+ memRead(true);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.IOR);
+
+
+ setReg();
+ break;
+ }
+ case 40: { // SB
+ addiu(R+rs,signedImmediate);
+ setTmp(); // addr
+
+ // FEATURE: DO the preMemRead(true) thing for the rest of the S* instructions
+ preMemRead(true);
+ pushTmp();
+ memRead(true);
+
+ pushConst(0xff000000);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.IAND);
+
+ if(rt != 0) {
+ pushReg(R+rt);
+ pushConst(0xff);
+ a(InstructionConstants.IAND);
+ } else {
+ pushConst(0);
+ }
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IOR);
+
+ memWrite();
+
+ break;
+ }
+ case 41: { // SH
+ preMemWrite1();
+
+ addiu(R+rs,signedImmediate);
+
+ a(InstructionConstants.DUP);
+ setTmp(); // addr
+
+ preMemWrite2(true);
+
+ preMemRead();
+ pushTmp();
+ memRead(true);
+
+ pushConst(0xffff);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IAND);
+
+ if(rt != 0) {
+ pushReg(R+rt);
+ pushConst(0xffff);
+ a(InstructionConstants.IAND);
+ } else {
+ pushConst(0);
+ }
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IOR);
+
+ memWrite();
+
+ break;
+ }
+ case 42: { // SWL
+ preMemWrite1();
+
+ addiu(R+rs,signedImmediate);
+ a(InstructionConstants.DUP);
+ setTmp(); // addr
+
+ preMemWrite2(true);
+
+ preMemRead();
+ pushTmp();
+ memRead(true);
+
+ pushConst(0xffffff00);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IAND);
+
+ pushRegWZ(R+rt);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.IOR);
+
+ memWrite();
+ break;
+
+ }
+ case 43: // SW
+ preMemWrite1();
+ preMemWrite2(R+rs,signedImmediate);
+ pushRegZ(R+rt);
+ memWrite();
+ break;
+ case 46: { // SWR
+ preMemWrite1();
+
+ addiu(R+rs,signedImmediate);
+ a(InstructionConstants.DUP);
+ setTmp(); // addr
+
+ preMemWrite2(true);
+
+ preMemRead();
+ pushTmp();
+ memRead(true);
+
+ pushConst(0x00ffffff);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.IAND);
+
+ pushRegWZ(R+rt);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IOR);
+
+ memWrite();
+ break;
+ }
+ // FEATURE: This need to be atomic if we ever support threads (see SWC0/SC)
+ case 48: // LWC0/LL
+ preSetReg(R+rt);
+ memRead(R+rs,signedImmediate);
+ setReg();
+ break;
+
+ case 49: // LWC1
+ preSetReg(F+rt);
+ memRead(R+rs,signedImmediate);
+ setReg();
+ break;
+
+ /* FEATURE: This needs to fail (set rt to 0) if the memory location was modified
+ * between the LL and SC if we every support threads.
+ */
+ case 56: // SWC0/SC
+ preSetReg(R+rt);
+ preMemWrite1();
+ preMemWrite2(R+rs,signedImmediate);
+ pushReg(R+rt);
+ memWrite();
+ pushConst(1);
+ setReg();
+ break;
+
+ case 57: // SWC1
+ preMemWrite1();
+ preMemWrite2(R+rs,signedImmediate);
+ pushReg(F+rt);
+ memWrite();
+ break;
+ default:
+ throw new Exn("Invalid Instruction: " + op + " at " + toHex(pc));
+ }
+ return false;
+ }
+
+ // Helper functions for emitText
+
+ private static final int R = 0;
+ private static final int F = 32;
+ private static final int HI = 64;
+ private static final int LO = 65;
+ private static final int FCSR = 66;
+ private static final int REG_COUNT=67;
+
+ private int[] regLocalMapping = new int[REG_COUNT];
+ private int[] regLocalReadCount = new int[REG_COUNT];
+ private int[] regLocalWriteCount = new int[REG_COUNT];
+ private int nextAvailLocal;
+
+ private int getLocalForReg(int reg) {
+ if(regLocalMapping[reg] != 0) return regLocalMapping[reg];
+ if(nextAvailLocal == 0) nextAvailLocal = onePage ? 3 : 4;
+ regLocalMapping[reg] = nextAvailLocal++;
+ return regLocalMapping[reg];
+ }
+
+ private void fixupRegs() {
+ InstructionHandle prev = realStart;
+ for(int i=0;i<REG_COUNT;i++) {
+ if(regLocalMapping[i] == 0) continue;
+
+ prev = insnList.append(prev,InstructionConstants.ALOAD_0);
+ prev = insnList.append(prev,fac.createFieldAccess(fullClassName,regField(i),Type.INT, GETFIELD));
+ prev = insnList.append(prev,InstructionFactory.createStore(Type.INT,regLocalMapping[i]));
+
+ if(regLocalWriteCount[i] > 0) {
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionFactory.createLoad(Type.INT,regLocalMapping[i]));
+ a(fac.createFieldAccess(fullClassName,regField(i),Type.INT, PUTFIELD));
+ }
+
+ regLocalMapping[i] = regLocalReadCount[i] = regLocalWriteCount[i] = 0;
+ }
+ nextAvailLocal = 0;
+ }
+
+ private void restoreChangedRegs() {
+ for(int i=0;i<REG_COUNT;i++) {
+ if(regLocalWriteCount[i] > 0) {
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionFactory.createLoad(Type.INT,regLocalMapping[i]));
+ a(fac.createFieldAccess(fullClassName,regField(i),Type.INT, PUTFIELD));
+ }
+ }
+ }
+
+ private String regField(int reg) {
+ String field;
+ switch(reg) {
+ case HI: field = "hi"; break;
+ case LO: field = "lo"; break;
+ case FCSR: field = "fcsr"; break;
+ default:
+ if(reg > R && reg < R+32) field="r"+(reg-R);
+ else if(reg >= F && reg < F+32) field="f"+(reg-F);
+ else throw new IllegalArgumentException(""+reg);
+ }
+ return field;
+ }
+
+ private boolean doLocal(int reg) { return reg == R+2 || reg == R+3 || reg == R+4 || reg == R+29; }
+
+ private InstructionHandle pushRegWZ(int reg) {
+ if(reg == R+0) {
+ warn.println("Warning: Pushing r0!");
+ new Exception().printStackTrace(warn);
+ }
+ return pushRegZ(reg);
+ }
+
+ private InstructionHandle pushRegZ(int reg) {
+ if(reg == R+0) return pushConst(0);
+ else return pushReg(reg);
+ }
+
+
+ private InstructionHandle pushReg(int reg) {
+ InstructionHandle h;
+ if(doLocal(reg)) {
+ regLocalReadCount[reg]++;
+ h = a(InstructionFactory.createLoad(Type.INT,getLocalForReg(reg)));
+ } else {
+ h = a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,regField(reg),Type.INT, GETFIELD));
+ }
+ return h;
+ }
+
+ private int preSetRegStackPos;
+ private int[] preSetRegStack = new int[8];
+
+ // This can push ONE or ZERO words to the stack. If it pushed one it returns true
+ private boolean preSetReg(int reg) {
+ regField(reg); // just to check for validity
+ preSetRegStack[preSetRegStackPos] = reg;
+ preSetRegStackPos++;
+ if(doLocal(reg)) {
+ return false;
+ } else {
+ a(InstructionConstants.ALOAD_0);
+ return true;
+ }
+ }
+
+ private InstructionHandle setReg() {
+ if(preSetRegStackPos==0) throw new RuntimeException("didn't do preSetReg");
+ preSetRegStackPos--;
+ int reg = preSetRegStack[preSetRegStackPos];
+ InstructionHandle h;
+ if(doLocal(reg)) {
+ h = a(InstructionFactory.createStore(Type.INT,getLocalForReg(reg)));
+ regLocalWriteCount[reg]++;
+ } else {
+ h = a(fac.createFieldAccess(fullClassName,regField(reg),Type.INT, PUTFIELD));
+ }
+ return h;
+ }
+
+ private InstructionHandle preSetPC() { return a(InstructionConstants.ALOAD_0); }
+ private InstructionHandle setPC() { return a(fac.createFieldAccess(fullClassName,"pc",Type.INT, PUTFIELD)); }
+
+ //unused - private InstructionHandle pushFloat(int reg) throws CompilationException { return pushDouble(reg,false); }
+ //unused - private InstructionHandle pushDouble(int reg) throws CompilationException { return pushDouble(reg,true); }
+ private InstructionHandle pushDouble(int reg, boolean d) throws Exn {
+ if(reg < F || reg >= F+32) throw new IllegalArgumentException(""+reg);
+ InstructionHandle h;
+ if(d) {
+ if(reg == F+31) throw new Exn("Tried to use a double in f31");
+ h = pushReg(reg+1);
+ a(InstructionConstants.I2L);
+ pushConst(32);
+ a(InstructionConstants.LSHL);
+ pushReg(reg);
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+ a(InstructionConstants.LAND);
+ a(InstructionConstants.LOR);
+ //p("invokestatic java/lang/Double/longBitsToDouble(J)D");
+ a(fac.createInvoke("java.lang.Double","longBitsToDouble",Type.DOUBLE,new Type[]{Type.LONG},INVOKESTATIC));
+ } else {
+ h = pushReg(reg);
+ a(fac.createInvoke("java.lang.Float","intBitsToFloat",Type.FLOAT,new Type[]{Type.INT},INVOKESTATIC));
+ }
+ return h;
+ }
+
+ private void preSetFloat(int reg) { preSetDouble(reg,false); }
+ private void preSetDouble(int reg) { preSetDouble(reg,true); }
+ private void preSetDouble(int reg, boolean d) { preSetReg(reg); }
+
+ private InstructionHandle setFloat() throws Exn { return setDouble(false); }
+ private InstructionHandle setDouble() throws Exn { return setDouble(true); }
+ private InstructionHandle setDouble(boolean d) throws Exn {
+ int reg = preSetRegStack[preSetRegStackPos-1];
+ if(reg < F || reg >= F+32) throw new IllegalArgumentException(""+reg);
+ //p("invokestatic java/lang/Double/doubleToLongBits(D)J");
+ InstructionHandle h;
+ if(d) {
+ if(reg == F+31) throw new Exn("Tried to use a double in f31");
+ h = a(fac.createInvoke("java.lang.Double","doubleToLongBits",Type.LONG,new Type[]{Type.DOUBLE},INVOKESTATIC));
+ a(InstructionConstants.DUP2);
+ pushConst(32);
+ a(InstructionConstants.LUSHR);
+ a(InstructionConstants.L2I);
+ if(preSetReg(reg+1))
+ a(InstructionConstants.SWAP);
+ setReg();
+ a(InstructionConstants.L2I);
+ setReg(); // preSetReg was already done for this by preSetDouble
+ } else {
+ h = a(fac.createInvoke("java.lang.Float","floatToRawIntBits",Type.INT,new Type[]{Type.FLOAT},INVOKESTATIC));
+ setReg();
+ }
+ return h;
+ }
+
+ private InstructionHandle pushConst(int n) {
+ if(n >= 0 && n <= 5) {
+ switch(n) {
+ case 0: return a(InstructionConstants.ICONST_0);
+ case 1: return a(InstructionConstants.ICONST_1);
+ case 2: return a(InstructionConstants.ICONST_2);
+ case 3: return a(InstructionConstants.ICONST_3);
+ case 4: return a(InstructionConstants.ICONST_4);
+ case 5: return a(InstructionConstants.ICONST_5);
+ default: return null;
+ }
+ } else if(n == -1) {
+ return a(InstructionConstants.ICONST_M1);
+ } else if(n >= -128 && n <= 127) {
+ return a(new BIPUSH((byte) n));
+ } else if(n >= -32768 && n <= 32767) {
+ return a(new SIPUSH((short) n));
+ } else {
+ return a(new PUSH(cp,n));
+ }
+ }
+
+ private InstructionHandle pushConst(long l) { return a(new PUSH(cp,l)); }
+ private InstructionHandle pushConst(float f) { return a(new PUSH(cp,f)); }
+ private InstructionHandle pushConst(double d) { return a(new PUSH(cp,d)); }
+
+ private void pushTmp() { a(InstructionConstants.ILOAD_1); }
+ private void setTmp() { a(InstructionConstants.ISTORE_1); }
+
+ private void addiu(int reg, int offset) {
+ if(reg != R+0 && offset != 0) {
+ pushReg(reg);
+ pushConst(offset);
+ a(InstructionConstants.IADD);
+ } else if(reg != R+0) {
+ pushReg(reg);
+ } else {
+ pushConst(offset);
+ }
+ }
+ private int memWriteStage;
+ private void preMemWrite1() {
+ if(memWriteStage!=0) throw new Error("pending preMemWrite1/2");
+ memWriteStage=1;
+ if(onePage)
+ a(InstructionConstants.ALOAD_2);
+ else if(fastMem)
+ a(InstructionFactory.createLoad(Type.OBJECT,3));
+ else
+ a(InstructionConstants.ALOAD_0);
+ }
+
+ private void preMemWrite2(int reg, int offset) {
+ addiu(reg,offset);
+ preMemWrite2();
+ }
+
+ private void preMemWrite2() { preMemWrite2(false); }
+ private void preMemWrite2(boolean addrInTmp) {
+ if(memWriteStage!=1) throw new Error("pending preMemWrite2 or no preMemWrite1");
+ memWriteStage=2;
+
+ if(nullPointerCheck) {
+ a(InstructionConstants.DUP);
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.SWAP);
+ a(fac.createInvoke(fullClassName,"nullPointerCheck",Type.VOID,new Type[]{Type.INT},INVOKEVIRTUAL));
+ }
+
+ if(onePage) {
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IUSHR);
+ } else if(fastMem) {
+ if(!addrInTmp)
+ a(InstructionConstants.DUP_X1);
+ pushConst(pageShift);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.AALOAD);
+ if(addrInTmp)
+ pushTmp();
+ else
+ a(InstructionConstants.SWAP);
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IUSHR);
+ pushConst((pageSize>>2)-1);
+ a(InstructionConstants.IAND);
+ }
+ }
+
+ // pops an address and value off the stack, sets *addr to value
+ private void memWrite() {
+ if(memWriteStage!=2) throw new Error("didn't do preMemWrite1 or preMemWrite2");
+ memWriteStage=0;
+
+ if(onePage) {
+ a(InstructionConstants.IASTORE);
+ } else if(fastMem) {
+ a(InstructionConstants.IASTORE);
+ } else {
+ a(fac.createInvoke(fullClassName,"unsafeMemWrite",Type.VOID,new Type[]{Type.INT,Type.INT},INVOKEVIRTUAL));
+ }
+
+ }
+
+ // reads the word at r[reg]+offset
+ private void memRead(int reg, int offset) {
+ preMemRead();
+ addiu(reg,offset);
+ memRead();
+ }
+
+ private boolean didPreMemRead;
+ private boolean preMemReadDoPreWrite;
+
+ private void preMemRead() { preMemRead(false); }
+ private void preMemRead(boolean preWrite) {
+ if(didPreMemRead) throw new Error("pending preMemRead");
+ didPreMemRead = true;
+ preMemReadDoPreWrite = preWrite;
+ if(onePage)
+ a(InstructionConstants.ALOAD_2);
+ else if(fastMem)
+ a(InstructionFactory.createLoad(Type.OBJECT,preWrite ? 3 : 2));
+ else
+ a(InstructionConstants.ALOAD_0);
+ }
+ // memRead pops an address off the stack, reads the value at that addr, and pushed the value
+ // preMemRead MUST be called BEFORE the addresses is pushed
+ private void memRead() { memRead(false); }
+
+ private void memRead(boolean addrInTmp) {
+ if(!didPreMemRead) throw new Error("didn't do preMemRead");
+ didPreMemRead = false;
+ if(preMemReadDoPreWrite)
+ memWriteStage=2;
+
+ if(nullPointerCheck) {
+ a(InstructionConstants.DUP);
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.SWAP);
+ a(fac.createInvoke(fullClassName,"nullPointerCheck",Type.VOID,new Type[]{Type.INT},INVOKEVIRTUAL));
+ }
+
+ if(onePage) {
+ // p(target + "= page[(" + addr + ")>>>2];");
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IUSHR);
+ if(preMemReadDoPreWrite)
+ a(InstructionConstants.DUP2);
+ a(InstructionConstants.IALOAD);
+ } else if(fastMem) {
+ //p(target + " = readPages[("+addr+")>>>"+pageShift+"][(("+addr+")>>>2)&"+toHex((pageSize>>2)-1)+"];");
+
+ if(!addrInTmp)
+ a(InstructionConstants.DUP_X1);
+ pushConst(pageShift);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.AALOAD);
+ if(addrInTmp)
+ pushTmp();
+ else
+ a(InstructionConstants.SWAP);
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IUSHR);
+ pushConst((pageSize>>2)-1);
+ a(InstructionConstants.IAND);
+ if(preMemReadDoPreWrite)
+ a(InstructionConstants.DUP2);
+ a(InstructionConstants.IALOAD);
+
+ } else {
+ if(preMemReadDoPreWrite)
+ a(InstructionConstants.DUP2);
+ a(fac.createInvoke(fullClassName,"unsafeMemWrite",Type.INT,new Type[]{Type.INT},INVOKEVIRTUAL));
+ }
+ }
+
+
+ // This might come in handy for something else
+ /*private boolean touchesReg(int insn, int reg) {
+ if((reg < R+0 || reg >= R+32) && reg != FCSR) throw new IllegalArgumentException(""+reg);
+ if(reg == R+0) return false; // r0 is never modified
+ int op = (insn >>> 26) & 0xff; // bits 26-31
+ int subcode = insn & 0x3f; // bits 0-5
+ int rd = (insn >>> 11) & 0x1f; // bits 11-15
+ int rt = (insn >>> 16) & 0x1f; // bits 16-20
+ int rs = (insn >>> 21) & 0x1f; // bits 21-25
+
+ switch(op) {
+ case 0:
+ if(subcode >= 0 && subcode <= 7) return reg == R+rd; // Shift ops
+ if(subcode >= 32 && subcode <= 43) return reg == R+rd; // Other math ops
+ if(subcode >= 24 && subcode <= 27) return reg == HI || reg == LO; // MULT/DIV
+ break;
+ case 13: return false; // BREAK
+ case 17:
+ switch(rs) {
+ case 0: return reg == R+rt; // MFC.1
+ case 2: return reg == R+rt; // CFC.1
+ case 4: return false; // MTC.1
+ case 6: return false; // CTC.1
+ case 16: // Single
+ case 17: // Double
+ if(subcode == 50 || subcode == 60 || subcode == 62) return reg == FCSR;
+ return false; // everything else just touches f0-f31
+ case 20: return false; // Integer - just touches f0-f31
+ }
+ break;
+ default:
+ if(op >= 8 && op <= 15) return reg == R+rt; // XXXI instructions
+ if(op >= 40 && op <= 46) return false; // Memory WRITE ops
+ if(op == 49) return reg == F+rt; // LWC1
+ if(op == 57) return false; // SWC1
+ break;
+ }
+ warn.println("Unknown instruction in touchesReg()- assuming it modifies all regs " + op + " " + subcode);
+ new Exception().fillInStackTrace().printStackTrace(warn);
+ return true;
+ }*/
+}
--- /dev/null
+package org.xwt.mips;
+
+import java.io.*;
+
+// FEATURE: This is just a quick hack, it is really ugly and broken
+
+public class ClassLoader extends java.lang.ClassLoader {
+ public Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ Class c;
+ if(name.startsWith("mips.")) {
+ String path = name.substring(5).replace('.','/') + ".mips";
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ new ClassFileCompiler(path,name,bos).go();
+ bos.close();
+ byte[] buf = bos.toByteArray();
+ c = defineClass(name,buf,0,buf.length);
+ } catch(IOException e) {
+ throw new ClassNotFoundException(name);
+ } catch(Compiler.Exn e) {
+ throw new ClassNotFoundException(e.getMessage());
+ }
+ } else {
+ c = findSystemClass(name);
+ }
+
+ if(c == null) throw new ClassNotFoundException(name);
+ if(resolve) resolveClass(c);
+ return c;
+ }
+
+ public Class classFromBinary(String path) throws ClassNotFoundException {
+ if(!path.endsWith(".mips")) throw new IllegalArgumentException("isn't a .mips");
+ return loadClass("mips." + path.substring(0,path.length()-5).replace('/','.'));
+ }
+
+ public Runtime runtimeFromBinary(String path) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+ return (Runtime) classFromBinary(path).newInstance();
+ }
+
+ public static void main(String[] args) throws Exception {
+ System.exit(new ClassLoader().runtimeFromBinary(args[0]).run(args));
+ }
+}
--- /dev/null
+// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
+
+package org.xwt.mips;
+
+import java.util.*;
+import java.io.*;
+
+import org.xwt.mips.util.SeekableData;
+import org.xwt.mips.util.SeekableFile;
+
+public abstract class Compiler implements Registers {
+ /** The ELF binary being read */
+ protected ELF elf;
+
+ /** The name of the class beging generated */
+ protected final String fullClassName;
+
+ /** The name of the binary this class is begin generated from */
+ protected String source = "unknown.mips.binary";
+ public void setSource(String source) { this.source = source; }
+
+ /** Thrown when the compilation fails for some reason */
+ protected static class Exn extends Exception { public Exn(String s) { super(s); } }
+
+ // Set this to true to enable fast memory access
+ // When this is enabled a Java RuntimeException will be thrown when a page fault occures. When it is disabled
+ // a FaultException will be throw which is easier to catch and deal with, however. as the name implies, this is slower
+ protected boolean fastMem = true;
+
+ // This MUST be a power of two. If it is not horrible things will happen
+ // NOTE: This value can be much higher without breaking the classfile
+ // specs (around 1024) but Hotstop seems to do much better with smaller
+ // methods.
+ protected int maxInsnPerMethod = 128;
+
+ // non-configurable
+ protected int maxBytesPerMethod;
+ protected int methodMask;
+ protected int methodShift;
+ protected void maxInsnPerMethodInit() throws Exn {
+ if((maxInsnPerMethod&(maxInsnPerMethod-1)) != 0) throw new Exn("maxBytesPerMethod is not a power of two");
+ maxBytesPerMethod = maxInsnPerMethod*4;
+ methodMask = ~(maxBytesPerMethod-1);
+ while(maxBytesPerMethod>>>methodShift != 1) methodShift++;
+ }
+
+ // True to try to determine which case statement are needed and only include them
+ protected boolean pruneCases = true;
+
+ protected boolean assumeTailCalls = true;
+
+ protected boolean optimizedMemcpy = true;
+
+ // True to insert some code in the output to help diagnore compiler problems
+ protected boolean debugCompiler = false;
+
+ // True to print various statistics about the compilation
+ protected boolean printStats = false;
+
+ // True to generate runtime statistics that slow execution down significantly
+ protected boolean runtimeStats = false;
+
+ protected boolean supportCall = true;
+
+ protected boolean nullPointerCheck = false;
+
+ protected String runtimeClass = "org.xwt.mips.Runtime";
+
+ protected String hashClass = "java.util.Hashtable";
+
+ protected boolean unixRuntime;
+
+ protected boolean lessConstants = false;
+
+ protected int pageSize = 4096;
+ protected int totalPages = 65536;
+ protected int pageShift;
+ protected boolean onePage;
+
+ protected void pageSizeInit() throws Exn {
+ try {
+ Runtime.checkPageSize(pageSize,totalPages);
+ } catch(IllegalArgumentException e) {
+ throw new Exn(e.getMessage());
+ }
+ while(pageSize>>>pageShift != 1) pageShift++;
+ }
+
+ /** The address of the memcpy function in the binary (used for optimizedMemcpy) */
+ protected int memcpy;
+
+ /** The address of the memset function in the binary (used for optimizedMemcpy) */
+ protected int memset;
+
+ /** A set of all addresses that can be jumped too (only available if pruneCases == true) */
+ protected Set jumpableAddresses;
+
+ /** Some important symbols */
+ ELF.Symbol userInfo, gp;
+
+ private static void usage() {
+ System.err.println("Usage: java Compiler [-outfile output.java] [-o options] [-dumpoptions] <classname> <binary.mips>");
+ System.err.println("-o takes mount(8) like options and can be specified multiple times");
+ System.err.println("Available options:");
+ for(int i=0;i<options.length;i+=2)
+ System.err.print(options[i] + ": " + wrapAndIndent(options[i+1],18-2-options[i].length(),18,62));
+ System.exit(1);
+ }
+
+ public static void main(String[] args) throws IOException {
+ String outfile = null;
+ String o = null;
+ String className = null;
+ String mipsBinaryFileName = null;
+ String outformat = null;
+ boolean dumpOptions = false;
+ int arg = 0;
+ while(args.length-arg > 0) {
+ if(args[arg].equals("-outfile")) {
+ arg++;
+ if(arg==args.length) usage();
+ outfile = args[arg];
+ } else if(args[arg].equals("-outformat")) {
+ arg++;
+ if(arg==args.length) usage();
+ outformat = args[arg];
+ } else if(args[arg].equals("-o")) {
+ arg++;
+ if(arg==args.length) usage();
+ if(o==null || o.length() == 0)
+ o = args[arg];
+ else if(args[arg].length() != 0)
+ o += "," + args[arg];
+ } else if(args[arg].equals("-dumpoptions")) {
+ dumpOptions = true;
+ } else if(className == null) {
+ className = args[arg];
+ } else if(mipsBinaryFileName == null) {
+ mipsBinaryFileName = args[arg];
+ } else {
+ usage();
+ }
+ arg++;
+ }
+ if(className == null || mipsBinaryFileName == null) usage();
+
+ SeekableData mipsBinary = new SeekableFile(mipsBinaryFileName);
+
+ Writer w = null;
+ OutputStream os = null;
+ Compiler comp = null;
+ if(outformat == null || outformat.equals("class")) {
+ if(outfile == null) {
+ System.err.println("Refusing to write a classfile to stdout - use -outfile foo.class");
+ System.exit(1);
+ }
+ os = new FileOutputStream(outfile);
+ comp = new ClassFileCompiler(mipsBinary,className,os);
+ } else if(outformat.equals("javasource") || outformat .equals("java")) {
+ w = outfile == null ? new OutputStreamWriter(System.out): new FileWriter(outfile);
+ comp = new JavaSourceCompiler(mipsBinary,className,w);
+ } else {
+ System.err.println("Unknown output format: " + outformat);
+ System.exit(1);
+ }
+
+ comp.parseOptions(o);
+ comp.setSource(mipsBinaryFileName);
+
+ if(dumpOptions) {
+ System.err.println("== Options ==");
+ for(int i=0;i<options.length;i+=2)
+ System.err.println(options[i] + ": " + comp.getOption(options[i]).get());
+ System.err.println("== End Options ==");
+ }
+
+ try {
+ comp.go();
+ } catch(Exn e) {
+ System.err.println("Compiler Error: " + e.getMessage());
+ System.exit(1);
+ } finally {
+ if(w != null) w.close();
+ if(os != null) os.close();
+ }
+ }
+
+ public Compiler(SeekableData binary, String fullClassName) throws IOException {
+ this.fullClassName = fullClassName;
+ elf = new ELF(binary);
+
+ if(elf.header.type != ELF.ELFHeader.ET_EXEC) throw new IOException("Binary is not an executable");
+ if(elf.header.machine != ELF.ELFHeader.EM_MIPS) throw new IOException("Binary is not for the MIPS I Architecture");
+ if(elf.ident.data != ELF.ELFIdent.ELFDATA2MSB) throw new IOException("Binary is not big endian");
+ }
+
+ protected abstract void _go() throws Exn, IOException;
+
+ private boolean used;
+ public void go() throws Exn, IOException {
+ if(used) throw new RuntimeException("Compiler instances are good for one shot only");
+ used = true;
+
+ if(onePage && pageSize <= 4096) pageSize = 4*1024*1024;
+ if(nullPointerCheck && !fastMem) throw new Exn("fastMem must be enabled for nullPointerCheck to be of any use");
+ if(onePage && !fastMem) throw new Exn("fastMem must be enabled for onePage to be of any use");
+ if(totalPages == 1 && !onePage) throw new Exn("totalPages == 1 and onePage is not set");
+ if(onePage) totalPages = 1;
+
+ maxInsnPerMethodInit();
+ pageSizeInit();
+
+ // Get a copy of the symbol table in the elf binary
+ ELF.Symtab symtab = elf.getSymtab();
+ if(symtab == null) throw new Exn("Binary has no symtab (did you strip it?)");
+ ELF.Symbol sym;
+
+ // Check for some functions we can override
+ sym = symtab.getGlobalSymbol("memcpy");
+ memcpy = sym == null ? -1 : sym.addr;
+
+ sym = symtab.getGlobalSymbol("memset");
+ memset = sym == null ? -1 : sym.addr;
+
+ userInfo = symtab.getGlobalSymbol("user_info");
+ gp = symtab.getGlobalSymbol("_gp");
+ if(gp == null) throw new Exn("no _gp symbol (did you strip the binary?)");
+
+ if(pruneCases) {
+ // Find all possible branches
+ jumpableAddresses = new HashSet();
+
+ jumpableAddresses.add(new Integer(elf.header.entry));
+
+ ELF.SHeader text = elf.sectionWithName(".text");
+ if(text == null) throw new Exn("No .text segment");
+
+ findBranchesInSymtab(symtab,jumpableAddresses);
+
+ for(int i=0;i<elf.sheaders.length;i++) {
+ ELF.SHeader sheader = elf.sheaders[i];
+ String name = sheader.name;
+ // if this section doesn't get loaded into our address space don't worry about it
+ if(sheader.addr == 0x0) continue;
+ if(name.equals(".data") || name.equals(".sdata") || name.equals(".rodata") || name.equals(".ctors") || name.equals(".dtors"))
+ findBranchesInData(new DataInputStream(sheader.getInputStream()),sheader.size,jumpableAddresses,text.addr,text.addr+text.size);
+ }
+
+ findBranchesInText(text.addr,new DataInputStream(text.getInputStream()),text.size,jumpableAddresses);
+ }
+
+ if(unixRuntime && runtimeClass.startsWith("org.xwt.mips.")) runtimeClass = "org.xwt.mips.UnixRuntime";
+
+ for(int i=0;i<elf.sheaders.length;i++) {
+ String name = elf.sheaders[i].name;
+ if(elf.sheaders[i].addr != 0 && !(
+ name.equals(".text")|| name.equals(".data") || name.equals(".sdata") || name.equals(".rodata") ||
+ name.equals(".ctors") || name.equals(".dtors") || name.equals(".bss") || name.equals(".sbss")))
+ throw new Exn("Unknown section: " + name);
+ }
+ _go();
+ }
+
+ private void findBranchesInSymtab(ELF.Symtab symtab, Set jumps) {
+ ELF.Symbol[] symbols = symtab.symbols;
+ int n=0;
+ for(int i=0;i<symbols.length;i++) {
+ ELF.Symbol s = symbols[i];
+ if(s.type == ELF.Symbol.STT_FUNC) {
+ if(jumps.add(new Integer(s.addr))) {
+ //System.err.println("Adding symbol from symtab: " + s.name + " at " + toHex(s.addr));
+ n++;
+ }
+ }
+ }
+ if(printStats) System.err.println("Found " + n + " additional possible branch targets in Symtab");
+ }
+
+ private void findBranchesInText(int base, DataInputStream dis, int size, Set jumps) throws IOException {
+ int count = size/4;
+ int pc = base;
+ int n=0;
+ int[] lui_val = new int[32];
+ int[] lui_pc = new int[32];
+ //Interpreter inter = new Interpreter(source);
+
+ for(int i=0;i<count;i++,pc+=4) {
+ int insn = dis.readInt();
+ int op = (insn >>> 26) & 0xff;
+ int rs = (insn >>> 21) & 0x1f;
+ int rt = (insn >>> 16) & 0x1f;
+ int signedImmediate = (insn << 16) >> 16;
+ int unsignedImmediate = insn & 0xffff;
+ int branchTarget = signedImmediate;
+ int jumpTarget = (insn & 0x03ffffff);
+ int subcode = insn & 0x3f;
+
+ switch(op) {
+ case 0:
+ switch(subcode) {
+ case 9: // JALR
+ if(jumps.add(new Integer(pc+8))) n++; // return address
+ break;
+ case 12: // SYSCALL
+ if(jumps.add(new Integer(pc+4))) n++;
+ break;
+ }
+ break;
+ case 1:
+ switch(rt) {
+ case 16: // BLTZAL
+ case 17: // BGTZAL
+ if(jumps.add(new Integer(pc+8))) n++; // return address
+ // fall through
+ case 0: // BLTZ
+ case 1: // BGEZ
+ if(jumps.add(new Integer(pc+branchTarget*4+4))) n++;
+ break;
+ }
+ break;
+ case 3: // JAL
+ if(jumps.add(new Integer(pc+8))) n++; // return address
+ // fall through
+ case 2: // J
+ if(jumps.add(new Integer((pc&0xf0000000)|(jumpTarget << 2)))) n++;
+ break;
+ case 4: // BEQ
+ case 5: // BNE
+ case 6: // BLEZ
+ case 7: // BGTZ
+ if(jumps.add(new Integer(pc+branchTarget*4+4))) n++;
+ break;
+ case 9: { // ADDIU
+ if(pc - lui_pc[rs] <= 4*32) {
+ int t = (lui_val[rs]<<16)+signedImmediate;
+ if((t&3)==0 && t >= base && t < base+size) {
+ if(jumps.add(new Integer(t))) {
+ //System.err.println("Possible jump to " + toHex(t) + " (" + inter.sourceLine(t) + ") from " + toHex(pc) + " (" + inter.sourceLine(pc) + ")");
+ n++;
+ }
+ }
+ // we just blew it away
+ if(rt == rs) lui_pc[rs] = 0;
+ }
+ break;
+ }
+ case 15: { // LUI
+ lui_val[rt] = unsignedImmediate;
+ lui_pc[rt] = pc;
+ break;
+ }
+
+ case 17: // FPU Instructions
+ switch(rs) {
+ case 8: // BC1F, BC1T
+ if(jumps.add(new Integer(pc+branchTarget*4+4))) n++;
+ break;
+ }
+ break;
+ }
+ }
+ dis.close();
+ if(printStats) System.err.println("Found " + n + " additional possible branch targets in Text segment");
+ }
+
+ private void findBranchesInData(DataInputStream dis, int size, Set jumps, int textStart, int textEnd) throws IOException {
+ int count = size/4;
+ int n=0;
+ for(int i=0;i<count;i++) {
+ int word = dis.readInt();
+ if((word&3)==0 && word >= textStart && word < textEnd) {
+ if(jumps.add(new Integer(word))) {
+ //System.err.println("Added " + toHex(word) + " as possible branch target (fron data segment)");
+ n++;
+ }
+ }
+ }
+ dis.close();
+ if(n>0 && printStats) System.err.println("Found " + n + " additional possible branch targets in Data segment");
+ }
+
+ // Helper functions for pretty output
+ protected final static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); }
+ protected final static String toHex8(int n) {
+ String s = Long.toString(n & 0xffffffffL, 16);
+ StringBuffer sb = new StringBuffer("0x");
+ for(int i=8-s.length();i>0;i--) sb.append('0');
+ sb.append(s);
+ return sb.toString();
+ }
+
+ protected final static String toOctal3(int n) {
+ char[] buf = new char[3];
+ for(int i=2;i>=0;i--) {
+ buf[i] = (char) ('0' + (n & 7));
+ n >>= 3;
+ }
+ return new String(buf);
+ }
+
+ // Option parsing
+ private class Option {
+ private java.lang.reflect.Field field;
+ public Option(String name) throws NoSuchFieldException { field = name==null ? null : Compiler.class.getDeclaredField(name); }
+ public void set(Object val) {
+ if(field == null) return;
+ try {
+ field.setAccessible(true);
+ field.set(Compiler.this,val);
+ } catch(IllegalAccessException e) {
+ System.err.println(e);
+ }
+ }
+ public Object get() {
+ if(field == null) return null;
+ try {
+ field.setAccessible(true);
+ return field.get(Compiler.this);
+ } catch(IllegalAccessException e) {
+ System.err.println(e); return null;
+ }
+ }
+ public Class getType() { return field == null ? null : field.getType(); }
+ }
+
+ private static String[] options = {
+ "fastMem", "Enable fast memory access - RuntimeExceptions will be thrown on faults",
+ "nullPointerCheck", "Enables checking at runtime for null pointer accessses (slows things down a bit, only applicable with fastMem)",
+ "maxInsnPerMethod", "Maximum number of MIPS instructions per java method (128 is optimal with Hotspot)",
+ "pruneCases", "Remove unnecessary case 0xAABCCDD blocks from methods - may break some weird code",
+ "assumeTailCalls", "Assume the JIT optimizes tail calls",
+ "optimizedMemcpy", "Use an optimized java version of memcpy where possible",
+ "debugCompiler", "Output information in the generated code for debugging the compiler - will slow down generated code significantly",
+ "printStats", "Output some useful statistics about the compilation",
+ "runtimeStats", "Keep track of some statistics at runtime in the generated code - will slow down generated code significantly",
+ "supportCall", "Keep a stripped down version of the symbol table in the generated code to support the call() method",
+ "runtimeClass", "Full classname of the Runtime class (default: Runtime) - use this is you put Runtime in a package",
+ "hashClass", "Full classname of a Hashtable class (default: java.util.HashMap) - this must support get() and put()",
+ "unixRuntime", "Use the UnixRuntime (has support for fork, wai, du, pipe, etc)",
+ "pageSize", "The page size (must be a power of two)",
+ "totalPages", "Total number of pages (total mem = pageSize*totalPages, must be a power of two)",
+ "onePage", "One page hack (FIXME: document this better)",
+ "lessConstants", "Use less constants at the cost of speed (FIXME: document this better)"
+ };
+
+ private Option getOption(String name) {
+ name = name.toLowerCase();
+ try {
+ for(int i=0;i<options.length;i+=2)
+ if(options[i].toLowerCase().equals(name))
+ return new Option(options[i]);
+ return null;
+ } catch(NoSuchFieldException e) {
+ return null;
+ }
+ }
+
+ public void parseOptions(String opts) {
+ if(opts == null || opts.length() == 0) return;
+ StringTokenizer st = new StringTokenizer(opts,",");
+ while(st.hasMoreElements()) {
+ String tok = st.nextToken();
+ String key;
+ String val;
+ if(tok.indexOf("=") != -1) {
+ key = tok.substring(0,tok.indexOf("="));
+ val = tok.substring(tok.indexOf("=")+1);
+ } else if(tok.startsWith("no")) {
+ key = tok.substring(2);
+ val = "false";
+ } else {
+ key = tok;
+ val = "true";
+ }
+ Option opt = getOption(key);
+ if(opt == null) {
+ System.err.println("WARNING: No such option: " + key);
+ continue;
+ }
+
+ if(opt.getType() == String.class)
+ opt.set(val);
+ else if(opt.getType() == Integer.TYPE)
+ try {
+ opt.set(parseInt(val));
+ } catch(NumberFormatException e) {
+ System.err.println("WARNING: " + val + " is not an integer");
+ }
+ else if(opt.getType() == Boolean.TYPE)
+ opt.set(new Boolean(val.toLowerCase().equals("true")||val.toLowerCase().equals("yes")));
+ else
+ throw new Error("Unknown type: " + opt.getType());
+ }
+ }
+
+ private static Integer parseInt(String s) {
+ int mult = 1;
+ s = s.toLowerCase();
+ if(!s.startsWith("0x") && s.endsWith("m")) { s = s.substring(0,s.length()-1); mult = 1024*1024; }
+ else if(!s.startsWith("0x") && s.endsWith("k")) { s = s.substring(0,s.length()-1); mult = 1024; }
+ int n;
+ if(s.length() > 2 && s.startsWith("0x")) n = Integer.parseInt(s.substring(2),16);
+ else n = Integer.parseInt(s);
+ return new Integer(n*mult);
+ }
+
+ private static String wrapAndIndent(String s, int firstindent, int indent, int width) {
+ StringTokenizer st = new StringTokenizer(s," ");
+ StringBuffer sb = new StringBuffer();
+ for(int i=0;i<firstindent;i++)
+ sb.append(' ');
+ int sofar = 0;
+ while(st.hasMoreTokens()) {
+ String tok = st.nextToken();
+ if(tok.length() + sofar + 1 > width && sofar > 0) {
+ sb.append('\n');
+ for(int i=0;i<indent;i++) sb.append(' ');
+ sofar = 0;
+ } else if(sofar > 0) {
+ sb.append(' ');
+ sofar++;
+ }
+ sb.append(tok);
+ sofar += tok.length();
+ }
+ sb.append('\n');
+ return sb.toString();
+ }
+
+ // This ugliness is to work around a gcj static linking bug (Bug 12908)
+ // The best solution is to force gnu.java.locale.Calendar to be linked in but this'll do
+ protected static String dateTime() {
+ try {
+ return new Date().toString();
+ } catch(RuntimeException e) {
+ return "<unknown>";
+ }
+ }
+}
+
--- /dev/null
+package org.xwt.mips;
+
+import org.xwt.mips.util.*;
+import java.io.*;
+
+public class ELF {
+ private SeekableData data;
+
+ public ELFIdent ident;
+ public ELFHeader header;
+ public PHeader[] pheaders;
+ public SHeader[] sheaders;
+
+ private byte[] stringTable;
+
+ private boolean sectionReaderActive;
+
+
+ private void readFully(byte[] buf) throws IOException {
+ int len = buf.length;
+ int pos = 0;
+ while(len > 0) {
+ int n = data.read(buf,pos,len);
+ if(n == -1) throw new IOException("EOF");
+ pos += n;
+ len -= n;
+ }
+ }
+
+ private int readIntBE() throws IOException {
+ byte[] buf = new byte[4];
+ readFully(buf);
+ return ((buf[0]&0xff)<<24)|((buf[1]&0xff)<<16)|((buf[2]&0xff)<<8)|((buf[3]&0xff)<<0);
+ }
+ private int readInt() throws IOException {
+ int x = readIntBE();
+ if(ident!=null && ident.data == ELFIdent.ELFDATA2LSB)
+ x = ((x<<24)&0xff000000) | ((x<<8)&0xff0000) | ((x>>>8)&0xff00) | ((x>>24)&0xff);
+ return x;
+ }
+
+ private short readShortBE() throws IOException {
+ byte[] buf = new byte[2];
+ readFully(buf);
+ return (short)(((buf[0]&0xff)<<8)|((buf[1]&0xff)<<0));
+ }
+ private short readShort() throws IOException {
+ short x = readShortBE();
+ if(ident!=null && ident.data == ELFIdent.ELFDATA2LSB)
+ x = (short)((((x<<8)&0xff00) | ((x>>8)&0xff))&0xffff);
+ return x;
+ }
+
+ private byte readByte() throws IOException {
+ byte[] buf = new byte[1];
+ readFully(buf);
+ return buf[0];
+ }
+
+ public class ELFIdent {
+ private static final int ELF_MAGIC = 0x7f454c46; // '\177', 'E', 'L', 'F'
+
+ public static final int ELFCLASSNONE = 0;
+ public static final int ELFCLASS32 = 1;
+ public static final int ELFCLASS64 = 2;
+ public byte klass;
+
+
+ public static final int ELFDATANONE = 0;
+ public static final int ELFDATA2LSB = 1;
+ public static final int ELFDATA2MSB = 2;
+ public byte data;
+ public byte osabi;
+ public byte abiversion;
+
+ ELFIdent() throws IOException {
+ if(readIntBE() != ELF_MAGIC) throw new ELFException("Bad Magic (is: " );
+
+ klass = readByte();
+ if(klass != ELFCLASS32) throw new ELFException("org.xwt.mips.ELF does not suport 64-bit binaries");
+
+ data = readByte();
+ if(data != ELFDATA2LSB && data != ELFDATA2MSB) throw new ELFException("Unknown byte order");
+
+ readByte(); // version
+ osabi = readByte();
+ abiversion = readByte();
+ for(int i=0;i<7;i++) readByte(); // padding
+ }
+ }
+
+ public class ELFHeader {
+ public static final short ET_EXEC = 2;
+ public short type;
+
+ public static final short EM_MIPS = 8;
+ public short machine;
+
+ public int version;
+ public int entry;
+ public int phoff;
+ public int shoff;
+ public int flags;
+ public short ehsize;
+ public short phentsize;
+ public short phnum;
+ public short shentsize;
+ public short shnum;
+ public short shstrndx;
+
+ ELFHeader() throws IOException {
+ type = readShort();
+ machine = readShort();
+ version = readInt();
+ if(version != 1) throw new ELFException("version != 1");
+ entry = readInt();
+ phoff = readInt();
+ shoff = readInt();
+ flags = readInt();
+ ehsize = readShort();
+ phentsize = readShort();
+ phnum = readShort();
+ shentsize = readShort();
+ shnum = readShort();
+ shstrndx = readShort();
+ }
+ }
+
+ public class PHeader {
+ public int type;
+ public int offset;
+ public int vaddr;
+ public int paddr;
+ public int filesz;
+ public int memsz;
+ public int flags;
+ public int align;
+
+ public static final int PF_X = 0x1;
+ public static final int PF_W = 0x2;
+ public static final int PF_R = 0x4;
+
+ public static final int PT_LOAD = 1;
+
+ PHeader() throws IOException {
+ type = readInt();
+ offset = readInt();
+ vaddr = readInt();
+ paddr = readInt();
+ filesz = readInt();
+ memsz = readInt();
+ flags = readInt();
+ align = readInt();
+ if(filesz > memsz) throw new ELFException("ELF inconsistency: filesz > memsz (" + toHex(filesz) + " > " + toHex(memsz) + ")");
+ }
+
+ public boolean writable() { return (flags & PF_W) != 0; }
+
+ public InputStream getInputStream() throws IOException {
+ return new BufferedInputStream(new SectionInputStream(
+ offset,offset+filesz));
+ }
+ }
+
+ public class SHeader {
+ int nameidx;
+ public String name;
+ public int type;
+ public int flags;
+ public int addr;
+ public int offset;
+ public int size;
+ public int link;
+ public int info;
+ public int addralign;
+ public int entsize;
+
+ public static final int SHT_SYMTAB = 2;
+ public static final int SHT_STRTAB = 3;
+ public static final int SHT_NOBITS = 8;
+
+ SHeader() throws IOException {
+ nameidx = readInt();
+ type = readInt();
+ flags = readInt();
+ addr = readInt();
+ offset = readInt();
+ size = readInt();
+ link = readInt();
+ info = readInt();
+ addralign = readInt();
+ entsize = readInt();
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return new BufferedInputStream(new SectionInputStream(
+ offset, type == SHT_NOBITS ? 0 : offset+size));
+ }
+
+ public boolean isText() { return name.equals(".text"); }
+ public boolean isData() { return name.equals(".data") || name.equals(".sdata") || name.equals(".rodata") || name.equals(".ctors") || name.equals(".dtors"); }
+ public boolean isBSS() { return name.equals(".bss") || name.equals(".sbss"); }
+ }
+
+ public ELF(String file) throws IOException, ELFException { this(new SeekableFile(file,false)); }
+ public ELF(SeekableData data) throws IOException, ELFException {
+ this.data = data;
+ ident = new ELFIdent();
+ header = new ELFHeader();
+ pheaders = new PHeader[header.phnum];
+ for(int i=0;i<header.phnum;i++) {
+ data.seek(header.phoff+i*header.phentsize);
+ pheaders[i] = new PHeader();
+ }
+ sheaders = new SHeader[header.shnum];
+ for(int i=0;i<header.shnum;i++) {
+ data.seek(header.shoff+i*header.shentsize);
+ sheaders[i] = new SHeader();
+ }
+ if(header.shstrndx < 0 || header.shstrndx >= header.shnum) throw new ELFException("Bad shstrndx");
+ data.seek(sheaders[header.shstrndx].offset);
+ stringTable = new byte[sheaders[header.shstrndx].size];
+ readFully(stringTable);
+
+ for(int i=0;i<header.shnum;i++) {
+ SHeader s = sheaders[i];
+ s.name = getString(s.nameidx);
+ }
+ }
+
+ private String getString(int off) { return getString(off,stringTable); }
+ private String getString(int off,byte[] strtab) {
+ StringBuffer sb = new StringBuffer();
+ if(off < 0 || off >= strtab.length) return "<invalid strtab entry>";
+ while(off >= 0 && off < strtab.length && strtab[off] != 0) sb.append((char)strtab[off++]);
+ return sb.toString();
+ }
+
+ public SHeader sectionWithName(String name) {
+ for(int i=0;i<sheaders.length;i++)
+ if(sheaders[i].name.equals(name))
+ return sheaders[i];
+ return null;
+ }
+
+ public class ELFException extends IOException { ELFException(String s) { super(s); } }
+
+ private class SectionInputStream extends InputStream {
+ private int pos;
+ private int maxpos;
+ SectionInputStream(int start, int end) throws IOException {
+ if(sectionReaderActive)
+ throw new IOException("Section reader already active");
+ sectionReaderActive = true;
+ pos = start;
+ data.seek(pos);
+ maxpos = end;
+ }
+
+ private int bytesLeft() { return maxpos - pos; }
+ public int read() throws IOException {
+ byte[] buf = new byte[1];
+ return read(buf,0,1) == -1 ? -1 : (buf[0]&0xff);
+ }
+ public int read(byte[] b, int off, int len) throws IOException {
+ int n = data.read(b,off,Math.min(len,bytesLeft())); if(n > 0) pos += n; return n;
+ }
+ public void close() { sectionReaderActive = false; }
+ }
+
+ private Symtab _symtab;
+ public Symtab getSymtab() throws IOException {
+ if(_symtab != null) return _symtab;
+
+ if(sectionReaderActive) throw new ELFException("Can't read the symtab while a section reader is active");
+
+ SHeader sh = sectionWithName(".symtab");
+ if(sh == null || sh.type != SHeader.SHT_SYMTAB) return null;
+
+ SHeader sth = sectionWithName(".strtab");
+ if(sth == null || sth.type != SHeader.SHT_STRTAB) return null;
+
+ byte[] strtab = new byte[sth.size];
+ DataInputStream dis = new DataInputStream(sth.getInputStream());
+ dis.readFully(strtab);
+ dis.close();
+
+ return _symtab = new Symtab(sh.offset, sh.size,strtab);
+ }
+
+ public class Symtab {
+ public Symbol[] symbols;
+
+ Symtab(int off, int size, byte[] strtab) throws IOException {
+ data.seek(off);
+ int count = size/16;
+ symbols = new Symbol[count];
+ for(int i=0;i<count;i++) symbols[i] = new Symbol(strtab);
+ }
+
+ public Symbol getSymbol(String name) {
+ Symbol sym = null;
+ for(int i=0;i<symbols.length;i++) {
+ if(symbols[i].name.equals(name)) {
+ if(sym == null)
+ sym = symbols[i];
+ else
+ System.err.println("WARNING: Multiple symbol matches for " + name);
+ }
+ }
+ return sym;
+ }
+
+ public Symbol getGlobalSymbol(String name) {
+ for(int i=0;i<symbols.length;i++)
+ if(symbols[i].binding == Symbol.STB_GLOBAL && symbols[i].name.equals(name))
+ return symbols[i];
+ return null;
+ }
+ }
+
+ public class Symbol {
+ public String name;
+ public int addr;
+ public int size;
+ public byte info;
+ public byte type;
+ public byte binding;
+ public byte other;
+ public SHeader sheader;
+
+ public final static int STT_FUNC = 2;
+ public final static int STB_GLOBAL = 1;
+
+ Symbol(byte[] strtab) throws IOException {
+ name = getString(readInt(),strtab);
+ addr = readInt();
+ size = readInt();
+ info = readByte();
+ type = (byte)(info&0xf);
+ binding = (byte)(info>>4);
+ other = readByte();
+ // FEATURE: This should point to some other entry or something
+ readShort();
+ }
+ }
+
+ private static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); }
+
+ public static void main(String[] args) throws IOException {
+ ELF elf = new ELF(new SeekableInputStream(new FileInputStream(args[0])));
+ System.out.println("Type: " + toHex(elf.header.type));
+ System.out.println("Machine: " + toHex(elf.header.machine));
+ System.out.println("Entry: " + toHex(elf.header.entry));
+ for(int i=0;i<elf.pheaders.length;i++) {
+ ELF.PHeader ph = elf.pheaders[i];
+ System.out.println("PHeader " + toHex(i));
+ System.out.println("\tOffset: " + ph.offset);
+ System.out.println("\tVaddr: " + toHex(ph.vaddr));
+ System.out.println("\tFile Size: " + ph.filesz);
+ System.out.println("\tMem Size: " + ph.memsz);
+ }
+ for(int i=0;i<elf.sheaders.length;i++) {
+ ELF.SHeader sh = elf.sheaders[i];
+ System.out.println("SHeader " + toHex(i));
+ System.out.println("\tName: " + sh.name);
+ System.out.println("\tOffset: " + sh.offset);
+ System.out.println("\tAddr: " + toHex(sh.addr));
+ System.out.println("\tSize: " + sh.size);
+ System.out.println("\tType: " + toHex(sh.type));
+ }
+ Symtab symtab = elf.getSymtab();
+ if(symtab != null) {
+ System.out.println("Symbol table:");
+ for(int i=0;i<symtab.symbols.length;i++)
+ System.out.println("\t" + symtab.symbols[i].name + " -> " + toHex(symtab.symbols[i].addr));
+ } else {
+ System.out.println("Symbol table: None");
+ }
+ }
+}
--- /dev/null
+// Copyright 2003 Brian Alliet
+// Based on org.xwt.imp.MIPS by Adam Megacz
+// Portions Copyright 2003 Adam Megacz
+
+package org.xwt.mips;
+
+import org.xwt.mips.util.*;
+import java.io.*;
+
+public class Interpreter extends UnixRuntime {
+ // Registers
+ private int[] registers = new int[32];
+ private int hi,lo;
+
+ // Floating Point Registers
+ private int[] fpregs = new int[32];
+ // 24-31 - unused
+ // 23 - conditional bit
+ // 18-22 - unused
+ // 12-17 - cause bits (unimplemented)
+ // 7-11 - enables bits (unimplemented)
+ // 2-6 - flags (unimplemented)
+ // 0-1 - rounding mode (only implemented for fixed point conversions)
+ private int fcsr;
+
+ private int pc;
+
+ // The filename if the binary we're running
+ public String image;
+ private ELF.Symtab symtab;
+
+ // Register Operations
+ private final void setFC(boolean b) { fcsr = (fcsr&~0x800000) | (b ? 0x800000 : 0x000000); }
+ private final int roundingMode() { return fcsr & 3; /* bits 0-1 */ }
+ private final double getDouble(int r) {
+ return Double.longBitsToDouble(((fpregs[r+1]&0xffffffffL) << 32) | (fpregs[r]&0xffffffffL));
+ }
+ private final void setDouble(int r, double d) {
+ long l = Double.doubleToLongBits(d);
+ fpregs[r+1] = (int)(l >>> 32); fpregs[r] = (int)l;
+ }
+ private final float getFloat(int r) { return Float.intBitsToFloat(fpregs[r]); }
+ private final void setFloat(int r, float f) { fpregs[r] = Float.floatToRawIntBits(f); }
+
+ protected void _execute() throws ExecutionException {
+ try {
+ runSome();
+ } catch(ExecutionException e) {
+ e.setLocation(toHex(pc) + ": " + sourceLine(pc));
+ throw e;
+ }
+ }
+
+ // Main interpretor
+ // the return value is meaningless, its just to catch people typing "return" by accident
+ private final int runSome() throws FaultException,ExecutionException {
+ int[] r = registers;
+ int[] f = fpregs;
+ int pc = this.pc;
+ int nextPC = pc + 4;
+ try {
+ OUTER: for(;;) {
+ int insn;
+ try {
+ insn = readPages[pc>>>PAGE_SHIFT][(pc>>>2)&PAGE_WORDS-1];
+ } catch (RuntimeException e) {
+ insn = memRead(pc);
+ }
+
+ int op = (insn >>> 26) & 0xff; // bits 26-31
+ int rs = (insn >>> 21) & 0x1f; // bits 21-25
+ int rt = (insn >>> 16) & 0x1f; // bits 16-20
+ int ft = (insn >>> 16) & 0x1f;
+ int rd = (insn >>> 11) & 0x1f; // bits 11-15
+ int fs = (insn >>> 11) & 0x1f;
+ int shamt = (insn >>> 6) & 0x1f; // bits 6-10
+ int fd = (insn >>> 6) & 0x1f;
+ int subcode = insn & 0x3f; // bits 0-5
+
+ int jumpTarget = (insn & 0x03ffffff); // bits 0-25
+ int unsignedImmediate = insn & 0xffff;
+ int signedImmediate = (insn << 16) >> 16;
+ int branchTarget = signedImmediate;
+
+ int tmp, addr; // temporaries
+
+ r[ZERO] = 0;
+
+ switch(op) {
+ case 0: {
+ switch(subcode) {
+ case 0: // SLL
+ if(insn == 0) break;
+ r[rd] = r[rt] << shamt;
+ break;
+ case 2: // SRL
+ r[rd] = r[rt] >>> shamt;
+ break;
+ case 3: // SRA
+ r[rd] = r[rt] >> shamt;
+ break;
+ case 4: // SLLV
+ r[rd] = r[rt] << (r[rs]&0x1f);
+ break;
+ case 6: // SRLV
+ r[rd] = r[rt] >>> (r[rs]&0x1f);
+ break;
+ case 7: // SRAV
+ r[rd] = r[rt] >> (r[rs]&0x1f);
+ break;
+ case 8: // JR
+ tmp = r[rs]; pc += 4; nextPC = tmp;
+ continue OUTER;
+ case 9: // JALR
+ tmp = r[rs]; pc += 4; r[rd] = pc+4; nextPC = tmp;
+ continue OUTER;
+ case 12: // SYSCALL
+ this.pc = pc;
+ r[V0] = syscall(r[V0],r[A0],r[A1],r[A2],r[A3]);
+ if(state != RUNNING) { this.pc = nextPC; break OUTER; }
+ break;
+ case 13: // BREAK
+ throw new ExecutionException("Break");
+ case 16: // MFHI
+ r[rd] = hi;
+ break;
+ case 17: // MTHI
+ hi = r[rs];
+ break;
+ case 18: // MFLO
+ r[rd] = lo;
+ break;
+ case 19: // MTLO
+ lo = r[rs];
+ break;
+ case 24: { // MULT
+ long hilo = (long)(r[rs]) * ((long)r[rt]);
+ hi = (int) (hilo >>> 32);
+ lo = (int) hilo;
+ break;
+ }
+ case 25: { // MULTU
+ long hilo = (r[rs] & 0xffffffffL) * (r[rt] & 0xffffffffL);
+ hi = (int) (hilo >>> 32);
+ lo = (int) hilo;
+ break;
+ }
+ case 26: // DIV
+ hi = r[rs]%r[rt];
+ lo = r[rs]/r[rt];
+ break;
+ case 27: // DIVU
+ if(rt != 0) {
+ hi = (int)((r[rs] & 0xffffffffL) % (r[rt] & 0xffffffffL));
+ lo = (int)((r[rs] & 0xffffffffL) / (r[rt] & 0xffffffffL));
+ }
+ break;
+ case 32: // ADD
+ throw new ExecutionException("ADD (add with oveflow trap) not suported");
+ /*This must trap on overflow
+ r[rd] = r[rs] + r[rt];
+ break;*/
+ case 33: // ADDU
+ r[rd] = r[rs] + r[rt];
+ break;
+ case 34: // SUB
+ throw new ExecutionException("SUB (sub with oveflow trap) not suported");
+ /*This must trap on overflow
+ r[rd] = r[rs] - r[rt];
+ break;*/
+ case 35: // SUBU
+ r[rd] = r[rs] - r[rt];
+ break;
+ case 36: // AND
+ r[rd] = r[rs] & r[rt];
+ break;
+ case 37: // OR
+ r[rd] = r[rs] | r[rt];
+ break;
+ case 38: // XOR
+ r[rd] = r[rs] ^ r[rt];
+ break;
+ case 39: // NOR
+ r[rd] = ~(r[rs] | r[rt]);
+ break;
+ case 42: // SLT
+ r[rd] = r[rs] < r[rt] ? 1 : 0;
+ break;
+ case 43: // SLTU
+ r[rd] = ((r[rs] & 0xffffffffL) < (r[rt] & 0xffffffffL)) ? 1 : 0;
+ break;
+ default:
+ throw new ExecutionException("Illegal instruction 0/" + subcode);
+ }
+ break;
+ }
+ case 1: {
+ switch(rt) {
+ case 0: // BLTZ
+ if(r[rs] < 0) {
+ pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 1: // BGEZ
+ if(r[rs] >= 0) {
+ pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 16: // BLTZAL
+ if(r[rs] < 0) {
+ pc += 4; r[RA] = pc+4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 17: // BGEZAL
+ if(r[rs] >= 0) {
+ pc += 4; r[RA] = pc+4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ default:
+ throw new ExecutionException("Illegal Instruction");
+ }
+ break;
+ }
+ case 2: { // J
+ tmp = (pc&0xf0000000) | (jumpTarget << 2);
+ pc+=4; nextPC = tmp;
+ continue OUTER;
+ }
+ case 3: { // JAL
+ tmp = (pc&0xf0000000) | (jumpTarget << 2);
+ pc+=4; r[RA] = pc+4; nextPC = tmp;
+ continue OUTER;
+ }
+ case 4: // BEQ
+ if(r[rs] == r[rt]) {
+ pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 5: // BNE
+ if(r[rs] != r[rt]) {
+ pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 6: //BLEZ
+ if(r[rs] <= 0) {
+ pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 7: //BGTZ
+ if(r[rs] > 0) {
+ pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 8: // ADDI
+ r[rt] = r[rs] + signedImmediate;
+ break;
+ case 9: // ADDIU
+ r[rt] = r[rs] + signedImmediate;
+ break;
+ case 10: // SLTI
+ r[rt] = r[rs] < signedImmediate ? 1 : 0;
+ break;
+ case 11: // SLTIU
+ r[rt] = (r[rs]&0xffffffffL) < (unsignedImmediate&0xffffffffL) ? 1 : 0;
+ break;
+ case 12: // ANDI
+ r[rt] = r[rs] & unsignedImmediate;
+ break;
+ case 13: // ORI
+ r[rt] = r[rs] | unsignedImmediate;
+ break;
+ case 14: // XORI
+ r[rt] = r[rs] ^ unsignedImmediate;
+ break;
+ case 15: // LUI
+ r[rt] = unsignedImmediate << 16;
+ break;
+ case 16:
+ throw new ExecutionException("TLB/Exception support not implemented");
+ case 17: { // FPU
+ boolean debug = false;
+ String line = debug ? sourceLine(pc) : "";
+ boolean debugon = debug && (line.indexOf("dtoa.c:51") >= 0 || line.indexOf("dtoa.c:52") >= 0 || line.indexOf("test.c") >= 0);
+ if(rs > 8 && debugon)
+ System.out.println(" FP Op: " + op + "/" + rs + "/" + subcode + " " + line);
+ if(roundingMode() != 0 && rs != 6 /*CTC.1*/ && !((rs==16 || rs==17) && subcode == 36 /* CVT.W.Z */))
+ throw new ExecutionException("Non-cvt.w.z operation attempted with roundingMode != round to nearest");
+ switch(rs) {
+ case 0: // MFC.1
+ r[rt] = f[rd];
+ break;
+ case 2: // CFC.1
+ if(fs != 31) throw new ExecutionException("FCR " + fs + " unavailable");
+ r[rt] = fcsr;
+ break;
+ case 4: // MTC.1
+ f[rd] = r[rt];
+ break;
+ case 6: // CTC.1
+ if(fs != 31) throw new ExecutionException("FCR " + fs + " unavailable");
+ fcsr = r[rt];
+ break;
+ case 8: // BC1F, BC1T
+ if(((fcsr&0x800000)!=0) == (((insn>>>16)&1)!=0)) {
+ pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 16: { // Single
+ switch(subcode) {
+ case 0: // ADD.S
+ setFloat(fd,getFloat(fs)+getFloat(ft));
+ break;
+ case 1: // SUB.S
+ setFloat(fd,getFloat(fs)-getFloat(ft));
+ break;
+ case 2: // MUL.S
+ setFloat(fd,getFloat(fs)*getFloat(ft));
+ break;
+ case 3: // DIV.S
+ setFloat(fd,getFloat(fs)/getFloat(ft));
+ break;
+ case 5: // ABS.S
+ setFloat(fd,Math.abs(getFloat(fs)));
+ break;
+ case 6: // MOV.S
+ f[fd] = f[fs];
+ break;
+ case 7: // NEG.S
+ setFloat(fd,-getFloat(fs));
+ break;
+ case 33: // CVT.D.S
+ setDouble(fd,getFloat(fs));
+ break;
+ case 36: // CVT.W.S
+ switch(roundingMode()) {
+ case 0: f[fd] = (int)Math.floor(getFloat(fs)+0.5f); break; // Round to nearest
+ case 1: f[fd] = (int)getFloat(fs); break; // Round towards zero
+ case 2: f[fd] = (int)Math.ceil(getFloat(fs)); break; // Round towards plus infinity
+ case 3: f[fd] = (int)Math.floor(getFloat(fs)); break; // Round towards minus infinity
+ }
+ break;
+ case 50: // C.EQ.S
+ setFC(getFloat(fs) == getFloat(ft));
+ break;
+ case 60: // C.LT.S
+ setFC(getFloat(fs) < getFloat(ft));
+ break;
+ default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode + " at " + sourceLine(pc));
+ }
+ break;
+ }
+ case 17: { // Double
+ switch(subcode) {
+ case 0: // ADD.D
+ setDouble(fd,getDouble(fs)+getDouble(ft));
+ break;
+ case 1: // SUB.D
+ if(debugon) System.out.println("f" + fd + " = f" + fs + " (" + getDouble(fs) + ") - f" + ft + " (" + getDouble(ft) + ")");
+ setDouble(fd,getDouble(fs)-getDouble(ft));
+ break;
+ case 2: // MUL.D
+ if(debugon) System.out.println("f" + fd + " = f" + fs + " (" + getDouble(fs) + ") * f" + ft + " (" + getDouble(ft) + ")");
+ setDouble(fd,getDouble(fs)*getDouble(ft));
+ if(debugon) System.out.println("f" + fd + " = " + getDouble(fd));
+ break;
+ case 3: // DIV.D
+ setDouble(fd,getDouble(fs)/getDouble(ft));
+ break;
+ case 5: // ABS.D
+ setDouble(fd,Math.abs(getDouble(fs)));
+ break;
+ case 6: // MOV.D
+ f[fd] = f[fs];
+ f[fd+1] = f[fs+1];
+ break;
+ case 7: // NEG.D
+ setDouble(fd,-getDouble(fs));
+ break;
+ case 32: // CVT.S.D
+ setFloat(fd,(float)getDouble(fs));
+ break;
+ case 36: // CVT.W.D
+ if(debugon) System.out.println("CVT.W.D rm: " + roundingMode() + " f" + fs + ":" + getDouble(fs));
+ switch(roundingMode()) {
+ case 0: f[fd] = (int)Math.floor(getDouble(fs)+0.5); break; // Round to nearest
+ case 1: f[fd] = (int)getDouble(fs); break; // Round towards zero
+ case 2: f[fd] = (int)Math.ceil(getDouble(fs)); break; // Round towards plus infinity
+ case 3: f[fd] = (int)Math.floor(getDouble(fs)); break; // Round towards minus infinity
+ }
+ if(debugon) System.out.println("CVT.W.D: f" + fd + ":" + f[fd]);
+ break;
+ case 50: // C.EQ.D
+ setFC(getDouble(fs) == getDouble(ft));
+ break;
+ case 60: // C.LT.D
+ setFC(getDouble(fs) < getDouble(ft));
+ break;
+ case 62: // C.LE.D
+ setFC(getDouble(fs) <= getDouble(ft));
+ break;
+ default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode + " at " + sourceLine(pc));
+ }
+ break;
+ }
+ case 20: { // Integer
+ switch(subcode) {
+ case 33: // CVT.D.W
+ setDouble(fd,f[fs]);
+ break;
+ default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode + " at " + sourceLine(pc));
+ }
+ break;
+ }
+ default:
+ throw new ExecutionException("Invalid Instruction 17/" + rs);
+ }
+ break;
+ }
+ case 18: case 19:
+ throw new ExecutionException("No coprocessor installed");
+ case 32: { // LB
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr&~3);
+ }
+ switch(addr&3) {
+ case 0: tmp = (tmp>>>24)&0xff; break;
+ case 1: tmp = (tmp>>>16)&0xff; break;
+ case 2: tmp = (tmp>>> 8)&0xff; break;
+ case 3: tmp = (tmp>>> 0)&0xff; break;
+ }
+ if((tmp&0x80)!=0) tmp |= 0xffffff00; // sign extend
+ r[rt] = tmp;
+ break;
+ }
+ case 33: { // LH
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr&~3);
+ }
+ switch(addr&2) {
+ case 0: tmp = (tmp>>>16)&0xffff; break;
+ case 2: tmp = (tmp>>> 0)&0xffff; break;
+ }
+ if((tmp&0x8000)!=0) tmp |= 0xffff0000; // sign extend
+ r[rt] = tmp;
+ break;
+ }
+ case 34: { // LWL;
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr&~3);
+ }
+ switch(addr&3) {
+ case 0: r[rt] = (r[rt]&0x00000000)|(tmp<< 0); break;
+ case 1: r[rt] = (r[rt]&0x000000ff)|(tmp<< 8); break;
+ case 2: r[rt] = (r[rt]&0x0000ffff)|(tmp<<16); break;
+ case 3: r[rt] = (r[rt]&0x00ffffff)|(tmp<<24); break;
+ }
+ break;
+ }
+ case 35: // LW
+ addr = r[rs] + signedImmediate;
+ try {
+ r[rt] = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ r[rt] = memRead(addr);
+ }
+ break;
+ case 36: { // LBU
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr);
+ }
+ switch(addr&3) {
+ case 0: r[rt] = (tmp>>>24)&0xff; break;
+ case 1: r[rt] = (tmp>>>16)&0xff; break;
+ case 2: r[rt] = (tmp>>> 8)&0xff; break;
+ case 3: r[rt] = (tmp>>> 0)&0xff; break;
+ }
+ break;
+ }
+ case 37: { // LHU
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr&~3);
+ }
+ switch(addr&2) {
+ case 0: r[rt] = (tmp>>>16)&0xffff; break;
+ case 2: r[rt] = (tmp>>> 0)&0xffff; break;
+ }
+ break;
+ }
+ case 38: { // LWR
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr&~3);
+ }
+ switch(addr&3) {
+ case 0: r[rt] = (r[rt]&0xffffff00)|(tmp>>>24); break;
+ case 1: r[rt] = (r[rt]&0xffff0000)|(tmp>>>16); break;
+ case 2: r[rt] = (r[rt]&0xff000000)|(tmp>>> 8); break;
+ case 3: r[rt] = (r[rt]&0x00000000)|(tmp>>> 0); break;
+ }
+ break;
+ }
+ case 40: { // SB
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr&~3);
+ }
+ switch(addr&3) {
+ case 0: tmp = (tmp&0x00ffffff) | ((r[rt]&0xff)<<24); break;
+ case 1: tmp = (tmp&0xff00ffff) | ((r[rt]&0xff)<<16); break;
+ case 2: tmp = (tmp&0xffff00ff) | ((r[rt]&0xff)<< 8); break;
+ case 3: tmp = (tmp&0xffffff00) | ((r[rt]&0xff)<< 0); break;
+ }
+ try {
+ writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
+ } catch(RuntimeException e) {
+ memWrite(addr&~3,tmp);
+ }
+ break;
+ }
+ case 41: { // SH
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr&~3);
+ }
+ switch(addr&2) {
+ case 0: tmp = (tmp&0x0000ffff) | ((r[rt]&0xffff)<<16); break;
+ case 2: tmp = (tmp&0xffff0000) | ((r[rt]&0xffff)<< 0); break;
+ }
+ try {
+ writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
+ } catch(RuntimeException e) {
+ memWrite(addr&~3,tmp);
+ }
+ break;
+ }
+ case 42: { // SWL
+ addr = r[rs] + signedImmediate;
+ tmp = memRead(addr&~3);
+ switch(addr&3) {
+ case 0: tmp=(tmp&0x00000000)|(r[rt]>>> 0); break;
+ case 1: tmp=(tmp&0xff000000)|(r[rt]>>> 8); break;
+ case 2: tmp=(tmp&0xffff0000)|(r[rt]>>>16); break;
+ case 3: tmp=(tmp&0xffffff00)|(r[rt]>>>24); break;
+ }
+ try {
+ writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
+ } catch(RuntimeException e) {
+ memWrite(addr&~3,tmp);
+ }
+ break;
+ }
+ case 43: // SW
+ addr = r[rs] + signedImmediate;
+ try {
+ writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = r[rt];
+ } catch(RuntimeException e) {
+ memWrite(addr&~3,r[rt]);
+ }
+ break;
+ case 46: { // SWR
+ addr = r[rs] + signedImmediate;
+ tmp = memRead(addr&~3);
+ switch(addr&3) {
+ case 0: tmp=(tmp&0x00ffffff)|(r[rt]<<24); break;
+ case 1: tmp=(tmp&0x0000ffff)|(r[rt]<<16); break;
+ case 2: tmp=(tmp&0x000000ff)|(r[rt]<< 8); break;
+ case 3: tmp=(tmp&0x00000000)|(r[rt]<< 0); break;
+ }
+ memWrite(addr&~3,tmp);
+ break;
+ }
+ // FEATURE: Needs to be atomic w/ threads
+ case 48: // LWC0/LL
+ r[rt] = memRead(r[rs] + signedImmediate);
+ break;
+ case 49: // LWC1
+ f[rt] = memRead(r[rs] + signedImmediate);
+ break;
+ // FEATURE: Needs to be atomic w/ threads
+ case 56:
+ memWrite(r[rs] + signedImmediate,r[rt]);
+ r[rt] = 1;
+ break;
+ case 57: // SWC1
+ memWrite(r[rs] + signedImmediate,f[rt]);
+ break;
+ default:
+ throw new ExecutionException("Invalid Instruction: " + op);
+ }
+ pc = nextPC;
+ nextPC = pc + 4;
+ } // for(;;)
+ } catch(ExecutionException e) {
+ this.pc = pc;
+ throw e;
+ }
+ return 0;
+ }
+
+ public int lookupSymbol(String name) {
+ ELF.Symbol sym = symtab.getGlobalSymbol(name);
+ return sym == null ? -1 : sym.addr;
+ }
+
+ // Image loading function
+ private void loadImage(SeekableData data) throws IOException {
+ if(state != UNINITIALIZED) throw new IllegalStateException("loadImage called on initialized runtime");
+
+ ELF elf = new ELF(data);
+ symtab = elf.getSymtab();
+
+ if(elf.header.type != ELF.ELFHeader.ET_EXEC) throw new IOException("Binary is not an executable");
+ if(elf.header.machine != ELF.ELFHeader.EM_MIPS) throw new IOException("Binary is not for the MIPS I Architecture");
+ if(elf.ident.data != ELF.ELFIdent.ELFDATA2MSB) throw new IOException("Binary is not big endian");
+
+ entryPoint = elf.header.entry;
+
+ ELF.Symtab symtab = elf.getSymtab();
+ if(symtab == null) throw new IOException("No symtab in binary (did you strip it?)");
+ ELF.Symbol userInfo = symtab.getGlobalSymbol("user_info");
+ ELF.Symbol gpsym = symtab.getGlobalSymbol("_gp");
+
+ if(gpsym == null) throw new IOException("NO _gp symbol!");
+ gp = gpsym.addr;
+
+ if(userInfo != null) {
+ userInfoBase = userInfo.addr;
+ userInfoSize = userInfo.size;
+ }
+
+ ELF.PHeader[] pheaders = elf.pheaders;
+ int brk = 0;
+ for(int i=0;i<pheaders.length;i++) {
+ ELF.PHeader ph = pheaders[i];
+ if(ph.type != ELF.PHeader.PT_LOAD) continue;
+ int memsize = ph.memsz;
+ int filesize = ph.filesz;
+ if(memsize == 0) continue;
+ if(memsize < 0) throw new IOException("pheader size too large");
+ int addr = ph.vaddr;
+ if(addr == 0x0) throw new IOException("pheader vaddr == 0x0");
+ brk = max(addr+memsize,brk);
+
+ for(int j=0;j<memsize+PAGE_SIZE-1;j+=PAGE_SIZE) {
+ int page = (j+addr) >>> PAGE_SHIFT;
+ if(readPages[page] == null)
+ readPages[page] = new int[PAGE_WORDS];
+ if(ph.writable()) writePages[page] = readPages[page];
+ }
+ if(filesize != 0) {
+ filesize = filesize & ~3;
+ DataInputStream dis = new DataInputStream(ph.getInputStream());
+ do {
+ readPages[addr >>> PAGE_SHIFT][(addr >>> 2)&(PAGE_WORDS-1)] = dis.readInt();
+ addr+=4;
+ filesize-=4;
+ } while(filesize > 0);
+ dis.close();
+ }
+ }
+ brkAddr = (brk+PAGE_SIZE-1)&~(PAGE_SIZE-1);
+ state = INITIALIZED;
+ }
+
+ protected void setCPUState(CPUState state) {
+ for(int i=1;i<32;i++) registers[i] = state.r[i];
+ for(int i=0;i<32;i++) fpregs[i] = state.f[i];
+ hi=state.hi; lo=state.lo; fcsr=state.fcsr;
+ pc=state.pc;
+ }
+
+ protected CPUState getCPUState() {
+ CPUState state = new CPUState();
+ for(int i=1;i<32;i++) state.r[i] = registers[i];
+ for(int i=0;i<32;i++) state.f[i] = fpregs[i];
+ state.hi=hi; state.lo=lo; state.fcsr=fcsr;
+ state.pc=pc;
+ return state;
+ }
+
+ // This is package private for fork() which does all kinds of ugly things behind the scenes
+ Interpreter() { super(4096,65536,true); }
+ public Interpreter(SeekableData data) throws IOException { this(); loadImage(data); }
+ public Interpreter(String filename) throws IOException {
+ this(new SeekableFile(filename,false));
+ image = filename;
+ }
+ public Interpreter(InputStream is) throws IOException { this(new SeekableInputStream(is)); }
+
+ // Debug functions
+ // NOTE: This probably requires a jdk > 1.1, however, it is only used for debugging
+ private java.util.HashMap sourceLineCache;
+ public String sourceLine(int pc) {
+ final String addr2line = "mips-unknown-elf-addr2line";
+ String line = (String) (sourceLineCache == null ? null : sourceLineCache.get(new Integer(pc)));
+ if(line != null) return line;
+ if(image==null) return null;
+ try {
+ Process p = java.lang.Runtime.getRuntime().exec(new String[]{addr2line,"-e",image,toHex(pc)});
+ line = new BufferedReader(new InputStreamReader(p.getInputStream())).readLine();
+ if(line == null) return null;
+ while(line.startsWith("../")) line = line.substring(3);
+ if(sourceLineCache == null) sourceLineCache = new java.util.HashMap();
+ sourceLineCache.put(new Integer(pc),line);
+ return line;
+ } catch(IOException e) {
+ return null;
+ }
+ }
+
+ public class DebugShutdownHook implements Runnable {
+ public void run() {
+ int pc = Interpreter.this.pc;
+ if(getState() == RUNNING)
+ System.err.print("\nCPU Executing " + toHex(pc) + ": " + sourceLine(pc) + "\n");
+ }
+ }
+
+ public static void main(String[] argv) throws Exception {
+ String image = argv[0];
+ Interpreter emu = new Interpreter(image);
+ java.lang.Runtime.getRuntime().addShutdownHook(new Thread(emu.new DebugShutdownHook()));
+ int status = emu.run(argv);
+ System.err.println("Exit status: " + status);
+ System.exit(status);
+ }
+}
--- /dev/null
+package org.xwt.mips;
+
+import java.util.*;
+import java.io.*;
+import org.xwt.mips.util.SeekableData;
+
+public class JavaSourceCompiler extends Compiler {
+ /** Stores the "case r XXX: ... run_YYYY();" blocks generated by the emitText method/ */
+ private StringBuffer runs = new StringBuffer();
+ /** Stores the "initData" and "cleadData" calls generated by the emitData and emitBSS methods */
+ private StringBuffer inits = new StringBuffer();
+ /** Stores lines to go in the class scope */
+ private StringBuffer classLevel = new StringBuffer();
+
+ /** The stream to write the compiled output to */
+ private PrintWriter out;
+
+ /** Prints a blank line to the output stream */
+ private void p() { out.println(); }
+ /** prints the given string (indented by <i>indent</i>*4 spaces) to the output stream */
+ private void p(String s) { out.println(indents[indent] + s); }
+ private void pblock(StringBuffer sb) { out.print(sb.toString()); }
+
+ /** Used by the p() method to add indentation */
+ private int indent;
+
+ private static String indents[] = new String[16];
+ static { String s=""; for(int i=0;i<indents.length;i++,s=s+" ") indents[i] = s; }
+
+ public JavaSourceCompiler(SeekableData binary, String className, Writer w) throws IOException {
+ super(binary,className);
+ out = new PrintWriter(w);
+ }
+
+ protected void _go() throws Exn, IOException {
+ String packageName;
+ String className;
+ if (fullClassName.indexOf('.') != -1) {
+ packageName = fullClassName.substring(0, fullClassName.lastIndexOf('.'));
+ className = fullClassName.substring(fullClassName.lastIndexOf('.') + 1);
+ } else {
+ className = fullClassName;
+ packageName = null;
+ }
+
+ p("/* This file was generated from " + source + " by Mips2Java on " + dateTime() + " */");
+ if (packageName != null) p("package " + packageName + ";");
+ if(runtimeStats) p("import java.util.*;");
+ p();
+ p("public class " + className + " extends " + runtimeClass + " {");
+ indent++;
+
+ p("/* program counter */");
+ p("private int pc = 0;");
+ if(debugCompiler)
+ p("private int lastPC = 0;");
+ p();
+ p("/* General Purpose registers */");
+ p("private final static int r0 = 0;");
+ p("private int r1, r2, r3, r4, r5, r6, r7,");
+ p(" r8, r9, r10, r11, r12, r13, r14, r15,");
+ p(" r16, r17, r18, r19, r20, r21, r22, r23,");
+ p(" r24, r25, r26, r27, r28, r29, r30, r31,");
+ p(" hi = 0, lo = 0;");
+ p("/* FP registers */");
+ p("private int f0, f1, f2, f3, f4, f5, f6, f7,");
+ p(" f8, f9, f10, f11, f12, f13, f14, f15,");
+ p(" f16, f17, f18, f19, f20, f21, f22, f23,");
+ p(" f24, f25, f26, f27, f28, f29, f30, f31;");
+ p("/* FP Control Register */");
+ p("private int fcsr = 0;");
+ p();
+
+ if(onePage) p("private final int[] page = readPages[0];");
+
+ // Generate main body functions (run_XXXX() blocks, _data[] arrays, etc)
+ int highestAddr = 0;
+
+ for(int i=0;i<elf.sheaders.length;i++) {
+ ELF.SHeader sheader = elf.sheaders[i];
+ String name = sheader.name;
+ // if this section doesn't get loaded into our address space don't worry about it
+ if(sheader.addr == 0x0) continue;
+
+ highestAddr = Math.max(highestAddr, sheader.addr + sheader.size);
+
+ if(name.equals(".text"))
+ emitText(sheader.addr, new DataInputStream(sheader.getInputStream()),sheader.size);
+ else if(name.equals(".data") || name.equals(".sdata") || name.equals(".rodata") || name.equals(".ctors") || name.equals(".dtors"))
+ emitData(sheader.addr, new DataInputStream(sheader.getInputStream()), sheader.size,name.equals(".rodata"));
+ else if(name.equals(".bss") || name.equals(".sbss"))
+ emitBSS(sheader.addr,sheader.size);
+ else
+ throw new Exn("Unknown segment: " + name);
+ }
+ p();
+
+ pblock(classLevel);
+ p();
+
+ // Trampoline (dispatch calls to the appropriate run_XXX() methods
+ p("private final void trampoline() throws ExecutionException {");
+ indent++;
+ p("while(state == RUNNING) {");
+ indent++;
+ p("switch(pc>>>" + methodShift+ ") {");
+ indent++;
+ pblock(runs);
+ p("default: throw new ExecutionException(\"invalid address 0x\" + Long.toString(this.pc&0xffffffffL,16) + \": r2: \" + r2);");
+ indent--; p("}");
+ indent--; p("}");
+ indent--; p("}");
+ p();
+
+ // Constructor
+ p("public " + className + "() {");
+ indent++;
+ p("super(" + pageSize + "," + totalPages + "," + (fastMem?"false":"true") + ");");
+ p("entryPoint = " + toHex(elf.header.entry) + ";");
+ if(userInfo != null) {
+ p("userInfoBase=" + toHex(userInfo.addr) + ";");
+ p("userInfoSize=" + userInfo.size + ";");
+ }
+ p("gp = " + toHex(gp.addr) + ";");
+ if(onePage)
+ p("brkAddr = " + toHex((highestAddr+4095)&~4095) + ";");
+ else
+ p("brkAddr = " + toHex((highestAddr+pageSize-1)&~(pageSize-1)) + ";");
+ pblock(inits);
+ p("state = INITIALIZED;");
+ indent--;
+ p("}");
+ p();
+
+ // main() function
+ p("public static void main(String[] args) throws Exception {");
+ indent++;
+ p("" + className + " me = new " + className + "();");
+ p("int status = me.run(\"" + fullClassName + "\",args);");
+ if(runtimeStats) p("me.printStats();");
+ p("System.exit(status);");
+ indent--;
+ p("}");
+ p();
+
+ // Runtime abstract methods
+ p("protected void _execute() throws ExecutionException { trampoline(); }");
+ p();
+
+ p("protected void setCPUState(CPUState state) {");
+ indent++;
+ for(int i=1;i<32;i++) p("r" + i + "=state.r[" + i + "];");
+ for(int i=0;i<32;i++) p("f" + i + "=state.f[" + i + "];");
+ p("hi=state.hi; lo=state.lo; fcsr=state.fcsr;");
+ p("pc=state.pc;");
+ indent--;
+ p("}");
+ p("protected CPUState getCPUState() {");
+ indent++;
+ p("CPUState state = new CPUState();");
+ for(int i=1;i<32;i++) p("state.r[" + i + "]=r" + i+ ";");
+ for(int i=0;i<32;i++) p("state.f[" + i + "]=f" + i +";");
+ p("state.hi=hi; state.lo=lo; state.fcsr=fcsr;");
+ p("state.pc=pc;");
+ p("return state;");
+ indent--;
+ p("}");
+ p();
+
+ if(supportCall) {
+ p("private static final " + hashClass + " symbols = new " + hashClass + "();");
+ p("static {");
+ indent++;
+ ELF.Symbol[] symbols = elf.getSymtab().symbols;
+ for(int i=0;i<symbols.length;i++) {
+ ELF.Symbol s = symbols[i];
+ if(s.type == ELF.Symbol.STT_FUNC && s.binding == ELF.Symbol.STB_GLOBAL && (s.name.equals("_call_helper") || !s.name.startsWith("_")))
+ p("symbols.put(\"" + s.name + "\",new Integer(" + toHex(s.addr) + "));");
+ }
+ indent--;
+ p("}");
+ p("public int lookupSymbol(String symbol) { Integer i = (Integer) symbols.get(symbol); return i==null ? -1 : i.intValue(); }");
+ p();
+ }
+
+ // Runtime stats
+ if(runtimeStats) {
+ p("private HashMap counters = new HashMap();");
+ p("private void inc(String k) { Long i = (Long)counters.get(k); counters.put(k,new Long(i==null ? 1 : i.longValue() + 1)); }");
+ p("private void printStats() {");
+ p(" Iterator i = new TreeSet(counters.keySet()).iterator();");
+ p(" while(i.hasNext()) { Object o = i.next(); System.err.println(\"\" + o + \": \" + counters.get(o)); }");
+ p("}");
+ p();
+ }
+
+ indent--;
+ p("}");
+ }
+
+ private int startOfMethod = 0;
+ private int endOfMethod = 0;
+
+ private void startMethod(int addr) {
+ addr &= ~(maxBytesPerMethod-1);
+ startOfMethod = addr;
+ endOfMethod = addr + maxBytesPerMethod;
+ String methodName = "run_" + Long.toString(addr & 0xffffffffL, 16);
+ runs.append(indents[4] + "case " + toHex(addr>>>methodShift) + ": " + methodName + "(); break; \n");
+ p("private final void " + methodName + "() throws ExecutionException { /"+"* " + toHex(addr) + " - " + toHex(endOfMethod) + " *" + "/");
+ indent++;
+ p("int addr, tmp;");
+ p("for(;;) {");
+ indent++;
+ p("switch(pc) {");
+ indent++;
+ }
+
+ private void endMethod() { endMethod(endOfMethod); }
+ private void endMethod(int lastAddr) {
+ if(startOfMethod == 0) return;
+ // FEATURE: We should be able to use if(!unreachable) here (i think)
+ // This isn't strictly necessary; its just here to work around unreachable code errors
+ p("case " + toHex(lastAddr) + ":");
+ indent++;
+ p("pc=" + constant(lastAddr) + ";");
+ leaveMethod();
+ indent--;
+ if(debugCompiler)
+ p("default: throw new ExecutionException(\"invalid address 0x\" + Long.toString(pc&0xffffffffL,16) + \" (got here from 0x\" + Long.toString(lastPC&0xffffffffL,16)+\")\");");
+ else
+ p("default: throw new ExecutionException(\"invalid address 0x\" + Long.toString(pc&0xffffffffL,16));");
+ indent--;
+ p("}"); // end switch
+ p("/* NOT REACHED */");
+ indent--;
+ p("}"); // end for
+ indent--;
+ p("}"); // end method
+ endOfMethod = startOfMethod = 0;
+ }
+
+ private HashMap relativeAddrs = new HashMap();
+ private String constant(int target) {
+ if(target >= 4096 && lessConstants) {
+ int n = target & ~1023;
+ String var = "N_" + toHex8(n);
+ if(relativeAddrs.get(new Integer(n)) == null) {
+ relativeAddrs.put(new Integer(n),Boolean.TRUE);
+ classLevel.append(indents[1] + "private static int " + var + " = " + toHex(n) + ";\n");
+ }
+ return "(" + var + " + " + toHex(target - n) + ")";
+ } else {
+ return toHex(target);
+ }
+ }
+
+ private void branch(int pc, int target) {
+ if(debugCompiler) p("lastPC = " + toHex(pc) + ";");
+ p("pc=" + constant(target) + ";");
+ if(target == 0)
+ p("throw new ExecutionException(\"Branch to addr 0x0\");");
+ else if((pc&methodMask) == (target&methodMask))
+ p("continue;");
+ else if(assumeTailCalls)
+ p("run_" + Long.toString((target&methodMask)&0xffffffffL, 16) + "(); return;");
+ else
+ leaveMethod();
+ }
+
+ private void leaveMethod() {
+ p("return;");
+ }
+
+ private boolean textDone;
+ private void emitText(int addr, DataInputStream dis, int size) throws Exn,IOException {
+ if(textDone) throw new Exn("Multiple text segments");
+ textDone = true;
+
+ if((addr&3)!=0 || (size&3)!=0) throw new Exn("Section on weird boundaries");
+ int count = size/4;
+ int nextInsn = dis.readInt();
+ if(nextInsn == -1) throw new Error("Actually read -1 at " + toHex(addr));
+ int insn;
+
+ for(int i=0;i<count;i++,addr+=4) {
+ insn = nextInsn;
+ nextInsn = (i == count-1) ? -1 : dis.readInt();
+ if(addr >= endOfMethod) { endMethod(); startMethod(addr); }
+ if(jumpableAddresses==null || addr == startOfMethod || jumpableAddresses.contains(new Integer(addr))) {
+ p("case " + toHex(addr) + ":");
+ unreachable = false;
+ } else if(unreachable) {
+ continue;
+ } else if(debugCompiler) {
+ p("/" + "* pc = " + toHex(addr) + "*" + "/");
+ }
+ indent++;
+ emitInstruction(addr,insn,nextInsn);
+ indent--;
+ }
+ endMethod(addr);
+ p();
+ dis.close();
+ }
+
+ private int initDataCount = 0;
+ private void emitData(int addr, DataInputStream dis, int size, boolean readOnly) throws Exn,IOException {
+ if((addr&3)!=0 || (size&3)!=0) throw new Exn("Data section on weird boundaries");
+ int last = addr + size;
+ while(addr < last) {
+ int segSize = Math.min(size,28000); // must be a multiple of 56
+ StringBuffer sb = new StringBuffer();
+ for(int i=0;i<segSize;i+=7) {
+ long l = 0;
+ for(int j=0;j<7;j++) {
+ l <<= 8;
+ byte b = (i+j < size) ? dis.readByte() : 1;
+ l |= (b & 0xffL);
+ }
+ for(int j=0;j<8;j++) {
+ char c = (char) ((l>>>(7*(7-j)))&0x7f);
+ if(c=='\n') sb.append("\\n");
+ else if(c=='\r') sb.append("\\r");
+ else if(c=='\\') sb.append("\\\\");
+ else if(c=='"') sb.append("\\\"");
+ else if(c >= 32 && c <= 126) sb.append(c);
+ else sb.append("\\" + toOctal3(c));
+ }
+ }
+ String varname = "_data" + (++initDataCount);
+ p("private static final int[] " + varname + " = decodeData(\"" + sb.toString() + "\"," + toHex(segSize/4) + ");");
+ inits.append(indents[2] + "initPages(" + varname +"," + toHex(addr) + "," + (readOnly?"true":"false") + ");\n");
+ addr += segSize;
+ size -= segSize;
+ }
+ dis.close();
+ }
+
+ private void emitBSS(int addr, int size) throws Exn {
+ if((addr&3)!=0) throw new Exn("BSS section on weird boundaries");
+ size = (size+3)&~3;
+ int count = size/4;
+ inits.append(indents[2] + "clearPages(" + toHex(addr) + "," + toHex(count) + ");\n");
+ }
+
+ // True if the current code path is unreachable (any instruction with a case statement is reachable)
+ private boolean unreachable = false;
+
+ private void emitInstruction(int pc, int insn, int nextInsn) throws IOException,Exn {
+ if(insn == -1) throw new Error("insn is -1");
+
+ int op = (insn >>> 26) & 0xff; // bits 26-31
+ int rs = (insn >>> 21) & 0x1f; // bits 21-25
+ int rt = (insn >>> 16) & 0x1f; // bits 16-20
+ int ft = (insn >>> 16) & 0x1f;
+ int rd = (insn >>> 11) & 0x1f; // bits 11-15
+ int fs = (insn >>> 11) & 0x1f;
+ int shamt = (insn >>> 6) & 0x1f; // bits 6-10
+ int fd = (insn >>> 6) & 0x1f;
+ int subcode = insn & 0x3f; // bits 0-5
+
+ int jumpTarget = (insn & 0x03ffffff); // bits 0-25
+ int unsignedImmediate = insn & 0xffff;
+ int signedImmediate = (insn << 16) >> 16;
+ int branchTarget = signedImmediate;
+
+ int tmp; // temporaries
+
+ //if(pc%64==0) p("System.err.println(\"Executing: " + toHex(pc) + "\");");
+ //p("/" + "*" + (pc == -1 ? "Delay Slot" : toHex(pc)) + " *" + "/ ");
+ if(pc==-1) p("/" + "* Next insn is delay slot *" + "/ ");
+
+ if(runtimeStats && op != 0) p("inc(\"opcode: " + op + "\");");
+ switch(op) {
+ case 0: {
+ if(runtimeStats && insn != 0) p("inc(\"opcode: 0/" + subcode + "\");");
+ switch(subcode) {
+ case 0: // SLL
+ if(insn != 0)
+ p( "r"+rd+" = r"+rt+" << "+shamt+";");
+ break;
+ case 2: // SRL
+ p( "r"+rd+" = r"+rt+" >>> "+shamt+";");
+ break;
+ case 3: // SRA
+ p( "r"+rd+" = r"+rt+" >> "+shamt+";");
+ break;
+ case 4: // SLLV
+ p( "r"+rd+" = r"+rt+" << (r"+rs+"&0x1f);");
+ break;
+ case 6: // SRLV
+ p( "r"+rd+" = r"+rt+" >>> (r"+rs+"&0x1f);");
+ break;
+ case 7: // SRAV
+ p( "r"+rd+" = r"+rt+" >> (r"+rs+"&0x1f);");
+ break;
+ case 8: // JR
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ emitInstruction(-1,nextInsn,-1);
+ if(debugCompiler) p("lastPC = " + toHex(pc) + ";");
+ p("pc=r" + rs + ";");
+ leaveMethod();
+ unreachable = true;
+ break;
+ case 9: // JALR
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ emitInstruction(-1,nextInsn,-1);
+ if(debugCompiler) p("lastPC = " + toHex(pc) + ";");
+ p("pc=r" + rs + ";");
+ p("r" + RA + "=" + constant(pc+8 /*skip this insn and delay slot*/) + ";");
+ leaveMethod();
+ unreachable = true;
+ break;
+ case 12: // SYSCALL
+ p("pc = " + toHex(pc) + ";");
+ p( "r"+V0+" = syscall(r"+V0+",r"+A0+",r"+A1+",r"+A2+",r"+A3+");");
+ p("if (state != RUNNING) {");
+ indent++;
+ p("pc = " + toHex(pc+4) + ";");
+ leaveMethod();
+ indent--;
+ p("}");
+ break;
+ case 13: // BREAK
+ p( "throw new ExecutionException(\"Break\");");
+ break;
+ case 16: // MFHI
+ p( "r"+rd+" = hi;");
+ break;
+ case 17: // MTHI
+ p( "hi = r"+rs+";");
+ break;
+ case 18: // MFLO
+ p( "r"+rd+" = lo;");
+ break;
+ case 19: // MTLO
+ p( "lo = r"+rs+";");
+ break;
+ case 24: // MULT
+ p( "{ long hilo = (long)(r"+rs+") * ((long)r"+rt+"); " +
+ "hi = (int) (hilo >>> 32); " +
+ "lo = (int) hilo; }");
+ break;
+ case 25: // MULTU
+ p( "{ long hilo = (r"+rs+" & 0xffffffffL) * (r"+rt+" & 0xffffffffL); " +
+ "hi = (int) (hilo >>> 32); " +
+ "lo = (int) hilo; } ");
+ break;
+ case 26: // DIV
+ p( "hi = r"+rs+"%r"+rt+"; lo = r"+rs+"/r"+rt+";");
+ break;
+ case 27: // DIVU
+ p("if(r"+rt+"!=0) {");
+ p( "hi = (int)((r"+rs+" & 0xffffffffL) % (r"+rt+" & 0xffffffffL)); " +
+ "lo = (int)((r"+rs+" & 0xffffffffL) / (r"+rt+" & 0xffffffffL));");
+ p("}");
+ break;
+ case 32: // ADD
+ throw new Exn("ADD (add with oveflow trap) not suported");
+ /*This must trap on overflow
+ p( "r"+rd+" = r"+rs+" + r"+rt+";");
+ break;*/
+ case 33: // ADDU
+ p( "r"+rd+" = r"+rs+" + r"+rt+";");
+ break;
+ case 34: // SUB
+ throw new Exn("SUB (add with oveflow trap) not suported");
+ /*This must trap on overflow
+ p( "r"+rd+" = r"+rs+" - r"+rt+";");
+ break;*/
+ case 35: // SUBU
+ p( "r"+rd+" = r"+rs+" - r"+rt+";");
+ break;
+ case 36: // AND
+ p( "r"+rd+" = r"+rs+" & r"+rt+";");
+ break;
+ case 37: // OR
+ p( "r"+rd+" = r"+rs+" | r"+rt+";");
+ break;
+ case 38: // XOR
+ p( "r"+rd+" = r"+rs+" ^ r"+rt+";");
+ break;
+ case 39: // NOR
+ p( "r"+rd+" = ~(r"+rs+" | r"+rt+");");
+ break;
+ case 42: // SLT
+ p( "r"+rd+" = r"+rs+" < r"+rt+" ? 1 : 0;");
+ break;
+ case 43: // SLTU
+ p( "r"+rd+" = ((r"+rs+" & 0xffffffffL) < (r"+rt+" & 0xffffffffL)) ? 1 : 0;");
+ break;
+ default:
+ throw new RuntimeException("Illegal instruction 0/" + subcode);
+ }
+ break;
+ }
+ case 1: {
+ switch(rt) {
+ case 0: // BLTZ
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " < 0) {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ case 1: // BGEZ
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " >= 0) {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ case 16: // BLTZAL
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " < 0) {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ p("r" + RA + "=" + constant(pc+8 /*skip this insn and delay slot*/) + ";");
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ case 17: // BGEZAL
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " >= 0) {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ p("r" + RA + "=" + constant(pc+8 /*skip this insn and delay slot*/) + ";");
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ default:
+ throw new RuntimeException("Illegal Instruction 1/" + rt);
+ }
+ break;
+ }
+ case 2: { // J
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,(pc&0xf0000000)|(jumpTarget << 2));
+ unreachable = true;
+ break;
+ }
+ case 3: { // JAL
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ int target = (pc&0xf0000000)|(jumpTarget << 2);
+ emitInstruction(-1,nextInsn,-1);
+ if(optimizedMemcpy && (target == memcpy || target == memset)) {
+ if(target == memcpy)
+ p("memcpy(r4,r5,r6);");
+ else if(target == memset)
+ p("memset(r4,r5,r6);");
+ p("r2 = r4;");
+ branch(pc,pc+8);
+ } else {
+ p("r" + RA + "=" + constant(pc+8 /*skip this insn and delay slot*/) + ";");
+ branch(pc, target);
+ }
+ unreachable = true;
+ break;
+ }
+ case 4: // BEQ
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " == r" + rt + ") {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ case 5: // BNE
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " != r" + rt + ") {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ case 6: //BLEZ
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " <= 0) {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ case 7: //BGTZ
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " > 0) {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ case 8: // ADDI
+ p( "r"+rt+" = r"+rs+" + "+signedImmediate +";");
+ break;
+ case 9: // ADDIU
+ p( "r"+rt+" = r"+rs+" + "+signedImmediate+";");
+ break;
+ case 10: // SLTI
+ p( "r"+rt+" = r"+rs+" < "+signedImmediate+" ? 1 : 0;");
+ break;
+ case 11: // SLTIU
+ p( "r"+rt+" = (r"+rs+"&0xffffffffL) < ("+unsignedImmediate+"&0xffffffffL) ? 1 : 0;");
+ break;
+ case 12: // ANDI
+ p( "r"+rt+" = r"+rs+" & "+unsignedImmediate+";");
+ break;
+ case 13: // ORI
+ p( "r"+rt+" = r"+rs+" | "+unsignedImmediate+";");
+ break;
+ case 14: // XORI
+ p( "r"+rt+" = r"+rs+" ^ "+unsignedImmediate+";");
+ break;
+ case 15: // LUI
+ p( "r"+rt+" = "+unsignedImmediate+" << 16;");
+ break;
+ case 16:
+ throw new Exn("TLB/Exception support not implemented");
+ case 17: { // FPU
+ switch(rs) {
+ case 0: // MFC.1
+ p( "r"+rt+" = f"+rd+";");
+ break;
+ case 2: // CFC.1
+ if(fs != 31) throw new Exn("FCR " + fs + " unavailable");
+ p( "r"+rt+" = fcsr;");
+ break;
+ case 4: // MTC.1
+ p( "f"+rd+" = r"+rt+";");
+ break;
+ case 6: // CTC.1
+ if(fs != 31) throw new Exn("FCR " + fs + " unavailable");
+ p( "fcsr = r"+rt+";");
+ break;
+ case 8: {// BC1F, BC1T
+ tmp = (insn>>>16)&1;
+ p("if(((fcsr&0x800000)!=0) == (" + tmp + "!=0)) {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ }
+ case 16: { // Single
+ switch(subcode) {
+ case 0: // ADD.S
+ p(setFloat(fd,getFloat(fs)+"+"+getFloat(ft)));
+ break;
+ case 1: // SUB.S
+ p(setFloat(fd,getFloat(fs)+"-"+getFloat(ft)));
+ break;
+ case 2: // MUL.S
+ p(setFloat(fd,getFloat(fs)+"*"+getFloat(ft)));
+ break;
+ case 3: // DIV.S
+ p(setFloat(fd,getFloat(fs)+"/"+getFloat(ft)));
+ break;
+ case 5: // ABS.S
+ p(setFloat(fd,"Math.abs("+getFloat(fs)+")"));
+ break;
+ case 6: // MOV.S
+ p("f"+fd+" = f"+fs+"; // MOV.S");
+ break;
+ case 7: // NEG.S
+ p(setFloat(fd,"-"+getFloat(fs)));
+ break;
+ case 33: // CVT.D.S
+ p(setDouble(fd,"(float)"+getFloat(fs)));
+ break;
+ case 36: // CVT.W.D
+ p("switch(fcsr & 3) {");
+ indent++;
+ p("case 0: f"+fd+" = (int)Math.floor("+getFloat(fs)+"+0.5); break; // Round to nearest");
+ p("case 1: f"+fd+" = (int)"+getFloat(fs)+"; break; // Round towards zero");
+ p("case 2: f"+fd+" = (int)Math.ceil("+getFloat(fs)+"); break; // Round towards plus infinity");
+ p("case 3: f"+fd+" = (int)Math.floor("+getFloat(fs)+"); break; // Round towards minus infinity");
+ indent--;
+ p("}");
+ break;
+ case 50: // C.EQ.S
+ p("fcsr = (fcsr&~0x800000) | (("+getFloat(fs)+"=="+getFloat(ft)+") ? 0x800000 : 0x000000);");
+ break;
+ case 60: // C.LT.S
+ p("fcsr = (fcsr&~0x800000) | (("+getFloat(fs)+"<"+getFloat(ft)+") ? 0x800000 : 0x000000);");
+ break;
+ case 62: // C.LE.S
+ p("fcsr = (fcsr&~0x800000) | (("+getFloat(fs)+"<="+getFloat(ft)+") ? 0x800000 : 0x000000);");
+ break;
+ default: throw new Exn("Invalid Instruction 17/" + rs + "/" + subcode);
+ }
+ break;
+ }
+ case 17: { // Double
+ switch(subcode) {
+ case 0: // ADD.D
+ p(setDouble(fd,getDouble(fs)+"+"+getDouble(ft)));
+ break;
+ case 1: // SUB.D
+ p(setDouble(fd,getDouble(fs)+"-"+getDouble(ft)));
+ break;
+ case 2: // MUL.D
+ p(setDouble(fd,getDouble(fs)+"*"+getDouble(ft)));
+ break;
+ case 3: // DIV.D
+ p(setDouble(fd,getDouble(fs)+"/"+getDouble(ft)));
+ break;
+ case 5: // ABS.D
+ p(setDouble(fd,"Math.abs("+getDouble(fs)+")"));
+ break;
+ case 6: // MOV.D
+ p("f"+fd+" = f"+fs+";");
+ p("f"+(fd+1)+" = f"+(fs+1)+";");
+ break;
+ case 7: // NEG.D
+ p(setDouble(fd,"-"+getDouble(fs)));
+ break;
+ case 32: // CVT.S.D
+ p(setFloat(fd,"(float)"+getDouble(fs)));
+ break;
+ case 36: // CVT.W.D
+ p("switch(fcsr & 3) {");
+ indent++;
+ p("case 0: f"+fd+" = (int)Math.floor("+getDouble(fs)+"+0.5); break; // Round to nearest");
+ p("case 1: f"+fd+" = (int)"+getDouble(fs)+"; break; // Round towards zero");
+ p("case 2: f"+fd+" = (int)Math.ceil("+getDouble(fs)+"); break; // Round towards plus infinity");
+ p("case 3: f"+fd+" = (int)Math.floor("+getDouble(fs)+"); break; // Round towards minus infinity");
+ indent--;
+ p("}");
+ break;
+ case 50: // C.EQ.D
+ p("fcsr = (fcsr&~0x800000) | (("+getDouble(fs)+"=="+getDouble(ft)+") ? 0x800000 : 0x000000);");
+ break;
+ case 60: // C.LT.D
+ p("fcsr = (fcsr&~0x800000) | (("+getDouble(fs)+"<"+getDouble(ft)+") ? 0x800000 : 0x000000);");
+ break;
+ case 62: // C.LE.D
+ p("fcsr = (fcsr&~0x800000) | (("+getDouble(fs)+"<="+getDouble(ft)+") ? 0x800000 : 0x000000);");
+ break;
+ default: throw new Exn("Invalid Instruction 17/" + rs + "/" + subcode);
+ }
+ break;
+ }
+ case 20: { // Integer
+ switch(subcode) {
+ case 32: // CVT.S.W
+ p(" // CVS.S.W");
+ p(setFloat(fd,"((float)f"+fs+")"));
+ break;
+ case 33: // CVT.D.W
+ p(setDouble(fd,"((double)f"+fs+")"));
+ break;
+ default: throw new Exn("Invalid Instruction 17/" + rs + "/" + subcode);
+ }
+ break;
+ }
+ default:
+ throw new Exn("Invalid Instruction 17/" + rs);
+ }
+ break;
+ }
+ case 18: case 19:
+ throw new Exn("coprocessor 2 and 3 instructions not available");
+ case 32: { // LB
+ if(runtimeStats) p("inc(\"LB\");");
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp>>>(((~addr)&3)<<3)) & 0xff;");
+ p("if((tmp&0x80)!=0) tmp |= 0xffffff00; /* sign extend */");
+ p("r"+rt+" = tmp;");
+ break;
+ }
+ case 33: { // LH
+ if(runtimeStats) p("inc(\"LH\");");
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp>>>(((~addr)&2)<<3)) & 0xffff;");
+ p("if((tmp&0x8000)!=0) tmp |= 0xffff0000; /* sign extend */");
+ p("r"+rt+" = tmp;");
+ break;
+ }
+ case 34: { // LWL;
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("r" + rt + " = (r"+rt+"&(0x00ffffff>>>(((~addr)&3)<<3)))|(tmp<<((addr&3)<<3));");
+ break;
+ /*p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr&~3","tmp");
+ p("switch(addr&3) {");
+ indent++;
+ p("case 0: r"+rt+" = (r"+rt+"&0x00000000)|(tmp<< 0); break;");
+ p("case 1: r"+rt+" = (r"+rt+"&0x000000ff)|(tmp<< 8); break;");
+ p("case 2: r"+rt+" = (r"+rt+"&0x0000ffff)|(tmp<<16); break;");
+ p("case 3: r"+rt+" = (r"+rt+"&0x00ffffff)|(tmp<<24); break;");
+ indent--;
+ p("}");
+ break;*/
+ }
+ case 35: // LW
+ if(runtimeStats) p("inc(\"LW\");");
+ memRead("r" + rs +"+"+signedImmediate,"r"+rt);
+ break;
+ case 36: { // LBU
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp>>>(((~addr)&3)<<3)) & 0xff;");
+ p("r"+rt+" = tmp;");
+ break;
+ }
+ case 37: { // LHU
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp>>>(((~addr)&2)<<3)) & 0xffff;");
+ p("r"+rt+" = tmp;");
+ break;
+ }
+ case 38: { // LWR
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("r" + rt + " = (r"+rt+"&(0xffffff00<<((addr&3)<<3)))|(tmp>>>(((~addr)&3)<<3));");
+ break;
+
+ /*p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr&~3","tmp");
+ p("switch(addr&3) {");
+ indent++;
+ p("case 0: r"+rt+" = (r"+rt+"&0xffffff00)|(tmp>>>24); break;");
+ p("case 1: r"+rt+" = (r"+rt+"&0xffff0000)|(tmp>>>16); break;");
+ p("case 2: r"+rt+" = (r"+rt+"&0xff000000)|(tmp>>> 8); break;");
+ p("case 3: r"+rt+" = (r"+rt+"&0x00000000)|(tmp>>> 0); break;");
+ indent--;
+ p("}");
+ break;*/
+
+ }
+ case 40: { // SB
+ if(runtimeStats) p("inc(\"SB\");");
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp&~(0xff000000>>>((addr&3)<<3)))|((r"+rt+"&0xff)<<(((~addr)&3)<<3));");
+ memWrite("addr","tmp");
+ break;
+ }
+ case 41: { // SH
+ if(runtimeStats) p("inc(\"SH\");");
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp&(0xffff<<((addr&2)<<3)))|((r" + rt + "&0xffff)<<(((~addr)&2)<<3));");
+ memWrite("addr","tmp");
+ break;
+ }
+ case 42: { // SWL
+ p(" // SWL");
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp&(0xffffff00<<(((~addr)&3)<<3)))|(r"+rt+">>>((addr&3)<<3));");
+ memWrite("addr","tmp");
+ break;
+ }
+ case 43: // SW
+ if(runtimeStats) p("inc(\"SW\");");
+ memWrite("r"+rs+"+"+signedImmediate,"r" + rt);
+ break;
+ case 46: { // SWR
+ p(" // SWR");
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp&(0x00ffffff>>>((addr&3)<<3)))|(r"+rt+"<<(((~addr)&3)<<3));");
+ memWrite("addr","tmp");
+ break;
+ }
+ // FEATURE: Need to be atomic if threads
+ case 48: // LWC0/LL
+ memRead("r"+rs+"+"+signedImmediate,"r"+rt);
+ break;
+ case 49: // LWC1
+ memRead("r"+rs+"+"+signedImmediate,"f"+rt);
+ break;
+ // FEATURE: Needs to be atomic if threads
+ case 56: // SWC1/SC
+ memWrite("r"+rs+"+"+signedImmediate,"r"+rt);
+ p("r" + rt + "=1;");
+ break;
+ case 57: // SWC1
+ memWrite("r"+rs+"+"+signedImmediate,"f"+rt);
+ break;
+ default:
+ throw new Exn("Invalid Instruction: " + op + " at " + toHex(pc));
+ }
+ }
+
+ // Helper functions for emitText
+ // NOTE: memWrite and memRead MUST discard the last two bits of addr
+ private void memWrite(String addr, String target) {
+ if(nullPointerCheck) p("nullPointerCheck(" + addr + ");");
+ if(onePage)
+ p("page[(" + addr + ")>>>2] = " + target + ";");
+ else if(fastMem)
+ p("writePages[("+addr+")>>>"+pageShift+"][(("+addr+")>>>2)&"+toHex((pageSize>>2)-1)+"] = " + target + ";");
+ else
+ p("unsafeMemWrite(" + addr + "," + target + ");");
+ }
+ private void memRead(String addr, String target) {
+ if(nullPointerCheck) p("nullPointerCheck(" + addr + ");");
+ if(onePage)
+ p(target + "= page[(" + addr + ")>>>2];");
+ else if(fastMem)
+ p(target + " = readPages[("+addr+")>>>"+pageShift+"][(("+addr+")>>>2)&"+toHex((pageSize>>2)-1)+"];");
+ else
+ p(target + " = unsafeMemRead(" + addr + ");");
+ }
+ private static String getFloat(int r) { return "(Float.intBitsToFloat(f"+r+"))"; }
+ private static String getDouble(int r) {
+ return "(Double.longBitsToDouble(((f"+(r+1)+"&0xffffffffL) << 32) | (f"+r+"&0xffffffffL)))";
+ }
+ private static String setFloat(int r, String expr) { return "f"+r+"=Float.floatToRawIntBits("+expr+");"; }
+ private static String setDouble(int r, String expr) {
+ return "{ long l = Double.doubleToLongBits("+expr+"); "+
+ "f"+(r+1)+" = (int)(l >>> 32); f"+r+" = (int)l; }";
+ }
+}
+
\ No newline at end of file
--- /dev/null
+package org.xwt.mips;
+
+interface Registers {
+ // Register Names
+ public final static int ZERO = 0; // Immutable, hardwired to 0
+ public final static int AT = 1; // Reserved for assembler
+ public final static int K0 = 26; // Reserved for kernel
+ public final static int K1 = 27; // Reserved for kernel
+ public final static int GP = 28; // Global pointer (the middle of .sdata/.sbss)
+ public final static int SP = 29; // Stack pointer
+ public final static int FP = 30; // Frame Pointer
+ public final static int RA = 31; // Return Address
+
+ // Return values (caller saved)
+ public final static int V0 = 2;
+ public final static int V1 = 3;
+ // Argument Registers (caller saved)
+ public final static int A0 = 4;
+ public final static int A1 = 5;
+ public final static int A2 = 6;
+ public final static int A3 = 7;
+ // Temporaries (caller saved)
+ public final static int T0 = 8;
+ public final static int T1 = 9;
+ public final static int T2 = 10;
+ public final static int T3 = 11;
+ public final static int T4 = 12;
+ public final static int T5 = 13;
+ public final static int T6 = 14;
+ public final static int T7 = 15;
+ public final static int T8 = 24;
+ public final static int T9 = 25;
+ // Saved (callee saved)
+ public final static int S0 = 16;
+ public final static int S1 = 17;
+ public final static int S2 = 18;
+ public final static int S3 = 19;
+ public final static int S4 = 20;
+ public final static int S5 = 21;
+ public final static int S6 = 22;
+ public final static int S7 = 23;
+}
--- /dev/null
+// Copyright 2003 Brian Alliet
+// Based on org.xwt.imp.MIPS by Adam Megacz
+// Portions Copyright 2003 Adam Megacz
+
+package org.xwt.mips;
+
+import org.xwt.mips.util.*;
+import java.io.*;
+import java.util.Arrays;
+
+// FEATURE: Look over the public API, make sure we're exposing a bare minimum
+// (we might make this an interface in the future)
+
+public abstract class Runtime implements UsermodeConstants,Registers {
+ /** Pages are 4k in size */
+ protected final int PAGE_SIZE;
+ protected final int PAGE_WORDS;
+ protected final int PAGE_SHIFT;
+ protected final int TOTAL_PAGES;
+ /** This is the upper limit of the pages allocated by the sbrk() syscall. */
+ protected final int BRK_LIMIT;
+ protected final int STACK_BOTTOM;
+
+ /** This is the maximum size of command line arguments */
+ public final static int ARGS_MAX = 1024*1024;
+
+ /** True if we allow empty pages (_emptyPage) to exist in memory.
+ Empty pages are pages which are allocated by the program but do not contain any
+ data yet (they are all 0s). If empty pages are allowed subclasses must always
+ access main memory with the memRead and memWrite functions */
+ private final boolean allowEmptyPages;
+ /** the "empty page" */
+ private final static int[] _emptyPage = new int[0];
+
+ protected final static boolean isEmptyPage(int[] page) { return page == _emptyPage; }
+
+ /** Returns a new empty page (_emptyPage is empty pages are enabled or a new zero'd page) */
+ private final int[] emptyPage() { return allowEmptyPages ? _emptyPage : new int[PAGE_WORDS]; }
+
+ /** Readable main memory pages */
+ protected final int[][] readPages;
+ /** Writable main memory pages.
+ If the page is writable writePages[x] == readPages[x]; if not writePages[x] == null. */
+ protected final int[][] writePages;
+
+ /** The current break between the heap and unallocated memory */
+ protected int brkAddr;
+
+ /** The program's entry point */
+ protected int entryPoint;
+
+ /** The location of the _user_info block (or 0 is there is none) */
+ protected int userInfoBase;
+ protected int userInfoSize;
+
+ /** The location of the global pointer */
+ protected int gp;
+
+ /** When the process started */
+ private long startTime;
+
+ /** State constant: There is no program loaded in memory */
+ public final static int UNINITIALIZED = 0;
+ /** Text/Data loaded in memory */
+ public final static int INITIALIZED = 1;
+ /** Program is executing instructions */
+ public final static int RUNNING = 2;
+ /** Prgram has been started but is paused */
+ public final static int PAUSED = 3;
+ /** Program is executing a callJava() method */
+ public final static int CALLJAVA = 4;
+ /** Program has exited (it cannot currently be restarted) */
+ public final static int DONE = 5;
+
+ /** The current state (UNINITIALIZED, INITIALIZED, RUNNING, PAUSED, or DONE) */
+ protected int state = UNINITIALIZED;
+ /** @see Runtime#state state */
+ public final int getState() { return state; }
+
+ /** The exit status if the process (only valid if state==DONE)
+ @see Runtime#state */
+ protected int exitStatus;
+ public ExecutionException exitException;
+
+ /** Maximum number of open file descriptors */
+ final static int OPEN_MAX = 256;
+ /** Table containing all open file descriptors. (Entries are null if the fd is not in use */
+ FD[] fds = new FD[OPEN_MAX];
+
+ /** Temporary buffer for read/write operations */
+ private byte[] _byteBuf = null;
+ /** Max size of temporary buffer
+ @see Runtime#_byteBuf */
+ private final static int MAX_CHUNK = 15*1024*1024;
+
+ /** Subclasses should actually execute program in this method. They should continue
+ executing until state != RUNNING. Only syscall() can modify state. It is safe
+ to only check the state attribute after a call to syscall() */
+ protected abstract void _execute() throws ExecutionException;
+
+ /** Subclasses should return the address of the symbol <i>symbol</i> or -1 it it doesn't exits in this method
+ This method is only required if the call() function is used */
+ protected int lookupSymbol(String symbol) { return -1; }
+
+ /** Subclasses should returns a CPUState object representing the cpu state */
+ protected abstract CPUState getCPUState();
+
+ /** Subclasses should set the CPUState to the state held in <i>state</i> */
+ protected abstract void setCPUState(CPUState state);
+
+ static void checkPageSize(int pageSize, int totalPages) throws IllegalArgumentException {
+ if(pageSize < 256) throw new IllegalArgumentException("pageSize too small");
+ if((pageSize&(pageSize-1)) != 0) throw new IllegalArgumentException("pageSize must be a power of two");
+ if((totalPages&(totalPages-1)) != 0) throw new IllegalArgumentException("totalPages must be a power of two");
+ if(totalPages != 1 && totalPages < 256) throw new IllegalArgumentException("totalPages too small");
+ if(totalPages * pageSize < 4*1024*1024) throw new IllegalArgumentException("total memory too small (" + totalPages + "*" + pageSize + ")");
+ }
+
+ protected Runtime(int pageSize, int totalPages, boolean allowEmptyPages) {
+ this.allowEmptyPages = allowEmptyPages;
+
+ checkPageSize(pageSize,totalPages);
+
+ PAGE_SIZE = pageSize;
+ PAGE_WORDS = pageSize>>>2;
+ int pageShift = 0;
+ while(pageSize>>>pageShift != 1) pageShift++;
+ PAGE_SHIFT = pageShift;
+
+ TOTAL_PAGES = totalPages;
+
+ readPages = new int[TOTAL_PAGES][];
+ writePages = new int[TOTAL_PAGES][];
+
+ if(TOTAL_PAGES == 1) {
+ readPages[0] = writePages[0] = new int[PAGE_WORDS];
+ BRK_LIMIT = STACK_BOTTOM = 0;
+ } else {
+ int stackPages = max(TOTAL_PAGES>>>8,(1024*1024)>>>PAGE_SHIFT);
+ STACK_BOTTOM = (TOTAL_PAGES - stackPages) * PAGE_SIZE;
+ // leave some unmapped pages between the stack and the heap
+ BRK_LIMIT = STACK_BOTTOM - 4*PAGE_SIZE;
+
+ for(int i=0;i<stackPages;i++)
+ readPages[TOTAL_PAGES-1-i] = writePages[TOTAL_PAGES-1-i] = emptyPage();
+ }
+
+ addFD(new StdinFD(System.in));
+ addFD(new StdoutFD(System.out));
+ addFD(new StdoutFD(System.err));
+ }
+
+ /** Copy everything from <i>src</i> to <i>addr</i> initializing uninitialized pages if required.
+ Newly initalized pages will be marked read-only if <i>ro</i> is set */
+ protected final void initPages(int[] src, int addr, boolean ro) {
+ for(int i=0;i<src.length;) {
+ int page = addr >>> PAGE_SHIFT;
+ int start = (addr&(PAGE_SIZE-1))>>2;
+ int elements = min(PAGE_WORDS-start,src.length-i);
+ if(readPages[page]==null) {
+ initPage(page,ro);
+ } else if(!ro) {
+ if(writePages[page] == null) writePages[page] = readPages[page];
+ }
+ System.arraycopy(src,i,readPages[page],start,elements);
+ i += elements;
+ addr += elements*4;
+ }
+ }
+
+ /** Initialize <i>words</i> of pages starting at <i>addr</i> to 0 */
+ protected final void clearPages(int addr, int words) {
+ for(int i=0;i<words;) {
+ int page = addr >>> PAGE_SHIFT;
+ int start = (addr&(PAGE_SIZE-1))>>2;
+ int elements = min(PAGE_WORDS-start,words-i);
+ if(readPages[page]==null) {
+ readPages[page] = writePages[page] = emptyPage();
+ } else {
+ if(writePages[page] == null) writePages[page] = readPages[page];
+ for(int j=start;j<start+elements;j++) writePages[page][j] = 0;
+ }
+ i += elements;
+ addr += elements*4;
+ }
+ }
+
+ /** Copies <i>length</i> bytes from the processes memory space starting at
+ <i>addr</i> INTO a java byte array <i>a</i> */
+ public final void copyin(int addr, byte[] buf, int count) throws ReadFaultException {
+ int x=0;
+ if((addr&3)!=0) {
+ int word = memRead(addr&~3);
+ switch(addr&3) {
+ case 1: buf[x++] = (byte)((word>>>16)&0xff); if(--count==0) break;
+ case 2: buf[x++] = (byte)((word>>> 8)&0xff); if(--count==0) break;
+ case 3: buf[x++] = (byte)((word>>> 0)&0xff); if(--count==0) break;
+ }
+ addr = (addr&~3)+4;
+ }
+ if((count&~3) != 0) {
+ int c = count>>>2;
+ int a = addr>>>2;
+ while(c != 0) {
+ int[] page = readPages[a >>> (PAGE_SHIFT-2)];
+ if(page == null) throw new ReadFaultException(a<<2);
+ int index = a&(PAGE_WORDS-1);
+ int n = min(c,PAGE_WORDS-index);
+ if(page != _emptyPage) {
+ for(int i=0;i<n;i++,x+=4) {
+ int word = page[index+i];
+ buf[x+0] = (byte)((word>>>24)&0xff); buf[x+1] = (byte)((word>>>16)&0xff);
+ buf[x+2] = (byte)((word>>> 8)&0xff); buf[x+3] = (byte)((word>>> 0)&0xff);
+ }
+ }
+ a += n; c -=n;
+ }
+ addr = a<<2; count &=3;
+ }
+ if(count != 0) {
+ int word = memRead(addr);
+ switch(count) {
+ case 3: buf[x+2] = (byte)((word>>>8)&0xff);
+ case 2: buf[x+1] = (byte)((word>>>16)&0xff);
+ case 1: buf[x+0] = (byte)((word>>>24)&0xff);
+ }
+ }
+ }
+
+ /** Copies <i>length</i> bytes OUT OF the java array <i>a</i> into the processes memory
+ space at <i>addr</i> */
+ public final void copyout(byte[] buf, int addr, int count) throws FaultException {
+ int x=0;
+ if((addr&3)!=0) {
+ int word = memRead(addr&~3);
+ switch(addr&3) {
+ case 1: word = (word&0xff00ffff)|((buf[x++]&0xff)<<16); if(--count==0) break;
+ case 2: word = (word&0xffff00ff)|((buf[x++]&0xff)<< 8); if(--count==0) break;
+ case 3: word = (word&0xffffff00)|((buf[x++]&0xff)<< 0); if(--count==0) break;
+ }
+ memWrite(addr&~3,word);
+ addr += x;
+ }
+ if((count&~3) != 0) {
+ int c = count>>>2;
+ int a = addr>>>2;
+ while(c != 0) {
+ int[] page = writePages[a >>> (PAGE_SHIFT-2)];
+ if(page == null) throw new WriteFaultException(a<<2);
+ if(page == _emptyPage) page = initPage(a >>> (PAGE_SHIFT-2));
+ int index = a&(PAGE_WORDS-1);
+ int n = min(c,PAGE_WORDS-index);
+ for(int i=0;i<n;i++,x+=4)
+ page[index+i] = ((buf[x+0]&0xff)<<24)|((buf[x+1]&0xff)<<16)|((buf[x+2]&0xff)<<8)|((buf[x+3]&0xff)<<0);
+ a += n; c -=n;
+ }
+ addr = a<<2; count&=3;
+ }
+ if(count != 0) {
+ int word = memRead(addr);
+ switch(count) {
+ case 1: word = (word&0x00ffffff)|((buf[x+0]&0xff)<<24); break;
+ case 2: word = (word&0x0000ffff)|((buf[x+0]&0xff)<<24)|((buf[x+1]&0xff)<<16); break;
+ case 3: word = (word&0x000000ff)|((buf[x+0]&0xff)<<24)|((buf[x+1]&0xff)<<16)|((buf[x+2]&0xff)<<8); break;
+ }
+ memWrite(addr,word);
+ }
+ }
+
+ public final void memcpy(int dst, int src, int count) throws FaultException {
+ if((dst&3) == 0 && (src&3)==0) {
+ if((count&~3) != 0) {
+ int c = count>>2;
+ int s = src>>>2;
+ int d = dst>>>2;
+ while(c != 0) {
+ int[] srcPage = readPages[s>>>(PAGE_SHIFT-2)];
+ if(srcPage == null) throw new ReadFaultException(s<<2);
+ int[] dstPage = writePages[d>>>(PAGE_SHIFT-2)];
+ if(dstPage == null) throw new WriteFaultException(d<<2);
+ int srcIndex = (s&(PAGE_WORDS-1));
+ int dstIndex = (d&(PAGE_WORDS-1));
+ int n = min(c,PAGE_WORDS-max(srcIndex,dstIndex));
+ if(srcPage != _emptyPage) {
+ if(dstPage == _emptyPage) dstPage = initPage(d>>>(PAGE_SHIFT-2));
+ System.arraycopy(srcPage,srcIndex,dstPage,dstIndex,n);
+ } else if(srcPage == _emptyPage && dstPage != _emptyPage) {
+ Arrays.fill(dstPage,dstIndex,dstIndex+n,0);
+ }
+ s += n; d += n; c -= n;
+ }
+ src = s<<2; dst = d<<2; count&=3;
+ }
+ if(count != 0) {
+ int word1 = memRead(src);
+ int word2 = memRead(dst);
+ switch(count) {
+ case 1: memWrite(dst,(word1&0xff000000)|(word2&0x00ffffff)); break;
+ case 2: memWrite(dst,(word1&0xffff0000)|(word2&0x0000ffff)); break;
+ case 3: memWrite(dst,(word1&0xffffff00)|(word2&0x000000ff)); break;
+ }
+ }
+ } else {
+ while(count > 0) {
+ int n = min(count,MAX_CHUNK);
+ byte[] buf = byteBuf(n);
+ copyin(src,buf,n);
+ copyout(buf,dst,n);
+ count -= n; src += n; dst += n;
+ }
+ }
+ }
+
+ public final void memset(int addr, int ch, int count) throws FaultException {
+ int fourBytes = ((ch&0xff)<<24)|((ch&0xff)<<16)|((ch&0xff)<<8)|((ch&0xff)<<0);
+ if((addr&3)!=0) {
+ int word = memRead(addr&~3);
+ switch(addr&3) {
+ case 1: word = (word&0xff00ffff)|((ch&0xff)<<16); if(--count==0) break;
+ case 2: word = (word&0xffff00ff)|((ch&0xff)<< 8); if(--count==0) break;
+ case 3: word = (word&0xffffff00)|((ch&0xff)<< 0); if(--count==0) break;
+ }
+ memWrite(addr&~3,word);
+ addr = (addr&~3)+4;
+ }
+ if((count&~3) != 0) {
+ int c = count>>2;
+ int a = addr>>>2;
+ while(c != 0) {
+ int[] page = readPages[a>>>(PAGE_SHIFT-2)];
+ if(page == null) throw new WriteFaultException(a<<2);
+ int index = (a&(PAGE_WORDS-1));
+ int n = min(c,PAGE_WORDS-index);
+ if(page != _emptyPage || ch != 0) {
+ if(page == _emptyPage) page = initPage(a>>>(PAGE_SHIFT-2));
+ Arrays.fill(page,index,index+n,fourBytes);
+ }
+ a += n; c -= n;
+ }
+ addr = a<<2; count&=3;
+ }
+ if(count != 0) {
+ int word = memRead(addr);
+ switch(count) {
+ case 1: word = (word&0x00ffffff)|(fourBytes&0xff000000); break;
+ case 2: word = (word&0x0000ffff)|(fourBytes&0xffff0000); break;
+ case 3: word = (word&0x000000ff)|(fourBytes&0xffffff00); break;
+ }
+ memWrite(addr,word);
+ }
+ }
+
+ /** Read a word from the processes memory at <i>addr</i> */
+ public final int memRead(int addr) throws ReadFaultException {
+ if((addr & 3) != 0) throw new ReadFaultException(addr);
+ return unsafeMemRead(addr);
+ }
+
+ protected final int unsafeMemRead(int addr) throws ReadFaultException {
+ int page = addr >>> PAGE_SHIFT;
+ int entry = (addr >>> 2) & (PAGE_WORDS-1);
+ try {
+ return readPages[page][entry];
+ } catch(ArrayIndexOutOfBoundsException e) {
+ if(page < 0) throw e; // should never happen
+ if(page >= readPages.length) throw new ReadFaultException(addr);
+ if(readPages[page] != _emptyPage) throw e; // should never happen
+ initPage(page);
+ return 0;
+ } catch(NullPointerException e) {
+ throw new ReadFaultException(addr);
+ }
+ }
+
+ /** Writes a word to the processes memory at <i>addr</i> */
+ public final void memWrite(int addr, int value) throws WriteFaultException {
+ if((addr & 3) != 0) throw new WriteFaultException(addr);
+ unsafeMemWrite(addr,value);
+ }
+
+ protected final void unsafeMemWrite(int addr, int value) throws WriteFaultException {
+ int page = addr >>> PAGE_SHIFT;
+ int entry = (addr>>>2)&(PAGE_WORDS-1);
+ try {
+ writePages[page][entry] = value;
+ } catch(ArrayIndexOutOfBoundsException e) {
+ if(page < 0) throw e;// should never happen
+ if(page >= writePages.length) throw new WriteFaultException(addr);
+ if(readPages[page] != _emptyPage) throw e; // should never happen
+ initPage(page);
+ writePages[page][entry] = value;
+ } catch(NullPointerException e) {
+ throw new WriteFaultException(addr);
+ }
+ }
+
+ /** Created a new non-empty writable page at page number <i>page</i> */
+ private final int[] initPage(int page) { return initPage(page,false); }
+ /** Created a new non-empty page at page number <i>page</i>. If <i>ro</i> is set the page will be read-only */
+ private final int[] initPage(int page, boolean ro) {
+ int[] buf = new int[PAGE_WORDS];
+ writePages[page] = ro ? null : buf;
+ readPages[page] = buf;
+ return buf;
+ }
+
+ /** Returns the exit status of the process. (only valid if state == DONE)
+ @see Runtime#state */
+ public final int exitStatus() {
+ if(state != DONE) throw new IllegalStateException("exitStatus() called in an inappropriate state");
+ return exitStatus;
+ }
+
+ private int addStringArray(String[] strings, int topAddr) {
+ int count = strings.length;
+ int total = 0; /* null last table entry */
+ for(int i=0;i<count;i++) total += strings[i].length() + 1;
+ if(total >= ARGS_MAX) throw new IllegalArgumentException("arguments/environ too big");
+ total += (count+1)*4;
+ int start = (topAddr - total)&~3;
+ int addr = start + (count+1)*4;
+ int[] table = new int[count+1];
+ try {
+ for(int i=0;i<count;i++) {
+ byte[] a = getBytes(strings[i]);
+ table[i] = addr;
+ copyout(a,addr,a.length);
+ memset(addr+a.length,0,1);
+ addr += a.length + 1;
+ }
+ addr=start;
+ for(int i=0;i<count+1;i++) {
+ memWrite(addr,table[i]);
+ addr += 4;
+ }
+ } catch(FaultException e) {
+ // should never happen
+ throw new Error(e);
+ }
+ return start;
+ }
+
+ protected String[] createEnv(String[] extra) { if(extra == null) extra = new String[0]; return extra; }
+
+ /** Sets word number <i>index</i> in the _user_info table to <i>word</i>
+ * The user_info table is a chunk of memory in the program's memory defined by the
+ * symbol "user_info". The compiler/interpreter automatically determine the size
+ * and location of the user_info table from the ELF symbol table. setUserInfo and
+ * getUserInfo are used to modify the words in the user_info table. */
+ public void setUserInfo(int index, int word) {
+ if(index < 0 || index >= userInfoSize/4) throw new IndexOutOfBoundsException("setUserInfo called with index >= " + (userInfoSize/4));
+ try {
+ memWrite(userInfoBase+index*4,word);
+ } catch(FaultException e) { throw new Error("should never happen: " + e); }
+ }
+
+ /** Returns the word in the _user_info table entry <i>index</i>
+ @see Runtime#setUserInfo(int,int) setUserInfo */
+ public int getUserInfo(int index) {
+ if(index < 0 || index >= userInfoSize/4) throw new IndexOutOfBoundsException("setUserInfo called with index >= " + (userInfoSize/4));
+ try {
+ return memRead(userInfoBase+index*4);
+ } catch(FaultException e) { throw new Error("should never happen: " + e); }
+ }
+
+ /** Calls _execute() (subclass's execute()) and catches exceptions */
+ private void __execute() {
+ try {
+ _execute();
+ } catch(FaultException e) {
+ e.printStackTrace();
+ sys_exit(128+11); // SIGSEGV
+ exitException = e;
+ } catch(ExecutionException e) {
+ e.printStackTrace();
+ System.err.println(e);
+ sys_exit(128+4); // SIGILL
+ exitException = e;
+ }
+ }
+
+ /** Executes the process until the PAUSE syscall is invoked or the process exits. Returns true if the process exited. */
+ public final boolean execute() {
+ if(state != PAUSED) throw new IllegalStateException("execute() called in inappropriate state");
+ if(startTime == 0) startTime = System.currentTimeMillis();
+ state = RUNNING;
+ __execute();
+ if(state != PAUSED && state != DONE) throw new IllegalStateException("execute() ended up in an inappropriate state (" + state + ")");
+ return state == DONE;
+ }
+
+ public final int run() { return run(null); }
+ public final int run(String argv0, String[] rest) {
+ String[] args = new String[rest.length+1];
+ System.arraycopy(rest,0,args,1,rest.length);
+ args[0] = argv0;
+ return run(args);
+ }
+ public final int run(String[] args) { return run(args,null); }
+
+ /** Runs the process until it exits and returns the exit status.
+ If the process executes the PAUSE syscall execution will be paused for 500ms and a warning will be displayed */
+ public final int run(String[] args, String[] env) {
+ start(args,env);
+ for(;;) {
+ if(execute()) break;
+ System.err.println("WARNING: Pause requested while executing run()");
+ try { Thread.sleep(500); } catch(InterruptedException e) { /* noop */ }
+ }
+ return exitStatus();
+ }
+
+ public final void start() { start(null); }
+ public final void start(String[] args) { start(args,null); }
+
+ /** Initializes the process and prepairs it to be executed with execute() */
+ public final void start(String[] args, String[] environ) {
+ int sp, argsAddr, envAddr;
+ if(state != INITIALIZED) throw new IllegalStateException("start() called in inappropriate state");
+
+ if(args == null) args = new String[]{getClass().getName()};
+
+ sp = TOTAL_PAGES*PAGE_SIZE-512;
+ sp = argsAddr = addStringArray(args,sp);
+ sp = envAddr = addStringArray(createEnv(environ),sp);
+ sp &= ~15;
+
+ CPUState cpuState = new CPUState();
+ cpuState.r[A0] = argsAddr;
+ cpuState.r[A1] = envAddr;
+ cpuState.r[SP] = sp;
+ cpuState.r[RA] = 0xdeadbeef;
+ cpuState.r[GP] = gp;
+ cpuState.pc = entryPoint;
+ setCPUState(cpuState);
+
+ state = PAUSED;
+
+ _start();
+ }
+
+ /** Hook for subclasses to do their own startup */
+ protected void _start() { /* noop */ }
+
+ public final int call(String sym) throws CallException { return call(sym,0,0,0,0,0,0,0); }
+ public final int call(String sym, int a0) throws CallException { return call(sym,a0,0,0,0,0,0,0); }
+ public final int call(String sym, int a0, int a1) throws CallException { return call(sym,a0,a1,0,0,0,0,0); }
+ public final int call(String sym, int a0, int a1, int a2) throws CallException { return call(sym,a0,a1,a2,0,0,0,0); }
+ public final int call(String sym, int a0, int a1, int a2, int a3) throws CallException { return call(sym,a0,a1,a2,a3,0,0,0); }
+ public final int call(String sym, int a0, int a1, int a2, int a3, int a4) throws CallException { return call(sym,a0,a1,a2,a3,a4,0,0); }
+ public final int call(String sym, int a0, int a1, int a2, int a3, int a4, int a5) throws CallException { return call(sym,a0,a1,a2,a3,a4,a5,0); }
+
+ /** Calls a function in the process with the given arguments */
+ public final int call(String sym, int a0, int a1, int a2, int a3, int a4, int a5, int a6) throws CallException {
+ int func = lookupSymbol(sym);
+ if(func == -1) throw new CallException(sym + " not found");
+ int helper = lookupSymbol("_call_helper");
+ if(helper == -1) throw new CallException("_call_helper not found");
+ return call(helper,func,a0,a1,a2,a3,a4,a5,a6);
+ }
+
+ /** Executes the code at <i>addr</i> in the process setting A0-A3 and S0-S3 to the given arguments
+ and returns the contents of V1 when the the pause syscall is invoked */
+ public final int call(int addr, int a0, int a1, int a2, int a3, int s0, int s1, int s2, int s3) {
+ if(state != PAUSED && state != CALLJAVA) throw new IllegalStateException("call() called in inappropriate state");
+ int oldState = state;
+ CPUState saved = getCPUState();
+ CPUState cpustate = new CPUState();
+ cpustate.r[SP] = saved.r[SP]&~15;
+ cpustate.r[RA] = 0xdeadbeef;
+ cpustate.r[A0] = a0;
+ cpustate.r[A1] = a1;
+ cpustate.r[A2] = a2;
+ cpustate.r[A3] = a3;
+ cpustate.r[S0] = s0;
+ cpustate.r[S1] = s1;
+ cpustate.r[S2] = s2;
+ cpustate.r[S3] = s3;
+ cpustate.r[GP] = gp;
+ cpustate.pc = addr;
+
+ state = RUNNING;
+
+ setCPUState(cpustate);
+ __execute();
+ cpustate = getCPUState();
+ setCPUState(saved);
+
+ if(state != PAUSED)
+ System.out.println("WARNING: Process exit()ed while servicing a call() request");
+ else
+ state = oldState;
+
+ return cpustate.r[V1];
+ }
+
+ // FEATURE: This is ugly - we should have some kind of way to specify a callback rather than requiring subclassing
+ protected int callJava(int a, int b, int c, int d) {
+ System.err.println("WARNING: Default implementation of callJava() called with args " + toHex(a) + "," + toHex(b) + "," + toHex(c) + "," + toHex(d));
+ return 0;
+ }
+
+ /** Determines if the process can access <i>fileName</i>. The default implementation simply logs
+ the request and allows it */
+ protected boolean allowFileAccess(String fileName, boolean write) {
+ //System.err.println("Allowing " + (write?"write":"read-only") + " access to " + fileName);
+ return true;
+ }
+
+ /** Allocated an entry in the FileDescriptor table for <i>fd</i> and returns the number.
+ Returns -1 if the table is full. This can be used by subclasses to use custom file
+ descriptors */
+ public int addFD(FD fd) {
+ int i;
+ for(i=0;i<OPEN_MAX;i++) if(fds[i] == null) break;
+ if(i==OPEN_MAX) return -1;
+ fds[i] = fd;
+ return i;
+ }
+
+ /** Closes file descriptor <i>fdn</i> and removes it from the file descriptor table */
+ public boolean closeFD(int fdn) {
+ if(fdn < 0 || fdn >= OPEN_MAX) return false;
+ if(fds[fdn] == null) return false;
+ fds[fdn].close();
+ fds[fdn] = null;
+ return true;
+ }
+
+ // FEATURE: These should be pulled in from UsermodeConstants but fcntl.h is hard to parse
+ public static final int RD_ONLY = 0;
+ public static final int WR_ONLY = 1;
+ public static final int RDWR = 2;
+
+ public static final int O_CREAT = 0x0200;
+ public static final int O_EXCL = 0x0800;
+ public static final int O_APPEND = 0x0008;
+ public static final int O_TRUNC = 0x0400;
+ public static final int O_NONBLOCK = 0x4000;
+
+ // FEATURE: Lots of duplicate code between this and UnixRuntime.HostFS.open()
+ protected FD open(String path, int flags, int mode) throws IOException {
+ final File f = new File(path);
+ // NOTE: createNewFile is a Java2 function
+ if((flags & (O_EXCL|O_CREAT)) == (O_EXCL|O_CREAT))
+ if(!f.createNewFile()) throw new ErrnoException(EEXIST);
+ if(!f.exists() && (flags&O_CREAT) == 0) return null;
+ if(f.isDirectory()) return null;
+ final SeekableFile sf = new SeekableFile(path,mode!=RD_ONLY);
+ if((flags&O_TRUNC)!=0) sf.setLength(0);
+ return new SeekableFD(sf,flags) {
+ protected FStat _fstat() { return new HostFStat(f) {
+ public int size() {
+ try { return sf.length(); } catch(IOException e) { return 0; }
+ }
+ };}
+ };
+ }
+
+ /** The open syscall */
+ private int sys_open(int addr, int flags, int mode) {
+ if((flags & O_NONBLOCK) != 0) {
+ System.err.println("WARNING: O_NONBLOCK not supported");
+ return -EOPNOTSUPP;
+ }
+
+ try {
+ FD fd = open(cstring(addr),flags,mode);
+ if(fd == null) return -ENOENT;
+ int fdn = addFD(fd);
+ if(fdn == -1) {
+ fd.close();
+ return -ENFILE;
+ }
+ return fdn;
+ }
+ catch(ErrnoException e) { return -e.errno; }
+ catch(FileNotFoundException e) {
+ if(e.getMessage() != null && e.getMessage().indexOf("Permission denied") >= 0) return -EACCES;
+ return -ENOENT;
+ }
+ catch(IOException e) { return -EIO; }
+ catch(FaultException e) { return -EFAULT; }
+ }
+
+ /** The write syscall */
+ private int sys_write(int fdn, int addr, int count) {
+ count = Math.min(count,MAX_CHUNK);
+ if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
+ if(fds[fdn] == null || !fds[fdn].writable()) return -EBADFD;
+ try {
+ byte[] buf = byteBuf(count);
+ copyin(addr,buf,count);
+ return fds[fdn].write(buf,0,count);
+ } catch(FaultException e) {
+ System.err.println(e);
+ return -EFAULT;
+ } catch(IOException e) {
+ // FEATURE: We should support signals and send a SIGPIPE
+ if(e.getMessage().equals("Pipe closed")) return sys_exit(128+13);
+ System.err.println(e);
+ return -EIO;
+ }
+ }
+
+ /** The read syscall */
+ private int sys_read(int fdn, int addr, int count) {
+ count = Math.min(count,MAX_CHUNK);
+ if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
+ if(fds[fdn] == null || !fds[fdn].readable()) return -EBADFD;
+ try {
+ byte[] buf = byteBuf(count);
+ int n = fds[fdn].read(buf,0,count);
+ copyout(buf,addr,n);
+ return n;
+ } catch(FaultException e) {
+ System.err.println(e);
+ return -EFAULT;
+ } catch(IOException e) {
+ System.err.println(e);
+ return -EIO;
+ }
+ }
+
+ /** The close syscall */
+ private int sys_close(int fdn) {
+ return closeFD(fdn) ? 0 : -EBADFD;
+ }
+
+
+ /** The seek syscall */
+ private int sys_lseek(int fdn, int offset, int whence) {
+ if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
+ if(fds[fdn] == null) return -EBADFD;
+ if(whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END) return -EINVAL;
+ try {
+ int n = fds[fdn].seek(offset,whence);
+ return n < 0 ? -ESPIPE : n;
+ } catch(IOException e) {
+ return -ESPIPE;
+ }
+ }
+
+ /** The stat/fstat syscall helper */
+ int stat(FStat fs, int addr) {
+ try {
+ memWrite(addr+0,(fs.dev()<<16)|(fs.inode()&0xffff)); // st_dev (top 16), // st_ino (bottom 16)
+ memWrite(addr+4,((fs.type()&0xf000))|(fs.mode()&0xfff)); // st_mode
+ memWrite(addr+8,1<<16); // st_nlink (top 16) // st_uid (bottom 16)
+ memWrite(addr+12,0); // st_gid (top 16) // st_rdev (bottom 16)
+ memWrite(addr+16,fs.size()); // st_size
+ memWrite(addr+20,fs.atime()); // st_atime
+ // memWrite(addr+24,0) // st_spare1
+ memWrite(addr+28,fs.mtime()); // st_mtime
+ // memWrite(addr+32,0) // st_spare2
+ memWrite(addr+36,fs.ctime()); // st_ctime
+ // memWrite(addr+40,0) // st_spare3
+ memWrite(addr+44,fs.blksize()); // st_bklsize;
+ memWrite(addr+48,fs.blocks()); // st_blocks
+ // memWrite(addr+52,0) // st_spare4[0]
+ // memWrite(addr+56,0) // st_spare4[1]
+ } catch(FaultException e) {
+ System.err.println(e);
+ return -EFAULT;
+ }
+ return 0;
+ }
+
+ /** The fstat syscall */
+ private int sys_fstat(int fdn, int addr) {
+ if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
+ if(fds[fdn] == null) return -EBADFD;
+ return stat(fds[fdn].fstat(),addr);
+ }
+
+ /*
+ struct timeval {
+ long tv_sec;
+ long tv_usec;
+ };
+ */
+ private int sys_gettimeofday(int timevalAddr, int timezoneAddr) {
+ long now = System.currentTimeMillis();
+ int tv_sec = (int)(now / 1000);
+ int tv_usec = (int)((now%1000)*1000);
+ try {
+ memWrite(timevalAddr+0,tv_sec);
+ memWrite(timevalAddr+4,tv_usec);
+ return 0;
+ } catch(FaultException e) {
+ return -EFAULT;
+ }
+ }
+
+ private int sys_sleep(int sec) {
+ if(sec < 0) sec = Integer.MAX_VALUE;
+ try {
+ Thread.sleep((long)sec*1000);
+ return 0;
+ } catch(InterruptedException e) {
+ return -1;
+ }
+ }
+
+ /*
+ #define _CLOCKS_PER_SEC_ 1000
+ #define _CLOCK_T_ unsigned long
+ struct tms {
+ clock_t tms_utime;
+ clock_t tms_stime;
+ clock_t tms_cutime;
+ clock_t tms_cstime;
+ };*/
+
+ private int sys_times(int tms) {
+ long now = System.currentTimeMillis();
+ int userTime = (int)((now - startTime)/16);
+ int sysTime = (int)((now - startTime)/16);
+
+ try {
+ if(tms!=0) {
+ memWrite(tms+0,userTime);
+ memWrite(tms+4,sysTime);
+ memWrite(tms+8,userTime);
+ memWrite(tms+12,sysTime);
+ }
+ } catch(FaultException e) {
+ return -EFAULT;
+ }
+ return (int)now;
+ }
+
+ private int sys_sysconf(int n) {
+ switch(n) {
+ case _SC_CLK_TCK: return 1000;
+ default:
+ System.err.println("WARNING: Attempted to use unknown sysconf key: " + n);
+ return -EINVAL;
+ }
+ }
+
+ /** The sbrk syscall. This can also be used by subclasses to allocate memory.
+ <i>incr</i> is how much to increase the break by */
+ public int sbrk(int incr) {
+ if(incr < 0) return -ENOMEM;
+ if(incr==0) return brkAddr;
+ incr = (incr+3)&~3;
+ int oldBrk = brkAddr;
+ int newBrk = oldBrk + incr;
+ if(TOTAL_PAGES == 1) {
+ CPUState state = getCPUState();
+ if(newBrk >= state.r[SP] - 65536) {
+ System.err.println("WARNING: brk too close to stack pointer");
+ return -ENOMEM;
+ }
+ } else if(newBrk >= BRK_LIMIT) {
+ System.err.println("WARNING: Hit BRK_LIMIT");
+ return -ENOMEM;
+ }
+ if(TOTAL_PAGES != 1) {
+ try {
+ for(int i=(oldBrk+PAGE_SIZE-1)>>>PAGE_SHIFT;i<((newBrk+PAGE_SIZE-1)>>>PAGE_SHIFT);i++)
+ readPages[i] = writePages[i] = emptyPage();
+ } catch(OutOfMemoryError e) {
+ System.err.println("WARNING: Caught OOM Exception in sbrk: " + e);
+ return -ENOMEM;
+ }
+ }
+ brkAddr = newBrk;
+ return oldBrk;
+ }
+
+ /** The getpid syscall */
+ private int sys_getpid() { return getPid(); }
+ protected int getPid() { return 1; }
+
+ private int sys_calljava(int a, int b, int c, int d) {
+ if(state != RUNNING) throw new IllegalStateException("wound up calling sys_calljava while not in RUNNING");
+ state = CALLJAVA;
+ int ret = callJava(a,b,c,d);
+ state = RUNNING;
+ return ret;
+ }
+
+ private int sys_pause() {
+ state = PAUSED;
+ return 0;
+ }
+
+ private int sys_getpagesize() { return TOTAL_PAGES == 1 ? 4096 : PAGE_SIZE; }
+
+ private int sys_isatty(int fdn) {
+ if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
+ if(fds[fdn] == null) return -EBADFD;
+ return fds[fdn].isatty() ? 1 : 0;
+ }
+
+
+ /** Hook for subclasses to do something when the process exits (MUST set state = DONE) */
+ protected void _exit() { state = DONE; }
+ private int sys_exit(int status) {
+ exitStatus = status;
+ for(int i=0;i<fds.length;i++) if(fds[i] != null) sys_close(i);
+ _exit();
+ return 0;
+ }
+
+ private int sys_fcntl(int fdn, int cmd, int arg) {
+ final int F_DUPFD = 0;
+ final int F_GETFL = 3;
+ int i;
+
+ if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
+ if(fds[fdn] == null) return -EBADFD;
+ FD fd = fds[fdn];
+
+ switch(cmd) {
+ case F_DUPFD:
+ if(arg < 0 || arg >= OPEN_MAX) return -EINVAL;
+ for(i=arg;i<OPEN_MAX;i++) if(fds[i]==null) break;
+ if(i==OPEN_MAX) return -EMFILE;
+ fds[i] = fd.dup();
+ return 0;
+ case F_GETFL:
+ int flags = 0;
+ if(fd.writable() && fd.readable()) flags = 2;
+ else if(fd.writable()) flags = 1;
+ return flags;
+ default:
+ System.err.println("WARNING: Unknown fcntl command: " + cmd);
+ return -ENOSYS;
+ }
+ }
+
+ /** The syscall dispatcher.
+ The should be called by subclasses when the syscall instruction is invoked.
+ <i>syscall</i> should be the contents of V0 and <i>a</i>, <i>b</i>, <i>c</i>, and <i>d</i> should be
+ the contenst of A0, A1, A2, and A3. The call MAY change the state
+ @see Runtime#state state */
+ protected int syscall(int syscall, int a, int b, int c, int d) {
+ switch(syscall) {
+ case SYS_null: return 0;
+ case SYS_exit: return sys_exit(a);
+ case SYS_pause: return sys_pause();
+ case SYS_write: return sys_write(a,b,c);
+ case SYS_fstat: return sys_fstat(a,b);
+ case SYS_sbrk: return sbrk(a);
+ case SYS_open: return sys_open(a,b,c);
+ case SYS_close: return sys_close(a);
+ case SYS_read: return sys_read(a,b,c);
+ case SYS_lseek: return sys_lseek(a,b,c);
+ case SYS_getpid: return sys_getpid();
+ case SYS_calljava: return sys_calljava(a,b,c,d);
+ case SYS_gettimeofday: return sys_gettimeofday(a,b);
+ case SYS_sleep: return sys_sleep(a);
+ case SYS_times: return sys_times(a);
+ case SYS_getpagesize: return sys_getpagesize();
+ case SYS_isatty: return sys_isatty(a);
+ case SYS_fcntl: return sys_fcntl(a,b,c);
+ case SYS_sysconf: return sys_sysconf(a);
+
+ case SYS_kill:
+ case SYS_fork:
+ case SYS_pipe:
+ case SYS_dup2:
+ case SYS_waitpid:
+ case SYS_stat:
+ case SYS_mkdir:
+ case SYS_getcwd:
+ case SYS_chdir:
+ System.err.println("Attempted to use a UnixRuntime syscall in Runtime (" + syscall + ")");
+ return -ENOSYS;
+ default:
+ System.err.println("Attempted to use unknown syscall: " + syscall);
+ return -ENOSYS;
+ }
+ }
+
+ public int xmalloc(int size) { int p=malloc(size); if(p==0) throw new RuntimeException("malloc() failed"); return p; }
+ public int xrealloc(int addr,int newsize) { int p=realloc(addr,newsize); if(p==0) throw new RuntimeException("realloc() failed"); return p; }
+ public int realloc(int addr, int newsize) { try { return call("realloc",addr,newsize); } catch(CallException e) { return 0; } }
+ public int malloc(int size) { try { return call("malloc",size); } catch(CallException e) { return 0; } }
+ public void free(int p) { try { if(p!=0) call("free",p); } catch(CallException e) { /*noop*/ } }
+
+ /** Helper function to create a cstring in main memory */
+ public int strdup(String s) {
+ byte[] a;
+ if(s == null) s = "(null)";
+ byte[] a2 = getBytes(s);
+ a = new byte[a2.length+1];
+ System.arraycopy(a2,0,a,0,a2.length);
+ int addr = malloc(a.length);
+ if(addr == 0) return 0;
+ try {
+ copyout(a,addr,a.length);
+ } catch(FaultException e) {
+ free(addr);
+ return 0;
+ }
+ return addr;
+ }
+
+ /** Helper function to read a cstring from main memory */
+ public String cstring(int addr) throws ReadFaultException {
+ StringBuffer sb = new StringBuffer();
+ for(;;) {
+ int word = memRead(addr&~3);
+ switch(addr&3) {
+ case 0: if(((word>>>24)&0xff)==0) return sb.toString(); sb.append((char)((word>>>24)&0xff)); addr++;
+ case 1: if(((word>>>16)&0xff)==0) return sb.toString(); sb.append((char)((word>>>16)&0xff)); addr++;
+ case 2: if(((word>>> 8)&0xff)==0) return sb.toString(); sb.append((char)((word>>> 8)&0xff)); addr++;
+ case 3: if(((word>>> 0)&0xff)==0) return sb.toString(); sb.append((char)((word>>> 0)&0xff)); addr++;
+ }
+ }
+ }
+
+ /** File Descriptor class */
+ public static abstract class FD {
+ private int refCount = 1;
+
+ /** returns true if the fd is readable */
+ public boolean readable() { return false; }
+ /** returns true if the fd is writable */
+ public boolean writable() { return false; }
+
+ /** Read some bytes. Should return the number of bytes read, 0 on EOF, or throw an IOException on error */
+ public int read(byte[] a, int off, int length) throws IOException { throw new IOException("no definition"); }
+ /** Write. Should return the number of bytes written or throw an IOException on error */
+ public int write(byte[] a, int off, int length) throws IOException { throw new IOException("no definition"); }
+
+ /** Seek in the filedescriptor. Whence is SEEK_SET, SEEK_CUR, or SEEK_END. Should return -1 on error or the new position. */
+ public int seek(int n, int whence) throws IOException { return -1; }
+
+ /** Should return true if this is a tty */
+ public boolean isatty() { return false; }
+
+ private FStat cachedFStat = null;
+ public final FStat fstat() {
+ if(cachedFStat == null) cachedFStat = _fstat();
+ return cachedFStat;
+ }
+
+ protected abstract FStat _fstat();
+
+ /** Closes the fd */
+ public final void close() { if(--refCount==0) _close(); }
+ protected void _close() { /* noop*/ }
+
+ FD dup() { refCount++; return this; }
+ }
+
+ /** FileDescriptor class for normal files */
+ public abstract static class SeekableFD extends FD {
+ private final int flags;
+ private final SeekableData data;
+ public boolean readable() { return (flags&3) != WR_ONLY; }
+ public boolean writable() { return (flags&3) != RD_ONLY; }
+
+ SeekableFD(SeekableData data, int flags) { this.data = data; this.flags = flags; }
+
+ protected abstract FStat _fstat();
+
+ public int seek(int n, int whence) throws IOException {
+ switch(whence) {
+ case SEEK_SET: break;
+ case SEEK_CUR: n += data.pos(); break;
+ case SEEK_END: n += data.length(); break;
+ default: return -1;
+ }
+ data.seek(n);
+ return n;
+ }
+
+ public int write(byte[] a, int off, int length) throws IOException {
+ // NOTE: There is race condition here but we can't fix it in pure java
+ if((flags&O_APPEND) != 0) seek(0,SEEK_END);
+ return data.write(a,off,length);
+ }
+
+ public int read(byte[] a, int off, int length) throws IOException {
+ int n = data.read(a,off,length);
+ return n < 0 ? 0 : n;
+ }
+
+ protected void _close() { try { data.close(); } catch(IOException e) { /*ignore*/ } }
+ }
+
+ public static class OutputStreamFD extends FD {
+ private OutputStream os;
+ public boolean writable() { return true; }
+ public OutputStreamFD(OutputStream os) { this.os = os; }
+ public int write(byte[] a, int off, int length) throws IOException { os.write(a,off,length); return length; }
+ public void _close() { try { os.close(); } catch(IOException e) { /*ignore*/ } }
+ public FStat _fstat() { return new FStat(); }
+ }
+
+ public static class InputStreamFD extends FD {
+ private InputStream is;
+ public boolean readable() { return true; }
+ public InputStreamFD(InputStream is) { this.is = is; }
+ public int read(byte[] a, int off, int length) throws IOException { int n = is.read(a,off,length); return n < 0 ? 0 : n; }
+ public void _close() { try { is.close(); } catch(IOException e) { /*ignore*/ } }
+ public FStat _fstat() { return new FStat(); }
+ }
+
+ protected static class StdinFD extends InputStreamFD {
+ public StdinFD(InputStream is) { super(is); }
+ public void _close() { /* noop */ }
+ public FStat _fstat() { return new FStat() { public int type() { return S_IFCHR; } }; }
+ public boolean isatty() { return true; }
+ }
+ protected static class StdoutFD extends OutputStreamFD {
+ public StdoutFD(OutputStream os) { super(os); }
+ public void _close() { /* noop */ }
+ public FStat _fstat() { return new FStat() { public int type() { return S_IFCHR; } }; }
+ public boolean isatty() { return true; }
+ }
+
+ public static class FStat {
+ public static final int S_IFIFO = 0010000;
+ public static final int S_IFCHR = 0020000;
+ public static final int S_IFDIR = 0040000;
+ public static final int S_IFREG = 0100000;
+
+ public int dev() { return -1; }
+ // FEATURE: inode numbers are calculated inconsistently throught the runtime
+ public int inode() { return hashCode() & 0xfffff; }
+ public int mode() { return 0; }
+ public int type() { return S_IFIFO; }
+ public int nlink() { return 0; }
+ public int uid() { return 0; }
+ public int gid() { return 0; }
+ public int size() { return 0; }
+ public int atime() { return 0; }
+ public int mtime() { return 0; }
+ public int ctime() { return 0; }
+ public int blksize() { return 512; }
+ public int blocks() { return (size()+blksize()-1)/blksize(); }
+ }
+
+ protected static class HostFStat extends FStat {
+ private final File f;
+ private final boolean executable;
+ public HostFStat(File f) {
+ this.f = f;
+ String name = f.getName();
+ // FEATURE: This is ugly.. maybe we should do a file(1) type check
+ executable = name.endsWith(".mips") || name.endsWith(".sh");
+ }
+ public int dev() { return 1; }
+ public int inode() { return f.getName().hashCode() & 0xffff; }
+ public int type() { return f.isDirectory() ? S_IFDIR : S_IFREG; }
+ public int nlink() { return 1; }
+ public int mode() {
+ int mode = 0;
+ boolean canread = f.canRead();
+ if(canread && (executable || f.isDirectory())) mode |= 0111;
+ if(canread) mode |= 0444;
+ if(f.canWrite()) mode |= 0222;
+ return mode;
+ }
+ public int size() { return (int) f.length(); }
+ public int mtime() { return (int)(f.lastModified()/1000); }
+ }
+
+ // Exceptions
+ public class ReadFaultException extends FaultException {
+ public ReadFaultException(int addr) { super(addr); }
+ }
+ public class WriteFaultException extends FaultException {
+ public WriteFaultException(int addr) { super(addr); }
+ }
+ public abstract class FaultException extends ExecutionException {
+ public int addr;
+ public FaultException(int addr) { super("fault at: " + toHex(addr)); this.addr = addr; }
+ }
+ public static class ExecutionException extends Exception {
+ private String message = "(null)";
+ private String location = "(unknown)";
+ public ExecutionException() { /* noop */ }
+ public ExecutionException(String s) { if(s != null) message = s; }
+ void setLocation(String s) { location = s == null ? "(unknown)" : s; }
+ public final String getMessage() { return message + " at " + location; }
+ }
+ public static class CallException extends Exception {
+ public CallException(String s) { super(s); }
+ }
+
+ protected static class ErrnoException extends IOException {
+ public int errno;
+ public ErrnoException(int errno) { super("Errno: " + errno); this.errno = errno; }
+ }
+
+ // CPU State
+ protected static class CPUState {
+ public CPUState() { /* noop */ }
+ /* GPRs */
+ public int[] r = new int[32];
+ /* Floating point regs */
+ public int[] f = new int[32];
+ public int hi, lo;
+ public int fcsr;
+ public int pc;
+ }
+
+ // Null pointer check helper function
+ protected final void nullPointerCheck(int addr) throws ExecutionException {
+ if(TOTAL_PAGES==1 ? addr < 65536 : (addr>>>PAGE_SHIFT) < 16)
+ throw new ExecutionException("Attempted to dereference a null pointer " + toHex(addr));
+ }
+
+ // Utility functions
+ private byte[] byteBuf(int size) {
+ if(_byteBuf==null) _byteBuf = new byte[size];
+ else if(_byteBuf.length < size)
+ _byteBuf = new byte[min(max(_byteBuf.length*2,size),MAX_CHUNK)];
+ return _byteBuf;
+ }
+
+ protected static String getSystemProperty(String key) {
+ try {
+ return System.getProperty(key);
+ } catch(SecurityException e) {
+ return null;
+ }
+ }
+
+ /** Decode an packed string.. FEATURE: document this better */
+ protected static final int[] decodeData(String s, int words) {
+ if(s.length() % 8 != 0) throw new IllegalArgumentException("string length must be a multiple of 8");
+ if((s.length() / 8) * 7 < words*4) throw new IllegalArgumentException("string isn't big enough");
+ int[] buf = new int[words];
+ int prev = 0, left=0;
+ for(int i=0,n=0;n<words;i+=8) {
+ long l = 0;
+ for(int j=0;j<8;j++) { l <<= 7; l |= s.charAt(i+j) & 0x7f; }
+ if(left > 0) buf[n++] = prev | (int)(l>>>(56-left));
+ if(n < words) buf[n++] = (int) (l >>> (24-left));
+ left = (left + 8) & 0x1f;
+ prev = (int)(l << left);
+ }
+ return buf;
+ }
+
+ protected static byte[] getBytes(String s) {
+ try {
+ return s.getBytes("ISO-8859-1");
+ } catch(UnsupportedEncodingException e) {
+ return null; // should never happen
+ }
+ }
+
+ protected final static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); }
+ protected final static int min(int a, int b) { return a < b ? a : b; }
+ protected final static int max(int a, int b) { return a > b ? a : b; }
+}
--- /dev/null
+package org.xwt.mips;
+
+import org.xwt.mips.util.*;
+import java.io.*;
+import java.util.*;
+
+public abstract class UnixRuntime extends Runtime {
+ /** The pid of this "process" */
+ private int pid;
+ private int ppid;
+ protected int getPid() { return pid; }
+
+ /** processes filesystem */
+ private FS fs;
+ public FS getFS() { return fs; }
+ public void setFS(FS fs) {
+ if(state >= RUNNING) throw new IllegalStateException("Can't change fs while process is running");
+ this.fs = fs;
+ }
+
+ /** proceses current working directory */
+ private String cwd;
+
+ /* Static stuff */
+ // FEATURE: Most of this is O(n) or worse - fix it
+ private final Object waitNotification = new Object();
+ private final static int MAX_TASKS = 256;
+ private final static UnixRuntime[] tasks = new UnixRuntime[MAX_TASKS];
+ private static int addTask(UnixRuntime rt) {
+ synchronized(tasks) {
+ for(int i=1;i<MAX_TASKS;i++) {
+ if(tasks[i] == null) {
+ tasks[i] = rt;
+ rt.pid = i;
+ return i;
+ }
+ }
+ return -1;
+ }
+ }
+ private static void removeTask(UnixRuntime rt) {
+ synchronized(tasks) {
+ for(int i=1;i<MAX_TASKS;i++)
+ if(tasks[i] == rt) { tasks[i] = null; break; }
+ }
+ }
+
+ public UnixRuntime(int pageSize, int totalPages, boolean allowEmptyPages) {
+ super(pageSize,totalPages,allowEmptyPages);
+
+ HostFS root = new HostFS();
+ fs = new UnixOverlayFS(root);
+
+ String dir = root.hostCWD();
+ try {
+ chdir(dir == null ? "/" : dir);
+ } catch(FileNotFoundException e) {
+ e.printStackTrace();
+ cwd = "/";
+ }
+ }
+
+ private static String posixTZ() {
+ StringBuffer sb = new StringBuffer();
+ TimeZone zone = TimeZone.getDefault();
+ int off = zone.getRawOffset() / 1000;
+ sb.append(zone.getDisplayName(false,TimeZone.SHORT));
+ if(off > 0) sb.append("-");
+ else off = -off;
+ sb.append(off/3600); off = off%3600;
+ if(off > 0) sb.append(":").append(off/60); off=off%60;
+ if(off > 0) sb.append(":").append(off);
+ if(zone.useDaylightTime())
+ sb.append(zone.getDisplayName(true,TimeZone.SHORT));
+ return sb.toString();
+ }
+
+ private static boolean envHas(String key,String[] environ) {
+ for(int i=0;i<environ.length;i++)
+ if(environ[i]!=null && environ[i].startsWith(key + "=")) return true;
+ return false;
+ }
+
+ protected String[] createEnv(String[] extra) {
+ String[] defaults = new String[5];
+ int n=0;
+ if(extra == null) extra = new String[0];
+ if(!envHas("USER",extra) && getSystemProperty("user.name") != null)
+ defaults[n++] = "USER=" + getSystemProperty("user.name");
+ if(!envHas("HOME",extra) && getSystemProperty("user.name") != null)
+ defaults[n++] = "HOME=" + getSystemProperty("user.home");
+ if(!envHas("SHELL",extra)) defaults[n++] = "SHELL=/bin/sh";
+ if(!envHas("TERM",extra)) defaults[n++] = "TERM=vt100";
+ if(!envHas("TZ",extra)) defaults[n++] = "TZ=" + posixTZ();
+ String[] env = new String[extra.length+n];
+ for(int i=0;i<n;i++) env[i] = defaults[i];
+ for(int i=0;i<extra.length;i++) env[n++] = extra[i];
+ return env;
+ }
+
+ protected void _start() {
+ if(addTask(this) < 0) throw new Error("Task list full");
+ }
+
+ protected void _exit() {
+ synchronized(tasks) {
+ if(ppid == 0) removeTask(this);
+ for(int i=0;i<MAX_TASKS;i++) {
+ if(tasks[i] != null && tasks[i].ppid == pid) {
+ if(tasks[i].state == DONE) removeTask(tasks[i]);
+ else tasks[i].ppid = 0;
+ }
+ }
+ state = DONE;
+ if(ppid != 0) synchronized(tasks[ppid].waitNotification) { tasks[ppid].waitNotification.notify(); }
+ }
+ }
+
+ protected int syscall(int syscall, int a, int b, int c, int d) {
+ switch(syscall) {
+ case SYS_kill: return sys_kill(a,b);
+ case SYS_fork: return sys_fork();
+ case SYS_pipe: return sys_pipe(a);
+ case SYS_dup2: return sys_dup2(a,b);
+ case SYS_waitpid: return sys_waitpid(a,b,c);
+ case SYS_stat: return sys_stat(a,b);
+ case SYS_mkdir: return sys_mkdir(a,b);
+ case SYS_getcwd: return sys_getcwd(a,b);
+ case SYS_chdir: return sys_chdir(a);
+
+ default: return super.syscall(syscall,a,b,c,d);
+ }
+ }
+
+ protected FD open(String path, int flags, int mode) throws IOException { return fs.open(cleanupPath(path),flags,mode); }
+
+ // FEATURE: Allow simple, broken signal delivery to other processes
+ // (check if a signal was delivered before and after syscalls)
+ // FEATURE: Implement raise() in terms of call("raise",...) - kinda cheap, but it keeps the complexity in newlib
+ /** The kill syscall.
+ SIGSTOP, SIGTSTO, SIGTTIN, and SIGTTOUT pause the process.
+ SIGCONT, SIGCHLD, SIGIO, and SIGWINCH are ignored.
+ Anything else terminates the process. */
+ private int sys_kill(int pid, int signal) {
+ // This will only be called by raise() in newlib to invoke the default handler
+ // We don't have to worry about actually delivering the signal
+ if(pid != pid) return -ESRCH;
+ if(signal < 0 || signal >= 32) return -EINVAL;
+ switch(signal) {
+ case 0: return 0;
+ case 17: // SIGSTOP
+ case 18: // SIGTSTP
+ case 21: // SIGTTIN
+ case 22: // SIGTTOU
+ state = PAUSED;
+ break;
+ case 19: // SIGCONT
+ case 20: // SIGCHLD
+ case 23: // SIGIO
+ case 28: // SIGWINCH
+ break;
+ default: {
+ String msg = "Terminating on signal: " + signal + "\n";
+ exitStatus = 1;
+ state = DONE;
+ if(fds[2]==null) {
+ System.out.print(msg);
+ } else {
+ try {
+ byte[] b = getBytes(msg);
+ fds[2].write(b,0,b.length);
+ }
+ catch(IOException e) { /* ignore */ }
+ }
+ }
+ }
+ return 0;
+ }
+
+ private int sys_waitpid(int pid, int statusAddr, int options) {
+ final int WNOHANG = 1;
+ if((options & ~(WNOHANG)) != 0) return -EINVAL;
+ if(pid !=-1 && (pid <= 0 || pid >= MAX_TASKS)) return -ECHILD;
+ for(;;) {
+ synchronized(tasks) {
+ UnixRuntime task = null;
+ if(pid == -1) {
+ for(int i=0;i<MAX_TASKS;i++) {
+ if(tasks[i] != null && tasks[i].ppid == this.pid && tasks[i].state == DONE) {
+ task = tasks[i];
+ break;
+ }
+ }
+ } else if(tasks[pid] != null && tasks[pid].ppid == this.pid && tasks[pid].state == DONE) {
+ task = tasks[pid];
+ }
+
+ if(task != null) {
+ removeTask(task);
+ try {
+ if(statusAddr!=0) memWrite(statusAddr,task.exitStatus()<<8);
+ } catch(FaultException e) {
+ return -EFAULT;
+ }
+
+ return task.pid;
+ }
+ }
+ if((options&WNOHANG)!=0) return 0;
+ synchronized(waitNotification) {
+ try { waitNotification.wait(); } catch(InterruptedException e) { throw new Error(e); }
+ }
+ }
+ }
+
+ // Great ugliness lies within.....
+ private int sys_fork() {
+ CPUState state = getCPUState();
+ int sp = state.r[SP];
+ final UnixRuntime r;
+ try {
+ r = (UnixRuntime) getClass().newInstance();
+ } catch(Exception e) {
+ System.err.println(e);
+ return -ENOMEM;
+ }
+ int child_pid = addTask(r);
+ if(child_pid < 0) return -ENOMEM;
+
+ r.ppid = pid;
+ r.brkAddr = brkAddr;
+ r.fds = new FD[OPEN_MAX];
+ for(int i=0;i<OPEN_MAX;i++) if(fds[i] != null) r.fds[i] = fds[i].dup();
+ r.cwd = cwd;
+ r.fs = fs;
+ for(int i=0;i<TOTAL_PAGES;i++) {
+ if(readPages[i] == null) continue;
+ if(isEmptyPage(writePages[i])) {
+ r.readPages[i] = r.writePages[i] = writePages[i];
+ } else if(writePages[i] != null) {
+ r.readPages[i] = r.writePages[i] = new int[PAGE_WORDS];
+ if(STACK_BOTTOM == 0 || i*PAGE_SIZE < STACK_BOTTOM || i*PAGE_SIZE >= sp-PAGE_SIZE*2)
+ System.arraycopy(writePages[i],0,r.writePages[i],0,PAGE_WORDS);
+ } else {
+ r.readPages[i] = r.readPages[i];
+ }
+ }
+ state.r[V0] = 0;
+ state.pc += 4;
+ r.setCPUState(state);
+ r.state = PAUSED;
+
+ new Thread() {
+ public void run() {
+ try {
+ while(!r.execute());
+ } catch(Exception e) {
+ System.err.println("Forked process threw exception: ");
+ e.printStackTrace();
+ }
+ }
+ }.start();
+
+ return child_pid;
+ }
+
+ private int sys_pipe(int addr) {
+ PipedOutputStream writerStream = new PipedOutputStream();
+ PipedInputStream readerStream;
+ try {
+ readerStream = new PipedInputStream(writerStream);
+ } catch(IOException e) {
+ return -EIO;
+ }
+ FD reader = new InputStreamFD(readerStream);
+ FD writer = new OutputStreamFD(writerStream);
+ int fd1 = addFD(reader);
+ if(fd1 < 0) return -ENFILE;
+ int fd2 = addFD(writer);
+ if(fd2 < 0) { closeFD(fd1); return -ENFILE; }
+ try {
+ memWrite(addr,fd1);
+ memWrite(addr+4,fd2);
+ } catch(FaultException e) {
+ closeFD(fd1);
+ closeFD(fd2);
+ return -EFAULT;
+ }
+ return 0;
+ }
+
+ private int sys_dup2(int oldd, int newd) {
+ if(oldd == newd) return 0;
+ if(oldd < 0 || oldd >= OPEN_MAX) return -EBADFD;
+ if(newd < 0 || newd >= OPEN_MAX) return -EBADFD;
+ if(fds[oldd] == null) return -EBADFD;
+ if(fds[newd] != null) fds[newd].close();
+ fds[newd] = fds[oldd].dup();
+ return 0;
+ }
+
+ private int sys_stat(int cstring, int addr) {
+ try {
+ String path = cleanupPath(cstring(cstring));
+ return stat(fs.stat(path),addr);
+ }
+ catch(ErrnoException e) { return -e.errno; }
+ catch(FileNotFoundException e) {
+ if(e.getMessage() != null && e.getMessage().indexOf("Permission denied") >= 0) return -EACCES;
+ return -ENOENT;
+ }
+ catch(IOException e) { return -EIO; }
+ catch(FaultException e) { return -EFAULT; }
+ }
+
+
+ private int sys_mkdir(int cstring, int mode) {
+ try {
+ fs.mkdir(cleanupPath(cstring(cstring)));
+ return 0;
+ }
+ catch(ErrnoException e) { return -e.errno; }
+ catch(FileNotFoundException e) { return -ENOENT; }
+ catch(IOException e) { return -EIO; }
+ catch(FaultException e) { return -EFAULT; }
+ }
+
+
+ private int sys_getcwd(int addr, int size) {
+ byte[] b = getBytes(cwd);
+ if(size == 0) return -EINVAL;
+ if(size < b.length+1) return -ERANGE;
+ if(!new File(cwd).exists()) return -ENOENT;
+ try {
+ copyout(b,addr,b.length);
+ memset(addr+b.length+1,0,1);
+ return addr;
+ } catch(FaultException e) {
+ return -EFAULT;
+ }
+ }
+
+ private int sys_chdir(int addr) {
+ try {
+ String path = cleanupPath(cstring(addr));
+ System.err.println("Chdir: " + cstring(addr) + " -> " + path + " pwd: " + cwd);
+ if(fs.stat(path).type() != FStat.S_IFDIR) return -ENOTDIR;
+ cwd = path;
+ System.err.println("Now: " + cwd);
+ return 0;
+ }
+ catch(ErrnoException e) { return -e.errno; }
+ catch(FileNotFoundException e) { return -ENOENT; }
+ catch(IOException e) { return -EIO; }
+ catch(FaultException e) { return -EFAULT; }
+ }
+
+ public void chdir(String dir) throws FileNotFoundException {
+ if(state >= RUNNING) throw new IllegalStateException("Can't chdir while process is running");
+ try {
+ dir = cleanupPath(dir);
+ if(fs.stat(dir).type() != FStat.S_IFDIR) throw new FileNotFoundException();
+ } catch(IOException e) {
+ throw new FileNotFoundException();
+ }
+ cwd = dir;
+ }
+
+ public abstract static class FS {
+ public FD open(String path, int flags, int mode) throws IOException { throw new FileNotFoundException(); }
+ public FStat stat(String path) throws IOException { throw new FileNotFoundException(); }
+ public void mkdir(String path) throws IOException { throw new ErrnoException(ENOTDIR); }
+
+ public static FD directoryFD(String[] files, int hashCode) throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(bos);
+ for(int i=0;i<files.length;i++) {
+ byte[] b = getBytes(files[i]);
+ int inode = (files[i].hashCode() ^ hashCode) & 0xfffff;
+ dos.writeInt(inode);
+ dos.writeInt(b.length);
+ dos.write(b,0,b.length);
+ }
+ final byte[] data = bos.toByteArray();
+ return new SeekableFD(new SeekableByteArray(data,false),RD_ONLY) {
+ protected FStat _fstat() { return new FStat() {
+ public int length() { return data.length; }
+ public int type() { return S_IFDIR; }
+ }; }
+ };
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ UnixRuntime rt = new Interpreter();
+ rt.cwd = getSystemProperty("user.dir");
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ String line;
+ while((line = br.readLine()) != null) {
+ System.out.println("[" + rt.cleanupPath(line) + "]");
+ }
+ }
+
+
+ private static boolean needsCleanup(String path) {
+ if(path.indexOf("//") != -1) return true;
+ if(path.indexOf('.') != -1) {
+ if(path.length() == 1) return true;
+ if(path.equals("..")) return true;
+ if(path.startsWith("./") || path.indexOf("/./") != -1 || path.endsWith("/.")) return true;
+ if(path.startsWith("../") || path.indexOf("/../") != -1 || path.endsWith("/..")) return true;
+ }
+ return false;
+ }
+
+ // FIXME: This is probably still buggy
+ // FEATURE: Remove some of the "should never happen checks"
+ protected String cleanupPath(String p) throws ErrnoException {
+ if(p.length() == 0) throw new ErrnoException(ENOENT);
+ if(needsCleanup(p)) {
+ char[] in = p.toCharArray();
+ char[] out;
+ int outp ;
+ if(in[0] == '/') {
+ out = new char[in.length];
+ outp = 0;
+ } else {
+ out = new char[cwd.length() + in.length + 1];
+ outp = cwd.length();
+ for(int i=0;i<outp;i++) out[i] = cwd.charAt(i);
+ if(outp == 0 || out[0] != '/') throw new Error("should never happen");
+ }
+ int inLength = in.length;
+ int inp = 0;
+ while(inp<inLength) {
+ if(inp == 0 || in[inp] == '/') {
+ while(inp < inLength && in[inp] == '/') inp++;
+ if(inp == inLength) break;
+ if(in[inp] == '.') {
+ if(inp+1 == inLength) break;
+ if(in[inp+1] == '.' && (inp+2 == inLength || in[inp+2] == '/')) {
+ inp+=2;
+ if(outp == 0) continue;
+ do { outp--; } while(outp > 0 && out[outp] != '/');
+ } else if(in[inp+1] == '/') {
+ inp++;
+ } else {
+ out[outp++] = '/';
+ }
+ } else {
+ out[outp++] = '/';
+ out[outp++] = in[inp++];
+ }
+ } else {
+ out[outp++] = in[inp++];
+ }
+ }
+ if(outp == 0) out[outp++] = '/';
+ return new String(out,0,outp);
+ } else {
+ if(p.startsWith("/")) return p;
+ StringBuffer sb = new StringBuffer(cwd);
+ if(!cwd.equals("/")) sb.append('/');
+ return sb.append(p).toString();
+ }
+ }
+
+ // FEATURE: Probably should make this more general - support mountpoints, etc
+ public class UnixOverlayFS extends FS {
+ private final FS root;
+ private final FS dev = new DevFS();
+ public UnixOverlayFS(FS root) {
+ this.root = root;
+ }
+ private String devPath(String path) {
+ if(path.startsWith("/dev")) {
+ if(path.length() == 4) return "/";
+ if(path.charAt(4) == '/') return path.substring(4);
+ }
+ return null;
+ }
+ public FD open(String path, int flags, int mode) throws IOException{
+ String dp = devPath(path);
+ return dp == null ? root.open(path,flags,mode) : dev.open(dp,flags,mode);
+ }
+ public FStat stat(String path) throws IOException {
+ String dp = devPath(path);
+ return dp == null ? root.stat(path) : dev.stat(dp);
+ }
+ public void mkdir(String path) throws IOException {
+ String dp = devPath(path);
+ if(dp == null) root.mkdir(path);
+ else dev.mkdir(dp);
+ }
+ }
+
+ // FIXME: This is totally broken on non-unix hosts - need to do some kind of cygwin type mapping
+ public static class HostFS extends FS {
+ public static String fixPath(String path) throws FileNotFoundException {
+ return path;
+ }
+
+ public String hostCWD() {
+ return getSystemProperty("user.dir");
+ }
+
+ // FEATURE: This shares a lot with Runtime.open
+ public FD open(String path, int flags, int mode) throws IOException {
+ path = fixPath(path);
+ final File f = new File(path);
+ // NOTE: createNewFile is a Java2 function
+ if((flags & (O_EXCL|O_CREAT)) == (O_EXCL|O_CREAT))
+ if(!f.createNewFile()) throw new ErrnoException(EEXIST);
+ if(!f.exists() && (flags&O_CREAT) == 0) return null;
+ if(f.isDirectory()) {
+ if((flags&3)!=RD_ONLY) throw new ErrnoException(EACCES);
+ return directoryFD(f.list(),path.hashCode());
+ }
+ final SeekableFile sf = new SeekableFile(path,(flags&3)!=RD_ONLY);
+ if((flags&O_TRUNC)!=0) sf.setLength(0);
+ return new SeekableFD(sf,mode) {
+ protected FStat _fstat() { return new HostFStat(f) {
+ public int size() {
+ try { return sf.length(); } catch(IOException e) { return 0; }
+ }
+ };}
+ };
+ }
+
+ public FStat stat(String path) throws FileNotFoundException {
+ File f = new File(fixPath(path));
+ if(!f.exists()) throw new FileNotFoundException();
+ return new HostFStat(f);
+ }
+
+ public void mkdir(String path) throws IOException {
+ File f = new File(fixPath(path));
+ if(f.exists() && f.isDirectory()) throw new ErrnoException(EEXIST);
+ if(f.exists()) throw new ErrnoException(ENOTDIR);
+ File parent = f.getParentFile();
+ if(parent!=null && (!parent.exists() || !parent.isDirectory())) throw new ErrnoException(ENOTDIR);
+ if(!f.mkdir()) throw new ErrnoException(EIO);
+ }
+ }
+
+ private static class DevFStat extends FStat {
+ public int dev() { return 1; }
+ public int mode() { return 0666; }
+ public int type() { return S_IFCHR; }
+ public int nlink() { return 1; }
+ }
+ private static FD devZeroFD = new FD() {
+ public boolean readable() { return true; }
+ public boolean writable() { return true; }
+ public int read(byte[] a, int off, int length) { Arrays.fill(a,off,off+length,(byte)0); return length; }
+ public int write(byte[] a, int off, int length) { return length; }
+ public int seek(int n, int whence) { return 0; }
+ public FStat _fstat() { return new DevFStat(); }
+ };
+ private static FD devNullFD = new FD() {
+ public boolean readable() { return true; }
+ public boolean writable() { return true; }
+ public int read(byte[] a, int off, int length) { return 0; }
+ public int write(byte[] a, int off, int length) { return length; }
+ public int seek(int n, int whence) { return 0; }
+ public FStat _fstat() { return new DevFStat(); }
+ };
+
+ public class DevFS extends FS {
+ public FD open(String path, int mode, int flags) throws IOException {
+ if(path.equals("/null")) return devNullFD;
+ if(path.equals("/zero")) return devZeroFD;
+ if(path.startsWith("/fd/")) {
+ int n;
+ try {
+ n = Integer.parseInt(path.substring(4));
+ } catch(NumberFormatException e) {
+ throw new FileNotFoundException();
+ }
+ if(n < 0 || n >= OPEN_MAX) throw new FileNotFoundException();
+ if(fds[n] == null) throw new FileNotFoundException();
+ return fds[n].dup();
+ }
+ if(path.equals("/fd")) {
+ int count=0;
+ for(int i=0;i<OPEN_MAX;i++) if(fds[i] != null) count++;
+ String[] files = new String[count];
+ count = 0;
+ for(int i=0;i<OPEN_MAX;i++) if(fds[i] != null) files[count++] = Integer.toString(i);
+ return directoryFD(files,hashCode());
+ }
+ if(path.equals("/")) {
+ String[] files = { "null", "zero", "fd" };
+ return directoryFD(files,hashCode());
+ }
+ throw new FileNotFoundException();
+ }
+
+ public FStat stat(String path) throws IOException {
+ if(path.equals("/null")) return devNullFD.fstat();
+ if(path.equals("/zero")) return devZeroFD.fstat();
+ if(path.startsWith("/fd/")) {
+ int n;
+ try {
+ n = Integer.parseInt(path.substring(4));
+ } catch(NumberFormatException e) {
+ throw new FileNotFoundException();
+ }
+ if(n < 0 || n >= OPEN_MAX) throw new FileNotFoundException();
+ if(fds[n] == null) throw new FileNotFoundException();
+ return fds[n].fstat();
+ }
+ if(path.equals("/fd")) return new FStat() { public int type() { return S_IFDIR; } public int mode() { return 0444; }};
+ if(path.equals("/")) return new FStat() { public int type() { return S_IFDIR; } public int mode() { return 0444; }};
+ throw new FileNotFoundException();
+ }
+
+ public void mkdir(String path) throws IOException { throw new ErrnoException(EACCES); }
+ }
+}
--- /dev/null
+#include <stddef.h>
+
+extern int _gp[];
+
+extern int main(int argc, char **argv, char **envp);
+extern void exit(int status);
+extern int atexit(void (*f)());
+
+/* For constuctors/destructors */
+extern void _init();
+extern void _fini();
+
+char **environ;
+
+void _start(char **argv, char **environ_) {
+ int argc;
+
+ environ = environ_;
+
+ /* Call global constructors */
+ _init();
+
+ /* Register _fini() to be called on exit */
+ atexit(_fini);
+
+ /* Count the arguments */
+ for(argc=0;argv[argc];argc++);
+
+ /* Call main and exit */
+ exit(main(argc,argv,environ));
+}
--- /dev/null
+ENTRY(_start)
+INPUT(support.o support_aux.o)
+GROUP(-lc -lgcc)
+/*GROUP(-lgcc)*/
+__DYNAMIC = 0;
+
+SECTIONS {
+ . = 0x10000;
+ .text : {
+ KEEP(*(.init))
+ KEEP(*(.fini))
+ KEEP(*(.text))
+ *(.text.*)
+ *(.gnu.linkonce.t*)
+ }
+
+ _etext = .;
+
+ .ctors :
+ {
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+
+ . = ALIGN(4k);
+
+ .rodata : {
+ *(.rodata*) *(.gnu.linkonce.r*)
+ *(.gcc_except_table)
+ KEEP(*(.eh_frame)) KEEP(*(.jcr))
+ }
+
+ .data : {
+ *(.data*) *(.gnu.linkonce.d*)
+ }
+
+ . = ALIGN(16);
+ _gp = . + 0x8000;
+ .sdata : {
+ *(.rosdata*) *(.sdata*) *(.gnu.linkonce.s*)
+ }
+ .sbss : {
+ *(.sbss*) *(.scommon*)
+ }
+ .bss : {
+ *(.bss*) *(.gnu.linkonce.b*) *(COMMON)
+ }
+
+ _end = .;
+}
--- /dev/null
+#include "syscalls.h"
+
+#define zero $0
+#define v0 $2
+#define v1 $3
+#define a0 $4
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define t0 $8
+#define t1 $9
+#define ra $31
+
+/* We intentionally don't take advantage of delay slots because
+ the compiler removes them anyway */
+
+.set noreorder;
+
+#define SYSCALL(name) SYSCALL2(name,SYS_##name)
+#define SYSCALL2(name,number) \
+ .section .text.name,"ax",@progbits; \
+ .align 2; \
+ .globl name; \
+ .ent name; \
+name: \
+ li v0, number; \
+ syscall; \
+ j ra; \
+ nop; \
+ .end name;
+
+#define SYSCALL_R(name) \
+ .section .text._##name##_r,"ax",@progbits; \
+ .align 2; \
+ .globl _##name##_r; \
+ .ent _##name##_r; \
+_##name##_r: \
+ li v0, SYS_##name; \
+ move t0, a0; \
+ move a0, a1; \
+ move a1, a2; \
+ move a2, a3; \
+ syscall; \
+ addu t1,v0,255; \
+ sltu t1,t1,255; \
+ bne t1,zero,$L##name##_errno;\
+ nop; \
+ j ra; \
+ nop; \
+$L##name##_errno: \
+ move a0, t0; \
+ move a1, v0; \
+ j _syscall_set_errno; \
+ nop; \
+ .end _##name##_r;
+
+
+ .align 2
+ .globl _call_helper
+ .ent _call_helper
+_call_helper:
+ subu $sp,$sp,32
+
+ /* addr */
+ move $2,$4
+
+ /* args 1-4 */
+ move $4,$5
+ move $5,$6
+ move $6,$7
+ move $7,$16
+
+ /* args 5 and 6 */
+ sw $17,16($sp)
+ sw $18,20($sp)
+
+ /* call the func */
+ jal $31,$2
+ nop
+
+ move $3,$2
+ li $2,SYS_pause
+ syscall
+
+ /* shouldn't get here */
+ li $2,SYS_exit
+ li $3,1
+ syscall
+
+ .end _call_helper
+
+SYSCALL2(_exit,SYS_exit)
+SYSCALL2(_pause,SYS_pause)
+SYSCALL_R(open)
+SYSCALL_R(close)
+SYSCALL_R(read)
+SYSCALL_R(write)
+SYSCALL_R(sbrk)
+SYSCALL_R(fstat)
+SYSCALL(isatty)
+SYSCALL_R(lseek)
+SYSCALL_R(kill)
+SYSCALL_R(getpid)
+SYSCALL2(_call_java,SYS_calljava)
+SYSCALL_R(stat)
+SYSCALL_R(gettimeofday)
+SYSCALL(sleep)
+SYSCALL_R(times)
+SYSCALL_R(mkdir)
+SYSCALL(getpagesize)
+SYSCALL_R(unlink)
+SYSCALL_R(utime)
+SYSCALL_R(chdir)
+SYSCALL_R(pipe)
+SYSCALL_R(dup2)
+SYSCALL_R(fork)
+SYSCALL_R(waitpid)
+SYSCALL_R(getcwd)
+SYSCALL_R(execve)
+SYSCALL_R(fcntl)
+SYSCALL_R(rmdir)
+SYSCALL_R(sysconf)
--- /dev/null
+#include <sys/stat.h>
+#include <sys/dirent.h>
+#include <sys/types.h>
+#include <utime.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int _syscall_set_errno(struct _reent *ptr, int err) {
+ ptr->_errno = -err;
+ return -1;
+}
+
+extern int _stat_r(struct _reent *ptr, const char *path, struct stat *sb);
+int _lstat_r(struct _reent *ptr, const char *path, struct stat *sb) {
+ return _stat_r(ptr,path,sb);
+}
+
+uid_t getuid() { return 0; }
+gid_t getgid() { return 0; }
+uid_t geteuid() { return 0; }
+gid_t getegid() { return 0; }
+int getgroups(int gidsetlen, gid_t *gidset) {
+ if(gidsetlen) *gidset = 0;
+ return 1;
+}
+mode_t umask(mode_t new) { return 0022; }
+
+static int syscall_nosys(struct _reent *ptr) {
+ ptr->_errno = ENOSYS;
+ return -1;
+}
+
+int _access_r(struct _reent *ptr, const char *pathname, int mode) {
+ struct stat statbuf;
+ if(_stat_r(ptr,pathname,&statbuf) < 0) return -1;
+ return 0;
+}
+
+/* FIXME: These should be in newlib */
+int access(const char *pathname, int mode) { return _access_r(_REENT,pathname,mode); }
+extern int _rmdir_r(struct _reent *ptr, const char *pathname);
+int rmdir(const char *pathname) { return _rmdir_r(_REENT,pathname); }
+extern long _sysconf_r(struct _reent *ptr, int n);
+long sysconf(int n) { return _sysconf_r(_REENT,n); }
+
+#define SYSCALL_NOSYS_R(name) int _##name##_r(struct _reent *ptr) { return syscall_nosys(ptr); }
+
+SYSCALL_NOSYS_R(link)
+SYSCALL_NOSYS_R(symlink)
+SYSCALL_NOSYS_R(readlink)
+SYSCALL_NOSYS_R(chown)
+SYSCALL_NOSYS_R(fchown)
+SYSCALL_NOSYS_R(chmod)
+SYSCALL_NOSYS_R(fchmod)
+
+static int read_fully(int fd, void *buf, size_t size) {
+ int n;
+ while(size) {
+ n = read(fd,buf,size);
+ if(n <= 0) return -1;
+ size -= n;
+ buf += n;
+ }
+ return 0;
+}
+
+DIR *opendir(const char *path) {
+ struct stat sb;
+ int fd;
+ DIR *dir;
+
+ fd = open(path,O_RDONLY);
+ if(fd < 0) return NULL;
+
+ if(fstat(fd,&sb) < 0 || !S_ISDIR(sb.st_mode)) {
+ close(fd);
+ errno = ENOTDIR;
+ return NULL;
+ }
+
+ dir = malloc(sizeof(*dir));
+ if(dir == NULL) {
+ close(fd);
+ errno = ENOMEM;
+ return NULL;
+ }
+ dir->dd_fd = fd;
+ dir->dd_pos = 0;
+ return dir;
+}
+
+static int readdir_r(DIR *dir,struct dirent *entry, struct dirent **result) {
+ struct {
+ int inode;
+ int name_len;
+ } h;
+ if(dir->dd_fd < 0) return -1;
+again:
+ if(read_fully(dir->dd_fd,&h,sizeof(h)) < 0) goto fail;
+ if(h.name_len < 0 || h.name_len >= sizeof(entry->d_name)-1) goto fail;
+
+ entry->d_ino = h.inode;
+ if(read_fully(dir->dd_fd,entry->d_name,h.name_len) < 0) goto fail;
+
+ entry->d_name[h.name_len] = '\0';
+ dir->dd_pos += h.name_len + 8;
+
+ if(result) *result = entry;
+ return 0;
+fail:
+ if(result) *result = NULL;
+ return -1;
+}
+
+struct dirent *readdir(DIR *dir) { return readdir_r(dir,&dir->ent,NULL) == 0 ? &dir->ent : NULL; }
+
+int closedir(DIR *dir) {
+ close(dir->dd_fd);
+ free(dir);
+ return 0;
+}
--- /dev/null
+#define SYS_null 0
+#define SYS_exit 1
+#define SYS_pause 2
+#define SYS_open 3
+#define SYS_close 4
+#define SYS_read 5
+#define SYS_write 6
+#define SYS_sbrk 7
+#define SYS_fstat 8
+#define SYS_isatty 9
+#define SYS_lseek 10
+#define SYS_kill 11
+#define SYS_getpid 12
+#define SYS_calljava 13
+#define SYS_stat 14
+#define SYS_gettimeofday 15
+#define SYS_sleep 16
+#define SYS_times 17
+#define SYS_mkdir 18
+#define SYS_getpagesize 19
+#define SYS_unlink 20
+#define SYS_utime 21
+#define SYS_chdir 22
+#define SYS_pipe 23
+#define SYS_dup2 24
+#define SYS_fork 25
+#define SYS_waitpid 26
+#define SYS_getcwd 27
+#define SYS_execve 28
+#define SYS_fcntl 29
+#define SYS_rmdir 30
+#define SYS_sysconf 31
--- /dev/null
+package org.xwt.mips.util;
+
+import java.io.IOException;
+
+public class SeekableByteArray implements SeekableData {
+ protected byte[] data;
+ protected int pos;
+ private final boolean writable;
+
+ public SeekableByteArray(byte[] data, boolean writable) {
+ this.data = data;
+ this.pos = 0;
+ this.writable = writable;
+ }
+
+ public int read(byte[] buf, int off, int len) {
+ len = Math.min(len,data.length-pos);
+ if(len <= 0) return -1;
+ System.arraycopy(data,pos,buf,off,len);
+ pos += len;
+ return len;
+ }
+
+ public int write(byte[] buf, int off, int len) throws IOException {
+ if(!writable) throw new IOException("read-only data");
+ len = Math.min(len,data.length-pos);
+ if(len <= 0) throw new IOException("no space");
+ System.arraycopy(buf,off,data,pos,len);
+ pos += len;
+ return len;
+ }
+
+ public int length() { return data.length; }
+ public int pos() { return pos; }
+ public void seek(int pos) { this.pos = pos; }
+ public void close() { /*noop*/ }
+}
--- /dev/null
+package org.xwt.mips.util;
+
+import java.io.IOException;
+
+public interface SeekableData {
+ public int read(byte[] buf, int offset, int length) throws IOException;
+ public int write(byte[] buf, int offset, int length) throws IOException;
+ public int length() throws IOException;
+ public void seek(int pos) throws IOException;
+ public void close() throws IOException;
+ public int pos() throws IOException;
+}
--- /dev/null
+package org.xwt.mips.util;
+
+import java.io.*;
+
+public class SeekableFile implements SeekableData {
+ private final RandomAccessFile raf;
+
+ public SeekableFile(String fileName) throws IOException { this(fileName,false); }
+ public SeekableFile(String fileName, boolean writable) throws IOException { this(new File(fileName),writable); }
+
+ public SeekableFile(File file, boolean writable) throws IOException {
+ raf = new RandomAccessFile(file,writable ? "rw" : "r");
+ }
+
+ // NOTE: RandomAccessFile.setLength() is a Java2 function
+ public void setLength(int n) throws IOException { raf.setLength(n); }
+
+ public int read(byte[] buf, int offset, int length) throws IOException { return raf.read(buf,offset,length); }
+ public int write(byte[] buf, int offset, int length) throws IOException { raf.write(buf,offset,length); return length; }
+ public void seek(int pos) throws IOException{ raf.seek(pos); }
+ public int pos() throws IOException { return (int) raf.getFilePointer(); }
+ public int length() throws IOException { return (int)raf.length(); }
+ public void close() throws IOException { raf.close(); }
+}
--- /dev/null
+package org.xwt.mips.util;
+
+import java.io.*;
+
+public class SeekableInputStream implements SeekableData {
+ private byte[] buffer = new byte[4096];
+ private int bytesRead = 0;
+ private boolean eof = false;
+ private int pos;
+ private InputStream is;
+
+ public SeekableInputStream(InputStream is) { this.is = is; }
+
+ public int read(byte[] outbuf, int off, int len) throws IOException {
+ if(pos >= bytesRead && !eof) readTo(pos + 1);
+ len = Math.min(len,bytesRead-pos);
+ if(len <= 0) return -1;
+ System.arraycopy(buffer,pos,outbuf,off,len);
+ pos += len;
+ return len;
+ }
+
+ private void readTo(int target) throws IOException {
+ if(target >= buffer.length) {
+ byte[] buf2 = new byte[Math.max(buffer.length+Math.min(buffer.length,65536),target)];
+ System.arraycopy(buffer,0,buf2,0,bytesRead);
+ buffer = buf2;
+ }
+ while(bytesRead < target) {
+ int n = is.read(buffer,bytesRead,buffer.length-bytesRead);
+ if(n == -1) {
+ eof = true;
+ break;
+ }
+ bytesRead += n;
+ }
+ }
+
+ public int length() throws IOException {
+ while(!eof) readTo(bytesRead+4096);
+ return bytesRead;
+ }
+
+ public int write(byte[] buf, int off, int len) throws IOException { throw new IOException("read-only"); }
+ public void seek(int pos) { this.pos = pos; }
+ public int pos() { return pos; }
+ public void close() throws IOException { is.close(); }
+}
--- /dev/null
+#include <iostream>
+
+using namespace std;
+
+class Test {
+public:
+ Test();
+ ~Test();
+ void sayhi();
+};
+
+class Exn {
+public:
+ Exn() { }
+};
+
+
+Test test;
+
+int main(int argc,char *argv[]) {
+ printf("Name: %p\n",typeid(const char*).name());
+ printf("Name: %s\n",typeid(const char*).name());
+ printf("Is pointer: %d\n",typeid(const char*).__is_pointer_p ());
+ printf("Name: %p\n",typeid(int).name());
+ printf("Name: %s\n",typeid(int).name());
+ printf("Is pointer: %d\n",typeid(int).__is_pointer_p ());
+
+ try {
+ test.sayhi();
+ } catch(char *e) {
+ printf("sayhi threw: %s\n",e);
+ } catch(const char *e) {
+ printf("sayhi threw: const char *:%s\n",e);
+ } catch(int n) {
+ printf("sayhi threw: %d\n",n);
+ }
+ return 0;
+}
+
+Test::Test() {
+ cout << "Test's constructor" << endl;
+}
+
+Test::~Test() {
+ cout << "Test's destructor" << endl;
+}
+
+void Test::sayhi() {
+ static char exn[] = "Non-const!";
+ cout << "Hello, World from Test" << endl;
+ cout << "Now throwing an exception" << endl;
+ throw "Hello, Exception Handling!";
+ //throw exn;
+}
--- /dev/null
+package tests;
+
+import org.xwt.mips.Runtime;
+import org.xwt.mips.Interpreter;
+import java.io.*;
+import java.util.*;
+
+public class CallTest {
+ public static void main(String[] args) throws Exception {
+ int a1 = args.length > 0 ? Integer.parseInt(args[0]) : 0;
+ int a2 = args.length > 1 ? Integer.parseInt(args[1]) : 0;
+ int a3 = args.length > 2 ? Integer.parseInt(args[2]) : 0;
+ int a4 = args.length > 3 ? Integer.parseInt(args[3]) : 0;
+ int a5 = args.length > 4 ? Integer.parseInt(args[4]) : 0;
+ int a6 = args.length > 5 ? Integer.parseInt(args[5]) : 0;
+
+ System.out.println("Version is: " + System.getProperty("os.version"));
+ Runtime rt;
+ if(a1 == 99) // yeah.. this is ugly
+ rt = new Interpreter("build/tests/Test.mips");
+ else
+ rt = new Test() {
+ protected int callJava(int a, int b, int c, int d) {
+ switch(a) {
+ case 1: return strdup("OS: " + System.getProperty("os.name"));
+ case 2: return strdup(System.getProperty("os.version"));
+ case 3: return strdup(new Date().toString());
+ case 4: return allocFDEnt(new OutputStreamFD(new CustomOS()));
+ case 5:
+ System.out.println("In callJava() in Java");
+ try { call("backinmips"); } catch(CallException e) { }
+ System.out.println("Back in callJava() in Java");
+ return 0;
+ default: return super.callJava(a,b,c,d);
+ }
+ }
+ };
+ System.out.println("Runtime: " + rt);
+
+ rt.start(new String[]{"Test","calltest"});
+ rt.execute();
+
+ System.out.println("== Start of CallTest ==");
+ System.out.println("Back in java... calling callme()");
+ int ret = rt.call("callme",a1,a2,a3,a4,a5,a6);
+ System.out.println("callme returned: " + ret);
+
+ int addr = rt.strdup("Hello, World from java");
+ rt.call("echo",addr,4);
+ rt.free(addr);
+ System.out.println("== End of CallTest ==");
+
+ rt.execute();
+ System.exit(rt.exitStatus());
+ }
+
+ private static class CustomOS extends OutputStream {
+ public CustomOS() { }
+ public void write(int b) { byte[] a = new byte[1]; a[0] = (byte)(b&0xff); write(a,0,1); }
+ public void write(byte[] b, int off, int len) {
+ int len2 = len;
+ while(b[len2-1]=='\n') len2--;
+ System.out.println("This just in from MIPS: " + new String(b,off,len2));
+ }
+ }
+}
--- /dev/null
+package tests;
+
+import java.net.*;
+
+import org.xwt.mips.Runtime;
+
+public class Echo {
+ private static final int PORT = 2000;
+ public static void main(String[] args) throws Exception {
+ ServerSocket sock = new ServerSocket(PORT);
+ System.err.println("Listening on " + PORT);
+ for(;;) new Client(sock.accept()).go();
+ }
+
+ private static class Client implements Runnable {
+ private Socket sock;
+ public Client(Socket sock) { this.sock = sock; }
+ public void go() { new Thread(this).start(); }
+ public void run() {
+ try {
+ Runtime task = new EchoHelper();
+ int status = task.run(
+ new String[]{"EchoHelper"},
+ null,
+ new Runtime.InputStreamFD(sock.getInputStream()),
+ new Runtime.OutputStreamFD(sock.getOutputStream()),
+ null
+ );
+ System.err.println("Exit status: " + status);
+ } catch(Exception e) {
+ System.err.println(e);
+ }
+ }
+ }
+}
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+
+int main() {
+ char buf[1024];
+ char *p;
+ printf("Hello! Welcome to EchoHelper.c\n");
+ while(fgets(buf,sizeof(buf),stdin) != NULL) {
+ for(p=buf;*p && *p!='\n' && *p!='\r';p++);
+ *p = '\0';
+ fprintf(stdout,"You said: %s\n",buf);
+ fprintf(stderr,"They said: %s\n",buf);
+ if(strcmp(buf,"exit")==0) break;
+ }
+ return 0;
+}
--- /dev/null
+package tests;
+
+import org.xwt.mips.Runtime;
+import org.xwt.mips.Interpreter;
+
+class Env {
+ public static void main(String[] args) throws Exception {
+ int n = 0;
+ while(n < args.length && args[n].indexOf("=") != -1) n++;
+
+ if(n==args.length) {
+ System.err.println("Usage: Env [name=value ...] classname [args ...]");
+ System.exit(1);
+ }
+
+ String[] env = new String[n];
+ String[] appArgs = new String[args.length-n-1];
+ for(int i=0;i<n;i++) env[i] = args[i];
+ String className = args[n];
+ for(int i=n+1;i<args.length;i++) appArgs[i-n-1] = args[i];
+
+ Runtime rt;
+ if(className.endsWith(".mips")) {
+ rt = new Interpreter(className);
+ } else {
+ Class c = Class.forName(className);
+ if(!Runtime.class.isAssignableFrom(c)) { System.err.println(className + " isn't a MIPS compiled class"); System.exit(1); }
+ rt = (Runtime) c.newInstance();
+ }
+ System.exit(rt.run(appArgs,env));
+ }
+}
--- /dev/null
+package tests;
+
+import org.xwt.mips.Runtime;
+
+public class FDTest {
+ public static void main(String[] args) throws Exception {
+ Runtime rt = new Test();
+ int fd = rt.allocFDEnt(new Runtime.SeekableInputStreamFD(System.in));
+ int status = rt.run(new String[]{"test","fdtest","/dev/fd/" + fd});
+ System.err.println("Exit status: " + status);
+ }
+}
+
+
+
\ No newline at end of file
--- /dev/null
+#include <stdio.h>
+#include <freetype/freetype.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#define FT_Check(expr) do { \
+ if((expr) != 0) { \
+ fprintf(stderr,#expr " failed\n"); \
+ exit(EXIT_FAILURE); \
+ } \
+} while(0)
+
+#define BMP_WIDTH 800
+#define BMP_HEIGHT 600
+
+static char buf[BMP_WIDTH*BMP_HEIGHT];
+
+int main(int argc, char **argv) {
+ char *ttf;
+ char *out;
+ FT_Library library;
+ FT_Face face;
+ FT_GlyphSlot glyph;
+ int num_glyphs;
+ int c;
+ int glyph_index;
+ int loc_x;
+ int loc_y;
+ int glyph_width;
+ int glyph_height;
+ int i,j;
+ int fd;
+ char *p;
+ int n,count;
+ char *glyph_buf;
+ int pixel_size;
+
+ if(argc < 3) {
+ fprintf(stderr,"Usage: %s ttf bmp\n",argv[0]);
+ exit(1);
+ }
+
+ ttf = argv[1];
+ out = argv[2];
+
+ memset(buf,'\377',BMP_WIDTH*BMP_HEIGHT);
+
+ FT_Check(FT_Init_FreeType(&library));
+ FT_Check(FT_New_Face(library,ttf,0,&face));
+
+ loc_y = loc_x = 0;
+ for(pixel_size=8;pixel_size<48;pixel_size+=4) {
+ FT_Check(FT_Set_Pixel_Sizes(face,0,pixel_size));
+ for(c=32;c<127;c++) {
+ glyph_index = FT_Get_Char_Index(face,c);
+ FT_Check(FT_Load_Glyph(face,glyph_index,FT_LOAD_DEFAULT));
+ FT_Check(FT_Render_Glyph(face->glyph, ft_render_mode_normal));
+ glyph = face->glyph;
+ glyph_width = glyph->bitmap.width;
+ glyph_height = glyph->bitmap.rows;
+ glyph_buf = glyph->bitmap.buffer;
+ if(loc_x + glyph_width + glyph->bitmap_left >= BMP_WIDTH) {
+ loc_x = 0;
+ loc_y += pixel_size;
+ if(loc_y >= BMP_HEIGHT-pixel_size) goto done;
+ }
+
+ for(i=0;i<glyph_height;i++)
+ for(j=0;j<glyph_width;j++)
+ buf[(loc_y+i)*BMP_WIDTH+loc_x+j] &= (~glyph_buf[i*glyph_width+j]);
+ loc_x += face->glyph->advance.x/64;
+ }
+ }
+done:
+
+ if((fd = open(out,O_CREAT|O_WRONLY,0644)) < 0) {
+ perror("open");
+ exit(1);
+ }
+ p = buf;
+ count = BMP_WIDTH*BMP_HEIGHT;
+
+ while(count) {
+ n = write(fd,p,count);
+ if(n < 0) {
+ perror("write");
+ exit(1);
+ }
+ count -=n;
+ p += n;
+ }
+ close(fd);
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+
+int main() {
+ fprintf(stderr,"In the main process (pid: %d), about to fork\n",getpid());
+ pid_t pid = fork();
+ int status;
+ int i;
+
+ switch(pid) {
+ case -1: perror("fork"); break;
+ case 0:
+ fprintf(stderr,"In the forked process (pid: %d), sleeping for 2 sec\n",getpid());
+ sleep(2);
+ fprintf(stderr,"Child done sleeping... exiting\n");
+ _exit(0);
+ break;
+ default:
+ fprintf(stderr,"In the main process (child is: %d) waiting for child\n",pid);
+ if(waitpid(pid,&status,0) < 0)
+ perror("waitpid");
+ else
+ fprintf(stderr,"Child process exited (status: %d)\n",status);
+ }
+
+ pid = fork();
+ if(pid==0) {
+ fprintf(stderr,"1st fork (pid: %d)\n",getpid());
+ if(fork()==0) {
+ fprintf(stderr,"2nd fork (pid: %d).. sleeping\n",getpid());
+ sleep(5);
+ fprintf(stderr,"2nd fork exiting\n");
+ _exit(0);
+ }
+ _exit(0);
+ } else {
+ waitpid(pid,NULL,0);
+ fprintf(stderr,"1st fork terminated\n");
+ }
+ fprintf(stderr,"Sleeping for a bit\n");
+ sleep(10);
+ fprintf(stderr,"Next few pids should be sequential\n");
+ for(i=0;i<10;i++) {
+ if(fork() == 0) {
+ fprintf(stderr,"I am a child %d\n",getpid());
+ sleep(i%4);
+ _exit(0);
+ }
+ }
+ for(i=0;i<10;i++) fprintf(stderr,"Waited on %d\n",waitpid(-1,NULL,0));
+
+ return 0;
+}
--- /dev/null
+package tests;
+
+import org.xwt.mips.Runtime;
+import org.xwt.mips.Interpreter;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.image.*;
+import java.awt.event.*;
+import java.io.*;
+
+public class FreeTypeDemo {
+ private JFrame frame;
+ private static final int OURWIDTH=640;
+ private static final int OURHEIGHT=256;
+ private static final int BASELINE=160;
+ private byte[] render = new byte[OURWIDTH*OURHEIGHT];
+ private int size = 72;
+ private StringBuffer sb = new StringBuffer();
+ private View view;
+ private Image image;
+
+ private Runnable renderThread;
+ private String theText;
+ private boolean renderNeeded;
+
+ private String name;
+ private Runtime rt;
+
+ int renderAddr;
+ int stringAddr;
+ int stringSize;
+
+ public static void main(String[] argv) throws Exception {
+ new FreeTypeDemo(argv);
+ }
+
+ public FreeTypeDemo(String[] argv) throws Exception {
+ if(argv.length >= 2 && argv[1].startsWith("int")) {
+ name = "Interpreter";
+ rt = new Interpreter("build/FreeTypeDemoHelper.mips");
+ } else {
+ rt = new FreeTypeDemoHelper();
+ name = "Compiler";
+ }
+
+ rt.start(new String[]{ "freetype.mips"});
+ if(rt.execute()) throw new Error("freetype.mips exited");
+
+ byte[] font = InputStreamToByteArray.convert(new FileInputStream(argv[0]));
+ int fontAddr = rt.malloc(font.length);
+ if(fontAddr == 0) throw new Error("malloc() failed");
+ rt.copyout(font,fontAddr,font.length);
+
+ rt.setUserInfo(0,fontAddr);
+ rt.setUserInfo(1,font.length);
+
+ renderAddr = rt.malloc(OURWIDTH*OURHEIGHT);
+ if(renderAddr == 0) throw new Error("malloc() failed");
+
+ if(rt.execute()) throw new Error("freetype.mips exited (" + rt.getUserInfo(1) +")");
+
+ createImage();
+
+ frame = new JFrame("FreeTypeDemo - " + name);
+ frame.setSize(OURWIDTH,OURHEIGHT);
+ view = new View();
+ frame.getContentPane().add(view,BorderLayout.CENTER);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.show();
+ view.requestFocus();
+ renderThread = new Runnable() {
+ public void run() {
+ try {
+ for(;;) {
+ synchronized(this) { while(!renderNeeded) wait(); renderNeeded = false; }
+ renderText(theText==null ? "" : theText);
+ }
+ } catch(Exception e) { throw new Error(e); }
+ }
+ };
+ new Thread(renderThread).start();
+ keyPress('\n');
+ }
+
+ private static ColorModel cmodel = new DirectColorModel(8, 0xff,0xff,0xff);
+ private void createImage() {
+ for(int i=0;i<OURHEIGHT;i++)
+ for(int j=0;j<OURWIDTH;j++)
+ render[i*OURWIDTH+j] = (byte)((~(render[i*OURWIDTH+j]&0xff))&0xff);
+ image = Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(OURWIDTH, OURHEIGHT, cmodel, render, 0, OURWIDTH));
+ MediaTracker mediatracker = new MediaTracker(new Canvas());
+ mediatracker.addImage(image, 1);
+ try { mediatracker.waitForAll(); } catch (InterruptedException e) { }
+ mediatracker.removeImage(image);
+ }
+ private void renderText(String s) {
+ try {
+ byte[] b = (s+"\0").getBytes("UTF-16BE");
+ if(stringSize < b.length) {
+ System.err.println("reallocing the string space");
+ if(stringAddr != 0) rt.free(stringAddr);
+ stringAddr = rt.malloc(b.length*2);
+ if(stringAddr == 0) throw new Error("malloc failed");
+ stringSize = b.length*2;
+ }
+ rt.copyout(b,stringAddr,b.length);
+ long start = System.currentTimeMillis();
+ if(rt.call("render",stringAddr,size,renderAddr,OURWIDTH,OURHEIGHT,BASELINE)==0) throw new Error("render() failed");
+ System.out.println(name + ": Render of: " + s + " took " + (System.currentTimeMillis()-start) + " ms");
+ rt.copyin(renderAddr,render,render.length);
+ createImage();
+ view.repaint();
+ } catch(Exception e) {
+ throw new Error(e);
+ }
+ }
+
+ private void keyPress(char c) {
+ if(c == '\n' || c == '\r') {
+ sb.setLength(0);
+ theText = "Press any key";
+ } else if(c == '+' || c == '-') {
+ size += (c=='+'?1:-1) * 8;
+ System.out.println("New size: " + size);
+ } else {
+ sb.append(c);
+ theText = sb.toString();
+ }
+ synchronized(renderThread) { renderNeeded = true; renderThread.notify(); }
+ }
+
+ public class View extends JComponent {
+ public void paintComponent(Graphics g) {
+ g.drawImage(image,0,0,OURWIDTH,OURHEIGHT,0,0,OURWIDTH,OURHEIGHT,null);
+ }
+ public View() {
+ addKeyListener(new KeyAdapter() {
+ public void keyTyped(KeyEvent e) {
+ keyPress(e.getKeyChar());
+ }
+ });
+ setPreferredSize(new Dimension(OURWIDTH,OURHEIGHT));
+ }
+ }
+ private static class InputStreamToByteArray {
+
+ /** scratch space for isToByteArray() */
+ private static byte[] workspace = new byte[16 * 1024];
+ /** Trivial method to completely read an InputStream */
+ public static synchronized byte[] convert(InputStream is) throws IOException {
+ int pos = 0;
+ while (true) {
+ int numread = is.read(workspace, pos, workspace.length - pos);
+ if (numread == -1) break;
+ else if (pos + numread < workspace.length) pos += numread;
+ else {
+ pos += numread;
+ byte[] temp = new byte[workspace.length * 2];
+ System.arraycopy(workspace, 0, temp, 0, workspace.length);
+ workspace = temp;
+ }
+ }
+ byte[] ret = new byte[pos];
+ System.arraycopy(workspace, 0, ret, 0, pos);
+ return ret;
+ }
+ }
+}
+
--- /dev/null
+// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
+
+#include <unistd.h>
+#include <freetype/freetype.h>
+
+FT_Library library; /* handle to library */
+FT_Face face; /* handle to face object */
+
+#define FT_Check(expr,err) do { \
+ if((expr) != 0) { \
+ errprint(#expr " failed\n"); \
+ return err; \
+ } \
+} while(0)
+
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#define min(a,b) ((a) < (b) ? (a) : (b))
+
+static int errprint(const char *s) {
+ int l = strlen(s);
+ int n;
+ while(l) {
+ n = write(STDERR_FILENO,s,l);
+ if(n < 0) return n;
+ l -= n;
+ s += n;
+ }
+ return 0;
+}
+
+void draw(FT_GlyphSlot glyph,int x, char *buf, int buf_width, int buf_height, int baseline) {
+ int y = max(baseline - glyph->bitmap_top,0);
+ int rows = glyph->bitmap.rows;
+ int width = glyph->bitmap.width;
+ int i,j;
+ x = x + glyph->bitmap_left;
+ if(x + width >= buf_width) return;
+ if(y + rows >= buf_height) return;
+ //if(buf == NULL) fprintf(stderr,"ABout to dereference %p\n",buf);
+ for(i=0;i<rows;i++)
+ for(j=0;j<width;j++)
+ buf[(i+y)*buf_width+x+j] |= glyph->bitmap.buffer[i*width+j];
+}
+
+/* Prevent --gc-sections from blowing this away */
+int render(short *s, int size, char *buf, int buf_width, int buf_height, int baseline) __attribute__((section(".text")));
+int render(short *s, int size, char *buf, int buf_width, int buf_height, int baseline) {
+ int glyph_index;
+ int x = 0;
+ FT_Check(FT_Set_Pixel_Sizes(face,0,size),0);
+ memset(buf,'\0',buf_width*buf_height);
+ //fprintf(stderr,"Rendering %d pt %c... at %p (%dx%d)\n",size,*s,buf,buf_width,buf_height);
+ while(*s) {
+ glyph_index = FT_Get_Char_Index(face,*s);
+ FT_Check(FT_Load_Glyph(face,glyph_index,FT_LOAD_DEFAULT),0);
+ FT_Check(FT_Render_Glyph(face->glyph,FT_RENDER_MODE_NORMAL/*256color antialiased*/),0);
+ draw(face->glyph,x,buf,buf_width,buf_height,baseline);
+ x += face->glyph->advance.x/64;
+ s++;
+ }
+ return 1;
+}
+
+char * user_info[2];
+extern void _pause();
+
+int main(int argc,char** argv) {
+ char *fontdata;
+ int fontsize;
+
+ _pause();
+
+ fontdata = user_info[0];
+ fontsize = (int)user_info[1];
+
+ //fprintf(stderr,"Initializng freetype with a %d byte font at %p\n", fontsize, fontdata);
+
+ FT_Check(FT_Init_FreeType(&library),EXIT_FAILURE);
+ FT_Check(FT_New_Memory_Face(library, fontdata,fontsize, 0, &face),EXIT_FAILURE);
+
+ errprint("Freetype initialized\n");
+ _pause();
+ errprint("Unpaused\n");
+
+ /* not reached */
+ return EXIT_FAILURE;
+}
--- /dev/null
+#include <stdio.h>
+
+int main() {
+ puts("Hello, World");
+ return 0;
+}
--- /dev/null
+package tests;
+
+import org.xwt.mips.Runtime;
+import java.io.*;
+
+public class MSPack {
+ private String[] fileNames;
+ private int[] lengths;
+ private byte[][] data;
+
+ public static class MSPackException extends IOException { public MSPackException(String s) { super(s); } }
+
+ public MSPack(InputStream cabIS) throws IOException {
+ byte[] cab = InputStreamToByteArray.convert(cabIS);
+ try {
+ //Interpreter vm = new Interpreter("mspack.mips");
+ MSPackHelper vm = new MSPackHelper();
+
+ int cabAddr = vm.sbrk(cab.length);
+ if(cabAddr < 0) throw new MSPackException("sbrk failed");
+
+ vm.copyout(cab,cabAddr,cab.length);
+
+ vm.setUserInfo(0,cabAddr);
+ vm.setUserInfo(1,cab.length);
+
+ int status = vm.run(new String[]{ "mspack.mips"} );
+ if(status != 0) throw new MSPackException("mspack.mips failed (" + status + ")");
+
+ /*static struct {
+ char *filename;
+ char *data;
+ int length;
+ } output_table[MAX_MEMBERS+1]; */
+
+ int filesTable = vm.getUserInfo(2);
+ int count=0;
+ while(vm.memRead(filesTable+count*12) != 0) count++;
+
+ fileNames = new String[count];
+ data = new byte[count][];
+ lengths = new int[count];
+
+ for(int i=0,addr=filesTable;i<count;i++,addr+=12) {
+ int length = vm.memRead(addr+8);
+ data[i] = new byte[length];
+ lengths[i] = length;
+ fileNames[i] = vm.cstring(vm.memRead(addr));
+ System.out.println("" + fileNames[i]);
+ vm.copyin(vm.memRead(addr+4),data[i],length);
+ }
+ } catch(Runtime.ExecutionException e) {
+ e.printStackTrace();
+ throw new MSPackException("mspack.mips crashed");
+ }
+ }
+
+ public String[] getFileNames() { return fileNames; }
+ public int[] getLengths() { return lengths; }
+ public InputStream getInputStream(int index) { return new ByteArrayInputStream(data[index]); }
+ public InputStream getInputStream(String fileName) {
+ for(int i=0;i<fileNames.length;i++) {
+ if(fileName.equalsIgnoreCase(fileNames[i])) return getInputStream(i);
+ }
+ return null;
+ }
+
+ public static void main(String[] args) throws IOException {
+ MSPack pack = new MSPack(new FileInputStream(args[0]));
+ String[] files = pack.getFileNames();
+ for(int i=0;i<files.length;i++)
+ System.out.println(i + ": " + files[i] + ": " + pack.getLengths()[i]);
+ System.out.println("Writing " + files[files.length-1]);
+ InputStream is = pack.getInputStream(files.length-1);
+ OutputStream os = new FileOutputStream(files[files.length-1]);
+ int n;
+ byte[] buf = new byte[4096];
+ while((n = is.read(buf)) != -1) os.write(buf,0,n);
+ os.close();
+ is.close();
+ }
+ private static class InputStreamToByteArray {
+
+ /** scratch space for isToByteArray() */
+ private static byte[] workspace = new byte[16 * 1024];
+ /** Trivial method to completely read an InputStream */
+ public static synchronized byte[] convert(InputStream is) throws IOException {
+ int pos = 0;
+ while (true) {
+ int numread = is.read(workspace, pos, workspace.length - pos);
+ if (numread == -1) break;
+ else if (pos + numread < workspace.length) pos += numread;
+ else {
+ pos += numread;
+ byte[] temp = new byte[workspace.length * 2];
+ System.arraycopy(workspace, 0, temp, 0, workspace.length);
+ workspace = temp;
+ }
+ }
+ byte[] ret = new byte[pos];
+ System.arraycopy(workspace, 0, ret, 0, pos);
+ return ret;
+ }
+ }
+}
+
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/fcntl.h>
+
+#include "mspack.h"
+
+int main(int argc, char **argv) {
+ struct mscab_decompressor *decomp;
+ struct mscabd_cabinet *cab;
+ struct mscabd_file *file;
+ int i;
+
+ if(argc < 2) {
+ fprintf(stderr,"Usage: %s cab\n",argv[0]);
+ exit(1);
+ }
+
+
+ decomp = mspack_create_cab_decompressor(NULL);
+ if(!decomp) exit(1);
+
+ for(i=1;i<argc;i++) {
+ cab = decomp->search(decomp,argv[i]);
+ if(!cab) exit(2);
+
+ for(file = cab->files;file;file=file->next)
+ decomp->extract(decomp,file,file->filename);
+
+ decomp->close(decomp,cab);
+ }
+ mspack_destroy_cab_decompressor(decomp);
+
+ return 0;
+}
--- /dev/null
+/*
+UserInfo:
+ On start:
+ 0: Addr of CAB/EXE
+ 1: Length of CAB/EXE
+ On Edit:
+ 2: Addr of output_table array
+
+Exit codes:
+ 0: Success
+ 1: Internal Error
+ 2: Invalid CAB
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/fcntl.h>
+
+#include "mspack.h"
+
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MAX_MEMBERS 64
+
+char *xstrdup(const char *s) {
+ char *ret = strdup(s);
+ if(ret == NULL) exit(1);
+ return ret;
+}
+
+typedef struct {
+ char *addr;
+ int pos;
+ int size;
+ int length;
+ int writable;
+} mem_buf_t;
+
+static mem_buf_t *cab_mem_buf = NULL;
+
+static void mem_buf_grow(mem_buf_t *buf,size_t newsize) {
+ size_t new_len;
+ char *p;
+ if(buf->length < 0) exit(1);
+ if(newsize <= buf->length) return;
+ new_len = MAX(buf->length ? buf->length*2 : 65536,newsize);
+ p = realloc(buf->addr,new_len);
+ if(p == NULL) exit(1);
+ buf->addr = p;
+ buf->length = new_len;
+}
+
+static struct {
+ char *filename;
+ mem_buf_t buf;
+} write_buf_table[MAX_MEMBERS];
+
+static struct {
+ char *filename;
+ char *data;
+ int length;
+} output_table[MAX_MEMBERS+1];
+
+static struct mspack_file *my_open(struct mspack_system *sys, char *filename, int mode) {
+ mem_buf_t *buf = NULL;
+ int i;
+ if(strcmp(filename,"/dev/cab")==0) {
+ if(mode != MSPACK_SYS_OPEN_READ) return NULL;
+ buf = cab_mem_buf;
+ } else {
+ if(mode != MSPACK_SYS_OPEN_WRITE) return NULL;
+
+ for(i=0;i<MAX_MEMBERS;i++) {
+ if(write_buf_table[i].filename == NULL) {
+ printf("%s in %d\n",filename,i);
+ write_buf_table[i].filename = xstrdup(filename);
+ buf = &write_buf_table[i].buf;
+ buf->writable = 1;
+ break;
+ }
+ }
+ }
+
+ return (struct mspack_file *) buf;
+}
+
+static void my_close(struct mspack_file *buf_) {
+ mem_buf_t *buf = (mem_buf_t*) buf_;
+ /* NO OP */
+}
+
+static int my_read(struct mspack_file *buf_, void *out, int count) {
+ mem_buf_t *buf = (mem_buf_t*) buf_;
+ count = MIN(buf->size - buf->pos, count);
+ memcpy(out,buf->addr + buf->pos,count);
+ buf->pos += count;
+ return count;
+}
+
+static int my_write(struct mspack_file *buf_, void *in, int count) {
+ mem_buf_t *buf = (mem_buf_t*) buf_;
+ if(!buf->writable) return -1;
+ if(buf->length < buf->pos + count) mem_buf_grow(buf,buf->pos + count);
+ memcpy(buf->addr+buf->pos,in,count);
+ buf->pos += count;
+ buf->size = MAX(buf->size,buf->pos);
+ return count;
+}
+
+static int my_seek(struct mspack_file *buf_, off_t off, int mode) {
+ mem_buf_t *buf = (mem_buf_t*) buf_;
+ int newpos;
+ switch(mode) {
+ case MSPACK_SYS_SEEK_START: newpos = off; break;
+ case MSPACK_SYS_SEEK_CUR: newpos = buf->pos + off; break;
+ case MSPACK_SYS_SEEK_END: newpos = buf->size - off; break;
+ default: return -1;
+ }
+ if(newpos < 0) return -1;
+ if(newpos > buf->size) {
+ if(!buf->writable) return -1;
+ if(newpos > buf->length)
+ mem_buf_grow(buf,newpos);
+ }
+ buf->pos = newpos;
+ return 0;
+}
+
+static off_t my_tell(struct mspack_file *buf_) {
+ mem_buf_t *buf = (mem_buf_t*) buf_;
+ return buf ? buf->pos : 0;
+}
+
+static void my_message(struct mspack_file *file, char *format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+ fputc((int) '\n', stderr);
+ fflush(stderr);
+}
+
+static void *my_alloc(struct mspack_system *sys, size_t size) { return malloc(size); }
+static void my_free(void *p) { free(p); }
+static void my_copy(void *src, void *dest, size_t bytes) { memcpy(dest, src, bytes); }
+
+static struct mspack_system my_system = {
+ &my_open,
+ &my_close,
+ &my_read,
+ &my_write,
+ &my_seek,
+ &my_tell,
+ &my_message,
+ &my_alloc,
+ &my_free,
+ &my_copy,
+ NULL
+};
+
+char *user_info[4];
+
+int main(int argc, char **argv) {
+ struct mscab_decompressor *decomp;
+ struct mscabd_cabinet *cab;
+ struct mscabd_file *file;
+ mem_buf_t mem_buf;
+ size_t size = (size_t)user_info[1];
+ int i;
+
+ mem_buf.addr = user_info[0];
+ mem_buf.pos = mem_buf.writable = 0;
+ mem_buf.length = -1;
+ mem_buf.size = size;
+
+ cab_mem_buf = &mem_buf;
+
+ decomp = mspack_create_cab_decompressor(&my_system);
+ if(!decomp) exit(1);
+
+ cab = decomp->search(decomp,"/dev/cab");
+ if(!cab) exit(2);
+
+ for(file = cab->files;file;file=file->next)
+ decomp->extract(decomp,file,file->filename);
+
+ decomp->close(decomp,cab);
+ mspack_destroy_cab_decompressor(decomp);
+
+ printf("Success!\n");
+
+ for(i=0;i<MAX_MEMBERS && write_buf_table[i].filename;i++) {
+ output_table[i].filename = write_buf_table[i].filename;
+ output_table[i].data = write_buf_table[i].buf.addr;
+ output_table[i].length = write_buf_table[i].buf.size;
+ }
+
+ user_info[2] = (char*) output_table;
+
+ /*
+ if(output_table[0].filename) {
+ printf("%s in 0\n",write_buf_table[0].filename);
+ fp = fopen(output_table[0].filename,"wb");
+ if(fp) {
+ fwrite(output_table[0].data,1,output_table[0].length,fp);
+ fclose(fp);
+ printf("Wrote: %s\n",output_table[0].filename);
+ }
+ }
+ */
+
+ return 0;
+}
--- /dev/null
+/* A C version of Kahan's Floating Point Test "Paranoia"
+
+ Thos Sumner, UCSF, Feb. 1985
+ David Gay, BTL, Jan. 1986
+
+ This is a rewrite from the Pascal version by
+
+ B. A. Wichmann, 18 Jan. 1985
+
+ (and does NOT exhibit good C programming style).
+
+ Adjusted to use Standard C headers 19 Jan. 1992 (dmg);
+ compile with -DKR_headers or insert
+#define KR_headers
+ at the beginning if you have an old-style C compiler.
+
+(C) Apr 19 1983 in BASIC version by:
+ Professor W. M. Kahan,
+ 567 Evans Hall
+ Electrical Engineering & Computer Science Dept.
+ University of California
+ Berkeley, California 94720
+ USA
+
+converted to Pascal by:
+ B. A. Wichmann
+ National Physical Laboratory
+ Teddington Middx
+ TW11 OLW
+ UK
+
+converted to C by:
+
+ David M. Gay and Thos Sumner
+ AT&T Bell Labs Computer Center, Rm. U-76
+ 600 Mountain Avenue University of California
+ Murray Hill, NJ 07974 San Francisco, CA 94143
+ USA USA
+
+with simultaneous corrections to the Pascal source (reflected
+in the Pascal source available over netlib).
+[A couple of bug fixes from dgh = sun!dhough incorporated 31 July 1986.]
+
+Reports of results on various systems from all the versions
+of Paranoia are being collected by Richard Karpinski at the
+same address as Thos Sumner. This includes sample outputs,
+bug reports, and criticisms.
+
+You may copy this program freely if you acknowledge its source.
+Comments on the Pascal version to NPL, please.
+
+
+The C version catches signals from floating-point exceptions.
+If signal(SIGFPE,...) is unavailable in your environment, you may
+#define NOSIGNAL to comment out the invocations of signal.
+
+This source file is too big for some C compilers, but may be split
+into pieces. Comments containing "SPLIT" suggest convenient places
+for this splitting. At the end of these comments is an "ed script"
+(for the UNIX(tm) editor ed) that will do this splitting.
+
+By #defining Single when you compile this source, you may obtain
+a single-precision C version of Paranoia.
+
+
+The following is from the introductory commentary from Wichmann's work:
+
+The BASIC program of Kahan is written in Microsoft BASIC using many
+facilities which have no exact analogy in Pascal. The Pascal
+version below cannot therefore be exactly the same. Rather than be
+a minimal transcription of the BASIC program, the Pascal coding
+follows the conventional style of block-structured languages. Hence
+the Pascal version could be useful in producing versions in other
+structured languages.
+
+Rather than use identifiers of minimal length (which therefore have
+little mnemonic significance), the Pascal version uses meaningful
+identifiers as follows [Note: A few changes have been made for C]:
+
+
+BASIC C BASIC C BASIC C
+
+ A J S StickyBit
+ A1 AInverse J0 NoErrors T
+ B Radix [Failure] T0 Underflow
+ B1 BInverse J1 NoErrors T2 ThirtyTwo
+ B2 RadixD2 [SeriousDefect] T5 OneAndHalf
+ B9 BMinusU2 J2 NoErrors T7 TwentySeven
+ C [Defect] T8 TwoForty
+ C1 CInverse J3 NoErrors U OneUlp
+ D [Flaw] U0 UnderflowThreshold
+ D4 FourD K PageNo U1
+ E0 L Milestone U2
+ E1 M V
+ E2 Exp2 N V0
+ E3 N1 V8
+ E5 MinSqEr O Zero V9
+ E6 SqEr O1 One W
+ E7 MaxSqEr O2 Two X
+ E8 O3 Three X1
+ E9 O4 Four X8
+ F1 MinusOne O5 Five X9 Random1
+ F2 Half O8 Eight Y
+ F3 Third O9 Nine Y1
+ F6 P Precision Y2
+ F9 Q Y9 Random2
+ G1 GMult Q8 Z
+ G2 GDiv Q9 Z0 PseudoZero
+ G3 GAddSub R Z1
+ H R1 RMult Z2
+ H1 HInverse R2 RDiv Z9
+ I R3 RAddSub
+ IO NoTrials R4 RSqrt
+ I3 IEEE R9 Random9
+
+ SqRWrng
+
+All the variables in BASIC are true variables and in consequence,
+the program is more difficult to follow since the "constants" must
+be determined (the glossary is very helpful). The Pascal version
+uses Real constants, but checks are added to ensure that the values
+are correctly converted by the compiler.
+
+The major textual change to the Pascal version apart from the
+identifiersis that named procedures are used, inserting parameters
+wherehelpful. New procedures are also introduced. The
+correspondence is as follows:
+
+
+BASIC Pascal
+lines
+
+ 90- 140 Pause
+ 170- 250 Instructions
+ 380- 460 Heading
+ 480- 670 Characteristics
+ 690- 870 History
+2940-2950 Random
+3710-3740 NewD
+4040-4080 DoesYequalX
+4090-4110 PrintIfNPositive
+4640-4850 TestPartialUnderflow
+
+=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
+
+Below is an "ed script" that splits para.c into 10 files
+of the form part[1-8].c, subs.c, and msgs.c, plus a header
+file, paranoia.h, that these files require.
+
+r paranoia.c
+$
+?SPLIT
+ .d
++d
+-,$w msgs.c
+-,$d
+?SPLIT
+ .d
++d
+-,$w subs.c
+-,$d
+?part8
++d
+?include
+ .,$w part8.c
+ .,$d
+-d
+?part7
++d
+?include
+ .,$w part7.c
+ .,$d
+-d
+?part6
++d
+?include
+ .,$w part6.c
+ .,$d
+-d
+?part5
++d
+?include
+ .,$w part5.c
+ .,$d
+-d
+?part4
++d
+?include
+ .,$w part4.c
+ .,$d
+-d
+?part3
++d
+?include
+ .,$w part3.c
+ .,$d
+-d
+?part2
++d
+?include
+ .,$w part2.c
+ .,$d
+?SPLIT
+ .d
+1,/^#include/-1d
+1,$w part1.c
+/Computed constants/,$d
+1,$s/^int/extern &/
+1,$s/^FLOAT/extern &/
+1,$s/^char/extern &/
+1,$s! = .*!;!
+/^Guard/,/^Round/s/^/extern /
+/^jmp_buf/s/^/extern /
+/^Sig_type/s/^/extern /
+s/$/\
+extern void sigfpe(INT);/
+w paranoia.h
+q
+
+*/
+
+#include <stdio.h>
+#ifndef NOSIGNAL
+#include <signal.h>
+#endif
+#include <setjmp.h>
+
+#ifdef Single
+#define FLOAT float
+#define FABS(x) (float)fabs((double)(x))
+#define FLOOR(x) (float)floor((double)(x))
+#define LOG(x) (float)log((double)(x))
+#define POW(x,y) (float)pow((double)(x),(double)(y))
+#define SQRT(x) (float)sqrt((double)(x))
+#else
+#define FLOAT double
+#define FABS(x) fabs(x)
+#define FLOOR(x) floor(x)
+#define LOG(x) log(x)
+#define POW(x,y) pow(x,y)
+#define SQRT(x) sqrt(x)
+#endif
+
+jmp_buf ovfl_buf;
+#ifdef KR_headers
+#define VOID /* void */
+#define INT /* int */
+#define FP /* FLOAT */
+#define CHARP /* char * */
+#define CHARPP /* char ** */
+extern double fabs(), floor(), log(), pow(), sqrt();
+extern void exit();
+typedef void (*Sig_type)();
+FLOAT Sign(), Random();
+extern void BadCond();
+extern void SqXMinX();
+extern void TstCond();
+extern void notify();
+extern int read();
+#else
+#define VOID void
+#define INT int
+#define FP FLOAT
+#define CHARP char *
+#define CHARPP char **
+#ifdef __STDC__
+#include <stdlib.h>
+#include <math.h>
+#else
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern double fabs(double), floor(double), log(double);
+extern double pow(double,double), sqrt(double);
+extern void exit(INT);
+#ifdef __cplusplus
+ }
+#endif
+#endif
+typedef void (*Sig_type)(int);
+FLOAT Sign(FLOAT), Random(void);
+extern void BadCond(int, char*);
+extern void SqXMinX(int);
+extern void TstCond(int, int, char*);
+extern void notify(char*);
+extern int read(int, char*, int);
+#endif
+#undef V9
+extern void Characteristics(VOID);
+extern void Heading(VOID);
+extern void History(VOID);
+extern void Instructions(VOID);
+extern void IsYeqX(VOID);
+extern void NewD(VOID);
+extern void Pause(VOID);
+extern void PrintIfNPositive(VOID);
+extern void SR3750(VOID);
+extern void SR3980(VOID);
+extern void TstPtUf(VOID);
+
+Sig_type sigsave;
+
+#define KEYBOARD 0
+
+FLOAT Radix, BInvrse, RadixD2, BMinusU2;
+
+/*Small floating point constants.*/
+FLOAT Zero = 0.0;
+FLOAT Half = 0.5;
+FLOAT One = 1.0;
+FLOAT Two = 2.0;
+FLOAT Three = 3.0;
+FLOAT Four = 4.0;
+FLOAT Five = 5.0;
+FLOAT Eight = 8.0;
+FLOAT Nine = 9.0;
+FLOAT TwentySeven = 27.0;
+FLOAT ThirtyTwo = 32.0;
+FLOAT TwoForty = 240.0;
+FLOAT MinusOne = -1.0;
+FLOAT OneAndHalf = 1.5;
+/*Integer constants*/
+int NoTrials = 20; /*Number of tests for commutativity. */
+#define False 0
+#define True 1
+
+/* Definitions for declared types
+ Guard == (Yes, No);
+ Rounding == (Chopped, Rounded, Other);
+ Message == packed array [1..40] of char;
+ Class == (Flaw, Defect, Serious, Failure);
+ */
+#define Yes 1
+#define No 0
+#define Chopped 2
+#define Rounded 1
+#define Other 0
+#define Flaw 3
+#define Defect 2
+#define Serious 1
+#define Failure 0
+typedef int Guard, Rounding, Class;
+typedef char Message;
+
+/* Declarations of Variables */
+int Indx;
+char ch[8];
+FLOAT AInvrse, A1;
+FLOAT C, CInvrse;
+FLOAT D, FourD;
+FLOAT E0, E1, Exp2, E3, MinSqEr;
+FLOAT SqEr, MaxSqEr, E9;
+FLOAT Third;
+FLOAT F6, F9;
+FLOAT H, HInvrse;
+int I;
+FLOAT StickyBit, J;
+FLOAT MyZero;
+FLOAT Precision;
+FLOAT Q, Q9;
+FLOAT R, Random9;
+FLOAT T, Underflow, S;
+FLOAT OneUlp, UfThold, U1, U2;
+FLOAT V, V0, V9;
+FLOAT W;
+FLOAT X, X1, X2, X8, Random1;
+FLOAT Y, Y1, Y2, Random2;
+FLOAT Z, PseudoZero, Z1, Z2, Z9;
+int ErrCnt[4];
+int fpecount;
+int Milestone;
+int PageNo;
+int M, N, N1;
+Guard GMult, GDiv, GAddSub;
+Rounding RMult, RDiv, RAddSub, RSqrt;
+int Break, Done, NotMonot, Monot, Anomaly, IEEE,
+ SqRWrng, UfNGrad;
+/* Computed constants. */
+/*U1 gap below 1.0, i.e, 1.0-U1 is next number below 1.0 */
+/*U2 gap above 1.0, i.e, 1.0+U2 is next number above 1.0 */
+
+/* floating point exception receiver */
+ void
+sigfpe(INT x)
+{
+ fpecount++;
+ printf("\n* * * FLOATING-POINT ERROR %d * * *\n", x);
+ fflush(stdout);
+ if (sigsave) {
+#ifndef NOSIGNAL
+ signal(SIGFPE, sigsave);
+#endif
+ sigsave = 0;
+ longjmp(ovfl_buf, 1);
+ }
+ exit(1);
+}
+
+main(VOID)
+{
+ /* First two assignments use integer right-hand sides. */
+ Zero = 0;
+ One = 1;
+ Two = One + One;
+ Three = Two + One;
+ Four = Three + One;
+ Five = Four + One;
+ Eight = Four + Four;
+ Nine = Three * Three;
+ TwentySeven = Nine * Three;
+ ThirtyTwo = Four * Eight;
+ TwoForty = Four * Five * Three * Four;
+ MinusOne = -One;
+ Half = One / Two;
+ OneAndHalf = One + Half;
+ ErrCnt[Failure] = 0;
+ ErrCnt[Serious] = 0;
+ ErrCnt[Defect] = 0;
+ ErrCnt[Flaw] = 0;
+ PageNo = 1;
+ /*=============================================*/
+ Milestone = 0;
+ /*=============================================*/
+#ifndef NOSIGNAL
+ signal(SIGFPE, sigfpe);
+#endif
+ Instructions();
+ Pause();
+ Heading();
+ Pause();
+ Characteristics();
+ Pause();
+ History();
+ Pause();
+ /*=============================================*/
+ Milestone = 7;
+ /*=============================================*/
+ printf("Program is now RUNNING tests on small integers:\n");
+
+ TstCond (Failure, (Zero + Zero == Zero) && (One - One == Zero)
+ && (One > Zero) && (One + One == Two),
+ "0+0 != 0, 1-1 != 0, 1 <= 0, or 1+1 != 2");
+ Z = - Zero;
+ if (Z != 0.0) {
+ ErrCnt[Failure] = ErrCnt[Failure] + 1;
+ printf("Comparison alleges that -0.0 is Non-zero!\n");
+ U2 = 0.001;
+ Radix = 1;
+ TstPtUf();
+ }
+ TstCond (Failure, (Three == Two + One) && (Four == Three + One)
+ && (Four + Two * (- Two) == Zero)
+ && (Four - Three - One == Zero),
+ "3 != 2+1, 4 != 3+1, 4+2*(-2) != 0, or 4-3-1 != 0");
+ TstCond (Failure, (MinusOne == (0 - One))
+ && (MinusOne + One == Zero ) && (One + MinusOne == Zero)
+ && (MinusOne + FABS(One) == Zero)
+ && (MinusOne + MinusOne * MinusOne == Zero),
+ "-1+1 != 0, (-1)+abs(1) != 0, or -1+(-1)*(-1) != 0");
+ TstCond (Failure, Half + MinusOne + Half == Zero,
+ "1/2 + (-1) + 1/2 != 0");
+ /*=============================================*/
+ /*SPLIT
+ {
+ extern void part2(VOID), part3(VOID), part4(VOID),
+ part5(VOID), part6(VOID), part7(VOID);
+ int part8(VOID);
+
+ part2();
+ part3();
+ part4();
+ part5();
+ part6();
+ part7();
+ return part8();
+ }
+ }
+#include "paranoia.h"
+void part2(VOID){
+*/
+ Milestone = 10;
+ /*=============================================*/
+ TstCond (Failure, (Nine == Three * Three)
+ && (TwentySeven == Nine * Three) && (Eight == Four + Four)
+ && (ThirtyTwo == Eight * Four)
+ && (ThirtyTwo - TwentySeven - Four - One == Zero),
+ "9 != 3*3, 27 != 9*3, 32 != 8*4, or 32-27-4-1 != 0");
+ TstCond (Failure, (Five == Four + One) &&
+ (TwoForty == Four * Five * Three * Four)
+ && (TwoForty / Three - Four * Four * Five == Zero)
+ && ( TwoForty / Four - Five * Three * Four == Zero)
+ && ( TwoForty / Five - Four * Three * Four == Zero),
+ "5 != 4+1, 240/3 != 80, 240/4 != 60, or 240/5 != 48");
+ if (ErrCnt[Failure] == 0) {
+ printf("-1, 0, 1/2, 1, 2, 3, 4, 5, 9, 27, 32 & 240 are O.K.\n");
+ printf("\n");
+ }
+ printf("Searching for Radix and Precision.\n");
+ W = One;
+ do {
+ W = W + W;
+ Y = W + One;
+ Z = Y - W;
+ Y = Z - One;
+ } while (MinusOne + FABS(Y) < Zero);
+ /*.. now W is just big enough that |((W+1)-W)-1| >= 1 ...*/
+ Precision = Zero;
+ Y = One;
+ do {
+ Radix = W + Y;
+ Y = Y + Y;
+ Radix = Radix - W;
+ } while ( Radix == Zero);
+ if (Radix < Two) Radix = One;
+ printf("Radix = %f .\n", Radix);
+ if (Radix != 1) {
+ W = One;
+ do {
+ Precision = Precision + One;
+ W = W * Radix;
+ Y = W + One;
+ } while ((Y - W) == One);
+ }
+ /*... now W == Radix^Precision is barely too big to satisfy (W+1)-W == 1
+ ...*/
+ U1 = One / W;
+ U2 = Radix * U1;
+ printf("Closest relative separation found is U1 = %.7e .\n\n", U1);
+ printf("Recalculating radix and precision\n ");
+
+ /*save old values*/
+ E0 = Radix;
+ E1 = U1;
+ E9 = U2;
+ E3 = Precision;
+
+ X = Four / Three;
+ Third = X - One;
+ F6 = Half - Third;
+ X = F6 + F6;
+ X = FABS(X - Third);
+ if (X < U2) X = U2;
+
+ /*... now X = (unknown no.) ulps of 1+...*/
+ do {
+ U2 = X;
+ Y = Half * U2 + ThirtyTwo * U2 * U2;
+ Y = One + Y;
+ X = Y - One;
+ } while ( ! ((U2 <= X) || (X <= Zero)));
+
+ /*... now U2 == 1 ulp of 1 + ... */
+ X = Two / Three;
+ F6 = X - Half;
+ Third = F6 + F6;
+ X = Third - Half;
+ X = FABS(X + F6);
+ if (X < U1) X = U1;
+
+ /*... now X == (unknown no.) ulps of 1 -... */
+ do {
+ U1 = X;
+ Y = Half * U1 + ThirtyTwo * U1 * U1;
+ Y = Half - Y;
+ X = Half + Y;
+ Y = Half - X;
+ X = Half + Y;
+ } while ( ! ((U1 <= X) || (X <= Zero)));
+ /*... now U1 == 1 ulp of 1 - ... */
+ if (U1 == E1) printf("confirms closest relative separation U1 .\n");
+ else printf("gets better closest relative separation U1 = %.7e .\n", U1);
+ W = One / U1;
+ F9 = (Half - U1) + Half;
+ Radix = FLOOR(0.01 + U2 / U1);
+ if (Radix == E0) printf("Radix confirmed.\n");
+ else printf("MYSTERY: recalculated Radix = %.7e .\n", Radix);
+ TstCond (Defect, Radix <= Eight + Eight,
+ "Radix is too big: roundoff problems");
+ TstCond (Flaw, (Radix == Two) || (Radix == 10)
+ || (Radix == One), "Radix is not as good as 2 or 10");
+ /*=============================================*/
+ Milestone = 20;
+ /*=============================================*/
+ TstCond (Failure, F9 - Half < Half,
+ "(1-U1)-1/2 < 1/2 is FALSE, prog. fails?");
+ X = F9;
+ I = 1;
+ Y = X - Half;
+ Z = Y - Half;
+ TstCond (Failure, (X != One)
+ || (Z == Zero), "Comparison is fuzzy,X=1 but X-1/2-1/2 != 0");
+ X = One + U2;
+ I = 0;
+ /*=============================================*/
+ Milestone = 25;
+ /*=============================================*/
+ /*... BMinusU2 = nextafter(Radix, 0) */
+ BMinusU2 = Radix - One;
+ BMinusU2 = (BMinusU2 - U2) + One;
+ /* Purify Integers */
+ if (Radix != One) {
+ X = - TwoForty * LOG(U1) / LOG(Radix);
+ Y = FLOOR(Half + X);
+ if (FABS(X - Y) * Four < One) X = Y;
+ Precision = X / TwoForty;
+ Y = FLOOR(Half + Precision);
+ if (FABS(Precision - Y) * TwoForty < Half) Precision = Y;
+ }
+ if ((Precision != FLOOR(Precision)) || (Radix == One)) {
+ printf("Precision cannot be characterized by an Integer number\n");
+ printf("of significant digits but, by itself, this is a minor flaw.\n");
+ }
+ if (Radix == One)
+ printf("logarithmic encoding has precision characterized solely by U1.\n");
+ else printf("The number of significant digits of the Radix is %f .\n",
+ Precision);
+ TstCond (Serious, U2 * Nine * Nine * TwoForty < One,
+ "Precision worse than 5 decimal figures ");
+ /*=============================================*/
+ Milestone = 30;
+ /*=============================================*/
+ /* Test for extra-precise subepressions */
+ X = FABS(((Four / Three - One) - One / Four) * Three - One / Four);
+ do {
+ Z2 = X;
+ X = (One + (Half * Z2 + ThirtyTwo * Z2 * Z2)) - One;
+ } while ( ! ((Z2 <= X) || (X <= Zero)));
+ X = Y = Z = FABS((Three / Four - Two / Three) * Three - One / Four);
+ do {
+ Z1 = Z;
+ Z = (One / Two - ((One / Two - (Half * Z1 + ThirtyTwo * Z1 * Z1))
+ + One / Two)) + One / Two;
+ } while ( ! ((Z1 <= Z) || (Z <= Zero)));
+ do {
+ do {
+ Y1 = Y;
+ Y = (Half - ((Half - (Half * Y1 + ThirtyTwo * Y1 * Y1)) + Half
+ )) + Half;
+ } while ( ! ((Y1 <= Y) || (Y <= Zero)));
+ X1 = X;
+ X = ((Half * X1 + ThirtyTwo * X1 * X1) - F9) + F9;
+ } while ( ! ((X1 <= X) || (X <= Zero)));
+ if ((X1 != Y1) || (X1 != Z1)) {
+ BadCond(Serious, "Disagreements among the values X1, Y1, Z1,\n");
+ printf("respectively %.7e, %.7e, %.7e,\n", X1, Y1, Z1);
+ printf("are symptoms of inconsistencies introduced\n");
+ printf("by extra-precise evaluation of arithmetic subexpressions.\n");
+ notify("Possibly some part of this");
+ if ((X1 == U1) || (Y1 == U1) || (Z1 == U1)) printf(
+ "That feature is not tested further by this program.\n") ;
+ }
+ else {
+ if ((Z1 != U1) || (Z2 != U2)) {
+ if ((Z1 >= U1) || (Z2 >= U2)) {
+ BadCond(Failure, "");
+ notify("Precision");
+ printf("\tU1 = %.7e, Z1 - U1 = %.7e\n",U1,Z1-U1);
+ printf("\tU2 = %.7e, Z2 - U2 = %.7e\n",U2,Z2-U2);
+ }
+ else {
+ if ((Z1 <= Zero) || (Z2 <= Zero)) {
+ printf("Because of unusual Radix = %f", Radix);
+ printf(", or exact rational arithmetic a result\n");
+ printf("Z1 = %.7e, or Z2 = %.7e ", Z1, Z2);
+ notify("of an\nextra-precision");
+ }
+ if (Z1 != Z2 || Z1 > Zero) {
+ X = Z1 / U1;
+ Y = Z2 / U2;
+ if (Y > X) X = Y;
+ Q = - LOG(X);
+ printf("Some subexpressions appear to be calculated extra\n");
+ printf("precisely with about %g extra B-digits, i.e.\n",
+ (Q / LOG(Radix)));
+ printf("roughly %g extra significant decimals.\n",
+ Q / LOG(10.));
+ }
+ printf("That feature is not tested further by this program.\n");
+ }
+ }
+ }
+ Pause();
+ /*=============================================*/
+ /*SPLIT
+ }
+#include "paranoia.h"
+void part3(VOID){
+*/
+ Milestone = 35;
+ /*=============================================*/
+ if (Radix >= Two) {
+ X = W / (Radix * Radix);
+ Y = X + One;
+ Z = Y - X;
+ T = Z + U2;
+ X = T - Z;
+ TstCond (Failure, X == U2,
+ "Subtraction is not normalized X=Y,X+Z != Y+Z!");
+ if (X == U2) printf(
+ "Subtraction appears to be normalized, as it should be.");
+ }
+ printf("\nChecking for guard digit in *, /, and -.\n");
+ Y = F9 * One;
+ Z = One * F9;
+ X = F9 - Half;
+ Y = (Y - Half) - X;
+ Z = (Z - Half) - X;
+ X = One + U2;
+ T = X * Radix;
+ R = Radix * X;
+ X = T - Radix;
+ X = X - Radix * U2;
+ T = R - Radix;
+ T = T - Radix * U2;
+ X = X * (Radix - One);
+ T = T * (Radix - One);
+ if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)) GMult = Yes;
+ else {
+ GMult = No;
+ TstCond (Serious, False,
+ "* lacks a Guard Digit, so 1*X != X");
+ }
+ Z = Radix * U2;
+ X = One + Z;
+ Y = FABS((X + Z) - X * X) - U2;
+ X = One - U2;
+ Z = FABS((X - U2) - X * X) - U1;
+ TstCond (Failure, (Y <= Zero)
+ && (Z <= Zero), "* gets too many final digits wrong.\n");
+ Y = One - U2;
+ X = One + U2;
+ Z = One / Y;
+ Y = Z - X;
+ X = One / Three;
+ Z = Three / Nine;
+ X = X - Z;
+ T = Nine / TwentySeven;
+ Z = Z - T;
+ TstCond(Defect, X == Zero && Y == Zero && Z == Zero,
+ "Division lacks a Guard Digit, so error can exceed 1 ulp\n\
+or 1/3 and 3/9 and 9/27 may disagree");
+ Y = F9 / One;
+ X = F9 - Half;
+ Y = (Y - Half) - X;
+ X = One + U2;
+ T = X / One;
+ X = T - X;
+ if ((X == Zero) && (Y == Zero) && (Z == Zero)) GDiv = Yes;
+ else {
+ GDiv = No;
+ TstCond (Serious, False,
+ "Division lacks a Guard Digit, so X/1 != X");
+ }
+ X = One / (One + U2);
+ Y = X - Half - Half;
+ TstCond (Serious, Y < Zero,
+ "Computed value of 1/1.000..1 >= 1");
+ X = One - U2;
+ Y = One + Radix * U2;
+ Z = X * Radix;
+ T = Y * Radix;
+ R = Z / Radix;
+ StickyBit = T / Radix;
+ X = R - X;
+ Y = StickyBit - Y;
+ TstCond (Failure, X == Zero && Y == Zero,
+ "* and/or / gets too many last digits wrong");
+ Y = One - U1;
+ X = One - F9;
+ Y = One - Y;
+ T = Radix - U2;
+ Z = Radix - BMinusU2;
+ T = Radix - T;
+ if ((X == U1) && (Y == U1) && (Z == U2) && (T == U2)) GAddSub = Yes;
+ else {
+ GAddSub = No;
+ TstCond (Serious, False,
+ "- lacks Guard Digit, so cancellation is obscured");
+ }
+ if (F9 != One && F9 - One >= Zero) {
+ BadCond(Serious, "comparison alleges (1-U1) < 1 although\n");
+ printf(" subtraction yields (1-U1) - 1 = 0 , thereby vitiating\n");
+ printf(" such precautions against division by zero as\n");
+ printf(" ... if (X == 1.0) {.....} else {.../(X-1.0)...}\n");
+ }
+ if (GMult == Yes && GDiv == Yes && GAddSub == Yes) printf(
+ " *, /, and - appear to have guard digits, as they should.\n");
+ /*=============================================*/
+ Milestone = 40;
+ /*=============================================*/
+ Pause();
+ printf("Checking rounding on multiply, divide and add/subtract.\n");
+ RMult = Other;
+ RDiv = Other;
+ RAddSub = Other;
+ RadixD2 = Radix / Two;
+ A1 = Two;
+ Done = False;
+ do {
+ AInvrse = Radix;
+ do {
+ X = AInvrse;
+ AInvrse = AInvrse / A1;
+ } while ( ! (FLOOR(AInvrse) != AInvrse));
+ Done = (X == One) || (A1 > Three);
+ if (! Done) A1 = Nine + One;
+ } while ( ! (Done));
+ if (X == One) A1 = Radix;
+ AInvrse = One / A1;
+ X = A1;
+ Y = AInvrse;
+ Done = False;
+ do {
+ Z = X * Y - Half;
+ TstCond (Failure, Z == Half,
+ "X * (1/X) differs from 1");
+ Done = X == Radix;
+ X = Radix;
+ Y = One / X;
+ } while ( ! (Done));
+ Y2 = One + U2;
+ Y1 = One - U2;
+ X = OneAndHalf - U2;
+ Y = OneAndHalf + U2;
+ Z = (X - U2) * Y2;
+ T = Y * Y1;
+ Z = Z - X;
+ T = T - X;
+ X = X * Y2;
+ Y = (Y + U2) * Y1;
+ X = X - OneAndHalf;
+ Y = Y - OneAndHalf;
+ if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T <= Zero)) {
+ X = (OneAndHalf + U2) * Y2;
+ Y = OneAndHalf - U2 - U2;
+ Z = OneAndHalf + U2 + U2;
+ T = (OneAndHalf - U2) * Y1;
+ X = X - (Z + U2);
+ StickyBit = Y * Y1;
+ S = Z * Y2;
+ T = T - Y;
+ Y = (U2 - Y) + StickyBit;
+ Z = S - (Z + U2 + U2);
+ StickyBit = (Y2 + U2) * Y1;
+ Y1 = Y2 * Y1;
+ StickyBit = StickyBit - Y2;
+ Y1 = Y1 - Half;
+ if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)
+ && ( StickyBit == Zero) && (Y1 == Half)) {
+ RMult = Rounded;
+ printf("Multiplication appears to round correctly.\n");
+ }
+ else if ((X + U2 == Zero) && (Y < Zero) && (Z + U2 == Zero)
+ && (T < Zero) && (StickyBit + U2 == Zero)
+ && (Y1 < Half)) {
+ RMult = Chopped;
+ printf("Multiplication appears to chop.\n");
+ }
+ else printf("* is neither chopped nor correctly rounded.\n");
+ if ((RMult == Rounded) && (GMult == No)) notify("Multiplication");
+ }
+ else printf("* is neither chopped nor correctly rounded.\n");
+ /*=============================================*/
+ Milestone = 45;
+ /*=============================================*/
+ Y2 = One + U2;
+ Y1 = One - U2;
+ Z = OneAndHalf + U2 + U2;
+ X = Z / Y2;
+ T = OneAndHalf - U2 - U2;
+ Y = (T - U2) / Y1;
+ Z = (Z + U2) / Y2;
+ X = X - OneAndHalf;
+ Y = Y - T;
+ T = T / Y1;
+ Z = Z - (OneAndHalf + U2);
+ T = (U2 - OneAndHalf) + T;
+ if (! ((X > Zero) || (Y > Zero) || (Z > Zero) || (T > Zero))) {
+ X = OneAndHalf / Y2;
+ Y = OneAndHalf - U2;
+ Z = OneAndHalf + U2;
+ X = X - Y;
+ T = OneAndHalf / Y1;
+ Y = Y / Y1;
+ T = T - (Z + U2);
+ Y = Y - Z;
+ Z = Z / Y2;
+ Y1 = (Y2 + U2) / Y2;
+ Z = Z - OneAndHalf;
+ Y2 = Y1 - Y2;
+ Y1 = (F9 - U1) / F9;
+ if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)
+ && (Y2 == Zero) && (Y2 == Zero)
+ && (Y1 - Half == F9 - Half )) {
+ RDiv = Rounded;
+ printf("Division appears to round correctly.\n");
+ if (GDiv == No) notify("Division");
+ }
+ else if ((X < Zero) && (Y < Zero) && (Z < Zero) && (T < Zero)
+ && (Y2 < Zero) && (Y1 - Half < F9 - Half)) {
+ RDiv = Chopped;
+ printf("Division appears to chop.\n");
+ }
+ }
+ if (RDiv == Other) printf("/ is neither chopped nor correctly rounded.\n");
+ BInvrse = One / Radix;
+ TstCond (Failure, (BInvrse * Radix - Half == Half),
+ "Radix * ( 1 / Radix ) differs from 1");
+ /*=============================================*/
+ /*SPLIT
+ }
+#include "paranoia.h"
+void part4(VOID){
+*/
+ Milestone = 50;
+ /*=============================================*/
+ TstCond (Failure, ((F9 + U1) - Half == Half)
+ && ((BMinusU2 + U2 ) - One == Radix - One),
+ "Incomplete carry-propagation in Addition");
+ X = One - U1 * U1;
+ Y = One + U2 * (One - U2);
+ Z = F9 - Half;
+ X = (X - Half) - Z;
+ Y = Y - One;
+ if ((X == Zero) && (Y == Zero)) {
+ RAddSub = Chopped;
+ printf("Add/Subtract appears to be chopped.\n");
+ }
+ if (GAddSub == Yes) {
+ X = (Half + U2) * U2;
+ Y = (Half - U2) * U2;
+ X = One + X;
+ Y = One + Y;
+ X = (One + U2) - X;
+ Y = One - Y;
+ if ((X == Zero) && (Y == Zero)) {
+ X = (Half + U2) * U1;
+ Y = (Half - U2) * U1;
+ X = One - X;
+ Y = One - Y;
+ X = F9 - X;
+ Y = One - Y;
+ if ((X == Zero) && (Y == Zero)) {
+ RAddSub = Rounded;
+ printf("Addition/Subtraction appears to round correctly.\n");
+ if (GAddSub == No) notify("Add/Subtract");
+ }
+ else printf("Addition/Subtraction neither rounds nor chops.\n");
+ }
+ else printf("Addition/Subtraction neither rounds nor chops.\n");
+ }
+ else printf("Addition/Subtraction neither rounds nor chops.\n");
+ S = One;
+ X = One + Half * (One + Half);
+ Y = (One + U2) * Half;
+ Z = X - Y;
+ T = Y - X;
+ StickyBit = Z + T;
+ if (StickyBit != Zero) {
+ S = Zero;
+ BadCond(Flaw, "(X - Y) + (Y - X) is non zero!\n");
+ }
+ StickyBit = Zero;
+ if ((GMult == Yes) && (GDiv == Yes) && (GAddSub == Yes)
+ && (RMult == Rounded) && (RDiv == Rounded)
+ && (RAddSub == Rounded) && (FLOOR(RadixD2) == RadixD2)) {
+ printf("Checking for sticky bit.\n");
+ X = (Half + U1) * U2;
+ Y = Half * U2;
+ Z = One + Y;
+ T = One + X;
+ if ((Z - One <= Zero) && (T - One >= U2)) {
+ Z = T + Y;
+ Y = Z - X;
+ if ((Z - T >= U2) && (Y - T == Zero)) {
+ X = (Half + U1) * U1;
+ Y = Half * U1;
+ Z = One - Y;
+ T = One - X;
+ if ((Z - One == Zero) && (T - F9 == Zero)) {
+ Z = (Half - U1) * U1;
+ T = F9 - Z;
+ Q = F9 - Y;
+ if ((T - F9 == Zero) && (F9 - U1 - Q == Zero)) {
+ Z = (One + U2) * OneAndHalf;
+ T = (OneAndHalf + U2) - Z + U2;
+ X = One + Half / Radix;
+ Y = One + Radix * U2;
+ Z = X * Y;
+ if (T == Zero && X + Radix * U2 - Z == Zero) {
+ if (Radix != Two) {
+ X = Two + U2;
+ Y = X / Two;
+ if ((Y - One == Zero)) StickyBit = S;
+ }
+ else StickyBit = S;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (StickyBit == One) printf("Sticky bit apparently used correctly.\n");
+ else printf("Sticky bit used incorrectly or not at all.\n");
+ TstCond (Flaw, !(GMult == No || GDiv == No || GAddSub == No ||
+ RMult == Other || RDiv == Other || RAddSub == Other),
+ "lack(s) of guard digits or failure(s) to correctly round or chop\n\
+(noted above) count as one flaw in the final tally below");
+ /*=============================================*/
+ Milestone = 60;
+ /*=============================================*/
+ printf("\n");
+ printf("Does Multiplication commute? ");
+ printf("Testing on %d random pairs.\n", NoTrials);
+ Random9 = SQRT(3.0);
+ Random1 = Third;
+ I = 1;
+ do {
+ X = Random();
+ Y = Random();
+ Z9 = Y * X;
+ Z = X * Y;
+ Z9 = Z - Z9;
+ I = I + 1;
+ } while ( ! ((I > NoTrials) || (Z9 != Zero)));
+ if (I == NoTrials) {
+ Random1 = One + Half / Three;
+ Random2 = (U2 + U1) + One;
+ Z = Random1 * Random2;
+ Y = Random2 * Random1;
+ Z9 = (One + Half / Three) * ((U2 + U1) + One) - (One + Half /
+ Three) * ((U2 + U1) + One);
+ }
+ if (! ((I == NoTrials) || (Z9 == Zero)))
+ BadCond(Defect, "X * Y == Y * X trial fails.\n");
+ else printf(" No failures found in %d integer pairs.\n", NoTrials);
+ /*=============================================*/
+ Milestone = 70;
+ /*=============================================*/
+ printf("\nRunning test of square root(x).\n");
+ TstCond (Failure, (Zero == SQRT(Zero))
+ && (- Zero == SQRT(- Zero))
+ && (One == SQRT(One)), "Square root of 0.0, -0.0 or 1.0 wrong");
+ MinSqEr = Zero;
+ MaxSqEr = Zero;
+ J = Zero;
+ X = Radix;
+ OneUlp = U2;
+ SqXMinX (Serious);
+ X = BInvrse;
+ OneUlp = BInvrse * U1;
+ SqXMinX (Serious);
+ X = U1;
+ OneUlp = U1 * U1;
+ SqXMinX (Serious);
+ if (J != Zero) Pause();
+ printf("Testing if sqrt(X * X) == X for %d Integers X.\n", NoTrials);
+ J = Zero;
+ X = Two;
+ Y = Radix;
+ if ((Radix != One)) do {
+ X = Y;
+ Y = Radix * Y;
+ } while ( ! ((Y - X >= NoTrials)));
+ OneUlp = X * U2;
+ I = 1;
+ while (I <= NoTrials) {
+ X = X + One;
+ SqXMinX (Defect);
+ if (J > Zero) break;
+ I = I + 1;
+ }
+ printf("Test for sqrt monotonicity.\n");
+ I = - 1;
+ X = BMinusU2;
+ Y = Radix;
+ Z = Radix + Radix * U2;
+ NotMonot = False;
+ Monot = False;
+ while ( ! (NotMonot || Monot)) {
+ I = I + 1;
+ X = SQRT(X);
+ Q = SQRT(Y);
+ Z = SQRT(Z);
+ if ((X > Q) || (Q > Z)) NotMonot = True;
+ else {
+ Q = FLOOR(Q + Half);
+ if (!(I > 0 || Radix == Q * Q)) Monot = True;
+ else if (I > 0) {
+ if (I > 1) Monot = True;
+ else {
+ Y = Y * BInvrse;
+ X = Y - U1;
+ Z = Y + U1;
+ }
+ }
+ else {
+ Y = Q;
+ X = Y - U2;
+ Z = Y + U2;
+ }
+ }
+ }
+ if (Monot) printf("sqrt has passed a test for Monotonicity.\n");
+ else {
+ BadCond(Defect, "");
+ printf("sqrt(X) is non-monotonic for X near %.7e .\n", Y);
+ }
+ /*=============================================*/
+ /*SPLIT
+ }
+#include "paranoia.h"
+void part5(VOID){
+*/
+ Milestone = 80;
+ /*=============================================*/
+ MinSqEr = MinSqEr + Half;
+ MaxSqEr = MaxSqEr - Half;
+ Y = (SQRT(One + U2) - One) / U2;
+ SqEr = (Y - One) + U2 / Eight;
+ if (SqEr > MaxSqEr) MaxSqEr = SqEr;
+ SqEr = Y + U2 / Eight;
+ if (SqEr < MinSqEr) MinSqEr = SqEr;
+ Y = ((SQRT(F9) - U2) - (One - U2)) / U1;
+ SqEr = Y + U1 / Eight;
+ if (SqEr > MaxSqEr) MaxSqEr = SqEr;
+ SqEr = (Y + One) + U1 / Eight;
+ if (SqEr < MinSqEr) MinSqEr = SqEr;
+ OneUlp = U2;
+ X = OneUlp;
+ for( Indx = 1; Indx <= 3; ++Indx) {
+ Y = SQRT((X + U1 + X) + F9);
+ Y = ((Y - U2) - ((One - U2) + X)) / OneUlp;
+ Z = ((U1 - X) + F9) * Half * X * X / OneUlp;
+ SqEr = (Y + Half) + Z;
+ if (SqEr < MinSqEr) MinSqEr = SqEr;
+ SqEr = (Y - Half) + Z;
+ if (SqEr > MaxSqEr) MaxSqEr = SqEr;
+ if (((Indx == 1) || (Indx == 3)))
+ X = OneUlp * Sign (X) * FLOOR(Eight / (Nine * SQRT(OneUlp)));
+ else {
+ OneUlp = U1;
+ X = - OneUlp;
+ }
+ }
+ /*=============================================*/
+ Milestone = 85;
+ /*=============================================*/
+ SqRWrng = False;
+ Anomaly = False;
+ RSqrt = Other; /* ~dgh */
+ if (Radix != One) {
+ printf("Testing whether sqrt is rounded or chopped.\n");
+ D = FLOOR(Half + POW(Radix, One + Precision - FLOOR(Precision)));
+ /* ... == Radix^(1 + fract) if (Precision == Integer + fract. */
+ X = D / Radix;
+ Y = D / A1;
+ if ((X != FLOOR(X)) || (Y != FLOOR(Y))) {
+ Anomaly = True;
+ }
+ else {
+ X = Zero;
+ Z2 = X;
+ Y = One;
+ Y2 = Y;
+ Z1 = Radix - One;
+ FourD = Four * D;
+ do {
+ if (Y2 > Z2) {
+ Q = Radix;
+ Y1 = Y;
+ do {
+ X1 = FABS(Q + FLOOR(Half - Q / Y1) * Y1);
+ Q = Y1;
+ Y1 = X1;
+ } while ( ! (X1 <= Zero));
+ if (Q <= One) {
+ Z2 = Y2;
+ Z = Y;
+ }
+ }
+ Y = Y + Two;
+ X = X + Eight;
+ Y2 = Y2 + X;
+ if (Y2 >= FourD) Y2 = Y2 - FourD;
+ } while ( ! (Y >= D));
+ X8 = FourD - Z2;
+ Q = (X8 + Z * Z) / FourD;
+ X8 = X8 / Eight;
+ if (Q != FLOOR(Q)) Anomaly = True;
+ else {
+ Break = False;
+ do {
+ X = Z1 * Z;
+ X = X - FLOOR(X / Radix) * Radix;
+ if (X == One)
+ Break = True;
+ else
+ Z1 = Z1 - One;
+ } while ( ! (Break || (Z1 <= Zero)));
+ if ((Z1 <= Zero) && (! Break)) Anomaly = True;
+ else {
+ if (Z1 > RadixD2) Z1 = Z1 - Radix;
+ do {
+ NewD();
+ } while ( ! (U2 * D >= F9));
+ if (D * Radix - D != W - D) Anomaly = True;
+ else {
+ Z2 = D;
+ I = 0;
+ Y = D + (One + Z) * Half;
+ X = D + Z + Q;
+ SR3750();
+ Y = D + (One - Z) * Half + D;
+ X = D - Z + D;
+ X = X + Q + X;
+ SR3750();
+ NewD();
+ if (D - Z2 != W - Z2) Anomaly = True;
+ else {
+ Y = (D - Z2) + (Z2 + (One - Z) * Half);
+ X = (D - Z2) + (Z2 - Z + Q);
+ SR3750();
+ Y = (One + Z) * Half;
+ X = Q;
+ SR3750();
+ if (I == 0) Anomaly = True;
+ }
+ }
+ }
+ }
+ }
+ if ((I == 0) || Anomaly) {
+ BadCond(Failure, "Anomalous arithmetic with Integer < ");
+ printf("Radix^Precision = %.7e\n", W);
+ printf(" fails test whether sqrt rounds or chops.\n");
+ SqRWrng = True;
+ }
+ }
+ if (! Anomaly) {
+ if (! ((MinSqEr < Zero) || (MaxSqEr > Zero))) {
+ RSqrt = Rounded;
+ printf("Square root appears to be correctly rounded.\n");
+ }
+ else {
+ if ((MaxSqEr + U2 > U2 - Half) || (MinSqEr > Half)
+ || (MinSqEr + Radix < Half)) SqRWrng = True;
+ else {
+ RSqrt = Chopped;
+ printf("Square root appears to be chopped.\n");
+ }
+ }
+ }
+ if (SqRWrng) {
+ printf("Square root is neither chopped nor correctly rounded.\n");
+ printf("Observed errors run from %.7e ", MinSqEr - Half);
+ printf("to %.7e ulps.\n", Half + MaxSqEr);
+ TstCond (Serious, MaxSqEr - MinSqEr < Radix * Radix,
+ "sqrt gets too many last digits wrong");
+ }
+ /*=============================================*/
+ Milestone = 90;
+ /*=============================================*/
+ Pause();
+ printf("Testing powers Z^i for small Integers Z and i.\n");
+ N = 0;
+ /* ... test powers of zero. */
+ I = 0;
+ Z = -Zero;
+ M = 3;
+ Break = False;
+ do {
+ X = One;
+ SR3980();
+ if (I <= 10) {
+ I = 1023;
+ SR3980();
+ }
+ if (Z == MinusOne) Break = True;
+ else {
+ Z = MinusOne;
+ /* .. if(-1)^N is invalid, replace MinusOne by One. */
+ I = - 4;
+ }
+ } while ( ! Break);
+ PrintIfNPositive();
+ N1 = N;
+ N = 0;
+ Z = A1;
+ M = (int)FLOOR(Two * LOG(W) / LOG(A1));
+ Break = False;
+ do {
+ X = Z;
+ I = 1;
+ SR3980();
+ if (Z == AInvrse) Break = True;
+ else Z = AInvrse;
+ } while ( ! (Break));
+ /*=============================================*/
+ Milestone = 100;
+ /*=============================================*/
+ /* Powers of Radix have been tested, */
+ /* next try a few primes */
+ M = NoTrials;
+ Z = Three;
+ do {
+ X = Z;
+ I = 1;
+ SR3980();
+ do {
+ Z = Z + Two;
+ } while ( Three * FLOOR(Z / Three) == Z );
+ } while ( Z < Eight * Three );
+ if (N > 0) {
+ printf("Errors like this may invalidate financial calculations\n");
+ printf("\tinvolving interest rates.\n");
+ }
+ PrintIfNPositive();
+ N += N1;
+ if (N == 0) printf("... no discrepancies found.\n");
+ if (N > 0) Pause();
+ else printf("\n");
+ /*=============================================*/
+ /*SPLIT
+ }
+#include "paranoia.h"
+void part6(VOID){
+*/
+ Milestone = 110;
+ /*=============================================*/
+ printf("Seeking Underflow thresholds UfThold and E0.\n");
+ D = U1;
+ if (Precision != FLOOR(Precision)) {
+ D = BInvrse;
+ X = Precision;
+ do {
+ D = D * BInvrse;
+ X = X - One;
+ } while ( X > Zero);
+ }
+ Y = One;
+ Z = D;
+ /* ... D is power of 1/Radix < 1. */
+ do {
+ C = Y;
+ Y = Z;
+ Z = Y * Y;
+ } while ((Y > Z) && (Z + Z > Z));
+ Y = C;
+ Z = Y * D;
+ do {
+ C = Y;
+ Y = Z;
+ Z = Y * D;
+ } while ((Y > Z) && (Z + Z > Z));
+ if (Radix < Two) HInvrse = Two;
+ else HInvrse = Radix;
+ H = One / HInvrse;
+ /* ... 1/HInvrse == H == Min(1/Radix, 1/2) */
+ CInvrse = One / C;
+ E0 = C;
+ Z = E0 * H;
+ /* ...1/Radix^(BIG Integer) << 1 << CInvrse == 1/C */
+ do {
+ Y = E0;
+ E0 = Z;
+ Z = E0 * H;
+ } while ((E0 > Z) && (Z + Z > Z));
+ UfThold = E0;
+ E1 = Zero;
+ Q = Zero;
+ E9 = U2;
+ S = One + E9;
+ D = C * S;
+ if (D <= C) {
+ E9 = Radix * U2;
+ S = One + E9;
+ D = C * S;
+ if (D <= C) {
+ BadCond(Failure, "multiplication gets too many last digits wrong.\n");
+ Underflow = E0;
+ Y1 = Zero;
+ PseudoZero = Z;
+ Pause();
+ }
+ }
+ else {
+ Underflow = D;
+ PseudoZero = Underflow * H;
+ UfThold = Zero;
+ do {
+ Y1 = Underflow;
+ Underflow = PseudoZero;
+ if (E1 + E1 <= E1) {
+ Y2 = Underflow * HInvrse;
+ E1 = FABS(Y1 - Y2);
+ Q = Y1;
+ if ((UfThold == Zero) && (Y1 != Y2)) UfThold = Y1;
+ }
+ PseudoZero = PseudoZero * H;
+ } while ((Underflow > PseudoZero)
+ && (PseudoZero + PseudoZero > PseudoZero));
+ }
+ /* Comment line 4530 .. 4560 */
+ if (PseudoZero != Zero) {
+ printf("\n");
+ Z = PseudoZero;
+ /* ... Test PseudoZero for "phoney- zero" violates */
+ /* ... PseudoZero < Underflow or PseudoZero < PseudoZero + PseudoZero
+ ... */
+ if (PseudoZero <= Zero) {
+ BadCond(Failure, "Positive expressions can underflow to an\n");
+ printf("allegedly negative value\n");
+ printf("PseudoZero that prints out as: %g .\n", PseudoZero);
+ X = - PseudoZero;
+ if (X <= Zero) {
+ printf("But -PseudoZero, which should be\n");
+ printf("positive, isn't; it prints out as %g .\n", X);
+ }
+ }
+ else {
+ BadCond(Flaw, "Underflow can stick at an allegedly positive\n");
+ printf("value PseudoZero that prints out as %g .\n", PseudoZero);
+ }
+ TstPtUf();
+ }
+ /*=============================================*/
+ Milestone = 120;
+ /*=============================================*/
+ if (CInvrse * Y > CInvrse * Y1) {
+ S = H * S;
+ E0 = Underflow;
+ }
+ if (! ((E1 == Zero) || (E1 == E0))) {
+ BadCond(Defect, "");
+ if (E1 < E0) {
+ printf("Products underflow at a higher");
+ printf(" threshold than differences.\n");
+ if (PseudoZero == Zero)
+ E0 = E1;
+ }
+ else {
+ printf("Difference underflows at a higher");
+ printf(" threshold than products.\n");
+ }
+ }
+ printf("Smallest strictly positive number found is E0 = %g .\n", E0);
+ Z = E0;
+ TstPtUf();
+ Underflow = E0;
+ if (N == 1) Underflow = Y;
+ I = 4;
+ if (E1 == Zero) I = 3;
+ if (UfThold == Zero) I = I - 2;
+ UfNGrad = True;
+ switch (I) {
+ case 1:
+ UfThold = Underflow;
+ if ((CInvrse * Q) != ((CInvrse * Y) * S)) {
+ UfThold = Y;
+ BadCond(Failure, "Either accuracy deteriorates as numbers\n");
+ printf("approach a threshold = %.17e\n", UfThold);;
+ printf(" coming down from %.17e\n", C);
+ printf(" or else multiplication gets too many last digits wrong.\n");
+ }
+ Pause();
+ break;
+
+ case 2:
+ BadCond(Failure, "Underflow confuses Comparison, which alleges that\n");
+ printf("Q == Y while denying that |Q - Y| == 0; these values\n");
+ printf("print out as Q = %.17e, Y = %.17e .\n", Q, Y2);
+ printf ("|Q - Y| = %.17e .\n" , FABS(Q - Y2));
+ UfThold = Q;
+ break;
+
+ case 3:
+ X = X;
+ break;
+
+ case 4:
+ if ((Q == UfThold) && (E1 == E0)
+ && (FABS( UfThold - E1 / E9) <= E1)) {
+ UfNGrad = False;
+ printf("Underflow is gradual; it incurs Absolute Error =\n");
+ printf("(roundoff in UfThold) < E0.\n");
+ Y = E0 * CInvrse;
+ Y = Y * (OneAndHalf + U2);
+ X = CInvrse * (One + U2);
+ Y = Y / X;
+ IEEE = (Y == E0);
+ }
+ }
+ if (UfNGrad) {
+ printf("\n");
+ sigsave = sigfpe;
+ if (setjmp(ovfl_buf)) {
+ printf("Underflow / UfThold failed!\n");
+ R = H + H;
+ }
+ else R = SQRT(Underflow / UfThold);
+ sigsave = 0;
+ if (R <= H) {
+ Z = R * UfThold;
+ X = Z * (One + R * H * (One + H));
+ }
+ else {
+ Z = UfThold;
+ X = Z * (One + H * H * (One + H));
+ }
+ if (! ((X == Z) || (X - Z != Zero))) {
+ BadCond(Flaw, "");
+ printf("X = %.17e\n\tis not equal to Z = %.17e .\n", X, Z);
+ Z9 = X - Z;
+ printf("yet X - Z yields %.17e .\n", Z9);
+ printf(" Should this NOT signal Underflow, ");
+ printf("this is a SERIOUS DEFECT\nthat causes ");
+ printf("confusion when innocent statements like\n");;
+ printf(" if (X == Z) ... else");
+ printf(" ... (f(X) - f(Z)) / (X - Z) ...\n");
+ printf("encounter Division by Zero although actually\n");
+ sigsave = sigfpe;
+ if (setjmp(ovfl_buf)) printf("X / Z fails!\n");
+ else printf("X / Z = 1 + %g .\n", (X / Z - Half) - Half);
+ sigsave = 0;
+ }
+ }
+ printf("The Underflow threshold is %.17e, %s\n", UfThold,
+ " below which");
+ printf("calculation may suffer larger Relative error than ");
+ printf("merely roundoff.\n");
+ Y2 = U1 * U1;
+ Y = Y2 * Y2;
+ Y2 = Y * U1;
+ if (Y2 <= UfThold) {
+ if (Y > E0) {
+ BadCond(Defect, "");
+ I = 5;
+ }
+ else {
+ BadCond(Serious, "");
+ I = 4;
+ }
+ printf("Range is too narrow; U1^%d Underflows.\n", I);
+ }
+ /*=============================================*/
+ /*SPLIT
+ }
+#include "paranoia.h"
+void part7(VOID){
+*/
+ Milestone = 130;
+ /*=============================================*/
+ Y = - FLOOR(Half - TwoForty * LOG(UfThold) / LOG(HInvrse)) / TwoForty;
+ Y2 = Y + Y;
+ printf("Since underflow occurs below the threshold\n");
+ printf("UfThold = (%.17e) ^ (%.17e)\nonly underflow ", HInvrse, Y);
+ printf("should afflict the expression\n\t(%.17e) ^ (%.17e);\n",
+ HInvrse, Y2);
+ printf("actually calculating yields:");
+ if (setjmp(ovfl_buf)) {
+ sigsave = 0;
+ BadCond(Serious, "trap on underflow.\n");
+ }
+ else {
+ sigsave = sigfpe;
+ V9 = POW(HInvrse, Y2);
+ sigsave = 0;
+ printf(" %.17e .\n", V9);
+ if (! ((V9 >= Zero) && (V9 <= (Radix + Radix + E9) * UfThold))) {
+ BadCond(Serious, "this is not between 0 and underflow\n");
+ printf(" threshold = %.17e .\n", UfThold);
+ }
+ else if (! (V9 > UfThold * (One + E9)))
+ printf("This computed value is O.K.\n");
+ else {
+ BadCond(Defect, "this is not between 0 and underflow\n");
+ printf(" threshold = %.17e .\n", UfThold);
+ }
+ }
+ /*=============================================*/
+ Milestone = 140;
+ /*=============================================*/
+ printf("\n");
+ /* ...calculate Exp2 == exp(2) == 7.389056099... */
+ X = Zero;
+ I = 2;
+ Y = Two * Three;
+ Q = Zero;
+ N = 0;
+ do {
+ Z = X;
+ I = I + 1;
+ Y = Y / (I + I);
+ R = Y + Q;
+ X = Z + R;
+ Q = (Z - X) + R;
+ } while(X > Z);
+ Z = (OneAndHalf + One / Eight) + X / (OneAndHalf * ThirtyTwo);
+ X = Z * Z;
+ Exp2 = X * X;
+ X = F9;
+ Y = X - U1;
+ printf("Testing X^((X + 1) / (X - 1)) vs. exp(2) = %.17e as X -> 1.\n",
+ Exp2);
+ for(I = 1;;) {
+ Z = X - BInvrse;
+ Z = (X + One) / (Z - (One - BInvrse));
+ Q = POW(X, Z) - Exp2;
+ if (FABS(Q) > TwoForty * U2) {
+ N = 1;
+ V9 = (X - BInvrse) - (One - BInvrse);
+ BadCond(Defect, "Calculated");
+ printf(" %.17e for\n", POW(X,Z));
+ printf("\t(1 + (%.17e) ^ (%.17e);\n", V9, Z);
+ printf("\tdiffers from correct value by %.17e .\n", Q);
+ printf("\tThis much error may spoil financial\n");
+ printf("\tcalculations involving tiny interest rates.\n");
+ break;
+ }
+ else {
+ Z = (Y - X) * Two + Y;
+ X = Y;
+ Y = Z;
+ Z = One + (X - F9)*(X - F9);
+ if (Z > One && I < NoTrials) I++;
+ else {
+ if (X > One) {
+ if (N == 0)
+ printf("Accuracy seems adequate.\n");
+ break;
+ }
+ else {
+ X = One + U2;
+ Y = U2 + U2;
+ Y += X;
+ I = 1;
+ }
+ }
+ }
+ }
+ /*=============================================*/
+ Milestone = 150;
+ /*=============================================*/
+ printf("Testing powers Z^Q at four nearly extreme values.\n");
+ N = 0;
+ Z = A1;
+ Q = FLOOR(Half - LOG(C) / LOG(A1));
+ Break = False;
+ do {
+ X = CInvrse;
+ Y = POW(Z, Q);
+ IsYeqX();
+ Q = - Q;
+ X = C;
+ Y = POW(Z, Q);
+ IsYeqX();
+ if (Z < One) Break = True;
+ else Z = AInvrse;
+ } while ( ! (Break));
+ PrintIfNPositive();
+ if (N == 0) printf(" ... no discrepancies found.\n");
+ printf("\n");
+
+ /*=============================================*/
+ Milestone = 160;
+ /*=============================================*/
+ Pause();
+ printf("Searching for Overflow threshold:\n");
+ printf("This may generate an error.\n");
+ Y = - CInvrse;
+ V9 = HInvrse * Y;
+ sigsave = sigfpe;
+ if (setjmp(ovfl_buf)) { I = 0; V9 = Y; goto overflow; }
+ do {
+ V = Y;
+ Y = V9;
+ V9 = HInvrse * Y;
+ } while(V9 < Y);
+ I = 1;
+overflow:
+ sigsave = 0;
+ Z = V9;
+ printf("Can `Z = -Y' overflow?\n");
+ printf("Trying it on Y = %.17e .\n", Y);
+ V9 = - Y;
+ V0 = V9;
+ if (V - Y == V + V0) printf("Seems O.K.\n");
+ else {
+ printf("finds a ");
+ BadCond(Flaw, "-(-Y) differs from Y.\n");
+ }
+ if (Z != Y) {
+ BadCond(Serious, "");
+ printf("overflow past %.17e\n\tshrinks to %.17e .\n", Y, Z);
+ }
+ if (I) {
+ Y = V * (HInvrse * U2 - HInvrse);
+ Z = Y + ((One - HInvrse) * U2) * V;
+ if (Z < V0) Y = Z;
+ if (Y < V0) V = Y;
+ if (V0 - V < V0) V = V0;
+ }
+ else {
+ V = Y * (HInvrse * U2 - HInvrse);
+ V = V + ((One - HInvrse) * U2) * Y;
+ }
+ printf("Overflow threshold is V = %.17e .\n", V);
+ if (I) printf("Overflow saturates at V0 = %.17e .\n", V0);
+ else printf("There is no saturation value because \
+the system traps on overflow.\n");
+ V9 = V * One;
+ printf("No Overflow should be signaled for V * 1 = %.17e\n", V9);
+ V9 = V / One;
+ printf(" nor for V / 1 = %.17e .\n", V9);
+ printf("Any overflow signal separating this * from the one\n");
+ printf("above is a DEFECT.\n");
+ /*=============================================*/
+ Milestone = 170;
+ /*=============================================*/
+ if (!(-V < V && -V0 < V0 && -UfThold < V && UfThold < V)) {
+ BadCond(Failure, "Comparisons involving ");
+ printf("+-%g, +-%g\nand +-%g are confused by Overflow.",
+ V, V0, UfThold);
+ }
+ /*=============================================*/
+ Milestone = 175;
+ /*=============================================*/
+ printf("\n");
+ for(Indx = 1; Indx <= 3; ++Indx) {
+ switch (Indx) {
+ case 1: Z = UfThold; break;
+ case 2: Z = E0; break;
+ case 3: Z = PseudoZero; break;
+ }
+ if (Z != Zero) {
+ V9 = SQRT(Z);
+ Y = V9 * V9;
+ if (Y / (One - Radix * E9) < Z
+ || Y > (One + Radix * E9) * Z) { /* dgh: + E9 --> * E9 */
+ if (V9 > U1) BadCond(Serious, "");
+ else BadCond(Defect, "");
+ printf("Comparison alleges that what prints as Z = %.17e\n", Z);
+ printf(" is too far from sqrt(Z) ^ 2 = %.17e .\n", Y);
+ }
+ }
+ }
+ /*=============================================*/
+ Milestone = 180;
+ /*=============================================*/
+ for(Indx = 1; Indx <= 2; ++Indx) {
+ if (Indx == 1) Z = V;
+ else Z = V0;
+ V9 = SQRT(Z);
+ X = (One - Radix * E9) * V9;
+ V9 = V9 * X;
+ if (((V9 < (One - Two * Radix * E9) * Z) || (V9 > Z))) {
+ Y = V9;
+ if (X < W) BadCond(Serious, "");
+ else BadCond(Defect, "");
+ printf("Comparison alleges that Z = %17e\n", Z);
+ printf(" is too far from sqrt(Z) ^ 2 (%.17e) .\n", Y);
+ }
+ }
+ /*=============================================*/
+ /*SPLIT
+ }
+#include "paranoia.h"
+int part8(VOID){
+*/
+ Milestone = 190;
+ /*=============================================*/
+ Pause();
+ X = UfThold * V;
+ Y = Radix * Radix;
+ if (X*Y < One || X > Y) {
+ if (X * Y < U1 || X > Y/U1) BadCond(Defect, "Badly");
+ else BadCond(Flaw, "");
+
+ printf(" unbalanced range; UfThold * V = %.17e\n\t%s\n",
+ X, "is too far from 1.\n");
+ }
+ /*=============================================*/
+ Milestone = 200;
+ /*=============================================*/
+ for (Indx = 1; Indx <= 5; ++Indx) {
+ X = F9;
+ switch (Indx) {
+ case 2: X = One + U2; break;
+ case 3: X = V; break;
+ case 4: X = UfThold; break;
+ case 5: X = Radix;
+ }
+ Y = X;
+ sigsave = sigfpe;
+ if (setjmp(ovfl_buf))
+ printf(" X / X traps when X = %g\n", X);
+ else {
+ V9 = (Y / X - Half) - Half;
+ if (V9 == Zero) continue;
+ if (V9 == - U1 && Indx < 5) BadCond(Flaw, "");
+ else BadCond(Serious, "");
+ printf(" X / X differs from 1 when X = %.17e\n", X);
+ printf(" instead, X / X - 1/2 - 1/2 = %.17e .\n", V9);
+ }
+ sigsave = 0;
+ }
+ /*=============================================*/
+ Milestone = 210;
+ /*=============================================*/
+ MyZero = Zero;
+ printf("\n");
+ printf("What message and/or values does Division by Zero produce?\n") ;
+#ifndef NOPAUSE
+ printf("This can interupt your program. You can ");
+ printf("skip this part if you wish.\n");
+ printf("Do you wish to compute 1 / 0? ");
+ fflush(stdout);
+ read (KEYBOARD, ch, 8);
+ if ((ch[0] == 'Y') || (ch[0] == 'y')) {
+#endif
+ sigsave = sigfpe;
+ printf(" Trying to compute 1 / 0 produces ...");
+ if (!setjmp(ovfl_buf)) printf(" %.7e .\n", One / MyZero);
+ sigsave = 0;
+#ifndef NOPAUSE
+ }
+ else printf("O.K.\n");
+ printf("\nDo you wish to compute 0 / 0? ");
+ fflush(stdout);
+ read (KEYBOARD, ch, 80);
+ if ((ch[0] == 'Y') || (ch[0] == 'y')) {
+#endif
+ sigsave = sigfpe;
+ printf("\n Trying to compute 0 / 0 produces ...");
+ if (!setjmp(ovfl_buf)) printf(" %.7e .\n", Zero / MyZero);
+ sigsave = 0;
+#ifndef NOPAUSE
+ }
+ else printf("O.K.\n");
+#endif
+ /*=============================================*/
+ Milestone = 220;
+ /*=============================================*/
+ Pause();
+ printf("\n");
+ {
+ static char *msg[] = {
+ "FAILUREs encountered =",
+ "SERIOUS DEFECTs discovered =",
+ "DEFECTs discovered =",
+ "FLAWs discovered =" };
+ int i;
+ for(i = 0; i < 4; i++) if (ErrCnt[i])
+ printf("The number of %-29s %d.\n",
+ msg[i], ErrCnt[i]);
+ }
+ printf("\n");
+ if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[Defect]
+ + ErrCnt[Flaw]) > 0) {
+ if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[
+ Defect] == 0) && (ErrCnt[Flaw] > 0)) {
+ printf("The arithmetic diagnosed seems ");
+ printf("Satisfactory though flawed.\n");
+ }
+ if ((ErrCnt[Failure] + ErrCnt[Serious] == 0)
+ && ( ErrCnt[Defect] > 0)) {
+ printf("The arithmetic diagnosed may be Acceptable\n");
+ printf("despite inconvenient Defects.\n");
+ }
+ if ((ErrCnt[Failure] + ErrCnt[Serious]) > 0) {
+ printf("The arithmetic diagnosed has ");
+ printf("unacceptable Serious Defects.\n");
+ }
+ if (ErrCnt[Failure] > 0) {
+ printf("Potentially fatal FAILURE may have spoiled this");
+ printf(" program's subsequent diagnoses.\n");
+ }
+ }
+ else {
+ printf("No failures, defects nor flaws have been discovered.\n");
+ if (! ((RMult == Rounded) && (RDiv == Rounded)
+ && (RAddSub == Rounded) && (RSqrt == Rounded)))
+ printf("The arithmetic diagnosed seems Satisfactory.\n");
+ else {
+ if (StickyBit >= One &&
+ (Radix - Two) * (Radix - Nine - One) == Zero) {
+ printf("Rounding appears to conform to ");
+ printf("the proposed IEEE standard P");
+ if ((Radix == Two) &&
+ ((Precision - Four * Three * Two) *
+ ( Precision - TwentySeven -
+ TwentySeven + One) == Zero))
+ printf("754");
+ else printf("854");
+ if (IEEE) printf(".\n");
+ else {
+ printf(",\nexcept for possibly Double Rounding");
+ printf(" during Gradual Underflow.\n");
+ }
+ }
+ printf("The arithmetic diagnosed appears to be Excellent!\n");
+ }
+ }
+ if (fpecount)
+ printf("\nA total of %d floating point exceptions were registered.\n",
+ fpecount);
+ printf("END OF TEST.\n");
+ return 0;
+ }
+
+/*SPLIT subs.c
+#include "paranoia.h"
+*/
+
+ FLOAT
+Sign (FP X)
+#ifdef KR_headers
+FLOAT X;
+#endif
+{ return X >= 0. ? 1.0 : -1.0; }
+
+ void
+Pause(VOID)
+{
+#ifndef NOPAUSE
+ char ch[8];
+
+ printf("\nTo continue, press RETURN");
+ fflush(stdout);
+ read(KEYBOARD, ch, 8);
+#endif
+ printf("\nDiagnosis resumes after milestone Number %d", Milestone);
+ printf(" Page: %d\n\n", PageNo);
+ ++Milestone;
+ ++PageNo;
+ }
+
+ void
+TstCond (INT K, INT Valid, CHARP T)
+#ifdef KR_headers
+int K, Valid;
+char *T;
+#endif
+{ if (! Valid) { BadCond(K,T); printf(".\n"); } }
+
+ void
+BadCond(INT K, CHARP T)
+#ifdef KR_headers
+int K;
+char *T;
+#endif
+{
+ static char *msg[] = { "FAILURE", "SERIOUS DEFECT", "DEFECT", "FLAW" };
+
+ ErrCnt [K] = ErrCnt [K] + 1;
+ printf("%s: %s", msg[K], T);
+ }
+
+
+ FLOAT
+Random(VOID)
+/* Random computes
+ X = (Random1 + Random9)^5
+ Random1 = X - FLOOR(X) + 0.000005 * X;
+ and returns the new value of Random1
+*/
+{
+ FLOAT X, Y;
+
+ X = Random1 + Random9;
+ Y = X * X;
+ Y = Y * Y;
+ X = X * Y;
+ Y = X - FLOOR(X);
+ Random1 = Y + X * 0.000005;
+ return(Random1);
+ }
+
+ void
+SqXMinX (INT ErrKind)
+#ifdef KR_headers
+int ErrKind;
+#endif
+{
+ FLOAT XA, XB;
+
+ XB = X * BInvrse;
+ XA = X - XB;
+ SqEr = ((SQRT(X * X) - XB) - XA) / OneUlp;
+ if (SqEr != Zero) {
+ if (SqEr < MinSqEr) MinSqEr = SqEr;
+ if (SqEr > MaxSqEr) MaxSqEr = SqEr;
+ J = J + 1.0;
+ BadCond(ErrKind, "\n");
+ printf("sqrt( %.17e) - %.17e = %.17e\n", X * X, X, OneUlp * SqEr);
+ printf("\tinstead of correct value 0 .\n");
+ }
+ }
+
+ void
+NewD(VOID)
+{
+ X = Z1 * Q;
+ X = FLOOR(Half - X / Radix) * Radix + X;
+ Q = (Q - X * Z) / Radix + X * X * (D / Radix);
+ Z = Z - Two * X * D;
+ if (Z <= Zero) {
+ Z = - Z;
+ Z1 = - Z1;
+ }
+ D = Radix * D;
+ }
+
+ void
+SR3750(VOID)
+{
+ if (! ((X - Radix < Z2 - Radix) || (X - Z2 > W - Z2))) {
+ I = I + 1;
+ X2 = SQRT(X * D);
+ Y2 = (X2 - Z2) - (Y - Z2);
+ X2 = X8 / (Y - Half);
+ X2 = X2 - Half * X2 * X2;
+ SqEr = (Y2 + Half) + (Half - X2);
+ if (SqEr < MinSqEr) MinSqEr = SqEr;
+ SqEr = Y2 - X2;
+ if (SqEr > MaxSqEr) MaxSqEr = SqEr;
+ }
+ }
+
+ void
+IsYeqX(VOID)
+{
+ if (Y != X) {
+ if (N <= 0) {
+ if (Z == Zero && Q <= Zero)
+ printf("WARNING: computing\n");
+ else BadCond(Defect, "computing\n");
+ printf("\t(%.17e) ^ (%.17e)\n", Z, Q);
+ printf("\tyielded %.17e;\n", Y);
+ printf("\twhich compared unequal to correct %.17e ;\n",
+ X);
+ printf("\t\tthey differ by %.17e .\n", Y - X);
+ }
+ N = N + 1; /* ... count discrepancies. */
+ }
+ }
+
+ void
+SR3980(VOID)
+{
+ do {
+ Q = (FLOAT) I;
+ Y = POW(Z, Q);
+ IsYeqX();
+ if (++I > M) break;
+ X = Z * X;
+ } while ( X < W );
+ }
+
+ void
+PrintIfNPositive(VOID)
+{
+ if (N > 0) printf("Similar discrepancies have occurred %d times.\n", N);
+ }
+
+ void
+TstPtUf(VOID)
+{
+ N = 0;
+ if (Z != Zero) {
+ printf("Since comparison denies Z = 0, evaluating ");
+ printf("(Z + Z) / Z should be safe.\n");
+ sigsave = sigfpe;
+ if (setjmp(ovfl_buf)) goto very_serious;
+ Q9 = (Z + Z) / Z;
+ printf("What the machine gets for (Z + Z) / Z is %.17e .\n",
+ Q9);
+ if (FABS(Q9 - Two) < Radix * U2) {
+ printf("This is O.K., provided Over/Underflow");
+ printf(" has NOT just been signaled.\n");
+ }
+ else {
+ if ((Q9 < One) || (Q9 > Two)) {
+very_serious:
+ N = 1;
+ ErrCnt [Serious] = ErrCnt [Serious] + 1;
+ printf("This is a VERY SERIOUS DEFECT!\n");
+ }
+ else {
+ N = 1;
+ ErrCnt [Defect] = ErrCnt [Defect] + 1;
+ printf("This is a DEFECT!\n");
+ }
+ }
+ sigsave = 0;
+ V9 = Z * One;
+ Random1 = V9;
+ V9 = One * Z;
+ Random2 = V9;
+ V9 = Z / One;
+ if ((Z == Random1) && (Z == Random2) && (Z == V9)) {
+ if (N > 0) Pause();
+ }
+ else {
+ N = 1;
+ BadCond(Defect, "What prints as Z = ");
+ printf("%.17e\n\tcompares different from ", Z);
+ if (Z != Random1) printf("Z * 1 = %.17e ", Random1);
+ if (! ((Z == Random2)
+ || (Random2 == Random1)))
+ printf("1 * Z == %g\n", Random2);
+ if (! (Z == V9)) printf("Z / 1 = %.17e\n", V9);
+ if (Random2 != Random1) {
+ ErrCnt [Defect] = ErrCnt [Defect] + 1;
+ BadCond(Defect, "Multiplication does not commute!\n");
+ printf("\tComparison alleges that 1 * Z = %.17e\n",
+ Random2);
+ printf("\tdiffers from Z * 1 = %.17e\n", Random1);
+ }
+ Pause();
+ }
+ }
+ }
+
+ void
+notify(CHARP s)
+#ifdef KR_headers
+ char *s;
+#endif
+{
+ printf("%s test appears to be inconsistent...\n", s);
+ printf(" PLEASE NOTIFY KARPINKSI!\n");
+ }
+
+/*SPLIT msgs.c
+#include "paranoia.h"
+*/
+
+ void
+msglist(CHARPP s)
+#ifdef KR_headers
+char **s;
+#endif
+{ while(*s) printf("%s\n", *s++); }
+
+ void
+Instructions(VOID)
+{
+ static char *instr[] = {
+ "Lest this program stop prematurely, i.e. before displaying\n",
+ " `END OF TEST',\n",
+ "try to persuade the computer NOT to terminate execution when an",
+ "error like Over/Underflow or Division by Zero occurs, but rather",
+ "to persevere with a surrogate value after, perhaps, displaying some",
+ "warning. If persuasion avails naught, don't despair but run this",
+ "program anyway to see how many milestones it passes, and then",
+ "amend it to make further progress.\n",
+ "Answer questions with Y, y, N or n (unless otherwise indicated).\n",
+ 0};
+
+ msglist(instr);
+ }
+
+ void
+Heading(VOID)
+{
+ static char *head[] = {
+ "Users are invited to help debug and augment this program so it will",
+ "cope with unanticipated and newly uncovered arithmetic pathologies.\n",
+ "Please send suggestions and interesting results to",
+ "\tRichard Karpinski",
+ "\tComputer Center U-76",
+ "\tUniversity of California",
+ "\tSan Francisco, CA 94143-0704, USA\n",
+ "In doing so, please include the following information:",
+#ifdef Single
+ "\tPrecision:\tsingle;",
+#else
+ "\tPrecision:\tdouble;",
+#endif
+ "\tVersion:\t10 February 1989;",
+ "\tComputer:\n",
+ "\tCompiler:\n",
+ "\tOptimization level:\n",
+ "\tOther relevant compiler options:",
+ 0};
+
+ msglist(head);
+ }
+
+ void
+Characteristics(VOID)
+{
+ static char *chars[] = {
+ "Running this program should reveal these characteristics:",
+ " Radix = 1, 2, 4, 8, 10, 16, 100, 256 ...",
+ " Precision = number of significant digits carried.",
+ " U2 = Radix/Radix^Precision = One Ulp",
+ "\t(OneUlpnit in the Last Place) of 1.000xxx .",
+ " U1 = 1/Radix^Precision = One Ulp of numbers a little less than 1.0 .",
+ " Adequacy of guard digits for Mult., Div. and Subt.",
+ " Whether arithmetic is chopped, correctly rounded, or something else",
+ "\tfor Mult., Div., Add/Subt. and Sqrt.",
+ " Whether a Sticky Bit used correctly for rounding.",
+ " UnderflowThreshold = an underflow threshold.",
+ " E0 and PseudoZero tell whether underflow is abrupt, gradual, or fuzzy.",
+ " V = an overflow threshold, roughly.",
+ " V0 tells, roughly, whether Infinity is represented.",
+ " Comparisions are checked for consistency with subtraction",
+ "\tand for contamination with pseudo-zeros.",
+ " Sqrt is tested. Y^X is not tested.",
+ " Extra-precise subexpressions are revealed but NOT YET tested.",
+ " Decimal-Binary conversion is NOT YET tested for accuracy.",
+ 0};
+
+ msglist(chars);
+ }
+
+ void
+History(VOID)
+{ /* History */
+ /* Converted from Brian Wichmann's Pascal version to C by Thos Sumner,
+ with further massaging by David M. Gay. */
+
+ static char *hist[] = {
+ "The program attempts to discriminate among",
+ " FLAWs, like lack of a sticky bit,",
+ " Serious DEFECTs, like lack of a guard digit, and",
+ " FAILUREs, like 2+2 == 5 .",
+ "Failures may confound subsequent diagnoses.\n",
+ "The diagnostic capabilities of this program go beyond an earlier",
+ "program called `MACHAR', which can be found at the end of the",
+ "book `Software Manual for the Elementary Functions' (1980) by",
+ "W. J. Cody and W. Waite. Although both programs try to discover",
+ "the Radix, Precision and range (over/underflow thresholds)",
+ "of the arithmetic, this program tries to cope with a wider variety",
+ "of pathologies, and to say how well the arithmetic is implemented.",
+ "\nThe program is based upon a conventional radix representation for",
+ "floating-point numbers, but also allows logarithmic encoding",
+ "as used by certain early WANG machines.\n",
+ "BASIC version of this program (C) 1983 by Prof. W. M. Kahan;",
+ "see source comments for more history.",
+ 0};
+
+ msglist(hist);
+ }
--- /dev/null
+#include <string.h>
+
+char *a = "bar";
+
+volatile char buf[] = "Hello World";
+
+int _start() {
+ return strlen("foo");
+}
--- /dev/null
+package tests;
+
+import org.xwt.mips.Runtime;
+import org.xwt.mips.Interpreter;
+
+class SpeedTest {
+ private static long start,end;
+ private static long now() { return System.currentTimeMillis(); }
+ private static void start() { start = now(); }
+ private static void end() { end = now(); }
+ private static float diff() { return ((float)(end-start))/1000; }
+
+ public static void main(String[] args) throws Exception {
+ float d;
+
+ if(args.length < 2) { System.err.println("Usage: SpeedTest {classname|mips binary} number_of_runs args"); System.exit(1); }
+ String className = args[0];
+ int runs = Integer.parseInt(args[1]);
+ if(runs < 5) throw new Error("Runs must be >= 5");
+ String[] appArgs = new String[args.length-1];
+ appArgs[0] = className;
+ for(int i=2;i<args.length;i++) appArgs[i-1] = args[i];
+
+ Class c = null;
+ boolean binary = className.endsWith(".mips");
+ if(!binary) {
+ start();
+ c = Class.forName(className);
+ end();
+ d = diff();
+ System.out.println("Class.forName() took " + d + "sec");
+
+ start();
+ c.newInstance();
+ end();
+ d = diff();
+ System.out.println("c.newInstance() took " + d + "sec");
+
+ if(!Runtime.class.isAssignableFrom(c)) { System.err.println(className + " isn't a MIPS compiled class"); System.exit(1); }
+ }
+
+ float times[] = new float[runs];
+
+ for(int i=0;i<runs;i++) {
+ Runtime runtime = binary ? new Interpreter(className) : (Runtime) c.newInstance();
+ System.gc();
+ start();
+ int status = runtime.run(appArgs);
+ if(status != 0) { System.err.println(className + " failed with exit status: " + status); System.exit(1); }
+ end();
+ times[i] = diff();
+ }
+
+ for(int i=0;i<runs;i++)
+ System.out.println("Run " + (i+1) + ": " + times[i] + " sec");
+ java.util.Arrays.sort(times);
+
+ System.out.println("Best: " + times[0]);
+ System.out.println("Worst: " + times[times.length-1]);
+ float sum = 0.0f;
+ for(int i=2;i<times.length-2;i++)
+ sum += times[i];
+ float avg = sum / (times.length-4);
+ System.out.println("Avg of middle " + (times.length-4) + ": " + avg);
+ }
+}
--- /dev/null
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <sys/unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/signal.h>
+#include <time.h>
+#include <dirent.h>
+#include <wchar.h>
+#include <math.h>
+
+char *user_info[1024];
+
+extern void _pause();
+extern int _call_java(int a, int b, int c, int d);
+
+void suckram();
+
+int main(int argc, char **argv) {
+ int i,n,fd;
+ time_t now;
+ DIR *dir;
+ struct dirent *dent;
+ char buf[1024];
+ unsigned char ubuf[1024];
+ unsigned short sbuf[1024];
+ char *s;
+
+ printf("Entered main()\n");
+
+ if(argc > 1 && strcmp(argv[1],"calltest")==0) {
+ printf("pausing for call test\n");
+ _pause();
+ printf("unpaused from call test\n");
+
+ for(i=1;i<=3;i++) {
+ char *s = (char*)_call_java(i,0,0,0);
+ printf("_call_java(%d,0,0,0) = \"%s\" (%d chars)\n",i,s,strlen(s));
+ free(s);
+ }
+ fd = _call_java(4,0,0,0);
+ if(fd != -1) {
+ FILE *fp;
+ fprintf(stderr,"fd: %i\n",fd);
+ fp = fdopen(fd,"w");
+ if(fp != NULL) {
+ fprintf(fp,"It worked! fp is %p - Hello, Java!\n",fp);
+ fclose(fp);
+ } else {
+ fprintf(stderr,"fdopen failed\n");
+ close(fd);
+ }
+ } else {
+ fprintf(stderr,"fd == -1\n");
+ }
+
+ printf("In main() in MIPS\n");
+ _call_java(5,0,0,0);
+ printf("Back in main() in MIPS\n");
+ } else if(argc > 2 && strcmp(argv[1],"fdtest")==0) {
+ printf("opening %s\n",argv[2]);
+ fd = open(argv[2],O_RDONLY);
+ if(fd < 0) { perror("open"); exit(1); }
+
+ printf("reading up to 64 bytes\n");
+ n = read(fd,buf,64);
+ if(n < 0) {perror("read"); exit(1); }
+ printf("read %d bytes\n",n);
+ for(i=0;i<n;i++) if(buf[i]=='\n' || buf[i]=='\r') { buf[i] = '\0'; break; }
+ printf("Read \"%s\"...\n",n == 0 ? NULL : buf);
+
+ printf("seeking back to pos 4...\n");
+ if(lseek(fd,4,SEEK_SET) < 0) { perror("lseek"); exit(1); }
+
+ printf("reading up to 64 bytes\n");
+ n = read(fd,buf,64);
+ if(n < 0) {perror("read"); exit(1); }
+ printf("read %d bytes\n",n);
+ for(i=0;i<n;i++) if(buf[i]=='\n' || buf[i]=='\r') { buf[i] = '\0'; break; }
+ printf("Read \"%s\"...\n",n == 0 ? NULL : buf);
+
+ printf("reading up to 64 bytes\n");
+ n = read(fd,buf,64);
+ if(n < 0) {perror("read"); exit(1); }
+ printf("read %d bytes\n",n);
+ for(i=0;i<n;i++) if(buf[i]=='\n' || buf[i]=='\r') { buf[i] = '\0'; break; }
+ printf("Read \"%s\"...\n",n == 0 ? NULL : buf);
+ } else if(argc > 1 && strcmp(argv[1],"fptest")==0) {
+ double d = 0.0;
+ while(d != 10.0) {
+ printf("d: %f\n",d);
+ d += 2.5;
+ }
+ } else if(argc > 1 && strcmp(argv[1],"nullderef")==0) {
+ volatile int *mem = 0;
+ *mem = 1;
+ } else {
+ printf("%d\n", 0xffffff);
+ printf("%u\n", 0xffffffU);
+ printf("%li\n",0xffffffL);
+ printf("%lu\n",0xffffffUL);
+
+
+ for(i=0;i<argc;i++)
+ printf("argv[%d] = \"%s\"\n",i,argv[i]);
+ for(i=0;user_info[i];i++)
+ printf("user_info[%d] = \"%s\"\n",i,user_info[i]);
+
+ printf("getenv(\"USER\") = \"%s\"\n",getenv("USER"));
+ printf("getenv(\"HOME\") = \"%s\"\n",getenv("HOME"));
+ printf("getenv(\"TZ\") = \"%s\"\n",getenv("TZ"));
+
+ time(&now);
+ tzset();
+ printf("%s %s %d\n",tzname[0],tzname[1],(int)_timezone);
+
+ printf("Running ctime\n");
+ s = ctime(&now);
+ printf("ctime returned: %p\n",s);
+ printf("Current time: %s",s);
+
+ printf("Trying to open /nonexistent\n");
+ fd = open("/nonexistent",O_RDONLY);
+ if(fd < 0) perror("open");
+ else close(fd);
+
+ printf("Tyring to mkdir .mkdirtest\n");
+ if(mkdir(".mkdirtest",0700) < 0) perror("mkdir");
+
+ printf("Trying to opendir /\n");
+ dir = opendir("/");
+ if(dir) {
+ while((dent=readdir(dir))!=NULL)
+ printf("\t[%s] %lu\n",dent->d_name,dent->d_ino);
+ closedir(dir);
+ } else {
+ perror("opendir");
+ }
+
+
+#if 0
+ printf("Sleeping...\n");
+ sleep(1);
+ printf("Done\n");
+#endif
+
+ fd = open("test.txt",O_RDONLY);
+ if(fd != -1) {
+ printf("Opened test.txt\n");
+ n = read(fd,sbuf,sizeof(sbuf));
+ printf("n: %d\n",n);
+ if(n < 0) perror("read");
+ ubuf[n] = '\0';
+ printf("buf: %s\n",buf);
+ for(i=0;i<n/2;i++) {
+ printf("Char %d: [%x]\n",i,sbuf[i]);
+ }
+ }
+
+ {
+ static double f = 1.574;
+ int n;
+ printf("%e\n",f);
+ f += 20.001;
+ f *= -2.0;
+ n = (int) f;
+ printf("%el\n",f);
+ printf("%d\n",n);
+ printf("%e\n",f);
+ printf("%e\n",fabs(f));
+ }
+ }
+
+ printf("exiting\n");
+ return 0;
+}
+
+void suckram() {
+ int total = 0;
+ fprintf(stderr,"Eating up all available memory\n");
+ while(malloc(1024*1024) != NULL) total ++;
+ fprintf(stderr,"Ate up %d megs\n",total);
+}
+
+__attribute__((constructor)) static void my_ctor() { printf("Constructor!\n"); }
+__attribute__((destructor)) static void my_dtor() { printf("Destructor!\n"); }
+
+int callme(int a1,int a2, int a3, int a4, int a5, int a6) __attribute__((section(".text")));
+int callme(int a1,int a2, int a3, int a4, int a5, int a6) {
+ printf("You said: %d %d %d %d %d %d\n",a1,a2,a3,a4,a5,a6);
+ return a1+a2+a3+a4+a5+a6;
+}
+
+void echo(const char *string, int count) __attribute__((section(".text")));
+void echo(const char *string, int count) {
+ int i;
+ for(i=0;i<count;i++)
+ printf("%d: %s\n",i,string);
+}
+
+void backinmips() __attribute__((section(".text")));
+void backinmips() {
+ fprintf(stderr,"In backinmips() in mips\n");
+}
--- /dev/null
+#!/bin/sh -e
+
+[ -z "$JAVA" ] && JAVA=java
+
+CLASSPATH="$(pwd)/build"; export CLASSPATH
+if [ "$1" != "running_from_make" ]; then
+ echo "Please don't run this scipt directly. Use make check" >&2
+ exit 1
+fi
+
+INT="$2"
+
+cd tmp
+
+if [ ! -e .skipmspack ]; then
+
+mkdir -p mspack
+cd mspack
+rm -f *.TTT *.inf FONTINST.EXE *.DLL *.TXT;
+for f in \
+ andale32.exe arial32.exe arialb32.exe comic32.exe courie32.exe georgi32.exe \
+ impact32.exe times32.exe trebuc32.exe verdan32.exe webdin32.exe; \
+do
+ [ -e "$f" ] || wget "http://dist.xwt.org/corefonts/$f" || rm -f "$f"
+ [ -e "$f" ] || exit 1
+done
+
+echo "Extracting MS Core Fonts using MSPackBench..."
+$JAVA tests.MSPackBench *32.exe
+
+cat <<EOF | md5sum -cv
+663974c9fe3ba55b228724fd4d4e445f AndaleMo.TTF
+3e7043e8125f1c8998347310f2c315bc AriBlk.TTF
+f11c0317db527bdd80fa0afa04703441 Arial.TTF
+34cd8fd9e4fae9f075d4c9a2c971d065 Arialbd.TTF
+a2b3bcdb39097b6aed17a766652b92b2 Arialbi.TTF
+25633f73d92a0646e733e50cf2cc3b07 Ariali.TTF
+a50f9c96a76356e3d01013e0b042989f Comic.TTF
+81d64ec3675c4adc14e9ad2c5c8103a7 Comicbd.TTF
+f4b306eed95aa7d274840533be635532 Georgia.TTF
+c61b355a5811e56ed3d7cea5d67c900e Georgiab.TTF
+1e4e5d1975bdf4a5c648afbf8872fa13 Georgiai.TTF
+e5d52bbfff45e1044381bacb7fc8e300 Georgiaz.TTF
+8fc622c3a2e2d992ec059cca61e3dfc0 Impact.TTF
+4f97f4d6ba74767259ccfb242ce0e3f7 Times.TTF
+ed6e29caf3843142d739232aa8642158 Timesbd.TTF
+6d2bd425ff00a79dd02e4c95f689861b Timesbi.TTF
+957dd4f17296522dead302ab4fcdfa8d Timesi.TTF
+055460df9ab3c8aadd3330bd30805f11 Trebucbd.ttf
+3ba52ab1fa0cd726e7868e9c6673902c Verdana.TTF
+a2b4dc9afc18e76cfcaa0071fa7cd0da Verdanab.TTF
+24b3a293c865a2c265280f017fb24ba5 Verdanai.TTF
+f7310c29df0070530c48a47f2dca9014 Verdanaz.TTF
+1a56b45a66b07b4c576d5ead048ed992 Webdings.TTF
+20f23317e90516cbb7d38bd53b3d1c5b cour.ttf
+7d94f95bf383769b51379d095139f2d7 courbd.ttf
+da414c01f951b020bb09a4165d3fb5fa courbi.ttf
+167e27add66e9e8eb0d28a1235dd3bda couri.ttf
+70e7be8567bc05f771b59abd9d696407 trebuc.ttf
+fb5d68cb58c6ad7e88249d65f6900740 trebucbi.ttf
+8f308fe77b584e20b246aa1f8403d2e9 trebucit.ttf
+663974c9fe3ba55b228724fd4d4e445f AndaleMo.TTF
+3e7043e8125f1c8998347310f2c315bc AriBlk.TTF
+f11c0317db527bdd80fa0afa04703441 Arial.TTF
+34cd8fd9e4fae9f075d4c9a2c971d065 Arialbd.TTF
+a2b3bcdb39097b6aed17a766652b92b2 Arialbi.TTF
+25633f73d92a0646e733e50cf2cc3b07 Ariali.TTF
+a50f9c96a76356e3d01013e0b042989f Comic.TTF
+81d64ec3675c4adc14e9ad2c5c8103a7 Comicbd.TTF
+f4b306eed95aa7d274840533be635532 Georgia.TTF
+c61b355a5811e56ed3d7cea5d67c900e Georgiab.TTF
+1e4e5d1975bdf4a5c648afbf8872fa13 Georgiai.TTF
+e5d52bbfff45e1044381bacb7fc8e300 Georgiaz.TTF
+8fc622c3a2e2d992ec059cca61e3dfc0 Impact.TTF
+4f97f4d6ba74767259ccfb242ce0e3f7 Times.TTF
+ed6e29caf3843142d739232aa8642158 Timesbd.TTF
+6d2bd425ff00a79dd02e4c95f689861b Timesbi.TTF
+957dd4f17296522dead302ab4fcdfa8d Timesi.TTF
+055460df9ab3c8aadd3330bd30805f11 Trebucbd.ttf
+3ba52ab1fa0cd726e7868e9c6673902c Verdana.TTF
+a2b4dc9afc18e76cfcaa0071fa7cd0da Verdanab.TTF
+24b3a293c865a2c265280f017fb24ba5 Verdanai.TTF
+f7310c29df0070530c48a47f2dca9014 Verdanaz.TTF
+1a56b45a66b07b4c576d5ead048ed992 Webdings.TTF
+20f23317e90516cbb7d38bd53b3d1c5b cour.ttf
+7d94f95bf383769b51379d095139f2d7 courbd.ttf
+da414c01f951b020bb09a4165d3fb5fa courbi.ttf
+167e27add66e9e8eb0d28a1235dd3bda couri.ttf
+70e7be8567bc05f771b59abd9d696407 trebuc.ttf
+fb5d68cb58c6ad7e88249d65f6900740 trebucbi.ttf
+8f308fe77b584e20b246aa1f8403d2e9 trebucit.ttf
+EOF
+
+echo "Core Fonts extracted successfully!"
+
+cd ..
+
+fi
+
+if [ ! -e .skipdjpeg ]; then
+echo "Decoding some jpegs with DJpeg..."
+
+rm -f *.tga
+
+[ -e banner.jpg ] || wget http://www.xwt.org/image/banner.jpg
+[ -e banner.jpg ] || exit 1
+
+$JAVA tests.DJpeg -targa -outfile thebride_1280.tga thebride_1280.jpg
+echo "e90f6b915aee2fc0d2eb9fc60ace6203 thebride_1280.tga" | md5sum -cv
+
+$JAVA tests.DJpeg -targa -outfile banner.tga banner.jpg
+echo "4c7cc29ae2094191a9b0308cf9a04fbd banner.tga" | md5sum -cv
+
+echo "JPEGs decoded successfully!"
+
+fi
+
+if [ ! -e .skipfreetype ]; then
+
+cd mspack
+
+echo "Rendering some fonts with FTBench..."
+if ! [ -e Verdana.TTF -a -e Arial.TTF -a -e Comic.TTF ]; then
+ echo "Can't find the corefonts - did the mspack test complete?"
+ exit 1
+fi
+
+rm -f *.render
+
+for f in Verdana.TTF Arial.TTF Comic.TTF; do
+ $JAVA tests.FTBench "$f" "$f".render
+done
+
+cat <<EOF|md5sum -cv
+e33b9db5a413af214b2524265af18026 Arial.TTF.render
+61dee4f697a61ebc1b47decbed04b2da Comic.TTF.render
+d5a6d39a63e49c597ed860913e27d2bb Verdana.TTF.render
+EOF
+
+echo "Fonts rendered successfully"
+cd ..
+
+fi
+
+if [ ! -e .skipgc ]; then
+
+echo "Running gctest from the boehm-gc library..."
+$JAVA tests.GCTest
+
+fi
+
+if [ ! -e .busybox -a -e ../build/tests/BusyBox.class ]; then
+ echo "Running busybox's md5sum command on some ttfs"
+ $JAVA tests.BusyBox ash -c "md5sum mspack/*.ttf > md5.1"
+ md5sum mspack/*.ttf > md5.2
+ cmp md5.1 md5.2 && echo "The BusyBox md5sum command and sh work properly!"
+fi
+
+cat <<EOF
+* * * * * * * * * * * * * * * * * * * * *
+* All tests completed with no failures *
+* * * * * * * * * * * * * * * * * * * * *
+
+EOF
--- /dev/null
+# Inspired by XWT's Makefile.upstream
+
+version_gcc = 3.3.3
+url_gcc-core = http://mirrors.rcn.net/pub/sourceware/gcc/releases/gcc-$(version_gcc)/gcc-core-$(version_gcc).tar.gz
+url_gcc-c++ = http://mirrors.rcn.net/pub/sourceware/gcc/releases/gcc-$(version_gcc)/gcc-g++-$(version_gcc).tar.gz
+patches_gcc = gcc-fixes.patch gcc-fdata-sections-bss.patch
+configure_gcc = --target=mips-unknown-elf --disable-threads --with-gnu-ld --with-gnu-as --with-newlib=yes --enable-sjlj-exceptions --enable-languages="c"
+configure_gcc_step2 = $(configure_gcc) --enable-languages="c,c++"
+
+version_binutils = 2.14
+url_binutils = ftp://ftp.gnu.org/gnu/binutils/binutils-$(version_binutils).tar.gz
+patches_binutils = binutils-no64.patch
+configure_binutils = --target=mips-unknown-elf
+
+version_newlib = 1.11.0
+url_newlib = http://mirrors.rcn.net/pub/sourceware/newlib/newlib-$(version_newlib).tar.gz
+patches_newlib = newlib-mips.patch newlib-tzset.patch newlib-malloc.patch
+configure_newlib = --enable-multilib --target=mips-unknown-elf
+
+url_openbsdglob = http://www.brianweb.net/xwt/openbsdglob.tar.gz
+url_regex = ftp://ftp.zoo.toronto.edu/pub/regex.shar
+
+version_bcel = 5.1
+url_bcel = http://mirrors.mix5.com/apache/jakarta/bcel/binaries/bcel-$(version_bcel).tar.gz
+
+.SECONDARY: # This is broken in gmake < 3.79.1
+
+upstream = $(shell pwd)
+root = $(shell dirname "`pwd`")
+prefix = $(upstream)/install
+
+PATH := $(prefix)/bin:$(PATH)
+export PATH
+
+# Solaris' patch doesn't work, use gnu patch on solaris
+PATCH = $(shell test `uname` = SunOS && echo gpatch || echo patch)
+
+tasks/full_toolchain: tasks/build_binutils tasks/build_gcc_step2 tasks/build_libc
+ touch $@
+
+tasks/build_gcc: tasks/build_binutils
+tasks/build_newlib: tasks/build_gcc
+
+tasks/build_libc: tasks/build_newlib tasks/build_regex tasks/build_openbsdglob
+ rm -f install/mips-unknown-elf/lib/crt0.o
+ ln -s $(root)/build/org/xwt/mips/crt0.o install/mips-unknown-elf/lib/crt0.o
+ echo '#include <unistd.h>' > install/mips-unknown-elf/include/getopt.h
+ touch $@
+
+clean_%:
+ rm -rf "build/$(*)"*
+ rm -f "tasks/build_$*" "tasks/patch_$*" "tasks/extract_$*"
+
+tasks/download_%:
+ if [ -z "$(url_$*)" ]; then echo "No url for $*" >&2; false; fi
+ mkdir -p download
+ cd download && wget --passive-ftp -N $(url_$*)
+ touch $@
+
+tasks/download_gcc: tasks/download_gcc-core tasks/download_gcc-c++
+ touch $@
+
+tasks/extract_%: tasks/download_%
+ mkdir -p build
+ cd build && \
+ gzip -dc ../download/$*-$(version_$*).tar.gz | tar xf - && \
+ rm -f $* && \
+ ln -s $*-$(version_$*) $*
+ touch $@
+
+tasks/extract_gcc: tasks/download_gcc
+ mkdir -p build
+ cd build && gzip -dc ../download/gcc-core-$(version_gcc).tar.gz | tar xf -
+ cd build && gzip -dc ../download/gcc-g++-$(version_gcc).tar.gz | tar xf -
+ touch $@
+
+tasks/patch_%: tasks/extract_%
+ cd build/$*-$(version_$*) && \
+ for p in $(patches_$*) end; do \
+ [ "$$p" = "end" ] || $(PATCH) -p0 < ../../patches/$$p || exit 1; \
+ done
+ touch $@
+
+tasks/build_%: tasks/patch_%
+ mkdir -p install
+ @[ "$*" = "newlib" ] && rm -f install/mips-unknown-elf/lib/crt0.o || true
+ mkdir -p build/$*-obj && cd build/$*-obj && \
+ ../$*-$(version_$*)/configure --prefix=$(prefix) $(configure_$*) && \
+ $(MAKE) TARGET_CFLAGS="$(MIPS_CFLAGS)" && \
+ $(MAKE) install
+ touch $@
+
+tasks/build_gcc_step2: tasks/patch_gcc tasks/build_libc
+ mkdir -p install
+ mkdir -p build/gcc-obj && cd build/gcc-obj && \
+ ../gcc-$(version_gcc)/configure --prefix=$(prefix) $(configure_gcc_step2) && \
+ $(MAKE) TARGET_CFLAGS="$(MIPS_CFLAGS)" && \
+ $(MAKE) install
+ touch $@
+
+tasks/build_openbsdglob: tasks/download_openbsdglob tasks/build_newlib
+ @mkdir -p install/mips-unknown-elf/{include,lib}
+ cd build && gzip -dc ../download/openbsdglob.tar.gz | tar xf -
+ cd build/openbsdglob && \
+ mips-unknown-elf-gcc '-Dissetugid()=0' -DARG_MAX=65536 $(MIPS_CFLAGS) -I. -c -o glob.o glob.c && \
+ mips-unknown-elf-gcc -O2 -Wall -Werror -I. -c -o fnmatch.o fnmatch.c && \
+ mips-unknown-elf-ar cr libglob.a *.o && \
+ mips-unknown-elf-ranlib libglob.a && \
+ cp *.h ../../install/mips-unknown-elf/include && \
+ cp *.a ../../install/mips-unknown-elf/lib
+ touch $@
+
+tasks/build_regex: tasks/download_regex tasks/build_newlib
+ @mkdir -p install/mips-unknown-elf/{include,lib}
+ mkdir -p build/regex build/regex/fake
+ cd build/regex && \
+ sh ../../download/regex.shar && \
+ make CC=mips-unknown-elf-gcc CFLAGS="-I. $(MIPS_CFLAGS)" regcomp.o regexec.o regerror.o regfree.o && \
+ mips-unknown-elf-ar cr libregex.a regcomp.o regexec.o regerror.o regfree.o && \
+ mips-unknown-elf-ranlib libregex.a && \
+ cp regex.h ../../install/mips-unknown-elf/include && \
+ cp libregex.a ../../install/mips-unknown-elf/lib
+ touch $@
+
+
+#
+# Tests
+# These are simply here for convenience. They aren't required
+# to build or run mips2java
+#
+
+tasks/build_freetype: tasks/full_toolchain
+tasks/build_libjpeg: tasks/full_toolchain
+tasks/build_boehmgc: tasks/full_toolchain
+tasks/build_libmspack: tasks/full_toolchain
+tasks/build_freetype: tasks/full_toolchain
+
+version_libjpeg = 6b
+url_libjpeg = http://www.ijg.org/files/jpegsrc.v$(version_libjpeg).tar.gz
+
+version_libmspack = 20030726
+url_libmspack = http://www.kyz.uklinux.net/downloads/libmspack-$(version_libmspack).tar.gz
+patches_libmspack = libmspack.patch
+
+version_freetype = 2.1.4
+url_freetype = http://umn.dl.sourceforge.net/sourceforge/freetype/freetype-$(version_freetype).tar.gz
+patches_freetype = freetype.patch ft-nostdio.patch
+
+version_boehmgc = 6.3alpha2
+url_boehmgc = http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc$(version_boehmgc).tar.gz
+patches_boehmgc = boehm-gc.patch
+
+version_busybox = 0.60.5
+url_busybox = http://busybox.net/downloads/busybox-$(version_busybox).tar.gz
+patches_busybox = busybox.patch
+
+
+tasks/extract_libjpeg: tasks/download_libjpeg
+ mkdir -p build
+ cd build && \
+ gzip -dc ../download/jpegsrc.v$(version_libjpeg).tar.gz | tar xf - && \
+ mv jpeg-$(version_libjpeg) libjpeg-$(version_libjpeg) && \
+ rm -f libjpeg && \
+ ln -s libjpeg-$(version_libjpeg) libjpeg
+ touch $@
+
+tasks/build_libjpeg: tasks/patch_libjpeg
+ cd build/libjpeg-$(version_libjpeg) && \
+ ./configure && \
+ make CC="mips-unknown-elf-gcc" \
+ AR="mips-unknown-elf-ar rc" \
+ AR2="mips-unknown-elf-ranlib" \
+ CFLAGS="$(MIPS_CFLAGS)" \
+ LDFLAGS="$(MIPS_LDFLAGS)"
+ touch $@
+
+tasks/extract_libmspack: tasks/download_libmspack
+ mkdir -p build
+ cd build && \
+ gzip -dc ../download/libmspack-$(version_libmspack).tar.gz | tar xf - && \
+ mv libmspack libmspack-$(version_libmspack) && \
+ rm -f libmspack && \
+ ln -s libmspack-$(version_libmspack) libmspack
+ touch $@
+
+tasks/build_libmspack: tasks/patch_libmspack tasks/full_toolchain
+ cd build/libmspack-$(version_libmspack)/mspack && \
+ make CC="mips-unknown-elf-gcc" \
+ AR="mips-unknown-elf-ar" \
+ RANLIB="mips-unknown-elf-ranlib" \
+ OPTIM="$(MIPS_CFLAGS)"
+ touch $@
+
+tasks/build_freetype: tasks/patch_freetype tasks/full_toolchain
+ cd build/freetype-$(version_freetype) && \
+ $(MAKE) setup ansi && \
+ $(MAKE) CC="mips-unknown-elf-gcc" \
+ CFLAGS="-c $(MIPS_CFLAGS)" \
+ AR="mips-unknown-elf-ar" \
+ RANLIB="mips-unknown-elf-ranlib" && \
+ mips-unknown-elf-ranlib objs/libfreetype.a
+ touch $@
+
+tasks/extract_boehmgc: tasks/download_boehmgc
+ mkdir -p build
+ cd build && \
+ rm -rf gc$(version_boehmgc) && \
+ gzip -dc ../download/gc$(version_boehmgc).tar.gz | tar xf - && \
+ rm -f boehmgc boehmgc-$(version_boehmgc) && \
+ ln -s gc$(version_boehmgc) boehmgc && \
+ ln -s gc$(version_boehmgc) boehmgc-$(version_boehmgc)
+ touch $@
+
+tasks/build_boehmgc: tasks/patch_boehmgc tasks/full_toolchain
+ cd build/gc$(version_boehmgc) && \
+ CC="mips-unknown-elf-gcc" CFLAGS="$(MIPS_CFLAGS)" LDFLAGS="$(MIPS_LDFLAGS)" \
+ ./configure --host=mips-unknown-elf --disable-shared --disable-threads && \
+ make && \
+ make gctest
+ touch $@
+
+tasks/build_busybox: tasks/patch_busybox tasks/full_toolchain
+ cd build && \
+ rm -f busybox && \
+ ln -s busybox-$(version_busybox) busybox
+ cd build/busybox && $(MAKE) SHELL=/bin/bash LDFLAGS="$(MIPS_LDFLAGS)" CFLAGS_EXTRA="$(MIPS_CFLAGS) -g"
+ touch $@
--- /dev/null
+diff -ru ../binutils-2.14/bfd/config.bfd ./bfd/config.bfd
+--- ../binutils-2.14/bfd/config.bfd Mon Jun 2 16:35:20 2003
++++ ./bfd/config.bfd Mon Sep 1 01:06:32 2003
+@@ -777,6 +777,10 @@
+ targ_defvec=bfd_elf32_littlemips_vec
+ targ_selvecs="bfd_elf32_bigmips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec"
+ ;;
++ mips*-unknown-elf*)
++ targ_defvec=bfd_elf32_bigmips_vec
++ targ_selvecs=bfd_elf32_littlemips_vec
++ ;;
+ mips*-*-elf* | mips*-*-rtems* | mips*-*-vxworks*)
+ targ_defvec=bfd_elf32_bigmips_vec
+ targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec"
+Only in ./bfd: config.bfd.old
+Only in ./bfd: config.bfd~
+diff -ru ../binutils-2.14/ld/configure.tgt ./ld/configure.tgt
+--- ../binutils-2.14/ld/configure.tgt Thu Jun 12 10:25:52 2003
++++ ./ld/configure.tgt Mon Sep 1 01:07:42 2003
+@@ -405,6 +405,7 @@
+ mips*vr5000el-*-elf*) targ_emul=elf32l4300 ;;
+ mips*vr5000-*-elf*) targ_emul=elf32b4300 ;;
+ mips*el-*-elf*) targ_emul=elf32elmip ;;
++mips*-unknown-elf*) targ_emul=elf32ebmip ;;
+ mips*-*-elf*) targ_emul=elf32ebmip ;;
+ mips*el-*-rtems*) targ_emul=elf32elmip ;;
+ mips*-*-rtems*) targ_emul=elf32ebmip ;;
+Only in ./ld: configure.tgt.old
+Only in ./ld: configure.tgt~
--- /dev/null
+diff -ruN ../gc6.3alpha2/configure ./configure
+--- ../gc6.3alpha2/configure Wed Oct 1 19:34:32 2003
++++ ./configure Wed Nov 19 04:17:25 2003
+@@ -1,7 +1,7 @@
+ #! /bin/sh
+ # From configure.in Revision: 1.2 .
+ # Guess values for system-dependent variables and create Makefiles.
+-# Generated by GNU Autoconf 2.53 for gc 6.3alpha2.
++# Generated by GNU Autoconf 2.57 for gc 6.3alpha2.
+ #
+ # Report bugs to <Hans.Boehm@hp.com>.
+ #
+@@ -9,173 +9,6 @@
+ # Free Software Foundation, Inc.
+ # This configure script is free software; the Free Software Foundation
+ # gives unlimited permission to copy, distribute and modify it.
+-
+-# Find the correct PATH separator. Usually this is `:', but
+-# DJGPP uses `;' like DOS.
+-if test "X${PATH_SEPARATOR+set}" != Xset; then
+- UNAME=${UNAME-`uname 2>/dev/null`}
+- case X$UNAME in
+- *-DOS) lt_cv_sys_path_separator=';' ;;
+- *) lt_cv_sys_path_separator=':' ;;
+- esac
+- PATH_SEPARATOR=$lt_cv_sys_path_separator
+-fi
+-
+-
+-# Check that we are running under the correct shell.
+-SHELL=${CONFIG_SHELL-/bin/sh}
+-
+-case X$ECHO in
+-X*--fallback-echo)
+- # Remove one level of quotation (which was required for Make).
+- ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
+- ;;
+-esac
+-
+-echo=${ECHO-echo}
+-if test "X$1" = X--no-reexec; then
+- # Discard the --no-reexec flag, and continue.
+- shift
+-elif test "X$1" = X--fallback-echo; then
+- # Avoid inline document here, it may be left over
+- :
+-elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+- # Yippee, $echo works!
+- :
+-else
+- # Restart under the correct shell.
+- exec $SHELL "$0" --no-reexec ${1+"$@"}
+-fi
+-
+-if test "X$1" = X--fallback-echo; then
+- # used as fallback echo
+- shift
+- cat <<EOF
+-
+-EOF
+- exit 0
+-fi
+-
+-# The HP-UX ksh and POSIX shell print the target directory to stdout
+-# if CDPATH is set.
+-if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+-
+-if test -z "$ECHO"; then
+-if test "X${echo_test_string+set}" != Xset; then
+-# find a string as large as possible, as long as the shell can cope with it
+- for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+- # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+- if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+- echo_test_string="`eval $cmd`" &&
+- (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+- then
+- break
+- fi
+- done
+-fi
+-
+-if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+- echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+- test "X$echo_testing_string" = "X$echo_test_string"; then
+- :
+-else
+- # The Solaris, AIX, and Digital Unix default echo programs unquote
+- # backslashes. This makes it impossible to quote backslashes using
+- # echo "$something" | sed 's/\\/\\\\/g'
+- #
+- # So, first we look for a working echo in the user's PATH.
+-
+- IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+- for dir in $PATH /usr/ucb; do
+- if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+- test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+- echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+- test "X$echo_testing_string" = "X$echo_test_string"; then
+- echo="$dir/echo"
+- break
+- fi
+- done
+- IFS="$save_ifs"
+-
+- if test "X$echo" = Xecho; then
+- # We didn't find a better echo, so look for alternatives.
+- if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+- echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+- test "X$echo_testing_string" = "X$echo_test_string"; then
+- # This shell has a builtin print -r that does the trick.
+- echo='print -r'
+- elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+- test "X$CONFIG_SHELL" != X/bin/ksh; then
+- # If we have ksh, try running configure again with it.
+- ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+- export ORIGINAL_CONFIG_SHELL
+- CONFIG_SHELL=/bin/ksh
+- export CONFIG_SHELL
+- exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+- else
+- # Try using printf.
+- echo='printf %s\n'
+- if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+- echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+- test "X$echo_testing_string" = "X$echo_test_string"; then
+- # Cool, printf works
+- :
+- elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+- test "X$echo_testing_string" = 'X\t' &&
+- echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+- test "X$echo_testing_string" = "X$echo_test_string"; then
+- CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+- export CONFIG_SHELL
+- SHELL="$CONFIG_SHELL"
+- export SHELL
+- echo="$CONFIG_SHELL $0 --fallback-echo"
+- elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+- test "X$echo_testing_string" = 'X\t' &&
+- echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+- test "X$echo_testing_string" = "X$echo_test_string"; then
+- echo="$CONFIG_SHELL $0 --fallback-echo"
+- else
+- # maybe with a smaller string...
+- prev=:
+-
+- for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+- if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+- then
+- break
+- fi
+- prev="$cmd"
+- done
+-
+- if test "$prev" != 'sed 50q "$0"'; then
+- echo_test_string=`eval $prev`
+- export echo_test_string
+- exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+- else
+- # Oops. We lost completely, so just stick with echo.
+- echo=echo
+- fi
+- fi
+- fi
+- fi
+-fi
+-fi
+-
+-# Copy echo and quote the copy suitably for passing to libtool from
+-# the Makefile, instead of quoting the original, which is used later.
+-ECHO=$echo
+-if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+- ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+-fi
+-
+-
+-
+-if expr a : '\(a\)' >/dev/null 2>&1; then
+- as_expr=expr
+-else
+- as_expr=false
+-fi
+-
+-
+ ## --------------------- ##
+ ## M4sh Initialization. ##
+ ## --------------------- ##
+@@ -184,11 +17,13 @@
+ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
++ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
++ # is contrary to our usage. Disable this feature.
++ alias -g '${1+"$@"}'='"$@"'
+ elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+ fi
+
+-# NLS nuisances.
+ # Support unset when possible.
+ if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+ as_unset=unset
+@@ -196,34 +31,42 @@
+ as_unset=false
+ fi
+
+-(set +x; test -n "`(LANG=C; export LANG) 2>&1`") &&
+- { $as_unset LANG || test "${LANG+set}" != set; } ||
+- { LANG=C; export LANG; }
+-(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") &&
+- { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } ||
+- { LC_ALL=C; export LC_ALL; }
+-(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") &&
+- { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } ||
+- { LC_TIME=C; export LC_TIME; }
+-(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") &&
+- { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } ||
+- { LC_CTYPE=C; export LC_CTYPE; }
+-(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") &&
+- { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } ||
+- { LANGUAGE=C; export LANGUAGE; }
+-(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") &&
+- { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } ||
+- { LC_COLLATE=C; export LC_COLLATE; }
+-(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") &&
+- { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } ||
+- { LC_NUMERIC=C; export LC_NUMERIC; }
+-(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") &&
+- { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } ||
+- { LC_MESSAGES=C; export LC_MESSAGES; }
++
++# Work around bugs in pre-3.0 UWIN ksh.
++$as_unset ENV MAIL MAILPATH
++PS1='$ '
++PS2='> '
++PS4='+ '
++
++# NLS nuisances.
++for as_var in \
++ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
++ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
++ LC_TELEPHONE LC_TIME
++do
++ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
++ eval $as_var=C; export $as_var
++ else
++ $as_unset $as_var
++ fi
++done
++
++# Required to use basename.
++if expr a : '\(a\)' >/dev/null 2>&1; then
++ as_expr=expr
++else
++ as_expr=false
++fi
++
++if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
++ as_basename=basename
++else
++ as_basename=false
++fi
+
+
+ # Name of the executable.
+-as_me=`(basename "$0") 2>/dev/null ||
++as_me=`$as_basename "$0" ||
+ $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+@@ -234,6 +77,7 @@
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
++
+ # PATH needs CR, and LINENO needs CR and PATH.
+ # Avoid depending upon Character Ranges.
+ as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+@@ -244,15 +88,15 @@
+
+ # The user is always right.
+ if test "${PATH_SEPARATOR+set}" != set; then
+- echo "#! /bin/sh" >conftest.sh
+- echo "exit 0" >>conftest.sh
+- chmod +x conftest.sh
+- if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then
++ echo "#! /bin/sh" >conf$$.sh
++ echo "exit 0" >>conf$$.sh
++ chmod +x conf$$.sh
++ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+- rm -f conftest.sh
++ rm -f conf$$.sh
+ fi
+
+
+@@ -300,6 +144,8 @@
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
++ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
++ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+@@ -372,6 +218,12 @@
+ fi
+ rm -f conf$$ conf$$.exe conf$$.file
+
++if mkdir -p . 2>/dev/null; then
++ as_mkdir_p=:
++else
++ as_mkdir_p=false
++fi
++
+ as_executable_p="test -f"
+
+ # Sed expression to map a string onto a valid CPP name.
+@@ -388,7 +240,166 @@
+ IFS=" $as_nl"
+
+ # CDPATH.
+-$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; }
++$as_unset CDPATH
++
++
++# Find the correct PATH separator. Usually this is `:', but
++# DJGPP uses `;' like DOS.
++if test "X${PATH_SEPARATOR+set}" != Xset; then
++ UNAME=${UNAME-`uname 2>/dev/null`}
++ case X$UNAME in
++ *-DOS) lt_cv_sys_path_separator=';' ;;
++ *) lt_cv_sys_path_separator=':' ;;
++ esac
++ PATH_SEPARATOR=$lt_cv_sys_path_separator
++fi
++
++
++# Check that we are running under the correct shell.
++SHELL=${CONFIG_SHELL-/bin/sh}
++
++case X$ECHO in
++X*--fallback-echo)
++ # Remove one level of quotation (which was required for Make).
++ ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
++ ;;
++esac
++
++echo=${ECHO-echo}
++if test "X$1" = X--no-reexec; then
++ # Discard the --no-reexec flag, and continue.
++ shift
++elif test "X$1" = X--fallback-echo; then
++ # Avoid inline document here, it may be left over
++ :
++elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
++ # Yippee, $echo works!
++ :
++else
++ # Restart under the correct shell.
++ exec $SHELL "$0" --no-reexec ${1+"$@"}
++fi
++
++if test "X$1" = X--fallback-echo; then
++ # used as fallback echo
++ shift
++ cat <<EOF
++
++EOF
++ exit 0
++fi
++
++# The HP-UX ksh and POSIX shell print the target directory to stdout
++# if CDPATH is set.
++if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
++
++if test -z "$ECHO"; then
++if test "X${echo_test_string+set}" != Xset; then
++# find a string as large as possible, as long as the shell can cope with it
++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
++ if (echo_test_string="`eval $cmd`") 2>/dev/null &&
++ echo_test_string="`eval $cmd`" &&
++ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
++ then
++ break
++ fi
++ done
++fi
++
++if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
++ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ :
++else
++ # The Solaris, AIX, and Digital Unix default echo programs unquote
++ # backslashes. This makes it impossible to quote backslashes using
++ # echo "$something" | sed 's/\\/\\\\/g'
++ #
++ # So, first we look for a working echo in the user's PATH.
++
++ IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
++ for dir in $PATH /usr/ucb; do
++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ echo="$dir/echo"
++ break
++ fi
++ done
++ IFS="$save_ifs"
++
++ if test "X$echo" = Xecho; then
++ # We didn't find a better echo, so look for alternatives.
++ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
++ echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ # This shell has a builtin print -r that does the trick.
++ echo='print -r'
++ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
++ test "X$CONFIG_SHELL" != X/bin/ksh; then
++ # If we have ksh, try running configure again with it.
++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
++ export ORIGINAL_CONFIG_SHELL
++ CONFIG_SHELL=/bin/ksh
++ export CONFIG_SHELL
++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
++ else
++ # Try using printf.
++ echo='printf %s\n'
++ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
++ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ # Cool, printf works
++ :
++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
++ test "X$echo_testing_string" = 'X\t' &&
++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
++ export CONFIG_SHELL
++ SHELL="$CONFIG_SHELL"
++ export SHELL
++ echo="$CONFIG_SHELL $0 --fallback-echo"
++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
++ test "X$echo_testing_string" = 'X\t' &&
++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ echo="$CONFIG_SHELL $0 --fallback-echo"
++ else
++ # maybe with a smaller string...
++ prev=:
++
++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
++ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
++ then
++ break
++ fi
++ prev="$cmd"
++ done
++
++ if test "$prev" != 'sed 50q "$0"'; then
++ echo_test_string=`eval $prev`
++ export echo_test_string
++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
++ else
++ # Oops. We lost completely, so just stick with echo.
++ echo=echo
++ fi
++ fi
++ fi
++ fi
++fi
++fi
++
++# Copy echo and quote the copy suitably for passing to libtool from
++# the Makefile, instead of quoting the original, which is used later.
++ECHO=$echo
++if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
++ ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
++fi
++
+
+
+ # Name of the host.
+@@ -402,6 +413,7 @@
+ # Initializations.
+ #
+ ac_default_prefix=/usr/local
++ac_config_libobj_dir=.
+ cross_compiling=no
+ subdirs=
+ MFLAGS=
+@@ -458,6 +470,8 @@
+ # include <unistd.h>
+ #endif"
+
++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE GC_VERSION CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE CCAS CCASFLAGS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT GC_CFLAGS THREADLIBS POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE EXTRA_TEST_LIBS target_all CPLUSPLUS_TRUE CPLUSPLUS_FALSE INCLUDES CXXINCLUDES addobjs addincludes addlibs addtests LN_S ECHO CPP EGREP LIBTOOL MY_CFLAGS USE_LIBDIR_TRUE USE_LIBDIR_FALSE LIBOBJS LTLIBOBJS'
++ac_subst_files=''
+
+ # Initialize some variables set by options.
+ ac_init_help=
+@@ -881,6 +895,9 @@
+ { (exit 1); exit 1; }; }
+ fi
+ fi
++(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
++ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
++ { (exit 1); exit 1; }; }
+ srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ ac_env_build_alias_set=${build_alias+set}
+ ac_env_build_alias_value=$build_alias
+@@ -1080,7 +1097,7 @@
+ # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+ # absolute.
+ ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+-ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
++ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+@@ -1107,7 +1124,7 @@
+ if $ac_init_version; then
+ cat <<\_ACEOF
+ gc configure 6.3alpha2
+-generated by GNU Autoconf 2.53
++generated by GNU Autoconf 2.57
+
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+@@ -1122,7 +1139,7 @@
+ running configure, to aid debugging if configure makes a mistake.
+
+ It was created by gc $as_me 6.3alpha2, which was
+-generated by GNU Autoconf 2.53. Invocation command line was
++generated by GNU Autoconf 2.57. Invocation command line was
+
+ $ $0 $@
+
+@@ -1174,27 +1191,54 @@
+
+ # Keep a trace of the command line.
+ # Strip out --no-create and --no-recursion so they do not pile up.
++# Strip out --silent because we don't want to record it for future runs.
+ # Also quote any args containing shell meta-characters.
++# Make two passes to allow for proper duplicate-argument suppression.
+ ac_configure_args=
++ac_configure_args0=
++ac_configure_args1=
+ ac_sep=
+-for ac_arg
++ac_must_keep_next=false
++for ac_pass in 1 2
+ do
+- case $ac_arg in
+- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+- | --no-cr | --no-c | -n ) continue ;;
+- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+- continue ;;
+- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+- ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+- esac
+- case " $ac_configure_args " in
+- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+- *) ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+- ac_sep=" " ;;
+- esac
+- # Get rid of the leading space.
++ for ac_arg
++ do
++ case $ac_arg in
++ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
++ | -silent | --silent | --silen | --sile | --sil)
++ continue ;;
++ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
++ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
++ esac
++ case $ac_pass in
++ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
++ 2)
++ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
++ if test $ac_must_keep_next = true; then
++ ac_must_keep_next=false # Got value, back to normal.
++ else
++ case $ac_arg in
++ *=* | --config-cache | -C | -disable-* | --disable-* \
++ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
++ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
++ | -with-* | --with-* | -without-* | --without-* | --x)
++ case "$ac_configure_args0 " in
++ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
++ esac
++ ;;
++ -* ) ac_must_keep_next=true ;;
++ esac
++ fi
++ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
++ # Get rid of the leading space.
++ ac_sep=" "
++ ;;
++ esac
++ done
+ done
++$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
++$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+ # When interrupted or exit'd, cleanup temporary files, and complete
+ # config.log. We remove comments because anyway the quotes in there
+@@ -1205,6 +1249,7 @@
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
++
+ cat <<\_ASBOX
+ ## ---------------- ##
+ ## Cache variables. ##
+@@ -1227,6 +1272,35 @@
+ esac;
+ }
+ echo
++
++ cat <<\_ASBOX
++## ----------------- ##
++## Output variables. ##
++## ----------------- ##
++_ASBOX
++ echo
++ for ac_var in $ac_subst_vars
++ do
++ eval ac_val=$`echo $ac_var`
++ echo "$ac_var='"'"'$ac_val'"'"'"
++ done | sort
++ echo
++
++ if test -n "$ac_subst_files"; then
++ cat <<\_ASBOX
++## ------------- ##
++## Output files. ##
++## ------------- ##
++_ASBOX
++ echo
++ for ac_var in $ac_subst_files
++ do
++ eval ac_val=$`echo $ac_var`
++ echo "$ac_var='"'"'$ac_val'"'"'"
++ done | sort
++ echo
++ fi
++
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+ ## ----------- ##
+@@ -1234,7 +1308,7 @@
+ ## ----------- ##
+ _ASBOX
+ echo
+- sed "/^$/d" confdefs.h
++ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+@@ -1399,6 +1473,7 @@
+
+
+
++
+ ## version must conform to [0-9]+[.][0-9]+(alpha[0-9]+)?
+
+ ac_aux_dir=
+@@ -1743,15 +1818,15 @@
+ test -n "$AWK" && break
+ done
+
+-echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \${MAKE}" >&5
+-echo $ECHO_N "checking whether ${MAKE-make} sets \${MAKE}... $ECHO_C" >&6
++echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
++echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+ set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
+ if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+ cat >conftest.make <<\_ACEOF
+ all:
+- @echo 'ac_maketemp="${MAKE}"'
++ @echo 'ac_maketemp="$(MAKE)"'
+ _ACEOF
+ # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+ eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+@@ -2116,9 +2191,7 @@
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+- set dummy "$as_dir/$ac_word" ${1+"$@"}
+- shift
+- ac_cv_prog_CC="$@"
++ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+ fi
+ fi
+@@ -2223,8 +2296,10 @@
+ fi
+
+
+-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH" >&5
+-echo "$as_me: error: no acceptable C compiler found in \$PATH" >&2;}
++test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
++See \`config.log' for more details." >&5
++echo "$as_me: error: no acceptable C compiler found in \$PATH
++See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Provide some information about the compiler.
+@@ -2249,14 +2324,12 @@
+
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -2266,7 +2339,7 @@
+ }
+ _ACEOF
+ ac_clean_files_save=$ac_clean_files
+-ac_clean_files="$ac_clean_files a.out a.exe"
++ac_clean_files="$ac_clean_files a.out a.exe b.out"
+ # Try to create an executable without -o first, disregard a.out.
+ # It will help us diagnose broken compilers, and finding out an intuition
+ # of exeext.
+@@ -2285,26 +2358,39 @@
+ # Be careful to initialize this variable, since it used to be cached.
+ # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ ac_cv_exeext=
+-for ac_file in `ls a_out.exe a.exe conftest.exe 2>/dev/null;
+- ls a.out conftest 2>/dev/null;
+- ls a.* conftest.* 2>/dev/null`; do
++# b.out is created by i960 compilers.
++for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
++do
++ test -f "$ac_file" || continue
+ case $ac_file in
+- *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb | *.xSYM ) ;;
+- a.out ) # We found the default executable, but exeext='' is most
+- # certainly right.
+- break;;
+- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+- # FIXME: I believe we export ac_cv_exeext for Libtool --akim.
+- export ac_cv_exeext
+- break;;
+- * ) break;;
++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
++ ;;
++ conftest.$ac_ext )
++ # This is the source file.
++ ;;
++ [ab].out )
++ # We found the default executable, but exeext='' is most
++ # certainly right.
++ break;;
++ *.* )
++ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
++ # FIXME: I believe we export ac_cv_exeext for Libtool,
++ # but it would be cool to find out if it's true. Does anybody
++ # maintain Libtool? --akim.
++ export ac_cv_exeext
++ break;;
++ * )
++ break;;
+ esac
+ done
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables" >&5
+-echo "$as_me: error: C compiler cannot create executables" >&2;}
++sed 's/^/| /' conftest.$ac_ext >&5
++
++{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
++See \`config.log' for more details." >&5
++echo "$as_me: error: C compiler cannot create executables
++See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+ fi
+
+@@ -2331,9 +2417,11 @@
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+-If you meant to cross compile, use \`--host'." >&5
++If you meant to cross compile, use \`--host'.
++See \`config.log' for more details." >&5
+ echo "$as_me: error: cannot run C compiled programs.
+-If you meant to cross compile, use \`--host'." >&2;}
++If you meant to cross compile, use \`--host'.
++See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+@@ -2341,7 +2429,7 @@
+ echo "$as_me:$LINENO: result: yes" >&5
+ echo "${ECHO_T}yes" >&6
+
+-rm -f a.out a.exe conftest$ac_cv_exeext
++rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ ac_clean_files=$ac_clean_files_save
+ # Check the compiler produces executables we can run. If not, either
+ # the compiler is broken, or we cross compile.
+@@ -2361,9 +2449,10 @@
+ # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+ # work properly (i.e., refer to `conftest.exe'), while it won't with
+ # `rm'.
+-for ac_file in `(ls conftest.exe; ls conftest; ls conftest.*) 2>/dev/null`; do
++for ac_file in conftest.exe conftest conftest.*; do
++ test -f "$ac_file" || continue
+ case $ac_file in
+- *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;;
++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ export ac_cv_exeext
+ break;;
+@@ -2371,8 +2460,10 @@
+ esac
+ done
+ else
+- { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link" >&5
+-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link" >&2;}
++ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
++See \`config.log' for more details." >&5
++echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
++See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+@@ -2390,14 +2481,12 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -2414,16 +2503,19 @@
+ (exit $ac_status); }; then
+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+ case $ac_file in
+- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb ) ;;
++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+ done
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile" >&5
+-echo "$as_me: error: cannot compute suffix of object files: cannot compile" >&2;}
++sed 's/^/| /' conftest.$ac_ext >&5
++
++{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
++See \`config.log' for more details." >&5
++echo "$as_me: error: cannot compute suffix of object files: cannot compile
++See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+@@ -2440,14 +2532,12 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -2474,7 +2564,8 @@
+ ac_compiler_gnu=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_compiler_gnu=no
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+@@ -2494,14 +2585,12 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -2525,7 +2614,8 @@
+ ac_cv_prog_cc_g=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_prog_cc_g=no
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+@@ -2547,6 +2637,102 @@
+ CFLAGS=
+ fi
+ fi
++echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
++echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
++if test "${ac_cv_prog_cc_stdc+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_cv_prog_cc_stdc=no
++ac_save_CC=$CC
++cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
++#include <stdarg.h>
++#include <stdio.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
++struct buf { int x; };
++FILE * (*rcsopen) (struct buf *, struct stat *, int);
++static char *e (p, i)
++ char **p;
++ int i;
++{
++ return p[i];
++}
++static char *f (char * (*g) (char **, int), char **p, ...)
++{
++ char *s;
++ va_list v;
++ va_start (v,p);
++ s = g (p, va_arg (v,int));
++ va_end (v);
++ return s;
++}
++int test (int i, double x);
++struct s1 {int (*f) (int a);};
++struct s2 {int (*f) (double a);};
++int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
++int argc;
++char **argv;
++int
++main ()
++{
++return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
++ ;
++ return 0;
++}
++_ACEOF
++# Don't try gcc -ansi; that turns off useful extensions and
++# breaks some systems' header files.
++# AIX -qlanglvl=ansi
++# Ultrix and OSF/1 -std1
++# HP-UX 10.20 and later -Ae
++# HP-UX older versions -Aa -D_HPUX_SOURCE
++# SVR4 -Xc -D__EXTENSIONS__
++for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
++do
++ CC="$ac_save_CC $ac_arg"
++ rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_cv_prog_cc_stdc=$ac_arg
++break
++else
++ echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++fi
++rm -f conftest.$ac_objext
++done
++rm -f conftest.$ac_ext conftest.$ac_objext
++CC=$ac_save_CC
++
++fi
++
++case "x$ac_cv_prog_cc_stdc" in
++ x|xno)
++ echo "$as_me:$LINENO: result: none needed" >&5
++echo "${ECHO_T}none needed" >&6 ;;
++ *)
++ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
++echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
++ CC="$CC $ac_cv_prog_cc_stdc" ;;
++esac
++
+ # Some people use a C++ compiler to compile C. Since we use `exit',
+ # in C++ we need to declare it. In case someone uses the same compiler
+ # for both compiling C and C++ we need to have the C++ compiler decide
+@@ -2579,15 +2765,13 @@
+ do
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <stdlib.h>
+ $ac_declaration
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -2611,20 +2795,19 @@
+ :
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ continue
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ $ac_declaration
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -2648,7 +2831,8 @@
+ break
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+ done
+@@ -2661,7 +2845,8 @@
+
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+@@ -2680,7 +2865,7 @@
+ rmdir .deps 2>/dev/null
+
+
+-ac_config_commands="$ac_config_commands depfiles"
++ ac_config_commands="$ac_config_commands depfiles"
+
+
+ am_make=${MAKE-make}
+@@ -2932,14 +3117,12 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -2966,7 +3149,8 @@
+ ac_compiler_gnu=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_compiler_gnu=no
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+@@ -2986,14 +3170,12 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -3017,7 +3199,8 @@
+ ac_cv_prog_cxx_g=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_prog_cxx_g=no
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+@@ -3050,15 +3233,13 @@
+ do
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <stdlib.h>
+ $ac_declaration
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -3082,20 +3263,19 @@
+ :
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ continue
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ $ac_declaration
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -3119,7 +3299,8 @@
+ break
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+ done
+@@ -3751,7 +3932,11 @@
+ LIBS="-ldl $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+@@ -3760,12 +3945,6 @@
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ char dlopen ();
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -3789,7 +3968,8 @@
+ ac_cv_lib_dl_dlopen=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_lib_dl_dlopen=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -3936,6 +4116,13 @@
+ ;;
+ mips*-*-linux*)
+ ;;
++ mips-unknown-elf*)
++ machdep="mips2java_mach_dep.lo"
++ cat >>confdefs.h <<\_ACEOF
++#define MIPS2JAVA 1
++_ACEOF
++
++ ;;
+ mips-*-*)
+ machdep="mips_sgi_mach_dep.lo"
+ cat >>confdefs.h <<\_ACEOF
+@@ -4595,18 +4782,28 @@
+ do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
++ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
++ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
+-#include <assert.h>
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
++#ifdef __STDC__
++# include <limits.h>
++#else
++# include <assert.h>
++#endif
+ Syntax error
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
++ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+@@ -4623,7 +4820,8 @@
+ :
+ else
+ echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ # Broken: fails on valid input.
+ continue
+ fi
+@@ -4633,13 +4831,17 @@
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <ac_nonexistent.h>
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
++ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+@@ -4657,7 +4859,8 @@
+ continue
+ else
+ echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ # Passes both tests.
+ ac_preproc_ok=:
+ break
+@@ -4686,18 +4889,28 @@
+ do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
++ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
++ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
+-#include <assert.h>
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
++#ifdef __STDC__
++# include <limits.h>
++#else
++# include <assert.h>
++#endif
+ Syntax error
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
++ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+@@ -4714,7 +4927,8 @@
+ :
+ else
+ echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ # Broken: fails on valid input.
+ continue
+ fi
+@@ -4724,13 +4938,17 @@
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <ac_nonexistent.h>
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
++ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+@@ -4748,7 +4966,8 @@
+ continue
+ else
+ echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ # Passes both tests.
+ ac_preproc_ok=:
+ break
+@@ -4761,8 +4980,10 @@
+ if $ac_preproc_ok; then
+ :
+ else
+- { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check" >&5
+-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check" >&2;}
++ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
++See \`config.log' for more details." >&5
++echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
++See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+@@ -4773,6 +4994,21 @@
+ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
++echo "$as_me:$LINENO: checking for egrep" >&5
++echo $ECHO_N "checking for egrep... $ECHO_C" >&6
++if test "${ac_cv_prog_egrep+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
++ then ac_cv_prog_egrep='grep -E'
++ else ac_cv_prog_egrep='egrep'
++ fi
++fi
++echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
++echo "${ECHO_T}$ac_cv_prog_egrep" >&6
++ EGREP=$ac_cv_prog_egrep
++
++
+ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+ echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+ if test "${ac_cv_header_stdc+set}" = set; then
+@@ -4780,48 +5016,59 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <string.h>
+ #include <float.h>
+
++int
++main ()
++{
++
++ ;
++ return 0;
++}
+ _ACEOF
+-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
+ ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
+- rm -f conftest.er1
+- cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } >/dev/null; then
+- if test -s conftest.err; then
+- ac_cpp_err=$ac_c_preproc_warn_flag
+- else
+- ac_cpp_err=
+- fi
+-else
+- ac_cpp_err=yes
+-fi
+-if test -z "$ac_cpp_err"; then
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+ else
+ echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
+- ac_cv_header_stdc=no
++sed 's/^/| /' conftest.$ac_ext >&5
++
++ac_cv_header_stdc=no
+ fi
+-rm -f conftest.err conftest.$ac_ext
++rm -f conftest.$ac_objext conftest.$ac_ext
+
+ if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <string.h>
+
+ _ACEOF
+ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+- egrep "memchr" >/dev/null 2>&1; then
++ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+ else
+ ac_cv_header_stdc=no
+@@ -4834,12 +5081,16 @@
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <stdlib.h>
+
+ _ACEOF
+ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+- egrep "free" >/dev/null 2>&1; then
++ $EGREP "free" >/dev/null 2>&1; then
+ :
+ else
+ ac_cv_header_stdc=no
+@@ -4855,13 +5106,18 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <ctype.h>
+ #if ((' ' & 0x0FF) == 0x020)
+ # define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+ # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+ #else
+-# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \
++# define ISLOWER(c) \
++ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+ # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+@@ -4894,11 +5150,12 @@
+ else
+ echo "$as_me: program exited with status $ac_status" >&5
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ( exit $ac_status )
+ ac_cv_header_stdc=no
+ fi
+-rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
++rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ fi
+ fi
+ fi
+@@ -4933,7 +5190,11 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ $ac_includes_default
+
+ #include <$ac_header>
+@@ -4953,7 +5214,8 @@
+ eval "$as_ac_Header=yes"
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ eval "$as_ac_Header=no"
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+@@ -4988,7 +5250,11 @@
+ echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ $ac_includes_default
+ #include <$ac_header>
+ _ACEOF
+@@ -5007,7 +5273,8 @@
+ ac_header_compiler=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_header_compiler=no
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+@@ -5019,13 +5286,17 @@
+ echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <$ac_header>
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
++ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+@@ -5042,7 +5313,8 @@
+ ac_header_preproc=yes
+ else
+ echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_header_preproc=no
+ fi
+ rm -f conftest.err conftest.$ac_ext
+@@ -5055,14 +5327,32 @@
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+ echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
++echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
++ (
++ cat <<\_ASBOX
++## ------------------------------------ ##
++## Report this to bug-autoconf@gnu.org. ##
++## ------------------------------------ ##
++_ASBOX
++ ) |
++ sed "s/^/$as_me: WARNING: /" >&2
++ ;;
+ no:yes )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+ echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+ echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
++echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
++ (
++ cat <<\_ASBOX
++## ------------------------------------ ##
++## Report this to bug-autoconf@gnu.org. ##
++## ------------------------------------ ##
++_ASBOX
++ ) |
++ sed "s/^/$as_me: WARNING: /" >&2
++ ;;
+ esac
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+@@ -5403,7 +5693,7 @@
+ case $host in
+ *-*-irix6*)
+ # Find out which ABI we are using.
+- echo '#line 5406 "configure"' > conftest.$ac_ext
++ echo '#line 5696 "configure"' > conftest.$ac_ext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+@@ -5443,14 +5733,12 @@
+
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -5474,7 +5762,8 @@
+ lt_cv_cc_needs_belf=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ lt_cv_cc_needs_belf=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -5777,14 +6066,12 @@
+ CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -5823,7 +6110,8 @@
+
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ lt_cv_prog_cc_pic_works=no
+
+ fi
+@@ -5866,14 +6154,12 @@
+ LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -5897,7 +6183,8 @@
+ lt_cv_prog_cc_static_works=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+@@ -5939,7 +6226,7 @@
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
+ compiler_c_o=no
+-if { (eval echo configure:5942: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
++if { (eval echo configure:6229: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s out/conftest.err; then
+@@ -5981,14 +6268,12 @@
+ ac_objext=lo
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -6019,7 +6304,8 @@
+
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+ ac_objext="$save_objext"
+@@ -6067,14 +6353,12 @@
+ compiler_rtti_exceptions=no
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -6105,7 +6389,8 @@
+
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="$save_CFLAGS"
+@@ -7326,37 +7611,44 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ /* System header to define __stub macros and hopefully few prototypes,
+- which can conflict with char shl_load (); below. */
+-#include <assert.h>
++ which can conflict with char shl_load (); below.
++ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
++ <limits.h> exists even on freestanding compilers. */
++#ifdef __STDC__
++# include <limits.h>
++#else
++# include <assert.h>
++#endif
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+ extern "C"
++{
+ #endif
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ char shl_load ();
+-char (*f) ();
+-
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
+ /* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+ #if defined (__stub_shl_load) || defined (__stub___shl_load)
+ choke me
+ #else
+-f = shl_load;
++char (*f) () = shl_load;
++#endif
++#ifdef __cplusplus
++}
+ #endif
+
++int
++main ()
++{
++return f != shl_load;
+ ;
+ return 0;
+ }
+@@ -7376,7 +7668,8 @@
+ ac_cv_func_shl_load=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_func_shl_load=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -7395,7 +7688,11 @@
+ LIBS="-ldld $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+@@ -7404,12 +7701,6 @@
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ char shl_load ();
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -7433,7 +7724,8 @@
+ ac_cv_lib_dld_shl_load=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_lib_dld_shl_load=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -7451,37 +7743,44 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ /* System header to define __stub macros and hopefully few prototypes,
+- which can conflict with char dlopen (); below. */
+-#include <assert.h>
++ which can conflict with char dlopen (); below.
++ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
++ <limits.h> exists even on freestanding compilers. */
++#ifdef __STDC__
++# include <limits.h>
++#else
++# include <assert.h>
++#endif
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+ extern "C"
++{
+ #endif
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ char dlopen ();
+-char (*f) ();
+-
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
+ /* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+ #if defined (__stub_dlopen) || defined (__stub___dlopen)
+ choke me
+ #else
+-f = dlopen;
++char (*f) () = dlopen;
++#endif
++#ifdef __cplusplus
++}
+ #endif
+
++int
++main ()
++{
++return f != dlopen;
+ ;
+ return 0;
+ }
+@@ -7501,7 +7800,8 @@
+ ac_cv_func_dlopen=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_func_dlopen=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -7520,7 +7820,11 @@
+ LIBS="-ldl $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+@@ -7529,12 +7833,6 @@
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ char dlopen ();
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -7558,7 +7856,8 @@
+ ac_cv_lib_dl_dlopen=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_lib_dl_dlopen=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -7578,7 +7877,11 @@
+ LIBS="-lsvld $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+@@ -7587,12 +7890,6 @@
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ char dlopen ();
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -7616,7 +7913,8 @@
+ ac_cv_lib_svld_dlopen=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_lib_svld_dlopen=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -7636,7 +7934,11 @@
+ LIBS="-ldld $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+@@ -7645,12 +7947,6 @@
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ char dld_link ();
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -7674,7 +7970,8 @@
+ ac_cv_lib_dld_dld_link=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_lib_dld_dld_link=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -7732,7 +8029,7 @@
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+-#line 7735 "configure"
++#line 8032 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -7830,7 +8127,7 @@
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+-#line 7833 "configure"
++#line 8130 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -8575,7 +8872,11 @@
+ echo $ECHO_N "checking sys/dg_sys_info.h usability... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ $ac_includes_default
+ #include <sys/dg_sys_info.h>
+ _ACEOF
+@@ -8594,7 +8895,8 @@
+ ac_header_compiler=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_header_compiler=no
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+@@ -8606,13 +8908,17 @@
+ echo $ECHO_N "checking sys/dg_sys_info.h presence... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <sys/dg_sys_info.h>
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
++ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+@@ -8629,7 +8935,8 @@
+ ac_header_preproc=yes
+ else
+ echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_header_preproc=no
+ fi
+ rm -f conftest.err conftest.$ac_ext
+@@ -8642,14 +8949,32 @@
+ { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: accepted by the compiler, rejected by the preprocessor!" >&5
+ echo "$as_me: WARNING: sys/dg_sys_info.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&5
+-echo "$as_me: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&2;};;
++echo "$as_me: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&2;}
++ (
++ cat <<\_ASBOX
++## ------------------------------------ ##
++## Report this to bug-autoconf@gnu.org. ##
++## ------------------------------------ ##
++_ASBOX
++ ) |
++ sed "s/^/$as_me: WARNING: /" >&2
++ ;;
+ no:yes )
+ { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: present but cannot be compiled" >&5
+ echo "$as_me: WARNING: sys/dg_sys_info.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: check for missing prerequisite headers?" >&5
+ echo "$as_me: WARNING: sys/dg_sys_info.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&5
+-echo "$as_me: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&2;};;
++echo "$as_me: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&2;}
++ (
++ cat <<\_ASBOX
++## ------------------------------------ ##
++## Report this to bug-autoconf@gnu.org. ##
++## ------------------------------------ ##
++_ASBOX
++ ) |
++ sed "s/^/$as_me: WARNING: /" >&2
++ ;;
+ esac
+ echo "$as_me:$LINENO: checking for sys/dg_sys_info.h" >&5
+ echo $ECHO_N "checking for sys/dg_sys_info.h... $ECHO_C" >&6
+@@ -8880,8 +9205,8 @@
+ fi
+
+
+-ac_config_files="$ac_config_files Makefile doc/Makefile include/Makefile"
+-ac_config_commands="$ac_config_commands default"
++ ac_config_files="$ac_config_files Makefile doc/Makefile include/Makefile"
++ ac_config_commands="$ac_config_commands default"
+ cat >confcache <<\_ACEOF
+ # This file is a shell script that caches the results of configure
+ # tests run on this system so they can be shared between configure
+@@ -8892,7 +9217,7 @@
+ # config.status only pays attention to the cache file if you give it
+ # the --recheck option to rerun configure.
+ #
+-# `ac_cv_env_foo' variables (set or unset) will be overriden when
++# `ac_cv_env_foo' variables (set or unset) will be overridden when
+ # loading this file, other *unset* `ac_cv_foo' will be assigned the
+ # following values.
+
+@@ -8927,7 +9252,7 @@
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+-if cmp -s $cache_file confcache; then :; else
++if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+@@ -8989,6 +9314,21 @@
+ rm -f confdef2opt.sed
+
+
++ac_libobjs=
++ac_ltlibobjs=
++for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
++ # 1. Remove the extension, and $U if already installed.
++ ac_i=`echo "$ac_i" |
++ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
++ # 2. Add them.
++ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
++ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
++done
++LIBOBJS=$ac_libobjs
++
++LTLIBOBJS=$ac_ltlibobjs
++
++
+ if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+ Usually this means the macro was only invoked conditionally." >&5
+@@ -9038,11 +9378,12 @@
+ # configure, is in config.log if it exists.
+
+ debug=false
++ac_cs_recheck=false
++ac_cs_silent=false
+ SHELL=\${CONFIG_SHELL-$SHELL}
+ _ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+-
+ ## --------------------- ##
+ ## M4sh Initialization. ##
+ ## --------------------- ##
+@@ -9051,11 +9392,13 @@
+ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
++ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
++ # is contrary to our usage. Disable this feature.
++ alias -g '${1+"$@"}'='"$@"'
+ elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+ fi
+
+-# NLS nuisances.
+ # Support unset when possible.
+ if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+ as_unset=unset
+@@ -9063,34 +9406,42 @@
+ as_unset=false
+ fi
+
+-(set +x; test -n "`(LANG=C; export LANG) 2>&1`") &&
+- { $as_unset LANG || test "${LANG+set}" != set; } ||
+- { LANG=C; export LANG; }
+-(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") &&
+- { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } ||
+- { LC_ALL=C; export LC_ALL; }
+-(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") &&
+- { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } ||
+- { LC_TIME=C; export LC_TIME; }
+-(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") &&
+- { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } ||
+- { LC_CTYPE=C; export LC_CTYPE; }
+-(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") &&
+- { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } ||
+- { LANGUAGE=C; export LANGUAGE; }
+-(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") &&
+- { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } ||
+- { LC_COLLATE=C; export LC_COLLATE; }
+-(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") &&
+- { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } ||
+- { LC_NUMERIC=C; export LC_NUMERIC; }
+-(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") &&
+- { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } ||
+- { LC_MESSAGES=C; export LC_MESSAGES; }
++
++# Work around bugs in pre-3.0 UWIN ksh.
++$as_unset ENV MAIL MAILPATH
++PS1='$ '
++PS2='> '
++PS4='+ '
++
++# NLS nuisances.
++for as_var in \
++ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
++ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
++ LC_TELEPHONE LC_TIME
++do
++ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
++ eval $as_var=C; export $as_var
++ else
++ $as_unset $as_var
++ fi
++done
++
++# Required to use basename.
++if expr a : '\(a\)' >/dev/null 2>&1; then
++ as_expr=expr
++else
++ as_expr=false
++fi
++
++if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
++ as_basename=basename
++else
++ as_basename=false
++fi
+
+
+ # Name of the executable.
+-as_me=`(basename "$0") 2>/dev/null ||
++as_me=`$as_basename "$0" ||
+ $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+@@ -9101,6 +9452,7 @@
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
++
+ # PATH needs CR, and LINENO needs CR and PATH.
+ # Avoid depending upon Character Ranges.
+ as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+@@ -9111,15 +9463,15 @@
+
+ # The user is always right.
+ if test "${PATH_SEPARATOR+set}" != set; then
+- echo "#! /bin/sh" >conftest.sh
+- echo "exit 0" >>conftest.sh
+- chmod +x conftest.sh
+- if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then
++ echo "#! /bin/sh" >conf$$.sh
++ echo "exit 0" >>conf$$.sh
++ chmod +x conf$$.sh
++ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+- rm -f conftest.sh
++ rm -f conf$$.sh
+ fi
+
+
+@@ -9168,6 +9520,8 @@
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
++ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
++ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+@@ -9241,6 +9595,12 @@
+ fi
+ rm -f conf$$ conf$$.exe conf$$.file
+
++if mkdir -p . 2>/dev/null; then
++ as_mkdir_p=:
++else
++ as_mkdir_p=false
++fi
++
+ as_executable_p="test -f"
+
+ # Sed expression to map a string onto a valid CPP name.
+@@ -9257,7 +9617,7 @@
+ IFS=" $as_nl"
+
+ # CDPATH.
+-$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; }
++$as_unset CDPATH
+
+ exec 6>&1
+
+@@ -9274,7 +9634,7 @@
+ cat >&5 <<_CSEOF
+
+ This file was extended by gc $as_me 6.3alpha2, which was
+-generated by GNU Autoconf 2.53. Invocation command line was
++generated by GNU Autoconf 2.57. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+@@ -9314,6 +9674,7 @@
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
++ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+@@ -9331,7 +9692,7 @@
+ cat >>$CONFIG_STATUS <<_ACEOF
+ ac_cs_version="\\
+ gc config.status 6.3alpha2
+-configured by $0, generated by GNU Autoconf 2.53,
++configured by $0, generated by GNU Autoconf 2.57,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+@@ -9352,25 +9713,25 @@
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+- shift
+- set dummy "$ac_option" "$ac_optarg" ${1+"$@"}
+- shift
++ ac_shift=:
++ ;;
++ -*)
++ ac_option=$1
++ ac_optarg=$2
++ ac_shift=shift
+ ;;
+- -*);;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
++ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+- case $1 in
++ case $ac_option in
+ # Handling of the options.
+ _ACEOF
+-cat >>$CONFIG_STATUS <<_ACEOF
+- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+- echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion"
+- exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;;
+-_ACEOF
+ cat >>$CONFIG_STATUS <<\_ACEOF
++ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
++ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+@@ -9385,13 +9746,16 @@
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+- shift
+- CONFIG_FILES="$CONFIG_FILES $1"
++ $ac_shift
++ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+- shift
+- CONFIG_HEADERS="$CONFIG_HEADERS $1"
++ $ac_shift
++ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
++ | -silent | --silent | --silen | --sile | --sil | --si | --s)
++ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+@@ -9406,6 +9770,20 @@
+ shift
+ done
+
++ac_configure_extra_args=
++
++if $ac_cs_silent; then
++ exec 6>/dev/null
++ ac_configure_extra_args="$ac_configure_extra_args --silent"
++fi
++
++_ACEOF
++cat >>$CONFIG_STATUS <<_ACEOF
++if \$ac_cs_recheck; then
++ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
++ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
++fi
++
+ _ACEOF
+
+ cat >>$CONFIG_STATUS <<_ACEOF
+@@ -9450,6 +9828,9 @@
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+ fi
+
++# Have a temporary directory for convenience. Make it in the build tree
++# simply because there is no reason to put it here, and in addition,
++# creating and moving files from /tmp can sometimes cause problems.
+ # Create a temporary directory, and hook for its removal unless debugging.
+ $debug ||
+ {
+@@ -9458,17 +9839,17 @@
+ }
+
+ # Create a (secure) tmp directory for tmp files.
+-: ${TMPDIR=/tmp}
++
+ {
+- tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` &&
++ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+ } ||
+ {
+- tmp=$TMPDIR/cs$$-$RANDOM
++ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+ } ||
+ {
+- echo "$me: cannot create a temporary directory in $TMPDIR" >&2
++ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+ }
+
+@@ -9590,10 +9971,13 @@
+ s,@LN_S@,$LN_S,;t t
+ s,@ECHO@,$ECHO,;t t
+ s,@CPP@,$CPP,;t t
++s,@EGREP@,$EGREP,;t t
+ s,@LIBTOOL@,$LIBTOOL,;t t
+ s,@MY_CFLAGS@,$MY_CFLAGS,;t t
+ s,@USE_LIBDIR_TRUE@,$USE_LIBDIR_TRUE,;t t
+ s,@USE_LIBDIR_FALSE@,$USE_LIBDIR_FALSE,;t t
++s,@LIBOBJS@,$LIBOBJS,;t t
++s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+ CEOF
+
+ _ACEOF
+@@ -9664,25 +10048,30 @@
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+- { case "$ac_dir" in
+- [\\/]* | ?:[\\/]* ) as_incr_dir=;;
+- *) as_incr_dir=.;;
+-esac
+-as_dummy="$ac_dir"
+-for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
+- case $as_mkdir_dir in
+- # Skip DOS drivespec
+- ?:) as_incr_dir=$as_mkdir_dir ;;
+- *)
+- as_incr_dir=$as_incr_dir/$as_mkdir_dir
+- test -d "$as_incr_dir" ||
+- mkdir "$as_incr_dir" ||
+- { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5
+-echo "$as_me: error: cannot create \"$ac_dir\"" >&2;}
+- { (exit 1); exit 1; }; }
+- ;;
+- esac
+-done; }
++ { if $as_mkdir_p; then
++ mkdir -p "$ac_dir"
++ else
++ as_dir="$ac_dir"
++ as_dirs=
++ while test ! -d "$as_dir"; do
++ as_dirs="$as_dir $as_dirs"
++ as_dir=`(dirname "$as_dir") 2>/dev/null ||
++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$as_dir" : 'X\(//\)[^/]' \| \
++ X"$as_dir" : 'X\(//\)$' \| \
++ X"$as_dir" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$as_dir" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ done
++ test ! -n "$as_dirs" || mkdir $as_dirs
++ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
++echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
++ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+@@ -9712,7 +10101,7 @@
+ # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+ # absolute.
+ ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+-ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
++ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+@@ -9842,7 +10231,7 @@
+ # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+ # absolute.
+ ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+-ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
++ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+@@ -9911,25 +10300,30 @@
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+- { case $dirpart/$fdir in
+- [\\/]* | ?:[\\/]* ) as_incr_dir=;;
+- *) as_incr_dir=.;;
+-esac
+-as_dummy=$dirpart/$fdir
+-for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
+- case $as_mkdir_dir in
+- # Skip DOS drivespec
+- ?:) as_incr_dir=$as_mkdir_dir ;;
+- *)
+- as_incr_dir=$as_incr_dir/$as_mkdir_dir
+- test -d "$as_incr_dir" ||
+- mkdir "$as_incr_dir" ||
+- { { echo "$as_me:$LINENO: error: cannot create $dirpart/$fdir" >&5
+-echo "$as_me: error: cannot create $dirpart/$fdir" >&2;}
+- { (exit 1); exit 1; }; }
+- ;;
+- esac
+-done; }
++ { if $as_mkdir_p; then
++ mkdir -p $dirpart/$fdir
++ else
++ as_dir=$dirpart/$fdir
++ as_dirs=
++ while test ! -d "$as_dir"; do
++ as_dirs="$as_dir $as_dirs"
++ as_dir=`(dirname "$as_dir") 2>/dev/null ||
++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$as_dir" : 'X\(//\)[^/]' \| \
++ X"$as_dir" : 'X\(//\)$' \| \
++ X"$as_dir" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$as_dir" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ done
++ test ! -n "$as_dirs" || mkdir $as_dirs
++ fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
++echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
++ { (exit 1); exit 1; }; }; }
+
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+@@ -9958,8 +10352,11 @@
+ # need to make the FD available again.
+ if test "$no_create" != yes; then
+ ac_cs_success=:
++ ac_config_status_args=
++ test "$silent" = yes &&
++ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+- $SHELL $CONFIG_STATUS || ac_cs_success=false
++ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+diff -ruN ../gc6.3alpha2/configure.in ./configure.in
+--- ../gc6.3alpha2/configure.in Mon Sep 29 14:13:34 2003
++++ ./configure.in Wed Nov 19 04:17:15 2003
+@@ -275,6 +275,10 @@
+ ;;
+ mips*-*-linux*)
+ ;;
++ mips-unknown-elf*)
++ machdep="mips2java_mach_dep.lo"
++ AC_DEFINE(MIPS2JAVA)
++ ;;
+ mips-*-*)
+ machdep="mips_sgi_mach_dep.lo"
+ AC_DEFINE(NO_EXECUTE_PERMISSION)
+diff -ruN ../gc6.3alpha2/include/private/gcconfig.h ./include/private/gcconfig.h
+--- ../gc6.3alpha2/include/private/gcconfig.h Wed Sep 3 14:16:01 2003
++++ ./include/private/gcconfig.h Wed Nov 19 04:47:25 2003
+@@ -115,7 +115,7 @@
+ # if defined(nec_ews) || defined(_nec_ews)
+ # define EWS4800
+ # endif
+-# if !defined(LINUX) && !defined(EWS4800)
++# if !defined(LINUX) && !defined(EWS4800) && !defined(MIPS2JAVA)
+ # if defined(ultrix) || defined(__ultrix) || defined(__NetBSD__)
+ # define ULTRIX
+ # else
+@@ -1236,6 +1236,16 @@
+
+ # ifdef MIPS
+ # define MACH_TYPE "MIPS"
++
++# ifdef MIPS2JAVA
++extern int _etext[];
++extern int _end[];
++# define ALIGNMENT 4
++# define STACKBOTTOM 0x10000000
++# define DATASTART (_etext)
++# define DATAEND (_end)
++# endif /* MIPS2JAVA */
++
+ # ifdef LINUX
+ /* This was developed for a linuxce style platform. Probably */
+ /* needs to be tweaked for workstation class machines. */
+diff -ruN ../gc6.3alpha2/mips2java_mach_dep.s ./mips2java_mach_dep.s
+--- ../gc6.3alpha2/mips2java_mach_dep.s Wed Dec 31 19:00:00 1969
++++ ./mips2java_mach_dep.s Wed Nov 19 04:56:28 2003
+@@ -0,0 +1,43 @@
++ .set noreorder
++ .text
++ .align 2
++ .globl GC_push_regs
++ .ent GC_push_regs
++GC_push_regs:
++ subu $sp,$sp,24
++ sw $31,20($sp)
++
++ jal GC_push_one
++ move $4,$1
++ jal GC_push_one
++ move $4,$16
++ jal GC_push_one
++ move $4,$17
++ jal GC_push_one
++ move $4,$18
++ jal GC_push_one
++ move $4,$19
++ jal GC_push_one
++ move $4,$20
++ jal GC_push_one
++ move $4,$21
++ jal GC_push_one
++ move $4,$22
++ jal GC_push_one
++ move $4,$23
++ jal GC_push_one
++ move $4,$26
++ jal GC_push_one
++ move $4,$27
++ jal GC_push_one
++ move $4,$28
++ jal GC_push_one
++ move $4,$29
++ jal GC_push_one
++ move $4,$30
++
++ lw $31,20($sp)
++ j $31
++ addu $sp,$sp,24
++
++ .end GC_push_regs
+diff -ruN ../gc6.3alpha2/os_dep.c ./os_dep.c
+--- ../gc6.3alpha2/os_dep.c Mon Sep 22 18:49:47 2003
++++ ./os_dep.c Wed Nov 19 04:12:13 2003
+@@ -497,7 +497,7 @@
+ # if !defined(PCR) && !defined(AMIGA) && !defined(MSWIN32) \
+ && !defined(MSWINCE) \
+ && !defined(MACOS) && !defined(DJGPP) && !defined(DOS4GW) \
+- && !defined(NOSYS) && !defined(ECOS)
++ && !defined(NOSYS) && !defined(ECOS) && !defined(MIPS2JAVA) \
+
+ # if defined(sigmask) && !defined(UTS4) && !defined(HURD)
+ /* Use the traditional BSD interface */
--- /dev/null
+Only in .: BusyBox.class
+Only in .: BusyBox.java
+diff -ur ../busybox-0.60.5/Config.h ./Config.h
+--- ../busybox-0.60.5/Config.h Tue Sep 17 18:04:28 2002
++++ ./Config.h Tue Nov 25 11:05:07 2003
+@@ -12,95 +12,95 @@
+ #define BB_ASH
+ #define BB_BASENAME
+ #define BB_CAT
+-#define BB_CHGRP
+-#define BB_CHMOD
+-#define BB_CHOWN
+-#define BB_CHROOT
+-#define BB_CHVT
++//#define BB_CHGRP
++//#define BB_CHMOD
++//#define BB_CHOWN
++//#define BB_CHROOT
++//#define BB_CHVT
+ #define BB_CLEAR
+-//#define BB_CMP
+-#define BB_CP
++#define BB_CMP
++//#define BB_CP
+ //#define BB_CPIO
+ #define BB_CUT
+ #define BB_DATE
+ //#define BB_DC
+-#define BB_DD
++//#define BB_DD
+ //#define BB_DEALLOCVT
+-#define BB_DF
++//#define BB_DF
+ #define BB_DIRNAME
+-#define BB_DMESG
++//#define BB_DMESG
+ //#define BB_DOS2UNIX
+ //#define BB_DPKG
+ //#define BB_DPKG_DEB
+ //#define BB_DUTMP
+-#define BB_DU
++//#define BB_DU
+ //#define BB_DUMPKMAP
+ #define BB_ECHO
+-#define BB_ENV
++//#define BB_ENV
+ //#define BB_EXPR
+ //#define BB_FBSET
+ //#define BB_FDFLUSH
+-#define BB_FIND
+-#define BB_FREE
++//#define BB_FIND
++//#define BB_FREE
+ //#define BB_FREERAMDISK
+ //#define BB_FSCK_MINIX
+ //#define BB_GETOPT
+ #define BB_GREP
+-#define BB_GUNZIP
++//#define BB_GUNZIP
+ #define BB_GZIP
+-#define BB_HALT
++//#define BB_HALT
+ #define BB_HEAD
+ //#define BB_HOSTID
+ //#define BB_HOSTNAME
+ //#define BB_HUSH
+-#define BB_ID
++//#define BB_ID
+ //#define BB_IFCONFIG
+-#define BB_INIT
++//#define BB_INIT
+ //#define BB_INSMOD
+-#define BB_KILL
+-#define BB_KILLALL
+-#define BB_KLOGD
++//#define BB_KILL
++//#define BB_KILLALL
++//#define BB_KLOGD
+ //#define BB_LASH
+ //#define BB_LENGTH
+-#define BB_LN
++//#define BB_LN
+ //#define BB_LOADACM
+ //#define BB_LOADFONT
+ //#define BB_LOADKMAP
+-#define BB_LOGGER
++//#define BB_LOGGER
+ //#define BB_LOGNAME
+ //#define BB_LOSETUP
+ #define BB_LS
+-#define BB_LSMOD
++//#define BB_LSMOD
+ //#define BB_MAKEDEVS
+-//#define BB_MD5SUM
++#define BB_MD5SUM
+ #define BB_MKDIR
+ //#define BB_MKFIFO
+ //#define BB_MKFS_MINIX
+-#define BB_MKNOD
+-#define BB_MKSWAP
++//#define BB_MKNOD
++//#define BB_MKSWAP
+ //#define BB_MKTEMP
+-#define BB_MODPROBE
+-#define BB_MORE
+-#define BB_MOUNT
++//#define BB_MODPROBE
++//#define BB_MORE
++//#define BB_MOUNT
+ //#define BB_MSH
+ //#define BB_MT
+-#define BB_MV
++//#define BB_MV
+ //#define BB_NC
+ //#define BB_NSLOOKUP
+-#define BB_PIDOF
++//#define BB_PIDOF
+ //#define BB_PING
+ //#define BB_PIVOT_ROOT
+-#define BB_POWEROFF
+-//#define BB_PRINTF
+-#define BB_PS
+-#define BB_PWD
++//#define BB_POWEROFF
++#define BB_PRINTF
++//#define BB_PS
++//#define BB_PWD
+ //#define BB_RDATE
+ //#define BB_READLINK
+-#define BB_REBOOT
++//#define BB_REBOOT
+ //#define BB_RENICE
+ #define BB_RESET
+-#define BB_RM
+-#define BB_RMDIR
++//#define BB_RM
++//#define BB_RMDIR
+ //#define BB_RMMOD
+ //#define BB_ROUTE
+ //#define BB_RPM2CPIO
+@@ -109,13 +109,13 @@
+ #define BB_SLEEP
+ #define BB_SORT
+ //#define BB_STTY
+-#define BB_SWAPONOFF
+-#define BB_SYNC
+-#define BB_SYSLOGD
++//#define BB_SWAPONOFF
++//#define BB_SYNC
++//#define BB_SYSLOGD
+ #define BB_TAIL
+-#define BB_TAR
+-//#define BB_TEE
+-//#define BB_TEST
++//#define BB_TAR
++#define BB_TEE
++#define BB_TEST
+ //#define BB_TELNET
+ //#define BB_TFTP
+ //#define BB_TIME
+@@ -124,15 +124,15 @@
+ //#define BB_TR
+ //#define BB_TRACEROUTE
+ #define BB_TRUE_FALSE
+-#define BB_TTY
++//#define BB_TTY
+ //#define BB_UNIX2DOS
+ //#define BB_UUENCODE
+ //#define BB_UUDECODE
+-#define BB_UMOUNT
++//#define BB_UMOUNT
+ #define BB_UNIQ
+-#define BB_UNAME
++//#define BB_UNAME
+ //#define BB_UPDATE
+-#define BB_UPTIME
++//#define BB_UPTIME
+ //#define BB_USLEEP
+ //#define BB_VI
+ //#define BB_WATCHDOG
+@@ -140,7 +140,7 @@
+ //#define BB_WGET
+ #define BB_WHICH
+ #define BB_WHOAMI
+-#define BB_XARGS
++//#define BB_XARGS
+ #define BB_YES
+ // End of Applications List
+ //
+@@ -182,13 +182,13 @@
+ //#define BB_FEATURE_USE_DEVPS_PATCH
+ //
+ // show verbose usage messages
+-#define BB_FEATURE_VERBOSE_USAGE
++//#define BB_FEATURE_VERBOSE_USAGE
+ //
+ // Use termios to manipulate the screen ('more' is prettier with this on)
+ //#define BB_FEATURE_USE_TERMIOS
+ //
+ // calculate terminal & column widths (for more, ls, and telnet)
+-#define BB_FEATURE_AUTOWIDTH
++//#define BB_FEATURE_AUTOWIDTH
+ //
+ // show username/groupnames for ls
+ #define BB_FEATURE_LS_USERNAME
+@@ -271,11 +271,11 @@
+ //
+ // Enable command line editing in the shell.
+ // Only relevant if a shell is enabled. On by default.
+-#define BB_FEATURE_COMMAND_EDITING
++//#define BB_FEATURE_COMMAND_EDITING
+ //
+ // Enable tab completion in the shell. This is now working quite nicely.
+ // This feature adds a bit over 4k. Only relevant if a shell is enabled.
+-#define BB_FEATURE_COMMAND_TAB_COMPLETION
++//#define BB_FEATURE_COMMAND_TAB_COMPLETION
+ //
+ // Attempts to match usernames in a ~-prefixed path
+ //#define BB_FEATURE_COMMAND_USERNAME_COMPLETION
+@@ -284,7 +284,7 @@
+ //were shell builtins. Nice for staticly linking an emergency rescue shell,
+ //among other things. Off by default.
+ // Only relevant if a shell is enabled.
+-//#define BB_FEATURE_SH_STANDALONE_SHELL
++#define BB_FEATURE_SH_STANDALONE_SHELL
+ //
+ //When this is enabled, busybox shell applets can be called using full path
+ //names. This causes applets (i.e., most busybox commands) to override
+@@ -306,7 +306,7 @@
+ // are doing is running scripts). Disabing this is bad for interactive
+ // use, since when you hit ^C in an application, it will also kill the
+ // shell. This adds about 2.5k on an x86 system.
+-#define BB_FEATURE_ASH_JOB_CONTROL
++//#define BB_FEATURE_ASH_JOB_CONTROL
+ //
+ //Turn on extra fbset options
+ //#define BB_FEATURE_FBSET_FANCY
+@@ -371,7 +371,7 @@
+ #define BB_FEATURE_FIND_TYPE
+ //
+ // Support for the find -perm option.
+-#define BB_FEATURE_FIND_PERM
++//#define BB_FEATURE_FIND_PERM
+ //
+ // Support for the find -mtime option.
+ #define BB_FEATURE_FIND_MTIME
+@@ -420,7 +420,10 @@
+ // Nothing beyond this point should ever be touched by
+ // mere mortals so leave this stuff alone.
+ //
++#ifdef _GNU_SOURCE
+ #include <features.h>
++#endif
++
+ #if defined(__uClinux__)
+ #undef BB_ASH /* Not even a chance it will work */
+ #undef BB_RPM2CPIO /* Uses gz_open(), which uses fork() */
+diff -ur ../busybox-0.60.5/Makefile ./Makefile
+--- ../busybox-0.60.5/Makefile Sun Oct 27 00:47:54 2002
++++ ./Makefile Tue Nov 25 11:27:30 2003
+@@ -49,7 +49,7 @@
+ # just 1.4k to the binary size (which is a _lot_ less then glibc NSS costs).
+ # Note that if you want hostname resolution to work with glibc, you still need
+ # the libnss_* libraries.
+-USE_SYSTEM_PWD_GRP = true
++USE_SYSTEM_PWD_GRP = false
+
+ # This enables compiling with dmalloc ( http://dmalloc.com/ )
+ # which is an excellent public domain mem leak and malloc problem
+@@ -83,7 +83,7 @@
+
+ # If you are running a cross compiler, you may want to set this
+ # to something more interesting, like "powerpc-linux-".
+-CROSS =
++CROSS = mips-unknown-elf-
+ CC = $(CROSS)gcc
+ AR = $(CROSS)ar
+ STRIP = $(CROSS)strip
+@@ -106,11 +106,11 @@
+ #
+ # For other libraries, you are on your own...
+ #LDFLAGS+=-nostdlib
+-#LIBRARIES = $(LIBCDIR)/lib/libc.a -lgcc
++LIBRARIES = -lglob -lregex
+ #CROSS_CFLAGS+=-nostdinc -I$(LIBCDIR)/include -I$(GCCINCDIR)
+ #GCCINCDIR = $(shell gcc -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp")
+
+-WARNINGS = -Wall -Wshadow
++WARNINGS = -Wall -Wshadow -Werror -Wno-unused
+
+ ARFLAGS = -r
+
+@@ -181,9 +181,9 @@
+ LDFLAGS += -Wl,-warn-common
+ STRIPCMD = /bin/true -Since_we_are_debugging
+ else
+- CFLAGS += $(WARNINGS) $(OPTIMIZATIONS) -D_GNU_SOURCE
+- LDFLAGS += -s -Wl,-warn-common
+- STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment
++ CFLAGS += $(WARNINGS) $(OPTIMIZATIONS) -DNEWLIB_ASH
++ LDFLAGS += -Wl,-warn-common
++ STRIPCMD = true
+ endif
+ ifeq ($(strip $(DOSTATIC)),true)
+ LDFLAGS += --static
+@@ -260,7 +260,7 @@
+ PWD_LIB = libpwd.a
+ PWD_CSRC=__getpwent.c pwent.c getpwnam.c getpwuid.c putpwent.c getpw.c \
+ fgetpwent.c __getgrent.c grent.c getgrnam.c getgrgid.c fgetgrent.c \
+- initgroups.c setgroups.c
++ initgroups.c
+ PWD_OBJS=$(patsubst %.c,$(PWD_GRP)/%.o, $(PWD_CSRC))
+ ifneq ($(strip $(BB_SRC_DIR)),)
+ PWD_CFLAGS = -I- -I.
+@@ -273,19 +273,19 @@
+ LIBBB = libbb
+ LIBBB_LIB = libbb.a
+ LIBBB_CSRC= ask_confirmation.c chomp.c concat_path_file.c copy_file.c \
+-copy_file_chunk.c libc5.c device_open.c error_msg.c inode_hash.c \
+-error_msg_and_die.c fgets_str.c find_mount_point.c find_pid_by_name.c \
+-find_root_device.c full_read.c full_write.c get_console.c \
++copy_file_chunk.c device_open.c error_msg.c inode_hash.c \
++error_msg_and_die.c fgets_str.c find_pid_by_name.c \
++find_root_device.c full_read.c full_write.c \
+ get_last_path_component.c get_line_from_file.c gz_open.c human_readable.c \
+-isdirectory.c kernel_version.c loop.c mode_string.c module_syscalls.c mtab.c \
++isdirectory.c mode_string.c \
+ mtab_file.c my_getgrnam.c my_getgrgid.c my_getpwnam.c my_getpwnamegid.c \
+ my_getpwuid.c parse_mode.c parse_number.c perror_msg.c perror_msg_and_die.c \
+ print_file.c process_escape_sequence.c read_package_field.c recursive_action.c \
+-safe_read.c safe_strncpy.c syscalls.c syslog_msg_with_name.c time_string.c \
++safe_read.c safe_strncpy.c time_string.c \
+ trim.c unzip.c vdprintf.c verror_msg.c vperror_msg.c wfopen.c xfuncs.c \
+-xgetcwd.c xreadlink.c xregcomp.c interface.c remove_file.c last_char_is.c \
+-copyfd.c vherror_msg.c herror_msg.c herror_msg_and_die.c xgethostbyname.c \
+-dirname.c make_directory.c create_icmp_socket.c u_signal_names.c arith.c \
++xgetcwd.c xreadlink.c xregcomp.c remove_file.c last_char_is.c \
++copyfd.c herror_msg.c herror_msg_and_die.c \
++dirname.c make_directory.c u_signal_names.c arith.c \
+ simplify_path.c
+ LIBBB_OBJS=$(patsubst %.c,$(LIBBB)/%.o, $(LIBBB_CSRC))
+ ifeq ($(strip $(BB_SRC_DIR)),)
+diff -ur ../busybox-0.60.5/ash.c ./ash.c
+--- ../busybox-0.60.5/ash.c Tue Oct 22 18:14:29 2002
++++ ./ash.c Tue Nov 25 11:17:08 2003
+@@ -84,11 +84,15 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#ifndef NEWLIB_ASH
+ #include <sysexits.h>
++#endif
+ #include <unistd.h>
+ #include <sys/stat.h>
+ #include <sys/cdefs.h>
++#ifndef NEWLIB_ASH
+ #include <sys/ioctl.h>
++#endif
+ #include <sys/param.h>
+ #include <sys/resource.h>
+ #include <sys/time.h>
+@@ -268,6 +272,7 @@
+ * more fun than worrying about efficiency and portability. :-))
+ */
+
++#ifndef NEWLIB_ASH
+ static void onint(void);
+ static volatile int suppressint;
+ static volatile int intpending;
+@@ -287,6 +292,16 @@
+ #define CLEAR_PENDING_INT intpending = 0
+ #define int_pending() intpending
+
++#else
++
++#define INTON
++#define INTOFF
++#define FORCEINTON
++#define CLEAR_PENDING_INT
++#define int_pending() 0
++
++#endif
++
+
+ typedef void *pointer;
+
+@@ -1556,7 +1571,9 @@
+ #endif
+ static int unsetcmd(int, char **);
+ static int waitcmd(int, char **);
++#ifndef NEWLIB_ASH
+ static int ulimitcmd(int, char **);
++#endif
+ static int timescmd(int, char **);
+
+ #ifdef CONFIG_ASH_MATH_SUPPORT
+@@ -1647,10 +1664,14 @@
+ {BUILTIN_NOSPEC "setvar", setvarcmd},
+ {BUILTIN_SPECIAL "shift", shiftcmd},
+ {BUILTIN_SPECIAL "times", timescmd},
++#ifndef NEWLIB_ASH
+ {BUILTIN_SPECIAL "trap", trapcmd},
++#endif
+ {BUILTIN_REGULAR "true", true_main},
+ {BUILTIN_NOSPEC "type", typecmd},
++#ifndef NEWLIB_ASH
+ {BUILTIN_NOSPEC "ulimit", ulimitcmd},
++#endif
+ {BUILTIN_REGULAR "umask", umaskcmd},
+ #ifdef CONFIG_ASH_ALIAS
+ {BUILTIN_REGULAR "unalias", unaliascmd},
+@@ -1918,6 +1939,8 @@
+ * just defensive programming.)
+ */
+
++#ifndef NEWLIB_ASH
++
+ static void onint(void)
+ {
+ sigset_t mysigset;
+@@ -1937,6 +1960,7 @@
+ /* NOTREACHED */
+ }
+
++#endif
+
+ static char *commandname; /* currently executing command */
+
+@@ -2086,7 +2110,7 @@
+ }
+
+
+-#ifdef CONFIG_ASH_OPTIMIZE_FOR_SIZE
++#if defined(CONFIG_ASH_OPTIMIZE_FOR_SIZE) && !defined(NEWLIB_ASH)
+ static void __inton()
+ {
+ if (--suppressint == 0 && intpending) {
+@@ -5597,7 +5621,6 @@
+
+ static void init(void)
+ {
+-
+ /* from cd.c: */
+ {
+ curdir = nullstr;
+@@ -5621,8 +5644,10 @@
+ }
+ }
+
++#ifndef NEWLIB_ASH
+ snprintf(ppid, sizeof(ppid), "%d", (int) getppid());
+ setvar("PPID", ppid, 0);
++#endif
+ }
+ }
+
+@@ -6214,12 +6239,16 @@
+ else /* WIFSIGNALED(ps->status) */
+ #endif
+ i = WTERMSIG(ps->status);
++#ifndef NEWLIB_ASH
+ if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F])
+ strcpy(s, sys_siglist[i & 0x7F]);
+ else
++#endif
+ snprintf(s, 64, "Signal %d", i & 0x7F);
++#ifndef NEWLIB_ASH
+ if (WCOREDUMP(ps->status))
+ strcat(s, " (core dumped)");
++#endif
+ }
+ out1str(s);
+ col += strlen(s);
+@@ -6641,7 +6670,11 @@
+ #endif
+ if (block == 0)
+ flags |= WNOHANG;
++#ifndef NEWLIB_ASH
+ return wait3(status, flags, (struct rusage *) NULL);
++#else
++ return waitpid(-1,status,flags);
++#endif
+ }
+
+ static int dowait(int block, struct job *job)
+@@ -6700,7 +6733,9 @@
+ }
+ INTON;
+ if (!rootshell || !iflag || (job && thisjob == job)) {
++#ifndef NEWLIB_ASH
+ core = WCOREDUMP(status);
++#endif
+ #ifdef BB_FEATURE_ASH_JOB_CONTROL
+ if (WIFSTOPPED(status))
+ sig = WSTOPSIG(status);
+@@ -6718,12 +6753,16 @@
+ if (sig == SIGTSTP && rootshell && iflag)
+ out2fmt("%%%ld ", (long) (job - jobtab + 1));
+ #endif
++#ifndef NEWLIB_ASH
+ if (sig < NSIG && sys_siglist[sig])
+ out2str(sys_siglist[sig]);
+ else
++#endif
+ out2fmt("Signal %d", sig);
++#ifndef NEWLIB_ASH
+ if (core)
+ out2str(" - core dumped");
++#endif
+ out2c('\n');
+ } else {
+ TRACE(("Not printing status: status=%d, sig=%d\n", status, sig));
+@@ -7993,6 +8032,8 @@
+ {NULL, 0, 0}
+ };
+
++#ifndef NEWLIB_ASH
++
+ static int ulimitcmd(int argc, char **argv)
+ {
+ static const char unlimited_string[] = "unlimited";
+@@ -8118,6 +8159,8 @@
+ return 0;
+ }
+
++#endif /* !NEWLIB_ASH */
++
+ /*
+ * prefix -- see if pfx is a prefix of string.
+ */
+@@ -11426,6 +11469,8 @@
+ * The trap builtin.
+ */
+
++#ifndef NEWLIB_ASH
++
+ static int trapcmd(int argc, char **argv)
+ {
+ char *action;
+@@ -11475,6 +11520,7 @@
+ return 0;
+ }
+
++#endif /*!NEWLIB_ASH */
+
+ /*
+ * Set the signal handler for the specified signal. The routine figures
+@@ -11485,7 +11531,9 @@
+ {
+ int action;
+ char *t;
++#ifndef NEWLIB_ASH
+ struct sigaction act;
++#endif
+
+ if ((t = trap[signo]) == NULL)
+ action = S_DFL;
+@@ -11527,6 +11575,7 @@
+ /*
+ * current setting unknown
+ */
++#ifndef NEWLIB_ASH
+ if (sigaction(signo, 0, &act) == -1) {
+ /*
+ * Pretend it worked; maybe we should give a warning
+@@ -11536,6 +11585,7 @@
+ return;
+ }
+ if (act.sa_handler == SIG_IGN) {
++
+ if (mflag && (signo == SIGTSTP ||
+ signo == SIGTTIN || signo == SIGTTOU)) {
+ *t = S_IGN; /* don't hard ignore these */
+@@ -11544,15 +11594,22 @@
+ } else {
+ *t = S_RESET; /* force to be set */
+ }
++#else
++ *t = S_DFL;
++#endif
+ }
+ if (*t == S_HARD_IGN || *t == action)
+ return;
++ *t = action;
++#ifndef NEWLIB_ASH
+ act.sa_handler = ((action == S_CATCH) ? onsig
+ : ((action == S_IGN) ? SIG_IGN : SIG_DFL));
+- *t = action;
+ act.sa_flags = 0;
+ sigemptyset(&act.sa_mask);
+ sigaction(signo, &act, 0);
++#else
++ signal(signo,((action == S_CATCH) ? onsig : ((action == S_IGN) ? SIG_IGN : SIG_DFL)));
++#endif
+ }
+
+ /*
+@@ -11574,10 +11631,12 @@
+
+ static void onsig(int signo)
+ {
++#ifndef NEWLIB_ASH
+ if (signo == SIGINT && trap[SIGINT] == NULL) {
+ onint();
+ return;
+ }
++#endif
+ gotsig[signo - 1] = 1;
+ pendingsigs++;
+ }
+@@ -12153,6 +12212,7 @@
+
+ static struct var **findvar(struct var **vpp, const char *name)
+ {
++ int n=0;
+ for (; *vpp; vpp = &(*vpp)->next) {
+ if (varequal((*vpp)->text, name)) {
+ break;
+@@ -12168,8 +12228,11 @@
+ static int timescmd(int argc, char **argv)
+ {
+ struct tms buf;
++#ifdef NEWLIB_ASH
++ long int clk_tck = _CLOCKS_PER_SEC_;
++#else
+ long int clk_tck = sysconf(_SC_CLK_TCK);
+-
++#endif
+ times(&buf);
+ printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n",
+ (int) (buf.tms_utime / clk_tck / 60),
+diff -ur ../busybox-0.60.5/busybox.h ./busybox.h
+--- ../busybox-0.60.5/busybox.h Fri Mar 15 21:11:46 2002
++++ ./busybox.h Tue Nov 25 11:10:52 2003
+@@ -37,8 +37,9 @@
+ #include "dmalloc.h"
+ #endif
+
++#ifdef _GNU_SOURCE
+ #include <features.h>
+-
++#endif
+
+ enum Location {
+ _BB_DIR_ROOT = 0,
+@@ -85,7 +86,9 @@
+
+ /* Bit map related macros -- libc5 doens't provide these... sigh. */
+ #ifndef setbit
++#ifndef NBBY
+ #define NBBY CHAR_BIT
++#endif
+ #define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
+ #define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+ #define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
+Only in ../busybox-0.60.5: busybox.links
+diff -ur ../busybox-0.60.5/busybox.sh ./busybox.sh
+--- ../busybox-0.60.5/busybox.sh Wed Sep 26 02:20:54 2001
++++ ./busybox.sh Tue Nov 25 10:57:58 2003
+@@ -5,7 +5,7 @@
+
+ RAW=` \
+ $CC -E -dM ${1:-Config.h} | \
+- sed -n -e '/^.*BB_FEATURE.*$/d;s/^#define.*\<BB_\(.*\)\>/\1.c/gp;' \
++ sed -n -e '/^.*BB_FEATURE.*$/d;s/^#define.*BB_\([A-Z0-9_]*\)/\1.c/gp;' \
+ | tr A-Z a-z | sort
+ `
+ test "${RAW}" != "" || exit
+diff -ur ../busybox-0.60.5/date.c ./date.c
+--- ../busybox-0.60.5/date.c Sat Jun 15 10:35:13 2002
++++ ./date.c Tue Nov 25 11:26:25 2003
+@@ -210,9 +210,7 @@
+
+ /* if setting time, set it */
+ if (set_time) {
+- if (stime(&tm) < 0) {
+- perror_msg("cannot set date");
+- }
++ perror_msg("cannot set date");
+ }
+ }
+
+Only in ../busybox-0.60.5/docs: BusyBox.1
+Only in ../busybox-0.60.5/docs: BusyBox.html
+Only in ../busybox-0.60.5/docs: BusyBox.txt
+Only in ../busybox-0.60.5/docs: busybox.pod
+diff -ur ../busybox-0.60.5/libbb/libbb.h ./libbb/libbb.h
+--- ../busybox-0.60.5/libbb/libbb.h Wed Sep 18 15:21:07 2002
++++ ./libbb/libbb.h Tue Nov 25 11:10:27 2003
+@@ -25,8 +25,6 @@
+ #include <sys/stat.h>
+ #include <sys/types.h>
+
+-#include <netdb.h>
+-
+ #ifndef _BB_INTERNAL_H_
+ #include "../busybox.h"
+ #endif
+@@ -35,7 +33,9 @@
+ #include "dmalloc.h"
+ #endif
+
++#ifdef _GNU_SOURCE
+ #include <features.h>
++#endif
+
+ #if (__GNU_LIBRARY__ < 5) && (!defined __dietlibc__)
+ /* libc5 doesn't define socklen_t */
+diff -ur ../busybox-0.60.5/ls.c ./ls.c
+--- ../busybox-0.60.5/ls.c Mon Sep 16 01:53:01 2002
++++ ./ls.c Tue Nov 25 11:29:41 2003
+@@ -43,7 +43,7 @@
+
+ enum {
+ TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */
+- COLUMN_WIDTH = 14, /* default if AUTOWIDTH not defined */
++ COLUMN_WIDTH = 18, /* default if AUTOWIDTH not defined */
+ COLUMN_GAP = 2, /* includes the file type char */
+ };
+
+@@ -61,8 +61,10 @@
+ #include <stdlib.h>
+ #include <fcntl.h>
+ #include <signal.h>
++#ifdef BB_FEATURE_AUTOWIDTH
+ #include <termios.h>
+ #include <sys/ioctl.h>
++#endif
+ #include "busybox.h"
+
+ #ifdef BB_FEATURE_LS_TIMESTAMPS
+@@ -484,7 +486,7 @@
+ column_width = COLUMN_WIDTH;
+ }
+ #else
+- ncols= TERMINAL_WIDTH;
++ ncols= (int) (TERMINAL_WIDTH / (COLUMN_WIDTH+COLUMN_GAP));
+ #endif
+ switch (style_fmt) {
+ case STYLE_LONG: /* one record per line, extended info */
+diff -ur ../busybox-0.60.5/md5sum.c ./md5sum.c
+--- ../busybox-0.60.5/md5sum.c Tue Oct 22 18:13:57 2002
++++ ./md5sum.c Tue Nov 25 11:22:37 2003
+@@ -44,13 +44,17 @@
+ #include <getopt.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <endian.h>
+ #include <sys/types.h>
+ #if defined HAVE_LIMITS_H
+ # include <limits.h>
+ #endif
+ #include "busybox.h"
+
++typedef unsigned int u_int32_t;
++#ifndef __P
++#define __P(x) x
++#endif
++
+ /* For some silly reason, this file uses backwards TRUE and FALSE conventions */
+ #undef TRUE
+ #undef FALSE
+@@ -146,11 +150,7 @@
+ //----------------------------------------------------------------------------
+
+ /* Handle endian-ness */
+-#if __BYTE_ORDER == __LITTLE_ENDIAN
+- #define SWAP(n) (n)
+-#else
+- #define SWAP(n) ((n << 24) | ((n&65280)<<8) | ((n&16711680)>>8) | (n>>24))
+-#endif
++#define SWAP(n) ((n << 24) | ((n&65280)<<8) | ((n&16711680)>>8) | (n>>24))
+
+
+
+diff -ur ../busybox-0.60.5/printf.c ./printf.c
+--- ../busybox-0.60.5/printf.c Mon Mar 19 14:25:49 2001
++++ ./printf.c Tue Nov 25 11:22:49 2003
+@@ -57,6 +57,10 @@
+ #include <ctype.h>
+ #include "busybox.h"
+
++#ifndef __P
++#define __P(x) x
++#endif
++
+
+ #ifndef S_IFMT
+ static const int S_IFMT = 0170000;
+diff -ur ../busybox-0.60.5/pwd_grp/grp.h ./pwd_grp/grp.h
+--- ../busybox-0.60.5/pwd_grp/grp.h Sat Jan 27 03:24:39 2001
++++ ./pwd_grp/grp.h Tue Nov 25 11:05:36 2003
+@@ -5,8 +5,14 @@
+ #include <grp.h>
+ #else
+
++#ifndef __P
++#define __P(x) x
++#endif
++
+ #include <sys/types.h>
++#ifdef _GNU_SOURCE
+ #include <features.h>
++#endif
+ #include <stdio.h>
+
+ /* The group structure */
+diff -ur ../busybox-0.60.5/pwd_grp/pwd.h ./pwd_grp/pwd.h
+--- ../busybox-0.60.5/pwd_grp/pwd.h Sat Jan 27 03:24:39 2001
++++ ./pwd_grp/pwd.h Tue Nov 25 11:05:09 2003
+@@ -5,8 +5,14 @@
+ #include <pwd.h>
+ #else
+
++#ifndef __P
++#define __P(x) x
++#endif
++
+ #include <sys/types.h>
++#ifdef _GNU_SOURCE
+ #include <features.h>
++#endif
+ #include <stdio.h>
+
+ /* The passwd structure. */
--- /dev/null
+--- include/freetype/config/ftmodule.h Thu Jul 31 12:59:06 2003
++++ include/freetype/config/ftmodule.h Thu Jul 31 12:59:17 2003
+@@ -1,4 +1,5 @@
+ FT_USE_MODULE(autohint_module_class)
++/*
+ FT_USE_MODULE(cff_driver_class)
+ FT_USE_MODULE(t1cid_driver_class)
+ FT_USE_MODULE(pcf_driver_class)
+@@ -7,13 +8,15 @@
+ FT_USE_MODULE(psnames_module_class)
+ FT_USE_MODULE(pshinter_module_class)
+ FT_USE_MODULE(ft_raster1_renderer_class)
++*/
+ FT_USE_MODULE(sfnt_module_class)
+ FT_USE_MODULE(ft_smooth_renderer_class)
+ FT_USE_MODULE(ft_smooth_lcd_renderer_class)
+ FT_USE_MODULE(ft_smooth_lcdv_renderer_class)
+ FT_USE_MODULE(tt_driver_class)
++/*
+ FT_USE_MODULE(t1_driver_class)
+ FT_USE_MODULE(t42_driver_class)
+ FT_USE_MODULE(pfr_driver_class)
+ FT_USE_MODULE(winfnt_driver_class)
+-
++*/
--- /dev/null
+--- src/base/ftsystem.c.origf Mon Dec 29 05:45:54 2003
++++ src/base/ftsystem.c Mon Dec 29 05:46:08 2003
+@@ -32,7 +32,8 @@
+ #include FT_ERRORS_H
+ #include FT_TYPES_H
+
+-#include <stdio.h>
++#include <fcntl.h>
++#include <unistd.h>
+ #include <stdlib.h>
+
+
+@@ -151,7 +152,7 @@
+
+ /* We use the macro STREAM_FILE for convenience to extract the */
+ /* system-specific stream handle from a given FreeType stream object */
+-#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer )
++#define STREAM_FD( stream ) ( (int)stream->descriptor.value )
+
+
+ /*************************************************************************/
+@@ -168,7 +169,7 @@
+ FT_CALLBACK_DEF( void )
+ ft_ansi_stream_close( FT_Stream stream )
+ {
+- fclose( STREAM_FILE( stream ) );
++ close(STREAM_FD(stream));
+
+ stream->descriptor.pointer = NULL;
+ stream->size = 0;
+@@ -202,14 +203,14 @@
+ unsigned char* buffer,
+ unsigned long count )
+ {
+- FILE* file;
++ int fd;
+
+
+- file = STREAM_FILE( stream );
++ fd = STREAM_FD( stream );
+
+- fseek( file, offset, SEEK_SET );
++ if(lseek( fd, offset, SEEK_SET ) < 0) return 0;
+
+- return (unsigned long)fread( buffer, 1, count, file );
++ return (unsigned long) read(fd,buffer,count);
+ }
+
+
+@@ -219,14 +220,14 @@
+ FT_Stream_Open( FT_Stream stream,
+ const char* filepathname )
+ {
+- FILE* file;
++ int fd,n;
+
+
+ if ( !stream )
+ return FT_Err_Invalid_Stream_Handle;
+
+- file = fopen( filepathname, "rb" );
+- if ( !file )
++ fd = open( filepathname, O_RDONLY);
++ if (fd < 0)
+ {
+ FT_ERROR(( "FT_Stream_Open:" ));
+ FT_ERROR(( " could not open `%s'\n", filepathname ));
+@@ -234,11 +235,11 @@
+ return FT_Err_Cannot_Open_Resource;
+ }
+
+- fseek( file, 0, SEEK_END );
+- stream->size = ftell( file );
+- fseek( file, 0, SEEK_SET );
++ n = lseek( fd, 0, SEEK_END );
++ stream-> size = n < 0 ? 0 : n;
++ lseek( fd, 0, SEEK_SET );
+
+- stream->descriptor.pointer = file;
++ stream->descriptor.value = fd;
+ stream->pathname.pointer = (char*)filepathname;
+ stream->pos = 0;
+
--- /dev/null
+--- gcc/config/mips/mips.c.orig Mon Dec 29 06:30:42 2003
++++ gcc/config/mips/mips.c Mon Dec 29 07:16:35 2003
+@@ -10535,11 +10535,13 @@
+ int len, size, sec;
+ const char *name, *prefix;
+ char *string;
+- static const char *const prefixes[4][2] = {
++ static const char *const prefixes[6][2] = {
+ { ".text.", ".gnu.linkonce.t." },
+ { ".rodata.", ".gnu.linkonce.r." },
+ { ".data.", ".gnu.linkonce.d." },
+- { ".sdata.", ".gnu.linkonce.s." }
++ { ".sdata.", ".gnu.linkonce.s." },
++ { ".bss.", ".gnu.linkonce.b." },
++ { ".sbss.", ".gnu.linkonce.sb." }
+ };
+
+ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+@@ -10551,8 +10553,9 @@
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ sec = 0;
+ else if (DECL_INITIAL (decl) == 0
+- || DECL_INITIAL (decl) == error_mark_node)
+- sec = 2;
++ || DECL_INITIAL (decl) == error_mark_node
++ || initializer_zerop (DECL_INITIAL (decl)))
++ sec = (size > 0 && size <= mips_section_threshold) ? 5 : 4;
+ else if ((TARGET_EMBEDDED_PIC || TARGET_MIPS16)
+ && TREE_CODE (decl) == STRING_CST
+ && !flag_writable_strings)
--- /dev/null
+diff -urN ../gcc-3.3.1/gcc/builtin-attrs.def ./gcc/builtin-attrs.def
+--- ../gcc-3.3.1/gcc/builtin-attrs.def Tue Mar 4 09:37:20 2003
++++ ./gcc/builtin-attrs.def Wed Aug 27 00:09:45 2003
+@@ -110,6 +110,7 @@
+ ATTR_NOTHROW_LIST)
+
+ /* Construct a tree for a format attribute. */
++#if 0
+ #define DEF_FORMAT_ATTRIBUTE(TYPE, FA, VALUES) \
+ DEF_ATTR_TREE_LIST (CONCAT4 (ATTR_,TYPE,_,VALUES), ATTR_NULL, \
+ CONCAT2 (ATTR_,TYPE), CONCAT2 (ATTR_LIST_,VALUES)) \
+@@ -128,6 +129,32 @@
+ DEF_FORMAT_ATTRIBUTE(STRFTIME,3,3_0)
+ DEF_FORMAT_ATTRIBUTE(STRFMON,3,3_4)
+ #undef DEF_FORMAT_ATTRIBUTE
++#else
++DEF_ATTR_TREE_LIST (ATTR_PRINTF_1_0, ATTR_NULL, ATTR_PRINTF, ATTR_LIST_1_0)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_PRINTF_1_0, ATTR_FORMAT, ATTR_PRINTF_1_0, ATTR_NONNULL_1)
++DEF_ATTR_TREE_LIST (ATTR_PRINTF_1_2, ATTR_NULL, ATTR_PRINTF, ATTR_LIST_1_2)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_PRINTF_1_2, ATTR_FORMAT, ATTR_PRINTF_1_2, ATTR_NONNULL_1)
++DEF_ATTR_TREE_LIST (ATTR_PRINTF_2_0, ATTR_NULL, ATTR_PRINTF, ATTR_LIST_2_0)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_PRINTF_2_0, ATTR_FORMAT, ATTR_PRINTF_2_0, ATTR_NONNULL_2)
++DEF_ATTR_TREE_LIST (ATTR_PRINTF_2_3, ATTR_NULL, ATTR_PRINTF, ATTR_LIST_2_3)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_PRINTF_2_3, ATTR_FORMAT, ATTR_PRINTF_2_3, ATTR_NONNULL_2)
++DEF_ATTR_TREE_LIST (ATTR_PRINTF_3_0, ATTR_NULL, ATTR_PRINTF, ATTR_LIST_3_0)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_PRINTF_3_0, ATTR_FORMAT, ATTR_PRINTF_3_0, ATTR_NONNULL_3)
++DEF_ATTR_TREE_LIST (ATTR_PRINTF_3_4, ATTR_NULL, ATTR_PRINTF, ATTR_LIST_3_4)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_PRINTF_3_4, ATTR_FORMAT, ATTR_PRINTF_3_4, ATTR_NONNULL_3)
++DEF_ATTR_TREE_LIST (ATTR_SCANF_1_0, ATTR_NULL, ATTR_SCANF, ATTR_LIST_1_0)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_SCANF_1_0, ATTR_FORMAT, ATTR_SCANF_1_0, ATTR_NONNULL_1)
++DEF_ATTR_TREE_LIST (ATTR_SCANF_1_2, ATTR_NULL, ATTR_SCANF, ATTR_LIST_1_2)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_SCANF_1_2, ATTR_FORMAT, ATTR_SCANF_1_2, ATTR_NONNULL_1)
++DEF_ATTR_TREE_LIST (ATTR_SCANF_2_0, ATTR_NULL, ATTR_SCANF, ATTR_LIST_2_0)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_SCANF_2_0, ATTR_FORMAT, ATTR_SCANF_2_0, ATTR_NONNULL_2)
++DEF_ATTR_TREE_LIST (ATTR_SCANF_2_3, ATTR_NULL, ATTR_SCANF, ATTR_LIST_2_3)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_SCANF_2_3, ATTR_FORMAT, ATTR_SCANF_2_3, ATTR_NONNULL_2)
++DEF_ATTR_TREE_LIST (ATTR_STRFTIME_3_0, ATTR_NULL, ATTR_STRFTIME, ATTR_LIST_3_0)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_STRFTIME_3_0, ATTR_FORMAT, ATTR_STRFTIME_3_0, ATTR_NONNULL_3)
++DEF_ATTR_TREE_LIST (ATTR_STRFMON_3_4, ATTR_NULL, ATTR_STRFMON, ATTR_LIST_3_4)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_STRFMON_3_4, ATTR_FORMAT, ATTR_STRFMON_3_4, ATTR_NONNULL_3)
++#endif
+
+ /* Construct a tree for a format_arg attribute. */
+ #define DEF_FORMAT_ARG_ATTRIBUTE(FA) \
+diff -urN ../gcc-3.3.1/gcc/config/mips/t-unknown ./gcc/config/mips/t-unknown
+--- ../gcc-3.3.1/gcc/config/mips/t-unknown Wed Dec 31 19:00:00 1969
++++ ./gcc/config/mips/t-unknown Mon Sep 1 01:19:35 2003
+@@ -0,0 +1,3 @@
++MULTILIB_OPTIONS=
++MULTILIB_DIRNAMES =
++MULTILIB_MATCHES =
+diff -urN ../gcc-3.3.1/gcc/config.gcc ./gcc/config.gcc
+--- ../gcc-3.3.1/gcc/config.gcc Fri Jun 27 07:44:22 2003
++++ ./gcc/config.gcc Sun Aug 31 12:39:12 2003
+@@ -1932,6 +1932,10 @@
+ target_cpu_default="MASK_64BIT|MASK_FLOAT64|MASK_GAS"
+ tm_defines="MIPS_ISA_DEFAULT=64 MIPS_CPU_STRING_DEFAULT=\\\"sb1\\\" MIPS_ABI_DEFAULT=ABI_O64"
+ ;;
++mips*-unknown-elf*)
++ tm_file="${tm_file} mips/elf.h"
++ tmake_file="mips/t-elf mips/t-unknown"
++ ;;
+ mips-*-elf* | mipsel-*-elf*)
+ tm_file="${tm_file} mips/elf.h"
+ tmake_file=mips/t-elf
--- /dev/null
+--- ../libmspack.orig/mspack/Makefile Sat Jul 26 10:44:57 2003
++++ mspack/Makefile Sun Nov 2 17:12:35 2003
+@@ -1,12 +1,13 @@
+ CC=gcc
+ RM=rm -f
+ AR=ar
++RANLIB=ranlib
+
+ WARNINGS=-Wall -Wsign-compare -Wconversion -pedantic
+ LARGEFILE=-std=c99 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+ DEBUG=-g -DDEBUG
+ OPTIM=-O3
+-CFLAGS= $(WARNINGS) $(LARGEFILE) $(DEBUG) $(OPTIM) -I.
++CFLAGS= $(WARNINGS) $(LARGEFILE) $(OPTIM) -I. #-DMSPACK_NO_DEFAULT_SYSTEM
+
+ all: libmspack.a
+
+@@ -27,6 +28,7 @@
+ libmspack.a: $(OBJS)
+ -$(RM) $@
+ $(AR) q $@ $(OBJS)
++ $(RANLIB) $@
+
+ .c.o:
+ $(CC) $(CFLAGS) -o $@ -c $<
--- /dev/null
+--- newlib/libc/stdlib/mallocr.c.old Sun Nov 23 18:41:21 2003
++++ newlib/libc/stdlib/mallocr.c Sun Nov 23 18:43:03 2003
+@@ -301,7 +301,8 @@
+ #define SEPARATE_OBJECTS
+ #define HAVE_MMAP 0
+ #define MORECORE(size) _sbrk_r(reent_ptr, (size))
+-#define MORECORE_CLEARS 0
++#define MORECORE_CLEARS 1
++#define malloc_getpagesize getpagesize()
+ #define MALLOC_LOCK __malloc_lock(reent_ptr)
+ #define MALLOC_UNLOCK __malloc_unlock(reent_ptr)
+
+@@ -310,7 +311,7 @@
+ # undef WIN32
+ #endif
+
+-#ifndef _WIN32
++#if !defined(_WIN32) && !defined(malloc_getpagesize)
+ #ifdef SMALL_MEMORY
+ #define malloc_getpagesize (128)
+ #else
--- /dev/null
+diff -urN ../newlib-1.11.0.orig/libgloss/configure ./libgloss/configure
+--- ../newlib-1.11.0.orig/libgloss/configure Tue Nov 25 09:05:13 2003
++++ ./libgloss/configure Mon Nov 24 20:12:14 2003
+@@ -762,6 +762,9 @@
+ mips*-*-pe)
+ configdirs="wince"
+ ;;
++ mips*-unknown-elf*)
++ configdirs="${configdirs}"
++ ;;
+ mips*-*-*)
+ configdirs="${configdirs} mips testsuite"
+ ;;
+@@ -818,7 +821,7 @@
+ # Extract the first word of "gcc", so it can be a program name with args.
+ set dummy gcc; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:822: checking for $ac_word" >&5
++echo "configure:825: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -848,7 +851,7 @@
+ # Extract the first word of "cc", so it can be a program name with args.
+ set dummy cc; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:852: checking for $ac_word" >&5
++echo "configure:855: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -897,7 +900,7 @@
+ fi
+
+ echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+-echo "configure:901: checking whether we are using GNU C" >&5
++echo "configure:904: checking whether we are using GNU C" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -906,7 +909,7 @@
+ yes;
+ #endif
+ EOF
+-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:910: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
++if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:913: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+ else
+ ac_cv_prog_gcc=no
+@@ -921,7 +924,7 @@
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+-echo "configure:925: checking whether ${CC-cc} accepts -g" >&5
++echo "configure:928: checking whether ${CC-cc} accepts -g" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -953,7 +956,7 @@
+ # Extract the first word of "ar", so it can be a program name with args.
+ set dummy ar; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:957: checking for $ac_word" >&5
++echo "configure:960: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -987,7 +990,7 @@
+ # Extract the first word of "ranlib", so it can be a program name with args.
+ set dummy ranlib; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:991: checking for $ac_word" >&5
++echo "configure:994: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+diff -urN ../newlib-1.11.0.orig/libgloss/configure.in ./libgloss/configure.in
+--- ../newlib-1.11.0.orig/libgloss/configure.in Tue Nov 25 09:05:13 2003
++++ ./libgloss/configure.in Mon Nov 24 20:12:14 2003
+@@ -73,6 +73,9 @@
+ mips*-*-pe)
+ configdirs="wince"
+ ;;
++ mips*-unknown-elf*)
++ configdirs="${configdirs}"
++ ;;
+ mips*-*-*)
+ configdirs="${configdirs} mips testsuite"
+ ;;
+diff -urN ../newlib-1.11.0.orig/newlib/configure.host ./newlib/configure.host
+--- ../newlib-1.11.0.orig/newlib/configure.host Tue Nov 25 09:05:13 2003
++++ ./newlib/configure.host Tue Nov 25 08:30:02 2003
+@@ -356,6 +356,9 @@
+ m8*-bug-*)
+ sys_dir=m88kbug
+ ;;
++ mips*-unknown-elf*)
++ sys_dir=mipsunknown
++ ;;
+ mips*-dec-*)
+ sys_dir=decstation
+ ;;
+@@ -508,6 +511,10 @@
+ newlib_cflags="${newlib_cflags}"
+ syscall_dir=syscalls
+ ;;
++ mips*-unknown-elf*)
++ newlib_cflags="${newlib_cflags} -DREENTRANT_SYSCALLS_PROVIDED -DHAVE_GETTIMEOFDAY -DHAVE_FCNTL"
++ syscall_dir=syscalls
++ ;;
+ mmix-*)
+ syscall_dir=syscalls
+ # We need every symbol 32-bit aligned, so the invalid
+diff -urN ../newlib-1.11.0.orig/newlib/libc/include/paths.h ./newlib/libc/include/paths.h
+--- ../newlib-1.11.0.orig/newlib/libc/include/paths.h Thu Feb 17 14:39:46 2000
++++ ./newlib/libc/include/paths.h Tue Nov 25 09:48:09 2003
+@@ -3,5 +3,6 @@
+
+ #define _PATH_DEV "/dev/"
+ #define _PATH_BSHELL "/bin/sh"
++#define _PATH_DEVNULL "/dev/null"
+
+ #endif /* _PATHS_H_ */
+diff -urN ../newlib-1.11.0.orig/newlib/libc/include/stdlib.h ./newlib/libc/include/stdlib.h
+--- ../newlib-1.11.0.orig/newlib/libc/include/stdlib.h Fri Dec 6 13:58:50 2002
++++ ./newlib/libc/include/stdlib.h Tue Nov 25 09:50:46 2003
+@@ -158,10 +158,12 @@
+ _VOID _EXFUN(cfree,(_PTR));
+ #else
+ char * _EXFUN(realpath,(const char *, char *));
++#endif
+ void _EXFUN(unsetenv,(const char *__string));
+ void _EXFUN(_unsetenv_r,(struct _reent *, const char *__string));
+ int _EXFUN(random,(_VOID));
+ long _EXFUN(srandom,(unsigned __seed));
++#ifdef __CYGWIN__
+ char * _EXFUN(ptsname, (int));
+ int _EXFUN(grantpt, (int));
+ int _EXFUN(unlockpt,(int));
+diff -urN ../newlib-1.11.0.orig/newlib/libc/include/sys/signal.h ./newlib/libc/include/sys/signal.h
+--- ../newlib-1.11.0.orig/newlib/libc/include/sys/signal.h Wed Jul 24 14:18:07 2002
++++ ./newlib/libc/include/sys/signal.h Tue Nov 25 09:56:00 2003
+@@ -142,6 +142,8 @@
+ int _EXFUN(pthread_sigmask, (int how, const sigset_t *set, sigset_t *oset));
+ #endif
+
++int _EXFUN(kill, (int, int));
++
+ /* protos for functions found in winsup sources for CYGWIN */
+ #if defined(__CYGWIN__) || defined(__rtems__)
+ #undef sigaddset
+@@ -150,7 +152,6 @@
+ <sys/types.h> always defines pid_t to be int. If that ever
+ changes, then we will need to do something else, perhaps along the
+ lines of <machine/types.h>. */
+-int _EXFUN(kill, (int, int));
+ int _EXFUN(killpg, (pid_t, int));
+ int _EXFUN(sigaction, (int, const struct sigaction *, struct sigaction *));
+ int _EXFUN(sigaddset, (sigset_t *, const int));
+diff -urN ../newlib-1.11.0.orig/newlib/libc/include/sys/stat.h ./newlib/libc/include/sys/stat.h
+--- ../newlib-1.11.0.orig/newlib/libc/include/sys/stat.h Sat Feb 23 15:46:28 2002
++++ ./newlib/libc/include/sys/stat.h Tue Nov 25 09:41:35 2003
+@@ -127,7 +127,7 @@
+ int _EXFUN(stat,( const char *__path, struct stat *__sbuf ));
+ mode_t _EXFUN(umask,( mode_t __mask ));
+
+-#if defined(__rtems__) || defined(__CYGWIN__)
++#if defined(__rtems__) || defined(__CYGWIN__) || 1
+ int _EXFUN(lstat,( const char *__path, struct stat *__buf ));
+ int _EXFUN(mknod,( const char *__path, mode_t __mode, dev_t __dev ));
+ #endif
+diff -urN ../newlib-1.11.0.orig/newlib/libc/include/sys/unistd.h ./newlib/libc/include/sys/unistd.h
+--- ../newlib-1.11.0.orig/newlib/libc/include/sys/unistd.h Sun Aug 18 02:08:39 2002
++++ ./newlib/libc/include/sys/unistd.h Tue Nov 25 09:46:58 2003
+@@ -158,9 +158,9 @@
+ #endif
+ char * _EXFUN(mktemp, (char *));
+ int _EXFUN(sync, (void));
++#endif
+ int _EXFUN(readlink, (const char *__path, char *__buf, int __buflen));
+ int _EXFUN(symlink, (const char *__name1, const char *__name2));
+-#endif
+
+ #define F_OK 0
+ #define R_OK 4
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/Makefile.am ./newlib/libc/sys/mipsunknown/Makefile.am
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/Makefile.am Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/Makefile.am Mon Nov 24 21:04:11 2003
+@@ -0,0 +1,14 @@
++## Process this file with automake to generate Makefile.in
++
++AUTOMAKE_OPTIONS = cygnus
++
++INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
++
++noinst_LIBRARIES = lib.a
++
++lib_a_SOURCES = syscalls.c
++
++all: crt0.o
++
++ACLOCAL_AMFLAGS = -I ../../..
++CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/Makefile.in ./newlib/libc/sys/mipsunknown/Makefile.in
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/Makefile.in Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/Makefile.in Mon Nov 24 21:04:22 2003
+@@ -0,0 +1,329 @@
++# Makefile.in generated automatically by automake 1.4 from Makefile.am
++
++# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
++# This Makefile.in is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
++
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
++# PARTICULAR PURPOSE.
++
++
++SHELL = @SHELL@
++
++srcdir = @srcdir@
++top_srcdir = @top_srcdir@
++VPATH = @srcdir@
++prefix = @prefix@
++exec_prefix = @exec_prefix@
++
++bindir = @bindir@
++sbindir = @sbindir@
++libexecdir = @libexecdir@
++datadir = @datadir@
++sysconfdir = @sysconfdir@
++sharedstatedir = @sharedstatedir@
++localstatedir = @localstatedir@
++libdir = @libdir@
++infodir = @infodir@
++mandir = @mandir@
++includedir = @includedir@
++oldincludedir = /usr/include
++
++DESTDIR =
++
++pkgdatadir = $(datadir)/@PACKAGE@
++pkglibdir = $(libdir)/@PACKAGE@
++pkgincludedir = $(includedir)/@PACKAGE@
++
++top_builddir = .
++
++ACLOCAL = @ACLOCAL@
++AUTOCONF = @AUTOCONF@
++AUTOMAKE = @AUTOMAKE@
++AUTOHEADER = @AUTOHEADER@
++
++INSTALL = @INSTALL@
++INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
++INSTALL_DATA = @INSTALL_DATA@
++INSTALL_SCRIPT = @INSTALL_SCRIPT@
++transform = @program_transform_name@
++
++NORMAL_INSTALL = :
++PRE_INSTALL = :
++POST_INSTALL = :
++NORMAL_UNINSTALL = :
++PRE_UNINSTALL = :
++POST_UNINSTALL = :
++build_alias = @build_alias@
++build_triplet = @build@
++host_alias = @host_alias@
++host_triplet = @host@
++target_alias = @target_alias@
++target_triplet = @target@
++AR = @AR@
++AS = @AS@
++CC = @CC@
++CPP = @CPP@
++EXEEXT = @EXEEXT@
++LDFLAGS = @LDFLAGS@
++MAINT = @MAINT@
++MAKEINFO = @MAKEINFO@
++NEWLIB_CFLAGS = @NEWLIB_CFLAGS@
++OBJEXT = @OBJEXT@
++PACKAGE = @PACKAGE@
++RANLIB = @RANLIB@
++VERSION = @VERSION@
++aext = @aext@
++libm_machine_dir = @libm_machine_dir@
++machine_dir = @machine_dir@
++newlib_basedir = @newlib_basedir@
++oext = @oext@
++sys_dir = @sys_dir@
++
++AUTOMAKE_OPTIONS = cygnus
++
++INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
++
++noinst_LIBRARIES = lib.a
++
++lib_a_SOURCES = syscalls.c
++
++ACLOCAL_AMFLAGS = -I ../../..
++CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
++mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs
++CONFIG_CLEAN_FILES =
++LIBRARIES = $(noinst_LIBRARIES)
++
++
++DEFS = @DEFS@ -I. -I$(srcdir)
++CPPFLAGS = @CPPFLAGS@
++LIBS = @LIBS@
++lib_a_LIBADD =
++lib_a_OBJECTS = syscalls.o
++CFLAGS = @CFLAGS@
++COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
++CCLD = $(CC)
++LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
++DIST_COMMON = Makefile.am Makefile.in aclocal.m4 configure configure.in
++
++
++DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
++
++TAR = gnutar
++GZIP_ENV = --best
++SOURCES = $(lib_a_SOURCES)
++OBJECTS = $(lib_a_OBJECTS)
++
++all: all-redirect
++.SUFFIXES:
++.SUFFIXES: .S .c .o .s
++$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
++ cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile
++
++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
++ cd $(top_builddir) \
++ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
++
++$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in \
++ ../../../acinclude.m4 ../../../aclocal.m4 \
++ ../../../libtool.m4
++ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
++
++config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
++ $(SHELL) ./config.status --recheck
++$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
++ cd $(srcdir) && $(AUTOCONF)
++
++mostlyclean-noinstLIBRARIES:
++
++clean-noinstLIBRARIES:
++ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
++
++distclean-noinstLIBRARIES:
++
++maintainer-clean-noinstLIBRARIES:
++
++.c.o:
++ $(COMPILE) -c $<
++
++.s.o:
++ $(COMPILE) -c $<
++
++.S.o:
++ $(COMPILE) -c $<
++
++mostlyclean-compile:
++ -rm -f *.o core *.core
++
++clean-compile:
++
++distclean-compile:
++ -rm -f *.tab.c
++
++maintainer-clean-compile:
++
++lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES)
++ -rm -f lib.a
++ $(AR) cru lib.a $(lib_a_OBJECTS) $(lib_a_LIBADD)
++ $(RANLIB) lib.a
++
++tags: TAGS
++
++ID: $(HEADERS) $(SOURCES) $(LISP)
++ list='$(SOURCES) $(HEADERS)'; \
++ unique=`for i in $$list; do echo $$i; done | \
++ awk ' { files[$$0] = 1; } \
++ END { for (i in files) print i; }'`; \
++ here=`pwd` && cd $(srcdir) \
++ && mkid -f$$here/ID $$unique $(LISP)
++
++TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
++ tags=; \
++ here=`pwd`; \
++ list='$(SOURCES) $(HEADERS)'; \
++ unique=`for i in $$list; do echo $$i; done | \
++ awk ' { files[$$0] = 1; } \
++ END { for (i in files) print i; }'`; \
++ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
++ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
++
++mostlyclean-tags:
++
++clean-tags:
++
++distclean-tags:
++ -rm -f TAGS ID
++
++maintainer-clean-tags:
++
++distdir = $(PACKAGE)-$(VERSION)
++top_distdir = $(distdir)
++
++# This target untars the dist file and tries a VPATH configuration. Then
++# it guarantees that the distribution is self-contained by making another
++# tarfile.
++distcheck: dist
++ -rm -rf $(distdir)
++ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
++ mkdir $(distdir)/=build
++ mkdir $(distdir)/=inst
++ dc_install_base=`cd $(distdir)/=inst && pwd`; \
++ cd $(distdir)/=build \
++ && ../configure --srcdir=.. --prefix=$$dc_install_base \
++ && $(MAKE) $(AM_MAKEFLAGS) \
++ && $(MAKE) $(AM_MAKEFLAGS) dvi \
++ && $(MAKE) $(AM_MAKEFLAGS) check \
++ && $(MAKE) $(AM_MAKEFLAGS) install \
++ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
++ && $(MAKE) $(AM_MAKEFLAGS) dist
++ -rm -rf $(distdir)
++ @banner="$(distdir).tar.gz is ready for distribution"; \
++ dashes=`echo "$$banner" | sed s/./=/g`; \
++ echo "$$dashes"; \
++ echo "$$banner"; \
++ echo "$$dashes"
++dist: distdir
++ -chmod -R a+r $(distdir)
++ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
++ -rm -rf $(distdir)
++dist-all: distdir
++ -chmod -R a+r $(distdir)
++ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
++ -rm -rf $(distdir)
++distdir: $(DISTFILES)
++ -rm -rf $(distdir)
++ mkdir $(distdir)
++ -chmod 777 $(distdir)
++ @for file in $(DISTFILES); do \
++ if test -f $$file; then d=.; else d=$(srcdir); fi; \
++ if test -d $$d/$$file; then \
++ cp -pr $$/$$file $(distdir)/$$file; \
++ else \
++ test -f $(distdir)/$$file \
++ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
++ || cp -p $$d/$$file $(distdir)/$$file || :; \
++ fi; \
++ done
++info-am:
++info: info-am
++dvi-am:
++dvi: dvi-am
++check-am:
++check: check-am
++installcheck-am:
++installcheck: installcheck-am
++install-info-am:
++install-info: install-info-am
++install-exec-am:
++install-exec: install-exec-am
++
++install-data-am:
++install-data: install-data-am
++
++install-am: all-am
++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
++install: install-am
++uninstall-am:
++uninstall: uninstall-am
++all-am: Makefile $(LIBRARIES)
++all-redirect: all-am
++install-strip:
++ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
++installdirs:
++
++
++mostlyclean-generic:
++
++clean-generic:
++
++distclean-generic:
++ -rm -f Makefile $(CONFIG_CLEAN_FILES)
++ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
++
++maintainer-clean-generic:
++mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
++ mostlyclean-tags mostlyclean-generic
++
++mostlyclean: mostlyclean-am
++
++clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
++ mostlyclean-am
++
++clean: clean-am
++
++distclean-am: distclean-noinstLIBRARIES distclean-compile \
++ distclean-tags distclean-generic clean-am
++
++distclean: distclean-am
++ -rm -f config.status
++
++maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
++ maintainer-clean-compile maintainer-clean-tags \
++ maintainer-clean-generic distclean-am
++ @echo "This command is intended for maintainers to use;"
++ @echo "it deletes files that may require special tools to rebuild."
++
++maintainer-clean: maintainer-clean-am
++ -rm -f config.status
++
++.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
++clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
++mostlyclean-compile distclean-compile clean-compile \
++maintainer-clean-compile tags mostlyclean-tags distclean-tags \
++clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
++check-am installcheck-am installcheck install-info-am install-info \
++install-exec-am install-exec install-data-am install-data install-am \
++install uninstall-am uninstall all-redirect all-am all installdirs \
++mostlyclean-generic distclean-generic clean-generic \
++maintainer-clean-generic clean mostlyclean distclean maintainer-clean
++
++
++all: crt0.o
++
++# Tell versions [3.59,3.63) of GNU make to not export all variables.
++# Otherwise a system limit (for SysV at least) may be exceeded.
++.NOEXPORT:
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/aclocal.m4 ./newlib/libc/sys/mipsunknown/aclocal.m4
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/aclocal.m4 Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/aclocal.m4 Mon Nov 24 20:40:47 2003
+@@ -0,0 +1,324 @@
++dnl aclocal.m4 generated automatically by aclocal 1.4
++
++dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
++dnl This file is free software; the Free Software Foundation
++dnl gives unlimited permission to copy and/or distribute it,
++dnl with or without modifications, as long as this notice is preserved.
++
++dnl This program is distributed in the hope that it will be useful,
++dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
++dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
++dnl PARTICULAR PURPOSE.
++
++dnl This provides configure definitions used by all the newlib
++dnl configure.in files.
++
++dnl Basic newlib configury. This calls basic introductory stuff,
++dnl including AM_INIT_AUTOMAKE and AC_CANONICAL_HOST. It also runs
++dnl configure.host. The only argument is the relative path to the top
++dnl newlib directory.
++
++AC_DEFUN(NEWLIB_CONFIGURE,
++[
++dnl Default to --enable-multilib
++AC_ARG_ENABLE(multilib,
++[ --enable-multilib build many library versions (default)],
++[case "${enableval}" in
++ yes) multilib=yes ;;
++ no) multilib=no ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for multilib option) ;;
++ esac], [multilib=yes])dnl
++
++dnl Support --enable-target-optspace
++AC_ARG_ENABLE(target-optspace,
++[ --enable-target-optspace optimize for space],
++[case "${enableval}" in
++ yes) target_optspace=yes ;;
++ no) target_optspace=no ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for target-optspace option) ;;
++ esac], [target_optspace=])dnl
++
++dnl Support --enable-malloc-debugging - currently only supported for Cygwin
++AC_ARG_ENABLE(malloc-debugging,
++[ --enable-malloc-debugging indicate malloc debugging requested],
++[case "${enableval}" in
++ yes) malloc_debugging=yes ;;
++ no) malloc_debugging=no ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for malloc-debugging option) ;;
++ esac], [malloc_debugging=])dnl
++
++dnl Support --enable-newlib-mb
++AC_ARG_ENABLE(newlib-mb,
++[ --enable-newlib-mb enable multibyte support],
++[case "${enableval}" in
++ yes) newlib_mb=yes ;;
++ no) newlib_mb=no ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for newlib-mb option) ;;
++ esac], [newlib_mb=])dnl
++
++dnl Support --enable-newlib-multithread
++AC_ARG_ENABLE(newlib-multithread,
++[ --enable-newlib-multithread enable support for multiple threads],
++[case "${enableval}" in
++ yes) newlib_multithread=yes ;;
++ no) newlib_multithread=no ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for newlib-multithread option) ;;
++ esac], [newlib_multithread=yes])dnl
++
++dnl Support --enable-newlib-elix-level
++AC_ARG_ENABLE(newlib-elix-level,
++[ --enable-newlib-elix-level supply desired elix library level (1-4)],
++[case "${enableval}" in
++ 0) newlib_elix_level=0 ;;
++ 1) newlib_elix_level=1 ;;
++ 2) newlib_elix_level=2 ;;
++ 3) newlib_elix_level=3 ;;
++ 4) newlib_elix_level=4 ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for newlib-elix-level option) ;;
++ esac], [newlib_elix_level=0])dnl
++
++dnl Support --disable-newlib-io-float
++AC_ARG_ENABLE(newlib-io-float,
++[ --disable-newlib-io-float disable printf/scanf family float support],
++[case "${enableval}" in
++ yes) newlib_io_float=yes ;;
++ no) newlib_io_float=no ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for newlib-io-float option) ;;
++ esac], [newlib_io_float=yes])dnl
++
++
++dnl We may get other options which we don't document:
++dnl --with-target-subdir, --with-multisrctop, --with-multisubdir
++
++test -z "[$]{with_target_subdir}" && with_target_subdir=.
++
++if test "[$]{srcdir}" = "."; then
++ if test "[$]{with_target_subdir}" != "."; then
++ newlib_basedir="[$]{srcdir}/[$]{with_multisrctop}../$1"
++ else
++ newlib_basedir="[$]{srcdir}/[$]{with_multisrctop}$1"
++ fi
++else
++ newlib_basedir="[$]{srcdir}/$1"
++fi
++AC_SUBST(newlib_basedir)
++
++AC_CANONICAL_SYSTEM
++
++AM_INIT_AUTOMAKE(newlib, 1.11.0)
++
++# FIXME: We temporarily define our own version of AC_PROG_CC. This is
++# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We
++# are probably using a cross compiler, which will not be able to fully
++# link an executable. This should really be fixed in autoconf
++# itself.
++
++AC_DEFUN(LIB_AC_PROG_CC,
++[AC_BEFORE([$0], [AC_PROG_CPP])dnl
++AC_CHECK_PROG(CC, gcc, gcc)
++if test -z "$CC"; then
++ AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc)
++ test -z "$CC" && AC_MSG_ERROR([no acceptable cc found in \$PATH])
++fi
++
++AC_PROG_CC_GNU
++
++if test $ac_cv_prog_gcc = yes; then
++ GCC=yes
++dnl Check whether -g works, even if CFLAGS is set, in case the package
++dnl plays around with CFLAGS (such as to build both debugging and
++dnl normal versions of a library), tasteless as that idea is.
++ ac_test_CFLAGS="${CFLAGS+set}"
++ ac_save_CFLAGS="$CFLAGS"
++ CFLAGS=
++ AC_PROG_CC_G
++ if test "$ac_test_CFLAGS" = set; then
++ CFLAGS="$ac_save_CFLAGS"
++ elif test $ac_cv_prog_cc_g = yes; then
++ CFLAGS="-g -O2"
++ else
++ CFLAGS="-O2"
++ fi
++else
++ GCC=
++ test "${CFLAGS+set}" = set || CFLAGS="-g"
++fi
++])
++
++LIB_AC_PROG_CC
++
++AC_CHECK_TOOL(AS, as)
++AC_CHECK_TOOL(AR, ar)
++AC_CHECK_TOOL(RANLIB, ranlib, :)
++
++AC_PROG_INSTALL
++
++AM_MAINTAINER_MODE
++
++# We need AC_EXEEXT to keep automake happy in cygnus mode. However,
++# at least currently, we never actually build a program, so we never
++# need to use $(EXEEXT). Moreover, the test for EXEEXT normally
++# fails, because we are probably configuring with a cross compiler
++# which can't create executables. So we include AC_EXEEXT to keep
++# automake happy, but we don't execute it, since we don't care about
++# the result.
++if false; then
++ AC_EXEEXT
++fi
++
++. [$]{newlib_basedir}/configure.host
++
++newlib_cflags="[$]{newlib_cflags} -fno-builtin"
++
++NEWLIB_CFLAGS=${newlib_cflags}
++AC_SUBST(NEWLIB_CFLAGS)
++
++LDFLAGS=${ldflags}
++AC_SUBST(LDFLAGS)
++
++AM_CONDITIONAL(ELIX_LEVEL_0, test x[$]{newlib_elix_level} = x0)
++AM_CONDITIONAL(ELIX_LEVEL_1, test x[$]{newlib_elix_level} = x1)
++AM_CONDITIONAL(ELIX_LEVEL_2, test x[$]{newlib_elix_level} = x2)
++AM_CONDITIONAL(ELIX_LEVEL_3, test x[$]{newlib_elix_level} = x3)
++AM_CONDITIONAL(ELIX_LEVEL_4, test x[$]{newlib_elix_level} = x4)
++
++AM_CONDITIONAL(USE_LIBTOOL, test x[$]{use_libtool} = xyes)
++
++# Hard-code OBJEXT. Normally it is set by AC_OBJEXT, but we
++# use oext, which is set in configure.host based on the target platform.
++OBJEXT=${oext}
++
++AC_SUBST(OBJEXT)
++AC_SUBST(oext)
++AC_SUBST(aext)
++
++AC_SUBST(libm_machine_dir)
++AC_SUBST(machine_dir)
++AC_SUBST(sys_dir)
++])
++
++# Do all the work for Automake. This macro actually does too much --
++# some checks are only needed if your package does certain things.
++# But this isn't really a big deal.
++
++# serial 1
++
++dnl Usage:
++dnl AM_INIT_AUTOMAKE(package,version, [no-define])
++
++AC_DEFUN(AM_INIT_AUTOMAKE,
++[AC_REQUIRE([AC_PROG_INSTALL])
++PACKAGE=[$1]
++AC_SUBST(PACKAGE)
++VERSION=[$2]
++AC_SUBST(VERSION)
++dnl test to see if srcdir already configured
++if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
++ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
++fi
++ifelse([$3],,
++AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
++AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
++AC_REQUIRE([AM_SANITY_CHECK])
++AC_REQUIRE([AC_ARG_PROGRAM])
++dnl FIXME This is truly gross.
++missing_dir=`cd $ac_aux_dir && pwd`
++AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
++AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
++AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
++AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
++AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
++AC_REQUIRE([AC_PROG_MAKE_SET])])
++
++#
++# Check to make sure that the build environment is sane.
++#
++
++AC_DEFUN(AM_SANITY_CHECK,
++[AC_MSG_CHECKING([whether build environment is sane])
++# Just in case
++sleep 1
++echo timestamp > conftestfile
++# Do `set' in a subshell so we don't clobber the current shell's
++# arguments. Must try -L first in case configure is actually a
++# symlink; some systems play weird games with the mod time of symlinks
++# (eg FreeBSD returns the mod time of the symlink's containing
++# directory).
++if (
++ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
++ if test "[$]*" = "X"; then
++ # -L didn't work.
++ set X `ls -t $srcdir/configure conftestfile`
++ fi
++ if test "[$]*" != "X $srcdir/configure conftestfile" \
++ && test "[$]*" != "X conftestfile $srcdir/configure"; then
++
++ # If neither matched, then we have a broken ls. This can happen
++ # if, for instance, CONFIG_SHELL is bash and it inherits a
++ # broken ls alias from the environment. This has actually
++ # happened. Such a system could not be considered "sane".
++ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
++alias in your environment])
++ fi
++
++ test "[$]2" = conftestfile
++ )
++then
++ # Ok.
++ :
++else
++ AC_MSG_ERROR([newly created file is older than distributed files!
++Check your system clock])
++fi
++rm -f conftest*
++AC_MSG_RESULT(yes)])
++
++dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
++dnl The program must properly implement --version.
++AC_DEFUN(AM_MISSING_PROG,
++[AC_MSG_CHECKING(for working $2)
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if ($2 --version) < /dev/null > /dev/null 2>&1; then
++ $1=$2
++ AC_MSG_RESULT(found)
++else
++ $1="$3/missing $2"
++ AC_MSG_RESULT(missing)
++fi
++AC_SUBST($1)])
++
++# Add --enable-maintainer-mode option to configure.
++# From Jim Meyering
++
++# serial 1
++
++AC_DEFUN(AM_MAINTAINER_MODE,
++[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
++ dnl maintainer-mode is disabled by default
++ AC_ARG_ENABLE(maintainer-mode,
++[ --enable-maintainer-mode enable make rules and dependencies not useful
++ (and sometimes confusing) to the casual installer],
++ USE_MAINTAINER_MODE=$enableval,
++ USE_MAINTAINER_MODE=no)
++ AC_MSG_RESULT($USE_MAINTAINER_MODE)
++ AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
++ MAINT=$MAINTAINER_MODE_TRUE
++ AC_SUBST(MAINT)dnl
++]
++)
++
++# Define a conditional.
++
++AC_DEFUN(AM_CONDITIONAL,
++[AC_SUBST($1_TRUE)
++AC_SUBST($1_FALSE)
++if $2; then
++ $1_TRUE=
++ $1_FALSE='#'
++else
++ $1_TRUE='#'
++ $1_FALSE=
++fi])
++
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/configure ./newlib/libc/sys/mipsunknown/configure
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/configure Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/configure Mon Nov 24 20:43:05 2003
+@@ -0,0 +1,1863 @@
++#! /bin/sh
++
++# Guess values for system-dependent variables and create Makefiles.
++# Generated automatically using autoconf version 2.13
++# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
++#
++# This configure script is free software; the Free Software Foundation
++# gives unlimited permission to copy, distribute and modify it.
++
++# Defaults:
++ac_help=
++ac_default_prefix=/usr/local
++# Any additions from configure.in:
++ac_help="$ac_help
++ --enable-multilib build many library versions (default)"
++ac_help="$ac_help
++ --enable-target-optspace optimize for space"
++ac_help="$ac_help
++ --enable-malloc-debugging indicate malloc debugging requested"
++ac_help="$ac_help
++ --enable-newlib-mb enable multibyte support"
++ac_help="$ac_help
++ --enable-newlib-multithread enable support for multiple threads"
++ac_help="$ac_help
++ --enable-newlib-elix-level supply desired elix library level (1-4)"
++ac_help="$ac_help
++ --disable-newlib-io-float disable printf/scanf family float support"
++ac_help="$ac_help
++ --enable-maintainer-mode enable make rules and dependencies not useful
++ (and sometimes confusing) to the casual installer"
++
++# Initialize some variables set by options.
++# The variables have the same names as the options, with
++# dashes changed to underlines.
++build=NONE
++cache_file=./config.cache
++exec_prefix=NONE
++host=NONE
++no_create=
++nonopt=NONE
++no_recursion=
++prefix=NONE
++program_prefix=NONE
++program_suffix=NONE
++program_transform_name=s,x,x,
++silent=
++site=
++sitefile=
++srcdir=
++target=NONE
++verbose=
++x_includes=NONE
++x_libraries=NONE
++bindir='${exec_prefix}/bin'
++sbindir='${exec_prefix}/sbin'
++libexecdir='${exec_prefix}/libexec'
++datadir='${prefix}/share'
++sysconfdir='${prefix}/etc'
++sharedstatedir='${prefix}/com'
++localstatedir='${prefix}/var'
++libdir='${exec_prefix}/lib'
++includedir='${prefix}/include'
++oldincludedir='/usr/include'
++infodir='${prefix}/info'
++mandir='${prefix}/man'
++
++# Initialize some other variables.
++subdirs=
++MFLAGS= MAKEFLAGS=
++SHELL=${CONFIG_SHELL-/bin/sh}
++# Maximum number of lines to put in a shell here document.
++ac_max_here_lines=12
++
++ac_prev=
++for ac_option
++do
++
++ # If the previous option needs an argument, assign it.
++ if test -n "$ac_prev"; then
++ eval "$ac_prev=\$ac_option"
++ ac_prev=
++ continue
++ fi
++
++ case "$ac_option" in
++ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
++ *) ac_optarg= ;;
++ esac
++
++ # Accept the important Cygnus configure options, so we can diagnose typos.
++
++ case "$ac_option" in
++
++ -bindir | --bindir | --bindi | --bind | --bin | --bi)
++ ac_prev=bindir ;;
++ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
++ bindir="$ac_optarg" ;;
++
++ -build | --build | --buil | --bui | --bu)
++ ac_prev=build ;;
++ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
++ build="$ac_optarg" ;;
++
++ -cache-file | --cache-file | --cache-fil | --cache-fi \
++ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
++ ac_prev=cache_file ;;
++ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
++ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
++ cache_file="$ac_optarg" ;;
++
++ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
++ ac_prev=datadir ;;
++ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
++ | --da=*)
++ datadir="$ac_optarg" ;;
++
++ -disable-* | --disable-*)
++ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
++ # Reject names that are not valid shell variable names.
++ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
++ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
++ fi
++ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
++ eval "enable_${ac_feature}=no" ;;
++
++ -enable-* | --enable-*)
++ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
++ # Reject names that are not valid shell variable names.
++ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
++ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
++ fi
++ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
++ case "$ac_option" in
++ *=*) ;;
++ *) ac_optarg=yes ;;
++ esac
++ eval "enable_${ac_feature}='$ac_optarg'" ;;
++
++ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
++ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
++ | --exec | --exe | --ex)
++ ac_prev=exec_prefix ;;
++ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
++ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
++ | --exec=* | --exe=* | --ex=*)
++ exec_prefix="$ac_optarg" ;;
++
++ -gas | --gas | --ga | --g)
++ # Obsolete; use --with-gas.
++ with_gas=yes ;;
++
++ -help | --help | --hel | --he)
++ # Omit some internal or obsolete options to make the list less imposing.
++ # This message is too long to be a string in the A/UX 3.1 sh.
++ cat << EOF
++Usage: configure [options] [host]
++Options: [defaults in brackets after descriptions]
++Configuration:
++ --cache-file=FILE cache test results in FILE
++ --help print this message
++ --no-create do not create output files
++ --quiet, --silent do not print \`checking...' messages
++ --site-file=FILE use FILE as the site file
++ --version print the version of autoconf that created configure
++Directory and file names:
++ --prefix=PREFIX install architecture-independent files in PREFIX
++ [$ac_default_prefix]
++ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
++ [same as prefix]
++ --bindir=DIR user executables in DIR [EPREFIX/bin]
++ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
++ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
++ --datadir=DIR read-only architecture-independent data in DIR
++ [PREFIX/share]
++ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
++ --sharedstatedir=DIR modifiable architecture-independent data in DIR
++ [PREFIX/com]
++ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
++ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
++ --includedir=DIR C header files in DIR [PREFIX/include]
++ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
++ --infodir=DIR info documentation in DIR [PREFIX/info]
++ --mandir=DIR man documentation in DIR [PREFIX/man]
++ --srcdir=DIR find the sources in DIR [configure dir or ..]
++ --program-prefix=PREFIX prepend PREFIX to installed program names
++ --program-suffix=SUFFIX append SUFFIX to installed program names
++ --program-transform-name=PROGRAM
++ run sed PROGRAM on installed program names
++EOF
++ cat << EOF
++Host type:
++ --build=BUILD configure for building on BUILD [BUILD=HOST]
++ --host=HOST configure for HOST [guessed]
++ --target=TARGET configure for TARGET [TARGET=HOST]
++Features and packages:
++ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
++ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
++ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
++ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
++ --x-includes=DIR X include files are in DIR
++ --x-libraries=DIR X library files are in DIR
++EOF
++ if test -n "$ac_help"; then
++ echo "--enable and --with options recognized:$ac_help"
++ fi
++ exit 0 ;;
++
++ -host | --host | --hos | --ho)
++ ac_prev=host ;;
++ -host=* | --host=* | --hos=* | --ho=*)
++ host="$ac_optarg" ;;
++
++ -includedir | --includedir | --includedi | --included | --include \
++ | --includ | --inclu | --incl | --inc)
++ ac_prev=includedir ;;
++ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
++ | --includ=* | --inclu=* | --incl=* | --inc=*)
++ includedir="$ac_optarg" ;;
++
++ -infodir | --infodir | --infodi | --infod | --info | --inf)
++ ac_prev=infodir ;;
++ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
++ infodir="$ac_optarg" ;;
++
++ -libdir | --libdir | --libdi | --libd)
++ ac_prev=libdir ;;
++ -libdir=* | --libdir=* | --libdi=* | --libd=*)
++ libdir="$ac_optarg" ;;
++
++ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
++ | --libexe | --libex | --libe)
++ ac_prev=libexecdir ;;
++ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
++ | --libexe=* | --libex=* | --libe=*)
++ libexecdir="$ac_optarg" ;;
++
++ -localstatedir | --localstatedir | --localstatedi | --localstated \
++ | --localstate | --localstat | --localsta | --localst \
++ | --locals | --local | --loca | --loc | --lo)
++ ac_prev=localstatedir ;;
++ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
++ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
++ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
++ localstatedir="$ac_optarg" ;;
++
++ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
++ ac_prev=mandir ;;
++ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
++ mandir="$ac_optarg" ;;
++
++ -nfp | --nfp | --nf)
++ # Obsolete; use --without-fp.
++ with_fp=no ;;
++
++ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
++ | --no-cr | --no-c)
++ no_create=yes ;;
++
++ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
++ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
++ no_recursion=yes ;;
++
++ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
++ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
++ | --oldin | --oldi | --old | --ol | --o)
++ ac_prev=oldincludedir ;;
++ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
++ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
++ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
++ oldincludedir="$ac_optarg" ;;
++
++ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
++ ac_prev=prefix ;;
++ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
++ prefix="$ac_optarg" ;;
++
++ -program-prefix | --program-prefix | --program-prefi | --program-pref \
++ | --program-pre | --program-pr | --program-p)
++ ac_prev=program_prefix ;;
++ -program-prefix=* | --program-prefix=* | --program-prefi=* \
++ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
++ program_prefix="$ac_optarg" ;;
++
++ -program-suffix | --program-suffix | --program-suffi | --program-suff \
++ | --program-suf | --program-su | --program-s)
++ ac_prev=program_suffix ;;
++ -program-suffix=* | --program-suffix=* | --program-suffi=* \
++ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
++ program_suffix="$ac_optarg" ;;
++
++ -program-transform-name | --program-transform-name \
++ | --program-transform-nam | --program-transform-na \
++ | --program-transform-n | --program-transform- \
++ | --program-transform | --program-transfor \
++ | --program-transfo | --program-transf \
++ | --program-trans | --program-tran \
++ | --progr-tra | --program-tr | --program-t)
++ ac_prev=program_transform_name ;;
++ -program-transform-name=* | --program-transform-name=* \
++ | --program-transform-nam=* | --program-transform-na=* \
++ | --program-transform-n=* | --program-transform-=* \
++ | --program-transform=* | --program-transfor=* \
++ | --program-transfo=* | --program-transf=* \
++ | --program-trans=* | --program-tran=* \
++ | --progr-tra=* | --program-tr=* | --program-t=*)
++ program_transform_name="$ac_optarg" ;;
++
++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
++ | -silent | --silent | --silen | --sile | --sil)
++ silent=yes ;;
++
++ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
++ ac_prev=sbindir ;;
++ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
++ | --sbi=* | --sb=*)
++ sbindir="$ac_optarg" ;;
++
++ -sharedstatedir | --sharedstatedir | --sharedstatedi \
++ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
++ | --sharedst | --shareds | --shared | --share | --shar \
++ | --sha | --sh)
++ ac_prev=sharedstatedir ;;
++ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
++ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
++ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
++ | --sha=* | --sh=*)
++ sharedstatedir="$ac_optarg" ;;
++
++ -site | --site | --sit)
++ ac_prev=site ;;
++ -site=* | --site=* | --sit=*)
++ site="$ac_optarg" ;;
++
++ -site-file | --site-file | --site-fil | --site-fi | --site-f)
++ ac_prev=sitefile ;;
++ -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
++ sitefile="$ac_optarg" ;;
++
++ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
++ ac_prev=srcdir ;;
++ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
++ srcdir="$ac_optarg" ;;
++
++ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
++ | --syscon | --sysco | --sysc | --sys | --sy)
++ ac_prev=sysconfdir ;;
++ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
++ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
++ sysconfdir="$ac_optarg" ;;
++
++ -target | --target | --targe | --targ | --tar | --ta | --t)
++ ac_prev=target ;;
++ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
++ target="$ac_optarg" ;;
++
++ -v | -verbose | --verbose | --verbos | --verbo | --verb)
++ verbose=yes ;;
++
++ -version | --version | --versio | --versi | --vers)
++ echo "configure generated by autoconf version 2.13"
++ exit 0 ;;
++
++ -with-* | --with-*)
++ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
++ # Reject names that are not valid shell variable names.
++ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
++ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
++ fi
++ ac_package=`echo $ac_package| sed 's/-/_/g'`
++ case "$ac_option" in
++ *=*) ;;
++ *) ac_optarg=yes ;;
++ esac
++ eval "with_${ac_package}='$ac_optarg'" ;;
++
++ -without-* | --without-*)
++ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
++ # Reject names that are not valid shell variable names.
++ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
++ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
++ fi
++ ac_package=`echo $ac_package| sed 's/-/_/g'`
++ eval "with_${ac_package}=no" ;;
++
++ --x)
++ # Obsolete; use --with-x.
++ with_x=yes ;;
++
++ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
++ | --x-incl | --x-inc | --x-in | --x-i)
++ ac_prev=x_includes ;;
++ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
++ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
++ x_includes="$ac_optarg" ;;
++
++ -x-libraries | --x-libraries | --x-librarie | --x-librari \
++ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
++ ac_prev=x_libraries ;;
++ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
++ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
++ x_libraries="$ac_optarg" ;;
++
++ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
++ ;;
++
++ *)
++ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
++ echo "configure: warning: $ac_option: invalid host type" 1>&2
++ fi
++ if test "x$nonopt" != xNONE; then
++ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
++ fi
++ nonopt="$ac_option"
++ ;;
++
++ esac
++done
++
++if test -n "$ac_prev"; then
++ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
++fi
++
++trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
++
++# File descriptor usage:
++# 0 standard input
++# 1 file creation
++# 2 errors and warnings
++# 3 some systems may open it to /dev/tty
++# 4 used on the Kubota Titan
++# 6 checking for... messages and results
++# 5 compiler messages saved in config.log
++if test "$silent" = yes; then
++ exec 6>/dev/null
++else
++ exec 6>&1
++fi
++exec 5>./config.log
++
++echo "\
++This file contains any messages produced by compilers while
++running configure, to aid debugging if configure makes a mistake.
++" 1>&5
++
++# Strip out --no-create and --no-recursion so they do not pile up.
++# Also quote any args containing shell metacharacters.
++ac_configure_args=
++for ac_arg
++do
++ case "$ac_arg" in
++ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
++ | --no-cr | --no-c) ;;
++ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
++ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
++ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
++ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
++ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
++ esac
++done
++
++# NLS nuisances.
++# Only set these to C if already set. These must not be set unconditionally
++# because not all systems understand e.g. LANG=C (notably SCO).
++# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
++# Non-C LC_CTYPE values break the ctype check.
++if test "${LANG+set}" = set; then LANG=C; export LANG; fi
++if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
++if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
++if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
++
++# confdefs.h avoids OS command line length limits that DEFS can exceed.
++rm -rf conftest* confdefs.h
++# AIX cpp loses on an empty file, so make sure it contains at least a newline.
++echo > confdefs.h
++
++# A filename unique to this package, relative to the directory that
++# configure is in, which we can look for to find out if srcdir is correct.
++ac_unique_file=syscalls.c
++
++# Find the source files, if location was not specified.
++if test -z "$srcdir"; then
++ ac_srcdir_defaulted=yes
++ # Try the directory containing this script, then its parent.
++ ac_prog=$0
++ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
++ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
++ srcdir=$ac_confdir
++ if test ! -r $srcdir/$ac_unique_file; then
++ srcdir=..
++ fi
++else
++ ac_srcdir_defaulted=no
++fi
++if test ! -r $srcdir/$ac_unique_file; then
++ if test "$ac_srcdir_defaulted" = yes; then
++ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
++ else
++ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
++ fi
++fi
++srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
++
++# Prefer explicitly selected file to automatically selected ones.
++if test -z "$sitefile"; then
++ if test -z "$CONFIG_SITE"; then
++ if test "x$prefix" != xNONE; then
++ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
++ else
++ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
++ fi
++ fi
++else
++ CONFIG_SITE="$sitefile"
++fi
++for ac_site_file in $CONFIG_SITE; do
++ if test -r "$ac_site_file"; then
++ echo "loading site script $ac_site_file"
++ . "$ac_site_file"
++ fi
++done
++
++if test -r "$cache_file"; then
++ echo "loading cache $cache_file"
++ . $cache_file
++else
++ echo "creating cache $cache_file"
++ > $cache_file
++fi
++
++ac_ext=c
++# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
++ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
++cross_compiling=$ac_cv_prog_cc_cross
++
++ac_exeext=
++ac_objext=o
++if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
++ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
++ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
++ ac_n= ac_c='
++' ac_t=' '
++ else
++ ac_n=-n ac_c= ac_t=
++ fi
++else
++ ac_n= ac_c='\c' ac_t=
++fi
++
++
++
++ac_aux_dir=
++for ac_dir in ../../../.. $srcdir/../../../..; do
++ if test -f $ac_dir/install-sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install-sh -c"
++ break
++ elif test -f $ac_dir/install.sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install.sh -c"
++ break
++ fi
++done
++if test -z "$ac_aux_dir"; then
++ { echo "configure: error: can not find install-sh or install.sh in ../../../.. $srcdir/../../../.." 1>&2; exit 1; }
++fi
++ac_config_guess=$ac_aux_dir/config.guess
++ac_config_sub=$ac_aux_dir/config.sub
++ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
++
++
++# Find a good install program. We prefer a C program (faster),
++# so one script is as good as another. But avoid the broken or
++# incompatible versions:
++# SysV /etc/install, /usr/sbin/install
++# SunOS /usr/etc/install
++# IRIX /sbin/install
++# AIX /bin/install
++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
++# AFS /usr/afsws/bin/install, which mishandles nonexistent args
++# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
++# ./install, which can be erroneously created by make from ./install.sh.
++echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
++echo "configure:586: checking for a BSD compatible install" >&5
++if test -z "$INSTALL"; then
++if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
++ for ac_dir in $PATH; do
++ # Account for people who put trailing slashes in PATH elements.
++ case "$ac_dir/" in
++ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
++ *)
++ # OSF1 and SCO ODT 3.0 have their own names for install.
++ # Don't use installbsd from OSF since it installs stuff as root
++ # by default.
++ for ac_prog in ginstall scoinst install; do
++ if test -f $ac_dir/$ac_prog; then
++ if test $ac_prog = install &&
++ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
++ # AIX install. It has an incompatible calling convention.
++ :
++ else
++ ac_cv_path_install="$ac_dir/$ac_prog -c"
++ break 2
++ fi
++ fi
++ done
++ ;;
++ esac
++ done
++ IFS="$ac_save_IFS"
++
++fi
++ if test "${ac_cv_path_install+set}" = set; then
++ INSTALL="$ac_cv_path_install"
++ else
++ # As a last resort, use the slow shell script. We don't cache a
++ # path for INSTALL within a source directory, because that will
++ # break other packages using the cache if that directory is
++ # removed, or if the path is relative.
++ INSTALL="$ac_install_sh"
++ fi
++fi
++echo "$ac_t""$INSTALL" 1>&6
++
++# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
++# It thinks the first close brace ends the variable substitution.
++test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
++
++test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
++
++test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
++
++echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
++echo "configure:639: checking whether build environment is sane" >&5
++# Just in case
++sleep 1
++echo timestamp > conftestfile
++# Do `set' in a subshell so we don't clobber the current shell's
++# arguments. Must try -L first in case configure is actually a
++# symlink; some systems play weird games with the mod time of symlinks
++# (eg FreeBSD returns the mod time of the symlink's containing
++# directory).
++if (
++ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
++ if test "$*" = "X"; then
++ # -L didn't work.
++ set X `ls -t $srcdir/configure conftestfile`
++ fi
++ if test "$*" != "X $srcdir/configure conftestfile" \
++ && test "$*" != "X conftestfile $srcdir/configure"; then
++
++ # If neither matched, then we have a broken ls. This can happen
++ # if, for instance, CONFIG_SHELL is bash and it inherits a
++ # broken ls alias from the environment. This has actually
++ # happened. Such a system could not be considered "sane".
++ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
++alias in your environment" 1>&2; exit 1; }
++ fi
++
++ test "$2" = conftestfile
++ )
++then
++ # Ok.
++ :
++else
++ { echo "configure: error: newly created file is older than distributed files!
++Check your system clock" 1>&2; exit 1; }
++fi
++rm -f conftest*
++echo "$ac_t""yes" 1>&6
++if test "$program_transform_name" = s,x,x,; then
++ program_transform_name=
++else
++ # Double any \ or $. echo might interpret backslashes.
++ cat <<\EOF_SED > conftestsed
++s,\\,\\\\,g; s,\$,$$,g
++EOF_SED
++ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
++ rm -f conftestsed
++fi
++test "$program_prefix" != NONE &&
++ program_transform_name="s,^,${program_prefix},; $program_transform_name"
++# Use a double $ so make ignores it.
++test "$program_suffix" != NONE &&
++ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
++
++# sed with no file args requires a program.
++test "$program_transform_name" = "" && program_transform_name="s,x,x,"
++
++echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
++echo "configure:696: checking whether ${MAKE-make} sets \${MAKE}" >&5
++set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
++if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ cat > conftestmake <<\EOF
++all:
++ @echo 'ac_maketemp="${MAKE}"'
++EOF
++# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
++eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
++if test -n "$ac_maketemp"; then
++ eval ac_cv_prog_make_${ac_make}_set=yes
++else
++ eval ac_cv_prog_make_${ac_make}_set=no
++fi
++rm -f conftestmake
++fi
++if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
++ echo "$ac_t""yes" 1>&6
++ SET_MAKE=
++else
++ echo "$ac_t""no" 1>&6
++ SET_MAKE="MAKE=${MAKE-make}"
++fi
++
++if test $host != $build; then
++ ac_tool_prefix=${host_alias}-
++else
++ ac_tool_prefix=
++fi
++
++echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
++echo "configure:729: checking for Cygwin environment" >&5
++if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ cat > conftest.$ac_ext <<EOF
++#line 734 "configure"
++#include "confdefs.h"
++
++int main() {
++
++#ifndef __CYGWIN__
++#define __CYGWIN__ __CYGWIN32__
++#endif
++return __CYGWIN__;
++; return 0; }
++EOF
++if { (eval echo configure:745: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++ rm -rf conftest*
++ ac_cv_cygwin=yes
++else
++ echo "configure: failed program was:" >&5
++ cat conftest.$ac_ext >&5
++ rm -rf conftest*
++ ac_cv_cygwin=no
++fi
++rm -f conftest*
++rm -f conftest*
++fi
++
++echo "$ac_t""$ac_cv_cygwin" 1>&6
++CYGWIN=
++test "$ac_cv_cygwin" = yes && CYGWIN=yes
++echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
++echo "configure:762: checking for mingw32 environment" >&5
++if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ cat > conftest.$ac_ext <<EOF
++#line 767 "configure"
++#include "confdefs.h"
++
++int main() {
++return __MINGW32__;
++; return 0; }
++EOF
++if { (eval echo configure:774: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++ rm -rf conftest*
++ ac_cv_mingw32=yes
++else
++ echo "configure: failed program was:" >&5
++ cat conftest.$ac_ext >&5
++ rm -rf conftest*
++ ac_cv_mingw32=no
++fi
++rm -f conftest*
++rm -f conftest*
++fi
++
++echo "$ac_t""$ac_cv_mingw32" 1>&6
++MINGW32=
++test "$ac_cv_mingw32" = yes && MINGW32=yes
++
++# Check whether --enable-multilib or --disable-multilib was given.
++if test "${enable_multilib+set}" = set; then
++ enableval="$enable_multilib"
++ case "${enableval}" in
++ yes) multilib=yes ;;
++ no) multilib=no ;;
++ *) { echo "configure: error: bad value ${enableval} for multilib option" 1>&2; exit 1; } ;;
++ esac
++else
++ multilib=yes
++fi
++
++# Check whether --enable-target-optspace or --disable-target-optspace was given.
++if test "${enable_target_optspace+set}" = set; then
++ enableval="$enable_target_optspace"
++ case "${enableval}" in
++ yes) target_optspace=yes ;;
++ no) target_optspace=no ;;
++ *) { echo "configure: error: bad value ${enableval} for target-optspace option" 1>&2; exit 1; } ;;
++ esac
++else
++ target_optspace=
++fi
++
++# Check whether --enable-malloc-debugging or --disable-malloc-debugging was given.
++if test "${enable_malloc_debugging+set}" = set; then
++ enableval="$enable_malloc_debugging"
++ case "${enableval}" in
++ yes) malloc_debugging=yes ;;
++ no) malloc_debugging=no ;;
++ *) { echo "configure: error: bad value ${enableval} for malloc-debugging option" 1>&2; exit 1; } ;;
++ esac
++else
++ malloc_debugging=
++fi
++
++# Check whether --enable-newlib-mb or --disable-newlib-mb was given.
++if test "${enable_newlib_mb+set}" = set; then
++ enableval="$enable_newlib_mb"
++ case "${enableval}" in
++ yes) newlib_mb=yes ;;
++ no) newlib_mb=no ;;
++ *) { echo "configure: error: bad value ${enableval} for newlib-mb option" 1>&2; exit 1; } ;;
++ esac
++else
++ newlib_mb=
++fi
++
++# Check whether --enable-newlib-multithread or --disable-newlib-multithread was given.
++if test "${enable_newlib_multithread+set}" = set; then
++ enableval="$enable_newlib_multithread"
++ case "${enableval}" in
++ yes) newlib_multithread=yes ;;
++ no) newlib_multithread=no ;;
++ *) { echo "configure: error: bad value ${enableval} for newlib-multithread option" 1>&2; exit 1; } ;;
++ esac
++else
++ newlib_multithread=yes
++fi
++
++# Check whether --enable-newlib-elix-level or --disable-newlib-elix-level was given.
++if test "${enable_newlib_elix_level+set}" = set; then
++ enableval="$enable_newlib_elix_level"
++ case "${enableval}" in
++ 0) newlib_elix_level=0 ;;
++ 1) newlib_elix_level=1 ;;
++ 2) newlib_elix_level=2 ;;
++ 3) newlib_elix_level=3 ;;
++ 4) newlib_elix_level=4 ;;
++ *) { echo "configure: error: bad value ${enableval} for newlib-elix-level option" 1>&2; exit 1; } ;;
++ esac
++else
++ newlib_elix_level=0
++fi
++
++# Check whether --enable-newlib-io-float or --disable-newlib-io-float was given.
++if test "${enable_newlib_io_float+set}" = set; then
++ enableval="$enable_newlib_io_float"
++ case "${enableval}" in
++ yes) newlib_io_float=yes ;;
++ no) newlib_io_float=no ;;
++ *) { echo "configure: error: bad value ${enableval} for newlib-io-float option" 1>&2; exit 1; } ;;
++ esac
++else
++ newlib_io_float=yes
++fi
++
++
++
++test -z "${with_target_subdir}" && with_target_subdir=.
++
++if test "${srcdir}" = "."; then
++ if test "${with_target_subdir}" != "."; then
++ newlib_basedir="${srcdir}/${with_multisrctop}../../../.."
++ else
++ newlib_basedir="${srcdir}/${with_multisrctop}../../.."
++ fi
++else
++ newlib_basedir="${srcdir}/../../.."
++fi
++
++
++
++# Do some error checking and defaulting for the host and target type.
++# The inputs are:
++# configure --host=HOST --target=TARGET --build=BUILD NONOPT
++#
++# The rules are:
++# 1. You are not allowed to specify --host, --target, and nonopt at the
++# same time.
++# 2. Host defaults to nonopt.
++# 3. If nonopt is not specified, then host defaults to the current host,
++# as determined by config.guess.
++# 4. Target and build default to nonopt.
++# 5. If nonopt is not specified, then target and build default to host.
++
++# The aliases save the names the user supplied, while $host etc.
++# will get canonicalized.
++case $host---$target---$nonopt in
++NONE---*---* | *---NONE---* | *---*---NONE) ;;
++*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
++esac
++
++
++# Make sure we can run config.sub.
++if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
++else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
++fi
++
++echo $ac_n "checking host system type""... $ac_c" 1>&6
++echo "configure:921: checking host system type" >&5
++
++host_alias=$host
++case "$host_alias" in
++NONE)
++ case $nonopt in
++ NONE)
++ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
++ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
++ fi ;;
++ *) host_alias=$nonopt ;;
++ esac ;;
++esac
++
++host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
++host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
++host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
++host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
++echo "$ac_t""$host" 1>&6
++
++echo $ac_n "checking target system type""... $ac_c" 1>&6
++echo "configure:942: checking target system type" >&5
++
++target_alias=$target
++case "$target_alias" in
++NONE)
++ case $nonopt in
++ NONE) target_alias=$host_alias ;;
++ *) target_alias=$nonopt ;;
++ esac ;;
++esac
++
++target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
++target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
++target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
++target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
++echo "$ac_t""$target" 1>&6
++
++echo $ac_n "checking build system type""... $ac_c" 1>&6
++echo "configure:960: checking build system type" >&5
++
++build_alias=$build
++case "$build_alias" in
++NONE)
++ case $nonopt in
++ NONE) build_alias=$host_alias ;;
++ *) build_alias=$nonopt ;;
++ esac ;;
++esac
++
++build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
++build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
++build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
++build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
++echo "$ac_t""$build" 1>&6
++
++test "$host_alias" != "$target_alias" &&
++ test "$program_prefix$program_suffix$program_transform_name" = \
++ NONENONEs,x,x, &&
++ program_prefix=${target_alias}-
++
++
++
++PACKAGE=newlib
++
++VERSION=1.11.0
++
++if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
++ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
++fi
++cat >> confdefs.h <<EOF
++#define PACKAGE "$PACKAGE"
++EOF
++
++cat >> confdefs.h <<EOF
++#define VERSION "$VERSION"
++EOF
++
++
++
++missing_dir=`cd $ac_aux_dir && pwd`
++echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
++echo "configure:1003: checking for working aclocal" >&5
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if (aclocal --version) < /dev/null > /dev/null 2>&1; then
++ ACLOCAL=aclocal
++ echo "$ac_t""found" 1>&6
++else
++ ACLOCAL="$missing_dir/missing aclocal"
++ echo "$ac_t""missing" 1>&6
++fi
++
++echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
++echo "configure:1016: checking for working autoconf" >&5
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if (autoconf --version) < /dev/null > /dev/null 2>&1; then
++ AUTOCONF=autoconf
++ echo "$ac_t""found" 1>&6
++else
++ AUTOCONF="$missing_dir/missing autoconf"
++ echo "$ac_t""missing" 1>&6
++fi
++
++echo $ac_n "checking for working automake""... $ac_c" 1>&6
++echo "configure:1029: checking for working automake" >&5
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if (automake --version) < /dev/null > /dev/null 2>&1; then
++ AUTOMAKE=automake
++ echo "$ac_t""found" 1>&6
++else
++ AUTOMAKE="$missing_dir/missing automake"
++ echo "$ac_t""missing" 1>&6
++fi
++
++echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
++echo "configure:1042: checking for working autoheader" >&5
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if (autoheader --version) < /dev/null > /dev/null 2>&1; then
++ AUTOHEADER=autoheader
++ echo "$ac_t""found" 1>&6
++else
++ AUTOHEADER="$missing_dir/missing autoheader"
++ echo "$ac_t""missing" 1>&6
++fi
++
++echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
++echo "configure:1055: checking for working makeinfo" >&5
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
++ MAKEINFO=makeinfo
++ echo "$ac_t""found" 1>&6
++else
++ MAKEINFO="$missing_dir/missing makeinfo"
++ echo "$ac_t""missing" 1>&6
++fi
++
++
++
++# FIXME: We temporarily define our own version of AC_PROG_CC. This is
++# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We
++# are probably using a cross compiler, which will not be able to fully
++# link an executable. This should really be fixed in autoconf
++# itself.
++
++
++
++# Extract the first word of "gcc", so it can be a program name with args.
++set dummy gcc; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:1080: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ if test -n "$CC"; then
++ ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_dummy="$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/$ac_word; then
++ ac_cv_prog_CC="gcc"
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++fi
++fi
++CC="$ac_cv_prog_CC"
++if test -n "$CC"; then
++ echo "$ac_t""$CC" 1>&6
++else
++ echo "$ac_t""no" 1>&6
++fi
++
++if test -z "$CC"; then
++ # Extract the first word of "cc", so it can be a program name with args.
++set dummy cc; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:1110: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ if test -n "$CC"; then
++ ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_prog_rejected=no
++ ac_dummy="$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/$ac_word; then
++ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
++ ac_prog_rejected=yes
++ continue
++ fi
++ ac_cv_prog_CC="cc"
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++if test $ac_prog_rejected = yes; then
++ # We found a bogon in the path, so make sure we never use it.
++ set dummy $ac_cv_prog_CC
++ shift
++ if test $# -gt 0; then
++ # We chose a different compiler from the bogus one.
++ # However, it has the same basename, so the bogon will be chosen
++ # first if we set CC to just the basename; use the full file name.
++ shift
++ set dummy "$ac_dir/$ac_word" "$@"
++ shift
++ ac_cv_prog_CC="$@"
++ fi
++fi
++fi
++fi
++CC="$ac_cv_prog_CC"
++if test -n "$CC"; then
++ echo "$ac_t""$CC" 1>&6
++else
++ echo "$ac_t""no" 1>&6
++fi
++
++ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
++fi
++
++echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
++echo "configure:1159: checking whether we are using GNU C" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ cat > conftest.c <<EOF
++#ifdef __GNUC__
++ yes;
++#endif
++EOF
++if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1168: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
++ ac_cv_prog_gcc=yes
++else
++ ac_cv_prog_gcc=no
++fi
++fi
++
++echo "$ac_t""$ac_cv_prog_gcc" 1>&6
++
++if test $ac_cv_prog_gcc = yes; then
++ GCC=yes
++ ac_test_CFLAGS="${CFLAGS+set}"
++ ac_save_CFLAGS="$CFLAGS"
++ CFLAGS=
++ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
++echo "configure:1183: checking whether ${CC-cc} accepts -g" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ echo 'void f(){}' > conftest.c
++if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
++ ac_cv_prog_cc_g=yes
++else
++ ac_cv_prog_cc_g=no
++fi
++rm -f conftest*
++
++fi
++
++echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
++ if test "$ac_test_CFLAGS" = set; then
++ CFLAGS="$ac_save_CFLAGS"
++ elif test $ac_cv_prog_cc_g = yes; then
++ CFLAGS="-g -O2"
++ else
++ CFLAGS="-O2"
++ fi
++else
++ GCC=
++ test "${CFLAGS+set}" = set || CFLAGS="-g"
++fi
++
++
++# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
++set dummy ${ac_tool_prefix}as; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:1214: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ if test -n "$AS"; then
++ ac_cv_prog_AS="$AS" # Let the user override the test.
++else
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_dummy="$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/$ac_word; then
++ ac_cv_prog_AS="${ac_tool_prefix}as"
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++ test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="as"
++fi
++fi
++AS="$ac_cv_prog_AS"
++if test -n "$AS"; then
++ echo "$ac_t""$AS" 1>&6
++else
++ echo "$ac_t""no" 1>&6
++fi
++
++
++
++# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
++set dummy ${ac_tool_prefix}ar; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:1246: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ if test -n "$AR"; then
++ ac_cv_prog_AR="$AR" # Let the user override the test.
++else
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_dummy="$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/$ac_word; then
++ ac_cv_prog_AR="${ac_tool_prefix}ar"
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++ test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar"
++fi
++fi
++AR="$ac_cv_prog_AR"
++if test -n "$AR"; then
++ echo "$ac_t""$AR" 1>&6
++else
++ echo "$ac_t""no" 1>&6
++fi
++
++
++
++# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
++set dummy ${ac_tool_prefix}ranlib; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:1278: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ if test -n "$RANLIB"; then
++ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
++else
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_dummy="$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/$ac_word; then
++ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++fi
++fi
++RANLIB="$ac_cv_prog_RANLIB"
++if test -n "$RANLIB"; then
++ echo "$ac_t""$RANLIB" 1>&6
++else
++ echo "$ac_t""no" 1>&6
++fi
++
++
++if test -z "$ac_cv_prog_RANLIB"; then
++if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "ranlib", so it can be a program name with args.
++set dummy ranlib; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:1310: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ if test -n "$RANLIB"; then
++ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
++else
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_dummy="$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/$ac_word; then
++ ac_cv_prog_RANLIB="ranlib"
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
++fi
++fi
++RANLIB="$ac_cv_prog_RANLIB"
++if test -n "$RANLIB"; then
++ echo "$ac_t""$RANLIB" 1>&6
++else
++ echo "$ac_t""no" 1>&6
++fi
++
++else
++ RANLIB=":"
++fi
++fi
++
++
++# Find a good install program. We prefer a C program (faster),
++# so one script is as good as another. But avoid the broken or
++# incompatible versions:
++# SysV /etc/install, /usr/sbin/install
++# SunOS /usr/etc/install
++# IRIX /sbin/install
++# AIX /bin/install
++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
++# AFS /usr/afsws/bin/install, which mishandles nonexistent args
++# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
++# ./install, which can be erroneously created by make from ./install.sh.
++echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
++echo "configure:1355: checking for a BSD compatible install" >&5
++if test -z "$INSTALL"; then
++if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
++ for ac_dir in $PATH; do
++ # Account for people who put trailing slashes in PATH elements.
++ case "$ac_dir/" in
++ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
++ *)
++ # OSF1 and SCO ODT 3.0 have their own names for install.
++ # Don't use installbsd from OSF since it installs stuff as root
++ # by default.
++ for ac_prog in ginstall scoinst install; do
++ if test -f $ac_dir/$ac_prog; then
++ if test $ac_prog = install &&
++ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
++ # AIX install. It has an incompatible calling convention.
++ :
++ else
++ ac_cv_path_install="$ac_dir/$ac_prog -c"
++ break 2
++ fi
++ fi
++ done
++ ;;
++ esac
++ done
++ IFS="$ac_save_IFS"
++
++fi
++ if test "${ac_cv_path_install+set}" = set; then
++ INSTALL="$ac_cv_path_install"
++ else
++ # As a last resort, use the slow shell script. We don't cache a
++ # path for INSTALL within a source directory, because that will
++ # break other packages using the cache if that directory is
++ # removed, or if the path is relative.
++ INSTALL="$ac_install_sh"
++ fi
++fi
++echo "$ac_t""$INSTALL" 1>&6
++
++# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
++# It thinks the first close brace ends the variable substitution.
++test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
++
++test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
++
++test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
++
++
++echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
++echo "configure:1409: checking whether to enable maintainer-specific portions of Makefiles" >&5
++ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
++if test "${enable_maintainer_mode+set}" = set; then
++ enableval="$enable_maintainer_mode"
++ USE_MAINTAINER_MODE=$enableval
++else
++ USE_MAINTAINER_MODE=no
++fi
++
++ echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
++
++
++if test $USE_MAINTAINER_MODE = yes; then
++ MAINTAINER_MODE_TRUE=
++ MAINTAINER_MODE_FALSE='#'
++else
++ MAINTAINER_MODE_TRUE='#'
++ MAINTAINER_MODE_FALSE=
++fi
++ MAINT=$MAINTAINER_MODE_TRUE
++
++
++
++# We need AC_EXEEXT to keep automake happy in cygnus mode. However,
++# at least currently, we never actually build a program, so we never
++# need to use $(EXEEXT). Moreover, the test for EXEEXT normally
++# fails, because we are probably configuring with a cross compiler
++# which can't create executables. So we include AC_EXEEXT to keep
++# automake happy, but we don't execute it, since we don't care about
++# the result.
++if false; then
++
++
++echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
++echo "configure:1443: checking for executable suffix" >&5
++if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
++ ac_cv_exeext=.exe
++else
++ rm -f conftest*
++ echo 'int main () { return 0; }' > conftest.$ac_ext
++ ac_cv_exeext=
++ if { (eval echo configure:1453: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
++ for file in conftest.*; do
++ case $file in
++ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
++ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
++ esac
++ done
++ else
++ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
++ fi
++ rm -f conftest*
++ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
++fi
++fi
++
++EXEEXT=""
++test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
++echo "$ac_t""${ac_cv_exeext}" 1>&6
++ac_exeext=$EXEEXT
++
++fi
++
++. ${newlib_basedir}/configure.host
++
++newlib_cflags="${newlib_cflags} -fno-builtin"
++
++NEWLIB_CFLAGS=${newlib_cflags}
++
++
++LDFLAGS=${ldflags}
++
++
++
++
++if test x${newlib_elix_level} = x0; then
++ ELIX_LEVEL_0_TRUE=
++ ELIX_LEVEL_0_FALSE='#'
++else
++ ELIX_LEVEL_0_TRUE='#'
++ ELIX_LEVEL_0_FALSE=
++fi
++
++
++if test x${newlib_elix_level} = x1; then
++ ELIX_LEVEL_1_TRUE=
++ ELIX_LEVEL_1_FALSE='#'
++else
++ ELIX_LEVEL_1_TRUE='#'
++ ELIX_LEVEL_1_FALSE=
++fi
++
++
++if test x${newlib_elix_level} = x2; then
++ ELIX_LEVEL_2_TRUE=
++ ELIX_LEVEL_2_FALSE='#'
++else
++ ELIX_LEVEL_2_TRUE='#'
++ ELIX_LEVEL_2_FALSE=
++fi
++
++
++if test x${newlib_elix_level} = x3; then
++ ELIX_LEVEL_3_TRUE=
++ ELIX_LEVEL_3_FALSE='#'
++else
++ ELIX_LEVEL_3_TRUE='#'
++ ELIX_LEVEL_3_FALSE=
++fi
++
++
++if test x${newlib_elix_level} = x4; then
++ ELIX_LEVEL_4_TRUE=
++ ELIX_LEVEL_4_FALSE='#'
++else
++ ELIX_LEVEL_4_TRUE='#'
++ ELIX_LEVEL_4_FALSE=
++fi
++
++
++
++if test x${use_libtool} = xyes; then
++ USE_LIBTOOL_TRUE=
++ USE_LIBTOOL_FALSE='#'
++else
++ USE_LIBTOOL_TRUE='#'
++ USE_LIBTOOL_FALSE=
++fi
++
++# Hard-code OBJEXT. Normally it is set by AC_OBJEXT, but we
++# use oext, which is set in configure.host based on the target platform.
++OBJEXT=${oext}
++
++
++
++
++
++
++
++
++
++
++trap '' 1 2 15
++cat > confcache <<\EOF
++# This file is a shell script that caches the results of configure
++# tests run on this system so they can be shared between configure
++# scripts and configure runs. It is not useful on other systems.
++# If it contains results you don't want to keep, you may remove or edit it.
++#
++# By default, configure uses ./config.cache as the cache file,
++# creating it if it does not exist already. You can give configure
++# the --cache-file=FILE option to use a different cache file; that is
++# what configure does when it calls configure scripts in
++# subdirectories, so they share the cache.
++# Giving --cache-file=/dev/null disables caching, for debugging configure.
++# config.status only pays attention to the cache file if you give it the
++# --recheck option to rerun configure.
++#
++EOF
++# The following way of writing the cache mishandles newlines in values,
++# but we know of no workaround that is simple, portable, and efficient.
++# So, don't put newlines in cache variables' values.
++# Ultrix sh set writes to stderr and can't be redirected directly,
++# and sets the high bit in the cache file unless we assign to the vars.
++(set) 2>&1 |
++ case `(ac_space=' '; set | grep ac_space) 2>&1` in
++ *ac_space=\ *)
++ # `set' does not quote correctly, so add quotes (double-quote substitution
++ # turns \\\\ into \\, and sed turns \\ into \).
++ sed -n \
++ -e "s/'/'\\\\''/g" \
++ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
++ ;;
++ *)
++ # `set' quotes correctly as required by POSIX, so do not add quotes.
++ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
++ ;;
++ esac >> confcache
++if cmp -s $cache_file confcache; then
++ :
++else
++ if test -w $cache_file; then
++ echo "updating cache $cache_file"
++ cat confcache > $cache_file
++ else
++ echo "not updating unwritable cache $cache_file"
++ fi
++fi
++rm -f confcache
++
++trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
++
++test "x$prefix" = xNONE && prefix=$ac_default_prefix
++# Let make expand exec_prefix.
++test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
++
++# Any assignment to VPATH causes Sun make to only execute
++# the first set of double-colon rules, so remove it if not needed.
++# If there is a colon in the path, we need to keep it.
++if test "x$srcdir" = x.; then
++ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
++fi
++
++trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
++
++# Transform confdefs.h into DEFS.
++# Protect against shell expansion while executing Makefile rules.
++# Protect against Makefile macro expansion.
++cat > conftest.defs <<\EOF
++s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
++s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
++s%\[%\\&%g
++s%\]%\\&%g
++s%\$%$$%g
++EOF
++DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
++rm -f conftest.defs
++
++
++# Without the "./", some shells look in PATH for config.status.
++: ${CONFIG_STATUS=./config.status}
++
++echo creating $CONFIG_STATUS
++rm -f $CONFIG_STATUS
++cat > $CONFIG_STATUS <<EOF
++#! /bin/sh
++# Generated automatically by configure.
++# Run this file to recreate the current configuration.
++# This directory was configured as follows,
++# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
++#
++# $0 $ac_configure_args
++#
++# Compiler output produced by configure, useful for debugging
++# configure, is in ./config.log if it exists.
++
++ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
++for ac_option
++do
++ case "\$ac_option" in
++ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
++ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
++ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
++ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
++ echo "$CONFIG_STATUS generated by autoconf version 2.13"
++ exit 0 ;;
++ -help | --help | --hel | --he | --h)
++ echo "\$ac_cs_usage"; exit 0 ;;
++ *) echo "\$ac_cs_usage"; exit 1 ;;
++ esac
++done
++
++ac_given_srcdir=$srcdir
++ac_given_INSTALL="$INSTALL"
++
++trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
++EOF
++cat >> $CONFIG_STATUS <<EOF
++
++# Protect against being on the right side of a sed subst in config.status.
++sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
++ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
++$ac_vpsub
++$extrasub
++s%@SHELL@%$SHELL%g
++s%@CFLAGS@%$CFLAGS%g
++s%@CPPFLAGS@%$CPPFLAGS%g
++s%@CXXFLAGS@%$CXXFLAGS%g
++s%@FFLAGS@%$FFLAGS%g
++s%@DEFS@%$DEFS%g
++s%@LDFLAGS@%$LDFLAGS%g
++s%@LIBS@%$LIBS%g
++s%@exec_prefix@%$exec_prefix%g
++s%@prefix@%$prefix%g
++s%@program_transform_name@%$program_transform_name%g
++s%@bindir@%$bindir%g
++s%@sbindir@%$sbindir%g
++s%@libexecdir@%$libexecdir%g
++s%@datadir@%$datadir%g
++s%@sysconfdir@%$sysconfdir%g
++s%@sharedstatedir@%$sharedstatedir%g
++s%@localstatedir@%$localstatedir%g
++s%@libdir@%$libdir%g
++s%@includedir@%$includedir%g
++s%@oldincludedir@%$oldincludedir%g
++s%@infodir@%$infodir%g
++s%@mandir@%$mandir%g
++s%@newlib_basedir@%$newlib_basedir%g
++s%@host@%$host%g
++s%@host_alias@%$host_alias%g
++s%@host_cpu@%$host_cpu%g
++s%@host_vendor@%$host_vendor%g
++s%@host_os@%$host_os%g
++s%@target@%$target%g
++s%@target_alias@%$target_alias%g
++s%@target_cpu@%$target_cpu%g
++s%@target_vendor@%$target_vendor%g
++s%@target_os@%$target_os%g
++s%@build@%$build%g
++s%@build_alias@%$build_alias%g
++s%@build_cpu@%$build_cpu%g
++s%@build_vendor@%$build_vendor%g
++s%@build_os@%$build_os%g
++s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
++s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
++s%@INSTALL_DATA@%$INSTALL_DATA%g
++s%@PACKAGE@%$PACKAGE%g
++s%@VERSION@%$VERSION%g
++s%@ACLOCAL@%$ACLOCAL%g
++s%@AUTOCONF@%$AUTOCONF%g
++s%@AUTOMAKE@%$AUTOMAKE%g
++s%@AUTOHEADER@%$AUTOHEADER%g
++s%@MAKEINFO@%$MAKEINFO%g
++s%@SET_MAKE@%$SET_MAKE%g
++s%@CC@%$CC%g
++s%@AS@%$AS%g
++s%@AR@%$AR%g
++s%@RANLIB@%$RANLIB%g
++s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
++s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
++s%@MAINT@%$MAINT%g
++s%@EXEEXT@%$EXEEXT%g
++s%@NEWLIB_CFLAGS@%$NEWLIB_CFLAGS%g
++s%@ELIX_LEVEL_0_TRUE@%$ELIX_LEVEL_0_TRUE%g
++s%@ELIX_LEVEL_0_FALSE@%$ELIX_LEVEL_0_FALSE%g
++s%@ELIX_LEVEL_1_TRUE@%$ELIX_LEVEL_1_TRUE%g
++s%@ELIX_LEVEL_1_FALSE@%$ELIX_LEVEL_1_FALSE%g
++s%@ELIX_LEVEL_2_TRUE@%$ELIX_LEVEL_2_TRUE%g
++s%@ELIX_LEVEL_2_FALSE@%$ELIX_LEVEL_2_FALSE%g
++s%@ELIX_LEVEL_3_TRUE@%$ELIX_LEVEL_3_TRUE%g
++s%@ELIX_LEVEL_3_FALSE@%$ELIX_LEVEL_3_FALSE%g
++s%@ELIX_LEVEL_4_TRUE@%$ELIX_LEVEL_4_TRUE%g
++s%@ELIX_LEVEL_4_FALSE@%$ELIX_LEVEL_4_FALSE%g
++s%@USE_LIBTOOL_TRUE@%$USE_LIBTOOL_TRUE%g
++s%@USE_LIBTOOL_FALSE@%$USE_LIBTOOL_FALSE%g
++s%@OBJEXT@%$OBJEXT%g
++s%@oext@%$oext%g
++s%@aext@%$aext%g
++s%@libm_machine_dir@%$libm_machine_dir%g
++s%@machine_dir@%$machine_dir%g
++s%@sys_dir@%$sys_dir%g
++
++CEOF
++EOF
++
++cat >> $CONFIG_STATUS <<\EOF
++
++# Split the substitutions into bite-sized pieces for seds with
++# small command number limits, like on Digital OSF/1 and HP-UX.
++ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
++ac_file=1 # Number of current file.
++ac_beg=1 # First line for current file.
++ac_end=$ac_max_sed_cmds # Line after last line for current file.
++ac_more_lines=:
++ac_sed_cmds=""
++while $ac_more_lines; do
++ if test $ac_beg -gt 1; then
++ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
++ else
++ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
++ fi
++ if test ! -s conftest.s$ac_file; then
++ ac_more_lines=false
++ rm -f conftest.s$ac_file
++ else
++ if test -z "$ac_sed_cmds"; then
++ ac_sed_cmds="sed -f conftest.s$ac_file"
++ else
++ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
++ fi
++ ac_file=`expr $ac_file + 1`
++ ac_beg=$ac_end
++ ac_end=`expr $ac_end + $ac_max_sed_cmds`
++ fi
++done
++if test -z "$ac_sed_cmds"; then
++ ac_sed_cmds=cat
++fi
++EOF
++
++cat >> $CONFIG_STATUS <<EOF
++
++CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
++EOF
++cat >> $CONFIG_STATUS <<\EOF
++for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
++ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
++ case "$ac_file" in
++ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
++ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
++ *) ac_file_in="${ac_file}.in" ;;
++ esac
++
++ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
++
++ # Remove last slash and all that follows it. Not all systems have dirname.
++ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
++ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
++ # The file is in a subdirectory.
++ test ! -d "$ac_dir" && mkdir "$ac_dir"
++ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
++ # A "../" for each directory in $ac_dir_suffix.
++ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
++ else
++ ac_dir_suffix= ac_dots=
++ fi
++
++ case "$ac_given_srcdir" in
++ .) srcdir=.
++ if test -z "$ac_dots"; then top_srcdir=.
++ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
++ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
++ *) # Relative path.
++ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
++ top_srcdir="$ac_dots$ac_given_srcdir" ;;
++ esac
++
++ case "$ac_given_INSTALL" in
++ [/$]*) INSTALL="$ac_given_INSTALL" ;;
++ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
++ esac
++
++ echo creating "$ac_file"
++ rm -f "$ac_file"
++ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
++ case "$ac_file" in
++ *Makefile*) ac_comsub="1i\\
++# $configure_input" ;;
++ *) ac_comsub= ;;
++ esac
++
++ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
++ sed -e "$ac_comsub
++s%@configure_input@%$configure_input%g
++s%@srcdir@%$srcdir%g
++s%@top_srcdir@%$top_srcdir%g
++s%@INSTALL@%$INSTALL%g
++" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
++fi; done
++rm -f conftest.s*
++
++EOF
++cat >> $CONFIG_STATUS <<EOF
++
++EOF
++cat >> $CONFIG_STATUS <<\EOF
++
++exit 0
++EOF
++chmod +x $CONFIG_STATUS
++rm -fr confdefs* $ac_clean_files
++test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
++
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/configure.in ./newlib/libc/sys/mipsunknown/configure.in
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/configure.in Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/configure.in Mon Nov 24 20:33:46 2003
+@@ -0,0 +1,12 @@
++dnl This is the newlib/libc/sys/mipsunknown configure.in file.
++dnl Process this file with autoconf to produce a configure script.
++
++AC_PREREQ(2.5)
++AC_INIT(syscalls.c)
++
++dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake.
++AC_CONFIG_AUX_DIR(../../../..)
++
++NEWLIB_CONFIGURE(../../..)
++
++AC_OUTPUT(Makefile)
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/crt0.c ./newlib/libc/sys/mipsunknown/crt0.c
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/crt0.c Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/crt0.c Mon Nov 24 21:03:56 2003
+@@ -0,0 +1,7 @@
++/* This is just here to make the build proccess happy. The real crt0.c is included in the
++ mips2java dist and will replace this after mips2java is installed */
++
++extern void puts(const char *s);
++void _start() {
++ puts("Your build is broken... you shouldn't be using the crt0.c in newlib");
++}
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/sys/dirent.h ./newlib/libc/sys/mipsunknown/sys/dirent.h
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/sys/dirent.h Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/sys/dirent.h Mon Nov 24 22:46:36 2003
+@@ -0,0 +1,24 @@
++#ifndef _SYS_DIRENT_H
++#define _SYS_DIRENT_H
++
++#include <sys/types.h>
++
++struct dirent {
++ long d_ino;
++ char d_name[1024];
++};
++
++typedef struct {
++ int dd_fd;
++ int dd_pos;
++ struct dirent ent;
++} DIR;
++
++# define __dirfd(dp) ((dp)->dd_fd)
++
++DIR *opendir (const char *);
++struct dirent *readdir (DIR *);
++void rewinddir (DIR *);
++int closedir (DIR *);
++
++#endif
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/sys/utime.h ./newlib/libc/sys/mipsunknown/sys/utime.h
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/sys/utime.h Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/sys/utime.h Tue Nov 25 09:45:17 2003
+@@ -0,0 +1,20 @@
++#ifndef _SYS_UTIME_H
++#define _SYS_UTIME_H
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++struct utimbuf
++{
++ time_t actime;
++ time_t modtime;
++};
++
++extern int utime(const char *file, const struct utimbuf *buf);
++
++#ifdef __cplusplus
++};
++#endif
++
++#endif /* _SYS_UTIME_H */
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/syscalls.c ./newlib/libc/sys/mipsunknown/syscalls.c
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/syscalls.c Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/syscalls.c Tue Nov 25 09:33:57 2003
+@@ -0,0 +1,49 @@
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <utime.h>
++#include <errno.h>
++#undef errno
++
++/* These are just connectors for the reent versions */
++
++extern int _mkdir_r(struct _reent *ptr, const char *path, mode_t mode);
++int mkdir(const char *path, mode_t mode) { return _mkdir_r(_REENT, path, mode); }
++
++extern int _utime_r(struct _reent *ptr, const char *file, struct utimbuf *buf);
++int utime(const char *file, const struct utimbuf *buf) { return _utime_r(_REENT,file,buf); }
++
++extern int _lstat_r(struct _reent *ptr, const char *path, struct stat *sb);
++int lstat(const char *path, struct stat *sb) { return _lstat_r(_REENT,path,sb); }
++
++extern int _chdir_r(struct _reent *ptr, const char *path);
++int chdir(const char *path) { return _chdir_r(_REENT,path); }
++
++extern int _pipe_r(struct _reent *ptr, int *filedes);
++int pipe(int *filedes) { return _pipe_r(_REENT,filedes); }
++
++extern int _dup2_r(struct _reent *ptr, int oldd, int newd);
++int dup2(int oldd,int newd) { return _dup2_r(_REENT,oldd,newd); }
++
++extern int _waitpid_r(struct _reent *ptr, pid_t pid, int *status, int opts);
++int waitpid(pid_t pid, int *status, int opts) { return _waitpid_r(_REENT,pid,status,opts); }
++
++extern char* _getcwd_r(struct _reent *ptr, char *buf, size_t size);
++char* getcwd(char *buf, size_t size) { return _getcwd_r(_REENT,buf,size); }
++
++extern int _symlink_r(struct _reent *ptr, const char *name1, const char *name2);
++int symlink(const char *name1, const char *name2) { return _symlink_r(_REENT,name1,name2); }
++
++extern int _readlink_r(struct _reent *ptr, const char *path, const char *buf, int bufsize);
++int readlink(const char *path, const char *buf, int bufsize) { return _readlink_r(_REENT,path,buf,bufsize); }
++
++extern int _chown_r(struct _reent *ptr, const char *path, uid_t uid, gid_t gid);
++int chown(const char *path, uid_t uid, gid_t gid) { return _chown_r(_REENT,path,uid,gid); }
++
++extern int _fchown_r(struct _reent *ptr, int fd, uid_t uid, gid_t gid);
++int fchown(int fd, uid_t uid, gid_t gid) { return _fchown_r(_REENT,fd,uid,gid); }
++
++extern int _chmod_r(struct _reent *ptr, const char *path, mode_t mode);
++int chmod(const char *path, mode_t mode) { return _chmod_r(_REENT,path,mode); }
++
++extern int _fchmod_r(struct _reent *ptr, int fd, mode_t mode);
++int fchmod(int fd, mode_t mode) { return _fchmod_r(_REENT,fd,mode); }
--- /dev/null
+===================================================================
+RCS file: /cvs/src/src/newlib/libc/time/tzset_r.c,v
+retrieving revision 1.2
+retrieving revision 1.3
+diff -u -r1.2 -r1.3
+--- newlib/libc/time/tzset_r.c 2002/08/26 18:56:09 1.2
++++ snewlib/libc/time/tzset_r.c 2003/06/03 18:42:09 1.3
+@@ -28,7 +28,8 @@
+ struct _reent *reent_ptr)
+ {
+ char *tzenv;
+- int hh, mm, ss, sign, m, w, d, n;
++ unsigned short hh, mm, ss, m, w, d;
++ int sign, n;
+ int i, ch;
+
+ if ((tzenv = _getenv_r (reent_ptr, "TZ")) == NULL)