1 /* CGEN generic opcode support.
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2005, 2007
4 Free Software Foundation, Inc.
6 This file is part of libopcodes.
8 This library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 It is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
25 #include "libiberty.h"
26 #include "safe-ctype.h"
29 #include "opcode/cgen.h"
35 static unsigned int hash_keyword_name
36 (const CGEN_KEYWORD
*, const char *, int);
37 static unsigned int hash_keyword_value
38 (const CGEN_KEYWORD
*, unsigned int);
39 static void build_keyword_hash_tables
42 /* Return number of hash table entries to use for N elements. */
43 #define KEYWORD_HASH_SIZE(n) ((n) <= 31 ? 17 : 31)
45 /* Look up *NAMEP in the keyword table KT.
46 The result is the keyword entry or NULL if not found. */
48 const CGEN_KEYWORD_ENTRY
*
49 cgen_keyword_lookup_name (CGEN_KEYWORD
*kt
, const char *name
)
51 const CGEN_KEYWORD_ENTRY
*ke
;
54 if (kt
->name_hash_table
== NULL
)
55 build_keyword_hash_tables (kt
);
57 ke
= kt
->name_hash_table
[hash_keyword_name (kt
, name
, 0)];
59 /* We do case insensitive comparisons.
60 If that ever becomes a problem, add an attribute that denotes
61 "do case sensitive comparisons". */
70 || (ISALPHA (*p
) && (TOLOWER (*p
) == TOLOWER (*n
)))))
80 return kt
->null_entry
;
84 /* Look up VALUE in the keyword table KT.
85 The result is the keyword entry or NULL if not found. */
87 const CGEN_KEYWORD_ENTRY
*
88 cgen_keyword_lookup_value (CGEN_KEYWORD
*kt
, int value
)
90 const CGEN_KEYWORD_ENTRY
*ke
;
92 if (kt
->name_hash_table
== NULL
)
93 build_keyword_hash_tables (kt
);
95 ke
= kt
->value_hash_table
[hash_keyword_value (kt
, value
)];
99 if (value
== ke
->value
)
107 /* Add an entry to a keyword table. */
110 cgen_keyword_add (CGEN_KEYWORD
*kt
, CGEN_KEYWORD_ENTRY
*ke
)
115 if (kt
->name_hash_table
== NULL
)
116 build_keyword_hash_tables (kt
);
118 hash
= hash_keyword_name (kt
, ke
->name
, 0);
119 ke
->next_name
= kt
->name_hash_table
[hash
];
120 kt
->name_hash_table
[hash
] = ke
;
122 hash
= hash_keyword_value (kt
, ke
->value
);
123 ke
->next_value
= kt
->value_hash_table
[hash
];
124 kt
->value_hash_table
[hash
] = ke
;
126 if (ke
->name
[0] == 0)
129 for (i
= 1; i
< strlen (ke
->name
); i
++)
130 if (! ISALNUM (ke
->name
[i
])
131 && ! strchr (kt
->nonalpha_chars
, ke
->name
[i
]))
133 size_t idx
= strlen (kt
->nonalpha_chars
);
135 /* If you hit this limit, please don't just
136 increase the size of the field, instead
137 look for a better algorithm. */
138 if (idx
>= sizeof (kt
->nonalpha_chars
) - 1)
140 kt
->nonalpha_chars
[idx
] = ke
->name
[i
];
141 kt
->nonalpha_chars
[idx
+1] = 0;
145 /* FIXME: Need function to return count of keywords. */
147 /* Initialize a keyword table search.
148 SPEC is a specification of what to search for.
149 A value of NULL means to find every keyword.
150 Currently NULL is the only acceptable value [further specification
152 The result is an opaque data item used to record the search status.
153 It is passed to each call to cgen_keyword_search_next. */
156 cgen_keyword_search_init (CGEN_KEYWORD
*kt
, const char *spec
)
158 CGEN_KEYWORD_SEARCH search
;
160 /* FIXME: Need to specify format of params. */
164 if (kt
->name_hash_table
== NULL
)
165 build_keyword_hash_tables (kt
);
169 search
.current_hash
= 0;
170 search
.current_entry
= NULL
;
174 /* Return the next keyword specified by SEARCH.
175 The result is the next entry or NULL if there are no more. */
177 const CGEN_KEYWORD_ENTRY
*
178 cgen_keyword_search_next (CGEN_KEYWORD_SEARCH
*search
)
180 /* Has search finished? */
181 if (search
->current_hash
== search
->table
->hash_table_size
)
184 /* Search in progress? */
185 if (search
->current_entry
!= NULL
186 /* Anything left on this hash chain? */
187 && search
->current_entry
->next_name
!= NULL
)
189 search
->current_entry
= search
->current_entry
->next_name
;
190 return search
->current_entry
;
193 /* Move to next hash chain [unless we haven't started yet]. */
194 if (search
->current_entry
!= NULL
)
195 ++search
->current_hash
;
197 while (search
->current_hash
< search
->table
->hash_table_size
)
199 search
->current_entry
= search
->table
->name_hash_table
[search
->current_hash
];
200 if (search
->current_entry
!= NULL
)
201 return search
->current_entry
;
202 ++search
->current_hash
;
208 /* Return first entry in hash chain for NAME.
209 If CASE_SENSITIVE_P is non-zero, return a case sensitive hash. */
212 hash_keyword_name (const CGEN_KEYWORD
*kt
,
214 int case_sensitive_p
)
218 if (case_sensitive_p
)
219 for (hash
= 0; *name
; ++name
)
220 hash
= (hash
* 97) + (unsigned char) *name
;
222 for (hash
= 0; *name
; ++name
)
223 hash
= (hash
* 97) + (unsigned char) TOLOWER (*name
);
224 return hash
% kt
->hash_table_size
;
227 /* Return first entry in hash chain for VALUE. */
230 hash_keyword_value (const CGEN_KEYWORD
*kt
, unsigned int value
)
232 return value
% kt
->hash_table_size
;
235 /* Build a keyword table's hash tables.
236 We probably needn't build the value hash table for the assembler when
237 we're using the disassembler, but we keep things simple. */
240 build_keyword_hash_tables (CGEN_KEYWORD
*kt
)
243 /* Use the number of compiled in entries as an estimate for the
244 typical sized table [not too many added at runtime]. */
245 unsigned int size
= KEYWORD_HASH_SIZE (kt
->num_init_entries
);
247 kt
->hash_table_size
= size
;
248 kt
->name_hash_table
= (CGEN_KEYWORD_ENTRY
**)
249 xmalloc (size
* sizeof (CGEN_KEYWORD_ENTRY
*));
250 memset (kt
->name_hash_table
, 0, size
* sizeof (CGEN_KEYWORD_ENTRY
*));
251 kt
->value_hash_table
= (CGEN_KEYWORD_ENTRY
**)
252 xmalloc (size
* sizeof (CGEN_KEYWORD_ENTRY
*));
253 memset (kt
->value_hash_table
, 0, size
* sizeof (CGEN_KEYWORD_ENTRY
*));
255 /* The table is scanned backwards as we want keywords appearing earlier to
256 be prefered over later ones. */
257 for (i
= kt
->num_init_entries
- 1; i
>= 0; --i
)
258 cgen_keyword_add (kt
, &kt
->init_entries
[i
]);
261 /* Hardware support. */
263 /* Lookup a hardware element by its name.
264 Returns NULL if NAME is not supported by the currently selected
267 const CGEN_HW_ENTRY
*
268 cgen_hw_lookup_by_name (CGEN_CPU_DESC cd
, const char *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 (CGEN_CPU_DESC cd
, unsigned int hwnum
)
289 const CGEN_HW_ENTRY
**hw
= cd
->hw_table
.entries
;
291 /* ??? This can be speeded up. */
292 for (i
= 0; i
< cd
->hw_table
.num_entries
; ++i
)
293 if (hw
[i
] && hwnum
== hw
[i
]->type
)
299 /* Operand support. */
301 /* Lookup an operand by its name.
302 Returns NULL if NAME is not supported by the currently selected
306 cgen_operand_lookup_by_name (CGEN_CPU_DESC cd
, const char *name
)
309 const CGEN_OPERAND
**op
= cd
->operand_table
.entries
;
311 for (i
= 0; i
< cd
->operand_table
.num_entries
; ++i
)
312 if (op
[i
] && strcmp (name
, op
[i
]->name
) == 0)
318 /* Lookup an operand by its number.
319 Operands are enumerated, however it may be possible to add some
320 at runtime, thus OPNUM is not an enum type but rather an int.
321 Returns NULL if OPNUM is not supported by the currently selected
325 cgen_operand_lookup_by_num (CGEN_CPU_DESC cd
, int opnum
)
327 return cd
->operand_table
.entries
[opnum
];
330 /* Instruction support. */
332 /* Return number of instructions. This includes any added at runtime. */
335 cgen_insn_count (CGEN_CPU_DESC cd
)
337 int count
= cd
->insn_table
.num_init_entries
;
338 CGEN_INSN_LIST
*rt_insns
= cd
->insn_table
.new_entries
;
340 for ( ; rt_insns
!= NULL
; rt_insns
= rt_insns
->next
)
346 /* Return number of macro-instructions.
347 This includes any added at runtime. */
350 cgen_macro_insn_count (CGEN_CPU_DESC cd
)
352 int count
= cd
->macro_insn_table
.num_init_entries
;
353 CGEN_INSN_LIST
*rt_insns
= cd
->macro_insn_table
.new_entries
;
355 for ( ; rt_insns
!= NULL
; rt_insns
= rt_insns
->next
)
361 /* Cover function to read and properly byteswap an insn value. */
364 cgen_get_insn_value (CGEN_CPU_DESC cd
, unsigned char *buf
, int length
)
366 int big_p
= (cd
->insn_endian
== CGEN_ENDIAN_BIG
);
367 int insn_chunk_bitsize
= cd
->insn_chunk_bitsize
;
368 CGEN_INSN_INT value
= 0;
370 if (insn_chunk_bitsize
!= 0 && insn_chunk_bitsize
< length
)
372 /* We need to divide up the incoming value into insn_chunk_bitsize-length
373 segments, and endian-convert them, one at a time. */
376 /* Enforce divisibility. */
377 if ((length
% insn_chunk_bitsize
) != 0)
380 for (i
= 0; i
< length
; i
+= insn_chunk_bitsize
) /* NB: i == bits */
384 index
= i
; /* NB: not dependent on endianness; opposite of cgen_put_insn_value! */
385 this_value
= bfd_get_bits (& buf
[index
/ 8], insn_chunk_bitsize
, big_p
);
386 value
= (value
<< insn_chunk_bitsize
) | this_value
;
391 value
= bfd_get_bits (buf
, length
, cd
->insn_endian
== CGEN_ENDIAN_BIG
);
397 /* Cover function to store an insn value properly byteswapped. */
400 cgen_put_insn_value (CGEN_CPU_DESC cd
,
405 int big_p
= (cd
->insn_endian
== CGEN_ENDIAN_BIG
);
406 int insn_chunk_bitsize
= cd
->insn_chunk_bitsize
;
408 if (insn_chunk_bitsize
!= 0 && insn_chunk_bitsize
< length
)
410 /* We need to divide up the incoming value into insn_chunk_bitsize-length
411 segments, and endian-convert them, one at a time. */
414 /* Enforce divisibility. */
415 if ((length
% insn_chunk_bitsize
) != 0)
418 for (i
= 0; i
< length
; i
+= insn_chunk_bitsize
) /* NB: i == bits */
421 index
= (length
- insn_chunk_bitsize
- i
); /* NB: not dependent on endianness! */
422 bfd_put_bits ((bfd_vma
) value
, & buf
[index
/ 8], insn_chunk_bitsize
, big_p
);
423 value
>>= insn_chunk_bitsize
;
428 bfd_put_bits ((bfd_vma
) value
, buf
, length
, big_p
);
432 /* Look up instruction INSN_*_VALUE and extract its fields.
433 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
434 Otherwise INSN_BYTES_VALUE is used.
435 INSN, if non-null, is the insn table entry.
436 Otherwise INSN_*_VALUE is examined to compute it.
437 LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0.
438 0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
439 If INSN != NULL, LENGTH must be valid.
440 ALIAS_P is non-zero if alias insns are to be included in the search.
442 The result is a pointer to the insn table entry, or NULL if the instruction
443 wasn't recognized. */
445 /* ??? Will need to be revisited for VLIW architectures. */
448 cgen_lookup_insn (CGEN_CPU_DESC cd
,
449 const CGEN_INSN
*insn
,
450 CGEN_INSN_INT insn_int_value
,
451 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
452 unsigned char *insn_bytes_value
,
458 CGEN_INSN_INT base_insn
;
459 CGEN_EXTRACT_INFO ex_info
;
460 CGEN_EXTRACT_INFO
*info
;
465 buf
= (unsigned char *) alloca (cd
->max_insn_bitsize
/ 8);
466 cgen_put_insn_value (cd
, buf
, length
, insn_int_value
);
467 base_insn
= insn_int_value
;
472 ex_info
.dis_info
= NULL
;
473 ex_info
.insn_bytes
= insn_bytes_value
;
475 buf
= insn_bytes_value
;
476 base_insn
= cgen_get_insn_value (cd
, buf
, length
);
481 const CGEN_INSN_LIST
*insn_list
;
483 /* The instructions are stored in hash lists.
484 Pick the first one and keep trying until we find the right one. */
486 insn_list
= cgen_dis_lookup_insn (cd
, (char *) buf
, base_insn
);
487 while (insn_list
!= NULL
)
489 insn
= insn_list
->insn
;
492 /* FIXME: Ensure ALIAS attribute always has same index. */
493 || ! CGEN_INSN_ATTR_VALUE (insn
, CGEN_INSN_ALIAS
))
495 /* Basic bit mask must be correct. */
496 /* ??? May wish to allow target to defer this check until the
498 if ((base_insn
& CGEN_INSN_BASE_MASK (insn
))
499 == CGEN_INSN_BASE_VALUE (insn
))
501 /* ??? 0 is passed for `pc' */
502 int elength
= CGEN_EXTRACT_FN (cd
, insn
)
503 (cd
, insn
, info
, base_insn
, fields
, (bfd_vma
) 0);
507 if (length
!= 0 && length
!= elength
)
514 insn_list
= insn_list
->next
;
519 /* Sanity check: can't pass an alias insn if ! alias_p. */
521 && CGEN_INSN_ATTR_VALUE (insn
, CGEN_INSN_ALIAS
))
523 /* Sanity check: length must be correct. */
524 if (length
!= CGEN_INSN_BITSIZE (insn
))
527 /* ??? 0 is passed for `pc' */
528 length
= CGEN_EXTRACT_FN (cd
, insn
)
529 (cd
, insn
, info
, base_insn
, fields
, (bfd_vma
) 0);
530 /* Sanity check: must succeed.
531 Could relax this later if it ever proves useful. */
540 /* Fill in the operand instances used by INSN whose operands are FIELDS.
541 INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
545 cgen_get_insn_operands (CGEN_CPU_DESC cd
,
546 const CGEN_INSN
*insn
,
547 const CGEN_FIELDS
*fields
,
550 const CGEN_OPINST
*opinst
;
553 if (insn
->opinst
== NULL
)
555 for (i
= 0, opinst
= insn
->opinst
; opinst
->type
!= CGEN_OPINST_END
; ++i
, ++opinst
)
557 enum cgen_operand_type op_type
= opinst
->op_type
;
558 if (op_type
== CGEN_OPERAND_NIL
)
559 indices
[i
] = opinst
->index
;
561 indices
[i
] = (*cd
->get_int_operand
) (cd
, op_type
, fields
);
565 /* Cover function to cgen_get_insn_operands when either INSN or FIELDS
567 The INSN, INSN_*_VALUE, and LENGTH arguments are passed to
568 cgen_lookup_insn unchanged.
569 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
570 Otherwise INSN_BYTES_VALUE is used.
572 The result is the insn table entry or NULL if the instruction wasn't
576 cgen_lookup_get_insn_operands (CGEN_CPU_DESC cd
,
577 const CGEN_INSN
*insn
,
578 CGEN_INSN_INT insn_int_value
,
579 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
580 unsigned char *insn_bytes_value
,
585 /* Pass non-zero for ALIAS_P only if INSN != NULL.
586 If INSN == NULL, we want a real insn. */
587 insn
= cgen_lookup_insn (cd
, insn
, insn_int_value
, insn_bytes_value
,
588 length
, fields
, insn
!= NULL
);
592 cgen_get_insn_operands (cd
, insn
, fields
, indices
);
596 /* Allow signed overflow of instruction fields. */
598 cgen_set_signed_overflow_ok (CGEN_CPU_DESC cd
)
600 cd
->signed_overflow_ok_p
= 1;
603 /* Generate an error message if a signed field in an instruction overflows. */
605 cgen_clear_signed_overflow_ok (CGEN_CPU_DESC cd
)
607 cd
->signed_overflow_ok_p
= 0;
610 /* Will an error message be generated if a signed field in an instruction overflows ? */
612 cgen_signed_overflow_ok_p (CGEN_CPU_DESC cd
)
614 return cd
->signed_overflow_ok_p
;