Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

lmdes.c

Go to the documentation of this file.
00001 /******************************************************************************\
00002  *
00003  *  File:  lmdes.c
00004  *
00005  *  Description:
00006  *    Reads in a low-level mdes file and builds all the necessary
00007  *    structures and arrays.
00008  *
00009  *  Creation Date :  May, 1993
00010  *
00011  *  Authors:  John C. Gyllenhaal, Scott Mahlke
00012  *
00013  *      (C) Copyright 1993, John C. Gyllenhaal, Scott Mahlke
00014  *      All rights granted to University of Illinois Board of Regents.
00015 \******************************************************************************/
00016 #include <malloc.h>
00017 #include <string.h>
00018 #include <stdlib.h>
00019 #include <stdarg.h>
00020 #include "lmdes.h"
00021 #include "l_alloc_new.h"
00022 
00023 
00024 /* Pointer through which the current LMDES is accessed */
00025 Mdes *lmdes;
00026 
00027 /* The version of the lmdes file this routine is expecting */
00028 #define MDES_VERSION 3
00029 
00030 /* Internal functions, do not use externally */
00031 static Mdes *load_lmdes (char *file_name);
00032 void Malloc_struct (void **ptr, int size);
00033 void Malloc_name (char **ptr, char *name);
00034 void M_punt (char *format, ...);
00035 
00036 /* Info structures for structures that can be dynamically allocated */
00037 static L_Alloc_Pool *Mdes_Info_pool = NULL;
00038 static L_Alloc_Pool *Mdes_Compatable_Alt_pool = NULL;
00039 
00040 /*
00041  * Returns 1 if a MDES file has been loaded (L_init_lmdes called)
00042  * returns 0 otherwise.
00043  * Useful for determining if a L_init_lmdes should be called.
00044  */
00045 int lmdes_initialized (void)
00046 {
00047     if (lmdes == NULL)
00048         return (0);
00049     else
00050         return (1);
00051 }
00052 /*
00053  * Returns 1 if opcode is specified in the mdes file.
00054  * Returns 0 if not.
00055  * Useful for gathering stats on all mdes opcodes in a pass.
00056  */
00057 int mdes_defined_opcode (unsigned int opcode)
00058 {
00059     /* See if opcode is in lmdes op_table */
00060     if ((opcode > lmdes->max_opcode) ||
00061         (lmdes->op_table[opcode] == NULL))
00062     {
00063         return (0);
00064     }
00065 
00066     /* Otherwise, legal opcode */
00067     return (1);
00068 }
00069 
00070 /*
00071  * Returns the maximum opcode defined in the mdes file.
00072  */
00073 int mdes_max_opcode (void)
00074 {
00075     return (lmdes->max_opcode);
00076 }
00077    
00078 /*  
00079  * Returns 1 if any of the alt_flags specified by mask are set for the 
00080  * opcode passed.
00081  *
00082  * Returns 0 otherwise.
00083  */
00084 int op_flag_set (unsigned int opcode, int mask)
00085 {
00086     /* Make sure opcode is valid */
00087     if ((opcode > lmdes->max_opcode) ||
00088         (lmdes->op_table[opcode] == NULL))
00089     {
00090             M_punt ("op_flag_set: opcode (%i) not defined in mdes file %s",
00091                     opcode, lmdes->file_name);
00092     }
00093 
00094     if ((lmdes->op_table[opcode]->op_flags & mask) != 0)
00095         return (1);
00096     else
00097         return (0);
00098 }
00099 
00100 /*
00101  * Returns 1 if any of the alt_flags specified by mask are set for the 
00102  * specified alternative.
00103  * 
00104  * Returns 0 otherwise.
00105  */
00106 int alt_flag_set (unsigned int opcode, unsigned int alt_no, int mask)
00107 {
00108     Mdes_Operation *op=NULL;
00109 
00110     /* Make sure valid opcode specified */
00111     if ((opcode > lmdes->max_opcode) ||
00112         ((op = lmdes->op_table[opcode])== NULL))
00113     {
00114             M_punt ("alt_flag_set: opcode (%i) not defined in mdes file %s",
00115                     opcode, lmdes->file_name);
00116     }
00117 
00118     /* Make sure valid alt_no specified */
00119     if (alt_no >= op->num_alts)
00120     {
00121         M_punt ("alt_flag_set: alt (%i) >= number of alts (%i)\n",
00122                 alt_no, op->num_alts);
00123     }
00124 
00125     if ((op->alt[alt_no].alt_flags & mask) != 0)
00126         return (1);
00127     else
00128         return (0);
00129 }
00130 /*  
00131  * Returns 1 if any of the alt_flags specified by mask are set for any 
00132  * of the compatable alternatives for the opcode passed.
00133  * "The compatable alternatives" are those which have the 
00134  * operand types which match the instruction being scheduled.
00135  *
00136  * Returns 0 otherwise.
00137  */
00138 int any_alt_flag_set (Mdes_Info *mdes_info, int mask)
00139 {
00140     Mdes_Compatable_Alt *comp_alt;
00141     
00142     for (comp_alt = mdes_info->compatable_alts; comp_alt != NULL;
00143          comp_alt = comp_alt->next)
00144     {
00145         if ((comp_alt->alt->alt_flags & mask) != 0)
00146         return (1);
00147     }
00148     return (0);
00149 }
00150 
00151 /* 
00152  * Returns the total number of src, dest and pred operands
00153  * Will be made into macro later.
00154  */
00155 int mdes_operand_count(void)
00156 {
00157     return (lmdes->operand_count);
00158 }
00159 
00160 /*
00161  * Returns the total number of src, dest, pred, sync_in, and sync_out
00162  * operands.  Will be made into macro later.
00163  */
00164 int mdes_latency_count(void)
00165 {
00166     return (lmdes->latency_count);
00167 }
00168 
00169 /*
00170  * Returns the number of operands of the specific type there are
00171  */
00172 int mdes_num_operands (unsigned int operand_type)
00173 {
00174     if (lmdes == NULL)
00175         M_punt ("mdes_num_operands: mdes file not loaded");
00176 
00177     if (operand_type > 4)
00178         M_punt ("mdes_num_operands: operand_type %i out of bounds",
00179                 operand_type);
00180 
00181     return (lmdes->number[operand_type]);
00182 }
00183 
00184 /*
00185  * Returns the null operand external id 
00186  */
00187 int mdes_null_operand (void)
00188 {
00189     return (lmdes->null_external_id);
00190 }
00191 
00192 /*
00193  * Given an operand index, it prints out the operand type and
00194  * which operand number to out.
00195  */
00196 void print_mdes_operand_name (FILE *out, Mdes *mdes, unsigned int index)
00197 {
00198     int operand_number;
00199 
00200     if (index >= mdes->latency_count)
00201     {
00202         fprintf (out, "operand index (%i) out of bounds", index);
00203         return;
00204     }
00205     
00206     if (index >= mdes->offset[MDES_SYNC_OUT])
00207     {
00208         operand_number = index - mdes->offset[MDES_SYNC_OUT];
00209         fprintf (out, "MDES_SYNC_OUT[%i]", operand_number);
00210     }
00211     else if (index >= mdes->offset[MDES_SYNC_IN])
00212     {
00213         operand_number = index - mdes->offset[MDES_SYNC_IN];
00214         fprintf (out, "MDES_SYNC_IN[%i]", operand_number);
00215     }
00216     else if (index >= mdes->offset[MDES_SRC])
00217     {
00218         operand_number = index - mdes->offset[MDES_SRC];
00219         fprintf (out, "MDES_SRC[%i]", operand_number);
00220     }
00221     else if (index >= mdes->offset[MDES_DEST])
00222     {
00223         operand_number = index - mdes->offset[MDES_DEST];
00224         fprintf (out, "MDES_DEST[%i]", operand_number);
00225     }
00226     else if (index >= mdes->offset[MDES_PRED])
00227     {
00228         operand_number = index - mdes->offset[MDES_PRED];
00229         fprintf (out, "MDES_PRED[%i]", operand_number);
00230     }
00231     else
00232     {
00233         M_punt ("print_mdes_operand_name: index %i not found",
00234                 index);
00235     }
00236 
00237 }
00238 
00239 /*
00240  * Returns 1 if IO_sets set1 and set2 have at least one bit set
00241  * in common.
00242  * Otherwise, returns 0.
00243  */
00244 static int IO_sets_intersect (Mdes *mdes, Mdes_IO_Set *set1, Mdes_IO_Set *set2)
00245 {
00246     int i;
00247 
00248     for (i=0; i < mdes->IOmask_width; i++)
00249     {
00250         /* Return 1 if this part of the mask has a common bit set */
00251         if ((set1->mask[i] & set2->mask[i]) != 0)
00252             return (1);
00253     }
00254 
00255     /* Masks don't intersect, return 0 */
00256     return (0);
00257 }
00258 
00259 static int IO_items_compatable (Mdes *mdes, Mdes_IO_Set **operand_type1,Mdes_IO_Set **operand_type2)
00260 {
00261    int i;
00262     
00263    /* Test all the operands for compatablitiy */
00264    for (i=0; i < mdes->operand_count; i++)
00265         {
00266                 /* If the operand i is not compatable, return 0 */
00267                 if (!IO_sets_intersect (mdes, operand_type1[i], operand_type2[i]))
00268                 {
00269                          return (0);
00270                 }
00271         }
00272    /* All operands compatable, return 1 */
00273    return (1);
00274 }
00275 
00276 /* 
00277  * Prints out IO_Set name for the given external id.
00278  */
00279 void mdes_print_IO_set (FILE *out, unsigned int id)
00280 {
00281     if ((id > lmdes->max_IO_set_id) ||
00282         (lmdes->IO_set_table[id] == NULL))
00283     {
00284         fprintf (out, "(Illegal IO_Set id %i) ", id);
00285     }
00286     else
00287     {
00288         fprintf (out, "%-5s ", lmdes->IO_set_table[id]->name);
00289     }
00290 }
00291 
00292 /*
00293  * Builds the compatable alt list for the operation.
00294  * Returns an Mdes_Info structure with this list in it.
00295  *
00296  * Returns NULL on error.
00297  */
00298 Mdes_Info *build_mdes_info (unsigned int opcode, int *io_list)
00299 {
00300     Mdes_Info *info;
00301     Mdes_Operation *op;
00302     Mdes_Compatable_Alt *tail, *comp_alt;
00303     Mdes_Alt *alt;
00304     Mdes_IO_Set **operand_type, **alt_operand_type;
00305     int i;
00306 
00307     /* Punt if opcode not defined */
00308     if ((opcode > lmdes->max_opcode) ||
00309         (lmdes->op_table[opcode] == NULL))
00310     {
00311         fprintf (stderr, 
00312                  "build_mdes_info: opcode %i undefined in lmdes (%s)\n",
00313                 opcode, lmdes->file_name);
00314         return (NULL);
00315     }
00316 
00317     /* Get the operation the opcode corresponds to */
00318     op = lmdes->op_table[opcode];
00319 
00320     /*
00321      * Build operand_type list from io_list 
00322      * use mdes->operand_type_buf to hold the io_list_types
00323      * (so I don't need to keep mallocing/freeing stuff)
00324      */
00325     operand_type = lmdes->operand_type_buf;
00326     for (i=0; i < lmdes->operand_count; i++)
00327     {
00328         /* Make sure valid operand type specified */
00329         if ((io_list[i] > lmdes->max_IO_set_id) ||
00330             (lmdes->IO_set_table[io_list[i]] == NULL))
00331         {
00332             fprintf (stderr, "build_mdes_info: ");
00333             print_mdes_operand_name (stderr, lmdes, i);
00334             fprintf (stderr, " = %i. Undefined in lmdes (%s)\n",
00335                     io_list[i], lmdes->file_name);
00336             return (NULL);
00337         }
00338         operand_type[i] = lmdes->IO_set_table[io_list[i]];
00339     }
00340 
00341     /* Allocate and initialize mdes_info structure */
00342     info = (Mdes_Info *) L_alloc (Mdes_Info_pool);
00343     info->opcode = opcode;
00344     info->compatable_alts = NULL;
00345     info->num_compatable_alts = 0;
00346 
00347     /* 
00348      * Test all the alts for compatable alts given this io_list,
00349      * and build compatable alt list
00350      */
00351     tail = NULL;
00352     for (i=0; i < op->num_alts; i++)
00353          {
00354                 /* Get alt and it's IO_item for easy access */
00355                 alt = &op->alt[i];
00356                 alt_operand_type = alt->IO_item->operand_type;
00357 
00358                 /* If alt and io_list operands types are compatable,
00359                  * add alt to compatable_alts list in mdes_info.
00360                  */
00361                 if (IO_items_compatable (lmdes, alt_operand_type, operand_type))
00362                 {
00363                          comp_alt=(Mdes_Compatable_Alt *)L_alloc (Mdes_Compatable_Alt_pool);
00364                          comp_alt->alt = alt;
00365                          comp_alt->next = NULL;
00366 
00367                          /* Add to end of linked list */
00368                          if (tail == NULL)
00369                         info->compatable_alts = comp_alt;
00370                          else
00371                         tail->next = comp_alt;
00372 
00373                          tail = comp_alt;
00374 
00375                          /* Update num compatable */
00376                          info->num_compatable_alts++;
00377                 }
00378          }
00379 
00380     /* Make sure there is at least one compatable alt */
00381     if (info->num_compatable_alts < 1)
00382     {
00383         fprintf (stderr,
00384                  "build_mdes_info: No alts for opcode %i match the io_list.\n",
00385                  opcode);
00386         return (NULL);
00387     }
00388 
00389     /* Return the info structure just built */
00390     return (info);
00391 }
00392 
00393 void free_mdes_info (Mdes_Info *info)
00394 {
00395     Mdes_Compatable_Alt *alt, *next_alt;
00396 
00397     for (alt = info->compatable_alts; alt != NULL; alt = next_alt)
00398     {
00399         next_alt = alt->next;
00400         L_free (Mdes_Compatable_Alt_pool, alt);
00401     }
00402     L_free (Mdes_Info_pool, info);
00403 }
00404 
00405 /* 
00406  * Returns the operand index for a specified operand.
00407  * This version also detects 'out of range' operand specification
00408  */
00409 int operand_index (unsigned int operand_type, unsigned int operand_number)
00410 {
00411     int index;
00412 
00413     /* Make sure legal operand type */
00414     if (operand_type > 4)
00415         M_punt ("operand_index: operand type %i must be between 0 and 4",
00416                 operand_type);
00417 
00418     /* Make sure operand_number is not out of bounds */
00419     if ((lmdes != NULL) &&
00420         (operand_number >= lmdes->number[operand_type]))
00421         M_punt("operand_index: illegal %s operand number %i (%i defined).", 
00422                 lmdes->name[operand_type], operand_number, 
00423                lmdes->number[operand_type]);
00424     
00425     /* Calculate index */
00426     index = lmdes->offset[operand_type] + operand_number;
00427 
00428     return (index);
00429 }
00430 
00431 /* 
00432  * Returns the operand type for a specified operand_index.
00433  * This version also detects 'out of range' operand_index specification
00434  */
00435 int operand_type (unsigned int operand_index)
00436 {
00437     int type;
00438 
00439     /* Make sure legal operand_index */
00440     if (operand_index >= lmdes->latency_count)
00441         M_punt ("operand_type: operand index %i must be between 0 and %i",
00442                 operand_index, lmdes->latency_count - 1);
00443 
00444     /* Lookup type */
00445     type = lmdes->index_type[operand_index];
00446 
00447     return (type);
00448 }
00449 
00450 /* 
00451  * Returns the operand number for a specified operand_index.
00452  * This version also detects 'out of range' operand_index specification
00453  */
00454 int operand_number (unsigned int operand_index)
00455 {
00456     int number;
00457 
00458     /* Make sure legal operand_index */
00459     if (operand_index >= lmdes->latency_count)
00460         M_punt ("operand_number: operand index %i must be between 0 and %i",
00461                 operand_index, lmdes->latency_count - 1);
00462 
00463     /* Lookup number */
00464     number = lmdes->index_number[operand_index];
00465 
00466     return (number);
00467 }
00468 
00469 /*
00470  * Returns the maximum operand type for the specified operand
00471  * for the compatable alternatives specified in mdes_info.
00472  */
00473 int max_operand_time (Mdes_Info *mdes_info, int operand_index)
00474 {
00475     Mdes_Compatable_Alt *compatable_alt;
00476     int max_time;
00477     
00478     if (mdes_info == NULL)
00479         M_punt ("max_operand_type: mdes_info is NULL");
00480 
00481     if (mdes_info->compatable_alts == NULL)
00482         M_punt ("max_operand_type: No compatable alts in mdes_info");
00483     
00484     if (operand_index >= lmdes->latency_count)
00485         M_punt ("max_operand_type: operand_index (%i) out of bounds", 
00486                 operand_index);
00487 
00488     /* Intiallize max to first alt's operand time */
00489     max_time =
00490         mdes_info->compatable_alts->alt->latency->operand_latency[operand_index];
00491 
00492     /* Search rest of compatable alts for max operand time*/
00493     for (compatable_alt = mdes_info->compatable_alts->next;
00494          compatable_alt != NULL; compatable_alt = compatable_alt->next)
00495     {
00496         if (compatable_alt->alt->latency->operand_latency[operand_index] >
00497             max_time)
00498         {
00499             max_time = 
00500                 compatable_alt->alt->latency->operand_latency[operand_index];
00501         }
00502     }
00503     return (max_time);
00504 }
00505 
00506 /*
00507  * Returns the minimum operand type for the specified operand
00508  * for the compatable alternatives specified in mdes_info.
00509  */
00510 int min_operand_time (Mdes_Info *mdes_info, int operand_index)
00511 {
00512     Mdes_Compatable_Alt *compatable_alt;
00513     int min_time;
00514     
00515     if (mdes_info == NULL)
00516         M_punt ("min_operand_type: mdes_info is NULL");
00517 
00518     if (mdes_info->compatable_alts == NULL)
00519         M_punt ("min_operand_type: No compatable alts in mdes_info");
00520 
00521     if (operand_index >= lmdes->latency_count)
00522         M_punt ("min_operand_type: operand_index (%i) out of bounds", 
00523                 operand_index);
00524 
00525     /* Intiallize max to first alt's operand time */
00526     min_time =
00527       mdes_info->compatable_alts->alt->latency->operand_latency[operand_index];
00528 
00529     /* Search rest of compatable alts for max operand time*/
00530     for (compatable_alt = mdes_info->compatable_alts->next;
00531          compatable_alt != NULL; compatable_alt = compatable_alt->next)
00532     {
00533         if (compatable_alt->alt->latency->operand_latency[operand_index] <
00534             min_time)
00535         {
00536             min_time = 
00537                 compatable_alt->alt->latency->operand_latency[operand_index];
00538         }
00539     }
00540     return (min_time);
00541 }
00542 
00543 /*
00544  * Returns the earliest time that one of the compatable alternatives
00545  * for this oper can be scheduled.
00546  */
00547 int mdes_calc_min_ready_time (Mdes_Info *mdes_info, int *ready_time)
00548 {
00549     Mdes_Compatable_Alt *comp_alt;
00550     int  *lat;
00551     int time, min_time;
00552     int i;
00553 
00554     if (mdes_info == NULL)
00555         M_punt ("mdes_calc_min_ready_time: mdes_info is NULL");
00556 
00557     min_time = -1;
00558     for (comp_alt = mdes_info->compatable_alts; comp_alt != NULL; 
00559          comp_alt = comp_alt->next)
00560     {
00561         /* Get the latency times for this alt*/
00562         lat = comp_alt->alt->latency->operand_latency;
00563 
00564         /* Get max contraint from all operands */
00565         time = 0;
00566         for (i=0; i < lmdes->latency_count; i++)
00567         {
00568             if ((ready_time[i] - lat[i]) > time)
00569                 time = ready_time[i] - lat[i];
00570         }
00571 
00572         /* If this is the first alt looked at, make this the min */
00573         if (min_time == -1)
00574             min_time = time;
00575 
00576         /* Otherwise, take the min of these max constraint times */
00577         else 
00578         {
00579             if (min_time > time)
00580                 min_time = time;
00581         }
00582     }
00583 
00584     return (min_time);
00585 }
00586 
00587 /*
00588  * Returns the operand latency for the specified alt and operand
00589  */
00590 int mdes_operand_latency (unsigned int opcode, unsigned int alt_no, 
00591                           unsigned int operand_index)
00592 {
00593     Mdes_Operation *op=NULL;
00594     int latency;
00595 
00596     /* Make sure opcode is valid */
00597     if ((opcode > lmdes->max_opcode) ||
00598         ((op = lmdes->op_table[opcode]) == NULL))
00599     {
00600         M_punt ("mdes_operand_latency: opcode (%i) not defined", opcode);
00601     }
00602 
00603     /* Make sure valid alt_no specified */
00604     if (alt_no >= op->num_alts)
00605     {
00606         M_punt ("mdes_operand_latency: alt (%i) >= number of alts (%i)\n",
00607                 alt_no, op->num_alts);
00608     }
00609     
00610     /* Make sure operand index is valid */
00611     if (operand_index >= lmdes->latency_count)
00612         M_punt ("mdes_operand_latency: operand_index (%i) out of bounds", 
00613                 operand_index);
00614 
00615 
00616 
00617     /* Return the operand latency */
00618     latency = op->alt[alt_no].latency->operand_latency[operand_index];
00619     return (latency);
00620 }
00621 
00622 /* 
00623  * This routine is intended to give a "best" choice for an 
00624  * alternative id when an opcode has not been scheduled such
00625  * as when scheduling for infinite issue or for approximating
00626  * the "best" choice for instruction latencies.
00627  *
00628  * Chooses the alternative with the lowest mdes_max_completion_time
00629  * (latency).  In case of ties, the lowest alt number will be
00630  * chosen.
00631  */
00632 int mdes_heuristic_alt_id (int opcode)
00633 {
00634     Mdes_Operation *op=NULL;
00635     int min_alt;
00636     int latency, min_latency;
00637     int alt;
00638 
00639     /* Make sure opcode is valid */
00640     if ((opcode > lmdes->max_opcode) ||
00641         ((op = lmdes->op_table[opcode]) == NULL))
00642     {
00643         M_punt ("mdes_heuristic_alt_id: opcode (%i) not defined", opcode);
00644     }
00645 
00646     /* If have not already selected the heuristic alt, do it now */
00647     if (op->heuristic_alt < 0)
00648     {
00649         /* Get the latency of the first alternative */
00650         min_alt = 0;
00651         min_latency =  mdes_max_completion_time (opcode, min_alt);
00652         
00653         for (alt = 1; alt < op->num_alts; alt++)
00654         {
00655             latency = mdes_max_completion_time (opcode, alt);
00656             if (latency < min_latency)
00657             {
00658                 min_latency = latency;
00659                 min_alt = alt;
00660             }
00661         }
00662 
00663         /* Set heuristic alt to this "best" alternative */
00664         op->heuristic_alt = min_alt;
00665     }
00666     
00667    return (op->heuristic_alt);
00668 }
00669 
00670 int mdes_max_completion_time (int opcode, int alt_no)
00671 {
00672     Mdes_Operation *op=NULL;
00673     int i, max_time, num_dests, dest_offset, *lat;
00674 
00675     /* Make sure opcode is valid */
00676     if ((opcode > lmdes->max_opcode) ||
00677         ((op = lmdes->op_table[opcode]) == NULL))
00678     {
00679         M_punt ("mdes_max_completion_time: opcode (%i) not defined", opcode);
00680     }
00681 
00682     /* Make sure valid alt_no specified */
00683     if (alt_no >= op->num_alts)
00684     {
00685         M_punt ("mdes_max_completion_time: alt (%i) >= number of alts (%i)\n",
00686                 alt_no, op->num_alts);
00687     }
00688 
00689     max_time = 0;
00690     num_dests = lmdes->number[MDES_DEST];
00691     dest_offset = operand_index (MDES_DEST, 0);
00692     lat = op->alt[alt_no].latency->operand_latency;
00693 
00694     for (i=0; i < num_dests; i++)
00695     {
00696         if (lat[dest_offset + i] > max_time)
00697             max_time = lat[dest_offset + i];
00698     }
00699 
00700     return (max_time);
00701 }
00702 
00703 
00704 /*
00705  * Loads the low level mdes file and points 'lmdes' at the
00706  * Mdes structure containing the loaded information
00707  */
00708 void L_init_lmdes (char *mdes_file_name, int num_pred, int num_dest, 
00709                    int num_src, int num_sync)
00710 {
00711     int len;
00712 
00713     if (lmdes != NULL)
00714         fprintf (stderr, "John- You need to free the old lmdes file\n");
00715 
00716     /* Build from md description if file name ends in .lmdes2 */
00717    len = strlen(mdes_file_name);
00718    if ((len > 7) &&
00719         (mdes_file_name[len-7] == '.') &&
00720         (mdes_file_name[len-6] == 'l') &&
00721         (mdes_file_name[len-5] == 'm') &&
00722         (mdes_file_name[len-4] == 'd') &&
00723         (mdes_file_name[len-3] == 'e') &&
00724         (mdes_file_name[len-2] == 's') &&
00725         (mdes_file_name[len-1] == '2'))
00726         {
00727         //      printf ("Building mdes version1 structures from version2 mdes!\n");
00728                 lmdes = load_lmdes_from_version2 (mdes_file_name, num_pred, num_dest,
00729                                                   num_src, num_sync);
00730         }
00731    else
00732    {
00733                 lmdes = load_lmdes (mdes_file_name);
00734    }
00735 
00736     /* Create alloc pools for mdes */
00737     Mdes_Info_pool = 
00738         L_create_alloc_pool ("Mdes_Info", sizeof (Mdes_Info), 4);
00739     Mdes_Compatable_Alt_pool = 
00740         L_create_alloc_pool ("Mdes_Compatable_Alt", 
00741                              sizeof (Mdes_Compatable_Alt), 4);
00742 }
00743 
00744 
00745 void Malloc_struct (void **ptr, int size)
00746 {
00747     if ((*ptr = (void *) malloc (size)) == NULL)
00748         M_punt ("Malloc_struct: Out of memory");
00749 }
00750 
00751 void Malloc_name (char **ptr, char *name)
00752 {
00753     int size;
00754     size = strlen (name) + 1;
00755     if ((*ptr = (char *) malloc (size)) == NULL)
00756         M_punt ("Malloc_name: Out of memory");
00757 
00758     strcpy (*ptr, name);
00759 }
00760 
00761 static void LM_read_mask (FILE *in, int *mask, int width)
00762 {
00763     int i;
00764     for (i=0; i < width; i++)
00765     {
00766         if (fscanf (in, "%8x", &mask[i]) != 1)
00767             M_punt ("LM_read_mask: error reading mask");
00768     }
00769 }
00770 
00771 /*
00772  * reads low-level mdes file and builds data structures.
00773  */
00774 static Mdes *load_lmdes (char *file_name)
00775 {
00776     Mdes *mdes;
00777     FILE *in;
00778     int version;
00779     int struct_size;
00780     int data_size;
00781     int set_table_size;
00782     int rused_size;
00783     int slots_size;
00784     int option_size;
00785     int alt_size;
00786     int buf_size;
00787     int *mask_ptr;
00788     int *array_ptr;
00789     int *slot_ptr;
00790     Mdes_IO_Set **type_ptr;
00791     Mdes_Rused *rused_ptr;
00792     Mdes_Rmask *option_ptr;
00793     Mdes_Alt *alt_ptr;
00794     int total_string_len;
00795     int total_used;
00796     int total_slots;
00797     int total_options;
00798     int total_alts;
00799     Mdes_IO_Set *IO_set;
00800     Mdes_IO_Item *IO_item;
00801     Mdes_Resource *resource;
00802     Mdes_ResList *reslist;
00803     Mdes_Rused  *rused;
00804     Mdes_Rmask *option;
00805     Mdes_Latency *latency;
00806     Mdes_Alt *alt;
00807     Mdes_Operation *operation;
00808     char *name_buf_ptr;
00809     int IO_set_id, IO_item_id, reslist_id, latency_id;
00810     int i, j, k, m;
00811 
00812     /* Open the file for reading */
00813     if ((in = fopen (file_name, "r")) == NULL)
00814         M_punt ("load_lmdes: Unable to open mdes file '%s' for reading",
00815                 file_name);
00816 
00817     /* Malloc mdes structure and copy file name to field */
00818     Malloc_struct ((void **)&mdes, sizeof (Mdes));
00819     Malloc_name (&mdes->file_name, file_name);
00820 
00821     /* This is build from version1 file.  Mark by placing NULL in mdes2 */
00822     mdes->mdes2 = NULL;
00823 
00824     /* Read version */
00825     version = -1;
00826     if (fscanf (in, "Lmdes Version %i\n\n", &version) != 1)
00827         M_punt ("load_lmdes: '%s' is not a lmdes file", file_name);
00828 
00829 
00830     /* Make sure file format is what we expect */
00831     if (version != MDES_VERSION)
00832     {
00833         fprintf(stderr, 
00834               "load_lmdes: '%s' internal format is incompatable with this reader.\n", file_name);
00835         fprintf (stderr,
00836               "load_lmdes: It's internal version is %i not the expected %i.\n",
00837               version, MDES_VERSION);
00838 
00839         /* Suggest a corrective action */
00840         if (version < MDES_VERSION)
00841         {
00842             fprintf (stderr, 
00843                      "load_lmdes: Please rebuild '%s' from the corresponding hmdes file.\n", 
00844                      file_name);
00845             M_punt ("load_lmdes: The hmdes file Version# does NOT need to be modified."); 
00846         }
00847 
00848         else
00849         {
00850             M_punt("load_lmdes: Please recompile this program with the new lmdes library.");
00851         }
00852     }
00853     
00854     /* Read in other paramaters (mainly processor_model) */
00855     fscanf (in, "proc_model: %d\n", &mdes->processor_model);
00856 
00857     /* Read number of src, dest, etc. operands */
00858     fscanf (in, "sizes: %d %d %d %d %d %d %d\n\n",
00859             &mdes->number[MDES_PRED], &mdes->number[MDES_DEST],
00860             &mdes->number[MDES_SRC], &mdes->number[MDES_SYNC_IN],
00861             &mdes->number[MDES_SYNC_OUT], 
00862             &mdes->max_slot, &mdes->num_slots);
00863 
00864 
00865     /*
00866      * Get total operand count, latency count, and calculate offsets into
00867      * arrays for pred, dest, src, etc. operands
00868      */
00869     mdes->operand_count = mdes->number[MDES_PRED] + mdes->number[MDES_DEST] +
00870         mdes->number[MDES_SRC];
00871 
00872     mdes->latency_count = mdes->operand_count + mdes->number[MDES_SYNC_IN] +
00873         mdes->number[MDES_SYNC_OUT];
00874 
00875     mdes->offset[MDES_PRED] = 0;
00876     mdes->offset[MDES_DEST] = mdes->offset[MDES_PRED] + 
00877         mdes->number[MDES_PRED];
00878     mdes->offset[MDES_SRC] = mdes->offset[MDES_DEST] + 
00879         mdes->number[MDES_DEST];
00880     mdes->offset[MDES_SYNC_IN] = mdes->offset[MDES_SRC] + 
00881         mdes->number[MDES_SRC];
00882     mdes->offset[MDES_SYNC_OUT] = mdes->offset[MDES_SYNC_IN] + 
00883         mdes->number[MDES_SYNC_IN];
00884 
00885     /* Set names for each operand type, for error messages */
00886     mdes->name[MDES_PRED] = "pred";
00887     mdes->name[MDES_DEST] = "dest";
00888     mdes->name[MDES_SRC] = "src";
00889     mdes->name[MDES_SYNC_IN] = "sync_in";
00890     mdes->name[MDES_SYNC_OUT] = "sync_out";
00891 
00892     /* Malloc structures to allow reverse mapping from operand_index
00893      * to operand_type and operand_number.
00894      */
00895     Malloc_struct ((void **)&mdes->index_type, 
00896                    mdes->latency_count * sizeof(int));
00897     Malloc_struct ((void **)&mdes->index_number, 
00898                    mdes->latency_count * sizeof(int));
00899 
00900     /* Init reverse map structure for MDES_PRED */
00901     for (i = 0; i < mdes->number[MDES_PRED] ; i++)
00902     {
00903         mdes->index_type[mdes->offset[MDES_PRED] + i] = MDES_PRED;
00904         mdes->index_number[mdes->offset[MDES_PRED] + i] = i;
00905     }
00906 
00907     /* Init reverse map structure for MDES_DEST */
00908     for (i = 0; i < mdes->number[MDES_DEST] ; i++)
00909     {
00910         mdes->index_type[mdes->offset[MDES_DEST] + i] = MDES_DEST;
00911         mdes->index_number[mdes->offset[MDES_DEST] + i] = i;
00912     }
00913 
00914     /* Init reverse map structure for MDES_SRC */
00915     for (i = 0; i < mdes->number[MDES_SRC] ; i++)
00916     {
00917         mdes->index_type[mdes->offset[MDES_SRC] + i] = MDES_SRC;
00918         mdes->index_number[mdes->offset[MDES_SRC] + i] = i;
00919     }
00920 
00921     /* Init reverse map structure for MDES_SYNC_IN */
00922     for (i = 0; i < mdes->number[MDES_SYNC_IN] ; i++)
00923     {
00924         mdes->index_type[mdes->offset[MDES_SYNC_IN] + i] = MDES_SYNC_IN;
00925         mdes->index_number[mdes->offset[MDES_SYNC_IN] + i] = i;
00926     }
00927 
00928     /* Init reverse map structure for MDES_SYNC_OUT */
00929     for (i = 0; i < mdes->number[MDES_SYNC_OUT] ; i++)
00930     {
00931         mdes->index_type[mdes->offset[MDES_SYNC_OUT] + i] = MDES_SYNC_OUT;
00932         mdes->index_number[mdes->offset[MDES_SYNC_OUT] + i] = i;
00933     }
00934 
00935     if (fscanf (in, "IO_Sets_begin %i %i %i %i %i %i\n", &mdes->IOmask_width, 
00936                 &mdes->num_reg_files, &mdes->num_IO_sets,
00937                 &mdes->null_external_id, 
00938                 &mdes->max_IO_set_id, &total_string_len) != 6)
00939         M_punt ("load_lmdes: error reading IO_Sets_begin");
00940     
00941 
00942     /* Allocate array of IO_Sets */
00943     struct_size = mdes->num_IO_sets * sizeof (Mdes_IO_Set);
00944     Malloc_struct ((void **)&mdes->IO_set, struct_size);
00945 
00946     /* Allocate array to map external_id's to IO_Sets */
00947     set_table_size = (mdes->max_IO_set_id + 1) * sizeof (Mdes_IO_Set *);
00948     Malloc_struct ((void **)&mdes->IO_set_table, set_table_size);
00949 
00950     /* Allocate array of IOmasks */
00951     data_size = mdes->num_IO_sets * (mdes->IOmask_width * sizeof(int) );
00952     Malloc_struct ((void **)&mask_ptr, data_size);
00953 
00954     /* Allocate all the name buffer space in one shot */
00955     Malloc_struct ((void **)&name_buf_ptr, total_string_len);
00956 
00957     /* Initialize IO_Set_table to NULL pointers */
00958     for (i=0; i <= mdes->max_IO_set_id; i++)
00959         mdes->IO_set_table[i] = NULL;
00960    
00961     /* Read in the IO_sets */
00962     for (i=0; i < mdes->num_IO_sets; i++)
00963     {
00964         IO_set = &mdes->IO_set[i];
00965         IO_set->name = name_buf_ptr;
00966         IO_set->mask = mask_ptr;
00967 
00968         fscanf (in, "%i %i %s", &IO_set->id, &IO_set->external_id,
00969                 IO_set->name);
00970 
00971         /* Put in IO_Set_table */
00972         if (IO_set->external_id != -1)
00973             mdes->IO_set_table[IO_set->external_id] = IO_set;
00974 
00975         /* Read mask from file */
00976         LM_read_mask (in, IO_set->mask, mdes->IOmask_width);
00977 
00978         /* Move name buf pointer after terminator */
00979         name_buf_ptr += strlen (IO_set->name) + 1;
00980 
00981         /* Move mask pointer after this mask */
00982         mask_ptr += mdes->IOmask_width;
00983 
00984     }
00985     fscanf (in, "\nIO_Sets_end\n\n");
00986 
00987     if (fscanf (in, "IO_Items_begin %i %i\n", &mdes->num_IO_items,
00988                 &total_string_len) != 2)
00989         M_punt ("load_lmdes: error reading IO_Items_begin");
00990     
00991     /* Allocate array of IO_Items */
00992     struct_size = mdes->num_IO_items * sizeof (Mdes_IO_Item);
00993     Malloc_struct ((void **)&mdes->IO_item, struct_size);
00994 
00995     /* Allocate array of operand types */
00996     data_size = mdes->num_IO_items * mdes->operand_count *
00997         sizeof(Mdes_IO_Set *);
00998     Malloc_struct ((void **)&type_ptr, data_size);
00999 
01000     /* Allocate all the name buffer space in one shot */
01001     Malloc_struct ((void **)&name_buf_ptr, total_string_len);
01002 
01003     for (i=0; i < mdes->num_IO_items; i++)
01004     {
01005         IO_item = &mdes->IO_item[i];
01006         IO_item->name = name_buf_ptr;
01007         IO_item->operand_type = type_ptr;
01008 
01009         fscanf (in, "%d %s", &IO_item->id, IO_item->name);
01010 
01011         for (j=0; j < mdes->operand_count; j++)
01012         {
01013             fscanf (in, "%d", &IO_set_id);
01014         
01015             /* Get pointer to appropriate IO_Set */
01016             IO_item->operand_type[j] = &mdes->IO_set[IO_set_id];
01017         }
01018 
01019         /* Move name buf pointer after terminator */
01020         name_buf_ptr += strlen (IO_item->name) + 1;
01021 
01022         /* Move type ptr to next operand type array */
01023         type_ptr += mdes->operand_count;
01024     }
01025     fscanf (in, "\nIO_Items_end\n\n");
01026 
01027     if (fscanf (in, "Resources_begin %i %i\n", &mdes->num_resources,
01028                 &total_string_len) != 2)
01029         M_punt ("load_lmdes: error reading Resources_begin");
01030     
01031     /* Allocate array of resources */
01032     struct_size = mdes->num_resources * sizeof (Mdes_Resource);
01033     Malloc_struct ((void **)&mdes->resource, struct_size);
01034 
01035     /* Allocate all the name buffer space in one shot */
01036     Malloc_struct ((void **)&name_buf_ptr, total_string_len);
01037 
01038     for (i=0; i < mdes->num_resources; i++)
01039     {
01040         resource = &mdes->resource[i];
01041         resource->name = name_buf_ptr;
01042 
01043         fscanf (in, "%d %s\n", &resource->id, resource->name);
01044 
01045         /* Move name buf pointer after terminator */
01046         name_buf_ptr += strlen (resource->name) + 1;
01047     }
01048     fscanf (in, "\nResources_end\n\n");
01049 
01050     if (fscanf (in, "ResList_begin %d %d %d %d %d %d\n", &mdes->num_reslists,
01051                 &total_used, &total_slots, &total_options, &mdes->Rmask_width,
01052                 &total_string_len) != 6)
01053         M_punt ("load_lmdes: error reading ResList_begin");
01054 
01055     /* Allocate array of resources */
01056     struct_size = mdes->num_reslists * sizeof (Mdes_ResList);
01057     Malloc_struct ((void **)&mdes->reslist, struct_size);
01058 
01059     /* Allocate array of Rused structs */
01060     rused_size = total_used * sizeof (Mdes_Rused);
01061     Malloc_struct ((void **)&rused_ptr, rused_size);
01062 
01063     /* Allocate array of slot options */
01064     slots_size = total_slots * sizeof (int);
01065     Malloc_struct ((void **)&slot_ptr, slots_size);
01066 
01067     /* Allocate array of options */
01068     option_size = total_options * sizeof (Mdes_Rmask);
01069     Malloc_struct ((void **)&option_ptr, option_size);
01070 
01071     /* Allocate array of ints for uncond/pred fields of options */
01072     data_size = total_options * 2 * mdes->Rmask_width * sizeof (int);
01073     Malloc_struct ((void **)&array_ptr, data_size);
01074 
01075     /* Allocate all the name buffer space in one shot */
01076     Malloc_struct ((void **)&name_buf_ptr, total_string_len);
01077 
01078     for (i=0; i < mdes->num_reslists; i++)
01079     {
01080         reslist = &mdes->reslist[i];
01081         reslist->name = name_buf_ptr;
01082         reslist->used = rused_ptr;
01083         reslist->slot_options = slot_ptr;
01084 
01085         fscanf (in, "%d %s %d %d %d\n", &reslist->id, reslist->name, 
01086                 &reslist->num_used, &reslist->num_slot_options,
01087                 &reslist->num_RU_entries_required);
01088 
01089         /* Read in slot options */
01090         for (j=0; j < reslist->num_slot_options; j++)
01091         {
01092             fscanf (in, "%d", &reslist->slot_options[j]);
01093         }
01094         fscanf (in, "\n");
01095 
01096         for (j=0; j < reslist->num_used; j++)
01097         {
01098             rused = &reslist->used[j];
01099             rused->option = option_ptr;
01100 
01101             fscanf (in, "%d %d %d %d\n", &rused->start_usage, 
01102                     &rused->end_usage, &rused->num_options, &rused->flags);
01103 
01104             for (k=0; k < rused->num_options; k++)
01105             {
01106                 option = &rused->option[k];
01107 
01108                 /* Grab int arrays of size mdes->Rmask_width for uncond/pred */
01109                 option->uncond = array_ptr;
01110                 array_ptr += mdes->Rmask_width;
01111                 option->pred = array_ptr;
01112                 array_ptr += mdes->Rmask_width;
01113                 
01114                 /* Read in uncond mask */
01115                 for (m=0; m < mdes->Rmask_width; m++)
01116                 {
01117                     fscanf (in, "%8x", &option->uncond[m]);
01118                 }
01119 
01120                 /* Read in pred mask */
01121                 for (m=0; m < mdes->Rmask_width; m++)
01122                 {
01123                     fscanf (in, "%8x", &option->pred[m]);
01124                 }
01125             }
01126             /* Move option pointer after this option array */
01127             option_ptr += rused->num_options;
01128         }
01129         /* Move slot pointer after slot option array */
01130         slot_ptr += reslist->num_slot_options;
01131         
01132         /* Move name buf pointer after terminator */
01133         name_buf_ptr += strlen (reslist->name) + 1;
01134 
01135         /* Move rused pointer to free space */
01136         rused_ptr += reslist->num_used;
01137     }
01138     fscanf (in, "\nResList_end\n\n");
01139 
01140     if (fscanf (in, "Latencies_begin %i %i\n", &mdes->num_latencies,
01141                 &total_string_len) != 2)
01142             M_punt ("load_lmdes: error reading Latencies_begin");
01143 
01144     /* Allocate array of latencies */
01145     struct_size = mdes->num_latencies * sizeof (Mdes_Latency);
01146     Malloc_struct ((void **)&mdes->latency, struct_size);
01147 
01148     /* Allocate all operand_latency arrays in one shot */
01149     data_size = mdes->num_latencies * mdes->latency_count * sizeof (int);
01150     Malloc_struct ((void **)&array_ptr, data_size);
01151 
01152     /* Allocate all the name buffer space in one shot */
01153     Malloc_struct ((void **)&name_buf_ptr, total_string_len);
01154 
01155     for (i=0; i < mdes->num_latencies; i++)
01156     {
01157         latency = &mdes->latency[i];
01158         latency->name = name_buf_ptr;
01159         latency->operand_latency = array_ptr;
01160 
01161         fscanf (in, "%d %s %d", &latency->id, latency->name, 
01162                 &latency->exception);
01163 
01164         for (j=0; j < mdes->latency_count; j++)
01165         {
01166             fscanf (in, "%d", &latency->operand_latency[j]);
01167         }
01168 
01169         /* Move name buf pointer after terminator */
01170         name_buf_ptr += strlen (latency->name) + 1;
01171 
01172         /* Move operand latency array ptr to next array */
01173         array_ptr += mdes->latency_count;
01174     }
01175     fscanf (in, "\nLatencies_end\n\n");
01176 
01177 
01178     if (fscanf (in, "Operations_begin %i %i %i %i\n",
01179                 &mdes->num_operations, &total_alts,
01180                 &mdes->max_opcode, &total_string_len) != 4)
01181             M_punt ("load_lmdes: error reading Operations_begin");
01182 
01183     /* Allocate array of Operations */
01184     struct_size = mdes->num_operations * sizeof (Mdes_Operation);
01185     Malloc_struct ((void **)&mdes->operation, struct_size);
01186 
01187     /* Allocate all alts in one shot */
01188     alt_size = total_alts * sizeof (Mdes_Alt);
01189     Malloc_struct ((void **)&alt_ptr, alt_size);
01190 
01191     /* Allocate op_table (indexed by opcode) */
01192     data_size = (mdes->max_opcode + 1) * sizeof (Mdes_Operation *);
01193     Malloc_struct ((void **)&mdes->op_table, data_size);
01194 
01195     /* Allocate all the name buffer space in one shot */
01196     Malloc_struct ((void **)&name_buf_ptr, total_string_len);
01197 
01198 
01199     /* Intialize all op_table pointers to NULL */
01200     for (i=0; i <= mdes->max_opcode; i++)
01201         mdes->op_table[i] = NULL;
01202 
01203     /* Read in operations */
01204     for (i=0; i < mdes->num_operations; i++)
01205     {
01206         operation = &mdes->operation[i];
01207         operation->external_name = name_buf_ptr;
01208         operation->alt = alt_ptr;
01209         operation->id = i;
01210         operation->heuristic_alt = -1;  /* Used for heuristics */
01211 
01212         fscanf (in, "%d %s %d %x\n", &operation->opcode, 
01213                 operation->external_name,
01214                 &operation->num_alts, &operation->op_flags);
01215 
01216         /* Insert into op_table */
01217         mdes->op_table[operation->opcode] = operation;
01218 
01219         /* Move name buf pointer after terminator */
01220         name_buf_ptr += strlen (operation->external_name) + 1;
01221 
01222         /* Read in alts for operation */
01223         for (j=0; j < operation->num_alts; j++)
01224         {
01225             alt = &operation->alt[j];
01226             alt->id = j;
01227             alt->asm_name = name_buf_ptr;
01228             alt->operation = operation;
01229             
01230             fscanf (in, "%s %x %d %d %d\n", alt->asm_name,
01231                     &alt->alt_flags, &IO_item_id, &reslist_id, &latency_id);
01232 
01233             /* Point at appropriate structures using ids */
01234             alt->IO_item = &mdes->IO_item[IO_item_id];
01235             alt->reslist = &mdes->reslist[reslist_id];
01236             alt->table = NULL; /* Since loading .lmdes not .lmdes2 */
01237             alt->latency = &mdes->latency[latency_id];
01238 
01239             /* Move name buf pointer after terminator */
01240             name_buf_ptr += strlen (alt->asm_name) + 1;
01241         }
01242 
01243         /* Move alt ptr to next alt array */
01244         alt_ptr += operation->num_alts;
01245     }
01246     fscanf (in, "\nOperations_end\n\n");
01247 
01248     /* Allocate temporary buffers used by Mdes routines */
01249     buf_size = mdes->operand_count * sizeof (Mdes_IO_Set *);
01250     Malloc_struct ((void **) &mdes->operand_type_buf, buf_size);
01251 
01252     /* Initialize mdes2 parameters to their implicit values for mdes1 */
01253     mdes->check_resources_for_only_one_alt = 0;
01254 
01255     return (mdes);
01256 }
01257 
01258 /*
01259  * Writes mdes file to out in a format simular to the low-level format 
01260  */
01261 void print_mdes (FILE *out, Mdes *mdes)
01262 {
01263     Mdes_IO_Set *IO_set;
01264     Mdes_IO_Item *IO_item;
01265     Mdes_Resource *resource;
01266     Mdes_ResList *reslist;
01267     Mdes_Rused  *rused;
01268     Mdes_Rmask *option;
01269     Mdes_Latency *latency;
01270     Mdes_Alt *alt;
01271     Mdes_Operation *operation;
01272     int i, j, k, m;
01273 
01274     /* Debug, print out internal data structures contents  */
01275     fprintf (out, "\nSizes  : ");
01276     fprintf (out, "%i %i %i %i %i\n", 
01277              mdes->number[MDES_PRED], mdes->number[MDES_DEST], 
01278              mdes->number[MDES_SRC], mdes->number[MDES_SYNC_IN],
01279              mdes->number[MDES_SYNC_OUT]);
01280 
01281     fprintf (out, "\nOffsets: ");
01282     fprintf (out, "%i %i %i %i %i\n", 
01283              mdes->offset[MDES_PRED], mdes->offset[MDES_DEST],
01284              mdes->offset[MDES_SRC], mdes->offset[MDES_SYNC_IN],
01285              mdes->offset[MDES_SYNC_OUT]);
01286 
01287     fprintf (out, "\nIO_sets:\n");
01288     for (i=0; i < mdes->num_IO_sets; i++)
01289     {
01290         IO_set = &mdes->IO_set[i];
01291         fprintf (out, "%2i %2i %-11s ", IO_set->id, IO_set->external_id, 
01292                 IO_set->name, IO_set->mask[0]);
01293         for (j=0; j < mdes->IOmask_width; j++)
01294             fprintf (out, "%08x ", IO_set->mask[j]);
01295         fprintf (out, "\n");
01296     }
01297     
01298     fprintf (out, "\nIO_Items:\n");
01299     for (i=0; i < mdes->num_IO_items; i++)
01300     {
01301         IO_item = &mdes->IO_item[i];
01302         fprintf (out, "%2i %-11s ", IO_item->id, IO_item->name);
01303         for (j=0; j < mdes->operand_count; j++)
01304             fprintf (out, "%2i ", IO_item->operand_type[j]->id);
01305         fprintf (out, "\n");
01306     }
01307 
01308     fprintf (out, "\nResources:\n");
01309     for (i=0; i < mdes->num_resources; i++)
01310     {
01311         resource = &mdes->resource[i];
01312         fprintf (out, "%2i %-11s\n", resource->id, resource->name);
01313     }
01314 
01315     fprintf (out, "\nResList:\n");
01316     for (i=0; i < mdes->num_reslists; i++)
01317     {
01318         reslist = &mdes->reslist[i];
01319 
01320         fprintf (out, "%2i %-11s %2i %2i %2i\n", reslist->id, reslist->name,
01321                  reslist->num_used, reslist->num_slot_options,
01322                  reslist->num_RU_entries_required);
01323 
01324         fprintf (out, "  ");
01325         for (j=0; j < reslist->num_slot_options; j++)
01326         {
01327             fprintf (out, "%2i ", reslist->slot_options[j]);
01328         }
01329         fprintf (out, "\n");
01330 
01331         for (j=0; j < reslist->num_used; j++)
01332         {
01333             rused = &reslist->used[j];
01334 
01335             fprintf (out, "  %2i %2i %2i\n", rused->start_usage, rused->end_usage,
01336                     rused->num_options);
01337 
01338             for (k=0; k < rused->num_options; k++)
01339             {
01340                 option = &rused->option[k];
01341 
01342                 fprintf (out, "    ");
01343                 for (m=0; m < mdes->Rmask_width; m++)
01344                 {
01345                     fprintf (out, "%08x ", option->uncond[m]);
01346                 }
01347                 fprintf (out, "  ");
01348                 for (m=0; m < mdes->Rmask_width; m++)
01349                 {
01350                     fprintf (out, "%08x ", option->pred[m]);
01351                 }
01352                 fprintf (out, "\n");
01353             }
01354         }
01355     }
01356 
01357     fprintf (out, "\nLatencies:\n");
01358     for (i=0; i < mdes->num_latencies; i++)
01359     {
01360         latency = &mdes->latency[i];
01361         fprintf (out, "%2i %-11s %2i ", latency->id, latency->name,
01362                 latency->exception);
01363 
01364         for (j=0; j < mdes->latency_count; j++)
01365         {
01366             fprintf (out, "%2i ", latency->operand_latency[j]);
01367         }
01368         fprintf (out, "\n");
01369     }
01370 
01371     fprintf (out, "\nOperations:\n");
01372     for (i=0; i < mdes->num_operations; i++)
01373     {
01374         operation = &mdes->operation[i];
01375 
01376         fprintf (out, "%3i %-11s %2i %08x\n", operation->opcode, 
01377                  operation->external_name,      operation->num_alts,
01378                  operation->op_flags);
01379         for (j=0; j < operation->num_alts; j++)
01380         {
01381             alt = &operation->alt[j];
01382             
01383             //HZ: 08/30/00 add check whether (alt->reslist== NULL)
01384             if(alt->reslist != NULL) //lmdes2 set alt->reslist as NULL
01385                     fprintf (out, "   %-11s %08x  %2i %2i %2i\n", 
01386                     alt->asm_name, alt->alt_flags, alt->IO_item->id,
01387                     alt->reslist->id, alt->latency->id);
01388             else
01389                     fprintf (out, "   %-11s %08x  %2i %2i\n", 
01390                     alt->asm_name, alt->alt_flags, alt->IO_item->id,
01391                     alt->latency->id);
01392         }
01393     }
01394 
01395     fprintf (out, "\nOperations sorted by opcode (testing mdes->op_table):\n");
01396     for (i=0; i <= mdes->max_opcode; i++)
01397     {
01398         if (mdes->op_table[i] != NULL)
01399             fprintf (out, "%4i %-11s\n", mdes->op_table[i]->opcode, 
01400                     mdes->op_table[i]->external_name);
01401     }
01402 }
01403 
01404 void M_punt (char *fmt, ...)
01405 {
01406     va_list     args;
01407 
01408     va_start (args, fmt);
01409     vfprintf (stderr, fmt, args);
01410     va_end(args);
01411     fprintf (stderr,"\nPUNT!\n");
01412     exit (1);
01413 }
01414 
01415 

Generated on Mon Jul 21 20:27:54 2003 for TINKER LEGO DOC by doxygen 1.3.2