summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--doc/building.xml82
-rw-r--r--doc/concepts.xml251
-rw-r--r--doc/opcode_table.xml897
-rw-r--r--doc/opcodes.xml101
-rw-r--r--doc/orc-docs.sgml8
-rw-r--r--doc/orc-sections.txt24
-rw-r--r--doc/table.xml786
-rw-r--r--examples/Makefile.am6
-rw-r--r--examples/example1.c74
-rw-r--r--examples/jit.c89
-rw-r--r--examples/mt19937ar.c32
-rw-r--r--examples/simple.c613
-rw-r--r--orc/orc.c7
-rw-r--r--orc/orccompiler.c65
-rw-r--r--orc/orcdebug.c2
-rw-r--r--orc/orcdebug.h21
-rw-r--r--orc/orcpowerpc.c6
-rw-r--r--orc/orcprogram-arm.c2
-rw-r--r--orc/orcprogram.c229
-rw-r--r--orc/orcprogram.h59
-rw-r--r--orc/orcrules-mmx.c2
-rw-r--r--testsuite/Makefile.am2
-rw-r--r--testsuite/generate_xml_table.c100
-rw-r--r--testsuite/generate_xml_table2.c230
25 files changed, 2954 insertions, 735 deletions
diff --git a/configure.ac b/configure.ac
index 73d5e59..18bee8e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -117,6 +117,7 @@ AC_SUBST(orcbindir)
AC_CONFIG_FILES([
Makefile
doc/Makefile
+doc/version.entities
orc/Makefile
orc-float/Makefile
orc-pixel/Makefile
diff --git a/doc/building.xml b/doc/building.xml
new file mode 100644
index 0000000..d65e10c
--- /dev/null
+++ b/doc/building.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+<!ENTITY % version-entities SYSTEM "version.entities">
+%version-entities;
+<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
+]>
+<refentry id="orc-building" revision="29 may 2009">
+<refmeta>
+<refentrytitle>Building Orc and Applications That Use Orc</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>Orc</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>Building Orc and Applications that use Orc</refname>
+<refpurpose>
+How to build Orc and applications using it.
+</refpurpose>
+</refnamediv>
+
+<refsect1>
+<title>Building Orc on UNIX</title>
+
+ <!-- this has been borrowed from the glib docs via gstreamer -->
+ <para>
+ On UNIX, Orc uses the standard GNU build system,
+ using <application>autoconf</application> for package
+ configuration and resolving portability issues,
+ <application>automake</application> for building makefiles
+ that comply with the GNU Coding Standards, and
+ <application>libtool</application> for building shared
+ libraries on multiple platforms. The normal sequence for
+ compiling and installing the Orc library is thus:
+
+ <literallayout>
+ <userinput>./configure</userinput>
+ <userinput>make</userinput>
+ <userinput>make install</userinput>
+ </literallayout>
+ </para>
+
+ <para>
+ The standard options provided by <application>GNU
+ autoconf</application> may be passed to the
+ <command>configure</command> script. Please see the
+ <application>autoconf</application> documentation or run
+ <command>./configure --help</command> for information about
+ the standard options.
+ </para>
+
+ <para>
+ Future releases will have configure options that allow Orc
+ to be compiled in a minimal configuration for embedded systems.
+ This functionality is not yet available for general use.
+ </para>
+
+</refsect1>
+
+<refsect1>
+<title>Building Orc Applications</title>
+
+<para>
+Applications and libraries can use <command>pkg-config</command> to get all the
+needed compiler and linker flags to build against Orc. The following
+commands will provide the necessary compiler and linker flags:
+
+<literallayout>
+ <userinput>pkg-config --cflags orc-&ORC_MAJORMINOR;</userinput>
+ <userinput>pkg-config --libs orc-&ORC_MAJORMINOR;</userinput>
+</literallayout>
+</para>
+
+<para>
+When compiling from source, the default installation directory is not
+in the default path for the <command>pkg-config</command>, so you may
+need to set the PKG_CONFIG_DIR environment variable.
+</para>
+
+</refsect1>
+
+</refentry>
diff --git a/doc/concepts.xml b/doc/concepts.xml
new file mode 100644
index 0000000..c15a185
--- /dev/null
+++ b/doc/concepts.xml
@@ -0,0 +1,251 @@
+<?xml version="1.0"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+<!ENTITY % version-entities SYSTEM "version.entities">
+%version-entities;
+<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
+]>
+<refentry id="orc-concepts" revision="29 may 2009">
+<refmeta>
+<refentrytitle>Orc Concepts</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>Orc</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>Orc Concepts</refname>
+<refpurpose>
+High-level view of what Orc does.
+</refpurpose>
+</refnamediv>
+
+<refsect1>
+<title>Orc Concepts</title>
+
+ <para>
+ Orc is a compiler for a simple assembly-like language. Unlike
+ most compilers, Orc is primarily a library, which means that
+ all its features can be controlled from any application that
+ uses it. Also unlike most compilers, Orc creates code that
+ can be immediately exectued by the application.
+ </para>
+
+ <para>
+ Orc is mainly useful for generating code that performs simple
+ mathematical operations on continguous arrays. An example Orc
+ function, translated to C, might look like:
+
+ <programlisting>
+ void function (int *dest, int *src1, int *src2, int n)
+ {
+ int i;
+ for (i = 0; i &lt; n; i++) {
+ dest[i] = (src1[i] + src2[i] + 1) >> 1;
+ }
+ }
+ </programlisting>
+
+ </para>
+
+ <para>
+ Orc is primarily targetted toward generating code for vector
+ CPU extensions such as SSE, Altivec, and NEON.
+ </para>
+
+ <para>
+ Possible usage patterns:
+ </para>
+
+ <para>
+ The application generates Orc code programmatically.
+ Generate Orc programs programmatically at runtime, compile at
+ runtime, and execute. This is what many of the Orc test programs
+ do, and is the most flexible and well-developed method at this
+ time. This requires depending on the Orc library at runtime.
+ </para>
+
+ <para>
+ The application developer uses Orc to produce assembly source
+ code that is then compiled into the application. This requires
+ the developer to have Orc installed at build time. The advantage
+ of this method is no Orc dependency at runtime. Disadvantages
+ are a more complex build process, potential for compiler
+ incompatibilities with generated assembly source code, and any
+ Orc improvements require the application to be recompiled.
+ </para>
+
+ <para>
+ The application developer writes Orc source files, and compiles
+ them into Orc bytecode to be included in the application. At
+ runtime, Orc compiles the bytecode into executable code. This
+ has the advantage of being easily editable. This method is
+ still somewhat experimental.
+ </para>
+
+ <para>
+ A wide variety of additional workflows are possible, although
+ tools are not yet available to make it convenient.
+ </para>
+
+ <para>
+ </para>
+
+ <para>
+ </para>
+
+</refsect1>
+
+<refsect1>
+<title>Concepts</title>
+
+<para>
+ The OrcProgram is the primary object that applications use when
+ using Orc to create code. It contains all the information related to
+ what is essentially a function definition in C. Orc programs can
+ be compiled into assembly source code, or directly into binary code
+ that can be executed as part of the running process. On CPUs that
+ are not supported, programs can also be executed via emulation. Orc
+ programs can also be compiled into C source code.
+</para>
+
+<para>
+ A program contains one or more instructions and operates on one or
+ more source and destination arrays, and may use scalar parameters.
+ When compiled and executed, or emulated, the instructions define
+ the operations performed on each source array member, and the results
+ are placed in the destination array. Another way of thinking about
+ it is that the compiler generates code that iterates over the
+ destination array, calculating the value of each members based on
+ the program instructions and the corresponding values in the source
+ arrays and scalar parameters.
+</para>
+
+<para>
+ The form of programs is strictly limited so that they may be compiled
+ into vector instructions effectively. It is anticipated that future
+ versions of Orc will allow more complex programs.
+</para>
+
+<para>
+ The arrays that Orc programs operate on must be contiguous.
+</para>
+
+<para>
+ Some example operations are "addw" which adds two 16-bit integers,
+ "convsbw" which converts a signed byte to a signed 16-bit integer,
+ and "minul" which selects the lesser of two 32-bit unsigned
+ integers. Orc only checks that the size of the operand matches
+ the size of the variable. Thus, the compiler will not warn against
+ using "minul" with signed 32-bit integers, because it does not know
+ that the variables are signed or unsigned.
+</para>
+
+<para>
+ Orc has a main set of opcodes, that is, an OrcOpcodeSet, with the
+ name "sys". These opcodes are always available. They cover most
+ common arithmetic and conversion instructions for 8, 16, and 32-bit
+ integers. There are two auxiliary libraries that provide additional
+ opcode sets, the liborc-float library that contains the "float"
+ opcode set for 32 and 64-bit floating point operations, and the
+ liborc-pixel library containing the "pixel" opcode set for operations
+ on 32-bit RGBA pixels.
+</para>
+
+<para>
+ Orc programs are compiled using the function orc_program_compile().
+ The compiled code will be targetted for the current processor, which
+ is useful for compiling code that will be immediately executed.
+ Compiling for other processor families or processor family variants,
+ in order to produce assembly source code, can be accomplished using
+ one of the orc_program_compile variants.
+</para>
+
+<para>
+ Once an Orc program is compiled, it can be executed by creating
+ an OrcExecutor structure, linking it to the program to be executed,
+ setting the arrays and parameters, and setting the iteration count.
+ Orc executors are the equivalent of stack frames in a called function
+ in normal C code. However, all Orc programs use the same OrcExecutor
+ structure, which makes code that manipulates executors simpler in
+ respect to those that manipulate stack frames. Executors can be
+ reused.
+</para>
+
+<para>
+ An OrcTarget represents a particular instruction set or CPU family
+ for which code can be generated. Current targets include MMX, SSE,
+ Altivec, and ARM. Entropy Wave also has non-open-source NEON and
+ C64x+ targets. There is also a special target that generates C
+ source code, but is not capable of producing executable code at
+ runtime. In most cases, the default target is the most appropriate
+ target for the current CPU.
+</para>
+
+<para>
+ Individual Orc targets may have various options that control code
+ generation for that target. For example, the various CPUs handled
+ by the SSE target have different subsets of SSE instructions that
+ are supported. The target flags for SSE enable generation of the
+ different subsets of SSE instructions.
+</para>
+
+<para>
+ In order to produce target code, the Orc compiler finds an appropriate
+ OrcRule to translate the instruction to target code. An OrcRuleSet
+ is an array of rules that all have the required target flags, and
+ a target may have one or more rule sets that can be enabled or
+ disabled based on the target flags. In many cases, Orc instructions
+ can be translated into one or two target instructions, which generates
+ fast code. In other cases, the CPU indicated by the target and target
+ flags does not have a fast method of performing the Orc instruction,
+ and a slower method is chosen. This is indicated in the value returned
+ by the compiling function call. In yet other cases, there is no
+ implemented rule to translate an Orc instruction to target code, so
+ compilation fails.
+</para>
+
+<para>
+ Compilation can fail for one of two main reasons. One reason is that
+ the compiler was unable to parse the correct meaning, such as an
+ unknown opcode, undeclared variable, or a size mismatch. These are
+ uncorrectible errors, and the program cannot be executed or emulated.
+ The other reason for a compilation failure is that target code could
+ not be generated for a variety of reasons, including missing rules
+ or unimplemented features. In this case, the program can be emulated.
+ This process occurs automatically.
+</para>
+
+<para>
+ Emulation is generally slower than corresponding C code. Since the
+ Orc compiler can produce C source code, it is possible to generate
+ and compile backup C code for programs. This process is not yet
+ automatic.
+</para>
+
+</refsect1>
+
+<refsect1>
+<title>Extending Orc</title>
+
+<para>
+ Developers can extend Orc primarily by adding new opcode sets, adding
+ new targets, and by adding new target rules.
+</para>
+
+<para>
+ Additional opcode sets can be created and registered in a manner
+ similar to how the liborc-float and liborc-pixel libraries. In order
+ to make full use of new opcode sets, one must also define rules for
+ translating these opcodes into target code. The example libraries
+ do this by registering rule sets for various targets (mainly SSE)
+ for their opcode sets. Orc provides low-level API for generating
+ target code. Not all possible target instructions can be generated
+ with the target API, so developers may need to modify and add
+ functions to the main Orc library as necessary to generate target
+ code.
+</para>
+
+</refsect1>
+
+</refentry>
+
diff --git a/doc/opcode_table.xml b/doc/opcode_table.xml
new file mode 100644
index 0000000..791de09
--- /dev/null
+++ b/doc/opcode_table.xml
@@ -0,0 +1,897 @@
+<table frame="all" id="table-basictypes" xreflabel="Table of Opcodes">
+<title>Table of Opcodes</title>
+<tgroup cols="3" align="left" colsep="1" rowsep="1">
+<thead>
+<row>
+<entry>opcode</entry>
+<entry>destination</entry>
+<entry>source 1</entry>
+<entry>source 2</entry>
+<entry>description</entry>
+<entry>pseudo code</entry>
+</row>
+</thead>
+<tbody valign="top">
+<row>
+<entry>absb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry></entry>
+<entry>absolute value</entry>
+<entry>(a &lt; 0) ? -a : a</entry>
+</row>
+<row>
+<entry>addb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>add</entry>
+<entry>a + b</entry>
+</row>
+<row>
+<entry>addssb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>add with signed saturate</entry>
+<entry>clamp(a + b)</entry>
+</row>
+<row>
+<entry>addusb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>add with unsigned saturate</entry>
+<entry>clamp(a + b)</entry>
+</row>
+<row>
+<entry>andb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>bitwise AND</entry>
+<entry>a &amp; b</entry>
+</row>
+<row>
+<entry>andnb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>bitwise AND NOT</entry>
+<entry>a &amp; (~b)</entry>
+</row>
+<row>
+<entry>avgsb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>signed average</entry>
+<entry>(a + b + 1)&gt;&gt;1</entry>
+</row>
+<row>
+<entry>avgub</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>unsigned average</entry>
+<entry>(a + b + 1)&gt;&gt;1</entry>
+</row>
+<row>
+<entry>cmpeqb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>compare equal</entry>
+<entry>(a == b) ? (~0) : 0</entry>
+</row>
+<row>
+<entry>cmpgtsb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>compare greater than</entry>
+<entry>(a &gt; b) ? (~0) : 0</entry>
+</row>
+<row>
+<entry>copyb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry></entry>
+<entry>copy</entry>
+<entry>a</entry>
+</row>
+<row>
+<entry>maxsb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>signed maximum</entry>
+<entry>(a &gt; b) ? a : b</entry>
+</row>
+<row>
+<entry>maxub</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>unsigned maximum</entry>
+<entry>(a &gt; b) ? a : b</entry>
+</row>
+<row>
+<entry>minsb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>signed minimum</entry>
+<entry>(a &lt; b) ? a : b</entry>
+</row>
+<row>
+<entry>minub</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>unsigned minimum</entry>
+<entry>(a &lt; b) ? a : b</entry>
+</row>
+<row>
+<entry>mullb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>low bits of multiply</entry>
+<entry>a * b</entry>
+</row>
+<row>
+<entry>mulhsb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>high bits of signed multiply</entry>
+<entry>(a * b) &gt;&gt; 8</entry>
+</row>
+<row>
+<entry>mulhub</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>high bits of unsigned multiply</entry>
+<entry>(a * b) &gt;&gt; 8</entry>
+</row>
+<row>
+<entry>orb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>bitwise or</entry>
+<entry>a | b</entry>
+</row>
+<row>
+<entry>shlb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>shift left</entry>
+<entry>a &lt;&lt; b</entry>
+</row>
+<row>
+<entry>shrsb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>signed shift right</entry>
+<entry>a &gt;&gt; b</entry>
+</row>
+<row>
+<entry>shrub</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>unsigned shift right</entry>
+<entry>a &gt;&gt; b</entry>
+</row>
+<row>
+<entry>signb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry></entry>
+<entry>sign</entry>
+<entry>sign(a)</entry>
+</row>
+<row>
+<entry>subb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>subtract</entry>
+<entry>a - b</entry>
+</row>
+<row>
+<entry>subssb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>subtract with signed saturate</entry>
+<entry>clamp(a - b)</entry>
+</row>
+<row>
+<entry>subusb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>subtract with unsigned saturate</entry>
+<entry>clamp(a - b)</entry>
+</row>
+<row>
+<entry>xorb</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>bitwise XOR</entry>
+<entry>a ^ b</entry>
+</row>
+<row>
+<entry>absw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry></entry>
+<entry>absolute value</entry>
+<entry>(a &lt; 0) ? -a : a</entry>
+</row>
+<row>
+<entry>addw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>add</entry>
+<entry>a + b</entry>
+</row>
+<row>
+<entry>addssw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>add with signed saturate</entry>
+<entry>clamp(a + b)</entry>
+</row>
+<row>
+<entry>addusw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>add with unsigned saturate</entry>
+<entry>clamp(a + b)</entry>
+</row>
+<row>
+<entry>andw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>bitwise AND</entry>
+<entry>a &amp; b</entry>
+</row>
+<row>
+<entry>andnw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>bitwise AND NOT</entry>
+<entry>a &amp; (~b)</entry>
+</row>
+<row>
+<entry>avgsw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>signed average</entry>
+<entry>(a + b + 1)&gt;&gt;1</entry>
+</row>
+<row>
+<entry>avguw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>unsigned average</entry>
+<entry>(a + b + 1)&gt;&gt;1</entry>
+</row>
+<row>
+<entry>cmpeqw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>compare equal</entry>
+<entry>(a == b) ? (~0) : 0</entry>
+</row>
+<row>
+<entry>cmpgtsw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>compare greater than</entry>
+<entry>(a &gt; b) ? (~0) : 0</entry>
+</row>
+<row>
+<entry>copyw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry></entry>
+<entry>copy</entry>
+<entry>a</entry>
+</row>
+<row>
+<entry>maxsw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>signed maximum</entry>
+<entry>(a &gt; b) ? a : b</entry>
+</row>
+<row>
+<entry>maxuw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>unsigned maximum</entry>
+<entry>(a &gt; b) ? a : b</entry>
+</row>
+<row>
+<entry>minsw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>signed minimum</entry>
+<entry>(a &lt; b) ? a : b</entry>
+</row>
+<row>
+<entry>minuw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>unsigned minimum</entry>
+<entry>(a &lt; b) ? a : b</entry>
+</row>
+<row>
+<entry>mullw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>low bits of multiply</entry>
+<entry>a * b</entry>
+</row>
+<row>
+<entry>mulhsw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>high bits of signed multiply</entry>
+<entry>(a * b) &gt;&gt; 8</entry>
+</row>
+<row>
+<entry>mulhuw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>high bits of unsigned multiply</entry>
+<entry>(a * b) &gt;&gt; 8</entry>
+</row>
+<row>
+<entry>orw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>bitwise or</entry>
+<entry>a | b</entry>
+</row>
+<row>
+<entry>shlw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>shift left</entry>
+<entry>a &lt;&lt; b</entry>
+</row>
+<row>
+<entry>shrsw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>signed shift right</entry>
+<entry>a &gt;&gt; b</entry>
+</row>
+<row>
+<entry>shruw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>unsigned shift right</entry>
+<entry>a &gt;&gt; b</entry>
+</row>
+<row>
+<entry>signw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry></entry>
+<entry>sign</entry>
+<entry>sign(a)</entry>
+</row>
+<row>
+<entry>subw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>subtract</entry>
+<entry>a - b</entry>
+</row>
+<row>
+<entry>subssw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>subtract with signed saturate</entry>
+<entry>clamp(a - b)</entry>
+</row>
+<row>
+<entry>subusw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>subtract with unsigned saturate</entry>
+<entry>clamp(a - b)</entry>
+</row>
+<row>
+<entry>xorw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>bitwise XOR</entry>
+<entry>a ^ b</entry>
+</row>
+<row>
+<entry>absl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry></entry>
+<entry>absolute value</entry>
+<entry>(a &lt; 0) ? -a : a</entry>
+</row>
+<row>
+<entry>addl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>add</entry>
+<entry>a + b</entry>
+</row>
+<row>
+<entry>addssl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>add with signed saturate</entry>
+<entry>clamp(a + b)</entry>
+</row>
+<row>
+<entry>addusl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>add with unsigned saturate</entry>
+<entry>clamp(a + b)</entry>
+</row>
+<row>
+<entry>andl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>bitwise AND</entry>
+<entry>a &amp; b</entry>
+</row>
+<row>
+<entry>andnl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>bitwise AND NOT</entry>
+<entry>a &amp; (~b)</entry>
+</row>
+<row>
+<entry>avgsl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>signed average</entry>
+<entry>(a + b + 1)&gt;&gt;1</entry>
+</row>
+<row>
+<entry>avgul</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>unsigned average</entry>
+<entry>(a + b + 1)&gt;&gt;1</entry>
+</row>
+<row>
+<entry>cmpeql</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>compare equal</entry>
+<entry>(a == b) ? (~0) : 0</entry>
+</row>
+<row>
+<entry>cmpgtsl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>compare greater than</entry>
+<entry>(a &gt; b) ? (~0) : 0</entry>
+</row>
+<row>
+<entry>copyl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry></entry>
+<entry>copy</entry>
+<entry>a</entry>
+</row>
+<row>
+<entry>maxsl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>signed maximum</entry>
+<entry>(a &gt; b) ? a : b</entry>
+</row>
+<row>
+<entry>maxul</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>unsigned maximum</entry>
+<entry>(a &gt; b) ? a : b</entry>
+</row>
+<row>
+<entry>minsl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>signed minimum</entry>
+<entry>(a &lt; b) ? a : b</entry>
+</row>
+<row>
+<entry>minul</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>unsigned minimum</entry>
+<entry>(a &lt; b) ? a : b</entry>
+</row>
+<row>
+<entry>mulll</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>low bits of multiply</entry>
+<entry>a * b</entry>
+</row>
+<row>
+<entry>mulhsl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>high bits of signed multiply</entry>
+<entry>(a * b) &gt;&gt; 8</entry>
+</row>
+<row>
+<entry>mulhul</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>high bits of unsigned multiply</entry>
+<entry>(a * b) &gt;&gt; 8</entry>
+</row>
+<row>
+<entry>orl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>bitwise or</entry>
+<entry>a | b</entry>
+</row>
+<row>
+<entry>shll</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>shift left</entry>
+<entry>a &lt;&lt; b</entry>
+</row>
+<row>
+<entry>shrsl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>signed shift right</entry>
+<entry>a &gt;&gt; b</entry>
+</row>
+<row>
+<entry>shrul</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>unsigned shift right</entry>
+<entry>a &gt;&gt; b</entry>
+</row>
+<row>
+<entry>signl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry></entry>
+<entry>sign</entry>
+<entry>sign(a)</entry>
+</row>
+<row>
+<entry>subl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>subtract</entry>
+<entry>a - b</entry>
+</row>
+<row>
+<entry>subssl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>subtract with signed saturate</entry>
+<entry>clamp(a - b)</entry>
+</row>
+<row>
+<entry>subusl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>subtract with unsigned saturate</entry>
+<entry>clamp(a - b)</entry>
+</row>
+<row>
+<entry>xorl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry>bitwise XOR</entry>
+<entry>a ^ b</entry>
+</row>
+<row>
+<entry>convsbw</entry>
+<entry>2</entry>
+<entry>1</entry>
+<entry></entry>
+<entry>convert signed</entry>
+<entry>a</entry>
+</row>
+<row>
+<entry>convubw</entry>
+<entry>2</entry>
+<entry>1</entry>
+<entry></entry>
+<entry>convert unsigned</entry>
+<entry>a</entry>
+</row>
+<row>
+<entry>convswl</entry>
+<entry>4</entry>
+<entry>2</entry>
+<entry></entry>
+<entry>convert signed</entry>
+<entry>a</entry>
+</row>
+<row>
+<entry>convuwl</entry>
+<entry>4</entry>
+<entry>2</entry>
+<entry></entry>
+<entry>convert unsigned</entry>
+<entry>a</entry>
+</row>
+<row>
+<entry>convwb</entry>
+<entry>1</entry>
+<entry>2</entry>
+<entry></entry>
+<entry>convert</entry>
+<entry>a</entry>
+</row>
+<row>
+<entry>convssswb</entry>
+<entry>1</entry>
+<entry>2</entry>
+<entry></entry>
+<entry>convert signed to signed with saturation</entry>
+<entry>clamp(a)</entry>
+</row>
+<row>
+<entry>convsuswb</entry>
+<entry>1</entry>
+<entry>2</entry>
+<entry></entry>
+<entry>convert signed to unsigned with saturation</entry>
+<entry>clamp(a)</entry>
+</row>
+<row>
+<entry>convusswb</entry>
+<entry>1</entry>
+<entry>2</entry>
+<entry></entry>
+<entry>convert unsigned to signed with saturation</entry>
+<entry>clamp(a)</entry>
+</row>
+<row>
+<entry>convuuswb</entry>
+<entry>1</entry>
+<entry>2</entry>
+<entry></entry>
+<entry>convert unsigned to unsigned with saturation</entry>
+<entry>clamp(a)</entry>
+</row>
+<row>
+<entry>convlw</entry>
+<entry>2</entry>
+<entry>4</entry>
+<entry></entry>
+<entry>convert</entry>
+<entry>a</entry>
+</row>
+<row>
+<entry>convssslw</entry>
+<entry>2</entry>
+<entry>4</entry>
+<entry></entry>
+<entry>convert signed to unsigned with saturation</entry>
+<entry>clamp(a)</entry>
+</row>
+<row>
+<entry>convsuslw</entry>
+<entry>2</entry>
+<entry>4</entry>
+<entry></entry>
+<entry>convert signed to signed with saturation</entry>
+<entry>clamp(a)</entry>
+</row>
+<row>
+<entry>convusslw</entry>
+<entry>2</entry>
+<entry>4</entry>
+<entry></entry>
+<entry>convert unsigned to unsigned with saturation</entry>
+<entry>clamp(a)</entry>
+</row>
+<row>
+<entry>convuuslw</entry>
+<entry>2</entry>
+<entry>4</entry>
+<entry></entry>
+<entry>convert unsigned to signed with saturation</entry>
+<entry>clamp(a)</entry>
+</row>
+<row>
+<entry>mulsbw</entry>
+<entry>2</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>multiply signed</entry>
+<entry>a * b</entry>
+</row>
+<row>
+<entry>mulubw</entry>
+<entry>2</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>multiply unsigned</entry>
+<entry>a * b</entry>
+</row>
+<row>
+<entry>mulswl</entry>
+<entry>4</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>multiply signed</entry>
+<entry>a * b</entry>
+</row>
+<row>
+<entry>muluwl</entry>
+<entry>4</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>multiply unsigned</entry>
+<entry>a * b</entry>
+</row>
+<row>
+<entry>accw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry></entry>
+<entry>accumulate</entry>
+<entry>+= a</entry>
+</row>
+<row>
+<entry>accl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry></entry>
+<entry>accumulate</entry>
+<entry>+= a</entry>
+</row>
+<row>
+<entry>accsadubl</entry>
+<entry>4</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>accumulate absolute difference</entry>
+<entry>+= abs(a - b)</entry>
+</row>
+<row>
+<entry>swapw</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry></entry>
+<entry>endianness swap</entry>
+<entry>special</entry>
+</row>
+<row>
+<entry>swapl</entry>
+<entry>4</entry>
+<entry>4</entry>
+<entry></entry>
+<entry>endianness swap</entry>
+<entry>special</entry>
+</row>
+<row>
+<entry>select0wb</entry>
+<entry>1</entry>
+<entry>2</entry>
+<entry></entry>
+<entry>select first half</entry>
+<entry>special</entry>
+</row>
+<row>
+<entry>select1wb</entry>
+<entry>1</entry>
+<entry>2</entry>
+<entry></entry>
+<entry>select second half</entry>
+<entry>special</entry>
+</row>
+<row>
+<entry>select0lw</entry>
+<entry>2</entry>
+<entry>4</entry>
+<entry></entry>
+<entry>select first half</entry>
+<entry>special</entry>
+</row>
+<row>
+<entry>select1lw</entry>
+<entry>2</entry>
+<entry>4</entry>
+<entry></entry>
+<entry>select second half</entry>
+<entry>special</entry>
+</row>
+<row>
+<entry>mergewl</entry>
+<entry>4</entry>
+<entry>2</entry>
+<entry>2</entry>
+<entry>merge halves</entry>
+<entry>special</entry>
+</row>
+<row>
+<entry>mergebw</entry>
+<entry>2</entry>
+<entry>1</entry>
+<entry>1</entry>
+<entry>merge halves</entry>
+<entry>special</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
diff --git a/doc/opcodes.xml b/doc/opcodes.xml
new file mode 100644
index 0000000..5e2235a
--- /dev/null
+++ b/doc/opcodes.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+<!ENTITY % version-entities SYSTEM "version.entities">
+%version-entities;
+<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
+]>
+<refentry id="orc-opcodes" revision="29 may 2009">
+<refmeta>
+<refentrytitle>Orc Opcodes</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>Orc</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>Orc Opcodes</refname>
+<refpurpose>
+Description of Opcodes
+</refpurpose>
+</refnamediv>
+
+<refsect1>
+<title>Orc Opcodes</title>
+
+ <para>
+ Opcodes only work with variables of a particular size. In the
+ table below, destination and source indicate the size of the
+ destination and source operands, in bytes. In general, opcodes
+ have a suffix indicating the sizes, "b" for 1-byte operations,
+ "w" for 2-byte operations, and "l" for 4-byte operations. If
+ the source and destination have different sizes, the source
+ size suffix is listed first, then the destination suffix. For
+ example, converting a 1-byte variable to 2-byte can be performed
+ using the "convsbw" opcode.
+ </para>
+
+ <para>
+ Signed, unsigned, and saturating operations are indicated by
+ the letters "s", "u", and "s". If signed or unsigned is not
+ indicated, it generally means that the signedness is not
+ relevant to the definition of the opcode, and that the operation
+ on signed or unsigned values will give the same result.
+ </para>
+
+ <para>
+ The "select" opcodes divide the bits in the source value into
+ two halves. For "select0", the half that is first in memory
+ order is selected, and the latter half for "select1". In other
+ words, "convwb" is the same as "select0wb" on little-endian
+ systems, and "select1wb" on big-endian systems.
+ </para>
+
+ <para>
+ The "merge" opcodes take two values and put them together in
+ memory order.
+ </para>
+
+ <para>
+ Accumulating opcodes require an accumulator variable as the
+ destination. Accumulating opcodes start with "acc". These
+ opcodes sum the source values over the entire array, and can
+ be read from the OrcExecutor structure after an execution
+ of an Orc program.
+ </para>
+
+ <para>
+ Shift opcodes only work with constants or parameters as the
+ second source value.
+ </para>
+
+ <para>
+ For more precise understanding of operations, it is recommended
+ to compile a program for the C target and examine the resulting C
+ source code.
+ </para>
+
+ <xi:include href="opcode_table.xml"/>
+
+ <para>
+ In the pseudo code of the above table, abs() indicates absolute
+ value, clamp() indicates that any values outside the destination
+ range are set to the nearest value in the destination range, and
+ sign() evaluates to -1 for values less than 0, 1 for values
+ greater than 0, and 0 for 0.
+ </para>
+
+</refsect1>
+
+<refsect1>
+<title>Rule Coverage</title>
+
+ <para>
+ The values for shift operations are not correct in this table.
+ </para>
+
+ <xi:include href="table.xml"/>
+
+</refsect1>
+
+</refentry>
+
diff --git a/doc/orc-docs.sgml b/doc/orc-docs.sgml
index 78ea262..c99c3e0 100644
--- a/doc/orc-docs.sgml
+++ b/doc/orc-docs.sgml
@@ -12,11 +12,18 @@
</bookinfo>
<chapter>
+ <title>Overview</title>
+ <xi:include href="building.xml"/>
+ <xi:include href="concepts.xml"/>
+ </chapter>
+
+ <chapter>
<title>Application API</title>
<xi:include href="xml/orc.xml"/>
<xi:include href="xml/orcprogram.xml"/>
<xi:include href="xml/orccompiler.xml"/>
<xi:include href="xml/orcexecutor.xml"/>
+ <xi:include href="opcodes.xml"/>
</chapter>
<chapter>
<title>Extension API</title>
@@ -29,6 +36,7 @@
<title>Code Generation</title>
<xi:include href="xml/orcarm.xml"/>
<xi:include href="xml/orcmmx.xml"/>
+ <xi:include href="xml/orcpowerpc.xml"/>
<xi:include href="xml/orcsse.xml"/>
<xi:include href="xml/orcx86.xml"/>
</chapter>
diff --git a/doc/orc-sections.txt b/doc/orc-sections.txt
index 6fe16c9..a70f68e 100644
--- a/doc/orc-sections.txt
+++ b/doc/orc-sections.txt
@@ -298,3 +298,27 @@ orc_arm_reg_name
orc_arm_storew
</SECTION>
+<SECTION>
+<FILE>orcpowerpc</FILE>
+powerpc_get_regname
+powerpc_regnum
+powerpc_add_fixup
+powerpc_do_fixups
+powerpc_emit
+powerpc_emit_655510
+powerpc_emit_VA
+powerpc_emit_VX
+powerpc_emit_VX_2
+powerpc_emit_X
+powerpc_emit_addi
+powerpc_emit_b
+powerpc_emit_beq
+powerpc_emit_bne
+powerpc_emit_label
+powerpc_emit_lwz
+powerpc_emit_ret
+powerpc_emit_srawi
+powerpc_emit_stwu
+powerpc_flush
+powerpc_get_constant
+</SECTION>
diff --git a/doc/table.xml b/doc/table.xml
new file mode 100644
index 0000000..3c218da
--- /dev/null
+++ b/doc/table.xml
@@ -0,0 +1,786 @@
+<table frame="all" id="table-basictypes" xreflabel="Table of Opcode Rule Coverage">
+<title>Table of Opcode Rule Coverage</title>
+<tgroup cols="5" align="left" colsep="1" rowsep="1">
+<thead>
+<row>
+<entry>opcode name</entry>
+<entry>sse</entry>
+<entry>mmx</entry>
+<entry>altivec</entry>
+<entry>arm</entry>
+</row>
+</thead>
+<tbody valign="top">
+<row>
+<entry>absb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>addb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>addssb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>addusb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>andb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>andnb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>avgsb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>avgub</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>cmpeqb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>cmpgtsb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>copyb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>maxsb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>maxub</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>minsb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>minub</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>mullb</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>mulhsb</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>mulhub</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>orb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>shlb</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>shrsb</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>shrub</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>signb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>subb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>subssb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>subusb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>xorb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>absw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>addw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+</row>
+<row>
+<entry>addssw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>addusw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>andw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>andnw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>avgsw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>avguw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>cmpeqw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>cmpgtsw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>copyw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>maxsw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>maxuw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>minsw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>minuw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>mullw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+</row>
+<row>
+<entry>mulhsw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>mulhuw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>orw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>shlw</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>shrsw</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+</row>
+<row>
+<entry>shruw</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>signw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>subw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+</row>
+<row>
+<entry>subssw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>subusw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>xorw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>absl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>addl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>addssl</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>addusl</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>andl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>andnl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>avgsl</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>avgul</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>cmpeql</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>cmpgtsl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>copyl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>maxsl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>maxul</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>minsl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>minul</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>mulll</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>mulhsl</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>mulhul</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>orl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>shll</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>shrsl</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>shrul</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>signl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>subl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>subssl</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>subusl</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>xorl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>convsbw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>convubw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>convswl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>convuwl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>convwb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>convssswb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>convsuswb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>convusswb</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>convuuswb</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>convlw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>convssslw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>convsuslw</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>convusslw</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>convuuslw</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>mulsbw</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>mulubw</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>mulswl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>muluwl</entry>
+<entry>no</entry>
+<entry>no</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>accw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>accl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>accsadubl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>swapw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>swapl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>select0wb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>select1wb</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>select0lw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>select1lw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>mergewl</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+<row>
+<entry>mergebw</entry>
+<entry>yes</entry>
+<entry>yes</entry>
+<entry>no</entry>
+<entry>no</entry>
+</row>
+</tbody>
+</tgroup>
+</table>
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 3216bf5..11e04cd 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1,10 +1,6 @@
-orcbin_PROGRAMS = jit simple mt19937ar
+orcbin_PROGRAMS = example1 mt19937ar
AM_LDFLAGS = $(ORC_LIBS)
AM_CFLAGS = $(ORC_CFLAGS)
-jit_SOURCES = jit.c
-
-simple_SOURCES = simple.c
-
diff --git a/examples/example1.c b/examples/example1.c
new file mode 100644
index 0000000..f4ef1b2
--- /dev/null
+++ b/examples/example1.c
@@ -0,0 +1,74 @@
+
+
+#include <stdio.h>
+
+#include <orc/orcprogram.h>
+
+#define N 10
+
+int16_t a[N];
+int16_t b[N];
+int16_t c[N];
+
+void add_s16(int16_t *dest, int16_t *src1, int16_t *src2, int n);
+
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+
+ /* orc_init() must be called before any other Orc function */
+ orc_init ();
+
+ /* Create some data in the source arrays */
+ for(i=0;i<N;i++){
+ a[i] = i;
+ b[i] = 100;
+ }
+
+ /* Call a function that uses Orc */
+ add_s16 (c, a, b, N);
+
+ /* Print the results */
+ for(i=0;i<N;i++){
+ printf("%d: %d %d -> %d\n", i, a[i], b[i], c[i]);
+ }
+
+ return 0;
+}
+
+void
+add_s16(int16_t *dest, int16_t *src1, int16_t *src2, int n)
+{
+ static OrcProgram *p = NULL;
+ OrcExecutor _ex;
+ OrcExecutor *ex = &_ex;
+
+ if (p == NULL) {
+ /* First time through, create the program */
+
+ /* Create a new program with two sources and one destination.
+ * Size of the members of each array is 2. */
+ p = orc_program_new_dss (2, 2, 2);
+
+ /* Append an instruction to add the 2-byte values s1 and s2 (which
+ * are the source arrays created above), and place the result in
+ * the destination array d1, which was also create above. */
+ orc_program_append_str (p, "addw", "d1", "s1", "s2");
+
+ /* Compile the program. Ignore the very important result. */
+ orc_program_compile (p);
+ }
+
+ /* Set the values on the executor structure */
+ orc_executor_set_n (ex, n);
+ orc_executor_set_array_str (ex, "s1", src1);
+ orc_executor_set_array_str (ex, "s2", src2);
+ orc_executor_set_array_str (ex, "d1", dest);
+
+ /* Run the program. This calls the code that was generated above,
+ * or, if the compilation failed, will emulate the program. */
+ orc_executor_run (ex);
+}
+
diff --git a/examples/jit.c b/examples/jit.c
deleted file mode 100644
index d7f313a..0000000
--- a/examples/jit.c
+++ /dev/null
@@ -1,89 +0,0 @@
-
-#include "config.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <orc/orcprogram.h>
-
-#define N 19
-
-int16_t src1[N];
-int16_t src2[N];
-int16_t dest[N];
-
-void test(OrcExecutor *ex);
-
-int
-main (int argc, char *argv[])
-{
- OrcProgram *p;
- OrcExecutor *ex;
- int s1, s2, d1, offset, shift;
- int t1;
-
- orc_init ();
-
- p = orc_program_new ();
-
- d1 = orc_program_add_destination (p, 2, "d1");
- s1 = orc_program_add_source (p, 2, "s1");
- s2 = orc_program_add_source (p, 2, "s2");
- t1 = orc_program_add_temporary (p, 2, "t1");
- offset = orc_program_add_constant (p, 2, 1, "offset");
- shift = orc_program_add_constant (p, 2, 1, "shift");
-
- orc_program_append (p, "addw", t1, s1, s2);
- orc_program_append (p, "addw", t1, t1, offset);
- orc_program_append (p, "shrsw", d1, t1, shift);
-
- orc_program_compile (p);
-
- if (1) {
- int i;
-
- for(i=0;i<N;i++){
- src1[i] = rand()&0xf;
- src2[i] = rand()&0xf;
- }
-
- ex = orc_executor_new (p);
-
- orc_executor_set_n (ex, N-4);
- orc_executor_set_array (ex, s1, src1);
- orc_executor_set_array (ex, s2, src2);
- orc_executor_set_array (ex, d1, dest);
-
- printf("#code exec %p\n", ex->program->code_exec);
-
- orc_executor_run (ex);
- //orc_executor_emulate (ex);
-
- for(i=0;i<N;i++){
- printf("# %4d %4d %4d %4d\n", src1[i], src2[i], dest[i],
- (src1[i] + src2[i] + 1) >> 1);
- }
-
- orc_executor_free (ex);
- }
-
- orc_program_free (p);
-
- return 0;
-}
-
-
-
-void
-test1 (int16_t *dest, int16_t *src1, int16_t *src2, int n)
-{
- int i;
- int16_t t1, t2;
- for(i=0;i<n;i++){
- t1 = src1[i] + src2[i];
- t2 = t1 + 1;
- dest[i] = t2>>1;
- }
-}
-
diff --git a/examples/mt19937ar.c b/examples/mt19937ar.c
index d939913..f23b50e 100644
--- a/examples/mt19937ar.c
+++ b/examples/mt19937ar.c
@@ -90,7 +90,7 @@ mt19937_ref (uint32_t *d, uint32_t *mt)
}
-OrcProgram *p1, *p2, *p3;
+OrcProgram *p1, *p2;
void
create_programs (void)
@@ -107,7 +107,6 @@ create_programs (void)
orc_program_add_constant (p1, 4, UPPER_MASK, "c1");
orc_program_add_constant (p1, 4, LOWER_MASK, "c2");
orc_program_add_constant (p1, 4, 1, "c3");
- orc_program_add_constant (p1, 4, 31, "c5");
orc_program_add_constant (p1, 4, MATRIX_A, "c6");
orc_program_append_str (p1, "andl", "t1", "s1", "c1");
@@ -117,14 +116,37 @@ create_programs (void)
orc_program_append_str (p1, "shrul", "t1", "y", "c3");
orc_program_append_str (p1, "xorl", "t2", "s3", "t1");
orc_program_append_str (p1, "andl", "y", "y", "c3");
- orc_program_append_str (p1, "shll", "y", "y", "c5");
- orc_program_append_str (p1, "shrsl", "y", "y", "c5");
+ orc_program_append_str (p1, "cmpeql", "y", "y", "c3");
orc_program_append_str (p1, "andl", "y", "y", "c6");
orc_program_append_str (p1, "xorl", "d1", "t2", "y");
orc_program_compile (p1);
- printf("%s", orc_program_get_asm_code (p1));
+
+ p2 = orc_program_new ();
+ orc_program_add_destination (p2, 4, "d1");
+ orc_program_add_temporary (p2, 4, "y");
+ orc_program_add_temporary (p2, 4, "t1");
+
+ orc_program_add_constant (p2, 4, 11, "c11");
+ orc_program_add_constant (p2, 4, 7, "c7");
+ orc_program_add_constant (p2, 4, 0x9d2c5680, "x1");
+ orc_program_add_constant (p2, 4, 15, "c15");
+ orc_program_add_constant (p2, 4, 0xefc60000, "x2");
+ orc_program_add_constant (p2, 4, 15, "c18");
+
+ orc_program_append_str (p2, "shrul", "t1", "d1", "c11");
+ orc_program_append_str (p2, "xorl", "y", "d1", "t1");
+ orc_program_append_str (p2, "shll", "t1", "y", "c7");
+ orc_program_append_str (p2, "andl", "t1", "t1", "x1");
+ orc_program_append_str (p2, "xorl", "y", "y", "t1");
+ orc_program_append_str (p2, "shll", "t1", "y", "c15");
+ orc_program_append_str (p2, "andl", "t1", "t1", "x2");
+ orc_program_append_str (p2, "xorl", "y", "y", "t1");
+ orc_program_append_str (p2, "shrul", "t1", "y", "c18");
+ orc_program_append_str (p2, "xorl", "d1", "y", "t1");
+
+ orc_program_compile (p2);
}
diff --git a/examples/simple.c b/examples/simple.c
deleted file mode 100644
index b620e13..0000000
--- a/examples/simple.c
+++ /dev/null
@@ -1,613 +0,0 @@
-
-#include "config.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <orc/orcprogram.h>
-
-#define N 100
-
-int16_t src1[N+4];
-int16_t src2[N];
-int16_t dest_test[N];
-int16_t dest_ref[N];
-int16_t dest[N];
-
-uint8_t bsrc1[N+4];
-uint8_t bsrc2[N];
-uint8_t bdest_test[N];
-uint8_t bdest_ref[N];
-uint8_t bdest[N];
-
-void test1(void);
-void test2(void);
-void test3(void);
-void test4(void);
-void test5(void);
-void test6(void);
-void test7(void);
-void test8(void);
-void test9(void);
-
-int
-main (int argc, char *argv[])
-{
- orc_init ();
-
- test1();
-
- exit(0);
-}
-
-void
-test1(void)
-{
- OrcProgram *p;
- OrcExecutor *ex;
-
- p = orc_program_new_dss (2, 2, 2);
-
- orc_program_append_str (p, "addw", "d1", "s1", "s2");
-
- orc_program_compile (p);
-
- ex = orc_executor_new (p);
- orc_executor_set_n (ex, N - 4);
- orc_executor_set_array_str (ex, "s1", src1);
- orc_executor_set_array_str (ex, "s2", src2);
- orc_executor_set_array_str (ex, "d1", dest);
-
- if (1) {
- int i;
-
- for(i=0;i<N;i++){
- src1[i] = rand()&0xf;
- src2[i] = rand()&0xf;
- }
-
- orc_executor_run (ex);
- //orc_executor_emulate (ex);
-
- for(i=0;i<N;i++){
- printf("# %4d %4d %4d %4d\n", src1[i], src2[i], dest[i],
- src1[i] + src2[i]);
- }
- }
-
- orc_executor_free (ex);
- orc_program_free (p);
-}
-
-
-void
-test2(void)
-{
- OrcProgram *p;
- OrcExecutor *ex;
- int s1, s2, s3, s4, d1;
- int t1, t2;
- int c1, c2, c3;
- int n;
-
- p = orc_program_new ();
-
- d1 = orc_program_add_destination (p, 2, "d1");
- //p->vars[d1].is_uncached = TRUE;
- s1 = orc_program_add_source (p, 2, "s1");
- s2 = orc_program_add_source (p, 2, "s2");
- s3 = orc_program_add_source (p, 2, "s3");
- s4 = orc_program_add_source (p, 2, "s4");
- c1 = orc_program_add_constant (p, 2, 3, "c1");
- c2 = orc_program_add_constant (p, 2, 4, "c2");
- c3 = orc_program_add_constant (p, 2, 3, "c3");
- t1 = orc_program_add_temporary (p, 2, "t1");
- t2 = orc_program_add_temporary (p, 2, "t2");
-
- orc_program_append (p, "addw", t1, s2, s3);
- orc_program_append (p, "addw", t2, s1, s4);
- orc_program_append (p, "mullw", t1, t1, c1);
- orc_program_append (p, "subw", t1, t1, t2);
- orc_program_append (p, "addw", t1, t1, c2);
- orc_program_append (p, "shrsw", d1, t1, c3);
-
- orc_program_compile (p);
-
- ex = orc_executor_new (p);
- orc_executor_set_n (ex, N);
- orc_executor_set_array (ex, s1, src1);
- orc_executor_set_array (ex, s2, src1 + 1);
- orc_executor_set_array (ex, s3, src1 + 2);
- orc_executor_set_array (ex, s4, src1 + 3);
-
- for(n=0;n<20;n++) {
- int i;
-
- for(i=0;i<n+3;i++){
- src1[i] = rand()&0xff;
- }
- for(i=0;i<n+4;i++){
- dest[i] = 0;
- }
-
- orc_executor_set_n (ex, n);
- orc_executor_set_array (ex, d1, dest_ref);
- orc_executor_emulate (ex);
-#if 1
- for(i=0;i<n;i++){
- dest_ref[i] = (3*(src1[i+1]+src1[i+2])-(src1[i]+src1[i+3])+4)>>3;
- }
-#endif
-
- orc_executor_set_array (ex, d1, dest_test + 1);
- orc_executor_run (ex);
-
- printf("# %d: %p %d %d %d\n",
- n, ex->arrays[0], ex->counter1, ex->counter2, ex->counter3);
-
- for(i=0;i<n+4;i++){
- printf("# %d: %4d %4d %4d %c\n", i, src1[i], dest_ref[i], dest_test[i+1],
- (dest_ref[i] == dest_test[i+1])?' ':'*');
- }
- }
-
- orc_executor_free (ex);
- orc_program_free (p);
-}
-
-
-void
-test3(void)
-{
- OrcProgram *p;
- OrcExecutor *ex;
- int s1, s2, d1;
- int t1, t2;
- int c1, c2;
- int n;
-
- p = orc_program_new ();
-
- d1 = orc_program_add_destination (p, 2, "d1");
- s1 = orc_program_add_source (p, 2, "s1");
- s2 = orc_program_add_source (p, 2, "s2");
- c1 = orc_program_add_constant (p, 2, -1, "c1");
- c2 = orc_program_add_constant (p, 2, 1, "c2");
- t1 = orc_program_add_temporary (p, 2, "t1");
- t2 = orc_program_add_temporary (p, 2, "t2");
-
- orc_program_append (p, "addw", t1, s1, s2);
- orc_program_append (p, "addw", t2, t1, c1);
- orc_program_append (p, "shrsw", d1, t2, c2);
-
- orc_program_compile (p);
-
- ex = orc_executor_new (p);
- orc_executor_set_n (ex, N);
- orc_executor_set_array (ex, s1, src1);
- orc_executor_set_array (ex, s2, src1 + 1);
-
- for(n=0;n<20;n++) {
- int i;
-
- for(i=0;i<n+1;i++){
- src1[i] = rand()&0xff;
- }
- for(i=0;i<n+4;i++){
- dest[i] = 0;
- }
-
- orc_executor_set_n (ex, n);
- orc_executor_set_array (ex, d1, dest_ref);
- orc_executor_emulate (ex);
-#if 1
- for(i=0;i<n;i++){
- dest_ref[i] = (src1[i+1]+src1[i]-1)>>1;
- }
-#endif
-
- orc_executor_set_array (ex, d1, dest_test);
- orc_executor_run (ex);
-
- for(i=0;i<n+4;i++){
- printf("# %d: %4d %4d %4d %c\n", i, src1[i], dest_ref[i], dest_test[i],
- (dest_ref[i] == dest_test[i])?' ':'*');
- }
- }
-
- orc_executor_free (ex);
- orc_program_free (p);
-}
-
-
-
-void
-test4(void)
-{
- OrcProgram *p;
- OrcExecutor *ex;
- int n;
-
- p = orc_program_new_dss (1, 1, 1);
-
- orc_program_append_str (p, "addb", "d1", "s1", "s2");
-
- orc_program_compile (p);
-
- ex = orc_executor_new (p);
- orc_executor_set_n (ex, N - 4);
- orc_executor_set_array_str (ex, "s1", bsrc1);
- orc_executor_set_array_str (ex, "s2", bsrc2);
- orc_executor_set_array_str (ex, "d1", bdest);
-
- for(n=0;n<20;n++) {
- int i;
-
- for(i=0;i<n;i++){
- bsrc1[i] = rand()&0xf;
- bsrc2[i] = rand()&0xf;
- }
- for(i=0;i<n+4;i++){
- bdest[i] = 0;
- }
-
- orc_executor_set_n (ex, n);
- orc_executor_set_array_str (ex, "d1", bdest_ref);
- orc_executor_emulate (ex);
-
- orc_executor_set_array_str (ex, "d1", bdest_test);
- orc_executor_run (ex);
-
- for(i=0;i<n+4;i++){
- printf("# %4d %4d %4d %4d %c\n", bsrc1[i], bsrc2[i], bdest_ref[i],
- bdest_test[i],
- (bdest_ref[i] == bdest_test[i])?' ':'*');
- }
- }
-
- orc_executor_free (ex);
- orc_program_free (p);
-}
-
-
-void
-test5(void)
-{
- OrcProgram *p;
- OrcExecutor *ex;
- int s1, s2, d1;
- int t1;
- int n;
-
- p = orc_program_new ();
-
- d1 = orc_program_add_destination (p, 2, "d1");
- s1 = orc_program_add_source (p, 2, "s1");
- s2 = orc_program_add_source (p, 2, "s2");
- t1 = orc_program_add_temporary (p, 2, "t1");
-
- orc_program_append (p, "absw", t1, s1, s2);
- orc_program_append (p, "addw", t1, s1, s2);
- orc_program_append (p, "addssw", t1, s1, s2);
- orc_program_append (p, "addusw", t1, s1, s2);
- orc_program_append (p, "andw", t1, s1, s2);
- orc_program_append (p, "andnw", t1, s1, s2);
- //orc_program_append (p, "avgsw", t1, s1, s2);
- orc_program_append (p, "avguw", t1, s1, s2);
- orc_program_append (p, "cmpeqw", t1, s1, s2);
- orc_program_append (p, "cmpgtsw", t1, s1, s2);
- orc_program_append (p, "maxsw", t1, s1, s2);
- //orc_program_append (p, "maxuw", t1, s1, s2);
- orc_program_append (p, "minsw", t1, s1, s2);
- //orc_program_append (p, "minuw", t1, s1, s2);
- orc_program_append (p, "mullw", t1, s1, s2);
- orc_program_append (p, "mulhsw", t1, s1, s2);
- orc_program_append (p, "mulhuw", t1, s1, s2);
- orc_program_append (p, "orw", t1, s1, s2);
- orc_program_append (p, "signw", t1, s1, s2);
- orc_program_append (p, "subw", t1, s1, s2);
- orc_program_append (p, "subssw", t1, s1, s2);
- orc_program_append (p, "subusw", t1, s1, s2);
- orc_program_append (p, "xorw", t1, s1, s2);
-
- orc_program_compile (p);
-
- ex = orc_executor_new (p);
- orc_executor_set_n (ex, N);
- orc_executor_set_array (ex, s1, src1);
- orc_executor_set_array (ex, s2, src1 + 1);
-
- for(n=0;n<20;n++) {
- int i;
-
- for(i=0;i<n+1;i++){
- src1[i] = rand()&0xff;
- }
- for(i=0;i<n+4;i++){
- dest[i] = 0;
- }
-
- orc_executor_set_n (ex, n);
- orc_executor_set_array (ex, d1, dest_ref);
- orc_executor_emulate (ex);
-#if 1
- for(i=0;i<n;i++){
- dest_ref[i] = (src1[i+1]+src1[i]-1)>>1;
- }
-#endif
-
- orc_executor_set_array (ex, d1, dest_test);
- //orc_executor_run (ex);
-
- for(i=0;i<n+4;i++){
- printf("# %d: %4d %4d %4d %c\n", i, src1[i], dest_ref[i], dest_test[i],
- (dest_ref[i] == dest_test[i])?' ':'*');
- }
- }
-
- orc_executor_free (ex);
- orc_program_free (p);
-}
-
-
-void
-test6(void)
-{
- OrcProgram *p;
- OrcExecutor *ex;
- int s1, s2, d1;
- int t1;
- int n;
-
- p = orc_program_new ();
-
- d1 = orc_program_add_destination (p, 1, "d1");
- s1 = orc_program_add_source (p, 1, "s1");
- s2 = orc_program_add_source (p, 1, "s2");
- t1 = orc_program_add_temporary (p, 1, "t1");
-
- orc_program_append (p, "absb", t1, s1, s2);
- orc_program_append (p, "addb", t1, s1, s2);
- orc_program_append (p, "addssb", t1, s1, s2);
- orc_program_append (p, "addusb", t1, s1, s2);
- orc_program_append (p, "andb", t1, s1, s2);
- orc_program_append (p, "andnb", t1, s1, s2);
- //orc_program_append (p, "avgsb", t1, s1, s2);
- orc_program_append (p, "avgub", t1, s1, s2);
- orc_program_append (p, "cmpeqb", t1, s1, s2);
- orc_program_append (p, "cmpgtsb", t1, s1, s2);
- //orc_program_append (p, "maxsb", t1, s1, s2);
- orc_program_append (p, "maxub", t1, s1, s2);
- //orc_program_append (p, "minsb", t1, s1, s2);
- orc_program_append (p, "minub", t1, s1, s2);
- //orc_program_append (p, "mullb", t1, s1, s2);
- //orc_program_append (p, "mulhsb", t1, s1, s2);
- //orc_program_append (p, "mulhub", t1, s1, s2);
- orc_program_append (p, "orb", t1, s1, s2);
- orc_program_append (p, "signb", t1, s1, s2);
- orc_program_append (p, "subb", t1, s1, s2);
- orc_program_append (p, "subssb", t1, s1, s2);
- orc_program_append (p, "subusb", t1, s1, s2);
- orc_program_append (p, "xorb", t1, s1, s2);
-
- orc_program_compile (p);
-
- ex = orc_executor_new (p);
- orc_executor_set_n (ex, N);
- orc_executor_set_array (ex, s1, src1);
- orc_executor_set_array (ex, s2, src1 + 1);
-
- for(n=0;n<20;n++) {
- int i;
-
- for(i=0;i<n+1;i++){
- src1[i] = rand()&0xff;
- }
- for(i=0;i<n+4;i++){
- dest[i] = 0;
- }
-
- orc_executor_set_n (ex, n);
- orc_executor_set_array (ex, d1, dest_ref);
- orc_executor_emulate (ex);
-#if 1
- for(i=0;i<n;i++){
- dest_ref[i] = (src1[i+1]+src1[i]-1)>>1;
- }
-#endif
-
- orc_executor_set_array (ex, d1, dest_test);
- //orc_executor_run (ex);
-
- for(i=0;i<n+4;i++){
- printf("# %d: %4d %4d %4d %c\n", i, src1[i], dest_ref[i], dest_test[i],
- (dest_ref[i] == dest_test[i])?' ':'*');
- }
- }
-
- orc_executor_free (ex);
- orc_program_free (p);
-}
-
-
-void
-test7(void)
-{
- OrcProgram *p;
- OrcExecutor *ex;
- int s1, s2, d1;
- int t1;
- int n;
-
- p = orc_program_new ();
-
- d1 = orc_program_add_destination (p, 1, "d1");
- s1 = orc_program_add_source (p, 1, "s1");
- s2 = orc_program_add_source (p, 1, "s2");
- t1 = orc_program_add_temporary (p, 1, "t1");
-
- orc_program_append (p, "absl", t1, s1, s2);
- orc_program_append (p, "addl", t1, s1, s2);
- //orc_program_append (p, "addssl", t1, s1, s2);
- //orc_program_append (p, "addusl", t1, s1, s2);
- orc_program_append (p, "andl", t1, s1, s2);
- orc_program_append (p, "andnl", t1, s1, s2);
- //orc_program_append (p, "avgsl", t1, s1, s2);
- //orc_program_append (p, "avgul", t1, s1, s2);
- orc_program_append (p, "cmpeql", t1, s1, s2);
- orc_program_append (p, "cmpgtsl", t1, s1, s2);
- //orc_program_append (p, "maxsl", t1, s1, s2);
- //orc_program_append (p, "maxul", t1, s1, s2);
- //orc_program_append (p, "minsl", t1, s1, s2);
- //orc_program_append (p, "minul", t1, s1, s2);
- //orc_program_append (p, "mulll", t1, s1, s2);
- //orc_program_append (p, "mulhsl", t1, s1, s2);
- //orc_program_append (p, "mulhul", t1, s1, s2);
- orc_program_append (p, "orl", t1, s1, s2);
- orc_program_append (p, "signl", t1, s1, s2);
- orc_program_append (p, "subl", t1, s1, s2);
- //orc_program_append (p, "subssl", t1, s1, s2);
- //orc_program_append (p, "subusl", t1, s1, s2);
- orc_program_append (p, "xorl", t1, s1, s2);
-
- orc_program_compile (p);
-
- ex = orc_executor_new (p);
- orc_executor_set_n (ex, N);
- orc_executor_set_array (ex, s1, src1);
- orc_executor_set_array (ex, s2, src1 + 1);
-
- for(n=0;n<20;n++) {
- int i;
-
- for(i=0;i<n+1;i++){
- src1[i] = rand()&0xff;
- }
- for(i=0;i<n+4;i++){
- dest[i] = 0;
- }
-
- orc_executor_set_n (ex, n);
- orc_executor_set_array (ex, d1, dest_ref);
- orc_executor_emulate (ex);
-#if 1
- for(i=0;i<n;i++){
- dest_ref[i] = (src1[i+1]+src1[i]-1)>>1;
- }
-#endif
-
- orc_executor_set_array (ex, d1, dest_test);
- //orc_executor_run (ex);
-
- for(i=0;i<n+4;i++){
- printf("# %d: %4d %4d %4d %c\n", i, src1[i], dest_ref[i], dest_test[i],
- (dest_ref[i] == dest_test[i])?' ':'*');
- }
- }
-
- orc_executor_free (ex);
- orc_program_free (p);
-}
-
-
-
-void
-test8(void)
-{
- OrcProgram *p;
- OrcExecutor *ex;
- int s1, d1;
- int n;
-
- p = orc_program_new ();
-
- d1 = orc_program_add_destination (p, 2, "d1");
- s1 = orc_program_add_source (p, 1, "s1");
-
- orc_program_append_ds (p, "convubw", d1, s1);
-
- orc_program_compile (p);
-
- ex = orc_executor_new (p);
- orc_executor_set_n (ex, N);
- orc_executor_set_array (ex, s1, bsrc1);
-
- for(n=0;n<20;n++) {
- int i;
-
- for(i=0;i<n;i++){
- bsrc1[i] = rand()&0xff;
- }
- for(i=0;i<n+4;i++){
- dest[i] = 0;
- }
-
- orc_executor_set_n (ex, n);
- orc_executor_set_array (ex, d1, dest_ref);
- orc_executor_emulate (ex);
-#if 0
- for(i=0;i<n;i++){
- dest_ref[i] = bsrc1[i];
- }
-#endif
-
- orc_executor_set_array (ex, d1, dest_test);
- orc_executor_run (ex);
-
-#if 1
- for(i=0;i<n+4;i++){
- printf("# %d: %4d %4d %4d %c\n", i, bsrc1[i], dest_ref[i], dest_test[i],
- (dest_ref[i] == dest_test[i])?' ':'*');
- }
-#endif
- }
-
- orc_executor_free (ex);
- orc_program_free (p);
-}
-
-
-void
-test9(void)
-{
- OrcProgram *p;
- OrcExecutor *ex;
- int value = 1;
-
- p = orc_program_new_ds (2, 2);
- orc_program_add_parameter (p, 2, "p1");
-
- orc_program_append_str (p, "shrsw", "d1", "s1", "p1");
-
- orc_program_compile (p);
-
- ex = orc_executor_new (p);
- orc_executor_set_n (ex, N - 4);
- orc_executor_set_array_str (ex, "s1", src1);
- orc_executor_set_param_str (ex, "p1", value);
- orc_executor_set_array_str (ex, "d1", dest);
-
- if (1) {
- int i;
-
- for(i=0;i<N;i++){
- src1[i] = rand()&0xf;
- }
-
- orc_executor_run (ex);
- //orc_executor_emulate (ex);
-
- for(i=0;i<N;i++){
- printf("# %4d %4d %4d\n", src1[i], dest[i],
- src1[i] >> value);
- }
- }
-
- printf("%s", orc_program_get_asm_code (p));
-
- orc_executor_free (ex);
- orc_program_free (p);
-}
-
-
diff --git a/orc/orc.c b/orc/orc.c
index 49f8466..813cdc3 100644
--- a/orc/orc.c
+++ b/orc/orc.c
@@ -15,6 +15,13 @@
void _orc_debug_init(void);
+/**
+ * orc_init:
+ *
+ * This function initializes the Orc library, and
+ * should be called before using any other Orc function.
+ * Subsequent calls to this function have no effect.
+ */
void
orc_init (void)
{
diff --git a/orc/orccompiler.c b/orc/orccompiler.c
index 905affb..0a4712e 100644
--- a/orc/orccompiler.c
+++ b/orc/orccompiler.c
@@ -13,6 +13,19 @@
* SECTION:orccompiler
* @title: OrcCompiler
* @short_description: Compile Orc programs
+ *
+ * OrcCompiler is the object used to convert Orc programs contained
+ * in an OrcProgram object into assembly code and object code.
+ *
+ * The OrcCompileResult enum is used to indicate whether or not
+ * a compilation attempt was successful or not. The macros
+ * ORC_COMPILE_RESULT_IS_SUCCESSFUL() and ORC_COMPILE_RESULT_IS_FATAL()
+ * should be used instead of checking values directly.
+ *
+ * When a program is compiled, the compiler calls the functions
+ * contained in various OrcRule structures. These functions generate
+ * assembly and object instructions by calling ORC_ASM_CODE()
+ * or functions that use ORC_ASM_CODE() internally.
*/
void orc_compiler_assign_rules (OrcCompiler *compiler);
@@ -70,12 +83,40 @@ orc_compiler_allocate_register (OrcCompiler *compiler, int data_reg)
return 0;
}
+/**
+ * orc_program_compile:
+ * @program: the OrcProgram to compile
+ *
+ * Compiles an Orc program for the current CPU. If successful,
+ * executable code for the program was generated and can be
+ * executed.
+ *
+ * The return value indicates various levels of success or failure.
+ * Success can be determined by checking for a true value of the
+ * macro ORC_COMPILE_RESULT_IS_SUCCESSFUL() on the return value. This
+ * indicates that executable code was generated. If the macro
+ * ORC_COMPILE_RESULT_IS_FATAL() on the return value evaluates to
+ * true, then there was a syntactical error in the program. If the
+ * result is neither successful nor fatal, the program can still be
+ * emulated.
+ *
+ * Returns: an OrcCompileResult
+ */
OrcCompileResult
orc_program_compile (OrcProgram *program)
{
return orc_program_compile_for_target (program, orc_target_get_default ());
}
+/**
+ * orc_program_compile_for_target:
+ * @program: the OrcProgram to compile
+ *
+ * Compiles an Orc program for the given target, using the
+ * default target flags for that target.
+ *
+ * Returns: an OrcCompileResult
+ */
OrcCompileResult
orc_program_compile_for_target (OrcProgram *program, OrcTarget *target)
{
@@ -86,6 +127,15 @@ orc_program_compile_for_target (OrcProgram *program, OrcTarget *target)
return orc_program_compile_full (program, target, flags);
}
+/**
+ * orc_program_compile_full:
+ * @program: the OrcProgram to compile
+ *
+ * Compiles an Orc program for the given target, using the
+ * given target flags.
+ *
+ * Returns: an OrcCompileResult
+ */
OrcCompileResult
orc_program_compile_full (OrcProgram *program, OrcTarget *target,
unsigned int flags)
@@ -463,6 +513,21 @@ orc_compiler_dump_asm (OrcCompiler *compiler)
printf("%s", compiler->asm_code);
}
+/**
+ * orc_compiler_append_code:
+ * @p: an OrcCompiler object
+ * @fmt: a printf-style format string
+ * @...: optional printf-style arguments
+ *
+ * Generates a string using sprintf() on the given format and
+ * arguments, and appends that string to the generated assembly
+ * code for the compiler.
+ *
+ * This function is used by the ORC_ASM_CODE() macro.
+ *
+ * This function is useful in a function implementing an OrcRule
+ * or implementing a target.
+ */
void
orc_compiler_append_code (OrcCompiler *p, const char *fmt, ...)
{
diff --git a/orc/orcdebug.c b/orc/orcdebug.c
index 38bde6a..c4aa7be 100644
--- a/orc/orcdebug.c
+++ b/orc/orcdebug.c
@@ -123,7 +123,7 @@ orc_debug_set_level (int level)
/**
* orc_debug_set_print_function:
- * @func:
+ * @func: the function to call
*
* Sets the function to call when outputting debugging information.
* A value of NULL for @func will restore the default handler,
diff --git a/orc/orcdebug.h b/orc/orcdebug.h
index 7964ab6..fe09605 100644
--- a/orc/orcdebug.h
+++ b/orc/orcdebug.h
@@ -51,6 +51,18 @@ typedef void (*OrcDebugPrintFunc) (int level, const char *file,
/**
* OrcDebugLevel:
+ * @ORC_DEBUG_NONE: No debugging. Used to disable debugging output.
+ * @ORC_DEBUG_ERROR: The level for messages indicating that an error
+ * has occurred that causes Orc to produce incorrect results. Also
+ * used temporarily by developers for testing code.
+ * @ORC_DEBUG_WARNING: Messages at this level indicate something has
+ * occurred that a developer looking into an application problem may
+ * want to know.
+ * @ORC_DEBUG_INFO: Messages at this level provide high-level
+ * information about Orc internals.
+ * @ORC_DEBUG_DEBUG: The default level for logging messages.
+ * @ORC_DEBUG_LOG: The level for messages that probably don't need to
+ * be logged at all.
*
* Enumeration describing debug levels in Orc.
*/
@@ -65,30 +77,35 @@ typedef enum {
/**
* ORC_ERROR:
+ * @...: printf-style format and arguments
*
* Macro to call ORC_DEBUG_PRINT() with a level of #ORC_DEBUG_ERROR.
*/
#define ORC_ERROR(...) ORC_DEBUG_PRINT(ORC_DEBUG_ERROR, __VA_ARGS__)
/**
* ORC_WARNING:
+ * @...: printf-style format and arguments
*
* Macro to call ORC_DEBUG_PRINT() with a level of #ORC_DEBUG_WARNING.
*/
#define ORC_WARNING(...) ORC_DEBUG_PRINT(ORC_DEBUG_WARNING, __VA_ARGS__)
/**
* ORC_INFO:
+ * @...: printf-style format and arguments
*
* Macro to call ORC_DEBUG_PRINT() with a level of #ORC_DEBUG_INFO.
*/
#define ORC_INFO(...) ORC_DEBUG_PRINT(ORC_DEBUG_INFO, __VA_ARGS__)
/**
* ORC_DEBUG:
+ * @...: printf-style format and arguments
*
* Macro to call ORC_DEBUG_PRINT() with a level of #ORC_DEBUG_DEBUG.
*/
#define ORC_DEBUG(...) ORC_DEBUG_PRINT(ORC_DEBUG_DEBUG, __VA_ARGS__)
/**
* ORC_LOG:
+ * @...: printf-style format and arguments
*
* Macro to call ORC_DEBUG_PRINT() with a level of #ORC_DEBUG_LOG.
*/
@@ -110,8 +127,8 @@ typedef enum {
/**
* ORC_DEBUG_PRINT:
- * @level:
- * @...:
+ * @level: debug level of message
+ * @Varargs: printf-style format and arguments
*
* Macro to call orc_debug_print() with the correct values for
* the name of the source file, line of source file, and function.
diff --git a/orc/orcpowerpc.c b/orc/orcpowerpc.c
index 38f08d0..169c1bb 100644
--- a/orc/orcpowerpc.c
+++ b/orc/orcpowerpc.c
@@ -12,6 +12,12 @@
#include <orc/orcprogram.h>
#include <orc/orcdebug.h>
+/**
+ * SECTION:orcpowerpc
+ * @title: PowerPC
+ * @short_description: code generation for PowerPC
+ */
+
void orc_compiler_powerpc_init (OrcCompiler *compiler);
void orc_compiler_powerpc_assemble (OrcCompiler *compiler);
diff --git a/orc/orcprogram-arm.c b/orc/orcprogram-arm.c
index 84e9c9f..027cf64 100644
--- a/orc/orcprogram-arm.c
+++ b/orc/orcprogram-arm.c
@@ -243,7 +243,7 @@ orc_arm_emit_store_dest (OrcCompiler *compiler, OrcVariable *var)
void
orc_compiler_orc_arm_assemble (OrcCompiler *compiler)
{
- int dest_var = orc_compiler_get_dest (compiler);
+ int dest_var = ORC_VAR_D1;
compiler->vars[dest_var].is_aligned = FALSE;
diff --git a/orc/orcprogram.c b/orc/orcprogram.c
index 2114382..7497152 100644
--- a/orc/orcprogram.c
+++ b/orc/orcprogram.c
@@ -16,6 +16,14 @@
*/
+/**
+ * orc_program_new:
+ *
+ * Create a new OrcProgram. The program should be freed using
+ * @orc_program_free().
+ *
+ * Returns: a pointer to an OrcProgram structure
+ */
OrcProgram *
orc_program_new (void)
{
@@ -30,6 +38,17 @@ orc_program_new (void)
return p;
}
+/**
+ * orc_program_new_dss:
+ * @size1: size of destination array members
+ * @size2: size of first source array members
+ * @size3: size of second source array members
+ *
+ * Create a new OrcProgram, with a destination named "d1" and
+ * two sources named "s1" and "s2".
+ *
+ * Returns: a pointer to an OrcProgram structure
+ */
OrcProgram *
orc_program_new_dss (int size1, int size2, int size3)
{
@@ -44,6 +63,16 @@ orc_program_new_dss (int size1, int size2, int size3)
return p;
}
+/**
+ * orc_program_new_ds:
+ * @size1: size of destination array members
+ * @size2: size of source array members
+ *
+ * Create a new OrcProgram, with a destination named "d1" and
+ * one source named "s1".
+ *
+ * Returns: a pointer to an OrcProgram structure
+ */
OrcProgram *
orc_program_new_ds (int size1, int size2)
{
@@ -57,6 +86,17 @@ orc_program_new_ds (int size1, int size2)
return p;
}
+/**
+ * orc_program_new_ass:
+ * @size1: size of destination array members
+ * @size2: size of first source array members
+ * @size3: size of second source array members
+ *
+ * Create a new OrcProgram, with an accumulator named "a1" and
+ * two source named "s1" and "s2".
+ *
+ * Returns: a pointer to an OrcProgram structure
+ */
OrcProgram *
orc_program_new_ass (int size1, int size2, int size3)
{
@@ -71,6 +111,16 @@ orc_program_new_ass (int size1, int size2, int size3)
return p;
}
+/**
+ * orc_program_new_as:
+ * @size1: size of destination array members
+ * @size2: size of source array members
+ *
+ * Create a new OrcProgram, with an accumulator named "a1" and
+ * one source named "s1".
+ *
+ * Returns: a pointer to an OrcProgram structure
+ */
OrcProgram *
orc_program_new_as (int size1, int size2)
{
@@ -84,6 +134,12 @@ orc_program_new_as (int size1, int size2)
return p;
}
+/**
+ * orc_program_free:
+ * @program: a pointer to an OrcProgram structure
+ *
+ * Frees an OrcProgram.
+ */
void
orc_program_free (OrcProgram *program)
{
@@ -97,6 +153,13 @@ orc_program_free (OrcProgram *program)
free (program);
}
+/**
+ * orc_program_set_name:
+ * @program: a pointer to an OrcProgram structure
+ * @name: string to set the name to
+ *
+ * Sets the name of the program. The string is copied.
+ */
void
orc_program_set_name (OrcProgram *program, const char *name)
{
@@ -106,12 +169,31 @@ orc_program_set_name (OrcProgram *program, const char *name)
program->name = strdup (name);
}
+/**
+ * orc_program_get_name:
+ * @program: a pointer to an OrcProgram structure
+ *
+ * Gets the name of the program. The string is valid until the name
+ * is changed or the program is freed.
+ *
+ * Returns: a character string
+ */
const char *
orc_program_get_name (OrcProgram *program)
{
return program->name;
}
+/**
+ * orc_program_add_temporary:
+ * @program: a pointer to an OrcProgram structure
+ * @size: size of data values
+ * @name: name of variable
+ *
+ * Creates a new variable holding temporary values.
+ *
+ * Returns: the index of the new variable
+ */
int
orc_program_add_temporary (OrcProgram *program, int size, const char *name)
{
@@ -125,6 +207,16 @@ orc_program_add_temporary (OrcProgram *program, int size, const char *name)
return i;
}
+/**
+ * orc_program_dup_temporary:
+ * @program: a pointer to an OrcProgram structure
+ * @var: variable to duplicate
+ * @j: index
+ *
+ * Internal function.
+ *
+ * Returns: the index of the new variable
+ */
int
orc_program_dup_temporary (OrcProgram *program, int var, int j)
{
@@ -139,6 +231,16 @@ orc_program_dup_temporary (OrcProgram *program, int var, int j)
return i;
}
+/**
+ * orc_program_add_source:
+ * @program: a pointer to an OrcProgram structure
+ * @size: size of data values
+ * @name: name of variable
+ *
+ * Creates a new variable representing a source array.
+ *
+ * Returns: the index of the new variable
+ */
int
orc_program_add_source (OrcProgram *program, int size, const char *name)
{
@@ -152,6 +254,16 @@ orc_program_add_source (OrcProgram *program, int size, const char *name)
return i;
}
+/**
+ * orc_program_add_destination:
+ * @program: a pointer to an OrcProgram structure
+ * @size: size of data values
+ * @name: name of variable
+ *
+ * Creates a new variable representing a destination array.
+ *
+ * Returns: the index of the new variable
+ */
int
orc_program_add_destination (OrcProgram *program, int size, const char *name)
{
@@ -165,6 +277,17 @@ orc_program_add_destination (OrcProgram *program, int size, const char *name)
return i;
}
+/**
+ * orc_program_add_constant:
+ * @program: a pointer to an OrcProgram structure
+ * @size: size of data value
+ * @value: the value
+ * @name: name of variable
+ *
+ * Creates a new variable representing a constant value.
+ *
+ * Returns: the index of the new variable
+ */
int
orc_program_add_constant (OrcProgram *program, int size, int value, const char *name)
{
@@ -179,6 +302,16 @@ orc_program_add_constant (OrcProgram *program, int size, int value, const char *
return i;
}
+/**
+ * orc_program_add_parameter:
+ * @program: a pointer to an OrcProgram structure
+ * @size: size of data value
+ * @name: name of variable
+ *
+ * Creates a new variable representing a scalar parameter.
+ *
+ * Returns: the index of the new variable
+ */
int
orc_program_add_parameter (OrcProgram *program, int size, const char *name)
{
@@ -192,6 +325,16 @@ orc_program_add_parameter (OrcProgram *program, int size, const char *name)
return i;
}
+/**
+ * orc_program_add_accumulator:
+ * @program: a pointer to an OrcProgram structure
+ * @size: size of data value
+ * @name: name of variable
+ *
+ * Creates a new variable representing an accumulator.
+ *
+ * Returns: the index of the new variable
+ */
int
orc_program_add_accumulator (OrcProgram *program, int size, const char *name)
{
@@ -205,6 +348,16 @@ orc_program_add_accumulator (OrcProgram *program, int size, const char *name)
return i;
}
+/**
+ * orc_program_append_ds:
+ * @program: a pointer to an OrcProgram structure
+ * @name: name of instruction
+ * @arg0: index of first variable
+ * @arg1: index of second variable
+ *
+ * Appends an instruction to the program, with arguments @arg0 and
+ * @arg1. The instruction must take 2 operands.
+ */
void
orc_program_append_ds (OrcProgram *program, const char *name, int arg0,
int arg1)
@@ -223,6 +376,17 @@ orc_program_append_ds (OrcProgram *program, const char *name, int arg0,
program->n_insns++;
}
+/**
+ * orc_program_append_ds:
+ * @program: a pointer to an OrcProgram structure
+ * @name: name of instruction
+ * @arg0: index of first variable
+ * @arg1: index of second variable
+ * @arg2: index of second variable
+ *
+ * Appends an instruction to the program, with arguments @arg0,
+ * @arg1, and @arg2. The instruction must take 3 operands.
+ */
void
orc_program_append (OrcProgram *program, const char *name, int arg0,
int arg1, int arg2)
@@ -242,6 +406,16 @@ orc_program_append (OrcProgram *program, const char *name, int arg0,
program->n_insns++;
}
+/**
+ * orc_program_find_var_by_name:
+ * @program: a pointer to an OrcProgram structure
+ * @name: name of instruction
+ *
+ * Finds the variable with the name @name. If no variable with the
+ * given name exists in the program, -1 is returned.
+ *
+ * Returns: the index of the variable
+ */
int
orc_program_find_var_by_name (OrcProgram *program, const char *name)
{
@@ -256,22 +430,17 @@ orc_program_find_var_by_name (OrcProgram *program, const char *name)
return -1;
}
-int
-orc_compiler_get_dest (OrcCompiler *compiler)
-{
- int k;
-
- for(k=0;k<ORC_N_VARIABLES;k++){
- if (compiler->vars[k].name &&
- compiler->vars[k].vartype == ORC_VAR_TYPE_DEST) {
- return k;
- }
- }
-
- ORC_PROGRAM_ERROR(compiler, "failed to find destination array");
- return -1;
-}
-
+/**
+ * orc_program_append_str:
+ * @program: a pointer to an OrcProgram structure
+ * @name: name of instruction
+ * @arg0: name of first variable
+ * @arg1: name of second variable
+ * @arg2: name of third variable
+ *
+ * Appends an instruction to the program, with arguments @arg0,
+ * @arg1, and @arg2. The instruction must take 3 operands.
+ */
void
orc_program_append_str (OrcProgram *program, const char *name,
const char *arg1, const char *arg2, const char *arg3)
@@ -291,6 +460,16 @@ orc_program_append_str (OrcProgram *program, const char *name,
program->n_insns++;
}
+/**
+ * orc_program_append_ds_str:
+ * @program: a pointer to an OrcProgram structure
+ * @name: name of instruction
+ * @arg0: name of first variable
+ * @arg1: name of second variable
+ *
+ * Appends an instruction to the program, with arguments @arg0 and
+ * @arg2. The instruction must take 2 operands.
+ */
void
orc_program_append_ds_str (OrcProgram *program, const char *name,
const char *arg1, const char *arg2)
@@ -309,12 +488,30 @@ orc_program_append_ds_str (OrcProgram *program, const char *name,
program->n_insns++;
}
+/**
+ * orc_program_get_asm_code:
+ * @program: a pointer to an OrcProgram structure
+ *
+ * Returns a character string containing the assembly code created
+ * by compiling the program. This string is valid until the program
+ * is compiled again or the program is freed.
+ *
+ * Returns: a character string
+ */
const char *
orc_program_get_asm_code (OrcProgram *program)
{
return program->asm_code;
}
+/**
+ * orc_program_get_max_var_size:
+ * @program: a pointer to an OrcProgram structure
+ *
+ * Returns the size of the largest variable used in the program.
+ *
+ * Returns: the number of bytes
+ */
int
orc_program_get_max_var_size (OrcProgram *program)
{
diff --git a/orc/orcprogram.h b/orc/orcprogram.h
index 67f6900..dd11b27 100644
--- a/orc/orcprogram.h
+++ b/orc/orcprogram.h
@@ -157,6 +157,11 @@ typedef enum {
#define ORC_COMPILE_RESULT_IS_SUCCESSFUL(x) ((x) < 0x100)
#define ORC_COMPILE_RESULT_IS_FATAL(x) ((x) >= 0x200)
+/**
+ * OrcVariable:
+ *
+ * The OrcVariable structure has no public members
+ */
struct _OrcVariable {
/*< private >*/
char *name;
@@ -181,12 +186,22 @@ struct _OrcVariable {
int ptr_offset;
};
+/**
+ * OrcRule:
+ *
+ * The OrcRule structure has no public members
+ */
struct _OrcRule {
/*< private >*/
OrcRuleEmitFunc emit;
void *emit_user;
};
+/**
+ * OrcRuleSet:
+ *
+ * The OrcRuleSet structure has no public members
+ */
struct _OrcRuleSet {
/*< private >*/
OrcOpcodeSet *opcode_set;
@@ -196,6 +211,11 @@ struct _OrcRuleSet {
int n_rules;
};
+/**
+ * OrcOpcodeSet:
+ *
+ * The OrcOpcodeSet structure has no public members
+ */
struct _OrcOpcodeSet {
/*< private >*/
int opcode_major;
@@ -216,6 +236,11 @@ struct _OrcStaticOpcode {
int src_size[ORC_STATIC_OPCODE_N_SRC];
};
+/**
+ * OrcInstruction:
+ *
+ * The OrcInstruction structure has no public members
+ */
struct _OrcInstruction {
/*< private >*/
OrcStaticOpcode *opcode;
@@ -225,6 +250,11 @@ struct _OrcInstruction {
OrcRule *rule;
};
+/**
+ * OrcConstant:
+ *
+ * The OrcConstant structure has no public members
+ */
struct _OrcConstant {
/*< private >*/
int type;
@@ -233,6 +263,11 @@ struct _OrcConstant {
unsigned int full_value[4];
};
+/**
+ * OrcFixup:
+ *
+ * The OrcFixup structure has no public members
+ */
struct _OrcFixup {
/*< private >*/
unsigned char *ptr;
@@ -240,6 +275,11 @@ struct _OrcFixup {
int label;
};
+/**
+ * OrcProgram:
+ *
+ * The OrcProgram structure has no public members
+ */
struct _OrcProgram {
/*< private >*/
OrcInstruction insns[ORC_N_INSNS];
@@ -261,6 +301,11 @@ struct _OrcProgram {
int code_size;
};
+/**
+ * OrcCompiler:
+ *
+ * The OrcCompiler structure has no public members
+ */
struct _OrcCompiler {
/*< private >*/
OrcProgram *program;
@@ -305,12 +350,21 @@ struct _OrcCompiler {
int gp_tmpreg;
};
+/**
+ * OrcOpcodeExecutor:
+ *
+ * The OrcOpcodeExecutor structure has no public members
+ */
struct _OrcOpcodeExecutor {
/*< private >*/
int src_values[ORC_STATIC_OPCODE_N_SRC];
int dest_values[ORC_STATIC_OPCODE_N_DEST];
};
+/**
+ * OrcExecutor:
+ *
+ */
struct _OrcExecutor {
/*< private >*/
OrcProgram *program;
@@ -324,6 +378,10 @@ struct _OrcExecutor {
int accumulators[4];
};
+/**
+ * OrcTarget:
+ *
+ */
struct _OrcTarget {
const char *name;
orc_bool executable;
@@ -374,7 +432,6 @@ OrcCompileResult orc_program_compile_full (OrcProgram *p, OrcTarget *target,
void orc_program_free (OrcProgram *program);
int orc_program_find_var_by_name (OrcProgram *program, const char *name);
-int orc_compiler_get_dest (OrcCompiler *compiler);
int orc_program_add_temporary (OrcProgram *program, int size, const char *name);
int orc_program_dup_temporary (OrcProgram *program, int i, int j);
diff --git a/orc/orcrules-mmx.c b/orc/orcrules-mmx.c
index 6704ea9..ee8ac32 100644
--- a/orc/orcrules-mmx.c
+++ b/orc/orcrules-mmx.c
@@ -764,7 +764,7 @@ orc_compiler_mmx_register_rules (OrcTarget *target)
/* MMX */
rule_set = orc_rule_set_new (orc_opcode_set_get("sys"), target,
- ORC_TARGET_MMX_MMX | ORC_TARGET_MMX_MMXEXT);
+ ORC_TARGET_MMX_MMX);
REG(addb);
REG(addssb);
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index ee30e71..acfcd6a 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -14,7 +14,7 @@ XFAIL_TESTS = \
exec_opcodes_float \
exec_opcodes_pixel
-orcbin_PROGRAMS = $(TESTS)
+orcbin_PROGRAMS = $(TESTS) generate_xml_table generate_xml_table2
CLEANFILES = temp-orc-test-*
diff --git a/testsuite/generate_xml_table.c b/testsuite/generate_xml_table.c
new file mode 100644
index 0000000..f4c2ba8
--- /dev/null
+++ b/testsuite/generate_xml_table.c
@@ -0,0 +1,100 @@
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <orc/orc.h>
+#include <orc-test/orctest.h>
+
+
+int error = FALSE;
+
+char * test_opcode (OrcStaticOpcode *opcode, OrcTarget *target,
+ unsigned int target_flags);
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ int j;
+ OrcOpcodeSet *opcode_set;
+ OrcTarget *targets[10];
+ unsigned int target_flags[10];
+ int n_targets;
+
+ orc_init();
+ orc_test_init();
+
+ targets[0] = orc_target_get_by_name("sse");
+ target_flags[0] = orc_target_get_default_flags(targets[0]);
+
+ targets[1] = orc_target_get_by_name("mmx");
+ target_flags[1] = orc_target_get_default_flags(targets[1]);
+
+ targets[2] = orc_target_get_by_name("altivec");
+ target_flags[2] = orc_target_get_default_flags(targets[2]);
+
+ targets[3] = orc_target_get_by_name("arm");
+ target_flags[3] = orc_target_get_default_flags(targets[3]);
+
+ n_targets=4;
+
+ printf(
+"<table frame=\"all\" id=\"table-basictypes\" xreflabel=\"Table of Opcode Rule Coverage\">\n"
+"<title>Table of Opcode Rule Coverage</title>\n"
+"<tgroup cols=\"%d\" align=\"left\" colsep=\"1\" rowsep=\"1\">\n"
+"<thead>\n"
+"<row>\n"
+"<entry>opcode name</entry>\n", n_targets+1);
+ for(j=0;j<n_targets;j++){
+ printf("<entry>%s</entry>\n",
+ orc_target_get_name(targets[j]));
+ }
+ printf(
+"</row>\n"
+"</thead>\n"
+"<tbody valign=\"top\">\n");
+
+ opcode_set = orc_opcode_set_get ("sys");
+
+ for(i=0;i<opcode_set->n_opcodes;i++){
+ printf("<row>\n");
+ printf("<entry>%s</entry>\n", opcode_set->opcodes[i].name);
+ for(j=0;j<n_targets;j++){
+ printf("<entry>%s</entry>\n",
+ test_opcode (opcode_set->opcodes + i, targets[j], target_flags[j]));
+ }
+ printf("</row>\n");
+ }
+ printf(
+"</tbody>\n"
+"</tgroup>\n"
+"</table>\n");
+
+ return 0;
+}
+
+char *
+test_opcode (OrcStaticOpcode *opcode, OrcTarget *target,
+ unsigned int target_flags)
+{
+ OrcProgram *p;
+ OrcCompileResult ret;
+
+ p = orc_test_get_program_for_opcode (opcode);
+ if (!p) return "fail";
+
+ ret = orc_program_compile_full (p, target, target_flags);
+ orc_program_free (p);
+
+ if (ORC_COMPILE_RESULT_IS_FATAL(ret)) {
+ //return "fail";
+ return "no";
+ }
+ if (ORC_COMPILE_RESULT_IS_SUCCESSFUL(ret)) {
+ return "yes";
+ }
+ return "no";
+}
+
diff --git a/testsuite/generate_xml_table2.c b/testsuite/generate_xml_table2.c
new file mode 100644
index 0000000..1d85de1
--- /dev/null
+++ b/testsuite/generate_xml_table2.c
@@ -0,0 +1,230 @@
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <orc/orc.h>
+#include <orc-test/orctest.h>
+
+
+int error = FALSE;
+
+char * get_desc (OrcStaticOpcode *opcode);
+char * get_code (OrcStaticOpcode *opcode);
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ OrcOpcodeSet *opcode_set;
+ OrcTarget *targets[10];
+ unsigned int target_flags[10];
+ int n_targets;
+
+ orc_init();
+ orc_test_init();
+
+ targets[0] = orc_target_get_by_name("sse");
+ target_flags[0] = orc_target_get_default_flags(targets[0]);
+
+ targets[1] = orc_target_get_by_name("mmx");
+ target_flags[1] = orc_target_get_default_flags(targets[1]);
+
+ targets[2] = orc_target_get_by_name("altivec");
+ target_flags[2] = orc_target_get_default_flags(targets[2]);
+
+ targets[3] = orc_target_get_by_name("arm");
+ target_flags[3] = orc_target_get_default_flags(targets[3]);
+
+ n_targets=4;
+
+ printf(
+"<table frame=\"all\" id=\"table-basictypes\" xreflabel=\"Table of Opcodes\">\n"
+"<title>Table of Opcodes</title>\n"
+"<tgroup cols=\"3\" align=\"left\" colsep=\"1\" rowsep=\"1\">\n"
+"<thead>\n"
+"<row>\n"
+"<entry>opcode</entry>\n"
+"<entry>destination</entry>\n"
+"<entry>source 1</entry>\n"
+"<entry>source 2</entry>\n"
+"<entry>description</entry>\n"
+"<entry>pseudo code</entry>\n"
+"</row>\n"
+"</thead>\n"
+"<tbody valign=\"top\">\n");
+
+ opcode_set = orc_opcode_set_get ("sys");
+
+ for(i=0;i<opcode_set->n_opcodes;i++){
+ printf("<row>\n");
+ printf("<entry>%s</entry>\n", opcode_set->opcodes[i].name);
+ printf("<entry>%d</entry>\n", opcode_set->opcodes[i].dest_size[0]);
+ printf("<entry>%d</entry>\n", opcode_set->opcodes[i].src_size[0]);
+ if (opcode_set->opcodes[i].src_size[1]) {
+ printf("<entry>%d</entry>\n", opcode_set->opcodes[i].src_size[1]);
+ } else {
+ printf("<entry></entry>\n");
+ }
+ printf("<entry>%s</entry>\n", get_desc(&opcode_set->opcodes[i]));
+ printf("<entry>%s</entry>\n", get_code(&opcode_set->opcodes[i]));
+ printf("</row>\n");
+ }
+ printf(
+"</tbody>\n"
+"</tgroup>\n"
+"</table>\n");
+
+ return 0;
+}
+
+struct a {
+ char *name;
+ char *code;
+ char *desc;
+};
+
+struct a ops[] = {
+ { "absb", "(a &lt; 0) ? -a : a", "absolute value" },
+ { "addb", "a + b", "add" },
+ { "addssb", "clamp(a + b)", "add with signed saturate" },
+ { "addusb", "clamp(a + b)", "add with unsigned saturate" },
+ { "andb", "a &amp; b", "bitwise AND" },
+ { "andnb", "a &amp; (~b)", "bitwise AND NOT" },
+ { "avgsb", "(a + b + 1)&gt;&gt;1", "signed average" },
+ { "avgub", "(a + b + 1)&gt;&gt;1", "unsigned average" },
+ { "cmpeqb", "(a == b) ? (~0) : 0", "compare equal" },
+ { "cmpgtsb", "(a &gt; b) ? (~0) : 0", "compare greater than" },
+ { "copyb", "a", "copy" },
+ { "maxsb", "(a &gt; b) ? a : b", "signed maximum" },
+ { "maxub", "(a &gt; b) ? a : b", "unsigned maximum" },
+ { "minsb", "(a &lt; b) ? a : b", "signed minimum" },
+ { "minub", "(a &lt; b) ? a : b", "unsigned minimum" },
+ { "mullb", "a * b", "low bits of multiply" },
+ { "mulhsb", "(a * b) &gt;&gt; 8", "high bits of signed multiply" },
+ { "mulhub", "(a * b) &gt;&gt; 8", "high bits of unsigned multiply" },
+ { "orb", "a | b", "bitwise or" },
+ { "shlb", "a &lt;&lt; b", "shift left" },
+ { "shrsb", "a &gt;&gt; b", "signed shift right" },
+ { "shrub", "a &gt;&gt; b", "unsigned shift right" },
+ { "signb", "sign(a)", "sign" },
+ { "subb", "a - b", "subtract" },
+ { "subssb", "clamp(a - b)", "subtract with signed saturate" },
+ { "subusb", "clamp(a - b)", "subtract with unsigned saturate" },
+ { "xorb", "a ^ b", "bitwise XOR" },
+
+ { "absw", "(a &lt; 0) ? -a : a", "absolute value" },
+ { "addw", "a + b", "add" },
+ { "addssw", "clamp(a + b)", "add with signed saturate" },
+ { "addusw", "clamp(a + b)", "add with unsigned saturate" },
+ { "andw", "a &amp; b", "bitwise AND" },
+ { "andnw", "a &amp; (~b)", "bitwise AND NOT" },
+ { "avgsw", "(a + b + 1)&gt;&gt;1", "signed average" },
+ { "avguw", "(a + b + 1)&gt;&gt;1", "unsigned average" },
+ { "cmpeqw", "(a == b) ? (~0) : 0", "compare equal" },
+ { "cmpgtsw", "(a &gt; b) ? (~0) : 0", "compare greater than" },
+ { "copyw", "a", "copy" },
+ { "maxsw", "(a &gt; b) ? a : b", "signed maximum" },
+ { "maxuw", "(a &gt; b) ? a : b", "unsigned maximum" },
+ { "minsw", "(a &lt; b) ? a : b", "signed minimum" },
+ { "minuw", "(a &lt; b) ? a : b", "unsigned minimum" },
+ { "mullw", "a * b", "low bits of multiply" },
+ { "mulhsw", "(a * b) &gt;&gt; 8", "high bits of signed multiply" },
+ { "mulhuw", "(a * b) &gt;&gt; 8", "high bits of unsigned multiply" },
+ { "orw", "a | b", "bitwise or" },
+ { "shlw", "a &lt;&lt; b", "shift left" },
+ { "shrsw", "a &gt;&gt; b", "signed shift right" },
+ { "shruw", "a &gt;&gt; b", "unsigned shift right" },
+ { "signw", "sign(a)", "sign" },
+ { "subw", "a - b", "subtract" },
+ { "subssw", "clamp(a - b)", "subtract with signed saturate" },
+ { "subusw", "clamp(a - b)", "subtract with unsigned saturate" },
+ { "xorw", "a ^ b", "bitwise XOR" },
+
+ { "absl", "(a &lt; 0) ? -a : a", "absolute value" },
+ { "addl", "a + b", "add" },
+ { "addssl", "clamp(a + b)", "add with signed saturate" },
+ { "addusl", "clamp(a + b)", "add with unsigned saturate" },
+ { "andl", "a &amp; b", "bitwise AND" },
+ { "andnl", "a &amp; (~b)", "bitwise AND NOT" },
+ { "avgsl", "(a + b + 1)&gt;&gt;1", "signed average" },
+ { "avgul", "(a + b + 1)&gt;&gt;1", "unsigned average" },
+ { "cmpeql", "(a == b) ? (~0) : 0", "compare equal" },
+ { "cmpgtsl", "(a &gt; b) ? (~0) : 0", "compare greater than" },
+ { "copyl", "a", "copy" },
+ { "maxsl", "(a &gt; b) ? a : b", "signed maximum" },
+ { "maxul", "(a &gt; b) ? a : b", "unsigned maximum" },
+ { "minsl", "(a &lt; b) ? a : b", "signed minimum" },
+ { "minul", "(a &lt; b) ? a : b", "unsigned minimum" },
+ { "mulll", "a * b", "low bits of multiply" },
+ { "mulhsl", "(a * b) &gt;&gt; 8", "high bits of signed multiply" },
+ { "mulhul", "(a * b) &gt;&gt; 8", "high bits of unsigned multiply" },
+ { "orl", "a | b", "bitwise or" },
+ { "shll", "a &lt;&lt; b", "shift left" },
+ { "shrsl", "a &gt;&gt; b", "signed shift right" },
+ { "shrul", "a &gt;&gt; b", "unsigned shift right" },
+ { "signl", "sign(a)", "sign" },
+ { "subl", "a - b", "subtract" },
+ { "subssl", "clamp(a - b)", "subtract with signed saturate" },
+ { "subusl", "clamp(a - b)", "subtract with unsigned saturate" },
+ { "xorl", "a ^ b", "bitwise XOR" },
+
+ { "convsbw", "a", "convert signed" },
+ { "convubw", "a", "convert unsigned" },
+ { "convswl", "a", "convert signed" },
+ { "convuwl", "a", "convert unsigned" },
+ { "convwb", "a", "convert" },
+ { "convssswb", "clamp(a)", "convert signed to signed with saturation" },
+ { "convsuswb", "clamp(a)", "convert signed to unsigned with saturation" },
+ { "convusswb", "clamp(a)", "convert unsigned to signed with saturation" },
+ { "convuuswb", "clamp(a)", "convert unsigned to unsigned with saturation" },
+ { "convlw", "a", "convert" },
+ { "convssslw", "clamp(a)", "convert signed to unsigned with saturation" },
+ { "convsuslw", "clamp(a)", "convert signed to signed with saturation" },
+ { "convusslw", "clamp(a)", "convert unsigned to unsigned with saturation" },
+ { "convuuslw", "clamp(a)", "convert unsigned to signed with saturation" },
+ { "mulsbw", "a * b", "multiply signed" },
+ { "mulubw", "a * b", "multiply unsigned" },
+ { "mulswl", "a * b", "multiply signed" },
+ { "muluwl", "a * b", "multiply unsigned" },
+ { "mergewl", "special", "merge halves" },
+ { "mergebw", "special", "merge halves" },
+ { "select0wb", "special", "select first half" },
+ { "select1wb", "special", "select second half" },
+ { "select0lw", "special", "select first half" },
+ { "select1lw", "special", "select second half" },
+ { "swapw", "special", "endianness swap" },
+ { "swapl", "special", "endianness swap" },
+
+ { "accw", "+= a", "accumulate" },
+ { "accl", "+= a", "accumulate" },
+ { "accsadubl", "+= abs(a - b)", "accumulate absolute difference" }
+};
+
+
+char *
+get_desc (OrcStaticOpcode *opcode)
+{
+ int i;
+ for(i=0;i<sizeof(ops)/sizeof(ops[0]);i++){
+ if (strcmp (opcode->name, ops[i].name) == 0) {
+ return ops[i].desc;
+ }
+ }
+ return "";
+}
+
+char *
+get_code (OrcStaticOpcode *opcode)
+{
+ int i;
+ for(i=0;i<sizeof(ops)/sizeof(ops[0]);i++){
+ if (strcmp (opcode->name, ops[i].name) == 0) {
+ return ops[i].code;
+ }
+ }
+ return "";
+}
+