arm: Implement 2d support
authorDavid Schleef <ds@schleef.org>
Thu, 1 Jul 2010 02:33:39 +0000 (19:33 -0700)
committerDavid Schleef <ds@schleef.org>
Thu, 1 Jul 2010 02:33:39 +0000 (19:33 -0700)
orc/orcprogram-arm.c

index 8d199e0..21652a3 100644 (file)
@@ -24,6 +24,7 @@ void orc_compiler_orc_arm_assemble (OrcCompiler *compiler);
 
 void orc_compiler_rewrite_vars (OrcCompiler *compiler);
 void orc_compiler_dump (OrcCompiler *compiler);
+void arm_add_strides (OrcCompiler *compiler);
 
 void
 orc_arm_emit_prologue (OrcCompiler *compiler)
@@ -139,7 +140,7 @@ orc_compiler_orc_arm_init (OrcCompiler *compiler)
 }
 
 void
-orc_arm_load_constants (OrcCompiler *compiler)
+orc_arm_load_constants_outer (OrcCompiler *compiler)
 {
   int i;
   for(i=0;i<ORC_N_VARIABLES;i++){
@@ -150,9 +151,31 @@ orc_arm_load_constants (OrcCompiler *compiler)
             (int)compiler->vars[i].value);
         break;
       case ORC_VAR_TYPE_PARAM:
-        orc_arm_loadw (compiler, compiler->vars[i].alloc,
-            compiler->exec_reg,
-            (int)ORC_STRUCT_OFFSET(OrcExecutor, params[i]));
+        ORC_PROGRAM_ERROR(compiler,"unimplemented");
+        return;
+        /* FIXME offset is too large */
+        //orc_arm_loadw (compiler, compiler->vars[i].alloc,
+        //    compiler->exec_reg,
+        //    (int)ORC_STRUCT_OFFSET(OrcExecutor, params[i]));
+        break;
+      case ORC_VAR_TYPE_SRC:
+      case ORC_VAR_TYPE_DEST:
+        break;
+      default:
+        break;
+    }
+  }
+}
+
+void
+orc_arm_load_constants_inner (OrcCompiler *compiler)
+{
+  int i;
+  for(i=0;i<ORC_N_VARIABLES;i++){
+    if (compiler->vars[i].name == NULL) continue;
+    switch (compiler->vars[i].vartype) {
+      case ORC_VAR_TYPE_CONST:
+      case ORC_VAR_TYPE_PARAM:
         break;
       case ORC_VAR_TYPE_SRC:
       case ORC_VAR_TYPE_DEST:
@@ -255,9 +278,27 @@ orc_compiler_orc_arm_assemble (OrcCompiler *compiler)
 
   orc_arm_emit_prologue (compiler);
 
+  orc_arm_load_constants_outer (compiler);
+
+  if (compiler->program->is_2d) {
+    if (compiler->program->constant_m > 0) {
+      orc_arm_emit_load_imm (compiler, ORC_ARM_A3, compiler->program->constant_m
+);    
+      orc_arm_emit_store_reg (compiler, ORC_ARM_A3, compiler->exec_reg,
+          (int)ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_A2]));
+    } else {
+      orc_arm_emit_load_reg (compiler, ORC_ARM_A3, compiler->exec_reg,
+          (int)ORC_STRUCT_OFFSET(OrcExecutor, params[ORC_VAR_A1]));
+      orc_arm_emit_store_reg (compiler, ORC_ARM_A3, compiler->exec_reg,
+          (int)ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_A2]));
+    }
+    
+    orc_arm_emit_label (compiler, 8);
+  }
+
   orc_arm_emit_load_reg (compiler, ORC_ARM_IP, compiler->exec_reg,
       (int)ORC_STRUCT_OFFSET(OrcExecutor,n));
-  orc_arm_load_constants (compiler);
+  orc_arm_load_constants_inner (compiler);
 
   orc_arm_emit_label (compiler, 1);
 
@@ -271,6 +312,18 @@ orc_compiler_orc_arm_assemble (OrcCompiler *compiler)
   orc_arm_emit_branch (compiler, ORC_ARM_COND_NE, 2);
   orc_arm_emit_label (compiler, 3);
 
+  if (compiler->program->is_2d) {
+    neon_add_strides (compiler);
+
+    orc_arm_emit_load_reg (compiler, ORC_ARM_A3, compiler->exec_reg,
+        (int)ORC_STRUCT_OFFSET(OrcExecutor, params[ORC_VAR_A2]));
+    orc_arm_emit_sub_imm (compiler, ORC_ARM_A3, ORC_ARM_A3, 1);
+    orc_arm_emit_store_reg (compiler, ORC_ARM_A3, compiler->exec_reg,
+        (int)ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_A2]));
+    orc_arm_emit_cmp_imm (compiler, ORC_ARM_A3, 0);
+    orc_arm_emit_branch (compiler, ORC_ARM_COND_NE, 8);
+  }
+
   orc_arm_emit_epilogue (compiler);
 
   orc_arm_do_fixups (compiler);
@@ -308,6 +361,7 @@ orc_arm_emit_loop (OrcCompiler *compiler)
 
       switch (compiler->vars[insn->src_args[k]].vartype) {
         case ORC_VAR_TYPE_SRC:
+        case ORC_VAR_TYPE_DEST:
           orc_arm_emit_load_src (compiler, &compiler->vars[insn->src_args[k]]);
           break;
         case ORC_VAR_TYPE_CONST:
@@ -368,3 +422,36 @@ orc_arm_emit_loop (OrcCompiler *compiler)
   }
 }
 
+void
+arm_add_strides (OrcCompiler *compiler)
+{
+  int i;
+
+  for(i=0;i<ORC_N_VARIABLES;i++){
+    if (compiler->vars[i].name == NULL) continue;
+    switch (compiler->vars[i].vartype) {
+      case ORC_VAR_TYPE_CONST:
+        break;
+      case ORC_VAR_TYPE_PARAM:
+        break;
+      case ORC_VAR_TYPE_SRC:
+      case ORC_VAR_TYPE_DEST:
+        orc_arm_emit_load_reg (compiler, ORC_ARM_A3, compiler->exec_reg,
+            (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[i]));
+        orc_arm_emit_load_reg (compiler, ORC_ARM_A2, compiler->exec_reg,
+            (int)ORC_STRUCT_OFFSET(OrcExecutor, params[i]));
+        orc_arm_emit_add (compiler, ORC_ARM_A3, ORC_ARM_A3, ORC_ARM_A2);
+        orc_arm_emit_store_reg (compiler, ORC_ARM_A3, compiler->exec_reg,
+            (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[i]));
+        break;
+      case ORC_VAR_TYPE_ACCUMULATOR:
+        break;
+      case ORC_VAR_TYPE_TEMP:
+        break;
+      default:
+        ORC_COMPILER_ERROR(compiler,"bad vartype");
+        break;
+    }
+  }
+}
+