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
00046
00048
00049
00050
00051
00052
00053
00054 #include <strings.h>
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 "gen_util.h"
00062 #include "targ_isa_registers.h"
00063 #include "abi_properties_gen.h"
00064 #include "bstring.h"
00065
00066
00067
00068
00069 struct abi_property {
00070 const char* name;
00071 bool single_class;
00072 bool single_reg;
00073 ISA_REGISTER_CLASS rc;
00074 INT reg[ISA_REGISTER_CLASS_MAX+1];
00075 unsigned long long val;
00076 };
00077
00078
00079
00080
00081 #define NUM_REGISTERS_LIMIT 1000
00082
00083 typedef struct {
00084 ISA_REGISTER_CLASS rc;
00085 INT reg;
00086 const char *name;
00087 } REG_NAME;
00088
00089 typedef struct {
00090 ISA_REGISTER_CLASS rc;
00091
00092
00093 INT minreg;
00094 INT maxreg;
00095 ABI_PROPERTY aprop;
00096 } ABI_PROPERTY_INFO;
00097
00098
00099
00100
00101 typedef struct abi {
00102 const char *name;
00103 #if 0
00104
00105 std::list<ABI_PROPERTY> flags;
00106 std::list<ABI_PROPERTY> values;
00107 #endif
00108 #if ISA_REGISTER_MAX < NUM_REGISTERS_LIMIT
00109 std::list<ABI_PROPERTY> reg_flags[ISA_REGISTER_CLASS_MAX+1][ISA_REGISTER_MAX+1];
00110
00111 #if 0
00112
00113 std::list<ABI_PROPERTY> reg_values[ISA_REGISTER_CLASS_MAX+1][ISA_REGISTER_MAX+1];
00114
00115 #endif
00116 const char *reg_names[ISA_REGISTER_CLASS_MAX+1][ISA_REGISTER_MAX+1];
00117
00118 #else
00119 std::list<ABI_PROPERTY_INFO> reg_flags;
00120 std::list<REG_NAME> reg_names;
00121 #endif
00122 } *ABI;
00123
00124
00125 static std::list<ABI_PROPERTY> props;
00126 static std::list<ABI> abis;
00127 static ABI current_abi;
00128 static int prop_count = 0;
00129
00130 static const char * const interface[] = {
00131 "/* ====================================================================",
00132 " * ====================================================================",
00133 " *",
00134 " * Description:",
00135 " *",
00136 " * A description of the ABI properties. The description exports",
00137 " * the following:",
00138 " *",
00139 " * typedef (enum) ABI_PROPERTIES_ABI",
00140 " *",
00141 " * An enumeration of the ABIs described. The names have the form:",
00142 " *",
00143 " * ABI_PROPERTIES_ABI_xxx",
00144 " *",
00145 " * where 'xxx' is replaced with the ABI name.",
00146 " *",
00147 " * const ABI_PROPERTIES_ABI ABI_PROPERTIES_ABI_UNDEFINED",
00148 " * Useful value guaranteed not to be a valid ABI_PROPERTIES_ABI.",
00149 " *",
00150 " * ABI_PROPERTIES_ABI ABI_PROPERTIES_ABI_Value",
00151 " * A variable containing the current ABI value.",
00152 " *",
00153 " * const char *ABI_PROPERTIES_ABI_Name(ABI_PROPERTIES_ABI abi)",
00154 " * Returns a name for the given 'abi'.",
00155 " *",
00156 " * void ABI_PROPERTIES_Initialize(void)",
00157 " * Initialize for the target ABI specified by ABI_PROPERTIES_ABI_Value.",
00158 " *",
00159 " * const char *ABI_PROPERTY_Reg_Name(",
00160 " * ISA_REGISTER_CLASS rc,",
00161 " * INT reg",
00162 " * )",
00163 " * Return the ABI specific name of register 'reg' in class 'rc'.",
00164 " *",
00165 " * BOOL ABI_PROPERTY_Is_xxx(",
00166 " * ISA_REGISTER_CLASS rc,",
00167 " * INT reg",
00168 " * )",
00169 " * Return a boolean that indicates if register 'reg' in class",
00170 " * 'rc' had the property 'xxx'.",
00171 " *",
00172 " * ====================================================================",
00173 " * ====================================================================",
00174 " */",
00175 NULL
00176 };
00177
00178
00180 void ABI_Properties_Begin(const char * )
00182
00184 {
00185 }
00186
00187
00189 ABI_PROPERTY Create_Reg_Property(const char *name)
00191
00193 {
00194 ABI_PROPERTY result = new abi_property;
00195
00196 result->name = name;
00197 result->val = 0;
00198 result->rc = ISA_REGISTER_CLASS_UNDEFINED;
00199 int rc;
00200 for (rc = 0; rc <= ISA_REGISTER_CLASS_MAX; ++rc)
00201 result->reg[rc] = -1;
00202 result->single_class = false;
00203 result->single_reg = false;
00204
00205 props.push_back(result);
00206 return result;
00207 }
00208
00209
00211 void Begin_ABI(const char *name)
00213
00215 {
00216 ABI result = new abi;
00217
00218 result->name = name;
00219 #if ISA_REGISTER_MAX < NUM_REGISTERS_LIMIT
00220 BZERO(result->reg_names, sizeof(result->reg_names));
00221 #endif
00222
00223 current_abi = result;
00224
00225 abis.push_back(result);
00226 }
00227
00228
00230 void Reg_Property(ABI_PROPERTY prop, ISA_REGISTER_CLASS rc, ...)
00232
00234 {
00235 va_list ap;
00236 int reg_num;
00237 bool used = false;
00238 int count = 0;
00239 int firstreg = -1;
00240
00241 va_start(ap,rc);
00242 while ( (reg_num = va_arg(ap,int)) != -1 ) {
00243 if (firstreg == -1)
00244 firstreg = reg_num;
00245 #if ISA_REGISTER_MAX < NUM_REGISTERS_LIMIT
00246 current_abi->reg_flags[rc][reg_num].push_back(prop);
00247 #else
00248 {
00249 ABI_PROPERTY_INFO api = {rc, reg_num, reg_num, prop};
00250 current_abi->reg_flags.push_back(api);
00251 }
00252 #endif
00253 used = true;
00254 ++count;
00255 }
00256 va_end(ap);
00257
00258 if (used && prop->val == 0) {
00259 prop->val = 1ULL << prop_count;
00260 ++prop_count;
00261 prop->single_class = true;
00262 if (count == 1)
00263 prop->single_reg = true;
00264 else
00265 prop->single_reg = false;
00266 prop->rc = rc;
00267 }
00268 else {
00269
00270 prop->single_class = false;
00271 }
00272 prop->reg[rc] = firstreg;
00273 }
00274
00276 void Reg_Property_Range(ABI_PROPERTY prop, ISA_REGISTER_CLASS rc, INT minreg, INT maxreg)
00278
00280 {
00281 int reg_num;
00282 bool used = false;
00283
00284 #if ISA_REGISTER_MAX < NUM_REGISTERS_LIMIT
00285 for (reg_num = minreg; reg_num <= maxreg; ++reg_num) {
00286 current_abi->reg_flags[rc][reg_num].push_back(prop);
00287 used = true;
00288 }
00289 #else
00290 ABI_PROPERTY_INFO api = {rc, minreg, maxreg, prop};
00291 current_abi->reg_flags.push_back(api);
00292 used = true;
00293 #endif
00294
00295 if (used && prop->val == 0) {
00296 prop->val = 1ULL << prop_count;
00297 ++prop_count;
00298 prop->rc = rc;
00299 prop->single_class = true;
00300 }
00301 else {
00302 prop->single_class = false;
00303 }
00304 prop->reg[rc] = minreg;
00305 }
00306
00307
00308 void Set_Reg_Name(ISA_REGISTER_CLASS rc, INT reg, const char *name)
00309 {
00310 #if ISA_REGISTER_MAX < NUM_REGISTERS_LIMIT
00311 current_abi->reg_names[rc][reg] = name;
00312 #else
00313 REG_NAME rn = {rc, reg, name};
00314 current_abi->reg_names.push_back(rn);
00315 #endif
00316 }
00317
00319 void Reg_Names(ISA_REGISTER_CLASS rc, INT minreg, INT maxreg, const char **names)
00321
00323 {
00324 int reg_num;
00325 for (reg_num = minreg; reg_num <= maxreg; ++reg_num) {
00326 Set_Reg_Name (rc, reg_num, names[reg_num - minreg]);
00327 }
00328 }
00329
00331 static const char *Type_Name(int bits)
00333
00334
00336 {
00337 if (bits <= 8) {
00338 return "mUINT8";
00339 } else if (bits <= 16) {
00340 return "mUINT16";
00341 } else if (bits <= 32) {
00342 return "mUINT32";
00343 } else {
00344 assert (bits <= 64);
00345 return "mUINT64";
00346 }
00347 }
00348
00349
00351 static const char *Type_Suffix(int bits)
00353
00354
00355
00357 {
00358 if (bits <= 8) {
00359 return "";
00360 } else if (bits <= 16) {
00361 return "";
00362 } else if (bits <= 32) {
00363 return "U";
00364 } else {
00365 assert (bits <= 64);
00366 return "ULL";
00367 }
00368 }
00369
00370
00372 static int Type_Size(int bits)
00374
00375
00377 {
00378 if (bits <= 8) {
00379 return 8;
00380 } else if (bits <= 16) {
00381 return 16;
00382 } else if (bits <= 32) {
00383 return 32;
00384 } else {
00385 assert (bits <= 64);
00386 return 64;
00387 }
00388 }
00389
00390
00392 void ABI_Properties_End(void)
00394
00396 {
00397 std::list<ABI_PROPERTY>::iterator prop_iter;
00398 std::list<ABI>::iterator abi_iter;
00399
00400 char filename[1000];
00401 sprintf (filename, "targ_abi_properties.h");
00402 FILE* hfile = fopen(filename, "w");
00403 sprintf (filename, "targ_abi_properties.c");
00404 FILE* cfile = fopen(filename, "w");
00405 sprintf(filename,"targ_abi_properties.Exported");
00406 FILE* efile = fopen(filename,"w");
00407
00408 fprintf(cfile,"#include \"targ_abi_properties.h\"\n\n");
00409
00410 sprintf (filename, "targ_abi_properties");
00411 Emit_Header (hfile, filename, interface);
00412 fprintf(hfile,"#include \"targ_isa_registers.h\"\n");
00413
00414
00415
00416
00417 fprintf(hfile, "\ntypedef struct {\n");
00418
00419 if (prop_count != 0) {
00420 fprintf(hfile, " %s reg_flags[%d][%d];\n",
00421 Type_Name(prop_count),
00422 ISA_REGISTER_CLASS_MAX+1,
00423 ISA_REGISTER_MAX+1);
00424 }
00425 fprintf(hfile, " const char *reg_names[%d][%d];\n",
00426 ISA_REGISTER_CLASS_MAX+1,
00427 ISA_REGISTER_MAX+1);
00428 fprintf(hfile, "} ABI_PROPERTIES;\n");
00429
00430
00431
00432
00433 fprintf(hfile, "\n");
00434 for (prop_iter = props.begin(); prop_iter != props.end(); ++prop_iter) {
00435 ABI_PROPERTY prop = *prop_iter;
00436 fprintf(hfile, "#define ABI_PROPERTY_%-20s 0x%0*" LL_FORMAT "x%s\n",
00437 prop->name,
00438 Type_Size(prop_count) / 4,
00439 prop->val,
00440 Type_Suffix(prop_count));
00441 }
00442
00443
00444
00445
00446 int num_abi = 0;
00447 fprintf(hfile, "\ntypedef enum {\n");
00448 fprintf(cfile, "\nstatic const ABI_PROPERTIES abi_properties[] = {\n");
00449 for (abi_iter = abis.begin(); abi_iter != abis.end(); ++abi_iter) {
00450 int rc;
00451 ABI abi = *abi_iter;
00452 ++num_abi;
00453
00454 fprintf(hfile, " ABI_PROPERTIES_ABI_%s,\n", abi->name);
00455
00456 fprintf(cfile, " {\n"
00457 " /* %s */\n",
00458 abi->name);
00459
00460 int count = prop_count;
00461 if (count != 0) {
00462 fprintf(cfile, " {\n");
00463 for (rc = 0; rc <= ISA_REGISTER_CLASS_MAX; ++rc) {
00464 int reg;
00465 const ISA_REGISTER_CLASS_INFO *cinfo
00466 = ISA_REGISTER_CLASS_Info((ISA_REGISTER_CLASS)rc);
00467
00468 fprintf(cfile, " /* ISA_REGISTER_CLASS_%s */\n",
00469 ISA_REGISTER_CLASS_INFO_Name(cinfo));
00470 int cursor = fprintf(cfile, " {");
00471 for (reg = 0; reg <= ISA_REGISTER_MAX; ++reg) {
00472 unsigned long long mask = 0;
00473 #if ISA_REGISTER_MAX < NUM_REGISTERS_LIMIT
00474 std::list<ABI_PROPERTY> props = abi->reg_flags[rc][reg];
00475 for (prop_iter = props.begin(); prop_iter != props.end(); ++prop_iter) {
00476 ABI_PROPERTY prop = *prop_iter;
00477 mask |= prop->val;
00478 }
00479 #else
00480 std::list<ABI_PROPERTY_INFO>::iterator api_iter;
00481 for (api_iter = abi->reg_flags.begin();
00482 api_iter != abi->reg_flags.end();
00483 ++api_iter)
00484 {
00485 ABI_PROPERTY_INFO api = *api_iter;
00486 if (api.rc == rc && reg >= api.minreg && reg <= api.maxreg) {
00487 ABI_PROPERTY prop = api.aprop;
00488 mask |= prop->val;
00489 }
00490 }
00491 #endif
00492 if (cursor >= 80 - (4 + Type_Size(count) / 4) - 3 - 1) {
00493 fprintf(cfile, "\n");
00494 cursor = fprintf(cfile, " ");
00495 }
00496 cursor += fprintf(cfile, " 0x%0*" LL_FORMAT "x%s,",
00497 Type_Size(count) / 4,
00498 mask,
00499 Type_Suffix(count));
00500 }
00501 fprintf(cfile, " },\n");
00502 }
00503 fprintf(cfile, " },\n");
00504 }
00505
00506 fprintf(cfile, " {\n");
00507 for (rc = 0; rc <= ISA_REGISTER_CLASS_MAX; ++rc) {
00508 int reg;
00509 const ISA_REGISTER_CLASS_INFO *cinfo
00510 = ISA_REGISTER_CLASS_Info((ISA_REGISTER_CLASS)rc);
00511
00512 fprintf(cfile, " /* ISA_REGISTER_CLASS_%s */\n",
00513 ISA_REGISTER_CLASS_INFO_Name(cinfo));
00514 int cursor = fprintf(cfile, " {");
00515 for (reg = 0; reg <= ISA_REGISTER_MAX; ++reg) {
00516 const char *name;
00517 #if ISA_REGISTER_MAX < NUM_REGISTERS_LIMIT
00518 name = abi->reg_names[rc][reg];
00519 #else
00520 name = NULL;
00521 std::list<REG_NAME>::iterator rn_iter;
00522 for (rn_iter = abi->reg_names.begin();
00523 rn_iter != abi->reg_names.end();
00524 ++rn_iter)
00525 {
00526 REG_NAME rn = *rn_iter;
00527 if (rn.rc == rc && rn.reg == reg) {
00528 name = rn.name;
00529 break;
00530 }
00531 }
00532 #endif
00533 if (name == NULL) name = ISA_REGISTER_CLASS_INFO_Reg_Name(cinfo, reg);
00534 if (name == NULL) name = "";
00535 if (cursor >= 80 - (4 + strlen(name))) {
00536 fprintf(cfile, "\n");
00537 cursor = fprintf(cfile, " ");
00538 }
00539 cursor += fprintf(cfile, " \"%s\",", name);
00540 }
00541 fprintf(cfile, " },\n");
00542 }
00543 fprintf(cfile, " },\n");
00544
00545 fprintf(cfile, " },\n");
00546 }
00547 fprintf(cfile, "};\n");
00548 fprintf(hfile, " ABI_PROPERTIES_ABI_UNDEFINED,\n"
00549 " ABI_PROPERTIES_ABI_MAX=%d\n"
00550 "} ABI_PROPERTIES_ABI;\n",
00551 num_abi-1);
00552
00553
00554
00555
00556 fprintf(cfile, "\nstatic const char * const abi_names[] = {\n");
00557 for (abi_iter = abis.begin(); abi_iter != abis.end(); ++abi_iter) {
00558 ABI abi = *abi_iter;
00559 fprintf(cfile, " \"%s\",\n", abi->name);
00560 }
00561 fprintf(cfile, " \"UNDEFINED\"\n"
00562 "};\n");
00563
00564
00565
00566
00567 fprintf(hfile, "\nextern ABI_PROPERTIES_ABI ABI_PROPERTIES_ABI_Value;\n");
00568 fprintf(cfile, "\nABI_PROPERTIES_ABI ABI_PROPERTIES_ABI_Value = ABI_PROPERTIES_ABI_UNDEFINED;\n");
00569 fprintf(efile, "ABI_PROPERTIES_ABI_Value\n");
00570
00571 fprintf(hfile, "\nextern const char *ABI_PROPERTIES_ABI_Name(ABI_PROPERTIES_ABI abi);\n");
00572 fprintf(cfile, "\nconst char *ABI_PROPERTIES_ABI_Name(ABI_PROPERTIES_ABI abi)\n"
00573 "{\n"
00574 " return abi_names[(INT)abi];\n"
00575 "}\n");
00576 fprintf(efile, "ABI_PROPERTIES_Initialize\n");
00577
00578 fprintf(cfile, "\nconst ABI_PROPERTIES *ABI_PROPERTIES_target_props"
00579 " = &abi_properties[ABI_PROPERTIES_ABI_UNDEFINED];\n");
00580 fprintf(efile, "ABI_PROPERTIES_target_props\n");
00581
00582 fprintf(hfile, "\nextern void ABI_PROPERTIES_Initialize(void);\n");
00583 fprintf(cfile, "\nvoid ABI_PROPERTIES_Initialize(void)\n"
00584 "{\n"
00585 " ABI_PROPERTIES_target_props = &abi_properties[(INT)ABI_PROPERTIES_ABI_Value];\n"
00586 "}\n");
00587 fprintf(efile, "ABI_PROPERTIES_Initialize\n");
00588
00589
00590
00591
00592 fprintf(hfile, "\ninline const char *ABI_PROPERTY_Reg_Name(\n"
00593 " ISA_REGISTER_CLASS rc,\n"
00594 " INT reg)\n"
00595 "{\n"
00596 " extern const ABI_PROPERTIES *ABI_PROPERTIES_target_props;\n"
00597 " return ABI_PROPERTIES_target_props->reg_names[rc][reg];\n"
00598 "}\n");
00599
00600 for (prop_iter = props.begin(); prop_iter != props.end(); ++prop_iter) {
00601 ABI_PROPERTY prop = *prop_iter;
00602 fputs(prop->val ? "\n" : "\n/*ARGSUSED*/\n", hfile);
00603 fprintf(hfile, "inline BOOL ABI_PROPERTY_Is_%s(\n"
00604 " ISA_REGISTER_CLASS rc,\n"
00605 " INT reg)\n"
00606 "{\n",
00607 prop->name);
00608 if (prop->val == 0) {
00609 fprintf(hfile, " return FALSE;\n"
00610 "}\n");
00611 } else {
00612 fprintf(hfile, " extern const ABI_PROPERTIES *ABI_PROPERTIES_target_props;\n"
00613 " return ( ABI_PROPERTIES_target_props->reg_flags[rc][reg]\n"
00614 " & ABI_PROPERTY_%s) != 0;\n"
00615 "}\n",
00616 prop->name);
00617 }
00618 }
00619
00620
00621
00622
00623
00624 fprintf(hfile, "\n");
00625 fprintf(hfile, "/* For properties that map to only one register,\n");
00626 fprintf(hfile, " * create accessor routines for those registers.\n");
00627 fprintf(hfile, " * If they map to multiple registers,\n");
00628 fprintf(hfile, " * create accessor routines for first register.\n");
00629 fprintf(hfile, " */\n");
00630 for (prop_iter = props.begin(); prop_iter != props.end(); ++prop_iter) {
00631 ABI_PROPERTY prop = *prop_iter;
00632 if (prop->rc == ISA_REGISTER_CLASS_UNDEFINED) {
00633 continue;
00634 }
00635 const ISA_REGISTER_CLASS_INFO *cinfo = ISA_REGISTER_CLASS_Info(prop->rc);
00636 if (prop->single_class) {
00637 fprintf(hfile, "#define ABI_PROPERTY_%s_Register_Class ISA_REGISTER_CLASS_%s\n",
00638 prop->name, ISA_REGISTER_CLASS_INFO_Name(cinfo));
00639 if (prop->single_reg)
00640 fprintf(hfile, "#define ABI_PROPERTY_%s_Register %d\n",
00641 prop->name, prop->reg[prop->rc]);
00642 else
00643 fprintf(hfile, "#define ABI_PROPERTY_%s_First_Register %d\n",
00644 prop->name, prop->reg[prop->rc]);
00645 }
00646 else {
00647 int rc;
00648 for (rc = 1; rc <= ISA_REGISTER_CLASS_MAX; ++rc) {
00649 if (prop->reg[rc] != -1) {
00650 if (prop->single_reg)
00651 fprintf(hfile, "#define ABI_PROPERTY_%s_%s_Register %d\n",
00652 ISA_REGISTER_CLASS_INFO_Name(
00653 ISA_REGISTER_CLASS_Info((ISA_REGISTER_CLASS)rc)),
00654 prop->name, prop->reg[rc]);
00655 else
00656 fprintf(hfile, "#define ABI_PROPERTY_%s_%s_First_Register %d\n",
00657 ISA_REGISTER_CLASS_INFO_Name(
00658 ISA_REGISTER_CLASS_Info((ISA_REGISTER_CLASS)rc)),
00659 prop->name, prop->reg[rc]);
00660 }
00661 }
00662 }
00663 fprintf(hfile, "\n");
00664 }
00665
00666 Emit_Footer (hfile);
00667 }