Initial commit. Previous history is in liboil
authorDavid Schleef <ds@ginger.bigkitten.com>
Sat, 7 Jun 2008 22:00:28 +0000 (15:00 -0700)
committerDavid Schleef <ds@ginger.bigkitten.com>
Sat, 7 Jun 2008 22:00:28 +0000 (15:00 -0700)
37 files changed:
Makefile.am [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
configure.ac [new file with mode: 0644]
doc/Makefile.am [new file with mode: 0644]
examples/Makefile.am [new file with mode: 0644]
examples/jit.c [new file with mode: 0644]
examples/simple.c [new file with mode: 0644]
gtk-doc.make [new file with mode: 0644]
m4/ac_libtool_tags.m4 [new file with mode: 0644]
m4/as-compiler-flag.m4 [new file with mode: 0644]
m4/as-host-defines.m4 [new file with mode: 0644]
m4/as-libtool.m4 [new file with mode: 0644]
m4/as-nano.m4 [new file with mode: 0644]
m4/ax_create_stdint_h.m4 [new file with mode: 0644]
orc-uninstalled.pc.in [new file with mode: 0644]
orc.pc.in [new file with mode: 0644]
orc/Makefile.am [new file with mode: 0644]
orc/orc-stdint.h [new file with mode: 0644]
orc/orc.c [new file with mode: 0644]
orc/orc.h [new file with mode: 0644]
orc/orcexecutor.c [new file with mode: 0644]
orc/orcopcodes.c [new file with mode: 0644]
orc/orcprogram-c.c [new file with mode: 0644]
orc/orcprogram-linux.c [new file with mode: 0644]
orc/orcprogram-powerpc.c [new file with mode: 0644]
orc/orcprogram-x86.c [new file with mode: 0644]
orc/orcprogram.c [new file with mode: 0644]
orc/orcprogram.h [new file with mode: 0644]
orc/orcrule.c [new file with mode: 0644]
orc/orcrules-mmx.c [new file with mode: 0644]
orc/orcrules-sse.c [new file with mode: 0644]
orc/orcrules-x86.c [new file with mode: 0644]
orc/orctype.c [new file with mode: 0644]
orc/test.c [new file with mode: 0644]
orc/x86.c [new file with mode: 0644]
orc/x86.h [new file with mode: 0644]
testsuite/Makefile.am [new file with mode: 0644]

diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..708428b
--- /dev/null
@@ -0,0 +1,23 @@
+
+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
+
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..ef72852
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+autoreconf -i -f &&
+./configure --enable-maintainer-mode --disable-static --enable-gtk-doc $@
+
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..e96c25e
--- /dev/null
@@ -0,0 +1,142 @@
+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
+
+
+
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644 (file)
index 0000000..e071059
--- /dev/null
@@ -0,0 +1,74 @@
+## 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/
+
diff --git a/examples/Makefile.am b/examples/Makefile.am
new file mode 100644 (file)
index 0000000..9023579
--- /dev/null
@@ -0,0 +1,10 @@
+
+noinst_PROGRAMS = jit simple
+
+AM_LDFLAGS = $(ORC_LIBS) $(GLIB_LIBS)
+AM_CFLAGS = $(ORC_CFLAGS) $(GLIB_CFLAGS)
+
+jit_SOURCES = jit.c
+
+simple_SOURCES = simple.c
+
diff --git a/examples/jit.c b/examples/jit.c
new file mode 100644 (file)
index 0000000..52cd1be
--- /dev/null
@@ -0,0 +1,97 @@
+
+#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;
+  }
+}
+
diff --git a/examples/simple.c b/examples/simple.c
new file mode 100644 (file)
index 0000000..388475c
--- /dev/null
@@ -0,0 +1,144 @@
+
+#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);
+}
+
+
diff --git a/gtk-doc.make b/gtk-doc.make
new file mode 100644 (file)
index 0000000..354ffb7
--- /dev/null
@@ -0,0 +1,173 @@
+# -*- 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
diff --git a/m4/ac_libtool_tags.m4 b/m4/ac_libtool_tags.m4
new file mode 100644 (file)
index 0000000..d0ddb2e
--- /dev/null
@@ -0,0 +1,57 @@
+
+# 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
+])
+
diff --git a/m4/as-compiler-flag.m4 b/m4/as-compiler-flag.m4
new file mode 100644 (file)
index 0000000..ebb2853
--- /dev/null
@@ -0,0 +1,33 @@
+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])
+])
+
diff --git a/m4/as-host-defines.m4 b/m4/as-host-defines.m4
new file mode 100644 (file)
index 0000000..8b813bb
--- /dev/null
@@ -0,0 +1,52 @@
+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")
+
+])
+
diff --git a/m4/as-libtool.m4 b/m4/as-libtool.m4
new file mode 100644 (file)
index 0000000..135f3f8
--- /dev/null
@@ -0,0 +1,39 @@
+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
+])
diff --git a/m4/as-nano.m4 b/m4/as-nano.m4
new file mode 100644 (file)
index 0000000..119666c
--- /dev/null
@@ -0,0 +1,27 @@
+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
+])
diff --git a/m4/ax_create_stdint_h.m4 b/m4/ax_create_stdint_h.m4
new file mode 100644 (file)
index 0000000..13bf699
--- /dev/null
@@ -0,0 +1,734 @@
+##### 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"
+])
+])
diff --git a/orc-uninstalled.pc.in b/orc-uninstalled.pc.in
new file mode 100644 (file)
index 0000000..00e6bad
--- /dev/null
@@ -0,0 +1,10 @@
+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}
diff --git a/orc.pc.in b/orc.pc.in
new file mode 100644 (file)
index 0000000..2347be7
--- /dev/null
+++ b/orc.pc.in
@@ -0,0 +1,14 @@
+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}
+
+
diff --git a/orc/Makefile.am b/orc/Makefile.am
new file mode 100644 (file)
index 0000000..220ea0d
--- /dev/null
@@ -0,0 +1,30 @@
+
+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
+
diff --git a/orc/orc-stdint.h b/orc/orc-stdint.h
new file mode 100644 (file)
index 0000000..58d9d8a
--- /dev/null
@@ -0,0 +1,9 @@
+#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
diff --git a/orc/orc.c b/orc/orc.c
new file mode 100644 (file)
index 0000000..d987ad0
--- /dev/null
+++ b/orc/orc.c
@@ -0,0 +1,19 @@
+
+#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();
+}
+
diff --git a/orc/orc.h b/orc/orc.h
new file mode 100644 (file)
index 0000000..ec27285
--- /dev/null
+++ b/orc/orc.h
@@ -0,0 +1,8 @@
+
+#ifndef _ORC_ORC_H_
+#define _ORC_ORC_H_
+
+#include <orc/orcprogram.h>
+
+#endif
+
diff --git a/orc/orcexecutor.c b/orc/orcexecutor.c
new file mode 100644 (file)
index 0000000..8c221ff
--- /dev/null
@@ -0,0 +1,112 @@
+
+#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;
+        }
+      }
+    }
+  }
+}
+
+
diff --git a/orc/orcopcodes.c b/orc/orcopcodes.c
new file mode 100644 (file)
index 0000000..1ec3ea7
--- /dev/null
@@ -0,0 +1,101 @@
+
+#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);
+}
+
+
diff --git a/orc/orcprogram-c.c b/orc/orcprogram-c.c
new file mode 100644 (file)
index 0000000..a2bdd91
--- /dev/null
@@ -0,0 +1,199 @@
+
+#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);
+}
+
diff --git a/orc/orcprogram-linux.c b/orc/orcprogram-linux.c
new file mode 100644 (file)
index 0000000..d590046
--- /dev/null
@@ -0,0 +1,54 @@
+
+#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;
+}
+
diff --git a/orc/orcprogram-powerpc.c b/orc/orcprogram-powerpc.c
new file mode 100644 (file)
index 0000000..bfb3a28
--- /dev/null
@@ -0,0 +1,737 @@
+
+#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);
+}
+
diff --git a/orc/orcprogram-x86.c b/orc/orcprogram-x86.c
new file mode 100644 (file)
index 0000000..9f87195
--- /dev/null
@@ -0,0 +1,449 @@
+
+#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);
+      }
+    }
+  }
+}
+
diff --git a/orc/orcprogram.c b/orc/orcprogram.c
new file mode 100644 (file)
index 0000000..9a1b9c9
--- /dev/null
@@ -0,0 +1,516 @@
+
+#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;
+}
+
diff --git a/orc/orcprogram.h b/orc/orcprogram.h
new file mode 100644 (file)
index 0000000..3281f0e
--- /dev/null
@@ -0,0 +1,273 @@
+
+#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
+
diff --git a/orc/orcrule.c b/orc/orcrule.c
new file mode 100644 (file)
index 0000000..1919e76
--- /dev/null
@@ -0,0 +1,23 @@
+
+#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;
+}
+
diff --git a/orc/orcrules-mmx.c b/orc/orcrules-mmx.c
new file mode 100644 (file)
index 0000000..1998483
--- /dev/null
@@ -0,0 +1,167 @@
+
+#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);
+  }
+}
+
diff --git a/orc/orcrules-sse.c b/orc/orcrules-sse.c
new file mode 100644 (file)
index 0000000..9f559e0
--- /dev/null
@@ -0,0 +1,172 @@
+
+#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);
+  }
+}
+
diff --git a/orc/orcrules-x86.c b/orc/orcrules-x86.c
new file mode 100644 (file)
index 0000000..4becb48
--- /dev/null
@@ -0,0 +1,146 @@
+
+#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);
+}
+
diff --git a/orc/orctype.c b/orc/orctype.c
new file mode 100644 (file)
index 0000000..fbbe5ca
--- /dev/null
@@ -0,0 +1,44 @@
+
+#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++;
+}
+
+
+
diff --git a/orc/test.c b/orc/test.c
new file mode 100644 (file)
index 0000000..bff0df2
--- /dev/null
@@ -0,0 +1,21 @@
+
+#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;
+  }
+}
+
diff --git a/orc/x86.c b/orc/x86.c
new file mode 100644 (file)
index 0000000..55de4b3
--- /dev/null
+++ b/orc/x86.c
@@ -0,0 +1,750 @@
+
+#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);
+      }
+    }
+  }
+
+}
+
diff --git a/orc/x86.h b/orc/x86.h
new file mode 100644 (file)
index 0000000..dc47b11
--- /dev/null
+++ b/orc/x86.h
@@ -0,0 +1,101 @@
+
+#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
+
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
new file mode 100644 (file)
index 0000000..e69de29