254 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			254 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "decl.h"
 | |
| #include <system.h>
 | |
| 
 | |
| /* This file contains a number of funtions which will be called to handle
 | |
|  * the 'DEF_C_INSTR' (e.g., C_loe).
 | |
|  */
 | |
| 
 | |
| #define _ICON	0
 | |
| #define _UCON	4
 | |
| #define _FCON	8
 | |
| #define C_DEE	12
 | |
| #define C_FIL	15
 | |
| #define C_GTO	18
 | |
| #define C_INE	21
 | |
| #define C_LAE	24
 | |
| #define C_LDE	27
 | |
| #define C_LOE	30
 | |
| #define C_SDE	33
 | |
| #define C_STE	36
 | |
| #define C_ZRE	39
 | |
| 
 | |
| struct { char *name; int segment, generated}
 | |
| 		def_info[] = {
 | |
| 		/* _ICON */	{ "C_con_icon", SEGCON, 0},
 | |
| 				{ "C_rom_icon", SEGROM, 0},
 | |
| 				{ "C_hol_icon", NOSEG, 0},
 | |
| 				{ "C_bss_icon", NOSEG, 0},
 | |
| 
 | |
| 		/* _UCON */	{ "C_con_ucon", SEGCON, 0},
 | |
| 				{ "C_rom_ucon", SEGROM, 0},
 | |
| 				{ "C_hol_ucon", NOSEG, 0},
 | |
| 				{ "C_bss_ucon", NOSEG, 0},
 | |
| 
 | |
| 		/* _FCON */	{ "C_con_fcon", SEGCON, 0},
 | |
| 				{ "C_rom_fcon", SEGROM, 0},
 | |
| 				{ "C_hol_fcon", NOSEG, 0},
 | |
| 				{ "C_bss_fcon", NOSEG, 0},
 | |
| 
 | |
| 		/* C_DEE */	{ "C_dee", SEGTXT, 0},
 | |
| 				{ "C_dee_dnam", SEGTXT, 0},
 | |
| 				{ "C_dee_dlb", SEGTXT, 0},
 | |
| 
 | |
| 		/* C_FIL */	{ "C_fil", SEGTXT, 0},
 | |
| 				{ "C_fil_dnam", SEGTXT, 0},
 | |
| 				{ "C_fil_dlb", SEGTXT, 0},
 | |
| 
 | |
| 		/* C_GTO */	{ "C_gto", SEGTXT, 0},
 | |
| 				{ "C_gto_dnam", SEGTXT, 0},
 | |
| 				{ "C_gto_dlb", SEGTXT, 0},
 | |
| 
 | |
| 		/* C_INE */	{ "C_ine", SEGTXT, 0},
 | |
| 				{ "C_ine_dnam", SEGTXT, 0},
 | |
| 				{ "C_ine_dlb", SEGTXT, 0},
 | |
| 
 | |
| 		/* C_LAE */	{ "C_lae", SEGTXT, 0},
 | |
| 				{ "C_lae_dnam", SEGTXT, 0},
 | |
| 				{ "C_lae_dlb", SEGTXT, 0},
 | |
| 
 | |
| 		/* C_LDE */	{ "C_lde", SEGTXT, 0},
 | |
| 				{ "C_lde_dnam", SEGTXT, 0},
 | |
| 				{ "C_lde_dlb", SEGTXT, 0},
 | |
| 
 | |
| 		/* C_LOE */	{ "C_loe", SEGTXT, 0},
 | |
| 				{ "C_loe_dnam", SEGTXT, 0},
 | |
| 				{ "C_loe_dlb", SEGTXT, 0},
 | |
| 
 | |
| 		/* C_SDE */	{ "C_sde", SEGTXT, 0},
 | |
| 				{ "C_sde_dnam", SEGTXT, 0},
 | |
| 				{ "C_sde_dlb", SEGTXT, 0},
 | |
| 
 | |
| 		/* C_STE */	{ "C_ste", SEGTXT, 0},
 | |
| 				{ "C_ste_dnam", SEGTXT, 0},
 | |
| 				{ "C_ste_dlb", SEGTXT, 0},
 | |
| 
 | |
| 		/* C_ZRE */	{ "C_zre", SEGTXT, 0},
 | |
| 				{ "C_zre_dnam", SEGTXT, 0},
 | |
| 				{ "C_zre_dlb", SEGTXT, 0}
 | |
| 		};	/* This big array contains information about the 
 | |
| 			 * functions that will be generated from the descrip-
 | |
| 			 * tion of 1 DEF_C_INSTR. It contains the name, the
 | |
| 			 * segment and a flag of these instructions. The flag
 | |
| 			 * is used to determine if the instruction is explicitly
 | |
| 			 * given in the EM_table or not.
 | |
| 			 */
 | |
| 
 | |
| 
 | |
| File	*save_file;	/* Save original output-file in this variable */
 | |
| int	def_start,	/* Index in def_info[], start of the expanded C_INSTR */
 | |
| 	def_end,	/* last expanded C_INSTR index. */
 | |
| 	save_lineno;
 | |
| 
 | |
| extern File *outfile;
 | |
| extern char yytext[];
 | |
| extern int yylineno;
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| init_defaults( instr)
 | |
| char *instr;
 | |
| 
 | |
| /* Save current output-file and write on a file called ".default" */
 | |
| 
 | |
| {
 | |
| 	save_file = outfile;
 | |
| 	save_lineno = yylineno;
 | |
| 	sys_open( ".default", OP_WRITE, &outfile);
 | |
| 	set_def_params( instr);
 | |
| }
 | |
| 
 | |
| 
 | |
| int bss_or_hol_instr( index)
 | |
