#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->ii==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 \ /*3:*/ #line 123 "mmix-pipe.w" #include #include #include #include "abstime.h" /*6:*/ #line 163 "mmix-pipe.w" #ifdef __STDC__ #define ARGS(list) list #else #define ARGS(list) () #endif /*:6*//*7:*/ #line 175 "mmix-pipe.w" #define random my_random #define fsqrt my_fsqrt #define div my_div /*:7*//*8:*/ #line 182 "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 1109 "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 1190 "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 1826 "mmix-pipe.w" #define ticks g[rC].o /*:87*//*129:*/ #line 2405 "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 3109 "mmix-pipe.w" #define WRITE_BACK 1 #define WRITE_ALLOC 2 /*:166*/ #line 128 "mmix-pipe.w" /*11:*/ #line 242 "mmix-pipe.w" typedef enum{false,true,wow}bool; /*:11*//*17:*/ #line 314 "mmix-pipe.w" typedef unsigned int tetra; typedef struct{tetra h,l;}octa; /*:17*//*23:*/ #line 432 "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 602 "mmix-pipe.w" typedef coroutine*lockvar; /*:37*//*40:*/ #line 645 "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 727 "mmix-pipe.w" /*47:*/ #line 793 "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 872 "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 728 "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 1490 "mmix-pipe.w" typedef struct{ octa loc; tetra inst; unsigned int interrupt; bool noted; unsigned int hist; }fetch; /*:68*//*76:*/ #line 1626 "mmix-pipe.w" typedef struct func_struct{ char name[16]; tetra ops[8]; int k; coroutine*co; }func; /*:76*//*164:*/ #line 3076 "mmix-pipe.w" typedef enum{random,serial,pseudo_lru,lru}replace_policy; /*:164*//*167:*/ #line 3120 "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 3640 "mmix-pipe.w" typedef struct{ tetra tag; octa*chunk; }chunknode; /*:206*//*246:*/ #line 4379 "mmix-pipe.w" typedef struct{ octa o; octa addr; tetra stamp; internal_opcode i; }write_node; /*:246*//*371:*/ #line 6450 "mmix-pipe.w" typedef enum{ Halt,Fopen,Fclose,Fread,Fgets,Fgetws, Fwrite,Fputs,Fputws,Fseek,Ftell}sys_call; /*:371*/ #line 129 "mmix-pipe.w" /*20:*/ #line 330 "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 582 "mmix-pipe.w" coroutine sentinel; /*:36*//*41:*/ #line 658 "mmix-pipe.w" spec zero_spec; /*:41*//*48:*/ #line 828 "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 969 "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 1065 "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 1143 "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 1172 "mmix-pipe.w" char bit_code_map[]= "EFHDVWIOUZXrwxnkbsp"; /*:54*//*65:*/ #line 1440 "mmix-pipe.w" int dispatch_count; bool suppress_dispatch; int doing_interrupt; lockvar dispatch_lock; /*:65*//*70:*/ #line 1514 "mmix-pipe.w" fetch*old_tail; /*:70*//*78:*/ #line 1642 "mmix-pipe.w" control*new_cool; int resuming; tetra support[8]; /*:78*//*83:*/ #line 1720 "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,0x8a,0x89, 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,0xc0,0xc0,0x60,0x60,0x02,0x01, 0x80,0x80,0x00,0x02,0x01,0x00,0x20,0x8a}; /*:83*//*88:*/ #line 1829 "mmix-pipe.w" int lring_mask; /*:88*//*99:*/ #line 1947 "mmix-pipe.w" int cool_L,cool_G; unsigned int cool_hist,peek_hist; octa new_O,new_S; /*:99*//*107:*/ #line 2034 "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 2384 "mmix-pipe.w" coroutine mem_locker; coroutine Dlocker; control vanish_ctl; /*:127*//*148:*/ #line 2739 "mmix-pipe.w" octa new_Q; /*:148*//*154:*/ #line 2877 "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 3451 "mmix-pipe.w" cacheset hit_set; /*:194*//*230:*/ #line 4057 "mmix-pipe.w" coroutine clean_co; control clean_ctl; lockvar clean_lock; /*:230*//*235:*/ #line 4204 "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 4265 "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 4403 "mmix-pipe.w" coroutine write_co; control write_ctl; /*:248*//*285:*/ #line 5107 "mmix-pipe.w" int fetch_lo,fetch_hi; coroutine fetch_co; control fetch_ctl; /*:285*//*303:*/ #line 5328 "mmix-pipe.w" bool sleepy; /*:303*//*305:*/ #line 5352 "mmix-pipe.w" int bad_inst_mask[4]= {0xfffffe,0xffff,0xffff00,0xfffff8}; /*:305*//*315:*/ #line 5507 "mmix-pipe.w" bool trying_to_interrupt; bool nullifying; /*:315*//*374:*/ #line 6488 "mmix-pipe.w" char arg_count[]= {1,3,1,3,3,3,3,2,2,2,1}; /*:374*//*376:*/ #line 6496 "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 6728 "mmix-pipe.w" char stdin_buf[256]; char*stdin_buf_start; char*stdin_buf_end; /*:388*/ #line 130 "mmix-pipe.w" /*4:*/ #line 145 "mmix-pipe.w" Extern int verbose; /*:4*//*29:*/ #line 511 "mmix-pipe.w" Extern int ring_size; Extern coroutine*ring; Extern int cur_time; /*:29*//*59:*/ #line 1361 "mmix-pipe.w" Extern int fetch_max,dispatch_max,peekahead,commit_max; /*:59*//*60:*/ #line 1387 "mmix-pipe.w" Extern control*reorder_bot,*reorder_top; Extern control*hot,*cool; Extern control*old_hot; Extern int deissues; /*:60*//*66:*/ #line 1446 "mmix-pipe.w" Extern int*dispatch_stat; Extern bool security_disabled; /*:66*//*69:*/ #line 1509 "mmix-pipe.w" Extern fetch*fetch_bot,*fetch_top; Extern fetch*head,*tail; /*:69*//*77:*/ #line 1634 "mmix-pipe.w" Extern func*funit; Extern int funit_count; /*:77*//*86:*/ #line 1818 "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 1944 "mmix-pipe.w" Extern octa cool_O,cool_S; /*:98*//*115:*/ #line 2168 "mmix-pipe.w" Extern specnode mem; /*:115*//*136:*/ #line 2534 "mmix-pipe.w" #define pipe_limit 90 Extern unsigned char pipe_seq[max_pipe_op+1][pipe_limit+1]; /*:136*//*150:*/ #line 2817 "mmix-pipe.w" Extern int bp_a,bp_b,bp_c,bp_n; Extern char*bp_table; /*:150*//*168:*/ #line 3158 "mmix-pipe.w" Extern cache*Icache,*Dcache,*Scache,*ITcache,*DTcache; /*:168*//*207:*/ #line 3652 "mmix-pipe.w" Extern int mem_chunks; Extern int mem_chunks_max; Extern int hash_prime; Extern chunknode*mem_hash; /*:207*//*211:*/ #line 3702 "mmix-pipe.w" Extern int last_h; /*:211*//*214:*/ #line 3745 "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 4313 "mmix-pipe.w" Extern bool no_hardware_PT; /*:242*//*247:*/ #line 4394 "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 5097 "mmix-pipe.w" Extern spec inst_ptr; Extern octa*fetched; /*:284*//*349:*/ #line 6111 "mmix-pipe.w" Extern int frem_max; Extern int denin_penalty,denout_penalty; /*:349*/ #line 131 "mmix-pipe.w" /*13:*/ #line 261 "mmix-pipe.w" static void expire ARGS((void)); /*:13*//*18:*/ #line 319 "mmix-pipe.w" static void print_octa ARGS((octa)); /*:18*//*24:*/ #line 441 "mmix-pipe.w" static void print_coroutine_id ARGS((coroutine*)); static void errprint_coroutine_id ARGS((coroutine*)); /*:24*//*27:*/ #line 489 "mmix-pipe.w" static void schedule ARGS((coroutine*,int,int)); /*:27*//*30:*/ #line 522 "mmix-pipe.w" static void startup ARGS((coroutine*,int)); /*:30*//*32:*/ #line 542 "mmix-pipe.w" static void unschedule ARGS((coroutine*)); /*:32*//*34:*/ #line 565 "mmix-pipe.w" static coroutine*queuelist ARGS((int)); /*:34*//*42:*/ #line 661 "mmix-pipe.w" static void print_spec ARGS((spec)); /*:42*//*45:*/ #line 753 "mmix-pipe.w" static void print_control_block ARGS((control*)); /*:45*//*55:*/ #line 1175 "mmix-pipe.w" static void print_bits ARGS((int)); /*:55*//*62:*/ #line 1398 "mmix-pipe.w" static void print_reorder_buffer ARGS((void)); /*:62*//*72:*/ #line 1523 "mmix-pipe.w" static void print_fetch_buffer ARGS((void)); /*:72*//*90:*/ #line 1867 "mmix-pipe.w" static void print_specnode_id ARGS((octa)); /*:90*//*92:*/ #line 1886 "mmix-pipe.w" static spec specval ARGS((specnode*)); /*:92*//*94:*/ #line 1901 "mmix-pipe.w" static void spec_install ARGS((specnode*,specnode*)); /*:94*//*96:*/ #line 1917 "mmix-pipe.w" static void spec_rem ARGS((specnode*)); /*:96*//*156:*/ #line 2901 "mmix-pipe.w" static int register_truth ARGS((octa,mmix_opcode)); /*:156*//*158:*/ #line 2923 "mmix-pipe.w" static int issued_between ARGS((control*,control*)); /*:158*//*169:*/ #line 3164 "mmix-pipe.w" static bool is_dirty ARGS((cache*,cacheblock*)); /*:169*//*171:*/ #line 3180 "mmix-pipe.w" static void print_cache_block ARGS((cacheblock,cache*)); /*:171*//*173:*/ #line 3194 "mmix-pipe.w" static void print_cache_locks ARGS((cache*)); /*:173*//*182:*/ #line 3298 "mmix-pipe.w" static int get_reader ARGS((cache*)); /*:182*//*184:*/ #line 3316 "mmix-pipe.w" static void copy_block ARGS((cache*,cacheblock*,cache*,cacheblock*)); /*:184*//*186:*/ #line 3342 "mmix-pipe.w" static cacheblock*choose_victim ARGS((cacheset,int,replace_policy)); /*:186*//*188:*/ #line 3367 "mmix-pipe.w" static void note_usage ARGS((cacheblock*,cacheset,int,replace_policy)); /*:188*//*190:*/ #line 3396 "mmix-pipe.w" static void demote_usage ARGS((cacheblock*,cacheset,int,replace_policy)); /*:190*//*192:*/ #line 3430 "mmix-pipe.w" static cacheblock*cache_search ARGS((cache*,octa)); /*:192*//*195:*/ #line 3460 "mmix-pipe.w" static cacheblock*use_and_fix ARGS((cache*,cacheblock*)); /*:195*//*198:*/ #line 3498 "mmix-pipe.w" static cacheblock*demote_and_fix ARGS((cache*,cacheblock*)); /*:198*//*200:*/ #line 3515 "mmix-pipe.w" static void load_cache ARGS((cache*,cacheblock*)); /*:200*//*202:*/ #line 3539 "mmix-pipe.w" static void flush_cache ARGS((cache*,cacheblock*,bool)); /*:202*//*204:*/ #line 3584 "mmix-pipe.w" static cacheblock*alloc_slot ARGS((cache*,octa)); /*:204*//*240:*/ #line 4297 "mmix-pipe.w" static octa phys_addr ARGS((octa,octa)); /*:240*//*250:*/ #line 4416 "mmix-pipe.w" static void print_write_buffer ARGS((void)); /*:250*//*254:*/ #line 4469 "mmix-pipe.w" static octa*write_search ARGS((control*,octa)); /*:254*//*377:*/ #line 6509 "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 132 "mmix-pipe.w" /*9:*/ #line 208 "mmix-pipe.w" Extern void MMIX_init ARGS((void)); Extern void MMIX_run ARGS((int cycs,octa breakpoint)); /*:9*//*38:*/ #line 605 "mmix-pipe.w" Extern void print_locks ARGS((void)); /*:38*//*161:*/ #line 2968 "mmix-pipe.w" Extern void print_stats ARGS((void)); /*:161*//*175:*/ #line 3214 "mmix-pipe.w" Extern void print_cache ARGS((cache*,bool)); /*:175*//*178:*/ #line 3258 "mmix-pipe.w" Extern void clean_block ARGS((cache*,cacheblock*)); /*:178*//*180:*/ #line 3275 "mmix-pipe.w" Extern void zap_cache ARGS((cache*)); /*:180*//*209:*/ #line 3677 "mmix-pipe.w" Extern octa mem_read ARGS((octa addr)); /*:209*//*212:*/ #line 3705 "mmix-pipe.w" Extern void mem_write ARGS((octa addr,octa val)); /*:212*//*252:*/ #line 4440 "mmix-pipe.w" Extern void print_pipe ARGS((void)); /*:252*/ #line 133 "mmix-pipe.w" /*14:*/ #line 264 "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 322 "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 344 "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 445 "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 492 "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->stagestage)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 525 "mmix-pipe.w" static void startup(c,d) coroutine*c; int d; { c->ctl->state= 0; schedule(c,d,0); } /*:31*//*33:*/ #line 545 "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 568 "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 664 "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 756 "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); printf(" state=%d",c->state); } /*:46*//*56:*/ #line 1178 "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 1401 "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 1526 "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 1870 "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 1889 "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 1904 "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 1920 "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 2904 "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 cc)return c-1-cc; return(c-reorder_bot)+(reorder_top-cc); } /*:159*//*170:*/ #line 3167 "mmix-pipe.w" static bool is_dirty(c,p) cache*c; cacheblock*p; { register int j; register char*d= p->dirty; for(j= 0;jbb;d++,j+= c->gg)if(*d)return true; return false; } /*:170*//*172:*/ #line 3183 "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;jlock)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 3301 "mmix-pipe.w" static int get_reader(c) cache*c; {register int j; for(j= 0;jports;j++) if(c->reader[j].next==NULL)return j; return-1; } /*:183*//*185:*/ #line 3319 "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;jbb>>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); idata[ii]= p->data[i]; } } /*:185*//*187:*/ #line 3345 "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;prank==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 3370 "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;prank> 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 3399 "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;prankrank++; 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 3433 "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;paa;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;pvv;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 3463 "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 3485 "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 3474 "mmix-pipe.w" ; return q; } } return p; } /*:196*//*199:*/ #line 3501 "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 3518 "mmix-pipe.w" static void load_cache(c,p) cache*c; cacheblock*p; { register int i; register octa*d; for(i= 0;ibb>>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 3542 "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;jbb>>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;jbb>>c->g;j++)p->dirty[j]= false; startup(&c->flusher,c->copy_out_time); } /*:203*//*205:*/ #line 3587 "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 3485 "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 3604 "mmix-pipe.w" ; q->tag.h|= sign_bit; return q; } p->tag.h|= sign_bit;return p; } /*:205*//*208:*/ #line 3662 "mmix-pipe.w" extern octa spec_read ARGS((octa addr)); extern void spec_write ARGS((octa addr,octa val)); /*:208*//*241:*/ #line 4300 "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 4419 "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 4472 "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 6521 "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==addr.l&&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(Scache){ p= cache_search(Scache,addr); if(p)return p->data[(addr.l&(Scache->bb-1))>>3]; } } return mem_read(addr); } /*:378*//*379:*/ #line 6548 "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==addr.l&&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->tagmask)==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->tagmask)==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->tagmask)==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->tagmask)==0&& Scache->outbuf.tag.h==addr.h) Scache->outbuf.data[(addr.l&(Scache->bb-1))>>3]= val; } } mem_write(addr,val); } /*:379*//*381:*/ #line 6606 "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-8)/*382:*/ #line 6629 "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 6623 "mmix-pipe.w" else/*383:*/ #line 6640 "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 6624 "mmix-pipe.w" } return size; } /*:381*//*384:*/ #line 6664 "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-8)/*385:*/ #line 6684 "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)^*p)&0xff)< ");fflush(stdout); fgets(stdin_buf,256,stdin); stdin_buf_start= stdin_buf; for(p= stdin_buf;pnext= p; } /*:26*//*61:*/ #line 1394 "mmix-pipe.w" hot= cool= reorder_top; deissues= 0; /*:61*//*71:*/ #line 1519 "mmix-pipe.w" head= tail= fetch_top; inst_ptr.p= UNKNOWN_SPEC; /*:71*//*79:*/ #line 1647 "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 1851 "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;jports;j++)DTcache->reader[j].ctl= &vanish_ctl; if(Dcache)for(j= 0;jports;j++)Dcache->reader[j].ctl= &vanish_ctl; for(j= 0;jports;j++)ITcache->reader[j].ctl= &vanish_ctl; if(Icache)for(j= 0;jports;j++)Icache->reader[j].ctl= &vanish_ctl; /*:128*//*153:*/ #line 2870 "mmix-pipe.w" bp_amask= ((1< 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 4407 "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 5112 "mmix-pipe.w" fetch_co.ctl= &fetch_ctl; fetch_co.name= "Fetch"; fetch_ctl.go.o.l= 4; startup(&fetch_co,1); /*:286*/ #line 216 "mmix-pipe.w" ; } void MMIX_run(cycs,breakpoint) int cycs; octa breakpoint; { /*12:*/ #line 245 "mmix-pipe.w" register int i,j,m; bool breakpoint_hit= false; bool halted= false; /*:12*//*124:*/ #line 2343 "mmix-pipe.w" register coroutine*self; register control*data; /*:124*//*258:*/ #line 4563 "mmix-pipe.w" register cacheblock*p,*q; /*:258*/ #line 223 "mmix-pipe.w" ; while(cycs){ if(verbose&(issue_bit|pipe_bit|coroutine_bit|schedule_bit)) printf("*** Cycle %d\n",ticks.l); /*64:*/ #line 1425 "mmix-pipe.w" { /*314:*/ #line 5487 "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 5521 "mmix-pipe.w" i= issued_between(hot,cool); if(i>=deissues){ deissues= i; tail= head;resuming= 0; /*287:*/ #line 5118 "mmix-pipe.w" if(fetch_co.lockloc)*(fetch_co.lockloc)= NULL,fetch_co.lockloc= NULL; unschedule(&fetch_co); startup(&fetch_co,1); /*:287*/ #line 5526 "mmix-pipe.w" ; if(is_load_store(hot->i))nullifying= true; } /*:316*/ #line 5502 "mmix-pipe.w" ; inst_ptr.o= g[rTT].o;inst_ptr.p= NULL; } } /*:314*/ #line 1427 "mmix-pipe.w" ; dispatch_count= 0; old_hot= hot; old_tail= tail; suppress_dispatch= (deissues||dispatch_lock); if(doing_interrupt)/*318:*/ #line 5553 "mmix-pipe.w" switch(doing_interrupt--){ case 3:/*319:*/ #line 5563 "mmix-pipe.w" j= hot->interrupt&H_BIT; g[j?rB:rBB].o= g[255].o; if(j)g[255].o= zero_octa; else g[255].o= g[hot->interrupt&F_BIT?rT:rTT].o; if(verbose&issue_bit){ if(j){ printf(" setting rB=");print_octa(g[rB].o); printf(", $255=0\n"); }else{ printf(" setting rBB=");print_octa(g[rBB].o); printf(", $255=");print_octa(g[255].o);printf("\n"); } } /*:319*/ #line 5555 "mmix-pipe.w" ; break; case 2:/*320:*/ #line 5587 "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 5557 "mmix-pipe.w" ;break; case 1:/*321:*/ #line 5619 "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 5558 "mmix-pipe.w" ; if(hot==reorder_bot)hot= reorder_top;else hot--; break; } /*:318*/ #line 1432 "mmix-pipe.w" else/*67:*/ #line 1451 "mmix-pipe.w" { for(m= commit_max;m> 0&&deissues> 0;m--) /*145:*/ #line 2668 "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 1454 "mmix-pipe.w" ; for(;m> 0;m--){ if(hot==cool)break; if(!security_disabled)/*149:*/ #line 2754 "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 1457 "mmix-pipe.w" ; if(hot->owner)break; /*146:*/ #line 2689 "mmix-pipe.w" { if(nullifying)/*147:*/ #line 2722 "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 2691 "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 4507 "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 2697 "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 5540 "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 2711 "mmix-pipe.w" ; } /*:146*/ #line 1459 "mmix-pipe.w" ; i= hot->i; if(hot==reorder_bot)hot= reorder_top; else hot--; if(i==resum)break; } } /*:67*/ #line 1433 "mmix-pipe.w" ; /*125:*/ #line 2359 "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 5129 "mmix-pipe.w" switch0:switch(data->state){ new_fetch:data->state= 0; case 0:/*290:*/ #line 5148 "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 5132 "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 5218 "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 5237 "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>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 5223 "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 5201 "mmix-pipe.w" if(data->i!=prego){ for(j= 0;jbb;j++)fetched[j]= q->data[j]; fetch_lo= (inst_ptr.o.l&(Icache->bb-1))>>3; fetch_hi= Icache->bb>>3; } /*:294*/ #line 5231 "mmix-pipe.w" ; data->state= fetch_ready; }else data->state= Ihit_and_miss; wait_or_pass(Icache->access_time); } /*:296*/ #line 5136 "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 5162 "mmix-pipe.w" p= cache_search(ITcache,trans_key(data->y.o)); if(!Icache||Icache->lock||(j= get_reader(Icache))<0) /*295:*/ #line 5208 "mmix-pipe.w" { if(p){ /*293:*/ #line 5195 "mmix-pipe.w" p= use_and_fix(ITcache,p); if(!(p->data[0].l&(PX_BIT>>PROT_OFFSET)))goto bad_fetch; /*:293*/ #line 5211 "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 5165 "mmix-pipe.w" ; startup(&Icache->reader[j],Icache->access_time); if(p)/*292:*/ #line 5177 "mmix-pipe.w" { /*293:*/ #line 5195 "mmix-pipe.w" p= use_and_fix(ITcache,p); if(!(p->data[0].l&(PX_BIT>>PROT_OFFSET)))goto bad_fetch; /*:293*/ #line 5179 "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<c)-(1<state= IT_hit; else{ q= cache_search(Icache,data->z.o); if(q){ q= use_and_fix(Icache,q); /*294:*/ #line 5201 "mmix-pipe.w" if(data->i!=prego){ for(j= 0;jbb;j++)fetched[j]= q->data[j]; fetch_lo= (inst_ptr.o.l&(Icache->bb-1))>>3; fetch_hi= Icache->bb>>3; } /*:294*/ #line 5188 "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 5167 "mmix-pipe.w" else data->state= IT_miss; /*:291*/ #line 5140 "mmix-pipe.w" ; wait_or_pass(ITcache->access_time); /*298:*/ #line 5252 "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 5320 "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 5255 "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 5276 "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 5271 "mmix-pipe.w" ; /*:298*//*301:*/ #line 5294 "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;jloc= 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 5310 "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 5142 "mmix-pipe.w" } /*:288*/ #line 2369 "mmix-pipe.w" ; case 1:/*130:*/ #line 2420 "mmix-pipe.w" switch1:switch(data->state){ case 0:/*131:*/ #line 2433 "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 2422 "mmix-pipe.w" ; case 1:/*132:*/ #line 2468 "mmix-pipe.w" switch(data->i){ /*137:*/ #line 2543 "mmix-pipe.w" case set:data->x.o= data->z.o;break; /*:137*//*138:*/ #line 2549 "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 2573 "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 2585 "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 2604 "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 2618 "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 2625 "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.hz.o.h)goto cmp_neg; if(data->y.o.h> data->z.o.h)goto cmp_pos; if(data->y.o.lz.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 5980 "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 6002 "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 6034 "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 6059 "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 6092 "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 6118 "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 2470 "mmix-pipe.w" ; /*265:*/ #line 4666 "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 2471 "mmix-pipe.w" ; /*155:*/ #line 2887 "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 2947 "mmix-pipe.w" i= issued_between(data,cool); if(igo.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 2893 "mmix-pipe.w" ; } goto fin_ex; /*:155*//*313:*/ #line 5478 "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 5726 "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 5757 "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 5771 "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 5783 "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 4273 "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<>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 5787 "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 5805 "mmix-pipe.w" if(data->z.o.h!=0||data->z.o.l>=256|| data->z.o.lz.o.l<32) data->interrupt|= B_BIT; else if(data->z.o.linterim= true; for(j= 0;jz.o.l==g[rG].o.l)break; } if(j==commit_max){ if(!trying_to_interrupt)wait(1); }else data->interim= false; } /*:330*/ #line 5795 "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 5823 "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 6218 "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 6233 "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 6222 "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 6286 "mmix-pipe.w" if(self->lockloc)*(self->lockloc)= NULL,self->lockloc= NULL; /*362:*/ #line 6299 "mmix-pipe.w" if(write_head!=write_tail){ if(!speed_lock)set_lock(self,speed_lock); wait(1); } /*:362*/ #line 6288 "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 6226 "mmix-pipe.w" ; case 6:if(data!=old_hot)wait(1); /*358:*/ #line 6244 "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 6228 "mmix-pipe.w" ; case 7:if(data!=old_hot)wait(1); /*359:*/ #line 6251 "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 6230 "mmix-pipe.w" ; } /*:356*/ #line 2472 "mmix-pipe.w" ; } /*133:*/ #line 2491 "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 2474 "mmix-pipe.w" ; /*:132*/ #line 2423 "mmix-pipe.w" ; case 2:/*134:*/ #line 2504 "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 2424 "mmix-pipe.w" ; case 3:/*144:*/ #line 2644 "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 5393 "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 5408 "mmix-pipe.w" { i= issued_between(data,cool); if(ihist; 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 5400 "mmix-pipe.w" ; if(data->interrupt&0xff)goto state_5; } /*:307*/ #line 2650 "mmix-pipe.w" ; die:data->owner= NULL;goto terminate; /*:144*/ #line 2425 "mmix-pipe.w" ; /*266:*/ #line 4680 "mmix-pipe.w" case ld_st_launch:if((self+1)->next) wait(1); /*289:*/ #line 5145 "mmix-pipe.w" if(data->i==prego)goto start_fetch; /*:289*//*352:*/ #line 6160 "mmix-pipe.w" if(data->i==ldvts)/*353:*/ #line 6163 "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 6161 "mmix-pipe.w" ; /*:352*/ #line 4683 "mmix-pipe.w" ; if(data->y.o.h&sign_bit) /*271:*/ #line 4794 "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 4685 "mmix-pipe.w" ; if(page_bad){ if(data->i==st||(data->ii> 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 4715 "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 4779 "mmix-pipe.w" {octa*m; if(p){ /*269:*/ #line 4769 "mmix-pipe.w" p= use_and_fix(DTcache,p); j= PRW_BITS; if(((p->data[0].l<i==syncd||data->i==syncid)goto sync_check; if(data->i!=preld&&data->i!=prest) data->interrupt|= j&~(p->data[0].l<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 4719 "mmix-pipe.w" ; startup(&Dcache->reader[j],Dcache->access_time); if(p)/*268:*/ #line 4741 "mmix-pipe.w" {octa*m; /*269:*/ #line 4769 "mmix-pipe.w" p= use_and_fix(DTcache,p); j= PRW_BITS; if(((p->data[0].l<i==syncd||data->i==syncid)goto sync_check; if(data->i!=preld&&data->i!=prest) data->interrupt|= j&~(p->data[0].l<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<c)-(1<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 4721 "mmix-pipe.w" else data->state= DT_miss; /*:267*/ #line 4693 "mmix-pipe.w" ; pass_after(DTcache->access_time);goto passit; /*:266*//*310:*/ #line 5438 "mmix-pipe.w" emulate_virt:/*309:*/ #line 5423 "mmix-pipe.w" i= issued_between(data,cool); if(ihist; inst_ptr.p= UNKNOWN_SPEC; data->interrupt|= F_BIT; /*:309*/ #line 5439 "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 5734 "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 6261 "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 6309 "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 2426 "mmix-pipe.w" ; } /*:130*/ #line 2370 "mmix-pipe.w" ; default:/*135:*/ #line 2517 "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 6131 "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 2522 "mmix-pipe.w" ; case 2:goto pass_data; case 3:goto fin_ex; /*272:*/ #line 4844 "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 4769 "mmix-pipe.w" p= use_and_fix(DTcache,p); j= PRW_BITS; if(((p->data[0].l<i==syncd||data->i==syncid)goto sync_check; if(data->i!=preld&&data->i!=prest) data->interrupt|= j&~(p->data[0].l<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<i==syncd||data->i==syncid)goto sync_check; data->interrupt|= j&~(data->z.o.l<z.o= phys_addr(data->y.o,data->z.o); if(data->i>=st&&data->i<=syncid)goto finish_store; /*:272*//*273:*/ #line 4889 "mmix-pipe.w" ld_retry:data->state= DT_hit; case DT_hit:if(data->i==preld||data->i==prest)goto fin_ex; /*278:*/ #line 4959 "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 4892 "mmix-pipe.w" ; if((data->z.o.h&0xffff0000)||!Dcache) /*277:*/ #line 4950 "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 4894 "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 4908 "mmix-pipe.w" /*275:*/ #line 4931 "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 4909 "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 4906 "mmix-pipe.w" ; /*:273*//*276:*/ #line 4937 "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 4974 "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 5888 "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 5000 "mmix-pipe.w" ; } /*:279*//*280:*/ #line 5003 "mmix-pipe.w" finish_store:data->state= st_ready; case st_ready:switch(data->i){ case st:case pst:/*281:*/ #line 5016 "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 5042 "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 5036 "mmix-pipe.w" ; goto fin_ex; case CSWAP>>1:/*283:*/ #line 5060 "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 5038 "mmix-pipe.w" ; case SAVE>>1:/*342:*/ #line 5960 "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 5039 "mmix-pipe.w" ; } /*:281*/ #line 5006 "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->bbb.o.l)data->b.o.l= Dcache->bb; goto do_syncid; } /*:280*//*299:*/ #line 5273 "mmix-pipe.w" case IT_miss:case Ihit_and_miss:case IT_hit:case fetch_ready:goto switch0; /*:299*//*311:*/ #line 5461 "mmix-pipe.w" case 4:goto state_4; case 5:goto state_5; /*:311*//*354:*/ #line 6183 "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 6334 "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 6373 "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 6340 "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 6299 "mmix-pipe.w" if(write_head!=write_tail){ if(!speed_lock)set_lock(self,speed_lock); wait(1); } /*:362*/ #line 6343 "mmix-pipe.w" ; if(((data->b.o.l-1)&~data->y.o.l)xx)data->interim= true; if(!Dcache)goto next_sync; /*366:*/ #line 6383 "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 6346 "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 6393 "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 6350 "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 6299 "mmix-pipe.w" if(write_head!=write_tail){ if(!speed_lock)set_lock(self,speed_lock); wait(1); } /*:362*/ #line 6355 "mmix-pipe.w" ; if(((data->b.o.l-1)&~data->y.o.l)xx)data->interim= true; if(!Dcache) if(data->i==syncd)goto fin_ex;else goto next_sync; /*368:*/ #line 6402 "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 6359 "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 6413 "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 6369 "mmix-pipe.w" ; data->go.known= true; goto fin_ex; /*:364*//*370:*/ #line 6428 "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 2525 "mmix-pipe.w" ; } /*:135*/ #line 2371 "mmix-pipe.w" ; /*126:*/ #line 2381 "mmix-pipe.w" case vanish:goto terminate; /*:126*//*215:*/ #line 3761 "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 3773 "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;jbb>>c->g;j++){ ii= i+del; if(!c->outbuf.dirty[j])i= ii,off+= del,addr.l+= del<<3; else while(ioutbuf.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 3768 "mmix-pipe.w" ; case 2:goto terminate; } } /*:215*//*217:*/ #line 3812 "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 3851 "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;jbb>>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 3825 "mmix-pipe.w" ; case 3:/*218:*/ #line 3841 "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 3826 "mmix-pipe.w" ; if(block_diff)/*220:*/ #line 3867 "mmix-pipe.w" { register octa*d= p->data; p->data= Scache->inbuf.data;Scache->inbuf.data= d; } /*:220*/ #line 3827 "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 3875 "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;jbb>>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 3837 "mmix-pipe.w" ; } } /*:217*//*222:*/ #line 3904 "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 3931 "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;iinbuf.data[i]= mem_hash[last_h].chunk[off]; if(count<=bus_words)wait(1+mem_read_time) else wait((int)(count/bus_words)*mem_read_time); } /*:223*/ #line 3914 "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 3946 "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 3984 "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 3954 "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 3997 "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;jbb>>3;j++,off++) c->inbuf.data[j]= p->data[off]; release_lock(self,Scache->fill_lock); set_lock(self,Scache->lock); } /*:226*/ #line 3966 "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 4068 "mmix-pipe.w" case cleanup:p= (cacheblock*)data->ptr_b; switch(data->state){ /*233:*/ #line 4076 "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= (icc?&(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(icc&&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 4071 "mmix-pipe.w" ; /*234:*/ #line 4122 "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= (icc?&(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(icc&&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 4072 "mmix-pipe.w" ; case 10:goto terminate; } /*:232*//*237:*/ #line 4237 "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 4322 "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]z.o= zero_octa; /*244:*/ #line 4342 "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 4335 "mmix-pipe.w" ; } /*:243*/ #line 4244 "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 4363 "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 4251 "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 4534 "mmix-pipe.w" case write_from_wbuf: p= (cacheblock*)data->ptr_b; switch(data->state){ case 4:/*263:*/ #line 4623 "mmix-pipe.w" if((Dcache->mode&WRITE_BACK)==0){ if(Dcache->flusher.next)wait(1); flush_cache(Dcache,p,true); } /*:263*/ #line 4538 "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 4629 "mmix-pipe.w" { set_lock(self,wbuf_lock); data->state= 5; wait(1); } /*:264*/ #line 4544 "mmix-pipe.w" ; if(ticks.l-write_head->stampaddr.h&0xffff0000))goto mem_direct; if(Dcache->lock||(j= get_reader(Dcache)<0))wait(1); startup(&Dcache->reader[j],Dcache->access_time); /*262:*/ #line 4612 "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 4552 "mmix-pipe.w" ; data->state= ((Dcache->mode&WRITE_ALLOC)&&write_head->i!=stunc?1:3); wait(Dcache->access_time); case 1:/*261:*/ #line 4594 "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 4556 "mmix-pipe.w" ; data->state= 2;sleep; case 2:data->state= 0;sleep; case 3:/*259:*/ #line 4570 "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;jbb>>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 4559 "mmix-pipe.w" ; mem_direct:/*260:*/ #line 4581 "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 4560 "mmix-pipe.w" ; } /*:257*/ #line 2372 "mmix-pipe.w" ; } terminate:if(self->lockloc)*(self->lockloc)= NULL,self->lockloc= NULL; done:; } /*:125*/ #line 1434 "mmix-pipe.w" ; if(!suppress_dispatch)/*74:*/ #line 1577 "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;jinst>>24;yz= head->inst&0xffff; /*80:*/ #line 1655 "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 1598 "mmix-pipe.w" ; /*100:*/ #line 1952 "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 1599 "mmix-pipe.w" ; if(f&rel_addr_bit)/*84:*/ #line 1755 "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 1600 "mmix-pipe.w" ; if(head->noted)peek_hist= head->hist; else/*85:*/ #line 1767 "mmix-pipe.w" {register int predicted= 0; if((op&0xe0)==0x40)/*151:*/ #line 2825 "mmix-pipe.w" { predicted= op&0x10; if(bp_table){register int h; m= ((head->loc.l&bp_cmask)<loc.l&bp_amask); m= ((cool_hist&bp_bcmask)<>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 1769 "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 5118 "mmix-pipe.w" if(fetch_co.lockloc)*(fetch_co.lockloc)= NULL,fetch_co.lockloc= NULL; unschedule(&fetch_co); startup(&fetch_co,1); /*:287*/ #line 1774 "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&& jo,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 1602 "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 1975 "mmix-pipe.w" if(new_cool==hot)goto stall; /*102:*/ #line 1991 "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 1977 "mmix-pipe.w" ; /*103:*/ #line 1997 "mmix-pipe.w" if(resuming) /*324:*/ #line 5709 "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 1999 "mmix-pipe.w" else{ if(f&0x10)/*106:*/ #line 2023 "mmix-pipe.w" { if(cool->xx>=cool_G)cool->b= specval(&g[cool->xx]); else if(cool->xxb= specval(&l[(cool_O.l+cool->xx)&lring_mask]); if(f&rel_addr_bit)cool->need_b= true; } /*:106*/ #line 2001 "mmix-pipe.w" if(third_operand[op]&&(cool->i!=trap)) /*108:*/ #line 2072 "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 2003 "mmix-pipe.w" ; if(f&0x1)cool->z.o.l= cool->zz; else if(f&0x2)/*104:*/ #line 2011 "mmix-pipe.w" { if(cool->zz>=cool_G)cool->z= specval(&g[cool->zz]); else if(cool->zzz= specval(&l[(cool_O.l+cool->zz)&lring_mask]); } /*:104*/ #line 2005 "mmix-pipe.w" else if((op&0xf0)==0xe0)/*109:*/ #line 2080 "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 2006 "mmix-pipe.w" ; if(f&0x4)cool->y.o.l= cool->yy; else if(f&0x8)/*105:*/ #line 2017 "mmix-pipe.w" { if(cool->yy>=cool_G)cool->y= specval(&g[cool->yy]); else if(cool->yyy= specval(&l[(cool_O.l+cool->yy)&lring_mask]); } /*:105*/ #line 2008 "mmix-pipe.w" } /*:103*/ #line 1978 "mmix-pipe.w" ; if(f&X_is_dest_bit)/*110:*/ #line 2092 "mmix-pipe.w" { if(cool->xx>=cool_G)cool->ren_x= true,spec_install(&g[cool->xx],&cool->x); else if(cool->xxren_x= true, spec_install(&l[(cool_O.l+cool->xx)&lring_mask],&cool->x); else{ increase_L:if(((cool_S.l-cool_O.l)&lring_mask)==cool_L&&cool_L!=0) /*113:*/ #line 2133 "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 2100 "mmix-pipe.w" else/*112:*/ #line 2115 "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 2101 "mmix-pipe.w" ; } } /*:110*/ #line 1980 "mmix-pipe.w" ; switch(i){ /*117:*/ #line 2182 "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 2198 "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 2222 "mmix-pipe.w" case pushgo:inst_ptr.p= &cool->go; case pushj:{register int x= cool->xx; if(x>=cool_L){ if(((cool_S.l-cool_O.l)&lring_mask)==cool_L&&cool_L!=0) /*113:*/ #line 2133 "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 2227 "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 2249 "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 2150 "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 2253 "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 2150 "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 2258 "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(xren_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 2274 "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 2295 "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 4014 "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 5465 "mmix-pipe.w" case trap:if((flags[op]&X_is_dest_bit)&& cool->xxxx>=cool_L) goto increase_L; if(!g[rT].up->known)goto stall; inst_ptr= specval(&g[rT]); cool->x.o= inst_ptr.o; cool->need_b= true,cool->b= specval(&g[255]); case trip:cool->ren_x= true,spec_install(&g[255],&cool->x); cool->x.known= true; if(i==trip)cool->x.o= cool->go.o= zero_octa; cool->ren_a= true,spec_install(&g[i==trap?rBB:rB],&cool->a);break; /*:312*//*322:*/ #line 5642 "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 6455 "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 6586 "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 6462 "mmix-pipe.w" ; switch(yy){ case Halt:/*373:*/ #line 6479 "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 6464 "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 5654 "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 5677 "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<b.o.l>>16)&0xff; if(m>=cool_L&&minst= 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 5661 "mmix-pipe.w" ; }break; /*:322*//*332:*/ #line 5848 "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 5871 "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 5856 "mmix-pipe.w" ;break; case 1:case 2:/*333:*/ #line 5865 "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 5857 "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 5903 "mmix-pipe.w" case save:if(cool->xxinterrupt|= B_BIT; if(cool->interrupt&B_BIT)cool->i= noop; else if(((cool_S.l-cool_O.l)&lring_mask)==cool_L&&cool_L!=0) /*113:*/ #line 2133 "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 5907 "mmix-pipe.w" else{ cool->interim= true; cool->i= sav; switch(cool->zz){ case 0:/*338:*/ #line 5926 "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 5912 "mmix-pipe.w" ;break; case 1:if(cool_O.l!=cool_S.l)/*113:*/ #line 2133 "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 5913 "mmix-pipe.w" cool->zz= 2;cool->yy= cool_G; case 2:case 3:/*339:*/ #line 5933 "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 5944 "mmix-pipe.w" { cool->i= save; cool->interim= false; cool->ren_a= true,spec_install(&g[cool->xx],&cool->a); } /*:340*/ #line 5938 "mmix-pipe.w" else cool->b= specval(&g[cool->yy]); /*:339*/ #line 5915 "mmix-pipe.w" ;break; default:cool->interim= false,cool->i= noop,cool->interrupt|= B_BIT;break; } } break; /*:337*//*347:*/ #line 6087 "mmix-pipe.w" case fsqrt:case fint:case fix:case flot:if(cool->y.o.l> 4) goto illegal_inst; break; /*:347*//*355:*/ #line 6209 "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 1982 "mmix-pipe.w" default:break; } dispatch_done: /*:101*/ #line 1608 "mmix-pipe.w" ; /*82:*/ #line 1692 "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;ik;i++)if(u->co[i].next)goto unit_busy; goto unit_found; unit_busy:; } for(u= funit;uops[t]&b)&&(u->co->next==NULL))goto unit_found; goto stall; } unit_found: /*:82*/ #line 1609 "mmix-pipe.w" ; /*111:*/ #line 2105 "mmix-pipe.w" if(rename_regsren_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 1610 "mmix-pipe.w" ; if((op&0xe0)==0x40)/*152:*/ #line 2842 "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)<loc.l&bp_amask); m= ((cool_hist&bp_bcmask)<>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 1611 "mmix-pipe.w" ; /*81:*/ #line 1662 "mmix-pipe.w" if(cool->interim){ cool->usage= false; if(cool->op==SAVE)/*341:*/ #line 5951 "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 1665 "mmix-pipe.w" else if(cool->op==UNSAVE)/*335:*/ #line 5878 "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 1666 "mmix-pipe.w" else if(cool->i==preld||cool->i==prest) /*228:*/ #line 4032 "mmix-pipe.w" head->inst= (head->inst&~((Dcache->bb-1)<<16))-0x10000; /*:228*/ #line 1668 "mmix-pipe.w" else if(cool->i==prego)/*229:*/ #line 4035 "mmix-pipe.w" head->inst= (head->inst&~((Icache->bb-1)<<16))-0x10000; /*:229*/ #line 1669 "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 1612 "mmix-pipe.w" ; cool= new_cool;cool_O= new_O;cool_S= new_S; cool_hist= peek_hist;continue; stall:/*123:*/ #line 2302 "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 1616 "mmix-pipe.w" ; } /*:75*/ #line 1585 "mmix-pipe.w" ; head= true_head; } /*:74*/ #line 1435 "mmix-pipe.w" ; ticks= incr(ticks,1); dispatch_stat[dispatch_count]++; } /*:64*/ #line 227 "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 608 "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 2971 "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 3217 "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 3242 "mmix-pipe.w" for(i= 0;icc;i++)for(j= 0;jaa;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;jvv;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 3235 "mmix-pipe.w" ; } } /*:176*//*179:*/ #line 3261 "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;jbb>>3;j++)p->data[j]= zero_octa; for(j= 0;jbb>>c->g;j++)p->dirty[j]= false; } /*:179*//*181:*/ #line 3281 "mmix-pipe.w" void zap_cache(c) cache*c; { register int i,j; for(i= 0;icc;i++)for(j= 0;jaa;j++){ clean_block(c,&(c->set[i][j])); } for(j= 0;jvv;j++){ clean_block(c,&(c->victim[j])); } } /*:181*//*210:*/ #line 3680 "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 3708 "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 4443 "mmix-pipe.w" void print_pipe() { print_write_buffer(); print_reorder_buffer(); print_fetch_buffer(); } /*:253*/ #line 135 "mmix-pipe.w" /*:3*/