sse,x86: Add some new instruction emission code
authorDavid Schleef <ds@schleef.org>
Wed, 18 Aug 2010 01:02:40 +0000 (18:02 -0700)
committerDavid Schleef <ds@schleef.org>
Wed, 18 Aug 2010 01:02:40 +0000 (18:02 -0700)
orc/orcsse.c
orc/orcsse.h
orc/orcx86.c
orc/orcx86.h

index 89f0dfd..b2103f5 100644 (file)
@@ -138,6 +138,44 @@ orc_sse_emit_pshuflw (OrcCompiler *p, int shuf, int src, int dest)
 }
 
 void
+orc_sse_emit_palignr (OrcCompiler *p, int align, int src, int dest)
+{
+  ORC_ASM_CODE(p,"  palignr $%d, %%%s, %%%s\n", align,
+      orc_x86_get_regname_sse(src),
+      orc_x86_get_regname_sse(dest));
+  *p->codeptr++ = 0x66;
+  orc_x86_emit_rex (p, 0, dest, 0, src);
+  *p->codeptr++ = 0x0f;
+  *p->codeptr++ = 0x3a;
+  *p->codeptr++ = 0x0f;
+  orc_x86_emit_modrm_reg (p, src, dest);
+  *p->codeptr++ = align;
+}
+
+void
+orc_sse_emit_pinsrw_memoffset (OrcCompiler *p, int imm, int offset,
+    int src, int dest)
+{
+  ORC_ASM_CODE(p,"  pinsrw $%d, %d(%%%s), %%%s\n", imm, offset,
+      orc_x86_get_regname(src),
+      orc_x86_get_regname_sse(dest));
+  *p->codeptr++ = 0x66;
+  orc_x86_emit_rex (p, 0, dest, 0, src);
+  *p->codeptr++ = 0x0f;
+  *p->codeptr++ = 0xc4;
+  orc_x86_emit_modrm_memoffset (p, dest, offset, src);
+  *p->codeptr++ = imm;
+
+}
+
+void
+orc_sse_emit_pextrw_memoffset (OrcCompiler *p, int imm, int src,
+    int offset, int dest)
+{
+
+}
+
+void
 orc_sse_emit_shiftimm (OrcCompiler *p, const char *insn_name, int code,
     int modrm_code, int shift, int reg)
 {
index f5397ff..aaf4451 100644 (file)
@@ -65,6 +65,9 @@ void orc_sse_emit_0f (OrcCompiler *p, const char *insn_name, int code,
 void orc_sse_emit_pshufd (OrcCompiler *p, int shuf, int src, int dest);
 void orc_sse_emit_pshuflw (OrcCompiler *p, int shuf, int src, int dest);
 void orc_sse_emit_pshufhw (OrcCompiler *p, int shuf, int src, int dest);
+void orc_sse_emit_palignr (OrcCompiler *p, int align, int src, int dest);
+void orc_sse_emit_pinsrw_memoffset (OrcCompiler *p, int imm, int offset, int src, int dest);
+void orc_sse_emit_pextrw_memoffset (OrcCompiler *p, int imm, int src, int offset, int dest);
 void orc_sse_emit_shiftimm (OrcCompiler *p, const char *insn_name,
     int code, int modrm_code, int shift, int reg);
 
@@ -107,12 +110,12 @@ unsigned int orc_sse_get_cpu_flags (void);
 #define orc_sse_emit_psrldq(p,a,b)     orc_sse_emit_shiftimm (p, "psrldq", 0x73, 3, a, b)
 #define orc_sse_emit_pslldq(p,a,b)     orc_sse_emit_shiftimm (p, "pslldq", 0x73, 7, a, b)
 
+#define orc_sse_emit_psrlq_reg(p,a,b)      orc_sse_emit_660f (p, "psrlq", 0xd3, a, b)
+
 #define orc_sse_emit_pcmpeqb(p,a,b)    orc_sse_emit_660f (p, "pcmpeqb", 0x74, a, b)
 #define orc_sse_emit_pcmpeqw(p,a,b)    orc_sse_emit_660f (p, "pcmpeqw", 0x75, a, b)
 #define orc_sse_emit_pcmpeqd(p,a,b)    orc_sse_emit_660f (p, "pcmpeqd", 0x76, a, b)
 
-#define orc_sse_emit_pinsrw(p,a,b)     orc_sse_emit_660f (p, "pinsrw", 0xc4, a, b)
-#define orc_sse_emit_pextrw(p,a,b)     orc_sse_emit_660f (p, "pextrw", 0xc5, a, b)
 
 #define orc_sse_emit_paddq(p,a,b)      orc_sse_emit_660f (p, "paddq", 0xd4, a, b)
 #define orc_sse_emit_pmullw(p,a,b)     orc_sse_emit_660f (p, "pmullw", 0xd5, a, b)
@@ -173,6 +176,7 @@ unsigned int orc_sse_get_cpu_flags (void);
 #define orc_sse_emit_pabsw(p,a,b)      orc_sse_emit_660f (p, "pabsw", 0x381d, a, b)
 #define orc_sse_emit_pabsd(p,a,b)      orc_sse_emit_660f (p, "pabsd", 0x381e, a, b)
 
+
 /* SSE4.1 instructions */
 #define orc_sse_emit_pmovsxbw(p,a,b)   orc_sse_emit_660f (p, "pmovsxbw", 0x3820, a, b)
 #define orc_sse_emit_pmovsxbd(p,a,b)   orc_sse_emit_660f (p, "pmovsxbd", 0x3821, a, b)
index 3c10505..60b1123 100644 (file)
@@ -617,6 +617,38 @@ orc_x86_emit_cmp_reg_memoffset (OrcCompiler *compiler, int size, int reg1,
 }
 
 void
+orc_x86_emit_cmp_imm_reg (OrcCompiler *compiler, int size, int value, int reg)
+{
+  if (size == 2) {
+    ORC_ASM_CODE(compiler,"  cmpw $%d, %%%s\n", value,
+        orc_x86_get_regname_ptr(compiler, reg));
+    *compiler->codeptr++ = 0x66;
+  } else if (size == 4) {
+    ORC_ASM_CODE(compiler,"  cmpl $%d, %%%s\n", value,
+        orc_x86_get_regname_ptr(compiler, reg));
+  } else {
+    ORC_ASM_CODE(compiler,"  cmp $%d, %%%s\n", value,
+        orc_x86_get_regname_ptr(compiler, reg));
+  }
+
+  orc_x86_emit_rex(compiler, size, 0, 0, reg);
+  if (value >= -128 && value < 128) {
+    *compiler->codeptr++ = 0x83;
+    orc_x86_emit_modrm_reg (compiler, reg, 7);
+    *compiler->codeptr++ = (value & 0xff);
+  } else {
+    *compiler->codeptr++ = 0x81;
+    orc_x86_emit_modrm_reg (compiler, reg, 7);
+    *compiler->codeptr++ = (value & 0xff);
+    *compiler->codeptr++ = ((value>>8) & 0xff);
+    if (size == 4) {
+      *compiler->codeptr++ = ((value>>16) & 0xff);
+      *compiler->codeptr++ = ((value>>24) & 0xff);
+    }
+  }
+}
+
+void
 orc_x86_emit_cmp_imm_memoffset (OrcCompiler *compiler, int size, int value,
     int offset, int reg)
 {
@@ -717,6 +749,13 @@ void orc_x86_emit_emms (OrcCompiler *compiler)
   *compiler->codeptr++ = 0x77;
 }
 
+void orc_x86_emit_rdtsc (OrcCompiler *compiler)
+{
+  ORC_ASM_CODE(compiler,"  rdtsc\n");
+  *compiler->codeptr++ = 0x0f;
+  *compiler->codeptr++ = 0x31;
+}
+
 void orc_x86_emit_rep_movs (OrcCompiler *compiler, int size)
 {
   switch (size) {
@@ -773,6 +812,26 @@ void orc_x86_emit_jmp (OrcCompiler *compiler, int 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;
+  }
+}
+
 void orc_x86_emit_jle (OrcCompiler *compiler, int label)
 {
   ORC_ASM_CODE(compiler,"  jle %d%c\n", label,
@@ -898,11 +957,18 @@ orc_x86_emit_prologue (OrcCompiler *compiler)
     }
   }
 
+  orc_x86_emit_rdtsc(compiler);
+  orc_x86_emit_mov_reg_memoffset (compiler, 4, X86_EAX,
+      ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_A3]), compiler->exec_reg);
 }
 
 void
 orc_x86_emit_epilogue (OrcCompiler *compiler)
 {
+  orc_x86_emit_rdtsc(compiler);
+  orc_x86_emit_mov_reg_memoffset (compiler, 4, X86_EAX,
+      ORC_STRUCT_OFFSET(OrcExecutor,params[ORC_VAR_A4]), compiler->exec_reg);
+
   if (compiler->is_64bit) {
     int i;
     for(i=15;i>=0;i--){
index 4358d20..3d60072 100644 (file)
@@ -54,12 +54,15 @@ void orc_x86_emit_cmp_reg_memoffset (OrcCompiler *compiler, int size, int reg1,
     int offset, int reg);
 void orc_x86_emit_cmp_imm_memoffset (OrcCompiler *compiler, int size, int value,
     int offset, int reg);
+void orc_x86_emit_cmp_imm_reg (OrcCompiler *compiler, int size, int value, int reg);
 void orc_x86_emit_test_imm_memoffset (OrcCompiler *compiler, int size, int value,
     int offset, int reg);
 void orc_x86_emit_emms (OrcCompiler *compiler);
+void orc_x86_emit_rdtsc (OrcCompiler *compiler);
 void orc_x86_emit_rep_movs (OrcCompiler *compiler, int size);
 void orc_x86_emit_ret (OrcCompiler *compiler);
 void orc_x86_emit_jle (OrcCompiler *compiler, int label);
+void orc_x86_emit_jg (OrcCompiler *compiler, int label);
 void orc_x86_emit_je (OrcCompiler *compiler, int label);
 void orc_x86_emit_jne (OrcCompiler *compiler, int label);
 void orc_x86_emit_jmp (OrcCompiler *compiler, int label);