1/* tc-mn10200.c -- Assembler code for the Matsushita 10200
2   Copyright (C) 1996-2017 Free Software Foundation, Inc.
3
4   This file is part of GAS, the GNU Assembler.
5
6   GAS 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 3, or (at your option)
9   any later version.
10
11   GAS 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 GAS; see the file COPYING.  If not, write to
18   the Free Software Foundation, 51 Franklin Street - Fifth Floor,
19   Boston, MA 02110-1301, USA.  */
20
21#include "as.h"
22#include "safe-ctype.h"
23#include "subsegs.h"
24#include "opcode/mn10200.h"
25
26/* Structure to hold information about predefined registers.  */
27struct reg_name
28{
29  const char *name;
30  int value;
31};
32
33/* Generic assembler global variables which must be defined by all
34   targets.  */
35
36/* Characters which always start a comment.  */
37const char comment_chars[] = "#";
38
39/* Characters which start a comment at the beginning of a line.  */
40const char line_comment_chars[] = ";#";
41
42/* Characters which may be used to separate multiple commands on a
43   single line.  */
44const char line_separator_chars[] = ";";
45
46/* Characters which are used to indicate an exponent in a floating
47   point number.  */
48const char EXP_CHARS[] = "eE";
49
50/* Characters which mean that a number is a floating point constant,
51   as in 0d1.0.  */
52const char FLT_CHARS[] = "dD";
53
54const relax_typeS md_relax_table[] =
55 {
56  /* bCC relaxing  */
57  {0x81, -0x7e, 2, 1},
58  {0x8004, -0x7ffb, 5, 2},
59  {0x800006, -0x7ffff9, 7, 0},
60  /* bCCx relaxing  */
61  {0x81, -0x7e, 3, 4},
62  {0x8004, -0x7ffb, 6, 5},
63  {0x800006, -0x7ffff9, 8, 0},
64  /* jsr relaxing  */
65  {0x8004, -0x7ffb, 3, 7},
66  {0x800006, -0x7ffff9, 5, 0},
67  /* jmp relaxing  */
68  {0x81, -0x7e, 2, 9},
69  {0x8004, -0x7ffb, 3, 10},
70  {0x800006, -0x7ffff9, 5, 0},
71
72};
73
74
75/* Fixups.  */
76#define MAX_INSN_FIXUPS 5
77
78struct mn10200_fixup
79{
80  expressionS exp;
81  int opindex;
82  bfd_reloc_code_real_type reloc;
83};
84
85struct mn10200_fixup fixups[MAX_INSN_FIXUPS];
86static int fc;
87
88const char *md_shortopts = "";
89
90struct option md_longopts[] =
91{
92  {NULL, no_argument, NULL, 0}
93};
94
95size_t md_longopts_size = sizeof (md_longopts);
96
97/* The target specific pseudo-ops which we support.  */
98const pseudo_typeS md_pseudo_table[] =
99{
100  { NULL,       NULL,           0 }
101};
102
103/* Opcode hash table.  */
104static struct hash_control *mn10200_hash;
105
106/* This table is sorted. Suitable for searching by a binary search.  */
107static const struct reg_name data_registers[] =
108{
109  { "d0", 0 },
110  { "d1", 1 },
111  { "d2", 2 },
112  { "d3", 3 },
113};
114#define DATA_REG_NAME_CNT				\
115  (sizeof (data_registers) / sizeof (struct reg_name))
116
117static const struct reg_name address_registers[] =
118{
119  { "a0", 0 },
120  { "a1", 1 },
121  { "a2", 2 },
122  { "a3", 3 },
123};
124#define ADDRESS_REG_NAME_CNT					\
125  (sizeof (address_registers) / sizeof (struct reg_name))
126
127static const struct reg_name other_registers[] =
128{
129  { "mdr", 0 },
130  { "psw", 0 },
131};
132#define OTHER_REG_NAME_CNT				\
133  (sizeof (other_registers) / sizeof (struct reg_name))
134
135/* reg_name_search does a binary search of the given register table
136   to see if "name" is a valid regiter name.  Returns the register
137   number from the array on success, or -1 on failure.  */
138
139static int
140reg_name_search (const struct reg_name *regs,
141		 int regcount,
142		 const char *name)
143{
144  int middle, low, high;
145  int cmp;
146
147  low = 0;
148  high = regcount - 1;
149
150  do
151    {
152      middle = (low + high) / 2;
153      cmp = strcasecmp (name, regs[middle].name);
154      if (cmp < 0)
155	high = middle - 1;
156      else if (cmp > 0)
157	low = middle + 1;
158      else
159	return regs[middle].value;
160    }
161  while (low <= high);
162  return -1;
163}
164
165/* Summary of register_name().
166
167   in: Input_line_pointer points to 1st char of operand.
168
169   out: An expressionS.
170  	The operand may have been a register: in this case, X_op == O_register,
171  	X_add_number is set to the register number, and truth is returned.
172  	Input_line_pointer->(next non-blank) char after operand, or is in
173  	its original state.  */
174
175static bfd_boolean
176data_register_name (expressionS *expressionP)
177{
178  int reg_number;
179  char *name;
180  char *start;
181  char c;
182
183  /* Find the spelling of the operand.  */
184  start = input_line_pointer;
185  c = get_symbol_name (&name);
186  reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);
187
188  /* Put back the delimiting char.  */
189  (void) restore_line_pointer (c);
190
191  /* Look to see if it's in the register table.  */
192  if (reg_number >= 0)
193    {
194      expressionP->X_op = O_register;
195      expressionP->X_add_number = reg_number;
196
197      /* Make the rest nice.  */
198      expressionP->X_add_symbol = NULL;
199      expressionP->X_op_symbol = NULL;
200
201      return TRUE;
202    }
203
204  /* Reset the line as if we had not done anything.  */
205  input_line_pointer = start;
206  return FALSE;
207}
208
209/* Summary of register_name().
210
211   in: Input_line_pointer points to 1st char of operand.
212
213   out: An expressionS.
214  	The operand may have been a register: in this case, X_op == O_register,
215  	X_add_number is set to the register number, and truth is returned.
216  	Input_line_pointer->(next non-blank) char after operand, or is in
217  	its original state.  */
218
219static bfd_boolean
220address_register_name (expressionS *expressionP)
221{
222  int reg_number;
223  char *name;
224  char *start;
225  char c;
226
227  /* Find the spelling of the operand.  */
228  start = input_line_pointer;
229  c = get_symbol_name (&name);
230  reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);
231
232  /* Put back the delimiting char.  */
233  (void) restore_line_pointer (c);
234
235  /* Look to see if it's in the register table.  */
236  if (reg_number >= 0)
237    {
238      expressionP->X_op = O_register;
239      expressionP->X_add_number = reg_number;
240
241      /* Make the rest nice.  */
242      expressionP->X_add_symbol = NULL;
243      expressionP->X_op_symbol = NULL;
244
245      return TRUE;
246    }
247
248  /* Reset the line as if we had not done anything.  */
249  input_line_pointer = start;
250  return FALSE;
251}
252
253/* Summary of register_name().
254
255   in: Input_line_pointer points to 1st char of operand.
256
257   out: An expressionS.
258  	The operand may have been a register: in this case, X_op == O_register,
259  	X_add_number is set to the register number, and truth is returned.
260  	Input_line_pointer->(next non-blank) char after operand, or is in
261  	its original state.  */
262
263static bfd_boolean
264other_register_name (expressionS *expressionP)
265{
266  int reg_number;
267  char *name;
268  char *start;
269  char c;
270
271  /* Find the spelling of the operand.  */
272  start = input_line_pointer;
273  c = get_symbol_name (&name);
274  reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);
275
276  /* Put back the delimiting char.  */
277  (void) restore_line_pointer (c);
278
279  /* Look to see if it's in the register table.  */
280  if (reg_number >= 0)
281    {
282      expressionP->X_op = O_register;
283      expressionP->X_add_number = reg_number;
284
285      /* Make the rest nice.  */
286      expressionP->X_add_symbol = NULL;
287      expressionP->X_op_symbol = NULL;
288
289      return TRUE;
290    }
291
292  /* Reset the line as if we had not done anything.  */
293  input_line_pointer = start;
294  return FALSE;
295}
296
297void
298md_show_usage (FILE *stream)
299{
300  fprintf (stream, _("MN10200 options:\n\
301none yet\n"));
302}
303
304int
305md_parse_option (int c ATTRIBUTE_UNUSED,
306		 const char *arg ATTRIBUTE_UNUSED)
307{
308  return 0;
309}
310
311symbolS *
312md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
313{
314  return 0;
315}
316
317const char *
318md_atof (int type, char *litp, int *sizep)
319{
320  return ieee_md_atof (type, litp, sizep, FALSE);
321}
322
323void
324md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
325		 asection *sec,
326		 fragS *fragP)
327{
328  static unsigned long label_count = 0;
329  char buf[40];
330
331  subseg_change (sec, 0);
332  if (fragP->fr_subtype == 0)
333    {
334      fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
335	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
336      fragP->fr_var = 0;
337      fragP->fr_fix += 2;
338    }
339  else if (fragP->fr_subtype == 1)
340    {
341      /* Reverse the condition of the first branch.  */
342      int offset = fragP->fr_fix;
343      int opcode = fragP->fr_literal[offset] & 0xff;
344
345      switch (opcode)
346	{
347	case 0xe8:
348	  opcode = 0xe9;
349	  break;
350	case 0xe9:
351	  opcode = 0xe8;
352	  break;
353	case 0xe0:
354	  opcode = 0xe2;
355	  break;
356	case 0xe2:
357	  opcode = 0xe0;
358	  break;
359	case 0xe3:
360	  opcode = 0xe1;
361	  break;
362	case 0xe1:
363	  opcode = 0xe3;
364	  break;
365	case 0xe4:
366	  opcode = 0xe6;
367	  break;
368	case 0xe6:
369	  opcode = 0xe4;
370	  break;
371	case 0xe7:
372	  opcode = 0xe5;
373	  break;
374	case 0xe5:
375	  opcode = 0xe7;
376	  break;
377	default:
378	  abort ();
379	}
380      fragP->fr_literal[offset] = opcode;
381
382      /* Create a fixup for the reversed conditional branch.  */
383      sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
384      fix_new (fragP, fragP->fr_fix + 1, 1,
385	       symbol_new (buf, sec, 0, fragP->fr_next),
386	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
387
388      /* Now create the unconditional branch + fixup to the
389	 final target.  */
390      fragP->fr_literal[offset + 2] = 0xfc;
391      fix_new (fragP, fragP->fr_fix + 3, 2, fragP->fr_symbol,
392	       fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
393      fragP->fr_var = 0;
394      fragP->fr_fix += 5;
395    }
396  else if (fragP->fr_subtype == 2)
397    {
398      /* Reverse the condition of the first branch.  */
399      int offset = fragP->fr_fix;
400      int opcode = fragP->fr_literal[offset] & 0xff;
401
402      switch (opcode)
403	{
404	case 0xe8:
405	  opcode = 0xe9;
406	  break;
407	case 0xe9:
408	  opcode = 0xe8;
409	  break;
410	case 0xe0:
411	  opcode = 0xe2;
412	  break;
413	case 0xe2:
414	  opcode = 0xe0;
415	  break;
416	case 0xe3:
417	  opcode = 0xe1;
418	  break;
419	case 0xe1:
420	  opcode = 0xe3;
421	  break;
422	case 0xe4:
423	  opcode = 0xe6;
424	  break;
425	case 0xe6:
426	  opcode = 0xe4;
427	  break;
428	case 0xe7:
429	  opcode = 0xe5;
430	  break;
431	case 0xe5:
432	  opcode = 0xe7;
433	  break;
434	default:
435	  abort ();
436	}
437      fragP->fr_literal[offset] = opcode;
438
439      /* Create a fixup for the reversed conditional branch.  */
440      sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
441      fix_new (fragP, fragP->fr_fix + 1, 1,
442	       symbol_new (buf, sec, 0, fragP->fr_next),
443	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
444
445      /* Now create the unconditional branch + fixup to the
446	 final target.  */
447      fragP->fr_literal[offset + 2] = 0xf4;
448      fragP->fr_literal[offset + 3] = 0xe0;
449      fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
450	       fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
451      fragP->fr_var = 0;
452      fragP->fr_fix += 7;
453    }
454  else if (fragP->fr_subtype == 3)
455    {
456      fix_new (fragP, fragP->fr_fix + 2, 1, fragP->fr_symbol,
457	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
458      fragP->fr_var = 0;
459      fragP->fr_fix += 3;
460    }
461  else if (fragP->fr_subtype == 4)
462    {
463      /* Reverse the condition of the first branch.  */
464      int offset = fragP->fr_fix;
465      int opcode = fragP->fr_literal[offset + 1] & 0xff;
466
467      switch (opcode)
468	{
469	case 0xfc:
470	  opcode = 0xfd;
471	  break;
472	case 0xfd:
473	  opcode = 0xfc;
474	  break;
475	case 0xfe:
476	  opcode = 0xff;
477	  break;
478	case 0xff:
479	  opcode = 0xfe;
480	  break;
481	case 0xe8:
482	  opcode = 0xe9;
483	  break;
484	case 0xe9:
485	  opcode = 0xe8;
486	  break;
487	case 0xe0:
488	  opcode = 0xe2;
489	  break;
490	case 0xe2:
491	  opcode = 0xe0;
492	  break;
493	case 0xe3:
494	  opcode = 0xe1;
495	  break;
496	case 0xe1:
497	  opcode = 0xe3;
498	  break;
499	case 0xe4:
500	  opcode = 0xe6;
501	  break;
502	case 0xe6:
503	  opcode = 0xe4;
504	  break;
505	case 0xe7:
506	  opcode = 0xe5;
507	  break;
508	case 0xe5:
509	  opcode = 0xe7;
510	  break;
511	case 0xec:
512	  opcode = 0xed;
513	  break;
514	case 0xed:
515	  opcode = 0xec;
516	  break;
517	case 0xee:
518	  opcode = 0xef;
519	  break;
520	case 0xef:
521	  opcode = 0xee;
522	  break;
523	default:
524	  abort ();
525	}
526      fragP->fr_literal[offset + 1] = opcode;
527
528      /* Create a fixup for the reversed conditional branch.  */
529      sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
530      fix_new (fragP, fragP->fr_fix + 2, 1,
531	       symbol_new (buf, sec, 0, fragP->fr_next),
532	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
533
534      /* Now create the unconditional branch + fixup to the
535	 final target.  */
536      fragP->fr_literal[offset + 3] = 0xfc;
537      fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol,
538	       fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
539      fragP->fr_var = 0;
540      fragP->fr_fix += 6;
541    }
542  else if (fragP->fr_subtype == 5)
543    {
544      /* Reverse the condition of the first branch.  */
545      int offset = fragP->fr_fix;
546      int opcode = fragP->fr_literal[offset + 1] & 0xff;
547
548      switch (opcode)
549	{
550	case 0xfc:
551	  opcode = 0xfd;
552	  break;
553	case 0xfd:
554	  opcode = 0xfc;
555	  break;
556	case 0xfe:
557	  opcode = 0xff;
558	  break;
559	case 0xff:
560	  opcode = 0xfe;
561	  break;
562	case 0xe8:
563	  opcode = 0xe9;
564	  break;
565	case 0xe9:
566	  opcode = 0xe8;
567	  break;
568	case 0xe0:
569	  opcode = 0xe2;
570	  break;
571	case 0xe2:
572	  opcode = 0xe0;
573	  break;
574	case 0xe3:
575	  opcode = 0xe1;
576	  break;
577	case 0xe1:
578	  opcode = 0xe3;
579	  break;
580	case 0xe4:
581	  opcode = 0xe6;
582	  break;
583	case 0xe6:
584	  opcode = 0xe4;
585	  break;
586	case 0xe7:
587	  opcode = 0xe5;
588	  break;
589	case 0xe5:
590	  opcode = 0xe7;
591	  break;
592	case 0xec:
593	  opcode = 0xed;
594	  break;
595	case 0xed:
596	  opcode = 0xec;
597	  break;
598	case 0xee:
599	  opcode = 0xef;
600	  break;
601	case 0xef:
602	  opcode = 0xee;
603	  break;
604	default:
605	  abort ();
606	}
607      fragP->fr_literal[offset + 1] = opcode;
608
609      /* Create a fixup for the reversed conditional branch.  */
610      sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
611      fix_new (fragP, fragP->fr_fix + 2, 1,
612	       symbol_new (buf, sec, 0, fragP->fr_next),
613	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
614
615      /* Now create the unconditional branch + fixup to the
616	 final target.  */
617      fragP->fr_literal[offset + 3] = 0xf4;
618      fragP->fr_literal[offset + 4] = 0xe0;
619      fix_new (fragP, fragP->fr_fix + 5, 4, fragP->fr_symbol,
620	       fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
621      fragP->fr_var = 0;
622      fragP->fr_fix += 8;
623    }
624  else if (fragP->fr_subtype == 6)
625    {
626      fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol,
627	       fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
628      fragP->fr_var = 0;
629      fragP->fr_fix += 3;
630    }
631  else if (fragP->fr_subtype == 7)
632    {
633      int offset = fragP->fr_fix;
634      fragP->fr_literal[offset] = 0xf4;
635      fragP->fr_literal[offset + 1] = 0xe1;
636
637      fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
638	       fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
639      fragP->fr_var = 0;
640      fragP->fr_fix += 5;
641    }
642  else if (fragP->fr_subtype == 8)
643    {
644      fragP->fr_literal[fragP->fr_fix] = 0xea;
645      fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
646	       fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
647      fragP->fr_var = 0;
648      fragP->fr_fix += 2;
649    }
650  else if (fragP->fr_subtype == 9)
651    {
652      int offset = fragP->fr_fix;
653      fragP->fr_literal[offset] = 0xfc;
654
655      fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
656	       fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
657      fragP->fr_var = 0;
658      fragP->fr_fix += 3;
659    }
660  else if (fragP->fr_subtype == 10)
661    {
662      int offset = fragP->fr_fix;
663      fragP->fr_literal[offset] = 0xf4;
664      fragP->fr_literal[offset + 1] = 0xe0;
665
666      fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
667	       fragP->fr_offset, 1, BFD_RELOC_24_PCREL);
668      fragP->fr_var = 0;
669      fragP->fr_fix += 5;
670    }
671  else
672    abort ();
673}
674
675valueT
676md_section_align (asection *seg, valueT addr)
677{
678  int align = bfd_get_section_alignment (stdoutput, seg);
679  return ((addr + (1 << align) - 1) & -(1 << align));
680}
681
682void
683md_begin (void)
684{
685  const char *prev_name = "";
686  const struct mn10200_opcode *op;
687
688  mn10200_hash = hash_new ();
689
690  /* Insert unique names into hash table.  The MN10200 instruction set
691     has many identical opcode names that have different opcodes based
692     on the operands.  This hash table then provides a quick index to
693     the first opcode with a particular name in the opcode table.  */
694
695  op = mn10200_opcodes;
696  while (op->name)
697    {
698      if (strcmp (prev_name, op->name))
699	{
700	  prev_name = (char *) op->name;
701	  hash_insert (mn10200_hash, op->name, (char *) op);
702	}
703      op++;
704    }
705
706  /* This is both a simplification (we don't have to write md_apply_fix)
707     and support for future optimizations (branch shortening and similar
708     stuff in the linker.  */
709  linkrelax = 1;
710}
711
712static unsigned long
713check_operand (unsigned long insn ATTRIBUTE_UNUSED,
714	       const struct mn10200_operand *operand,
715	       offsetT val)
716{
717  /* No need to check 24bit or 32bit operands for a bit.  */
718  if (operand->bits < 24
719      && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
720    {
721      long min, max;
722      offsetT test;
723
724      if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
725	{
726	  max = (1 << (operand->bits - 1)) - 1;
727	  min = - (1 << (operand->bits - 1));
728	}
729      else
730	{
731	  max = (1 << operand->bits) - 1;
732	  min = 0;
733	}
734
735      test = val;
736
737      if (test < (offsetT) min || test > (offsetT) max)
738	return 0;
739      else
740	return 1;
741    }
742  return 1;
743}
744/* If while processing a fixup, a reloc really needs to be created
745   Then it is done here.  */
746
747arelent *
748tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
749{
750  arelent *reloc;
751  reloc = XNEW (arelent);
752
753  if (fixp->fx_subsy != NULL)
754    {
755      if (S_GET_SEGMENT (fixp->fx_addsy) == S_GET_SEGMENT (fixp->fx_subsy)
756	  && S_IS_DEFINED (fixp->fx_subsy))
757	{
758	  fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
759	  fixp->fx_subsy = NULL;
760	}
761      else
762	/* FIXME: We should try more ways to resolve difference expressions
763	   here.  At least this is better than silently ignoring the
764	   subtrahend.  */
765	as_bad_where (fixp->fx_file, fixp->fx_line,
766		      _("can't resolve `%s' {%s section} - `%s' {%s section}"),
767		      fixp->fx_addsy ? S_GET_NAME (fixp->fx_addsy) : "0",
768		      segment_name (fixp->fx_addsy
769				    ? S_GET_SEGMENT (fixp->fx_addsy)
770				    : absolute_section),
771		      S_GET_NAME (fixp->fx_subsy),
772		      segment_name (S_GET_SEGMENT (fixp->fx_addsy)));
773    }
774
775  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
776  if (reloc->howto == NULL)
777    {
778      as_bad_where (fixp->fx_file, fixp->fx_line,
779		    _("reloc %d not supported by object file format"),
780		    (int) fixp->fx_r_type);
781      return NULL;
782    }
783  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
784  reloc->sym_ptr_ptr = XNEW (asymbol *);
785  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
786  reloc->addend = fixp->fx_offset;
787  return reloc;
788}
789
790int
791md_estimate_size_before_relax (fragS *fragp, asection *seg)
792{
793  if (fragp->fr_subtype == 6
794      && (!S_IS_DEFINED (fragp->fr_symbol)
795	  || seg != S_GET_SEGMENT (fragp->fr_symbol)))
796    fragp->fr_subtype = 7;
797  else if (fragp->fr_subtype == 8
798	   && (!S_IS_DEFINED (fragp->fr_symbol)
799	       || seg != S_GET_SEGMENT (fragp->fr_symbol)))
800    fragp->fr_subtype = 10;
801
802  if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
803    abort ();
804
805  return md_relax_table[fragp->fr_subtype].rlx_length;
806}
807
808long
809md_pcrel_from (fixS *fixp)
810{
811  return fixp->fx_frag->fr_address;
812}
813
814void
815md_apply_fix (fixS * fixP, valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
816{
817  /* We shouldn't ever get here because linkrelax is nonzero.  */
818  abort ();
819  fixP->fx_done = 1;
820}
821
822/* Insert an operand value into an instruction.  */
823
824static void
825mn10200_insert_operand (unsigned long *insnp,
826			unsigned long *extensionp,
827			const struct mn10200_operand *operand,
828			offsetT val,
829			char *file,
830			unsigned int line,
831			unsigned int shift)
832{
833  /* No need to check 24 or 32bit operands for a bit.  */
834  if (operand->bits < 24
835      && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
836    {
837      long min, max;
838      offsetT test;
839
840      if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
841	{
842	  max = (1 << (operand->bits - 1)) - 1;
843	  min = - (1 << (operand->bits - 1));
844	}
845      else
846	{
847	  max = (1 << operand->bits) - 1;
848	  min = 0;
849	}
850
851      test = val;
852
853      if (test < (offsetT) min || test > (offsetT) max)
854	as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line);
855    }
856
857  if ((operand->flags & MN10200_OPERAND_EXTENDED) == 0)
858    {
859      *insnp |= (((long) val & ((1 << operand->bits) - 1))
860		 << (operand->shift + shift));
861
862      if ((operand->flags & MN10200_OPERAND_REPEATED) != 0)
863	*insnp |= (((long) val & ((1 << operand->bits) - 1))
864		   << (operand->shift + shift + 2));
865    }
866  else
867    {
868      *extensionp |= (val >> 16) & 0xff;
869      *insnp |= val & 0xffff;
870    }
871}
872
873void
874md_assemble (char *str)
875{
876  char *s;
877  struct mn10200_opcode *opcode;
878  struct mn10200_opcode *next_opcode;
879  const unsigned char *opindex_ptr;
880  int next_opindex, relaxable;
881  unsigned long insn, extension, size = 0;
882  char *f;
883  int i;
884  int match;
885
886  /* Get the opcode.  */
887  for (s = str; *s != '\0' && !ISSPACE (*s); s++)
888    ;
889  if (*s != '\0')
890    *s++ = '\0';
891
892  /* Find the first opcode with the proper name.  */
893  opcode = (struct mn10200_opcode *) hash_find (mn10200_hash, str);
894  if (opcode == NULL)
895    {
896      as_bad (_("Unrecognized opcode: `%s'"), str);
897      return;
898    }
899
900  str = s;
901  while (ISSPACE (*str))
902    ++str;
903
904  input_line_pointer = str;
905
906  for (;;)
907    {
908      const char *errmsg = NULL;
909      int op_idx;
910      char *hold;
911      int extra_shift = 0;
912
913      relaxable = 0;
914      fc = 0;
915      match = 0;
916      next_opindex = 0;
917      insn = opcode->opcode;
918      extension = 0;
919      for (op_idx = 1, opindex_ptr = opcode->operands;
920	   *opindex_ptr != 0;
921	   opindex_ptr++, op_idx++)
922	{
923	  const struct mn10200_operand *operand;
924	  expressionS ex;
925
926	  if (next_opindex == 0)
927	    {
928	      operand = &mn10200_operands[*opindex_ptr];
929	    }
930	  else
931	    {
932	      operand = &mn10200_operands[next_opindex];
933	      next_opindex = 0;
934	    }
935
936	  errmsg = NULL;
937
938	  while (*str == ' ' || *str == ',')
939	    ++str;
940
941	  if (operand->flags & MN10200_OPERAND_RELAX)
942	    relaxable = 1;
943
944	  /* Gather the operand.  */
945	  hold = input_line_pointer;
946	  input_line_pointer = str;
947
948	  if (operand->flags & MN10200_OPERAND_PAREN)
949	    {
950	      if (*input_line_pointer != ')' && *input_line_pointer != '(')
951		{
952		  input_line_pointer = hold;
953		  str = hold;
954		  goto error;
955		}
956	      input_line_pointer++;
957	      goto keep_going;
958	    }
959	  /* See if we can match the operands.  */
960	  else if (operand->flags & MN10200_OPERAND_DREG)
961	    {
962	      if (!data_register_name (&ex))
963		{
964		  input_line_pointer = hold;
965		  str = hold;
966		  goto error;
967		}
968	    }
969	  else if (operand->flags & MN10200_OPERAND_AREG)
970	    {
971	      if (!address_register_name (&ex))
972		{
973		  input_line_pointer = hold;
974		  str = hold;
975		  goto error;
976		}
977	    }
978	  else if (operand->flags & MN10200_OPERAND_PSW)
979	    {
980	      char *start;
981	      char c = get_symbol_name (&start);
982
983	      if (strcmp (start, "psw") != 0)
984		{
985		  (void) restore_line_pointer (c);
986		  input_line_pointer = hold;
987		  str = hold;
988		  goto error;
989		}
990	      (void) restore_line_pointer (c);
991	      goto keep_going;
992	    }
993	  else if (operand->flags & MN10200_OPERAND_MDR)
994	    {
995	      char *start;
996	      char c = get_symbol_name (&start);
997
998	      if (strcmp (start, "mdr") != 0)
999		{
1000		  (void) restore_line_pointer (c);
1001		  input_line_pointer = hold;
1002		  str = hold;
1003		  goto error;
1004		}
1005	      (void) restore_line_pointer (c);
1006	      goto keep_going;
1007	    }
1008	  else if (data_register_name (&ex))
1009	    {
1010	      input_line_pointer = hold;
1011	      str = hold;
1012	      goto error;
1013	    }
1014	  else if (address_register_name (&ex))
1015	    {
1016	      input_line_pointer = hold;
1017	      str = hold;
1018	      goto error;
1019	    }
1020	  else if (other_register_name (&ex))
1021	    {
1022	      input_line_pointer = hold;
1023	      str = hold;
1024	      goto error;
1025	    }
1026	  else if (*str == ')' || *str == '(')
1027	    {
1028	      input_line_pointer = hold;
1029	      str = hold;
1030	      goto error;
1031	    }
1032	  else
1033	    {
1034	      expression (&ex);
1035	    }
1036
1037	  switch (ex.X_op)
1038	    {
1039	    case O_illegal:
1040	      errmsg = _("illegal operand");
1041	      goto error;
1042	    case O_absent:
1043	      errmsg = _("missing operand");
1044	      goto error;
1045	    case O_register:
1046	      if ((operand->flags
1047		   & (MN10200_OPERAND_DREG | MN10200_OPERAND_AREG)) == 0)
1048		{
1049		  input_line_pointer = hold;
1050		  str = hold;
1051		  goto error;
1052		}
1053
1054	      if (opcode->format == FMT_2 || opcode->format == FMT_5)
1055		extra_shift = 8;
1056	      else if (opcode->format == FMT_3 || opcode->format == FMT_6
1057		       || opcode->format == FMT_7)
1058		extra_shift = 16;
1059	      else
1060		extra_shift = 0;
1061
1062	      mn10200_insert_operand (&insn, &extension, operand,
1063				      ex.X_add_number, NULL,
1064				      0, extra_shift);
1065
1066	      break;
1067
1068	    case O_constant:
1069	      /* If this operand can be promoted, and it doesn't
1070		 fit into the allocated bitfield for this insn,
1071		 then promote it (ie this opcode does not match).  */
1072	      if (operand->flags
1073		  & (MN10200_OPERAND_PROMOTE | MN10200_OPERAND_RELAX)
1074		  && !check_operand (insn, operand, ex.X_add_number))
1075		{
1076		  input_line_pointer = hold;
1077		  str = hold;
1078		  goto error;
1079		}
1080
1081	      mn10200_insert_operand (&insn, &extension, operand,
1082				      ex.X_add_number, NULL,
1083				      0, 0);
1084	      break;
1085
1086	    default:
1087	      /* If this operand can be promoted, then this opcode didn't
1088		 match since we can't know if it needed promotion!  */
1089	      if (operand->flags & MN10200_OPERAND_PROMOTE)
1090		{
1091		  input_line_pointer = hold;
1092		  str = hold;
1093		  goto error;
1094		}
1095
1096	      /* We need to generate a fixup for this expression.  */
1097	      if (fc >= MAX_INSN_FIXUPS)
1098		as_fatal (_("too many fixups"));
1099	      fixups[fc].exp = ex;
1100	      fixups[fc].opindex = *opindex_ptr;
1101	      fixups[fc].reloc = BFD_RELOC_UNUSED;
1102	      ++fc;
1103	      break;
1104	    }
1105
1106keep_going:
1107	  str = input_line_pointer;
1108	  input_line_pointer = hold;
1109
1110	  while (*str == ' ' || *str == ',')
1111	    ++str;
1112
1113	}
1114
1115      /* Make sure we used all the operands!  */
1116      if (*str != ',')
1117	match = 1;
1118
1119    error:
1120      if (match == 0)
1121	{
1122	  next_opcode = opcode + 1;
1123	  if (!strcmp (next_opcode->name, opcode->name))
1124	    {
1125	      opcode = next_opcode;
1126	      continue;
1127	    }
1128
1129	  as_bad ("%s", errmsg);
1130	  return;
1131	}
1132      break;
1133    }
1134
1135  while (ISSPACE (*str))
1136    ++str;
1137
1138  if (*str != '\0')
1139    as_bad (_("junk at end of line: `%s'"), str);
1140
1141  input_line_pointer = str;
1142
1143  if (opcode->format == FMT_1)
1144    size = 1;
1145  else if (opcode->format == FMT_2 || opcode->format == FMT_4)
1146    size = 2;
1147  else if (opcode->format == FMT_3 || opcode->format == FMT_5)
1148    size = 3;
1149  else if (opcode->format == FMT_6)
1150    size = 4;
1151  else if (opcode->format == FMT_7)
1152    size = 5;
1153  else
1154    abort ();
1155
1156  /* Write out the instruction.  */
1157  dwarf2_emit_insn (size);
1158  if (relaxable && fc > 0)
1159    {
1160      /* On a 64-bit host the size of an 'int' is not the same
1161	 as the size of a pointer, so we need a union to convert
1162	 the opindex field of the fr_cgen structure into a char *
1163	 so that it can be stored in the frag.  We do not have
1164	 to worry about losing accuracy as we are not going to
1165	 be even close to the 32bit limit of the int.  */
1166      union
1167      {
1168	int opindex;
1169	char * ptr;
1170      }
1171      opindex_converter;
1172      int type;
1173
1174      /* bCC  */
1175      if (size == 2 && opcode->opcode != 0xfc0000)
1176	{
1177	  /* Handle bra specially.  Basically treat it like jmp so
1178	     that we automatically handle 8, 16 and 32 bit offsets
1179	     correctly as well as jumps to an undefined address.
1180
1181	     It is also important to not treat it like other bCC
1182	     instructions since the long forms of bra is different
1183	     from other bCC instructions.  */
1184	  if (opcode->opcode == 0xea00)
1185	    type = 8;
1186	  else
1187	    type = 0;
1188	}
1189      /* jsr  */
1190      else if (size == 3 && opcode->opcode == 0xfd0000)
1191	type = 6;
1192      /* jmp  */
1193      else if (size == 3 && opcode->opcode == 0xfc0000)
1194	type = 8;
1195      /* bCCx  */
1196      else
1197	type = 3;
1198
1199      opindex_converter.opindex = fixups[0].opindex;
1200      f = frag_var (rs_machine_dependent, 8, 8 - size, type,
1201		    fixups[0].exp.X_add_symbol,
1202		    fixups[0].exp.X_add_number,
1203		    opindex_converter.ptr);
1204      number_to_chars_bigendian (f, insn, size);
1205      if (8 - size > 4)
1206	{
1207	  number_to_chars_bigendian (f + size, 0, 4);
1208	  number_to_chars_bigendian (f + size + 4, 0, 8 - size - 4);
1209	}
1210      else
1211	number_to_chars_bigendian (f + size, 0, 8 - size);
1212    }
1213  else
1214    {
1215      f = frag_more (size);
1216
1217      /* Oh, what a mess.  The instruction is in big endian format, but
1218	 16 and 24bit immediates are little endian!  */
1219      if (opcode->format == FMT_3)
1220	{
1221	  number_to_chars_bigendian (f, (insn >> 16) & 0xff, 1);
1222	  number_to_chars_littleendian (f + 1, insn & 0xffff, 2);
1223	}
1224      else if (opcode->format == FMT_6)
1225	{
1226	  number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1227	  number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1228	}
1229      else if (opcode->format == FMT_7)
1230	{
1231	  number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1232	  number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1233	  number_to_chars_littleendian (f + 4, extension & 0xff, 1);
1234	}
1235      else
1236	number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);
1237
1238      /* Create any fixups.  */
1239      for (i = 0; i < fc; i++)
1240	{
1241	  const struct mn10200_operand *operand;
1242	  int reloc_size;
1243
1244	  operand = &mn10200_operands[fixups[i].opindex];
1245	  if (fixups[i].reloc != BFD_RELOC_UNUSED)
1246	    {
1247	      reloc_howto_type *reloc_howto;
1248	      int offset;
1249	      fixS *fixP;
1250
1251	      reloc_howto = bfd_reloc_type_lookup (stdoutput,
1252						   fixups[i].reloc);
1253
1254	      if (!reloc_howto)
1255		abort ();
1256
1257	      reloc_size = bfd_get_reloc_size (reloc_howto);
1258
1259	      if (reloc_size < 1 || reloc_size > 4)
1260		abort ();
1261
1262	      offset = 4 - reloc_size;
1263	      fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1264				  reloc_size,
1265				  &fixups[i].exp,
1266				  reloc_howto->pc_relative,
1267				  fixups[i].reloc);
1268
1269	      /* PC-relative offsets are from the first byte of the
1270		 next instruction, not from the start of the current
1271		 instruction.  */
1272	      if (reloc_howto->pc_relative)
1273		fixP->fx_offset += reloc_size;
1274	    }
1275	  else
1276	    {
1277	      int reloc, pcrel, offset;
1278	      fixS *fixP;
1279
1280	      reloc = BFD_RELOC_NONE;
1281	      /* How big is the reloc?  Remember SPLIT relocs are
1282		 implicitly 32bits.  */
1283	      reloc_size = operand->bits;
1284
1285	      offset = size - reloc_size / 8;
1286
1287	      /* Is the reloc pc-relative?  */
1288	      pcrel = (operand->flags & MN10200_OPERAND_PCREL) != 0;
1289
1290	      /* Choose a proper BFD relocation type.  */
1291	      if (pcrel)
1292		{
1293		  if (reloc_size == 8)
1294		    reloc = BFD_RELOC_8_PCREL;
1295		  else if (reloc_size == 24)
1296		    reloc = BFD_RELOC_24_PCREL;
1297		  else
1298		    abort ();
1299		}
1300	      else
1301		{
1302		  if (reloc_size == 32)
1303		    reloc = BFD_RELOC_32;
1304		  else if (reloc_size == 16)
1305		    reloc = BFD_RELOC_16;
1306		  else if (reloc_size == 8)
1307		    reloc = BFD_RELOC_8;
1308		  else if (reloc_size == 24)
1309		    reloc = BFD_RELOC_24;
1310		  else
1311		    abort ();
1312		}
1313
1314	      /* Convert the size of the reloc into what fix_new_exp
1315                 wants.  */
1316	      reloc_size = reloc_size / 8;
1317	      if (reloc_size == 8)
1318		reloc_size = 0;
1319	      else if (reloc_size == 16)
1320		reloc_size = 1;
1321	      else if (reloc_size == 32 || reloc_size == 24)
1322		reloc_size = 2;
1323
1324	      fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1325				  reloc_size, &fixups[i].exp, pcrel,
1326				  ((bfd_reloc_code_real_type) reloc));
1327
1328	      /* PC-relative offsets are from the first byte of the
1329		 next instruction, not from the start of the current
1330		 instruction.  */
1331	      if (pcrel)
1332		fixP->fx_offset += size;
1333	    }
1334	}
1335    }
1336}
1337