arm: Add load/store opcodes
authorDavid Schleef <ds@schleef.org>
Tue, 3 Aug 2010 00:59:54 +0000 (17:59 -0700)
committerDavid Schleef <ds@schleef.org>
Tue, 3 Aug 2010 00:59:54 +0000 (17:59 -0700)
orc/orcprogram-arm.c
orc/orcrules-arm.c

index 6518a54..3f5054a 100644 (file)
@@ -97,6 +97,10 @@ static OrcTarget orc_arm_target = {
 void
 orc_arm_init (void)
 {
+#if defined(HAVE_ARM)
+  orc_arm_get_cpu_flags ();
+#endif
+
   orc_target_register (&orc_arm_target);
 
   orc_compiler_orc_arm_register_rules (&orc_arm_target);
@@ -105,7 +109,11 @@ orc_arm_init (void)
 unsigned int
 orc_compiler_orc_arm_get_default_flags (void)
 {
-  return 0;
+#if defined(HAVE_ARM)
+  return orc_arm_get_cpu_flags ();
+#else
+  return ORC_TARGET_ARM_EDSP;
+#endif
 }
 
 void
@@ -147,8 +155,8 @@ orc_arm_load_constants_outer (OrcCompiler *compiler)
     if (compiler->vars[i].name == NULL) continue;
     switch (compiler->vars[i].vartype) {
       case ORC_VAR_TYPE_CONST:
-        orc_arm_emit_load_imm (compiler, compiler->vars[i].alloc,
-            (int)compiler->vars[i].value);
+        //orc_arm_emit_load_imm (compiler, compiler->vars[i].alloc,
+        //    (int)compiler->vars[i].value);
         break;
       case ORC_VAR_TYPE_PARAM:
         ORC_PROGRAM_ERROR(compiler,"unimplemented");
@@ -165,6 +173,23 @@ orc_arm_load_constants_outer (OrcCompiler *compiler)
         break;
     }
   }
+
+  for(i=0;i<compiler->n_insns;i++){
+    OrcInstruction *insn = compiler->insns + i;
+    OrcStaticOpcode *opcode = insn->opcode;
+    OrcRule *rule;
+
+    if (!(compiler->insn_flags[i] & ORC_INSN_FLAG_INVARIANT)) continue;
+
+    ORC_ASM_CODE(compiler,"# %d: %s\n", i, insn->opcode->name);
+
+    rule = insn->rule;
+    if (rule && rule->emit) {
+      rule->emit (compiler, rule->emit_user, insn);
+    } else {
+      ORC_COMPILER_ERROR(compiler,"No rule for: %s", opcode->name);
+    }
+  }
 }
 
 void
@@ -189,6 +214,7 @@ orc_arm_load_constants_inner (OrcCompiler *compiler)
   }
 }
 
+#if 0
 void
 orc_arm_emit_load_src (OrcCompiler *compiler, OrcVariable *var)
 {
@@ -268,6 +294,7 @@ orc_arm_emit_store_dest (OrcCompiler *compiler, OrcVariable *var)
       ORC_COMPILER_ERROR(compiler, "bad size %d", var->size << compiler->loop_shift);
   }
 }
+#endif
 
 void
 orc_compiler_orc_arm_assemble (OrcCompiler *compiler)
@@ -341,6 +368,8 @@ orc_arm_emit_loop (OrcCompiler *compiler)
     insn = compiler->insns + j;
     opcode = insn->opcode;
 
+    if (compiler->insn_flags[j] & ORC_INSN_FLAG_INVARIANT) continue;
+
     orc_compiler_append_code(compiler,"# %d: %s", j, insn->opcode->name);
 
     /* set up args */
@@ -361,7 +390,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]]);
+          //orc_arm_emit_load_src (compiler, &compiler->vars[insn->src_args[k]]);
           break;
         case ORC_VAR_TYPE_CONST:
           break;
@@ -392,7 +421,7 @@ orc_arm_emit_loop (OrcCompiler *compiler)
 
       switch (compiler->vars[insn->dest_args[k]].vartype) {
         case ORC_VAR_TYPE_DEST:
-          orc_arm_emit_store_dest (compiler, &compiler->vars[insn->dest_args[k]]);
+          //orc_arm_emit_store_dest (compiler, &compiler->vars[insn->dest_args[k]]);
           break;
         case ORC_VAR_TYPE_TEMP:
           break;
index 53b335c..fcc8353 100644 (file)
@@ -78,6 +78,87 @@ arm_rule_ ## opcode (OrcCompiler *p, void *user, OrcInstruction *insn) \
   orc_arm_emit(p,orc_arm_mull (0x00800090,cond,S,RdL,RdH,Rn,Rm)); \
 } while (0)
 
+static void
+arm_rule_loadpX (OrcCompiler *compiler, void *user, OrcInstruction *insn)
+{
+  if (compiler->vars[insn->src_args[0]].vartype == ORC_VAR_TYPE_CONST) {
+    orc_arm_emit_load_imm (compiler, compiler->vars[insn->dest_args[0]].alloc,
+        (int)compiler->vars[insn->src_args[0]].value);
+  } else {
+    orc_arm_loadw (compiler, compiler->vars[insn->dest_args[0]].alloc,
+        compiler->exec_reg,
+        (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->src_args[0]]));
+  }
+}
+
+static void
+arm_rule_loadX (OrcCompiler *compiler, void *user, OrcInstruction *insn)
+{
+  int src = compiler->vars[insn->src_args[0]].ptr_register;
+  int dest = compiler->vars[insn->dest_args[0]].alloc;
+  int size;
+  orc_uint32 code;
+  int offset = 0;
+
+  size = (compiler->vars[insn->src_args[0]].size << compiler->loop_shift);
+
+  if (size == 4) {
+    code = 0xe5900000;
+    ORC_ASM_CODE(compiler,"  ldr %s, [%s, #%d]\n",
+        orc_arm_reg_name (dest),
+        orc_arm_reg_name (src), offset);
+  } else if (size == 2) {
+    code = 0xe1d000b0;
+    ORC_ASM_CODE(compiler,"  ldrh %s, [%s, #%d]\n",
+        orc_arm_reg_name (dest),
+        orc_arm_reg_name (src), offset);
+  } else {
+    code = 0xe5d00000;
+    ORC_ASM_CODE(compiler,"  ldrb %s, [%s, #%d]\n",
+        orc_arm_reg_name (dest),
+        orc_arm_reg_name (src), offset);
+  }
+  code |= (src&0xf) << 16;
+  code |= (dest&0xf) << 12;
+  code |= (offset&0xf0) << 4;
+  code |= offset&0x0f;
+  orc_arm_emit (compiler, code);
+}
+
+static void
+arm_rule_storeX (OrcCompiler *compiler, void *user, OrcInstruction *insn)
+{
+  int src = compiler->vars[insn->src_args[0]].alloc;
+  int dest = compiler->vars[insn->dest_args[0]].ptr_register;
+  int size;
+  orc_uint32 code;
+  int offset = 0;
+
+  size = (compiler->vars[insn->src_args[0]].size << compiler->loop_shift);
+
+  if (size == 4) {
+    code = 0xe5800000;
+    ORC_ASM_CODE(compiler,"  str %s, [%s, #%d]\n",
+        orc_arm_reg_name (src),
+        orc_arm_reg_name (dest), offset);
+  } else if (size == 2) {
+    code = 0xe1c000b0;
+    ORC_ASM_CODE(compiler,"  strh %s, [%s, #%d]\n",
+        orc_arm_reg_name (src),
+        orc_arm_reg_name (dest), offset);
+  } else {
+    code = 0xe5c00000;
+    ORC_ASM_CODE(compiler,"  strb %s, [%s, #%d]\n",
+        orc_arm_reg_name (src),
+        orc_arm_reg_name (dest), offset);
+  }
+  code |= (dest&0xf) << 16;
+  code |= (src&0xf) << 12;
+  code |= (offset&0xf0) << 4;
+  code |= offset&0x0f;
+  orc_arm_emit (compiler, code);
+}
+
 void
 orc_arm_loadb (OrcCompiler *compiler, int dest, int src1, int offset)
 {
@@ -1499,6 +1580,16 @@ orc_compiler_orc_arm_register_rules (OrcTarget *target)
 
   rule_set = orc_rule_set_new (orc_opcode_set_get("sys"), target, 0);
 
+  orc_rule_register (rule_set, "loadpb", arm_rule_loadpX, NULL);
+  orc_rule_register (rule_set, "loadpw", arm_rule_loadpX, NULL);
+  orc_rule_register (rule_set, "loadpl", arm_rule_loadpX, NULL);
+  orc_rule_register (rule_set, "loadb", arm_rule_loadX, NULL);
+  orc_rule_register (rule_set, "loadw", arm_rule_loadX, NULL);
+  orc_rule_register (rule_set, "loadl", arm_rule_loadX, NULL);
+  orc_rule_register (rule_set, "storeb", arm_rule_storeX, NULL);
+  orc_rule_register (rule_set, "storew", arm_rule_storeX, NULL);
+  orc_rule_register (rule_set, "storel", arm_rule_storeX, NULL);
+
   orc_rule_register (rule_set, "andb", arm_rule_andX, NULL);
   orc_rule_register (rule_set, "andnb", arm_rule_andnX, NULL);
   orc_rule_register (rule_set, "avgsb", arm_rule_avgX, (void *)3);
@@ -1550,7 +1641,7 @@ orc_compiler_orc_arm_register_rules (OrcTarget *target)
   FAIL orc_rule_register (rule_set, "muluwl", arm_rule_muluwl, NULL);
 
   rule_set = orc_rule_set_new (orc_opcode_set_get("sys"), target,
-      ORC_TARGET_ARM_ARMV6);
+      ORC_TARGET_ARM_EDSP);
 
   FAIL orc_rule_register (rule_set, "absb", arm_rule_absX, (void *)0);
   orc_rule_register (rule_set, "addb", arm_rule_addb, NULL);