Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 // isa_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 }