* doc/as.texinfo: Add mention of RX port and inclusion of RX
[binutils/dougsmingw.git] / opcodes / ia64-opc.c
blob7938fbc9f7c0e65fee90fd339a7a6df5e907e7a5
1 /* ia64-opc.c -- Functions to access the compacted opcode table
2 Copyright 1999, 2000, 2001, 2003, 2005, 2007 Free Software Foundation, Inc.
3 Written by Bob Manson of Cygnus Solutions, <manson@cygnus.com>
5 This file is part of the GNU opcodes library.
7 This library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 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,
20 MA 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];