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