diff options
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | doc/building.xml | 82 | ||||
-rw-r--r-- | doc/concepts.xml | 251 | ||||
-rw-r--r-- | doc/opcode_table.xml | 897 | ||||
-rw-r--r-- | doc/opcodes.xml | 101 | ||||
-rw-r--r-- | doc/orc-docs.sgml | 8 | ||||
-rw-r--r-- | doc/orc-sections.txt | 24 | ||||
-rw-r--r-- | doc/table.xml | 786 | ||||
-rw-r--r-- | examples/Makefile.am | 6 | ||||
-rw-r--r-- | examples/example1.c | 74 | ||||
-rw-r--r-- | examples/jit.c | 89 | ||||
-rw-r--r-- | examples/mt19937ar.c | 32 | ||||
-rw-r--r-- | examples/simple.c | 613 | ||||
-rw-r--r-- | orc/orc.c | 7 | ||||
-rw-r--r-- | orc/orccompiler.c | 65 | ||||
-rw-r--r-- | orc/orcdebug.c | 2 | ||||
-rw-r--r-- | orc/orcdebug.h | 21 | ||||
-rw-r--r-- | orc/orcpowerpc.c | 6 | ||||
-rw-r--r-- | orc/orcprogram-arm.c | 2 | ||||
-rw-r--r-- | orc/orcprogram.c | 229 | ||||
-rw-r--r-- | orc/orcprogram.h | 59 | ||||
-rw-r--r-- | orc/orcrules-mmx.c | 2 | ||||
-rw-r--r-- | testsuite/Makefile.am | 2 | ||||
-rw-r--r-- | testsuite/generate_xml_table.c | 100 | ||||
-rw-r--r-- | testsuite/generate_xml_table2.c | 230 |
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 < 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 < 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 & b</entry> +</row> +<row> +<entry>andnb</entry> +<entry>1</entry> +<entry>1</entry> +<entry>1</entry> +<entry>bitwise AND NOT</entry> +<entry>a & (~b)</entry> +</row> +<row> +<entry>avgsb</entry> +<entry>1</entry> +<entry>1</entry> +<entry>1</entry> +<entry>signed average</entry> +<entry>(a + b + 1)>>1</entry> +</row> +<row> +<entry>avgub</entry> +<entry>1</entry> +<entry>1</entry> +<entry>1</entry> +<entry>unsigned average</entry> +<entry>(a + b + 1)>>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 > 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 > b) ? a : b</entry> +</row> +<row> +<entry>maxub</entry> +<entry>1</entry> +<entry>1</entry> +<entry>1</entry> +<entry>unsigned maximum</entry> +<entry>(a > b) ? a : b</entry> +</row> +<row> +<entry>minsb</entry> +<entry>1</entry> +<entry>1</entry> +<entry>1</entry> +<entry>signed minimum</entry> +<entry>(a < b) ? a : b</entry> +</row> +<row> +<entry>minub</entry> +<entry>1</entry> +<entry>1</entry> +<entry>1</entry> +<entry>unsigned minimum</entry> +<entry>(a < 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) >> 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) >> 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 << b</entry> +</row> +<row> +<entry>shrsb</entry> +<entry>1</entry> +<entry>1</entry> +<entry>1</entry> +<entry>signed shift right</entry> +<entry>a >> b</entry> +</row> +<row> +<entry>shrub</entry> +<entry>1</entry> +<entry>1</entry> +<entry>1</entry> +<entry>unsigned shift right</entry> +<entry>a >> 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 < 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 & b</entry> +</row> +<row> +<entry>andnw</entry> +<entry>2</entry> +<entry>2</entry> +<entry>2</entry> +<entry>bitwise AND NOT</entry> +<entry>a & (~b)</entry> +</row> +<row> +<entry>avgsw</entry> +<entry>2</entry> +<entry>2</entry> +<entry>2</entry> +<entry>signed average</entry> +<entry>(a + b + 1)>>1</entry> +</row> +<row> +<entry>avguw</entry> +<entry>2</entry> +<entry>2</entry> +<entry>2</entry> +<entry>unsigned average</entry> +<entry>(a + b + 1)>>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 > 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 > b) ? a : b</entry> +</row> +<row> +<entry>maxuw</entry> +<entry>2</entry> +<entry>2</entry> +<entry>2</entry> +<entry>unsigned maximum</entry> +<entry>(a > b) ? a : b</entry> +</row> +<row> +<entry>minsw</entry> +<entry>2</entry> +<entry>2</entry> +<entry>2</entry> +<entry>signed minimum</entry> +<entry>(a < b) ? a : b</entry> +</row> +<row> +<entry>minuw</entry> +<entry>2</entry> +<entry>2</entry> +<entry>2</entry> +<entry>unsigned minimum</entry> +<entry>(a < 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) >> 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) >> 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 << b</entry> +</row> +<row> +<entry>shrsw</entry> +<entry>2</entry> +<entry>2</entry> +<entry>2</entry> +<entry>signed shift right</entry> +<entry>a >> b</entry> +</row> +<row> +<entry>shruw</entry> +<entry>2</entry> +<entry>2</entry> +<entry>2</entry> +<entry>unsigned shift right</entry> +<entry>a >> 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 < 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 & b</entry> +</row> +<row> +<entry>andnl</entry> +<entry>4</entry> +<entry>4</entry> +<entry>4</entry> +<entry>bitwise AND NOT</entry> +<entry>a & (~b)</entry> +</row> +<row> +<entry>avgsl</entry> +<entry>4</entry> +<entry>4</entry> +<entry>4</entry> +<entry>signed average</entry> +<entry>(a + b + 1)>>1</entry> +</row> +<row> +<entry>avgul</entry> +<entry>4</entry> +<entry>4</entry> +<entry>4</entry> +<entry>unsigned average</entry> +<entry>(a + b + 1)>>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 > 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 > b) ? a : b</entry> +</row> +<row> +<entry>maxul</entry> +<entry>4</entry> +<entry>4</entry> +<entry>4</entry> +<entry>unsigned maximum</entry> +<entry>(a > b) ? a : b</entry> +</row> +<row> +<entry>minsl</entry> +<entry>4</entry> +<entry>4</entry> +<entry>4</entry> +<entry>signed minimum</entry> +<entry>(a < b) ? a : b</entry> +</row> +<row> +<entry>minul</entry> +<entry>4</entry> +<entry>4</entry> +<entry>4</entry> +<entry>unsigned minimum</entry> +<entry>(a < 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) >> 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) >> 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 << b</entry> +</row> +<row> +<entry>shrsl</entry> +<entry>4</entry> +<entry>4</entry> +<entry>4</entry> +<entry>signed shift right</entry> +<entry>a >> b</entry> +</row> +<row> +<entry>shrul</entry> +<entry>4</entry> +<entry>4</entry> +<entry>4</entry> +<entry>unsigned shift right</entry> +<entry>a >> 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); -} - - @@ -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 < 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 & b", "bitwise AND" }, + { "andnb", "a & (~b)", "bitwise AND NOT" }, + { "avgsb", "(a + b + 1)>>1", "signed average" }, + { "avgub", "(a + b + 1)>>1", "unsigned average" }, + { "cmpeqb", "(a == b) ? (~0) : 0", "compare equal" }, + { "cmpgtsb", "(a > b) ? (~0) : 0", "compare greater than" }, + { "copyb", "a", "copy" }, + { "maxsb", "(a > b) ? a : b", "signed maximum" }, + { "maxub", "(a > b) ? a : b", "unsigned maximum" }, + { "minsb", "(a < b) ? a : b", "signed minimum" }, + { "minub", "(a < b) ? a : b", "unsigned minimum" }, + { "mullb", "a * b", "low bits of multiply" }, + { "mulhsb", "(a * b) >> 8", "high bits of signed multiply" }, + { "mulhub", "(a * b) >> 8", "high bits of unsigned multiply" }, + { "orb", "a | b", "bitwise or" }, + { "shlb", "a << b", "shift left" }, + { "shrsb", "a >> b", "signed shift right" }, + { "shrub", "a >> 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 < 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 & b", "bitwise AND" }, + { "andnw", "a & (~b)", "bitwise AND NOT" }, + { "avgsw", "(a + b + 1)>>1", "signed average" }, + { "avguw", "(a + b + 1)>>1", "unsigned average" }, + { "cmpeqw", "(a == b) ? (~0) : 0", "compare equal" }, + { "cmpgtsw", "(a > b) ? (~0) : 0", "compare greater than" }, + { "copyw", "a", "copy" }, + { "maxsw", "(a > b) ? a : b", "signed maximum" }, + { "maxuw", "(a > b) ? a : b", "unsigned maximum" }, + { "minsw", "(a < b) ? a : b", "signed minimum" }, + { "minuw", "(a < b) ? a : b", "unsigned minimum" }, + { "mullw", "a * b", "low bits of multiply" }, + { "mulhsw", "(a * b) >> 8", "high bits of signed multiply" }, + { "mulhuw", "(a * b) >> 8", "high bits of unsigned multiply" }, + { "orw", "a | b", "bitwise or" }, + { "shlw", "a << b", "shift left" }, + { "shrsw", "a >> b", "signed shift right" }, + { "shruw", "a >> 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 < 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 & b", "bitwise AND" }, + { "andnl", "a & (~b)", "bitwise AND NOT" }, + { "avgsl", "(a + b + 1)>>1", "signed average" }, + { "avgul", "(a + b + 1)>>1", "unsigned average" }, + { "cmpeql", "(a == b) ? (~0) : 0", "compare equal" }, + { "cmpgtsl", "(a > b) ? (~0) : 0", "compare greater than" }, + { "copyl", "a", "copy" }, + { "maxsl", "(a > b) ? a : b", "signed maximum" }, + { "maxul", "(a > b) ? a : b", "unsigned maximum" }, + { "minsl", "(a < b) ? a : b", "signed minimum" }, + { "minul", "(a < b) ? a : b", "unsigned minimum" }, + { "mulll", "a * b", "low bits of multiply" }, + { "mulhsl", "(a * b) >> 8", "high bits of signed multiply" }, + { "mulhul", "(a * b) >> 8", "high bits of unsigned multiply" }, + { "orl", "a | b", "bitwise or" }, + { "shll", "a << b", "shift left" }, + { "shrsl", "a >> b", "signed shift right" }, + { "shrul", "a >> 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 ""; +} + |