#define mm 0x98 \ #define lop_quote 0x0 #define lop_loc 0x1 #define lop_skip 0x2 #define lop_fixo 0x3 #define lop_fixr 0x4 #define lop_fixrx 0x5 #define lop_file 0x6 #define lop_line 0x7 #define lop_spec 0x8 #define lop_pre 0x9 #define lop_post 0xa #define lop_stab 0xb #define lop_end 0xc \ #define err(m) {report_error(m) ;if(m[0]!='*') goto bypass;} #define derr(m,p) {sprintf(err_buf,m,p) ; \ report_error(err_buf) ;if(err_buf[0]!='*') goto bypass;} #define dderr(m,p,q) {sprintf(err_buf,m,p,q) ; \ report_error(err_buf) ;if(err_buf[0]!='*') goto bypass;} #define panic(m) {sprintf(err_buf,"!%s",m) ;report_error(err_buf) ;} #define dpanic(m,p) {err_buf[0]= '!';sprintf(err_buf+1,m,p) ; \ report_error(err_buf) ;} \ #define mmo_write(buf) if(fwrite(buf,1,4,obj_file) !=4) \ dpanic("Can't write on %s",obj_file_name) \ \ #define isletter(c) (isalpha(c) ||c=='_'||c==':'||c> 126) \ #define DEFINED (sym_node*) 1 #define REGISTER (sym_node*) 2 #define PREDEFINED (sym_node*) 3 #define fix_o 0 #define fix_yz 1 #define fix_xyz 2 \ #define recycle_fixup(pp) pp->link= sym_avail,sym_avail= pp \ #define rel_addr_bit 0x1 #define immed_bit 0x2 #define zar_bit 0x4 #define zr_bit 0x8 #define yar_bit 0x10 #define yr_bit 0x20 #define xar_bit 0x40 #define xr_bit 0x80 #define yzar_bit 0x100 #define yzr_bit 0x200 #define xyzar_bit 0x400 #define xyzr_bit 0x800 #define one_arg_bit 0x1000 #define two_arg_bit 0x2000 #define three_arg_bit 0x4000 #define many_arg_bit 0x8000 #define align_bits 0x30000 #define no_label_bit 0x40000 #define mem_bit 0x80000 #define spec_bit 0x100000 \ #define top_op op_stack[op_ptr-1] #define top_val val_stack[val_ptr-1] #define next_val val_stack[val_ptr-2] \ #define unary_check(verb) if(top_val.status!=pure) \ derr("can %s pure values only",verb) \ #define binary_check(verb) \ if(top_val.status!=pure||next_val.status!=pure) \ derr("can %s pure values only",verb) \ #define SETH 0xe0 #define ORH 0xe8 #define ORL 0xeb \ /*136:*/ #line 3136 "mmixal.w" #include #include #include #include #include /*31:*/ #line 1008 "mmixal.w" #ifdef __STDC__ #define ARGS(list) list #else #define ARGS(list) () #endif /*:31*//*39:*/ #line 1104 "mmixal.w" #ifndef FILENAME_MAX #define FILENAME_MAX 256 #endif /*:39*/ #line 3143 "mmixal.w" /*26:*/ #line 943 "mmixal.w" typedef unsigned int tetra; typedef struct{tetra h,l;}octa; typedef enum{false,true}bool; /*:26*//*30:*/ #line 999 "mmixal.w" typedef unsigned char Char; /*:30*//*54:*/ #line 1426 "mmixal.w" typedef struct ternary_trie_struct{ unsigned short ch; struct ternary_trie_struct*left,*mid,*right; struct sym_tab_struct*sym; }trie_node; /*:54*//*58:*/ #line 1530 "mmixal.w" typedef struct sym_tab_struct{ int serial; struct sym_tab_struct*link; octa equiv; }sym_node; /*:58*//*62:*/ #line 1611 "mmixal.w" typedef struct{ Char*name; short code; int bits; }op_spec; typedef enum{ SET= 0x100,IS,LOC,PREFIX,BSPEC,ESPEC,GREG,LOCAL, BYTE,WYDE,TETRA,OCTA}pseudo_op; /*:62*//*68:*/ #line 1975 "mmixal.w" typedef struct{ Char*name; tetra h,l; }predef_spec; /*:68*//*82:*/ #line 2280 "mmixal.w" typedef enum{negate,serialize,complement,registerize,inner_lp, plus,minus,times,over,frac,mod,shl,shr,and,or,xor, outer_lp,outer_rp,inner_rp}stack_op; typedef enum{zero,weak,strong,unary}prec; typedef enum{pure,reg_val,undefined}stat; typedef struct{ octa equiv; trie_node*link; stat status; }val_node; /*:82*/ #line 3144 "mmixal.w" /*27:*/ #line 949 "mmixal.w" extern octa zero_octa; extern octa neg_one; extern octa aux; extern bool overflow; /*:27*//*33:*/ #line 1031 "mmixal.w" Char*buffer; Char*buf_ptr; Char*lab_field; Char*op_field; Char*operand_list; Char*err_buf; /*:33*//*36:*/ #line 1061 "mmixal.w" int cur_file; int line_no; bool line_listed; bool long_warning_given; /*:36*//*37:*/ #line 1071 "mmixal.w" Char*filename[257]; int filename_count; /*:37*//*43:*/ #line 1155 "mmixal.w" octa cur_loc; octa listing_loc; unsigned char hold_buf[4]; unsigned char held_bits; unsigned char listing_bits; bool spec_mode; tetra spec_mode_loc; /*:43*//*46:*/ #line 1239 "mmixal.w" int err_count; /*:46*//*51:*/ #line 1369 "mmixal.w" octa mmo_cur_loc; int mmo_line_no; int mmo_cur_file; char filename_passed[256]; /*:51*//*56:*/ #line 1451 "mmixal.w" trie_node*trie_root; trie_node*op_root; trie_node*next_trie_node,*last_trie_node; trie_node*cur_prefix; /*:56*//*60:*/ #line 1565 "mmixal.w" int serial_number; sym_node*sym_root; sym_node*next_sym_node,*last_sym_node; sym_node*sym_avail; /*:60*//*63:*/ #line 1622 "mmixal.w" op_spec op_init_table[]= { {"TRAP",0x00,0x27554}, {"FCMP",0x01,0x240a8}, {"FUN",0x02,0x240a8}, {"FEQL",0x03,0x240a8}, {"FADD",0x04,0x240a8}, {"FIX",0x05,0x26288}, {"FSUB",0x06,0x240a8}, {"FIXU",0x07,0x26288}, {"FLOT",0x08,0x26282}, {"FLOTU",0x0a,0x26282}, {"SFLOT",0x0c,0x26282}, {"SFLOTU",0x0e,0x26282}, {"FMUL",0x10,0x240a8}, {"FCMPE",0x11,0x240a8}, {"FUNE",0x12,0x240a8}, {"FEQLE",0x13,0x240a8}, {"FDIV",0x14,0x240a8}, {"FSQRT",0x15,0x26288}, {"FREM",0x16,0x240a8}, {"FINT",0x17,0x26288}, {"MUL",0x18,0x240a2}, {"MULU",0x1a,0x240a2}, {"DIV",0x1c,0x240a2}, {"DIVU",0x1e,0x240a2}, {"ADD",0x20,0x240a2}, {"ADDU",0x22,0x240a2}, {"SUB",0x24,0x240a2}, {"SUBU",0x26,0x240a2}, {"2ADDU",0x28,0x240a2}, {"4ADDU",0x2a,0x240a2}, {"8ADDU",0x2c,0x240a2}, {"16ADDU",0x2e,0x240a2}, {"CMP",0x30,0x240a2}, {"CMPU",0x32,0x240a2}, {"NEG",0x34,0x26082}, {"NEGU",0x36,0x26082}, {"SL",0x38,0x240a2}, {"SLU",0x3a,0x240a2}, {"SR",0x3c,0x240a2}, {"SRU",0x3e,0x240a2}, {"BN",0x40,0x22081}, {"BZ",0x42,0x22081}, {"BP",0x44,0x22081}, {"BOD",0x46,0x22081}, {"BNN",0x48,0x22081}, {"BNZ",0x4a,0x22081}, {"BNP",0x4c,0x22081}, {"BEV",0x4e,0x22081}, {"PBN",0x50,0x22081}, {"PBZ",0x52,0x22081}, {"PBP",0x54,0x22081}, {"PBOD",0x56,0x22081}, {"PBNN",0x58,0x22081}, {"PBNZ",0x5a,0x22081}, {"PBNP",0x5c,0x22081}, {"PBEV",0x5e,0x22081}, {"CSN",0x60,0x240a2}, {"CSZ",0x62,0x240a2}, {"CSP",0x64,0x240a2}, {"CSOD",0x66,0x240a2}, {"CSNN",0x68,0x240a2}, {"CSNZ",0x6a,0x240a2}, {"CSNP",0x6c,0x240a2}, {"CSEV",0x6e,0x240a2}, {"ZSN",0x70,0x240a2}, {"ZSZ",0x72,0x240a2}, {"ZSP",0x74,0x240a2}, {"ZSOD",0x76,0x240a2}, {"ZSNN",0x78,0x240a2}, {"ZSNZ",0x7a,0x240a2}, {"ZSNP",0x7c,0x240a2}, {"ZSEV",0x7e,0x240a2}, {"LDB",0x80,0xa60a2}, {"LDBU",0x82,0xa60a2}, {"LDW",0x84,0xa60a2}, {"LDWU",0x86,0xa60a2}, {"LDT",0x88,0xa60a2}, {"LDTU",0x8a,0xa60a2}, {"LDO",0x8c,0xa60a2}, {"LDOU",0x8e,0xa60a2}, {"LDSF",0x90,0xa60a2}, {"LDHT",0x92,0xa60a2}, {"CSWAP",0x94,0xa60a2}, {"LDUNC",0x96,0xa60a2}, {"LDVTS",0x98,0xa60a2}, {"PRELD",0x9a,0xa6022}, {"PREGO",0x9c,0xa6022}, {"GO",0x9e,0xa60a2}, {"STB",0xa0,0xa60a2}, {"STBU",0xa2,0xa60a2}, {"STW",0xa4,0xa60a2}, {"STWU",0xa6,0xa60a2}, {"STT",0xa8,0xa60a2}, {"STTU",0xaa,0xa60a2}, {"STO",0xac,0xa60a2}, {"STOU",0xae,0xa60a2}, {"STSF",0xb0,0xa60a2}, {"STHT",0xb2,0xa60a2}, {"STCO",0xb4,0xa6022}, {"STUNC",0xb6,0xa60a2}, {"SYNCD",0xb8,0xa6022}, {"PREST",0xba,0xa6022}, {"SYNCID",0xbc,0xa6022}, {"PUSHGO",0xbe,0xa6062}, {"OR",0xc0,0x240a2}, {"ORN",0xc2,0x240a2}, {"NOR",0xc4,0x240a2}, {"XOR",0xc6,0x240a2}, {"AND",0xc8,0x240a2}, {"ANDN",0xca,0x240a2}, {"NAND",0xcc,0x240a2}, {"NXOR",0xce,0x240a2}, {"BDIF",0xd0,0x240a2}, {"WDIF",0xd2,0x240a2}, {"TDIF",0xd4,0x240a2}, {"ODIF",0xd6,0x240a2}, {"MUX",0xd8,0x240a2}, {"SADD",0xda,0x240a2}, {"MOR",0xdc,0x240a2}, {"MXOR",0xde,0x240a2}, {"SETH",0xe0,0x22080}, {"SETMH",0xe1,0x22080}, {"SETML",0xe2,0x22080}, {"SETL",0xe3,0x22080}, {"INCH",0xe4,0x22080}, {"INCMH",0xe5,0x22080}, {"INCML",0xe6,0x22080}, {"INCL",0xe7,0x22080}, {"ORH",0xe8,0x22080}, {"ORMH",0xe9,0x22080}, {"ORML",0xea,0x22080}, {"ORL",0xeb,0x22080}, {"ANDNH",0xec,0x22080}, {"ANDNMH",0xed,0x22080}, {"ANDNML",0xee,0x22080}, {"ANDNL",0xef,0x22080}, {"JMP",0xf0,0x21001}, {"PUSHJ",0xf2,0x22041}, {"GETA",0xf4,0x22081}, {"PUT",0xf6,0x22002}, {"POP",0xf8,0x23000}, {"RESUME",0xf9,0x21000}, {"SAVE",0xfa,0x22080}, {"UNSAVE",0xfb,0x23a00}, {"SYNC",0xfc,0x21000}, {"SWYM",0xfd,0x27554}, {"GET",0xfe,0x22080}, {"TRIP",0xff,0x27554}, {"SET",SET,0x22180}, {"LDA",0x22,0xa60a2}, {"IS",IS,0x101400}, {"LOC",LOC,0x1400}, {"PREFIX",PREFIX,0x141000}, {"BYTE",BYTE,0x10f000}, {"WYDE",WYDE,0x11f000}, {"TETRA",TETRA,0x12f000}, {"OCTA",OCTA,0x13f000}, {"BSPEC",BSPEC,0x41400}, {"ESPEC",ESPEC,0x141000}, {"GREG",GREG,0x101000}, {"LOCAL",LOCAL,0x141800}}; int op_init_size; /*:63*//*67:*/ #line 1969 "mmixal.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"}; /*:67*//*69:*/ #line 1981 "mmixal.w" predef_spec predefs[]= { {"ROUND_CURRENT",0,0}, {"ROUND_OFF",0,1}, {"ROUND_UP",0,2}, {"ROUND_DOWN",0,3}, {"ROUND_NEAR",0,4}, {"Inf",0x7ff00000,0}, {"Data_Segment",0x20000000,0}, {"Pool_Segment",0x40000000,0}, {"Stack_Segment",0x60000000,0}, {"D_BIT",0,0x80}, {"V_BIT",0,0x40}, {"W_BIT",0,0x20}, {"I_BIT",0,0x10}, {"O_BIT",0,0x08}, {"U_BIT",0,0x04}, {"Z_BIT",0,0x02}, {"X_BIT",0,0x01}, {"D_Handler",0,0x10}, {"V_Handler",0,0x20}, {"W_Handler",0,0x30}, {"I_Handler",0,0x40}, {"O_Handler",0,0x50}, {"U_Handler",0,0x60}, {"Z_Handler",0,0x70}, {"X_Handler",0,0x80}, {"StdIn",0,0}, {"StdOut",0,1}, {"StdErr",0,2}, {"TextRead",0,0}, {"TextWrite",0,1}, {"BinaryRead",0,2}, {"BinaryWrite",0,3}, {"BinaryReadWrite",0,4}, {"Halt",0,0}, {"Fopen",0,1}, {"Fclose",0,2}, {"Fread",0,3}, {"Fgets",0,4}, {"Fgetws",0,5}, {"Fwrite",0,6}, {"Fputs",0,7}, {"Fputws",0,8}, {"Fseek",0,9}, {"Ftell",0,10}}; int predef_size; /*:69*//*77:*/ #line 2218 "mmixal.w" Char sym_buf[1000]; Char*sym_ptr; /*:77*//*83:*/ #line 2296 "mmixal.w" stack_op*op_stack; int op_ptr; val_node*val_stack; int val_ptr; prec precedence[]= {unary,unary,unary,unary,zero, weak,weak,strong,strong,strong,strong,strong,strong,strong,weak,weak, zero,zero,zero}; stack_op rt_op; octa acc; /*:83*//*90:*/ #line 2385 "mmixal.w" trie_node forward_local_host[10],backward_local_host[10]; sym_node forward_local[10],backward_local[10]; /*:90*//*105:*/ #line 2633 "mmixal.w" tetra opcode; tetra op_bits; /*:105*//*120:*/ #line 2866 "mmixal.w" tetra z,y,x,yz,xyz; int future_bits; /*:120*//*133:*/ #line 3099 "mmixal.w" octa greg_val[256]; /*:133*//*139:*/ #line 3206 "mmixal.w" char*src_file_name; char obj_file_name[FILENAME_MAX+1]; char listing_name[FILENAME_MAX+1]; FILE*src_file,*obj_file,*listing_file; int expanding; int buf_size; /*:139*//*143:*/ #line 3238 "mmixal.w" int greg= 255; int cur_greg; int lreg= 32; /*:143*/ #line 3145 "mmixal.w" /*28:*/ #line 961 "mmixal.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 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 odiv ARGS((octa x,octa y,octa z)); /*:28*//*41:*/ #line 1126 "mmixal.w" void flush_listing_line ARGS((char*)); void flush_listing_line(s) char*s; { if(line_listed)fprintf(listing_file,"\n"); else{ fprintf(listing_file,"%s%s\n",s,buffer); line_listed= true; } } /*:41*//*42:*/ #line 1142 "mmixal.w" void update_listing_loc ARGS((int)); void update_listing_loc(k) int k; { if(cur_loc.h!=listing_loc.h||((cur_loc.l^listing_loc.l)&0xfffff000)){ fprintf(listing_file,"%08x%08x:",cur_loc.h,(cur_loc.l&-4)|k); flush_listing_line(" "); } listing_loc.h= cur_loc.h; listing_loc.l= (cur_loc.l&-4)|k; } /*:42*//*44:*/ #line 1176 "mmixal.w" void listing_clear ARGS((void)); void listing_clear() { register int j,k; for(k= 0;k<4;k++)if(listing_bits&(1<>24;mmo_buf[1]= (t>>16)&0xff; mmo_buf[2]= (t>>8)&0xff;mmo_buf[3]= t&0xff; mmo_out(); } void mmo_byte(b) unsigned char b; { mmo_buf[(mmo_ptr++)&3]= b; if(!(mmo_ptr&3))mmo_out(); } void mmo_lop(x,y,z) char x; unsigned char y,z; { mmo_buf[0]= mm;mmo_buf[1]= x;mmo_buf[2]= y;mmo_buf[3]= z; mmo_out(); } void mmo_lopp(x,yz) char x; unsigned short yz; { mmo_buf[0]= mm;mmo_buf[1]= x; mmo_buf[2]= yz>>8;mmo_buf[3]= yz&0xff; mmo_out(); } /*:48*//*49:*/ #line 1316 "mmixal.w" void mmo_loc ARGS((void)); void mmo_loc() { octa o; if(held_bits)mmo_clear(); o= ominus(cur_loc,mmo_cur_loc); if(o.h==0&&o.l<0x10000){ if(o.l)mmo_lopp(lop_skip,o.l); }else{ if(cur_loc.h&0xffffff){ mmo_lop(lop_loc,0,2); mmo_tetra(cur_loc.h); }else mmo_lop(lop_loc,cur_loc.h>>24,1); mmo_tetra(cur_loc.l); } mmo_cur_loc= cur_loc; } /*:49*//*50:*/ #line 1338 "mmixal.w" void mmo_sync ARGS((void)); void mmo_sync() { register int j;register unsigned char*p; if(cur_file!=mmo_cur_file){ if(filename_passed[cur_file])mmo_lop(lop_file,cur_file,0); else{ mmo_lop(lop_file,cur_file,(strlen(filename[cur_file])+3)>>2); for(j= 0,p= filename[cur_file];*p;p++,j= (j+1)&3){ mmo_buf[j]= *p; if(j==3)mmo_out(); } if(j){ for(;j<4;j++)mmo_buf[j]= 0; mmo_out(); } filename_passed[cur_file]= 1; } mmo_cur_file= cur_file; mmo_line_no= 0; } if(line_no!=mmo_line_no){ if(line_no>=0x10000) panic("I can't deal with line numbers exceeding 65535"); mmo_lopp(lop_line,line_no); mmo_line_no= line_no; } } /*:50*//*52:*/ #line 1380 "mmixal.w" void assemble ARGS((char,tetra,unsigned char)); void assemble(k,dat,x_bits) char k; tetra dat; unsigned char x_bits; { register int j,jj,l; if(spec_mode)l= spec_mode_loc; else{ l= cur_loc.l; /*53:*/ #line 1408 "mmixal.w" if(cur_loc.h!=mmo_cur_loc.h||((cur_loc.l^mmo_cur_loc.l)&0xfffffffc)) mmo_loc(); /*:53*/ #line 1391 "mmixal.w" ; if(!held_bits&&!(cur_loc.h&0xe0000000))mmo_sync(); } for(j= 0;j>(8*(k-1-j)))&0xff; held_bits|= 1<mid){ tt= tt->mid; while(*p!=tt->ch){ if(*pch){ if(tt->left)tt= tt->left; else{ tt->left= new_trie_node();tt= tt->left;goto store_new_char; } }else{ if(tt->right)tt= tt->right; else{ tt->right= new_trie_node();tt= tt->right;goto store_new_char; } } } p++; }else{ tt->mid= new_trie_node();tt= tt->mid; store_new_char:tt->ch= *p++; } } } /*:57*//*59:*/ #line 1543 "mmixal.w" sym_node*new_sym_node ARGS((bool)); sym_node*new_sym_node(serialize) bool serialize; { register sym_node*p= sym_avail; if(p){ sym_avail= p->link;p->link= NULL;p->serial= 0;p->equiv= zero_octa; }else{ p= next_sym_node; if(p==last_sym_node){ p= (sym_node*)calloc(1000,sizeof(sym_node)); if(!p)panic("Capacity exceeded: Out of symbol memory"); last_sym_node= p+1000; } next_sym_node= p+1; } if(serialize)p->serial= ++serial_number; return p; } /*:59*//*73:*/ #line 2129 "mmixal.w" trie_node*prune ARGS((trie_node*)); trie_node*prune(t) trie_node*t; { register int useful= 0; if(t->sym){ if(t->sym->serial)useful= 1; else t->sym= NULL; } if(t->left){ t->left= prune(t->left); if(t->left)useful= 1; } if(t->mid){ t->mid= prune(t->mid); if(t->mid)useful= 1; } if(t->right){ t->right= prune(t->right); if(t->right)useful= 1; } if(useful)return t; else return NULL; } /*:73*//*74:*/ #line 2157 "mmixal.w" void out_stab ARGS((trie_node*)); void out_stab(t) trie_node*t; { register int m= 0,j; register sym_node*pp; if(t->ch> 0xff)m+= 0x80; if(t->left)m+= 0x40; if(t->mid)m+= 0x20; if(t->right)m+= 0x10; if(t->sym){ if(t->sym->link==REGISTER)m+= 0xf; else if(t->sym->link==DEFINED) /*76:*/ #line 2205 "mmixal.w" {register tetra x; if((t->sym->equiv.h&0xffff0000)==0x20000000) m+= 8,x= t->sym->equiv.h-0x20000000; else x= t->sym->equiv.h; if(x)m+= 4;else x= t->sym->equiv.l; for(j= 1;j<4;j++)if(x<(1<<(8*j)))break; m+= j; } /*:76*/ #line 2171 "mmixal.w" else if(t->sym->link||t->sym->serial==1)/*79:*/ #line 2241 "mmixal.w" { *sym_ptr= (m&0x80?'?':t->ch); *(sym_ptr+1)= '\0'; fprintf(stderr,"undefined symbol: %s\n",sym_buf+1); err_count++; m+= 2; } /*:79*/ #line 2172 "mmixal.w" ; } mmo_byte(m); if(t->left)out_stab(t->left); if(m&0x2f)/*75:*/ #line 2185 "mmixal.w" { if(m&0x80)mmo_byte(t->ch>>8); mmo_byte(t->ch&0xff); *sym_ptr++= (m&0x80?'?':t->ch); m&= 0xf;if(m&&t->sym->link){ if(listing_file)/*78:*/ #line 2228 "mmixal.w" { *sym_ptr= '\0'; fprintf(listing_file," %s = ",sym_buf+1); pp= t->sym; if(pp->link==DEFINED) fprintf(listing_file,"#%08x%08x",pp->equiv.h,pp->equiv.l); else if(pp->link==REGISTER) fprintf(listing_file,"$%03d",pp->equiv.l); else fprintf(listing_file,"?"); fprintf(listing_file," (%d)\n",pp->serial); } /*:78*/ #line 2191 "mmixal.w" ; if(m==15)m= 1; else if(m> 8)m-= 8; for(;m> 0;m--) if(m> 4)mmo_byte((t->sym->equiv.h>>(8*(m-5)))&0xff); else mmo_byte((t->sym->equiv.l>>(8*(m-1)))&0xff); for(m= 0;m<4;m++)if(t->sym->serial<(1<<(7*(m+1))))break; for(;m>=0;m--) mmo_byte(((t->sym->serial>>(7*m))&0x7f)+(m?0:0x80)); } if(t->mid)out_stab(t->mid); sym_ptr--; } /*:75*/ #line 2176 "mmixal.w" ; if(t->right)out_stab(t->right); } /*:74*/ #line 3146 "mmixal.w" int main(argc,argv) int argc; char*argv[]; { register int j,k; /*40:*/ #line 1109 "mmixal.w" register Char*p,*q; /*:40*//*65:*/ #line 1957 "mmixal.w" register trie_node*tt; register sym_node*pp,*qq; /*:65*/ #line 3153 "mmixal.w" ; /*137:*/ #line 3173 "mmixal.w" for(j= 1;jmid= op_root; trie_root->ch= ':'; op_root->ch= '^'; /*64:*/ #line 1948 "mmixal.w" op_init_size= (sizeof op_init_table)/sizeof(op_spec); for(j= 0;jsym= new_sym_node(false); pp->link= PREDEFINED; pp->equiv.h= op_init_table[j].code,pp->equiv.l= op_init_table[j].bits; } /*:64*/ #line 1583 "mmixal.w" ; /*66:*/ #line 1961 "mmixal.w" for(j= 0;j<32;j++){ tt= trie_search(trie_root,special_name[j]); pp= tt->sym= new_sym_node(false); pp->link= PREDEFINED; pp->equiv.l= j; } /*:66*/ #line 1584 "mmixal.w" ; /*70:*/ #line 2074 "mmixal.w" predef_size= (sizeof predefs)/sizeof(predef_spec); for(j= 0;jsym= new_sym_node(false); pp->link= PREDEFINED; pp->equiv.h= predefs[j].h,pp->equiv.l= predefs[j].l; } /*:70*/ #line 1585 "mmixal.w" ; /*:61*//*71:*/ #line 2088 "mmixal.w" trie_search(trie_root,"Main")->sym= new_sym_node(true); /*:71*//*84:*/ #line 2307 "mmixal.w" op_stack= (stack_op*)calloc(buf_size,sizeof(stack_op)); val_stack= (val_node*)calloc(buf_size,sizeof(val_node)); if(!op_stack||!val_stack)panic("No room for the stacks"); /*:84*//*91:*/ #line 2391 "mmixal.w" for(j= 0;j<10;j++){ forward_local_host[j].sym= &forward_local[j]; backward_local_host[j].sym= &backward_local[j]; backward_local[j].link= DEFINED; } /*:91*//*140:*/ #line 3214 "mmixal.w" /*138:*/ #line 3189 "mmixal.w" src_file= fopen(src_file_name,"r"); if(!src_file)dpanic("Can't open the source file %s",src_file_name); if(!obj_file_name[0]){ j= strlen(src_file_name); if(src_file_name[j-1]=='s'){ strcpy(obj_file_name,src_file_name);obj_file_name[j-1]= 'o'; }else sprintf(obj_file_name,"%s.mmo",src_file_name); } obj_file= fopen(obj_file_name,"wb"); if(!obj_file)dpanic("Can't open the object file %s",obj_file_name); if(listing_name[0]){ listing_file= fopen(listing_name,"w"); if(!listing_file)dpanic("Can't open the listing file %s",listing_name); } /*:138*/ #line 3215 "mmixal.w" ; filename[0]= src_file_name; filename_count= 1; /*141:*/ #line 3220 "mmixal.w" mmo_lop(lop_pre,1,1); mmo_tetra(time(NULL)); mmo_cur_file= -1; /*:141*/ #line 3218 "mmixal.w" ; /*:140*/ #line 3155 "mmixal.w" ; while(1){ /*34:*/ #line 1039 "mmixal.w" if(!fgets(buffer,buf_size+1,src_file))break; line_no++; line_listed= false; j= strlen(buffer); if(buffer[j-1]=='\n')buffer[j-1]= '\0'; else if(fgetc(src_file)!=EOF)/*35:*/ #line 1049 "mmixal.w" { do j= fgetc(src_file);while(j!='\n'&&j!=EOF); if(!long_warning_given){ long_warning_given= true; err("*trailing characters of long input line have been dropped"); fprintf(stderr, "(say `-b ' to increase the length of my input buffer)\n"); }else err("*trailing characters dropped"); } /*:35*/ #line 1045 "mmixal.w" ; if(buffer[0]=='#')/*38:*/ #line 1079 "mmixal.w" { for(p= buffer+1;isspace(*p);p++); for(j= *p++-'0';isdigit(*p);p++)j= 10*j+*p-'0'; for(;isspace(*p);p++); if(*p=='\"'){ if(!filename[filename_count]){ filename[filename_count]= (Char*)calloc(FILENAME_MAX+1,sizeof(Char)); if(!filename[filename_count]) panic("Capacity exceeded: Out of filename memory"); } for(p++,q= filename[filename_count];*p&&*p!='\"';p++,q++)*q= *p; if(*p=='\"'&&*(p-1)!='\"'){ *q= '\0'; for(k= 0;strcmp(filename[k],filename[filename_count])!=0;k++); if(k==filename_count)filename_count++; cur_file= k; line_no= j-1; } } } /*:38*/ #line 1046 "mmixal.w" ; buf_ptr= buffer; /*:34*/ #line 3157 "mmixal.w" ; while(1){ /*102:*/ #line 2577 "mmixal.w" p= buf_ptr;buf_ptr= ""; /*103:*/ #line 2598 "mmixal.w" if(!*p)goto bypass; q= lab_field; if(!isspace(*p)){ if(!isdigit(*p)&&!isletter(*p))goto bypass; for(*q++= *p++;isdigit(*p)||isletter(*p);p++,q++)*q= *p; if(*p&&!isspace(*p))derr("label syntax error at `%c'",*p); } *q= '\0'; if(isdigit(lab_field[0])&&(lab_field[1]!='H'||lab_field[2])) derr("improper local label `%s'",lab_field); for(p++;isspace(*p);p++); /*:103*/ #line 2579 "mmixal.w" ; /*104:*/ #line 2616 "mmixal.w" q= op_field; while(isletter(*p)||isdigit(*p))*q++= *p++; *q= '\0'; if(!isspace(*p)&&*p&&op_field[0])derr("opcode syntax error at `%c'",*p); pp= trie_search(op_root,op_field)->sym; if(!pp){ if(op_field[0])derr("unknown operation code `%s'",op_field); if(lab_field[0])derr("*no opcode; label `%s' will be ignored",lab_field); goto bypass; } opcode= pp->equiv.h,op_bits= pp->equiv.l; while(isspace(*p))p++; /*:104*/ #line 2580 "mmixal.w" ; /*106:*/ #line 2640 "mmixal.w" q= operand_list; while(*p){ if(*p==';')break; if(*p=='\''){ *q++= *p++; if(!*p)err("incomplete character constant"); *q++= *p++; if(*p!='\'')err("illegal character constant"); }else if(*p=='\"'){ for(*q++= *p++;*p&&*p!='\"';p++,q++)*q= *p; if(!*p)err("incomplete string constant"); } *q++= *p++; if(isspace(*p))break; } while(isspace(*p))p++; if(*p==';')p++; else p= ""; if(q==operand_list)*q++= '0'; *q= '\0'; /*:106*/ #line 2581 "mmixal.w" ; buf_ptr= p; if(spec_mode&&!(op_bits&spec_bit)) derr("cannot use `%s' in special mode",op_field); if((op_bits&no_label_bit)&&lab_field[0]){ derr("*label field of `%s' instruction is ignored",op_field); lab_field[0]= '\0'; } if(op_bits&align_bits)/*107:*/ #line 2667 "mmixal.w" { j= (op_bits&align_bits)>>16; acc.h= -1,acc.l= -(1<sym; if(!pp)pp= tt->sym= new_sym_node(true); top_val.link= tt,top_val.equiv= pp->equiv; if(pp->link==PREDEFINED)pp->link= DEFINED; top_val.status= (pp->link==DEFINED?pure:pp->link==REGISTER?reg_val: undefined); } /*:87*/ #line 2333 "mmixal.w" else if(isdigit(*p)){ if(*(p+1)=='F')/*88:*/ #line 2372 "mmixal.w" { tt= &forward_local_host[*p-'0'];p+= 2;goto symbol_found; } /*:88*/ #line 2335 "mmixal.w" else if(*(p+1)=='B')/*89:*/ #line 2377 "mmixal.w" { tt= &backward_local_host[*p-'0'];p+= 2;goto symbol_found; } /*:89*/ #line 2336 "mmixal.w" else/*94:*/ #line 2414 "mmixal.w" acc.h= 0,acc.l= *p-'0'; for(p++;isdigit(*p);p++){ acc= oplus(acc,shift_left(acc,2)); acc= incr(shift_left(acc,1),*p-'0'); } constant_found:val_ptr++; top_val.link= NULL; top_val.equiv= acc; top_val.status= pure; /*:94*/ #line 2337 "mmixal.w" ; }else switch(*p++){ case'#':/*95:*/ #line 2425 "mmixal.w" if(!isxdigit(*p))err("illegal hexadecimal constant"); acc.h= acc.l= 0; for(;isxdigit(*p);p++){ acc= incr(shift_left(acc,4),*p-'0'); if(*p>='a')acc= incr(acc,'0'-'a'+10); else if(*p>='A')acc= incr(acc,'0'-'A'+10); } goto constant_found; /*:95*/ #line 2339 "mmixal.w" ;break; case'\'':/*92:*/ #line 2400 "mmixal.w" acc.h= 0,acc.l= *p; p+= 2; goto constant_found; /*:92*/ #line 2340 "mmixal.w" ;break; case'\"':/*93:*/ #line 2405 "mmixal.w" acc.h= 0,acc.l= *p; if(*p=='\"'){ p++;acc.l= 0;err("*null string is treated as zero"); }else if(*(p+1)=='\"')p+= 2; else*p= '\"',*--p= ','; goto constant_found; /*:93*/ #line 2341 "mmixal.w" ;break; case'@':/*96:*/ #line 2436 "mmixal.w" acc= cur_loc; goto constant_found; /*:96*/ #line 2342 "mmixal.w" ;break; case'-':op_stack[op_ptr++]= negate; case'+':goto scan_open; case'&':op_stack[op_ptr++]= serialize;goto scan_open; case'~':op_stack[op_ptr++]= complement;goto scan_open; case'$':op_stack[op_ptr++]= registerize;goto scan_open; case'(':op_stack[op_ptr++]= inner_lp;goto scan_open; default:if(p==operand_list+1){ operand_list[0]= '0',operand_list[1]= '\0',p= operand_list; goto scan_open; } if(*(p-1))derr("syntax error at character `%c'",*(p-1)); derr("syntax error after character `%c'",*(p-2)); } /*:86*/ #line 2322 "mmixal.w" ; scan_close:/*97:*/ #line 2440 "mmixal.w" switch(*p++){ case'+':rt_op= plus;break; case'-':rt_op= minus;break; case'*':rt_op= times;break; case'/':if(*p!='/')rt_op= over; else p++,rt_op= frac;break; case'%':rt_op= mod;break; case'<':rt_op= shl;goto sh_check; case'>':rt_op= shr; sh_check:if(*p++==*(p-1))break; derr("syntax error at `%c'",*(p-2)); case'&':rt_op= and;break; case'|':rt_op= or;break; case'^':rt_op= xor;break; case')':rt_op= inner_rp;break; case'\0':case',':rt_op= outer_rp;break; default:derr("syntax error at `%c'",*(p-1)); } /*:97*/ #line 2323 "mmixal.w" ; while(precedence[top_op]>=precedence[rt_op]) /*98:*/ #line 2461 "mmixal.w" switch(op_stack[--op_ptr]){ case inner_lp:if(rt_op==inner_rp)goto scan_close; err("*missing right parenthesis");break; case outer_lp:if(rt_op==outer_rp){ if(top_val.status==reg_val&&(top_val.equiv.l> 0xff||top_val.equiv.h)){ err("*register number too large, will be reduced mod 256"); top_val.equiv.h= 0,top_val.equiv.l&= 0xff; } if(!*(p-1))goto operands_done; else rt_op= outer_lp;goto hold_op; }else{ op_ptr++; err("*missing left parenthesis"); goto scan_close; } /*100:*/ #line 2507 "mmixal.w" case negate:unary_check("negate"); top_val.equiv= ominus(zero_octa,top_val.equiv);goto delink; case complement:unary_check("complement"); top_val.equiv.h= ~top_val.equiv.h,top_val.equiv.l= ~top_val.equiv.l; goto delink; case registerize:unary_check("registerize"); top_val.status= reg_val;goto delink; case serialize:if(!top_val.link) err("can take serial number of symbol only"); top_val.equiv.h= 0,top_val.equiv.l= top_val.link->sym->serial; top_val.status= pure;goto delink; /*:100*/ #line 2480 "mmixal.w" /*99:*/ #line 2491 "mmixal.w" case plus:if(top_val.status==undefined) err("cannot add an undefined quantity"); if(next_val.status==undefined) err("cannot add to an undefined quantity"); if(top_val.status==reg_val&&next_val.status==reg_val) err("cannot add two register numbers"); next_val.equiv= oplus(next_val.equiv,top_val.equiv); fin_bin:next_val.status= (top_val.status==next_val.status?pure:reg_val); val_ptr--; delink:top_val.link= NULL;break; /*:99*//*101:*/ #line 2528 "mmixal.w" case minus:if(top_val.status==undefined) err("cannot subtract an undefined quantity"); if(next_val.status==undefined) err("cannot subtract from an undefined quantity"); if(top_val.status==reg_val&&next_val.status!=reg_val) err("cannot subtract register number from pure value"); next_val.equiv= ominus(next_val.equiv,top_val.equiv);goto fin_bin; case times:binary_check("multiply"); next_val.equiv= omult(next_val.equiv,top_val.equiv);goto fin_bin; case over:case mod:binary_check("divide"); if(top_val.equiv.l==0&&top_val.equiv.h==0) err("*division by zero"); next_val.equiv= odiv(zero_octa,next_val.equiv,top_val.equiv); if(op_stack[op_ptr]==mod)next_val.equiv= aux; goto fin_bin; case frac:binary_check("compute a ratio of"); if(next_val.equiv.h>=top_val.equiv.h&& (next_val.equiv.l>=top_val.equiv.l||next_val.equiv.h> top_val.equiv.h)) err("*illegal fraction"); next_val.equiv= odiv(next_val.equiv,zero_octa,top_val.equiv);goto fin_bin; case shl:case shr:binary_check("compute a bitwise shift of"); if(top_val.equiv.h||top_val.equiv.l> 63)next_val.equiv= zero_octa; else if(op_stack[op_ptr]==shl) next_val.equiv= shift_left(next_val.equiv,top_val.equiv.l); else next_val.equiv= shift_right(next_val.equiv,top_val.equiv.l,true); goto fin_bin; case and:binary_check("compute bitwise and of"); next_val.equiv.h&= top_val.equiv.h,next_val.equiv.l&= top_val.equiv.l; goto fin_bin; case or:binary_check("compute bitwise or of"); next_val.equiv.h|= top_val.equiv.h,next_val.equiv.l|= top_val.equiv.l; goto fin_bin; case xor:binary_check("compute bitwise xor of"); next_val.equiv.h^= top_val.equiv.h,next_val.equiv.l^= top_val.equiv.l; goto fin_bin; /*:101*/ #line 2481 "mmixal.w" } /*:98*/ #line 2325 "mmixal.w" ; hold_op:op_stack[op_ptr++]= rt_op; } operands_done: /*:85*/ #line 2592 "mmixal.w" ; if(opcode==GREG)/*108:*/ #line 2674 "mmixal.w" { if(val_stack[0].equiv.l||val_stack[0].equiv.h){ for(j= greg;j<255;j++) if(greg_val[j].l==val_stack[0].equiv.l&& greg_val[j].h==val_stack[0].equiv.h){ cur_greg= j;goto got_greg; } } if(greg==32)err("too many global registers"); greg--; greg_val[greg]= val_stack[0].equiv;cur_greg= greg; got_greg:; } /*:108*/ #line 2593 "mmixal.w" ; if(lab_field[0])/*109:*/ #line 2701 "mmixal.w" { sym_node*new_link= DEFINED; acc= cur_loc; if(opcode==IS){ cur_loc= val_stack[0].equiv; if(val_stack[0].status==reg_val)new_link= REGISTER; }else if(opcode==GREG)cur_loc.h= 0,cur_loc.l= cur_greg,new_link= REGISTER; /*111:*/ #line 2740 "mmixal.w" if(isdigit(lab_field[0]))pp= &forward_local[lab_field[0]-'0']; else{ if(lab_field[0]==':')tt= trie_search(trie_root,lab_field+1); else tt= trie_search(cur_prefix,lab_field); pp= tt->sym; if(!pp)pp= tt->sym= new_sym_node(true); } /*:111*/ #line 2709 "mmixal.w" ; if(pp->link==DEFINED||pp->link==REGISTER){ if(pp->equiv.l!=cur_loc.l||pp->equiv.h!=cur_loc.h||pp->link!=new_link){ if(pp->serial)derr("symbol `%s' is already defined",lab_field); pp->serial= ++serial_number; derr("*redefinition of predefined symbol `%s'",lab_field); } }else if(pp->link==PREDEFINED)pp->serial= ++serial_number; else if(pp->link){ if(new_link==REGISTER)err("future reference cannot be to a register"); do/*112:*/ #line 2749 "mmixal.w" { qq= pp->link; pp->link= qq->link; mmo_loc(); if(qq->serial==fix_o)/*113:*/ #line 2759 "mmixal.w" { if(qq->equiv.h&0xffffff){ mmo_lop(lop_fixo,0,2); mmo_tetra(qq->equiv.h); }else mmo_lop(lop_fixo,qq->equiv.h>>24,1); mmo_tetra(qq->equiv.l); } /*:113*/ #line 2754 "mmixal.w" else/*114:*/ #line 2768 "mmixal.w" { octa o; o= ominus(cur_loc,qq->equiv); if(o.l&3) dderr("*relative address in location #%08x%08x not divisible by 4", qq->equiv.h,qq->equiv.l); o= shift_right(o,2,0); k= 0; if(o.h==0) if(o.l<0x10000)mmo_lopp(lop_fixr,o.l); else if(qq->serial==fix_xyz&&o.l<0x1000000){ mmo_lop(lop_fixrx,0,24);mmo_tetra(o.l); }else k= 1; else if(o.h==0xffffffff) if(qq->serial==fix_xyz&&o.l>=0xff000000){ mmo_lop(lop_fixrx,0,24);mmo_tetra(o.l&0x1ffffff); }else if(qq->serial==fix_yz&&o.l>=0xffff0000){ mmo_lop(lop_fixrx,0,16);mmo_tetra(o.l&0x100ffff); }else k= 1; else k= 1; if(k)dderr("relative address in location #%08x%08x is too far away", qq->equiv.h,qq->equiv.l); } /*:114*/ #line 2755 "mmixal.w" ; recycle_fixup(qq); } /*:112*/ #line 2722 "mmixal.w" while(pp->link); } if(isdigit(lab_field[0]))pp= &backward_local[lab_field[0]-'0']; pp->equiv= cur_loc;pp->link= new_link; /*110:*/ #line 2732 "mmixal.w" if(!isdigit(lab_field[0])) for(j= 0;jsym==pp){ val_stack[j].status= (new_link==REGISTER?reg_val:pure); val_stack[j].equiv= cur_loc; } /*:110*/ #line 2726 "mmixal.w" ; if(listing_file&&(opcode==IS||opcode==LOC)) /*115:*/ #line 2794 "mmixal.w" if(new_link==DEFINED){ fprintf(listing_file,"(%08x%08x)",cur_loc.h,cur_loc.l); flush_listing_line(" "); }else{ fprintf(listing_file,"($%03d)",cur_loc.l&0xff); flush_listing_line(" "); } /*:115*/ #line 2728 "mmixal.w" ; cur_loc= acc; } /*:109*/ #line 2594 "mmixal.w" ; /*116:*/ #line 2803 "mmixal.w" future_bits= 0; if(op_bits&many_arg_bit)/*117:*/ #line 2825 "mmixal.w" for(j= 0;jsym; qq= new_sym_node(false); qq->link= pp->link; pp->link= qq; qq->serial= fix_o; qq->equiv= cur_loc; } /*:118*/ #line 2827 "mmixal.w" ; k= 1<<(opcode-BYTE); if((val_stack[j].equiv.h&&opcode 0xffff&&opcode 0xff&&opcodesym; qq= new_sym_node(false); qq->link= pp->link; pp->link= qq; qq->serial= fix_xyz; qq->equiv= cur_loc; xyz= 0; future_bits= 0xe0; goto assemble_inst; } /*:130*/ #line 3020 "mmixal.w" else if(opcode!=PREFIX)err("the operand is undefined"); }else if(val_stack[0].status==reg_val){ if(!(op_bits&(xyzr_bit+xyzar_bit))) derr("*operand of `%s' should not be a register number",op_field); }else{ if(op_bits&xyzr_bit) derr("*operand of `%s' should be a register number",op_field); if(op_bits&rel_addr_bit) /*131:*/ #line 3053 "mmixal.w" { octa source,dest; if(val_stack[0].equiv.l&3) err("*relative address is not divisible by 4"); source= shift_right(cur_loc,2,0); dest= shift_right(val_stack[0].equiv,2,0); acc= ominus(dest,source); if(!(acc.h&0x80000000)){ if(acc.l> 0xffffff||acc.h) err("relative address is more than #ffffff tetrabytes forward"); }else{ acc= incr(acc,0x1000000); opcode++; if(acc.l> 0xffffff||acc.h) err("relative address is more than #1000000 tetrabytes backward"); } xyz= acc.l; goto assemble_inst; } /*:131*/ #line 3031 "mmixal.w" ; } if(opcode> 0xff)/*132:*/ #line 3075 "mmixal.w" switch(opcode){ case LOC:cur_loc= val_stack[0].equiv; case IS:goto bypass; case PREFIX:if(!val_stack[0].link)err("not a valid prefix"); cur_prefix= val_stack[0].link;goto bypass; case GREG:if(listing_file)/*134:*/ #line 3102 "mmixal.w" if(val_stack[0].equiv.l||val_stack[0].equiv.h){ fprintf(listing_file,"($%03d=#%08x",cur_greg,val_stack[0].equiv.h); flush_listing_line(" "); fprintf(listing_file," %08x)",val_stack[0].equiv.l); flush_listing_line(" "); }else{ fprintf(listing_file,"($%03d)",cur_greg); flush_listing_line(" "); } /*:134*/ #line 3082 "mmixal.w" ; goto bypass; case LOCAL:if(val_stack[0].equiv.l> lreg)lreg= val_stack[0].equiv.l; if(listing_file){ fprintf(listing_file,"($%03d)",val_stack[0].equiv.l); flush_listing_line(" "); } goto bypass; case BSPEC:if(val_stack[0].equiv.l> 0xffff||val_stack[0].equiv.h) err("*operand of `BSPEC' doesn't fit in two bytes"); mmo_loc();mmo_sync(); mmo_lopp(lop_spec,val_stack[0].equiv.l); spec_mode= true;spec_mode_loc= 0;goto bypass; case ESPEC:spec_mode= false;goto bypass; } /*:132*/ #line 3033 "mmixal.w" ; if(val_stack[0].equiv.h||val_stack[0].equiv.l> 0xffffff) err("*XYZ field doesn't fit in three bytes"); xyz= val_stack[0].equiv.l&0xffffff; goto assemble_inst; /*:129*/ #line 2810 "mmixal.w" ; case 2:if(!(op_bits&two_arg_bit)) if(op_bits&one_arg_bit) derr("opcode `%s' must not have two operands",op_field) else derr("opcode `%s' must have more than two operands",op_field); /*124:*/ #line 2915 "mmixal.w" if(val_stack[1].status==undefined){ if(op_bits&rel_addr_bit) /*125:*/ #line 2945 "mmixal.w" { pp= val_stack[1].link->sym; qq= new_sym_node(false); qq->link= pp->link; pp->link= qq; qq->serial= fix_yz; qq->equiv= cur_loc; yz= 0; future_bits= 0xc0; goto assemble_X; } /*:125*/ #line 2918 "mmixal.w" else err("YZ field is undefined"); }else if(val_stack[1].status==reg_val){ if(!(op_bits&(immed_bit+yzr_bit+yzar_bit))) derr("*YZ field of `%s' should not be a register number",op_field); if(opcode==SET)val_stack[1].equiv.l<<= 8,opcode= 0xc1; else if(op_bits&mem_bit) val_stack[1].equiv.l<<= 8,opcode++; }else{ if(op_bits&mem_bit) /*127:*/ #line 2980 "mmixal.w" { octa o; o= val_stack[1].equiv,k= 0; for(j= greg;j<255;j++)if(greg_val[j].h||greg_val[j].l){ acc= ominus(val_stack[1].equiv,greg_val[j]); if(acc.h<=o.h&&(acc.l<=o.l||acc.h>16;break; case 1:yz= o.h&0xffff;break; case 2:yz= o.l>>16;break; case 3:yz= o.l&0xffff;break; } if(yz){ assemble(4,(j<<24)+(255<<16)+yz,0); j|= ORH; } } if(k)yz= (k<<8)+255; else yz= 255<<8,opcode++; } /*:128*/ #line 2991 "mmixal.w" ; goto assemble_X; } /*:127*/ #line 2930 "mmixal.w" ; if(opcode==SET)opcode= 0xe3; else if(op_bits&immed_bit)opcode++; else if(op_bits&yzr_bit){ derr("*YZ field of `%s' should be a register number",op_field); } if(op_bits&rel_addr_bit) /*126:*/ #line 2958 "mmixal.w" { octa source,dest; if(val_stack[1].equiv.l&3) err("*relative address is not divisible by 4"); source= shift_right(cur_loc,2,0); dest= shift_right(val_stack[1].equiv,2,0); acc= ominus(dest,source); if(!(acc.h&0x80000000)){ if(acc.l> 0xffff||acc.h) err("relative address is more than #ffff tetrabytes forward"); }else{ acc= incr(acc,0x10000); opcode++; if(acc.l> 0xffff||acc.h) err("relative address is more than #10000 tetrabytes backward"); } yz= acc.l; goto assemble_X; } /*:126*/ #line 2937 "mmixal.w" ; } if(val_stack[1].equiv.h||val_stack[1].equiv.l> 0xffff) err("*YZ field doesn't fit in two bytes"); yz= val_stack[1].equiv.l&0xffff; goto assemble_X; /*:124*/ #line 2815 "mmixal.w" ; case 3:if(!(op_bits&three_arg_bit)) derr("opcode `%s' must not have three operands",op_field); /*119:*/ #line 2856 "mmixal.w" /*121:*/ #line 2870 "mmixal.w" if(val_stack[2].status==undefined)err("Z field is undefined"); if(val_stack[2].status==reg_val){ if(!(op_bits&(immed_bit+zr_bit+zar_bit))) derr("*Z field of `%s' should not be a register number",op_field); }else if(op_bits&immed_bit)opcode++; else if(op_bits&zr_bit) derr("*Z field of `%s' should be a register number",op_field); if(val_stack[2].equiv.h||val_stack[2].equiv.l> 0xff) err("*Z field doesn't fit in one byte"); z= val_stack[2].equiv.l&0xff; /*:121*/ #line 2857 "mmixal.w" ; /*122:*/ #line 2885 "mmixal.w" if(val_stack[1].status==undefined)err("Y field is undefined"); if(val_stack[1].status==reg_val){ if(!(op_bits&(yr_bit+yar_bit))) derr("*Y field of `%s' should not be a register number",op_field); }else if(op_bits&yr_bit) derr("*Y field of `%s' should be a register number",op_field); if(val_stack[1].equiv.h||val_stack[1].equiv.l> 0xff) err("*Y field doesn't fit in one byte"); y= val_stack[1].equiv.l&0xff; yz= (y<<8)+z; /*:122*/ #line 2858 "mmixal.w" ; assemble_X:/*123:*/ #line 2900 "mmixal.w" if(val_stack[0].status==undefined)err("X field is undefined"); if(val_stack[0].status==reg_val){ if(!(op_bits&(xr_bit+xar_bit))) derr("*X field of `%s' should not be a register number",op_field); }else if(op_bits&xr_bit) derr("*X field of `%s' should be a register number",op_field); if(val_stack[0].equiv.h||val_stack[0].equiv.l> 0xff) err("*X field doesn't fit in one byte"); x= val_stack[0].equiv.l&0xff; xyz= (x<<16)+yz; /*:123*/ #line 2859 "mmixal.w" ; assemble_inst:assemble(4,(opcode<<24)+xyz,future_bits); break; /*:119*/ #line 2818 "mmixal.w" ; default:derr("too many operands for opcode `%s'",op_field); } /*:116*/ #line 2595 "mmixal.w" ; bypass: /*:102*/ #line 3159 "mmixal.w" ; if(!*buf_ptr)break; } if(listing_file){ if(listing_bits)listing_clear(); else if(!line_listed)flush_listing_line(" "); } } /*142:*/ #line 3225 "mmixal.w" if(lreg>=greg) dpanic("Danger: Must reduce the number of GREGs by %d",lreg-greg+1); /*144:*/ #line 3243 "mmixal.w" mmo_lop(lop_post,0,greg); greg_val[255]= trie_search(trie_root,"Main")->sym->equiv; for(j= greg;j<256;j++){ mmo_tetra(greg_val[j].h); mmo_tetra(greg_val[j].l); } /*:144*/ #line 3229 "mmixal.w" ; /*80:*/ #line 2251 "mmixal.w" op_root->mid= NULL; prune(trie_root); sym_ptr= sym_buf; if(listing_file)fprintf(listing_file,"\nSymbol table:\n"); mmo_lop(lop_stab,0,0); out_stab(trie_root); while(mmo_ptr&3)mmo_byte(0); mmo_lopp(lop_end,mmo_ptr>>2); /*:80*/ #line 3230 "mmixal.w" ; /*145:*/ #line 3251 "mmixal.w" for(j= 0;j<10;j++)if(forward_local[j].link) err_count++,fprintf(stderr,"undefined local symbol %dF\n",j); /*:145*/ #line 3231 "mmixal.w" ; if(err_count){ if(err_count> 1)fprintf(stderr,"(%d errors were found.)\n",err_count); else fprintf(stderr,"(One error was found.)\n"); } exit(err_count); /*:142*/ #line 3167 "mmixal.w" ; } /*:136*/