Vendor import of llvm 3.0 final release:
http://llvm.org/svn/llvm-project/llvm/tags/RELEASE_30/final@145349
This commit is contained in:
parent
30815c536b
commit
d4c8b5d2e8
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>LLVM Alias Analysis Infrastructure</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
@ -1060,7 +1061,7 @@ analysis directly.</p>
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2011-05-25 00:01:32 +0200 (Wed, 25 May 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:23 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>LLVM Branch Weight Metadata</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>LLVM bugpoint tool: design and usage</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
@ -231,7 +232,7 @@ non-obvious ways. Here are some hints and tips:<p>
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2011-08-30 20:26:11 +0200 (Tue, 30 Aug 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:23 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Building LLVM with CMake</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
|
@ -1813,6 +1813,8 @@ $ llc -regalloc=pbqp file.bc -o pbqp.s;
|
||||
<a name="proepicode">Prolog/Epilog Code Insertion</a>
|
||||
</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<h4>
|
||||
<a name="compact_unwind">Compact Unwind</a>
|
||||
@ -1927,6 +1929,8 @@ $ llc -regalloc=pbqp file.bc -o pbqp.s;
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3>
|
||||
<a name="latemco">Late Machine Code Optimizations</a>
|
||||
@ -2988,7 +2992,7 @@ MOVSX32rm16 -> movsx, 32-bit register, 16-bit memory
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2011-09-19 20:15:46 +0200 (Mon, 19 Sep 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:54 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
<title>LLVM Coding Standards</title>
|
||||
</head>
|
||||
@ -1526,7 +1527,7 @@ something.</p>
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2011-08-12 21:49:16 +0200 (Fri, 12 Aug 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:23 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Debugging JITed Code With GDB</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
@ -146,7 +147,7 @@ coordinate with GDB to get better debug information.
|
||||
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
|
||||
<a href="mailto:reid.kleckner@gmail.com">Reid Kleckner</a><br>
|
||||
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:23 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Extending LLVM: Adding instructions, intrinsics, types, etc.</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
@ -384,7 +385,7 @@ void calcTypeName(const Type *Ty,
|
||||
|
||||
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a>
|
||||
<br>
|
||||
Last modified: $Date: 2011-06-30 08:37:07 +0200 (Thu, 30 Jun 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:23 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -746,8 +746,8 @@ idx3 = (char*) &MyVar + 8
|
||||
src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS"></a>
|
||||
<a href="http://validator.w3.org/check/referer"><img
|
||||
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
|
||||
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br/>
|
||||
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
|
||||
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2011-11-03 07:43:54 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>LLVM gold plugin</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>How To Release LLVM To The Public</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
@ -574,7 +575,7 @@ $ svn copy https://llvm.org/svn/llvm-project/test-suite/branches/release_XY \
|
||||
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
|
||||
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a>
|
||||
<br>
|
||||
Last modified: $Date: 2011-10-17 22:32:14 +0200 (Mon, 17 Oct 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:23 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>How to submit an LLVM bug report</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
@ -340,7 +341,7 @@ the following:</p>
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a>
|
||||
<br>
|
||||
Last modified: $Date: 2011-06-07 22:03:13 +0200 (Tue, 07 Jun 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:23 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -281,23 +281,6 @@
|
||||
<li><a href="#int_at">'<tt>llvm.adjust.trampoline</tt>' Intrinsic</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#int_atomics">Atomic intrinsics</a>
|
||||
<ol>
|
||||
<li><a href="#int_memory_barrier"><tt>llvm.memory_barrier</tt></a></li>
|
||||
<li><a href="#int_atomic_cmp_swap"><tt>llvm.atomic.cmp.swap</tt></a></li>
|
||||
<li><a href="#int_atomic_swap"><tt>llvm.atomic.swap</tt></a></li>
|
||||
<li><a href="#int_atomic_load_add"><tt>llvm.atomic.load.add</tt></a></li>
|
||||
<li><a href="#int_atomic_load_sub"><tt>llvm.atomic.load.sub</tt></a></li>
|
||||
<li><a href="#int_atomic_load_and"><tt>llvm.atomic.load.and</tt></a></li>
|
||||
<li><a href="#int_atomic_load_nand"><tt>llvm.atomic.load.nand</tt></a></li>
|
||||
<li><a href="#int_atomic_load_or"><tt>llvm.atomic.load.or</tt></a></li>
|
||||
<li><a href="#int_atomic_load_xor"><tt>llvm.atomic.load.xor</tt></a></li>
|
||||
<li><a href="#int_atomic_load_max"><tt>llvm.atomic.load.max</tt></a></li>
|
||||
<li><a href="#int_atomic_load_min"><tt>llvm.atomic.load.min</tt></a></li>
|
||||
<li><a href="#int_atomic_load_umax"><tt>llvm.atomic.load.umax</tt></a></li>
|
||||
<li><a href="#int_atomic_load_umin"><tt>llvm.atomic.load.umin</tt></a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#int_memorymarkers">Memory Use Markers</a>
|
||||
<ol>
|
||||
<li><a href="#int_lifetime_start"><tt>llvm.lifetime.start</tt></a></li>
|
||||
@ -1915,9 +1898,6 @@ in signal handlers).</p>
|
||||
possible to have a two dimensional array, using an array as the element type
|
||||
of another array.</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<h4>
|
||||
<a name="t_aggregate">Aggregate Types</a>
|
||||
@ -2225,6 +2205,8 @@ in signal handlers).</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<h2><a name="constants">Constants</a></h2>
|
||||
<!-- *********************************************************************** -->
|
||||
@ -6321,8 +6303,6 @@ declare void @llvm.va_end(i8*)
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3>
|
||||
<a name="int_gc">Accurate Garbage Collection Intrinsics</a>
|
||||
@ -7018,8 +6998,6 @@ LLVM</a>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<h4>
|
||||
<a name="int_exp">'<tt>llvm.exp.*</tt>' Intrinsic</a>
|
||||
@ -7084,6 +7062,9 @@ LLVM</a>.</p>
|
||||
<p>This function returns the same values as the libm <tt>log</tt> functions
|
||||
would, and handles error conditions in the same way.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<h4>
|
||||
<a name="int_fma">'<tt>llvm.fma.*</tt>' Intrinsic</a>
|
||||
</h4>
|
||||
@ -7117,6 +7098,8 @@ LLVM</a>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3>
|
||||
<a name="int_manip">Bit Manipulation Intrinsics</a>
|
||||
@ -7810,503 +7793,6 @@ LLVM</a>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3>
|
||||
<a name="int_atomics">Atomic Operations and Synchronization Intrinsics</a>
|
||||
</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p>These intrinsic functions expand the "universal IR" of LLVM to represent
|
||||
hardware constructs for atomic operations and memory synchronization. This
|
||||
provides an interface to the hardware, not an interface to the programmer. It
|
||||
is aimed at a low enough level to allow any programming models or APIs
|
||||
(Application Programming Interfaces) which need atomic behaviors to map
|
||||
cleanly onto it. It is also modeled primarily on hardware behavior. Just as
|
||||
hardware provides a "universal IR" for source languages, it also provides a
|
||||
starting point for developing a "universal" atomic operation and
|
||||
synchronization IR.</p>
|
||||
|
||||
<p>These do <em>not</em> form an API such as high-level threading libraries,
|
||||
software transaction memory systems, atomic primitives, and intrinsic
|
||||
functions as found in BSD, GNU libc, atomic_ops, APR, and other system and
|
||||
application libraries. The hardware interface provided by LLVM should allow
|
||||
a clean implementation of all of these APIs and parallel programming models.
|
||||
No one model or paradigm should be selected above others unless the hardware
|
||||
itself ubiquitously does so.</p>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<h4>
|
||||
<a name="int_memory_barrier">'<tt>llvm.memory.barrier</tt>' Intrinsic</a>
|
||||
</h4>
|
||||
|
||||
<div>
|
||||
<h5>Syntax:</h5>
|
||||
<pre>
|
||||
declare void @llvm.memory.barrier(i1 <ll>, i1 <ls>, i1 <sl>, i1 <ss>, i1 <device>)
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>The <tt>llvm.memory.barrier</tt> intrinsic guarantees ordering between
|
||||
specific pairs of memory access types.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The <tt>llvm.memory.barrier</tt> intrinsic requires five boolean arguments.
|
||||
The first four arguments enables a specific barrier as listed below. The
|
||||
fifth argument specifies that the barrier applies to io or device or uncached
|
||||
memory.</p>
|
||||
|
||||
<ul>
|
||||
<li><tt>ll</tt>: load-load barrier</li>
|
||||
<li><tt>ls</tt>: load-store barrier</li>
|
||||
<li><tt>sl</tt>: store-load barrier</li>
|
||||
<li><tt>ss</tt>: store-store barrier</li>
|
||||
<li><tt>device</tt>: barrier applies to device and uncached memory also.</li>
|
||||
</ul>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>This intrinsic causes the system to enforce some ordering constraints upon
|
||||
the loads and stores of the program. This barrier does not
|
||||
indicate <em>when</em> any events will occur, it only enforces
|
||||
an <em>order</em> in which they occur. For any of the specified pairs of load
|
||||
and store operations (f.ex. load-load, or store-load), all of the first
|
||||
operations preceding the barrier will complete before any of the second
|
||||
operations succeeding the barrier begin. Specifically the semantics for each
|
||||
pairing is as follows:</p>
|
||||
|
||||
<ul>
|
||||
<li><tt>ll</tt>: All loads before the barrier must complete before any load
|
||||
after the barrier begins.</li>
|
||||
<li><tt>ls</tt>: All loads before the barrier must complete before any
|
||||
store after the barrier begins.</li>
|
||||
<li><tt>ss</tt>: All stores before the barrier must complete before any
|
||||
store after the barrier begins.</li>
|
||||
<li><tt>sl</tt>: All stores before the barrier must complete before any
|
||||
load after the barrier begins.</li>
|
||||
</ul>
|
||||
|
||||
<p>These semantics are applied with a logical "and" behavior when more than one
|
||||
is enabled in a single memory barrier intrinsic.</p>
|
||||
|
||||
<p>Backends may implement stronger barriers than those requested when they do
|
||||
not support as fine grained a barrier as requested. Some architectures do
|
||||
not need all types of barriers and on such architectures, these become
|
||||
noops.</p>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
%mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
|
||||
%ptr = bitcast i8* %mallocP to i32*
|
||||
store i32 4, %ptr
|
||||
|
||||
%result1 = load i32* %ptr <i>; yields {i32}:result1 = 4</i>
|
||||
call void @llvm.memory.barrier(i1 false, i1 true, i1 false, i1 false, i1 true)
|
||||
<i>; guarantee the above finishes</i>
|
||||
store i32 8, %ptr <i>; before this begins</i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<h4>
|
||||
<a name="int_atomic_cmp_swap">'<tt>llvm.atomic.cmp.swap.*</tt>' Intrinsic</a>
|
||||
</h4>
|
||||
|
||||
<div>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<p>This is an overloaded intrinsic. You can use <tt>llvm.atomic.cmp.swap</tt> on
|
||||
any integer bit width and for different address spaces. Not all targets
|
||||
support all bit widths however.</p>
|
||||
|
||||
<pre>
|
||||
declare i8 @llvm.atomic.cmp.swap.i8.p0i8(i8* <ptr>, i8 <cmp>, i8 <val>)
|
||||
declare i16 @llvm.atomic.cmp.swap.i16.p0i16(i16* <ptr>, i16 <cmp>, i16 <val>)
|
||||
declare i32 @llvm.atomic.cmp.swap.i32.p0i32(i32* <ptr>, i32 <cmp>, i32 <val>)
|
||||
declare i64 @llvm.atomic.cmp.swap.i64.p0i64(i64* <ptr>, i64 <cmp>, i64 <val>)
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>This loads a value in memory and compares it to a given value. If they are
|
||||
equal, it stores a new value into the memory.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The <tt>llvm.atomic.cmp.swap</tt> intrinsic takes three arguments. The result
|
||||
as well as both <tt>cmp</tt> and <tt>val</tt> must be integer values with the
|
||||
same bit width. The <tt>ptr</tt> argument must be a pointer to a value of
|
||||
this integer type. While any bit width integer may be used, targets may only
|
||||
lower representations they support in hardware.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>This entire intrinsic must be executed atomically. It first loads the value
|
||||
in memory pointed to by <tt>ptr</tt> and compares it with the
|
||||
value <tt>cmp</tt>. If they are equal, <tt>val</tt> is stored into the
|
||||
memory. The loaded value is yielded in all cases. This provides the
|
||||
equivalent of an atomic compare-and-swap operation within the SSA
|
||||
framework.</p>
|
||||
|
||||
<h5>Examples:</h5>
|
||||
<pre>
|
||||
%mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
|
||||
%ptr = bitcast i8* %mallocP to i32*
|
||||
store i32 4, %ptr
|
||||
|
||||
%val1 = add i32 4, 4
|
||||
%result1 = call i32 @llvm.atomic.cmp.swap.i32.p0i32(i32* %ptr, i32 4, %val1)
|
||||
<i>; yields {i32}:result1 = 4</i>
|
||||
%stored1 = icmp eq i32 %result1, 4 <i>; yields {i1}:stored1 = true</i>
|
||||
%memval1 = load i32* %ptr <i>; yields {i32}:memval1 = 8</i>
|
||||
|
||||
%val2 = add i32 1, 1
|
||||
%result2 = call i32 @llvm.atomic.cmp.swap.i32.p0i32(i32* %ptr, i32 5, %val2)
|
||||
<i>; yields {i32}:result2 = 8</i>
|
||||
%stored2 = icmp eq i32 %result2, 5 <i>; yields {i1}:stored2 = false</i>
|
||||
|
||||
%memval2 = load i32* %ptr <i>; yields {i32}:memval2 = 8</i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<h4>
|
||||
<a name="int_atomic_swap">'<tt>llvm.atomic.swap.*</tt>' Intrinsic</a>
|
||||
</h4>
|
||||
|
||||
<div>
|
||||
<h5>Syntax:</h5>
|
||||
|
||||
<p>This is an overloaded intrinsic. You can use <tt>llvm.atomic.swap</tt> on any
|
||||
integer bit width. Not all targets support all bit widths however.</p>
|
||||
|
||||
<pre>
|
||||
declare i8 @llvm.atomic.swap.i8.p0i8(i8* <ptr>, i8 <val>)
|
||||
declare i16 @llvm.atomic.swap.i16.p0i16(i16* <ptr>, i16 <val>)
|
||||
declare i32 @llvm.atomic.swap.i32.p0i32(i32* <ptr>, i32 <val>)
|
||||
declare i64 @llvm.atomic.swap.i64.p0i64(i64* <ptr>, i64 <val>)
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>This intrinsic loads the value stored in memory at <tt>ptr</tt> and yields
|
||||
the value from memory. It then stores the value in <tt>val</tt> in the memory
|
||||
at <tt>ptr</tt>.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The <tt>llvm.atomic.swap</tt> intrinsic takes two arguments. Both
|
||||
the <tt>val</tt> argument and the result must be integers of the same bit
|
||||
width. The first argument, <tt>ptr</tt>, must be a pointer to a value of this
|
||||
integer type. The targets may only lower integer representations they
|
||||
support.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>This intrinsic loads the value pointed to by <tt>ptr</tt>, yields it, and
|
||||
stores <tt>val</tt> back into <tt>ptr</tt> atomically. This provides the
|
||||
equivalent of an atomic swap operation within the SSA framework.</p>
|
||||
|
||||
<h5>Examples:</h5>
|
||||
<pre>
|
||||
%mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
|
||||
%ptr = bitcast i8* %mallocP to i32*
|
||||
store i32 4, %ptr
|
||||
|
||||
%val1 = add i32 4, 4
|
||||
%result1 = call i32 @llvm.atomic.swap.i32.p0i32(i32* %ptr, i32 %val1)
|
||||
<i>; yields {i32}:result1 = 4</i>
|
||||
%stored1 = icmp eq i32 %result1, 4 <i>; yields {i1}:stored1 = true</i>
|
||||
%memval1 = load i32* %ptr <i>; yields {i32}:memval1 = 8</i>
|
||||
|
||||
%val2 = add i32 1, 1
|
||||
%result2 = call i32 @llvm.atomic.swap.i32.p0i32(i32* %ptr, i32 %val2)
|
||||
<i>; yields {i32}:result2 = 8</i>
|
||||
|
||||
%stored2 = icmp eq i32 %result2, 8 <i>; yields {i1}:stored2 = true</i>
|
||||
%memval2 = load i32* %ptr <i>; yields {i32}:memval2 = 2</i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<h4>
|
||||
<a name="int_atomic_load_add">'<tt>llvm.atomic.load.add.*</tt>' Intrinsic</a>
|
||||
</h4>
|
||||
|
||||
<div>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<p>This is an overloaded intrinsic. You can use <tt>llvm.atomic.load.add</tt> on
|
||||
any integer bit width. Not all targets support all bit widths however.</p>
|
||||
|
||||
<pre>
|
||||
declare i8 @llvm.atomic.load.add.i8.p0i8(i8* <ptr>, i8 <delta>)
|
||||
declare i16 @llvm.atomic.load.add.i16.p0i16(i16* <ptr>, i16 <delta>)
|
||||
declare i32 @llvm.atomic.load.add.i32.p0i32(i32* <ptr>, i32 <delta>)
|
||||
declare i64 @llvm.atomic.load.add.i64.p0i64(i64* <ptr>, i64 <delta>)
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>This intrinsic adds <tt>delta</tt> to the value stored in memory
|
||||
at <tt>ptr</tt>. It yields the original value at <tt>ptr</tt>.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The intrinsic takes two arguments, the first a pointer to an integer value
|
||||
and the second an integer value. The result is also an integer value. These
|
||||
integer types can have any bit width, but they must all have the same bit
|
||||
width. The targets may only lower integer representations they support.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>This intrinsic does a series of operations atomically. It first loads the
|
||||
value stored at <tt>ptr</tt>. It then adds <tt>delta</tt>, stores the result
|
||||
to <tt>ptr</tt>. It yields the original value stored at <tt>ptr</tt>.</p>
|
||||
|
||||
<h5>Examples:</h5>
|
||||
<pre>
|
||||
%mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
|
||||
%ptr = bitcast i8* %mallocP to i32*
|
||||
store i32 4, %ptr
|
||||
%result1 = call i32 @llvm.atomic.load.add.i32.p0i32(i32* %ptr, i32 4)
|
||||
<i>; yields {i32}:result1 = 4</i>
|
||||
%result2 = call i32 @llvm.atomic.load.add.i32.p0i32(i32* %ptr, i32 2)
|
||||
<i>; yields {i32}:result2 = 8</i>
|
||||
%result3 = call i32 @llvm.atomic.load.add.i32.p0i32(i32* %ptr, i32 5)
|
||||
<i>; yields {i32}:result3 = 10</i>
|
||||
%memval1 = load i32* %ptr <i>; yields {i32}:memval1 = 15</i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<h4>
|
||||
<a name="int_atomic_load_sub">'<tt>llvm.atomic.load.sub.*</tt>' Intrinsic</a>
|
||||
</h4>
|
||||
|
||||
<div>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<p>This is an overloaded intrinsic. You can use <tt>llvm.atomic.load.sub</tt> on
|
||||
any integer bit width and for different address spaces. Not all targets
|
||||
support all bit widths however.</p>
|
||||
|
||||
<pre>
|
||||
declare i8 @llvm.atomic.load.sub.i8.p0i32(i8* <ptr>, i8 <delta>)
|
||||
declare i16 @llvm.atomic.load.sub.i16.p0i32(i16* <ptr>, i16 <delta>)
|
||||
declare i32 @llvm.atomic.load.sub.i32.p0i32(i32* <ptr>, i32 <delta>)
|
||||
declare i64 @llvm.atomic.load.sub.i64.p0i32(i64* <ptr>, i64 <delta>)
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>This intrinsic subtracts <tt>delta</tt> to the value stored in memory at
|
||||
<tt>ptr</tt>. It yields the original value at <tt>ptr</tt>.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The intrinsic takes two arguments, the first a pointer to an integer value
|
||||
and the second an integer value. The result is also an integer value. These
|
||||
integer types can have any bit width, but they must all have the same bit
|
||||
width. The targets may only lower integer representations they support.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>This intrinsic does a series of operations atomically. It first loads the
|
||||
value stored at <tt>ptr</tt>. It then subtracts <tt>delta</tt>, stores the
|
||||
result to <tt>ptr</tt>. It yields the original value stored
|
||||
at <tt>ptr</tt>.</p>
|
||||
|
||||
<h5>Examples:</h5>
|
||||
<pre>
|
||||
%mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
|
||||
%ptr = bitcast i8* %mallocP to i32*
|
||||
store i32 8, %ptr
|
||||
%result1 = call i32 @llvm.atomic.load.sub.i32.p0i32(i32* %ptr, i32 4)
|
||||
<i>; yields {i32}:result1 = 8</i>
|
||||
%result2 = call i32 @llvm.atomic.load.sub.i32.p0i32(i32* %ptr, i32 2)
|
||||
<i>; yields {i32}:result2 = 4</i>
|
||||
%result3 = call i32 @llvm.atomic.load.sub.i32.p0i32(i32* %ptr, i32 5)
|
||||
<i>; yields {i32}:result3 = 2</i>
|
||||
%memval1 = load i32* %ptr <i>; yields {i32}:memval1 = -3</i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<h4>
|
||||
<a name="int_atomic_load_and">
|
||||
'<tt>llvm.atomic.load.and.*</tt>' Intrinsic
|
||||
</a>
|
||||
<br>
|
||||
<a name="int_atomic_load_nand">
|
||||
'<tt>llvm.atomic.load.nand.*</tt>' Intrinsic
|
||||
</a>
|
||||
<br>
|
||||
<a name="int_atomic_load_or">
|
||||
'<tt>llvm.atomic.load.or.*</tt>' Intrinsic
|
||||
</a>
|
||||
<br>
|
||||
<a name="int_atomic_load_xor">
|
||||
'<tt>llvm.atomic.load.xor.*</tt>' Intrinsic
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
<div>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<p>These are overloaded intrinsics. You can
|
||||
use <tt>llvm.atomic.load_and</tt>, <tt>llvm.atomic.load_nand</tt>,
|
||||
<tt>llvm.atomic.load_or</tt>, and <tt>llvm.atomic.load_xor</tt> on any integer
|
||||
bit width and for different address spaces. Not all targets support all bit
|
||||
widths however.</p>
|
||||
|
||||
<pre>
|
||||
declare i8 @llvm.atomic.load.and.i8.p0i8(i8* <ptr>, i8 <delta>)
|
||||
declare i16 @llvm.atomic.load.and.i16.p0i16(i16* <ptr>, i16 <delta>)
|
||||
declare i32 @llvm.atomic.load.and.i32.p0i32(i32* <ptr>, i32 <delta>)
|
||||
declare i64 @llvm.atomic.load.and.i64.p0i64(i64* <ptr>, i64 <delta>)
|
||||
</pre>
|
||||
|
||||
<pre>
|
||||
declare i8 @llvm.atomic.load.or.i8.p0i8(i8* <ptr>, i8 <delta>)
|
||||
declare i16 @llvm.atomic.load.or.i16.p0i16(i16* <ptr>, i16 <delta>)
|
||||
declare i32 @llvm.atomic.load.or.i32.p0i32(i32* <ptr>, i32 <delta>)
|
||||
declare i64 @llvm.atomic.load.or.i64.p0i64(i64* <ptr>, i64 <delta>)
|
||||
</pre>
|
||||
|
||||
<pre>
|
||||
declare i8 @llvm.atomic.load.nand.i8.p0i32(i8* <ptr>, i8 <delta>)
|
||||
declare i16 @llvm.atomic.load.nand.i16.p0i32(i16* <ptr>, i16 <delta>)
|
||||
declare i32 @llvm.atomic.load.nand.i32.p0i32(i32* <ptr>, i32 <delta>)
|
||||
declare i64 @llvm.atomic.load.nand.i64.p0i32(i64* <ptr>, i64 <delta>)
|
||||
</pre>
|
||||
|
||||
<pre>
|
||||
declare i8 @llvm.atomic.load.xor.i8.p0i32(i8* <ptr>, i8 <delta>)
|
||||
declare i16 @llvm.atomic.load.xor.i16.p0i32(i16* <ptr>, i16 <delta>)
|
||||
declare i32 @llvm.atomic.load.xor.i32.p0i32(i32* <ptr>, i32 <delta>)
|
||||
declare i64 @llvm.atomic.load.xor.i64.p0i32(i64* <ptr>, i64 <delta>)
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>These intrinsics bitwise the operation (and, nand, or, xor) <tt>delta</tt> to
|
||||
the value stored in memory at <tt>ptr</tt>. It yields the original value
|
||||
at <tt>ptr</tt>.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>These intrinsics take two arguments, the first a pointer to an integer value
|
||||
and the second an integer value. The result is also an integer value. These
|
||||
integer types can have any bit width, but they must all have the same bit
|
||||
width. The targets may only lower integer representations they support.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>These intrinsics does a series of operations atomically. They first load the
|
||||
value stored at <tt>ptr</tt>. They then do the bitwise
|
||||
operation <tt>delta</tt>, store the result to <tt>ptr</tt>. They yield the
|
||||
original value stored at <tt>ptr</tt>.</p>
|
||||
|
||||
<h5>Examples:</h5>
|
||||
<pre>
|
||||
%mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
|
||||
%ptr = bitcast i8* %mallocP to i32*
|
||||
store i32 0x0F0F, %ptr
|
||||
%result0 = call i32 @llvm.atomic.load.nand.i32.p0i32(i32* %ptr, i32 0xFF)
|
||||
<i>; yields {i32}:result0 = 0x0F0F</i>
|
||||
%result1 = call i32 @llvm.atomic.load.and.i32.p0i32(i32* %ptr, i32 0xFF)
|
||||
<i>; yields {i32}:result1 = 0xFFFFFFF0</i>
|
||||
%result2 = call i32 @llvm.atomic.load.or.i32.p0i32(i32* %ptr, i32 0F)
|
||||
<i>; yields {i32}:result2 = 0xF0</i>
|
||||
%result3 = call i32 @llvm.atomic.load.xor.i32.p0i32(i32* %ptr, i32 0F)
|
||||
<i>; yields {i32}:result3 = FF</i>
|
||||
%memval1 = load i32* %ptr <i>; yields {i32}:memval1 = F0</i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<h4>
|
||||
<a name="int_atomic_load_max">
|
||||
'<tt>llvm.atomic.load.max.*</tt>' Intrinsic
|
||||
</a>
|
||||
<br>
|
||||
<a name="int_atomic_load_min">
|
||||
'<tt>llvm.atomic.load.min.*</tt>' Intrinsic
|
||||
</a>
|
||||
<br>
|
||||
<a name="int_atomic_load_umax">
|
||||
'<tt>llvm.atomic.load.umax.*</tt>' Intrinsic
|
||||
</a>
|
||||
<br>
|
||||
<a name="int_atomic_load_umin">
|
||||
'<tt>llvm.atomic.load.umin.*</tt>' Intrinsic
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
<div>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<p>These are overloaded intrinsics. You can use <tt>llvm.atomic.load_max</tt>,
|
||||
<tt>llvm.atomic.load_min</tt>, <tt>llvm.atomic.load_umax</tt>, and
|
||||
<tt>llvm.atomic.load_umin</tt> on any integer bit width and for different
|
||||
address spaces. Not all targets support all bit widths however.</p>
|
||||
|
||||
<pre>
|
||||
declare i8 @llvm.atomic.load.max.i8.p0i8(i8* <ptr>, i8 <delta>)
|
||||
declare i16 @llvm.atomic.load.max.i16.p0i16(i16* <ptr>, i16 <delta>)
|
||||
declare i32 @llvm.atomic.load.max.i32.p0i32(i32* <ptr>, i32 <delta>)
|
||||
declare i64 @llvm.atomic.load.max.i64.p0i64(i64* <ptr>, i64 <delta>)
|
||||
</pre>
|
||||
|
||||
<pre>
|
||||
declare i8 @llvm.atomic.load.min.i8.p0i8(i8* <ptr>, i8 <delta>)
|
||||
declare i16 @llvm.atomic.load.min.i16.p0i16(i16* <ptr>, i16 <delta>)
|
||||
declare i32 @llvm.atomic.load.min.i32.p0i32(i32* <ptr>, i32 <delta>)
|
||||
declare i64 @llvm.atomic.load.min.i64.p0i64(i64* <ptr>, i64 <delta>)
|
||||
</pre>
|
||||
|
||||
<pre>
|
||||
declare i8 @llvm.atomic.load.umax.i8.p0i8(i8* <ptr>, i8 <delta>)
|
||||
declare i16 @llvm.atomic.load.umax.i16.p0i16(i16* <ptr>, i16 <delta>)
|
||||
declare i32 @llvm.atomic.load.umax.i32.p0i32(i32* <ptr>, i32 <delta>)
|
||||
declare i64 @llvm.atomic.load.umax.i64.p0i64(i64* <ptr>, i64 <delta>)
|
||||
</pre>
|
||||
|
||||
<pre>
|
||||
declare i8 @llvm.atomic.load.umin.i8.p0i8(i8* <ptr>, i8 <delta>)
|
||||
declare i16 @llvm.atomic.load.umin.i16.p0i16(i16* <ptr>, i16 <delta>)
|
||||
declare i32 @llvm.atomic.load.umin.i32.p0i32(i32* <ptr>, i32 <delta>)
|
||||
declare i64 @llvm.atomic.load.umin.i64.p0i64(i64* <ptr>, i64 <delta>)
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>These intrinsics takes the signed or unsigned minimum or maximum of
|
||||
<tt>delta</tt> and the value stored in memory at <tt>ptr</tt>. It yields the
|
||||
original value at <tt>ptr</tt>.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>These intrinsics take two arguments, the first a pointer to an integer value
|
||||
and the second an integer value. The result is also an integer value. These
|
||||
integer types can have any bit width, but they must all have the same bit
|
||||
width. The targets may only lower integer representations they support.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>These intrinsics does a series of operations atomically. They first load the
|
||||
value stored at <tt>ptr</tt>. They then do the signed or unsigned min or
|
||||
max <tt>delta</tt> and the value, store the result to <tt>ptr</tt>. They
|
||||
yield the original value stored at <tt>ptr</tt>.</p>
|
||||
|
||||
<h5>Examples:</h5>
|
||||
<pre>
|
||||
%mallocP = tail call i8* @malloc(i32 ptrtoint (i32* getelementptr (i32* null, i32 1) to i32))
|
||||
%ptr = bitcast i8* %mallocP to i32*
|
||||
store i32 7, %ptr
|
||||
%result0 = call i32 @llvm.atomic.load.min.i32.p0i32(i32* %ptr, i32 -2)
|
||||
<i>; yields {i32}:result0 = 7</i>
|
||||
%result1 = call i32 @llvm.atomic.load.max.i32.p0i32(i32* %ptr, i32 8)
|
||||
<i>; yields {i32}:result1 = -2</i>
|
||||
%result2 = call i32 @llvm.atomic.load.umin.i32.p0i32(i32* %ptr, i32 10)
|
||||
<i>; yields {i32}:result2 = 8</i>
|
||||
%result3 = call i32 @llvm.atomic.load.umax.i32.p0i32(i32* %ptr, i32 30)
|
||||
<i>; yields {i32}:result3 = 8</i>
|
||||
%memval1 = load i32* %ptr <i>; yields {i32}:memval1 = 30</i>
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3>
|
||||
<a name="int_memorymarkers">Memory Use Markers</a>
|
||||
@ -8615,7 +8101,7 @@ LLVM</a>.</p>
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2011-10-14 01:04:49 +0200 (Fri, 14 Oct 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:54 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>LLVM Link Time Optimization: Design and Implementation</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
@ -392,7 +393,7 @@ of the native object files.</p>
|
||||
|
||||
Devang Patel and Nick Kledzik<br>
|
||||
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2011-09-18 14:51:05 +0200 (Sun, 18 Sep 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:23 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Advice on Packaging LLVM</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
@ -112,7 +113,7 @@ line numbers.</dd>
|
||||
<a href="http://validator.w3.org/check/referer"><img
|
||||
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
|
||||
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:23 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -226,11 +226,8 @@ perl -e '$/ = undef; for (split(/\n/, <>)) { s:^ *///? ?::; print " <p>\n" if !
|
||||
<a name="basicaa">-basicaa: Basic Alias Analysis (stateless AA impl)</a>
|
||||
</h3>
|
||||
<div>
|
||||
<p>
|
||||
This is the default implementation of the Alias Analysis interface
|
||||
that simply implements a few identities (two different globals cannot alias,
|
||||
etc), but otherwise does no analysis.
|
||||
</p>
|
||||
<p>A basic alias analysis pass that implements identities (two different
|
||||
globals cannot alias, etc), but does no stateful analysis.</p>
|
||||
</div>
|
||||
|
||||
<!-------------------------------------------------------------------------- -->
|
||||
@ -527,9 +524,10 @@ perl -e '$/ = undef; for (split(/\n/, <>)) { s:^ *///? ?::; print " <p>\n" if !
|
||||
</h3>
|
||||
<div>
|
||||
<p>
|
||||
Always returns "I don't know" for alias queries. NoAA is unlike other alias
|
||||
analysis implementations, in that it does not chain to a previous analysis. As
|
||||
such it doesn't follow many of the rules that other alias analyses must.
|
||||
This is the default implementation of the Alias Analysis interface. It always
|
||||
returns "I don't know" for alias queries. NoAA is unlike other alias analysis
|
||||
implementations, in that it does not chain to a previous analysis. As such it
|
||||
doesn't follow many of the rules that other alias analyses must.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -2041,7 +2039,7 @@ if (X < 3) {</pre>
|
||||
|
||||
<a href="mailto:rspencer@x10sys.com">Reid Spencer</a><br>
|
||||
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2011-08-04 00:18:20 +0200 (Thu, 04 Aug 2011) $
|
||||
Last modified: $Date: 2011-11-04 07:30:50 +0100 (Fri, 04 Nov 2011) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -879,9 +879,6 @@ elements (but could contain many), for example, it's much better to use
|
||||
. Doing so avoids (relatively) expensive malloc/free calls, which dwarf the
|
||||
cost of adding the elements to the container. </p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3>
|
||||
<a name="ds_sequential">Sequential Containers (std::vector, std::list, etc)</a>
|
||||
@ -4055,7 +4052,7 @@ arguments. An argument has a pointer to the parent Function.</p>
|
||||
<a href="mailto:dhurjati@cs.uiuc.edu">Dinakar Dhurjati</a> and
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2011-10-11 08:33:56 +0200 (Tue, 11 Oct 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:54 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Creating an LLVM Project</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
@ -481,7 +482,7 @@ Mailing List</a>.</p>
|
||||
<a href="mailto:criswell@uiuc.edu">John Criswell</a><br>
|
||||
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a>
|
||||
<br>
|
||||
Last modified: $Date: 2011-06-03 04:20:48 +0200 (Fri, 03 Jun 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:23 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -189,13 +189,7 @@ Release Notes</a>.</h1>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://lldb.llvm.org/">LLDB</a> is a brand new member of the LLVM
|
||||
umbrella of projects. LLDB is a next generation, high-performance
|
||||
debugger. It is built as a set of reusable components which highly leverage
|
||||
existing libraries in the larger LLVM Project, such as the Clang expression
|
||||
parser, the LLVM disassembler and the LLVM JIT.</p>
|
||||
|
||||
<p>LLDB is has advanced by leaps and bounds in the 3.0 timeframe. It is
|
||||
<p>LLDB has advanced by leaps and bounds in the 3.0 timeframe. It is
|
||||
dramatically more stable and useful, and includes both a
|
||||
new <a href="http://lldb.llvm.org/tutorial.html">tutorial</a> and
|
||||
a <a href="http://lldb.llvm.org/lldb-gdb.html">side-by-side comparison with
|
||||
@ -210,13 +204,6 @@ Release Notes</a>.</h1>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://libcxx.llvm.org/">libc++</a> is another new member of the
|
||||
LLVM family. It is an implementation of the C++ standard library, written
|
||||
from the ground up to specifically target the forthcoming C++'0X standard and
|
||||
focus on delivering great performance.</p>
|
||||
|
||||
<p>In the LLVM 3.0 timeframe,</p>
|
||||
|
||||
<p>Like compiler_rt, libc++ is now <a href="DeveloperPolicy.html#license">dual
|
||||
licensed</a> under the MIT and UIUC license, allowing it to be used more
|
||||
permissively.</p>
|
||||
@ -290,20 +277,254 @@ be used to verify some algorithms.
|
||||
projects that have already been updated to work with LLVM 3.0.</p>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>Crack Programming Language</h3>
|
||||
<h3>AddressSanitizer</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://code.google.com/p/crack-language/">Crack</a> aims to provide
|
||||
the ease of development of a scripting language with the performance of a
|
||||
compiled language. The language derives concepts from C++, Java and Python,
|
||||
incorporating object-oriented programming, operator overloading and strong
|
||||
typing.</p>
|
||||
<p><a href="http://code.google.com/p/address-sanitizer/">AddressSanitizer</a>
|
||||
uses compiler instrumentation and a specialized malloc library to find C/C++
|
||||
bugs such as use-after-free and out-of-bound accesses to heap, stack, and
|
||||
globals. The key feature of the tool is speed: the average slowdown
|
||||
introduced by AddressSanitizer is less than 2x.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>TTA-based Codesign Environment (TCE)</h3>
|
||||
<h3>ClamAV</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://www.clamav.net">Clam AntiVirus</a> is an open source (GPL)
|
||||
anti-virus toolkit for UNIX, designed especially for e-mail scanning on mail
|
||||
gateways.</p>
|
||||
|
||||
<p>Since version 0.96 it
|
||||
has <a href="http://vrt-sourcefire.blogspot.com/2010/09/introduction-to-clamavs-low-level.html">bytecode
|
||||
signatures</a> that allow writing detections for complex malware.</p>
|
||||
|
||||
<p>It uses LLVM's JIT to speed up the execution of bytecode on X86, X86-64,
|
||||
PPC32/64, falling back to its own interpreter otherwise. The git version was
|
||||
updated to work with LLVM 3.0.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>clReflect</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="https://bitbucket.org/dwilliamson/clreflect">clReflect</a> is a C++
|
||||
parser that uses clang/LLVM to derive a light-weight reflection database
|
||||
suitable for use in game development. It comes with a very simple runtime
|
||||
library for loading and querying the database, requiring no external
|
||||
dependencies (including CRT), and an additional utility library for object
|
||||
management and serialisation.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>Cling C++ Interpreter</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://cern.ch/cling">Cling</a> is an interactive compiler interface
|
||||
(aka C++ interpreter). It uses LLVM's JIT and clang; it currently supports
|
||||
C++ and C. It has a prompt interface, runs source files, calls into shared
|
||||
libraries, prints the value of expressions, even does runtime lookup of
|
||||
identifiers (dynamic scopes). And it just behaves like one would expect from
|
||||
an interpreter.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<!-- FIXME: Comment out
|
||||
<h3>Crack Programming Language</h3>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
<a href="http://code.google.com/p/crack-language/">Crack</a> aims to provide the
|
||||
ease of development of a scripting language with the performance of a compiled
|
||||
language. The language derives concepts from C++, Java and Python, incorporating
|
||||
object-oriented programming, operator overloading and strong typing.</p>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>Glasgow Haskell Compiler (GHC)</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p>GHC is an open source, state-of-the-art programming suite for Haskell, a
|
||||
standard lazy functional programming language. It includes an optimizing
|
||||
static compiler generating good code for a variety of platforms, together
|
||||
with an interactive system for convenient, quick development.</p>
|
||||
|
||||
<p>GHC 7.0 and onwards include an LLVM code generator, supporting LLVM 2.8 and
|
||||
later. Since LLVM 2.9, GHC now includes experimental support for the ARM
|
||||
platform with LLVM 3.0.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>gwXscript</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://botwars.tk/gwscript/">gwXscript</a> is an object oriented,
|
||||
aspect oriented programming language which can create both executables (ELF,
|
||||
EXE) and shared libraries (DLL, SO, DYNLIB). The compiler is implemented in
|
||||
its own language and translates scripts into LLVM-IR which can be optimized
|
||||
and translated into native code by the LLVM framework. Source code in
|
||||
gwScript contains definitions that expand the namespaces. So you can build
|
||||
your project and simply 'plug out' features by removing a file. The remaining
|
||||
project does not leave scars since you directly separate concerns by the
|
||||
'template' feature of gwX. It is also possible to add new features to a
|
||||
project by just adding files and without editing the original project. This
|
||||
language is used for example to create games or content management systems
|
||||
that should be extendable.</p>
|
||||
|
||||
<p>gwXscript is strongly typed and offers comfort with its native types string,
|
||||
hash and array. You can easily write new libraries in gwXscript or native
|
||||
code. gwXscript is type safe and users should not be able to crash your
|
||||
program or execute malicious code except code that is eating CPU time.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>include-what-you-use</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://code.google.com/p/include-what-you-use">include-what-you-use</a>
|
||||
is a tool to ensure that a file directly <code>#include</code>s
|
||||
all <code>.h</code> files that provide a symbol that the file uses. It also
|
||||
removes superfluous <code>#include</code>s from source files.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>LanguageKit and Pragmatic Smalltalk</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://etoileos.com/etoile/features/languagekit/">LanguageKit</a> is
|
||||
a framework for implementing dynamic languages sharing an object model with
|
||||
Objective-C. It provides static and JIT compilation using LLVM along with
|
||||
its own interpreter. Pragmatic Smalltalk is a dialect of Smalltalk, built on
|
||||
top of LanguageKit, that interfaces directly with Objective-C, sharing the
|
||||
same object representation and message sending behaviour. These projects are
|
||||
developed as part of the Étoié desktop environment.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>LuaAV</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://lua-av.mat.ucsb.edu/blog/">LuaAV</a> is a real-time
|
||||
audiovisual scripting environment based around the Lua language and a
|
||||
collection of libraries for sound, graphics, and other media protocols. LuaAV
|
||||
uses LLVM and Clang to JIT compile efficient user-defined audio synthesis
|
||||
routines specified in a declarative syntax.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>Mono</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p>An open source, cross-platform implementation of C# and the CLR that is
|
||||
binary compatible with Microsoft.NET. Has an optional, dynamically-loaded
|
||||
LLVM code generation backend in Mini, the JIT compiler.</p>
|
||||
|
||||
<p>Note that we use a Git mirror of LLVM with some patches. See:
|
||||
https://github.com/mono/llvm</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>Portable OpenCL (pocl)</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p>Portable OpenCL is an open source implementation of the OpenCL standard which
|
||||
can be easily adapted for new targets. One of the goals of the project is
|
||||
improving performance portability of OpenCL programs, avoiding the need for
|
||||
target-dependent manual optimizations. A "native" target is included, which
|
||||
allows running OpenCL kernels on the host (CPU).</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>Pure</h3>
|
||||
|
||||
<div>
|
||||
<p><a href="http://pure-lang.googlecode.com/">Pure</a> is an
|
||||
algebraic/functional programming language based on term rewriting. Programs
|
||||
are collections of equations which are used to evaluate expressions in a
|
||||
symbolic fashion. The interpreter uses LLVM as a backend to JIT-compile Pure
|
||||
programs to fast native code. Pure offers dynamic typing, eager and lazy
|
||||
evaluation, lexical closures, a hygienic macro system (also based on term
|
||||
rewriting), built-in list and matrix support (including list and matrix
|
||||
comprehensions) and an easy-to-use interface to C and other programming
|
||||
languages (including the ability to load LLVM bitcode modules, and inline C,
|
||||
C++, Fortran and Faust code in Pure programs if the corresponding LLVM-enabled
|
||||
compilers are installed).</p>
|
||||
|
||||
<p>Pure version 0.48 has been tested and is known to work with LLVM 3.0
|
||||
(and continues to work with older LLVM releases >= 2.5).</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>Renderscript</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://developer.android.com/guide/topics/renderscript/index.html">Renderscript</a>
|
||||
is Android's advanced 3D graphics rendering and compute API. It provides a
|
||||
portable C99-based language with extensions to facilitate common use cases
|
||||
for enhancing graphics and thread level parallelism. The Renderscript
|
||||
compiler frontend is based on Clang/LLVM. It emits a portable bitcode format
|
||||
for the actual compiled script code, as well as reflects a Java interface for
|
||||
developers to control the execution of the compiled bitcode. Executable
|
||||
machine code is then generated from this bitcode by an LLVM backend on the
|
||||
device. Renderscript is thus able to provide a mechanism by which Android
|
||||
developers can improve performance of their applications while retaining
|
||||
portability.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>SAFECode</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://safecode.cs.illinois.edu">SAFECode</a> is a memory safe C/C++
|
||||
compiler built using LLVM. It takes standard, unannotated C/C++ code,
|
||||
analyzes the code to ensure that memory accesses and array indexing
|
||||
operations are safe, and instruments the code with run-time checks when
|
||||
safety cannot be proven statically. SAFECode can be used as a debugging aid
|
||||
(like Valgrind) to find and repair memory safety bugs. It can also be used
|
||||
to protect code from security attacks at run-time.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>The Stupid D Compiler (SDC)</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="https://github.com/bhelyer/SDC">The Stupid D Compiler</a> is a
|
||||
project seeking to write a self-hosting compiler for the D programming
|
||||
language without using the frontend of the reference compiler (DMD).</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>TTA-based Co-design Environment (TCE)</h3>
|
||||
|
||||
<div>
|
||||
|
||||
@ -322,120 +543,140 @@ be used to verify some algorithms.
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>Tart Programming Language</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://code.google.com/p/tart/">Tart</a> is a general-purpose,
|
||||
strongly typed programming language designed for application
|
||||
developers. Strongly inspired by Python and C#, Tart focuses on practical
|
||||
solutions for the professional software developer, while avoiding the clutter
|
||||
and boilerplate of legacy languages like Java and C++. Although Tart is still
|
||||
in development, the current implementation supports many features expected of
|
||||
a modern programming language, such as garbage collection, powerful
|
||||
bidirectional type inference, a greatly simplified syntax for template
|
||||
metaprogramming, closures and function literals, reflection, operator
|
||||
overloading, explicit mutability and immutability, and much more. Tart is
|
||||
flexible enough to accommodate a broad range of programming styles and
|
||||
philosophies, while maintaining a strong commitment to simplicity, minimalism
|
||||
and elegance in design.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>ThreadSanitizer</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://code.google.com/p/data-race-test/">ThreadSanitizer</a> is a
|
||||
data race detector for (mostly) C and C++ code, available for Linux, Mac OS
|
||||
and Windows. On different systems, we use binary instrumentation frameworks
|
||||
(Valgrind and Pin) as frontends that generate the program events for the race
|
||||
detection algorithm. On Linux, there's an option of using LLVM-based
|
||||
compile-time instrumentation.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>The ZooLib C++ Cross-Platform Application Framework</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://www.zoolib.org/">ZooLib</a> is Open Source under the MIT
|
||||
License. It provides GUI, filesystem access, TCP networking, thread-safe
|
||||
memory management, threading and locking for Mac OS X, Classic Mac OS,
|
||||
Microsoft Windows, POSIX operating systems with X11, BeOS, Haiku, Apple's iOS
|
||||
and Research in Motion's BlackBerry.</p>
|
||||
|
||||
<p>My current work is to use CLang's static analyzer to improve ZooLib's code
|
||||
quality. I also plan to set up LLVM compiles of the demo programs and test
|
||||
programs using CLang and LLVM on all the platforms that CLang, LLVM and
|
||||
ZooLib all support.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<!--
|
||||
<h3>PinaVM</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://gitorious.org/pinavm/pages/Home">PinaVM</a> is an open
|
||||
source, <a href="http://www.systemc.org/">SystemC</a> front-end. Unlike many
|
||||
other front-ends, PinaVM actually executes the elaboration of the program
|
||||
analyzed using LLVM's JIT infrastructure. It later enriches the bitcode with
|
||||
SystemC-specific information.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>Pure</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://pure-lang.googlecode.com/">Pure</a> is an
|
||||
algebraic/functional programming language based on term rewriting. Programs
|
||||
are collections of equations which are used to evaluate expressions in a
|
||||
symbolic fashion. The interpreter uses LLVM as a backend to JIT-compile Pure
|
||||
programs to fast native code. Pure offers dynamic typing, eager and lazy
|
||||
evaluation, lexical closures, a hygienic macro system (also based on term
|
||||
rewriting), built-in list and matrix support (including list and matrix
|
||||
comprehensions) and an easy-to-use interface to C and other programming
|
||||
languages (including the ability to load LLVM bitcode modules, and inline C,
|
||||
C++, Fortran and Faust code in Pure programs if the corresponding
|
||||
LLVM-enabled compilers are installed).</p>
|
||||
|
||||
<p>Pure version 0.47 has been tested and is known to work with LLVM 3.0 (and
|
||||
continues to work with older LLVM releases >= 2.5).</p>
|
||||
|
||||
source, <a href="http://www.systemc.org/">SystemC</a> front-end. Unlike many
|
||||
other front-ends, PinaVM actually executes the elaboration of the
|
||||
program analyzed using LLVM's JIT infrastructure. It later enriches the
|
||||
bitcode with SystemC-specific information.</p>
|
||||
</div>
|
||||
-->
|
||||
|
||||
|
||||
<!--=========================================================================-->
|
||||
<!--
|
||||
<h3 id="icedtea">IcedTea Java Virtual Machine Implementation</h3>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
<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.
|
||||
</p>
|
||||
|
||||
<p><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.</p>
|
||||
|
||||
<p>OpenJDK 7 b112, IcedTea6 1.9 and IcedTea7 1.13 and later have been tested and
|
||||
are known to work with LLVM 3.0 (and continue to work with older LLVM
|
||||
releases >= 2.6 as well).</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!--=========================================================================-->
|
||||
<h3>Glasgow Haskell Compiler (GHC)</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p>GHC is an open source, state-of-the-art programming suite for Haskell, a
|
||||
standard lazy functional programming language. It includes an optimizing
|
||||
static compiler generating good code for a variety of platforms, together
|
||||
with an interactive system for convenient, quick development.</p>
|
||||
|
||||
<p>In addition to the existing C and native code generators, GHC 7.0 now
|
||||
supports an LLVM code generator. GHC supports LLVM 2.7 and later.</p>
|
||||
|
||||
<p> OpenJDK 7 b112, IcedTea6 1.9 and IcedTea7 1.13 and later have been tested
|
||||
and are known to work with LLVM 3.0 (and continue to work with older LLVM
|
||||
releases >= 2.6 as well).</p>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<!--=========================================================================-->
|
||||
<!--
|
||||
<h3>Polly - Polyhedral optimizations for LLVM</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p>Polly is a project that aims to provide advanced memory access optimizations
|
||||
to better take advantage of SIMD units, cache hierarchies, multiple cores or
|
||||
even vector accelerators for LLVM. Built around an abstract mathematical
|
||||
description based on Z-polyhedra, it provides the infrastructure to develop
|
||||
advanced optimizations in LLVM and to connect complex external optimizers. In
|
||||
its first year of existence Polly already provides an exact value-based
|
||||
dependency analysis as well as basic SIMD and OpenMP code generation support.
|
||||
Furthermore, Polly can use PoCC(Pluto) an advanced optimizer for
|
||||
data-locality and parallelism.</p>
|
||||
|
||||
to better take advantage of SIMD units, cache hierarchies, multiple cores or
|
||||
even vector accelerators for LLVM. Built around an abstract mathematical
|
||||
description based on Z-polyhedra, it provides the infrastructure to develop
|
||||
advanced optimizations in LLVM and to connect complex external optimizers. In
|
||||
its first year of existence Polly already provides an exact value-based
|
||||
dependency analysis as well as basic SIMD and OpenMP code generation support.
|
||||
Furthermore, Polly can use PoCC(Pluto) an advanced optimizer for data-locality
|
||||
and parallelism.</p>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<!--=========================================================================-->
|
||||
<!--
|
||||
<h3>Rubinius</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<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 implementation in
|
||||
Ruby as possible. Combined with a bytecode interpreting VM, it uses LLVM to
|
||||
optimize and compile ruby code down to machine code. Techniques such as type
|
||||
feedback, method inlining, and deoptimization are all used to remove dynamism
|
||||
from ruby execution and increase performance.</p>
|
||||
|
||||
<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 implementation in
|
||||
Ruby as possible. Combined with a bytecode interpreting VM, it uses LLVM to
|
||||
optimize and compile ruby code down to machine code. Techniques such as type
|
||||
feedback, method inlining, and deoptimization are all used to remove dynamism
|
||||
from ruby execution and increase performance.</p>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<!--=========================================================================-->
|
||||
<!--
|
||||
<h3>
|
||||
<a name="FAUST">FAUST Real-Time Audio Signal Processing Language</a>
|
||||
</h3>
|
||||
|
||||
<div>
|
||||
|
||||
<p><a href="http://faust.grame.fr">FAUST</a> is a compiled language for
|
||||
real-time audio signal processing. The name FAUST stands for Functional AUdio
|
||||
STream. Its programming model combines two approaches: functional programming
|
||||
and block diagram composition. In addition with the C, C++, JAVA output
|
||||
formats, the Faust compiler can now generate LLVM bitcode, and works with
|
||||
LLVM 2.7-3.0.</p>
|
||||
<p>
|
||||
<a href="http://faust.grame.fr">FAUST</a> is a compiled language for real-time
|
||||
audio signal processing. The name FAUST stands for Functional AUdio STream. Its
|
||||
programming model combines two approaches: functional programming and block
|
||||
diagram composition. In addition with the C, C++, JAVA output formats, the
|
||||
Faust compiler can now generate LLVM bitcode, and works with LLVM 2.7-3.0.</p>
|
||||
|
||||
</div>
|
||||
-->
|
||||
|
||||
</div>
|
||||
|
||||
@ -698,6 +939,9 @@ Builder.CreateResume(UnwindData);
|
||||
<a name="OtherTS">Other Target Specific Improvements</a>
|
||||
</h3>
|
||||
|
||||
<p>PPC32/ELF va_arg was implemented.</p>
|
||||
<p>PPC32 initial support for .o file writing was implemented.</p>
|
||||
|
||||
<div>
|
||||
|
||||
<ul>
|
||||
@ -730,6 +974,9 @@ Builder.CreateResume(UnwindData);
|
||||
"<code>load volatile</code>"/"<code>store volatile</code>". The old
|
||||
syntax ("<code>volatile load</code>"/"<code>volatile store</code>")
|
||||
is still accepted, but is now considered deprecated.</li>
|
||||
<li>The old atomic intrinscs (<code>llvm.memory.barrier</code> and
|
||||
<code>llvm.atomic.*</code>) are now gone. Please use the new atomic
|
||||
instructions, described in the <a href="Atomics.html">atomics guide</a>.
|
||||
</ul>
|
||||
|
||||
<h4>Windows (32-bit)</h4>
|
||||
@ -943,8 +1190,7 @@ Builder.CreateResume(UnwindData);
|
||||
<div>
|
||||
|
||||
<ul>
|
||||
<li>The Linux PPC32/ABI support needs testing for the interpreter and static
|
||||
compilation, and lacks support for debug information.</li>
|
||||
<li>The PPC32/ELF support lacks PIC support.</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@ -1096,7 +1342,7 @@ Builder.CreateResume(UnwindData);
|
||||
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: 2011-10-17 08:31:58 +0200 (Mon, 17 Oct 2011) $
|
||||
Last modified: $Date: 2011-11-01 05:51:35 +0100 (Tue, 01 Nov 2011) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>System Library</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
@ -309,7 +310,7 @@
|
||||
|
||||
<a href="mailto:rspencer@x10sys.com">Reid Spencer</a><br>
|
||||
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:23 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>TableGen Fundamentals</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
@ -911,7 +912,7 @@ This should highlight the APIs in <tt>TableGen/Record.h</tt>.</p>
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2011-10-07 20:25:05 +0200 (Fri, 07 Oct 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:23 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>LLVM Testing Infrastructure Guide</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
@ -1206,7 +1207,7 @@ example reports that can do fancy stuff.</p>
|
||||
|
||||
John T. Criswell, Daniel Dunbar, Reid Spencer, and Tanya Lattner<br>
|
||||
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2011-05-18 20:07:16 +0200 (Wed, 18 May 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:23 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,7 +1,8 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Using The LLVM Libraries</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Using The LLVM Libraries</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
@ -440,7 +441,7 @@
|
||||
<a href="mailto:rspencer@x10sys.com">Reid Spencer</a>
|
||||
</address>
|
||||
<a href="http://llvm.org/">The LLVM Compiler Infrastructure</a>
|
||||
<br>Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ </div>
|
||||
<br>Last modified: $Date: 2011-11-03 07:43:23 +0100 (Thu, 03 Nov 2011) $ </div>
|
||||
</body>
|
||||
</html>
|
||||
<!-- vim: sw=2 ts=2 ai
|
||||
|
@ -2,6 +2,7 @@
|
||||
"http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Documentation for the LLVM System at SVN head</title>
|
||||
<link rel="stylesheet" href="llvm.css" type="text/css">
|
||||
</head>
|
||||
@ -285,7 +286,7 @@ times each day, making it a high volume list.</li>
|
||||
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: 2011-10-11 18:35:07 +0200 (Tue, 11 Oct 2011) $
|
||||
Last modified: $Date: 2011-11-03 07:43:23 +0100 (Thu, 03 Nov 2011) $
|
||||
</address>
|
||||
</body></html>
|
||||
|
||||
|
@ -527,18 +527,20 @@ bool CompileUnit::addConstantValue(DIE *Die, const ConstantInt *CI,
|
||||
|
||||
// Get the raw data form of the large APInt.
|
||||
const APInt Val = CI->getValue();
|
||||
const char *Ptr = (const char*)Val.getRawData();
|
||||
const uint64_t *Ptr64 = Val.getRawData();
|
||||
|
||||
int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.
|
||||
bool LittleEndian = Asm->getTargetData().isLittleEndian();
|
||||
int Incr = (LittleEndian ? 1 : -1);
|
||||
int Start = (LittleEndian ? 0 : NumBytes - 1);
|
||||
int Stop = (LittleEndian ? NumBytes : -1);
|
||||
|
||||
// Output the constant to DWARF one byte at a time.
|
||||
for (; Start != Stop; Start += Incr)
|
||||
addUInt(Block, 0, dwarf::DW_FORM_data1,
|
||||
(unsigned char)0xFF & Ptr[Start]);
|
||||
for (int i = 0; i < NumBytes; i++) {
|
||||
uint8_t c;
|
||||
if (LittleEndian)
|
||||
c = Ptr64[i / 8] >> (8 * (i & 7));
|
||||
else
|
||||
c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));
|
||||
addUInt(Block, 0, dwarf::DW_FORM_data1, c);
|
||||
}
|
||||
|
||||
addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
|
||||
return true;
|
||||
|
@ -119,7 +119,8 @@ LLVMTargetMachine::LLVMTargetMachine(const Target &T, StringRef Triple,
|
||||
// we'll crash later.
|
||||
// Provide the user with a useful error message about what's wrong.
|
||||
assert(AsmInfo && "MCAsmInfo not initialized."
|
||||
"Make sure you include the correct TargetSelect.h!");
|
||||
"Make sure you include the correct TargetSelect.h"
|
||||
"and that InitializeAllTargetMCs() is being invoked!");
|
||||
}
|
||||
|
||||
bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
|
||||
|
@ -2034,14 +2034,17 @@ bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec &CR,
|
||||
return false;
|
||||
|
||||
APInt Range = ComputeRange(First, Last);
|
||||
double Density = TSize.roundToDouble() / Range.roundToDouble();
|
||||
if (Density < 0.4)
|
||||
// The density is TSize / Range. Require at least 40%.
|
||||
// It should not be possible for IntTSize to saturate for sane code, but make
|
||||
// sure we handle Range saturation correctly.
|
||||
uint64_t IntRange = Range.getLimitedValue(UINT64_MAX/10);
|
||||
uint64_t IntTSize = TSize.getLimitedValue(UINT64_MAX/10);
|
||||
if (IntTSize * 10 < IntRange * 4)
|
||||
return false;
|
||||
|
||||
DEBUG(dbgs() << "Lowering jump table\n"
|
||||
<< "First entry: " << First << ". Last entry: " << Last << '\n'
|
||||
<< "Range: " << Range
|
||||
<< ". Size: " << TSize << ". Density: " << Density << "\n\n");
|
||||
<< "Range: " << Range << ". Size: " << TSize << ".\n\n");
|
||||
|
||||
// Get the MachineFunction which holds the current MBB. This is used when
|
||||
// inserting any additional MBBs necessary to represent the switch.
|
||||
|
@ -506,7 +506,9 @@ getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
|
||||
// Add information about the stub reference to MachOMMI so that the stub
|
||||
// gets emitted by the asmprinter.
|
||||
MCSymbol *SSym = getContext().GetOrCreateSymbol(Name.str());
|
||||
MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);
|
||||
MachineModuleInfoImpl::StubValueTy &StubSym =
|
||||
GV->hasHiddenVisibility() ? MachOMMI.getHiddenGVStubEntry(SSym) :
|
||||
MachOMMI.getGVStubEntry(SSym);
|
||||
if (StubSym.getPointer() == 0) {
|
||||
MCSymbol *Sym = Mang->getSymbol(GV);
|
||||
StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
|
||||
@ -534,7 +536,9 @@ getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
|
||||
// Add information about the stub reference to MachOMMI so that the stub
|
||||
// gets emitted by the asmprinter.
|
||||
MCSymbol *SSym = getContext().GetOrCreateSymbol(Name.str());
|
||||
MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);
|
||||
MachineModuleInfoImpl::StubValueTy &StubSym =
|
||||
GV->hasHiddenVisibility() ? MachOMMI.getHiddenGVStubEntry(SSym) :
|
||||
MachOMMI.getGVStubEntry(SSym);
|
||||
if (StubSym.getPointer() == 0) {
|
||||
MCSymbol *Sym = Mang->getSymbol(GV);
|
||||
StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
|
||||
|
@ -63,6 +63,13 @@ ARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii,
|
||||
|
||||
const unsigned*
|
||||
ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
||||
bool ghcCall = false;
|
||||
|
||||
if (MF) {
|
||||
const Function *F = MF->getFunction();
|
||||
ghcCall = (F ? F->getCallingConv() == CallingConv::GHC : false);
|
||||
}
|
||||
|
||||
static const unsigned CalleeSavedRegs[] = {
|
||||
ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8,
|
||||
ARM::R7, ARM::R6, ARM::R5, ARM::R4,
|
||||
@ -82,7 +89,13 @@ ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
||||
ARM::D11, ARM::D10, ARM::D9, ARM::D8,
|
||||
0
|
||||
};
|
||||
return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs;
|
||||
|
||||
static const unsigned GhcCalleeSavedRegs[] = {
|
||||
0
|
||||
};
|
||||
|
||||
return ghcCall ? GhcCalleeSavedRegs :
|
||||
STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs;
|
||||
}
|
||||
|
||||
BitVector ARMBaseRegisterInfo::
|
||||
|
@ -82,6 +82,25 @@ def RetFastCC_ARM_APCS : CallingConv<[
|
||||
CCDelegateTo<RetCC_ARM_APCS>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM APCS Calling Convention for GHC
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CC_ARM_APCS_GHC : CallingConv<[
|
||||
// Handle all vector types as either f64 or v2f64.
|
||||
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
||||
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
||||
|
||||
CCIfType<[v2f64], CCAssignToReg<[Q4, Q5]>>,
|
||||
CCIfType<[f64], CCAssignToReg<[D8, D9, D10, D11]>>,
|
||||
CCIfType<[f32], CCAssignToReg<[S16, S17, S18, S19, S20, S21, S22, S23]>>,
|
||||
|
||||
// Promote i8/i16 arguments to i32.
|
||||
CCIfType<[i8, i16], CCPromoteToType<i32>>,
|
||||
|
||||
// Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, SpLim
|
||||
CCIfType<[i32], CCAssignToReg<[R4, R5, R6, R7, R8, R9, R10, R11]>>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM AAPCS (EABI) Calling Convention, common parts
|
||||
|
@ -1548,6 +1548,11 @@ CCAssignFn *ARMFastISel::CCAssignFnForCall(CallingConv::ID CC, bool Return) {
|
||||
return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
|
||||
case CallingConv::ARM_APCS:
|
||||
return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
|
||||
case CallingConv::GHC:
|
||||
if (Return)
|
||||
llvm_unreachable("Can't return in GHC call convention");
|
||||
else
|
||||
return CC_ARM_APCS_GHC;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "ARMBaseInstrInfo.h"
|
||||
#include "ARMBaseRegisterInfo.h"
|
||||
#include "ARMMachineFunctionInfo.h"
|
||||
#include "llvm/CallingConv.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "MCTargetDesc/ARMAddressingModes.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
@ -139,6 +141,10 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||
unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
|
||||
int FramePtrSpillFI = 0;
|
||||
|
||||
// All calls are tail calls in GHC calling conv, and functions have no prologue/epilogue.
|
||||
if (MF.getFunction()->getCallingConv() == CallingConv::GHC)
|
||||
return;
|
||||
|
||||
// Allocate the vararg register save area. This is not counted in NumBytes.
|
||||
if (VARegSaveSize)
|
||||
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -VARegSaveSize,
|
||||
@ -326,6 +332,10 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
int NumBytes = (int)MFI->getStackSize();
|
||||
unsigned FramePtr = RegInfo->getFrameRegister(MF);
|
||||
|
||||
// All calls are tail calls in GHC calling conv, and functions have no prologue/epilogue.
|
||||
if (MF.getFunction()->getCallingConv() == CallingConv::GHC)
|
||||
return;
|
||||
|
||||
if (!AFI->hasStackFrame()) {
|
||||
if (NumBytes != 0)
|
||||
emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
|
||||
|
@ -1091,6 +1091,8 @@ CCAssignFn *ARMTargetLowering::CCAssignFnForNode(CallingConv::ID CC,
|
||||
return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
|
||||
case CallingConv::ARM_APCS:
|
||||
return (Return ? RetCC_ARM_APCS : CC_ARM_APCS);
|
||||
case CallingConv::GHC:
|
||||
return (Return ? RetCC_ARM_APCS : CC_ARM_APCS_GHC);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1538,8 +1538,7 @@ multiclass thumb2_ld_mult<string asm, InstrItinClass itin,
|
||||
let Inst{21} = 0; // No writeback
|
||||
let Inst{20} = L_bit;
|
||||
let Inst{19-16} = Rn;
|
||||
let Inst{15} = 0;
|
||||
let Inst{14-0} = regs{14-0};
|
||||
let Inst{15-0} = regs;
|
||||
}
|
||||
def IA_UPD :
|
||||
T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
|
||||
@ -1554,8 +1553,7 @@ multiclass thumb2_ld_mult<string asm, InstrItinClass itin,
|
||||
let Inst{21} = 1; // Writeback
|
||||
let Inst{20} = L_bit;
|
||||
let Inst{19-16} = Rn;
|
||||
let Inst{15} = 0;
|
||||
let Inst{14-0} = regs{14-0};
|
||||
let Inst{15-0} = regs;
|
||||
}
|
||||
def DB :
|
||||
T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
|
||||
@ -1570,8 +1568,7 @@ multiclass thumb2_ld_mult<string asm, InstrItinClass itin,
|
||||
let Inst{21} = 0; // No writeback
|
||||
let Inst{20} = L_bit;
|
||||
let Inst{19-16} = Rn;
|
||||
let Inst{15} = 0;
|
||||
let Inst{14-0} = regs{14-0};
|
||||
let Inst{15-0} = regs;
|
||||
}
|
||||
def DB_UPD :
|
||||
T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
|
||||
@ -1586,8 +1583,7 @@ multiclass thumb2_ld_mult<string asm, InstrItinClass itin,
|
||||
let Inst{21} = 1; // Writeback
|
||||
let Inst{20} = L_bit;
|
||||
let Inst{19-16} = Rn;
|
||||
let Inst{15} = 0;
|
||||
let Inst{14-0} = regs{14-0};
|
||||
let Inst{15-0} = regs;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1016,6 +1016,27 @@ std::string CppWriter::getOpName(const Value* V) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static StringRef ConvertAtomicOrdering(AtomicOrdering Ordering) {
|
||||
switch (Ordering) {
|
||||
case NotAtomic: return "NotAtomic";
|
||||
case Unordered: return "Unordered";
|
||||
case Monotonic: return "Monotonic";
|
||||
case Acquire: return "Acquire";
|
||||
case Release: return "Release";
|
||||
case AcquireRelease: return "AcquireRelease";
|
||||
case SequentiallyConsistent: return "SequentiallyConsistent";
|
||||
}
|
||||
llvm_unreachable("Unknown ordering");
|
||||
}
|
||||
|
||||
static StringRef ConvertAtomicSynchScope(SynchronizationScope SynchScope) {
|
||||
switch (SynchScope) {
|
||||
case SingleThread: return "SingleThread";
|
||||
case CrossThread: return "CrossThread";
|
||||
}
|
||||
llvm_unreachable("Unknown synch scope");
|
||||
}
|
||||
|
||||
// printInstruction - This member is called for each Instruction in a function.
|
||||
void CppWriter::printInstruction(const Instruction *I,
|
||||
const std::string& bbname) {
|
||||
@ -1237,15 +1258,33 @@ void CppWriter::printInstruction(const Instruction *I,
|
||||
printEscapedString(load->getName());
|
||||
Out << "\", " << (load->isVolatile() ? "true" : "false" )
|
||||
<< ", " << bbname << ");";
|
||||
if (load->getAlignment())
|
||||
nl(Out) << iName << "->setAlignment("
|
||||
<< load->getAlignment() << ");";
|
||||
if (load->isAtomic()) {
|
||||
StringRef Ordering = ConvertAtomicOrdering(load->getOrdering());
|
||||
StringRef CrossThread = ConvertAtomicSynchScope(load->getSynchScope());
|
||||
nl(Out) << iName << "->setAtomic("
|
||||
<< Ordering << ", " << CrossThread << ");";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Instruction::Store: {
|
||||
const StoreInst* store = cast<StoreInst>(I);
|
||||
Out << " new StoreInst("
|
||||
Out << "StoreInst* " << iName << " = new StoreInst("
|
||||
<< opNames[0] << ", "
|
||||
<< opNames[1] << ", "
|
||||
<< (store->isVolatile() ? "true" : "false")
|
||||
<< ", " << bbname << ");";
|
||||
if (store->getAlignment())
|
||||
nl(Out) << iName << "->setAlignment("
|
||||
<< store->getAlignment() << ");";
|
||||
if (store->isAtomic()) {
|
||||
StringRef Ordering = ConvertAtomicOrdering(store->getOrdering());
|
||||
StringRef CrossThread = ConvertAtomicSynchScope(store->getSynchScope());
|
||||
nl(Out) << iName << "->setAtomic("
|
||||
<< Ordering << ", " << CrossThread << ");";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Instruction::GetElementPtr: {
|
||||
@ -1447,6 +1486,60 @@ void CppWriter::printInstruction(const Instruction *I,
|
||||
Out << "\", " << bbname << ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::Fence: {
|
||||
const FenceInst *fi = cast<FenceInst>(I);
|
||||
StringRef Ordering = ConvertAtomicOrdering(fi->getOrdering());
|
||||
StringRef CrossThread = ConvertAtomicSynchScope(fi->getSynchScope());
|
||||
Out << "FenceInst* " << iName
|
||||
<< " = new FenceInst(mod->getContext(), "
|
||||
<< Ordering << ", " << CrossThread << ", " << bbname
|
||||
<< ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::AtomicCmpXchg: {
|
||||
const AtomicCmpXchgInst *cxi = cast<AtomicCmpXchgInst>(I);
|
||||
StringRef Ordering = ConvertAtomicOrdering(cxi->getOrdering());
|
||||
StringRef CrossThread = ConvertAtomicSynchScope(cxi->getSynchScope());
|
||||
Out << "AtomicCmpXchgInst* " << iName
|
||||
<< " = new AtomicCmpXchgInst("
|
||||
<< opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", "
|
||||
<< Ordering << ", " << CrossThread << ", " << bbname
|
||||
<< ");";
|
||||
nl(Out) << iName << "->setName(\"";
|
||||
printEscapedString(cxi->getName());
|
||||
Out << "\");";
|
||||
break;
|
||||
}
|
||||
case Instruction::AtomicRMW: {
|
||||
const AtomicRMWInst *rmwi = cast<AtomicRMWInst>(I);
|
||||
StringRef Ordering = ConvertAtomicOrdering(rmwi->getOrdering());
|
||||
StringRef CrossThread = ConvertAtomicSynchScope(rmwi->getSynchScope());
|
||||
StringRef Operation;
|
||||
switch (rmwi->getOperation()) {
|
||||
case AtomicRMWInst::Xchg: Operation = "AtomicRMWInst::Xchg"; break;
|
||||
case AtomicRMWInst::Add: Operation = "AtomicRMWInst::Add"; break;
|
||||
case AtomicRMWInst::Sub: Operation = "AtomicRMWInst::Sub"; break;
|
||||
case AtomicRMWInst::And: Operation = "AtomicRMWInst::And"; break;
|
||||
case AtomicRMWInst::Nand: Operation = "AtomicRMWInst::Nand"; break;
|
||||
case AtomicRMWInst::Or: Operation = "AtomicRMWInst::Or"; break;
|
||||
case AtomicRMWInst::Xor: Operation = "AtomicRMWInst::Xor"; break;
|
||||
case AtomicRMWInst::Max: Operation = "AtomicRMWInst::Max"; break;
|
||||
case AtomicRMWInst::Min: Operation = "AtomicRMWInst::Min"; break;
|
||||
case AtomicRMWInst::UMax: Operation = "AtomicRMWInst::UMax"; break;
|
||||
case AtomicRMWInst::UMin: Operation = "AtomicRMWInst::UMin"; break;
|
||||
case AtomicRMWInst::BAD_BINOP: llvm_unreachable("Bad atomic operation");
|
||||
}
|
||||
Out << "AtomicRMWInst* " << iName
|
||||
<< " = new AtomicRMWInst("
|
||||
<< Operation << ", "
|
||||
<< opNames[0] << ", " << opNames[1] << ", "
|
||||
<< Ordering << ", " << CrossThread << ", " << bbname
|
||||
<< ");";
|
||||
nl(Out) << iName << "->setName(\"";
|
||||
printEscapedString(rmwi->getName());
|
||||
Out << "\");";
|
||||
break;
|
||||
}
|
||||
}
|
||||
DefinedValues.insert(I);
|
||||
nl(Out);
|
||||
@ -1623,7 +1716,9 @@ void CppWriter::printFunctionBody(const Function *F) {
|
||||
Out << "Value* " << getCppName(AI) << " = args++;";
|
||||
nl(Out);
|
||||
if (AI->hasName()) {
|
||||
Out << getCppName(AI) << "->setName(\"" << AI->getName() << "\");";
|
||||
Out << getCppName(AI) << "->setName(\"";
|
||||
printEscapedString(AI->getName());
|
||||
Out << "\");";
|
||||
nl(Out);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ set(LLVM_TARGET_DEFINITIONS Mips.td)
|
||||
|
||||
llvm_tablegen(MipsGenRegisterInfo.inc -gen-register-info)
|
||||
llvm_tablegen(MipsGenInstrInfo.inc -gen-instr-info)
|
||||
llvm_tablegen(MipsGenCodeEmitter.inc -gen-emitter)
|
||||
llvm_tablegen(MipsGenAsmWriter.inc -gen-asm-writer)
|
||||
llvm_tablegen(MipsGenDAGISel.inc -gen-dag-isel)
|
||||
llvm_tablegen(MipsGenCallingConv.inc -gen-callingconv)
|
||||
|
@ -13,7 +13,7 @@ TARGET = Mips
|
||||
|
||||
# Make sure that tblgen is run, first thing.
|
||||
BUILT_SOURCES = MipsGenRegisterInfo.inc MipsGenInstrInfo.inc \
|
||||
MipsGenAsmWriter.inc \
|
||||
MipsGenAsmWriter.inc MipsGenCodeEmitter.inc \
|
||||
MipsGenDAGISel.inc MipsGenCallingConv.inc \
|
||||
MipsGenSubtargetInfo.inc
|
||||
|
||||
|
@ -39,51 +39,51 @@ def imm32_63 : ImmLeaf<i64,
|
||||
// Shifts
|
||||
class LogicR_shift_rotate_imm64<bits<6> func, bits<5> _rs, string instr_asm,
|
||||
SDNode OpNode, PatFrag PF>:
|
||||
FR<0x00, func, (outs CPU64Regs:$dst), (ins CPU64Regs:$b, shamt_64:$c),
|
||||
!strconcat(instr_asm, "\t$dst, $b, $c"),
|
||||
[(set CPU64Regs:$dst, (OpNode CPU64Regs:$b, (i64 PF:$c)))],
|
||||
FR<0x00, func, (outs CPU64Regs:$rd), (ins CPU64Regs:$rt, shamt_64:$shamt),
|
||||
!strconcat(instr_asm, "\t$rd, $rt, $shamt"),
|
||||
[(set CPU64Regs:$rd, (OpNode CPU64Regs:$rt, (i64 PF:$shamt)))],
|
||||
IIAlu> {
|
||||
let rs = _rs;
|
||||
}
|
||||
|
||||
class LogicR_shift_rotate_reg64<bits<6> func, bits<5> _shamt, string instr_asm,
|
||||
SDNode OpNode>:
|
||||
FR<0x00, func, (outs CPU64Regs:$dst), (ins CPU64Regs:$c, CPU64Regs:$b),
|
||||
!strconcat(instr_asm, "\t$dst, $b, $c"),
|
||||
[(set CPU64Regs:$dst, (OpNode CPU64Regs:$b, CPU64Regs:$c))], IIAlu> {
|
||||
FR<0x00, func, (outs CPU64Regs:$rd), (ins CPU64Regs:$rs, CPU64Regs:$rt),
|
||||
!strconcat(instr_asm, "\t$rd, $rt, $rs"),
|
||||
[(set CPU64Regs:$rd, (OpNode CPU64Regs:$rt, CPU64Regs:$rs))], IIAlu> {
|
||||
let shamt = _shamt;
|
||||
}
|
||||
|
||||
// Mul, Div
|
||||
let Defs = [HI64, LO64] in {
|
||||
let rd = 0, shamt = 0, Defs = [HI64, LO64] in {
|
||||
let isCommutable = 1 in
|
||||
class Mul64<bits<6> func, string instr_asm, InstrItinClass itin>:
|
||||
FR<0x00, func, (outs), (ins CPU64Regs:$a, CPU64Regs:$b),
|
||||
!strconcat(instr_asm, "\t$a, $b"), [], itin>;
|
||||
FR<0x00, func, (outs), (ins CPU64Regs:$rs, CPU64Regs:$rt),
|
||||
!strconcat(instr_asm, "\t$rs, $rt"), [], itin>;
|
||||
|
||||
class Div64<SDNode op, bits<6> func, string instr_asm, InstrItinClass itin>:
|
||||
FR<0x00, func, (outs), (ins CPU64Regs:$a, CPU64Regs:$b),
|
||||
!strconcat(instr_asm, "\t$$zero, $a, $b"),
|
||||
[(op CPU64Regs:$a, CPU64Regs:$b)], itin>;
|
||||
FR<0x00, func, (outs), (ins CPU64Regs:$rs, CPU64Regs:$rt),
|
||||
!strconcat(instr_asm, "\t$$zero, $rs, $rt"),
|
||||
[(op CPU64Regs:$rs, CPU64Regs:$rt)], itin>;
|
||||
}
|
||||
|
||||
// Move from Hi/Lo
|
||||
let shamt = 0 in {
|
||||
let rs = 0, rt = 0 in
|
||||
class MoveFromLOHI64<bits<6> func, string instr_asm>:
|
||||
FR<0x00, func, (outs CPU64Regs:$dst), (ins),
|
||||
!strconcat(instr_asm, "\t$dst"), [], IIHiLo>;
|
||||
FR<0x00, func, (outs CPU64Regs:$rd), (ins),
|
||||
!strconcat(instr_asm, "\t$rd"), [], IIHiLo>;
|
||||
|
||||
let rt = 0, rd = 0 in
|
||||
class MoveToLOHI64<bits<6> func, string instr_asm>:
|
||||
FR<0x00, func, (outs), (ins CPU64Regs:$src),
|
||||
!strconcat(instr_asm, "\t$src"), [], IIHiLo>;
|
||||
FR<0x00, func, (outs), (ins CPU64Regs:$rs),
|
||||
!strconcat(instr_asm, "\t$rs"), [], IIHiLo>;
|
||||
}
|
||||
|
||||
// Count Leading Ones/Zeros in Word
|
||||
class CountLeading64<bits<6> func, string instr_asm, list<dag> pattern>:
|
||||
FR<0x1c, func, (outs CPU64Regs:$dst), (ins CPU64Regs:$src),
|
||||
!strconcat(instr_asm, "\t$dst, $src"), pattern, IIAlu>,
|
||||
FR<0x1c, func, (outs CPU64Regs:$rd), (ins CPU64Regs:$rs),
|
||||
!strconcat(instr_asm, "\t$rd, $rs"), pattern, IIAlu>,
|
||||
Requires<[HasBitCount]> {
|
||||
let shamt = 0;
|
||||
let rt = rd;
|
||||
@ -180,9 +180,9 @@ let Uses = [LO64] in
|
||||
|
||||
/// Count Leading
|
||||
def DCLZ : CountLeading64<0x24, "dclz",
|
||||
[(set CPU64Regs:$dst, (ctlz CPU64Regs:$src))]>;
|
||||
[(set CPU64Regs:$rd, (ctlz CPU64Regs:$rs))]>;
|
||||
def DCLO : CountLeading64<0x25, "dclo",
|
||||
[(set CPU64Regs:$dst, (ctlz (not CPU64Regs:$src)))]>;
|
||||
[(set CPU64Regs:$rd, (ctlz (not CPU64Regs:$rs)))]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Arbitrary patterns that map to one or more instructions
|
||||
|
@ -105,6 +105,9 @@ class MipsCodeEmitter : public MachineFunctionPass {
|
||||
unsigned getRelocation(const MachineInstr &MI,
|
||||
const MachineOperand &MO) const;
|
||||
|
||||
unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||
unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||
unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||
};
|
||||
}
|
||||
|
||||
@ -153,6 +156,28 @@ unsigned MipsCodeEmitter::getRelocation(const MachineInstr &MI,
|
||||
return Mips::reloc_mips_lo;
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getMemEncoding(const MachineInstr &MI,
|
||||
unsigned OpNo) const {
|
||||
// Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
|
||||
assert(MI.getOperand(OpNo).isReg());
|
||||
unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo)) << 16;
|
||||
return
|
||||
(getMachineOpValue(MI, MI.getOperand(OpNo+1)) & 0xFFFF) | RegBits;
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getSizeExtEncoding(const MachineInstr &MI,
|
||||
unsigned OpNo) const {
|
||||
// size is encoded as size-1.
|
||||
return getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI,
|
||||
unsigned OpNo) const {
|
||||
// size is encoded as pos+size-1.
|
||||
return getMachineOpValue(MI, MI.getOperand(OpNo-1)) +
|
||||
getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
|
||||
}
|
||||
|
||||
/// getMachineOpValue - Return binary encoding of operand. If the machine
|
||||
/// operand requires relocation, record the relocation and return zero.
|
||||
unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
|
||||
@ -238,8 +263,4 @@ FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
|
||||
return new MipsCodeEmitter(TM, JCE);
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const {
|
||||
// this function will be automatically generated by the CodeEmitterGenerator
|
||||
// using TableGen
|
||||
return 0;
|
||||
}
|
||||
#include "MipsGenCodeEmitter.inc"
|
||||
|
@ -76,14 +76,16 @@ def IsNotSingleFloat : Predicate<"!Subtarget.isSingleFloat()">;
|
||||
// FP load.
|
||||
class FPLoad<bits<6> op, string opstr, PatFrag FOp, RegisterClass RC,
|
||||
Operand MemOpnd>:
|
||||
FFI<op, (outs RC:$ft), (ins MemOpnd:$base),
|
||||
!strconcat(opstr, "\t$ft, $base"), [(set RC:$ft, (FOp addr:$base))]>;
|
||||
FMem<op, (outs RC:$ft), (ins MemOpnd:$addr),
|
||||
!strconcat(opstr, "\t$ft, $addr"), [(set RC:$ft, (FOp addr:$addr))],
|
||||
IILoad>;
|
||||
|
||||
// FP store.
|
||||
class FPStore<bits<6> op, string opstr, PatFrag FOp, RegisterClass RC,
|
||||
Operand MemOpnd>:
|
||||
FFI<op, (outs), (ins RC:$ft, MemOpnd:$base),
|
||||
!strconcat(opstr, "\t$ft, $base"), [(store RC:$ft, addr:$base)]>;
|
||||
FMem<op, (outs), (ins RC:$ft, MemOpnd:$addr),
|
||||
!strconcat(opstr, "\t$ft, $addr"), [(store RC:$ft, addr:$addr)],
|
||||
IIStore>;
|
||||
|
||||
// Instructions that convert an FP value to 32-bit fixed point.
|
||||
multiclass FFR1_W_M<bits<6> funct, string opstr> {
|
||||
@ -158,22 +160,28 @@ defm FSQRT : FFR1P_M<0x4, "sqrt", fsqrt>;
|
||||
// stores, and moves between floating-point and integer registers.
|
||||
// When defining instructions, we reference all 32-bit registers,
|
||||
// regardless of register aliasing.
|
||||
let fd = 0 in {
|
||||
/// Move Control Registers From/To CPU Registers
|
||||
def CFC1 : FFR<0x11, 0x0, 0x2, (outs CPURegs:$rt), (ins CCR:$fs),
|
||||
|
||||
class FFRGPR<bits<5> _fmt, dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
FFR<0x11, 0x0, _fmt, outs, ins, asmstr, pattern> {
|
||||
bits<5> rt;
|
||||
let ft = rt;
|
||||
let fd = 0;
|
||||
}
|
||||
|
||||
/// Move Control Registers From/To CPU Registers
|
||||
def CFC1 : FFRGPR<0x2, (outs CPURegs:$rt), (ins CCR:$fs),
|
||||
"cfc1\t$rt, $fs", []>;
|
||||
|
||||
def CTC1 : FFR<0x11, 0x0, 0x6, (outs CCR:$rt), (ins CPURegs:$fs),
|
||||
"ctc1\t$fs, $rt", []>;
|
||||
def CTC1 : FFRGPR<0x6, (outs CCR:$fs), (ins CPURegs:$rt),
|
||||
"ctc1\t$rt, $fs", []>;
|
||||
|
||||
def MFC1 : FFR<0x11, 0x00, 0x00, (outs CPURegs:$rt), (ins FGR32:$fs),
|
||||
def MFC1 : FFRGPR<0x00, (outs CPURegs:$rt), (ins FGR32:$fs),
|
||||
"mfc1\t$rt, $fs",
|
||||
[(set CPURegs:$rt, (bitconvert FGR32:$fs))]>;
|
||||
|
||||
def MTC1 : FFR<0x11, 0x00, 0x04, (outs FGR32:$fs), (ins CPURegs:$rt),
|
||||
def MTC1 : FFRGPR<0x04, (outs FGR32:$fs), (ins CPURegs:$rt),
|
||||
"mtc1\t$rt, $fs",
|
||||
[(set FGR32:$fs, (bitconvert CPURegs:$rt))]>;
|
||||
}
|
||||
|
||||
def FMOV_S : FFR1<0x6, 16, "mov", "s", FGR32, FGR32>;
|
||||
def FMOV_D32 : FFR1<0x6, 17, "mov", "d", AFGR64, AFGR64>,
|
||||
@ -203,7 +211,7 @@ let Predicates = [NotN64] in {
|
||||
}
|
||||
|
||||
/// Floating-point Aritmetic
|
||||
defm FADD : FFR2P_M<0x10, "add", fadd, 1>;
|
||||
defm FADD : FFR2P_M<0x00, "add", fadd, 1>;
|
||||
defm FDIV : FFR2P_M<0x03, "div", fdiv>;
|
||||
defm FMUL : FFR2P_M<0x02, "mul", fmul, 1>;
|
||||
defm FSUB : FFR2P_M<0x01, "sub", fsub>;
|
||||
@ -218,12 +226,16 @@ def MIPS_BRANCH_T : PatLeaf<(i32 1)>;
|
||||
|
||||
/// Floating Point Branch of False/True (Likely)
|
||||
let isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in
|
||||
class FBRANCH<PatLeaf op, string asmstr> : FFI<0x11, (outs),
|
||||
(ins brtarget:$dst), !strconcat(asmstr, "\t$dst"),
|
||||
[(MipsFPBrcond op, bb:$dst)]>;
|
||||
class FBRANCH<bits<1> nd, bits<1> tf, PatLeaf op, string asmstr> :
|
||||
FFI<0x11, (outs), (ins brtarget:$dst), !strconcat(asmstr, "\t$dst"),
|
||||
[(MipsFPBrcond op, bb:$dst)]> {
|
||||
let Inst{20-18} = 0;
|
||||
let Inst{17} = nd;
|
||||
let Inst{16} = tf;
|
||||
}
|
||||
|
||||
def BC1F : FBRANCH<MIPS_BRANCH_F, "bc1f">;
|
||||
def BC1T : FBRANCH<MIPS_BRANCH_T, "bc1t">;
|
||||
def BC1F : FBRANCH<0, 0, MIPS_BRANCH_F, "bc1f">;
|
||||
def BC1T : FBRANCH<0, 1, MIPS_BRANCH_T, "bc1t">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Floating Point Flag Conditions
|
||||
@ -249,11 +261,11 @@ def MIPS_FCOND_NGT : PatLeaf<(i32 15)>;
|
||||
|
||||
/// Floating Point Compare
|
||||
let Defs=[FCR31] in {
|
||||
def FCMP_S32 : FCC<0x0, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc),
|
||||
def FCMP_S32 : FCC<0x10, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc),
|
||||
"c.$cc.s\t$fs, $ft",
|
||||
[(MipsFPCmp FGR32:$fs, FGR32:$ft, imm:$cc)]>;
|
||||
|
||||
def FCMP_D32 : FCC<0x1, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc),
|
||||
def FCMP_D32 : FCC<0x11, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc),
|
||||
"c.$cc.d\t$fs, $ft",
|
||||
[(MipsFPCmp AFGR64:$fs, AFGR64:$ft, imm:$cc)]>,
|
||||
Requires<[NotFP64bit]>;
|
||||
@ -287,7 +299,8 @@ let Predicates = [NotFP64bit] in {
|
||||
defm : MovnPats<AFGR64, MOVN_D>;
|
||||
}
|
||||
|
||||
let usesCustomInserter = 1, Uses = [FCR31], Constraints = "$F = $dst" in {
|
||||
let cc = 0, usesCustomInserter = 1, Uses = [FCR31],
|
||||
Constraints = "$F = $dst" in {
|
||||
// flag:float, data:int
|
||||
class CondMovFPInt<SDNode cmov, bits<1> tf, string instr_asm> :
|
||||
FCMOV<tf, (outs CPURegs:$dst), (ins CPURegs:$T, CPURegs:$F),
|
||||
@ -295,6 +308,7 @@ class CondMovFPInt<SDNode cmov, bits<1> tf, string instr_asm> :
|
||||
[(set CPURegs:$dst, (cmov CPURegs:$T, CPURegs:$F))]>;
|
||||
|
||||
// flag:float, data:float
|
||||
let cc = 0 in
|
||||
class CondMovFPFP<RegisterClass RC, SDNode cmov, bits<5> fmt, bits<1> tf,
|
||||
string instr_asm> :
|
||||
FFCMOV<fmt, tf, (outs RC:$dst), (ins RC:$T, RC:$F),
|
||||
|
@ -21,30 +21,55 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// 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<4> val> {
|
||||
bits<4> Value = val;
|
||||
}
|
||||
|
||||
def Pseudo : Format<0>;
|
||||
def FrmR : Format<1>;
|
||||
def FrmI : Format<2>;
|
||||
def FrmJ : Format<3>;
|
||||
def FrmFR : Format<4>;
|
||||
def FrmFI : Format<5>;
|
||||
def FrmOther : Format<6>; // Instruction w/ a custom format
|
||||
|
||||
// Generic Mips Format
|
||||
class MipsInst<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin>: Instruction
|
||||
InstrItinClass itin, Format f>: Instruction
|
||||
{
|
||||
field bits<32> Inst;
|
||||
Format Form = f;
|
||||
|
||||
let Namespace = "Mips";
|
||||
|
||||
bits<6> opcode;
|
||||
bits<6> Opcode = 0;
|
||||
|
||||
// Top 5 bits are the 'opcode' field
|
||||
let Inst{31-26} = opcode;
|
||||
// Top 6 bits are the 'opcode' field
|
||||
let Inst{31-26} = Opcode;
|
||||
|
||||
dag OutOperandList = outs;
|
||||
dag InOperandList = ins;
|
||||
let OutOperandList = outs;
|
||||
let InOperandList = ins;
|
||||
|
||||
let AsmString = asmstr;
|
||||
let Pattern = pattern;
|
||||
let Itinerary = itin;
|
||||
|
||||
//
|
||||
// Attributes specific to Mips instructions...
|
||||
//
|
||||
bits<4> FormBits = Form.Value;
|
||||
|
||||
// TSFlags layout should be kept in sync with MipsInstrInfo.h.
|
||||
let TSFlags{3-0} = FormBits;
|
||||
}
|
||||
|
||||
// Mips Pseudo Instructions Format
|
||||
class MipsPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
MipsInst<outs, ins, asmstr, pattern, IIPseudo> {
|
||||
MipsInst<outs, ins, asmstr, pattern, IIPseudo, Pseudo> {
|
||||
let isCodeGenOnly = 1;
|
||||
let isPseudo = 1;
|
||||
}
|
||||
|
||||
@ -54,7 +79,7 @@ class MipsPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
|
||||
class FR<bits<6> op, bits<6> _funct, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern, InstrItinClass itin>:
|
||||
MipsInst<outs, ins, asmstr, pattern, itin>
|
||||
MipsInst<outs, ins, asmstr, pattern, itin, FrmR>
|
||||
{
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
@ -62,7 +87,7 @@ class FR<bits<6> op, bits<6> _funct, dag outs, dag ins, string asmstr,
|
||||
bits<5> shamt;
|
||||
bits<6> funct;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
let funct = _funct;
|
||||
|
||||
let Inst{25-21} = rs;
|
||||
@ -77,13 +102,13 @@ class FR<bits<6> op, bits<6> _funct, dag outs, dag ins, string asmstr,
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class FI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin>
|
||||
InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin, FrmI>
|
||||
{
|
||||
bits<5> rt;
|
||||
bits<5> rs;
|
||||
bits<16> imm16;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
|
||||
let Inst{25-21} = rs;
|
||||
let Inst{20-16} = rt;
|
||||
@ -92,13 +117,13 @@ class FI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
|
||||
class CBranchBase<bits<6> op, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern, InstrItinClass itin>:
|
||||
MipsInst<outs, ins, asmstr, pattern, itin>
|
||||
MipsInst<outs, ins, asmstr, pattern, itin, FrmI>
|
||||
{
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
bits<16> imm16;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
|
||||
let Inst{25-21} = rs;
|
||||
let Inst{20-16} = rt;
|
||||
@ -110,11 +135,11 @@ class CBranchBase<bits<6> op, dag outs, dag ins, string asmstr,
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class FJ<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin>
|
||||
InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin, FrmJ>
|
||||
{
|
||||
bits<26> addr;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
|
||||
let Inst{25-0} = addr;
|
||||
}
|
||||
@ -138,7 +163,7 @@ class FJ<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
|
||||
class FFR<bits<6> op, bits<6> _funct, bits<5> _fmt, dag outs, dag ins,
|
||||
string asmstr, list<dag> pattern> :
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary>
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmFR>
|
||||
{
|
||||
bits<5> fd;
|
||||
bits<5> fs;
|
||||
@ -146,7 +171,7 @@ class FFR<bits<6> op, bits<6> _funct, bits<5> _fmt, dag outs, dag ins,
|
||||
bits<5> fmt;
|
||||
bits<6> funct;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
let funct = _funct;
|
||||
let fmt = _fmt;
|
||||
|
||||
@ -162,13 +187,13 @@ class FFR<bits<6> op, bits<6> _funct, bits<5> _fmt, dag outs, dag ins,
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class FFI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary>
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmFI>
|
||||
{
|
||||
bits<5> ft;
|
||||
bits<5> base;
|
||||
bits<16> imm16;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
|
||||
let Inst{25-21} = base;
|
||||
let Inst{20-16} = ft;
|
||||
@ -180,14 +205,14 @@ class FFI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class FCC<bits<5> _fmt, dag outs, dag ins, string asmstr, list<dag> pattern> :
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary>
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmOther>
|
||||
{
|
||||
bits<5> fs;
|
||||
bits<5> ft;
|
||||
bits<4> cc;
|
||||
bits<5> fmt;
|
||||
|
||||
let opcode = 0x11;
|
||||
let Opcode = 0x11;
|
||||
let fmt = _fmt;
|
||||
|
||||
let Inst{25-21} = fmt;
|
||||
@ -201,18 +226,18 @@ class FCC<bits<5> _fmt, dag outs, dag ins, string asmstr, list<dag> pattern> :
|
||||
|
||||
class FCMOV<bits<1> _tf, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern> :
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary>
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmOther>
|
||||
{
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<3> N;
|
||||
bits<3> cc;
|
||||
bits<1> tf;
|
||||
|
||||
let opcode = 0;
|
||||
let Opcode = 0;
|
||||
let tf = _tf;
|
||||
|
||||
let Inst{25-21} = rs;
|
||||
let Inst{20-18} = N;
|
||||
let Inst{20-18} = cc;
|
||||
let Inst{17} = 0;
|
||||
let Inst{16} = tf;
|
||||
let Inst{15-11} = rd;
|
||||
@ -222,20 +247,20 @@ class FCMOV<bits<1> _tf, dag outs, dag ins, string asmstr,
|
||||
|
||||
class FFCMOV<bits<5> _fmt, bits<1> _tf, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern> :
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary>
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmOther>
|
||||
{
|
||||
bits<5> fd;
|
||||
bits<5> fs;
|
||||
bits<3> N;
|
||||
bits<3> cc;
|
||||
bits<5> fmt;
|
||||
bits<1> tf;
|
||||
|
||||
let opcode = 17;
|
||||
let Opcode = 17;
|
||||
let fmt = _fmt;
|
||||
let tf = _tf;
|
||||
|
||||
let Inst{25-21} = fmt;
|
||||
let Inst{20-18} = N;
|
||||
let Inst{20-18} = cc;
|
||||
let Inst{17} = 0;
|
||||
let Inst{16} = tf;
|
||||
let Inst{15-11} = fs;
|
||||
|
@ -153,6 +153,7 @@ def uimm16 : Operand<i32> {
|
||||
def mem : Operand<i32> {
|
||||
let PrintMethod = "printMemOperand";
|
||||
let MIOperandInfo = (ops CPURegs, simm16);
|
||||
let EncoderMethod = "getMemEncoding";
|
||||
}
|
||||
|
||||
def mem64 : Operand<i64> {
|
||||
@ -163,6 +164,17 @@ def mem64 : Operand<i64> {
|
||||
def mem_ea : Operand<i32> {
|
||||
let PrintMethod = "printMemOperandEA";
|
||||
let MIOperandInfo = (ops CPURegs, simm16);
|
||||
let EncoderMethod = "getMemEncoding";
|
||||
}
|
||||
|
||||
// size operand of ext instruction
|
||||
def size_ext : Operand<i32> {
|
||||
let EncoderMethod = "getSizeExtEncoding";
|
||||
}
|
||||
|
||||
// size operand of ins instruction
|
||||
def size_ins : Operand<i32> {
|
||||
let EncoderMethod = "getSizeInsEncoding";
|
||||
}
|
||||
|
||||
// Transformation Function - get the lower 16 bits.
|
||||
@ -271,14 +283,14 @@ class ArithOverflowR<bits<6> op, bits<6> func, string instr_asm,
|
||||
// Arithmetic and logical instructions with 2 register operands.
|
||||
class ArithLogicI<bits<6> op, string instr_asm, SDNode OpNode,
|
||||
Operand Od, PatLeaf imm_type, RegisterClass RC> :
|
||||
FI<op, (outs RC:$rt), (ins RC:$rs, Od:$i),
|
||||
!strconcat(instr_asm, "\t$rt, $rs, $i"),
|
||||
[(set RC:$rt, (OpNode RC:$rs, imm_type:$i))], IIAlu>;
|
||||
FI<op, (outs RC:$rt), (ins RC:$rs, Od:$imm16),
|
||||
!strconcat(instr_asm, "\t$rt, $rs, $imm16"),
|
||||
[(set RC:$rt, (OpNode RC:$rs, imm_type:$imm16))], IIAlu>;
|
||||
|
||||
class ArithOverflowI<bits<6> op, string instr_asm, SDNode OpNode,
|
||||
Operand Od, PatLeaf imm_type, RegisterClass RC> :
|
||||
FI<op, (outs RC:$rt), (ins RC:$rs, Od:$i),
|
||||
!strconcat(instr_asm, "\t$rt, $rs, $i"), [], IIAlu>;
|
||||
FI<op, (outs RC:$rt), (ins RC:$rs, Od:$imm16),
|
||||
!strconcat(instr_asm, "\t$rt, $rs, $imm16"), [], IIAlu>;
|
||||
|
||||
// Arithmetic Multiply ADD/SUB
|
||||
let rd = 0, shamt = 0, Defs = [HI, LO], Uses = [HI, LO] in
|
||||
@ -319,16 +331,23 @@ class LogicR_shift_rotate_reg<bits<6> func, bits<5> isRotate, string instr_asm,
|
||||
|
||||
// Load Upper Imediate
|
||||
class LoadUpper<bits<6> op, string instr_asm>:
|
||||
FI<op, (outs CPURegs:$rt), (ins uimm16:$imm),
|
||||
!strconcat(instr_asm, "\t$rt, $imm"), [], IIAlu> {
|
||||
FI<op, (outs CPURegs:$rt), (ins uimm16:$imm16),
|
||||
!strconcat(instr_asm, "\t$rt, $imm16"), [], IIAlu> {
|
||||
let rs = 0;
|
||||
}
|
||||
|
||||
class FMem<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin>: FFI<op, outs, ins, asmstr, pattern> {
|
||||
bits<21> addr;
|
||||
let Inst{25-21} = addr{20-16};
|
||||
let Inst{15-0} = addr{15-0};
|
||||
}
|
||||
|
||||
// Memory Load/Store
|
||||
let canFoldAsLoad = 1 in
|
||||
class LoadM<bits<6> op, string instr_asm, PatFrag OpNode, RegisterClass RC,
|
||||
Operand MemOpnd, bit Pseudo>:
|
||||
FI<op, (outs RC:$rt), (ins MemOpnd:$addr),
|
||||
FMem<op, (outs RC:$rt), (ins MemOpnd:$addr),
|
||||
!strconcat(instr_asm, "\t$rt, $addr"),
|
||||
[(set RC:$rt, (OpNode addr:$addr))], IILoad> {
|
||||
let isPseudo = Pseudo;
|
||||
@ -336,7 +355,7 @@ class LoadM<bits<6> op, string instr_asm, PatFrag OpNode, RegisterClass RC,
|
||||
|
||||
class StoreM<bits<6> op, string instr_asm, PatFrag OpNode, RegisterClass RC,
|
||||
Operand MemOpnd, bit Pseudo>:
|
||||
FI<op, (outs), (ins RC:$rt, MemOpnd:$addr),
|
||||
FMem<op, (outs), (ins RC:$rt, MemOpnd:$addr),
|
||||
!strconcat(instr_asm, "\t$rt, $addr"),
|
||||
[(OpNode RC:$rt, addr:$addr)], IIStore> {
|
||||
let isPseudo = Pseudo;
|
||||
@ -380,9 +399,9 @@ multiclass StoreM64<bits<6> op, string instr_asm, PatFrag OpNode,
|
||||
|
||||
// Conditional Branch
|
||||
class CBranch<bits<6> op, string instr_asm, PatFrag cond_op, RegisterClass RC>:
|
||||
CBranchBase<op, (outs), (ins RC:$rs, RC:$rt, brtarget:$offset),
|
||||
!strconcat(instr_asm, "\t$rs, $rt, $offset"),
|
||||
[(brcond (i32 (cond_op RC:$rs, RC:$rt)), bb:$offset)], IIBranch> {
|
||||
CBranchBase<op, (outs), (ins RC:$rs, RC:$rt, brtarget:$imm16),
|
||||
!strconcat(instr_asm, "\t$rs, $rt, $imm16"),
|
||||
[(brcond (i32 (cond_op RC:$rs, RC:$rt)), bb:$imm16)], IIBranch> {
|
||||
let isBranch = 1;
|
||||
let isTerminator = 1;
|
||||
let hasDelaySlot = 1;
|
||||
@ -390,9 +409,9 @@ class CBranch<bits<6> op, string instr_asm, PatFrag cond_op, RegisterClass RC>:
|
||||
|
||||
class CBranchZero<bits<6> op, bits<5> _rt, string instr_asm, PatFrag cond_op,
|
||||
RegisterClass RC>:
|
||||
CBranchBase<op, (outs), (ins RC:$rs, brtarget:$offset),
|
||||
!strconcat(instr_asm, "\t$rs, $offset"),
|
||||
[(brcond (i32 (cond_op RC:$rs, 0)), bb:$offset)], IIBranch> {
|
||||
CBranchBase<op, (outs), (ins RC:$rs, brtarget:$imm16),
|
||||
!strconcat(instr_asm, "\t$rs, $imm16"),
|
||||
[(brcond (i32 (cond_op RC:$rs, 0)), bb:$imm16)], IIBranch> {
|
||||
let rt = _rt;
|
||||
let isBranch = 1;
|
||||
let isTerminator = 1;
|
||||
@ -411,9 +430,9 @@ class SetCC_R<bits<6> op, bits<6> func, string instr_asm, PatFrag cond_op,
|
||||
|
||||
class SetCC_I<bits<6> op, string instr_asm, PatFrag cond_op, Operand Od,
|
||||
PatLeaf imm_type, RegisterClass RC>:
|
||||
FI<op, (outs CPURegs:$rd), (ins RC:$rs, Od:$i),
|
||||
!strconcat(instr_asm, "\t$rd, $rs, $i"),
|
||||
[(set CPURegs:$rd, (cond_op RC:$rs, imm_type:$i))],
|
||||
FI<op, (outs CPURegs:$rt), (ins RC:$rs, Od:$imm16),
|
||||
!strconcat(instr_asm, "\t$rt, $rs, $imm16"),
|
||||
[(set CPURegs:$rt, (cond_op RC:$rs, imm_type:$imm16))],
|
||||
IIAlu>;
|
||||
|
||||
// Unconditional branch
|
||||
@ -450,10 +469,8 @@ let isCall=1, hasDelaySlot=1,
|
||||
}
|
||||
|
||||
class BranchLink<string instr_asm>:
|
||||
FI<0x1, (outs), (ins CPURegs:$rs, brtarget:$target, variable_ops),
|
||||
!strconcat(instr_asm, "\t$rs, $target"), [], IIBranch> {
|
||||
let rt = 0;
|
||||
}
|
||||
FI<0x1, (outs), (ins CPURegs:$rs, brtarget:$imm16, variable_ops),
|
||||
!strconcat(instr_asm, "\t$rs, $imm16"), [], IIBranch>;
|
||||
}
|
||||
|
||||
// Mul, Div
|
||||
@ -493,7 +510,7 @@ class MoveToLOHI<bits<6> func, string instr_asm>:
|
||||
}
|
||||
|
||||
class EffectiveAddress<string instr_asm> :
|
||||
FI<0x09, (outs CPURegs:$rt), (ins mem_ea:$addr),
|
||||
FMem<0x09, (outs CPURegs:$rt), (ins mem_ea:$addr),
|
||||
instr_asm, [(set CPURegs:$rt, addr:$addr)], IIAlu>;
|
||||
|
||||
// Count Leading Ones/Zeros in Word
|
||||
@ -507,7 +524,7 @@ class CountLeading<bits<6> func, string instr_asm, list<dag> pattern>:
|
||||
|
||||
// Sign Extend in Register.
|
||||
class SignExtInReg<bits<5> sa, string instr_asm, ValueType vt>:
|
||||
FR<0x3f, 0x20, (outs CPURegs:$rd), (ins CPURegs:$rt),
|
||||
FR<0x1f, 0x20, (outs CPURegs:$rd), (ins CPURegs:$rt),
|
||||
!strconcat(instr_asm, "\t$rd, $rt"),
|
||||
[(set CPURegs:$rd, (sext_inreg CPURegs:$rt, vt))], NoItinerary> {
|
||||
let rs = 0;
|
||||
@ -685,20 +702,22 @@ defm USW : StoreM32<0x2b, "usw", store_u, 1>;
|
||||
|
||||
let hasSideEffects = 1 in
|
||||
def SYNC : MipsInst<(outs), (ins i32imm:$stype), "sync $stype",
|
||||
[(MipsSync imm:$stype)], NoItinerary>
|
||||
[(MipsSync imm:$stype)], NoItinerary, FrmOther>
|
||||
{
|
||||
let opcode = 0;
|
||||
bits<5> stype;
|
||||
let Opcode = 0;
|
||||
let Inst{25-11} = 0;
|
||||
let Inst{10-6} = stype;
|
||||
let Inst{5-0} = 15;
|
||||
}
|
||||
|
||||
/// Load-linked, Store-conditional
|
||||
let mayLoad = 1 in
|
||||
def LL : FI<0x30, (outs CPURegs:$dst), (ins mem:$addr),
|
||||
"ll\t$dst, $addr", [], IILoad>;
|
||||
let mayStore = 1, Constraints = "$src = $dst" in
|
||||
def SC : FI<0x38, (outs CPURegs:$dst), (ins CPURegs:$src, mem:$addr),
|
||||
"sc\t$src, $addr", [], IIStore>;
|
||||
def LL : FMem<0x30, (outs CPURegs:$rt), (ins mem:$addr),
|
||||
"ll\t$rt, $addr", [], IILoad>;
|
||||
let mayStore = 1, Constraints = "$rt = $dst" in
|
||||
def SC : FMem<0x38, (outs CPURegs:$dst), (ins CPURegs:$rt, mem:$addr),
|
||||
"sc\t$rt, $addr", [], IIStore>;
|
||||
|
||||
/// Jump and Branch Instructions
|
||||
def J : JumpFJ<0x02, "j">;
|
||||
@ -710,15 +729,17 @@ def BEQ : CBranch<0x04, "beq", seteq, CPURegs>;
|
||||
def BNE : CBranch<0x05, "bne", setne, CPURegs>;
|
||||
def BGEZ : CBranchZero<0x01, 1, "bgez", setge, CPURegs>;
|
||||
def BGTZ : CBranchZero<0x07, 0, "bgtz", setgt, CPURegs>;
|
||||
def BLEZ : CBranchZero<0x07, 0, "blez", setle, CPURegs>;
|
||||
def BLEZ : CBranchZero<0x06, 0, "blez", setle, CPURegs>;
|
||||
def BLTZ : CBranchZero<0x01, 0, "bltz", setlt, CPURegs>;
|
||||
|
||||
def BGEZAL : BranchLink<"bgezal">;
|
||||
def BLTZAL : BranchLink<"bltzal">;
|
||||
let rt=0x11 in
|
||||
def BGEZAL : BranchLink<"bgezal">;
|
||||
let rt=0x10 in
|
||||
def BLTZAL : BranchLink<"bltzal">;
|
||||
|
||||
let isReturn=1, isTerminator=1, hasDelaySlot=1,
|
||||
isBarrier=1, hasCtrlDep=1, rs=0, rt=0, shamt=0 in
|
||||
def RET : FR <0x00, 0x02, (outs), (ins CPURegs:$target),
|
||||
isBarrier=1, hasCtrlDep=1, rd=0, rt=0, shamt=0 in
|
||||
def RET : FR <0x00, 0x08, (outs), (ins CPURegs:$target),
|
||||
"jr\t$target", [(MipsRet CPURegs:$target)], IIBranch>;
|
||||
|
||||
/// Multiply and Divide Instructions.
|
||||
@ -797,14 +818,14 @@ def MUL : ArithLogicR<0x1c, 0x02, "mul", mul, IIImul, CPURegs, 1>,
|
||||
def RDHWR : ReadHardware;
|
||||
|
||||
def EXT : ExtIns<0, "ext", (outs CPURegs:$rt),
|
||||
(ins CPURegs:$rs, uimm16:$pos, uimm16:$sz),
|
||||
(ins CPURegs:$rs, uimm16:$pos, size_ext:$sz),
|
||||
[(set CPURegs:$rt,
|
||||
(MipsExt CPURegs:$rs, immZExt5:$pos, immZExt5:$sz))],
|
||||
NoItinerary>;
|
||||
|
||||
let Constraints = "$src = $rt" in
|
||||
def INS : ExtIns<4, "ins", (outs CPURegs:$rt),
|
||||
(ins CPURegs:$rs, uimm16:$pos, uimm16:$sz, CPURegs:$src),
|
||||
(ins CPURegs:$rs, uimm16:$pos, size_ins:$sz, CPURegs:$src),
|
||||
[(set CPURegs:$rt,
|
||||
(MipsIns CPURegs:$rs, immZExt5:$pos, immZExt5:$sz,
|
||||
CPURegs:$src))],
|
||||
|
@ -57,11 +57,11 @@ void MipsCompilationCallback();
|
||||
".globl " ASMPREFIX "MipsCompilationCallback\n"
|
||||
ASMPREFIX "MipsCompilationCallback:\n"
|
||||
".ent " ASMPREFIX "MipsCompilationCallback\n"
|
||||
".frame $29, 32, $31\n"
|
||||
".frame $sp, 32, $ra\n"
|
||||
".set noreorder\n"
|
||||
".cpload $t9\n"
|
||||
|
||||
"addiu $sp, $sp, -60\n"
|
||||
"addiu $sp, $sp, -64\n"
|
||||
".cprestore 16\n"
|
||||
|
||||
// Save argument registers a0, a1, a2, a3, f12, f14 since they may contain
|
||||
@ -76,8 +76,8 @@ void MipsCompilationCallback();
|
||||
"sw $a3, 32($sp)\n"
|
||||
"sw $ra, 36($sp)\n"
|
||||
"sw $t8, 40($sp)\n"
|
||||
"sdc1 $f12, 44($sp)\n"
|
||||
"sdc1 $f14, 52($sp)\n"
|
||||
"sdc1 $f12, 48($sp)\n"
|
||||
"sdc1 $f14, 56($sp)\n"
|
||||
|
||||
// t8 points at the end of function stub. Pass the beginning of the stub
|
||||
// to the MipsCompilationCallbackC.
|
||||
@ -92,9 +92,9 @@ void MipsCompilationCallback();
|
||||
"lw $a3, 32($sp)\n"
|
||||
"lw $ra, 36($sp)\n"
|
||||
"lw $t8, 40($sp)\n"
|
||||
"ldc1 $f12, 44($sp)\n"
|
||||
"ldc1 $f14, 52($sp)\n"
|
||||
"addiu $sp, $sp, 60\n"
|
||||
"ldc1 $f12, 48($sp)\n"
|
||||
"ldc1 $f14, 56($sp)\n"
|
||||
"addiu $sp, $sp, 64\n"
|
||||
|
||||
// Jump to the (newly modified) stub to invoke the real function.
|
||||
"addiu $t8, $t8, -16\n"
|
||||
|
@ -490,10 +490,8 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||
|
||||
// This is a bit of a hack: CR2LT, CR2GT, CR2EQ and CR2UN are just
|
||||
// subregisters of CR2. We just need to emit a move of CR2.
|
||||
if (Reg == PPC::CR2LT || Reg == PPC::CR2GT || Reg == PPC::CR2EQ)
|
||||
if (PPC::CRBITRCRegisterClass->contains(Reg))
|
||||
continue;
|
||||
if (Reg == PPC::CR2UN)
|
||||
Reg = PPC::CR2;
|
||||
|
||||
MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
|
||||
MachineLocation CSSrc(Reg);
|
||||
|
@ -589,6 +589,13 @@ void Emitter<CodeEmitter>::emitMemModRMByte(const MachineInstr &MI,
|
||||
}
|
||||
}
|
||||
|
||||
static const MCInstrDesc *UpdateOp(MachineInstr &MI, const X86InstrInfo *II,
|
||||
unsigned Opcode) {
|
||||
const MCInstrDesc *Desc = &II->get(Opcode);
|
||||
MI.setDesc(*Desc);
|
||||
return Desc;
|
||||
}
|
||||
|
||||
template<class CodeEmitter>
|
||||
void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
|
||||
const MCInstrDesc *Desc) {
|
||||
@ -596,15 +603,23 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
|
||||
|
||||
// If this is a pseudo instruction, lower it.
|
||||
switch (Desc->getOpcode()) {
|
||||
case X86::ADD16rr_DB: Desc = &II->get(X86::OR16rr); MI.setDesc(*Desc);break;
|
||||
case X86::ADD32rr_DB: Desc = &II->get(X86::OR32rr); MI.setDesc(*Desc);break;
|
||||
case X86::ADD64rr_DB: Desc = &II->get(X86::OR64rr); MI.setDesc(*Desc);break;
|
||||
case X86::ADD16ri_DB: Desc = &II->get(X86::OR16ri); MI.setDesc(*Desc);break;
|
||||
case X86::ADD32ri_DB: Desc = &II->get(X86::OR32ri); MI.setDesc(*Desc);break;
|
||||
case X86::ADD64ri32_DB:Desc = &II->get(X86::OR64ri32);MI.setDesc(*Desc);break;
|
||||
case X86::ADD16ri8_DB: Desc = &II->get(X86::OR16ri8);MI.setDesc(*Desc);break;
|
||||
case X86::ADD32ri8_DB: Desc = &II->get(X86::OR32ri8);MI.setDesc(*Desc);break;
|
||||
case X86::ADD64ri8_DB: Desc = &II->get(X86::OR64ri8);MI.setDesc(*Desc);break;
|
||||
case X86::ADD16rr_DB: Desc = UpdateOp(MI, II, X86::OR16rr); break;
|
||||
case X86::ADD32rr_DB: Desc = UpdateOp(MI, II, X86::OR32rr); break;
|
||||
case X86::ADD64rr_DB: Desc = UpdateOp(MI, II, X86::OR64rr); break;
|
||||
case X86::ADD16ri_DB: Desc = UpdateOp(MI, II, X86::OR16ri); break;
|
||||
case X86::ADD32ri_DB: Desc = UpdateOp(MI, II, X86::OR32ri); break;
|
||||
case X86::ADD64ri32_DB: Desc = UpdateOp(MI, II, X86::OR64ri32); break;
|
||||
case X86::ADD16ri8_DB: Desc = UpdateOp(MI, II, X86::OR16ri8); break;
|
||||
case X86::ADD32ri8_DB: Desc = UpdateOp(MI, II, X86::OR32ri8); break;
|
||||
case X86::ADD64ri8_DB: Desc = UpdateOp(MI, II, X86::OR64ri8); break;
|
||||
case X86::ACQUIRE_MOV8rm: Desc = UpdateOp(MI, II, X86::MOV8rm); break;
|
||||
case X86::ACQUIRE_MOV16rm: Desc = UpdateOp(MI, II, X86::MOV16rm); break;
|
||||
case X86::ACQUIRE_MOV32rm: Desc = UpdateOp(MI, II, X86::MOV32rm); break;
|
||||
case X86::ACQUIRE_MOV64rm: Desc = UpdateOp(MI, II, X86::MOV64rm); break;
|
||||
case X86::RELEASE_MOV8mr: Desc = UpdateOp(MI, II, X86::MOV8mr); break;
|
||||
case X86::RELEASE_MOV16mr: Desc = UpdateOp(MI, II, X86::MOV16mr); break;
|
||||
case X86::RELEASE_MOV32mr: Desc = UpdateOp(MI, II, X86::MOV32mr); break;
|
||||
case X86::RELEASE_MOV64mr: Desc = UpdateOp(MI, II, X86::MOV64mr); break;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2025,9 +2025,10 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) {
|
||||
BasicBlock *InstParent = I->getParent();
|
||||
BasicBlock::iterator InsertPos = I;
|
||||
|
||||
if (!isa<PHINode>(Result)) // If combining a PHI, don't insert
|
||||
while (isa<PHINode>(InsertPos)) // middle of a block of PHIs.
|
||||
++InsertPos;
|
||||
// If we replace a PHI with something that isn't a PHI, fix up the
|
||||
// insertion point.
|
||||
if (!isa<PHINode>(Result) && isa<PHINode>(InsertPos))
|
||||
InsertPos = InstParent->getFirstInsertionPt();
|
||||
|
||||
InstParent->getInstList().insert(InsertPos, Result);
|
||||
|
||||
|
36
test/CodeGen/ARM/gv-stubs-crash.ll
Normal file
36
test/CodeGen/ARM/gv-stubs-crash.ll
Normal file
@ -0,0 +1,36 @@
|
||||
; RUN: llc < %s -mtriple=thumbv7-apple-ios -relocation-model=pic
|
||||
; <rdar://problem/10336715>
|
||||
|
||||
@Exn = external hidden unnamed_addr constant { i8*, i8* }
|
||||
|
||||
define hidden void @func(i32* %this, i32* %e) optsize align 2 {
|
||||
%e.ld = load i32* %e, align 4
|
||||
%inv = invoke zeroext i1 @func2(i32* %this, i32 %e.ld) optsize
|
||||
to label %ret unwind label %lpad
|
||||
|
||||
ret:
|
||||
ret void
|
||||
|
||||
lpad:
|
||||
%lp = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*)
|
||||
catch i8* bitcast ({ i8*, i8* }* @Exn to i8*)
|
||||
br label %.loopexit4
|
||||
|
||||
.loopexit4:
|
||||
%exn = call i8* @__cxa_allocate_exception(i32 8) nounwind
|
||||
call void @__cxa_throw(i8* %exn, i8* bitcast ({ i8*, i8* }* @Exn to i8*), i8* bitcast (void (i32*)* @dtor to i8*)) noreturn
|
||||
unreachable
|
||||
|
||||
resume:
|
||||
resume { i8*, i32 } %lp
|
||||
}
|
||||
|
||||
declare hidden zeroext i1 @func2(i32*, i32) optsize align 2
|
||||
|
||||
declare i8* @__cxa_allocate_exception(i32)
|
||||
|
||||
declare i32 @__gxx_personality_sj0(...)
|
||||
|
||||
declare void @dtor(i32*) optsize
|
||||
|
||||
declare void @__cxa_throw(i8*, i8*, i8*)
|
@ -1,3 +1,7 @@
|
||||
; PR11218
|
||||
; FIXME: This depends on assertion failure for now.
|
||||
; REQUIRES: asserts
|
||||
|
||||
; RUN: llc < %s
|
||||
; XFAIL: *
|
||||
; PR2356
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: llc < %s | FileCheck %s
|
||||
; RUN: llc -mtriple=x86_64-linux < %s | FileCheck %s
|
||||
|
||||
; CHECK: DW_AT_const_value
|
||||
; CHECK-NEXT: 42
|
||||
|
@ -22,7 +22,7 @@ entry:
|
||||
|
||||
|
||||
; make sure that bl 0 <foo> (fff7feff) is correctly encoded
|
||||
; CHECK: '_section_data', '704700bf 2de90048 fff7feff bde80008'
|
||||
; CHECK: '_section_data', '704700bf 2de90048 fff7feff bde80088'
|
||||
|
||||
; Offset Info Type Sym.Value Sym. Name
|
||||
; 00000008 0000070a R_ARM_THM_CALL 00000001 foo
|
||||
|
@ -1,6 +1,7 @@
|
||||
// RUN: llvm-mc %s
|
||||
// RUN: llvm-mc -triple i386-unknown-unknown %s
|
||||
movl %gs:8, %eax
|
||||
// RUN: llvm-mc %s
|
||||
// RUN: llvm-mc -triple i386-unknown-unknown %s
|
||||
movl %gs:8, %eax
|
||||
// RUN: llvm-mc %s
|
||||
// RUN: llvm-mc -triple i386-unknown-unknown %s
|
||||
movl %gs:8, %eax
|
||||
|
@ -374,3 +374,28 @@ for.inc: ; preds = %for.cond
|
||||
return: ; No predecessors!
|
||||
ret void
|
||||
}
|
||||
|
||||
; PR11275
|
||||
declare void @test18b() noreturn
|
||||
declare void @test18foo(double**)
|
||||
declare void @test18a() noreturn
|
||||
define fastcc void @test18x(i8* %t0, i1 %b) uwtable align 2 {
|
||||
entry:
|
||||
br i1 %b, label %e1, label %e2
|
||||
e1:
|
||||
%t2 = bitcast i8* %t0 to double**
|
||||
invoke void @test18b() noreturn
|
||||
to label %u unwind label %lpad
|
||||
e2:
|
||||
%t4 = bitcast i8* %t0 to double**
|
||||
invoke void @test18a() noreturn
|
||||
to label %u unwind label %lpad
|
||||
lpad:
|
||||
%t5 = phi double** [ %t2, %e1 ], [ %t4, %e2 ]
|
||||
%lpad.nonloopexit262 = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
|
||||
cleanup
|
||||
call void @test18foo(double** %t5)
|
||||
unreachable
|
||||
u:
|
||||
unreachable
|
||||
}
|
||||
|
@ -192,9 +192,9 @@ static void SortAndPrintSymbolList() {
|
||||
strcpy(SymbolSizeStr, " ");
|
||||
|
||||
if (i->Address != object::UnknownAddressOrSize)
|
||||
format("%08x", i->Address).print(SymbolAddrStr, sizeof(SymbolAddrStr));
|
||||
format("%08"PRIx64, i->Address).print(SymbolAddrStr, sizeof(SymbolAddrStr));
|
||||
if (i->Size != object::UnknownAddressOrSize)
|
||||
format("%08x", i->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));
|
||||
format("%08"PRIx64, i->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));
|
||||
|
||||
if (OutputFormat == posix) {
|
||||
outs() << i->Name << " " << i->TypeChar << " "
|
||||
|
@ -285,7 +285,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
|
||||
|
||||
if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
|
||||
DebugOut, nulls())) {
|
||||
outs() << format("%8x:\t", SectionAddr + Index);
|
||||
outs() << format("%8"PRIx64":\t", SectionAddr + Index);
|
||||
DumpBytes(StringRef(Bytes.data() + Index, Size));
|
||||
IP->printInst(&Inst, outs(), "");
|
||||
outs() << "\n";
|
||||
@ -306,7 +306,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
|
||||
if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
|
||||
if (error(rel_cur->getValueString(val))) goto skip_print_rel;
|
||||
|
||||
outs() << format("\t\t\t%8x: ", SectionAddr + addr) << name << "\t"
|
||||
outs() << format("\t\t\t%8"PRIx64": ", SectionAddr + addr) << name << "\t"
|
||||
<< val << "\n";
|
||||
|
||||
skip_print_rel:
|
||||
|
@ -171,11 +171,11 @@ function export_sources() {
|
||||
echo "# Creating symlinks"
|
||||
cd $BuildDir/llvm.src/tools
|
||||
if [ ! -h clang ]; then
|
||||
ln -s $BuildDir/cfe.src clang
|
||||
ln -s ../../cfe.src clang
|
||||
fi
|
||||
cd $BuildDir/llvm.src/projects
|
||||
if [ ! -h llvm-test ]; then
|
||||
ln -s $BuildDir/test-suite.src llvm-test
|
||||
ln -s ../../test-suite.src llvm-test
|
||||
fi
|
||||
cd $BuildDir
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user