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