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
00042
00044
00045
00046 #include <cstring>
00047 #include <cstddef>
00048 #include <cstdlib>
00049 #include <cstdarg>
00050 #include <cstdio>
00051 #include <cassert>
00052
00053 #include <list>
00054
00055 using namespace std;
00056
00057 #include "gen_util.h"
00058 #include "targ_isa_registers.h"
00059 #include "abi_properties_gen.h"
00060
00061
00062
00063
00064 struct abi_property {
00065 const char* name;
00066 bool is_reg;
00067 bool is_flag;
00068 unsigned long long v;
00069 };
00070
00071
00072
00073
00074 typedef struct abi {
00075 const char *name;
00076 list<ABI_PROPERTY> flags;
00077 list<ABI_PROPERTY> values;
00078 list<ABI_PROPERTY> reg_flags[ISA_REGISTER_CLASS_MAX+1][ISA_REGISTER_MAX+1];
00079
00080 list<ABI_PROPERTY> reg_values[ISA_REGISTER_CLASS_MAX+1][ISA_REGISTER_MAX+1];
00081
00082 const char *reg_names[ISA_REGISTER_CLASS_MAX+1][ISA_REGISTER_MAX+1];
00083
00084 } *ABI;
00085
00086
00087 static list<ABI_PROPERTY> props;
00088 static list<ABI> abis;
00089 static ABI current_abi;
00090 static int prop_count[2 ][2 ] = {0};
00091
00092
00093 static const char * const interface[] = {
00094 "/* ====================================================================",
00095 " * ====================================================================",
00096 " *",
00097 " * Description:",
00098 " *",
00099 " * A description of the ABI properties. The description exports",
00100 " * the following:",
00101 " *",
00102 " * typedef (enum) ABI_PROPERTIES_ABI",
00103 " *",
00104 " * An enumeration of the ABIs described. The names have the form:",
00105 " *",
00106 " * ABI_PROPERTIES_ABI_xxx",
00107 " *",
00108 " * where 'xxx' is replaced with the ABI name.",
00109 " *",
00110 " * const ABI_PROPERTIES_ABI ABI_PROPERTIES_ABI_UNDEFINED",
00111 " * Useful value guaranteed not to be a valid ABI_PROPERTIES_ABI.",
00112 " *",
00113 " * ABI_PROPERTIES_ABI ABI_PROPERTIES_ABI_Value",
00114 " * A variable containing the current ABI value.",
00115 " *",
00116 " * const char *ABI_PROPERTIES_ABI_Name(ABI_PROPERTIES_ABI abi)",
00117 " * Returns a name for the given 'abi'.",
00118 " *",
00119 " * void ABI_PROPERTIES_Initialize(void)",
00120 " * Initialize for the target ABI specified by ABI_PROPERTIES_ABI_Value.",
00121 " *",
00122 " * const char *ABI_PROPERTY_Reg_Name(",
00123 " * ISA_REGISTER_CLASS rc,",
00124 " * INT reg",
00125 " * )",
00126 " * Return the ABI specific name of register 'reg' in class 'rc'.",
00127 " *",
00128 " * BOOL ABI_PROPERTY_Is_xxx(",
00129 " * ISA_REGISTER_CLASS rc,",
00130 " * INT reg",
00131 " * )",
00132 " * Return a boolean that indicates if register 'reg' in class",
00133 " * 'rc' had the property 'xxx'.",
00134 " *",
00135 " * ====================================================================",
00136 " * ====================================================================",
00137 " */",
00138 NULL
00139 };
00140
00141
00143 void ABI_Properties_Begin(const char * )
00145
00147 {
00148 }
00149
00150
00152 ABI_PROPERTY Create_Reg_Property(const char *name)
00154
00156 {
00157 ABI_PROPERTY result = new abi_property;
00158
00159 result->name = name;
00160 result->is_reg = true;
00161 result->is_flag = true;
00162 result->v = 0;
00163
00164 props.push_back(result);
00165
00166 return result;
00167 }
00168
00169
00171 void Begin_ABI(const char *name)
00173
00175 {
00176 ABI result = new abi;
00177
00178 result->name = name;
00179 bzero(result->reg_names, sizeof(result->reg_names));
00180
00181 current_abi = result;
00182
00183 abis.push_back(result);
00184 }
00185
00186
00188 void Reg_Property(ABI_PROPERTY prop, ISA_REGISTER_CLASS rc, ...)
00190
00192 {
00193 va_list ap;
00194 int reg_num;
00195 bool used = false;
00196
00197 va_start(ap,rc);
00198 while ( (reg_num = va_arg(ap,int)) != -1 ) {
00199 current_abi->reg_flags[rc][reg_num].push_back(prop);
00200 used = true;
00201 }
00202 va_end(ap);
00203
00204 if (used && prop->v == 0) {
00205 prop->v = 1ULL << prop_count[true][true];
00206 ++prop_count[true][true];
00207 }
00208 }
00209
00210
00212 void Reg_Names(ISA_REGISTER_CLASS rc, INT minreg, INT maxreg, const char **names)
00214
00216 {
00217 int reg_num;
00218 for (reg_num = minreg; reg_num <= maxreg; ++reg_num) {
00219 current_abi->reg_names[rc][reg_num] = names[reg_num - minreg];
00220 }
00221 }
00222
00223
00225 static const char *Type_Name(int bits)
00227
00228
00230 {
00231 if (bits <= 8) {
00232 return "mUINT8";
00233 } else if (bits <= 16) {
00234 return "mUINT16";
00235 } else if (bits <= 32) {
00236 return "mUINT32";
00237 } else {
00238 assert (bits <= 64);
00239 return "mUINT64";
00240 }
00241 }
00242
00243
00245 static const char *Type_Suffix(int bits)
00247
00248
00249
00251 {
00252 if (bits <= 8) {
00253 return "";
00254 } else if (bits <= 16) {
00255 return "";
00256 } else if (bits <= 32) {
00257 return "U";
00258 } else {
00259 assert (bits <= 64);
00260 return "ULL";
00261 }
00262 }
00263
00264
00266 static int Type_Size(int bits)
00268
00269
00271 {
00272 if (bits <= 8) {
00273 return 8;
00274 } else if (bits <= 16) {
00275 return 16;
00276 } else if (bits <= 32) {
00277 return 32;
00278 } else {
00279 assert (bits <= 64);
00280 return 64;
00281 }
00282 }
00283
00284
00286 void ABI_Properties_End(void)
00288
00290 {
00291 list<ABI_PROPERTY>::iterator prop_iter;
00292 list<ABI>::iterator abi_iter;
00293
00294 char filename[1000];
00295 sprintf (filename, "targ_abi_properties.h");
00296 FILE* hfile = fopen(filename, "w");
00297 sprintf (filename, "targ_abi_properties.c");
00298 FILE* cfile = fopen(filename, "w");
00299 sprintf(filename,"targ_abi_properties.Exported");
00300 FILE* efile = fopen(filename,"w");
00301
00302 fprintf(cfile,"#include \"targ_abi_properties.h\"\n\n");
00303
00304 sprintf (filename, "targ_abi_properties");
00305 Emit_Header (hfile, filename, interface);
00306 fprintf(hfile,"#include \"targ_isa_registers.h\"\n");
00307
00308
00309
00310
00311 fprintf(hfile, "\ntypedef struct {\n");
00312 if (prop_count[true][false] != 0) {
00313 fprintf(hfile, " %s flags;\n", Type_Name(prop_count[true][false]));
00314 }
00315 if (prop_count[true][true] != 0) {
00316 fprintf(hfile, " %s reg_flags[%d][%d];\n",
00317 Type_Name(prop_count[true][true]),
00318 ISA_REGISTER_CLASS_MAX+1,
00319 ISA_REGISTER_MAX+1);
00320 }
00321 fprintf(hfile, " const char *reg_names[%d][%d];\n",
00322 ISA_REGISTER_CLASS_MAX+1,
00323 ISA_REGISTER_MAX+1);
00324 fprintf(hfile, "} ABI_PROPERTIES;\n");
00325
00326
00327
00328
00329 fprintf(hfile, "\n");
00330 for (prop_iter = props.begin(); prop_iter != props.end(); ++prop_iter) {
00331 ABI_PROPERTY prop = *prop_iter;
00332 assert(prop->is_flag);
00333 fprintf(hfile, "#define ABI_PROPERTY_%-20s 0x%0*llx%s\n",
00334 prop->name,
00335 Type_Size(prop_count[true][prop->is_reg]) / 4,
00336 prop->v,
00337 Type_Suffix(prop_count[true][prop->is_reg]));
00338 }
00339
00340
00341
00342
00343 int num_abi = 0;
00344 fprintf(hfile, "\ntypedef enum {\n");
00345 fprintf(cfile, "\nstatic const ABI_PROPERTIES abi_properties[] = {\n");
00346 for (abi_iter = abis.begin(); abi_iter != abis.end(); ++abi_iter) {
00347 int rc;
00348 ABI abi = *abi_iter;
00349 ++num_abi;
00350
00351 fprintf(hfile, " ABI_PROPERTIES_ABI_%s,\n", abi->name);
00352
00353 fprintf(cfile, " {\n"
00354 " /* %s */\n",
00355 abi->name);
00356
00357 int count = prop_count[true][false];
00358 if (count != 0) {
00359 unsigned long long mask = 0;
00360 for (prop_iter = abi->flags.begin(); prop_iter != abi->flags.end(); ++prop_iter) {
00361 ABI_PROPERTY prop = *prop_iter;
00362 mask |= prop->v;
00363 }
00364 fprintf(cfile, " 0x%0*llx%s,\n",
00365 Type_Size(count) / 4,
00366 mask,
00367 Type_Suffix(count));
00368 }
00369
00370 count = prop_count[true][true];
00371 if (count != 0) {
00372 fprintf(cfile, " {\n");
00373 for (rc = 0; rc <= ISA_REGISTER_CLASS_MAX; ++rc) {
00374 int reg;
00375 const ISA_REGISTER_CLASS_INFO *cinfo
00376 = ISA_REGISTER_CLASS_Info((ISA_REGISTER_CLASS)rc);
00377
00378 fprintf(cfile, " /* ISA_REGISTER_CLASS_%s */\n",
00379 ISA_REGISTER_CLASS_INFO_Name(cinfo));
00380 int cursor = fprintf(cfile, " {");
00381 for (reg = 0; reg <= ISA_REGISTER_MAX; ++reg) {
00382 unsigned long long mask = 0;
00383 list<ABI_PROPERTY> props = abi->reg_flags[rc][reg];
00384 for (prop_iter = props.begin(); prop_iter != props.end(); ++prop_iter) {
00385 ABI_PROPERTY prop = *prop_iter;
00386 mask |= prop->v;
00387 }
00388 if (cursor >= 80 - (4 + Type_Size(count) / 4) - 3 - 1) {
00389 fprintf(cfile, "\n");
00390 cursor = fprintf(cfile, " ");
00391 }
00392 cursor += fprintf(cfile, " 0x%0*llx%s,",
00393 Type_Size(count) / 4,
00394 mask,
00395 Type_Suffix(count));
00396 }
00397 fprintf(cfile, " },\n");
00398 }
00399 fprintf(cfile, " },\n");
00400 }
00401
00402 fprintf(cfile, " {\n");
00403 for (rc = 0; rc <= ISA_REGISTER_CLASS_MAX; ++rc) {
00404 int reg;
00405 const ISA_REGISTER_CLASS_INFO *cinfo
00406 = ISA_REGISTER_CLASS_Info((ISA_REGISTER_CLASS)rc);
00407
00408 fprintf(cfile, " /* ISA_REGISTER_CLASS_%s */\n",
00409 ISA_REGISTER_CLASS_INFO_Name(cinfo));
00410 int cursor = fprintf(cfile, " {");
00411 for (reg = 0; reg <= ISA_REGISTER_MAX; ++reg) {
00412 const char *name = abi->reg_names[rc][reg];
00413 if (name == NULL) name = ISA_REGISTER_CLASS_INFO_Reg_Name(cinfo, reg);
00414 if (name == NULL) name = "";
00415 if (cursor >= 80 - (4 + strlen(name))) {
00416 fprintf(cfile, "\n");
00417 cursor = fprintf(cfile, " ");
00418 }
00419 cursor += fprintf(cfile, " \"%s\",", name);
00420 }
00421 fprintf(cfile, " },\n");
00422 }
00423 fprintf(cfile, " },\n");
00424
00425 fprintf(cfile, " },\n");
00426 }
00427 fprintf(cfile, "};\n");
00428 fprintf(hfile, " ABI_PROPERTIES_ABI_UNDEFINED,\n"
00429 " ABI_PROPERTIES_ABI_MAX=%d\n"
00430 "} ABI_PROPERTIES_ABI;\n",
00431 num_abi-1);
00432
00433
00434
00435
00436 fprintf(cfile, "\nstatic const char * const abi_names[] = {\n");
00437 for (abi_iter = abis.begin(); abi_iter != abis.end(); ++abi_iter) {
00438 ABI abi = *abi_iter;
00439 fprintf(cfile, " \"%s\",\n", abi->name);
00440 }
00441 fprintf(cfile, " \"UNDEFINED\"\n"
00442 "};\n");
00443
00444
00445
00446
00447 fprintf(hfile, "\nextern ABI_PROPERTIES_ABI ABI_PROPERTIES_ABI_Value;\n");
00448 fprintf(cfile, "\nABI_PROPERTIES_ABI ABI_PROPERTIES_ABI_Value = ABI_PROPERTIES_ABI_UNDEFINED;\n");
00449 fprintf(efile, "ABI_PROPERTIES_ABI_Value\n");
00450
00451 fprintf(hfile, "\nextern const char *ABI_PROPERTIES_ABI_Name(ABI_PROPERTIES_ABI abi);\n");
00452 fprintf(cfile, "\nconst char *ABI_PROPERTIES_ABI_Name(ABI_PROPERTIES_ABI abi)\n"
00453 "{\n"
00454 " return abi_names[(INT)abi];\n"
00455 "}\n");
00456 fprintf(efile, "ABI_PROPERTIES_Initialize\n");
00457
00458 fprintf(cfile, "\nconst ABI_PROPERTIES *ABI_PROPERTIES_target_props"
00459 " = &abi_properties[ABI_PROPERTIES_ABI_UNDEFINED];\n");
00460 fprintf(efile, "ABI_PROPERTIES_target_props\n");
00461
00462 fprintf(hfile, "\nextern void ABI_PROPERTIES_Initialize(void);\n");
00463 fprintf(cfile, "\nvoid ABI_PROPERTIES_Initialize(void)\n"
00464 "{\n"
00465 " ABI_PROPERTIES_target_props = &abi_properties[(INT)ABI_PROPERTIES_ABI_Value];\n"
00466 "}\n");
00467 fprintf(efile, "ABI_PROPERTIES_Initialize\n");
00468
00469
00470
00471
00472 fprintf(hfile, "\ninline const char *ABI_PROPERTY_Reg_Name(\n"
00473 " ISA_REGISTER_CLASS rc,\n"
00474 " INT reg)\n"
00475 "{\n"
00476 " extern const ABI_PROPERTIES *ABI_PROPERTIES_target_props;\n"
00477 " return ABI_PROPERTIES_target_props->reg_names[rc][reg];\n"
00478 "}\n");
00479
00480 for (prop_iter = props.begin(); prop_iter != props.end(); ++prop_iter) {
00481 ABI_PROPERTY prop = *prop_iter;
00482 assert(prop->is_flag);
00483 fputs(prop->v ? "\n" : "\n/*ARGSUSED*/\n", hfile);
00484 if (prop->is_reg) {
00485 fprintf(hfile, "inline BOOL ABI_PROPERTY_Is_%s(\n"
00486 " ISA_REGISTER_CLASS rc,\n"
00487 " INT reg)\n"
00488 "{\n",
00489 prop->name);
00490 if (prop->v == 0) {
00491 fprintf(hfile, " return FALSE;\n"
00492 "}\n");
00493 } else {
00494 fprintf(hfile, " extern const ABI_PROPERTIES *ABI_PROPERTIES_target_props;\n"
00495 " return ( ABI_PROPERTIES_target_props->reg_flags[rc][reg]\n"
00496 " & ABI_PROPERTY_%s) != 0;\n"
00497 "}\n",
00498 prop->name);
00499 }
00500 } else {
00501 fprintf(hfile, "inline BOOL ABI_PROPERTY_Is_%s(void)\n"
00502 "{\n",
00503 prop->name);
00504 if (prop->v == 0) {
00505 fprintf(hfile, " return FALSE;\n"
00506 "}\n");
00507 } else {
00508 fprintf(hfile, " extern const ABI_PROPERTIES *ABI_PROPERTIES_target_props;\n"
00509 " return ( ABI_PROPERTIES_target_props->flags\n"
00510 " & ABI_PROPERTY_%s) != 0;\n"
00511 "}\n",
00512 prop->name);
00513 }
00514 }
00515 }
00516
00517 Emit_Footer (hfile);
00518 }