Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
isa_hazards_gen.cxx
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 //  isa_hazards_gen.cxx
00038 //
00039 //  Description:
00040 //
00041 //      Generate a description of the ISA hazards. 
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;         // hazard 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;    // All the 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* /* name */ )
00143 //  See interface description.
00145 {
00146 }
00147 
00149 ISA_HAZARD Hazard_Create( const char *name )
00151 //  See interface description.
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 //  See interface description.
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 //  See interface description.
00199 {
00200   current_haz_desc->type = isa_hazard;
00201 }
00202 
00203 
00205 void Hazard_Data( int data )
00207 //  See interface description.
00209 {
00210   current_haz_desc->data = data;
00211 }
00212 
00213 
00215 void Hazard_Post_Ops( int ops )
00217 //  See interface description.
00219 {
00220   current_haz_desc->post_ops = ops;
00221 }
00222 
00223 
00225 void Hazard_Pre_Ops( int ops )
00227 //  See interface description.
00229 {
00230   current_haz_desc->pre_ops = ops;
00231 }
00232 
00233 
00235 void Hazard_ISA( ISA_SUBSET isa )
00237 //  See interface description.
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 //  See interface description.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines