diff options
author | David Schleef <ds@schleef.org> | 2010-09-08 13:29:02 -0700 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2010-09-08 13:35:00 -0700 |
commit | 890139b611605b71b44f83a8571fffdbe887588e (patch) | |
tree | 0c9fd01c5d91114426d4324e49df4b1129ce4e81 | |
parent | a02f8ced722af1c9fd97adc2b7ba78478bc33b46 (diff) |
Add orc_compiler_try_get_constant_long()
For loading long constants if it happens to be fast. Use case is
for when there's a backup rule that is almost as fast. (The
assumption is that loading long constants is slow.)
-rw-r--r-- | orc/orccompiler.c | 35 | ||||
-rw-r--r-- | orc/orcprogram.h | 2 | ||||
-rw-r--r-- | orc/orcrules-sse.c | 62 |
3 files changed, 79 insertions, 20 deletions
diff --git a/orc/orccompiler.c b/orc/orccompiler.c index 16b4d76..7d60eb9 100644 --- a/orc/orccompiler.c +++ b/orc/orccompiler.c @@ -1081,6 +1081,41 @@ orc_compiler_get_constant_long (OrcCompiler *compiler, } int +orc_compiler_try_get_constant_long (OrcCompiler *compiler, + orc_uint32 a, orc_uint32 b, orc_uint32 c, orc_uint32 d) +{ + int i; + + for(i=0;i<compiler->n_constants;i++){ + if (compiler->constants[i].is_long == TRUE && + compiler->constants[i].full_value[0] == a && + compiler->constants[i].full_value[1] == b && + compiler->constants[i].full_value[2] == c && + compiler->constants[i].full_value[3] == d) { + break; + } + } + if (i == compiler->n_constants) { + compiler->n_constants++; + compiler->constants[i].full_value[0] = a; + compiler->constants[i].full_value[1] = b; + compiler->constants[i].full_value[2] = c; + compiler->constants[i].full_value[3] = d; + compiler->constants[i].is_long = TRUE; + compiler->constants[i].alloc_reg = 0; + compiler->constants[i].use_count = 0; + } + + compiler->constants[i].use_count++; + + if (compiler->constants[i].alloc_reg != 0) {; + return compiler->constants[i].alloc_reg; + } + return ORC_REG_INVALID; +} + + +int orc_compiler_get_constant_reg (OrcCompiler *compiler) { int j; diff --git a/orc/orcprogram.h b/orc/orcprogram.h index e74de23..c88ccf2 100644 --- a/orc/orcprogram.h +++ b/orc/orcprogram.h @@ -722,6 +722,8 @@ int orc_compiler_label_new (OrcCompiler *compiler); int orc_compiler_get_constant (OrcCompiler *compiler, int size, int value); int orc_compiler_get_constant_long (OrcCompiler *compiler, orc_uint32 a, orc_uint32 b, orc_uint32 c, orc_uint32 d); +int orc_compiler_try_get_constant_long (OrcCompiler *compiler, orc_uint32 a, + orc_uint32 b, orc_uint32 c, orc_uint32 d); int orc_compiler_get_temp_constant (OrcCompiler *compiler, int size, int value); int orc_compiler_get_temp_reg (OrcCompiler *compiler); int orc_compiler_get_constant_reg (OrcCompiler *compiler); diff --git a/orc/orcrules-sse.c b/orc/orcrules-sse.c index f880423..841fa28 100644 --- a/orc/orcrules-sse.c +++ b/orc/orcrules-sse.c @@ -1550,9 +1550,13 @@ sse_rule_swapw_ssse3 (OrcCompiler *p, void *user, OrcInstruction *insn) int dest = p->vars[insn->dest_args[0]].alloc; int tmp; - tmp = orc_compiler_get_constant_long (p, + tmp = orc_compiler_try_get_constant_long (p, 0x02030001, 0x06070405, 0x0a0b0809, 0x0e0f0c0d); - orc_sse_emit_pshufb (p, tmp, dest); + if (tmp != ORC_REG_INVALID) { + orc_sse_emit_pshufb (p, tmp, dest); + } else { + sse_rule_swapw (p, user, insn); + } } static void @@ -1561,10 +1565,13 @@ sse_rule_swapl_ssse3 (OrcCompiler *p, void *user, OrcInstruction *insn) int dest = p->vars[insn->dest_args[0]].alloc; int tmp; - tmp = orc_compiler_get_constant_long (p, + tmp = orc_compiler_try_get_constant_long (p, 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f); - - orc_sse_emit_pshufb (p, tmp, dest); + if (tmp != ORC_REG_INVALID) { + orc_sse_emit_pshufb (p, tmp, dest); + } else { + sse_rule_swapl (p, user, insn); + } } static void @@ -1573,10 +1580,13 @@ sse_rule_swapq_ssse3 (OrcCompiler *p, void *user, OrcInstruction *insn) int dest = p->vars[insn->dest_args[0]].alloc; int tmp; - tmp = orc_compiler_get_constant_long (p, + tmp = orc_compiler_try_get_constant_long (p, 0x04050607, 0x00010203, 0x0c0d0e0f, 0x08090a0b); - - orc_sse_emit_pshufb (p, tmp, dest); + if (tmp != ORC_REG_INVALID) { + orc_sse_emit_pshufb (p, tmp, dest); + } else { + sse_rule_swapq (p, user, insn); + } } static void @@ -1585,10 +1595,13 @@ sse_rule_select0lw_ssse3 (OrcCompiler *p, void *user, OrcInstruction *insn) int dest = p->vars[insn->dest_args[0]].alloc; int tmp; - tmp = orc_compiler_get_constant_long (p, + tmp = orc_compiler_try_get_constant_long (p, 0x05040100, 0x0d0c0908, 0x05040100, 0x0d0c0908); - - orc_sse_emit_pshufb (p, tmp, dest); + if (tmp != ORC_REG_INVALID) { + orc_sse_emit_pshufb (p, tmp, dest); + } else { + sse_rule_select0lw (p, user, insn); + } } static void @@ -1597,10 +1610,13 @@ sse_rule_select1lw_ssse3 (OrcCompiler *p, void *user, OrcInstruction *insn) int dest = p->vars[insn->dest_args[0]].alloc; int tmp; - tmp = orc_compiler_get_constant_long (p, + tmp = orc_compiler_try_get_constant_long (p, 0x07060302, 0x0f0e0b0a, 0x07060302, 0x0f0e0b0a); - - orc_sse_emit_pshufb (p, tmp, dest); + if (tmp != ORC_REG_INVALID) { + orc_sse_emit_pshufb (p, tmp, dest); + } else { + sse_rule_select1lw (p, user, insn); + } } static void @@ -1609,10 +1625,13 @@ sse_rule_select0wb_ssse3 (OrcCompiler *p, void *user, OrcInstruction *insn) int dest = p->vars[insn->dest_args[0]].alloc; int tmp; - tmp = orc_compiler_get_constant_long (p, + tmp = orc_compiler_try_get_constant_long (p, 0x06040200, 0x0e0c0a08, 0x06040200, 0x0e0c0a08); - - orc_sse_emit_pshufb (p, tmp, dest); + if (tmp != ORC_REG_INVALID) { + orc_sse_emit_pshufb (p, tmp, dest); + } else { + sse_rule_select0wb (p, user, insn); + } } static void @@ -1621,10 +1640,13 @@ sse_rule_select1wb_ssse3 (OrcCompiler *p, void *user, OrcInstruction *insn) int dest = p->vars[insn->dest_args[0]].alloc; int tmp; - tmp = orc_compiler_get_constant_long (p, + tmp = orc_compiler_try_get_constant_long (p, 0x07050301, 0x0f0d0b09, 0x07050301, 0x0f0d0b09); - - orc_sse_emit_pshufb (p, tmp, dest); + if (tmp != ORC_REG_INVALID) { + orc_sse_emit_pshufb (p, tmp, dest); + } else { + sse_rule_select1wb (p, user, insn); + } } #endif |