- move common definitions into blur-translate.h, which is included by

both blur-translate.c and all translated code when it is compiled.
- use DO_*() macros in blur-translate.h to implement the switch() statement
  in the emulate function, so that the same code is really used for both
  emulation and translation.
This commit is contained in:
Bryce Denney 2002-04-17 21:53:33 +00:00
parent 05d6a719b9
commit 8dbf420ac5
2 changed files with 84 additions and 40 deletions

View File

@ -1,6 +1,6 @@
/*
*
* $Id: blur-translate.c,v 1.2 2002-04-17 19:34:57 bdenney Exp $
* $Id: blur-translate.c,v 1.3 2002-04-17 21:53:33 bdenney Exp $
*
*/
@ -10,13 +10,14 @@
#include <unistd.h>
#include <assert.h>
#include <ltdl.h> // libtool library
#include "blur-translate.h"
#define MAX 128
int array[MAX][MAX];
int array2[MAX][MAX];
#define BLUR_WINDOW_HALF 1
#define DEFAULT_TIMES 1000
int array[MAX_ARRAY][MAX_ARRAY];
int array2[MAX_ARRAY][MAX_ARRAY];
#define MAX_TIMERS 3
struct timeval start[MAX_TIMERS], stop[MAX_TIMERS];
#define start_timer(T) gettimeofday (&start[T], NULL);
@ -36,7 +37,6 @@ void report_time (FILE *fp, int T, int iters)
}
}
typedef enum {
OP_MOVE_REL, // 2 args delta_x and delta_y
OP_SET_ACCUM, // 1 arg, sets accum to that arg
@ -48,14 +48,6 @@ typedef enum {
N_OPS // must be last
} Opcode;
typedef struct {
int x, y;
int accum;
int *load_ptr;
int *store_ptr;
int done;
} State;
typedef void (*exec_func)(State *state);
typedef struct {
@ -108,12 +100,14 @@ void print_state (State *state)
state->store_ptr);
}
void blur_simple()
// this is the original blur function from blur.c. I keep it around
// for regression testing.
void blur_reference()
{
int sum;
int x,y,x2,y2;
for (x=1; x<MAX-1; x++)
for (y=1; y<MAX-1; y++)
for (x=1; x<MAX_ARRAY-1; x++)
for (y=1; y<MAX_ARRAY-1; y++)
{
sum = 0;
for (x2=x-BLUR_WINDOW_HALF; x2<=x+BLUR_WINDOW_HALF; x2++)
@ -124,13 +118,18 @@ void blur_simple()
}
}
// This is the opcode emulator. It uses switch statement to decode
// the opcodes and implement them.
//
#define ST(x) (state.x)
void emulate_opcodes (int *opcode_list)
{
int sum;
int x,y,x2,y2;
int arg1,arg2;
State state;
for (x=1; x<MAX-1; x++)
for (y=1; y<MAX-1; y++)
for (x=1; x<MAX_ARRAY-1; x++)
for (y=1; y<MAX_ARRAY-1; y++)
{
int *pc;
int done = 0;
@ -146,24 +145,25 @@ void emulate_opcodes (int *opcode_list)
switch (*pc++)
{
case OP_MOVE_REL:
state.x += *pc++;
state.y += *pc++;
state.load_ptr = &array[state.x][state.y];
arg1=*pc++;
arg2=*pc++;
DO_MOVE_REL(arg1,arg2);
break;
case OP_SET_ACCUM:
state.accum = *pc++;
arg1=*pc++;
DO_SET_ACCUM(arg1);
break;
case OP_ADD_DATA:
state.accum += *state.load_ptr;
DO_ADD_DATA();
break;
case OP_SUBTRACT_DATA:
state.accum -= *state.load_ptr;
DO_SUBTRACT_DATA();
break;
case OP_MULTIPLY_DATA:
state.accum *= *state.load_ptr;
DO_MULTIPLY_DATA();
break;
case OP_STORE_DATA:
*state.store_ptr = state.accum;
DO_STORE_DATA();
break;
case OP_END:
done = 1;
@ -178,7 +178,8 @@ void emulate_opcodes (int *opcode_list)
int gen_header (FILE *out)
{
fprintf (out, "// code generated by blur-translate.c\n");
fprintf (out, "#include \"translate2-defs.h\"\n");
fprintf (out, "#define IN_TRANSLATED_CODE 1\n");
fprintf (out, "#include \"blur-translate.h\"\n");
fprintf (out, "\n");
return 0;
}
@ -189,7 +190,7 @@ int gen_function (int *instructions, FILE *out, int fnid)
int *pc = instructions;
fprintf (out, "\nvoid translate%d (State *state) {\n", fnid);
// the BEGIN_TRANSLATED_FUNCTION macro is defined in the
// translate2-defs.h file. It creates local variables to mirror the
// blur-translate.h file. It creates local variables to mirror the
// frequently used fields in the state struct.
fprintf (out, "BEGIN_TRANSLATED_FUNCTION()\n");
@ -227,10 +228,10 @@ int gen_function (int *instructions, FILE *out, int fnid)
// loop count updates
fprintf (out, " ST(y)++; \n");
fprintf (out, " if (!(ST(y)<MAX-1)) { \n");
fprintf (out, " if (!(ST(y)<MAX_ARRAY-1)) { \n");
fprintf (out, " ST(y)=1; \n");
fprintf (out, " ST(x)++; \n");
fprintf (out, " if (!(ST(x)<MAX-1)) { \n");
fprintf (out, " if (!(ST(x)<MAX_ARRAY-1)) { \n");
fprintf (out, " done=1; \n");
fprintf (out, " } \n");
fprintf (out, " } \n");
@ -274,7 +275,6 @@ int translate_block (CodeBlock *block)
fprintf (stderr, "stat failed\n");
return -1;
}
fprintf (stderr, "shared library is %d bytes\n", (int)st.st_size);
// open shared library and get the function pointer
sprintf (buffer, "libtranslate%d.la", id);
block->dlhandle = lt_dlopen (buffer);
@ -290,9 +290,9 @@ int translate_block (CodeBlock *block)
return -1;
}
stop_timer(1);
fprintf (stderr, "How long did translation take?\n");
fprintf (stderr, "Loaded shared library.\n");
fprintf (stderr, "Translation took ");
report_time(stderr, 1, 1);
fprintf (stderr, "---\n");
return 0;
}
@ -312,16 +312,16 @@ void execute_code_block (CodeBlock *block)
void fill_array()
{
int x,y;
for (x=0; x<MAX; x++)
for (y=0; y<MAX; y++)
for (x=0; x<MAX_ARRAY; x++)
for (y=0; y<MAX_ARRAY; y++)
array[x][y] = (x*17+y*31)%29;
}
void dump_array (FILE *fp, int ptr[MAX][MAX])
void dump_array (FILE *fp, int ptr[MAX_ARRAY][MAX_ARRAY])
{
int x,y;
for (x=0; x<MAX; x++) {
for (y=0; y<MAX; y++) {
for (x=0; x<MAX_ARRAY; x++) {
for (y=0; y<MAX_ARRAY; y++) {
fprintf (fp, "%3d ", ptr[x][y]);
}
fprintf (fp, "\n");
@ -374,7 +374,7 @@ int main (int argc, char *argv[])
for (i=0; i<times; i++) {
switch (method) {
case METHOD_REFERENCE:
blur_simple ();
blur_reference ();
break;
case METHOD_EMULATE:
emulate_opcodes (blur.opcode_list);
@ -385,7 +385,7 @@ int main (int argc, char *argv[])
}
}
stop_timer(0);
printf ("Total time elapsed:\n");
printf ("Total time elapsed: ");
report_time (stdout, 0, times);
//fprintf (stderr, "-----------------------------------\n");
out = fopen ("blur.out", "w");

View File

@ -0,0 +1,44 @@
#define MAX_ARRAY 128
extern int array[MAX_ARRAY][MAX_ARRAY];
extern int array2[MAX_ARRAY][MAX_ARRAY];
typedef struct {
int x, y;
int accum;
int *load_ptr;
int *store_ptr;
int done;
} State;
#if defined(IN_TRANSLATED_CODE)
#define ST(n) (n)
#define BEGIN_TRANSLATED_FUNCTION() \
int x=state->x, y=state->y, accum=state->accum; \
int *load_ptr=state->load_ptr, *store_ptr=state->store_ptr; \
int done = 0; \
while (!done) {
#define END_TRANSLATED_FUNCTION() \
} /* end of while block started in BEGIN_TRANSLATED_FUNCTION() */ \
state->x=x; state->y=y; state->accum=accum; \
state->load_ptr=load_ptr; state->store_ptr=store_ptr;
#endif // defined IN_TRANSLATED_CODE
#define DO_MOVE_REL(delta_x,delta_y) do { \
ST(x) += delta_x; \
ST(y) += delta_y; \
ST(load_ptr) = &array[ST(x)][ST(y)]; \
} while (0)
#define DO_SET_ACCUM(x) ST(accum) = x
#define DO_ADD_DATA() ST(accum) += *ST(load_ptr)
#define DO_SUBTRACT_DATA() ST(accum) -= *ST(load_ptr)
#define DO_MULTIPLY_DATA() ST(accum) *= *ST(load_ptr)
#define DO_STORE_DATA() *ST(store_ptr) = ST(accum)
#define DO_END() done = 1