Update LLVM to r99115.

This commit is contained in:
rdivacky 2010-03-21 10:49:05 +00:00
parent 0f448b8416
commit 2f2afc1aae
277 changed files with 6822 additions and 4286 deletions

View File

@ -217,7 +217,9 @@ if( MSVC )
# List of valid CRTs for MSVC
set(MSVC_CRT
MD
MDd)
MDd
MT
MTd)
set(LLVM_USE_CRT "" CACHE STRING "Specify VC++ CRT to use for debug/release configurations.")
add_llvm_definitions( -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS )

View File

@ -578,8 +578,6 @@ endif
ifeq ($(TARGET_OS),Darwin)
ifneq ($(ARCH),ARM)
TargetCommonOpts += -mmacosx-version-min=$(DARWIN_VERSION)
else
TargetCommonOpts += -marm
endif
endif

View File

@ -31,12 +31,12 @@ dnl===
dnl===-----------------------------------------------------------------------===
dnl Initialize autoconf and define the package name, version number and
dnl email address for reporting bugs.
AC_INIT([[llvm]],[[2.7svn]],[llvmbugs@cs.uiuc.edu])
AC_INIT([[llvm]],[[2.8svn]],[llvmbugs@cs.uiuc.edu])
dnl Provide a copyright substitution and ensure the copyright notice is included
dnl in the output of --version option of the generated configure script.
AC_SUBST(LLVM_COPYRIGHT,["Copyright (c) 2003-2009 University of Illinois at Urbana-Champaign."])
AC_COPYRIGHT([Copyright (c) 2003-2009 University of Illinois at Urbana-Champaign.])
AC_SUBST(LLVM_COPYRIGHT,["Copyright (c) 2003-2010 University of Illinois at Urbana-Champaign."])
AC_COPYRIGHT([Copyright (c) 2003-2010 University of Illinois at Urbana-Champaign.])
dnl Indicate that we require autoconf 2.59 or later. Ths is needed because we
dnl use some autoconf macros only available in 2.59.
@ -62,6 +62,41 @@ dnl Configure all of the projects present in our source tree. While we could
dnl just AC_CONFIG_SUBDIRS on the set of directories in projects that have a
dnl configure script, that usage of the AC_CONFIG_SUBDIRS macro is deprecated.
dnl Instead we match on the known projects.
dnl
dnl One tricky part of doing this is that some projects depend upon other
dnl projects. For example, several projects rely upon the LLVM test suite.
dnl We want to configure those projects first so that their object trees are
dnl created before running the configure scripts of projects that depend upon
dnl them.
dnl
dnl Several projects use llvm-gcc, so configure that first
if test -d ${srcdir}/projects/llvm-gcc ; then
AC_CONFIG_SUBDIRS([projects/llvm-gcc])
fi
dnl Several projects use the LLVM test suite, so configure it next.
if test -d ${srcdir}/projects/test-suite ; then
AC_CONFIG_SUBDIRS([projects/test-suite])
fi
dnl llvm-test is the old name of the test-suite, kept here for backwards
dnl compatibility
if test -d ${srcdir}/projects/llvm-test ; then
AC_CONFIG_SUBDIRS([projects/llvm-test])
fi
dnl Some projects use poolalloc; configure that next
if test -d ${srcdir}/projects/poolalloc ; then
AC_CONFIG_SUBDIRS([projects/poolalloc])
fi
if test -d ${srcdir}/projects/llvm-poolalloc ; then
AC_CONFIG_SUBDIRS([projects/llvm-poolalloc])
fi
dnl Check for all other projects
for i in `ls ${srcdir}/projects`
do
if test -d ${srcdir}/projects/${i} ; then
@ -70,16 +105,9 @@ do
sample) AC_CONFIG_SUBDIRS([projects/sample]) ;;
privbracket) AC_CONFIG_SUBDIRS([projects/privbracket]) ;;
llvm-stacker) AC_CONFIG_SUBDIRS([projects/llvm-stacker]) ;;
# llvm-test is the old name of the test-suite, kept here for backwards
# compatibility
llvm-test) AC_CONFIG_SUBDIRS([projects/llvm-test]) ;;
test-suite) AC_CONFIG_SUBDIRS([projects/test-suite]) ;;
llvm-reopt) AC_CONFIG_SUBDIRS([projects/llvm-reopt]);;
llvm-gcc) AC_CONFIG_SUBDIRS([projects/llvm-gcc]) ;;
llvm-java) AC_CONFIG_SUBDIRS([projects/llvm-java]) ;;
llvm-tv) AC_CONFIG_SUBDIRS([projects/llvm-tv]) ;;
llvm-poolalloc) AC_CONFIG_SUBDIRS([projects/llvm-poolalloc]) ;;
poolalloc) AC_CONFIG_SUBDIRS([projects/poolalloc]) ;;
safecode) AC_CONFIG_SUBDIRS([projects/safecode]) ;;
llvm-kernel) AC_CONFIG_SUBDIRS([projects/llvm-kernel]) ;;
*)

