Add splitql opcode
authorDavid Schleef <ds@schleef.org>
Fri, 27 Aug 2010 17:45:57 +0000 (10:45 -0700)
committerDavid Schleef <ds@schleef.org>
Fri, 27 Aug 2010 17:45:57 +0000 (10:45 -0700)
orc/orcemulateopcodes.c
orc/orcemulateopcodes.h
orc/orcopcodes.c
orc/orcprogram-c.c
orc/orcrules-sse.c

index d3f75ca..8ea7c55 100644 (file)
@@ -3725,6 +3725,35 @@ emulate_mergebw (OrcOpcodeExecutor *ex, int offset, int n)
 }
 
 void
+emulate_splitql (OrcOpcodeExecutor *ex, int offset, int n)
+{
+  int i;
+  orc_union32 * ORC_RESTRICT ptr0;
+  orc_union32 * ORC_RESTRICT ptr1;
+  const orc_union64 * ORC_RESTRICT ptr4;
+  orc_union64 var32;
+  orc_union32 var33;
+  orc_union32 var34;
+
+  ptr0 = (orc_union32 *)ex->dest_ptrs[0];
+  ptr1 = (orc_union32 *)ex->dest_ptrs[1];
+  ptr4 = (orc_union64 *)ex->src_ptrs[0];
+
+  for (i = 0; i < n; i++) {
+    /* 0: loadq */
+    var32 = ptr4[i];
+    /* 1: splitql */
+    var33.i = (var32.i >> 32) & 0xffffffff;
+    var34.i = var32.i & 0xffffffff;
+    /* 2: storel */
+    ptr0[i] = var33;
+    /* 3: storel */
+    ptr1[i] = var34;
+  }
+
+}
+
+void
 emulate_splitlw (OrcOpcodeExecutor *ex, int offset, int n)
 {
   int i;
index 1bace52..c036c62 100644 (file)
@@ -151,6 +151,7 @@ void emulate_select0lw (OrcOpcodeExecutor *ex, int i, int n);
 void emulate_select1lw (OrcOpcodeExecutor *ex, int i, int n);
 void emulate_mergewl (OrcOpcodeExecutor *ex, int i, int n);
 void emulate_mergebw (OrcOpcodeExecutor *ex, int i, int n);
+void emulate_splitql (OrcOpcodeExecutor *ex, int i, int n);
 void emulate_splitlw (OrcOpcodeExecutor *ex, int i, int n);
 void emulate_splitwb (OrcOpcodeExecutor *ex, int i, int n);
 void emulate_addf (OrcOpcodeExecutor *ex, int i, int n);
index 0611f82..73fcd5e 100644 (file)
@@ -278,6 +278,7 @@ void
 emulate_null (OrcOpcodeExecutor *ex, int offset, int n)
 {
   /* This is a placeholder for adding new opcodes */
+  ORC_ERROR("emulate_null() called.  This is a bug.");
 }
 
 #include "orc/orcemulateopcodes.h"
@@ -450,6 +451,7 @@ static OrcStaticOpcode opcodes[] = {
   { "select1lw", 0, { 2 }, { 4 }, emulate_select1lw },
   { "mergewl", 0, { 4 }, { 2, 2 }, emulate_mergewl },
   { "mergebw", 0, { 2 }, { 1, 1 }, emulate_mergebw },
+  { "splitql", 0, { 4, 4 }, { 8 }, emulate_splitql },
   { "splitlw", 0, { 2, 2 }, { 4 }, emulate_splitlw },
   { "splitwb", 0, { 1, 1 }, { 2 }, emulate_splitwb },
 
index c4eda3b..42d88b6 100644 (file)
@@ -896,6 +896,19 @@ c_rule_accsadubl (OrcCompiler *p, void *user, OrcInstruction *insn)
 }
 
 static void
+c_rule_splitql (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+  char dest1[40], dest2[40], src[40];
+
+  c_get_name_int (dest1, p, insn, insn->dest_args[0]);
+  c_get_name_int (dest2, p, insn, insn->dest_args[1]);
+  c_get_name_int (src, p, insn, insn->src_args[0]);
+
+  ORC_ASM_CODE(p,"    %s = (%s >> 32) & 0xffffffff;\n", dest1, src);
+  ORC_ASM_CODE(p,"    %s = %s & 0xffffffff;\n", dest2, src);
+}
+
+static void
 c_rule_splitlw (OrcCompiler *p, void *user, OrcInstruction *insn)
 {
   char dest1[40], dest2[40], src[40];
@@ -1077,6 +1090,7 @@ orc_c_init (void)
   orc_rule_register (rule_set, "accw", c_rule_accw, NULL);
   orc_rule_register (rule_set, "accl", c_rule_accl, NULL);
   orc_rule_register (rule_set, "accsadubl", c_rule_accsadubl, NULL);
+  orc_rule_register (rule_set, "splitql", c_rule_splitql, NULL);
   orc_rule_register (rule_set, "splitlw", c_rule_splitlw, NULL);
   orc_rule_register (rule_set, "splitwb", c_rule_splitwb, NULL);
   orc_rule_register (rule_set, "splatbw", c_rule_splatbw, NULL);
index 0da4d5f..b500d02 100644 (file)
@@ -1342,6 +1342,17 @@ sse_rule_select1wb (OrcCompiler *p, void *user, OrcInstruction *insn)
 }
 
 static void
+sse_rule_splitql (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+  int src = p->vars[insn->src_args[0]].alloc;
+  int dest1 = p->vars[insn->dest_args[0]].alloc;
+  int dest2 = p->vars[insn->dest_args[1]].alloc;
+
+  orc_sse_emit_pshufd (p, ORC_SSE_SHUF(2,0,2,0), src, dest2);
+  orc_sse_emit_pshufd (p, ORC_SSE_SHUF(3,1,3,1), src, dest1);
+}
+
+static void
 sse_rule_splitlw (OrcCompiler *p, void *user, OrcInstruction *insn)
 {
   int src = p->vars[insn->src_args[0]].alloc;
@@ -2366,6 +2377,7 @@ orc_compiler_sse_register_rules (OrcTarget *target)
   orc_rule_register (rule_set, "swapw", sse_rule_swapw, NULL);
   orc_rule_register (rule_set, "swapl", sse_rule_swapl, NULL);
   orc_rule_register (rule_set, "swapq", sse_rule_swapq, NULL);
+  orc_rule_register (rule_set, "splitql", sse_rule_splitql, NULL);
   orc_rule_register (rule_set, "splitlw", sse_rule_splitlw, NULL);
   orc_rule_register (rule_set, "splitwb", sse_rule_splitwb, NULL);
   orc_rule_register (rule_set, "avgsl", sse_rule_avgsl, NULL);