00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00042
00043
00044
00045
00047
00048
00049
00050
00051
00052 #include <alloca.h>
00053 #include <stddef.h>
00054 #include <stdlib.h>
00055 #include <stdarg.h>
00056 #include <stdio.h>
00057 #include <assert.h>
00058 #include <strings.h>
00059 #include <list>
00060 #include <vector>
00061 #include "topcode.h"
00062 #include "targ_isa_properties.h"
00063 #include "gen_util.h"
00064 #include "isa_bundle_gen.h"
00065 #include "bstring.h"
00066
00067 #define MAX_SLOTS 3 // max # of slots the generator can handle
00068 #define TAG_SHIFT 12 // max # of bits required to encode all the
00069
00070
00071 struct isa_exec_unit_type {
00072 const char *name;
00073 int bit_position;
00074 std::vector<bool> members;
00075 ISA_EXEC_UNIT_TYPE base_unit;
00076 };
00077
00078 struct isa_bundle_type {
00079 const char *name;
00080 const char *asm_name;
00081 int slot_count;
00082 ISA_EXEC_UNIT_TYPE slot[MAX_SLOTS];
00083 bool stop_bit[MAX_SLOTS];
00084 unsigned int pack_code;
00085 };
00086
00087 static int isa_exec_property_count = 0;
00088
00089 static int num_bundles = 0;
00090
00091
00092
00093
00094
00095
00096
00097 static int max_slots = 1;
00098 static int bundle_bits;
00099 static std::list<ISA_EXEC_UNIT_TYPE> all_exec_types;
00100 static std::list<ISA_BUNDLE_TYPE> all_bundles;
00101 static ISA_EXEC_UNIT_TYPE current_exec_type_desc;
00102 static ISA_BUNDLE_TYPE current_bundle_desc;
00103
00104 static const char * const interface[] = {
00105 "/* ====================================================================",
00106 " * ====================================================================",
00107 " *",
00108 " * Description:",
00109 " *",
00110 " * A description of the bundling properties. The interface is",
00111 " * divided into two pieces: scheduling, and packing. The scheduling",
00112 " * interface exports the following:",
00113 " *",
00114 " * const INT ISA_MAX_SLOTS",
00115 " * An integer constant that indicates the maximum number of",
00116 " * slots in a bundle.",
00117 " *",
00118 " * const INT ISA_TAG_SHIFT",
00119 " * Maximum number of bits required to encode all the execution",
00120 " * property types.",
00121 " *",
00122 " * typedef mUINTxx ISA_EXEC_UNIT_PROPERTY",
00123 " * A single-bit mask of representing an execution unit.",
00124 " *",
00125 " * The names have the form ISA_EXEC_PROPERTY_xxx",
00126 " * where 'xxx' is replaced with the EXEC_UNIT_PROPERTY name.",
00127 " *",
00128 " * typedef (enum) ISA_EXEC_UNIT",
00129 " * An enumeration of the execution units.",
00130 " *",
00131 " * The names have the form ISA_EXEC_xxx",
00132 " * where 'xxx' is replaced with the EXEC_UNIT_PROPERTY name.",
00133 " *",
00134 " * The values of ISA_EXEC_UNIT and ISA_EXEC_UNIT_PROPERTY are",
00135 " * related in that the bit-mask value of an ISA_EXEC_UNIT_PROPERTY",
00136 " * is equal to 2**ISA_EXEC_UNIT.",
00137 " *",
00138 " * const INT ISA_EXEC_MAX",
00139 " * The highest value ISA_EXEC_UNIT value.",
00140 " *",
00141 " * BOOL ISA_EXEC_PROPERTY_is_xxx(TOP t) ",
00142 " * Returns TRUE if EXEC_PROPERTY_is_xxx matches <t>'s property.",
00143 " *",
00144 " * ISA_EXEC_UNIT_PROPERTY ISA_EXEC_Unit_Prop(TOP topcode)",
00145 " * Returns exec_unit_property for the instruction specified",
00146 " * by <topcode>.",
00147 " *",
00148 " * ISA_BUNDLE_INFO ISA_EXEC_Bundle_Info(INT index)",
00149 " * Return isa_bundle_info specified by <index>. ",
00150 " *",
00151 " * ISA_EXEC_UNIT_PROPERTY ISA_EXEC_Slot_Prop(INT bundle, INT slot_index)",
00152 " * Return exec_unit_property for the slot position <slot_index>",
00153 " * in <bundle>.",
00154 " *",
00155 " * UINT64 ISA_EXEC_Slot_Mask(INT bundle)",
00156 " * Return slot_mask for <bundle>.",
00157 " *",
00158 " * BOOL ISA_EXEC_Stop(INT bundle, INT slot_index)",
00159 " * Return stop bit for the slot position <slot_index> in <bundle>.",
00160 " *",
00161 " * ISA_EXEC_UNIT ISA_EXEC_Unit(INT bundle, INT slot_index)",
00162 " * Return the execution unit slot position <slot_index> in <bundle>.",
00163 " *",
00164 " * UINT32 ISA_EXEC_Stop_Mask(INT bundle)",
00165 " * Return stop_mask for <bundle>.",
00166 " *",
00167 " * const char *ISA_EXEC_Name(INT bundle)",
00168 " * Return the name for <bundle>.",
00169 " *",
00170 " * const char *ISA_EXEC_AsmName(INT bundle)",
00171 " * Return the assembly language name for <bundle>.",
00172 " *",
00173 " * ====================================================================",
00174 " *",
00175 " * The packing interface exports the following:",
00176 " *",
00177 " * typedef ISA_BUNDLE",
00178 " * A type large enough to hold a bundle. This type will always",
00179 " * be a struct containing an array of either 32-, or 64-bit",
00180 " * unsigned integers.",
00181 " *",
00182 " * typedef (enum) ISA_BUNDLE_PACK_COMP",
00183 " * An enumeration of the bundle components to be packed.",
00184 " *",
00185 " * const INT ISA_BUNDLE_PACK_COMP_MAX",
00186 " * The maximum number of components to be packed for a bundle.",
00187 " *",
00188 " * typedef (struct) ISA_BUNDLE_PACK_INFO",
00189 " * Describes how a the components of a bundle are packed.",
00190 " * The contents are private.",
00191 " *",
00192 " * const ISA_BUNDLE_PACK_INFO *ISA_BUNDLE_Pack_Info(void)",
00193 " * Returns a pointer to the first packing component.",
00194 " * Increment the returned pointer to access any additional packing",
00195 " * components for the bundle. A component of ISA_PACK_COMP_end",
00196 " * marks the end.",
00197 " *",
00198 " * INT ISA_BUNDLE_PACK_INFO_Comp(const ISA_BUNDLE_PACK_INFO *info)",
00199 " * Identifies the bundle component to be packed.",
00200 " *",
00201 " * INT ISA_BUNDLE_PACK_INFO_Index(const ISA_BUNDLE_PACK_INFO *info)",
00202 " * The index of the bundle word containing the component.",
00203 " *",
00204 " * ISA_BUNDLE_PACK_INFO_Index is meaningless for ISA_BUNDLE_PACK_COMP_end.",
00205 " *",
00206 " * INT ISA_BUNDLE_PACK_INFO_CompPos(const ISA_BUNDLE_PACK_INFO *info)",
00207 " * The offset, in bits, to the start of the component in the",
00208 " * component value.",
00209 " *",
00210 " * ISA_BUNDLE_PACK_INFO_CompPos is meaningless for ISA_BUNDLE_PACK_COMP_end.",
00211 " *",
00212 " * INT ISA_BUNDLE_PACK_INFO_BundlePos(const ISA_BUNDLE_PACK_INFO *info)",
00213 " * The offset, in bits, to the start of the component in the",
00214 " * bundle word.",
00215 " *",
00216 " * ISA_BUNDLE_PACK_INFO_BundlePos is meaningless for ISA_BUNDLE_PACK_COMP_end.",
00217 " *",
00218 " * UINT64 ISA_BUNDLE_PACK_INFO_Mask(const ISA_BUNDLE_PACK_INFO *info)",
00219 " * A bit mask that is as wide as the bundle component being",
00220 " * packed. The mask is shifted to match the field in the",
00221 " * bundle word.",
00222 " *",
00223 " * ISA_BUNDLE_PACK_INFO_Mask is meaningless for ISA_BUNDLE_PACK_COMP_end.",
00224 " *",
00225 " * INT ISA_BUNDLE_Pack_Info_Index(ISA_BUNDLE_PACK_COMP comp)",
00226 " * Index into bundle packing info array (see ISA_BUNDLE_Pack_Info)",
00227 " * to the start of the info for the component <comp>. If there",
00228 " * is no packing info for <comp>, the index is for the 'end'",
00229 " * component.",
00230 " *",
00231 " * ====================================================================",
00232 " * ====================================================================",
00233 " */",
00234 NULL
00235 };
00236
00237
00238
00239
00240
00241
00242
00243
00245 ISA_EXEC_UNIT_TYPE ISA_Exec_Unit_Type_Create ( const char* name,
00246 ISA_EXEC_UNIT_TYPE base_unit )
00248
00250 {
00251 ISA_EXEC_UNIT_TYPE cur_type = new isa_exec_unit_type;
00252
00253 cur_type->name = name;
00254 cur_type->bit_position = isa_exec_property_count++;
00255 cur_type->members = std::vector<bool> (TOP_count, false);
00256 cur_type->base_unit = base_unit;
00257
00258 current_exec_type_desc = cur_type;
00259 all_exec_types.push_back (current_exec_type_desc);
00260 return cur_type;
00261 }
00262
00264 void Instruction_Exec_Unit_Group(ISA_EXEC_UNIT_TYPE unit_type, ... )
00266
00268 {
00269 va_list ap;
00270 TOP opcode;
00271
00272 if (!current_exec_type_desc->name) {
00273 fprintf(stderr,"### Error: no execution unit type name specified for %s\n",
00274 current_exec_type_desc->name);
00275 exit(EXIT_FAILURE);
00276 }
00277
00278 va_start(ap, unit_type);
00279 while ( (opcode = static_cast<TOP>(va_arg(ap, int))) != TOP_UNDEFINED) {
00280 unit_type->members[(int)opcode] = true;
00281 }
00282 va_end(ap);
00283 }
00284
00286 void ISA_Bundle_Type_Create (const char* name, const char* asm_name,
00287 int no_slots )
00289
00291 {
00292 int i;
00293 ISA_BUNDLE_TYPE cur_type = new isa_bundle_type;
00294 cur_type->name = name;
00295 cur_type->asm_name = asm_name;
00296 cur_type->slot_count = no_slots;
00297 cur_type->pack_code = num_bundles;
00298 for (i = 0; i < no_slots; ++i) cur_type->stop_bit[i] = false;
00299
00300 current_bundle_desc = cur_type;
00301 all_bundles.push_back (current_bundle_desc);
00302
00303 if (no_slots > max_slots) max_slots = no_slots;
00304 ++num_bundles;
00305 }
00306
00308 void Slot (int slot_index, ISA_EXEC_UNIT_TYPE type)
00310
00312 {
00313 if (slot_index > current_bundle_desc->slot_count) {
00314 fprintf(stderr, "### Error: slot index (%d) exceeds %d\n",
00315 slot_index, current_bundle_desc->slot_count);
00316 exit(EXIT_FAILURE);
00317 }
00318
00319 if (!type) {
00320 fprintf(stderr, "### Error: slot type have non NULL value \n");
00321 exit(EXIT_FAILURE);
00322 }
00323
00324 current_bundle_desc->slot[slot_index] = type;
00325 }
00326
00328 void Stop (int slot_index)
00330
00332 {
00333 if (slot_index > current_bundle_desc->slot_count) {
00334 fprintf(stderr, "### Error: slot index (%d) exceeds %d\n",
00335 slot_index, current_bundle_desc->slot_count);
00336 exit(EXIT_FAILURE);
00337 }
00338
00339 current_bundle_desc->stop_bit[slot_index] = true;
00340 }
00341
00343 static void Emit_Bundle_Scheduling(FILE *hfile, FILE *cfile, FILE *efile)
00345
00347 {
00348 std::list<ISA_EXEC_UNIT_TYPE>::iterator iei;
00349 std::list<ISA_BUNDLE_TYPE>::iterator ibi;
00350 int i;
00351
00352 const char * const isa_exec_type_format = " %3" LL_FORMAT "u, /* %s: ";
00353 const char *info_index_type;
00354
00355 int index = 0;
00356 for (iei = all_exec_types.begin(); iei != all_exec_types.end(); ++index,
00357 ++iei) {
00358 }
00359
00360 char *int_suffix;
00361
00362 if (index <= 8) {
00363 info_index_type = "mUINT8";
00364 int_suffix = "";
00365 } else if (index <= 16) {
00366 info_index_type = "mUINT16";
00367 int_suffix = "";
00368 } else if (index <= 32) {
00369 info_index_type = "mUINT32";
00370 int_suffix = "U";
00371 } else {
00372 assert (index <= 64);
00373 info_index_type = "mUINT64";
00374 int_suffix = "ULL";
00375 }
00376
00377 fprintf (hfile, "\n#define ISA_MAX_SLOTS (%d)\n", max_slots);
00378 fprintf (hfile, "#define ISA_TAG_SHIFT (%d)\n", TAG_SHIFT);
00379
00380 fprintf (hfile, "\ntypedef %s ISA_EXEC_UNIT_PROPERTY;\n",
00381 info_index_type);
00382
00383 fprintf (hfile, "\n");
00384 for (iei = all_exec_types.begin(); iei != all_exec_types.end(); ++iei) {
00385 ISA_EXEC_UNIT_TYPE curr_exec_type = *iei;
00386 fprintf (hfile, "#define ISA_EXEC_PROPERTY_%-15s (0x%" LL_FORMAT "x%s)\n",
00387 curr_exec_type->name,
00388 (1ULL << curr_exec_type->bit_position), int_suffix);
00389 }
00390
00391 fprintf (hfile, "\ntypedef enum {\n");
00392 for (iei = all_exec_types.begin(); iei != all_exec_types.end(); ++iei) {
00393 ISA_EXEC_UNIT_TYPE curr_exec_type = *iei;
00394 fprintf (hfile, " ISA_EXEC_%-15s = %d,\n",
00395 curr_exec_type->name,
00396 curr_exec_type->bit_position);
00397 }
00398 fprintf (hfile, " ISA_EXEC_%-15s = %d\n"
00399 "} ISA_EXEC_UNIT;\n",
00400 "MAX", isa_exec_property_count - 1);
00401
00402 fprintf (hfile, "\ntypedef struct {\n"
00403 " const char *name;\n"
00404 " const char *asm_name;\n"
00405 " int slot_count;\n"
00406 " ISA_EXEC_UNIT_PROPERTY slot[%d];\n"
00407 " mBOOL stop[%d];\n"
00408 " mUINT8 unit[%d];\n"
00409 " mUINT8 pack_code;\n"
00410 " mUINT8 stop_mask;\n"
00411 " mUINT64 slot_mask;\n"
00412 "} ISA_BUNDLE_INFO;\n",
00413 max_slots ? max_slots : 1,
00414 max_slots ? max_slots : 1,
00415 max_slots ? max_slots : 1);
00416
00417 fprintf(efile, "ISA_BUNDLE_info\n");
00418 fprintf(cfile, "\nconst ISA_BUNDLE_INFO ISA_BUNDLE_info[] = {\n");
00419
00420 int slot_mask_digits = ((TAG_SHIFT * max_slots) + 3) / 4;
00421 for (ibi = all_bundles.begin(); ibi != all_bundles.end(); ++ibi) {
00422 ISA_BUNDLE_TYPE curr_exec_type = *ibi;
00423 fprintf (cfile, " {\n \"%s\",%*s \"%s\",%*s %d,",
00424 curr_exec_type->name,
00425 13 - (int)strlen(curr_exec_type->name), "",
00426 curr_exec_type->asm_name,
00427 8 - (int)strlen(curr_exec_type->asm_name), "",
00428 curr_exec_type->slot_count);
00429
00430 unsigned long long slot_mask = 0;
00431 unsigned int stop_mask = 0;
00432 fprintf (cfile, "\n {");
00433 for (i = 0; i < curr_exec_type->slot_count; i++) {
00434 unsigned int flag_value = 1 << curr_exec_type->slot[i]->bit_position;
00435 int shift_count = max_slots - i - 1;
00436 slot_mask |= ((unsigned long long)flag_value << (TAG_SHIFT * shift_count));
00437 stop_mask |= (curr_exec_type->stop_bit[i] << shift_count);
00438 fprintf (cfile, " %2d /* %7s */,",
00439 flag_value,
00440 curr_exec_type->slot[i]->name);
00441 }
00442 fprintf (cfile, " },");
00443
00444 fprintf (cfile, "\n {");
00445 for (i = 0; i < max_slots; i++) {
00446 fprintf (cfile, " %5s,", curr_exec_type->stop_bit[i] ? "TRUE" : "FALSE");
00447 }
00448 fprintf (cfile, " },");
00449
00450 fprintf (cfile, "\n {");
00451 for (i = 0; i < curr_exec_type->slot_count; i++) {
00452 ISA_EXEC_UNIT_TYPE unit_type = curr_exec_type->slot[i];
00453 if (unit_type->base_unit) unit_type = unit_type->base_unit;
00454 fprintf (cfile, " ISA_EXEC_%5s,", unit_type->name);
00455 }
00456 fprintf (cfile, " },");
00457
00458 fprintf(cfile, "\n %2d,", curr_exec_type->pack_code);
00459 fprintf(cfile, " 0x%1x,", stop_mask);
00460 fprintf(cfile, " 0x%0*" LL_FORMAT "x\n },\n", slot_mask_digits, slot_mask);
00461 }
00462 fprintf (cfile, " {\n \"template_MAX\", \"\", -1,\n { -1 /* ??????? */");
00463 for (i = 1; i < max_slots; ++i) fprintf (cfile, ", -1 /* ??????? */");
00464 fprintf (cfile, ",},\n { FALSE");
00465 for (i = 1; i < max_slots; ++i) fprintf (cfile, ", FALSE");
00466 fprintf (cfile, ",},\n -1, 0x0, 0x%0*x\n }\n};\n", slot_mask_digits, 0);
00467
00468 fprintf(hfile,"\n#define ISA_MAX_BUNDLES %d\n",num_bundles);
00469
00470 fprintf (efile, "ISA_EXEC_unit_prop\n");
00471 fprintf (cfile, "\nconst ISA_EXEC_UNIT_PROPERTY ISA_EXEC_unit_prop[%d] = {\n",
00472 TOP_count);
00473
00474 for (int top = 0; top < TOP_count; ++top) {
00475 unsigned long long flag_value = 0;
00476
00477 for (iei = all_exec_types.begin(); iei != all_exec_types.end(); ++iei) {
00478 ISA_EXEC_UNIT_TYPE exec_type = *iei;
00479 if (exec_type->members[top])
00480 flag_value |= (1ULL << exec_type->bit_position);
00481 }
00482 fprintf(cfile, isa_exec_type_format,
00483 flag_value,
00484 TOP_Name((TOP)top));
00485 for ( iei = all_exec_types.begin(); iei != all_exec_types.end(); ++iei ) {
00486 ISA_EXEC_UNIT_TYPE exec_type = *iei;
00487 if (exec_type->members[top])
00488 fprintf (cfile, " %s", exec_type->name);
00489 }
00490 fprintf (cfile, " */\n");
00491 }
00492 fprintf(cfile, "};\n");
00493
00494 fprintf(hfile, "\nextern const ISA_EXEC_UNIT_PROPERTY ISA_EXEC_unit_prop[];\n");
00495 fprintf(hfile, "\n");
00496 for (iei = all_exec_types.begin(); iei != all_exec_types.end(); ++iei) {
00497 ISA_EXEC_UNIT_TYPE exec_type = *iei;
00498 fprintf(hfile,
00499 "#define EXEC_PROPERTY_is_%s(t)\t (ISA_EXEC_unit_prop[(INT)t] & ISA_EXEC_PROPERTY_%s)\n",
00500 exec_type->name, exec_type->name);
00501 }
00502
00503 fprintf (hfile, "\ninline ISA_EXEC_UNIT_PROPERTY "
00504 "ISA_EXEC_Unit_Prop(TOP topcode)\n"
00505 "{\n"
00506 " return ISA_EXEC_unit_prop[(INT)topcode];\n"
00507 "}\n");
00508
00509 fprintf (hfile, "\ninline ISA_BUNDLE_INFO "
00510 "ISA_EXEC_Bundle_Info(INT index)\n"
00511 "{\n"
00512 " extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00513 " return ISA_BUNDLE_info[index];\n"
00514 "}\n");
00515
00516 fprintf (hfile, "\ninline ISA_EXEC_UNIT_PROPERTY "
00517 "ISA_EXEC_Slot_Prop(INT bundle, INT slot_index)\n"
00518 "{\n"
00519 " extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00520 " const ISA_BUNDLE_INFO *info = ISA_BUNDLE_info + bundle;\n"
00521 " return info->slot[slot_index];\n"
00522 "}\n");
00523
00524 fprintf (hfile, "\ninline UINT64 "
00525 "ISA_EXEC_Slot_Mask(INT bundle)\n"
00526 "{\n"
00527 " extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00528 " const ISA_BUNDLE_INFO *info = ISA_BUNDLE_info + bundle;\n"
00529 " return info->slot_mask;\n"
00530 "}\n");
00531
00532 fprintf (hfile, "\ninline BOOL "
00533 "ISA_EXEC_Stop(INT bundle, INT slot_index)\n"
00534 "{\n"
00535 " extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00536 " const ISA_BUNDLE_INFO *info = ISA_BUNDLE_info + bundle;\n"
00537 " return info->stop[slot_index];\n"
00538 "}\n");
00539
00540 fprintf (hfile, "\ninline ISA_EXEC_UNIT "
00541 "ISA_EXEC_Unit(INT bundle, INT slot_index)\n"
00542 "{\n"
00543 " extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00544 " const ISA_BUNDLE_INFO *info = ISA_BUNDLE_info + bundle;\n"
00545 " return (ISA_EXEC_UNIT)info->unit[slot_index];\n"
00546 "}\n");
00547
00548 fprintf (hfile, "\ninline UINT32 "
00549 "ISA_EXEC_Stop_Mask(INT bundle)\n"
00550 "{\n"
00551 " extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00552 " const ISA_BUNDLE_INFO *info = ISA_BUNDLE_info + bundle;\n"
00553 " return info->stop_mask;\n"
00554 "}\n");
00555
00556 fprintf (hfile, "\ninline const char * "
00557 "ISA_EXEC_Name(INT bundle)\n"
00558 "{\n"
00559 " extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00560 " const ISA_BUNDLE_INFO *info = ISA_BUNDLE_info + bundle;\n"
00561 " return info->name;\n"
00562 "}\n");
00563
00564 fprintf (hfile, "\ninline const char * "
00565 "ISA_EXEC_AsmName(INT bundle)\n"
00566 "{\n"
00567 " extern const ISA_BUNDLE_INFO ISA_BUNDLE_info[];\n"
00568 " const ISA_BUNDLE_INFO *info = ISA_BUNDLE_info + bundle;\n"
00569 " return info->asm_name;\n"
00570 "}\n");
00571 }
00572
00573
00574
00575
00576
00577
00578
00579
00580 typedef enum {
00581 END = 0,
00582 FTEMPLATE = 1,
00583 FSLOT = 2,
00584 } PACK_COMP_TYPE;
00585
00586 #define MAX_PACK_COMPS (FSLOT+MAX_SLOTS)
00587
00588 static const char * const pack_comp_type_name[] = {
00589 "END",
00590 "TEMPLATE",
00591 "SLOT0",
00592 "SLOT1",
00593 "SLOT2",
00594 };
00595
00596 static const char * const pack_comp_name[] = {
00597 "ISA_BUNDLE_PACK_COMP_end",
00598 "ISA_BUNDLE_PACK_COMP_template",
00599 "ISA_BUNDLE_PACK_COMP_slot+0",
00600 "ISA_BUNDLE_PACK_COMP_slot+1",
00601 "ISA_BUNDLE_PACK_COMP_slot+2",
00602 };
00603
00604 typedef struct {
00605 int comp_pos;
00606 int bundle_pos;
00607 int width;
00608 } BUNDLE_FIELD;
00609
00610 typedef struct {
00611 ISA_BUNDLE_PACK_ENDIAN endian;
00612 BUNDLE_FIELD ftemplate;
00613 BUNDLE_FIELD fslot[MAX_SLOTS];
00614 } BUNDLE_PACK_INFO;
00615
00616 static BUNDLE_PACK_INFO *bundle_pack_info = NULL;
00617
00619 void ISA_Bundle_Pack_Create (ISA_BUNDLE_PACK_ENDIAN endian)
00621
00623 {
00624 if (bundle_pack_info) {
00625 fprintf(stderr, "### Error: ISA_Bundle_Pack_Create called multiple times\n");
00626 exit(EXIT_FAILURE);
00627 }
00628
00629 bundle_pack_info = new(BUNDLE_PACK_INFO);
00630 BZERO(bundle_pack_info, sizeof(*bundle_pack_info));
00631 bundle_pack_info->endian = endian;
00632 }
00633
00635 void Pack_Template (int comp_pos, int bundle_pos, int width)
00637
00639 {
00640 if (bundle_pack_info == NULL) {
00641 fprintf(stderr, "### Error: Missing call to ISA_Bundle_Pack_Create\n");
00642 exit(EXIT_FAILURE);
00643 }
00644 if (bundle_pos + width > bundle_bits) {
00645 fprintf(stderr, "### Error: field exceeds bundle boundaries\n");
00646 exit(EXIT_FAILURE);
00647 }
00648
00649 bundle_pack_info->ftemplate.comp_pos = comp_pos;
00650 bundle_pack_info->ftemplate.bundle_pos = bundle_pos;
00651 bundle_pack_info->ftemplate.width = width;
00652 }
00653
00655 void Pack_Slot (int slot, int comp_pos, int bundle_pos, int width)
00657
00659 {
00660 if (bundle_pack_info == NULL) {
00661 fprintf(stderr, "### Error: Missing call to ISA_Bundle_Pack_Create\n");
00662 exit(EXIT_FAILURE);
00663 }
00664 if (slot >= MAX_SLOTS) {
00665 fprintf(stderr, "### Error: slot (%d) exceeds %d\n", slot, MAX_SLOTS);
00666 exit(EXIT_FAILURE);
00667 }
00668 if (bundle_pos + width > bundle_bits) {
00669 fprintf(stderr, "### Error: field exceeds bundle boundaries\n");
00670 exit(EXIT_FAILURE);
00671 }
00672
00673 bundle_pack_info->fslot[slot].comp_pos = comp_pos;
00674 bundle_pack_info->fslot[slot].bundle_pos = bundle_pos;
00675 bundle_pack_info->fslot[slot].width = width;
00676 }
00677
00679 static unsigned long long Mask64(int width)
00681
00683 {
00684 if ((unsigned)width > 64U) {
00685 fprintf(stderr, "### Error: field width (%d) exceeds 64\n", width);
00686 exit(EXIT_FAILURE);
00687 } else if (width == 64) {
00688 return -1ULL;
00689 }
00690 return (1ULL << width) - 1;
00691 }
00692
00694 static ISA_BUNDLE_PACK_ENDIAN Host_Endian(void)
00696
00698 {
00699 int i = 0x12;
00700 int lowbyte = *(char *)&i;
00701 assert(sizeof(int) > sizeof(char));
00702 return (lowbyte == 0x12) ? ISA_Bundle_Pack_Little_Endian
00703 : ISA_Bundle_Pack_Big_Endian;
00704 }
00705
00707 static void Emit_Pack_Component(
00708 FILE *cfile,
00709 BUNDLE_FIELD *field,
00710 int comp,
00711 int *first_comps,
00712 int *pack_index)
00714
00715
00716
00718 {
00719 if (first_comps[comp] < 0) first_comps[comp] = *pack_index;
00720
00721 if (comp == END) {
00722 fprintf (cfile, " { %-30s, %2d, %2d, %2d, %16" LL_FORMAT "d }, /* %s */\n",
00723 pack_comp_name[comp],
00724 -1,
00725 -1,
00726 -1,
00727 -1LL,
00728 pack_comp_type_name[comp]);
00729 ++*pack_index;
00730 } else {
00731 bool wrong_endian = (bundle_pack_info->endian != Host_Endian());
00732 int incr;
00733 int flip_mask;
00734 int comp_pos = field->comp_pos;
00735 int bundle_pos = field->bundle_pos;
00736 int width = field->width;
00737 int word_size = bundle_bits >= 64 ? 64 : (bundle_bits + 7) & ~7;
00738 if (wrong_endian) {
00739 incr = 8;
00740 flip_mask = (word_size - 1) & 070;
00741 } else {
00742 incr = word_size;
00743 flip_mask = 0;
00744 }
00745 do {
00746 int bundle_word_pos = (bundle_pos % word_size) ^ flip_mask;
00747 int index = bundle_pos / word_size;
00748 int b = bundle_pos % incr;
00749 int w = width;
00750 if (b + width > incr) w = incr - b;
00751 fprintf (cfile, " { %-30s, %2d, %2d, %2d, 0x%016" LL_FORMAT "x }, /* %s */\n",
00752 pack_comp_name[comp],
00753 index,
00754 comp_pos,
00755 bundle_word_pos,
00756 Mask64(w) << bundle_word_pos,
00757 pack_comp_type_name[comp]);
00758 ++*pack_index;
00759 bundle_pos += w;
00760 comp_pos += w;
00761 width -= w;
00762 } while (width != 0);
00763 }
00764 }
00765
00767 static void Emit_Bundle_Packing(FILE *hfile, FILE *cfile, FILE *efile)
00769
00771 {
00772 int i;
00773 int first_comps[MAX_PACK_COMPS];
00774 int max_pack_comps = FSLOT + max_slots;
00775 int word_size = bundle_bits >= 64 ? 64 : (bundle_bits + 7) & ~7;
00776 int pack_index = 0;
00777
00778 if (bundle_pack_info == NULL) {
00779 fprintf(stderr, "### Error: no bundle packing specification!\n");
00780 exit(EXIT_FAILURE);
00781 }
00782
00783 for (i = 0; i < MAX_PACK_COMPS; ++i) first_comps[i] = -1;
00784
00785 fprintf(hfile, "\ntypedef struct {\n"
00786 " mUINT%d word[%d];\n"
00787 "} ISA_BUNDLE;\n",
00788 word_size, bundle_bits / word_size);
00789
00790 fprintf(hfile, "\ntypedef enum {\n"
00791 " %-30s = %d, /* %s */\n"
00792 " %-30s = %d, /* %s */\n"
00793 " %-30s = %d, /* %s */\n"
00794 " %-30s = %d /* %s */\n"
00795 "} ISA_BUNDLE_PACK_COMP;\n",
00796 "ISA_BUNDLE_PACK_COMP_end", END, "End of list marker",
00797 "ISA_BUNDLE_PACK_COMP_template", FTEMPLATE, "Template",
00798 "ISA_BUNDLE_PACK_COMP_slot", FSLOT, "SLOT+n => slot n",
00799 "ISA_BUNDLE_PACK_COMP_MAX", max_pack_comps-1, "Last component");
00800
00801 fprintf(hfile, "\ntypedef struct {\n"
00802 " mUINT8 comp;\n"
00803 " mUINT8 index;\n"
00804 " mUINT8 comp_pos;\n"
00805 " mUINT8 bundle_pos;\n"
00806 " UINT64 mask;\n"
00807 "} ISA_BUNDLE_PACK_INFO;\n");
00808
00809 fprintf(efile, "ISA_BUNDLE_pack_info\n");
00810
00811 fprintf(cfile, "\nconst ISA_BUNDLE_PACK_INFO ISA_BUNDLE_pack_info[] = {\n");
00812 pack_index = 0;
00813 if (bundle_pack_info->ftemplate.width != 0) {
00814 Emit_Pack_Component(cfile,
00815 &bundle_pack_info->ftemplate,
00816 FTEMPLATE,
00817 first_comps,
00818 &pack_index);
00819
00820 }
00821 for (i = 0; i < max_slots; ++i) {
00822 Emit_Pack_Component(cfile,
00823 &bundle_pack_info->fslot[i],
00824 FSLOT+i,
00825 first_comps,
00826 &pack_index);
00827 }
00828 Emit_Pack_Component(cfile,
00829 NULL,
00830 END,
00831 first_comps,
00832 &pack_index);
00833
00834 fprintf (cfile, "};\n");
00835
00836 fprintf(hfile, "\ninline const ISA_BUNDLE_PACK_INFO *ISA_BUNDLE_Pack_Info(void)\n"
00837 "{\n"
00838 " extern const ISA_BUNDLE_PACK_INFO ISA_BUNDLE_pack_info[];\n"
00839 " return ISA_BUNDLE_pack_info;\n"
00840 "}\n");
00841
00842 fprintf(hfile, "\ninline INT ISA_BUNDLE_PACK_INFO_Comp(const ISA_BUNDLE_PACK_INFO *info)\n"
00843 "{\n"
00844 " return info->comp;\n"
00845 "}\n");
00846
00847 fprintf(hfile, "\ninline INT ISA_BUNDLE_PACK_INFO_Index(const ISA_BUNDLE_PACK_INFO *info)\n"
00848 "{\n"
00849 " return info->index;\n"
00850 "}\n");
00851
00852 fprintf(hfile, "\ninline INT ISA_BUNDLE_PACK_INFO_CompPos(const ISA_BUNDLE_PACK_INFO *info)\n"
00853 "{\n"
00854 " return info->comp_pos;\n"
00855 "}\n");
00856
00857 fprintf(hfile, "\ninline INT ISA_BUNDLE_PACK_INFO_BundlePos(const ISA_BUNDLE_PACK_INFO *info)\n"
00858 "{\n"
00859 " return info->bundle_pos;\n"
00860 "}\n");
00861
00862 fprintf(hfile, "\ninline UINT64 ISA_BUNDLE_PACK_INFO_Mask(const ISA_BUNDLE_PACK_INFO *info)\n"
00863 "{\n"
00864 " return info->mask;\n"
00865 "}\n");
00866
00867 fprintf(efile, "ISA_BUNDLE_pack_info_index\n");
00868
00869 fprintf(cfile, "\nconst mUINT8 ISA_BUNDLE_pack_info_index[%d] = {\n",
00870 MAX_PACK_COMPS);
00871 for (i = 0; i < MAX_PACK_COMPS; ++i) {
00872 int index = first_comps[i];
00873 if (index < 0) index = first_comps[END];
00874 fprintf(cfile, " %2d, /* %s */\n", index, pack_comp_name[i]);
00875 }
00876 fprintf(cfile, "};\n");
00877
00878 fprintf(hfile, "\ninline INT ISA_BUNDLE_Pack_Info_Index(ISA_BUNDLE_PACK_COMP comp)\n"
00879 "{\n"
00880 " extern const mUINT8 ISA_BUNDLE_pack_info_index[%d];\n"
00881 " return ISA_BUNDLE_pack_info_index[(INT)comp];\n"
00882 "}\n",
00883 MAX_PACK_COMPS);
00884 }
00885
00886
00887
00888
00889
00890
00891
00892
00894 void ISA_Bundle_Begin( const char* , int bundle_width )
00896
00898 {
00899 bundle_bits = bundle_width;
00900 }
00901
00903 void ISA_Bundle_End(void)
00905
00907 {
00908
00909 #define FNAME "targ_isa_bundle"
00910 char buf[1000];
00911 sprintf (buf, "%s.h", FNAME);
00912 FILE* hfile = fopen(buf, "w");
00913 sprintf (buf, "%s.c", FNAME);
00914 FILE* cfile = fopen(buf, "w");
00915 sprintf (buf, "%s.Exported", FNAME);
00916 FILE* efile = fopen(buf, "w");
00917
00918 fprintf(hfile, "#include \"topcode.h\"\n");
00919 fprintf(cfile,"#include \"%s.h\"\n\n", FNAME);
00920
00921 sprintf (buf, "%s", FNAME);
00922 Emit_Header (hfile, buf, interface);
00923
00924 Emit_Bundle_Scheduling(hfile, cfile, efile);
00925 fprintf(hfile, "\f");
00926 fprintf(cfile, "\f");
00927 Emit_Bundle_Packing(hfile, cfile, efile);
00928
00929 Emit_Footer (hfile);
00930 }