77
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.60 for llvm 2.7svn.
# Generated by GNU Autoconf 2.60 for llvm 2.8svn.
#
# Report bugs to <llvmbugs@cs.uiuc.edu>.
#
@ -9,7 +9,7 @@
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
#
# Copyright (c) 2003-2009 University of Illinois at Urbana-Champaign.
# Copyright (c) 2003-2010 University of Illinois at Urbana-Champaign.
## --------------------- ##
## M4sh Initialization. ##
## --------------------- ##
@ -561,8 +561,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='llvm'
PACKAGE_TARNAME='-llvm-'
PACKAGE_VERSION='2.7svn'
PACKAGE_STRING='llvm 2.7svn'
PACKAGE_VERSION='2.8svn'
PACKAGE_STRING='llvm 2.8svn'
PACKAGE_BUGREPORT='llvmbugs@cs.uiuc.edu'
ac_unique_file="lib/VMCore/Module.cpp"
@ -802,17 +802,17 @@ CPP
CXX
CXXFLAGS
CCC'
ac_subdirs_all='projects/sample
ac_subdirs_all='projects/llvm-gcc
projects/test-suite
projects/llvm-test
projects/poolalloc
projects/llvm-poolalloc
projects/sample
projects/privbracket
projects/llvm-stacker
projects/llvm-test
projects/test-suite
projects/llvm-reopt
projects/llvm-gcc
projects/llvm-java
projects/llvm-tv
projects/llvm-poolalloc
projects/poolalloc
projects/safecode
projects/llvm-kernel'
@ -1316,7 +1316,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures llvm 2.7svn to adapt to many kinds of systems.
\`configure' configures llvm 2.8svn to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1382,7 +1382,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of llvm 2.7svn:";;
short | recursive ) echo "Configuration of llvm 2.8svn:";;
esac
cat <<\_ACEOF
@ -1533,7 +1533,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
llvm configure 2.7svn
llvm configure 2.8svn
generated by GNU Autoconf 2.60
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@ -1541,7 +1541,7 @@ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
Copyright (c) 2003-2009 University of Illinois at Urbana-Champaign.
Copyright (c) 2003-2010 University of Illinois at Urbana-Champaign.
_ACEOF
exit
fi
@ -1549,7 +1549,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by llvm $as_me 2.7svn, which was
It was created by llvm $as_me 2.8svn, which was
generated by GNU Autoconf 2.60. Invocation command line was
$ $0 $@
@ -1903,7 +1903,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
LLVM_COPYRIGHT="Copyright (c) 2003-2009 University of Illinois at Urbana-Champaign."
LLVM_COPYRIGHT="Copyright (c) 2003-2010 University of Illinois at Urbana-Champaign."
@ -1951,6 +1951,33 @@ echo "$as_me: error: Already configured in ${srcdir}" >&2;}
fi
fi
if test -d ${srcdir}/projects/llvm-gcc ; then
subdirs="$subdirs projects/llvm-gcc"
fi
if test -d ${srcdir}/projects/test-suite ; then
subdirs="$subdirs projects/test-suite"
fi
if test -d ${srcdir}/projects/llvm-test ; then
subdirs="$subdirs projects/llvm-test"
fi
if test -d ${srcdir}/projects/poolalloc ; then
subdirs="$subdirs projects/poolalloc"
fi
if test -d ${srcdir}/projects/llvm-poolalloc ; then
subdirs="$subdirs projects/llvm-poolalloc"
fi
for i in `ls ${srcdir}/projects`
do
if test -d ${srcdir}/projects/${i} ; then
@ -1961,25 +1988,13 @@ do
privbracket) subdirs="$subdirs projects/privbracket"
;;
llvm-stacker) subdirs="$subdirs projects/llvm-stacker"
;;
# llvm-test is the old name of the test-suite, kept here for backwards
# compatibility
llvm-test) subdirs="$subdirs projects/llvm-test"
;;
test-suite) subdirs="$subdirs projects/test-suite"
;;
llvm-reopt) subdirs="$subdirs projects/llvm-reopt"
;;
llvm-gcc) subdirs="$subdirs projects/llvm-gcc"
;;
llvm-java) subdirs="$subdirs projects/llvm-java"
;;
llvm-tv) subdirs="$subdirs projects/llvm-tv"
;;
llvm-poolalloc) subdirs="$subdirs projects/llvm-poolalloc"
;;
poolalloc) subdirs="$subdirs projects/poolalloc"
;;
safecode) subdirs="$subdirs projects/safecode"
;;
llvm-kernel) subdirs="$subdirs projects/llvm-kernel"
@ -11136,7 +11151,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 11139 "configure"
#line 11154 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -20608,7 +20623,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by llvm $as_me 2.7svn, which was
This file was extended by llvm $as_me 2.8svn, which was
generated by GNU Autoconf 2.60. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -20661,7 +20676,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
llvm config.status 2.7svn
llvm config.status 2.8svn
configured by $0, generated by GNU Autoconf 2.60,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

View File

@ -10,6 +10,9 @@
<div class="doc_title">LLVM 2.7 Release Notes</div>
<img align=right src="http://llvm.org/img/DragonSmall.png"
width="136" height="136">
<ol>
<li><a href="#intro">Introduction</a></li>
<li><a href="#subproj">Sub-project Status Update</a></li>
@ -48,14 +51,18 @@ href="http://llvm.org/releases/">LLVM releases web site</a>.</p>
<p>For more information about LLVM, including information about the latest
release, please check out the <a href="http://llvm.org/">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>
href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVM Developer's
Mailing List</a> is a good place to send them.</p>
<p>Note that if you are reading this file from a Subversion checkout or the
main LLVM web page, this document applies to the <i>next</i> release, not the
current one. To see the release notes for a specific release, please see the
<a href="http://llvm.org/releases/">releases page</a>.</p>
<p>FIXME: llvm.org moved to new server, mention new logo, Ted and Doug new code
owners.</p>
</div>
@ -66,6 +73,7 @@ Almost dead code.
llvm/Analysis/PointerTracking.h => Edwin wants this, consider for 2.8.
ABCD, SCCVN, GEPSplitterPass
MSIL backend?
lib/Transforms/Utils/SSI.cpp -> ABCD depends on it.
-->
@ -78,8 +86,6 @@ Almost dead code.
loop dependence analysis
ELF Writer? How stable?
<li>PostRA scheduler improvements, ARM adoption (David Goodwin).</li>
2.7 supports the GDB 7.0 jit interfaces for debug info.
2.7 eliminates ADT/iterator.h
-->
<!-- for announcement email:
@ -88,8 +94,7 @@ Almost dead code.
compiler_rt
KLEE web page at klee.llvm.org
Many new papers added to /pubs/
Mention gcc plugin.
Mention gcc plugin.
-->
<!-- *********************************************************************** -->
@ -123,6 +128,7 @@ development. Here we include updates on these subprojects.
<ul>
<li>...</li>
include a link to cxx_compatibility.html
</ul>
</div>
@ -139,7 +145,7 @@ href="http://clang.llvm.org/StaticAnalysis.html">automatically finding bugs</a>
in C and Objective-C programs. The tool performs checks to find
bugs that occur on a specific path within a program.</p>
<p>In the LLVM 2.7 time-frame, the analyzer core has ...</p>
<p>In the LLVM 2.7 time-frame, the analyzer core has sprouted legs and...</p>
</div>
@ -190,24 +196,6 @@ License, a "BSD-style" license.</p>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="klee">KLEE: Symbolic Execution and Automatic Test Case Generator</a>
</div>
<div class="doc_text">
<p>
The new LLVM <a href="http://klee.llvm.org/">KLEE project</a> is a symbolic
execution framework for programs in LLVM bitcode form. KLEE tries to
symbolically evaluate "all" paths through the application and records state
transitions that lead to fault states. This allows it to construct testcases
that lead to faults and can even be used to verify algorithms. For more
details, please see the <a
href="http://llvm.org/pubs/2008-12-OSDI-KLEE.html">OSDI 2008 paper</a> about
KLEE.</p>
</div>
<!--=========================================================================-->
<div class="doc_subsection">
<a name="dragonegg">DragonEgg: GCC-4.5 as an LLVM frontend</a>
@ -257,6 +245,8 @@ The LLVM Machine Code (MC) Toolkit project is ...
</div>
<div class="doc_text">
Need update.
<!--
<p><a href="http://github.com/evanphx/rubinius">Rubinius</a> is an environment
for running Ruby code which strives to write as much of the core class
implementation in Ruby as possible. Combined with a bytecode interpreting VM, it
@ -266,6 +256,7 @@ remove dynamism from ruby execution and increase performance.</p>
<p>Since LLVM 2.5, Rubinius has made several major leaps forward, implementing
a counter based JIT, type feedback and speculative method inlining.
-->
</p>
</div>
@ -278,6 +269,8 @@ a counter based JIT, type feedback and speculative method inlining.
<div class="doc_text">
<p>
Need update.
<!--
<a href="http://macruby.org">MacRuby</a> is an implementation of Ruby on top of
core Mac OS X technologies, such as the Objective-C common runtime and garbage
collector and the CoreFoundation framework. It is principally developed by
@ -287,7 +280,7 @@ Apple and aims at enabling the creation of full-fledged Mac OS X applications.
<p>
MacRuby uses LLVM for optimization passes, JIT and AOT compilation of Ruby
expressions. It also uses zero-cost DWARF exceptions to implement Ruby exception
handling.</p>
handling.--> </p>
</div>
@ -308,9 +301,9 @@ built-in list and matrix support (including list and matrix comprehensions) and
an easy-to-use C interface. The interpreter uses LLVM as a backend to
JIT-compile Pure programs to fast native code.</p>
<p>Pure versions ??? and later have been tested and are known to work with
LLVM 2.7 (and continue to work with older LLVM releases >= 2.3 as well).
</p>
<p>Pure versions 0.43 and later have been tested and are known to work with
LLVM 2.7 (and continue to work with older LLVM releases >= 2.5).</p>
</div>
@ -321,6 +314,8 @@ LLVM 2.7 (and continue to work with older LLVM releases >= 2.3 as well).
<div class="doc_text">
<p>
Need update.
<!--
<a href="http://www.dsource.org/projects/ldc">LDC</a> is an implementation of
the D Programming Language using the LLVM optimizer and code generator.
The LDC project works great with the LLVM 2.6 release. General improvements in
@ -328,7 +323,7 @@ this
cycle have included new inline asm constraint handling, better debug info
support, general bug fixes and better x86-64 support. This has allowed
some major improvements in LDC, getting it much closer to being as
fully featured as the original DMD compiler from DigitalMars.
fully featured as the original DMD compiler from DigitalMars.-->
</p>
</div>
@ -342,7 +337,8 @@ fully featured as the original DMD compiler from DigitalMars.
<a href="http://code.roadsend.com/rphp">Roadsend PHP</a> (rphp) is an open
source implementation of the PHP programming
language that uses LLVM for its optimizer, JIT and static compiler. This is a
reimplementation of an earlier project that is now based on LLVM.</p>
reimplementation of an earlier project that is now based on LLVM.
</p>
</div>
<!--=========================================================================-->
@ -355,7 +351,8 @@ reimplementation of an earlier project that is now based on LLVM.</p>
<a href="http://code.google.com/p/unladen-swallow/">Unladen Swallow</a> is a
branch of <a href="http://python.org/">Python</a> intended to be fully
compatible and significantly faster. It uses LLVM's optimization passes and JIT
compiler.</p>
compiler.
</p>
</div>
<!--=========================================================================-->
@ -365,10 +362,13 @@ compiler.</p>
<div class="doc_text">
<p>
Need update.
<!--
<a href="http://code.google.com/p/llvm-lua/">LLVM-Lua</a> uses LLVM to add JIT
and static compiling support to the Lua VM. Lua bytecode is analyzed to
remove type checks, then LLVM is used to compile the bytecode down to machine
code.</p>
code.-->
</p>
</div>
<!--=========================================================================-->
@ -378,13 +378,15 @@ code.</p>
<div class="doc_text">
<p>
Need update.
<!--
<a href="http://icedtea.classpath.org/wiki/Main_Page">IcedTea</a> provides a
harness to build OpenJDK using only free software build tools and to provide
replacements for the not-yet free parts of OpenJDK. One of the extensions that
IcedTea provides is a new JIT compiler named <a
href="http://icedtea.classpath.org/wiki/ZeroSharkFaq">Shark</a> which uses LLVM
to provide native code generation without introducing processor-dependent
code.
code.-->
</p>
</div>
@ -418,6 +420,54 @@ in this section.
<li>...</li>
</ul>
Extensible metadata solid.
Debug info improvements: using metadata instead of llvm.dbg global variables.
This brings several enhancements including improved compile times.
New instruction selector.
GHC Haskell ABI/ calling conv support.
Pre-Alpha support for unions in IR.
New InlineHint and StackAlignment function attributes
Code generator MC'ized except for debug info and EH.
New SCEV AA pass: -scev-aa
Inliner reuses arrays allocas when inlining multiple callers to reduce stack usage.
MC encoding and disassembler apis.
Optimal Edge Profiling?
Instcombine is now a library, has its own IRBuilder to simplify itself.
New llvm/Support/Regex.h API. FileCheck now does regex's
Many subtle pointer invalidation bugs in Callgraph have been fixed and it now uses asserting value handles.
MC Disassembler (with blog post), MCInstPrinter. Many X86 backend and AsmPrinter simplifications
Various tools like llc and opt now read either .ll or .bc files as input.
Malloc and free instructions got removed.
compiler-rt support for ARM.
completely llvm-gcc NEON support.
Can transcode from GAS to intel syntax with "llvm-mc foo.s -output-asm-variant=1"
JIT debug information with GDB 7.0
New CodeGen Level CSE
CMake can now run tests, what other improvements?
ARM/Thumb using reg scavenging for stack object address materialization (PEI).
New SSAUpdater and MachineSSAUpdater classes for unstructured ssa updating,
changed jump threading, GVN, etc to use it which simplified them and speed
them up.
Combiner-AA improvements, why not on by default?
Pre-regalloc tail duplication
x86 sibcall optimization
New LSR with full strength reduction mode
The most awesome sext / zext optimization pass. ?
CondProp pass removed (functionality merged into jump threading).
AndersAA got removed (from 2.7 or mainline?)
PredSimplify, LoopVR, GVNPRE got removed.
LLVM command line tools now overwrite their output, before they would only do this with -f.
DOUT removed, use DEBUG(errs() instead.
Much stuff converted to use raw_ostream instead of std::ostream.
TargetAsmInfo renamed to MCAsmInfo
llvm/ADT/iterator.h gone.
</div>
<!--=========================================================================-->
@ -699,13 +749,7 @@ listed by component. If you run into a problem, please check the <a
href="http://llvm.org/bugs/">LLVM bug database</a> and submit a bug if
there isn't already one.</p>
<ul>
<li>The llvm-gcc bootstrap will fail with some versions of binutils (e.g. 2.15)
with a message of "<tt><a href="http://llvm.org/PR5004">Error: can not do 8
byte pc-relative relocation</a></tt>" when building C++ code. We intend to
fix this on mainline, but a workaround is to upgrade to binutils 2.17 or
later.</li>
<ul>
<li>LLVM will not correctly compile on Solaris and/or OpenSolaris
using the stock GCC 3.x.x series 'out the box',
See: <a href="GettingStarted.html#brokengcc">Broken versions of GCC and other tools</a>.
@ -731,10 +775,11 @@ components, please contact us on the <a
href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVMdev list</a>.</p>
<ul>
<li>The MSIL, Alpha, SPU, MIPS, PIC16, Blackfin, MSP430 and SystemZ backends are
experimental.</li>
<li>The MSIL, Alpha, SPU, MIPS, PIC16, Blackfin, MSP430, SystemZ and MicroBlaze
backends are experimental.</li>
<li>The <tt>llc</tt> "<tt>-filetype=asm</tt>" (the default) is the only
supported value for this option. The ELF writer is experimental.</li>
supported value for this option. The MachO writer is experimental, and
works much better in mainline SVN.</li>
</ul>
</div>
@ -865,7 +910,7 @@ appropriate nops inserted to ensure restartability.</li>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="c-fe">Known problems with the llvm-gcc C front-end</a>
<a name="c-fe">Known problems with the llvm-gcc C and C++ front-end</a>
</div>
<div class="doc_text">
@ -881,24 +926,6 @@ appropriate nops inserted to ensure restartability.</li>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="c++-fe">Known problems with the llvm-gcc C++ front-end</a>
</div>
<div class="doc_text">
<p>The C++ front-end is considered to be fully
tested and works for a number of non-trivial programs, including LLVM
itself, Qt, Mozilla, etc.</p>
<ul>
<li>Exception handling works well on the X86 and PowerPC targets. Currently
only Linux and Darwin targets are supported (both 32 and 64 bit).</li>
</ul>
</div>
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="fortran-fe">Known problems with the llvm-gcc Fortran front-end</a>
@ -997,7 +1024,7 @@ lists</a>.</p>
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2010-03-01 20:29:17 +0100 (Mon, 01 Mar 2010) $
Last modified: $Date: 2010-03-19 04:18:05 +0100 (Fri, 19 Mar 2010) $
</address>
</body>

View File

@ -237,7 +237,7 @@ height="369">
<p>LLVM debugging information has been carefully designed to make it possible
for the optimizer to optimize the program and debugging information without
necessarily having to know anything about debugging information. In
particular, te use of metadadta avoids duplicated dubgging information from
particular, the use of metadata avoids duplicated debugging information from
the beginning, and the global dead code elimination pass automatically
deletes debugging information for a function if it decides to delete the
function. </p>
@ -370,7 +370,7 @@ height="369">
</pre>
</div>
<p>These descriptors contain informations for a file. Global variables and top
<p>These descriptors contain information for a file. Global variables and top
level functions would be defined using this context.k File descriptors also
provide context for source line correspondence. </p>
@ -967,7 +967,7 @@ call void @llvm.dbg.declare({ }* %2, metadata !12), !dbg !14
</pre>
</div>
<p>Here <tt>!14</tt> indicates that <tt>Z</tt> is declaread at line number 5 and
<p>Here <tt>!14</tt> indicates that <tt>Z</tt> is declared at line number 5 and
column number 9 inside of lexical scope <tt>!13</tt>. The lexical scope
itself resides inside of lexical scope <tt>!1</tt> described above.</p>
@ -1762,7 +1762,7 @@ enum Trees {
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br>
Last modified: $Date: 2010-03-09 01:44:10 +0100 (Tue, 09 Mar 2010) $
Last modified: $Date: 2010-03-17 16:01:50 +0100 (Wed, 17 Mar 2010) $
</address>
</body>

View File

@ -329,7 +329,8 @@ class BitVector {
Size = RHS.size();
unsigned RHSWords = NumBitWords(Size);
if (Size <= Capacity * BITWORD_SIZE) {
std::copy(RHS.Bits, &RHS.Bits[RHSWords], Bits);
if (Size)
std::copy(RHS.Bits, &RHS.Bits[RHSWords], Bits);
clear_unused_bits();
return *this;
}

View File

@ -16,6 +16,7 @@
#define LLVM_ADT_EQUIVALENCECLASSES_H
#include "llvm/System/DataTypes.h"
#include <cassert>
#include <set>
namespace llvm {

View File

@ -23,6 +23,7 @@
namespace llvm {
class APFloat;
class APInt;
class BumpPtrAllocator;
/// This folding set used for two purposes:
/// 1. Given information about a node we want to create, look up the unique
@ -197,6 +198,23 @@ template<typename T> struct FoldingSetTrait {
static inline void Profile(T& X, FoldingSetNodeID& ID) { X.Profile(ID); }
};
//===--------------------------------------------------------------------===//
/// FoldingSetNodeIDRef - This class describes a reference to an interned
/// FoldingSetNodeID, which can be a useful to store node id data rather
/// than using plain FoldingSetNodeIDs, since the 32-element SmallVector
/// is often much larger than necessary, and the possibility of heap
/// allocation means it requires a non-trivial destructor call.
class FoldingSetNodeIDRef {
unsigned* Data;
size_t Size;
public:
FoldingSetNodeIDRef() : Data(0), Size(0) {}
FoldingSetNodeIDRef(unsigned *D, size_t S) : Data(D), Size(S) {}
unsigned *getData() const { return Data; }
size_t getSize() const { return Size; }
};
//===--------------------------------------------------------------------===//
/// FoldingSetNodeID - This class is used to gather all the unique data bits of
/// a node. When all the bits are gathered this class is used to produce a
@ -210,11 +228,8 @@ class FoldingSetNodeID {
public:
FoldingSetNodeID() {}
/// getRawData - Return the ith entry in the Bits data.
///
unsigned getRawData(unsigned i) const {
return Bits[i];
}
FoldingSetNodeID(FoldingSetNodeIDRef Ref)
: Bits(Ref.getData(), Ref.getData() + Ref.getSize()) {}
/// Add* - Add various data types to Bit data.
///
@ -242,6 +257,11 @@ class FoldingSetNodeID {
/// operator== - Used to compare two nodes to each other.
///
bool operator==(const FoldingSetNodeID &RHS) const;
/// Intern - Copy this node's data to a memory region allocated from the
/// given allocator and return a FoldingSetNodeIDRef describing the
/// interned data.
FoldingSetNodeIDRef Intern(BumpPtrAllocator &Allocator) const;
};
// Convenience type to hide the implementation of the folding set.

View File

@ -57,17 +57,18 @@ class SmallVectorBase {
// something else. An array of char would work great, but might not be
// aligned sufficiently. Instead, we either use GCC extensions, or some
// number of union instances for the space, which guarantee maximal alignment.
struct U {
#ifdef __GNUC__
typedef char U;
U FirstEl __attribute__((aligned));
char X __attribute__((aligned));
#else
union U {
double D;
long double LD;
long long L;
void *P;
} FirstEl;
union {
double D;
long double LD;
long long L;
void *P;
} X;
#endif
} FirstEl;
// Space after 'FirstEl' is clobbered, do not add any instance vars after it.
protected:

View File

@ -49,7 +49,11 @@ namespace llvm {
/// are opaque objects that the client is not allowed to do much with
/// directly.
///
class SCEV : public FastFoldingSetNode {
class SCEV : public FoldingSetNode {
/// FastID - A reference to an Interned FoldingSetNodeID for this node.
/// The ScalarEvolution's BumpPtrAllocator holds the data.
FoldingSetNodeIDRef FastID;
// The SCEV baseclass this node corresponds to
const unsigned short SCEVType;
@ -64,11 +68,14 @@ namespace llvm {
protected:
virtual ~SCEV();
public:
explicit SCEV(const FoldingSetNodeID &ID, unsigned SCEVTy) :
FastFoldingSetNode(ID), SCEVType(SCEVTy), SubclassData(0) {}
explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy) :
FastID(ID), SCEVType(SCEVTy), SubclassData(0) {}
unsigned getSCEVType() const { return SCEVType; }
/// Profile - FoldingSet support.
void Profile(FoldingSetNodeID& ID) { ID = FastID; }
/// isLoopInvariant - Return true if the value of this SCEV is unchanging in
/// the specified loop.
virtual bool isLoopInvariant(const Loop *L) const = 0;

View File

@ -79,12 +79,7 @@ namespace llvm {
/// expandCodeFor - Insert code to directly compute the specified SCEV
/// expression into the program. The inserted code is inserted into the
/// specified block.
Value *expandCodeFor(const SCEV *SH, const Type *Ty, Instruction *I) {
BasicBlock::iterator IP = I;
while (isInsertedInstruction(IP)) ++IP;
Builder.SetInsertPoint(IP->getParent(), IP);
return expandCodeFor(SH, Ty);
}
Value *expandCodeFor(const SCEV *SH, const Type *Ty, Instruction *I);
/// setIVIncInsertPos - Set the current IV increment loop and position.
void setIVIncInsertPos(const Loop *L, Instruction *Pos) {
@ -109,6 +104,13 @@ namespace llvm {
/// is useful for late optimization passes.
void disableCanonicalMode() { CanonicalMode = false; }
/// clearInsertPoint - Clear the current insertion point. This is useful
/// if the instruction that had been serving as the insertion point may
/// have been deleted.
void clearInsertPoint() {
Builder.ClearInsertionPoint();
}
private:
LLVMContext &getContext() const { return SE.getContext(); }

View File

@ -37,7 +37,7 @@ namespace llvm {
friend class ScalarEvolution;
ConstantInt *V;
SCEVConstant(const FoldingSetNodeID &ID, ConstantInt *v) :
SCEVConstant(const FoldingSetNodeIDRef ID, ConstantInt *v) :
SCEV(ID, scConstant), V(v) {}
public:
ConstantInt *getValue() const { return V; }
@ -81,7 +81,7 @@ namespace llvm {
const SCEV *Op;
const Type *Ty;
SCEVCastExpr(const FoldingSetNodeID &ID,
SCEVCastExpr(const FoldingSetNodeIDRef ID,
unsigned SCEVTy, const SCEV *op, const Type *ty);
public:
@ -120,7 +120,7 @@ namespace llvm {
class SCEVTruncateExpr : public SCEVCastExpr {
friend class ScalarEvolution;
SCEVTruncateExpr(const FoldingSetNodeID &ID,
SCEVTruncateExpr(const FoldingSetNodeIDRef ID,
const SCEV *op, const Type *ty);
public:
@ -140,7 +140,7 @@ namespace llvm {
class SCEVZeroExtendExpr : public SCEVCastExpr {
friend class ScalarEvolution;
SCEVZeroExtendExpr(const FoldingSetNodeID &ID,
SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID,
const SCEV *op, const Type *ty);
public:
@ -160,7 +160,7 @@ namespace llvm {
class SCEVSignExtendExpr : public SCEVCastExpr {
friend class ScalarEvolution;
SCEVSignExtendExpr(const FoldingSetNodeID &ID,
SCEVSignExtendExpr(const FoldingSetNodeIDRef ID,
const SCEV *op, const Type *ty);
public:
@ -180,25 +180,27 @@ namespace llvm {
///
class SCEVNAryExpr : public SCEV {
protected:
SmallVector<const SCEV *, 8> Operands;
// Since SCEVs are immutable, ScalarEvolution allocates operand
// arrays with its SCEVAllocator, so this class just needs a simple
// pointer rather than a more elaborate vector-like data structure.
// This also avoids the need for a non-trivial destructor.
const SCEV *const *Operands;
size_t NumOperands;
SCEVNAryExpr(const FoldingSetNodeID &ID,
enum SCEVTypes T, const SmallVectorImpl<const SCEV *> &ops)
: SCEV(ID, T), Operands(ops.begin(), ops.end()) {}
SCEVNAryExpr(const FoldingSetNodeIDRef ID,
enum SCEVTypes T, const SCEV *const *O, size_t N)
: SCEV(ID, T), Operands(O), NumOperands(N) {}
public:
unsigned getNumOperands() const { return (unsigned)Operands.size(); }
size_t getNumOperands() const { return NumOperands; }
const SCEV *getOperand(unsigned i) const {
assert(i < Operands.size() && "Operand index out of range!");
assert(i < NumOperands && "Operand index out of range!");
return Operands[i];
}
const SmallVectorImpl<const SCEV *> &getOperands() const {
return Operands;
}
typedef SmallVectorImpl<const SCEV *>::const_iterator op_iterator;
op_iterator op_begin() const { return Operands.begin(); }
op_iterator op_end() const { return Operands.end(); }
typedef const SCEV *const *op_iterator;
op_iterator op_begin() const { return Operands; }
op_iterator op_end() const { return Operands + NumOperands; }
virtual bool isLoopInvariant(const Loop *L) const {
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
@ -260,10 +262,9 @@ namespace llvm {
///
class SCEVCommutativeExpr : public SCEVNAryExpr {
protected:
SCEVCommutativeExpr(const FoldingSetNodeID &ID,
enum SCEVTypes T,
const SmallVectorImpl<const SCEV *> &ops)
: SCEVNAryExpr(ID, T, ops) {}
SCEVCommutativeExpr(const FoldingSetNodeIDRef ID,
enum SCEVTypes T, const SCEV *const *O, size_t N)
: SCEVNAryExpr(ID, T, O, N) {}
public:
virtual const char *getOperationStr() const = 0;
@ -287,9 +288,9 @@ namespace llvm {
class SCEVAddExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
SCEVAddExpr(const FoldingSetNodeID &ID,
const SmallVectorImpl<const SCEV *> &ops)
: SCEVCommutativeExpr(ID, scAddExpr, ops) {
SCEVAddExpr(const FoldingSetNodeIDRef ID,
const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scAddExpr, O, N) {
}
public:
@ -315,9 +316,9 @@ namespace llvm {
class SCEVMulExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
SCEVMulExpr(const FoldingSetNodeID &ID,
const SmallVectorImpl<const SCEV *> &ops)
: SCEVCommutativeExpr(ID, scMulExpr, ops) {
SCEVMulExpr(const FoldingSetNodeIDRef ID,
const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scMulExpr, O, N) {
}
public:
@ -339,7 +340,7 @@ namespace llvm {
const SCEV *LHS;
const SCEV *RHS;
SCEVUDivExpr(const FoldingSetNodeID &ID, const SCEV *lhs, const SCEV *rhs)
SCEVUDivExpr(const FoldingSetNodeIDRef ID, const SCEV *lhs, const SCEV *rhs)
: SCEV(ID, scUDivExpr), LHS(lhs), RHS(rhs) {}
public:
@ -389,10 +390,10 @@ namespace llvm {
const Loop *L;
SCEVAddRecExpr(const FoldingSetNodeID &ID,
const SmallVectorImpl<const SCEV *> &ops, const Loop *l)
: SCEVNAryExpr(ID, scAddRecExpr, ops), L(l) {
for (size_t i = 0, e = Operands.size(); i != e; ++i)
SCEVAddRecExpr(const FoldingSetNodeIDRef ID,
const SCEV *const *O, size_t N, const Loop *l)
: SCEVNAryExpr(ID, scAddRecExpr, O, N), L(l) {
for (size_t i = 0, e = NumOperands; i != e; ++i)
assert(Operands[i]->isLoopInvariant(l) &&
"Operands of AddRec must be loop-invariant!");
}
@ -471,9 +472,9 @@ namespace llvm {
class SCEVSMaxExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
SCEVSMaxExpr(const FoldingSetNodeID &ID,
const SmallVectorImpl<const SCEV *> &ops)
: SCEVCommutativeExpr(ID, scSMaxExpr, ops) {
SCEVSMaxExpr(const FoldingSetNodeIDRef ID,
const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scSMaxExpr, O, N) {
// Max never overflows.
setHasNoUnsignedWrap(true);
setHasNoSignedWrap(true);
@ -496,9 +497,9 @@ namespace llvm {
class SCEVUMaxExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
SCEVUMaxExpr(const FoldingSetNodeID &ID,
const SmallVectorImpl<const SCEV *> &ops)
: SCEVCommutativeExpr(ID, scUMaxExpr, ops) {
SCEVUMaxExpr(const FoldingSetNodeIDRef ID,
const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scUMaxExpr, O, N) {
// Max never overflows.
setHasNoUnsignedWrap(true);
setHasNoSignedWrap(true);
@ -523,7 +524,7 @@ namespace llvm {
friend class ScalarEvolution;
Value *V;
SCEVUnknown(const FoldingSetNodeID &ID, Value *v) :
SCEVUnknown(const FoldingSetNodeIDRef ID, Value *v) :
SCEV(ID, scUnknown), V(v) {}
public:

View File

@ -83,9 +83,9 @@ class MachineJumpTableInfo {
/// getEntryAlignment - Return the alignment of each entry in the jump table.
unsigned getEntryAlignment(const TargetData &TD) const;
/// getJumpTableIndex - Create a new jump table or return an existing one.
/// createJumpTableIndex - Create a new jump table.
///
unsigned getJumpTableIndex(const std::vector<MachineBasicBlock*> &DestBBs);
unsigned createJumpTableIndex(const std::vector<MachineBasicBlock*> &DestBBs);
/// isEmpty - Return true if there are no jump tables.
///

View File

@ -2516,6 +2516,11 @@ class InvokeInst : public TerminatorInst {
const Value *getCalledValue() const { return getOperand(0); }
Value *getCalledValue() { return getOperand(0); }
/// setCalledFunction - Set the function called.
void setCalledFunction(Value* Fn) {
Op<0>() = Fn;
}
// get*Dest - Return the destination basic blocks...
BasicBlock *getNormalDest() const {
return cast<BasicBlock>(getOperand(1));

View File

@ -892,7 +892,10 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse42_crc32_32 : GCCBuiltin<"__builtin_ia32_crc32si">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_x86_sse42_crc32_64 : GCCBuiltin<"__builtin_ia32_crc32di">,
def int_x86_sse42_crc64_8 :
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i8_ty],
[IntrNoMem]>;
def int_x86_sse42_crc64_64 : GCCBuiltin<"__builtin_ia32_crc32di">,
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
[IntrNoMem]>;
}

View File

@ -24,8 +24,10 @@ class raw_ostream;
class MCAsmLayout;
class MCAssembler;
class MCContext;
class MCCodeEmitter;
class MCExpr;
class MCFragment;
class MCObjectWriter;
class MCSection;
class MCSectionData;
class MCSymbol;
@ -35,7 +37,8 @@ class TargetAsmBackend;
/// MCAsmFixup - Represent a fixed size region of bytes inside some fragment
/// which needs to be rewritten. This region will either be rewritten by the
/// assembler or cause a relocation entry to be generated.
struct MCAsmFixup {
class MCAsmFixup {
public:
/// Offset - The offset inside the fragment which needs to be rewritten.
uint64_t Offset;
@ -45,14 +48,9 @@ struct MCAsmFixup {
/// Kind - The fixup kind.
MCFixupKind Kind;
/// FixedValue - The value to replace the fix up by.
//
// FIXME: This should not be here.
uint64_t FixedValue;
public:
MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind)
: Offset(_Offset), Value(&_Value), Kind(_Kind), FixedValue(0) {}
: Offset(_Offset), Value(&_Value), Kind(_Kind) {}
};
class MCFragment : public ilist_node<MCFragment> {
@ -590,6 +588,8 @@ class MCAssembler {
typedef SymbolDataListType::const_iterator const_symbol_iterator;
typedef SymbolDataListType::iterator symbol_iterator;
typedef std::vector<IndirectSymbolData>::const_iterator
const_indirect_symbol_iterator;
typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
private:
@ -600,6 +600,8 @@ class MCAssembler {
TargetAsmBackend &Backend;
MCCodeEmitter &Emitter;
raw_ostream &OS;
iplist<MCSectionData> Sections;
@ -621,21 +623,6 @@ class MCAssembler {
unsigned SubsectionsViaSymbols : 1;
private:
/// Check whether a fixup can be satisfied, or whether it needs to be relaxed
/// (increased in size, in order to hold its value correctly).
bool FixupNeedsRelaxation(MCAsmFixup &Fixup, MCDataFragment *DF);
/// LayoutSection - Assign offsets and sizes to the fragments in the section
/// \arg SD, and update the section size. The section file offset should
/// already have been computed.
void LayoutSection(MCSectionData &SD);
/// LayoutOnce - Perform one layout iteration and return true if any offsets
/// were adjusted.
bool LayoutOnce();
// FIXME: Make protected once we factor out object writer classes.
public:
/// Evaluate a fixup to a relocatable expression and the value which should be
/// placed into the fixup.
///
@ -653,6 +640,44 @@ class MCAssembler {
MCAsmFixup &Fixup, MCDataFragment *DF,
MCValue &Target, uint64_t &Value) const;
/// Check whether a fixup can be satisfied, or whether it needs to be relaxed
/// (increased in size, in order to hold its value correctly).
bool FixupNeedsRelaxation(MCAsmFixup &Fixup, MCDataFragment *DF);
/// LayoutSection - Assign offsets and sizes to the fragments in the section
/// \arg SD, and update the section size. The section file offset should
/// already have been computed.
void LayoutSection(MCSectionData &SD);
/// LayoutOnce - Perform one layout iteration and return true if any offsets
/// were adjusted.
bool LayoutOnce();
public:
/// Find the symbol which defines the atom containing given address, inside
/// the given section, or null if there is no such symbol.
//
// FIXME: Eliminate this, it is very slow.
const MCSymbolData *getAtomForAddress(const MCSectionData *Section,
uint64_t Address) const;
/// Find the symbol which defines the atom containing the given symbol, or
/// null if there is no such symbol.
//
// FIXME: Eliminate this, it is very slow.
const MCSymbolData *getAtom(const MCSymbolData *Symbol) const;
/// Check whether a particular symbol is visible to the linker and is required
/// in the symbol table, or whether it can be discarded by the assembler. This
/// also effects whether the assembler treats the label as potentially
/// defining a separate atom.
bool isSymbolLinkerVisible(const MCSymbolData *SD) const;
/// Emit the section contents using the given object writer.
//
// FIXME: Should MCAssembler always have a reference to the object writer?
void WriteSectionData(const MCSectionData *Section, MCObjectWriter *OW) const;
public:
/// Construct a new assembler instance.
///
@ -662,13 +687,16 @@ class MCAssembler {
// concrete and require clients to pass in a target like object. The other
// option is to make this abstract, and have targets provide concrete
// implementations as we do with AsmParser.
MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend, raw_ostream &OS);
MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend,
MCCodeEmitter &_Emitter, raw_ostream &OS);
~MCAssembler();
MCContext &getContext() const { return Context; }
TargetAsmBackend &getBackend() const { return Backend; }
MCCodeEmitter &getEmitter() const { return Emitter; }
/// Finish - Do final processing and write the object to the output stream.
void Finish();
@ -723,10 +751,16 @@ class MCAssembler {
indirect_symbol_iterator indirect_symbol_begin() {
return IndirectSymbols.begin();
}
const_indirect_symbol_iterator indirect_symbol_begin() const {
return IndirectSymbols.begin();
}
indirect_symbol_iterator indirect_symbol_end() {
return IndirectSymbols.end();
}
const_indirect_symbol_iterator indirect_symbol_end() const {
return IndirectSymbols.end();
}
size_t indirect_symbol_size() const { return IndirectSymbols.size(); }

View File

@ -22,6 +22,12 @@ template<typename T> class SmallVectorImpl;
/// MCFixupKindInfo - Target independent information on a fixup kind.
struct MCFixupKindInfo {
enum FixupKindFlags {
/// Is this fixup kind PCrelative. This is used by the assembler backend to
/// evaluate fixup values in a target independent manner when possible.
FKF_IsPCRel = (1 << 0)
};
/// A target specific name for the fixup kind. The names will be unique for
/// distinct kinds on any given target.
const char *Name;
@ -36,6 +42,9 @@ struct MCFixupKindInfo {
/// The number of bits written by this fixup. The bits are assumed to be
/// contiguous.
unsigned TargetSize;
/// Flags describing additional information on this fixup kind.
unsigned Flags;
};
/// MCCodeEmitter - Generic instruction encoding interface.

View File

@ -73,9 +73,10 @@ namespace llvm {
/// one if it does.
///
/// @param Name - The symbol name, for debugging purposes only, temporary
/// symbols do not surive assembly. If non-empty the name must be unique
/// across all symbols.
MCSymbol *GetOrCreateTemporarySymbol(StringRef Name = "");
/// symbols do not surive assembly.
MCSymbol *GetOrCreateTemporarySymbol(StringRef Name) {
return GetOrCreateSymbol(Name, true);
}
MCSymbol *GetOrCreateTemporarySymbol(const Twine &Name);
/// LookupSymbol - Get the symbol for \p Name, or null.

View File

@ -0,0 +1,162 @@
//===-- llvm/MC/MCObjectWriter.h - Object File Writer Interface -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCOBJECTWRITER_H
#define LLVM_MC_MCOBJECTWRITER_H
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/DataTypes.h"
#include <cassert>
namespace llvm {
class MCAsmFixup;
class MCAssembler;
class MCDataFragment;
class MCValue;
class raw_ostream;
/// MCObjectWriter - Defines the object file and target independent interfaces
/// used by the assembler backend to write native file format object files.
///
/// The object writer contains a few callbacks used by the assembler to allow
/// the object writer to modify the assembler data structures at appropriate
/// points. Once assembly is complete, the object writer is given the
/// MCAssembler instance, which contains all the symbol and section data which
/// should be emitted as part of WriteObject().
///
/// The object writer also contains a number of helper methods for writing
/// binary data to the output stream.
class MCObjectWriter {
MCObjectWriter(const MCObjectWriter &); // DO NOT IMPLEMENT
void operator=(const MCObjectWriter &); // DO NOT IMPLEMENT
protected:
raw_ostream &OS;
unsigned IsLittleEndian : 1;
protected: // Can only create subclasses.
MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian)
: OS(_OS), IsLittleEndian(_IsLittleEndian) {}
public:
virtual ~MCObjectWriter();
bool isLittleEndian() { return IsLittleEndian; }
raw_ostream &getStream() { return OS; }
/// @name High-Level API
/// @{
/// Perform any late binding of symbols (for example, to assign symbol indices
/// for use when generating relocations).
///
/// This routine is called by the assembler after layout and relaxation is
/// complete.
virtual void ExecutePostLayoutBinding(MCAssembler &Asm) = 0;
/// Record a relocation entry.
///
/// This routine is called by the assembler after layout and relaxation, and
/// post layout binding. The implementation is responsible for storing
/// information about the relocation so that it can be emitted during
/// WriteObject().
virtual void RecordRelocation(const MCAssembler &Asm,
const MCDataFragment &Fragment,
const MCAsmFixup &Fixup, MCValue Target,
uint64_t &FixedValue) = 0;
/// Write the object file.
///
/// This routine is called by the assembler after layout and relaxation is
/// complete, fixups have been evaluate and applied, and relocations
/// generated.
virtual void WriteObject(const MCAssembler &Asm) = 0;
/// @}
/// @name Binary Output
/// @{
void Write8(uint8_t Value) {
OS << char(Value);
}
void WriteLE16(uint16_t Value) {
Write8(uint8_t(Value >> 0));
Write8(uint8_t(Value >> 8));
}
void WriteLE32(uint32_t Value) {
WriteLE16(uint16_t(Value >> 0));
WriteLE16(uint16_t(Value >> 16));
}
void WriteLE64(uint64_t Value) {
WriteLE32(uint32_t(Value >> 0));
WriteLE32(uint32_t(Value >> 32));
}
void WriteBE16(uint16_t Value) {
Write8(uint8_t(Value >> 8));
Write8(uint8_t(Value >> 0));
}
void WriteBE32(uint32_t Value) {
WriteBE16(uint16_t(Value >> 16));
WriteBE16(uint16_t(Value >> 0));
}
void WriteBE64(uint64_t Value) {
WriteBE32(uint32_t(Value >> 32));
WriteBE32(uint32_t(Value >> 0));
}
void Write16(uint16_t Value) {
if (IsLittleEndian)
WriteLE16(Value);
else
WriteBE16(Value);
}
void Write32(uint32_t Value) {
if (IsLittleEndian)
WriteLE32(Value);
else
WriteBE32(Value);
}
void Write64(uint64_t Value) {
if (IsLittleEndian)
WriteLE64(Value);
else
WriteBE64(Value);
}
void WriteZeros(unsigned N) {
const char Zeros[16] = { 0 };
for (unsigned i = 0, e = N / 16; i != e; ++i)
OS << StringRef(Zeros, 16);
OS << StringRef(Zeros, N % 16);
}
void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
OS << Str;
if (ZeroFillSize)
WriteZeros(ZeroFillSize - Str.size());
}
/// @}
};
} // End llvm namespace
#endif

View File

@ -291,7 +291,8 @@ class TargetAsmBackend;
/// assembler.
///
/// \param InstPrint - If given, the instruction printer to use. If not given
/// the MCInst representation will be printed.
/// the MCInst representation will be printed. This method takes ownership of
/// InstPrint.
///
/// \param CE - If given, a code emitter to use to show the instruction
/// encoding inline with the assembly.

View File

@ -28,8 +28,7 @@ namespace llvm {
///
/// If the symbol is defined/emitted into the current translation unit, the
/// Section member is set to indicate what section it lives in. Otherwise, if
/// it is a reference to an external entity, it has a null section.
///
/// it is a reference to an external entity, it has a null section.
class MCSymbol {
// Special sentinal value for the absolute pseudo section.
//
@ -52,7 +51,7 @@ namespace llvm {
/// typically does not survive in the .o file's symbol table. Usually
/// "Lfoo" or ".foo".
unsigned IsTemporary : 1;
private: // MCContext creates and uniques these.
friend class MCContext;
MCSymbol(StringRef name, bool isTemporary)
@ -83,6 +82,12 @@ namespace llvm {
return Section != 0;
}
/// isInSection - Check if this symbol is defined in some section (i.e., it
/// is defined but not absolute).
bool isInSection() const {
return isDefined() && !isAbsolute();
}
/// isUndefined - Check if this symbol undefined (i.e., implicitly defined).
bool isUndefined() const {
return !isDefined();
@ -96,7 +101,7 @@ namespace llvm {
/// getSection - Get the section associated with a defined, non-absolute
/// symbol.
const MCSection &getSection() const {
assert(!isUndefined() && !isAbsolute() && "Invalid accessor!");
assert(isInSection() && "Invalid accessor!");
return *Section;
}

View File

@ -19,8 +19,9 @@
#include <cassert>
namespace llvm {
class MCSymbol;
class MCAsmInfo;
class MCSymbol;
class MCSymbolRefExpr;
class raw_ostream;
/// MCValue - This represents an "assembler immediate". In its most general
@ -34,13 +35,13 @@ class raw_ostream;
/// Note that this class must remain a simple POD value class, because we need
/// it to live in unions etc.
class MCValue {
const MCSymbol *SymA, *SymB;
const MCSymbolRefExpr *SymA, *SymB;
int64_t Cst;
public:
int64_t getConstant() const { return Cst; }
const MCSymbol *getSymA() const { return SymA; }
const MCSymbol *getSymB() const { return SymB; }
const MCSymbolRefExpr *getSymA() const { return SymA; }
const MCSymbolRefExpr *getSymB() const { return SymB; }
/// isAbsolute - Is this an absolute (as opposed to relocatable) value.
bool isAbsolute() const { return !SymA && !SymB; }
@ -57,11 +58,11 @@ class MCValue {
/// print - Print the value to the stream \arg OS.
void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
/// dump - Print the value to stderr.
void dump() const;
static MCValue get(const MCSymbol *SymA, const MCSymbol *SymB = 0,
static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=0,
int64_t Val = 0) {
MCValue R;
assert((!SymB || SymA) && "Invalid relocatable MCValue!");
@ -70,7 +71,7 @@ class MCValue {
R.SymB = SymB;
return R;
}
static MCValue get(int64_t Val) {
MCValue R;
R.Cst = Val;
@ -78,7 +79,7 @@ class MCValue {
R.SymB = 0;
return R;
}
};
} // end namespace llvm

View File

@ -0,0 +1,43 @@
//===-- llvm/MC/MachObjectWriter.h - Mach-O File Writer ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MACHOBJECTWRITER_H
#define LLVM_MC_MACHOBJECTWRITER_H
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
namespace llvm {
class MCAsmFixup;
class MCAssembler;
class MCDataFragment;
class MCValue;
class raw_ostream;
class MachObjectWriter : public MCObjectWriter {
void *Impl;
public:
MachObjectWriter(raw_ostream &OS, bool Is64Bit, bool IsLittleEndian = true);
virtual ~MachObjectWriter();
virtual void ExecutePostLayoutBinding(MCAssembler &Asm);
virtual void RecordRelocation(const MCAssembler &Asm,
const MCDataFragment &Fragment,
const MCAsmFixup &Fixup, MCValue Target,
uint64_t &FixedValue);
virtual void WriteObject(const MCAssembler &Asm);
};
} // End llvm namespace
#endif

View File

@ -15,9 +15,12 @@
#define LLVM_SUPPORT_ALLOCATOR_H
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/System/DataTypes.h"
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <cstddef>
namespace llvm {
@ -175,4 +178,22 @@ class BumpPtrAllocator {
} // end namespace llvm
inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) {
struct S {
char c;
#ifdef __GNUC__
char x __attribute__((aligned));
#else
union {
double D;
long double LD;
long long L;
void *P;
} x;
#endif
};
return Allocator.Allocate(Size, std::min((size_t)llvm::NextPowerOf2(Size),
offsetof(S, x)));
}
#endif // LLVM_SUPPORT_ALLOCATOR_H

View File

@ -56,4 +56,11 @@ class RecyclingAllocator {
}
template<class AllocatorType, class T, size_t Size, size_t Align>
inline void *operator new(size_t,
llvm::RecyclingAllocator<AllocatorType,
T, Size, Align> &Allocator) {
return Allocator.Allocate();
}
#endif

View File

@ -389,66 +389,66 @@ class InstrInfo {
// Standard Pseudo Instructions.
let isCodeGenOnly = 1 in {
def PHI : Instruction {
let OutOperandList = (ops);
let InOperandList = (ops variable_ops);
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "PHINODE";
let Namespace = "TargetOpcode";
}
def INLINEASM : Instruction {
let OutOperandList = (ops);
let InOperandList = (ops variable_ops);
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "";
let Namespace = "TargetOpcode";
}
def DBG_LABEL : Instruction {
let OutOperandList = (ops);
let InOperandList = (ops i32imm:$id);
let OutOperandList = (outs);
let InOperandList = (ins i32imm:$id);
let AsmString = "";
let Namespace = "TargetOpcode";
let hasCtrlDep = 1;
let isNotDuplicable = 1;
}
def EH_LABEL : Instruction {
let OutOperandList = (ops);
let InOperandList = (ops i32imm:$id);
let OutOperandList = (outs);
let InOperandList = (ins i32imm:$id);
let AsmString = "";
let Namespace = "TargetOpcode";
let hasCtrlDep = 1;
let isNotDuplicable = 1;
}
def GC_LABEL : Instruction {
let OutOperandList = (ops);
let InOperandList = (ops i32imm:$id);
let OutOperandList = (outs);
let InOperandList = (ins i32imm:$id);
let AsmString = "";
let Namespace = "TargetOpcode";
let hasCtrlDep = 1;
let isNotDuplicable = 1;
}
def KILL : Instruction {
let OutOperandList = (ops);
let InOperandList = (ops variable_ops);
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "";
let Namespace = "TargetOpcode";
let neverHasSideEffects = 1;
}
def EXTRACT_SUBREG : Instruction {
let OutOperandList = (ops unknown:$dst);
let InOperandList = (ops unknown:$supersrc, i32imm:$subidx);
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$supersrc, i32imm:$subidx);
let AsmString = "";
let Namespace = "TargetOpcode";
let neverHasSideEffects = 1;
}
def INSERT_SUBREG : Instruction {
let OutOperandList = (ops unknown:$dst);
let InOperandList = (ops unknown:$supersrc, unknown:$subsrc, i32imm:$subidx);
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$supersrc, unknown:$subsrc, i32imm:$subidx);
let AsmString = "";
let Namespace = "TargetOpcode";
let neverHasSideEffects = 1;
let Constraints = "$supersrc = $dst";
}
def IMPLICIT_DEF : Instruction {
let OutOperandList = (ops unknown:$dst);
let InOperandList = (ops);
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins);
let AsmString = "";
let Namespace = "TargetOpcode";
let neverHasSideEffects = 1;
@ -456,23 +456,23 @@ def IMPLICIT_DEF : Instruction {
let isAsCheapAsAMove = 1;
}
def SUBREG_TO_REG : Instruction {
let OutOperandList = (ops unknown:$dst);
let InOperandList = (ops unknown:$implsrc, unknown:$subsrc, i32imm:$subidx);
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$implsrc, unknown:$subsrc, i32imm:$subidx);
let AsmString = "";
let Namespace = "TargetOpcode";
let neverHasSideEffects = 1;
}
def COPY_TO_REGCLASS : Instruction {
let OutOperandList = (ops unknown:$dst);
let InOperandList = (ops unknown:$src, i32imm:$regclass);
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$src, i32imm:$regclass);
let AsmString = "";
let Namespace = "TargetOpcode";
let neverHasSideEffects = 1;
let isAsCheapAsAMove = 1;
}
def DBG_VALUE : Instruction {
let OutOperandList = (ops);
let InOperandList = (ops variable_ops);
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "DBG_VALUE";
let Namespace = "TargetOpcode";
let isAsCheapAsAMove = 1;
@ -491,6 +491,11 @@ class AsmParser {
// class. Generated AsmParser classes are always prefixed with the target
// name.
string AsmParserClassName = "AsmParser";
// AsmParserInstCleanup - If non-empty, this is the name of a custom function on the
// AsmParser class to call on every matched instruction. This can be used to
// perform target specific instruction post-processing.
string AsmParserInstCleanup = "";
// Variant - AsmParsers can be of multiple different variants. Variants are
// used to support targets that need to parser multiple formats for the

View File

@ -10,9 +10,15 @@
#ifndef LLVM_TARGET_TARGETASMBACKEND_H
#define LLVM_TARGET_TARGETASMBACKEND_H
#include "llvm/System/DataTypes.h"
namespace llvm {
class MCAsmFixup;
class MCDataFragment;
class MCObjectWriter;
class MCSection;
class Target;
class raw_ostream;
/// TargetAsmBackend - Generic interface to target specific assembler backends.
class TargetAsmBackend {
@ -24,11 +30,19 @@ class TargetAsmBackend {
/// TheTarget - The Target that this machine was created for.
const Target &TheTarget;
unsigned HasAbsolutizedSet : 1;
unsigned HasReliableSymbolDifference : 1;
unsigned HasScatteredSymbols : 1;
public:
virtual ~TargetAsmBackend();
const Target &getTarget() const { return TheTarget; }
/// createObjectWriter - Create a new MCObjectWriter instance for use by the
/// assembler backend to emit the final object file.
virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0;
/// hasAbsolutizedSet - Check whether this target "absolutizes"
/// assignments. That is, given code like:
/// a:
@ -40,7 +54,21 @@ class TargetAsmBackend {
/// value of L0 - L1. This distinction is only relevant for platforms that
/// support scattered symbols, since in the absence of scattered symbols (a -
/// b) cannot change after assembly.
virtual bool hasAbsolutizedSet() const { return false; }
bool hasAbsolutizedSet() const { return HasAbsolutizedSet; }
/// hasReliableSymbolDifference - Check whether this target implements
/// accurate relocations for differences between symbols. If not, differences
/// between symbols will always be relocatable expressions and any references
/// to temporary symbols will be assumed to be in the same atom, unless they
/// reside in a different section.
///
/// This should always be true (since it results in fewer relocations with no
/// loss of functionality), but is currently supported as a way to maintain
/// exact object compatibility with Darwin 'as' (on non-x86_64). It should
/// eventually should be eliminated. See also \see hasAbsolutizedSet.
bool hasReliableSymbolDifference() const {
return HasReliableSymbolDifference;
}
/// hasScatteredSymbols - Check whether this target supports scattered
/// symbols. If so, the assembler should assume that atoms can be scattered by
@ -50,13 +78,23 @@ class TargetAsmBackend {
///
/// Note that the assembler currently does not reason about atoms, instead it
/// assumes all temporary symbols reside in the "current atom".
virtual bool hasScatteredSymbols() const { return false; }
bool hasScatteredSymbols() const { return HasScatteredSymbols; }
/// doesSectionRequireSymbols - Check whether the given section requires that
/// all symbols (even temporaries) have symbol table entries.
virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
return false;
}
/// isVirtualSection - Check whether the given section is "virtual", that is
/// has no actual object file contents.
virtual bool isVirtualSection(const MCSection &Section) const = 0;
/// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided
/// data fragment, at the offset specified by the fixup and following the
/// fixup kind as appropriate.
virtual void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &Fragment,
uint64_t Value) const = 0;
};
} // End llvm namespace

View File

@ -307,7 +307,7 @@ class TargetLowering {
/// intrinsic will need to map to a MemIntrinsicNode (touches memory). If
/// this is the case, it returns true and store the intrinsic
/// information into the IntrinsicInfo that was passed to the function.
typedef struct IntrinsicInfo {
struct IntrinsicInfo {
unsigned opc; // target opcode
EVT memVT; // memory VT
const Value* ptrVal; // value representing memory location
@ -316,9 +316,9 @@ class TargetLowering {
bool vol; // is volatile?
bool readMem; // reads memory?
bool writeMem; // writes memory?
} IntrinisicInfo;
};
virtual bool getTgtMemIntrinsic(IntrinsicInfo& Info,
virtual bool getTgtMemIntrinsic(IntrinsicInfo &Info,
CallInst &I, unsigned Intrinsic) {
return false;
}

View File

@ -144,11 +144,6 @@ namespace llvm {
/// wth earlier copy coalescing.
extern bool StrongPHIElim;
/// DisableScheduling - This flag disables instruction scheduling. In
/// particular, it assigns an ordering to the SDNodes, which the scheduler
/// uses instead of its normal heuristics to perform scheduling.
extern bool DisableScheduling;
} // End llvm namespace
#endif

View File

@ -55,7 +55,7 @@ namespace llvm {
typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
typedef const MCAsmInfo *(*AsmInfoCtorFnTy)(const Target &T,
typedef MCAsmInfo *(*AsmInfoCtorFnTy)(const Target &T,
StringRef TT);
typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T,
const std::string &TT,
@ -68,7 +68,7 @@ namespace llvm {
typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T,
const MCAsmInfo &MAI);
typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,MCAsmParser &P);
typedef const MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T);
typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T);
typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
unsigned SyntaxVariant,
const MCAsmInfo &MAI,
@ -184,7 +184,7 @@ namespace llvm {
/// feature set; it should always be provided. Generally this should be
/// either the target triple from the module, or the target triple of the
/// host if that does not exist.
const MCAsmInfo *createAsmInfo(StringRef Triple) const {
MCAsmInfo *createAsmInfo(StringRef Triple) const {
if (!AsmInfoCtorFn)
return 0;
return AsmInfoCtorFn(*this, Triple);
@ -241,7 +241,7 @@ namespace llvm {
return AsmPrinterCtorFn(OS, TM, Streamer);
}
const MCDisassembler *createMCDisassembler() const {
MCDisassembler *createMCDisassembler() const {
if (!MCDisassemblerCtorFn)
return 0;
return MCDisassemblerCtorFn(*this);
@ -529,7 +529,7 @@ namespace llvm {
TargetRegistry::RegisterAsmInfo(T, &Allocator);
}
private:
static const MCAsmInfo *Allocator(const Target &T, StringRef TT) {
static MCAsmInfo *Allocator(const Target &T, StringRef TT) {
return new MCAsmInfoImpl(T, TT);
}

View File

@ -219,6 +219,7 @@ def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'.
def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'.
def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'.
def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand
def SDNPVariadic : SDNodeProperty; // Node has variable arguments.
//===----------------------------------------------------------------------===//
// Selection DAG Node definitions.

View File

@ -564,21 +564,6 @@ static Constant *SymbolicallyEvaluateGEP(Constant *const *Ops, unsigned NumOps,
unsigned BitWidth =
TD->getTypeSizeInBits(TD->getIntPtrType(Ptr->getContext()));
APInt BasePtr(BitWidth, 0);
bool BaseIsInt = true;
if (!Ptr->isNullValue()) {
// If this is a inttoptr from a constant int, we can fold this as the base,
// otherwise we can't.
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr))
if (CE->getOpcode() == Instruction::IntToPtr)
if (ConstantInt *Base = dyn_cast<ConstantInt>(CE->getOperand(0))) {
BasePtr = Base->getValue();
BasePtr.zextOrTrunc(BitWidth);
}
if (BasePtr == 0)
BaseIsInt = false;
}
// If this is a constant expr gep that is effectively computing an
// "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12'
@ -615,7 +600,14 @@ static Constant *SymbolicallyEvaluateGEP(Constant *const *Ops, unsigned NumOps,
// If the base value for this address is a literal integer value, fold the
// getelementptr to the resulting integer value casted to the pointer type.
if (BaseIsInt) {
APInt BasePtr(BitWidth, 0);
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr))
if (CE->getOpcode() == Instruction::IntToPtr)
if (ConstantInt *Base = dyn_cast<ConstantInt>(CE->getOperand(0))) {
BasePtr = Base->getValue();
BasePtr.zextOrTrunc(BitWidth);
}
if (Ptr->isNullValue() || BasePtr != 0) {
Constant *C = ConstantInt::get(Ptr->getContext(), Offset+BasePtr);
return ConstantExpr::getIntToPtr(C, ResultTy);
}
@ -1002,6 +994,8 @@ llvm::canConstantFoldCallTo(const Function *F) {
case Intrinsic::usub_with_overflow:
case Intrinsic::sadd_with_overflow:
case Intrinsic::ssub_with_overflow:
case Intrinsic::convert_from_fp16:
case Intrinsic::convert_to_fp16:
return true;
default:
return false;
@ -1082,6 +1076,15 @@ llvm::ConstantFoldCall(Function *F,
const Type *Ty = F->getReturnType();
if (NumOperands == 1) {
if (ConstantFP *Op = dyn_cast<ConstantFP>(Operands[0])) {
if (Name == "llvm.convert.to.fp16") {
APFloat Val(Op->getValueAPF());
bool lost = false;
Val.convert(APFloat::IEEEhalf, APFloat::rmNearestTiesToEven, &lost);
return ConstantInt::get(F->getContext(), Val.bitcastToAPInt());
}
if (!Ty->isFloatTy() && !Ty->isDoubleTy())
return 0;
/// Currently APFloat versions of these functions do not exist, so we use
@ -1166,6 +1169,20 @@ llvm::ConstantFoldCall(Function *F,
return ConstantInt::get(Ty, Op->getValue().countTrailingZeros());
else if (Name.startswith("llvm.ctlz"))
return ConstantInt::get(Ty, Op->getValue().countLeadingZeros());
else if (Name == "llvm.convert.from.fp16") {
APFloat Val(Op->getValue());
bool lost = false;
APFloat::opStatus status =
Val.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, &lost);
// Conversion is always precise.
status = status;
assert(status == APFloat::opOK && !lost &&
"Precision lost during fp16 constfolding");
return ConstantFP::get(F->getContext(), Val);
}
return 0;
}

View File

@ -119,8 +119,7 @@ bool LoopDependenceAnalysis::findOrInsertDependencePair(Value *A,
P = Pairs.FindNodeOrInsertPos(id, insertPos);
if (P) return true;
P = PairAllocator.Allocate<DependencePair>();
new (P) DependencePair(id, A, B);
P = new (PairAllocator) DependencePair(id, A, B);
Pairs.InsertNode(P, insertPos);
return false;
}

View File

@ -141,7 +141,7 @@ bool SCEV::isAllOnesValue() const {
}
SCEVCouldNotCompute::SCEVCouldNotCompute() :
SCEV(FoldingSetNodeID(), scCouldNotCompute) {}
SCEV(FoldingSetNodeIDRef(), scCouldNotCompute) {}
bool SCEVCouldNotCompute::isLoopInvariant(const Loop *L) const {
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
@ -177,8 +177,7 @@ const SCEV *ScalarEvolution::getConstant(ConstantInt *V) {
ID.AddPointer(V);
void *IP = 0;
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
SCEV *S = SCEVAllocator.Allocate<SCEVConstant>();
new (S) SCEVConstant(ID, V);
SCEV *S = new (SCEVAllocator) SCEVConstant(ID.Intern(SCEVAllocator), V);
UniqueSCEVs.InsertNode(S, IP);
return S;
}
@ -199,7 +198,7 @@ void SCEVConstant::print(raw_ostream &OS) const {
WriteAsOperand(OS, V, false);
}
SCEVCastExpr::SCEVCastExpr(const FoldingSetNodeID &ID,
SCEVCastExpr::SCEVCastExpr(const FoldingSetNodeIDRef ID,
unsigned SCEVTy, const SCEV *op, const Type *ty)
: SCEV(ID, SCEVTy), Op(op), Ty(ty) {}
@ -211,7 +210,7 @@ bool SCEVCastExpr::properlyDominates(BasicBlock *BB, DominatorTree *DT) const {
return Op->properlyDominates(BB, DT);
}
SCEVTruncateExpr::SCEVTruncateExpr(const FoldingSetNodeID &ID,
SCEVTruncateExpr::SCEVTruncateExpr(const FoldingSetNodeIDRef ID,
const SCEV *op, const Type *ty)
: SCEVCastExpr(ID, scTruncate, op, ty) {
assert((Op->getType()->isIntegerTy() || Op->getType()->isPointerTy()) &&
@ -223,7 +222,7 @@ void SCEVTruncateExpr::print(raw_ostream &OS) const {
OS << "(trunc " << *Op->getType() << " " << *Op << " to " << *Ty << ")";
}
SCEVZeroExtendExpr::SCEVZeroExtendExpr(const FoldingSetNodeID &ID,
SCEVZeroExtendExpr::SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID,
const SCEV *op, const Type *ty)
: SCEVCastExpr(ID, scZeroExtend, op, ty) {
assert((Op->getType()->isIntegerTy() || Op->getType()->isPointerTy()) &&
@ -235,7 +234,7 @@ void SCEVZeroExtendExpr::print(raw_ostream &OS) const {
OS << "(zext " << *Op->getType() << " " << *Op << " to " << *Ty << ")";
}
SCEVSignExtendExpr::SCEVSignExtendExpr(const FoldingSetNodeID &ID,
SCEVSignExtendExpr::SCEVSignExtendExpr(const FoldingSetNodeIDRef ID,
const SCEV *op, const Type *ty)
: SCEVCastExpr(ID, scSignExtend, op, ty) {
assert((Op->getType()->isIntegerTy() || Op->getType()->isPointerTy()) &&
@ -248,10 +247,10 @@ void SCEVSignExtendExpr::print(raw_ostream &OS) const {
}
void SCEVCommutativeExpr::print(raw_ostream &OS) const {
assert(Operands.size() > 1 && "This plus expr shouldn't exist!");
assert(NumOperands > 1 && "This plus expr shouldn't exist!");
const char *OpStr = getOperationStr();
OS << "(" << *Operands[0];
for (unsigned i = 1, e = Operands.size(); i != e; ++i)
for (unsigned i = 1, e = NumOperands; i != e; ++i)
OS << OpStr << *Operands[i];
OS << ")";
}
@ -329,7 +328,7 @@ SCEVAddRecExpr::properlyDominates(BasicBlock *BB, DominatorTree *DT) const {
void SCEVAddRecExpr::print(raw_ostream &OS) const {
OS << "{" << *Operands[0];
for (unsigned i = 1, e = Operands.size(); i != e; ++i)
for (unsigned i = 1, e = NumOperands; i != e; ++i)
OS << ",+," << *Operands[i];
OS << "}<";
WriteAsOperand(OS, L->getHeader(), /*PrintType=*/false);
@ -846,8 +845,8 @@ const SCEV *ScalarEvolution::getTruncateExpr(const SCEV *Op,
// The cast wasn't folded; create an explicit cast node.
// Recompute the insert position, as it may have been invalidated.
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
SCEV *S = SCEVAllocator.Allocate<SCEVTruncateExpr>();
new (S) SCEVTruncateExpr(ID, Op, Ty);
SCEV *S = new (SCEVAllocator) SCEVTruncateExpr(ID.Intern(SCEVAllocator),
Op, Ty);
UniqueSCEVs.InsertNode(S, IP);
return S;
}
@ -981,8 +980,8 @@ const SCEV *ScalarEvolution::getZeroExtendExpr(const SCEV *Op,
// The cast wasn't folded; create an explicit cast node.
// Recompute the insert position, as it may have been invalidated.
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
SCEV *S = SCEVAllocator.Allocate<SCEVZeroExtendExpr>();
new (S) SCEVZeroExtendExpr(ID, Op, Ty);
SCEV *S = new (SCEVAllocator) SCEVZeroExtendExpr(ID.Intern(SCEVAllocator),
Op, Ty);
UniqueSCEVs.InsertNode(S, IP);
return S;
}
@ -1116,8 +1115,8 @@ const SCEV *ScalarEvolution::getSignExtendExpr(const SCEV *Op,
// The cast wasn't folded; create an explicit cast node.
// Recompute the insert position, as it may have been invalidated.
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
SCEV *S = SCEVAllocator.Allocate<SCEVSignExtendExpr>();
new (S) SCEVSignExtendExpr(ID, Op, Ty);
SCEV *S = new (SCEVAllocator) SCEVSignExtendExpr(ID.Intern(SCEVAllocator),
Op, Ty);
UniqueSCEVs.InsertNode(S, IP);
return S;
}
@ -1202,23 +1201,23 @@ static bool
CollectAddOperandsWithScales(DenseMap<const SCEV *, APInt> &M,
SmallVector<const SCEV *, 8> &NewOps,
APInt &AccumulatedConstant,
const SmallVectorImpl<const SCEV *> &Ops,
const SCEV *const *Ops, size_t NumOperands,
const APInt &Scale,
ScalarEvolution &SE) {
bool Interesting = false;
// Iterate over the add operands.
for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
for (unsigned i = 0, e = NumOperands; i != e; ++i) {
const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(Ops[i]);
if (Mul && isa<SCEVConstant>(Mul->getOperand(0))) {
APInt NewScale =
Scale * cast<SCEVConstant>(Mul->getOperand(0))->getValue()->getValue();
if (Mul->getNumOperands() == 2 && isa<SCEVAddExpr>(Mul->getOperand(1))) {
// A multiplication of a constant with another add; recurse.
const SCEVAddExpr *Add = cast<SCEVAddExpr>(Mul->getOperand(1));
Interesting |=
CollectAddOperandsWithScales(M, NewOps, AccumulatedConstant,
cast<SCEVAddExpr>(Mul->getOperand(1))
->getOperands(),
Add->op_begin(), Add->getNumOperands(),
NewScale, SE);
} else {
// A multiplication of a constant with some other value. Update
@ -1427,7 +1426,8 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
SmallVector<const SCEV *, 8> NewOps;
APInt AccumulatedConstant(BitWidth, 0);
if (CollectAddOperandsWithScales(M, NewOps, AccumulatedConstant,
Ops, APInt(BitWidth, 1), *this)) {
Ops.data(), Ops.size(),
APInt(BitWidth, 1), *this)) {
// Some interesting folding opportunity is present, so its worthwhile to
// re-generate the operands list. Group the operands by constant scale,
// to avoid multiplying by the same constant scale multiple times.
@ -1611,8 +1611,10 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
SCEVAddExpr *S =
static_cast<SCEVAddExpr *>(UniqueSCEVs.FindNodeOrInsertPos(ID, IP));
if (!S) {
S = SCEVAllocator.Allocate<SCEVAddExpr>();
new (S) SCEVAddExpr(ID, Ops);
const SCEV **O = SCEVAllocator.Allocate<const SCEV *>(Ops.size());
std::uninitialized_copy(Ops.begin(), Ops.end(), O);
S = new (SCEVAllocator) SCEVAddExpr(ID.Intern(SCEVAllocator),
O, Ops.size());
UniqueSCEVs.InsertNode(S, IP);
}
if (HasNUW) S->setHasNoUnsignedWrap(true);
@ -1819,8 +1821,10 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
SCEVMulExpr *S =
static_cast<SCEVMulExpr *>(UniqueSCEVs.FindNodeOrInsertPos(ID, IP));
if (!S) {
S = SCEVAllocator.Allocate<SCEVMulExpr>();
new (S) SCEVMulExpr(ID, Ops);
const SCEV **O = SCEVAllocator.Allocate<const SCEV *>(Ops.size());
std::uninitialized_copy(Ops.begin(), Ops.end(), O);
S = new (SCEVAllocator) SCEVMulExpr(ID.Intern(SCEVAllocator),
O, Ops.size());
UniqueSCEVs.InsertNode(S, IP);
}
if (HasNUW) S->setHasNoUnsignedWrap(true);
@ -1880,9 +1884,7 @@ const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS,
const SCEV *Op = M->getOperand(i);
const SCEV *Div = getUDivExpr(Op, RHSC);
if (!isa<SCEVUDivExpr>(Div) && getMulExpr(Div, RHSC) == Op) {
const SmallVectorImpl<const SCEV *> &MOperands = M->getOperands();
Operands = SmallVector<const SCEV *, 4>(MOperands.begin(),
MOperands.end());
Operands = SmallVector<const SCEV *, 4>(M->op_begin(), M->op_end());
Operands[i] = Div;
return getMulExpr(Operands);
}
@ -1921,8 +1923,8 @@ const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS,
ID.AddPointer(RHS);
void *IP = 0;
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
SCEV *S = SCEVAllocator.Allocate<SCEVUDivExpr>();
new (S) SCEVUDivExpr(ID, LHS, RHS);
SCEV *S = new (SCEVAllocator) SCEVUDivExpr(ID.Intern(SCEVAllocator),
LHS, RHS);
UniqueSCEVs.InsertNode(S, IP);
return S;
}
@ -2030,8 +2032,10 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
SCEVAddRecExpr *S =
static_cast<SCEVAddRecExpr *>(UniqueSCEVs.FindNodeOrInsertPos(ID, IP));
if (!S) {
S = SCEVAllocator.Allocate<SCEVAddRecExpr>();
new (S) SCEVAddRecExpr(ID, Operands, L);
const SCEV **O = SCEVAllocator.Allocate<const SCEV *>(Operands.size());
std::uninitialized_copy(Operands.begin(), Operands.end(), O);
S = new (SCEVAllocator) SCEVAddRecExpr(ID.Intern(SCEVAllocator),
O, Operands.size(), L);
UniqueSCEVs.InsertNode(S, IP);
}
if (HasNUW) S->setHasNoUnsignedWrap(true);
@ -2130,8 +2134,10 @@ ScalarEvolution::getSMaxExpr(SmallVectorImpl<const SCEV *> &Ops) {
ID.AddPointer(Ops[i]);
void *IP = 0;
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
SCEV *S = SCEVAllocator.Allocate<SCEVSMaxExpr>();
new (S) SCEVSMaxExpr(ID, Ops);
const SCEV **O = SCEVAllocator.Allocate<const SCEV *>(Ops.size());
std::uninitialized_copy(Ops.begin(), Ops.end(), O);
SCEV *S = new (SCEVAllocator) SCEVSMaxExpr(ID.Intern(SCEVAllocator),
O, Ops.size());
UniqueSCEVs.InsertNode(S, IP);
return S;
}
@ -2227,8 +2233,10 @@ ScalarEvolution::getUMaxExpr(SmallVectorImpl<const SCEV *> &Ops) {
ID.AddPointer(Ops[i]);
void *IP = 0;
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
SCEV *S = SCEVAllocator.Allocate<SCEVUMaxExpr>();
new (S) SCEVUMaxExpr(ID, Ops);
const SCEV **O = SCEVAllocator.Allocate<const SCEV *>(Ops.size());
std::uninitialized_copy(Ops.begin(), Ops.end(), O);
SCEV *S = new (SCEVAllocator) SCEVUMaxExpr(ID.Intern(SCEVAllocator),
O, Ops.size());
UniqueSCEVs.InsertNode(S, IP);
return S;
}
@ -2290,8 +2298,7 @@ const SCEV *ScalarEvolution::getUnknown(Value *V) {
ID.AddPointer(V);
void *IP = 0;
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
SCEV *S = SCEVAllocator.Allocate<SCEVUnknown>();
new (S) SCEVUnknown(ID, V);
SCEV *S = new (SCEVAllocator) SCEVUnknown(ID.Intern(SCEVAllocator), V);
UniqueSCEVs.InsertNode(S, IP);
return S;
}

View File

@ -232,9 +232,7 @@ static bool FactorOutConstant(const SCEV *&S,
const SCEVConstant *FC = cast<SCEVConstant>(Factor);
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(M->getOperand(0)))
if (!C->getValue()->getValue().srem(FC->getValue()->getValue())) {
const SmallVectorImpl<const SCEV *> &MOperands = M->getOperands();
SmallVector<const SCEV *, 4> NewMulOps(MOperands.begin(),
MOperands.end());
SmallVector<const SCEV *, 4> NewMulOps(M->op_begin(), M->op_end());
NewMulOps[0] =
SE.getConstant(C->getValue()->getValue().sdiv(
FC->getValue()->getValue()));
@ -249,9 +247,7 @@ static bool FactorOutConstant(const SCEV *&S,
const SCEV *Remainder = SE.getIntegerSCEV(0, SOp->getType());
if (FactorOutConstant(SOp, Remainder, Factor, SE, TD) &&
Remainder->isZero()) {
const SmallVectorImpl<const SCEV *> &MOperands = M->getOperands();
SmallVector<const SCEV *, 4> NewMulOps(MOperands.begin(),
MOperands.end());
SmallVector<const SCEV *, 4> NewMulOps(M->op_begin(), M->op_end());
NewMulOps[i] = SOp;
S = SE.getMulExpr(NewMulOps);
return true;
@ -297,13 +293,11 @@ static void SimplifyAddOperands(SmallVectorImpl<const SCEV *> &Ops,
SE.getAddExpr(NoAddRecs);
// If it returned an add, use the operands. Otherwise it simplified
// the sum into a single value, so just use that.
Ops.clear();
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Sum))
Ops = Add->getOperands();
else {
Ops.clear();
if (!Sum->isZero())
Ops.push_back(Sum);
}
Ops.insert(Ops.end(), Add->op_begin(), Add->op_end());
else if (!Sum->isZero())
Ops.push_back(Sum);
// Then append the addrecs.
Ops.insert(Ops.end(), AddRecs.begin(), AddRecs.end());
}
@ -1060,10 +1054,9 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
if (CanonicalIV &&
SE.getTypeSizeInBits(CanonicalIV->getType()) >
SE.getTypeSizeInBits(Ty)) {
const SmallVectorImpl<const SCEV *> &Ops = S->getOperands();
SmallVector<const SCEV *, 4> NewOps(Ops.size());
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
NewOps[i] = SE.getAnyExtendExpr(Ops[i], CanonicalIV->getType());
SmallVector<const SCEV *, 4> NewOps(S->getNumOperands());
for (unsigned i = 0, e = S->getNumOperands(); i != e; ++i)
NewOps[i] = SE.getAnyExtendExpr(S->op_begin()[i], CanonicalIV->getType());
Value *V = expand(SE.getAddRecExpr(NewOps, S->getLoop()));
BasicBlock *SaveInsertBB = Builder.GetInsertBlock();
BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint();
@ -1078,8 +1071,7 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
// {X,+,F} --> X + {0,+,F}
if (!S->getStart()->isZero()) {
const SmallVectorImpl<const SCEV *> &SOperands = S->getOperands();
SmallVector<const SCEV *, 4> NewOps(SOperands.begin(), SOperands.end());
SmallVector<const SCEV *, 4> NewOps(S->op_begin(), S->op_end());
NewOps[0] = SE.getIntegerSCEV(0, Ty);
const SCEV *Rest = SE.getAddRecExpr(NewOps, L);
@ -1248,6 +1240,15 @@ Value *SCEVExpander::visitUMaxExpr(const SCEVUMaxExpr *S) {
return LHS;
}
Value *SCEVExpander::expandCodeFor(const SCEV *SH, const Type *Ty,
Instruction *I) {
BasicBlock::iterator IP = I;
while (isInsertedInstruction(IP) || isa<DbgInfoIntrinsic>(IP))
++IP;
Builder.SetInsertPoint(IP->getParent(), IP);
return expandCodeFor(SH, Ty);
}
Value *SCEVExpander::expandCodeFor(const SCEV *SH, const Type *Ty) {
// Expand the code for this SCEV.
Value *V = expand(SH);
@ -1286,9 +1287,7 @@ Value *SCEVExpander::expand(const SCEV *S) {
// there) so that it is guaranteed to dominate any user inside the loop.
if (L && S->hasComputableLoopEvolution(L) && L != PostIncLoop)
InsertPt = L->getHeader()->getFirstNonPHI();
while (isa<DbgInfoIntrinsic>(InsertPt))
InsertPt = llvm::next(BasicBlock::iterator(InsertPt));
while (isInsertedInstruction(InsertPt))
while (isInsertedInstruction(InsertPt) || isa<DbgInfoIntrinsic>(InsertPt))
InsertPt = llvm::next(BasicBlock::iterator(InsertPt));
break;
}
@ -1324,7 +1323,8 @@ void SCEVExpander::rememberInstruction(Value *I) {
// subsequently inserted code will be dominated.
if (Builder.GetInsertPoint() == I) {
BasicBlock::iterator It = cast<Instruction>(I);
do { ++It; } while (isInsertedInstruction(It));
do { ++It; } while (isInsertedInstruction(It) ||
isa<DbgInfoIntrinsic>(It));
Builder.SetInsertPoint(Builder.GetInsertBlock(), It);
}
}
@ -1332,7 +1332,7 @@ void SCEVExpander::rememberInstruction(Value *I) {
void SCEVExpander::restoreInsertPoint(BasicBlock *BB, BasicBlock::iterator I) {
// If we acquired more instructions since the old insert point was saved,
// advance past them.
while (isInsertedInstruction(I)) ++I;
while (isInsertedInstruction(I) || isa<DbgInfoIntrinsic>(I)) ++I;
Builder.SetInsertPoint(BB, I);
}

View File

@ -293,6 +293,8 @@ void BitcodeReaderValueList::ResolveConstantForwardRefs() {
} else if (ConstantStruct *UserCS = dyn_cast<ConstantStruct>(UserC)) {
NewC = ConstantStruct::get(Context, &NewOps[0], NewOps.size(),
UserCS->getType()->isPacked());
} else if (ConstantUnion *UserCU = dyn_cast<ConstantUnion>(UserC)) {
NewC = ConstantUnion::get(UserCU->getType(), NewOps[0]);
} else if (isa<ConstantVector>(UserC)) {
NewC = ConstantVector::get(&NewOps[0], NewOps.size());
} else {
@ -1015,6 +1017,11 @@ bool BitcodeReader::ParseConstants() {
Elts.push_back(ValueList.getConstantFwdRef(Record[i],
STy->getElementType(i)));
V = ConstantStruct::get(STy, Elts);
} else if (const UnionType *UnTy = dyn_cast<UnionType>(CurTy)) {
uint64_t Index = Record[0];
Constant *Val = ValueList.getConstantFwdRef(Record[1],
UnTy->getElementType(Index));
V = ConstantUnion::get(UnTy, Val);
} else if (const ArrayType *ATy = dyn_cast<ArrayType>(CurTy)) {
const Type *EltTy = ATy->getElementType();
for (unsigned i = 0; i != Size; ++i)

View File

@ -808,11 +808,25 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
else if (isCStr7)
AbbrevToUse = CString7Abbrev;
} else if (isa<ConstantArray>(C) || isa<ConstantStruct>(V) ||
isa<ConstantUnion>(C) || isa<ConstantVector>(V)) {
isa<ConstantVector>(V)) {
Code = bitc::CST_CODE_AGGREGATE;
for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
Record.push_back(VE.getValueID(C->getOperand(i)));
AbbrevToUse = AggregateAbbrev;
} else if (isa<ConstantUnion>(C)) {
Code = bitc::CST_CODE_AGGREGATE;
// Unions only have one entry but we must send type along with it.
const Type *EntryKind = C->getOperand(0)->getType();
const UnionType *UnTy = cast<UnionType>(C->getType());
int UnionIndex = UnTy->getElementTypeIndex(EntryKind);
assert(UnionIndex != -1 && "Constant union contains invalid entry");
Record.push_back(UnionIndex);
Record.push_back(VE.getValueID(C->getOperand(0)));
AbbrevToUse = AggregateAbbrev;
} else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
switch (CE->getOpcode()) {
default:

View File

@ -1138,6 +1138,21 @@ static void EmitGlobalConstantStruct(const ConstantStruct *CS,
"Layout of constant struct may be incorrect!");
}
static void EmitGlobalConstantUnion(const ConstantUnion *CU,
unsigned AddrSpace, AsmPrinter &AP) {
const TargetData *TD = AP.TM.getTargetData();
unsigned Size = TD->getTypeAllocSize(CU->getType());
const Constant *Contents = CU->getOperand(0);
unsigned FilledSize = TD->getTypeAllocSize(Contents->getType());
// Print the actually filled part
AP.EmitGlobalConstant(Contents, AddrSpace);
// And pad with enough zeroes
AP.OutStreamer.EmitZeros(Size-FilledSize, AddrSpace);
}
static void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
AsmPrinter &AP) {
// FP Constants are printed as integer constants to avoid losing
@ -1257,9 +1272,6 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) {
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
return EmitGlobalConstantFP(CFP, AddrSpace, *this);
if (const ConstantVector *V = dyn_cast<ConstantVector>(CV))
return EmitGlobalConstantVector(V, AddrSpace, *this);
if (isa<ConstantPointerNull>(CV)) {
unsigned Size = TM.getTargetData()->getTypeAllocSize(CV->getType());
@ -1267,6 +1279,12 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) {
return;
}
if (const ConstantUnion *CVU = dyn_cast<ConstantUnion>(CV))
return EmitGlobalConstantUnion(CVU, AddrSpace, *this);
if (const ConstantVector *V = dyn_cast<ConstantVector>(CV))
return EmitGlobalConstantVector(V, AddrSpace, *this);
// Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it
// thread the streamer with EmitValue.
OutStreamer.EmitValue(LowerConstant(CV, *this),

View File

@ -2531,8 +2531,8 @@ void DwarfDebug::emitDebugInfo() {
Asm->OutStreamer.AddComment("DWARF version number");
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Offset Into Abbrev. Section");
EmitSectionOffset(getTempLabel("abbrev_begin"),getTempLabel("section_abbrev"),
true, false);
EmitSectionOffset(getTempLabel("abbrev_begin"),getTempLabel("section_abbrev"),
true);
Asm->OutStreamer.AddComment("Address Size (in bytes)");
Asm->EmitInt8(TD->getPointerSize());
@ -2842,8 +2842,8 @@ emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo) {
Asm->OutStreamer.EmitLabel(DebugFrameBegin);
Asm->OutStreamer.AddComment("FDE CIE offset");
EmitSectionOffset(getTempLabel("debug_frame_common"),
getTempLabel("section_debug_frame"), true, false);
EmitSectionOffset(getTempLabel("debug_frame_common"),
getTempLabel("section_debug_frame"), true);
Asm->OutStreamer.AddComment("FDE initial location");
MCSymbol *FuncBeginSym = getDWLabel("func_begin", DebugFrameInfo.Number);
@ -2878,8 +2878,7 @@ void DwarfDebug::emitDebugPubNames() {
Asm->OutStreamer.AddComment("Offset of Compilation Unit Info");
EmitSectionOffset(getDWLabel("info_begin", ModuleCU->getID()),
getTempLabel("section_info"),
true, false);
getTempLabel("section_info"), true);
Asm->OutStreamer.AddComment("Compilation Unit Length");
EmitDifference(getDWLabel("info_end", ModuleCU->getID()),
@ -2920,7 +2919,7 @@ void DwarfDebug::emitDebugPubTypes() {
Asm->OutStreamer.AddComment("Offset of Compilation ModuleCU Info");
EmitSectionOffset(getDWLabel("info_begin", ModuleCU->getID()),
getTempLabel("section_info"), true, false);
getTempLabel("section_info"), true);
Asm->OutStreamer.AddComment("Compilation ModuleCU Length");
EmitDifference(getDWLabel("info_end", ModuleCU->getID()),
@ -3068,8 +3067,8 @@ void DwarfDebug::emitDebugInlineInfo() {
getTempLabel("section_str"), true);
Asm->OutStreamer.AddComment("Function name");
EmitSectionOffset(getStringPoolEntry(Name), getTempLabel("section_str"),
false, true);
EmitSectionOffset(getStringPoolEntry(Name), getTempLabel("section_str"),
true);
EmitULEB128(Labels.size(), "Inline count");
for (SmallVector<InlineInfoLabels, 4>::iterator LI = Labels.begin(),

View File

@ -192,7 +192,7 @@ bool BranchFolder::OptimizeFunction(MachineFunction &MF,
MadeChange |= MadeChangeThisIteration;
}
// See if any jump tables have become mergable or dead as the code generator
// See if any jump tables have become dead as the code generator
// did its thing.
MachineJumpTableInfo *JTI = MF.getJumpTableInfo();
if (JTI == 0) {
@ -200,27 +200,8 @@ bool BranchFolder::OptimizeFunction(MachineFunction &MF,
return MadeChange;
}
const std::vector<MachineJumpTableEntry> &JTs = JTI->getJumpTables();
// Figure out how these jump tables should be merged.
std::vector<unsigned> JTMapping;
JTMapping.reserve(JTs.size());
// We always keep the 0th jump table.
JTMapping.push_back(0);
// Scan the jump tables, seeing if there are any duplicates. Note that this
// is N^2, which should be fixed someday.
for (unsigned i = 1, e = JTs.size(); i != e; ++i) {
if (JTs[i].MBBs.empty())
JTMapping.push_back(i);
else
JTMapping.push_back(JTI->getJumpTableIndex(JTs[i].MBBs));
}
// If a jump table was merge with another one, walk the function rewriting
// references to jump tables to reference the new JT ID's. Keep track of
// whether we see a jump table idx, if not, we can delete the JT.
BitVector JTIsLive(JTs.size());
// Walk the function to find jump tables that are live.
BitVector JTIsLive(JTI->getJumpTables().size());
for (MachineFunction::iterator BB = MF.begin(), E = MF.end();
BB != E; ++BB) {
for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
@ -228,17 +209,14 @@ bool BranchFolder::OptimizeFunction(MachineFunction &MF,
for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) {
MachineOperand &Op = I->getOperand(op);
if (!Op.isJTI()) continue;
unsigned NewIdx = JTMapping[Op.getIndex()];
Op.setIndex(NewIdx);
// Remember that this JT is live.
JTIsLive.set(NewIdx);
JTIsLive.set(Op.getIndex());
}
}
// Finally, remove dead jump tables. This happens either because the
// indirect jump was unreachable (and thus deleted) or because the jump
// table was merged with some other one.
// Finally, remove dead jump tables. This happens when the
// indirect jump was unreachable (and thus deleted).
for (unsigned i = 0, e = JTIsLive.size(); i != e; ++i)
if (!JTIsLive.test(i)) {
JTI->RemoveJumpTable(i);
@ -1143,22 +1121,6 @@ bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) {
!IsBetterFallthrough(PriorTBB, MBB))
DoTransform = false;
// We don't want to do this transformation if we have control flow like:
// br cond BB2
// BB1:
// ..
// jmp BBX
// BB2:
// ..
// ret
//
// In this case, we could actually be moving the return block *into* a
// loop!
if (DoTransform && !MBB->succ_empty() &&
(!PriorTBB->canFallThrough() || PriorTBB->empty()))
DoTransform = false;
if (DoTransform) {
// Reverse the branch so we will fall through on the previous true cond.
SmallVector<MachineOperand, 4> NewPriorCond(PriorCond);

View File

@ -332,7 +332,7 @@ void MachineCodeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
MCSymbol *MachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
DebugLoc DL) const {
MCSymbol *Label = MBB.getParent()->getContext().GetOrCreateTemporarySymbol();
MCSymbol *Label = MBB.getParent()->getContext().CreateTempSymbol();
BuildMI(MBB, MI, DL, TII->get(TargetOpcode::GC_LABEL)).addSym(Label);
return Label;
}

View File

@ -141,7 +141,7 @@ void LiveIntervals::printInstrs(raw_ostream &OS) const {
for (MachineBasicBlock::iterator mii = mbbi->begin(),
mie = mbbi->end(); mii != mie; ++mii) {
if (mii->isDebugValue())
OS << SlotIndex::getEmptyKey() << '\t' << *mii;
OS << " \t" << *mii;
else
OS << getInstructionIndex(mii) << '\t' << *mii;
}
@ -583,6 +583,16 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
// Look for kills, if it reaches a def before it's killed, then it shouldn't
// be considered a livein.
MachineBasicBlock::iterator mi = MBB->begin();
MachineBasicBlock::iterator E = MBB->end();
// Skip over DBG_VALUE at the start of the MBB.
if (mi != E && mi->isDebugValue()) {
while (++mi != E && mi->isDebugValue())
;
if (mi == E)
// MBB is empty except for DBG_VALUE's.
return;
}
SlotIndex baseIndex = MIIdx;
SlotIndex start = baseIndex;
if (getInstructionFromIndex(baseIndex) == 0)
@ -591,12 +601,7 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
SlotIndex end = baseIndex;
bool SeenDefUse = false;
MachineBasicBlock::iterator E = MBB->end();
while (mi != E) {
while (mi != E && mi->isDebugValue())
++mi;
if (mi == E)
break;
if (mi->killsRegister(interval.reg, tri_)) {
DEBUG(dbgs() << " killed");
end = baseIndex.getDefIndex();
@ -613,10 +618,11 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
break;
}
++mi;
if (mi != E && !mi->isDebugValue()) {
while (++mi != E && mi->isDebugValue())
// Skip over DBG_VALUE.
;
if (mi != E)
baseIndex = indexes_->getNextNonNullIndex(baseIndex);
}
}
// Live-in register might not be used at all.

View File

@ -88,18 +88,15 @@ MachineFunction::MachineFunction(Function *F, const TargetMachine &TM,
unsigned FunctionNum, MCContext &ctx)
: Fn(F), Target(TM), Ctx(ctx) {
if (TM.getRegisterInfo())
RegInfo = new (Allocator.Allocate<MachineRegisterInfo>())
MachineRegisterInfo(*TM.getRegisterInfo());
RegInfo = new (Allocator) MachineRegisterInfo(*TM.getRegisterInfo());
else
RegInfo = 0;
MFInfo = 0;
FrameInfo = new (Allocator.Allocate<MachineFrameInfo>())
MachineFrameInfo(*TM.getFrameInfo());
FrameInfo = new (Allocator) MachineFrameInfo(*TM.getFrameInfo());
if (Fn->hasFnAttr(Attribute::StackAlignment))
FrameInfo->setMaxAlignment(Attribute::getStackAlignmentFromAttrs(
Fn->getAttributes().getFnAttributes()));
ConstantPool = new (Allocator.Allocate<MachineConstantPool>())
MachineConstantPool(TM.getTargetData());
ConstantPool = new (Allocator) MachineConstantPool(TM.getTargetData());
Alignment = TM.getTargetLowering()->getFunctionAlignment(F);
FunctionNumber = FunctionNum;
JumpTableInfo = 0;
@ -132,7 +129,7 @@ MachineJumpTableInfo *MachineFunction::
getOrCreateJumpTableInfo(unsigned EntryKind) {
if (JumpTableInfo) return JumpTableInfo;
JumpTableInfo = new (Allocator.Allocate<MachineJumpTableInfo>())
JumpTableInfo = new (Allocator)
MachineJumpTableInfo((MachineJumpTableInfo::JTEntryKind)EntryKind);
return JumpTableInfo;
}
@ -229,14 +226,13 @@ MachineMemOperand *
MachineFunction::getMachineMemOperand(const Value *v, unsigned f,
int64_t o, uint64_t s,
unsigned base_alignment) {
return new (Allocator.Allocate<MachineMemOperand>())
MachineMemOperand(v, f, o, s, base_alignment);
return new (Allocator) MachineMemOperand(v, f, o, s, base_alignment);
}
MachineMemOperand *
MachineFunction::getMachineMemOperand(const MachineMemOperand *MMO,
int64_t Offset, uint64_t Size) {
return new (Allocator.Allocate<MachineMemOperand>())
return new (Allocator)
MachineMemOperand(MMO->getValue(), MMO->getFlags(),
int64_t(uint64_t(MMO->getOffset()) +
uint64_t(Offset)),
@ -600,17 +596,15 @@ unsigned MachineJumpTableInfo::getEntryAlignment(const TargetData &TD) const {
return ~0;
}
/// getJumpTableIndex - Create a new jump table entry in the jump table info
/// or return an existing one.
/// createJumpTableIndex - Create a new jump table entry in the jump table info.
///
unsigned MachineJumpTableInfo::getJumpTableIndex(
unsigned MachineJumpTableInfo::createJumpTableIndex(
const std::vector<MachineBasicBlock*> &DestBBs) {
assert(!DestBBs.empty() && "Cannot create an empty jump table!");
JumpTables.push_back(MachineJumpTableEntry(DestBBs));
return JumpTables.size()-1;
}
/// ReplaceMBBInJumpTables - If Old is the target of any jump tables, update
/// the jump tables to branch to New instead.
bool MachineJumpTableInfo::ReplaceMBBInJumpTables(MachineBasicBlock *Old,

View File

@ -739,7 +739,7 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
// Physical registers and those that are not live-out of the block are
// killed/dead at their last use/def within this block.
if (isPhysReg || !usedOutsideBlock || BBEndsInReturn)
if (isPhysReg || !usedOutsideBlock || BBEndsInReturn) {
if (MO.isUse()) {
// Don't mark uses that are tied to defs as kills.
if (!MI->isRegTiedToDefOperand(idx))
@ -747,6 +747,7 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
} else {
MO.setIsDead(true);
}
}
}
}

View File

@ -851,8 +851,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
case ISD::MERGE_VALUES:
case ISD::EH_RETURN:
case ISD::FRAME_TO_ARGS_OFFSET:
case ISD::FP16_TO_FP32:
case ISD::FP32_TO_FP16:
// These operations lie about being legal: when they claim to be legal,
// they should actually be expanded.
Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));

View File

@ -2167,7 +2167,7 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain,
} else
return LdOp;
} else {
unsigned NumElts = WidenWidth / LdWidth;
unsigned NumElts = WidenWidth / NewVTWidth;
EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NumElts);
SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
return DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, VecOp);

View File

@ -906,8 +906,7 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, EVT VT, bool isT) {
return SDValue(N, 0);
if (!N) {
N = NodeAllocator.Allocate<ConstantSDNode>();
new (N) ConstantSDNode(isT, &Val, EltVT);
N = new (NodeAllocator) ConstantSDNode(isT, &Val, EltVT);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
}
@ -950,8 +949,7 @@ SDValue SelectionDAG::getConstantFP(const ConstantFP& V, EVT VT, bool isTarget){
return SDValue(N, 0);
if (!N) {
N = NodeAllocator.Allocate<ConstantFPSDNode>();
new (N) ConstantFPSDNode(isTarget, &V, EltVT);
N = new (NodeAllocator) ConstantFPSDNode(isTarget, &V, EltVT);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
}
@ -1010,8 +1008,8 @@ SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV,
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<GlobalAddressSDNode>();
new (N) GlobalAddressSDNode(Opc, GV, VT, Offset, TargetFlags);
SDNode *N = new (NodeAllocator) GlobalAddressSDNode(Opc, GV, VT,
Offset, TargetFlags);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -1026,8 +1024,7 @@ SDValue SelectionDAG::getFrameIndex(int FI, EVT VT, bool isTarget) {
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<FrameIndexSDNode>();
new (N) FrameIndexSDNode(FI, VT, isTarget);
SDNode *N = new (NodeAllocator) FrameIndexSDNode(FI, VT, isTarget);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -1046,8 +1043,8 @@ SDValue SelectionDAG::getJumpTable(int JTI, EVT VT, bool isTarget,
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<JumpTableSDNode>();
new (N) JumpTableSDNode(JTI, VT, isTarget, TargetFlags);
SDNode *N = new (NodeAllocator) JumpTableSDNode(JTI, VT, isTarget,
TargetFlags);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -1072,8 +1069,8 @@ SDValue SelectionDAG::getConstantPool(Constant *C, EVT VT,
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<ConstantPoolSDNode>();
new (N) ConstantPoolSDNode(isTarget, C, VT, Offset, Alignment, TargetFlags);
SDNode *N = new (NodeAllocator) ConstantPoolSDNode(isTarget, C, VT, Offset,
Alignment, TargetFlags);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -1099,8 +1096,8 @@ SDValue SelectionDAG::getConstantPool(MachineConstantPoolValue *C, EVT VT,
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<ConstantPoolSDNode>();
new (N) ConstantPoolSDNode(isTarget, C, VT, Offset, Alignment, TargetFlags);
SDNode *N = new (NodeAllocator) ConstantPoolSDNode(isTarget, C, VT, Offset,
Alignment, TargetFlags);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -1114,8 +1111,7 @@ SDValue SelectionDAG::getBasicBlock(MachineBasicBlock *MBB) {
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<BasicBlockSDNode>();
new (N) BasicBlockSDNode(MBB);
SDNode *N = new (NodeAllocator) BasicBlockSDNode(MBB);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -1130,8 +1126,7 @@ SDValue SelectionDAG::getValueType(EVT VT) {
ExtendedValueTypeNodes[VT] : ValueTypeNodes[VT.getSimpleVT().SimpleTy];
if (N) return SDValue(N, 0);
N = NodeAllocator.Allocate<VTSDNode>();
new (N) VTSDNode(VT);
N = new (NodeAllocator) VTSDNode(VT);
AllNodes.push_back(N);
return SDValue(N, 0);
}
@ -1139,8 +1134,7 @@ SDValue SelectionDAG::getValueType(EVT VT) {
SDValue SelectionDAG::getExternalSymbol(const char *Sym, EVT VT) {
SDNode *&N = ExternalSymbols[Sym];
if (N) return SDValue(N, 0);
N = NodeAllocator.Allocate<ExternalSymbolSDNode>();
new (N) ExternalSymbolSDNode(false, Sym, 0, VT);
N = new (NodeAllocator) ExternalSymbolSDNode(false, Sym, 0, VT);
AllNodes.push_back(N);
return SDValue(N, 0);
}
@ -1151,8 +1145,7 @@ SDValue SelectionDAG::getTargetExternalSymbol(const char *Sym, EVT VT,
TargetExternalSymbols[std::pair<std::string,unsigned char>(Sym,
TargetFlags)];
if (N) return SDValue(N, 0);
N = NodeAllocator.Allocate<ExternalSymbolSDNode>();
new (N) ExternalSymbolSDNode(true, Sym, TargetFlags, VT);
N = new (NodeAllocator) ExternalSymbolSDNode(true, Sym, TargetFlags, VT);
AllNodes.push_back(N);
return SDValue(N, 0);
}
@ -1162,8 +1155,7 @@ SDValue SelectionDAG::getCondCode(ISD::CondCode Cond) {
CondCodeNodes.resize(Cond+1);
if (CondCodeNodes[Cond] == 0) {
CondCodeSDNode *N = NodeAllocator.Allocate<CondCodeSDNode>();
new (N) CondCodeSDNode(Cond);
CondCodeSDNode *N = new (NodeAllocator) CondCodeSDNode(Cond);
CondCodeNodes[Cond] = N;
AllNodes.push_back(N);
}
@ -1268,8 +1260,8 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, DebugLoc dl, SDValue N1,
int *MaskAlloc = OperandAllocator.Allocate<int>(NElts);
memcpy(MaskAlloc, &MaskVec[0], NElts * sizeof(int));
ShuffleVectorSDNode *N = NodeAllocator.Allocate<ShuffleVectorSDNode>();
new (N) ShuffleVectorSDNode(VT, dl, N1, N2, MaskAlloc);
ShuffleVectorSDNode *N =
new (NodeAllocator) ShuffleVectorSDNode(VT, dl, N1, N2, MaskAlloc);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -1292,8 +1284,8 @@ SDValue SelectionDAG::getConvertRndSat(EVT VT, DebugLoc dl,
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
CvtRndSatSDNode *N = NodeAllocator.Allocate<CvtRndSatSDNode>();
new (N) CvtRndSatSDNode(VT, dl, Ops, 5, Code);
CvtRndSatSDNode *N = new (NodeAllocator) CvtRndSatSDNode(VT, dl, Ops, 5,
Code);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -1307,8 +1299,7 @@ SDValue SelectionDAG::getRegister(unsigned RegNo, EVT VT) {
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<RegisterSDNode>();
new (N) RegisterSDNode(RegNo, VT);
SDNode *N = new (NodeAllocator) RegisterSDNode(RegNo, VT);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -1323,8 +1314,7 @@ SDValue SelectionDAG::getEHLabel(DebugLoc dl, SDValue Root, MCSymbol *Label) {
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<EHLabelSDNode>();
new (N) EHLabelSDNode(dl, Root, Label);
SDNode *N = new (NodeAllocator) EHLabelSDNode(dl, Root, Label);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -1344,8 +1334,7 @@ SDValue SelectionDAG::getBlockAddress(BlockAddress *BA, EVT VT,
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<BlockAddressSDNode>();
new (N) BlockAddressSDNode(Opc, VT, BA, TargetFlags);
SDNode *N = new (NodeAllocator) BlockAddressSDNode(Opc, VT, BA, TargetFlags);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -1363,8 +1352,7 @@ SDValue SelectionDAG::getSrcValue(const Value *V) {
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<SrcValueSDNode>();
new (N) SrcValueSDNode(V);
SDNode *N = new (NodeAllocator) SrcValueSDNode(V);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -2313,8 +2301,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT) {
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<SDNode>();
new (N) SDNode(Opcode, DL, getVTList(VT));
SDNode *N = new (NodeAllocator) SDNode(Opcode, DL, getVTList(VT));
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
@ -2542,12 +2529,10 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL,
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
N = NodeAllocator.Allocate<UnarySDNode>();
new (N) UnarySDNode(Opcode, DL, VTs, Operand);
N = new (NodeAllocator) UnarySDNode(Opcode, DL, VTs, Operand);
CSEMap.InsertNode(N, IP);
} else {
N = NodeAllocator.Allocate<UnarySDNode>();
new (N) UnarySDNode(Opcode, DL, VTs, Operand);
N = new (NodeAllocator) UnarySDNode(Opcode, DL, VTs, Operand);
}
AllNodes.push_back(N);
@ -2975,12 +2960,10 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT,
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
N = NodeAllocator.Allocate<BinarySDNode>();
new (N) BinarySDNode(Opcode, DL, VTs, N1, N2);
N = new (NodeAllocator) BinarySDNode(Opcode, DL, VTs, N1, N2);
CSEMap.InsertNode(N, IP);
} else {
N = NodeAllocator.Allocate<BinarySDNode>();
new (N) BinarySDNode(Opcode, DL, VTs, N1, N2);
N = new (NodeAllocator) BinarySDNode(Opcode, DL, VTs, N1, N2);
}
AllNodes.push_back(N);
@ -3053,12 +3036,10 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT,
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
N = NodeAllocator.Allocate<TernarySDNode>();
new (N) TernarySDNode(Opcode, DL, VTs, N1, N2, N3);
N = new (NodeAllocator) TernarySDNode(Opcode, DL, VTs, N1, N2, N3);
CSEMap.InsertNode(N, IP);
} else {
N = NodeAllocator.Allocate<TernarySDNode>();
new (N) TernarySDNode(Opcode, DL, VTs, N1, N2, N3);
N = new (NodeAllocator) TernarySDNode(Opcode, DL, VTs, N1, N2, N3);
}
AllNodes.push_back(N);
@ -3659,8 +3640,8 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT,
cast<AtomicSDNode>(E)->refineAlignment(MMO);
return SDValue(E, 0);
}
SDNode* N = NodeAllocator.Allocate<AtomicSDNode>();
new (N) AtomicSDNode(Opcode, dl, VTs, MemVT, Chain, Ptr, Cmp, Swp, MMO);
SDNode *N = new (NodeAllocator) AtomicSDNode(Opcode, dl, VTs, MemVT, Chain,
Ptr, Cmp, Swp, MMO);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -3722,8 +3703,8 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT,
cast<AtomicSDNode>(E)->refineAlignment(MMO);
return SDValue(E, 0);
}
SDNode* N = NodeAllocator.Allocate<AtomicSDNode>();
new (N) AtomicSDNode(Opcode, dl, VTs, MemVT, Chain, Ptr, Val, MMO);
SDNode *N = new (NodeAllocator) AtomicSDNode(Opcode, dl, VTs, MemVT, Chain,
Ptr, Val, MMO);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -3801,12 +3782,12 @@ SelectionDAG::getMemIntrinsicNode(unsigned Opcode, DebugLoc dl, SDVTList VTList,
return SDValue(E, 0);
}
N = NodeAllocator.Allocate<MemIntrinsicSDNode>();
new (N) MemIntrinsicSDNode(Opcode, dl, VTList, Ops, NumOps, MemVT, MMO);
N = new (NodeAllocator) MemIntrinsicSDNode(Opcode, dl, VTList, Ops, NumOps,
MemVT, MMO);
CSEMap.InsertNode(N, IP);
} else {
N = NodeAllocator.Allocate<MemIntrinsicSDNode>();
new (N) MemIntrinsicSDNode(Opcode, dl, VTList, Ops, NumOps, MemVT, MMO);
N = new (NodeAllocator) MemIntrinsicSDNode(Opcode, dl, VTList, Ops, NumOps,
MemVT, MMO);
}
AllNodes.push_back(N);
return SDValue(N, 0);
@ -3879,8 +3860,8 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, DebugLoc dl,
cast<LoadSDNode>(E)->refineAlignment(MMO);
return SDValue(E, 0);
}
SDNode *N = NodeAllocator.Allocate<LoadSDNode>();
new (N) LoadSDNode(Ops, dl, VTs, AM, ExtType, MemVT, MMO);
SDNode *N = new (NodeAllocator) LoadSDNode(Ops, dl, VTs, AM, ExtType,
MemVT, MMO);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -3961,8 +3942,8 @@ SDValue SelectionDAG::getStore(SDValue Chain, DebugLoc dl, SDValue Val,
cast<StoreSDNode>(E)->refineAlignment(MMO);
return SDValue(E, 0);
}
SDNode *N = NodeAllocator.Allocate<StoreSDNode>();
new (N) StoreSDNode(Ops, dl, VTs, ISD::UNINDEXED, false, VT, MMO);
SDNode *N = new (NodeAllocator) StoreSDNode(Ops, dl, VTs, ISD::UNINDEXED,
false, VT, MMO);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -4025,8 +4006,8 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val,
cast<StoreSDNode>(E)->refineAlignment(MMO);
return SDValue(E, 0);
}
SDNode *N = NodeAllocator.Allocate<StoreSDNode>();
new (N) StoreSDNode(Ops, dl, VTs, ISD::UNINDEXED, true, SVT, MMO);
SDNode *N = new (NodeAllocator) StoreSDNode(Ops, dl, VTs, ISD::UNINDEXED,
true, SVT, MMO);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -4048,10 +4029,10 @@ SelectionDAG::getIndexedStore(SDValue OrigStore, DebugLoc dl, SDValue Base,
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<StoreSDNode>();
new (N) StoreSDNode(Ops, dl, VTs, AM,
ST->isTruncatingStore(), ST->getMemoryVT(),
ST->getMemOperand());
SDNode *N = new (NodeAllocator) StoreSDNode(Ops, dl, VTs, AM,
ST->isTruncatingStore(),
ST->getMemoryVT(),
ST->getMemOperand());
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@ -4122,12 +4103,10 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT,
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
N = NodeAllocator.Allocate<SDNode>();
new (N) SDNode(Opcode, DL, VTs, Ops, NumOps);
N = new (NodeAllocator) SDNode(Opcode, DL, VTs, Ops, NumOps);
CSEMap.InsertNode(N, IP);
} else {
N = NodeAllocator.Allocate<SDNode>();
new (N) SDNode(Opcode, DL, VTs, Ops, NumOps);
N = new (NodeAllocator) SDNode(Opcode, DL, VTs, Ops, NumOps);
}
AllNodes.push_back(N);
@ -4190,32 +4169,26 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, SDVTList VTList,
return SDValue(E, 0);
if (NumOps == 1) {
N = NodeAllocator.Allocate<UnarySDNode>();
new (N) UnarySDNode(Opcode, DL, VTList, Ops[0]);
N = new (NodeAllocator) UnarySDNode(Opcode, DL, VTList, Ops[0]);
} else if (NumOps == 2) {
N = NodeAllocator.Allocate<BinarySDNode>();
new (N) BinarySDNode(Opcode, DL, VTList, Ops[0], Ops[1]);
N = new (NodeAllocator) BinarySDNode(Opcode, DL, VTList, Ops[0], Ops[1]);
} else if (NumOps == 3) {
N = NodeAllocator.Allocate<TernarySDNode>();
new (N) TernarySDNode(Opcode, DL, VTList, Ops[0], Ops[1], Ops[2]);
N = new (NodeAllocator) TernarySDNode(Opcode, DL, VTList, Ops[0], Ops[1],
Ops[2]);
} else {
N = NodeAllocator.Allocate<SDNode>();
new (N) SDNode(Opcode, DL, VTList, Ops, NumOps);
N = new (NodeAllocator) SDNode(Opcode, DL, VTList, Ops, NumOps);
}
CSEMap.InsertNode(N, IP);
} else {
if (NumOps == 1) {
N = NodeAllocator.Allocate<UnarySDNode>();
new (N) UnarySDNode(Opcode, DL, VTList, Ops[0]);
N = new (NodeAllocator) UnarySDNode(Opcode, DL, VTList, Ops[0]);
} else if (NumOps == 2) {
N = NodeAllocator.Allocate<BinarySDNode>();
new (N) BinarySDNode(Opcode, DL, VTList, Ops[0], Ops[1]);
N = new (NodeAllocator) BinarySDNode(Opcode, DL, VTList, Ops[0], Ops[1]);
} else if (NumOps == 3) {
N = NodeAllocator.Allocate<TernarySDNode>();
new (N) TernarySDNode(Opcode, DL, VTList, Ops[0], Ops[1], Ops[2]);
N = new (NodeAllocator) TernarySDNode(Opcode, DL, VTList, Ops[0], Ops[1],
Ops[2]);
} else {
N = NodeAllocator.Allocate<SDNode>();
new (N) SDNode(Opcode, DL, VTList, Ops, NumOps);
N = new (NodeAllocator) SDNode(Opcode, DL, VTList, Ops, NumOps);
}
}
AllNodes.push_back(N);
@ -4640,7 +4613,7 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
// remainder of the current SelectionDAG iteration, so we can allocate
// the operands directly out of a pool with no recycling metadata.
MN->InitOperands(OperandAllocator.Allocate<SDUse>(NumOps),
Ops, NumOps);
Ops, NumOps);
else
MN->InitOperands(MN->LocalOperands, Ops, NumOps);
MN->OperandsNeedDelete = false;
@ -4814,8 +4787,7 @@ SelectionDAG::getMachineNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
}
// Allocate a new MachineSDNode.
N = NodeAllocator.Allocate<MachineSDNode>();
new (N) MachineSDNode(~Opcode, DL, VTs);
N = new (NodeAllocator) MachineSDNode(~Opcode, DL, VTs);
// Initialize the operands list.
if (NumOps > array_lengthof(N->LocalOperands))

View File

@ -1675,11 +1675,10 @@ bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec& CR,
}
}
// Create a jump table index for this jump table, or return an existing
// one.
// Create a jump table index for this jump table.
unsigned JTEncoding = TLI.getJumpTableEncoding();
unsigned JTI = CurMF->getOrCreateJumpTableInfo(JTEncoding)
->getJumpTableIndex(DestBBs);
->createJumpTableIndex(DestBBs);
// Set the jump table information so that we can codegen it as a second
// MachineBasicBlock
@ -2592,6 +2591,11 @@ void SelectionDAGBuilder::visitGetElementPtr(User &I) {
}
Ty = StTy->getElementType(Field);
} else if (const UnionType *UnTy = dyn_cast<UnionType>(Ty)) {
unsigned Field = cast<ConstantInt>(Idx)->getZExtValue();
// Offset canonically 0 for unions, but type changes
Ty = UnTy->getElementType(Field);
} else {
Ty = cast<SequentialType>(Ty)->getElementType();
@ -4277,6 +4281,9 @@ isInTailCallPosition(CallSite CS, Attributes CalleeRetAttr,
--BBI) {
if (&*BBI == I)
break;
// Debug info intrinsics do not get in the way of tail call optimization.
if (isa<DbgInfoIntrinsic>(BBI))
continue;
if (BBI->mayHaveSideEffects() || BBI->mayReadFromMemory() ||
!BBI->isSafeToSpeculativelyExecute())
return false;

View File

@ -31,6 +31,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
@ -1639,11 +1640,11 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
// Save a copy of the virtual register live interval. We'll manually
// merge this into the "real" physical register live interval this is
// coalesced with.
LiveInterval *SavedLI = 0;
OwningPtr<LiveInterval> SavedLI;
if (RealDstReg)
SavedLI = li_->dupInterval(&SrcInt);
SavedLI.reset(li_->dupInterval(&SrcInt));
else if (RealSrcReg)
SavedLI = li_->dupInterval(&DstInt);
SavedLI.reset(li_->dupInterval(&DstInt));
// Check if it is necessary to propagate "isDead" property.
if (!isExtSubReg && !isInsSubReg && !isSubRegToReg) {
@ -1853,7 +1854,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
// Manually deleted the live interval copy.
if (SavedLI) {
SavedLI->clear();
delete SavedLI;
SavedLI.reset();
}
// If resulting interval has a preference that no longer fits because of subreg

View File

@ -495,7 +495,7 @@ TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF,
if (InstrCount == MaxDuplicateCount) return false;
// Remember if we saw a call.
if (I->getDesc().isCall()) HasCall = true;
if (!I->isPHI())
if (!I->isPHI() && !I->isDebugValue())
InstrCount += 1;
}
// Heuristically, don't tail-duplicate calls if it would expand code size,

View File

@ -12,11 +12,13 @@ add_llvm_library(LLVMMC
MCInstPrinter.cpp
MCMachOStreamer.cpp
MCNullStreamer.cpp
MCObjectWriter.cpp
MCSection.cpp
MCSectionELF.cpp
MCSectionMachO.cpp
MCStreamer.cpp
MCSymbol.cpp
MCValue.cpp
MachObjectWriter.cpp
TargetAsmBackend.cpp
)

View File

@ -16,6 +16,7 @@
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorHandling.h"
@ -29,7 +30,7 @@ namespace {
class MCAsmStreamer : public MCStreamer {
formatted_raw_ostream &OS;
const MCAsmInfo &MAI;
MCInstPrinter *InstPrinter;
OwningPtr<MCInstPrinter> InstPrinter;
MCCodeEmitter *Emitter;
SmallString<128> CommentToEmit;

File diff suppressed because it is too large Load Diff

View File

@ -19,10 +19,10 @@ MCCodeEmitter::~MCCodeEmitter() {
const MCFixupKindInfo &MCCodeEmitter::getFixupKindInfo(MCFixupKind Kind) const {
static const MCFixupKindInfo Builtins[] = {
{ "FK_Data_1", 0, 8 },
{ "FK_Data_2", 0, 16 },
{ "FK_Data_4", 0, 32 },
{ "FK_Data_8", 0, 64 }
{ "FK_Data_1", 0, 8, 0 },
{ "FK_Data_2", 0, 16, 0 },
{ "FK_Data_4", 0, 32, 0 },
{ "FK_Data_8", 0, 64, 0 }
};
assert(Kind <= 3 && "Unknown fixup kind");

View File

@ -49,17 +49,6 @@ MCSymbol *MCContext::CreateTempSymbol() {
"tmp" + Twine(NextUniqueID++));
}
MCSymbol *MCContext::GetOrCreateTemporarySymbol(StringRef Name) {
// If there is no name, create a new anonymous symbol.
// FIXME: Remove this. This form of the method should always take a name.
if (Name.empty())
return GetOrCreateTemporarySymbol(Twine(MAI.getPrivateGlobalPrefix()) +
"tmp" + Twine(NextUniqueID++));
return GetOrCreateSymbol(Name, true);
}
MCSymbol *MCContext::GetOrCreateTemporarySymbol(const Twine &Name) {
SmallString<128> NameSV;
Name.toVector(NameSV);

View File

@ -30,7 +30,7 @@ void MCExpr::print(raw_ostream &OS) const {
case MCExpr::SymbolRef: {
const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*this);
const MCSymbol &Sym = SRE.getSymbol();
// Parenthesize names that start with $ so that they don't look like
// absolute names.
if (Sym.getName()[0] == '$')
@ -59,14 +59,14 @@ void MCExpr::print(raw_ostream &OS) const {
case MCExpr::Binary: {
const MCBinaryExpr &BE = cast<MCBinaryExpr>(*this);
// Only print parens around the LHS if it is non-trivial.
if (isa<MCConstantExpr>(BE.getLHS()) || isa<MCSymbolRefExpr>(BE.getLHS())) {
OS << *BE.getLHS();
} else {
OS << '(' << *BE.getLHS() << ')';
}
switch (BE.getOpcode()) {
default: assert(0 && "Invalid opcode!");
case MCBinaryExpr::Add:
@ -77,7 +77,7 @@ void MCExpr::print(raw_ostream &OS) const {
return;
}
}
OS << '+';
break;
case MCBinaryExpr::And: OS << '&'; break;
@ -98,7 +98,7 @@ void MCExpr::print(raw_ostream &OS) const {
case MCBinaryExpr::Sub: OS << '-'; break;
case MCBinaryExpr::Xor: OS << '^'; break;
}
// Only print parens around the LHS if it is non-trivial.
if (isa<MCConstantExpr>(BE.getRHS()) || isa<MCSymbolRefExpr>(BE.getRHS())) {
OS << *BE.getRHS();
@ -193,7 +193,7 @@ void MCTargetExpr::Anchor() {}
bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout *Layout) const {
MCValue Value;
if (!EvaluateAsRelocatable(Value, Layout) || !Value.isAbsolute())
return false;
@ -201,16 +201,16 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout *Layout) const {
return true;
}
static bool EvaluateSymbolicAdd(const MCValue &LHS, const MCSymbol *RHS_A,
const MCSymbol *RHS_B, int64_t RHS_Cst,
static bool EvaluateSymbolicAdd(const MCValue &LHS,const MCSymbolRefExpr *RHS_A,
const MCSymbolRefExpr *RHS_B, int64_t RHS_Cst,
MCValue &Res) {
// We can't add or subtract two symbols.
if ((LHS.getSymA() && RHS_A) ||
(LHS.getSymB() && RHS_B))
return false;
const MCSymbol *A = LHS.getSymA() ? LHS.getSymA() : RHS_A;
const MCSymbol *B = LHS.getSymB() ? LHS.getSymB() : RHS_B;
const MCSymbolRefExpr *A = LHS.getSymA() ? LHS.getSymA() : RHS_A;
const MCSymbolRefExpr *B = LHS.getSymB() ? LHS.getSymB() : RHS_B;
if (B) {
// If we have a negated symbol, then we must have also have a non-negated
// symbol in order to encode the expression. We can do this check later to
@ -228,13 +228,14 @@ bool MCExpr::EvaluateAsRelocatable(MCValue &Res,
switch (getKind()) {
case Target:
return cast<MCTargetExpr>(this)->EvaluateAsRelocatableImpl(Res, Layout);
case Constant:
Res = MCValue::get(cast<MCConstantExpr>(this)->getValue());
return true;
case SymbolRef: {
const MCSymbol &Sym = cast<MCSymbolRefExpr>(this)->getSymbol();
const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this);
const MCSymbol &Sym = SRE->getSymbol();
// Evaluate recursively if this is a variable.
if (Sym.isVariable()) {
@ -245,9 +246,12 @@ bool MCExpr::EvaluateAsRelocatable(MCValue &Res,
// layout object and the target requests it.
if (Layout && Res.getSymB() &&
Layout->getAssembler().getBackend().hasAbsolutizedSet() &&
Res.getSymA()->isDefined() && Res.getSymB()->isDefined()) {
MCSymbolData &A = Layout->getAssembler().getSymbolData(*Res.getSymA());
MCSymbolData &B = Layout->getAssembler().getSymbolData(*Res.getSymB());
Res.getSymA()->getSymbol().isDefined() &&
Res.getSymB()->getSymbol().isDefined()) {
MCSymbolData &A =
Layout->getAssembler().getSymbolData(Res.getSymA()->getSymbol());
MCSymbolData &B =
Layout->getAssembler().getSymbolData(Res.getSymB()->getSymbol());
Res = MCValue::get(+ A.getFragment()->getAddress() + A.getOffset()
- B.getFragment()->getAddress() - B.getOffset()
+ Res.getConstant());
@ -256,7 +260,7 @@ bool MCExpr::EvaluateAsRelocatable(MCValue &Res,
return true;
}
Res = MCValue::get(&Sym, 0, 0);
Res = MCValue::get(SRE, 0, 0);
return true;
}
@ -277,13 +281,13 @@ bool MCExpr::EvaluateAsRelocatable(MCValue &Res,
/// -(a - b + const) ==> (b - a - const)
if (Value.getSymA() && !Value.getSymB())
return false;
Res = MCValue::get(Value.getSymB(), Value.getSymA(),
-Value.getConstant());
Res = MCValue::get(Value.getSymB(), Value.getSymA(),
-Value.getConstant());
break;
case MCUnaryExpr::Not:
if (!Value.isAbsolute())
return false;
Res = MCValue::get(~Value.getConstant());
Res = MCValue::get(~Value.getConstant());
break;
case MCUnaryExpr::Plus:
Res = Value;
@ -296,7 +300,7 @@ bool MCExpr::EvaluateAsRelocatable(MCValue &Res,
case Binary: {
const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this);
MCValue LHSValue, RHSValue;
if (!ABE->getLHS()->EvaluateAsRelocatable(LHSValue, Layout) ||
!ABE->getRHS()->EvaluateAsRelocatable(RHSValue, Layout))
return false;

View File

@ -45,7 +45,6 @@ class MCMachOStreamer : public MCStreamer {
private:
MCAssembler Assembler;
MCCodeEmitter *Emitter;
MCSectionData *CurSectionData;
private:
@ -61,7 +60,7 @@ class MCMachOStreamer : public MCStreamer {
public:
MCMachOStreamer(MCContext &Context, TargetAsmBackend &TAB,
raw_ostream &_OS, MCCodeEmitter *_Emitter)
: MCStreamer(Context), Assembler(Context, TAB, _OS), Emitter(_Emitter),
: MCStreamer(Context), Assembler(Context, TAB, *_Emitter, _OS),
CurSectionData(0) {}
~MCMachOStreamer() {}
@ -370,15 +369,12 @@ void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
if (Inst.getOperand(i).isExpr())
AddValueSymbols(Inst.getOperand(i).getExpr());
if (!Emitter)
llvm_unreachable("no code emitter available!");
CurSectionData->setHasInstructions(true);
SmallVector<MCFixup, 4> Fixups;
SmallString<256> Code;
raw_svector_ostream VecOS(Code);
Emitter->EncodeInstruction(Inst, VecOS, Fixups);
Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
VecOS.flush();
// Add the fixups and data.

15
lib/MC/MCObjectWriter.cpp Normal file
View File

@ -0,0 +1,15 @@
//===- lib/MC/MCObjectWriter.cpp - MCObjectWriter implementation ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCObjectWriter.h"
using namespace llvm;
MCObjectWriter::~MCObjectWriter() {
}

View File

@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCValue.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@ -19,10 +20,12 @@ void MCValue::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
return;
}
OS << *getSymA();
getSymA()->print(OS);
if (getSymB())
OS << " - " << *getSymB();
if (getSymB()) {
OS << " - ";
getSymB()->print(OS);
}
if (getConstant())
OS << " + " << getConstant();

1109
lib/MC/MachObjectWriter.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,10 @@
using namespace llvm;
TargetAsmBackend::TargetAsmBackend(const Target &T)
: TheTarget(T)
: TheTarget(T),
HasAbsolutizedSet(false),
HasReliableSymbolDifference(false),
HasScatteredSymbols(false)
{
}

View File

@ -15,6 +15,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
@ -130,6 +131,15 @@ bool FoldingSetNodeID::operator==(const FoldingSetNodeID &RHS)const{
return memcmp(&Bits[0], &RHS.Bits[0], Bits.size()*sizeof(Bits[0])) == 0;
}
/// Intern - Copy this node's data to a memory region allocated from the
/// given allocator and return a FoldingSetNodeIDRef describing the
/// interned data.
FoldingSetNodeIDRef
FoldingSetNodeID::Intern(BumpPtrAllocator &Allocator) const {
unsigned *New = Allocator.Allocate<unsigned>(Bits.size());
std::uninitialized_copy(Bits.begin(), Bits.end(), New);
return FoldingSetNodeIDRef(New, Bits.size());
}
//===----------------------------------------------------------------------===//
/// Helper functions for FoldingSetImpl.

View File

@ -39,8 +39,8 @@ static SmartMutex<true> SignalsMutex;
/// InterruptFunction - The function to call if ctrl-c is pressed.
static void (*InterruptFunction)() = 0;
static std::vector<sys::Path> *FilesToRemove = 0;
static std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0;
static std::vector<sys::Path> FilesToRemove;
static std::vector<std::pair<void(*)(void*), void*> > CallBacksToRun;
// IntSigs - Signals that may interrupt the program at any time.
static const int IntSigs[] = {
@ -126,11 +126,10 @@ static RETSIGTYPE SignalHandler(int Sig) {
sigprocmask(SIG_UNBLOCK, &SigMask, 0);
SignalsMutex.acquire();
if (FilesToRemove != 0)
while (!FilesToRemove->empty()) {
FilesToRemove->back().eraseFromDisk(true);
FilesToRemove->pop_back();
}
while (!FilesToRemove.empty()) {
FilesToRemove.back().eraseFromDisk(true);
FilesToRemove.pop_back();
}
if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd) {
if (InterruptFunction) {
@ -149,9 +148,8 @@ static RETSIGTYPE SignalHandler(int Sig) {
SignalsMutex.release();
// Otherwise if it is a fault (like SEGV) run any handler.
if (CallBacksToRun)
for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i)
(*CallBacksToRun)[i].first((*CallBacksToRun)[i].second);
for (unsigned i = 0, e = CallBacksToRun.size(); i != e; ++i)
CallBacksToRun[i].first(CallBacksToRun[i].second);
}
@ -167,10 +165,7 @@ void llvm::sys::SetInterruptFunction(void (*IF)()) {
bool llvm::sys::RemoveFileOnSignal(const sys::Path &Filename,
std::string* ErrMsg) {
SignalsMutex.acquire();
if (FilesToRemove == 0)
FilesToRemove = new std::vector<sys::Path>();
FilesToRemove->push_back(Filename);
FilesToRemove.push_back(Filename);
SignalsMutex.release();
@ -182,9 +177,7 @@ bool llvm::sys::RemoveFileOnSignal(const sys::Path &Filename,
/// to the process. The handler can have a cookie passed to it to identify
/// what instance of the handler it is.
void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
if (CallBacksToRun == 0)
CallBacksToRun = new std::vector<std::pair<void(*)(void*), void*> >();
CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie));
CallBacksToRun.push_back(std::make_pair(FnPtr, Cookie));
RegisterHandlers();
}

View File

@ -35,6 +35,10 @@ namespace ARM_AM {
add = '+', sub = '-'
};
static inline const char *getAddrOpcStr(AddrOpc Op) {
return Op == sub ? "-" : "";
}
static inline const char *getShiftOpcStr(ShiftOpc Op) {
switch (Op) {
default: assert(0 && "Unknown shift opc!");
@ -78,16 +82,6 @@ namespace ARM_AM {
}
}
static inline const char *getAMSubModeAltStr(AMSubMode Mode, bool isLD) {
switch (Mode) {
default: assert(0 && "Unknown addressing sub-mode!");
case ARM_AM::ia: return isLD ? "fd" : "ea";
case ARM_AM::ib: return isLD ? "ed" : "fa";
case ARM_AM::da: return isLD ? "fa" : "ed";
case ARM_AM::db: return isLD ? "ea" : "fd";
}
}
/// rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
///
static inline unsigned rotr32(unsigned Val, unsigned Amt) {
@ -473,20 +467,13 @@ namespace ARM_AM {
// IB - Increment before
// DA - Decrement after
// DB - Decrement before
//
// If the 4th bit (writeback)is set, then the base register is updated after
// the memory transfer.
static inline AMSubMode getAM4SubMode(unsigned Mode) {
return (AMSubMode)(Mode & 0x7);
}
static inline unsigned getAM4ModeImm(AMSubMode SubMode, bool WB = false) {
return (int)SubMode | ((int)WB << 3);
}
static inline bool getAM4WBFlag(unsigned Mode) {
return (Mode >> 3) & 1;
static inline unsigned getAM4ModeImm(AMSubMode SubMode) {
return (int)SubMode;
}
//===--------------------------------------------------------------------===//
@ -501,9 +488,9 @@ namespace ARM_AM {
// operation in bit 8 and the immediate in bits 0-7.
//
// This is also used for FP load/store multiple ops. The second operand
// encodes the writeback mode in bit 8 and the number of registers (or 2
// times the number of registers for DPR ops) in bits 0-7. In addition,
// bits 9-11 encode one of the following two sub-modes:
// encodes the number of registers (or 2 times the number of registers
// for DPR ops) in bits 0-7. In addition, bits 8-10 encode one of the
// following two sub-modes:
//
// IA - Increment after
// DB - Decrement before
@ -522,17 +509,13 @@ namespace ARM_AM {
/// getAM5Opc - This function encodes the addrmode5 opc field for VLDM and
/// VSTM instructions.
static inline unsigned getAM5Opc(AMSubMode SubMode, bool WB,
unsigned char Offset) {
static inline unsigned getAM5Opc(AMSubMode SubMode, unsigned char Offset) {
assert((SubMode == ia || SubMode == db) &&
"Illegal addressing mode 5 sub-mode!");
return ((int)SubMode << 9) | ((int)WB << 8) | Offset;
return ((int)SubMode << 8) | Offset;
}
static inline AMSubMode getAM5SubMode(unsigned AM5Opc) {
return (AMSubMode)((AM5Opc >> 9) & 0x7);
}
static inline bool getAM5WBFlag(unsigned AM5Opc) {
return ((AM5Opc >> 8) & 1);
return (AMSubMode)((AM5Opc >> 8) & 0x7);
}
//===--------------------------------------------------------------------===//
@ -541,23 +524,11 @@ namespace ARM_AM {
//
// This is used for NEON load / store instructions.
//
// addrmode6 := reg with optional writeback and alignment
// addrmode6 := reg with optional alignment
//
// This is stored in four operands [regaddr, regupdate, opc, align]. The
// first is the address register. The second register holds the value of
// a post-access increment for writeback or reg0 if no writeback or if the
// writeback increment is the size of the memory access. The third
// operand encodes whether there is writeback to the address register. The
// fourth operand is the value of the alignment specifier to use or zero if
// no explicit alignment.
static inline unsigned getAM6Opc(bool WB = false) {
return (int)WB;
}
static inline bool getAM6WBFlag(unsigned Mode) {
return Mode & 1;
}
// This is stored in two operands [regaddr, align]. The first is the
// address register. The second operand is the value of the alignment
// specifier to use or zero if no explicit alignment.
} // end namespace ARM_AM
} // end namespace llvm

View File

@ -650,39 +650,49 @@ ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
if (SrcRC == ARM::tGPRRegisterClass)
SrcRC = ARM::GPRRegisterClass;
if (DestRC != SrcRC) {
if (DestRC->getSize() != SrcRC->getSize())
return false;
// Allow DPR / DPR_VFP2 / DPR_8 cross-class copies.
if (DestRC == ARM::DPR_8RegisterClass)
DestRC = ARM::DPR_VFP2RegisterClass;
if (SrcRC == ARM::DPR_8RegisterClass)
SrcRC = ARM::DPR_VFP2RegisterClass;
// Allow DPR / DPR_VFP2 / DPR_8 cross-class copies.
// Allow QPR / QPR_VFP2 / QPR_8 cross-class copies.
if (DestRC->getSize() != 8 && DestRC->getSize() != 16)
return false;
}
// Allow QPR / QPR_VFP2 / QPR_8 cross-class copies.
if (DestRC == ARM::QPR_VFP2RegisterClass ||
DestRC == ARM::QPR_8RegisterClass)
DestRC = ARM::QPRRegisterClass;
if (SrcRC == ARM::QPR_VFP2RegisterClass ||
SrcRC == ARM::QPR_8RegisterClass)
SrcRC = ARM::QPRRegisterClass;
// Disallow copies of unequal sizes.
if (DestRC != SrcRC && DestRC->getSize() != SrcRC->getSize())
return false;
if (DestRC == ARM::GPRRegisterClass) {
AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr),
DestReg).addReg(SrcReg)));
} else if (DestRC == ARM::SPRRegisterClass) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVS), DestReg)
.addReg(SrcReg));
} else if (DestRC == ARM::DPRRegisterClass) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVD), DestReg)
.addReg(SrcReg));
} else if (DestRC == ARM::DPR_VFP2RegisterClass ||
DestRC == ARM::DPR_8RegisterClass ||
SrcRC == ARM::DPR_VFP2RegisterClass ||
SrcRC == ARM::DPR_8RegisterClass) {
// Always use neon reg-reg move if source or dest is NEON-only regclass.
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVDneon),
DestReg).addReg(SrcReg));
} else if (DestRC == ARM::QPRRegisterClass ||
DestRC == ARM::QPR_VFP2RegisterClass ||
DestRC == ARM::QPR_8RegisterClass) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVQ),
DestReg).addReg(SrcReg));
if (SrcRC == ARM::SPRRegisterClass)
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVRS), DestReg)
.addReg(SrcReg));
else
AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr),
DestReg).addReg(SrcReg)));
} else {
return false;
unsigned Opc;
if (DestRC == ARM::SPRRegisterClass)
Opc = (SrcRC == ARM::GPRRegisterClass ? ARM::VMOVSR : ARM::VMOVS);
else if (DestRC == ARM::DPRRegisterClass)
Opc = ARM::VMOVD;
else if (DestRC == ARM::DPR_VFP2RegisterClass ||
SrcRC == ARM::DPR_VFP2RegisterClass)
// Always use neon reg-reg move if source or dest is NEON-only regclass.
Opc = ARM::VMOVDneon;
else if (DestRC == ARM::QPRRegisterClass)
Opc = ARM::VMOVQ;
else
return false;
AddDefaultPred(BuildMI(MBB, I, DL, get(Opc), DestReg)
.addReg(SrcReg));
}
return true;
@ -727,10 +737,9 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
assert((RC == ARM::QPRRegisterClass ||
RC == ARM::QPR_VFP2RegisterClass) && "Unknown regclass!");
// FIXME: Neon instructions should support predicates
if (Align >= 16
&& (getRegisterInfo().canRealignStack(MF))) {
if (Align >= 16 && (getRegisterInfo().canRealignStack(MF))) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1q64))
.addFrameIndex(FI).addImm(0).addImm(0).addImm(128)
.addFrameIndex(FI).addImm(128)
.addMemOperand(MMO)
.addReg(SrcReg, getKillRegState(isKill)));
} else {
@ -780,7 +789,7 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
if (Align >= 16
&& (getRegisterInfo().canRealignStack(MF))) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1q64), DestReg)
.addFrameIndex(FI).addImm(0).addImm(0).addImm(128)
.addFrameIndex(FI).addImm(128)
.addMemOperand(MMO));
} else {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRQ), DestReg)

View File

@ -93,34 +93,34 @@ namespace ARMII {
StMiscFrm = 9 << FormShift,
LdStMulFrm = 10 << FormShift,
LdStExFrm = 28 << FormShift,
LdStExFrm = 11 << FormShift,
// Miscellaneous arithmetic instructions
ArithMiscFrm = 11 << FormShift,
ArithMiscFrm = 12 << FormShift,
// Extend instructions
ExtFrm = 12 << FormShift,
ExtFrm = 13 << FormShift,
// VFP formats
VFPUnaryFrm = 13 << FormShift,
VFPBinaryFrm = 14 << FormShift,
VFPConv1Frm = 15 << FormShift,
VFPConv2Frm = 16 << FormShift,
VFPConv3Frm = 17 << FormShift,
VFPConv4Frm = 18 << FormShift,
VFPConv5Frm = 19 << FormShift,
VFPLdStFrm = 20 << FormShift,
VFPLdStMulFrm = 21 << FormShift,
VFPMiscFrm = 22 << FormShift,
VFPUnaryFrm = 14 << FormShift,
VFPBinaryFrm = 15 << FormShift,
VFPConv1Frm = 16 << FormShift,
VFPConv2Frm = 17 << FormShift,
VFPConv3Frm = 18 << FormShift,
VFPConv4Frm = 19 << FormShift,
VFPConv5Frm = 20 << FormShift,
VFPLdStFrm = 21 << FormShift,
VFPLdStMulFrm = 22 << FormShift,
VFPMiscFrm = 23 << FormShift,
// Thumb format
ThumbFrm = 23 << FormShift,
ThumbFrm = 24 << FormShift,
// NEON format
NEONFrm = 24 << FormShift,
NEONGetLnFrm = 25 << FormShift,
NEONSetLnFrm = 26 << FormShift,
NEONDupFrm = 27 << FormShift,
NEONFrm = 25 << FormShift,
NEONGetLnFrm = 26 << FormShift,
NEONSetLnFrm = 27 << FormShift,
NEONDupFrm = 28 << FormShift,
//===------------------------------------------------------------------===//
// Misc flags.

View File

@ -80,7 +80,7 @@ unsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum,
case D23: return 23;
case D24: return 24;
case D25: return 25;
case D26: return 27;
case D26: return 26;
case D27: return 27;
case D28: return 28;
case D29: return 29;

View File

@ -55,12 +55,12 @@ namespace {
const std::vector<MachineConstantPoolEntry> *MCPEs;
const std::vector<MachineJumpTableEntry> *MJTEs;
bool IsPIC;
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineModuleInfo>();
MachineFunctionPass::getAnalysisUsage(AU);
}
static char ID;
public:
ARMCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce)
@ -68,7 +68,7 @@ namespace {
TD(tm.getTargetData()), TM(tm),
MCE(mce), MCPEs(0), MJTEs(0),
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
/// getBinaryCodeForInstr - This function, generated by the
/// CodeEmitterGenerator using TableGen, produces the binary encoding for
/// machine instructions.
@ -163,7 +163,7 @@ namespace {
char ARMCodeEmitter::ID = 0;
/// createARMJITCodeEmitterPass - Return a pass that emits the collected ARM
/// createARMJITCodeEmitterPass - Return a pass that emits the collected ARM
/// code to the specified MCE object.
FunctionPass *llvm::createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM,
JITCodeEmitter &JCE) {
@ -617,8 +617,7 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
}
}
unsigned ARMCodeEmitter::getMachineSoRegOpValue(
const MachineInstr &MI,
unsigned ARMCodeEmitter::getMachineSoRegOpValue(const MachineInstr &MI,
const TargetInstrDesc &TID,
const MachineOperand &MO,
unsigned OpIdx) {
@ -690,7 +689,7 @@ unsigned ARMCodeEmitter::getMachineSoImmOpValue(unsigned SoImm) {
}
unsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI,
const TargetInstrDesc &TID) const {
const TargetInstrDesc &TID) const {
for (unsigned i = MI.getNumOperands(), e = TID.getNumOperands(); i != e; --i){
const MachineOperand &MO = MI.getOperand(i-1);
if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR)
@ -699,8 +698,7 @@ unsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI,
return 0;
}
void ARMCodeEmitter::emitDataProcessingInstruction(
const MachineInstr &MI,
void ARMCodeEmitter::emitDataProcessingInstruction(const MachineInstr &MI,
unsigned ImplicitRd,
unsigned ImplicitRn) {
const TargetInstrDesc &TID = MI.getDesc();
@ -765,8 +763,7 @@ void ARMCodeEmitter::emitDataProcessingInstruction(
emitWordLE(Binary);
}
void ARMCodeEmitter::emitLoadStoreInstruction(
const MachineInstr &MI,
void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI,
unsigned ImplicitRd,
unsigned ImplicitRn) {
const TargetInstrDesc &TID = MI.getDesc();
@ -841,7 +838,7 @@ void ARMCodeEmitter::emitLoadStoreInstruction(
}
void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
unsigned ImplicitRn) {
unsigned ImplicitRn) {
const TargetInstrDesc &TID = MI.getDesc();
unsigned Form = TID.TSFlags & ARMII::FormMask;
bool IsPrePost = (TID.TSFlags & ARMII::IndexModeMask) != 0;
@ -950,7 +947,7 @@ void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
Binary |= getAddrModeUPBits(ARM_AM::getAM4SubMode(MO.getImm()));
// Set bit W(21)
if (ARM_AM::getAM4WBFlag(MO.getImm()))
if (IsUpdating)
Binary |= 0x1 << ARMII::W_BitShift;
// Set registers
@ -1238,8 +1235,7 @@ void ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
void ARMCodeEmitter::emitVFPConversionInstruction(
const MachineInstr &MI) {
void ARMCodeEmitter::emitVFPConversionInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
unsigned Form = TID.TSFlags & ARMII::FormMask;
@ -1329,8 +1325,8 @@ void ARMCodeEmitter::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
void ARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(
const MachineInstr &MI) {
void
ARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
bool IsUpdating = (TID.TSFlags & ARMII::IndexModeMask) != 0;
@ -1353,7 +1349,7 @@ void ARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(
Binary |= getAddrModeUPBits(ARM_AM::getAM5SubMode(MO.getImm()));
// Set bit W(21)
if (ARM_AM::getAM5WBFlag(MO.getImm()))
if (IsUpdating)
Binary |= 0x1 << ARMII::W_BitShift;
// First register is encoded in Dd.

View File

@ -80,8 +80,7 @@ class ARMDAGToDAGISel : public SelectionDAGISel {
SDValue &Mode);
bool SelectAddrMode5(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Offset);
bool SelectAddrMode6(SDNode *Op, SDValue N, SDValue &Addr, SDValue &Update,
SDValue &Opc, SDValue &Align);
bool SelectAddrMode6(SDNode *Op, SDValue N, SDValue &Addr, SDValue &Align);
bool SelectAddrModePC(SDNode *Op, SDValue N, SDValue &Offset,
SDValue &Label);
@ -502,12 +501,8 @@ bool ARMDAGToDAGISel::SelectAddrMode5(SDNode *Op, SDValue N,
}
bool ARMDAGToDAGISel::SelectAddrMode6(SDNode *Op, SDValue N,
SDValue &Addr, SDValue &Update,
SDValue &Opc, SDValue &Align) {
SDValue &Addr, SDValue &Align) {
Addr = N;
// Default to no writeback.
Update = CurDAG->getRegister(0, MVT::i32);
Opc = CurDAG->getTargetConstant(ARM_AM::getAM6Opc(false), MVT::i32);
// Default to no alignment.
Align = CurDAG->getTargetConstant(0, MVT::i32);
return true;
@ -1030,8 +1025,8 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, unsigned NumVecs,
assert(NumVecs >=2 && NumVecs <= 4 && "VLD NumVecs out-of-range");
DebugLoc dl = N->getDebugLoc();
SDValue MemAddr, MemUpdate, MemOpc, Align;
if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align))
SDValue MemAddr, Align;
if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, Align))
return NULL;
SDValue Chain = N->getOperand(0);
@ -1055,14 +1050,13 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, unsigned NumVecs,
}
SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32);
SDValue PredReg = CurDAG->getRegister(0, MVT::i32);
SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
if (is64BitVector) {
unsigned Opc = DOpcodes[OpcodeIndex];
const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Align,
Pred, PredReg, Chain };
const SDValue Ops[] = { MemAddr, Align, Pred, Reg0, Chain };
std::vector<EVT> ResTys(NumVecs, VT);
ResTys.push_back(MVT::Other);
return CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 7);
return CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5);
}
EVT RegVT = GetNEONSubregVT(VT);
@ -1070,11 +1064,10 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, unsigned NumVecs,
// Quad registers are directly supported for VLD2,
// loading 2 pairs of D regs.
unsigned Opc = QOpcodes0[OpcodeIndex];
const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Align,
Pred, PredReg, Chain };
const SDValue Ops[] = { MemAddr, Align, Pred, Reg0, Chain };
std::vector<EVT> ResTys(4, VT);
ResTys.push_back(MVT::Other);
SDNode *VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 7);
SDNode *VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5);
Chain = SDValue(VLd, 4);
// Combine the even and odd subregs to produce the result.
@ -1086,25 +1079,21 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, unsigned NumVecs,
// Otherwise, quad registers are loaded with two separate instructions,
// where one loads the even registers and the other loads the odd registers.
// Enable writeback to the address register.
MemOpc = CurDAG->getTargetConstant(ARM_AM::getAM6Opc(true), MVT::i32);
std::vector<EVT> ResTys(NumVecs, RegVT);
ResTys.push_back(MemAddr.getValueType());
ResTys.push_back(MVT::Other);
// Load the even subregs.
unsigned Opc = QOpcodes0[OpcodeIndex];
const SDValue OpsA[] = { MemAddr, MemUpdate, MemOpc, Align,
Pred, PredReg, Chain };
SDNode *VLdA = CurDAG->getMachineNode(Opc, dl, ResTys, OpsA, 7);
const SDValue OpsA[] = { MemAddr, Align, Reg0, Pred, Reg0, Chain };
SDNode *VLdA = CurDAG->getMachineNode(Opc, dl, ResTys, OpsA, 6);
Chain = SDValue(VLdA, NumVecs+1);
// Load the odd subregs.
Opc = QOpcodes1[OpcodeIndex];
const SDValue OpsB[] = { SDValue(VLdA, NumVecs), MemUpdate, MemOpc,
Align, Pred, PredReg, Chain };
SDNode *VLdB = CurDAG->getMachineNode(Opc, dl, ResTys, OpsB, 7);
const SDValue OpsB[] = { SDValue(VLdA, NumVecs),
Align, Reg0, Pred, Reg0, Chain };
SDNode *VLdB = CurDAG->getMachineNode(Opc, dl, ResTys, OpsB, 6);
Chain = SDValue(VLdB, NumVecs+1);
// Combine the even and odd subregs to produce the result.
@ -1123,8 +1112,8 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, unsigned NumVecs,
assert(NumVecs >=2 && NumVecs <= 4 && "VST NumVecs out-of-range");
DebugLoc dl = N->getDebugLoc();
SDValue MemAddr, MemUpdate, MemOpc, Align;
if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align))
SDValue MemAddr, Align;
if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, Align))
return NULL;
SDValue Chain = N->getOperand(0);
@ -1148,12 +1137,10 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, unsigned NumVecs,
}
SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32);
SDValue PredReg = CurDAG->getRegister(0, MVT::i32);
SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
SmallVector<SDValue, 8> Ops;
SmallVector<SDValue, 10> Ops;
Ops.push_back(MemAddr);
Ops.push_back(MemUpdate);
Ops.push_back(MemOpc);
Ops.push_back(Align);
if (is64BitVector) {
@ -1161,9 +1148,9 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, unsigned NumVecs,
for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
Ops.push_back(N->getOperand(Vec+3));
Ops.push_back(Pred);
Ops.push_back(PredReg);
Ops.push_back(Reg0); // predicate register
Ops.push_back(Chain);
return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+7);
return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+5);
}
EVT RegVT = GetNEONSubregVT(VT);
@ -1178,40 +1165,37 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, unsigned NumVecs,
N->getOperand(Vec+3)));
}
Ops.push_back(Pred);
Ops.push_back(PredReg);
Ops.push_back(Reg0); // predicate register
Ops.push_back(Chain);
return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), 11);
return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), 9);
}
// Otherwise, quad registers are stored with two separate instructions,
// where one stores the even registers and the other stores the odd registers.
// Enable writeback to the address register.
MemOpc = CurDAG->getTargetConstant(ARM_AM::getAM6Opc(true), MVT::i32);
Ops.push_back(Reg0); // post-access address offset
// Store the even subregs.
for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT,
N->getOperand(Vec+3)));
Ops.push_back(Pred);
Ops.push_back(PredReg);
Ops.push_back(Reg0); // predicate register
Ops.push_back(Chain);
unsigned Opc = QOpcodes0[OpcodeIndex];
SDNode *VStA = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(),
MVT::Other, Ops.data(), NumVecs+7);
MVT::Other, Ops.data(), NumVecs+6);
Chain = SDValue(VStA, 1);
// Store the odd subregs.
Ops[0] = SDValue(VStA, 0); // MemAddr
for (unsigned Vec = 0; Vec < NumVecs; ++Vec)
Ops[Vec+4] = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT,
Ops[Vec+3] = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT,
N->getOperand(Vec+3));
Ops[NumVecs+4] = Pred;
Ops[NumVecs+5] = PredReg;
Ops[NumVecs+6] = Chain;
Ops[NumVecs+5] = Chain;
Opc = QOpcodes1[OpcodeIndex];
SDNode *VStB = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(),
MVT::Other, Ops.data(), NumVecs+7);
MVT::Other, Ops.data(), NumVecs+6);
Chain = SDValue(VStB, 1);
ReplaceUses(SDValue(N, 0), Chain);
return NULL;
@ -1224,8 +1208,8 @@ SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad,
assert(NumVecs >=2 && NumVecs <= 4 && "VLDSTLane NumVecs out-of-range");
DebugLoc dl = N->getDebugLoc();
SDValue MemAddr, MemUpdate, MemOpc, Align;
if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align))
SDValue MemAddr, Align;
if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, Align))
return NULL;
SDValue Chain = N->getOperand(0);
@ -1259,12 +1243,10 @@ SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad,
}
SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32);
SDValue PredReg = CurDAG->getRegister(0, MVT::i32);
SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
SmallVector<SDValue, 9> Ops;
SmallVector<SDValue, 10> Ops;
Ops.push_back(MemAddr);
Ops.push_back(MemUpdate);
Ops.push_back(MemOpc);
Ops.push_back(Align);
unsigned Opc = 0;
@ -1287,16 +1269,16 @@ SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad,
}
Ops.push_back(getI32Imm(Lane));
Ops.push_back(Pred);
Ops.push_back(PredReg);
Ops.push_back(Reg0);
Ops.push_back(Chain);
if (!IsLoad)
return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+8);
return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+6);
std::vector<EVT> ResTys(NumVecs, RegVT);
ResTys.push_back(MVT::Other);
SDNode *VLdLn =
CurDAG->getMachineNode(Opc, dl, ResTys, Ops.data(), NumVecs+8);
CurDAG->getMachineNode(Opc, dl, ResTys, Ops.data(), NumVecs+6);
// For a 64-bit vector load to D registers, nothing more needs to be done.
if (is64BitVector)
return VLdLn;
@ -1859,37 +1841,45 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) {
case Intrinsic::arm_neon_vld3: {
unsigned DOpcodes[] = { ARM::VLD3d8, ARM::VLD3d16,
ARM::VLD3d32, ARM::VLD3d64 };
unsigned QOpcodes0[] = { ARM::VLD3q8a, ARM::VLD3q16a, ARM::VLD3q32a };
unsigned QOpcodes1[] = { ARM::VLD3q8b, ARM::VLD3q16b, ARM::VLD3q32b };
unsigned QOpcodes0[] = { ARM::VLD3q8_UPD,
ARM::VLD3q16_UPD,
ARM::VLD3q32_UPD };
unsigned QOpcodes1[] = { ARM::VLD3q8odd_UPD,
ARM::VLD3q16odd_UPD,
ARM::VLD3q32odd_UPD };
return SelectVLD(N, 3, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vld4: {
unsigned DOpcodes[] = { ARM::VLD4d8, ARM::VLD4d16,
ARM::VLD4d32, ARM::VLD4d64 };
unsigned QOpcodes0[] = { ARM::VLD4q8a, ARM::VLD4q16a, ARM::VLD4q32a };
unsigned QOpcodes1[] = { ARM::VLD4q8b, ARM::VLD4q16b, ARM::VLD4q32b };
unsigned QOpcodes0[] = { ARM::VLD4q8_UPD,
ARM::VLD4q16_UPD,
ARM::VLD4q32_UPD };
unsigned QOpcodes1[] = { ARM::VLD4q8odd_UPD,
ARM::VLD4q16odd_UPD,
ARM::VLD4q32odd_UPD };
return SelectVLD(N, 4, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vld2lane: {
unsigned DOpcodes[] = { ARM::VLD2LNd8, ARM::VLD2LNd16, ARM::VLD2LNd32 };
unsigned QOpcodes0[] = { ARM::VLD2LNq16a, ARM::VLD2LNq32a };
unsigned QOpcodes1[] = { ARM::VLD2LNq16b, ARM::VLD2LNq32b };
unsigned QOpcodes0[] = { ARM::VLD2LNq16, ARM::VLD2LNq32 };
unsigned QOpcodes1[] = { ARM::VLD2LNq16odd, ARM::VLD2LNq32odd };
return SelectVLDSTLane(N, true, 2, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vld3lane: {
unsigned DOpcodes[] = { ARM::VLD3LNd8, ARM::VLD3LNd16, ARM::VLD3LNd32 };
unsigned QOpcodes0[] = { ARM::VLD3LNq16a, ARM::VLD3LNq32a };
unsigned QOpcodes1[] = { ARM::VLD3LNq16b, ARM::VLD3LNq32b };
unsigned QOpcodes0[] = { ARM::VLD3LNq16, ARM::VLD3LNq32 };
unsigned QOpcodes1[] = { ARM::VLD3LNq16odd, ARM::VLD3LNq32odd };
return SelectVLDSTLane(N, true, 3, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vld4lane: {
unsigned DOpcodes[] = { ARM::VLD4LNd8, ARM::VLD4LNd16, ARM::VLD4LNd32 };
unsigned QOpcodes0[] = { ARM::VLD4LNq16a, ARM::VLD4LNq32a };
unsigned QOpcodes1[] = { ARM::VLD4LNq16b, ARM::VLD4LNq32b };
unsigned QOpcodes0[] = { ARM::VLD4LNq16, ARM::VLD4LNq32 };
unsigned QOpcodes1[] = { ARM::VLD4LNq16odd, ARM::VLD4LNq32odd };
return SelectVLDSTLane(N, true, 4, DOpcodes, QOpcodes0, QOpcodes1);
}
@ -1903,37 +1893,45 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) {
case Intrinsic::arm_neon_vst3: {
unsigned DOpcodes[] = { ARM::VST3d8, ARM::VST3d16,
ARM::VST3d32, ARM::VST3d64 };
unsigned QOpcodes0[] = { ARM::VST3q8a, ARM::VST3q16a, ARM::VST3q32a };
unsigned QOpcodes1[] = { ARM::VST3q8b, ARM::VST3q16b, ARM::VST3q32b };
unsigned QOpcodes0[] = { ARM::VST3q8_UPD,
ARM::VST3q16_UPD,
ARM::VST3q32_UPD };
unsigned QOpcodes1[] = { ARM::VST3q8odd_UPD,
ARM::VST3q16odd_UPD,
ARM::VST3q32odd_UPD };
return SelectVST(N, 3, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vst4: {
unsigned DOpcodes[] = { ARM::VST4d8, ARM::VST4d16,
ARM::VST4d32, ARM::VST4d64 };
unsigned QOpcodes0[] = { ARM::VST4q8a, ARM::VST4q16a, ARM::VST4q32a };
unsigned QOpcodes1[] = { ARM::VST4q8b, ARM::VST4q16b, ARM::VST4q32b };
unsigned QOpcodes0[] = { ARM::VST4q8_UPD,
ARM::VST4q16_UPD,
ARM::VST4q32_UPD };
unsigned QOpcodes1[] = { ARM::VST4q8odd_UPD,
ARM::VST4q16odd_UPD,
ARM::VST4q32odd_UPD };
return SelectVST(N, 4, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vst2lane: {
unsigned DOpcodes[] = { ARM::VST2LNd8, ARM::VST2LNd16, ARM::VST2LNd32 };
unsigned QOpcodes0[] = { ARM::VST2LNq16a, ARM::VST2LNq32a };
unsigned QOpcodes1[] = { ARM::VST2LNq16b, ARM::VST2LNq32b };
unsigned QOpcodes0[] = { ARM::VST2LNq16, ARM::VST2LNq32 };
unsigned QOpcodes1[] = { ARM::VST2LNq16odd, ARM::VST2LNq32odd };
return SelectVLDSTLane(N, false, 2, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vst3lane: {
unsigned DOpcodes[] = { ARM::VST3LNd8, ARM::VST3LNd16, ARM::VST3LNd32 };
unsigned QOpcodes0[] = { ARM::VST3LNq16a, ARM::VST3LNq32a };
unsigned QOpcodes1[] = { ARM::VST3LNq16b, ARM::VST3LNq32b };
unsigned QOpcodes0[] = { ARM::VST3LNq16, ARM::VST3LNq32 };
unsigned QOpcodes1[] = { ARM::VST3LNq16odd, ARM::VST3LNq32odd };
return SelectVLDSTLane(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vst4lane: {
unsigned DOpcodes[] = { ARM::VST4LNd8, ARM::VST4LNd16, ARM::VST4LNd32 };
unsigned QOpcodes0[] = { ARM::VST4LNq16a, ARM::VST4LNq32a };
unsigned QOpcodes1[] = { ARM::VST4LNq16b, ARM::VST4LNq32b };
unsigned QOpcodes0[] = { ARM::VST4LNq16, ARM::VST4LNq32 };
unsigned QOpcodes1[] = { ARM::VST4LNq16odd, ARM::VST4LNq32odd };
return SelectVLDSTLane(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1);
}
}

View File

@ -436,9 +436,9 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
}
// Special handling for half-precision FP.
if (Subtarget->hasVFP3() && Subtarget->hasFP16()) {
setOperationAction(ISD::FP16_TO_FP32, MVT::f32, Custom);
setOperationAction(ISD::FP32_TO_FP16, MVT::i32, Custom);
if (!Subtarget->hasFP16()) {
setOperationAction(ISD::FP16_TO_FP32, MVT::f32, Expand);
setOperationAction(ISD::FP32_TO_FP16, MVT::i32, Expand);
}
}
@ -499,8 +499,6 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
case ARMISD::FTOUI: return "ARMISD::FTOUI";
case ARMISD::SITOF: return "ARMISD::SITOF";
case ARMISD::UITOF: return "ARMISD::UITOF";
case ARMISD::F16_TO_F32: return "ARMISD::F16_TO_F32";
case ARMISD::F32_TO_F16: return "ARMISD::F32_TO_F16";
case ARMISD::SRL_FLAG: return "ARMISD::SRL_FLAG";
case ARMISD::SRA_FLAG: return "ARMISD::SRA_FLAG";
@ -1987,9 +1985,6 @@ static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) {
switch (Op.getOpcode()) {
default:
assert(0 && "Invalid opcode!");
case ISD::FP32_TO_FP16:
Opc = ARMISD::F32_TO_F16;
break;
case ISD::FP_TO_SINT:
Opc = ARMISD::FTOSI;
break;
@ -2009,9 +2004,6 @@ static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
switch (Op.getOpcode()) {
default:
assert(0 && "Invalid opcode!");
case ISD::FP16_TO_FP32:
Opc = ARMISD::F16_TO_F32;
break;
case ISD::SINT_TO_FP:
Opc = ARMISD::SITOF;
break;
@ -3078,10 +3070,8 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
case ISD::VASTART: return LowerVASTART(Op, DAG, VarArgsFrameIndex);
case ISD::MEMBARRIER: return LowerMEMBARRIER(Op, DAG, Subtarget);
case ISD::FP16_TO_FP32:
case ISD::SINT_TO_FP:
case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG);
case ISD::FP32_TO_FP16:
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG);
case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);

View File

@ -59,8 +59,6 @@ namespace llvm {
FTOUI, // FP to uint within a FP register.
SITOF, // sint to FP within a FP register.
UITOF, // uint to FP within a FP register.
F16_TO_F32, // Half FP to single FP within a FP register.
F32_TO_F16, // Single FP to half FP within a FP register.
SRL_FLAG, // V,Flag = srl_flag X -> srl X, 1 + save carry out.
SRA_FLAG, // V,Flag = sra_flag X -> sra X, 1 + save carry out.

View File

@ -15,8 +15,8 @@
// Format specifies the encoding used by the instruction. This is part of the
// ad-hoc solution used to emit machine instruction encodings by our machine
// code emitter.
class Format<bits<5> val> {
bits<5> Value = val;
class Format<bits<6> val> {
bits<6> Value = val;
}
def Pseudo : Format<0>;
@ -33,32 +33,34 @@ def LdMiscFrm : Format<8>;
def StMiscFrm : Format<9>;
def LdStMulFrm : Format<10>;
def LdStExFrm : Format<28>;
def LdStExFrm : Format<11>;
def ArithMiscFrm : Format<11>;
def ExtFrm : Format<12>;
def ArithMiscFrm : Format<12>;
def ExtFrm : Format<13>;
def VFPUnaryFrm : Format<13>;
def VFPBinaryFrm : Format<14>;
def VFPConv1Frm : Format<15>;
def VFPConv2Frm : Format<16>;
def VFPConv3Frm : Format<17>;
def VFPConv4Frm : Format<18>;
def VFPConv5Frm : Format<19>;
def VFPLdStFrm : Format<20>;
def VFPLdStMulFrm : Format<21>;
def VFPMiscFrm : Format<22>;
def VFPUnaryFrm : Format<14>;
def VFPBinaryFrm : Format<15>;
def VFPConv1Frm : Format<16>;
def VFPConv2Frm : Format<17>;
def VFPConv3Frm : Format<18>;
def VFPConv4Frm : Format<19>;
def VFPConv5Frm : Format<20>;
def VFPLdStFrm : Format<21>;
def VFPLdStMulFrm : Format<22>;
def VFPMiscFrm : Format<23>;
def ThumbFrm : Format<23>;
def ThumbFrm : Format<24>;
def NEONFrm : Format<24>;
def NEONGetLnFrm : Format<25>;
def NEONSetLnFrm : Format<26>;
def NEONDupFrm : Format<27>;
def NEONFrm : Format<25>;
def NEONGetLnFrm : Format<26>;
def NEONSetLnFrm : Format<27>;
def NEONDupFrm : Format<28>;
def MiscFrm : Format<29>;
def ThumbMiscFrm : Format<30>;
def NLdStFrm : Format<31>;
// Misc flags.
// the instruction has a Rn register operand.
@ -71,7 +73,7 @@ class UnaryDP { bit isUnaryDataProc = 1; }
class Xform16Bit { bit canXformTo16Bit = 1; }
//===----------------------------------------------------------------------===//
// ARM Instruction flags. These need to match ARMInstrInfo.h.
// ARM Instruction flags. These need to match ARMBaseInstrInfo.h.
//
// Addressing mode.
@ -183,7 +185,7 @@ class InstTemplate<AddrMode am, SizeFlagVal sz, IndexMode im,
bits<2> IndexModeBits = IM.Value;
Format F = f;
bits<5> Form = F.Value;
bits<6> Form = F.Value;
Domain D = d;
bits<2> Dom = D.Value;
@ -229,7 +231,7 @@ class I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
list<dag> pattern>
: InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
let OutOperandList = oops;
let InOperandList = !con(iops, (ops pred:$p));
let InOperandList = !con(iops, (ins pred:$p));
let AsmString = !strconcat(opc, !strconcat("${p}", asm));
let Pattern = pattern;
list<Predicate> Predicates = [IsARM];
@ -257,7 +259,7 @@ class sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
list<dag> pattern>
: InstARM<am, sz, im, f, GenericDomain, cstr, itin> {
let OutOperandList = oops;
let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
let AsmString = !strconcat(opc, !strconcat("${p}${s}", asm));
let Pattern = pattern;
list<Predicate> Predicates = [IsARM];
@ -1007,8 +1009,8 @@ class Thumb1sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
InstrItinClass itin,
string opc, string asm, string cstr, list<dag> pattern>
: InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
let OutOperandList = !con(oops, (ops s_cc_out:$s));
let InOperandList = !con(iops, (ops pred:$p));
let OutOperandList = !con(oops, (outs s_cc_out:$s));
let InOperandList = !con(iops, (ins pred:$p));
let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
let Pattern = pattern;
list<Predicate> Predicates = [IsThumb1Only];
@ -1030,7 +1032,7 @@ class Thumb1pI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
string opc, string asm, string cstr, list<dag> pattern>
: InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
let OutOperandList = oops;
let InOperandList = !con(iops, (ops pred:$p));
let InOperandList = !con(iops, (ins pred:$p));
let AsmString = !strconcat(opc, !strconcat("${p}", asm));
let Pattern = pattern;
list<Predicate> Predicates = [IsThumb1Only];
@ -1109,7 +1111,7 @@ class Thumb2I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
string opc, string asm, string cstr, list<dag> pattern>
: InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
let OutOperandList = oops;
let InOperandList = !con(iops, (ops pred:$p));
let InOperandList = !con(iops, (ins pred:$p));
let AsmString = !strconcat(opc, !strconcat("${p}", asm));
let Pattern = pattern;
list<Predicate> Predicates = [IsThumb2];
@ -1125,7 +1127,7 @@ class Thumb2sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
string opc, string asm, string cstr, list<dag> pattern>
: InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
let OutOperandList = oops;
let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
let InOperandList = !con(iops, (ins pred:$p, cc_out:$s));
let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
let Pattern = pattern;
list<Predicate> Predicates = [IsThumb2];
@ -1209,7 +1211,7 @@ class T2Iidxldst<bit signed, bits<2> opcod, bit load, bit pre,
string opc, string asm, string cstr, list<dag> pattern>
: InstARM<am, Size4Bytes, im, ThumbFrm, GenericDomain, cstr, itin> {
let OutOperandList = oops;
let InOperandList = !con(iops, (ops pred:$p));
let InOperandList = !con(iops, (ins pred:$p));
let AsmString = !strconcat(opc, !strconcat("${p}", asm));
let Pattern = pattern;
list<Predicate> Predicates = [IsThumb2];
@ -1265,7 +1267,7 @@ class VFPI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
string opc, string asm, string cstr, list<dag> pattern>
: InstARM<am, sz, im, f, VFPDomain, cstr, itin> {
let OutOperandList = oops;
let InOperandList = !con(iops, (ops pred:$p));
let InOperandList = !con(iops, (ins pred:$p));
let AsmString = !strconcat(opc, !strconcat("${p}", asm));
let Pattern = pattern;
list<Predicate> Predicates = [HasVFP2];
@ -1464,11 +1466,12 @@ class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops,
// ARM NEON Instruction templates.
//
class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, InstrItinClass itin,
string opc, string dt, string asm, string cstr, list<dag> pattern>
: InstARM<am, Size4Bytes, im, NEONFrm, NeonDomain, cstr, itin> {
class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, Format f,
InstrItinClass itin, string opc, string dt, string asm, string cstr,
list<dag> pattern>
: InstARM<am, Size4Bytes, im, f, NeonDomain, cstr, itin> {
let OutOperandList = oops;
let InOperandList = !con(iops, (ops pred:$p));
let InOperandList = !con(iops, (ins pred:$p));
let AsmString = !strconcat(
!strconcat(!strconcat(opc, "${p}"), !strconcat(".", dt)),
!strconcat("\t", asm));
@ -1481,7 +1484,7 @@ class NeonXI<dag oops, dag iops, AddrMode am, IndexMode im, InstrItinClass itin,
string opc, string asm, string cstr, list<dag> pattern>
: InstARM<am, Size4Bytes, im, NEONFrm, NeonDomain, cstr, itin> {
let OutOperandList = oops;
let InOperandList = !con(iops, (ops pred:$p));
let InOperandList = !con(iops, (ins pred:$p));
let AsmString = !strconcat(!strconcat(opc, "${p}"), !strconcat("\t", asm));
let Pattern = pattern;
list<Predicate> Predicates = [HasNEON];
@ -1502,8 +1505,8 @@ class NI4<dag oops, dag iops, InstrItinClass itin, string opc,
class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
dag oops, dag iops, InstrItinClass itin,
string opc, string dt, string asm, string cstr, list<dag> pattern>
: NeonI<oops, iops, AddrMode6, IndexModeNone, itin, opc, dt, asm, cstr,
pattern> {
: NeonI<oops, iops, AddrMode6, IndexModeNone, NLdStFrm, itin, opc, dt, asm,
cstr, pattern> {
let Inst{31-24} = 0b11110100;
let Inst{23} = op23;
let Inst{21-20} = op21_20;
@ -1513,7 +1516,7 @@ class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4,
class NDataI<dag oops, dag iops, InstrItinClass itin,
string opc, string dt, string asm, string cstr, list<dag> pattern>
: NeonI<oops, iops, AddrModeNone, IndexModeNone, itin, opc, dt, asm,
: NeonI<oops, iops, AddrModeNone, IndexModeNone, NEONFrm, itin, opc, dt, asm,
cstr, pattern> {
let Inst{31-25} = 0b1111001;
}
@ -1621,7 +1624,7 @@ class NVLaneOp<bits<8> opcod1, bits<4> opcod2, bits<2> opcod3,
let Inst{4} = 1;
let OutOperandList = oops;
let InOperandList = !con(iops, (ops pred:$p));
let InOperandList = !con(iops, (ins pred:$p));
let AsmString = !strconcat(
!strconcat(!strconcat(opc, "${p}"), !strconcat(".", dt)),
!strconcat("\t", asm));

View File

@ -62,11 +62,14 @@ def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
SDNPVariadic]>;
def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
SDNPVariadic]>;
def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
SDNPVariadic]>;
def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
[SDNPHasChain, SDNPOptInFlag]>;
@ -282,7 +285,7 @@ def pclabel : Operand<i32> {
// shifter_operand operands: so_reg and so_imm.
def so_reg : Operand<i32>, // reg reg imm
ComplexPattern<i32, 3, "SelectShifterOperandReg",
ComplexPattern<i32, 3, "SelectShifterOperandReg",
[shl,srl,sra,rotr]> {
let PrintMethod = "printSORegOperand";
let MIOperandInfo = (ops GPR, GPR, i32imm);
@ -392,9 +395,14 @@ def addrmode5 : Operand<i32>,
// addrmode6 := reg with optional writeback
//
def addrmode6 : Operand<i32>,
ComplexPattern<i32, 4, "SelectAddrMode6", []> {
ComplexPattern<i32, 2, "SelectAddrMode6", []> {
let PrintMethod = "printAddrMode6Operand";
let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm, i32imm);
let MIOperandInfo = (ops GPR:$addr, i32imm);
}
def am6offset : Operand<i32> {
let PrintMethod = "printAddrMode6OffsetOperand";
let MIOperandInfo = (ops GPR);
}
// addrmodepc := pc + reg
@ -909,7 +917,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
def LDM_RET : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
reglist:$dsts, variable_ops),
IndexModeUpd, LdStMulFrm, IIC_Br,
"ldm${addr:submode}${p}\t$addr, $dsts",
"ldm${addr:submode}${p}\t$addr!, $dsts",
"$addr.addr = $wb", []>;
// On non-Darwin platforms R9 is callee-saved.
@ -1354,7 +1362,7 @@ def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p,
def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
reglist:$dsts, variable_ops),
IndexModeUpd, LdStMulFrm, IIC_iLoadm,
"ldm${addr:submode}${p}\t$addr, $dsts",
"ldm${addr:submode}${p}\t$addr!, $dsts",
"$addr.addr = $wb", []>;
} // mayLoad, hasExtraDefRegAllocReq
@ -1367,7 +1375,7 @@ def STM : AXI4st<(outs), (ins addrmode4:$addr, pred:$p,
def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
reglist:$srcs, variable_ops),
IndexModeUpd, LdStMulFrm, IIC_iStorem,
"stm${addr:submode}${p}\t$addr, $srcs",
"stm${addr:submode}${p}\t$addr!, $srcs",
"$addr.addr = $wb", []>;
} // mayStore, hasExtraSrcRegAllocReq

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,8 @@
//
def ARMtcall : SDNode<"ARMISD::tCALL", SDT_ARMcall,
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
SDNPVariadic]>;
def imm_neg_XFORM : SDNodeXForm<imm, [{
return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
@ -549,7 +550,7 @@ def tLDM : T1I<(outs),
def tLDM_UPD : T1It<(outs tGPR:$wb),
(ins addrmode4:$addr, pred:$p, reglist:$dsts, variable_ops),
IIC_iLoadm,
"ldm${addr:submode}${p}\t$addr, $dsts",
"ldm${addr:submode}${p}\t$addr!, $dsts",
"$addr.addr = $wb", []>,
T1Encoding<{1,1,0,0,1,?}>; // A6.2 & A8.6.53
} // mayLoad, hasExtraDefRegAllocReq
@ -558,7 +559,7 @@ let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
def tSTM_UPD : T1It<(outs tGPR:$wb),
(ins addrmode4:$addr, pred:$p, reglist:$srcs, variable_ops),
IIC_iStorem,
"stm${addr:submode}${p}\t$addr, $srcs",
"stm${addr:submode}${p}\t$addr!, $srcs",
"$addr.addr = $wb", []>,
T1Encoding<{1,1,0,0,0,?}>; // A6.2 & A8.6.189

View File

@ -1218,7 +1218,7 @@ def t2LDM : T2XI<(outs), (ins addrmode4:$addr, pred:$p,
def t2LDM_UPD : T2XIt<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
reglist:$dsts, variable_ops), IIC_iLoadm,
"ldm${addr:submode}${p}${addr:wide}\t$addr, $dsts",
"ldm${addr:submode}${p}${addr:wide}\t$addr!, $dsts",
"$addr.addr = $wb", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
@ -1244,7 +1244,7 @@ def t2STM : T2XI<(outs), (ins addrmode4:$addr, pred:$p,
def t2STM_UPD : T2XIt<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
reglist:$srcs, variable_ops),
IIC_iStorem,
"stm${addr:submode}${p}${addr:wide}\t$addr, $srcs",
"stm${addr:submode}${p}${addr:wide}\t$addr!, $srcs",
"$addr.addr = $wb", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;

View File

@ -25,8 +25,6 @@ def arm_ftoui : SDNode<"ARMISD::FTOUI", SDT_FTOI>;
def arm_ftosi : SDNode<"ARMISD::FTOSI", SDT_FTOI>;
def arm_sitof : SDNode<"ARMISD::SITOF", SDT_ITOF>;
def arm_uitof : SDNode<"ARMISD::UITOF", SDT_ITOF>;
def arm_f16tof32 : SDNode<"ARMISD::F16_TO_F32", SDT_ITOF>;
def arm_f32tof16 : SDNode<"ARMISD::F32_TO_F16", SDT_FTOI>;
def arm_fmstat : SDNode<"ARMISD::FMSTAT", SDTNone, [SDNPInFlag,SDNPOutFlag]>;
def arm_cmpfp : SDNode<"ARMISD::CMPFP", SDT_ARMCmp, [SDNPOutFlag]>;
def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0",SDT_CMPFP0, [SDNPOutFlag]>;
@ -94,7 +92,7 @@ def VLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dsts,
def VLDMD_UPD : AXDI5<(outs GPR:$wb), (ins addrmode5:$addr, pred:$p,
reglist:$dsts, variable_ops),
IndexModeUpd, IIC_fpLoadm,
"vldm${addr:submode}${p}\t${addr:base}, $dsts",
"vldm${addr:submode}${p}\t${addr:base}!, $dsts",
"$addr.base = $wb", []> {
let Inst{20} = 1;
}
@ -102,7 +100,7 @@ def VLDMD_UPD : AXDI5<(outs GPR:$wb), (ins addrmode5:$addr, pred:$p,
def VLDMS_UPD : AXSI5<(outs GPR:$wb), (ins addrmode5:$addr, pred:$p,
reglist:$dsts, variable_ops),
IndexModeUpd, IIC_fpLoadm,
"vldm${addr:submode}${p}\t${addr:base}, $dsts",
"vldm${addr:submode}${p}\t${addr:base}!, $dsts",
"$addr.base = $wb", []> {
let Inst{20} = 1;
}
@ -124,7 +122,7 @@ def VSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$srcs,
def VSTMD_UPD : AXDI5<(outs GPR:$wb), (ins addrmode5:$addr, pred:$p,
reglist:$srcs, variable_ops),
IndexModeUpd, IIC_fpStorem,
"vstm${addr:submode}${p}\t${addr:base}, $srcs",
"vstm${addr:submode}${p}\t${addr:base}!, $srcs",
"$addr.base = $wb", []> {
let Inst{20} = 0;
}
@ -132,7 +130,7 @@ def VSTMD_UPD : AXDI5<(outs GPR:$wb), (ins addrmode5:$addr, pred:$p,
def VSTMS_UPD : AXSI5<(outs GPR:$wb), (ins addrmode5:$addr, pred:$p,
reglist:$srcs, variable_ops),
IndexModeUpd, IIC_fpStorem,
"vstm${addr:submode}${p}\t${addr:base}, $srcs",
"vstm${addr:submode}${p}\t${addr:base}!, $srcs",
"$addr.base = $wb", []> {
let Inst{20} = 0;
}
@ -259,11 +257,17 @@ def VCVTSD : VFPAI<(outs SPR:$dst), (ins DPR:$a), VFPUnaryFrm,
def VCVTBSH : ASuI<0b11101, 0b11, 0b0010, 0b01, 0, (outs SPR:$dst), (ins SPR:$a),
/* FIXME */ IIC_fpCVTDS, "vcvtb", ".f32.f16\t$dst, $a",
[(set SPR:$dst, (f32 (arm_f32tof16 SPR:$a)))]>;
[/* For disassembly only; pattern left blank */]>;
def : ARMPat<(f32_to_f16 SPR:$a),
(i32 (COPY_TO_REGCLASS (VCVTBSH SPR:$a), GPR))>;
def VCVTBHS : ASuI<0b11101, 0b11, 0b0011, 0b01, 0, (outs SPR:$dst), (ins SPR:$a),
/* FIXME */ IIC_fpCVTDS, "vcvtb", ".f16.f32\t$dst, $a",
[(set SPR:$dst, (arm_f16tof32 SPR:$a))]>;
[/* For disassembly only; pattern left blank */]>;
def : ARMPat<(f16_to_f32 GPR:$a),
(VCVTBHS (COPY_TO_REGCLASS GPR:$a, SPR))>;
def VCVTTSH : ASuI<0b11101, 0b11, 0b0010, 0b11, 0, (outs SPR:$dst), (ins SPR:$a),
/* FIXME */ IIC_fpCVTDS, "vcvtt", ".f32.f16\t$dst, $a",

View File

@ -253,7 +253,7 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
.addImm(ARM_AM::getAM4ModeImm(Mode)).addImm(Pred).addReg(PredReg)
: BuildMI(MBB, MBBI, dl, TII->get(Opcode))
.addReg(Base, getKillRegState(BaseKill))
.addImm(ARM_AM::getAM5Opc(Mode, false, isDPR ? NumRegs<<1 : NumRegs))
.addImm(ARM_AM::getAM5Opc(Mode, isDPR ? NumRegs<<1 : NumRegs))
.addImm(Pred).addReg(PredReg);
for (unsigned i = 0; i != NumRegs; ++i)
MIB = MIB.addReg(Regs[i].first, getDefRegState(isDef)
@ -505,11 +505,9 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSMultiple(MachineBasicBlock &MBB,
if (MI->getOperand(i).getReg() == Base)
return false;
}
assert(!ARM_AM::getAM4WBFlag(MI->getOperand(1).getImm()));
Mode = ARM_AM::getAM4SubMode(MI->getOperand(1).getImm());
} else {
// VLDM{D|S}, VSTM{D|S} addressing mode 5 ops.
assert(!ARM_AM::getAM5WBFlag(MI->getOperand(1).getImm()));
Mode = ARM_AM::getAM5SubMode(MI->getOperand(1).getImm());
Offset = ARM_AM::getAM5Offset(MI->getOperand(1).getImm());
}
@ -573,11 +571,11 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSMultiple(MachineBasicBlock &MBB,
.addReg(Base, getKillRegState(BaseKill));
if (isAM4) {
// [t2]LDM_UPD, [t2]STM_UPD
MIB.addImm(ARM_AM::getAM4ModeImm(Mode, true))
MIB.addImm(ARM_AM::getAM4ModeImm(Mode))
.addImm(Pred).addReg(PredReg);
} else {
// VLDM[SD}_UPD, VSTM[SD]_UPD
MIB.addImm(ARM_AM::getAM5Opc(Mode, true, Offset))
MIB.addImm(ARM_AM::getAM5Opc(Mode, Offset))
.addImm(Pred).addReg(PredReg);
}
// Transfer the rest of operands.
@ -709,7 +707,7 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineBasicBlock &MBB,
unsigned Offset = 0;
if (isAM5)
Offset = ARM_AM::getAM5Opc(AddSub == ARM_AM::sub ? ARM_AM::db : ARM_AM::ia,
true, (isDPR ? 2 : 1));
(isDPR ? 2 : 1));
else if (isAM2)
Offset = ARM_AM::getAM2Opc(AddSub, Bytes, ARM_AM::no_shift);
else
@ -1157,19 +1155,24 @@ namespace {
};
}
/// MergeReturnIntoLDM - If this is a exit BB, try merging the return op
/// (bx lr) into the preceeding stack restore so it directly restore the value
/// of LR into pc.
/// ldmfd sp!, {r7, lr}
/// MergeReturnIntoLDM - If this is a exit BB, try merging the return ops
/// ("bx lr" and "mov pc, lr") into the preceeding stack restore so it
/// directly restore the value of LR into pc.
/// ldmfd sp!, {..., lr}
/// bx lr
/// or
/// ldmfd sp!, {..., lr}
/// mov pc, lr
/// =>
/// ldmfd sp!, {r7, pc}
/// ldmfd sp!, {..., pc}
bool ARMLoadStoreOpt::MergeReturnIntoLDM(MachineBasicBlock &MBB) {
if (MBB.empty()) return false;
MachineBasicBlock::iterator MBBI = prior(MBB.end());
if (MBBI != MBB.begin() &&
(MBBI->getOpcode() == ARM::BX_RET || MBBI->getOpcode() == ARM::tBX_RET)) {
(MBBI->getOpcode() == ARM::BX_RET ||
MBBI->getOpcode() == ARM::tBX_RET ||
MBBI->getOpcode() == ARM::MOVPCLR)) {
MachineInstr *PrevMI = prior(MBBI);
if (PrevMI->getOpcode() == ARM::LDM_UPD ||
PrevMI->getOpcode() == ARM::t2LDM_UPD) {

View File

@ -21,7 +21,7 @@
#include "llvm/Target/TargetRegistry.h"
using namespace llvm;
static const MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) {
static MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) {
Triple TheTriple(TT);
switch (TheTriple.getOS()) {
case Triple::Darwin:

View File

@ -23,6 +23,7 @@
#include "ARMISelLowering.h"
#include "Thumb1InstrInfo.h"
#include "Thumb2InstrInfo.h"
#include "llvm/ADT/OwningPtr.h"
namespace llvm {
@ -83,7 +84,8 @@ class ARMTargetMachine : public ARMBaseTargetMachine {
/// Thumb-1 and Thumb-2.
///
class ThumbTargetMachine : public ARMBaseTargetMachine {
ARMBaseInstrInfo *InstrInfo; // either Thumb1InstrInfo or Thumb2InstrInfo
// Either Thumb1InstrInfo or Thumb2InstrInfo.
OwningPtr<ARMBaseInstrInfo> InstrInfo;
const TargetData DataLayout; // Calculates type size & alignment
ARMTargetLowering TLInfo;
public:
@ -100,7 +102,9 @@ class ThumbTargetMachine : public ARMBaseTargetMachine {
}
/// returns either Thumb1InstrInfo or Thumb2InstrInfo
virtual const ARMBaseInstrInfo *getInstrInfo() const { return InstrInfo; }
virtual const ARMBaseInstrInfo *getInstrInfo() const {
return InstrInfo.get();
}
virtual const TargetData *getTargetData() const { return &DataLayout; }
};

View File

@ -101,6 +101,7 @@ namespace {
void printAddrMode5Operand(const MachineInstr *MI, int OpNum,
const char *Modifier = 0);
void printAddrMode6Operand(const MachineInstr *MI, int OpNum);
void printAddrMode6OffsetOperand(const MachineInstr *MI, int OpNum);
void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
const char *Modifier = 0);
void printBitfieldInvMaskImmOperand (const MachineInstr *MI, int OpNum);
@ -431,16 +432,16 @@ void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) {
O << "[" << getRegisterName(MO1.getReg());
if (!MO2.getReg()) {
if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
O << ", #"
<< (char)ARM_AM::getAM2Op(MO3.getImm())
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
<< ARM_AM::getAM2Offset(MO3.getImm());
O << "]";
return;
}
O << ", "
<< (char)ARM_AM::getAM2Op(MO3.getImm())
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
<< getRegisterName(MO2.getReg());
if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
@ -458,12 +459,12 @@ void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op){
unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
assert(ImmOffs && "Malformed indexed load / store!");
O << "#"
<< (char)ARM_AM::getAM2Op(MO2.getImm())
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
<< ImmOffs;
return;
}
O << (char)ARM_AM::getAM2Op(MO2.getImm())
O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
<< getRegisterName(MO1.getReg());
if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
@ -490,7 +491,7 @@ void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op) {
if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
O << ", #"
<< (char)ARM_AM::getAM3Op(MO3.getImm())
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()))
<< ImmOffs;
O << "]";
}
@ -508,35 +509,22 @@ void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op){
unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
assert(ImmOffs && "Malformed indexed load / store!");
O << "#"
<< (char)ARM_AM::getAM3Op(MO2.getImm())
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()))
<< ImmOffs;
}
void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
const char *Modifier) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
if (Modifier && strcmp(Modifier, "submode") == 0) {
if (MO1.getReg() == ARM::SP) {
// FIXME
bool isLDM = (MI->getOpcode() == ARM::LDM ||
MI->getOpcode() == ARM::LDM_UPD ||
MI->getOpcode() == ARM::LDM_RET ||
MI->getOpcode() == ARM::t2LDM ||
MI->getOpcode() == ARM::t2LDM_UPD ||
MI->getOpcode() == ARM::t2LDM_RET);
O << ARM_AM::getAMSubModeAltStr(Mode, isLDM);
} else
O << ARM_AM::getAMSubModeStr(Mode);
O << ARM_AM::getAMSubModeStr(Mode);
} else if (Modifier && strcmp(Modifier, "wide") == 0) {
ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
if (Mode == ARM_AM::ia)
O << ".w";
} else {
printOperand(MI, Op);
if (ARM_AM::getAM4WBFlag(MO2.getImm()))
O << "!";
}
}
@ -559,8 +547,6 @@ void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
} else if (Modifier && strcmp(Modifier, "base") == 0) {
// Used for FSTM{D|S} and LSTM{D|S} operations.
O << getRegisterName(MO1.getReg());
if (ARM_AM::getAM5WBFlag(MO2.getImm()))
O << "!";
return;
}
@ -568,7 +554,7 @@ void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
O << ", #"
<< (char)ARM_AM::getAM5Op(MO2.getImm())
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm()))
<< ImmOffs*4;
}
O << "]";
@ -577,22 +563,21 @@ void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
void ARMAsmPrinter::printAddrMode6Operand(const MachineInstr *MI, int Op) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
const MachineOperand &MO3 = MI->getOperand(Op+2);
const MachineOperand &MO4 = MI->getOperand(Op+3);
O << "[" << getRegisterName(MO1.getReg());
if (MO4.getImm()) {
if (MO2.getImm()) {
// FIXME: Both darwin as and GNU as violate ARM docs here.
O << ", :" << MO4.getImm();
O << ", :" << MO2.getImm();
}
O << "]";
}
if (ARM_AM::getAM6WBFlag(MO3.getImm())) {
if (MO2.getReg() == 0)
O << "!";
else
O << ", " << getRegisterName(MO2.getReg());
}
void ARMAsmPrinter::printAddrMode6OffsetOperand(const MachineInstr *MI, int Op){
const MachineOperand &MO = MI->getOperand(Op);
if (MO.getReg() == 0)
O << "!";
else
O << ", " << getRegisterName(MO.getReg());
}
void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
@ -604,7 +589,7 @@ void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
const MachineOperand &MO1 = MI->getOperand(Op);
assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
O << "[pc, +" << getRegisterName(MO1.getReg()) << "]";
O << "[pc, " << getRegisterName(MO1.getReg()) << "]";
}
void
@ -627,10 +612,11 @@ void
ARMAsmPrinter::printThumbITMask(const MachineInstr *MI, int Op) {
// (3 - the number of trailing zeros) is the number of then / else.
unsigned Mask = MI->getOperand(Op).getImm();
unsigned CondBit0 = Mask >> 4 & 1;
unsigned NumTZ = CountTrailingZeros_32(Mask);
assert(NumTZ <= 3 && "Invalid IT mask!");
for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
bool T = (Mask & (1 << Pos)) == 0;
bool T = ((Mask >> Pos) & 1) == CondBit0;
if (T)
O << 't';
else
@ -662,7 +648,7 @@ ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
if (MO3.getReg())
O << ", " << getRegisterName(MO3.getReg());
else if (unsigned ImmOffs = MO2.getImm())
O << ", #+" << ImmOffs * Scale;
O << ", #" << ImmOffs * Scale;
O << "]";
}
@ -684,7 +670,7 @@ void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
const MachineOperand &MO2 = MI->getOperand(Op+1);
O << "[" << getRegisterName(MO1.getReg());
if (unsigned ImmOffs = MO2.getImm())
O << ", #+" << ImmOffs*4;
O << ", #" << ImmOffs*4;
O << "]";
}
@ -720,7 +706,7 @@ void ARMAsmPrinter::printT2AddrModeImm12Operand(const MachineInstr *MI,
unsigned OffImm = MO2.getImm();
if (OffImm) // Don't print +0.
O << ", #+" << OffImm;
O << ", #" << OffImm;
O << "]";
}
@ -736,7 +722,7 @@ void ARMAsmPrinter::printT2AddrModeImm8Operand(const MachineInstr *MI,
if (OffImm < 0)
O << ", #-" << -OffImm;
else if (OffImm > 0)
O << ", #+" << OffImm;
O << ", #" << OffImm;
O << "]";
}
@ -752,7 +738,7 @@ void ARMAsmPrinter::printT2AddrModeImm8s4Operand(const MachineInstr *MI,
if (OffImm < 0)
O << ", #-" << -OffImm * 4;
else if (OffImm > 0)
O << ", #+" << OffImm * 4;
O << ", #" << OffImm * 4;
O << "]";
}
@ -764,7 +750,7 @@ void ARMAsmPrinter::printT2AddrModeImm8OffsetOperand(const MachineInstr *MI,
if (OffImm < 0)
O << "#-" << -OffImm;
else if (OffImm > 0)
O << "#+" << OffImm;
O << "#" << OffImm;
}
void ARMAsmPrinter::printT2AddrModeSoRegOperand(const MachineInstr *MI,

View File

@ -28,7 +28,159 @@ using namespace llvm;
#undef MachineInstr
#undef ARMAsmPrinter
void ARMInstPrinter::printInst(const MCInst *MI) { printInstruction(MI); }
static unsigned NextReg(unsigned Reg) {
switch (Reg) {
default:
assert(0 && "Unexpected register enum");
case ARM::D0:
return ARM::D1;
case ARM::D1:
return ARM::D2;
case ARM::D2:
return ARM::D3;
case ARM::D3:
return ARM::D4;
case ARM::D4:
return ARM::D5;
case ARM::D5:
return ARM::D6;
case ARM::D6:
return ARM::D7;
case ARM::D7:
return ARM::D8;
case ARM::D8:
return ARM::D9;
case ARM::D9:
return ARM::D10;
case ARM::D10:
return ARM::D11;
case ARM::D11:
return ARM::D12;
case ARM::D12:
return ARM::D13;
case ARM::D13:
return ARM::D14;
case ARM::D14:
return ARM::D15;
case ARM::D15:
return ARM::D16;
case ARM::D16:
return ARM::D17;
case ARM::D17:
return ARM::D18;
case ARM::D18:
return ARM::D19;
case ARM::D19:
return ARM::D20;
case ARM::D20:
return ARM::D21;
case ARM::D21:
return ARM::D22;
case ARM::D22:
return ARM::D23;
case ARM::D23:
return ARM::D24;
case ARM::D24:
return ARM::D25;
case ARM::D25:
return ARM::D26;
case ARM::D26:
return ARM::D27;
case ARM::D27:
return ARM::D28;
case ARM::D28:
return ARM::D29;
case ARM::D29:
return ARM::D30;
case ARM::D30:
return ARM::D31;
}
}
void ARMInstPrinter::printInst(const MCInst *MI) {
// Check for MOVs and print canonical forms, instead.
if (MI->getOpcode() == ARM::MOVs) {
const MCOperand &Dst = MI->getOperand(0);
const MCOperand &MO1 = MI->getOperand(1);
const MCOperand &MO2 = MI->getOperand(2);
const MCOperand &MO3 = MI->getOperand(3);
O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
printSBitModifierOperand(MI, 6);
printPredicateOperand(MI, 4);
O << '\t' << getRegisterName(Dst.getReg())
<< ", " << getRegisterName(MO1.getReg());
if (ARM_AM::getSORegShOp(MO3.getImm()) == ARM_AM::rrx)
return;
O << ", ";
if (MO2.getReg()) {
O << getRegisterName(MO2.getReg());
assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
} else {
O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
}
return;
}
// A8.6.123 PUSH
if ((MI->getOpcode() == ARM::STM_UPD || MI->getOpcode() == ARM::t2STM_UPD) &&
MI->getOperand(0).getReg() == ARM::SP) {
const MCOperand &MO1 = MI->getOperand(2);
if (ARM_AM::getAM4SubMode(MO1.getImm()) == ARM_AM::db) {
O << '\t' << "push";
printPredicateOperand(MI, 3);
O << '\t';
printRegisterList(MI, 5);
return;
}
}
// A8.6.122 POP
if ((MI->getOpcode() == ARM::LDM_UPD || MI->getOpcode() == ARM::t2LDM_UPD) &&
MI->getOperand(0).getReg() == ARM::SP) {
const MCOperand &MO1 = MI->getOperand(2);
if (ARM_AM::getAM4SubMode(MO1.getImm()) == ARM_AM::ia) {
O << '\t' << "pop";
printPredicateOperand(MI, 3);
O << '\t';
printRegisterList(MI, 5);
return;
}
}
// A8.6.355 VPUSH
if ((MI->getOpcode() == ARM::VSTMS_UPD || MI->getOpcode() ==ARM::VSTMD_UPD) &&
MI->getOperand(0).getReg() == ARM::SP) {
const MCOperand &MO1 = MI->getOperand(2);
if (ARM_AM::getAM5SubMode(MO1.getImm()) == ARM_AM::db) {
O << '\t' << "vpush";
printPredicateOperand(MI, 3);
O << '\t';
printRegisterList(MI, 5);
return;
}
}
// A8.6.354 VPOP
if ((MI->getOpcode() == ARM::VLDMS_UPD || MI->getOpcode() ==ARM::VLDMD_UPD) &&
MI->getOperand(0).getReg() == ARM::SP) {
const MCOperand &MO1 = MI->getOperand(2);
if (ARM_AM::getAM5SubMode(MO1.getImm()) == ARM_AM::ia) {
O << '\t' << "vpop";
printPredicateOperand(MI, 3);
O << '\t';
printRegisterList(MI, 5);
return;
}
}
printInstruction(MI);
}
void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
const char *Modifier) {
@ -36,6 +188,9 @@ void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
if (Op.isReg()) {
unsigned Reg = Op.getReg();
if (Modifier && strcmp(Modifier, "dregpair") == 0) {
O << '{' << getRegisterName(Reg) << ", "
<< getRegisterName(NextReg(Reg)) << '}';
#if 0
// FIXME: Breaks e.g. ARM/vmul.ll.
assert(0);
/*
@ -44,6 +199,7 @@ void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
O << '{'
<< getRegisterName(DRegLo) << ',' << getRegisterName(DRegHi)
<< '}';*/
#endif
} else if (Modifier && strcmp(Modifier, "lane") == 0) {
assert(0);
/*
@ -56,7 +212,8 @@ void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
O << getRegisterName(Reg);
}
} else if (Op.isImm()) {
assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
assert((Modifier && !strcmp(Modifier, "call")) ||
((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported"));
O << '#' << Op.getImm();
} else {
assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
@ -142,17 +299,17 @@ void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op) {
O << "[" << getRegisterName(MO1.getReg());
if (!MO2.getReg()) {
if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
O << ", #"
<< (char)ARM_AM::getAM2Op(MO3.getImm())
<< ARM_AM::getAM2Offset(MO3.getImm());
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
<< ARM_AM::getAM2Offset(MO3.getImm());
O << "]";
return;
}
O << ", "
<< (char)ARM_AM::getAM2Op(MO3.getImm())
<< getRegisterName(MO2.getReg());
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
<< getRegisterName(MO2.getReg());
if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
O << ", "
@ -169,11 +326,14 @@ void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
if (!MO1.getReg()) {
unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
assert(ImmOffs && "Malformed indexed load / store!");
O << '#' << (char)ARM_AM::getAM2Op(MO2.getImm()) << ImmOffs;
O << '#'
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
<< ImmOffs;
return;
}
O << (char)ARM_AM::getAM2Op(MO2.getImm()) << getRegisterName(MO1.getReg());
O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
<< getRegisterName(MO1.getReg());
if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
O << ", "
@ -196,8 +356,8 @@ void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned OpNum) {
if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
O << ", #"
<< (char)ARM_AM::getAM3Op(MO3.getImm())
<< ImmOffs;
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()))
<< ImmOffs;
O << ']';
}
@ -214,35 +374,24 @@ void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI,
unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
assert(ImmOffs && "Malformed indexed load / store!");
O << "#"
<< (char)ARM_AM::getAM3Op(MO2.getImm())
<< ImmOffs;
O << '#'
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()))
<< ImmOffs;
}
void ARMInstPrinter::printAddrMode4Operand(const MCInst *MI, unsigned OpNum,
const char *Modifier) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
if (Modifier && strcmp(Modifier, "submode") == 0) {
if (MO1.getReg() == ARM::SP) {
// FIXME
bool isLDM = (MI->getOpcode() == ARM::LDM ||
MI->getOpcode() == ARM::LDM_RET ||
MI->getOpcode() == ARM::t2LDM ||
MI->getOpcode() == ARM::t2LDM_RET);
O << ARM_AM::getAMSubModeAltStr(Mode, isLDM);
} else
O << ARM_AM::getAMSubModeStr(Mode);
O << ARM_AM::getAMSubModeStr(Mode);
} else if (Modifier && strcmp(Modifier, "wide") == 0) {
ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
if (Mode == ARM_AM::ia)
O << ".w";
} else {
printOperand(MI, OpNum);
if (ARM_AM::getAM4WBFlag(MO2.getImm()))
O << "!";
}
}
@ -263,8 +412,6 @@ void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
} else if (Modifier && strcmp(Modifier, "base") == 0) {
// Used for FSTM{D|S} and LSTM{D|S} operations.
O << getRegisterName(MO1.getReg());
if (ARM_AM::getAM5WBFlag(MO2.getImm()))
O << "!";
return;
}
@ -272,7 +419,7 @@ void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
O << ", #"
<< (char)ARM_AM::getAM5Op(MO2.getImm())
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm()))
<< ImmOffs*4;
}
O << "]";
@ -281,17 +428,22 @@ void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
const MCOperand &MO3 = MI->getOperand(OpNum+2);
// FIXME: No support yet for specifying alignment.
O << '[' << getRegisterName(MO1.getReg()) << ']';
if (ARM_AM::getAM6WBFlag(MO3.getImm())) {
if (MO2.getReg() == 0)
O << '!';
else
O << ", " << getRegisterName(MO2.getReg());
O << "[" << getRegisterName(MO1.getReg());
if (MO2.getImm()) {
// FIXME: Both darwin as and GNU as violate ARM docs here.
O << ", :" << MO2.getImm();
}
O << "]";
}
void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
unsigned OpNum) {
const MCOperand &MO = MI->getOperand(OpNum);
if (MO.getReg() == 0)
O << "!";
else
O << ", " << getRegisterName(MO.getReg());
}
void ARMInstPrinter::printAddrModePCOperand(const MCInst *MI, unsigned OpNum,
@ -311,14 +463,56 @@ void ARMInstPrinter::printBitfieldInvMaskImmOperand (const MCInst *MI,
void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum) {
O << "{";
// Always skip the first operand, it's the optional (and implicit writeback).
for (unsigned i = OpNum+1, e = MI->getNumOperands(); i != e; ++i) {
if (i != OpNum+1) O << ", ";
for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
if (i != OpNum) O << ", ";
O << getRegisterName(MI->getOperand(i).getReg());
}
O << "}";
}
void ARMInstPrinter::printCPSOptionOperand(const MCInst *MI, unsigned OpNum) {
const MCOperand &Op = MI->getOperand(OpNum);
unsigned option = Op.getImm();
unsigned mode = option & 31;
bool changemode = option >> 5 & 1;
unsigned AIF = option >> 6 & 7;
unsigned imod = option >> 9 & 3;
if (imod == 2)
O << "ie";
else if (imod == 3)
O << "id";
O << '\t';
if (imod > 1) {
if (AIF & 4) O << 'a';
if (AIF & 2) O << 'i';
if (AIF & 1) O << 'f';
if (AIF > 0 && changemode) O << ", ";
}
if (changemode)
O << '#' << mode;
}
void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum) {
const MCOperand &Op = MI->getOperand(OpNum);
unsigned Mask = Op.getImm();
if (Mask) {
O << '_';
if (Mask & 8) O << 'f';
if (Mask & 4) O << 's';
if (Mask & 2) O << 'x';
if (Mask & 1) O << 'c';
}
}
void ARMInstPrinter::printNegZeroOperand(const MCInst *MI, unsigned OpNum){
const MCOperand &Op = MI->getOperand(OpNum);
O << '#';
if (Op.getImm() < 0)
O << '-' << (-Op.getImm() - 1);
else
O << Op.getImm();
}
void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum) {
ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
if (CC != ARMCC::AL)
@ -360,3 +554,191 @@ void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum) {
void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum) {
O << "#" << MI->getOperand(OpNum).getImm() * 4;
}
void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum) {
// (3 - the number of trailing zeros) is the number of then / else.
unsigned Mask = MI->getOperand(OpNum).getImm();
unsigned CondBit0 = Mask >> 4 & 1;
unsigned NumTZ = CountTrailingZeros_32(Mask);
assert(NumTZ <= 3 && "Invalid IT mask!");
for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
bool T = ((Mask >> Pos) & 1) == CondBit0;
if (T)
O << 't';
else
O << 'e';
}
}
void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op)
{
const MCOperand &MO1 = MI->getOperand(Op);
const MCOperand &MO2 = MI->getOperand(Op+1);
O << "[" << getRegisterName(MO1.getReg());
O << ", " << getRegisterName(MO2.getReg()) << "]";
}
void ARMInstPrinter::printThumbAddrModeRI5Operand(const MCInst *MI, unsigned Op,
unsigned Scale) {
const MCOperand &MO1 = MI->getOperand(Op);
const MCOperand &MO2 = MI->getOperand(Op+1);
const MCOperand &MO3 = MI->getOperand(Op+2);
if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
printOperand(MI, Op);
return;
}
O << "[" << getRegisterName(MO1.getReg());
if (MO3.getReg())
O << ", " << getRegisterName(MO3.getReg());
else if (unsigned ImmOffs = MO2.getImm())
O << ", #" << ImmOffs * Scale;
O << "]";
}
void ARMInstPrinter::printThumbAddrModeS1Operand(const MCInst *MI, unsigned Op)
{
printThumbAddrModeRI5Operand(MI, Op, 1);
}
void ARMInstPrinter::printThumbAddrModeS2Operand(const MCInst *MI, unsigned Op)
{
printThumbAddrModeRI5Operand(MI, Op, 2);
}
void ARMInstPrinter::printThumbAddrModeS4Operand(const MCInst *MI, unsigned Op)
{
printThumbAddrModeRI5Operand(MI, Op, 4);
}
void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI,unsigned Op) {
const MCOperand &MO1 = MI->getOperand(Op);
const MCOperand &MO2 = MI->getOperand(Op+1);
O << "[" << getRegisterName(MO1.getReg());
if (unsigned ImmOffs = MO2.getImm())
O << ", #" << ImmOffs*4;
O << "]";
}
void ARMInstPrinter::printTBAddrMode(const MCInst *MI, unsigned OpNum) {
O << "[pc, " << getRegisterName(MI->getOperand(OpNum).getReg());
if (MI->getOpcode() == ARM::t2TBH)
O << ", lsl #1";
O << ']';
}
// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
// register with shift forms.
// REG 0 0 - e.g. R5
// REG IMM, SH_OPC - e.g. R5, LSL #3
void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
unsigned Reg = MO1.getReg();
O << getRegisterName(Reg);
// Print the shift opc.
O << ", "
<< ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()))
<< " ";
assert(MO2.isImm() && "Not a valid t2_so_reg value!");
O << "#" << ARM_AM::getSORegOffset(MO2.getImm());
}
void ARMInstPrinter::printT2AddrModeImm12Operand(const MCInst *MI,
unsigned OpNum) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
O << "[" << getRegisterName(MO1.getReg());
unsigned OffImm = MO2.getImm();
if (OffImm) // Don't print +0.
O << ", #" << OffImm;
O << "]";
}
void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI,
unsigned OpNum) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
O << "[" << getRegisterName(MO1.getReg());
int32_t OffImm = (int32_t)MO2.getImm();
// Don't print +0.
if (OffImm < 0)
O << ", #-" << -OffImm;
else if (OffImm > 0)
O << ", #" << OffImm;
O << "]";
}
void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI,
unsigned OpNum) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
O << "[" << getRegisterName(MO1.getReg());
int32_t OffImm = (int32_t)MO2.getImm() / 4;
// Don't print +0.
if (OffImm < 0)
O << ", #-" << -OffImm * 4;
else if (OffImm > 0)
O << ", #" << OffImm * 4;
O << "]";
}
void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(const MCInst *MI,
unsigned OpNum) {
const MCOperand &MO1 = MI->getOperand(OpNum);
int32_t OffImm = (int32_t)MO1.getImm();
// Don't print +0.
if (OffImm < 0)
O << "#-" << -OffImm;
else if (OffImm > 0)
O << "#" << OffImm;
}
void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(const MCInst *MI,
unsigned OpNum) {
const MCOperand &MO1 = MI->getOperand(OpNum);
int32_t OffImm = (int32_t)MO1.getImm() / 4;
// Don't print +0.
if (OffImm < 0)
O << "#-" << -OffImm * 4;
else if (OffImm > 0)
O << "#" << OffImm * 4;
}
void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
unsigned OpNum) {
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum+1);
const MCOperand &MO3 = MI->getOperand(OpNum+2);
O << "[" << getRegisterName(MO1.getReg());
assert(MO2.getReg() && "Invalid so_reg load / store address!");
O << ", " << getRegisterName(MO2.getReg());
unsigned ShAmt = MO3.getImm();
if (ShAmt) {
assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
O << ", lsl #" << ShAmt;
}
O << "]";
}
void ARMInstPrinter::printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum) {
O << '#' << MI->getOperand(OpNum).getImm();
}
void ARMInstPrinter::printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum) {
O << '#' << MI->getOperand(OpNum).getImm();
}

View File

@ -48,32 +48,33 @@ class ARMInstPrinter : public MCInstPrinter {
void printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
const char *Modifier = 0);
void printAddrMode6Operand(const MCInst *MI, unsigned OpNum);
void printAddrMode6OffsetOperand(const MCInst *MI, unsigned OpNum);
void printAddrModePCOperand(const MCInst *MI, unsigned OpNum,
const char *Modifier = 0);
void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum);
void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum);
void printThumbITMask(const MCInst *MI, unsigned OpNum) {}
void printThumbAddrModeRROperand(const MCInst *MI, unsigned OpNum) {}
void printThumbITMask(const MCInst *MI, unsigned OpNum);
void printThumbAddrModeRROperand(const MCInst *MI, unsigned OpNum);
void printThumbAddrModeRI5Operand(const MCInst *MI, unsigned OpNum,
unsigned Scale) {}
void printThumbAddrModeS1Operand(const MCInst *MI, unsigned OpNum) {}
void printThumbAddrModeS2Operand(const MCInst *MI, unsigned OpNum) {}
void printThumbAddrModeS4Operand(const MCInst *MI, unsigned OpNum) {}
void printThumbAddrModeSPOperand(const MCInst *MI, unsigned OpNum) {}
unsigned Scale);
void printThumbAddrModeS1Operand(const MCInst *MI, unsigned OpNum);
void printThumbAddrModeS2Operand(const MCInst *MI, unsigned OpNum);
void printThumbAddrModeS4Operand(const MCInst *MI, unsigned OpNum);
void printThumbAddrModeSPOperand(const MCInst *MI, unsigned OpNum);
void printT2SOOperand(const MCInst *MI, unsigned OpNum) {}
void printT2AddrModeImm12Operand(const MCInst *MI, unsigned OpNum) {}
void printT2AddrModeImm8Operand(const MCInst *MI, unsigned OpNum) {}
void printT2AddrModeImm8s4Operand(const MCInst *MI, unsigned OpNum) {}
void printT2AddrModeImm8OffsetOperand(const MCInst *MI, unsigned OpNum) {}
void printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, unsigned OpNum) {}
void printT2AddrModeSoRegOperand(const MCInst *MI, unsigned OpNum) {}
void printT2SOOperand(const MCInst *MI, unsigned OpNum);
void printT2AddrModeImm12Operand(const MCInst *MI, unsigned OpNum);
void printT2AddrModeImm8Operand(const MCInst *MI, unsigned OpNum);
void printT2AddrModeImm8s4Operand(const MCInst *MI, unsigned OpNum);
void printT2AddrModeImm8OffsetOperand(const MCInst *MI, unsigned OpNum);
void printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, unsigned OpNum);
void printT2AddrModeSoRegOperand(const MCInst *MI, unsigned OpNum);
void printCPSOptionOperand(const MCInst *MI, unsigned OpNum) {}
void printMSRMaskOperand(const MCInst *MI, unsigned OpNum) {}
void printNegZeroOperand(const MCInst *MI, unsigned OpNum) {}
void printCPSOptionOperand(const MCInst *MI, unsigned OpNum);
void printMSRMaskOperand(const MCInst *MI, unsigned OpNum);
void printNegZeroOperand(const MCInst *MI, unsigned OpNum);
void printPredicateOperand(const MCInst *MI, unsigned OpNum);
void printMandatoryPredicateOperand(const MCInst *MI, unsigned OpNum);
void printSBitModifierOperand(const MCInst *MI, unsigned OpNum);
@ -82,10 +83,10 @@ class ARMInstPrinter : public MCInstPrinter {
const char *Modifier);
void printJTBlockOperand(const MCInst *MI, unsigned OpNum) {}
void printJT2BlockOperand(const MCInst *MI, unsigned OpNum) {}
void printTBAddrMode(const MCInst *MI, unsigned OpNum) {}
void printTBAddrMode(const MCInst *MI, unsigned OpNum);
void printNoHashImmediate(const MCInst *MI, unsigned OpNum);
void printVFPf32ImmOperand(const MCInst *MI, int OpNum) {}
void printVFPf64ImmOperand(const MCInst *MI, int OpNum) {}
void printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum);
void printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum);
void printHex8ImmOperand(const MCInst *MI, int OpNum) {}
void printHex16ImmOperand(const MCInst *MI, int OpNum) {}
void printHex32ImmOperand(const MCInst *MI, int OpNum) {}

View File

@ -64,16 +64,16 @@ static bool isNEONMultiRegOp(int Opcode, unsigned &FirstOpnd, unsigned &NumRegs,
NumRegs = 4;
return true;
case ARM::VLD2LNq16a:
case ARM::VLD2LNq32a:
case ARM::VLD2LNq16:
case ARM::VLD2LNq32:
FirstOpnd = 0;
NumRegs = 2;
Offset = 0;
Stride = 2;
return true;
case ARM::VLD2LNq16b:
case ARM::VLD2LNq32b:
case ARM::VLD2LNq16odd:
case ARM::VLD2LNq32odd:
FirstOpnd = 0;
NumRegs = 2;
Offset = 1;
@ -91,34 +91,34 @@ static bool isNEONMultiRegOp(int Opcode, unsigned &FirstOpnd, unsigned &NumRegs,
NumRegs = 3;
return true;
case ARM::VLD3q8a:
case ARM::VLD3q16a:
case ARM::VLD3q32a:
case ARM::VLD3q8_UPD:
case ARM::VLD3q16_UPD:
case ARM::VLD3q32_UPD:
FirstOpnd = 0;
NumRegs = 3;
Offset = 0;
Stride = 2;
return true;
case ARM::VLD3q8b:
case ARM::VLD3q16b:
case ARM::VLD3q32b:
case ARM::VLD3q8odd_UPD:
case ARM::VLD3q16odd_UPD:
case ARM::VLD3q32odd_UPD:
FirstOpnd = 0;
NumRegs = 3;
Offset = 1;
Stride = 2;
return true;
case ARM::VLD3LNq16a:
case ARM::VLD3LNq32a:
case ARM::VLD3LNq16:
case ARM::VLD3LNq32:
FirstOpnd = 0;
NumRegs = 3;
Offset = 0;
Stride = 2;
return true;
case ARM::VLD3LNq16b:
case ARM::VLD3LNq32b:
case ARM::VLD3LNq16odd:
case ARM::VLD3LNq32odd:
FirstOpnd = 0;
NumRegs = 3;
Offset = 1;
@ -136,34 +136,34 @@ static bool isNEONMultiRegOp(int Opcode, unsigned &FirstOpnd, unsigned &NumRegs,
NumRegs = 4;
return true;
case ARM::VLD4q8a:
case ARM::VLD4q16a:
case ARM::VLD4q32a:
case ARM::VLD4q8_UPD:
case ARM::VLD4q16_UPD:
case ARM::VLD4q32_UPD:
FirstOpnd = 0;
NumRegs = 4;
Offset = 0;
Stride = 2;
return true;
case ARM::VLD4q8b:
case ARM::VLD4q16b:
case ARM::VLD4q32b:
case ARM::VLD4q8odd_UPD:
case ARM::VLD4q16odd_UPD:
case ARM::VLD4q32odd_UPD:
FirstOpnd = 0;
NumRegs = 4;
Offset = 1;
Stride = 2;
return true;
case ARM::VLD4LNq16a:
case ARM::VLD4LNq32a:
case ARM::VLD4LNq16:
case ARM::VLD4LNq32:
FirstOpnd = 0;
NumRegs = 4;
Offset = 0;
Stride = 2;
return true;
case ARM::VLD4LNq16b:
case ARM::VLD4LNq32b:
case ARM::VLD4LNq16odd:
case ARM::VLD4LNq32odd:
FirstOpnd = 0;
NumRegs = 4;
Offset = 1;
@ -177,28 +177,28 @@ static bool isNEONMultiRegOp(int Opcode, unsigned &FirstOpnd, unsigned &NumRegs,
case ARM::VST2LNd8:
case ARM::VST2LNd16:
case ARM::VST2LNd32:
FirstOpnd = 4;
FirstOpnd = 2;
NumRegs = 2;
return true;
case ARM::VST2q8:
case ARM::VST2q16:
case ARM::VST2q32:
FirstOpnd = 4;
FirstOpnd = 2;
NumRegs = 4;
return true;
case ARM::VST2LNq16a:
case ARM::VST2LNq32a:
FirstOpnd = 4;
case ARM::VST2LNq16:
case ARM::VST2LNq32:
FirstOpnd = 2;
NumRegs = 2;
Offset = 0;
Stride = 2;
return true;
case ARM::VST2LNq16b:
case ARM::VST2LNq32b:
FirstOpnd = 4;
case ARM::VST2LNq16odd:
case ARM::VST2LNq32odd:
FirstOpnd = 2;
NumRegs = 2;
Offset = 1;
Stride = 2;
@ -211,39 +211,39 @@ static bool isNEONMultiRegOp(int Opcode, unsigned &FirstOpnd, unsigned &NumRegs,
case ARM::VST3LNd8:
case ARM::VST3LNd16:
case ARM::VST3LNd32:
FirstOpnd = 4;
FirstOpnd = 2;
NumRegs = 3;
return true;
case ARM::VST3q8a:
case ARM::VST3q16a:
case ARM::VST3q32a:
FirstOpnd = 5;
case ARM::VST3q8_UPD:
case ARM::VST3q16_UPD:
case ARM::VST3q32_UPD:
FirstOpnd = 4;
NumRegs = 3;
Offset = 0;
Stride = 2;
return true;
case ARM::VST3q8b:
case ARM::VST3q16b:
case ARM::VST3q32b:
FirstOpnd = 5;
case ARM::VST3q8odd_UPD:
case ARM::VST3q16odd_UPD:
case ARM::VST3q32odd_UPD:
FirstOpnd = 4;
NumRegs = 3;
Offset = 1;
Stride = 2;
return true;
case ARM::VST3LNq16a:
case ARM::VST3LNq32a:
FirstOpnd = 4;
case ARM::VST3LNq16:
case ARM::VST3LNq32:
FirstOpnd = 2;
NumRegs = 3;
Offset = 0;
Stride = 2;
return true;
case ARM::VST3LNq16b:
case ARM::VST3LNq32b:
FirstOpnd = 4;
case ARM::VST3LNq16odd:
case ARM::VST3LNq32odd:
FirstOpnd = 2;
NumRegs = 3;
Offset = 1;
Stride = 2;
@ -256,39 +256,39 @@ static bool isNEONMultiRegOp(int Opcode, unsigned &FirstOpnd, unsigned &NumRegs,
case ARM::VST4LNd8:
case ARM::VST4LNd16:
case ARM::VST4LNd32:
FirstOpnd = 4;
FirstOpnd = 2;
NumRegs = 4;
return true;
case ARM::VST4q8a:
case ARM::VST4q16a:
case ARM::VST4q32a:
FirstOpnd = 5;
case ARM::VST4q8_UPD:
case ARM::VST4q16_UPD:
case ARM::VST4q32_UPD:
FirstOpnd = 4;
NumRegs = 4;
Offset = 0;
Stride = 2;
return true;
case ARM::VST4q8b:
case ARM::VST4q16b:
case ARM::VST4q32b:
FirstOpnd = 5;
case ARM::VST4q8odd_UPD:
case ARM::VST4q16odd_UPD:
case ARM::VST4q32odd_UPD:
FirstOpnd = 4;
NumRegs = 4;
Offset = 1;
Stride = 2;
return true;
case ARM::VST4LNq16a:
case ARM::VST4LNq32a:
FirstOpnd = 4;
case ARM::VST4LNq16:
case ARM::VST4LNq32:
FirstOpnd = 2;
NumRegs = 4;
Offset = 0;
Stride = 2;
return true;
case ARM::VST4LNq16b:
case ARM::VST4LNq32b:
FirstOpnd = 4;
case ARM::VST4LNq16odd:
case ARM::VST4LNq32odd:
FirstOpnd = 2;
NumRegs = 4;
Offset = 1;
Stride = 2;

View File

@ -78,14 +78,16 @@ bool Thumb2ITBlockPass::InsertITBlocks(MachineBasicBlock &MBB) {
DebugLoc ndl = NMI->getDebugLoc();
unsigned NPredReg = 0;
ARMCC::CondCodes NCC = getPredicate(NMI, NPredReg);
if (NCC == OCC) {
Mask |= (1 << Pos);
} else if (NCC != CC)
if (NCC == CC || NCC == OCC)
Mask |= (NCC & 1) << Pos;
else
break;
--Pos;
++MBBI;
}
Mask |= (1 << Pos);
// Tag along (firstcond[0] << 4) with the mask.
Mask |= (CC & 1) << 4;
MIB.addImm(Mask);
Modified = true;
++NumITs;

View File

@ -56,16 +56,16 @@ class MfcForm<bits<6> opcode, bits<16> fc, string asmstr, InstrItinClass itin>
: InstAlpha<opcode, asmstr, itin> {
bits<5> Ra;
let OutOperandList = (ops GPRC:$RA);
let InOperandList = (ops);
let OutOperandList = (outs GPRC:$RA);
let InOperandList = (ins);
let Inst{25-21} = Ra;
let Inst{20-16} = 0;
let Inst{15-0} = fc;
}
class MfcPForm<bits<6> opcode, bits<16> fc, string asmstr, InstrItinClass itin>
: InstAlpha<opcode, asmstr, itin> {
let OutOperandList = (ops);
let InOperandList = (ops);
let OutOperandList = (outs);
let InOperandList = (ins);
let Inst{25-21} = 0;
let Inst{20-16} = 0;
let Inst{15-0} = fc;
@ -77,7 +77,7 @@ class MbrForm<bits<6> opcode, bits<2> TB, dag OL, string asmstr, InstrItinClass
bits<5> Rb;
bits<14> disp;
let OutOperandList = (ops);
let OutOperandList = (outs);
let InOperandList = OL;
let Inst{25-21} = Ra;
@ -92,7 +92,7 @@ class MbrpForm<bits<6> opcode, bits<2> TB, dag OL, string asmstr, list<dag> patt
bits<5> Rb;
bits<14> disp;
let OutOperandList = (ops);
let OutOperandList = (outs);
let InOperandList = OL;
let Inst{25-21} = Ra;
@ -107,7 +107,7 @@ def target : Operand<OtherVT> {}
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
class BFormN<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin>
: InstAlpha<opcode, asmstr, itin> {
let OutOperandList = (ops);
let OutOperandList = (outs);
let InOperandList = OL;
bits<64> Opc; //dummy
bits<5> Ra;
@ -122,8 +122,8 @@ let isBranch = 1, isTerminator = 1 in
class BFormD<bits<6> opcode, string asmstr, list<dag> pattern, InstrItinClass itin>
: InstAlpha<opcode, asmstr, itin> {
let Pattern = pattern;
let OutOperandList = (ops);
let InOperandList = (ops target:$DISP);
let OutOperandList = (outs);
let InOperandList = (ins target:$DISP);
bits<5> Ra;
bits<21> disp;
@ -250,7 +250,7 @@ class FPForm<bits<6> opcode, bits<11> fun, string asmstr, list<dag> pattern, Ins
//3.3.5
class PALForm<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin>
: InstAlpha<opcode, asmstr, itin> {
let OutOperandList = (ops);
let OutOperandList = (outs);
let InOperandList = OL;
bits<26> Function;

View File

@ -392,12 +392,12 @@ def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0
let isReturn = 1, isTerminator = 1, isBarrier = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in {
def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1", s_jsr>; //Return from subroutine
def RETDAGp : MbrpForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1", [(retflag)], s_jsr>; //Return from subroutine
def RETDAG : MbrForm< 0x1A, 0x02, (ins), "ret $$31,($$26),1", s_jsr>; //Return from subroutine
def RETDAGp : MbrpForm< 0x1A, 0x02, (ins), "ret $$31,($$26),1", [(retflag)], s_jsr>; //Return from subroutine
}
let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1, Ra = 31, disp = 0 in
def JMP : MbrpForm< 0x1A, 0x00, (ops GPRC:$RS), "jmp $$31,($RS),0",
def JMP : MbrpForm< 0x1A, 0x00, (ins GPRC:$RS), "jmp $$31,($RS),0",
[(brind GPRC:$RS)], s_jsr>; //Jump
let isCall = 1, Ra = 26,
@ -414,18 +414,18 @@ let isCall = 1, Ra = 26, Rb = 27, disp = 0,
F0, F1,
F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R27, R29] in {
def JSR : MbrForm< 0x1A, 0x01, (ops ), "jsr $$26,($$27),0", s_jsr>; //Jump to subroutine
def JSR : MbrForm< 0x1A, 0x01, (ins), "jsr $$26,($$27),0", s_jsr>; //Jump to subroutine
}
let isCall = 1, Ra = 23, Rb = 27, disp = 0,
Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in
def JSRs : MbrForm< 0x1A, 0x01, (ops ), "jsr $$23,($$27),0", s_jsr>; //Jump to div or rem
def JSRs : MbrForm< 0x1A, 0x01, (ins), "jsr $$23,($$27),0", s_jsr>; //Jump to div or rem
def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP", s_jsr>; //Jump to subroutine return
def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ins GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP", s_jsr>; //Jump to subroutine return
let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
let OutOperandList = (outs GPRC:$RA), InOperandList = (ins s64imm:$DISP, GPRC:$RB) in {
def LDQ : MForm<0x29, 1, "ldq $RA,$DISP($RB)",
[(set GPRC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
def LDQr : MForm<0x29, 1, "ldq $RA,$DISP($RB)\t\t!gprellow",
@ -445,7 +445,7 @@ def LDWUr : MForm<0x0C, 1, "ldwu $RA,$DISP($RB)\t\t!gprellow",
}
let OutOperandList = (ops), InOperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in {
let OutOperandList = (outs), InOperandList = (ins GPRC:$RA, s64imm:$DISP, GPRC:$RB) in {
def STB : MForm<0x0E, 0, "stb $RA,$DISP($RB)",
[(truncstorei8 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
def STBr : MForm<0x0E, 0, "stb $RA,$DISP($RB)\t\t!gprellow",
@ -465,7 +465,7 @@ def STQr : MForm<0x2D, 0, "stq $RA,$DISP($RB)\t\t!gprellow",
}
//Load address
let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
let OutOperandList = (outs GPRC:$RA), InOperandList = (ins s64imm:$DISP, GPRC:$RB) in {
def LDA : MForm<0x08, 0, "lda $RA,$DISP($RB)",
[(set GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_lda>;
def LDAr : MForm<0x08, 0, "lda $RA,$DISP($RB)\t\t!gprellow",
@ -476,25 +476,25 @@ def LDAHr : MForm<0x09, 0, "ldah $RA,$DISP($RB)\t\t!gprelhigh",
[(set GPRC:$RA, (Alpha_gprelhi tglobaladdr:$DISP, GPRC:$RB))], s_lda>; //Load address high
}
let OutOperandList = (ops), InOperandList = (ops F4RC:$RA, s64imm:$DISP, GPRC:$RB) in {
let OutOperandList = (outs), InOperandList = (ins F4RC:$RA, s64imm:$DISP, GPRC:$RB) in {
def STS : MForm<0x26, 0, "sts $RA,$DISP($RB)",
[(store F4RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
def STSr : MForm<0x26, 0, "sts $RA,$DISP($RB)\t\t!gprellow",
[(store F4RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
}
let OutOperandList = (ops F4RC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
let OutOperandList = (outs F4RC:$RA), InOperandList = (ins s64imm:$DISP, GPRC:$RB) in {
def LDS : MForm<0x22, 1, "lds $RA,$DISP($RB)",
[(set F4RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
def LDSr : MForm<0x22, 1, "lds $RA,$DISP($RB)\t\t!gprellow",
[(set F4RC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_fld>;
}
let OutOperandList = (ops), InOperandList = (ops F8RC:$RA, s64imm:$DISP, GPRC:$RB) in {
let OutOperandList = (outs), InOperandList = (ins F8RC:$RA, s64imm:$DISP, GPRC:$RB) in {
def STT : MForm<0x27, 0, "stt $RA,$DISP($RB)",
[(store F8RC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_fst>;
def STTr : MForm<0x27, 0, "stt $RA,$DISP($RB)\t\t!gprellow",
[(store F8RC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_fst>;
}
let OutOperandList = (ops F8RC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in {
let OutOperandList = (outs F8RC:$RA), InOperandList = (ins s64imm:$DISP, GPRC:$RB) in {
def LDT : MForm<0x23, 1, "ldt $RA,$DISP($RB)",
[(set F8RC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_fld>;
def LDTr : MForm<0x23, 1, "ldt $RA,$DISP($RB)\t\t!gprellow",
@ -570,15 +570,15 @@ def : Pat<(truncstorei8 GPRC:$DATA, GPRC:$addr),
//load address, rellocated gpdist form
let OutOperandList = (ops GPRC:$RA),
InOperandList = (ops s16imm:$DISP, GPRC:$RB, s16imm:$NUM),
let OutOperandList = (outs GPRC:$RA),
InOperandList = (ins s16imm:$DISP, GPRC:$RB, s16imm:$NUM),
mayLoad = 1 in {
def LDAg : MForm<0x08, 1, "lda $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address
def LDAHg : MForm<0x09, 1, "ldah $RA,0($RB)\t\t!gpdisp!$NUM", [], s_lda>; //Load address
}
//Load quad, rellocated literal form
let OutOperandList = (ops GPRC:$RA), InOperandList = (ops s64imm:$DISP, GPRC:$RB) in
let OutOperandList = (outs GPRC:$RA), InOperandList = (ins s64imm:$DISP, GPRC:$RB) in
def LDQl : MForm<0x29, 1, "ldq $RA,$DISP($RB)\t\t!literal",
[(set GPRC:$RA, (Alpha_rellit tglobaladdr:$DISP, GPRC:$RB))], s_ild>;
def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB),
@ -591,8 +591,8 @@ let OutOperandList = (outs GPRC:$RR),
def STQ_C : MForm<0x2F, 0, "stq_l $RA,$DISP($RB)", [], s_ist>;
def STL_C : MForm<0x2E, 0, "stl_l $RA,$DISP($RB)", [], s_ist>;
}
let OutOperandList = (ops GPRC:$RA),
InOperandList = (ops s64imm:$DISP, GPRC:$RB),
let OutOperandList = (outs GPRC:$RA),
InOperandList = (ins s64imm:$DISP, GPRC:$RB),
mayLoad = 1 in {
def LDQ_L : MForm<0x2B, 1, "ldq_l $RA,$DISP($RB)", [], s_ild>;
def LDL_L : MForm<0x2A, 1, "ldl_l $RA,$DISP($RB)", [], s_ild>;
@ -611,11 +611,11 @@ def : Pat<(membarrier (i64 imm), (i64 imm), (i64 imm), (i64 imm), (i64 imm)),
//Floats
let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F4RC:$RB), Fa = 31 in
let OutOperandList = (outs F4RC:$RC), InOperandList = (ins F4RC:$RB), Fa = 31 in
def SQRTS : FPForm<0x14, 0x58B, "sqrts/su $RB,$RC",
[(set F4RC:$RC, (fsqrt F4RC:$RB))], s_fsqrts>;
let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F4RC:$RA, F4RC:$RB) in {
let OutOperandList = (outs F4RC:$RC), InOperandList = (ins F4RC:$RA, F4RC:$RB) in {
def ADDS : FPForm<0x16, 0x580, "adds/su $RA,$RB,$RC",
[(set F4RC:$RC, (fadd F4RC:$RA, F4RC:$RB))], s_fadd>;
def SUBS : FPForm<0x16, 0x581, "subs/su $RA,$RB,$RC",
@ -634,11 +634,11 @@ def CPYSNS : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
//Doubles
let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
let OutOperandList = (outs F8RC:$RC), InOperandList = (ins F8RC:$RB), Fa = 31 in
def SQRTT : FPForm<0x14, 0x5AB, "sqrtt/su $RB,$RC",
[(set F8RC:$RC, (fsqrt F8RC:$RB))], s_fsqrtt>;
let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RA, F8RC:$RB) in {
let OutOperandList = (outs F8RC:$RC), InOperandList = (ins F8RC:$RA, F8RC:$RB) in {
def ADDT : FPForm<0x16, 0x5A0, "addt/su $RA,$RB,$RC",
[(set F8RC:$RC, (fadd F8RC:$RA, F8RC:$RB))], s_fadd>;
def SUBT : FPForm<0x16, 0x5A1, "subt/su $RA,$RB,$RC",
@ -665,13 +665,13 @@ def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", [], s_fadd>;
}
//More CPYS forms:
let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F4RC:$RA, F8RC:$RB) in {
let OutOperandList = (outs F8RC:$RC), InOperandList = (ins F4RC:$RA, F8RC:$RB) in {
def CPYSTs : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
[(set F8RC:$RC, (fcopysign F8RC:$RB, F4RC:$RA))], s_fadd>;
def CPYSNTs : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
[(set F8RC:$RC, (fneg (fcopysign F8RC:$RB, F4RC:$RA)))], s_fadd>;
}
let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RA, F4RC:$RB) in {
let OutOperandList = (outs F4RC:$RC), InOperandList = (ins F8RC:$RA, F4RC:$RB) in {
def CPYSSt : FPForm<0x17, 0x020, "cpys $RA,$RB,$RC",
[(set F4RC:$RC, (fcopysign F4RC:$RB, F8RC:$RA))], s_fadd>;
def CPYSESt : FPForm<0x17, 0x022, "cpyse $RA,$RB,$RC",[], s_fadd>; //Copy sign and exponent
@ -680,7 +680,7 @@ def CPYSNSt : FPForm<0x17, 0x021, "cpysn $RA,$RB,$RC",
}
//conditional moves, floats
let OutOperandList = (ops F4RC:$RDEST), InOperandList = (ops F4RC:$RFALSE, F4RC:$RTRUE, F8RC:$RCOND),
let OutOperandList = (outs F4RC:$RDEST), InOperandList = (ins F4RC:$RFALSE, F4RC:$RTRUE, F8RC:$RCOND),
isTwoAddress = 1 in {
def FCMOVEQS : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if = zero
def FCMOVGES : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if >= zero
@ -690,7 +690,7 @@ def FCMOVLTS : FPForm<0x17, 0x02C, "fcmovlt $RCOND,$RTRUE,$RDEST",[], s_fcmov>;
def FCMOVNES : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST",[], s_fcmov>; //FCMOVE if != zero
}
//conditional moves, doubles
let OutOperandList = (ops F8RC:$RDEST), InOperandList = (ops F8RC:$RFALSE, F8RC:$RTRUE, F8RC:$RCOND),
let OutOperandList = (outs F8RC:$RDEST), InOperandList = (ins F8RC:$RFALSE, F8RC:$RTRUE, F8RC:$RCOND),
isTwoAddress = 1 in {
def FCMOVEQT : FPForm<0x17, 0x02A, "fcmoveq $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
def FCMOVGET : FPForm<0x17, 0x02D, "fcmovge $RCOND,$RTRUE,$RDEST", [], s_fcmov>;
@ -790,33 +790,33 @@ def : Pat<(select (setule F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf),
let OutOperandList = (ops GPRC:$RC), InOperandList = (ops F4RC:$RA), Fb = 31 in
let OutOperandList = (outs GPRC:$RC), InOperandList = (ins F4RC:$RA), Fb = 31 in
def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",
[(set GPRC:$RC, (bitconvert F4RC:$RA))], s_ftoi>; //Floating to integer move, S_floating
let OutOperandList = (ops GPRC:$RC), InOperandList = (ops F8RC:$RA), Fb = 31 in
let OutOperandList = (outs GPRC:$RC), InOperandList = (ins F8RC:$RA), Fb = 31 in
def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC",
[(set GPRC:$RC, (bitconvert F8RC:$RA))], s_ftoi>; //Floating to integer move
let OutOperandList = (ops F4RC:$RC), InOperandList = (ops GPRC:$RA), Fb = 31 in
let OutOperandList = (outs F4RC:$RC), InOperandList = (ins GPRC:$RA), Fb = 31 in
def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",
[(set F4RC:$RC, (bitconvert GPRC:$RA))], s_itof>; //Integer to floating move, S_floating
let OutOperandList = (ops F8RC:$RC), InOperandList = (ops GPRC:$RA), Fb = 31 in
let OutOperandList = (outs F8RC:$RC), InOperandList = (ins GPRC:$RA), Fb = 31 in
def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC",
[(set F8RC:$RC, (bitconvert GPRC:$RA))], s_itof>; //Integer to floating move
let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
let OutOperandList = (outs F4RC:$RC), InOperandList = (ins F8RC:$RB), Fa = 31 in
def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC",
[(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))], s_fadd>;
let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
let OutOperandList = (outs F8RC:$RC), InOperandList = (ins F8RC:$RB), Fa = 31 in
def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC",
[(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))], s_fadd>;
let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
let OutOperandList = (outs F8RC:$RC), InOperandList = (ins F8RC:$RB), Fa = 31 in
def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC",
[(set F8RC:$RC, (Alpha_cvttq F8RC:$RB))], s_fadd>;
let OutOperandList = (ops F8RC:$RC), InOperandList = (ops F4RC:$RB), Fa = 31 in
let OutOperandList = (outs F8RC:$RC), InOperandList = (ins F4RC:$RB), Fa = 31 in
def CVTST : FPForm<0x16, 0x6AC, "cvtst/s $RB,$RC",
[(set F8RC:$RC, (fextend F4RC:$RB))], s_fadd>;
let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in
let OutOperandList = (outs F4RC:$RC), InOperandList = (ins F8RC:$RB), Fa = 31 in
def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC",
[(set F4RC:$RC, (fround F8RC:$RB))], s_fadd>;
@ -829,20 +829,20 @@ def : Pat<(select GPRC:$RC, F4RC:$st, F4RC:$sf),
//Branching
/////////////////////////////////////////////////////////
class br_icc<bits<6> opc, string asmstr>
: BFormN<opc, (ops u64imm:$opc, GPRC:$R, target:$dst),
: BFormN<opc, (ins u64imm:$opc, GPRC:$R, target:$dst),
!strconcat(asmstr, " $R,$dst"), s_icbr>;
class br_fcc<bits<6> opc, string asmstr>
: BFormN<opc, (ops u64imm:$opc, F8RC:$R, target:$dst),
: BFormN<opc, (ins u64imm:$opc, F8RC:$R, target:$dst),
!strconcat(asmstr, " $R,$dst"), s_fbr>;
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
let Ra = 31 in
def BR : BFormD<0x30, "br $$31,$DISP", [(br bb:$DISP)], s_ubr>;
def COND_BRANCH_I : BFormN<0, (ops u64imm:$opc, GPRC:$R, target:$dst),
def COND_BRANCH_I : BFormN<0, (ins u64imm:$opc, GPRC:$R, target:$dst),
"{:comment} COND_BRANCH imm:$opc, GPRC:$R, bb:$dst",
s_icbr>;
def COND_BRANCH_F : BFormN<0, (ops u64imm:$opc, F8RC:$R, target:$dst),
def COND_BRANCH_F : BFormN<0, (ins u64imm:$opc, F8RC:$R, target:$dst),
"{:comment} COND_BRANCH imm:$opc, F8RC:$R, bb:$dst",
s_fbr>;
//Branches, int

View File

@ -29,7 +29,8 @@ def BfinCallseqEnd : SDNode<"ISD::CALLSEQ_END", SDT_BfinCallSeqEnd,
def SDT_BfinCall : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
def BfinCall : SDNode<"BFISD::CALL", SDT_BfinCall,
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
SDNPVariadic]>;
def BfinRet: SDNode<"BFISD::RET_FLAG", SDTNone,
[SDNPHasChain, SDNPOptInFlag]>;
@ -610,7 +611,7 @@ def MOVE_ncccc : F1<(outs NotCC:$cc), (ins JustCC:$sb),
def MOVECC_zext : F1<(outs D:$dst), (ins JustCC:$cc),
"$dst = $cc;",
[(set D:$dst, (zext JustCC:$cc))]>;
[/*(set D:$dst, (zext JustCC:$cc))*/]>;
def MOVENCC_z : F1<(outs D:$dst), (ins NotCC:$cc),
"$dst = cc;", []>;
@ -859,10 +860,10 @@ def : Pat<(BfinCall (i32 tglobaladdr:$dst)),
def : Pat<(BfinCall (i32 texternalsym:$dst)),
(CALLa texternalsym:$dst)>;
def : Pat<(sext JustCC:$cc),
(NEG (MOVECC_zext JustCC:$cc))>;
def : Pat<(anyext JustCC:$cc),
(MOVECC_zext JustCC:$cc)>;
//def : Pat<(sext JustCC:$cc),
// (NEG (MOVECC_zext JustCC:$cc))>;
//def : Pat<(anyext JustCC:$cc),
// (MOVECC_zext JustCC:$cc)>;
def : Pat<(i16 (zext JustCC:$cc)),
(EXTRACT_SUBREG (MOVECC_zext JustCC:$cc), bfin_subreg_lo16)>;
def : Pat<(i16 (sext JustCC:$cc)),

View File

@ -53,6 +53,10 @@ std::string BlackfinIntrinsicInfo::getName(unsigned IntrID, const Type **Tys,
unsigned
BlackfinIntrinsicInfo::lookupName(const char *Name, unsigned Len) const {
if (Len < 5 || Name[4] != '.' || Name[0] != 'l' || Name[1] != 'l'
|| Name[2] != 'v' || Name[3] != 'm')
return 0; // All intrinsics start with 'llvm.'
#define GET_FUNCTION_RECOGNIZER
#include "BlackfinGenIntrinsics.inc"
#undef GET_FUNCTION_RECOGNIZER

View File

@ -111,7 +111,8 @@ namespace {
static char ID;
explicit CWriter(formatted_raw_ostream &o)
: FunctionPass(&ID), Out(o), IL(0), Mang(0), LI(0),
TheModule(0), TAsm(0), TD(0), OpaqueCounter(0), NextAnonValueNumber(0) {
TheModule(0), TAsm(0), TCtx(0), TD(0), OpaqueCounter(0),
NextAnonValueNumber(0) {
FPCounter = 0;
}
@ -147,6 +148,8 @@ namespace {
delete IL;
delete TD;
delete Mang;
delete TCtx;
delete TAsm;
FPConstantMap.clear();
TypeNames.clear();
ByValParams.clear();

View File

@ -1133,16 +1133,14 @@ class XSBHInst<dag OOL, dag IOL, list<dag> pattern>:
"xsbh\t$rDst, $rSrc",
IntegerOp, pattern>;
class XSBHVecInst<ValueType vectype>:
XSBHInst<(outs VECREG:$rDst), (ins VECREG:$rSrc),
[(set (v8i16 VECREG:$rDst), (sext (vectype VECREG:$rSrc)))]>;
class XSBHInRegInst<RegisterClass rclass, list<dag> pattern>:
XSBHInst<(outs rclass:$rDst), (ins rclass:$rSrc),
pattern>;
multiclass ExtendByteHalfword {
def v16i8: XSBHVecInst<v8i16>;
def v16i8: XSBHInst<(outs VECREG:$rDst), (ins VECREG:$rSrc),
[
/*(set (v8i16 VECREG:$rDst), (sext (v8i16 VECREG:$rSrc)))*/]>;
def r8: XSBHInst<(outs R16C:$rDst), (ins R8C:$rSrc),
[(set R16C:$rDst, (sext R8C:$rSrc))]>;
def r16: XSBHInRegInst<R16C,
@ -1200,8 +1198,8 @@ class XSWDInst<dag OOL, dag IOL, list<dag> pattern>:
class XSWDVecInst<ValueType in_vectype, ValueType out_vectype>:
XSWDInst<(outs VECREG:$rDst), (ins VECREG:$rSrc),
[(set (out_vectype VECREG:$rDst),
(sext (out_vectype VECREG:$rSrc)))]>;
[/*(set (out_vectype VECREG:$rDst),
(sext (out_vectype VECREG:$rSrc)))*/]>;
class XSWDRegInst<RegisterClass in_rclass, RegisterClass out_rclass>:
XSWDInst<(outs out_rclass:$rDst), (ins in_rclass:$rSrc),
@ -4146,7 +4144,7 @@ def CFSif32 :
def FESDvec :
RRForm_1<0b00011101110, (outs VECREG:$rT), (ins VECREG:$rA),
"fesd\t$rT, $rA", SPrecFP,
[(set (v2f64 VECREG:$rT), (fextend (v4f32 VECREG:$rA)))]>;
[/*(set (v2f64 VECREG:$rT), (fextend (v4f32 VECREG:$rA)))*/]>;
def FESDf32 :
RRForm_1<0b00011101110, (outs R64FP:$rT), (ins R32FP:$rA),

View File

@ -28,7 +28,8 @@ def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPUCallSeq,
def SDT_SPUCall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
def SPUcall : SDNode<"SPUISD::CALL", SDT_SPUCall,
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
SDNPVariadic]>;
// Operand type constraints for vector shuffle/permute operations
def SDT_SPUshuffle : SDTypeProfile<1, 3, [

View File

@ -57,6 +57,10 @@ std::string MBlazeIntrinsicInfo::getName(unsigned IntrID, const Type **Tys,
unsigned MBlazeIntrinsicInfo::
lookupName(const char *Name, unsigned Len) const {
if (Len < 5 || Name[4] != '.' || Name[0] != 'l' || Name[1] != 'l'
|| Name[2] != 'v' || Name[3] != 'm')
return 0; // All intrinsics start with 'llvm.'
#define GET_FUNCTION_RECOGNIZER
#include "MBlazeGenIntrinsics.inc"
#undef GET_FUNCTION_RECOGNIZER

View File

@ -29,7 +29,8 @@ def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
// Call
def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
[SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
[SDNPHasChain, SDNPOutFlag, SDNPOptInFlag,
SDNPVariadic]>;
// Hi and Lo nodes are used to handle global addresses. Used on
// MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol

View File

@ -184,7 +184,7 @@ void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
// by any chance, as we do not link in those as .bc lib. So these calls
// are always external and it is safe to emit an extern.
if (PAN::isMemIntrinsic(Sym->getName()))
LibcallDecls.push_back(createESName(Sym->getName()));
LibcallDecls.insert(Sym->getName());
O << *Sym;
break;
@ -199,7 +199,7 @@ void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
Printname = PAN::Rename(Sname);
}
// Record these decls, we need to print them in asm as extern.
LibcallDecls.push_back(createESName(Printname));
LibcallDecls.insert(Printname);
}
O << Printname;
@ -221,18 +221,6 @@ void PIC16AsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
O << PIC16CondCodeToString((PIC16CC::CondCodes)CC);
}
// This function is used to sort the decls list.
// should return true if s1 should come before s2.
static bool is_before(const char *s1, const char *s2) {
return strcmp(s1, s2) <= 0;
}
// This is used by list::unique below.
// unique will filter out duplicates if it knows them.
static bool is_duplicate(const char *s1, const char *s2) {
return !strcmp(s1, s2);
}
/// printLibcallDecls - print the extern declarations for compiler
/// intrinsics.
///
@ -241,12 +229,9 @@ void PIC16AsmPrinter::printLibcallDecls() {
if (LibcallDecls.empty()) return;
O << MAI->getCommentString() << "External decls for libcalls - BEGIN." <<"\n";
// Remove duplicate entries.
LibcallDecls.sort(is_before);
LibcallDecls.unique(is_duplicate);
for (std::list<const char*>::const_iterator I = LibcallDecls.begin();
I != LibcallDecls.end(); I++) {
for (std::set<std::string>::const_iterator I = LibcallDecls.begin(),
E = LibcallDecls.end(); I != E; I++) {
O << MAI->getExternDirective() << *I << "\n";
}
O << MAI->getCommentString() << "External decls for libcalls - END." <<"\n";

View File

@ -25,6 +25,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetMachine.h"
#include <list>
#include <set>
#include <string>
namespace llvm {
@ -80,7 +81,7 @@ namespace llvm {
PIC16TargetLowering *PTLI;
PIC16DbgInfo DbgInfo;
const PIC16MCAsmInfo *PMAI;
std::list<const char *> LibcallDecls; // List of extern decls.
std::set<std::string> LibcallDecls; // Sorted & uniqued set of extern decls.
std::vector<const GlobalVariable *> ExternalVarDecls;
std::vector<const GlobalVariable *> ExternalVarDefs;
};

View File

@ -45,7 +45,7 @@ namespace llvm {
PIC16Section(const StringRef &name, SectionKind K, const std::string &addr,
int color)
: MCSection(K), Name(name), Address(addr), Color(color) {
: MCSection(K), Name(name), Address(addr), Color(color), Size(0) {
}
public:

View File

@ -111,9 +111,11 @@ def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_PPCCallSeqEnd,
def SDT_PPCCall : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
def PPCcall_Darwin : SDNode<"PPCISD::CALL_Darwin", SDT_PPCCall,
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
SDNPVariadic]>;
def PPCcall_SVR4 : SDNode<"PPCISD::CALL_SVR4", SDT_PPCCall,
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
SDNPVariadic]>;
def PPCnop : SDNode<"PPCISD::NOP", SDT_PPCnop, [SDNPInFlag, SDNPOutFlag]>;
def PPCload : SDNode<"PPCISD::LOAD", SDTypeProfile<1, 1, []>,
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
@ -124,16 +126,18 @@ def PPCtoc_restore : SDNode<"PPCISD::TOC_RESTORE", SDTypeProfile<0, 0, []>,
def PPCmtctr : SDNode<"PPCISD::MTCTR", SDT_PPCCall,
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
def PPCbctrl_Darwin : SDNode<"PPCISD::BCTRL_Darwin", SDTNone,
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
SDNPVariadic]>;
def PPCbctrl_SVR4 : SDNode<"PPCISD::BCTRL_SVR4", SDTNone,
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag,
SDNPVariadic]>;
def retflag : SDNode<"PPCISD::RET_FLAG", SDTNone,
[SDNPHasChain, SDNPOptInFlag]>;
[SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>;
def PPCtc_return : SDNode<"PPCISD::TC_RETURN", SDT_PPCTC_ret,
[SDNPHasChain, SDNPOptInFlag]>;
[SDNPHasChain, SDNPOptInFlag, SDNPVariadic]>;
def PPCvcmp : SDNode<"PPCISD::VCMP" , SDT_PPCvcmp, []>;
def PPCvcmp_o : SDNode<"PPCISD::VCMPo", SDT_PPCvcmp, [SDNPOutFlag]>;

View File

@ -20,7 +20,7 @@
#include "llvm/Support/FormattedStream.h"
using namespace llvm;
static const MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) {
static MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) {
Triple TheTriple(TT);
bool isPPC64 = TheTriple.getArch() == Triple::ppc64;
if (TheTriple.getOS() == Triple::Darwin)

Some files were not shown because too many files have changed in this diff Show More