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