1 1.1 christos /* ia64-gen.c -- Generate a shrunk set of opcode tables 2 1.11 christos Copyright (C) 1999-2024 Free Software Foundation, Inc. 3 1.1 christos Written by Bob Manson, Cygnus Solutions, <manson (at) cygnus.com> 4 1.1 christos 5 1.1 christos This file is part of the GNU opcodes library. 6 1.1 christos 7 1.1 christos This library is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3, or (at your option) 10 1.1 christos any later version. 11 1.1 christos 12 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT 13 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 1.1 christos License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this file; see the file COPYING. If not, write to the 19 1.1 christos Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 20 1.1 christos 02110-1301, USA. */ 21 1.1 christos 22 1.1 christos 23 1.1 christos /* While the ia64-opc-* set of opcode tables are easy to maintain, 24 1.1 christos they waste a tremendous amount of space. ia64-gen rearranges the 25 1.6 christos instructions into a directed acyclic graph (DAG) of instruction opcodes and 26 1.6 christos their possible completers, as well as compacting the set of strings used. 27 1.1 christos 28 1.1 christos The disassembler table consists of a state machine that does 29 1.1 christos branching based on the bits of the opcode being disassembled. The 30 1.1 christos state encodings have been chosen to minimize the amount of space 31 1.6 christos required. 32 1.1 christos 33 1.6 christos The resource table is constructed based on some text dependency tables, 34 1.1 christos which are also easier to maintain than the final representation. */ 35 1.1 christos 36 1.1 christos #include "sysdep.h" 37 1.1 christos #include <stdio.h> 38 1.1 christos #include <stdarg.h> 39 1.1 christos #include <errno.h> 40 1.1 christos 41 1.1 christos #include "libiberty.h" 42 1.1 christos #include "safe-ctype.h" 43 1.1 christos #include "getopt.h" 44 1.1 christos #include "ia64-opc.h" 45 1.1 christos #include "ia64-opc-a.c" 46 1.1 christos #include "ia64-opc-i.c" 47 1.1 christos #include "ia64-opc-m.c" 48 1.1 christos #include "ia64-opc-b.c" 49 1.1 christos #include "ia64-opc-f.c" 50 1.1 christos #include "ia64-opc-x.c" 51 1.1 christos #include "ia64-opc-d.c" 52 1.1 christos 53 1.1 christos #include <libintl.h> 54 1.1 christos #define _(String) gettext (String) 55 1.1 christos 56 1.1 christos const char * program_name = NULL; 57 1.1 christos int debug = 0; 58 1.1 christos 59 1.1 christos #define NELEMS(a) (sizeof (a) / sizeof ((a)[0])) 60 1.1 christos #define tmalloc(X) (X *) xmalloc (sizeof (X)) 61 1.1 christos 62 1.1 christos typedef unsigned long long ci_t; 63 1.1 christos /* The main opcode table entry. Each entry is a unique combination of 64 1.1 christos name and flags (no two entries in the table compare as being equal 65 1.1 christos via opcodes_eq). */ 66 1.1 christos struct main_entry 67 1.1 christos { 68 1.1 christos /* The base name of this opcode. The names of its completers are 69 1.1 christos appended to it to generate the full instruction name. */ 70 1.1 christos struct string_entry *name; 71 1.1 christos /* The base opcode entry. Which one to use is a fairly arbitrary choice; 72 1.1 christos it uses the first one passed to add_opcode_entry. */ 73 1.1 christos struct ia64_opcode *opcode; 74 1.1 christos /* The list of completers that can be applied to this opcode. */ 75 1.1 christos struct completer_entry *completers; 76 1.1 christos /* Next entry in the chain. */ 77 1.1 christos struct main_entry *next; 78 1.1 christos /* Index in the main table. */ 79 1.1 christos int main_index; 80 1.1 christos } *maintable, **ordered_table; 81 1.1 christos 82 1.1 christos int otlen = 0; 83 1.1 christos int ottotlen = 0; 84 1.1 christos int opcode_count = 0; 85 1.1 christos 86 1.1 christos /* The set of possible completers for an opcode. */ 87 1.1 christos struct completer_entry 88 1.1 christos { 89 1.1 christos /* This entry's index in the ia64_completer_table[] array. */ 90 1.1 christos int num; 91 1.1 christos 92 1.1 christos /* The name of the completer. */ 93 1.1 christos struct string_entry *name; 94 1.1 christos 95 1.1 christos /* This entry's parent. */ 96 1.1 christos struct completer_entry *parent; 97 1.1 christos 98 1.1 christos /* Set if this is a terminal completer (occurs at the end of an 99 1.1 christos opcode). */ 100 1.1 christos int is_terminal; 101 1.1 christos 102 1.1 christos /* An alternative completer. */ 103 1.1 christos struct completer_entry *alternative; 104 1.1 christos 105 1.1 christos /* Additional completers that can be appended to this one. */ 106 1.1 christos struct completer_entry *addl_entries; 107 1.1 christos 108 1.1 christos /* Before compute_completer_bits () is invoked, this contains the actual 109 1.1 christos instruction opcode for this combination of opcode and completers. 110 1.1 christos Afterwards, it contains those bits that are different from its 111 1.1 christos parent opcode. */ 112 1.1 christos ia64_insn bits; 113 1.1 christos 114 1.1 christos /* Bits set to 1 correspond to those bits in this completer's opcode 115 1.1 christos that are different from its parent completer's opcode (or from 116 1.1 christos the base opcode if the entry is the root of the opcode's completer 117 1.1 christos list). This field is filled in by compute_completer_bits (). */ 118 1.1 christos ia64_insn mask; 119 1.1 christos 120 1.1 christos /* Index into the opcode dependency list, or -1 if none. */ 121 1.1 christos int dependencies; 122 1.1 christos 123 1.1 christos /* Remember the order encountered in the opcode tables. */ 124 1.1 christos int order; 125 1.1 christos }; 126 1.1 christos 127 1.1 christos /* One entry in the disassembler name table. */ 128 1.1 christos struct disent 129 1.1 christos { 130 1.1 christos /* The index into the ia64_name_dis array for this entry. */ 131 1.1 christos int ournum; 132 1.1 christos 133 1.1 christos /* The index into the main_table[] array. */ 134 1.1 christos int insn; 135 1.1 christos 136 1.1 christos /* The disassmbly priority of this entry. */ 137 1.1 christos int priority; 138 1.1 christos 139 1.1 christos /* The completer_index value for this entry. */ 140 1.1 christos ci_t completer_index; 141 1.1 christos 142 1.1 christos /* How many other entries share this decode. */ 143 1.1 christos int nextcnt; 144 1.1 christos 145 1.1 christos /* The next entry sharing the same decode. */ 146 1.1 christos struct disent *nexte; 147 1.1 christos 148 1.1 christos /* The next entry in the name list. */ 149 1.1 christos struct disent *next_ent; 150 1.1 christos } *disinsntable = NULL; 151 1.1 christos 152 1.1 christos /* A state machine that will eventually be used to generate the 153 1.1 christos disassembler table. */ 154 1.1 christos struct bittree 155 1.1 christos { 156 1.1 christos struct disent *disent; 157 1.1 christos struct bittree *bits[3]; /* 0, 1, and X (don't care). */ 158 1.1 christos int bits_to_skip; 159 1.1 christos int skip_flag; 160 1.1 christos } *bittree; 161 1.1 christos 162 1.1 christos /* The string table contains all opcodes and completers sorted in 163 1.1 christos alphabetical order. */ 164 1.1 christos 165 1.1 christos /* One entry in the string table. */ 166 1.6 christos struct string_entry 167 1.1 christos { 168 1.1 christos /* The index in the ia64_strings[] array for this entry. */ 169 1.1 christos int num; 170 1.1 christos /* And the string. */ 171 1.1 christos char *s; 172 1.1 christos } **string_table = NULL; 173 1.1 christos 174 1.1 christos int strtablen = 0; 175 1.1 christos int strtabtotlen = 0; 176 1.1 christos 177 1.1 christos 178 1.1 christos /* Resource dependency entries. */ 180 1.1 christos struct rdep 181 1.1 christos { 182 1.6 christos char *name; /* Resource name. */ 183 1.1 christos unsigned 184 1.1 christos mode:2, /* RAW, WAW, or WAR. */ 185 1.1 christos semantics:3; /* Dependency semantics. */ 186 1.6 christos char *extra; /* Additional semantics info. */ 187 1.1 christos int nchks; 188 1.1 christos int total_chks; /* Total #of terminal insns. */ 189 1.1 christos int *chks; /* Insn classes which read (RAW), write 190 1.1 christos (WAW), or write (WAR) this rsrc. */ 191 1.1 christos int *chknotes; /* Dependency notes for each class. */ 192 1.1 christos int nregs; 193 1.1 christos int total_regs; /* Total #of terminal insns. */ 194 1.1 christos int *regs; /* Insn class which write (RAW), write2 195 1.1 christos (WAW), or read (WAR) this rsrc. */ 196 1.1 christos int *regnotes; /* Dependency notes for each class. */ 197 1.1 christos 198 1.1 christos int waw_special; /* Special WAW dependency note. */ 199 1.1 christos } **rdeps = NULL; 200 1.1 christos 201 1.1 christos static int rdepslen = 0; 202 1.1 christos static int rdepstotlen = 0; 203 1.1 christos 204 1.1 christos /* Array of all instruction classes. */ 205 1.6 christos struct iclass 206 1.1 christos { 207 1.1 christos char *name; /* Instruction class name. */ 208 1.6 christos int is_class; /* Is a class, not a terminal. */ 209 1.1 christos int nsubs; 210 1.6 christos int *subs; /* Other classes within this class. */ 211 1.1 christos int nxsubs; 212 1.1 christos int xsubs[4]; /* Exclusions. */ 213 1.1 christos char *comment; /* Optional comment. */ 214 1.1 christos int note; /* Optional note. */ 215 1.1 christos int terminal_resolved; /* Did we match this with anything? */ 216 1.1 christos int orphan; /* Detect class orphans. */ 217 1.1 christos } **ics = NULL; 218 1.1 christos 219 1.1 christos static int iclen = 0; 220 1.1 christos static int ictotlen = 0; 221 1.1 christos 222 1.1 christos /* An opcode dependency (chk/reg pair of dependency lists). */ 223 1.1 christos struct opdep 224 1.1 christos { 225 1.1 christos int chk; /* index into dlists */ 226 1.1 christos int reg; /* index into dlists */ 227 1.1 christos } **opdeps; 228 1.1 christos 229 1.1 christos static int opdeplen = 0; 230 1.1 christos static int opdeptotlen = 0; 231 1.1 christos 232 1.1 christos /* A generic list of dependencies w/notes encoded. These may be shared. */ 233 1.1 christos struct deplist 234 1.1 christos { 235 1.1 christos int len; 236 1.1 christos unsigned short *deps; 237 1.1 christos } **dlists; 238 1.1 christos 239 1.1 christos static int dlistlen = 0; 240 1.1 christos static int dlisttotlen = 0; 241 1.1 christos 242 1.1 christos 243 1.1 christos static void fail (const char *, ...) ATTRIBUTE_PRINTF_1; 244 1.1 christos static void warn (const char *, ...) ATTRIBUTE_PRINTF_1; 245 1.1 christos static struct rdep * insert_resource (const char *, enum ia64_dependency_mode); 246 1.1 christos static int deplist_equals (struct deplist *, struct deplist *); 247 1.1 christos static short insert_deplist (int, unsigned short *); 248 1.1 christos static short insert_dependencies (int, unsigned short *, int, unsigned short *); 249 1.1 christos static void mark_used (struct iclass *, int); 250 1.1 christos static int fetch_insn_class (const char *, int); 251 1.1 christos static int sub_compare (const void *, const void *); 252 1.1 christos static void load_insn_classes (void); 253 1.1 christos static void parse_resource_users (const char *, int **, int *, int **); 254 1.1 christos static int parse_semantics (char *); 255 1.1 christos static void add_dep (const char *, const char *, const char *, int, int, char *, int); 256 1.1 christos static void load_depfile (const char *, enum ia64_dependency_mode); 257 1.1 christos static void load_dependencies (void); 258 1.1 christos static int irf_operand (int, const char *); 259 1.1 christos static int in_iclass_mov_x (struct ia64_opcode *, struct iclass *, const char *, const char *); 260 1.1 christos static int in_iclass (struct ia64_opcode *, struct iclass *, const char *, const char *, int *); 261 1.1 christos static int lookup_regindex (const char *, int); 262 1.1 christos static int lookup_specifier (const char *); 263 1.1 christos static void print_dependency_table (void); 264 1.1 christos static struct string_entry * insert_string (char *); 265 1.1 christos static void gen_dis_table (struct bittree *); 266 1.1 christos static void print_dis_table (void); 267 1.1 christos static void generate_disassembler (void); 268 1.1 christos static void print_string_table (void); 269 1.1 christos static int completer_entries_eq (struct completer_entry *, struct completer_entry *); 270 1.1 christos static struct completer_entry * insert_gclist (struct completer_entry *); 271 1.1 christos static int get_prefix_len (const char *); 272 1.1 christos static void compute_completer_bits (struct main_entry *, struct completer_entry *); 273 1.1 christos static void collapse_redundant_completers (void); 274 1.1 christos static int insert_opcode_dependencies (struct ia64_opcode *, struct completer_entry *); 275 1.1 christos static void insert_completer_entry (struct ia64_opcode *, struct main_entry *, int); 276 1.1 christos static void print_completer_entry (struct completer_entry *); 277 1.1 christos static void print_completer_table (void); 278 1.1 christos static int opcodes_eq (struct ia64_opcode *, struct ia64_opcode *); 279 1.1 christos static void add_opcode_entry (struct ia64_opcode *); 280 1.1 christos static void print_main_table (void); 281 1.1 christos static void shrink (struct ia64_opcode *); 282 1.1 christos static void print_version (void); 283 1.1 christos static void usage (FILE *, int); 284 1.1 christos static void finish_distable (void); 285 1.1 christos static void insert_bit_table_ent (struct bittree *, int, ia64_insn, ia64_insn, int, int, ci_t); 286 1.1 christos static void add_dis_entry (struct bittree *, ia64_insn, ia64_insn, int, struct completer_entry *, ci_t); 287 1.1 christos static void compact_distree (struct bittree *); 288 1.1 christos static struct bittree * make_bittree_entry (void); 289 1.1 christos static struct disent * add_dis_table_ent (struct disent *, int, int, ci_t); 290 1.1 christos 291 1.1 christos 292 1.1 christos static void 294 1.1 christos fail (const char *message, ...) 295 1.6 christos { 296 1.1 christos va_list args; 297 1.1 christos 298 1.1 christos va_start (args, message); 299 1.1 christos fprintf (stderr, _("%s: Error: "), program_name); 300 1.1 christos vfprintf (stderr, message, args); 301 1.1 christos va_end (args); 302 1.1 christos xexit (1); 303 1.1 christos } 304 1.1 christos 305 1.1 christos static void 306 1.1 christos warn (const char *message, ...) 307 1.1 christos { 308 1.1 christos va_list args; 309 1.1 christos 310 1.1 christos va_start (args, message); 311 1.1 christos 312 1.1 christos fprintf (stderr, _("%s: Warning: "), program_name); 313 1.1 christos vfprintf (stderr, message, args); 314 1.1 christos va_end (args); 315 1.1 christos } 316 1.1 christos 317 1.1 christos /* Add NAME to the resource table, where TYPE is RAW or WAW. */ 318 1.1 christos static struct rdep * 319 1.1 christos insert_resource (const char *name, enum ia64_dependency_mode type) 320 1.1 christos { 321 1.1 christos if (rdepslen == rdepstotlen) 322 1.1 christos { 323 1.1 christos rdepstotlen += 20; 324 1.1 christos rdeps = (struct rdep **) 325 1.1 christos xrealloc (rdeps, sizeof(struct rdep **) * rdepstotlen); 326 1.1 christos } 327 1.1 christos rdeps[rdepslen] = tmalloc(struct rdep); 328 1.1 christos memset((void *)rdeps[rdepslen], 0, sizeof(struct rdep)); 329 1.1 christos rdeps[rdepslen]->name = xstrdup (name); 330 1.6 christos rdeps[rdepslen]->mode = type; 331 1.1 christos rdeps[rdepslen]->waw_special = 0; 332 1.1 christos 333 1.1 christos return rdeps[rdepslen++]; 334 1.1 christos } 335 1.1 christos 336 1.1 christos /* Are the lists of dependency indexes equivalent? */ 337 1.1 christos static int 338 1.1 christos deplist_equals (struct deplist *d1, struct deplist *d2) 339 1.1 christos { 340 1.1 christos int i; 341 1.1 christos 342 1.1 christos if (d1->len != d2->len) 343 1.1 christos return 0; 344 1.1 christos 345 1.1 christos for (i = 0; i < d1->len; i++) 346 1.1 christos if (d1->deps[i] != d2->deps[i]) 347 1.1 christos return 0; 348 1.1 christos 349 1.1 christos return 1; 350 1.1 christos } 351 1.1 christos 352 1.1 christos /* Add the list of dependencies to the list of dependency lists. */ 353 1.1 christos static short 354 1.1 christos insert_deplist (int count, unsigned short *deps) 355 1.1 christos { 356 1.1 christos /* Sort the list, then see if an equivalent list exists already. 357 1.1 christos this results in a much smaller set of dependency lists. */ 358 1.1 christos struct deplist *list; 359 1.1 christos char set[0x10000]; 360 1.1 christos int i; 361 1.1 christos 362 1.1 christos memset ((void *)set, 0, sizeof (set)); 363 1.1 christos for (i = 0; i < count; i++) 364 1.1 christos set[deps[i]] = 1; 365 1.1 christos 366 1.1 christos count = 0; 367 1.1 christos for (i = 0; i < (int) sizeof (set); i++) 368 1.1 christos if (set[i]) 369 1.1 christos ++count; 370 1.1 christos 371 1.1 christos list = tmalloc (struct deplist); 372 1.1 christos list->len = count; 373 1.1 christos list->deps = (unsigned short *) malloc (sizeof (unsigned short) * count); 374 1.1 christos 375 1.1 christos for (i = 0, count = 0; i < (int) sizeof (set); i++) 376 1.1 christos if (set[i]) 377 1.1 christos list->deps[count++] = i; 378 1.1 christos 379 1.1 christos /* Does this list exist already? */ 380 1.1 christos for (i = 0; i < dlistlen; i++) 381 1.1 christos if (deplist_equals (list, dlists[i])) 382 1.1 christos { 383 1.1 christos free (list->deps); 384 1.1 christos free (list); 385 1.1 christos return i; 386 1.1 christos } 387 1.1 christos 388 1.1 christos if (dlistlen == dlisttotlen) 389 1.1 christos { 390 1.1 christos dlisttotlen += 20; 391 1.1 christos dlists = (struct deplist **) 392 1.1 christos xrealloc (dlists, sizeof(struct deplist **) * dlisttotlen); 393 1.1 christos } 394 1.1 christos dlists[dlistlen] = list; 395 1.1 christos 396 1.1 christos return dlistlen++; 397 1.1 christos } 398 1.1 christos 399 1.6 christos /* Add the given pair of dependency lists to the opcode dependency list. */ 400 1.1 christos static short 401 1.1 christos insert_dependencies (int nchks, unsigned short *chks, 402 1.1 christos int nregs, unsigned short *regs) 403 1.1 christos { 404 1.1 christos struct opdep *pair; 405 1.1 christos int i; 406 1.1 christos int regind = -1; 407 1.1 christos int chkind = -1; 408 1.1 christos 409 1.1 christos if (nregs > 0) 410 1.1 christos regind = insert_deplist (nregs, regs); 411 1.1 christos if (nchks > 0) 412 1.1 christos chkind = insert_deplist (nchks, chks); 413 1.6 christos 414 1.1 christos for (i = 0; i < opdeplen; i++) 415 1.1 christos if (opdeps[i]->chk == chkind 416 1.1 christos && opdeps[i]->reg == regind) 417 1.1 christos return i; 418 1.1 christos 419 1.1 christos pair = tmalloc (struct opdep); 420 1.6 christos pair->chk = chkind; 421 1.1 christos pair->reg = regind; 422 1.1 christos 423 1.1 christos if (opdeplen == opdeptotlen) 424 1.1 christos { 425 1.1 christos opdeptotlen += 20; 426 1.1 christos opdeps = (struct opdep **) 427 1.1 christos xrealloc (opdeps, sizeof(struct opdep **) * opdeptotlen); 428 1.1 christos } 429 1.1 christos opdeps[opdeplen] = pair; 430 1.1 christos 431 1.1 christos return opdeplen++; 432 1.6 christos } 433 1.1 christos 434 1.1 christos static void 435 1.1 christos mark_used (struct iclass *ic, int clear_terminals) 436 1.1 christos { 437 1.1 christos int i; 438 1.1 christos 439 1.1 christos ic->orphan = 0; 440 1.1 christos if (clear_terminals) 441 1.1 christos ic->terminal_resolved = 1; 442 1.1 christos 443 1.1 christos for (i = 0; i < ic->nsubs; i++) 444 1.1 christos mark_used (ics[ic->subs[i]], clear_terminals); 445 1.1 christos 446 1.1 christos for (i = 0; i < ic->nxsubs; i++) 447 1.1 christos mark_used (ics[ic->xsubs[i]], clear_terminals); 448 1.1 christos } 449 1.1 christos 450 1.1 christos /* Look up an instruction class; if CREATE make a new one if none found; 451 1.1 christos returns the index into the insn class array. */ 452 1.1 christos static int 453 1.1 christos fetch_insn_class (const char *full_name, int create) 454 1.1 christos { 455 1.1 christos char *name; 456 1.1 christos char *notestr; 457 1.1 christos char *xsect; 458 1.1 christos char *comment; 459 1.1 christos int i, note = 0; 460 1.1 christos int ind; 461 1.10 christos int is_class = 0; 462 1.1 christos 463 1.1 christos if (startswith (full_name, "IC:")) 464 1.1 christos { 465 1.1 christos name = xstrdup (full_name + 3); 466 1.1 christos is_class = 1; 467 1.1 christos } 468 1.1 christos else 469 1.1 christos name = xstrdup (full_name); 470 1.1 christos 471 1.1 christos if ((xsect = strchr(name, '\\')) != NULL) 472 1.1 christos is_class = 1; 473 1.1 christos if ((comment = strchr(name, '[')) != NULL) 474 1.1 christos is_class = 1; 475 1.1 christos if ((notestr = strchr(name, '+')) != NULL) 476 1.1 christos is_class = 1; 477 1.1 christos 478 1.1 christos /* If it is a composite class, then ignore comments and notes that come after 479 1.1 christos the '\\', since they don't apply to the part we are decoding now. */ 480 1.1 christos if (xsect) 481 1.1 christos { 482 1.1 christos if (comment > xsect) 483 1.1 christos comment = 0; 484 1.1 christos if (notestr > xsect) 485 1.1 christos notestr = 0; 486 1.1 christos } 487 1.1 christos 488 1.1 christos if (notestr) 489 1.1 christos { 490 1.1 christos char *nextnotestr; 491 1.1 christos 492 1.1 christos note = atoi (notestr + 1); 493 1.1 christos if ((nextnotestr = strchr (notestr + 1, '+')) != NULL) 494 1.1 christos { 495 1.1 christos if (strcmp (notestr, "+1+13") == 0) 496 1.1 christos note = 13; 497 1.1 christos else if (!xsect || nextnotestr < xsect) 498 1.1 christos warn (_("multiple note %s not handled\n"), notestr); 499 1.1 christos } 500 1.1 christos } 501 1.1 christos 502 1.1 christos /* If it's a composite class, leave the notes and comments in place so that 503 1.1 christos we have a unique name for the composite class. Otherwise, we remove 504 1.1 christos them. */ 505 1.1 christos if (!xsect) 506 1.1 christos { 507 1.1 christos if (notestr) 508 1.1 christos *notestr = 0; 509 1.1 christos if (comment) 510 1.1 christos *comment = 0; 511 1.1 christos } 512 1.1 christos 513 1.1 christos for (i = 0; i < iclen; i++) 514 1.1 christos if (strcmp (name, ics[i]->name) == 0 515 1.6 christos && ((comment == NULL && ics[i]->comment == NULL) 516 1.1 christos || (comment != NULL && ics[i]->comment != NULL 517 1.1 christos && strncmp (ics[i]->comment, comment, 518 1.1 christos strlen (ics[i]->comment)) == 0)) 519 1.1 christos && note == ics[i]->note) 520 1.1 christos return i; 521 1.1 christos 522 1.1 christos if (!create) 523 1.1 christos return -1; 524 1.1 christos 525 1.1 christos /* Doesn't exist, so make a new one. */ 526 1.1 christos if (iclen == ictotlen) 527 1.1 christos { 528 1.1 christos ictotlen += 20; 529 1.1 christos ics = (struct iclass **) 530 1.1 christos xrealloc (ics, (ictotlen) * sizeof (struct iclass *)); 531 1.1 christos } 532 1.1 christos 533 1.1 christos ind = iclen++; 534 1.1 christos ics[ind] = tmalloc (struct iclass); 535 1.1 christos memset ((void *)ics[ind], 0, sizeof (struct iclass)); 536 1.1 christos ics[ind]->name = xstrdup (name); 537 1.1 christos ics[ind]->is_class = is_class; 538 1.1 christos ics[ind]->orphan = 1; 539 1.1 christos 540 1.1 christos if (comment) 541 1.1 christos { 542 1.1 christos ics[ind]->comment = xstrdup (comment + 1); 543 1.1 christos ics[ind]->comment[strlen (ics[ind]->comment)-1] = 0; 544 1.1 christos } 545 1.1 christos 546 1.1 christos if (notestr) 547 1.1 christos ics[ind]->note = note; 548 1.1 christos 549 1.1 christos /* If it's a composite class, there's a comment or note, look for an 550 1.1 christos existing class or terminal with the same name. */ 551 1.1 christos if ((xsect || comment || notestr) && is_class) 552 1.1 christos { 553 1.1 christos /* First, populate with the class we're based on. */ 554 1.1 christos char *subname = name; 555 1.1 christos 556 1.1 christos if (xsect) 557 1.1 christos *xsect = 0; 558 1.1 christos else if (comment) 559 1.1 christos *comment = 0; 560 1.1 christos else if (notestr) 561 1.1 christos *notestr = 0; 562 1.1 christos 563 1.1 christos ics[ind]->nsubs = 1; 564 1.1 christos ics[ind]->subs = tmalloc(int); 565 1.1 christos ics[ind]->subs[0] = fetch_insn_class (subname, 1); 566 1.1 christos } 567 1.1 christos 568 1.1 christos while (xsect) 569 1.1 christos { 570 1.1 christos char *subname = xsect + 1; 571 1.1 christos 572 1.1 christos xsect = strchr (subname, '\\'); 573 1.1 christos if (xsect) 574 1.1 christos *xsect = 0; 575 1.1 christos ics[ind]->xsubs[ics[ind]->nxsubs] = fetch_insn_class (subname,1); 576 1.1 christos ics[ind]->nxsubs++; 577 1.1 christos } 578 1.1 christos free (name); 579 1.1 christos 580 1.1 christos return ind; 581 1.1 christos } 582 1.1 christos 583 1.1 christos /* For sorting a class's sub-class list only; make sure classes appear before 584 1.1 christos terminals. */ 585 1.1 christos static int 586 1.1 christos sub_compare (const void *e1, const void *e2) 587 1.1 christos { 588 1.1 christos struct iclass *ic1 = ics[*(int *)e1]; 589 1.1 christos struct iclass *ic2 = ics[*(int *)e2]; 590 1.1 christos 591 1.1 christos if (ic1->is_class) 592 1.1 christos { 593 1.1 christos if (!ic2->is_class) 594 1.1 christos return -1; 595 1.1 christos } 596 1.1 christos else if (ic2->is_class) 597 1.1 christos return 1; 598 1.1 christos 599 1.1 christos return strcmp (ic1->name, ic2->name); 600 1.1 christos } 601 1.1 christos 602 1.1 christos static void 603 1.1 christos load_insn_classes (void) 604 1.1 christos { 605 1.1 christos FILE *fp = fopen ("ia64-ic.tbl", "r"); 606 1.1 christos char buf[2048]; 607 1.1 christos 608 1.1 christos if (fp == NULL) 609 1.1 christos fail (_("can't find ia64-ic.tbl for reading\n")); 610 1.11 christos 611 1.11 christos /* Discard first line. */ 612 1.1 christos if (fgets (buf, sizeof(buf), fp) == NULL) 613 1.1 christos return; 614 1.1 christos 615 1.1 christos while (!feof (fp)) 616 1.1 christos { 617 1.1 christos int iclass; 618 1.6 christos char *name; 619 1.1 christos char *tmp; 620 1.1 christos 621 1.6 christos if (fgets (buf, sizeof (buf), fp) == NULL) 622 1.1 christos break; 623 1.1 christos 624 1.1 christos while (ISSPACE (buf[strlen (buf) - 1])) 625 1.1 christos buf[strlen (buf) - 1] = '\0'; 626 1.1 christos 627 1.1 christos name = tmp = buf; 628 1.1 christos while (*tmp != ';') 629 1.1 christos { 630 1.1 christos ++tmp; 631 1.1 christos if (tmp == buf + sizeof (buf)) 632 1.1 christos abort (); 633 1.1 christos } 634 1.1 christos *tmp++ = '\0'; 635 1.1 christos 636 1.1 christos iclass = fetch_insn_class (name, 1); 637 1.1 christos ics[iclass]->is_class = 1; 638 1.1 christos 639 1.1 christos if (strcmp (name, "none") == 0) 640 1.1 christos { 641 1.1 christos ics[iclass]->is_class = 0; 642 1.1 christos ics[iclass]->terminal_resolved = 1; 643 1.1 christos continue; 644 1.1 christos } 645 1.1 christos 646 1.1 christos /* For this class, record all sub-classes. */ 647 1.1 christos while (*tmp) 648 1.1 christos { 649 1.1 christos char *subname; 650 1.1 christos int sub; 651 1.1 christos 652 1.1 christos while (*tmp && ISSPACE (*tmp)) 653 1.1 christos { 654 1.1 christos ++tmp; 655 1.1 christos if (tmp == buf + sizeof (buf)) 656 1.1 christos abort (); 657 1.1 christos } 658 1.1 christos subname = tmp; 659 1.1 christos while (*tmp && *tmp != ',') 660 1.1 christos { 661 1.1 christos ++tmp; 662 1.1 christos if (tmp == buf + sizeof (buf)) 663 1.1 christos abort (); 664 1.1 christos } 665 1.6 christos if (*tmp == ',') 666 1.1 christos *tmp++ = '\0'; 667 1.6 christos 668 1.1 christos ics[iclass]->subs = (int *) 669 1.1 christos xrealloc ((void *)ics[iclass]->subs, 670 1.1 christos (ics[iclass]->nsubs + 1) * sizeof (int)); 671 1.1 christos 672 1.1 christos sub = fetch_insn_class (subname, 1); 673 1.1 christos ics[iclass]->subs = (int *) 674 1.1 christos xrealloc (ics[iclass]->subs, (ics[iclass]->nsubs + 1) * sizeof (int)); 675 1.1 christos ics[iclass]->subs[ics[iclass]->nsubs++] = sub; 676 1.1 christos } 677 1.6 christos 678 1.1 christos /* Make sure classes come before terminals. */ 679 1.1 christos qsort ((void *)ics[iclass]->subs, 680 1.1 christos ics[iclass]->nsubs, sizeof(int), sub_compare); 681 1.1 christos } 682 1.1 christos fclose (fp); 683 1.1 christos 684 1.1 christos if (debug) 685 1.1 christos printf ("%d classes\n", iclen); 686 1.1 christos } 687 1.1 christos 688 1.1 christos /* Extract the insn classes from the given line. */ 689 1.1 christos static void 690 1.1 christos parse_resource_users (const char *ref, int **usersp, int *nusersp, 691 1.1 christos int **notesp) 692 1.1 christos { 693 1.1 christos int c; 694 1.1 christos char *line = xstrdup (ref); 695 1.1 christos char *tmp = line; 696 1.1 christos int *users = *usersp; 697 1.1 christos int count = *nusersp; 698 1.1 christos int *notes = *notesp; 699 1.1 christos 700 1.1 christos c = *tmp; 701 1.1 christos while (c != 0) 702 1.1 christos { 703 1.1 christos char *notestr; 704 1.1 christos int note; 705 1.1 christos char *xsect; 706 1.1 christos int iclass; 707 1.6 christos int create = 0; 708 1.1 christos char *name; 709 1.1 christos 710 1.1 christos while (ISSPACE (*tmp)) 711 1.1 christos ++tmp; 712 1.1 christos name = tmp; 713 1.1 christos while (*tmp && *tmp != ',') 714 1.1 christos ++tmp; 715 1.6 christos c = *tmp; 716 1.1 christos *tmp++ = '\0'; 717 1.1 christos 718 1.1 christos xsect = strchr (name, '\\'); 719 1.1 christos if ((notestr = strstr (name, "+")) != NULL) 720 1.1 christos { 721 1.1 christos char *nextnotestr; 722 1.1 christos 723 1.1 christos note = atoi (notestr + 1); 724 1.1 christos if ((nextnotestr = strchr (notestr + 1, '+')) != NULL) 725 1.1 christos { 726 1.1 christos /* Note 13 always implies note 1. */ 727 1.1 christos if (strcmp (notestr, "+1+13") == 0) 728 1.1 christos note = 13; 729 1.1 christos else if (!xsect || nextnotestr < xsect) 730 1.1 christos warn (_("multiple note %s not handled\n"), notestr); 731 1.1 christos } 732 1.1 christos if (!xsect) 733 1.6 christos *notestr = '\0'; 734 1.1 christos } 735 1.1 christos else 736 1.1 christos note = 0; 737 1.1 christos 738 1.1 christos /* All classes are created when the insn class table is parsed; 739 1.1 christos Individual instructions might not appear until the dependency tables 740 1.1 christos are read. Only create new classes if it's *not* an insn class, 741 1.10 christos or if it's a composite class (which wouldn't necessarily be in the IC 742 1.1 christos table). */ 743 1.6 christos if (! startswith (name, "IC:") || xsect != NULL) 744 1.1 christos create = 1; 745 1.1 christos 746 1.1 christos iclass = fetch_insn_class (name, create); 747 1.1 christos if (iclass != -1) 748 1.1 christos { 749 1.1 christos users = (int *) 750 1.1 christos xrealloc ((void *) users,(count + 1) * sizeof (int)); 751 1.1 christos notes = (int *) 752 1.1 christos xrealloc ((void *) notes,(count + 1) * sizeof (int)); 753 1.1 christos notes[count] = note; 754 1.1 christos users[count++] = iclass; 755 1.1 christos mark_used (ics[iclass], 0); 756 1.1 christos } 757 1.1 christos else if (debug) 758 1.1 christos printf("Class %s not found\n", name); 759 1.1 christos } 760 1.1 christos /* Update the return values. */ 761 1.1 christos *usersp = users; 762 1.1 christos *nusersp = count; 763 1.1 christos *notesp = notes; 764 1.1 christos 765 1.1 christos free (line); 766 1.1 christos } 767 1.1 christos 768 1.1 christos static int 769 1.1 christos parse_semantics (char *sem) 770 1.1 christos { 771 1.1 christos if (strcmp (sem, "none") == 0) 772 1.1 christos return IA64_DVS_NONE; 773 1.1 christos else if (strcmp (sem, "implied") == 0) 774 1.1 christos return IA64_DVS_IMPLIED; 775 1.1 christos else if (strcmp (sem, "impliedF") == 0) 776 1.1 christos return IA64_DVS_IMPLIEDF; 777 1.1 christos else if (strcmp (sem, "data") == 0) 778 1.1 christos return IA64_DVS_DATA; 779 1.1 christos else if (strcmp (sem, "instr") == 0) 780 1.1 christos return IA64_DVS_INSTR; 781 1.1 christos else if (strcmp (sem, "specific") == 0) 782 1.1 christos return IA64_DVS_SPECIFIC; 783 1.6 christos else if (strcmp (sem, "stop") == 0) 784 1.1 christos return IA64_DVS_STOP; 785 1.1 christos else 786 1.1 christos return IA64_DVS_OTHER; 787 1.1 christos } 788 1.1 christos 789 1.1 christos static void 790 1.1 christos add_dep (const char *name, const char *chk, const char *reg, 791 1.1 christos int semantics, int mode, char *extra, int flag) 792 1.1 christos { 793 1.1 christos struct rdep *rs; 794 1.1 christos 795 1.1 christos rs = insert_resource (name, mode); 796 1.1 christos 797 1.1 christos parse_resource_users (chk, &rs->chks, &rs->nchks, &rs->chknotes); 798 1.1 christos parse_resource_users (reg, &rs->regs, &rs->nregs, &rs->regnotes); 799 1.1 christos 800 1.1 christos rs->semantics = semantics; 801 1.1 christos rs->extra = extra; 802 1.1 christos rs->waw_special = flag; 803 1.1 christos } 804 1.1 christos 805 1.1 christos static void 806 1.1 christos load_depfile (const char *filename, enum ia64_dependency_mode mode) 807 1.1 christos { 808 1.1 christos FILE *fp = fopen (filename, "r"); 809 1.1 christos char buf[1024]; 810 1.1 christos 811 1.1 christos if (fp == NULL) 812 1.11 christos fail (_("can't find %s for reading\n"), filename); 813 1.11 christos 814 1.1 christos if (fgets (buf, sizeof(buf), fp) == NULL) 815 1.1 christos return; 816 1.1 christos while (!feof (fp)) 817 1.1 christos { 818 1.1 christos char *name, *tmp; 819 1.1 christos int semantics; 820 1.1 christos char *extra; 821 1.1 christos char *regp, *chkp; 822 1.1 christos 823 1.1 christos if (fgets (buf, sizeof(buf), fp) == NULL) 824 1.1 christos break; 825 1.1 christos 826 1.1 christos while (ISSPACE (buf[strlen (buf) - 1])) 827 1.1 christos buf[strlen (buf) - 1] = '\0'; 828 1.1 christos 829 1.1 christos name = tmp = buf; 830 1.1 christos while (*tmp != ';') 831 1.6 christos ++tmp; 832 1.1 christos *tmp++ = '\0'; 833 1.1 christos 834 1.1 christos while (ISSPACE (*tmp)) 835 1.1 christos ++tmp; 836 1.1 christos regp = tmp; 837 1.1 christos tmp = strchr (tmp, ';'); 838 1.1 christos if (!tmp) 839 1.1 christos abort (); 840 1.1 christos *tmp++ = 0; 841 1.1 christos while (ISSPACE (*tmp)) 842 1.1 christos ++tmp; 843 1.1 christos chkp = tmp; 844 1.1 christos tmp = strchr (tmp, ';'); 845 1.1 christos if (!tmp) 846 1.1 christos abort (); 847 1.1 christos *tmp++ = 0; 848 1.1 christos while (ISSPACE (*tmp)) 849 1.1 christos ++tmp; 850 1.1 christos semantics = parse_semantics (tmp); 851 1.1 christos extra = semantics == IA64_DVS_OTHER ? xstrdup (tmp) : NULL; 852 1.1 christos 853 1.1 christos /* For WAW entries, if the chks and regs differ, we need to enter the 854 1.1 christos entries in both positions so that the tables will be parsed properly, 855 1.1 christos without a lot of extra work. */ 856 1.1 christos if (mode == IA64_DV_WAW && strcmp (regp, chkp) != 0) 857 1.1 christos { 858 1.1 christos add_dep (name, chkp, regp, semantics, mode, extra, 0); 859 1.1 christos add_dep (name, regp, chkp, semantics, mode, extra, 1); 860 1.1 christos } 861 1.1 christos else 862 1.1 christos { 863 1.1 christos add_dep (name, chkp, regp, semantics, mode, extra, 0); 864 1.1 christos } 865 1.1 christos } 866 1.1 christos fclose (fp); 867 1.1 christos } 868 1.1 christos 869 1.1 christos static void 870 1.1 christos load_dependencies (void) 871 1.1 christos { 872 1.1 christos load_depfile ("ia64-raw.tbl", IA64_DV_RAW); 873 1.1 christos load_depfile ("ia64-waw.tbl", IA64_DV_WAW); 874 1.1 christos load_depfile ("ia64-war.tbl", IA64_DV_WAR); 875 1.1 christos 876 1.1 christos if (debug) 877 1.1 christos printf ("%d RAW/WAW/WAR dependencies\n", rdepslen); 878 1.1 christos } 879 1.6 christos 880 1.1 christos /* Is the given operand an indirect register file operand? */ 881 1.1 christos static int 882 1.1 christos irf_operand (int op, const char *field) 883 1.1 christos { 884 1.1 christos if (!field) 885 1.1 christos { 886 1.1 christos return op == IA64_OPND_RR_R3 || op == IA64_OPND_DBR_R3 887 1.1 christos || op == IA64_OPND_IBR_R3 || op == IA64_OPND_PKR_R3 888 1.1 christos || op == IA64_OPND_PMC_R3 || op == IA64_OPND_PMD_R3 889 1.1 christos || op == IA64_OPND_MSR_R3 || op == IA64_OPND_CPUID_R3; 890 1.1 christos } 891 1.1 christos else 892 1.1 christos { 893 1.1 christos return ((op == IA64_OPND_RR_R3 && strstr (field, "rr")) 894 1.1 christos || (op == IA64_OPND_DBR_R3 && strstr (field, "dbr")) 895 1.1 christos || (op == IA64_OPND_IBR_R3 && strstr (field, "ibr")) 896 1.1 christos || (op == IA64_OPND_PKR_R3 && strstr (field, "pkr")) 897 1.1 christos || (op == IA64_OPND_PMC_R3 && strstr (field, "pmc")) 898 1.1 christos || (op == IA64_OPND_PMD_R3 && strstr (field, "pmd")) 899 1.1 christos || (op == IA64_OPND_MSR_R3 && strstr (field, "msr")) 900 1.1 christos || (op == IA64_OPND_CPUID_R3 && strstr (field, "cpuid")) 901 1.1 christos || (op == IA64_OPND_DAHR_R3 && strstr (field, "dahr"))); 902 1.1 christos } 903 1.1 christos } 904 1.1 christos 905 1.1 christos /* Handle mov_ar, mov_br, mov_cr, move_dahr, mov_indirect, mov_ip, mov_pr, 906 1.6 christos * mov_psr, and mov_um insn classes. */ 907 1.1 christos static int 908 1.1 christos in_iclass_mov_x (struct ia64_opcode *idesc, struct iclass *ic, 909 1.1 christos const char *format, const char *field) 910 1.1 christos { 911 1.1 christos int plain_mov = strcmp (idesc->name, "mov") == 0; 912 1.1 christos 913 1.1 christos if (!format) 914 1.1 christos return 0; 915 1.1 christos 916 1.1 christos switch (ic->name[4]) 917 1.1 christos { 918 1.1 christos default: 919 1.1 christos abort (); 920 1.1 christos case 'a': 921 1.1 christos { 922 1.1 christos int i = strcmp (idesc->name, "mov.i") == 0; 923 1.1 christos int m = strcmp (idesc->name, "mov.m") == 0; 924 1.1 christos int i2627 = i && idesc->operands[0] == IA64_OPND_AR3; 925 1.1 christos int i28 = i && idesc->operands[1] == IA64_OPND_AR3; 926 1.1 christos int m2930 = m && idesc->operands[0] == IA64_OPND_AR3; 927 1.1 christos int m31 = m && idesc->operands[1] == IA64_OPND_AR3; 928 1.1 christos int pseudo0 = plain_mov && idesc->operands[1] == IA64_OPND_AR3; 929 1.1 christos int pseudo1 = plain_mov && idesc->operands[0] == IA64_OPND_AR3; 930 1.1 christos 931 1.1 christos /* IC:mov ar */ 932 1.1 christos if (i2627) 933 1.1 christos return strstr (format, "I26") || strstr (format, "I27"); 934 1.1 christos if (i28) 935 1.1 christos return strstr (format, "I28") != NULL; 936 1.1 christos if (m2930) 937 1.1 christos return strstr (format, "M29") || strstr (format, "M30"); 938 1.1 christos if (m31) 939 1.1 christos return strstr (format, "M31") != NULL; 940 1.1 christos if (pseudo0 || pseudo1) 941 1.1 christos return 1; 942 1.1 christos } 943 1.1 christos break; 944 1.1 christos case 'b': 945 1.1 christos { 946 1.1 christos int i21 = idesc->operands[0] == IA64_OPND_B1; 947 1.1 christos int i22 = plain_mov && idesc->operands[1] == IA64_OPND_B2; 948 1.1 christos if (i22) 949 1.1 christos return strstr (format, "I22") != NULL; 950 1.1 christos if (i21) 951 1.1 christos return strstr (format, "I21") != NULL; 952 1.1 christos } 953 1.1 christos break; 954 1.1 christos case 'c': 955 1.1 christos { 956 1.1 christos int m32 = plain_mov && idesc->operands[0] == IA64_OPND_CR3; 957 1.1 christos int m33 = plain_mov && idesc->operands[1] == IA64_OPND_CR3; 958 1.1 christos if (m32) 959 1.1 christos return strstr (format, "M32") != NULL; 960 1.1 christos if (m33) 961 1.1 christos return strstr (format, "M33") != NULL; 962 1.1 christos } 963 1.1 christos break; 964 1.1 christos case 'd': 965 1.1 christos { 966 1.1 christos int m50 = plain_mov && idesc->operands[0] == IA64_OPND_DAHR3; 967 1.1 christos if (m50) 968 1.1 christos return strstr (format, "M50") != NULL; 969 1.1 christos } 970 1.1 christos break; 971 1.1 christos case 'i': 972 1.1 christos if (ic->name[5] == 'n') 973 1.1 christos { 974 1.1 christos int m42 = plain_mov && irf_operand (idesc->operands[0], field); 975 1.1 christos int m43 = plain_mov && irf_operand (idesc->operands[1], field); 976 1.1 christos if (m42) 977 1.1 christos return strstr (format, "M42") != NULL; 978 1.1 christos if (m43) 979 1.1 christos return strstr (format, "M43") != NULL; 980 1.1 christos } 981 1.1 christos else if (ic->name[5] == 'p') 982 1.1 christos { 983 1.1 christos return idesc->operands[1] == IA64_OPND_IP; 984 1.1 christos } 985 1.1 christos else 986 1.1 christos abort (); 987 1.1 christos break; 988 1.1 christos case 'p': 989 1.1 christos if (ic->name[5] == 'r') 990 1.1 christos { 991 1.1 christos int i25 = plain_mov && idesc->operands[1] == IA64_OPND_PR; 992 1.1 christos int i23 = plain_mov && idesc->operands[0] == IA64_OPND_PR; 993 1.1 christos int i24 = plain_mov && idesc->operands[0] == IA64_OPND_PR_ROT; 994 1.1 christos if (i23) 995 1.1 christos return strstr (format, "I23") != NULL; 996 1.1 christos if (i24) 997 1.1 christos return strstr (format, "I24") != NULL; 998 1.1 christos if (i25) 999 1.1 christos return strstr (format, "I25") != NULL; 1000 1.1 christos } 1001 1.1 christos else if (ic->name[5] == 's') 1002 1.1 christos { 1003 1.1 christos int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_L; 1004 1.1 christos int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR; 1005 1.1 christos if (m35) 1006 1.1 christos return strstr (format, "M35") != NULL; 1007 1.1 christos if (m36) 1008 1.1 christos return strstr (format, "M36") != NULL; 1009 1.1 christos } 1010 1.1 christos else 1011 1.1 christos abort (); 1012 1.1 christos break; 1013 1.1 christos case 'u': 1014 1.1 christos { 1015 1.1 christos int m35 = plain_mov && idesc->operands[0] == IA64_OPND_PSR_UM; 1016 1.1 christos int m36 = plain_mov && idesc->operands[1] == IA64_OPND_PSR_UM; 1017 1.1 christos if (m35) 1018 1.1 christos return strstr (format, "M35") != NULL; 1019 1.1 christos if (m36) 1020 1.1 christos return strstr (format, "M36") != NULL; 1021 1.1 christos } 1022 1.1 christos break; 1023 1.1 christos } 1024 1.1 christos return 0; 1025 1.1 christos } 1026 1.1 christos 1027 1.6 christos /* Is the given opcode in the given insn class? */ 1028 1.1 christos static int 1029 1.1 christos in_iclass (struct ia64_opcode *idesc, struct iclass *ic, 1030 1.1 christos const char *format, const char *field, int *notep) 1031 1.1 christos { 1032 1.1 christos int i; 1033 1.1 christos int resolved = 0; 1034 1.1 christos 1035 1.10 christos if (ic->comment) 1036 1.1 christos { 1037 1.1 christos if (startswith (ic->comment, "Format")) 1038 1.1 christos { 1039 1.1 christos /* Assume that the first format seen is the most restrictive, and 1040 1.1 christos only keep a later one if it looks like it's more restrictive. */ 1041 1.1 christos if (format) 1042 1.1 christos { 1043 1.1 christos if (strlen (ic->comment) < strlen (format)) 1044 1.1 christos { 1045 1.6 christos warn (_("most recent format '%s'\nappears more restrictive than '%s'\n"), 1046 1.1 christos ic->comment, format); 1047 1.1 christos format = ic->comment; 1048 1.1 christos } 1049 1.1 christos } 1050 1.1 christos else 1051 1.10 christos format = ic->comment; 1052 1.1 christos } 1053 1.1 christos else if (startswith (ic->comment, "Field")) 1054 1.1 christos { 1055 1.1 christos if (field) 1056 1.1 christos warn (_("overlapping field %s->%s\n"), 1057 1.1 christos ic->comment, field); 1058 1.1 christos field = ic->comment; 1059 1.1 christos } 1060 1.1 christos } 1061 1.1 christos 1062 1.1 christos /* An insn class matches anything that is the same followed by completers, 1063 1.1 christos except when the absence and presence of completers constitutes different 1064 1.1 christos instructions. */ 1065 1.10 christos if (ic->nsubs == 0 && ic->nxsubs == 0) 1066 1.1 christos { 1067 1.1 christos int is_mov = startswith (idesc->name, "mov"); 1068 1.1 christos int plain_mov = strcmp (idesc->name, "mov") == 0; 1069 1.1 christos int len = strlen(ic->name); 1070 1.6 christos 1071 1.1 christos resolved = ((strncmp (ic->name, idesc->name, len) == 0) 1072 1.1 christos && (idesc->name[len] == '\0' 1073 1.1 christos || idesc->name[len] == '.')); 1074 1.1 christos 1075 1.1 christos /* All break, nop, and hint variations must match exactly. */ 1076 1.1 christos if (resolved && 1077 1.1 christos (strcmp (ic->name, "break") == 0 1078 1.1 christos || strcmp (ic->name, "nop") == 0 1079 1.1 christos || strcmp (ic->name, "hint") == 0)) 1080 1.1 christos resolved = strcmp (ic->name, idesc->name) == 0; 1081 1.1 christos 1082 1.1 christos /* Assume restrictions in the FORMAT/FIELD negate resolution, 1083 1.1 christos unless specifically allowed by clauses in this block. */ 1084 1.1 christos if (resolved && field) 1085 1.1 christos { 1086 1.1 christos /* Check Field(sf)==sN against opcode sN. */ 1087 1.1 christos if (strstr(field, "(sf)==") != NULL) 1088 1.1 christos { 1089 1.1 christos char *sf; 1090 1.1 christos 1091 1.1 christos if ((sf = strstr (idesc->name, ".s")) != 0) 1092 1.1 christos resolved = strcmp (sf + 1, strstr (field, "==") + 2) == 0; 1093 1.1 christos } 1094 1.1 christos /* Check Field(lftype)==XXX. */ 1095 1.1 christos else if (strstr (field, "(lftype)") != NULL) 1096 1.1 christos { 1097 1.1 christos if (strstr (idesc->name, "fault") != NULL) 1098 1.1 christos resolved = strstr (field, "fault") != NULL; 1099 1.1 christos else 1100 1.1 christos resolved = strstr (field, "fault") == NULL; 1101 1.1 christos } 1102 1.1 christos /* Handle Field(ctype)==XXX. */ 1103 1.1 christos else if (strstr (field, "(ctype)") != NULL) 1104 1.1 christos { 1105 1.1 christos if (strstr (idesc->name, "or.andcm")) 1106 1.1 christos resolved = strstr (field, "or.andcm") != NULL; 1107 1.1 christos else if (strstr (idesc->name, "and.orcm")) 1108 1.1 christos resolved = strstr (field, "and.orcm") != NULL; 1109 1.1 christos else if (strstr (idesc->name, "orcm")) 1110 1.1 christos resolved = strstr (field, "or orcm") != NULL; 1111 1.1 christos else if (strstr (idesc->name, "or")) 1112 1.1 christos resolved = strstr (field, "or orcm") != NULL; 1113 1.1 christos else if (strstr (idesc->name, "andcm")) 1114 1.1 christos resolved = strstr (field, "and andcm") != NULL; 1115 1.1 christos else if (strstr (idesc->name, "and")) 1116 1.1 christos resolved = strstr (field, "and andcm") != NULL; 1117 1.1 christos else if (strstr (idesc->name, "unc")) 1118 1.1 christos resolved = strstr (field, "unc") != NULL; 1119 1.1 christos else 1120 1.1 christos resolved = strcmp (field, "Field(ctype)==") == 0; 1121 1.1 christos } 1122 1.1 christos } 1123 1.1 christos 1124 1.10 christos if (resolved && format) 1125 1.1 christos { 1126 1.1 christos if (startswith (idesc->name, "dep") 1127 1.10 christos && strstr (format, "I13") != NULL) 1128 1.1 christos resolved = idesc->operands[1] == IA64_OPND_IMM8; 1129 1.1 christos else if (startswith (idesc->name, "chk") 1130 1.10 christos && strstr (format, "M21") != NULL) 1131 1.1 christos resolved = idesc->operands[0] == IA64_OPND_F2; 1132 1.1 christos else if (startswith (idesc->name, "lfetch")) 1133 1.1 christos resolved = (strstr (format, "M14 M15") != NULL 1134 1.10 christos && (idesc->operands[1] == IA64_OPND_R2 1135 1.1 christos || idesc->operands[1] == IA64_OPND_IMM9b)); 1136 1.1 christos else if (startswith (idesc->name, "br.call") 1137 1.10 christos && strstr (format, "B5") != NULL) 1138 1.1 christos resolved = idesc->operands[1] == IA64_OPND_B2; 1139 1.1 christos else if (startswith (idesc->name, "br.call") 1140 1.10 christos && strstr (format, "B3") != NULL) 1141 1.1 christos resolved = idesc->operands[1] == IA64_OPND_TGT25c; 1142 1.1 christos else if (startswith (idesc->name, "brp") 1143 1.1 christos && strstr (format, "B7") != NULL) 1144 1.1 christos resolved = idesc->operands[0] == IA64_OPND_B2; 1145 1.10 christos else if (strcmp (ic->name, "invala") == 0) 1146 1.1 christos resolved = strcmp (idesc->name, ic->name) == 0; 1147 1.1 christos else if (startswith (idesc->name, "st") 1148 1.1 christos && (strstr (format, "M5") != NULL 1149 1.10 christos || strstr (format, "M10") != NULL)) 1150 1.1 christos resolved = idesc->flags & IA64_OPCODE_POSTINC; 1151 1.1 christos else if (startswith (idesc->name, "ld") 1152 1.1 christos && (strstr (format, "M2 M3") != NULL 1153 1.1 christos || strstr (format, "M12") != NULL 1154 1.1 christos || strstr (format, "M7 M8") != NULL)) 1155 1.1 christos resolved = idesc->flags & IA64_OPCODE_POSTINC; 1156 1.1 christos else 1157 1.1 christos resolved = 0; 1158 1.6 christos } 1159 1.1 christos 1160 1.1 christos /* Misc brl variations ('.cond' is optional); 1161 1.1 christos plain brl matches brl.cond. */ 1162 1.10 christos if (!resolved 1163 1.1 christos && (strcmp (idesc->name, "brl") == 0 1164 1.1 christos || startswith (idesc->name, "brl.")) 1165 1.1 christos && strcmp (ic->name, "brl.cond") == 0) 1166 1.1 christos { 1167 1.1 christos resolved = 1; 1168 1.1 christos } 1169 1.6 christos 1170 1.1 christos /* Misc br variations ('.cond' is optional). */ 1171 1.10 christos if (!resolved 1172 1.1 christos && (strcmp (idesc->name, "br") == 0 1173 1.1 christos || startswith (idesc->name, "br.")) 1174 1.1 christos && strcmp (ic->name, "br.cond") == 0) 1175 1.1 christos { 1176 1.1 christos if (format) 1177 1.1 christos resolved = (strstr (format, "B4") != NULL 1178 1.1 christos && idesc->operands[0] == IA64_OPND_B2) 1179 1.1 christos || (strstr (format, "B1") != NULL 1180 1.1 christos && idesc->operands[0] == IA64_OPND_TGT25c); 1181 1.1 christos else 1182 1.1 christos resolved = 1; 1183 1.1 christos } 1184 1.10 christos 1185 1.1 christos /* probe variations. */ 1186 1.6 christos if (!resolved && startswith (idesc->name, "probe")) 1187 1.6 christos { 1188 1.1 christos resolved = strcmp (ic->name, "probe") == 0 1189 1.1 christos && !((strstr (idesc->name, "fault") != NULL) 1190 1.1 christos ^ (format && strstr (format, "M40") != NULL)); 1191 1.1 christos } 1192 1.1 christos 1193 1.1 christos /* mov variations. */ 1194 1.1 christos if (!resolved && is_mov) 1195 1.1 christos { 1196 1.1 christos if (plain_mov) 1197 1.1 christos { 1198 1.1 christos /* mov alias for fmerge. */ 1199 1.1 christos if (strcmp (ic->name, "fmerge") == 0) 1200 1.1 christos { 1201 1.1 christos resolved = idesc->operands[0] == IA64_OPND_F1 1202 1.1 christos && idesc->operands[1] == IA64_OPND_F3; 1203 1.1 christos } 1204 1.1 christos /* mov alias for adds (r3 or imm14). */ 1205 1.1 christos else if (strcmp (ic->name, "adds") == 0) 1206 1.1 christos { 1207 1.1 christos resolved = (idesc->operands[0] == IA64_OPND_R1 1208 1.1 christos && (idesc->operands[1] == IA64_OPND_R3 1209 1.1 christos || (idesc->operands[1] == IA64_OPND_IMM14))); 1210 1.1 christos } 1211 1.1 christos /* mov alias for addl. */ 1212 1.1 christos else if (strcmp (ic->name, "addl") == 0) 1213 1.1 christos { 1214 1.1 christos resolved = idesc->operands[0] == IA64_OPND_R1 1215 1.1 christos && idesc->operands[1] == IA64_OPND_IMM22; 1216 1.1 christos } 1217 1.1 christos } 1218 1.10 christos 1219 1.1 christos /* Some variants of mov and mov.[im]. */ 1220 1.1 christos if (!resolved && startswith (ic->name, "mov_")) 1221 1.1 christos resolved = in_iclass_mov_x (idesc, ic, format, field); 1222 1.6 christos } 1223 1.1 christos 1224 1.1 christos /* Keep track of this so we can flag any insn classes which aren't 1225 1.1 christos mapped onto at least one real insn. */ 1226 1.1 christos if (resolved) 1227 1.1 christos ic->terminal_resolved = 1; 1228 1.1 christos } 1229 1.1 christos else for (i = 0; i < ic->nsubs; i++) 1230 1.1 christos { 1231 1.1 christos if (in_iclass (idesc, ics[ic->subs[i]], format, field, notep)) 1232 1.1 christos { 1233 1.1 christos int j; 1234 1.1 christos 1235 1.1 christos for (j = 0; j < ic->nxsubs; j++) 1236 1.1 christos if (in_iclass (idesc, ics[ic->xsubs[j]], NULL, NULL, NULL)) 1237 1.1 christos return 0; 1238 1.1 christos 1239 1.1 christos if (debug > 1) 1240 1.1 christos printf ("%s is in IC %s\n", idesc->name, ic->name); 1241 1.1 christos 1242 1.1 christos resolved = 1; 1243 1.1 christos break; 1244 1.6 christos } 1245 1.1 christos } 1246 1.1 christos 1247 1.1 christos /* If it's in this IC, add the IC note (if any) to the insn. */ 1248 1.1 christos if (resolved) 1249 1.1 christos { 1250 1.1 christos if (ic->note && notep) 1251 1.1 christos { 1252 1.1 christos if (*notep && *notep != ic->note) 1253 1.1 christos warn (_("overwriting note %d with note %d (IC:%s)\n"), 1254 1.1 christos *notep, ic->note, ic->name); 1255 1.1 christos 1256 1.1 christos *notep = ic->note; 1257 1.1 christos } 1258 1.1 christos } 1259 1.1 christos 1260 1.1 christos return resolved; 1261 1.1 christos } 1262 1.1 christos 1263 1.1 christos 1264 1.1 christos static int 1266 1.1 christos lookup_regindex (const char *name, int specifier) 1267 1.1 christos { 1268 1.1 christos switch (specifier) 1269 1.1 christos { 1270 1.1 christos case IA64_RS_ARX: 1271 1.1 christos if (strstr (name, "[RSC]")) 1272 1.1 christos return 16; 1273 1.1 christos if (strstr (name, "[BSP]")) 1274 1.1 christos return 17; 1275 1.1 christos else if (strstr (name, "[BSPSTORE]")) 1276 1.1 christos return 18; 1277 1.1 christos else if (strstr (name, "[RNAT]")) 1278 1.1 christos return 19; 1279 1.1 christos else if (strstr (name, "[FCR]")) 1280 1.1 christos return 21; 1281 1.1 christos else if (strstr (name, "[EFLAG]")) 1282 1.1 christos return 24; 1283 1.1 christos else if (strstr (name, "[CSD]")) 1284 1.1 christos return 25; 1285 1.1 christos else if (strstr (name, "[SSD]")) 1286 1.1 christos return 26; 1287 1.1 christos else if (strstr (name, "[CFLG]")) 1288 1.1 christos return 27; 1289 1.1 christos else if (strstr (name, "[FSR]")) 1290 1.1 christos return 28; 1291 1.1 christos else if (strstr (name, "[FIR]")) 1292 1.1 christos return 29; 1293 1.1 christos else if (strstr (name, "[FDR]")) 1294 1.1 christos return 30; 1295 1.1 christos else if (strstr (name, "[CCV]")) 1296 1.1 christos return 32; 1297 1.1 christos else if (strstr (name, "[ITC]")) 1298 1.1 christos return 44; 1299 1.1 christos else if (strstr (name, "[RUC]")) 1300 1.1 christos return 45; 1301 1.1 christos else if (strstr (name, "[PFS]")) 1302 1.1 christos return 64; 1303 1.1 christos else if (strstr (name, "[LC]")) 1304 1.1 christos return 65; 1305 1.1 christos else if (strstr (name, "[EC]")) 1306 1.1 christos return 66; 1307 1.1 christos abort (); 1308 1.1 christos case IA64_RS_CRX: 1309 1.1 christos if (strstr (name, "[DCR]")) 1310 1.1 christos return 0; 1311 1.1 christos else if (strstr (name, "[ITM]")) 1312 1.1 christos return 1; 1313 1.1 christos else if (strstr (name, "[IVA]")) 1314 1.1 christos return 2; 1315 1.1 christos else if (strstr (name, "[PTA]")) 1316 1.1 christos return 8; 1317 1.1 christos else if (strstr (name, "[GPTA]")) 1318 1.1 christos return 9; 1319 1.1 christos else if (strstr (name, "[IPSR]")) 1320 1.1 christos return 16; 1321 1.1 christos else if (strstr (name, "[ISR]")) 1322 1.1 christos return 17; 1323 1.1 christos else if (strstr (name, "[IIP]")) 1324 1.1 christos return 19; 1325 1.1 christos else if (strstr (name, "[IFA]")) 1326 1.1 christos return 20; 1327 1.1 christos else if (strstr (name, "[ITIR]")) 1328 1.1 christos return 21; 1329 1.1 christos else if (strstr (name, "[IIPA]")) 1330 1.1 christos return 22; 1331 1.1 christos else if (strstr (name, "[IFS]")) 1332 1.1 christos return 23; 1333 1.1 christos else if (strstr (name, "[IIM]")) 1334 1.1 christos return 24; 1335 1.1 christos else if (strstr (name, "[IHA]")) 1336 1.1 christos return 25; 1337 1.1 christos else if (strstr (name, "[LID]")) 1338 1.1 christos return 64; 1339 1.1 christos else if (strstr (name, "[IVR]")) 1340 1.1 christos return 65; 1341 1.1 christos else if (strstr (name, "[TPR]")) 1342 1.1 christos return 66; 1343 1.1 christos else if (strstr (name, "[EOI]")) 1344 1.1 christos return 67; 1345 1.1 christos else if (strstr (name, "[ITV]")) 1346 1.1 christos return 72; 1347 1.1 christos else if (strstr (name, "[PMV]")) 1348 1.1 christos return 73; 1349 1.1 christos else if (strstr (name, "[CMCV]")) 1350 1.1 christos return 74; 1351 1.1 christos abort (); 1352 1.1 christos case IA64_RS_PSR: 1353 1.1 christos if (strstr (name, ".be")) 1354 1.1 christos return 1; 1355 1.1 christos else if (strstr (name, ".up")) 1356 1.1 christos return 2; 1357 1.1 christos else if (strstr (name, ".ac")) 1358 1.1 christos return 3; 1359 1.1 christos else if (strstr (name, ".mfl")) 1360 1.1 christos return 4; 1361 1.1 christos else if (strstr (name, ".mfh")) 1362 1.1 christos return 5; 1363 1.1 christos else if (strstr (name, ".ic")) 1364 1.1 christos return 13; 1365 1.1 christos else if (strstr (name, ".i")) 1366 1.1 christos return 14; 1367 1.1 christos else if (strstr (name, ".pk")) 1368 1.1 christos return 15; 1369 1.1 christos else if (strstr (name, ".dt")) 1370 1.1 christos return 17; 1371 1.1 christos else if (strstr (name, ".dfl")) 1372 1.1 christos return 18; 1373 1.1 christos else if (strstr (name, ".dfh")) 1374 1.1 christos return 19; 1375 1.1 christos else if (strstr (name, ".sp")) 1376 1.1 christos return 20; 1377 1.1 christos else if (strstr (name, ".pp")) 1378 1.1 christos return 21; 1379 1.1 christos else if (strstr (name, ".di")) 1380 1.1 christos return 22; 1381 1.1 christos else if (strstr (name, ".si")) 1382 1.1 christos return 23; 1383 1.1 christos else if (strstr (name, ".db")) 1384 1.1 christos return 24; 1385 1.1 christos else if (strstr (name, ".lp")) 1386 1.1 christos return 25; 1387 1.1 christos else if (strstr (name, ".tb")) 1388 1.1 christos return 26; 1389 1.1 christos else if (strstr (name, ".rt")) 1390 1.1 christos return 27; 1391 1.1 christos else if (strstr (name, ".cpl")) 1392 1.1 christos return 32; 1393 1.1 christos else if (strstr (name, ".rs")) 1394 1.1 christos return 34; 1395 1.1 christos else if (strstr (name, ".mc")) 1396 1.1 christos return 35; 1397 1.1 christos else if (strstr (name, ".it")) 1398 1.1 christos return 36; 1399 1.1 christos else if (strstr (name, ".id")) 1400 1.1 christos return 37; 1401 1.1 christos else if (strstr (name, ".da")) 1402 1.1 christos return 38; 1403 1.1 christos else if (strstr (name, ".dd")) 1404 1.1 christos return 39; 1405 1.1 christos else if (strstr (name, ".ss")) 1406 1.1 christos return 40; 1407 1.1 christos else if (strstr (name, ".ri")) 1408 1.1 christos return 41; 1409 1.1 christos else if (strstr (name, ".ed")) 1410 1.1 christos return 43; 1411 1.1 christos else if (strstr (name, ".bn")) 1412 1.1 christos return 44; 1413 1.1 christos else if (strstr (name, ".ia")) 1414 1.1 christos return 45; 1415 1.1 christos else if (strstr (name, ".vm")) 1416 1.1 christos return 46; 1417 1.1 christos else 1418 1.1 christos abort (); 1419 1.1 christos default: 1420 1.1 christos break; 1421 1.1 christos } 1422 1.1 christos return REG_NONE; 1423 1.1 christos } 1424 1.1 christos 1425 1.1 christos static int 1426 1.1 christos lookup_specifier (const char *name) 1427 1.1 christos { 1428 1.1 christos if (strchr (name, '%')) 1429 1.1 christos { 1430 1.1 christos if (strstr (name, "AR[K%]") != NULL) 1431 1.1 christos return IA64_RS_AR_K; 1432 1.1 christos if (strstr (name, "AR[UNAT]") != NULL) 1433 1.1 christos return IA64_RS_AR_UNAT; 1434 1.1 christos if (strstr (name, "AR%, % in 8") != NULL) 1435 1.1 christos return IA64_RS_AR; 1436 1.1 christos if (strstr (name, "AR%, % in 48") != NULL) 1437 1.1 christos return IA64_RS_ARb; 1438 1.1 christos if (strstr (name, "BR%") != NULL) 1439 1.1 christos return IA64_RS_BR; 1440 1.1 christos if (strstr (name, "CR[IIB%]") != NULL) 1441 1.1 christos return IA64_RS_CR_IIB; 1442 1.1 christos if (strstr (name, "CR[IRR%]") != NULL) 1443 1.1 christos return IA64_RS_CR_IRR; 1444 1.1 christos if (strstr (name, "CR[LRR%]") != NULL) 1445 1.1 christos return IA64_RS_CR_LRR; 1446 1.1 christos if (strstr (name, "CR%") != NULL) 1447 1.1 christos return IA64_RS_CR; 1448 1.1 christos if (strstr (name, "DAHR%, % in 0") != NULL) 1449 1.1 christos return IA64_RS_DAHR; 1450 1.1 christos if (strstr (name, "FR%, % in 0") != NULL) 1451 1.1 christos return IA64_RS_FR; 1452 1.1 christos if (strstr (name, "FR%, % in 2") != NULL) 1453 1.1 christos return IA64_RS_FRb; 1454 1.1 christos if (strstr (name, "GR%") != NULL) 1455 1.1 christos return IA64_RS_GR; 1456 1.1 christos if (strstr (name, "PR%, % in 1 ") != NULL) 1457 1.1 christos return IA64_RS_PR; 1458 1.1 christos if (strstr (name, "PR%, % in 16 ") != NULL) 1459 1.1 christos return IA64_RS_PRr; 1460 1.1 christos 1461 1.1 christos warn (_("don't know how to specify %% dependency %s\n"), 1462 1.1 christos name); 1463 1.1 christos } 1464 1.1 christos else if (strchr (name, '#')) 1465 1.1 christos { 1466 1.1 christos if (strstr (name, "CPUID#") != NULL) 1467 1.1 christos return IA64_RS_CPUID; 1468 1.1 christos if (strstr (name, "DBR#") != NULL) 1469 1.1 christos return IA64_RS_DBR; 1470 1.1 christos if (strstr (name, "IBR#") != NULL) 1471 1.1 christos return IA64_RS_IBR; 1472 1.1 christos if (strstr (name, "MSR#") != NULL) 1473 1.1 christos return IA64_RS_MSR; 1474 1.1 christos if (strstr (name, "PKR#") != NULL) 1475 1.1 christos return IA64_RS_PKR; 1476 1.1 christos if (strstr (name, "PMC#") != NULL) 1477 1.1 christos return IA64_RS_PMC; 1478 1.1 christos if (strstr (name, "PMD#") != NULL) 1479 1.6 christos return IA64_RS_PMD; 1480 1.1 christos if (strstr (name, "RR#") != NULL) 1481 1.1 christos return IA64_RS_RR; 1482 1.1 christos 1483 1.10 christos warn (_("Don't know how to specify # dependency %s\n"), 1484 1.1 christos name); 1485 1.10 christos } 1486 1.1 christos else if (startswith (name, "AR[FPSR]")) 1487 1.10 christos return IA64_RS_AR_FPSR; 1488 1.1 christos else if (startswith (name, "AR[")) 1489 1.10 christos return IA64_RS_ARX; 1490 1.1 christos else if (startswith (name, "CR[")) 1491 1.1 christos return IA64_RS_CRX; 1492 1.1 christos else if (startswith (name, "PSR.")) 1493 1.1 christos return IA64_RS_PSR; 1494 1.1 christos else if (strcmp (name, "InService*") == 0) 1495 1.1 christos return IA64_RS_INSERVICE; 1496 1.1 christos else if (strcmp (name, "GR0") == 0) 1497 1.1 christos return IA64_RS_GR0; 1498 1.1 christos else if (strcmp (name, "CFM") == 0) 1499 1.1 christos return IA64_RS_CFM; 1500 1.1 christos else if (strcmp (name, "PR63") == 0) 1501 1.1 christos return IA64_RS_PR63; 1502 1.1 christos else if (strcmp (name, "RSE") == 0) 1503 1.1 christos return IA64_RS_RSE; 1504 1.1 christos 1505 1.1 christos return IA64_RS_ANY; 1506 1.1 christos } 1507 1.1 christos 1508 1.1 christos static void 1509 1.1 christos print_dependency_table (void) 1510 1.6 christos { 1511 1.1 christos int i, j; 1512 1.1 christos 1513 1.1 christos if (debug) 1514 1.1 christos { 1515 1.1 christos for (i=0;i < iclen;i++) 1516 1.1 christos { 1517 1.1 christos if (ics[i]->is_class) 1518 1.1 christos { 1519 1.1 christos if (!ics[i]->nsubs) 1520 1.1 christos { 1521 1.1 christos if (ics[i]->comment) 1522 1.1 christos warn (_("IC:%s [%s] has no terminals or sub-classes\n"), 1523 1.1 christos ics[i]->name, ics[i]->comment); 1524 1.1 christos else 1525 1.1 christos warn (_("IC:%s has no terminals or sub-classes\n"), 1526 1.6 christos ics[i]->name); 1527 1.1 christos } 1528 1.1 christos } 1529 1.1 christos else 1530 1.1 christos { 1531 1.1 christos if (!ics[i]->terminal_resolved && !ics[i]->orphan) 1532 1.1 christos { 1533 1.1 christos if (ics[i]->comment) 1534 1.1 christos warn (_("no insns mapped directly to terminal IC %s [%s]"), 1535 1.1 christos ics[i]->name, ics[i]->comment); 1536 1.1 christos else 1537 1.1 christos warn (_("no insns mapped directly to terminal IC %s\n"), 1538 1.1 christos ics[i]->name); 1539 1.1 christos } 1540 1.1 christos } 1541 1.1 christos } 1542 1.1 christos 1543 1.1 christos for (i = 0; i < iclen; i++) 1544 1.1 christos { 1545 1.1 christos if (ics[i]->orphan) 1546 1.1 christos { 1547 1.1 christos mark_used (ics[i], 1); 1548 1.1 christos warn (_("class %s is defined but not used\n"), 1549 1.1 christos ics[i]->name); 1550 1.1 christos } 1551 1.1 christos } 1552 1.6 christos 1553 1.1 christos if (debug > 1) 1554 1.1 christos for (i = 0; i < rdepslen; i++) 1555 1.1 christos { 1556 1.1 christos static const char *mode_str[] = { "RAW", "WAW", "WAR" }; 1557 1.1 christos 1558 1.6 christos if (rdeps[i]->total_chks == 0) 1559 1.1 christos { 1560 1.1 christos if (rdeps[i]->total_regs) 1561 1.6 christos warn (_("Warning: rsrc %s (%s) has no chks\n"), 1562 1.1 christos rdeps[i]->name, mode_str[rdeps[i]->mode]); 1563 1.1 christos else 1564 1.1 christos warn (_("Warning: rsrc %s (%s) has no chks or regs\n"), 1565 1.1 christos rdeps[i]->name, mode_str[rdeps[i]->mode]); 1566 1.1 christos } 1567 1.1 christos else if (rdeps[i]->total_regs == 0) 1568 1.1 christos warn (_("rsrc %s (%s) has no regs\n"), 1569 1.1 christos rdeps[i]->name, mode_str[rdeps[i]->mode]); 1570 1.1 christos } 1571 1.1 christos } 1572 1.1 christos 1573 1.1 christos /* The dependencies themselves. */ 1574 1.1 christos printf ("static const struct ia64_dependency\ndependencies[] = {\n"); 1575 1.6 christos for (i = 0; i < rdepslen; i++) 1576 1.1 christos { 1577 1.1 christos /* '%', '#', AR[], CR[], or PSR. indicates we need to specify the actual 1578 1.1 christos resource used. */ 1579 1.1 christos int specifier = lookup_specifier (rdeps[i]->name); 1580 1.1 christos int regindex = lookup_regindex (rdeps[i]->name, specifier); 1581 1.1 christos 1582 1.1 christos printf (" { \"%s\", %d, %d, %d, %d, ", 1583 1.1 christos rdeps[i]->name, specifier, 1584 1.1 christos (int)rdeps[i]->mode, (int)rdeps[i]->semantics, regindex); 1585 1.1 christos if (rdeps[i]->semantics == IA64_DVS_OTHER) 1586 1.1 christos { 1587 1.1 christos const char *quote, *rest; 1588 1.1 christos 1589 1.1 christos putchar ('\"'); 1590 1.1 christos rest = rdeps[i]->extra; 1591 1.1 christos quote = strchr (rest, '\"'); 1592 1.1 christos while (quote != NULL) 1593 1.1 christos { 1594 1.1 christos printf ("%.*s\\\"", (int) (quote - rest), rest); 1595 1.1 christos rest = quote + 1; 1596 1.1 christos quote = strchr (rest, '\"'); 1597 1.1 christos } 1598 1.1 christos printf ("%s\", ", rest); 1599 1.1 christos } 1600 1.1 christos else 1601 1.1 christos printf ("NULL, "); 1602 1.1 christos printf("},\n"); 1603 1.1 christos } 1604 1.1 christos printf ("};\n\n"); 1605 1.1 christos 1606 1.6 christos /* And dependency lists. */ 1607 1.6 christos for (i=0;i < dlistlen;i++) 1608 1.1 christos { 1609 1.1 christos unsigned int len = (unsigned) -1; 1610 1.6 christos printf ("static const unsigned short dep%d[] = {", i); 1611 1.1 christos for (j=0;j < dlists[i]->len; j++) 1612 1.6 christos { 1613 1.6 christos if (len > 74) 1614 1.1 christos { 1615 1.6 christos printf("\n "); 1616 1.1 christos len = 1; 1617 1.1 christos } 1618 1.1 christos len += printf (" %d,", dlists[i]->deps[j]); 1619 1.1 christos } 1620 1.1 christos printf ("\n};\n\n"); 1621 1.1 christos } 1622 1.1 christos 1623 1.1 christos /* And opcode dependency list. */ 1624 1.1 christos printf ("#define NELS(X) (sizeof(X)/sizeof(X[0]))\n"); 1625 1.1 christos printf ("static const struct ia64_opcode_dependency\n"); 1626 1.1 christos printf ("op_dependencies[] = {\n"); 1627 1.1 christos for (i = 0; i < opdeplen; i++) 1628 1.1 christos { 1629 1.6 christos printf (" { "); 1630 1.1 christos if (opdeps[i]->chk == -1) 1631 1.1 christos printf ("0, NULL, "); 1632 1.1 christos else 1633 1.6 christos printf ("NELS(dep%d), dep%d, ", opdeps[i]->chk, opdeps[i]->chk); 1634 1.1 christos if (opdeps[i]->reg == -1) 1635 1.1 christos printf ("0, NULL, "); 1636 1.1 christos else 1637 1.1 christos printf ("NELS(dep%d), dep%d, ", opdeps[i]->reg, opdeps[i]->reg); 1638 1.1 christos printf ("},\n"); 1639 1.1 christos } 1640 1.1 christos printf ("};\n\n"); 1641 1.1 christos } 1642 1.1 christos 1643 1.1 christos 1644 1.1 christos /* Add STR to the string table. */ 1646 1.1 christos static struct string_entry * 1647 1.1 christos insert_string (char *str) 1648 1.1 christos { 1649 1.1 christos int start = 0, end = strtablen; 1650 1.1 christos int i, x; 1651 1.1 christos 1652 1.6 christos if (strtablen == strtabtotlen) 1653 1.1 christos { 1654 1.1 christos strtabtotlen += 20; 1655 1.1 christos string_table = (struct string_entry **) 1656 1.1 christos xrealloc (string_table, 1657 1.1 christos sizeof (struct string_entry **) * strtabtotlen); 1658 1.1 christos } 1659 1.1 christos 1660 1.1 christos if (strtablen == 0) 1661 1.1 christos { 1662 1.1 christos strtablen = 1; 1663 1.1 christos string_table[0] = tmalloc (struct string_entry); 1664 1.1 christos string_table[0]->s = xstrdup (str); 1665 1.1 christos string_table[0]->num = 0; 1666 1.1 christos return string_table[0]; 1667 1.1 christos } 1668 1.1 christos 1669 1.1 christos if (strcmp (str, string_table[strtablen - 1]->s) > 0) 1670 1.1 christos i = end; 1671 1.1 christos else if (strcmp (str, string_table[0]->s) < 0) 1672 1.1 christos i = 0; 1673 1.1 christos else 1674 1.1 christos { 1675 1.1 christos while (1) 1676 1.1 christos { 1677 1.1 christos int c; 1678 1.1 christos 1679 1.1 christos i = (start + end) / 2; 1680 1.1 christos c = strcmp (str, string_table[i]->s); 1681 1.1 christos 1682 1.1 christos if (c < 0) 1683 1.1 christos end = i - 1; 1684 1.1 christos else if (c == 0) 1685 1.1 christos return string_table[i]; 1686 1.1 christos else 1687 1.1 christos start = i + 1; 1688 1.1 christos 1689 1.1 christos if (start > end) 1690 1.1 christos break; 1691 1.1 christos } 1692 1.1 christos } 1693 1.1 christos 1694 1.1 christos for (; i > 0 && i < strtablen; i--) 1695 1.1 christos if (strcmp (str, string_table[i - 1]->s) > 0) 1696 1.1 christos break; 1697 1.1 christos 1698 1.1 christos for (; i < strtablen; i++) 1699 1.1 christos if (strcmp (str, string_table[i]->s) < 0) 1700 1.1 christos break; 1701 1.1 christos 1702 1.1 christos for (x = strtablen - 1; x >= i; x--) 1703 1.1 christos { 1704 1.1 christos string_table[x + 1] = string_table[x]; 1705 1.1 christos string_table[x + 1]->num = x + 1; 1706 1.1 christos } 1707 1.1 christos 1708 1.1 christos string_table[i] = tmalloc (struct string_entry); 1709 1.1 christos string_table[i]->s = xstrdup (str); 1710 1.1 christos string_table[i]->num = i; 1711 1.1 christos strtablen++; 1712 1.1 christos 1713 1.1 christos return string_table[i]; 1714 1.1 christos } 1715 1.1 christos 1716 1.1 christos static struct bittree * 1718 1.1 christos make_bittree_entry (void) 1719 1.1 christos { 1720 1.1 christos struct bittree *res = tmalloc (struct bittree); 1721 1.1 christos 1722 1.1 christos res->disent = NULL; 1723 1.1 christos res->bits[0] = NULL; 1724 1.1 christos res->bits[1] = NULL; 1725 1.6 christos res->bits[2] = NULL; 1726 1.1 christos res->skip_flag = 0; 1727 1.1 christos res->bits_to_skip = 0; 1728 1.1 christos return res; 1729 1.1 christos } 1730 1.1 christos 1731 1.1 christos 1732 1.1 christos static struct disent * 1734 1.1 christos add_dis_table_ent (struct disent *which, int insn, int order, 1735 1.1 christos ci_t completer_index) 1736 1.1 christos { 1737 1.1 christos int ci = 0; 1738 1.1 christos struct disent *ent; 1739 1.1 christos 1740 1.1 christos if (which != NULL) 1741 1.1 christos { 1742 1.1 christos ent = which; 1743 1.1 christos 1744 1.1 christos ent->nextcnt++; 1745 1.1 christos while (ent->nexte != NULL) 1746 1.1 christos ent = ent->nexte; 1747 1.1 christos 1748 1.1 christos ent = (ent->nexte = tmalloc (struct disent)); 1749 1.1 christos } 1750 1.1 christos else 1751 1.1 christos { 1752 1.1 christos ent = tmalloc (struct disent); 1753 1.1 christos ent->next_ent = disinsntable; 1754 1.1 christos disinsntable = ent; 1755 1.1 christos which = ent; 1756 1.1 christos } 1757 1.1 christos ent->nextcnt = 0; 1758 1.1 christos ent->nexte = NULL; 1759 1.1 christos ent->insn = insn; 1760 1.1 christos ent->priority = order; 1761 1.1 christos 1762 1.1 christos while (completer_index != 1) 1763 1.1 christos { 1764 1.1 christos ci = (ci << 1) | (completer_index & 1); 1765 1.1 christos completer_index >>= 1; 1766 1.1 christos } 1767 1.1 christos ent->completer_index = ci; 1768 1.1 christos return which; 1769 1.1 christos } 1770 1.1 christos 1771 1.1 christos static void 1773 1.1 christos finish_distable (void) 1774 1.1 christos { 1775 1.1 christos struct disent *ent = disinsntable; 1776 1.1 christos struct disent *prev = ent; 1777 1.1 christos 1778 1.1 christos ent->ournum = 32768; 1779 1.1 christos while ((ent = ent->next_ent) != NULL) 1780 1.1 christos { 1781 1.1 christos ent->ournum = prev->ournum + prev->nextcnt + 1; 1782 1.1 christos prev = ent; 1783 1.1 christos } 1784 1.1 christos } 1785 1.1 christos 1786 1.1 christos static void 1788 1.1 christos insert_bit_table_ent (struct bittree *curr_ent, int bit, ia64_insn opcode, 1789 1.1 christos ia64_insn mask, int opcodenum, int order, 1790 1.6 christos ci_t completer_index) 1791 1.1 christos { 1792 1.1 christos ia64_insn m; 1793 1.1 christos int b; 1794 1.1 christos struct bittree *next; 1795 1.1 christos 1796 1.1 christos if (bit == -1) 1797 1.1 christos { 1798 1.1 christos struct disent *nent = add_dis_table_ent (curr_ent->disent, 1799 1.1 christos opcodenum, order, 1800 1.1 christos completer_index); 1801 1.1 christos curr_ent->disent = nent; 1802 1.1 christos return; 1803 1.1 christos } 1804 1.1 christos 1805 1.1 christos m = ((ia64_insn) 1) << bit; 1806 1.1 christos 1807 1.1 christos if (mask & m) 1808 1.1 christos b = (opcode & m) ? 1 : 0; 1809 1.1 christos else 1810 1.1 christos b = 2; 1811 1.1 christos 1812 1.1 christos next = curr_ent->bits[b]; 1813 1.1 christos if (next == NULL) 1814 1.1 christos { 1815 1.1 christos next = make_bittree_entry (); 1816 1.1 christos curr_ent->bits[b] = next; 1817 1.1 christos } 1818 1.1 christos insert_bit_table_ent (next, bit - 1, opcode, mask, opcodenum, order, 1819 1.1 christos completer_index); 1820 1.1 christos } 1821 1.1 christos 1822 1.1 christos static void 1824 1.1 christos add_dis_entry (struct bittree *first, ia64_insn opcode, ia64_insn mask, 1825 1.1 christos int opcodenum, struct completer_entry *ent, ci_t completer_index) 1826 1.1 christos { 1827 1.1 christos if (completer_index & ((ci_t)1 << 32) ) 1828 1.1 christos abort (); 1829 1.6 christos 1830 1.6 christos while (ent != NULL) 1831 1.1 christos { 1832 1.1 christos ia64_insn newopcode = (opcode & (~ ent->mask)) | ent->bits; 1833 1.1 christos add_dis_entry (first, newopcode, mask, opcodenum, ent->addl_entries, 1834 1.1 christos (completer_index << 1) | 1); 1835 1.1 christos 1836 1.1 christos if (ent->is_terminal) 1837 1.1 christos { 1838 1.1 christos insert_bit_table_ent (bittree, 40, newopcode, mask, 1839 1.1 christos opcodenum, opcode_count - ent->order - 1, 1840 1.1 christos (completer_index << 1) | 1); 1841 1.1 christos } 1842 1.1 christos completer_index <<= 1; 1843 1.1 christos ent = ent->alternative; 1844 1.1 christos } 1845 1.1 christos } 1846 1.1 christos 1847 1.1 christos /* This optimization pass combines multiple "don't care" nodes. */ 1849 1.1 christos static void 1850 1.1 christos compact_distree (struct bittree *ent) 1851 1.1 christos { 1852 1.1 christos #define IS_SKIP(ent) \ 1853 1.1 christos ((ent->bits[2] !=NULL) \ 1854 1.1 christos && (ent->bits[0] == NULL && ent->bits[1] == NULL && ent->skip_flag == 0)) 1855 1.1 christos 1856 1.1 christos int bitcnt = 0; 1857 1.1 christos struct bittree *nent = ent; 1858 1.1 christos int x; 1859 1.1 christos 1860 1.1 christos while (IS_SKIP (nent)) 1861 1.1 christos { 1862 1.1 christos bitcnt++; 1863 1.1 christos nent = nent->bits[2]; 1864 1.1 christos } 1865 1.1 christos 1866 1.1 christos if (bitcnt) 1867 1.1 christos { 1868 1.1 christos struct bittree *next = ent->bits[2]; 1869 1.1 christos 1870 1.1 christos ent->bits[0] = nent->bits[0]; 1871 1.1 christos ent->bits[1] = nent->bits[1]; 1872 1.1 christos ent->bits[2] = nent->bits[2]; 1873 1.1 christos ent->disent = nent->disent; 1874 1.1 christos ent->skip_flag = 1; 1875 1.1 christos ent->bits_to_skip = bitcnt; 1876 1.1 christos while (next != nent) 1877 1.1 christos { 1878 1.1 christos struct bittree *b = next; 1879 1.1 christos next = next->bits[2]; 1880 1.1 christos free (b); 1881 1.1 christos } 1882 1.1 christos free (nent); 1883 1.1 christos } 1884 1.1 christos 1885 1.1 christos for (x = 0; x < 3; x++) 1886 1.1 christos { 1887 1.1 christos struct bittree *i = ent->bits[x]; 1888 1.1 christos 1889 1.1 christos if (i != NULL) 1890 1.1 christos compact_distree (i); 1891 1.1 christos } 1892 1.1 christos } 1893 1.1 christos 1894 1.1 christos static unsigned char *insn_list; 1896 1.1 christos static int insn_list_len = 0; 1897 1.1 christos static int tot_insn_list_len = 0; 1898 1.1 christos 1899 1.1 christos /* Generate the disassembler state machine corresponding to the tree 1900 1.1 christos in ENT. */ 1901 1.1 christos static void 1902 1.1 christos gen_dis_table (struct bittree *ent) 1903 1.1 christos { 1904 1.1 christos int x; 1905 1.1 christos int our_offset = insn_list_len; 1906 1.1 christos int bitsused = 5; 1907 1.1 christos int totbits = bitsused; 1908 1.1 christos int needed_bytes; 1909 1.1 christos int zero_count = 0; 1910 1.1 christos int zero_dest = 0; /* Initialize this with 0 to keep gcc quiet... */ 1911 1.1 christos 1912 1.1 christos /* If this is a terminal entry, there's no point in skipping any 1913 1.1 christos bits. */ 1914 1.1 christos if (ent->skip_flag && ent->bits[0] == NULL && ent->bits[1] == NULL && 1915 1.1 christos ent->bits[2] == NULL) 1916 1.1 christos { 1917 1.1 christos if (ent->disent == NULL) 1918 1.1 christos abort (); 1919 1.1 christos else 1920 1.1 christos ent->skip_flag = 0; 1921 1.1 christos } 1922 1.1 christos 1923 1.1 christos /* Calculate the amount of space needed for this entry, or at least 1924 1.1 christos a conservatively large approximation. */ 1925 1.1 christos if (ent->skip_flag) 1926 1.1 christos totbits += 5; 1927 1.1 christos 1928 1.1 christos for (x = 1; x < 3; x++) 1929 1.1 christos if (ent->bits[x] != NULL) 1930 1.1 christos totbits += 16; 1931 1.1 christos 1932 1.1 christos if (ent->disent != NULL) 1933 1.1 christos { 1934 1.1 christos if (ent->bits[2] != NULL) 1935 1.1 christos abort (); 1936 1.1 christos 1937 1.1 christos totbits += 16; 1938 1.1 christos } 1939 1.1 christos 1940 1.1 christos /* Now allocate the space. */ 1941 1.1 christos needed_bytes = (totbits + 7) / 8; 1942 1.1 christos if ((needed_bytes + insn_list_len) > tot_insn_list_len) 1943 1.1 christos { 1944 1.1 christos tot_insn_list_len += 256; 1945 1.1 christos insn_list = (unsigned char *) xrealloc (insn_list, tot_insn_list_len); 1946 1.1 christos } 1947 1.1 christos our_offset = insn_list_len; 1948 1.1 christos insn_list_len += needed_bytes; 1949 1.1 christos memset (insn_list + our_offset, 0, needed_bytes); 1950 1.1 christos 1951 1.1 christos /* Encode the skip entry by setting bit 6 set in the state op field, 1952 1.1 christos and store the # of bits to skip immediately after. */ 1953 1.1 christos if (ent->skip_flag) 1954 1.1 christos { 1955 1.1 christos bitsused += 5; 1956 1.1 christos insn_list[our_offset + 0] |= 0x40 | ((ent->bits_to_skip >> 2) & 0xf); 1957 1.1 christos insn_list[our_offset + 1] |= ((ent->bits_to_skip & 3) << 6); 1958 1.1 christos } 1959 1.1 christos 1960 1.1 christos #define IS_ONLY_IFZERO(ENT) \ 1961 1.1 christos ((ENT)->bits[0] != NULL && (ENT)->bits[1] == NULL && (ENT)->bits[2] == NULL \ 1962 1.1 christos && (ENT)->disent == NULL && (ENT)->skip_flag == 0) 1963 1.1 christos 1964 1.1 christos /* Store an "if (bit is zero)" instruction by setting bit 7 in the 1965 1.1 christos state op field. */ 1966 1.1 christos if (ent->bits[0] != NULL) 1967 1.1 christos { 1968 1.1 christos struct bittree *nent = ent->bits[0]; 1969 1.1 christos zero_count = 0; 1970 1.1 christos 1971 1.1 christos insn_list[our_offset] |= 0x80; 1972 1.1 christos 1973 1.1 christos /* We can encode sequences of multiple "if (bit is zero)" tests 1974 1.1 christos by storing the # of zero bits to check in the lower 3 bits of 1975 1.1 christos the instruction. However, this only applies if the state 1976 1.1 christos solely tests for a zero bit. */ 1977 1.1 christos 1978 1.1 christos if (IS_ONLY_IFZERO (ent)) 1979 1.1 christos { 1980 1.1 christos while (IS_ONLY_IFZERO (nent) && zero_count < 7) 1981 1.1 christos { 1982 1.1 christos nent = nent->bits[0]; 1983 1.1 christos zero_count++; 1984 1.1 christos } 1985 1.1 christos 1986 1.1 christos insn_list[our_offset + 0] |= zero_count; 1987 1.1 christos } 1988 1.1 christos zero_dest = insn_list_len; 1989 1.1 christos gen_dis_table (nent); 1990 1.1 christos } 1991 1.1 christos 1992 1.1 christos /* Now store the remaining tests. We also handle a sole "termination 1993 1.1 christos entry" by storing it as an "any bit" test. */ 1994 1.1 christos 1995 1.1 christos for (x = 1; x < 3; x++) 1996 1.1 christos { 1997 1.1 christos if (ent->bits[x] != NULL || (x == 2 && ent->disent != NULL)) 1998 1.1 christos { 1999 1.1 christos struct bittree *i = ent->bits[x]; 2000 1.1 christos int idest; 2001 1.1 christos int currbits = 15; 2002 1.1 christos 2003 1.1 christos if (i != NULL) 2004 1.1 christos { 2005 1.1 christos /* If the instruction being branched to only consists of 2006 1.1 christos a termination entry, use the termination entry as the 2007 1.1 christos place to branch to instead. */ 2008 1.1 christos if (i->bits[0] == NULL && i->bits[1] == NULL 2009 1.6 christos && i->bits[2] == NULL && i->disent != NULL) 2010 1.1 christos { 2011 1.1 christos idest = i->disent->ournum; 2012 1.1 christos i = NULL; 2013 1.1 christos } 2014 1.1 christos else 2015 1.1 christos idest = insn_list_len - our_offset; 2016 1.1 christos } 2017 1.1 christos else 2018 1.1 christos idest = ent->disent->ournum; 2019 1.1 christos 2020 1.1 christos /* If the destination offset for the if (bit is 1) test is less 2021 1.1 christos than 256 bytes away, we can store it as 8-bits instead of 16; 2022 1.1 christos the instruction has bit 5 set for the 16-bit address, and bit 2023 1.1 christos 4 for the 8-bit address. Since we've already allocated 16 2024 1.1 christos bits for the address we need to deallocate the space. 2025 1.1 christos 2026 1.1 christos Note that branchings within the table are relative, and 2027 1.1 christos there are no branches that branch past our instruction yet 2028 1.1 christos so we do not need to adjust any other offsets. */ 2029 1.1 christos if (x == 1) 2030 1.1 christos { 2031 1.1 christos if (idest <= 256) 2032 1.1 christos { 2033 1.1 christos int start = our_offset + bitsused / 8 + 1; 2034 1.1 christos 2035 1.1 christos memmove (insn_list + start, 2036 1.1 christos insn_list + start + 1, 2037 1.1 christos insn_list_len - (start + 1)); 2038 1.1 christos currbits = 7; 2039 1.1 christos totbits -= 8; 2040 1.1 christos needed_bytes--; 2041 1.1 christos insn_list_len--; 2042 1.1 christos insn_list[our_offset] |= 0x10; 2043 1.1 christos idest--; 2044 1.1 christos } 2045 1.1 christos else 2046 1.1 christos insn_list[our_offset] |= 0x20; 2047 1.1 christos } 2048 1.1 christos else 2049 1.1 christos { 2050 1.1 christos /* An instruction which solely consists of a termination 2051 1.1 christos marker and whose disassembly name index is < 4096 2052 1.1 christos can be stored in 16 bits. The encoding is slightly 2053 1.1 christos odd; the upper 4 bits of the instruction are 0x3, and 2054 1.1 christos bit 3 loses its normal meaning. */ 2055 1.1 christos 2056 1.1 christos if (ent->bits[0] == NULL && ent->bits[1] == NULL 2057 1.1 christos && ent->bits[2] == NULL && ent->skip_flag == 0 2058 1.1 christos && ent->disent != NULL 2059 1.1 christos && ent->disent->ournum < (32768 + 4096)) 2060 1.1 christos { 2061 1.1 christos int start = our_offset + bitsused / 8 + 1; 2062 1.1 christos 2063 1.1 christos memmove (insn_list + start, 2064 1.1 christos insn_list + start + 1, 2065 1.1 christos insn_list_len - (start + 1)); 2066 1.1 christos currbits = 11; 2067 1.1 christos totbits -= 5; 2068 1.1 christos bitsused--; 2069 1.1 christos needed_bytes--; 2070 1.1 christos insn_list_len--; 2071 1.1 christos insn_list[our_offset] |= 0x30; 2072 1.1 christos idest &= ~32768; 2073 1.1 christos } 2074 1.1 christos else 2075 1.1 christos insn_list[our_offset] |= 0x08; 2076 1.1 christos } 2077 1.1 christos 2078 1.1 christos if (debug) 2079 1.1 christos { 2080 1.1 christos int id = idest; 2081 1.1 christos 2082 1.1 christos if (i == NULL) 2083 1.1 christos id |= 32768; 2084 1.1 christos else if (! (id & 32768)) 2085 1.1 christos id += our_offset; 2086 1.1 christos 2087 1.1 christos if (x == 1) 2088 1.1 christos printf ("%d: if (1) goto %d\n", our_offset, id); 2089 1.1 christos else 2090 1.1 christos printf ("%d: try %d\n", our_offset, id); 2091 1.1 christos } 2092 1.1 christos 2093 1.1 christos /* Store the address of the entry being branched to. */ 2094 1.1 christos while (currbits >= 0) 2095 1.1 christos { 2096 1.1 christos unsigned char *byte = insn_list + our_offset + bitsused / 8; 2097 1.1 christos 2098 1.1 christos if (idest & (1 << currbits)) 2099 1.1 christos *byte |= (1 << (7 - (bitsused % 8))); 2100 1.1 christos 2101 1.1 christos bitsused++; 2102 1.1 christos currbits--; 2103 1.1 christos } 2104 1.6 christos 2105 1.1 christos /* Now generate the states for the entry being branched to. */ 2106 1.1 christos if (i != NULL) 2107 1.1 christos gen_dis_table (i); 2108 1.1 christos } 2109 1.1 christos } 2110 1.1 christos 2111 1.1 christos if (debug) 2112 1.1 christos { 2113 1.1 christos if (ent->skip_flag) 2114 1.1 christos printf ("%d: skipping %d\n", our_offset, ent->bits_to_skip); 2115 1.1 christos 2116 1.1 christos if (ent->bits[0] != NULL) 2117 1.1 christos printf ("%d: if (0:%d) goto %d\n", our_offset, zero_count + 1, 2118 1.1 christos zero_dest); 2119 1.1 christos } 2120 1.6 christos 2121 1.1 christos if (bitsused != totbits) 2122 1.1 christos abort (); 2123 1.6 christos } 2124 1.6 christos 2125 1.1 christos static void 2127 1.1 christos print_dis_table (void) 2128 1.1 christos { 2129 1.1 christos int x; 2130 1.1 christos struct disent *cent = disinsntable; 2131 1.1 christos 2132 1.1 christos printf ("static const char dis_table[] = {"); 2133 1.1 christos for (x = 0; x < insn_list_len; x++) 2134 1.1 christos { 2135 1.1 christos if (x % 12 == 0) 2136 1.1 christos printf ("\n "); 2137 1.1 christos 2138 1.1 christos printf (" 0x%02x,", insn_list[x]); 2139 1.1 christos } 2140 1.1 christos printf ("\n};\n\n"); 2141 1.1 christos 2142 1.1 christos printf ("static const struct ia64_dis_names ia64_dis_names[] = {\n"); 2143 1.1 christos while (cent != NULL) 2144 1.1 christos { 2145 1.1 christos struct disent *ent = cent; 2146 1.1 christos 2147 1.1 christos while (ent != NULL) 2148 1.1 christos { 2149 1.1 christos printf ("{ 0x%lx, %d, %d, %d },\n", ( long ) ent->completer_index, 2150 1.1 christos ent->insn, (ent->nexte != NULL ? 1 : 0), 2151 1.1 christos ent->priority); 2152 1.1 christos ent = ent->nexte; 2153 1.1 christos } 2154 1.1 christos cent = cent->next_ent; 2155 1.1 christos } 2156 1.1 christos printf ("};\n\n"); 2157 1.1 christos } 2158 1.1 christos 2159 1.1 christos static void 2161 1.1 christos generate_disassembler (void) 2162 1.1 christos { 2163 1.1 christos int i; 2164 1.1 christos 2165 1.1 christos bittree = make_bittree_entry (); 2166 1.1 christos 2167 1.1 christos for (i = 0; i < otlen; i++) 2168 1.1 christos { 2169 1.1 christos struct main_entry *ptr = ordered_table[i]; 2170 1.1 christos 2171 1.1 christos if (ptr->opcode->type != IA64_TYPE_DYN) 2172 1.1 christos add_dis_entry (bittree, 2173 1.1 christos ptr->opcode->opcode, ptr->opcode->mask, 2174 1.1 christos ptr->main_index, 2175 1.1 christos ptr->completers, 1); 2176 1.1 christos } 2177 1.1 christos 2178 1.1 christos compact_distree (bittree); 2179 1.1 christos finish_distable (); 2180 1.1 christos gen_dis_table (bittree); 2181 1.1 christos 2182 1.1 christos print_dis_table (); 2183 1.1 christos } 2184 1.1 christos 2185 1.6 christos static void 2187 1.1 christos print_string_table (void) 2188 1.1 christos { 2189 1.1 christos int x; 2190 1.1 christos char lbuf[80], buf[80]; 2191 1.1 christos int blen = 0; 2192 1.1 christos 2193 1.1 christos printf ("static const char * const ia64_strings[] = {\n"); 2194 1.1 christos lbuf[0] = '\0'; 2195 1.1 christos 2196 1.1 christos for (x = 0; x < strtablen; x++) 2197 1.1 christos { 2198 1.1 christos int len; 2199 1.1 christos 2200 1.1 christos if (strlen (string_table[x]->s) > 75) 2201 1.1 christos abort (); 2202 1.1 christos 2203 1.1 christos sprintf (buf, " \"%s\",", string_table[x]->s); 2204 1.1 christos len = strlen (buf); 2205 1.1 christos 2206 1.1 christos if ((blen + len) > 75) 2207 1.1 christos { 2208 1.1 christos printf (" %s\n", lbuf); 2209 1.1 christos lbuf[0] = '\0'; 2210 1.1 christos blen = 0; 2211 1.1 christos } 2212 1.1 christos strcat (lbuf, buf); 2213 1.1 christos blen += len; 2214 1.1 christos } 2215 1.1 christos 2216 1.1 christos if (blen > 0) 2217 1.1 christos printf (" %s\n", lbuf); 2218 1.1 christos 2219 1.1 christos printf ("};\n\n"); 2220 1.1 christos } 2221 1.1 christos 2222 1.1 christos static struct completer_entry **glist; 2224 1.1 christos static int glistlen = 0; 2225 1.1 christos static int glisttotlen = 0; 2226 1.1 christos 2227 1.1 christos /* If the completer trees ENT1 and ENT2 are equal, return 1. */ 2228 1.1 christos 2229 1.1 christos static int 2230 1.1 christos completer_entries_eq (struct completer_entry *ent1, 2231 1.1 christos struct completer_entry *ent2) 2232 1.1 christos { 2233 1.1 christos while (ent1 != NULL && ent2 != NULL) 2234 1.1 christos { 2235 1.1 christos if (ent1->name->num != ent2->name->num 2236 1.1 christos || ent1->bits != ent2->bits 2237 1.1 christos || ent1->mask != ent2->mask 2238 1.1 christos || ent1->is_terminal != ent2->is_terminal 2239 1.1 christos || ent1->dependencies != ent2->dependencies 2240 1.1 christos || ent1->order != ent2->order) 2241 1.1 christos return 0; 2242 1.1 christos 2243 1.1 christos if (! completer_entries_eq (ent1->addl_entries, ent2->addl_entries)) 2244 1.1 christos return 0; 2245 1.1 christos 2246 1.1 christos ent1 = ent1->alternative; 2247 1.1 christos ent2 = ent2->alternative; 2248 1.1 christos } 2249 1.1 christos 2250 1.1 christos return ent1 == ent2; 2251 1.1 christos } 2252 1.1 christos 2253 1.1 christos /* Insert ENT into the global list of completers and return it. If an 2255 1.1 christos equivalent entry (according to completer_entries_eq) already exists, 2256 1.1 christos it is returned instead. */ 2257 1.1 christos static struct completer_entry * 2258 1.1 christos insert_gclist (struct completer_entry *ent) 2259 1.1 christos { 2260 1.1 christos if (ent != NULL) 2261 1.1 christos { 2262 1.1 christos int i; 2263 1.1 christos int x; 2264 1.1 christos int start = 0, end; 2265 1.1 christos 2266 1.1 christos ent->addl_entries = insert_gclist (ent->addl_entries); 2267 1.1 christos ent->alternative = insert_gclist (ent->alternative); 2268 1.1 christos 2269 1.1 christos i = glistlen / 2; 2270 1.1 christos end = glistlen; 2271 1.1 christos 2272 1.1 christos if (glisttotlen == glistlen) 2273 1.1 christos { 2274 1.1 christos glisttotlen += 20; 2275 1.1 christos glist = (struct completer_entry **) 2276 1.1 christos xrealloc (glist, sizeof (struct completer_entry *) * glisttotlen); 2277 1.1 christos } 2278 1.1 christos 2279 1.1 christos if (glistlen == 0) 2280 1.1 christos { 2281 1.1 christos glist[0] = ent; 2282 1.1 christos glistlen = 1; 2283 1.1 christos return ent; 2284 1.1 christos } 2285 1.1 christos 2286 1.1 christos if (ent->name->num < glist[0]->name->num) 2287 1.6 christos i = 0; 2288 1.1 christos else if (ent->name->num > glist[end - 1]->name->num) 2289 1.1 christos i = end; 2290 1.1 christos else 2291 1.1 christos { 2292 1.1 christos int c; 2293 1.1 christos 2294 1.1 christos while (1) 2295 1.1 christos { 2296 1.1 christos i = (start + end) / 2; 2297 1.1 christos c = ent->name->num - glist[i]->name->num; 2298 1.1 christos 2299 1.1 christos if (c < 0) 2300 1.1 christos end = i - 1; 2301 1.1 christos else if (c == 0) 2302 1.1 christos { 2303 1.1 christos while (i > 0 2304 1.1 christos && ent->name->num == glist[i - 1]->name->num) 2305 1.1 christos i--; 2306 1.1 christos 2307 1.1 christos break; 2308 1.1 christos } 2309 1.1 christos else 2310 1.1 christos start = i + 1; 2311 1.1 christos 2312 1.1 christos if (start > end) 2313 1.1 christos break; 2314 1.1 christos } 2315 1.1 christos 2316 1.1 christos if (c == 0) 2317 1.1 christos { 2318 1.1 christos while (i < glistlen) 2319 1.1 christos { 2320 1.1 christos if (ent->name->num != glist[i]->name->num) 2321 1.1 christos break; 2322 1.1 christos 2323 1.1 christos if (completer_entries_eq (ent, glist[i])) 2324 1.1 christos return glist[i]; 2325 1.1 christos 2326 1.1 christos i++; 2327 1.1 christos } 2328 1.1 christos } 2329 1.1 christos } 2330 1.1 christos 2331 1.1 christos for (; i > 0 && i < glistlen; i--) 2332 1.1 christos if (ent->name->num >= glist[i - 1]->name->num) 2333 1.1 christos break; 2334 1.1 christos 2335 1.1 christos for (; i < glistlen; i++) 2336 1.1 christos if (ent->name->num < glist[i]->name->num) 2337 1.1 christos break; 2338 1.1 christos 2339 1.1 christos for (x = glistlen - 1; x >= i; x--) 2340 1.1 christos glist[x + 1] = glist[x]; 2341 1.1 christos 2342 1.1 christos glist[i] = ent; 2343 1.1 christos glistlen++; 2344 1.1 christos } 2345 1.1 christos return ent; 2346 1.1 christos } 2347 1.1 christos 2348 1.1 christos static int 2350 1.1 christos get_prefix_len (const char *name) 2351 1.1 christos { 2352 1.1 christos char *c; 2353 1.1 christos 2354 1.1 christos if (name[0] == '\0') 2355 1.1 christos return 0; 2356 1.1 christos 2357 1.1 christos c = strchr (name, '.'); 2358 1.1 christos if (c != NULL) 2359 1.1 christos return c - name; 2360 1.1 christos else 2361 1.1 christos return strlen (name); 2362 1.1 christos } 2363 1.1 christos 2364 1.6 christos static void 2366 1.1 christos compute_completer_bits (struct main_entry *ment, struct completer_entry *ent) 2367 1.1 christos { 2368 1.1 christos while (ent != NULL) 2369 1.1 christos { 2370 1.1 christos compute_completer_bits (ment, ent->addl_entries); 2371 1.1 christos 2372 1.1 christos if (ent->is_terminal) 2373 1.1 christos { 2374 1.1 christos ia64_insn mask = 0; 2375 1.1 christos ia64_insn our_bits = ent->bits; 2376 1.1 christos struct completer_entry *p = ent->parent; 2377 1.1 christos ia64_insn p_bits; 2378 1.1 christos int x; 2379 1.1 christos 2380 1.1 christos while (p != NULL && ! p->is_terminal) 2381 1.1 christos p = p->parent; 2382 1.1 christos 2383 1.1 christos if (p != NULL) 2384 1.1 christos p_bits = p->bits; 2385 1.1 christos else 2386 1.1 christos p_bits = ment->opcode->opcode; 2387 1.1 christos 2388 1.1 christos for (x = 0; x < 64; x++) 2389 1.1 christos { 2390 1.1 christos ia64_insn m = ((ia64_insn) 1) << x; 2391 1.1 christos 2392 1.1 christos if ((p_bits & m) != (our_bits & m)) 2393 1.1 christos mask |= m; 2394 1.1 christos else 2395 1.1 christos our_bits &= ~m; 2396 1.1 christos } 2397 1.1 christos ent->bits = our_bits; 2398 1.1 christos ent->mask = mask; 2399 1.1 christos } 2400 1.1 christos else 2401 1.1 christos { 2402 1.1 christos ent->bits = 0; 2403 1.1 christos ent->mask = 0; 2404 1.1 christos } 2405 1.1 christos 2406 1.1 christos ent = ent->alternative; 2407 1.1 christos } 2408 1.1 christos } 2409 1.1 christos 2410 1.1 christos /* Find identical completer trees that are used in different 2412 1.1 christos instructions and collapse their entries. */ 2413 1.1 christos static void 2414 1.1 christos collapse_redundant_completers (void) 2415 1.1 christos { 2416 1.1 christos struct main_entry *ptr; 2417 1.6 christos int x; 2418 1.1 christos 2419 1.1 christos for (ptr = maintable; ptr != NULL; ptr = ptr->next) 2420 1.1 christos { 2421 1.1 christos if (ptr->completers == NULL) 2422 1.1 christos abort (); 2423 1.1 christos 2424 1.1 christos compute_completer_bits (ptr, ptr->completers); 2425 1.1 christos ptr->completers = insert_gclist (ptr->completers); 2426 1.1 christos } 2427 1.1 christos 2428 1.6 christos /* The table has been finalized, now number the indexes. */ 2429 1.1 christos for (x = 0; x < glistlen; x++) 2430 1.1 christos glist[x]->num = x; 2431 1.1 christos } 2432 1.1 christos 2433 1.1 christos 2435 1.1 christos /* Attach two lists of dependencies to each opcode. 2436 1.1 christos 1) all resources which, when already marked in use, conflict with this 2437 1.1 christos opcode (chks) 2438 1.1 christos 2) all resources which must be marked in use when this opcode is used 2439 1.1 christos (regs). */ 2440 1.10 christos static int 2441 1.1 christos insert_opcode_dependencies (struct ia64_opcode *opc, 2442 1.1 christos struct completer_entry *cmp ATTRIBUTE_UNUSED) 2443 1.1 christos { 2444 1.1 christos /* Note all resources which point to this opcode. rfi has the most chks 2445 1.1 christos (79) and cmpxchng has the most regs (54) so 100 here should be enough. */ 2446 1.1 christos int i; 2447 1.1 christos int nregs = 0; 2448 1.1 christos unsigned short regs[256]; 2449 1.1 christos int nchks = 0; 2450 1.1 christos unsigned short chks[256]; 2451 1.10 christos /* Flag insns for which no class matched; there should be none. */ 2452 1.1 christos int no_class_found = 1; 2453 1.1 christos 2454 1.1 christos for (i = 0; i < rdepslen; i++) 2455 1.1 christos { 2456 1.1 christos struct rdep *rs = rdeps[i]; 2457 1.1 christos int j; 2458 1.1 christos 2459 1.1 christos if (strcmp (opc->name, "cmp.eq.and") == 0 2460 1.1 christos && startswith (rs->name, "PR%") 2461 1.1 christos && rs->mode == 1) 2462 1.1 christos no_class_found = 99; 2463 1.1 christos 2464 1.1 christos for (j=0; j < rs->nregs;j++) 2465 1.1 christos { 2466 1.1 christos int ic_note = 0; 2467 1.1 christos 2468 1.1 christos if (in_iclass (opc, ics[rs->regs[j]], NULL, NULL, &ic_note)) 2469 1.1 christos { 2470 1.1 christos /* We can ignore ic_note 11 for non PR resources. */ 2471 1.1 christos if (ic_note == 11 && ! startswith (rs->name, "PR")) 2472 1.1 christos ic_note = 0; 2473 1.1 christos 2474 1.1 christos if (ic_note != 0 && rs->regnotes[j] != 0 2475 1.1 christos && ic_note != rs->regnotes[j] 2476 1.1 christos && !(ic_note == 11 && rs->regnotes[j] == 1)) 2477 1.1 christos warn (_("IC note %d in opcode %s (IC:%s) conflicts with resource %s note %d\n"), 2478 1.1 christos ic_note, opc->name, ics[rs->regs[j]]->name, 2479 1.10 christos rs->name, rs->regnotes[j]); 2480 1.1 christos /* Instruction class notes override resource notes. 2481 1.1 christos So far, only note 11 applies to an IC instead of a resource, 2482 1.1 christos and note 11 implies note 1. */ 2483 1.1 christos if (ic_note) 2484 1.1 christos regs[nregs++] = RDEP(ic_note, i); 2485 1.1 christos else 2486 1.1 christos regs[nregs++] = RDEP(rs->regnotes[j], i); 2487 1.1 christos no_class_found = 0; 2488 1.1 christos ++rs->total_regs; 2489 1.1 christos } 2490 1.1 christos } 2491 1.1 christos 2492 1.1 christos for (j = 0; j < rs->nchks; j++) 2493 1.1 christos { 2494 1.1 christos int ic_note = 0; 2495 1.1 christos 2496 1.1 christos if (in_iclass (opc, ics[rs->chks[j]], NULL, NULL, &ic_note)) 2497 1.1 christos { 2498 1.1 christos /* We can ignore ic_note 11 for non PR resources. */ 2499 1.1 christos if (ic_note == 11 && ! startswith (rs->name, "PR")) 2500 1.6 christos ic_note = 0; 2501 1.1 christos 2502 1.1 christos if (ic_note != 0 && rs->chknotes[j] != 0 2503 1.1 christos && ic_note != rs->chknotes[j] 2504 1.1 christos && !(ic_note == 11 && rs->chknotes[j] == 1)) 2505 1.1 christos warn (_("IC note %d for opcode %s (IC:%s) conflicts with resource %s note %d\n"), 2506 1.1 christos ic_note, opc->name, ics[rs->chks[j]]->name, 2507 1.1 christos rs->name, rs->chknotes[j]); 2508 1.1 christos if (ic_note) 2509 1.1 christos chks[nchks++] = RDEP(ic_note, i); 2510 1.1 christos else 2511 1.1 christos chks[nchks++] = RDEP(rs->chknotes[j], i); 2512 1.1 christos no_class_found = 0; 2513 1.1 christos ++rs->total_chks; 2514 1.1 christos } 2515 1.1 christos } 2516 1.1 christos } 2517 1.1 christos 2518 1.1 christos if (no_class_found) 2519 1.1 christos warn (_("opcode %s has no class (ops %d %d %d)\n"), 2520 1.1 christos opc->name, 2521 1.1 christos opc->operands[0], opc->operands[1], opc->operands[2]); 2522 1.1 christos 2523 1.1 christos return insert_dependencies (nchks, chks, nregs, regs); 2524 1.1 christos } 2525 1.1 christos 2526 1.1 christos static void 2528 1.1 christos insert_completer_entry (struct ia64_opcode *opc, struct main_entry *tabent, 2529 1.1 christos int order) 2530 1.1 christos { 2531 1.1 christos struct completer_entry **ptr = &tabent->completers; 2532 1.1 christos struct completer_entry *parent = NULL; 2533 1.1 christos char pcopy[129], *prefix; 2534 1.1 christos int at_end = 0; 2535 1.1 christos 2536 1.1 christos if (strlen (opc->name) > 128) 2537 1.1 christos abort (); 2538 1.1 christos 2539 1.1 christos strcpy (pcopy, opc->name); 2540 1.1 christos prefix = pcopy + get_prefix_len (pcopy); 2541 1.1 christos 2542 1.1 christos if (prefix[0] != '\0') 2543 1.1 christos prefix++; 2544 1.1 christos 2545 1.1 christos while (! at_end) 2546 1.1 christos { 2547 1.1 christos int need_new_ent = 1; 2548 1.1 christos int plen = get_prefix_len (prefix); 2549 1.1 christos struct string_entry *sent; 2550 1.1 christos 2551 1.1 christos at_end = (prefix[plen] == '\0'); 2552 1.1 christos prefix[plen] = '\0'; 2553 1.1 christos sent = insert_string (prefix); 2554 1.1 christos 2555 1.1 christos while (*ptr != NULL) 2556 1.1 christos { 2557 1.1 christos int cmpres = sent->num - (*ptr)->name->num; 2558 1.1 christos 2559 1.1 christos if (cmpres == 0) 2560 1.1 christos { 2561 1.1 christos need_new_ent = 0; 2562 1.1 christos break; 2563 1.1 christos } 2564 1.1 christos else 2565 1.1 christos ptr = &((*ptr)->alternative); 2566 1.1 christos } 2567 1.1 christos 2568 1.1 christos if (need_new_ent) 2569 1.1 christos { 2570 1.1 christos struct completer_entry *nent = tmalloc (struct completer_entry); 2571 1.1 christos 2572 1.1 christos nent->name = sent; 2573 1.1 christos nent->parent = parent; 2574 1.1 christos nent->addl_entries = NULL; 2575 1.1 christos nent->alternative = *ptr; 2576 1.1 christos *ptr = nent; 2577 1.1 christos nent->is_terminal = 0; 2578 1.1 christos nent->dependencies = -1; 2579 1.1 christos } 2580 1.1 christos 2581 1.1 christos if (! at_end) 2582 1.1 christos { 2583 1.1 christos parent = *ptr; 2584 1.1 christos ptr = &((*ptr)->addl_entries); 2585 1.1 christos prefix += plen + 1; 2586 1.1 christos } 2587 1.1 christos } 2588 1.1 christos 2589 1.1 christos if ((*ptr)->is_terminal) 2590 1.1 christos abort (); 2591 1.1 christos 2592 1.1 christos (*ptr)->is_terminal = 1; 2593 1.1 christos (*ptr)->mask = (ia64_insn)-1; 2594 1.1 christos (*ptr)->bits = opc->opcode; 2595 1.1 christos (*ptr)->dependencies = insert_opcode_dependencies (opc, *ptr); 2596 1.6 christos (*ptr)->order = order; 2597 1.1 christos } 2598 1.1 christos 2599 1.1 christos static void 2601 1.1 christos print_completer_entry (struct completer_entry *ent) 2602 1.1 christos { 2603 1.1 christos int moffset = 0; 2604 1.1 christos ia64_insn mask = ent->mask, bits = ent->bits; 2605 1.1 christos 2606 1.1 christos if (mask != 0) 2607 1.1 christos { 2608 1.1 christos while (! (mask & 1)) 2609 1.1 christos { 2610 1.1 christos moffset++; 2611 1.1 christos mask = mask >> 1; 2612 1.1 christos bits = bits >> 1; 2613 1.1 christos } 2614 1.1 christos 2615 1.1 christos if (bits & 0xffffffff00000000LL) 2616 1.1 christos abort (); 2617 1.1 christos } 2618 1.1 christos 2619 1.1 christos printf (" { 0x%x, 0x%x, %d, %d, %d, %d, %d, %d },\n", 2620 1.1 christos (int)bits, 2621 1.1 christos (int)mask, 2622 1.1 christos ent->name->num, 2623 1.1 christos ent->alternative != NULL ? ent->alternative->num : -1, 2624 1.1 christos ent->addl_entries != NULL ? ent->addl_entries->num : -1, 2625 1.6 christos moffset, 2626 1.1 christos ent->is_terminal ? 1 : 0, 2627 1.1 christos ent->dependencies); 2628 1.1 christos } 2629 1.1 christos 2630 1.1 christos static void 2632 1.1 christos print_completer_table (void) 2633 1.1 christos { 2634 1.1 christos int x; 2635 1.1 christos 2636 1.1 christos printf ("static const struct ia64_completer_table\ncompleter_table[] = {\n"); 2637 1.1 christos for (x = 0; x < glistlen; x++) 2638 1.1 christos print_completer_entry (glist[x]); 2639 1.1 christos printf ("};\n\n"); 2640 1.1 christos } 2641 1.1 christos 2642 1.1 christos static int 2644 1.1 christos opcodes_eq (struct ia64_opcode *opc1, struct ia64_opcode *opc2) 2645 1.1 christos { 2646 1.1 christos int x; 2647 1.1 christos int plen1, plen2; 2648 1.1 christos 2649 1.1 christos if ((opc1->mask != opc2->mask) || (opc1->type != opc2->type) 2650 1.1 christos || (opc1->num_outputs != opc2->num_outputs) 2651 1.1 christos || (opc1->flags != opc2->flags)) 2652 1.1 christos return 0; 2653 1.1 christos 2654 1.1 christos for (x = 0; x < 5; x++) 2655 1.1 christos if (opc1->operands[x] != opc2->operands[x]) 2656 1.1 christos return 0; 2657 1.1 christos 2658 1.1 christos plen1 = get_prefix_len (opc1->name); 2659 1.1 christos plen2 = get_prefix_len (opc2->name); 2660 1.6 christos 2661 1.1 christos if (plen1 == plen2 && (memcmp (opc1->name, opc2->name, plen1) == 0)) 2662 1.1 christos return 1; 2663 1.1 christos 2664 1.1 christos return 0; 2665 1.1 christos } 2666 1.1 christos 2667 1.1 christos static void 2669 1.1 christos add_opcode_entry (struct ia64_opcode *opc) 2670 1.1 christos { 2671 1.1 christos struct main_entry **place; 2672 1.1 christos struct string_entry *name; 2673 1.1 christos char prefix[129]; 2674 1.1 christos int found_it = 0; 2675 1.1 christos 2676 1.1 christos if (strlen (opc->name) > 128) 2677 1.1 christos abort (); 2678 1.1 christos 2679 1.1 christos place = &maintable; 2680 1.1 christos strcpy (prefix, opc->name); 2681 1.1 christos prefix[get_prefix_len (prefix)] = '\0'; 2682 1.1 christos name = insert_string (prefix); 2683 1.1 christos 2684 1.1 christos /* Walk the list of opcode table entries. If it's a new 2685 1.1 christos instruction, allocate and fill in a new entry. Note 2686 1.1 christos the main table is alphabetical by opcode name. */ 2687 1.1 christos 2688 1.1 christos while (*place != NULL) 2689 1.1 christos { 2690 1.1 christos if ((*place)->name->num == name->num 2691 1.1 christos && opcodes_eq ((*place)->opcode, opc)) 2692 1.1 christos { 2693 1.1 christos found_it = 1; 2694 1.1 christos break; 2695 1.1 christos } 2696 1.1 christos if ((*place)->name->num > name->num) 2697 1.1 christos break; 2698 1.1 christos 2699 1.1 christos place = &((*place)->next); 2700 1.1 christos } 2701 1.1 christos if (! found_it) 2702 1.1 christos { 2703 1.1 christos struct main_entry *nent = tmalloc (struct main_entry); 2704 1.1 christos 2705 1.1 christos nent->name = name; 2706 1.1 christos nent->opcode = opc; 2707 1.10 christos nent->next = *place; 2708 1.10 christos nent->completers = 0; 2709 1.1 christos *place = nent; 2710 1.1 christos 2711 1.10 christos if (otlen == ottotlen) 2712 1.10 christos { 2713 1.10 christos ottotlen += 20; 2714 1.1 christos ordered_table = (struct main_entry **) 2715 1.1 christos xrealloc (ordered_table, sizeof (struct main_entry *) * ottotlen); 2716 1.1 christos } 2717 1.1 christos ordered_table[otlen++] = nent; 2718 1.1 christos } 2719 1.1 christos 2720 1.1 christos insert_completer_entry (opc, *place, opcode_count++); 2721 1.1 christos } 2722 1.1 christos 2723 1.1 christos static void 2725 1.1 christos print_main_table (void) 2726 1.1 christos { 2727 1.1 christos struct main_entry *ptr = maintable; 2728 1.1 christos int tindex = 0; 2729 1.1 christos 2730 1.1 christos printf ("static const struct ia64_main_table\nmain_table[] = {\n"); 2731 1.1 christos while (ptr != NULL) 2732 1.1 christos { 2733 1.1 christos printf (" { %d, %d, %d, 0x%016" PRIx64 "ull, 0x%016" PRIx64 2734 1.1 christos "ull, { %d, %d, %d, %d, %d }, 0x%x, %d, },\n", 2735 1.1 christos ptr->name->num, 2736 1.1 christos ptr->opcode->type, 2737 1.1 christos ptr->opcode->num_outputs, 2738 1.1 christos ptr->opcode->opcode, 2739 1.1 christos ptr->opcode->mask, 2740 1.1 christos ptr->opcode->operands[0], 2741 1.1 christos ptr->opcode->operands[1], 2742 1.1 christos ptr->opcode->operands[2], 2743 1.1 christos ptr->opcode->operands[3], 2744 1.1 christos ptr->opcode->operands[4], 2745 1.1 christos ptr->opcode->flags, 2746 1.1 christos ptr->completers->num); 2747 1.1 christos 2748 1.1 christos ptr->main_index = tindex++; 2749 1.1 christos 2750 1.1 christos ptr = ptr->next; 2751 1.1 christos } 2752 1.1 christos printf ("};\n\n"); 2753 1.1 christos } 2754 1.1 christos 2755 1.1 christos static void 2757 1.1 christos shrink (struct ia64_opcode *table) 2758 1.1 christos { 2759 1.1 christos int curr_opcode; 2760 1.1 christos 2761 1.6 christos for (curr_opcode = 0; table[curr_opcode].name != NULL; curr_opcode++) 2762 1.1 christos { 2763 1.1 christos add_opcode_entry (table + curr_opcode); 2764 1.1 christos if (table[curr_opcode].num_outputs == 2 2765 1.1 christos && ((table[curr_opcode].operands[0] == IA64_OPND_P1 2766 1.1 christos && table[curr_opcode].operands[1] == IA64_OPND_P2) 2767 1.1 christos || (table[curr_opcode].operands[0] == IA64_OPND_P2 2768 1.1 christos && table[curr_opcode].operands[1] == IA64_OPND_P1))) 2769 1.1 christos { 2770 1.1 christos struct ia64_opcode *alias = tmalloc(struct ia64_opcode); 2771 1.1 christos unsigned i; 2772 1.1 christos 2773 1.1 christos *alias = table[curr_opcode]; 2774 1.1 christos for (i = 2; i < NELEMS (alias->operands); ++i) 2775 1.1 christos alias->operands[i - 1] = alias->operands[i]; 2776 1.1 christos alias->operands[NELEMS (alias->operands) - 1] = IA64_OPND_NIL; 2777 1.1 christos --alias->num_outputs; 2778 1.1 christos alias->flags |= PSEUDO; 2779 1.1 christos add_opcode_entry (alias); 2780 1.1 christos } 2781 1.1 christos } 2782 1.1 christos } 2783 1.1 christos 2784 1.1 christos 2786 1.1 christos /* Program options. */ 2787 1.1 christos #define OPTION_SRCDIR 200 2788 1.1 christos 2789 1.1 christos struct option long_options[] = 2790 1.1 christos { 2791 1.6 christos {"srcdir", required_argument, NULL, OPTION_SRCDIR}, 2792 1.1 christos {"debug", no_argument, NULL, 'd'}, 2793 1.1 christos {"version", no_argument, NULL, 'V'}, 2794 1.1 christos {"help", no_argument, NULL, 'h'}, 2795 1.1 christos {0, no_argument, NULL, 0} 2796 1.1 christos }; 2797 1.1 christos 2798 1.1 christos static void 2799 1.1 christos print_version (void) 2800 1.1 christos { 2801 1.1 christos printf ("%s: version 1.0\n", program_name); 2802 1.1 christos xexit (0); 2803 1.1 christos } 2804 1.1 christos 2805 1.1 christos static void 2806 1.1 christos usage (FILE * stream, int status) 2807 1.1 christos { 2808 1.1 christos fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n", 2809 1.1 christos program_name); 2810 1.1 christos xexit (status); 2811 1.1 christos } 2812 1.1 christos 2813 1.1 christos int 2814 1.1 christos main (int argc, char **argv) 2815 1.1 christos { 2816 1.1 christos extern int chdir (char *); 2817 1.1 christos char *srcdir = NULL; 2818 1.1 christos int c; 2819 1.6 christos 2820 1.1 christos program_name = *argv; 2821 1.1 christos xmalloc_set_program_name (program_name); 2822 1.1 christos 2823 1.1 christos while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF) 2824 1.1 christos switch (c) 2825 1.1 christos { 2826 1.1 christos case OPTION_SRCDIR: 2827 1.1 christos srcdir = optarg; 2828 1.1 christos break; 2829 1.1 christos case 'V': 2830 1.1 christos case 'v': 2831 1.1 christos print_version (); 2832 1.1 christos break; 2833 1.1 christos case 'd': 2834 1.1 christos debug = 1; 2835 1.1 christos break; 2836 1.1 christos case 'h': 2837 1.1 christos case '?': 2838 1.11 christos usage (stderr, 0); 2839 1.1 christos default: 2840 1.1 christos case 0: 2841 1.1 christos break; 2842 1.1 christos } 2843 1.1 christos 2844 1.1 christos if (optind != argc) 2845 1.1 christos usage (stdout, 1); 2846 1.1 christos 2847 1.1 christos if (srcdir != NULL) 2848 1.1 christos if (chdir (srcdir) != 0) 2849 1.1 christos fail (_("unable to change directory to \"%s\", errno = %s\n"), 2850 1.1 christos srcdir, strerror (errno)); 2851 1.1 christos 2852 1.1 christos load_insn_classes (); 2853 1.1 christos load_dependencies (); 2854 1.1 christos 2855 1.1 christos shrink (ia64_opcodes_a); 2856 1.1 christos shrink (ia64_opcodes_b); 2857 1.1 christos shrink (ia64_opcodes_f); 2858 1.1 christos shrink (ia64_opcodes_i); 2859 1.1 christos shrink (ia64_opcodes_m); 2860 1.1 christos shrink (ia64_opcodes_x); 2861 1.1 christos shrink (ia64_opcodes_d); 2862 1.1 christos 2863 1.1 christos collapse_redundant_completers (); 2864 1.1 christos 2865 1.1 christos printf ("/* This file is automatically generated by ia64-gen. Do not edit! */\n"); 2866 printf ("/* Copyright (C) 2007-2024 Free Software Foundation, Inc.\n\ 2867 \n\ 2868 This file is part of the GNU opcodes library.\n\ 2869 \n\ 2870 This library is free software; you can redistribute it and/or modify\n\ 2871 it under the terms of the GNU General Public License as published by\n\ 2872 the Free Software Foundation; either version 3, or (at your option)\n\ 2873 any later version.\n\ 2874 \n\ 2875 It is distributed in the hope that it will be useful, but WITHOUT\n\ 2876 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\ 2877 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\ 2878 License for more details.\n\ 2879 \n\ 2880 You should have received a copy of the GNU General Public License\n\ 2881 along with this program; see the file COPYING. If not, write to the\n\ 2882 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA\n\ 2883 02110-1301, USA. */\n"); 2884 2885 print_string_table (); 2886 print_dependency_table (); 2887 print_completer_table (); 2888 print_main_table (); 2889 2890 generate_disassembler (); 2891 2892 exit (0); 2893 } 2894