[Liboil-commit] orc/Makefile.am orc/orc.c orc/orcprogram-c.c orc/orcprogram-x86.c orc/orcprogram.c orc/orcprogram.h orc/test.c

David Schleef ds at kemper.freedesktop.org
Tue May 20 22:42:18 PDT 2008


 orc/Makefile.am      |    1 
 orc/orc.c            |    1 
 orc/orcprogram-c.c   |  199 +++++++++++++++++++++++++++++++++++++++++++++++++++
 orc/orcprogram-x86.c |   56 +++++++-------
 orc/orcprogram.c     |    6 +
 orc/orcprogram.h     |    8 +-
 orc/test.c           |   21 +++++
 7 files changed, 263 insertions(+), 29 deletions(-)

New commits:
commit 4477508ae5af09e741f530abf0bf73ed8f396513
Author: David Schleef <ds at ginger.bigkitten.com>
Date:   Tue May 20 22:41:35 2008 -0700

    [orc] Fix some mmx instructions.  Add C backend

diff --git a/orc/Makefile.am b/orc/Makefile.am
index 6554224..9388c8b 100644
--- a/orc/Makefile.am
+++ b/orc/Makefile.am
@@ -12,6 +12,7 @@ liborc_ at LIBOIL_MAJORMINOR@_la_SOURCES = \
 	orcrule.c \
 	orctype.c \
 	orcprogram.c \
+	orcprogram-c.c \
 	orcprogram-x86.c \
 	orcprogram.h \
 	orcopcodes.c \
diff --git a/orc/orc.c b/orc/orc.c
index 1475505..a1dfce8 100644
--- a/orc/orc.c
+++ b/orc/orc.c
@@ -16,5 +16,6 @@ orc_init (void)
   oil_init ();
   orc_opcode_init();
   orc_x86_init();
+  orc_c_init();
 }
 
diff --git a/orc/orcprogram-c.c b/orc/orcprogram-c.c
new file mode 100644
index 0000000..a2bdd91
--- /dev/null
+++ b/orc/orcprogram-c.c
@@ -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-x86.c b/orc/orcprogram-x86.c
index a669bb3..abb8470 100644
--- a/orc/orcprogram-x86.c
+++ b/orc/orcprogram-x86.c
@@ -274,6 +274,9 @@ x86_emit_store_dest (OrcProgram *program, OrcVariable *var)
       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;
@@ -303,7 +306,7 @@ orc_program_assemble_x86 (OrcProgram *program)
   x86_emit_mov_memoffset_reg (program, 4, (int)G_STRUCT_OFFSET(OrcExecutor,n),
       X86_EBP, X86_ECX);
 
-  x86_emit_sar_imm_reg (program, 4, 2, X86_ECX);
+  x86_emit_sar_imm_reg (program, 4, program->loop_shift, X86_ECX);
   x86_emit_mov_reg_memoffset (program, 4, X86_ECX,
       (int)G_STRUCT_OFFSET(OrcExecutor,counter), X86_EBP);
 
@@ -658,19 +661,23 @@ mmx_rule_rshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
 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);
 
-  orc_rule_register ("add_s16", ORC_RULE_MMX_4, mmx_rule_add_s16, NULL,
-      ORC_RULE_REG_REG);
-  orc_rule_register ("sub_s16", ORC_RULE_MMX_4, mmx_rule_sub_s16, NULL,
-      ORC_RULE_REG_REG);
-  orc_rule_register ("mul_s16", ORC_RULE_MMX_4, mmx_rule_mul_s16, NULL,
-      ORC_RULE_REG_REG);
-  orc_rule_register ("lshift_s16", ORC_RULE_MMX_4, mmx_rule_lshift_s16, NULL,
-      ORC_RULE_REG_REG);
-  orc_rule_register ("rshift_s16", ORC_RULE_MMX_4, mmx_rule_rshift_s16, NULL,
-      ORC_RULE_REG_REG);
+  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);
+  }
 }
 
 /* code generation */
@@ -765,18 +772,17 @@ void
 x86_emit_mov_memoffset_mmx (OrcProgram *program, int size, int offset,
     int reg1, int reg2)
 {
-  /* FIXME */
   if (size == 4) {
     g_print("  movd %d(%%%s), %%%s\n", offset, x86_get_regname(reg1),
         x86_get_regname_mmx(reg2));
-    *program->codeptr++ = 0x66;
+    *program->codeptr++ = 0x0f;
+    *program->codeptr++ = 0x6e;
   } else {
     g_print("  movq %d(%%%s), %%%s\n", offset, x86_get_regname(reg1),
         x86_get_regname_mmx(reg2));
+    *program->codeptr++ = 0x0f;
+    *program->codeptr++ = 0x6f;
   }
-
-  *program->codeptr++ = 0x0f;
-  *program->codeptr++ = 0x6f;
   x86_emit_modrm_memoffset (program, reg2, offset, reg1);
 }
 
