From bcaa3c3af0f0f8dd5a4640d1ce31a15ea54a70b6 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Tue, 10 Aug 2010 22:16:50 -0700 Subject: [PATCH] Better constant loading --- orc/orccompiler.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ orc/orcprogram-sse.c | 26 +++++++++++++++++++++++- orc/orcprogram.h | 3 +++ orc/orcrules-sse.c | 36 +++++++++++++++++---------------- 4 files changed, 103 insertions(+), 18 deletions(-) diff --git a/orc/orccompiler.c b/orc/orccompiler.c index 6980bb5..a7ecabf 100644 --- a/orc/orccompiler.c +++ b/orc/orccompiler.c @@ -581,6 +581,11 @@ orc_compiler_get_temp_reg (OrcCompiler *compiler) compiler->alloc_regs[compiler->vars[j].alloc] = 1; } } + for(j=0;jn_constants;j++){ + if (compiler->constants[j].alloc_reg) { + compiler->alloc_regs[compiler->constants[j].alloc_reg] = 1; + } + } ORC_DEBUG("at insn %d", compiler->insn_index); for(j=0;j<8;j++){ @@ -924,6 +929,16 @@ orc_compiler_load_constant (OrcCompiler *compiler, int reg, int size, } int +orc_compiler_get_temp_constant (OrcCompiler *compiler, int size, int value) +{ + int tmp; + + tmp = orc_compiler_get_temp_reg (compiler); + orc_compiler_load_constant (compiler, tmp, size, value); + return tmp; +} + +int orc_compiler_get_constant (OrcCompiler *compiler, int size, int value) { int i; @@ -960,3 +975,44 @@ orc_compiler_get_constant (OrcCompiler *compiler, int size, int value) return tmp; } +int +orc_compiler_get_constant_reg (OrcCompiler *compiler) +{ + int j; + + for(j=0;jalloc_regs[j] = 0; + } + for(j=0;jvars[j].alloc) continue; + + ORC_DEBUG("var %d: %d %d %d", j, compiler->vars[j].alloc, + compiler->vars[j].first_use, + compiler->vars[j].last_use); + + if (compiler->vars[j].first_use == -1) { + compiler->alloc_regs[compiler->vars[j].alloc] = 1; + } else if (compiler->vars[j].last_use != -1) { + compiler->alloc_regs[compiler->vars[j].alloc] = 1; + } + } + for(j=0;jn_constants;j++){ + if (compiler->constants[j].alloc_reg) { + compiler->alloc_regs[compiler->constants[j].alloc_reg] = 1; + } + } + + for(j=0;j<8;j++){ + ORC_DEBUG("xmm%d: %d %d", j, compiler->valid_regs[ORC_VEC_REG_BASE + j], + compiler->alloc_regs[ORC_VEC_REG_BASE + j]); + } + + for(j=compiler->min_temp_reg;jvalid_regs[j] && !compiler->alloc_regs[j]) { + return j; + } + } + + return 0; +} + diff --git a/orc/orcprogram-sse.c b/orc/orcprogram-sse.c index 3d5bc5e..0024f0b 100644 --- a/orc/orcprogram-sse.c +++ b/orc/orcprogram-sse.c @@ -306,17 +306,20 @@ sse_load_constant (OrcCompiler *compiler, int reg, int size, int value) value |= (value << 16); } + ORC_ASM_CODE(compiler, "# loading constant %d 0x%08x\n", value, value); if (value == 0) { orc_sse_emit_pxor(compiler, reg, reg); return; } if (value == 0xffffffff) { orc_sse_emit_pcmpeqb (compiler, reg, reg); + return; } if (compiler->target_flags & ORC_TARGET_SSE_SSSE3) { if (value == 0x01010101) { orc_sse_emit_pcmpeqb (compiler, reg, reg); orc_sse_emit_pabsb (compiler, reg, reg); + return; } } @@ -375,7 +378,7 @@ sse_load_constants_outer (OrcCompiler *compiler) case ORC_VAR_TYPE_DEST: break; case ORC_VAR_TYPE_ACCUMULATOR: - orc_sse_emit_660f (compiler, "pxor", 0xef, + orc_sse_emit_pxor (compiler, compiler->vars[i].alloc, compiler->vars[i].alloc); break; case ORC_VAR_TYPE_TEMP: @@ -388,6 +391,18 @@ sse_load_constants_outer (OrcCompiler *compiler) orc_sse_emit_invariants (compiler); + /* FIXME move to a better place */ + for(i=0;in_constants;i++){ + compiler->constants[i].alloc_reg = + orc_compiler_get_constant_reg (compiler); + } + + for(i=0;in_constants;i++){ + if (compiler->constants[i].alloc_reg) { + sse_load_constant (compiler, compiler->constants[i].alloc_reg, + 4, compiler->constants[i].value); + } + } } void @@ -619,6 +634,15 @@ orc_compiler_sse_assemble (OrcCompiler *compiler) compiler->vars[align_var].is_aligned = FALSE; + { + orc_sse_emit_loop (compiler, 0, 0); + + compiler->codeptr = compiler->program->code; + free (compiler->asm_code); + compiler->asm_code = NULL; + compiler->asm_code_len = 0; + } + orc_x86_emit_prologue (compiler); #ifndef MMX diff --git a/orc/orcprogram.h b/orc/orcprogram.h index 97ea55c..5586534 100644 --- a/orc/orcprogram.h +++ b/orc/orcprogram.h @@ -648,7 +648,10 @@ int orc_program_allocate_register (OrcProgram *program, int is_data); void orc_compiler_allocate_codemem (OrcCompiler *compiler); int orc_compiler_label_new (OrcCompiler *compiler); int orc_compiler_get_constant (OrcCompiler *compiler, int size, int value); +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); + const char *orc_program_get_asm_code (OrcProgram *program); const char *orc_target_get_asm_preamble (const char *target); diff --git a/orc/orcrules-sse.c b/orc/orcrules-sse.c index b709a4b..4e8c63b 100644 --- a/orc/orcrules-sse.c +++ b/orc/orcrules-sse.c @@ -46,6 +46,8 @@ sse_rule_loadpX (OrcCompiler *compiler, void *user, OrcInstruction *insn) #endif } else if (src->vartype == ORC_VAR_TYPE_CONST) { sse_load_constant (compiler, dest->alloc, src->size, src->value); + } else { + ORC_ASSERT(0); } } @@ -515,7 +517,7 @@ sse_rule_signX_ssse3 (OrcCompiler *p, void *user, OrcInstruction *insn) int type = ORC_PTR_TO_INT(user); int tmpc; - tmpc = orc_compiler_get_constant (p, 1<vars[insn->src_args[1]].alloc; int dest = p->vars[insn->dest_args[0]].alloc; - int tmp; + int tmp = orc_compiler_get_temp_reg (p); + int tmpc; - tmp = orc_compiler_get_constant (p, 4, 0x80000000); - orc_sse_emit_pxor(p, tmp, src); - orc_sse_emit_pxor(p, tmp, dest); + tmpc = orc_compiler_get_constant (p, 4, 0x80000000); + orc_sse_emit_pxor(p, tmpc, src); + orc_sse_emit_pxor(p, tmpc, dest); orc_sse_emit_movdqa (p, dest, tmp); orc_sse_emit_pcmpgtd (p, src, tmp); @@ -1767,9 +1770,8 @@ sse_rule_maxul_slow (OrcCompiler *p, void *user, OrcInstruction *insn) orc_sse_emit_pandn (p, src, tmp); orc_sse_emit_por (p, tmp, dest); - tmp = orc_compiler_get_constant (p, 4, 0x80000000); - orc_sse_emit_pxor(p, tmp, src); - orc_sse_emit_pxor(p, tmp, dest); + orc_sse_emit_pxor(p, tmpc, src); + orc_sse_emit_pxor(p, tmpc, dest); } static void @@ -1777,11 +1779,12 @@ sse_rule_minul_slow (OrcCompiler *p, void *user, OrcInstruction *insn) { int src = p->vars[insn->src_args[1]].alloc; int dest = p->vars[insn->dest_args[0]].alloc; - int tmp; + int tmp = orc_compiler_get_temp_reg (p); + int tmpc; - tmp = orc_compiler_get_constant (p, 4, 0x80000000); - orc_sse_emit_pxor(p, tmp, src); - orc_sse_emit_pxor(p, tmp, dest); + tmpc = orc_compiler_get_constant (p, 4, 0x80000000); + orc_sse_emit_pxor(p, tmpc, src); + orc_sse_emit_pxor(p, tmpc, dest); orc_sse_emit_movdqa (p, src, tmp); orc_sse_emit_pcmpgtd (p, dest, tmp); @@ -1789,9 +1792,8 @@ sse_rule_minul_slow (OrcCompiler *p, void *user, OrcInstruction *insn) orc_sse_emit_pandn (p, src, tmp); orc_sse_emit_por (p, tmp, dest); - tmp = orc_compiler_get_constant (p, 4, 0x80000000); - orc_sse_emit_pxor(p, tmp, src); - orc_sse_emit_pxor(p, tmp, dest); + orc_sse_emit_pxor(p, tmpc, src); + orc_sse_emit_pxor(p, tmpc, dest); } static void @@ -1917,7 +1919,7 @@ sse_rule_subssl_slow (OrcCompiler *p, void *user, OrcInstruction *insn) int tmp2 = orc_compiler_get_temp_reg (p); int tmp3 = orc_compiler_get_temp_reg (p); - tmp = orc_compiler_get_constant (p, 4, 0xffffffff); + tmp = orc_compiler_get_temp_constant (p, 4, 0xffffffff); orc_sse_emit_pxor (p, src, tmp); orc_sse_emit_movdqa (p, tmp, tmp2); orc_sse_emit_por (p, dest, tmp); -- 2.7.4