version 1.105, 2003/05/08 08:49:24
|
version 1.106, 2003/05/13 09:37:00
|
Line 516 void print_sizes(Cell sizebyte)
|
Line 516 void print_sizes(Cell sizebyte)
|
1 << ((sizebyte >> 5) & 3)); |
1 << ((sizebyte >> 5) & 3)); |
} |
} |
|
|
|
/* static superinstruction stuff */ |
|
|
|
struct cost { |
|
char loads; /* number of stack loads */ |
|
char stores; /* number of stack stores */ |
|
char updates; /* number of stack pointer updates */ |
|
short offset; /* offset into super2 table */ |
|
char length; /* number of components */ |
|
}; |
|
|
|
short super2[] = { |
|
#include "super2.i" |
|
}; |
|
|
|
struct cost super_costs[] = { |
|
#include "costs.i" |
|
}; |
|
|
|
#define HASH_SIZE 256 |
|
|
|
struct super_table_entry { |
|
struct super_table_entry *next; |
|
short *start; |
|
short length; |
|
short super; |
|
} *super_table[HASH_SIZE]; |
|
int max_super=2; |
|
|
|
int hash_super(short *start, int length) |
|
{ |
|
int i, r; |
|
|
|
for (i=0, r=0; i<length; i++) { |
|
r <<= 1; |
|
r += start[i]; |
|
} |
|
return r & (HASH_SIZE-1); |
|
} |
|
|
|
int lookup_super(short *start, int length) |
|
{ |
|
int hash=hash_super(start,length); |
|
struct super_table_entry *p = super_table[hash]; |
|
|
|
assert(length >= 2); |
|
for (; p!=NULL; p = p->next) { |
|
if (length == p->length && |
|
memcmp((char *)p->start, (char *)start, length*sizeof(short))==0) |
|
return p->super; |
|
} |
|
return -1; |
|
} |
|
|
|
void prepare_super_table() |
|
{ |
|
int i; |
|
|
|
for (i=0; i<sizeof(super_costs)/sizeof(super_costs[0]); i++) { |
|
struct cost *c = &super_costs[i]; |
|
if (c->length > 1) { |
|
int hash = hash_super(super2+c->offset, c->length); |
|
struct super_table_entry **p = &super_table[hash]; |
|
struct super_table_entry *e = malloc(sizeof(struct super_table_entry)); |
|
e->next = *p; |
|
e->start = super2 + c->offset; |
|
e->length = c->length; |
|
e->super = i; |
|
*p = e; |
|
if (c->length > max_super) |
|
max_super = c->length; |
|
} |
|
} |
|
} |
|
|
|
int mycost(int prim) |
|
{ |
|
return 1; |
|
} |
|
|
|
/* dynamic replication/superinstruction stuff */ |
|
|
#define MAX_IMMARGS 2 |
#define MAX_IMMARGS 2 |
|
|
#ifndef NO_DYNAMIC |
#ifndef NO_DYNAMIC |
Line 551 int compare_priminfo_length(const void *
|
Line 632 int compare_priminfo_length(const void *
|
#endif /* defined(NO_DYNAMIC) */ |
#endif /* defined(NO_DYNAMIC) */ |
Cell npriminfos=0; |
Cell npriminfos=0; |
|
|
|
static char superend[]={ |
|
#include "prim_superend.i" |
|
}; |
|
|
void check_prims(Label symbols1[]) |
void check_prims(Label symbols1[]) |
{ |
{ |
int i; |
int i; |
#ifndef NO_DYNAMIC |
#ifndef NO_DYNAMIC |
Label *symbols2, *symbols3, *ends1; |
Label *symbols2, *symbols3, *ends1; |
static char superend[]={ |
|
#include "prim_superend.i" |
|
}; |
|
#endif |
#endif |
|
|
if (debug) |
if (debug) |
Line 736 int forget_dyncode(Address code)
|
Line 817 int forget_dyncode(Address code)
|
long dyncodesize(void) |
long dyncodesize(void) |
{ |
{ |
#ifndef NO_DYNAMIC |
#ifndef NO_DYNAMIC |
struct code_block_list *p, **pp; |
struct code_block_list *p; |
long size=0; |
long size=0; |
for (p=code_block_list; p!=NULL; p=p->next) { |
for (p=code_block_list; p!=NULL; p=p->next) { |
if (code_here >= p->block && code_here < p->block+p->size) |
if (code_here >= p->block && code_here < p->block+p->size) |
Line 945 void compile_prim_dyn(Cell *start)
|
Line 1026 void compile_prim_dyn(Cell *start)
|
#endif /* !defined(DOUBLY_INDIRECT) */ |
#endif /* !defined(DOUBLY_INDIRECT) */ |
} |
} |
|
|
|
#define MAX_BB 128 /* maximum number of instructions in BB */ |
|
|
/* compile *start, possibly rewriting it into a static and/or dynamic |
/* compile *start, possibly rewriting it into a static and/or dynamic |
superinstruction */ |
superinstruction */ |
void compile_prim1(Cell *start) |
void compile_prim1(Cell *start) |
{ |
{ |
|
#if defined(DOUBLY_INDIRECT) || defined(INDIRECT_THREADED) |
compile_prim_dyn(start); |
compile_prim_dyn(start); |
|
#else |
|
static struct { |
|
Cell *instp; |
|
int superinst; /* best superinst for instp */ |
|
int cost; /* cost from here to end of bb */ |
|
} best[MAX_BB+1], *p; |
|
static int ninsts=0; |
|
int i,j, nextdyn; |
|
unsigned prim_num; |
|
|
|
if (start==NULL) |
|
goto end_bb; |
|
prim_num = ((Xt)*start)-vm_prims; |
|
if (prim_num >= npriminfos) |
|
goto end_bb; |
|
assert(ninsts<MAX_BB); |
|
best[ninsts++].instp = start; |
|
if (ninsts >= MAX_BB || superend[prim_num-DOESJUMP-1]) { |
|
end_bb: |
|
best[ninsts].cost=0; |
|
for (i=ninsts-1; i>=0; i--) { |
|
short components[max_super]; |
|
p=&best[i]; |
|
p->superinst = ((Xt)*(p->instp))-vm_prims-DOESJUMP-1; |
|
p->cost = p[1].cost + mycost(p->superinst); |
|
components[0] = p->superinst; |
|
for (j=2; j<=max_super && i+j<=ninsts ; j++) { |
|
int super, jcost; |
|
components[j-1] = ((Xt)*(p[j-1].instp))-vm_prims-DOESJUMP-1; |
|
super = lookup_super(components,j); |
|
if (super >= 0) { |
|
jcost = p[j].cost + mycost(super); |
|
if (jcost <= p->cost) { |
|
p->superinst = super; |
|
p->cost = jcost; |
|
} |
|
} |
|
} |
|
} |
|
for (i=0, nextdyn=0; i<ninsts; i++) { |
|
p=&best[i]; |
|
*(p->instp) = vm_prims[p->superinst+DOESJUMP+1]; |
|
if (i==nextdyn) { |
|
nextdyn += super_costs[p->superinst].length; |
|
/* !! *(p->instp) = compile_prim_dyn(p->superinst); */ |
|
} |
|
} |
|
ninsts=0; |
|
} |
|
#endif /* defined(DOUBLY_INDIRECT) || defined(INDIRECT_THREADED) */ |
} |
} |
|
|
#if defined(PRINT_SUPER_LENGTHS) && !defined(NO_DYNAMIC) |
#if defined(PRINT_SUPER_LENGTHS) && !defined(NO_DYNAMIC) |
Line 989 Address loader(FILE *imagefile, char* fi
|
Line 1123 Address loader(FILE *imagefile, char* fi
|
|
|
vm_prims = engine(0,0,0,0,0); |
vm_prims = engine(0,0,0,0,0); |
check_prims(vm_prims); |
check_prims(vm_prims); |
|
prepare_super_table(); |
#ifndef DOUBLY_INDIRECT |
#ifndef DOUBLY_INDIRECT |
#ifdef PRINT_SUPER_LENGTHS |
#ifdef PRINT_SUPER_LENGTHS |
print_super_lengths(); |
print_super_lengths(); |