$NetBSD: patch-ab,v 1.1 2006/02/06 16:10:14 tonio Exp $ --- mmix-pipe.w.orig 2003-06-16 00:18:12.000000000 +0200 +++ mmix-pipe.w @@ -2355,9 +2355,9 @@ it says |goto done|. It will not be sche unless the |schedule| routine has been called since it began execution. The |wait| macro is a convenient way to say ``Please schedule me to resume again at the current |data->state|'' after a specified time; for example, -|wait(1)| will restart a coroutine on the next clock tick. +|mmix_wait(1)| will restart a coroutine on the next clock tick. -@d wait(t)@+ {@+schedule(self,t,data->state);@+ goto done;@+} +@d mmix_wait(t)@+ {@+schedule(self,t,data->state);@+ goto done;@+} @d pass_after(t) schedule(self+1,t,data->state) @d sleep@+ {@+self->next=self;@+ goto done;@+} /* wait forever */ @d awaken(c,t) schedule(c,t,c->ctl->state) @@ -2459,7 +2459,7 @@ if (data->ra.p) { else if (data->need_ra) j+=10; } if (j<10) data->state=1; -if (j) wait(1); /* otherwise we fall through to case 1 */ +if (j) mmix_wait(1); /* otherwise we fall through to case 1 */ @ Simple register-to-register instructions like \.{ADD} are assumed to take just one cycle, but others like \.{FADD} almost certainly require more time. @@ -2500,7 +2500,7 @@ if (data->i<=max_pipe_op) {@+register un j=s[0]+data->denin; if (s[1]) data->state=2; /* more than one stage */ else j+=data->denout; - if (j>1) wait(j-1); + if (j>1) mmix_wait(j-1); } goto switch1; @@ -2509,7 +2509,7 @@ unit is |self+1|. @= pass_data:@+ -if ((self+1)->next) wait(1); /* stall if the next stage is occupied */ +if ((self+1)->next) mmix_wait(1); /* stall if the next stage is occupied */ {@+register unsigned char *s=pipe_seq[data->i]; j=s[self->stage]; if (s[self->stage+1]==0) j+=data->denout,data->state=3; @@ -3766,7 +3766,7 @@ or~|Dcache|. The data to be written will @= case flush_to_mem: {@+register cache *c=(cache *)data->ptr_a; switch (data->state) { - case 0:@+ if (mem_lock) wait(1); + case 0:@+ if (mem_lock) mmix_wait(1); data->state=1; case 1: set_lock(self,mem_lock); data->state=2; @@ -3796,7 +3796,7 @@ case flush_to_mem: {@+register cache *c= i++;@+ off++;@+ addr.l+=8; } } - wait(mem_addr_time+count*mem_write_time); + mmix_wait(mem_addr_time+count*mem_write_time); } @* Cache transfers. We have seen that the |Dcache->flusher| sends @@ -3819,23 +3819,23 @@ case flush_to_S: {@+register cache *c=(c register int block_diff=Scache->bb-c->bb; p=(cacheblock*)data->ptr_b; switch (data->state) { - case 0:@+ if (Scache->lock) wait(1); + case 0:@+ if (Scache->lock) mmix_wait(1); data->state=1; case 1: set_lock(self,Scache->lock); data->ptr_b=(void*)cache_search(Scache,c->outbuf.tag); if (data->ptr_b) data->state=4; else if (Scache->mode & WRITE_ALLOC) data->state=(block_diff? 2: 3); else data->state=6; - wait(Scache->access_time); + mmix_wait(Scache->access_time); case 2: @inbuf| with clean memory data@>; case 3: @; if (block_diff) @inbuf| to slot |p|@>; case 4: copy_block(c,&(c->outbuf),Scache,p); hit_set=cache_addr(Scache,c->outbuf.tag);@+ use_and_fix(Scache,p); /* |p| not moved */ - data->state=5;@+ wait(Scache->copy_in_time); + data->state=5;@+ mmix_wait(Scache->copy_in_time); case 5:@+ if ((Scache->mode&WRITE_BACK)==0) { /* write-through */ - if (Scache->flusher.next) wait(1); + if (Scache->flusher.next) mmix_wait(1); flush_cache(Scache,p,true); } goto terminate; @@ -3844,9 +3844,9 @@ case flush_to_S: {@+register cache *c=(c } @ @= -if (Scache->filler.next) wait(1); /* perhaps an unnecessary precaution? */ +if (Scache->filler.next) mmix_wait(1); /* perhaps an unnecessary precaution? */ p=alloc_slot(Scache,c->outbuf.tag); -if (!p) wait(1); +if (!p) mmix_wait(1); data->ptr_b=(void*)p; p->tag=c->outbuf.tag;@+ p->tag.l=c->outbuf.tag.l&(-Scache->bb); @@ -3857,7 +3857,7 @@ read them all and to charge only for rea {@+register int count=block_diff>>3; register int off,delay; octa addr; - if (mem_lock) wait(1); + if (mem_lock) mmix_wait(1); addr.h=c->outbuf.tag.h;@+ addr.l=c->outbuf.tag.l&-Scache->bb; off=(addr.l&0xffff)>>3; for (j=0;jbb>>3;j++) @@ -3866,7 +3866,7 @@ read them all and to charge only for rea set_lock(&mem_locker,mem_lock); delay=mem_addr_time+(int)((count+bus_words-1)/(bus_words))*mem_read_time; startup(&mem_locker,delay); - data->state=3;@+ wait(delay); + data->state=3;@+ mmix_wait(delay); } @ @inbuf| to slot |p|@>= @@ -3878,7 +3878,7 @@ read them all and to charge only for rea @ Here we assume that the granularity is~8. @= -if (Scache->flusher.next) wait(1); +if (Scache->flusher.next) mmix_wait(1); Scache->outbuf.tag.h=c->outbuf.tag.h; Scache->outbuf.tag.l=c->outbuf.tag.l&(-Scache->bb); for (j=0;jbb>>Scache->g;j++) Scache->outbuf.dirty[j]=false; @@ -3920,12 +3920,12 @@ case fill_from_mem: {@+register cache *c case 1: release_lock(self,mem_lock); data->state=2; case 2:@+if (c!=Scache) { - if (c->lock) wait(1); + if (c->lock) mmix_wait(1); set_lock(self,c->lock); } if (cc) awaken(cc,c->copy_in_time); /* the second wakeup call */ load_cache(c,(cacheblock*)data->ptr_b); - data->state=3;@+ wait(c->copy_in_time); + data->state=3;@+ mmix_wait(c->copy_in_time); case 3: goto terminate; } } @@ -3939,8 +3939,8 @@ cycle, so that there will be two wakeup c->inbuf.tag=data->z.o;@+ c->inbuf.tag.l &= -c->bb; count=c->bb>>3, off=(c->inbuf.tag.l&0xffff)>>3; for (i=0;iinbuf.data[i]=mem_hash[last_h].chunk[off]; - if (count<=bus_words) wait(1+mem_read_time)@; - else wait((int)(count/bus_words)*mem_read_time); + if (count<=bus_words) mmix_wait(1+mem_read_time)@; + else mmix_wait((int)(count/bus_words)*mem_read_time); } @ The |fill_from_S| coroutine has the same conventions as |fill_from_mem|, @@ -3969,12 +3969,12 @@ case fill_from_S: {@+register cache *c=( awaken(cc,Scache->access_time); } case 3: @inbuf|@>; - data->state=4;@+wait(Scache->access_time); - case 4:@+ if (c->lock) wait(1); + data->state=4;@+mmix_wait(Scache->access_time); + case 4:@+ if (c->lock) mmix_wait(1); set_lock(self,c->lock); Scache->lock=NULL; /* we had been holding that lock */ load_cache(c,(cacheblock*)data->ptr_b); - data->state=5;@+ wait(c->copy_in_time); + data->state=5;@+ mmix_wait(c->copy_in_time); case 5:@+if (cc) awaken(cc,1); /* second wakeup call */ goto terminate; } @@ -3987,9 +3987,9 @@ but we will point to |Scache->fill_lock| because the present coroutine is not abortable. @= -if (Scache->filler.next || mem_lock) wait(1); +if (Scache->filler.next || mem_lock) mmix_wait(1); p=alloc_slot(Scache,data->z.o); -if (!p) wait(1); +if (!p) mmix_wait(1); set_lock(&Scache->filler,mem_lock); set_lock(self,Scache->fill_lock); data->ptr_c=Scache->filler_ctl.ptr_b=(void *)p; @@ -4079,7 +4079,7 @@ case 10: goto terminate; } @ @= -case 0:@+ if (Dcache->lock || (j=get_reader(Dcache)<0)) wait(1); +case 0:@+ if (Dcache->lock || (j=get_reader(Dcache)<0)) mmix_wait(1); startup(&Dcache->reader[j],Dcache->access_time); set_lock(self,Dcache->lock); i=j=0; @@ -4091,18 +4091,18 @@ Dclean_loop: p=(icc? &(Dcache-> data->y.o.h=i, data->y.o.l=j; Dclean: data->state=1;@+ data->ptr_b=(void*)p;@+ - wait(Dcache->access_time); -case 1:@+if (Dcache->flusher.next) wait(1); + mmix_wait(Dcache->access_time); +case 1:@+if (Dcache->flusher.next) mmix_wait(1); flush_cache(Dcache,p,data->x.o.h==0); p->tag.h|=data->x.o.h; release_lock(self,Dcache->lock); data->state=2;@+ - wait(Dcache->copy_out_time); + mmix_wait(Dcache->copy_out_time); case 2:@+ if (!clean_lock) goto done; /* premature termination */ - if (Dcache->flusher.next) wait(1); + if (Dcache->flusher.next) mmix_wait(1); if (data->i!=sync) goto Sprep; data->state=3; -case 3:@+ if (Dcache->lock || (j=get_reader(Dcache)<0)) wait(1); +case 3:@+ if (Dcache->lock || (j=get_reader(Dcache)<0)) mmix_wait(1); startup(&Dcache->reader[j],Dcache->access_time); set_lock(self,Dcache->lock); i=data->y.o.h, j=data->y.o.l; @@ -4110,10 +4110,10 @@ Dclean_inc: j++; if (icc && j==Dcache->aa) j=0, i++; if (i==Dcache->cc && j==Dcache->vv) { data->state=5;@+ - wait(Dcache->access_time); + mmix_wait(Dcache->access_time); } goto Dclean_loop; -case 4:@+ if (Dcache->lock || (j=get_reader(Dcache)<0)) wait(1); +case 4:@+ if (Dcache->lock || (j=get_reader(Dcache)<0)) mmix_wait(1); startup(&Dcache->reader[j],Dcache->access_time); set_lock(self,Dcache->lock); p=cache_search(Dcache,data->z.o); @@ -4122,12 +4122,12 @@ case 4:@+ if (Dcache->lock || (j=get_rea if (is_dirty(Dcache,p)) goto Dclean; } data->state=9;@+ - wait(Dcache->access_time); + mmix_wait(Dcache->access_time); @ @= case 5:@+ if (self->lockloc) *(self->lockloc)=NULL, self->lockloc=NULL; if (!Scache) goto done; - if (Scache->lock) wait(1); + if (Scache->lock) mmix_wait(1); set_lock(self,Scache->lock); i=j=0; Sclean_loop: p=(icc? &(Scache->set[i][j]): &(Scache->victim[j])); @@ -4138,31 +4138,31 @@ Sclean_loop: p=(icc? &(Scache-> data->y.o.h=i, data->y.o.l=j; Sclean: data->state=6;@+ data->ptr_b=(void*)p;@+ - wait(Scache->access_time); -case 6:@+if (Scache->flusher.next) wait(1); + mmix_wait(Scache->access_time); +case 6:@+if (Scache->flusher.next) mmix_wait(1); flush_cache(Scache,p,data->x.o.h==0); p->tag.h|=data->x.o.h; release_lock(self,Scache->lock); data->state=7;@+ - wait(Scache->copy_out_time); + mmix_wait(Scache->copy_out_time); case 7:@+ if (!clean_lock) goto done; /* premature termination */ - if (Scache->flusher.next) wait(1); + if (Scache->flusher.next) mmix_wait(1); if (data->i!=sync) goto done; data->state=8; -case 8:@+ if (Scache->lock) wait(1); +case 8:@+ if (Scache->lock) mmix_wait(1); set_lock(self,Scache->lock); i=data->y.o.h, j=data->y.o.l; Sclean_inc: j++; if (icc && j==Scache->aa) j=0, i++; if (i==Scache->cc && j==Scache->vv) { data->state=10;@+ - wait(Scache->access_time); + mmix_wait(Scache->access_time); } goto Sclean_loop; Sprep: data->state=9; case 9:@+if (self->lockloc) release_lock(self,Dcache->lock); if (!Scache) goto done; - if (Scache->lock) wait(1); + if (Scache->lock) mmix_wait(1); set_lock(self,Scache->lock); p=cache_search(Scache,data->z.o); if (p) { @@ -4170,7 +4170,7 @@ case 9:@+if (self->lockloc) release_lock if (is_dirty(Scache,p)) goto Sclean; } data->state=10;@+ - wait(Scache->access_time); + mmix_wait(Scache->access_time); @* Virtual address translation. Special arrays of coroutines and control blocks come into play when we need to implement \MMIX's rather complicated @@ -4250,15 +4250,15 @@ case fill_from_virt: {@+register cache * data->state=1; case 1:@+if (data->b.p) { if (data->b.p->known) data->b.o=data->b.p->o, data->b.p=NULL; - else wait(1); + else mmix_wait(1); } @inbuf| and give the caller a sneak preview@>; data->state=2; - case 2:@+if (c->lock) wait(1); + case 2:@+if (c->lock) mmix_wait(1); set_lock(self,c->lock); load_cache(c,(cacheblock*)data->ptr_b); - data->state=3;@+ wait(c->copy_in_time); + data->state=3;@+ mmix_wait(c->copy_in_time); case 3: data->b.o=zero_octa;@+goto terminate; } } @@ -4545,18 +4545,18 @@ case write_from_wbuf: case 5:@+if (write_head==wbuf_bot) write_head=wbuf_top;@+ else write_head--; write_restart: data->state=0; case 0:@+ if (self->lockloc) *(self->lockloc)=NULL,self->lockloc=NULL; - if (write_head==write_tail) wait(1); /* write buffer is empty */ + if (write_head==write_tail) mmix_wait(1); /* write buffer is empty */ if (write_head->i==sync) @; if (ticks.l-write_head->stampaddr.h&0xffff0000)) goto mem_direct; /* not cached */ - if (Dcache->lock || (j=get_reader(Dcache)<0)) wait(1); /* D-cache busy */ + if (Dcache->lock || (j=get_reader(Dcache)<0)) mmix_wait(1); /* D-cache busy */ startup(&Dcache->reader[j],Dcache->access_time); @; data->state=((Dcache->mode&WRITE_ALLOC) && write_head->i!=stunc? 1: 3); - wait(Dcache->access_time); + mmix_wait(Dcache->access_time); case 1: @addr| into the D-cache@>; data->state=2;@+sleep; @@ -4573,7 +4573,7 @@ register cacheblock *p,*q; D-cache (unless it hits in the D-cache), it will go into a secondary cache. @= -if (Dcache->flusher.next) wait(1); +if (Dcache->flusher.next) mmix_wait(1); Dcache->outbuf.tag.h=write_head->addr.h; Dcache->outbuf.tag.l=write_head->addr.l&(-Dcache->bb); for (j=0;jbb>>Dcache->g;j++) Dcache->outbuf.dirty[j]=false; @@ -4581,20 +4581,20 @@ Dcache->outbuf.data[(write_head->addr.l& Dcache->outbuf.dirty[(write_head->addr.l&(Dcache->bb-1))>>Dcache->g]=true; set_lock(self,wbuf_lock); startup(&Dcache->flusher,Dcache->copy_out_time); -data->state=5;@+ wait(Dcache->copy_out_time); +data->state=5;@+ mmix_wait(Dcache->copy_out_time); @ @= -if (mem_lock) wait(1); +if (mem_lock) mmix_wait(1); set_lock(self,wbuf_lock); set_lock(&mem_locker,mem_lock); /* a coroutine of type |vanish| */ startup(&mem_locker,mem_addr_time+mem_write_time); mem_write(write_head->addr,write_head->o); -data->state=5;@+ wait(mem_addr_time+mem_write_time); +data->state=5;@+ mmix_wait(mem_addr_time+mem_write_time); @ A subtlety needs to be mentioned here: While we're trying to update the D-cache, another instruction might be filling the same cache block (although not because of the same physical address). -Therefore we |goto write_restart| here instead of saying |wait(1)|. +Therefore we |goto write_restart| here instead of saying |mmix_wait(1)|. @addr| into the D-cache@>= if (Dcache->filler.next) goto write_restart; @@ -4622,12 +4622,12 @@ if (p) { data->ptr_b=(void *)p; p->data[(write_head->addr.l&(Dcache->bb-1))>>3]=write_head->o; p->dirty[(write_head->addr.l&(Dcache->bb-1))>>Dcache->g]=true; - data->state=4;@+ wait(Dcache->access_time); + data->state=4;@+ mmix_wait(Dcache->access_time); } @ @= if ((Dcache->mode&WRITE_BACK)==0) { /* write-through */ - if (Dcache->flusher.next) wait(1); + if (Dcache->flusher.next) mmix_wait(1); flush_cache(Dcache,p,true); } @@ -4635,7 +4635,7 @@ if ((Dcache->mode&WRITE_BACK)==0) { /* w { set_lock(self,wbuf_lock); data->state=5; - wait(1); + mmix_wait(1); } @* Loading and storing. A RISC machine is often said to have a ``load/store @@ -4684,7 +4684,7 @@ case ldptp: case ldpte:@+if (data->y.o.h @= case ld_st_launch:@+if ((self+1)->next) - wait(1); /* second stage must be clear */ + mmix_wait(1); /* second stage must be clear */ @; if (data->y.o.h&sign_bit) @; @@ -4693,7 +4693,7 @@ case ld_st_launch:@+if ((self+1)->next) data->interrupt|=PRW_BITS; goto fin_ex; } - if (DTcache->lock || (j=get_reader(DTcache))<0) wait(1); + if (DTcache->lock || (j=get_reader(DTcache))<0) mmix_wait(1); startup(&DTcache->reader[j],DTcache->access_time); @; pass_after(DTcache->access_time);@+ goto passit; @@ -4812,7 +4812,7 @@ if (((p->data[0].l<state=DT_hit; else data->x.o=*m, data->state=ld_ready; }@+ else if ((data->z.o.h&0xffff0000) || !Dcache) { - if (mem_lock) wait(1); + if (mem_lock) mmix_wait(1); set_lock(&mem_locker,mem_lock); data->x.o=mem_read(data->z.o); data->state=ld_ready; @@ -4848,7 +4848,7 @@ are rare. @= square_one: data->state=DT_retry; - case DT_retry:@+if (DTcache->lock || (j=get_reader(DTcache))<0) wait(1); + case DT_retry:@+if (DTcache->lock || (j=get_reader(DTcache))<0) mmix_wait(1); startup(&DTcache->reader[j],DTcache->access_time); p=cache_search(DTcache,trans_key(data->y.o)); if (p) { @@ -4857,7 +4857,7 @@ square_one: data->state=DT_retry; if (data->i>=st && data->i<=syncid) data->state=st_ready; else data->state=DT_hit; }@+ else data->state=DT_miss; - wait(DTcache->access_time); + mmix_wait(DTcache->access_time); case DT_miss:@+if (DTcache->filler.next) if (data->i==preld || data->i==prest) goto fin_ex;@+ else goto square_one; if (no_hardware_PT) @@ -4897,7 +4897,7 @@ ld_retry: data->state=DT_hit; @; if ((data->z.o.h&0xffff0000) || !Dcache) @; - if (Dcache->lock || (j=get_reader(Dcache))<0) wait(1); + if (Dcache->lock || (j=get_reader(Dcache))<0) mmix_wait(1); startup(&Dcache->reader[j],Dcache->access_time); q=cache_search(Dcache,data->z.o); if (q) { @@ -4906,7 +4906,7 @@ ld_retry: data->state=DT_hit; data->x.o=q->data[(data->z.o.l&(Dcache->bb-1))>>3]; data->state=ld_ready; }@+else data->state=hit_and_miss; - wait(Dcache->access_time); + mmix_wait(Dcache->access_time); case hit_and_miss:@+if (data->i==ldunc) goto avoid_D; @z.o| in the D-cache@>; @@ -4941,7 +4941,7 @@ if (data->i==prest &&@| @ @= prest_span: data->state=prest_win; -case prest_win:@+ if (data!=old_hot || Dlocker.next) wait(1); +case prest_win:@+ if (data!=old_hot || Dlocker.next) mmix_wait(1); if (Dcache->lock) goto fin_ex; q=alloc_slot(Dcache,data->z.o); /* OK if |Dcache->filler| is busy */ if (q) { @@ -4954,21 +4954,21 @@ case prest_win:@+ if (data!=old_hot || D @ @= { -avoid_D:@+ if (mem_lock) wait(1); +avoid_D:@+ if (mem_lock) mmix_wait(1); set_lock(&mem_locker,mem_lock); startup(&mem_locker, mem_addr_time+mem_read_time); data->x.o=mem_read(data->z.o); - data->state=ld_ready;@+ wait(mem_addr_time+mem_read_time); + data->state=ld_ready;@+ mmix_wait(mem_addr_time+mem_read_time); } @ @= { octa *m=write_search(data,data->z.o); - if (m==DUNNO) wait(1); + if (m==DUNNO) mmix_wait(1); if (m) { data->x.o=*m; data->state=ld_ready; - wait(1); + mmix_wait(1); } } @@ -4991,7 +4991,7 @@ case ld_ready:@+if (self->lockloc) case LDSF>>1:@+if (data->z.o.l&4) data->x.o.h=data->x.o.l; if ((data->x.o.h&0x7f800000)==0 && (data->x.o.h&0x7fffff)) { data->x.o=load_sf(data->x.o.h); - data->state=3;@+wait(denin_penalty); + data->state=3;@+mmix_wait(denin_penalty); } else data->x.o=load_sf(data->x.o.h);@+goto fin_ex; case LDPTP>>1:@+ @@ -5020,7 +5020,7 @@ to check for overflow. @= data->x.addr=data->z.o; -if (data->b.p) wait(1); +if (data->b.p) mmix_wait(1); switch(data->op>>1) { case STUNC>>1: data->i=stunc; default: data->x.o=data->b.o;@+goto fin_ex; @@ -5029,7 +5029,7 @@ switch(data->op>>1) { if ((data->b.o.h&0x7f800000)==0 && (data->b.o.h&0x7fffff)) { if (data->z.o.l&4) data->x.o.l=data->b.o.h; else data->x.o.h=data->b.o.h; - data->state=3;@+wait(denout_penalty); + data->state=3;@+mmix_wait(denout_penalty); } case STHT>>1:@+if (data->z.o.l&4) data->x.o.l=data->b.o.h; else data->x.o.h=data->b.o.h; @@ -5063,7 +5063,7 @@ of the control blocks in our pipeline, w the hot seat, thereby allowing us non-speculative access to~rP. @= -if (data!=old_hot) wait(1); +if (data!=old_hot) mmix_wait(1); if (data->x.o.h==g[rP].o.h && data->x.o.l==g[rP].o.l) { data->a.o.l=1; /* |data->a.o.h| is zero */ data->x.o=data->b.o; @@ -5129,7 +5129,7 @@ startup(&fetch_co,1); first and second stages of a |prego| operation. @d wait_or_pass(t) if (data->i==prego) {@+pass_after(t);@+goto passit;@+} - else wait(t) + else mmix_wait(t) @= switch0:@+ switch(data->state) { @@ -5140,7 +5140,7 @@ switch0:@+ switch(data->state) { case 1: start_fetch:@+ if (data->y.o.h&sign_bit) @; if (page_bad) goto bad_fetch; - if (ITcache->lock || (j=get_reader(ITcache))<0) wait(1); + if (ITcache->lock || (j=get_reader(ITcache))<0) mmix_wait(1); startup(&ITcache->reader[j],ITcache->access_time); @; wait_or_pass(ITcache->access_time); @@ -5154,7 +5154,7 @@ if (data->i==prego) goto start_fetch; if (inst_ptr.p) { if (inst_ptr.p!=UNKNOWN_SPEC && inst_ptr.p->known) inst_ptr.o=inst_ptr.p->o, inst_ptr.p=NULL; - wait(1); + mmix_wait(1); } @ @d got_IT 19 /* |state| when IT-cache entry has been computed */ @@ -5242,7 +5242,7 @@ if (data->i!=prego) { @ @= {@+octa addr; addr=data->z.o; - if (mem_lock) wait(1); + if (mem_lock) mmix_wait(1); set_lock(&mem_locker,mem_lock); startup(&mem_locker,mem_addr_time+mem_read_time); addr.l&=-(bus_words<<3); @@ -5251,12 +5251,12 @@ if (data->i!=prego) { fetched[j]=mem_hash[last_h].chunk[((addr.l&0xffff)>>3)+j]; fetch_lo=(data->z.o.l>>3)&(bus_words-1);@+ fetch_hi=bus_words; data->state=fetch_ready; - wait(mem_addr_time+mem_read_time); + mmix_wait(mem_addr_time+mem_read_time); } @ @= case IT_miss:@+if (ITcache->filler.next) - if (data->i==prego) goto fin_ex;@+else wait(1); + if (data->i==prego) goto fin_ex;@+else mmix_wait(1); if (no_hardware_PT) @; p=alloc_slot(ITcache,trans_key(data->y.o)); if (!p) /* hey, it was present after all */ @@ -5320,7 +5320,7 @@ case fetch_ready:@+if (self->lockloc) inst_ptr.o=incr(inst_ptr.o,4); if (fetch_lo==fetch_hi) goto new_fetch; } - wait(1); + mmix_wait(1); @ @= { @@ -5443,10 +5443,10 @@ lest we issue an instruction that uses @= emulate_virt: @; state_4: data->state=4; -case 4:@+if (dispatch_lock) wait(1); +case 4:@+if (dispatch_lock) mmix_wait(1); set_lock(self,dispatch_lock); state_5: data->state=5; -case 5:@+if (data!=old_hot) wait(1); +case 5:@+if (data!=old_hot) mmix_wait(1); if ((data->interrupt&F_BIT) && data->i!=trap) { inst_ptr.o=g[rT].o, inst_ptr.p=NULL; if (is_load_store(data->i)) nullifying=true; @@ -5736,8 +5736,8 @@ case resume: case resum:@+if (data->xx!= @ @= case do_resume_trans: resume_trans: {@+register cache*c=(cache*)data->ptr_a; - if (c->lock) wait(1); - if (c->filler.next) wait(1); + if (c->lock) mmix_wait(1); + if (c->filler.next) mmix_wait(1); p=alloc_slot(c,trans_key(data->y.o)); if (p) { c->filler_ctl.ptr_b=(void*)p; @@ -5773,7 +5773,7 @@ by emulated instructions. @= case get:@+ if (data->zz>=21 || data->zz==rK) { - if (data!=old_hot) wait(1); + if (data!=old_hot) mmix_wait(1); data->z.o=g[data->zz].o; } data->x.o=data->z.o;@+goto fin_ex; @@ -5785,7 +5785,7 @@ drastic implications. @= case put:@+if (data->xx>=15 && data->xx<=20) { - if (data!=old_hot) wait(1); + if (data!=old_hot) mmix_wait(1); switch (data->xx) { case rV: @;@+break; case rQ: new_Q.h |= data->z.o.h &~ g[rQ].o.h;@+ @@ -5817,7 +5817,7 @@ else if (data->z.o.lz.o.l==g[rG].o.l) break; } if (j==commit_max) { - if (!trying_to_interrupt) wait(1); + if (!trying_to_interrupt) mmix_wait(1); }@+else data->interim=false; } @@ -5964,7 +5964,7 @@ switch (cool->zz) { { if (data->interim) data->x.o=data->b.o; else { - if (data!=old_hot) wait(1); /* we need the hottest value of rA */ + if (data!=old_hot) mmix_wait(1); /* we need the hottest value of rA */ data->x.o.h=g[rG].o.l<<24; data->x.o.l=g[rA].o.l; data->a.o=data->y.o; @@ -6123,7 +6123,7 @@ case frem:@+if(is_trivial(data->y.o) || { data->x.o=fremstep(data->y.o,data->z.o,2500);@+ goto fin_ex; } - if ((self+1)->next) wait(1); + if ((self+1)->next) mmix_wait(1); data->interim=true; j=1; if (is_denormal(data->y.o)||is_denormal(data->z.o)) j+=denin_penalty; @@ -6144,7 +6144,7 @@ if (data->i==frem) { data->interrupt |= exceptions; if (is_denormal(data->x.o)) j+=denout_penalty; } - wait(j); + mmix_wait(j); } @* System operations. Finally we need to implement some operations for the @@ -6165,8 +6165,8 @@ if (data->i==ldvts) @= { - if (data!=old_hot) wait(1); - if (DTcache->lock || (j=get_reader(DTcache))<0) wait(1); + if (data!=old_hot) mmix_wait(1); + if (DTcache->lock || (j=get_reader(DTcache))<0) mmix_wait(1); startup(&DTcache->reader[j],DTcache->access_time); data->z.o.h=0, data->z.o.l=data->y.o.l&0x7; p=cache_search(DTcache,data->y.o); /* N.B.: Not |trans_key(data->y.o)| */ @@ -6184,7 +6184,7 @@ if (data->i==ldvts) @= -case ld_st_launch:@+ if (ITcache->lock || (j=get_reader(ITcache))<0) wait(1); +case ld_st_launch:@+ if (ITcache->lock || (j=get_reader(ITcache))<0) mmix_wait(1); startup(&ITcache->reader[j],ITcache->access_time); p=cache_search(ITcache,data->y.o); /* N.B.: Not |trans_key(data->y.o)| */ if (p) { @@ -6197,7 +6197,7 @@ case ld_st_launch:@+ if (ITcache->lock | p->tag.h|=sign_bit; /* invalidate the tag */ } } - data->state=3;@+wait(ITcache->access_time); + data->state=3;@+mmix_wait(ITcache->access_time); @ The \.{SYNC} operation interacts with the pipeline in interesting ways. \.{SYNC}~\.0 and \.{SYNC}~\.4 are the simplest; they just lock the @@ -6220,16 +6220,16 @@ case sync:@+ if (cool->zz>3) { @ @= case sync:@+ switch (data->zz) { - case 0: case 4:@+ if (data!=old_hot) wait(1); + case 0: case 4:@+ if (data!=old_hot) mmix_wait(1); halted=(data->zz!=0);@+goto fin_ex; case 2: case 3: @; release_lock(self,dispatch_lock); case 1: data->x.addr=zero_octa;@+goto fin_ex; - case 5:@+ if (data!=old_hot) wait(1); + case 5:@+ if (data!=old_hot) mmix_wait(1); @; - case 6:@+ if (data!=old_hot) wait(1); + case 6:@+ if (data!=old_hot) mmix_wait(1); @; - case 7:@+ if (data!=old_hot) wait(1); + case 7:@+ if (data!=old_hot) mmix_wait(1); @; } @@ -6238,58 +6238,58 @@ case sync:@+ switch (data->zz) { register control *cc; for (cc=data;cc!=hot;) { cc=(cc==reorder_top? reorder_bot: cc+1); - if (cc->owner && (cc->i==ld || cc->i==ldunc || cc->i==pst)) wait(1); + if (cc->owner && (cc->i==ld || cc->i==ldunc || cc->i==pst)) mmix_wait(1); } } @ Perhaps the delay should be longer here. @= -if (DTcache->lock || (j=get_reader(DTcache))<0) wait(1); +if (DTcache->lock || (j=get_reader(DTcache))<0) mmix_wait(1); startup(&DTcache->reader[j],DTcache->access_time); set_lock(self,DTcache->lock); zap_cache(DTcache); -data->state=10;@+wait(DTcache->access_time); +data->state=10;@+mmix_wait(DTcache->access_time); @ @= if (!Icache) { data->state=11;@+goto switch1; } -if (Icache->lock || (j=get_reader(Icache))<0) wait(1); +if (Icache->lock || (j=get_reader(Icache))<0) mmix_wait(1); startup(&Icache->reader[j],Icache->access_time); set_lock(self,Icache->lock); zap_cache(Icache); -data->state=11;@+wait(Icache->access_time); +data->state=11;@+mmix_wait(Icache->access_time); @ @= case 10:@+ if (self->lockloc) *(self->lockloc)=NULL,self->lockloc=NULL; - if (ITcache->lock || (j=get_reader(ITcache))<0) wait(1); + if (ITcache->lock || (j=get_reader(ITcache))<0) mmix_wait(1); startup(&ITcache->reader[j],ITcache->access_time); set_lock(self,ITcache->lock); zap_cache(ITcache); - data->state=3;@+wait(ITcache->access_time); + data->state=3;@+mmix_wait(ITcache->access_time); case 11:@+ if (self->lockloc) *(self->lockloc)=NULL,self->lockloc=NULL; - if (wbuf_lock) wait(1); + if (wbuf_lock) mmix_wait(1); write_head=write_tail, write_ctl.state=0; /* zap the write buffer */ if (!Dcache) { data->state=12;@+ goto switch1; } - if (Dcache->lock || (j=get_reader(Dcache))<0) wait(1); + if (Dcache->lock || (j=get_reader(Dcache))<0) mmix_wait(1); startup(&Dcache->reader[j],Dcache->access_time); set_lock(self,Dcache->lock); zap_cache(Dcache); - data->state=12;@+wait(Dcache->access_time); + data->state=12;@+mmix_wait(Dcache->access_time); case 12:@+ if (self->lockloc) *(self->lockloc)=NULL,self->lockloc=NULL; if (!Scache) goto fin_ex; - if (Scache->lock) wait(1); + if (Scache->lock) mmix_wait(1); set_lock(self,Scache->lock); zap_cache(Scache); - data->state=3;@+wait(Scache->access_time); + data->state=3;@+mmix_wait(Scache->access_time); @ @= if (self->lockloc) *(self->lockloc)=NULL,self->lockloc=NULL; @; -if (clean_co.next || clean_lock) wait(1); +if (clean_co.next || clean_lock) mmix_wait(1); set_lock(self,clean_lock); clean_ctl.i=sync;@+ clean_ctl.state=0;@+ @@ -6297,12 +6297,12 @@ clean_ctl.x.o.h=0; startup(&clean_co,1); data->state=13; data->interim=true; -wait(1); +mmix_wait(1); @ @= if (write_head!=write_tail) { if (!speed_lock) set_lock(self,speed_lock); - wait(1); + mmix_wait(1); } @ The cleanup process might take a huge amount of time, so we must allow @@ -6314,7 +6314,7 @@ case 13:@+ if (!clean_co.next) { data->interim=false;@+ goto fin_ex; /* it's done! */ } if (trying_to_interrupt) goto fin_ex; /* accept an interruption */ - wait(1); + mmix_wait(1); @ Now we consider \.{SYNCD} and \.{SYNCID}. When control comes to this part of the program, |data->y.o| is a virtual address and |data->z.o| @@ -6336,24 +6336,24 @@ brought the memory up to date. @= do_syncid: data->state=30; -case 30:@+ if (data!=old_hot) wait(1); +case 30:@+ if (data!=old_hot) mmix_wait(1); if (!Icache) { data->state=(data->loc.h&sign_bit? 31:33);@+goto switch2; } @z.o|, if any@>; - data->state=(data->loc.h&sign_bit? 31: 33);@+wait(Icache->access_time); + data->state=(data->loc.h&sign_bit? 31: 33);@+mmix_wait(Icache->access_time); case 31:@+ if (self->lockloc) *(self->lockloc)=NULL,self->lockloc=NULL; @; if (((data->b.o.l-1)&~data->y.o.l)xx) data->interim=true; if (!Dcache) goto next_sync; @z.o|, if any@>; - data->state=32;@+wait(Dcache->access_time); + data->state=32;@+mmix_wait(Dcache->access_time); case 32:@+ if (self->lockloc) *(self->lockloc)=NULL,self->lockloc=NULL; if (!Scache) goto next_sync; @z.o|, if any@>; - data->state=35;@+wait(Scache->access_time); + data->state=35;@+mmix_wait(Scache->access_time); do_syncd: data->state=33; -case 33:@+ if (data!=old_hot) wait(1); +case 33:@+ if (data!=old_hot) mmix_wait(1); if (self->lockloc) *(self->lockloc)=NULL,self->lockloc=NULL; @; if (((data->b.o.l-1)&~data->y.o.l)xx) data->interim=true; @@ -6366,7 +6366,7 @@ case 34:@+if (!clean_co.next) goto next_ data->z.o=zero_octa; /* anticipate |RESUME_CONT| */ goto fin_ex; /* accept an interruption */ } - wait(1); + mmix_wait(1); next_sync: data->state=35; case 35:@+ if (self->lockloc) *(self->lockloc)=NULL,self->lockloc=NULL; if (data->interim) @; @@ -6374,7 +6374,7 @@ case 35:@+ if (self->lockloc) *(self->lo goto fin_ex; @ @z.o|, if any@>= -if (Icache->lock || (j=get_reader(Icache))<0) wait(1); +if (Icache->lock || (j=get_reader(Icache))<0) mmix_wait(1); startup(&Icache->reader[j],Icache->access_time); set_lock(self,Icache->lock); p=cache_search(Icache,data->z.o); @@ -6384,7 +6384,7 @@ if (p) { } @ @z.o|, if any@>= -if (Dcache->lock || (j=get_reader(Dcache))<0) wait(1); +if (Dcache->lock || (j=get_reader(Dcache))<0) mmix_wait(1); startup(&Dcache->reader[j],Dcache->access_time); set_lock(self,Dcache->lock); p=cache_search(Dcache,data->z.o); @@ -6394,7 +6394,7 @@ if (p) { } @ @z.o|, if any@>= -if (Scache->lock) wait(1); +if (Scache->lock) mmix_wait(1); set_lock(self,Scache->lock); p=cache_search(Scache,data->z.o); if (p) { @@ -6403,7 +6403,7 @@ if (p) { } @ @z.o|, if any@>= -if (clean_co.next || clean_lock) wait(1); +if (clean_co.next || clean_lock) mmix_wait(1); set_lock(self,clean_lock); clean_ctl.i=syncd; clean_ctl.state=4;