1/* tc-xgate.c -- Assembler code for Freescale XGATE
2   Copyright (C) 2010-2017 Free Software Foundation, Inc.
3   Contributed by Sean Keys <skeys@ipdatasys.com>
4
5   This file is part of GAS, the GNU Assembler.
6
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.
11
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.
16
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.  */
21
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"
28
29const char comment_chars[] = ";!";
30const char line_comment_chars[] = "#*";
31const char line_separator_chars[] = "";
32const char EXP_CHARS[] = "eE";
33const char FLT_CHARS[] = "dD";
34
35/* Max opcodes per opcode handle.  */
36#define MAX_OPCODES     0x05
37
38#define SIXTEENTH_BIT		0x8000
39#define N_BITS_IN_WORD		16
40#define MAX_NUM_OPERANDS	3
41
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
49
50#define OPTION_MMCU 'm'
51
52/* This macro has no side-effects.  */
53#define ENCODE_RELAX(what,length) (((what) << 2) + (length))
54
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.  */
58struct xgate_opcode_handle
59{
60  int number_of_modes;
61  char *name;
62  struct xgate_opcode *opc0[MAX_OPCODES];
63};
64
65/* XGATE's registers all are 16-bit general purpose.
66   They are numbered according to the specifications.  */
67typedef enum register_id
68{
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;
81
82/* Operand Modifiers */
83typedef enum op_modifiers
84{
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;
92
93typedef struct s_operand
94{
95  expressionS exp;
96  register_id reg;
97  op_modifiers mod;
98} s_operand;
99
100
101/* Forward declarations.  */
102static inline char *skip_whitespace (char *);
103static void get_default_target (void);
104static char *extract_word (char *, char *, int);
105static struct xgate_opcode *xgate_find_match (struct xgate_opcode_handle *,
106					      int, s_operand [], unsigned int);
107static int cmp_opcode (struct xgate_opcode *, struct xgate_opcode *);
108static void xgate_print_table (void);
109static unsigned int xgate_get_operands (char *, s_operand []);
110static register_id reg_name_search (char *);
111static op_modifiers xgate_determine_modifiers (char **);
112static void xgate_scan_operands (struct xgate_opcode *opcode, s_operand []);
113static unsigned int xgate_parse_operand (struct xgate_opcode *, int *, int,
114					 char **, s_operand);
115
116static struct hash_control *xgate_hash;
117
118/* Previous opcode.  */
119static unsigned int prev = 0;
120
121static unsigned char fixup_required = 0;
122
123/* Used to enable clipping of 16 bit operands into 8 bit constraints.  */
124static unsigned char autoHiLo = 0;
125
126static char oper_check;
127static char flag_print_insn_syntax = 0;
128static char flag_print_opcodes = 0;
129
130static int current_architecture;
131static const char *default_cpu;
132
133/* ELF flags to set in the output file header.  */
134static int elf_flags = E_XGATE_F64;
135
136/* This table describes how you change sizes for the various types of variable
137   size expressions.  This version only supports two kinds.  */
138
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.  */
144
145relax_typeS md_relax_table[] =
146{
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}
155};
156
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.  */
160const pseudo_typeS md_pseudo_table[] =
161{
162  /* The following pseudo-ops are supported for MRI compatibility.  */
163  {0, 0, 0}
164};
165
166const char *md_shortopts = "m:";
167
168struct option md_longopts[] =
169{
170#define OPTION_PRINT_INSN_SYNTAX  (OPTION_MD_BASE + 0)
171  { "print-insn-syntax", no_argument, NULL, OPTION_PRINT_INSN_SYNTAX },
172
173#define OPTION_PRINT_OPCODES  (OPTION_MD_BASE + 1)
174  { "print-opcodes", no_argument, NULL, OPTION_PRINT_OPCODES },
175
176#define OPTION_GENERATE_EXAMPLE  (OPTION_MD_BASE + 2)
177  { "generate-example", no_argument, NULL, OPTION_GENERATE_EXAMPLE },
178
179#define OPTION_MSHORT  (OPTION_MD_BASE + 3)
180  { "mshort", no_argument, NULL, OPTION_MSHORT },
181
182#define OPTION_MLONG  (OPTION_MD_BASE + 4)
183  { "mlong", no_argument, NULL, OPTION_MLONG },
184
185#define OPTION_MSHORT_DOUBLE  (OPTION_MD_BASE + 5)
186  { "mshort-double", no_argument, NULL, OPTION_MSHORT_DOUBLE },
187
188#define OPTION_MLONG_DOUBLE  (OPTION_MD_BASE + 6)
189  { "mlong-double", no_argument, NULL, OPTION_MLONG_DOUBLE },
190
191  { NULL, no_argument, NULL, 0 }
192};
193
194size_t md_longopts_size = sizeof (md_longopts);
195
196const char *
197md_atof (int type, char *litP, int *sizeP)
198{
199  return ieee_md_atof (type, litP, sizeP, TRUE);
200}
201
202int
203md_parse_option (int c, const char *arg)
204{
205  switch (c)
206    {
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;
217
218    case OPTION_PRINT_INSN_SYNTAX:
219      flag_print_insn_syntax = 1;
220      break;
221
222    case OPTION_PRINT_OPCODES:
223      flag_print_opcodes = 1;
224      break;
225
226    case OPTION_GENERATE_EXAMPLE:
227      flag_print_opcodes = 2;
228      break;
229
230    case OPTION_MSHORT:
231      elf_flags &= ~E_XGATE_I32;
232      break;
233
234    case OPTION_MLONG:
235      elf_flags |= E_XGATE_I32;
236      break;
237
238    case OPTION_MSHORT_DOUBLE:
239      elf_flags &= ~E_XGATE_F64;
240      break;
241
242    case OPTION_MLONG_DOUBLE:
243      elf_flags |= E_XGATE_F64;
244      break;
245
246    default:
247      return 0;
248    }
249  return 1;
250}
251
252const char *
253xgate_arch_format (void)
254{
255  get_default_target ();
256
257  if (current_architecture & cpuxgate)
258    return "elf32-xgate";
259
260  return "error";
261}
262
263static void
264get_default_target (void)
265{
266  const bfd_target *target;
267  bfd abfd;
268
269  if (current_architecture != 0)
270    return;
271
272  default_cpu = "unknown";
273  target = bfd_find_target (0, &abfd);
274
275  if (target && target->name)
276    {
277      if (strcmp (target->name, "elf32-xgate") == 0)
278	{
279	  current_architecture = cpuxgate;
280	  default_cpu = "XGATE V1";
281	  return;
282	}
283
284      as_bad (_("Default target `%s' is not supported."), target->name);
285    }
286}
287
288void
289md_begin (void)
290{
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;
298
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);
302
303  memset (xgate_op_table, 0,
304	  sizeof (struct xgate_opcode) * (xgate_num_opcodes));
305
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];
309
310  qsort (xgate_op_table, xgate_num_opcodes, sizeof (struct xgate_opcode),
311	 (int (*)(const void *, const void *)) cmp_opcode);
312
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++)
318    {
319      if (strcmp (prev_op_name, xgate_opcode_ptr->name))
320	number_of_op_handles++;
321      prev_op_name = xgate_opcode_ptr->name;
322    }
323
324  op_handles = XNEWVEC (struct xgate_opcode_handle, number_of_op_handles);
325
326  /* Insert unique opcode names into hash table, aliasing duplicates.  */
327  xgate_hash = hash_new ();
328
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++)
332    {
333      if (!strcmp (prev_op_name, xgate_opcode_ptr->name))
334	{
335	  handle_enum++;
336	  op_handles[j].opc0[handle_enum] = xgate_opcode_ptr;
337	}
338      else
339	{
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	  hash_insert (xgate_hash, (char *) op_handles[j].name,
346		       (char *) &(op_handles[j]));
347	}
348      op_handles[j].number_of_modes = handle_enum;
349      prev_op_name = op_handles[j].name;
350    }
351
352  if (flag_print_opcodes)
353    {
354      xgate_print_table ();
355      exit (EXIT_SUCCESS);
356    }
357}
358
359void
360xgate_init_after_args (void)
361{
362}
363
364void
365md_show_usage (FILE * stream)
366{
367  get_default_target ();
368
369  fprintf (stream,
370	   _("\
371Freescale XGATE co-processor options:\n\
372  -mshort                 use 16-bit int ABI (default)\n\
373  -mlong                  use 32-bit int ABI\n\
374  -mshort-double          use 32-bit double ABI\n\
375  -mlong-double           use 64-bit double ABI (default)\n\
376  --mxgate                specify the processor variant[default %s]\n\
377  --print-insn-syntax     print the syntax of instruction in case of error\n\
378  --print-opcodes         print the list of instructions with syntax\n\
379  --generate-example      generate an example of each instruction"),
380	   default_cpu);
381}
382
383enum bfd_architecture
384xgate_arch (void)
385{
386  get_default_target ();
387  return bfd_arch_xgate;
388}
389
390int
391xgate_mach (void)
392{
393  return 0;
394}
395
396static void
397xgate_print_syntax (char *name)
398{
399  int i;
400
401  for (i = 0; i < xgate_num_opcodes; i++)
402    {
403      if (!strcmp (xgate_opcodes[i].name, name))
404	{
405	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IDR))
406	    printf ("\tFormat is %s\tRx, Rx, Rx+|-Rx|Rx\n",
407		    xgate_opcodes[i].name);
408	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_INH))
409	    printf ("\tFormat is %s\n", xgate_opcodes[i].name);
410	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_TRI))
411	    printf ("\tFormat is %s\tRx, Rx, Rx\n", xgate_opcodes[i].name);
412	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_DYA))
413	    printf ("\tFormat is %s\tRx, Rx\n", xgate_opcodes[i].name);
414	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM3))
415	    printf ("\tFormat is %s\t<3-bit value>\n", xgate_opcodes[i].name);
416	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM4))
417	    printf ("\tFormat is %s\t<4 -bit value>\n", xgate_opcodes[i].name);
418	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM8))
419	    printf ("\tFormat is %s\tRx, <8-bit value>\n",
420		    xgate_opcodes[i].name);
421	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16))
422	    printf ("\tFormat is %s\tRx, <16-bit value>\n",
423		    xgate_opcodes[i].name);
424	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_C))
425	    printf ("\tFormat is %s\tRx, CCR\n", xgate_opcodes[i].name);
426	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_C_R))
427	    printf ("\tFormat is %s\tCCR, Rx\n", xgate_opcodes[i].name);
428	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_MON_R_P))
429	    printf ("\tFormat is %s\tRx, PC\n", xgate_opcodes[i].name);
430	  if (!strcmp (xgate_opcodes[i].constraints, XGATE_OP_IMM16mLDW))
431	    printf ("\tFormat is %s\tRx, <16-bit value>\n",
432		    xgate_opcodes[i].name);
433	}
434    }
435}
436
437static void
438xgate_print_table (void)
439{
440  int i;
441
442  for (i = 0; i < xgate_num_opcodes; i++)
443    xgate_print_syntax (xgate_opcodes[i].name);
444
445  return;
446}
447
448const char *
449xgate_listing_header (void)
450{
451  if (current_architecture & cpuxgate)
452    return "XGATE GAS ";
453
454  return "ERROR MC9S12X GAS ";
455}
456
457symbolS *
458md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
459{
460  return NULL;
461}
462
463/* GAS will call this function for each section at the end of the assembly,
464   to permit the CPU backend to adjust the alignment of a section.  */
465
466valueT
467md_section_align (asection * seg, valueT addr)
468{
469  int align = bfd_get_section_alignment (stdoutput, seg);
470  return ((addr + (1 << align) - 1) & -(1 << align));
471}
472
473void
474md_assemble (char *input_line)
475{
476  struct xgate_opcode *opcode = 0;
477  struct xgate_opcode *macro_opcode = 0;
478  struct xgate_opcode_handle *opcode_handle = 0;
479  /* Caller expects it to be returned as it was passed.  */
480  char *saved_input_line = input_line;
481  char op_name[9] =  { 0 };
482  unsigned int operandCount = 0;
483  char *p = 0;
484
485  s_operand new_operands[MAX_NUM_OPERANDS];
486
487  fixup_required = 0;
488  oper_check = 0; /* set error flags */
489  input_line = extract_word (input_line, op_name, sizeof (op_name));
490
491  /* Check to make sure we are not reading a bogus line.  */
492  if (!op_name[0])
493    as_bad (_("opcode missing or not found on input line"));
494
495  if (!(opcode_handle = (struct xgate_opcode_handle *) hash_find (xgate_hash,
496								  op_name)))
497    {
498      as_bad (_("opcode %s not found in opcode hash table"), op_name);
499    }
500  else
501    {
502      /* Parse operands so we can find the proper opcode bin.  */
503
504      operandCount = xgate_get_operands (input_line, new_operands);
505
506      opcode = xgate_find_match (opcode_handle, opcode_handle->number_of_modes,
507				 new_operands, operandCount);
508
509      if (!opcode)
510	{
511	  as_bad (_("matching operands to opcode "));
512	  xgate_print_syntax (opcode_handle->opc0[0]->name);
513	}
514      else if (opcode->size == 2)
515	{
516	  /* Size is one word - assemble that native insn.  */
517	  xgate_scan_operands (opcode, new_operands);
518	}
519      else
520	{
521	  /* Insn is a simplified instruction - expand it out.  */
522	  autoHiLo = 1;
523	  unsigned int i;
524
525	  /* skip past our ';' separator.  */
526	  for (i = strlen (opcode->constraints), p = opcode->constraints; i > 0;
527	       i--, p++)
528	    {
529	      if (*p == ';')
530		{
531		  p++;
532		  break;
533		}
534	    }
535	  input_line = skip_whitespace (input_line);
536	  char *macro_inline = input_line;
537
538	  /* Loop though the macro's opcode list and apply operands to
539	     each real opcode. */
540	  for (i = 0; *p && i < (opcode->size / 2); i++)
541	    {
542	      /* Loop though macro operand list.  */
543	      input_line = macro_inline; /* Rewind.  */
544	      p = extract_word (p, op_name, 10);
545
546	      if (!(opcode_handle = (struct xgate_opcode_handle *)
547		    hash_find (xgate_hash, op_name)))
548		{
549		  as_bad (_(": processing macro, real opcode handle"
550			    " not found in hash"));
551		  break;
552		}
553	      else
554		{
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);
560		}
561	    }
562	}
563    }
564  autoHiLo = 0;
565  input_line = saved_input_line;
566}
567
568/* Force truly undefined symbols to their maximum size, and generally set up
569   the frag list to be relaxed.  */
570
571int
572md_estimate_size_before_relax (fragS *fragp, asection *seg)
573{
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 };
578
579  for (subtype = 0; subtype < ARRAY_SIZE (rlx_state); subtype += 2)
580    {
581      if (fragp->fr_subtype == rlx_state[subtype]
582	  && (!S_IS_DEFINED (fragp->fr_symbol)
583	      || seg != S_GET_SEGMENT (fragp->fr_symbol)))
584	{
585	  fragp->fr_subtype = rlx_state[subtype + 1];
586	  break;
587	}
588    }
589
590  if (fragp->fr_subtype >= ARRAY_SIZE (md_relax_table))
591    abort ();
592
593  return md_relax_table[fragp->fr_subtype].rlx_length;
594}
595
596
597/* Relocation, relaxation and frag conversions.  */
598
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.  */
602
603long
604md_pcrel_from (fixS * fixP)
605{
606  return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
607}
608
609/* If while processing a fixup, a reloc really needs to be created
610   then it is done here.  */
611
612arelent *
613tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
614{
615  arelent * reloc;
616
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;
621
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);
626
627  if (reloc->howto == (reloc_howto_type *) NULL)
628    {
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;
633    }
634
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;
641}
642
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.  */
647
648void
649md_apply_fix (fixS * fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
650{
651  char *where;
652  long value = *valP;
653  int opcode = 0;
654  ldiv_t result;
655
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;
660
661  /* We don't actually support subtracting a symbol.  */
662  if (fixP->fx_subsy != (symbolS *) NULL)
663    as_bad_where (fixP->fx_file, fixP->fx_line, _("Expression too complex."));
664
665  where = fixP->fx_frag->fr_literal + fixP->fx_where;
666  opcode = bfd_getl16 (where);
667  int mask = 0;
668
669  switch (fixP->fx_r_type)
670    {
671    case R_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 R_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;
755    }
756}
757
758/* See whether we need to force a relocation into the output file.  */
759
760int
761tc_xgate_force_relocation (fixS * fixP)
762{
763  if (fixP->fx_r_type == BFD_RELOC_XGATE_RL_GROUP)
764    return 1;
765  return generic_force_reloc (fixP);
766}
767
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.  */
773
774int
775tc_xgate_fix_adjustable (fixS * fixP)
776{
777  switch (fixP->fx_r_type)
778    {
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;
790    }
791}
792
793void
794md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
795		 asection * sec ATTRIBUTE_UNUSED,
796		 fragS * fragP ATTRIBUTE_UNUSED)
797{
798  as_bad (("md_convert_frag not implemented yet"));
799  abort ();
800}
801
802/* Set the ELF specific flags.  */
803
804void
805xgate_elf_final_processing (void)
806{
807  elf_flags |= EF_XGATE_MACH;
808  elf_elfheader (stdoutput)->e_flags &= ~EF_XGATE_ABI;
809  elf_elfheader (stdoutput)->e_flags |= elf_flags;
810}
811
812static inline char *
813skip_whitespace (char *s)
814{
815  while (*s == ' ' || *s == '\t' || *s == '(' || *s == ')')
816    s++;
817
818  return s;
819}
820
821/* Extract a word (continuous alpha-numeric chars) from the input line.  */
822
823static char *
824extract_word (char *from, char *to, int limit)
825{
826  char *op_end;
827  int size = 0;
828
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);)
834    {
835      to[size++] = *op_end++;
836      if (size + 1 >= limit)
837	break;
838    }
839  to[size] = 0;
840  return op_end;
841}
842
843static char *
844xgate_new_instruction (int size)
845{
846  char *f = frag_more (size);
847  dwarf2_emit_insn (size);
848  return f;
849}
850
851static unsigned short
852xgate_apply_operand (unsigned short new_mask,
853		     unsigned short *availiable_mask_bits,
854		     unsigned short mask,
855		     unsigned char n_bits)
856{
857  unsigned short n_shifts;
858  unsigned int n_drop_bits;
859
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;
866
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;
873
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))
878    {
879      oper_check = 1; /* flag operand check as good */
880    }
881  new_mask <<= N_BITS_IN_WORD - (n_shifts + n_bits);
882  mask |= new_mask;
883  return mask;
884}
885
886/* Parse ordinary expression.  */
887
888static char *
889xgate_parse_exp (char *s, expressionS * op)
890{
891  input_line_pointer = s;
892
893  expression (op);
894  if (op->X_op == O_absent)
895    as_bad (_("missing operand"));
896  return input_line_pointer;
897}
898
899static int
900cmp_opcode (struct xgate_opcode *op1, struct xgate_opcode *op2)
901{
902  return strcmp (op1->name, op2->name);
903}
904
905static struct xgate_opcode *
906xgate_find_match (struct xgate_opcode_handle *opcode_handle,
907		  int numberOfModes, s_operand oprs[], unsigned int operandCount)
908{
909  int i;
910
911  if (numberOfModes == 0)
912    return opcode_handle->opc0[0];
913
914  for (i = 0; i <= numberOfModes; i++)
915    {
916      switch (operandCount)
917        {
918      case 0:
919        if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_INH))
920          return opcode_handle->opc0[i];
921        break;
922      case 1:
923        if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
924	  {
925	    if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_MON))
926	      return opcode_handle->opc0[i];
927	    if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_DYA_MON))
928	      return opcode_handle->opc0[i];
929	  }
930        if (oprs[0].reg == REG_NONE)
931          if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM3))
932            return opcode_handle->opc0[i];
933        break;
934      case 2:
935        if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
936          {
937            if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7)
938	      {
939		if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_DYA))
940		  return opcode_handle->opc0[i];
941	      }
942            if (oprs[1].reg == REG_CCR)
943              if (!strcmp (opcode_handle->opc0[i]->constraints,
944                  XGATE_OP_MON_R_C))
945                return opcode_handle->opc0[i];
946            if (oprs[1].reg == REG_PC)
947              if (!strcmp (opcode_handle->opc0[i]->constraints,
948                  XGATE_OP_MON_R_P))
949                return opcode_handle->opc0[i];
950            if (oprs[1].reg == REG_NONE)
951              if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM16)
952                  || !strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM8)
953                  || !strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_IMM4)
954                  || !strcmp (opcode_handle->opc0[i]->constraints,
955                      XGATE_OP_IMM16mADD)
956                  || !strcmp (opcode_handle->opc0[i]->constraints,
957                      XGATE_OP_IMM16mAND)
958                  || !strcmp (opcode_handle->opc0[i]->constraints,
959                      XGATE_OP_IMM16mCPC)
960                  || !strcmp (opcode_handle->opc0[i]->constraints,
961                      XGATE_OP_IMM16mSUB)
962                  || !strcmp (opcode_handle->opc0[i]->constraints,
963                      XGATE_OP_IMM16mLDW))
964                return opcode_handle->opc0[i];
965          }
966        if (oprs[0].reg == REG_CCR)
967          if (!strcmp (opcode_handle->opc0[i]->constraints, XGATE_OP_MON_C_R))
968            return opcode_handle->opc0[i];
969        break;
970      case 3:
971        if (oprs[0].reg >= REG_R0 && oprs[0].reg <= REG_R7)
972          {
973            if (oprs[1].reg >= REG_R0 && oprs[1].reg <= REG_R7)
974              {
975                if (oprs[2].reg >= REG_R0 && oprs[2].reg <= REG_R7)
976                  {
977                    if (!strcmp (opcode_handle->opc0[i]->constraints,
978                        XGATE_OP_IDR)
979                        || !strcmp (opcode_handle->opc0[i]->constraints,
980                            XGATE_OP_TRI))
981                      return opcode_handle->opc0[i];
982                  }
983
984                if (oprs[2].reg == REG_NONE)
985                  if (!strcmp (opcode_handle->opc0[i]->constraints,
986                      XGATE_OP_IDO5))
987                    return opcode_handle->opc0[i];
988              }
989          }
990        break;
991      default:
992        as_bad (_("unknown operand count"));
993        break;
994        }
995    }
996  return NULL ;
997}
998
999/* Because we are dealing with two different core that view the system
1000   memory with different offsets, we must differentiate what core a
1001   symbol belongs to, in order for the linker to cross-link.  */
1002
1003int
1004xgate_frob_symbol (symbolS *sym)
1005{
1006  asymbol *bfdsym;
1007  elf_symbol_type *elfsym;
1008
1009  bfdsym = symbol_get_bfdsym (sym);
1010  elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym);
1011
1012  gas_assert (elfsym);
1013
1014  /* Mark the symbol as being *from XGATE  */
1015  elfsym->internal_elf_sym.st_target_internal = 1;
1016
1017  return 0;
1018}
1019
1020static unsigned int
1021xgate_get_operands (char *line, s_operand oprs[])
1022{
1023  int num_operands;
1024
1025  /* If there are no operands, then it must be inherent.  */
1026  if (*line == 0 || *line == '\n' || *line == '\r')
1027    return 0;
1028
1029  for (num_operands = 0; strlen (line) && (num_operands < MAX_NUM_OPERANDS);
1030       num_operands++)
1031    {
1032      line = skip_whitespace (line);
1033      if (*line == '#')
1034	line++;
1035
1036      oprs[num_operands].mod = xgate_determine_modifiers (&line);
1037
1038      if ((oprs[num_operands].reg = reg_name_search (line)) == REG_NONE)
1039	line = xgate_parse_exp (line, &oprs[num_operands].exp);
1040
1041      /* skip to next operand */
1042      while (*line != 0)
1043	{
1044	  if (*line == ',')
1045	    {
1046	      line++;
1047	      break;
1048	    }
1049	  line++;
1050	}
1051    }
1052  if (num_operands > MAX_NUM_OPERANDS)
1053    return 0;
1054  return num_operands;
1055}
1056
1057/* reg_name_search() finds the register number given its name.
1058   Returns the register number or REG_NONE on failure.  */
1059
1060static register_id
1061reg_name_search (char *name)
1062{
1063  if (strncasecmp (name, "r0", 2) == 0)
1064    return REG_R0;
1065  if (strncasecmp (name, "r1", 2) == 0)
1066    return REG_R1;
1067  if (strncasecmp (name, "r2", 2) == 0)
1068    return REG_R2;
1069  if (strncasecmp (name, "r3", 2) == 0)
1070    return REG_R3;
1071  if (strncasecmp (name, "r4", 2) == 0)
1072    return REG_R4;
1073  if (strncasecmp (name, "r5", 2) == 0)
1074    return REG_R5;
1075  if (strncasecmp (name, "r6", 2) == 0)
1076    return REG_R6;
1077  if (strncasecmp (name, "r7", 2) == 0)
1078    return REG_R7;
1079  if (strncasecmp (name, "pc", 2) == 0)
1080    return REG_PC;
1081  if (strncasecmp (name, "ccr", 3) == 0)
1082    return REG_CCR;
1083  return REG_NONE;
1084}
1085
1086/* Parse operand modifiers such as inc/dec/hi/low.  */
1087
1088static op_modifiers
1089xgate_determine_modifiers (char **line)
1090{
1091  char *local_line = line[0];
1092
1093  if (strncasecmp (local_line, "%hi", 3) == 0)
1094    {
1095      *line += 3;
1096      return MOD_LOAD_HIGH;
1097    }
1098  if (strncasecmp (local_line, "%lo", 3) == 0)
1099    {
1100      *line += 3;
1101      return MOD_LOAD_LOW;
1102    }
1103  if (*(local_line + 2) == '+')
1104    return MOD_POSTINC;
1105  if (strncasecmp (local_line, "-r", 2) == 0)
1106    {
1107      *line += 1;
1108      return MOD_PREDEC;
1109    }
1110  return MOD_NONE;
1111}
1112
1113/* Parse instruction operands.  */
1114
1115static void
1116xgate_scan_operands (struct xgate_opcode *opcode, s_operand oprs[])
1117{
1118  char *frag = xgate_new_instruction (opcode->size);
1119  int where = frag - frag_now->fr_literal;
1120  char *op = opcode->constraints;
1121  unsigned int bin = (int) opcode->bin_opcode;
1122  unsigned short oper_mask = 0;
1123  int operand_bit_length = 0;
1124  unsigned int operand = 0;
1125  char n_operand_bits = 0;
1126  char first_operand_equals_second = 0;
1127  int i = 0;
1128  char c = 0;
1129
1130  /* Generate available operand bits mask.  */
1131  for (i = 0; (c = opcode->format[i]); i++)
1132    {
1133      if (ISDIGIT (c) || (c == 's'))
1134	{
1135	  oper_mask <<= 1;
1136	}
1137      else
1138	{
1139	  oper_mask <<= 1;
1140	  oper_mask += 1;
1141	  n_operand_bits++;
1142	}
1143    }
1144
1145  /* Parse first operand.  */
1146  if (*op)
1147    {
1148      if (*op == '=')
1149	{
1150	  first_operand_equals_second = 1;
1151	  ++op;
1152	}
1153      operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1154				     &op, oprs[0]);
1155      ++op;
1156      bin = xgate_apply_operand (operand, &oper_mask, bin, operand_bit_length);
1157
1158      if (first_operand_equals_second)
1159	bin = xgate_apply_operand (operand, &oper_mask, bin,
1160				   operand_bit_length);
1161      /* Parse second operand.  */
1162      if (*op)
1163	{
1164	  if (*op == ',')
1165	    ++op;
1166	  if (first_operand_equals_second)
1167	    {
1168	      bin = xgate_apply_operand (operand, &oper_mask, bin,
1169					 operand_bit_length);
1170	      ++op;
1171	    }
1172	  else
1173	    {
1174	      operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1175					     &op, oprs[1]);
1176	      bin = xgate_apply_operand (operand, &oper_mask, bin,
1177					 operand_bit_length);
1178	      ++op;
1179	    }
1180	}
1181      /* Parse the third register.  */
1182      if (*op)
1183	{
1184	  if (*op == ',')
1185	    ++op;
1186	  operand = xgate_parse_operand (opcode, &operand_bit_length, where,
1187					 &op, oprs[2]);
1188	  bin = xgate_apply_operand (operand, &oper_mask, bin,
1189				     operand_bit_length);
1190	}
1191    }
1192  if (opcode->size == 2 && fixup_required)
1193    {
1194      bfd_putl16 (bin, frag);
1195    }
1196  else if ( !strcmp (opcode->constraints, XGATE_OP_REL9)
1197      || !strcmp (opcode->constraints, XGATE_OP_REL10))
1198    {
1199      /* Write our data to a frag for further processing.  */
1200      bfd_putl16 (opcode->bin_opcode, frag);
1201    }
1202  else
1203    {
1204      /* Apply operand mask(s)to bin opcode and write the output.  */
1205      /* Since we are done write this frag in xgate BE format.  */
1206      number_to_chars_bigendian (frag, bin, opcode->size);
1207    }
1208  prev = bin;
1209  return;
1210}
1211
1212static unsigned int
1213xgate_parse_operand (struct xgate_opcode *opcode,
1214		     int *bit_width,
1215		     int where,
1216		     char **op_con,
1217		     s_operand operand)
1218{
1219  char *op_constraint = *op_con;
1220  unsigned int op_mask = 0;
1221  unsigned int pp_fix = 0;
1222  unsigned short max_size = 0;
1223  int i;
1224
1225  *bit_width = 0;
1226  /* Reset.  */
1227
1228  switch (*op_constraint)
1229    {
1230    case '+': /* Indexed register operand +/- or plain r.  */
1231      /* Default to neither inc or dec.  */
1232      pp_fix = 0;
1233      *bit_width = 5;
1234
1235      if (operand.reg == REG_NONE)
1236	as_bad (_(": expected register name r0-r7 ") );
1237      op_mask = operand.reg;
1238      if (operand.mod == MOD_POSTINC)
1239	pp_fix = INCREMENT;
1240      if (operand.mod == MOD_PREDEC)
1241	pp_fix = DECREMENT;
1242      op_mask <<= 2;
1243      op_mask |= pp_fix;
1244      break;
1245
1246    case 'r': /* Register operand.  */
1247      if (operand.reg == REG_NONE)
1248	as_bad (_(": expected register name r0-r7 "));
1249
1250      *bit_width = 3;
1251
1252      op_mask = operand.reg;
1253      break;
1254
1255    case 'i': /* Immediate value or expression expected.  */
1256      /* Advance the original format pointer.  */
1257      (*op_con)++;
1258      op_constraint++;
1259      if (ISDIGIT (*op_constraint))
1260	*bit_width = (int) *op_constraint - '0';
1261      else if (*op_constraint == 'a')
1262	*bit_width = 0x0A;
1263      else if (*op_constraint == 'f')
1264	*bit_width = 0x0F;
1265
1266      /* http://tigcc.ticalc.org/doc/gnuasm.html#SEC31 */
1267      if (operand.exp.X_op == O_constant)
1268	{
1269	  op_mask = operand.exp.X_add_number;
1270	  if (((opcode->name[strlen (opcode->name) - 1] == 'l') && autoHiLo)
1271	      || operand.mod == MOD_LOAD_LOW)
1272	    op_mask &= 0x00FF;
1273	  else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
1274		    && autoHiLo) || operand.mod == MOD_LOAD_HIGH)
1275	    op_mask >>= 8;
1276
1277	  /* Make sure it fits.  */
1278	  for (i = *bit_width; i; i--)
1279	    {
1280	      max_size <<= 1;
1281	      max_size += 1;
1282	    }
1283	  if (op_mask > max_size)
1284	    as_bad (_(":operand value(%d) too big for constraint"), op_mask);
1285	}
1286      else
1287	{
1288	  /* Should be BFD_RELOC_XGATE_IMM8_LO instead of BFD_RELOC_XGATE_24
1289	     TODO fix.  */
1290	  fixup_required = 1;
1291	  if (*op_constraint == '8')
1292	    {
1293	      if (((opcode->name[strlen (opcode->name) - 1] == 'l')
1294		   && autoHiLo) || operand.mod == MOD_LOAD_LOW)
1295		fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1296			     BFD_RELOC_XGATE_24);
1297	      else if (((opcode->name[strlen (opcode->name) - 1]) == 'h'
1298			&& autoHiLo) || operand.mod == MOD_LOAD_HIGH )
1299		fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1300			     BFD_RELOC_XGATE_IMM8_HI);
1301	      else
1302		as_bad (_("you must use a hi/lo directive or 16-bit macro "
1303			  "to load a 16-bit value."));
1304	    }
1305	  else if (*op_constraint == '5')
1306	    fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1307			 BFD_RELOC_XGATE_IMM5);
1308	  else if (*op_constraint == '4')
1309	    fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1310			 BFD_RELOC_XGATE_IMM4);
1311	  else if (*op_constraint == '3')
1312	    fix_new_exp (frag_now, where, 2, &operand.exp, FALSE,
1313			 BFD_RELOC_XGATE_IMM3);
1314	  else
1315	    as_bad (_(":unknown relocation constraint size"));
1316	}
1317      break;
1318
1319    case 'c': /* CCR register expected.  */
1320      *bit_width = 0;
1321      if (operand.reg != REG_CCR)
1322	as_bad (_(": expected register name ccr "));
1323      break;
1324
1325    case 'p': /* PC register expected.  */
1326      *bit_width = 0;
1327      if (operand.reg != REG_PC)
1328	as_bad (_(": expected register name pc "));
1329      break;
1330
1331    case 'b': /* Branch expected.  */
1332      (*op_con)++;
1333      op_constraint++;
1334
1335      if (operand.exp.X_op != O_register)
1336	{
1337	  if (*op_constraint == '9')
1338	    fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
1339			 R_XGATE_PCREL_9);
1340	  else if (*op_constraint == 'a')
1341	    fix_new_exp (frag_now, where, 2, &operand.exp, TRUE,
1342			 R_XGATE_PCREL_10);
1343	}
1344      else
1345	as_fatal (_("Operand `%x' not recognized in fixup8."),
1346		  operand.exp.X_op);
1347      break;
1348    case '?':
1349      break;
1350
1351    default:
1352      as_bad (_("unknown constraint `%c'"), *op_constraint);
1353      break;
1354    }
1355  return op_mask;
1356}
1357