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
00042
00043
00044
00045 #include <stddef.h>
00046 #include <stdlib.h>
00047 #include <stdarg.h>
00048 #include <stdio.h>
00049 #include <assert.h>
00050
00051 #include <vector>
00052 #include <list>
00053
00054 using namespace std;
00055
00056 #include "topcode.h"
00057 #include "gen_util.h"
00058 #include "isa_subset_gen.h"
00059
00060
00061 struct isa_subset {
00062 const char* name;
00063 int index;
00064 ISA_SUBSET superset;
00065 vector<unsigned char> members;
00066
00067 };
00068
00069 static int isa_subset_count = 0;
00070 static list<ISA_SUBSET> subsets;
00071 static size_t bit_vector_sizeof;
00072
00073 static vector<ISA_SUBSET> opcode_subset;
00074
00075
00076
00077 static const char * const interface[] = {
00078 "/* ====================================================================",
00079 " * ====================================================================",
00080 " *",
00081 " * Description:",
00082 " *",
00083 " * A description of the ISA subset hierarchy. The description",
00084 " * exports the following:",
00085 " *",
00086 " * typedef (enum) ISA_SUBSET",
00087 " * An enumberated type of the different subsets.",
00088 " *",
00089 " * const ISA_SUBSET ISA_SUBSET_UNDEFINED",
00090 " * Useful value guaranteed not to be a valid ISA_SUBSET.",
00091 " *",
00092 " * extern ISA_SUBSET ISA_SUBSET_Value",
00093 " * A variable containing the current subset value.",
00094 " *",
00095 " * const char* ISA_SUBSET_Name( ISA_SUBSET subset )",
00096 " * Returns a name suitable for printing.",
00097 " *",
00098 " * int ISA_SUBSET_Member( ISA_SUBSET subset, TOP opcode )",
00099 " * Is the given <opcode> a member of the given <subset>?",
00100 " *",
00101 " * ====================================================================",
00102 " * ====================================================================",
00103 " */",
00104 NULL
00105 };
00106
00107
00109 void ISA_Subset_Begin( const char* )
00111
00113 {
00114 bit_vector_sizeof = (TOP_count + 7) / 8;
00115 opcode_subset = vector<ISA_SUBSET>(TOP_count,(ISA_SUBSET)0);
00116 for ( int code = 0; code < TOP_count; ++code )
00117 opcode_subset[code] = NULL;
00118 }
00119
00121 ISA_SUBSET ISA_Subset_Create( ISA_SUBSET parent, const char* name )
00123
00125 {
00126 ISA_SUBSET result = new isa_subset;
00127
00128 result->name = name;
00129 result->index = isa_subset_count++;
00130 result->superset = parent;
00131 result->members = vector<unsigned char>(bit_vector_sizeof,0);
00132
00133 subsets.push_front(result);
00134
00135 return result;
00136 }
00137
00139 void Instruction_Group( ISA_SUBSET subset, ... )
00141
00143 {
00144 va_list ap;
00145 TOP opcode;
00146
00147 va_start(ap,subset);
00148 while ( (opcode = static_cast<TOP>(va_arg(ap,int))) != TOP_UNDEFINED ) {
00149 ISA_SUBSET ss;
00150 int byte_index = ((unsigned int) opcode) / 8;
00151 int bit_index = ((unsigned int) opcode) % 8;
00152
00153 for ( ss = subset; ss != NULL; ss = ss->superset )
00154 ss->members[byte_index] |= (1 << bit_index);
00155
00156 if ( opcode_subset[opcode] != NULL ) {
00157 fprintf(stderr,"### attempting to add %s to ISA subset %s but "
00158 "already in %s\n",
00159 TOP_Name(opcode),
00160 subset->name,
00161 opcode_subset[opcode]->name);
00162 exit(EXIT_FAILURE);
00163 }
00164 opcode_subset[opcode] = subset;
00165 }
00166 va_end(ap);
00167 }
00168
00170 void ISA_Subset_End(void)
00172
00174 {
00175 list<ISA_SUBSET>::iterator isi;
00176 bool err;
00177 int code;
00178
00179 for ( err = false, code = 0; code < TOP_count; ++code ) {
00180 if ( ! opcode_subset[code] ) {
00181 fprintf(stderr,"### Error: no opcode subset for %s\n",
00182 TOP_Name((TOP)code));
00183 err = true;
00184 }
00185 }
00186 if (err) exit(EXIT_FAILURE);
00187
00188 #define FNAME "targ_isa_subset"
00189 char filename[1000];
00190 sprintf(filename,"%s.h", FNAME);
00191 FILE* hfile = fopen(filename,"w");
00192 sprintf(filename,"%s.c", FNAME);
00193 FILE* cfile = fopen(filename,"w");
00194 sprintf(filename,"%s.Exported", FNAME);
00195 FILE* efile = fopen(filename,"w");
00196
00197 fprintf(cfile,"#include \"topcode.h\"\n");
00198 fprintf(cfile,"#include \"%s.h\"\n", FNAME);
00199
00200 sprintf (filename, "%s", FNAME);
00201 Emit_Header (hfile, filename, interface);
00202 fprintf(hfile,"#include \"topcode.h\"\n");
00203
00204 fprintf(hfile,"\ntypedef enum {\n");
00205 fprintf(cfile,"\nstatic const char* const isa_subset_names[] = {\n");
00206
00207 for ( isi = subsets.begin(); isi != subsets.end(); ++isi ) {
00208 ISA_SUBSET subset = *isi;
00209 fprintf(hfile," ISA_SUBSET_%s,\n", subset->name);
00210 fprintf(cfile," \"%s\",", subset->name);
00211 }
00212 fprintf(hfile," ISA_SUBSET_UNDEFINED,\n"
00213 " ISA_SUBSET_MIN=ISA_SUBSET_%s,\n"
00214 " ISA_SUBSET_MAX=ISA_SUBSET_%s\n"
00215 "} ISA_SUBSET;\n",
00216 (*subsets.begin())->name,
00217 (*subsets.rbegin())->name);
00218 fprintf(cfile," \"UNDEFINED\"\n"
00219 "};\n");
00220
00221 fprintf(hfile,"extern ISA_SUBSET ISA_SUBSET_Value;\n\n");
00222 fprintf(efile,"ISA_SUBSET_Value\n");
00223 fprintf(cfile,"ISA_SUBSET ISA_SUBSET_Value = ISA_SUBSET_UNDEFINED;\n\n");
00224
00225 fprintf(hfile,"extern const char* ISA_SUBSET_Name( ISA_SUBSET subset );\n");
00226 fprintf(efile,"ISA_SUBSET_Name\n");
00227 fprintf(cfile,"const char* ISA_SUBSET_Name( ISA_SUBSET subset ) {\n");
00228 fprintf(cfile," return isa_subset_names[(INT)subset];\n");
00229 fprintf(cfile,"}\n");
00230
00231 fprintf(cfile,
00232 "static const unsigned char isa_subset_opcode_table[%d][%d] = {\n",
00233 isa_subset_count+1,bit_vector_sizeof);
00234
00235 for ( isi = subsets.begin(); isi != subsets.end(); ++isi ) {
00236 ISA_SUBSET subset = *isi;
00237
00238 fprintf(cfile," { /* %s */\n", subset->name);
00239 for ( int i = 0; i < bit_vector_sizeof; ++i ) {
00240 int members = subset->members[i];
00241 fprintf(cfile," 0%03o, /* ",members);
00242 for (int j = 0; j < 8; ++j) {
00243 if (members & (1 << j)) {
00244 TOP top = (TOP)((i * 8) + j);
00245 fprintf(cfile,"%s ",TOP_Name(top));
00246 }
00247 }
00248 fprintf(cfile,"*/\n");
00249 }
00250 fprintf(cfile," },\n");
00251 }
00252 fprintf(cfile," { /* UNDEFINED */\n"
00253 " 0\n"
00254 " }\n");
00255 fprintf(cfile,"};\n");
00256
00257 fprintf(hfile,"extern INT ISA_SUBSET_Member( ISA_SUBSET subset,\n"
00258 " TOP opcode );\n");
00259 fprintf(efile,"ISA_SUBSET_Member\n");
00260 fprintf(cfile,
00261 "int ISA_SUBSET_Member( ISA_SUBSET subset, TOP opcode )\n"
00262 "{\n"
00263 " INT byte_index = ((UINT) opcode) / 8;\n"
00264 " INT bit_index = ((UINT) opcode) %% 8;\n"
00265 " INT byte = (INT)isa_subset_opcode_table[(int) subset][byte_index];\n"
00266 " return (byte >> bit_index) & 1;\n"
00267 "}\n");
00268
00269 Emit_Footer (hfile);
00270 }