00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00042
00043
00044
00045
00046
00048
00049
00050
00051
00052
00053
00054
00055 #include <stddef.h>
00056 #include <stdlib.h>
00057 #include <stdarg.h>
00058 #include <stdio.h>
00059 #include <strings.h>
00060 #include <assert.h>
00061 #include <list>
00062 #include "topcode.h"
00063 #include "gen_util.h"
00064 #include "targ_isa_subset.h"
00065 #include "isa_hazards_gen.h"
00066 #include "bstring.h"
00067
00068
00069 struct isa_hazard {
00070 const char *name;
00071 };
00072
00073 struct haz_desc {
00074 isa_hazard *type;
00075 int data;
00076 int pre_ops;
00077 int post_ops;
00078 int subsets[ISA_SUBSET_MAX+1];
00079 };
00080
00081 struct op_haz {
00082 haz_desc *desc;
00083 struct op_haz *next;
00084 int index;
00085 };
00086
00087 static std::list<ISA_HAZARD> hazards;
00088 static op_haz *op_hazards[TOP_count+1];
00089 static std::list<op_haz *> op_hazards_list;
00090 static haz_desc *current_haz_desc;
00091 static int haz_index;
00092
00093 static const char * const interface[] = {
00094 "/* ====================================================================",
00095 " * ====================================================================",
00096 " *",
00097 " * Description:",
00098 " *",
00099 " * A description of the ISA hazards. The description exports",
00100 " * the following:",
00101 " *",
00102 " * typedef (enum) ISA_HAZARD",
00103 " * An enumeration of the hazard types, and ISA_HAZARD_UNDEFINED.",
00104 " *",
00105 " * typedef (struct) ISA_HAZARD_INFO",
00106 " * Describes a particular hazard. The contents are private.",
00107 " *",
00108 " * BOOL ISA_HAZARD_TOP_Has_Hazard(TOP topcode)",
00109 " * Returns TRUE if the instruction specified by 'topcode'",
00110 " * has a hazard.",
00111 " *",
00112 " * ISA_HAZARD_INFO *ISA_HAZARD_First(TOP topcode)",
00113 " * Get the first hazard description for 'topcode'.",
00114 " *",
00115 " * ISA_HAZARD_INFO *ISA_HAZARD_Next(ISA_HAZARD_INFO *info)",
00116 " * Gets the next hazard description when a 'topcode' has",
00117 " * more than one hazard.",
00118 " *",
00119 " * ISA_HAZARD ISA_HAZARD_Type(ISA_HAZARD_INFO *info)",
00120 " * Returns the type of the hazard.",
00121 " *",
00122 " * INT ISA_HAZARD_Data(ISA_HAZARD_INFO *info)",
00123 " * Returns the hazard specific data.",
00124 " *",
00125 " * INT ISA_HAZARD_Pre_Ops(ISA_HAZARD_INFO *info)",
00126 " * Returns the number of OPs that must precede the instruction",
00127 " * with the hazard.",
00128 " *",
00129 " * INT ISA_HAZARD_Post_Ops(ISA_HAZARD_INFO *info)",
00130 " * Returns the number of OPs that must follow the instruction",
00131 " * with the hazard.",
00132 " *",
00133 " * void ISA_HAZARD_Initialize(void)",
00134 " * Initializes the hazard description data for ISA_SUBSET_Value."
00135 " * This may only be called once (if not called at all the description",
00136 " * contains the hazards for all ISAs).",
00137 " *",
00138 " * ====================================================================",
00139 " * ====================================================================",
00140 " */",
00141 NULL
00142 };
00143
00144
00146 void ISA_Hazards_Begin( const char* )
00148
00150 {
00151 }
00152
00154 ISA_HAZARD Hazard_Create( const char *name )
00156
00158 {
00159 ISA_HAZARD result = new isa_hazard;
00160 BZERO(result, sizeof(isa_hazard));
00161 hazards.push_back(result);
00162 result->name = name;
00163 return result;
00164 }
00165
00167 void Hazard_Group( TOP topcode, ... )
00169
00171 {
00172 va_list ap;
00173 TOP opcode;
00174 int count = 0;
00175
00176 current_haz_desc = new haz_desc;
00177 BZERO(current_haz_desc, sizeof(haz_desc));
00178
00179 va_start(ap,topcode);
00180 for (opcode = topcode;
00181 opcode != TOP_UNDEFINED;
00182 opcode = static_cast<TOP>(va_arg(ap,int))) {
00183 op_haz *op_hazard = new op_haz;
00184 op_hazards_list.push_back(op_hazard);
00185 op_hazard->desc = current_haz_desc;
00186 op_hazard->next = op_hazards[(int)opcode];
00187 op_hazard->index = ++haz_index;
00188 op_hazards[(int)opcode] = op_hazard;
00189 ++count;
00190 }
00191 va_end(ap);
00192
00193 if (count == 0) {
00194 fprintf(stderr, "### Warning: hazard group is empty\n");
00195 }
00196 }
00197
00198
00200 void Hazard_Type( ISA_HAZARD isa_hazard )
00202
00204 {
00205 current_haz_desc->type = isa_hazard;
00206 }
00207
00208
00210 void Hazard_Data( int data )
00212
00214 {
00215 current_haz_desc->data = data;
00216 }
00217
00218
00220 void Hazard_Post_Ops( int ops )
00222
00224 {
00225 current_haz_desc->post_ops = ops;
00226 }
00227
00228
00230 void Hazard_Pre_Ops( int ops )
00232
00234 {
00235 current_haz_desc->pre_ops = ops;
00236 }
00237
00238
00240 void Hazard_ISA( ISA_SUBSET isa )
00242
00244 {
00245 if ((unsigned)isa > (unsigned)ISA_SUBSET_MAX) {
00246 fprintf(stderr, "### Error: isa value (%d) out of range (%d..%d)\n",
00247 (int)isa, ISA_SUBSET_MIN, ISA_SUBSET_MAX);
00248 exit(EXIT_FAILURE);
00249 }
00250
00251 current_haz_desc->subsets[(int)isa] = true;
00252 }
00253
00254
00256 void ISA_Hazards_End(void)
00258
00260 {
00261 int top;
00262 bool first;
00263 std::list<ISA_HAZARD>::iterator isi;
00264 std::list<op_haz *>::iterator ophaz_iter;
00265 const char * const isa_hazard_info_format =
00266 " { ISA_HAZARD_%-9s, %d, %d, %2d, 0x%02x, %d }, /* %2d */\n";
00267
00268 #define FNAME "targ_isa_hazards"
00269 char filename[1000];
00270 sprintf(filename,"%s.h",FNAME);
00271 FILE* hfile = fopen(filename,"w");
00272 sprintf(filename,"%s.c",FNAME);
00273 FILE* cfile = fopen(filename,"w");
00274 sprintf(filename,"%s.Exported",FNAME);
00275 FILE* efile = fopen(filename,"w");
00276
00277 fprintf(cfile,"#include \"topcode.h\"\n");
00278 fprintf(cfile,"#include \"targ_isa_subset.h\"\n");
00279 fprintf(cfile,"#include \"%s.h\"\n",FNAME);
00280
00281 sprintf (filename, "%s", FNAME);
00282 Emit_Header (hfile, filename, interface);
00283 fprintf(hfile,"#include \"targ_isa_subset.h\"\n");
00284
00285 fprintf(hfile,"typedef enum {");
00286 first = true;
00287 for ( isi = hazards.begin(); isi != hazards.end(); ++isi ) {
00288 ISA_HAZARD hazard = *isi;
00289 fprintf(hfile,"%c\n ISA_HAZARD_%s",first ? ' ' : ',',
00290 hazard->name);
00291 first = false;
00292 }
00293 fprintf(hfile,",\n ISA_HAZARD_UNDEFINED");
00294 fprintf(hfile,"\n} ISA_HAZARD;\n");
00295
00296 fprintf(hfile, "\ntypedef struct {\n"
00297 " ISA_HAZARD type;\n"
00298 " mUINT16 data;\n"
00299 " mUINT16 pre_ops;\n"
00300 " mUINT16 post_ops;\n"
00301 " mUINT8 isa_mask;\n"
00302 " mUINT8 next;\n"
00303 "} ISA_HAZARD_INFO;\n");
00304
00305 fprintf(efile, "ISA_HAZARD_hazard_info\n");
00306
00307 fprintf(cfile, "\nISA_HAZARD_INFO ISA_HAZARD_hazard_info[%d] = {\n",
00308 haz_index + 1);
00309 fprintf(cfile, isa_hazard_info_format,
00310 "UNDEFINED", 0, 0, 0, 0, 0, 0);
00311 for ( ophaz_iter = op_hazards_list.begin();
00312 ophaz_iter != op_hazards_list.end();
00313 ++ophaz_iter
00314 ) {
00315 int mask;
00316 ISA_SUBSET subset;
00317 op_haz *op_hazard = *ophaz_iter;
00318 haz_desc *haz = op_hazard->desc;
00319 op_haz *next = op_hazard->next;
00320
00321 mask = 0;
00322 for (subset = ISA_SUBSET_MIN;
00323 subset <= ISA_SUBSET_MAX;
00324 subset = (ISA_SUBSET)((int)subset + 1)
00325 ) {
00326 if ( haz->subsets[(int)subset] ) mask |= 1 << (int)subset;
00327 }
00328
00329 fprintf(cfile, isa_hazard_info_format,
00330 haz->type->name,
00331 haz->data,
00332 haz->pre_ops,
00333 haz->post_ops,
00334 mask,
00335 next ? next->index : 0,
00336 op_hazard->index);
00337 }
00338 fprintf(cfile, "};\n");
00339
00340 fprintf(efile, "ISA_HAZARD_hazard_index\n");
00341
00342 fprintf(cfile, "\nmUINT8 ISA_HAZARD_hazard_index[%d] = {\n", TOP_count);
00343 for ( top = 0; top < TOP_count; ++top ) {
00344 op_haz *op_hazard = op_hazards[top];
00345 fprintf(cfile, " %3d, ", op_hazard ? op_hazard->index : 0);
00346 fprintf(cfile, "/* %-9s */\n", TOP_Name((TOP)top));
00347 }
00348 fprintf(cfile, "};\n");
00349
00350 fprintf(hfile, "\ninline BOOL ISA_HAZARD_TOP_Has_Hazard(TOP topcode)\n"
00351 "{\n"
00352 " extern mUINT8 ISA_HAZARD_hazard_index[%d];\n"
00353 " return ISA_HAZARD_hazard_index[(INT)topcode] != 0;\n"
00354 "}\n",
00355 TOP_count);
00356
00357 fprintf(hfile, "\ninline ISA_HAZARD_INFO *ISA_HAZARD_First(TOP topcode)\n"
00358 "{\n"
00359 " extern mUINT8 ISA_HAZARD_hazard_index[%d];\n"
00360 " extern ISA_HAZARD_INFO ISA_HAZARD_hazard_info[%d];\n"
00361 " INT index = ISA_HAZARD_hazard_index[(INT)topcode];\n"
00362 " return index ? ISA_HAZARD_hazard_info + index : (ISA_HAZARD_INFO *)0;\n"
00363 "}\n",
00364 TOP_count,
00365 haz_index + 1);
00366
00367 fprintf(hfile, "\ninline ISA_HAZARD_INFO *ISA_HAZARD_Next(ISA_HAZARD_INFO *info)\n"
00368 "{\n"
00369 " extern ISA_HAZARD_INFO ISA_HAZARD_hazard_info[%d];\n"
00370 " INT index = info->next;\n"
00371 " return index ? ISA_HAZARD_hazard_info + index : (ISA_HAZARD_INFO *)0;\n"
00372 "}\n",
00373 haz_index + 1);
00374
00375 fprintf(hfile, "\ninline ISA_HAZARD ISA_HAZARD_Type(ISA_HAZARD_INFO *info)\n"
00376 "{\n"
00377 " return info->type;\n"
00378 "}\n");
00379
00380 fprintf(hfile, "\ninline INT ISA_HAZARD_Data(ISA_HAZARD_INFO *info)\n"
00381 "{\n"
00382 " return info->data;\n"
00383 "}\n");
00384
00385 fprintf(hfile, "\ninline INT ISA_HAZARD_Pre_Ops(ISA_HAZARD_INFO *info)\n"
00386 "{\n"
00387 " return info->pre_ops;\n"
00388 "}\n");
00389
00390 fprintf(hfile, "\ninline INT ISA_HAZARD_Post_Ops(ISA_HAZARD_INFO *info)\n"
00391 "{\n"
00392 " return info->post_ops;\n"
00393 "}\n");
00394
00395 fprintf(hfile, "\nextern void ISA_HAZARD_Initialize(void);\n");
00396
00397 fprintf(efile, "ISA_HAZARD_Initialize\n");
00398
00399 fprintf(cfile, "\nvoid ISA_HAZARD_Initialize(void)\n"
00400 "{\n"
00401 " INT top;\n"
00402 " INT mask = 1 << (INT)ISA_SUBSET_Value;\n"
00403 " for ( top = 0; top < TOP_count; ++top ) {\n"
00404 " INT j, k;\n"
00405 " INT i = ISA_HAZARD_hazard_index[top];\n"
00406 " for (j = i; j != 0; j = k) {\n"
00407 " for (k = ISA_HAZARD_hazard_info[j].next;\n"
00408 " k != 0 && (ISA_HAZARD_hazard_info[k].isa_mask & mask) == 0;\n"
00409 " k = ISA_HAZARD_hazard_info[k].next\n"
00410 " );\n"
00411 " ISA_HAZARD_hazard_info[j].next = k;\n"
00412 " }\n"
00413 " if ((ISA_HAZARD_hazard_info[i].isa_mask & mask) == 0) {\n"
00414 " ISA_HAZARD_hazard_index[top] = ISA_HAZARD_hazard_info[i].next;\n"
00415 " }\n"
00416 " }\n"
00417 "}\n");
00418
00419 Emit_Footer (hfile);
00420 }