| int index;
 | |
| {
 | |
| 	return ( index == _ICON + 2 || index == _ICON + 3 ||
 | |
| 	     	 index == _UCON + 2 || index == _UCON + 3 ||
 | |
| 	     	 index == _FCON + 2 || index == _FCON + 3);
 | |
| }
 | |
| 
 | |
| 
 | |
| set_def_params( instr)
 | |
| char *instr;
 | |
| 
 | |
| /* Give 'def_start' and 'def_end' their correct values. */
 | |
| 
 | |
| {
 | |
| 	int low, high, mid, rel;
 | |
| 
 | |
| 	if ( *instr == '.') {	/* ..icon | ..ucon | ..fcon */
 | |
| 		switch ( *(instr+2)) {
 | |
| 		  case 'i' : def_start = _ICON;
 | |
| 			     break;
 | |
| 		  case 'u' : def_start = _UCON;
 | |
| 			     break;
 | |
| 		  case 'f' : def_start = _FCON;
 | |
| 			     break;
 | |
| 		}
 | |
| 		def_end = def_start + 3;
 | |
| 	}
 | |
| 	else {
 | |
| 		low = C_DEE;
 | |
| 		high = C_ZRE;
 | |
| 
 | |
| 		while ( TRUE) {
 | |
| 			mid = ( low + high) / 6 * 3;
 | |
| 			rel = strncmp( instr, def_info[mid].name, 5);
 | |
| 
 | |
| 			if ( rel == 0 )
 | |
| 				break;
 | |
| 			else if ( high == low)
 | |
| 				abort();
 | |
| 			else if ( rel < 0)
 | |
| 				high = mid;
 | |
| 			else
 | |
| 				/* be careful : 'mid' is truncated */
 | |
| 				low = ( mid == low ? low + 3: mid);
 | |
| 		}
 | |
| 		def_start = mid;
 | |
| 		def_end = def_start + 2;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include "Lpars.h"
 | |
| 
 | |
| handle_defaults()
 | |
| 
 | |
| /* Switch back to original output-file and start generating the functions 
 | |
|  * from the file ".default".
 | |
|  */
 | |
| {
 | |
| 	FILE *old, *tmp, *switch_input();
 | |
| 	int i, old_yylineno;
 | |
| 	extern int CD_pos;
 | |
| 
 | |
| 	sys_close( outfile);
 | |
| 	outfile = save_file;
 | |
| 
 | |
| 	tmp = fopen( ".default", "r");
 | |
| 	old = switch_input( tmp);
 | |
| 	old_yylineno = yylineno;
 | |
| 
 | |
| 	for ( i = def_start; i <= def_end; i++) {
 | |
| 		yylineno = save_lineno;
 | |
| 		if ( !def_info[i].generated) {
 | |
| 			set_C_instr_info( def_info[i].name);
 | |
| 			segment = def_info[i].segment;
 | |
| 
 | |
| 			set_outfile( def_info[i].name);
 | |
| 			header( def_info[i].name);
 | |
| 			CD_pos = TRUE;	/* Set mylex() in correct state */
 | |
| 
 | |
| 			if ( bss_or_hol_instr( i)) {
 | |
| 				extnd_header();
 | |
| 				/* Rest of body is just the same as the corres-
 | |
| 				 * ponding C_con_xxx C_rom_xxx instruction
 | |
| 				 * so set correct info.
 | |
| 				 */
 | |
| 				set_C_instr_info( def_info[i-2].name);
 | |
| 				def_row();
 | |
| 				out( "}\n\n");
 | |
| 			}
 | |
| 			else
 | |
| 				def_row();
 | |
| 			rewind( tmp);
 | |
| 		}
 | |
| 	}
 | |
| 	fclose( tmp);
 | |
| 	switch_input( old);
 | |
| 	yylineno = old_yylineno;
 | |
| }
 | |
| 
 | |
| def_admn( instr)
 | |
| char *instr;
 | |
| 
 | |
| /* Mark this 'instr' as being generated */
 | |
| 
 | |
| {
 | |
| 	int low, high, mid, rel;
 | |
| 
 | |
| 	low = _ICON;
 | |
| 	high = C_ZRE + 2;
 | |
| 
 | |
| 	while ( TRUE) {
 | |
| 		mid = ( low + high) / 2;
 | |
| 		rel = strcmp( instr, def_info[mid].name);
 | |
| 
 | |
| 		if ( rel == 0 )
 | |
| 			break;
 | |
| 		else if ( high == low)
 | |
| 			return;
 | |
| 		else if ( rel < 0)
 | |
| 			high = mid;
 | |
| 		else
 | |
| 			low = ( mid == low ? low + 1: mid);
 | |
| 	}
 | |
| 	def_info[mid].generated = 1;
 | |
| }
 | |
| 
 | |
| extnd_header()
 | |
| 
 | |
| /* Generates code for loooking at the parameters 'nbytes' and 'i' of the
 | |
|  * bss an hol pseudo-instructions.
 | |
|  */
 | |
| {
 | |
| 	out( "if ( %s == 0 ) {\n", C_instr_info->arg_id[3]);
 | |
| 	set_segment( SEGBSS);
 | |
| 	out( "bss( %s);\n", C_instr_info->arg_id[0]);
 | |
| 	out( "}\nelse {\n");
 | |
| 	set_segment( SEGCON);
 | |
| 	out( "for ( %s = 0; %s < %s/EM_WSIZE; %s++)\n",
 | |
| 	     C_instr_info->arg_id[3], C_instr_info->arg_id[3],
 | |
| 	     C_instr_info->arg_id[0], C_instr_info->arg_id[3]);
 | |
| }
 |