More altivec rules
authorDavid Schleef <ds@schleef.org>
Sun, 10 May 2009 19:22:46 +0000 (12:22 -0700)
committerDavid Schleef <ds@schleef.org>
Sun, 10 May 2009 19:22:46 +0000 (12:22 -0700)
orc/orcprogram-powerpc.c

index b1ae9ae..643c1fe 100644 (file)
@@ -9,6 +9,7 @@
 #include <sys/types.h>
 
 #include <orc/orcprogram.h>
+#include <orc/orcdebug.h>
 
 #define SIZE 65536
 
@@ -253,9 +254,9 @@ powerpc_emit_VA (OrcCompiler *compiler, int major, int d, int a, int b,
 void
 powerpc_emit_VX (OrcCompiler *compiler, unsigned int insn, int d, int a, int b)
 {
-  insn |= (d<<21);
-  insn |= (a<<16);
-  insn |= (b<<11);
+  insn |= ((d&0x1f)<<21);
+  insn |= ((a&0x1f)<<16);
+  insn |= ((b&0x1f)<<11);
   powerpc_emit (compiler, insn);
 }
 
@@ -350,7 +351,9 @@ orc_compiler_powerpc_init (OrcCompiler *compiler)
   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->valid_regs[POWERPC_V0] = 0; /* used for temp space */
+
+  compiler->tmpreg = POWERPC_V0;
+  compiler->valid_regs[compiler->tmpreg] = 0;
 
   for(i=14;i<32;i++){
     compiler->save_regs[POWERPC_R0 + i] = 1;
@@ -630,6 +633,24 @@ powerpc_rule_ ## name (OrcCompiler *p, void *user, OrcInstruction *insn) \
       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_PROGRAM_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)
@@ -637,14 +658,16 @@ 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(shlb, "vrlb", 0x10000004)
-RULE(shrsb, "vsrab", 0x10000304)
-RULE(shrub, "vsrb", 0x10000204)
+RULE_SHIFT(shlb, "vrlb", 0x10000004)
+RULE_SHIFT(shrsb, "vsrab", 0x10000304)
+RULE_SHIFT(shrub, "vsrb", 0x10000204)
 RULE(subb, "vsububm", 0x10000400)
 RULE(subssb, "vsubsbs", 0x10000700)
 RULE(subusb, "vsububs", 0x10000600)
@@ -657,14 +680,16 @@ 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(shlw, "vrlh", 0x10000044)
-RULE(shrsw, "vsrah", 0x10000344)
-RULE(shruw, "vsrh", 0x10000244)
+RULE_SHIFT(shlw, "vrlh", 0x10000044)
+RULE_SHIFT(shrsw, "vsrah", 0x10000344)
+RULE_SHIFT(shruw, "vsrh", 0x10000244)
 RULE(subw, "vsubuhm", 0x10000440)
 RULE(subssw, "vsubshs", 0x10000740)
 RULE(subusw, "vsubuhs", 0x10000640)
@@ -677,14 +702,16 @@ 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(shll, "vrlw", 0x10000084)
-RULE(shrsl, "vsraw", 0x10000384)
-RULE(shrul, "vsrw", 0x10000284)
+RULE_SHIFT(shll, "vrlw", 0x10000084)
+RULE_SHIFT(shrsl, "vsraw", 0x10000384)
+RULE_SHIFT(shrul, "vsrw", 0x10000284)
 RULE(subl, "vsubuwm", 0x10000480)
 RULE(subssl, "vsubsws", 0x10000780)
 RULE(subusl, "vsubuws", 0x10000680)
@@ -716,11 +743,107 @@ powerpc_rule_copyX (OrcCompiler *p, void *user, OrcInstruction *insn)
       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),
@@ -742,36 +865,302 @@ powerpc_rule_mullw (OrcCompiler *p, void *user, OrcInstruction *insn)
       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 int
+powerpc_get_constant (OrcCompiler *p, int value)
+{
+  int reg = p->tmpreg;
+
+  ORC_ASM_CODE(p,"  vxor %s, %s, %s\n",
+      powerpc_get_regname(reg),
+      powerpc_get_regname(reg),
+      powerpc_get_regname(reg));
+  powerpc_emit_VX(p, 0x100004c4,
+      powerpc_regnum(reg),
+      powerpc_regnum(reg),
+      powerpc_regnum(reg));
+
+  return reg;
+}
+
+static void
+powerpc_rule_convubw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+  int reg = powerpc_get_constant (p, 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, 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));
+}
 
-#if 0
 static void
-powerpc_rule_shlw (OrcCompiler *p, void *user, OrcInstruction *insn)
+powerpc_rule_convssswb (OrcCompiler *p, void *user, OrcInstruction *insn)
 {
-  ORC_ASM_CODE(p,"  vrlh %s, %s, %s\n",
+  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, 0x10000044,
+  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_shrsw (OrcCompiler *p, void *user, OrcInstruction *insn)
+powerpc_rule_mulubw (OrcCompiler *p, void *user, OrcInstruction *insn)
 {
-  ORC_ASM_CODE(p,"  vsrah %s, %s, %s\n",
+  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));
+}
 
-  powerpc_emit_VX(p, 0x10000344,
+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));
 }
-#endif
 
+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));
+}
 
 void
 orc_compiler_powerpc_register_rules (OrcTarget *target)
@@ -787,9 +1176,10 @@ orc_compiler_powerpc_register_rules (OrcTarget *target)
   REG(addssb);
   REG(addusb);
   REG(andb);
-  //REG(andnb);
   REG(avgsb);
   REG(avgub);
+  REG(cmpeqb);
+  REG(cmpgtsb);
   REG(maxsb);
   REG(maxub);
   REG(minsb);
@@ -807,9 +1197,10 @@ orc_compiler_powerpc_register_rules (OrcTarget *target)
   REG(addssw);
   REG(addusw);
   REG(andw);
-  //REG(andnw);
   REG(avgsw);
   REG(avguw);
+  REG(cmpeqw);
+  REG(cmpgtsw);
   REG(maxsw);
   REG(maxuw);
   REG(minsw);
@@ -827,9 +1218,10 @@ orc_compiler_powerpc_register_rules (OrcTarget *target)
   REG(addssl);
   REG(addusl);
   REG(andl);
-  //REG(andnl);
   REG(avgsl);
   REG(avgul);
+  REG(cmpeql);
+  REG(cmpgtsl);
   REG(maxsl);
   REG(maxul);
   REG(minsl);
@@ -843,6 +1235,35 @@ orc_compiler_powerpc_register_rules (OrcTarget *target)
   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);
+
   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);
@@ -850,8 +1271,6 @@ orc_compiler_powerpc_register_rules (OrcTarget *target)
   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);
-
-  orc_rule_register (rule_set, "mullw", powerpc_rule_mullw, NULL);
 }
 
 /* code generation */