Remove special case handling for rtems targets that are sufficiently handled by
[binutils.git] / opcodes / ia64-opc.c
blob5f2cfc738914b81491dc93bbbd5e70452b36db86
1 /* ia64-opc.c -- Functions to access the compacted opcode table
2 Copyright 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
3 Written by Bob Manson of Cygnus Solutions, <manson@cygnus.com>
5 This file is part of GDB, GAS, and the GNU binutils.
7 GDB, GAS, and the GNU binutils are free software; you can redistribute
8 them and/or modify them under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either version
10 2, or (at your option) any later version.
12 GDB, GAS, and the GNU binutils are distributed in the hope that they
13 will be useful, but WITHOUT ANY WARRANTY; without even the implied
14 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this file; see the file COPYING. If not, write to the
19 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
22 #include "ansidecl.h"
23 #include "sysdep.h"
24 #include "libiberty.h"
25 #include "ia64-asmtab.h"
26 #include "ia64-asmtab.c"
28 static void get_opc_prefix (const char **, char *);
29 static short int find_string_ent (const char *);
30 static short int find_main_ent (short int);
31 static short int find_completer (short int, short int, const char *);
32 static ia64_insn apply_completer (ia64_insn, int);
33 static int extract_op_bits (int, int, int);
34 static int extract_op (int, int *, unsigned int *);
35 static int opcode_verify (ia64_insn, int, enum ia64_insn_type);
36 static int locate_opcode_ent (ia64_insn, enum ia64_insn_type);
37 static struct ia64_opcode *make_ia64_opcode
38 (ia64_insn, const char *, int, int);
39 static struct ia64_opcode *ia64_find_matching_opcode
40 (const char *, short int);
42 const struct ia64_templ_desc ia64_templ_desc[16] =
44 { 0, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_I }, "MII" }, /* 0 */
45 { 2, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_I }, "MII" },
46 { 0, { IA64_UNIT_M, IA64_UNIT_L, IA64_UNIT_X }, "MLX" },
47 { 0, { 0, }, "-3-" },
48 { 0, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_I }, "MMI" }, /* 4 */
49 { 1, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_I }, "MMI" },
50 { 0, { IA64_UNIT_M, IA64_UNIT_F, IA64_UNIT_I }, "MFI" },
51 { 0, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_F }, "MMF" },
52 { 0, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_B }, "MIB" }, /* 8 */
53 { 0, { IA64_UNIT_M, IA64_UNIT_B, IA64_UNIT_B }, "MBB" },
54 { 0, { 0, }, "-a-" },
55 { 0, { IA64_UNIT_B, IA64_UNIT_B, IA64_UNIT_B }, "BBB" },
56 { 0, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_B }, "MMB" }, /* c */
57 { 0, { 0, }, "-d-" },
58 { 0, { IA64_UNIT_M, IA64_UNIT_F, IA64_UNIT_B }, "MFB" },
59 { 0, { 0, }, "-f-" },
63 /* Copy the prefix contained in *PTR (up to a '.' or a NUL) to DEST.
64 PTR will be adjusted to point to the start of the next portion
65 of the opcode, or at the NUL character. */
67 static void
68 get_opc_prefix (const char **ptr, char *dest)
70 char *c = strchr (*ptr, '.');
71 if (c != NULL)
73 memcpy (dest, *ptr, c - *ptr);
74 dest[c - *ptr] = '\0';
75 *ptr = c + 1;
77 else
79 int l = strlen (*ptr);
80 memcpy (dest, *ptr, l);
81 dest[l] = '\0';
82 *ptr += l;
86 /* Find the index of the entry in the string table corresponding to
87 STR; return -1 if one does not exist. */
89 static short
90 find_string_ent (const char *str)
92 short start = 0;
93 short end = sizeof (ia64_strings) / sizeof (const char *);
94 short i = (start + end) / 2;
96 if (strcmp (str, ia64_strings[end - 1]) > 0)
98 return -1;
100 while (start <= end)
102 int c = strcmp (str, ia64_strings[i]);
103 if (c < 0)
105 end = i - 1;
107 else if (c == 0)
109 return i;
111 else
113 start = i + 1;
115 i = (start + end) / 2;
117 return -1;
120 /* Find the opcode in the main opcode table whose name is STRINGINDEX, or
121 return -1 if one does not exist. */
123 static short
124 find_main_ent (short nameindex)
126 short start = 0;
127 short end = sizeof (main_table) / sizeof (struct ia64_main_table);
128 short i = (start + end) / 2;
130 if (nameindex < main_table[0].name_index
131 || nameindex > main_table[end - 1].name_index)
133 return -1;
135 while (start <= end)
137 if (nameindex < main_table[i].name_index)
139 end = i - 1;
141 else if (nameindex == main_table[i].name_index)
143 while (i > 0 && main_table[i - 1].name_index == nameindex)
145 i--;
147 return i;
149 else
151 start = i + 1;
153 i = (start + end) / 2;
155 return -1;
158 /* Find the index of the entry in the completer table that is part of
159 MAIN_ENT (starting from PREV_COMPLETER) that matches NAME, or
160 return -1 if one does not exist. */
162 static short
163 find_completer (short main_ent, short prev_completer, const char *name)
165 short name_index = find_string_ent (name);
167 if (name_index < 0)
169 return -1;
172 if (prev_completer == -1)
174 prev_completer = main_table[main_ent].completers;
176 else
178 prev_completer = completer_table[prev_completer].subentries;
181 while (prev_completer != -1)
183 if (completer_table[prev_completer].name_index == name_index)
185 return prev_completer;
187 prev_completer = completer_table[prev_completer].alternative;
189 return -1;
192 /* Apply the completer referred to by COMPLETER_INDEX to OPCODE, and
193 return the result. */
195 static ia64_insn
196 apply_completer (ia64_insn opcode, int completer_index)
198 ia64_insn mask = completer_table[completer_index].mask;
199 ia64_insn bits = completer_table[completer_index].bits;
200 int shiftamt = (completer_table[completer_index].offset & 63);
202 mask = mask << shiftamt;
203 bits = bits << shiftamt;
204 opcode = (opcode & ~mask) | bits;
205 return opcode;
208 /* Extract BITS number of bits starting from OP_POINTER + BITOFFSET in
209 the dis_table array, and return its value. (BITOFFSET is numbered
210 starting from MSB to LSB, so a BITOFFSET of 0 indicates the MSB of the
211 first byte in OP_POINTER.) */
213 static int
214 extract_op_bits (int op_pointer, int bitoffset, int bits)
216 int res = 0;
218 op_pointer += (bitoffset / 8);
220 if (bitoffset % 8)
222 unsigned int op = dis_table[op_pointer++];
223 int numb = 8 - (bitoffset % 8);
224 int mask = (1 << numb) - 1;
225 int bata = (bits < numb) ? bits : numb;
226 int delta = numb - bata;
228 res = (res << bata) | ((op & mask) >> delta);
229 bitoffset += bata;
230 bits -= bata;
232 while (bits >= 8)
234 res = (res << 8) | (dis_table[op_pointer++] & 255);
235 bits -= 8;
237 if (bits > 0)
239 unsigned int op = (dis_table[op_pointer++] & 255);
240 res = (res << bits) | (op >> (8 - bits));
242 return res;
245 /* Examine the state machine entry at OP_POINTER in the dis_table
246 array, and extract its values into OPVAL and OP. The length of the
247 state entry in bits is returned. */
249 static int
250 extract_op (int op_pointer, int *opval, unsigned int *op)
252 int oplen = 5;
254 *op = dis_table[op_pointer];
256 if ((*op) & 0x40)
258 opval[0] = extract_op_bits (op_pointer, oplen, 5);
259 oplen += 5;
261 switch ((*op) & 0x30)
263 case 0x10:
265 opval[1] = extract_op_bits (op_pointer, oplen, 8);
266 oplen += 8;
267 opval[1] += op_pointer;
268 break;
270 case 0x20:
272 opval[1] = extract_op_bits (op_pointer, oplen, 16);
273 if (! (opval[1] & 32768))
275 opval[1] += op_pointer;
277 oplen += 16;
278 break;
280 case 0x30:
282 oplen--;
283 opval[2] = extract_op_bits (op_pointer, oplen, 12);
284 oplen += 12;
285 opval[2] |= 32768;
286 break;
289 if (((*op) & 0x08) && (((*op) & 0x30) != 0x30))
291 opval[2] = extract_op_bits (op_pointer, oplen, 16);
292 oplen += 16;
293 if (! (opval[2] & 32768))
295 opval[2] += op_pointer;
298 return oplen;
301 /* Returns a non-zero value if the opcode in the main_table list at
302 PLACE matches OPCODE and is of type TYPE. */
304 static int
305 opcode_verify (ia64_insn opcode, int place, enum ia64_insn_type type)
307 if (main_table[place].opcode_type != type)
309 return 0;
311 if (main_table[place].flags
312 & (IA64_OPCODE_F2_EQ_F3 | IA64_OPCODE_LEN_EQ_64MCNT))
314 const struct ia64_operand *o1, *o2;
315 ia64_insn f2, f3;
317 if (main_table[place].flags & IA64_OPCODE_F2_EQ_F3)
319 o1 = elf64_ia64_operands + IA64_OPND_F2;
320 o2 = elf64_ia64_operands + IA64_OPND_F3;
321 (*o1->extract) (o1, opcode, &f2);
322 (*o2->extract) (o2, opcode, &f3);
323 if (f2 != f3)
324 return 0;
326 else
328 ia64_insn len, count;
330 /* length must equal 64-count: */
331 o1 = elf64_ia64_operands + IA64_OPND_LEN6;
332 o2 = elf64_ia64_operands + main_table[place].operands[2];
333 (*o1->extract) (o1, opcode, &len);
334 (*o2->extract) (o2, opcode, &count);
335 if (len != 64 - count)
336 return 0;
339 return 1;
342 /* Find an instruction entry in the ia64_dis_names array that matches
343 opcode OPCODE and is of type TYPE. Returns either a positive index
344 into the array, or a negative value if an entry for OPCODE could
345 not be found. Checks all matches and returns the one with the highest
346 priority. */
348 static int
349 locate_opcode_ent (ia64_insn opcode, enum ia64_insn_type type)
351 int currtest[41];
352 int bitpos[41];
353 int op_ptr[41];
354 int currstatenum = 0;
355 short found_disent = -1;
356 short found_priority = -1;
358 currtest[currstatenum] = 0;
359 op_ptr[currstatenum] = 0;
360 bitpos[currstatenum] = 40;
362 while (1)
364 int op_pointer = op_ptr[currstatenum];
365 unsigned int op;
366 int currbitnum = bitpos[currstatenum];
367 int oplen;
368 int opval[3] = {0};
369 int next_op;
370 int currbit;
372 oplen = extract_op (op_pointer, opval, &op);
374 bitpos[currstatenum] = currbitnum;
376 /* Skip opval[0] bits in the instruction. */
377 if (op & 0x40)
379 currbitnum -= opval[0];
382 /* The value of the current bit being tested. */
383 currbit = opcode & (((ia64_insn) 1) << currbitnum) ? 1 : 0;
384 next_op = -1;
386 /* We always perform the tests specified in the current state in
387 a particular order, falling through to the next test if the
388 previous one failed. */
389 switch (currtest[currstatenum])
391 case 0:
392 currtest[currstatenum]++;
393 if (currbit == 0 && (op & 0x80))
395 /* Check for a zero bit. If this test solely checks for
396 a zero bit, we can check for up to 8 consecutive zero
397 bits (the number to check is specified by the lower 3
398 bits in the state code.)
400 If the state instruction matches, we go to the very
401 next state instruction; otherwise, try the next test. */
403 if ((op & 0xf8) == 0x80)
405 int count = op & 0x7;
406 int x;
408 for (x = 0; x <= count; x++)
410 int i =
411 opcode & (((ia64_insn) 1) << (currbitnum - x)) ? 1 : 0;
412 if (i)
414 break;
417 if (x > count)
419 next_op = op_pointer + ((oplen + 7) / 8);
420 currbitnum -= count;
421 break;
424 else if (! currbit)
426 next_op = op_pointer + ((oplen + 7) / 8);
427 break;
430 /* FALLTHROUGH */
431 case 1:
432 /* If the bit in the instruction is one, go to the state
433 instruction specified by opval[1]. */
434 currtest[currstatenum]++;
435 if (currbit && (op & 0x30) != 0 && ((op & 0x30) != 0x30))
437 next_op = opval[1];
438 break;
440 /* FALLTHROUGH */
441 case 2:
442 /* Don't care. Skip the current bit and go to the state
443 instruction specified by opval[2].
445 An encoding of 0x30 is special; this means that a 12-bit
446 offset into the ia64_dis_names[] array is specified. */
447 currtest[currstatenum]++;
448 if ((op & 0x08) || ((op & 0x30) == 0x30))
450 next_op = opval[2];
451 break;
455 /* If bit 15 is set in the address of the next state, an offset
456 in the ia64_dis_names array was specified instead. We then
457 check to see if an entry in the list of opcodes matches the
458 opcode we were given; if so, we have succeeded. */
460 if ((next_op >= 0) && (next_op & 32768))
462 short disent = next_op & 32767;
463 short priority = -1;
465 if (next_op > 65535)
467 abort ();
470 /* Run through the list of opcodes to check, trying to find
471 one that matches. */
472 while (disent >= 0)
474 int place = ia64_dis_names[disent].insn_index;
476 priority = ia64_dis_names[disent].priority;
478 if (opcode_verify (opcode, place, type)
479 && priority > found_priority)
481 break;
483 if (ia64_dis_names[disent].next_flag)
485 disent++;
487 else
489 disent = -1;
493 if (disent >= 0)
495 found_disent = disent;
496 found_priority = priority;
498 /* Try the next test in this state, regardless of whether a match
499 was found. */
500 next_op = -2;
503 /* next_op == -1 is "back up to the previous state".
504 next_op == -2 is "stay in this state and try the next test".
505 Otherwise, transition to the state indicated by next_op. */
507 if (next_op == -1)
509 currstatenum--;
510 if (currstatenum < 0)
512 return found_disent;
515 else if (next_op >= 0)
517 currstatenum++;
518 bitpos[currstatenum] = currbitnum - 1;
519 op_ptr[currstatenum] = next_op;
520 currtest[currstatenum] = 0;
525 /* Construct an ia64_opcode entry based on OPCODE, NAME and PLACE. */
527 static struct ia64_opcode *
528 make_ia64_opcode (ia64_insn opcode, const char *name, int place, int depind)
530 struct ia64_opcode *res =
531 (struct ia64_opcode *) xmalloc (sizeof (struct ia64_opcode));
532 res->name = xstrdup (name);
533 res->type = main_table[place].opcode_type;
534 res->num_outputs = main_table[place].num_outputs;
535 res->opcode = opcode;
536 res->mask = main_table[place].mask;
537 res->operands[0] = main_table[place].operands[0];
538 res->operands[1] = main_table[place].operands[1];
539 res->operands[2] = main_table[place].operands[2];
540 res->operands[3] = main_table[place].operands[3];
541 res->operands[4] = main_table[place].operands[4];
542 res->flags = main_table[place].flags;
543 res->ent_index = place;
544 res->dependencies = &op_dependencies[depind];
545 return res;
548 /* Determine the ia64_opcode entry for the opcode specified by INSN
549 and TYPE. If a valid entry is not found, return NULL. */
550 struct ia64_opcode *
551 ia64_dis_opcode (ia64_insn insn, enum ia64_insn_type type)
553 int disent = locate_opcode_ent (insn, type);
555 if (disent < 0)
557 return NULL;
559 else
561 unsigned int cb = ia64_dis_names[disent].completer_index;
562 static char name[128];
563 int place = ia64_dis_names[disent].insn_index;
564 int ci = main_table[place].completers;
565 ia64_insn tinsn = main_table[place].opcode;
567 strcpy (name, ia64_strings [main_table[place].name_index]);
569 while (cb)
571 if (cb & 1)
573 int cname = completer_table[ci].name_index;
575 tinsn = apply_completer (tinsn, ci);
577 if (ia64_strings[cname][0] != '\0')
579 strcat (name, ".");
580 strcat (name, ia64_strings[cname]);
582 if (cb != 1)
584 ci = completer_table[ci].subentries;
587 else
589 ci = completer_table[ci].alternative;
591 if (ci < 0)
593 abort ();
595 cb = cb >> 1;
597 if (tinsn != (insn & main_table[place].mask))
599 abort ();
601 return make_ia64_opcode (insn, name, place,
602 completer_table[ci].dependencies);
606 /* Search the main_opcode table starting from PLACE for an opcode that
607 matches NAME. Return NULL if one is not found. */
609 static struct ia64_opcode *
610 ia64_find_matching_opcode (const char *name, short place)
612 char op[129];
613 const char *suffix;
614 short name_index;
616 if (strlen (name) > 128)
618 return NULL;
620 suffix = name;
621 get_opc_prefix (&suffix, op);
622 name_index = find_string_ent (op);
623 if (name_index < 0)
625 return NULL;
628 while (main_table[place].name_index == name_index)
630 const char *curr_suffix = suffix;
631 ia64_insn curr_insn = main_table[place].opcode;
632 short completer = -1;
634 do {
635 if (suffix[0] == '\0')
637 completer = find_completer (place, completer, suffix);
639 else
641 get_opc_prefix (&curr_suffix, op);
642 completer = find_completer (place, completer, op);
644 if (completer != -1)
646 curr_insn = apply_completer (curr_insn, completer);
648 } while (completer != -1 && curr_suffix[0] != '\0');
650 if (completer != -1 && curr_suffix[0] == '\0'
651 && completer_table[completer].terminal_completer)
653 int depind = completer_table[completer].dependencies;
654 return make_ia64_opcode (curr_insn, name, place, depind);
656 else
658 place++;
661 return NULL;
664 /* Find the next opcode after PREV_ENT that matches PREV_ENT, or return NULL
665 if one does not exist.
667 It is the caller's responsibility to invoke ia64_free_opcode () to
668 release any resources used by the returned entry. */
670 struct ia64_opcode *
671 ia64_find_next_opcode (struct ia64_opcode *prev_ent)
673 return ia64_find_matching_opcode (prev_ent->name,
674 prev_ent->ent_index + 1);
677 /* Find the first opcode that matches NAME, or return NULL if it does
678 not exist.
680 It is the caller's responsibility to invoke ia64_free_opcode () to
681 release any resources used by the returned entry. */
683 struct ia64_opcode *
684 ia64_find_opcode (const char *name)
686 char op[129];
687 const char *suffix;
688 short place;
689 short name_index;
691 if (strlen (name) > 128)
693 return NULL;
695 suffix = name;
696 get_opc_prefix (&suffix, op);
697 name_index = find_string_ent (op);
698 if (name_index < 0)
700 return NULL;
703 place = find_main_ent (name_index);
705 if (place < 0)
707 return NULL;
709 return ia64_find_matching_opcode (name, place);
712 /* Free any resources used by ENT. */
713 void
714 ia64_free_opcode (struct ia64_opcode *ent)
716 free ((void *)ent->name);
717 free (ent);
720 const struct ia64_dependency *
721 ia64_find_dependency (int index)
723 index = DEP(index);
725 if (index < 0
726 || index >= (int)(sizeof(dependencies) / sizeof(dependencies[0])))
727 return NULL;
729 return &dependencies[index];