1 /* CGEN generic opcode support.
3 Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
5 This file is part of the GNU Binutils and GDB, the GNU debugger.
7 This program 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 2, or (at your option)
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 #include "libiberty.h"
28 #include "opcode/cgen.h"
34 static unsigned int hash_keyword_name
35 PARAMS ((const CGEN_KEYWORD
*, const char *, int));
36 static unsigned int hash_keyword_value
37 PARAMS ((const CGEN_KEYWORD
*, unsigned int));
38 static void build_keyword_hash_tables
39 PARAMS ((CGEN_KEYWORD
*));
41 /* Return number of hash table entries to use for N elements. */
42 #define KEYWORD_HASH_SIZE(n) ((n) <= 31 ? 17 : 31)
44 /* Look up *NAMEP in the keyword table KT.
45 The result is the keyword entry or NULL if not found. */
47 const CGEN_KEYWORD_ENTRY
*
48 cgen_keyword_lookup_name (kt
, name
)
52 const CGEN_KEYWORD_ENTRY
*ke
;
55 if (kt
->name_hash_table
== NULL
)
56 build_keyword_hash_tables (kt
);
58 ke
= kt
->name_hash_table
[hash_keyword_name (kt
, name
, 0)];
60 /* We do case insensitive comparisons.
61 If that ever becomes a problem, add an attribute that denotes
62 "do case sensitive comparisons". */
71 || (isalpha ((unsigned char) *p
)
72 && (tolower ((unsigned char) *p
)
73 == tolower ((unsigned char) *n
)))))
83 return kt
->null_entry
;
87 /* Look up VALUE in the keyword table KT.
88 The result is the keyword entry or NULL if not found. */
90 const CGEN_KEYWORD_ENTRY
*
91 cgen_keyword_lookup_value (kt
, value
)
95 const CGEN_KEYWORD_ENTRY
*ke
;
97 if (kt
->name_hash_table
== NULL
)
98 build_keyword_hash_tables (kt
);
100 ke
= kt
->value_hash_table
[hash_keyword_value (kt
, value
)];
104 if (value
== ke
->value
)
112 /* Add an entry to a keyword table. */
115 cgen_keyword_add (kt
, ke
)
117 CGEN_KEYWORD_ENTRY
*ke
;
121 if (kt
->name_hash_table
== NULL
)
122 build_keyword_hash_tables (kt
);
124 hash
= hash_keyword_name (kt
, ke
->name
, 0);
125 ke
->next_name
= kt
->name_hash_table
[hash
];
126 kt
->name_hash_table
[hash
] = ke
;
128 hash
= hash_keyword_value (kt
, ke
->value
);
129 ke
->next_value
= kt
->value_hash_table
[hash
];
130 kt
->value_hash_table
[hash
] = ke
;
132 if (ke
->name
[0] == 0)
136 /* FIXME: Need function to return count of keywords. */
138 /* Initialize a keyword table search.
139 SPEC is a specification of what to search for.
140 A value of NULL means to find every keyword.
141 Currently NULL is the only acceptable value [further specification
143 The result is an opaque data item used to record the search status.
144 It is passed to each call to cgen_keyword_search_next. */
147 cgen_keyword_search_init (kt
, spec
)
151 CGEN_KEYWORD_SEARCH search
;
153 /* FIXME: Need to specify format of PARAMS. */
157 if (kt
->name_hash_table
== NULL
)
158 build_keyword_hash_tables (kt
);
162 search
.current_hash
= 0;
163 search
.current_entry
= NULL
;
167 /* Return the next keyword specified by SEARCH.
168 The result is the next entry or NULL if there are no more. */
170 const CGEN_KEYWORD_ENTRY
*
171 cgen_keyword_search_next (search
)
172 CGEN_KEYWORD_SEARCH
*search
;
174 /* Has search finished? */
175 if (search
->current_hash
== search
->table
->hash_table_size
)
178 /* Search in progress? */
179 if (search
->current_entry
!= NULL
180 /* Anything left on this hash chain? */
181 && search
->current_entry
->next_name
!= NULL
)
183 search
->current_entry
= search
->current_entry
->next_name
;
184 return search
->current_entry
;
187 /* Move to next hash chain [unless we haven't started yet]. */
188 if (search
->current_entry
!= NULL
)
189 ++search
->current_hash
;
191 while (search
->current_hash
< search
->table
->hash_table_size
)
193 search
->current_entry
= search
->table
->name_hash_table
[search
->current_hash
];
194 if (search
->current_entry
!= NULL
)
195 return search
->current_entry
;
196 ++search
->current_hash
;
202 /* Return first entry in hash chain for NAME.
203 If CASE_SENSITIVE_P is non-zero, return a case sensitive hash. */
206 hash_keyword_name (kt
, name
, case_sensitive_p
)
207 const CGEN_KEYWORD
*kt
;
209 int case_sensitive_p
;
213 if (case_sensitive_p
)
214 for (hash
= 0; *name
; ++name
)
215 hash
= (hash
* 97) + (unsigned char) *name
;
217 for (hash
= 0; *name
; ++name
)
218 hash
= (hash
* 97) + (unsigned char) tolower (*name
);
219 return hash
% kt
->hash_table_size
;
222 /* Return first entry in hash chain for VALUE. */
225 hash_keyword_value (kt
, value
)
226 const CGEN_KEYWORD
*kt
;
229 return value
% kt
->hash_table_size
;
232 /* Build a keyword table's hash tables.
233 We probably needn't build the value hash table for the assembler when
234 we're using the disassembler, but we keep things simple. */
237 build_keyword_hash_tables (kt
)
241 /* Use the number of compiled in entries as an estimate for the
242 typical sized table [not too many added at runtime]. */
243 unsigned int size
= KEYWORD_HASH_SIZE (kt
->num_init_entries
);
245 kt
->hash_table_size
= size
;
246 kt
->name_hash_table
= (CGEN_KEYWORD_ENTRY
**)
247 xmalloc (size
* sizeof (CGEN_KEYWORD_ENTRY
*));
248 memset (kt
->name_hash_table
, 0, size
* sizeof (CGEN_KEYWORD_ENTRY
*));
249 kt
->value_hash_table
= (CGEN_KEYWORD_ENTRY
**)
250 xmalloc (size
* sizeof (CGEN_KEYWORD_ENTRY
*));
251 memset (kt
->value_hash_table
, 0, size
* sizeof (CGEN_KEYWORD_ENTRY
*));
253 /* The table is scanned backwards as we want keywords appearing earlier to
254 be prefered over later ones. */
255 for (i
= kt
->num_init_entries
- 1; i
>= 0; --i
)
256 cgen_keyword_add (kt
, &kt
->init_entries
[i
]);
259 /* Hardware support. */
261 /* Lookup a hardware element by its name.
262 Returns NULL if NAME is not supported by the currently selected
265 const CGEN_HW_ENTRY
*
266 cgen_hw_lookup_by_name (cd
, name
)
271 const CGEN_HW_ENTRY
**hw
= cd
->hw_table
.entries
;
273 for (i
= 0; i
< cd
->hw_table
.num_entries
; ++i
)
274 if (hw
[i
] && strcmp (name
, hw
[i
]->name
) == 0)
280 /* Lookup a hardware element by its number.
281 Hardware elements are enumerated, however it may be possible to add some
282 at runtime, thus HWNUM is not an enum type but rather an int.
283 Returns NULL if HWNUM is not supported by the currently selected mach. */
285 const CGEN_HW_ENTRY
*
286 cgen_hw_lookup_by_num (cd
, hwnum
)
291 const CGEN_HW_ENTRY
**hw
= cd
->hw_table
.entries
;
293 /* ??? This can be speeded up. */
294 for (i
= 0; i
< cd
->hw_table
.num_entries
; ++i
)
295 if (hw
[i
] && hwnum
== hw
[i
]->type
)
301 /* Operand support. */
303 /* Lookup an operand by its name.
304 Returns NULL if NAME is not supported by the currently selected
308 cgen_operand_lookup_by_name (cd
, name
)
313 const CGEN_OPERAND
**op
= cd
->operand_table
.entries
;
315 for (i
= 0; i
< cd
->operand_table
.num_entries
; ++i
)
316 if (op
[i
] && strcmp (name
, op
[i
]->name
) == 0)
322 /* Lookup an operand by its number.
323 Operands are enumerated, however it may be possible to add some
324 at runtime, thus OPNUM is not an enum type but rather an int.
325 Returns NULL if OPNUM is not supported by the currently selected
329 cgen_operand_lookup_by_num (cd
, opnum
)
333 return cd
->operand_table
.entries
[opnum
];
336 /* Instruction support. */
338 /* Return number of instructions. This includes any added at runtime. */
344 int count
= cd
->insn_table
.num_init_entries
;
345 CGEN_INSN_LIST
*rt_insns
= cd
->insn_table
.new_entries
;
347 for ( ; rt_insns
!= NULL
; rt_insns
= rt_insns
->next
)
353 /* Return number of macro-instructions.
354 This includes any added at runtime. */
357 cgen_macro_insn_count (cd
)
360 int count
= cd
->macro_insn_table
.num_init_entries
;
361 CGEN_INSN_LIST
*rt_insns
= cd
->macro_insn_table
.new_entries
;
363 for ( ; rt_insns
!= NULL
; rt_insns
= rt_insns
->next
)
369 /* Cover function to read and properly byteswap an insn value. */
372 cgen_get_insn_value (cd
, buf
, length
)
385 if (cd
->insn_endian
== CGEN_ENDIAN_BIG
)
386 value
= bfd_getb16 (buf
);
388 value
= bfd_getl16 (buf
);
391 if (cd
->insn_endian
== CGEN_ENDIAN_BIG
)
392 value
= bfd_getb32 (buf
);
394 value
= bfd_getl32 (buf
);
403 /* Cover function to store an insn value properly byteswapped. */
406 cgen_put_insn_value (cd
, buf
, length
, value
)
418 if (cd
->insn_endian
== CGEN_ENDIAN_BIG
)
419 bfd_putb16 (value
, buf
);
421 bfd_putl16 (value
, buf
);
424 if (cd
->insn_endian
== CGEN_ENDIAN_BIG
)
425 bfd_putb32 (value
, buf
);
427 bfd_putl32 (value
, buf
);
434 /* Look up instruction INSN_*_VALUE and extract its fields.
435 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
436 Otherwise INSN_BYTES_VALUE is used.
437 INSN, if non-null, is the insn table entry.
438 Otherwise INSN_*_VALUE is examined to compute it.
439 LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0.
440 0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
441 If INSN != NULL, LENGTH must be valid.
442 ALIAS_P is non-zero if alias insns are to be included in the search.
444 The result is a pointer to the insn table entry, or NULL if the instruction
445 wasn't recognized. */
447 /* ??? Will need to be revisited for VLIW architectures. */
450 cgen_lookup_insn (cd
, insn
, insn_int_value
, insn_bytes_value
, length
, fields
,
453 const CGEN_INSN
*insn
;
454 CGEN_INSN_INT insn_int_value
;
455 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
456 unsigned char *insn_bytes_value
;
462 CGEN_INSN_INT base_insn
;
463 CGEN_EXTRACT_INFO ex_info
;
464 CGEN_EXTRACT_INFO
*info
;
469 buf
= (unsigned char *) alloca (cd
->max_insn_bitsize
/ 8);
470 cgen_put_insn_value (cd
, buf
, length
, insn_int_value
);
471 base_insn
= insn_int_value
;
476 ex_info
.dis_info
= NULL
;
477 ex_info
.insn_bytes
= insn_bytes_value
;
479 buf
= insn_bytes_value
;
480 base_insn
= cgen_get_insn_value (cd
, buf
, length
);
485 const CGEN_INSN_LIST
*insn_list
;
487 /* The instructions are stored in hash lists.
488 Pick the first one and keep trying until we find the right one. */
490 insn_list
= cgen_dis_lookup_insn (cd
, buf
, base_insn
);
491 while (insn_list
!= NULL
)
493 insn
= insn_list
->insn
;
496 /* FIXME: Ensure ALIAS attribute always has same index. */
497 || ! CGEN_INSN_ATTR_VALUE (insn
, CGEN_INSN_ALIAS
))
499 /* Basic bit mask must be correct. */
500 /* ??? May wish to allow target to defer this check until the
502 if ((base_insn
& CGEN_INSN_BASE_MASK (insn
))
503 == CGEN_INSN_BASE_VALUE (insn
))
505 /* ??? 0 is passed for `pc' */
506 int elength
= CGEN_EXTRACT_FN (cd
, insn
)
507 (cd
, insn
, info
, base_insn
, fields
, (bfd_vma
) 0);
511 if (length
!= 0 && length
!= elength
)
518 insn_list
= insn_list
->next
;
523 /* Sanity check: can't pass an alias insn if ! alias_p. */
525 && CGEN_INSN_ATTR_VALUE (insn
, CGEN_INSN_ALIAS
))
527 /* Sanity check: length must be correct. */
528 if (length
!= CGEN_INSN_BITSIZE (insn
))
531 /* ??? 0 is passed for `pc' */
532 length
= CGEN_EXTRACT_FN (cd
, insn
)
533 (cd
, insn
, info
, base_insn
, fields
, (bfd_vma
) 0);
534 /* Sanity check: must succeed.
535 Could relax this later if it ever proves useful. */
544 /* Fill in the operand instances used by INSN whose operands are FIELDS.
545 INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
549 cgen_get_insn_operands (cd
, insn
, fields
, indices
)
551 const CGEN_INSN
*insn
;
552 const CGEN_FIELDS
*fields
;
555 const CGEN_OPINST
*opinst
;
558 if (insn
->opinst
== NULL
)
560 for (i
= 0, opinst
= insn
->opinst
; opinst
->type
!= CGEN_OPINST_END
; ++i
, ++opinst
)
562 enum cgen_operand_type op_type
= opinst
->op_type
;
563 if (op_type
== CGEN_OPERAND_NIL
)
564 indices
[i
] = opinst
->index
;
566 indices
[i
] = (*cd
->get_int_operand
) (cd
, op_type
, fields
);
570 /* Cover function to cgen_get_insn_operands when either INSN or FIELDS
572 The INSN, INSN_*_VALUE, and LENGTH arguments are passed to
573 cgen_lookup_insn unchanged.
574 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
575 Otherwise INSN_BYTES_VALUE is used.
577 The result is the insn table entry or NULL if the instruction wasn't
581 cgen_lookup_get_insn_operands (cd
, insn
, insn_int_value
, insn_bytes_value
,
582 length
, indices
, fields
)
584 const CGEN_INSN
*insn
;
585 CGEN_INSN_INT insn_int_value
;
586 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
587 unsigned char *insn_bytes_value
;
592 /* Pass non-zero for ALIAS_P only if INSN != NULL.
593 If INSN == NULL, we want a real insn. */
594 insn
= cgen_lookup_insn (cd
, insn
, insn_int_value
, insn_bytes_value
,
595 length
, fields
, insn
!= NULL
);
599 cgen_get_insn_operands (cd
, insn
, fields
, indices
);
603 /* Allow signed overflow of instruction fields. */
605 cgen_set_signed_overflow_ok (cd
)
608 cd
->signed_overflow_ok_p
= 1;
611 /* Generate an error message if a signed field in an instruction overflows. */
613 cgen_clear_signed_overflow_ok (cd
)
616 cd
->signed_overflow_ok_p
= 0;
619 /* Will an error message be generated if a signed field in an instruction overflows ? */
621 cgen_signed_overflow_ok_p (cd
)
624 return cd
->signed_overflow_ok_p
;