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_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 }