From aab523c77fb54d02b8a8a499a6c031ae3324b6fb Mon Sep 17 00:00:00 2001 From: David Schleef Date: Tue, 17 Aug 2010 18:02:40 -0700 Subject: [PATCH] sse,x86: Add some new instruction emission code --- orc/orcsse.c | 38 ++++++++++++++++++++++++++++++++++ orc/orcsse.h | 8 ++++++-- orc/orcx86.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ orc/orcx86.h | 3 +++ 4 files changed, 113 insertions(+), 2 deletions(-) diff --git a/orc/orcsse.c b/orc/orcsse.c index 89f0dfd..b2103f5 100644 --- a/orc/orcsse.c +++ b/orc/orcsse.c @@ -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) { diff --git a/orc/orcsse.h b/orc/orcsse.h index f5397ff..aaf4451 100644 --- a/orc/orcsse.h +++ b/orc/orcsse.h @@ -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) diff --git a/orc/orcx86.c b/orc/orcx86.c index 3c10505..60b1123 100644 --- a/orc/orcx86.c +++ b/orc/orcx86.c @@ -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--){ diff --git a/orc/orcx86.h b/orc/orcx86.h index 4358d20..3d60072 100644 --- a/orc/orcx86.h +++ b/orc/orcx86.h @@ -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); -- 2.7.4