Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
isa_operands_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_operands_gen.cxx
00038 //
00039 //  Interface for specifying operands and results for various
00040 //  instructions in the ISA.
00041 //
00043 //
00044 
00045 typedef struct operand_value_type *OPERAND_VALUE_TYPE;
00046 
00047 #include <stddef.h>
00048 #include <stdlib.h>
00049 #include <stdarg.h>
00050 #include <stdio.h>
00051 #include <assert.h>
00052 
00053 #include <vector>
00054 #include <list>
00055 #include <algorithm>
00056 
00057 using namespace std;
00058 
00059 #include "topcode.h"
00060 #include "gen_util.h"
00061 #include "isa_operands_gen.h"
00062 
00063 
00064 struct operand_value_type {
00065   const char* name;         // Name given for documentation and debugging
00066   ISA_REGISTER_CLASS register_class;    
00067   ISA_REGISTER_SUBCLASS register_subclass;
00068   ISA_LIT_CLASS literal_class;
00069   ISA_ENUM_CLASS enum_class;
00070   bool is_register;
00071   bool is_signed;
00072   bool is_pcrel;
00073   bool is_fpu_int;
00074   int size;
00075   int index;
00076 };
00077 
00078 typedef struct operands_group {
00079   const char* name;         // Name given for documentation and debugging
00080   int opnd_count;
00081   int result_count;
00082   vector <OPERAND_VALUE_TYPE> operands;
00083   int relocatable_opnd;
00084   vector <OPERAND_VALUE_TYPE> results;
00085   vector <OPERAND_USE_TYPE> opnd_use;
00086   vector <OPERAND_USE_TYPE> res_use;
00087   int index;
00088 } *OPERANDS_GROUP;
00089 
00090 struct operand_use_type {
00091   const char *name;
00092   int index;
00093 };
00094 
00095 static vector <OPERANDS_GROUP> op_groups;
00096 static OPERANDS_GROUP cur_oper_group;
00097 static list <OPERAND_VALUE_TYPE> all_operand_types;
00098 static list <OPERAND_USE_TYPE> all_use_types;
00099 static list <OPERANDS_GROUP> all_groups; // All the instruction groups
00100 
00101 static int max_operands = 0;
00102 static int max_results = 0;
00103 static int max_valtypes = 0;
00104 static int max_groups = 0;
00105 static int max_uses = 0;
00106 
00107 /* The generated interface description:
00108  */
00109 static const char * const interface[] = {
00110   "/* ====================================================================",
00111   " * ====================================================================",
00112   " *",
00113   " * Description:",
00114   " *",
00115   " *   A description of the ISA instruction operands. The description",
00116   " *   exports the following:",
00117   " *",
00118   " *   typedef (struct) ISA_OPERAND_VALTYP",
00119   " *       Describes a particular operand/result type, including",
00120   " *       the type of value it may contain and whether or not is",
00121   " *       a register, literal or enum. The contents are private.",
00122   " *",
00123   " *   typedef (struct) ISA_OPERAND_INFO",
00124   " *       Identifies the operand types of a particular instruction.",
00125   " *       The contents are private.",
00126   " *",
00127   " *,  typedef (enum) ISA_OPERAND_USE",
00128   " *       Identifies the useage of an operand of a particular instruction.",
00129   " *       The names have the form OU_xxxx.",
00130   " *",
00131   " *   const INT OU_UNDEFINED",
00132   " *       Identifies an undefined/unknown operand use.",
00133   " *",
00134   " *   const INT ISA_OPERAND_max_operands",
00135   " *       The maximum number of operands of any instruction.",
00136   " *",
00137   " *   const INT ISA_OPERAND_max_results",
00138   " *       The maximum number of results of any instruction.",
00139   " *",
00140   " *   const ISA_OPERAND_INFO *ISA_OPERAND_Info(TOP topcode)",
00141   " *       Return a pointer to the operand info for the instruction",
00142   " *       specified by 'topcode'.",
00143   " *",
00144   " *   INT ISA_OPERAND_INFO_Operands(const ISA_OPERAND_INFO *oinfo)",
00145   " *       Return the number of operands specified by the operand",
00146   " *       info 'oinfo'.",
00147   " *",
00148   " *   const ISA_OPERAND_VALTYP *ISA_OPERAND_INFO_Operand(",
00149   " *     const ISA_OPERAND_INFO *oinfo,",
00150   " *     int opnd",
00151   " *   )",
00152   " *       Get the operand type of operand 'opnd' specified by the",
00153   " *       operand info 'oinfo'.",
00154   " *",
00155   " *   INT ISA_OPERAND_INFO_Results(const ISA_OPERAND_INFO *oinfo)",
00156   " *       Return the number of results specified by the operand",
00157   " *       info 'oinfo'.",
00158   " *",
00159   " *   const ISA_OPERAND_VALTYP *ISA_OPERAND_INFO_Result(",
00160   " *     const ISA_OPERAND_INFO *oinfo,",
00161   " *     int result",
00162   " *   )",
00163   " *       Get the operand type for the result 'result' specified by the",
00164   " *       operand info 'oinfo'.",
00165   " *",
00166   " *   ISA_OPERAND_USE ISA_OPERAND_INFO_Use(",
00167   " *     const ISA_OPERAND_INFO *oinfo,",
00168   " *     INT opnd",
00169   " *   )",
00170   " *       Get the operand use type of operand 'opnd' specified by the",
00171   " *       operand info 'oinfo'.",
00172   " *",
00173   " *   BOOL ISA_OPERAND_Any_Use(ISA_OPERAND_USE ouse)",
00174   " *       Returns a boolean that indicates if any instruction in the",
00175   " *       architecture has an an operand with usage 'use'. Useful",
00176   " *       for omitting sections of code that aren't applicable to",
00177   " *       some architectures.",
00178   " *",
00179   " *   ISA_REGISTER_CLASS ISA_OPERAND_VALTYP_Register_Class(",
00180   " *     const ISA_OPERAND_VALTYP *otype",
00181   " *   )",
00182   " *       Get the register class for the operand specified by 'otype'.",
00183   " *",
00184   " *   ISA_REGISTER_SUBCLASS ISA_OPERAND_VALTYP_Register_Subclass(",
00185   " *     const ISA_OPERAND_VALTYP *otype",
00186   " *   )",
00187   " *       Get the register subclass for the operand specified by 'otype'.",
00188   " *",
00189   " *   ISA_LIT_CLASS ISA_OPERAND_VALTYP_Literal_Class(const ISA_OPERAND_VALTYP *otype)",
00190   " *       Get the literal class for the operand specified by 'otype'.",
00191   " *",
00192   " *   ISA_ENUM_CLASS ISA_OPERAND_VALTYP_Enum_Class(",
00193   " *     const ISA_OPERAND_VALTYP *otype",
00194   " *   )",
00195   " *       Get the enum class for the operand specified by 'otype'.",
00196   " *",
00197   " *   INT ISA_OPERAND_VALTYP_Size(const ISA_OPERAND_VALTYP *otype)",
00198   " *       Get the size for the operand specified by 'otype'.",
00199   " *",
00200   " *   BOOL ISA_OPERAND_VALTYP_Is_Register(const ISA_OPERAND_VALTYP *otype)",
00201   " *       Return a boolean to specify if the operand specifed",
00202   " *       by 'otype' is a register.",
00203   " *",
00204   " *   BOOL ISA_OPERAND_VALTYP_Is_Signed(const ISA_OPERAND_VALTYP *otype)",
00205   " *       Return a boolean to specify if the operand specifed",
00206   " *       by 'otype' is signed.",
00207   " *",
00208   " *   BOOL ISA_OPERAND_VALTYP_Is_FPU_Int(const ISA_OPERAND_VALTYP *otype)",
00209   " *       Return a boolean to specify if the operand specifed",
00210   " *       by 'otype' is an FPU integer.",
00211   " *",
00212   " *   BOOL ISA_OPERAND_VALTYP_Is_PCRel(const ISA_OPERAND_VALTYP *otype)",
00213   " *       Return a boolean to specify if the operand specifed",
00214   " *       by 'otype' is pc-relative.",
00215   " *",
00216   " *   BOOL ISA_OPERAND_VALTYP_Is_Literal (const ISA_OPERAND_VALTYP *otype)",
00217   " *       Return a boolean to specify if the operand specifed",
00218   " *       by 'otype' is a literal.",
00219   " *",
00220   " *   BOOL ISA_OPERAND_VALTYP_Is_Enum (const ISA_OPERAND_VALTYP *otype)",
00221   " *       Return a boolean to specify if the operand specifed",
00222   " *       by 'otype' is an enum.",
00223   " *",
00224   " *   BOOL TOP_Can_Have_Immediate(INT64 value, TOP topcode)",
00225   " *       Return a boolean to specify if the 64-bit integer value can fit",
00226   " *       in the literal field of an instruction with the given topcode.",
00227   " *",
00228   " *   INT TOP_Immediate_Operand(TOP topcode, ISA_LIT_CLASS *lclass)",
00229   " *       If 'topcode' has an immediate operand, return its operand",
00230   " *       number by value and literal class by reference through 'lclass'",
00231   " *       (a null pointer can be passed for 'lclass' if the literal",
00232   " *       class is not needed). If there is no immediate operand, return -1.",
00233   " *",
00234   " *   INT TOP_Relocatable_Operand(TOP topcode, ISA_LIT_CLASS *lclass)",
00235   " *       If 'topcode' has a relocatable operand, return its operand",
00236   " *       number by value and literal class by reference through 'lclass'",
00237   " *       (a null pointer can be passed for 'lclass' if the literal",
00238   " *       class is not needed). If there is no relocatable operand, return -1.",
00239   " *",
00240   " *   INT TOP_Find_Operand_Use(TOP topcode, ISA_OPERAND_USE use)",
00241   " *       For the instruction specified by 'topcode', give the",
00242   " *       operand number with the use 'use'. If there is no such",
00243   " *       operand, return -1.",
00244   " *",
00245   " *   void TOP_Operand_Uses(TOP topcode, ISA_OPERAND_USE *uses)",
00246   " *       For the instruction specified by 'topcode', return",
00247   " *       the usage of all its operands in the array pointed to",
00248   " *       by 'uses'. The use of operand n corresponds to 'uses'[n].",
00249   " *",
00250   " * ====================================================================",
00251   " * ====================================================================",
00252   " */",
00253   NULL
00254 };
00255 
00256 
00258 void ISA_Operands_Begin( const char* /* name */ )
00260 //  See interface description.
00262 {
00263   op_groups = vector <OPERANDS_GROUP> (TOP_count, (OPERANDS_GROUP) false);
00264 }
00265 
00266 
00268 OPERAND_VALUE_TYPE ISA_Reg_Opnd_Type_Create ( 
00269   const char* name, 
00270   ISA_REGISTER_CLASS register_class, 
00271   ISA_REGISTER_SUBCLASS subclass,
00272   int size,
00273   RTYPE type,
00274   FP_TYPE fp_int)
00276 //  See interface description.
00278 {
00279   if (type != SIGNED && type != UNSIGNED) {
00280     fprintf(stderr, "### Error: RTYPE for register operand %s must be SIGNED or UNSIGNED\n",
00281                     name);
00282     exit(EXIT_FAILURE);
00283   }
00284 
00285   OPERAND_VALUE_TYPE result = new operand_value_type;
00286 
00287   all_operand_types.push_back(result);
00288 
00289   result->name = name;
00290   result->register_class = register_class;
00291   result->register_subclass = subclass;
00292   result->literal_class = LC_UNDEFINED;
00293   result->enum_class = EC_UNDEFINED;
00294   result->size = size;
00295   result->is_register = true;
00296   result->is_signed = type == SIGNED;
00297   result->is_pcrel = false;
00298   result->is_fpu_int = fp_int != INVALID;
00299   result->index = max_valtypes++;
00300 
00301   return result;
00302 }
00303 
00304 
00306 OPERAND_VALUE_TYPE ISA_Lit_Opnd_Type_Create ( 
00307   const char* name, 
00308   int size,
00309   RTYPE type,
00310   ISA_LIT_CLASS literal_class)
00312 //  See interface description.
00314 {
00315   if (type != SIGNED && type != UNSIGNED && type != PCREL) {
00316     fprintf(stderr, "### Error: RTYPE for literal operand %s must be PCREL, SIGNED or UNSIGNED\n",
00317                     name);
00318     exit(EXIT_FAILURE);
00319   }
00320 
00321   OPERAND_VALUE_TYPE result = new operand_value_type;
00322 
00323   all_operand_types.push_back(result);
00324 
00325   result->name = name;
00326   result->register_class = ISA_REGISTER_CLASS_UNDEFINED;
00327   result->register_subclass = ISA_REGISTER_SUBCLASS_UNDEFINED;
00328   result->literal_class = literal_class;
00329   result->enum_class = EC_UNDEFINED;
00330   result->is_register = false;
00331   result->is_signed = (type == SIGNED) || (type == PCREL);
00332   result->is_pcrel = (type == PCREL);
00333   result->is_fpu_int = false;
00334   result->size = size;
00335   result->index = max_valtypes++;
00336 
00337   return result;
00338 }
00339 
00341 OPERAND_VALUE_TYPE ISA_Enum_Opnd_Type_Create ( 
00342   const char* name, 
00343   int size,
00344   RTYPE type,
00345   ISA_ENUM_CLASS enum_class)
00347 //  See interface description.
00349 {
00350   if (type != SIGNED && type != UNSIGNED) {
00351     fprintf(stderr, "### Error: RTYPE for enumerated operand %s must be SIGNED or UNSIGNED\n",
00352                     name);
00353     exit(EXIT_FAILURE);
00354   }
00355 
00356   OPERAND_VALUE_TYPE result = new operand_value_type;
00357 
00358   all_operand_types.push_back(result);
00359 
00360   result->name = name;
00361   result->register_class = ISA_REGISTER_CLASS_UNDEFINED;
00362   result->register_subclass = ISA_REGISTER_SUBCLASS_UNDEFINED;
00363   result->literal_class = LC_UNDEFINED;
00364   result->enum_class = enum_class;
00365   result->is_register = false;
00366   result->is_signed = type == SIGNED;
00367   result->is_pcrel = false;
00368   result->is_fpu_int = false;
00369   result->size = size;
00370   result->index = max_valtypes++;
00371 
00372   return result;
00373 }
00374 
00375 
00377 OPERAND_USE_TYPE Create_Operand_Use( const char *name )
00379 //  See interface description.
00381 {
00382   OPERAND_USE_TYPE result = new operand_use_type;
00383 
00384   all_use_types.push_back(result);
00385 
00386   result->name = name;
00387   result->index = max_uses++;
00388 
00389   return result;
00390 }
00391 
00392 
00394 void Instruction_Group( const char *name, ... )
00396 //  See interface description.
00398 {
00399   va_list ap;
00400   TOP opcode;
00401 
00402   OPERANDS_GROUP oper_group = new operands_group;
00403 
00404   cur_oper_group = oper_group;
00405   oper_group->name = name;
00406   oper_group->opnd_count = 0;
00407   oper_group->operands = vector<OPERAND_VALUE_TYPE>();
00408   oper_group->relocatable_opnd = -1;
00409   oper_group->result_count = 0;
00410   oper_group->results = vector<OPERAND_VALUE_TYPE>();
00411   oper_group->opnd_use = vector<OPERAND_USE_TYPE>();
00412   oper_group->res_use = vector<OPERAND_USE_TYPE>();
00413   oper_group->index = max_groups++;
00414 
00415   va_start(ap, name);
00416   while ( (opcode = static_cast<TOP>(va_arg(ap,int))) != TOP_UNDEFINED ) {
00417     if (op_groups[(int)opcode]) {
00418       fprintf(stderr, 
00419               "### Error: Instruction_Group %s: redefines group (%s) for %s\n",
00420               name, op_groups[(int)opcode]->name, TOP_Name(opcode));
00421     }
00422     op_groups[(int)opcode] = oper_group;
00423   }
00424   va_end(ap);
00425 
00426   all_groups.push_back (oper_group);
00427 }
00428 
00429 
00431 void Operand (int operand_index, 
00432               OPERAND_VALUE_TYPE operand_type,
00433               OPERAND_USE_TYPE operand_use)
00435 //  See interface description.
00437 {
00438   if (operand_index > max_operands) max_operands = operand_index;
00439 
00440   if (operand_index >= cur_oper_group->opnd_count) {
00441     cur_oper_group->opnd_count = operand_index + 1;
00442   }
00443 
00444   int incr = (operand_index+1) - cur_oper_group->operands.size();
00445   if (incr > 0) {
00446     cur_oper_group->operands.insert(cur_oper_group->operands.end(),
00447                                     incr,
00448                                     (OPERAND_VALUE_TYPE)NULL);
00449     cur_oper_group->opnd_use.insert(cur_oper_group->opnd_use.end(),
00450                                     incr,
00451                                     (OPERAND_USE_TYPE)NULL);
00452   }
00453   cur_oper_group->operands[operand_index] = operand_type;
00454   cur_oper_group->opnd_use[operand_index] = operand_use;
00455 }
00456 
00458 void Relocatable (int operand_index)
00460 //  See interface description.
00462 {
00463   if (cur_oper_group->relocatable_opnd >= 0) {
00464     fprintf(stderr, "### Error: %s has more than one relocatable operand\n",
00465                     cur_oper_group->name);
00466     exit(EXIT_FAILURE);
00467   }
00468   cur_oper_group->relocatable_opnd = operand_index;
00469 }
00470 
00472 void Result (int result_index, OPERAND_VALUE_TYPE result_type)
00474 //  See interface description.
00476 {
00477   if (result_index > max_results) max_results = result_index;
00478 
00479   if (result_index >= cur_oper_group->result_count) {
00480     cur_oper_group->result_count = result_index + 1;
00481   }
00482 
00483   int incr = (result_index+1) - cur_oper_group->results.size();
00484   if (incr > 0) {
00485     cur_oper_group->results.insert(cur_oper_group->results.end(),
00486                                     incr,
00487                                     (OPERAND_VALUE_TYPE)NULL);
00488     cur_oper_group->res_use.insert(cur_oper_group->res_use.end(),
00489                                     incr,
00490                                     (OPERAND_USE_TYPE)NULL);
00491   }
00492   cur_oper_group->results[result_index] = result_type;
00493   cur_oper_group->res_use[result_index] = (OPERAND_USE_TYPE)NULL;
00494 }
00495 
00496 
00498 void ISA_Operands_End(void)
00500 //  See interface description.
00502 {
00503   list<OPERAND_VALUE_TYPE>::iterator ivti;
00504   list<OPERANDS_GROUP>::iterator ogi;
00505   list<OPERAND_USE_TYPE>::iterator iuti;
00506   int code;
00507   bool err;
00508   const char *info_index_type;
00509   int first_literal = max_operands;
00510   int last_literal = -1;
00511   int flag_mask = 0;
00512   unsigned long long use_mask = 0;
00513   const char *max_operands_name = "ISA_OPERAND_max_operands";
00514   const char *max_results_name = "ISA_OPERAND_max_results";
00515   enum {
00516     FLAG_IS_REG     = 0x1,
00517     FLAG_IS_SIGNED  = 0x2,
00518     FLAG_IS_FPU_INT = 0x4,
00519     FLAG_IS_PCREL   = 0x8
00520   };
00521 
00522   if (max_uses > 64 - 1) {
00523     fprintf(stderr, "###Error: can't handle > 63 (%d) OPERAND_USE_TYPEs\n",
00524                     max_uses);
00525     exit(EXIT_FAILURE);
00526   }
00527 
00528   for (err = false, code = 0; code < TOP_count; ++code) {
00529     if (!op_groups[code]) {
00530       fprintf (stderr, "###Error: no specification for opcode: %s\n",
00531                        TOP_Name((TOP)code));
00532       err = true;
00533     }
00534   }
00535   if (err) exit(EXIT_FAILURE);
00536 
00537 #define FNAME "targ_isa_operands"
00538   char filename[1000];
00539   sprintf (filename, "%s.h", FNAME);
00540   FILE* hfile = fopen(filename, "w");
00541   sprintf (filename, "%s.c", FNAME);
00542   FILE* cfile = fopen(filename, "w");
00543   sprintf (filename, "%s.Exported", FNAME);
00544   FILE* efile = fopen(filename, "w");
00545   int maxenum;
00546 
00547   fprintf(cfile,"#include \"%s.h\"\n", FNAME);
00548   fprintf(cfile,"#include \"targ_isa_registers.h\"\n");
00549   fprintf(cfile,"#include \"targ_isa_properties.h\"\n");
00550   fprintf(cfile,"#include \"targ_isa_lits.h\"\n\n");
00551 
00552   Emit_Header (hfile, "targ_isa_operands", interface);
00553 
00554   fprintf(hfile, "#include \"topcode.h\"\n");
00555   fprintf(hfile, "#include \"targ_isa_registers.h\"\n");
00556   fprintf(hfile, "#include \"targ_isa_enums.h\"\n");
00557   fprintf(hfile, "#include \"targ_isa_lits.h\"\n");
00558 
00559   fprintf(hfile, "\ntypedef enum {\n"
00560                  "  OU_UNDEFINED,\n");
00561   for (maxenum = 0, iuti = all_use_types.begin(); 
00562        iuti != all_use_types.end(); 
00563        ++maxenum, ++iuti)
00564   {
00565     OPERAND_USE_TYPE use_type = *iuti;
00566     fprintf(hfile, "  OU_%s,\n", use_type->name);
00567   }
00568   fprintf(hfile, "  OU_MAX = %d\n"
00569                  "} ISA_OPERAND_USE;\n",
00570                  maxenum);
00571 
00572   fprintf(hfile, "\ntypedef struct {\n"
00573                  "  mUINT8 rclass;\n"
00574                  "  mUINT8 rsubclass;\n"
00575                  "  mUINT8 lclass;\n"
00576                  "  mUINT8 eclass;\n"
00577                  "  mUINT8 size;\n"
00578                  "  mUINT8 flags;\n"
00579                  "} ISA_OPERAND_VALTYP;\n");
00580 
00581   fprintf(efile, "ISA_OPERAND_operand_types\n");
00582 
00583   fprintf(cfile, "\nconst ISA_OPERAND_VALTYP ISA_OPERAND_operand_types[] = {\n");
00584   for (ivti = all_operand_types.begin(); ivti != all_operand_types.end(); ++ivti) {
00585     unsigned int flags;
00586     OPERAND_VALUE_TYPE val_type = *ivti;
00587     const ISA_REGISTER_CLASS_INFO *rcinfo = ISA_REGISTER_CLASS_Info(val_type->register_class);
00588     const ISA_REGISTER_SUBCLASS_INFO *scinfo = ISA_REGISTER_SUBCLASS_Info(val_type->register_subclass);
00589     flags = 0;
00590     if (val_type->is_register) flags |= FLAG_IS_REG;
00591     if (val_type->is_signed) flags |= FLAG_IS_SIGNED;
00592     if (val_type->is_fpu_int) flags |= FLAG_IS_FPU_INT;
00593     if (val_type->is_pcrel) flags |= FLAG_IS_PCREL;
00594     flag_mask |= flags;
00595     fprintf(cfile, "  { ISA_REGISTER_CLASS_%-10s, ISA_REGISTER_SUBCLASS_%-10s,\n"
00596                    "    %3d, %s, %2d, 0x%02x }, /* %s */\n",
00597                    ISA_REGISTER_CLASS_INFO_Name(rcinfo),
00598                    ISA_REGISTER_SUBCLASS_INFO_Name(scinfo),
00599                    val_type->literal_class,
00600                    ISA_EC_Name(val_type->enum_class),
00601                    val_type->size,
00602                    flags,
00603                    val_type->name);
00604   }
00605   fprintf(cfile, "};\n");
00606 
00607   max_operands++;
00608   max_results++;
00609   fprintf (hfile, "\nenum {\n"
00610                   "  %s=%d,\n"
00611                   "  %s=%d\n"
00612                   "};\n",
00613                   max_operands_name, max_operands,
00614                   max_results_name, max_results);
00615 
00616   fprintf (hfile, "\ntypedef struct {\n"
00617                   "  mUINT8 opnds;\n"
00618                   "  mUINT8 opnd[%s];\n"
00619                   "  mUINT8 ouse[%s];\n"
00620                   "  mUINT8 results;\n"
00621                   "  mUINT8 result[%s];\n"
00622                   "} ISA_OPERAND_INFO;\n",
00623                   max_operands_name, max_operands_name, max_results_name);
00624   fprintf(efile, "ISA_OPERAND_info\n");
00625 
00626   fprintf(cfile, "\nconst ISA_OPERAND_INFO ISA_OPERAND_info[] = {\n");
00627   for (ogi = all_groups.begin(); ogi != all_groups.end(); ++ogi) {
00628     int i;
00629     int pos;
00630     vector<OPERAND_VALUE_TYPE>::iterator oper_iter;
00631     vector<OPERAND_USE_TYPE>::iterator use_iter;
00632     OPERANDS_GROUP oper_group = *ogi;
00633 
00634     pos = fprintf(cfile, "  { %d, {", oper_group->opnd_count);
00635     for (i = 0, oper_iter = oper_group->operands.begin(); 
00636          i < max_operands;
00637          ++i
00638     ) {
00639       int val_type_index = -1;
00640       if (oper_iter != oper_group->operands.end()) {
00641         OPERAND_VALUE_TYPE val_type = *oper_iter;
00642         if (val_type == NULL) {
00643           fprintf(stderr, "### Error: operand missing for %s\n", oper_group->name);
00644           exit(EXIT_FAILURE);
00645         }
00646         val_type_index = val_type->index;
00647         ++oper_iter;
00648 
00649         if (!val_type->is_register && val_type->literal_class != LC_UNDEFINED) {
00650 
00651           /* track the range of operands that can possibly be literal
00652            */
00653           if (i < first_literal) first_literal = i;
00654           if (i > last_literal) last_literal = i;
00655         }
00656       }
00657       pos += fprintf(cfile, "%s%3d", i == 0 ? " " : ", ", val_type_index);
00658     }
00659     fprintf(cfile, " },%*s/* %s */\n", 50 - (pos + 3), "", oper_group->name);
00660 
00661     pos = fprintf(cfile, "       {");
00662     for (i = 0, use_iter = oper_group->opnd_use.begin(); 
00663          i < max_operands;
00664          ++i
00665     ) {
00666       int use_type_index = 0;
00667       if (use_iter != oper_group->opnd_use.end()) {
00668         OPERAND_USE_TYPE use_type = *use_iter;
00669         if (use_type) {
00670           use_type_index = use_type->index + 1; // +1 for OU_UNDEFINED
00671           use_mask |= 1ULL << use_type_index;
00672         } else {
00673           use_mask |= 1; // OU_UNDEFINED
00674         }
00675         ++use_iter;
00676       }
00677       pos += fprintf(cfile, "%s%3d", i == 0 ? " " : ", ", use_type_index);
00678     }
00679     fprintf(cfile, " },%*s/* %s */\n", 50 - (pos + 3), "", oper_group->name);
00680 
00681     pos = fprintf(cfile, "    %d, {", oper_group->result_count);
00682     for (i = 0, oper_iter = oper_group->results.begin(); 
00683          i < max_results;
00684          ++i
00685     ) {
00686       int val_type_index = -1;
00687       if (oper_iter != oper_group->results.end()) {
00688         OPERAND_VALUE_TYPE val_type = *oper_iter;
00689         if (val_type == NULL) {
00690           fprintf(stderr, "### Error: result missing for %s\n", oper_group->name);
00691           exit(EXIT_FAILURE);
00692         }
00693         val_type_index = val_type->index;
00694          ++oper_iter;
00695       }
00696       pos += fprintf(cfile, "%s%3d", i == 0 ? " " : ", ", val_type_index);
00697     }
00698     fprintf(cfile, " } },%*s/* %s */\n", 50 - (pos + 5), "", oper_group->name);
00699   }
00700   fprintf(cfile, "};\n");
00701 
00702   info_index_type = max_groups < 256 ? "mUINT8" : "mUINT16";
00703   assert(max_groups <= 0xffff);
00704 
00705   fprintf (efile, "ISA_OPERAND_info_index\n");
00706   fprintf (cfile, "\nconst %s ISA_OPERAND_info_index[] = {\n", info_index_type);
00707   for (code = 0; code < TOP_count; code++) {
00708     OPERANDS_GROUP oper_group = op_groups[code];
00709     fprintf (cfile, "  %3d,  /* %s: %s */\n",
00710                     oper_group->index,
00711                     TOP_Name((TOP)code), 
00712                     oper_group->name);
00713   }
00714   fprintf (cfile, "};\n");
00715 
00716   fprintf(efile, "ISA_OPERAND_relocatable_opnd\n");
00717   fprintf(cfile, "\nconst mINT8 ISA_OPERAND_relocatable_opnd[] = {\n");
00718   for (code = 0; code < TOP_count; code++) {
00719     OPERANDS_GROUP oper_group = op_groups[code];
00720     fprintf(cfile, "  %2d,  /* %s */\n",
00721                    oper_group->relocatable_opnd,
00722                    TOP_Name((TOP)code));
00723   }
00724   fprintf (cfile, "};\n");
00725 
00726   fprintf(hfile, "\ninline const ISA_OPERAND_INFO *"
00727                    "ISA_OPERAND_Info(TOP topcode)\n"
00728                  "{\n"
00729                  "  extern const %s ISA_OPERAND_info_index[];\n"
00730                  "  extern const ISA_OPERAND_INFO ISA_OPERAND_info[];\n"
00731                  "  INT index = ISA_OPERAND_info_index[(INT)topcode];\n"
00732                  "  return &ISA_OPERAND_info[index];\n"
00733                  "}\n",
00734                  info_index_type);
00735 
00736   fprintf(hfile, "\ninline INT ISA_OPERAND_INFO_Operands("
00737                    "const ISA_OPERAND_INFO *oinfo)\n"
00738                  "{\n"
00739                  "  return oinfo->opnds;\n"
00740                  "}\n");
00741 
00742   fprintf(hfile, "\ninline const ISA_OPERAND_VALTYP *ISA_OPERAND_INFO_Operand(\n"
00743                  "  const ISA_OPERAND_INFO *oinfo,\n"
00744                  "  INT opnd)\n"
00745                  "{\n"
00746                  "  extern const ISA_OPERAND_VALTYP ISA_OPERAND_operand_types[];\n"
00747                  "  INT index = oinfo->opnd[opnd];\n"
00748                  "  return &ISA_OPERAND_operand_types[index];\n"
00749                  "}\n");
00750 
00751   fprintf(hfile, "\ninline INT ISA_OPERAND_INFO_Results("
00752                    "const ISA_OPERAND_INFO *oinfo)\n"
00753                  "{\n"
00754                  "  return oinfo->results;\n"
00755                  "}\n");
00756 
00757   fprintf(hfile, "\ninline const ISA_OPERAND_VALTYP *ISA_OPERAND_INFO_Result(\n"
00758                  "  const ISA_OPERAND_INFO *oinfo,\n"
00759                  "  INT result)\n"
00760                  "{\n"
00761                  "  extern const ISA_OPERAND_VALTYP ISA_OPERAND_operand_types[];\n"
00762                  "  INT index = oinfo->result[result];\n"
00763                  "  return &ISA_OPERAND_operand_types[index];\n"
00764                  "}\n");
00765 
00766   fprintf(hfile, "\ninline ISA_REGISTER_CLASS ISA_OPERAND_VALTYP_Register_Class(\n"
00767                  "  const ISA_OPERAND_VALTYP *otype)\n"
00768                  "{\n"
00769                  "  return (ISA_REGISTER_CLASS)otype->rclass;\n"
00770                  "}\n");
00771 
00772   fprintf(hfile, "\ninline ISA_REGISTER_SUBCLASS ISA_OPERAND_VALTYP_Register_Subclass(\n"
00773                  "  const ISA_OPERAND_VALTYP *otype)\n"
00774                  "{\n"
00775                  "  return (ISA_REGISTER_SUBCLASS)otype->rsubclass;\n"
00776                  "}\n");
00777 
00778   fprintf(hfile, "\ninline ISA_LIT_CLASS ISA_OPERAND_VALTYP_Literal_Class("
00779                    "const ISA_OPERAND_VALTYP *otype)\n"
00780                  "{\n"
00781                  "  return (ISA_LIT_CLASS)otype->lclass;\n"
00782                  "}\n");
00783 
00784   fprintf(hfile, "\ninline ISA_ENUM_CLASS ISA_OPERAND_VALTYP_Enum_Class(\n"
00785                  "  const ISA_OPERAND_VALTYP *otype)\n"
00786                  "{\n"
00787                  "  return (ISA_ENUM_CLASS)otype->eclass;\n"
00788                  "}\n");
00789 
00790   fprintf(hfile, "\ninline INT ISA_OPERAND_VALTYP_Size("
00791                    "const ISA_OPERAND_VALTYP *otype)\n"
00792                  "{\n"
00793                  "  return otype->size;\n"
00794                  "}\n");
00795 
00796   fprintf(hfile, "\ninline BOOL ISA_OPERAND_VALTYP_Is_Register("
00797                    "const ISA_OPERAND_VALTYP *otype)\n"
00798                  "{\n"
00799                  "  return (otype->flags & 0x%02x) != 0;\n"
00800                  "}\n",
00801                  FLAG_IS_REG);
00802 
00803   fprintf(hfile, "\ninline BOOL ISA_OPERAND_VALTYP_Is_Literal("
00804                    "const ISA_OPERAND_VALTYP *otype)\n"
00805                  "{\n"
00806                  "  return (otype->lclass != LC_UNDEFINED);\n"
00807                  "}\n");
00808 
00809   fprintf(hfile, "\ninline BOOL ISA_OPERAND_VALTYP_Is_Enum("
00810                    "const ISA_OPERAND_VALTYP *otype)\n"
00811                  "{\n"
00812                  "  return (otype->eclass != EC_UNDEFINED);\n"
00813                  "}\n");
00814 
00815   fprintf(hfile, "\ninline BOOL ISA_OPERAND_VALTYP_Is_Signed("
00816                    "const ISA_OPERAND_VALTYP *otype)\n"
00817                  "{\n"
00818                  "  return (otype->flags & 0x%02x) != 0;\n"
00819                  "}\n",
00820                  FLAG_IS_SIGNED);
00821 
00822   if (flag_mask & FLAG_IS_FPU_INT) {
00823     fprintf(hfile, "\ninline BOOL ISA_OPERAND_VALTYP_Is_FPU_Int("
00824                    "const ISA_OPERAND_VALTYP *otype)\n"
00825                    "{\n"
00826                    "  return (otype->flags & 0x%02x) != 0;\n"
00827                    "}\n",
00828                    FLAG_IS_FPU_INT);
00829   } else {
00830     fprintf(hfile, "\n/*ARGSUSED*/\n"
00831                    "inline BOOL ISA_OPERAND_VALTYP_Is_FPU_Int("
00832                    "const ISA_OPERAND_VALTYP *otype)\n"
00833                    "{\n"
00834                    "  return FALSE;\n"
00835                    "}\n");
00836   }
00837 
00838   fprintf(hfile, "\ninline BOOL ISA_OPERAND_VALTYP_Is_PCRel("
00839                    "const ISA_OPERAND_VALTYP *otype)\n"
00840                  "{\n"
00841                  "  return (otype->flags & 0x%02x) != 0;\n"
00842                  "}\n",
00843                  FLAG_IS_PCREL);
00844 
00845   fprintf(hfile, "\ninline ISA_OPERAND_USE ISA_OPERAND_INFO_Use(\n"
00846                  "  const ISA_OPERAND_INFO *oinfo,\n"
00847                  "  INT opnd)\n"
00848                  "{\n"
00849                  "  return (ISA_OPERAND_USE)oinfo->ouse[opnd];\n"
00850                  "}\n");
00851 
00852   fprintf(hfile, "\ninline BOOL ISA_OPERAND_Any_Use(ISA_OPERAND_USE ouse)\n"
00853                  "{\n"
00854                  "  return (0x%016llxULL & (1ULL << ouse)) != 0;\n"
00855                  "}\n",
00856                  use_mask);
00857 
00858   assert(first_literal <= last_literal); // incorrect if arch has no literals!
00859   fprintf(hfile, "\nextern INT TOP_Immediate_Operand(TOP topcode, ISA_LIT_CLASS *lclass);\n");
00860   fprintf(efile, "TOP_Immediate_Operand\n");
00861   fprintf(cfile, "\nINT TOP_Immediate_Operand(TOP topcode, ISA_LIT_CLASS *lclass)\n"
00862                  "{\n"
00863                  "  INT iopnd;\n"
00864                  "  const ISA_OPERAND_INFO *opinfo = ISA_OPERAND_Info(topcode);\n"
00865                  "  INT opnds = ISA_OPERAND_INFO_Operands(opinfo);\n"
00866                  "  const INT first = %d;\n",
00867                  first_literal);
00868   if (last_literal != max_operands - 1) {
00869     fprintf(cfile, "  const INT last = %d;\n"
00870                    "\n"
00871                    "  if (last + 1 < opnds) opnds = last + 1;\n",
00872                    last_literal);
00873   }
00874   fprintf(cfile, "\n"
00875                  "  for (iopnd = first; iopnd < opnds; ++iopnd) {\n"
00876                  "    const ISA_OPERAND_VALTYP *vtype = ISA_OPERAND_INFO_Operand(opinfo, iopnd);\n"
00877                  "    ISA_LIT_CLASS lit_class = ISA_OPERAND_VALTYP_Literal_Class(vtype);\n"
00878                  "    if (lit_class != LC_UNDEFINED) {\n"
00879                  "      if (lclass) *lclass = lit_class;\n"
00880                  "      return iopnd;\n"
00881                  "    }\n"
00882                  "  }\n"
00883                  "\n"
00884                  "  return -1;\n"
00885                  "}\n");
00886 
00887   fprintf(hfile, "\nextern INT TOP_Relocatable_Operand(TOP topcode, ISA_LIT_CLASS *lclass);\n");
00888   fprintf(efile, "TOP_Relocatable_Operand\n");
00889   fprintf(cfile, "\nINT TOP_Relocatable_Operand(TOP topcode, ISA_LIT_CLASS *lclass)\n"
00890                  "{\n"
00891                  "  extern const mINT8 ISA_OPERAND_relocatable_opnd[];\n"
00892                  "  INT iopnd = ISA_OPERAND_relocatable_opnd[(INT)topcode];\n"
00893                  "  if (lclass && iopnd >= 0) {\n"
00894                  "    const ISA_OPERAND_INFO *opinfo = ISA_OPERAND_Info(topcode);\n"
00895                  "    const ISA_OPERAND_VALTYP *vtype = ISA_OPERAND_INFO_Operand(opinfo,iopnd);\n"
00896                  "    *lclass = (ISA_LIT_CLASS)ISA_OPERAND_VALTYP_Literal_Class(vtype);\n"
00897                  "  }\n"
00898                  "  return iopnd;\n"
00899                  "}\n");
00900 
00901   fprintf(hfile, "\nextern BOOL TOP_Can_Have_Immediate(INT64 value, TOP topcode);\n");
00902   fprintf(efile, "TOP_Can_Have_Immediate\n");
00903   fprintf(cfile, "\nBOOL TOP_Can_Have_Immediate(INT64 value, TOP topcode)\n"
00904                  "{\n"
00905                  "  ISA_LIT_CLASS lclass;\n"
00906                  "  if (TOP_Immediate_Operand(topcode, &lclass) < 0) return %d;\n"
00907                  "  return ISA_LC_Value_In_Class(value, lclass);\n"
00908                  "}\n",
00909                  false);
00910 
00911   fprintf(hfile, "\nextern INT TOP_Find_Operand_Use(TOP topcode, "
00912                  "ISA_OPERAND_USE use);\n");
00913   fprintf(efile, "TOP_Find_Operand_Use\n");
00914   fprintf(cfile, "\nINT TOP_Find_Operand_Use(TOP topcode, ISA_OPERAND_USE use)\n"
00915                  "{\n"
00916                  "  INT i;\n"
00917                  "  const ISA_OPERAND_INFO *oinfo = ISA_OPERAND_Info(topcode);\n"
00918                  "  INT opnds = ISA_OPERAND_INFO_Operands(oinfo);\n"
00919                  "  for (i = 0; i < opnds; ++i) {\n"
00920                  "    ISA_OPERAND_USE this_use = ISA_OPERAND_INFO_Use(oinfo, i);\n"
00921                  "    if (this_use == use) return i;\n"
00922                  "  }\n"
00923                  "  return -1;\n"
00924                  "}\n");
00925 
00926   fprintf(hfile, "\nextern void TOP_Operand_Uses(TOP topcode, "
00927                  "ISA_OPERAND_USE *uses);\n");
00928   fprintf(efile, "TOP_Operand_Uses\n");
00929   fprintf(cfile, "\nvoid TOP_Operand_Uses(TOP topcode, ISA_OPERAND_USE *uses)\n"
00930                  "{\n"
00931                  "  INT i;\n"
00932                  "  const ISA_OPERAND_INFO *oinfo = ISA_OPERAND_Info(topcode);\n"
00933                  "  INT opnds = ISA_OPERAND_INFO_Operands(oinfo);\n"
00934                  "  for (i = 0; i < opnds; ++i) {\n"
00935                  "    ISA_OPERAND_USE this_use = ISA_OPERAND_INFO_Use(oinfo, i);\n"
00936                  "    uses[i] = this_use;\n"
00937                  "  }\n"
00938                  "}\n");
00939 
00940   Emit_Footer (hfile);
00941 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines