aboutsummaryrefslogtreecommitdiff
path: root/sim/common/sim-gx.c
diff options
context:
space:
mode:
Diffstat (limited to 'sim/common/sim-gx.c')
-rw-r--r--sim/common/sim-gx.c861
1 files changed, 0 insertions, 861 deletions
diff --git a/sim/common/sim-gx.c b/sim/common/sim-gx.c
deleted file mode 100644
index 8780ac9..0000000
--- a/sim/common/sim-gx.c
+++ /dev/null
@@ -1,861 +0,0 @@
-/* GX target-independent functions for block translation.
- Copyright (C) 1998 Cygnus Solutions. */
-
-
-#include "sim-main.h"
-#include "sim-assert.h"
-#include "sim-gx.h"
-
-#include "config.h"
-
-/* shared object functions */
-#ifdef HAVE_DLFCN_H
-#include <dlfcn.h>
-#else
-#error "need dlfcn.h"
-#endif
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#else
-#error "need errno.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#include "bfd.h"
-
-
-
-
-/* Load the object file with given gx block. Return pointer to GX
- function or NULL on failure. */
-
-sim_gx_function
-sim_gx_compiled_block_f(sim_gx_compiled_block* gx)
-{
- sim_gx_function f = gx->function_dlhandle;
- SIM_DESC sd = current_state;
- static int dlopened_main = 0;
-
- if(f == NULL)
- {
- /* load object */
- if(gx->object_dlhandle == NULL && gx->object_name != NULL)
- {
- if(! dlopened_main)
- {
- /* dlopen executable itself first to share symbols with shared library */
- void* exec_handle = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
- if(exec_handle == NULL)
- {
- sim_io_error(sd, "Load error for executable: %s",
- dlerror());
- }
-
- dlopened_main = 1;
- }
-
- /* dlopen the gx block dso itself */
- gx->object_dlhandle = dlopen(gx->object_name, RTLD_NOW);
- if(gx->object_dlhandle == NULL)
- {
- sim_io_error(sd, "Load error for GX object %s: %s",
- gx->object_name,
- dlerror());
- }
- }
-
- /* locate function */
- if(gx->function_dlhandle == NULL && gx->object_dlhandle != NULL && gx->symbol_name != NULL)
- {
- f = gx->function_dlhandle = dlsym(gx->object_dlhandle, gx->symbol_name);
- if(f == NULL)
- {
- sim_io_error(sd, "Resolve error for GX object %s symbol %s: %s",
- gx->object_name,
- gx->symbol_name,
- dlerror());
- }
- }
- } /* f == NULL */
-
- return f;
-}
-
-
-
-/* Forget about given GX block. Remove its source/object; unload it
- from memory. */
-void
-sim_gx_compiled_block_dispose(sim_gx_compiled_block* gx)
-{
- SIM_DESC sd = current_state;
- int rc;
- char compile_command[2000];
- char la_name[2000];
-
- /* forget dl information */
- gx->function_dlhandle = NULL;
-
- /* unload shared library */
- if(gx->object_dlhandle != NULL)
- {
- rc = dlclose(gx->object_dlhandle);
- if(rc != 0)
- {
- sim_io_error(sd, "dlclose() error for GX object %s: %s",
- gx->object_name,
- dlerror());
- }
- gx->object_dlhandle = NULL;
- }
-
- /* uninstall shared object */
-
- strcpy(la_name, gx->object_name);
- strcpy(strstr(la_name, ".so.0"), ".la");
- sprintf(compile_command, "gxtool --silent --mode=uninstall rm -f %s", la_name);
-
- rc = system(compile_command);
- if(rc != 0)
- {
- sim_io_error(sd, "Error during finish: `%s' rc %d",
- compile_command, rc);
- }
-
-
- /* erase source */
- /* sprintf(compile_command, "rm -f %s", block->source_name); */
-
- /* final gasps */
- zfree(gx->source_name);
- zfree(gx->object_name);
- zfree(gx->symbol_name);
- zfree(gx);
-}
-
-
-
-/* Translate a piece of the code segment around given PC, in given mode. */
-sim_gx_block*
-sim_gx_block_create(sim_cia cia)
-{
- sim_gx_block* block;
-
- /* allocate emtpy block */
- block = zalloc(sizeof(sim_gx_block));
-
- /* initialize block bounds, callback struct etc. */
- tgx_block_ctor(block, cia);
-
- /* create learning mode translation */
- sim_gx_block_translate(block, 0 /* learning mode */);
-
- /* add block to block list */
- sim_gx_block_add(block);
-
- return block;
-}
-
-
-
-/* Write the current block list to the state file */
-void
-sim_gx_write_block_list()
-{
- int i;
- SIM_DESC sd = current_state;
- sim_gx_block_list* blocks = STATE_BLOCKS(sd);
- FILE* f;
- char state_file_name[PATH_MAX];
- char *exec_name;
-
- /* get base of executable name */
- exec_name = bfd_get_filename(STATE_PROG_BFD(sd));
- if(strrchr(exec_name, '/') != NULL)
- exec_name = strrchr(exec_name, '/') + 1;
-
- /* generate base name */
- sprintf(state_file_name, "%s/%s.gx",
- GX_DIR,
- exec_name);
-
- f = fopen(state_file_name, "w");
- if(f == NULL)
- {
- sim_io_error(sd, "Error: cannot write to state file %s, errno %d",
- state_file_name, errno);
- }
-
- fprintf(f, "# This file was automatically generated. Do not edit.\n");
-
- /* write block descriptors into state file */
- for(i=0; i<blocks->gx_blocks_used; i++)
- {
- sim_gx_block* gx = blocks->gx_blocks[i];
- sim_gx_compiled_block* block;
- int j;
- int age;
-
- age = time(NULL) - gx->learn_last_change; /* store interval */
- fprintf(f, "BLOCK 0x%x 0x%x %u %u\n", (unsigned)gx->origin, (unsigned)gx->length, gx->divisor, age);
- fprintf(f, "FLAGS ");
- for(j=0; j<GX_PC_FLAGS_INDEX(gx, gx->origin + gx->length); j++)
- {
- fprintf(f, "%2x ", gx->pc_flags[j]);
- }
- fprintf(f, "\n");
-
- /* write learning mode names */
- block = gx->learning_block;
- fprintf(f, "LEARNING %s %s %s %lu %u\n",
- block->source_name, block->object_name, block->symbol_name,
- gx->compile_time, gx->opt_compile_count);
-
- /* write optimized mode names */
- block = gx->optimized_block;
- if(block)
- fprintf(f, "OPTIMIZED %s %s %s\n",
- block->source_name, block->object_name, block->symbol_name);
-
- /* NB: other fields will be filled in with freshly guessed values */
- }
-
- (void) fclose(f);
-}
-
-
-
-void
-print_gx_blocks(sim_gx_block_list* blocks, char* where)
-{
- printf("print_gx_blocks: %s\n", where);
-
- if(blocks == NULL)
- printf("(null)\n");
- else
- {
- int i;
- printf("size: %d, used: %d\n",
- blocks->gx_blocks_size, blocks->gx_blocks_used);
-
- /* linear search */
- for(i=0; i<blocks->gx_blocks_used; i++)
- {
- sim_gx_block* gx = blocks->gx_blocks[i];
- printf("block %d: %p\n", i, (void*) gx);
- if(gx == NULL)
- printf("** NULL!\n");
- else
- printf(" begin 0x%08x length 0x%08x [opt %d%s]\n",
- (unsigned)gx->origin, (unsigned)gx->length,
- gx->opt_compile_count,
- (gx->optimized_block ? " loaded" : " discarded"));
- }
-
- }
-}
-
-
-
-/* Read the current block list from the cache */
-void
-sim_gx_read_block_list()
-{
- SIM_DESC sd = current_state;
- FILE* f;
- char state_file_name[PATH_MAX];
- const char *exec_name;
-
- /* check for block */
- if(STATE_PROG_BFD(sd) == NULL)
- return;
-
- /* get base of executable name */
- exec_name = bfd_get_filename(STATE_PROG_BFD(sd));
- if(strrchr(exec_name, '/') != NULL)
- exec_name = strrchr(exec_name, '/') + 1;
-
- /* generate base name */
- sprintf(state_file_name, "%s/%s.gx",
- GX_DIR,
- exec_name);
-
- f = fopen(state_file_name, "r");
- if(f == NULL)
- {
- /* XXX: print warning */
- return;
- }
-
- fscanf(f, "#%*[^\n]\n"); /* swallow # comment line */
-
- while(1)
- {
- unsigned_4 origin, length;
- unsigned divisor;
- sim_gx_block* gx;
- int rc;
- sim_gx_compiled_block* block;
- unsigned age;
- int j;
-
- rc = fscanf(f, "BLOCK 0x%0x 0x%x %u %u\n", (unsigned*)& origin, (unsigned*)& length, & divisor, & age);
- if(rc != 4) /* not all fields matched - assume EOF */
- break;
-
- gx = zalloc(sizeof(sim_gx_block));
-
- /* initialize block bounds, callback struct etc. */
- tgx_block_ctor2(gx, origin, length, divisor);
-
- /* read flags */
- fscanf(f, "FLAGS");
- for(j=0; j<GX_PC_FLAGS_INDEX(gx, gx->origin + gx->length); j++)
- {
- unsigned value;
- fscanf(f, "%2x ", & value);
- gx->pc_flags[j] = (unsigned_1) value;
- }
- fscanf(f, "\n");
-
- /* read learning mode info */
- block = zalloc(sizeof(sim_gx_compiled_block));
- gx->learning_block = block;
- block->source_name = zalloc(PATH_MAX);
- block->object_name = zalloc(PATH_MAX);
- block->symbol_name = zalloc(PATH_MAX);
- fscanf(f, "LEARNING %s %s %s %u %u\n",
- block->source_name, block->object_name, block->symbol_name,
- (unsigned*) & gx->compile_time, & gx->opt_compile_count);
-
- /* read optimized mode info */
- block = zalloc(sizeof(sim_gx_compiled_block));
- gx->optimized_block = block;
- block->source_name = zalloc(PATH_MAX);
- block->object_name = zalloc(PATH_MAX);
- block->symbol_name = zalloc(PATH_MAX);
- rc = fscanf(f, "OPTIMIZED %s %s %s\n",
- block->source_name, block->object_name, block->symbol_name);
- if(rc != 3)
- {
- /* oops, not an optimized block */
- zfree(block->source_name);
- zfree(block->object_name);
- zfree(block->symbol_name);
- zfree(block);
- gx->optimized_block = NULL;
- }
-
- /* fill in remaining fields */
- gx->learn_last_change = time(NULL) - age; /* make absolute */
-
- /* store it away */
- sim_gx_block_add(gx);
- }
-
- /* print_gx_blocks(STATE_BLOCKS(sd), "after restoring state"); */
-}
-
-
-
-
-
-
-/* Add a gx block to list */
-void
-sim_gx_block_add(sim_gx_block* block)
-{
- SIM_DESC sd = current_state;
- sim_gx_block_list* blocks = STATE_BLOCKS(sd);
- int i;
-
- /* print_gx_blocks(blocks, "pre add"); */
-
- if(blocks == NULL)
- blocks = STATE_BLOCKS(sd) = zalloc(sizeof(sim_gx_block_list));
-
- /* need to enlarge block vector? */
- if(blocks->gx_blocks_used == blocks->gx_blocks_size)
- {
- sim_gx_block** new_blocks;
- int j;
-
- blocks->gx_blocks_size += 20;
- new_blocks = zalloc(blocks->gx_blocks_size * sizeof(sim_gx_block*));
- for(j=0; j<blocks->gx_blocks_used; j++)
- new_blocks[j] = blocks->gx_blocks[j];
- if(blocks->gx_blocks) zfree(blocks->gx_blocks);
- blocks->gx_blocks = new_blocks;
- }
-
- /* insert new block */
- for(i=0; i<blocks->gx_blocks_used; i++)
- {
- ASSERT(blocks->gx_blocks[i] != NULL);
-
- /* insertion point reached? */
- if(blocks->gx_blocks[i]->origin > block->origin)
- {
- int j;
- for(j=blocks->gx_blocks_used; j>=i; j--)
- blocks->gx_blocks[j] = blocks->gx_blocks[j-1];
- blocks->gx_blocks[i] = block;
- blocks->gx_blocks_used ++;
- break;
- }
- }
-
- /* end of block vector */
- if(i == blocks->gx_blocks_used)
- {
- blocks->gx_blocks[blocks->gx_blocks_used ++] = block;
- }
-
- /* print_gx_blocks(blocks, "post add"); */
-}
-
-
-
-/* Remove a gx block from list */
-void
-sim_gx_block_remove(sim_gx_block* block)
-{
- SIM_DESC sd = current_state;
- sim_gx_block_list* blocks = STATE_BLOCKS(sd);
- int i;
-
- /* print_gx_blocks(blocks, "pre remove"); */
-
- /* linear search */
- for(i=0; i<blocks->gx_blocks_used; i++)
- {
- if(blocks->gx_blocks[i] == block)
- {
- /* found it */
- while(i < blocks->gx_blocks_used - 1)
- {
- blocks->gx_blocks[i] = blocks->gx_blocks[i+1];
- i++;
- }
- blocks->gx_blocks_used --;
- break;
- }
- }
-
- /* print_gx_blocks(blocks, "post remove"); */
-}
-
-
-/* Find a gx block from list */
-sim_gx_block*
-sim_gx_block_find(sim_cia cia)
-{
- SIM_DESC sd = current_state;
- sim_gx_block_list* blocks = STATE_BLOCKS(sd);
- int i;
-
- if(blocks == NULL) return NULL;
-
- /* print_gx_blocks(blocks, "pre find"); */
-
- /* linear search */
- for(i=0; i<blocks->gx_blocks_used; i++)
- {
- sim_gx_block* gx = blocks->gx_blocks[i];
- ASSERT(gx != NULL);
-
- if(GX_PC_INCLUDES(gx,cia))
- {
- return gx;
- }
- }
-
- return NULL;
-}
-
-
-
-/* generate */
-void
-sim_gx_block_translate(sim_gx_block* gx, int optimized)
-{
- char pwd_name[PATH_MAX];
- char dir_name[PATH_MAX];
- char base_name[PATH_MAX];
- char compile_command[PATH_MAX*4];
- const char* exec_name;
- SIM_DESC sd = current_state;
- int rc;
- sim_cia gx_cia;
- sim_gx_compiled_block* block = zalloc(sizeof(sim_gx_compiled_block));
- unsigned time_begin, time_end;
-
- time_begin = time(NULL);
-
- if(optimized) gx->optimized_block = block;
- else gx->learning_block = block;
-
- /* get base of executable name */
- exec_name = bfd_get_filename(STATE_PROG_BFD(sd));
- if(strrchr(exec_name, '/') != NULL)
- exec_name = strrchr(exec_name, '/') + 1;
-
- /* generate base name */
- sprintf(dir_name, "%s/%s",
- GX_DIR,
- exec_name);
-
- /* generate base name */
- getcwd(pwd_name, sizeof(pwd_name));
-
- /* create work directory */
- rc = mkdir(GX_DIR, 0777);
- if(rc != 0 &&
- errno != EEXIST)
- {
- sim_io_error(sd, "Error: cannot create directory %s, errno %d",
- GX_DIR, errno);
- }
-
- rc = mkdir(dir_name, 0777);
- if(rc != 0 &&
- errno != EEXIST)
- {
- sim_io_error(sd, "Error: cannot create directory %s, errno %d",
- dir_name, errno);
- }
-
- /* compute base name */
- if(optimized)
- sprintf(base_name, "%08x_opt%d", (unsigned) gx->origin, gx->opt_compile_count);
- else
- sprintf(base_name, "%08x", (unsigned) gx->origin);
-
- /* generate source/object file names */
- block->source_name = zalloc(PATH_MAX);
- block->object_name = zalloc(PATH_MAX);
- sprintf(block->source_name, "%s/%s.c", dir_name, base_name);
-
- /* generate symbol name for gx function */
- block->symbol_name = zalloc(PATH_MAX);
- sprintf(block->symbol_name, "gx_%s", base_name);
-
- /* open source file */
- block->source_file = fopen(block->source_name, "w");
- if(block->source_file == NULL)
- {
- sim_io_error(sd, "Error: cannot open file %s, errno %d",
- block->source_name, errno);
- }
-
- /* front matter */
- fprintf(block->source_file, "/* sim-gx version %d */\n", GX_VERSION);
- fprintf(block->source_file, "/* gx block date stamp %lu */\n\n", time(NULL));
-
- /* emit head end of source */
- tgx_emit_pre_function(gx, optimized);
-
- /* emit function header */
- fprintf(block->source_file, "\n\n");
- fprintf(block->source_file, "extern int\n");
- fprintf(block->source_file, "%s", block->symbol_name);
- fprintf(block->source_file, "(struct tgx_info* info)\n");
- fprintf(block->source_file, "{\n");
- fprintf(block->source_file, " int rc = 0;\n");
- if(! optimized)
- fprintf(block->source_file, " unsigned int insn_count = 0;\n");
-
- /* emit threaded goto vector for __GNUC__ */
- fprintf(block->source_file, "#ifdef __GNUC__\n");
- fprintf(block->source_file, " static void* jump_table[] =\n");
- fprintf(block->source_file, " {\n");
- gx_cia = gx->origin;
- while(GX_PC_INCLUDES(gx,gx_cia))
- {
- sim_cia next_gx_cia;
- if((! optimized) ||
- (GX_PC_FLAGS(gx, gx_cia) & GX_PCF_JUMPTARGET))
- {
- fprintf(block->source_file, " && gx_label_%ld,\n",
- ((gx_cia - gx->origin) / gx->divisor));
- }
- else
- {
- fprintf(block->source_file, " && gx_label_default,\n");
- }
- gx_cia = gx_cia + gx->divisor;
- }
- fprintf(block->source_file, " };\n");
- fprintf(block->source_file, "#endif /*__GNUC__*/\n");
-
- /* pre-block gunk: register load */
- tgx_emit_load_block(gx, optimized);
-
- /* emit intra-block jump label */
- fprintf(block->source_file, "\n");
- fprintf(block->source_file, "shortjump:\n");
- fprintf(block->source_file, " pc = npc;\n");
-
- /* translate jumptarget table */
- if(! optimized)
- {
- fprintf(block->source_file, " pc_flags[(pc - 0x%08x) / %u] |= %d;\n",
- (unsigned)gx->origin, gx->divisor, GX_PCF_JUMPTARGET);
- }
-
- /* enforce learning mode run limit */
- if(! optimized)
- {
- fprintf(block->source_file, " insn_count++;\n");
- fprintf(block->source_file, " if (insn_count > %d)\n", GX_LEARN_RUN_LIMIT);
- fprintf(block->source_file, " {\n");
- fprintf(block->source_file, " rc = %d;\n", GX_F_YIELD);
- fprintf(block->source_file, " npc = pc;\n");
- fprintf(block->source_file, " goto save;\n");
- fprintf(block->source_file, " }\n");
- }
-
- /* emit PC switch, use compressed case numbers */
- fprintf(block->source_file, "\n");
- fprintf(block->source_file, "#ifdef __GNUC__\n");
- fprintf(block->source_file, " goto * jump_table[((pc - 0x%08x) / %u)];\n",
- (unsigned)gx->origin, gx->divisor);
- fprintf(block->source_file, "#else /* ! __GNUC__*/\n");
- fprintf(block->source_file, " switch((pc - 0x%08x) / %u)\n",
- (unsigned)gx->origin, gx->divisor);
- fprintf(block->source_file, "#endif /*__GNUC__*/\n");
- fprintf(block->source_file, " {\n");
-
- /* handle bad-PC event */
- fprintf(block->source_file, " /* handle unknown jump target */\n");
- fprintf(block->source_file, "#ifdef __GNUC__\n");
- fprintf(block->source_file, " gx_label_default:\n");
- fprintf(block->source_file, "#else /* ! __GNUC__*/\n");
- fprintf(block->source_file, " default:\n");
- fprintf(block->source_file, "#endif /*__GNUC__*/\n");
- fprintf(block->source_file, " pc_flags[%d] |= %d;\n",
- GX_PC_FLAGS_INDEX(gx, gx_cia), GX_PCF_INSTRUCTION);
- fprintf(block->source_file, " rc = %d;\n", GX_F_NONPC);
- fprintf(block->source_file, " npc = pc;\n");
- fprintf(block->source_file, " goto save;\n");
-
- /* start translating at the origin */
- gx_cia = gx->origin;
-
- /* translate instructions in block */
- while(GX_PC_INCLUDES(gx,gx_cia))
- {
- sim_cia next_gx_cia;
-
- /* translate PC case statement */
- fprintf(block->source_file, "\n");
- fprintf(block->source_file, " /* PC: 0x%08x, flags %02x */\n",
- gx_cia, (int) GX_PC_FLAGS(gx, gx_cia));
-
-
- /* skip over this instruction if it is not executed */
- if(optimized && !(GX_PC_FLAGS(gx, gx_cia) & GX_PCF_INSTRUCTION))
- {
- fprintf(block->source_file, " /* (not reached) */\n");
-
- /* prevent fall-through from previous translated insn */
- if(gx_cia > gx->origin &&
- GX_PC_FLAGS(gx, (gx_cia - gx->divisor)) & GX_PCF_INSTRUCTION)
- {
- fprintf(block->source_file, " /* prevent fall-through */\n");
- fprintf(block->source_file, " npc = 0x%08x;\n", gx_cia);
- fprintf(block->source_file, " pc_flags[%d] |= %d;\n",
- GX_PC_FLAGS_INDEX(gx, gx_cia), GX_PCF_INSTRUCTION);
- fprintf(block->source_file, " rc = %d;\n", GX_F_NONPC);
- fprintf(block->source_file, " goto save;\n");
- }
-
- next_gx_cia = gx_cia + gx->divisor;
- goto skip_instruction;
- }
-
- /* translate PC case statement */
- if((! optimized) ||
- (GX_PC_FLAGS(gx, gx_cia) & GX_PCF_JUMPTARGET))
- {
- fprintf(block->source_file, " gx_label_%d:\n",
- ((gx_cia - gx->origin) / gx->divisor));
- fprintf(block->source_file, "#ifndef __GNUC__\n");
- fprintf(block->source_file, " case %d:\n",
- ((gx_cia - gx->origin) / gx->divisor));
- fprintf(block->source_file, "#endif /* !__GNUC__ */\n");
- }
-
- /* translate breakpoint check & exit */
- if(GX_PC_FLAGS(gx, gx_cia) & GX_PCF_COND_HALT)
- {
- fprintf(block->source_file, " if(pc_flags[%d] & %d)\n",
- GX_PC_FLAGS_INDEX(gx, gx_cia),
- GX_PCF_HALT);
- fprintf(block->source_file, " {\n");
- fprintf(block->source_file, " rc = %d;\n", GX_F_HALT);
- fprintf(block->source_file, " npc = pc;\n");
- fprintf(block->source_file, " goto save;\n");
- fprintf(block->source_file, " }\n");
- }
-
- /* [don't] emit PC-setting */
- /* fprintf(block->source_file, " pc = 0x%08x;\n", gx_cia); */
-
- /* mark traversed instructions */
- if(! optimized)
- {
- fprintf(block->source_file, " pc_flags[%d] |= %d;\n",
- GX_PC_FLAGS_INDEX(gx, gx_cia),
- GX_PCF_INSTRUCTION);
- }
-
-
- /* translate instruction semantics */
- next_gx_cia = tgx_emit_insn(gx, gx_cia, optimized);
-
- skip_instruction:
-
- /* go to next instruction */
- gx_cia = next_gx_cia;
- }
- fprintf(block->source_file, " }\n");
-
- /* dropped through last instruction in switch block */
- fprintf(block->source_file, "\n");
- fprintf(block->source_file, " /* dropped through PC switch */\n");
- fprintf(block->source_file, " npc = 0x%08x;\n", gx_cia);
- fprintf(block->source_file, " rc = %d;\n", GX_F_RANGE);
- fprintf(block->source_file, " goto save;\n");
-
- /* unknown length jump */
- fprintf(block->source_file, "\n");
- fprintf(block->source_file, "unknownjump:\n");
- fprintf(block->source_file, " if(npc >= 0x%08x && npc < 0x%08x)\n",
- (unsigned)gx->origin, (unsigned)gx->origin + gx->length);
- fprintf(block->source_file, " goto shortjump;\n");
-
- /* long jump */
- fprintf(block->source_file, "\n");
- fprintf(block->source_file, "longjump:\n");
- fprintf(block->source_file, " rc = %d;\n", GX_F_RANGE);
-
- /* post-block gunk: SAVE etc. */
- fprintf(block->source_file, "\n");
- fprintf(block->source_file, "save:\n");
-
- tgx_emit_save_block(gx, optimized);
-
- /* emit tail end of function */
- fprintf(block->source_file, "\n");
- fprintf(block->source_file, " return rc;\n");
- fprintf(block->source_file, "}\n");
-
- /* emit tail end of source */
- tgx_emit_post_function(gx, optimized);
-
- /* close source file */
- fclose(block->source_file);
- block->source_file = NULL;
-
- /* compile source & produce shared object */
-
- {
- char* extra_flags = NULL;
-#ifdef HAVE_GETENV
- extra_flags = getenv("GX_FLAGS");
-#endif
- if (extra_flags == NULL) extra_flags = "";
-
- sprintf(compile_command,
- "gxtool --silent --mode=compile gcc %s %s -c %s",
- (optimized ? "-O9 -fomit-frame-pointer" : "-O"),
- extra_flags,
- block->source_name);
-
- rc = system(compile_command);
- if(rc != 0)
- {
- sim_io_error(sd, "Error during compiling: `%s' rc %d",
- compile_command, rc);
- }
-
- /* link source */
-
- sprintf(compile_command,
- "gxtool --silent --mode=link gcc -export-dynamic -rpath %s %s -o lib%s.la %s.lo",
- dir_name, extra_flags, base_name, base_name);
-
- rc = system(compile_command);
- if(rc != 0)
- {
- sim_io_error(sd, "Error during linking: `%s' rc %d",
- compile_command, rc);
- }
- }
-
- /* install */
-
- sprintf(compile_command,
- "gxtool --silent --mode=install cp lib%s.la %s/%s >/dev/null 2>/dev/null",
- base_name, pwd_name, dir_name);
-
- rc = system(compile_command);
- if(rc != 0)
- {
- sim_io_error(sd, "Error during install: `%s' rc %d",
- compile_command, rc);
- }
-
-
- /* finish */
-
- sprintf(compile_command,
- "gxtool --silent --mode=finish %s >/dev/null 2>/dev/null",
- dir_name);
-
- rc = system(compile_command);
- if(rc != 0)
- {
- sim_io_error(sd, "Error during finish: `%s' rc %d",
- compile_command, rc);
- }
-
- /* clean up */
-
- sprintf(compile_command, "gxtool --silent --mode=uninstall rm -f lib%s.la %s.lo", base_name, base_name);
- rc = system(compile_command);
- if(rc != 0)
- {
- sim_io_error(sd, "Error during cleanup: `%s' rc %d",
- compile_command, rc);
- }
-
- /* XXX: FILL IN block->object_name from .la file */
- sprintf(block->object_name, "%s/%s/lib%s.so.0",
- pwd_name, dir_name, base_name);
-
- /* measure compile time */
- time_end = time(NULL);
-
- if(time_end == time_begin) time_end ++; /* clamp minimum duration to 1 */
- gx->compile_time += time_end - time_begin;
- /* fprintf(stderr, "*** compile time: %d\n", gx->compile_time); */
-}
-