diff options
author | David Schleef <ds@schleef.org> | 2010-09-14 15:12:40 -0700 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2010-09-14 15:12:40 -0700 |
commit | 78a88f506ed1deb4c810d7e348ea21c83684d148 (patch) | |
tree | 150ad5a753e377444d0e7262b31021f7f70afdec | |
parent | 18d5d8ba84f618892d4f25079d10b16eb96464f1 (diff) |
sse: implement swapwl, swaplq
-rw-r--r-- | orc/orcrules-sse.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/orc/orcrules-sse.c b/orc/orcrules-sse.c index fc85cd0..fd7c24a 100644 --- a/orc/orcrules-sse.c +++ b/orc/orcrules-sse.c @@ -1660,6 +1660,19 @@ sse_rule_swapl (OrcCompiler *p, void *user, OrcInstruction *insn) } static void +sse_rule_swapwl (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + int src = p->vars[insn->src_args[0]].alloc; + int dest = p->vars[insn->dest_args[0]].alloc; + int tmp = orc_compiler_get_temp_reg (p); + + orc_sse_emit_movdqa (p, src, tmp); + orc_sse_emit_pslld (p, 16, tmp); + orc_sse_emit_psrld (p, 16, dest); + orc_sse_emit_por (p, tmp, dest); +} + +static void sse_rule_swapq (OrcCompiler *p, void *user, OrcInstruction *insn) { int src = p->vars[insn->src_args[0]].alloc; @@ -1680,6 +1693,14 @@ sse_rule_swapq (OrcCompiler *p, void *user, OrcInstruction *insn) orc_sse_emit_por (p, tmp, dest); } +static void +sse_rule_swaplq (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + int dest = p->vars[insn->dest_args[0]].alloc; + + orc_sse_emit_pshufd (p, ORC_SSE_SHUF(2,3,0,1), dest, dest); +} + #ifndef MMX static void sse_rule_swapw_ssse3 (OrcCompiler *p, void *user, OrcInstruction *insn) @@ -1712,6 +1733,21 @@ sse_rule_swapl_ssse3 (OrcCompiler *p, void *user, OrcInstruction *insn) } static void +sse_rule_swapwl_ssse3 (OrcCompiler *p, void *user, OrcInstruction *insn) +{ + int dest = p->vars[insn->dest_args[0]].alloc; + int tmp; + + tmp = orc_compiler_try_get_constant_long (p, + 0x01000302, 0x05040706, 0x09080b0a, 0x0d0c0f0e); + if (tmp != ORC_REG_INVALID) { + orc_sse_emit_pshufb (p, tmp, dest); + } else { + sse_rule_swapl (p, user, insn); + } +} + +static void sse_rule_swapq_ssse3 (OrcCompiler *p, void *user, OrcInstruction *insn) { int dest = p->vars[insn->dest_args[0]].alloc; @@ -2650,7 +2686,9 @@ orc_compiler_sse_register_rules (OrcTarget *target) orc_rule_register (rule_set, "absl", sse_rule_absl_slow, NULL); 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, "swapwl", sse_rule_swapwl, NULL); orc_rule_register (rule_set, "swapq", sse_rule_swapq, NULL); + orc_rule_register (rule_set, "swaplq", sse_rule_swaplq, 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); @@ -2694,6 +2732,7 @@ orc_compiler_sse_register_rules (OrcTarget *target) #ifndef MMX orc_rule_register (rule_set, "swapw", sse_rule_swapw_ssse3, NULL); orc_rule_register (rule_set, "swapl", sse_rule_swapl_ssse3, NULL); + orc_rule_register (rule_set, "swapwl", sse_rule_swapwl_ssse3, NULL); orc_rule_register (rule_set, "swapq", sse_rule_swapq_ssse3, NULL); orc_rule_register (rule_set, "select0lw", sse_rule_select0lw_ssse3, NULL); orc_rule_register (rule_set, "select1lw", sse_rule_select1lw_ssse3, NULL); |