Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
isa_bundle_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_bundle_gen.cxx
00038 //
00039 //  Gneerate an interface for specifying template encoding instructions 
00040 //  within a bundle.
00041 //
00043 
00044 #include <alloca.h>
00045 #include <cstddef>
00046 #include <cstdlib>
00047 #include <cstdarg>
00048 #include <cstdio>
00049 #include <cassert>
00050 #include <cstring>
00051 
00052 #include <vector>
00053 #include <list>
00054 
00055 using namespace std;
00056 
00057 #include "topcode.h"
00058 #include "targ_isa_properties.h"
00059 #include "gen_util.h"
00060 #include "isa_bundle_gen.h"
00061 
00062 #define MAX_SLOTS 3     // max # of slots the generator can handle
00063 #define TAG_SHIFT 12    // max # of bits required to encode all the
00064                         // execution property types.
00065 
00066 struct isa_exec_unit_type {
00067   const char *name;     // Name given for documentation and debugging
00068   int bit_position;     // bit position in flag word
00069   vector <bool> members; // set of opcodes that have this property
00070   ISA_EXEC_UNIT_TYPE base_unit; // base exec unit type (or null if base)
00071 };
00072 
00073 struct isa_bundle_type {
00074   const char *name;
00075   const char *asm_name;
00076   int slot_count;
00077   ISA_EXEC_UNIT_TYPE slot[MAX_SLOTS];
00078   bool stop_bit[MAX_SLOTS];
00079   unsigned int pack_code;
00080 };
00081 
00082 static int isa_exec_property_count = 0; 
00083 
00084 static int num_bundles = 0;
00085 static int max_slots = 0;
00086 static int bundle_bits;
00087 static list <ISA_EXEC_UNIT_TYPE> all_exec_types; 
00088 static list <ISA_BUNDLE_TYPE> all_bundles; 
00089 static ISA_EXEC_UNIT_TYPE current_exec_type_desc;
00090 static ISA_BUNDLE_TYPE current_bundle_desc;
00091 
00092 static const char * const interface[] = {
00093   "/* ====================================================================",
00094   " * ====================================================================",
00095   " *",
00096   " * Description:",
00097   " *",
00098   " *   A description of the bundling properties. The interface is",
00099   " *   divided into two pieces: scheduling, and packing. The scheduling",
00100   " *   interface exports the following:",
00101   " *",
00102   " *   const INT ISA_MAX_SLOTS",
00103   " *       An integer constant that indicates the maximum number of",
00104   " *       slots in a bundle.",
00105   " *",
00106   " *   const INT ISA_TAG_SHIFT",
00107   " *       Maximum number of bits required to encode all the execution",
00108   " *       property types.",
00109   " *",
00110   " *   typedef mUINTxx ISA_EXEC_UNIT_PROPERTY",
00111   " *       A single-bit mask of representing an execution unit.",
00112   " *",
00113   " *       The names have the form ISA_EXEC_PROPERTY_xxx",
00114   " *       where 'xxx' is replaced with the EXEC_UNIT_PROPERTY name.",
00115   " *",
00116   " *   typedef (enum) ISA_EXEC_UNIT",
00117   " *       An enumeration of the execution units.",
00118   " *",
00119   " *       The names have the form ISA_EXEC_xxx",
00120   " *       where 'xxx' is replaced with the EXEC_UNIT_PROPERTY name.",
00121   " *",
00122   " *       The values of ISA_EXEC_UNIT and ISA_EXEC_UNIT_PROPERTY are",
00123   " *       related in that the bit-mask value of an ISA_EXEC_UNIT_PROPERTY",
00124   " *       is equal to 2**ISA_EXEC_UNIT.",
00125   " *",
00126   " *   const INT ISA_EXEC_MAX",
00127   " *       The highest value ISA_EXEC_UNIT value.",
00128   " *",
00129   " *   BOOL ISA_EXEC_PROPERTY_is_xxx(TOP t) ",
00130   " *       Returns TRUE if EXEC_PROPERTY_is_xxx matches <t>'s property.",
00131   " *",
00132   " *   ISA_EXEC_UNIT_PROPERTY ISA_EXEC_Unit_Prop(TOP topcode)",
00133   " *       Returns exec_unit_property for the instruction specified",
00134   " *       by <topcode>.",
00135   " *",
00136   " *   ISA_BUNDLE_INFO ISA_EXEC_Bundle_Info(INT index)",
00137   " *       Return isa_bundle_info specified by <index>. ",
00138   " *",
00139   " *   ISA_EXEC_UNIT_PROPERTY ISA_EXEC_Slot_Prop(INT bundle, INT slot_index)",
00140   " *       Return exec_unit_property for the slot position <slot_index>",
00141   " *       in <bundle>.",
00142   " *",
00143   " *   UINT64 ISA_EXEC_Slot_Mask(INT bundle)",
00144   " *       Return slot_mask for <bundle>.",
00145   " *",
00146   " *   BOOL ISA_EXEC_Stop(INT bundle, INT slot_index)",
00147   " *       Return stop bit for the slot position <slot_index> in <bundle>.",
00148   " *",
00149   " *   ISA_EXEC_UNIT ISA_EXEC_Unit(INT bundle, INT slot_index)",
00150   " *       Return the execution unit slot position <slot_index> in <bundle>.",
00151   " *",
00152   " *   UINT32 ISA_EXEC_Stop_Mask(INT bundle)",
00153   " *       Return stop_mask for <bundle>.",
00154   " *",
00155   " *   const char *ISA_EXEC_Name(INT bundle)",
00156   " *       Return the name for <bundle>.",
00157   " *",
00158   " *   const char *ISA_EXEC_AsmName(INT bundle)",
00159   " *       Return the assembly language name for <bundle>.",
00160   " *",
00161   " * ====================================================================",
00162   " *",
00163   " *   The packing interface exports the following:",
00164   " *",
00165   " *   typedef ISA_BUNDLE",
00166   " *       A type large enough to hold a bundle. This type will always",
00167   " *       be a struct containing an array of either 32-, or 64-bit",
00168   " *       unsigned integers.",
00169   " *",
00170   " *   typedef (enum) ISA_BUNDLE_PACK_COMP",
00171   " *       An enumeration of the bundle components to be packed.",
00172   " *",
00173   " *   const INT ISA_BUNDLE_PACK_COMP_MAX",
00174   " *       The maximum number of components to be packed for a bundle.",
00175   " *",
00176   " *   typedef (struct) ISA_BUNDLE_PACK_INFO",
00177   " *       Describes how a the components of a bundle are packed.",
00178   " *       The contents are private.",
00179   " *",
00180   " *   const ISA_BUNDLE_PACK_INFO *ISA_BUNDLE_Pack_Info(void)",
00181   " *       Returns a pointer to the first packing component.",
00182   " *       Increment the returned pointer to access any additional packing",
00183   " *       components for the bundle. A component of ISA_PACK_COMP_end",
00184   " *       marks the end.",
00185   " *",
00186   " *   INT ISA_BUNDLE_PACK_INFO_Comp(const ISA_BUNDLE_PACK_INFO *info)",
00187   " *       Identifies the bundle component to be packed.",
00188   " *",
00189   " *   INT ISA_BUNDLE_PACK_INFO_Index(const ISA_BUNDLE_PACK_INFO *info)",
00190   " *       The index of the bundle word containing the component.",
00191   " *",
00192   " *       ISA_BUNDLE_PACK_INFO_Index is meaningless for ISA_BUNDLE_PACK_COMP_end.",
00193   " *",
00194   " *   INT ISA_BUNDLE_PACK_INFO_CompPos(const ISA_BUNDLE_PACK_INFO *info)",
00195   " *       The offset, in bits, to the start of the component in the",
00196   " *       component value.",
00197   " *",
00198   " *       ISA_BUNDLE_PACK_INFO_CompPos is meaningless for ISA_BUNDLE_PACK_COMP_end.",
00199   " *",
00200   " *   INT ISA_BUNDLE_PACK_INFO_BundlePos(const ISA_BUNDLE_PACK_INFO *info)",
00201   " *       The offset, in bits, to the start of the component in the",
00202   " *       bundle word.",
00203   " *",
00204   " *       ISA_BUNDLE_PACK_INFO_BundlePos is meaningless for ISA_BUNDLE_PACK_COMP_end.",
00205   " *",
00206   " *   UINT64 ISA_BUNDLE_PACK_INFO_Mask(const ISA_BUNDLE_PACK_INFO *info)",
00207   " *       A bit mask that is as wide as the bundle component being",
00208   " *       packed. The mask is shifted to match the field in the",
00209   " *       bundle word.",
00210   " *",
00211   " *       ISA_BUNDLE_PACK_INFO_Mask is meaningless for ISA_BUNDLE_PACK_COMP_end.",
00212   " *",
00213   " *   INT ISA_BUNDLE_Pack_Info_Index(ISA_BUNDLE_PACK_COMP comp)",
00214   " *       Index into bundle packing info array (see ISA_BUNDLE_Pack_Info)",
00215   " *       to the start of the info for the component <comp>. If there",
00216   " *       is no packing info for <comp>, the index is for the 'end'",
00217   " *       component.",
00218   " *",
00219   " * ====================================================================",
00220   " * ====================================================================",
00221   " */",
00222   NULL
00223 };
00224 
00225 /* ====================================================================
00226  *
00227  * This section handles bundle scheduling
00228  *
00229  * ====================================================================
00230  */
00231 
00233 ISA_EXEC_UNIT_TYPE ISA_Exec_Unit_Type_Create ( const char* name,
00234                                                ISA_EXEC_UNIT_TYPE base_unit )
00236 //  See interface description.
00238 {
00239   ISA_EXEC_UNIT_TYPE cur_type = new isa_exec_unit_type;
00240 
00241   cur_type->name = name;
00242   cur_type->bit_position = isa_exec_property_count++;
00243   cur_type->members = vector<bool> (TOP_count, false);
00244   cur_type->base_unit = base_unit;
00245 
00246   current_exec_type_desc = cur_type;
00247   all_exec_types.push_back (current_exec_type_desc);
00248   return cur_type;
00249 }
00250 
00252 void Instruction_Exec_Unit_Group(ISA_EXEC_UNIT_TYPE unit_type, ... )
00254 //  See interface description.
00256 {
00257   va_list ap;
00258   TOP opcode;
00259 
00260   if (!current_exec_type_desc->name) {
00261     fprintf(stderr,"### Error: no execution unit type name specified for %s\n",
00262                    current_exec_type_desc->name);
00263     exit(EXIT_FAILURE);
00264   }
00265  
00266   va_start(ap, unit_type);
00267   while ( (opcode = static_cast<TOP>(va_arg(ap, int))) != TOP_UNDEFINED) {
00268       unit_type->members[(int)opcode] = true;      
00269   }
00270   va_end(ap);  
00271 }
00272 
00274 void ISA_Bundle_Type_Create (const char* name, const char* asm_name, 
00275                              int no_slots )
00277 //  See interface description.
00279 {
00280   int i;
00281   ISA_BUNDLE_TYPE cur_type = new isa_bundle_type;
00282   cur_type->name = name;
00283   cur_type->asm_name = asm_name;
00284   cur_type->slot_count = no_slots;
00285   cur_type->pack_code = num_bundles;
00286   for (i = 0; i < no_slots; ++i) cur_type->stop_bit[i] = false;
00287 
00288   current_bundle_desc = cur_type;
00289   all_bundles.push_back (current_bundle_desc);
00290 
00291   if (no_slots > max_slots) max_slots = no_slots;
00292   ++num_bundles;
00293 }
00294 
00296 void Slot (int slot_index, ISA_EXEC_UNIT_TYPE type)
00298 //  See interface description.
00300 {
00301   if (slot_index > current_bundle_desc->slot_count) {
00302     fprintf(stderr, "### Error: slot index (%d) exceeds %d\n",
00303                     slot_index, current_bundle_desc->slot_count);
00304     exit(EXIT_FAILURE);
00305   }
00306 
00307   if (!type) {
00308     fprintf(stderr, "### Error: slot type have non NULL value \n");
00309     exit(EXIT_FAILURE);
00310   }
00311 
00312   current_bundle_desc->slot[slot_index] = type;
00313 }
00314 
00316 void Stop (int slot_index)
00318 //  See interface description.
00320 {
00321   if (slot_index > current_bundle_desc->slot_count) {
00322     fprintf(stderr, "### Error: slot index (%d) exceeds %d\n",
00323                     slot_index, current_bundle_desc->slot_count);
00324     exit(EXIT_FAILURE);
00325   }
00326 
00327   current_bundle_desc->stop_bit[slot_index] = true;
00328 }
00329 
00331 static void Emit_Bundle_Scheduling(FILE *hfile, FILE *cfile, FILE *efile)
00333 //  Emit the bundle scheduling interface.
00335 {
00336   list<ISA_EXEC_UNIT_TYPE>::iterator iei;
00337   list<ISA_BUNDLE_TYPE>::iterator ibi;
00338   int i;
00339 
00340   const char * const isa_exec_type_format = "  %3llu,  /* %s: ";
00341   const char *info_index_type;
00342 
00343   int index = 0;
00344   for (iei = all_exec_types.begin(); iei != all_exec_types.end(); ++index,
00345                                                                   ++iei) {
00346   }
00347 
00348   const char *int_suffix;
00349   // select the ISA_EXEC_unit_prop based on the number of exec info types.
00350   if (index <= 8) {
00351     info_index_type = "mUINT8";
00352     int_suffix = "";
00353   } else if (index <= 16) {
00354     info_index_type = "mUINT16";
00355     int_suffix = "";
00356   } else if (index <= 32) {
00357     info_index_type = "mUINT32";
00358     int_suffix = "U";
00359   } else {
00360     assert (index <= 64);
00361     info_index_type = "mUINT64";
00362     int_suffix = "ULL";
00363   }
00364 
00365   fprintf (hfile, "\n#define ISA_MAX_SLOTS (%d)\n", max_slots);
00366   fprintf (hfile, "#define ISA_TAG_SHIFT (%d)\n", TAG_SHIFT);
00367 
00368   fprintf (hfile, "\ntypedef %s ISA_EXEC_UNIT_PROPERTY;\n",
00369            info_index_type);
00370 
00371   fprintf (hfile, "\n");
00372   for (iei = all_exec_types.begin(); iei != all_exec_types.end(); ++iei) {
00373     ISA_EXEC_UNIT_TYPE curr_exec_type = *iei;
00374     fprintf (hfile, "#define ISA_EXEC_PROPERTY_%-15s (0x%llx%s)\n",
00375                     curr_exec_type->name,
00376                     (1ULL << curr_exec_type->bit_position), int_suffix);
00377   }
00378 
00379   fprintf (hfile, "\ntypedef enum {\n");
00380   for (iei = all_exec_types.begin(); iei != all_exec_types.end(); ++iei) {
00381     ISA_EXEC_UNIT_TYPE curr_exec_type = *iei;
00382     fprintf (hfile, "  ISA_EXEC_%-15s = %d,\n",
00383                     curr_exec_type->name,
00384                     curr_exec_type->bit_position);
00385   }
00386   fprintf (hfile, "  ISA_EXEC_%-15s = %d\n"
00387                   "} ISA_EXEC_UNIT;\n",
00388                   "MAX", isa_exec_property_count - 1);
00389 
00390   fprintf (hfile, "\ntypedef struct {\n"
00391                   "  const char *name;\n"
00392                   "  const char *asm_name;\n"
00393                   "  int slot_count;\n"
00394                   "  ISA_EXEC_UNIT_PROPERTY slot[%d];\n"
00395                   "  mBOOL stop[%d];\n"
00396                   "  mUINT8 unit[%d];\n"
00397                   "  mUINT8 pack_code;\n"
00398                   "  mUINT8 stop_mask;\n"
00399                   "  mUINT64 slot_mask;\n"
00400                   "} ISA_BUNDLE_INFO;\n",
00401                   max_slots ? max_slots : 1,
00402                   max_slots ? max_slots : 1,
00403                   max_slots ? max_slots : 1);
00404 
00405   fprintf(efile, "ISA_BUNDLE_info\n");
00406   fprintf(cfile, "\nconst ISA_BUNDLE_INFO ISA_BUNDLE_info[] = {\n");
00407 
00408   int slot_mask_digits = ((TAG_SHIFT * max_slots) + 3) / 4;
00409   for (ibi = all_bundles.begin(); ibi != all_bundles.end(); ++ibi) {
00410     ISA_BUNDLE_TYPE curr_exec_type = *ibi;
00411     fprintf (cfile, " {\n    \"%s\",%*s \"%s\",%*s %d,", 
00412                     curr_exec_type->name, 
00413                     13 - strlen(curr_exec_type->name), "",
00414                     curr_exec_type->asm_name, 
00415                     8 - strlen(curr_exec_type->asm_name), "",
00416                     curr_exec_type->slot_count);
00417 
00418     unsigned long long slot_mask = 0;
00419     unsigned int stop_mask = 0;
00420     fprintf (cfile, "\n    {");
00421     for (i = 0; i < curr_exec_type->slot_count; i++) {
00422       unsigned int flag_value = 1 << curr_exec_type->slot[i]->bit_position;
00423       int shift_count = max_slots - i - 1;
00424       slot_mask |= ((unsigned long long)flag_value << (TAG_SHIFT * shift_count));
00425       stop_mask |= (curr_exec_type->stop_bit[i] << shift_count);
00426       fprintf (cfile, " %2d /* %7s */,", 
00427                       flag_value,
00428                       curr_exec_type->slot[i]->name);
00429     }
00430     fprintf (cfile, " },");
00431 
00432     fprintf (cfile, "\n    {");
00433     for (i = 0; i < max_slots; i++) {
00434       fprintf (cfile, " %5s,", curr_exec_type->stop_bit[i] ? "TRUE" : "FALSE");
00435     }
00436     fprintf (cfile, " },");
00437 
00438     fprintf (cfile, "\n    {");
00439     for (i = 0; i < curr_exec_type->slot_count; i++) {
00440       ISA_EXEC_UNIT_TYPE unit_type = curr_exec_type->slot[i];
00441       if (unit_type->base_unit) unit_type = unit_type->base_unit;
00442       fprintf (cfile, " ISA_EXEC_%5s,", unit_type->name);
00443     }
00444     fprintf (cfile, " },");
00445 
00446     fprintf(cfile, "\n    %2d,", curr_exec_type->pack_code);
00447     fprintf(cfile, " 0x%1x,", stop_mask);
00448     fprintf(cfile, " 0x%0*llx\n  },\n", slot_mask_digits, slot_mask);
00449   }
00450   fprintf (cfile, "  {\n    \"template_MAX\", \"\", -1,\n    { -1 /* ??????? */");
00451   for (i = 1; i < max_slots; ++i) fprintf (cfile, ", -1 /* ??????? */");
00452   fprintf (cfile, ",},\n    { FALSE");
00453   for (i = 1; i < max_slots; ++i) fprintf (cfile, ", FALSE");
00454   fprintf (cfile, ",},\n    -1, 0x0, 0x%0*x\n  }\n};\n", slot_mask_digits, 0);
00455 
00456   fprintf(hfile,"\n#define ISA_MAX_BUNDLES %d\n",num_bundles);
00457 
00458   fprintf (efile, "ISA_EXEC_unit_prop\n");
00459   fprintf (cfile, "\nconst ISA_EXEC_UNIT_PROPERTY ISA_EXEC_unit_prop[%d] = {\n",
00460           TOP_count);
00461 
00462   for (int top = 0; top < TOP_count; ++top) {
00463     unsigned long long flag_value = 0;
00464 
00465     for (iei = all_exec_types.begin(); iei != all_exec_types.end(); ++iei) {
00466       ISA_EXEC_UNIT_TYPE exec_type = *iei;
00467       if (exec_type->members[top]) 
00468         flag_value |= (1ULL << exec_type->bit_position);
00469     }
00470     fprintf(cfile,      isa_exec_type_format,
00471                         flag_value,
00472                         TOP_Name((TOP)top));
00473     for ( iei = all_exec_types.begin(); iei != all_exec_types.end(); ++iei ) {
00474       ISA_EXEC_UNIT_TYPE exec_type = *iei;
00475       if (exec_type->members[top]) 
00476         fprintf (cfile, " %s", exec_type->name);
00477     }
00478     fprintf (cfile, " */\n");
00479   }
00480   fprintf(cfile, "};\n");
00481 
00482   fprintf(hfile, "\nextern const ISA_EXEC_UNIT_PROPERTY ISA_EXEC_unit_prop[];\n");
00483   fprintf(hfile, "\n");
00484   for (iei = all_exec_types.begin(); iei != all_exec_types.end(); ++iei) {
00485     ISA_EXEC_UNIT_TYPE exec_type = *iei;
00486     fprintf(hfile,
00487              "#define EXEC_PROPERTY_is_%s(t)\t (ISA_EXEC_unit_prop[(INT)t] & ISA_EXEC_PROPERTY_%s)\n",
00488              exec_type->name, exec_type->name);
00489   }
00490 
00491   fprintf (hfile, "\ninline ISA_EXEC_UNIT_PROPERTY "
00492                    "ISA_EXEC_Unit_Prop(TOP topcode)\n"
00493                  "{\n"
00494                  "  return ISA_EXEC_unit_prop[(INT)topcode];\n"
00495                  "}\n");
00496                    
00497   fprintf (hfile, "\ninline ISA_BUNDLE_INFO "
00498                    "ISA_EXEC_Bundle_Info(INT index)\n"
00499                  "{\n"
00500                  "  extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00501                  "  return ISA_BUNDLE_info[index];\n"
00502                  "}\n");
00503                    
00504   fprintf (hfile, "\ninline ISA_EXEC_UNIT_PROPERTY "
00505                    "ISA_EXEC_Slot_Prop(INT bundle, INT slot_index)\n"
00506                  "{\n"
00507                  "  extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00508                  "  const ISA_BUNDLE_INFO *info = ISA_BUNDLE_info + bundle;\n"
00509                  "  return info->slot[slot_index];\n"
00510                  "}\n");
00511 
00512   fprintf (hfile, "\ninline UINT64 "
00513                    "ISA_EXEC_Slot_Mask(INT bundle)\n"
00514                  "{\n"
00515                  "  extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00516                  "  const ISA_BUNDLE_INFO *info = ISA_BUNDLE_info + bundle;\n"
00517                  "  return info->slot_mask;\n"
00518                  "}\n");
00519 
00520   fprintf (hfile, "\ninline BOOL "
00521                    "ISA_EXEC_Stop(INT bundle, INT slot_index)\n"
00522                  "{\n"
00523                  "  extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00524                  "  const ISA_BUNDLE_INFO *info = ISA_BUNDLE_info + bundle;\n"
00525                  "  return info->stop[slot_index];\n"
00526                  "}\n");
00527 
00528   fprintf (hfile, "\ninline ISA_EXEC_UNIT "
00529                    "ISA_EXEC_Unit(INT bundle, INT slot_index)\n"
00530                  "{\n"
00531                  "  extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00532                  "  const ISA_BUNDLE_INFO *info = ISA_BUNDLE_info + bundle;\n"
00533                  "  return (ISA_EXEC_UNIT)info->unit[slot_index];\n"
00534                  "}\n");
00535 
00536   fprintf (hfile, "\ninline UINT32 "
00537                    "ISA_EXEC_Stop_Mask(INT bundle)\n"
00538                  "{\n"
00539                  "  extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00540                  "  const ISA_BUNDLE_INFO *info = ISA_BUNDLE_info + bundle;\n"
00541                  "  return info->stop_mask;\n"
00542                  "}\n");
00543 
00544   fprintf (hfile, "\ninline const char * "
00545                    "ISA_EXEC_Name(INT bundle)\n"
00546                  "{\n"
00547                  "  extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00548                  "  const ISA_BUNDLE_INFO *info = ISA_BUNDLE_info + bundle;\n"
00549                  "  return info->name;\n"
00550                  "}\n");
00551 
00552   fprintf (hfile, "\ninline const char * "
00553                    "ISA_EXEC_AsmName(INT bundle)\n"
00554                  "{\n"
00555                  "  extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00556                  "  const ISA_BUNDLE_INFO *info = ISA_BUNDLE_info + bundle;\n"
00557                  "  return info->asm_name;\n"
00558                  "}\n");
00559 }
00560 
00561 /* ====================================================================
00562  *
00563  * This section handles bundle packing
00564  *
00565  * ====================================================================
00566  */
00567 
00568 // deleting ending ',' after 2
00569 typedef enum {
00570   END           = 0,            // end of list marker
00571   FTEMPLATE     = 1,            // template
00572   FSLOT         = 2             // slot+n => slot n
00573 } PACK_COMP_TYPE;
00574 
00575 #define MAX_PACK_COMPS (FSLOT+MAX_SLOTS)
00576 
00577 static const char * const pack_comp_type_name[] = {
00578   "END",
00579   "TEMPLATE",
00580   "SLOT0",
00581   "SLOT1",
00582   "SLOT2",
00583 };
00584 
00585 static const char * const pack_comp_name[] = {
00586   "ISA_BUNDLE_PACK_COMP_end",
00587   "ISA_BUNDLE_PACK_COMP_template",
00588   "ISA_BUNDLE_PACK_COMP_slot+0",
00589   "ISA_BUNDLE_PACK_COMP_slot+1",
00590   "ISA_BUNDLE_PACK_COMP_slot+2",
00591 };
00592 
00593 typedef struct {
00594   int comp_pos;
00595   int bundle_pos;
00596   int width;
00597 } BUNDLE_FIELD;
00598 
00599 typedef struct {
00600   ISA_BUNDLE_PACK_ENDIAN endian;
00601   BUNDLE_FIELD ftemplate;
00602   BUNDLE_FIELD fslot[MAX_SLOTS];
00603 } BUNDLE_PACK_INFO;
00604 
00605 static BUNDLE_PACK_INFO *bundle_pack_info = NULL;
00606 
00608 void ISA_Bundle_Pack_Create (ISA_BUNDLE_PACK_ENDIAN endian)
00610 //  See interface description.
00612 {
00613   if (bundle_pack_info) {
00614     fprintf(stderr, "### Error: ISA_Bundle_Pack_Create called multiple times\n");
00615     exit(EXIT_FAILURE);
00616   }
00617 
00618   bundle_pack_info = new(BUNDLE_PACK_INFO);
00619   bzero(bundle_pack_info, sizeof(*bundle_pack_info));
00620   bundle_pack_info->endian = endian;
00621 }
00622 
00624 void Pack_Template (int comp_pos, int bundle_pos, int width)
00626 //  See interface description.
00628 {
00629   if (bundle_pack_info == NULL) {
00630     fprintf(stderr, "### Error: Missing call to ISA_Bundle_Pack_Create\n");
00631     exit(EXIT_FAILURE);
00632   }
00633   if (bundle_pos + width > bundle_bits) {
00634     fprintf(stderr, "### Error: field exceeds bundle boundaries\n");
00635     exit(EXIT_FAILURE);
00636   }
00637 
00638   bundle_pack_info->ftemplate.comp_pos = comp_pos;
00639   bundle_pack_info->ftemplate.bundle_pos = bundle_pos;
00640   bundle_pack_info->ftemplate.width = width;
00641 }
00642 
00644 void Pack_Slot (int slot, int comp_pos, int bundle_pos, int width)
00646 //  See interface description.
00648 {
00649   if (bundle_pack_info == NULL) {
00650     fprintf(stderr, "### Error: Missing call to ISA_Bundle_Pack_Create\n");
00651     exit(EXIT_FAILURE);
00652   }
00653   if (slot >= MAX_SLOTS) {
00654     fprintf(stderr, "### Error: slot (%d) exceeds %d\n", slot, MAX_SLOTS);
00655     exit(EXIT_FAILURE);
00656   }
00657   if (bundle_pos + width > bundle_bits) {
00658     fprintf(stderr, "### Error: field exceeds bundle boundaries\n");
00659     exit(EXIT_FAILURE);
00660   }
00661 
00662   bundle_pack_info->fslot[slot].comp_pos = comp_pos;
00663   bundle_pack_info->fslot[slot].bundle_pos = bundle_pos;
00664   bundle_pack_info->fslot[slot].width = width;
00665 }
00666 
00668 static unsigned long long Mask64(int width)
00670 //  Return a bit-mask of size <width>.
00672 {
00673   if ((unsigned)width > 64U) {
00674     fprintf(stderr, "### Error: field width (%d) exceeds 64\n", width);
00675     exit(EXIT_FAILURE);
00676   } else if (width == 64) {
00677     return -1ULL;
00678   }
00679   return (1ULL << width) - 1;
00680 }
00681 
00683 static ISA_BUNDLE_PACK_ENDIAN Host_Endian(void)
00685 //  Return the endian-ness of the host machine.
00687 {
00688   int i = 0x12;
00689   int lowbyte = *(char *)&i;
00690   assert(sizeof(int) > sizeof(char));
00691   return (lowbyte == 0x12) ? ISA_Bundle_Pack_Little_Endian
00692                            : ISA_Bundle_Pack_Big_Endian;
00693 }
00694 
00696 static void Emit_Pack_Component(
00697   FILE *cfile,
00698   BUNDLE_FIELD *field,
00699   int comp,
00700   int *first_comps,
00701   int *pack_index)
00703 //  Emit the packing info for a component. A single source specification
00704 //  may result in multiple packing info entries depending on endian
00705 //  specification and word boundary crossings.
00707 {
00708   if (first_comps[comp] < 0) first_comps[comp] = *pack_index;
00709 
00710   if (comp == END) {
00711     fprintf (cfile, "  { %-30s, %2d, %2d, %2d,   %16lld },  /* %s */\n",
00712                     pack_comp_name[comp],
00713                     -1,
00714                     -1,
00715                     -1, 
00716                     -1LL,
00717                     pack_comp_type_name[comp]);
00718     ++*pack_index;
00719   } else {
00720     bool wrong_endian = (bundle_pack_info->endian != Host_Endian());
00721     int incr;
00722     int flip_mask;
00723     int comp_pos = field->comp_pos;
00724     int bundle_pos = field->bundle_pos;
00725     int width = field->width;
00726     int word_size = bundle_bits >= 64 ? 64 : (bundle_bits + 7) & ~7;
00727     if (wrong_endian) {
00728       incr = 8;
00729       flip_mask = (word_size - 1) & 070;
00730     } else {
00731       incr = word_size;
00732       flip_mask = 0;
00733     }
00734     do {
00735       int bundle_word_pos = (bundle_pos % word_size) ^ flip_mask;
00736       int index = bundle_pos / word_size;
00737       int b = bundle_pos % incr;
00738       int w = width;
00739       if (b + width > incr) w = incr - b;
00740       fprintf (cfile, "  { %-30s, %2d, %2d, %2d, 0x%016llx },  /* %s */\n",
00741                       pack_comp_name[comp],
00742                       index,
00743                       comp_pos,
00744                       bundle_word_pos,
00745                       Mask64(w) << bundle_word_pos,
00746                       pack_comp_type_name[comp]);
00747       ++*pack_index;
00748       bundle_pos += w;
00749       comp_pos += w;
00750       width -= w;
00751     } while (width != 0);
00752   }
00753 }
00754 
00756 static void Emit_Bundle_Packing(FILE *hfile, FILE *cfile, FILE *efile)
00758 //  Emit the bundle packing interface.
00760 {
00761   int i;
00762   int first_comps[MAX_PACK_COMPS];
00763   int max_pack_comps = FSLOT + max_slots;
00764   int word_size = bundle_bits >= 64 ? 64 : (bundle_bits + 7) & ~7;
00765   int pack_index = 0;
00766 
00767   if (bundle_pack_info == NULL) {
00768     fprintf(stderr, "### Error: no bundle packing specification!\n");
00769     exit(EXIT_FAILURE);
00770   }
00771 
00772   for (i = 0; i < MAX_PACK_COMPS; ++i) first_comps[i] = -1;
00773 
00774   fprintf(hfile, "\ntypedef struct {\n"
00775                  "  mUINT%d word[%d];\n"
00776                  "} ISA_BUNDLE;\n",
00777                  word_size, bundle_bits / word_size);
00778 
00779   fprintf(hfile, "\ntypedef enum {\n"
00780         "  %-30s = %d,  /* %s */\n"
00781         "  %-30s = %d,  /* %s */\n"
00782         "  %-30s = %d,  /* %s */\n"
00783         "  %-30s = %d   /* %s */\n"
00784         "} ISA_BUNDLE_PACK_COMP;\n",
00785         "ISA_BUNDLE_PACK_COMP_end", END, "End of list marker",
00786         "ISA_BUNDLE_PACK_COMP_template", FTEMPLATE, "Template",
00787         "ISA_BUNDLE_PACK_COMP_slot", FSLOT, "SLOT+n => slot n",
00788         "ISA_BUNDLE_PACK_COMP_MAX", max_pack_comps-1, "Last component");
00789 
00790   fprintf(hfile, "\ntypedef struct {\n"
00791                 "  mUINT8 comp;\n"
00792                 "  mUINT8 index;\n"
00793                 "  mUINT8 comp_pos;\n"
00794                 "  mUINT8 bundle_pos;\n"
00795                 "  UINT64 mask;\n" 
00796                 "} ISA_BUNDLE_PACK_INFO;\n");
00797 
00798   fprintf(efile, "ISA_BUNDLE_pack_info\n");
00799 
00800   fprintf(cfile, "\nconst ISA_BUNDLE_PACK_INFO ISA_BUNDLE_pack_info[] = {\n");
00801   pack_index = 0;
00802   if (bundle_pack_info->ftemplate.width != 0) {
00803     Emit_Pack_Component(cfile,
00804                         &bundle_pack_info->ftemplate,
00805                         FTEMPLATE,
00806                         first_comps,
00807                         &pack_index);
00808 
00809   }
00810   for (i = 0; i < max_slots; ++i) {
00811     Emit_Pack_Component(cfile,
00812                         &bundle_pack_info->fslot[i],
00813                         FSLOT+i,
00814                         first_comps,
00815                         &pack_index);
00816   }
00817   Emit_Pack_Component(cfile,
00818                       NULL,
00819                       END,
00820                       first_comps,
00821                       &pack_index);
00822 
00823   fprintf (cfile, "};\n");
00824 
00825   fprintf(hfile, "\ninline const ISA_BUNDLE_PACK_INFO *ISA_BUNDLE_Pack_Info(void)\n"
00826                  "{\n"
00827                  "  extern const ISA_BUNDLE_PACK_INFO ISA_BUNDLE_pack_info[];\n"
00828                  "  return ISA_BUNDLE_pack_info;\n"
00829                  "}\n");
00830 
00831   fprintf(hfile, "\ninline INT ISA_BUNDLE_PACK_INFO_Comp(const ISA_BUNDLE_PACK_INFO *info)\n"
00832                  "{\n"
00833                  "  return info->comp;\n"
00834                  "}\n");
00835 
00836   fprintf(hfile, "\ninline INT ISA_BUNDLE_PACK_INFO_Index(const ISA_BUNDLE_PACK_INFO *info)\n"
00837                  "{\n"
00838                  "  return info->index;\n"
00839                  "}\n");
00840 
00841   fprintf(hfile, "\ninline INT ISA_BUNDLE_PACK_INFO_CompPos(const ISA_BUNDLE_PACK_INFO *info)\n"
00842                  "{\n"
00843                  "  return info->comp_pos;\n"
00844                  "}\n");
00845 
00846   fprintf(hfile, "\ninline INT ISA_BUNDLE_PACK_INFO_BundlePos(const ISA_BUNDLE_PACK_INFO *info)\n"
00847                  "{\n"
00848                  "  return info->bundle_pos;\n"
00849                  "}\n");
00850 
00851   fprintf(hfile, "\ninline UINT64 ISA_BUNDLE_PACK_INFO_Mask(const ISA_BUNDLE_PACK_INFO *info)\n"
00852                  "{\n"
00853                  "  return info->mask;\n"
00854                  "}\n");
00855 
00856   fprintf(efile, "ISA_BUNDLE_pack_info_index\n");
00857 
00858   fprintf(cfile, "\nconst mUINT8 ISA_BUNDLE_pack_info_index[%d] = {\n",
00859                  MAX_PACK_COMPS);
00860   for (i = 0; i < MAX_PACK_COMPS; ++i) {
00861     int index = first_comps[i];
00862     if (index < 0) index = first_comps[END];
00863     fprintf(cfile, "  %2d, /* %s */\n", index, pack_comp_name[i]);
00864   }
00865   fprintf(cfile, "};\n");
00866 
00867   fprintf(hfile, "\ninline INT ISA_BUNDLE_Pack_Info_Index(ISA_BUNDLE_PACK_COMP comp)\n"
00868                  "{\n"
00869                  "  extern const mUINT8 ISA_BUNDLE_pack_info_index[%d];\n"
00870                  "  return ISA_BUNDLE_pack_info_index[(INT)comp];\n"
00871                  "}\n",
00872                  MAX_PACK_COMPS);
00873 }
00874 
00875 /* ====================================================================
00876  *
00877  * This section handles the common interfaces
00878  *
00879  * ====================================================================
00880  */
00881 
00883 void ISA_Bundle_Begin( const char* /* name */, int bundle_width )
00885 //  See interface description.
00887 {
00888   bundle_bits = bundle_width;
00889 }
00890 
00892 void ISA_Bundle_End(void)
00894 //  See interface description.
00896 {
00897 
00898 #define FNAME "targ_isa_bundle"
00899   char buf[1000];
00900   sprintf (buf, "%s.h", FNAME);
00901   FILE* hfile = fopen(buf, "w");
00902   sprintf (buf, "%s.c", FNAME);
00903   FILE* cfile = fopen(buf, "w");
00904   sprintf (buf, "%s.Exported", FNAME);
00905   FILE* efile = fopen(buf, "w");
00906 
00907   fprintf(hfile, "#include \"topcode.h\"\n");
00908   fprintf(cfile,"#include \"%s.h\"\n\n", FNAME);
00909 
00910   sprintf (buf, "%s", FNAME);
00911   Emit_Header (hfile, buf, interface);
00912 
00913   Emit_Bundle_Scheduling(hfile, cfile, efile);
00914   fprintf(hfile, "\f");
00915   fprintf(cfile, "\f");
00916   Emit_Bundle_Packing(hfile, cfile, efile);
00917                    
00918   Emit_Footer (hfile);
00919 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines