AC_DEFINE(HAVE_MONOTONIC_CLOCK,1,[Defined if we have a monotonic clock])
fi
+AC_CHECK_HEADERS([valgrind/valgrind.h])
+
AS_COMPILER_FLAG(-Wall, ORC_CFLAGS="$ORC_CFLAGS -Wall")
if test "x$ORC_CVS" = "xyes"
then
fclose (file);
file = fopen (dump_filename, "w");
- ret = fwrite(p->code, p->code_size, 1, file);
+ ret = fwrite(p->orccode->code, p->orccode->code_size, 1, file);
fclose (file);
#if defined(HAVE_POWERPC)
fclose (file);
file = fopen (dump_filename, "w");
- ret = fwrite(p->code, p->code_size, 1, file);
+ ret = fwrite(p->orccode->code, p->orccode->code_size, 1, file);
fclose (file);
sprintf (cmd, PREFIX "gcc -march=armv6t2 -mcpu=cortex-a8 -mfpu=neon -Wall "
fclose (file);
file = fopen (dump_filename, "w");
- ret = fwrite(p->code, p->code_size, 1, file);
+ ret = fwrite(p->orccode->code, p->orccode->code_size, 1, file);
fclose (file);
sprintf (cmd, C64X_PREFIX "cl6x -mv=6400+ "
result = orc_program_compile_full (program, target, flags);
if (ORC_COMPILE_RESULT_IS_FATAL(result)) {
- return ORC_TEST_FAILED;
+ ret = ORC_TEST_FAILED;
+ goto out;
}
if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL(result)) {
- return ORC_TEST_INDETERMINATE;
+ ret = ORC_TEST_INDETERMINATE;
+ goto out;
}
}
orc_executor_free (ex);
+out:
+ orc_program_reset (program);
+
return ret;
}
result = orc_program_compile_full (program, target, flags);
if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL(result)) {
//printf("compile failed\n");
+ orc_program_reset (program);
return 0;
}
}
}
orc_executor_free (ex);
+ orc_program_reset (program);
return ave/(n*m);
}
{
int diff;
- diff = (compiler->program->code - compiler->codeptr)&((1<<align_shift) - 1);
+ diff = (compiler->code - compiler->codeptr)&((1<<align_shift) - 1);
while (diff) {
orc_arm_emit_nop (compiler);
diff-=4;
}
void
-orc_arm_flush_cache (OrcCompiler *compiler)
+orc_arm_flush_cache (OrcCode *code)
{
#ifdef HAVE_ARM
- __clear_cache (compiler->program->code, compiler->codeptr);
+ __clear_cache (code->code, code->code + code->code_size);
#endif
}
int Rd, int Rm);
void orc_arm_emit_nop (OrcCompiler *compiler);
-void orc_arm_flush_cache (OrcCompiler *compiler);
+void orc_arm_flush_cache (OrcCode *code);
/* ALL cpus */
/* data procesing instructions */
{
if (code->insns) {
free (code->insns);
+ code->insns = NULL;
+ }
+ if (code->vars) {
+ free (code->vars);
+ code->vars = NULL;
+ }
+ if (code->chunk) {
+ orc_code_chunk_free (code->chunk);
+ code->chunk = NULL;
}
free (code);
#define SIZE 65536
typedef struct _OrcCodeRegion OrcCodeRegion;
-typedef struct _OrcCodeChunk OrcCodeChunk;
struct _OrcCodeRegion {
orc_uint8 *write_ptr;
}
void
-orc_compiler_allocate_codemem (OrcCompiler *compiler)
+orc_code_allocate_codemem (OrcCode *code, int size)
{
OrcCodeRegion *region;
OrcCodeChunk *chunk;
- int size = 4096;
+ int aligned_size = (size + 15) & (~15);
- chunk = orc_code_region_get_free_chunk (size);
+ chunk = orc_code_region_get_free_chunk (aligned_size);
region = chunk->region;
- if (chunk->size > size) {
- orc_code_chunk_split (chunk, size);
+ if (chunk->size > aligned_size) {
+ orc_code_chunk_split (chunk, aligned_size);
}
chunk->used = TRUE;
- compiler->program->code = ORC_PTR_OFFSET(region->write_ptr, chunk->offset);
- compiler->program->code_exec = ORC_PTR_OFFSET(region->exec_ptr, chunk->offset);
- compiler->program->code_size = chunk->size;
- compiler->codeptr = ORC_PTR_OFFSET(region->write_ptr, chunk->offset);
+ code->chunk = chunk;
+ code->code = ORC_PTR_OFFSET(region->write_ptr, chunk->offset);
+ code->exec = ORC_PTR_OFFSET(region->exec_ptr, chunk->offset);
+ code->code_size = size;
+ //compiler->codeptr = ORC_PTR_OFFSET(region->write_ptr, chunk->offset);
}
+void
+orc_code_chunk_free (OrcCodeChunk *chunk)
+{
+ if (_orc_compiler_flag_debug) {
+ /* If debug is turned on, don't free code */
+ return;
+ }
-
+ chunk->used = FALSE;
+ if (chunk->next && !chunk->next->used) {
+ orc_code_chunk_merge (chunk);
+ }
+ if (chunk->prev && !chunk->prev->used) {
+ orc_code_chunk_merge (chunk->prev);
+ }
+}
#ifdef HAVE_CODEMEM_MMAP
void
#include <orc/orcprogram.h>
#include <orc/orcdebug.h>
+#ifdef HAVE_VALGRIND_VALGRIND_H
+#include <valgrind/valgrind.h>
+#endif
+
/**
* SECTION:orccompiler
* @title: OrcCompiler
memset (compiler, 0, sizeof(OrcCompiler));
if (program->backup_func) {
- program->code = program->backup_func;
+ program->code_exec = program->backup_func;
} else {
- program->code = (void *)orc_executor_emulate;
+ program->code_exec = (void *)orc_executor_emulate;
}
compiler->program = program;
orc_compiler_rewrite_insns (compiler);
if (compiler->error) goto error;
- orc_compiler_assign_rules (compiler);
- if (compiler->error) goto error;
-
orc_compiler_rewrite_vars (compiler);
if (compiler->error) goto error;
orc_compiler_global_reg_alloc (compiler);
orc_compiler_rewrite_vars2 (compiler);
+
#if 0
{
ORC_ERROR("variables");
if (compiler->error) goto error;
+ program->orccode = orc_code_new ();
+
+ program->orccode->is_2d = program->is_2d;
+ program->orccode->constant_n = program->constant_n;
+ program->orccode->constant_m = program->constant_m;
+
+ program->orccode->n_insns = compiler->n_insns;
+ program->orccode->insns = malloc(sizeof(OrcInstruction) * compiler->n_insns);
+ memcpy (program->orccode->insns, compiler->insns,
+ sizeof(OrcInstruction) * compiler->n_insns);
+
+ program->orccode->vars = malloc (sizeof(OrcCodeVariable) * ORC_N_COMPILER_VARIABLES);
+ memset (program->orccode->vars, 0,
+ sizeof(OrcCodeVariable) * ORC_N_COMPILER_VARIABLES);
+ for(i=0;i<ORC_N_COMPILER_VARIABLES;i++){
+ program->orccode->vars[i].vartype = compiler->vars[i].vartype;
+ program->orccode->vars[i].size = compiler->vars[i].size;
+ program->orccode->vars[i].value = compiler->vars[i].value;
+ }
+
+ orc_compiler_assign_rules (compiler);
+ if (compiler->error) goto error;
+
ORC_INFO("allocating code memory");
- orc_compiler_allocate_codemem (compiler);
+ compiler->code = malloc(65536);
+ compiler->codeptr = compiler->code;
+
if (compiler->error) goto error;
ORC_INFO("compiling for target \"%s\"", compiler->target->name);
goto error;
}
- program->orccode = orc_code_new ();
- program->orccode->exec = program->code_exec;
- program->orccode->code = program->code;
- program->orccode->code_size = compiler->codeptr - program->code;
- program->orccode->is_2d = program->is_2d;
- program->orccode->constant_n = program->constant_n;
- program->orccode->constant_m = program->constant_m;
+ orc_code_allocate_codemem (program->orccode, program->orccode->code_size);
+ program->orccode->code_size = compiler->codeptr - compiler->code;
- program->orccode->n_insns = compiler->n_insns;
- program->orccode->insns = malloc(sizeof(OrcInstruction) * compiler->n_insns);
- memcpy (program->orccode->insns, compiler->insns,
- sizeof(OrcInstruction) * compiler->n_insns);
+ memcpy (program->orccode->code, compiler->code, program->orccode->code_size);
- program->orccode->vars = malloc (sizeof(OrcVariable) * ORC_N_COMPILER_VARIABLES);
- memcpy (program->orccode->vars, compiler->vars,
- sizeof(OrcVariable) * ORC_N_COMPILER_VARIABLES);
+#ifdef VALGRIND_DISCARD_TRANSLATIONS
+ VALGRIND_DISCARD_TRANSLATIONS (program->orccode->exec,
+ program->orccode->code_size);
+#endif
+
+ if (compiler->target->flush_cache) {
+ compiler->target->flush_cache (program->orccode);
+ }
+
+ program->code_exec = program->orccode->exec;
program->asm_code = compiler->asm_code;
- program->code_size = compiler->codeptr - program->code;
result = compiler->result;
for (i=0;i<compiler->n_dup_vars;i++){
free(compiler->vars[ORC_VAR_T1 + compiler->n_temp_vars + i].name);
+ compiler->vars[ORC_VAR_T1 + compiler->n_temp_vars + i].name = NULL;
}
+ free (compiler->code);
+ compiler->code = NULL;
free (compiler);
ORC_INFO("finished compiling (success)");
if (result == 0) {
result = ORC_COMPILE_RESULT_UNKNOWN_COMPILE;
}
- program->code_exec = program->backup_func;
- if (compiler->asm_code) free (compiler->asm_code);
+ if (compiler->asm_code) {
+ free (compiler->asm_code);
+ compiler->asm_code = NULL;
+ }
for (i=0;i<compiler->n_dup_vars;i++){
free(compiler->vars[ORC_VAR_T1 + compiler->n_temp_vars + i].name);
+ compiler->vars[ORC_VAR_T1 + compiler->n_temp_vars + i].name = NULL;
}
+ free (compiler->code);
+ compiler->code = NULL;
free (compiler);
ORC_INFO("finished compiling (fail)");
return result;
}
for(i=0;i<ORC_N_COMPILER_VARIABLES;i++){
- OrcVariable *var = code->vars + i;
+ OrcCodeVariable *var = code->vars + i;
if (var->size) {
tmpspace[i] = malloc(ORC_MAX_VAR_SIZE * CHUNK_SIZE);
}
for(k=0;k<ORC_STATIC_OPCODE_N_SRC;k++) {
- OrcVariable *var = code->vars + insn->src_args[k];
+ OrcCodeVariable *var = code->vars + insn->src_args[k];
if (opcode->src_size[k] == 0) continue;
if (var->vartype == ORC_VAR_TYPE_CONST) {
}
}
for(k=0;k<ORC_STATIC_OPCODE_N_DEST;k++) {
- OrcVariable *var = code->vars + insn->dest_args[k];
+ OrcCodeVariable *var = code->vars + insn->dest_args[k];
if (opcode->dest_size[k] == 0) continue;
if (var->vartype == ORC_VAR_TYPE_TEMP) {
opcode = insn->opcode;
for(k=0;k<ORC_STATIC_OPCODE_N_SRC;k++) {
- OrcVariable *var = code->vars + insn->src_args[k];
+ OrcCodeVariable *var = code->vars + insn->src_args[k];
+ if (opcode->src_size[k] == 0) continue;
if (var->vartype == ORC_VAR_TYPE_SRC) {
opcode_ex[j].src_ptrs[k] =
}
}
for(k=0;k<ORC_STATIC_OPCODE_N_DEST;k++) {
- OrcVariable *var = code->vars + insn->dest_args[k];
+ OrcCodeVariable *var = code->vars + insn->dest_args[k];
+ if (opcode->dest_size[k] == 0) continue;
if (var->vartype == ORC_VAR_TYPE_DEST) {
opcode_ex[j].dest_ptrs[k] =
*(unsigned int *)ptr = (insn&0xffff0000) | ((insn + (label-ptr))&0xffff);
break;
case 1:
- *(unsigned int *)ptr = (insn&0xffff0000) | ((insn + (label-compiler->program->code))&0xffff);
+ *(unsigned int *)ptr = (insn&0xffff0000) | ((insn + (label-compiler->code))&0xffff);
break;
case 2:
*(unsigned int *)ptr = (insn&0xfc000000) | ((insn + (label-ptr))&0x03ffffff);
}
void
-powerpc_flush (OrcCompiler *compiler)
+orc_powerpc_flush_cache (OrcCode *code)
{
#ifdef HAVE_POWERPC
unsigned char *ptr;
int cache_line_size = 32;
int i;
- int size = compiler->codeptr - compiler->program->code;
+ int size = code->code_size;
- ptr = compiler->program->code;
+ ptr = code->code;
for (i=0;i<size;i+=cache_line_size) {
__asm__ __volatile__ ("dcbst %0,%1" :: "r" (ptr), "r" (i));
}
__asm__ __volatile ("sync");
- ptr = compiler->program->code_exec;
+ ptr = code->exec;
for (i=0;i<size;i+=cache_line_size) {
__asm__ __volatile__ ("icbi %0,%1" :: "r" (ptr), "r" (i));
}
powerpc_emit_b (p, label_skip);
- while ((p->codeptr - p->program->code) & 0xf) {
+ while ((p->codeptr - p->code) & 0xf) {
ORC_ASM_CODE(p," .long 0x00000000\n");
powerpc_emit (p, 0x00000000);
}
void powerpc_emit_label (OrcCompiler *compiler, int label);
void powerpc_add_fixup (OrcCompiler *compiler, int type, unsigned char *ptr, int label);
void powerpc_do_fixups (OrcCompiler *compiler);
-void powerpc_flush (OrcCompiler *compiler);
+void orc_powerpc_flush_cache (OrcCode *code);
void powerpc_emit_srawi (OrcCompiler *compiler, int regd, int rega, int shift,
int record);
ORC_VEC_REG_BASE,
orc_compiler_powerpc_get_default_flags,
orc_compiler_powerpc_init,
- orc_compiler_powerpc_assemble
+ orc_compiler_powerpc_assemble,
+ { { 0 } },
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ orc_powerpc_flush_cache
+
};
void
powerpc_emit_epilogue (compiler);
powerpc_do_fixups (compiler);
-
- powerpc_flush (compiler);
}
ORC_GP_REG_BASE,
orc_compiler_orc_arm_get_default_flags,
orc_compiler_orc_arm_init,
- orc_compiler_orc_arm_assemble
+ orc_compiler_orc_arm_assemble,
+ { { 0 } },
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ orc_arm_flush_cache
};
void
0,
NULL,
mmx_load_constant,
- mmx_get_flag_name
+ mmx_get_flag_name,
+ NULL
};
{
orc_mmx_emit_loop (compiler, 0, 0);
- compiler->codeptr = compiler->program->code;
+ compiler->codeptr = compiler->code;
free (compiler->asm_code);
compiler->asm_code = NULL;
compiler->asm_code_len = 0;
ORC_VEC_REG_BASE,
orc_compiler_neon_get_default_flags,
orc_compiler_neon_init,
- orc_compiler_neon_assemble
+ orc_compiler_neon_assemble,
+ { { 0 } }, 0,
+ NULL,
+ NULL,
+ NULL,
+ orc_arm_flush_cache
};
void
orc_arm_emit_data (compiler, 0x0f0e0f0e);
orc_arm_do_fixups (compiler);
-
- orc_arm_flush_cache (compiler);
}
void
0,
NULL,
sse_load_constant,
- sse_get_flag_name
+ sse_get_flag_name,
+ NULL
};
{
orc_sse_emit_loop (compiler, 0, 0);
- compiler->codeptr = compiler->program->code;
+ compiler->codeptr = compiler->code;
free (compiler->asm_code);
compiler->asm_code = NULL;
compiler->asm_code_len = 0;
{
int i;
for(i=0;i<ORC_N_VARIABLES;i++){
- if (program->vars[i].name) free (program->vars[i].name);
+ if (program->vars[i].name) {
+ free (program->vars[i].name);
+ program->vars[i].name = NULL;
+ }
}
if (program->asm_code) {
free (program->asm_code);
+ program->asm_code = NULL;
}
if (program->name) {
free (program->name);
+ program->name = NULL;
}
free (program);
}
}
+void
+orc_program_reset (OrcProgram *program)
+{
+ if (program->orccode) {
+ orc_code_free (program->orccode);
+ program->orccode = NULL;
+ }
+ if (program->asm_code) {
+ free(program->asm_code);
+ program->asm_code = NULL;
+ }
+}
+
+OrcCode *
+orc_program_take_code (OrcProgram *program)
+{
+ OrcCode *code = program->orccode;
+ program->orccode = NULL;
+ return code;
+}
+
typedef struct _OrcFixup OrcFixup;
typedef struct _OrcTarget OrcTarget;
typedef struct _OrcCode OrcCode;
+typedef struct _OrcCodeChunk OrcCodeChunk;
typedef void (*OrcOpcodeEmulateFunc)(OrcOpcodeExecutor *ex, void *user);
typedef void (*OrcOpcodeEmulateNFunc)(OrcOpcodeExecutor *ex, int index, int n);
char *name;
char *asm_code;
- unsigned char *code;
+ unsigned char *_unused2;
+ /* The offset of code_exec in this structure is part of the ABI */
void *code_exec;
- int code_size;
OrcInstruction insns[ORC_N_INSNS];
int n_temp_vars;
int n_dup_vars;
+ unsigned char *code;
unsigned char *codeptr;
OrcConstant constants[ORC_N_CONSTANTS];
#define ORC_EXECUTOR_M_INDEX(ex) ((ex)->params[ORC_VAR_A2])
#define ORC_EXECUTOR_TIME(ex) ((ex)->params[ORC_VAR_A3])
+typedef struct _OrcCodeVariable OrcCodeVariable;
+struct _OrcCodeVariable {
+ /*< private >*/
+ int vartype;
+ int size;
+ int value;
+};
+
struct _OrcCode {
/*< private >*/
OrcCompileResult result;
OrcExecutorFunc exec;
unsigned char *code;
int code_size;
+ void *chunk;
/* for emulation */
int n_insns;
OrcInstruction *insns;
- OrcVariable *vars;
+ OrcCodeVariable *vars;
int is_2d;
int constant_n;
int constant_m;
const char * (*get_asm_preamble)(void);
void (*load_constant)(OrcCompiler *compiler, int reg, int size, int value);
const char * (*get_flag_name)(int shift);
+ void (*flush_cache) (OrcCode *code);
- void *_unused[7];
+ void *_unused[6];
};
int orc_program_allocate_register (OrcProgram *program, int is_data);
-void orc_compiler_allocate_codemem (OrcCompiler *compiler);
+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_temp_constant (OrcCompiler *compiler, int size, int value);
int orc_compiler_get_temp_reg (OrcCompiler *compiler);
int orc_compiler_get_constant_reg (OrcCompiler *compiler);
+void orc_program_reset (OrcProgram *program);
+OrcCode *orc_program_take_code (OrcProgram *program);
const char *orc_program_get_asm_code (OrcProgram *program);
const char *orc_target_get_asm_preamble (const char *target);
extern int _orc_compiler_flag_backup;
extern int _orc_compiler_flag_debug;
+void orc_code_chunk_free (OrcCodeChunk *chunk);
+
#endif
#endif
int diff;
int align_shift = 4;
- diff = (compiler->program->code - compiler->codeptr)&((1<<align_shift) - 1);
+ diff = (compiler->code - compiler->codeptr)&((1<<align_shift) - 1);
while (diff) {
ORC_ASM_CODE(compiler," nop\n");
*compiler->codeptr++ = 0x90;