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