x86: convert jumps to sysinsn
authorDavid Schleef <ds@schleef.org>
Thu, 4 Nov 2010 16:26:06 +0000 (09:26 -0700)
committerDavid Schleef <ds@schleef.org>
Thu, 4 Nov 2010 16:26:06 +0000 (09:26 -0700)
orc/orcsse.h
orc/orcx86.c
orc/orcx86.h
orc/orcx86insn.c
orc/orcx86insn.h

index 3b3ff86..d4da3ae 100644 (file)
@@ -84,6 +84,8 @@ void orc_sse_emit_sysinsn_reg_memoffset (OrcCompiler *p, int index, int src,
     int offset, int dest);
 void orc_sse_emit_sysinsn_memoffset_reg (OrcCompiler *p, int index, int offset,
     int src, int dest);
+void orc_sse_emit_sysinsn_branch (OrcCompiler *p, int index, int label);
+void orc_sse_emit_sysinsn_label (OrcCompiler *p, int index, int label);
 
 unsigned int orc_sse_get_cpu_flags (void);
 
index 2eb0d25..5d9965d 100644 (file)
@@ -700,108 +700,32 @@ x86_add_label (OrcCompiler *compiler, unsigned char *ptr, int label)
 
 void orc_x86_emit_jmp (OrcCompiler *compiler, int label)
 {
-  ORC_ASM_CODE(compiler,"  jmp %d%c\n", label,
-      (compiler->labels[label]!=NULL) ? 'b' : 'f');
-
-  if (compiler->long_jumps) {
-    *compiler->codeptr++ = 0xe9;
-    x86_add_fixup (compiler, compiler->codeptr, label, 1);
-    *compiler->codeptr++ = 0xfc;
-    *compiler->codeptr++ = 0xff;
-    *compiler->codeptr++ = 0xff;
-    *compiler->codeptr++ = 0xff;
-  } else {
-    *compiler->codeptr++ = 0xeb;
-    x86_add_fixup (compiler, compiler->codeptr, label, 0);
-    *compiler->codeptr++ = 0xff;
-  }
+  orc_sse_emit_sysinsn_branch (compiler, ORC_X86_jmp, label);
 }
 
 void orc_x86_emit_jg (OrcCompiler *compiler, int label)
 {
-  ORC_ASM_CODE(compiler,"  jg %d%c\n", label,
-      (compiler->labels[label]!=NULL) ? 'b' : 'f');
-
-  if (compiler->long_jumps) {
-    *compiler->codeptr++ = 0x0f;
-    *compiler->codeptr++ = 0x8f;
-    x86_add_fixup (compiler, compiler->codeptr, label, 1);
-    *compiler->codeptr++ = 0xfc;
-    *compiler->codeptr++ = 0xff;
-    *compiler->codeptr++ = 0xff;
-    *compiler->codeptr++ = 0xff;
-  } else {
-    *compiler->codeptr++ = 0x7f;
-    x86_add_fixup (compiler, compiler->codeptr, label, 0);
-    *compiler->codeptr++ = 0xff;
-  }
+  orc_sse_emit_sysinsn_branch (compiler, ORC_X86_jg, label);
 }
 
 void orc_x86_emit_jle (OrcCompiler *compiler, int label)
 {
-  ORC_ASM_CODE(compiler,"  jle %d%c\n", label,
-      (compiler->labels[label]!=NULL) ? 'b' : 'f');
-
-  if (compiler->long_jumps) {
-    *compiler->codeptr++ = 0x0f;
-    *compiler->codeptr++ = 0x8e;
-    x86_add_fixup (compiler, compiler->codeptr, label, 1);
-    *compiler->codeptr++ = 0xfc;
-    *compiler->codeptr++ = 0xff;
-    *compiler->codeptr++ = 0xff;
-    *compiler->codeptr++ = 0xff;
-  } else {
-    *compiler->codeptr++ = 0x7e;
-    x86_add_fixup (compiler, compiler->codeptr, label, 0);
-    *compiler->codeptr++ = 0xff;
-  }
+  orc_sse_emit_sysinsn_branch (compiler, ORC_X86_jle, label);
 }
 
 void orc_x86_emit_je (OrcCompiler *compiler, int label)
 {
-  ORC_ASM_CODE(compiler,"  je %d%c\n", label,
-      (compiler->labels[label]!=NULL) ? 'b' : 'f');
-
-  if (compiler->long_jumps) {
-    *compiler->codeptr++ = 0x0f;
-    *compiler->codeptr++ = 0x84;
-    x86_add_fixup (compiler, compiler->codeptr, label, 1);
-    *compiler->codeptr++ = 0xfc;
-    *compiler->codeptr++ = 0xff;
-    *compiler->codeptr++ = 0xff;
-    *compiler->codeptr++ = 0xff;
-  } else {
-    *compiler->codeptr++ = 0x74;
-    x86_add_fixup (compiler, compiler->codeptr, label, 0);
-    *compiler->codeptr++ = 0xff;
-  }
+  orc_sse_emit_sysinsn_branch (compiler, ORC_X86_jz, label);
 }
 
 void orc_x86_emit_jne (OrcCompiler *compiler, int label)
 {
-  ORC_ASM_CODE(compiler,"  jne %d%c\n", label,
-      (compiler->labels[label]!=NULL) ? 'b' : 'f');
-
-  if (compiler->long_jumps) {
-    *compiler->codeptr++ = 0x0f;
-    *compiler->codeptr++ = 0x85;
-    x86_add_fixup (compiler, compiler->codeptr, label, 1);
-    *compiler->codeptr++ = 0xfc;
-    *compiler->codeptr++ = 0xff;
-    *compiler->codeptr++ = 0xff;
-    *compiler->codeptr++ = 0xff;
-  } else {
-    *compiler->codeptr++ = 0x75;
-    x86_add_fixup (compiler, compiler->codeptr, label, 0);
-    *compiler->codeptr++ = 0xff;
-  }
+  orc_sse_emit_sysinsn_branch (compiler, ORC_X86_jnz, label);
 }
 
 void orc_x86_emit_label (OrcCompiler *compiler, int label)
 {
-  ORC_ASM_CODE(compiler,"%d:\n", label);
-
-  x86_add_label (compiler, compiler->codeptr, label);
+  orc_sse_emit_sysinsn_label (compiler, ORC_X86_LABEL, label);
 }
 
 void
