From 72f0fcb729762ef808eb16c2706c2e76cca5f6f8 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Tue, 7 Sep 2010 21:09:51 -0700 Subject: compiler: Implement long (128-bit) constants --- orc/orccompiler.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- orc/orcprogram-sse.c | 38 +++++++++++++++++++++++++++++++++++--- orc/orcprogram.h | 7 ++++++- 3 files changed, 88 insertions(+), 5 deletions(-) diff --git a/orc/orccompiler.c b/orc/orccompiler.c index acfda58..512bb46 100644 --- a/orc/orccompiler.c +++ b/orc/orccompiler.c @@ -984,6 +984,13 @@ orc_compiler_load_constant (OrcCompiler *compiler, int reg, int size, compiler->target->load_constant (compiler, reg, size, value); } +void +orc_compiler_load_constant_long (OrcCompiler *compiler, int reg, + OrcConstant *constant) +{ + compiler->target->load_constant_long (compiler, reg, constant); +} + int orc_compiler_get_temp_constant (OrcCompiler *compiler, int size, int value) { @@ -1010,7 +1017,8 @@ orc_compiler_get_constant (OrcCompiler *compiler, int size, int value) } for(i=0;in_constants;i++){ - if (compiler->constants[i].value == value) { + if (compiler->constants[i].is_long == FALSE && + compiler->constants[i].value == value) { break; } } @@ -1019,6 +1027,7 @@ orc_compiler_get_constant (OrcCompiler *compiler, int size, int value) compiler->constants[i].value = value; compiler->constants[i].alloc_reg = 0; compiler->constants[i].use_count = 0; + compiler->constants[i].is_long = FALSE; } compiler->constants[i].use_count++; @@ -1031,6 +1040,43 @@ orc_compiler_get_constant (OrcCompiler *compiler, int size, int value) return tmp; } +int +orc_compiler_get_constant_long (OrcCompiler *compiler, + orc_uint32 a, orc_uint32 b, orc_uint32 c, orc_uint32 d) +{ + int i; + int tmp; + + for(i=0;in_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; + } + tmp = orc_compiler_get_temp_reg (compiler); + orc_compiler_load_constant_long (compiler, tmp, &compiler->constants[i]); + return tmp; +} + int orc_compiler_get_constant_reg (OrcCompiler *compiler) { diff --git a/orc/orcprogram-sse.c b/orc/orcprogram-sse.c index e1a1153..435630e 100644 --- a/orc/orcprogram-sse.c +++ b/orc/orcprogram-sse.c @@ -30,6 +30,8 @@ void orc_sse_emit_invariants (OrcCompiler *compiler); void orc_compiler_rewrite_vars (OrcCompiler *compiler); void orc_compiler_dump (OrcCompiler *compiler); void sse_load_constant (OrcCompiler *compiler, int reg, int size, int value); +void sse_load_constant_long (OrcCompiler *compiler, int reg, + OrcConstant *constant); static const char * sse_get_flag_name (int shift); static OrcTarget sse_target = { @@ -48,7 +50,8 @@ static OrcTarget sse_target = { NULL, sse_load_constant, sse_get_flag_name, - NULL + NULL, + sse_load_constant_long }; @@ -393,6 +396,30 @@ sse_load_constant (OrcCompiler *compiler, int reg, int size, int value) #endif } +void +sse_load_constant_long (OrcCompiler *compiler, int reg, + OrcConstant *constant) +{ + int i; + int offset = ORC_STRUCT_OFFSET(OrcExecutor,arrays[ORC_VAR_T1]); + + /* FIXME this is slower than it could be */ + + ORC_ASM_CODE(compiler, "# loading constant %08x %08x %08x %08x\n", + constant->full_value[0], constant->full_value[1], + constant->full_value[2], constant->full_value[3]); + + for(i=0;i<4;i++){ + orc_x86_emit_mov_imm_reg (compiler, 4, constant->full_value[i], + compiler->gp_tmpreg); + orc_x86_emit_mov_reg_memoffset (compiler, 4, compiler->gp_tmpreg, + offset + 4*i, compiler->exec_reg); + } + orc_x86_emit_mov_memoffset_sse (compiler, 16, offset, compiler->exec_reg, + reg, FALSE); + +} + void sse_load_constants_outer (OrcCompiler *compiler) { @@ -429,8 +456,13 @@ sse_load_constants_outer (OrcCompiler *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); + if (compiler->constants[i].is_long) { + sse_load_constant_long (compiler, compiler->constants[i].alloc_reg, + compiler->constants + i); + } else { + sse_load_constant (compiler, compiler->constants[i].alloc_reg, + 4, compiler->constants[i].value); + } } } } diff --git a/orc/orcprogram.h b/orc/orcprogram.h index 1185667..634ea27 100644 --- a/orc/orcprogram.h +++ b/orc/orcprogram.h @@ -325,6 +325,7 @@ struct _OrcConstant { unsigned int value; unsigned int full_value[4]; int use_count; + int is_long; }; /** @@ -603,8 +604,10 @@ struct _OrcTarget { void (*load_constant)(OrcCompiler *compiler, int reg, int size, int value); const char * (*get_flag_name)(int shift); void (*flush_cache) (OrcCode *code); + void (*load_constant_long)(OrcCompiler *compiler, int reg, + OrcConstant *constant); - void *_unused[6]; + void *_unused[5]; }; @@ -714,6 +717,8 @@ int orc_program_allocate_register (OrcProgram *program, int is_data); void orc_code_allocate_codemem (OrcCode *code, int size); 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_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); -- cgit v1.2.3