#define BUF_SIZE 100 \

#define rQ 16 \

/*2:*/
#line 35 "mmmix.w"

#include <stdio.h> 
#include "mmix-pipe.h"

char*config_file_name,*prog_file_name;
/*5:*/
#line 102 "mmmix.w"

octa cur_loc;
octa cur_dat;
bool new_chunk;
char buffer[BUF_SIZE];
FILE*prog_file;

/*:5*//*16:*/
#line 407 "mmmix.w"

int n,m;
octa bp= {-1,-1};
octa tmp;
static unsigned char d[BUF_SIZE];

/*:16*//*25:*/
#line 533 "mmmix.w"

bool bad_address;
extern bool page_bad;
extern octa page_mask;
extern int page_r,page_s,page_b[5];
extern octa zero_octa;
extern octa neg_one;
octa seven_octa= {0,7};
extern octa incr ARGS((octa y,int delta));

extern void mmix_io_init ARGS((void));
extern void MMIX_config ARGS((char*));

/*:25*/
#line 40 "mmmix.w"

/*10:*/
#line 206 "mmmix.w"

static bool undump_octa ARGS((void));
static bool undump_octa()
{
register int t0,t1,t2,t3;
t0= fgetc(prog_file);if(t0==EOF)return false;
t1= fgetc(prog_file);if(t1==EOF)goto oops;
t2= fgetc(prog_file);if(t2==EOF)goto oops;
t3= fgetc(prog_file);if(t3==EOF)goto oops;
cur_dat.h= (t0<<24)+(t1<<16)+(t2<<8)+t3;
t0= fgetc(prog_file);if(t0==EOF)goto oops;
t1= fgetc(prog_file);if(t1==EOF)goto oops;
t2= fgetc(prog_file);if(t2==EOF)goto oops;
t3= fgetc(prog_file);if(t3==EOF)goto oops;
cur_dat.l= (t0<<24)+(t1<<16)+(t2<<8)+t3;
return true;
oops:fprintf(stderr,"Premature end of file on %s!\n",prog_file_name);

return false;
}

/*:10*//*17:*/
#line 418 "mmmix.w"

octa read_hex ARGS((char*));
octa read_hex(p)
char*p;
{
register int j,k;
octa val;
val.h= val.l= 0;
for(j= 0;;j++){
if(p[j]>='0'&&p[j]<='9')d[j]= p[j]-'0';
else if(p[j]>='a'&&p[j]<='f')d[j]= p[j]-'a'+10;
else if(p[j]>='A'&&p[j]<='F')d[j]= p[j]-'A'+10;
else break;
}
p[j]= '\0';
for(j--,k= 0;k<=j;k++){
if(k>=8)val.h+= d[j-k]<<(4*k-32);
else val.l+= d[j-k]<<(4*k);
}
return val;
}

/*:17*//*20:*/
#line 466 "mmmix.w"

static octa sl3 ARGS((octa));
static octa sl3(y)
octa y;
{
register tetra yhl= y.h<<3,ylh= y.l>>29;
y.h= yhl+ylh;y.l<<= 3;
return y;
}

/*:20*/
#line 41 "mmmix.w"


