diff options
author | Guillaume Emont <guijemont@igalia.com> | 2012-12-19 14:39:05 +0100 |
---|---|---|
committer | Guillaume Emont <guijemont@igalia.com> | 2012-12-28 15:23:39 +0100 |
commit | 097221af38a1432078a1690a43cb15e73bf6524b (patch) | |
tree | a62e579c95510617867866e68bea934c998b5a44 | |
parent | 9d39b049b9faaf302ff063115ffcafe7051512ee (diff) |
mips: added cache prefetching hints
-rw-r--r-- | orc/orcmips.c | 17 | ||||
-rw-r--r-- | orc/orcmips.h | 2 | ||||
-rw-r--r-- | orc/orcprogram-mips.c | 42 |
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; |