summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCVS to SVN Conversion <nobody@llvm.org>2004-12-08 20:35:47 +0000
committerCVS to SVN Conversion <nobody@llvm.org>2004-12-08 20:35:47 +0000
commit1c8ba66d60fdc00f1795d9ef8051d5579e08883e (patch)
tree446195483b328f56a026807ccee6cb4c90d31021
parenta3df351820c2ec7cafb87d2fb8581cea484feb35 (diff)
downloadllvm-1c8ba66d60fdc00f1795d9ef8051d5579e08883e.tar.gz
This commit was manufactured by cvs2svn to create branch 'release_14'.
llvm-svn: 18659
-rw-r--r--llvm/Makefile3
-rw-r--r--llvm/Makefile.rules34
-rw-r--r--llvm/docs/.cvsignore2
-rw-r--r--llvm/docs/CommandGuide/Makefile35
-rw-r--r--llvm/docs/FAQ.html4
-rw-r--r--llvm/docs/GettingStarted.html238
-rw-r--r--llvm/docs/MakefileGuide.html254
-rw-r--r--llvm/docs/ProgrammersManual.html3
-rw-r--r--llvm/docs/Projects.html21
-rw-r--r--llvm/docs/ReleaseNotes.html189
-rw-r--r--llvm/docs/TestingGuide.html225
-rw-r--r--llvm/docs/WritingAnLLVMPass.html2
-rw-r--r--llvm/lib/Linker/LinkItems.cpp159
-rw-r--r--llvm/lib/Target/SparcV8/DelaySlotFiller.cpp73
-rw-r--r--llvm/lib/Target/SparcV8/FPMover.cpp103
-rw-r--r--llvm/lib/Target/SparcV8/Makefile19
-rw-r--r--llvm/lib/Target/SparcV8/README.txt35
-rw-r--r--llvm/lib/Target/SparcV8/SparcV8.h42
-rw-r--r--llvm/lib/Target/SparcV8/SparcV8.td52
-rw-r--r--llvm/lib/Target/SparcV8/SparcV8AsmPrinter.cpp645
-rw-r--r--llvm/lib/Target/SparcV8/SparcV8CodeEmitter.cpp186
-rw-r--r--llvm/lib/Target/SparcV8/SparcV8ISelSimple.cpp1671
-rw-r--r--llvm/lib/Target/SparcV8/SparcV8InstrFormats.td95
-rw-r--r--llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp41
-rw-r--r--llvm/lib/Target/SparcV8/SparcV8InstrInfo.h54
-rw-r--r--llvm/lib/Target/SparcV8/SparcV8InstrInfo.td292
-rw-r--r--llvm/lib/Target/SparcV8/SparcV8JITInfo.h49
-rw-r--r--llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp176
-rw-r--r--llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h55
-rw-r--r--llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td51
-rw-r--r--llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp155
-rw-r--r--llvm/lib/Target/SparcV8/SparcV8TargetMachine.h61
-rw-r--r--llvm/runtime/GCCLibraries/crtend/Makefile4
-rw-r--r--llvm/test/Makefile98
-rw-r--r--llvm/test/Regression/CFrontend/2004-01-01-UnknownInitSize.c2
-rw-r--r--llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr2
-rw-r--r--llvm/test/Regression/Debugger/funccall.ll1
-rw-r--r--llvm/tools/gccld/gccld.cpp44
-rw-r--r--llvm/tools/llvm-ld/llvm-ld.cpp44
39 files changed, 797 insertions, 4422 deletions
diff --git a/llvm/Makefile b/llvm/Makefile
index 4c6f7097fd9f..e9cbc789ced4 100644
--- a/llvm/Makefile
+++ b/llvm/Makefile
@@ -41,7 +41,4 @@ dist-hook::
$(TopDistDir)/include/llvm/Support/DataTypes.h \
$(TopDistDir)/include/llvm/Support/ThreadSupport.h
-check :
- $(MAKE) -C test check TESTSUITE=$(TESTSUITE)
-
tools-only: all
diff --git a/llvm/Makefile.rules b/llvm/Makefile.rules
index d2d0556f9ee7..9abc4afc2354 100644
--- a/llvm/Makefile.rules
+++ b/llvm/Makefile.rules
@@ -20,10 +20,10 @@
# Define the various target sets
#--------------------------------------------------------------------
RecursiveTargets := all clean clean-all install uninstall install-bytecode
-LocalTargets := all-local clean-local clean-all-local \
+LocalTargets := all-local clean-local clean-all-local check-local \
install-local printvars uninstall-local \
install-bytecode-local
-TopLevelTargets := dist dist-check dist-clean tags dist-gzip dist-bzip2 \
+TopLevelTargets := check dist dist-check dist-clean tags dist-gzip dist-bzip2 \
dist-zip
UserTargets := $(RecursiveTargets) $(LocalTargets) $(TopLevelTargets)
InternalTargets := preconditions distdir dist-hook
@@ -154,12 +154,13 @@ ifdef ENABLE_PROFILING
else
ifdef ENABLE_OPTIMIZED
BuildMode := Release
- CXX.Flags := -O3 -DNDEBUG -finline-functions -felide-constructors -fomit-frame-pointer
+ CXX.Flags := -O3 -DNDEBUG -finline-functions \
+ -felide-constructors -fomit-frame-pointer
C.Flags := -O3 -DNDEBUG -fomit-frame-pointer
LD.Flags := -O3 -DNDEBUG
else
BuildMode := Debug
- CXX.Flags := -g -D_DEBUG
+ CXX.Flags := -g -D_DEBUG
C.Flags := -g -D_DEBUG
LD.Flags := -g -D_DEBUG
KEEP_SYMBOLS := 1
@@ -214,10 +215,6 @@ ifndef LLVMGXX
LLVMGXX := PATH=$(LLVMToolDir):$(PATH) $(LLVMGCCDIR)/bin/g++
endif
-# Need a better way to compute this.
-LLVMGCCLibDir := $(dir $(shell $(LLVMGCC) -print-file-name=libgcc.a))/
-LLVMGCCStdCXXLibDir := $(dir $(shell $(LLVMGCC) -print-file-name=libstdc++.a))/
-
#--------------------------------------------------------------------
# Adjust to user's request
#--------------------------------------------------------------------
@@ -1090,6 +1087,23 @@ endif
endif
###############################################################################
+# CHECK: Running the test suite
+###############################################################################
+
+check::
+ $(Verb) if test -d "$(BUILD_OBJ_ROOT)/test" ; then \
+ if test -f "$(BUILD_OBJ_ROOT)/test/Makefile" ; then \
+ $(EchoCmd) Running test suite ; \
+ $(MAKE) -C $(BUILD_OBJ_ROOT)/test check-local \
+ TESTSUITE=$(TESTSUITE) ; \
+ else \
+ $(EchoCmd) No Makefile in test directory ; \
+ fi ; \
+ else \
+ $(EchoCmd) No test directory ; \
+ fi
+
+###############################################################################
# DISTRIBUTION: Handle construction of a distribution tarball
###############################################################################
@@ -1212,7 +1226,7 @@ $(DistDir)/.makedistdir: $(DistSources)
fi ; \
$(EchoCmd) Removing old $(DistDir) ; \
$(RM) -rf $(DistDir); \
- $(EchoCmd) Making 'all' to be sure. ; \
+ $(EchoCmd) Making 'all' to verify build ; \
$(MAKE) all ; \
fi
$(Echo) Building Distribution Directory $(DistDir)
@@ -1296,7 +1310,7 @@ endif
ifeq ($(LEVEL),.)
#------------------------------------------------------------------------
-# Install support for project's include files:
+# Install support for the project's include files:
#------------------------------------------------------------------------
install-local::
$(Echo) Installing include files
diff --git a/llvm/docs/.cvsignore b/llvm/docs/.cvsignore
new file mode 100644
index 000000000000..25aac7cd67bb
--- /dev/null
+++ b/llvm/docs/.cvsignore
@@ -0,0 +1,2 @@
+doxygen.cfg
+
diff --git a/llvm/docs/CommandGuide/Makefile b/llvm/docs/CommandGuide/Makefile
index 5b1afa9aa8a3..51088d397d58 100644
--- a/llvm/docs/CommandGuide/Makefile
+++ b/llvm/docs/CommandGuide/Makefile
@@ -7,6 +7,39 @@
#
##===----------------------------------------------------------------------===##
+ifdef BUILD_FOR_WEBSITE
+
+# This special case is for keeping the CommandGuide on the LLVM web site
+# up to date automatically as the documents are checked in. It must build
+# the POD files to HTML only and keep them in the src directories. It must also
+# build in an unconfigured tree, hence the ifdef. To use this, run
+# make -s BUILD_FOR_WEBSITE=1 inside the cvs commit script.
+
+POD := $(wildcard *.pod)
+HTML := $(patsubst %.pod, html/%.html, $(POD))
+MAN := $(patsubst %.pod, man/man1/%.1, $(POD))
+PS := $(patsubst %.pod, ps/%.ps, $(POD))
+
+all: $(HTML) $(MAN) $(PS)
+
+.SUFFIXES:
+.SUFFIXES: .html .pod .1 .ps
+
+html/%.html: %.pod
+ pod2html --css=manpage.css --htmlroot=. \
+ --podpath=. --noindex --infile=$< --outfile=$@ --title=$*
+
+man/man1/%.1: %.pod
+ pod2man --release=1.4 --center="LLVM Command Guide" $< $@
+
+ps/%.ps: man/man1/%.1
+ groff -Tps -man $< > $@
+
+clean:
+ rm -f pod2htm*.*~~ $(HTML) $(MAN) $(PS)
+
+else
+
LEVEL := ../..
include $(LEVEL)/Makefile.common
@@ -62,3 +95,5 @@ uninstall-local::
printvars::
$(Echo) "POD : " '$(POD)'
$(Echo) "HTML : " '$(HTML)'
+
+endif
diff --git a/llvm/docs/FAQ.html b/llvm/docs/FAQ.html
index a8f80dd10fa5..e43e3b22a570 100644
--- a/llvm/docs/FAQ.html
+++ b/llvm/docs/FAQ.html
@@ -168,10 +168,6 @@ LLVM have been ported to a plethora of platforms.</p>
<li>The GCC front end code is not as portable as the LLVM suite, so it may not
compile as well on unsupported platforms.</li>
- <li>The Python test classes are more UNIX-centric than they should be, so
- porting to non-UNIX like platforms (i.e. Windows, MacOS 9) will require some
- effort.</li>
-
<li>The LLVM build system relies heavily on UNIX shell tools, like the Bourne
Shell and sed. Porting to systems without these tools (MacOS 9, Plan 9) will
require more effort.</li>
diff --git a/llvm/docs/GettingStarted.html b/llvm/docs/GettingStarted.html
index 4e8702769b8e..d23ac9213023 100644
--- a/llvm/docs/GettingStarted.html
+++ b/llvm/docs/GettingStarted.html
@@ -38,13 +38,16 @@
<li><a href="#layout">Program layout</a>
<ol>
<li><a href="#cvsdir"><tt>CVS</tt> directories</a>
+ <li><a href="#examples"><tt>llvm/examples</tt></a>
<li><a href="#include"><tt>llvm/include</tt></a>
<li><a href="#lib"><tt>llvm/lib</tt></a>
+ <li><a href="#projects"><tt>llvm/projects</tt></a>
<li><a href="#runtime"><tt>llvm/runtime</tt></a>
<li><a href="#test"><tt>llvm/test</tt></a>
<li><a href="#llvmtest"><tt>llvm-test</tt></a>
<li><a href="#tools"><tt>llvm/tools</tt></a>
<li><a href="#utils"><tt>llvm/utils</tt></a>
+ <li><a href="#win32"><tt>llvm/win32</tt></a>
</ol></li>
<li><a href="#tutorial">An Example Using the LLVM Tool Chain</a>
@@ -86,6 +89,12 @@ end is a modified version of GCC 3.4 (we track the GCC 3.4 development). Once
compiled into LLVM bytecode, a program can be manipulated with the LLVM tools
from the LLVM suite.</p>
+<p>
+There is a third, optional piece called llvm-test. It is a suite of programs
+with a testing harness that can be used to further test LLVM's functionality
+and performance.
+</p>
+
</div>
<!-- *********************************************************************** -->
@@ -295,7 +304,7 @@ href="CFEBuildInstrs.html">try to compile it</a> on your platform.</p>
<tr>
<td><a href="http://gcc.gnu.org">GCC</a></td>
<td>3.4.2</td>
- <td>C/C++ compiler (<a href="#Note4">Note 4</a>)</td>
+ <td>C/C++ compiler (<a href="#Note3">Note 3</a>)</td>
</tr>
<tr>
@@ -359,23 +368,9 @@ href="CFEBuildInstrs.html">try to compile it</a> on your platform.</p>
</tr>
<tr>
- <td><a href="http://www.codesourcery.com/qmtest">QMTest</a></td>
- <td>2.0.3</td>
- <td>Automated test suite (<a href="#Note2">Note 2</a>,<a href="#Note3">
- Note 3</a>)</td>
- </tr>
-
- <tr>
- <td><a href="http://www.python.org">Python</a></td>
- <td>2.3</td>
- <td>Automated test suite (<a href="#Note2">Note 2</a>,<a href="#Note3">
- Note 3</a>)</td>
- </tr>
-
- <tr>
<td><a href="https://www.cvshome.org/downloads.html">CVS</a></td>
<td>&gt;1.11</td>
- <td>CVS access to LLVM (<a href="#Note5">Note 5</a>)</td>
+ <td>CVS access to LLVM (<a href="#Note4">Note 4</a>)</td>
</tr>
</table>
@@ -388,21 +383,12 @@ href="CFEBuildInstrs.html">try to compile it</a> on your platform.</p>
package.</a></li>
<li><a name="Note2">Only needed if you want to run the automated test
suite in the <tt>test</tt> directory.</a></li>
- <li><a name="Note3">These are needed to use the LLVM test suite.</a>
- Please note that newer versions of QMTest may not work with the LLVM
- test suite. QMTest 2.0.3 can be retrieved from the QMTest CVS
- repository using the following commands:
- <ul>
- <li><tt>cvs -d :pserver:anoncvs@cvs.codesourcery.com:/home/qm/Repository login</tt></li>
- <li>When prompted, use <tt>anoncvs</tt> as the password. </li>
- <li><tt>cvs -d :pserver:anoncvs@cvs.codesourcery.com:/home/qm/Repository co -r release-2-0-3 qm</tt></li>
- </ul>
</li>
- <li><a name="Note4">Only the C and C++ languages are needed so there's no
+ <li><a name="Note3">Only the C and C++ languages are needed so there's no
need to build the other languages for LLVM's purposes.</a> See
<a href="#brokengcc">below</a> for specific version info.
</li>
- <li><a name="Note5">You only need CVS if you intend to build from the
+ <li><a name="Note4">You only need CVS if you intend to build from the
latest LLVM sources. If you're working from a release distribution, you
don't need CVS.</a></li>
</ol>
@@ -413,7 +399,7 @@ href="CFEBuildInstrs.html">try to compile it</a> on your platform.</p>
<li><b>bzip2*</b> - bzip2 command for distribution generation</li>
<li><b>bunzip2*</b> - bunzip2 command for distribution checking</li>
<li><b>chmod</b> - change permissions on a file</li>
- <li><b>cat</b> - output concatentation utility</li>
+ <li><b>cat</b> - output concatenation utility</li>
<li><b>cp</b> - copy files</li>
<li><b>date</b> - print the current date/time </li>
<li><b>echo</b> - print to standard output</li>
@@ -546,7 +532,7 @@ You can set these on the command line, or better yet, set them in your
<dt>alias llvmgcc <i>LLVMGCCDIR</i><tt>/bin/gcc</tt>
<dt>alias llvmg++ <i>LLVMGCCDIR</i><tt>/bin/g++</tt>
<dd>
- This alias allows you to use the LLVM C and C++ front ends without putting
+ These aliases allow you to use the LLVM C and C++ front ends without putting
them in your <tt>PATH</tt> or typing in their complete pathnames.
</dl>
@@ -568,28 +554,27 @@ file is a TAR archive that is compressed with the gzip program.
<p> The files are as follows:
<dl>
- <dt>llvm-1.3.tar.gz
- <dd>This is the source code to the LLVM suite.
- <p>
+ <dt><tt>llvm-1.4.tar.gz</tt></dt>
+ <dd>This is the source code for the LLVM libraries and tools.<br/></dd>
- <dt>cfrontend-1.3.source.tar.gz
- <dd>This is the source release of the GCC front end.
- <p>
+ <dt><tt>llvm-test-1.4.tar.gz</tt></dt>
+ <dd>This is the source code for the LLVM test suite.</tt></dd>
- <dt>cfrontend-1.3.sparc-sun-solaris2.8.tar.gz
- <dd>This is the binary release of the GCC front end for Solaris/Sparc.
- <p>
+ <dt><tt>cfrontend-1.4.source.tar.gz</tt></dt>
+ <dd>This is the source release of the GCC front end.<br/></dd>
- <dt>cfrontend-1.3.i686-redhat-linux-gnu.tar.gz
- <dd>This is the binary release of the GCC front end for Linux/x86.
- <p>
+ <dt><tt>cfrontend-1.4.sparc-sun-solaris2.8.tar.gz</tt></dt>
+ <dd>This is the binary release of the GCC front end for Solaris/Sparc.
+ <br/></dd>
- <dt>cfrontend-1.3.i386-unknown-freebsd5.1.tar.gz
- <dd>This is the binary release of the GCC front end for FreeBSD/x86.
- <p>
+ <dt><tt>cfrontend-1.4.i686-redhat-linux-gnu.tar.gz</tt></dt>
+ <dd>This is the binary release of the GCC front end for Linux/x86.<br/></dd>
- <dt>cfrontend-1.3.powerpc-apple-darwin7.0.0.tar.gz
- <dd>This is the binary release of the GCC front end for MacOS X/PPC.
+ <dt><tt>cfrontend-1.4.i386-unknown-freebsd5.1.tar.gz</tt></dt>
+ <dd>This is the binary release of the GCC front end for FreeBSD/x86.<br/></dd>
+
+ <dt><tt>cfrontend-1.4.powerpc-apple-darwin7.0.0.tar.gz</tt></dt>
+ <dd>This is the binary release of the GCC front end for MacOS X/PPC.<br/></dd>
</dl>
</div>
@@ -622,12 +607,23 @@ revision), you can specify a label. The following releases have the following
label:</p>
<ul>
+<li>Release 1.4: <b>RELEASE_14</b></li>
<li>Release 1.3: <b>RELEASE_13</b></li>
<li>Release 1.2: <b>RELEASE_12</b></li>
<li>Release 1.1: <b>RELEASE_11</b></li>
<li>Release 1.0: <b>RELEASE_1</b></li>
</ul>
+<p>If you would like to get the LLVM test suite (a separate package as of 1.4),
+you get it from the CVS repository:</p>
+<pre>
+ cd llvm/projects
+ cvs -z3 -d :pserver:anon@llvm-cvs.cs.uiuc.edu:/var/cvs/llvm co llvm-test
+</pre>
+<p>By placing it in the <tt>llvm/projects</tt>, it will be automatically
+configured by the LLVM configure script as well as automatically updated when
+you run <tt>cvs update</tt>.</p>
+
<p>If you would like to get the GCC front end source code, you can also get it
from the CVS repository:</p>
@@ -636,7 +632,7 @@ from the CVS repository:</p>
</pre>
<p>Please note that you must follow <a href="CFEBuildInstrs.html">these
-instructions</a> to successfully build the LLVM C front-end.</p>
+instructions</a> to successfully build the LLVM GCC front-end.</p>
</div>
@@ -701,10 +697,10 @@ not for the faint of heart, so be forewarned.</p>
<div class="doc_text">
<p>Once checked out from the CVS repository, the LLVM suite source code must be
-configured via the <tt>configure</tt> script. This script sets variables in
-<tt>llvm/Makefile.config</tt> and <tt>llvm/include/Config/config.h</tt>. It
-also populates <i>OBJ_ROOT</i> with the Makefiles needed to begin building
-LLVM.</p>
+configured via the <tt>configure</tt> script. This script sets variables in the
+various <tt>*.in</tt> files, most notably <tt>llvm/Makefile.config</tt> and
+<tt>llvm/include/Config/config.h</tt>. It also populates <i>OBJ_ROOT</i> with
+the Makefiles needed to begin building LLVM.</p>
<p>The following environment variables are used by the <tt>configure</tt>
script to configure the build system:</p>
@@ -730,47 +726,41 @@ script to configure the build system:</p>
<p>The following options can be used to set or enable LLVM specific options:</p>
<dl>
- <dt><i>--with-llvmgccdir=LLVMGCCDIR</i>
+ <dt><i>--with-llvmgccdir=LLVMGCCDIR</i></dt>
<dd>
Path to the location where the LLVM GCC front end binaries and
associated libraries were installed. This must be specified as an
absolute pathname.
- <p>
- <dt><i>--enable-optimized</i>
+ <p></p>
+ </dd>
+ <dt><i>--with-tclinclude</i></dt>
+ <dd>Path to the tcl include directory under which the <tt>tclsh</tt> can be
+ found. Use this if you have multiple tcl installations on your machine and you
+ want to use a specific one (8.x) for LLVM. LLVM only uses tcl for running the
+ dejagnu based test suite in <tt>llvm/test</tt>. If you don't specify this
+ option, the LLVM configure script will search for tcl 8.4 and 8.3 releases.
+ <p></p>
+ </dd>
+ <dt><i>--enable-optimized</i></dt>
<dd>
Enables optimized compilation by default (debugging symbols are removed
and GCC optimization flags are enabled). The default is to use an
unoptimized build (also known as a debug build).
- <p>
- <dt><i>--enable-jit</i>
+ <p></p>
+ </dd>
+ <dt><i>--enable-jit</i></dt>
<dd>
Compile the Just In Time (JIT) compiler functionality. This is not
available
on all platforms. The default is dependent on platform, so it is best
to explicitly enable it if you want it.
- <p>
- <dt><i>--enable-spec2000</i>
- <dt><i>--enable-spec2000=&lt;<tt>directory</tt>&gt;</i>
- <dd>
- Enable the use of SPEC2000 when testing LLVM. This is disabled by default
- (unless <tt>configure</tt> finds SPEC2000 installed). By specifying
- <tt>directory</tt>, you can tell configure where to find the SPEC2000
- benchmarks. If <tt>directory</tt> is left unspecified, <tt>configure</tt>
- uses the default value
- <tt>/home/vadve/shared/benchmarks/speccpu2000/benchspec</tt>.
- <p>
- <dt><i>--enable-spec95</i>
- <dt><i>--enable-spec95=&lt;<tt>directory</tt>&gt;</i>
- <dd>
- Enable the use of SPEC95 when testing LLVM. It is similar to the
- <i>--enable-spec2000</i> option.
- <p>
- <dt><i>--enable-povray</i>
- <dt><i>--enable-povray=&lt;<tt>directory</tt>&gt;</i>
- <dd>
- Enable the use of Povray as an external test. Versions of Povray written
- in C should work. This option is similar to the <i>--enable-spec2000</i>
- option.
+ <p></p>
+ </dd>
+ <dt><i>--enable-doxygen</i></dt>
+ <dd>Look for the doxygen program and enable construction of doxygen based
+ documentation from the source code. This is disabled by default because
+ generating the documentation can take a long time and producess 100s of
+ megabytes of output.</dd>
</dl>
<p>To configure LLVM, follow these steps:</p>
@@ -783,13 +773,13 @@ script to configure the build system:</p>
<li>Run the <tt>configure</tt> script located in the LLVM source tree:
<br>
- <tt><i>SRC_ROOT</i>/configure</tt>
+ <tt><i>SRC_ROOT</i>/configure --prefix=/install/path [other options]</tt>
<p>
</ol>
<p>In addition to running <tt>configure</tt>, you must set the
-<tt>LLVM_LIB_SEARCH_PATH</tt> environment variable in your startup scripts.
-This environment variable is used to locate "system" libraries like
+<tt>LLVM_LIB_SEARCH_PATH</tt> environment variable in your startup shell
+scripts. This environment variable is used to locate "system" libraries like
"<tt>-lc</tt>" and "<tt>-lm</tt>" when linking. This variable should be set to
the absolute path of the <tt>bytecode-libs</tt> subdirectory of the GCC front
end, or <i>LLVMGCCDIR</i>/<tt>bytecode-libs</tt>. For example, one might set
@@ -841,7 +831,7 @@ builds:</p>
<p><tt>gmake</tt></p>
<p>If the build fails, please <a href="#brokengcc">check here</a> to see if you
-are using a known broken version of GCC to compile LLVM with.</p>
+are using a version of GCC that is known not to compile LLVM.</p>
<p>
If you have multiple processors in your machine, you may wish to use some of
@@ -860,7 +850,7 @@ source code:</p>
generated C/C++ files, libraries, and executables.
<p>
- <dt><tt>gmake distclean</tt>
+ <dt><tt>gmake dist-clean</tt>
<dd>
Removes everything that <tt>gmake clean</tt> does, but also removes files
generated by <tt>configure</tt>. It attempts to return the source tree to the
@@ -869,11 +859,13 @@ source code:</p>
<dt><tt>gmake install</tt>
<dd>
- Installs LLVM libraries and tools in a heirarchy under $PREFIX, specified with
- <tt>./configure --prefix=[dir]</tt>, defaults to <tt>/usr/local</tt>.
+ Installs LLVM header files, libraries, tools, and documentation in a
+ hierarchy
+ under $PREFIX, specified with <tt>./configure --prefix=[dir]</tt>, which
+ defaults to <tt>/usr/local</tt>.
<p>
- <dt><tt>gmake -C runtime install</tt>
+ <dt><tt>gmake -C runtime install-bytecode</tt>
<dd>
Assuming you built LLVM into $OBJDIR, when this command is run, it will
install bytecode libraries into the GCC front end's bytecode library
@@ -882,6 +874,10 @@ source code:</p>
<p>
</dl>
+<p>Please see the <a href="MakefileGuide.html">Makefile Guide</a> for further
+details on these <tt>make</tt> targets and descriptions of other targets
+available.</p>
+
<p>It is also possible to override default values from <tt>configure</tt> by
declaring variables on the command line. The following are some examples:</p>
@@ -900,6 +896,11 @@ declaring variables on the command line. The following are some examples:</p>
<dd>
Print what <tt>gmake</tt> is doing on standard output.
<p>
+
+ <dt><tt>gmake TOOL_VERBOSE=1</tt></dt>
+ <dd>Ask each tool invoked by the makefiles to print out what it is doing on
+ the standard output. This also implies <tt>VERBOSE=1</tt>.
+ <p></dd>
</dl>
<p>Every directory in the LLVM object tree includes a <tt>Makefile</tt> to build
@@ -941,9 +942,9 @@ named after the build type:</p>
<dd>
<dl>
<dt>Tools
- <dd><tt><i>OBJ_ROOT</i>/tools/Debug</tt>
+ <dd><tt><i>OBJ_ROOT</i>/Debug/bin</tt>
<dt>Libraries
- <dd><tt><i>OBJ_ROOT</i>/lib/Debug</tt>
+ <dd><tt><i>OBJ_ROOT</i>/Debug/lib</tt>
</dl>
<p>
@@ -951,9 +952,9 @@ named after the build type:</p>
<dd>
<dl>
<dt>Tools
- <dd><tt><i>OBJ_ROOT</i>/tools/Release</tt>
+ <dd><tt><i>OBJ_ROOT</i>/Release/bin</tt>
<dt>Libraries
- <dd><tt><i>OBJ_ROOT</i>/lib/Release</tt>
+ <dd><tt><i>OBJ_ROOT</i>/Release/lib</tt>
</dl>
<p>
@@ -961,9 +962,9 @@ named after the build type:</p>
<dd>
<dl>
<dt>Tools
- <dd><tt><i>OBJ_ROOT</i>/tools/Profile</tt>
+ <dd><tt><i>OBJ_ROOT</i>/Profile/bin</tt>
<dt>Libraries
- <dd><tt><i>OBJ_ROOT</i>/lib/Profile</tt>
+ <dd><tt><i>OBJ_ROOT</i>/Profile/lib</tt>
</dl>
</dl>
@@ -978,7 +979,8 @@ named after the build type:</p>
<p>
If you're running on a linux system that supports the "<a
-href="http://www.tat.physik.uni-tuebingen.de/~rguenth/linux/binfmt_misc.html">binfmt_misc</a>"
+ href="http://www.tat.physik.uni-tuebingen.de/~rguenth/linux/binfmt_misc.html">
+ binfmt_misc</a>"
module, and you have root access on the system, you can set your system up to
execute LLVM bytecode files directly. To do this, use commands like this (the
first command may not be required if you are already using the module):</p>
@@ -1015,17 +1017,20 @@ The following is a brief introduction to code layout:</p>
<!-- ======================================================================= -->
<div class="doc_subsection"><a name="cvsdir"><tt>CVS</tt> directories</a></div>
-
<div class="doc_text">
-
<p>Every directory checked out of CVS will contain a <tt>CVS</tt> directory; for
the most part these can just be ignored.</p>
+</div>
+<!-- ======================================================================= -->
+<div class="doc_subsection"><a name="examples"><tt>llvm/examples</tt></a></div>
+<div class="doc_text">
+ <p>This directory contains some simple examples of how to use the LLVM IR and
+ JIT.</p>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection"><a name="include"><tt>llvm/include</tt></a></div>
-
<div class="doc_text">
<p>This directory contains public header files exported from the LLVM
@@ -1054,7 +1059,6 @@ library. The three main subdirectories of this directory are:</p>
<!-- ======================================================================= -->
<div class="doc_subsection"><a name="lib"><tt>llvm/lib</tt></a></div>
-
<div class="doc_text">
<p>This directory contains most of the source files of the LLVM system. In LLVM,
@@ -1115,6 +1119,16 @@ different <a href="#tools">tools</a>.</p>
</div>
<!-- ======================================================================= -->
+<div class="doc_subsection"><a name="projects"><tt>llvm/projects</tt></a></div>
+<div class="doc_text">
+ <p>This directory contains projects that are not strictly part of LLVM but are
+ shipped with LLVM. This is also the directory where you should create your own
+ LLVM-based projects. See <tt>llvm/projects/sample</tt> for an example of how
+ to set up your own project. See <tt>llvm/projects/Stacker</tt> for a fully
+ functional example of a compiler front end.</p>
+</div>
+
+<!-- ======================================================================= -->
<div class="doc_subsection"><a name="runtime"><tt>llvm/runtime</tt></a></div>
<div class="doc_text">
@@ -1139,9 +1153,10 @@ end to compile.</p>
<!-- ======================================================================= -->
<div class="doc_subsection"><a name="llvmtest"><tt>llvm-test</tt></a></div>
<div class="doc_text">
- <p>This is not a directory in the normal llvm module, it is a separate CVS
+ <p>This is not a directory in the normal llvm module; it is a separate CVS
module that must be checked out (usually to <tt>projects/llvm-test</tt>). This
- module contains a comprehensive correctness, performance and benchmarking test
+ module contains a comprehensive correctness, performance, and benchmarking
+ test
suite for LLVM. It is a separate CVS module because not every LLVM user is
interested in downloading or building such a comprehensive test. For further
details on this test suite, please see the
@@ -1179,7 +1194,9 @@ information is in the <a href="CommandGuide/index.html">Command Guide</a>.</p>
pre-processing, translation, optimization, assembly, and linking of programs
all from one command line. <tt>llvmc</tt> also takes care of processing the
dependent libraries found in bytecode. This reduces the need to get the
- traditional <tt>-l&lt;name&gt;</tt> options right on the command line.</dd>
+ traditional <tt>-l&lt;name&gt;</tt> options right on the command line. Please
+ note that this tool is new in 1.4 and considered experimental. It will be
+ fully supported in 1.5.</dd>
<dt><tt><b>llvm-ar</b></tt></dt>
<dd>The archiver produces an archive containing
@@ -1194,6 +1211,14 @@ information is in the <a href="CommandGuide/index.html">Command Guide</a>.</p>
<dd>The disassembler transforms the LLVM bytecode to human readable
LLVM assembly.</dd>
+ <dt><tt><b>llvm-ld</b></tt></dt>
+ <dd><tt>llvm-ld</tt> is very similar to gccld and provides a general purpose
+ and extensible linker for LLVM. This is the linker invoked by <tt>llvmc</tt>.
+ It allows optimization modules to be loaded so that language specific
+ optimizations can be applied at link time. Please note that this tool is new
+ in LLVM 1.4 and still considered experimental. It will be fully supported in
+ LLVM 1.5.</dd>
+
<dt><tt><b>llvm-link</b></tt></dt>
<dd><tt>llvm-link</tt>, not surprisingly, links multiple LLVM modules into
a single program.</dd>
@@ -1203,7 +1228,7 @@ information is in the <a href="CommandGuide/index.html">Command Guide</a>.</p>
can directly execute LLVM bytecode (although very slowly...). In addition
to a simple interpreter, <tt>lli</tt> also has a tracing mode (entered by
specifying <tt>-trace</tt> on the command line). Finally, for
- architectures that support it (currently only x86 and Sparc), by default,
+ architectures that support it (currently x86, Sparc, and PowerPC), by default,
<tt>lli</tt> will function as a Just-In-Time compiler (if the
functionality was compiled in), and will execute the code <i>much</i>
faster than the interpreter.</dd>
@@ -1331,6 +1356,15 @@ are code generators for parts of LLVM infrastructure.</p>
</div>
+<!-- ======================================================================= -->
+<div class="doc_subsection"><a name="win32"><tt>llvm/win32</tt></a></div>
+<div class="doc_text">
+ <p>This directory contains build scripts and project files for use with
+ Visual C++. This allows developers on Windows to build LLVM without the need
+ for Cygwin. The contents of this directory should be considered experimental
+ at this time.
+ </p>
+</div>
<!-- *********************************************************************** -->
<div class="doc_section">
<a name="tutorial">An Example Using the LLVM Tool Chain</a>
diff --git a/llvm/docs/MakefileGuide.html b/llvm/docs/MakefileGuide.html
index 465a81cb402b..7e70f3aabed6 100644
--- a/llvm/docs/MakefileGuide.html
+++ b/llvm/docs/MakefileGuide.html
@@ -28,7 +28,11 @@
</li>
<li><a href="#tutorial">Tutorial</a>
<ol>
- <li><a href="#libraries">Libraries</a></li>
+ <li><a href="#libraries">Libraries</a>
+ <ol>
+ <li><a href="#Modules">Bytecode Modules</a></li>
+ </ol>
+ </li>
<li><a href="#tools">Tools</a>
<ol>
<li><a href="#JIT">JIT Tools</a></li>
@@ -41,6 +45,7 @@
<li><a href="#all">all</a></li>
<li><a href="#all-local">all-local</a></li>
<li><a href="#check">check</a></li>
+ <li><a href="#check-local">check-local</a></li>
<li><a href="#clean">clean</a></li>
<li><a href="#clean-local">clean-local</a></li>
<li><a href="#dist">dist</a></li>
@@ -195,7 +200,7 @@
<div class="doc_subsection"><a name="Comments">Comments</a></div>
<div class="doc_text">
<p>User Makefiles need not have comments in them unless the construction is
- unusual or it doesn't strictly follow the rules and patterns of the LLVM
+ unusual or it does not strictly follow the rules and patterns of the LLVM
makefile system. Makefile comments are invoked with the pound (#) character.
The # character and any text following it, to the end of the line, are ignored
by <tt>make</tt>.</p>
@@ -236,6 +241,27 @@
</div>
<!-- ======================================================================= -->
+<div class="doc_subsubsection"><a name="Modules">Bytecode Modules</a></div>
+<div class="doc_text">
+ <p>In some situations, it is desireable to build a single bytecode module from
+ a variety of sources, instead of an archive, shared library, or bytecode
+ library. Bytecode modules can be specified in addition to any of the other
+ types of libraries by defining the <a href="#MODULE_NAME">MODULE_NAME</a>
+ variable. For example:</p>
+ <pre><tt>
+ LIBRARYNAME = mylib
+ BYTECODE_LIBRARY = 1
+ MODULE_NAME = mymod
+ </tt></pre>
+ <p>will build a module named <tt>mymod.bc</tt> from the sources in the
+ directory. This module will be an aggregation of all the bytecode modules
+ derived from the sources. The example will also build a bytecode archive
+ containing a bytecode module for each compiled source file. The difference is
+ subtle, but important depending on how the module or library is to be linked.
+ </p>
+</div>
+
+<!-- ======================================================================= -->
<div class="doc_subsection"><a name="tools">Tools</a></div>
<div class="doc_text">
<p>For building executable programs (tools), you must provide the name of the
@@ -312,11 +338,13 @@
<div class="doc_text">
<p>This section describes each of the targets that can be built using the LLVM
Makefile system. Any target can be invoked from any directory but not all are
- applicable to a given directory (e.g. "check", "dist", and "install" will
+ applicable to a given directory (e.g. "check", "dist" and "install" will
always operate as if invoked from the top level directory).</p>
<table style="text-align:left">
- <tr><th>Target Name</th><th>Implied Targets</th><th>Target Description</th></tr>
+ <tr>
+ <th>Target Name</th><th>Implied Targets</th><th>Target Description</th>
+ </tr>
<tr><td><a href="#all"><tt>all</tt></a></td><td></td>
<td>Compile the software recursively. Default target.
</td></tr>
@@ -324,7 +352,12 @@
<td>Compile the software in the local directory only.
</td></tr>
<tr><td><a href="#check"><tt>check</tt></a></td><td></td>
- <td>Change to the llvm/test directory and run regression tests.
+ <td>Change to the <tt>test</tt> directory in a project and run the
+ test suite there.
+ </td></tr>
+ <tr><td><a href="#check-local"><tt>check-local</tt></a></td><td></td>
+ <td>Run a local test suite. Generally this is only defined in the
+ <tt>Makefile</tt> of the project's <tt>test</tt> directory.
</td></tr>
<tr><td><a href="#clean"><tt>clean</tt></a></td><td></td>
<td>Remove built objects recursively.
@@ -378,11 +411,40 @@
</div>
<!-- ======================================================================= -->
+<div class="doc_subsection"><a name="check">check</a></div>
+<div class="doc_text">
+ <p>This target can be invoked from anywhere within a project's directories
+ but always invokes the <a href="#check-local"><tt>check-local</tt></a> target
+ in the project's <tt>test</tt> directory, if it exists and has a
+ <tt>Makefile</tt>. A warning is produced otherwise. If
+ <a href="#TESTSUITE"><tt>TESTSUITE</tt></a> is defined on the <tt>make</tt>
+ command line, it will be passed down to the invocation of
+ <tt>make check-local</tt> in the <tt>test</tt> directory. The intended usage
+ for this is to assist in running specific suites of tests. If
+ <tt>TESTSUITE</tt> is not set, the implementation of <tt>check-local</tt>
+ should run all normal tests. It is up to the project to define what
+ different values for <tt>TESTSUTE</tt> will do. See the
+ <a href="TestingGuide.html">TestingGuide</a> for further details.</p>
+</div>
+
+<!-- ======================================================================= -->
+<div class="doc_subsection"><a name="check-local">check-local</a></div>
+<div class="doc_text">
+ <p>This target should be implemented by the <tt>Makefile</tt> in the project's
+ <tt>test</tt> directory. It is invoked by the <tt>check</tt> target elsewhere.
+ Each project is free to define the actions of <tt>check-local</tt> as
+ appropriate for that project. The LLVM project itself uses dejagnu to run a
+ suite of feature and regresson tests. Other projects may choose to use
+ dejagnu or any other testing mechanism.</p>
+</div>
+
+<!-- ======================================================================= -->
<div class="doc_subsection"><a name="clean">clean</a></div>
<div class="doc_text">
<p>This target cleans the build directory, recursively removing all things
- that the Makefile builds. Despite once or twice attempting to remove /*, the
- cleaning rules have been made guarded so they shouldn't go awry.</p>
+ that the Makefile builds. The cleaning rules have been made guarded so they
+ shouldn't go awry (via <tt>rm -f $(UNSET_VARIABLE)/*</tt> which will attempt
+ to erase the entire directory structure.</p>
</div>
<!-- ======================================================================= -->
@@ -453,8 +515,8 @@
<!-- ======================================================================= -->
<div class="doc_subsection"><a name="printvars">printvars</a></div>
<div class="doc_text">
- <p>This utility target just causes LLVM to print out some of its variables so
- that you can double check how things are set. </p>
+ <p>This utility target just causes the LLVM makefiles to print out some of
+ the makefile variables so that you can double check how things are set. </p>
</div>
<!-- ======================================================================= -->
@@ -544,6 +606,14 @@
source files, all built sources, all Makefiles, and most documentation files
will be automatically distributed. Use this variable to distribute any
files that are not automatically distributed.</dd>
+ <dt><a name="FAKE_SOURCES"><tt>FAKE_SOURCES</tt><small>(optional)</small>
+ </a></dt>
+ <dd>This variable is like <a href="#SOURCES"><tt>SOURCES</tt></a> except that
+ the source files don't need to exist. The makefiles only use
+ <tt>FAKE_SOURCES</tt> to create the names of derived objects that should be
+ included in the directory's result. It is assumed that the project's
+ <tt>Makefile</tt> will define how to build the derived objects
+ necessary.</dd>
<dt><a name="KEEP_SYMBOLS"><tt>KEEP_SYMBOLS</tt></a></dt>
<dd>If set to any value, specifies that when linking executables the
makefiles should retain debug symbols in the executable. Normally, symbols
@@ -588,6 +658,8 @@
<dd>Specifies the name of the LLVM code generation target that the
current directory builds. Setting this variable enables additional rules to
build <tt>.inc</tt> files from <tt>.td</tt> files. </dd>
+ <dt><a name="TESTSUITE"><tt>TESTSUITE</tt></a></dt>
+ <dd>Specifies the directory of tests to run in <tt>llvm/test</tt>.</dd>
<dt><a name="TOOLNAME"><tt>TOOLNAME</tt></a></dt>
<dd>Specifies the name of the tool that the current directory should
build.</dd>
@@ -619,7 +691,7 @@
<li>In the Makefile (only <em>after</em> the inclusion of <a
href="#Makefile.common"><tt>$(LEVEL)/Makefile.common</tt></a>).</li>
</ul>
- <p>The overridable variables are given below:</p>
+ <p>The override variables are given below:</p>
<dl>
<dt><a name="AR"><tt>AR</tt></a> <small>(defaulted)</small></dt>
<dd>Specifies the path to the <tt>ar</tt> tool.</dd>
@@ -772,7 +844,8 @@
<dd>The configuration specific directory into which executables are placed
before they are installed.</dd>
<dt><a name="TopDistDir"><tt>TopDistDir</tt></a></dt>
- <dd>The top most directory into which the distribution files are copied.</dd>
+ <dd>The top most directory into which the distribution files are copied.
+ </dd>
<dt><a name="Verb"><tt>Verb</tt></a></dt>
<dd>Use this as the first thing on your build script lines to enable or
disable verbose mode. It expands to either an @ (quiet mode) or nothing
@@ -786,83 +859,88 @@
<p>Variables listed below are used by the LLVM Makefile System
and considered internal. You should not use these variables under any
circumstances.</p>
- <dl>
- <dt><a name="Archive"><tt>Archive</tt></a></dt><dd></dd>
- <dt><a name="AR.Flags"><tt>AR.Flags</tt></a></dt><dd></dd>
- <dt><a name="BaseNameSources"><tt>BaseNameSources</tt></a></dt><dd></dd>
- <dt><a name="BCCompile.C"><tt>BCCompile.C</tt></a></dt><dd></dd>
- <dt><a name="BCCompile.CXX"><tt>BCCompile.CXX</tt></a></dt><dd></dd>
- <dt><a name="BCLinkLib"><tt>BCLinkLib</tt></a></dt><dd></dd>
- <dt><a name="Burg"><tt>Burg</tt></a></dt><dd></dd>
- <dt><a name="C.Flags"><tt>C.Flags</tt></a></dt><dd></dd>
- <dt><a name="Compile.C"><tt>Compile.C</tt></a></dt><dd></dd>
- <dt><a name="CompileCommonOpts"><tt>CompileCommonOpts</tt></a></dt><dd></dd>
- <dt><a name="Compile.CXX"><tt>Compile.CXX</tt></a></dt><dd></dd>
- <dt><a name="ConfigStatusScript"><tt>ConfigStatusScript</tt></a></dt><dd></dd>
- <dt><a name="ConfigureScript"><tt>ConfigureScript</tt></a></dt><dd></dd>
- <dt><a name="CPP.Flags"><tt>CPP.Flags</tt></a></dt><dd></dd>
- <dt><a name="CPP.Flags "><tt>CPP.Flags </tt></a></dt><dd></dd>
- <dt><a name="CXX.Flags"><tt>CXX.Flags</tt></a></dt><dd></dd>
- <dt><a name="DependFiles"><tt>DependFiles</tt></a></dt><dd></dd>
- <dt><a name="DestArchiveLib"><tt>DestArchiveLib</tt></a></dt><dd></dd>
- <dt><a name="DestBytecodeLib"><tt>DestBytecodeLib</tt></a></dt><dd></dd>
- <dt><a name="DestRelinkedLib"><tt>DestRelinkedLib</tt></a></dt><dd></dd>
- <dt><a name="DestSharedLib"><tt>DestSharedLib</tt></a></dt><dd></dd>
- <dt><a name="DestTool"><tt>DestTool</tt></a></dt><dd></dd>
- <dt><a name="DistAlways"><tt>DistAlways</tt></a></dt><dd></dd>
- <dt><a name="DistCheckDir"><tt>DistCheckDir</tt></a></dt><dd></dd>
- <dt><a name="DistCheckTop"><tt>DistCheckTop</tt></a></dt><dd></dd>
- <dt><a name="DistFiles"><tt>DistFiles</tt></a></dt><dd></dd>
- <dt><a name="DistName"><tt>DistName</tt></a></dt><dd></dd>
- <dt><a name="DistOther"><tt>DistOther</tt></a></dt><dd></dd>
- <dt><a name="DistSources"><tt>DistSources</tt></a></dt><dd></dd>
- <dt><a name="DistSubDirs"><tt>DistSubDirs</tt></a></dt><dd></dd>
- <dt><a name="DistTarBZ2"><tt>DistTarBZ2</tt></a></dt><dd></dd>
- <dt><a name="DistTarGZip"><tt>DistTarGZip</tt></a></dt><dd></dd>
- <dt><a name="DistZip"><tt>DistZip</tt></a></dt><dd></dd>
- <dt><a name="ExtraLibs"><tt>ExtraLibs</tt></a></dt><dd></dd>
- <dt><a name="INCFiles"><tt>INCFiles</tt></a></dt><dd></dd>
- <dt><a name="InternalTargets"><tt>InternalTargets</tt></a></dt><dd></dd>
- <dt><a name="LD.Flags"><tt>LD.Flags</tt></a></dt><dd></dd>
- <dt><a name="LexOutput"><tt>LexOutput</tt></a></dt><dd></dd>
- <dt><a name="LibName.A"><tt>LibName.A</tt></a></dt><dd></dd>
- <dt><a name="LibName.BC"><tt>LibName.BC</tt></a></dt><dd></dd>
- <dt><a name="LibName.LA"><tt>LibName.LA</tt></a></dt><dd></dd>
- <dt><a name="LibName.O"><tt>LibName.O</tt></a></dt><dd></dd>
- <dt><a name="LibTool.Flags"><tt>LibTool.Flags</tt></a></dt><dd></dd>
- <dt><a name="Link"><tt>Link</tt></a></dt><dd></dd>
- <dt><a name="LLVMGCCLibDir"><tt>LLVMGCCLibDir</tt></a></dt><dd></dd>
- <dt><a name="LLVMLibDir"><tt>LLVMLibDir</tt></a></dt><dd></dd>
- <dt><a name="LLVMLibsOptions"><tt>LLVMLibsOptions</tt></a></dt><dd></dd>
- <dt><a name="LLVMLibsPaths"><tt>LLVMLibsPaths</tt></a></dt><dd></dd>
- <dt><a name="LLVMToolDir"><tt>LLVMToolDir</tt></a></dt><dd></dd>
- <dt><a name="LLVMUsedLibs"><tt>LLVMUsedLibs</tt></a></dt><dd></dd>
- <dt><a name="LocalTargets"><tt>LocalTargets</tt></a></dt><dd></dd>
- <dt><a name="LTCompile.C"><tt>LTCompile.C</tt></a></dt><dd></dd>
- <dt><a name="LTCompile.CXX"><tt>LTCompile.CXX</tt></a></dt><dd></dd>
- <dt><a name="LTInstall"><tt>LTInstall</tt></a></dt><dd></dd>
- <dt><a name="ObjectsBC"><tt>ObjectsBC</tt></a></dt><dd></dd>
- <dt><a name="ObjectsLO"><tt>ObjectsLO</tt></a></dt><dd></dd>
- <dt><a name="ObjectsO"><tt>ObjectsO</tt></a></dt><dd></dd>
- <dt><a name="ObjMakefiles"><tt>ObjMakefiles</tt></a></dt><dd></dd>
- <dt><a name="Parallel_Targets"><tt>Parallel_Targets</tt></a></dt><dd></dd>
- <dt><a name="PreConditions"><tt>PreConditions</tt></a></dt><dd></dd>
- <dt><a name="ProjLibsOptions"><tt>ProjLibsOptions</tt></a></dt><dd></dd>
- <dt><a name="ProjLibsPaths"><tt>ProjLibsPaths</tt></a></dt><dd></dd>
- <dt><a name="ProjUsedLibs"><tt>ProjUsedLibs</tt></a></dt><dd></dd>
- <dt><a name="Ranlib"><tt>Ranlib</tt></a></dt><dd></dd>
- <dt><a name="RecursiveTargets"><tt>RecursiveTargets</tt></a></dt><dd></dd>
- <dt><a name="Relink"><tt>Relink</tt></a></dt><dd></dd>
- <dt><a name="SrcMakefiles"><tt>SrcMakefiles</tt></a></dt><dd></dd>
- <dt><a name="Strip"><tt>Strip</tt></a></dt><dd></dd>
- <dt><a name="StripWarnMsg"><tt>StripWarnMsg</tt></a></dt><dd></dd>
- <dt><a name="TableGen"><tt>TableGen</tt></a></dt><dd></dd>
- <dt><a name="TDFiles"><tt>TDFiles</tt></a></dt><dd></dd>
- <dt><a name="ToolBuildPath"><tt>ToolBuildPath</tt></a></dt><dd></dd>
- <dt><a name="TopLevelTargets"><tt>TopLevelTargets</tt></a></dt><dd></dd>
- <dt><a name="UserTargets"><tt>UserTargets</tt></a></dt><dd></dd>
- <dt><a name="YaccOutput"><tt>YaccOutput</tt></a></dt><dd></dd>
- </dl>
+ <p><tt>
+ Archive
+ AR.Flags
+ BaseNameSources
+ BCCompile.C
+ BCCompile.CXX
+ BCLinkLib
+ Burg
+ C.Flags
+ Compile.C
+ CompileCommonOpts
+ Compile.CXX
+ ConfigStatusScript
+ ConfigureScript
+ CPP.Flags
+ CPP.Flags
+ CXX.Flags
+ DependFiles
+ DestArchiveLib
+ DestBytecodeLib
+ DestModule
+ DestRelinkedLib
+ DestSharedLib
+ DestTool
+ DistAlways
+ DistCheckDir
+ DistCheckTop
+ DistFiles
+ DistName
+ DistOther
+ DistSources
+ DistSubDirs
+ DistTarBZ2
+ DistTarGZip
+ DistZip
+ ExtraLibs
+ FakeSources
+ INCFiles
+ InternalTargets
+ LD.Flags
+ LexFiles
+ LexOutput
+ LibName.A
+ LibName.BC
+ LibName.LA
+ LibName.O
+ LibTool.Flags
+ Link
+ LinkModule
+ LLVMLibDir
+ LLVMLibsOptions
+ LLVMLibsPaths
+ LLVMToolDir
+ LLVMUsedLibs
+ LocalTargets
+ LTCompile.C
+ LTCompile.CXX
+ LTInstall
+ Module
+ ObjectsBC
+ ObjectsLO
+ ObjectsO
+ ObjMakefiles
+ ParallelTargets
+ PreConditions
+ ProjLibsOptions
+ ProjLibsPaths
+ ProjUsedLibs
+ Ranlib
+ RecursiveTargets
+ Relink
+ SrcMakefiles
+ Strip
+ StripWarnMsg
+ TableGen
+ TDFiles
+ ToolBuildPath
+ TopLevelTargets
+ UserTargets
+ YaccFiles
+ YaccOutput
+ </tt></p>
</div>
<!-- *********************************************************************** -->
diff --git a/llvm/docs/ProgrammersManual.html b/llvm/docs/ProgrammersManual.html
index 7c6bd15f3573..714f3c484452 100644
--- a/llvm/docs/ProgrammersManual.html
+++ b/llvm/docs/ProgrammersManual.html
@@ -20,6 +20,7 @@
<li>The <tt>-time-passes</tt> option</li>
<li>How to use the LLVM Makefile system</li>
<li>How to write a regression test</li>
+
-->
</ul>
</li>
@@ -212,7 +213,7 @@ STL</a>.</li>
<li><a href="http://www.research.att.com/%7Ebs/C++.html">Bjarne Stroustrup's C++
Page</a></li>
-<li><a href="http://www.linux.com.cn/Bruce_Eckel/TICPPv2/Contents.htm">
+<li><a href="http://64.78.49.204/">
Bruce Eckel's Thinking in C++, 2nd ed. Volume 2 Revision 4.0 (even better, get
the book).</a></li>
diff --git a/llvm/docs/Projects.html b/llvm/docs/Projects.html
index ecdb35b54c6c..d708c8eda351 100644
--- a/llvm/docs/Projects.html
+++ b/llvm/docs/Projects.html
@@ -186,19 +186,18 @@ directories:</p>
This subdirectory should contain tests that verify that your code
works correctly. Automated tests are especially useful.
<p>
- Currently, the LLVM build system provides little support for tests,
- although some exists. Expanded support for tests will hopefully
- occur in the future. In the meantime, the LLVM system does provide the
- following:
+ Currently, the LLVM build system provides basic support for tests.
+ The LLVM system provides the following:
<ul>
<li>
- LLVM provides several QMTest test classes that can be used to
- create tests. They can be found in
- <tt>llvm/test/QMTest/llvm.py</tt>. These test classes perform a
- variety of functions, including code optimization tests, assembly
- tests, and code analysis tests. The Makefile in
- <tt>llvm/test</tt> provides the QMTest context needed by LLVM test
- classes.
+ LLVM provides a tcl procedure that is used by Dejagnu to run
+ tests. It can be found in <tt>llvm/lib/llvm-dg.exp</tt>. This
+ test procedure uses RUN lines in the actual test case to determine
+ how to run the test. See the <a
+ href="TestingGuide.html">TestingGuide</a> for more details. You
+ can easily write Makefile support similar to the Makefiles in <tt>llvm/test</tt>
+ to use Dejagnu to run your project's tests.</li>
+
<p>
<li>
diff --git a/llvm/docs/ReleaseNotes.html b/llvm/docs/ReleaseNotes.html
index cf189e6a6434..938a2645f4ce 100644
--- a/llvm/docs/ReleaseNotes.html
+++ b/llvm/docs/ReleaseNotes.html
@@ -44,14 +44,14 @@
<p>This document contains the release notes for the LLVM compiler
infrastructure, release 1.4. Here we describe the status of LLVM, including any
-known problems and bug fixes from the previous release. The most up-to-date
+known problems and improvements from the previous release. The most up-to-date
version of this document can be found on the <a
href="http://llvm.cs.uiuc.edu/releases/1.4/">LLVM 1.4 web site</a>. If you are
not reading this on the LLVM web pages, you should probably go there because
this document may be updated after the release.</p>
-<p>For more information about LLVM, including information about potentially more
-current releases, please check out the <a href="http://llvm.cs.uiuc.edu">main
+<p>For more information about LLVM, including information about the latest
+release, please check out the <a href="http://llvm.cs.uiuc.edu">main LLVM
web site</a>. If you have questions or comments, the <a
href="http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVM developer's mailing
list</a> is a good place to send them.</p>
@@ -73,9 +73,18 @@ href="http://llvm.cs.uiuc.edu/releases/">releases page</a>.</p>
<p>This is the fifth public release of the LLVM compiler infrastructure.</p>
-<p> At this time, LLVM is known to correctly compile and run all C &amp; C++
-SPEC CPU95 &amp; 2000 benchmarks, the Olden benchmarks, and the Ptrdist
-benchmarks, and <b>many</b> other C and C++ programs.</p>
+<p> At this time, LLVM is known to correctly compile on a broad range of
+C and C++ programs, including the SPEC CPU95 &amp; 2000 suite. This release
+includes several major enhancements to the LLVM system, including a new
+PowerPC JIT, enhancements to the C/C++ front-end to provide source line number
+information in LLVM, a new <a href="CommandGuide/html/llvmc.html">compiler
+driver</a>, and several other enhancements listed below. It also includes
+bug fixes for those problems found since the 1.3 release.</p>
+
+<p>Note that this release seperates the LLVM Program Testsuite out of the
+main LLVM distribution into a seperate CVS repository and tarball. This
+reduces the size of the main LLVM distribution. Also note that LLVM now
+builds tools into llvm/Debug/bin by default instead of llvm/tools/Debug.</p>
</div>
@@ -86,71 +95,67 @@ benchmarks, and <b>many</b> other C and C++ programs.</p>
<div class="doc_text">
<ol>
- <li>LLVM now includes a JIT for the PowerPC target.</li>
- <li>LLVM now optimizes global variables significantly more than it did
- before.
+ <li>LLVM now includes a Just-In-Time compiler for the PowerPC target.</li>
+ <li>llvmgcc and llvmg++ now emit source line number information when '-g' is
+ passed in, making it possible to map from LLVM code back to source.
+ This information is currently used by llvm-db and can be used with other
+ tools and passes.</li>
+ <li>The test/Programs hierarchy <a href="http://llvm.cs.uiuc.edu/PR257">has
+ been moved out of the main LLVM tree</a> into a separate CVS repository and
+ tarball. This shrinks the distribution size of LLVM itself significantly.
</li>
+ <li>LLVM now optimizes global variables more aggressively than it did
+ before.</li>
<li>LLVM now includes the new '<tt>undef</tt>' value and
<a href="LangRef.html#i_unreachable"><tt>unreachable</tt></a> instruction,
which give the optimizer more information about the behavior of the
program.
</li>
- <li>llvmgcc and llvmg++ now emit source line number information when '-g' is
- passed in. This information can be used with llvm-db or other tools and
- passes.
- </li>
- <li>The test/Programs hierarchy <a href="http://llvm.cs.uiuc.edu/PR257">has
- been moved out of the main LLVM tree</a> into a separate CVS repository and
- tarball. This shrinks the distribution size of LLVM itself significantly.
- </li>
<li>Bytecode compression with bzip2 has been implemented. All bytecode files
generated by LLVM will now be compressed by default. Compression can be
disabled with the <tt>-disable-compression</tt> option to the tools that can
generate bytecode files.
</li>
- <li>A generic <a href="http://llvm.cs.uiuc.edu/PR353">compiler driver</a> and
- an associated <a href="CommandGuide/html/llvm-ld.html">generic linker</a> have
- been implemented. The compiler driver is generic because it can be configured
+ <li>A generic <a href="CommandGuide/html/llvmc.html">compiler driver</a>
+ (llvmc) and
+ an associated <a href="CommandGuide/html/llvm-ld.html">generic linker</a>
+ (llvm-ld) have been added. The compiler driver is generic because it can be
+ configured
to pre-process, translate, optimize, assemble, and link code from any source
- language. This aids compiler writers because all that is needed is a
- source-to-bytecode or source-to-assembly translator and a configuration file.
- The linker is generic because it allows dynamically loadable optimization
- modules to be executed for link-time optimization. Language specific
- link-time optimization modules can be created and executed automatically.
+ language with an LLVM front-end. This makes it easier for compiler writers
+ to hide the multiple steps required to compile a program (compiling,
+ optimizing, linking runtime libraries, etc) in one simple command.
</li>
<li>The <a href="http://llvm.cs.uiuc.edu/PR263">dependent libraries</a>
feature has been implemented. This allows front end compilers to indicate in
the bytecode which libraries the bytecode needs to be linked with. Both the
- C/C++ front end and Stacker support generating the required libraries. The
- Linker now supports using this information to ensure required libaries are
+ C/C++ and Stacker front ends support generating the required dependencies.
+ The linker now supports using this information to ensure required libaries are
linked into the module. This minimizes the need to use the <tt>-l</tt> option
- when using <a href="CommandGuide/html/llvmc.html"><tt>llvmc</tt></a>
+ when using <a href="CommandGuide/html/llvmc.html"><tt>llvmc</tt></a>.
</li>
- <li>The LLVM makefiles have been improved to build LLVM faster (2x) and
- includes new targets (like dist-check, uninstall). One important change is
- associated with <a href="http://llvm.cs.uiuc.edu/PR456">PR456</a>. The
- libraries and tools will now be built into <tt>$builddir/Debug/{bin,lib}</tt>
- instead of <tt>$builddir/tools/Debug</tt> and <tt>$builddir/lib/Debug</tt>.
- Similarly for <tt>Release</tt> and <tt>Profile</tt> builds.
+ <li>The LLVM makefiles have been improved to build LLVM much faster and
+ includes new targets (like dist-check, uninstall). One important user-visible
+ change is that libraries and tools will now be built into
+ <tt>$builddir/Debug/{bin,lib}</tt>
+ instead of <tt>$builddir/tools/Debug</tt> and <tt>$builddir/lib/Debug</tt>
+ (Similarly for <tt>Release</tt> and <tt>Profile</tt> builds).
</li>
<li>The LLVM source code is much more compatible with Microsoft Visual C++,
including the JIT and runtime-code generation, though the entire system
may not work with it.
</li>
- <li>The target-to-JIT interfaces <a href="http://llvm.cs.uiuc.edu/PR283">are
+ <li>The JIT-Target interfaces <a href="http://llvm.cs.uiuc.edu/PR283">are
now much simpler</a> and more powerful.
</li>
+ <li>LLVM now provides llvm-ar and llvm-ranlib tools for working with archives
+ of LLVM bytecode files.</li>
<li>zlib and libpng are <a href="http://llvm.cs.uiuc.edu/PR417">no longer
included in the main LLVM tarball</a>.</li>
- <li>The LLVM code generator now generates asm writers for the target from
- an abstract target description, instead of requiring them to be hand
- written.</li>
- <li>LLVM regression and feature tests can now be run with DejaGNU.</li>
- <li>llvmgcc and llvmg++ now emit source-level line number information, making
- it possible to map from LLVM code back to source. This is currently used
- by llvm-db.</li>
- <li>Floating point intensive programs on X86 systems run much faster
- with the LLC code generator and JIT than in 1.3.</li>
+ <li>The LLVM code generator now automatically generates assembly code writers
+ from an abstract target descriptions, eliminating the need to write
+ assembly printers manually.</li>
+ <li>LLVM regression and feature tests now use DejaGNU instead of QMTest.</li>
</ol>
</div>
@@ -187,11 +192,12 @@ issues were fixed:</a>
<div class="doc_text">
<ol>
- <li><a href="http://llvm.cs.uiuc.edu/PR426">[llvmg++] Tons of warnings
- are spewed when linking to libstdc++</a>
+ <li>The linker no longer <a href="http://llvm.cs.uiuc.edu/PR426">emits many
+ useless warnings</a> when linking C++ programs.
</li>
- <li><a href="http://llvm.cs.uiuc.edu/PR352">include/{Support,Config} ->
- include/llvm/{Support,Config}</a>
+ <li>The LLVM <a href="http://llvm.cs.uiuc.edu/PR352">#include namespace</a>
+ has been made consistent. Files in <tt>llvm/include/{Support,Config}</tt>
+ are now located in <tt>llvm/include/llvm/{Support,Config}</tt>.
</li>
<li>The names of the libraries generated by compiling LLVM source have been
changed to ensure they do not conflict with other packages upon installation.
@@ -199,23 +205,13 @@ issues were fixed:</a>
the library <tt>libasmparser.a</tt> in 1.3 has become
<tt>libLLVMAsmParser.a</tt> in release 1.4.
</li>
- <li><a href="http://llvm.cs.uiuc.edu/PR459">[llvmg++] C++ frontend is expanding
- lots of unused inline functions</a></li>
-</ol>
-
-</div>
+ <li>The C++ frontend no longer expands and emits <a
+ href="http://llvm.cs.uiuc.edu/PR459">all inline functions, even if they
+ are unused</a>. It now properly tracks which functions are needed and
+ only compiles those.</li>
-<!--=========================================================================-->
-<div class="doc_subsubsection">
-In this release, the following build problems were fixed:
-</div>
-
-<div class="doc_text">
-<ol>
- <li><a href="http://llvm.cs.uiuc.edu/PR256">[autoconf] further standardizing
- autoconf usage</a>. Various improvements in the configure.ac script were
- made as well as the makefile system.
- </li>
+ <li>Many improvements in the <a href="http://llvm.cs.uiuc.edu/PR256">autoconf
+ and makefile systems</a> have been implemented.</li>
</ol>
</div>
@@ -227,9 +223,12 @@ improvements:</a>
<div class="doc_text">
<ol>
- <li><a href="http://llvm.cs.uiuc.edu/PR362">Ugly code generated for
- std::min/std::max</a>
- </li>
+ <li>The optimizer produces <a href="http://llvm.cs.uiuc.edu/PR362">more
+ efficient code for std::min/std::max</a> and other similar functions.</li>
+ <li>The X86 backend generates substantially faster code for floating point
+ intensive programs.</li>
+ <li>The PowerPC backend generates more efficient code in many common
+ scenarios.</li>
</ol>
</div>
@@ -269,7 +268,7 @@ were fixed:</a>
bitfield which does not increase struct size</a></li>
<li><a href="http://llvm.cs.uiuc.edu/PR424">[llvmgcc] llvmgcc emits invalid
constant exprs</a></li>
- <li><a href="http://llvm.cs.uiuc.edu/PR421">[llvmg++] Crash in initializing
+ <li><a href="http://llvm.cs.uiuc.edu/PR421">[llvmg++] Crash initializing
array with constructors in hard EH situations</a></li>
<li><a href="http://llvm.cs.uiuc.edu/PR397">[llvm-gcc] Inline function
redefinitions error due to 'asm' function rename</a></li>
@@ -298,14 +297,15 @@ were fixed:</a>
<div class="doc_text">
-<p>LLVM is known to work in the following platforms:</p>
+<p>LLVM is known to work on the following platforms:</p>
<ul>
<li>Intel and AMD machines running Red Hat Linux and FreeBSD (and probably
other unix-like systems).</li>
<li>Sun UltraSPARC workstations running Solaris 8.</li>
-<li>Intel and AMD machines running on Win32 with the Cygwin libraries.</li>
-<li>PowerPC-based Mac OS X boxes, running 10.2 and above.</li>
+<li>Intel and AMD machines running on Win32 with the Cygwin libraries (limited
+ support is available for native builds with Visual C++).</li>
+<li>PowerPC-based Mac OS X systems, running 10.2 and above.</li>
</ul>
<p>The core LLVM infrastructure uses
@@ -314,6 +314,7 @@ to the machine and operating system on which it is built. However, minor
porting may be required to get LLVM to work on new platforms. We welcome your
portability patches and reports of successful builds or error messages.</p>
+<!--
<p>Note that the LLVM build system does not currently support directories with
spaces on them when running on Win32/cygwin. We strongly recommend running
LLVM and the C frontend out of a top-level directory without spaces (e.g.,
@@ -322,6 +323,7 @@ cygwin packages. By default, many important tools are not installed that
are needed by the LLVM build process or test suite (e.g., /bin/time). Finally,
please make sure that there are no directories with spaces in them in your
PATH environment variable.</p>
+-->
</div>
@@ -355,11 +357,11 @@ useful to some people. In particular, if you would like to work on one of these
components, please contact us on the llvmdev list.</p>
<ul>
-<li>The following passes are incomplete or buggy: <tt>-pgmdep, -memdep,
- -ipmodref, -cee, -branch-combine, -instloops, -paths</tt></li>
-<li>The <tt>-pre</tt> pass is incomplete (there are cases it doesn't handle that
- it should) and not thoroughly tested.</li>
-<li>The <tt>llvm-db</tt> tool is in a very early stage of development.</li>
+<li>The following passes are incomplete or buggy, and may be removed in future
+ releases: <tt>-pgmdep, -memdep, -ipmodref, -cee, -branch-combine,
+ -instloops, -paths, -pre</tt></li>
+<li>The <tt>llvm-db</tt> tool is in a very early stage of development, but can
+ be used to step through programs and inspect the stack.</li>
<li>The "iterative scan" register allocator (enabled with -regalloc=iterativescan)
is not stable.</li>
</ul>
@@ -380,22 +382,10 @@ components, please contact us on the llvmdev list.</p>
such, execution of a threaded program could cause these data structures to be
corrupted.
</li>
- <li>Linking in static archive files (.a files) is slow by default because
- there is no symbol table in the archive. To remedy this, run
- <a href="CommandGuide/html/llvm-ranlib.html"><tt>llvm-ranlib</tt></a> on the
- archive to add an LLVM symbol table.
- </li>
- <li>The gccld program <a href="http://llvm.cs.uiuc.edu/PR139">does not link
- objects/archives in the order specified on the command line.</a>
- </li>
<li><a href="http://llvm.cs.uiuc.edu/PR240">The lower-invoke pass does not
mark values live across a setjmp as volatile</a>. This missing feature
only affects targets whose setjmp/longjmp libraries do not save and restore
the entire register file.</li>
- <li><a href="http://llvm.cs.uiuc.edu/PR427">[bytecode] Assertion on V1
- Bytecode Files</a>. This bug won't be fixed because V1 bytecode had its own
- problems, no one is using V1 bytecode any more, and the fix is non-trivial.
- </li>
</ul>
</div>
@@ -421,9 +411,6 @@ components, please contact us on the llvmdev list.</p>
<li>Initialization of global union variables can only be done <a
href="http://llvm.cs.uiuc.edu/PR162">with the largest union member</a>.</li>
-<li><a href="http://llvm.cs.uiuc.edu/PR244">[llvm-gcc] Error when an implicitly
-external function is re-declared as static</a></li>
-
</ul>
</div>
@@ -464,7 +451,7 @@ work:
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Explicit-Reg-Vars.html#Explicit%20Reg%20Vars">Explicit Reg Vars</a>: Defining variables residing in specified registers.</li>
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html#Vector%20Extensions">Vector Extensions</a>: Using vector instructions through built-in functions.</li>
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Target-Builtins.html#Target%20Builtins">Target Builtins</a>: Built-in functions specific to particular targets.</li>
- <li><a href="http://gcc.gnu.org/onlinedocs/gcc/Thread-Local.html#Thread-Local">Thread-Local</a>: Per-thread variables.</li>
+ <li><a href="http://gcc.gnu.org/onlinedocs/gcc/Thread_002dLocal.html">Thread-Local</a>: Per-thread variables.</li>
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html#Pragmas">Pragmas</a>: Pragmas accepted by GCC.</li>
</ol>
@@ -485,10 +472,11 @@ work:
return.<br>
<b>Supported:</b> <tt>format</tt>, <tt>format_arg</tt>, <tt>non_null</tt>,
- <tt>constructor</tt>, <tt>destructor</tt>, <tt>unused</tt>,
+ <tt>noreturn</tt>, <tt>constructor</tt>, <tt>destructor</tt>,
+ <tt>unused</tt>,
<tt>deprecated</tt>, <tt>warn_unused_result</tt>, <tt>weak</tt><br>
- <b>Ignored:</b> <tt>noreturn</tt>, <tt>noinline</tt>,
+ <b>Ignored:</b> <tt>noinline</tt>,
<tt>always_inline</tt>, <tt>pure</tt>, <tt>const</tt>, <tt>nothrow</tt>,
<tt>malloc</tt>, <tt>no_instrument_function</tt>, <tt>cdecl</tt><br>
@@ -549,7 +537,7 @@ or arrays as values.</li>
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html#Case%20Ranges">Case Ranges</a>: `case 1 ... 9' and such.</li>
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Mixed-Declarations.html#Mixed%20Declarations">Mixed Declarations</a>: Mixing declarations and code.</li>
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Function-Prototypes.html#Function%20Prototypes">Function Prototypes</a>: Prototype declarations and old-style definitions.</li>
- <li><a href="http://gcc.gnu.org/onlinedocs/gcc/C---Comments.html#C++%20Comments">C++ Comments</a>: C++ comments are recognized.</li>
+ <li><a href="http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Comments.html#C_002b_002b-Comments">C++ Comments</a>: C++ comments are recognized.</li>
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Dollar-Signs.html#Dollar%20Signs">Dollar Signs</a>: Dollar sign is allowed in identifiers.</li>
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Character-Escapes.html#Character%20Escapes">Character Escapes</a>: <code>\e</code> stands for the character &lt;ESC&gt;.</li>
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Alignment.html#Alignment">Alignment</a>: Inquiring about the alignment of a type or variable.</li>
@@ -576,10 +564,9 @@ lists, please let us know (also including whether or not they work).</p>
<div class="doc_text">
-<p>For this release, the C++ front-end is considered to be fully functional but
-has not been tested as thoroughly as the C front-end. It has been tested and
-works for a number of non-trivial programs, but there may be lurking bugs.
-Please report any bugs or problems.</p>
+<p>For this release, the C++ front-end is considered to be fully
+tested and works for a number of non-trivial programs, including LLVM
+itself.</p>
</div>
@@ -691,10 +678,6 @@ Analysis rules. As such, special options may be necessary to compile the code
(for example, GCC requires the <tt>-fno-strict-aliasing</tt> option). This
problem probably cannot be fixed.</li>
-<li><a href="http://llvm.cs.uiuc.edu/PR33">Initializers for global variables</a>
-cannot include special floating point numbers like Not-A-Number or
-Infinity.</li>
-
<li><a href="http://llvm.cs.uiuc.edu/PR56">Zero arg vararg functions are not
supported</a>. This should not affect LLVM produced by the C or C++
frontends.</li>
diff --git a/llvm/docs/TestingGuide.html b/llvm/docs/TestingGuide.html
index 0f3d1b020b29..b08d96c83bc5 100644
--- a/llvm/docs/TestingGuide.html
+++ b/llvm/docs/TestingGuide.html
@@ -22,15 +22,15 @@
</ul>
</li>
<li><a href="#tree">LLVM Test Suite Tree</a></li>
- <li><a href="#qmstructure">QMTest Structure</a></li>
+ <li><a href="#dgstructure">DejaGNU Structure</a></li>
<li><a href="#progstructure"><tt>llvm-test</tt> Structure</a></li>
<li><a href="#run">Running the LLVM Tests</a></li>
<li><a href="#nightly">Running the nightly tester</a></li>
</ol>
<div class="doc_author">
- <p>Written by John T. Criswell and <a
- href="http://llvm.x10sys.com/rspencer">Reid Spencer</a></p>
+ <p>Written by John T. Criswell, <a
+ href="http://llvm.x10sys.com/rspencer">Reid Spencer</a>, and Tanya Lattner</p>
</div>
<!--=========================================================================-->
@@ -55,15 +55,12 @@ and run tests.</p>
required to build LLVM, plus the following:</p>
<dl>
-<dt><a href="http://www.qmtest.com">QMTest</a></dt>
-<dd>The LLVM test suite uses QMTest to organize and run tests. <b>Note:
-you will need <a href="http://llvm.cs.uiuc.edu/qm-2.0.3.tar.gz">QMTest
-2.0.3 (source tar.gz file)</a> to be successful. The tests do not run with
-any other version.</b></dd>
-
-<dt><a href="http://www.python.org">Python</a></dt>
-<dd>You will need a Python interpreter that works with QMTest. Python will
-need zlib and SAX support enabled.</dd>
+<dt><a href="http://www.gnu.org/software/dejagnu/">DejaGNU</a></dt>
+<dd>The Feature and Regressions tests are organized and run by DejaGNU.</dd>
+<dt><a href="http://expect.nist.gov/">Expect</a></dt>
+<dd>Expect is required by DejaGNU.</dd>
+<dt><a href="http://www.tcl.tk/software/tcltk/">tcl</a></dt>
+<dd>Tcl is required by DejaGNU. </dd>
<dt><a href="http://www.netlib.org/f2c">F2C</a></dt>
<dd>For now, LLVM does not have a Fortran front-end, but using F2C, we can run
@@ -106,29 +103,20 @@ programs in C and C++ is in the <tt>llvm-test</tt> module. This module should
be checked out to the <tt>llvm/projects</tt> directory. When you
<tt>configure</tt> the <tt>llvm</tt> module, the <tt>llvm-test</tt> module
will be automatically configured. Or you can do it manually.</p>
-<p>To run all of the simple tests in LLVM, use the master Makefile in the
+<p>To run all of the simple tests in LLVM using DejaGNU, use the master Makefile in the
<tt>llvm/test</tt> directory:</p>
<pre>
% gmake -C llvm/test
</pre>
-
-<p>To run only the code fragment tests (i.e. those that do basic testing of
-LLVM), run the tests organized by QMTest:</p>
-<pre>
-% gmake -C llvm/test qmtest
-</pre>
-
-<p>To run only the basic feature tests, QMTest supports the following
-target:</p>
+or<br>
<pre>
-% gmake -C llvm/test Feature.t
+% gmake check
</pre>
-
-<p>To run only the regression tests, QMTest supports the following
-target:</p>
+<p>To run only a subdirectory of tests in llvm/test using DejaGNU (ie. Regression/Transforms). Just substitute the path to the subdirectory:</p>
<pre>
-% gmake -C llvm/test Regression.t
+% gmake -C llvm/test TESTSUITE=Regression/Transforms
</pre>
+<dd><b>Note: If you are running the tests with <tt>objdir != subdir</tt> you must have run the complete testsuite before you can specify a subdirectory.</b></dd>
<p>To run the comprehensive test suite (tests that compile and execute whole
programs), run the <tt>llvm-test</tt> tests:</p>
@@ -169,7 +157,7 @@ language front end.</p>
<p>Code fragments are not complete programs, and they are never executed to
determine correct behavior.</p>
-<p>Thes code fragment tests are located in the <tt>llvm/test/Features</tt> and
+<p>These code fragment tests are located in the <tt>llvm/test/Features</tt> and
<tt>llvm/test/Regression</tt> directories.</p>
</div>
@@ -253,87 +241,84 @@ directory are the SPEC 95 and SPEC 2000 benchmark suites. The presence and
location of these external programs is configured by the llvm-test
<tt>configure</tt> script.</p></li>
-<li><tt>llvm/test/QMTest</tt>
-<p>This directory contains the QMTest information files. Inside this directory
-are QMTest administration files and the Python code that implements the LLVM
-test and database classes.</p></li>
-
</ul>
</div>
-
<!--=========================================================================-->
-<div class="doc_section"><a name="qmstructure">QMTest Structure</a></div>
+<div class="doc_section"><a name="dgstructure">DejaGNU Structure</a></div>
<!--=========================================================================-->
<div class="doc_text">
-
-<p>The LLVM test suite is partially driven by QMTest and partially driven by GNU
-Make. Specifically, the Features and Regression tests are all driven by QMTest.
-The <tt>llvm-test</tt> module is currently driven by a set of Makefiles.</p>
-
-<p>The QMTest system needs to have several pieces of information available;
-these pieces of configuration information are known collectively as the
-"context" in QMTest parlance. Since the context for LLVM is relatively large,
-the master Makefile in llvm/test sets it for you.</p>
-
-<p>The LLVM database class makes the subdirectories of llvm/test a QMTest test
-database. For each directory that contains tests driven by QMTest, it knows
-what type of test the source file is and how to run it.</p>
-
-<p>Hence, the QMTest namespace is essentially what you see in the Feature and
-Regression directories, but there is some magic that the database class performs
-(as described below).</p>
-
-<p>The QMTest namespace is currently composed of the following tests and test
-suites:</p>
-
-<ul>
-<li>Feature
-
-<p>These are the feature tests found in the Feature directory.
-They are broken up into the following categories:</p>
-
+<p>The LLVM test suite is partially driven by DejaGNU and partially
+driven by GNU Make. Specifically, the Features and Regression tests
+are all driven by DejaGNU. The llvm-test
+module is currently driven by a set of Makefiles.</p>
+
+<p>The DejaGNU structure is very simple, but does require some
+information to be set. This information is gathered via configure and
+is written to a file, <tt>site.exp</tt> in llvm/test. The llvm/test
+Makefile does this work for you.</p>
+
+<p>In order for DejaGNU to work, each directory of tests must have a
+<tt>dg.exp</tt> file. This file is a program written in tcl that calls
+the <tt>llvm-runtests</tt> procedure on each test file. The
+llvm-runtests procedure is defined in
+<tt>llvm/test/lib/llvm-dg.exp</tt>. Any directory that contains only
+directories does not need the <tt>dg.exp</tt> file.</p>
+
+<p>In order for a test to be run, it must contain information within
+the test file on how to run the test. These are called <tt>RUN</tt>
+lines. Run lines are specified in the comments of the test program
+using the keyword <tt>RUN</tt> followed by a colon, and lastly the
+commands to execute. These commands will be executed in a bash script,
+so any bash syntax is acceptable. You can specify as many RUN lines as
+necessary. Each RUN line translates to one line in the resulting bash
+script. Below is an example of legal RUN lines in a <tt>.ll</tt>
+file:</p>
+<pre>
+; RUN: llvm-as < %s | llvm-dis > %t1
+; RUN: llvm-dis < %s.bc-13 > %t2
+; RUN: diff %t1 %t2
+</pre>
+<p>There are a couple patterns within a <tt>RUN</tt> line that the
+llvm-runtest procedure looks for and replaces with the appropriate
+syntax:</p>
<ul>
- <li>ad
- <p>Assembler/Disassembler tests. These tests verify that a piece of LLVM
- assembly language can be assembled into bytecode and then disassembled
- into the original assembly language code. It does this several times to
- ensure that assembled output can be disassembled and disassembler output
- can be assembled. It also verifies that the give assembly language file
- can be assembled correctly.</p></li>
-
- <li>opt
- <p>Optimizer tests. These tests verify that two of the optimizer passes
- completely optimize a program (i.e. after a single pass, they cannot
- optimize a program any further).</p></li>
-
- <li>mc
- <p> Machine code tests. These tests verify that the LLVM assembly
- language file can be translated into native assembly code.</p></li>
-
- <li>cc
- <p>C code tests. These tests verify that the specified LLVM assembly
- code can be converted into C source code using the C backend.</p></li>
+<dt>%p</dt>
+<dd>The path to the source directory. This is for locating
+any supporting files that are not generated by the test, but used by
+the test.</dd>
+<dt>%s</dt>
+<dd>The test file.</dd>
+
+<dt>%t</dt>
+<dd>Temporary filename: testscript.test_filename.tmp, where
+test_filename is the name of the test file. All temporary files are
+placed in the Output directory within the directory the test is
+located.</dd>
+
+<dt>%prcontext</dt>
+<dd>Path to a script that performs grep -C. Use this since not all
+platforms support grep -C.</dd>
+
+<dt>%llvmgcc</dt> <dd>Full path to the llvmgcc executable.</dd>
+<dt>%llvmgxx</dt> <dd>Full path to the llvmg++ executable.</dd>
</ul>
-<p>The LLVM database class looks at every file in the Feature directory and
-creates a fake test hierarchy containing
-<tt>Feature.&lt;testtype&gt;.&lt;testname&gt;</tt>. So, if you add an LLVM
-assembly language file to the Feature directory, it actually creates 5 new
-tests: assembler/disassembler, assembler, optimizer, machine code, and C code.
-</p></li>
-
-<li>Regression
- <p>These are the regression tests. There is one suite for each
- subdirectory of the Regression directory. If you add a new subdirectory
- there, you will need to modify, at least, the <tt>RegressionMap</tt>
- variable in <tt>QMTest/llvmdb.py</tt> so that QMTest knows how to run the
- tests in the new subdirectory.</p>
-</li>
+<p>There are also several scripts in the llvm/test/Scripts directory
+that you might find useful when writing <tt>RUN</tt> lines.</p>
+
+<p>Lastly, you can easily mark a test that is expected to fail on a
+specific platform by using the <tt>XFAIL</tt> keyword. Xfail lines are
+specified in the comments of the test program using <tt>XFAIL</tt>,
+followed by a colon, and one or more regular expressions (separated by
+a comma) that will match against the target triplet for the
+machine. You can use * to match all targets. Here is an example of an
+<tt>XFAIL</tt> line:</p>
+<pre>
+; XFAIL: darwin,sun
+</pre>
-</ul>
-
</div>
<!--=========================================================================-->
@@ -364,7 +349,33 @@ designed for internal LLVM research and will not work outside of the LLVM
research group. They may still be valuable, however, as a guide to writing your
own TEST Makefile for any optimization or analysis passes that you develop with
LLVM.</p>
-
+
+<p>Note, when configuring the <tt>llvm-test</tt> module, you might want to
+specify the following configuration options:</p>
+<dl>
+ <dt><i>--enable-spec2000</i>
+ <dt><i>--enable-spec2000=&lt;<tt>directory</tt>&gt;</i>
+ <dd>
+ Enable the use of SPEC2000 when testing LLVM. This is disabled by default
+ (unless <tt>configure</tt> finds SPEC2000 installed). By specifying
+ <tt>directory</tt>, you can tell configure where to find the SPEC2000
+ benchmarks. If <tt>directory</tt> is left unspecified, <tt>configure</tt>
+ uses the default value
+ <tt>/home/vadve/shared/benchmarks/speccpu2000/benchspec</tt>.
+ <p>
+ <dt><i>--enable-spec95</i>
+ <dt><i>--enable-spec95=&lt;<tt>directory</tt>&gt;</i>
+ <dd>
+ Enable the use of SPEC95 when testing LLVM. It is similar to the
+ <i>--enable-spec2000</i> option.
+ <p>
+ <dt><i>--enable-povray</i>
+ <dt><i>--enable-povray=&lt;<tt>directory</tt>&gt;</i>
+ <dd>
+ Enable the use of Povray as an external test. Versions of Povray written
+ in C should work. This option is similar to the <i>--enable-spec2000</i>
+ option.
+</dl>
</div>
<!--=========================================================================-->
@@ -377,18 +388,18 @@ LLVM.</p>
<i>are not</i> executed inside of the LLVM source tree. This is because the
test suite creates temporary files during execution.</p>
-<p>The master Makefile in llvm/test is capable of running only the QMTest driven
+<p>The master Makefile in llvm/test is capable of running only the DejaGNU driven
tests. By default, it will run all of these tests.</p>
-<p>To run only the QMTest driven tests, run <tt>gmake qmtest</tt> at the
-command line in llvm/tests. To run a specific qmtest, suffix the test name with
-".t" when running gmake.</p>
+<p>To run only the DejaGNU driven tests, run <tt>gmake</tt> at the
+command line in llvm/tests. To run a specific directory of tests, specify the TESTSUITE.
+</p>
-<p>For example, to run the Regression.LLC tests, type
-<tt>gmake Regression.LLC.t</tt> in <tt>llvm/tests</tt>.</p>
+<p>For example, to run the Regression tests, type
+<tt>gmake TESTSUITE=Regression</tt> in <tt>llvm/tests</tt>.</p>
<p>Note that there are no Makefiles in <tt>llvm/test/Features</tt> and
-<tt>llvm/test/Regression</tt>. You must use QMTest from the <tt>llvm/test</tt>
+<tt>llvm/test/Regression</tt>. You must use DejaGNU from the <tt>llvm/test</tt>
directory to run them.</p>
<p>To run the <tt>llvm-test</tt> suite, you need to use the following steps:
@@ -430,7 +441,7 @@ output and standard error. You can redirect these results to a file if you
choose.</p>
<p>Some tests are known to fail. Some are bugs that we have not fixed yet;
-others are features that we haven't added yet (or may never add). In QMTest,
+others are features that we haven't added yet (or may never add). In DejaGNU,
the result for such tests will be XFAIL (eXpected FAILure). In this way, you
can tell the difference between an expected and unexpected failure.</p>
diff --git a/llvm/docs/WritingAnLLVMPass.html b/llvm/docs/WritingAnLLVMPass.html
index 7b90db352bc1..65a1e0e30cb9 100644
--- a/llvm/docs/WritingAnLLVMPass.html
+++ b/llvm/docs/WritingAnLLVMPass.html
@@ -1212,7 +1212,7 @@ pass is the default implementation for the interface.</p>
<div class="doc_text">
<p>The <a
-href="http:://llvm.cs.uiuc.edu/doxygen/Statistic_8h-source.html"><tt>Statistic</tt></a>
+href="http://llvm.cs.uiuc.edu/doxygen/Statistic_8h-source.html"><tt>Statistic</tt></a>
class, is designed to be an easy way to expose various success
metrics from passes. These statistics are printed at the end of a
run, when the -stats command line option is enabled on the command
diff --git a/llvm/lib/Linker/LinkItems.cpp b/llvm/lib/Linker/LinkItems.cpp
new file mode 100644
index 000000000000..d055a4d0285f
--- /dev/null
+++ b/llvm/lib/Linker/LinkItems.cpp
@@ -0,0 +1,159 @@
+//===- lib/Linker/LinkItems.cpp - Link LLVM objects and libraries ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains routines to handle linking together LLVM bytecode files,
+// and to handle annoying things like static libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Linker.h"
+#include "llvm/Module.h"
+#include "llvm/ModuleProvider.h"
+#include "llvm/PassManager.h"
+#include "llvm/ADT/SetOperations.h"
+#include "llvm/Bytecode/Reader.h"
+#include "llvm/Bytecode/Archive.h"
+#include "llvm/Bytecode/WriteBytecodePass.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/System/Signals.h"
+#include "llvm/Support/SystemUtils.h"
+#include <algorithm>
+#include <fstream>
+#include <memory>
+#include <set>
+using namespace llvm;
+
+static bool
+LinkOneLibrary(const char*progname, Module* HeadModule,
+ const std::string& Lib,
+ const std::vector<std::string>& LibPaths,
+ bool Verbose, bool Native) {
+
+ // String in which to receive error messages.
+ std::string ErrorMessage;
+
+ // Determine where this library lives.
+ std::string Pathname = FindLib(Lib, LibPaths);
+ if (Pathname.empty()) {
+ // If the pathname does not exist, then simply return if we're doing a
+ // native link and give a warning if we're doing a bytecode link.
+ if (!Native) {
+ std::cerr << progname << ": warning: Cannot find library '"
+ << Lib << "'\n";
+ return false;
+ }
+ }
+
+ // A user may specify an ar archive without -l, perhaps because it
+ // is not installed as a library. Detect that and link the library.
+ if (IsArchive(Pathname)) {
+ if (Verbose)
+ std::cerr << "Trying to link archive '" << Pathname << "' (-l"
+ << Lib << ")\n";
+
+ if (LinkInArchive(HeadModule, Pathname, &ErrorMessage, Verbose)) {
+ std::cerr << progname << ": " << ErrorMessage
+ << ": Error linking in archive '" << Pathname << "' (-l"
+ << Lib << ")\n";
+ return true;
+ }
+ } else {
+ std::cerr << progname << ": WARNING: Supposed library -l"
+ << Lib << " isn't a library.\n";
+ }
+ return false;
+}
+
+// LinkItems - preserve link order for an arbitrary set of linkage items.
+Module*
+llvm::LinkItems(const char *progname, const LinkItemList& Items,
+ const std::vector<std::string>& LibPaths,
+ bool Verbose, bool Native) {
+
+ // Construct the HeadModule to contain the result of the linkage
+ std::auto_ptr<Module> HeadModule(new Module(progname));
+
+ // Construct a mutable path list we can add paths to. This list will always
+ // have LLVM_LIB_SEARCH_PATH at the end so we place it there now.
+ std::vector<std::string> MyLibPaths(LibPaths);
+ MyLibPaths.insert(MyLibPaths.begin(),".");
+ char* SearchPath = getenv("LLVM_LIB_SEARCH_PATH");
+ if (SearchPath)
+ MyLibPaths.push_back(SearchPath);
+
+ // For each linkage item ...
+ for (LinkItemList::const_iterator I = Items.begin(), E = Items.end();
+ I != E; ++I) {
+ if (I->second) {
+ // Link in the library suggested.
+ if (LinkOneLibrary(progname,HeadModule.get(),I->first,MyLibPaths,
+ Verbose,Native))
+ return 0;
+ } else {
+ std::vector<std::string> Files;
+ Files.push_back(I->first);
+ if (LinkFiles(progname,HeadModule.get(),Files,Verbose))
+ return 0;
+ }
+ }
+
+ // At this point we have processed all the link items provided to us. Since
+ // we have an aggregated module at this point, the dependent libraries in
+ // that module should also be aggregated with duplicates eliminated. This is
+ // now the time to process the dependent libraries to resolve any remaining
+ // symbols.
+ const Module::LibraryListType& DepLibs = HeadModule->getLibraries();
+ for (Module::LibraryListType::const_iterator I = DepLibs.begin(),
+ E = DepLibs.end(); I != E; ++I) {
+ if(LinkOneLibrary(progname,HeadModule.get(),*I,MyLibPaths,Verbose,Native))
+ return 0;
+ }
+
+ return HeadModule.release();
+}
+
+// BuildLinkItems -- This function
+void llvm::BuildLinkItems(
+ LinkItemList& Items,
+ const cl::list<std::string>& Files,
+ const cl::list<std::string>& Libraries) {
+
+ // Build the list of linkage items for LinkItems.
+
+ cl::list<std::string>::const_iterator fileIt = Files.begin();
+ cl::list<std::string>::const_iterator libIt = Libraries.begin();
+
+ int libPos = -1, filePos = -1;
+ while ( 1 ) {
+ if (libIt != Libraries.end())
+ libPos = Libraries.getPosition(libIt - Libraries.begin());
+ else
+ libPos = -1;
+ if (fileIt != Files.end())
+ filePos = Files.getPosition(fileIt - Files.begin());
+ else
+ filePos = -1;
+
+ if (filePos != -1 && (libPos == -1 || filePos < libPos)) {
+ // Add a source file
+ Items.push_back(std::make_pair(*fileIt++, false));
+ } else if (libPos != -1 && (filePos == -1 || libPos < filePos)) {
+ // Add a library
+ Items.push_back(std::make_pair(*libIt++, true));
+ } else {
+ break; // we're done with the list
+ }
+ }
+}
diff --git a/llvm/lib/Target/SparcV8/DelaySlotFiller.cpp b/llvm/lib/Target/SparcV8/DelaySlotFiller.cpp
deleted file mode 100644
index 09937dea26b7..000000000000
--- a/llvm/lib/Target/SparcV8/DelaySlotFiller.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-//===-- DelaySlotFiller.cpp - SparcV8 delay slot filler -------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is a simple local pass that fills delay slots with NOPs.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SparcV8.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/ADT/Statistic.h"
-
-using namespace llvm;
-
-namespace {
- Statistic<> FilledSlots ("delayslotfiller", "Num. of delay slots filled");
-
- struct Filler : public MachineFunctionPass {
- /// Target machine description which we query for reg. names, data
- /// layout, etc.
- ///
- TargetMachine &TM;
- const TargetInstrInfo *TII;
-
- Filler (TargetMachine &tm) : TM (tm), TII (tm.getInstrInfo ()) { }
-
- virtual const char *getPassName () const {
- return "SparcV8 Delay Slot Filler";
- }
-
- bool runOnMachineBasicBlock (MachineBasicBlock &MBB);
- bool runOnMachineFunction (MachineFunction &F) {
- bool Changed = false;
- for (MachineFunction::iterator FI = F.begin (), FE = F.end ();
- FI != FE; ++FI)
- Changed |= runOnMachineBasicBlock (*FI);
- return Changed;
- }
-
- };
-} // end of anonymous namespace
-
-/// createSparcV8DelaySlotFillerPass - Returns a pass that fills in delay
-/// slots in SparcV8 MachineFunctions
-///
-FunctionPass *llvm::createSparcV8DelaySlotFillerPass (TargetMachine &tm) {
- return new Filler (tm);
-}
-
-/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
-/// Currently, we fill delay slots with NOPs. We assume there is only one
-/// delay slot per delayed instruction.
-///
-bool Filler::runOnMachineBasicBlock (MachineBasicBlock &MBB) {
- bool Changed = false;
- for (MachineBasicBlock::iterator I = MBB.begin (); I != MBB.end (); ++I)
- if (TII->hasDelaySlot (I->getOpcode ())) {
- MachineBasicBlock::iterator J = I;
- ++J;
- BuildMI (MBB, J, V8::NOP, 0);
- ++FilledSlots;
- Changed = true;
- }
- return Changed;
-}
diff --git a/llvm/lib/Target/SparcV8/FPMover.cpp b/llvm/lib/Target/SparcV8/FPMover.cpp
deleted file mode 100644
index 6450f47f2572..000000000000
--- a/llvm/lib/Target/SparcV8/FPMover.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-//===-- FPMover.cpp - SparcV8 double-precision floating point move fixer --===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Turns FpMOVD instructions into FMOVS pairs after regalloc.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SparcV8.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/Debug.h"
-
-using namespace llvm;
-
-namespace {
- Statistic<> NumFpMOVDs ("fpmover", "# FpMOVD instructions translated");
- Statistic<> SkippedFpMOVDs ("fpmover", "# FpMOVD instructions skipped");
-
- struct FPMover : public MachineFunctionPass {
- /// Target machine description which we query for reg. names, data
- /// layout, etc.
- ///
- TargetMachine &TM;
-
- FPMover (TargetMachine &tm) : TM (tm) { }
-
- virtual const char *getPassName () const {
- return "SparcV8 Double-FP Move Fixer";
- }
-
- bool runOnMachineBasicBlock (MachineBasicBlock &MBB);
- bool runOnMachineFunction (MachineFunction &F) {
- bool Changed = false;
- for (MachineFunction::iterator FI = F.begin (), FE = F.end ();
- FI != FE; ++FI)
- Changed |= runOnMachineBasicBlock (*FI);
- return Changed;
- }
-
- };
-} // end of anonymous namespace
-
-/// createSparcV8FPMoverPass - Returns a pass that turns FpMOVD
-/// instructions into FMOVS instructions
-///
-FunctionPass *llvm::createSparcV8FPMoverPass (TargetMachine &tm) {
- return new FPMover (tm);
-}
-
-static void doubleToSingleRegPair(unsigned doubleReg, unsigned &singleReg1, unsigned &singleReg2) {
- const unsigned EvenHalvesOfPairs[] = { V8::F0, V8::F2, V8::F4, V8::F6, V8::F8, V8::F10, V8::F12, V8::F14, V8::F16, V8::F18, V8::F20, V8::F22, V8::F24, V8::F26, V8::F28, V8::F30 };
- const unsigned OddHalvesOfPairs[] = { V8::F1, V8::F3, V8::F5, V8::F7, V8::F9, V8::F11, V8::F13, V8::F15, V8::F17, V8::F19, V8::F21, V8::F23, V8::F25, V8::F27, V8::F29, V8::F31 };
- const unsigned DoubleRegsInOrder[] = { V8::D0, V8::D1, V8::D2, V8::D3, V8::D4, V8::D5, V8::D6, V8::D7, V8::D8, V8::D9, V8::D10, V8::D11, V8::D12, V8::D13, V8::D14, V8::D15 };
- for (unsigned i = 0; i < sizeof(DoubleRegsInOrder)/sizeof(unsigned); ++i)
- if (DoubleRegsInOrder[i] == doubleReg) {
- singleReg1 = EvenHalvesOfPairs[i];
- singleReg2 = OddHalvesOfPairs[i];
- return;
- }
- assert (0 && "Can't find reg");
-}
-
-/// runOnMachineBasicBlock - Fixup FpMOVD instructions in this MBB.
-///
-bool FPMover::runOnMachineBasicBlock (MachineBasicBlock &MBB) {
- bool Changed = false;
- for (MachineBasicBlock::iterator I = MBB.begin (); I != MBB.end (); ++I)
- if (V8::FpMOVD == I->getOpcode ()) {
- unsigned NewSrcReg0, NewSrcReg1, NewDestReg0, NewDestReg1;
- doubleToSingleRegPair (I->getOperand (0).getReg (), NewDestReg0,
- NewDestReg1);
- doubleToSingleRegPair (I->getOperand (1).getReg (), NewSrcReg0,
- NewSrcReg1);
- MachineBasicBlock::iterator J = I;
- ++J;
- if (!(NewDestReg0 == NewSrcReg0 && NewDestReg1 == NewSrcReg1)) {
- I->setOpcode (V8::FMOVS);
- I->SetMachineOperandReg (0, NewDestReg0);
- I->SetMachineOperandReg (1, NewSrcReg0);
- DEBUG (std::cerr << "FPMover: new dest reg. is: " << NewDestReg0
- << "; modified instr is: " << *I);
- // Insert copy for the other half of the double:
- MachineInstr *MI2 =
- BuildMI (MBB, J, V8::FMOVS, 1, NewDestReg1).addReg (NewSrcReg1);
- DEBUG (std::cerr << "FPMover: new dest reg. is " << NewDestReg1
- << "; inserted instr is: " << *MI2);
- ++NumFpMOVDs;
- } else {
- MBB.erase (I);
- ++SkippedFpMOVDs;
- }
- I = J;
- Changed = true;
- }
- return Changed;
-}
diff --git a/llvm/lib/Target/SparcV8/Makefile b/llvm/lib/Target/SparcV8/Makefile
deleted file mode 100644
index f2f8c5f8ce6a..000000000000
--- a/llvm/lib/Target/SparcV8/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-##===- lib/Target/Sparc/V8/Makefile ------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file was developed by the LLVM research group and is distributed under
-# the University of Illinois Open Source License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMSparcV8
-TARGET = SparcV8
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = SparcV8GenRegisterInfo.h.inc SparcV8GenRegisterNames.inc \
- SparcV8GenRegisterInfo.inc SparcV8GenInstrNames.inc \
- SparcV8GenInstrInfo.inc SparcV8GenCodeEmitter.inc
-
-include $(LEVEL)/Makefile.common
-
diff --git a/llvm/lib/Target/SparcV8/README.txt b/llvm/lib/Target/SparcV8/README.txt
deleted file mode 100644
index ba7f1454d113..000000000000
--- a/llvm/lib/Target/SparcV8/README.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-
-SparcV8 backend skeleton
-------------------------
-
-This directory houses a 32-bit SPARC V8 backend employing an expander-based
-instruction selector. It is not yet functionally complete. Watch
-this space for more news coming soon!
-
-Current expected test failures
-------------------------------
-
-The SparcV8 backend works on many simple C++ SingleSource codes. Here
-are the known SingleSource failures:
-
- UnitTests/SetjmpLongjmp/C++/SimpleC++Test
- Regression/C++/EH/exception_spec_test
- Regression/C++/EH/throw_rethrow_test
- Benchmarks/Shootout-C++/moments
- Benchmarks/Shootout-C++/random
-
-Here are some known MultiSource test failures - this is probably not a
-complete list right now.
-
- burg siod lambda make_dparser hbd treecc hexxagon fhourstones
- bisect testtrie eks imp power anagram bc distray
-
-To-do
------
-
-* support shifts on longs
-* support casting 64-bit integers to FP types
-* support FP rem
-
-$Date$
-
diff --git a/llvm/lib/Target/SparcV8/SparcV8.h b/llvm/lib/Target/SparcV8/SparcV8.h
deleted file mode 100644
index 5b820708ac7b..000000000000
--- a/llvm/lib/Target/SparcV8/SparcV8.h
+++ /dev/null
@@ -1,42 +0,0 @@
-//===-- SparcV8.h - Top-level interface for SparcV8 representation -*- C++ -*-//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the entry points for global functions defined in the LLVM
-// SparcV8 back-end.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef TARGET_SPARCV8_H
-#define TARGET_SPARCV8_H
-
-#include <iosfwd>
-
-namespace llvm {
-
- class FunctionPass;
- class TargetMachine;
-
- FunctionPass *createSparcV8SimpleInstructionSelector(TargetMachine &TM);
- FunctionPass *createSparcV8CodePrinterPass(std::ostream &OS,
- TargetMachine &TM);
- FunctionPass *createSparcV8DelaySlotFillerPass(TargetMachine &TM);
- FunctionPass *createSparcV8FPMoverPass(TargetMachine &TM);
-
-} // end namespace llvm;
-
-// Defines symbolic names for SparcV8 registers. This defines a mapping from
-// register name to register number.
-//
-#include "SparcV8GenRegisterNames.inc"
-
-// Defines symbolic names for the SparcV8 instructions.
-//
-#include "SparcV8GenInstrNames.inc"
-
-#endif
diff --git a/llvm/lib/Target/SparcV8/SparcV8.td b/llvm/lib/Target/SparcV8/SparcV8.td
deleted file mode 100644
index 892b9cc350a4..000000000000
--- a/llvm/lib/Target/SparcV8/SparcV8.td
+++ /dev/null
@@ -1,52 +0,0 @@
-//===- SparcV8.td - Describe the SparcV8 Target Machine ---------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// Target-independent interfaces which we are implementing
-//===----------------------------------------------------------------------===//
-
-include "../../Target.td"
-
-//===----------------------------------------------------------------------===//
-// Register File Description
-//===----------------------------------------------------------------------===//
-
-include "SparcV8RegisterInfo.td"
-
-//===----------------------------------------------------------------------===//
-// Instruction Descriptions
-//===----------------------------------------------------------------------===//
-
-include "SparcV8InstrInfo.td"
-
-def SparcV8InstrInfo : InstrInfo {
- let PHIInst = PHI;
-
- // Define how we want to layout our target-specific information field.
- let TSFlagsFields = [];
- let TSFlagsShifts = [];
-}
-
-//===----------------------------------------------------------------------===//
-// Declare the target which we are implementing
-//===----------------------------------------------------------------------===//
-
-def SparcV8 : Target {
- // Pointers are 32-bits in size.
- let PointerType = i32;
-
- // FIXME: Specify callee-saved registers
- let CalleeSavedRegisters = [];
-
- // Pull in Instruction Info:
- let InstructionSet = SparcV8InstrInfo;
-}
diff --git a/llvm/lib/Target/SparcV8/SparcV8AsmPrinter.cpp b/llvm/lib/Target/SparcV8/SparcV8AsmPrinter.cpp
deleted file mode 100644
index 80fc85b1400b..000000000000
--- a/llvm/lib/Target/SparcV8/SparcV8AsmPrinter.cpp
+++ /dev/null
@@ -1,645 +0,0 @@
-//===-- SparcV8AsmPrinter.cpp - SparcV8 LLVM assembly writer --------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains a printer that converts from our internal representation
-// of machine-dependent LLVM code to GAS-format Sparc V8 assembly language.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SparcV8.h"
-#include "SparcV8InstrInfo.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/Assembly/Writer.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Support/Mangler.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/CommandLine.h"
-#include <cctype>
-using namespace llvm;
-
-namespace {
- Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
-
- struct V8Printer : public MachineFunctionPass {
- /// Output stream on which we're printing assembly code.
- ///
- std::ostream &O;
-
- /// Target machine description which we query for reg. names, data
- /// layout, etc.
- ///
- TargetMachine &TM;
-
- /// Name-mangler for global names.
- ///
- Mangler *Mang;
-
- V8Printer(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) { }
-
- /// We name each basic block in a Function with a unique number, so
- /// that we can consistently refer to them later. This is cleared
- /// at the beginning of each call to runOnMachineFunction().
- ///
- typedef std::map<const Value *, unsigned> ValueMapTy;
- ValueMapTy NumberForBB;
-
- /// Cache of mangled name for current function. This is
- /// recalculated at the beginning of each call to
- /// runOnMachineFunction().
- ///
- std::string CurrentFnName;
-
- virtual const char *getPassName() const {
- return "SparcV8 Assembly Printer";
- }
-
- void emitConstantValueOnly(const Constant *CV);
- void emitGlobalConstant(const Constant *CV);
- void printConstantPool(MachineConstantPool *MCP);
- void printOperand(const MachineInstr *MI, int opNum);
- void printBaseOffsetPair (const MachineInstr *MI, int i, bool brackets=true);
- void printMachineInstruction(const MachineInstr *MI);
- bool runOnMachineFunction(MachineFunction &F);
- bool doInitialization(Module &M);
- bool doFinalization(Module &M);
- };
-} // end of anonymous namespace
-
-/// createSparcV8CodePrinterPass - Returns a pass that prints the SparcV8
-/// assembly code for a MachineFunction to the given output stream,
-/// using the given target machine description. This should work
-/// regardless of whether the function is in SSA form.
-///
-FunctionPass *llvm::createSparcV8CodePrinterPass (std::ostream &o,
- TargetMachine &tm) {
- return new V8Printer(o, tm);
-}
-
-/// toOctal - Convert the low order bits of X into an octal digit.
-///
-static inline char toOctal(int X) {
- return (X&7)+'0';
-}
-
-/// getAsCString - Return the specified array as a C compatible
-/// string, only if the predicate isStringCompatible is true.
-///
-static void printAsCString(std::ostream &O, const ConstantArray *CVA) {
- assert(CVA->isString() && "Array is not string compatible!");
-
- O << "\"";
- for (unsigned i = 0; i != CVA->getNumOperands(); ++i) {
- unsigned char C = cast<ConstantInt>(CVA->getOperand(i))->getRawValue();
-
- if (C == '"') {
- O << "\\\"";
- } else if (C == '\\') {
- O << "\\\\";
- } else if (isprint(C)) {
- O << C;
- } else {
- switch(C) {
- case '\b': O << "\\b"; break;
- case '\f': O << "\\f"; break;
- case '\n': O << "\\n"; break;
- case '\r': O << "\\r"; break;
- case '\t': O << "\\t"; break;
- default:
- O << '\\';
- O << toOctal(C >> 6);
- O << toOctal(C >> 3);
- O << toOctal(C >> 0);
- break;
- }
- }
- }
- O << "\"";
-}
-
-// Print out the specified constant, without a storage class. Only the
-// constants valid in constant expressions can occur here.
-void V8Printer::emitConstantValueOnly(const Constant *CV) {
- if (CV->isNullValue() || isa<UndefValue> (CV))
- O << "0";
- else if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
- assert(CB == ConstantBool::True);
- O << "1";
- } else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV))
- if (((CI->getValue() << 32) >> 32) == CI->getValue())
- O << CI->getValue();
- else
- O << (unsigned long long)CI->getValue();
- else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV))
- O << CI->getValue();
- else if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
- // This is a constant address for a global variable or function. Use the
- // name of the variable or function as the address value.
- O << Mang->getValueName(GV);
- else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
- const TargetData &TD = TM.getTargetData();
- switch(CE->getOpcode()) {
- case Instruction::GetElementPtr: {
- // generate a symbolic expression for the byte address
- const Constant *ptrVal = CE->getOperand(0);
- std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end());
- if (unsigned Offset = TD.getIndexedOffset(ptrVal->getType(), idxVec)) {
- O << "(";
- emitConstantValueOnly(ptrVal);
- O << ") + " << Offset;
- } else {
- emitConstantValueOnly(ptrVal);
- }
- break;
- }
- case Instruction::Cast: {
- // Support only non-converting or widening casts for now, that is, ones
- // that do not involve a change in value. This assertion is really gross,
- // and may not even be a complete check.
- Constant *Op = CE->getOperand(0);
- const Type *OpTy = Op->getType(), *Ty = CE->getType();
-
- // Pointers on ILP32 machines can be losslessly converted back and
- // forth into 32-bit or wider integers, regardless of signedness.
- assert(((isa<PointerType>(OpTy)
- && (Ty == Type::LongTy || Ty == Type::ULongTy
- || Ty == Type::IntTy || Ty == Type::UIntTy))
- || (isa<PointerType>(Ty)
- && (OpTy == Type::LongTy || OpTy == Type::ULongTy
- || OpTy == Type::IntTy || OpTy == Type::UIntTy))
- || (((TD.getTypeSize(Ty) >= TD.getTypeSize(OpTy))
- && OpTy->isLosslesslyConvertibleTo(Ty))))
- && "FIXME: Don't yet support this kind of constant cast expr");
- O << "(";
- emitConstantValueOnly(Op);
- O << ")";
- break;
- }
- case Instruction::Add:
- O << "(";
- emitConstantValueOnly(CE->getOperand(0));
- O << ") + (";
- emitConstantValueOnly(CE->getOperand(1));
- O << ")";
- break;
- default:
- assert(0 && "Unsupported operator!");
- }
- } else {
- assert(0 && "Unknown constant value!");
- }
-}
-
-// Print a constant value or values, with the appropriate storage class as a
-// prefix.
-void V8Printer::emitGlobalConstant(const Constant *CV) {
- const TargetData &TD = TM.getTargetData();
-
- if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
- if (CVA->isString()) {
- O << "\t.ascii\t";
- printAsCString(O, CVA);
- O << "\n";
- } else { // Not a string. Print the values in successive locations
- for (unsigned i = 0, e = CVA->getNumOperands(); i != e; i++)
- emitGlobalConstant(CVA->getOperand(i));
- }
- return;
- } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
- // Print the fields in successive locations. Pad to align if needed!
- const StructLayout *cvsLayout = TD.getStructLayout(CVS->getType());
- unsigned sizeSoFar = 0;
- for (unsigned i = 0, e = CVS->getNumOperands(); i != e; i++) {
- const Constant* field = CVS->getOperand(i);
-
- // Check if padding is needed and insert one or more 0s.
- unsigned fieldSize = TD.getTypeSize(field->getType());
- unsigned padSize = ((i == e-1? cvsLayout->StructSize
- : cvsLayout->MemberOffsets[i+1])
- - cvsLayout->MemberOffsets[i]) - fieldSize;
- sizeSoFar += fieldSize + padSize;
-
- // Now print the actual field value
- emitGlobalConstant(field);
-
- // Insert the field padding unless it's zero bytes...
- if (padSize)
- O << "\t.skip\t " << padSize << "\n";
- }
- assert(sizeSoFar == cvsLayout->StructSize &&
- "Layout of constant struct may be incorrect!");
- return;
- } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
- // FP Constants are printed as integer constants to avoid losing
- // precision...
- double Val = CFP->getValue();
- switch (CFP->getType()->getTypeID()) {
- default: assert(0 && "Unknown floating point type!");
- case Type::FloatTyID: {
- union FU { // Abide by C TBAA rules
- float FVal;
- unsigned UVal;
- } U;
- U.FVal = Val;
- O << ".long\t" << U.UVal << "\t! float " << Val << "\n";
- return;
- }
- case Type::DoubleTyID: {
- union DU { // Abide by C TBAA rules
- double FVal;
- uint64_t UVal;
- } U;
- U.FVal = Val;
- O << ".word\t0x" << std::hex << (U.UVal >> 32) << std::dec << "\t! double " << Val << "\n";
- O << ".word\t0x" << std::hex << (U.UVal & 0xffffffffUL) << std::dec << "\t! double " << Val << "\n";
- return;
- }
- }
- } else if (isa<UndefValue> (CV)) {
- unsigned size = TD.getTypeSize (CV->getType ());
- O << "\t.skip\t " << size << "\n";
- return;
- } else if (isa<ConstantAggregateZero> (CV)) {
- unsigned size = TD.getTypeSize (CV->getType ());
- for (unsigned i = 0; i < size; ++i)
- O << "\t.byte 0\n";
- return;
- }
-
- const Type *type = CV->getType();
- O << "\t";
- switch (type->getTypeID()) {
- case Type::BoolTyID: case Type::UByteTyID: case Type::SByteTyID:
- O << ".byte";
- break;
- case Type::UShortTyID: case Type::ShortTyID:
- O << ".word";
- break;
- case Type::FloatTyID: case Type::PointerTyID:
- case Type::UIntTyID: case Type::IntTyID:
- O << ".long";
- break;
- case Type::DoubleTyID:
- case Type::ULongTyID: case Type::LongTyID:
- O << ".quad";
- break;
- default:
- assert (0 && "Can't handle printing this type of thing");
- break;
- }
- O << "\t";
- emitConstantValueOnly(CV);
- O << "\n";
-}
-
-/// printConstantPool - Print to the current output stream assembly
-/// representations of the constants in the constant pool MCP. This is
-/// used to print out constants which have been "spilled to memory" by
-/// the code generator.
-///
-void V8Printer::printConstantPool(MachineConstantPool *MCP) {
- const std::vector<Constant*> &CP = MCP->getConstants();
- const TargetData &TD = TM.getTargetData();
-
- if (CP.empty()) return;
-
- for (unsigned i = 0, e = CP.size(); i != e; ++i) {
- O << "\t.section \".rodata\"\n";
- O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType())
- << "\n";
- O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t!"
- << *CP[i] << "\n";
- emitGlobalConstant(CP[i]);
- }
-}
-
-/// runOnMachineFunction - This uses the printMachineInstruction()
-/// method to print assembly for each instruction.
-///
-bool V8Printer::runOnMachineFunction(MachineFunction &MF) {
- // BBNumber is used here so that a given Printer will never give two
- // BBs the same name. (If you have a better way, please let me know!)
- static unsigned BBNumber = 0;
-
- O << "\n\n";
- // What's my mangled name?
- CurrentFnName = Mang->getValueName(MF.getFunction());
-
- // Print out constants referenced by the function
- printConstantPool(MF.getConstantPool());
-
- // Print out labels for the function.
- O << "\t.text\n";
- O << "\t.align 16\n";
- O << "\t.globl\t" << CurrentFnName << "\n";
- O << "\t.type\t" << CurrentFnName << ", #function\n";
- O << CurrentFnName << ":\n";
-
- // Number each basic block so that we can consistently refer to them
- // in PC-relative references.
- NumberForBB.clear();
- for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
- I != E; ++I) {
- NumberForBB[I->getBasicBlock()] = BBNumber++;
- }
-
- // Print out code for the function.
- for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
- I != E; ++I) {
- // Print a label for the basic block.
- O << ".LBB" << Mang->getValueName(MF.getFunction ())
- << "_" << I->getNumber () << ":\t! "
- << I->getBasicBlock ()->getName () << "\n";
- for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
- II != E; ++II) {
- // Print the assembly for the instruction.
- O << "\t";
- printMachineInstruction(II);
- }
- }
-
- // We didn't modify anything.
- return false;
-}
-
-void V8Printer::printOperand(const MachineInstr *MI, int opNum) {
- const MachineOperand &MO = MI->getOperand (opNum);
- const MRegisterInfo &RI = *TM.getRegisterInfo();
- bool CloseParen = false;
- if (MI->getOpcode() == V8::SETHIi && !MO.isRegister() && !MO.isImmediate()) {
- O << "%hi(";
- CloseParen = true;
- } else if (MI->getOpcode() ==V8::ORri &&!MO.isRegister() &&!MO.isImmediate())
- {
- O << "%lo(";
- CloseParen = true;
- }
- switch (MO.getType()) {
- case MachineOperand::MO_VirtualRegister:
- if (Value *V = MO.getVRegValueOrNull()) {
- O << "<" << V->getName() << ">";
- break;
- }
- // FALLTHROUGH
- case MachineOperand::MO_MachineRegister:
- if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
- O << "%" << LowercaseString (RI.get(MO.getReg()).Name);
- else
- O << "%reg" << MO.getReg();
- break;
-
- case MachineOperand::MO_SignExtendedImmed:
- case MachineOperand::MO_UnextendedImmed:
- O << (int)MO.getImmedValue();
- break;
- case MachineOperand::MO_MachineBasicBlock: {
- MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
- O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
- << "_" << MBBOp->getNumber () << "\t! "
- << MBBOp->getBasicBlock ()->getName ();
- return;
- }
- case MachineOperand::MO_PCRelativeDisp:
- std::cerr << "Shouldn't use addPCDisp() when building SparcV8 MachineInstrs";
- abort ();
- return;
- case MachineOperand::MO_GlobalAddress:
- O << Mang->getValueName(MO.getGlobal());
- break;
- case MachineOperand::MO_ExternalSymbol:
- O << MO.getSymbolName();
- break;
- case MachineOperand::MO_ConstantPoolIndex:
- O << ".CPI" << CurrentFnName << "_" << MO.getConstantPoolIndex();
- break;
- default:
- O << "<unknown operand type>"; abort (); break;
- }
- if (CloseParen) O << ")";
-}
-
-static bool isLoadInstruction (const MachineInstr *MI) {
- switch (MI->getOpcode ()) {
- case V8::LDSB:
- case V8::LDSH:
- case V8::LDUB:
- case V8::LDUH:
- case V8::LD:
- case V8::LDD:
- case V8::LDFrr:
- case V8::LDFri:
- case V8::LDDFrr:
- case V8::LDDFri:
- return true;
- default:
- return false;
- }
-}
-
-static bool isStoreInstruction (const MachineInstr *MI) {
- switch (MI->getOpcode ()) {
- case V8::STB:
- case V8::STH:
- case V8::ST:
- case V8::STD:
- case V8::STFrr:
- case V8::STFri:
- case V8::STDFrr:
- case V8::STDFri:
- return true;
- default:
- return false;
- }
-}
-
-static bool isPseudoInstruction (const MachineInstr *MI) {
- switch (MI->getOpcode ()) {
- case V8::PHI:
- case V8::ADJCALLSTACKUP:
- case V8::ADJCALLSTACKDOWN:
- case V8::IMPLICIT_USE:
- case V8::IMPLICIT_DEF:
- return true;
- default:
- return false;
- }
-}
-
-/// printBaseOffsetPair - Print two consecutive operands of MI, starting at #i,
-/// which form a base + offset pair (which may have brackets around it, if
-/// brackets is true, or may be in the form base - constant, if offset is a
-/// negative constant).
-///
-void V8Printer::printBaseOffsetPair (const MachineInstr *MI, int i,
- bool brackets) {
- if (brackets) O << "[";
- printOperand (MI, i);
- if (MI->getOperand (i + 1).isImmediate()) {
- int Val = (int) MI->getOperand (i + 1).getImmedValue ();
- if (Val != 0) {
- O << ((Val >= 0) ? " + " : " - ");
- O << ((Val >= 0) ? Val : -Val);
- }
- } else {
- O << " + ";
- printOperand (MI, i + 1);
- }
- if (brackets) O << "]";
-}
-
-/// printMachineInstruction -- Print out a single SparcV8 LLVM instruction
-/// MI in GAS syntax to the current output stream.
-///
-void V8Printer::printMachineInstruction(const MachineInstr *MI) {
- unsigned Opcode = MI->getOpcode();
- const TargetInstrInfo &TII = *TM.getInstrInfo();
- const TargetInstrDescriptor &Desc = TII.get(Opcode);
-
- // If it's a pseudo-instruction, comment it out.
- if (isPseudoInstruction (MI))
- O << "! ";
-
- O << Desc.Name << " ";
-
- // Printing memory instructions is a special case.
- // for loads: %dest = op %base, offset --> op [%base + offset], %dest
- // for stores: op %base, offset, %src --> op %src, [%base + offset]
- if (isLoadInstruction (MI)) {
- printBaseOffsetPair (MI, 1);
- O << ", ";
- printOperand (MI, 0);
- O << "\n";
- return;
- } else if (isStoreInstruction (MI)) {
- printOperand (MI, 2);
- O << ", ";
- printBaseOffsetPair (MI, 0);
- O << "\n";
- return;
- } else if (Opcode == V8::JMPLrr) {
- printBaseOffsetPair (MI, 1, false);
- O << ", ";
- printOperand (MI, 0);
- O << "\n";
- return;
- }
-
- // print non-immediate, non-register-def operands
- // then print immediate operands
- // then print register-def operands.
- std::vector<int> print_order;
- for (unsigned i = 0; i < MI->getNumOperands (); ++i)
- if (!(MI->getOperand (i).isImmediate ()
- || (MI->getOperand (i).isRegister ()
- && MI->getOperand (i).isDef ())))
- print_order.push_back (i);
- for (unsigned i = 0; i < MI->getNumOperands (); ++i)
- if (MI->getOperand (i).isImmediate ())
- print_order.push_back (i);
- for (unsigned i = 0; i < MI->getNumOperands (); ++i)
- if (MI->getOperand (i).isRegister () && MI->getOperand (i).isDef ())
- print_order.push_back (i);
- for (unsigned i = 0, e = print_order.size (); i != e; ++i) {
- printOperand (MI, print_order[i]);
- if (i != (print_order.size () - 1))
- O << ", ";
- }
- O << "\n";
-}
-
-bool V8Printer::doInitialization(Module &M) {
- Mang = new Mangler(M);
- return false; // success
-}
-
-// SwitchSection - Switch to the specified section of the executable if we are
-// not already in it!
-//
-static void SwitchSection(std::ostream &OS, std::string &CurSection,
- const char *NewSection) {
- if (CurSection != NewSection) {
- CurSection = NewSection;
- if (!CurSection.empty())
- OS << "\t.section \"" << NewSection << "\"\n";
- }
-}
-
-bool V8Printer::doFinalization(Module &M) {
- const TargetData &TD = TM.getTargetData();
- std::string CurSection;
-
- // Print out module-level global variables here.
- for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
- if (I->hasInitializer()) { // External global require no code
- O << "\n\n";
- std::string name = Mang->getValueName(I);
- Constant *C = I->getInitializer();
- unsigned Size = TD.getTypeSize(C->getType());
- unsigned Align = TD.getTypeAlignment(C->getType());
-
- if (C->isNullValue() &&
- (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
- I->hasWeakLinkage() /* FIXME: Verify correct */)) {
- SwitchSection(O, CurSection, ".data");
- if (I->hasInternalLinkage())
- O << "\t.local " << name << "\n";
-
- O << "\t.comm " << name << "," << TD.getTypeSize(C->getType())
- << "," << (unsigned)TD.getTypeAlignment(C->getType());
- O << "\t\t! ";
- WriteAsOperand(O, I, true, true, &M);
- O << "\n";
- } else {
- switch (I->getLinkage()) {
- case GlobalValue::LinkOnceLinkage:
- case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak.
- // Nonnull linkonce -> weak
- O << "\t.weak " << name << "\n";
- SwitchSection(O, CurSection, "");
- O << "\t.section\t\".llvm.linkonce.d." << name << "\",\"aw\",@progbits\n";
- break;
-
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.globl " << name << "\n";
- // FALL THROUGH
- case GlobalValue::InternalLinkage:
- if (C->isNullValue())
- SwitchSection(O, CurSection, ".bss");
- else
- SwitchSection(O, CurSection, ".data");
- break;
- case GlobalValue::GhostLinkage:
- std::cerr << "Should not have any unmaterialized functions!\n";
- abort();
- }
-
- O << "\t.align " << Align << "\n";
- O << "\t.type " << name << ",#object\n";
- O << "\t.size " << name << "," << Size << "\n";
- O << name << ":\t\t\t\t! ";
- WriteAsOperand(O, I, true, true, &M);
- O << " = ";
- WriteAsOperand(O, C, false, false, &M);
- O << "\n";
- emitGlobalConstant(C);
- }
- }
-
- delete Mang;
- return false; // success
-}
diff --git a/llvm/lib/Target/SparcV8/SparcV8CodeEmitter.cpp b/llvm/lib/Target/SparcV8/SparcV8CodeEmitter.cpp
deleted file mode 100644
index 76c854bc5369..000000000000
--- a/llvm/lib/Target/SparcV8/SparcV8CodeEmitter.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-//===-- SparcV8CodeEmitter.cpp - JIT Code Emitter for SparcV8 -----*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//
-//===----------------------------------------------------------------------===//
-
-#include "SparcV8.h"
-#include "SparcV8TargetMachine.h"
-#include "llvm/Module.h"
-#include "llvm/CodeGen/MachineCodeEmitter.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Support/Debug.h"
-#include <cstdlib>
-#include <map>
-#include <vector>
-
-namespace llvm {
-
-namespace {
- class SparcV8CodeEmitter : public MachineFunctionPass {
- TargetMachine &TM;
- MachineCodeEmitter &MCE;
-
- /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
- ///
- int64_t getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
-
- // Tracks which instruction references which BasicBlock
- std::vector<std::pair<const BasicBlock*,
- std::pair<unsigned*,MachineInstr*> > > BBRefs;
- // Tracks where each BasicBlock starts
- std::map<const BasicBlock*, long> BBLocations;
-
- public:
- SparcV8CodeEmitter(TargetMachine &T, MachineCodeEmitter &M)
- : TM(T), MCE(M) {}
-
- const char *getPassName() const { return "SparcV8 Machine Code Emitter"; }
-
- /// runOnMachineFunction - emits the given MachineFunction to memory
- ///
- bool runOnMachineFunction(MachineFunction &MF);
-
- /// emitBasicBlock - emits the given MachineBasicBlock to memory
- ///
- void emitBasicBlock(MachineBasicBlock &MBB);
-
- /// emitWord - write a 32-bit word to memory at the current PC
- ///
- void emitWord(unsigned w) { MCE.emitWord(w); }
-
- /// getValueBit - return the particular bit of Val
- ///
- unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; }
-
- /// getBinaryCodeForInstr - This function, generated by the
- /// CodeEmitterGenerator using TableGen, produces the binary encoding for
- /// machine instructions.
- ///
- unsigned getBinaryCodeForInstr(MachineInstr &MI);
- };
-}
-
-/// addPassesToEmitMachineCode - Add passes to the specified pass manager to get
-/// machine code emitted. This uses a MachineCodeEmitter object to handle
-/// actually outputting the machine code and resolving things like the address
-/// of functions. This method should returns true if machine code emission is
-/// not supported.
-///
-bool SparcV8TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE) {
- // Keep as `true' until this is a functional JIT to allow llvm-gcc to build
- return true;
-
- // Machine code emitter pass for SparcV8
- PM.add(new SparcV8CodeEmitter(*this, MCE));
- // Delete machine code for this function after emitting it
- PM.add(createMachineCodeDeleter());
- return false;
-}
-
-bool SparcV8CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
- MCE.startFunction(MF);
- MCE.emitConstantPool(MF.getConstantPool());
- for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
- emitBasicBlock(*I);
- MCE.finishFunction(MF);
-
- // Resolve branches to BasicBlocks for the entire function
- for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
- long Location = BBLocations[BBRefs[i].first];
- unsigned *Ref = BBRefs[i].second.first;
- MachineInstr *MI = BBRefs[i].second.second;
- DEBUG(std::cerr << "Fixup @ " << std::hex << Ref << " to 0x" << Location
- << " in instr: " << std::dec << *MI);
- for (unsigned ii = 0, ee = MI->getNumOperands(); ii != ee; ++ii) {
- MachineOperand &op = MI->getOperand(ii);
- if (op.isPCRelativeDisp()) {
- // the instruction's branch target is made such that it branches to
- // PC + (branchTarget * 4), so undo that arithmetic here:
- // Location is the target of the branch
- // Ref is the location of the instruction, and hence the PC
- int64_t branchTarget = (Location - (long)Ref) >> 2;
- MI->SetMachineOperandConst(ii, MachineOperand::MO_SignExtendedImmed,
- branchTarget);
- unsigned fixedInstr = SparcV8CodeEmitter::getBinaryCodeForInstr(*MI);
- MCE.emitWordAt(fixedInstr, Ref);
- break;
- }
- }
- }
- BBRefs.clear();
- BBLocations.clear();
-
- return false;
-}
-
-void SparcV8CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
- for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I)
- emitWord(getBinaryCodeForInstr(*I));
-}
-
-int64_t SparcV8CodeEmitter::getMachineOpValue(MachineInstr &MI,
- MachineOperand &MO) {
- int64_t rv = 0; // Return value; defaults to 0 for unhandled cases
- // or things that get fixed up later by the JIT.
- if (MO.isPCRelativeDisp()) {
- std::cerr << "SparcV8CodeEmitter: PC-relative disp unhandled\n";
- abort();
- } else if (MO.isRegister()) {
- rv = MO.getReg();
- } else if (MO.isImmediate()) {
- rv = MO.getImmedValue();
- } else if (MO.isGlobalAddress()) {
- GlobalValue *GV = MO.getGlobal();
- std::cerr << "Unhandled global value: " << GV << "\n";
- abort();
- } else if (MO.isMachineBasicBlock()) {
- const BasicBlock *BB = MO.getMachineBasicBlock()->getBasicBlock();
- unsigned* CurrPC = (unsigned*)(intptr_t)MCE.getCurrentPCValue();
- BBRefs.push_back(std::make_pair(BB, std::make_pair(CurrPC, &MI)));
- } else if (MO.isExternalSymbol()) {
- } else if (MO.isConstantPoolIndex()) {
- unsigned index = MO.getConstantPoolIndex();
- rv = MCE.getConstantPoolEntryAddress(index);
- } else if (MO.isFrameIndex()) {
- std::cerr << "SparcV8CodeEmitter: error: Frame index unhandled!\n";
- abort();
- } else {
- std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
- abort();
- }
-
- // Adjust for special meaning of operands in some instructions
- unsigned Opcode = MI.getOpcode();
- if (Opcode == V8::SETHIi && !MO.isRegister() && !MO.isImmediate()) {
- rv &= 0x03ff;
- } else if (Opcode == V8::ORri &&!MO.isRegister() &&!MO.isImmediate()) {
- rv = (rv >> 10) & 0x03fffff;
- }
-
- return rv;
-}
-
-void *SparcV8JITInfo::getJITStubForFunction(Function *F,
- MachineCodeEmitter &MCE) {
- std::cerr << "SparcV8JITInfo::getJITStubForFunction not implemented!\n";
- abort();
- return 0;
-}
-
-void SparcV8JITInfo::replaceMachineCodeForFunction(void *Old, void *New) {
- std::cerr << "SparcV8JITInfo::replaceMachineCodeForFunction not implemented!";
- abort();
-}
-
-#include "SparcV8GenCodeEmitter.inc"
-
-} // end llvm namespace
diff --git a/llvm/lib/Target/SparcV8/SparcV8ISelSimple.cpp b/llvm/lib/Target/SparcV8/SparcV8ISelSimple.cpp
deleted file mode 100644
index 0ea1f4a2d8ac..000000000000
--- a/llvm/lib/Target/SparcV8/SparcV8ISelSimple.cpp
+++ /dev/null
@@ -1,1671 +0,0 @@
-//===-- InstSelectSimple.cpp - A simple instruction selector for SparcV8 --===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a simple peephole instruction selector for the V8 target
-//
-//===----------------------------------------------------------------------===//
-
-#include "SparcV8.h"
-#include "SparcV8InstrInfo.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Instructions.h"
-#include "llvm/Pass.h"
-#include "llvm/Constants.h"
-#include "llvm/CodeGen/IntrinsicLowering.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/SSARegMap.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Support/GetElementPtrTypeIterator.h"
-#include "llvm/Support/InstVisitor.h"
-#include "llvm/Support/CFG.h"
-using namespace llvm;
-
-namespace {
- struct V8ISel : public FunctionPass, public InstVisitor<V8ISel> {
- TargetMachine &TM;
- MachineFunction *F; // The function we are compiling into
- MachineBasicBlock *BB; // The current MBB we are compiling
- int VarArgsOffset; // Offset from fp for start of varargs area
-
- std::map<Value*, unsigned> RegMap; // Mapping between Val's and SSA Regs
-
- // MBBMap - Mapping between LLVM BB -> Machine BB
- std::map<const BasicBlock*, MachineBasicBlock*> MBBMap;
-
- V8ISel(TargetMachine &tm) : TM(tm), F(0), BB(0) {}
-
- /// runOnFunction - Top level implementation of instruction selection for
- /// the entire function.
- ///
- bool runOnFunction(Function &Fn);
-
- virtual const char *getPassName() const {
- return "SparcV8 Simple Instruction Selection";
- }
-
- /// emitGEPOperation - Common code shared between visitGetElementPtrInst and
- /// constant expression GEP support.
- ///
- void emitGEPOperation(MachineBasicBlock *BB, MachineBasicBlock::iterator IP,
- Value *Src, User::op_iterator IdxBegin,
- User::op_iterator IdxEnd, unsigned TargetReg);
-
- /// emitCastOperation - Common code shared between visitCastInst and
- /// constant expression cast support.
- ///
- void emitCastOperation(MachineBasicBlock *BB,MachineBasicBlock::iterator IP,
- Value *Src, const Type *DestTy, unsigned TargetReg);
-
- /// emitIntegerCast, emitFPToIntegerCast - Helper methods for
- /// emitCastOperation.
- ///
- unsigned emitIntegerCast (MachineBasicBlock *BB,
- MachineBasicBlock::iterator IP,
- const Type *oldTy, unsigned SrcReg,
- const Type *newTy, unsigned DestReg);
- void emitFPToIntegerCast (MachineBasicBlock *BB,
- MachineBasicBlock::iterator IP, const Type *oldTy,
- unsigned SrcReg, const Type *newTy,
- unsigned DestReg);
-
- /// visitBasicBlock - This method is called when we are visiting a new basic
- /// block. This simply creates a new MachineBasicBlock to emit code into
- /// and adds it to the current MachineFunction. Subsequent visit* for
- /// instructions will be invoked for all instructions in the basic block.
- ///
- void visitBasicBlock(BasicBlock &LLVM_BB) {
- BB = MBBMap[&LLVM_BB];
- }
-
- void emitOp64LibraryCall (MachineBasicBlock *MBB,
- MachineBasicBlock::iterator IP,
- unsigned DestReg, const char *FuncName,
- unsigned Op0Reg, unsigned Op1Reg);
- void emitShift64 (MachineBasicBlock *MBB, MachineBasicBlock::iterator IP,
- Instruction &I, unsigned DestReg, unsigned Op0Reg,
- unsigned Op1Reg);
- void visitBinaryOperator(Instruction &I);
- void visitShiftInst (ShiftInst &SI) { visitBinaryOperator (SI); }
- void visitSetCondInst(SetCondInst &I);
- void visitCallInst(CallInst &I);
- void visitReturnInst(ReturnInst &I);
- void visitBranchInst(BranchInst &I);
- void visitUnreachableInst(UnreachableInst &I) {}
- void visitCastInst(CastInst &I);
- void visitVANextInst(VANextInst &I);
- void visitVAArgInst(VAArgInst &I);
- void visitLoadInst(LoadInst &I);
- void visitStoreInst(StoreInst &I);
- void visitPHINode(PHINode &I) {} // PHI nodes handled by second pass
- void visitGetElementPtrInst(GetElementPtrInst &I);
- void visitAllocaInst(AllocaInst &I);
-
- void visitInstruction(Instruction &I) {
- std::cerr << "Unhandled instruction: " << I;
- abort();
- }
-
- /// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the
- /// function, lowering any calls to unknown intrinsic functions into the
- /// equivalent LLVM code.
- void LowerUnknownIntrinsicFunctionCalls(Function &F);
- void visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI);
-
- void LoadArgumentsToVirtualRegs(Function *F);
-
- /// SelectPHINodes - Insert machine code to generate phis. This is tricky
- /// because we have to generate our sources into the source basic blocks,
- /// not the current one.
- ///
- void SelectPHINodes();
-
- /// copyConstantToRegister - Output the instructions required to put the
- /// specified constant into the specified register.
- ///
- void copyConstantToRegister(MachineBasicBlock *MBB,
- MachineBasicBlock::iterator IP,
- Constant *C, unsigned R);
-
- /// makeAnotherReg - This method returns the next register number we haven't
- /// yet used.
- ///
- /// Long values are handled somewhat specially. They are always allocated
- /// as pairs of 32 bit integer values. The register number returned is the
- /// lower 32 bits of the long value, and the regNum+1 is the upper 32 bits
- /// of the long value.
- ///
- unsigned makeAnotherReg(const Type *Ty) {
- assert(dynamic_cast<const SparcV8RegisterInfo*>(TM.getRegisterInfo()) &&
- "Current target doesn't have SparcV8 reg info??");
- const SparcV8RegisterInfo *MRI =
- static_cast<const SparcV8RegisterInfo*>(TM.getRegisterInfo());
- if (Ty == Type::LongTy || Ty == Type::ULongTy) {
- const TargetRegisterClass *RC = MRI->getRegClassForType(Type::IntTy);
- // Create the lower part
- F->getSSARegMap()->createVirtualRegister(RC);
- // Create the upper part.
- return F->getSSARegMap()->createVirtualRegister(RC)-1;
- }
-
- // Add the mapping of regnumber => reg class to MachineFunction
- const TargetRegisterClass *RC = MRI->getRegClassForType(Ty);
- return F->getSSARegMap()->createVirtualRegister(RC);
- }
-
- unsigned getReg(Value &V) { return getReg (&V); } // allow refs.
- unsigned getReg(Value *V) {
- // Just append to the end of the current bb.
- MachineBasicBlock::iterator It = BB->end();
- return getReg(V, BB, It);
- }
- unsigned getReg(Value *V, MachineBasicBlock *MBB,
- MachineBasicBlock::iterator IPt) {
- unsigned &Reg = RegMap[V];
- if (Reg == 0) {
- Reg = makeAnotherReg(V->getType());
- RegMap[V] = Reg;
- }
- // If this operand is a constant, emit the code to copy the constant into
- // the register here...
- //
- if (Constant *C = dyn_cast<Constant>(V)) {
- copyConstantToRegister(MBB, IPt, C, Reg);
- RegMap.erase(V); // Assign a new name to this constant if ref'd again
- } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
- // Move the address of the global into the register
- unsigned TmpReg = makeAnotherReg(V->getType());
- BuildMI (*MBB, IPt, V8::SETHIi, 1, TmpReg).addGlobalAddress (GV);
- BuildMI (*MBB, IPt, V8::ORri, 2, Reg).addReg (TmpReg)
- .addGlobalAddress (GV);
- RegMap.erase(V); // Assign a new name to this address if ref'd again
- }
-
- return Reg;
- }
-
- };
-}
-
-FunctionPass *llvm::createSparcV8SimpleInstructionSelector(TargetMachine &TM) {
- return new V8ISel(TM);
-}
-
-enum TypeClass {
- cByte, cShort, cInt, cLong, cFloat, cDouble
-};
-
-static TypeClass getClass (const Type *T) {
- switch (T->getTypeID()) {
- case Type::UByteTyID: case Type::SByteTyID: return cByte;
- case Type::UShortTyID: case Type::ShortTyID: return cShort;
- case Type::PointerTyID:
- case Type::UIntTyID: case Type::IntTyID: return cInt;
- case Type::ULongTyID: case Type::LongTyID: return cLong;
- case Type::FloatTyID: return cFloat;
- case Type::DoubleTyID: return cDouble;
- default:
- assert (0 && "Type of unknown class passed to getClass?");
- return cByte;
- }
-}
-
-static TypeClass getClassB(const Type *T) {
- if (T == Type::BoolTy) return cByte;
- return getClass(T);
-}
-
-/// copyConstantToRegister - Output the instructions required to put the
-/// specified constant into the specified register.
-///
-void V8ISel::copyConstantToRegister(MachineBasicBlock *MBB,
- MachineBasicBlock::iterator IP,
- Constant *C, unsigned R) {
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
- switch (CE->getOpcode()) {
- case Instruction::GetElementPtr:
- emitGEPOperation(MBB, IP, CE->getOperand(0),
- CE->op_begin()+1, CE->op_end(), R);
- return;
- case Instruction::Cast:
- emitCastOperation(MBB, IP, CE->getOperand(0), CE->getType(), R);
- return;
- default:
- std::cerr << "Copying this constant expr not yet handled: " << *CE;
- abort();
- }
- } else if (isa<UndefValue>(C)) {
- BuildMI(*MBB, IP, V8::IMPLICIT_DEF, 0, R);
- if (getClassB (C->getType ()) == cLong)
- BuildMI(*MBB, IP, V8::IMPLICIT_DEF, 0, R+1);
- return;
- }
-
- if (C->getType()->isIntegral ()) {
- uint64_t Val;
- unsigned Class = getClassB (C->getType ());
- if (Class == cLong) {
- unsigned TmpReg = makeAnotherReg (Type::IntTy);
- unsigned TmpReg2 = makeAnotherReg (Type::IntTy);
- // Copy the value into the register pair.
- // R = top(more-significant) half, R+1 = bottom(less-significant) half
- uint64_t Val = cast<ConstantInt>(C)->getRawValue();
- copyConstantToRegister(MBB, IP, ConstantUInt::get(Type::UIntTy,
- Val >> 32), R);
- copyConstantToRegister(MBB, IP, ConstantUInt::get(Type::UIntTy,
- Val & 0xffffffffU), R+1);
- return;
- }
-
- assert(Class <= cInt && "Type not handled yet!");
-
- if (C->getType() == Type::BoolTy) {
- Val = (C == ConstantBool::True);
- } else {
- ConstantInt *CI = cast<ConstantInt> (C);
- Val = CI->getRawValue ();
- }
- switch (Class) {
- case cByte: Val = (int8_t) Val; break;
- case cShort: Val = (int16_t) Val; break;
- case cInt: Val = (int32_t) Val; break;
- default:
- std::cerr << "Offending constant: " << *C << "\n";
- assert (0 && "Can't copy this kind of constant into register yet");
- return;
- }
- if (Val == 0) {
- BuildMI (*MBB, IP, V8::ORrr, 2, R).addReg (V8::G0).addReg(V8::G0);
- } else if (((int64_t)Val >= -4096) && ((int64_t)Val <= 4095)) {
- BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (V8::G0).addSImm(Val);
- } else {
- unsigned TmpReg = makeAnotherReg (C->getType ());
- BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg)
- .addSImm (((uint32_t) Val) >> 10);
- BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (TmpReg)
- .addSImm (((uint32_t) Val) & 0x03ff);
- return;
- }
- } else if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
- // We need to spill the constant to memory...
- MachineConstantPool *CP = F->getConstantPool();
- unsigned CPI = CP->getConstantPoolIndex(CFP);
- const Type *Ty = CFP->getType();
- unsigned TmpReg = makeAnotherReg (Type::UIntTy);
- unsigned AddrReg = makeAnotherReg (Type::UIntTy);
-
- assert(Ty == Type::FloatTy || Ty == Type::DoubleTy && "Unknown FP type!");
- unsigned LoadOpcode = Ty == Type::FloatTy ? V8::LDFri : V8::LDDFri;
- BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg).addConstantPoolIndex (CPI);
- BuildMI (*MBB, IP, V8::ORri, 2, AddrReg).addReg (TmpReg)
- .addConstantPoolIndex (CPI);
- BuildMI (*MBB, IP, LoadOpcode, 2, R).addReg (AddrReg).addSImm (0);
- } else if (isa<ConstantPointerNull>(C)) {
- // Copy zero (null pointer) to the register.
- BuildMI (*MBB, IP, V8::ORri, 2, R).addReg (V8::G0).addSImm (0);
- } else if (GlobalValue *GV = dyn_cast<GlobalValue>(C)) {
- // Copy it with a SETHI/OR pair; the JIT + asmwriter should recognize
- // that SETHI %reg,global == SETHI %reg,%hi(global) and
- // OR %reg,global,%reg == OR %reg,%lo(global),%reg.
- unsigned TmpReg = makeAnotherReg (C->getType ());
- BuildMI (*MBB, IP, V8::SETHIi, 1, TmpReg).addGlobalAddress(GV);
- BuildMI (*MBB, IP, V8::ORri, 2, R).addReg(TmpReg).addGlobalAddress(GV);
- } else {
- std::cerr << "Offending constant: " << *C << "\n";
- assert (0 && "Can't copy this kind of constant into register yet");
- }
-}
-
-void V8ISel::LoadArgumentsToVirtualRegs (Function *LF) {
- static const unsigned IncomingArgRegs[] = { V8::I0, V8::I1, V8::I2,
- V8::I3, V8::I4, V8::I5 };
-
- // Add IMPLICIT_DEFs of input regs.
- unsigned ArgNo = 0;
- for (Function::aiterator I = LF->abegin(), E = LF->aend();
- I != E && ArgNo < 6; ++I, ++ArgNo) {
- switch (getClassB(I->getType())) {
- case cByte:
- case cShort:
- case cInt:
- case cFloat:
- BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgNo]);
- break;
- case cDouble:
- case cLong:
- // Double and Long use register pairs.
- BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgNo]);
- ++ArgNo;
- if (ArgNo < 6)
- BuildMI(BB, V8::IMPLICIT_DEF, 0, IncomingArgRegs[ArgNo]);
- break;
- default:
- assert (0 && "type not handled");
- return;
- }
- }
-
- const unsigned *IAREnd = &IncomingArgRegs[6];
- const unsigned *IAR = &IncomingArgRegs[0];
- unsigned ArgOffset = 68;
-
- // Store registers onto stack if this is a varargs function.
- // FIXME: This doesn't really pertain to "loading arguments into
- // virtual registers", so it's not clear that it really belongs here.
- // FIXME: We could avoid storing any args onto the stack that don't
- // need to be in memory, because they come before the ellipsis in the
- // parameter list (and thus could never be accessed through va_arg).
- if (LF->getFunctionType ()->isVarArg ()) {
- for (unsigned i = 0; i < 6; ++i) {
- int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
- assert (IAR != IAREnd
- && "About to dereference past end of IncomingArgRegs");
- BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (*IAR++);
- ArgOffset += 4;
- }
- // Reset the pointers now that we're done.
- ArgOffset = 68;
- IAR = &IncomingArgRegs[0];
- }
-
- // Copy args out of their incoming hard regs or stack slots into virtual regs.
- for (Function::aiterator I = LF->abegin(), E = LF->aend(); I != E; ++I) {
- Argument &A = *I;
- unsigned ArgReg = getReg (A);
- if (getClassB (A.getType ()) < cLong) {
- // Get it out of the incoming arg register
- if (ArgOffset < 92) {
- assert (IAR != IAREnd
- && "About to dereference past end of IncomingArgRegs");
- BuildMI (BB, V8::ORrr, 2, ArgReg).addReg (V8::G0).addReg (*IAR++);
- } else {
- int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
- BuildMI (BB, V8::LD, 3, ArgReg).addFrameIndex (FI).addSImm (0);
- }
- ArgOffset += 4;
- } else if (getClassB (A.getType ()) == cFloat) {
- if (ArgOffset < 92) {
- // Single-fp args are passed in integer registers; go through
- // memory to get them out of integer registers and back into fp. (Bleh!)
- unsigned FltAlign = TM.getTargetData().getFloatAlignment();
- int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
- assert (IAR != IAREnd
- && "About to dereference past end of IncomingArgRegs");
- BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (*IAR++);
- BuildMI (BB, V8::LDFri, 2, ArgReg).addFrameIndex (FI).addSImm (0);
- } else {
- int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
- BuildMI (BB, V8::LDFri, 3, ArgReg).addFrameIndex (FI).addSImm (0);
- }
- ArgOffset += 4;
- } else if (getClassB (A.getType ()) == cDouble) {
- // Double-fp args are passed in pairs of integer registers; go through
- // memory to get them out of integer registers and back into fp. (Bleh!)
- // We'd like to 'ldd' these right out of the incoming-args area,
- // but it might not be 8-byte aligned (e.g., call x(int x, double d)).
- unsigned DblAlign = TM.getTargetData().getDoubleAlignment();
- int FI = F->getFrameInfo()->CreateStackObject(8, DblAlign);
- if (ArgOffset < 92 && IAR != IAREnd) {
- BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (*IAR++);
- } else {
- unsigned TempReg = makeAnotherReg (Type::IntTy);
- BuildMI (BB, V8::LD, 2, TempReg).addFrameIndex (FI).addSImm (0);
- BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (TempReg);
- }
- ArgOffset += 4;
- if (ArgOffset < 92 && IAR != IAREnd) {
- BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (4).addReg (*IAR++);
- } else {
- unsigned TempReg = makeAnotherReg (Type::IntTy);
- BuildMI (BB, V8::LD, 2, TempReg).addFrameIndex (FI).addSImm (4);
- BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (4).addReg (TempReg);
- }
- ArgOffset += 4;
- BuildMI (BB, V8::LDDFri, 2, ArgReg).addFrameIndex (FI).addSImm (0);
- } else if (getClassB (A.getType ()) == cLong) {
- // do the first half...
- if (ArgOffset < 92) {
- assert (IAR != IAREnd
- && "About to dereference past end of IncomingArgRegs");
- BuildMI (BB, V8::ORrr, 2, ArgReg).addReg (V8::G0).addReg (*IAR++);
- } else {
- int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
- BuildMI (BB, V8::LD, 2, ArgReg).addFrameIndex (FI).addSImm (0);
- }
- ArgOffset += 4;
- // ...then do the second half
- if (ArgOffset < 92) {
- assert (IAR != IAREnd
- && "About to dereference past end of IncomingArgRegs");
- BuildMI (BB, V8::ORrr, 2, ArgReg+1).addReg (V8::G0).addReg (*IAR++);
- } else {
- int FI = F->getFrameInfo()->CreateFixedObject(4, ArgOffset);
- BuildMI (BB, V8::LD, 2, ArgReg+1).addFrameIndex (FI).addSImm (0);
- }
- ArgOffset += 4;
- } else {
- assert (0 && "Unknown class?!");
- }
- }
-
- // If the function takes variable number of arguments, remember the fp
- // offset for the start of the first vararg value... this is used to expand
- // llvm.va_start.
- if (LF->getFunctionType ()->isVarArg ())
- VarArgsOffset = ArgOffset;
-}
-
-void V8ISel::SelectPHINodes() {
- const TargetInstrInfo &TII = *TM.getInstrInfo();
- const Function &LF = *F->getFunction(); // The LLVM function...
- for (Function::const_iterator I = LF.begin(), E = LF.end(); I != E; ++I) {
- const BasicBlock *BB = I;
- MachineBasicBlock &MBB = *MBBMap[I];
-
- // Loop over all of the PHI nodes in the LLVM basic block...
- MachineBasicBlock::iterator PHIInsertPoint = MBB.begin();
- for (BasicBlock::const_iterator I = BB->begin();
- PHINode *PN = const_cast<PHINode*>(dyn_cast<PHINode>(I)); ++I) {
-
- // Create a new machine instr PHI node, and insert it.
- unsigned PHIReg = getReg(*PN);
- MachineInstr *PhiMI = BuildMI(MBB, PHIInsertPoint,
- V8::PHI, PN->getNumOperands(), PHIReg);
-
- MachineInstr *LongPhiMI = 0;
- if (PN->getType() == Type::LongTy || PN->getType() == Type::ULongTy)
- LongPhiMI = BuildMI(MBB, PHIInsertPoint,
- V8::PHI, PN->getNumOperands(), PHIReg+1);
-
- // PHIValues - Map of blocks to incoming virtual registers. We use this
- // so that we only initialize one incoming value for a particular block,
- // even if the block has multiple entries in the PHI node.
- //
- std::map<MachineBasicBlock*, unsigned> PHIValues;
-
- for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
- MachineBasicBlock *PredMBB = 0;
- for (MachineBasicBlock::pred_iterator PI = MBB.pred_begin (),
- PE = MBB.pred_end (); PI != PE; ++PI)
- if (PN->getIncomingBlock(i) == (*PI)->getBasicBlock()) {
- PredMBB = *PI;
- break;
- }
- assert (PredMBB && "Couldn't find incoming machine-cfg edge for phi");
-
- unsigned ValReg;
- std::map<MachineBasicBlock*, unsigned>::iterator EntryIt =
- PHIValues.lower_bound(PredMBB);
-
- if (EntryIt != PHIValues.end() && EntryIt->first == PredMBB) {
- // We already inserted an initialization of the register for this
- // predecessor. Recycle it.
- ValReg = EntryIt->second;
-
- } else {
- // Get the incoming value into a virtual register.
- //
- Value *Val = PN->getIncomingValue(i);
-
- // If this is a constant or GlobalValue, we may have to insert code
- // into the basic block to compute it into a virtual register.
- if ((isa<Constant>(Val) && !isa<ConstantExpr>(Val)) ||
- isa<GlobalValue>(Val)) {
- // Simple constants get emitted at the end of the basic block,
- // before any terminator instructions. We "know" that the code to
- // move a constant into a register will never clobber any flags.
- ValReg = getReg(Val, PredMBB, PredMBB->getFirstTerminator());
- } else {
- // Because we don't want to clobber any values which might be in
- // physical registers with the computation of this constant (which
- // might be arbitrarily complex if it is a constant expression),
- // just insert the computation at the top of the basic block.
- MachineBasicBlock::iterator PI = PredMBB->begin();
-
- // Skip over any PHI nodes though!
- while (PI != PredMBB->end() && PI->getOpcode() == V8::PHI)
- ++PI;
-
- ValReg = getReg(Val, PredMBB, PI);
- }
-
- // Remember that we inserted a value for this PHI for this predecessor
- PHIValues.insert(EntryIt, std::make_pair(PredMBB, ValReg));
- }
-
- PhiMI->addRegOperand(ValReg);
- PhiMI->addMachineBasicBlockOperand(PredMBB);
- if (LongPhiMI) {
- LongPhiMI->addRegOperand(ValReg+1);
- LongPhiMI->addMachineBasicBlockOperand(PredMBB);
- }
- }
-
- // Now that we emitted all of the incoming values for the PHI node, make
- // sure to reposition the InsertPoint after the PHI that we just added.
- // This is needed because we might have inserted a constant into this
- // block, right after the PHI's which is before the old insert point!
- PHIInsertPoint = LongPhiMI ? LongPhiMI : PhiMI;
- ++PHIInsertPoint;
- }
- }
-}
-
-bool V8ISel::runOnFunction(Function &Fn) {
- // First pass over the function, lower any unknown intrinsic functions
- // with the IntrinsicLowering class.
- LowerUnknownIntrinsicFunctionCalls(Fn);
-
- F = &MachineFunction::construct(&Fn, TM);
-
- // Create all of the machine basic blocks for the function...
- for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
- F->getBasicBlockList().push_back(MBBMap[I] = new MachineBasicBlock(I));
-
- BB = &F->front();
-
- // Set up a frame object for the return address. This is used by the
- // llvm.returnaddress & llvm.frameaddress intrinisics.
- //ReturnAddressIndex = F->getFrameInfo()->CreateFixedObject(4, -4);
-
- // Copy incoming arguments off of the stack and out of fixed registers.
- LoadArgumentsToVirtualRegs(&Fn);
-
- // Instruction select everything except PHI nodes
- visit(Fn);
-
- // Select the PHI nodes
- SelectPHINodes();
-
- RegMap.clear();
- MBBMap.clear();
- F = 0;
- // We always build a machine code representation for the function
- return true;
-}
-
-void V8ISel::visitCastInst(CastInst &I) {
- Value *Op = I.getOperand(0);
- unsigned DestReg = getReg(I);
- MachineBasicBlock::iterator MI = BB->end();
- emitCastOperation(BB, MI, Op, I.getType(), DestReg);
-}
-
-unsigned V8ISel::emitIntegerCast (MachineBasicBlock *BB,
- MachineBasicBlock::iterator IP, const Type *oldTy,
- unsigned SrcReg, const Type *newTy,
- unsigned DestReg) {
- if (oldTy == newTy) {
- // No-op cast - just emit a copy; assume the reg. allocator will zap it.
- BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg(SrcReg);
- return SrcReg;
- }
- // Emit left-shift, then right-shift to sign- or zero-extend.
- unsigned TmpReg = makeAnotherReg (newTy);
- unsigned shiftWidth = 32 - (8 * TM.getTargetData ().getTypeSize (newTy));
- BuildMI (*BB, IP, V8::SLLri, 2, TmpReg).addZImm (shiftWidth).addReg(SrcReg);
- if (newTy->isSigned ()) { // sign-extend with SRA
- BuildMI(*BB, IP, V8::SRAri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg);
- } else { // zero-extend with SRL
- BuildMI(*BB, IP, V8::SRLri, 2, DestReg).addZImm (shiftWidth).addReg(TmpReg);
- }
- // Return the temp reg. in case this is one half of a cast to long.
- return TmpReg;
-}
-
-void V8ISel::emitFPToIntegerCast (MachineBasicBlock *BB,
- MachineBasicBlock::iterator IP,
- const Type *oldTy, unsigned SrcReg,
- const Type *newTy, unsigned DestReg) {
- unsigned FPCastOpcode, FPStoreOpcode, FPSize, FPAlign;
- unsigned oldTyClass = getClassB(oldTy);
- if (oldTyClass == cFloat) {
- FPCastOpcode = V8::FSTOI; FPStoreOpcode = V8::STFri; FPSize = 4;
- FPAlign = TM.getTargetData().getFloatAlignment();
- } else { // it's a double
- FPCastOpcode = V8::FDTOI; FPStoreOpcode = V8::STDFri; FPSize = 8;
- FPAlign = TM.getTargetData().getDoubleAlignment();
- }
- unsigned TempReg = makeAnotherReg (oldTy);
- BuildMI (*BB, IP, FPCastOpcode, 1, TempReg).addReg (SrcReg);
- int FI = F->getFrameInfo()->CreateStackObject(FPSize, FPAlign);
- BuildMI (*BB, IP, FPStoreOpcode, 3).addFrameIndex (FI).addSImm (0)
- .addReg (TempReg);
- unsigned TempReg2 = makeAnotherReg (newTy);
- BuildMI (*BB, IP, V8::LD, 3, TempReg2).addFrameIndex (FI).addSImm (0);
- emitIntegerCast (BB, IP, Type::IntTy, TempReg2, newTy, DestReg);
-}
-
-/// emitCastOperation - Common code shared between visitCastInst and constant
-/// expression cast support.
-///
-void V8ISel::emitCastOperation(MachineBasicBlock *BB,
- MachineBasicBlock::iterator IP, Value *Src,
- const Type *DestTy, unsigned DestReg) {
- const Type *SrcTy = Src->getType();
- unsigned SrcClass = getClassB(SrcTy);
- unsigned DestClass = getClassB(DestTy);
- unsigned SrcReg = getReg(Src, BB, IP);
-
- const Type *oldTy = SrcTy;
- const Type *newTy = DestTy;
- unsigned oldTyClass = SrcClass;
- unsigned newTyClass = DestClass;
-
- if (oldTyClass < cLong && newTyClass < cLong) {
- emitIntegerCast (BB, IP, oldTy, SrcReg, newTy, DestReg);
- } else switch (newTyClass) {
- case cByte:
- case cShort:
- case cInt:
- switch (oldTyClass) {
- case cLong:
- // Treat it like a cast from the lower half of the value.
- emitIntegerCast (BB, IP, Type::IntTy, SrcReg+1, newTy, DestReg);
- break;
- case cFloat:
- case cDouble:
- emitFPToIntegerCast (BB, IP, oldTy, SrcReg, newTy, DestReg);
- break;
- default: goto not_yet;
- }
- return;
-
- case cFloat:
- switch (oldTyClass) {
- case cLong: goto not_yet;
- case cFloat:
- BuildMI (*BB, IP, V8::FMOVS, 1, DestReg).addReg (SrcReg);
- break;
- case cDouble:
- BuildMI (*BB, IP, V8::FDTOS, 1, DestReg).addReg (SrcReg);
- break;
- default: {
- unsigned FltAlign = TM.getTargetData().getFloatAlignment();
- // cast integer type to float. Store it to a stack slot and then load
- // it using ldf into a floating point register. then do fitos.
- unsigned TmpReg = makeAnotherReg (newTy);
- int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
- BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
- .addReg (SrcReg);
- BuildMI (*BB, IP, V8::LDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
- BuildMI (*BB, IP, V8::FITOS, 1, DestReg).addReg(TmpReg);
- break;
- }
- }
- return;
-
- case cDouble:
- switch (oldTyClass) {
- case cLong: goto not_yet;
- case cFloat:
- BuildMI (*BB, IP, V8::FSTOD, 1, DestReg).addReg (SrcReg);
- break;
- case cDouble: // use double move pseudo-instr
- BuildMI (*BB, IP, V8::FpMOVD, 1, DestReg).addReg (SrcReg);
- break;
- default: {
- unsigned DoubleAlignment = TM.getTargetData().getDoubleAlignment();
- unsigned TmpReg = makeAnotherReg (newTy);
- int FI = F->getFrameInfo()->CreateStackObject(8, DoubleAlignment);
- BuildMI (*BB, IP, V8::ST, 3).addFrameIndex (FI).addSImm (0)
- .addReg (SrcReg);
- BuildMI (*BB, IP, V8::LDDFri, 2, TmpReg).addFrameIndex (FI).addSImm (0);
- BuildMI (*BB, IP, V8::FITOD, 1, DestReg).addReg(TmpReg);
- break;
- }
- }
- return;
-
- case cLong:
- switch (oldTyClass) {
- case cByte:
- case cShort:
- case cInt: {
- // Cast to (u)int in the bottom half, and sign(zero) extend in the top
- // half.
- const Type *OldHalfTy = oldTy->isSigned() ? Type::IntTy : Type::UIntTy;
- const Type *NewHalfTy = newTy->isSigned() ? Type::IntTy : Type::UIntTy;
- unsigned TempReg = emitIntegerCast (BB, IP, OldHalfTy, SrcReg,
- NewHalfTy, DestReg+1);
- if (newTy->isSigned ()) {
- BuildMI (*BB, IP, V8::SRAri, 2, DestReg).addReg (TempReg)
- .addZImm (31);
- } else {
- BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0)
- .addReg (V8::G0);
- }
- break;
- }
- case cLong:
- // Just copy both halves.
- BuildMI (*BB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg);
- BuildMI (*BB, IP, V8::ORrr, 2, DestReg+1).addReg (V8::G0)
- .addReg (SrcReg+1);
- break;
- default: goto not_yet;
- }
- return;
-
- default: goto not_yet;
- }
- return;
-not_yet:
- std::cerr << "Sorry, cast still unsupported: SrcTy = " << *SrcTy
- << ", DestTy = " << *DestTy << "\n";
- abort ();
-}
-
-void V8ISel::visitLoadInst(LoadInst &I) {
- unsigned DestReg = getReg (I);
- unsigned PtrReg = getReg (I.getOperand (0));
- switch (getClassB (I.getType ())) {
- case cByte:
- if (I.getType ()->isSigned ())
- BuildMI (BB, V8::LDSB, 2, DestReg).addReg (PtrReg).addSImm(0);
- else
- BuildMI (BB, V8::LDUB, 2, DestReg).addReg (PtrReg).addSImm(0);
- return;
- case cShort:
- if (I.getType ()->isSigned ())
- BuildMI (BB, V8::LDSH, 2, DestReg).addReg (PtrReg).addSImm(0);
- else
- BuildMI (BB, V8::LDUH, 2, DestReg).addReg (PtrReg).addSImm(0);
- return;
- case cInt:
- BuildMI (BB, V8::LD, 2, DestReg).addReg (PtrReg).addSImm(0);
- return;
- case cLong:
- BuildMI (BB, V8::LD, 2, DestReg).addReg (PtrReg).addSImm(0);
- BuildMI (BB, V8::LD, 2, DestReg+1).addReg (PtrReg).addSImm(4);
- return;
- case cFloat:
- BuildMI (BB, V8::LDFri, 2, DestReg).addReg (PtrReg).addSImm(0);
- return;
- case cDouble:
- BuildMI (BB, V8::LDDFri, 2, DestReg).addReg (PtrReg).addSImm(0);
- return;
- default:
- std::cerr << "Load instruction not handled: " << I;
- abort ();
- return;
- }
-}
-
-void V8ISel::visitStoreInst(StoreInst &I) {
- Value *SrcVal = I.getOperand (0);
- unsigned SrcReg = getReg (SrcVal);
- unsigned PtrReg = getReg (I.getOperand (1));
- switch (getClassB (SrcVal->getType ())) {
- case cByte:
- BuildMI (BB, V8::STB, 3).addReg (PtrReg).addSImm (0).addReg (SrcReg);
- return;
- case cShort:
- BuildMI (BB, V8::STH, 3).addReg (PtrReg).addSImm (0).addReg (SrcReg);
- return;
- case cInt:
- BuildMI (BB, V8::ST, 3).addReg (PtrReg).addSImm (0).addReg (SrcReg);
- return;
- case cLong:
- BuildMI (BB, V8::ST, 3).addReg (PtrReg).addSImm (0).addReg (SrcReg);
- BuildMI (BB, V8::ST, 3).addReg (PtrReg).addSImm (4).addReg (SrcReg+1);
- return;
- case cFloat:
- BuildMI (BB, V8::STFri, 3).addReg (PtrReg).addSImm (0).addReg (SrcReg);
- return;
- case cDouble:
- BuildMI (BB, V8::STDFri, 3).addReg (PtrReg).addSImm (0).addReg (SrcReg);
- return;
- default:
- std::cerr << "Store instruction not handled: " << I;
- abort ();
- return;
- }
-}
-
-void V8ISel::visitCallInst(CallInst &I) {
- MachineInstr *TheCall;
- // Is it an intrinsic function call?
- if (Function *F = I.getCalledFunction()) {
- if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) {
- visitIntrinsicCall(ID, I); // Special intrinsics are not handled here
- return;
- }
- }
-
- // How much extra call stack will we need?
- int extraStack = 0;
- for (unsigned i = 0; i < I.getNumOperands (); ++i) {
- switch (getClassB (I.getOperand (i)->getType ())) {
- case cLong: extraStack += 8; break;
- case cFloat: extraStack += 4; break;
- case cDouble: extraStack += 8; break;
- default: extraStack += 4; break;
- }
- }
- extraStack -= 24;
- if (extraStack < 0) {
- extraStack = 0;
- } else {
- // Round up extra stack size to the nearest doubleword.
- extraStack = (extraStack + 7) & ~7;
- }
-
- // Deal with args
- static const unsigned OutgoingArgRegs[] = { V8::O0, V8::O1, V8::O2, V8::O3,
- V8::O4, V8::O5 };
- const unsigned *OAREnd = &OutgoingArgRegs[6];
- const unsigned *OAR = &OutgoingArgRegs[0];
- unsigned ArgOffset = 68;
- if (extraStack) BuildMI (BB, V8::ADJCALLSTACKDOWN, 1).addImm (extraStack);
- for (unsigned i = 1; i < I.getNumOperands (); ++i) {
- unsigned ArgReg = getReg (I.getOperand (i));
- if (getClassB (I.getOperand (i)->getType ()) < cLong) {
- // Schlep it over into the incoming arg register
- if (ArgOffset < 92) {
- assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
- BuildMI (BB, V8::ORrr, 2, *OAR++).addReg (V8::G0).addReg (ArgReg);
- } else {
- BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg);
- }
- ArgOffset += 4;
- } else if (getClassB (I.getOperand (i)->getType ()) == cFloat) {
- if (ArgOffset < 92) {
- // Single-fp args are passed in integer registers; go through
- // memory to get them out of FP registers. (Bleh!)
- unsigned FltAlign = TM.getTargetData().getFloatAlignment();
- int FI = F->getFrameInfo()->CreateStackObject(4, FltAlign);
- BuildMI (BB, V8::STFri, 3).addFrameIndex (FI).addSImm (0).addReg (ArgReg);
- assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
- BuildMI (BB, V8::LD, 2, *OAR++).addFrameIndex (FI).addSImm (0);
- } else {
- BuildMI (BB, V8::STFri, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg);
- }
- ArgOffset += 4;
- } else if (getClassB (I.getOperand (i)->getType ()) == cDouble) {
- // Double-fp args are passed in pairs of integer registers; go through
- // memory to get them out of FP registers. (Bleh!)
- // We'd like to 'std' these right onto the outgoing-args area, but it might
- // not be 8-byte aligned (e.g., call x(int x, double d)). sigh.
- unsigned DblAlign = TM.getTargetData().getDoubleAlignment();
- int FI = F->getFrameInfo()->CreateStackObject(8, DblAlign);
- BuildMI (BB, V8::STDFri, 3).addFrameIndex (FI).addSImm (0).addReg (ArgReg);
- if (ArgOffset < 92 && OAR != OAREnd) {
- assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
- BuildMI (BB, V8::LD, 2, *OAR++).addFrameIndex (FI).addSImm (0);
- } else {
- unsigned TempReg = makeAnotherReg (Type::IntTy);
- BuildMI (BB, V8::LD, 2, TempReg).addFrameIndex (FI).addSImm (0);
- BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (TempReg);
- }
- ArgOffset += 4;
- if (ArgOffset < 92 && OAR != OAREnd) {
- assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
- BuildMI (BB, V8::LD, 2, *OAR++).addFrameIndex (FI).addSImm (4);
- } else {
- unsigned TempReg = makeAnotherReg (Type::IntTy);
- BuildMI (BB, V8::LD, 2, TempReg).addFrameIndex (FI).addSImm (4);
- BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (TempReg);
- }
- ArgOffset += 4;
- } else if (getClassB (I.getOperand (i)->getType ()) == cLong) {
- // do the first half...
- if (ArgOffset < 92) {
- assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
- BuildMI (BB, V8::ORrr, 2, *OAR++).addReg (V8::G0).addReg (ArgReg);
- } else {
- BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg);
- }
- ArgOffset += 4;
- // ...then do the second half
- if (ArgOffset < 92) {
- assert (OAR != OAREnd && "About to dereference past end of OutgoingArgRegs");
- BuildMI (BB, V8::ORrr, 2, *OAR++).addReg (V8::G0).addReg (ArgReg+1);
- } else {
- BuildMI (BB, V8::ST, 3).addReg (V8::SP).addSImm (ArgOffset).addReg (ArgReg+1);
- }
- ArgOffset += 4;
- } else {
- assert (0 && "Unknown class?!");
- }
- }
-
- // Emit call instruction
- if (Function *F = I.getCalledFunction ()) {
- BuildMI (BB, V8::CALL, 1).addGlobalAddress (F, true);
- } else { // Emit an indirect call...
- unsigned Reg = getReg (I.getCalledValue ());
- BuildMI (BB, V8::JMPLrr, 3, V8::O7).addReg (Reg).addReg (V8::G0);
- }
-
- if (extraStack) BuildMI (BB, V8::ADJCALLSTACKUP, 1).addImm (extraStack);
-
- // Deal w/ return value: schlep it over into the destination register
- if (I.getType () == Type::VoidTy)
- return;
- unsigned DestReg = getReg (I);
- switch (getClassB (I.getType ())) {
- case cByte:
- case cShort:
- case cInt:
- BuildMI (BB, V8::ORrr, 2, DestReg).addReg(V8::G0).addReg(V8::O0);
- break;
- case cFloat:
- BuildMI (BB, V8::FMOVS, 2, DestReg).addReg(V8::F0);
- break;
- case cDouble:
- BuildMI (BB, V8::FpMOVD, 2, DestReg).addReg(V8::D0);
- break;
- case cLong:
- BuildMI (BB, V8::ORrr, 2, DestReg).addReg(V8::G0).addReg(V8::O0);
- BuildMI (BB, V8::ORrr, 2, DestReg+1).addReg(V8::G0).addReg(V8::O1);
- break;
- default:
- std::cerr << "Return type of call instruction not handled: " << I;
- abort ();
- }
-}
-
-void V8ISel::visitReturnInst(ReturnInst &I) {
- if (I.getNumOperands () == 1) {
- unsigned RetValReg = getReg (I.getOperand (0));
- switch (getClassB (I.getOperand (0)->getType ())) {
- case cByte:
- case cShort:
- case cInt:
- // Schlep it over into i0 (where it will become o0 after restore).
- BuildMI (BB, V8::ORrr, 2, V8::I0).addReg(V8::G0).addReg(RetValReg);
- break;
- case cFloat:
- BuildMI (BB, V8::FMOVS, 1, V8::F0).addReg(RetValReg);
- break;
- case cDouble:
- BuildMI (BB, V8::FpMOVD, 1, V8::D0).addReg(RetValReg);
- break;
- case cLong:
- BuildMI (BB, V8::ORrr, 2, V8::I0).addReg(V8::G0).addReg(RetValReg);
- BuildMI (BB, V8::ORrr, 2, V8::I1).addReg(V8::G0).addReg(RetValReg+1);
- break;
- default:
- std::cerr << "Return instruction of this type not handled: " << I;
- abort ();
- }
- }
-
- // Just emit a 'retl' instruction to return.
- BuildMI(BB, V8::RETL, 0);
- return;
-}
-
-static inline BasicBlock *getBlockAfter(BasicBlock *BB) {
- Function::iterator I = BB; ++I; // Get iterator to next block
- return I != BB->getParent()->end() ? &*I : 0;
-}
-
-/// visitBranchInst - Handles conditional and unconditional branches.
-///
-void V8ISel::visitBranchInst(BranchInst &I) {
- BasicBlock *takenSucc = I.getSuccessor (0);
- MachineBasicBlock *takenSuccMBB = MBBMap[takenSucc];
- BB->addSuccessor (takenSuccMBB);
- if (I.isConditional()) { // conditional branch
- BasicBlock *notTakenSucc = I.getSuccessor (1);
- MachineBasicBlock *notTakenSuccMBB = MBBMap[notTakenSucc];
- BB->addSuccessor (notTakenSuccMBB);
-
- // CondReg=(<condition>);
- // If (CondReg==0) goto notTakenSuccMBB;
- unsigned CondReg = getReg (I.getCondition ());
- BuildMI (BB, V8::CMPri, 2).addSImm (0).addReg (CondReg);
- BuildMI (BB, V8::BE, 1).addMBB (notTakenSuccMBB);
- }
- // goto takenSuccMBB;
- BuildMI (BB, V8::BA, 1).addMBB (takenSuccMBB);
-}
-
-/// emitGEPOperation - Common code shared between visitGetElementPtrInst and
-/// constant expression GEP support.
-///
-void V8ISel::emitGEPOperation (MachineBasicBlock *MBB,
- MachineBasicBlock::iterator IP,
- Value *Src, User::op_iterator IdxBegin,
- User::op_iterator IdxEnd, unsigned TargetReg) {
- const TargetData &TD = TM.getTargetData ();
- const Type *Ty = Src->getType ();
- unsigned basePtrReg = getReg (Src, MBB, IP);
-
- // GEPs have zero or more indices; we must perform a struct access
- // or array access for each one.
- for (GetElementPtrInst::op_iterator oi = IdxBegin, oe = IdxEnd; oi != oe;
- ++oi) {
- Value *idx = *oi;
- unsigned nextBasePtrReg = makeAnotherReg (Type::UIntTy);
- if (const StructType *StTy = dyn_cast<StructType> (Ty)) {
- // It's a struct access. idx is the index into the structure,
- // which names the field. Use the TargetData structure to
- // pick out what the layout of the structure is in memory.
- // Use the (constant) structure index's value to find the
- // right byte offset from the StructLayout class's list of
- // structure member offsets.
- unsigned fieldIndex = cast<ConstantUInt> (idx)->getValue ();
- unsigned memberOffset =
- TD.getStructLayout (StTy)->MemberOffsets[fieldIndex];
- // Emit an ADD to add memberOffset to the basePtr.
- // We might have to copy memberOffset into a register first, if it's
- // big.
- if (memberOffset + 4096 < 8191) {
- BuildMI (*MBB, IP, V8::ADDri, 2,
- nextBasePtrReg).addReg (basePtrReg).addSImm (memberOffset);
- } else {
- unsigned offsetReg = makeAnotherReg (Type::IntTy);
- copyConstantToRegister (MBB, IP,
- ConstantInt::get(Type::IntTy, memberOffset), offsetReg);
- BuildMI (*MBB, IP, V8::ADDrr, 2,
- nextBasePtrReg).addReg (basePtrReg).addReg (offsetReg);
- }
- // The next type is the member of the structure selected by the
- // index.
- Ty = StTy->getElementType (fieldIndex);
- } else if (const SequentialType *SqTy = dyn_cast<SequentialType> (Ty)) {
- // It's an array or pointer access: [ArraySize x ElementType].
- // We want to add basePtrReg to (idxReg * sizeof ElementType). First, we
- // must find the size of the pointed-to type (Not coincidentally, the next
- // type is the type of the elements in the array).
- Ty = SqTy->getElementType ();
- unsigned elementSize = TD.getTypeSize (Ty);
- unsigned idxReg = getReg (idx, MBB, IP);
- unsigned OffsetReg = makeAnotherReg (Type::IntTy);
- unsigned elementSizeReg = makeAnotherReg (Type::UIntTy);
- copyConstantToRegister (MBB, IP,
- ConstantUInt::get(Type::UIntTy, elementSize), elementSizeReg);
- // Emit a SMUL to multiply the register holding the index by
- // elementSize, putting the result in OffsetReg.
- BuildMI (*MBB, IP, V8::SMULrr, 2,
- OffsetReg).addReg (elementSizeReg).addReg (idxReg);
- // Emit an ADD to add OffsetReg to the basePtr.
- BuildMI (*MBB, IP, V8::ADDrr, 2,
- nextBasePtrReg).addReg (basePtrReg).addReg (OffsetReg);
- }
- basePtrReg = nextBasePtrReg;
- }
- // After we have processed all the indices, the result is left in
- // basePtrReg. Move it to the register where we were expected to
- // put the answer.
- BuildMI (BB, V8::ORrr, 1, TargetReg).addReg (V8::G0).addReg (basePtrReg);
-}
-
-void V8ISel::visitGetElementPtrInst (GetElementPtrInst &I) {
- unsigned outputReg = getReg (I);
- emitGEPOperation (BB, BB->end (), I.getOperand (0),
- I.op_begin ()+1, I.op_end (), outputReg);
-}
-
-void V8ISel::emitOp64LibraryCall (MachineBasicBlock *MBB,
- MachineBasicBlock::iterator IP,
- unsigned DestReg,
- const char *FuncName,
- unsigned Op0Reg, unsigned Op1Reg) {
- BuildMI (*MBB, IP, V8::ORrr, 2, V8::O0).addReg (V8::G0).addReg (Op0Reg);
- BuildMI (*MBB, IP, V8::ORrr, 2, V8::O1).addReg (V8::G0).addReg (Op0Reg+1);
- BuildMI (*MBB, IP, V8::ORrr, 2, V8::O2).addReg (V8::G0).addReg (Op1Reg);
- BuildMI (*MBB, IP, V8::ORrr, 2, V8::O3).addReg (V8::G0).addReg (Op1Reg+1);
- BuildMI (*MBB, IP, V8::CALL, 1).addExternalSymbol (FuncName, true);
- BuildMI (*MBB, IP, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (V8::O0);
- BuildMI (*MBB, IP, V8::ORrr, 2, DestReg+1).addReg (V8::G0).addReg (V8::O1);
-}
-
-void V8ISel::emitShift64 (MachineBasicBlock *MBB,
- MachineBasicBlock::iterator IP, Instruction &I,
- unsigned DestReg, unsigned SrcReg,
- unsigned ShiftAmtReg) {
- bool isSigned = I.getType()->isSigned();
-
- switch (I.getOpcode ()) {
- case Instruction::Shr: {
- unsigned CarryReg = makeAnotherReg (Type::IntTy),
- ThirtyTwo = makeAnotherReg (Type::IntTy),
- HalfShiftReg = makeAnotherReg (Type::IntTy),
- NegHalfShiftReg = makeAnotherReg (Type::IntTy),
- TempReg = makeAnotherReg (Type::IntTy);
- unsigned OneShiftOutReg = makeAnotherReg (Type::ULongTy),
- TwoShiftsOutReg = makeAnotherReg (Type::ULongTy);
-
- MachineBasicBlock *thisMBB = BB;
- const BasicBlock *LLVM_BB = BB->getBasicBlock ();
- MachineBasicBlock *shiftMBB = new MachineBasicBlock (LLVM_BB);
- F->getBasicBlockList ().push_back (shiftMBB);
- MachineBasicBlock *oneShiftMBB = new MachineBasicBlock (LLVM_BB);
- F->getBasicBlockList ().push_back (oneShiftMBB);
- MachineBasicBlock *twoShiftsMBB = new MachineBasicBlock (LLVM_BB);
- F->getBasicBlockList ().push_back (twoShiftsMBB);
- MachineBasicBlock *continueMBB = new MachineBasicBlock (LLVM_BB);
- F->getBasicBlockList ().push_back (continueMBB);
-
- // .lshr_begin:
- // ...
- // subcc %g0, ShiftAmtReg, %g0 ! Is ShAmt == 0?
- // be .lshr_continue ! Then don't shift.
- // ba .lshr_shift ! else shift.
-
- BuildMI (BB, V8::SUBCCrr, 2, V8::G0).addReg (V8::G0)
- .addReg (ShiftAmtReg);
- BuildMI (BB, V8::BE, 1).addMBB (continueMBB);
- BuildMI (BB, V8::BA, 1).addMBB (shiftMBB);
-
- // Update machine-CFG edges
- BB->addSuccessor (continueMBB);
- BB->addSuccessor (shiftMBB);
-
- // .lshr_shift: ! [preds: begin]
- // or %g0, 32, ThirtyTwo
- // subcc ThirtyTwo, ShiftAmtReg, HalfShiftReg ! Calculate 32 - shamt
- // bg .lshr_two_shifts ! If >0, b two_shifts
- // ba .lshr_one_shift ! else one_shift.
-
- BB = shiftMBB;
-
- BuildMI (BB, V8::ORri, 2, ThirtyTwo).addReg (V8::G0).addSImm (32);
- BuildMI (BB, V8::SUBCCrr, 2, HalfShiftReg).addReg (ThirtyTwo)
- .addReg (ShiftAmtReg);
- BuildMI (BB, V8::BG, 1).addMBB (twoShiftsMBB);
- BuildMI (BB, V8::BA, 1).addMBB (oneShiftMBB);
-
- // Update machine-CFG edges
- BB->addSuccessor (twoShiftsMBB);
- BB->addSuccessor (oneShiftMBB);
-
- // .lshr_two_shifts: ! [preds: shift]
- // sll SrcReg, HalfShiftReg, CarryReg ! Save the borrows
- // ! <SHIFT> in following is sra if signed, srl if unsigned
- // <SHIFT> SrcReg, ShiftAmtReg, TwoShiftsOutReg ! Shift top half
- // srl SrcReg+1, ShiftAmtReg, TempReg ! Shift bottom half
- // or TempReg, CarryReg, TwoShiftsOutReg+1 ! Restore the borrows
- // ba .lshr_continue
- unsigned ShiftOpcode = (isSigned ? V8::SRArr : V8::SRLrr);
-
- BB = twoShiftsMBB;
-
- BuildMI (BB, V8::SLLrr, 2, CarryReg).addReg (SrcReg)
- .addReg (HalfShiftReg);
- BuildMI (BB, ShiftOpcode, 2, TwoShiftsOutReg).addReg (SrcReg)
- .addReg (ShiftAmtReg);
- BuildMI (BB, V8::SRLrr, 2, TempReg).addReg (SrcReg+1)
- .addReg (ShiftAmtReg);
- BuildMI (BB, V8::ORrr, 2, TwoShiftsOutReg+1).addReg (TempReg)
- .addReg (CarryReg);
- BuildMI (BB, V8::BA, 1).addMBB (continueMBB);
-
- // Update machine-CFG edges
- BB->addSuccessor (continueMBB);
-
- // .lshr_one_shift: ! [preds: shift]
- // ! if unsigned:
- // or %g0, %g0, OneShiftOutReg ! Zero top half
- // ! or, if signed:
- // sra SrcReg, 31, OneShiftOutReg ! Sign-ext top half
- // sub %g0, HalfShiftReg, NegHalfShiftReg ! Make ShiftAmt >0
- // <SHIFT> SrcReg, NegHalfShiftReg, OneShiftOutReg+1 ! Shift bottom half
- // ba .lshr_continue
-
- BB = oneShiftMBB;
-
- if (isSigned)
- BuildMI (BB, V8::SRAri, 2, OneShiftOutReg).addReg (SrcReg).addZImm (31);
- else
- BuildMI (BB, V8::ORrr, 2, OneShiftOutReg).addReg (V8::G0)
- .addReg (V8::G0);
- BuildMI (BB, V8::SUBrr, 2, NegHalfShiftReg).addReg (V8::G0)
- .addReg (HalfShiftReg);
- BuildMI (BB, ShiftOpcode, 2, OneShiftOutReg+1).addReg (SrcReg)
- .addReg (NegHalfShiftReg);
- BuildMI (BB, V8::BA, 1).addMBB (continueMBB);
-
- // Update machine-CFG edges
- BB->addSuccessor (continueMBB);
-
- // .lshr_continue: ! [preds: begin, do_one_shift, do_two_shifts]
- // phi (SrcReg, begin), (TwoShiftsOutReg, two_shifts),
- // (OneShiftOutReg, one_shift), DestReg ! Phi top half...
- // phi (SrcReg+1, begin), (TwoShiftsOutReg+1, two_shifts),
- // (OneShiftOutReg+1, one_shift), DestReg+1 ! And phi bottom half.
-
- BB = continueMBB;
- BuildMI (BB, V8::PHI, 6, DestReg).addReg (SrcReg).addMBB (thisMBB)
- .addReg (TwoShiftsOutReg).addMBB (twoShiftsMBB)
- .addReg (OneShiftOutReg).addMBB (oneShiftMBB);
- BuildMI (BB, V8::PHI, 6, DestReg+1).addReg (SrcReg+1).addMBB (thisMBB)
- .addReg (TwoShiftsOutReg+1).addMBB (twoShiftsMBB)
- .addReg (OneShiftOutReg+1).addMBB (oneShiftMBB);
- return;
- }
- case Instruction::Shl:
- default:
- std::cerr << "Sorry, 64-bit shifts are not yet supported:\n" << I;
- abort ();
- }
-}
-
-void V8ISel::visitBinaryOperator (Instruction &I) {
- unsigned DestReg = getReg (I);
- unsigned Op0Reg = getReg (I.getOperand (0));
- unsigned Op1Reg = getReg (I.getOperand (1));
-
- unsigned Class = getClassB (I.getType());
- unsigned OpCase = ~0;
-
- if (Class > cLong) {
- switch (I.getOpcode ()) {
- case Instruction::Add: OpCase = 0; break;
- case Instruction::Sub: OpCase = 1; break;
- case Instruction::Mul: OpCase = 2; break;
- case Instruction::Div: OpCase = 3; break;
- default: visitInstruction (I); return;
- }
- static unsigned Opcodes[] = { V8::FADDS, V8::FADDD,
- V8::FSUBS, V8::FSUBD,
- V8::FMULS, V8::FMULD,
- V8::FDIVS, V8::FDIVD };
- BuildMI (BB, Opcodes[2*OpCase + (Class - cFloat)], 2, DestReg)
- .addReg (Op0Reg).addReg (Op1Reg);
- return;
- }
-
- unsigned ResultReg = DestReg;
- if (Class != cInt && Class != cLong)
- ResultReg = makeAnotherReg (I.getType ());
-
- if (Class == cLong) {
- const char *FuncName;
- DEBUG (std::cerr << "Class = cLong\n");
- DEBUG (std::cerr << "Op0Reg = " << Op0Reg << ", " << Op0Reg+1 << "\n");
- DEBUG (std::cerr << "Op1Reg = " << Op1Reg << ", " << Op1Reg+1 << "\n");
- DEBUG (std::cerr << "ResultReg = " << ResultReg << ", " << ResultReg+1 << "\n");
- DEBUG (std::cerr << "DestReg = " << DestReg << ", " << DestReg+1 << "\n");
- switch (I.getOpcode ()) {
- case Instruction::Add:
- BuildMI (BB, V8::ADDCCrr, 2, ResultReg+1).addReg (Op0Reg+1)
- .addReg (Op1Reg+1);
- BuildMI (BB, V8::ADDXrr, 2, ResultReg).addReg (Op0Reg).addReg (Op1Reg);
- return;
- case Instruction::Sub:
- BuildMI (BB, V8::SUBCCrr, 2, ResultReg+1).addReg (Op0Reg+1)
- .addReg (Op1Reg+1);
- BuildMI (BB, V8::SUBXrr, 2, ResultReg).addReg (Op0Reg).addReg (Op1Reg);
- return;
- case Instruction::Mul:
- FuncName = I.getType ()->isSigned () ? "__mul64" : "__umul64";
- emitOp64LibraryCall (BB, BB->end (), DestReg, FuncName, Op0Reg, Op1Reg);
- return;
- case Instruction::Div:
- FuncName = I.getType ()->isSigned () ? "__div64" : "__udiv64";
- emitOp64LibraryCall (BB, BB->end (), DestReg, FuncName, Op0Reg, Op1Reg);
- return;
- case Instruction::Rem:
- FuncName = I.getType ()->isSigned () ? "__rem64" : "__urem64";
- emitOp64LibraryCall (BB, BB->end (), DestReg, FuncName, Op0Reg, Op1Reg);
- return;
- case Instruction::Shl:
- case Instruction::Shr:
- emitShift64 (BB, BB->end (), I, DestReg, Op0Reg, Op1Reg);
- return;
- }
- }
-
- // FIXME: support long, ulong.
- switch (I.getOpcode ()) {
- case Instruction::Add: OpCase = 0; break;
- case Instruction::Sub: OpCase = 1; break;
- case Instruction::Mul: OpCase = 2; break;
- case Instruction::And: OpCase = 3; break;
- case Instruction::Or: OpCase = 4; break;
- case Instruction::Xor: OpCase = 5; break;
- case Instruction::Shl: OpCase = 6; break;
- case Instruction::Shr: OpCase = 7+I.getType()->isSigned(); break;
-
- case Instruction::Div:
- case Instruction::Rem: {
- unsigned Dest = ResultReg;
- if (I.getOpcode() == Instruction::Rem)
- Dest = makeAnotherReg(I.getType());
-
- // FIXME: this is probably only right for 32 bit operands.
- if (I.getType ()->isSigned()) {
- unsigned Tmp = makeAnotherReg (I.getType ());
- // Sign extend into the Y register
- BuildMI (BB, V8::SRAri, 2, Tmp).addReg (Op0Reg).addZImm (31);
- BuildMI (BB, V8::WRrr, 2, V8::Y).addReg (Tmp).addReg (V8::G0);
- BuildMI (BB, V8::SDIVrr, 2, Dest).addReg (Op0Reg).addReg (Op1Reg);
- } else {
- // Zero extend into the Y register, ie, just set it to zero
- BuildMI (BB, V8::WRrr, 2, V8::Y).addReg (V8::G0).addReg (V8::G0);
- BuildMI (BB, V8::UDIVrr, 2, Dest).addReg (Op0Reg).addReg (Op1Reg);
- }
-
- if (I.getOpcode() == Instruction::Rem) {
- unsigned Tmp = makeAnotherReg (I.getType ());
- BuildMI (BB, V8::SMULrr, 2, Tmp).addReg(Dest).addReg(Op1Reg);
- BuildMI (BB, V8::SUBrr, 2, ResultReg).addReg(Op0Reg).addReg(Tmp);
- }
- break;
- }
- default:
- visitInstruction (I);
- return;
- }
-
- static const unsigned Opcodes[] = {
- V8::ADDrr, V8::SUBrr, V8::SMULrr, V8::ANDrr, V8::ORrr, V8::XORrr,
- V8::SLLrr, V8::SRLrr, V8::SRArr
- };
- if (OpCase != ~0U) {
- BuildMI (BB, Opcodes[OpCase], 2, ResultReg).addReg (Op0Reg).addReg (Op1Reg);
- }
-
- switch (getClassB (I.getType ())) {
- case cByte:
- if (I.getType ()->isSigned ()) { // add byte
- BuildMI (BB, V8::ANDri, 2, DestReg).addReg (ResultReg).addZImm (0xff);
- } else { // add ubyte
- unsigned TmpReg = makeAnotherReg (I.getType ());
- BuildMI (BB, V8::SLLri, 2, TmpReg).addReg (ResultReg).addZImm (24);
- BuildMI (BB, V8::SRAri, 2, DestReg).addReg (TmpReg).addZImm (24);
- }
- break;
- case cShort:
- if (I.getType ()->isSigned ()) { // add short
- unsigned TmpReg = makeAnotherReg (I.getType ());
- BuildMI (BB, V8::SLLri, 2, TmpReg).addReg (ResultReg).addZImm (16);
- BuildMI (BB, V8::SRAri, 2, DestReg).addReg (TmpReg).addZImm (16);
- } else { // add ushort
- unsigned TmpReg = makeAnotherReg (I.getType ());
- BuildMI (BB, V8::SLLri, 2, TmpReg).addReg (ResultReg).addZImm (16);
- BuildMI (BB, V8::SRLri, 2, DestReg).addReg (TmpReg).addZImm (16);
- }
- break;
- case cInt:
- // Nothing to do here.
- break;
- case cLong:
- // Only support and, or, xor here - others taken care of above.
- if (OpCase < 3 || OpCase > 5) {
- visitInstruction (I);
- return;
- }
- // Do the other half of the value:
- BuildMI (BB, Opcodes[OpCase], 2, ResultReg+1).addReg (Op0Reg+1)
- .addReg (Op1Reg+1);
- break;
- default:
- visitInstruction (I);
- }
-}
-
-void V8ISel::visitSetCondInst(SetCondInst &I) {
- unsigned Op0Reg = getReg (I.getOperand (0));
- unsigned Op1Reg = getReg (I.getOperand (1));
- unsigned DestReg = getReg (I);
- const Type *Ty = I.getOperand (0)->getType ();
-
- // Compare the two values.
- if (getClass (Ty) < cLong) {
- BuildMI(BB, V8::SUBCCrr, 2, V8::G0).addReg(Op0Reg).addReg(Op1Reg);
- } else if (getClass (Ty) == cLong) {
- switch (I.getOpcode()) {
- default: assert(0 && "Unknown setcc instruction!");
- case Instruction::SetEQ:
- case Instruction::SetNE: {
- unsigned TempReg0 = makeAnotherReg (Type::IntTy),
- TempReg1 = makeAnotherReg (Type::IntTy),
- TempReg2 = makeAnotherReg (Type::IntTy),
- TempReg3 = makeAnotherReg (Type::IntTy);
- MachineOpCode Opcode;
- int Immed;
- // These guys are special - no branches needed!
- BuildMI (BB, V8::XORrr, 2, TempReg0).addReg (Op0Reg+1).addReg (Op1Reg+1);
- BuildMI (BB, V8::XORrr, 2, TempReg1).addReg (Op0Reg).addReg (Op1Reg);
- BuildMI (BB, V8::SUBCCrr, 2, V8::G0).addReg (V8::G0).addReg (TempReg1);
- Opcode = I.getOpcode() == Instruction::SetEQ ? V8::SUBXri : V8::ADDXri;
- Immed = I.getOpcode() == Instruction::SetEQ ? -1 : 0;
- BuildMI (BB, Opcode, 2, TempReg2).addReg (V8::G0).addSImm (Immed);
- BuildMI (BB, V8::SUBCCrr, 2, V8::G0).addReg (V8::G0).addReg (TempReg0);
- BuildMI (BB, Opcode, 2, TempReg3).addReg (V8::G0).addSImm (Immed);
- Opcode = I.getOpcode() == Instruction::SetEQ ? V8::ANDrr : V8::ORrr;
- BuildMI (BB, Opcode, 2, DestReg).addReg (TempReg2).addReg (TempReg3);
- return;
- }
- case Instruction::SetLT:
- case Instruction::SetGE:
- BuildMI (BB, V8::SUBCCrr, 2, V8::G0).addReg (Op0Reg+1).addReg (Op1Reg+1);
- BuildMI (BB, V8::SUBXCCrr, 2, V8::G0).addReg (Op0Reg).addReg (Op1Reg);
- break;
- case Instruction::SetGT:
- case Instruction::SetLE:
- BuildMI (BB, V8::SUBCCri, 2, V8::G0).addReg (V8::G0).addSImm (1);
- BuildMI (BB, V8::SUBXCCrr, 2, V8::G0).addReg (Op0Reg+1).addReg (Op1Reg+1);
- BuildMI (BB, V8::SUBXCCrr, 2, V8::G0).addReg (Op0Reg).addReg (Op1Reg);
- break;
- }
- } else if (getClass (Ty) == cFloat) {
- BuildMI(BB, V8::FCMPS, 2).addReg(Op0Reg).addReg(Op1Reg);
- } else if (getClass (Ty) == cDouble) {
- BuildMI(BB, V8::FCMPD, 2).addReg(Op0Reg).addReg(Op1Reg);
- }
-
- unsigned BranchIdx;
- switch (I.getOpcode()) {
- default: assert(0 && "Unknown setcc instruction!");
- case Instruction::SetEQ: BranchIdx = 0; break;
- case Instruction::SetNE: BranchIdx = 1; break;
- case Instruction::SetLT: BranchIdx = 2; break;
- case Instruction::SetGT: BranchIdx = 3; break;
- case Instruction::SetLE: BranchIdx = 4; break;
- case Instruction::SetGE: BranchIdx = 5; break;
- }
-
- unsigned Column = 0;
- if (Ty->isSigned() && !Ty->isFloatingPoint()) Column = 1;
- if (Ty->isFloatingPoint()) Column = 2;
- static unsigned OpcodeTab[3*6] = {
- // LLVM SparcV8
- // unsigned signed fp
- V8::BE, V8::BE, V8::FBE, // seteq = be be fbe
- V8::BNE, V8::BNE, V8::FBNE, // setne = bne bne fbne
- V8::BCS, V8::BL, V8::FBL, // setlt = bcs bl fbl
- V8::BGU, V8::BG, V8::FBG, // setgt = bgu bg fbg
- V8::BLEU, V8::BLE, V8::FBLE, // setle = bleu ble fble
- V8::BCC, V8::BGE, V8::FBGE // setge = bcc bge fbge
- };
- unsigned Opcode = OpcodeTab[3*BranchIdx + Column];
-
- MachineBasicBlock *thisMBB = BB;
- const BasicBlock *LLVM_BB = BB->getBasicBlock ();
- // thisMBB:
- // ...
- // subcc %reg0, %reg1, %g0
- // bCC copy1MBB
- // ba copy0MBB
-
- // FIXME: we wouldn't need copy0MBB (we could fold it into thisMBB)
- // if we could insert other, non-terminator instructions after the
- // bCC. But MBB->getFirstTerminator() can't understand this.
- MachineBasicBlock *copy1MBB = new MachineBasicBlock (LLVM_BB);
- F->getBasicBlockList ().push_back (copy1MBB);
- BuildMI (BB, Opcode, 1).addMBB (copy1MBB);
- MachineBasicBlock *copy0MBB = new MachineBasicBlock (LLVM_BB);
- F->getBasicBlockList ().push_back (copy0MBB);
- BuildMI (BB, V8::BA, 1).addMBB (copy0MBB);
- // Update machine-CFG edges
- BB->addSuccessor (copy1MBB);
- BB->addSuccessor (copy0MBB);
-
- // copy0MBB:
- // %FalseValue = or %G0, 0
- // ba sinkMBB
- BB = copy0MBB;
- unsigned FalseValue = makeAnotherReg (I.getType ());
- BuildMI (BB, V8::ORri, 2, FalseValue).addReg (V8::G0).addZImm (0);
- MachineBasicBlock *sinkMBB = new MachineBasicBlock (LLVM_BB);
- F->getBasicBlockList ().push_back (sinkMBB);
- BuildMI (BB, V8::BA, 1).addMBB (sinkMBB);
- // Update machine-CFG edges
- BB->addSuccessor (sinkMBB);
-
- DEBUG (std::cerr << "thisMBB is at " << (void*)thisMBB << "\n");
- DEBUG (std::cerr << "copy1MBB is at " << (void*)copy1MBB << "\n");
- DEBUG (std::cerr << "copy0MBB is at " << (void*)copy0MBB << "\n");
- DEBUG (std::cerr << "sinkMBB is at " << (void*)sinkMBB << "\n");
-
- // copy1MBB:
- // %TrueValue = or %G0, 1
- // ba sinkMBB
- BB = copy1MBB;
- unsigned TrueValue = makeAnotherReg (I.getType ());
- BuildMI (BB, V8::ORri, 2, TrueValue).addReg (V8::G0).addZImm (1);
- BuildMI (BB, V8::BA, 1).addMBB (sinkMBB);
- // Update machine-CFG edges
- BB->addSuccessor (sinkMBB);
-
- // sinkMBB:
- // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, copy1MBB ]
- // ...
- BB = sinkMBB;
- BuildMI (BB, V8::PHI, 4, DestReg).addReg (FalseValue)
- .addMBB (copy0MBB).addReg (TrueValue).addMBB (copy1MBB);
-}
-
-void V8ISel::visitAllocaInst(AllocaInst &I) {
- // Find the data size of the alloca inst's getAllocatedType.
- const Type *Ty = I.getAllocatedType();
- unsigned TySize = TM.getTargetData().getTypeSize(Ty);
-
- unsigned ArraySizeReg = getReg (I.getArraySize ());
- unsigned TySizeReg = getReg (ConstantUInt::get (Type::UIntTy, TySize));
- unsigned TmpReg1 = makeAnotherReg (Type::UIntTy);
- unsigned TmpReg2 = makeAnotherReg (Type::UIntTy);
- unsigned StackAdjReg = makeAnotherReg (Type::UIntTy);
-
- // StackAdjReg = (ArraySize * TySize) rounded up to nearest
- // doubleword boundary.
- BuildMI (BB, V8::UMULrr, 2, TmpReg1).addReg (ArraySizeReg).addReg (TySizeReg);
-
- // Round up TmpReg1 to nearest doubleword boundary:
- BuildMI (BB, V8::ADDri, 2, TmpReg2).addReg (TmpReg1).addSImm (7);
- BuildMI (BB, V8::ANDri, 2, StackAdjReg).addReg (TmpReg2).addSImm (-8);
-
- // Subtract size from stack pointer, thereby allocating some space.
- BuildMI (BB, V8::SUBrr, 2, V8::SP).addReg (V8::SP).addReg (StackAdjReg);
-
- // Put a pointer to the space into the result register, by copying
- // the stack pointer.
- BuildMI (BB, V8::ADDri, 2, getReg(I)).addReg (V8::SP).addSImm (96);
-
- // Inform the Frame Information that we have just allocated a variable-sized
- // object.
- F->getFrameInfo()->CreateVariableSizedObject();
-}
-
-/// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the
-/// function, lowering any calls to unknown intrinsic functions into the
-/// equivalent LLVM code.
-void V8ISel::LowerUnknownIntrinsicFunctionCalls(Function &F) {
- for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
- for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; )
- if (CallInst *CI = dyn_cast<CallInst>(I++))
- if (Function *F = CI->getCalledFunction())
- switch (F->getIntrinsicID()) {
- case Intrinsic::vastart:
- case Intrinsic::vacopy:
- case Intrinsic::vaend:
- // We directly implement these intrinsics
- case Intrinsic::not_intrinsic: break;
- default:
- // All other intrinsic calls we must lower.
- Instruction *Before = CI->getPrev();
- TM.getIntrinsicLowering().LowerIntrinsicCall(CI);
- if (Before) { // Move iterator to instruction after call
- I = Before; ++I;
- } else {
- I = BB->begin();
- }
- }
-}
-
-
-void V8ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) {
- switch (ID) {
- default:
- std::cerr << "Sorry, unknown intrinsic function call:\n" << CI; abort ();
-
- case Intrinsic::vastart: {
- // Add the VarArgsOffset to the frame pointer, and copy it to the result.
- unsigned DestReg = getReg (CI);
- BuildMI (BB, V8::ADDri, 2, DestReg).addReg (V8::FP).addSImm (VarArgsOffset);
- return;
- }
-
- case Intrinsic::vaend:
- // va_end is a no-op on SparcV8.
- return;
-
- case Intrinsic::vacopy: {
- // Copy the va_list ptr (arg1) to the result.
- unsigned DestReg = getReg (CI), SrcReg = getReg (CI.getOperand (1));
- BuildMI (BB, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg);
- return;
- }
- }
-}
-
-void V8ISel::visitVANextInst (VANextInst &I) {
- // Add the type size to the vararg pointer (arg0).
- unsigned DestReg = getReg (I);
- unsigned SrcReg = getReg (I.getOperand (0));
- unsigned TySize = TM.getTargetData ().getTypeSize (I.getArgType ());
- BuildMI (BB, V8::ADDri, 2, DestReg).addReg (SrcReg).addSImm (TySize);
-}
-
-void V8ISel::visitVAArgInst (VAArgInst &I) {
- unsigned VAList = getReg (I.getOperand (0));
- unsigned DestReg = getReg (I);
-
- switch (I.getType ()->getTypeID ()) {
- case Type::PointerTyID:
- case Type::UIntTyID:
- case Type::IntTyID:
- BuildMI (BB, V8::LD, 2, DestReg).addReg (VAList).addSImm (0);
- return;
-
- case Type::ULongTyID:
- case Type::LongTyID:
- BuildMI (BB, V8::LD, 2, DestReg).addReg (VAList).addSImm (0);
- BuildMI (BB, V8::LD, 2, DestReg+1).addReg (VAList).addSImm (4);
- return;
-
- case Type::DoubleTyID: {
- unsigned DblAlign = TM.getTargetData().getDoubleAlignment();
- unsigned TempReg = makeAnotherReg (Type::IntTy);
- unsigned TempReg2 = makeAnotherReg (Type::IntTy);
- int FI = F->getFrameInfo()->CreateStackObject(8, DblAlign);
- BuildMI (BB, V8::LD, 2, TempReg).addReg (VAList).addSImm (0);
- BuildMI (BB, V8::LD, 2, TempReg2).addReg (VAList).addSImm (4);
- BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (0).addReg (TempReg);
- BuildMI (BB, V8::ST, 3).addFrameIndex (FI).addSImm (4).addReg (TempReg2);
- BuildMI (BB, V8::LDDFri, 2, DestReg).addFrameIndex (FI).addSImm (0);
- return;
- }
-
- default:
- std::cerr << "Sorry, vaarg instruction of this type still unsupported:\n"
- << I;
- abort ();
- return;
- }
-}
diff --git a/llvm/lib/Target/SparcV8/SparcV8InstrFormats.td b/llvm/lib/Target/SparcV8/SparcV8InstrFormats.td
deleted file mode 100644
index 14c10fb23b5b..000000000000
--- a/llvm/lib/Target/SparcV8/SparcV8InstrFormats.td
+++ /dev/null
@@ -1,95 +0,0 @@
-//===- SparcV8InstrFormats.td - SparcV8 Instr Formats ------*- tablegen -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// Format #2 instruction classes in the SparcV8
-//===----------------------------------------------------------------------===//
-
-class F2 : InstV8 { // Format 2 instructions
- bits<3> op2;
- bits<22> imm22;
- let op = 0; // op = 0
- let Inst{24-22} = op2;
- let Inst{21-0} = imm22;
-}
-
-// Specific F2 classes: SparcV8 manual, page 44
-//
-class F2_1<bits<3> op2Val, string name> : F2 {
- bits<5> rd;
-
- let op2 = op2Val;
- let Name = name;
-
- let Inst{29-25} = rd;
-}
-
-class F2_2<bits<4> condVal, bits<3> op2Val, string name> : F2 {
- bits<4> cond;
- bit annul = 0; // currently unused
-
- let cond = condVal;
- let op2 = op2Val;
- let Name = name;
-
- let Inst{29} = annul;
- let Inst{28-25} = cond;
-}
-
-//===----------------------------------------------------------------------===//
-// Format #3 instruction classes in the SparcV8
-//===----------------------------------------------------------------------===//
-
-class F3 : InstV8 {
- bits<5> rd;
- bits<6> op3;
- bits<5> rs1;
- let op{1} = 1; // Op = 2 or 3
- let Inst{29-25} = rd;
- let Inst{24-19} = op3;
- let Inst{18-14} = rs1;
-}
-
-// Specific F3 classes: SparcV8 manual, page 44
-//
-class F3_1<bits<2> opVal, bits<6> op3val, string name> : F3 {
- bits<8> asi = 0; // asi not currently used in SparcV8
- bits<5> rs2;
-
- let op = opVal;
- let op3 = op3val;
- let Name = name;
-
- let Inst{13} = 0; // i field = 0
- let Inst{12-5} = asi; // address space identifier
- let Inst{4-0} = rs2;
-}
-
-class F3_2<bits<2> opVal, bits<6> op3val, string name> : F3 {
- bits<13> simm13;
-
- let op = opVal;
- let op3 = op3val;
- let Name = name;
-
- let Inst{13} = 1; // i field = 1
- let Inst{12-0} = simm13;
-}
-
-// floating-point
-class F3_3<bits<2> opVal, bits<6> op3val, bits<9> opfval, string name> : F3 {
- bits<5> rs2;
-
- let op = opVal;
- let op3 = op3val;
- let Name = name;
-
- let Inst{13-5} = opfval; // fp opcode
- let Inst{4-0} = rs2;
-}
diff --git a/llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp b/llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp
deleted file mode 100644
index 01c513ac5ed2..000000000000
--- a/llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-//===- SparcV8InstrInfo.cpp - SparcV8 Instruction Information ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the SparcV8 implementation of the TargetInstrInfo class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SparcV8InstrInfo.h"
-#include "SparcV8.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "SparcV8GenInstrInfo.inc"
-using namespace llvm;
-
-SparcV8InstrInfo::SparcV8InstrInfo()
- : TargetInstrInfo(SparcV8Insts, sizeof(SparcV8Insts)/sizeof(SparcV8Insts[0])){
-}
-
-/// Return true if the instruction is a register to register move and
-/// leave the source and dest operands in the passed parameters.
-///
-bool SparcV8InstrInfo::isMoveInstr(const MachineInstr &MI,
- unsigned &SrcReg, unsigned &DstReg) const {
- if (MI.getOpcode() == V8::ORrr) {
- if (MI.getOperand(1).getReg() == V8::G0) { // X = or G0, Y -> X = Y
- DstReg = MI.getOperand(0).getReg();
- SrcReg = MI.getOperand(2).getReg();
- return true;
- }
- } else if (MI.getOpcode() == V8::FMOVS || MI.getOpcode() == V8::FpMOVD) {
- SrcReg = MI.getOperand(1).getReg();
- DstReg = MI.getOperand(0).getReg();
- return true;
- }
- return false;
-}
diff --git a/llvm/lib/Target/SparcV8/SparcV8InstrInfo.h b/llvm/lib/Target/SparcV8/SparcV8InstrInfo.h
deleted file mode 100644
index 9c7838dfdd7e..000000000000
--- a/llvm/lib/Target/SparcV8/SparcV8InstrInfo.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//===- SparcV8InstrInfo.h - SparcV8 Instruction Information -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the SparcV8 implementation of the TargetInstrInfo class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SPARCV8INSTRUCTIONINFO_H
-#define SPARCV8INSTRUCTIONINFO_H
-
-#include "llvm/Target/TargetInstrInfo.h"
-#include "SparcV8RegisterInfo.h"
-
-namespace llvm {
-
-/// V8II - This namespace holds all of the target specific flags that
-/// instruction info tracks.
-///
-namespace V8II {
- enum {
- Pseudo = (1<<0),
- Load = (1<<1),
- Store = (1<<2),
- DelaySlot = (1<<3)
- };
-};
-
-class SparcV8InstrInfo : public TargetInstrInfo {
- const SparcV8RegisterInfo RI;
-public:
- SparcV8InstrInfo();
-
- /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
- /// such, whenever a client has an instance of instruction info, it should
- /// always be able to get register info as well (through this method).
- ///
- virtual const MRegisterInfo &getRegisterInfo() const { return RI; }
-
- /// Return true if the instruction is a register to register move and
- /// leave the source and dest operands in the passed parameters.
- ///
- virtual bool isMoveInstr(const MachineInstr &MI,
- unsigned &SrcReg, unsigned &DstReg) const;
-};
-
-}
-
-#endif
diff --git a/llvm/lib/Target/SparcV8/SparcV8InstrInfo.td b/llvm/lib/Target/SparcV8/SparcV8InstrInfo.td
deleted file mode 100644
index a79892619e96..000000000000
--- a/llvm/lib/Target/SparcV8/SparcV8InstrInfo.td
+++ /dev/null
@@ -1,292 +0,0 @@
-//===- SparcV8Instrs.td - Target Description for SparcV8 Target -----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file describes the SparcV8 instructions in TableGen format.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// Instruction format superclass
-//===----------------------------------------------------------------------===//
-
-class InstV8 : Instruction { // SparcV8 instruction baseline
- field bits<32> Inst;
-
- let Namespace = "V8";
-
- bits<2> op;
- let Inst{31-30} = op; // Top two bits are the 'op' field
-
- // Bit attributes specific to SparcV8 instructions
- bit isPasi = 0; // Does this instruction affect an alternate addr space?
- bit isPrivileged = 0; // Is this a privileged instruction?
-}
-
-include "SparcV8InstrFormats.td"
-
-//===----------------------------------------------------------------------===//
-// Instructions
-//===----------------------------------------------------------------------===//
-
-// Pseudo instructions.
-class PseudoInstV8<string nm> : InstV8 {
- let Name = nm;
-}
-def PHI : PseudoInstV8<"PHI">;
-def ADJCALLSTACKDOWN : PseudoInstV8<"ADJCALLSTACKDOWN">;
-def ADJCALLSTACKUP : PseudoInstV8<"ADJCALLSTACKUP">;
-def IMPLICIT_USE : PseudoInstV8<"IMPLICIT_USE">;
-def IMPLICIT_DEF : PseudoInstV8<"IMPLICIT_DEF">;
-def FpMOVD : PseudoInstV8<"FpMOVD">; // pseudo 64-bit double move
-
-// Section A.3 - Synthetic Instructions, p. 85
-// special cases of JMPL:
-let isReturn = 1, isTerminator = 1, hasDelaySlot = 1 in {
- let rd = I7.Num, rs1 = G0.Num, simm13 = 8 in
- def RET : F3_2<2, 0b111000, "ret">;
- let rd = O7.Num, rs1 = G0.Num, simm13 = 8 in
- def RETL: F3_2<2, 0b111000, "retl">;
-}
-// CMP is a special case of SUBCC where destination is ignored, by setting it to
-// %g0 (hardwired zero).
-// FIXME: should keep track of the fact that it defs the integer condition codes
-let rd = 0 in
- def CMPri: F3_2<2, 0b010100, "cmp">;
-
-// Section B.1 - Load Integer Instructions, p. 90
-def LDSB: F3_2<3, 0b001001, "ldsb">;
-def LDSH: F3_2<3, 0b001010, "ldsh">;
-def LDUB: F3_2<3, 0b000001, "ldub">;
-def LDUH: F3_2<3, 0b000010, "lduh">;
-def LD : F3_2<3, 0b000000, "ld">;
-def LDD : F3_2<3, 0b000011, "ldd">;
-
-// Section B.2 - Load Floating-point Instructions, p. 92
-def LDFrr : F3_1<3, 0b100000, "ld">;
-def LDFri : F3_2<3, 0b100000, "ld">;
-def LDDFrr : F3_1<3, 0b100011, "ldd">;
-def LDDFri : F3_2<3, 0b100011, "ldd">;
-def LDFSRrr: F3_1<3, 0b100001, "ld">;
-def LDFSRri: F3_2<3, 0b100001, "ld">;
-
-// Section B.4 - Store Integer Instructions, p. 95
-def STB : F3_2<3, 0b000101, "stb">;
-def STH : F3_2<3, 0b000110, "sth">;
-def ST : F3_2<3, 0b000100, "st">;
-def STD : F3_2<3, 0b000111, "std">;
-
-// Section B.5 - Store Floating-point Instructions, p. 97
-def STFrr : F3_1<3, 0b100100, "st">;
-def STFri : F3_2<3, 0b100100, "st">;
-def STDFrr : F3_1<3, 0b100111, "std">;
-def STDFri : F3_2<3, 0b100111, "std">;
-def STFSRrr : F3_1<3, 0b100101, "st">;
-def STFSRri : F3_2<3, 0b100101, "st">;
-def STDFQrr : F3_1<3, 0b100110, "std">;
-def STDFQri : F3_2<3, 0b100110, "std">;
-
-// Section B.9 - SETHI Instruction, p. 104
-def SETHIi: F2_1<0b100, "sethi">;
-
-// Section B.10 - NOP Instruction, p. 105
-// (It's a special case of SETHI)
-let rd = 0, imm22 = 0 in
- def NOP : F2_1<0b100, "nop">;
-
-// Section B.11 - Logical Instructions, p. 106
-def ANDrr : F3_1<2, 0b000001, "and">;
-def ANDri : F3_2<2, 0b000001, "and">;
-def ANDCCrr : F3_1<2, 0b010001, "andcc">;
-def ANDCCri : F3_2<2, 0b010001, "andcc">;
-def ANDNrr : F3_1<2, 0b000101, "andn">;
-def ANDNri : F3_2<2, 0b000101, "andn">;
-def ANDNCCrr: F3_1<2, 0b010101, "andncc">;
-def ANDNCCri: F3_2<2, 0b010101, "andncc">;
-def ORrr : F3_1<2, 0b000010, "or">;
-def ORri : F3_2<2, 0b000010, "or">;
-def ORCCrr : F3_1<2, 0b010010, "orcc">;
-def ORCCri : F3_2<2, 0b010010, "orcc">;
-def ORNrr : F3_1<2, 0b000110, "orn">;
-def ORNri : F3_2<2, 0b000110, "orn">;
-def ORNCCrr : F3_1<2, 0b010110, "orncc">;
-def ORNCCri : F3_2<2, 0b010110, "orncc">;
-def XORrr : F3_1<2, 0b000011, "xor">;
-def XORri : F3_2<2, 0b000011, "xor">;
-def XORCCrr : F3_1<2, 0b010011, "xorcc">;
-def XORCCri : F3_2<2, 0b010011, "xorcc">;
-def XNORrr : F3_1<2, 0b000111, "xnor">;
-def XNORri : F3_2<2, 0b000111, "xnor">;
-def XNORCCrr: F3_1<2, 0b010111, "xnorcc">;
-def XNORCCri: F3_2<2, 0b010111, "xnorcc">;
-
-// Section B.12 - Shift Instructions, p. 107
-def SLLrr : F3_1<2, 0b100101, "sll">;
-def SLLri : F3_2<2, 0b100101, "sll">;
-def SRLrr : F3_1<2, 0b100110, "srl">;
-def SRLri : F3_2<2, 0b100110, "srl">;
-def SRArr : F3_1<2, 0b100111, "sra">;
-def SRAri : F3_2<2, 0b100111, "sra">;
-
-// Section B.13 - Add Instructions, p. 108
-def ADDrr : F3_1<2, 0b000000, "add">;
-def ADDri : F3_2<2, 0b000000, "add">;
-def ADDCCrr : F3_1<2, 0b010000, "addcc">;
-def ADDCCri : F3_2<2, 0b010000, "addcc">;
-def ADDXrr : F3_1<2, 0b001000, "addx">;
-def ADDXri : F3_2<2, 0b001000, "addx">;
-def ADDXCCrr: F3_1<2, 0b011000, "addxcc">;
-def ADDXCCri: F3_2<2, 0b011000, "addxcc">;
-
-// Section B.15 - Subtract Instructions, p. 110
-def SUBrr : F3_1<2, 0b000100, "sub">;
-def SUBri : F3_2<2, 0b000100, "sub">;
-def SUBCCrr : F3_1<2, 0b010100, "subcc">;
-def SUBCCri : F3_2<2, 0b010100, "subcc">;
-def SUBXrr : F3_1<2, 0b001100, "subx">;
-def SUBXri : F3_2<2, 0b001100, "subx">;
-def SUBXCCrr: F3_1<2, 0b011100, "subxcc">;
-def SUBXCCri: F3_2<2, 0b011100, "subxcc">;
-
-// Section B.18 - Multiply Instructions, p. 113
-def UMULrr : F3_1<2, 0b001010, "umul">;
-def SMULrr : F3_1<2, 0b001011, "smul">;
-
-// Section B.19 - Divide Instructions, p. 115
-def UDIVrr : F3_1<2, 0b001110, "udiv">;
-def UDIVri : F3_2<2, 0b001110, "udiv">;
-def SDIVrr : F3_1<2, 0b001111, "sdiv">;
-def SDIVri : F3_2<2, 0b001111, "sdiv">;
-def UDIVCCrr : F3_1<2, 0b011110, "udivcc">;
-def UDIVCCri : F3_2<2, 0b011110, "udivcc">;
-def SDIVCCrr : F3_1<2, 0b011111, "sdivcc">;
-def SDIVCCri : F3_2<2, 0b011111, "sdivcc">;
-
-// Section B.20 - SAVE and RESTORE, p. 117
-def SAVErr : F3_1<2, 0b111100, "save">; // save r, r, r
-def SAVEri : F3_2<2, 0b111100, "save">; // save r, i, r
-def RESTORErr : F3_1<2, 0b111101, "restore">; // restore r, r, r
-def RESTOREri : F3_2<2, 0b111101, "restore">; // restore r, i, r
-
-// Section B.21 - Branch on Integer Condition Codes Instructions, p. 119
-
-// conditional branch class:
-class BranchV8<bits<4> cc, string nm> : F2_2<cc, 0b010, nm> {
- let isBranch = 1;
- let isTerminator = 1;
- let hasDelaySlot = 1;
-}
-
-let isBarrier = 1 in
- def BA : BranchV8<0b1000, "ba">;
-def BN : BranchV8<0b0000, "bn">;
-def BNE : BranchV8<0b1001, "bne">;
-def BE : BranchV8<0b0001, "be">;
-def BG : BranchV8<0b1010, "bg">;
-def BLE : BranchV8<0b0010, "ble">;
-def BGE : BranchV8<0b1011, "bge">;
-def BL : BranchV8<0b0011, "bl">;
-def BGU : BranchV8<0b1100, "bgu">;
-def BLEU : BranchV8<0b0100, "bleu">;
-def BCC : BranchV8<0b1101, "bcc">;
-def BCS : BranchV8<0b0101, "bcs">;
-
-// Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121
-
-// floating-point conditional branch class:
-class FPBranchV8<bits<4> cc, string nm> : F2_2<cc, 0b110, nm> {
- let isBranch = 1;
- let isTerminator = 1;
- let hasDelaySlot = 1;
-}
-
-def FBA : FPBranchV8<0b1000, "fba">;
-def FBN : FPBranchV8<0b0000, "fbn">;
-def FBU : FPBranchV8<0b0111, "fbu">;
-def FBG : FPBranchV8<0b0110, "fbg">;
-def FBUG : FPBranchV8<0b0101, "fbug">;
-def FBL : FPBranchV8<0b0100, "fbl">;
-def FBUL : FPBranchV8<0b0011, "fbul">;
-def FBLG : FPBranchV8<0b0010, "fblg">;
-def FBNE : FPBranchV8<0b0001, "fbne">;
-def FBE : FPBranchV8<0b1001, "fbe">;
-def FBUE : FPBranchV8<0b1010, "fbue">;
-def FBGE : FPBranchV8<0b1011, "fbge">;
-def FBUGE: FPBranchV8<0b1100, "fbuge">;
-def FBLE : FPBranchV8<0b1101, "fble">;
-def FBULE: FPBranchV8<0b1110, "fbule">;
-def FBO : FPBranchV8<0b1111, "fbo">;
-
-
-
-// Section B.24 - Call and Link Instruction, p. 125
-// This is the only Format 1 instruction
-let Uses = [O0, O1, O2, O3, O4, O5], hasDelaySlot = 1, isCall = 1 in {
- // pc-relative call:
- let Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7,
- D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in
- def CALL : InstV8 {
- bits<30> disp;
- let op = 1;
- let Inst{29-0} = disp;
- let Name = "call";
- }
-
- // indirect call (O7 is an EXPLICIT def in indirect calls, so it cannot also
- // be an implicit def):
- let Defs = [O0, O1, O2, O3, O4, O5, G1, G2, G3, G4, G5, G6, G7,
- D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in
- def JMPLrr : F3_1<2, 0b111000, "jmpl">; // jmpl [rs1+rs2], rd
-}
-
-// Section B.29 - Write State Register Instructions
-def WRrr : F3_1<2, 0b110000, "wr">; // wr rs1, rs2, rd
-def WRri : F3_2<2, 0b110000, "wr">; // wr rs1, imm, rd
-
-// Convert Integer to Floating-point Instructions, p. 141
-def FITOS : F3_3<2, 0b110100, 0b011000100, "fitos">;
-def FITOD : F3_3<2, 0b110100, 0b011001000, "fitod">;
-
-// Convert Floating-point to Integer Instructions, p. 142
-def FSTOI : F3_3<2, 0b110100, 0b011010001, "fstoi">;
-def FDTOI : F3_3<2, 0b110100, 0b011010010, "fdtoi">;
-
-// Convert between Floating-point Formats Instructions, p. 143
-def FSTOD : F3_3<2, 0b110100, 0b011001001, "fstod">;
-def FDTOS : F3_3<2, 0b110100, 0b011000110, "fdtos">;
-
-// Floating-point Move Instructions, p. 144
-def FMOVS : F3_3<2, 0b110100, 0b000000001, "fmovs">;
-def FNEGS : F3_3<2, 0b110100, 0b000000101, "fnegs">;
-def FABSS : F3_3<2, 0b110100, 0b000001001, "fabss">;
-
-// Floating-point Add and Subtract Instructions, p. 146
-def FADDS : F3_3<2, 0b110100, 0b001000001, "fadds">;
-def FADDD : F3_3<2, 0b110100, 0b001000010, "faddd">;
-def FSUBS : F3_3<2, 0b110100, 0b001000101, "fsubs">;
-def FSUBD : F3_3<2, 0b110100, 0b001000110, "fsubd">;
-
-// Floating-point Multiply and Divide Instructions, p. 147
-def FMULS : F3_3<2, 0b110100, 0b001001001, "fmuls">;
-def FMULD : F3_3<2, 0b110100, 0b001001010, "fmuld">;
-def FSMULD : F3_3<2, 0b110100, 0b001101001, "fsmuld">;
-def FDIVS : F3_3<2, 0b110100, 0b001001101, "fdivs">;
-def FDIVD : F3_3<2, 0b110100, 0b001001110, "fdivd">;
-
-// Floating-point Compare Instructions, p. 148
-// Note: the 2nd template arg is different for these guys.
-// Note 2: the result of a FCMP is not available until the 2nd cycle
-// after the instr is retired, but there is no interlock. This behavior
-// is modelled as a delay slot.
-let hasDelaySlot = 1 in {
- def FCMPS : F3_3<2, 0b110101, 0b001010001, "fcmps">;
- def FCMPD : F3_3<2, 0b110101, 0b001010010, "fcmpd">;
- def FCMPES : F3_3<2, 0b110101, 0b001010101, "fcmpes">;
- def FCMPED : F3_3<2, 0b110101, 0b001010110, "fcmped">;
-}
-
diff --git a/llvm/lib/Target/SparcV8/SparcV8JITInfo.h b/llvm/lib/Target/SparcV8/SparcV8JITInfo.h
deleted file mode 100644
index db866a0af775..000000000000
--- a/llvm/lib/Target/SparcV8/SparcV8JITInfo.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//===- SparcV8JITInfo.h - SparcV8 impl. of the JIT interface ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the SparcV8 implementation of the TargetJITInfo class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SPARCV8JITINFO_H
-#define SPARCV8JITINFO_H
-
-#include "llvm/Target/TargetJITInfo.h"
-
-namespace llvm {
- class TargetMachine;
- class IntrinsicLowering;
-
- class SparcV8JITInfo : public TargetJITInfo {
- TargetMachine &TM;
- public:
- SparcV8JITInfo(TargetMachine &tm) : TM(tm) {}
-
- /// addPassesToJITCompile - Add passes to the specified pass manager to
- /// implement a fast dynamic compiler for this target. Return true if this
- /// is not supported for this target.
- ///
- virtual void addPassesToJITCompile(FunctionPassManager &PM);
-
- /// replaceMachineCodeForFunction - Make it so that calling the function
- /// whose machine code is at OLD turns into a call to NEW, perhaps by
- /// overwriting OLD with a branch to NEW. This is used for self-modifying
- /// code.
- ///
- virtual void replaceMachineCodeForFunction(void *Old, void *New);
-
- /// getJITStubForFunction - Create or return a stub for the specified
- /// function. This stub acts just like the specified function, except that
- /// it allows the "address" of the function to be taken without having to
- /// generate code for it.
- virtual void *getJITStubForFunction(Function *F, MachineCodeEmitter &MCE);
- };
-}
-
-#endif
diff --git a/llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp b/llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp
deleted file mode 100644
index fe7aa2f879bb..000000000000
--- a/llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-//===- SparcV8RegisterInfo.cpp - SparcV8 Register Information ---*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the SparcV8 implementation of the MRegisterInfo class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SparcV8.h"
-#include "SparcV8RegisterInfo.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/Type.h"
-#include "llvm/ADT/STLExtras.h"
-#include <iostream>
-using namespace llvm;
-
-SparcV8RegisterInfo::SparcV8RegisterInfo()
- : SparcV8GenRegisterInfo(V8::ADJCALLSTACKDOWN,
- V8::ADJCALLSTACKUP) {}
-
-static const TargetRegisterClass *getClass(unsigned SrcReg) {
- if (SparcV8::IntRegsRegisterClass->contains(SrcReg))
- return SparcV8::IntRegsRegisterClass;
- else if (SparcV8::FPRegsRegisterClass->contains(SrcReg))
- return SparcV8::FPRegsRegisterClass;
- else if (SparcV8::DFPRegsRegisterClass->contains(SrcReg))
- return SparcV8::DFPRegsRegisterClass;
- else {
- std::cerr << "Error: register of unknown class found: " << SrcReg << "\n";
- abort ();
- }
-}
-
-void SparcV8RegisterInfo::
-storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
- unsigned SrcReg, int FrameIdx) const {
- const TargetRegisterClass *RC = getClass(SrcReg);
-
- // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
- if (RC == SparcV8::IntRegsRegisterClass)
- BuildMI (MBB, I, V8::ST, 3).addFrameIndex (FrameIdx).addSImm (0)
- .addReg (SrcReg);
- else if (RC == SparcV8::FPRegsRegisterClass)
- BuildMI (MBB, I, V8::STFri, 3).addFrameIndex (FrameIdx).addSImm (0)
- .addReg (SrcReg);
- else if (RC == SparcV8::DFPRegsRegisterClass)
- BuildMI (MBB, I, V8::STDFri, 3).addFrameIndex (FrameIdx).addSImm (0)
- .addReg (SrcReg);
- else
- assert (0 && "Can't store this register to stack slot");
-}
-
-void SparcV8RegisterInfo::
-loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
- unsigned DestReg, int FrameIdx) const {
- const TargetRegisterClass *RC = getClass(DestReg);
- if (RC == SparcV8::IntRegsRegisterClass)
- BuildMI (MBB, I, V8::LD, 2, DestReg).addFrameIndex (FrameIdx).addSImm (0);
- else if (RC == SparcV8::FPRegsRegisterClass)
- BuildMI (MBB, I, V8::LDFri, 2, DestReg).addFrameIndex (FrameIdx)
- .addSImm (0);
- else if (RC == SparcV8::DFPRegsRegisterClass)
- BuildMI (MBB, I, V8::LDDFri, 2, DestReg).addFrameIndex (FrameIdx)
- .addSImm (0);
- else
- assert(0 && "Can't load this register from stack slot");
-}
-
-void SparcV8RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator I,
- unsigned DestReg, unsigned SrcReg,
- const TargetRegisterClass *RC) const {
- if (RC == SparcV8::IntRegsRegisterClass)
- BuildMI (MBB, I, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg);
- else if (RC == SparcV8::FPRegsRegisterClass)
- BuildMI (MBB, I, V8::FMOVS, 1, DestReg).addReg (SrcReg);
- else if (RC == SparcV8::DFPRegsRegisterClass)
- BuildMI (MBB, I, V8::FpMOVD, 1, DestReg).addReg (SrcReg);
- else
- assert (0 && "Can't copy this register");
-}
-
-void SparcV8RegisterInfo::
-eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
- MachineBasicBlock::iterator I) const {
- MachineInstr &MI = *I;
- int size = MI.getOperand (0).getImmedValue ();
- if (MI.getOpcode () == V8::ADJCALLSTACKDOWN)
- size = -size;
- BuildMI (MBB, I, V8::ADDri, 2, V8::SP).addReg (V8::SP).addSImm (size);
- MBB.erase (I);
-}
-
-void
-SparcV8RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
- unsigned i = 0;
- MachineInstr &MI = *II;
- while (!MI.getOperand(i).isFrameIndex()) {
- ++i;
- assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
- }
-
- int FrameIndex = MI.getOperand(i).getFrameIndex();
-
- // Replace frame index with a frame pointer reference
- MI.SetMachineOperandReg (i, V8::FP);
-
- // Addressable stack objects are accessed using neg. offsets from %fp
- MachineFunction &MF = *MI.getParent()->getParent();
- int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
- MI.getOperand(i+1).getImmedValue();
- // note: Offset < 0
- MI.SetMachineOperandConst (i+1, MachineOperand::MO_SignExtendedImmed, Offset);
-}
-
-void SparcV8RegisterInfo::
-processFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
-
-void SparcV8RegisterInfo::emitPrologue(MachineFunction &MF) const {
- MachineBasicBlock &MBB = MF.front();
- MachineFrameInfo *MFI = MF.getFrameInfo();
-
- // Get the number of bytes to allocate from the FrameInfo
- int NumBytes = (int) MFI->getStackSize();
-
- // Emit the correct save instruction based on the number of bytes in
- // the frame. Minimum stack frame size according to V8 ABI is:
- // 16 words for register window spill
- // 1 word for address of returned aggregate-value
- // + 6 words for passing parameters on the stack
- // ----------
- // 23 words * 4 bytes per word = 92 bytes
- NumBytes += 92;
- // Round up to next doubleword boundary -- a double-word boundary
- // is required by the ABI.
- NumBytes = (NumBytes + 7) & ~7;
- BuildMI(MBB, MBB.begin(), V8::SAVEri, 2,
- V8::SP).addImm(-NumBytes).addReg(V8::SP);
-}
-
-void SparcV8RegisterInfo::emitEpilogue(MachineFunction &MF,
- MachineBasicBlock &MBB) const {
- MachineBasicBlock::iterator MBBI = prior(MBB.end());
- assert(MBBI->getOpcode() == V8::RETL &&
- "Can only put epilog before 'retl' instruction!");
- BuildMI(MBB, MBBI, V8::RESTORErr, 2, V8::G0).addReg(V8::G0).addReg(V8::G0);
-}
-
-#include "SparcV8GenRegisterInfo.inc"
-
-const TargetRegisterClass*
-SparcV8RegisterInfo::getRegClassForType(const Type* Ty) const {
- switch (Ty->getTypeID()) {
- case Type::FloatTyID: return &FPRegsInstance;
- case Type::DoubleTyID: return &DFPRegsInstance;
- case Type::LongTyID:
- case Type::ULongTyID: assert(0 && "Long values do not fit in registers!");
- default: assert(0 && "Invalid type to getClass!");
- case Type::BoolTyID:
- case Type::SByteTyID:
- case Type::UByteTyID:
- case Type::ShortTyID:
- case Type::UShortTyID:
- case Type::IntTyID:
- case Type::UIntTyID:
- case Type::PointerTyID: return &IntRegsInstance;
- }
-}
-
diff --git a/llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h b/llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h
deleted file mode 100644
index b53202edaf4f..000000000000
--- a/llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//===- SparcV8RegisterInfo.h - SparcV8 Register Information Impl -*- C++ -*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the SparcV8 implementation of the MRegisterInfo class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SPARCV8REGISTERINFO_H
-#define SPARCV8REGISTERINFO_H
-
-#include "llvm/Target/MRegisterInfo.h"
-#include "SparcV8GenRegisterInfo.h.inc"
-
-namespace llvm {
-
-class Type;
-
-struct SparcV8RegisterInfo : public SparcV8GenRegisterInfo {
- SparcV8RegisterInfo();
- const TargetRegisterClass* getRegClassForType(const Type* Ty) const;
-
- /// Code Generation virtual methods...
- void storeRegToStackSlot(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MBBI,
- unsigned SrcReg, int FrameIndex) const;
-
- void loadRegFromStackSlot(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MBBI,
- unsigned DestReg, int FrameIndex) const;
-
- void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
- unsigned DestReg, unsigned SrcReg,
- const TargetRegisterClass *RC) const;
-
- void eliminateCallFramePseudoInstr(MachineFunction &MF,
- MachineBasicBlock &MBB,
- MachineBasicBlock::iterator I) const;
-
- void eliminateFrameIndex(MachineBasicBlock::iterator II) const;
-
- void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
-
- void emitPrologue(MachineFunction &MF) const;
- void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td b/llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td
deleted file mode 100644
index 6e0806a3a9d7..000000000000
--- a/llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td
+++ /dev/null
@@ -1,51 +0,0 @@
-//===- SparcV8RegisterInfo.td - SparcV8 Register defs ------*- tablegen -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-// Declarations that describe the SparcV8 register file
-//===----------------------------------------------------------------------===//
-
-class SparcReg<string n> : Register<n> {
- field bits<5> Num;
- let Namespace = "V8";
-}
-
-include "../SparcRegisterInfo.td"
-
-// Register classes.
-//
-// FIXME: the register order should be defined in terms of the preferred
-// allocation order...
-//
-def IntRegs : RegisterClass<i32, 32, [L0, L1, L2, L3, L4, L5, L6, L7,
- I0, I1, I2, I3, I4, I5,
- G1,
- O0, O1, O2, O3, O4, O5, O7,
- // Non-allocatable regs:
- G2, G3, G4, // FIXME: OK for use only in
- // applications, not libraries.
- O6, // stack ptr
- I6, // frame ptr
- I7, // return address
- G0, // constant zero
- G5, G6, G7 // reserved for kernel
- ]> {
- let Methods = [{
- iterator allocation_order_end(MachineFunction &MF) const {
- return end()-10; // Don't allocate special registers
- }
- }];
-}
-
-def FPRegs : RegisterClass<f32, 32, [F0, F1, F2, F3, F4, F5, F6, F7, F8,
- F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22,
- F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
-
-def DFPRegs : RegisterClass<f64, 64, [D0, D1, D2, D3, D4, D5, D6, D7,
- D8, D9, D10, D11, D12, D13, D14, D15]>;
diff --git a/llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp b/llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp
deleted file mode 100644
index 604f683499f7..000000000000
--- a/llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-//===-- SparcV8TargetMachine.cpp - Define TargetMachine for SparcV8 -------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//
-//===----------------------------------------------------------------------===//
-
-#include "SparcV8TargetMachine.h"
-#include "SparcV8.h"
-#include "llvm/Module.h"
-#include "llvm/PassManager.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetMachineRegistry.h"
-#include "llvm/Transforms/Scalar.h"
-#include <iostream>
-using namespace llvm;
-
-namespace {
- // Register the target.
- RegisterTarget<SparcV8TargetMachine> X("sparcv8"," SPARC V8 (experimental)");
-}
-
-/// SparcV8TargetMachine ctor - Create an ILP32 architecture model
-///
-SparcV8TargetMachine::SparcV8TargetMachine(const Module &M,
- IntrinsicLowering *IL)
- : TargetMachine("SparcV8", IL, false, 4, 4, 8, 4, 8, 4, 4, 4, 4),
- FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0), JITInfo(*this) {
-}
-
-unsigned SparcV8TargetMachine::getJITMatchQuality() {
- return 0; // No JIT yet.
-}
-
-unsigned SparcV8TargetMachine::getModuleMatchQuality(const Module &M) {
- if (M.getEndianness() == Module::BigEndian &&
- M.getPointerSize() == Module::Pointer32)
-#ifdef __sparc__
- return 20; // BE/32 ==> Prefer sparcv8 on sparc
-#else
- return 5; // BE/32 ==> Prefer ppc elsewhere
-#endif
- else if (M.getEndianness() != Module::AnyEndianness ||
- M.getPointerSize() != Module::AnyPointerSize)
- return 0; // Match for some other target
-
- return getJITMatchQuality()/2;
-}
-
-/// addPassesToEmitAssembly - Add passes to the specified pass manager
-/// to implement a static compiler for this target.
-///
-bool SparcV8TargetMachine::addPassesToEmitAssembly(PassManager &PM,
- std::ostream &Out) {
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // Replace malloc and free instructions with library calls.
- PM.add(createLowerAllocationsPass());
-
- // FIXME: implement the select instruction in the instruction selector.
- PM.add(createLowerSelectPass());
-
- // FIXME: implement the switch instruction in the instruction selector.
- PM.add(createLowerSwitchPass());
-
- // FIXME: implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- PM.add(createLowerConstantExpressionsPass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
-
- PM.add(createSparcV8SimpleInstructionSelector(*this));
-
- // Print machine instructions as they were initially generated.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createRegisterAllocator());
- PM.add(createPrologEpilogCodeInserter());
-
- // Print machine instructions after register allocation and prolog/epilog
- // insertion.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createSparcV8FPMoverPass(*this));
- PM.add(createSparcV8DelaySlotFillerPass(*this));
-
- // Print machine instructions after filling delay slots.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- // Output assembly language.
- PM.add(createSparcV8CodePrinterPass(Out, *this));
-
- // Delete the MachineInstrs we generated, since they're no longer needed.
- PM.add(createMachineCodeDeleter());
- return false;
-}
-
-/// addPassesToJITCompile - Add passes to the specified pass manager to
-/// implement a fast dynamic compiler for this target.
-///
-void SparcV8JITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // Replace malloc and free instructions with library calls.
- PM.add(createLowerAllocationsPass());
-
- // FIXME: implement the select instruction in the instruction selector.
- PM.add(createLowerSelectPass());
-
- // FIXME: implement the switch instruction in the instruction selector.
- PM.add(createLowerSwitchPass());
-
- // FIXME: implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- PM.add(createLowerConstantExpressionsPass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
-
- PM.add(createSparcV8SimpleInstructionSelector(TM));
-
- // Print machine instructions as they were initially generated.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createRegisterAllocator());
- PM.add(createPrologEpilogCodeInserter());
-
- // Print machine instructions after register allocation and prolog/epilog
- // insertion.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createSparcV8FPMoverPass(TM));
- PM.add(createSparcV8DelaySlotFillerPass(TM));
-
- // Print machine instructions after filling delay slots.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-}
diff --git a/llvm/lib/Target/SparcV8/SparcV8TargetMachine.h b/llvm/lib/Target/SparcV8/SparcV8TargetMachine.h
deleted file mode 100644
index 86bfa8d99040..000000000000
--- a/llvm/lib/Target/SparcV8/SparcV8TargetMachine.h
+++ /dev/null
@@ -1,61 +0,0 @@
-//===-- SparcV8TargetMachine.h - Define TargetMachine for SparcV8 -*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the SparcV8 specific subclass of TargetMachine.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SPARCV8TARGETMACHINE_H
-#define SPARCV8TARGETMACHINE_H
-
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/PassManager.h"
-#include "SparcV8InstrInfo.h"
-#include "SparcV8JITInfo.h"
-
-namespace llvm {
-
-class IntrinsicLowering;
-class Module;
-
-class SparcV8TargetMachine : public TargetMachine {
- SparcV8InstrInfo InstrInfo;
- TargetFrameInfo FrameInfo;
- SparcV8JITInfo JITInfo;
-public:
- SparcV8TargetMachine(const Module &M, IntrinsicLowering *IL);
-
- virtual const SparcV8InstrInfo *getInstrInfo() const { return &InstrInfo; }
- virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; }
- virtual const MRegisterInfo *getRegisterInfo() const {
- return &InstrInfo.getRegisterInfo();
- }
- virtual TargetJITInfo *getJITInfo() {
- return &JITInfo;
- }
-
- static unsigned getModuleMatchQuality(const Module &M);
- static unsigned getJITMatchQuality();
-
- /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
- /// get machine code emitted. This uses a MachineCodeEmitter object to handle
- /// actually outputting the machine code and resolving things like the address
- /// of functions. This method should returns true if machine code emission is
- /// not supported.
- ///
- virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE);
-
- virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/llvm/runtime/GCCLibraries/crtend/Makefile b/llvm/runtime/GCCLibraries/crtend/Makefile
index a65ddc41a248..2680bb103288 100644
--- a/llvm/runtime/GCCLibraries/crtend/Makefile
+++ b/llvm/runtime/GCCLibraries/crtend/Makefile
@@ -47,14 +47,14 @@ $(ObjDir)/comp_main.bc: $(MainObj)
$(Echo) Linking $(notdir $@) component...
$(Verb) $(GCCLD) -link-as-library \
-internalize-public-api-file=$(BUILD_SRC_DIR)/comp_main.lst \
- $(MainObj) -o $@ \
+ $(MainObj) -o $@
# Generic exception handling support runtime.
$(ObjDir)/comp_genericeh.bc: $(GenericEHObj)
$(Echo) Linking $(notdir $@) component...
$(Verb) $(GCCLD) -link-as-library \
-internalize-public-api-file=$(BUILD_SRC_DIR)/comp_genericeh.lst \
- $(GenericEHObj) -o $@
+ $(GenericEHObj) -o $@
# setjmp/longjmp exception handling support runtime.
$(ObjDir)/comp_sjljeh.bc: $(SJLJEHObj)
diff --git a/llvm/test/Makefile b/llvm/test/Makefile
index 2c218a755ebd..5aa74d376b0e 100644
--- a/llvm/test/Makefile
+++ b/llvm/test/Makefile
@@ -13,105 +13,11 @@ DIRS =
#
# Make Dejagnu the default for testing
#
-all:: check
+all:: check-local
# Include other test rules
include Makefile.tests
-# New QMTest functionality:
-# The test suite is being transitioned over to QMTest. Eventually, it
-# will use QMTest by default.
-
-# QMTest option specifying the location of the QMTest database.
-QMDB= -D $(LLVM_SRC_ROOT)/test
-QMCLASSES=$(LLVM_OBJ_ROOT)/test/QMTest
-
-#
-# Determine which expectations file we will use
-#
-QMEXPECT:=$(LLVM_SRC_ROOT)/test/QMTest/expectations.unknown.qmr
-ifeq ($(OS),Linux)
-QMEXPECT:=$(LLVM_SRC_ROOT)/test/QMTest/expectations.linux.qmr
-endif
-
-ifeq ($(OS),SunOS)
-QMEXPECT:=$(LLVM_SRC_ROOT)/test/QMTest/expectations.sunos.qmr
-endif
-
-ifeq ($(OS),Darwin)
-QMEXPECT:=$(LLVM_SRC_ROOT)/test/QMTest/expectations.darwin.qmr
-endif
-
-#
-# This is configuration information used by the test suite. In QM Test, it's
-# called a 'context.'
-#
-CONTEXT= -c "srcroot=$(LLVM_SRC_ROOT)" \
- -c "buildroot=$(LLVM_OBJ_ROOT)" \
- -c "buildtype=$(BuildMode)" \
- -c "tmpdir=$(LLVM_OBJ_ROOT)/test/tmp" \
- -c "coresize=0" \
- -c "cc=$(CC)" \
- -c "cxx=$(CXX)" \
- -c "llvmgcc=$(LLVMGCC)" \
- -c "llvmgxx=$(LLVMGXX)" \
- -c "make=$(MAKE)" \
- -c "python=$(PYTHON)"
-
-#
-# Location of the QMTest program.
-#
-QMTEST= QMTEST_CLASS_PATH=$(QMCLASSES) qmtest $(QMDB)
-
-
-#
-# Execute the tests
-#
-qmtest:: $(LLVM_OBJ_ROOT)/test/tmp register
- -$(QMTEST) run -O $(QMEXPECT) $(CONTEXT)
-
-%.t:: $(LLVM_OBJ_ROOT)/test/tmp register
- -$(QMTEST) run -O $(QMEXPECT) $(CONTEXT) $*
-
-#
-# Create the temporary directory used by the test suite.
-#
-$(LLVM_OBJ_ROOT)/test/tmp::
- ${MKDIR} $(LLVM_OBJ_ROOT)/test/tmp
-
-#
-# Right now, QMTest compiles the python test classes and put them into the
-# source tree. Since Python bytecode is *not* cross-platform compatible (I
-# think), we'll regenerate every time.
-#
-# Simultaneous builds won't work, but shared source trees will.
-#
-register:
- $(QMTEST) register test llvm.TestAsmDisasm
- $(QMTEST) register test llvm.AssembleTest
- $(QMTEST) register test llvm.ConvertToCTest
- $(QMTEST) register test llvm.LLToCTest
- $(QMTEST) register test llvm.MachineCodeTest
- $(QMTEST) register test llvm.TestOptimizer
- $(QMTEST) register test llvm.LLITest
- $(QMTEST) register test llvm.TestRunner
- $(QMTEST) register test llvm.VerifierTest
- $(QMTEST) register test llvm.CTest
- $(QMTEST) register test llvm.CXXTest
- $(QMTEST) register database llvmdb.llvmdb
-
-# Start up the QMTest GUI
-gui::
- $(QMTEST) gui --no-browser --daemon
-
-# Also get rid of qmtest garbage when we 'make clean' in this directory.
-qmtest-clean:
- $(RM) -rf $(LLVM_OBJ_ROOT)/test/tmp
- $(RM) -f $(LLVM_SRC_ROOT)/test/QMTest/*.pyo \
- $(LLVM_OBJ_ROOT)/test/QMTest/*.pyo
- $(RM) -f $(LLVM_SRC_ROOT)/test/results.qmr \
- $(LLVM_OBJ_ROOT)/test/results.qmr
-
#===------------------------------------------------------------------------===#
# DejaGNU testing support
#===------------------------------------------------------------------------===#
@@ -120,7 +26,7 @@ ifdef TESTSUITE
RUNTESTFLAGS := --tool $(TESTSUITE)
endif
-check:: site.exp
+check-local:: site.exp
PATH=$(LLVMToolDir):$(LLVM_SRC_ROOT)/test/Scripts:$(PATH) \
$(RUNTEST) $(RUNTESTFLAGS)
diff --git a/llvm/test/Regression/CFrontend/2004-01-01-UnknownInitSize.c b/llvm/test/Regression/CFrontend/2004-01-01-UnknownInitSize.c
index c021c7a10835..7de3aba41acf 100644
--- a/llvm/test/Regression/CFrontend/2004-01-01-UnknownInitSize.c
+++ b/llvm/test/Regression/CFrontend/2004-01-01-UnknownInitSize.c
@@ -3,7 +3,7 @@
/*
* This regression test ensures that the C front end can compile initializers
* even when it cannot determine the size (as below).
- * XFAIL: linux,darwin
+ * XFAIL: *
*/
struct one
{
diff --git a/llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr b/llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr
index 41cfde1e3526..e3c930bd9f0c 100644
--- a/llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr
+++ b/llvm/test/Regression/CFrontend/2004-06-17-UnorderedCompares.c.tr
@@ -1,4 +1,4 @@
-// RUN: llvmgcc -xc -std=c99 %s -c -o - | llvm-dis | grep -v llvm.isunordered | not grep call
+// RUN: %llvmgcc -xc -std=c99 %s -c -o - | llvm-dis | grep -v llvm.isunordered | not grep call
// XFAIL: sparcv9
#include <math.h>
diff --git a/llvm/test/Regression/Debugger/funccall.ll b/llvm/test/Regression/Debugger/funccall.ll
index 846250b567fa..a781446ad70b 100644
--- a/llvm/test/Regression/Debugger/funccall.ll
+++ b/llvm/test/Regression/Debugger/funccall.ll
@@ -1,3 +1,4 @@
+;; XFAIL: darwin,sun
;; RUN: echo create > %t.commands
;; RUN: echo s >> %t.commands
;; RUN: echo s >> %t.commands
diff --git a/llvm/tools/gccld/gccld.cpp b/llvm/tools/gccld/gccld.cpp
index c1f430affa4f..d06eb6ec05f5 100644
--- a/llvm/tools/gccld/gccld.cpp
+++ b/llvm/tools/gccld/gccld.cpp
@@ -168,31 +168,37 @@ int main(int argc, char **argv, char **envp) {
int exitCode = 0;
try {
- std::string ModuleID("gccld-output");
- std::auto_ptr<Module> Composite(new Module(ModuleID));
-
- // We always look first in the current directory when searching for
- // libraries.
- LibPaths.insert(LibPaths.begin(), ".");
-
- // If the user specified an extra search path in their environment, respect
- // it.
- if (char *SearchPath = getenv("LLVM_LIB_SEARCH_PATH"))
- LibPaths.push_back(SearchPath);
-
// Remove any consecutive duplicates of the same library...
Libraries.erase(std::unique(Libraries.begin(), Libraries.end()),
Libraries.end());
- // Link in all of the files
- if (LinkFiles(argv[0], Composite.get(), InputFilenames, Verbose))
- return 1; // Error already printed
+ // Set up the Composite module.
+ std::auto_ptr<Module> Composite(0);
+
+ if (LinkAsLibrary) {
+ // Link in only the files.
+ Composite.reset( new Module(argv[0]) );
+ if (LinkFiles(argv[0], Composite.get(), InputFilenames, Verbose))
+ return 1; // Error already printed
+ // The libraries aren't linked in but are noted as "dependent" in the
+ // module.
+ for (cl::list<std::string>::const_iterator I = Libraries.begin(),
+ E = Libraries.end(); I != E ; ++I) {
+ Composite.get()->addLibrary(*I);
+ }
+
+ } else {
+ // Build a list of the items from our command line
+ LinkItemList Items;
+ BuildLinkItems(Items, InputFilenames, Libraries);
- if (!LinkAsLibrary)
- LinkLibraries(argv[0], Composite.get(), Libraries, LibPaths,
- Verbose, Native);
+ // Link all the items together
+ Composite.reset( LinkItems(argv[0], Items, LibPaths, Verbose, Native) );
- // Link in all of the libraries next...
+ // Check for an error during linker
+ if (!Composite.get())
+ return 1; // Error already printed
+ }
// Create the output file.
std::string RealBytecodeOutput = OutputFilename;
diff --git a/llvm/tools/llvm-ld/llvm-ld.cpp b/llvm/tools/llvm-ld/llvm-ld.cpp
index 31c1812df7b9..db5c4173a37c 100644
--- a/llvm/tools/llvm-ld/llvm-ld.cpp
+++ b/llvm/tools/llvm-ld/llvm-ld.cpp
@@ -389,29 +389,37 @@ int main(int argc, char **argv, char **envp) {
cl::ParseCommandLineOptions(argc, argv, " llvm linker for GCC\n");
sys::PrintStackTraceOnErrorSignal();
- std::string ModuleID("llvm-ld-output");
- std::auto_ptr<Module> Composite(new Module(ModuleID));
-
- // We always look first in the current directory when searching for libraries.
- LibPaths.insert(LibPaths.begin(), ".");
-
- // If the user specified an extra search path in their environment, respect
- // it.
- if (char *SearchPath = getenv("LLVM_LIB_SEARCH_PATH"))
- LibPaths.push_back(SearchPath);
-
// Remove any consecutive duplicates of the same library...
Libraries.erase(std::unique(Libraries.begin(), Libraries.end()),
Libraries.end());
- // Link in all of the files
- if (LinkFiles(argv[0], Composite.get(), InputFilenames, Verbose))
- return 1; // Error already printed
+ // Set up the Composite module.
+ std::auto_ptr<Module> Composite(0);
+
+ if (LinkAsLibrary) {
+ // Link in only the files.
+ Composite.reset( new Module(argv[0]) );
+ if (LinkFiles(argv[0], Composite.get(), InputFilenames, Verbose))
+ return 1; // Error already printed
- // Link in all of the libraries next...
- if (!LinkAsLibrary)
- LinkLibraries(argv[0], Composite.get(), Libraries, LibPaths,
- Verbose, Native);
+ // The libraries aren't linked in but are noted as "dependent" in the
+ // module.
+ for (cl::list<std::string>::const_iterator I = Libraries.begin(),
+ E = Libraries.end(); I != E ; ++I) {
+ Composite.get()->addLibrary(*I);
+ }
+ } else {
+ // Build a list of the items from our command line
+ LinkItemList Items;
+ BuildLinkItems(Items, InputFilenames, Libraries);
+
+ // Link all the items together
+ Composite.reset( LinkItems(argv[0], Items, LibPaths, Verbose, Native) );
+
+ // Check for an error during linker
+ if (!Composite.get())
+ return 1; // Error already printed
+ }
// Optimize the module
Optimize(Composite.get());