From: David Schleef Date: Fri, 29 May 2009 04:35:39 +0000 (-0700) Subject: split powerpc files X-Git-Tag: orc-0.4.0~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fd98d146079cf3ae2db3a81358379df42b331bc3;p=platform%2Fupstream%2Forc.git split powerpc files --- diff --git a/orc/Makefile.am b/orc/Makefile.am index 7cea88d..dbab597 100644 --- a/orc/Makefile.am +++ b/orc/Makefile.am @@ -18,17 +18,19 @@ liborc_@ORC_MAJORMINOR@_la_SOURCES = \ orccompiler.c \ orcprogram-arm.c \ orcprogram-c.c \ - orcprogram-powerpc.c \ + orcprogram-altivec.c \ orcprogram-mmx.c \ orcprogram-sse.c \ orcprogram.h \ orcopcodes.c \ orcparse.c \ + orcrules-altivec.c \ orcrules-mmx.c \ orcrules-sse.c \ orcrules-arm.c \ orcdebug.c \ orcutils.c \ + orcpowerpc.c \ orcsse.c \ orcmmx.c \ orcx86.c \ @@ -57,7 +59,8 @@ pkginclude_HEADERS = \ orcsse.h \ orcmmx.h \ orcx86.h \ - orcarm.h + orcarm.h \ + orcpowerpc.h nodist_pkginclude_HEADERS = orc-stdint.h diff --git a/orc/orc.h b/orc/orc.h index 43884ab..2cf6c7b 100644 --- a/orc/orc.h +++ b/orc/orc.h @@ -3,15 +3,16 @@ #define _ORC_ORC_H_ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #endif diff --git a/orc/orcpowerpc.c b/orc/orcpowerpc.c new file mode 100644 index 0000000..38f08d0 --- /dev/null +++ b/orc/orcpowerpc.c @@ -0,0 +1,435 @@ + +#include "config.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include + + +void orc_compiler_powerpc_init (OrcCompiler *compiler); +void orc_compiler_powerpc_assemble (OrcCompiler *compiler); +void orc_compiler_powerpc_register_rules (OrcTarget *target); + +const char * +powerpc_get_regname(int i) +{ + static const char *powerpc_regs[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", + "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", + "r30", "r31", + "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", + "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", + "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", + "v30", "v31", + }; + + if (i>=ORC_GP_REG_BASE && icodeptr++ = (insn>>24); + *compiler->codeptr++ = (insn>>16); + *compiler->codeptr++ = (insn>>8); + *compiler->codeptr++ = (insn>>0); +} + +void +powerpc_emit_addi (OrcCompiler *compiler, int regd, int rega, int imm) +{ + unsigned int insn; + + ORC_ASM_CODE(compiler," addi %s, %s, %d\n", + powerpc_get_regname(regd), + powerpc_get_regname(rega), imm); + insn = (14<<26) | (powerpc_regnum (regd)<<21) | (powerpc_regnum (rega)<<16); + insn |= imm&0xffff; + + powerpc_emit (compiler, insn); +} + +void +powerpc_emit_lwz (OrcCompiler *compiler, int regd, int rega, int imm) +{ + unsigned int insn; + + ORC_ASM_CODE(compiler," lwz %s, %d(%s)\n", + powerpc_get_regname(regd), + imm, powerpc_get_regname(rega)); + insn = (32<<26) | (powerpc_regnum (regd)<<21) | (powerpc_regnum (rega)<<16); + insn |= imm&0xffff; + + powerpc_emit (compiler, insn); +} + +void +powerpc_emit_stwu (OrcCompiler *compiler, int regs, int rega, int offset) +{ + unsigned int insn; + + ORC_ASM_CODE(compiler," stwu %s, %d(%s)\n", + powerpc_get_regname(regs), + offset, powerpc_get_regname(rega)); + insn = (37<<26) | (powerpc_regnum (regs)<<21) | (powerpc_regnum (rega)<<16); + insn |= offset&0xffff; + + powerpc_emit (compiler, insn); +} + +void +powerpc_emit_srawi (OrcCompiler *compiler, int regd, int rega, int shift, + int record) +{ + unsigned int insn; + + ORC_ASM_CODE(compiler," srawi%s %s, %s, %d\n", (record)?".":"", + powerpc_get_regname(regd), + powerpc_get_regname(rega), shift); + + insn = (31<<26) | (powerpc_regnum (regd)<<21) | (powerpc_regnum (rega)<<16); + insn |= (shift<<11) | (824<<1) | record; + + powerpc_emit (compiler, insn); +} + +void +powerpc_emit_655510 (OrcCompiler *compiler, int major, int d, int a, int b, + int minor) +{ + unsigned int insn; + + insn = (major<<26) | (d<<21) | (a<<16); + insn |= (b<<11) | (minor<<0); + + powerpc_emit (compiler, insn); +} + +void +powerpc_emit_X (OrcCompiler *compiler, unsigned int insn, int d, int a, int b) +{ +#if 0 + unsigned int insn; + + insn = (major<<26) | (d<<21) | (a<<16); + insn |= (b<<11) | (minor<<1) | (0<<0); + + powerpc_emit (compiler, insn); +#endif + insn |= ((d&0x1f)<<21); + insn |= ((a&0x1f)<<16); + insn |= ((b&0x1f)<<11); + powerpc_emit (compiler, insn); +} + +void +powerpc_emit_VA (OrcCompiler *compiler, int major, int d, int a, int b, + int c, int minor) +{ + unsigned int insn; + + insn = (major<<26) | (d<<21) | (a<<16); + insn |= (b<<11) | (c<<6) | (minor<<0); + + powerpc_emit (compiler, insn); +} + +void +powerpc_emit_VX (OrcCompiler *compiler, unsigned int insn, int d, int a, int b) +{ + insn |= ((d&0x1f)<<21); + insn |= ((a&0x1f)<<16); + insn |= ((b&0x1f)<<11); + powerpc_emit (compiler, insn); +} + +void +powerpc_emit_VX_2 (OrcCompiler *p, const char *name, + unsigned int insn, int d, int a, int b) +{ + ORC_ASM_CODE(p," %s %s, %s, %s\n", name, + powerpc_get_regname(d), + powerpc_get_regname(a), + powerpc_get_regname(b)); + powerpc_emit_VX(p, insn, + powerpc_regnum(d), + powerpc_regnum(a), + powerpc_regnum(b)); +} + +void +powerpc_do_fixups (OrcCompiler *compiler) +{ + int i; + unsigned int insn; + + for(i=0;in_fixups;i++){ + if (compiler->fixups[i].type == 0) { + unsigned char *label = compiler->labels[compiler->fixups[i].label]; + unsigned char *ptr = compiler->fixups[i].ptr; + + insn = *(unsigned int *)ptr; + *(unsigned int *)ptr = (insn&0xffff0000) | ((insn + (label-ptr))&0xffff); + } else { + unsigned char *label = compiler->labels[compiler->fixups[i].label]; + unsigned char *ptr = compiler->fixups[i].ptr; + + insn = *(unsigned int *)ptr; + *(unsigned int *)ptr = (insn&0xffff0000) | ((insn + (label-compiler->program->code))&0xffff); + } + } +} + +void +powerpc_flush (OrcCompiler *compiler) +{ +#ifdef HAVE_POWERPC + unsigned char *ptr; + int cache_line_size = 32; + int i; + int size = compiler->codeptr - compiler->program->code; + + ptr = compiler->program->code; + for (i=0;iprogram->code_exec; + for (i=0;iconstants[i].value; + int greg = POWERPC_R31; + int label_skip, label_data; + +#if 0 + switch (p->constants[i].type) { + case ORC_CONST_ZERO: + powerpc_emit_VX_2(p, "vxor", 0x100004c4, reg, reg, reg); + break; + case ORC_CONST_SPLAT_B: + if (value < 16 && value >= -16) { + ORC_ASM_CODE(p," vspltisb %s, %d\n", + powerpc_get_regname(reg), value&0x1f); + powerpc_emit_VX(p, 0x1000020c, + powerpc_regnum(reg), value & 0x1f, 0); + } else { + ORC_COMPILER_ERROR(p,"can't load constant"); + } + break; + case ORC_CONST_SPLAT_W: + if (value < 16 && value >= -16) { + ORC_ASM_CODE(p," vspltish %s, %d\n", + powerpc_get_regname(reg), value&0x1f); + powerpc_emit_VX(p, 0x1000024c, + powerpc_regnum(reg), value & 0x1f, 0); + } else { + ORC_COMPILER_ERROR(p,"can't load constant"); + } + break; + case ORC_CONST_SPLAT_L: + if (value < 16 && value >= -16) { + ORC_ASM_CODE(p," vspltisw %s, %d\n", + powerpc_get_regname(reg), value&0x1f); + powerpc_emit_VX(p, 0x1000028c, + powerpc_regnum(reg), value & 0x1f, 0); + } else { + ORC_COMPILER_ERROR(p,"can't load constant"); + } + break; + default: + ORC_COMPILER_ERROR(p,"unhandled"); + break; + } +#endif + + switch (p->constants[i].type) { + case ORC_CONST_ZERO: + for(j=0;j<4;j++){ + p->constants[i].full_value[j] = 0; + } + break; + case ORC_CONST_SPLAT_B: + value &= 0xff; + value |= (value<<8); + value |= (value<<16); + for(j=0;j<4;j++){ + p->constants[i].full_value[j] = value; + } + break; + case ORC_CONST_SPLAT_W: + value &= 0xffff; + value |= (value<<16); + for(j=0;j<4;j++){ + p->constants[i].full_value[j] = value; + } + break; + case ORC_CONST_SPLAT_L: + for(j=0;j<4;j++){ + p->constants[i].full_value[j] = value; + } + break; + default: + break; + } + + label_skip = orc_compiler_label_new (p); + label_data = orc_compiler_label_new (p); + + powerpc_emit_b (p, label_skip); + + while ((p->codeptr - p->program->code) & 0xf) { + ORC_ASM_CODE(p," .long 0x00000000\n"); + powerpc_emit (p, 0x00000000); + } + + powerpc_emit_label (p, label_data); + for(j=0;j<4;j++){ + ORC_ASM_CODE(p," .long 0x%08x\n", p->constants[i].full_value[j]); + powerpc_emit (p, p->constants[i].full_value[j]); + } + + powerpc_emit_label (p, label_skip); + powerpc_emit_lwz (p, + greg, + POWERPC_R3, + (int)ORC_STRUCT_OFFSET(OrcExecutor, program)); + powerpc_emit_lwz (p, + greg, greg, + (int)ORC_STRUCT_OFFSET(OrcProgram, code_exec)); + + powerpc_add_fixup (p, 1, p->codeptr, label_data); + { + unsigned int insn; + + ORC_ASM_CODE(p," addi %s, %s, %db - %s\n", + powerpc_get_regname(greg), + powerpc_get_regname(greg), label_data, p->program->name); + insn = (14<<26) | (powerpc_regnum (greg)<<21) | (powerpc_regnum (greg)<<16); + insn |= 0; + + powerpc_emit (p, insn); + } + + ORC_ASM_CODE(p," lvx %s, 0, %s\n", + powerpc_get_regname(reg), + powerpc_get_regname(greg)); + powerpc_emit_X (p, 0x7c0000ce, reg, 0, greg); + +} + +int +powerpc_get_constant (OrcCompiler *p, int type, int value) +{ + int reg = p->tmpreg; + int i; + + for(i=0;in_constants;i++){ + if (p->constants[i].type == type && + p->constants[i].value == value) { + if (p->constants[i].alloc_reg != 0) { + return p->constants[i].alloc_reg; + } + break; + } + } + if (i == p->n_constants) { + p->n_constants++; + p->constants[i].type = type; + p->constants[i].value = value; + p->constants[i].alloc_reg = 0; + } + + powerpc_load_constant (p, i, reg); + + return reg; +} + +void powerpc_emit_ret (OrcCompiler *compiler) +{ + ORC_ASM_CODE(compiler," ret\n"); + //*compiler->codeptr++ = 0xc3; +} + +void +powerpc_add_fixup (OrcCompiler *compiler, int type, unsigned char *ptr, int label) +{ + compiler->fixups[compiler->n_fixups].ptr = ptr; + compiler->fixups[compiler->n_fixups].label = label; + compiler->fixups[compiler->n_fixups].type = type; + compiler->n_fixups++; +} + +void +powerpc_add_label (OrcCompiler *compiler, unsigned char *ptr, int label) +{ + compiler->labels[label] = ptr; +} + +void powerpc_emit_b (OrcCompiler *compiler, int label) +{ + ORC_ASM_CODE(compiler," b %d%c\n", label, + (compiler->labels[label]!=NULL) ? 'b' : 'f'); + + powerpc_add_fixup (compiler, 0, compiler->codeptr, label); + powerpc_emit (compiler, 0x48000000); +} + +void powerpc_emit_beq (OrcCompiler *compiler, int label) +{ + ORC_ASM_CODE(compiler," ble- %d%c\n", label, + (compiler->labels[label]!=NULL) ? 'b' : 'f'); + + powerpc_add_fixup (compiler, 0, compiler->codeptr, label); + powerpc_emit (compiler, 0x40810000); +} + +void powerpc_emit_bne (OrcCompiler *compiler, int label) +{ + ORC_ASM_CODE(compiler," bdnz+ %d%c\n", label, + (compiler->labels[label]!=NULL) ? 'b' : 'f'); + + powerpc_add_fixup (compiler, 0, compiler->codeptr, label); + powerpc_emit (compiler, 0x42000000); +} + +void powerpc_emit_label (OrcCompiler *compiler, int label) +{ + ORC_ASM_CODE(compiler,"%d:\n", label); + + powerpc_add_label (compiler, compiler->codeptr, label); +} + diff --git a/orc/orcpowerpc.h b/orc/orcpowerpc.h new file mode 100644 index 0000000..0769931 --- /dev/null +++ b/orc/orcpowerpc.h @@ -0,0 +1,107 @@ + +#ifndef _ORC_POWERPC_H_ +#define _ORC_POWERPC_H_ + +#include + +enum { + POWERPC_R0 = ORC_GP_REG_BASE, + POWERPC_R1, + POWERPC_R2, + POWERPC_R3, + POWERPC_R4, + POWERPC_R5, + POWERPC_R6, + POWERPC_R7, + POWERPC_R8, + POWERPC_R9, + POWERPC_R10, + POWERPC_R11, + POWERPC_R12, + POWERPC_R13, + POWERPC_R14, + POWERPC_R15, + POWERPC_R16, + POWERPC_R17, + POWERPC_R18, + POWERPC_R19, + POWERPC_R20, + POWERPC_R21, + POWERPC_R22, + POWERPC_R23, + POWERPC_R24, + POWERPC_R25, + POWERPC_R26, + POWERPC_R27, + POWERPC_R28, + POWERPC_R29, + POWERPC_R30, + POWERPC_R31, + POWERPC_V0 = ORC_VEC_REG_BASE, + POWERPC_V1, + POWERPC_V2, + POWERPC_V3, + POWERPC_V4, + POWERPC_V5, + POWERPC_V6, + POWERPC_V7, + POWERPC_V8, + POWERPC_V9, + POWERPC_V10, + POWERPC_V11, + POWERPC_V12, + POWERPC_V13, + POWERPC_V14, + POWERPC_V15, + POWERPC_V16, + POWERPC_V17, + POWERPC_V18, + POWERPC_V19, + POWERPC_V20, + POWERPC_V21, + POWERPC_V22, + POWERPC_V23, + POWERPC_V24, + POWERPC_V25, + POWERPC_V26, + POWERPC_V27, + POWERPC_V28, + POWERPC_V29, + POWERPC_V30, + POWERPC_V31 +}; + +const char * powerpc_get_regname(int i); +int powerpc_regnum (int i); + +void powerpc_emit(OrcCompiler *compiler, unsigned int insn); + +void powerpc_emit_addi (OrcCompiler *compiler, int regd, int rega, int imm); +void powerpc_emit_lwz (OrcCompiler *compiler, int regd, int rega, int imm); +void powerpc_emit_stwu (OrcCompiler *compiler, int regs, int rega, int offset); + +void powerpc_emit_ret (OrcCompiler *compiler); +void powerpc_emit_b (OrcCompiler *compiler, int label); +void powerpc_emit_beq (OrcCompiler *compiler, int label); +void powerpc_emit_bne (OrcCompiler *compiler, int label); +void powerpc_emit_label (OrcCompiler *compiler, int label); +void powerpc_add_fixup (OrcCompiler *compiler, int type, unsigned char *ptr, int label); +void powerpc_do_fixups (OrcCompiler *compiler); +void powerpc_flush (OrcCompiler *compiler); + +void powerpc_emit_srawi (OrcCompiler *compiler, int regd, int rega, int shift, + int record); +void powerpc_emit_655510 (OrcCompiler *compiler, int major, int d, int a, + int b, int minor); +void powerpc_emit_X (OrcCompiler *compiler, unsigned int insn, int d, int a, + int b); +void powerpc_emit_VA (OrcCompiler *compiler, int major, int d, int a, int b, + int c, int minor); +void powerpc_emit_VX (OrcCompiler *compiler, unsigned int insn, int d, int a, + int b); +void powerpc_emit_VX_2 (OrcCompiler *p, const char *name, unsigned int insn, + int d, int a, int b); +int powerpc_get_constant (OrcCompiler *p, int type, int value); + +#endif + diff --git a/orc/orcprogram-altivec.c b/orc/orcprogram-altivec.c new file mode 100644 index 0000000..fd33457 --- /dev/null +++ b/orc/orcprogram-altivec.c @@ -0,0 +1,557 @@ + +#include "config.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include + + +void orc_compiler_powerpc_init (OrcCompiler *compiler); +unsigned int orc_compiler_powerpc_get_default_flags (void); +void orc_compiler_powerpc_assemble (OrcCompiler *compiler); +void orc_compiler_powerpc_register_rules (OrcTarget *target); + + +void +powerpc_emit_prologue (OrcCompiler *compiler) +{ + int i; + + ORC_ASM_CODE (compiler, ".global %s\n", compiler->program->name); + ORC_ASM_CODE (compiler, "%s:\n", compiler->program->name); + + powerpc_emit_stwu (compiler, POWERPC_R1, POWERPC_R1, -16); + + for(i=POWERPC_R13;i<=POWERPC_R31;i++){ + if (compiler->used_regs[i]) { + //powerpc_emit_push (compiler, 4, i); + } + } +} + +void +powerpc_emit_epilogue (OrcCompiler *compiler) +{ + int i; + + for(i=POWERPC_R31;i>=POWERPC_R31;i--){ + if (compiler->used_regs[i]) { + //powerpc_emit_pop (compiler, 4, i); + } + } + + powerpc_emit_addi (compiler, POWERPC_R1, POWERPC_R1, 16); + ORC_ASM_CODE(compiler," blr\n"); + powerpc_emit(compiler, 0x4e800020); +} + +static OrcTarget altivec_target = { + "altivec", +#ifdef HAVE_POWERPC + TRUE, +#else + FALSE, +#endif + ORC_VEC_REG_BASE, + orc_compiler_powerpc_get_default_flags, + orc_compiler_powerpc_init, + orc_compiler_powerpc_assemble +}; + +void +orc_powerpc_init (void) +{ + orc_target_register (&altivec_target); + + orc_compiler_powerpc_register_rules (&altivec_target); +} + +unsigned int +orc_compiler_powerpc_get_default_flags (void) +{ + return 0; +} + +void +orc_compiler_powerpc_init (OrcCompiler *compiler) +{ + int i; + + for(i=0;i<32;i++){ + compiler->valid_regs[POWERPC_R0+i] = 1; + compiler->valid_regs[POWERPC_V0+i] = 1; + } + compiler->valid_regs[POWERPC_R0] = 0; /* used for temp space */ + compiler->valid_regs[POWERPC_R1] = 0; /* stack pointer */ + compiler->valid_regs[POWERPC_R2] = 0; /* TOC pointer */ + compiler->valid_regs[POWERPC_R3] = 0; /* pointer to OrcExecutor */ + compiler->valid_regs[POWERPC_R13] = 0; /* reserved */ + + compiler->tmpreg = POWERPC_V0; + compiler->valid_regs[compiler->tmpreg] = 0; + + for(i=14;i<32;i++){ + compiler->save_regs[POWERPC_R0 + i] = 1; + } + for(i=20;i<32;i++){ + compiler->save_regs[POWERPC_V0 + i] = 1; + } + + compiler->loop_shift = 0; +} + +static void +powerpc_load_constant (OrcCompiler *p, int i, int reg) +{ + int j; + int value = p->constants[i].value; + int greg = POWERPC_R31; + int label_skip, label_data; + +#if 0 + switch (p->constants[i].type) { + case ORC_CONST_ZERO: + powerpc_emit_VX_2(p, "vxor", 0x100004c4, reg, reg, reg); + break; + case ORC_CONST_SPLAT_B: + if (value < 16 && value >= -16) { + ORC_ASM_CODE(p," vspltisb %s, %d\n", + powerpc_get_regname(reg), value&0x1f); + powerpc_emit_VX(p, 0x1000020c, + powerpc_regnum(reg), value & 0x1f, 0); + } else { + ORC_COMPILER_ERROR(p,"can't load constant"); + } + break; + case ORC_CONST_SPLAT_W: + if (value < 16 && value >= -16) { + ORC_ASM_CODE(p," vspltish %s, %d\n", + powerpc_get_regname(reg), value&0x1f); + powerpc_emit_VX(p, 0x1000024c, + powerpc_regnum(reg), value & 0x1f, 0); + } else { + ORC_COMPILER_ERROR(p,"can't load constant"); + } + break; + case ORC_CONST_SPLAT_L: + if (value < 16 && value >= -16) { + ORC_ASM_CODE(p," vspltisw %s, %d\n", + powerpc_get_regname(reg), value&0x1f); + powerpc_emit_VX(p, 0x1000028c, + powerpc_regnum(reg), value & 0x1f, 0); + } else { + ORC_COMPILER_ERROR(p,"can't load constant"); + } + break; + default: + ORC_COMPILER_ERROR(p,"unhandled"); + break; + } +#endif + + switch (p->constants[i].type) { + case ORC_CONST_ZERO: + for(j=0;j<4;j++){ + p->constants[i].full_value[j] = 0; + } + break; + case ORC_CONST_SPLAT_B: + value &= 0xff; + value |= (value<<8); + value |= (value<<16); + for(j=0;j<4;j++){ + p->constants[i].full_value[j] = value; + } + break; + case ORC_CONST_SPLAT_W: + value &= 0xffff; + value |= (value<<16); + for(j=0;j<4;j++){ + p->constants[i].full_value[j] = value; + } + break; + case ORC_CONST_SPLAT_L: + for(j=0;j<4;j++){ + p->constants[i].full_value[j] = value; + } + break; + default: + break; + } + + label_skip = orc_compiler_label_new (p); + label_data = orc_compiler_label_new (p); + + powerpc_emit_b (p, label_skip); + + while ((p->codeptr - p->program->code) & 0xf) { + ORC_ASM_CODE(p," .long 0x00000000\n"); + powerpc_emit (p, 0x00000000); + } + + powerpc_emit_label (p, label_data); + for(j=0;j<4;j++){ + ORC_ASM_CODE(p," .long 0x%08x\n", p->constants[i].full_value[j]); + powerpc_emit (p, p->constants[i].full_value[j]); + } + + powerpc_emit_label (p, label_skip); + powerpc_emit_lwz (p, + greg, + POWERPC_R3, + (int)ORC_STRUCT_OFFSET(OrcExecutor, program)); + powerpc_emit_lwz (p, + greg, greg, + (int)ORC_STRUCT_OFFSET(OrcProgram, code_exec)); + + powerpc_add_fixup (p, 1, p->codeptr, label_data); + { + unsigned int insn; + + ORC_ASM_CODE(p," addi %s, %s, %db - %s\n", + powerpc_get_regname(greg), + powerpc_get_regname(greg), label_data, p->program->name); + insn = (14<<26) | (powerpc_regnum (greg)<<21) | (powerpc_regnum (greg)<<16); + insn |= 0; + + powerpc_emit (p, insn); + } + + ORC_ASM_CODE(p," lvx %s, 0, %s\n", + powerpc_get_regname(reg), + powerpc_get_regname(greg)); + powerpc_emit_X (p, 0x7c0000ce, reg, 0, greg); + +} + +void +powerpc_load_constants (OrcCompiler *compiler) +{ + OrcVariable *var; + int i; + int j; + int greg = POWERPC_R0; + + for(i=0;ivars + i; + + if (compiler->vars[i].name == NULL) continue; + switch (compiler->vars[i].vartype) { + case ORC_VAR_TYPE_CONST: + j = compiler->n_constants; + compiler->n_constants++; + if (compiler->vars[i].size == 1) { + compiler->constants[j].type = ORC_CONST_SPLAT_B; + } else if (compiler->vars[i].size == 2) { + compiler->constants[j].type = ORC_CONST_SPLAT_W; + } else { + compiler->constants[j].type = ORC_CONST_SPLAT_L; + } + compiler->constants[j].value = compiler->vars[i].value; + compiler->constants[j].alloc_reg = compiler->vars[i].alloc; + break; + case ORC_VAR_TYPE_PARAM: + powerpc_emit_addi (compiler, + greg, POWERPC_R3, + (int)ORC_STRUCT_OFFSET(OrcExecutor, params[i])); + ORC_ASM_CODE(compiler," lvewx %s, 0, %s\n", + powerpc_get_regname (var->alloc), + powerpc_get_regname (greg)); + powerpc_emit_X (compiler, 0x7c00008e, powerpc_regnum(var->alloc), + 0, powerpc_regnum(greg)); + + ORC_ASM_CODE(compiler," lvsl %s, 0, %s\n", + powerpc_get_regname (POWERPC_V0), + powerpc_get_regname (greg)); + powerpc_emit_X (compiler, 0x7c00000c, powerpc_regnum(POWERPC_V0), + 0, powerpc_regnum(greg)); + + ORC_ASM_CODE(compiler," vperm %s, %s, %s, %s\n", + powerpc_get_regname (var->alloc), + powerpc_get_regname (var->alloc), + powerpc_get_regname (var->alloc), + powerpc_get_regname (POWERPC_V0)); + powerpc_emit_VA (compiler, 4, + powerpc_regnum(var->alloc), + powerpc_regnum(var->alloc), + powerpc_regnum(var->alloc), + powerpc_regnum(POWERPC_V0), 43); + switch (var->size) { + case 1: + ORC_ASM_CODE(compiler," vspltb %s, %s, 3\n", + powerpc_get_regname (var->alloc), + powerpc_get_regname (var->alloc)); + powerpc_emit_VX (compiler, 0x1000020c, + powerpc_regnum(var->alloc), 3, powerpc_regnum(var->alloc)); + break; + case 2: + ORC_ASM_CODE(compiler," vsplth %s, %s, 1\n", + powerpc_get_regname (var->alloc), + powerpc_get_regname (var->alloc)); + powerpc_emit_VX (compiler, 0x1000024c, + powerpc_regnum(var->alloc), 1, powerpc_regnum(var->alloc)); + break; + case 4: + ORC_ASM_CODE(compiler," vspltw %s, %s, 0\n", + powerpc_get_regname (var->alloc), + powerpc_get_regname (var->alloc)); + powerpc_emit_VX (compiler, 0x1000028c, + powerpc_regnum(var->alloc), 0, powerpc_regnum(var->alloc)); + break; + } + break; + case ORC_VAR_TYPE_SRC: + case ORC_VAR_TYPE_DEST: + if (compiler->vars[i].ptr_register) { + powerpc_emit_lwz (compiler, + compiler->vars[i].ptr_register, + POWERPC_R3, + (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[i])); + } else { + /* FIXME */ + ORC_ASM_CODE(compiler,"ERROR"); + } + break; + default: + break; + } + } + + for(i=0;in_constants;i++){ + if (compiler->constants[i].alloc_reg > 0) { + powerpc_load_constant (compiler, i, compiler->constants[i].alloc_reg); + } + } +} + +void +powerpc_emit_load_src (OrcCompiler *compiler, OrcVariable *var) +{ + int ptr_reg; + ptr_reg = var->ptr_register; + + switch (compiler->loop_shift) { + case 0: + switch (var->size) { + case 1: + ORC_ASM_CODE(compiler," lvebx %s, 0, %s\n", + powerpc_get_regname (var->alloc), + powerpc_get_regname (ptr_reg)); + powerpc_emit_X (compiler, 0x7c00000e, powerpc_regnum(var->alloc), + 0, powerpc_regnum(ptr_reg)); + break; + case 2: + ORC_ASM_CODE(compiler," lvehx %s, 0, %s\n", + powerpc_get_regname (var->alloc), + powerpc_get_regname (ptr_reg)); + powerpc_emit_X (compiler, 0x7c00004e, powerpc_regnum(var->alloc), + 0, powerpc_regnum(ptr_reg)); + break; + case 4: + ORC_ASM_CODE(compiler," lvewx %s, 0, %s\n", + powerpc_get_regname (var->alloc), + powerpc_get_regname (ptr_reg)); + powerpc_emit_X (compiler, 0x7c00008e, powerpc_regnum(var->alloc), + 0, powerpc_regnum(ptr_reg)); + break; + } + ORC_ASM_CODE(compiler," lvsl %s, 0, %s\n", + powerpc_get_regname (POWERPC_V0), + powerpc_get_regname (ptr_reg)); + powerpc_emit_X (compiler, 0x7c00000c, powerpc_regnum(POWERPC_V0), + 0, powerpc_regnum(ptr_reg)); + ORC_ASM_CODE(compiler," vperm %s, %s, %s, %s\n", + powerpc_get_regname (var->alloc), + powerpc_get_regname (var->alloc), + powerpc_get_regname (var->alloc), + powerpc_get_regname (POWERPC_V0)); + powerpc_emit_VA (compiler, 4, + powerpc_regnum(var->alloc), + powerpc_regnum(var->alloc), + powerpc_regnum(var->alloc), + powerpc_regnum(POWERPC_V0), 43); + break; + default: + ORC_ASM_CODE(compiler,"ERROR\n"); + } +} + +void +powerpc_emit_store_dest (OrcCompiler *compiler, OrcVariable *var) +{ + int ptr_reg; + ptr_reg = var->ptr_register; + + switch (compiler->loop_shift) { + case 0: + ORC_ASM_CODE(compiler," lvsr %s, 0, %s\n", + powerpc_get_regname (POWERPC_V0), + powerpc_get_regname (ptr_reg)); + powerpc_emit_X (compiler, 0x7c00004c, powerpc_regnum(POWERPC_V0), + 0, powerpc_regnum(ptr_reg)); + ORC_ASM_CODE(compiler," vperm %s, %s, %s, %s\n", + powerpc_get_regname (var->alloc), + powerpc_get_regname (var->alloc), + powerpc_get_regname (var->alloc), + powerpc_get_regname (POWERPC_V0)); + powerpc_emit_VA (compiler, 4, + powerpc_regnum(var->alloc), + powerpc_regnum(var->alloc), + powerpc_regnum(var->alloc), + powerpc_regnum(POWERPC_V0), 43); + switch (var->size) { + case 1: + ORC_ASM_CODE(compiler," stvebx %s, 0, %s\n", + powerpc_get_regname (var->alloc), + powerpc_get_regname (ptr_reg)); + powerpc_emit_X (compiler, 0x7c00010e, + powerpc_regnum(var->alloc), + 0, powerpc_regnum(ptr_reg)); + break; + case 2: + ORC_ASM_CODE(compiler," stvehx %s, 0, %s\n", + powerpc_get_regname (var->alloc), + powerpc_get_regname (ptr_reg)); + powerpc_emit_X (compiler, 0x7c00014e, + powerpc_regnum(var->alloc), + 0, powerpc_regnum(ptr_reg)); + break; + case 4: + ORC_ASM_CODE(compiler," stvewx %s, 0, %s\n", + powerpc_get_regname (var->alloc), + powerpc_get_regname (ptr_reg)); + powerpc_emit_X (compiler, 0x7c00018e, + powerpc_regnum(var->alloc), + 0, powerpc_regnum(ptr_reg)); + break; + } + break; + default: + ORC_ASM_CODE(compiler,"ERROR\n"); + } +} + +void +orc_compiler_powerpc_assemble (OrcCompiler *compiler) +{ + int j; + int k; + OrcInstruction *insn; + OrcStaticOpcode *opcode; + //OrcVariable *args[10]; + OrcRule *rule; + int label_loop_start; + int label_leave; + + label_loop_start = orc_compiler_label_new (compiler); + label_leave = orc_compiler_label_new (compiler); + + powerpc_emit_prologue (compiler); + + powerpc_emit_lwz (compiler, POWERPC_R0, POWERPC_R3, + (int)ORC_STRUCT_OFFSET(OrcExecutor, n)); + powerpc_emit_srawi (compiler, POWERPC_R0, POWERPC_R0, + compiler->loop_shift, 1); + + powerpc_emit_beq (compiler, label_leave); + + powerpc_emit (compiler, 0x7c0903a6); + ORC_ASM_CODE (compiler, " mtctr %s\n", powerpc_get_regname(POWERPC_R0)); + + powerpc_load_constants (compiler); + + powerpc_emit_label (compiler, label_loop_start); + + for(j=0;jn_insns;j++){ + insn = compiler->insns + j; + opcode = insn->opcode; + + ORC_ASM_CODE(compiler,"# %d: %s\n", j, insn->opcode->name); + +#if 0 + /* set up args */ + for(k=0;kn_src + opcode->n_dest;k++){ + args[k] = compiler->vars + insn->args[k]; + ORC_ASM_CODE(compiler," %d", args[k]->alloc); + if (args[k]->is_chained) { + ORC_ASM_CODE(compiler," (chained)"); + } + } + ORC_ASM_CODE(compiler,"\n"); +#endif + + for(k=0;kvars + insn->src_args[k]; + + if (opcode->src_size[k] == 0) continue; + + switch (var->vartype) { + case ORC_VAR_TYPE_SRC: + case ORC_VAR_TYPE_DEST: + powerpc_emit_load_src (compiler, var); + break; + case ORC_VAR_TYPE_CONST: + break; + case ORC_VAR_TYPE_TEMP: + break; + default: + break; + } + } + + rule = insn->rule; + if (rule) { + rule->emit (compiler, rule->emit_user, insn); + } else { + ORC_ASM_CODE(compiler,"No rule for: %s\n", opcode->name); + } + + for(k=0;kvars + insn->dest_args[k]; + + if (opcode->dest_size[k] == 0) continue; + + switch (var->vartype) { + case ORC_VAR_TYPE_DEST: + powerpc_emit_store_dest (compiler, var); + break; + case ORC_VAR_TYPE_TEMP: + break; + default: + break; + } + } + } + + for(k=0;kvars[k].name == NULL) continue; + if (compiler->vars[k].vartype == ORC_VAR_TYPE_SRC || + compiler->vars[k].vartype == ORC_VAR_TYPE_DEST) { + if (compiler->vars[k].ptr_register) { + powerpc_emit_addi (compiler, + compiler->vars[k].ptr_register, + compiler->vars[k].ptr_register, + compiler->vars[k].size << compiler->loop_shift); + } else { + ORC_ASM_CODE(compiler,"ERROR\n"); + } + } + } + + powerpc_emit_bne (compiler, label_loop_start); + powerpc_emit_label (compiler, label_leave); + + powerpc_emit_epilogue (compiler); + + powerpc_do_fixups (compiler); + + powerpc_flush (compiler); +} + diff --git a/orc/orcprogram-powerpc.c b/orc/orcprogram-powerpc.c deleted file mode 100644 index d65b946..0000000 --- a/orc/orcprogram-powerpc.c +++ /dev/null @@ -1,1626 +0,0 @@ - -#include "config.h" - -#include -#include -#include - -#include -#include - -#include -#include - -#define SIZE 65536 - -void powerpc_emit_addi (OrcCompiler *compiler, int regd, int rega, int imm); -void powerpc_emit_lwz (OrcCompiler *compiler, int regd, int rega, int imm); -void powerpc_emit_stwu (OrcCompiler *compiler, int regs, int rega, int offset); - -void powerpc_emit_ret (OrcCompiler *compiler); -void powerpc_emit_b (OrcCompiler *compiler, int label); -void powerpc_emit_beq (OrcCompiler *compiler, int label); -void powerpc_emit_bne (OrcCompiler *compiler, int label); -void powerpc_emit_label (OrcCompiler *compiler, int label); -void powerpc_add_fixup (OrcCompiler *compiler, int type, unsigned char *ptr, int label); - -void orc_compiler_powerpc_init (OrcCompiler *compiler); -unsigned int orc_compiler_powerpc_get_default_flags (void); -void orc_compiler_powerpc_assemble (OrcCompiler *compiler); -void orc_compiler_powerpc_register_rules (OrcTarget *target); - -enum { - POWERPC_R0 = ORC_GP_REG_BASE, - POWERPC_R1, - POWERPC_R2, - POWERPC_R3, - POWERPC_R4, - POWERPC_R5, - POWERPC_R6, - POWERPC_R7, - POWERPC_R8, - POWERPC_R9, - POWERPC_R10, - POWERPC_R11, - POWERPC_R12, - POWERPC_R13, - POWERPC_R14, - POWERPC_R15, - POWERPC_R16, - POWERPC_R17, - POWERPC_R18, - POWERPC_R19, - POWERPC_R20, - POWERPC_R21, - POWERPC_R22, - POWERPC_R23, - POWERPC_R24, - POWERPC_R25, - POWERPC_R26, - POWERPC_R27, - POWERPC_R28, - POWERPC_R29, - POWERPC_R30, - POWERPC_R31, - POWERPC_V0 = ORC_VEC_REG_BASE, - POWERPC_V1, - POWERPC_V2, - POWERPC_V3, - POWERPC_V4, - POWERPC_V5, - POWERPC_V6, - POWERPC_V7, - POWERPC_V8, - POWERPC_V9, - POWERPC_V10, - POWERPC_V11, - POWERPC_V12, - POWERPC_V13, - POWERPC_V14, - POWERPC_V15, - POWERPC_V16, - POWERPC_V17, - POWERPC_V18, - POWERPC_V19, - POWERPC_V20, - POWERPC_V21, - POWERPC_V22, - POWERPC_V23, - POWERPC_V24, - POWERPC_V25, - POWERPC_V26, - POWERPC_V27, - POWERPC_V28, - POWERPC_V29, - POWERPC_V30, - POWERPC_V31 -}; - -const char * -powerpc_get_regname(int i) -{ - static const char *powerpc_regs[] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", - "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", - "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", - "r30", "r31", - "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", - "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", - "v30", "v31", - }; - - if (i>=ORC_GP_REG_BASE && icodeptr++ = (insn>>24); - *compiler->codeptr++ = (insn>>16); - *compiler->codeptr++ = (insn>>8); - *compiler->codeptr++ = (insn>>0); -} - -void -powerpc_emit_prologue (OrcCompiler *compiler) -{ - int i; - - ORC_ASM_CODE (compiler, ".global %s\n", compiler->program->name); - ORC_ASM_CODE (compiler, "%s:\n", compiler->program->name); - - powerpc_emit_stwu (compiler, POWERPC_R1, POWERPC_R1, -16); - - for(i=POWERPC_R13;i<=POWERPC_R31;i++){ - if (compiler->used_regs[i]) { - //powerpc_emit_push (compiler, 4, i); - } - } -} - -void -powerpc_emit_addi (OrcCompiler *compiler, int regd, int rega, int imm) -{ - unsigned int insn; - - ORC_ASM_CODE(compiler," addi %s, %s, %d\n", - powerpc_get_regname(regd), - powerpc_get_regname(rega), imm); - insn = (14<<26) | (powerpc_regnum (regd)<<21) | (powerpc_regnum (rega)<<16); - insn |= imm&0xffff; - - powerpc_emit (compiler, insn); -} - -void -powerpc_emit_lwz (OrcCompiler *compiler, int regd, int rega, int imm) -{ - unsigned int insn; - - ORC_ASM_CODE(compiler," lwz %s, %d(%s)\n", - powerpc_get_regname(regd), - imm, powerpc_get_regname(rega)); - insn = (32<<26) | (powerpc_regnum (regd)<<21) | (powerpc_regnum (rega)<<16); - insn |= imm&0xffff; - - powerpc_emit (compiler, insn); -} - -void -powerpc_emit_stwu (OrcCompiler *compiler, int regs, int rega, int offset) -{ - unsigned int insn; - - ORC_ASM_CODE(compiler," stwu %s, %d(%s)\n", - powerpc_get_regname(regs), - offset, powerpc_get_regname(rega)); - insn = (37<<26) | (powerpc_regnum (regs)<<21) | (powerpc_regnum (rega)<<16); - insn |= offset&0xffff; - - powerpc_emit (compiler, insn); -} - -void -powerpc_emit_srawi (OrcCompiler *compiler, int regd, int rega, int shift, - int record) -{ - unsigned int insn; - - ORC_ASM_CODE(compiler," srawi%s %s, %s, %d\n", (record)?".":"", - powerpc_get_regname(regd), - powerpc_get_regname(rega), shift); - - insn = (31<<26) | (powerpc_regnum (regd)<<21) | (powerpc_regnum (rega)<<16); - insn |= (shift<<11) | (824<<1) | record; - - powerpc_emit (compiler, insn); -} - -void -powerpc_emit_655510 (OrcCompiler *compiler, int major, int d, int a, int b, - int minor) -{ - unsigned int insn; - - insn = (major<<26) | (d<<21) | (a<<16); - insn |= (b<<11) | (minor<<0); - - powerpc_emit (compiler, insn); -} - -void -powerpc_emit_X (OrcCompiler *compiler, unsigned int insn, int d, int a, int b) -{ -#if 0 - unsigned int insn; - - insn = (major<<26) | (d<<21) | (a<<16); - insn |= (b<<11) | (minor<<1) | (0<<0); - - powerpc_emit (compiler, insn); -#endif - insn |= ((d&0x1f)<<21); - insn |= ((a&0x1f)<<16); - insn |= ((b&0x1f)<<11); - powerpc_emit (compiler, insn); -} - -void -powerpc_emit_VA (OrcCompiler *compiler, int major, int d, int a, int b, - int c, int minor) -{ - unsigned int insn; - - insn = (major<<26) | (d<<21) | (a<<16); - insn |= (b<<11) | (c<<6) | (minor<<0); - - powerpc_emit (compiler, insn); -} - -void -powerpc_emit_VX (OrcCompiler *compiler, unsigned int insn, int d, int a, int b) -{ - insn |= ((d&0x1f)<<21); - insn |= ((a&0x1f)<<16); - insn |= ((b&0x1f)<<11); - powerpc_emit (compiler, insn); -} - -void -powerpc_emit_VX_2 (OrcCompiler *p, const char *name, - unsigned int insn, int d, int a, int b) -{ - ORC_ASM_CODE(p," %s %s, %s, %s\n", name, - powerpc_get_regname(d), - powerpc_get_regname(a), - powerpc_get_regname(b)); - powerpc_emit_VX(p, insn, - powerpc_regnum(d), - powerpc_regnum(a), - powerpc_regnum(b)); -} - -void -powerpc_emit_epilogue (OrcCompiler *compiler) -{ - int i; - - for(i=POWERPC_R31;i>=POWERPC_R31;i--){ - if (compiler->used_regs[i]) { - //powerpc_emit_pop (compiler, 4, i); - } - } - - powerpc_emit_addi (compiler, POWERPC_R1, POWERPC_R1, 16); - ORC_ASM_CODE(compiler," blr\n"); - powerpc_emit(compiler, 0x4e800020); -} - -void -powerpc_do_fixups (OrcCompiler *compiler) -{ - int i; - unsigned int insn; - - for(i=0;in_fixups;i++){ - if (compiler->fixups[i].type == 0) { - unsigned char *label = compiler->labels[compiler->fixups[i].label]; - unsigned char *ptr = compiler->fixups[i].ptr; - - insn = *(unsigned int *)ptr; - *(unsigned int *)ptr = (insn&0xffff0000) | ((insn + (label-ptr))&0xffff); - } else { - unsigned char *label = compiler->labels[compiler->fixups[i].label]; - unsigned char *ptr = compiler->fixups[i].ptr; - - insn = *(unsigned int *)ptr; - *(unsigned int *)ptr = (insn&0xffff0000) | ((insn + (label-compiler->program->code))&0xffff); - } - } -} - -void -powerpc_flush (OrcCompiler *compiler) -{ -#ifdef HAVE_POWERPC - unsigned char *ptr; - int cache_line_size = 32; - int i; - int size = compiler->codeptr - compiler->program->code; - - ptr = compiler->program->code; - for (i=0;iprogram->code_exec; - for (i=0;ivalid_regs[POWERPC_R0+i] = 1; - compiler->valid_regs[POWERPC_V0+i] = 1; - } - compiler->valid_regs[POWERPC_R0] = 0; /* used for temp space */ - compiler->valid_regs[POWERPC_R1] = 0; /* stack pointer */ - compiler->valid_regs[POWERPC_R2] = 0; /* TOC pointer */ - compiler->valid_regs[POWERPC_R3] = 0; /* pointer to OrcExecutor */ - compiler->valid_regs[POWERPC_R13] = 0; /* reserved */ - - compiler->tmpreg = POWERPC_V0; - compiler->valid_regs[compiler->tmpreg] = 0; - - for(i=14;i<32;i++){ - compiler->save_regs[POWERPC_R0 + i] = 1; - } - for(i=20;i<32;i++){ - compiler->save_regs[POWERPC_V0 + i] = 1; - } - - compiler->loop_shift = 0; -} - -static void -powerpc_load_constant (OrcCompiler *p, int i, int reg) -{ - int j; - int value = p->constants[i].value; - int greg = POWERPC_R31; - int label_skip, label_data; - -#if 0 - switch (p->constants[i].type) { - case ORC_CONST_ZERO: - powerpc_emit_VX_2(p, "vxor", 0x100004c4, reg, reg, reg); - break; - case ORC_CONST_SPLAT_B: - if (value < 16 && value >= -16) { - ORC_ASM_CODE(p," vspltisb %s, %d\n", - powerpc_get_regname(reg), value&0x1f); - powerpc_emit_VX(p, 0x1000020c, - powerpc_regnum(reg), value & 0x1f, 0); - } else { - ORC_COMPILER_ERROR(p,"can't load constant"); - } - break; - case ORC_CONST_SPLAT_W: - if (value < 16 && value >= -16) { - ORC_ASM_CODE(p," vspltish %s, %d\n", - powerpc_get_regname(reg), value&0x1f); - powerpc_emit_VX(p, 0x1000024c, - powerpc_regnum(reg), value & 0x1f, 0); - } else { - ORC_COMPILER_ERROR(p,"can't load constant"); - } - break; - case ORC_CONST_SPLAT_L: - if (value < 16 && value >= -16) { - ORC_ASM_CODE(p," vspltisw %s, %d\n", - powerpc_get_regname(reg), value&0x1f); - powerpc_emit_VX(p, 0x1000028c, - powerpc_regnum(reg), value & 0x1f, 0); - } else { - ORC_COMPILER_ERROR(p,"can't load constant"); - } - break; - default: - ORC_COMPILER_ERROR(p,"unhandled"); - break; - } -#endif - - switch (p->constants[i].type) { - case ORC_CONST_ZERO: - for(j=0;j<4;j++){ - p->constants[i].full_value[j] = 0; - } - break; - case ORC_CONST_SPLAT_B: - value &= 0xff; - value |= (value<<8); - value |= (value<<16); - for(j=0;j<4;j++){ - p->constants[i].full_value[j] = value; - } - break; - case ORC_CONST_SPLAT_W: - value &= 0xffff; - value |= (value<<16); - for(j=0;j<4;j++){ - p->constants[i].full_value[j] = value; - } - break; - case ORC_CONST_SPLAT_L: - for(j=0;j<4;j++){ - p->constants[i].full_value[j] = value; - } - break; - default: - break; - } - - label_skip = orc_compiler_label_new (p); - label_data = orc_compiler_label_new (p); - - powerpc_emit_b (p, label_skip); - - while ((p->codeptr - p->program->code) & 0xf) { - ORC_ASM_CODE(p," .long 0x00000000\n"); - powerpc_emit (p, 0x00000000); - } - - powerpc_emit_label (p, label_data); - for(j=0;j<4;j++){ - ORC_ASM_CODE(p," .long 0x%08x\n", p->constants[i].full_value[j]); - powerpc_emit (p, p->constants[i].full_value[j]); - } - - powerpc_emit_label (p, label_skip); - powerpc_emit_lwz (p, - greg, - POWERPC_R3, - (int)ORC_STRUCT_OFFSET(OrcExecutor, program)); - powerpc_emit_lwz (p, - greg, greg, - (int)ORC_STRUCT_OFFSET(OrcProgram, code_exec)); - - powerpc_add_fixup (p, 1, p->codeptr, label_data); - { - unsigned int insn; - - ORC_ASM_CODE(p," addi %s, %s, %db - %s\n", - powerpc_get_regname(greg), - powerpc_get_regname(greg), label_data, p->program->name); - insn = (14<<26) | (powerpc_regnum (greg)<<21) | (powerpc_regnum (greg)<<16); - insn |= 0; - - powerpc_emit (p, insn); - } - - ORC_ASM_CODE(p," lvx %s, 0, %s\n", - powerpc_get_regname(reg), - powerpc_get_regname(greg)); - powerpc_emit_X (p, 0x7c0000ce, reg, 0, greg); - -} - -static int -powerpc_get_constant (OrcCompiler *p, int type, int value) -{ - int reg = p->tmpreg; - int i; - - for(i=0;in_constants;i++){ - if (p->constants[i].type == type && - p->constants[i].value == value) { - if (p->constants[i].alloc_reg != 0) { - return p->constants[i].alloc_reg; - } - break; - } - } - if (i == p->n_constants) { - p->n_constants++; - p->constants[i].type = type; - p->constants[i].value = value; - p->constants[i].alloc_reg = 0; - } - - powerpc_load_constant (p, i, reg); - - return reg; -} - -void -powerpc_load_constants (OrcCompiler *compiler) -{ - OrcVariable *var; - int i; - int j; - int greg = POWERPC_R0; - - for(i=0;ivars + i; - - if (compiler->vars[i].name == NULL) continue; - switch (compiler->vars[i].vartype) { - case ORC_VAR_TYPE_CONST: - j = compiler->n_constants; - compiler->n_constants++; - if (compiler->vars[i].size == 1) { - compiler->constants[j].type = ORC_CONST_SPLAT_B; - } else if (compiler->vars[i].size == 2) { - compiler->constants[j].type = ORC_CONST_SPLAT_W; - } else { - compiler->constants[j].type = ORC_CONST_SPLAT_L; - } - compiler->constants[j].value = compiler->vars[i].value; - compiler->constants[j].alloc_reg = compiler->vars[i].alloc; - break; - case ORC_VAR_TYPE_PARAM: - powerpc_emit_addi (compiler, - greg, POWERPC_R3, - (int)ORC_STRUCT_OFFSET(OrcExecutor, params[i])); - ORC_ASM_CODE(compiler," lvewx %s, 0, %s\n", - powerpc_get_regname (var->alloc), - powerpc_get_regname (greg)); - powerpc_emit_X (compiler, 0x7c00008e, powerpc_regnum(var->alloc), - 0, powerpc_regnum(greg)); - - ORC_ASM_CODE(compiler," lvsl %s, 0, %s\n", - powerpc_get_regname (POWERPC_V0), - powerpc_get_regname (greg)); - powerpc_emit_X (compiler, 0x7c00000c, powerpc_regnum(POWERPC_V0), - 0, powerpc_regnum(greg)); - - ORC_ASM_CODE(compiler," vperm %s, %s, %s, %s\n", - powerpc_get_regname (var->alloc), - powerpc_get_regname (var->alloc), - powerpc_get_regname (var->alloc), - powerpc_get_regname (POWERPC_V0)); - powerpc_emit_VA (compiler, 4, - powerpc_regnum(var->alloc), - powerpc_regnum(var->alloc), - powerpc_regnum(var->alloc), - powerpc_regnum(POWERPC_V0), 43); - switch (var->size) { - case 1: - ORC_ASM_CODE(compiler," vspltb %s, %s, 3\n", - powerpc_get_regname (var->alloc), - powerpc_get_regname (var->alloc)); - powerpc_emit_VX (compiler, 0x1000020c, - powerpc_regnum(var->alloc), 3, powerpc_regnum(var->alloc)); - break; - case 2: - ORC_ASM_CODE(compiler," vsplth %s, %s, 1\n", - powerpc_get_regname (var->alloc), - powerpc_get_regname (var->alloc)); - powerpc_emit_VX (compiler, 0x1000024c, - powerpc_regnum(var->alloc), 1, powerpc_regnum(var->alloc)); - break; - case 4: - ORC_ASM_CODE(compiler," vspltw %s, %s, 0\n", - powerpc_get_regname (var->alloc), - powerpc_get_regname (var->alloc)); - powerpc_emit_VX (compiler, 0x1000028c, - powerpc_regnum(var->alloc), 0, powerpc_regnum(var->alloc)); - break; - } - break; - case ORC_VAR_TYPE_SRC: - case ORC_VAR_TYPE_DEST: - if (compiler->vars[i].ptr_register) { - powerpc_emit_lwz (compiler, - compiler->vars[i].ptr_register, - POWERPC_R3, - (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[i])); - } else { - /* FIXME */ - ORC_ASM_CODE(compiler,"ERROR"); - } - break; - default: - break; - } - } - - for(i=0;in_constants;i++){ - if (compiler->constants[i].alloc_reg > 0) { - powerpc_load_constant (compiler, i, compiler->constants[i].alloc_reg); - } - } -} - -void -powerpc_emit_load_src (OrcCompiler *compiler, OrcVariable *var) -{ - int ptr_reg; - ptr_reg = var->ptr_register; - - switch (compiler->loop_shift) { - case 0: - switch (var->size) { - case 1: - ORC_ASM_CODE(compiler," lvebx %s, 0, %s\n", - powerpc_get_regname (var->alloc), - powerpc_get_regname (ptr_reg)); - powerpc_emit_X (compiler, 0x7c00000e, powerpc_regnum(var->alloc), - 0, powerpc_regnum(ptr_reg)); - break; - case 2: - ORC_ASM_CODE(compiler," lvehx %s, 0, %s\n", - powerpc_get_regname (var->alloc), - powerpc_get_regname (ptr_reg)); - powerpc_emit_X (compiler, 0x7c00004e, powerpc_regnum(var->alloc), - 0, powerpc_regnum(ptr_reg)); - break; - case 4: - ORC_ASM_CODE(compiler," lvewx %s, 0, %s\n", - powerpc_get_regname (var->alloc), - powerpc_get_regname (ptr_reg)); - powerpc_emit_X (compiler, 0x7c00008e, powerpc_regnum(var->alloc), - 0, powerpc_regnum(ptr_reg)); - break; - } - ORC_ASM_CODE(compiler," lvsl %s, 0, %s\n", - powerpc_get_regname (POWERPC_V0), - powerpc_get_regname (ptr_reg)); - powerpc_emit_X (compiler, 0x7c00000c, powerpc_regnum(POWERPC_V0), - 0, powerpc_regnum(ptr_reg)); - ORC_ASM_CODE(compiler," vperm %s, %s, %s, %s\n", - powerpc_get_regname (var->alloc), - powerpc_get_regname (var->alloc), - powerpc_get_regname (var->alloc), - powerpc_get_regname (POWERPC_V0)); - powerpc_emit_VA (compiler, 4, - powerpc_regnum(var->alloc), - powerpc_regnum(var->alloc), - powerpc_regnum(var->alloc), - powerpc_regnum(POWERPC_V0), 43); - break; - default: - ORC_ASM_CODE(compiler,"ERROR\n"); - } -} - -void -powerpc_emit_store_dest (OrcCompiler *compiler, OrcVariable *var) -{ - int ptr_reg; - ptr_reg = var->ptr_register; - - switch (compiler->loop_shift) { - case 0: - ORC_ASM_CODE(compiler," lvsr %s, 0, %s\n", - powerpc_get_regname (POWERPC_V0), - powerpc_get_regname (ptr_reg)); - powerpc_emit_X (compiler, 0x7c00004c, powerpc_regnum(POWERPC_V0), - 0, powerpc_regnum(ptr_reg)); - ORC_ASM_CODE(compiler," vperm %s, %s, %s, %s\n", - powerpc_get_regname (var->alloc), - powerpc_get_regname (var->alloc), - powerpc_get_regname (var->alloc), - powerpc_get_regname (POWERPC_V0)); - powerpc_emit_VA (compiler, 4, - powerpc_regnum(var->alloc), - powerpc_regnum(var->alloc), - powerpc_regnum(var->alloc), - powerpc_regnum(POWERPC_V0), 43); - switch (var->size) { - case 1: - ORC_ASM_CODE(compiler," stvebx %s, 0, %s\n", - powerpc_get_regname (var->alloc), - powerpc_get_regname (ptr_reg)); - powerpc_emit_X (compiler, 0x7c00010e, - powerpc_regnum(var->alloc), - 0, powerpc_regnum(ptr_reg)); - break; - case 2: - ORC_ASM_CODE(compiler," stvehx %s, 0, %s\n", - powerpc_get_regname (var->alloc), - powerpc_get_regname (ptr_reg)); - powerpc_emit_X (compiler, 0x7c00014e, - powerpc_regnum(var->alloc), - 0, powerpc_regnum(ptr_reg)); - break; - case 4: - ORC_ASM_CODE(compiler," stvewx %s, 0, %s\n", - powerpc_get_regname (var->alloc), - powerpc_get_regname (ptr_reg)); - powerpc_emit_X (compiler, 0x7c00018e, - powerpc_regnum(var->alloc), - 0, powerpc_regnum(ptr_reg)); - break; - } - break; - default: - ORC_ASM_CODE(compiler,"ERROR\n"); - } -} - -void -orc_compiler_powerpc_assemble (OrcCompiler *compiler) -{ - int j; - int k; - OrcInstruction *insn; - OrcStaticOpcode *opcode; - //OrcVariable *args[10]; - OrcRule *rule; - int label_loop_start; - int label_leave; - - label_loop_start = orc_compiler_label_new (compiler); - label_leave = orc_compiler_label_new (compiler); - - powerpc_emit_prologue (compiler); - - powerpc_emit_lwz (compiler, POWERPC_R0, POWERPC_R3, - (int)ORC_STRUCT_OFFSET(OrcExecutor, n)); - powerpc_emit_srawi (compiler, POWERPC_R0, POWERPC_R0, - compiler->loop_shift, 1); - - powerpc_emit_beq (compiler, label_leave); - - powerpc_emit (compiler, 0x7c0903a6); - ORC_ASM_CODE (compiler, " mtctr %s\n", powerpc_get_regname(POWERPC_R0)); - - powerpc_load_constants (compiler); - - powerpc_emit_label (compiler, label_loop_start); - - for(j=0;jn_insns;j++){ - insn = compiler->insns + j; - opcode = insn->opcode; - - ORC_ASM_CODE(compiler,"# %d: %s\n", j, insn->opcode->name); - -#if 0 - /* set up args */ - for(k=0;kn_src + opcode->n_dest;k++){ - args[k] = compiler->vars + insn->args[k]; - ORC_ASM_CODE(compiler," %d", args[k]->alloc); - if (args[k]->is_chained) { - ORC_ASM_CODE(compiler," (chained)"); - } - } - ORC_ASM_CODE(compiler,"\n"); -#endif - - for(k=0;kvars + insn->src_args[k]; - - if (opcode->src_size[k] == 0) continue; - - switch (var->vartype) { - case ORC_VAR_TYPE_SRC: - case ORC_VAR_TYPE_DEST: - powerpc_emit_load_src (compiler, var); - break; - case ORC_VAR_TYPE_CONST: - break; - case ORC_VAR_TYPE_TEMP: - break; - default: - break; - } - } - - rule = insn->rule; - if (rule) { - rule->emit (compiler, rule->emit_user, insn); - } else { - ORC_ASM_CODE(compiler,"No rule for: %s\n", opcode->name); - } - - for(k=0;kvars + insn->dest_args[k]; - - if (opcode->dest_size[k] == 0) continue; - - switch (var->vartype) { - case ORC_VAR_TYPE_DEST: - powerpc_emit_store_dest (compiler, var); - break; - case ORC_VAR_TYPE_TEMP: - break; - default: - break; - } - } - } - - for(k=0;kvars[k].name == NULL) continue; - if (compiler->vars[k].vartype == ORC_VAR_TYPE_SRC || - compiler->vars[k].vartype == ORC_VAR_TYPE_DEST) { - if (compiler->vars[k].ptr_register) { - powerpc_emit_addi (compiler, - compiler->vars[k].ptr_register, - compiler->vars[k].ptr_register, - compiler->vars[k].size << compiler->loop_shift); - } else { - ORC_ASM_CODE(compiler,"ERROR\n"); - } - } - } - - powerpc_emit_bne (compiler, label_loop_start); - powerpc_emit_label (compiler, label_leave); - - powerpc_emit_epilogue (compiler); - - powerpc_do_fixups (compiler); - - powerpc_flush (compiler); -} - - -/* rules */ - -#define RULE(name, opcode, code) \ -static void \ -powerpc_rule_ ## name (OrcCompiler *p, void *user, OrcInstruction *insn) \ -{ \ - ORC_ASM_CODE(p," " opcode " %s, %s, %s\n", \ - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), \ - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), \ - powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); \ - powerpc_emit_VX(p, code , \ - powerpc_regnum (p->vars[insn->dest_args[0]].alloc), \ - powerpc_regnum (p->vars[insn->src_args[0]].alloc), \ - powerpc_regnum (p->vars[insn->src_args[1]].alloc)); \ -} - -#define RULE_SHIFT(name, opcode, code) \ -static void \ -powerpc_rule_ ## name (OrcCompiler *p, void *user, OrcInstruction *insn) \ -{ \ - if (p->vars[insn->src_args[1]].vartype != ORC_VAR_TYPE_CONST && \ - p->vars[insn->src_args[1]].vartype != ORC_VAR_TYPE_PARAM) { \ - ORC_COMPILER_ERROR(p,"rule only works with constants or params"); \ - } \ - ORC_ASM_CODE(p," " opcode " %s, %s, %s\n", \ - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), \ - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), \ - powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); \ - powerpc_emit_VX(p, code , \ - powerpc_regnum (p->vars[insn->dest_args[0]].alloc), \ - powerpc_regnum (p->vars[insn->src_args[0]].alloc), \ - powerpc_regnum (p->vars[insn->src_args[1]].alloc)); \ -} - -RULE(addb, "vaddubm", 0x10000000) -RULE(addssb, "vaddsbs", 0x10000300) -RULE(addusb, "vaddubs", 0x10000200) -RULE(andb, "vand", 0x10000404) -//RULE(andnb, "vandc", 0x10000444) -RULE(avgsb, "vavgsb", 0x10000502) -RULE(avgub, "vavgub", 0x10000402) -RULE(cmpeqb, "vcmpequb", 0x10000006) -RULE(cmpgtsb, "vcmpgtsb", 0x10000306) -RULE(maxsb, "vmaxsb", 0x10000102) -RULE(maxub, "vmaxub", 0x10000002) -RULE(minsb, "vminsb", 0x10000302) -RULE(minub, "vminub", 0x10000202) -RULE(orb, "vor", 0x10000484) -RULE_SHIFT(shlb, "vslb", 0x10000104) -RULE_SHIFT(shrsb, "vsrab", 0x10000304) -RULE_SHIFT(shrub, "vsrb", 0x10000204) -RULE(subb, "vsububm", 0x10000400) -RULE(subssb, "vsubsbs", 0x10000700) -RULE(subusb, "vsububs", 0x10000600) -RULE(xorb, "vxor", 0x100004c4) - -RULE(addw, "vadduhm", 0x10000040) -RULE(addssw, "vaddshs", 0x10000340) -RULE(addusw, "vadduhs", 0x10000240) -RULE(andw, "vand", 0x10000404) -//RULE(andnw, "vandc", 0x10000444) -RULE(avgsw, "vavgsh", 0x10000542) -RULE(avguw, "vavguh", 0x10000442) -RULE(cmpeqw, "vcmpequh", 0x10000046) -RULE(cmpgtsw, "vcmpgtsh", 0x10000346) -RULE(maxsw, "vmaxsh", 0x10000142) -RULE(maxuw, "vmaxuh", 0x10000042) -RULE(minsw, "vminsh", 0x10000342) -RULE(minuw, "vminuh", 0x10000242) -RULE(orw, "vor", 0x10000484) -RULE_SHIFT(shlw, "vslh", 0x10000144) -RULE_SHIFT(shrsw, "vsrah", 0x10000344) -RULE_SHIFT(shruw, "vsrh", 0x10000244) -RULE(subw, "vsubuhm", 0x10000440) -RULE(subssw, "vsubshs", 0x10000740) -RULE(subusw, "vsubuhs", 0x10000640) -RULE(xorw, "vxor", 0x100004c4) - -RULE(addl, "vadduwm", 0x10000080) -RULE(addssl, "vaddsws", 0x10000380) -RULE(addusl, "vadduws", 0x10000280) -RULE(andl, "vand", 0x10000404) -//RULE(andnl, "vandc", 0x10000444) -RULE(avgsl, "vavgsw", 0x10000582) -RULE(avgul, "vavguw", 0x10000482) -RULE(cmpeql, "vcmpequw", 0x10000086) -RULE(cmpgtsl, "vcmpgtsw", 0x10000386) -RULE(maxsl, "vmaxsw", 0x10000182) -RULE(maxul, "vmaxuw", 0x10000082) -RULE(minsl, "vminsw", 0x10000382) -RULE(minul, "vminuw", 0x10000282) -RULE(orl, "vor", 0x10000484) -RULE_SHIFT(shll, "vslw", 0x10000184) -RULE_SHIFT(shrsl, "vsraw", 0x10000384) -RULE_SHIFT(shrul, "vsrw", 0x10000284) -RULE(subl, "vsubuwm", 0x10000480) -RULE(subssl, "vsubsws", 0x10000780) -RULE(subusl, "vsubuws", 0x10000680) -RULE(xorl, "vxor", 0x100004c4) - -static void -powerpc_rule_andnX (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vandc %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[1]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x10000444, - powerpc_regnum (p->vars[insn->dest_args[0]].alloc), - powerpc_regnum (p->vars[insn->src_args[1]].alloc), - powerpc_regnum (p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_copyX (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vor %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x10000484, - powerpc_regnum (p->vars[insn->dest_args[0]].alloc), - powerpc_regnum (p->vars[insn->src_args[0]].alloc), - powerpc_regnum (p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_mullb (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vmulesb %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); - powerpc_emit_VX(p, 0x10000308, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[1]].alloc)); - - ORC_ASM_CODE(p," vsldoi %s, %s, %s, 1\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc)); - powerpc_emit_VX(p, 0x1000002c | (1<<6), - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->dest_args[0]].alloc)); -} - -static void -powerpc_rule_mulhsb (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vmulesb %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); - powerpc_emit_VX(p, 0x10000308, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[1]].alloc)); -} - -static void -powerpc_rule_mulhub (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vmuleub %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); - powerpc_emit_VX(p, 0x10000208, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[1]].alloc)); -} - -static void -powerpc_rule_mullw (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vmulesh %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); - powerpc_emit_VX(p, 0x10000348, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[1]].alloc)); - - ORC_ASM_CODE(p," vsldoi %s, %s, %s, 2\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc)); - powerpc_emit_VX(p, 0x1000002c | (2<<6), - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->dest_args[0]].alloc)); -} - -static void -powerpc_rule_mulhsw (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vmulesh %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); - powerpc_emit_VX(p, 0x10000348, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[1]].alloc)); -} - -static void -powerpc_rule_mulhuw (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vmuleuh %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); - powerpc_emit_VX(p, 0x10000248, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[1]].alloc)); -} - - -#ifdef alternate -static void -powerpc_rule_mullw (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vxor %s, %s, %s\n", - powerpc_get_regname(POWERPC_V0), - powerpc_get_regname(POWERPC_V0), - powerpc_get_regname(POWERPC_V0)); - powerpc_emit_VX(p, 0x100004c4, - powerpc_regnum(POWERPC_V0), - powerpc_regnum(POWERPC_V0), - powerpc_regnum(POWERPC_V0)); - - ORC_ASM_CODE(p," vmladduhm %s, %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[1]].alloc), - powerpc_get_regname(POWERPC_V0)); - powerpc_emit_VA(p, 4, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[1]].alloc), - powerpc_regnum(POWERPC_V0), 34); - -} -#endif - -static void -powerpc_rule_convsbw (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vupkhsb %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x1000020e, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - 0, - powerpc_regnum(p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_convswl (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vupkhsh %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x1000024e, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - 0, - powerpc_regnum(p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_convubw (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - int reg = powerpc_get_constant (p, ORC_CONST_ZERO, 0); - - ORC_ASM_CODE(p," vmrghb %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(reg), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x1000000c, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(reg), - powerpc_regnum(p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_convuwl (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - int reg = powerpc_get_constant (p, ORC_CONST_ZERO, 0); - - ORC_ASM_CODE(p," vmrghh %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(reg), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x1000004c, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(reg), - powerpc_regnum(p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_convssswb (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vpkshss %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x1000018e, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_convssslw (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vpkswss %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x100001ce, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_convsuswb (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vpkshus %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x1000010e, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_convsuslw (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vpkswus %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x1000014e, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_convuuswb (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vpkuhus %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x1000008e, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_convuuslw (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vpkuwus %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x100000ce, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_convwb (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vpkuhum %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x1000000e, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_convlw (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vpkuwum %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x1000004e, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_mulsbw (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vmulesb %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); - powerpc_emit_VX(p, 0x10000308, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[1]].alloc)); -} - -static void -powerpc_rule_mulubw (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vmuleub %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); - powerpc_emit_VX(p, 0x10000208, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[1]].alloc)); -} - -static void -powerpc_rule_mulswl (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vmulesh %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); - powerpc_emit_VX(p, 0x10000348, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[1]].alloc)); -} - -static void -powerpc_rule_muluwl (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vmuleuh %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); - powerpc_emit_VX(p, 0x10000248, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[1]].alloc)); -} - -static void -powerpc_rule_accw (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vadduhm %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x10000040, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_accl (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - ORC_ASM_CODE(p," vadduwm %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); - powerpc_emit_VX(p, 0x10000080, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[0]].alloc)); -} - -static void -powerpc_rule_accsadubl (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - int tmpreg2 = POWERPC_V31; - - ORC_ASM_CODE(p," vmaxub %s, %s, %s\n", - powerpc_get_regname(p->tmpreg), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); - powerpc_emit_VX(p, 0x10000002, - powerpc_regnum(p->tmpreg), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[1]].alloc)); - - ORC_ASM_CODE(p," vminub %s, %s, %s\n", - powerpc_get_regname(tmpreg2), - powerpc_get_regname(p->vars[insn->src_args[0]].alloc), - powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); - powerpc_emit_VX(p, 0x10000202, - powerpc_regnum(tmpreg2), - powerpc_regnum(p->vars[insn->src_args[0]].alloc), - powerpc_regnum(p->vars[insn->src_args[1]].alloc)); - - ORC_ASM_CODE(p," vsububm %s, %s, %s\n", - powerpc_get_regname(p->tmpreg), - powerpc_get_regname(p->tmpreg), - powerpc_get_regname(tmpreg2)); - powerpc_emit_VX(p, 0x10000400, - powerpc_regnum(p->tmpreg), - powerpc_regnum(p->tmpreg), - powerpc_regnum(tmpreg2)); - - ORC_ASM_CODE(p," vsum4ubs %s, %s, %s\n", - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), - powerpc_get_regname(p->tmpreg)); - powerpc_emit_VX(p, 0x10000608, - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->vars[insn->dest_args[0]].alloc), - powerpc_regnum(p->tmpreg)); -} - -static void -powerpc_rule_signb (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - int reg; - - reg = powerpc_get_constant (p, ORC_CONST_SPLAT_B, 1); - powerpc_emit_VX_2(p, "vminsb", 0x10000302, - p->vars[insn->dest_args[0]].alloc, - p->vars[insn->src_args[0]].alloc, - reg); - - reg = powerpc_get_constant (p, ORC_CONST_SPLAT_B, -1); - powerpc_emit_VX_2(p, "vmaxsb", 0x10000102, - p->vars[insn->dest_args[0]].alloc, - p->vars[insn->dest_args[0]].alloc, - reg); -} - -static void -powerpc_rule_signw (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - int reg; - - reg = powerpc_get_constant (p, ORC_CONST_SPLAT_W, 1); - powerpc_emit_VX_2(p, "vminsh", 0x10000342, - p->vars[insn->dest_args[0]].alloc, - p->vars[insn->src_args[0]].alloc, - reg); - - reg = powerpc_get_constant (p, ORC_CONST_SPLAT_W, -1); - powerpc_emit_VX_2(p, "vmaxsh", 0x10000142, - p->vars[insn->dest_args[0]].alloc, - p->vars[insn->dest_args[0]].alloc, - reg); -} - -static void -powerpc_rule_signl (OrcCompiler *p, void *user, OrcInstruction *insn) -{ - int reg; - - reg = powerpc_get_constant (p, ORC_CONST_SPLAT_L, 1); - powerpc_emit_VX_2(p, "vminsw", 0x10000382, - p->vars[insn->dest_args[0]].alloc, - p->vars[insn->src_args[0]].alloc, - reg); - - reg = powerpc_get_constant (p, ORC_CONST_SPLAT_L, -1); - powerpc_emit_VX_2(p, "vmaxsw", 0x10000182, - p->vars[insn->dest_args[0]].alloc, - p->vars[insn->dest_args[0]].alloc, - reg); -} - -void -orc_compiler_powerpc_register_rules (OrcTarget *target) -{ - OrcRuleSet *rule_set; - - rule_set = orc_rule_set_new (orc_opcode_set_get("sys"), target, 0); - -#define REG(name) \ - orc_rule_register (rule_set, #name , powerpc_rule_ ## name , NULL); - - REG(addb); - REG(addssb); - REG(addusb); - REG(andb); - REG(avgsb); - REG(avgub); - REG(cmpeqb); - REG(cmpgtsb); - REG(maxsb); - REG(maxub); - REG(minsb); - REG(minub); - REG(orb); - REG(shlb); - REG(shrsb); - REG(shrub); - REG(subb); - REG(subssb); - REG(subusb); - REG(xorb); - - REG(addw); - REG(addssw); - REG(addusw); - REG(andw); - REG(avgsw); - REG(avguw); - REG(cmpeqw); - REG(cmpgtsw); - REG(maxsw); - REG(maxuw); - REG(minsw); - REG(minuw); - REG(orw); - REG(shlw); - REG(shrsw); - REG(shruw); - REG(subw); - REG(subssw); - REG(subusw); - REG(xorw); - - REG(addl); - REG(addssl); - REG(addusl); - REG(andl); - REG(avgsl); - REG(avgul); - REG(cmpeql); - REG(cmpgtsl); - REG(maxsl); - REG(maxul); - REG(minsl); - REG(minul); - REG(orl); - REG(shll); - REG(shrsl); - REG(shrul); - REG(subl); - REG(subssl); - REG(subusl); - REG(xorl); - - REG(mullb); - REG(mulhsb); - REG(mulhub); - REG(mullw); - REG(mulhsw); - REG(mulhuw); - - REG(convsbw); - REG(convswl); - REG(convubw); - REG(convuwl); - REG(convssswb); - REG(convssslw); - REG(convsuswb); - REG(convsuslw); - REG(convuuswb); - REG(convuuslw); - REG(convwb); - REG(convlw); - - REG(mulsbw); - REG(mulubw); - REG(mulswl); - REG(muluwl); - - REG(accw); - REG(accl); - REG(accsadubl); - - REG(signb); - REG(signw); - REG(signl); - - orc_rule_register (rule_set, "andnb", powerpc_rule_andnX, NULL); - orc_rule_register (rule_set, "andnw", powerpc_rule_andnX, NULL); - orc_rule_register (rule_set, "andnl", powerpc_rule_andnX, NULL); - - orc_rule_register (rule_set, "copyb", powerpc_rule_copyX, NULL); - orc_rule_register (rule_set, "copyw", powerpc_rule_copyX, NULL); - orc_rule_register (rule_set, "copyl", powerpc_rule_copyX, NULL); -} - -/* code generation */ - -void powerpc_emit_ret (OrcCompiler *compiler) -{ - ORC_ASM_CODE(compiler," ret\n"); - //*compiler->codeptr++ = 0xc3; -} - -void -powerpc_add_fixup (OrcCompiler *compiler, int type, unsigned char *ptr, int label) -{ - compiler->fixups[compiler->n_fixups].ptr = ptr; - compiler->fixups[compiler->n_fixups].label = label; - compiler->fixups[compiler->n_fixups].type = type; - compiler->n_fixups++; -} - -void -powerpc_add_label (OrcCompiler *compiler, unsigned char *ptr, int label) -{ - compiler->labels[label] = ptr; -} - -void powerpc_emit_b (OrcCompiler *compiler, int label) -{ - ORC_ASM_CODE(compiler," b %d%c\n", label, - (compiler->labels[label]!=NULL) ? 'b' : 'f'); - - powerpc_add_fixup (compiler, 0, compiler->codeptr, label); - powerpc_emit (compiler, 0x48000000); -} - -void powerpc_emit_beq (OrcCompiler *compiler, int label) -{ - ORC_ASM_CODE(compiler," ble- %d%c\n", label, - (compiler->labels[label]!=NULL) ? 'b' : 'f'); - - powerpc_add_fixup (compiler, 0, compiler->codeptr, label); - powerpc_emit (compiler, 0x40810000); -} - -void powerpc_emit_bne (OrcCompiler *compiler, int label) -{ - ORC_ASM_CODE(compiler," bdnz+ %d%c\n", label, - (compiler->labels[label]!=NULL) ? 'b' : 'f'); - - powerpc_add_fixup (compiler, 0, compiler->codeptr, label); - powerpc_emit (compiler, 0x42000000); -} - -void powerpc_emit_label (OrcCompiler *compiler, int label) -{ - ORC_ASM_CODE(compiler,"%d:\n", label); - - powerpc_add_label (compiler, compiler->codeptr, label); -} - diff --git a/orc/orcrules-altivec.c b/orc/orcrules-altivec.c new file mode 100644 index 0000000..200e6a4 --- /dev/null +++ b/orc/orcrules-altivec.c @@ -0,0 +1,713 @@ + +#include "config.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include + + + +/* rules */ + +#define RULE(name, opcode, code) \ +static void \ +powerpc_rule_ ## name (OrcCompiler *p, void *user, OrcInstruction *insn) \ +{ \ + ORC_ASM_CODE(p," " opcode " %s, %s, %s\n", \ + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), \ + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), \ + powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); \ + powerpc_emit_VX(p, code , \ + powerpc_regnum (p->vars[insn->dest_args[0]].alloc), \ + powerpc_regnum (p->vars[insn->src_args[0]].alloc), \ + powerpc_regnum (p->vars[insn->src_args[1]].alloc)); \ +} + +#define RULE_SHIFT(name, opcode, code) \ +static void \ +powerpc_rule_ ## name (OrcCompiler *p, void *user, OrcInstruction *insn) \ +{ \ + if (p->vars[insn->src_args[1]].vartype != ORC_VAR_TYPE_CONST && \ + p->vars[insn->src_args[1]].vartype != ORC_VAR_TYPE_PARAM) { \ + ORC_COMPILER_ERROR(p,"rule only works with constants or params"); \ + } \ + ORC_ASM_CODE(p," " opcode " %s, %s, %s\n", \ + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), \ + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), \ + powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); \ + powerpc_emit_VX(p, code , \ + powerpc_regnum (p->vars[insn->dest_args[0]].alloc), \ + powerpc_regnum (p->vars[insn->src_args[0]].alloc), \ + powerpc_regnum (p->vars[insn->src_args[1]].alloc)); \ +} + +RULE(addb, "vaddubm", 0x10000000) +RULE(addssb, "vaddsbs", 0x10000300) +RULE(addusb, "vaddubs", 0x10000200) +RULE(andb, "vand", 0x10000404) +//RULE(andnb, "vandc", 0x10000444) +RULE(avgsb, "vavgsb", 0x10000502) +RULE(avgub, "vavgub", 0x10000402) +RULE(cmpeqb, "vcmpequb", 0x10000006) +RULE(cmpgtsb, "vcmpgtsb", 0x10000306) +RULE(maxsb, "vmaxsb", 0x10000102) +RULE(maxub, "vmaxub", 0x10000002) +RULE(minsb, "vminsb", 0x10000302) +RULE(minub, "vminub", 0x10000202) +RULE(orb, "vor", 0x10000484) +RULE_SHIFT(shlb, "vslb", 0x10000104) +RULE_SHIFT(shrsb, "vsrab", 0x10000304) +RULE_SHIFT(shrub, "vsrb", 0x10000204) +RULE(subb, "vsububm", 0x10000400) +RULE(subssb, "vsubsbs", 0x10000700) +RULE(subusb, "vsububs", 0x10000600) +RULE(xorb, "vxor", 0x100004c4) + +RULE(addw, "vadduhm", 0x10000040) +RULE(addssw, "vaddshs", 0x10000340) +RULE(addusw, "vadduhs", 0x10000240) +RULE(andw, "vand", 0x10000404) +//RULE(andnw, "vandc", 0x10000444) +RULE(avgsw, "vavgsh", 0x10000542) +RULE(avguw, "vavguh", 0x10000442) +RULE(cmpeqw, "vcmpequh", 0x10000046) +RULE(cmpgtsw, "vcmpgtsh", 0x10000346) +RULE(maxsw, "vmaxsh", 0x10000142) +RULE(maxuw, "vmaxuh", 0x10000042) +RULE(minsw, "vminsh", 0x10000342) +RULE(minuw, "vminuh", 0x10000242) +RULE(orw, "vor", 0x10000484) +RULE_SHIFT(shlw, "vslh", 0x10000144) +RULE_SHIFT(shrsw, "vsrah", 0x10000344) +RULE_SHIFT(shruw, "vsrh", 0x10000244) +RULE(subw, "vsubuhm", 0x10000440) +RULE(subssw, "vsubshs", 0x10000740) +RULE(subusw, "vsubuhs", 0x10000640) +RULE(xorw, "vxor", 0x100004c4) + +RULE(addl, "vadduwm", 0x10000080) +RULE(addssl, "vaddsws", 0x10000380) +RULE(addusl, "vadduws", 0x10000280) +RULE(andl, "vand", 0x10000404) +//RULE(andnl, "vandc", 0x10000444) +RULE(avgsl, "vavgsw", 0x10000582) +RULE(avgul, "vavguw", 0x10000482) +RULE(cmpeql, "vcmpequw", 0x10000086) +RULE(cmpgtsl, "vcmpgtsw", 0x10000386) +RULE(maxsl, "vmaxsw", 0x10000182) +RULE(maxul, "vmaxuw", 0x10000082) +RULE(minsl, "vminsw", 0x10000382) +RULE(minul, "vminuw", 0x10000282) +RULE(orl, "vor", 0x10000484) +RULE_SHIFT(shll, "vslw", 0x10000184) +RULE_SHIFT(shrsl, "vsraw", 0x10000384) +RULE_SHIFT(shrul, "vsrw", 0x10000284) +RULE(subl, "vsubuwm", 0x10000480) +RULE(subssl, "vsubsws", 0x10000780) +RULE(subusl, "vsubuws", 0x10000680) +RULE(xorl, "vxor", 0x100004c4) + +static void +powerpc_rule_andnX (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vandc %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[1]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x10000444, + powerpc_regnum (p->vars[insn->dest_args[0]].alloc), + powerpc_regnum (p->vars[insn->src_args[1]].alloc), + powerpc_regnum (p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_copyX (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vor %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x10000484, + powerpc_regnum (p->vars[insn->dest_args[0]].alloc), + powerpc_regnum (p->vars[insn->src_args[0]].alloc), + powerpc_regnum (p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_mullb (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vmulesb %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); + powerpc_emit_VX(p, 0x10000308, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[1]].alloc)); + + ORC_ASM_CODE(p," vsldoi %s, %s, %s, 1\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc)); + powerpc_emit_VX(p, 0x1000002c | (1<<6), + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->dest_args[0]].alloc)); +} + +static void +powerpc_rule_mulhsb (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vmulesb %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); + powerpc_emit_VX(p, 0x10000308, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[1]].alloc)); +} + +static void +powerpc_rule_mulhub (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vmuleub %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); + powerpc_emit_VX(p, 0x10000208, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[1]].alloc)); +} + +static void +powerpc_rule_mullw (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vmulesh %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); + powerpc_emit_VX(p, 0x10000348, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[1]].alloc)); + + ORC_ASM_CODE(p," vsldoi %s, %s, %s, 2\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc)); + powerpc_emit_VX(p, 0x1000002c | (2<<6), + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->dest_args[0]].alloc)); +} + +static void +powerpc_rule_mulhsw (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vmulesh %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); + powerpc_emit_VX(p, 0x10000348, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[1]].alloc)); +} + +static void +powerpc_rule_mulhuw (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vmuleuh %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); + powerpc_emit_VX(p, 0x10000248, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[1]].alloc)); +} + + +#ifdef alternate +static void +powerpc_rule_mullw (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vxor %s, %s, %s\n", + powerpc_get_regname(POWERPC_V0), + powerpc_get_regname(POWERPC_V0), + powerpc_get_regname(POWERPC_V0)); + powerpc_emit_VX(p, 0x100004c4, + powerpc_regnum(POWERPC_V0), + powerpc_regnum(POWERPC_V0), + powerpc_regnum(POWERPC_V0)); + + ORC_ASM_CODE(p," vmladduhm %s, %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[1]].alloc), + powerpc_get_regname(POWERPC_V0)); + powerpc_emit_VA(p, 4, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[1]].alloc), + powerpc_regnum(POWERPC_V0), 34); + +} +#endif + +static void +powerpc_rule_convsbw (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vupkhsb %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x1000020e, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + 0, + powerpc_regnum(p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_convswl (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vupkhsh %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x1000024e, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + 0, + powerpc_regnum(p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_convubw (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + int reg = powerpc_get_constant (p, ORC_CONST_ZERO, 0); + + ORC_ASM_CODE(p," vmrghb %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(reg), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x1000000c, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(reg), + powerpc_regnum(p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_convuwl (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + int reg = powerpc_get_constant (p, ORC_CONST_ZERO, 0); + + ORC_ASM_CODE(p," vmrghh %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(reg), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x1000004c, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(reg), + powerpc_regnum(p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_convssswb (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vpkshss %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x1000018e, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_convssslw (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vpkswss %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x100001ce, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_convsuswb (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vpkshus %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x1000010e, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_convsuslw (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vpkswus %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x1000014e, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_convuuswb (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vpkuhus %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x1000008e, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_convuuslw (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vpkuwus %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x100000ce, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_convwb (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vpkuhum %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x1000000e, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_convlw (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vpkuwum %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x1000004e, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_mulsbw (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vmulesb %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); + powerpc_emit_VX(p, 0x10000308, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[1]].alloc)); +} + +static void +powerpc_rule_mulubw (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vmuleub %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); + powerpc_emit_VX(p, 0x10000208, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[1]].alloc)); +} + +static void +powerpc_rule_mulswl (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vmulesh %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); + powerpc_emit_VX(p, 0x10000348, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[1]].alloc)); +} + +static void +powerpc_rule_muluwl (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vmuleuh %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); + powerpc_emit_VX(p, 0x10000248, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[1]].alloc)); +} + +static void +powerpc_rule_accw (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vadduhm %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x10000040, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_accl (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + ORC_ASM_CODE(p," vadduwm %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc)); + powerpc_emit_VX(p, 0x10000080, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[0]].alloc)); +} + +static void +powerpc_rule_accsadubl (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + int tmpreg2 = POWERPC_V31; + + ORC_ASM_CODE(p," vmaxub %s, %s, %s\n", + powerpc_get_regname(p->tmpreg), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); + powerpc_emit_VX(p, 0x10000002, + powerpc_regnum(p->tmpreg), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[1]].alloc)); + + ORC_ASM_CODE(p," vminub %s, %s, %s\n", + powerpc_get_regname(tmpreg2), + powerpc_get_regname(p->vars[insn->src_args[0]].alloc), + powerpc_get_regname(p->vars[insn->src_args[1]].alloc)); + powerpc_emit_VX(p, 0x10000202, + powerpc_regnum(tmpreg2), + powerpc_regnum(p->vars[insn->src_args[0]].alloc), + powerpc_regnum(p->vars[insn->src_args[1]].alloc)); + + ORC_ASM_CODE(p," vsububm %s, %s, %s\n", + powerpc_get_regname(p->tmpreg), + powerpc_get_regname(p->tmpreg), + powerpc_get_regname(tmpreg2)); + powerpc_emit_VX(p, 0x10000400, + powerpc_regnum(p->tmpreg), + powerpc_regnum(p->tmpreg), + powerpc_regnum(tmpreg2)); + + ORC_ASM_CODE(p," vsum4ubs %s, %s, %s\n", + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->vars[insn->dest_args[0]].alloc), + powerpc_get_regname(p->tmpreg)); + powerpc_emit_VX(p, 0x10000608, + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->vars[insn->dest_args[0]].alloc), + powerpc_regnum(p->tmpreg)); +} + +static void +powerpc_rule_signb (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + int reg; + + reg = powerpc_get_constant (p, ORC_CONST_SPLAT_B, 1); + powerpc_emit_VX_2(p, "vminsb", 0x10000302, + p->vars[insn->dest_args[0]].alloc, + p->vars[insn->src_args[0]].alloc, + reg); + + reg = powerpc_get_constant (p, ORC_CONST_SPLAT_B, -1); + powerpc_emit_VX_2(p, "vmaxsb", 0x10000102, + p->vars[insn->dest_args[0]].alloc, + p->vars[insn->dest_args[0]].alloc, + reg); +} + +static void +powerpc_rule_signw (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + int reg; + + reg = powerpc_get_constant (p, ORC_CONST_SPLAT_W, 1); + powerpc_emit_VX_2(p, "vminsh", 0x10000342, + p->vars[insn->dest_args[0]].alloc, + p->vars[insn->src_args[0]].alloc, + reg); + + reg = powerpc_get_constant (p, ORC_CONST_SPLAT_W, -1); + powerpc_emit_VX_2(p, "vmaxsh", 0x10000142, + p->vars[insn->dest_args[0]].alloc, + p->vars[insn->dest_args[0]].alloc, + reg); +} + +static void +powerpc_rule_signl (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + int reg; + + reg = powerpc_get_constant (p, ORC_CONST_SPLAT_L, 1); + powerpc_emit_VX_2(p, "vminsw", 0x10000382, + p->vars[insn->dest_args[0]].alloc, + p->vars[insn->src_args[0]].alloc, + reg); + + reg = powerpc_get_constant (p, ORC_CONST_SPLAT_L, -1); + powerpc_emit_VX_2(p, "vmaxsw", 0x10000182, + p->vars[insn->dest_args[0]].alloc, + p->vars[insn->dest_args[0]].alloc, + reg); +} + +void +orc_compiler_powerpc_register_rules (OrcTarget *target) +{ + OrcRuleSet *rule_set; + + rule_set = orc_rule_set_new (orc_opcode_set_get("sys"), target, 0); + +#define REG(name) \ + orc_rule_register (rule_set, #name , powerpc_rule_ ## name , NULL); + + REG(addb); + REG(addssb); + REG(addusb); + REG(andb); + REG(avgsb); + REG(avgub); + REG(cmpeqb); + REG(cmpgtsb); + REG(maxsb); + REG(maxub); + REG(minsb); + REG(minub); + REG(orb); + REG(shlb); + REG(shrsb); + REG(shrub); + REG(subb); + REG(subssb); + REG(subusb); + REG(xorb); + + REG(addw); + REG(addssw); + REG(addusw); + REG(andw); + REG(avgsw); + REG(avguw); + REG(cmpeqw); + REG(cmpgtsw); + REG(maxsw); + REG(maxuw); + REG(minsw); + REG(minuw); + REG(orw); + REG(shlw); + REG(shrsw); + REG(shruw); + REG(subw); + REG(subssw); + REG(subusw); + REG(xorw); + + REG(addl); + REG(addssl); + REG(addusl); + REG(andl); + REG(avgsl); + REG(avgul); + REG(cmpeql); + REG(cmpgtsl); + REG(maxsl); + REG(maxul); + REG(minsl); + REG(minul); + REG(orl); + REG(shll); + REG(shrsl); + REG(shrul); + REG(subl); + REG(subssl); + REG(subusl); + REG(xorl); + + REG(mullb); + REG(mulhsb); + REG(mulhub); + REG(mullw); + REG(mulhsw); + REG(mulhuw); + + REG(convsbw); + REG(convswl); + REG(convubw); + REG(convuwl); + REG(convssswb); + REG(convssslw); + REG(convsuswb); + REG(convsuslw); + REG(convuuswb); + REG(convuuslw); + REG(convwb); + REG(convlw); + + REG(mulsbw); + REG(mulubw); + REG(mulswl); + REG(muluwl); + + REG(accw); + REG(accl); + REG(accsadubl); + + REG(signb); + REG(signw); + REG(signl); + + orc_rule_register (rule_set, "andnb", powerpc_rule_andnX, NULL); + orc_rule_register (rule_set, "andnw", powerpc_rule_andnX, NULL); + orc_rule_register (rule_set, "andnl", powerpc_rule_andnX, NULL); + + orc_rule_register (rule_set, "copyb", powerpc_rule_copyX, NULL); + orc_rule_register (rule_set, "copyw", powerpc_rule_copyX, NULL); + orc_rule_register (rule_set, "copyl", powerpc_rule_copyX, NULL); +} +