Automatic date update in version.in
[binutils-gdb.git] / gas / config / tc-xgate.c
blob6a345c5a0a5ac1021f0a3d273e959e6aebe24366
1 /* tc-xgate.c -- Assembler code for Freescale XGATE
2 Copyright (C) 2010-2024 Free Software Foundation, Inc.
3 Contributed by Sean Keys <skeys@ipdatasys.com>
5 This file is part of GAS, the GNU Assembler.
7 GAS 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 3, or (at your option)
10 any later version.
12 GAS 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
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 #include "as.h"
23 #include "safe-ctype.h"
24 #include "subsegs.h"
25 #include "opcode/xgate.h"
26 #include "dwarf2dbg.h"
27 #include "elf/xgate.h"
29 const char comment_chars[] = ";!";
30 const char line_comment_chars[] = "#*";
31 const char line_separator_chars[] = "";
32 const char EXP_CHARS[] = "eE";
33 const char FLT_CHARS[] = "dD";
35 /* Max opcodes per opcode handle. */
36 #define MAX_OPCODES 0x05
38 #define SIXTEENTH_BIT 0x8000
39 #define N_BITS_IN_WORD 16
40 #define MAX_NUM_OPERANDS 3
42 /* #define STATE_CONDITIONAL_BRANCH (1) */
43 #define STATE_PC_RELATIVE (2)
44 #define REGISTER_P(ptr) (ptr == 'r')
45 #define INCREMENT 01
46 #define DECREMENT 02
47 #define MAXREGISTER 07
48 #define MINREGISTER 00
50 #define OPTION_MMCU 'm'
52 /* This macro has no side-effects. */
53 #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
55 /* Each unique opcode name has a handle. That handle may
56 contain pointers to opcodes with the same name but
57 different address modes. */
58 struct xgate_opcode_handle
60 int number_of_modes;
61 char *name;
62 struct xgate_opcode *opc0[MAX_OPCODES];
65 /* XGATE's registers all are 16-bit general purpose.
66 They are numbered according to the specifications. */
67 typedef enum register_id
69 REG_NONE = -1,
70 REG_R0 = 0,
71 REG_R1 = 1,
72 REG_R2 = 2,
73 REG_R3 = 3,
74 REG_R4 = 4,
75 REG_R5 = 5,
76 REG_R6 = 6,
77 REG_R7 = 7,
78 REG_PC = 8,
79 REG_CCR = 9
80 } register_id;
82 /* Operand Modifiers */
83 typedef enum op_modifiers
85 MOD_NONE = -1,
86 MOD_POSTINC = 1,
87 MOD_PREDEC = 2,
88 MOD_CONSTANT = 3,
89 MOD_LOAD_HIGH = 4,
90 MOD_LOAD_LOW = 5
91 }op_modifiers;
93 typedef struct s_operand
95 expressionS exp;
96 register_id reg;
97 op_modifiers mod;
98 } s_operand;
101 /* Forward declarations. */
102 static inline char *skip_whitespace (char *);
103 static void get_default_target (void);
104 static char *extract_word (char *, char *, int);
105 static struct xgate_opcode *xgate_find_match (struct xgate_opcode_handle *,
106 int, s_operand [], unsigned int);
107 static int cmp_opcode (struct xgate_opcode *, struct xgate_opcode *);
108 static void xgate_print_table (void);
109 static unsigned int xgate_get_operands (char *, s_operand []);
110 static register_id reg_name_search (char *);
111 static op_modifiers xgate_determine_modifiers (char **);
112 static void xgate_scan_operands (struct xgate_opcode *opcode, s_operand []);
113 static unsigned int xgate_parse_operand (struct xgate_opcode *, int *, int,
114 char **, s_operand);
116 static htab_t xgate_hash;
118 /* Previous opcode. */
119 static unsigned int prev = 0;
121 static unsigned char fixup_required = 0;
123 /* Used to enable clipping of 16 bit operands into 8 bit constraints. */
124 static unsigned char autoHiLo = 0;
126 static char oper_check;
127 static char flag_print_insn_syntax = 0;
128 static char flag_print_opcodes = 0;
130 static int current_architecture;
131 static const char *default_cpu;
133 /* ELF flags to set in the output file header. */
134 static int elf_flags = E_XGATE_F64;
136 /* This table describes how you change sizes for the various types of variable
137 size expressions. This version only supports two kinds. */
139 /* The fields are:
140 How far Forward this mode will reach.
141 How far Backward this mode will reach.
142 How many bytes this mode will add to the size of the frag.
143 Which mode to go to if the offset won't fit in this one. */
145 relax_typeS md_relax_table[] =
147 {1, 1, 0, 0}, /* First entries aren't used. */
148 {1, 1, 0, 0}, /* For no good reason except. */
149 {1, 1, 0, 0}, /* that the VAX doesn't either. */
150 {1, 1, 0, 0},
151 /* XGATE 9 and 10 bit pc rel todo complete and test */
152 /*{(511), (-512), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)},
153 {(1023), (-1024), 0, ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD)}, */
154 {0, 0, 0, 0}
157 /* This table describes all the machine specific pseudo-ops the assembler
158 has to support. The fields are: pseudo-op name without dot function to
159 call to execute this pseudo-op Integer arg to pass to the function. */
160 const pseudo_typeS md_pseudo_table[] =
162 /* The following pseudo-ops are supported for MRI compatibility. */
163 {0, 0, 0}
166 const char md_shortopts[] = "m:";
168 const struct option md_longopts[] =
170 #define OPTION_PRINT_INSN_SYNTAX (OPTION_MD_BASE + 0)
171 { "print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX },
173 #define OPTION_PRINT_OPCODES (OPTION_MD_BASE + 1)
174 { "print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES },
176 #define OPTION_GENERATE_EXAMPLE (OPTION_MD_BASE + 2)
177 { "generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE },
179 #define OPTION_MSHORT (OPTION_MD_BASE + 3)
180 { "mshort", no_argument, NULL, OPTION_MSHORT },
182 #define OPTION_MLONG (OPTION_MD_BASE + 4)
183 { "mlong", no_argument, NULL, OPTION_MLONG },
185 #define OPTION_MSHORT_DOUBLE (OPTION_MD_BASE + 5)
186 { "mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE },
188 #define OPTION_MLONG_DOUBLE (OPTION_MD_BASE + 6)
189 { "mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE },
191 { NULL, no_argument, NULL, 0 }
194 const size_t md_longopts_size = sizeof (md_longopts);
196 const char *
197 md_atof (int type, char *litP, int *sizeP)
199 return ieee_md_atof (type, litP, sizeP, true);
203 md_parse_option (int c, const char *arg)
205 switch (c)
207 case OPTION_MMCU:
208 if (strcasecmp (arg, "v1") == 0)
209 current_architecture = XGATE_V1;
210 else if (strcasecmp (arg, "v2") == 0)
211 current_architecture = XGATE_V2;
212 else if (strcasecmp (arg, "v3") == 0)
213 current_architecture = XGATE_V3;
214 else
215 as_bad (_("architecture variant invalid"));
216 break;
218 case OPTION_PRINT_INSN_SYNTAX:
219 flag_print_insn_syntax = 1;
220 break;
222 case OPTION_PRINT_OPCODES:
223 flag_print_opcodes = 1;
224 break;
226 case OPTION_GENERATE_EXAMPLE:
227 flag_print_opcodes = 2;
228 break;
230 case OPTION_MSHORT:
231 elf_flags &= ~E_XGATE_I32;
232 break;
234 case OPTION_MLONG:
235 elf_flags |= E_XGATE_I32;
236 break;
238 case OPTION_MSHORT_DOUBLE:
239 elf_flags &= ~E_XGATE_F64;
240 break;
242 case OPTION_MLONG_DOUBLE:
243 elf_flags |= E_XGATE_F64;
244 break;
246 default:
247 return 0;
249 return 1;
252 const char *
253 xgate_arch_format (void)
255 get_default_target ();
257 if (current_architecture & cpuxgate)
258 return "elf32-xgate";
260 return "error";
263 static void
264 get_default_target (void)
266 const bfd_target *target;
267 bfd abfd;
269 if (current_architecture != 0)
270 return;
272 default_cpu = "unknown";
273 target = bfd_find_target (0, &abfd);
275 if (target && target->name)
277 if (strcmp (target->name, "elf32-xgate") == 0)
279 current_architecture = cpuxgate;
280 default_cpu = "XGATE V1";
281 return;
284 as_bad (_("Default target `%s' is not supported."), target->name);
288 void
289 md_begin (void)
291 struct xgate_opcode *xgate_opcode_ptr = NULL;
292 struct xgate_opcode *xgate_op_table = NULL;
293 struct xgate_opcode_handle *op_handles = 0;
294 const char *prev_op_name = 0;
295 int handle_enum = 0;
296 int number_of_op_handles = 0;
297 int i, j = 0;
299 /* Create a local copy of our opcode table
300 including an extra line for NULL termination. */
301 xgate_op_table = XNEWVEC (struct xgate_opcode, xgate_num_opcodes);
303 memset (xgate_op_table, 0,
304 sizeof (struct xgate_opcode) * (xgate_num_opcodes));
306 for (xgate_opcode_ptr = (struct xgate_opcode*) xgate_opcodes, i = 0;
307 i < xgate_num_opcodes; i++)
308 xgate_op_table[i] = xgate_opcode_ptr[i];
310 qsort (xgate_op_table, xgate_num_opcodes, sizeof (struct xgate_opcode),
311 (int (*)(const void *, const void *)) cmp_opcode);
313 /* Calculate number of handles since this will be
314 smaller than the raw number of opcodes in the table. */
315 prev_op_name = "";
316 for (xgate_opcode_ptr = xgate_op_table, i = 0; i < xgate_num_opcodes;
317 xgate_opcode_ptr++, i++)
319 if (strcmp (prev_op_name, xgate_opcode_ptr->name))
320 number_of_op_handles++;
321 prev_op_name = xgate_opcode_ptr->name;
324 op_handles = XNEWVEC (struct xgate_opcode_handle, number_of_op_handles);
326 /* Insert unique opcode names into hash table, aliasing duplicates. */
327 xgate_hash = str_htab_create ();
329 prev_op_name = "";
330 for (xgate_opcode_ptr = xgate_op_table, i = 0, j = 0; i < xgate_num_opcodes;
331 i++, xgate_opcode_ptr++)
333 if (!strcmp (prev_op_name, xgate_opcode_ptr->name))
335 handle_enum++;
336 op_handles[j].opc0[handle_enum] = xgate_opcode_ptr;
338 else
340 handle_enum = 0;
341 if (i)
342 j++;
343 op_handles[j].name = xgate_opcode_ptr->name;
344 op_handles[j].opc0[0] = xgate_opcode_ptr;
345 str_hash_insert (xgate_hash, op_handles[j].name, &op_handles[j], 0);
347 op_handles[j].number_of_modes = handle_enum;
348 prev_op_name = op_handles[j].name;
351 if (flag_print_opcodes)
353 xgate_print_table ();
354 exit (EXIT_SUCCESS);
358 void
359 xgate_init_after_args (void)
363 void
364 md_show_usage (FILE * stream)
366 get_default_target ();
368 fprintf (stream,
369 _("\
370 Freescale XGATE co-processor options:\n\
371 -mshort use 16-bit int ABI (default)\n\
372 -mlong use 32-bit int ABI\n\
373 -mshort-double use 32-bit double ABI\n\
374 -mlong-double use 64-bit double ABI (default)\n\
375 --mxgate specify the processor variant [default %s]\n\
376 --print-insn-syntax print the syntax of instruction in case of error\n\
377 --print-opcodes print the list of instructions with syntax\n\
378 --generate-example generate an example of each instruction"),
379 default_cpu);
382 enum bfd_architecture
383 xgate_arch (void)
385 get_default_target ();
386 return bfd_arch_xgate;
390 xgate_mach (void)
392 return 0;
395 static void
396 xgate_print_syntax (char *name)
398 int i;
400 for (i = 0; i < xgate_num_opcodes; i++)
402 if (!strcmp (xgate_opcodes[i].name, name))
404 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IDR))
405 printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n",
406 xgate_opcodes[i].name);
407 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_INH))
408 printf ("\tFormat is %s\n", xgate_opcodes[i].name);
409 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_TRI))
410 printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes[i].name);
411 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_DYA))
412 printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes[i].name);
413 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM3))
414 printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes[i].name);
415 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM4))
416 printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes[i].name);
417 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM8))
418 printf ("\tFormat is %s\tRx, <8-bit value>\n",
419 xgate_opcodes[i].name);
420 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16))
421 printf ("\tFormat is %s\tRx, <16-bit value>\n",
422 xgate_opcodes[i].name);
423 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_C))
424 printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes[i].name);
425 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_C_R))
426 printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes[i].name);
427 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_P))
428 printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes[i].name);
429 if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16mLDW))
430 printf ("\tFormat is %s\tRx, <16-bit value>\n",
431 xgate_opcodes[i].name);
436 static void
437 xgate_print_table (void)
439 int i;
441 for (i = 0; i < xgate_num_opcodes; i++)
442 xgate_print_syntax (xgate_opcodes[i].name);
444 return;
447 const char *
448 xgate_listing_header (void)
450 if (current_architecture & cpuxgate)
451 return "XGATE GAS ";
453 return "ERROR MC9S12X GAS ";
456 symbolS *
457 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
459 return NULL;
462 /* GAS will call this function for each section at the end of the assembly,
463 to permit the CPU backend to adjust the alignment of a section. */
465 valueT
466 md_section_align (asection * seg, valueT addr)
468 int align = bfd_section_alignment (seg);
469 return ((addr + (1 << align) - 1) & -(1 << align));
472 void
473 md_assemble (char *input_line)
475 struct xgate_opcode *opcode = 0;
476 struct xgate_opcode *macro_opcode = 0;
477 struct xgate_opcode_handle *opcode_handle = 0;
478 /* Caller expects it to be returned as it was passed. */
479 char *saved_input_line = input_line;
480 char op_name[9] = { 0 };
481 unsigned int operandCount = 0;
482 char *p = 0;
484 s_operand new_operands[MAX_NUM_OPERANDS];
486 fixup_required = 0;
487 oper_check = 0; /* set error flags */
488 input_line = extract_word (input_line, op_name, sizeof (op_name));
490 /* Check to make sure we are not reading a bogus line. */
491 if (!op_name[0])
492 as_bad (_("opcode missing or not found on input line"));
494 opcode_handle = (struct xgate_opcode_handle *) str_hash_find (xgate_hash,
495 op_name);
496 if (!opcode_handle)
497 as_bad (_("opcode %s not found in opcode hash table"), op_name);
498 else
500 /* Parse operands so we can find the proper opcode bin. */
502 operandCount = xgate_get_operands (input_line, new_operands);
504 opcode = xgate_find_match (opcode_handle, opcode_handle->number_of_modes,
505 new_operands, operandCount);
507 if (!opcode)
509 as_bad (_("matching operands to opcode"));
510 xgate_print_syntax (opcode_handle->opc0[0]->name);
512 else if (opcode->size == 2)
514 /* Size is one word - assemble that native insn. */
515 xgate_scan_operands (opcode, new_operands);
517 else
519 /* Insn is a simplified instruction - expand it out. */
520 autoHiLo = 1;
521 unsigned int i;
523 /* skip past our ';' separator. */
524 for (i = strlen (opcode->constraints), p = opcode->constraints; i > 0;
525 i--, p++)
527 if (*p == ';')
529 p++;
530 break;
533 input_line = skip_whitespace (input_line);
534 char *macro_inline = input_line;
536 /* Loop though the macro's opcode list and apply operands to
537 each real opcode. */
538 for (i = 0; *p && i < (opcode->size / 2); i++)
540 /* Loop though macro operand list. */
541 input_line = macro_inline; /* Rewind. */
542 p = extract_word (p, op_name, 10);
544 opcode_handle
545 = (struct xgate_opcode_handle *) str_hash_find (xgate_hash,
546 op_name);
547 if (!opcode_handle)
549 as_bad (_(": processing macro, real opcode handle"
550 " not found in hash"));
551 break;
553 else
555 operandCount = xgate_get_operands (input_line, new_operands);
556 macro_opcode = xgate_find_match (opcode_handle,
557 opcode_handle->number_of_modes, new_operands,
558 operandCount);
559 xgate_scan_operands (macro_opcode, new_operands);
564 autoHiLo = 0;
565 input_line = saved_input_line;
568 /* Force truly undefined symbols to their maximum size, and generally set up
569 the frag list to be relaxed. */
572 md_estimate_size_before_relax (fragS *fragp, asection *seg)
574 /* If symbol is undefined or located in a different section,
575 select the largest supported relocation. */
576 relax_substateT subtype;
577 relax_substateT rlx_state[] = { 0, 2 };
579 for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
581 if (fragp->fr_subtype == rlx_state[subtype]
582 && (!S_IS_DEFINED (fragp->fr_symbol)
583 || seg != S_GET_SEGMENT (fragp->fr_symbol)))
585 fragp->fr_subtype = rlx_state[subtype + 1];
586 break;
590 if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
591 abort ();
593 return md_relax_table[fragp->fr_subtype].rlx_length;
597 /* Relocation, relaxation and frag conversions. */
599 /* PC-relative offsets are relative to the start of the
600 next instruction. That is, the address of the offset, plus its
601 size, since the offset is always the last part of the insn. */
603 long
604 md_pcrel_from (fixS * fixP)
606 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
609 /* If while processing a fixup, a reloc really needs to be created
610 then it is done here. */
612 arelent *
613 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
615 arelent * reloc;
617 reloc = XNEW (arelent);
618 reloc->sym_ptr_ptr = XNEW (asymbol *);
619 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
620 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
622 if (fixp->fx_r_type == 0)
623 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
624 else
625 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
627 if (reloc->howto == (reloc_howto_type *) NULL)
629 as_bad_where (fixp->fx_file, fixp->fx_line, _
630 ("Relocation %d is not supported by object file format."),
631 (int) fixp->fx_r_type);
632 return NULL;
635 /* Since we use Rel instead of Rela, encode the vtable entry to be
636 used in the relocation's section offset. */
637 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
638 reloc->address = fixp->fx_offset;
639 reloc->addend = 0;
640 return reloc;
643 /* Patch the instruction with the resolved operand. Elf relocation
644 info will also be generated to take care of linker/loader fixups.
645 The XGATE addresses only 16-bit addresses.The BFD_RELOC_32 is necessary
646 for the support of --gstabs. */
648 void
649 md_apply_fix (fixS * fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
651 char *where;
652 long value = *valP;
653 int opcode = 0;
654 ldiv_t result;
656 /* If the fixup is done mark it done so no further symbol resolution
657 will take place. */
658 if (fixP->fx_addsy == (symbolS *) NULL)
659 fixP->fx_done = 1;
661 /* We don't actually support subtracting a symbol. */
662 if (fixP->fx_subsy != (symbolS *) NULL)
663 as_bad_subtract (fixP);
665 where = fixP->fx_frag->fr_literal + fixP->fx_where;
666 opcode = bfd_getl16 (where);
667 int mask = 0;
669 switch (fixP->fx_r_type)
671 case BFD_RELOC_XGATE_PCREL_9:
672 if (value < -512 || value > 511)
673 as_bad_where (fixP->fx_file, fixP->fx_line,
674 _("Value %ld too large for 9-bit PC-relative branch."),
675 value);
676 result = ldiv (value, 2); /* from bytes to words */
677 value = result.quot;
678 if (result.rem)
679 as_bad_where (fixP->fx_file, fixP->fx_line, _
680 ("Value %ld not aligned by 2 for 9-bit"
681 " PC-relative branch."), value);
682 /* Clip into 8-bit field.
683 FIXME I'm sure there is a more proper place for this. */
684 mask = 0x1FF;
685 value &= mask;
686 number_to_chars_bigendian (where, (opcode | value), 2);
687 break;
688 case BFD_RELOC_XGATE_PCREL_10:
689 if (value < -1024 || value > 1023)
690 as_bad_where (fixP->fx_file, fixP->fx_line,
691 _("Value %ld too large for 10-bit PC-relative branch."),
692 value);
693 result = ldiv (value, 2); /* from bytes to words */
694 value = result.quot;
695 if (result.rem)
696 as_bad_where (fixP->fx_file, fixP->fx_line, _
697 ("Value %ld not aligned by 2 for 10-bit"
698 " PC-relative branch."), value);
699 /* Clip into 9-bit field.
700 FIXME I'm sure there is a more proper place for this. */
701 mask = 0x3FF;
702 value &= mask;
703 number_to_chars_bigendian (where, (opcode | value), 2);
704 break;
705 case BFD_RELOC_XGATE_IMM8_HI:
706 if (value < -65537 || value > 65535)
707 as_bad_where (fixP->fx_file, fixP->fx_line,
708 _("Value out of 16-bit range."));
709 value >>= 8;
710 value &= 0x00ff;
711 bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
712 break;
713 case BFD_RELOC_XGATE_24:
714 case BFD_RELOC_XGATE_IMM8_LO:
715 if (value < -65537 || value > 65535)
716 as_bad_where (fixP->fx_file, fixP->fx_line,
717 _("Value out of 16-bit range."));
718 value &= 0x00ff;
719 bfd_putb16 ((bfd_vma) value | opcode, (void *) where);
720 break;
721 case BFD_RELOC_XGATE_IMM3:
722 if (value < 0 || value > 7)
723 as_bad_where (fixP->fx_file, fixP->fx_line,
724 _("Value out of 3-bit range."));
725 value <<= 8; /* make big endian */
726 number_to_chars_bigendian (where, (opcode | value), 2);
727 break;
728 case BFD_RELOC_XGATE_IMM4:
729 if (value < 0 || value > 15)
730 as_bad_where (fixP->fx_file, fixP->fx_line,
731 _("Value out of 4-bit range."));
732 value <<= 4; /* align the operand bits */
733 number_to_chars_bigendian (where, (opcode | value), 2);
734 break;
735 case BFD_RELOC_XGATE_IMM5:
736 if (value < 0 || value > 31)
737 as_bad_where (fixP->fx_file, fixP->fx_line,
738 _("Value out of 5-bit range."));
739 value <<= 5; /* align the operand bits */
740 number_to_chars_bigendian (where, (opcode | value), 2);
741 break;
742 case BFD_RELOC_8:
743 ((bfd_byte *) where)[0] = (bfd_byte) value;
744 break;
745 case BFD_RELOC_32:
746 bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
747 break;
748 case BFD_RELOC_16:
749 bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
750 break;
751 default:
752 as_fatal (_("Line %d: unknown relocation type: 0x%x."), fixP->fx_line,
753 fixP->fx_r_type);
754 break;
758 /* See whether we need to force a relocation into the output file. */
761 tc_xgate_force_relocation (fixS * fixP)
763 if (fixP->fx_r_type == BFD_RELOC_XGATE_RL_GROUP)
764 return 1;
765 return generic_force_reloc (fixP);
768 /* Here we decide which fixups can be adjusted to make them relative
769 to the beginning of the section instead of the symbol. Basically
770 we need to make sure that the linker relaxation is done
771 correctly, so in some cases we force the original symbol to be
772 used. */
775 tc_xgate_fix_adjustable (fixS * fixP)
777 switch (fixP->fx_r_type)
779 /* For the linker relaxation to work correctly, these relocs
780 need to be on the symbol itself. */
781 case BFD_RELOC_16:
782 case BFD_RELOC_XGATE_RL_JUMP:
783 case BFD_RELOC_XGATE_RL_GROUP:
784 case BFD_RELOC_VTABLE_INHERIT:
785 case BFD_RELOC_VTABLE_ENTRY:
786 case BFD_RELOC_32:
787 return 0;
788 default:
789 return 1;
793 void
794 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
795 asection * sec ATTRIBUTE_UNUSED,
796 fragS * fragP ATTRIBUTE_UNUSED)
798 as_bad (("md_convert_frag not implemented yet"));
799 abort ();
802 /* Set the ELF specific flags. */
804 void
805 xgate_elf_final_processing (void)
807 elf_flags |= EF_XGATE_MACH;
808 elf_elfheader (stdoutput)->e_flags &= ~EF_XGATE_ABI;
809 elf_elfheader (stdoutput)->e_flags |= elf_flags;
812 static inline char *
813 skip_whitespace (char *s)
815 while (*s == ' ' || *s == '\t' || *s == '(' || *s == ')')
816 s++;
818 return s;
821 /* Extract a word (continuous alpha-numeric chars) from the input line. */
823 static char *
824 extract_word (char *from, char *to, int limit)
826 char *op_end;
827 int size = 0;
829 /* Drop leading whitespace. */
830 from = skip_whitespace (from);
831 *to = 0;
832 /* Find the op code end. */
833 for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
835 to[size++] = *op_end++;
836 if (size + 1 >= limit)
837 break;
839 to[size] = 0;
840 return op_end;
843 static char *
844 xgate_new_instruction (int size)
846 char *f = frag_more (size);
847 dwarf2_emit_insn (size);
848 return f;
851 static unsigned short
852 xgate_apply_operand (unsigned short new_mask,
853 unsigned short *availiable_mask_bits,
854 unsigned short mask,
855 unsigned char n_bits)
857 unsigned short n_shifts;
858 unsigned int n_drop_bits;
860 /* Shift until you find an available operand bit "1" and record
861 the number of shifts. */
862 for (n_shifts = 0;
863 !(*availiable_mask_bits & SIXTEENTH_BIT) && n_shifts < 16;
864 n_shifts++)
865 *availiable_mask_bits <<= 1;
867 /* Shift for the number of bits your operand requires while bits
868 are available. */
869 for (n_drop_bits = n_bits;
870 n_drop_bits && (*availiable_mask_bits & SIXTEENTH_BIT);
871 --n_drop_bits)
872 *availiable_mask_bits <<= 1;
874 if (n_drop_bits)
875 as_bad (_(":operand has too many bits"));
876 *availiable_mask_bits >>= n_shifts + n_bits;
877 if ((n_drop_bits == 0) && (*availiable_mask_bits == 0))
879 oper_check = 1; /* flag operand check as good */
881 new_mask <<= N_BITS_IN_WORD - (n_shifts + n_bits);
882 mask |= new_mask;
883 return mask;
886 /* Parse ordinary expression. */
888 static char *
889 xgate_parse_exp (char *s, expressionS * op)
891 input_line_pointer = s;
893 expression (op);
894 if (op->X_op == O_absent)
895 as_bad (_("missing operand"));
896 else
897 resolve_register (op);
898 return input_line_pointer;
901 static int
902 cmp_opcode (struct xgate_opcode *op1, struct xgate_opcode *op2)
904 return strcmp (op1->name, op2->name);
907 static struct xgate_opcode *
908 xgate_find_match (struct xgate_opcode_handle *opcode_handle,
909 int numberOfModes, s_operand oprs[], unsigned int operandCount)
911 int i;
913 if (numberOfModes == 0)
914 return opcode_handle->opc0[0];
916 for (i = 0; i <= numberOfModes; i++)
918 switch (operandCount)
920 case 0:
921 if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_INH))
922 return opcode_handle->opc0[i];
923 break;
924 case 1:
925 if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
927 if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_MON))
928 return opcode_handle->opc0[i];
929 if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_DYA_MON))
930 return opcode_handle->opc0[i];
932 if (oprs[0].reg == REG_NONE)
933 if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM3))
934 return opcode_handle->opc0[i];
935 break;
936 case 2:
937 if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
939 if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7)
941 if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_DYA))
942 return opcode_handle->opc0[i];
944 if (oprs[1].reg == REG_CCR)
945 if (!strcmp (opcode_handle->opc0[i]->constraints,
946 XGATE_OP_MON_R_C))
947 return opcode_handle->opc0[i];
948 if (oprs[1].reg == REG_PC)
949 if (!strcmp (opcode_handle->opc0[i]->constraints,
950 XGATE_OP_MON_R_P))
951 return opcode_handle->opc0[i];
952 if (oprs[1].reg == REG_NONE)
953 if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM16)
954 || !strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM8)
955 || !strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM4)
956 || !strcmp (opcode_handle->opc0[i]->constraints,
957 XGATE_OP_IMM16mADD)
958 || !strcmp (opcode_handle->opc0[i]->constraints,
959 XGATE_OP_IMM16mAND)
960 || !strcmp (opcode_handle->opc0[i]->constraints,
961 XGATE_OP_IMM16mCPC)
962 || !strcmp (opcode_handle->opc0[i]->constraints,
963 XGATE_OP_IMM16mSUB)
964 || !strcmp (opcode_handle->opc0[i]->constraints,
965 XGATE_OP_IMM16mLDW))
966 return opcode_handle->opc0[i];
968 if (oprs[0].reg == REG_CCR)
969 if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_MON_C_R))
970 return opcode_handle->opc0[i];
971 break;
972 case 3:
973 if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
975 if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7)
977 if (oprs[2].reg >= REG_R0 && oprs[2].reg <= REG_R7)
979 if (!strcmp (opcode_handle->opc0[i]->constraints,
980 XGATE_OP_IDR)
981 || !strcmp (opcode_handle->opc0[i]->constraints,
982 XGATE_OP_TRI))
983 return opcode_handle->opc0[i];
986 if (oprs[2].reg == REG_NONE)
987 if (!strcmp (opcode_handle->opc0[i]->constraints,
988 XGATE_OP_IDO5))
989 return opcode_handle->opc0[i];
992 break;
993 default:
994 as_bad (_("unknown operand count"));
995 break;
998 return NULL ;
1001 /* Because we are dealing with two different core that view the system
1002 memory with different offsets, we must differentiate what core a
1003 symbol belongs to, in order for the linker to cross-link. */
1006 xgate_frob_symbol (symbolS *sym)
1008 asymbol *bfdsym;
1009 elf_symbol_type *elfsym;
1011 bfdsym = symbol_get_bfdsym (sym);
1012 elfsym = elf_symbol_from (bfdsym);
1014 gas_assert (elfsym);
1016 /* Mark the symbol as being *from XGATE */
1017 elfsym->internal_elf_sym.st_target_internal = 1;
1019 return 0;
1022 static unsigned int
1023 xgate_get_operands (char *line, s_operand oprs[])
1025 int num_operands;
1027 /* If there are no operands, then it must be inherent. */
1028 if (*line == 0 || *line == '\n' || *line == '\r')
1029 return 0;
1031 for (num_operands = 0; strlen (line) && (num_operands < MAX_NUM_OPERANDS);
1032 num_operands++)
1034 line = skip_whitespace (line);
1035 if (*line == '#')
1036 line++;
1038 oprs[num_operands].mod = xgate_determine_modifiers (&line);
1040 if ((oprs[num_operands].reg = reg_name_search (line)) == REG_NONE)
1041 line = xgate_parse_exp (line, &oprs[num_operands].exp);
1043 /* skip to next operand */
1044 while (*line != 0)
1046 if (*line == ',')
1048 line++;
1049 break;
1051 line++;
1054 if (num_operands > MAX_NUM_OPERANDS)
1055 return 0;
1056 return num_operands;
1059 /* reg_name_search() finds the register number given its name.
1060 Returns the register number or REG_NONE on failure. */
1062 static register_id
1063 reg_name_search (char *name)
1065 if (strncasecmp (name, "r0", 2) == 0)
1066 return REG_R0;
1067 if (strncasecmp (name, "r1", 2) == 0)
1068 return REG_R1;
1069 if (strncasecmp (name, "r2", 2) == 0)
1070 return REG_R2;
1071 if (strncasecmp (name, "r3", 2) == 0)
1072 return REG_R3;
1073 if (strncasecmp (name, "r4", 2) == 0)
1074 return REG_R4;
1075 if (strncasecmp (name, "r5", 2) == 0)
1076 return REG_R5;
1077 if (strncasecmp (name, "r6", 2) == 0)
1078 return REG_R6;
1079 if (strncasecmp (name, "r7", 2) == 0)
1080 return REG_R7;
1081 if (strncasecmp (name, "pc", 2) == 0)
1082 return REG_PC;
1083 if (strncasecmp (name, "ccr", 3) == 0)
1084 return REG_CCR;
1085 return REG_NONE;
1088 /* Parse operand modifiers such as inc/dec/hi/low. */
1090 static op_modifiers
1091 xgate_determine_modifiers (char **line)
1093 char *local_line = line[0];
1095 if (strncasecmp (local_line, "%hi", 3) == 0)
1097 *line += 3;
1098 return MOD_LOAD_HIGH;
1100 if (strncasecmp (local_line, "%lo", 3) == 0)
1102 *line += 3;
1103 return MOD_LOAD_LOW;
1105 if (*(local_line + 2) == '+')
1106 return MOD_POSTINC;
1107 if (strncasecmp (local_line, "-r", 2) == 0)
1109 *line += 1;
1110 return MOD_PREDEC;
1112 return MOD_NONE;
1115 /* Parse instruction operands. */
1117 static void
1118 xgate_scan_operands (struct xgate_opcode *opcode, s_operand oprs[])
1120 char *frag = xgate_new_instruction (opcode->size);
1121 int where = frag - frag_now->fr_literal;
1122 char *op = opcode->constraints;
1123 unsigned int bin = (int) opcode->bin_opcode;
1124 unsigned short oper_mask = 0;
1125 int operand_bit_length = 0;
1126 unsigned int operand = 0;
1127 char n_operand_bits = 0;
1128 char first_operand_equals_second = 0;
1129 int i = 0;
1130 char c = 0;
1132 /* Generate available operand bits mask. */
1133 for (i = 0; (c = opcode->format[i]); i++)
1135 if (ISDIGIT (c) || (c == 's'))
1137 oper_mask <<= 1;
1139 else
1141 oper_mask <<= 1;
1142 oper_mask += 1;
1143 n_operand_bits++;
1147 /* Parse first operand. */
1148 if (*op)
1150 if (*op == '=')
1152 first_operand_equals_second = 1;
1153 ++op;
1155 operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1156 &op, oprs[0]);
1157 ++op;
1158 bin = xgate_apply_operand (operand, &oper_mask, bin, operand_bit_length);
1160 if (first_operand_equals_second)
1161 bin = xgate_apply_operand (operand, &oper_mask, bin,
1162 operand_bit_length);
1163 /* Parse second operand. */
1164 if (*op)
1166 if (*op == ',')
1167 ++op;
1168 if (first_operand_equals_second)
1170 bin = xgate_apply_operand (operand, &oper_mask, bin,
1171 operand_bit_length);
1172 ++op;
1174 else
1176 operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1177 &op, oprs[1]);
1178 bin = xgate_apply_operand (operand, &oper_mask, bin,
1179 operand_bit_length);
1180 ++op;
1183 /* Parse the third register. */
1184 if (*op)
1186 if (*op == ',')
1187 ++op;
1188 operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1189 &op, oprs[2]);
1190 bin = xgate_apply_operand (operand, &oper_mask, bin,
1191 operand_bit_length);
1194 if (opcode->size == 2 && fixup_required)
1196 bfd_putl16 (bin, frag);
1198 else if ( !strcmp (opcode->constraints, XGATE_OP_REL9)
1199 || !strcmp (opcode->constraints, XGATE_OP_REL10))
1201 /* Write our data to a frag for further processing. */
1202 bfd_putl16 (opcode->bin_opcode, frag);
1204 else
1206 /* Apply operand mask(s)to bin opcode and write the output. */
1207 /* Since we are done write this frag in xgate BE format. */
1208 number_to_chars_bigendian (frag, bin, opcode->size);
1210 prev = bin;
1211 return;
1214 static unsigned int
1215 xgate_parse_operand (struct xgate_opcode *opcode,
1216 int *bit_width,
1217 int where,
1218 char **op_con,
1219 s_operand operand)
1221 char *op_constraint = *op_con;
1222 unsigned int op_mask = 0;
1223 unsigned int pp_fix = 0;
1224 unsigned short max_size = 0;
1225 int i;
1227 *bit_width = 0;
1228 /* Reset. */
1230 switch (*op_constraint)
1232 case '+': /* Indexed register operand +/- or plain r. */
1233 /* Default to neither inc or dec. */
1234 pp_fix = 0;
1235 *bit_width = 5;
1237 if (operand.reg == REG_NONE)
1238 as_bad (_(": expected register name r0-r7 ") );
1239 op_mask = operand.reg;
1240 if (operand.mod == MOD_POSTINC)
1241 pp_fix = INCREMENT;
1242 if (operand.mod == MOD_PREDEC)
1243 pp_fix = DECREMENT;
1244 op_mask <<= 2;
1245 op_mask |= pp_fix;
1246 break;
1248 case 'r': /* Register operand. */
1249 if (operand.reg == REG_NONE)
1250 as_bad (_(": expected register name r0-r7 "));
1252 *bit_width = 3;
1254 op_mask = operand.reg;
1255 break;
1257 case 'i': /* Immediate value or expression expected. */
1258 /* Advance the original format pointer. */
1259 (*op_con)++;
1260 op_constraint++;
1261 if (ISDIGIT (*op_constraint))
1262 *bit_width = (int) *op_constraint - '0';
1263 else if (*op_constraint == 'a')
1264 *bit_width = 0x0A;
1265 else if (*op_constraint == 'f')
1266 *bit_width = 0x0F;
1268 /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
1269 if (operand.exp.X_op == O_constant)
1271 op_mask = operand.exp.X_add_number;
1272 if (((opcode->name[strlen (opcode->name) - 1] == 'l') && autoHiLo)
1273 || operand.mod == MOD_LOAD_LOW)
1274 op_mask &= 0x00FF;
1275 else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
1276 && autoHiLo) || operand.mod == MOD_LOAD_HIGH)
1277 op_mask >>= 8;
1279 /* Make sure it fits. */
1280 for (i = *bit_width; i; i--)
1282 max_size <<= 1;
1283 max_size += 1;
1285 if (op_mask > max_size)
1286 as_bad (_(":operand value(%d) too big for constraint"), op_mask);
1288 else
1290 /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24
1291 TODO fix. */
1292 fixup_required = 1;
1293 if (*op_constraint == '8')
1295 if (((opcode->name[strlen (opcode->name) - 1] == 'l')
1296 && autoHiLo) || operand.mod == MOD_LOAD_LOW)
1297 fix_new_exp (frag_now, where, 2, &operand.exp, false,
1298 BFD_RELOC_XGATE_24);
1299 else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
1300 && autoHiLo) || operand.mod == MOD_LOAD_HIGH )
1301 fix_new_exp (frag_now, where, 2, &operand.exp, false,
1302 BFD_RELOC_XGATE_IMM8_HI);
1303 else
1304 as_bad (_("you must use a hi/lo directive or 16-bit macro "
1305 "to load a 16-bit value."));
1307 else if (*op_constraint == '5')
1308 fix_new_exp (frag_now, where, 2, &operand.exp, false,
1309 BFD_RELOC_XGATE_IMM5);
1310 else if (*op_constraint == '4')
1311 fix_new_exp (frag_now, where, 2, &operand.exp, false,
1312 BFD_RELOC_XGATE_IMM4);
1313 else if (*op_constraint == '3')
1314 fix_new_exp (frag_now, where, 2, &operand.exp, false,
1315 BFD_RELOC_XGATE_IMM3);
1316 else
1317 as_bad (_(":unknown relocation constraint size"));
1319 break;
1321 case 'c': /* CCR register expected. */
1322 *bit_width = 0;
1323 if (operand.reg != REG_CCR)
1324 as_bad (_(": expected register name ccr "));
1325 break;
1327 case 'p': /* PC register expected. */
1328 *bit_width = 0;
1329 if (operand.reg != REG_PC)
1330 as_bad (_(": expected register name pc "));
1331 break;
1333 case 'b': /* Branch expected. */
1334 (*op_con)++;
1335 op_constraint++;
1337 if (operand.exp.X_op != O_register)
1339 if (*op_constraint == '9')
1340 fix_new_exp (frag_now, where, 2, &operand.exp, true,
1341 BFD_RELOC_XGATE_PCREL_9);
1342 else if (*op_constraint == 'a')
1343 fix_new_exp (frag_now, where, 2, &operand.exp, true,
1344 BFD_RELOC_XGATE_PCREL_10);
1346 else
1347 as_fatal (_("Operand `%x' not recognized in fixup8."),
1348 operand.exp.X_op);
1349 break;
1350 case '?':
1351 break;
1353 default:
1354 as_bad (_("unknown constraint `%c'"), *op_constraint);
1355 break;
1357 return op_mask;