Add Xtensa port
[external/binutils.git] / bfd / xtensa-isa.c
1 /* Configurable Xtensa ISA support.
2    Copyright 2003 Free Software Foundation, Inc.
3
4    This file is part of BFD, the Binary File Descriptor library.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <sys/types.h>
23 #include <string.h>
24
25 #include "xtensa-isa.h"
26 #include "xtensa-isa-internal.h"
27
28 xtensa_isa xtensa_default_isa = NULL;
29
30 static int
31 opname_lookup_compare (const void *v1, const void *v2)
32 {
33   opname_lookup_entry *e1 = (opname_lookup_entry *)v1;
34   opname_lookup_entry *e2 = (opname_lookup_entry *)v2;
35
36   return strcmp (e1->key, e2->key);
37 }
38
39
40 xtensa_isa
41 xtensa_isa_init (void)
42 {
43   xtensa_isa isa;
44   int mod;
45
46   isa = xtensa_load_isa (0);
47   if (isa == 0)
48     {
49       fprintf (stderr, "Failed to initialize Xtensa base ISA module\n");
50       return NULL;
51     }
52
53   for (mod = 1; xtensa_isa_modules[mod].get_num_opcodes_fn; mod++)
54     {
55       if (!xtensa_extend_isa (isa, mod))
56         {
57           fprintf (stderr, "Failed to initialize Xtensa TIE ISA module\n");
58           return NULL;
59         }
60     }
61
62   return isa;
63 }
64
65 /* ISA information.  */
66
67 static int
68 xtensa_check_isa_config (xtensa_isa_internal *isa,
69                          struct config_struct *config_table)
70 {
71   int i, j;
72
73   if (!config_table)
74     {
75       fprintf (stderr, "Error: Empty configuration table in ISA DLL\n");
76       return 0;
77     }
78
79   /* For the first module, save a pointer to the table and record the
80      specified endianness and availability of the density option.  */
81
82   if (isa->num_modules == 0)
83     {
84       int found_memory_order = 0;
85
86       isa->config = config_table;
87       isa->has_density = 1;  /* Default to have density option.  */
88
89       for (i = 0; config_table[i].param_name; i++)
90         {
91           if (!strcmp (config_table[i].param_name, "IsaMemoryOrder"))
92             {
93               isa->is_big_endian =
94                 (strcmp (config_table[i].param_value, "BigEndian") == 0);
95               found_memory_order = 1;
96             }
97           if (!strcmp (config_table[i].param_name, "IsaUseDensityInstruction"))
98             {
99               isa->has_density = atoi (config_table[i].param_value);
100             }
101         }
102       if (!found_memory_order)
103         {
104           fprintf (stderr, "Error: \"IsaMemoryOrder\" missing from "
105                    "configuration table in ISA DLL\n");
106           return 0;
107         }
108
109       return 1;
110     }
111
112   /* For subsequent modules, check that the parameters match.  Note: This
113      code is sufficient to handle the current model where there are never
114      more than 2 modules; we might at some point want to handle cases where
115      module N > 0 specifies some parameters not included in the base table,
116      and we would then add those to isa->config so that subsequent modules
117      would check against them. */
118
119   for (i = 0; config_table[i].param_name; i++)
120     {
121       for (j = 0; isa->config[j].param_name; j++)
122         {
123           if (!strcmp (config_table[i].param_name, isa->config[j].param_name))
124             {
125               int mismatch;
126               if (!strcmp (config_table[i].param_name, "IsaCoprocessorCount"))
127                 {
128                   /* Only require the coprocessor count to be <= the base.  */
129                   int tiecnt = atoi (config_table[i].param_value);
130                   int basecnt = atoi (isa->config[j].param_value);
131                   mismatch = (tiecnt > basecnt);
132                 }
133               else
134                 mismatch = strcmp (config_table[i].param_value,
135                                    isa->config[j].param_value);
136               if (mismatch)
137                 {
138 #define MISMATCH_MESSAGE \
139 "Error: Configuration mismatch in the \"%s\" parameter:\n\
140 the configuration used when the TIE file was compiled had a value of\n\
141 \"%s\", while the current configuration has a value of\n\
142 \"%s\". Please rerun the TIE compiler with a matching\n\
143 configuration.\n"
144                   fprintf (stderr, MISMATCH_MESSAGE,
145                            config_table[i].param_name,
146                            config_table[i].param_value,
147                            isa->config[j].param_value);
148                   return 0;
149                 }
150               break;
151             }
152         }
153     }
154
155   return 1;
156 }
157
158
159 static int
160 xtensa_add_isa (xtensa_isa_internal *isa, libisa_module_specifier libisa)
161 {
162   const int (*get_num_opcodes_fn) (void);
163   struct config_struct *(*get_config_table_fn) (void);
164   xtensa_opcode_internal **(*get_opcodes_fn) (void);
165   int (*decode_insn_fn) (const xtensa_insnbuf);
166   xtensa_opcode_internal **opcodes;
167   int opc, insn_size, prev_num_opcodes, new_num_opcodes, this_module;
168
169   get_num_opcodes_fn = xtensa_isa_modules[libisa].get_num_opcodes_fn;
170   get_opcodes_fn = xtensa_isa_modules[libisa].get_opcodes_fn;
171   decode_insn_fn = xtensa_isa_modules[libisa].decode_insn_fn;
172   get_config_table_fn = xtensa_isa_modules[libisa].get_config_table_fn;
173
174   if (!get_num_opcodes_fn || !get_opcodes_fn || !decode_insn_fn
175       || (!get_config_table_fn && isa->num_modules == 0))
176     return 0;
177
178   if (get_config_table_fn
179       && !xtensa_check_isa_config (isa, get_config_table_fn ()))
180     return 0;
181
182   prev_num_opcodes = isa->num_opcodes;
183   new_num_opcodes = (*get_num_opcodes_fn) ();
184
185   isa->num_opcodes += new_num_opcodes;
186   isa->opcode_table = (xtensa_opcode_internal **)
187     realloc (isa->opcode_table, isa->num_opcodes *
188              sizeof (xtensa_opcode_internal *));
189   isa->opname_lookup_table = (opname_lookup_entry *)
190     realloc (isa->opname_lookup_table, isa->num_opcodes *
191              sizeof (opname_lookup_entry));
192
193   opcodes = (*get_opcodes_fn) ();
194
195   insn_size = isa->insn_size;
196   for (opc = 0; opc < new_num_opcodes; opc++)
197     {
198       xtensa_opcode_internal *intopc = opcodes[opc];
199       int newopc = prev_num_opcodes + opc;
200       isa->opcode_table[newopc] = intopc;
201       isa->opname_lookup_table[newopc].key = intopc->name;
202       isa->opname_lookup_table[newopc].opcode = newopc;
203       if (intopc->length > insn_size)
204         insn_size = intopc->length;
205     }
206
207   isa->insn_size = insn_size;
208   isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
209                        sizeof (xtensa_insnbuf_word));
210
211   qsort (isa->opname_lookup_table, isa->num_opcodes,
212          sizeof (opname_lookup_entry), opname_lookup_compare);
213
214   /* Check for duplicate opcode names.  */
215   for (opc = 1; opc < isa->num_opcodes; opc++)
216     {
217       if (!opname_lookup_compare (&isa->opname_lookup_table[opc-1],
218                                   &isa->opname_lookup_table[opc]))
219         {
220           fprintf (stderr, "Error: Duplicate TIE opcode \"%s\"\n",
221                    isa->opname_lookup_table[opc].key);
222           return 0;
223         }
224     }
225
226   this_module = isa->num_modules;
227   isa->num_modules += 1;
228
229   isa->module_opcode_base = (int *) realloc (isa->module_opcode_base,
230                                              isa->num_modules * sizeof (int));
231   isa->module_decode_fn = (xtensa_insn_decode_fn *)
232     realloc (isa->module_decode_fn, isa->num_modules *
233              sizeof (xtensa_insn_decode_fn));
234
235   isa->module_opcode_base[this_module] = prev_num_opcodes;
236   isa->module_decode_fn[this_module] = decode_insn_fn;
237
238   xtensa_default_isa = isa;
239
240   return 1;     /* Library was successfully added.  */
241 }
242
243
244 xtensa_isa
245 xtensa_load_isa (libisa_module_specifier libisa)
246 {
247   xtensa_isa_internal *isa;
248
249   isa = (xtensa_isa_internal *) malloc (sizeof (xtensa_isa_internal));
250   memset (isa, 0, sizeof (xtensa_isa_internal));
251   if (!xtensa_add_isa (isa, libisa))
252     {
253       xtensa_isa_free (isa);
254       return NULL;
255     }
256   return (xtensa_isa) isa;
257 }
258
259
260 int
261 xtensa_extend_isa (xtensa_isa isa, libisa_module_specifier libisa)
262 {
263   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
264   return xtensa_add_isa (intisa, libisa);
265 }
266
267
268 void
269 xtensa_isa_free (xtensa_isa isa)
270 {
271   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
272   if (intisa->opcode_table)
273     free (intisa->opcode_table);
274   if (intisa->opname_lookup_table)
275     free (intisa->opname_lookup_table);
276   if (intisa->module_opcode_base)
277     free (intisa->module_opcode_base);
278   if (intisa->module_decode_fn)
279     free (intisa->module_decode_fn);
280   free (intisa);
281 }
282
283
284 int
285 xtensa_insn_maxlength (xtensa_isa isa)
286 {
287   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
288   return intisa->insn_size;
289 }
290
291
292 int
293 xtensa_insnbuf_size (xtensa_isa isa)
294 {
295   xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
296   return intisa->insnbuf_size;
297 }
298
299
300 int
301 xtensa_num_opcodes (xtensa_isa isa)
302 {
303   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
304   return intisa->num_opcodes;
305 }
306
307
308 xtensa_opcode
309 xtensa_opcode_lookup (xtensa_isa isa, const char *opname)
310 {
311   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
312   opname_lookup_entry entry, *result;
313
314   entry.key = opname;
315   result = bsearch (&entry, intisa->opname_lookup_table, intisa->num_opcodes,
316                     sizeof (opname_lookup_entry), opname_lookup_compare);
317   if (!result) return XTENSA_UNDEFINED;
318   return result->opcode;
319 }
320
321
322 xtensa_opcode
323 xtensa_decode_insn (xtensa_isa isa, const xtensa_insnbuf insn)
324 {
325   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
326   int n, opc;
327   for (n = 0; n < intisa->num_modules; n++) {
328     opc = (intisa->module_decode_fn[n]) (insn);
329     if (opc != XTENSA_UNDEFINED)
330       return intisa->module_opcode_base[n] + opc;
331   }
332   return XTENSA_UNDEFINED;
333 }
334
335
336 /* Opcode information.  */
337
338 void
339 xtensa_encode_insn (xtensa_isa isa, xtensa_opcode opc, xtensa_insnbuf insn)
340 {
341   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
342   xtensa_insnbuf template = intisa->opcode_table[opc]->template();
343   int len = intisa->opcode_table[opc]->length;
344   int n;
345
346   /* Convert length to 32-bit words.  */
347   len = (len + 3) / 4;
348
349   /* Copy the template.  */
350   for (n = 0; n < len; n++)
351     insn[n] = template[n];
352
353   /* Fill any unused buffer space with zeros.  */
354   for ( ; n < intisa->insnbuf_size; n++)
355     insn[n] = 0;
356 }
357
358
359 const char *
360 xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc)
361 {
362   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
363   return intisa->opcode_table[opc]->name;
364 }
365
366
367 int
368 xtensa_insn_length (xtensa_isa isa, xtensa_opcode opc)
369 {
370   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
371   return intisa->opcode_table[opc]->length;
372 }
373
374
375 int
376 xtensa_insn_length_from_first_byte (xtensa_isa isa, char first_byte)
377 {
378   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
379   int is_density = (first_byte & (intisa->is_big_endian ? 0x80 : 0x08)) != 0;
380   return (intisa->has_density && is_density ? 2 : 3);
381 }
382
383
384 int
385 xtensa_num_operands (xtensa_isa isa, xtensa_opcode opc)
386 {
387   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
388   return intisa->opcode_table[opc]->iclass->num_operands;
389 }
390
391
392 xtensa_operand
393 xtensa_get_operand (xtensa_isa isa, xtensa_opcode opc, int opnd)
394 {
395   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
396   xtensa_iclass_internal *iclass = intisa->opcode_table[opc]->iclass;
397   if (opnd >= iclass->num_operands)
398     return NULL;
399   return (xtensa_operand) iclass->operands[opnd];
400 }
401
402
403 /* Operand information.  */
404
405 char *
406 xtensa_operand_kind (xtensa_operand opnd)
407 {
408   xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
409   return intop->operand_kind;
410 }
411
412
413 char
414 xtensa_operand_inout (xtensa_operand opnd)
415 {
416   xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
417   return intop->inout;
418 }
419
420
421 uint32
422 xtensa_operand_get_field (xtensa_operand opnd, const xtensa_insnbuf insn)
423 {
424   xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
425   return (*intop->get_field) (insn);
426 }
427
428
429 void
430 xtensa_operand_set_field (xtensa_operand opnd, xtensa_insnbuf insn, uint32 val)
431 {
432   xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
433   return (*intop->set_field) (insn, val);
434 }
435
436
437 xtensa_encode_result
438 xtensa_operand_encode (xtensa_operand opnd, uint32 *valp)
439 {
440   xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
441   return (*intop->encode) (valp);
442 }
443
444
445 uint32
446 xtensa_operand_decode (xtensa_operand opnd, uint32 val)
447 {
448   xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
449   return (*intop->decode) (val);
450 }
451
452
453 int
454 xtensa_operand_isPCRelative (xtensa_operand opnd)
455 {
456   xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
457   return intop->isPCRelative;
458 }
459
460
461 uint32
462 xtensa_operand_do_reloc (xtensa_operand opnd, uint32 addr, uint32 pc)
463 {
464   xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
465   if (!intop->isPCRelative)
466     return addr;
467   return (*intop->do_reloc) (addr, pc);
468 }
469
470
471 uint32
472 xtensa_operand_undo_reloc (xtensa_operand opnd, uint32 offset, uint32 pc)
473 {
474   xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
475   if (!intop->isPCRelative)
476     return offset;
477   return (*intop->undo_reloc) (offset, pc);
478 }
479
480
481 /* Instruction buffers.  */
482
483 xtensa_insnbuf
484 xtensa_insnbuf_alloc (xtensa_isa isa)
485 {
486   return (xtensa_insnbuf) malloc (xtensa_insnbuf_size (isa) *
487                                   sizeof (xtensa_insnbuf_word));
488 }
489
490
491 void
492 xtensa_insnbuf_free (xtensa_insnbuf buf)
493 {
494   free( buf );
495 }
496
497
498 /* Given <byte_index>, the index of a byte in a xtensa_insnbuf, our
499    internal representation of a xtensa instruction word, return the index of
500    its word and the bit index of its low order byte in the xtensa_insnbuf.  */
501
502 static inline int
503 byte_to_word_index (int byte_index)
504 {
505   return byte_index / sizeof (xtensa_insnbuf_word);
506 }
507
508
509 static inline int
510 byte_to_bit_index (int byte_index)
511 {
512   return (byte_index & 0x3) * 8;
513 }
514
515
516 /* Copy an instruction in the 32 bit words pointed at by <insn> to characters
517    pointed at by <cp>.  This is more complicated than you might think because
518    we want 16 bit instructions in bytes 2,3 for big endian. This function
519    allows us to specify which byte in <insn> to start with and which way to
520    increment, allowing trivial implementation for both big and little endian.
521    And it seems to make pretty good code for both.  */
522
523 void
524 xtensa_insnbuf_to_chars (xtensa_isa isa, const xtensa_insnbuf insn, char *cp)
525 {
526   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
527   int insn_size = xtensa_insn_maxlength (intisa);
528   int fence_post, start, increment, i, byte_count;
529   xtensa_opcode opc;
530
531   if (intisa->is_big_endian)
532     {
533       start = insn_size - 1;
534       increment = -1;
535     }
536   else
537     {
538       start = 0;
539       increment = 1;
540     }
541
542   /* Find the opcode; do nothing if the buffer does not contain a valid
543      instruction since we need to know how many bytes to copy.  */
544   opc = xtensa_decode_insn (isa, insn);
545   if (opc == XTENSA_UNDEFINED)
546     return;
547
548   byte_count = xtensa_insn_length (isa, opc);
549   fence_post = start + (byte_count * increment);
550
551   for (i = start; i != fence_post; i += increment, ++cp)
552     {
553       int word_inx = byte_to_word_index (i);
554       int bit_inx = byte_to_bit_index (i);
555
556       *cp = (insn[word_inx] >> bit_inx) & 0xff;
557     }
558 }
559
560 /* Inward conversion from byte stream to xtensa_insnbuf.  See
561    xtensa_insnbuf_to_chars for a discussion of why this is
562    complicated by endianness.  */
563     
564 void
565 xtensa_insnbuf_from_chars (xtensa_isa isa, xtensa_insnbuf insn, const char* cp)
566 {
567   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
568   int insn_size = xtensa_insn_maxlength (intisa);
569   int fence_post, start, increment, i;
570
571   if (intisa->is_big_endian)
572     {
573       start = insn_size - 1;
574       increment = -1;
575     }
576   else
577     {
578       start = 0;
579       increment = 1;
580     }
581
582   fence_post = start + (insn_size * increment);
583   memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
584
585   for ( i = start; i != fence_post; i += increment, ++cp )
586     {
587       int word_inx = byte_to_word_index (i);
588       int bit_inx = byte_to_bit_index (i);
589
590       insn[word_inx] |= (*cp & 0xff) << bit_inx;
591     }
592 }
593