BINARY(xorl,"pxor",0xef)
+#if 0
static void
sse_rule_shlw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
ORC_PROGRAM_ERROR(p,"rule only works with constants or params");
}
}
+#endif
+
+static void
+sse_rule_shift (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ int type = (int)user;
+ int imm_code1[] = { 0x71, 0x71, 0x71, 0x72, 0x72, 0x72 };
+ int imm_code2[] = { 6, 2, 4, 6, 2, 4 };
+ int reg_code[] = { 0xf1, 0xd1, 0xe1, 0xf2, 0xd2, 0xe2 };
+ //const char *code[] = { "psllw", "psrlw", "psraw", "pslld", "psrld", "psrad" };
+
+ if (p->vars[insn->src_args[1]].vartype == ORC_VAR_TYPE_CONST) {
+ ORC_ASM_CODE(p," %s $%d, %%%s\n", code[type],
+ p->vars[insn->src_args[1]].value,
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = imm_code1[type];
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc, imm_code2[type]);
+ *p->codeptr++ = p->vars[insn->src_args[1]].value;
+ } else if (p->vars[insn->src_args[1]].vartype == ORC_VAR_TYPE_PARAM) {
+ /* FIXME this is a gross hack to reload the register with a
+ * 64-bit version of the parameter. */
+ ORC_ASM_CODE(p," movd %d(%%%s), %%%s\n",
+ (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->src_args[1]]),
+ x86_get_regname_ptr(x86_exec_ptr),
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc));
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = 0x6e;
+ x86_emit_modrm_memoffset (p,
+ p->vars[insn->src_args[1]].alloc,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->src_args[1]]),
+ x86_exec_ptr);
+
+ ORC_ASM_CODE(p," %s %%%s, %%%s\n", code[type],
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
+
+ *p->codeptr++ = 0x66;
+ *p->codeptr++ = 0x0f;
+ *p->codeptr++ = reg_code[type];
+ x86_emit_modrm_reg (p, p->vars[insn->src_args[1]].alloc,
+ p->vars[insn->dest_args[0]].alloc);
+ } else {
+ ORC_PROGRAM_ERROR(p,"rule only works with constants or params");
+ }
+}
static void
sse_rule_convsbw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
ORC_ASM_CODE(p," punpcklbw %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_sse(p->vars[insn->src_args[0]].alloc),
x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x60;
x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc,
- p->vars[insn->src_args[1]].alloc);
+ p->vars[insn->src_args[0]].alloc);
ORC_ASM_CODE(p," psraw $8, %%%s\n",
x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
/* FIXME should do this by unpacking with a zero reg */
ORC_ASM_CODE(p," punpcklbw %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_sse(p->vars[insn->src_args[0]].alloc),
x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x60;
x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc,
- p->vars[insn->src_args[1]].alloc);
+ p->vars[insn->src_args[0]].alloc);
ORC_ASM_CODE(p," psrlw $8, %%%s\n",
x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
sse_rule_convsuswb (OrcCompiler *p, void *user, OrcInstruction *insn)
{
ORC_ASM_CODE(p," packuswb %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_sse(p->vars[insn->src_args[0]].alloc),
x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x67;
x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc,
- p->vars[insn->src_args[1]].alloc);
+ p->vars[insn->src_args[0]].alloc);
}
void
orc_rule_register (rule_set, "copyw", sse_rule_copyx, NULL);
orc_rule_register (rule_set, "copyl", sse_rule_copyx, NULL);
- orc_rule_register (rule_set, "shlw", sse_rule_shlw, NULL);
- orc_rule_register (rule_set, "shrsw", sse_rule_shrsw, NULL);
+ //orc_rule_register (rule_set, "shlw", sse_rule_shlw, NULL);
+ //orc_rule_register (rule_set, "shrsw", sse_rule_shrsw, NULL);
+
+ orc_rule_register (rule_set, "shlw", sse_rule_shift, (void *)0);
+ orc_rule_register (rule_set, "shruw", sse_rule_shift, (void *)1);
+ orc_rule_register (rule_set, "shrsw", sse_rule_shift, (void *)2);
+ orc_rule_register (rule_set, "shll", sse_rule_shift, (void *)3);
+ orc_rule_register (rule_set, "shrul", sse_rule_shift, (void *)4);
+ orc_rule_register (rule_set, "shrsl", sse_rule_shift, (void *)5);
orc_rule_register (rule_set, "convsbw", sse_rule_convsbw, NULL);
orc_rule_register (rule_set, "convubw", sse_rule_convubw, NULL);
void x86_emit_jmp (OrcCompiler *compiler, int label)
{
- ORC_ASM_CODE(compiler," jmp .L%d\n", label);
+ ORC_ASM_CODE(compiler," jmp %d%c\n", label,
+ (compiler->labels[label]!=NULL) ? 'b' : 'f');
if (compiler->long_jumps) {
ORC_PROGRAM_ERROR(compiler, "unimplemented");
void x86_emit_jle (OrcCompiler *compiler, int label)
{
- ORC_ASM_CODE(compiler," jle .L%d\n", label);
+ ORC_ASM_CODE(compiler," jle %d%c\n", label,
+ (compiler->labels[label]!=NULL) ? 'b' : 'f');
if (compiler->long_jumps) {
ORC_PROGRAM_ERROR(compiler, "unimplemented");
void x86_emit_je (OrcCompiler *compiler, int label)
{
- ORC_ASM_CODE(compiler," je .L%d\n", label);
+ ORC_ASM_CODE(compiler," je %d%c\n", label,
+ (compiler->labels[label]!=NULL) ? 'b' : 'f');
if (compiler->long_jumps) {
*compiler->codeptr++ = 0x0f;
void x86_emit_jne (OrcCompiler *compiler, int label)
{
- ORC_ASM_CODE(compiler," jne .L%d\n", label);
+ ORC_ASM_CODE(compiler," jne %d%c\n", label,
+ (compiler->labels[label]!=NULL) ? 'b' : 'f');
if (compiler->long_jumps) {
*compiler->codeptr++ = 0x0f;
void x86_emit_label (OrcCompiler *compiler, int label)
{
- ORC_ASM_CODE(compiler,".L%d:\n", label);
+ ORC_ASM_CODE(compiler,"%d:\n", label);
x86_add_label (compiler, compiler->codeptr, label);
}
x86_emit_prologue (OrcCompiler *compiler)
{
orc_compiler_append_code(compiler,".global %s\n", compiler->program->name);
+ orc_compiler_append_code(compiler,".p2align 4\n");
orc_compiler_append_code(compiler,"%s:\n", compiler->program->name);
if (x86_64) {
int i;
--- /dev/null
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <orc/orc.h>
+
+
+int error = FALSE;
+
+void test_opcode (const char *name);
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+ OrcOpcodeSet *opcode_set;
+
+ orc_init();
+
+ opcode_set = orc_opcode_set_get ("sys");
+
+ for(i=0;i<opcode_set->n_opcodes;i++){
+ printf("/* %s %d,%d,%d %p */\n",
+ opcode_set->opcodes[i].name,
+ opcode_set->opcodes[i].dest_size[0],
+ opcode_set->opcodes[i].src_size[0],
+ opcode_set->opcodes[i].src_size[1],
+ opcode_set->opcodes[i].emulate);
+ test_opcode (opcode_set->opcodes[i].name);
+ }
+
+ if (error) return 1;
+ return 0;
+}
+
+void
+test_opcode (const char *name)
+{
+ OrcProgram *p;
+ char s[40];
+ char cmd[200];
+ int ret;
+ FILE *file;
+
+ p = orc_program_new_dss (2,2,2);
+
+ sprintf(s, "test_%s", name);
+ orc_program_set_name (p, s);
+ orc_program_add_constant (p, 2, 1, "c1");
+
+ orc_program_append_str (p, name, "d1", "s1", "c1");
+
+ ret = orc_program_compile (p);
+ if (!ret) {
+ error = TRUE;
+ goto out;
+ }
+
+ fflush (stdout);
+
+ file = fopen ("tmp-test5.s", "w");
+ fprintf(file, "%s", orc_program_get_asm_code (p));
+ fclose (file);
+
+ file = fopen ("dump", "w");
+ ret = fwrite(p->code, p->code_size, 1, file);
+ fclose (file);
+
+ ret = system ("gcc -Wall -c tmp-test5.s");
+ if (ret != 0) {
+ printf("gcc failed\n");
+ error = TRUE;
+ }
+
+ ret = system ("objdump -dr tmp-test5.o >tmp-test5.dis");
+ if (ret != 0) {
+ printf("objdump failed\n");
+ error = TRUE;
+ goto out;
+ }
+
+ sprintf (cmd, "objcopy -I binary -O elf32-i386 -B i386 "
+ "--rename-section .data=.text "
+ "--redefine-sym _binary_dump_start=%s "
+ "dump tmp-test5.o", s);
+ ret = system (cmd);
+ if (ret != 0) {
+ printf("objcopy failed\n");
+ error = TRUE;
+ goto out;
+ }
+
+ ret = system ("objdump -Dr tmp-test5.o >tmp-test5-dump.dis");
+ if (ret != 0) {
+ printf("objdump failed\n");
+ error = TRUE;
+ goto out;
+ }
+
+ ret = system ("diff -u tmp-test5.dis tmp-test5-dump.dis");
+ if (ret != 0) {
+ printf("diff failed\n");
+ error = TRUE;
+ goto out;
+ }
+
+out:
+ orc_program_free (p);
+}
+
+