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