1 /* ia64-opc.c -- Functions to access the compacted opcode table
2 Copyright (C) 1999 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, 59 Temple Place - Suite 330, Boston, MA
23 #include "libiberty.h"
25 #include "ia64-asmtab.h"
26 #include "ia64-asmtab.c"
28 const struct ia64_templ_desc ia64_templ_desc
[16] =
30 { 0, { IA64_UNIT_M
, IA64_UNIT_I
, IA64_UNIT_I
}, "MII" }, /* 0 */
31 { 2, { IA64_UNIT_M
, IA64_UNIT_I
, IA64_UNIT_I
}, "MII" },
32 { 0, { IA64_UNIT_M
, IA64_UNIT_L
, IA64_UNIT_X
}, "MLX" },
34 { 0, { IA64_UNIT_M
, IA64_UNIT_M
, IA64_UNIT_I
}, "MMI" }, /* 4 */
35 { 1, { IA64_UNIT_M
, IA64_UNIT_M
, IA64_UNIT_I
}, "MMI" },
36 { 0, { IA64_UNIT_M
, IA64_UNIT_F
, IA64_UNIT_I
}, "MFI" },
37 { 0, { IA64_UNIT_M
, IA64_UNIT_M
, IA64_UNIT_F
}, "MMF" },
38 { 0, { IA64_UNIT_M
, IA64_UNIT_I
, IA64_UNIT_B
}, "MIB" }, /* 8 */
39 { 0, { IA64_UNIT_M
, IA64_UNIT_B
, IA64_UNIT_B
}, "MBB" },
41 { 0, { IA64_UNIT_B
, IA64_UNIT_B
, IA64_UNIT_B
}, "BBB" },
42 { 0, { IA64_UNIT_M
, IA64_UNIT_M
, IA64_UNIT_B
}, "MMB" }, /* c */
44 { 0, { IA64_UNIT_M
, IA64_UNIT_F
, IA64_UNIT_B
}, "MFB" },
49 /* Copy the prefix contained in *PTR (up to a '.' or a NUL) to DEST.
50 PTR will be adjusted to point to the start of the next portion
51 of the opcode, or at the NUL character. */
54 get_opc_prefix (ptr
, dest
)
58 char *c
= strchr (*ptr
, '.');
61 memcpy (dest
, *ptr
, c
- *ptr
);
62 dest
[c
- *ptr
] = '\0';
67 int l
= strlen (*ptr
);
68 memcpy (dest
, *ptr
, l
);
74 /* Find the index of the entry in the string table corresponding to
75 STR; return -1 if one does not exist. */
82 short end
= sizeof (ia64_strings
) / sizeof (const char *);
83 short i
= (start
+ end
) / 2;
85 if (strcmp (str
, ia64_strings
[end
- 1]) > 0)
91 int c
= strcmp (str
, ia64_strings
[i
]);
104 i
= (start
+ end
) / 2;
109 /* Find the opcode in the main opcode table whose name is STRINGINDEX, or
110 return -1 if one does not exist. */
113 find_main_ent (nameindex
)
117 short end
= sizeof (main_table
) / sizeof (struct ia64_main_table
);
118 short i
= (start
+ end
) / 2;
120 if (nameindex
< main_table
[0].name_index
121 || nameindex
> main_table
[end
- 1].name_index
)
127 if (nameindex
< main_table
[i
].name_index
)
131 else if (nameindex
== main_table
[i
].name_index
)
133 while (i
> 0 && main_table
[i
- 1].name_index
== nameindex
)
143 i
= (start
+ end
) / 2;
148 /* Find the index of the entry in the completer table that is part of
149 MAIN_ENT (starting from PREV_COMPLETER) that matches NAME, or
150 return -1 if one does not exist. */
153 find_completer (main_ent
, prev_completer
, name
)
155 short prev_completer
;
158 short name_index
= find_string_ent (name
);
165 if (prev_completer
== -1)
167 prev_completer
= main_table
[main_ent
].completers
;
171 prev_completer
= completer_table
[prev_completer
].subentries
;
174 while (prev_completer
!= -1)
176 if (completer_table
[prev_completer
].name_index
== name_index
)
178 return prev_completer
;
180 prev_completer
= completer_table
[prev_completer
].alternative
;
185 /* Apply the completer referred to by COMPLETER_INDEX to OPCODE, and
186 return the result. */
189 apply_completer (opcode
, completer_index
)
193 ia64_insn mask
= completer_table
[completer_index
].mask
;
194 ia64_insn bits
= completer_table
[completer_index
].bits
;
195 int shiftamt
= (completer_table
[completer_index
].offset
& 63);
197 mask
= mask
<< shiftamt
;
198 bits
= bits
<< shiftamt
;
199 opcode
= (opcode
& ~mask
) | bits
;
203 /* Extract BITS number of bits starting from OP_POINTER + BITOFFSET in
204 the dis_table array, and return its value. (BITOFFSET is numbered
205 starting from MSB to LSB, so a BITOFFSET of 0 indicates the MSB of the
206 first byte in OP_POINTER.) */
209 extract_op_bits (op_pointer
, bitoffset
, bits
)
216 op_pointer
+= (bitoffset
/ 8);
220 unsigned int op
= dis_table
[op_pointer
++];
221 int numb
= 8 - (bitoffset
% 8);
222 int mask
= (1 << numb
) - 1;
223 int bata
= (bits
< numb
) ? bits
: numb
;
224 int delta
= numb
- bata
;
226 res
= (res
<< bata
) | ((op
& mask
) >> delta
);
232 res
= (res
<< 8) | (dis_table
[op_pointer
++] & 255);
237 unsigned int op
= (dis_table
[op_pointer
++] & 255);
238 res
= (res
<< bits
) | (op
>> (8 - bits
));
243 /* Examine the state machine entry at OP_POINTER in the dis_table
244 array, and extract its values into OPVAL and OP. The length of the
245 state entry in bits is returned. */
248 extract_op (op_pointer
, opval
, op
)
255 *op
= dis_table
[op_pointer
];
259 opval
[0] = extract_op_bits (op_pointer
, oplen
, 5);
262 switch ((*op
) & 0x30)
266 opval
[1] = extract_op_bits (op_pointer
, oplen
, 8);
268 opval
[1] += op_pointer
;
273 opval
[1] = extract_op_bits (op_pointer
, oplen
, 16);
274 if (! (opval
[1] & 32768))
276 opval
[1] += op_pointer
;
284 opval
[2] = extract_op_bits (op_pointer
, oplen
, 12);
290 if (((*op
) & 0x08) && (((*op
) & 0x30) != 0x30))
292 opval
[2] = extract_op_bits (op_pointer
, oplen
, 16);
294 if (! (opval
[2] & 32768))
296 opval
[2] += op_pointer
;
302 /* Returns a non-zero value if the opcode in the main_table list at
303 PLACE matches OPCODE and is of type TYPE. */
306 opcode_verify (opcode
, place
, type
)
309 enum ia64_insn_type type
;
311 if (main_table
[place
].opcode_type
!= type
)
315 if (main_table
[place
].flags
316 & (IA64_OPCODE_F2_EQ_F3
| IA64_OPCODE_LEN_EQ_64MCNT
))
318 const struct ia64_operand
*o1
, *o2
;
321 if (main_table
[place
].flags
& IA64_OPCODE_F2_EQ_F3
)
323 o1
= elf64_ia64_operands
+ IA64_OPND_F2
;
324 o2
= elf64_ia64_operands
+ IA64_OPND_F3
;
325 (*o1
->extract
) (o1
, opcode
, &f2
);
326 (*o2
->extract
) (o2
, opcode
, &f3
);
332 ia64_insn len
, count
;
334 /* length must equal 64-count: */
335 o1
= elf64_ia64_operands
+ IA64_OPND_LEN6
;
336 o2
= elf64_ia64_operands
+ main_table
[place
].operands
[2];
337 (*o1
->extract
) (o1
, opcode
, &len
);
338 (*o2
->extract
) (o2
, opcode
, &count
);
339 if (len
!= 64 - count
)
346 /* Find an instruction entry in the ia64_dis_names array that matches
347 opcode OPCODE and is of type TYPE. Returns either a positive index
348 into the array, or a negative value if an entry for OPCODE could
349 not be found. Checks all matches and returns the one with the highest
353 locate_opcode_ent (opcode
, type
)
355 enum ia64_insn_type type
;
360 int currstatenum
= 0;
361 short found_disent
= -1;
362 short found_priority
= -1;
364 currtest
[currstatenum
] = 0;
365 op_ptr
[currstatenum
] = 0;
366 bitpos
[currstatenum
] = 40;
370 int op_pointer
= op_ptr
[currstatenum
];
372 int currbitnum
= bitpos
[currstatenum
];
378 oplen
= extract_op (op_pointer
, opval
, &op
);
380 bitpos
[currstatenum
] = currbitnum
;
382 /* Skip opval[0] bits in the instruction. */
385 currbitnum
-= opval
[0];
388 /* The value of the current bit being tested. */
389 currbit
= opcode
& (((ia64_insn
) 1) << currbitnum
) ? 1 : 0;
392 /* We always perform the tests specified in the current state in
393 a particular order, falling through to the next test if the
394 previous one failed. */
395 switch (currtest
[currstatenum
])
398 currtest
[currstatenum
]++;
399 if (currbit
== 0 && (op
& 0x80))
401 /* Check for a zero bit. If this test solely checks for
402 a zero bit, we can check for up to 8 consecutive zero
403 bits (the number to check is specified by the lower 3
404 bits in the state code.)
406 If the state instruction matches, we go to the very
407 next state instruction; otherwise, try the next test. */
409 if ((op
& 0xf8) == 0x80)
411 int count
= op
& 0x7;
414 for (x
= 0; x
<= count
; x
++)
417 opcode
& (((ia64_insn
) 1) << (currbitnum
- x
)) ? 1 : 0;
425 next_op
= op_pointer
+ ((oplen
+ 7) / 8);
432 next_op
= op_pointer
+ ((oplen
+ 7) / 8);
438 /* If the bit in the instruction is one, go to the state
439 instruction specified by opval[1]. */
440 currtest
[currstatenum
]++;
441 if (currbit
&& (op
& 0x30) != 0 && ((op
& 0x30) != 0x30))
448 /* Don't care. Skip the current bit and go to the state
449 instruction specified by opval[2].
451 An encoding of 0x30 is special; this means that a 12-bit
452 offset into the ia64_dis_names[] array is specified. */
453 currtest
[currstatenum
]++;
454 if ((op
& 0x08) || ((op
& 0x30) == 0x30))
461 /* If bit 15 is set in the address of the next state, an offset
462 in the ia64_dis_names array was specified instead. We then
463 check to see if an entry in the list of opcodes matches the
464 opcode we were given; if so, we have succeeded. */
466 if ((next_op
>= 0) && (next_op
& 32768))
468 short disent
= next_op
& 32767;
476 /* Run through the list of opcodes to check, trying to find
480 int place
= ia64_dis_names
[disent
].insn_index
;
482 priority
= ia64_dis_names
[disent
].priority
;
484 if (opcode_verify (opcode
, place
, type
)
485 && priority
> found_priority
)
489 if (ia64_dis_names
[disent
].next_flag
)
501 found_disent
= disent
;
502 found_priority
= priority
;
504 /* Try the next test in this state, regardless of whether a match
509 /* next_op == -1 is "back up to the previous state".
510 next_op == -2 is "stay in this state and try the next test".
511 Otherwise, transition to the state indicated by next_op. */
516 if (currstatenum
< 0)
521 else if (next_op
>= 0)
524 bitpos
[currstatenum
] = currbitnum
- 1;
525 op_ptr
[currstatenum
] = next_op
;
526 currtest
[currstatenum
] = 0;
531 /* Construct an ia64_opcode entry based on OPCODE, NAME and PLACE. */
533 static struct ia64_opcode
*
534 make_ia64_opcode (opcode
, name
, place
, depind
)
540 struct ia64_opcode
*res
=
541 (struct ia64_opcode
*) xmalloc (sizeof (struct ia64_opcode
));
542 res
->name
= xstrdup (name
);
543 res
->type
= main_table
[place
].opcode_type
;
544 res
->num_outputs
= main_table
[place
].num_outputs
;
545 res
->opcode
= opcode
;
546 res
->mask
= main_table
[place
].mask
;
547 res
->operands
[0] = main_table
[place
].operands
[0];
548 res
->operands
[1] = main_table
[place
].operands
[1];
549 res
->operands
[2] = main_table
[place
].operands
[2];
550 res
->operands
[3] = main_table
[place
].operands
[3];
551 res
->operands
[4] = main_table
[place
].operands
[4];
552 res
->flags
= main_table
[place
].flags
;
553 res
->ent_index
= place
;
554 res
->dependencies
= &op_dependencies
[depind
];
558 /* Determine the ia64_opcode entry for the opcode specified by INSN
559 and TYPE. If a valid entry is not found, return NULL. */
561 ia64_dis_opcode (insn
, type
)
563 enum ia64_insn_type type
;
565 int disent
= locate_opcode_ent (insn
, type
);
573 unsigned int cb
= ia64_dis_names
[disent
].completer_index
;
574 static char name
[128];
575 int place
= ia64_dis_names
[disent
].insn_index
;
576 int ci
= main_table
[place
].completers
;
577 ia64_insn tinsn
= main_table
[place
].opcode
;
579 strcpy (name
, ia64_strings
[main_table
[place
].name_index
]);
585 int cname
= completer_table
[ci
].name_index
;
587 tinsn
= apply_completer (tinsn
, ci
);
589 if (ia64_strings
[cname
][0] != '\0')
592 strcat (name
, ia64_strings
[cname
]);
596 ci
= completer_table
[ci
].subentries
;
601 ci
= completer_table
[ci
].alternative
;
609 if (tinsn
!= (insn
& main_table
[place
].mask
))
613 return make_ia64_opcode (insn
, name
, place
,
614 completer_table
[ci
].dependencies
);
618 /* Search the main_opcode table starting from PLACE for an opcode that
619 matches NAME. Return NULL if one is not found. */
621 static struct ia64_opcode
*
622 ia64_find_matching_opcode (name
, place
)
630 if (strlen (name
) > 128)
635 get_opc_prefix (&suffix
, op
);
636 name_index
= find_string_ent (op
);
642 while (main_table
[place
].name_index
== name_index
)
644 const char *curr_suffix
= suffix
;
645 ia64_insn curr_insn
= main_table
[place
].opcode
;
646 short completer
= -1;
649 if (suffix
[0] == '\0')
651 completer
= find_completer (place
, completer
, suffix
);
655 get_opc_prefix (&curr_suffix
, op
);
656 completer
= find_completer (place
, completer
, op
);
660 curr_insn
= apply_completer (curr_insn
, completer
);
662 } while (completer
!= -1 && curr_suffix
[0] != '\0');
664 if (completer
!= -1 && curr_suffix
[0] == '\0'
665 && completer_table
[completer
].terminal_completer
)
667 int depind
= completer_table
[completer
].dependencies
;
668 return make_ia64_opcode (curr_insn
, name
, place
, depind
);
678 /* Find the next opcode after PREV_ENT that matches PREV_ENT, or return NULL
679 if one does not exist.
681 It is the caller's responsibility to invoke ia64_free_opcode () to
682 release any resources used by the returned entry. */
685 ia64_find_next_opcode (prev_ent
)
686 struct ia64_opcode
*prev_ent
;
688 return ia64_find_matching_opcode (prev_ent
->name
,
689 prev_ent
->ent_index
+ 1);
692 /* Find the first opcode that matches NAME, or return NULL if it does
695 It is the caller's responsibility to invoke ia64_free_opcode () to
696 release any resources used by the returned entry. */
699 ia64_find_opcode (name
)
707 if (strlen (name
) > 128)
712 get_opc_prefix (&suffix
, op
);
713 name_index
= find_string_ent (op
);
719 place
= find_main_ent (name_index
);
725 return ia64_find_matching_opcode (name
, place
);
728 /* Free any resources used by ENT. */
730 ia64_free_opcode (ent
)
731 struct ia64_opcode
*ent
;
733 free ((void *)ent
->name
);
737 const struct ia64_dependency
*
738 ia64_find_dependency (index
)
744 || index
>= (int)(sizeof(dependencies
) / sizeof(dependencies
[0])))
747 return &dependencies
[index
];