Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
isa_print_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_print_gen.cxx
00038 //
00039 //  Generate an interface for printing the instructions in an ISA.
00040 //
00042 //
00043 
00044 #include <cstddef>
00045 #include <cstdlib>
00046 #include <cstdarg>
00047 #include <cstdio>
00048 #include <cassert>
00049 #include <cstring>
00050 
00051 #include <vector>
00052 #include <list>
00053 
00054 using namespace std;
00055 
00056 #include "topcode.h"
00057 #include "targ_isa_properties.h"
00058 #include "gen_util.h"
00059 #include "isa_print_gen.h"
00060 
00061 /* The maximum number of operands and results used by ANY target.
00062  * (It would be better to get the max operands and results from the
00063  * generated targ_isa_operands.h file -- Ken)
00064  */
00065 #define MAX_OPNDS 6
00066 #define MAX_RESULTS 2
00067 
00068 
00069 typedef enum {
00070         END     = 0,                    // end of list marker
00071         NAME    = 1,                    // instruction name/mnemonic
00072         OPND    = 2,                    // OPND+n => operand n
00073         RESULT  = OPND+MAX_OPNDS        // RESULT+n => result n
00074 } COMP_TYPE;
00075 
00076 #define MAX_LISTING_OPERANDS (RESULT+MAX_RESULTS)
00077 
00078 struct isa_print_type {
00079   const char *name;         // Name given for documentation and debugging
00080   const char *format_string; // format string to print this print type
00081 };
00082 
00083 struct list_info {
00084   isa_print_type *type;
00085   unsigned char  args;  // Number of sprintf arguments
00086   unsigned char  arg[MAX_LISTING_OPERANDS]; 
00087   int index;            
00088   bool have_name;
00089 };
00090 
00091 typedef list_info *LISTING_INFO;
00092 
00093 // map to link TOPs_ with list_info properties
00094 struct op_pr {
00095   list_info *desc;
00096   struct op_pr *next;
00097 };
00098 
00099 static list<LISTING_INFO> all_prints;  // all the different print formats
00100 static LISTING_INFO current_print_desc;
00101 static op_pr *op_prints[TOP_count+1];
00102 static list<op_pr*> op_prints_list;
00103 static int list_index;
00104 static const char *(*asmname)(TOP topcode);
00105 static bool top_specified[TOP_count];
00106 
00107 static const char * const interface[] = {
00108   "/* ====================================================================",
00109   " * ====================================================================",
00110   " *",
00111   " * Description:",
00112   " *",
00113   " *   A description of how to print the operands of ISA instructions",
00114   " *   in ascii. The description exports the following:",
00115   " *",
00116   " *   typedef (enum) ISA_PRINT_COMP",
00117   " *       An enumeration of the instruction components to be printed.",
00118   " *",
00119   " *   typedef (struct) ISA_PRINT_INFO",
00120   " *       Describes how one particular instruction is printed.",
00121   " *       The contents are private.",
00122   " *",
00123   " *   const INT ISA_PRINT_COMP_MAX",
00124   " *       The maximum number of components to be printed for any instruction.",
00125   " *",
00126   " *   const ISA_PRINT_INFO *ISA_PRINT_Info(TOP topcode)",
00127   " *       Returns a pointer to the printing description for the",
00128   " *       instruction specified by 'topcode'.",
00129   " *",
00130   " *       The instruction is printed by calling one of the printf routines",
00131   " *       with the format string returned from ISA_PRINT_INFO_Format.",
00132   " *       Additional printf arguments, necessitated by the format string,",
00133   " *       are described by ISA_PRINT_INFO_Comp.",
00134   " *",
00135   " *   INT ISA_PRINT_INFO_Comp(const ISA_PRINT_INFO *info, INT index)",
00136   " *       Identifies a instruction component to be printed.",
00137   " *",
00138   " *       'index' specifies the component. The first component has index",
00139   " *       0; the end of the components is signalled by the return of",
00140   " *       ISA_PRINT_COMP_end.",
00141   " *",
00142   " *   const char *ISA_PRINT_INFO_Format(const ISA_PRINT_INFO *info)",
00143   " *       The printf format string for printing the instruction",
00144   " *       described by 'info'.",
00145   " *",
00146   " *   const char *ISA_PRINT_AsmName(TOP topcode)",
00147   " *       Returns the assembly language name for <topcode>.",
00148   " *",
00149   " *   BOOL ISA_PRINT_Operand_Is_Part_Of_Name(TOP topcode, INT opindex)",
00150   " *       Returns whether the operand is part of the full asm name.",
00151   " *",
00152   " * ====================================================================",
00153   " * ====================================================================",
00154   " */",
00155   NULL
00156 };
00157 
00159 const char* Print_Name(int print_index)
00161 {
00162   static const char *comp_name[MAX_LISTING_OPERANDS];
00163   static bool initialized;
00164 
00165   if (!initialized) {
00166     int i;
00167     for (i = 0; i < MAX_LISTING_OPERANDS; ++i) {
00168       char buf[80];
00169       if (i == END) {
00170         comp_name[i] = "ISA_PRINT_COMP_end";
00171       } else if (i == NAME) {
00172         comp_name[i] = "ISA_PRINT_COMP_name";
00173       } else if (i == OPND) {
00174         comp_name[i] = "ISA_PRINT_COMP_opnd";
00175       } else if (i > OPND && i < (OPND + MAX_OPNDS)) {
00176         sprintf(buf, "ISA_PRINT_COMP_opnd+%d", i - OPND);
00177         comp_name[i] = strdup(buf);
00178       } else if (i == RESULT) {
00179         comp_name[i] = "ISA_PRINT_COMP_result";
00180       } else {
00181         assert(i > RESULT && i < (RESULT + MAX_RESULTS));
00182         sprintf(buf, "ISA_PRINT_COMP_result+%d", i - RESULT);
00183         comp_name[i] = strdup(buf);
00184       }
00185     }
00186     initialized = true;
00187   }
00188 
00189   return comp_name[print_index];
00190 }
00191 
00193 void ISA_Print_Begin( const char* /* name */ )
00195 //  See interface description.
00197 {
00198 }
00199 
00201 ISA_PRINT_TYPE ISA_Print_Type_Create ( 
00202   const char* name, 
00203   const char* format_string)
00205 //  See interface description.
00207 {
00208   LISTING_INFO result = new list_info;
00209   result->type = new isa_print_type;
00210   result->type->name = name;
00211   result->type->format_string = format_string;
00212   result->index = list_index;
00213   result->args = 0;
00214   result->have_name = false;
00215   current_print_desc = result;
00216   all_prints.push_back (current_print_desc);
00217   ++list_index;
00218   return result->type;
00219 }
00220 
00222 void Instruction_Print_Group(ISA_PRINT_TYPE print_type, TOP top, ... )
00224 //  See interface description.
00226 {
00227   va_list ap;
00228   TOP opcode;
00229 
00230   if (!current_print_desc->have_name) {
00231     fprintf(stderr, "### Warning: no instruction name specified for %s\n",
00232                     current_print_desc->type->name);
00233     // exit(EXIT_FAILURE);
00234   }
00235   op_pr *op_print = new op_pr;
00236   op_prints_list.push_back(op_print);
00237   op_print->desc = current_print_desc;
00238   op_prints[(int)top] = op_print;
00239   top_specified[(int)top] = true;
00240 
00241   va_start(ap, top);
00242   while ( (opcode = static_cast<TOP>(va_arg(ap,int))) != TOP_UNDEFINED ) {
00243     op_print = new op_pr;
00244     op_prints_list.push_back(op_print);
00245     op_print->desc = current_print_desc;
00246     op_prints[(int)opcode] = op_print;
00247     top_specified[(int)opcode] = true;
00248   }
00249   va_end(ap);
00250 }
00251 
00253 void Name (void)
00255 //  See interface description.
00257 {
00258   if (current_print_desc->args == MAX_LISTING_OPERANDS) {
00259     fprintf(stderr, "### Error: too many listing operands for %s\n",
00260                     current_print_desc->type->name);
00261     exit(EXIT_FAILURE);
00262   }
00263   current_print_desc->arg[current_print_desc->args] = NAME;
00264   current_print_desc->args++;
00265   current_print_desc->have_name = true;
00266 }
00267 
00269 void Operand (int operand_index)
00271 //  See interface description.
00273 {
00274   if (operand_index >= MAX_OPNDS) {
00275     fprintf(stderr, "### Error: operand index (%d) exceeds %d\n",
00276                     operand_index, MAX_OPNDS-1);
00277     exit(EXIT_FAILURE);
00278   }
00279   if (current_print_desc->args == MAX_LISTING_OPERANDS) {
00280     fprintf(stderr, "### Error: too many listing operands for %s\n",
00281                     current_print_desc->type->name);
00282     exit(EXIT_FAILURE);
00283   }
00284   current_print_desc->arg[current_print_desc->args] = OPND+operand_index;
00285   current_print_desc->args++;
00286 }
00287 
00289 void Result (int result_index)
00291 //  See interface description.
00293 {
00294   if (result_index >= MAX_RESULTS) {
00295     fprintf(stderr, "### Error: result index (%d) exceeds %d\n",
00296                     result_index, MAX_RESULTS-1);
00297     exit(EXIT_FAILURE);
00298   }
00299   if (current_print_desc->args == MAX_LISTING_OPERANDS) {
00300     fprintf(stderr, "### Error: too many listing operands for %s\n",
00301                     current_print_desc->type->name);
00302     exit(EXIT_FAILURE);
00303   }
00304   current_print_desc->arg[current_print_desc->args] = RESULT+result_index;
00305   current_print_desc->args++;
00306 }
00307 
00309 
00310 // try to fix the name resolution problem occuring to functions taking
00311 // function as arguments
00312 
00313 extern "C" { void Set_AsmName_Func(const char *(*asmname_func)(TOP topcode))
00315 //  See interface description.
00317 {
00318   asmname = asmname_func;
00319 }
00320 
00321 }
00323 void ISA_Print_End(void)
00325 //  See interface description.
00327 {
00328   list<LISTING_INFO>::iterator isi;
00329 
00330 #define FNAME "targ_isa_print"
00331   char buf[1000];
00332   sprintf (buf, "%s.h", FNAME);
00333   FILE* hfile = fopen(buf, "w");
00334   sprintf (buf, "%s.c", FNAME);
00335   FILE* cfile = fopen(buf, "w");
00336   sprintf (buf, "%s.Exported", FNAME);
00337   FILE* efile = fopen(buf, "w");
00338   const char comma = ',';
00339   const char space = ' ';
00340   const char * const isa_print_type_format = "\t/* %s[%d] */";
00341   const char * const isa_print_format_format = "  { %-14s ";
00342   const char * const isa_print_args_format = " %s%c";
00343   int top;
00344   bool err;
00345 
00346   for (err = false, top = 0; top < TOP_count; ++top) {
00347     bool is_dummy = TOP_is_dummy((TOP)top);
00348     bool is_simulated = TOP_is_simulated((TOP)top);
00349     if (!top_specified[top]) {
00350       if (!is_simulated && !is_dummy) {
00351         fprintf(stderr, "### Error: no print specification for %s\n",
00352                         TOP_Name((TOP)top));
00353         err = true;
00354       }
00355     } else if (is_dummy) {
00356       fprintf(stderr, "### Error: print specification for dummy op %s\n",
00357                       TOP_Name((TOP)top));
00358       err = true;
00359     } else if (is_simulated) {
00360       fprintf(stderr, "### Error: print specification for simulated op %s\n",
00361                       TOP_Name((TOP)top));
00362       err = true;
00363     }
00364   }
00365   if (err) exit(EXIT_FAILURE);
00366 
00367   fprintf(cfile,"#include <string.h>\n");
00368   fprintf(cfile,"#include \"topcode.h\"\n");
00369   fprintf(cfile,"#include \"%s.h\"\n\n", FNAME);
00370 
00371   sprintf (buf, "%s", FNAME);
00372   Emit_Header (hfile, buf, interface);
00373   fprintf(hfile,"#include \"topcode.h\"\n");
00374 
00375   Emit_Definitions (hfile, "ISA_PRINT_");
00376 
00377   fprintf(hfile, "\ntypedef enum {\n"
00378         "  %-21s = %d,  /* %s */\n"
00379         "  %-21s = %d,  /* %s */\n"
00380         "  %-21s = %d,  /* %s */\n"
00381         "  %-21s = %d,  /* %s */\n"
00382         "  %-21s = %d   /* %s */\n"
00383         "} ISA_PRINT_COMP;\n",
00384         Print_Name(END), END, "End of list marker",
00385         Print_Name(NAME), NAME, "Instruction name",
00386         Print_Name(OPND), OPND, "OPND+n => operand n",
00387         Print_Name(RESULT), RESULT, "RESULT+n => result n",
00388         "ISA_PRINT_COMP_MAX", MAX_LISTING_OPERANDS-1, "Last component");
00389 
00390   fprintf(hfile, "\ntypedef struct {\n"
00391                 "  const char *format;\n"
00392                 "  mUINT8 comp[%d];\n" 
00393                 "} ISA_PRINT_INFO;\n",MAX_LISTING_OPERANDS);
00394 
00395   fprintf(hfile, "\nextern const ISA_PRINT_INFO ISA_PRINT_info[%d];\n",
00396                                                 list_index + 1);
00397 
00398   fprintf(efile, "ISA_PRINT_info\n");
00399 
00400   fprintf(cfile, "\nconst ISA_PRINT_INFO ISA_PRINT_info[%d] = {\n",
00401                                                 list_index + 1);
00402 
00403   fprintf (cfile, isa_print_format_format, "\"\",");
00404   fprintf (cfile, isa_print_args_format, Print_Name(END), space);
00405   fprintf (cfile, "},");
00406   fprintf (cfile, isa_print_type_format, "print_NULL", 0);
00407   fprintf (cfile, "\n");
00408   for ( isi = all_prints.begin(); isi != all_prints.end(); ++isi ) {
00409         LISTING_INFO curr_type = *isi;
00410         sprintf (buf, "\"%s\",", curr_type->type->format_string);
00411         fprintf (cfile, isa_print_format_format, buf);
00412         for (int i = 0; i < curr_type->args; i++) {
00413             fprintf (cfile, isa_print_args_format,
00414                         Print_Name(curr_type->arg[i]),
00415                         comma);
00416             fprintf (cfile, isa_print_type_format, curr_type->type->name, i);
00417             fprintf (cfile, "\n%19s", "");
00418         }
00419         fprintf (cfile, isa_print_args_format, Print_Name(END), space);
00420         fprintf (cfile, "},");
00421         fprintf (cfile, isa_print_type_format, 
00422                         curr_type->type->name,
00423                         curr_type->args);
00424         fprintf (cfile, "\n");
00425   }
00426   fprintf (cfile, "};\n");
00427 
00428   fprintf(hfile, "\nextern const unsigned char ISA_PRINT_info_index[%d];\n", TOP_count);
00429 
00430   fprintf(efile, "ISA_PRINT_info_index\n");
00431 
00432   fprintf(cfile, "\nconst mUINT8 ISA_PRINT_info_index[%d] = {\n", TOP_count);
00433   for (top = 0; top < TOP_count; ++top ) {
00434         op_pr *op_print = op_prints[top];
00435         if (op_print) {
00436             fprintf(cfile, "  %3d,  /* %s: %s */\n", 
00437                         op_print->desc->index+1,
00438                         TOP_Name((TOP)top),
00439                         op_print->desc->type->name);
00440         } else {
00441             fprintf(cfile, "  %3d,  /* %s */\n", 
00442                         0,
00443                         TOP_Name((TOP)top));
00444         }
00445   }
00446   fprintf(cfile, "};\n");
00447 
00448   fprintf(hfile, "\ninline const ISA_PRINT_INFO *ISA_PRINT_Info(TOP topcode)\n"
00449                  "{\n"
00450                  "  INT index = ISA_PRINT_info_index[(INT)topcode];\n"
00451                  "  return index == 0 ? 0 : &ISA_PRINT_info[index];\n"
00452                  "}\n");
00453 
00454   fprintf(hfile, "\ninline const char* ISA_PRINT_INFO_Format(const ISA_PRINT_INFO *info)\n"
00455                  "{\n"
00456                  "  return info->format;\n"
00457                  "}\n");
00458 
00459   fprintf(hfile, "\ninline INT ISA_PRINT_INFO_Comp(const ISA_PRINT_INFO *info, INT index)\n"
00460                  "{\n"
00461                  "  return info->comp[index];\n"
00462                  "}\n");
00463 
00464   if (asmname) {
00465     fprintf(cfile, "\nconst char * const ISA_PRINT_asmname[] = {\n");
00466     for (top = 0; top < TOP_count; ++top) {
00467       fprintf(cfile, "  \"%s\",\n", asmname((TOP)top));
00468     }
00469     fprintf(cfile, "  \"UNDEFINED\"\n"
00470                    "};\n");
00471 
00472     fprintf(hfile, "\ninline const char *ISA_PRINT_AsmName(TOP topcode)\n"
00473                    "{\n"
00474                    "  extern const char * const ISA_PRINT_asmname[];\n"
00475                    "  return ISA_PRINT_asmname[(INT)topcode];\n"
00476                    "}\n");
00477 
00478     fprintf(efile, "ISA_PRINT_asmname\n");
00479   } else {
00480     fprintf(hfile, "\ninline const char *ISA_PRINT_AsmName(TOP topcode)\n"
00481                    "{\n"
00482                    "  return TOP_Name(topcode);\n"
00483                    "}\n");
00484   }
00485 
00486   fprintf(hfile, "\nextern BOOL ISA_PRINT_Operand_Is_Part_Of_Name(TOP topcode, INT opindex);\n");
00487   fprintf(efile, "ISA_PRINT_Operand_Is_Part_Of_Name\n");
00488   fprintf(cfile, "\nBOOL ISA_PRINT_Operand_Is_Part_Of_Name(TOP topcode, INT opindex)\n"
00489                 "{\n"
00490                 "  const ISA_PRINT_INFO *info = ISA_PRINT_Info(topcode);\n"
00491                 "  const char *place_in_format = ISA_PRINT_INFO_Format(info);\n"
00492                 "  BOOL in_name_part = 0;\n"
00493                 "  INT comp;\n"
00494                 "  INT i = 0;\n"
00495                 "  for (;;) {\n"
00496                 "       comp = ISA_PRINT_INFO_Comp(info,i);\n"
00497                 "       if (comp == ISA_PRINT_COMP_end) break;\n"
00498                 "       place_in_format = strchr(place_in_format, '%%');\n"
00499                 "       place_in_format += 2; /* assume %%s */\n"
00500                 "       if (comp == ISA_PRINT_COMP_name) {\n"
00501                 "         if (*place_in_format == '\\0' || *place_in_format == ' ')\n"
00502                 "               in_name_part = 0;\n"
00503                 "         else\n"
00504                 "               in_name_part = 1;\n"
00505                 "       }\n"
00506                 "       if (comp >= ISA_PRINT_COMP_opnd && comp < ISA_PRINT_COMP_result) {\n"
00507                 "         if (in_name_part) {\n"
00508                 "           INT comp_opindex = comp - ISA_PRINT_COMP_opnd;\n"
00509                 "           if (comp_opindex == opindex)\n"
00510                 "               return 1;\n"
00511                 "           if (*place_in_format == '\\0' || *place_in_format == ' ')\n"
00512                 "               in_name_part = 0;\n"
00513                 "         }\n"
00514                 "       }\n"
00515                 "       ++i;\n"
00516                 "  }\n"
00517                 "  return 0;\n"
00518                 "}\n");
00519 
00520   Emit_Footer (hfile);
00521 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines