Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
isa_pack_gen.cxx
Go to the documentation of this file.
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_pack_gen.cxx
00038 //
00039 //  Generate an interface for packing instructions into an instruction 
00040 //  word for all instructions in the ISA.
00041 //
00043 //
00044 
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_pack_gen.h"
00061 
00062 /* The maximum number of operands and results used by ANY target.
00063  * (It would be better to get the max operands and results from the
00064  * generated targ_isa_operands.h file -- Ken)
00065  */
00066 #define MAX_OPNDS 6
00067 #define MAX_RESULTS 2
00068 
00069 
00070 typedef enum {
00071         END     = 0,                    // end of list marker
00072         OPND    = 1,                    // OPND+n => operand n
00073         RESULT  = OPND+MAX_OPNDS        // RESULT+n => result n
00074 } COMP_TYPE;
00075 
00076 #define MAX_LISTING_OPERANDS (RESULT+MAX_RESULTS)
00077 
00078 typedef struct isa_args_type {
00079   unsigned char name;
00080   int   opnd_position;
00081   int   inst_position;
00082   int   width;
00083 } *ISA_ARGS_TYPE;
00084 
00085 typedef struct isa_adj_type {
00086   int opnd_index;
00087   OPND_ADJ_TYPE padj;
00088   OPND_ADJ_TYPE uadj;
00089 } *ISA_ADJ_TYPE;
00090 
00091 /* Define the maximum number of words an inst can have:
00092  */
00093 #define MAX_WORDS 20
00094 
00095 struct isa_pack_type {
00096   const char* name;     // to represent the pack type
00097   struct {
00098     list <ISA_ARGS_TYPE> operands;
00099     list <ISA_ARGS_TYPE> results;
00100   } word[MAX_WORDS];
00101   list <ISA_ADJ_TYPE> oadj;
00102   int max_word;
00103   int index;            
00104   int adj_index;
00105 };
00106 
00107 // map to link TOPs_ with assmbly_info properties
00108 struct op_assembly {
00109   isa_pack_type *desc;
00110   struct op_assembly *next;
00111   unsigned long long opcode_mask[MAX_WORDS];
00112 };
00113 
00114 struct opnd_adj_type {
00115   const char *name;
00116   const char *adj;
00117   int code;
00118 };
00119 
00120 static list <ISA_PACK_TYPE> all_packs;  // all the different print formats
00121 static list <OPND_ADJ_TYPE> all_oadj;   // all the different opnd adjustments
00122 static ISA_PACK_TYPE current_pack_desc;
00123 static op_assembly *op_packs[TOP_count+1];
00124 static list<op_assembly*> op_packs_list;
00125 static bool top_specified[TOP_count];
00126 static int inst_bits;
00127 static int inst_words;
00128 static int num_adj;
00129 static int mask_width;
00130 
00131 static const char * const interface[] = {
00132   "/* ====================================================================",
00133   " * ====================================================================",
00134   " *",
00135   " * Description:",
00136   " *",
00137   " *   A description of how to pack the operands of ISA instructions",
00138   " *   into binary object code. The description exports the following:",
00139   " *",
00140   " *   typedef ISA_PACK_INST",
00141   " *       A scalar type large enough to hold an instruction.",
00142   " *",
00143   " *   const INT ISA_PACK_INST_SIZE",
00144   " *       The size, in bits, of an instruction.",
00145   " *",
00146   " *   typedef (enum) ISA_PACK_COMP",
00147   " *       An enumeration of the instruction components to be packed.",
00148   " *",
00149   " *   typedef (struct) ISA_PACK_INFO",
00150   " *       Describes how the operands of a particular instruction",
00151   " *       are packed. The contents are private.",
00152   " *",
00153   " *   const INT ISA_PACK_COMP_MAX",
00154   " *       The maximum number of operands to be packed for any instruction.",
00155   " *",
00156   " *   UINT64 ISA_PACK_Init_Mask(TOP topcode, INT iword)",
00157   " *       Returns an initial bit mask to initialize the instruction word,",
00158   " *       with index 'iword', for the instruction specified by 'topcode'",
00159   " *",
00160   " *   INT ISA_PACK_Inst_Words(TOP topcode)",
00161   " *       Returns the number of instruction words for the specified topcode.",
00162   " *",
00163   " *   const ISA_PACK_INFO *ISA_PACK_Info(TOP topcode)",
00164   " *       Returns a pointer to the first packing descriptions for",
00165   " *       the instruction specified by 'topcode'. Increment",
00166   " *       the returned pointer to access any additional packing",
00167   " *       descriptions for the instruction. A packing description",
00168   " *       with component ISA_PACK_COMP_end marks the end.",
00169   " *",
00170   " *   INT ISA_PACK_INFO_Comp(const ISA_PACK_INFO *info)",
00171   " *       Identifies the instruction component to be packed.",
00172   " *",
00173   " *   INT ISA_PACK_INFO_OpndPos(const ISA_PACK_INFO *info)",
00174   " *       The offset, in bits, to the start of the component in the",
00175   " *       operand value.",
00176   " *",
00177   " *       ISA_PACK_INFO_OpndPos is meaningless for ISA_PACK_COMP_end.",
00178   " *",
00179   " *   INT ISA_PACK_INFO_InstPos(const ISA_PACK_INFO *info)",
00180   " *       The offset, in bits, to the start of the component in the",
00181   " *       instruction word.",
00182   " *",
00183   " *       ISA_PACK_INFO_InstPos is meaningless for ISA_PACK_COMP_end.",
00184   " *",
00185   " *   UINT64 ISA_PACK_INFO_Mask(const ISA_PACK_INFO *info)",
00186   " *       A bit-mask that is as wide as the instruction field being",
00187   " *       packed. The mask is normalized such that the lowest bit",
00188   " *       of the mask is in bit-0.",
00189   " *",
00190   " *       The mask is meaningless for ISA_PACK_COMP_end.",
00191   " *",
00192   " *   typedef (struct) ISA_PACK_ADJ_INFO",
00193   " *       Describes how the operands of a particular instruction",
00194   " *       are to be adjust. The contents are private.",
00195   " *",
00196   " *   const INT ISA_PACK_ADJ_END",
00197   " *       A reserved ISA_PACK_ADJ_INFO code which indicates the end",
00198   " *       of a sequence of adjustments.",
00199   " *",
00200   " *   const ISA_PACK_ADJ_INFO *ISA_PACK_Adj_Info(TOP topcode)",
00201   " *       Returns a pointer to the first operand adjustment description",
00202   " *       for the instruction specified by 'topcode'. Increment",
00203   " *       the returned pointer to access any additional adjustment",
00204   " *       descriptions for the instruction. An adjustment description",
00205   " *       with code ISA_PACK_ADJ_END marks the end.",
00206   " *",
00207   " *   INT ISA_PACK_ADJ_INFO_Code(const ISA_PACK_ADJ_INFO *info, BOOL invert)",
00208   " *       Identifies the adjustment to be made. If <invert> is FALSE,",
00209   " *       the adjustment is for packing; otherwise if <invert> is TRUE,",
00210   " *       the adjustment is for unpacking.",
00211   " *",
00212   " *   INT ISA_PACK_ADJ_INFO_OpndIdx(const ISA_PACK_ADJ_INFO *info)",
00213   " *       The index of the operand, i.e. the operand number, to be adjusted.",
00214   " *",
00215   " *   void ISA_PACK_Adjust_Operands(const ISA_PACK_ADJ_INFO *info,",
00216   " *                                 INT64 *opnd,",
00217   " *                                 BOOL invert)",
00218   " *       Apply adjustemnts to all operands of an instruction, as",
00219   " *       specified by <info>. <opnd> is a pointer to an array of",
00220   " *       of operand values for the instruction. If <invert> is FALSE,",
00221   " *       the adjustment is for packing; otherwise if <invert> is TRUE,",
00222   " *       the adjustment is for unpacking.",
00223   " *",
00224   " * ====================================================================",
00225   " * ====================================================================",
00226   " */",
00227   NULL
00228 };
00229 
00230 
00232 const char* Print_Name(int print_index)
00234 {
00235   static const char *comp_name[MAX_LISTING_OPERANDS];
00236   static bool initialized;
00237 
00238   if (!initialized) {
00239     int i;
00240     for (i = 0; i < MAX_LISTING_OPERANDS; ++i) {
00241       char buf[80];
00242       if (i == END) {
00243         comp_name[i] = "ISA_PACK_COMP_end";
00244       } else if (i == OPND) {
00245         comp_name[i] = "ISA_PACK_COMP_opnd";
00246       } else if (i > OPND && i < (OPND + MAX_OPNDS)) {
00247         sprintf(buf, "ISA_PACK_COMP_opnd+%d", i - OPND);
00248         comp_name[i] = strdup(buf);
00249       } else if (i == RESULT) {
00250         comp_name[i] = "ISA_PACK_COMP_result";
00251       } else {
00252         assert(i > RESULT && i < (RESULT + MAX_RESULTS));
00253         sprintf(buf, "ISA_PACK_COMP_result+%d", i - RESULT);
00254         comp_name[i] = strdup(buf);
00255       }
00256     }
00257     initialized = true;
00258   }
00259 
00260   return comp_name[print_index];
00261 }
00262 
00264 void ISA_Pack_Begin( const char* /* name */, int inst_bit_size )
00266 //  See interface description.
00268 {
00269   inst_bits = inst_bit_size;
00270 }
00271 
00273 ISA_PACK_TYPE ISA_Pack_Type_Create ( const char* name)
00275 //  See interface description.
00277 {
00278   ISA_PACK_TYPE result = new isa_pack_type;
00279   result->name = name;
00280   result->max_word = 0;
00281   current_pack_desc = result;
00282   all_packs.push_back (current_pack_desc);
00283   return result;
00284 }
00285 
00287 OPND_ADJ_TYPE Create_Operand_Adjustment(const char *name, const char *adj)
00289 //  See interface description.
00291 {
00292   OPND_ADJ_TYPE oadj = new opnd_adj_type;
00293   oadj->name = name;
00294   oadj->adj = adj;
00295   oadj->code = ++num_adj;
00296   all_oadj.push_back (oadj);
00297   return oadj;
00298 }
00299 
00301 void Instruction_Pack_Group(ISA_PACK_TYPE pack_type, ...)
00303 //  See interface description.
00305 {
00306   va_list ap;
00307   TOP opcode;
00308 
00309   int words = current_pack_desc->max_word + 1;
00310   if (words > inst_words) inst_words = words;
00311 
00312   va_start(ap, pack_type);
00313   for (opcode = static_cast<TOP>(va_arg(ap, int)); 
00314        opcode != TOP_UNDEFINED; 
00315        opcode = static_cast<TOP>(va_arg(ap, int)))
00316   {
00317     int i;
00318     op_assembly *op_pack = new op_assembly;
00319     for (i = 0; i < words; ++i) {
00320       unsigned long long opcode_mask;
00321       opcode_mask = inst_bits > 32 ? va_arg(ap,unsigned long long)
00322                                    : va_arg(ap,unsigned long);
00323       op_pack->opcode_mask[i] = opcode_mask;
00324     }
00325     for (i = words; i < MAX_WORDS; ++i) op_pack->opcode_mask[i] = 0;
00326     top_specified[(int)opcode] = true;
00327     op_packs_list.push_back(op_pack);
00328     op_pack->desc = current_pack_desc;
00329     op_packs[(int)opcode] = op_pack;
00330   }
00331   va_end(ap);
00332 }
00333 
00335 void Adjust_Operand(int operand_index,
00336                     OPND_ADJ_TYPE pack_adj,
00337                     OPND_ADJ_TYPE unpack_adj)
00339 //  See interface description.
00341 {
00342   ISA_ADJ_TYPE curr_adj = new isa_adj_type;
00343 
00344   if (operand_index >= MAX_OPNDS) {
00345     fprintf(stderr, "### Error: operand index (%d) exceeds %d\n",
00346                     operand_index, MAX_OPNDS-1);
00347     exit(EXIT_FAILURE);
00348   }
00349   curr_adj->opnd_index = operand_index;
00350   curr_adj->padj = pack_adj;
00351   curr_adj->uadj = unpack_adj;
00352   current_pack_desc->oadj.push_back (curr_adj);
00353 }
00354 
00356 void Operand (int operand_index, 
00357               int opnd_position, 
00358               int inst_position, 
00359               int width)
00361 //  See interface description.
00363 {
00364   ISA_ARGS_TYPE curr_args_type = new isa_args_type;
00365   int w = current_pack_desc->max_word;
00366 
00367   if (operand_index >= MAX_OPNDS) {
00368     fprintf(stderr, "### Error: operand index (%d) exceeds %d\n",
00369                     operand_index, MAX_OPNDS-1);
00370     exit(EXIT_FAILURE);
00371   }
00372   curr_args_type->name = OPND + operand_index;
00373   curr_args_type->opnd_position = opnd_position;
00374   curr_args_type->inst_position = inst_position;
00375   curr_args_type->width = width;
00376   current_pack_desc->word[w].operands.push_back (curr_args_type);
00377 
00378   if (width > mask_width) mask_width = width;
00379 }
00380 
00382 void Result (int result_index, int bit_position, int width)
00384 //  See interface description.
00386 {
00387   ISA_ARGS_TYPE curr_args_type = new isa_args_type;
00388   int w = current_pack_desc->max_word;
00389 
00390   if (result_index >= MAX_RESULTS) {
00391     fprintf(stderr, "### Error: result index (%d) exceeds %d\n",
00392                     result_index, MAX_RESULTS-1);
00393     exit(EXIT_FAILURE);
00394   }
00395   curr_args_type->name = RESULT + result_index;
00396   curr_args_type->inst_position = bit_position;
00397   curr_args_type->opnd_position = 0;
00398   curr_args_type->width = width;
00399   current_pack_desc->word[w].results.push_back (curr_args_type);
00400 
00401   if (width > mask_width) mask_width = width;
00402 }
00403 
00404 
00406 void Next_Word (void)
00408 //  See interface description.
00410 {
00411   ++current_pack_desc->max_word;
00412   if (current_pack_desc->max_word >= MAX_WORDS) {
00413     fprintf(stderr, "### Error: number of inst words (%d) exceeds MAX_WORDS\n",
00414                     current_pack_desc->max_word+1);
00415     exit(EXIT_FAILURE);
00416   }
00417 }
00418 
00419 
00421 static unsigned long long Mask(int width)
00422 {
00423   if (width > 64) {
00424     fprintf(stderr, "### Error: field width (%d) exceeds 64\n", width);
00425     exit(EXIT_FAILURE);
00426   } else if (width == 64) {
00427     return -1ULL;
00428   }
00429   return (1ULL << width) - 1;
00430 }
00431 
00432 
00434 void ISA_Pack_End(void)
00436 //  See interface description.
00438 {
00439   enum { isa_pack_adj_end = 0 };
00440   list<ISA_PACK_TYPE>::iterator isi;
00441   list<ISA_ARGS_TYPE>::iterator iai;
00442   list<ISA_ADJ_TYPE>::iterator ioi;
00443   list<OPND_ADJ_TYPE>::iterator ioai;
00444 #define FNAME "targ_isa_pack"
00445   char buf[1000];
00446   sprintf (buf, "%s.h", FNAME);
00447   FILE* hfile = fopen(buf, "w");
00448   sprintf (buf, "%s.c", FNAME);
00449   FILE* cfile = fopen(buf, "w");
00450   sprintf (buf, "%s.Exported", FNAME);
00451   FILE* efile = fopen(buf, "w");
00452   int w, i, index;
00453   const char * const isa_pack_index_format = "  %3d,  /* %s: %s */\n";
00454   const char * const isa_pack_words_format = "  %3d,  /* %s */\n";
00455   const char * const isa_pack_null_format = 
00456                         "  { %-22s, %2d, %2d,   %*d },  /* %s */\n";
00457   const char * const isa_pack_operand_format = 
00458                         "  { %-22s, %2d, %2d, 0x%0*llx },  /* %s, OPND%d */\n";
00459   const char * const isa_pack_result_format = 
00460                         "  { %-22s, %2d, %2d, 0x%0*llx },  /* %s, RESULT%d */\n";
00461   int init_digits;
00462   int mask_digits;
00463   int top;
00464   bool err;
00465   bool only_zero_opndpos;
00466   const char *info_index_type;
00467 
00468   for (err = false, top = 0; top < TOP_count; ++top) {
00469     bool is_dummy = TOP_is_dummy((TOP)top);
00470     bool is_simulated = TOP_is_simulated((TOP)top);
00471     if (!top_specified[top]) {
00472       if (!is_simulated && !is_dummy) {
00473         fprintf(stderr, "### Error: no pack specification for %s\n",
00474                         TOP_Name((TOP)top));
00475         err = true;
00476       }
00477     } else if (is_dummy) {
00478       fprintf(stderr, "### Error: pack specification for dummy op %s\n",
00479                       TOP_Name((TOP)top));
00480       err = true;
00481     } else if (is_simulated) {
00482       fprintf(stderr, "### Error: pack specification for simulated op %s\n",
00483                       TOP_Name((TOP)top));
00484       err = true;
00485     }
00486   }
00487   if (err) exit(EXIT_FAILURE);
00488 
00489   // setup types and formats depending on instruction size.
00490   if (inst_bits > 32) {
00491     init_digits = 64 / 4;
00492   } else if (inst_bits > 16) {
00493     init_digits = 32 / 4;
00494   } else if (inst_bits > 8) {
00495     init_digits = 16 / 4;
00496   } else {
00497     init_digits = 8 / 4;
00498   }
00499 
00500   if (mask_width > 32) {
00501     mask_digits = 64 / 4;
00502   } else if (mask_width > 16) {
00503     mask_digits = 32 / 4;
00504   } else if (mask_width > 8) {
00505     mask_digits = 16 / 4;
00506   } else {
00507     mask_digits = 8 / 4;
00508   }
00509 
00510   // for some archs, opndpos will always be zero, so detect those
00511   // archs so we can optimize the interface.
00512   only_zero_opndpos = true;
00513   for ( isi = all_packs.begin(); isi != all_packs.end(); ++index, ++isi ) {
00514     ISA_PACK_TYPE curr_ptype = *isi;
00515     for (w = 0; w <= curr_ptype->max_word; ++w) {
00516       for ( iai = curr_ptype->word[w].operands.begin();
00517             iai != curr_ptype->word[w].operands.end();
00518             ++iai) 
00519       {
00520         ISA_ARGS_TYPE curr_atype =  *iai;
00521         if (curr_atype->opnd_position != 0) only_zero_opndpos = false;
00522       }
00523       for ( iai = curr_ptype->word[w].results.begin(); 
00524             iai != curr_ptype->word[w].results.end(); 
00525             ++iai)
00526       {
00527         ISA_ARGS_TYPE curr_atype =  *iai;
00528         if (curr_atype->opnd_position != 0) only_zero_opndpos = false;
00529       }
00530     }
00531   }
00532 
00533   fprintf(cfile,"#include \"topcode.h\"\n");
00534   fprintf(cfile,"#include \"%s.h\"\n\n", FNAME);
00535 
00536   sprintf (buf, "%s", FNAME);
00537   Emit_Header (hfile, buf, interface);
00538   fprintf(hfile,"#include \"topcode.h\"\n");
00539   if (inst_words == 1) fprintf(hfile,"#include \"targ_isa_properties.h\"\n");
00540 
00541   fprintf(hfile, "\ntypedef mUINT%d ISA_PACK_INST;\n", init_digits * 4);
00542 
00543   fprintf(hfile, "\n#define ISA_PACK_INST_SIZE (%d)\n", inst_bits);
00544 
00545   fprintf(hfile, "\n#define ISA_PACK_MAX_INST_WORDS (%d)\n", inst_words);
00546 
00547   fprintf(hfile, "\ntypedef enum {\n"
00548         "  %-20s = %d,  /* %s */\n"
00549         "  %-20s = %d,  /* %s */\n"
00550         "  %-20s = %d,  /* %s */\n"
00551         "  %-20s = %d   /* %s */\n"
00552         "} ISA_PACK_COMP;\n",
00553         Print_Name(END), END, "End of list marker",
00554         Print_Name(OPND), OPND, "OPND+n => operand n",
00555         Print_Name(RESULT), RESULT, "RESULT+n => result n",
00556         "ISA_PACK_COMP_MAX", MAX_LISTING_OPERANDS-1, "Last component");
00557 
00558   fprintf(hfile, "\ntypedef struct {\n"
00559                 "  mUINT8 comp;\n"
00560                 "  mUINT8 opndpos;\n"
00561                 "  mUINT8 instpos;\n"
00562                 "  mUINT%d mask;\n" 
00563                 "} ISA_PACK_INFO;\n",
00564                 mask_digits * 4);
00565 
00566   fprintf(efile, "ISA_PACK_info\n");
00567 
00568   fprintf(cfile, "\nconst ISA_PACK_INFO ISA_PACK_info[] = {\n");
00569 
00570   fprintf (cfile, isa_pack_null_format, Print_Name(END), -1, -1, mask_digits, -1, "UNDEFINED");
00571   index = 1;
00572   for ( isi = all_packs.begin(); isi != all_packs.end(); ++isi ) {
00573     ISA_PACK_TYPE curr_ptype = *isi;
00574     curr_ptype->index = index;
00575     for (w = 0; w <= curr_ptype->max_word; ++w, ++index) {
00576       i = 0;
00577       for ( iai = curr_ptype->word[w].operands.begin(); 
00578             iai != curr_ptype->word[w].operands.end(); ++index, ++iai) {
00579         ISA_ARGS_TYPE curr_atype =  *iai;
00580         fprintf (cfile, isa_pack_operand_format,
00581                         Print_Name(curr_atype->name), 
00582                         curr_atype->opnd_position,
00583                         curr_atype->inst_position,
00584                         mask_digits, Mask(curr_atype->width),
00585                         curr_ptype->name, 
00586                         i++);
00587       }
00588       i = 0;
00589       for ( iai = curr_ptype->word[w].results.begin(); 
00590             iai != curr_ptype->word[w].results.end(); ++index, ++iai) {
00591         ISA_ARGS_TYPE curr_atype =  *iai;
00592         fprintf (cfile, isa_pack_result_format,
00593                         Print_Name(curr_atype->name), 
00594                         curr_atype->opnd_position,
00595                         curr_atype->inst_position,
00596                         mask_digits, Mask(curr_atype->width),
00597                         curr_ptype->name,
00598                         i++);
00599       }
00600       fprintf (cfile, isa_pack_null_format, 
00601                       Print_Name(END), 
00602                       -1,
00603                       -1, 
00604                       mask_digits, -1,
00605                       curr_ptype->name);
00606     }
00607   }
00608   fprintf (cfile, "};\n\n");
00609 
00610   // select the ISA_PACK_info_index based on the number of packing types.
00611   if (index < 1<<8) {
00612     info_index_type = "mUINT8";
00613   } else {
00614     assert (index < 1<<16);
00615     info_index_type = "mUINT16";
00616   }
00617 
00618   fprintf(efile, "ISA_PACK_info_index\n");
00619 
00620   fprintf(cfile, "\nconst %s ISA_PACK_info_index[%d] = {\n", 
00621                  info_index_type, TOP_count);
00622   for (top = 0; top < TOP_count; ++top ) {
00623         op_assembly *op_pack = op_packs[top];
00624         if (op_pack) {
00625             fprintf(cfile, isa_pack_index_format,
00626                         op_pack->desc->index,
00627                         TOP_Name((TOP)top),
00628                         op_pack->desc->name);
00629         } else {
00630             fprintf(cfile, "  %3d,  /* %s */\n", 
00631                         0,
00632                         TOP_Name((TOP)top));
00633         }
00634   }
00635   fprintf(cfile, "};\n");
00636 
00637   fprintf(efile, "ISA_PACK_init_mask\n");
00638 
00639   fprintf(cfile, "\nconst mUINT%d ISA_PACK_init_mask[%d][%d] = {\n",
00640                  init_digits * 4,
00641                  TOP_count,
00642                  inst_words);
00643   for (top = 0; top < TOP_count; ++top ) {
00644     op_assembly *op_pack = op_packs[top];
00645     fprintf(cfile, "  {");
00646     for (w = 0; w < inst_words; ++w) {
00647       fprintf(cfile, " 0x%0*llx,",
00648                      init_digits, op_pack ? op_pack->opcode_mask[w] : 0LL);
00649     }
00650     fprintf(cfile, " }, /* %s */\n", TOP_Name((TOP)top));
00651 
00652   }
00653   fprintf(cfile, "};\n");
00654 
00655   if (inst_words > 1) {
00656     fprintf(efile, "ISA_PACK_inst_words\n");
00657 
00658     fprintf(cfile, "\nconst mUINT8 ISA_PACK_inst_words[%d] = {\n", TOP_count);
00659     for (top = 0; top < TOP_count; ++top ) {
00660       op_assembly *op_pack = op_packs[top];
00661       int words = op_pack ? op_pack->desc->max_word + 1 
00662                           : (TOP_is_dummy(top) ? 0 : 1);
00663       fprintf(cfile, isa_pack_words_format,
00664                      words,
00665                      TOP_Name((TOP)top));
00666     }
00667     fprintf(cfile, "};\n");
00668   }
00669 
00670   fprintf(hfile, "\ninline UINT64 ISA_PACK_Init_Mask(TOP topcode, INT iword)\n"
00671                  "{\n"
00672                  "  extern const mUINT%d ISA_PACK_init_mask[%d][%d];\n"
00673                  "  return ISA_PACK_init_mask[(INT)topcode][iword];\n"
00674                  "}\n",
00675                  init_digits * 4,
00676                  TOP_count,
00677                  inst_words);
00678 
00679   fprintf(hfile, "\ninline INT ISA_PACK_Inst_Words(TOP topcode)\n"
00680                  "{\n");
00681   if (inst_words == 1) {
00682     fprintf(hfile, "  return TOP_is_dummy(topcode) ? 0 : 1;\n");
00683   } else {
00684     fprintf(hfile, "  extern const mUINT8 ISA_PACK_inst_words[%d];\n"
00685                    "  return ISA_PACK_inst_words[(INT)topcode];\n",
00686                    TOP_count);
00687   }
00688   fprintf(hfile, "}\n");
00689 
00690   fprintf(hfile, "\ninline const ISA_PACK_INFO *ISA_PACK_Info(TOP topcode)\n"
00691                  "{\n"
00692                  "  extern const %s ISA_PACK_info_index[];\n"
00693                  "  extern const ISA_PACK_INFO ISA_PACK_info[];\n"
00694                  "  INT index = ISA_PACK_info_index[(INT)topcode];\n"
00695                  "  return index == 0 ? 0 : &ISA_PACK_info[index];\n"
00696                  "}\n",
00697                  info_index_type);
00698 
00699   fprintf(hfile, "\ninline INT ISA_PACK_INFO_Comp(const ISA_PACK_INFO *info)\n"
00700                  "{\n"
00701                  "  return info->comp;\n"
00702                  "}\n");
00703 
00704   fprintf(hfile, "\n%s"
00705                  "inline INT ISA_PACK_INFO_OpndPos(const ISA_PACK_INFO *info)\n"
00706                  "{\n"
00707                  "  return %s;\n"
00708                  "}\n",
00709                  only_zero_opndpos ? "/*ARGSUSED*/\n" : "",
00710                  only_zero_opndpos ? "0" : "info->opndpos");
00711 
00712   fprintf(hfile, "\ninline INT ISA_PACK_INFO_InstPos(const ISA_PACK_INFO *info)\n"
00713                  "{\n"
00714                  "  return info->instpos;\n"
00715                  "}\n");
00716 
00717   fprintf(hfile, "\ninline UINT64 ISA_PACK_INFO_Mask(const ISA_PACK_INFO *info)\n"
00718                  "{\n"
00719                  "  return info->mask;\n"
00720                  "}\n");
00721 
00722   fprintf(hfile, "\ntypedef struct {\n"
00723                  "  mUINT8 code[2];\n"
00724                  "  mUINT8 opndidx;\n"
00725                  "} ISA_PACK_ADJ_INFO;\n");
00726 
00727   fprintf(hfile, "\nenum { ISA_PACK_ADJ_END = %d };\n",
00728                  isa_pack_adj_end);
00729 
00730   fprintf(efile, "ISA_PACK_adj_info\n");
00731 
00732   fprintf(cfile, "\nconst ISA_PACK_ADJ_INFO ISA_PACK_adj_info[] = {\n"
00733                  "  { { %2d, %2d }, -1 },  /* [ 0]: ISA_PACK_ADJ_END */\n",
00734                  isa_pack_adj_end, isa_pack_adj_end);
00735   index = 1;
00736   for ( isi = all_packs.begin(); isi != all_packs.end(); ++isi ) {
00737     ISA_PACK_TYPE curr_ptype = *isi;
00738     i = 0;
00739     if (curr_ptype->oadj.begin() != curr_ptype->oadj.end()) {
00740       curr_ptype->adj_index = index;
00741       for ( ioi = curr_ptype->oadj.begin(); 
00742             ioi != curr_ptype->oadj.end(); 
00743             ++index, ++ioi)
00744       {
00745         ISA_ADJ_TYPE curr_adj = *ioi;
00746         fprintf(cfile, "  { { %2d, %2d }, %2d },  /* [%2d]: %s (%s) operand %d*/\n", 
00747                        curr_adj->padj->code, 
00748                        curr_adj->uadj->code, 
00749                        curr_adj->opnd_index,
00750                        index,
00751                        curr_adj->padj->name,
00752                        curr_adj->uadj->name,
00753                        curr_adj->opnd_index);
00754       }
00755       fprintf (cfile, "  { { %2d, %2d }, -1 },  /* [%2d]: ISA_PACK_ADJ_END */\n", 
00756                       isa_pack_adj_end, isa_pack_adj_end, index);
00757       ++index;
00758     } else {
00759       curr_ptype->adj_index = 0;
00760     }
00761   }
00762   fprintf(cfile, "};\n");
00763 
00764   fprintf(hfile, "\ninline INT ISA_PACK_ADJ_INFO_Code(const ISA_PACK_ADJ_INFO *info, BOOL invert)\n"
00765                  "{\n"
00766                  "  return info->code[invert];\n"
00767                  "}\n");
00768 
00769   fprintf(hfile, "\ninline INT ISA_PACK_ADJ_INFO_OpndIdx(const ISA_PACK_ADJ_INFO *info)\n"
00770                  "{\n"
00771                  "  return info->opndidx;\n"
00772                  "}\n");
00773 
00774   fprintf(efile, "ISA_PACK_adj_info_index\n");
00775 
00776   fprintf(cfile, "\nconst mUINT8 ISA_PACK_adj_info_index[] = {\n");
00777   for (top = 0; top < TOP_count; ++top ) {
00778     op_assembly *op_pack = op_packs[top];
00779     fprintf(cfile, "  %2d,  /* %s */\n",
00780                    op_pack ? op_pack->desc->adj_index : 0,
00781                    TOP_Name((TOP)top));
00782   }
00783   fprintf(cfile, "};\n");
00784 
00785   fprintf(hfile, "\ninline const ISA_PACK_ADJ_INFO *ISA_PACK_Adj_Info(TOP topcode)\n"
00786                  "{\n"
00787                  "  extern const ISA_PACK_ADJ_INFO ISA_PACK_adj_info[];\n"
00788                  "  extern const mUINT8 ISA_PACK_adj_info_index[];\n"
00789                  "  INT index = ISA_PACK_adj_info_index[(INT)topcode];\n"
00790                  "  return index == 0 ? 0 : &ISA_PACK_adj_info[index];\n"
00791                  "}\n");
00792 
00793   fprintf(hfile, "\nextern void ISA_PACK_Adjust_Operands(const ISA_PACK_ADJ_INFO *info,\n"
00794                  "                                       INT64 *opnd,\n"
00795                  "                                       BOOL invert);\n");
00796 
00797   fprintf(efile, "ISA_PACK_Adjust_Operands\n");
00798 
00799   fprintf(cfile, "\n"
00800                  "void ISA_PACK_Adjust_Operands(const ISA_PACK_ADJ_INFO *info,\n"
00801                  "                              INT64 *opnd,\n"
00802                  "                              BOOL invert)\n"
00803                  "{\n"
00804                  "  INT code;\n"
00805                  "\n"
00806                  "  for (; (code = ISA_PACK_ADJ_INFO_Code(info, invert)) != ISA_PACK_ADJ_END; ++info) {\n"
00807                  "    INT index = ISA_PACK_ADJ_INFO_OpndIdx(info);\n"
00808                  "    INT64 O_VAL = opnd[index];\n"
00809                  "    switch (code) {\n");
00810   for ( ioai = all_oadj.begin(); ioai != all_oadj.end(); ++ioai ) {
00811     OPND_ADJ_TYPE curr_oadj = *ioai;
00812     fprintf(cfile, "    case %2d:  /* %s */\n"
00813                    "      O_VAL = (%s);\n"
00814                    "      break;\n",
00815                    curr_oadj->code, curr_oadj->name,
00816                    curr_oadj->adj);
00817   }
00818   fprintf(cfile, "    }\n"
00819                  "    opnd[index] = O_VAL;\n"
00820                  "  }\n"
00821                  "}\n");
00822 
00823   Emit_Footer (hfile);
00824 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines