From 28051d83049250561110fd91cf13397ad3cb538f Mon Sep 17 00:00:00 2001 From: David Schleef Date: Fri, 27 Aug 2010 10:45:57 -0700 Subject: [PATCH] Add splitql opcode --- orc/orcemulateopcodes.c | 29 +++++++++++++++++++++++++++++ orc/orcemulateopcodes.h | 1 + orc/orcopcodes.c | 2 ++ orc/orcprogram-c.c | 14 ++++++++++++++ orc/orcrules-sse.c | 12 ++++++++++++ 5 files changed, 58 insertions(+) diff --git a/orc/orcemulateopcodes.c b/orc/orcemulateopcodes.c index d3f75ca..8ea7c55 100644 --- a/orc/orcemulateopcodes.c +++ b/orc/orcemulateopcodes.c @@ -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; diff --git a/orc/orcemulateopcodes.h b/orc/orcemulateopcodes.h index 1bace52..c036c62 100644 --- a/orc/orcemulateopcodes.h +++ b/orc/orcemulateopcodes.h @@ -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); diff --git a/orc/orcopcodes.c b/orc/orcopcodes.c index 0611f82..73fcd5e 100644 --- a/orc/orcopcodes.c +++ b/orc/orcopcodes.c @@ -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 }, diff --git a/orc/orcprogram-c.c b/orc/orcprogram-c.c index c4eda3b..42d88b6 100644 --- a/orc/orcprogram-c.c +++ b/orc/orcprogram-c.c @@ -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); diff --git a/orc/orcrules-sse.c b/orc/orcrules-sse.c index 0da4d5f..b500d02 100644 --- a/orc/orcrules-sse.c +++ b/orc/orcrules-sse.c @@ -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); -- 2.7.4