From 4cc72f5091e1e3186a42c11f83abfd51462c340f Mon Sep 17 00:00:00 2001 From: David Schleef Date: Thu, 4 Nov 2010 15:12:38 +0000 Subject: [PATCH] x86: convert arith instructions to sysinsn --- orc/orcrules-sse.c | 22 +--- orc/orcsse.h | 8 ++ orc/orcsysinsn.h | 1 + orc/orcx86.c | 273 ++++++------------------------------------------ orc/orcx86insn.c | 296 +++++++++++++++++++++++++++++++++++++++++------------ orc/orcx86insn.h | 38 ++++++- 6 files changed, 310 insertions(+), 328 deletions(-) diff --git a/orc/orcrules-sse.c b/orc/orcrules-sse.c index 4a878fe..5075832 100644 --- a/orc/orcrules-sse.c +++ b/orc/orcrules-sse.c @@ -381,16 +381,8 @@ sse_rule_ldresnearl (OrcCompiler *compiler, void *user, OrcInstruction *insn) orc_x86_emit_mov_sse_reg (compiler, X86_XMM6, compiler->gp_tmpreg); orc_x86_emit_sar_imm_reg (compiler, 4, 16, compiler->gp_tmpreg); - ORC_ASM_CODE(compiler," movdqu 0(%%%s,%%%s,4), %%%s\n", - orc_x86_get_regname_ptr(compiler, src->ptr_register), - orc_x86_get_regname_ptr(compiler, compiler->gp_tmpreg), - orc_x86_get_regname_sse(dest->alloc)); - *compiler->codeptr++ = 0xf3; - orc_x86_emit_rex(compiler, 0, dest->ptr_register, 0, dest->alloc); - *compiler->codeptr++ = 0x0f; - *compiler->codeptr++ = 0x6f; - orc_x86_emit_modrm_memindex (compiler, dest->alloc, 0, - src->ptr_register, compiler->gp_tmpreg, 2); + orc_sse_emit_movdqu_load_memindex (compiler, 0, src->ptr_register, + compiler->gp_tmpreg, 4, dest->alloc); #if 0 orc_sse_emit_movdqa (compiler, X86_XMM6, tmp); @@ -564,15 +556,7 @@ sse_rule_ldreslinl (OrcCompiler *compiler, void *user, OrcInstruction *insn) orc_sse_emit_psubw (compiler, tmp, tmp2); - ORC_ASM_CODE(compiler," pinsrw $%d, %%%s, %%%s\n", 1, - orc_x86_get_regname (src->ptr_offset), - orc_x86_get_regname_sse(tmp4)); - *compiler->codeptr++ = 0x66; - orc_x86_emit_rex (compiler, 0, tmp4, 0, src->ptr_offset); - *compiler->codeptr++ = 0x0f; - *compiler->codeptr++ = 0xc4; - orc_x86_emit_modrm_reg (compiler, src->ptr_offset, tmp4); - *compiler->codeptr++ = 1; + orc_sse_emit_pinsrw_register (compiler, 1, src->ptr_offset, tmp4); #if 0 orc_sse_emit_punpcklwd (compiler, tmp4, tmp4); diff --git a/orc/orcsse.h b/orc/orcsse.h index 7c5d451..3b3ff86 100644 --- a/orc/orcsse.h +++ b/orc/orcsse.h @@ -76,6 +76,14 @@ void orc_sse_emit_sysinsn_load_memindex (OrcCompiler *p, int index, int imm, int offset, int src, int src_index, int shift, int dest); void orc_sse_emit_sysinsn_load_register (OrcCompiler *p, int index, int imm, int src, int dest); +void orc_sse_emit_sysinsn_imm_reg (OrcCompiler *p, int index, int imm, + int dest); +void orc_sse_emit_sysinsn_imm_memoffset (OrcCompiler *p, int index, int imm, + int offset, int dest); +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); unsigned int orc_sse_get_cpu_flags (void); diff --git a/orc/orcsysinsn.h b/orc/orcsysinsn.h index 3411f3c..b8e8745 100644 --- a/orc/orcsysinsn.h +++ b/orc/orcsysinsn.h @@ -17,6 +17,7 @@ struct _OrcSysInsn { int memoffset; int indexreg; int shift; + int size; }; struct _OrcSysOpcode { diff --git a/orc/orcx86.c b/orc/orcx86.c index 214f464..2eb0d25 100644 --- a/orc/orcx86.c +++ b/orc/orcx86.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include /** @@ -421,67 +423,22 @@ void orc_x86_emit_and_imm_memoffset (OrcCompiler *compiler, int size, int value, int offset, int reg) { - if (size == 2) { - ORC_ASM_CODE(compiler," andw $%d, %d(%%%s)\n", value, offset, - orc_x86_get_regname_ptr(compiler, reg)); - *compiler->codeptr++ = 0x66; - } else if (size == 4) { - ORC_ASM_CODE(compiler," andl $%d, %d(%%%s)\n", value, offset, - orc_x86_get_regname_ptr(compiler, reg)); - } else { - ORC_ASM_CODE(compiler," and $%d, %d(%%%s)\n", value, offset, - orc_x86_get_regname_ptr(compiler, reg)); - } - - orc_x86_emit_rex(compiler, size, 0, 0, reg); if (value >= -128 && value < 128) { - *compiler->codeptr++ = 0x83; - /* FIXME */ - orc_x86_emit_modrm_memoffset_old (compiler, 0, offset, reg); - *compiler->codeptr++ = (value & 0xff); + orc_sse_emit_sysinsn_imm_memoffset (compiler, ORC_X86_and_imm8_rm, + value, offset, reg); } else { - *compiler->codeptr++ = 0x81; - /* FIXME */ - orc_x86_emit_modrm_memoffset_old (compiler, 0, offset, reg); - *compiler->codeptr++ = (value & 0xff); - *compiler->codeptr++ = ((value>>8) & 0xff); - if (size == 4) { - *compiler->codeptr++ = ((value>>16) & 0xff); - *compiler->codeptr++ = ((value>>24) & 0xff); - } + orc_sse_emit_sysinsn_imm_memoffset (compiler, ORC_X86_and_imm32_rm, + value, offset, reg); } } void orc_x86_emit_and_imm_reg (OrcCompiler *compiler, int size, int value, int reg) { - if (size == 2) { - ORC_ASM_CODE(compiler," andw $%d, %%%s\n", value, orc_x86_get_regname_16(reg)); - *compiler->codeptr++ = 0x66; - } else if (size == 4) { - ORC_ASM_CODE(compiler," andl $%d, %%%s\n", value, orc_x86_get_regname(reg)); - } else { - ORC_ASM_CODE(compiler," and $%d, %%%s\n", value, orc_x86_get_regname_64(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, 4); - *compiler->codeptr++ = (value & 0xff); + orc_sse_emit_sysinsn_imm_reg (compiler, ORC_X86_and_imm8_rm, value, reg); } else { - if (reg == X86_EAX) { - *compiler->codeptr++ = 0x25; - } else { - *compiler->codeptr++ = 0x81; - orc_x86_emit_modrm_reg (compiler, reg, 4); - } - *compiler->codeptr++ = (value & 0xff); - *compiler->codeptr++ = ((value>>8) & 0xff); - if (size == 4) { - *compiler->codeptr++ = ((value>>16) & 0xff); - *compiler->codeptr++ = ((value>>24) & 0xff); - } + orc_sse_emit_sysinsn_imm_reg (compiler, ORC_X86_and_imm32_rm, value, reg); } } @@ -489,32 +446,12 @@ void orc_x86_emit_add_imm_memoffset (OrcCompiler *compiler, int size, int value, int offset, int reg) { - if (size == 2) { - ORC_ASM_CODE(compiler," addw $%d, %d(%%%s)\n", value, offset, - orc_x86_get_regname_ptr(compiler, reg)); - *compiler->codeptr++ = 0x66; - } else if (size == 4) { - ORC_ASM_CODE(compiler," addl $%d, %d(%%%s)\n", value, offset, - orc_x86_get_regname_ptr(compiler, reg)); - } else { - ORC_ASM_CODE(compiler," addq $%d, %d(%%%s)\n", value, offset, - 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_memoffset_old (compiler, 0, offset, reg); - *compiler->codeptr++ = (value & 0xff); + orc_sse_emit_sysinsn_imm_memoffset (compiler, ORC_X86_add_imm8_rm, + value, offset, reg); } else { - *compiler->codeptr++ = 0x81; - orc_x86_emit_modrm_memoffset_old (compiler, 0, offset, reg); - *compiler->codeptr++ = (value & 0xff); - *compiler->codeptr++ = ((value>>8) & 0xff); - if (size == 4 || size == 8) { - *compiler->codeptr++ = ((value>>16) & 0xff); - *compiler->codeptr++ = ((value>>24) & 0xff); - } + orc_sse_emit_sysinsn_imm_memoffset (compiler, ORC_X86_add_imm32_rm, + value, offset, reg); } } @@ -522,24 +459,8 @@ void orc_x86_emit_add_reg_memoffset (OrcCompiler *compiler, int size, int reg1, int offset, int reg) { - if (size == 2) { - ORC_ASM_CODE(compiler," addw %%%s, %d(%%%s)\n", - orc_x86_get_regname_ptr(compiler, reg1), offset, - orc_x86_get_regname_ptr(compiler, reg)); - *compiler->codeptr++ = 0x66; - } else if (size == 4) { - ORC_ASM_CODE(compiler," addl %%%s, %d(%%%s)\n", - orc_x86_get_regname_ptr(compiler, reg1), offset, - orc_x86_get_regname_ptr(compiler, reg)); - } else { - ORC_ASM_CODE(compiler," add %%%s, %d(%%%s)\n", - orc_x86_get_regname_ptr(compiler, reg1), offset, - orc_x86_get_regname_ptr(compiler, reg)); - } - - orc_x86_emit_rex(compiler, size, reg1, 0, reg); - *compiler->codeptr++ = 0x01; - orc_x86_emit_modrm_memoffset_old (compiler, reg1, offset, reg); + orc_sse_emit_sysinsn_reg_memoffset (compiler, ORC_X86_add_r_rm, + reg1, offset, reg); } void @@ -564,29 +485,12 @@ orc_x86_emit_add_imm_reg (OrcCompiler *compiler, int size, int value, int reg, o } } - if (size == 2) { - ORC_ASM_CODE(compiler," addw $%d, %%%s\n", value, orc_x86_get_regname_16(reg)); - *compiler->codeptr++ = 0x66; - } else if (size == 4) { - ORC_ASM_CODE(compiler," addl $%d, %%%s\n", value, orc_x86_get_regname(reg)); - } else { - ORC_ASM_CODE(compiler," addq $%d, %%%s\n", value, orc_x86_get_regname_64(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, 0); - *compiler->codeptr++ = (value & 0xff); + orc_sse_emit_sysinsn_imm_reg (compiler, ORC_X86_add_imm8_rm, + value, reg); } else { - *compiler->codeptr++ = 0x81; - orc_x86_emit_modrm_reg (compiler, reg, 0); - *compiler->codeptr++ = (value & 0xff); - *compiler->codeptr++ = ((value>>8) & 0xff); - if (size == 4 || size == 8) { - *compiler->codeptr++ = ((value>>16) & 0xff); - *compiler->codeptr++ = ((value>>24) & 0xff); - } + orc_sse_emit_sysinsn_imm_reg (compiler, ORC_X86_add_imm32_rm, + value, reg); } } @@ -614,41 +518,13 @@ orc_x86_emit_add_reg_reg_shift (OrcCompiler *compiler, int size, int reg1, void orc_x86_emit_add_reg_reg (OrcCompiler *compiler, int size, int reg1, int reg2) { - if (size == 2) { - ORC_ASM_CODE(compiler," addw %%%s, %%%s\n", orc_x86_get_regname_16(reg1), - orc_x86_get_regname_16(reg2)); - *compiler->codeptr++ = 0x66; - } else if (size == 4) { - ORC_ASM_CODE(compiler," addl %%%s, %%%s\n", orc_x86_get_regname(reg1), - orc_x86_get_regname(reg2)); - } else { - ORC_ASM_CODE(compiler," add %%%s, %%%s\n", orc_x86_get_regname_64(reg1), - orc_x86_get_regname_64(reg2)); - } - - orc_x86_emit_rex(compiler, size, reg2, 0, reg1); - *compiler->codeptr++ = 0x01; - orc_x86_emit_modrm_reg (compiler, reg2, reg1); + orc_sse_emit_sysinsn (compiler, ORC_X86_add_r_rm, 0, reg1, reg2); } void orc_x86_emit_sub_reg_reg (OrcCompiler *compiler, int size, int reg1, int reg2) { - if (size == 2) { - ORC_ASM_CODE(compiler," subw %%%s, %%%s\n", orc_x86_get_regname_16(reg1), - orc_x86_get_regname_16(reg2)); - *compiler->codeptr++ = 0x66; - } else if (size == 4) { - ORC_ASM_CODE(compiler," subl %%%s, %%%s\n", orc_x86_get_regname(reg1), - orc_x86_get_regname(reg2)); - } else { - ORC_ASM_CODE(compiler," sub %%%s, %%%s\n", orc_x86_get_regname_64(reg1), - orc_x86_get_regname_64(reg2)); - } - - orc_x86_emit_rex(compiler, size, reg2, 0, reg1); - *compiler->codeptr++ = 0x29; - orc_x86_emit_modrm_reg (compiler, reg2, reg1); + orc_sse_emit_sysinsn (compiler, ORC_X86_sub_r_rm, 0, reg1, reg2); } void @@ -669,100 +545,33 @@ void orc_x86_emit_add_memoffset_reg (OrcCompiler *compiler, int size, int offset, int reg, int destreg) { - if (size == 2) { - ORC_ASM_CODE(compiler," addw %d(%%%s), %%%s\n", offset, - orc_x86_get_regname_ptr(compiler, reg), - orc_x86_get_regname_16(destreg)); - *compiler->codeptr++ = 0x66; - } else if (size == 4) { - ORC_ASM_CODE(compiler," addl %d(%%%s), %%%s\n", offset, - orc_x86_get_regname_ptr(compiler, reg), - orc_x86_get_regname(destreg)); - } else { - ORC_ASM_CODE(compiler," add %d(%%%s), %%%s\n", offset, - orc_x86_get_regname_ptr(compiler, reg), - orc_x86_get_regname_64(destreg)); - } - - orc_x86_emit_rex(compiler, size, destreg, 0, reg); - *compiler->codeptr++ = 0x03; - orc_x86_emit_modrm_memoffset_old (compiler, destreg, offset, reg); + orc_sse_emit_sysinsn_memoffset_reg (compiler, ORC_X86_add_rm_r, + offset, reg, destreg); } void orc_x86_emit_sub_memoffset_reg (OrcCompiler *compiler, int size, int offset, int reg, int destreg) { - if (size == 2) { - ORC_ASM_CODE(compiler," subw %d(%%%s), %%%s\n", offset, - orc_x86_get_regname_ptr(compiler, reg), - orc_x86_get_regname_16(destreg)); - *compiler->codeptr++ = 0x66; - } else if (size == 4) { - ORC_ASM_CODE(compiler," subl %d(%%%s), %%%s\n", offset, - orc_x86_get_regname_ptr(compiler, reg), - orc_x86_get_regname(destreg)); - } else { - ORC_ASM_CODE(compiler," sub %d(%%%s), %%%s\n", offset, - orc_x86_get_regname_ptr(compiler, reg), - orc_x86_get_regname_64(destreg)); - } - - orc_x86_emit_rex(compiler, size, 0, 0, reg); - *compiler->codeptr++ = 0x2b; - orc_x86_emit_modrm_memoffset_old (compiler, destreg, offset, reg); + orc_sse_emit_sysinsn_memoffset_reg (compiler, ORC_X86_sub_rm_r, + offset, reg, destreg); } void orc_x86_emit_cmp_reg_memoffset (OrcCompiler *compiler, int size, int reg1, int offset, int reg) { - if (size == 2) { - ORC_ASM_CODE(compiler," cmpw %%%s, %d(%%%s)\n", orc_x86_get_regname_16(reg1), offset, - orc_x86_get_regname_ptr(compiler, reg)); - *compiler->codeptr++ = 0x66; - } else if (size == 4) { - ORC_ASM_CODE(compiler," cmpl %%%s, %d(%%%s)\n", orc_x86_get_regname(reg1), offset, - orc_x86_get_regname_ptr(compiler, reg)); - } else { - ORC_ASM_CODE(compiler," cmp %%%s, %d(%%%s)\n", orc_x86_get_regname_64(reg1), offset, - orc_x86_get_regname_ptr(compiler, reg)); - } - - orc_x86_emit_rex(compiler, size, 0, 0, reg); - *compiler->codeptr++ = 0x39; - orc_x86_emit_modrm_memoffset_old (compiler, reg1, offset, reg); + orc_sse_emit_sysinsn_reg_memoffset (compiler, ORC_X86_cmp_r_rm, reg1, + offset, reg); } 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); + orc_sse_emit_sysinsn_imm_reg (compiler, ORC_X86_cmp_imm8_rm, value, reg); } 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); - } + orc_sse_emit_sysinsn_imm_reg (compiler, ORC_X86_cmp_imm32_rm, value, reg); } } @@ -770,32 +579,10 @@ void orc_x86_emit_cmp_imm_memoffset (OrcCompiler *compiler, int size, int value, int offset, int reg) { - if (size == 2) { - ORC_ASM_CODE(compiler," cmpw $%d, %d(%%%s)\n", value, offset, - orc_x86_get_regname_ptr(compiler, reg)); - *compiler->codeptr++ = 0x66; - } else if (size == 4) { - ORC_ASM_CODE(compiler," cmpl $%d, %d(%%%s)\n", value, offset, - orc_x86_get_regname_ptr(compiler, reg)); - } else { - ORC_ASM_CODE(compiler," cmp $%d, %d(%%%s)\n", value, offset, - 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_memoffset_old (compiler, 7, offset, reg); - *compiler->codeptr++ = (value & 0xff); + orc_sse_emit_sysinsn_imm_memoffset (compiler, ORC_X86_cmp_imm8_rm, value, offset, reg); } else { - *compiler->codeptr++ = 0x81; - orc_x86_emit_modrm_memoffset_old (compiler, 7, offset, reg); - *compiler->codeptr++ = (value & 0xff); - *compiler->codeptr++ = ((value>>8) & 0xff); - if (size == 4) { - *compiler->codeptr++ = ((value>>16) & 0xff); - *compiler->codeptr++ = ((value>>24) & 0xff); - } + orc_sse_emit_sysinsn_imm_memoffset (compiler, ORC_X86_cmp_imm32_rm, value, offset, reg); } } diff --git a/orc/orcx86insn.c b/orc/orcx86insn.c index d471b7a..1946211 100644 --- a/orc/orcx86insn.c +++ b/orc/orcx86insn.c @@ -165,9 +165,67 @@ static const OrcSysOpcode orc_x86_opcodes[] = { { "movntdq", ORC_X86_INSN_TYPE_SD_REV, 0, 0x660fe7 }, { "ldmxcsr", ORC_X86_INSN_TYPE_MEM, 0, 0x0fae, 2 }, { "stmxcsr", ORC_X86_INSN_TYPE_MEM, 0, 0x0fae, 3 }, + { "add", ORC_X86_INSN_TYPE_imm8_rm, 0, 0x83, 0 }, + { "add", ORC_X86_INSN_TYPE_imm32_rm, 0, 0x81, 0 }, + { "add", ORC_X86_INSN_TYPE_rm_r, 0, 0x03 }, + { "add", ORC_X86_INSN_TYPE_r_rm, 0, 0x01 }, + { "or", ORC_X86_INSN_TYPE_imm8_rm, 0, 0x83, 1 }, + { "or", ORC_X86_INSN_TYPE_imm32_rm, 0, 0x81, 1 }, + { "or", ORC_X86_INSN_TYPE_rm_r, 0, 0x0b }, + { "or", ORC_X86_INSN_TYPE_r_rm, 0, 0x09 }, + { "adc", ORC_X86_INSN_TYPE_imm8_rm, 0, 0x83, 2 }, + { "adc", ORC_X86_INSN_TYPE_imm32_rm, 0, 0x81, 2 }, + { "adc", ORC_X86_INSN_TYPE_rm_r, 0, 0x13 }, + { "adc", ORC_X86_INSN_TYPE_r_rm, 0, 0x11 }, + { "sbb", ORC_X86_INSN_TYPE_imm8_rm, 0, 0x83, 3 }, + { "sbb", ORC_X86_INSN_TYPE_imm32_rm, 0, 0x81, 3 }, + { "sbb", ORC_X86_INSN_TYPE_rm_r, 0, 0x1b }, + { "sbb", ORC_X86_INSN_TYPE_r_rm, 0, 0x19 }, + { "and", ORC_X86_INSN_TYPE_imm8_rm, 0, 0x83, 4 }, + { "and", ORC_X86_INSN_TYPE_imm32_rm, 0, 0x81, 4 }, + { "and", ORC_X86_INSN_TYPE_rm_r, 0, 0x23 }, + { "and", ORC_X86_INSN_TYPE_r_rm, 0, 0x21 }, + { "sub", ORC_X86_INSN_TYPE_imm8_rm, 0, 0x83, 5 }, + { "sub", ORC_X86_INSN_TYPE_imm32_rm, 0, 0x81, 5 }, + { "sub", ORC_X86_INSN_TYPE_rm_r, 0, 0x2b }, + { "sub", ORC_X86_INSN_TYPE_r_rm, 0, 0x29 }, + { "xor", ORC_X86_INSN_TYPE_imm8_rm, 0, 0x83, 6 }, + { "xor", ORC_X86_INSN_TYPE_imm32_rm, 0, 0x81, 6 }, + { "xor", ORC_X86_INSN_TYPE_rm_r, 0, 0x33 }, + { "xor", ORC_X86_INSN_TYPE_r_rm, 0, 0x31 }, + { "cmp", ORC_X86_INSN_TYPE_imm8_rm, 0, 0x83, 7 }, + { "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 }, }; +static void +output_opcode (OrcCompiler *p, const OrcSysOpcode *opcode, int size, + int src, int dest) +{ + ORC_ASSERT(opcode->code != 0); + + if (opcode->code & 0xff000000) { + *p->codeptr++ = (opcode->code >> 24) & 0xff; + orc_x86_emit_rex (p, size, dest, 0, 0); + *p->codeptr++ = (opcode->code >> 16) & 0xff; + *p->codeptr++ = (opcode->code >> 8) & 0xff; + *p->codeptr++ = (opcode->code >> 0) & 0xff; + } else if (opcode->code & 0xff0000) { + *p->codeptr++ = (opcode->code >> 16) & 0xff; + orc_x86_emit_rex (p, size, dest, 0, 0); + *p->codeptr++ = (opcode->code >> 8) & 0xff; + *p->codeptr++ = (opcode->code >> 0) & 0xff; + } else if (opcode->code & 0xff00) { + *p->codeptr++ = (opcode->code >> 8) & 0xff; + orc_x86_emit_rex (p, size, dest, 0, 0); + *p->codeptr++ = (opcode->code >> 0) & 0xff; + } else { + orc_x86_emit_rex (p, size, dest, 0, 0); + *p->codeptr++ = (opcode->code >> 0) & 0xff; + } +} void orc_sse_emit_sysinsn (OrcCompiler *p, int index, int imm, int src, int dest) @@ -203,34 +261,27 @@ orc_sse_emit_sysinsn (OrcCompiler *p, int index, int imm, int src, int dest) orc_x86_get_regname_sse(src), orc_x86_get_regname_sse(dest)); break; + case ORC_X86_INSN_TYPE_rm_r: + case ORC_X86_INSN_TYPE_r_rm: + ORC_ASM_CODE(p," %s %%%s, %%%s\n", opcode->name, + orc_x86_get_regname(src), + orc_x86_get_regname(dest)); + break; case ORC_X86_INSN_TYPE_MEM: default: ORC_ASSERT(0); break; } - if (opcode->code & 0xff000000) { - *p->codeptr++ = (opcode->code >> 24) & 0xff; - orc_x86_emit_rex (p, 0, dest, 0, src); - *p->codeptr++ = (opcode->code >> 16) & 0xff; - *p->codeptr++ = (opcode->code >> 8) & 0xff; - *p->codeptr++ = (opcode->code >> 0) & 0xff; - } else if (opcode->code & 0xff0000) { - *p->codeptr++ = (opcode->code >> 16) & 0xff; - orc_x86_emit_rex (p, 0, dest, 0, src); - *p->codeptr++ = (opcode->code >> 8) & 0xff; - *p->codeptr++ = (opcode->code >> 0) & 0xff; - } else { - *p->codeptr++ = (opcode->code >> 8) & 0xff; - orc_x86_emit_rex (p, 0, dest, 0, src); - *p->codeptr++ = (opcode->code >> 0) & 0xff; - } + output_opcode (p, opcode, 4, src, dest); switch (opcode->type) { + case ORC_X86_INSN_TYPE_rm_r: case ORC_X86_INSN_TYPE_ED: case ORC_X86_INSN_TYPE_SD: orc_x86_emit_modrm_reg (p, src, dest); break; + case ORC_X86_INSN_TYPE_r_rm: case ORC_X86_INSN_TYPE_SD_REV: case ORC_X86_INSN_TYPE_ED_REV: orc_x86_emit_modrm_reg (p, dest, src); @@ -289,22 +340,7 @@ orc_sse_emit_sysinsn_load_memoffset (OrcCompiler *p, int index, int imm, int off break; } - if (opcode->code & 0xff000000) { - *p->codeptr++ = (opcode->code >> 24) & 0xff; - orc_x86_emit_rex (p, 0, dest, 0, src); - *p->codeptr++ = (opcode->code >> 16) & 0xff; - *p->codeptr++ = (opcode->code >> 8) & 0xff; - *p->codeptr++ = (opcode->code >> 0) & 0xff; - } else if (opcode->code & 0xff0000) { - *p->codeptr++ = (opcode->code >> 16) & 0xff; - orc_x86_emit_rex (p, 0, dest, 0, src); - *p->codeptr++ = (opcode->code >> 8) & 0xff; - *p->codeptr++ = (opcode->code >> 0) & 0xff; - } else { - *p->codeptr++ = (opcode->code >> 8) & 0xff; - orc_x86_emit_rex (p, 0, dest, 0, src); - *p->codeptr++ = (opcode->code >> 0) & 0xff; - } + output_opcode (p, opcode, 4, src, dest); switch (opcode->type) { case ORC_X86_INSN_TYPE_SD: @@ -365,22 +401,7 @@ orc_sse_emit_sysinsn_store_memoffset (OrcCompiler *p, int index, int imm, int of break; } - if (opcode->code & 0xff000000) { - *p->codeptr++ = (opcode->code >> 24) & 0xff; - orc_x86_emit_rex (p, 0, dest, 0, src); - *p->codeptr++ = (opcode->code >> 16) & 0xff; - *p->codeptr++ = (opcode->code >> 8) & 0xff; - *p->codeptr++ = (opcode->code >> 0) & 0xff; - } else if (opcode->code & 0xff0000) { - *p->codeptr++ = (opcode->code >> 16) & 0xff; - orc_x86_emit_rex (p, 0, dest, 0, src); - *p->codeptr++ = (opcode->code >> 8) & 0xff; - *p->codeptr++ = (opcode->code >> 0) & 0xff; - } else { - *p->codeptr++ = (opcode->code >> 8) & 0xff; - orc_x86_emit_rex (p, 0, dest, 0, src); - *p->codeptr++ = (opcode->code >> 0) & 0xff; - } + output_opcode (p, opcode, 4, src, dest); switch (opcode->type) { case ORC_X86_INSN_TYPE_SD: @@ -440,23 +461,7 @@ orc_sse_emit_sysinsn_load_memindex (OrcCompiler *p, int index, int imm, break; } - ORC_ASSERT(opcode->code != 0); - if (opcode->code & 0xff000000) { - *p->codeptr++ = (opcode->code >> 24) & 0xff; - orc_x86_emit_rex (p, 0, dest, 0, src); - *p->codeptr++ = (opcode->code >> 16) & 0xff; - *p->codeptr++ = (opcode->code >> 8) & 0xff; - *p->codeptr++ = (opcode->code >> 0) & 0xff; - } else if (opcode->code & 0xff0000) { - *p->codeptr++ = (opcode->code >> 16) & 0xff; - orc_x86_emit_rex (p, 0, dest, 0, src); - *p->codeptr++ = (opcode->code >> 8) & 0xff; - *p->codeptr++ = (opcode->code >> 0) & 0xff; - } else { - *p->codeptr++ = (opcode->code >> 8) & 0xff; - orc_x86_emit_rex (p, 0, dest, 0, src); - *p->codeptr++ = (opcode->code >> 0) & 0xff; - } + output_opcode (p, opcode, 4, src, dest); switch (opcode->type) { case ORC_X86_INSN_TYPE_SD: @@ -485,3 +490,164 @@ orc_sse_emit_sysinsn_load_memindex (OrcCompiler *p, int index, int imm, } } +void +orc_sse_emit_sysinsn_imm_reg (OrcCompiler *p, int index, int imm, int dest) +{ + const OrcSysOpcode *opcode = orc_x86_opcodes + index; + int size = 4; + + switch (opcode->type) { + case ORC_X86_INSN_TYPE_imm8_rm: + case ORC_X86_INSN_TYPE_imm32_rm: + if (size == 4) { + ORC_ASM_CODE(p," %s $%d, %%%s\n", opcode->name, + imm, + orc_x86_get_regname(dest)); + } else { + ORC_ASM_CODE(p," %s $%d, %%%s\n", opcode->name, + imm, + orc_x86_get_regname_64(dest)); + } + break; + default: + ORC_ASSERT(0); + break; + } + + output_opcode (p, opcode, size, 0, dest); + + switch (opcode->type) { + case ORC_X86_INSN_TYPE_imm8_rm: + orc_x86_emit_modrm_reg (p, dest, opcode->code2); + *p->codeptr++ = imm; + break; + case ORC_X86_INSN_TYPE_imm32_rm: + orc_x86_emit_modrm_reg (p, dest, opcode->code2); + *p->codeptr++ = imm&0xff; + *p->codeptr++ = (imm>>8)&0xff; + *p->codeptr++ = (imm>>16)&0xff; + *p->codeptr++ = (imm>>24)&0xff; + break; + default: + ORC_ASSERT(0); + break; + } +} + +void +orc_sse_emit_sysinsn_imm_memoffset (OrcCompiler *p, int index, int imm, + int offset, int dest) +{ + const OrcSysOpcode *opcode = orc_x86_opcodes + index; + int size = 4; + + switch (opcode->type) { + case ORC_X86_INSN_TYPE_imm8_rm: + case ORC_X86_INSN_TYPE_imm32_rm: + if (size == 4) { + ORC_ASM_CODE(p," %s $%d, %d(%%%s)\n", opcode->name, + imm, offset, + orc_x86_get_regname(dest)); + } else { + ORC_ASM_CODE(p," %s $%d, %d(%%%s)\n", opcode->name, + imm, offset, + orc_x86_get_regname_64(dest)); + } + break; + default: + ORC_ASSERT(0); + break; + } + + output_opcode (p, opcode, size, 0, dest); + + switch (opcode->type) { + case ORC_X86_INSN_TYPE_imm8_rm: + orc_x86_emit_modrm_memoffset (p, offset, dest, opcode->code2); + *p->codeptr++ = imm; + break; + case ORC_X86_INSN_TYPE_imm32_rm: + orc_x86_emit_modrm_memoffset (p, offset, dest, opcode->code2); + *p->codeptr++ = imm&0xff; + *p->codeptr++ = (imm>>8)&0xff; + *p->codeptr++ = (imm>>16)&0xff; + *p->codeptr++ = (imm>>24)&0xff; + break; + default: + ORC_ASSERT(0); + break; + } +} + +void +orc_sse_emit_sysinsn_reg_memoffset (OrcCompiler *p, int index, int src, + int offset, int dest) +{ + const OrcSysOpcode *opcode = orc_x86_opcodes + index; + int size = 4; + + switch (opcode->type) { + case ORC_X86_INSN_TYPE_r_rm: + if (size == 4) { + ORC_ASM_CODE(p," %s %%%s, %d(%%%s)\n", opcode->name, + orc_x86_get_regname(src), offset, + orc_x86_get_regname(dest)); + } else { + ORC_ASM_CODE(p," %s %%%s, %d(%%%s)\n", opcode->name, + orc_x86_get_regname(src), offset, + orc_x86_get_regname_64(dest)); + } + break; + default: + ORC_ASSERT(0); + break; + } + + output_opcode (p, opcode, size, 0, dest); + + switch (opcode->type) { + case ORC_X86_INSN_TYPE_r_rm: + orc_x86_emit_modrm_memoffset (p, offset, dest, src); + break; + default: + ORC_ASSERT(0); + break; + } +} + +void +orc_sse_emit_sysinsn_memoffset_reg (OrcCompiler *p, int index, int offset, + int src, int dest) +{ + const OrcSysOpcode *opcode = orc_x86_opcodes + index; + int size = 4; + + switch (opcode->type) { + case ORC_X86_INSN_TYPE_rm_r: + if (size == 4) { + ORC_ASM_CODE(p," %s %d(%%%s), %%%s\n", opcode->name, + offset, orc_x86_get_regname(src), + orc_x86_get_regname(dest)); + } else { + ORC_ASM_CODE(p," %s %d(%%%s), %%%s\n", opcode->name, + offset, orc_x86_get_regname(src), + orc_x86_get_regname_64(dest)); + } + break; + default: + ORC_ASSERT(0); + break; + } + + output_opcode (p, opcode, size, src, dest); + + switch (opcode->type) { + case ORC_X86_INSN_TYPE_rm_r: + orc_x86_emit_modrm_memoffset (p, offset, src, dest); + break; + default: + ORC_ASSERT(0); + break; + } +} + diff --git a/orc/orcx86insn.h b/orc/orcx86insn.h index 5c830c6..36caf09 100644 --- a/orc/orcx86insn.h +++ b/orc/orcx86insn.h @@ -11,7 +11,11 @@ enum { ORC_X86_INSN_TYPE_SD_REV, ORC_X86_INSN_TYPE_ED, ORC_X86_INSN_TYPE_ED_REV, - ORC_X86_INSN_TYPE_MEM + ORC_X86_INSN_TYPE_MEM, + ORC_X86_INSN_TYPE_imm8_rm, + ORC_X86_INSN_TYPE_imm32_rm, + ORC_X86_INSN_TYPE_rm_r, + ORC_X86_INSN_TYPE_r_rm }; enum { @@ -171,6 +175,38 @@ enum { ORC_X86_movntdq_store, ORC_X86_ldmxcsr, ORC_X86_stmxcsr, + ORC_X86_add_imm8_rm, + ORC_X86_add_imm32_rm, + ORC_X86_add_rm_r, + ORC_X86_add_r_rm, + ORC_X86_or_imm8_rm, + ORC_X86_or_imm32_rm, + ORC_X86_or_rm_r, + ORC_X86_or_r_rm, + ORC_X86_adc_imm8_rm, + ORC_X86_adc_imm32_rm, + ORC_X86_adc_rm_r, + ORC_X86_adc_r_rm, + ORC_X86_sbb_imm8_rm, + ORC_X86_sbb_imm32_rm, + ORC_X86_sbb_rm_r, + ORC_X86_sbb_r_rm, + ORC_X86_and_imm8_rm, + ORC_X86_and_imm32_rm, + ORC_X86_and_rm_r, + ORC_X86_and_r_rm, + ORC_X86_sub_imm8_rm, + ORC_X86_sub_imm32_rm, + ORC_X86_sub_rm_r, + ORC_X86_sub_r_rm, + ORC_X86_xor_imm8_rm, + ORC_X86_xor_imm32_rm, + ORC_X86_xor_rm_r, + ORC_X86_xor_r_rm, + ORC_X86_cmp_imm8_rm, + ORC_X86_cmp_imm32_rm, + ORC_X86_cmp_rm_r, + ORC_X86_cmp_r_rm, }; -- 2.7.4