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
00046
00047
00048
00049
00050
00051
00052 #include <stddef.h>
00053 #include <stdlib.h>
00054 #include <stdarg.h>
00055 #include <stdio.h>
00056 #include <assert.h>
00057 #include <limits.h>
00058 #include "gen_util.h"
00059 #include "isa_lits_gen.h"
00060
00061 struct lit_range {
00062 const char *name;
00063 long long min;
00064 long long max;
00065 };
00066
00067 static const char * const interface[] = {
00068 "/* ====================================================================",
00069 " * ====================================================================",
00070 " *",
00071 " * Description:",
00072 " *",
00073 " * A list of all the lit classes used in an ISA.",
00074 " * It exports the following:",
00075 " *",
00076 " * typedef (enum) ISA_LIT_CLASS",
00077 " * An enumeration of the lit classes.",
00078 " *",
00079 " * typedef (struct) ISA_LIT_CLASS_INFO",
00080 " * Contains info about first and last ECV in the EC.",
00081 " * The contents are private.",
00082 " *",
00083 " * typedef (struct) ISA_LIT_CLASS_VALUE_INFO",
00084 " * Contains info about name and min/max of the LC.",
00085 " * The contents are private.",
00086 " *",
00087 " * const char * ISA_LC_Name (ISA_LIT_CLASS lc)",
00088 " * Returns name of <lc>.",
00089 " *",
00090 " * INT64 ISA_LC_Min (ISA_LIT_CLASS lc)",
00091 " * Returns the minimum value for the specified <lc>. For classes",
00092 " * that have multiple sub-ranges, ISA_LC_Min returns the smallest",
00093 " * minimum of all the sub-ranges.",
00094 " *",
00095 " * INT64 ISA_LC_Max (ISA_LIT_CLASS lc)",
00096 " * Returns the maximum value for the specified <lc>. For classes",
00097 " * that have multiple sub-ranges, ISA_LC_Max returns the largest",
00098 " * maximum of all the sub-ranges.",
00099 " *",
00100 " * BOOL ISA_LC_Is_Signed (ISA_LIT_CLASS lc)",
00101 " * Returns whether the lit-class <lc> is signed.",
00102 " *",
00103 " * BOOL ISA_LC_Value_In_Class (INT64 val, ISA_LIT_CLASS lc)",
00104 " * Returns whether <val> is a value that belongs to <lc>.",
00105 " *",
00106 " * ====================================================================",
00107 " * ====================================================================",
00108 " */",
00109 NULL
00110 };
00111
00112 static FILE *hfile, *cfile, *efile;
00113 static struct lit_range signed_range[65];
00114 static struct lit_range unsigned_range[65];
00115 static int max_ranges = 0;
00116
00118 void ISA_Lits_Begin (void)
00120
00122 {
00123 #define FNAME "targ_isa_lits"
00124 char buf[1000];
00125 sprintf (buf, "%s.h", FNAME);
00126 hfile = fopen(buf, "w");
00127 sprintf (buf, "%s.c", FNAME);
00128 cfile = fopen(buf, "w");
00129 sprintf (buf, "%s.Exported", FNAME);
00130 efile = fopen(buf, "w");
00131
00132 fprintf(cfile,"#include \"%s.h\"\n\n", FNAME);
00133
00134 sprintf (buf, "%s", FNAME);
00135 Emit_Header (hfile, buf, interface);
00136
00137 #ifdef __MINGW32__
00138 fprintf(hfile, "\n#undef LC_MAX\n");
00139 #endif
00140
00141 fprintf(hfile, "\ntypedef enum {\n");
00142
00143 fprintf(hfile, "\tLC_UNDEFINED,\n");
00144
00145 fprintf(cfile, "const ISA_LIT_CLASS_INFO ISA_LIT_CLASS_info[] = {\n");
00146 fprintf(cfile, " { { { 0x0000000000000000LL, 0x0000000000000000LL } }, 0, 0, \"LC_UNDEFINED\" },\n");
00147
00148 for (int i = 1; i <= 64; ++i) {
00149 unsigned_range[i].min = 0;
00150 unsigned_range[i].max = (i == 64) ? -1ULL : (1ULL << i) - 1;
00151
00152 signed_range[i].min = -1LL << (i - 1);
00153 signed_range[i].max = (1LL << (i - 1)) - 1;
00154 }
00155 }
00156
00157
00159 LIT_RANGE SignedBitRange(unsigned int bit_size)
00161
00163 {
00164 if (bit_size == 0 || bit_size > 64) {
00165 fprintf(stderr, "### Error: invalid signed bit range: %d\n", bit_size);
00166 exit(EXIT_FAILURE);
00167 }
00168 return &signed_range[bit_size];
00169 }
00170
00171
00173 LIT_RANGE UnsignedBitRange(unsigned int bit_size)
00175
00177 {
00178 if (bit_size == 0 || bit_size > 64) {
00179 fprintf(stderr, "### Error: invalid unsigned bit range: %d\n", bit_size);
00180 exit(EXIT_FAILURE);
00181 }
00182 return &unsigned_range[bit_size];
00183 }
00184
00185
00187 LIT_RANGE ISA_Create_Lit_Range(const char *name, long long min, long long max)
00189
00191 {
00192 LIT_RANGE range = new lit_range;
00193 range->name = name;
00194 range->min = min;
00195 range->max = max;
00196 return range;
00197 }
00198
00199
00201 void ISA_Create_Lit_Class(const char* name, LIT_CLASS_TYPE type, ...)
00203
00205 {
00206 va_list ap;
00207 LIT_RANGE range;
00208 bool is_signed = type == SIGNED;
00209 long long min = is_signed ? LONG_LONG_MAX : ULONG_LONG_MAX;
00210 long long max = is_signed ? LONG_LONG_MIN : 0;
00211 int num_ranges = 0;
00212
00213
00214
00215 va_start(ap,type);
00216 while ((range = va_arg(ap,LIT_RANGE)) != LIT_RANGE_END) {
00217 ++num_ranges;
00218 if (is_signed) {
00219 if (range->min < min) min = range->min;
00220 if (range->max > max) max = range->max;
00221 } else {
00222 if ((unsigned long long)range->min < (unsigned long long)min) {
00223 min = range->min;
00224 }
00225 if ((unsigned long long)range->max > (unsigned long long)max) {
00226 max = range->max;
00227 }
00228 }
00229 }
00230 va_end(ap);
00231 if (num_ranges > max_ranges) max_ranges = num_ranges;
00232
00233
00234
00235 fprintf(hfile, "\tLC_%s,\n", name);
00236 fprintf(cfile, " { { { 0x%016" LL_FORMAT "xLL, 0x%016" LL_FORMAT "xLL }", min, max);
00237 va_start(ap,type);
00238 while ((range = va_arg(ap,LIT_RANGE)) != LIT_RANGE_END) {
00239 fprintf(cfile, ",\n { 0x%016" LL_FORMAT "xLL, 0x%016" LL_FORMAT "xLL }",
00240 range->min, range->max);
00241 }
00242 va_end(ap);
00243 fprintf(cfile, " }, %d, %d, \"LC_%s\" },\n",
00244 num_ranges, is_signed, name);
00245 }
00246
00247
00249 void ISA_Lits_End(void)
00251
00253 {
00254 fprintf(hfile, "\tLC_MAX\n");
00255 fprintf(hfile, "} ISA_LIT_CLASS;\n");
00256
00257 fprintf(cfile, "};\n");
00258
00259 fprintf(hfile, "\ntypedef struct {\n"
00260 " struct { INT64 min; INT64 max; } range[%d];\n"
00261 " mUINT8 num_ranges;\n"
00262 " mBOOL is_signed;\n"
00263 " const char *name;\n"
00264 "} ISA_LIT_CLASS_INFO;\n",
00265 max_ranges + 1);
00266 fprintf(efile, "ISA_LIT_CLASS_info\n");
00267
00268 fprintf(hfile, "\ninline const char * ISA_LC_Name (ISA_LIT_CLASS lc)\n"
00269 "{\n"
00270 " extern const ISA_LIT_CLASS_INFO ISA_LIT_CLASS_info[];\n"
00271 " return ISA_LIT_CLASS_info[lc].name;\n"
00272 "}\n");
00273
00274 fprintf(hfile, "\ninline INT64 ISA_LC_Min (ISA_LIT_CLASS lc)\n"
00275 "{\n"
00276 " extern const ISA_LIT_CLASS_INFO ISA_LIT_CLASS_info[];\n"
00277 " return ISA_LIT_CLASS_info[lc].range[0].min;\n"
00278 "}\n");
00279
00280 fprintf(hfile, "\ninline INT64 ISA_LC_Max (ISA_LIT_CLASS lc)\n"
00281 "{\n"
00282 " extern const ISA_LIT_CLASS_INFO ISA_LIT_CLASS_info[];\n"
00283 " return ISA_LIT_CLASS_info[lc].range[0].max;\n"
00284 "}\n");
00285
00286 fprintf(hfile, "\ninline BOOL ISA_LC_Is_Signed (ISA_LIT_CLASS lc)\n"
00287 "{\n"
00288 " extern const ISA_LIT_CLASS_INFO ISA_LIT_CLASS_info[];\n"
00289 " return ISA_LIT_CLASS_info[lc].is_signed;\n"
00290 "}\n");
00291
00292 fprintf(hfile, "\ninline BOOL ISA_LC_Value_In_Class (INT64 val, ISA_LIT_CLASS lc)\n"
00293 "{\n"
00294 " extern const ISA_LIT_CLASS_INFO ISA_LIT_CLASS_info[];\n"
00295 " const ISA_LIT_CLASS_INFO *plc = ISA_LIT_CLASS_info + lc;\n"
00296 " INT i;\n"
00297 " for (i = 1; i <= plc->num_ranges; ++i) {\n"
00298 " INT64 min = plc->range[i].min;\n"
00299 " INT64 max = plc->range[i].max;\n"
00300 " if ( plc->is_signed ) {\n"
00301 " if (val >= min && val <= max) return TRUE;\n"
00302 " } else {\n"
00303 " if ((UINT64)val >= (UINT64)min && (UINT64)val <= (UINT64)max) return TRUE;\n"
00304 " }\n"
00305 " }\n"
00306 " return FALSE;\n"
00307 "}\n");
00308
00309 Emit_Footer (hfile);
00310 }