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