Pristine Ack-5.5
[Ack-5.5.git] / util / ceg / EM_parser / common / default.c
1 #include "decl.h"
2 #include <system.h>
3
4 /* This file contains a number of funtions which will be called to handle
5  * the 'DEF_C_INSTR' (e.g., C_loe).
6  */
7
8 #define _ICON   0
9 #define _UCON   4
10 #define _FCON   8
11 #define C_DEE   12
12 #define C_FIL   15
13 #define C_GTO   18
14 #define C_INE   21
15 #define C_LAE   24
16 #define C_LDE   27
17 #define C_LOE   30
18 #define C_SDE   33
19 #define C_STE   36
20 #define C_ZRE   39
21
22 struct { char *name; int segment, generated; }
23                 def_info[] = {
24                 /* _ICON */     { "C_con_icon", SEGCON, 0},
25                                 { "C_rom_icon", SEGROM, 0},
26                                 { "C_hol_icon", NOSEG, 0},
27                                 { "C_bss_icon", NOSEG, 0},
28
29                 /* _UCON */     { "C_con_ucon", SEGCON, 0},
30                                 { "C_rom_ucon", SEGROM, 0},
31                                 { "C_hol_ucon", NOSEG, 0},
32                                 { "C_bss_ucon", NOSEG, 0},
33
34                 /* _FCON */     { "C_con_fcon", SEGCON, 0},
35                                 { "C_rom_fcon", SEGROM, 0},
36                                 { "C_hol_fcon", NOSEG, 0},
37                                 { "C_bss_fcon", NOSEG, 0},
38
39                 /* C_DEE */     { "C_dee", SEGTXT, 0},
40                                 { "C_dee_dnam", SEGTXT, 0},
41                                 { "C_dee_dlb", SEGTXT, 0},
42
43                 /* C_FIL */     { "C_fil", SEGTXT, 0},
44                                 { "C_fil_dnam", SEGTXT, 0},
45                                 { "C_fil_dlb", SEGTXT, 0},
46
47                 /* C_GTO */     { "C_gto", SEGTXT, 0},
48                                 { "C_gto_dnam", SEGTXT, 0},
49                                 { "C_gto_dlb", SEGTXT, 0},
50
51                 /* C_INE */     { "C_ine", SEGTXT, 0},
52                                 { "C_ine_dnam", SEGTXT, 0},
53                                 { "C_ine_dlb", SEGTXT, 0},
54
55                 /* C_LAE */     { "C_lae", SEGTXT, 0},
56                                 { "C_lae_dnam", SEGTXT, 0},
57                                 { "C_lae_dlb", SEGTXT, 0},
58
59                 /* C_LDE */     { "C_lde", SEGTXT, 0},
60                                 { "C_lde_dnam", SEGTXT, 0},
61                                 { "C_lde_dlb", SEGTXT, 0},
62
63                 /* C_LOE */     { "C_loe", SEGTXT, 0},
64                                 { "C_loe_dnam", SEGTXT, 0},
65                                 { "C_loe_dlb", SEGTXT, 0},
66
67                 /* C_SDE */     { "C_sde", SEGTXT, 0},
68                                 { "C_sde_dnam", SEGTXT, 0},
69                                 { "C_sde_dlb", SEGTXT, 0},
70
71                 /* C_STE */     { "C_ste", SEGTXT, 0},
72                                 { "C_ste_dnam", SEGTXT, 0},
73                                 { "C_ste_dlb", SEGTXT, 0},
74
75                 /* C_ZRE */     { "C_zre", SEGTXT, 0},
76                                 { "C_zre_dnam", SEGTXT, 0},
77                                 { "C_zre_dlb", SEGTXT, 0}
78                 };      /* This big array contains information about the 
79                          * functions that will be generated from the descrip-
80                          * tion of 1 DEF_C_INSTR. It contains the name, the
81                          * segment and a flag of these instructions. The flag
82                          * is used to determine if the instruction is explicitly
83                          * given in the EM_table or not.
84                          */
85
86
87 File    *save_file;     /* Save original output-file in this variable */
88 int     def_start,      /* Index in def_info[], start of the expanded C_INSTR */
89         def_end,        /* last expanded C_INSTR index. */
90         save_lineno;
91
92 extern File *outfile;
93 extern char yytext[];
94 extern int yylineno;
95
96
97
98
99 init_defaults( instr)
100 char *instr;
101
102 /* Save current output-file and write on a file called ".default" */
103
104 {
105         save_file = outfile;
106         save_lineno = yylineno;
107         sys_open( ".default", OP_WRITE, &outfile);
108         set_def_params( instr);
109 }
110
111
112 int bss_or_hol_instr( index)
113 int index;
114 {
115         return ( index == _ICON + 2 || index == _ICON + 3 ||
116                  index == _UCON + 2 || index == _UCON + 3 ||
117                  index == _FCON + 2 || index == _FCON + 3);
118 }
119
120
121 set_def_params( instr)
122 char *instr;
123
124 /* Give 'def_start' and 'def_end' their correct values. */
125
126 {
127         int low, high, mid, rel;
128
129         if ( *instr == '.') {   /* ..icon | ..ucon | ..fcon */
130                 switch ( *(instr+2)) {
131                   case 'i' : def_start = _ICON;
132                              break;
133                   case 'u' : def_start = _UCON;
134                              break;
135                   case 'f' : def_start = _FCON;
136                              break;
137                 }
138                 def_end = def_start + 3;
139         }
140         else {
141                 low = C_DEE;
142                 high = C_ZRE;
143
144                 while ( TRUE) {
145                         mid = ( low + high) / 6 * 3;
146                         rel = strncmp( instr, def_info[mid].name, 5);
147
148                         if ( rel == 0 )
149                                 break;
150                         else if ( high == low)
151                                 abort();
152                         else if ( rel < 0)
153                                 high = mid;
154                         else
155                                 /* be careful : 'mid' is truncated */
156                                 low = ( mid == low ? low + 3: mid);
157                 }
158                 def_start = mid;
159                 def_end = def_start + 2;
160         }
161 }
162
163 #include <stdio.h>
164 #include "Lpars.h"
165
166 handle_defaults()
167
168 /* Switch back to original output-file and start generating the functions 
169  * from the file ".default".
170  */
171 {
172         FILE *old, *tmp, *switch_input();
173         int i, old_yylineno;
174         extern int CD_pos;
175
176         sys_close( outfile);
177         outfile = save_file;
178
179         tmp = fopen( ".default", "r");
180         old = switch_input( tmp);
181         old_yylineno = yylineno;
182
183         for ( i = def_start; i <= def_end; i++) {
184                 yylineno = save_lineno;
185                 if ( !def_info[i].generated) {
186                         set_C_instr_info( def_info[i].name);
187                         segment = def_info[i].segment;
188
189                         set_outfile( def_info[i].name);
190                         header( def_info[i].name);
191                         CD_pos = TRUE;  /* Set mylex() in correct state */
192
193                         if ( bss_or_hol_instr( i)) {
194                                 extnd_header();
195                                 /* Rest of body is just the same as the corres-
196                                  * ponding C_con_xxx C_rom_xxx instruction
197                                  * so set correct info.
198                                  */
199                                 set_C_instr_info( def_info[(i>>2)<<2].name);
200                                 segment = UNKNOWN;
201                                 /* to prevent another dump_label+switchseg */
202                                 def_row();
203                                 out( "}}\n\n");
204                         }
205                         else
206                                 def_row();
207                         rewind( tmp);
208                 }
209         }
210         fclose( tmp);
211         switch_input( old);
212         yylineno = old_yylineno;
213 }
214
215 def_admn( instr)
216 char *instr;
217
218 /* Mark this 'instr' as being generated */
219
220 {
221         int low, high, mid, rel;
222
223         low = _ICON;
224         high = C_ZRE + 2;
225
226         while ( TRUE) {
227                 mid = ( low + high) / 2;
228                 rel = strcmp( instr, def_info[mid].name);
229
230                 if ( rel == 0 )
231                         break;
232                 else if ( high == low)
233                         return;
234                 else if ( rel < 0)
235                         high = mid;
236                 else
237                         low = ( mid == low ? low + 1: mid);
238         }
239         def_info[mid].generated = 1;
240 }
241
242 extnd_header()
243
244 /* Generates code for loooking at the parameters 'nbytes' and 'i' of the
245  * bss an hol pseudo-instructions.
246  */
247 {
248         out( "if ( %s == 0 ) {\n", C_instr_info->arg_id[3]);
249         out( "common( %s);\n", C_instr_info->arg_id[0]);
250         out( "}\nelse {\n");
251         set_segment( SEGCON);
252         out( "for ( %s = 0; %s < %s/EM_WSIZE; %s++) {\n",
253              C_instr_info->arg_id[3], C_instr_info->arg_id[3],
254              C_instr_info->arg_id[0], C_instr_info->arg_id[3]);
255 }