index cdd0a60..4eb73d8 100644 (file)
@@ -100,6 +100,8 @@ void orc_x86_emit_modrm_memindex (OrcCompiler *compiler, int reg1, int offset,
 void orc_x86_emit_modrm_memindex2 (OrcCompiler *compiler, int offset,
     int src, int src_index, int shift, int dest);
 
+void x86_add_fixup (OrcCompiler *compiler, unsigned char *ptr, int label, int type);
+void x86_add_label (OrcCompiler *compiler, unsigned char *ptr, int label);
 void orc_x86_do_fixups (OrcCompiler *compiler);
 
 int orc_x86_assemble_copy_check (OrcCompiler *compiler);
index 1946211..93a8872 100644 (file)
@@ -197,6 +197,24 @@ static const OrcSysOpcode orc_x86_opcodes[] = {
   { "cmp", ORC_X86_INSN_TYPE_imm32_rm, 0, 0x81, 7 },
   { "cmp", ORC_X86_INSN_TYPE_rm_r, 0, 0x3b },
   { "cmp", ORC_X86_INSN_TYPE_r_rm, 0, 0x39 },
+  { "jo", ORC_X86_INSN_TYPE_LABEL, 0, 0x70 },
+  { "jno", ORC_X86_INSN_TYPE_LABEL, 0, 0x71 },
+  { "jc", ORC_X86_INSN_TYPE_LABEL, 0, 0x72 },
+  { "jnc", ORC_X86_INSN_TYPE_LABEL, 0, 0x73 },
+  { "jz", ORC_X86_INSN_TYPE_LABEL, 0, 0x74 },
+  { "jnz", ORC_X86_INSN_TYPE_LABEL, 0, 0x75 },
+  { "jbe", ORC_X86_INSN_TYPE_LABEL, 0, 0x76 },
+  { "ja", ORC_X86_INSN_TYPE_LABEL, 0, 0x77 },
+  { "js", ORC_X86_INSN_TYPE_LABEL, 0, 0x78 },
+  { "jns", ORC_X86_INSN_TYPE_LABEL, 0, 0x79 },
+  { "jp", ORC_X86_INSN_TYPE_LABEL, 0, 0x7a },
+  { "jnp", ORC_X86_INSN_TYPE_LABEL, 0, 0x7b },
+  { "jl", ORC_X86_INSN_TYPE_LABEL, 0, 0x7c },
+  { "jge", ORC_X86_INSN_TYPE_LABEL, 0, 0x7d },
+  { "jle", ORC_X86_INSN_TYPE_LABEL, 0, 0x7e },
+  { "jg", ORC_X86_INSN_TYPE_LABEL, 0, 0x7f },
+  { "jmp", ORC_X86_INSN_TYPE_LABEL, 0, 0xeb },
+  { "", ORC_X86_INSN_TYPE_LABEL, 0, 0x00 },
 
 };
 
@@ -651,3 +669,72 @@ orc_sse_emit_sysinsn_memoffset_reg (OrcCompiler *p, int index, int offset,
   }
 }
 
