sim/mips/
[deliverable/binutils-gdb.git] / opcodes / ia64-opc.c
CommitLineData
800eeca4 1/* ia64-opc.c -- Functions to access the compacted opcode table
aef6203b 2 Copyright 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
800eeca4
JW
3 Written by Bob Manson of Cygnus Solutions, <manson@cygnus.com>
4
5 This file is part of GDB, GAS, and the GNU binutils.
6
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.
11
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.
16
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
f4321104
NC
19 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
800eeca4
JW
21
22#include "ansidecl.h"
800eeca4 23#include "sysdep.h"
10b076a2 24#include "libiberty.h"
800eeca4
JW
25#include "ia64-asmtab.h"
26#include "ia64-asmtab.c"
27
26ca5450
AJ
28static void get_opc_prefix (const char **, char *);
29static short int find_string_ent (const char *);
30static short int find_main_ent (short int);
31static short int find_completer (short int, short int, const char *);
32static ia64_insn apply_completer (ia64_insn, int);
33static int extract_op_bits (int, int, int);
34static int extract_op (int, int *, unsigned int *);
35static int opcode_verify (ia64_insn, int, enum ia64_insn_type);
36static int locate_opcode_ent (ia64_insn, enum ia64_insn_type);
279a96ca 37static struct ia64_opcode *make_ia64_opcode
26ca5450 38 (ia64_insn, const char *, int, int);
279a96ca 39static struct ia64_opcode *ia64_find_matching_opcode
26ca5450 40 (const char *, short int);
279a96ca 41
800eeca4
JW
42const struct ia64_templ_desc ia64_templ_desc[16] =
43 {
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-" },
60 };
61
62
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. */
66
67static void
26ca5450 68get_opc_prefix (const char **ptr, char *dest)
800eeca4
JW
69{
70 char *c = strchr (*ptr, '.');
71 if (c != NULL)
72 {
73 memcpy (dest, *ptr, c - *ptr);
74 dest[c - *ptr] = '\0';
75 *ptr = c + 1;
76 }
77 else
78 {
79 int l = strlen (*ptr);
80 memcpy (dest, *ptr, l);
81 dest[l] = '\0';
82 *ptr += l;
83 }
84}
85\f
86/* Find the index of the entry in the string table corresponding to
87 STR; return -1 if one does not exist. */
88
89static short
26ca5450 90find_string_ent (const char *str)
800eeca4
JW
91{
92 short start = 0;
93 short end = sizeof (ia64_strings) / sizeof (const char *);
94 short i = (start + end) / 2;
95
96 if (strcmp (str, ia64_strings[end - 1]) > 0)
97 {
98 return -1;
99 }
100 while (start <= end)
101 {
102 int c = strcmp (str, ia64_strings[i]);
103 if (c < 0)
104 {
105 end = i - 1;
106 }
107 else if (c == 0)
108 {
109 return i;
110 }
111 else
112 {
113 start = i + 1;
114 }
115 i = (start + end) / 2;
116 }
117 return -1;
118}
119\f
120/* Find the opcode in the main opcode table whose name is STRINGINDEX, or
121 return -1 if one does not exist. */
122
123static short
26ca5450 124find_main_ent (short nameindex)
800eeca4
JW
125{
126 short start = 0;
127 short end = sizeof (main_table) / sizeof (struct ia64_main_table);
128 short i = (start + end) / 2;
129
130 if (nameindex < main_table[0].name_index
131 || nameindex > main_table[end - 1].name_index)
132 {
133 return -1;
134 }
135 while (start <= end)
136 {
137 if (nameindex < main_table[i].name_index)
138 {
139 end = i - 1;
140 }
141 else if (nameindex == main_table[i].name_index)
142 {
143 while (i > 0 && main_table[i - 1].name_index == nameindex)
144 {
145 i--;
146 }
147 return i;
148 }
149 else
150 {
151 start = i + 1;
152 }
153 i = (start + end) / 2;
154 }
155 return -1;
156}
157\f
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. */
161
279a96ca 162static short
26ca5450 163find_completer (short main_ent, short prev_completer, const char *name)
800eeca4
JW
164{
165 short name_index = find_string_ent (name);
166
167 if (name_index < 0)
168 {
169 return -1;
170 }
171
172 if (prev_completer == -1)
173 {
174 prev_completer = main_table[main_ent].completers;
175 }
176 else
177 {
178 prev_completer = completer_table[prev_completer].subentries;
179 }
180
181 while (prev_completer != -1)
182 {
183 if (completer_table[prev_completer].name_index == name_index)
184 {
185 return prev_completer;
186 }
187 prev_completer = completer_table[prev_completer].alternative;
188 }
189 return -1;
190}
191\f
192/* Apply the completer referred to by COMPLETER_INDEX to OPCODE, and
193 return the result. */
194
195static ia64_insn
26ca5450 196apply_completer (ia64_insn opcode, int completer_index)
800eeca4
JW
197{
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);
201
202 mask = mask << shiftamt;
203 bits = bits << shiftamt;
204 opcode = (opcode & ~mask) | bits;
205 return opcode;
206}
207\f
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.) */
212
213static int
26ca5450 214extract_op_bits (int op_pointer, int bitoffset, int bits)
800eeca4
JW
215{
216 int res = 0;
217
218 op_pointer += (bitoffset / 8);
219
220 if (bitoffset % 8)
221 {
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;
227
228 res = (res << bata) | ((op & mask) >> delta);
229 bitoffset += bata;
230 bits -= bata;
231 }
232 while (bits >= 8)
233 {
234 res = (res << 8) | (dis_table[op_pointer++] & 255);
235 bits -= 8;
236 }
237 if (bits > 0)
238 {
239 unsigned int op = (dis_table[op_pointer++] & 255);
240 res = (res << bits) | (op >> (8 - bits));
241 }
242 return res;
243}
244\f
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. */
248
249static int
26ca5450 250extract_op (int op_pointer, int *opval, unsigned int *op)
800eeca4
JW
251{
252 int oplen = 5;
253
254 *op = dis_table[op_pointer];
255
256 if ((*op) & 0x40)
257 {
258 opval[0] = extract_op_bits (op_pointer, oplen, 5);
259 oplen += 5;
260 }
261 switch ((*op) & 0x30)
262 {
263 case 0x10:
264 {
265 opval[1] = extract_op_bits (op_pointer, oplen, 8);
266 oplen += 8;
267 opval[1] += op_pointer;
268 break;
269 }
270 case 0x20:
271 {
272 opval[1] = extract_op_bits (op_pointer, oplen, 16);
273 if (! (opval[1] & 32768))
274 {
275 opval[1] += op_pointer;
276 }
277 oplen += 16;
278 break;
279 }
280 case 0x30:
281 {
282 oplen--;
283 opval[2] = extract_op_bits (op_pointer, oplen, 12);
284 oplen += 12;
285 opval[2] |= 32768;
286 break;
287 }
288 }
289 if (((*op) & 0x08) && (((*op) & 0x30) != 0x30))
290 {
291 opval[2] = extract_op_bits (op_pointer, oplen, 16);
292 oplen += 16;
293 if (! (opval[2] & 32768))
294 {
295 opval[2] += op_pointer;
296 }
297 }
298 return oplen;
299}
300\f
301/* Returns a non-zero value if the opcode in the main_table list at
302 PLACE matches OPCODE and is of type TYPE. */
303
304static int
26ca5450 305opcode_verify (ia64_insn opcode, int place, enum ia64_insn_type type)
800eeca4
JW
306{
307 if (main_table[place].opcode_type != type)
308 {
309 return 0;
310 }
279a96ca 311 if (main_table[place].flags
800eeca4
JW
312 & (IA64_OPCODE_F2_EQ_F3 | IA64_OPCODE_LEN_EQ_64MCNT))
313 {
314 const struct ia64_operand *o1, *o2;
315 ia64_insn f2, f3;
316
317 if (main_table[place].flags & IA64_OPCODE_F2_EQ_F3)
318 {
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;
325 }
326 else
327 {
328 ia64_insn len, count;
329
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;
337 }
338 }
339 return 1;
340}
341\f
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
aa170a07
TW
345 not be found. Checks all matches and returns the one with the highest
346 priority. */
800eeca4
JW
347
348static int
26ca5450 349locate_opcode_ent (ia64_insn opcode, enum ia64_insn_type type)
800eeca4
JW
350{
351 int currtest[41];
352 int bitpos[41];
353 int op_ptr[41];
354 int currstatenum = 0;
aa170a07
TW
355 short found_disent = -1;
356 short found_priority = -1;
800eeca4
JW
357
358 currtest[currstatenum] = 0;
359 op_ptr[currstatenum] = 0;
360 bitpos[currstatenum] = 40;
361
362 while (1)
363 {
364 int op_pointer = op_ptr[currstatenum];
365 unsigned int op;
366 int currbitnum = bitpos[currstatenum];
367 int oplen;
33b71eeb 368 int opval[3] = {0};
800eeca4
JW
369 int next_op;
370 int currbit;
371
372 oplen = extract_op (op_pointer, opval, &op);
373
374 bitpos[currstatenum] = currbitnum;
375
376 /* Skip opval[0] bits in the instruction. */
377 if (op & 0x40)
378 {
379 currbitnum -= opval[0];
380 }
381
382 /* The value of the current bit being tested. */
383 currbit = opcode & (((ia64_insn) 1) << currbitnum) ? 1 : 0;
384 next_op = -1;
385
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])
390 {
391 case 0:
392 currtest[currstatenum]++;
393 if (currbit == 0 && (op & 0x80))
394 {
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.)
399
400 If the state instruction matches, we go to the very
401 next state instruction; otherwise, try the next test. */
402
403 if ((op & 0xf8) == 0x80)
404 {
405 int count = op & 0x7;
406 int x;
407
408 for (x = 0; x <= count; x++)
409 {
410 int i =
411 opcode & (((ia64_insn) 1) << (currbitnum - x)) ? 1 : 0;
412 if (i)
413 {
414 break;
415 }
416 }
417 if (x > count)
418 {
419 next_op = op_pointer + ((oplen + 7) / 8);
420 currbitnum -= count;
421 break;
422 }
423 }
424 else if (! currbit)
425 {
426 next_op = op_pointer + ((oplen + 7) / 8);
427 break;
428 }
429 }
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))
436 {
437 next_op = opval[1];
438 break;
439 }
440 /* FALLTHROUGH */
441 case 2:
442 /* Don't care. Skip the current bit and go to the state
443 instruction specified by opval[2].
444
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))
449 {
450 next_op = opval[2];
451 break;
452 }
453 }
454
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. */
459
460 if ((next_op >= 0) && (next_op & 32768))
461 {
462 short disent = next_op & 32767;
aa170a07 463 short priority = -1;
800eeca4
JW
464
465 if (next_op > 65535)
466 {
467 abort ();
468 }
469
470 /* Run through the list of opcodes to check, trying to find
471 one that matches. */
472 while (disent >= 0)
473 {
474 int place = ia64_dis_names[disent].insn_index;
475
aa170a07
TW
476 priority = ia64_dis_names[disent].priority;
477
279a96ca 478 if (opcode_verify (opcode, place, type)
aa170a07 479 && priority > found_priority)
800eeca4
JW
480 {
481 break;
482 }
483 if (ia64_dis_names[disent].next_flag)
484 {
485 disent++;
486 }
487 else
488 {
489 disent = -1;
490 }
491 }
492
493 if (disent >= 0)
494 {
aa170a07
TW
495 found_disent = disent;
496 found_priority = priority;
800eeca4 497 }
aa170a07
TW
498 /* Try the next test in this state, regardless of whether a match
499 was found. */
500 next_op = -2;
800eeca4
JW
501 }
502
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. */
506
507 if (next_op == -1)
508 {
509 currstatenum--;
510 if (currstatenum < 0)
511 {
aa170a07 512 return found_disent;
800eeca4
JW
513 }
514 }
515 else if (next_op >= 0)
516 {
517 currstatenum++;
518 bitpos[currstatenum] = currbitnum - 1;
519 op_ptr[currstatenum] = next_op;
520 currtest[currstatenum] = 0;
521 }
522 }
523}
524\f
525/* Construct an ia64_opcode entry based on OPCODE, NAME and PLACE. */
526
527static struct ia64_opcode *
26ca5450 528make_ia64_opcode (ia64_insn opcode, const char *name, int place, int depind)
800eeca4
JW
529{
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;
546}
547\f
548/* Determine the ia64_opcode entry for the opcode specified by INSN
549 and TYPE. If a valid entry is not found, return NULL. */
550struct ia64_opcode *
26ca5450 551ia64_dis_opcode (ia64_insn insn, enum ia64_insn_type type)
800eeca4
JW
552{
553 int disent = locate_opcode_ent (insn, type);
554
555 if (disent < 0)
556 {
557 return NULL;
558 }
559 else
560 {
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;
566
567 strcpy (name, ia64_strings [main_table[place].name_index]);
568
569 while (cb)
570 {
571 if (cb & 1)
572 {
573 int cname = completer_table[ci].name_index;
574
575 tinsn = apply_completer (tinsn, ci);
576
577 if (ia64_strings[cname][0] != '\0')
578 {
579 strcat (name, ".");
580 strcat (name, ia64_strings[cname]);
581 }
582 if (cb != 1)
583 {
584 ci = completer_table[ci].subentries;
585 }
586 }
587 else
588 {
589 ci = completer_table[ci].alternative;
590 }
591 if (ci < 0)
592 {
593 abort ();
594 }
595 cb = cb >> 1;
596 }
597 if (tinsn != (insn & main_table[place].mask))
598 {
599 abort ();
600 }
279a96ca 601 return make_ia64_opcode (insn, name, place,
800eeca4
JW
602 completer_table[ci].dependencies);
603 }
604}
605\f
606/* Search the main_opcode table starting from PLACE for an opcode that
607 matches NAME. Return NULL if one is not found. */
608
609static struct ia64_opcode *
26ca5450 610ia64_find_matching_opcode (const char *name, short place)
800eeca4
JW
611{
612 char op[129];
613 const char *suffix;
614 short name_index;
615
616 if (strlen (name) > 128)
617 {
618 return NULL;
619 }
620 suffix = name;
621 get_opc_prefix (&suffix, op);
622 name_index = find_string_ent (op);
623 if (name_index < 0)
624 {
625 return NULL;
626 }
627
628 while (main_table[place].name_index == name_index)
629 {
630 const char *curr_suffix = suffix;
631 ia64_insn curr_insn = main_table[place].opcode;
632 short completer = -1;
633
634 do {
279a96ca 635 if (suffix[0] == '\0')
800eeca4
JW
636 {
637 completer = find_completer (place, completer, suffix);
638 }
639 else
640 {
641 get_opc_prefix (&curr_suffix, op);
642 completer = find_completer (place, completer, op);
643 }
644 if (completer != -1)
645 {
646 curr_insn = apply_completer (curr_insn, completer);
647 }
648 } while (completer != -1 && curr_suffix[0] != '\0');
649
650 if (completer != -1 && curr_suffix[0] == '\0'
651 && completer_table[completer].terminal_completer)
652 {
653 int depind = completer_table[completer].dependencies;
654 return make_ia64_opcode (curr_insn, name, place, depind);
655 }
656 else
657 {
658 place++;
659 }
660 }
661 return NULL;
662}
663\f
664/* Find the next opcode after PREV_ENT that matches PREV_ENT, or return NULL
665 if one does not exist.
666
667 It is the caller's responsibility to invoke ia64_free_opcode () to
668 release any resources used by the returned entry. */
669
670struct ia64_opcode *
26ca5450 671ia64_find_next_opcode (struct ia64_opcode *prev_ent)
800eeca4
JW
672{
673 return ia64_find_matching_opcode (prev_ent->name,
674 prev_ent->ent_index + 1);
675}
676
677/* Find the first opcode that matches NAME, or return NULL if it does
678 not exist.
679
680 It is the caller's responsibility to invoke ia64_free_opcode () to
681 release any resources used by the returned entry. */
682
683struct ia64_opcode *
26ca5450 684ia64_find_opcode (const char *name)
800eeca4
JW
685{
686 char op[129];
687 const char *suffix;
688 short place;
689 short name_index;
690
691 if (strlen (name) > 128)
692 {
693 return NULL;
694 }
695 suffix = name;
696 get_opc_prefix (&suffix, op);
697 name_index = find_string_ent (op);
698 if (name_index < 0)
699 {
700 return NULL;
701 }
702
703 place = find_main_ent (name_index);
704
705 if (place < 0)
706 {
707 return NULL;
708 }
709 return ia64_find_matching_opcode (name, place);
710}
711
712/* Free any resources used by ENT. */
713void
26ca5450 714ia64_free_opcode (struct ia64_opcode *ent)
800eeca4
JW
715{
716 free ((void *)ent->name);
717 free (ent);
718}
719
720const struct ia64_dependency *
26ca5450 721ia64_find_dependency (int index)
800eeca4
JW
722{
723 index = DEP(index);
724
514829c3
JW
725 if (index < 0
726 || index >= (int)(sizeof(dependencies) / sizeof(dependencies[0])))
800eeca4
JW
727 return NULL;
728
729 return &dependencies[index];
730}
This page took 0.340919 seconds and 4 git commands to generate.