1 /* CGEN generic opcode support.
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2005, 2007, 2009
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. */
22 #include "alloca-conf.h"
26 #include "libiberty.h"
27 #include "safe-ctype.h"
30 #include "opcode/cgen.h"
32 static unsigned int hash_keyword_name
33 (const CGEN_KEYWORD
*, const char *, int);
34 static unsigned int hash_keyword_value
35 (const CGEN_KEYWORD
*, unsigned int);
36 static void build_keyword_hash_tables
39 /* Return number of hash table entries to use for N elements. */
40 #define KEYWORD_HASH_SIZE(n) ((n) <= 31 ? 17 : 31)
42 /* Look up *NAMEP in the keyword table KT.
43 The result is the keyword entry or NULL if not found. */
45 const CGEN_KEYWORD_ENTRY
*
46 cgen_keyword_lookup_name (CGEN_KEYWORD
*kt
, const char *name
)
48 const CGEN_KEYWORD_ENTRY
*ke
;
51 if (kt
->name_hash_table
== NULL
)
52 build_keyword_hash_tables (kt
);
54 ke
= kt
->name_hash_table
[hash_keyword_name (kt
, name
, 0)];
56 /* We do case insensitive comparisons.
57 If that ever becomes a problem, add an attribute that denotes
58 "do case sensitive comparisons". */
67 || (ISALPHA (*p
) && (TOLOWER (*p
) == TOLOWER (*n
)))))
77 return kt
->null_entry
;
81 /* Look up VALUE in the keyword table KT.
82 The result is the keyword entry or NULL if not found. */
84 const CGEN_KEYWORD_ENTRY
*
85 cgen_keyword_lookup_value (CGEN_KEYWORD
*kt
, int value
)
87 const CGEN_KEYWORD_ENTRY
*ke
;
89 if (kt
->name_hash_table
== NULL
)
90 build_keyword_hash_tables (kt
);
92 ke
= kt
->value_hash_table
[hash_keyword_value (kt
, value
)];
96 if (value
== ke
->value
)
104 /* Add an entry to a keyword table. */
107 cgen_keyword_add (CGEN_KEYWORD
*kt
, CGEN_KEYWORD_ENTRY
*ke
)
112 if (kt
->name_hash_table
== NULL
)
113 build_keyword_hash_tables (kt
);
115 hash
= hash_keyword_name (kt
, ke
->name
, 0);
116 ke
->next_name
= kt
->name_hash_table
[hash
];
117 kt
->name_hash_table
[hash
] = ke
;
119 hash
= hash_keyword_value (kt
, ke
->value
);
120 ke
->next_value
= kt
->value_hash_table
[hash
];
121 kt
->value_hash_table
[hash
] = ke
;
123 if (ke
->name
[0] == 0)
126 for (i
= 1; i
< strlen (ke
->name
); i
++)
127 if (! ISALNUM (ke
->name
[i
])
128 && ! strchr (kt
->nonalpha_chars
, ke
->name
[i
]))
130 size_t idx
= strlen (kt
->nonalpha_chars
);
132 /* If you hit this limit, please don't just
133 increase the size of the field, instead
134 look for a better algorithm. */
135 if (idx
>= sizeof (kt
->nonalpha_chars
) - 1)
137 kt
->nonalpha_chars
[idx
] = ke
->name
[i
];
138 kt
->nonalpha_chars
[idx
+1] = 0;
142 /* FIXME: Need function to return count of keywords. */
144 /* Initialize a keyword table search.
145 SPEC is a specification of what to search for.
146 A value of NULL means to find every keyword.
147 Currently NULL is the only acceptable value [further specification
149 The result is an opaque data item used to record the search status.
150 It is passed to each call to cgen_keyword_search_next. */
153 cgen_keyword_search_init (CGEN_KEYWORD
*kt
, const char *spec
)
155 CGEN_KEYWORD_SEARCH search
;
157 /* FIXME: Need to specify format of params. */
161 if (kt
->name_hash_table
== NULL
)
162 build_keyword_hash_tables (kt
);
166 search
.current_hash
= 0;
167 search
.current_entry
= NULL
;
171 /* Return the next keyword specified by SEARCH.
172 The result is the next entry or NULL if there are no more. */
174 const CGEN_KEYWORD_ENTRY
*
175 cgen_keyword_search_next (CGEN_KEYWORD_SEARCH
*search
)
177 /* Has search finished? */
178 if (search
->current_hash
== search
->table
->hash_table_size
)
181 /* Search in progress? */
182 if (search
->current_entry
!= NULL
183 /* Anything left on this hash chain? */
184 && search
->current_entry
->next_name
!= NULL
)
186 search
->current_entry
= search
->current_entry
->next_name
;
187 return search
->current_entry
;
190 /* Move to next hash chain [unless we haven't started yet]. */
191 if (search
->current_entry
!= NULL
)
192 ++search
->current_hash
;
194 while (search
->current_hash
< search
->table
->hash_table_size
)
196 search
->current_entry
= search
->table
->name_hash_table
[search
->current_hash
];
197 if (search
->current_entry
!= NULL
)
198 return search
->current_entry
;
199 ++search
->current_hash
;
205 /* Return first entry in hash chain for NAME.
206 If CASE_SENSITIVE_P is non-zero, return a case sensitive hash. */
209 hash_keyword_name (const CGEN_KEYWORD
*kt
,
211 int case_sensitive_p
)
215 if (case_sensitive_p
)
216 for (hash
= 0; *name
; ++name
)
217 hash
= (hash
* 97) + (unsigned char) *name
;
219 for (hash
= 0; *name
; ++name
)
220 hash
= (hash
* 97) + (unsigned char) TOLOWER (*name
);
221 return hash
% kt
->hash_table_size
;
224 /* Return first entry in hash chain for VALUE. */
227 hash_keyword_value (const CGEN_KEYWORD
*kt
, unsigned int value
)
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 (CGEN_KEYWORD
*kt
)
240 /* Use the number of compiled in entries as an estimate for the
241 typical sized table [not too many added at runtime]. */
242 unsigned int size
= KEYWORD_HASH_SIZE (kt
->num_init_entries
);
244 kt
->hash_table_size
= size
;
245 kt
->name_hash_table
= (CGEN_KEYWORD_ENTRY
**)
246 xmalloc (size
* sizeof (CGEN_KEYWORD_ENTRY
*));
247 memset (kt
->name_hash_table
, 0, size
* sizeof (CGEN_KEYWORD_ENTRY
*));
248 kt
->value_hash_table
= (CGEN_KEYWORD_ENTRY
**)
249 xmalloc (size
* sizeof (CGEN_KEYWORD_ENTRY
*));
250 memset (kt
->value_hash_table
, 0, size
* sizeof (CGEN_KEYWORD_ENTRY
*));
252 /* The table is scanned backwards as we want keywords appearing earlier to
253 be prefered over later ones. */
254 for (i
= kt
->num_init_entries
- 1; i
>= 0; --i
)
255 cgen_keyword_add (kt
, &kt
->init_entries
[i
]);
258 /* Hardware support. */
260 /* Lookup a hardware element by its name.
261 Returns NULL if NAME is not supported by the currently selected
264 const CGEN_HW_ENTRY
*
265 cgen_hw_lookup_by_name (CGEN_CPU_DESC cd
, const char *name
)
268 const CGEN_HW_ENTRY
**hw
= cd
->hw_table
.entries
;
270 for (i
= 0; i
< cd
->hw_table
.num_entries
; ++i
)
271 if (hw
[i
] && strcmp (name
, hw
[i
]->name
) == 0)
277 /* Lookup a hardware element by its number.
278 Hardware elements are enumerated, however it may be possible to add some
279 at runtime, thus HWNUM is not an enum type but rather an int.
280 Returns NULL if HWNUM is not supported by the currently selected mach. */
282 const CGEN_HW_ENTRY
*
283 cgen_hw_lookup_by_num (CGEN_CPU_DESC cd
, unsigned int hwnum
)
286 const CGEN_HW_ENTRY
**hw
= cd
->hw_table
.entries
;
288 /* ??? This can be speeded up. */
289 for (i
= 0; i
< cd
->hw_table
.num_entries
; ++i
)
290 if (hw
[i
] && hwnum
== hw
[i
]->type
)
296 /* Operand support. */
298 /* Lookup an operand by its name.
299 Returns NULL if NAME is not supported by the currently selected
303 cgen_operand_lookup_by_name (CGEN_CPU_DESC cd
, const char *name
)
306 const CGEN_OPERAND
**op
= cd
->operand_table
.entries
;
308 for (i
= 0; i
< cd
->operand_table
.num_entries
; ++i
)
309 if (op
[i
] && strcmp (name
, op
[i
]->name
) == 0)
315 /* Lookup an operand by its number.
316 Operands are enumerated, however it may be possible to add some
317 at runtime, thus OPNUM is not an enum type but rather an int.
318 Returns NULL if OPNUM is not supported by the currently selected
322 cgen_operand_lookup_by_num (CGEN_CPU_DESC cd
, int opnum
)
324 return cd
->operand_table
.entries
[opnum
];
327 /* Instruction support. */
329 /* Return number of instructions. This includes any added at runtime. */
332 cgen_insn_count (CGEN_CPU_DESC cd
)
334 int count
= cd
->insn_table
.num_init_entries
;
335 CGEN_INSN_LIST
*rt_insns
= cd
->insn_table
.new_entries
;
337 for ( ; rt_insns
!= NULL
; rt_insns
= rt_insns
->next
)
343 /* Return number of macro-instructions.
344 This includes any added at runtime. */
347 cgen_macro_insn_count (CGEN_CPU_DESC cd
)
349 int count
= cd
->macro_insn_table
.num_init_entries
;
350 CGEN_INSN_LIST
*rt_insns
= cd
->macro_insn_table
.new_entries
;
352 for ( ; rt_insns
!= NULL
; rt_insns
= rt_insns
->next
)
358 /* Cover function to read and properly byteswap an insn value. */
361 cgen_get_insn_value (CGEN_CPU_DESC cd
, unsigned char *buf
, int length
)
363 int big_p
= (cd
->insn_endian
== CGEN_ENDIAN_BIG
);
364 int insn_chunk_bitsize
= cd
->insn_chunk_bitsize
;
365 CGEN_INSN_INT value
= 0;
367 if (insn_chunk_bitsize
!= 0 && insn_chunk_bitsize
< length
)
369 /* We need to divide up the incoming value into insn_chunk_bitsize-length
370 segments, and endian-convert them, one at a time. */
373 /* Enforce divisibility. */
374 if ((length
% insn_chunk_bitsize
) != 0)
377 for (i
= 0; i
< length
; i
+= insn_chunk_bitsize
) /* NB: i == bits */
382 bit_index
= i
; /* NB: not dependent on endianness; opposite of cgen_put_insn_value! */
383 this_value
= bfd_get_bits (& buf
[bit_index
/ 8], insn_chunk_bitsize
, big_p
);
384 value
= (value
<< insn_chunk_bitsize
) | this_value
;
389 value
= bfd_get_bits (buf
, length
, cd
->insn_endian
== CGEN_ENDIAN_BIG
);
395 /* Cover function to store an insn value properly byteswapped. */
398 cgen_put_insn_value (CGEN_CPU_DESC cd
,
403 int big_p
= (cd
->insn_endian
== CGEN_ENDIAN_BIG
);
404 int insn_chunk_bitsize
= cd
->insn_chunk_bitsize
;
406 if (insn_chunk_bitsize
!= 0 && insn_chunk_bitsize
< length
)
408 /* We need to divide up the incoming value into insn_chunk_bitsize-length
409 segments, and endian-convert them, one at a time. */
412 /* Enforce divisibility. */
413 if ((length
% insn_chunk_bitsize
) != 0)
416 for (i
= 0; i
< length
; i
+= insn_chunk_bitsize
) /* NB: i == bits */
420 bit_index
= (length
- insn_chunk_bitsize
- i
); /* NB: not dependent on endianness! */
421 bfd_put_bits ((bfd_vma
) value
, & buf
[bit_index
/ 8], insn_chunk_bitsize
, big_p
);
422 value
>>= insn_chunk_bitsize
;
427 bfd_put_bits ((bfd_vma
) value
, buf
, length
, big_p
);
431 /* Look up instruction INSN_*_VALUE and extract its fields.
432 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
433 Otherwise INSN_BYTES_VALUE is used.
434 INSN, if non-null, is the insn table entry.
435 Otherwise INSN_*_VALUE is examined to compute it.
436 LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0.
437 0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
438 If INSN != NULL, LENGTH must be valid.
439 ALIAS_P is non-zero if alias insns are to be included in the search.
441 The result is a pointer to the insn table entry, or NULL if the instruction
442 wasn't recognized. */
444 /* ??? Will need to be revisited for VLIW architectures. */
447 cgen_lookup_insn (CGEN_CPU_DESC cd
,
448 const CGEN_INSN
*insn
,
449 CGEN_INSN_INT insn_int_value
,
450 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
451 unsigned char *insn_bytes_value
,
457 CGEN_INSN_INT base_insn
;
458 CGEN_EXTRACT_INFO ex_info
;
459 CGEN_EXTRACT_INFO
*info
;
464 buf
= (unsigned char *) alloca (cd
->max_insn_bitsize
/ 8);
465 cgen_put_insn_value (cd
, buf
, length
, insn_int_value
);
466 base_insn
= insn_int_value
;
471 ex_info
.dis_info
= NULL
;
472 ex_info
.insn_bytes
= insn_bytes_value
;
474 buf
= insn_bytes_value
;
475 base_insn
= cgen_get_insn_value (cd
, buf
, length
);
480 const CGEN_INSN_LIST
*insn_list
;
482 /* The instructions are stored in hash lists.
483 Pick the first one and keep trying until we find the right one. */
485 insn_list
= cgen_dis_lookup_insn (cd
, (char *) buf
, base_insn
);
486 while (insn_list
!= NULL
)
488 insn
= insn_list
->insn
;
491 /* FIXME: Ensure ALIAS attribute always has same index. */
492 || ! CGEN_INSN_ATTR_VALUE (insn
, CGEN_INSN_ALIAS
))
494 /* Basic bit mask must be correct. */
495 /* ??? May wish to allow target to defer this check until the
497 if ((base_insn
& CGEN_INSN_BASE_MASK (insn
))
498 == CGEN_INSN_BASE_VALUE (insn
))
500 /* ??? 0 is passed for `pc' */
501 int elength
= CGEN_EXTRACT_FN (cd
, insn
)
502 (cd
, insn
, info
, base_insn
, fields
, (bfd_vma
) 0);
506 if (length
!= 0 && length
!= elength
)
513 insn_list
= insn_list
->next
;
518 /* Sanity check: can't pass an alias insn if ! alias_p. */
520 && CGEN_INSN_ATTR_VALUE (insn
, CGEN_INSN_ALIAS
))
522 /* Sanity check: length must be correct. */
523 if (length
!= CGEN_INSN_BITSIZE (insn
))
526 /* ??? 0 is passed for `pc' */
527 length
= CGEN_EXTRACT_FN (cd
, insn
)
528 (cd
, insn
, info
, base_insn
, fields
, (bfd_vma
) 0);
529 /* Sanity check: must succeed.
530 Could relax this later if it ever proves useful. */
539 /* Fill in the operand instances used by INSN whose operands are FIELDS.
540 INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
544 cgen_get_insn_operands (CGEN_CPU_DESC cd
,
545 const CGEN_INSN
*insn
,
546 const CGEN_FIELDS
*fields
,
549 const CGEN_OPINST
*opinst
;
552 if (insn
->opinst
== NULL
)
554 for (i
= 0, opinst
= insn
->opinst
; opinst
->type
!= CGEN_OPINST_END
; ++i
, ++opinst
)
556 enum cgen_operand_type op_type
= opinst
->op_type
;
557 if (op_type
== CGEN_OPERAND_NIL
)
558 indices
[i
] = opinst
->index
;
560 indices
[i
] = (*cd
->get_int_operand
) (cd
, op_type
, fields
);
564 /* Cover function to cgen_get_insn_operands when either INSN or FIELDS
566 The INSN, INSN_*_VALUE, and LENGTH arguments are passed to
567 cgen_lookup_insn unchanged.
568 INSN_INT_VALUE is used if CGEN_INT_INSN_P.
569 Otherwise INSN_BYTES_VALUE is used.
571 The result is the insn table entry or NULL if the instruction wasn't
575 cgen_lookup_get_insn_operands (CGEN_CPU_DESC cd
,
576 const CGEN_INSN
*insn
,
577 CGEN_INSN_INT insn_int_value
,
578 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */
579 unsigned char *insn_bytes_value
,
584 /* Pass non-zero for ALIAS_P only if INSN != NULL.
585 If INSN == NULL, we want a real insn. */
586 insn
= cgen_lookup_insn (cd
, insn
, insn_int_value
, insn_bytes_value
,
587 length
, fields
, insn
!= NULL
);
591 cgen_get_insn_operands (cd
, insn
, fields
, indices
);
595 /* Allow signed overflow of instruction fields. */
597 cgen_set_signed_overflow_ok (CGEN_CPU_DESC cd
)
599 cd
->signed_overflow_ok_p
= 1;
602 /* Generate an error message if a signed field in an instruction overflows. */
604 cgen_clear_signed_overflow_ok (CGEN_CPU_DESC cd
)
606 cd
->signed_overflow_ok_p
= 0;
609 /* Will an error message be generated if a signed field in an instruction overflows ? */
611 cgen_signed_overflow_ok_p (CGEN_CPU_DESC cd
)
613 return cd
->signed_overflow_ok_p
;