From 7c1c3fdd4cbb495824fb80b751e72831cd7a10fa Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sun, 5 Dec 2010 17:47:26 -0800 Subject: [PATCH] cpuinsn: Fix code generation breakage on x86_64 --- orc/orcx86.h | 3 ++- orc/orcx86insn.c | 43 ++++++++++++++++++++++++++++++++++++------- orc/orcx86insn.h | 2 ++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/orc/orcx86.h b/orc/orcx86.h index 2eb5ecd..2c6b3b5 100644 --- a/orc/orcx86.h +++ b/orc/orcx86.h @@ -70,7 +70,8 @@ void orc_x86_emit_pop (OrcCompiler *compiler, int size, int reg); ORC_X86_and_imm8_rm : ORC_X86_and_imm32_rm, size, value, offset, reg) #define orc_x86_emit_and_imm_reg(p,size,value,reg) \ orc_x86_emit_cpuinsn_imm_reg (p, (value >= -128 && value < 128) ? \ - ORC_X86_and_imm8_rm : ORC_X86_and_imm32_rm, size, value, reg) + ORC_X86_and_imm8_rm : \ + (reg == X86_EAX ? ORC_X86_and_imm32_a : ORC_X86_and_imm32_rm), size, value, reg) #define orc_x86_emit_add_imm_memoffset(p,size,value,offset,reg) \ orc_x86_emit_cpuinsn_imm_memoffset (p, (value >= -128 && value < 128) ? \ ORC_X86_add_imm8_rm : ORC_X86_add_imm32_rm, size, value, offset, reg) diff --git a/orc/orcx86insn.c b/orc/orcx86insn.c index 6ec87cc..0abcbd9 100644 --- a/orc/orcx86insn.c +++ b/orc/orcx86insn.c @@ -244,6 +244,7 @@ static const OrcSysOpcode orc_x86_opcodes[] = { { "decl", ORC_X86_INSN_TYPE_MEM, 0, 0xff, 1 }, { "sar", ORC_X86_INSN_TYPE_imm8_rm, 0, 0xc1, 7 }, { "sar", ORC_X86_INSN_TYPE_MEM, 0, 0xd1, 7 }, + { "and", ORC_X86_INSN_TYPE_imm32_a, 0, 0x25 }, }; @@ -255,6 +256,7 @@ output_opcode (OrcCompiler *p, const OrcSysOpcode *opcode, int size, if (opcode->code & 0xff000000) { if ((opcode->code & 0xff000000) == 0x66000000 || + (opcode->code & 0xff000000) == 0xf2000000 || (opcode->code & 0xff000000) == 0xf3000000) { *p->codeptr++ = (opcode->code >> 24) & 0xff; orc_x86_emit_rex (p, size, dest, 0, src); @@ -267,6 +269,7 @@ output_opcode (OrcCompiler *p, const OrcSysOpcode *opcode, int size, *p->codeptr++ = (opcode->code >> 0) & 0xff; } else if (opcode->code & 0xff0000) { if ((opcode->code & 0xff0000) == 0x660000 || + (opcode->code & 0xff0000) == 0xf20000 || (opcode->code & 0xff0000) == 0xf30000) { *p->codeptr++ = (opcode->code >> 16) & 0xff; orc_x86_emit_rex (p, size, dest, 0, src); @@ -278,6 +281,7 @@ output_opcode (OrcCompiler *p, const OrcSysOpcode *opcode, int size, *p->codeptr++ = (opcode->code >> 0) & 0xff; } else if (opcode->code & 0xff00) { if ((opcode->code & 0xff00) == 0x6600 || + (opcode->code & 0xff00) == 0xf200 || (opcode->code & 0xff00) == 0xf300) { *p->codeptr++ = (opcode->code >> 8) & 0xff; orc_x86_emit_rex (p, size, dest, 0, src); @@ -342,10 +346,19 @@ orc_x86_emit_cpuinsn (OrcCompiler *p, int index, int imm, int src, int dest) break; } - if (opcode->type == ORC_X86_INSN_TYPE_SHIFTIMM) { - output_opcode (p, opcode, 4, dest, 0); - } else if (opcode->type != ORC_X86_INSN_TYPE_STACK) { - output_opcode (p, opcode, 4, src, dest); + switch (opcode->type) { + case ORC_X86_INSN_TYPE_SHIFTIMM: + output_opcode (p, opcode, 4, dest, 0); + break; + case ORC_X86_INSN_TYPE_STACK: + break; + case ORC_X86_INSN_TYPE_SD_REV: + case ORC_X86_INSN_TYPE_ED_REV: + output_opcode (p, opcode, 4, dest, src); + break; + default: + output_opcode (p, opcode, 4, src, dest); + break; } switch (opcode->type) { @@ -483,7 +496,16 @@ orc_x86_emit_cpuinsn_store_memoffset (OrcCompiler *p, int index, int size, break; } - output_opcode (p, opcode, 4, src, dest); + switch (opcode->type) { + default: + output_opcode (p, opcode, 4, src, dest); + break; + case ORC_X86_INSN_TYPE_SDI_REV: + case ORC_X86_INSN_TYPE_SD_REV: + case ORC_X86_INSN_TYPE_ED_REV: + output_opcode (p, opcode, 4, dest, src); + break; + } switch (opcode->type) { case ORC_X86_INSN_TYPE_SD: @@ -590,6 +612,7 @@ orc_x86_emit_cpuinsn_imm_reg (OrcCompiler *p, int index, int size, int imm, case ORC_X86_INSN_TYPE_imm8_rm: case ORC_X86_INSN_TYPE_imm32_rm: case ORC_X86_INSN_TYPE_mov_imm32: + case ORC_X86_INSN_TYPE_imm32_a: if (size == 4) { ORC_ASM_CODE(p," %s $%d, %%%s\n", opcode->name, imm, @@ -630,6 +653,12 @@ orc_x86_emit_cpuinsn_imm_reg (OrcCompiler *p, int index, int size, int imm, *p->codeptr++ = (imm>>16)&0xff; *p->codeptr++ = (imm>>24)&0xff; break; + case ORC_X86_INSN_TYPE_imm32_a: + *p->codeptr++ = imm&0xff; + *p->codeptr++ = (imm>>8)&0xff; + *p->codeptr++ = (imm>>16)&0xff; + *p->codeptr++ = (imm>>24)&0xff; + break; case ORC_X86_INSN_TYPE_mov_imm32: *p->codeptr++ = opcode->code + (dest&7); *p->codeptr++ = imm&0xff; @@ -718,12 +747,12 @@ orc_x86_emit_cpuinsn_reg_memoffset (OrcCompiler *p, int index, int src, break; } - output_opcode (p, opcode, size, 0, dest); + output_opcode (p, opcode, size, dest, src); switch (opcode->type) { case ORC_X86_INSN_TYPE_r_rm: - case ORC_X86_INSN_TYPE_r_rm_byte: case ORC_X86_INSN_TYPE_r_rm_word: + case ORC_X86_INSN_TYPE_r_rm_byte: orc_x86_emit_modrm_memoffset (p, offset, dest, src); break; default: diff --git a/orc/orcx86insn.h b/orc/orcx86insn.h index 62522d8..aaa33dc 100644 --- a/orc/orcx86insn.h +++ b/orc/orcx86insn.h @@ -22,6 +22,7 @@ enum { ORC_X86_INSN_TYPE_mov_imm32, ORC_X86_INSN_TYPE_r_rm_byte, ORC_X86_INSN_TYPE_r_rm_word, + ORC_X86_INSN_TYPE_imm32_a, }; enum { @@ -260,6 +261,7 @@ enum { ORC_X86_dec, ORC_X86_sar_imm, ORC_X86_sar, + ORC_X86_and_imm32_a, }; -- 2.7.4