Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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 }