arm: add arm code from neon branch
authorDavid Schleef <ds@schleef.org>
Sun, 20 Sep 2009 05:50:19 +0000 (22:50 -0700)
committerDavid Schleef <ds@schleef.org>
Sun, 20 Sep 2009 05:50:19 +0000 (22:50 -0700)
orc/orcarm.c
orc/orcarm.h

index 7ef3494..6cc09fc 100644 (file)
@@ -142,9 +142,28 @@ orc_arm_do_fixups (OrcCompiler *compiler)
     uint32_t code;
     int diff;
 
-    code = ORC_READ_UINT32_LE (ptr);
-    diff = ORC_READ_UINT32_LE (ptr) + ((label - ptr) >> 2);
-    ORC_WRITE_UINT32_LE(ptr, (code&0xff000000) | (diff&0x00ffffff));
+    if (compiler->fixups[i].type == 0) {
+      code = ORC_READ_UINT32_LE (ptr);
+      diff = ORC_READ_UINT32_LE (ptr) + ((label - ptr) >> 2);
+      ORC_WRITE_UINT32_LE(ptr, (code&0xff000000) | (diff&0x00ffffff));
+    } else {
+      code = ORC_READ_UINT32_LE (ptr);
+      diff = (code&0xff) + ((label - ptr) >> 2);
+      ORC_WRITE_UINT32_LE(ptr, (code&0xffffff00) | (diff&0x000000ff));
+    }
+  }
+}
+
+void
+orc_arm_emit_align (OrcCompiler *compiler, int align_shift)
+{
+  int diff;
+
+  diff = (compiler->program->code - compiler->codeptr)&((1<<align_shift) - 1);
+  while (diff) {
+    ORC_ASM_CODE(compiler,"  nop\n");
+    orc_arm_emit (compiler, 0xe1a00000);
+    diff-=4;
   }
 }
 
@@ -166,19 +185,134 @@ orc_arm_emit_load_imm (OrcCompiler *compiler, int dest, int imm)
 {
   uint32_t code;
   int shift2;
+  unsigned int x;
 
-  shift2 = 0;
-  while (imm && ((imm&3)==0)) {
-    imm >>= 2;
-    shift2++;
+  if ((imm & 0xff) == imm) {
+    shift2 = 0;
+    x = imm;
+  } else {
+    shift2 = 0;
+    x = imm & 0xffffffff;
+    while ((x & 3) == 0) {
+      x >>= 2;
+      shift2++;
+    }
+    if (x > 0xff) {
+      ORC_PROGRAM_ERROR(compiler, "bad immediate value");
+    }
   }
 
   code = 0xe3a00000;
   code |= (dest&0xf) << 12;
   code |= (((16-shift2)&0xf) << 8);
-  code |= (imm&0xff);
+  code |= (x&0xff);
+
+  ORC_ASM_CODE(compiler,"  mov %s, #0x%08x\n", orc_arm_reg_name (dest), imm);
+  orc_arm_emit (compiler, code);
+}
+
+void
+orc_arm_emit_add_imm (OrcCompiler *compiler, int dest, int src1, int imm)
+{
+  uint32_t code;
+  int shift2;
+  unsigned int x;
+
+  if ((imm & 0xff) == imm) {
+    shift2 = 0;
+    x = imm;
+  } else {
+    shift2 = 0;
+    x = imm & 0xffffffff;
+    while ((x & 3) == 0) {
+      x >>= 2;
+      shift2++;
+    }
+    if (x > 0xff) {
+      ORC_PROGRAM_ERROR(compiler, "bad immediate value");
+    }
+  }
+
+  code = 0xe2800000;
+  code |= (src1&0xf) << 16;
+  code |= (dest&0xf) << 12;
+  code |= (((16-shift2)&0xf) << 8);
+  code |= (x&0xff);
+
+  ORC_ASM_CODE(compiler,"  add %s, %s, #0x%08x\n", orc_arm_reg_name (dest),
+      orc_arm_reg_name(src1), imm);
+  orc_arm_emit (compiler, code);
+}
+
+void
+orc_arm_emit_and_imm (OrcCompiler *compiler, int dest, int src1, int value)
+{
+  uint32_t code;
+
+  code = 0xe2000000;
+  code |= (src1&0xf) << 16;
+  code |= (dest&0xf) << 12;
+  code |= (value) << 0;
+
+  ORC_ASM_CODE(compiler,"  and %s, %s, #%d\n",
+      orc_arm_reg_name (dest),
+      orc_arm_reg_name (src1),
+      value);
+  orc_arm_emit (compiler, code);
+}
+
+void
+orc_arm_emit_cmp (OrcCompiler *compiler, int src1, int src2)
+{
+  uint32_t code;
+
+  code = 0xe1500000;
+  code |= (src1&0xf) << 16;
+  code |= (src2&0xf) << 0;
+
+  ORC_ASM_CODE(compiler,"  cmp %s, %s\n",
+      orc_arm_reg_name (src1),
+      orc_arm_reg_name (src2));
+  orc_arm_emit (compiler, code);
+}
+
+void
+orc_arm_emit_asr_imm (OrcCompiler *compiler, int dest, int src1, int value)
+{
+  uint32_t code;
+
+  if (value == 0) {
+    ORC_ERROR("bad immediate value");
+  }
+  code = 0xe1a00040;
+  code |= (src1&0xf) << 0;
+  code |= (dest&0xf) << 12;
+  code |= (value) << 7;
+
+  ORC_ASM_CODE(compiler,"  asr %s, %s, #%d\n",
+      orc_arm_reg_name (dest),
+      orc_arm_reg_name (src1),
+      value);
+  orc_arm_emit (compiler, code);
+}
+
+void
+orc_arm_emit_lsl_imm (OrcCompiler *compiler, int dest, int src1, int value)
+{
+  uint32_t code;
 
-  ORC_ASM_CODE(compiler,"  mov %s, #0x%08x\n", orc_arm_reg_name (dest), imm << (shift2*2));
+  if (value == 0) {
+    ORC_ERROR("bad immediate value");
+  }
+  code = 0xe1a00000;
+  code |= (src1&0xf) << 0;
+  code |= (dest&0xf) << 12;
+  code |= (value) << 7;
+
+  ORC_ASM_CODE(compiler,"  lsl %s, %s, #%d\n",
+      orc_arm_reg_name (dest),
+      orc_arm_reg_name (src1),
+      value);
   orc_arm_emit (compiler, code);
 }
 
@@ -198,6 +332,23 @@ orc_arm_emit_load_reg (OrcCompiler *compiler, int dest, int src1, int offset)
   orc_arm_emit (compiler, code);
 }
 
+void
+orc_arm_emit_store_reg (OrcCompiler *compiler, int src1, int dest, int offset)
+{
+  uint32_t code;
+
+  code = 0xe5800000;
+  code |= (dest&0xf) << 16;
+  code |= (src1&0xf) << 12;
+  code |= offset&0xfff;
+
+  ORC_ASM_CODE(compiler,"  str %s, [%s, #%d]\n",
+      orc_arm_reg_name (src1),
+      orc_arm_reg_name (dest), offset);
+  orc_arm_emit (compiler, code);
+}
+
+
 /* shifter operands */
 /*    1
  *  1 0 9 8 7 6 5 4 3 2 1 0
index c0225f1..b093a68 100644 (file)
@@ -74,6 +74,16 @@ const char * orc_arm_reg_name (int reg);
 const char * orc_arm_cond_name (OrcArmCond cond);
 void orc_arm_emit_load_imm (OrcCompiler *compiler, int dest, int imm);
 
+void orc_arm_emit_add (OrcCompiler *compiler, int dest, int src1, int src2);
+void orc_arm_emit_sub (OrcCompiler *compiler, int dest, int src1, int src2);
+void orc_arm_emit_add_imm (OrcCompiler *compiler, int dest, int src1, int value);
+void orc_arm_emit_and_imm (OrcCompiler *compiler, int dest, int src1, int value);
+void orc_arm_emit_sub_imm (OrcCompiler *compiler, int dest, int src1, int value);
+void orc_arm_emit_asr_imm (OrcCompiler *compiler, int dest, int src1, int value);
+void orc_arm_emit_lsl_imm (OrcCompiler *compiler, int dest, int src1, int value);
+void orc_arm_emit_cmp_imm (OrcCompiler *compiler, int src1, int value);
+void orc_arm_emit_cmp (OrcCompiler *compiler, int src1, int src2);
+
 void orc_arm_emit_label (OrcCompiler *compiler, int label);
 void orc_arm_emit_push (OrcCompiler *compiler, int regs);
 void orc_arm_emit_pop (OrcCompiler *compiler, int regs);
@@ -83,7 +93,9 @@ void orc_arm_loadw (OrcCompiler *compiler, int dest, int src1, int offset);
 void orc_arm_storew (OrcCompiler *compiler, int dest, int offset, int src1);
 
 void orc_arm_emit_load_reg (OrcCompiler *compiler, int dest, int src1, int offset);
+void orc_arm_emit_store_reg (OrcCompiler *compiler, int src, int dest, int offset);
 
+void orc_arm_add_fixup (OrcCompiler *compiler, int label, int type);
 void orc_arm_do_fixups (OrcCompiler *compiler);
 
 void orc_arm_emit_dp (OrcCompiler *p, int type, OrcArmCond cond, OrcArmDP opcode,