+void
+orc_sse_emit_sysinsn_branch (OrcCompiler *p, int index, int label)
+{
+  const OrcSysOpcode *opcode = orc_x86_opcodes + index;
+
+  switch (opcode->type) {
+    case ORC_X86_INSN_TYPE_LABEL:
+      ORC_ASM_CODE(p,"  %s %d%c\n", opcode->name, label,
+          (p->labels[label]!=NULL) ? 'b' : 'f');
+      break;
+    default:
+      ORC_ASSERT(0);
+      break;
+  }
+
+  if (p->long_jumps) {
+    if (index == ORC_X86_jmp) {
+      *p->codeptr++ = 0xe9;
+    } else {
+      *p->codeptr++ = 0x0f;
+      *p->codeptr++ = opcode->code + 0x10;
+    }
+  } else {
+    *p->codeptr++ = opcode->code;
+  }
+
+  switch (opcode->type) {
+    case ORC_X86_INSN_TYPE_LABEL:
+      if (p->long_jumps) {
+        x86_add_fixup (p, p->codeptr, label, 1);
+        *p->codeptr++ = 0xfc;
+        *p->codeptr++ = 0xff;
+        *p->codeptr++ = 0xff;
+        *p->codeptr++ = 0xff;
+      } else {
+        x86_add_fixup (p, p->codeptr, label, 0);
+        *p->codeptr++ = 0xff;
+      }
+      break;
+    default:
+      ORC_ASSERT(0);
+      break;
+  }
+}
+
+void
+orc_sse_emit_sysinsn_label (OrcCompiler *p, int index, int label)
+{
+  const OrcSysOpcode *opcode = orc_x86_opcodes + index;
+
+  switch (opcode->type) {
+    case ORC_X86_INSN_TYPE_LABEL:
+      ORC_ASM_CODE(p,"%d:\n", label);
+      break;
+    default:
+      ORC_ASSERT(0);
+      break;
+  }
+
+  switch (opcode->type) {
+    case ORC_X86_INSN_TYPE_LABEL:
+      x86_add_label (p, p->codeptr, label);
+      break;
+    default:
+      ORC_ASSERT(0);
+      break;
+  }
+}
+
index 36caf09..4a53c15 100644 (file)
@@ -15,7 +15,8 @@ enum {
   ORC_X86_INSN_TYPE_imm8_rm,
   ORC_X86_INSN_TYPE_imm32_rm,
   ORC_X86_INSN_TYPE_rm_r,
-  ORC_X86_INSN_TYPE_r_rm
+  ORC_X86_INSN_TYPE_r_rm,
+  ORC_X86_INSN_TYPE_LABEL
 };
 
 enum {
@@ -207,6 +208,24 @@ enum {
   ORC_X86_cmp_imm32_rm,
   ORC_X86_cmp_rm_r,
   ORC_X86_cmp_r_rm,
+  ORC_X86_jo,
+  ORC_X86_jno,
+  ORC_X86_jc,
+  ORC_X86_jnc,
+  ORC_X86_jz,
+  ORC_X86_jnz,
+  ORC_X86_jbe,
+  ORC_X86_ja,
+  ORC_X86_js,
+  ORC_X86_jns,
+  ORC_X86_jp,
+  ORC_X86_jnp,
+  ORC_X86_jl,
+  ORC_X86_jge,
+  ORC_X86_jle,
+  ORC_X86_jg,
+  ORC_X86_jmp,
+  ORC_X86_LABEL,
 };