Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
abi_properties_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 //  abi_properties_gen.cxx
00038 //
00039 //  Description:
00040 //
00041 //      Generate a description of the ABI properties.
00042 //
00044 //
00045 
00046 #include <cstring>
00047 #include <cstddef>
00048 #include <cstdlib>
00049 #include <cstdarg>
00050 #include <cstdio>
00051 #include <cassert>
00052 
00053 #include <list>
00054 
00055 using namespace std;
00056 
00057 #include "gen_util.h"
00058 #include "targ_isa_registers.h"
00059 #include "abi_properties_gen.h"
00060 
00061 //
00062 // Information about a property
00063 //
00064 struct abi_property {
00065   const char* name;             // Name given for documentation and debugging
00066   bool is_reg;                  // Register or non-register
00067   bool is_flag;                 // Boolean flag or value
00068   unsigned long long v;         // Flag mask (is_flag) or value (!is_flag)
00069 };
00070 
00071 //
00072 // Information about an ABI
00073 //
00074 typedef struct abi {
00075   const char *name;             // Name
00076   list<ABI_PROPERTY> flags;     // Non-register flag properties
00077   list<ABI_PROPERTY> values;    // Non-register value properties
00078   list<ABI_PROPERTY> reg_flags[ISA_REGISTER_CLASS_MAX+1][ISA_REGISTER_MAX+1];
00079                                 // Register flag properties
00080   list<ABI_PROPERTY> reg_values[ISA_REGISTER_CLASS_MAX+1][ISA_REGISTER_MAX+1];
00081                                 // Register value properties
00082   const char *reg_names[ISA_REGISTER_CLASS_MAX+1][ISA_REGISTER_MAX+1];
00083                                 // Register names
00084 } *ABI;
00085 
00086 
00087 static list<ABI_PROPERTY> props; // All the properties
00088 static list<ABI> abis;          // All the ABIs
00089 static ABI current_abi;         // The current ABI being described
00090 static int prop_count[2 /* is_flag */][2 /* is_reg */] = {0};
00091                                 // Counts of the various kinds of props
00092 
00093 static const char * const interface[] = {
00094   "/* ====================================================================",
00095   " * ====================================================================",
00096   " *",
00097   " * Description:",
00098   " *",
00099   " *   A description of the ABI properties. The description exports",
00100   " *   the following:",
00101   " *",
00102   " *   typedef (enum) ABI_PROPERTIES_ABI",
00103   " *",
00104   " *       An enumeration of the ABIs described. The names have the form:",
00105   " *",
00106   " *          ABI_PROPERTIES_ABI_xxx",
00107   " *",
00108   " *       where 'xxx' is replaced with the ABI name.",
00109   " *",
00110   " *   const ABI_PROPERTIES_ABI ABI_PROPERTIES_ABI_UNDEFINED",
00111   " *       Useful value guaranteed not to be a valid ABI_PROPERTIES_ABI.",
00112   " *",
00113   " *   ABI_PROPERTIES_ABI ABI_PROPERTIES_ABI_Value",
00114   " *       A variable containing the current ABI value.",
00115   " *",
00116   " *   const char *ABI_PROPERTIES_ABI_Name(ABI_PROPERTIES_ABI abi)",
00117   " *      Returns a name for the given 'abi'.",
00118   " *",
00119   " *   void ABI_PROPERTIES_Initialize(void)",
00120   " *       Initialize for the target ABI specified by ABI_PROPERTIES_ABI_Value.",
00121   " *",
00122   " *   const char *ABI_PROPERTY_Reg_Name(",
00123   " *     ISA_REGISTER_CLASS rc,",
00124   " *     INT reg",
00125   " *   )",
00126   " *       Return the ABI specific name of register 'reg' in class 'rc'.",
00127   " *",
00128   " *   BOOL ABI_PROPERTY_Is_xxx(",
00129   " *     ISA_REGISTER_CLASS rc,",
00130   " *     INT reg",
00131   " *   )",
00132   " *       Return a boolean that indicates if register 'reg' in class",
00133   " *       'rc' had the property 'xxx'.",
00134   " *",
00135   " * ====================================================================",
00136   " * ====================================================================",
00137   " */",
00138   NULL
00139 };
00140 
00141 
00143 void ABI_Properties_Begin(const char * /* name */)
00145 //  See interface description.
00147 {
00148 }
00149 
00150 
00152 ABI_PROPERTY Create_Reg_Property(const char *name)
00154 //  See interface description.
00156 {
00157   ABI_PROPERTY result = new abi_property;
00158 
00159   result->name = name;
00160   result->is_reg = true;
00161   result->is_flag = true;
00162   result->v = 0;
00163 
00164   props.push_back(result);
00165 
00166   return result;
00167 }
00168 
00169 
00171 void Begin_ABI(const char *name)
00173 //  See interface description.
00175 {
00176   ABI result = new abi;
00177 
00178   result->name = name;
00179   bzero(result->reg_names, sizeof(result->reg_names));
00180 
00181   current_abi = result;
00182 
00183   abis.push_back(result);
00184 }
00185 
00186 
00188 void Reg_Property(ABI_PROPERTY prop, ISA_REGISTER_CLASS rc, ...)
00190 //  See interface description.
00192 {
00193   va_list ap;
00194   int reg_num;
00195   bool used = false;
00196 
00197   va_start(ap,rc);
00198   while ( (reg_num = va_arg(ap,int)) != -1 ) {
00199     current_abi->reg_flags[rc][reg_num].push_back(prop);
00200     used = true;
00201   }
00202   va_end(ap);
00203 
00204   if (used && prop->v == 0) {
00205     prop->v = 1ULL << prop_count[true][true];
00206     ++prop_count[true][true];
00207   }
00208 }
00209 
00210 
00212 void Reg_Names(ISA_REGISTER_CLASS rc, INT minreg, INT maxreg, const char **names)
00214 //  See interface description.
00216 {
00217   int reg_num;
00218   for (reg_num = minreg; reg_num <= maxreg; ++reg_num) {
00219     current_abi->reg_names[rc][reg_num] = names[reg_num - minreg];
00220   }
00221 }
00222 
00223 
00225 static const char *Type_Name(int bits)
00227 //  Given a number of bits, return the name of the smallest unsigned
00228 //  type that can hold values of that size.
00230 {
00231   if (bits <= 8) {
00232     return "mUINT8";
00233   } else if (bits <= 16) {
00234     return "mUINT16";
00235   } else if (bits <= 32) {
00236     return "mUINT32";
00237   } else {
00238     assert (bits <= 64);
00239     return "mUINT64";
00240   }
00241 }
00242 
00243 
00245 static const char *Type_Suffix(int bits)
00247 //  Given a number of bits, return the suffix, for an integral constant
00248 //  specification, that corresponds to the type used to hold values of
00249 //  this size.
00251 {
00252   if (bits <= 8) {
00253     return "";
00254   } else if (bits <= 16) {
00255     return "";
00256   } else if (bits <= 32) {
00257     return "U";
00258   } else {
00259     assert (bits <= 64);
00260     return "ULL";
00261   }
00262 }
00263 
00264 
00266 static int Type_Size(int bits)
00268 //  Given a number of bits, return the size in bits of the smallest
00269 //  unsigned type can hold values of that size.
00271 {
00272   if (bits <= 8) {
00273     return 8;
00274   } else if (bits <= 16) {
00275     return 16;
00276   } else if (bits <= 32) {
00277     return 32;
00278   } else {
00279     assert (bits <= 64);
00280     return 64;
00281   }
00282 }
00283 
00284 
00286 void ABI_Properties_End(void)
00288 //  See interface description.
00290 {
00291   list<ABI_PROPERTY>::iterator prop_iter;
00292   list<ABI>::iterator abi_iter;
00293 
00294   char filename[1000];
00295   sprintf (filename, "targ_abi_properties.h");
00296   FILE* hfile = fopen(filename, "w");
00297   sprintf (filename, "targ_abi_properties.c");
00298   FILE* cfile = fopen(filename, "w");
00299   sprintf(filename,"targ_abi_properties.Exported");
00300   FILE* efile = fopen(filename,"w");
00301 
00302   fprintf(cfile,"#include \"targ_abi_properties.h\"\n\n");
00303 
00304   sprintf (filename, "targ_abi_properties");
00305   Emit_Header (hfile, filename, interface);
00306   fprintf(hfile,"#include \"targ_isa_registers.h\"\n");
00307 
00308   //
00309   // Generate the ABI_PROPERTIES decl
00310   //
00311   fprintf(hfile, "\ntypedef struct {\n");
00312   if (prop_count[true][false] != 0) {
00313     fprintf(hfile, "  %s flags;\n", Type_Name(prop_count[true][false]));
00314   }
00315   if (prop_count[true][true] != 0) {
00316     fprintf(hfile, "  %s reg_flags[%d][%d];\n", 
00317                    Type_Name(prop_count[true][true]),
00318                    ISA_REGISTER_CLASS_MAX+1,
00319                    ISA_REGISTER_MAX+1);
00320   }
00321   fprintf(hfile, "  const char *reg_names[%d][%d];\n",
00322                  ISA_REGISTER_CLASS_MAX+1,
00323                  ISA_REGISTER_MAX+1);
00324   fprintf(hfile, "} ABI_PROPERTIES;\n");
00325 
00326   //
00327   // Generate the property flags decls
00328   //
00329   fprintf(hfile, "\n");
00330   for (prop_iter = props.begin(); prop_iter != props.end(); ++prop_iter) {
00331     ABI_PROPERTY prop = *prop_iter;
00332     assert(prop->is_flag);
00333     fprintf(hfile, "#define ABI_PROPERTY_%-20s 0x%0*llx%s\n",
00334                    prop->name,
00335                    Type_Size(prop_count[true][prop->is_reg]) / 4,
00336                    prop->v,
00337                    Type_Suffix(prop_count[true][prop->is_reg]));
00338   }
00339 
00340   //
00341   // Generate the properties data and the ABI enumeration
00342   //
00343   int num_abi = 0;
00344   fprintf(hfile, "\ntypedef enum {\n");
00345   fprintf(cfile, "\nstatic const ABI_PROPERTIES abi_properties[] = {\n");
00346   for (abi_iter = abis.begin(); abi_iter != abis.end(); ++abi_iter) {
00347     int rc;
00348     ABI abi = *abi_iter;
00349     ++num_abi;
00350 
00351     fprintf(hfile, "  ABI_PROPERTIES_ABI_%s,\n", abi->name);
00352 
00353     fprintf(cfile, "  {\n"
00354                    "    /* %s */\n",
00355                    abi->name);
00356 
00357     int count = prop_count[true][false];
00358     if (count != 0) {
00359       unsigned long long mask = 0;
00360       for (prop_iter = abi->flags.begin(); prop_iter != abi->flags.end(); ++prop_iter) {
00361         ABI_PROPERTY prop = *prop_iter;
00362         mask |= prop->v;
00363       }
00364       fprintf(cfile, "    0x%0*llx%s,\n",
00365                      Type_Size(count) / 4,
00366                      mask,
00367                      Type_Suffix(count));
00368     }
00369 
00370     count = prop_count[true][true];
00371     if (count != 0) {
00372       fprintf(cfile, "    {\n");
00373       for (rc = 0; rc <= ISA_REGISTER_CLASS_MAX; ++rc) {
00374         int reg;
00375         const ISA_REGISTER_CLASS_INFO *cinfo 
00376           = ISA_REGISTER_CLASS_Info((ISA_REGISTER_CLASS)rc);
00377 
00378         fprintf(cfile, "      /* ISA_REGISTER_CLASS_%s */\n",
00379                        ISA_REGISTER_CLASS_INFO_Name(cinfo));
00380         int cursor = fprintf(cfile, "      {");
00381         for (reg = 0; reg <= ISA_REGISTER_MAX; ++reg) {
00382           unsigned long long mask = 0;
00383           list<ABI_PROPERTY> props = abi->reg_flags[rc][reg];
00384           for (prop_iter = props.begin(); prop_iter != props.end(); ++prop_iter) {
00385             ABI_PROPERTY prop = *prop_iter;
00386             mask |= prop->v;
00387           }
00388           if (cursor >= 80 - (4 + Type_Size(count) / 4) - 3 - 1) {
00389             fprintf(cfile, "\n");
00390             cursor = fprintf(cfile, "       ");
00391           }
00392           cursor += fprintf(cfile, " 0x%0*llx%s,",
00393                                    Type_Size(count) / 4,
00394                                    mask,
00395                                    Type_Suffix(count));
00396         }
00397         fprintf(cfile, " },\n");
00398       }
00399       fprintf(cfile, "    },\n");
00400     }
00401 
00402     fprintf(cfile, "    {\n");
00403     for (rc = 0; rc <= ISA_REGISTER_CLASS_MAX; ++rc) {
00404       int reg;
00405       const ISA_REGISTER_CLASS_INFO *cinfo 
00406         = ISA_REGISTER_CLASS_Info((ISA_REGISTER_CLASS)rc);
00407 
00408       fprintf(cfile, "      /* ISA_REGISTER_CLASS_%s */\n",
00409                      ISA_REGISTER_CLASS_INFO_Name(cinfo));
00410       int cursor = fprintf(cfile, "      {");
00411       for (reg = 0; reg <= ISA_REGISTER_MAX; ++reg) {
00412         const char *name = abi->reg_names[rc][reg];
00413         if (name == NULL) name = ISA_REGISTER_CLASS_INFO_Reg_Name(cinfo, reg);
00414         if (name == NULL) name = "";
00415         if (cursor >= 80 - (4 + strlen(name))) {
00416           fprintf(cfile, "\n");
00417           cursor = fprintf(cfile, "       ");
00418         }
00419         cursor += fprintf(cfile, " \"%s\",", name);
00420       }
00421       fprintf(cfile, " },\n");
00422     }
00423     fprintf(cfile, "    },\n");
00424 
00425     fprintf(cfile, "  },\n");
00426   }
00427   fprintf(cfile, "};\n");
00428   fprintf(hfile, "  ABI_PROPERTIES_ABI_UNDEFINED,\n"
00429                  "  ABI_PROPERTIES_ABI_MAX=%d\n"
00430                  "} ABI_PROPERTIES_ABI;\n",
00431                  num_abi-1);
00432 
00433   //
00434   // Generate the abi names
00435   //
00436   fprintf(cfile, "\nstatic const char * const abi_names[] = {\n");
00437   for (abi_iter = abis.begin(); abi_iter != abis.end(); ++abi_iter) {
00438     ABI abi = *abi_iter;
00439     fprintf(cfile, "  \"%s\",\n", abi->name);
00440   }
00441   fprintf(cfile, "  \"UNDEFINED\"\n"
00442                  "};\n");
00443 
00444   //
00445   // Generate decls for accessing the ABI data and initializiation
00446   //
00447   fprintf(hfile, "\nextern ABI_PROPERTIES_ABI ABI_PROPERTIES_ABI_Value;\n");
00448   fprintf(cfile, "\nABI_PROPERTIES_ABI ABI_PROPERTIES_ABI_Value = ABI_PROPERTIES_ABI_UNDEFINED;\n");
00449   fprintf(efile, "ABI_PROPERTIES_ABI_Value\n");
00450 
00451   fprintf(hfile, "\nextern const char *ABI_PROPERTIES_ABI_Name(ABI_PROPERTIES_ABI abi);\n");
00452   fprintf(cfile, "\nconst char *ABI_PROPERTIES_ABI_Name(ABI_PROPERTIES_ABI abi)\n"
00453                  "{\n"
00454                  "  return abi_names[(INT)abi];\n"
00455                  "}\n");
00456   fprintf(efile, "ABI_PROPERTIES_Initialize\n");
00457 
00458   fprintf(cfile, "\nconst ABI_PROPERTIES *ABI_PROPERTIES_target_props"
00459                  " = &abi_properties[ABI_PROPERTIES_ABI_UNDEFINED];\n");
00460   fprintf(efile, "ABI_PROPERTIES_target_props\n");
00461 
00462   fprintf(hfile, "\nextern void ABI_PROPERTIES_Initialize(void);\n");
00463   fprintf(cfile, "\nvoid ABI_PROPERTIES_Initialize(void)\n"
00464                  "{\n"
00465                  "  ABI_PROPERTIES_target_props = &abi_properties[(INT)ABI_PROPERTIES_ABI_Value];\n"
00466                  "}\n");
00467   fprintf(efile, "ABI_PROPERTIES_Initialize\n");
00468 
00469   //
00470   // Generate the property accessors
00471   //
00472   fprintf(hfile, "\ninline const char *ABI_PROPERTY_Reg_Name(\n"
00473                  "  ISA_REGISTER_CLASS rc,\n"
00474                  "  INT reg)\n"
00475                  "{\n"
00476                  "  extern const ABI_PROPERTIES *ABI_PROPERTIES_target_props;\n"
00477                  "  return ABI_PROPERTIES_target_props->reg_names[rc][reg];\n"
00478                  "}\n");
00479 
00480   for (prop_iter = props.begin(); prop_iter != props.end(); ++prop_iter) {
00481     ABI_PROPERTY prop = *prop_iter;
00482     assert(prop->is_flag);
00483     fputs(prop->v ? "\n" : "\n/*ARGSUSED*/\n", hfile);
00484     if (prop->is_reg) {
00485       fprintf(hfile, "inline BOOL ABI_PROPERTY_Is_%s(\n"
00486                      "  ISA_REGISTER_CLASS rc,\n"
00487                      "  INT reg)\n"
00488                      "{\n",
00489                      prop->name);
00490       if (prop->v == 0) {
00491         fprintf(hfile, "  return FALSE;\n"
00492                        "}\n");
00493       } else {
00494         fprintf(hfile, "  extern const ABI_PROPERTIES *ABI_PROPERTIES_target_props;\n"
00495                        "  return (  ABI_PROPERTIES_target_props->reg_flags[rc][reg]\n"
00496                        "          & ABI_PROPERTY_%s) != 0;\n"
00497                        "}\n",
00498                        prop->name);
00499       }
00500     } else {
00501       fprintf(hfile, "inline BOOL ABI_PROPERTY_Is_%s(void)\n"
00502                      "{\n",
00503                      prop->name);
00504       if (prop->v == 0) {
00505         fprintf(hfile, "  return FALSE;\n"
00506                        "}\n");
00507       } else {
00508         fprintf(hfile, "  extern const ABI_PROPERTIES *ABI_PROPERTIES_target_props;\n"
00509                        "  return (  ABI_PROPERTIES_target_props->flags\n"
00510                        "          & ABI_PROPERTY_%s) != 0;\n"
00511                        "}\n",
00512                        prop->name);
00513       }
00514     }
00515   }
00516   
00517   Emit_Footer (hfile);
00518 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines