summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Emont <guijemont@igalia.com>2012-12-19 14:39:05 +0100
committerGuillaume Emont <guijemont@igalia.com>2012-12-28 15:23:39 +0100
commit097221af38a1432078a1690a43cb15e73bf6524b (patch)
treea62e579c95510617867866e68bea934c998b5a44
parent9d39b049b9faaf302ff063115ffcafe7051512ee (diff)
mips: added cache prefetching hints
-rw-r--r--orc/orcmips.c17
-rw-r--r--orc/orcmips.h2
-rw-r--r--orc/orcprogram-mips.c42
3 files changed, 58 insertions, 3 deletions
diff --git a/orc/orcmips.c b/orc/orcmips.c
index e133a15..d2d26ae 100644
--- a/orc/orcmips.c
+++ b/orc/orcmips.c
@@ -941,4 +941,21 @@ orc_mips_emit_seh (OrcCompiler *compiler,
source, dest,
030, /* SEH */
040 /* BSHFL */));
+
+}
+
+void
+orc_mips_emit_pref (OrcCompiler *compiler,
+ int hint,
+ OrcMipsRegister base,
+ int offset)
+{
+ ORC_ASM_CODE (compiler, " pref %d, %d(%s)\n",
+ hint, offset, orc_mips_reg_name (base));
+ orc_mips_emit (compiler,
+ 063 << 26 /* PREF */
+ | (base - ORC_GP_REG_BASE) << 21
+ | (hint & 0x1f) << 16
+ | (offset & 0xffff));
+
}
diff --git a/orc/orcmips.h b/orc/orcmips.h
index 1e42902..431551a 100644
--- a/orc/orcmips.h
+++ b/orc/orcmips.h
@@ -187,6 +187,8 @@ void orc_mips_emit_align (OrcCompiler *compiler, int align_shift);
void orc_mips_emit_wsbh (OrcCompiler *compiler, OrcMipsRegister dest, OrcMipsRegister source);
void orc_mips_emit_seh (OrcCompiler *compiler, OrcMipsRegister dest, OrcMipsRegister source);
+void orc_mips_emit_pref (OrcCompiler *compiler, int hint, OrcMipsRegister base, int offset);
+
void orc_mips_do_fixups (OrcCompiler *compiler);
/* ORC_STRUCT_OFFSET doesn't work for cross-compiling, so we use that */
diff --git a/orc/orcprogram-mips.c b/orc/orcprogram-mips.c
index a93cb48..b1a5498 100644
--- a/orc/orcprogram-mips.c
+++ b/orc/orcprogram-mips.c
@@ -311,6 +311,37 @@ orc_mips_load_constants_inner (OrcCompiler *compiler)
}
}
+#define CACHE_LINE_SIZE 32
+
+void
+orc_mips_emit_var_pref (OrcCompiler *compiler, int iter_offset, int total_shift)
+{
+ int i, j;
+ int offset = 0;
+ /* prefetch stuff into cache */
+ for (i=0; i<ORC_N_COMPILER_VARIABLES; i++) {
+ OrcVariable *var = compiler->vars + i;
+
+ if (var->name == NULL) continue;
+ if (var->vartype == ORC_VAR_TYPE_SRC) {
+ if (var->update_type == 0) {
+ offset = 0;
+ } else if (var->update_type == 1) {
+ offset = (var->size << total_shift) >> 1;
+ } else {
+ offset = var->size << total_shift;
+ }
+ for (j = iter_offset*offset; j < (iter_offset+1)*offset; j+=CACHE_LINE_SIZE)
+ orc_mips_emit_pref (compiler, 4 /* load-streamed */,
+ var->ptr_register, iter_offset * offset + j*CACHE_LINE_SIZE);
+ } else if (var->vartype == ORC_VAR_TYPE_DEST) {
+ for (j = iter_offset*offset; j < (iter_offset+1)*offset; j+=CACHE_LINE_SIZE)
+ orc_mips_emit_pref (compiler, 5 /* store-streamed */,
+ var->ptr_register, iter_offset * offset + j*CACHE_LINE_SIZE);
+ }
+ }
+}
+
void
orc_mips_emit_loop (OrcCompiler *compiler, int unroll)
{
@@ -319,11 +350,18 @@ orc_mips_emit_loop (OrcCompiler *compiler, int unroll)
OrcInstruction *insn;
OrcStaticOpcode *opcode;
OrcRule *rule;
+ int total_shift = compiler->loop_shift;
ORC_DEBUG ("loop_shift=%d", compiler->loop_shift);
if (unroll)
+ total_shift += compiler->unroll_shift;
+
+
+ if (unroll)
iteration_per_loop = 1 << compiler->unroll_shift;
+ orc_mips_emit_var_pref (compiler, 1, total_shift);
+
for (j=0; j<iteration_per_loop; j++) {
compiler->unroll_index = j;
for (i=0; i<compiler->n_insns; i++) {
@@ -355,9 +393,6 @@ orc_mips_emit_loop (OrcCompiler *compiler, int unroll)
for (j=0; j<ORC_N_COMPILER_VARIABLES; j++) {
OrcVariable *var = compiler->vars + j;
- int total_shift = compiler->loop_shift;
- if (unroll)
- total_shift += compiler->unroll_shift;
if (var->name == NULL) continue;
if (var->vartype == ORC_VAR_TYPE_SRC ||
@@ -443,6 +478,7 @@ orc_mips_emit_full_loop (OrcCompiler *compiler, OrcMipsRegister counter,
compiler->loop_shift = loop_shift;
saved_alignment = orc_mips_get_alignment (compiler);
orc_mips_set_alignment (compiler, alignment);
+ orc_mips_emit_var_pref (compiler, 0, compiler->loop_shift + unroll * compiler->unroll_shift);
orc_mips_emit_loop (compiler, unroll);
orc_mips_set_alignment (compiler, saved_alignment);
compiler->loop_shift = saved_loop_shift;