/*3:*/
#line 123 "mmix-pipe.w"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "abstime.h"
#define Extern
#define errprint0(f) fprintf(stderr,f)
#define errprint1(f,a) fprintf(stderr,f,a)
#define errprint2(f,a,b) fprintf(stderr,f,a,b)
#define panic(x) {errprint0("Panic: ") ;x;errprint0("!\n") ;expire() ;}
#define confusion(m) errprint1("This can't happen: %s",m) \
\
#define set_lock(c,l) {l= c;(c) ->lockloc= &(l) ;}
#define release_lock(c,l) {l= NULL;(c) ->lockloc= NULL;} \
#define P_BIT (1<<0)
#define S_BIT (1<<1)
#define B_BIT (1<<2)
#define K_BIT (1<<3)
#define N_BIT (1<<4)
#define PX_BIT (1<<5)
#define PW_BIT (1<<6)
#define PR_BIT (1<<7)
#define PROT_OFFSET 5
#define X_BIT (1<<8)
#define Z_BIT (1<<9)
#define U_BIT (1<<10)
#define O_BIT (1<<11)
#define I_BIT (1<<12)
#define W_BIT (1<<13)
#define V_BIT (1<<14)
#define D_BIT (1<<15)
#define H_BIT (1<<16)
#define F_BIT (1<<17)
#define E_BIT (1<<18) \
#define UNKNOWN_SPEC ((specnode*) 1) \
#define sign_bit ((unsigned) 0x80000000) \
#define X_is_dest_bit 0x20
#define rel_addr_bit 0x40
#define ctl_change_bit 0x80 \
#define VERSION 1
#define SUBVERSION 0
#define SUBSUBVERSION 0 \
#define wait(t) {schedule(self,t,data->state) ;goto done;}
#define pass_after(t) schedule(self+1,t,data->state)
#define sleep {self->next= self;goto done;}
#define awaken(c,t) schedule(c,t,c->ctl->state) \
#define shift_amt (data->z.o.h||data->z.o.l>=64?64:data->z.o.l) \
#define cache_addr(c,alf) c->set[(alf.l&~(c->tagmask) ) >>c->b] \
#define LDPTP PREGO
#define LDPTE GO \
#define trans_key(addr) incr(oandn(addr,page_mask) ,page_n) \
#define DUNNO ((octa*) 1) \
#define ld_st_launch 7 \
#define PRW_BITS (data->i<st?PR_BIT:data->i==pst?PR_BIT+PW_BIT: \
(data->i==syncid&&(data->loc.h&sign_bit) ) ?0:PW_BIT) \
#define DT_miss 10
#define DT_hit 11
#define hit_and_miss 12
#define ld_ready 13
#define st_ready 14
#define prest_win 15 \
#define max(x,y) ((x) <(y) ?(y) :(x) ) \
#define DT_retry 8
#define got_DT 9 \
#define wait_or_pass(t) if(data->i==prego) {pass_after(t) ;goto passit;} \
else wait(t) \
#define got_IT 19
#define IT_miss 20
#define IT_hit 21
#define Ihit_and_miss 22
#define fetch_ready 23
#define got_one 24 \
#define is_load_store(i) (i>=ld&&i<=cswap) \
#define RESUME_AGAIN 0
#define RESUME_CONT 1
#define RESUME_SET 2
#define RESUME_TRANS 3 \
#define pack_bytes(a,b,c,d) ((((((unsigned) (a) <<8) +(b) ) <<8) +(c) ) <<8) +(d) \
#define do_resume_trans 17 \
#define ROUND_OFF 1
#define ROUND_UP 2
#define ROUND_DOWN 3
#define ROUND_NEAR 4
#define is_denormal(x) ((x.h&0x7ff00000) ==0&&((x.h&0xfffff) ||x.l) )
#define is_trivial(x) ((x.h&0x7ff00000) ==0x7ff00000)
#define set_round cur_round= (data->ra.o.l<0x10000?ROUND_NEAR:data->ra.o.l>>16) \
#define max_sys_call Ftell \
#line 128 "mmix-pipe.w"
/*6:*/
#line 164 "mmix-pipe.w"
#ifdef __STDC__
#define ARGS(list) list
#else
#define ARGS(list) ()
#endif
/*:6*//*7:*/
#line 176 "mmix-pipe.w"
#define random my_random
#define fsqrt my_fsqrt
#define div my_div
/*:7*//*8:*/
#line 183 "mmix-pipe.w"
#define issue_bit (1<<0)
#define pipe_bit (1<<1)
#define coroutine_bit (1<<2)
#define schedule_bit (1<<3)
#define uninit_mem_bit (1<<4)
#define interactive_read_bit (1<<5)
#define show_spec_bit (1<<6)
#define show_pred_bit (1<<7)
#define show_wholecache_bit (1<<8)
/*:8*//*52:*/
#line 1114 "mmix-pipe.w"
#define rA 21
#define rB 0
#define rC 8
#define rD 1
#define rE 2
#define rF 22
#define rG 19
#define rH 3
#define rI 12
#define rJ 4
#define rK 15
#define rL 20
#define rM 5
#define rN 9
#define rO 10
#define rP 23
#define rQ 16
#define rR 6
#define rS 11
#define rT 13
#define rU 17
#define rV 18
#define rW 24
#define rX 25
#define rY 26
#define rZ 27
#define rBB 7
#define rTT 14
#define rWW 28
#define rXX 29
#define rYY 30
#define rZZ 31
/*:52*//*57:*/
#line 1195 "mmix-pipe.w"
#define POWER_FAILURE (1<<0)
#define PARITY_ERROR (1<<1)
#define NONEXISTENT_MEMORY (1<<2)
#define REBOOT_SIGNAL (1<<4)
#define INTERVAL_TIMEOUT (1<<7)
/*:57*//*87:*/
#line 1831 "mmix-pipe.w"
#define ticks g[rC].o
/*:87*//*129:*/
#line 2412 "mmix-pipe.w"
#define max_stage 99
#define vanish 98
#define flush_to_mem 97
#define flush_to_S 96
#define fill_from_mem 95
#define fill_from_S 94
#define fill_from_virt 93
#define write_from_wbuf 92
#define cleanup 91
/*:129*//*166:*/
#line 3116 "mmix-pipe.w"
#define WRITE_BACK 1
#define WRITE_ALLOC 2
/*:166*/
#line 129 "mmix-pipe.w"
/*11:*/
#line 243 "mmix-pipe.w"
typedef enum{false,true,wow}bool;
/*:11*//*17:*/
#line 315 "mmix-pipe.w"
typedef unsigned int tetra;
typedef struct{tetra h,l;}octa;
/*:17*//*23:*/
#line 433 "mmix-pipe.w"
typedef struct coroutine_struct{
char*name;
int stage;
struct coroutine_struct*next;
struct coroutine_struct**lockloc;
struct control_struct*ctl;
}coroutine;
/*:23*//*37:*/
#line 603 "mmix-pipe.w"
typedef coroutine*lockvar;
/*:37*//*40:*/
#line 646 "mmix-pipe.w"
typedef struct{
octa o;
struct specnode_struct*p;
}spec;
typedef struct specnode_struct{
octa o;
bool known;
octa addr;
struct specnode_struct*up,*down;
}specnode;
/*:40*//*44:*/
#line 728 "mmix-pipe.w"
/*47:*/
#line 798 "mmix-pipe.w"
typedef enum{
TRAP,FCMP,FUN,FEQL,FADD,FIX,FSUB,FIXU,
FLOT,FLOTI,FLOTU,FLOTUI,SFLOT,SFLOTI,SFLOTU,SFLOTUI,
FMUL,FCMPE,FUNE,FEQLE,FDIV,FSQRT,FREM,FINT,
MUL,MULI,MULU,MULUI,DIV,DIVI,DIVU,DIVUI,
ADD,ADDI,ADDU,ADDUI,SUB,SUBI,SUBU,SUBUI,
IIADDU,IIADDUI,IVADDU,IVADDUI,VIIIADDU,VIIIADDUI,XVIADDU,XVIADDUI,
CMP,CMPI,CMPU,CMPUI,NEG,NEGI,NEGU,NEGUI,
SL,SLI,SLU,SLUI,SR,SRI,SRU,SRUI,
BN,BNB,BZ,BZB,BP,BPB,BOD,BODB,
BNN,BNNB,BNZ,BNZB,BNP,BNPB,BEV,BEVB,
PBN,PBNB,PBZ,PBZB,PBP,PBPB,PBOD,PBODB,
PBNN,PBNNB,PBNZ,PBNZB,PBNP,PBNPB,PBEV,PBEVB,
CSN,CSNI,CSZ,CSZI,CSP,CSPI,CSOD,CSODI,
CSNN,CSNNI,CSNZ,CSNZI,CSNP,CSNPI,CSEV,CSEVI,
ZSN,ZSNI,ZSZ,ZSZI,ZSP,ZSPI,ZSOD,ZSODI,
ZSNN,ZSNNI,ZSNZ,ZSNZI,ZSNP,ZSNPI,ZSEV,ZSEVI,
LDB,LDBI,LDBU,LDBUI,LDW,LDWI,LDWU,LDWUI,
LDT,LDTI,LDTU,LDTUI,LDO,LDOI,LDOU,LDOUI,
LDSF,LDSFI,LDHT,LDHTI,CSWAP,CSWAPI,LDUNC,LDUNCI,
LDVTS,LDVTSI,PRELD,PRELDI,PREGO,PREGOI,GO,GOI,
STB,STBI,STBU,STBUI,STW,STWI,STWU,STWUI,
STT,STTI,STTU,STTUI,STO,STOI,STOU,STOUI,
STSF,STSFI,STHT,STHTI,STCO,STCOI,STUNC,STUNCI,
SYNCD,SYNCDI,PREST,PRESTI,SYNCID,SYNCIDI,PUSHGO,PUSHGOI,
OR,ORI,ORN,ORNI,NOR,NORI,XOR,XORI,
AND,ANDI,ANDN,ANDNI,NAND,NANDI,NXOR,NXORI,
BDIF,BDIFI,WDIF,WDIFI,TDIF,TDIFI,ODIF,ODIFI,
MUX,MUXI,SADD,SADDI,MOR,MORI,MXOR,MXORI,
SETH,SETMH,SETML,SETL,INCH,INCMH,INCML,INCL,
ORH,ORMH,ORML,ORL,ANDNH,ANDNMH,ANDNML,ANDNL,
JMP,JMPB,PUSHJ,PUSHJB,GETA,GETAB,PUT,PUTI,
POP,RESUME,SAVE,UNSAVE,SYNC,SWYM,GET,TRIP}mmix_opcode;
/*:47*//*49:*/
#line 877 "mmix-pipe.w"
#define max_pipe_op feps
#define max_real_command trip
typedef enum{
mul0,
mul1,
mul2,
mul3,
mul4,
mul5,
mul6,
mul7,
mul8,
div,
sh,
mux,
sadd,
mor,
fadd,
fmul,
fdiv,
fsqrt,
fint,
fix,
flot,
feps,
fcmp,
funeq,
fsub,
frem,
mul,
mulu,
divu,
add,
addu,
sub,
subu,
set,
or,
orn,
nor,
and,
andn,
nand,
xor,
nxor,
shlu,
shru,
shl,
shr,
cmp,
cmpu,
bdif,
wdif,
tdif,
odif,
zset,
cset,
get,
put,
ld,
ldptp,
ldpte,
ldunc,
ldvts,
preld,
prest,
st,
syncd,
syncid,
pst,
stunc,
cswap,
br,
pbr,
pushj,
go,
prego,
pushgo,
pop,
resume,
save,
unsave,
sync,
jmp,
noop,
trap,
trip,
incgamma,
decgamma,
incrl,
sav,
unsav,
resum
}internal_opcode;
/*:49*/
#line 729 "mmix-pipe.w"
typedef struct control_struct{
octa loc;
mmix_opcode op;unsigned char xx,yy,zz;
spec y,z,b,ra;
specnode x,a,go,rl;
coroutine*owner;
internal_opcode i;
int state;
bool usage;
bool need_b;
bool need_ra;
bool ren_x;
bool mem_x;
bool ren_a;
bool set_l;
bool interim;
unsigned int arith_exc;
unsigned int hist;
int denin,denout;
octa cur_O,cur_S;
unsigned int interrupt;
void*ptr_a,*ptr_b,*ptr_c;
}control;
/*:44*//*68:*/
#line 1495 "mmix-pipe.w"
typedef struct{
octa loc;
tetra inst;
unsigned int interrupt;
bool noted;
unsigned int hist;
}fetch;
/*:68*//*76:*/
#line 1631 "mmix-pipe.w"
typedef struct func_struct{
char name[16];
tetra ops[8];
int k;
coroutine*co;
}func;
/*:76*//*164:*/
#line 3083 "mmix-pipe.w"
typedef enum{random,serial,pseudo_lru,lru}replace_policy;
/*:164*//*167:*/
#line 3127 "mmix-pipe.w"
typedef struct{
octa tag;
char*dirty;
octa*data;
int rank;
}cacheblock;
typedef cacheblock*cacheset;
typedef struct{
int a,b,c,g,v;
int aa,bb,cc,gg,vv;
int tagmask;
replace_policy repl,vrepl;
int mode;
int access_time;
int copy_in_time;
int copy_out_time;
cacheset*set;
cacheset victim;
coroutine filler;
control filler_ctl;
coroutine flusher;
control flusher_ctl;
cacheblock inbuf;
cacheblock outbuf;
lockvar lock;
lockvar fill_lock;
int ports;
coroutine*reader;
char*name;
}cache;
/*:167*//*206:*/
#line 3647 "mmix-pipe.w"
typedef struct{
tetra tag;
octa*chunk;
}chunknode;
/*:206*//*246:*/
#line 4386 "mmix-pipe.w"
typedef struct{
octa o;
octa addr;
tetra stamp;
internal_opcode i;
}write_node;
/*:246*//*371:*/
#line 6455 "mmix-pipe.w"
typedef enum{
Halt,Fopen,Fclose,Fread,Fgets,Fgetws,
Fwrite,Fputs,Fputws,Fseek,Ftell}sys_call;
/*:371*/
#line 130 "mmix-pipe.w"
/*20:*/
#line 331 "mmix-pipe.w"
extern octa zero_octa;
extern octa neg_one;
extern octa aux;
extern bool overflow;
extern int exceptions;
extern int cur_round;
/*:20*//*36:*/
#line 583 "mmix-pipe.w"
coroutine sentinel;
/*:36*//*41:*/
#line 659 "mmix-pipe.w"
spec zero_spec;
/*:41*//*48:*/
#line 833 "mmix-pipe.w"
char*opcode_name[]= {
"TRAP","FCMP","FUN","FEQL","FADD","FIX","FSUB","FIXU",
"FLOT","FLOTI","FLOTU","FLOTUI","SFLOT","SFLOTI","SFLOTU","SFLOTUI",
"FMUL","FCMPE","FUNE","FEQLE","FDIV","FSQRT","FREM","FINT",
"MUL","MULI","MULU","MULUI","DIV","DIVI","DIVU","DIVUI",
"ADD","ADDI","ADDU","ADDUI","SUB","SUBI","SUBU","SUBUI",
"2ADDU","2ADDUI","4ADDU","4ADDUI","8ADDU","8ADDUI","16ADDU","16ADDUI",
"CMP","CMPI","CMPU","CMPUI","NEG","NEGI","NEGU","NEGUI",
"SL","SLI","SLU","SLUI","SR","SRI","SRU","SRUI",
"BN","BNB","BZ","BZB","BP","BPB","BOD","BODB",
"BNN","BNNB","BNZ","BNZB","BNP","BNPB","BEV","BEVB",
"PBN","PBNB","PBZ","PBZB","PBP","PBPB","PBOD","PBODB",
"PBNN","PBNNB","PBNZ","PBNZB","PBNP","PBNPB","PBEV","PBEVB",
"CSN","CSNI","CSZ","CSZI","CSP","CSPI","CSOD","CSODI",
"CSNN","CSNNI","CSNZ","CSNZI","CSNP","CSNPI","CSEV","CSEVI",
"ZSN","ZSNI","ZSZ","ZSZI","ZSP","ZSPI","ZSOD","ZSODI",
"ZSNN","ZSNNI","ZSNZ","ZSNZI","ZSNP","ZSNPI","ZSEV","ZSEVI",
"LDB","LDBI","LDBU","LDBUI","LDW","LDWI","LDWU","LDWUI",
"LDT","LDTI","LDTU","LDTUI","LDO","LDOI","LDOU","LDOUI",
"LDSF","LDSFI","LDHT","LDHTI","CSWAP","CSWAPI","LDUNC","LDUNCI",
"LDVTS","LDVTSI","PRELD","PRELDI","PREGO","PREGOI","GO","GOI",
"STB","STBI","STBU","STBUI","STW","STWI","STWU","STWUI",
"STT","STTI","STTU","STTUI","STO","STOI","STOU","STOUI",
"STSF","STSFI","STHT","STHTI","STCO","STCOI","STUNC","STUNCI",
"SYNCD","SYNCDI","PREST","PRESTI","SYNCID","SYNCIDI","PUSHGO","PUSHGOI",
"OR","ORI","ORN","ORNI","NOR","NORI","XOR","XORI",
"AND","ANDI","ANDN","ANDNI","NAND","NANDI","NXOR","NXORI",
"BDIF","BDIFI","WDIF","WDIFI","TDIF","TDIFI","ODIF","ODIFI",
"MUX","MUXI","SADD","SADDI","MOR","MORI","MXOR","MXORI",
"SETH","SETMH","SETML","SETL","INCH","INCMH","INCML","INCL",
"ORH","ORMH","ORML","ORL","ANDNH","ANDNMH","ANDNML","ANDNL",
"JMP","JMPB","PUSHJ","PUSHJB","GETA","GETAB","PUT","PUTI",
"POP","RESUME","SAVE","UNSAVE","SYNC","SWYM","GET","TRIP"};
/*:48*//*50:*/
#line 974 "mmix-pipe.w"
char*internal_op_name[]= {
"mul0",
"mul1",
"mul2",
"mul3",
"mul4",
"mul5",
"mul6",
"mul7",
"mul8",
"div",
"sh",
"mux",
"sadd",
"mor",
"fadd",
"fmul",
"fdiv",
"fsqrt",
"fint",
"fix",
"flot",
"feps",
"fcmp",
"funeq",
"fsub",
"frem",
"mul",
"mulu",
"divu",
"add",
"addu",
"sub",
"subu",
"set",
"or",
"orn",
"nor",
"and",
"andn",
"nand",
"xor",
"nxor",
"shlu",
"shru",
"shl",
"shr",
"cmp",
"cmpu",
"bdif",
"wdif",
"tdif",
"odif",
"zset",
"cset",
"get",
"put",
"ld",
"ldptp",
"ldpte",
"ldunc",
"ldvts",
"preld",
"prest",
"st",
"syncd",
"syncid",
"pst",
"stunc",
"cswap",
"br",
"pbr",
"pushj",
"go",
"prego",
"pushgo",
"pop",
"resume",
"save",
"unsave",
"sync",
"jmp",
"noop",
"trap",
"trip",
"incgamma",
"decgamma",
"incrl",
"sav",
"unsav",
"resum"};
/*:50*//*51:*/
#line 1070 "mmix-pipe.w"
internal_opcode internal_op[256]= {
trap,fcmp,funeq,funeq,fadd,fix,fsub,fix,
flot,flot,flot,flot,flot,flot,flot,flot,
fmul,feps,feps,feps,fdiv,fsqrt,frem,fint,
mul,mul,mulu,mulu,div,div,divu,divu,
add,add,addu,addu,sub,sub,subu,subu,
addu,addu,addu,addu,addu,addu,addu,addu,
cmp,cmp,cmpu,cmpu,sub,sub,subu,subu,
shl,shl,shlu,shlu,shr,shr,shru,shru,
br,br,br,br,br,br,br,br,
br,br,br,br,br,br,br,br,
pbr,pbr,pbr,pbr,pbr,pbr,pbr,pbr,
pbr,pbr,pbr,pbr,pbr,pbr,pbr,pbr,
cset,cset,cset,cset,cset,cset,cset,cset,
cset,cset,cset,cset,cset,cset,cset,cset,
zset,zset,zset,zset,zset,zset,zset,zset,
zset,zset,zset,zset,zset,zset,zset,zset,
ld,ld,ld,ld,ld,ld,ld,ld,
ld,ld,ld,ld,ld,ld,ld,ld,
ld,ld,ld,ld,cswap,cswap,ldunc,ldunc,
ldvts,ldvts,preld,preld,prego,prego,go,go,
pst,pst,pst,pst,pst,pst,pst,pst,
pst,pst,pst,pst,st,st,st,st,
pst,pst,pst,pst,st,st,st,st,
syncd,syncd,prest,prest,syncid,syncid,pushgo,pushgo,
or,or,orn,orn,nor,nor,xor,xor,
and,and,andn,andn,nand,nand,nxor,nxor,
bdif,bdif,wdif,wdif,tdif,tdif,odif,odif,
mux,mux,sadd,sadd,mor,mor,mor,mor,
set,set,set,set,addu,addu,addu,addu,
or,or,or,or,andn,andn,andn,andn,
jmp,jmp,pushj,pushj,set,set,put,put,
pop,resume,save,unsave,sync,noop,get,trip};
/*:51*//*53:*/
#line 1148 "mmix-pipe.w"
char*special_name[32]= {"rB","rD","rE","rH","rJ","rM","rR","rBB",
"rC","rN","rO","rS","rI","rT","rTT","rK","rQ","rU","rV","rG","rL",
"rA","rF","rP","rW","rX","rY","rZ","rWW","rXX","rYY","rZZ"};
/*:53*//*54:*/
#line 1177 "mmix-pipe.w"
char bit_code_map[]= "EFHDVWIOUZXrwxnkbsp";
/*:54*//*65:*/
#line 1445 "mmix-pipe.w"
int dispatch_count;
bool suppress_dispatch;
int doing_interrupt;
lockvar dispatch_lock;
/*:65*//*70:*/
#line 1519 "mmix-pipe.w"
fetch*old_tail;
/*:70*//*78:*/
#line 1647 "mmix-pipe.w"
control*new_cool;
int resuming;
tetra support[8];
/*:78*//*83:*/
#line 1725 "mmix-pipe.w"
unsigned char flags[256]= {
0x8a,0x2a,0x2a,0x2a,0x2a,0x26,0x2a,0x26,
0x26,0x25,0x26,0x25,0x26,0x25,0x26,0x25,
0x2a,0x2a,0x2a,0x2a,0x2a,0x26,0x2a,0x26,
0x2a,0x29,0x2a,0x29,0x2a,0x29,0x2a,0x29,
0x2a,0x29,0x2a,0x29,0x2a,0x29,0x2a,0x29,
0x2a,0x29,0x2a,0x29,0x2a,0x29,0x2a,0x29,
0x2a,0x29,0x2a,0x29,0x26,0x25,0x26,0x25,
0x2a,0x29,0x2a,0x29,0x2a,0x29,0x2a,0x29,
0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,
0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,
0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,
0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,
0x3a,0x39,0x3a,0x39,0x3a,0x39,0x3a,0x39,
0x3a,0x39,0x3a,0x39,0x3a,0x39,0x3a,0x39,
0x2a,0x29,0x2a,0x29,0x2a,0x29,0x2a,0x29,
0x2a,0x29,0x2a,0x29,0x2a,0x29,0x2a,0x29,
0x2a,0x29,0x2a,0x29,0x2a,0x29,0x2a,0x29,
0x2a,0x29,0x2a,0x29,0x2a,0x29,0x2a,0x29,
0x2a,0x29,0x2a,0x29,0x1a,0x19,0x2a,0x29,
0x2a,0x29,0x0a,0x09,0x0a,0x09,0xaa,0xa9,
0x1a,0x19,0x1a,0x19,0x1a,0x19,0x1a,0x19,
0x1a,0x19,0x1a,0x19,0x1a,0x19,0x1a,0x19,
0x1a,0x19,0x1a,0x19,0x0a,0x09,0x1a,0x19,
0x0a,0x09,0x0a,0x09,0x0a,0x09,0xaa,0xa9,
0x2a,0x29,0x2a,0x29,0x2a,0x29,0x2a,0x29,
0x2a,0x29,0x2a,0x29,0x2a,0x29,0x2a,0x29,
0x2a,0x29,0x2a,0x29,0x2a,0x29,0x2a,0x29,
0x2a,0x29,0x2a,0x29,0x2a,0x29,0x2a,0x29,
0x20,0x20,0x20,0x20,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0xc0,0xc0,0xe0,0xe0,0x60,0x60,0x02,0x01,
0x80,0x80,0x00,0x02,0x01,0x00,0x20,0x8a};
/*:83*//*88:*/
#line 1834 "mmix-pipe.w"
int lring_mask;
/*:88*//*99:*/
#line 1952 "mmix-pipe.w"
int cool_L,cool_G;
unsigned int cool_hist,peek_hist;
octa new_O,new_S;
/*:99*//*107:*/
#line 2039 "mmix-pipe.w"
unsigned char third_operand[256]= {
0,rA,0,0,rA,rA,rA,rA,
rA,rA,rA,rA,rA,rA,rA,rA,
rA,rE,rE,rE,rA,rA,rA,rA,
rA,rA,0,0,rA,rA,rD,rD,
rA,rA,0,0,rA,rA,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,rA,rA,0,0,
rA,rA,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
rA,rA,0,0,rA,rA,0,0,
rA,rA,0,0,0,0,0,0,
rA,rA,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
rM,rM,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
rJ,0,0,0,0,0,0,255};
/*:107*//*127:*/
#line 2391 "mmix-pipe.w"
coroutine mem_locker;
coroutine Dlocker;
control vanish_ctl;
/*:127*//*148:*/
#line 2746 "mmix-pipe.w"
octa new_Q;
/*:148*//*154:*/
#line 2884 "mmix-pipe.w"
int bp_amask,bp_cmask,bp_bcmask,bp_nmask,bp_npower;
int bp_rev_stat,bp_ok_stat;
int bp_bad_stat,bp_good_stat;
/*:154*//*194:*/
#line 3458 "mmix-pipe.w"
cacheset hit_set;
/*:194*//*230:*/
#line 4064 "mmix-pipe.w"
coroutine clean_co;
control clean_ctl;
lockvar clean_lock;
/*:230*//*235:*/
#line 4211 "mmix-pipe.w"
control IPTctl[5],DPTctl[5];
coroutine IPTco[10],DPTco[10];
char*IPTname[5]= {"IPT0","IPT1","IPT2","IPT3","IPT4"};
char*DPTname[5]= {"DPT0","DPT1","DPT2","DPT3","DPT4"};
/*:235*//*238:*/
#line 4272 "mmix-pipe.w"
int page_n;
int page_r;
int page_s;
int page_b[5];
octa page_mask;
bool page_bad= true;
/*:238*//*248:*/
#line 4410 "mmix-pipe.w"
coroutine write_co;
control write_ctl;
/*:248*//*285:*/
#line 5114 "mmix-pipe.w"
int fetch_lo,fetch_hi;
coroutine fetch_co;
control fetch_ctl;
/*:285*//*303:*/
#line 5335 "mmix-pipe.w"
bool sleepy;
/*:303*//*305:*/
#line 5359 "mmix-pipe.w"
int bad_inst_mask[4]= {0xfffffe,0xffff,0xffff00,0xfffff8};
/*:305*//*315:*/
#line 5514 "mmix-pipe.w"
bool trying_to_interrupt;
bool nullifying;
/*:315*//*374:*/
#line 6493 "mmix-pipe.w"
char arg_count[]= {1,3,1,3,3,3,3,2,2,2,1};
/*:374*//*376:*/
#line 6501 "mmix-pipe.w"
extern octa mmix_fopen ARGS((unsigned char,octa,octa));
extern octa mmix_fclose ARGS((unsigned char));
extern octa mmix_fread ARGS((unsigned char,octa,octa));
extern octa mmix_fgets ARGS((unsigned char,octa,octa));
extern octa mmix_fgetws ARGS((unsigned char,octa,octa));
extern octa mmix_fwrite ARGS((unsigned char,octa,octa));
extern octa mmix_fputs ARGS((unsigned char,octa));
extern octa mmix_fputws ARGS((unsigned char,octa));
extern octa mmix_fseek ARGS((unsigned char,octa));
extern octa mmix_ftell ARGS((unsigned char));
extern void print_trip_warning ARGS((int,octa));
/*:376*//*388:*/
#line 6739 "mmix-pipe.w"
char stdin_buf[256];
char*stdin_buf_start;
char*stdin_buf_end;
/*:388*/
#line 131 "mmix-pipe.w"
/*4:*/
#line 146 "mmix-pipe.w"
Extern int verbose;
/*:4*//*29:*/
#line 512 "mmix-pipe.w"
Extern int ring_size;
Extern coroutine*ring;
Extern int cur_time;
/*:29*//*59:*/
#line 1366 "mmix-pipe.w"
Extern int fetch_max,dispatch_max,peekahead,commit_max;
/*:59*//*60:*/
#line 1392 "mmix-pipe.w"
Extern control*reorder_bot,*reorder_top;
Extern control*hot,*cool;
Extern control*old_hot;
Extern int deissues;
/*:60*//*66:*/
#line 1451 "mmix-pipe.w"
Extern int*dispatch_stat;
Extern bool security_disabled;
/*:66*//*69:*/
#line 1514 "mmix-pipe.w"
Extern fetch*fetch_bot,*fetch_top;
Extern fetch*head,*tail;
/*:69*//*77:*/
#line 1639 "mmix-pipe.w"
Extern func*funit;
Extern int funit_count;
/*:77*//*86:*/
#line 1823 "mmix-pipe.w"
Extern specnode g[256];
Extern specnode*l;
Extern int lring_size;
Extern int max_rename_regs,max_mem_slots;
Extern int rename_regs,mem_slots;
/*:86*//*98:*/
#line 1949 "mmix-pipe.w"
Extern octa cool_O,cool_S;
/*:98*//*115:*/
#line 2175 "mmix-pipe.w"
Extern specnode mem;
/*:115*//*136:*/
#line 2541 "mmix-pipe.w"
#define pipe_limit 90
Extern unsigned char pipe_seq[max_pipe_op+1][pipe_limit+1];
/*:136*//*150:*/
#line 2824 "mmix-pipe.w"
Extern int bp_a,bp_b,bp_c,bp_n;
Extern char*bp_table;
/*:150*//*168:*/
#line 3165 "mmix-pipe.w"
Extern cache*Icache,*Dcache,*Scache,*ITcache,*DTcache;
/*:168*//*207:*/
#line 3659 "mmix-pipe.w"
Extern int mem_chunks;
Extern int mem_chunks_max;
Extern int hash_prime;
Extern chunknode*mem_hash;
/*:207*//*211:*/
#line 3709 "mmix-pipe.w"
Extern int last_h;
/*:211*//*214:*/
#line 3752 "mmix-pipe.w"
Extern int mem_addr_time;
Extern int bus_words;
Extern int mem_read_time;
Extern int mem_write_time;
Extern lockvar mem_lock;
/*:214*//*242:*/
#line 4320 "mmix-pipe.w"
Extern bool no_hardware_PT;
/*:242*//*247:*/
#line 4401 "mmix-pipe.w"
Extern write_node*wbuf_bot,*wbuf_top;
Extern write_node*write_head,*write_tail;
Extern lockvar wbuf_lock;
Extern int holding_time;
Extern lockvar speed_lock;
/*:247*//*284:*/
#line 5104 "mmix-pipe.w"
Extern spec inst_ptr;
Extern octa*fetched;
/*:284*//*349:*/
#line 6116 "mmix-pipe.w"
Extern int frem_max;
Extern int denin_penalty,denout_penalty;
/*:349*/
#line 132 "mmix-pipe.w"
/*13:*/
#line 262 "mmix-pipe.w"
static void expire ARGS((void));
/*:13*//*18:*/
#line 320 "mmix-pipe.w"
static void print_octa ARGS((octa));
/*:18*//*24:*/
#line 442 "mmix-pipe.w"
static void print_coroutine_id ARGS((coroutine*));
static void errprint_coroutine_id ARGS((coroutine*));
/*:24*//*27:*/
#line 490 "mmix-pipe.w"
static void schedule ARGS((coroutine*,int,int));
/*:27*//*30:*/
#line 523 "mmix-pipe.w"
static void startup ARGS((coroutine*,int));
/*:30*//*32:*/
#line 543 "mmix-pipe.w"
static void unschedule ARGS((coroutine*));
/*:32*//*34:*/
#line 566 "mmix-pipe.w"
static coroutine*queuelist ARGS((int));
/*:34*//*42:*/
#line 662 "mmix-pipe.w"
static void print_spec ARGS((spec));
/*:42*//*45:*/
#line 754 "mmix-pipe.w"
static void print_control_block ARGS((control*));
/*:45*//*55:*/
#line 1180 "mmix-pipe.w"
static void print_bits ARGS((int));
/*:55*//*62:*/
#line 1403 "mmix-pipe.w"
static void print_reorder_buffer ARGS((void));
/*:62*//*72:*/
#line 1528 "mmix-pipe.w"
static void print_fetch_buffer ARGS((void));
/*:72*//*90:*/
#line 1872 "mmix-pipe.w"
static void print_specnode_id ARGS((octa));
/*:90*//*92:*/
#line 1891 "mmix-pipe.w"
static spec specval ARGS((specnode*));
/*:92*//*94:*/
#line 1906 "mmix-pipe.w"
static void spec_install ARGS((specnode*,specnode*));
/*:94*//*96:*/
#line 1922 "mmix-pipe.w"
static void spec_rem ARGS((specnode*));
/*:96*//*156:*/
#line 2908 "mmix-pipe.w"
static int register_truth ARGS((octa,mmix_opcode));
/*:156*//*158:*/
#line 2930 "mmix-pipe.w"
static int issued_between ARGS((control*,control*));
/*:158*//*169:*/
#line 3171 "mmix-pipe.w"
static bool is_dirty ARGS((cache*,cacheblock*));
/*:169*//*171:*/
#line 3187 "mmix-pipe.w"
static void print_cache_block ARGS((cacheblock,cache*));
/*:171*//*173:*/
#line 3201 "mmix-pipe.w"
static void print_cache_locks ARGS((cache*));
/*:173*//*182:*/
#line 3305 "mmix-pipe.w"
static int get_reader ARGS((cache*));
/*:182*//*184:*/
#line 3323 "mmix-pipe.w"
static void copy_block ARGS((cache*,cacheblock*,cache*,cacheblock*));
/*:184*//*186:*/
#line 3349 "mmix-pipe.w"
static cacheblock*choose_victim ARGS((cacheset,int,replace_policy));
/*:186*//*188:*/
#line 3374 "mmix-pipe.w"
static void note_usage ARGS((cacheblock*,cacheset,int,replace_policy));
/*:188*//*190:*/
#line 3403 "mmix-pipe.w"
static void demote_usage ARGS((cacheblock*,cacheset,int,replace_policy));
/*:190*//*192:*/
#line 3437 "mmix-pipe.w"
static cacheblock*cache_search ARGS((cache*,octa));
/*:192*//*195:*/
#line 3467 "mmix-pipe.w"
static cacheblock*use_and_fix ARGS((cache*,cacheblock*));
/*:195*//*198:*/
#line 3505 "mmix-pipe.w"
static cacheblock*demote_and_fix ARGS((cache*,cacheblock*));
/*:198*//*200:*/
#line 3522 "mmix-pipe.w"
static void load_cache ARGS((cache*,cacheblock*));
/*:200*//*202:*/
#line 3546 "mmix-pipe.w"
static void flush_cache ARGS((cache*,cacheblock*,bool));
/*:202*//*204:*/
#line 3591 "mmix-pipe.w"
static cacheblock*alloc_slot ARGS((cache*,octa));
/*:204*//*240:*/
#line 4304 "mmix-pipe.w"
static octa phys_addr ARGS((octa,octa));
/*:240*//*250:*/
#line 4423 "mmix-pipe.w"
static void print_write_buffer ARGS((void));
/*:250*//*254:*/
#line 4476 "mmix-pipe.w"
static octa*write_search ARGS((control*,octa));
/*:254*//*377:*/
#line 6514 "mmix-pipe.w"
int mmgetchars ARGS((char*,int,octa,int));
void mmputchars ARGS((unsigned char*,int,octa));
char stdin_chr ARGS((void));
octa magic_read ARGS((octa));
void magic_write ARGS((octa,octa));
/*:377*/
#line 133 "mmix-pipe.w"
/*9:*/
#line 209 "mmix-pipe.w"
Extern void MMIX_init ARGS((void));
Extern void MMIX_run ARGS((int cycs,octa breakpoint));
/*:9*//*38:*/
#line 606 "mmix-pipe.w"
Extern void print_locks ARGS((void));
/*:38*//*161:*/
#line 2975 "mmix-pipe.w"
Extern void print_stats ARGS((void));
/*:161*//*175:*/
#line 3221 "mmix-pipe.w"
Extern void print_cache ARGS((cache*,bool));
/*:175*//*178:*/
#line 3265 "mmix-pipe.w"
Extern void clean_block ARGS((cache*,cacheblock*));
/*:178*//*180:*/
#line 3282 "mmix-pipe.w"
Extern void zap_cache ARGS((cache*));
/*:180*//*209:*/
#line 3684 "mmix-pipe.w"
Extern octa mem_read ARGS((octa addr));
/*:209*//*212:*/
#line 3712 "mmix-pipe.w"
Extern void mem_write ARGS((octa addr,octa val));
/*:212*//*252:*/
#line 4447 "mmix-pipe.w"
Extern void print_pipe ARGS((void));
/*:252*/
#line 134 "mmix-pipe.w"
/*14:*/
#line 265 "mmix-pipe.w"
static void expire()
{
if(ticks.h)errprint2("(Clock time is %dH+%d.)\n",ticks.h,ticks.l);
else errprint1("(Clock time is %d.)\n",ticks.l);
exit(-2);
}
/*:14*//*19:*/
#line 323 "mmix-pipe.w"
static void print_octa(o)
octa o;
{
if(o.h)printf("%x%08x",o.h,o.l);
else printf("%x",o.l);
}
/*:19*//*21:*/
#line 345 "mmix-pipe.w"
extern octa oplus ARGS((octa y,octa z));
extern octa ominus ARGS((octa y,octa z));
extern octa incr ARGS((octa y,int delta));
extern octa oand ARGS((octa y,octa z));
extern octa oandn ARGS((octa y,octa z));
extern octa shift_left ARGS((octa y,int s));
extern octa shift_right ARGS((octa y,int s,int uns));
extern octa omult ARGS((octa y,octa z));
extern octa signed_omult ARGS((octa y,octa z));
extern octa odiv ARGS((octa x,octa y,octa z));
extern octa signed_odiv ARGS((octa y,octa z));
extern int count_bits ARGS((tetra z));
extern tetra byte_diff ARGS((tetra y,tetra z));
extern tetra wyde_diff ARGS((tetra y,tetra z));
extern octa bool_mult ARGS((octa y,octa z,bool xor));
extern octa load_sf ARGS((tetra z));
extern tetra store_sf ARGS((octa x));
extern octa fplus ARGS((octa y,octa z));
extern octa fmult ARGS((octa y,octa z));
extern octa fdivide ARGS((octa y,octa z));
extern octa froot ARGS((octa,int));
extern octa fremstep ARGS((octa y,octa z,int delta));
extern octa fintegerize ARGS((octa z,int mode));
extern int fcomp ARGS((octa y,octa z));
extern int fepscomp ARGS((octa y,octa z,octa eps,int sim));
extern octa floatit ARGS((octa z,int mode,int unsgnd,int shrt));
extern octa fixit ARGS((octa z,int mode));
/*:21*//*25:*/
#line 446 "mmix-pipe.w"
static void print_coroutine_id(c)
coroutine*c;
{
if(c)printf("%s:%d",c->name,c->stage);
else printf("??");
}
static void errprint_coroutine_id(c)
coroutine*c;
{
if(c)errprint2("%s:%d",c->name,c->stage);
else errprint0("??");
}
/*:25*//*28:*/
#line 493 "mmix-pipe.w"
static void schedule(c,d,s)
coroutine*c;
int d,s;
{
register int tt= (cur_time+d)%ring_size;
register coroutine*p= &ring[tt];
if(d<=0||d>=ring_size)
panic(confusion("Scheduling ");errprint_coroutine_id(c);
errprint1(" with delay %d",d));
while(p->next->stage<c->stage)p= p->next;
c->next= p->next;
p->next= c;
if(verbose&schedule_bit){
printf(" scheduling ");print_coroutine_id(c);
printf(" at time %d, state %d\n",ticks.l+d,s);
}
}
/*:28*//*31:*/
#line 526 "mmix-pipe.w"
static void startup(c,d)
coroutine*c;
int d;
{
c->ctl->state= 0;
schedule(c,d,0);
}
/*:31*//*33:*/
#line 546 "mmix-pipe.w"
static void unschedule(c)
coroutine*c;
{register coroutine*p;
if(c->next){
for(p= c;p->next!=c;p= p->next);
p->next= c->next;
c->next= NULL;
if(verbose&schedule_bit){
printf(" unscheduling ");print_coroutine_id(c);printf("\n");
}
}
}
/*:33*//*35:*/
#line 569 "mmix-pipe.w"
static coroutine*queuelist(t)
int t;
{register coroutine*p,*q= &sentinel,*r;
for(p= ring[t].next;p!=&ring[t];p= r){
r= p->next;
p->next= q;
q= p;
}
ring[t].next= &ring[t];
sentinel.next= q;
return q;
}
/*:35*//*43:*/
#line 665 "mmix-pipe.w"
static void print_spec(s)
spec s;
{
if(!s.p)print_octa(s.o);
else{
printf(">");print_specnode_id(s.p->addr);
}
}
static void print_specnode(s)
specnode s;
{
if(s.known){print_octa(s.o);printf("!");}
else if(s.o.h||s.o.l){print_octa(s.o);printf("?");}
else printf("?");
print_specnode_id(s.addr);
}
/*:43*//*46:*/
#line 757 "mmix-pipe.w"
static void print_control_block(c)
control*c;
{
octa default_go;
if(c->loc.h||c->loc.l||c->op||c->xx||c->yy||c->zz||c->owner){
print_octa(c->loc);
printf(": %02x%02x%02x%02x(%s)",c->op,c->xx,c->yy,c->zz,
internal_op_name[c->i]);
}
if(c->usage)printf("*");
if(c->interim)printf("+");
if(c->y.o.h||c->y.o.l||c->y.p){printf(" y=");print_spec(c->y);}
if(c->z.o.h||c->z.o.l||c->z.p){printf(" z=");print_spec(c->z);}
if(c->b.o.h||c->b.o.l||c->b.p||c->need_b){
printf(" b=");print_spec(c->b);
if(c->need_b)printf("*");
}
if(c->need_ra){printf(" rA=");print_spec(c->ra);}
if(c->ren_x||c->mem_x){printf(" x=");print_specnode(c->x);}
else if(c->x.o.h||c->x.o.l){
printf(" x=");print_octa(c->x.o);printf("%c",c->x.known?'!':'?');
}
if(c->ren_a){printf(" a=");print_specnode(c->a);}
if(c->set_l){printf(" rL=");print_specnode(c->rl);}
if(c->interrupt){printf(" int=");print_bits(c->interrupt);}
if(c->arith_exc){printf(" exc=");print_bits(c->arith_exc<<8);}
default_go= incr(c->loc,4);
if(c->go.o.l!=default_go.l||c->go.o.h!=default_go.h){
printf(" ->");print_octa(c->go.o);
}
if(verbose&show_pred_bit)printf(" hist=%x",c->hist);
if(c->i==pop){
printf(" rS=");print_octa(c->cur_S);
printf(" rO=");print_octa(c->cur_O);
}
printf(" state=%d",c->state);
}
/*:46*//*56:*/
#line 1183 "mmix-pipe.w"
static void print_bits(x)
int x;
{
register int b,j;
for(j= 0,b= E_BIT;(x&(b+b-1))&&b;j++,b>>= 1)
if(x&b)printf("%c",bit_code_map[j]);
}
/*:56*//*63:*/
#line 1406 "mmix-pipe.w"
static void print_reorder_buffer()
{
printf("Reorder buffer");
if(hot==cool)printf(" (empty)\n");
else{register control*p;
if(deissues)printf(" (%d to be deissued)",deissues);
if(doing_interrupt)printf(" (interrupt state %d)",doing_interrupt);
printf(":\n");
for(p= hot;p!=cool;p= (p==reorder_bot?reorder_top:p-1)){
print_control_block(p);
if(p->owner){
printf(" ");print_coroutine_id(p->owner);
}
printf("\n");
}
}
printf(" %d available rename register%s, %d memory slot%s\n",
rename_regs,rename_regs!=1?"s":"",
mem_slots,mem_slots!=1?"s":"");
}
/*:63*//*73:*/
#line 1531 "mmix-pipe.w"
static void print_fetch_buffer()
{
printf("Fetch buffer");
if(head==tail)printf(" (empty)\n");
else{register fetch*p;
if(resuming)printf(" (resumption state %d)",resuming);
printf(":\n");
for(p= head;p!=tail;p= (p==fetch_bot?fetch_top:p-1)){
print_octa(p->loc);
printf(": %08x(%s)",p->inst,opcode_name[p->inst>>24]);
if(p->interrupt)print_bits(p->interrupt);
if(p->noted)printf("*");
printf("\n");
}
}
printf("Instruction pointer is ");
if(inst_ptr.p==NULL)print_octa(inst_ptr.o);
else{
printf("waiting for ");
if(inst_ptr.p==UNKNOWN_SPEC)printf("dispatch");
else if(inst_ptr.p->addr.h==(tetra)-1)
print_coroutine_id(((control*)inst_ptr.p->up)->owner);
else print_specnode_id(inst_ptr.p->addr);
}
printf("\n");
}
/*:73*//*91:*/
#line 1875 "mmix-pipe.w"
static void print_specnode_id(a)
octa a;
{
if(a.h==sign_bit){
if(a.l<32)printf(special_name[a.l]);
else if(a.l<256)printf("g[%d]",a.l);
else printf("l[%d]",a.l-256);
}else if(a.h!=(tetra)-1){
printf("m[");print_octa(a);printf("]");
}
}
/*:91*//*93:*/
#line 1894 "mmix-pipe.w"
static spec specval(r)
specnode*r;
{spec res;
if(r->up->known)res.o= r->up->o,res.p= NULL;
else res.p= r->up;
return res;
}
/*:93*//*95:*/
#line 1909 "mmix-pipe.w"
static void spec_install(r,t)
specnode*r,*t;
{
t->up= r->up;
t->up->down= t;
r->up= t;
t->down= r;
t->addr= r->addr;
}
/*:95*//*97:*/
#line 1925 "mmix-pipe.w"
static void spec_rem(t)
specnode*t;
{register specnode*u= t->up,*d= t->down;
u->down= d;d->up= u;
}
/*:97*//*157:*/
#line 2911 "mmix-pipe.w"
static int register_truth(o,op)
octa o;
mmix_opcode op;
{register int b;
switch((op>>1)&0x3){
case 0:b= o.h>>31;break;
case 1:b= (o.h==0&&o.l==0);break;
case 2:b= (o.h<sign_bit&&(o.h||o.l));break;
case 3:b= o.l&0x1;break;
}
if(op&0x8)return b^1;
else return b;
}
/*:157*//*159:*/
#line 2933 "mmix-pipe.w"
static int issued_between(c,cc)
control*c,*cc;
{
if(c> cc)return c-1-cc;
return(c-reorder_bot)+(reorder_top-cc);
}
/*:159*//*170:*/
#line 3174 "mmix-pipe.w"
static bool is_dirty(c,p)
cache*c;
cacheblock*p;
{
register int j;
register char*d= p->dirty;
for(j= 0;j<c->bb;d++,j+= c->gg)if(*d)return true;
return false;
}
/*:170*//*172:*/
#line 3190 "mmix-pipe.w"
static void print_cache_block(p,c)
cacheblock p;
cache*c;
{register int i,j,b= c->bb>>3,g= c->gg>>3;
printf("%08x%08x: ",p.tag.h,p.tag.l);
for(i= j= 0;j<b;j++,i+= ((j&(g-1))?0:1))
printf("%08x%08x%c",p.data[j].h,p.data[j].l,p.dirty[i]?'*':' ');
printf(" (%d)\n",p.rank);
}
/*:172*//*174:*/
#line 3204 "mmix-pipe.w"
static void print_cache_locks(c)
cache*c;
{
if(c){
if(c->lock)printf("%s locked by %s:%d\n",
c->name,c->lock->name,c->lock->stage);
if(c->fill_lock)printf("%sfill locked by %s:%d\n",
c->name,c->fill_lock->name,c->fill_lock->stage);
}
}
/*:174*//*183:*/
#line 3308 "mmix-pipe.w"
static int get_reader(c)
cache*c;
{register int j;
for(j= 0;j<c->ports;j++)
if(c->reader[j].next==NULL)return j;
return-1;
}
/*:183*//*185:*/
#line 3326 "mmix-pipe.w"
static void copy_block(c,p,cc,pp)
cache*c,*cc;
cacheblock*p,*pp;
{
register int j,jj,i,ii,lim;register int off= p->tag.l&(cc->bb-1);
if(c->g!=cc->g||p->tag.h!=pp->tag.h||p->tag.l-off!=pp->tag.l)
panic(confusion("copy block"));
for(j= 0,jj= off>>c->g;j<c->bb>>c->g;j++,jj++)if(p->dirty[j]){
pp->dirty[jj]= true;
for(i= j<<(c->g-3),ii= jj<<(c->g-3),lim= (j+1)<<(c->g-3);
i<lim;i++,ii++)pp->data[ii]= p->data[i];
}
}
/*:185*//*187:*/
#line 3352 "mmix-pipe.w"
static cacheblock*choose_victim(s,aa,policy)
cacheset s;
int aa;
replace_policy policy;
{
register cacheblock*p;
register int l,m;
switch(policy){
case random:return&s[ticks.l&(aa-1)];
case serial:l= s[0].rank;s[0].rank= (l+1)&(aa-1);return&s[l];
case lru:for(p= s;p<s+aa;p++)
if(p->rank==0)return p;
panic(confusion("lru victim"));
case pseudo_lru:for(l= 1,m= aa>>1;m;m>>= 1)l= l+l+s[l].rank;
return&s[l-aa];
}
}
/*:187*//*189:*/
#line 3377 "mmix-pipe.w"
static void note_usage(l,s,aa,policy)
cacheblock*l;
cacheset s;
int aa;
replace_policy policy;
{
register cacheblock*p;
register int j,m,r;
if(aa==1||policy<=serial)return;
if(policy==lru){
r= l->rank;
for(p= s;p<s+aa;p++)if(p->rank> r)p->rank--;
l->rank= aa-1;
}else{
r= l-s;
for(j= 1,m= aa>>1;m;m>>= 1)
if(r&m)s[j].rank= 0,j= j+j+1;
else s[j].rank= 1,j= j+j;
}
return;
}
/*:189*//*191:*/
#line 3406 "mmix-pipe.w"
static void demote_usage(l,s,aa,policy)
cacheblock*l;
cacheset s;
int aa;
replace_policy policy;
{
register cacheblock*p;
register int j,m,r;
if(aa==1||policy<=serial)return;
if(policy==lru){
r= l->rank;
for(p= s;p<s+aa;p++)if(p->rank<r)p->rank++;
l->rank= 0;
}else{
r= l-s;
for(j= 1,m= aa>>1;m;m>>= 1)
if(r&m)s[j].rank= 1,j= j+j+1;
else s[j].rank= 0,j= j+j;
}
return;
}
/*:191*//*193:*/
#line 3440 "mmix-pipe.w"
static cacheblock*cache_search(c,alf)
cache*c;
octa alf;
{
register cacheset s;
register cacheblock*p;
s= cache_addr(c,alf);
for(p= s;p<s+c->aa;p++)
if(((p->tag.l^alf.l)&c->tagmask)==0&&p->tag.h==alf.h)goto hit;
s= c->victim;
if(!s)return NULL;
for(p= s;p<s+c->vv;p++)
if(((p->tag.l^alf.l)&(-c->bb))==0&&p->tag.h==alf.h)goto hit;
return NULL;
hit:hit_set= s;return p;
}
/*:193*//*196:*/
#line 3470 "mmix-pipe.w"
static cacheblock*use_and_fix(c,p)
cache*c;
cacheblock*p;
{
if(hit_set!=c->victim)note_usage(p,hit_set,c->aa,c->repl);
else{note_usage(p,hit_set,c->vv,c->vrepl);
if(!c->filler.next){
register cacheset s= cache_addr(c,p->tag);
register cacheblock*q= choose_victim(s,c->aa,c->repl);
note_usage(q,s,c->aa,c->repl);
/*197:*/
#line 3492 "mmix-pipe.w"
{
octa t;
register char*d= p->dirty;
register octa*dd= p->data;
t= p->tag;p->tag= q->tag;q->tag= t;
p->dirty= q->dirty;q->dirty= d;
p->data= q->data;q->data= dd;
}
/*:197*/
#line 3481 "mmix-pipe.w"
;
return q;
}
}
return p;
}
/*:196*//*199:*/
#line 3508 "mmix-pipe.w"
static cacheblock*demote_and_fix(c,p)
cache*c;
cacheblock*p;
{
if(hit_set!=c->victim)demote_usage(p,hit_set,c->aa,c->repl);
else demote_usage(p,hit_set,c->vv,c->vrepl);
return p;
}
/*:199*//*201:*/
#line 3525 "mmix-pipe.w"
static void load_cache(c,p)
cache*c;
cacheblock*p;
{
register int i;
register octa*d;
for(i= 0;i<c->bb>>c->g;i++)p->dirty[i]= false;
d= p->data;p->data= c->inbuf.data;c->inbuf.data= d;
p->tag= c->inbuf.tag;
hit_set= cache_addr(c,p->tag);
use_and_fix(c,p);
}
/*:201*//*203:*/
#line 3549 "mmix-pipe.w"
static void flush_cache(c,p,keep)
cache*c;
cacheblock*p;
bool keep;
{
register octa*d;
register char*dd;
register int j;
c->outbuf.tag= p->tag;
if(keep)for(j= 0;j<c->bb>>3;j++)c->outbuf.data[j]= p->data[j];
else d= c->outbuf.data,c->outbuf.data= p->data,p->data= d;
dd= c->outbuf.dirty,c->outbuf.dirty= p->dirty,p->dirty= dd;
for(j= 0;j<c->bb>>c->g;j++)p->dirty[j]= false;
startup(&c->flusher,c->copy_out_time);
}
/*:203*//*205:*/
#line 3594 "mmix-pipe.w"
static cacheblock*alloc_slot(c,alf)
cache*c;
octa alf;
{
register cacheset s;
register cacheblock*p,*q;
if(cache_search(c,alf))return NULL;
s= cache_addr(c,alf);
if(c->victim)p= choose_victim(c->victim,c->vv,c->vrepl);
else p= choose_victim(s,c->aa,c->repl);
if(is_dirty(c,p)){
if(c->flusher.next)return NULL;
flush_cache(c,p,false);
}
if(c->victim){
q= choose_victim(s,c->aa,c->repl);
/*197:*/
#line 3492 "mmix-pipe.w"
{
octa t;
register char*d= p->dirty;
register octa*dd= p->data;
t= p->tag;p->tag= q->tag;q->tag= t;
p->dirty= q->dirty;q->dirty= d;
p->data= q->data;q->data= dd;
}
/*:197*/
#line 3611 "mmix-pipe.w"
;
q->tag.h|= sign_bit;
return q;
}
p->tag.h|= sign_bit;return p;
}
/*:205*//*208:*/
#line 3669 "mmix-pipe.w"
extern octa spec_read ARGS((octa addr));
extern void spec_write ARGS((octa addr,octa val));
/*:208*//*241:*/
#line 4307 "mmix-pipe.w"
static octa phys_addr(virt,trans)
octa virt,trans;
{octa t;
t= trans;t.l&= -8;
return oplus(t,oand(virt,page_mask));
}
/*:241*//*251:*/
#line 4426 "mmix-pipe.w"
static void print_write_buffer()
{
printf("Write buffer");
if(write_head==write_tail)printf(" (empty)\n");
else{register write_node*p;
printf(":\n");
for(p= write_head;p!=write_tail;p= (p==wbuf_bot?wbuf_top:p-1)){
printf("m[");print_octa(p->addr);printf("]=");print_octa(p->o);
if(p->i==stunc)printf(" unc");
else if(p->i==sync)printf(" sync");
printf(" (age %d)\n",ticks.l-p->stamp);
}
}
}
/*:251*//*255:*/
#line 4479 "mmix-pipe.w"
static octa*write_search(ctl,addr)
control*ctl;
octa addr;
{register specnode*p= (ctl->mem_x?ctl->x.up:(specnode*)ctl->ptr_a);
register write_node*q= write_tail;
addr.l&= -8;
if(p==&mem)goto qloop;
if(p> &hot->x&&ctl<=hot)goto qloop;
if(p<&ctl->x&&(ctl<=hot||p> &hot->x))goto qloop;
for(;p!=&mem;p= p->up){
if(p->addr.h==(tetra)-1)return DUNNO;
if((p->addr.l&-8)==addr.l&&p->addr.h==addr.h)
return(p->known?&(p->o):DUNNO);
}
qloop:for(;;){
if(q==write_head)return NULL;
if(q==wbuf_top)q= wbuf_bot;else q++;
if(q->addr.l==addr.l&&q->addr.h==addr.h)return&(q->o);
}
}
/*:255*//*378:*/
#line 6526 "mmix-pipe.w"
octa magic_read(addr)
octa addr;
{
register write_node*q;
register cacheblock*p;
for(q= write_tail;;){
if(q==write_head)break;
if(q==wbuf_top)q= wbuf_bot;else q++;
if((q->addr.l&-8)==(addr.l&-8)&&q->addr.h==addr.h)return q->o;
}
if(Dcache){
p= cache_search(Dcache,addr);
if(p)return p->data[(addr.l&(Dcache->bb-1))>>3];
if(((Dcache->outbuf.tag.l^addr.l)&-Dcache->bb)==0&&
Dcache->outbuf.tag.h==addr.h)
return Dcache->outbuf.data[(addr.l&(Dcache->bb-1))>>3];
if(Scache){
p= cache_search(Scache,addr);
if(p)return p->data[(addr.l&(Scache->bb-1))>>3];
if(((Scache->outbuf.tag.l^addr.l)&-Scache->bb)==0&&
Scache->outbuf.tag.h==addr.h)
return Scache->outbuf.data[(addr.l&(Scache->bb-1))>>3];
}
}
return mem_read(addr);
}
/*:378*//*379:*/
#line 6559 "mmix-pipe.w"
void magic_write(addr,val)
octa addr,val;
{
register write_node*q;
register cacheblock*p;
for(q= write_tail;;){
if(q==write_head)break;
if(q==wbuf_top)q= wbuf_bot;else q++;
if((q->addr.l&-8)==(addr.l&-8)&&q->addr.h==addr.h)q->o= val;
}
if(Dcache){
p= cache_search(Dcache,addr);
if(p)p->data[(addr.l&(Dcache->bb-1))>>3]= val;
if(((Dcache->inbuf.tag.l^addr.l)&-Dcache->bb)==0&&
Dcache->inbuf.tag.h==addr.h)
Dcache->inbuf.data[(addr.l&(Dcache->bb-1))>>3]= val;
if(((Dcache->outbuf.tag.l^addr.l)&-Dcache->bb)==0&&
Dcache->outbuf.tag.h==addr.h)
Dcache->outbuf.data[(addr.l&(Dcache->bb-1))>>3]= val;
if(Scache){
p= cache_search(Scache,addr);
if(p)p->data[(addr.l&(Scache->bb-1))>>3]= val;
if(((Scache->inbuf.tag.l^addr.l)&-Scache->bb)==0&&
Scache->inbuf.tag.h==addr.h)
Scache->inbuf.data[(addr.l&(Scache->bb-1))>>3]= val;
if(((Scache->outbuf.tag.l^addr.l)&-Scache->bb)==0&&
Scache->outbuf.tag.h==addr.h)
Scache->outbuf.data[(addr.l&(Scache->bb-1))>>3]= val;
}
}
mem_write(addr,val);
}
/*:379*//*381:*/
#line 6617 "mmix-pipe.w"
int mmgetchars(buf,size,addr,stop)
char*buf;
int size;
octa addr;
int stop;
{
register char*p;
register int m;
octa a,x;
if(((addr.h&0x9fffffff)||(incr(addr,size-1).h&0x9fffffff))&&size){
fprintf(stderr,"Attempt to get characters from off the page!\n");
return 0;
}
for(p= buf,m= 0,a= addr,a.h>>= 29;m<size;){
x= magic_read(a);
if((a.l&0x7)||m> size-8)/*382:*/
#line 6640 "mmix-pipe.w"
{
if(a.l&0x4)*p= (x.l>>(8*((~a.l)&0x3)))&0xff;
else*p= (x.h>>(8*((~a.l)&0x3)))&0xff;
if(!*p&&stop>=0){
if(stop==0)return m;
if((a.l&0x1)&&*(p-1)=='\0')return m-1;
}
p++,m++,a= incr(a,1);
}
/*:382*/
#line 6634 "mmix-pipe.w"
else/*383:*/
#line 6651 "mmix-pipe.w"
{
*p= x.h>>24;
if(!*p&&(stop==0||(stop> 0&&x.h<0x10000)))return m;
*(p+1)= (x.h>>16)&0xff;
if(!*(p+1)&&stop==0)return m+1;
*(p+2)= (x.h>>8)&0xff;
if(!*(p+2)&&(stop==0||(stop> 0&&(x.h&0xffff)==0)))return m+2;
*(p+3)= x.h&0xff;
if(!*(p+3)&&stop==0)return m+3;
*(p+4)= x.l>>24;
if(!*(p+4)&&(stop==0||(stop> 0&&x.l<0x10000)))return m+4;
*(p+5)= (x.l>>16)&0xff;
if(!*(p+5)&&stop==0)return m+5;
*(p+6)= (x.l>>8)&0xff;
if(!*(p+6)&&(stop==0||(stop> 0&&(x.l&0xffff)==0)))return m+6;
*(p+7)= x.l&0xff;
if(!*(p+7)&&stop==0)return m+7;
p+= 8,m+= 8,a= incr(a,8);
}
/*:383*/
#line 6635 "mmix-pipe.w"
}
return size;
}
/*:381*//*384:*/
#line 6675 "mmix-pipe.w"
void mmputchars(buf,size,addr)
unsigned char*buf;
int size;
octa addr;
{
register unsigned char*p;
register int m;
octa a,x;
if(((addr.h&0x9fffffff)||(incr(addr,size-1).h&0x9fffffff))&&size){
fprintf(stderr,"Attempt to put characters off the page!\n");
return;
}
for(p= buf,m= 0,a= addr,a.h>>= 29;m<size;){
if((a.l&0x7)||m> size-8)/*385:*/
#line 6695 "mmix-pipe.w"
{
register int s= 8*((~a.l)&0x3);
x= magic_read(a);
if(a.l&0x4)x.l^= (((x.l>>s)^*p)&0xff)<<s;
else x.h^= (((x.h>>s)^*p)&0xff)<<s;
magic_write(a,x);
p++,m++,a= incr(a,1);
}
/*:385*/
#line 6690 "mmix-pipe.w"
else/*386:*/
#line 6705 "mmix-pipe.w"
{
x.h= (*p<<24)+(*(p+1)<<16)+(*(p+2)<<8)+*(p+3);
x.l= (*(p+4)<<24)+(*(p+5)<<16)+(*(p+6)<<8)+*(p+7);
magic_write(a,x);
p+= 8,m+= 8,a= incr(a,8);
}
/*:386*/
#line 6691 "mmix-pipe.w"
;
}
}
/*:384*//*387:*/
#line 6724 "mmix-pipe.w"
char stdin_chr()
{
register char*p;
while(stdin_buf_start==stdin_buf_end){
printf("StdIn> ");fflush(stdout);
fgets(stdin_buf,256,stdin);
stdin_buf_start= stdin_buf;
for(p= stdin_buf;p<stdin_buf+254;p++)if(*p=='\n')break;
stdin_buf_end= p+1;
}
return*stdin_buf_start++;
}
/*:387*/
#line 135 "mmix-pipe.w"
/*10:*/
#line 213 "mmix-pipe.w"
void MMIX_init()
{
register int i,j;
/*22:*/
#line 403 "mmix-pipe.w"
if(shift_left(neg_one,1).h!=0xffffffff)
panic(errprint0("Incorrect implementation of type tetra"));
/*:22*//*26:*/
#line 480 "mmix-pipe.w"
{register coroutine*p;
for(p= ring;p<ring+ring_size;p++)p->next= p;
}
/*:26*//*61:*/
#line 1399 "mmix-pipe.w"
hot= cool= reorder_top;
deissues= 0;
/*:61*//*71:*/
#line 1524 "mmix-pipe.w"
head= tail= fetch_top;
inst_ptr.p= UNKNOWN_SPEC;
/*:71*//*79:*/
#line 1652 "mmix-pipe.w"
{register func*u;
for(u= funit;u<=funit+funit_count;u++)
for(i= 0;i<8;i++)support[i]|= u->ops[i];
}
/*:79*//*89:*/
#line 1856 "mmix-pipe.w"
rename_regs= max_rename_regs;
mem_slots= max_mem_slots;
lring_mask= lring_size-1;
for(j= 0;j<256;j++){
g[j].addr.h= sign_bit,g[j].addr.l= j,g[j].known= true;
g[j].up= g[j].down= &g[j];
}
g[rG].o.l= 255;
g[rN].o.h= (VERSION<<24)+(SUBVERSION<<16)+(SUBSUBVERSION<<8);
g[rN].o.l= ABSTIME;
for(j= 0;j<lring_size;j++){
l[j].addr.h= sign_bit,l[j].addr.l= 256+j,l[j].known= true;
l[j].up= l[j].down= &l[j];
}
/*:89*//*116:*/
#line 2181 "mmix-pipe.w"
mem.addr.h= mem.addr.l= -1;
mem.up= mem.down= &mem;
/*:116*//*128:*/
#line 2396 "mmix-pipe.w"
mem_locker.name= "Locker";
mem_locker.ctl= &vanish_ctl;
mem_locker.stage= vanish;
Dlocker.name= "Dlocker";
Dlocker.ctl= &vanish_ctl;
Dlocker.stage= vanish;
vanish_ctl.go.o.l= 4;
for(j= 0;j<DTcache->ports;j++)DTcache->reader[j].ctl= &vanish_ctl;
if(Dcache)for(j= 0;j<Dcache->ports;j++)Dcache->reader[j].ctl= &vanish_ctl;
for(j= 0;j<ITcache->ports;j++)ITcache->reader[j].ctl= &vanish_ctl;
if(Icache)for(j= 0;j<Icache->ports;j++)Icache->reader[j].ctl= &vanish_ctl;
/*:128*//*153:*/
#line 2877 "mmix-pipe.w"
bp_amask= ((1<<bp_a)-1)<<2;
bp_cmask= ((1<<bp_c)-1)<<(bp_a+2);
bp_bcmask= (1<<(bp_b+bp_c))-1;
bp_nmask= (1<<bp_n)-1;
bp_npower= 1<<(bp_n-1);
/*:153*//*231:*/
#line 4069 "mmix-pipe.w"
clean_co.ctl= &clean_ctl;
clean_co.name= "Clean";
clean_co.stage= cleanup;
clean_ctl.go.o.l= 4;
/*:231*//*236:*/
#line 4217 "mmix-pipe.w"
for(j= 0;j<5;j++){
DPTco[2*j].ctl= &DPTctl[j];IPTco[2*j].ctl= &IPTctl[j];
if(j> 0)DPTctl[j].op= IPTctl[j].op= LDPTP,DPTctl[j].i= IPTctl[j].i= ldptp;
else DPTctl[0].op= IPTctl[0].op= LDPTE,DPTctl[0].i= IPTctl[0].i= ldpte;
IPTctl[j].loc= DPTctl[j].loc= neg_one;
IPTctl[j].go.o= DPTctl[j].go.o= incr(neg_one,4);
IPTctl[j].ptr_a= DPTctl[j].ptr_a= (void*)&mem;
IPTctl[j].ren_x= DPTctl[j].ren_x= true;
IPTctl[j].x.addr.h= DPTctl[j].x.addr.h= -1;
IPTco[2*j].stage= DPTco[2*j].stage= 1;
IPTco[2*j+1].stage= DPTco[2*j+1].stage= 2;
IPTco[2*j].name= IPTco[2*j+1].name= IPTname[j];
DPTco[2*j].name= DPTco[2*j+1].name= DPTname[j];
}
ITcache->filler_ctl.ptr_c= (void*)&IPTco[0];
DTcache->filler_ctl.ptr_c= (void*)&DPTco[0];
/*:236*//*249:*/
#line 4414 "mmix-pipe.w"
write_co.ctl= &write_ctl;
write_co.name= "Write";
write_co.stage= write_from_wbuf;
write_ctl.ptr_a= (void*)&mem;
write_ctl.go.o.l= 4;
startup(&write_co,1);
write_head= write_tail= wbuf_top;
/*:249*//*286:*/
#line 5119 "mmix-pipe.w"
fetch_co.ctl= &fetch_ctl;
fetch_co.name= "Fetch";
fetch_ctl.go.o.l= 4;
startup(&fetch_co,1);
/*:286*/
#line 217 "mmix-pipe.w"
;
}
void MMIX_run(cycs,breakpoint)
int cycs;
octa breakpoint;
{
/*12:*/
#line 246 "mmix-pipe.w"
register int i,j,m;
bool breakpoint_hit= false;
bool halted= false;
/*:12*//*124:*/
#line 2350 "mmix-pipe.w"
register coroutine*self;
register control*data;
/*:124*//*258:*/
#line 4570 "mmix-pipe.w"
register cacheblock*p,*q;
/*:258*/
#line 224 "mmix-pipe.w"
;
while(cycs){
if(verbose&(issue_bit|pipe_bit|coroutine_bit|schedule_bit))
printf("*** Cycle %d\n",ticks.l);
/*64:*/
#line 1430 "mmix-pipe.w"
{
/*314:*/
#line 5494 "mmix-pipe.w"
g[rI].o= incr(g[rI].o,-1);
if(g[rI].o.l==0&&g[rI].o.h==0){
g[rQ].o.l|= INTERVAL_TIMEOUT,new_Q.l|= INTERVAL_TIMEOUT;
if(verbose&issue_bit){
printf(" setting rQ=");print_octa(g[rQ].o);printf("\n");
}
}
trying_to_interrupt= false;
if(((g[rQ].o.h&g[rK].o.h)||(g[rQ].o.l&g[rK].o.l))&&cool!=hot&&
!(hot->interrupt&(E_BIT+F_BIT+H_BIT))&&!doing_interrupt&&
!(hot->i==resum)){
if(hot->owner)trying_to_interrupt= true;
else{
hot->interrupt|= E_BIT;
/*316:*/
#line 5528 "mmix-pipe.w"
i= issued_between(hot,cool);
if(i>=deissues){
deissues= i;
tail= head;resuming= 0;
/*287:*/
#line 5125 "mmix-pipe.w"
if(fetch_co.lockloc)*(fetch_co.lockloc)= NULL,fetch_co.lockloc= NULL;
unschedule(&fetch_co);
startup(&fetch_co,1);
/*:287*/
#line 5533 "mmix-pipe.w"
;
if(is_load_store(hot->i))nullifying= true;
}
/*:316*/
#line 5509 "mmix-pipe.w"
;
inst_ptr.o= g[rTT].o;inst_ptr.p= NULL;
}
}
/*:314*/
#line 1432 "mmix-pipe.w"
;
dispatch_count= 0;
old_hot= hot;
old_tail= tail;
suppress_dispatch= (deissues||dispatch_lock);
if(doing_interrupt)/*318:*/
#line 5560 "mmix-pipe.w"
switch(doing_interrupt--){
case 3:/*319:*/
#line 5570 "mmix-pipe.w"
j= hot->interrupt&H_BIT;
g[j?rB:rBB].o= g[255].o;
g[255].o= g[rJ].o;
if(verbose&issue_bit){
if(j){
printf(" setting rB=");print_octa(g[rB].o);
}else{
printf(" setting rBB=");print_octa(g[rBB].o);
}
printf(", $255=");print_octa(g[255].o);printf("\n");
}
/*:319*/
#line 5562 "mmix-pipe.w"
;
break;
case 2:/*320:*/
#line 5592 "mmix-pipe.w"
j= pack_bytes(hot->op,hot->xx,hot->yy,hot->zz);
if(hot->interrupt&H_BIT){
g[rW].o= incr(hot->loc,4);
g[rX].o.h= sign_bit,g[rX].o.l= j;
if(verbose&issue_bit){
printf(" setting rW=");print_octa(g[rW].o);
printf(", rX=");print_octa(g[rX].o);printf("\n");
}
}else{
g[rWW].o= hot->go.o;
g[rXX].o.l= j;
if(hot->interrupt&F_BIT){
if(hot->i!=trap)j= RESUME_TRANS;
else if(hot->op==TRAP)j= 0x80;
else if(flags[internal_op[hot->op]]&X_is_dest_bit)
j= RESUME_SET;
else j= 0x80;
}else{
if(hot->interim)
j= (hot->i==frem||hot->i==syncd||hot->i==syncid?RESUME_CONT:
RESUME_AGAIN);
else if(is_load_store(hot->i))j= RESUME_AGAIN;
else j= 0x80;
}
g[rXX].o.h= (j<<24)+(hot->interrupt&0xff);
if(verbose&issue_bit){
printf(" setting rWW=");print_octa(g[rWW].o);
printf(", rXX=");print_octa(g[rXX].o);printf("\n");
}
}
/*:320*/
#line 5564 "mmix-pipe.w"
;break;
case 1:/*321:*/
#line 5624 "mmix-pipe.w"
j= hot->interrupt&H_BIT;
if((hot->interrupt&F_BIT)&&hot->op==SWYM)g[rYY].o= hot->go.o;
else g[j?rY:rYY].o= hot->y.o;
if(hot->i==st||hot->i==pst)g[j?rZ:rZZ].o= hot->x.o;
else g[j?rZ:rZZ].o= hot->z.o;
if(verbose&issue_bit){
if(j){
printf(" setting rY=");print_octa(g[rY].o);
printf(", rZ=");print_octa(g[rZ].o);printf("\n");
}else{
printf(" setting rYY=");print_octa(g[rYY].o);
printf(", rZZ=");print_octa(g[rZZ].o);printf("\n");
}
}
/*:321*/
#line 5565 "mmix-pipe.w"
;
if(hot==reorder_bot)hot= reorder_top;else hot--;
break;
}
/*:318*/
#line 1437 "mmix-pipe.w"
else/*67:*/
#line 1456 "mmix-pipe.w"
{
for(m= commit_max;m> 0&&deissues> 0;m--)
/*145:*/
#line 2675 "mmix-pipe.w"
{
cool= (cool==reorder_top?reorder_bot:cool+1);
if(verbose&issue_bit){
printf("Deissuing ");print_control_block(cool);
if(cool->owner){printf(" ");print_coroutine_id(cool->owner);}
printf("\n");
}
if(cool->ren_x)rename_regs++,spec_rem(&cool->x);
if(cool->ren_a)rename_regs++,spec_rem(&cool->a);
if(cool->mem_x)mem_slots++,spec_rem(&cool->x);
if(cool->set_l)spec_rem(&cool->rl);
if(cool->owner){
if(cool->owner->lockloc)
*(cool->owner->lockloc)= NULL,cool->owner->lockloc= NULL;
if(cool->owner->next)unschedule(cool->owner);
}
cool_O= cool->cur_O;cool_S= cool->cur_S;
deissues--;
}
/*:145*/
#line 1459 "mmix-pipe.w"
;
for(;m> 0;m--){
if(hot==cool)break;
if(!security_disabled)/*149:*/
#line 2761 "mmix-pipe.w"
{
if(hot->loc.h&sign_bit){
if((g[rK].o.h&P_BIT)&&!(hot->interrupt&P_BIT)){
hot->interrupt|= P_BIT;
g[rQ].o.h|= P_BIT;
new_Q.h|= P_BIT;
if(verbose&issue_bit){
printf(" setting rQ=");print_octa(g[rQ].o);printf("\n");
}
break;
}
}else if((g[rK].o.h&0xff)!=0xff&&!(hot->interrupt&S_BIT)){
hot->interrupt|= S_BIT;
g[rQ].o.h|= S_BIT;
new_Q.h|= S_BIT;
g[rK].o.h|= S_BIT;
if(verbose&issue_bit){
printf(" setting rQ=");print_octa(g[rQ].o);
printf(", rK=");print_octa(g[rK].o);printf("\n");
}
break;
}
}
/*:149*/
#line 1462 "mmix-pipe.w"
;
if(hot->owner)break;
/*146:*/
#line 2696 "mmix-pipe.w"
{
if(nullifying)/*147:*/
#line 2729 "mmix-pipe.w"
{
if(verbose&issue_bit){
printf("Nullifying ");print_control_block(hot);printf("\n");
}
if(hot->ren_x)rename_regs++,spec_rem(&hot->x);
if(hot->ren_a)rename_regs++,spec_rem(&hot->a);
if(hot->mem_x)mem_slots++,spec_rem(&hot->x);
if(hot->set_l)spec_rem(&hot->rl);
cool_O= hot->cur_O,cool_S= hot->cur_S;
nullifying= false;
}
/*:147*/
#line 2698 "mmix-pipe.w"
else{
if(hot->i==get&&hot->zz==rQ)
new_Q= oandn(g[rQ].o,hot->x.o);
else if(hot->i==put&&hot->xx==rQ)
hot->x.o.h|= new_Q.h,hot->x.o.l|= new_Q.l;
if(hot->mem_x)/*256:*/
#line 4514 "mmix-pipe.w"
{register write_node*q= write_tail;
if(hot->interrupt&(F_BIT+0xff))goto done_with_write;
if(hot->i!=sync)for(;;){
if(q==write_head)break;
if(q==wbuf_top)q= wbuf_bot;else q++;
if(q->i==sync)break;
if(q->addr.l==hot->x.addr.l&&q->addr.h==hot->x.addr.h
&&(q!=write_head||!wbuf_lock))goto addr_found;
}
{register write_node*p= (write_tail==wbuf_bot?wbuf_top:write_tail-1);
if(p==write_head)break;
q= write_tail;write_tail= p;
q->addr= hot->x.addr;
}
addr_found:q->o= hot->x.o;
q->stamp= ticks.l;
q->i= hot->i;
done_with_write:spec_rem(&(hot->x));
mem_slots++;
}
/*:256*/
#line 2704 "mmix-pipe.w"
;
if(verbose&issue_bit){
printf("Committing ");print_control_block(hot);printf("\n");
}
if(hot->ren_x)rename_regs++,hot->x.up->o= hot->x.o,spec_rem(&(hot->x));
if(hot->ren_a)rename_regs++,hot->a.up->o= hot->a.o,spec_rem(&(hot->a));
if(hot->set_l)hot->rl.up->o= hot->rl.o,spec_rem(&(hot->rl));
if(hot->arith_exc)g[rA].o.l|= hot->arith_exc;
if(hot->usage){
g[rU].o.l++;if(g[rU].o.l==0){
g[rU].o.h++;if((g[rU].o.h&0x7fff)==0)g[rU].o.h-= 0x8000;
}
}
}
if(hot->interrupt>=H_BIT)/*317:*/
#line 5547 "mmix-pipe.w"
{
if(!(hot->interrupt&H_BIT))g[rK].o= zero_octa;
if(((hot->interrupt&H_BIT)&&hot->i!=trip)||
((hot->interrupt&F_BIT)&&hot->i!=trap)||
(hot->interrupt&E_BIT))doing_interrupt= 3,suppress_dispatch= true;
else doing_interrupt= 2;
break;
}
/*:317*/
#line 2718 "mmix-pipe.w"
;
}
/*:146*/
#line 1464 "mmix-pipe.w"
;
i= hot->i;
if(hot==reorder_bot)hot= reorder_top;
else hot--;
if(i==resum)break;
}
}
/*:67*/
#line 1438 "mmix-pipe.w"
;
/*125:*/
#line 2366 "mmix-pipe.w"
cur_time++;if(cur_time==ring_size)cur_time= 0;
for(self= queuelist(cur_time);self!=&sentinel;self= sentinel.next){
sentinel.next= self->next;self->next= NULL;
data= self->ctl;
if(verbose&coroutine_bit){
printf(" running ");print_coroutine_id(self);printf(" ");
print_control_block(data);printf("\n");
}
switch(self->stage){
case 0:/*288:*/
#line 5136 "mmix-pipe.w"
switch0:switch(data->state){
new_fetch:data->state= 0;
case 0:/*290:*/
#line 5155 "mmix-pipe.w"
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);
}
/*:290*/
#line 5139 "mmix-pipe.w"
;
data->y.o= inst_ptr.o;
data->state= 1;data->interrupt= 0;data->x.o= data->z.o= zero_octa;
case 1:start_fetch:if(data->y.o.h&sign_bit)
/*296:*/
#line 5225 "mmix-pipe.w"
{
if(data->i==prego&&!(data->loc.h&sign_bit))goto fin_ex;
data->z.o= data->y.o;data->z.o.h-= sign_bit;
known_phys:if(data->z.o.h&0xffff0000)goto bad_fetch;
if(!Icache)/*297:*/
#line 5244 "mmix-pipe.w"
{octa addr;
addr= data->z.o;
if(mem_lock)wait(1);
set_lock(&mem_locker,mem_lock);
startup(&mem_locker,mem_addr_time+mem_read_time);
addr.l&= -(bus_words<<3);
fetched[0]= mem_read(addr);
for(j= 1;j<bus_words;j++)
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);
}
/*:297*/
#line 5230 "mmix-pipe.w"
;
if(Icache->lock||(j= get_reader(Icache))<0){
data->state= IT_hit;wait_or_pass(1);
}
startup(&Icache->reader[j],Icache->access_time);
q= cache_search(Icache,data->z.o);
if(q){
q= use_and_fix(Icache,q);
/*294:*/
#line 5208 "mmix-pipe.w"
if(data->i!=prego){
for(j= 0;j<Icache->bb;j++)fetched[j]= q->data[j];
fetch_lo= (inst_ptr.o.l&(Icache->bb-1))>>3;
fetch_hi= Icache->bb>>3;
}
/*:294*/
#line 5238 "mmix-pipe.w"
;
data->state= fetch_ready;
}else data->state= Ihit_and_miss;
wait_or_pass(Icache->access_time);
}
/*:296*/
#line 5143 "mmix-pipe.w"
;
if(page_bad)goto bad_fetch;
if(ITcache->lock||(j= get_reader(ITcache))<0)wait(1);
startup(&ITcache->reader[j],ITcache->access_time);
/*291:*/
#line 5169 "mmix-pipe.w"
p= cache_search(ITcache,trans_key(data->y.o));
if(!Icache||Icache->lock||(j= get_reader(Icache))<0)
/*295:*/
#line 5215 "mmix-pipe.w"
{
if(p){
/*293:*/
#line 5202 "mmix-pipe.w"
p= use_and_fix(ITcache,p);
if(!(p->data[0].l&(PX_BIT>>PROT_OFFSET)))goto bad_fetch;
/*:293*/
#line 5218 "mmix-pipe.w"
;
data->z.o= phys_addr(data->y.o,p->data[0]);
data->state= IT_hit;
}else data->state= IT_miss;
wait_or_pass(ITcache->access_time);
}
/*:295*/
#line 5172 "mmix-pipe.w"
;
startup(&Icache->reader[j],Icache->access_time);
if(p)/*292:*/
#line 5184 "mmix-pipe.w"
{
/*293:*/
#line 5202 "mmix-pipe.w"
p= use_and_fix(ITcache,p);
if(!(p->data[0].l&(PX_BIT>>PROT_OFFSET)))goto bad_fetch;
/*:293*/
#line 5186 "mmix-pipe.w"
;
data->z.o= phys_addr(data->y.o,p->data[0]);
if(Icache->b+Icache->c> page_s&&
((data->y.o.l^data->z.o.l)&((Icache->bb<<Icache->c)-(1<<page_s))))
data->state= IT_hit;
else{
q= cache_search(Icache,data->z.o);
if(q){
q= use_and_fix(Icache,q);
/*294:*/
#line 5208 "mmix-pipe.w"
if(data->i!=prego){
for(j= 0;j<Icache->bb;j++)fetched[j]= q->data[j];
fetch_lo= (inst_ptr.o.l&(Icache->bb-1))>>3;
fetch_hi= Icache->bb>>3;
}
/*:294*/
#line 5195 "mmix-pipe.w"
;
data->state= fetch_ready;
}else data->state= Ihit_and_miss;
}
wait_or_pass(max(ITcache->access_time,Icache->access_time));
}
/*:292*/
#line 5174 "mmix-pipe.w"
else data->state= IT_miss;
/*:291*/
#line 5147 "mmix-pipe.w"
;
wait_or_pass(ITcache->access_time);
/*298:*/
#line 5259 "mmix-pipe.w"
case IT_miss:if(ITcache->filler.next)
if(data->i==prego)goto fin_ex;else wait(1);
if(no_hardware_PT)/*302:*/
#line 5327 "mmix-pipe.w"
{
if(cache_search(ITcache,trans_key(inst_ptr.o)))goto new_fetch;
data->interrupt|= F_BIT;
sleepy= true;
goto swym_one;
}
/*:302*/
#line 5262 "mmix-pipe.w"
;
p= alloc_slot(ITcache,trans_key(data->y.o));
if(!p)
if(data->i==prego)goto fin_ex;else goto new_fetch;
data->ptr_b= ITcache->filler_ctl.ptr_b= (void*)p;
ITcache->filler_ctl.y.o= data->y.o;
set_lock(self,ITcache->fill_lock);
startup(&ITcache->filler,1);
data->state= got_IT;
if(data->i==prego)goto fin_ex;else sleep;
case got_IT:release_lock(self,ITcache->fill_lock);
if(!(data->z.o.l&(PX_BIT>>PROT_OFFSET)))goto bad_fetch;
data->z.o= phys_addr(data->y.o,data->z.o);
fetch_retry:data->state= IT_hit;
case IT_hit:if(data->i==prego)goto fin_ex;else goto known_phys;
case Ihit_and_miss:
/*300:*/
#line 5283 "mmix-pipe.w"
if(Icache->filler.next)goto fetch_retry;
if((Scache&&Scache->lock)||(!Scache&&mem_lock))goto fetch_retry;
q= alloc_slot(Icache,data->z.o);
if(!q)goto fetch_retry;
if(Scache)set_lock(&Icache->filler,Scache->lock)
else set_lock(&Icache->filler,mem_lock);
set_lock(self,Icache->fill_lock);
data->ptr_b= Icache->filler_ctl.ptr_b= (void*)q;
Icache->filler_ctl.z.o= data->z.o;
startup(&Icache->filler,Scache?Scache->access_time:mem_addr_time);
data->state= got_one;
if(data->i==prego)goto fin_ex;else sleep;
/*:300*/
#line 5278 "mmix-pipe.w"
;
/*:298*//*301:*/
#line 5301 "mmix-pipe.w"
bad_fetch:if(data->i==prego)goto fin_ex;
data->interrupt|= PX_BIT;
swym_one:fetched[0].h= fetched[0].l= SWYM<<24;
goto fetch_one;
case got_one:fetched[0]= data->x.o;
fetch_one:fetch_lo= 0;fetch_hi= 1;
data->state= fetch_ready;
case fetch_ready:if(self->lockloc)
*(self->lockloc)= NULL,self->lockloc= NULL;
if(data->i==prego)goto fin_ex;
for(j= 0;j<fetch_max;j++){
register fetch*new_tail;
if(tail==fetch_bot)new_tail= fetch_top;
else new_tail= tail-1;
if(new_tail==head)break;
/*304:*/
#line 5342 "mmix-pipe.w"
tail->loc= inst_ptr.o;
if(inst_ptr.o.l&4)tail->inst= fetched[fetch_lo++].l;
else tail->inst= fetched[fetch_lo].h;
tail->interrupt= data->interrupt;
i= tail->inst>>24;
if(i>=RESUME&&i<=SYNC&&(tail->inst&bad_inst_mask[i-RESUME]))
tail->interrupt|= B_BIT;
tail->noted= false;
if(inst_ptr.o.l==breakpoint.l&&inst_ptr.o.h==breakpoint.h)
breakpoint_hit= true;
/*:304*/
#line 5317 "mmix-pipe.w"
;
tail= new_tail;
if(sleepy){
sleepy= false;sleep;
}
inst_ptr.o= incr(inst_ptr.o,4);
if(fetch_lo==fetch_hi)goto new_fetch;
}
wait(1);
/*:301*/
#line 5149 "mmix-pipe.w"
}
/*:288*/
#line 2376 "mmix-pipe.w"
;
case 1:/*130:*/
#line 2427 "mmix-pipe.w"
switch1:switch(data->state){
case 0:/*131:*/
#line 2440 "mmix-pipe.w"
j= 0;
if(data->y.p){
j++;
if(data->y.p->known)data->y.o= data->y.p->o,data->y.p= NULL;
else j+= 10;
}
if(data->z.p){
j++;
if(data->z.p->known)data->z.o= data->z.p->o,data->z.p= NULL;
else j+= 10;
}
if(data->b.p){
if(data->need_b)j++;
if(data->b.p->known)data->b.o= data->b.p->o,data->b.p= NULL;
else if(data->need_b)j+= 10;
}
if(data->ra.p){
if(data->need_ra)j++;
if(data->ra.p->known)data->ra.o= data->ra.p->o,data->ra.p= NULL;
else if(data->need_ra)j+= 10;
}
if(j<10)data->state= 1;
if(j)wait(1);
/*:131*/
#line 2429 "mmix-pipe.w"
;
case 1:/*132:*/
#line 2475 "mmix-pipe.w"
switch(data->i){
/*137:*/
#line 2550 "mmix-pipe.w"
case set:data->x.o= data->z.o;break;
/*:137*//*138:*/
#line 2556 "mmix-pipe.w"
case or:data->x.o.h= data->y.o.h|data->z.o.h;
data->x.o.l= data->y.o.l|data->z.o.l;break;
case orn:data->x.o.h= data->y.o.h|~data->z.o.h;
data->x.o.l= data->y.o.l|~data->z.o.l;break;
case nor:data->x.o.h= ~(data->y.o.h|data->z.o.h);
data->x.o.l= ~(data->y.o.l|data->z.o.l);break;
case and:data->x.o.h= data->y.o.h&data->z.o.h;
data->x.o.l= data->y.o.l&data->z.o.l;break;
case andn:data->x.o.h= data->y.o.h&~data->z.o.h;
data->x.o.l= data->y.o.l&~data->z.o.l;break;
case nand:data->x.o.h= ~(data->y.o.h&data->z.o.h);
data->x.o.l= ~(data->y.o.l&data->z.o.l);break;
case xor:data->x.o.h= data->y.o.h^data->z.o.h;
data->x.o.l= data->y.o.l^data->z.o.l;break;
case nxor:data->x.o.h= data->y.o.h^~data->z.o.h;
data->x.o.l= data->y.o.l^~data->z.o.l;break;
/*:138*//*139:*/
#line 2580 "mmix-pipe.w"
case addu:data->x.o= oplus((data->op&0xf8)==0x28?
shift_left(data->y.o,1+((data->op>>1)&0x3)):data->y.o,data->z.o);
break;
case subu:data->x.o= ominus(data->y.o,data->z.o);break;
/*:139*//*140:*/
#line 2592 "mmix-pipe.w"
case add:data->x.o= oplus(data->y.o,data->z.o);
if(((data->y.o.h^data->z.o.h)&sign_bit)==0&&
((data->y.o.h^data->x.o.h)&sign_bit)!=0)data->interrupt|= V_BIT;
break;
case sub:data->x.o= ominus(data->y.o,data->z.o);
if(((data->x.o.h^data->z.o.h)&sign_bit)==0&&
((data->y.o.h^data->x.o.h)&sign_bit)!=0)data->interrupt|= V_BIT;
break;
/*:140*//*141:*/
#line 2611 "mmix-pipe.w"
case shlu:data->x.o= shift_left(data->y.o,shift_amt);data->i= sh;break;
case shl:data->x.o= shift_left(data->y.o,shift_amt);data->i= sh;
{octa tmpo;
tmpo= shift_right(data->x.o,shift_amt,0);
if(tmpo.h!=data->y.o.h||tmpo.l!=data->y.o.l)data->interrupt|= V_BIT;
}break;
case shru:data->x.o= shift_right(data->y.o,shift_amt,1);data->i= sh;break;
case shr:data->x.o= shift_right(data->y.o,shift_amt,0);data->i= sh;break;
/*:141*//*142:*/
#line 2625 "mmix-pipe.w"
case mux:data->x.o.h= (data->y.o.h&data->b.o.h)+(data->z.o.h&~data->b.o.h);
data->x.o.l= (data->y.o.l&data->b.o.l)+(data->z.o.l&~data->b.o.l);
break;
/*:142*//*143:*/
#line 2632 "mmix-pipe.w"
case cmp:if((data->y.o.h&sign_bit)> (data->z.o.h&sign_bit))goto cmp_neg;
if((data->y.o.h&sign_bit)<(data->z.o.h&sign_bit))goto cmp_pos;
case cmpu:if(data->y.o.h<data->z.o.h)goto cmp_neg;
if(data->y.o.h> data->z.o.h)goto cmp_pos;
if(data->y.o.l<data->z.o.l)goto cmp_neg;
if(data->y.o.l> data->z.o.l)goto cmp_pos;
cmp_zero:break;
cmp_pos:data->x.o.l= 1;break;
cmp_neg:data->x.o= neg_one;break;
/*:143*//*343:*/
#line 5985 "mmix-pipe.w"
case mulu:data->x.o= omult(data->y.o,data->z.o);
data->a.o= aux;
goto quantify_mul;
case mul:data->x.o= signed_omult(data->y.o,data->z.o);
if(overflow)data->interrupt|= V_BIT;
quantify_mul:aux= data->z.o;
for(j= mul0;aux.l||aux.h;j++)aux= shift_right(aux,8,1);
data->i= j;break;
case divu:data->x.o= odiv(data->b.o,data->y.o,data->z.o);
data->a.o= aux;data->i= div;break;
case div:if(data->z.o.l==0&&data->z.o.h==0){
data->interrupt|= D_BIT;data->a.o= data->y.o;
data->i= set;
}else{
data->x.o= signed_odiv(data->y.o,data->z.o);
if(overflow)data->interrupt|= V_BIT;
data->a.o= aux;
}break;
/*:343*//*344:*/
#line 6007 "mmix-pipe.w"
case sadd:data->x.o.l= count_bits(data->y.o.h&~data->z.o.h)
+count_bits(data->y.o.l&~data->z.o.l);break;
case mor:data->x.o= bool_mult(data->y.o,data->z.o,data->op&0x2);break;
case bdif:data->x.o.h= byte_diff(data->y.o.h,data->z.o.h);
data->x.o.l= byte_diff(data->y.o.l,data->z.o.l);break;
case wdif:data->x.o.h= wyde_diff(data->y.o.h,data->z.o.h);
data->x.o.l= wyde_diff(data->y.o.l,data->z.o.l);break;
case tdif:if(data->y.o.h> data->z.o.h)
data->x.o.h= data->y.o.h-data->z.o.h;
tdif_l:if(data->y.o.l> data->z.o.l)
data->x.o.l= data->y.o.l-data->z.o.l;break;
case odif:if(data->y.o.h> data->z.o.h)
data->x.o= ominus(data->y.o,data->z.o);
else if(data->y.o.h==data->z.o.h)goto tdif_l;
break;
/*:344*//*345:*/
#line 6039 "mmix-pipe.w"
case zset:if(register_truth(data->y.o,data->op))data->x.o= data->z.o;
goto fin_ex;
case cset:if(register_truth(data->y.o,data->op))
data->x.o= data->z.o,data->b.p= NULL;
else if(data->b.p==NULL)data->x.o= data->b.o;
else{
data->state= 0;data->need_b= true;goto switch1;
}break;
/*:345*//*346:*/
#line 6064 "mmix-pipe.w"
case fadd:set_round;data->x.o= fplus(data->y.o,data->z.o);
fin_bflot:if(is_denormal(data->y.o))data->denin= denin_penalty;
fin_uflot:if(is_denormal(data->x.o))data->denout= denout_penalty;
fin_flot:if(is_denormal(data->z.o))data->denin= denin_penalty;
data->interrupt|= exceptions;
if(is_trivial(data->y.o)||is_trivial(data->z.o))goto fin_ex;
if(data->i==fsqrt&&(data->z.o.h&sign_bit))goto fin_ex;
break;
case fsub:data->a.o= data->z.o;
if(fcomp(data->z.o,zero_octa)!=2)data->a.o.h^= sign_bit;
set_round;data->x.o= fplus(data->y.o,data->a.o);
data->i= fadd;
goto fin_bflot;
case fmul:set_round;data->x.o= fmult(data->y.o,data->z.o);goto fin_bflot;
case fdiv:set_round;data->x.o= fdivide(data->y.o,data->z.o);
goto fin_bflot;
case fsqrt:set_round;data->x.o= froot(data->z.o,data->y.o.l);
goto fin_uflot;
case fint:set_round;data->x.o= fintegerize(data->z.o,data->y.o.l);
goto fin_uflot;
case fix:set_round;data->x.o= fixit(data->z.o,data->y.o.l);
if(data->op&0x2)exceptions&= ~W_BIT;
goto fin_flot;
case flot:set_round;
data->x.o= floatit(data->z.o,data->y.o.l,data->op&0x2,data->op&0x4);
data->interrupt|= exceptions;break;
/*:346*//*348:*/
#line 6097 "mmix-pipe.w"
case feps:j= fepscomp(data->y.o,data->z.o,data->b.o,data->op!=FEQLE);
if(j==2)data->i= fcmp;
else if(is_denormal(data->y.o)||is_denormal(data->z.o))
data->denin= denin_penalty;
switch(data->op){
case FUNE:if(j==2)goto cmp_pos;else goto cmp_zero;
case FEQLE:goto cmp_fin;
case FCMPE:if(j)goto cmp_zero_or_invalid;
}
case fcmp:j= fcomp(data->y.o,data->z.o);
if(j<0)goto cmp_neg;
cmp_fin:if(j==1)goto cmp_pos;
cmp_zero_or_invalid:if(j==2)data->interrupt|= I_BIT;
goto cmp_zero;
case funeq:if(fcomp(data->y.o,data->z.o)==(data->op==FUN?2:0))
goto cmp_pos;
else goto cmp_zero;
/*:348*//*350:*/
#line 6123 "mmix-pipe.w"
case frem:if(is_trivial(data->y.o)||is_trivial(data->z.o))
{
data->x.o= fremstep(data->y.o,data->z.o,2500);goto fin_ex;
}
if((self+1)->next)wait(1);
data->interim= true;
j= 1;
if(is_denormal(data->y.o)||is_denormal(data->z.o))j+= denin_penalty;
pass_after(j);
goto passit;
/*:350*/
#line 2477 "mmix-pipe.w"
;
/*265:*/
#line 4673 "mmix-pipe.w"
case preld:case prest:case prego:
data->z.o= incr(data->z.o,data->xx&-(data->i==prego?Icache:Dcache)->bb);
case ld:case ldunc:case ldvts:
case st:case pst:case syncd:case syncid:
start_ld_st:data->y.o= oplus(data->y.o,data->z.o);
data->state= ld_st_launch;goto switch1;
case ldptp:case ldpte:if(data->y.o.h)goto start_ld_st;
data->x.o= zero_octa;data->x.known= true;goto die;
/*:265*/
#line 2478 "mmix-pipe.w"
;
/*155:*/
#line 2894 "mmix-pipe.w"
case br:case pbr:j= register_truth(data->b.o,data->op);
if(j)data->go.o= data->z.o;else data->go.o= data->y.o;
if(j==(data->i==pbr))bp_good_stat++;
else{
bp_bad_stat++;
/*160:*/
#line 2954 "mmix-pipe.w"
i= issued_between(data,cool);
if(i<deissues)goto die;
deissues= i;
old_tail= tail= head;resuming= 0;
/*287:*/
#line 5125 "mmix-pipe.w"
if(fetch_co.lockloc)*(fetch_co.lockloc)= NULL,fetch_co.lockloc= NULL;
unschedule(&fetch_co);
startup(&fetch_co,1);
/*:287*/
#line 2959 "mmix-pipe.w"
;
inst_ptr.o= data->go.o,inst_ptr.p= NULL;
if(!(data->loc.h&sign_bit)){
if(inst_ptr.o.h&sign_bit)data->interrupt|= P_BIT;
else data->interrupt&= ~P_BIT;
}
if(bp_table){
bp_table[data->x.o.h]= data->x.o.l;
if(verbose&show_pred_bit){
printf(" mispredicted ");print_octa(data->loc);
printf("; bp[%x]=%d\n",data->x.o.h,
data->x.o.l-((data->x.o.l&bp_npower)<<1));
}
}
cool_hist= (j?(data->hist<<1)+1:data->hist<<1);
/*:160*/
#line 2900 "mmix-pipe.w"
;
}
goto fin_ex;
/*:155*//*313:*/
#line 5485 "mmix-pipe.w"
case trap:data->interrupt|= F_BIT;data->a.o= data->b.o;goto fin_ex;
case trip:data->interrupt|= H_BIT;data->a.o= data->b.o;goto fin_ex;
/*:313*//*325:*/
#line 5731 "mmix-pipe.w"
case resume:case resum:if(data->xx!=RESUME_TRANS)goto fin_ex;
data->ptr_a= (void*)((data->b.o.l>>24)==SWYM?ITcache:DTcache);
data->state= do_resume_trans;
data->z.o= incr(oandn(data->z.o,page_mask),data->z.o.l&7);
data->z.o.h&= 0xffff;
goto resume_trans;
/*:325*//*327:*/
#line 5762 "mmix-pipe.w"
case noop:if(data->interrupt&F_BIT)goto emulate_virt;
case jmp:case pushj:case incrl:case unsave:goto fin_ex;
case sav:if(!(data->mem_x))goto fin_ex;
case incgamma:case save:data->i= st;goto switch1;
case decgamma:case unsav:data->i= ld;goto switch1;
/*:327*//*328:*/
#line 5776 "mmix-pipe.w"
case get:if(data->zz>=21||data->zz==rK){
if(data!=old_hot)wait(1);
data->z.o= g[data->zz].o;
}
data->x.o= data->z.o;goto fin_ex;
/*:328*//*329:*/
#line 5788 "mmix-pipe.w"
case put:if(data->xx>=15&&data->xx<=20){
if(data!=old_hot)wait(1);
switch(data->xx){
case rV:/*239:*/
#line 4280 "mmix-pipe.w"
{octa rv;
rv= data->z.o;
page_bad= (rv.l&7?true:false);
page_n= rv.l&0x1ff8;
rv= shift_right(rv,13,1);
page_r= rv.l&0x7ffffff;
rv= shift_right(rv,27,1);
page_s= rv.l&0xff;
if(page_s<13||page_s> 48)page_bad= true;
else if(page_s<32)page_mask.h= 0,page_mask.l= (1<<page_s)-1;
else page_mask.h= (1<<(page_s-32))-1,page_mask.l= 0xffffffff;
page_b[4]= (rv.l>>8)&0xf;
page_b[3]= (rv.l>>12)&0xf;
page_b[2]= (rv.l>>16)&0xf;
page_b[1]= (rv.l>>20)&0xf;
}
/*:239*/
#line 5792 "mmix-pipe.w"
;break;
case rQ:new_Q.h|= data->z.o.h&~g[rQ].o.h;
new_Q.l|= data->z.o.l&~g[rQ].o.l;
data->z.o.l|= new_Q.l;
data->z.o.h|= new_Q.h;break;
case rL:if(data->z.o.h!=0)data->z.o.h= 0,data->z.o.l= g[rL].o.l;
else if(data->z.o.l> g[rL].o.l)data->z.o.l= g[rL].o.l;
default:break;
case rG:/*330:*/
#line 5810 "mmix-pipe.w"
if(data->z.o.h!=0||data->z.o.l>=256||
data->z.o.l<g[rL].o.l||data->z.o.l<32)
data->interrupt|= B_BIT;
else if(data->z.o.l<g[rG].o.l){
data->interim= true;
for(j= 0;j<commit_max;j++){
g[rG].o.l--;
g[g[rG].o.l].o= zero_octa;
if(data->z.o.l==g[rG].o.l)break;
}
if(j==commit_max){
if(!trying_to_interrupt)wait(1);
}else data->interim= false;
}
/*:330*/
#line 5800 "mmix-pipe.w"
;break;
}
}else if(data->xx==rA&&(data->z.o.h!=0||data->z.o.l>=0x40000))
data->interrupt|= B_BIT;
data->x.o= data->z.o;goto fin_ex;
/*:329*//*331:*/
#line 5828 "mmix-pipe.w"
case go:data->x.o= data->go.o;goto add_go;
case pop:data->x.o= data->y.o;data->y.o= data->b.o;
case pushgo:add_go:data->go.o= oplus(data->y.o,data->z.o);
if((data->go.o.h&sign_bit)&&!(data->loc.h&sign_bit))
data->interrupt|= P_BIT;
data->go.known= true;goto fin_ex;
/*:331*//*356:*/
#line 6223 "mmix-pipe.w"
case sync:switch(data->zz){
case 0:case 4:if(data!=old_hot)wait(1);
halted= (data->zz!=0);goto fin_ex;
case 2:case 3:/*357:*/
#line 6238 "mmix-pipe.w"
{
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);
}
}
/*:357*/
#line 6227 "mmix-pipe.w"
;
release_lock(self,dispatch_lock);
case 1:data->x.addr= zero_octa;goto fin_ex;
case 5:if(data!=old_hot)wait(1);
/*361:*/
#line 6291 "mmix-pipe.w"
if(self->lockloc)*(self->lockloc)= NULL,self->lockloc= NULL;
/*362:*/
#line 6304 "mmix-pipe.w"
if(write_head!=write_tail){
if(!speed_lock)set_lock(self,speed_lock);
wait(1);
}
/*:362*/
#line 6293 "mmix-pipe.w"
;
if(clean_co.next||clean_lock)wait(1);
set_lock(self,clean_lock);
clean_ctl.i= sync;
clean_ctl.state= 0;
clean_ctl.x.o.h= 0;
startup(&clean_co,1);
data->state= 13;
data->interim= true;
wait(1);
/*:361*/
#line 6231 "mmix-pipe.w"
;
case 6:if(data!=old_hot)wait(1);
/*358:*/
#line 6249 "mmix-pipe.w"
if(DTcache->lock||(j= get_reader(DTcache))<0)wait(1);
startup(&DTcache->reader[j],DTcache->access_time);
set_lock(self,DTcache->lock);
zap_cache(DTcache);
data->state= 10;wait(DTcache->access_time);
/*:358*/
#line 6233 "mmix-pipe.w"
;
case 7:if(data!=old_hot)wait(1);
/*359:*/
#line 6256 "mmix-pipe.w"
if(!Icache){
data->state= 11;goto switch1;
}
if(Icache->lock||(j= get_reader(Icache))<0)wait(1);
startup(&Icache->reader[j],Icache->access_time);
set_lock(self,Icache->lock);
zap_cache(Icache);
data->state= 11;wait(Icache->access_time);
/*:359*/
#line 6235 "mmix-pipe.w"
;
}
/*:356*/
#line 2479 "mmix-pipe.w"
;
}
/*133:*/
#line 2498 "mmix-pipe.w"
data->state= 3;
if(data->i<=max_pipe_op){register unsigned char*s= pipe_seq[data->i];
j= s[0]+data->denin;
if(s[1])data->state= 2;
else j+= data->denout;
if(j> 1)wait(j-1);
}
goto switch1;
/*:133*/
#line 2481 "mmix-pipe.w"
;
/*:132*/
#line 2430 "mmix-pipe.w"
;
case 2:/*134:*/
#line 2511 "mmix-pipe.w"
pass_data:
if((self+1)->next)wait(1);
{register unsigned char*s= pipe_seq[data->i];
j= s[self->stage];
if(s[self->stage+1]==0)j+= data->denout,data->state= 3;
pass_after(j);
}
passit:(self+1)->ctl= data;
data->owner= self+1;
goto done;
/*:134*/
#line 2431 "mmix-pipe.w"
;
case 3:/*144:*/
#line 2651 "mmix-pipe.w"
fin_ex:if(data->ren_x)data->x.known= true;
else if(data->mem_x)data->x.known= true,data->x.addr.l&= -8;
if(data->ren_a)data->a.known= true;
if(data->loc.h&sign_bit)
data->ra.o.l= 0;
if(data->interrupt&0xffff)/*307:*/
#line 5400 "mmix-pipe.w"
{
if((data->interrupt&0xff)&&is_load_store(data->i))goto state_5;
j= data->interrupt&0xff00;
data->interrupt-= j;
if((j&(U_BIT+X_BIT))==U_BIT&&!(data->ra.o.l&U_BIT))j&= ~U_BIT;
data->arith_exc= (j&~data->ra.o.l)>>8;
if(j&data->ra.o.l)/*308:*/
#line 5415 "mmix-pipe.w"
{
i= issued_between(data,cool);
if(i<deissues)goto die;
deissues= i;
old_tail= tail= head;resuming= 0;
/*287:*/
#line 5125 "mmix-pipe.w"
if(fetch_co.lockloc)*(fetch_co.lockloc)= NULL,fetch_co.lockloc= NULL;
unschedule(&fetch_co);
startup(&fetch_co,1);
/*:287*/
#line 5421 "mmix-pipe.w"
;
cool_hist= data->hist;
for(i= j&data->ra.o.l,m= 16;!(i&D_BIT);i<<= 1,m+= 16);
data->go.o.h= 0,data->go.o.l= m;
inst_ptr.o= data->go.o,inst_ptr.p= NULL;
data->interrupt|= H_BIT;
goto state_4;
}
/*:308*/
#line 5407 "mmix-pipe.w"
;
if(data->interrupt&0xff)goto state_5;
}
/*:307*/
#line 2657 "mmix-pipe.w"
;
die:data->owner= NULL;goto terminate;
/*:144*/
#line 2432 "mmix-pipe.w"
;
/*266:*/
#line 4687 "mmix-pipe.w"
case ld_st_launch:if((self+1)->next)
wait(1);
/*289:*/
#line 5152 "mmix-pipe.w"
if(data->i==prego)goto start_fetch;
/*:289*//*352:*/
#line 6165 "mmix-pipe.w"
if(data->i==ldvts)/*353:*/
#line 6168 "mmix-pipe.w"
{
if(data!=old_hot)wait(1);
if(DTcache->lock||(j= get_reader(DTcache))<0)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);
if(p){
data->x.o.l= 2;
if(data->z.o.l){
p= use_and_fix(DTcache,p);
p->data[0].l= (p->data[0].l&-8)+data->z.o.l;
}else{
p= demote_and_fix(DTcache,p);
p->tag.h|= sign_bit;
}
}
pass_after(DTcache->access_time);goto passit;
}
/*:353*/
#line 6166 "mmix-pipe.w"
;
/*:352*/
#line 4690 "mmix-pipe.w"
;
if(data->y.o.h&sign_bit)
/*271:*/
#line 4801 "mmix-pipe.w"
{octa*m;
if(!(data->loc.h&sign_bit)){
if(data->i==syncd||data->i==syncid)goto sync_check;
if(data->i!=preld&&data->i!=prest)data->interrupt|= N_BIT;
goto fin_ex;
}
data->z.o= data->y.o;data->z.o.h-= sign_bit;
if(data->i>=st&&data->i<=syncid){
data->state= st_ready;pass_after(1);goto passit;
}
m= write_search(data,data->z.o);
if(m){
if(m==DUNNO)data->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);
set_lock(&mem_locker,mem_lock);
data->x.o= mem_read(data->z.o);
data->state= ld_ready;
startup(&mem_locker,mem_addr_time+mem_read_time);
pass_after(mem_addr_time+mem_read_time);goto passit;
}
if(Dcache->lock||(j= get_reader(Dcache))<0){
data->state= DT_hit;pass_after(1);goto passit;
}
startup(&Dcache->reader[j],Dcache->access_time);
q= cache_search(Dcache,data->z.o);
if(q){
if(data->i==ldunc)q= demote_and_fix(Dcache,q);
else q= use_and_fix(Dcache,q);
data->x.o= q->data[(data->z.o.l&(Dcache->bb-1))>>3];
data->state= ld_ready;
}else data->state= hit_and_miss;
pass_after(Dcache->access_time);goto passit;
}
/*:271*/
#line 4692 "mmix-pipe.w"
;
if(page_bad){
if(data->i==st||(data->i<preld&&data->i> syncid))
data->interrupt|= PRW_BITS;
goto fin_ex;
}
if(DTcache->lock||(j= get_reader(DTcache))<0)wait(1);
startup(&DTcache->reader[j],DTcache->access_time);
/*267:*/
#line 4722 "mmix-pipe.w"
p= cache_search(DTcache,trans_key(data->y.o));
if(!Dcache||Dcache->lock||(j= get_reader(Dcache))<0||
(data->i>=st&&data->i<=syncid))
/*270:*/
#line 4786 "mmix-pipe.w"
{octa*m;
if(p){
/*269:*/
#line 4776 "mmix-pipe.w"
p= use_and_fix(DTcache,p);
j= PRW_BITS;
if(((p->data[0].l<<PROT_OFFSET)&j)!=j){
if(data->i==syncd||data->i==syncid)goto sync_check;
if(data->i!=preld&&data->i!=prest)
data->interrupt|= j&~(p->data[0].l<<PROT_OFFSET);
goto fin_ex;
}
/*:269*/
#line 4789 "mmix-pipe.w"
;
data->z.o= phys_addr(data->y.o,p->data[0]);
if(data->i>=st&&data->i<=syncid)data->state= st_ready;
else{
m= write_search(data,data->z.o);
if(m&&m!=DUNNO)data->x.o= *m,data->state= ld_ready;
else data->state= DT_hit;
}
}else data->state= DT_miss;
pass_after(DTcache->access_time);goto passit;
}
/*:270*/
#line 4726 "mmix-pipe.w"
;
startup(&Dcache->reader[j],Dcache->access_time);
if(p)/*268:*/
#line 4748 "mmix-pipe.w"
{octa*m;
/*269:*/
#line 4776 "mmix-pipe.w"
p= use_and_fix(DTcache,p);
j= PRW_BITS;
if(((p->data[0].l<<PROT_OFFSET)&j)!=j){
if(data->i==syncd||data->i==syncid)goto sync_check;
if(data->i!=preld&&data->i!=prest)
data->interrupt|= j&~(p->data[0].l<<PROT_OFFSET);
goto fin_ex;
}
/*:269*/
#line 4750 "mmix-pipe.w"
;
data->z.o= phys_addr(data->y.o,p->data[0]);
m= write_search(data,data->z.o);
if(m==DUNNO)data->state= DT_hit;
else if(m)data->x.o= *m,data->state= ld_ready;
else if(Dcache->b+Dcache->c> page_s&&
((data->y.o.l^data->z.o.l)&((Dcache->bb<<Dcache->c)-(1<<page_s))))
data->state= DT_hit;
else{
q= cache_search(Dcache,data->z.o);
if(q){
if(data->i==ldunc)q= demote_and_fix(Dcache,q);
else q= use_and_fix(Dcache,q);
data->x.o= q->data[(data->z.o.l&(Dcache->bb-1))>>3];
data->state= ld_ready;
}else data->state= hit_and_miss;
}
pass_after(max(DTcache->access_time,Dcache->access_time));
goto passit;
}
/*:268*/
#line 4728 "mmix-pipe.w"
else data->state= DT_miss;
/*:267*/
#line 4700 "mmix-pipe.w"
;
pass_after(DTcache->access_time);goto passit;
/*:266*//*310:*/
#line 5445 "mmix-pipe.w"
emulate_virt:/*309:*/
#line 5430 "mmix-pipe.w"
i= issued_between(data,cool);
if(i<deissues)goto die;
deissues= i;
old_tail= tail= head;resuming= 0;
/*287:*/
#line 5125 "mmix-pipe.w"
if(fetch_co.lockloc)*(fetch_co.lockloc)= NULL,fetch_co.lockloc= NULL;
unschedule(&fetch_co);
startup(&fetch_co,1);
/*:287*/
#line 5435 "mmix-pipe.w"
;
cool_hist= data->hist;
inst_ptr.p= UNKNOWN_SPEC;
data->interrupt|= F_BIT;
/*:309*/
#line 5446 "mmix-pipe.w"
;
state_4:data->state= 4;
case 4:if(dispatch_lock)wait(1);
set_lock(self,dispatch_lock);
state_5:data->state= 5;
case 5:if(data!=old_hot)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;
}
if(data->interrupt&0xff){
g[rQ].o.h|= data->interrupt&0xff;
new_Q.h|= data->interrupt&0xff;
if(verbose&issue_bit){
printf(" setting rQ=");print_octa(g[rQ].o);printf("\n");
}
}
goto die;
/*:310*//*326:*/
#line 5739 "mmix-pipe.w"
case do_resume_trans:resume_trans:{register cache*c= (cache*)data->ptr_a;
if(c->lock)wait(1);
if(c->filler.next)wait(1);
p= alloc_slot(c,trans_key(data->y.o));
if(p){
c->filler_ctl.ptr_b= (void*)p;
c->filler_ctl.y.o= data->y.o;
c->filler_ctl.b.o= data->z.o;
c->filler_ctl.state= 1;
schedule(&c->filler,c->access_time,1);
}
goto fin_ex;
}
/*:326*//*360:*/
#line 6266 "mmix-pipe.w"
case 10:if(self->lockloc)*(self->lockloc)= NULL,self->lockloc= NULL;
if(ITcache->lock||(j= get_reader(ITcache))<0)wait(1);
startup(&ITcache->reader[j],ITcache->access_time);
set_lock(self,ITcache->lock);
zap_cache(ITcache);
data->state= 3;wait(ITcache->access_time);
case 11:if(self->lockloc)*(self->lockloc)= NULL,self->lockloc= NULL;
if(wbuf_lock)wait(1);
write_head= write_tail,write_ctl.state= 0;
if(!Dcache){
data->state= 12;goto switch1;
}
if(Dcache->lock||(j= get_reader(Dcache))<0)wait(1);
startup(&Dcache->reader[j],Dcache->access_time);
set_lock(self,Dcache->lock);
zap_cache(Dcache);
data->state= 12;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);
set_lock(self,Scache->lock);
zap_cache(Scache);
data->state= 3;wait(Scache->access_time);
/*:360*//*363:*/
#line 6314 "mmix-pipe.w"
case 13:if(!clean_co.next){
data->interim= false;goto fin_ex;
}
if(trying_to_interrupt)goto fin_ex;
wait(1);
/*:363*/
#line 2433 "mmix-pipe.w"
;
}
/*:130*/
#line 2377 "mmix-pipe.w"
;
default:/*135:*/
#line 2524 "mmix-pipe.w"
switch2:if(data->b.p&&data->b.p->known)
data->b.o= data->b.p->o,data->b.p= NULL;
switch(data->state){
case 0:panic(confusion("switch2"));
case 1:/*351:*/
#line 6136 "mmix-pipe.w"
j= 1;
if(data->i==frem){
data->x.o= fremstep(data->y.o,data->z.o,frem_max);
if(exceptions&E_BIT){
data->y.o= data->x.o;
if(trying_to_interrupt&&data==old_hot)goto fin_ex;
}else{
data->state= 3;
data->interim= false;
data->interrupt|= exceptions;
if(is_denormal(data->x.o))j+= denout_penalty;
}
wait(j);
}
/*:351*/
#line 2529 "mmix-pipe.w"
;
case 2:goto pass_data;
case 3:goto fin_ex;
/*272:*/
#line 4851 "mmix-pipe.w"
square_one:data->state= DT_retry;
case DT_retry:if(DTcache->lock||(j= get_reader(DTcache))<0)wait(1);
startup(&DTcache->reader[j],DTcache->access_time);
p= cache_search(DTcache,trans_key(data->y.o));
if(p){
/*269:*/
#line 4776 "mmix-pipe.w"
p= use_and_fix(DTcache,p);
j= PRW_BITS;
if(((p->data[0].l<<PROT_OFFSET)&j)!=j){
if(data->i==syncd||data->i==syncid)goto sync_check;
if(data->i!=preld&&data->i!=prest)
data->interrupt|= j&~(p->data[0].l<<PROT_OFFSET);
goto fin_ex;
}
/*:269*/
#line 4857 "mmix-pipe.w"
;
data->z.o= phys_addr(data->y.o,p->data[0]);
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);
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)
if(data->i==preld||data->i==prest)goto fin_ex;else goto emulate_virt;
p= alloc_slot(DTcache,trans_key(data->y.o));
if(!p)goto square_one;
data->ptr_b= DTcache->filler_ctl.ptr_b= (void*)p;
DTcache->filler_ctl.y.o= data->y.o;
set_lock(self,DTcache->fill_lock);
startup(&DTcache->filler,1);
data->state= got_DT;
if(data->i==preld||data->i==prest)goto fin_ex;else sleep;
case got_DT:release_lock(self,DTcache->fill_lock);
j= PRW_BITS;
if(((data->z.o.l<<PROT_OFFSET)&j)!=j){
if(data->i==syncd||data->i==syncid)goto sync_check;
data->interrupt|= j&~(data->z.o.l<<PROT_OFFSET);
goto fin_ex;
}
data->z.o= phys_addr(data->y.o,data->z.o);
if(data->i>=st&&data->i<=syncid)goto finish_store;
/*:272*//*273:*/
#line 4896 "mmix-pipe.w"
ld_retry:data->state= DT_hit;
case DT_hit:if(data->i==preld||data->i==prest)goto fin_ex;
/*278:*/
#line 4966 "mmix-pipe.w"
{
octa*m= write_search(data,data->z.o);
if(m==DUNNO)wait(1);
if(m){
data->x.o= *m;
data->state= ld_ready;
wait(1);
}
}
/*:278*/
#line 4899 "mmix-pipe.w"
;
if((data->z.o.h&0xffff0000)||!Dcache)
/*277:*/
#line 4957 "mmix-pipe.w"
{
avoid_D:if(mem_lock)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);
}
/*:277*/
#line 4901 "mmix-pipe.w"
;
if(Dcache->lock||(j= get_reader(Dcache))<0)wait(1);
startup(&Dcache->reader[j],Dcache->access_time);
q= cache_search(Dcache,data->z.o);
if(q){
if(data->i==ldunc)q= demote_and_fix(Dcache,q);
else q= use_and_fix(Dcache,q);
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);
case hit_and_miss:if(data->i==ldunc)goto avoid_D;
/*274:*/
#line 4915 "mmix-pipe.w"
/*275:*/
#line 4938 "mmix-pipe.w"
if(data->i==prest&&
(data->xx>=Dcache->bb||((data->y.o.l&(Dcache->bb-1))==0))&&
((data->y.o.l+(data->xx&(Dcache->bb-1))+1)^data->y.o.l)>=Dcache->bb)
goto prest_span;
/*:275*/
#line 4916 "mmix-pipe.w"
;
if(Dcache->filler.next)goto ld_retry;
if((Scache&&Scache->lock)||(!Scache&&mem_lock))goto ld_retry;
q= alloc_slot(Dcache,data->z.o);
if(!q)goto ld_retry;
if(Scache)set_lock(&Dcache->filler,Scache->lock)
else set_lock(&Dcache->filler,mem_lock);
set_lock(self,Dcache->fill_lock);
data->ptr_b= Dcache->filler_ctl.ptr_b= (void*)q;
Dcache->filler_ctl.z.o= data->z.o;
startup(&Dcache->filler,Scache?Scache->access_time:mem_addr_time);
data->state= ld_ready;
if(data->i==preld||data->i==prest)goto fin_ex;else sleep;
/*:274*/
#line 4913 "mmix-pipe.w"
;
/*:273*//*276:*/
#line 4944 "mmix-pipe.w"
prest_span:data->state= prest_win;
case prest_win:if(data!=old_hot||Dlocker.next)wait(1);
if(Dcache->lock)goto fin_ex;
q= alloc_slot(Dcache,data->z.o);
if(q){
clean_block(Dcache,q);
q->tag= data->z.o;q->tag.l&= -Dcache->bb;
set_lock(&Dlocker,Dcache->lock);
startup(&Dlocker,Dcache->copy_in_time);
}
goto fin_ex;
/*:276*//*279:*/
#line 4981 "mmix-pipe.w"
case ld_ready:if(self->lockloc)
*(self->lockloc)= NULL,self->lockloc= NULL;
if(data->i>=st)goto finish_store;
switch(data->op>>1){
case LDB>>1:case LDBU>>1:j= (data->z.o.l&0x7)<<3;i= 56;goto fin_ld;
case LDW>>1:case LDWU>>1:j= (data->z.o.l&0x6)<<3;i= 48;goto fin_ld;
case LDT>>1:case LDTU>>1:j= (data->z.o.l&0x4)<<3;i= 32;
fin_ld:data->x.o= shift_right(shift_left(data->x.o,j),i,data->op&0x2);
default:goto fin_ex;
case LDHT>>1:if(data->z.o.l&4)data->x.o.h= data->x.o.l;
data->x.o.l= 0;goto fin_ex;
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);
}
else data->x.o= load_sf(data->x.o.h);goto fin_ex;
case LDPTP>>1:
if((data->x.o.h&sign_bit)==0||(data->x.o.l&0x1ff8)!=page_n)
data->x.o= zero_octa;
else data->x.o.l&= -(1<<13);
goto fin_ex;
case LDPTE>>1:if((data->x.o.l&0x1ff8)!=page_n)data->x.o= zero_octa;
else data->x.o= incr(oandn(data->x.o,page_mask),data->x.o.l&0x7);
data->x.o.h&= 0xffff;goto fin_ex;
case UNSAVE>>1:/*336:*/
#line 5893 "mmix-pipe.w"
if(data->xx==0){
data->a.o= data->x.o;data->a.o.h&= 0xffffff;
data->x.o.l= data->x.o.h>>24;data->x.o.h= 0;
if(data->a.o.h||(data->a.o.l&0xfffc0000)){
data->a.o.h= 0,data->a.o.l&= 0x3ffff;data->interrupt|= B_BIT;
}
if(data->x.o.l<32){
data->x.o.l= 32;data->interrupt|= B_BIT;
}
}
goto fin_ex;
/*:336*/
#line 5007 "mmix-pipe.w"
;
}
/*:279*//*280:*/
#line 5010 "mmix-pipe.w"
finish_store:data->state= st_ready;
case st_ready:switch(data->i){
case st:case pst:/*281:*/
#line 5023 "mmix-pipe.w"
data->x.addr= data->z.o;
if(data->b.p)wait(1);
switch(data->op>>1){
case STUNC>>1:data->i= stunc;
default:data->x.o= data->b.o;goto fin_ex;
case STSF>>1:set_round;data->b.o.h= store_sf(data->b.o);
data->interrupt|= exceptions;
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);
}
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;
goto fin_ex;
case STB>>1:case STBU>>1:j= (data->z.o.l&0x7)<<3;i= 56;goto fin_st;
case STW>>1:case STWU>>1:j= (data->z.o.l&0x6)<<3;i= 48;goto fin_st;
case STT>>1:case STTU>>1:j= (data->z.o.l&0x4)<<3;i= 32;
fin_st:/*282:*/
#line 5049 "mmix-pipe.w"
{
octa mask;
if(!(data->op&2)){octa before,after;
before= data->b.o;after= shift_right(shift_left(data->b.o,i),i,0);
if(before.l!=after.l||before.h!=after.h)data->interrupt|= V_BIT;
}
mask= shift_right(shift_left(neg_one,i),j,1);
data->b.o= shift_right(shift_left(data->b.o,i),j,1);
data->x.o.h^= mask.h&(data->x.o.h^data->b.o.h);
data->x.o.l^= mask.l&(data->x.o.l^data->b.o.l);
}
/*:282*/
#line 5043 "mmix-pipe.w"
;
goto fin_ex;
case CSWAP>>1:/*283:*/
#line 5067 "mmix-pipe.w"
if(data!=old_hot)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->x.o= data->b.o;
}else{
g[rP].o= data->x.o;
if(verbose&issue_bit){
printf(" setting rP=");print_octa(g[rP].o);printf("\n");
}
}
data->i= cswap;
goto fin_ex;
/*:283*/
#line 5045 "mmix-pipe.w"
;
case SAVE>>1:/*342:*/
#line 5965 "mmix-pipe.w"
{
if(data->interim)data->x.o= data->b.o;
else{
if(data!=old_hot)wait(1);
data->x.o.h= g[rG].o.l<<24;
data->x.o.l= g[rA].o.l;
data->a.o= data->y.o;
}
goto fin_ex;
}
/*:342*/
#line 5046 "mmix-pipe.w"
;
}
/*:281*/
#line 5013 "mmix-pipe.w"
;
case syncd:data->b.o.l= (Dcache?Dcache->bb:8192);goto do_syncd;
case syncid:data->b.o.l= (Icache?Icache->bb:8192);
if(Dcache&&Dcache->bb<data->b.o.l)data->b.o.l= Dcache->bb;
goto do_syncid;
}
/*:280*//*299:*/
#line 5280 "mmix-pipe.w"
case IT_miss:case Ihit_and_miss:case IT_hit:case fetch_ready:goto switch0;
/*:299*//*311:*/
#line 5468 "mmix-pipe.w"
case 4:goto state_4;
case 5:goto state_5;
/*:311*//*354:*/
#line 6188 "mmix-pipe.w"
case ld_st_launch:if(ITcache->lock||(j= get_reader(ITcache))<0)wait(1);
startup(&ITcache->reader[j],ITcache->access_time);
p= cache_search(ITcache,data->y.o);
if(p){
data->x.o.l|= 1;
if(data->z.o.l){
p= use_and_fix(ITcache,p);
p->data[0].l= (p->data[0].l&-8)+data->z.o.l;
}else{
p= demote_and_fix(ITcache,p);
p->tag.h|= sign_bit;
}
}
data->state= 3;wait(ITcache->access_time);
/*:354*//*364:*/
#line 6339 "mmix-pipe.w"
do_syncid:data->state= 30;
case 30:if(data!=old_hot)wait(1);
if(!Icache){
data->state= (data->loc.h&sign_bit?31:33);goto switch2;
}
/*365:*/
#line 6378 "mmix-pipe.w"
if(Icache->lock||(j= get_reader(Icache))<0)wait(1);
startup(&Icache->reader[j],Icache->access_time);
set_lock(self,Icache->lock);
p= cache_search(Icache,data->z.o);
if(p){
demote_and_fix(Icache,p);
clean_block(Icache,p);
}
/*:365*/
#line 6345 "mmix-pipe.w"
;
data->state= (data->loc.h&sign_bit?31:33);wait(Icache->access_time);
case 31:if(self->lockloc)*(self->lockloc)= NULL,self->lockloc= NULL;
/*362:*/
#line 6304 "mmix-pipe.w"
if(write_head!=write_tail){
if(!speed_lock)set_lock(self,speed_lock);
wait(1);
}
/*:362*/
#line 6348 "mmix-pipe.w"
;
if(((data->b.o.l-1)&~data->y.o.l)<data->xx)data->interim= true;
if(!Dcache)goto next_sync;
/*366:*/
#line 6388 "mmix-pipe.w"
if(Dcache->lock||(j= get_reader(Dcache))<0)wait(1);
startup(&Dcache->reader[j],Dcache->access_time);
set_lock(self,Dcache->lock);
p= cache_search(Dcache,data->z.o);
if(p){
demote_and_fix(Dcache,p);
clean_block(Dcache,p);
}
/*:366*/
#line 6351 "mmix-pipe.w"
;
data->state= 32;wait(Dcache->access_time);
case 32:if(self->lockloc)*(self->lockloc)= NULL,self->lockloc= NULL;
if(!Scache)goto next_sync;
/*367:*/
#line 6398 "mmix-pipe.w"
if(Scache->lock)wait(1);
set_lock(self,Scache->lock);
p= cache_search(Scache,data->z.o);
if(p){
demote_and_fix(Scache,p);
clean_block(Scache,p);
}
/*:367*/
#line 6355 "mmix-pipe.w"
;
data->state= 35;wait(Scache->access_time);
do_syncd:data->state= 33;
case 33:if(data!=old_hot)wait(1);
if(self->lockloc)*(self->lockloc)= NULL,self->lockloc= NULL;
/*362:*/
#line 6304 "mmix-pipe.w"
if(write_head!=write_tail){
if(!speed_lock)set_lock(self,speed_lock);
wait(1);
}
/*:362*/
#line 6360 "mmix-pipe.w"
;
if(((data->b.o.l-1)&~data->y.o.l)<data->xx)data->interim= true;
if(!Dcache)
if(data->i==syncd)goto fin_ex;else goto next_sync;
/*368:*/
#line 6407 "mmix-pipe.w"
if(clean_co.next||clean_lock)wait(1);
set_lock(self,clean_lock);
clean_ctl.i= syncd;
clean_ctl.state= 4;
clean_ctl.x.o.h= data->loc.h&sign_bit;
clean_ctl.z.o= data->z.o;
schedule(&clean_co,1,4);
/*:368*/
#line 6364 "mmix-pipe.w"
;
data->state= 34;
case 34:if(!clean_co.next)goto next_sync;
if(trying_to_interrupt&&data->interim&&data==old_hot){
data->z.o= zero_octa;
goto fin_ex;
}
wait(1);
next_sync:data->state= 35;
case 35:if(self->lockloc)*(self->lockloc)= NULL,self->lockloc= NULL;
if(data->interim)/*369:*/
#line 6418 "mmix-pipe.w"
{
data->interim= false;
data->xx-= ((data->b.o.l-1)&~data->y.o.l)+1;
data->y.o= incr(data->y.o,data->b.o.l);
data->y.o.l&= -data->b.o.l;
data->z.o.l= (data->z.o.l&-8192)+(data->y.o.l&8191);
if((data->y.o.l&8191)==0)goto square_one;
if(data->i==syncd)goto do_syncd;else goto do_syncid;
}
/*:369*/
#line 6374 "mmix-pipe.w"
;
data->go.known= true;
goto fin_ex;
/*:364*//*370:*/
#line 6433 "mmix-pipe.w"
sync_check:if((data->y.o.l^(data->y.o.l+data->xx))>=8192){
data->xx-= (8191&~data->y.o.l)+1;
data->y.o= incr(data->y.o,8192);
data->y.o.l&= -8192;
goto square_one;
}
goto fin_ex;
/*:370*/
#line 2532 "mmix-pipe.w"
;
}
/*:135*/
#line 2378 "mmix-pipe.w"
;
/*126:*/
#line 2388 "mmix-pipe.w"
case vanish:goto terminate;
/*:126*//*215:*/
#line 3768 "mmix-pipe.w"
case flush_to_mem:{register cache*c= (cache*)data->ptr_a;
switch(data->state){
case 0:if(mem_lock)wait(1);
data->state= 1;
case 1:set_lock(self,mem_lock);
data->state= 2;
/*216:*/
#line 3780 "mmix-pipe.w"
{
register int off,last_off,count,first,ii;
register int del= c->gg>>3;
octa addr;
addr= c->outbuf.tag;off= (addr.l&0xffff)>>3;
for(i= j= 0,first= 1,count= 0;j<c->bb>>c->g;j++){
ii= i+del;
if(!c->outbuf.dirty[j])i= ii,off+= del,addr.l+= del<<3;
else while(i<ii){
if(first){
count++;last_off= off;first= 0;
mem_write(addr,c->outbuf.data[i]);
}else{
if((off^last_off)&(-bus_words))count++;
last_off= off;
mem_hash[last_h].chunk[off]= c->outbuf.data[i];
}
i++;off++;addr.l+= 8;
}
}
wait(mem_addr_time+count*mem_write_time);
}
/*:216*/
#line 3775 "mmix-pipe.w"
;
case 2:goto terminate;
}
}
/*:215*//*217:*/
#line 3819 "mmix-pipe.w"
case flush_to_S:{register cache*c= (cache*)data->ptr_a;
register int block_diff= Scache->bb-c->bb;
p= (cacheblock*)data->ptr_b;
switch(data->state){
case 0:if(Scache->lock)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);
case 2:/*219:*/
#line 3858 "mmix-pipe.w"
{register int count= block_diff>>3;
register int off,delay;
octa addr;
if(mem_lock)wait(1);
addr.h= c->outbuf.tag.h;addr.l= c->outbuf.tag.l&-Scache->bb;
off= (addr.l&0xffff)>>3;
for(j= 0;j<Scache->bb>>3;j++)
if(j==0)Scache->inbuf.data[j]= mem_read(addr);
else Scache->inbuf.data[j]= mem_hash[last_h].chunk[j+off];
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);
}
/*:219*/
#line 3832 "mmix-pipe.w"
;
case 3:/*218:*/
#line 3848 "mmix-pipe.w"
if(Scache->filler.next)wait(1);
p= alloc_slot(Scache,c->outbuf.tag);
if(!p)wait(1);
data->ptr_b= (void*)p;
p->tag= c->outbuf.tag;p->tag.l= c->outbuf.tag.l&(-Scache->bb);
/*:218*/
#line 3833 "mmix-pipe.w"
;
if(block_diff)/*220:*/
#line 3874 "mmix-pipe.w"
{
register octa*d= p->data;
p->data= Scache->inbuf.data;Scache->inbuf.data= d;
}
/*:220*/
#line 3834 "mmix-pipe.w"
;
case 4:copy_block(c,&(c->outbuf),Scache,p);
hit_set= cache_addr(Scache,c->outbuf.tag);use_and_fix(Scache,p);
data->state= 5;wait(Scache->copy_in_time);
case 5:if((Scache->mode&WRITE_BACK)==0){
if(Scache->flusher.next)wait(1);
flush_cache(Scache,p,true);
}
goto terminate;
case 6:/*221:*/
#line 3882 "mmix-pipe.w"
if(Scache->flusher.next)wait(1);
Scache->outbuf.tag.h= c->outbuf.tag.h;
Scache->outbuf.tag.l= c->outbuf.tag.l&(-Scache->bb);
for(j= 0;j<Scache->bb>>Scache->g;j++)Scache->outbuf.dirty[j]= false;
copy_block(c,&(c->outbuf),Scache,&(Scache->outbuf));
startup(&Scache->flusher,Scache->copy_out_time);
goto terminate;
/*:221*/
#line 3844 "mmix-pipe.w"
;
}
}
/*:217*//*222:*/
#line 3911 "mmix-pipe.w"
case fill_from_mem:{register cache*c= (cache*)data->ptr_a;
register coroutine*cc= c->fill_lock;
switch(data->state){
case 0:data->x.o= mem_read(data->z.o);
if(cc){
cc->ctl->x.o= data->x.o;
awaken(cc,mem_read_time);
}
data->state= 1;
/*223:*/
#line 3938 "mmix-pipe.w"
{
register int count,off;
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;i<count;i++,off++)c->inbuf.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);
}
/*:223*/
#line 3921 "mmix-pipe.w"
;
case 1:release_lock(self,mem_lock);
data->state= 2;
case 2:if(c!=Scache){
if(c->lock)wait(1);
set_lock(self,c->lock);
}
if(cc)awaken(cc,c->copy_in_time);
load_cache(c,(cacheblock*)data->ptr_b);
data->state= 3;wait(c->copy_in_time);
case 3:goto terminate;
}
}
/*:222*//*224:*/
#line 3953 "mmix-pipe.w"
case fill_from_S:{register cache*c= (cache*)data->ptr_a;
register coroutine*cc= c->fill_lock;
p= (cacheblock*)data->ptr_c;
switch(data->state){
case 0:p= cache_search(Scache,data->z.o);
if(p)goto S_non_miss;
data->state= 1;
case 1:/*225:*/
#line 3991 "mmix-pipe.w"
if(Scache->filler.next||mem_lock)wait(1);
p= alloc_slot(Scache,data->z.o);
if(!p)wait(1);
set_lock(&Scache->filler,mem_lock);
set_lock(self,Scache->fill_lock);
data->ptr_c= Scache->filler_ctl.ptr_b= (void*)p;
Scache->filler_ctl.z.o= data->z.o;
startup(&Scache->filler,mem_addr_time);
/*:225*/
#line 3961 "mmix-pipe.w"
;
data->state= 2;sleep;
case 2:if(cc){
cc->ctl->x.o= data->x.o;
awaken(cc,Scache->access_time);
}
data->state= 3;sleep;
S_non_miss:if(cc){
cc->ctl->x.o= p->data[(data->z.o.l&(Scache->bb-1))>>3];
awaken(cc,Scache->access_time);
}
case 3:/*226:*/
#line 4004 "mmix-pipe.w"
{register int off;
c->inbuf.tag= data->z.o;c->inbuf.tag.l&= -c->bb;
for(j= 0,off= (c->inbuf.tag.l&(Scache->bb-1))>>3;j<c->bb>>3;j++,off++)
c->inbuf.data[j]= p->data[off];
release_lock(self,Scache->fill_lock);
set_lock(self,Scache->lock);
}
/*:226*/
#line 3973 "mmix-pipe.w"
;
data->state= 4;wait(Scache->access_time);
case 4:if(c->lock)wait(1);
set_lock(self,c->lock);
Scache->lock= NULL;
load_cache(c,(cacheblock*)data->ptr_b);
data->state= 5;wait(c->copy_in_time);
case 5:if(cc)awaken(cc,1);
goto terminate;
}
}
/*:224*//*232:*/
#line 4075 "mmix-pipe.w"
case cleanup:p= (cacheblock*)data->ptr_b;
switch(data->state){
/*233:*/
#line 4083 "mmix-pipe.w"
case 0:if(Dcache->lock||(j= get_reader(Dcache)<0))wait(1);
startup(&Dcache->reader[j],Dcache->access_time);
set_lock(self,Dcache->lock);
i= j= 0;
Dclean_loop:p= (i<Dcache->cc?&(Dcache->set[i][j]):&(Dcache->victim[j]));
if(p->tag.h&sign_bit)goto Dclean_inc;
if(!is_dirty(Dcache,p)){
p->tag.h|= data->x.o.h;goto Dclean_inc;
}
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);
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);
case 2:if(!clean_lock)goto done;
if(Dcache->flusher.next)wait(1);
if(data->i!=sync)goto Sprep;
data->state= 3;
case 3:if(Dcache->lock||(j= get_reader(Dcache)<0))wait(1);
startup(&Dcache->reader[j],Dcache->access_time);
set_lock(self,Dcache->lock);
i= data->y.o.h,j= data->y.o.l;
Dclean_inc:j++;
if(i<Dcache->cc&&j==Dcache->aa)j= 0,i++;
if(i==Dcache->cc&&j==Dcache->vv){
data->state= 5;
wait(Dcache->access_time);
}
goto Dclean_loop;
case 4:if(Dcache->lock||(j= get_reader(Dcache)<0))wait(1);
startup(&Dcache->reader[j],Dcache->access_time);
set_lock(self,Dcache->lock);
p= cache_search(Dcache,data->z.o);
if(p){
demote_and_fix(Dcache,p);
if(is_dirty(Dcache,p))goto Dclean;
}
data->state= 9;
wait(Dcache->access_time);
/*:233*/
#line 4078 "mmix-pipe.w"
;
/*234:*/
#line 4129 "mmix-pipe.w"
case 5:if(self->lockloc)*(self->lockloc)= NULL,self->lockloc= NULL;
if(!Scache)goto done;
if(Scache->lock)wait(1);
set_lock(self,Scache->lock);
i= j= 0;
Sclean_loop:p= (i<Scache->cc?&(Scache->set[i][j]):&(Scache->victim[j]));
if(p->tag.h&sign_bit)goto Sclean_inc;
if(!is_dirty(Scache,p)){
p->tag.h|= data->x.o.h;goto Sclean_inc;
}
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);
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);
case 7:if(!clean_lock)goto done;
if(Scache->flusher.next)wait(1);
if(data->i!=sync)goto done;
data->state= 8;
case 8:if(Scache->lock)wait(1);
set_lock(self,Scache->lock);
i= data->y.o.h,j= data->y.o.l;
Sclean_inc:j++;
if(i<Scache->cc&&j==Scache->aa)j= 0,i++;
if(i==Scache->cc&&j==Scache->vv){
data->state= 10;
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);
set_lock(self,Scache->lock);
p= cache_search(Scache,data->z.o);
if(p){
demote_and_fix(Scache,p);
if(is_dirty(Scache,p))goto Sclean;
}
data->state= 10;
wait(Scache->access_time);
/*:234*/
#line 4079 "mmix-pipe.w"
;
case 10:goto terminate;
}
/*:232*//*237:*/
#line 4244 "mmix-pipe.w"
case fill_from_virt:{register cache*c= (cache*)data->ptr_a;
register coroutine*cc= c->fill_lock;
register coroutine*co= (coroutine*)data->ptr_c;
octa aaaaa;
switch(data->state){
case 0:/*243:*/
#line 4329 "mmix-pipe.w"
aaaaa= data->y.o;
i= aaaaa.h>>29;
aaaaa.h&= 0x1fffffff;
aaaaa= shift_right(aaaaa,page_s,1);
for(j= 0;aaaaa.l!=0||aaaaa.h!=0;j++){
co[2*j].ctl->z.o.h= 0,co[2*j].ctl->z.o.l= (aaaaa.l&0x3ff)<<3;
aaaaa= shift_right(aaaaa,10,1);
}
if(page_b[i+1]<page_b[i]+j)
;
else{
if(j==0)j= 1,co[0].ctl->z.o= zero_octa;
/*244:*/
#line 4349 "mmix-pipe.w"
j--;
aaaaa.l= page_r+page_b[i]+j;
co[2*j].ctl->y.p= NULL;
co[2*j].ctl->y.o= shift_left(aaaaa,13);
co[2*j].ctl->y.o.h+= sign_bit;
for(;;j--){
co[2*j].ctl->x.o= zero_octa;co[2*j].ctl->x.known= false;
co[2*j].ctl->owner= &co[2*j];
startup(&co[2*j],1);
if(j==0)break;
co[2*(j-1)].ctl->y.p= &co[2*j].ctl->x;
}
data->b.p= &co[0].ctl->x;
/*:244*/
#line 4342 "mmix-pipe.w"
;
}
/*:243*/
#line 4251 "mmix-pipe.w"
;
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);
}
/*245:*/
#line 4370 "mmix-pipe.w"
c->inbuf.tag= trans_key(data->y.o);
c->inbuf.data[0]= data->b.o;
if(cc){
cc->ctl->z.o= data->b.o;
awaken(cc,1);
}
/*:245*/
#line 4258 "mmix-pipe.w"
;
data->state= 2;
case 2:if(c->lock)wait(1);
set_lock(self,c->lock);
load_cache(c,(cacheblock*)data->ptr_b);
data->state= 3;wait(c->copy_in_time);
case 3:data->b.o= zero_octa;goto terminate;
}
}
/*:237*//*257:*/
#line 4541 "mmix-pipe.w"
case write_from_wbuf:
p= (cacheblock*)data->ptr_b;
switch(data->state){
case 4:/*263:*/
#line 4630 "mmix-pipe.w"
if((Dcache->mode&WRITE_BACK)==0){
if(Dcache->flusher.next)wait(1);
flush_cache(Dcache,p,true);
}
/*:263*/
#line 4545 "mmix-pipe.w"
;
data->state= 5;
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);
if(write_head->i==sync)/*264:*/
#line 4636 "mmix-pipe.w"
{
set_lock(self,wbuf_lock);
data->state= 5;
wait(1);
}
/*:264*/
#line 4551 "mmix-pipe.w"
;
if(ticks.l-write_head->stamp<holding_time&&!speed_lock)
wait(1);
if(!Dcache||(write_head->addr.h&0xffff0000))goto mem_direct;
if(Dcache->lock||(j= get_reader(Dcache)<0))wait(1);
startup(&Dcache->reader[j],Dcache->access_time);
/*262:*/
#line 4619 "mmix-pipe.w"
p= cache_search(Dcache,write_head->addr);
if(p){
p= use_and_fix(Dcache,p);
set_lock(self,wbuf_lock);
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);
}
/*:262*/
#line 4559 "mmix-pipe.w"
;
data->state= ((Dcache->mode&WRITE_ALLOC)&&write_head->i!=stunc?1:3);
wait(Dcache->access_time);
case 1:/*261:*/
#line 4601 "mmix-pipe.w"
if(Dcache->filler.next)goto write_restart;
if((Scache&&Scache->lock)||(!Scache&&mem_lock))goto write_restart;
p= alloc_slot(Dcache,write_head->addr);
if(!p)goto write_restart;
if(Scache)set_lock(&Dcache->filler,Scache->lock)
else set_lock(&Dcache->filler,mem_lock);
set_lock(self,Dcache->fill_lock);
data->ptr_b= Dcache->filler_ctl.ptr_b= (void*)p;
Dcache->filler_ctl.z.o= write_head->addr;
startup(&Dcache->filler,Scache?Scache->access_time:mem_addr_time);
/*:261*/
#line 4563 "mmix-pipe.w"
;
data->state= 2;sleep;
case 2:data->state= 0;sleep;
case 3:/*259:*/
#line 4577 "mmix-pipe.w"
if(Dcache->flusher.next)wait(1);
Dcache->outbuf.tag.h= write_head->addr.h;
Dcache->outbuf.tag.l= write_head->addr.l&(-Dcache->bb);
for(j= 0;j<Dcache->bb>>Dcache->g;j++)Dcache->outbuf.dirty[j]= false;
Dcache->outbuf.data[(write_head->addr.l&(Dcache->bb-1))>>3]= write_head->o;
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);
/*:259*/
#line 4566 "mmix-pipe.w"
;
mem_direct:/*260:*/
#line 4588 "mmix-pipe.w"
if(mem_lock)wait(1);
set_lock(self,wbuf_lock);
set_lock(&mem_locker,mem_lock);
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);
/*:260*/
#line 4567 "mmix-pipe.w"
;
}
/*:257*/
#line 2379 "mmix-pipe.w"
;
}
terminate:if(self->lockloc)*(self->lockloc)= NULL,self->lockloc= NULL;
done:;
}
/*:125*/
#line 1439 "mmix-pipe.w"
;
if(!suppress_dispatch)/*74:*/
#line 1582 "mmix-pipe.w"
{register fetch*true_head,*new_head;
true_head= head;
if(head==old_tail&&head!=tail)
old_tail= (head==fetch_bot?fetch_top:head-1);
peek_hist= cool_hist;
for(j= 0;j<dispatch_max+peekahead;j++)
/*75:*/
#line 1594 "mmix-pipe.w"
{
register mmix_opcode op;
register int yz,f;
register bool freeze_dispatch= false;
register func*u= NULL;
if(head==old_tail)break;
if(head==fetch_bot)new_head= fetch_top;else new_head= head-1;
op= head->inst>>24;yz= head->inst&0xffff;
/*80:*/
#line 1660 "mmix-pipe.w"
if(!(support[op>>5]&(sign_bit>>(op&31)))){
f= flags[TRAP],i= trap;
}else f= flags[op],i= internal_op[op];
if(i==trip&&(head->loc.h&sign_bit))f= 0,i= noop;
/*:80*/
#line 1603 "mmix-pipe.w"
;
/*100:*/
#line 1957 "mmix-pipe.w"
cool->op= op;cool->i= i;
cool->xx= (head->inst>>16)&0xff;
cool->yy= (head->inst>>8)&0xff;
cool->zz= (head->inst)&0xff;
cool->loc= head->loc;
cool->y= cool->z= cool->b= cool->ra= zero_spec;
cool->x.o= cool->a.o= cool->rl.o= zero_octa;
cool->x.known= false;cool->x.up= NULL;
cool->a.known= false;cool->a.up= NULL;
cool->rl.known= true;cool->rl.up= NULL;
cool->need_b= cool->need_ra=
cool->ren_x= cool->mem_x= cool->ren_a= cool->set_l= false;
cool->arith_exc= cool->denin= cool->denout= 0;
if((head->loc.h&sign_bit)&&!(g[rU].o.h&0x8000))cool->usage= false;
else cool->usage= ((op&(g[rU].o.h>>16))==g[rU].o.h>>24?true:false);
new_O= cool->cur_O= cool_O;new_S= cool->cur_S= cool_S;
cool->interrupt= head->interrupt;
cool->hist= peek_hist;
cool->go.o= incr(cool->loc,4);
cool->go.known= false,cool->go.addr.h= -1,cool->go.up= (specnode*)cool;
cool->interim= false;
/*:100*/
#line 1604 "mmix-pipe.w"
;
if(f&rel_addr_bit)/*84:*/
#line 1760 "mmix-pipe.w"
{
if(i==jmp)yz= head->inst&0xffffff;
if(op&1)yz-= (i==jmp?0x1000000:0x10000);
cool->y.o= incr(head->loc,4),cool->y.p= NULL;
cool->z.o= incr(head->loc,yz<<2),cool->z.p= NULL;
}
/*:84*/
#line 1605 "mmix-pipe.w"
;
if(head->noted)peek_hist= head->hist;
else/*85:*/
#line 1772 "mmix-pipe.w"
{register int predicted= 0;
if((op&0xe0)==0x40)/*151:*/
#line 2832 "mmix-pipe.w"
{
predicted= op&0x10;
if(bp_table){register int h;
m= ((head->loc.l&bp_cmask)<<bp_b)+(head->loc.l&bp_amask);
m= ((cool_hist&bp_bcmask)<<bp_a)^(m>>2);
h= bp_table[m];
if(h&bp_npower)predicted^= 0x10;
}
if(predicted)peek_hist= (peek_hist<<1)+1;
else peek_hist<<= 1;
}
/*:151*/
#line 1774 "mmix-pipe.w"
;
head->noted= true;
head->hist= peek_hist;
if(predicted||(f&ctl_change_bit)||(i==syncid&&!(cool->loc.h&sign_bit))){
old_tail= tail= new_head;
/*287:*/
#line 5125 "mmix-pipe.w"
if(fetch_co.lockloc)*(fetch_co.lockloc)= NULL,fetch_co.lockloc= NULL;
unschedule(&fetch_co);
startup(&fetch_co,1);
/*:287*/
#line 1779 "mmix-pipe.w"
;
switch(i){
case jmp:case br:case pbr:case pushj:inst_ptr= cool->z;break;
case pop:if(g[rJ].up->known&&
j<dispatch_max&&!dispatch_lock&&!nullifying){
inst_ptr.o= incr(g[rJ].up->o,yz<<2),inst_ptr.p= NULL;break;
}
case go:case pushgo:case trap:case resume:case syncid:
inst_ptr.p= UNKNOWN_SPEC;break;
case trip:inst_ptr= zero_spec;break;
}
}
}
/*:85*/
#line 1607 "mmix-pipe.w"
;
if(j>=dispatch_max||dispatch_lock||nullifying){
head= new_head;continue;
}
if(cool==reorder_bot)new_cool= reorder_top;else new_cool= cool-1;
/*101:*/
#line 1980 "mmix-pipe.w"
if(new_cool==hot)goto stall;
/*102:*/
#line 1996 "mmix-pipe.w"
if(!g[rL].up->known)goto stall;
cool_L= g[rL].up->o.l;
if(!g[rG].up->known&&!(op==UNSAVE&&cool->xx==1))goto stall;
cool_G= g[rG].up->o.l;
/*:102*/
#line 1982 "mmix-pipe.w"
;
/*103:*/
#line 2002 "mmix-pipe.w"
if(resuming)
/*324:*/
#line 5714 "mmix-pipe.w"
{
if(resuming&1){
cool->y= specval(&g[rY]);
cool->z= specval(&g[rZ]);
}else{
cool->y= specval(&g[rYY]);
cool->z= specval(&g[rZZ]);
}
if(resuming>=3){
cool->need_ra= true,cool->ra= specval(&g[rA]);
}
cool->usage= false;
}
/*:324*/
#line 2004 "mmix-pipe.w"
else{
if(f&0x10)/*106:*/
#line 2028 "mmix-pipe.w"
{
if(cool->xx>=cool_G)cool->b= specval(&g[cool->xx]);
else if(cool->xx<cool_L)
cool->b= specval(&l[(cool_O.l+cool->xx)&lring_mask]);
if(f&rel_addr_bit)cool->need_b= true;
}
/*:106*/
#line 2006 "mmix-pipe.w"
if(third_operand[op]&&(cool->i!=trap))
/*108:*/
#line 2077 "mmix-pipe.w"
{
if(third_operand[op]==rA||third_operand[op]==rE)
cool->need_ra= true,cool->ra= specval(&g[rA]);
if(third_operand[op]!=rA)
cool->need_b= true,cool->b= specval(&g[third_operand[op]]);
}
/*:108*/
#line 2008 "mmix-pipe.w"
;
if(f&0x1)cool->z.o.l= cool->zz;
else if(f&0x2)/*104:*/
#line 2016 "mmix-pipe.w"
{
if(cool->zz>=cool_G)cool->z= specval(&g[cool->zz]);
else if(cool->zz<cool_L)cool->z= specval(&l[(cool_O.l+cool->zz)&lring_mask]);
}
/*:104*/
#line 2010 "mmix-pipe.w"
else if((op&0xf0)==0xe0)/*109:*/
#line 2085 "mmix-pipe.w"
{switch(op&3){
case 0:cool->z.o.h= yz<<16;break;
case 1:cool->z.o.h= yz;break;
case 2:cool->z.o.l= yz<<16;break;
case 3:cool->z.o.l= yz;break;
}
if(i!=set){
cool->y= cool->b;cool->b= zero_spec;
}
}
/*:109*/
#line 2011 "mmix-pipe.w"
;
if(f&0x4)cool->y.o.l= cool->yy;
else if(f&0x8)/*105:*/
#line 2022 "mmix-pipe.w"
{
if(cool->yy>=cool_G)cool->y= specval(&g[cool->yy]);
else if(cool->yy<cool_L)cool->y= specval(&l[(cool_O.l+cool->yy)&lring_mask]);
}
/*:105*/
#line 2013 "mmix-pipe.w"
}
/*:103*/
#line 1983 "mmix-pipe.w"
;
if(f&X_is_dest_bit)/*110:*/
#line 2097 "mmix-pipe.w"
{
if(cool->xx>=cool_G){
if(i!=pushgo&&i!=pushj)
cool->ren_x= true,spec_install(&g[cool->xx],&cool->x);
}else if(cool->xx<cool_L)
cool->ren_x= true,
spec_install(&l[(cool_O.l+cool->xx)&lring_mask],&cool->x);
else{
increase_L:if(((cool_S.l-cool_O.l-cool_L-1)&lring_mask)==0)
/*113:*/
#line 2140 "mmix-pipe.w"
{
cool->need_b= cool->need_ra= false;
cool->i= incgamma;
new_S= incr(cool_S,1);
cool->b= specval(&l[cool_S.l&lring_mask]);
cool->y.p= NULL,cool->y.o= shift_left(cool_S,3);
cool->z= zero_spec;
cool->mem_x= true,spec_install(&mem,&cool->x);
op= STOU;
cool->interim= true;
goto dispatch_done;
}
/*:113*/
#line 2107 "mmix-pipe.w"
else/*112:*/
#line 2122 "mmix-pipe.w"
{
cool->i= incrl;
spec_install(&l[(cool_O.l+cool_L)&lring_mask],&cool->x);
cool->need_b= cool->need_ra= false;
cool->y= cool->z= zero_spec;
cool->x.known= true;
spec_install(&g[rL],&cool->rl);
cool->rl.o.l= cool_L+1;
cool->ren_x= cool->set_l= true;
op= SETH;
cool->interim= true;
goto dispatch_done;
}
/*:112*/
#line 2108 "mmix-pipe.w"
;
}
}
/*:110*/
#line 1985 "mmix-pipe.w"
;
switch(i){
/*117:*/
#line 2189 "mmix-pipe.w"
case cswap:cool->ren_a= true;
spec_install(cool->xx>=cool_G?&g[cool->xx]:
&l[(cool_O.l+cool->xx)&lring_mask],&cool->a);
cool->i= pst;
case st:if((op&0xfe)==STCO)cool->b.o.l= cool->xx;
case pst:
cool->mem_x= true,spec_install(&mem,&cool->x);break;
case ld:case ldunc:cool->ptr_a= (void*)mem.up;break;
/*:117*//*118:*/
#line 2205 "mmix-pipe.w"
case put:if(cool->yy!=0||cool->xx>=32)goto illegal_inst;
if(cool->xx>=8){
if(cool->xx<=11)goto illegal_inst;
if(cool->xx<=18&&!(cool->loc.h&sign_bit))goto privileged_inst;
}
if(cool->xx>=15&&cool->xx<=20)freeze_dispatch= true;
cool->ren_x= true,spec_install(&g[cool->xx],&cool->x);break;
case get:if(cool->yy||cool->zz>=32)goto illegal_inst;
if(cool->zz==rO)cool->z.o= shift_left(cool_O,3);
else if(cool->zz==rS)cool->z.o= shift_left(cool_S,3);
else cool->z= specval(&g[cool->zz]);break;
illegal_inst:cool->interrupt|= B_BIT;goto noop_inst;
case ldvts:if(cool->loc.h&sign_bit)break;
privileged_inst:cool->interrupt|= K_BIT;
noop_inst:cool->i= noop;break;
/*:118*//*119:*/
#line 2229 "mmix-pipe.w"
case pushgo:inst_ptr.p= &cool->go;
case pushj:{register int x= cool->xx;
if(x>=cool_G){
if(((cool_S.l-cool_O.l-cool_L-1)&lring_mask)==0)
/*113:*/
#line 2140 "mmix-pipe.w"
{
cool->need_b= cool->need_ra= false;
cool->i= incgamma;
new_S= incr(cool_S,1);
cool->b= specval(&l[cool_S.l&lring_mask]);
cool->y.p= NULL,cool->y.o= shift_left(cool_S,3);
cool->z= zero_spec;
cool->mem_x= true,spec_install(&mem,&cool->x);
op= STOU;
cool->interim= true;
goto dispatch_done;
}
/*:113*/
#line 2234 "mmix-pipe.w"
x= cool_L;cool_L++;
cool->ren_x= true,spec_install(&l[(cool_O.l+x)&lring_mask],&cool->x);
}
cool->x.known= true,cool->x.o.h= 0,cool->x.o.l= x;
cool->ren_a= true,spec_install(&g[rJ],&cool->a);
cool->a.known= true,cool->a.o= incr(cool->loc,4);
cool->set_l= true,spec_install(&g[rL],&cool->rl);
cool->rl.o.l= cool_L-x-1;
new_O= incr(cool_O,x+1);
}break;
case syncid:if(cool->loc.h&sign_bit)break;
case go:inst_ptr.p= &cool->go;break;
/*:119*//*120:*/
#line 2256 "mmix-pipe.w"
case pop:if(cool->xx&&cool_L>=cool->xx)
cool->y= specval(&l[(cool_O.l+cool->xx-1)&lring_mask]);
pop_unsave:if(cool_S.l==cool_O.l)
/*114:*/
#line 2157 "mmix-pipe.w"
{
cool->i= decgamma;
new_S= incr(cool_S,-1);
cool->z= cool->b= zero_spec;cool->need_b= false;
cool->y.p= NULL,cool->y.o= shift_left(new_S,3);
cool->ren_x= true,spec_install(&l[new_S.l&lring_mask],&cool->x);
op= LDOU;
cool->interim= true;
cool->ptr_a= (void*)mem.up;
goto dispatch_done;
}
/*:114*/
#line 2260 "mmix-pipe.w"
;
{register tetra x;register int new_L;
register specnode*p= l[(cool_O.l-1)&lring_mask].up;
if(p->known)x= (p->o.l)&0xff;else goto stall;
if((tetra)(cool_O.l-cool_S.l)<=x)
/*114:*/
#line 2157 "mmix-pipe.w"
{
cool->i= decgamma;
new_S= incr(cool_S,-1);
cool->z= cool->b= zero_spec;cool->need_b= false;
cool->y.p= NULL,cool->y.o= shift_left(new_S,3);
cool->ren_x= true,spec_install(&l[new_S.l&lring_mask],&cool->x);
op= LDOU;
cool->interim= true;
cool->ptr_a= (void*)mem.up;
goto dispatch_done;
}
/*:114*/
#line 2265 "mmix-pipe.w"
;
new_O= incr(cool_O,-x-1);
if(cool->i==pop)new_L= x+(cool->xx<=cool_L?cool->xx:cool_L+1);
else new_L= x;
if(new_L> cool_G)new_L= cool_G;
if(x<new_L)
cool->ren_x= true,spec_install(&l[(cool_O.l-1)&lring_mask],&cool->x);
cool->set_l= true,spec_install(&g[rL],&cool->rl);
cool->rl.o.l= new_L;
if(cool->i==pop){
cool->z.o.l= yz<<2;
if(inst_ptr.p==UNKNOWN_SPEC&&new_head==tail)inst_ptr.p= &cool->go;
}
break;
}
/*:120*//*121:*/
#line 2281 "mmix-pipe.w"
case mulu:cool->ren_a= true,spec_install(&g[rH],&cool->a);break;
case div:case divu:cool->ren_a= true,spec_install(&g[rR],&cool->a);break;
/*:121*//*122:*/
#line 2302 "mmix-pipe.w"
case noop:if(cool->interrupt&F_BIT){
cool->go.o= cool->y.o= cool->loc;
inst_ptr= specval(&g[rT]);
}
break;
/*:122*//*227:*/
#line 4021 "mmix-pipe.w"
case preld:case prest:if(!Dcache)goto noop_inst;
if(cool->xx>=Dcache->bb)cool->interim= true;
cool->ptr_a= (void*)mem.up;break;
case prego:if(!Icache)goto noop_inst;
if(cool->xx>=Icache->bb)cool->interim= true;
cool->ptr_a= (void*)mem.up;break;
/*:227*//*312:*/
#line 5472 "mmix-pipe.w"
case trap:if((flags[op]&X_is_dest_bit)&&
cool->xx<cool_G&&cool->xx>=cool_L)
goto increase_L;
if(!g[rT].up->known||!g[rJ].up->known)goto stall;
inst_ptr= specval(&g[rT]);
cool->need_b= true,cool->b= specval(&g[255]);
case trip:if(!g[rJ].up->known)goto stall;
cool->ren_x= true,spec_install(&g[255],&cool->x);
cool->x.known= true,cool->x.o= g[rJ].up->o;
if(i==trip)cool->go.o= zero_octa;
cool->ren_a= true,spec_install(&g[i==trap?rBB:rB],&cool->a);break;
/*:312*//*322:*/
#line 5647 "mmix-pipe.w"
case resume:if(cool!=old_hot)goto stall;
inst_ptr= specval(&g[cool->zz?rWW:rW]);
if(!(cool->loc.h&sign_bit)){
if(cool->zz)cool->interrupt|= K_BIT;
else if(inst_ptr.o.h&sign_bit)cool->interrupt|= P_BIT;
}
if(cool->interrupt){
inst_ptr.o= incr(cool->loc,4);cool->i= noop;
}else{
cool->go.o= inst_ptr.o;
if(cool->zz){
/*372:*/
#line 6460 "mmix-pipe.w"
if(cool->loc.l==g[rT].o.l&&cool->loc.h==g[rT].o.h){
register unsigned char yy,zz;octa ma,mb;
if(g[rXX].o.l&0xffff0000)goto magic_done;
yy= g[rXX].o.l>>8,zz= g[rXX].o.l&0xff;
if(yy> max_sys_call)goto magic_done;
/*380:*/
#line 6597 "mmix-pipe.w"
if(arg_count[yy]==3){
octa arg_loc;
arg_loc= g[rBB].o;
if(arg_loc.h&0x9fffffff)mb= zero_octa;
else arg_loc.h>>= 29,mb= magic_read(arg_loc);
arg_loc= incr(g[rBB].o,8);
if(arg_loc.h&0x9fffffff)ma= zero_octa;
else arg_loc.h>>= 29,ma= magic_read(arg_loc);
}
/*:380*/
#line 6467 "mmix-pipe.w"
;
switch(yy){
case Halt:/*373:*/
#line 6484 "mmix-pipe.w"
if(!zz)halted= true;
else if(zz==1){
octa trap_loc;
trap_loc= incr(g[rWW].o,-4);
if(!(trap_loc.h||trap_loc.l>=0x90))
print_trip_warning(trap_loc.l>>4,incr(g[rW].o,-4));
}
/*:373*/
#line 6469 "mmix-pipe.w"
;break;
case Fopen:g[rBB].o= mmix_fopen(zz,mb,ma);break;
case Fclose:g[rBB].o= mmix_fclose(zz);break;
case Fread:g[rBB].o= mmix_fread(zz,mb,ma);break;
case Fgets:g[rBB].o= mmix_fgets(zz,mb,ma);break;
case Fgetws:g[rBB].o= mmix_fgetws(zz,mb,ma);break;
case Fwrite:g[rBB].o= mmix_fwrite(zz,mb,ma);break;
case Fputs:g[rBB].o= mmix_fputs(zz,g[rBB].o);break;
case Fputws:g[rBB].o= mmix_fputws(zz,g[rBB].o);break;
case Fseek:g[rBB].o= mmix_fseek(zz,g[rBB].o);break;
case Ftell:g[rBB].o= mmix_ftell(zz);break;
}
magic_done:g[255].o= neg_one;
}
/*:372*/
#line 5659 "mmix-pipe.w"
;
cool->ren_a= true,spec_install(&g[rK],&cool->a);
cool->a.known= true,cool->a.o= g[255].o;
cool->ren_x= true,spec_install(&g[255],&cool->x);
cool->x.known= true,cool->x.o= g[rBB].o;
}
cool->b= specval(&g[cool->zz?rXX:rX]);
if(!(cool->b.o.h&sign_bit))/*323:*/
#line 5682 "mmix-pipe.w"
{
cool->xx= cool->b.o.h>>24,cool->i= resum;
head->loc= incr(inst_ptr.o,-4);
switch(cool->xx){
case RESUME_SET:cool->b.o.l= (SETH<<24)+(cool->b.o.l&0xff0000);
head->interrupt|= cool->b.o.h&0xff00;
resuming= 2;
case RESUME_CONT:resuming+= 1+cool->zz;
if(((cool->b.o.l>>24)&0xfa)!=0xb8){
m= cool->b.o.l>>28;
if((1<<m)&0x8f30)goto bad_resume;
m= (cool->b.o.l>>16)&0xff;
if(m>=cool_L&&m<cool_G)goto bad_resume;
}
case RESUME_AGAIN:resume_again:head->inst= cool->b.o.l;
m= head->inst>>24;
if(m==RESUME)goto bad_resume;
if(!cool->zz&&
m> RESUME&&m<=SYNC&&(head->inst&bad_inst_mask[m-RESUME]))
head->interrupt|= B_BIT;
head->noted= false;break;
case RESUME_TRANS:if(cool->zz){
cool->y= specval(&g[rYY]),cool->z= specval(&g[rZZ]);
if((cool->b.o.l>>24)!=SWYM)goto resume_again;
cool->i= resume;break;
}
default:bad_resume:cool->interrupt|= B_BIT,cool->i= noop;
resuming= 0;break;
}
}
/*:323*/
#line 5666 "mmix-pipe.w"
;
}break;
/*:322*//*332:*/
#line 5853 "mmix-pipe.w"
case unsave:if(cool->interrupt&B_BIT)cool->i= noop;
else{
cool->interim= true;
op= LDOU;
cool->i= unsav;
switch(cool->xx){
case 0:if(cool->z.p)goto stall;
/*334:*/
#line 5876 "mmix-pipe.w"
cool->ren_x= true,spec_install(&g[rG],&cool->x);
cool->ren_a= true,spec_install(&g[rA],&cool->a);
new_O= new_S= shift_right(cool->z.o,3,1);
cool->set_l= true,spec_install(&g[rL],&cool->rl);
cool->ptr_a= (void*)mem.up;
/*:334*/
#line 5861 "mmix-pipe.w"
;break;
case 1:case 2:/*333:*/
#line 5870 "mmix-pipe.w"
cool->ren_x= true,spec_install(&g[cool->yy],&cool->x);
new_O= new_S= incr(cool_O,-1);
cool->z.o= shift_left(new_O,3);
cool->ptr_a= (void*)mem.up;
/*:333*/
#line 5862 "mmix-pipe.w"
;break;
case 3:cool->i= unsave,cool->interim= false,op= UNSAVE;
goto pop_unsave;
default:cool->interim= false,cool->i= noop,cool->interrupt|= B_BIT;break;
}
}
break;
/*:332*//*337:*/
#line 5908 "mmix-pipe.w"
case save:if(cool->xx<cool_G)cool->interrupt|= B_BIT;
if(cool->interrupt&B_BIT)cool->i= noop;
else if(((cool_S.l-cool_O.l-cool_L-1)&lring_mask)==0)
/*113:*/
#line 2140 "mmix-pipe.w"
{
cool->need_b= cool->need_ra= false;
cool->i= incgamma;
new_S= incr(cool_S,1);
cool->b= specval(&l[cool_S.l&lring_mask]);
cool->y.p= NULL,cool->y.o= shift_left(cool_S,3);
cool->z= zero_spec;
cool->mem_x= true,spec_install(&mem,&cool->x);
op= STOU;
cool->interim= true;
goto dispatch_done;
}
/*:113*/
#line 5912 "mmix-pipe.w"
else{
cool->interim= true;
cool->i= sav;
switch(cool->zz){
case 0:/*338:*/
#line 5931 "mmix-pipe.w"
cool->zz= 1;
cool->ren_x= true,spec_install(&l[(cool_O.l+cool_L)&lring_mask],&cool->x);
cool->x.known= true,cool->x.o.h= 0,cool->x.o.l= cool_L;
cool->set_l= true,spec_install(&g[rL],&cool->rl);
new_O= incr(cool_O,cool_L+1);
/*:338*/
#line 5917 "mmix-pipe.w"
;break;
case 1:if(cool_O.l!=cool_S.l)/*113:*/
#line 2140 "mmix-pipe.w"
{
cool->need_b= cool->need_ra= false;
cool->i= incgamma;
new_S= incr(cool_S,1);
cool->b= specval(&l[cool_S.l&lring_mask]);
cool->y.p= NULL,cool->y.o= shift_left(cool_S,3);
cool->z= zero_spec;
cool->mem_x= true,spec_install(&mem,&cool->x);
op= STOU;
cool->interim= true;
goto dispatch_done;
}
/*:113*/
#line 5918 "mmix-pipe.w"
cool->zz= 2;cool->yy= cool_G;
case 2:case 3:/*339:*/
#line 5938 "mmix-pipe.w"
op= STOU;
cool->mem_x= true,spec_install(&mem,&cool->x);
cool->z.o= shift_left(cool_O,3);
new_O= new_S= incr(cool_O,1);
if(cool->zz==3&&cool->yy> rZ)/*340:*/
#line 5949 "mmix-pipe.w"
{
cool->i= save;
cool->interim= false;
cool->ren_a= true,spec_install(&g[cool->xx],&cool->a);
}
/*:340*/
#line 5943 "mmix-pipe.w"
else cool->b= specval(&g[cool->yy]);
/*:339*/
#line 5920 "mmix-pipe.w"
;break;
default:cool->interim= false,cool->i= noop,cool->interrupt|= B_BIT;break;
}
}
break;
/*:337*//*347:*/
#line 6092 "mmix-pipe.w"
case fsqrt:case fint:case fix:case flot:if(cool->y.o.l> 4)
goto illegal_inst;
break;
/*:347*//*355:*/
#line 6214 "mmix-pipe.w"
case sync:if(cool->zz> 3){
if(!(cool->loc.h&sign_bit))goto privileged_inst;
if(cool->zz==4)freeze_dispatch= true;
}else{
if(cool->zz!=1)freeze_dispatch= true;
if(cool->zz&1)cool->mem_x= true,spec_install(&mem,&cool->x);
}break;
/*:355*/
#line 1987 "mmix-pipe.w"
default:break;
}
dispatch_done:
/*:101*/
#line 1613 "mmix-pipe.w"
;
/*82:*/
#line 1697 "mmix-pipe.w"
{register int t= op>>5,b= sign_bit>>(op&31);
if(cool->i==trap&&op!=TRAP){
u= funit+funit_count;
goto unit_found;
}
for(u= funit;u<=funit+funit_count;u++)if(u->ops[t]&b){
for(i= 0;i<u->k;i++)if(u->co[i].next)goto unit_busy;
goto unit_found;
unit_busy:;
}
for(u= funit;u<funit+funit_count;u++)
if((u->ops[t]&b)&&(u->co->next==NULL))goto unit_found;
goto stall;
}
unit_found:
/*:82*/
#line 1614 "mmix-pipe.w"
;
/*111:*/
#line 2112 "mmix-pipe.w"
if(rename_regs<cool->ren_x+cool->ren_a)goto stall;
if(cool->mem_x)
if(mem_slots)mem_slots--;else goto stall;
rename_regs-= cool->ren_x+cool->ren_a;
/*:111*/
#line 1615 "mmix-pipe.w"
;
if((op&0xe0)==0x40)/*152:*/
#line 2849 "mmix-pipe.w"
if(bp_table){register int reversed,h,h_up,h_down;
reversed= op&0x10;
if(peek_hist&1)reversed^= 0x10;
m= ((head->loc.l&bp_cmask)<<bp_b)+(head->loc.l&bp_amask);
m= ((cool_hist&bp_bcmask)<<bp_a)^(m>>2);
h= bp_table[m];
h_up= (h+1)&bp_nmask;if(h_up==bp_npower)h_up= h;
if(h==bp_npower)h_down= h;else h_down= (h-1)&bp_nmask;
if(reversed){
bp_table[m]= h_down,cool->x.o.l= h_up;
cool->i= pbr+br-cool->i;
bp_rev_stat++;
}else{
bp_table[m]= h_up,cool->x.o.l= h_down;
bp_ok_stat++;
}
if(verbose&show_pred_bit){
printf(" predicting ");print_octa(cool->loc);
printf(" %s; bp[%x]=%d\n",reversed?"NG":"OK",m,
bp_table[m]-((bp_table[m]&bp_npower)<<1));
}
cool->x.o.h= m;
}
/*:152*/
#line 1616 "mmix-pipe.w"
;
/*81:*/
#line 1667 "mmix-pipe.w"
if(cool->interim){
cool->usage= false;
if(cool->op==SAVE)/*341:*/
#line 5956 "mmix-pipe.w"
switch(cool->zz){
case 1:head->inst= pack_bytes(SAVE,cool->xx,0,1);break;
case 2:if(cool->yy==255)head->inst= pack_bytes(SAVE,cool->xx,0,3);
else head->inst= pack_bytes(SAVE,cool->xx,cool->yy+1,2);break;
case 3:if(cool->yy==rR)head->inst= pack_bytes(SAVE,cool->xx,rP,3);
else head->inst= pack_bytes(SAVE,cool->xx,cool->yy+1,3);break;
}
/*:341*/
#line 1670 "mmix-pipe.w"
else if(cool->op==UNSAVE)/*335:*/
#line 5883 "mmix-pipe.w"
switch(cool->xx){
case 0:head->inst= pack_bytes(UNSAVE,1,rZ,0);break;
case 1:if(cool->yy==rP)head->inst= pack_bytes(UNSAVE,1,rR,0);
else if(cool->yy==0)head->inst= pack_bytes(UNSAVE,2,255,0);
else head->inst= pack_bytes(UNSAVE,1,cool->yy-1,0);break;
case 2:if(cool->yy==cool_G)head->inst= pack_bytes(UNSAVE,3,0,0);
else head->inst= pack_bytes(UNSAVE,2,cool->yy-1,0);break;
}
/*:335*/
#line 1671 "mmix-pipe.w"
else if(cool->i==preld||cool->i==prest)
/*228:*/
#line 4039 "mmix-pipe.w"
head->inst= (head->inst&~((Dcache->bb-1)<<16))-0x10000;
/*:228*/
#line 1673 "mmix-pipe.w"
else if(cool->i==prego)/*229:*/
#line 4042 "mmix-pipe.w"
head->inst= (head->inst&~((Icache->bb-1)<<16))-0x10000;
/*:229*/
#line 1674 "mmix-pipe.w"
}
else if(cool->i<=max_real_command){
if((flags[cool->op]&ctl_change_bit)||cool->i==pbr)
if(inst_ptr.p==NULL&&(inst_ptr.o.h&sign_bit)&&!(cool->loc.h&sign_bit)
&&cool->i!=trap)
cool->interrupt|= P_BIT;
true_head= head= new_head;
resuming= 0;
}
if(freeze_dispatch)set_lock(u->co,dispatch_lock);
cool->owner= u->co;u->co->ctl= cool;
startup(u->co,1);
if(verbose&issue_bit){
printf("Issuing ");print_control_block(cool);
printf(" ");print_coroutine_id(u->co);printf("\n");
}
dispatch_count++;
/*:81*/
#line 1617 "mmix-pipe.w"
;
cool= new_cool;cool_O= new_O;cool_S= new_S;
cool_hist= peek_hist;continue;
stall:/*123:*/
#line 2309 "mmix-pipe.w"
if(cool->ren_x||cool->mem_x)spec_rem(&cool->x);
if(cool->ren_a)spec_rem(&cool->a);
if(cool->set_l)spec_rem(&cool->rl);
if(inst_ptr.p==&cool->go)inst_ptr.p= UNKNOWN_SPEC;
break;
/*:123*/
#line 1621 "mmix-pipe.w"
;
}
/*:75*/
#line 1590 "mmix-pipe.w"
;
head= true_head;
}
/*:74*/
#line 1440 "mmix-pipe.w"
;
ticks= incr(ticks,1);
dispatch_stat[dispatch_count]++;
}
/*:64*/
#line 228 "mmix-pipe.w"
;
if(verbose&pipe_bit){
print_pipe();print_locks();
}
if(breakpoint_hit||halted){
if(breakpoint_hit)
printf("Breakpoint instruction fetched at time %d\n",ticks.l-1);
if(halted)printf("Halted at time %d\n",ticks.l-1);
break;
}
cycs--;
}
cease:;
}
/*:10*//*39:*/
#line 609 "mmix-pipe.w"
void print_locks()
{
print_cache_locks(ITcache);
print_cache_locks(DTcache);
print_cache_locks(Icache);
print_cache_locks(Dcache);
print_cache_locks(Scache);
if(mem_lock)printf("mem locked by %s:%d\n",mem_lock->name,mem_lock->stage);
if(dispatch_lock)printf("dispatch locked by %s:%d\n",
dispatch_lock->name,dispatch_lock->stage);
if(wbuf_lock)printf("head of write buffer locked by %s:%d\n",
wbuf_lock->name,wbuf_lock->stage);
if(clean_lock)printf("cleaner locked by %s:%d\n",
clean_lock->name,clean_lock->stage);
if(speed_lock)printf("write buffer flush locked by %s:%d\n",
speed_lock->name,speed_lock->stage);
}
/*:39*//*162:*/
#line 2978 "mmix-pipe.w"
void print_stats()
{
register int j;
if(bp_table)
printf("Predictions: %d in agreement, %d in opposition; %d good, %d bad\n",
bp_ok_stat,bp_rev_stat,bp_good_stat,bp_bad_stat);
else printf("Predictions: %d good, %d bad\n",bp_good_stat,bp_bad_stat);
printf("Instructions issued per cycle:\n");
for(j= 0;j<=dispatch_max;j++)
printf(" %d %d\n",j,dispatch_stat[j]);
}
/*:162*//*176:*/
#line 3224 "mmix-pipe.w"
void print_cache(c,dirty_only)
cache*c;
bool dirty_only;
{
if(c){register int i,j;
printf("%s of %s:",dirty_only?"Dirty blocks":"Contents",c->name);
if(c->filler.next){
printf(" (filling ");
print_octa(c->name[1]=='T'?c->filler_ctl.y.o:c->filler_ctl.z.o);
printf(")");
}
if(c->flusher.next){
printf(" (flushing ");
print_octa(c->outbuf.tag);
printf(")");
}
printf("\n");
/*177:*/
#line 3249 "mmix-pipe.w"
for(i= 0;i<c->cc;i++)for(j= 0;j<c->aa;j++)
if((!(c->set[i][j].tag.h&sign_bit)||(verbose&show_wholecache_bit))&&
(!dirty_only||is_dirty(c,&c->set[i][j]))){
printf("[%d][%d] ",i,j);
print_cache_block(c->set[i][j],c);
}
for(j= 0;j<c->vv;j++)
if((!(c->victim[j].tag.h&sign_bit)||(verbose&show_wholecache_bit))&&
(!dirty_only||is_dirty(c,&c->victim[j]))){
printf("V[%d] ",j);
print_cache_block(c->victim[j],c);
}
/*:177*/
#line 3242 "mmix-pipe.w"
;
}
}
/*:176*//*179:*/
#line 3268 "mmix-pipe.w"
void clean_block(c,p)
cache*c;
cacheblock*p;
{
register int j;
p->tag.h= sign_bit,p->tag.l= 0;
for(j= 0;j<c->bb>>3;j++)p->data[j]= zero_octa;
for(j= 0;j<c->bb>>c->g;j++)p->dirty[j]= false;
}
/*:179*//*181:*/
#line 3288 "mmix-pipe.w"
void zap_cache(c)
cache*c;
{
register int i,j;
for(i= 0;i<c->cc;i++)for(j= 0;j<c->aa;j++){
clean_block(c,&(c->set[i][j]));
}
for(j= 0;j<c->vv;j++){
clean_block(c,&(c->victim[j]));
}
}
/*:181*//*210:*/
#line 3687 "mmix-pipe.w"
octa mem_read(addr)
octa addr;
{
register tetra off,key;
register int h;
if(addr.h>=(1<<16))return spec_read(addr);
off= (addr.l&0xffff)>>3;
key= (addr.l&0xffff0000)+addr.h;
for(h= key%hash_prime;mem_hash[h].tag!=key;h--){
if(mem_hash[h].chunk==NULL){
if(verbose&uninit_mem_bit)
errprint2("uninitialized memory read at %08x%08x",addr.h,addr.l);
h= hash_prime;break;
}
if(h==0)h= hash_prime;
}
last_h= h;
return mem_hash[h].chunk[off];
}
/*:210*//*213:*/
#line 3715 "mmix-pipe.w"
void mem_write(addr,val)
octa addr,val;
{
register tetra off,key;
register int h;
if(addr.h>=(1<<16)){spec_write(addr,val);return;}
off= (addr.l&0xffff)>>3;
key= (addr.l&0xffff0000)+addr.h;
for(h= key%hash_prime;mem_hash[h].tag!=key;h--){
if(mem_hash[h].chunk==NULL){
if(++mem_chunks> mem_chunks_max)
panic(errprint1("More than %d memory chunks are needed",
mem_chunks_max));
mem_hash[h].chunk= (octa*)calloc(1<<13,sizeof(octa));
if(mem_hash[h].chunk==NULL)
panic(errprint1("I can't allocate memory chunk number %d",
mem_chunks));
mem_hash[h].tag= key;
break;
}
if(h==0)h= hash_prime;
}
last_h= h;
mem_hash[h].chunk[off]= val;
}
/*:213*//*253:*/
#line 4450 "mmix-pipe.w"
void print_pipe()
{
print_write_buffer();
print_reorder_buffer();
print_fetch_buffer();
}
/*:253*/
#line 136 "mmix-pipe.w"
/*:3*/
syntax highlighted by Code2HTML, v. 0.9.1