summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Schleef <ds@schleef.org>2010-09-08 13:29:02 -0700
committerDavid Schleef <ds@schleef.org>2010-09-08 13:35:00 -0700
commit890139b611605b71b44f83a8571fffdbe887588e (patch)
tree0c9fd01c5d91114426d4324e49df4b1129ce4e81
parenta02f8ced722af1c9fd97adc2b7ba78478bc33b46 (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.c35
-rw-r--r--orc/orcprogram.h2
-rw-r--r--orc/orcrules-sse.c62
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