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
00043
00044
00045
00046 #include <stddef.h>
00047 #include <stdlib.h>
00048 #include <stdarg.h>
00049 #include <stdio.h>
00050 #include <assert.h>
00051
00052 #include <list>
00053 #include <vector>
00054
00055 using namespace std;
00056
00057 #include "topcode.h"
00058 #include "gen_util.h"
00059 #include "isa_properties_gen.h"
00060
00061
00062 struct isa_property {
00063 const char* name;
00064 int bit_position;
00065 vector <bool> members;
00066 };
00067
00068
00069 enum {
00070 BIT_POS_ALL = -1,
00071 BIT_POS_NONE = -2
00072 };
00073
00074 static list<ISA_PROPERTY> properties;
00075
00076 static const char * const interface[] = {
00077 "/* ====================================================================",
00078 " * ====================================================================",
00079 " *",
00080 " * Description:",
00081 " *",
00082 " * A description of the properties (attributes) for the instructions",
00083 " * in the ISA. The description exports the following:",
00084 " *",
00085 " * BOOL TOP_is_xxx(TOP topcode)",
00086 " * Return true/false if 'topcode' has/does-not-have the property",
00087 " * 'xxx'.",
00088 " *",
00089 " * ====================================================================",
00090 " * ====================================================================",
00091 " */",
00092 NULL
00093 };
00094
00095
00097 void ISA_Properties_Begin( const char* )
00099
00101 {
00102 }
00103
00105 ISA_PROPERTY ISA_Property_Create( const char* name )
00107
00109 {
00110 ISA_PROPERTY result = new isa_property;
00111
00112 result->name = name;
00113 result->members = vector <bool> (TOP_count, false);
00114
00115 properties.push_back(result);
00116
00117 return result;
00118 }
00119
00121 void Instruction_Group( ISA_PROPERTY property, ... )
00123
00125 {
00126 va_list ap;
00127 TOP opcode;
00128
00129 va_start(ap,property);
00130 while ( (opcode = static_cast<TOP>(va_arg(ap,int))) != TOP_UNDEFINED ) {
00131 property->members[(int)opcode] = true;
00132 }
00133 va_end(ap);
00134 }
00135
00137 void ISA_Properties_End(void)
00139
00141 {
00142 list<ISA_PROPERTY>::iterator isi;
00143 int isa_property_count;
00144 int code;
00145
00146 #define FNAME "targ_isa_properties"
00147 char filename[1000];
00148 sprintf (filename, "%s.h", FNAME);
00149 FILE* hfile = fopen(filename, "w");
00150 sprintf (filename, "%s.c", FNAME);
00151 FILE* cfile = fopen(filename, "w");
00152 sprintf (filename, "%s.Exported", FNAME);
00153 FILE* efile = fopen(filename, "w");
00154
00155 fprintf(cfile,"#include \"%s.h\"\n\n", FNAME);
00156
00157 Emit_Header (hfile, "targ_isa_properties", interface);
00158
00159 isa_property_count = 0;
00160 for ( isi = properties.begin(); isi != properties.end(); ++isi ) {
00161 ISA_PROPERTY property = *isi;
00162 bool member;
00163 bool prev_member = property->members[0];
00164 for (code = 1; code < TOP_count; code++) {
00165 member = property->members[code];
00166 if (member != prev_member) break;
00167 }
00168 if (member != prev_member) {
00169 property->bit_position = isa_property_count++;
00170 } else {
00171 property->bit_position = member ? BIT_POS_ALL : BIT_POS_NONE;
00172 }
00173 }
00174
00175 const char *int_type;
00176 const char *int_suffix;
00177 int int_size;
00178 if (isa_property_count <= 8) {
00179 int_type = "mUINT8";
00180 int_suffix = "";
00181 int_size = 8;
00182 } else if (isa_property_count <= 16) {
00183 int_type = "mUINT16";
00184 int_suffix = "";
00185 int_size = 16;
00186 } else if (isa_property_count <= 32) {
00187 int_type = "mUINT32";
00188 int_suffix = "U";
00189 int_size = 32;
00190 } else {
00191 assert (isa_property_count <= 64);
00192 int_type = "mUINT64";
00193 int_suffix = "ULL";
00194 int_size = 64;
00195 }
00196 fprintf (hfile, "extern const %s ISA_PROPERTIES_flags[];\n\n", int_type);
00197 fprintf (efile, "ISA_PROPERTIES_flags\n");
00198 fprintf (cfile,"const %s ISA_PROPERTIES_flags[] = {\n", int_type);
00199
00200 for (code = 0; code < TOP_count; code++) {
00201 unsigned long long flag_value = 0;
00202
00203 for ( isi = properties.begin(); isi != properties.end(); ++isi ) {
00204 ISA_PROPERTY property = *isi;
00205 if (property->bit_position >= 0 && property->members[code]) {
00206 flag_value |= (1ULL << property->bit_position);
00207 }
00208 }
00209 fprintf (cfile, " 0x%0*llx%s, /* %s:", int_size / 4,
00210 flag_value,
00211 int_suffix,
00212 TOP_Name((TOP)code));
00213 for ( isi = properties.begin(); isi != properties.end(); ++isi ) {
00214 ISA_PROPERTY property = *isi;
00215 if (property->members[code]) fprintf (cfile, " %s", property->name);
00216 }
00217 fprintf (cfile, " */\n");
00218 }
00219 fprintf (cfile, "};\n");
00220
00221 for ( isi = properties.begin(); isi != properties.end(); ++isi ) {
00222 ISA_PROPERTY property = *isi;
00223 int bit_position = property->bit_position;
00224 if (bit_position >= 0) {
00225 fprintf (hfile, "#define PROP_%-16s 0x%llx%s\n",
00226 property->name,
00227 (1ULL << bit_position),
00228 int_suffix);
00229 }
00230 }
00231
00232 fprintf (hfile, "\n\n");
00233 for ( isi = properties.begin(); isi != properties.end(); ++isi ) {
00234 ISA_PROPERTY property = *isi;
00235 int bit_position = property->bit_position;
00236 if (bit_position < 0) {
00237 fprintf (hfile, "#define TOP_is_%s(t)\t (%s)\n",
00238 property->name,
00239 bit_position == BIT_POS_ALL ? "TRUE" : "FALSE");
00240 } else {
00241 fprintf (hfile, "#define TOP_is_%s(t)\t (ISA_PROPERTIES_flags[(INT)t] & PROP_%s)\n",
00242 property->name,
00243 property->name);
00244 }
00245 }
00246
00247 Emit_Footer (hfile);
00248 }