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