@@ -801,18 +807,18 @@ void
 x86_emit_mov_mmx_memoffset (OrcProgram *program, int size, int reg1, int offset,
     int reg2)
 {
-  /* FIXME */
   if (size == 4) {
     g_print("  movd %%%s, %d(%%%s)\n", x86_get_regname_mmx(reg1), offset,
         x86_get_regname(reg2));
-    *program->codeptr++ = 0x66;
+    *program->codeptr++ = 0x0f;
+    *program->codeptr++ = 0x7e;
   } else {
     g_print("  movq %%%s, %d(%%%s)\n", x86_get_regname_mmx(reg1), offset,
         x86_get_regname(reg2));
+    *program->codeptr++ = 0x0f;
+    *program->codeptr++ = 0x7f;
   }
 
-  *program->codeptr++ = 0x0f;
-  *program->codeptr++ = 0x7f;
   x86_emit_modrm_memoffset (program, reg1, offset, reg2);
 }
 
@@ -856,9 +862,9 @@ void x86_emit_mov_reg_mmx (OrcProgram *program, int reg1, int reg2)
   /* FIXME */
   g_print("  movd %%%s, %%%s\n", x86_get_regname(reg1),
       x86_get_regname_mmx(reg2));
-  *program->codeptr++ = 0x66;
-  *program->codeptr++ = 0x89;
-  x86_emit_modrm_reg (program, reg2, reg1);
+  *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)
@@ -866,8 +872,8 @@ void x86_emit_mov_mmx_reg (OrcProgram *program, int reg1, int reg2)
   /* FIXME */
   g_print("  movd %%%s, %%%s\n", x86_get_regname_mmx(reg1),
       x86_get_regname(reg2));
-  *program->codeptr++ = 0x66;
-  *program->codeptr++ = 0x89;
+  *program->codeptr++ = 0x0f;
+  *program->codeptr++ = 0x7e;
   x86_emit_modrm_reg (program, reg2, reg1);
 }
 
diff --git a/orc/orcprogram.c b/orc/orcprogram.c
index 37402dc..be1b591 100644
--- a/orc/orcprogram.c
+++ b/orc/orcprogram.c
@@ -22,8 +22,9 @@ orc_program_new (void)
   p = malloc(sizeof(OrcProgram));
   memset (p, 0, sizeof(OrcProgram));
 
-  p->rule_set = ORC_RULE_MMX_4;
-  p->n_per_loop = 4;
+  p->rule_set = ORC_RULE_MMX_1;
+  p->n_per_loop = 1;
+  p->loop_shift = 0;
 
   return p;
 }
@@ -176,6 +177,7 @@ orc_program_compile (OrcProgram *program)
 
   orc_program_allocate_codemem (program);
   orc_program_assemble_x86 (program);
+  //orc_program_assemble_c (program);
 
   orc_program_dump_code (program);
 }
diff --git a/orc/orcprogram.h b/orc/orcprogram.h
index e5cb83c..29a6a4f 100644
--- a/orc/orcprogram.h
+++ b/orc/orcprogram.h
@@ -2,7 +2,7 @@
 #ifndef _ORC_PROGRAM_H_
 #define _ORC_PROGRAM_H_
 
-#include <glib.h>
+//#include <glib.h>
 
 typedef struct _OrcType OrcType;
 typedef struct _OrcExecutor OrcExecutor;
@@ -24,7 +24,8 @@ typedef void (*OrcRuleEmitFunc)(OrcProgram *p, void *user, OrcInstruction *insn)
 #define ORC_OPCODE_N_RULES 8
 
 enum {
-  ORC_RULE_SCALAR_1 = 0,
+  ORC_RULE_C = 0,
+  ORC_RULE_SCALAR_1,
   ORC_RULE_SCALAR_2,
   ORC_RULE_MMX_1,
   ORC_RULE_MMX_2,
@@ -146,6 +147,7 @@ struct _OrcProgram {
   int used_regs[ORC_N_REGS];
   int alloc_regs[ORC_N_REGS];
 
+  int loop_shift;
   int n_per_loop;
 };
 
@@ -182,9 +184,11 @@ void orc_opcode_init (void);
 void orc_program_append (OrcProgram *p, const char *opcode, int arg0, int arg1, int arg2);
 
 void orc_x86_init (void);
+void orc_c_init (void);
 
 void orc_program_compile (OrcProgram *p);
 void orc_program_assemble_x86 (OrcProgram *p);
+void orc_program_assemble_c (OrcProgram *p);
 void orc_program_free (OrcProgram *program);
 
 int orc_program_add_temporary (OrcProgram *program, const char *type, const char *name);
diff --git a/orc/test.c b/orc/test.c
new file mode 100644
index 0000000..bff0df2
--- /dev/null
+++ b/orc/test.c
@@ -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;
+  }
+}
+


More information about the Liboil-commit mailing list