--- /dev/null
+
+AUTOMAKE_OPTIONS = foreign
+
+SUBDIRS = orc testsuite examples doc
+
+EXTRA_DIST = COPYING autogen.sh gtk-doc.make HACKING BUG-REPORTING
+
+DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc
+
+pkgconfig_DATA = orc-$(ORC_MAJORMINOR).pc
+
+orc-$(ORC_MAJORMINOR).pc: orc.pc
+ cp orc.pc orc-$(ORC_MAJORMINOR).pc
+
+orc-$(ORC_MAJORMINOR)-uninstalled.pc: orc-uninstalled.pc
+ cp orc-uninstalled.pc orc-$(ORC_MAJORMINOR)-uninstalled.pc
+
+BUILT_SOURCES=orc-$(ORC_MAJORMINOR)-uninstalled.pc
+
+CLEANFILES = orc-$(ORC_MAJORMINOR).pc orc-$(ORC_MAJORMINOR)-uninstalled.pc
+
+ACLOCAL_FLAGS = -I m4
+
--- /dev/null
+#!/bin/sh
+
+autoreconf -i -f &&
+./configure --enable-maintainer-mode --disable-static --enable-gtk-doc $@
+
--- /dev/null
+AC_PREREQ([2.58])
+AC_INIT(orc,0.3.14.1)
+
+AS_NANO(ORC_CVS=no,ORC_CVS=yes)
+
+AC_CANONICAL_HOST([])
+AM_INIT_AUTOMAKE(1.6)
+
+AM_MAINTAINER_MODE
+
+ORC_MAJORMINOR=0.3
+AC_SUBST(ORC_MAJORMINOR)
+
+AM_CONFIG_HEADER(config.h)
+
+dnl CURRENT, REVISION, AGE
+dnl - library source changed -> increment REVISION
+dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0
+dnl - interfaces added -> increment AGE
+dnl - interfaces removed -> AGE = 0
+ORC_LIBVERSION="2:0:2"
+AC_SUBST(ORC_LIBVERSION)
+AC_LIBTOOL_WIN32_DLL
+AC_LIBTOOL_TAGS([])
+AC_PROG_LIBTOOL
+AM_PROG_AS
+
+AC_CONFIG_SRCDIR([orc/orc.h])
+
+ACLOCAL_AMFLAGS="-I m4 $ACLOCAL_AMFLAGS"
+AC_SUBST(ACLOCAL_AMFLAGS)
+
+PKG_CHECK_MODULES(GLIB, glib-2.0, HAVE_GLIB=yes, HAVE_GLIB=no)
+AC_SUBST(GLIB_LIBS)
+AC_SUBST(GLIB_CFLAGS)
+AC_ARG_ENABLE(glib,
+AC_HELP_STRING([--disable-glib],[disable usage of glib]),
+[case "${enableval}" in
+ yes) HAVE_GLIB=yes ;;
+ no) HAVE_GLIB=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --disable-glib) ;;
+esac])
+AM_CONDITIONAL(HAVE_GLIB, test "x$HAVE_GLIB" = "xyes")
+
+##################################################
+# Check for gtk-doc.
+##################################################
+
+if test "x$cross_compiling" = "xyes" ; then
+ enable_gtk_doc=no
+fi
+GTK_DOC_CHECK([1.0])
+
+
+AS_HOST_DEFINES()
+
+AC_C_BIGENDIAN
+
+AC_LTDL_SYMBOL_USCORE
+if test x${ac_cv_sys_symbol_underscore} = xyes ; then
+ AC_DEFINE(HAVE_SYMBOL_UNDERSCORE, 1, [Define if C symbols have leading underscore])
+fi
+
+AX_CREATE_STDINT_H([orc/orc-stdint.h])
+
+AC_FUNC_MMAP()
+AC_CHECK_LIB(m, rint,
+ AC_DEFINE(HAVE_RINT, 1, [Define if rint() is available]))
+AC_CHECK_LIB(m, rintf,
+ AC_DEFINE(HAVE_RINTF, 1, [Define if rintf() is available]))
+AC_CHECK_LIB(m, lrint,
+ AC_DEFINE(HAVE_LRINT, 1, [Define if lrint() is available]))
+AC_CHECK_LIB(m, lrintf,
+ AC_DEFINE(HAVE_LRINTF, 1, [Define if lrintf() is available]))
+AC_CHECK_LIB(m, sincos,
+ AC_DEFINE(HAVE_SINCOS, 1, [Define if sincos() is available]))
+
+AC_CHECK_HEADER(ieee754.h,
+ AC_DEFINE(HAVE_IEEE754_H, 1, [Define if ieee754.h exists]))
+
+AC_CHECK_HEADERS([inttypes.h])
+AC_CHECK_HEADERS([sys/time.h])
+AC_CHECK_HEADERS([unistd.h])
+
+AC_CHECK_FUNCS([gettimeofday])
+AC_CHECK_FUNCS([sigaction])
+AC_CHECK_FUNCS([sigsetjmp])
+
+AC_CHECK_LIBM
+AC_SUBST(LIBM)
+
+AC_CHECK_LIB(rt, clock_gettime,
+ AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Defined if we have clock_gettime()])
+ LIBRT=-lrt
+ )
+AC_SUBST(LIBRT)
+
+AC_CACHE_CHECK(for monotonic clocks,
+ orc_cv_monotonic_clock,AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+#include <time.h>
+#include <unistd.h>
+int main() {
+#if !(defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 && defined(CLOCK_MONOTONIC))
+ #error No monotonic clock
+#endif
+ return 0;
+}
+]])],orc_cv_monotonic_clock=yes,orc_cv_monotonic_clock=no))
+if test "$orc_cv_monotonic_clock" = "yes"; then
+ AC_DEFINE(HAVE_MONOTONIC_CLOCK,1,[Defined if we have a monotonic clock])
+fi
+
+AS_COMPILER_FLAG(-Wall, ORC_CFLAGS="$ORC_CFLAGS -Wall")
+if test "x$ORC_CVS" = "xyes"
+then
+ AS_COMPILER_FLAG(-Werror, ORC_CFLAGS="$ORC_CFLAGS -Werror")
+fi
+
+AC_DEFINE(ORC_EXPORTS, 1, [Defined for compiling internal code])
+
+ORC_CFLAGS="$ORC_CFLAGS -D_BSD_SOURCE -D_GNU_SOURCE -I\$(top_srcdir) -DORC_ENABLE_UNSTABLE_API"
+AC_SUBST(ORC_CFLAGS)
+
+ORC_LIBS="\$(top_builddir)/orc/orc-$ORC_MAJORMINOR.la $LIBM $LIBRT"
+AC_SUBST(ORC_LIBS)
+
+pkgconfigdir="\$(libdir)/pkgconfig"
+AC_SUBST(pkgconfigdir)
+
+AC_CONFIG_FILES([
+Makefile
+doc/Makefile
+orc/Makefile
+testsuite/Makefile
+examples/Makefile
+orc-uninstalled.pc
+orc.pc
+])
+AC_OUTPUT
+
+
+
--- /dev/null
+## Process this file with automake to produce Makefile.in
+
+# We require automake 1.6 at least.
+AUTOMAKE_OPTIONS = 1.6
+
+# This is a blank Makefile.am for using gtk-doc.
+# Copy this to your project's API docs directory and modify the variables to
+# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
+# of using the various options.
+
+# The name of the module, e.g. 'glib'.
+DOC_MODULE=orc
+
+# The top-level SGML file. You can change this if you want to.
+DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
+
+# The directory containing the source code. Relative to $(srcdir).
+# gtk-doc will search all .c & .h files beneath here for inline comments
+# documenting the functions and macros.
+# e.g. DOC_SOURCE_DIR=../../../gtk
+DOC_SOURCE_DIR=../orc
+
+# Extra options to pass to gtkdoc-scangobj. Not normally needed.
+SCANGOBJ_OPTIONS=
+
+# Extra options to supply to gtkdoc-scan.
+# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
+SCAN_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkdb.
+# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
+MKDB_OPTIONS=--sgml-mode --output-format=xml
+
+# Extra options to supply to gtkdoc-fixref. Not normally needed.
+# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
+FIXXREF_OPTIONS=
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
+# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
+HFILE_GLOB=$(top_srcdir)/orc/*.h
+CFILE_GLOB=$(top_srcdir)/orc/*.c
+
+# Header files to ignore when scanning.
+# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
+IGNORE_HFILES=orc-stdint.h
+
+# Images to copy into HTML directory.
+# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
+HTML_IMAGES=
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
+# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
+content_files=
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+# Only needed if you are using gtkdoc-scangobj to dynamically query widget
+# signals and properties.
+# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
+# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
+INCLUDES=
+GTKDOC_LIBS=
+
+# This includes the standard gtk-doc make rules, copied by gtkdocize.
+include $(top_srcdir)/gtk-doc.make
+
+# Other files to distribute
+# e.g. EXTRA_DIST += version.xml.in
+EXTRA_DIST +=
+
+
+sync:
+ cd html && rsync -a . freedesktop.org:/srv/liboil.freedesktop.org/www/documentation/
+
--- /dev/null
+
+noinst_PROGRAMS = jit simple
+
+AM_LDFLAGS = $(ORC_LIBS) $(GLIB_LIBS)
+AM_CFLAGS = $(ORC_CFLAGS) $(GLIB_CFLAGS)
+
+jit_SOURCES = jit.c
+
+simple_SOURCES = simple.c
+
--- /dev/null
+
+#include "config.h"
+
+#include <glib.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, "s16", "d1");
+ s1 = orc_program_add_source (p, "s16", "s1");
+ s2 = orc_program_add_source (p, "s16", "s2");
+ t1 = orc_program_add_temporary (p, "s16", "t1");
+ offset = orc_program_add_constant (p, "s16", 1, "offset");
+ shift = orc_program_add_constant (p, "s16", 1, "shift");
+
+ orc_program_append (p, "add_s16", t1, s1, s2);
+ orc_program_append (p, "add_s16", t1, t1, offset);
+ orc_program_append (p, "rshift_s16", d1, t1, shift);
+
+#if 0
+ orc_program_append (p, "lshift_s16", d1, s1, shift);
+ //orc_program_append (p, "sub_s16", t1, t1, shift);
+ //orc_program_append (p, "mul_s16", d1, s1, s2);
+ //orc_program_append (p, "_loadi_s16", t1, t1, shift);
+#endif
+
+ 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;
+ }
+}
+
--- /dev/null
+
+#include "config.h"
+
+#include <glib.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];
+
+void test1(void);
+void test2(void);
+
+int
+main (int argc, char *argv[])
+{
+ orc_init ();
+
+ test1();
+
+ exit(0);
+}
+
+
+void
+test1(void)
+{
+ OrcProgram *p;
+ OrcExecutor *ex;
+
+ p = orc_program_new_dss ("s16", "s16", "s16");
+
+ orc_program_append_str (p, "add_s16", "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, "s16", "d1");
+ s1 = orc_program_add_source (p, "s16", "s1");
+ s2 = orc_program_add_source (p, "s16", "s2");
+ s3 = orc_program_add_source (p, "s16", "s3");
+ s4 = orc_program_add_source (p, "s16", "s4");
+ c1 = orc_program_add_constant (p, "s16", 3, "c1");
+ c2 = orc_program_add_constant (p, "s16", 4, "c2");
+ c3 = orc_program_add_constant (p, "s16", 3, "c3");
+ t1 = orc_program_add_temporary (p, "s16", "t1");
+ t2 = orc_program_add_temporary (p, "s16", "t2");
+
+ orc_program_append (p, "add_s16", t1, s2, s3);
+ orc_program_append (p, "add_s16", t2, s1, s4);
+ orc_program_append (p, "mul_s16", t1, t1, c1);
+ orc_program_append (p, "sub_s16", t1, t1, t2);
+ orc_program_append (p, "add_s16", t1, t1, c2);
+ orc_program_append (p, "rshift_s16", 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 0
+ 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);
+ 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);
+}
+
+
--- /dev/null
+# -*- mode: makefile -*-
+
+####################################
+# Everything below here is generic #
+####################################
+
+if GTK_DOC_USE_LIBTOOL
+GTKDOC_CC = $(LIBTOOL) --mode=compile $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+GTKDOC_LD = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS)
+else
+GTKDOC_CC = $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+GTKDOC_LD = $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS)
+endif
+
+# We set GPATH here; this gives us semantics for GNU make
+# which are more like other make's VPATH, when it comes to
+# whether a source that is a target of one rule is then
+# searched for in VPATH/GPATH.
+#
+GPATH = $(srcdir)
+
+TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE)
+
+EXTRA_DIST = \
+ $(content_files) \
+ $(HTML_IMAGES) \
+ $(DOC_MAIN_SGML_FILE) \
+ $(DOC_MODULE)-sections.txt \
+ $(DOC_MODULE)-overrides.txt
+
+DOC_STAMPS=scan-build.stamp tmpl-build.stamp sgml-build.stamp html-build.stamp \
+ $(srcdir)/tmpl.stamp $(srcdir)/sgml.stamp $(srcdir)/html.stamp
+
+SCANOBJ_FILES = \
+ $(DOC_MODULE).args \
+ $(DOC_MODULE).hierarchy \
+ $(DOC_MODULE).interfaces \
+ $(DOC_MODULE).prerequisites \
+ $(DOC_MODULE).signals
+
+REPORT_FILES = \
+ $(DOC_MODULE)-undocumented.txt \
+ $(DOC_MODULE)-undeclared.txt \
+ $(DOC_MODULE)-unused.txt
+
+CLEANFILES = $(SCANOBJ_FILES) $(REPORT_FILES) $(DOC_STAMPS)
+
+if ENABLE_GTK_DOC
+all-local: html-build.stamp
+else
+all-local:
+endif
+
+docs: html-build.stamp
+
+#### scan ####
+
+scan-build.stamp: $(HFILE_GLOB) $(CFILE_GLOB)
+ @echo 'gtk-doc: Scanning header files'
+ @-chmod -R u+w $(srcdir)
+ cd $(srcdir) && \
+ gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers="$(IGNORE_HFILES)" $(SCAN_OPTIONS) $(EXTRA_HFILES)
+ if grep -l '^..*$$' $(srcdir)/$(DOC_MODULE).types > /dev/null 2>&1 ; then \
+ CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" CFLAGS="$(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" gtkdoc-scangobj $(SCANGOBJ_OPTIONS) --module=$(DOC_MODULE) --output-dir=$(srcdir) ; \
+ else \
+ cd $(srcdir) ; \
+ for i in $(SCANOBJ_FILES) ; do \
+ test -f $$i || touch $$i ; \
+ done \
+ fi
+ touch scan-build.stamp
+
+$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt: scan-build.stamp
+ @true
+
+#### templates ####
+
+tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt
+ @echo 'gtk-doc: Rebuilding template files'
+ @-chmod -R u+w $(srcdir)
+ cd $(srcdir) && gtkdoc-mktmpl --module=$(DOC_MODULE) $(MKTMPL_OPTIONS)
+ touch tmpl-build.stamp
+
+tmpl.stamp: tmpl-build.stamp
+ @true
+
+tmpl/*.sgml:
+ @true
+
+
+#### xml ####
+
+sgml-build.stamp: tmpl.stamp $(HFILE_GLOB) $(CFILE_GLOB) $(DOC_MODULE)-sections.txt $(srcdir)/tmpl/*.sgml $(expand_content_files)
+ @echo 'gtk-doc: Building XML'
+ @-chmod -R u+w $(srcdir)
+ cd $(srcdir) && \
+ gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --output-format=xml --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) $(MKDB_OPTIONS)
+ touch sgml-build.stamp
+
+sgml.stamp: sgml-build.stamp
+ @true
+
+#### html ####
+
+html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files)
+ @echo 'gtk-doc: Building HTML'
+ @-chmod -R u+w $(srcdir)
+ rm -rf $(srcdir)/html
+ mkdir $(srcdir)/html
+ cd $(srcdir)/html && gtkdoc-mkhtml $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE)
+ test "x$(HTML_IMAGES)" = "x" || ( cd $(srcdir) && cp $(HTML_IMAGES) html )
+ @echo 'gtk-doc: Fixing cross-references'
+ cd $(srcdir) && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS)
+ touch html-build.stamp
+
+##############
+
+clean-local:
+ rm -f *~ *.bak
+ rm -rf .libs
+
+distclean-local:
+ cd $(srcdir) && \
+ rm -rf xml $(REPORT_FILES) \
+ $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt
+
+maintainer-clean-local: clean
+ cd $(srcdir) && rm -rf xml html
+
+install-data-local:
+ -installfiles=`echo $(srcdir)/html/*`; \
+ if test "$$installfiles" = '$(srcdir)/html/*'; \
+ then echo '-- Nothing to install' ; \
+ else \
+ $(mkinstalldirs) $(DESTDIR)$(TARGET_DIR); \
+ for i in $$installfiles; do \
+ echo '-- Installing '$$i ; \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \
+ done; \
+ echo '-- Installing $(srcdir)/html/index.sgml' ; \
+ $(INSTALL_DATA) $(srcdir)/html/index.sgml $(DESTDIR)$(TARGET_DIR) || :; \
+ which gtkdoc-rebase >/dev/null && \
+ gtkdoc-rebase --relative --dest-dir=$(DESTDIR) --html-dir=$(DESTDIR)$(TARGET_DIR) ; \
+ fi
+
+
+uninstall-local:
+ rm -f $(DESTDIR)$(TARGET_DIR)/*
+
+#
+# Require gtk-doc when making dist
+#
+if ENABLE_GTK_DOC
+dist-check-gtkdoc:
+else
+dist-check-gtkdoc:
+ @echo "*** gtk-doc must be installed and enabled in order to make dist"
+ @false
+endif
+
+dist-hook: dist-check-gtkdoc dist-hook-local
+ mkdir $(distdir)/tmpl
+ mkdir $(distdir)/xml
+ mkdir $(distdir)/html
+ -cp $(srcdir)/tmpl/*.sgml $(distdir)/tmpl
+ -cp $(srcdir)/xml/*.xml $(distdir)/xml
+ cp $(srcdir)/html/* $(distdir)/html
+ -cp $(srcdir)/$(DOC_MODULE).types $(distdir)/
+ -cp $(srcdir)/$(DOC_MODULE)-sections.txt $(distdir)/
+ cd $(distdir) && rm -f $(DISTCLEANFILES)
+ -gtkdoc-rebase --online --relative --html-dir=$(distdir)/html
+
+.PHONY : dist-hook-local docs
--- /dev/null
+
+# backported from libtool 1.6 by Paolo Bonzini
+# When AC_LIBTOOL_TAGS is used, I redefine _LT_AC_TAGCONFIG
+# to be more similar to the libtool 1.6 implementation, which
+# uses an m4 loop and m4 case instead of a shell loop. This
+# way the CXX/GCJ/F77/RC tests are not always expanded.
+
+# AC_LIBTOOL_TAGS
+# ---------------
+# tags to enable
+AC_DEFUN([AC_LIBTOOL_TAGS],
+[m4_define([_LT_TAGS],[$1])
+m4_define([_LT_AC_TAGCONFIG], [
+ if test -f "$ltmain"; then
+ if test ! -f "${ofile}"; then
+ AC_MSG_WARN([output file `$ofile' does not exist])
+ fi
+
+ if test -z "$LTCC"; then
+ eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
+ if test -z "$LTCC"; then
+ AC_MSG_WARN([output file `$ofile' does not look like a libtool script])
+ else
+ AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile'])
+ fi
+ fi
+
+ AC_FOREACH([_LT_TAG], _LT_TAGS,
+ [m4_case(_LT_TAG,
+ [CXX], [
+ if test -n "$CXX" && test "X$CXX" != "Xno"; then
+ AC_LIBTOOL_LANG_CXX_CONFIG
+ available_tags="$available_tags _LT_TAG"
+ fi],
+ [F77], [
+ if test -n "$F77" && test "X$F77" != "Xno"; then
+ AC_LIBTOOL_LANG_F77_CONFIG
+ available_tags="$available_tags _LT_TAG"
+ fi],
+ [GCJ], [
+ if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
+ AC_LIBTOOL_LANG_GCJ_CONFIG
+ available_tags="$available_tags _LT_TAG"
+ fi],
+ [RC], [
+ if test -n "$RC" && test "X$RC" != "Xno"; then
+ AC_LIBTOOL_LANG_RC_CONFIG
+ available_tags="$available_tags _LT_TAG"
+ fi],
+ [m4_errprintn(m4_location[: error: invalid tag name: ]"_LT_TAG")
+ m4_exit(1)])
+ ])
+ fi
+
+])dnl _LT_AC_TAG_CONFIG
+])
+
--- /dev/null
+dnl as-compiler-flag.m4 0.1.0
+
+dnl autostars m4 macro for detection of compiler flags
+
+dnl David Schleef <ds@schleef.org>
+
+dnl $Id: as-compiler-flag.m4,v 1.1 2004-08-20 22:25:22 ds Exp $
+
+dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED])
+dnl Tries to compile with the given CFLAGS.
+dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags,
+dnl and ACTION-IF-NOT-ACCEPTED otherwise.
+
+AC_DEFUN([AS_COMPILER_FLAG],
+[
+ AC_MSG_CHECKING([to see if compiler understands $1])
+
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $1"
+
+ AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no])
+ CFLAGS="$save_CFLAGS"
+
+ if test "X$flag_ok" = Xyes ; then
+ $2
+ true
+ else
+ $3
+ true
+ fi
+ AC_MSG_RESULT([$flag_ok])
+])
+
--- /dev/null
+dnl as-host-defines.m4 0.1.0
+
+dnl autostars m4 macro for generating defines for various host architectures
+
+dnl David Schleef <ds@schleef.org>
+
+dnl $Id: as-host-defines.m4,v 1.3 2007-08-22 20:55:24 uid2631 Exp $
+
+dnl AS_HOST_DEFINES()
+
+AC_DEFUN([AS_HOST_DEFINES],
+[
+ case "x${host_cpu}" in
+ xi?86 | k?)
+ HAVE_I386=yes
+ AC_DEFINE(HAVE_I386, 1, [Defined if host is i386])
+ ;;
+ xx86_64|xamd64)
+ HAVE_AMD64=yes
+ AC_DEFINE(HAVE_AMD64, 1, [Defined if host is amd64])
+ ;;
+ xpowerpc|xppc|xpowerpc64|xppc64)
+ HAVE_POWERPC=yes
+ AC_DEFINE(HAVE_POWERPC, 1, [Defined if host is powerpc])
+ ;;
+ xarm)
+ HAVE_ARM=yes
+ AC_DEFINE(HAVE_ARM, 1, [Defined if host is arm])
+ ;;
+ esac
+
+AM_CONDITIONAL(HAVE_I386, test "x$HAVE_I386" = "xyes")
+AM_CONDITIONAL(HAVE_AMD64, test "x$HAVE_AMD64" = "xyes")
+AM_CONDITIONAL(HAVE_POWERPC, test "x$HAVE_POWERPC" = "xyes")
+AM_CONDITIONAL(HAVE_ARM, test "x$HAVE_ARM" = "xyes")
+
+ case "${host_os}" in
+ mingw*)
+ HAVE_OS_WIN32=yes
+ AC_DEFINE(HAVE_OS_WIN32, 1, [Defined if host OS is MS Windows])
+ ;;
+ linux*)
+ HAVE_OS_LINUX=yes
+ AC_DEFINE(HAVE_OS_LINUX, 1, [Defined if host OS is linux])
+ ;;
+ esac
+
+AM_CONDITIONAL(HAVE_OS_WIN32, test "$HAVE_WIN32" = "yes")
+AM_CONDITIONAL(HAVE_OS_LINUX, test "$HAVE_LINUX" = "yes")
+
+])
+
--- /dev/null
+dnl as-libtool.m4 0.1.0
+dnl autostars m4 macro for libtool versioning
+dnl thomas@apestaart.org
+dnl
+dnl AS_LIBTOOL(PREFIX, CURRENT, REVISION, AGE, RELEASE)
+dnl example
+dnl AS_VERSION(GST, 2, 0, 0)
+dnl
+dnl this macro
+dnl - defines [$PREFIX]_CURRENT, REVISION AND AGE
+dnl - defines [$PREFIX]_LIBVERSION
+dnl - defines [$PREFIX]_LT_LDFLAGS to set versioning
+dnl - AC_SUBST's them all
+dnl
+dnl if USE_RELEASE is used, then add a -release option to the LDFLAGS
+dnl with the given release version
+dnl then use [$PREFIX]_LT_LDFLAGS in the relevant Makefile.am's
+
+AC_DEFUN([AS_LIBTOOL],
+[
+ [$1]_CURRENT=[$2]
+ [$1]_REVISION=[$3]
+ [$1]_AGE=[$4]
+ [$1]_LIBVERSION=[$2]:[$3]:[$4]
+ AC_SUBST([$1]_CURRENT)
+ AC_SUBST([$1]_REVISION)
+ AC_SUBST([$1]_AGE)
+ AC_SUBST([$1]_LIBVERSION)
+
+dnl [$1]_LT_LDFLAGS="$[$1]_LT_LDFLAGS -version-info $[$1]_LIBVERSION"
+ if test ! -z "[$5]"
+ then
+ [$1]_LT_LDFLAGS="$[$1]_LT_LDFLAGS -release [$5]"
+ fi
+ AC_SUBST([$1]_LT_LDFLAGS)
+
+ AC_LIBTOOL_DLOPEN
+ AM_PROG_LIBTOOL
+])
--- /dev/null
+dnl as-version.m4 0.1.0
+
+dnl autostars m4 macro for versioning (modified)
+
+dnl Thomas Vander Stichele <thomas at apestaart dot org>
+dnl David Schleef <ds@schleef.org>
+
+dnl $Id: as-nano.m4,v 1.2 2007-03-16 23:30:02 ds Exp $
+
+dnl AS_VERSION(ACTION-IF-NO-NANO, [ACTION-IF-NANO])
+
+AC_DEFUN([AS_NANO],
+[
+ AC_MSG_CHECKING(nano version)
+
+ NANO=$(echo AC_PACKAGE_VERSION | sed ['s/[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.*//'])
+ AC_SUBST(NANO)
+
+ if test x"$NANO" = x || test "x$NANO" = "x0" ; then
+ AC_MSG_RESULT([0 (release)])
+ NANO=0
+ ifelse([$1], , :, [$1])
+ else
+ AC_MSG_RESULT($NANO)
+ ifelse([$2], , :, [$2])
+ fi
+])
--- /dev/null
+##### http://autoconf-archive.cryp.to/ax_create_stdint_h.html
+#
+# SYNOPSIS
+#
+# AX_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEDERS-TO-CHECK])]
+#
+# DESCRIPTION
+#
+# the "ISO C9X: 7.18 Integer types <stdint.h>" section requires the
+# existence of an include file <stdint.h> that defines a set of
+# typedefs, especially uint8_t,int32_t,uintptr_t. Many older
+# installations will not provide this file, but some will have the
+# very same definitions in <inttypes.h>. In other enviroments we can
+# use the inet-types in <sys/types.h> which would define the typedefs
+# int8_t and u_int8_t respectivly.
+#
+# This macros will create a local "_stdint.h" or the headerfile given
+# as an argument. In many cases that file will just "#include
+# <stdint.h>" or "#include <inttypes.h>", while in other environments
+# it will provide the set of basic 'stdint's definitions/typedefs:
+#
+# int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t
+# int_least32_t.. int_fast32_t.. intmax_t
+#
+# which may or may not rely on the definitions of other files, or
+# using the AC_CHECK_SIZEOF macro to determine the actual sizeof each
+# type.
+#
+# if your header files require the stdint-types you will want to
+# create an installable file mylib-int.h that all your other
+# installable header may include. So if you have a library package
+# named "mylib", just use
+#
+# AX_CREATE_STDINT_H(mylib-int.h)
+#
+# in configure.ac and go to install that very header file in
+# Makefile.am along with the other headers (mylib.h) - and the
+# mylib-specific headers can simply use "#include <mylib-int.h>" to
+# obtain the stdint-types.
+#
+# Remember, if the system already had a valid <stdint.h>, the
+# generated file will include it directly. No need for fuzzy
+# HAVE_STDINT_H things... (oops, GCC 4.2.x has deliberatly disabled
+# its stdint.h for non-c99 compilation and the c99-mode is not the
+# default. Therefore this macro will not use the compiler's stdint.h
+# - please complain to the GCC developers).
+#
+# LAST MODIFICATION
+#
+# 2007-06-27
+#
+# COPYLEFT
+#
+# Copyright (c) 2007 Guido U. Draheim <guidod@gmx.de>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# As a special exception, the respective Autoconf Macro's copyright
+# owner gives unlimited permission to copy, distribute and modify the
+# configure scripts that are the output of Autoconf when processing
+# the Macro. You need not follow the terms of the GNU General Public
+# License when using or distributing such scripts, even though
+# portions of the text of the Macro appear in them. The GNU General
+# Public License (GPL) does govern all other use of the material that
+# constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the
+# Autoconf Macro released by the Autoconf Macro Archive. When you
+# make and distribute a modified version of the Autoconf Macro, you
+# may extend this special exception to the GPL to apply to your
+# modified version as well.
+
+AC_DEFUN([AX_CHECK_DATA_MODEL],[
+ AC_CHECK_SIZEOF(char)
+ AC_CHECK_SIZEOF(short)
+ AC_CHECK_SIZEOF(int)
+ AC_CHECK_SIZEOF(long)
+ AC_CHECK_SIZEOF(void*)
+ ac_cv_char_data_model=""
+ ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_char"
+ ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_short"
+ ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_int"
+ ac_cv_long_data_model=""
+ ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_int"
+ ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_long"
+ ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_voidp"
+ AC_MSG_CHECKING([data model])
+ case "$ac_cv_char_data_model/$ac_cv_long_data_model" in
+ 122/242) ac_cv_data_model="IP16" ; n="standard 16bit machine" ;;
+ 122/244) ac_cv_data_model="LP32" ; n="standard 32bit machine" ;;
+ 122/*) ac_cv_data_model="i16" ; n="unusual int16 model" ;;
+ 124/444) ac_cv_data_model="ILP32" ; n="standard 32bit unixish" ;;
+ 124/488) ac_cv_data_model="LP64" ; n="standard 64bit unixish" ;;
+ 124/448) ac_cv_data_model="LLP64" ; n="unusual 64bit unixish" ;;
+ 124/*) ac_cv_data_model="i32" ; n="unusual int32 model" ;;
+ 128/888) ac_cv_data_model="ILP64" ; n="unusual 64bit numeric" ;;
+ 128/*) ac_cv_data_model="i64" ; n="unusual int64 model" ;;
+ 222/*2) ac_cv_data_model="DSP16" ; n="strict 16bit dsptype" ;;
+ 333/*3) ac_cv_data_model="DSP24" ; n="strict 24bit dsptype" ;;
+ 444/*4) ac_cv_data_model="DSP32" ; n="strict 32bit dsptype" ;;
+ 666/*6) ac_cv_data_model="DSP48" ; n="strict 48bit dsptype" ;;
+ 888/*8) ac_cv_data_model="DSP64" ; n="strict 64bit dsptype" ;;
+ 222/*|333/*|444/*|666/*|888/*) :
+ ac_cv_data_model="iDSP" ; n="unusual dsptype" ;;
+ *) ac_cv_data_model="none" ; n="very unusual model" ;;
+ esac
+ AC_MSG_RESULT([$ac_cv_data_model ($ac_cv_long_data_model, $n)])
+])
+
+dnl AX_CHECK_HEADER_STDINT_X([HEADERLIST][,ACTION-IF])
+AC_DEFUN([AX_CHECK_HEADER_STDINT_X],[
+AC_CACHE_CHECK([for stdint uintptr_t], [ac_cv_header_stdint_x],[
+ ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h)
+ AC_MSG_RESULT([(..)])
+ for i in m4_ifval([$1],[$1],[stdint.h inttypes.h sys/inttypes.h sys/types.h])
+ do
+ unset ac_cv_type_uintptr_t
+ unset ac_cv_type_uint64_t
+ AC_CHECK_TYPE(uintptr_t,[ac_cv_header_stdint_x=$i],continue,[#include <$i>])
+ AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>])
+ m4_ifvaln([$2],[$2]) break
+ done
+ AC_MSG_CHECKING([for stdint uintptr_t])
+ ])
+])
+
+AC_DEFUN([AX_CHECK_HEADER_STDINT_O],[
+AC_CACHE_CHECK([for stdint uint32_t], [ac_cv_header_stdint_o],[
+ ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h)
+ AC_MSG_RESULT([(..)])
+ for i in m4_ifval([$1],[$1],[inttypes.h sys/inttypes.h sys/types.h stdint.h])
+ do
+ unset ac_cv_type_uint32_t
+ unset ac_cv_type_uint64_t
+ AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],continue,[#include <$i>])
+ AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>])
+ m4_ifvaln([$2],[$2]) break
+ break;
+ done
+ AC_MSG_CHECKING([for stdint uint32_t])
+ ])
+])
+
+AC_DEFUN([AX_CHECK_HEADER_STDINT_U],[
+AC_CACHE_CHECK([for stdint u_int32_t], [ac_cv_header_stdint_u],[
+ ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h)
+ AC_MSG_RESULT([(..)])
+ for i in m4_ifval([$1],[$1],[sys/types.h inttypes.h sys/inttypes.h]) ; do
+ unset ac_cv_type_u_int32_t
+ unset ac_cv_type_u_int64_t
+ AC_CHECK_TYPE(u_int32_t,[ac_cv_header_stdint_u=$i],continue,[#include <$i>])
+ AC_CHECK_TYPE(u_int64_t,[and64="/u_int64_t"],[and64=""],[#include<$i>])
+ m4_ifvaln([$2],[$2]) break
+ break;
+ done
+ AC_MSG_CHECKING([for stdint u_int32_t])
+ ])
+])
+
+AC_DEFUN([AX_CREATE_STDINT_H],
+[# ------ AX CREATE STDINT H -------------------------------------
+AC_MSG_CHECKING([for stdint types])
+ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)`
+# try to shortcircuit - if the default include path of the compiler
+# can find a "stdint.h" header then we assume that all compilers can.
+AC_CACHE_VAL([ac_cv_header_stdint_t],[
+old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS=""
+old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS=""
+old_CFLAGS="$CFLAGS" ; CFLAGS=""
+AC_TRY_COMPILE([#include <stdint.h>],[int_least32_t v = 0;],
+[ac_cv_stdint_result="(assuming C99 compatible system)"
+ ac_cv_header_stdint_t="stdint.h"; ],
+[ac_cv_header_stdint_t=""])
+if test "$GCC" = "yes" && test ".$ac_cv_header_stdint_t" = "."; then
+CFLAGS="-std=c99"
+AC_TRY_COMPILE([#include <stdint.h>],[int_least32_t v = 0;],
+[AC_MSG_WARN(your GCC compiler has a defunct stdint.h for its default-mode)])
+fi
+CXXFLAGS="$old_CXXFLAGS"
+CPPFLAGS="$old_CPPFLAGS"
+CFLAGS="$old_CFLAGS" ])
+
+v="... $ac_cv_header_stdint_h"
+if test "$ac_stdint_h" = "stdint.h" ; then
+ AC_MSG_RESULT([(are you sure you want them in ./stdint.h?)])
+elif test "$ac_stdint_h" = "inttypes.h" ; then
+ AC_MSG_RESULT([(are you sure you want them in ./inttypes.h?)])
+elif test "_$ac_cv_header_stdint_t" = "_" ; then
+ AC_MSG_RESULT([(putting them into $ac_stdint_h)$v])
+else
+ ac_cv_header_stdint="$ac_cv_header_stdint_t"
+ AC_MSG_RESULT([$ac_cv_header_stdint (shortcircuit)])
+fi
+
+if test "_$ac_cv_header_stdint_t" = "_" ; then # can not shortcircuit..
+
+dnl .....intro message done, now do a few system checks.....
+dnl btw, all old CHECK_TYPE macros do automatically "DEFINE" a type,
+dnl therefore we use the autoconf implementation detail CHECK_TYPE_NEW
+dnl instead that is triggered with 3 or more arguments (see types.m4)
+
+inttype_headers=`echo $2 | sed -e 's/,/ /g'`
+
+ac_cv_stdint_result="(no helpful system typedefs seen)"
+AX_CHECK_HEADER_STDINT_X(dnl
+ stdint.h inttypes.h sys/inttypes.h $inttype_headers,
+ ac_cv_stdint_result="(seen uintptr_t$and64 in $i)")
+
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+AX_CHECK_HEADER_STDINT_O(dnl,
+ inttypes.h sys/inttypes.h stdint.h $inttype_headers,
+ ac_cv_stdint_result="(seen uint32_t$and64 in $i)")
+fi
+
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+if test "_$ac_cv_header_stdint_o" = "_" ; then
+AX_CHECK_HEADER_STDINT_U(dnl,
+ sys/types.h inttypes.h sys/inttypes.h $inttype_headers,
+ ac_cv_stdint_result="(seen u_int32_t$and64 in $i)")
+fi fi
+
+dnl if there was no good C99 header file, do some typedef checks...
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+ AC_MSG_CHECKING([for stdint datatype model])
+ AC_MSG_RESULT([(..)])
+ AX_CHECK_DATA_MODEL
+fi
+
+if test "_$ac_cv_header_stdint_x" != "_" ; then
+ ac_cv_header_stdint="$ac_cv_header_stdint_x"
+elif test "_$ac_cv_header_stdint_o" != "_" ; then
+ ac_cv_header_stdint="$ac_cv_header_stdint_o"
+elif test "_$ac_cv_header_stdint_u" != "_" ; then
+ ac_cv_header_stdint="$ac_cv_header_stdint_u"
+else
+ ac_cv_header_stdint="stddef.h"
+fi
+
+AC_MSG_CHECKING([for extra inttypes in chosen header])
+AC_MSG_RESULT([($ac_cv_header_stdint)])
+dnl see if int_least and int_fast types are present in _this_ header.
+unset ac_cv_type_int_least32_t
+unset ac_cv_type_int_fast32_t
+AC_CHECK_TYPE(int_least32_t,,,[#include <$ac_cv_header_stdint>])
+AC_CHECK_TYPE(int_fast32_t,,,[#include<$ac_cv_header_stdint>])
+AC_CHECK_TYPE(intmax_t,,,[#include <$ac_cv_header_stdint>])
+
+fi # shortcircut to system "stdint.h"
+# ------------------ PREPARE VARIABLES ------------------------------
+if test "$GCC" = "yes" ; then
+ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1`
+else
+ac_cv_stdint_message="using $CC"
+fi
+
+AC_MSG_RESULT([make use of $ac_cv_header_stdint in $ac_stdint_h dnl
+$ac_cv_stdint_result])
+
+dnl -----------------------------------------------------------------
+# ----------------- DONE inttypes.h checks START header -------------
+AC_CONFIG_COMMANDS([$ac_stdint_h],[
+AC_MSG_NOTICE(creating $ac_stdint_h : $_ac_stdint_h)
+ac_stdint=$tmp/_stdint.h
+
+echo "#ifndef" $_ac_stdint_h >$ac_stdint
+echo "#define" $_ac_stdint_h "1" >>$ac_stdint
+echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint
+echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint
+echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint
+if test "_$ac_cv_header_stdint_t" != "_" ; then
+echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint
+echo "#include <stdint.h>" >>$ac_stdint
+echo "#endif" >>$ac_stdint
+echo "#endif" >>$ac_stdint
+else
+
+cat >>$ac_stdint <<STDINT_EOF
+
+/* ................... shortcircuit part ........................... */
+
+#if defined HAVE_STDINT_H || defined _STDINT_HAVE_STDINT_H
+#include <stdint.h>
+#else
+#include <stddef.h>
+
+/* .................... configured part ............................ */
+
+STDINT_EOF
+
+echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint
+if test "_$ac_cv_header_stdint_x" != "_" ; then
+ ac_header="$ac_cv_header_stdint_x"
+ echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint
+else
+ echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint
+fi
+
+echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint
+if test "_$ac_cv_header_stdint_o" != "_" ; then
+ ac_header="$ac_cv_header_stdint_o"
+ echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint
+else
+ echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint
+fi
+
+echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint
+if test "_$ac_cv_header_stdint_u" != "_" ; then
+ ac_header="$ac_cv_header_stdint_u"
+ echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint
+else
+ echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint
+fi
+
+echo "" >>$ac_stdint
+
+if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then
+ echo "#include <$ac_header>" >>$ac_stdint
+ echo "" >>$ac_stdint
+fi fi
+
+echo "/* which 64bit typedef has been found */" >>$ac_stdint
+if test "$ac_cv_type_uint64_t" = "yes" ; then
+echo "#define _STDINT_HAVE_UINT64_T" "1" >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint
+fi
+if test "$ac_cv_type_u_int64_t" = "yes" ; then
+echo "#define _STDINT_HAVE_U_INT64_T" "1" >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+echo "/* which type model has been detected */" >>$ac_stdint
+if test "_$ac_cv_char_data_model" != "_" ; then
+echo "#define _STDINT_CHAR_MODEL" "$ac_cv_char_data_model" >>$ac_stdint
+echo "#define _STDINT_LONG_MODEL" "$ac_cv_long_data_model" >>$ac_stdint
+else
+echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint
+echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+echo "/* whether int_least types were detected */" >>$ac_stdint
+if test "$ac_cv_type_int_least32_t" = "yes"; then
+echo "#define _STDINT_HAVE_INT_LEAST32_T" "1" >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint
+fi
+echo "/* whether int_fast types were detected */" >>$ac_stdint
+if test "$ac_cv_type_int_fast32_t" = "yes"; then
+echo "#define _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint
+fi
+echo "/* whether intmax_t type was detected */" >>$ac_stdint
+if test "$ac_cv_type_intmax_t" = "yes"; then
+echo "#define _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+ cat >>$ac_stdint <<STDINT_EOF
+/* .................... detections part ............................ */
+
+/* whether we need to define bitspecific types from compiler base types */
+#ifndef _STDINT_HEADER_INTPTR
+#ifndef _STDINT_HEADER_UINT32
+#ifndef _STDINT_HEADER_U_INT32
+#define _STDINT_NEED_INT_MODEL_T
+#else
+#define _STDINT_HAVE_U_INT_TYPES
+#endif
+#endif
+#endif
+
+#ifdef _STDINT_HAVE_U_INT_TYPES
+#undef _STDINT_NEED_INT_MODEL_T
+#endif
+
+#ifdef _STDINT_CHAR_MODEL
+#if _STDINT_CHAR_MODEL+0 == 122 || _STDINT_CHAR_MODEL+0 == 124
+#ifndef _STDINT_BYTE_MODEL
+#define _STDINT_BYTE_MODEL 12
+#endif
+#endif
+#endif
+
+#ifndef _STDINT_HAVE_INT_LEAST32_T
+#define _STDINT_NEED_INT_LEAST_T
+#endif
+
+#ifndef _STDINT_HAVE_INT_FAST32_T
+#define _STDINT_NEED_INT_FAST_T
+#endif
+
+#ifndef _STDINT_HEADER_INTPTR
+#define _STDINT_NEED_INTPTR_T
+#ifndef _STDINT_HAVE_INTMAX_T
+#define _STDINT_NEED_INTMAX_T
+#endif
+#endif
+
+
+/* .................... definition part ............................ */
+
+/* some system headers have good uint64_t */
+#ifndef _HAVE_UINT64_T
+#if defined _STDINT_HAVE_UINT64_T || defined HAVE_UINT64_T
+#define _HAVE_UINT64_T
+#elif defined _STDINT_HAVE_U_INT64_T || defined HAVE_U_INT64_T
+#define _HAVE_UINT64_T
+typedef u_int64_t uint64_t;
+#endif
+#endif
+
+#ifndef _HAVE_UINT64_T
+/* .. here are some common heuristics using compiler runtime specifics */
+#if defined __STDC_VERSION__ && defined __STDC_VERSION__ >= 199901L
+#define _HAVE_UINT64_T
+#define _HAVE_LONGLONG_UINT64_T
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+
+#elif !defined __STRICT_ANSI__
+#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__
+#define _HAVE_UINT64_T
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__
+/* note: all ELF-systems seem to have loff-support which needs 64-bit */
+#if !defined _NO_LONGLONG
+#define _HAVE_UINT64_T
+#define _HAVE_LONGLONG_UINT64_T
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+#endif
+
+#elif defined __alpha || (defined __mips && defined _ABIN32)
+#if !defined _NO_LONGLONG
+typedef long int64_t;
+typedef unsigned long uint64_t;
+#endif
+ /* compiler/cpu type to define int64_t */
+#endif
+#endif
+#endif
+
+#if defined _STDINT_HAVE_U_INT_TYPES
+/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */
+typedef u_int8_t uint8_t;
+typedef u_int16_t uint16_t;
+typedef u_int32_t uint32_t;
+
+/* glibc compatibility */
+#ifndef __int8_t_defined
+#define __int8_t_defined
+#endif
+#endif
+
+#ifdef _STDINT_NEED_INT_MODEL_T
+/* we must guess all the basic types. Apart from byte-adressable system, */
+/* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */
+/* (btw, those nibble-addressable systems are way off, or so we assume) */
+
+dnl /* have a look at "64bit and data size neutrality" at */
+dnl /* http://unix.org/version2/whatsnew/login_64bit.html */
+dnl /* (the shorthand "ILP" types always have a "P" part) */
+
+#if defined _STDINT_BYTE_MODEL
+#if _STDINT_LONG_MODEL+0 == 242
+/* 2:4:2 = IP16 = a normal 16-bit system */
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef char int8_t;
+typedef short int16_t;
+typedef long int32_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444
+/* 2:4:4 = LP32 = a 32-bit system derived from a 16-bit */
+/* 4:4:4 = ILP32 = a normal 32-bit system */
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488
+/* 4:8:4 = IP32 = a 32-bit system prepared for 64-bit */
+/* 4:8:8 = LP64 = a normal 64-bit system */
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+#endif
+/* this system has a "long" of 64bit */
+#ifndef _HAVE_UINT64_T
+#define _HAVE_UINT64_T
+typedef unsigned long uint64_t;
+typedef long int64_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 448
+/* LLP64 a 64-bit system derived from a 32-bit system */
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+#endif
+/* assuming the system has a "long long" */
+#ifndef _HAVE_UINT64_T
+#define _HAVE_UINT64_T
+#define _HAVE_LONGLONG_UINT64_T
+typedef unsigned long long uint64_t;
+typedef long long int64_t;
+#endif
+#else
+#define _STDINT_NO_INT32_T
+#endif
+#else
+#define _STDINT_NO_INT8_T
+#define _STDINT_NO_INT32_T
+#endif
+#endif
+
+/*
+ * quote from SunOS-5.8 sys/inttypes.h:
+ * Use at your own risk. As of February 1996, the committee is squarely
+ * behind the fixed sized types; the "least" and "fast" types are still being
+ * discussed. The probability that the "fast" types may be removed before
+ * the standard is finalized is high enough that they are not currently
+ * implemented.
+ */
+
+#if defined _STDINT_NEED_INT_LEAST_T
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+#ifdef _HAVE_UINT64_T
+typedef int64_t int_least64_t;
+#endif
+
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+#ifdef _HAVE_UINT64_T
+typedef uint64_t uint_least64_t;
+#endif
+ /* least types */
+#endif
+
+#if defined _STDINT_NEED_INT_FAST_T
+typedef int8_t int_fast8_t;
+typedef int int_fast16_t;
+typedef int32_t int_fast32_t;
+#ifdef _HAVE_UINT64_T
+typedef int64_t int_fast64_t;
+#endif
+
+typedef uint8_t uint_fast8_t;
+typedef unsigned uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+#ifdef _HAVE_UINT64_T
+typedef uint64_t uint_fast64_t;
+#endif
+ /* fast types */
+#endif
+
+#ifdef _STDINT_NEED_INTMAX_T
+#ifdef _HAVE_UINT64_T
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+#else
+typedef long intmax_t;
+typedef unsigned long uintmax_t;
+#endif
+#endif
+
+#ifdef _STDINT_NEED_INTPTR_T
+#ifndef __intptr_t_defined
+#define __intptr_t_defined
+/* we encourage using "long" to store pointer values, never use "int" ! */
+#if _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484
+typedef unsigned int uintptr_t;
+typedef int intptr_t;
+#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444
+typedef unsigned long uintptr_t;
+typedef long intptr_t;
+#elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T
+typedef uint64_t uintptr_t;
+typedef int64_t intptr_t;
+#else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */
+typedef unsigned long uintptr_t;
+typedef long intptr_t;
+#endif
+#endif
+#endif
+
+/* The ISO C99 standard specifies that in C++ implementations these
+ should only be defined if explicitly requested. */
+#if !defined __cplusplus || defined __STDC_CONSTANT_MACROS
+#ifndef UINT32_C
+
+/* Signed. */
+# define INT8_C(c) c
+# define INT16_C(c) c
+# define INT32_C(c) c
+# ifdef _HAVE_LONGLONG_UINT64_T
+# define INT64_C(c) c ## L
+# else
+# define INT64_C(c) c ## LL
+# endif
+
+/* Unsigned. */
+# define UINT8_C(c) c ## U
+# define UINT16_C(c) c ## U
+# define UINT32_C(c) c ## U
+# ifdef _HAVE_LONGLONG_UINT64_T
+# define UINT64_C(c) c ## UL
+# else
+# define UINT64_C(c) c ## ULL
+# endif
+
+/* Maximal type. */
+# ifdef _HAVE_LONGLONG_UINT64_T
+# define INTMAX_C(c) c ## L
+# define UINTMAX_C(c) c ## UL
+# else
+# define INTMAX_C(c) c ## LL
+# define UINTMAX_C(c) c ## ULL
+# endif
+
+ /* literalnumbers */
+#endif
+#endif
+
+/* These limits are merily those of a two complement byte-oriented system */
+
+/* Minimum of signed integral types. */
+# define INT8_MIN (-128)
+# define INT16_MIN (-32767-1)
+# define INT32_MIN (-2147483647-1)
+# define INT64_MIN (-__INT64_C(9223372036854775807)-1)
+/* Maximum of signed integral types. */
+# define INT8_MAX (127)
+# define INT16_MAX (32767)
+# define INT32_MAX (2147483647)
+# define INT64_MAX (__INT64_C(9223372036854775807))
+
+/* Maximum of unsigned integral types. */
+# define UINT8_MAX (255)
+# define UINT16_MAX (65535)
+# define UINT32_MAX (4294967295U)
+# define UINT64_MAX (__UINT64_C(18446744073709551615))
+
+/* Minimum of signed integral types having a minimum size. */
+# define INT_LEAST8_MIN INT8_MIN
+# define INT_LEAST16_MIN INT16_MIN
+# define INT_LEAST32_MIN INT32_MIN
+# define INT_LEAST64_MIN INT64_MIN
+/* Maximum of signed integral types having a minimum size. */
+# define INT_LEAST8_MAX INT8_MAX
+# define INT_LEAST16_MAX INT16_MAX
+# define INT_LEAST32_MAX INT32_MAX
+# define INT_LEAST64_MAX INT64_MAX
+
+/* Maximum of unsigned integral types having a minimum size. */
+# define UINT_LEAST8_MAX UINT8_MAX
+# define UINT_LEAST16_MAX UINT16_MAX
+# define UINT_LEAST32_MAX UINT32_MAX
+# define UINT_LEAST64_MAX UINT64_MAX
+
+ /* shortcircuit*/
+#endif
+ /* once */
+#endif
+#endif
+STDINT_EOF
+fi
+ if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then
+ AC_MSG_NOTICE([$ac_stdint_h is unchanged])
+ else
+ ac_dir=`AS_DIRNAME(["$ac_stdint_h"])`
+ AS_MKDIR_P(["$ac_dir"])
+ rm -f $ac_stdint_h
+ mv $ac_stdint $ac_stdint_h
+ fi
+],[# variables for create stdint.h replacement
+PACKAGE="$PACKAGE"
+VERSION="$VERSION"
+ac_stdint_h="$ac_stdint_h"
+_ac_stdint_h=AS_TR_CPP(_$PACKAGE-$ac_stdint_h)
+ac_cv_stdint_message="$ac_cv_stdint_message"
+ac_cv_header_stdint_t="$ac_cv_header_stdint_t"
+ac_cv_header_stdint_x="$ac_cv_header_stdint_x"
+ac_cv_header_stdint_o="$ac_cv_header_stdint_o"
+ac_cv_header_stdint_u="$ac_cv_header_stdint_u"
+ac_cv_type_uint64_t="$ac_cv_type_uint64_t"
+ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t"
+ac_cv_char_data_model="$ac_cv_char_data_model"
+ac_cv_long_data_model="$ac_cv_long_data_model"
+ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t"
+ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t"
+ac_cv_type_intmax_t="$ac_cv_type_intmax_t"
+])
+])
--- /dev/null
+prefix=
+exec_prefix=
+libdir=${pcfiledir}/orc/
+includedir=${pcfiledir}/
+
+Name: orc-@LIBOIL_MAJORMINOR@ uninstalled
+Description: Library of Optimized Inner Loops Runtime Compiler
+Version: @VERSION@
+Libs: -L${libdir} -lorc-@LIBOIL_MAJORMINOR@ @LIBM@ @LIBRT@
+Cflags: -I${includedir}
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/orc-@LIBOIL_MAJORMINOR@
+toolsdir=${exec_prefix}/bin
+
+
+Name: orc-@LIBOIL_MAJORMINOR@
+Description: Library of Optimized Inner Loops Runtime Compiler
+Version: @VERSION@
+Libs: -L${libdir} -lorc-@LIBOIL_MAJORMINOR@ @LIBM@ @LIBRT@
+Cflags: -I${includedir}
+
+
--- /dev/null
+
+pkgincludedir = $(includedir)/orc-@ORC_MAJORMINOR@/orc
+
+lib_LTLIBRARIES = liborc-@ORC_MAJORMINOR@.la
+
+liborc_@ORC_MAJORMINOR@_la_LIBS = $(ORC_LIBS)
+liborc_@ORC_MAJORMINOR@_la_CFLAGS = $(ORC_CFLAGS)
+
+liborc_@ORC_MAJORMINOR@_la_SOURCES = \
+ orc.c \
+ orcexecutor.c \
+ orcrule.c \
+ orctype.c \
+ orcprogram.c \
+ orcprogram-c.c \
+ orcprogram-x86.c \
+ orcprogram-powerpc.c \
+ orcprogram.h \
+ orcopcodes.c \
+ orcprogram-linux.c \
+ orcrules-mmx.c \
+ orcrules-x86.c \
+ orcrules-sse.c \
+ x86.c
+
+pkginclude_HEADERS = \
+ orc.h \
+ orcprogram.h \
+ x86.h
+
--- /dev/null
+#ifndef _ORC_ORC_ORC_STDINT_H
+#define _ORC_ORC_ORC_STDINT_H 1
+#ifndef _GENERATED_STDINT_H
+#define _GENERATED_STDINT_H "orc 0.3.14.1"
+/* generated using gnu compiler gcc (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu7) */
+#define _STDINT_HAVE_STDINT_H 1
+#include <stdint.h>
+#endif
+#endif
--- /dev/null
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <orc/orcprogram.h>
+
+
+void
+orc_init (void)
+{
+ orc_opcode_init();
+ orc_x86_init();
+ orc_powerpc_init();
+ orc_c_init();
+}
+
--- /dev/null
+
+#ifndef _ORC_ORC_H_
+#define _ORC_ORC_H_
+
+#include <orc/orcprogram.h>
+
+#endif
+
--- /dev/null
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <orc/orcprogram.h>
+
+
+OrcExecutor *
+orc_executor_new (OrcProgram *program)
+{
+ OrcExecutor *ex;
+
+ ex = malloc(sizeof(OrcExecutor));
+ memset(ex,0,sizeof(OrcExecutor));
+
+ ex->program = program;
+
+ memcpy (ex->vars, program->vars, 10*sizeof(OrcVariable));
+
+ return ex;
+}
+
+void
+orc_executor_free (OrcExecutor *ex)
+{
+ free (ex);
+}
+
+void
+orc_executor_run (OrcExecutor *ex)
+{
+ void (*func) (OrcExecutor *);
+
+ func = ex->program->code_exec;
+ func (ex);
+}
+
+void
+orc_executor_set_array (OrcExecutor *ex, int var, void *ptr)
+{
+ ex->arrays[var] = ptr;
+}
+
+void
+orc_executor_set_array_str (OrcExecutor *ex, const char *name, void *ptr)
+{
+ int var;
+ var = orc_program_find_var_by_name (ex->program, name);
+ ex->arrays[var] = ptr;
+}
+
+void
+orc_executor_set_n (OrcExecutor *ex, int n)
+{
+ ex->n = n;
+}
+
+void
+orc_executor_emulate (OrcExecutor *ex)
+{
+ int i;
+ int j;
+ int k;
+ OrcProgram *program = ex->program;
+ OrcInstruction *insn;
+ OrcOpcode *opcode;
+
+ //printf("n %d\n", ex->n);
+ //printf("n_insns %d\n", program->n_insns);
+
+ for(i=0;i<ex->n;i++){
+ for(j=0;j<program->n_insns;j++){
+ insn = program->insns + j;
+ opcode = insn->opcode;
+
+ //printf("%d: %s\n", j, insn->opcode->name);
+
+ /* set up args */
+ for(k=0;k<opcode->n_src + opcode->n_dest;k++){
+ ex->args[k] = ex->vars + insn->args[k];
+
+ //printf("setting up arg %d as var %d vartype %d\n",
+ // k, insn->args[k], ex->args[k]->vartype);
+
+ if (ex->args[k]->vartype == ORC_VAR_TYPE_SRC) {
+ void *ptr = ex->arrays[insn->args[k]] + 2*i;
+
+ //printf("load %p\n", ptr);
+ ex->args[k]->s16 = *(int16_t *)ptr;
+ }
+ }
+
+ opcode->emulate (ex, opcode->emulate_user);
+ //printf("emulate: %d %d %d\n", ex->args[0]->s16,
+ // ex->args[1]->s16, ex->args[2]->s16);
+
+ for(k=0;k<opcode->n_src + opcode->n_dest;k++){
+ if (ex->args[k]->vartype == ORC_VAR_TYPE_DEST) {
+ void *ptr = ex->arrays[insn->args[k]] + 2*i;
+
+ //printf("store %p\n", ptr);
+ *(int16_t *)ptr = ex->args[k]->s16;
+ }
+ }
+ }
+ }
+}
+
+
--- /dev/null
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <orc/orcprogram.h>
+
+
+static OrcOpcode *opcode_list;
+static int n_opcodes;
+static int n_opcodes_alloc;
+
+
+
+void
+orc_opcode_register (const char *name, int n_dest, int n_src,
+ OrcOpcodeEmulateFunc emulate, void *user)
+{
+ OrcOpcode *opcode;
+
+ if (n_opcodes == n_opcodes_alloc) {
+ n_opcodes_alloc += 100;
+ opcode_list = realloc(opcode_list, sizeof(OrcOpcode) * n_opcodes_alloc);
+ }
+
+ opcode = opcode_list + n_opcodes;
+
+ opcode->name = strdup (name);
+ opcode->n_src = n_src;
+ opcode->n_dest = n_dest;
+ opcode->emulate = emulate;
+ opcode->emulate_user = user;
+
+ n_opcodes++;
+}
+
+OrcOpcode *
+orc_opcode_find_by_name (const char *name)
+{
+ int i;
+
+ for(i=0;i<n_opcodes;i++){
+ if (!strcmp (name, opcode_list[i].name)) {
+ return opcode_list + i;
+ }
+ }
+
+ return NULL;
+}
+
+static void
+move_s16 (OrcExecutor *ex, void *user)
+{
+ ex->args[0]->s16 = ex->args[1]->s16;
+}
+
+static void
+add_s16 (OrcExecutor *ex, void *user)
+{
+ ex->args[0]->s16 = (int16_t)(ex->args[1]->s16 + ex->args[2]->s16);
+}
+
+static void
+sub_s16 (OrcExecutor *ex, void *user)
+{
+ ex->args[0]->s16 = (int16_t)(ex->args[1]->s16 - ex->args[2]->s16);
+}
+
+static void
+mul_s16 (OrcExecutor *ex, void *user)
+{
+ ex->args[0]->s16 = (int16_t)(ex->args[1]->s16 * ex->args[2]->s16);
+}
+
+static void
+lshift_s16 (OrcExecutor *ex, void *user)
+{
+ ex->args[0]->s16 = (int16_t)(ex->args[1]->s16 << ex->args[2]->s16);
+}
+
+static void
+rshift_s16 (OrcExecutor *ex, void *user)
+{
+ ex->args[0]->s16 = (int16_t)(ex->args[1]->s16 >> ex->args[2]->s16);
+}
+
+void
+orc_opcode_init (void)
+{
+ orc_opcode_register("_loadi_s16", 1, 1, move_s16, NULL);
+
+ orc_opcode_register("add_s16", 1, 2, add_s16, NULL);
+ orc_opcode_register("sub_s16", 1, 2, sub_s16, NULL);
+ orc_opcode_register("mul_s16", 1, 2, mul_s16, NULL);
+ orc_opcode_register("lshift_s16", 1, 2, lshift_s16, NULL);
+ orc_opcode_register("rshift_s16", 1, 2, rshift_s16, NULL);
+}
+
+
--- /dev/null
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <orc/orcprogram.h>
+
+
+void orc_c_init (void);
+
+void
+orc_program_assemble_c (OrcProgram *program)
+{
+ int i;
+ int j;
+ OrcInstruction *insn;
+ OrcOpcode *opcode;
+ OrcRule *rule;
+
+ printf("\n");
+ printf("void\n");
+ printf("test (OrcExecutor *ex)\n");
+ printf("{\n");
+ printf(" int i;\n");
+
+ for(i=0;i<program->n_vars;i++){
+ OrcVariable *var = program->vars + i;
+ switch (var->vartype) {
+ case ORC_VAR_TYPE_CONST:
+ printf(" int16_t var%d = %d;\n", i, var->s16);
+ break;
+ case ORC_VAR_TYPE_TEMP:
+ printf(" int16_t var%d;\n", i);
+ break;
+ case ORC_VAR_TYPE_SRC:
+ case ORC_VAR_TYPE_DEST:
+ printf(" int16_t *var%d = ex->var%d;\n", i, i);
+ break;
+ case ORC_VAR_TYPE_PARAM:
+ printf(" int16_t var%d = ex->var%d;\n", i, i);
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ printf("\n");
+ printf(" for (i = 0; i < n; i++) {\n");
+
+ for(j=0;j<program->n_insns;j++){
+ insn = program->insns + j;
+ opcode = insn->opcode;
+
+ printf(" // %d: %s\n", j, insn->opcode->name);
+
+#if 0
+ for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
+ switch (args[k]->vartype) {
+ case ORC_VAR_TYPE_SRC:
+ x86_emit_load_src (program, args[k]);
+ break;
+ case ORC_VAR_TYPE_CONST:
+ break;
+ case ORC_VAR_TYPE_TEMP:
+ break;
+ default:
+ break;
+ }
+ }
+#endif
+
+ rule = insn->rule;
+ if (rule) {
+ rule->emit (program, rule->emit_user, insn);
+ } else {
+ printf("No rule for: %s\n", opcode->name);
+ }
+
+#if 0
+ for(k=0;k<opcode->n_dest;k++){
+ switch (args[k]->vartype) {
+ case ORC_VAR_TYPE_DEST:
+ x86_emit_store_dest (program, args[k]);
+ break;
+ case ORC_VAR_TYPE_TEMP:
+ break;
+ default:
+ break;
+ }
+ }
+#endif
+ }
+
+ printf(" }\n");
+ printf("}\n");
+ printf("\n");
+}
+
+
+/* rules */
+
+static void
+c_get_name (char *name, OrcProgram *p, int var)
+{
+ switch (p->vars[var].vartype) {
+ case ORC_VAR_TYPE_CONST:
+ case ORC_VAR_TYPE_PARAM:
+ case ORC_VAR_TYPE_TEMP:
+ sprintf(name, "var%d", var);
+ break;
+ case ORC_VAR_TYPE_SRC:
+ case ORC_VAR_TYPE_DEST:
+ sprintf(name, "var%d[i]", var);
+ break;
+ default:
+ sprintf(name, "ERROR");
+ break;
+ }
+
+}
+
+static void
+c_rule_add_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ char dest[20], src1[20], src2[20];
+
+ c_get_name (dest, p, insn->args[0]);
+ c_get_name (src1, p, insn->args[1]);
+ c_get_name (src2, p, insn->args[2]);
+
+ printf (" %s = %s + %s;\n", dest, src1, src2);
+}
+
+static void
+c_rule_sub_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ char dest[20], src1[20], src2[20];
+
+ c_get_name (dest, p, insn->args[0]);
+ c_get_name (src1, p, insn->args[1]);
+ c_get_name (src2, p, insn->args[2]);
+
+ printf (" %s = %s - %s;\n", dest, src1, src2);
+}
+
+static void
+c_rule_mul_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ char dest[20], src1[20], src2[20];
+
+ c_get_name (dest, p, insn->args[0]);
+ c_get_name (src1, p, insn->args[1]);
+ c_get_name (src2, p, insn->args[2]);
+
+ printf (" %s = %s * %s;\n", dest, src1, src2);
+}
+
+static void
+c_rule_lshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ char dest[20], src1[20], src2[20];
+
+ c_get_name (dest, p, insn->args[0]);
+ c_get_name (src1, p, insn->args[1]);
+ c_get_name (src2, p, insn->args[2]);
+
+ printf (" %s = %s << %s;\n", dest, src1, src2);
+}
+
+static void
+c_rule_rshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ char dest[20], src1[20], src2[20];
+
+ c_get_name (dest, p, insn->args[0]);
+ c_get_name (src1, p, insn->args[1]);
+ c_get_name (src2, p, insn->args[2]);
+
+ printf (" %s = %s >> %s;\n", dest, src1, src2);
+}
+
+
+void
+orc_c_init (void)
+{
+ orc_rule_register ("add_s16", ORC_RULE_C, c_rule_add_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("sub_s16", ORC_RULE_C, c_rule_sub_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("mul_s16", ORC_RULE_C, c_rule_mul_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("lshift_s16", ORC_RULE_C, c_rule_lshift_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("rshift_s16", ORC_RULE_C, c_rule_rshift_s16, NULL,
+ ORC_RULE_REG_REG);
+}
+
--- /dev/null
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <orc/orcprogram.h>
+
+#define SIZE 65536
+
+
+void
+orc_program_allocate_codemem (OrcProgram *program)
+{
+ char filename[32] = "/tmp/orcexecXXXXXX";
+ int fd;
+
+ fd = mkstemp (filename);
+ if (fd == -1) {
+ /* FIXME oh crap */
+ printf("failed to create temp file\n");
+ program->error = TRUE;
+ return;
+ }
+ unlink (filename);
+
+ ftruncate (fd, SIZE);
+
+ program->code = mmap (NULL, SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (program->code == MAP_FAILED) {
+ /* FIXME oh crap */
+ printf("failed to create write map\n");
+ program->error = TRUE;
+ return;
+ }
+ program->code_exec = mmap (NULL, SIZE, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);
+ if (program->code_exec == MAP_FAILED) {
+ /* FIXME oh crap */
+ printf("failed to create exec map\n");
+ program->error = TRUE;
+ return;
+ }
+
+ close (fd);
+
+ program->code_size = SIZE;
+ program->codeptr = program->code;
+}
+
--- /dev/null
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <orc/orcprogram.h>
+
+#define SIZE 65536
+
+void powerpc_emit_addi (OrcProgram *program, int regd, int rega, int imm);
+void powerpc_emit_lwz (OrcProgram *program, int regd, int rega, int imm);
+void powerpc_emit_stwu (OrcProgram *program, int regs, int rega, int offset);
+
+void powerpc_emit_ret (OrcProgram *program);
+void powerpc_emit_beq (OrcProgram *program, int label);
+void powerpc_emit_bne (OrcProgram *program, int label);
+void powerpc_emit_label (OrcProgram *program, int label);
+
+void orc_program_powerpc_register_rules (void);
+
+enum {
+ POWERPC_R0 = ORC_GP_REG_BASE,
+ POWERPC_R1,
+ POWERPC_R2,
+ POWERPC_R3,
+ POWERPC_R4,
+ POWERPC_R5,
+ POWERPC_R6,
+ POWERPC_R7,
+ POWERPC_R8,
+ POWERPC_R9,
+ POWERPC_R10,
+ POWERPC_R11,
+ POWERPC_R12,
+ POWERPC_R13,
+ POWERPC_R14,
+ POWERPC_R15,
+ POWERPC_R16,
+ POWERPC_R17,
+ POWERPC_R18,
+ POWERPC_R19,
+ POWERPC_R20,
+ POWERPC_R21,
+ POWERPC_R22,
+ POWERPC_R23,
+ POWERPC_R24,
+ POWERPC_R25,
+ POWERPC_R26,
+ POWERPC_R27,
+ POWERPC_R28,
+ POWERPC_R29,
+ POWERPC_R30,
+ POWERPC_R31,
+ POWERPC_V0 = ORC_VEC1_REG_BASE,
+ POWERPC_V1,
+ POWERPC_V2,
+ POWERPC_V3,
+ POWERPC_V4,
+ POWERPC_V5,
+ POWERPC_V6,
+ POWERPC_V7,
+ POWERPC_V8,
+ POWERPC_V9,
+ POWERPC_V10,
+ POWERPC_V11,
+ POWERPC_V12,
+ POWERPC_V13,
+ POWERPC_V14,
+ POWERPC_V15,
+ POWERPC_V16,
+ POWERPC_V17,
+ POWERPC_V18,
+ POWERPC_V19,
+ POWERPC_V20,
+ POWERPC_V21,
+ POWERPC_V22,
+ POWERPC_V23,
+ POWERPC_V24,
+ POWERPC_V25,
+ POWERPC_V26,
+ POWERPC_V27,
+ POWERPC_V28,
+ POWERPC_V29,
+ POWERPC_V30,
+ POWERPC_V31,
+ POWERPC_F0 = ORC_VEC2_REG_BASE,
+ POWERPC_F1,
+ POWERPC_F2,
+ POWERPC_F3,
+ POWERPC_F4,
+ POWERPC_F5,
+ POWERPC_F6,
+ POWERPC_F7,
+ POWERPC_F8,
+ POWERPC_F9,
+ POWERPC_F10,
+ POWERPC_F11,
+ POWERPC_F12,
+ POWERPC_F13,
+ POWERPC_F14,
+ POWERPC_F15,
+ POWERPC_F16,
+ POWERPC_F17,
+ POWERPC_F18,
+ POWERPC_F19,
+ POWERPC_F20,
+ POWERPC_F21,
+ POWERPC_F22,
+ POWERPC_F23,
+ POWERPC_F24,
+ POWERPC_F25,
+ POWERPC_F26,
+ POWERPC_F27,
+ POWERPC_F28,
+ POWERPC_F29,
+ POWERPC_F30,
+ POWERPC_F31
+};
+
+const char *
+powerpc_get_regname(int i)
+{
+ static const char *powerpc_regs[] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
+ "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
+ "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29",
+ "r30", "r31",
+ "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9",
+ "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19",
+ "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29",
+ "v30", "v31",
+ };
+
+ if (i>=ORC_GP_REG_BASE && i<ORC_GP_REG_BASE + 64) {
+ return powerpc_regs[i - ORC_GP_REG_BASE];
+ }
+ switch (i) {
+ case 0:
+ return "UNALLOCATED";
+ case 1:
+ return "direct";
+ default:
+ return "ERROR";
+ }
+}
+
+int
+powerpc_regnum (int i)
+{
+ return (i-ORC_GP_REG_BASE)&0x1f;
+}
+
+void
+powerpc_emit(OrcProgram *program, unsigned int insn)
+{
+ *program->codeptr++ = (insn>>24);
+ *program->codeptr++ = (insn>>16);
+ *program->codeptr++ = (insn>>8);
+ *program->codeptr++ = (insn>>0);
+}
+
+void
+powerpc_emit_prologue (OrcProgram *program)
+{
+ int i;
+
+ printf (".global test\n");
+ printf ("test:\n");
+
+ powerpc_emit_stwu (program, POWERPC_R1, POWERPC_R1, -16);
+
+ for(i=POWERPC_R13;i<=POWERPC_R31;i++){
+ if (program->used_regs[i]) {
+ //powerpc_emit_push (program, 4, i);
+ }
+ }
+}
+
+void
+powerpc_emit_addi (OrcProgram *program, int regd, int rega, int imm)
+{
+ unsigned int insn;
+
+ printf(" addi %s, %s, %d\n",
+ powerpc_get_regname(regd),
+ powerpc_get_regname(rega), imm);
+ insn = (14<<26) | (powerpc_regnum (regd)<<21) | (powerpc_regnum (rega)<<16);
+ insn |= imm&0xffff;
+
+ powerpc_emit (program, insn);
+}
+
+void
+powerpc_emit_lwz (OrcProgram *program, int regd, int rega, int imm)
+{
+ unsigned int insn;
+
+ printf(" lwz %s, %d(%s)\n",
+ powerpc_get_regname(regd),
+ imm, powerpc_get_regname(rega));
+ insn = (32<<26) | (powerpc_regnum (regd)<<21) | (powerpc_regnum (rega)<<16);
+ insn |= imm&0xffff;
+
+ powerpc_emit (program, insn);
+}
+
+void
+powerpc_emit_stwu (OrcProgram *program, int regs, int rega, int offset)
+{
+ unsigned int insn;
+
+ printf(" stwu %s, %d(%s)\n",
+ powerpc_get_regname(regs),
+ offset, powerpc_get_regname(rega));
+ insn = (37<<26) | (powerpc_regnum (regs)<<21) | (powerpc_regnum (rega)<<16);
+ insn |= offset&0xffff;
+
+ powerpc_emit (program, insn);
+}
+
+void
+powerpc_emit_srawi (OrcProgram *program, int regd, int rega, int shift,
+ int record)
+{
+ unsigned int insn;
+
+ printf(" srawi%s %s, %s, %d\n", (record)?".":"",
+ powerpc_get_regname(regd),
+ powerpc_get_regname(rega), shift);
+
+ insn = (31<<26) | (powerpc_regnum (regd)<<21) | (powerpc_regnum (rega)<<16);
+ insn |= (shift<<11) | (824<<1) | record;
+
+ powerpc_emit (program, insn);
+}
+
+void
+powerpc_emit_655510 (OrcProgram *program, int major, int d, int a, int b,
+ int minor)
+{
+ unsigned int insn;
+
+ insn = (major<<26) | (d<<21) | (a<<16);
+ insn |= (b<<11) | (minor<<0);
+
+ powerpc_emit (program, insn);
+}
+
+void
+powerpc_emit_X (OrcProgram *program, int major, int d, int a, int b,
+ int minor)
+{
+ unsigned int insn;
+
+ insn = (major<<26) | (d<<21) | (a<<16);
+ insn |= (b<<11) | (minor<<1) | (0<<0);
+
+ powerpc_emit (program, insn);
+}
+
+void
+powerpc_emit_VA (OrcProgram *program, int major, int d, int a, int b,
+ int c, int minor)
+{
+ unsigned int insn;
+
+ insn = (major<<26) | (d<<21) | (a<<16);
+ insn |= (b<<11) | (c<<6) | (minor<<0);
+
+ powerpc_emit (program, insn);
+}
+
+void
+powerpc_emit_VX (OrcProgram *program, int major, int d, int a, int b,
+ int minor)
+{
+ unsigned int insn;
+
+ insn = (major<<26) | (d<<21) | (a<<16);
+ insn |= (b<<11) | (minor<<0);
+
+ powerpc_emit (program, insn);
+}
+
+
+void
+powerpc_emit_epilogue (OrcProgram *program)
+{
+ int i;
+
+ for(i=POWERPC_R31;i>=POWERPC_R31;i--){
+ if (program->used_regs[i]) {
+ //powerpc_emit_pop (program, 4, i);
+ }
+ }
+
+ powerpc_emit_addi (program, POWERPC_R1, POWERPC_R1, 16);
+ printf(" blr\n");
+ powerpc_emit(program, 0x4e800020);
+}
+
+void
+powerpc_do_fixups (OrcProgram *program)
+{
+ int i;
+ unsigned int insn;
+
+ for(i=0;i<program->n_fixups;i++){
+ if (program->fixups[i].type == 0) {
+ unsigned char *label = program->labels[program->fixups[i].label];
+ unsigned char *ptr = program->fixups[i].ptr;
+
+ insn = *(unsigned int *)ptr;
+ *(unsigned int *)ptr = (insn&0xffff0000) | ((insn + (label-ptr))&0xffff);
+ }
+ }
+}
+
+void
+powerpc_flush (OrcProgram *program)
+{
+#ifdef HAVE_POWERPC
+ unsigned char *ptr;
+ int cache_line_size = 32;
+ int i;
+ int size = program->codeptr - program->code;
+
+ ptr = program->code;
+ for (i=0;i<size;i+=cache_line_size) {
+ __asm__ __volatile__ ("dcbst %0,%1" :: "r" (ptr), "r" (i));
+ }
+ __asm__ __volatile ("sync");
+
+ ptr = program->code_exec;
+ for (i=0;i<size;i+=cache_line_size) {
+ __asm__ __volatile__ ("icbi %0,%1" :: "r" (ptr), "r" (i));
+ }
+ __asm__ __volatile ("isync");
+#endif
+}
+
+void
+orc_powerpc_init (void)
+{
+ orc_program_powerpc_register_rules ();
+}
+
+void
+orc_program_powerpc_init (OrcProgram *program)
+{
+ int i;
+
+ for(i=0;i<32;i++){
+ program->valid_regs[POWERPC_R0+i] = 1;
+ program->valid_regs[POWERPC_F0+i] = 1;
+ program->valid_regs[POWERPC_V0+i] = 1;
+ }
+ program->valid_regs[POWERPC_R0] = 0; /* used for temp space */
+ program->valid_regs[POWERPC_R1] = 0; /* stack pointer */
+ program->valid_regs[POWERPC_R2] = 0; /* TOC pointer */
+ program->valid_regs[POWERPC_R3] = 0; /* pointer to OrcExecutor */
+ program->valid_regs[POWERPC_R13] = 0; /* reserved */
+ program->valid_regs[POWERPC_V0] = 0; /* used for temp space */
+
+ for(i=14;i<32;i++){
+ program->save_regs[POWERPC_R0 + i] = 1;
+ program->save_regs[POWERPC_F0 + i] = 1;
+ }
+ for(i=20;i<32;i++){
+ program->save_regs[POWERPC_V0 + i] = 1;
+ }
+
+ program->data_register_class = 2;
+
+ program->rule_set = ORC_RULE_ALTIVEC_1;
+ program->n_per_loop = 4;
+ program->loop_shift = 2;
+}
+
+void
+powerpc_load_constants (OrcProgram *program)
+{
+ int i;
+ for(i=0;i<program->n_vars;i++){
+ switch (program->vars[i].vartype) {
+ case ORC_VAR_TYPE_CONST:
+ printf(" vspltish %s, %d\n",
+ powerpc_get_regname(program->vars[i].alloc),
+ program->vars[i].s16);
+ powerpc_emit_655510 (program, 4,
+ powerpc_regnum(program->vars[i].alloc),
+ program->vars[i].s16, 0, 844);
+ break;
+ case ORC_VAR_TYPE_SRC:
+ case ORC_VAR_TYPE_DEST:
+ if (program->vars[i].ptr_register) {
+ powerpc_emit_lwz (program,
+ program->vars[i].ptr_register,
+ POWERPC_R3,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[i]));
+ } else {
+ /* FIXME */
+ printf("ERROR");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void
+powerpc_emit_load_src (OrcProgram *program, OrcVariable *var)
+{
+ int ptr_reg;
+ ptr_reg = var->ptr_register;
+
+ switch (program->rule_set) {
+ case ORC_RULE_ALTIVEC_1:
+ printf(" lvehx %s, 0, %s\n",
+ powerpc_get_regname (var->alloc),
+ powerpc_get_regname (ptr_reg));
+ powerpc_emit_X (program, 31, powerpc_regnum(var->alloc),
+ 0, powerpc_regnum(ptr_reg), 39);
+ printf(" lvsl %s, 0, %s\n",
+ powerpc_get_regname (POWERPC_V0),
+ powerpc_get_regname (ptr_reg));
+ powerpc_emit_X (program, 31, powerpc_regnum(POWERPC_V0),
+ 0, powerpc_regnum(ptr_reg), 6);
+ printf(" vperm %s, %s, %s, %s\n",
+ powerpc_get_regname (var->alloc),
+ powerpc_get_regname (var->alloc),
+ powerpc_get_regname (var->alloc),
+ powerpc_get_regname (POWERPC_V0));
+ powerpc_emit_VA (program, 4,
+ powerpc_regnum(var->alloc),
+ powerpc_regnum(var->alloc),
+ powerpc_regnum(var->alloc),
+ powerpc_regnum(POWERPC_V0), 43);
+ break;
+ default:
+ printf("ERROR\n");
+ }
+}
+
+void
+powerpc_emit_store_dest (OrcProgram *program, OrcVariable *var)
+{
+ int ptr_reg;
+ ptr_reg = var->ptr_register;
+
+ switch (program->rule_set) {
+ case ORC_RULE_ALTIVEC_1:
+ printf(" lvsr %s, 0, %s\n",
+ powerpc_get_regname (POWERPC_V0),
+ powerpc_get_regname (ptr_reg));
+ powerpc_emit_X (program, 31, powerpc_regnum(POWERPC_V0),
+ 0, powerpc_regnum(ptr_reg), 38);
+ printf(" vperm %s, %s, %s, %s\n",
+ powerpc_get_regname (var->alloc),
+ powerpc_get_regname (var->alloc),
+ powerpc_get_regname (var->alloc),
+ powerpc_get_regname (POWERPC_V0));
+ powerpc_emit_VA (program, 4,
+ powerpc_regnum(var->alloc),
+ powerpc_regnum(var->alloc),
+ powerpc_regnum(var->alloc),
+ powerpc_regnum(POWERPC_V0), 43);
+ printf(" stvehx %s, 0, %s\n",
+ powerpc_get_regname (var->alloc),
+ powerpc_get_regname (ptr_reg));
+ powerpc_emit_X (program, 31,
+ powerpc_regnum(var->alloc),
+ 0, powerpc_regnum(ptr_reg), 167);
+ break;
+ default:
+ printf("ERROR\n");
+ }
+}
+
+void
+orc_program_assemble_powerpc (OrcProgram *program)
+{
+ int j;
+ int k;
+ OrcInstruction *insn;
+ OrcOpcode *opcode;
+ OrcVariable *args[10];
+ OrcRule *rule;
+
+ powerpc_emit_prologue (program);
+
+ powerpc_emit_lwz (program, POWERPC_R0, POWERPC_R3,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor, n));
+ powerpc_emit_srawi (program, POWERPC_R0, POWERPC_R0,
+ program->loop_shift, 1);
+
+ powerpc_emit_beq (program, 1);
+
+ powerpc_emit (program, 0x7c0903a6);
+ printf (" mtctr %s\n", powerpc_get_regname(POWERPC_R0));
+
+ powerpc_load_constants (program);
+
+ powerpc_emit_label (program, 0);
+
+ for(j=0;j<program->n_insns;j++){
+ insn = program->insns + j;
+ opcode = insn->opcode;
+
+ printf("# %d: %s", j, insn->opcode->name);
+
+ /* set up args */
+ for(k=0;k<opcode->n_src + opcode->n_dest;k++){
+ args[k] = program->vars + insn->args[k];
+ printf(" %d", args[k]->alloc);
+ if (args[k]->is_chained) {
+ printf(" (chained)");
+ }
+ }
+ printf(" rule_flag=%d", insn->rule_flag);
+ printf("\n");
+
+ for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
+ switch (args[k]->vartype) {
+ case ORC_VAR_TYPE_SRC:
+ powerpc_emit_load_src (program, args[k]);
+ break;
+ case ORC_VAR_TYPE_CONST:
+ break;
+ case ORC_VAR_TYPE_TEMP:
+ break;
+ default:
+ break;
+ }
+ }
+
+ rule = insn->rule;
+ if (rule) {
+ rule->emit (program, rule->emit_user, insn);
+ } else {
+ printf("No rule for: %s\n", opcode->name);
+ }
+
+ for(k=0;k<opcode->n_dest;k++){
+ switch (args[k]->vartype) {
+ case ORC_VAR_TYPE_DEST:
+ powerpc_emit_store_dest (program, args[k]);
+ break;
+ case ORC_VAR_TYPE_TEMP:
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ for(k=0;k<program->n_vars;k++){
+ if (program->vars[k].vartype == ORC_VAR_TYPE_SRC ||
+ program->vars[k].vartype == ORC_VAR_TYPE_DEST) {
+ if (program->vars[k].ptr_register) {
+ powerpc_emit_addi (program,
+ program->vars[k].ptr_register,
+ program->vars[k].ptr_register,
+ orc_variable_get_size(program->vars + k) << program->loop_shift);
+ } else {
+ printf("ERROR\n");
+ }
+ }
+ }
+
+ powerpc_emit_bne (program, 0);
+ powerpc_emit_label (program, 1);
+
+ powerpc_emit_epilogue (program);
+
+ powerpc_do_fixups (program);
+
+ powerpc_flush (program);
+}
+
+
+/* rules */
+
+static void
+powerpc_rule_add_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ unsigned int x;
+
+ printf(" vadduhm %s, %s, %s\n",
+ powerpc_get_regname(p->vars[insn->args[0]].alloc),
+ powerpc_get_regname(p->vars[insn->args[1]].alloc),
+ powerpc_get_regname(p->vars[insn->args[2]].alloc));
+
+ x = (4<<26);
+ x |= (powerpc_regnum (p->vars[insn->args[0]].alloc)<<21);
+ x |= (powerpc_regnum (p->vars[insn->args[1]].alloc)<<16);
+ x |= (powerpc_regnum (p->vars[insn->args[2]].alloc)<<11);
+ x |= 64;
+
+ powerpc_emit (p, x);
+}
+
+static void
+powerpc_rule_sub_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" vsubuhm %s, %s, %s\n",
+ powerpc_get_regname(p->vars[insn->args[0]].alloc),
+ powerpc_get_regname(p->vars[insn->args[1]].alloc),
+ powerpc_get_regname(p->vars[insn->args[2]].alloc));
+}
+
+static void
+powerpc_rule_mul_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" vxor %s, %s, %s\n",
+ powerpc_get_regname(POWERPC_V0),
+ powerpc_get_regname(POWERPC_V0),
+ powerpc_get_regname(POWERPC_V0));
+ powerpc_emit_VX(p, 4,
+ powerpc_regnum(POWERPC_V0),
+ powerpc_regnum(POWERPC_V0),
+ powerpc_regnum(POWERPC_V0), 1220);
+
+ printf(" vmladduhm %s, %s, %s, %s\n",
+ powerpc_get_regname(p->vars[insn->args[0]].alloc),
+ powerpc_get_regname(p->vars[insn->args[1]].alloc),
+ powerpc_get_regname(p->vars[insn->args[2]].alloc),
+ powerpc_get_regname(POWERPC_V0));
+ powerpc_emit_VA(p, 4,
+ powerpc_regnum(p->vars[insn->args[0]].alloc),
+ powerpc_regnum(p->vars[insn->args[1]].alloc),
+ powerpc_regnum(p->vars[insn->args[2]].alloc),
+ powerpc_regnum(POWERPC_V0), 34);
+
+}
+
+static void
+powerpc_rule_lshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" vrlh %s, %s, %s\n",
+ powerpc_get_regname(p->vars[insn->args[0]].alloc),
+ powerpc_get_regname(p->vars[insn->args[1]].alloc),
+ powerpc_get_regname(p->vars[insn->args[2]].alloc));
+ powerpc_emit_VX(p, 4,
+ powerpc_regnum(p->vars[insn->args[0]].alloc),
+ powerpc_regnum(p->vars[insn->args[1]].alloc),
+ powerpc_regnum(p->vars[insn->args[2]].alloc), 68);
+}
+
+static void
+powerpc_rule_rshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ unsigned int x;
+
+ printf(" vsrah %s, %s, %s\n",
+ powerpc_get_regname(p->vars[insn->args[0]].alloc),
+ powerpc_get_regname(p->vars[insn->args[1]].alloc),
+ powerpc_get_regname(p->vars[insn->args[2]].alloc));
+
+ x = (4<<26);
+ x |= (powerpc_regnum (p->vars[insn->args[0]].alloc)<<21);
+ x |= (powerpc_regnum (p->vars[insn->args[1]].alloc)<<16);
+ x |= (powerpc_regnum (p->vars[insn->args[2]].alloc)<<11);
+ x |= 836;
+
+ powerpc_emit (p, x);
+}
+
+
+void
+orc_program_powerpc_register_rules (void)
+{
+ orc_rule_register ("add_s16", ORC_RULE_ALTIVEC_1, powerpc_rule_add_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("sub_s16", ORC_RULE_ALTIVEC_1, powerpc_rule_sub_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("mul_s16", ORC_RULE_ALTIVEC_1, powerpc_rule_mul_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("lshift_s16", ORC_RULE_ALTIVEC_1, powerpc_rule_lshift_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("rshift_s16", ORC_RULE_ALTIVEC_1, powerpc_rule_rshift_s16, NULL,
+ ORC_RULE_REG_REG);
+}
+
+/* code generation */
+
+void powerpc_emit_ret (OrcProgram *program)
+{
+ printf(" ret\n");
+ //*program->codeptr++ = 0xc3;
+}
+
+void
+powerpc_add_fixup (OrcProgram *program, unsigned char *ptr, int label)
+{
+ program->fixups[program->n_fixups].ptr = ptr;
+ program->fixups[program->n_fixups].label = label;
+ program->fixups[program->n_fixups].type = 0;
+ program->n_fixups++;
+}
+
+void
+powerpc_add_label (OrcProgram *program, unsigned char *ptr, int label)
+{
+ program->labels[label] = ptr;
+}
+
+void powerpc_emit_beq (OrcProgram *program, int label)
+{
+ printf(" ble- .L%d\n", label);
+
+ powerpc_add_fixup (program, program->codeptr, label);
+ powerpc_emit (program, 0x40810000);
+}
+
+void powerpc_emit_bne (OrcProgram *program, int label)
+{
+ printf(" bdnz+ .L%d\n", label);
+
+ powerpc_add_fixup (program, program->codeptr, label);
+ powerpc_emit (program, 0x42000000);
+}
+
+void powerpc_emit_label (OrcProgram *program, int label)
+{
+ printf(".L%d:\n", label);
+
+ powerpc_add_label (program, program->codeptr, label);
+}
+
--- /dev/null
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <orc/orcprogram.h>
+#include <orc/x86.h>
+
+#define SIZE 65536
+
+void x86_emit_loop (OrcProgram *program);
+
+
+void orc_program_x86_register_rules (void);
+void orc_program_mmx_register_rules (void);
+void orc_program_sse_register_rules (void);
+
+#ifdef HAVE_AMD64
+int x86_64 = 1;
+int x86_ptr_size = 8;
+int x86_exec_ptr = X86_EDI;
+#else
+int x86_64 = 0;
+int x86_ptr_size = 4;
+int x86_exec_ptr = X86_EBP;
+#endif
+
+
+int
+orc_program_x86_allocate_register (OrcProgram *program, int data_reg)
+{
+ int i;
+ int klass;
+ int offset;
+
+ if (data_reg) {
+ klass = program->data_register_class;
+ } else {
+ klass = ORC_REGCLASS_GP;
+ }
+ offset = klass << 5;
+
+ for(i=offset;i<offset+32;i++){
+ if (program->valid_regs[i] &&
+ !program->save_regs[i] &&
+ program->alloc_regs[i] == 0) {
+ program->alloc_regs[i]++;
+ program->used_regs[i] = 1;
+ return i;
+ }
+ }
+ for(i=offset;i<offset+32;i++){
+ if (program->valid_regs[i] &&
+ program->alloc_regs[i] == 0) {
+ program->alloc_regs[i]++;
+ program->used_regs[i] = 1;
+ return i;
+ }
+ }
+
+ printf("register overflow\n");
+ return 0;
+}
+
+
+void orc_program_rewrite_vars (OrcProgram *program);
+void orc_program_dump (OrcProgram *program);
+
+void
+x86_emit_prologue (OrcProgram *program)
+{
+ printf(".global test\n");
+ printf("test:\n");
+ if (x86_64) {
+
+ } else {
+ x86_emit_push (program, 4, X86_EBP);
+ x86_emit_mov_memoffset_reg (program, 4, 8, X86_ESP, X86_EBP);
+ if (program->used_regs[X86_EDI]) {
+ x86_emit_push (program, 4, X86_EDI);
+ }
+ if (program->used_regs[X86_ESI]) {
+ x86_emit_push (program, 4, X86_ESI);
+ }
+ if (program->used_regs[X86_EBX]) {
+ x86_emit_push (program, 4, X86_EBX);
+ }
+ }
+}
+
+void
+x86_emit_epilogue (OrcProgram *program)
+{
+ if (program->rule_set == ORC_RULE_MMX_1 ||
+ program->rule_set == ORC_RULE_MMX_2 ||
+ program->rule_set == ORC_RULE_MMX_4 ||
+ program->rule_set == ORC_RULE_MMX_8) {
+ x86_emit_emms (program);
+ }
+ if (x86_64) {
+
+ } else {
+ if (program->used_regs[X86_EBX]) {
+ x86_emit_pop (program, 4, X86_EBX);
+ }
+ if (program->used_regs[X86_ESI]) {
+ x86_emit_pop (program, 4, X86_ESI);
+ }
+ if (program->used_regs[X86_EDI]) {
+ x86_emit_pop (program, 4, X86_EDI);
+ }
+ x86_emit_pop (program, 4, X86_EBP);
+ }
+ x86_emit_ret (program);
+}
+
+void
+x86_do_fixups (OrcProgram *program)
+{
+ int i;
+ for(i=0;i<program->n_fixups;i++){
+ if (program->fixups[i].type == 0) {
+ unsigned char *label = program->labels[program->fixups[i].label];
+ unsigned char *ptr = program->fixups[i].ptr;
+
+ ptr[0] += label - ptr;
+ }
+ }
+}
+
+void
+orc_x86_init (void)
+{
+ orc_program_x86_register_rules ();
+ orc_program_mmx_register_rules ();
+ orc_program_sse_register_rules ();
+}
+
+void
+orc_program_x86_init (OrcProgram *program)
+{
+ int i;
+
+ if (x86_64) {
+ for(i=ORC_GP_REG_BASE;i<ORC_GP_REG_BASE+16;i++){
+ program->valid_regs[i] = 1;
+ }
+ program->valid_regs[X86_ECX] = 0;
+ program->valid_regs[X86_EDI] = 0;
+ program->valid_regs[X86_ESP] = 0;
+ for(i=X86_XMM0;i<X86_XMM0+16;i++){
+ program->valid_regs[i] = 1;
+ }
+ program->save_regs[X86_EBX] = 1;
+ program->save_regs[X86_EBP] = 1;
+ program->save_regs[X86_R12] = 1;
+ program->save_regs[X86_R13] = 1;
+ program->save_regs[X86_R14] = 1;
+ program->save_regs[X86_R15] = 1;
+ } else {
+ for(i=ORC_GP_REG_BASE;i<ORC_GP_REG_BASE+8;i++){
+ program->valid_regs[i] = 1;
+ }
+ program->valid_regs[X86_ECX] = 0;
+ program->valid_regs[X86_ESP] = 0;
+ program->valid_regs[X86_EBP] = 0;
+ for(i=X86_XMM0;i<X86_XMM0+8;i++){
+ program->valid_regs[i] = 1;
+ }
+ program->save_regs[X86_EBX] = 1;
+ program->save_regs[X86_EDI] = 1;
+ program->save_regs[X86_EBP] = 1;
+ }
+ for(i=X86_MM0;i<X86_MM0+8;i++){
+ program->valid_regs[i] = 1;
+ }
+ for(i=0;i<128;i++){
+ program->alloc_regs[i] = 0;
+ program->used_regs[i] = 0;
+ }
+
+ program->data_register_class = 2;
+}
+
+void
+x86_load_constants (OrcProgram *program)
+{
+ int i;
+ for(i=0;i<program->n_vars;i++){
+ switch (program->vars[i].vartype) {
+ case ORC_VAR_TYPE_CONST:
+ mmx_emit_loadi_s16 (program, program->vars[i].alloc,
+ program->vars[i].s16);
+ break;
+ case ORC_VAR_TYPE_SRC:
+ case ORC_VAR_TYPE_DEST:
+ if (program->vars[i].ptr_register) {
+ x86_emit_mov_memoffset_reg (program, x86_ptr_size,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[i]), x86_exec_ptr,
+ program->vars[i].ptr_register);
+ } else {
+ /* FIXME */
+ printf("ERROR");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void
+x86_emit_load_src (OrcProgram *program, OrcVariable *var)
+{
+ int ptr_reg;
+ if (var->ptr_register == 0) {
+ x86_emit_mov_memoffset_reg (program, x86_ptr_size,
+ var->ptr_offset, x86_exec_ptr, X86_ECX);
+ ptr_reg = X86_ECX;
+ } else {
+ ptr_reg = var->ptr_register;
+ }
+ switch (program->rule_set) {
+ case ORC_RULE_SCALAR_1:
+ x86_emit_mov_memoffset_reg (program, 2, 0, ptr_reg, var->alloc);
+ break;
+ case ORC_RULE_MMX_1:
+ x86_emit_mov_memoffset_reg (program, 2, 0, ptr_reg, X86_ECX);
+ x86_emit_mov_reg_mmx (program, X86_ECX, var->alloc);
+ break;
+ case ORC_RULE_MMX_2:
+ x86_emit_mov_memoffset_mmx (program, 4, 0, ptr_reg, var->alloc);
+ break;
+ case ORC_RULE_MMX_4:
+ x86_emit_mov_memoffset_mmx (program, 8, 0, ptr_reg, var->alloc);
+ break;
+ case ORC_RULE_SSE_1:
+ x86_emit_mov_memoffset_reg (program, 2, 0, ptr_reg, X86_ECX);
+ x86_emit_mov_reg_sse (program, X86_ECX, var->alloc);
+ break;
+ case ORC_RULE_SSE_2:
+ x86_emit_mov_memoffset_sse (program, 4, 0, ptr_reg, var->alloc);
+ break;
+ case ORC_RULE_SSE_4:
+ x86_emit_mov_memoffset_sse (program, 8, 0, ptr_reg, var->alloc);
+ break;
+ case ORC_RULE_SSE_8:
+ x86_emit_mov_memoffset_sse (program, 16, 0, ptr_reg, var->alloc);
+ break;
+ default:
+ printf("ERROR\n");
+ }
+}
+
+void
+x86_emit_store_dest (OrcProgram *program, OrcVariable *var)
+{
+ int ptr_reg;
+ if (var->ptr_register == 0) {
+ x86_emit_mov_memoffset_reg (program, x86_ptr_size,
+ var->ptr_offset, x86_exec_ptr, X86_ECX);
+ ptr_reg = X86_ECX;
+ } else {
+ ptr_reg = var->ptr_register;
+ }
+ switch (program->rule_set) {
+ case ORC_RULE_SCALAR_1:
+ x86_emit_mov_reg_memoffset (program, 2, var->alloc, 0, ptr_reg);
+ break;
+ case ORC_RULE_MMX_1:
+ /* FIXME we might be using ecx twice here */
+ if (ptr_reg == X86_ECX) {
+ printf("ERROR\n");
+ }
+ x86_emit_mov_mmx_reg (program, var->alloc, X86_ECX);
+ x86_emit_mov_reg_memoffset (program, 2, X86_ECX, 0, ptr_reg);
+ break;
+ case ORC_RULE_MMX_2:
+ x86_emit_mov_mmx_memoffset (program, 4, var->alloc, 0, ptr_reg);
+ break;
+ case ORC_RULE_MMX_4:
+ x86_emit_mov_mmx_memoffset (program, 8, var->alloc, 0, ptr_reg);
+ break;
+ case ORC_RULE_SSE_1:
+ /* FIXME we might be using ecx twice here */
+ if (ptr_reg == X86_ECX) {
+ printf("ERROR\n");
+ }
+ x86_emit_mov_sse_reg (program, var->alloc, X86_ECX);
+ x86_emit_mov_reg_memoffset (program, 2, X86_ECX, 0, ptr_reg);
+ break;
+ case ORC_RULE_SSE_2:
+ x86_emit_mov_sse_memoffset (program, 4, var->alloc, 0, ptr_reg);
+ break;
+ case ORC_RULE_SSE_4:
+ x86_emit_mov_sse_memoffset (program, 8, var->alloc, 0, ptr_reg);
+ break;
+ case ORC_RULE_SSE_8:
+ x86_emit_mov_sse_memoffset (program, 16, var->alloc, 0, ptr_reg);
+ break;
+ default:
+ printf("ERROR\n");
+ }
+}
+
+void
+orc_program_assemble_x86 (OrcProgram *program)
+{
+ x86_emit_prologue (program);
+
+ x86_emit_mov_memoffset_reg (program, 4, (int)ORC_STRUCT_OFFSET(OrcExecutor,n),
+ x86_exec_ptr, X86_ECX);
+ x86_emit_sar_imm_reg (program, 4, program->loop_shift, X86_ECX);
+ x86_emit_mov_reg_memoffset (program, 4, X86_ECX,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor,counter2), x86_exec_ptr);
+
+ x86_emit_mov_memoffset_reg (program, 4,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor,n), x86_exec_ptr, X86_ECX);
+ x86_emit_and_imm_reg (program, 4, (1<<program->loop_shift)-1, X86_ECX);
+ x86_emit_mov_reg_memoffset (program, 4, X86_ECX,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor,counter1), x86_exec_ptr);
+
+ x86_load_constants (program);
+
+ x86_emit_cmp_imm_memoffset (program, 4, 0,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor,counter1), x86_exec_ptr);
+ x86_emit_je (program, 1);
+
+ program->rule_set = ORC_RULE_MMX_1;
+ program->n_per_loop = 1;
+ program->loop_shift = 0;
+ x86_emit_label (program, 0);
+ x86_emit_loop (program);
+ x86_emit_dec_memoffset (program, 4,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor,counter1),
+ x86_exec_ptr);
+ x86_emit_cmp_imm_memoffset (program, 4, 0,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor,counter1),
+ x86_exec_ptr);
+ x86_emit_jne (program, 0);
+ x86_emit_label (program, 1);
+
+ x86_emit_cmp_imm_memoffset (program, 4, 0,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor,counter2), x86_exec_ptr);
+ x86_emit_je (program, 3);
+
+ program->rule_set = ORC_RULE_MMX_4;
+ program->n_per_loop = 4;
+ program->loop_shift = 2;
+ x86_emit_label (program, 2);
+ x86_emit_loop (program);
+ x86_emit_dec_memoffset (program, 4,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor,counter2),
+ x86_exec_ptr);
+ x86_emit_jne (program, 2);
+ x86_emit_label (program, 3);
+
+ x86_emit_epilogue (program);
+
+ x86_do_fixups (program);
+}
+
+void
+x86_emit_loop (OrcProgram *program)
+{
+ int j;
+ int k;
+ OrcInstruction *insn;
+ OrcOpcode *opcode;
+ OrcVariable *args[10];
+ OrcRule *rule;
+
+ for(j=0;j<program->n_insns;j++){
+ insn = program->insns + j;
+ opcode = insn->opcode;
+
+ printf("# %d: %s", j, insn->opcode->name);
+
+ /* set up args */
+ for(k=0;k<opcode->n_src + opcode->n_dest;k++){
+ args[k] = program->vars + insn->args[k];
+ printf(" %d", args[k]->alloc);
+ if (args[k]->is_chained) {
+ printf(" (chained)");
+ }
+ }
+ printf(" rule_flag=%d", insn->rule_flag);
+ printf("\n");
+
+ for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
+ switch (args[k]->vartype) {
+ case ORC_VAR_TYPE_SRC:
+ x86_emit_load_src (program, args[k]);
+ break;
+ case ORC_VAR_TYPE_CONST:
+ break;
+ case ORC_VAR_TYPE_TEMP:
+ break;
+ default:
+ break;
+ }
+ }
+
+ rule = insn->rule;
+ if (rule) {
+ if (!(rule->flags & ORC_RULE_3REG) && args[0]->alloc != args[1]->alloc) {
+ x86_emit_mov_reg_reg (program, 2, args[1]->alloc, args[0]->alloc);
+ }
+ rule->emit (program, rule->emit_user, insn);
+ } else {
+ printf("No rule for: %s\n", opcode->name);
+ }
+
+ for(k=0;k<opcode->n_dest;k++){
+ switch (args[k]->vartype) {
+ case ORC_VAR_TYPE_DEST:
+ x86_emit_store_dest (program, args[k]);
+ break;
+ case ORC_VAR_TYPE_TEMP:
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ for(k=0;k<program->n_vars;k++){
+ if (program->vars[k].vartype == ORC_VAR_TYPE_SRC ||
+ program->vars[k].vartype == ORC_VAR_TYPE_DEST) {
+ if (program->vars[k].ptr_register) {
+ x86_emit_add_imm_reg (program, x86_ptr_size,
+ orc_variable_get_size(program->vars + k) * program->n_per_loop,
+ program->vars[k].ptr_register);
+ } else {
+ x86_emit_add_imm_memoffset (program, x86_ptr_size,
+ orc_variable_get_size(program->vars + k) * program->n_per_loop,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[k]),
+ x86_exec_ptr);
+ }
+ }
+ }
+}
+
--- /dev/null
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <orc/orcprogram.h>
+
+void orc_program_assign_rules (OrcProgram *program);
+void orc_program_global_reg_alloc (OrcProgram *program);
+void orc_program_rewrite_vars (OrcProgram *program);
+void orc_program_rewrite_vars2 (OrcProgram *program);
+void orc_program_do_regs (OrcProgram *program);
+
+OrcProgram *
+orc_program_new (void)
+{
+ OrcProgram *p;
+
+ p = malloc(sizeof(OrcProgram));
+ memset (p, 0, sizeof(OrcProgram));
+
+ return p;
+}
+
+OrcProgram *
+orc_program_new_dss (const char *type_d1, const char *type_s1,
+ const char *type_s2)
+{
+ OrcProgram *p;
+
+ p = orc_program_new ();
+
+ orc_program_add_destination (p, type_d1, "d1");
+ orc_program_add_source (p, type_d1, "s1");
+ orc_program_add_source (p, type_d1, "s2");
+
+ return p;
+}
+
+void
+orc_program_free (OrcProgram *program)
+{
+ int i;
+ for(i=0;i<program->n_vars;i++){
+ free (program->vars[i].name);
+ }
+ free (program);
+}
+
+int
+orc_program_add_temporary (OrcProgram *program, const char *type, const char *name)
+{
+ int i = program->n_vars;
+
+ program->vars[i].vartype = ORC_VAR_TYPE_TEMP;
+ program->vars[i].type = orc_type_get(type);
+ program->vars[i].name = strdup(name);
+ program->n_vars++;
+
+ return i;
+}
+
+int
+orc_program_dup_temporary (OrcProgram *program, int var, int j)
+{
+ int i = program->n_vars;
+
+ program->vars[i].vartype = ORC_VAR_TYPE_TEMP;
+ program->vars[i].type = program->vars[var].type;
+ program->vars[i].name = malloc (strlen(program->vars[var].name) + 10);
+ sprintf(program->vars[i].name, "%s.dup%d", program->vars[var].name, j);
+ program->n_vars++;
+
+ return i;
+}
+
+int
+orc_program_add_source (OrcProgram *program, const char *type, const char *name)
+{
+ int i = program->n_vars;
+
+ program->vars[i].vartype = ORC_VAR_TYPE_SRC;
+ program->vars[i].type = orc_type_get(type);
+ program->vars[i].name = strdup(name);
+ program->n_vars++;
+
+ return i;
+}
+
+int
+orc_program_add_destination (OrcProgram *program, const char *type, const char *name)
+{
+ int i = program->n_vars;
+
+ program->vars[i].vartype = ORC_VAR_TYPE_DEST;
+ program->vars[i].type = orc_type_get(type);
+ program->vars[i].name = strdup(name);
+ program->n_vars++;
+
+ return i;
+}
+
+int
+orc_program_add_constant (OrcProgram *program, const char *type, int value, const char *name)
+{
+ int i = program->n_vars;
+
+ program->vars[i].vartype = ORC_VAR_TYPE_CONST;
+ program->vars[i].type = orc_type_get(type);
+ program->vars[i].s16 = value;
+ program->vars[i].name = strdup(name);
+ program->n_vars++;
+
+ return i;
+}
+
+int
+orc_program_add_parameter (OrcProgram *program, OrcType *type, int value, const char *name)
+{
+
+ return 0;
+}
+
+void
+orc_program_append (OrcProgram *program, const char *name, int arg0,
+ int arg1, int arg2)
+{
+ OrcInstruction *insn;
+
+ insn = program->insns + program->n_insns;
+
+ insn->opcode = orc_opcode_find_by_name (name);
+ if (!insn->opcode) {
+ printf("unknown opcode: %s\n", name);
+ }
+ insn->args[0] = arg0;
+ insn->args[1] = arg1;
+ insn->args[2] = arg2;
+
+ program->n_insns++;
+}
+
+int
+orc_program_find_var_by_name (OrcProgram *program, const char *name)
+{
+ int i;
+
+ for(i=0;i<program->n_vars;i++){
+ if (strcmp (program->vars[i].name, name) == 0) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+void
+orc_program_append_str (OrcProgram *program, const char *name,
+ const char *arg1, const char *arg2, const char *arg3)
+{
+ OrcInstruction *insn;
+
+ insn = program->insns + program->n_insns;
+
+ insn->opcode = orc_opcode_find_by_name (name);
+ if (!insn->opcode) {
+ printf("unknown opcode: %s\n", name);
+ }
+ insn->args[0] = orc_program_find_var_by_name (program, arg1);
+ insn->args[1] = orc_program_find_var_by_name (program, arg2);
+ insn->args[2] = orc_program_find_var_by_name (program, arg3);
+
+ program->n_insns++;
+}
+
+int
+orc_program_allocate_register (OrcProgram *program, int data_reg)
+{
+ int i;
+ int klass;
+ int offset;
+
+ if (data_reg) {
+ klass = program->data_register_class;
+ } else {
+ klass = ORC_REGCLASS_GP;
+ }
+ offset = klass << 5;
+
+ for(i=offset;i<offset+32;i++){
+ if (program->valid_regs[i] &&
+ !program->save_regs[i] &&
+ program->alloc_regs[i] == 0) {
+ program->alloc_regs[i]++;
+ program->used_regs[i] = 1;
+ return i;
+ }
+ }
+ for(i=offset;i<offset+32;i++){
+ if (program->valid_regs[i] &&
+ program->alloc_regs[i] == 0) {
+ program->alloc_regs[i]++;
+ program->used_regs[i] = 1;
+ return i;
+ }
+ }
+
+ printf("register overflow\n");
+ return 0;
+}
+
+void
+orc_program_compile (OrcProgram *program)
+{
+#if defined(HAVE_POWERPC)
+ orc_program_powerpc_init (program);
+#elif defined(HAVE_I386)
+ orc_program_x86_init (program);
+#elif defined(HAVE_AMD64)
+ orc_program_x86_init (program);
+#else
+#error FIXME
+#endif
+
+ orc_program_assign_rules (program);
+ orc_program_rewrite_vars (program);
+
+ orc_program_global_reg_alloc (program);
+
+ orc_program_do_regs (program);
+
+ orc_program_rewrite_vars2 (program);
+
+ orc_program_allocate_codemem (program);
+#if defined(HAVE_POWERPC)
+ orc_program_assemble_powerpc (program);
+#elif defined(HAVE_I386)
+ orc_program_assemble_x86 (program);
+#elif defined(HAVE_AMD64)
+ orc_program_assemble_x86 (program);
+#else
+#error FIXME
+#endif
+ //orc_program_assemble_c (program);
+
+ orc_program_dump_code (program);
+}
+
+void
+orc_program_assign_rules (OrcProgram *program)
+{
+ int i;
+
+ for(i=0;i<program->n_insns;i++) {
+ OrcInstruction *insn = program->insns + i;
+ unsigned int flags;
+
+ insn->rule = insn->opcode->rules + program->rule_set;
+
+ flags = insn->rule->flags;
+ if (flags & ORC_RULE_REG_IMM &&
+ program->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
+ program->insns[i].rule_flag = ORC_RULE_REG_IMM;
+ } else {
+ program->insns[i].rule_flag = ORC_RULE_REG_REG;
+ }
+ }
+}
+
+void
+orc_program_rewrite_vars (OrcProgram *program)
+{
+ int j;
+ int k;
+ OrcInstruction *insn;
+ OrcOpcode *opcode;
+ int var;
+ int actual_var;
+
+ for(j=0;j<program->n_insns;j++){
+ insn = program->insns + j;
+ opcode = insn->opcode;
+
+ /* set up args */
+ for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
+ var = insn->args[k];
+ if (program->vars[var].vartype == ORC_VAR_TYPE_DEST) {
+ printf("ERROR: using dest var as source\n");
+ }
+
+ actual_var = var;
+ if (program->vars[var].replaced) {
+ actual_var = program->vars[var].replacement;
+ insn->args[k] = actual_var;
+ }
+
+ if (!program->vars[var].used) {
+ if (program->vars[var].vartype == ORC_VAR_TYPE_TEMP) {
+ printf("ERROR: using uninitialized temp var\n");
+ }
+ program->vars[var].used = TRUE;
+ program->vars[var].first_use = j;
+ }
+ program->vars[actual_var].last_use = j;
+ }
+
+ for(k=0;k<opcode->n_dest;k++){
+ var = insn->args[k];
+
+ if (program->vars[var].vartype == ORC_VAR_TYPE_SRC) {
+ printf("ERROR: using src var as dest\n");
+ }
+ if (program->vars[var].vartype == ORC_VAR_TYPE_CONST) {
+ printf("ERROR: using const var as dest\n");
+ }
+ if (program->vars[var].vartype == ORC_VAR_TYPE_PARAM) {
+ printf("ERROR: using param var as dest\n");
+ }
+
+ actual_var = var;
+ if (program->vars[var].replaced) {
+ actual_var = program->vars[var].replacement;
+ insn->args[k] = actual_var;
+ }
+
+ if (!program->vars[var].used) {
+ program->vars[actual_var].used = TRUE;
+ program->vars[actual_var].first_use = j;
+ } else {
+ if (program->vars[var].vartype == ORC_VAR_TYPE_DEST) {
+ printf("ERROR: writing dest more than once\n");
+ }
+ if (program->vars[var].vartype == ORC_VAR_TYPE_TEMP) {
+ actual_var = orc_program_dup_temporary (program, var, j);
+ program->vars[var].replaced = TRUE;
+ program->vars[var].replacement = actual_var;
+ insn->args[k] = actual_var;
+ program->vars[actual_var].used = TRUE;
+ program->vars[actual_var].first_use = j;
+ }
+ }
+ program->vars[actual_var].last_use = j;
+ }
+ }
+}
+
+void
+orc_program_global_reg_alloc (OrcProgram *program)
+{
+ int i;
+ OrcVariable *var;
+
+
+ for(i=0;i<program->n_vars;i++){
+ var = program->vars + i;
+ switch (var->vartype) {
+ case ORC_VAR_TYPE_CONST:
+ var->first_use = -1;
+ var->last_use = -1;
+ var->alloc = orc_program_allocate_register (program, TRUE);
+ break;
+ case ORC_VAR_TYPE_SRC:
+ case ORC_VAR_TYPE_DEST:
+ var->ptr_register = orc_program_allocate_register (program, FALSE);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void
+orc_program_do_regs (OrcProgram *program)
+{
+ int i;
+ int k;
+ int var;
+ OrcInstruction *insn;
+ OrcOpcode *opcode;
+
+ for(i=0;i<program->n_insns;i++){
+ insn = program->insns + i;
+ opcode = insn->opcode;
+
+ for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
+ var = insn->args[k];
+
+
+ }
+
+ for(k=0;k<opcode->n_dest;k++){
+ var = insn->args[k];
+ }
+ }
+}
+
+void
+orc_program_rewrite_vars2 (OrcProgram *program)
+{
+ int i;
+ int j;
+ int k;
+
+ for(j=0;j<program->n_insns;j++){
+#if 1
+ /* must be true to chain src1 to dest:
+ * - rule must handle it
+ * - src1 must be last_use
+ */
+ if (1 || program->insns[j].rule->flags & ORC_RULE_REG_REG) {
+ int src1 = program->insns[j].args[1];
+ int dest = program->insns[j].args[0];
+ if (program->vars[src1].last_use == j) {
+ if (program->vars[src1].first_use == j) {
+ k = orc_program_allocate_register (program, TRUE);
+ program->vars[src1].alloc = k;
+ }
+ program->alloc_regs[program->vars[src1].alloc]++;
+ program->vars[dest].alloc = program->vars[src1].alloc;
+ }
+ }
+#endif
+
+ if (program->insns[j].rule_flag == ORC_RULE_REG_IMM) {
+ /* immediate operand, don't load */
+ int src2 = program->insns[j].args[2];
+ program->vars[src2].alloc = 1;
+ } else {
+ int src2 = program->insns[j].args[2];
+ if (program->vars[src2].alloc == 1) {
+ program->vars[src2].alloc = 0;
+ }
+ }
+
+ for(i=0;i<program->n_vars;i++){
+ if (program->vars[i].first_use == j) {
+ if (program->vars[i].alloc) continue;
+ k = orc_program_allocate_register (program, TRUE);
+ program->vars[i].alloc = k;
+ }
+ }
+ for(i=0;i<program->n_vars;i++){
+ if (program->vars[i].last_use == j) {
+ program->alloc_regs[program->vars[i].alloc]--;
+ }
+ }
+ }
+
+#if 0
+ for(i=0;i<program->n_vars;i++){
+ printf("# %2d: %2d %2d %d\n",
+ i,
+ program->vars[i].first_use,
+ program->vars[i].last_use,
+ program->vars[i].alloc);
+ }
+#endif
+
+}
+
+void
+orc_program_dump_code (OrcProgram *program)
+{
+ FILE *file;
+
+ file = fopen("dump","w");
+
+ fwrite (program->code, 1, program->codeptr - program->code, file);
+ fclose (file);
+}
+
+void
+orc_program_dump (OrcProgram *program)
+{
+ int i;
+ int j;
+ OrcOpcode *opcode;
+ OrcInstruction *insn;
+
+ for(i=0;i<program->n_insns;i++){
+ insn = program->insns + i;
+ opcode = insn->opcode;
+
+ printf("insn: %d\n", i);
+ printf(" opcode: %s\n", opcode->name);
+
+ for(j=0;j<opcode->n_dest;j++){
+ printf(" dest%d: %d %s\n", j, insn->args[j],
+ program->vars[insn->args[j]].name);
+ }
+ for(j=0;j<opcode->n_src;j++){
+ printf(" src%d: %d %s\n", j, insn->args[opcode->n_dest + j],
+ program->vars[insn->args[opcode->n_dest + j]].name);
+ }
+
+ printf("\n");
+ }
+
+ for(i=0;i<program->n_vars;i++){
+ printf("var: %d %s\n", i, program->vars[i].name);
+ printf("first_use: %d\n", program->vars[i].first_use);
+ printf("last_use: %d\n", program->vars[i].last_use);
+
+ printf("\n");
+ }
+
+}
+
+int
+orc_variable_get_size (OrcVariable *var)
+{
+ return 2;
+}
+
--- /dev/null
+
+#ifndef _ORC_PROGRAM_H_
+#define _ORC_PROGRAM_H_
+
+//#include <glib.h>
+
+typedef struct _OrcType OrcType;
+typedef struct _OrcExecutor OrcExecutor;
+typedef struct _OrcVariable OrcVariable;
+typedef struct _OrcOpcode OrcOpcode;
+typedef struct _OrcArgument OrcArgument;
+typedef struct _OrcInstruction OrcInstruction;
+typedef struct _OrcProgram OrcProgram;
+typedef struct _OrcRegister OrcRegister;
+typedef struct _OrcRule OrcRule;
+typedef struct _OrcFixup OrcFixup;
+
+typedef void (*OrcOpcodeEmulateFunc)(OrcExecutor *ex, void *user);
+typedef void (*OrcRuleEmitFunc)(OrcProgram *p, void *user, OrcInstruction *insn);
+
+#define ORC_N_REGS (32*4)
+#define ORC_N_INSNS 100
+#define ORC_N_VARIABLES 100
+#define ORC_N_REGISTERS 100
+#define ORC_N_FIXUPS 100
+#define ORC_N_LABELS 100
+
+#define ORC_GP_REG_BASE 32
+#define ORC_VEC1_REG_BASE 64
+#define ORC_VEC2_REG_BASE 96
+
+#define ORC_REGCLASS_GP 1
+
+#define ORC_OPCODE_N_ARGS 4
+#define ORC_OPCODE_N_RULES 12
+
+#define ORC_STRUCT_OFFSET(struct_type, member) \
+ ((long) ((unsigned int *) &((struct_type*) 0)->member))
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+enum {
+ ORC_RULE_C = 0,
+ ORC_RULE_SCALAR_1,
+ ORC_RULE_SCALAR_2,
+ ORC_RULE_MMX_1,
+ ORC_RULE_MMX_2,
+ ORC_RULE_MMX_4,
+ ORC_RULE_MMX_8,
+ ORC_RULE_SSE_1,
+ ORC_RULE_SSE_2,
+ ORC_RULE_SSE_4,
+ ORC_RULE_SSE_8,
+ ORC_RULE_ALTIVEC_1
+};
+
+struct _OrcType {
+ char *name;
+ int size;
+};
+
+typedef enum {
+ ORC_VAR_TYPE_TEMP,
+ ORC_VAR_TYPE_SRC,
+ ORC_VAR_TYPE_DEST,
+ ORC_VAR_TYPE_CONST,
+ ORC_VAR_TYPE_PARAM
+} OrcVarType;
+
+struct _OrcVariable {
+ char *name;
+
+ OrcType *type;
+ OrcVarType vartype;
+
+ int used;
+ int first_use;
+ int last_use;
+ int replaced;
+ int replacement;
+
+ int alloc;
+ int is_chained;
+
+ int16_t s16;
+
+ int ptr_register;
+ int ptr_offset;
+};
+
+struct _OrcRule {
+ unsigned int flags;
+ OrcRuleEmitFunc emit;
+ void *emit_user;
+};
+
+struct _OrcOpcode {
+ char *name;
+ int n_src;
+ int n_dest;
+ OrcType *arg_types[ORC_OPCODE_N_ARGS];
+
+ OrcRule rules[ORC_OPCODE_N_RULES];
+
+ OrcOpcodeEmulateFunc emulate;
+ void *emulate_user;
+};
+
+struct _OrcArgument {
+ OrcVariable *var;
+ int is_indirect;
+ int is_indexed;
+ OrcVariable *index_var;
+ int index_scale;
+ int type; // remove
+ int index; // remove
+ int offset;
+};
+
+struct _OrcInstruction {
+ OrcOpcode *opcode;
+ int args[3];
+
+ OrcRule *rule;
+ unsigned int rule_flag;
+};
+
+struct _OrcFixup {
+ unsigned char *ptr;
+ int type;
+ int label;
+};
+
+struct _OrcRegister {
+ int var;
+
+ int is_data;
+ int is_chained;
+ int chained_reg;
+
+ int merge;
+};
+
+
+struct _OrcProgram {
+ OrcInstruction insns[ORC_N_INSNS];
+ int n_insns;
+
+ OrcVariable vars[ORC_N_VARIABLES];
+ int n_vars;
+
+ OrcInstruction *insn;
+ int rule_set;
+
+ OrcRegister registers[ORC_N_REGISTERS];
+ int n_regs;
+
+ unsigned char *code;
+ void *code_exec;
+ unsigned char *codeptr;
+ int code_size;
+
+ OrcFixup fixups[ORC_N_FIXUPS];
+ int n_fixups;
+ unsigned char *labels[ORC_N_LABELS];
+
+ int error;
+
+ int data_register_class;
+
+ int valid_regs[ORC_N_REGS];
+ int save_regs[ORC_N_REGS];
+ int used_regs[ORC_N_REGS];
+ int alloc_regs[ORC_N_REGS];
+
+ int loop_shift;
+ int n_per_loop;
+};
+
+struct _OrcExecutor {
+ OrcProgram *program;
+ int n;
+ int counter1;
+ int counter2;
+ int counter3;
+
+ void *arrays[ORC_N_VARIABLES];
+
+ OrcVariable vars[ORC_N_VARIABLES];
+ OrcVariable *args[ORC_OPCODE_N_ARGS];
+
+};
+
+enum {
+ ORC_RULE_3REG = (1<<0),
+ ORC_RULE_REG_REG = (1<<1),
+ ORC_RULE_MEM_REG = (1<<2),
+ ORC_RULE_REG_MEM = (1<<3),
+ ORC_RULE_REG_IMM = (1<<4),
+ ORC_RULE_MEM_IMM = (1<<5),
+ ORC_RULE_REG_CL = (1<<6)
+};
+
+
+void orc_init (void);
+
+OrcProgram * orc_program_new (void);
+OrcProgram * orc_program_new_dss (const char *type1, const char *type2,
+ const char *type3);
+OrcOpcode * orc_opcode_find_by_name (const char *name);
+void orc_opcode_init (void);
+
+void orc_program_append (OrcProgram *p, const char *opcode, int arg0, int arg1, int arg2);
+void orc_program_append_str (OrcProgram *p, const char *opcode,
+ const char * arg0, const char * arg1, const char * arg2);
+
+void orc_x86_init (void);
+void orc_powerpc_init (void);
+void orc_c_init (void);
+
+void orc_program_compile (OrcProgram *p);
+void orc_program_x86_init (OrcProgram *p);
+void orc_program_powerpc_init (OrcProgram *p);
+void orc_program_assemble_x86 (OrcProgram *p);
+void orc_program_assemble_powerpc (OrcProgram *p);
+void orc_program_assemble_c (OrcProgram *p);
+void orc_program_free (OrcProgram *program);
+
+int orc_program_find_var_by_name (OrcProgram *program, const char *name);
+
+int orc_program_add_temporary (OrcProgram *program, const char *type, const char *name);
+int orc_program_dup_temporary (OrcProgram *program, int i, int j);
+int orc_program_add_source (OrcProgram *program, const char *type, const char *name);
+int orc_program_add_destination (OrcProgram *program, const char *type, const char *name);
+int orc_program_add_constant (OrcProgram *program, const char *type, int value, const char *name);
+void orc_program_append (OrcProgram *program, const char *opcode, int arg0,
+ int arg1, int arg2);
+
+void orc_program_x86_reset_alloc (OrcProgram *program);
+void orc_program_powerpc_reset_alloc (OrcProgram *program);
+
+
+OrcType * orc_type_get (const char *name);
+void orc_type_register (const char *name, int size);
+
+OrcExecutor * orc_executor_new (OrcProgram *program);
+void orc_executor_free (OrcExecutor *ex);
+void orc_executor_set_array (OrcExecutor *ex, int var, void *ptr);
+void orc_executor_set_array_str (OrcExecutor *ex, const char *name, void *ptr);
+void orc_executor_set_n (OrcExecutor *ex, int n);
+void orc_executor_emulate (OrcExecutor *ex);
+void orc_executor_run (OrcExecutor *ex);
+
+void orc_rule_register (const char *opcode_name, unsigned int mode,
+ OrcRuleEmitFunc emit, void *emit_user, unsigned int flags);
+
+int orc_program_allocate_register (OrcProgram *program, int is_data);
+int orc_program_x86_allocate_register (OrcProgram *program, int is_data);
+int orc_program_powerpc_allocate_register (OrcProgram *program, int is_data);
+
+void orc_program_x86_register_rules (void);
+void orc_program_allocate_codemem (OrcProgram *program);
+void orc_program_dump_code (OrcProgram *program);
+
+int orc_variable_get_size (OrcVariable *var);
+
+#endif
+
--- /dev/null
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <orc/orcprogram.h>
+
+
+void
+orc_rule_register (const char *opcode_name, unsigned int mode,
+ OrcRuleEmitFunc emit, void *emit_user, unsigned int flags)
+{
+ OrcOpcode *opcode;
+
+ opcode = orc_opcode_find_by_name (opcode_name);
+
+ opcode->rules[mode].emit = emit;
+ opcode->rules[mode].emit_user = emit_user;
+ opcode->rules[mode].flags = flags;
+}
+
--- /dev/null
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <orc/orcprogram.h>
+#include <orc/x86.h>
+
+#define SIZE 65536
+
+/* mmx rules */
+
+void
+mmx_emit_loadi_s16 (OrcProgram *p, int reg, int value)
+{
+ if (value == 0) {
+ printf(" pxor %%%s, %%%s\n", x86_get_regname_mmx(reg),
+ x86_get_regname_mmx(reg));
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xef;
+ x86_emit_modrm_reg (p, reg, reg);
+ } else {
+#if 1
+ x86_emit_mov_imm_reg (p, 4, value, X86_ECX);
+
+ printf(" movd %%ecx, %%%s\n", x86_get_regname_mmx(reg));
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x6e;
+ x86_emit_modrm_reg (p, X86_ECX, reg);
+#else
+ printf(" pinsrw $0, %%ecx, %%%s\n", x86_get_regname_mmx(reg));
+#endif
+
+ printf(" pshufw $0, %%%s, %%%s\n", x86_get_regname_mmx(reg),
+ x86_get_regname_mmx(reg));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x70;
+ x86_emit_modrm_reg (p, reg, reg);
+ *p->codeptr++ = 0x00;
+ }
+}
+
+static void
+mmx_rule_loadi_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ mmx_emit_loadi_s16 (p, p->vars[insn->args[0]].alloc,
+ p->vars[insn->args[2]].s16);
+}
+
+static void
+mmx_rule_add_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" paddw %%%s, %%%s\n",
+ x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
+ x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xfd;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+mmx_rule_sub_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" psubw %%%s, %%%s\n",
+ x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
+ x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xf9;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+mmx_rule_mul_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" pmullw %%%s, %%%s\n",
+ x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
+ x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xd5;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+mmx_rule_lshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
+ printf(" psllw $%d, %%%s\n",
+ p->vars[insn->args[2]].s16,
+ x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x71;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 6);
+ *p->codeptr++ = p->vars[insn->args[2]].s16;
+ } else {
+ /* FIXME this doesn't work quite right */
+ printf(" psllw %%%s, %%%s\n",
+ x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
+ x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xf1;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
+ p->vars[insn->args[2]].alloc);
+ }
+}
+
+static void
+mmx_rule_rshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
+ printf(" psraw $%d, %%%s\n",
+ p->vars[insn->args[2]].s16,
+ x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x71;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 4);
+ *p->codeptr++ = p->vars[insn->args[2]].s16;
+ } else {
+ /* FIXME this doesn't work quite right */
+ printf(" psraw %%%s, %%%s\n",
+ x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
+ x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xe1;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
+ p->vars[insn->args[2]].alloc);
+ }
+}
+
+void
+orc_program_mmx_register_rules (void)
+{
+ int i;
+
+ orc_rule_register ("_loadi_s16", ORC_RULE_MMX_4, mmx_rule_loadi_s16, NULL,
+ ORC_RULE_REG_IMM);
+
+ for(i=ORC_RULE_MMX_1; i <= ORC_RULE_MMX_4; i++) {
+ orc_rule_register ("add_s16", i, mmx_rule_add_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("sub_s16", i, mmx_rule_sub_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("mul_s16", i, mmx_rule_mul_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("lshift_s16", i, mmx_rule_lshift_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("rshift_s16", i, mmx_rule_rshift_s16, NULL,
+ ORC_RULE_REG_REG);
+ }
+}
+
--- /dev/null
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <orc/orcprogram.h>
+#include <orc/x86.h>
+
+#define SIZE 65536
+
+/* sse rules */
+
+static void
+sse_emit_loadi_s16 (OrcProgram *p, int reg, int value)
+{
+ if (value == 0) {
+ printf(" pxor %%%s, %%%s\n", x86_get_regname_sse(reg),
+ x86_get_regname_sse(reg));
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xef;
+ x86_emit_modrm_reg (p, reg, reg);
+ } else {
+ x86_emit_mov_imm_reg (p, 4, value, X86_ECX);
+
+ printf(" movd %%ecx, %%%s\n", x86_get_regname_sse(reg));
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x6e;
+ x86_emit_modrm_reg (p, X86_ECX, reg);
+
+ printf(" pshufw $0, %%%s, %%%s\n", x86_get_regname_sse(reg),
+ x86_get_regname_sse(reg));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x70;
+ x86_emit_modrm_reg (p, reg, reg);
+ *p->codeptr++ = 0x00;
+ }
+}
+
+static void
+sse_rule_loadi_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ sse_emit_loadi_s16 (p, p->vars[insn->args[0]].alloc,
+ p->vars[insn->args[2]].s16);
+}
+
+static void
+sse_rule_add_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" paddw %%%s, %%%s\n",
+ x86_get_regname_sse(p->vars[insn->args[2]].alloc),
+ x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xfd;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+sse_rule_sub_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" psubw %%%s, %%%s\n",
+ x86_get_regname_sse(p->vars[insn->args[2]].alloc),
+ x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xf9;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+sse_rule_mul_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" pmullw %%%s, %%%s\n",
+ x86_get_regname_sse(p->vars[insn->args[2]].alloc),
+ x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xd5;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+sse_rule_lshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
+ printf(" psllw $%d, %%%s\n",
+ p->vars[insn->args[2]].s16,
+ x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x71;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 6);
+ *p->codeptr++ = p->vars[insn->args[2]].s16;
+ } else {
+ /* FIXME this doesn't work quite right */
+ printf(" psllw %%%s, %%%s\n",
+ x86_get_regname_sse(p->vars[insn->args[2]].alloc),
+ x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xf1;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
+ p->vars[insn->args[2]].alloc);
+ }
+}
+
+static void
+sse_rule_rshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
+ printf(" psraw $%d, %%%s\n",
+ p->vars[insn->args[2]].s16,
+ x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x71;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 4);
+ *p->codeptr++ = p->vars[insn->args[2]].s16;
+ } else {
+ /* FIXME this doesn't work quite right */
+ printf(" psraw %%%s, %%%s\n",
+ x86_get_regname_sse(p->vars[insn->args[2]].alloc),
+ x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xe1;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
+ p->vars[insn->args[2]].alloc);
+ }
+}
+
+void
+orc_program_sse_register_rules (void)
+{
+ int i;
+
+ orc_rule_register ("_loadi_s16", ORC_RULE_SSE_4, sse_rule_loadi_s16, NULL,
+ ORC_RULE_REG_IMM);
+
+ for(i=ORC_RULE_SSE_1; i <= ORC_RULE_SSE_8; i++) {
+ orc_rule_register ("add_s16", i, sse_rule_add_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("sub_s16", i, sse_rule_sub_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("mul_s16", i, sse_rule_mul_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("lshift_s16", i, sse_rule_lshift_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("rshift_s16", i, sse_rule_rshift_s16, NULL,
+ ORC_RULE_REG_REG);
+ }
+}
+
--- /dev/null
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <orc/orcprogram.h>
+#include <orc/x86.h>
+
+#define SIZE 65536
+
+/* rules */
+
+static void
+x86_rule_loadi_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ x86_emit_mov_imm_reg (p, 2, p->vars[insn->args[2]].s16,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+x86_rule_add_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ if (insn->rule_flag == ORC_RULE_REG_IMM) {
+ int value = p->vars[insn->args[2]].s16;
+ printf(" addw $%d, %%%s\n", value,
+ x86_get_regname_16(p->vars[insn->args[0]].alloc));
+
+ if (value >= -128 && value < 128) {
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x83;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 0);
+ *p->codeptr++ = value;
+ } else {
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x81;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 0);
+ *p->codeptr++ = value & 0xff;
+ *p->codeptr++ = value >> 8;
+ }
+ } else {
+ printf(" addw %%%s, %%%s\n",
+ x86_get_regname_16(p->vars[insn->args[2]].alloc),
+ x86_get_regname_16(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x03;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+ }
+}
+
+static void
+x86_rule_sub_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" subw %%%s, %%%s\n",
+ x86_get_regname_16(p->vars[insn->args[2]].alloc),
+ x86_get_regname_16(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x2b;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+x86_rule_mul_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" imulw %%%s, %%%s\n",
+ x86_get_regname_16(p->vars[insn->args[2]].alloc),
+ x86_get_regname_16(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xaf;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+x86_rule_lshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ x86_emit_mov_reg_reg(p, 4, p->vars[insn->args[2]].alloc, X86_ECX);
+
+ printf(" shlw %%cl, %%%s\n",
+ x86_get_regname_16(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0xd3;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 4);
+}
+
+static void
+x86_rule_rshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ if (insn->rule_flag == ORC_RULE_REG_IMM) {
+ printf(" sarw $%d, %%%s\n",
+ p->vars[insn->args[2]].s16,
+ x86_get_regname_16(p->vars[insn->args[0]].alloc));
+
+ if (p->vars[insn->args[2]].s16 == 1) {
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0xd1;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 7);
+ } else {
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0xc1;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 7);
+ *p->codeptr++ = p->vars[insn->args[2]].s16;
+ }
+ } else {
+ x86_emit_mov_reg_reg(p, 4, p->vars[insn->args[2]].alloc, X86_ECX);
+
+ printf(" sarw %%cl, %%%s\n",
+ x86_get_regname_16(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0xd3;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 7);
+ }
+}
+
+
+void
+orc_program_x86_register_rules (void)
+{
+ orc_rule_register ("_loadi_s16", ORC_RULE_SCALAR_1, x86_rule_loadi_s16, NULL,
+ ORC_RULE_REG_IMM);
+
+ orc_rule_register ("add_s16", ORC_RULE_SCALAR_1, x86_rule_add_s16, NULL,
+ ORC_RULE_REG_REG | ORC_RULE_REG_IMM);
+ orc_rule_register ("sub_s16", ORC_RULE_SCALAR_1, x86_rule_sub_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("mul_s16", ORC_RULE_SCALAR_1, x86_rule_mul_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("lshift_s16", ORC_RULE_SCALAR_1, x86_rule_lshift_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("rshift_s16", ORC_RULE_SCALAR_1, x86_rule_rshift_s16, NULL,
+ ORC_RULE_REG_REG | ORC_RULE_REG_IMM);
+}
+
--- /dev/null
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <orc/orcprogram.h>
+
+OrcType *types;
+static int n_types;
+static int n_alloc_types;
+
+OrcType *
+orc_type_get (const char *name)
+{
+ int i;
+ for(i=0;i<n_types;i++){
+ if (!strcmp (types[i].name, name)) {
+ return types + i;
+ }
+ }
+ return NULL;
+}
+
+void
+orc_type_register (const char *name, int size)
+{
+ OrcType *type;
+
+ if (n_types == n_alloc_types) {
+ n_alloc_types += 100;
+ types = realloc (types, sizeof(OrcType) * n_alloc_types);
+ }
+
+ type = types + n_types;
+ type->name = strdup (name);
+ type->size = size;
+
+ n_types++;
+}
+
+
+
--- /dev/null
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <orc/orcprogram.h>
+
+void
+test (OrcExecutor *ex)
+{
+ int i;
+ int n = ex->n;
+ int16_t *var0 = ex->arrays[0];
+ int16_t *var1 = ex->arrays[1];
+ int16_t *var2 = ex->arrays[2];
+ int16_t var3;
+ int16_t var6;
+
+ for (i = 0; i < n; i++) {
+ var0[i] = (var1[i] + var2[i] + 1) >> 1;
+ }
+}
+
--- /dev/null
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <orc/orcprogram.h>
+#include <orc/x86.h>
+
+const char *
+x86_get_regname(int i)
+{
+ static const char *x86_regs[] = {
+ "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
+ "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" };
+
+ if (i>=ORC_GP_REG_BASE && i<ORC_GP_REG_BASE + 16) return x86_regs[i - ORC_GP_REG_BASE];
+ switch (i) {
+ case 0:
+ return "UNALLOCATED";
+ case 1:
+ return "direct";
+ default:
+ printf("register %d\n", i);
+ return "ERROR";
+ }
+}
+
+int
+x86_get_regnum(int i)
+{
+ return (i&0xf);
+}
+
+const char *
+x86_get_regname_16(int i)
+{
+ static const char *x86_regs[] = { "ax", "cx", "dx", "bx",
+ "sp", "bp", "si", "di" };
+
+ if (i>=ORC_GP_REG_BASE && i<ORC_GP_REG_BASE + 8) return x86_regs[i - ORC_GP_REG_BASE];
+ switch (i) {
+ case 0:
+ return "UNALLOCATED";
+ case 1:
+ return "direct";
+ default:
+ return "ERROR";
+ }
+}
+
+const char *
+x86_get_regname_64(int i)
+{
+ static const char *x86_regs[] = {
+ "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" };
+
+ if (i>=ORC_GP_REG_BASE && i<ORC_GP_REG_BASE + 16) return x86_regs[i - ORC_GP_REG_BASE];
+ switch (i) {
+ case 0:
+ return "UNALLOCATED";
+ case 1:
+ return "direct";
+ default:
+ return "ERROR";
+ }
+}
+
+const char *
+x86_get_regname_ptr(int i)
+{
+ if (x86_64) {
+ return x86_get_regname_64 (i);
+ } else {
+ return x86_get_regname (i);
+ }
+}
+
+const char *
+x86_get_regname_mmx(int i)
+{
+ static const char *x86_regs[] = { "mm0", "mm1", "mm2", "mm3",
+ "mm4", "mm5", "mm6", "mm7" };
+
+ if (i>=X86_MM0 && i<X86_MM0 + 8) return x86_regs[i - X86_MM0];
+ switch (i) {
+ case 0:
+ return "UNALLOCATED";
+ case 1:
+ return "direct";
+ default:
+ return "ERROR";
+ }
+}
+
+const char *
+x86_get_regname_sse(int i)
+{
+ static const char *x86_regs[] = {
+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
+ "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
+ };
+
+ if (i>=X86_XMM0 && i<X86_XMM0 + 16) return x86_regs[i - X86_XMM0];
+ switch (i) {
+ case 0:
+ return "UNALLOCATED";
+ case 1:
+ return "direct";
+ default:
+ return "ERROR";
+ }
+}
+
+void
+x86_emit_push (OrcProgram *program, int size, int reg)
+{
+
+ if (size == 1) {
+ program->error = 1;
+ } else if (size == 2) {
+ printf(" pushw %%%s\n", x86_get_regname_16(reg));
+ *program->codeptr++ = 0x66;
+ *program->codeptr++ = 0x50 + x86_get_regnum(reg);
+ } else {
+ printf(" pushl %%%s\n", x86_get_regname(reg));
+ *program->codeptr++ = 0x50 + x86_get_regnum(reg);
+ }
+}
+
+void
+x86_emit_pop (OrcProgram *program, int size, int reg)
+{
+
+ if (size == 1) {
+ program->error = 1;
+ } else if (size == 2) {
+ printf(" popw %%%s\n", x86_get_regname_16(reg));
+ *program->codeptr++ = 0x66;
+ *program->codeptr++ = 0x58 + x86_get_regnum(reg);
+ } else {
+ printf(" popl %%%s\n", x86_get_regname(reg));
+ *program->codeptr++ = 0x58 + x86_get_regnum(reg);
+ }
+}
+
+#define X86_MODRM(mod, rm, reg) ((((mod)&3)<<6)|(((rm)&7)<<0)|(((reg)&7)<<3))
+#define X86_SIB(ss, ind, reg) ((((ss)&3)<<6)|(((ind)&7)<<3)|((reg)&7))
+
+void
+x86_emit_modrm_memoffset (OrcProgram *program, int reg1, int offset, int reg2)
+{
+ if (offset == 0 && reg2 != x86_exec_ptr) {
+ if (reg2 == X86_ESP) {
+ *program->codeptr++ = X86_MODRM(0, 4, reg1);
+ *program->codeptr++ = X86_SIB(0, 4, reg2);
+ } else {
+ *program->codeptr++ = X86_MODRM(0, reg2, reg1);
+ }
+ } else if (offset >= -128 && offset < 128) {
+ *program->codeptr++ = X86_MODRM(1, reg2, reg1);
+ if (reg2 == X86_ESP) {
+ *program->codeptr++ = X86_SIB(0, 4, reg2);
+ }
+ *program->codeptr++ = (offset & 0xff);
+ } else {
+ *program->codeptr++ = X86_MODRM(2, reg2, reg1);
+ if (reg2 == X86_ESP) {
+ *program->codeptr++ = X86_SIB(0, 4, reg2);
+ }
+ *program->codeptr++ = (offset & 0xff);
+ *program->codeptr++ = ((offset>>8) & 0xff);
+ *program->codeptr++ = ((offset>>16) & 0xff);
+ *program->codeptr++ = ((offset>>24) & 0xff);
+ }
+}
+
+void
+x86_emit_modrm_reg (OrcProgram *program, int reg1, int reg2)
+{
+ *program->codeptr++ = X86_MODRM(3, reg1, reg2);
+}
+
+void
+x86_emit_rex (OrcProgram *program, int size, int reg1, int reg2, int reg3)
+{
+ int rex = 0x40;
+
+ if (x86_64) {
+ if (size >= 8) rex |= 0x08;
+ if (reg1 == 1 || (x86_get_regnum(reg1)>=8)) rex |= 0x4;
+ if (reg2 == 1 || (x86_get_regnum(reg2)>=8)) rex |= 0x2;
+ if (reg3 == 1 || (x86_get_regnum(reg3)>=8)) rex |= 0x1;
+
+ if (rex != 0x40) *program->codeptr++ = rex;
+ //*program->codeptr++ = rex;
+ }
+}
+
+void
+x86_emit_mov_memoffset_reg (OrcProgram *program, int size, int offset,
+ int reg1, int reg2)
+{
+
+ if (size == 2) {
+ printf(" movw %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
+ x86_get_regname_16(reg2));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" movl %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
+ x86_get_regname(reg2));
+ } else {
+ printf(" mov %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
+ x86_get_regname_64(reg2));
+ }
+
+ x86_emit_rex(program, size, reg2, 0, reg1);
+ *program->codeptr++ = 0x8b;
+ x86_emit_modrm_memoffset (program, reg2, offset, reg1);
+}
+
+void
+x86_emit_mov_memoffset_mmx (OrcProgram *program, int size, int offset,
+ int reg1, int reg2)
+{
+ if (size == 4) {
+ printf(" movd %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
+ x86_get_regname_mmx(reg2));
+ x86_emit_rex(program, 0, reg2, 0, reg1);
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x6e;
+ } else {
+ printf(" movq %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
+ x86_get_regname_mmx(reg2));
+ x86_emit_rex(program, 0, reg2, 0, reg1);
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x6f;
+ }
+ x86_emit_modrm_memoffset (program, reg2, offset, reg1);
+}
+
+void
+x86_emit_mov_memoffset_sse (OrcProgram *program, int size, int offset,
+ int reg1, int reg2)
+{
+ if (size == 4) {
+ printf(" movd %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
+ x86_get_regname_sse(reg2));
+ *program->codeptr++ = 0x66;
+ x86_emit_rex(program, 0, reg2, 0, reg1);
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x6e;
+ } else if (size == 8) {
+ printf(" movq %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
+ x86_get_regname_sse(reg2));
+ *program->codeptr++ = 0x66;
+ x86_emit_rex(program, 0, reg2, 0, reg1);
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x6f;
+ } else {
+ printf(" movdqu %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
+ x86_get_regname_sse(reg2));
+ x86_emit_rex(program, 0, reg2, 0, reg1);
+ *program->codeptr++ = 0xf3;
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x6f;
+ }
+ x86_emit_modrm_memoffset (program, reg2, offset, reg1);
+}
+
+void
+x86_emit_mov_reg_memoffset (OrcProgram *program, int size, int reg1, int offset,
+ int reg2)
+{
+ if (size == 2) {
+ printf(" movw %%%s, %d(%%%s)\n", x86_get_regname_16(reg1), offset,
+ x86_get_regname_ptr(reg2));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" movl %%%s, %d(%%%s)\n", x86_get_regname(reg1), offset,
+ x86_get_regname_ptr(reg2));
+ } else {
+ printf(" mov %%%s, %d(%%%s)\n", x86_get_regname(reg1), offset,
+ x86_get_regname_ptr(reg2));
+ }
+
+ x86_emit_rex(program, size, reg1, 0, reg2);
+ *program->codeptr++ = 0x89;
+ x86_emit_modrm_memoffset (program, reg1, offset, reg2);
+}
+
+void
+x86_emit_mov_mmx_memoffset (OrcProgram *program, int size, int reg1, int offset,
+ int reg2)
+{
+ x86_emit_rex(program, 0, reg1, 0, reg2);
+ if (size == 4) {
+ printf(" movd %%%s, %d(%%%s)\n", x86_get_regname_mmx(reg1), offset,
+ x86_get_regname_ptr(reg2));
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x7e;
+ } else if (size == 8) {
+ printf(" movq %%%s, %d(%%%s)\n", x86_get_regname_mmx(reg1), offset,
+ x86_get_regname_ptr(reg2));
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x7f;
+ }
+
+ x86_emit_modrm_memoffset (program, reg1, offset, reg2);
+}
+
+void
+x86_emit_mov_sse_memoffset (OrcProgram *program, int size, int reg1, int offset,
+ int reg2)
+{
+ if (size == 4) {
+ printf(" movd %%%s, %d(%%%s)\n", x86_get_regname_sse(reg1), offset,
+ x86_get_regname_ptr(reg2));
+ *program->codeptr++ = 0x66;
+ x86_emit_rex(program, 0, reg1, 0, reg2);
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x7e;
+ } else if (size == 8) {
+ printf(" movq %%%s, %d(%%%s)\n", x86_get_regname_sse(reg1), offset,
+ x86_get_regname_ptr(reg2));
+ *program->codeptr++ = 0x66;
+ x86_emit_rex(program, 0, reg1, 0, reg2);
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x7f;
+ } else {
+ printf(" movdqu %%%s, %d(%%%s)\n", x86_get_regname_sse(reg1), offset,
+ x86_get_regname_ptr(reg2));
+ *program->codeptr++ = 0xf3;
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x7f;
+ }
+
+ x86_emit_modrm_memoffset (program, reg1, offset, reg2);
+}
+
+void
+x86_emit_mov_imm_reg (OrcProgram *program, int size, int value, int reg1)
+{
+ if (size == 2) {
+ printf(" movw $%d, %%%s\n", value, x86_get_regname_16(reg1));
+ x86_emit_rex(program, size, reg1, 0, 0);
+ *program->codeptr++ = 0x66;
+ *program->codeptr++ = 0xb8 + x86_get_regnum(reg1);
+ *program->codeptr++ = (value & 0xff);
+ *program->codeptr++ = ((value>>8) & 0xff);
+ } else if (size == 4) {
+ printf(" movl $%d, %%%s\n", value, x86_get_regname(reg1));
+ x86_emit_rex(program, size, reg1, 0, 0);
+ *program->codeptr++ = 0xb8 + x86_get_regnum(reg1);
+ *program->codeptr++ = (value & 0xff);
+ *program->codeptr++ = ((value>>8) & 0xff);
+ *program->codeptr++ = ((value>>16) & 0xff);
+ *program->codeptr++ = ((value>>24) & 0xff);
+ } else {
+ /* FIXME */
+ }
+
+}
+
+void x86_emit_mov_reg_reg (OrcProgram *program, int size, int reg1, int reg2)
+{
+ if (size == 2) {
+ printf(" movw %%%s, %%%s\n", x86_get_regname_16(reg1),
+ x86_get_regname_16(reg2));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" movl %%%s, %%%s\n", x86_get_regname(reg1),
+ x86_get_regname(reg2));
+ } else {
+ printf(" mov %%%s, %%%s\n", x86_get_regname_64(reg1),
+ x86_get_regname_64(reg2));
+ }
+
+ x86_emit_rex(program, size, reg2, 0, reg1);
+ *program->codeptr++ = 0x89;
+ x86_emit_modrm_reg (program, reg2, reg1);
+}
+
+void x86_emit_mov_reg_mmx (OrcProgram *program, int reg1, int reg2)
+{
+ /* FIXME */
+ printf(" movd %%%s, %%%s\n", x86_get_regname(reg1),
+ x86_get_regname_mmx(reg2));
+ x86_emit_rex(program, 0, reg1, 0, reg2);
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x6e;
+ x86_emit_modrm_reg (program, reg1, reg2);
+}
+
+void x86_emit_mov_mmx_reg (OrcProgram *program, int reg1, int reg2)
+{
+ /* FIXME */
+ printf(" movd %%%s, %%%s\n", x86_get_regname_mmx(reg1),
+ x86_get_regname(reg2));
+ x86_emit_rex(program, 0, reg2, 0, reg1);
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x7e;
+ x86_emit_modrm_reg (program, reg2, reg1);
+}
+
+void x86_emit_mov_reg_sse (OrcProgram *program, int reg1, int reg2)
+{
+ /* FIXME */
+ printf(" movd %%%s, %%%s\n", x86_get_regname(reg1),
+ x86_get_regname_sse(reg2));
+ *program->codeptr++ = 0x66;
+ x86_emit_rex(program, 0, reg1, 0, reg2);
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x6e;
+ x86_emit_modrm_reg (program, reg1, reg2);
+}
+
+void x86_emit_mov_sse_reg (OrcProgram *program, int reg1, int reg2)
+{
+ /* FIXME */
+ printf(" movd %%%s, %%%s\n", x86_get_regname_sse(reg1),
+ x86_get_regname(reg2));
+ *program->codeptr++ = 0x66;
+ x86_emit_rex(program, 0, reg2, 0, reg1);
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x7e;
+ x86_emit_modrm_reg (program, reg2, reg1);
+}
+
+void
+x86_emit_test_reg_reg (OrcProgram *program, int size, int reg1, int reg2)
+{
+ if (size == 2) {
+ printf(" testw %%%s, %%%s\n", x86_get_regname_16(reg1),
+ x86_get_regname_16(reg2));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" testl %%%s, %%%s\n", x86_get_regname(reg1),
+ x86_get_regname(reg2));
+ } else {
+ printf(" test %%%s, %%%s\n", x86_get_regname(reg1),
+ x86_get_regname(reg2));
+ }
+
+ x86_emit_rex(program, size, reg2, 0, reg1);
+ *program->codeptr++ = 0x85;
+ x86_emit_modrm_reg (program, reg2, reg1);
+}
+
+void
+x86_emit_sar_imm_reg (OrcProgram *program, int size, int value, int reg)
+{
+ if (size == 2) {
+ printf(" sarw $%d, %%%s\n", value, x86_get_regname_16(reg));
+ } else if (size == 4) {
+ printf(" sarl $%d, %%%s\n", value, x86_get_regname(reg));
+ } else {
+ printf(" sar $%d, %%%s\n", value, x86_get_regname_64(reg));
+ }
+
+ x86_emit_rex(program, size, reg, 0, 0);
+ if (value == 1) {
+ *program->codeptr++ = 0xd1;
+ x86_emit_modrm_reg (program, reg, 7);
+ } else {
+ *program->codeptr++ = 0xc1;
+ x86_emit_modrm_reg (program, reg, 7);
+ *program->codeptr++ = value;
+ }
+}
+
+void
+x86_emit_and_imm_memoffset (OrcProgram *program, int size, int value,
+ int offset, int reg)
+{
+ if (size == 2) {
+ printf(" andw $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" andl $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ } else {
+ printf(" and $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ }
+
+ x86_emit_rex(program, size, 0, 0, reg);
+ if (value >= -128 && value < 128) {
+ *program->codeptr++ = 0x83;
+ /* FIXME */
+ x86_emit_modrm_memoffset (program, 0, offset, reg);
+ *program->codeptr++ = (value & 0xff);
+ } else {
+ *program->codeptr++ = 0x81;
+ /* FIXME */
+ x86_emit_modrm_memoffset (program, 0, offset, reg);
+ *program->codeptr++ = (value & 0xff);
+ *program->codeptr++ = ((value>>8) & 0xff);
+ if (size == 4) {
+ *program->codeptr++ = ((value>>16) & 0xff);
+ *program->codeptr++ = ((value>>24) & 0xff);
+ }
+ }
+}
+
+void
+x86_emit_and_imm_reg (OrcProgram *program, int size, int value, int reg)
+{
+ if (size == 2) {
+ printf(" andw $%d, %%%s\n", value, x86_get_regname_16(reg));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" andl $%d, %%%s\n", value, x86_get_regname(reg));
+ } else {
+ printf(" and $%d, %%%s\n", value, x86_get_regname_64(reg));
+ }
+
+ x86_emit_rex(program, size, 0, 0, reg);
+ if (value >= -128 && value < 128) {
+ *program->codeptr++ = 0x83;
+ x86_emit_modrm_reg (program, reg, 4);
+ *program->codeptr++ = (value & 0xff);
+ } else {
+ *program->codeptr++ = 0x81;
+ x86_emit_modrm_reg (program, reg, 4);
+ *program->codeptr++ = (value & 0xff);
+ *program->codeptr++ = ((value>>8) & 0xff);
+ if (size == 4) {
+ *program->codeptr++ = ((value>>16) & 0xff);
+ *program->codeptr++ = ((value>>24) & 0xff);
+ }
+ }
+}
+
+void
+x86_emit_add_imm_memoffset (OrcProgram *program, int size, int value,
+ int offset, int reg)
+{
+ if (size == 2) {
+ printf(" addw $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" addl $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ } else {
+ printf(" add $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ }
+
+ x86_emit_rex(program, size, 0, 0, reg);
+ if (value >= -128 && value < 128) {
+ *program->codeptr++ = 0x83;
+ x86_emit_modrm_memoffset (program, 0, offset, reg);
+ *program->codeptr++ = (value & 0xff);
+ } else {
+ *program->codeptr++ = 0x81;
+ x86_emit_modrm_memoffset (program, 0, offset, reg);
+ *program->codeptr++ = (value & 0xff);
+ *program->codeptr++ = ((value>>8) & 0xff);
+ if (size == 4) {
+ *program->codeptr++ = ((value>>16) & 0xff);
+ *program->codeptr++ = ((value>>24) & 0xff);
+ }
+ }
+}
+
+void
+x86_emit_add_imm_reg (OrcProgram *program, int size, int value, int reg)
+{
+ if (size == 2) {
+ printf(" addw $%d, %%%s\n", value, x86_get_regname_16(reg));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" addl $%d, %%%s\n", value, x86_get_regname(reg));
+ } else {
+ printf(" add $%d, %%%s\n", value, x86_get_regname_64(reg));
+ }
+
+ x86_emit_rex(program, size, 0, 0, reg);
+ if (value >= -128 && value < 128) {
+ *program->codeptr++ = 0x83;
+ x86_emit_modrm_reg (program, reg, 0);
+ *program->codeptr++ = (value & 0xff);
+ } else {
+ *program->codeptr++ = 0x81;
+ x86_emit_modrm_reg (program, reg, 0);
+ *program->codeptr++ = (value & 0xff);
+ *program->codeptr++ = ((value>>8) & 0xff);
+ if (size == 4) {
+ *program->codeptr++ = ((value>>16) & 0xff);
+ *program->codeptr++ = ((value>>24) & 0xff);
+ }
+ }
+}
+
+void
+x86_emit_cmp_imm_memoffset (OrcProgram *program, int size, int value,
+ int offset, int reg)
+{
+ if (size == 2) {
+ printf(" cmpw $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" cmpl $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ } else {
+ printf(" cmp $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ }
+
+ x86_emit_rex(program, size, 0, 0, reg);
+ if (value >= -128 && value < 128) {
+ *program->codeptr++ = 0x83;
+ x86_emit_modrm_memoffset (program, 7, offset, reg);
+ *program->codeptr++ = (value & 0xff);
+ } else {
+ *program->codeptr++ = 0x81;
+ x86_emit_modrm_memoffset (program, 7, offset, reg);
+ *program->codeptr++ = (value & 0xff);
+ *program->codeptr++ = ((value>>8) & 0xff);
+ if (size == 4) {
+ *program->codeptr++ = ((value>>16) & 0xff);
+ *program->codeptr++ = ((value>>24) & 0xff);
+ }
+ }
+}
+
+void
+x86_emit_dec_memoffset (OrcProgram *program, int size,
+ int offset, int reg)
+{
+ if (size == 2) {
+ printf(" decw %d(%%%s)\n", offset, x86_get_regname_ptr(reg));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" decl %d(%%%s)\n", offset, x86_get_regname_ptr(reg));
+ } else {
+ printf(" dec %d(%%%s)\n", offset, x86_get_regname_ptr(reg));
+ }
+
+ x86_emit_rex(program, size, 0, 0, reg);
+ *program->codeptr++ = 0xff;
+ x86_emit_modrm_memoffset (program, 1, offset, reg);
+}
+
+void x86_emit_ret (OrcProgram *program)
+{
+ if (x86_64) {
+ printf(" retq\n");
+ } else {
+ printf(" ret\n");
+ }
+ *program->codeptr++ = 0xc3;
+}
+
+void x86_emit_emms (OrcProgram *program)
+{
+ printf(" emms\n");
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x77;
+}
+
+void
+x86_add_fixup (OrcProgram *program, unsigned char *ptr, int label)
+{
+ program->fixups[program->n_fixups].ptr = ptr;
+ program->fixups[program->n_fixups].label = label;
+ program->fixups[program->n_fixups].type = 0;
+ program->n_fixups++;
+}
+
+void
+x86_add_label (OrcProgram *program, unsigned char *ptr, int label)
+{
+ program->labels[label] = ptr;
+}
+
+void x86_emit_je (OrcProgram *program, int label)
+{
+ printf(" je .L%d\n", label);
+
+ *program->codeptr++ = 0x74;
+ x86_add_fixup (program, program->codeptr, label);
+ *program->codeptr++ = -1;
+}
+
+void x86_emit_jne (OrcProgram *program, int label)
+{
+ printf(" jne .L%d\n", label);
+ *program->codeptr++ = 0x75;
+ x86_add_fixup (program, program->codeptr, label);
+ *program->codeptr++ = -1;
+}
+
+void x86_emit_label (OrcProgram *program, int label)
+{
+ printf(".L%d:\n", label);
+
+ x86_add_label (program, program->codeptr, label);
+}
+
+void
+x86_test (OrcProgram *program)
+{
+ int size;
+ int i;
+ int j;
+ int reg;
+
+ for(size=2;size<=4;size+=2) {
+ for(i=0;i<8;i++){
+ reg = ORC_GP_REG_BASE + i;
+ x86_emit_push (program, size, reg);
+ x86_emit_pop (program, size, reg);
+ x86_emit_mov_imm_reg (program, size, 0, reg);
+ x86_emit_mov_imm_reg (program, size, 1, reg);
+ x86_emit_mov_imm_reg (program, size, 256, reg);
+ x86_emit_dec_memoffset (program, size, 0, reg);
+ x86_emit_dec_memoffset (program, size, 1, reg);
+ x86_emit_dec_memoffset (program, size, 256, reg);
+ x86_emit_add_imm_memoffset (program, size, 1, 0, reg);
+ x86_emit_add_imm_memoffset (program, size, 1, 1, reg);
+ x86_emit_add_imm_memoffset (program, size, 1, 256, reg);
+ x86_emit_add_imm_memoffset (program, size, 256, 0, reg);
+ x86_emit_add_imm_memoffset (program, size, 256, 1, reg);
+ x86_emit_add_imm_memoffset (program, size, 256, 256, reg);
+ for(j=0;j<8;j++){
+ int reg2 = ORC_GP_REG_BASE + j;
+ x86_emit_mov_reg_reg (program, size, reg, reg2);
+ x86_emit_mov_memoffset_reg (program, size, 0, reg, reg2);
+ x86_emit_mov_memoffset_reg (program, size, 1, reg, reg2);
+ x86_emit_mov_memoffset_reg (program, size, 256, reg, reg2);
+ x86_emit_mov_reg_memoffset (program, size, reg, 0, reg2);
+ x86_emit_mov_reg_memoffset (program, size, reg, 1, reg2);
+ x86_emit_mov_reg_memoffset (program, size, reg, 256, reg2);
+ }
+ }
+ }
+
+}
+
--- /dev/null
+
+#ifndef _ORC_X86_H_
+#define _ORC_X86_H_
+
+#include <unistd.h>
+
+extern int x86_64;
+extern int x86_exec_ptr;
+
+void x86_emit_push (OrcProgram *program, int size, int reg);
+void x86_emit_pop (OrcProgram *program, int size, int reg);
+void x86_emit_mov_memoffset_reg (OrcProgram *program, int size, int offset, int reg1, int reg2);
+void x86_emit_mov_memoffset_mmx (OrcProgram *program, int size, int offset,
+ int reg1, int reg2);
+void x86_emit_mov_memoffset_sse (OrcProgram *program, int size, int offset,
+ int reg1, int reg2);
+void x86_emit_mov_reg_memoffset (OrcProgram *program, int size, int reg1, int offset, int reg2);
+void x86_emit_mov_mmx_memoffset (OrcProgram *program, int size, int reg1, int offset,
+ int reg2);
+void x86_emit_mov_sse_memoffset (OrcProgram *program, int size, int reg1, int offset,
+ int reg2);
+void x86_emit_mov_imm_reg (OrcProgram *program, int size, int value, int reg1);
+void x86_emit_mov_reg_reg (OrcProgram *program, int size, int reg1, int reg2);
+void x86_emit_mov_reg_mmx (OrcProgram *program, int reg1, int reg2);
+void x86_emit_mov_mmx_reg (OrcProgram *program, int reg1, int reg2);
+void x86_emit_mov_reg_sse (OrcProgram *program, int reg1, int reg2);
+void x86_emit_mov_sse_reg (OrcProgram *program, int reg1, int reg2);
+void x86_emit_test_reg_reg (OrcProgram *program, int size, int reg1, int reg2);
+void x86_emit_sar_imm_reg (OrcProgram *program, int size, int value, int reg);
+void x86_emit_dec_memoffset (OrcProgram *program, int size, int offset, int reg);
+void x86_emit_add_imm_memoffset (OrcProgram *program, int size, int value, int offset, int reg);
+void x86_emit_and_imm_memoffset (OrcProgram *program, int size, int value, int offset, int reg);
+void x86_emit_add_imm_reg (OrcProgram *program, int size, int value, int reg);
+void x86_emit_and_imm_reg (OrcProgram *program, int size, int value, int reg);
+void x86_emit_cmp_imm_memoffset (OrcProgram *program, int size, int value,
+ int offset, int reg);
+void x86_emit_emms (OrcProgram *program);
+void x86_emit_ret (OrcProgram *program);
+void x86_emit_je (OrcProgram *program, int label);
+void x86_emit_jne (OrcProgram *program, int label);
+void x86_emit_label (OrcProgram *program, int label);
+
+void x86_emit_modrm_memoffset (OrcProgram *program, int reg1, int offset, int reg2);
+void x86_emit_modrm_reg (OrcProgram *program, int reg1, int reg2);
+void x86_test (OrcProgram *program);
+
+void mmx_emit_loadi_s16 (OrcProgram *p, int reg, int value);
+
+enum {
+ X86_EAX = ORC_GP_REG_BASE,
+ X86_ECX,
+ X86_EDX,
+ X86_EBX,
+ X86_ESP,
+ X86_EBP,
+ X86_ESI,
+ X86_EDI,
+ X86_R8,
+ X86_R9,
+ X86_R10,
+ X86_R11,
+ X86_R12,
+ X86_R13,
+ X86_R14,
+ X86_R15,
+ X86_MM0 = ORC_VEC1_REG_BASE,
+ X86_MM1,
+ X86_MM2,
+ X86_MM3,
+ X86_MM4,
+ X86_MM5,
+ X86_MM6,
+ X86_MM7,
+ X86_XMM0 = ORC_VEC2_REG_BASE,
+ X86_XMM1,
+ X86_XMM2,
+ X86_XMM3,
+ X86_XMM4,
+ X86_XMM5,
+ X86_XMM6,
+ X86_XMM7,
+ X86_XMM8,
+ X86_XMM9,
+ X86_XMM10,
+ X86_XMM11,
+ X86_XMM12,
+ X86_XMM13,
+ X86_XMM14,
+ X86_XMM15
+};
+
+const char * x86_get_regname(int i);
+int x86_get_regnum(int i);
+const char * x86_get_regname_16(int i);
+const char * x86_get_regname_64(int i);
+const char * x86_get_regname_ptr(int i);
+const char * x86_get_regname_mmx(int i);
+const char * x86_get_regname_sse(int i);
+
+#endif
+