summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Schleef <ds@ginger.bigkitten.com>2008-05-26 22:14:39 -0700
committerDavid Schleef <ds@ginger.bigkitten.com>2008-05-26 22:14:39 -0700
commit486e63504ffc558be68effcfffb315d18a0cfb82 (patch)
treee593c399ce54bb2530f45b3aba04aa268d4b5d7e
parent97fbf6b517bc7c39c404e780d110328093423175 (diff)
downloadliboil-486e63504ffc558be68effcfffb315d18a0cfb82.tar.gz
[orc] split up x86 related files
-rw-r--r--orc/Makefile.am9
-rw-r--r--orc/orcprogram-x86.c1166
-rw-r--r--orc/orcrules-mmx.c163
-rw-r--r--orc/orcrules-sse.c163
-rw-r--r--orc/orcrules-x86.c146
-rw-r--r--orc/x86.c666
-rw-r--r--orc/x86.h95
7 files changed, 1247 insertions, 1161 deletions
diff --git a/orc/Makefile.am b/orc/Makefile.am
index 098d0d5..bb0d56e 100644
--- a/orc/Makefile.am
+++ b/orc/Makefile.am
@@ -17,9 +17,14 @@ liborc_@LIBOIL_MAJORMINOR@_la_SOURCES = \
orcprogram-powerpc.c \
orcprogram.h \
orcopcodes.c \
- orcprogram-linux.c
+ orcprogram-linux.c \
+ orcrules-mmx.c \
+ orcrules-x86.c \
+ orcrules-sse.c \
+ x86.c
pkginclude_HEADERS = \
orc.h \
- orcprogram.h
+ orcprogram.h \
+ x86.h
diff --git a/orc/orcprogram-x86.c b/orc/orcprogram-x86.c
index 0778ad2..cb811c3 100644
--- a/orc/orcprogram-x86.c
+++ b/orc/orcprogram-x86.c
@@ -10,206 +10,28 @@
#include <sys/mman.h>
#include <orc/orcprogram.h>
+#include <orc/x86.h>
#define SIZE 65536
-void x86_emit_push (OrcProgram *program, int size, int reg);
-void x86_emit_pop (OrcProgram *program, int size, int reg);
-void x86_emit_mov_memoffset_reg (OrcProgram *program, int size, int offset, int reg1, int reg2);
-void x86_emit_mov_memoffset_mmx (OrcProgram *program, int size, int offset,
- int reg1, int reg2);
-void x86_emit_mov_reg_memoffset (OrcProgram *program, int size, int reg1, int offset, int reg2);
-void x86_emit_mov_mmx_memoffset (OrcProgram *program, int size, int reg1, int offset,
- int reg2);
-void x86_emit_mov_imm_reg (OrcProgram *program, int size, int value, int reg1);
-void x86_emit_mov_reg_reg (OrcProgram *program, int size, int reg1, int reg2);
-void x86_emit_mov_reg_mmx (OrcProgram *program, int reg1, int reg2);
-void x86_emit_mov_mmx_reg (OrcProgram *program, int reg1, int reg2);
-void x86_emit_test_reg_reg (OrcProgram *program, int size, int reg1, int reg2);
-void x86_emit_sar_imm_reg (OrcProgram *program, int size, int value, int reg);
-void x86_emit_dec_memoffset (OrcProgram *program, int size, int offset, int reg);
-void x86_emit_add_imm_memoffset (OrcProgram *program, int size, int value, int offset, int reg);
-void x86_emit_and_imm_memoffset (OrcProgram *program, int size, int value, int offset, int reg);
-void x86_emit_add_imm_reg (OrcProgram *program, int size, int value, int reg);
-void x86_emit_and_imm_reg (OrcProgram *program, int size, int value, int reg);
-void x86_emit_cmp_imm_memoffset (OrcProgram *program, int size, int value,
- int offset, int reg);
-void x86_emit_emms (OrcProgram *program);
-void x86_emit_ret (OrcProgram *program);
-void x86_emit_je (OrcProgram *program, int label);
-void x86_emit_jne (OrcProgram *program, int label);
-void x86_emit_label (OrcProgram *program, int label);
-
void x86_emit_loop (OrcProgram *program);
-static void mmx_emit_loadi_s16 (OrcProgram *p, int reg, int value);
-
-void x86_emit_modrm_memoffset (OrcProgram *program, int reg1, int offset, int reg2);
-void x86_emit_modrm_reg (OrcProgram *program, int reg1, int reg2);
-void x86_test (OrcProgram *program);
void orc_program_x86_register_rules (void);
void orc_program_mmx_register_rules (void);
void orc_program_sse_register_rules (void);
-enum {
- X86_EAX = ORC_GP_REG_BASE,
- X86_ECX,
- X86_EDX,
- X86_EBX,
- X86_ESP,
- X86_EBP,
- X86_ESI,
- X86_EDI,
- X86_R8,
- X86_R9,
- X86_R10,
- X86_R11,
- X86_R12,
- X86_R13,
- X86_R14,
- X86_R15,
- X86_MM0 = ORC_VEC1_REG_BASE,
- X86_MM1,
- X86_MM2,
- X86_MM3,
- X86_MM4,
- X86_MM5,
- X86_MM6,
- X86_MM7,
- X86_XMM0 = ORC_VEC2_REG_BASE,
- X86_XMM1,
- X86_XMM2,
- X86_XMM3,
- X86_XMM4,
- X86_XMM5,
- X86_XMM6,
- X86_XMM7,
- X86_XMM8,
- X86_XMM9,
- X86_XMM10,
- X86_XMM11,
- X86_XMM12,
- X86_XMM13,
- X86_XMM14,
- X86_XMM15
-};
-
#ifdef HAVE_AMD64
-static int x86_64 = 1;
-static int x86_ptr_size = 8;
-static int x86_exec_ptr = X86_EDI;
+int x86_64 = 1;
+int x86_ptr_size = 8;
+int x86_exec_ptr = X86_EDI;
#else
-static int x86_64 = 0;
-static int x86_ptr_size = 4;
-static int x86_exec_ptr = X86_EBP;
+int x86_64 = 0;
+int x86_ptr_size = 4;
+int x86_exec_ptr = X86_EBP;
#endif
-static const char *
-x86_get_regname(int i)
-{
- static const char *x86_regs[] = {
- "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
- "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" };
-
- if (i>=ORC_GP_REG_BASE && i<ORC_GP_REG_BASE + 16) return x86_regs[i - ORC_GP_REG_BASE];
- switch (i) {
- case 0:
- return "UNALLOCATED";
- case 1:
- return "direct";
- default:
- printf("register %d\n", i);
- return "ERROR";
- }
-}
-
-static int
-x86_get_regnum(int i)
-{
- return (i&0xf);
-}
-
-static const char *
-x86_get_regname_16(int i)
-{
- static const char *x86_regs[] = { "ax", "cx", "dx", "bx",
- "sp", "bp", "si", "di" };
-
- if (i>=ORC_GP_REG_BASE && i<ORC_GP_REG_BASE + 8) return x86_regs[i - ORC_GP_REG_BASE];
- switch (i) {
- case 0:
- return "UNALLOCATED";
- case 1:
- return "direct";
- default:
- return "ERROR";
- }
-}
-
-const char *
-x86_get_regname_64(int i)
-{
- static const char *x86_regs[] = {
- "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" };
-
- if (i>=ORC_GP_REG_BASE && i<ORC_GP_REG_BASE + 16) return x86_regs[i - ORC_GP_REG_BASE];
- switch (i) {
- case 0:
- return "UNALLOCATED";
- case 1:
- return "direct";
- default:
- return "ERROR";
- }
-}
-
-const char *
-x86_get_regname_ptr(int i)
-{
- if (x86_64) {
- return x86_get_regname_64 (i);
- } else {
- return x86_get_regname (i);
- }
-}
-
-static const char *
-x86_get_regname_mmx(int i)
-{
- static const char *x86_regs[] = { "mm0", "mm1", "mm2", "mm3",
- "mm4", "mm5", "mm6", "mm7" };
-
- if (i>=X86_MM0 && i<X86_MM0 + 8) return x86_regs[i - X86_MM0];
- switch (i) {
- case 0:
- return "UNALLOCATED";
- case 1:
- return "direct";
- default:
- return "ERROR";
- }
-}
-
-static const char *
-x86_get_regname_sse(int i)
-{
- static const char *x86_regs[] = { "xmm0", "xmm1", "xmm2", "xmm3",
- "xmm4", "xmm5", "xmm6", "xmm7" };
-
- if (i>=X86_XMM0 && i<X86_XMM0 + 8) return x86_regs[i - X86_XMM0];
- switch (i) {
- case 0:
- return "UNALLOCATED";
- case 1:
- return "direct";
- default:
- return "ERROR";
- }
-}
-
int
orc_program_x86_allocate_register (OrcProgram *program, int data_reg)
{
@@ -595,977 +417,3 @@ x86_emit_loop (OrcProgram *program)
}
}
-/* rules */
-
-static void
-x86_rule_loadi_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- x86_emit_mov_imm_reg (p, 2, p->vars[insn->args[2]].s16,
- p->vars[insn->args[0]].alloc);
-}
-
-static void
-x86_rule_add_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- if (insn->rule_flag == ORC_RULE_REG_IMM) {
- int value = p->vars[insn->args[2]].s16;
- printf(" addw $%d, %%%s\n", value,
- x86_get_regname_16(p->vars[insn->args[0]].alloc));
-
- if (value >= -128 && value < 128) {
- *p->codeptr++ = 0x66;
- *p->codeptr++ = 0x83;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 0);
- *p->codeptr++ = value;
- } else {
- *p->codeptr++ = 0x66;
- *p->codeptr++ = 0x81;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 0);
- *p->codeptr++ = value & 0xff;
- *p->codeptr++ = value >> 8;
- }
- } else {
- printf(" addw %%%s, %%%s\n",
- x86_get_regname_16(p->vars[insn->args[2]].alloc),
- x86_get_regname_16(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x66;
- *p->codeptr++ = 0x03;
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
- }
-}
-
-static void
-x86_rule_sub_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- printf(" subw %%%s, %%%s\n",
- x86_get_regname_16(p->vars[insn->args[2]].alloc),
- x86_get_regname_16(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x66;
- *p->codeptr++ = 0x2b;
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
-}
-
-static void
-x86_rule_mul_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- printf(" imulw %%%s, %%%s\n",
- x86_get_regname_16(p->vars[insn->args[2]].alloc),
- x86_get_regname_16(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x66;
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0xaf;
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
-}
-
-static void
-x86_rule_lshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- x86_emit_mov_reg_reg(p, 4, p->vars[insn->args[2]].alloc, X86_ECX);
-
- printf(" shlw %%cl, %%%s\n",
- x86_get_regname_16(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x66;
- *p->codeptr++ = 0xd3;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 4);
-}
-
-static void
-x86_rule_rshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- if (insn->rule_flag == ORC_RULE_REG_IMM) {
- printf(" sarw $%d, %%%s\n",
- p->vars[insn->args[2]].s16,
- x86_get_regname_16(p->vars[insn->args[0]].alloc));
-
- if (p->vars[insn->args[2]].s16 == 1) {
- *p->codeptr++ = 0x66;
- *p->codeptr++ = 0xd1;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 7);
- } else {
- *p->codeptr++ = 0x66;
- *p->codeptr++ = 0xc1;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 7);
- *p->codeptr++ = p->vars[insn->args[2]].s16;
- }
- } else {
- x86_emit_mov_reg_reg(p, 4, p->vars[insn->args[2]].alloc, X86_ECX);
-
- printf(" sarw %%cl, %%%s\n",
- x86_get_regname_16(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x66;
- *p->codeptr++ = 0xd3;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 7);
- }
-}
-
-
-void
-orc_program_x86_register_rules (void)
-{
- orc_rule_register ("_loadi_s16", ORC_RULE_SCALAR_1, x86_rule_loadi_s16, NULL,
- ORC_RULE_REG_IMM);
-
- orc_rule_register ("add_s16", ORC_RULE_SCALAR_1, x86_rule_add_s16, NULL,
- ORC_RULE_REG_REG | ORC_RULE_REG_IMM);
- orc_rule_register ("sub_s16", ORC_RULE_SCALAR_1, x86_rule_sub_s16, NULL,
- ORC_RULE_REG_REG);
- orc_rule_register ("mul_s16", ORC_RULE_SCALAR_1, x86_rule_mul_s16, NULL,
- ORC_RULE_REG_REG);
- orc_rule_register ("lshift_s16", ORC_RULE_SCALAR_1, x86_rule_lshift_s16, NULL,
- ORC_RULE_REG_REG);
- orc_rule_register ("rshift_s16", ORC_RULE_SCALAR_1, x86_rule_rshift_s16, NULL,
- ORC_RULE_REG_REG | ORC_RULE_REG_IMM);
-}
-
-/* mmx rules */
-
-static void
-mmx_emit_loadi_s16 (OrcProgram *p, int reg, int value)
-{
- if (value == 0) {
- printf(" pxor %%%s, %%%s\n", x86_get_regname_mmx(reg),
- x86_get_regname_mmx(reg));
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0xef;
- x86_emit_modrm_reg (p, reg, reg);
- } else {
- x86_emit_mov_imm_reg (p, 4, value, X86_ECX);
-
- printf(" movd %%ecx, %%%s\n", x86_get_regname_mmx(reg));
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0x6e;
- x86_emit_modrm_reg (p, X86_ECX, reg);
-
- printf(" pshufw $0, %%%s, %%%s\n", x86_get_regname_mmx(reg),
- x86_get_regname_mmx(reg));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0x70;
- x86_emit_modrm_reg (p, reg, reg);
- *p->codeptr++ = 0x00;
- }
-}
-
-static void
-mmx_rule_loadi_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- mmx_emit_loadi_s16 (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[2]].s16);
-}
-
-static void
-mmx_rule_add_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- printf(" paddw %%%s, %%%s\n",
- x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
- x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0xfd;
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
-}
-
-static void
-mmx_rule_sub_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- printf(" psubw %%%s, %%%s\n",
- x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
- x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0xf9;
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
-}
-
-static void
-mmx_rule_mul_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- printf(" pmullw %%%s, %%%s\n",
- x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
- x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0xd5;
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
-}
-
-static void
-mmx_rule_lshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
- printf(" psllw $%d, %%%s\n",
- p->vars[insn->args[2]].s16,
- x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0x71;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 6);
- *p->codeptr++ = p->vars[insn->args[2]].s16;
- } else {
- /* FIXME this doesn't work quite right */
- printf(" psllw %%%s, %%%s\n",
- x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
- x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0xf1;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[2]].alloc);
- }
-}
-
-static void
-mmx_rule_rshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
- printf(" psraw $%d, %%%s\n",
- p->vars[insn->args[2]].s16,
- x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0x71;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 4);
- *p->codeptr++ = p->vars[insn->args[2]].s16;
- } else {
- /* FIXME this doesn't work quite right */
- printf(" psraw %%%s, %%%s\n",
- x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
- x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0xe1;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[2]].alloc);
- }
-}
-
-void
-orc_program_mmx_register_rules (void)
-{
- int i;
-
- orc_rule_register ("_loadi_s16", ORC_RULE_MMX_4, mmx_rule_loadi_s16, NULL,
- ORC_RULE_REG_IMM);
-
- for(i=ORC_RULE_MMX_1; i <= ORC_RULE_MMX_4; i++) {
- orc_rule_register ("add_s16", i, mmx_rule_add_s16, NULL,
- ORC_RULE_REG_REG);
- orc_rule_register ("sub_s16", i, mmx_rule_sub_s16, NULL,
- ORC_RULE_REG_REG);
- orc_rule_register ("mul_s16", i, mmx_rule_mul_s16, NULL,
- ORC_RULE_REG_REG);
- orc_rule_register ("lshift_s16", i, mmx_rule_lshift_s16, NULL,
- ORC_RULE_REG_REG);
- orc_rule_register ("rshift_s16", i, mmx_rule_rshift_s16, NULL,
- ORC_RULE_REG_REG);
- }
-}
-
-/* sse rules */
-
-static void
-sse_emit_loadi_s16 (OrcProgram *p, int reg, int value)
-{
- if (value == 0) {
- printf(" pxor %%%s, %%%s\n", x86_get_regname_sse(reg),
- x86_get_regname_sse(reg));
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0xef;
- x86_emit_modrm_reg (p, reg, reg);
- } else {
- x86_emit_mov_imm_reg (p, 4, value, X86_ECX);
-
- printf(" movd %%ecx, %%%s\n", x86_get_regname_sse(reg));
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0x6e;
- x86_emit_modrm_reg (p, X86_ECX, reg);
-
- printf(" pshufw $0, %%%s, %%%s\n", x86_get_regname_sse(reg),
- x86_get_regname_sse(reg));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0x70;
- x86_emit_modrm_reg (p, reg, reg);
- *p->codeptr++ = 0x00;
- }
-}
-
-static void
-sse_rule_loadi_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- sse_emit_loadi_s16 (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[2]].s16);
-}
-
-static void
-sse_rule_add_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- printf(" paddw %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[2]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0xfd;
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
-}
-
-static void
-sse_rule_sub_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- printf(" psubw %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[2]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0xf9;
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
-}
-
-static void
-sse_rule_mul_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- printf(" pmullw %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[2]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0xd5;
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
-}
-
-static void
-sse_rule_lshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
- printf(" psllw $%d, %%%s\n",
- p->vars[insn->args[2]].s16,
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0x71;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 6);
- *p->codeptr++ = p->vars[insn->args[2]].s16;
- } else {
- /* FIXME this doesn't work quite right */
- printf(" psllw %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[2]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0xf1;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[2]].alloc);
- }
-}
-
-static void
-sse_rule_rshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
-{
- if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
- printf(" psraw $%d, %%%s\n",
- p->vars[insn->args[2]].s16,
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0x71;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 4);
- *p->codeptr++ = p->vars[insn->args[2]].s16;
- } else {
- /* FIXME this doesn't work quite right */
- printf(" psraw %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[2]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
-
- *p->codeptr++ = 0x0f;
- *p->codeptr++ = 0xe1;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[2]].alloc);
- }
-}
-
-void
-orc_program_sse_register_rules (void)
-{
- int i;
-
- orc_rule_register ("_loadi_s16", ORC_RULE_SSE_4, sse_rule_loadi_s16, NULL,
- ORC_RULE_REG_IMM);
-
- for(i=ORC_RULE_SSE_1; i <= ORC_RULE_SSE_8; i++) {
- orc_rule_register ("add_s16", i, sse_rule_add_s16, NULL,
- ORC_RULE_REG_REG);
- orc_rule_register ("sub_s16", i, sse_rule_sub_s16, NULL,
- ORC_RULE_REG_REG);
- orc_rule_register ("mul_s16", i, sse_rule_mul_s16, NULL,
- ORC_RULE_REG_REG);
- orc_rule_register ("lshift_s16", i, sse_rule_lshift_s16, NULL,
- ORC_RULE_REG_REG);
- orc_rule_register ("rshift_s16", i, sse_rule_rshift_s16, NULL,
- ORC_RULE_REG_REG);
- }
-}
-
-/* code generation */
-
-void
-x86_emit_push (OrcProgram *program, int size, int reg)
-{
-
- if (size == 1) {
- program->error = 1;
- } else if (size == 2) {
- printf(" pushw %%%s\n", x86_get_regname_16(reg));
- *program->codeptr++ = 0x66;
- *program->codeptr++ = 0x50 + x86_get_regnum(reg);
- } else {
- printf(" pushl %%%s\n", x86_get_regname(reg));
- *program->codeptr++ = 0x50 + x86_get_regnum(reg);
- }
-}
-
-void
-x86_emit_pop (OrcProgram *program, int size, int reg)
-{
-
- if (size == 1) {
- program->error = 1;
- } else if (size == 2) {
- printf(" popw %%%s\n", x86_get_regname_16(reg));
- *program->codeptr++ = 0x66;
- *program->codeptr++ = 0x58 + x86_get_regnum(reg);
- } else {
- printf(" popl %%%s\n", x86_get_regname(reg));
- *program->codeptr++ = 0x58 + x86_get_regnum(reg);
- }
-}
-
-#define X86_MODRM(mod, rm, reg) ((((mod)&3)<<6)|(((rm)&7)<<0)|(((reg)&7)<<3))
-#define X86_SIB(ss, ind, reg) ((((ss)&3)<<6)|(((ind)&7)<<3)|((reg)&7))
-
-void
-x86_emit_modrm_memoffset (OrcProgram *program, int reg1, int offset, int reg2)
-{
- if (offset == 0 && reg2 != x86_exec_ptr) {
- if (reg2 == X86_ESP) {
- *program->codeptr++ = X86_MODRM(0, 4, reg1);
- *program->codeptr++ = X86_SIB(0, 4, reg2);
- } else {
- *program->codeptr++ = X86_MODRM(0, reg2, reg1);
- }
- } else if (offset >= -128 && offset < 128) {
- *program->codeptr++ = X86_MODRM(1, reg2, reg1);
- if (reg2 == X86_ESP) {
- *program->codeptr++ = X86_SIB(0, 4, reg2);
- }
- *program->codeptr++ = (offset & 0xff);
- } else {
- *program->codeptr++ = X86_MODRM(2, reg2, reg1);
- if (reg2 == X86_ESP) {
- *program->codeptr++ = X86_SIB(0, 4, reg2);
- }
- *program->codeptr++ = (offset & 0xff);
- *program->codeptr++ = ((offset>>8) & 0xff);
- *program->codeptr++ = ((offset>>16) & 0xff);
- *program->codeptr++ = ((offset>>24) & 0xff);
- }
-}
-
-void
-x86_emit_modrm_reg (OrcProgram *program, int reg1, int reg2)
-{
- *program->codeptr++ = X86_MODRM(3, reg1, reg2);
-}
-
-void
-x86_emit_rex (OrcProgram *program, int size, int reg1, int reg2, int reg3)
-{
- int rex = 0x40;
-
- if (x86_64) {
- if (size >= 8) rex |= 0x08;
- if (reg1 == 1 || (x86_get_regnum(reg1)>=8)) rex |= 0x4;
- if (reg2 == 1 || (x86_get_regnum(reg2)>=8)) rex |= 0x2;
- if (reg3 == 1 || (x86_get_regnum(reg3)>=8)) rex |= 0x1;
-
- if (rex != 0x40) *program->codeptr++ = rex;
- //*program->codeptr++ = rex;
- }
-}
-
-void
-x86_emit_mov_memoffset_reg (OrcProgram *program, int size, int offset,
- int reg1, int reg2)
-{
-
- if (size == 2) {
- printf(" movw %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
- x86_get_regname_16(reg2));
- *program->codeptr++ = 0x66;
- } else if (size == 4) {
- printf(" movl %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
- x86_get_regname(reg2));
- } else {
- printf(" mov %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
- x86_get_regname_64(reg2));
- }
-
- x86_emit_rex(program, size, reg2, 0, reg1);
- *program->codeptr++ = 0x8b;
- x86_emit_modrm_memoffset (program, reg2, offset, reg1);
-}
-
-void
-x86_emit_mov_memoffset_mmx (OrcProgram *program, int size, int offset,
- int reg1, int reg2)
-{
- if (size == 4) {
- printf(" movd %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
- x86_get_regname_mmx(reg2));
- x86_emit_rex(program, 0, reg2, 0, reg1);
- *program->codeptr++ = 0x0f;
- *program->codeptr++ = 0x6e;
- } else {
- printf(" movq %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
- x86_get_regname_mmx(reg2));
- x86_emit_rex(program, 0, reg2, 0, reg1);
- *program->codeptr++ = 0x0f;
- *program->codeptr++ = 0x6f;
- }
- x86_emit_modrm_memoffset (program, reg2, offset, reg1);
-}
-
-void
-x86_emit_mov_reg_memoffset (OrcProgram *program, int size, int reg1, int offset,
- int reg2)
-{
- if (size == 2) {
- printf(" movw %%%s, %d(%%%s)\n", x86_get_regname_16(reg1), offset,
- x86_get_regname_ptr(reg2));
- *program->codeptr++ = 0x66;
- } else if (size == 4) {
- printf(" movl %%%s, %d(%%%s)\n", x86_get_regname(reg1), offset,
- x86_get_regname_ptr(reg2));
- } else {
- printf(" mov %%%s, %d(%%%s)\n", x86_get_regname(reg1), offset,
- x86_get_regname_ptr(reg2));
- }
-
- x86_emit_rex(program, size, reg1, 0, reg2);
- *program->codeptr++ = 0x89;
- x86_emit_modrm_memoffset (program, reg1, offset, reg2);
-}
-
-void
-x86_emit_mov_mmx_memoffset (OrcProgram *program, int size, int reg1, int offset,
- int reg2)
-{
- x86_emit_rex(program, 0, reg1, 0, reg2);
- if (size == 4) {
- printf(" movd %%%s, %d(%%%s)\n", x86_get_regname_mmx(reg1), offset,
- x86_get_regname_ptr(reg2));
- *program->codeptr++ = 0x0f;
- *program->codeptr++ = 0x7e;
- } else if (size == 8) {
- printf(" movq %%%s, %d(%%%s)\n", x86_get_regname_mmx(reg1), offset,
- x86_get_regname_ptr(reg2));
- *program->codeptr++ = 0x0f;
- *program->codeptr++ = 0x7f;
- }
-
- x86_emit_modrm_memoffset (program, reg1, offset, reg2);
-}
-
-void
-x86_emit_mov_imm_reg (OrcProgram *program, int size, int value, int reg1)
-{
- if (size == 2) {
- printf(" movw $%d, %%%s\n", value, x86_get_regname_16(reg1));
- x86_emit_rex(program, size, reg1, 0, 0);
- *program->codeptr++ = 0x66;
- *program->codeptr++ = 0xb8 + x86_get_regnum(reg1);
- *program->codeptr++ = (value & 0xff);
- *program->codeptr++ = ((value>>8) & 0xff);
- } else if (size == 4) {
- printf(" movl $%d, %%%s\n", value, x86_get_regname(reg1));
- x86_emit_rex(program, size, reg1, 0, 0);
- *program->codeptr++ = 0xb8 + x86_get_regnum(reg1);
- *program->codeptr++ = (value & 0xff);
- *program->codeptr++ = ((value>>8) & 0xff);
- *program->codeptr++ = ((value>>16) & 0xff);
- *program->codeptr++ = ((value>>24) & 0xff);
- } else {
- /* FIXME */
- }
-
-}
-
-void x86_emit_mov_reg_reg (OrcProgram *program, int size, int reg1, int reg2)
-{
- if (size == 2) {
- printf(" movw %%%s, %%%s\n", x86_get_regname_16(reg1),
- x86_get_regname_16(reg2));
- *program->codeptr++ = 0x66;
- } else if (size == 4) {
- printf(" movl %%%s, %%%s\n", x86_get_regname(reg1),
- x86_get_regname(reg2));
- } else {
- printf(" mov %%%s, %%%s\n", x86_get_regname_64(reg1),
- x86_get_regname_64(reg2));
- }
-
- x86_emit_rex(program, size, reg2, 0, reg1);
- *program->codeptr++ = 0x89;
- x86_emit_modrm_reg (program, reg2, reg1);
-}
-
-void x86_emit_mov_reg_mmx (OrcProgram *program, int reg1, int reg2)
-{
- /* FIXME */
- printf(" movd %%%s, %%%s\n", x86_get_regname(reg1),
- x86_get_regname_mmx(reg2));
- x86_emit_rex(program, 0, reg1, 0, reg2);
- *program->codeptr++ = 0x0f;
- *program->codeptr++ = 0x6e;
- x86_emit_modrm_reg (program, reg1, reg2);
-}
-
-void x86_emit_mov_mmx_reg (OrcProgram *program, int reg1, int reg2)
-{
- /* FIXME */
- printf(" movd %%%s, %%%s\n", x86_get_regname_mmx(reg1),
- x86_get_regname(reg2));
- x86_emit_rex(program, 0, reg2, 0, reg1);
- *program->codeptr++ = 0x0f;
- *program->codeptr++ = 0x7e;
- x86_emit_modrm_reg (program, reg2, reg1);
-}
-
-void
-x86_emit_test_reg_reg (OrcProgram *program, int size, int reg1, int reg2)
-{
- if (size == 2) {
- printf(" testw %%%s, %%%s\n", x86_get_regname_16(reg1),
- x86_get_regname_16(reg2));
- *program->codeptr++ = 0x66;
- } else if (size == 4) {
- printf(" testl %%%s, %%%s\n", x86_get_regname(reg1),
- x86_get_regname(reg2));
- } else {
- printf(" test %%%s, %%%s\n", x86_get_regname(reg1),
- x86_get_regname(reg2));
- }
-
- x86_emit_rex(program, size, reg2, 0, reg1);
- *program->codeptr++ = 0x85;
- x86_emit_modrm_reg (program, reg2, reg1);
-}
-
-void
-x86_emit_sar_imm_reg (OrcProgram *program, int size, int value, int reg)
-{
- if (size == 2) {
- printf(" sarw $%d, %%%s\n", value, x86_get_regname_16(reg));
- } else if (size == 4) {
- printf(" sarl $%d, %%%s\n", value, x86_get_regname(reg));
- } else {
- printf(" sar $%d, %%%s\n", value, x86_get_regname_64(reg));
- }
-
- x86_emit_rex(program, size, reg, 0, 0);
- if (value == 1) {
- *program->codeptr++ = 0xd1;
- x86_emit_modrm_reg (program, reg, 7);
- } else {
- *program->codeptr++ = 0xc1;
- x86_emit_modrm_reg (program, reg, 7);
- *program->codeptr++ = value;
- }
-}
-
-void
-x86_emit_and_imm_memoffset (OrcProgram *program, int size, int value,
- int offset, int reg)
-{
- if (size == 2) {
- printf(" andw $%d, %d(%%%s)\n", value, offset,
- x86_get_regname_ptr(reg));
- *program->codeptr++ = 0x66;
- } else if (size == 4) {
- printf(" andl $%d, %d(%%%s)\n", value, offset,
- x86_get_regname_ptr(reg));
- } else {
- printf(" and $%d, %d(%%%s)\n", value, offset,
- x86_get_regname_ptr(reg));
- }
-
- x86_emit_rex(program, size, 0, 0, reg);
- if (value >= -128 && value < 128) {
- *program->codeptr++ = 0x83;
- /* FIXME */
- x86_emit_modrm_memoffset (program, 0, offset, reg);
- *program->codeptr++ = (value & 0xff);
- } else {
- *program->codeptr++ = 0x81;
- /* FIXME */
- x86_emit_modrm_memoffset (program, 0, offset, reg);
- *program->codeptr++ = (value & 0xff);
- *program->codeptr++ = ((value>>8) & 0xff);
- if (size == 4) {
- *program->codeptr++ = ((value>>16) & 0xff);
- *program->codeptr++ = ((value>>24) & 0xff);
- }
- }
-}
-
-void
-x86_emit_and_imm_reg (OrcProgram *program, int size, int value, int reg)
-{
- if (size == 2) {
- printf(" andw $%d, %%%s\n", value, x86_get_regname_16(reg));
- *program->codeptr++ = 0x66;
- } else if (size == 4) {
- printf(" andl $%d, %%%s\n", value, x86_get_regname(reg));
- } else {
- printf(" and $%d, %%%s\n", value, x86_get_regname_64(reg));
- }
-
- x86_emit_rex(program, size, 0, 0, reg);
- if (value >= -128 && value < 128) {
- *program->codeptr++ = 0x83;
- x86_emit_modrm_reg (program, reg, 4);
- *program->codeptr++ = (value & 0xff);
- } else {
- *program->codeptr++ = 0x81;
- x86_emit_modrm_reg (program, reg, 4);
- *program->codeptr++ = (value & 0xff);
- *program->codeptr++ = ((value>>8) & 0xff);
- if (size == 4) {
- *program->codeptr++ = ((value>>16) & 0xff);
- *program->codeptr++ = ((value>>24) & 0xff);
- }
- }
-}
-
-void
-x86_emit_add_imm_memoffset (OrcProgram *program, int size, int value,
- int offset, int reg)
-{
- if (size == 2) {
- printf(" addw $%d, %d(%%%s)\n", value, offset,
- x86_get_regname_ptr(reg));
- *program->codeptr++ = 0x66;
- } else if (size == 4) {
- printf(" addl $%d, %d(%%%s)\n", value, offset,
- x86_get_regname_ptr(reg));
- } else {
- printf(" add $%d, %d(%%%s)\n", value, offset,
- x86_get_regname_ptr(reg));
- }
-
- x86_emit_rex(program, size, 0, 0, reg);
- if (value >= -128 && value < 128) {
- *program->codeptr++ = 0x83;
- x86_emit_modrm_memoffset (program, 0, offset, reg);
- *program->codeptr++ = (value & 0xff);
- } else {
- *program->codeptr++ = 0x81;
- x86_emit_modrm_memoffset (program, 0, offset, reg);
- *program->codeptr++ = (value & 0xff);
- *program->codeptr++ = ((value>>8) & 0xff);
- if (size == 4) {
- *program->codeptr++ = ((value>>16) & 0xff);
- *program->codeptr++ = ((value>>24) & 0xff);
- }
- }
-}
-
-void
-x86_emit_add_imm_reg (OrcProgram *program, int size, int value, int reg)
-{
- if (size == 2) {
- printf(" addw $%d, %%%s\n", value, x86_get_regname_16(reg));
- *program->codeptr++ = 0x66;
- } else if (size == 4) {
- printf(" addl $%d, %%%s\n", value, x86_get_regname(reg));
- } else {
- printf(" add $%d, %%%s\n", value, x86_get_regname_64(reg));
- }
-
- x86_emit_rex(program, size, 0, 0, reg);
- if (value >= -128 && value < 128) {
- *program->codeptr++ = 0x83;
- x86_emit_modrm_reg (program, reg, 0);
- *program->codeptr++ = (value & 0xff);
- } else {
- *program->codeptr++ = 0x81;
- x86_emit_modrm_reg (program, reg, 0);
- *program->codeptr++ = (value & 0xff);
- *program->codeptr++ = ((value>>8) & 0xff);
- if (size == 4) {
- *program->codeptr++ = ((value>>16) & 0xff);
- *program->codeptr++ = ((value>>24) & 0xff);
- }
- }
-}
-
-void
-x86_emit_cmp_imm_memoffset (OrcProgram *program, int size, int value,
- int offset, int reg)
-{
- if (size == 2) {
- printf(" cmpw $%d, %d(%%%s)\n", value, offset,
- x86_get_regname_ptr(reg));
- *program->codeptr++ = 0x66;
- } else if (size == 4) {
- printf(" cmpl $%d, %d(%%%s)\n", value, offset,
- x86_get_regname_ptr(reg));
- } else {
- printf(" cmp $%d, %d(%%%s)\n", value, offset,
- x86_get_regname_ptr(reg));
- }
-
- x86_emit_rex(program, size, 0, 0, reg);
- if (value >= -128 && value < 128) {
- *program->codeptr++ = 0x83;
- x86_emit_modrm_memoffset (program, 7, offset, reg);
- *program->codeptr++ = (value & 0xff);
- } else {
- *program->codeptr++ = 0x81;
- x86_emit_modrm_memoffset (program, 7, offset, reg);
- *program->codeptr++ = (value & 0xff);
- *program->codeptr++ = ((value>>8) & 0xff);
- if (size == 4) {
- *program->codeptr++ = ((value>>16) & 0xff);
- *program->codeptr++ = ((value>>24) & 0xff);
- }
- }
-}
-
-void
-x86_emit_dec_memoffset (OrcProgram *program, int size,
- int offset, int reg)
-{
- if (size == 2) {
- printf(" decw %d(%%%s)\n", offset, x86_get_regname_ptr(reg));
- *program->codeptr++ = 0x66;
- } else if (size == 4) {
- printf(" decl %d(%%%s)\n", offset, x86_get_regname_ptr(reg));
- } else {
- printf(" dec %d(%%%s)\n", offset, x86_get_regname_ptr(reg));
- }
-
- x86_emit_rex(program, size, 0, 0, reg);
- *program->codeptr++ = 0xff;
- x86_emit_modrm_memoffset (program, 1, offset, reg);
-}
-
-void x86_emit_ret (OrcProgram *program)
-{
- if (x86_64) {
- printf(" retq\n");
- } else {
- printf(" ret\n");
- }
- *program->codeptr++ = 0xc3;
-}
-
-void x86_emit_emms (OrcProgram *program)
-{
- printf(" emms\n");
- *program->codeptr++ = 0x0f;
- *program->codeptr++ = 0x77;
-}
-
-void
-x86_add_fixup (OrcProgram *program, unsigned char *ptr, int label)
-{
- program->fixups[program->n_fixups].ptr = ptr;
- program->fixups[program->n_fixups].label = label;
- program->fixups[program->n_fixups].type = 0;
- program->n_fixups++;
-}
-
-void
-x86_add_label (OrcProgram *program, unsigned char *ptr, int label)
-{
- program->labels[label] = ptr;
-}
-
-void x86_emit_je (OrcProgram *program, int label)
-{
- printf(" je .L%d\n", label);
-
- *program->codeptr++ = 0x74;
- x86_add_fixup (program, program->codeptr, label);
- *program->codeptr++ = -1;
-}
-
-void x86_emit_jne (OrcProgram *program, int label)
-{
- printf(" jne .L%d\n", label);
- *program->codeptr++ = 0x75;
- x86_add_fixup (program, program->codeptr, label);
- *program->codeptr++ = -1;
-}
-
-void x86_emit_label (OrcProgram *program, int label)
-{
- printf(".L%d:\n", label);
-
- x86_add_label (program, program->codeptr, label);
-}
-
-void
-x86_test (OrcProgram *program)
-{
- int size;
- int i;
- int j;
- int reg;
-
- for(size=2;size<=4;size+=2) {
- for(i=0;i<8;i++){
- reg = ORC_GP_REG_BASE + i;
- x86_emit_push (program, size, reg);
- x86_emit_pop (program, size, reg);
- x86_emit_mov_imm_reg (program, size, 0, reg);
- x86_emit_mov_imm_reg (program, size, 1, reg);
- x86_emit_mov_imm_reg (program, size, 256, reg);
- x86_emit_dec_memoffset (program, size, 0, reg);
- x86_emit_dec_memoffset (program, size, 1, reg);
- x86_emit_dec_memoffset (program, size, 256, reg);
- x86_emit_add_imm_memoffset (program, size, 1, 0, reg);
- x86_emit_add_imm_memoffset (program, size, 1, 1, reg);
- x86_emit_add_imm_memoffset (program, size, 1, 256, reg);
- x86_emit_add_imm_memoffset (program, size, 256, 0, reg);
- x86_emit_add_imm_memoffset (program, size, 256, 1, reg);
- x86_emit_add_imm_memoffset (program, size, 256, 256, reg);
- for(j=0;j<8;j++){
- int reg2 = ORC_GP_REG_BASE + j;
- x86_emit_mov_reg_reg (program, size, reg, reg2);
- x86_emit_mov_memoffset_reg (program, size, 0, reg, reg2);
- x86_emit_mov_memoffset_reg (program, size, 1, reg, reg2);
- x86_emit_mov_memoffset_reg (program, size, 256, reg, reg2);
- x86_emit_mov_reg_memoffset (program, size, reg, 0, reg2);
- x86_emit_mov_reg_memoffset (program, size, reg, 1, reg2);
- x86_emit_mov_reg_memoffset (program, size, reg, 256, reg2);
- }
- }
- }
-
-}
-
diff --git a/orc/orcrules-mmx.c b/orc/orcrules-mmx.c
new file mode 100644
index 0000000..23248de
--- /dev/null
+++ b/orc/orcrules-mmx.c
@@ -0,0 +1,163 @@
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <orc/orcprogram.h>
+#include <orc/x86.h>
+
+#define SIZE 65536
+
+/* mmx rules */
+
+void
+mmx_emit_loadi_s16 (OrcProgram *p, int reg, int value)
+{
+ if (value == 0) {
+ printf(" pxor %%%s, %%%s\n", x86_get_regname_mmx(reg),
+ x86_get_regname_mmx(reg));
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xef;
+ x86_emit_modrm_reg (p, reg, reg);
+ } else {
+ x86_emit_mov_imm_reg (p, 4, value, X86_ECX);
+
+ printf(" movd %%ecx, %%%s\n", x86_get_regname_mmx(reg));
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x6e;
+ x86_emit_modrm_reg (p, X86_ECX, reg);
+
+ printf(" pshufw $0, %%%s, %%%s\n", x86_get_regname_mmx(reg),
+ x86_get_regname_mmx(reg));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x70;
+ x86_emit_modrm_reg (p, reg, reg);
+ *p->codeptr++ = 0x00;
+ }
+}
+
+static void
+mmx_rule_loadi_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ mmx_emit_loadi_s16 (p, p->vars[insn->args[0]].alloc,
+ p->vars[insn->args[2]].s16);
+}
+
+static void
+mmx_rule_add_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" paddw %%%s, %%%s\n",
+ x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
+ x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xfd;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+mmx_rule_sub_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" psubw %%%s, %%%s\n",
+ x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
+ x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xf9;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+mmx_rule_mul_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" pmullw %%%s, %%%s\n",
+ x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
+ x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xd5;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+mmx_rule_lshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
+ printf(" psllw $%d, %%%s\n",
+ p->vars[insn->args[2]].s16,
+ x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x71;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 6);
+ *p->codeptr++ = p->vars[insn->args[2]].s16;
+ } else {
+ /* FIXME this doesn't work quite right */
+ printf(" psllw %%%s, %%%s\n",
+ x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
+ x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xf1;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
+ p->vars[insn->args[2]].alloc);
+ }
+}
+
+static void
+mmx_rule_rshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
+ printf(" psraw $%d, %%%s\n",
+ p->vars[insn->args[2]].s16,
+ x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x71;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 4);
+ *p->codeptr++ = p->vars[insn->args[2]].s16;
+ } else {
+ /* FIXME this doesn't work quite right */
+ printf(" psraw %%%s, %%%s\n",
+ x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
+ x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xe1;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
+ p->vars[insn->args[2]].alloc);
+ }
+}
+
+void
+orc_program_mmx_register_rules (void)
+{
+ int i;
+
+ orc_rule_register ("_loadi_s16", ORC_RULE_MMX_4, mmx_rule_loadi_s16, NULL,
+ ORC_RULE_REG_IMM);
+
+ for(i=ORC_RULE_MMX_1; i <= ORC_RULE_MMX_4; i++) {
+ orc_rule_register ("add_s16", i, mmx_rule_add_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("sub_s16", i, mmx_rule_sub_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("mul_s16", i, mmx_rule_mul_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("lshift_s16", i, mmx_rule_lshift_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("rshift_s16", i, mmx_rule_rshift_s16, NULL,
+ ORC_RULE_REG_REG);
+ }
+}
+
diff --git a/orc/orcrules-sse.c b/orc/orcrules-sse.c
new file mode 100644
index 0000000..2c56449
--- /dev/null
+++ b/orc/orcrules-sse.c
@@ -0,0 +1,163 @@
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <orc/orcprogram.h>
+#include <orc/x86.h>
+
+#define SIZE 65536
+
+/* sse rules */
+
+static void
+sse_emit_loadi_s16 (OrcProgram *p, int reg, int value)
+{
+ if (value == 0) {
+ printf(" pxor %%%s, %%%s\n", x86_get_regname_sse(reg),
+ x86_get_regname_sse(reg));
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xef;
+ x86_emit_modrm_reg (p, reg, reg);
+ } else {
+ x86_emit_mov_imm_reg (p, 4, value, X86_ECX);
+
+ printf(" movd %%ecx, %%%s\n", x86_get_regname_sse(reg));
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x6e;
+ x86_emit_modrm_reg (p, X86_ECX, reg);
+
+ printf(" pshufw $0, %%%s, %%%s\n", x86_get_regname_sse(reg),
+ x86_get_regname_sse(reg));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x70;
+ x86_emit_modrm_reg (p, reg, reg);
+ *p->codeptr++ = 0x00;
+ }
+}
+
+static void
+sse_rule_loadi_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ sse_emit_loadi_s16 (p, p->vars[insn->args[0]].alloc,
+ p->vars[insn->args[2]].s16);
+}
+
+static void
+sse_rule_add_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" paddw %%%s, %%%s\n",
+ x86_get_regname_sse(p->vars[insn->args[2]].alloc),
+ x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xfd;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+sse_rule_sub_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" psubw %%%s, %%%s\n",
+ x86_get_regname_sse(p->vars[insn->args[2]].alloc),
+ x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xf9;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+sse_rule_mul_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" pmullw %%%s, %%%s\n",
+ x86_get_regname_sse(p->vars[insn->args[2]].alloc),
+ x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xd5;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+sse_rule_lshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
+ printf(" psllw $%d, %%%s\n",
+ p->vars[insn->args[2]].s16,
+ x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x71;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 6);
+ *p->codeptr++ = p->vars[insn->args[2]].s16;
+ } else {
+ /* FIXME this doesn't work quite right */
+ printf(" psllw %%%s, %%%s\n",
+ x86_get_regname_sse(p->vars[insn->args[2]].alloc),
+ x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xf1;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
+ p->vars[insn->args[2]].alloc);
+ }
+}
+
+static void
+sse_rule_rshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
+ printf(" psraw $%d, %%%s\n",
+ p->vars[insn->args[2]].s16,
+ x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x71;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 4);
+ *p->codeptr++ = p->vars[insn->args[2]].s16;
+ } else {
+ /* FIXME this doesn't work quite right */
+ printf(" psraw %%%s, %%%s\n",
+ x86_get_regname_sse(p->vars[insn->args[2]].alloc),
+ x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xe1;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
+ p->vars[insn->args[2]].alloc);
+ }
+}
+
+void
+orc_program_sse_register_rules (void)
+{
+ int i;
+
+ orc_rule_register ("_loadi_s16", ORC_RULE_SSE_4, sse_rule_loadi_s16, NULL,
+ ORC_RULE_REG_IMM);
+
+ for(i=ORC_RULE_SSE_1; i <= ORC_RULE_SSE_8; i++) {
+ orc_rule_register ("add_s16", i, sse_rule_add_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("sub_s16", i, sse_rule_sub_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("mul_s16", i, sse_rule_mul_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("lshift_s16", i, sse_rule_lshift_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("rshift_s16", i, sse_rule_rshift_s16, NULL,
+ ORC_RULE_REG_REG);
+ }
+}
+
diff --git a/orc/orcrules-x86.c b/orc/orcrules-x86.c
new file mode 100644
index 0000000..4becb48
--- /dev/null
+++ b/orc/orcrules-x86.c
@@ -0,0 +1,146 @@
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <orc/orcprogram.h>
+#include <orc/x86.h>
+
+#define SIZE 65536
+
+/* rules */
+
+static void
+x86_rule_loadi_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ x86_emit_mov_imm_reg (p, 2, p->vars[insn->args[2]].s16,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+x86_rule_add_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ if (insn->rule_flag == ORC_RULE_REG_IMM) {
+ int value = p->vars[insn->args[2]].s16;
+ printf(" addw $%d, %%%s\n", value,
+ x86_get_regname_16(p->vars[insn->args[0]].alloc));
+
+ if (value >= -128 && value < 128) {
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x83;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 0);
+ *p->codeptr++ = value;
+ } else {
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x81;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 0);
+ *p->codeptr++ = value & 0xff;
+ *p->codeptr++ = value >> 8;
+ }
+ } else {
+ printf(" addw %%%s, %%%s\n",
+ x86_get_regname_16(p->vars[insn->args[2]].alloc),
+ x86_get_regname_16(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x03;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+ }
+}
+
+static void
+x86_rule_sub_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" subw %%%s, %%%s\n",
+ x86_get_regname_16(p->vars[insn->args[2]].alloc),
+ x86_get_regname_16(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x2b;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+x86_rule_mul_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ printf(" imulw %%%s, %%%s\n",
+ x86_get_regname_16(p->vars[insn->args[2]].alloc),
+ x86_get_regname_16(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0xaf;
+ x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
+ p->vars[insn->args[0]].alloc);
+}
+
+static void
+x86_rule_lshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ x86_emit_mov_reg_reg(p, 4, p->vars[insn->args[2]].alloc, X86_ECX);
+
+ printf(" shlw %%cl, %%%s\n",
+ x86_get_regname_16(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0xd3;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 4);
+}
+
+static void
+x86_rule_rshift_s16 (OrcProgram *p, void *user, OrcInstruction *insn)
+{
+ if (insn->rule_flag == ORC_RULE_REG_IMM) {
+ printf(" sarw $%d, %%%s\n",
+ p->vars[insn->args[2]].s16,
+ x86_get_regname_16(p->vars[insn->args[0]].alloc));
+
+ if (p->vars[insn->args[2]].s16 == 1) {
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0xd1;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 7);
+ } else {
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0xc1;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 7);
+ *p->codeptr++ = p->vars[insn->args[2]].s16;
+ }
+ } else {
+ x86_emit_mov_reg_reg(p, 4, p->vars[insn->args[2]].alloc, X86_ECX);
+
+ printf(" sarw %%cl, %%%s\n",
+ x86_get_regname_16(p->vars[insn->args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0xd3;
+ x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 7);
+ }
+}
+
+
+void
+orc_program_x86_register_rules (void)
+{
+ orc_rule_register ("_loadi_s16", ORC_RULE_SCALAR_1, x86_rule_loadi_s16, NULL,
+ ORC_RULE_REG_IMM);
+
+ orc_rule_register ("add_s16", ORC_RULE_SCALAR_1, x86_rule_add_s16, NULL,
+ ORC_RULE_REG_REG | ORC_RULE_REG_IMM);
+ orc_rule_register ("sub_s16", ORC_RULE_SCALAR_1, x86_rule_sub_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("mul_s16", ORC_RULE_SCALAR_1, x86_rule_mul_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("lshift_s16", ORC_RULE_SCALAR_1, x86_rule_lshift_s16, NULL,
+ ORC_RULE_REG_REG);
+ orc_rule_register ("rshift_s16", ORC_RULE_SCALAR_1, x86_rule_rshift_s16, NULL,
+ ORC_RULE_REG_REG | ORC_RULE_REG_IMM);
+}
+
diff --git a/orc/x86.c b/orc/x86.c
new file mode 100644
index 0000000..7ef3878
--- /dev/null
+++ b/orc/x86.c
@@ -0,0 +1,666 @@
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <orc/orcprogram.h>
+#include <orc/x86.h>
+
+const char *
+x86_get_regname(int i)
+{
+ static const char *x86_regs[] = {
+ "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
+ "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" };
+
+ if (i>=ORC_GP_REG_BASE && i<ORC_GP_REG_BASE + 16) return x86_regs[i - ORC_GP_REG_BASE];
+ switch (i) {
+ case 0:
+ return "UNALLOCATED";
+ case 1:
+ return "direct";
+ default:
+ printf("register %d\n", i);
+ return "ERROR";
+ }
+}
+
+int
+x86_get_regnum(int i)
+{
+ return (i&0xf);
+}
+
+const char *
+x86_get_regname_16(int i)
+{
+ static const char *x86_regs[] = { "ax", "cx", "dx", "bx",
+ "sp", "bp", "si", "di" };
+
+ if (i>=ORC_GP_REG_BASE && i<ORC_GP_REG_BASE + 8) return x86_regs[i - ORC_GP_REG_BASE];
+ switch (i) {
+ case 0:
+ return "UNALLOCATED";
+ case 1:
+ return "direct";
+ default:
+ return "ERROR";
+ }
+}
+
+const char *
+x86_get_regname_64(int i)
+{
+ static const char *x86_regs[] = {
+ "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" };
+
+ if (i>=ORC_GP_REG_BASE && i<ORC_GP_REG_BASE + 16) return x86_regs[i - ORC_GP_REG_BASE];
+ switch (i) {
+ case 0:
+ return "UNALLOCATED";
+ case 1:
+ return "direct";
+ default:
+ return "ERROR";
+ }
+}
+
+const char *
+x86_get_regname_ptr(int i)
+{
+ if (x86_64) {
+ return x86_get_regname_64 (i);
+ } else {
+ return x86_get_regname (i);
+ }
+}
+
+const char *
+x86_get_regname_mmx(int i)
+{
+ static const char *x86_regs[] = { "mm0", "mm1", "mm2", "mm3",
+ "mm4", "mm5", "mm6", "mm7" };
+
+ if (i>=X86_MM0 && i<X86_MM0 + 8) return x86_regs[i - X86_MM0];
+ switch (i) {
+ case 0:
+ return "UNALLOCATED";
+ case 1:
+ return "direct";
+ default:
+ return "ERROR";
+ }
+}
+
+const char *
+x86_get_regname_sse(int i)
+{
+ static const char *x86_regs[] = { "xmm0", "xmm1", "xmm2", "xmm3",
+ "xmm4", "xmm5", "xmm6", "xmm7" };
+
+ if (i>=X86_XMM0 && i<X86_XMM0 + 8) return x86_regs[i - X86_XMM0];
+ switch (i) {
+ case 0:
+ return "UNALLOCATED";
+ case 1:
+ return "direct";
+ default:
+ return "ERROR";
+ }
+}
+
+void
+x86_emit_push (OrcProgram *program, int size, int reg)
+{
+
+ if (size == 1) {
+ program->error = 1;
+ } else if (size == 2) {
+ printf(" pushw %%%s\n", x86_get_regname_16(reg));
+ *program->codeptr++ = 0x66;
+ *program->codeptr++ = 0x50 + x86_get_regnum(reg);
+ } else {
+ printf(" pushl %%%s\n", x86_get_regname(reg));
+ *program->codeptr++ = 0x50 + x86_get_regnum(reg);
+ }
+}
+
+void
+x86_emit_pop (OrcProgram *program, int size, int reg)
+{
+
+ if (size == 1) {
+ program->error = 1;
+ } else if (size == 2) {
+ printf(" popw %%%s\n", x86_get_regname_16(reg));
+ *program->codeptr++ = 0x66;
+ *program->codeptr++ = 0x58 + x86_get_regnum(reg);
+ } else {
+ printf(" popl %%%s\n", x86_get_regname(reg));
+ *program->codeptr++ = 0x58 + x86_get_regnum(reg);
+ }
+}
+
+#define X86_MODRM(mod, rm, reg) ((((mod)&3)<<6)|(((rm)&7)<<0)|(((reg)&7)<<3))
+#define X86_SIB(ss, ind, reg) ((((ss)&3)<<6)|(((ind)&7)<<3)|((reg)&7))
+
+void
+x86_emit_modrm_memoffset (OrcProgram *program, int reg1, int offset, int reg2)
+{
+ if (offset == 0 && reg2 != x86_exec_ptr) {
+ if (reg2 == X86_ESP) {
+ *program->codeptr++ = X86_MODRM(0, 4, reg1);
+ *program->codeptr++ = X86_SIB(0, 4, reg2);
+ } else {
+ *program->codeptr++ = X86_MODRM(0, reg2, reg1);
+ }
+ } else if (offset >= -128 && offset < 128) {
+ *program->codeptr++ = X86_MODRM(1, reg2, reg1);
+ if (reg2 == X86_ESP) {
+ *program->codeptr++ = X86_SIB(0, 4, reg2);
+ }
+ *program->codeptr++ = (offset & 0xff);
+ } else {
+ *program->codeptr++ = X86_MODRM(2, reg2, reg1);
+ if (reg2 == X86_ESP) {
+ *program->codeptr++ = X86_SIB(0, 4, reg2);
+ }
+ *program->codeptr++ = (offset & 0xff);
+ *program->codeptr++ = ((offset>>8) & 0xff);
+ *program->codeptr++ = ((offset>>16) & 0xff);
+ *program->codeptr++ = ((offset>>24) & 0xff);
+ }
+}
+
+void
+x86_emit_modrm_reg (OrcProgram *program, int reg1, int reg2)
+{
+ *program->codeptr++ = X86_MODRM(3, reg1, reg2);
+}
+
+void
+x86_emit_rex (OrcProgram *program, int size, int reg1, int reg2, int reg3)
+{
+ int rex = 0x40;
+
+ if (x86_64) {
+ if (size >= 8) rex |= 0x08;
+ if (reg1 == 1 || (x86_get_regnum(reg1)>=8)) rex |= 0x4;
+ if (reg2 == 1 || (x86_get_regnum(reg2)>=8)) rex |= 0x2;
+ if (reg3 == 1 || (x86_get_regnum(reg3)>=8)) rex |= 0x1;
+
+ if (rex != 0x40) *program->codeptr++ = rex;
+ //*program->codeptr++ = rex;
+ }
+}
+
+void
+x86_emit_mov_memoffset_reg (OrcProgram *program, int size, int offset,
+ int reg1, int reg2)
+{
+
+ if (size == 2) {
+ printf(" movw %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
+ x86_get_regname_16(reg2));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" movl %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
+ x86_get_regname(reg2));
+ } else {
+ printf(" mov %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
+ x86_get_regname_64(reg2));
+ }
+
+ x86_emit_rex(program, size, reg2, 0, reg1);
+ *program->codeptr++ = 0x8b;
+ x86_emit_modrm_memoffset (program, reg2, offset, reg1);
+}
+
+void
+x86_emit_mov_memoffset_mmx (OrcProgram *program, int size, int offset,
+ int reg1, int reg2)
+{
+ if (size == 4) {
+ printf(" movd %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
+ x86_get_regname_mmx(reg2));
+ x86_emit_rex(program, 0, reg2, 0, reg1);
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x6e;
+ } else {
+ printf(" movq %d(%%%s), %%%s\n", offset, x86_get_regname_ptr(reg1),
+ x86_get_regname_mmx(reg2));
+ x86_emit_rex(program, 0, reg2, 0, reg1);
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x6f;
+ }
+ x86_emit_modrm_memoffset (program, reg2, offset, reg1);
+}
+
+void
+x86_emit_mov_reg_memoffset (OrcProgram *program, int size, int reg1, int offset,
+ int reg2)
+{
+ if (size == 2) {
+ printf(" movw %%%s, %d(%%%s)\n", x86_get_regname_16(reg1), offset,
+ x86_get_regname_ptr(reg2));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" movl %%%s, %d(%%%s)\n", x86_get_regname(reg1), offset,
+ x86_get_regname_ptr(reg2));
+ } else {
+ printf(" mov %%%s, %d(%%%s)\n", x86_get_regname(reg1), offset,
+ x86_get_regname_ptr(reg2));
+ }
+
+ x86_emit_rex(program, size, reg1, 0, reg2);
+ *program->codeptr++ = 0x89;
+ x86_emit_modrm_memoffset (program, reg1, offset, reg2);
+}
+
+void
+x86_emit_mov_mmx_memoffset (OrcProgram *program, int size, int reg1, int offset,
+ int reg2)
+{
+ x86_emit_rex(program, 0, reg1, 0, reg2);
+ if (size == 4) {
+ printf(" movd %%%s, %d(%%%s)\n", x86_get_regname_mmx(reg1), offset,
+ x86_get_regname_ptr(reg2));
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x7e;
+ } else if (size == 8) {
+ printf(" movq %%%s, %d(%%%s)\n", x86_get_regname_mmx(reg1), offset,
+ x86_get_regname_ptr(reg2));
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x7f;
+ }
+
+ x86_emit_modrm_memoffset (program, reg1, offset, reg2);
+}
+
+void
+x86_emit_mov_imm_reg (OrcProgram *program, int size, int value, int reg1)
+{
+ if (size == 2) {
+ printf(" movw $%d, %%%s\n", value, x86_get_regname_16(reg1));
+ x86_emit_rex(program, size, reg1, 0, 0);
+ *program->codeptr++ = 0x66;
+ *program->codeptr++ = 0xb8 + x86_get_regnum(reg1);
+ *program->codeptr++ = (value & 0xff);
+ *program->codeptr++ = ((value>>8) & 0xff);
+ } else if (size == 4) {
+ printf(" movl $%d, %%%s\n", value, x86_get_regname(reg1));
+ x86_emit_rex(program, size, reg1, 0, 0);
+ *program->codeptr++ = 0xb8 + x86_get_regnum(reg1);
+ *program->codeptr++ = (value & 0xff);
+ *program->codeptr++ = ((value>>8) & 0xff);
+ *program->codeptr++ = ((value>>16) & 0xff);
+ *program->codeptr++ = ((value>>24) & 0xff);
+ } else {
+ /* FIXME */
+ }
+
+}
+
+void x86_emit_mov_reg_reg (OrcProgram *program, int size, int reg1, int reg2)
+{
+ if (size == 2) {
+ printf(" movw %%%s, %%%s\n", x86_get_regname_16(reg1),
+ x86_get_regname_16(reg2));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" movl %%%s, %%%s\n", x86_get_regname(reg1),
+ x86_get_regname(reg2));
+ } else {
+ printf(" mov %%%s, %%%s\n", x86_get_regname_64(reg1),
+ x86_get_regname_64(reg2));
+ }
+
+ x86_emit_rex(program, size, reg2, 0, reg1);
+ *program->codeptr++ = 0x89;
+ x86_emit_modrm_reg (program, reg2, reg1);
+}
+
+void x86_emit_mov_reg_mmx (OrcProgram *program, int reg1, int reg2)
+{
+ /* FIXME */
+ printf(" movd %%%s, %%%s\n", x86_get_regname(reg1),
+ x86_get_regname_mmx(reg2));
+ x86_emit_rex(program, 0, reg1, 0, reg2);
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x6e;
+ x86_emit_modrm_reg (program, reg1, reg2);
+}
+
+void x86_emit_mov_mmx_reg (OrcProgram *program, int reg1, int reg2)
+{
+ /* FIXME */
+ printf(" movd %%%s, %%%s\n", x86_get_regname_mmx(reg1),
+ x86_get_regname(reg2));
+ x86_emit_rex(program, 0, reg2, 0, reg1);
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x7e;
+ x86_emit_modrm_reg (program, reg2, reg1);
+}
+
+void
+x86_emit_test_reg_reg (OrcProgram *program, int size, int reg1, int reg2)
+{
+ if (size == 2) {
+ printf(" testw %%%s, %%%s\n", x86_get_regname_16(reg1),
+ x86_get_regname_16(reg2));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" testl %%%s, %%%s\n", x86_get_regname(reg1),
+ x86_get_regname(reg2));
+ } else {
+ printf(" test %%%s, %%%s\n", x86_get_regname(reg1),
+ x86_get_regname(reg2));
+ }
+
+ x86_emit_rex(program, size, reg2, 0, reg1);
+ *program->codeptr++ = 0x85;
+ x86_emit_modrm_reg (program, reg2, reg1);
+}
+
+void
+x86_emit_sar_imm_reg (OrcProgram *program, int size, int value, int reg)
+{
+ if (size == 2) {
+ printf(" sarw $%d, %%%s\n", value, x86_get_regname_16(reg));
+ } else if (size == 4) {
+ printf(" sarl $%d, %%%s\n", value, x86_get_regname(reg));
+ } else {
+ printf(" sar $%d, %%%s\n", value, x86_get_regname_64(reg));
+ }
+
+ x86_emit_rex(program, size, reg, 0, 0);
+ if (value == 1) {
+ *program->codeptr++ = 0xd1;
+ x86_emit_modrm_reg (program, reg, 7);
+ } else {
+ *program->codeptr++ = 0xc1;
+ x86_emit_modrm_reg (program, reg, 7);
+ *program->codeptr++ = value;
+ }
+}
+
+void
+x86_emit_and_imm_memoffset (OrcProgram *program, int size, int value,
+ int offset, int reg)
+{
+ if (size == 2) {
+ printf(" andw $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" andl $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ } else {
+ printf(" and $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ }
+
+ x86_emit_rex(program, size, 0, 0, reg);
+ if (value >= -128 && value < 128) {
+ *program->codeptr++ = 0x83;
+ /* FIXME */
+ x86_emit_modrm_memoffset (program, 0, offset, reg);
+ *program->codeptr++ = (value & 0xff);
+ } else {
+ *program->codeptr++ = 0x81;
+ /* FIXME */
+ x86_emit_modrm_memoffset (program, 0, offset, reg);
+ *program->codeptr++ = (value & 0xff);
+ *program->codeptr++ = ((value>>8) & 0xff);
+ if (size == 4) {
+ *program->codeptr++ = ((value>>16) & 0xff);
+ *program->codeptr++ = ((value>>24) & 0xff);
+ }
+ }
+}
+
+void
+x86_emit_and_imm_reg (OrcProgram *program, int size, int value, int reg)
+{
+ if (size == 2) {
+ printf(" andw $%d, %%%s\n", value, x86_get_regname_16(reg));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" andl $%d, %%%s\n", value, x86_get_regname(reg));
+ } else {
+ printf(" and $%d, %%%s\n", value, x86_get_regname_64(reg));
+ }
+
+ x86_emit_rex(program, size, 0, 0, reg);
+ if (value >= -128 && value < 128) {
+ *program->codeptr++ = 0x83;
+ x86_emit_modrm_reg (program, reg, 4);
+ *program->codeptr++ = (value & 0xff);
+ } else {
+ *program->codeptr++ = 0x81;
+ x86_emit_modrm_reg (program, reg, 4);
+ *program->codeptr++ = (value & 0xff);
+ *program->codeptr++ = ((value>>8) & 0xff);
+ if (size == 4) {
+ *program->codeptr++ = ((value>>16) & 0xff);
+ *program->codeptr++ = ((value>>24) & 0xff);
+ }
+ }
+}
+
+void
+x86_emit_add_imm_memoffset (OrcProgram *program, int size, int value,
+ int offset, int reg)
+{
+ if (size == 2) {
+ printf(" addw $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" addl $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ } else {
+ printf(" add $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ }
+
+ x86_emit_rex(program, size, 0, 0, reg);
+ if (value >= -128 && value < 128) {
+ *program->codeptr++ = 0x83;
+ x86_emit_modrm_memoffset (program, 0, offset, reg);
+ *program->codeptr++ = (value & 0xff);
+ } else {
+ *program->codeptr++ = 0x81;
+ x86_emit_modrm_memoffset (program, 0, offset, reg);
+ *program->codeptr++ = (value & 0xff);
+ *program->codeptr++ = ((value>>8) & 0xff);
+ if (size == 4) {
+ *program->codeptr++ = ((value>>16) & 0xff);
+ *program->codeptr++ = ((value>>24) & 0xff);
+ }
+ }
+}
+
+void
+x86_emit_add_imm_reg (OrcProgram *program, int size, int value, int reg)
+{
+ if (size == 2) {
+ printf(" addw $%d, %%%s\n", value, x86_get_regname_16(reg));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" addl $%d, %%%s\n", value, x86_get_regname(reg));
+ } else {
+ printf(" add $%d, %%%s\n", value, x86_get_regname_64(reg));
+ }
+
+ x86_emit_rex(program, size, 0, 0, reg);
+ if (value >= -128 && value < 128) {
+ *program->codeptr++ = 0x83;
+ x86_emit_modrm_reg (program, reg, 0);
+ *program->codeptr++ = (value & 0xff);
+ } else {
+ *program->codeptr++ = 0x81;
+ x86_emit_modrm_reg (program, reg, 0);
+ *program->codeptr++ = (value & 0xff);
+ *program->codeptr++ = ((value>>8) & 0xff);
+ if (size == 4) {
+ *program->codeptr++ = ((value>>16) & 0xff);
+ *program->codeptr++ = ((value>>24) & 0xff);
+ }
+ }
+}
+
+void
+x86_emit_cmp_imm_memoffset (OrcProgram *program, int size, int value,
+ int offset, int reg)
+{
+ if (size == 2) {
+ printf(" cmpw $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" cmpl $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ } else {
+ printf(" cmp $%d, %d(%%%s)\n", value, offset,
+ x86_get_regname_ptr(reg));
+ }
+
+ x86_emit_rex(program, size, 0, 0, reg);
+ if (value >= -128 && value < 128) {
+ *program->codeptr++ = 0x83;
+ x86_emit_modrm_memoffset (program, 7, offset, reg);
+ *program->codeptr++ = (value & 0xff);
+ } else {
+ *program->codeptr++ = 0x81;
+ x86_emit_modrm_memoffset (program, 7, offset, reg);
+ *program->codeptr++ = (value & 0xff);
+ *program->codeptr++ = ((value>>8) & 0xff);
+ if (size == 4) {
+ *program->codeptr++ = ((value>>16) & 0xff);
+ *program->codeptr++ = ((value>>24) & 0xff);
+ }
+ }
+}
+
+void
+x86_emit_dec_memoffset (OrcProgram *program, int size,
+ int offset, int reg)
+{
+ if (size == 2) {
+ printf(" decw %d(%%%s)\n", offset, x86_get_regname_ptr(reg));
+ *program->codeptr++ = 0x66;
+ } else if (size == 4) {
+ printf(" decl %d(%%%s)\n", offset, x86_get_regname_ptr(reg));
+ } else {
+ printf(" dec %d(%%%s)\n", offset, x86_get_regname_ptr(reg));
+ }
+
+ x86_emit_rex(program, size, 0, 0, reg);
+ *program->codeptr++ = 0xff;
+ x86_emit_modrm_memoffset (program, 1, offset, reg);
+}
+
+void x86_emit_ret (OrcProgram *program)
+{
+ if (x86_64) {
+ printf(" retq\n");
+ } else {
+ printf(" ret\n");
+ }
+ *program->codeptr++ = 0xc3;
+}
+
+void x86_emit_emms (OrcProgram *program)
+{
+ printf(" emms\n");
+ *program->codeptr++ = 0x0f;
+ *program->codeptr++ = 0x77;
+}
+
+void
+x86_add_fixup (OrcProgram *program, unsigned char *ptr, int label)
+{
+ program->fixups[program->n_fixups].ptr = ptr;
+ program->fixups[program->n_fixups].label = label;
+ program->fixups[program->n_fixups].type = 0;
+ program->n_fixups++;
+}
+
+void
+x86_add_label (OrcProgram *program, unsigned char *ptr, int label)
+{
+ program->labels[label] = ptr;
+}
+
+void x86_emit_je (OrcProgram *program, int label)
+{
+ printf(" je .L%d\n", label);
+
+ *program->codeptr++ = 0x74;
+ x86_add_fixup (program, program->codeptr, label);
+ *program->codeptr++ = -1;
+}
+
+void x86_emit_jne (OrcProgram *program, int label)
+{
+ printf(" jne .L%d\n", label);
+ *program->codeptr++ = 0x75;
+ x86_add_fixup (program, program->codeptr, label);
+ *program->codeptr++ = -1;
+}
+
+void x86_emit_label (OrcProgram *program, int label)
+{
+ printf(".L%d:\n", label);
+
+ x86_add_label (program, program->codeptr, label);
+}
+
+void
+x86_test (OrcProgram *program)
+{
+ int size;
+ int i;
+ int j;
+ int reg;
+
+ for(size=2;size<=4;size+=2) {
+ for(i=0;i<8;i++){
+ reg = ORC_GP_REG_BASE + i;
+ x86_emit_push (program, size, reg);
+ x86_emit_pop (program, size, reg);
+ x86_emit_mov_imm_reg (program, size, 0, reg);
+ x86_emit_mov_imm_reg (program, size, 1, reg);
+ x86_emit_mov_imm_reg (program, size, 256, reg);
+ x86_emit_dec_memoffset (program, size, 0, reg);
+ x86_emit_dec_memoffset (program, size, 1, reg);
+ x86_emit_dec_memoffset (program, size, 256, reg);
+ x86_emit_add_imm_memoffset (program, size, 1, 0, reg);
+ x86_emit_add_imm_memoffset (program, size, 1, 1, reg);
+ x86_emit_add_imm_memoffset (program, size, 1, 256, reg);
+ x86_emit_add_imm_memoffset (program, size, 256, 0, reg);
+ x86_emit_add_imm_memoffset (program, size, 256, 1, reg);
+ x86_emit_add_imm_memoffset (program, size, 256, 256, reg);
+ for(j=0;j<8;j++){
+ int reg2 = ORC_GP_REG_BASE + j;
+ x86_emit_mov_reg_reg (program, size, reg, reg2);
+ x86_emit_mov_memoffset_reg (program, size, 0, reg, reg2);
+ x86_emit_mov_memoffset_reg (program, size, 1, reg, reg2);
+ x86_emit_mov_memoffset_reg (program, size, 256, reg, reg2);
+ x86_emit_mov_reg_memoffset (program, size, reg, 0, reg2);
+ x86_emit_mov_reg_memoffset (program, size, reg, 1, reg2);
+ x86_emit_mov_reg_memoffset (program, size, reg, 256, reg2);
+ }
+ }
+ }
+
+}
+
diff --git a/orc/x86.h b/orc/x86.h
new file mode 100644
index 0000000..a844a32
--- /dev/null
+++ b/orc/x86.h
@@ -0,0 +1,95 @@
+
+#ifndef _ORC_X86_H_
+#define _ORC_X86_H_
+
+#include <unistd.h>
+
+extern int x86_64;
+extern int x86_exec_ptr;
+
+void x86_emit_push (OrcProgram *program, int size, int reg);
+void x86_emit_pop (OrcProgram *program, int size, int reg);
+void x86_emit_mov_memoffset_reg (OrcProgram *program, int size, int offset, int reg1, int reg2);
+void x86_emit_mov_memoffset_mmx (OrcProgram *program, int size, int offset,
+ int reg1, int reg2);
+void x86_emit_mov_reg_memoffset (OrcProgram *program, int size, int reg1, int offset, int reg2);
+void x86_emit_mov_mmx_memoffset (OrcProgram *program, int size, int reg1, int offset,
+ int reg2);
+void x86_emit_mov_imm_reg (OrcProgram *program, int size, int value, int reg1);
+void x86_emit_mov_reg_reg (OrcProgram *program, int size, int reg1, int reg2);
+void x86_emit_mov_reg_mmx (OrcProgram *program, int reg1, int reg2);
+void x86_emit_mov_mmx_reg (OrcProgram *program, int reg1, int reg2);
+void x86_emit_test_reg_reg (OrcProgram *program, int size, int reg1, int reg2);
+void x86_emit_sar_imm_reg (OrcProgram *program, int size, int value, int reg);
+void x86_emit_dec_memoffset (OrcProgram *program, int size, int offset, int reg);
+void x86_emit_add_imm_memoffset (OrcProgram *program, int size, int value, int offset, int reg);
+void x86_emit_and_imm_memoffset (OrcProgram *program, int size, int value, int offset, int reg);
+void x86_emit_add_imm_reg (OrcProgram *program, int size, int value, int reg);
+void x86_emit_and_imm_reg (OrcProgram *program, int size, int value, int reg);
+void x86_emit_cmp_imm_memoffset (OrcProgram *program, int size, int value,
+ int offset, int reg);
+void x86_emit_emms (OrcProgram *program);
+void x86_emit_ret (OrcProgram *program);
+void x86_emit_je (OrcProgram *program, int label);
+void x86_emit_jne (OrcProgram *program, int label);
+void x86_emit_label (OrcProgram *program, int label);
+
+void x86_emit_modrm_memoffset (OrcProgram *program, int reg1, int offset, int reg2);
+void x86_emit_modrm_reg (OrcProgram *program, int reg1, int reg2);
+void x86_test (OrcProgram *program);
+
+void mmx_emit_loadi_s16 (OrcProgram *p, int reg, int value);
+
+enum {
+ X86_EAX = ORC_GP_REG_BASE,
+ X86_ECX,
+ X86_EDX,
+ X86_EBX,
+ X86_ESP,
+ X86_EBP,
+ X86_ESI,
+ X86_EDI,
+ X86_R8,
+ X86_R9,
+ X86_R10,
+ X86_R11,
+ X86_R12,
+ X86_R13,
+ X86_R14,
+ X86_R15,
+ X86_MM0 = ORC_VEC1_REG_BASE,
+ X86_MM1,
+ X86_MM2,
+ X86_MM3,
+ X86_MM4,
+ X86_MM5,
+ X86_MM6,
+ X86_MM7,
+ X86_XMM0 = ORC_VEC2_REG_BASE,
+ X86_XMM1,
+ X86_XMM2,
+ X86_XMM3,
+ X86_XMM4,
+ X86_XMM5,
+ X86_XMM6,
+ X86_XMM7,
+ X86_XMM8,
+ X86_XMM9,
+ X86_XMM10,
+ X86_XMM11,
+ X86_XMM12,
+ X86_XMM13,
+ X86_XMM14,
+ X86_XMM15
+};
+
+const char * x86_get_regname(int i);
+int x86_get_regnum(int i);
+const char * x86_get_regname_16(int i);
+const char * x86_get_regname_64(int i);
+const char * x86_get_regname_ptr(int i);
+const char * x86_get_regname_mmx(int i);
+const char * x86_get_regname_sse(int i);
+
+#endif
+