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