int main(argc,argv)
int argc;
char*argv[];
{
/*3:*/
#line 62 "mmmix.w"

if(argc!=3){
fprintf(stderr,"Usage: %s configfile progfile\n",argv[0]);

exit(-3);
}
config_file_name= argv[1];
prog_file_name= argv[2];

/*:3*/
#line 47 "mmmix.w"
;
MMIX_config(config_file_name);
MMIX_init();
mmix_io_init();
/*4:*/
#line 71 "mmmix.w"

if(strlen(prog_file_name)> 4&&
strcmp(prog_file_name+strlen(prog_file_name)-4,".mmb")==0)
/*9:*/
#line 180 "mmmix.w"

{
prog_file= fopen(prog_file_name,"rb");
if(!prog_file){
fprintf(stderr,"Panic: Can't open MMIX binary file %s!\n",prog_file_name);

exit(-3);
}
while(1){
if(!undump_octa())break;
new_chunk= true;
cur_loc= cur_dat;
if(cur_loc.h&0x9fffffff)bad_address= true;
else bad_address= false,cur_loc.h>>= 29;

/*11:*/
#line 227 "mmmix.w"

while(1){
if(!undump_octa()){
fprintf(stderr,"Unexpected end of file on %s!\n",prog_file_name);

break;
}
if(!(cur_dat.h||cur_dat.l))break;
if(bad_address){
fprintf(stderr,"Panic: Unsupported virtual address %08x%08x!\n",

cur_loc.h,cur_loc.l);
exit(-5);
}
if(new_chunk)mem_write(cur_loc,cur_dat);
else mem_hash[last_h].chunk[(cur_loc.l&0xffff)>>3]= cur_dat;
cur_loc.l+= 8;
if((cur_loc.l&0xfff8)!=0)new_chunk= false;
else{
new_chunk= true;
if((cur_loc.l&0xffff0000)==0){
bad_address= true;cur_loc.h= (cur_loc.h<<29)+1;
}
}
}

/*:11*/
#line 195 "mmmix.w"
;
}
/*12:*/
#line 261 "mmmix.w"

if(cur_loc.h!=3){
fprintf(stderr,"Panic: MMIX binary file didn't set up the stack!\n");

exit(-6);
}
inst_ptr.o= mem_read(incr(cur_loc,-8*14));
inst_ptr.p= NULL;
cur_loc.h= 0x60000000;
g[255].o= incr(cur_loc,-8);
cur_dat.l= 0x90;
if(mem_read(cur_dat).h)inst_ptr.o= cur_dat;
head->inst= (UNSAVE<<24)+255,tail--;
head->loc= incr(inst_ptr.o,-4);
g[rT].o.h= 0x80000005,g[rTT].o.h= 0x80000006;
cur_dat.h= (RESUME<<24)+1,cur_dat.l= 0,cur_loc.h= 5,cur_loc.l= 0;
mem_write(cur_loc,cur_dat);
cur_dat.l= cur_dat.h,cur_dat.h= (NEGI<<24)+(255<<16)+1;
cur_loc.h= 6,cur_loc.l= 8;
mem_write(cur_loc,cur_dat);
cur_dat.h= (GET<<24)+rQ,cur_dat.l= (PUTI<<24)+(rQ<<16),cur_loc.l= 0;
mem_write(cur_loc,cur_dat);
cur_dat.h= 0,cur_dat.l= 7;
cur_loc.h= 4;
mem_write(cur_loc,cur_dat);
ITcache->set[0][0].tag= zero_octa;
ITcache->set[0][0].data[0]= cur_dat;
cur_dat.l= 6;
cur_dat.h= 1,cur_loc.l= 3<<13;
mem_write(cur_loc,cur_dat);
cur_dat.h= 2,cur_loc.l= 6<<13;
mem_write(cur_loc,cur_dat);
cur_dat.h= 3,cur_loc.l= 9<<13;
mem_write(cur_loc,cur_dat);
g[rK].o= neg_one;
g[rV].o.h= 0x369c2004;
page_bad= false,page_r= 4<<(32-13),page_s= 32,page_mask.l= 0xffffffff;
page_b[1]= 3,page_b[2]= 6,page_b[3]= 9,page_b[4]= 12;

/*:12*/
#line 197 "mmmix.w"
;
}

/*:9*/
#line 74 "mmmix.w"

else/*6:*/
#line 109 "mmmix.w"

{
prog_file= fopen(prog_file_name,"r");
if(!prog_file){
fprintf(stderr,"Panic: Can't open MMIX hexadecimal file %s!\n",prog_file_name);

exit(-3);
}
new_chunk= true;
while(1){
if(!fgets(buffer,BUF_SIZE,prog_file))break;
if(buffer[strlen(buffer)-1]!='\n'){
fprintf(stderr,"Panic: Hexadecimal file line too long: `%s...'!\n",buffer);

exit(-3);
}
if(buffer[12]==':')/*7:*/
#line 135 "mmmix.w"

{
if(sscanf(buffer,"%4x%8x",&cur_loc.h,&cur_loc.l)!=2){
fprintf(stderr,"Panic: Improper hexadecimal file location: `%s'!\n",buffer);

exit(-3);
}
new_chunk= true;
}

/*:7*/
#line 125 "mmmix.w"

else if(buffer[0]==' ')/*8:*/
#line 145 "mmmix.w"

{
if(sscanf(buffer+1,"%8x%8x",&cur_dat.h,&cur_dat.l)!=2){
fprintf(stderr,"Panic: Improper hexadecimal file data: `%s'!\n",buffer);

exit(-3);
}
if(new_chunk)mem_write(cur_loc,cur_dat);
else mem_hash[last_h].chunk[(cur_loc.l&0xffff)>>3]= cur_dat;
cur_loc.l+= 8;
if((cur_loc.l&0xfff8)!=0)new_chunk= false;
else{
new_chunk= true;
if((cur_loc.l&0xffff0000)==0)cur_loc.h++;
}
}

/*:8*/
#line 126 "mmmix.w"

else{
fprintf(stderr,"Panic: Improper hexadecimal file line: `%s'!\n",buffer);

exit(-3);
}
}
}

/*:6*/
#line 75 "mmmix.w"
;
fclose(prog_file);

/*:4*/
#line 51 "mmmix.w"
;
/*13:*/
#line 354 "mmmix.w"

while(1){
printf("mmmix> ");fflush(stdout);

fgets(buffer,BUF_SIZE,stdin);
switch(buffer[0]){
default:what_say:
printf("Eh? Sorry, I don't understand. (Type h for help)\n");
continue;
case'q':case'x':goto done;
/*14:*/
#line 369 "mmmix.w"

case'h':case'?':printf("The interactive commands are as follows:\n");
printf(" <n> to run for n cycles\n");
printf(" @<x> to take next instruction from location x\n");
printf(" b<x> to pause when location x is fetched\n");
printf(" v<x> to print specified diagnostics when running;\n");
printf("    x=1[insts enter/leave pipe]+2[whole pipeline each cycle]+\n");
printf("      4[coroutine activations]+8[coroutine scheduling]+\n");
printf("      10[uninitialized read]+20[online I/O read]+\n");
printf("      40[I/O read/write]+80[branch prediction details]+\n");
printf("      100[invalid cache blocks displayed too]\n");
printf(" -<n> to deissue n instructions\n");
printf(" l<n> to print current value of local register n\n");
printf(" g<n> to print current value of global register n\n");
printf(" m<x> to print current value of memory address x\n");
printf(" f<x> to insert instruction x into the fetch buffer\n");
printf(" i<n> to initiate a timer interrupt after n cycles\n");
printf(" IT, DT, I, D, or S to print current cache contents\n");
printf(" D* or S* to print dirty blocks of a cache\n");
printf(" p to print current pipeline contents\n");
printf(" s to print current stats\n");
printf(" h to print this message\n");
printf(" q to exit\n");
printf("(Here <n> is a decimal integer, <x> is hexadecimal.)\n");
continue;

/*:14*//*15:*/
#line 395 "mmmix.w"

case'0':case'1':case'2':case'3':case'4':
case'5':case'6':case'7':case'8':case'9':
if(sscanf(buffer,"%d",&n)!=1)goto what_say;
printf("Running %d at time %d",n,ticks.l);
if(bp.h==(tetra)-1&&bp.l==(tetra)-1)printf("\n");
else printf(" with breakpoint %08x%08x\n",bp.h,bp.l);
MMIX_run(n,bp);continue;
case'@':inst_ptr.o= read_hex(buffer+1);inst_ptr.p= NULL;continue;
case'b':bp= read_hex(buffer+1);continue;
case'v':verbose= read_hex(buffer+1).l;continue;

/*:15*//*18:*/
#line 440 "mmmix.w"

case'-':if(sscanf(buffer+1,"%d",&n)!=1||n<0)goto what_say;
if(cool<=hot)m= hot-cool;else m= (hot-reorder_bot)+1+(reorder_top-cool);
if(n> m)deissues= m;else deissues= n;
continue;
case'l':if(sscanf(buffer+1,"%d",&n)!=1||n<0)goto what_say;
if(n>=lring_size)goto what_say;
printf("  l[%d]=%08x%08x\n",n,l[n].o.h,l[n].o.l);continue;
case'm':tmp= mem_read(read_hex(buffer+1));
printf("  m[%s]=%08x%08x\n",buffer+1,tmp.h,tmp.l);continue;

/*:18*//*19:*/
#line 455 "mmmix.w"

case'g':if(sscanf(buffer+1,"%d",&n)!=1||n<0)goto what_say;
if(n>=256)goto what_say;
if(n==rO||n==rS){
if(hot==cool)
g[rO].o= sl3(cool_O),g[rS].o= sl3(cool_S);
else g[rO].o= sl3(hot->cur_O),g[rS].o= sl3(hot->cur_S);
}
printf("  g[%d]=%08x%08x\n",n,g[n].o.h,g[n].o.l);
continue;

/*:19*//*21:*/
#line 476 "mmmix.w"

case'I':print_cache(buffer[1]=='T'?ITcache:Icache,false);continue;
case'D':print_cache(buffer[1]=='T'?DTcache:Dcache,
buffer[1]=='*');continue;
case'S':print_cache(Scache,buffer[1]=='*');continue;
case'p':print_pipe();print_locks();continue;
case's':print_stats();continue;
case'i':if(sscanf(buffer+1,"%d",&n)==1)g[rI].o= incr(zero_octa,n);
continue;

/*:21*//*22:*/
#line 486 "mmmix.w"

case'f':tmp= read_hex(buffer+1);
{
register fetch*new_tail;
if(tail==fetch_bot)new_tail= fetch_top;
else new_tail= tail-1;
if(new_tail==head)printf("Sorry, the fetch buffer is full!\n");
else{
tail->loc= inst_ptr.o;
tail->inst= tmp.l;
tail->interrupt= 0;
tail->noted= false;
tail= new_tail;
}
continue;
}

/*:22*//*23:*/
#line 507 "mmmix.w"

case'd':if(ticks.l)
printf("Sorry: I disable ITcache and DTcache only at the beginning!\n");
else{
ITcache->set[0][0].tag= zero_octa;
ITcache->set[0][0].data[0]= seven_octa;
DTcache->set[0][0].tag= zero_octa;
DTcache->set[0][0].data[0]= seven_octa;
g[rK].o= neg_one;
page_bad= false;
page_mask= neg_one;
inst_ptr.p= (specnode*)1;
}continue;

/*:23*//*24:*/
#line 526 "mmmix.w"

case'k':{register int j;
for(j= 0;j<funit_count;j++)
printf("unit %s %d\n",funit[j].name,funit[j].k);
}
continue;

/*:24*/
#line 364 "mmmix.w"

}
}
done:

/*:13*/
#line 52 "mmmix.w"
;
printf("Simulation ended at time %d.\n",ticks.l);
print_stats();
return 0;
}

/*:2*/


syntax highlighted by Code2HTML, v. 0.9.1