xref: /netbsd-src/external/gpl3/binutils/dist/gas/config/tc-mn10200.c (revision 782713e6c126f1866c6d9cfdee4ceb49483b5828)
1 /* tc-mn10200.c -- Assembler code for the Matsushita 10200
2    Copyright (C) 1996-2022 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.  */
27 struct 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.  */
37 const char comment_chars[] = "#";
38 
39 /* Characters which start a comment at the beginning of a line.  */
40 const char line_comment_chars[] = ";#";
41 
42 /* Characters which may be used to separate multiple commands on a
43    single line.  */
44 const char line_separator_chars[] = ";";
45 
46 /* Characters which are used to indicate an exponent in a floating
47    point number.  */
48 const char EXP_CHARS[] = "eE";
49 
50 /* Characters which mean that a number is a floating point constant,
51    as in 0d1.0.  */
52 const char FLT_CHARS[] = "dD";
53 
54 const 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 
78 struct mn10200_fixup
79 {
80   expressionS exp;
81   int opindex;
82   bfd_reloc_code_real_type reloc;
83 };
84 
85 struct mn10200_fixup fixups[MAX_INSN_FIXUPS];
86 static int fc;
87 
88 const char *md_shortopts = "";
89 
90 struct option md_longopts[] =
91 {
92   {NULL, no_argument, NULL, 0}
93 };
94 
95 size_t md_longopts_size = sizeof (md_longopts);
96 
97 /* The target specific pseudo-ops which we support.  */
98 const pseudo_typeS md_pseudo_table[] =
99 {
100   { NULL,       NULL,           0 }
101 };
102 
103 /* Opcode hash table.  */
104 static htab_t mn10200_hash;
105 
106 /* This table is sorted. Suitable for searching by a binary search.  */
107 static 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 
117 static 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 
127 static 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 register name.  Returns the register
137    number from the array on success, or -1 on failure.  */
138 
139 static int
140 reg_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 
175 static bool
176 data_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 
219 static bool
220 address_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 
263 static bool
264 other_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 
297 void
298 md_show_usage (FILE *stream)
299 {
300   fprintf (stream, _("MN10200 options:\n\
301 none yet\n"));
302 }
303 
304 int
305 md_parse_option (int c ATTRIBUTE_UNUSED,
306 		 const char *arg ATTRIBUTE_UNUSED)
307 {
308   return 0;
309 }
310 
311 symbolS *
312 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
313 {
314   return 0;
315 }
316 
317 const char *
318 md_atof (int type, char *litp, int *sizep)
319 {
320   return ieee_md_atof (type, litp, sizep, false);
321 }
322 
323 void
324 md_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, fragP->fr_next, 0),
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, fragP->fr_next, 0),
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, fragP->fr_next, 0),
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, fragP->fr_next, 0),
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 
675 valueT
676 md_section_align (asection *seg, valueT addr)
677 {
678   int align = bfd_section_alignment (seg);
679   return ((addr + (1 << align) - 1) & -(1 << align));
680 }
681 
682 void
683 md_begin (void)
684 {
685   const char *prev_name = "";
686   const struct mn10200_opcode *op;
687 
688   mn10200_hash = str_htab_create ();
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 	  str_hash_insert (mn10200_hash, op->name, op, 0);
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 
712 static unsigned long
713 check_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 
747 arelent *
748 tc_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_subtract (fixp);
766     }
767 
768   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
769   if (reloc->howto == NULL)
770     {
771       as_bad_where (fixp->fx_file, fixp->fx_line,
772 		    _("reloc %d not supported by object file format"),
773 		    (int) fixp->fx_r_type);
774       return NULL;
775     }
776   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
777   reloc->sym_ptr_ptr = XNEW (asymbol *);
778   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
779   reloc->addend = fixp->fx_offset;
780   return reloc;
781 }
782 
783 int
784 md_estimate_size_before_relax (fragS *fragp, asection *seg)
785 {
786   if (fragp->fr_subtype == 6
787       && (!S_IS_DEFINED (fragp->fr_symbol)
788 	  || seg != S_GET_SEGMENT (fragp->fr_symbol)))
789     fragp->fr_subtype = 7;
790   else if (fragp->fr_subtype == 8
791 	   && (!S_IS_DEFINED (fragp->fr_symbol)
792 	       || seg != S_GET_SEGMENT (fragp->fr_symbol)))
793     fragp->fr_subtype = 10;
794 
795   if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
796     abort ();
797 
798   return md_relax_table[fragp->fr_subtype].rlx_length;
799 }
800 
801 long
802 md_pcrel_from (fixS *fixp)
803 {
804   return fixp->fx_frag->fr_address;
805 }
806 
807 void
808 md_apply_fix (fixS * fixP, valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
809 {
810   /* We shouldn't ever get here because linkrelax is nonzero.  */
811   abort ();
812   fixP->fx_done = 1;
813 }
814 
815 /* Insert an operand value into an instruction.  */
816 
817 static void
818 mn10200_insert_operand (unsigned long *insnp,
819 			unsigned long *extensionp,
820 			const struct mn10200_operand *operand,
821 			offsetT val,
822 			char *file,
823 			unsigned int line,
824 			unsigned int shift)
825 {
826   /* No need to check 24 or 32bit operands for a bit.  */
827   if (operand->bits < 24
828       && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
829     {
830       long min, max;
831       offsetT test;
832 
833       if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
834 	{
835 	  max = (1 << (operand->bits - 1)) - 1;
836 	  min = - (1 << (operand->bits - 1));
837 	}
838       else
839 	{
840 	  max = (1 << operand->bits) - 1;
841 	  min = 0;
842 	}
843 
844       test = val;
845 
846       if (test < (offsetT) min || test > (offsetT) max)
847 	as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line);
848     }
849 
850   if ((operand->flags & MN10200_OPERAND_EXTENDED) == 0)
851     {
852       *insnp |= (((long) val & ((1 << operand->bits) - 1))
853 		 << (operand->shift + shift));
854 
855       if ((operand->flags & MN10200_OPERAND_REPEATED) != 0)
856 	*insnp |= (((long) val & ((1 << operand->bits) - 1))
857 		   << (operand->shift + shift + 2));
858     }
859   else
860     {
861       *extensionp |= (val >> 16) & 0xff;
862       *insnp |= val & 0xffff;
863     }
864 }
865 
866 void
867 md_assemble (char *str)
868 {
869   char *s;
870   struct mn10200_opcode *opcode;
871   struct mn10200_opcode *next_opcode;
872   const unsigned char *opindex_ptr;
873   int next_opindex, relaxable;
874   unsigned long insn, extension, size = 0;
875   char *f;
876   int i;
877   int match;
878 
879   /* Get the opcode.  */
880   for (s = str; *s != '\0' && !ISSPACE (*s); s++)
881     ;
882   if (*s != '\0')
883     *s++ = '\0';
884 
885   /* Find the first opcode with the proper name.  */
886   opcode = (struct mn10200_opcode *) str_hash_find (mn10200_hash, str);
887   if (opcode == NULL)
888     {
889       as_bad (_("Unrecognized opcode: `%s'"), str);
890       return;
891     }
892 
893   str = s;
894   while (ISSPACE (*str))
895     ++str;
896 
897   input_line_pointer = str;
898 
899   for (;;)
900     {
901       const char *errmsg = NULL;
902       int op_idx;
903       char *hold;
904       int extra_shift = 0;
905 
906       relaxable = 0;
907       fc = 0;
908       match = 0;
909       next_opindex = 0;
910       insn = opcode->opcode;
911       extension = 0;
912       for (op_idx = 1, opindex_ptr = opcode->operands;
913 	   *opindex_ptr != 0;
914 	   opindex_ptr++, op_idx++)
915 	{
916 	  const struct mn10200_operand *operand;
917 	  expressionS ex;
918 
919 	  if (next_opindex == 0)
920 	    {
921 	      operand = &mn10200_operands[*opindex_ptr];
922 	    }
923 	  else
924 	    {
925 	      operand = &mn10200_operands[next_opindex];
926 	      next_opindex = 0;
927 	    }
928 
929 	  errmsg = NULL;
930 
931 	  while (*str == ' ' || *str == ',')
932 	    ++str;
933 
934 	  if (operand->flags & MN10200_OPERAND_RELAX)
935 	    relaxable = 1;
936 
937 	  /* Gather the operand.  */
938 	  hold = input_line_pointer;
939 	  input_line_pointer = str;
940 
941 	  if (operand->flags & MN10200_OPERAND_PAREN)
942 	    {
943 	      if (*input_line_pointer != ')' && *input_line_pointer != '(')
944 		{
945 		  input_line_pointer = hold;
946 		  str = hold;
947 		  goto error;
948 		}
949 	      input_line_pointer++;
950 	      goto keep_going;
951 	    }
952 	  /* See if we can match the operands.  */
953 	  else if (operand->flags & MN10200_OPERAND_DREG)
954 	    {
955 	      if (!data_register_name (&ex))
956 		{
957 		  input_line_pointer = hold;
958 		  str = hold;
959 		  goto error;
960 		}
961 	    }
962 	  else if (operand->flags & MN10200_OPERAND_AREG)
963 	    {
964 	      if (!address_register_name (&ex))
965 		{
966 		  input_line_pointer = hold;
967 		  str = hold;
968 		  goto error;
969 		}
970 	    }
971 	  else if (operand->flags & MN10200_OPERAND_PSW)
972 	    {
973 	      char *start;
974 	      char c = get_symbol_name (&start);
975 
976 	      if (strcmp (start, "psw") != 0)
977 		{
978 		  (void) restore_line_pointer (c);
979 		  input_line_pointer = hold;
980 		  str = hold;
981 		  goto error;
982 		}
983 	      (void) restore_line_pointer (c);
984 	      goto keep_going;
985 	    }
986 	  else if (operand->flags & MN10200_OPERAND_MDR)
987 	    {
988 	      char *start;
989 	      char c = get_symbol_name (&start);
990 
991 	      if (strcmp (start, "mdr") != 0)
992 		{
993 		  (void) restore_line_pointer (c);
994 		  input_line_pointer = hold;
995 		  str = hold;
996 		  goto error;
997 		}
998 	      (void) restore_line_pointer (c);
999 	      goto keep_going;
1000 	    }
1001 	  else if (data_register_name (&ex))
1002 	    {
1003 	      input_line_pointer = hold;
1004 	      str = hold;
1005 	      goto error;
1006 	    }
1007 	  else if (address_register_name (&ex))
1008 	    {
1009 	      input_line_pointer = hold;
1010 	      str = hold;
1011 	      goto error;
1012 	    }
1013 	  else if (other_register_name (&ex))
1014 	    {
1015 	      input_line_pointer = hold;
1016 	      str = hold;
1017 	      goto error;
1018 	    }
1019 	  else if (*str == ')' || *str == '(')
1020 	    {
1021 	      input_line_pointer = hold;
1022 	      str = hold;
1023 	      goto error;
1024 	    }
1025 	  else
1026 	    {
1027 	      expression (&ex);
1028 	    }
1029 
1030 	  switch (ex.X_op)
1031 	    {
1032 	    case O_illegal:
1033 	      errmsg = _("illegal operand");
1034 	      goto error;
1035 	    case O_absent:
1036 	      errmsg = _("missing operand");
1037 	      goto error;
1038 	    case O_register:
1039 	      if ((operand->flags
1040 		   & (MN10200_OPERAND_DREG | MN10200_OPERAND_AREG)) == 0)
1041 		{
1042 		  input_line_pointer = hold;
1043 		  str = hold;
1044 		  goto error;
1045 		}
1046 
1047 	      if (opcode->format == FMT_2 || opcode->format == FMT_5)
1048 		extra_shift = 8;
1049 	      else if (opcode->format == FMT_3 || opcode->format == FMT_6
1050 		       || opcode->format == FMT_7)
1051 		extra_shift = 16;
1052 	      else
1053 		extra_shift = 0;
1054 
1055 	      mn10200_insert_operand (&insn, &extension, operand,
1056 				      ex.X_add_number, NULL,
1057 				      0, extra_shift);
1058 
1059 	      break;
1060 
1061 	    case O_constant:
1062 	      /* If this operand can be promoted, and it doesn't
1063 		 fit into the allocated bitfield for this insn,
1064 		 then promote it (ie this opcode does not match).  */
1065 	      if (operand->flags
1066 		  & (MN10200_OPERAND_PROMOTE | MN10200_OPERAND_RELAX)
1067 		  && !check_operand (insn, operand, ex.X_add_number))
1068 		{
1069 		  input_line_pointer = hold;
1070 		  str = hold;
1071 		  goto error;
1072 		}
1073 
1074 	      mn10200_insert_operand (&insn, &extension, operand,
1075 				      ex.X_add_number, NULL,
1076 				      0, 0);
1077 	      break;
1078 
1079 	    default:
1080 	      /* If this operand can be promoted, then this opcode didn't
1081 		 match since we can't know if it needed promotion!  */
1082 	      if (operand->flags & MN10200_OPERAND_PROMOTE)
1083 		{
1084 		  input_line_pointer = hold;
1085 		  str = hold;
1086 		  goto error;
1087 		}
1088 
1089 	      /* We need to generate a fixup for this expression.  */
1090 	      if (fc >= MAX_INSN_FIXUPS)
1091 		as_fatal (_("too many fixups"));
1092 	      fixups[fc].exp = ex;
1093 	      fixups[fc].opindex = *opindex_ptr;
1094 	      fixups[fc].reloc = BFD_RELOC_UNUSED;
1095 	      ++fc;
1096 	      break;
1097 	    }
1098 
1099 	keep_going:
1100 	  str = input_line_pointer;
1101 	  input_line_pointer = hold;
1102 
1103 	  while (*str == ' ' || *str == ',')
1104 	    ++str;
1105 
1106 	}
1107 
1108       /* Make sure we used all the operands!  */
1109       if (*str != ',')
1110 	match = 1;
1111 
1112     error:
1113       if (match == 0)
1114 	{
1115 	  next_opcode = opcode + 1;
1116 	  if (!strcmp (next_opcode->name, opcode->name))
1117 	    {
1118 	      opcode = next_opcode;
1119 	      continue;
1120 	    }
1121 
1122 	  as_bad ("%s", errmsg);
1123 	  return;
1124 	}
1125       break;
1126     }
1127 
1128   while (ISSPACE (*str))
1129     ++str;
1130 
1131   if (*str != '\0')
1132     as_bad (_("junk at end of line: `%s'"), str);
1133 
1134   input_line_pointer = str;
1135 
1136   if (opcode->format == FMT_1)
1137     size = 1;
1138   else if (opcode->format == FMT_2 || opcode->format == FMT_4)
1139     size = 2;
1140   else if (opcode->format == FMT_3 || opcode->format == FMT_5)
1141     size = 3;
1142   else if (opcode->format == FMT_6)
1143     size = 4;
1144   else if (opcode->format == FMT_7)
1145     size = 5;
1146   else
1147     abort ();
1148 
1149   /* Write out the instruction.  */
1150   dwarf2_emit_insn (size);
1151   if (relaxable && fc > 0)
1152     {
1153       /* On a 64-bit host the size of an 'int' is not the same
1154 	 as the size of a pointer, so we need a union to convert
1155 	 the opindex field of the fr_cgen structure into a char *
1156 	 so that it can be stored in the frag.  We do not have
1157 	 to worry about losing accuracy as we are not going to
1158 	 be even close to the 32bit limit of the int.  */
1159       union
1160       {
1161 	int opindex;
1162 	char * ptr;
1163       }
1164       opindex_converter;
1165       int type;
1166 
1167       /* bCC  */
1168       if (size == 2 && opcode->opcode != 0xfc0000)
1169 	{
1170 	  /* Handle bra specially.  Basically treat it like jmp so
1171 	     that we automatically handle 8, 16 and 32 bit offsets
1172 	     correctly as well as jumps to an undefined address.
1173 
1174 	     It is also important to not treat it like other bCC
1175 	     instructions since the long forms of bra is different
1176 	     from other bCC instructions.  */
1177 	  if (opcode->opcode == 0xea00)
1178 	    type = 8;
1179 	  else
1180 	    type = 0;
1181 	}
1182       /* jsr  */
1183       else if (size == 3 && opcode->opcode == 0xfd0000)
1184 	type = 6;
1185       /* jmp  */
1186       else if (size == 3 && opcode->opcode == 0xfc0000)
1187 	type = 8;
1188       /* bCCx  */
1189       else
1190 	type = 3;
1191 
1192       opindex_converter.opindex = fixups[0].opindex;
1193       f = frag_var (rs_machine_dependent, 8, 8 - size, type,
1194 		    fixups[0].exp.X_add_symbol,
1195 		    fixups[0].exp.X_add_number,
1196 		    opindex_converter.ptr);
1197       number_to_chars_bigendian (f, insn, size);
1198       if (8 - size > 4)
1199 	{
1200 	  number_to_chars_bigendian (f + size, 0, 4);
1201 	  number_to_chars_bigendian (f + size + 4, 0, 8 - size - 4);
1202 	}
1203       else
1204 	number_to_chars_bigendian (f + size, 0, 8 - size);
1205     }
1206   else
1207     {
1208       f = frag_more (size);
1209 
1210       /* Oh, what a mess.  The instruction is in big endian format, but
1211 	 16 and 24bit immediates are little endian!  */
1212       if (opcode->format == FMT_3)
1213 	{
1214 	  number_to_chars_bigendian (f, (insn >> 16) & 0xff, 1);
1215 	  number_to_chars_littleendian (f + 1, insn & 0xffff, 2);
1216 	}
1217       else if (opcode->format == FMT_6)
1218 	{
1219 	  number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1220 	  number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1221 	}
1222       else if (opcode->format == FMT_7)
1223 	{
1224 	  number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1225 	  number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1226 	  number_to_chars_littleendian (f + 4, extension & 0xff, 1);
1227 	}
1228       else
1229 	number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);
1230 
1231       /* Create any fixups.  */
1232       for (i = 0; i < fc; i++)
1233 	{
1234 	  const struct mn10200_operand *operand;
1235 	  int reloc_size;
1236 
1237 	  operand = &mn10200_operands[fixups[i].opindex];
1238 	  if (fixups[i].reloc != BFD_RELOC_UNUSED)
1239 	    {
1240 	      reloc_howto_type *reloc_howto;
1241 	      int offset;
1242 	      fixS *fixP;
1243 
1244 	      reloc_howto = bfd_reloc_type_lookup (stdoutput,
1245 						   fixups[i].reloc);
1246 
1247 	      if (!reloc_howto)
1248 		abort ();
1249 
1250 	      reloc_size = bfd_get_reloc_size (reloc_howto);
1251 
1252 	      if (reloc_size < 1 || reloc_size > 4)
1253 		abort ();
1254 
1255 	      offset = 4 - reloc_size;
1256 	      fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1257 				  reloc_size,
1258 				  &fixups[i].exp,
1259 				  reloc_howto->pc_relative,
1260 				  fixups[i].reloc);
1261 
1262 	      /* PC-relative offsets are from the first byte of the
1263 		 next instruction, not from the start of the current
1264 		 instruction.  */
1265 	      if (reloc_howto->pc_relative)
1266 		fixP->fx_offset += reloc_size;
1267 	    }
1268 	  else
1269 	    {
1270 	      int reloc, pcrel, offset;
1271 	      fixS *fixP;
1272 
1273 	      reloc = BFD_RELOC_NONE;
1274 	      /* How big is the reloc?  Remember SPLIT relocs are
1275 		 implicitly 32bits.  */
1276 	      reloc_size = operand->bits;
1277 
1278 	      offset = size - reloc_size / 8;
1279 
1280 	      /* Is the reloc pc-relative?  */
1281 	      pcrel = (operand->flags & MN10200_OPERAND_PCREL) != 0;
1282 
1283 	      /* Choose a proper BFD relocation type.  */
1284 	      if (pcrel)
1285 		{
1286 		  if (reloc_size == 8)
1287 		    reloc = BFD_RELOC_8_PCREL;
1288 		  else if (reloc_size == 24)
1289 		    reloc = BFD_RELOC_24_PCREL;
1290 		  else
1291 		    abort ();
1292 		}
1293 	      else
1294 		{
1295 		  if (reloc_size == 32)
1296 		    reloc = BFD_RELOC_32;
1297 		  else if (reloc_size == 16)
1298 		    reloc = BFD_RELOC_16;
1299 		  else if (reloc_size == 8)
1300 		    reloc = BFD_RELOC_8;
1301 		  else if (reloc_size == 24)
1302 		    reloc = BFD_RELOC_24;
1303 		  else
1304 		    abort ();
1305 		}
1306 
1307 	      /* Convert the size of the reloc into what fix_new_exp
1308                  wants.  */
1309 	      reloc_size = reloc_size / 8;
1310 	      if (reloc_size == 8)
1311 		reloc_size = 0;
1312 	      else if (reloc_size == 16)
1313 		reloc_size = 1;
1314 	      else if (reloc_size == 32 || reloc_size == 24)
1315 		reloc_size = 2;
1316 
1317 	      fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1318 				  reloc_size, &fixups[i].exp, pcrel,
1319 				  ((bfd_reloc_code_real_type) reloc));
1320 
1321 	      /* PC-relative offsets are from the first byte of the
1322 		 next instruction, not from the start of the current
1323 		 instruction.  */
1324 	      if (pcrel)
1325 		fixP->fx_offset += size;
1326 	    }
1327 	}
1328     }
1329 }
1330