version 1.73, 2002/12/08 09:57:54
|
version 1.74, 2002/12/08 20:24:35
|
Line 81 char *progname = "gforth";
|
Line 81 char *progname = "gforth";
|
int optind = 1; |
int optind = 1; |
#endif |
#endif |
|
|
#define CODE_BLOCK_SIZE (1024*1024) |
#define CODE_BLOCK_SIZE (256*1024) |
Address code_area=0; |
Address code_area=0; |
Cell code_area_size = CODE_BLOCK_SIZE; |
Cell code_area_size = CODE_BLOCK_SIZE; |
Address code_here=0; /* does for code-area what HERE does for the dictionary */ |
Address code_here=0; /* does for code-area what HERE does for the dictionary */ |
Address start_flush=0; /* start of unflushed code */ |
Address start_flush=0; /* start of unflushed code */ |
|
Cell last_jump=0; /* if the last prim was compiled without jump, this |
|
is it's number, otherwise this contains 0 */ |
|
|
static int no_super=0; /* true if compile_prim should not fuse prims */ |
static int no_super=0; /* true if compile_prim should not fuse prims */ |
/* --no-dynamic by default on gcc versions >=3.1 (it works with 3.0.4, |
/* --no-dynamic by default on gcc versions >=3.1 (it works with 3.0.4, |
Line 449 void print_sizes(Cell sizebyte)
|
Line 451 void print_sizes(Cell sizebyte)
|
#ifndef NO_DYNAMIC |
#ifndef NO_DYNAMIC |
typedef struct { |
typedef struct { |
Label start; |
Label start; |
Cell length; /* excluding the jump */ |
Cell length; /* only includes the jump iff superend is true*/ |
|
Cell restlength; /* length of the rest (i.e., the jump or (on superend) 0) */ |
char superend; /* true if primitive ends superinstruction, i.e., |
char superend; /* true if primitive ends superinstruction, i.e., |
unconditional branch, execute, etc. */ |
unconditional branch, execute, etc. */ |
Cell nimmargs; |
Cell nimmargs; |
Line 508 void check_prims(Label symbols1[])
|
Line 511 void check_prims(Label symbols1[])
|
pi->length = symbols1[i+1]-symbols1[i]; |
pi->length = symbols1[i+1]-symbols1[i]; |
else |
else |
pi->length = prim_len; |
pi->length = prim_len; |
|
pi->restlength = symbols1[i+1] - symbols1[i] - pi->length; |
pi->nimmargs = 0; |
pi->nimmargs = 0; |
if (debug) |
if (debug) |
fprintf(stderr, "Prim %3d @ %p %p %p, length=%3d superend=%1d", |
fprintf(stderr, "Prim %3d @ %p %p %p, length=%3d restlength=%2d superend=%1d", |
i, s1, s2, s3, prim_len, pi->superend); |
i, s1, s2, s3, pi->length, pi->restlength, pi->superend); |
assert(prim_len>=0); |
assert(prim_len>=0); |
while (j<prim_len) { |
while (j<(pi->length+pi->restlength)) { |
if (s1[j]==s3[j]) { |
if (s1[j]==s3[j]) { |
if (s1[j] != s2[j]) { |
if (s1[j] != s2[j]) { |
pi->start = NULL; /* not relocatable */ |
pi->start = NULL; /* not relocatable */ |
if (debug) |
if (debug) |
fprintf(stderr,"\n non_reloc: engine1!=engine2 offset %3d",j); |
fprintf(stderr,"\n non_reloc: engine1!=engine2 offset %3d",j); |
|
/* assert(j<prim_len); */ |
break; |
break; |
} |
} |
j++; |
j++; |
Line 540 void check_prims(Label symbols1[])
|
Line 545 void check_prims(Label symbols1[])
|
pi->start = NULL; /* not relocatable */ |
pi->start = NULL; /* not relocatable */ |
if (debug) |
if (debug) |
fprintf(stderr,"\n non_reloc: engine1!=engine3 offset %3d",j); |
fprintf(stderr,"\n non_reloc: engine1!=engine3 offset %3d",j); |
|
/* assert(j<prim_len);*/ |
break; |
break; |
} |
} |
j+=4; |
j+=4; |
Line 551 void check_prims(Label symbols1[])
|
Line 557 void check_prims(Label symbols1[])
|
#endif |
#endif |
} |
} |
|
|
|
#ifndef NO_DYNAMIC |
|
void flush_to_here(void) |
|
{ |
|
FLUSH_ICACHE(start_flush, code_here-start_flush); |
|
start_flush=code_here; |
|
} |
|
|
|
void append_jump(void) |
|
{ |
|
if (last_jump) { |
|
PrimInfo *pi = &priminfos[last_jump]; |
|
|
|
memcpy(code_here, pi->start+pi->length, pi->restlength); |
|
code_here += pi->restlength; |
|
last_jump=0; |
|
flush_to_here(); |
|
} |
|
} |
|
|
|
Address append_prim(Cell p) |
|
{ |
|
PrimInfo *pi = &priminfos[p]; |
|
Address old_code_here = code_here; |
|
|
|
if (code_area+code_area_size < code_here+pi->length+pi->restlength) { |
|
/* not enough space for all cases */ |
|
append_jump(); |
|
code_here = start_flush = code_area = my_alloc(code_area_size); |
|
old_code_here = code_here; |
|
} |
|
memcpy(code_here, pi->start, pi->length); |
|
code_here += pi->length; |
|
if (pi->superend) |
|
flush_to_here(); |
|
return old_code_here; |
|
} |
|
#endif |
|
|
#ifdef NO_IP |
#ifdef NO_IP |
int nbranchinfos=0; |
int nbranchinfos=0; |
|
|
Line 586 Cell *compile_prim1arg(Cell p)
|
Line 630 Cell *compile_prim1arg(Cell p)
|
int l = priminfos[p].length; |
int l = priminfos[p].length; |
Address old_code_here=code_here; |
Address old_code_here=code_here; |
|
|
memcpy(code_here, vm_prims[p], l); |
assert(vm_prims[p]==priminfos[p].start); |
code_here+=l; |
append_prim(p); |
return (Cell*)(old_code_here+priminfos[p].immargs[0].offset); |
return (Cell*)(old_code_here+priminfos[p].immargs[0].offset); |
} |
} |
|
|
Line 595 Cell *compile_call2(Cell targetptr)
|
Line 639 Cell *compile_call2(Cell targetptr)
|
{ |
{ |
Cell *next_code_target; |
Cell *next_code_target; |
PrimInfo *pi = &priminfos[N_call2]; |
PrimInfo *pi = &priminfos[N_call2]; |
|
Address old_code_here = append_prim(N_call2); |
|
|
memcpy(code_here, pi->start, pi->length); |
next_code_target = (Cell *)(old_code_here + pi->immargs[0].offset); |
next_code_target = (Cell *)(code_here + pi->immargs[0].offset); |
register_branchinfo(old_code_here + pi->immargs[1].offset, targetptr); |
register_branchinfo(code_here + pi->immargs[1].offset, targetptr); |
|
code_here += pi->length; |
|
return next_code_target; |
return next_code_target; |
} |
} |
#endif |
#endif |
Line 668 void compile_prim1(Cell *start)
|
Line 711 void compile_prim1(Cell *start)
|
set_rel_target(compile_prim1arg(N_abranch),*(Xt)last_prim); |
set_rel_target(compile_prim1arg(N_abranch),*(Xt)last_prim); |
} else { |
} else { |
unsigned j; |
unsigned j; |
|
Address old_code_here = append_prim(i); |
|
|
memcpy(code_here, *last_prim, pi->length); |
|
for (j=0; j<pi->nimmargs; j++) { |
for (j=0; j<pi->nimmargs; j++) { |
struct immarg *ia = &(pi->immargs[j]); |
struct immarg *ia = &(pi->immargs[j]); |
Cell argval = last_start[pi->nimmargs - j]; /* !! specific to prims */ |
Cell argval = last_start[pi->nimmargs - j]; /* !! specific to prims */ |
if (ia->rel) { /* !! assumption: relative refs are branches */ |
if (ia->rel) { /* !! assumption: relative refs are branches */ |
register_branchinfo(code_here + ia->offset, argval); |
register_branchinfo(old_code_here + ia->offset, argval); |
} else /* plain argument */ |
} else /* plain argument */ |
*(Cell *)(code_here + ia->offset) = argval; |
*(Cell *)(old_code_here + ia->offset) = argval; |
} |
} |
code_here += pi->length; |
|
} |
} |
if (next_code_target!=NULL) |
if (next_code_target!=NULL) |
*next_code_target = (Cell)code_here; |
*next_code_target = (Cell)code_here; |
Line 692 void compile_prim1(Cell *start)
|
Line 734 void compile_prim1(Cell *start)
|
#elif !defined(NO_DYNAMIC) |
#elif !defined(NO_DYNAMIC) |
Label prim=(Label)*start; |
Label prim=(Label)*start; |
unsigned i; |
unsigned i; |
Address old_code_here=code_here; |
Address old_code_here; |
static Address last_jump=0; |
|
|
|
i = ((Xt)prim)-vm_prims; |
i = ((Xt)prim)-vm_prims; |
prim = *(Xt)prim; |
prim = *(Xt)prim; |
Line 702 void compile_prim1(Cell *start)
|
Line 743 void compile_prim1(Cell *start)
|
return; |
return; |
} |
} |
if (i>=npriminfos || priminfos[i].start == 0) { /* not a relocatable prim */ |
if (i>=npriminfos || priminfos[i].start == 0) { /* not a relocatable prim */ |
if (last_jump) { /* make sure the last sequence is complete */ |
append_jump(); |
memcpy(code_here, last_jump, IND_JUMP_LENGTH); |
|
code_here += IND_JUMP_LENGTH; |
|
last_jump = 0; |
|
FLUSH_ICACHE(start_flush, code_here-start_flush); |
|
start_flush=code_here; |
|
} |
|
*start = (Cell)prim; |
*start = (Cell)prim; |
return; |
return; |
} |
} |
Line 716 void compile_prim1(Cell *start)
|
Line 751 void compile_prim1(Cell *start)
|
#ifdef ALIGN_CODE |
#ifdef ALIGN_CODE |
ALIGN_CODE; |
ALIGN_CODE; |
#endif |
#endif |
memcpy(code_here, (Address)prim, priminfos[i].length); |
assert(prim==priminfos[i].start); |
code_here += priminfos[i].length; |
old_code_here = append_prim(i); |
last_jump = (priminfos[i].superend) ? 0 : (prim+priminfos[i].length); |
last_jump = (priminfos[i].superend) ? 0 : i; |
if (last_jump == 0) { |
|
FLUSH_ICACHE(start_flush, code_here-start_flush); |
|
start_flush=code_here; |
|
} |
|
*start = (Cell)old_code_here; |
*start = (Cell)old_code_here; |
return; |
return; |
#else /* !defined(DOUBLY_INDIRECT), no code replication */ |
#else /* !defined(DOUBLY_INDIRECT), no code replication */ |