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
00038
00039
00040
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;
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;
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;
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
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* )
00260
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
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
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
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
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
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
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
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
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
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
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;
00671 use_mask |= 1ULL << use_type_index;
00672 } else {
00673 use_mask |= 1;
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);
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 }