This commit was manufactured by cvs2svn to create branch
[external/binutils.git] / gas / config / tc-mn10200.c
1 /* tc-mn10200.c -- Assembler code for the Matsushita 10200
2    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
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 \f
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 \f
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 \f
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
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
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
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
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
316 md_show_usage (stream)
317      FILE *stream;
318 {
319   fprintf (stream, _("MN10200 options:\n\
320 none yet\n"));
321 }
322
323 int
324 md_parse_option (c, arg)
325      int c ATTRIBUTE_UNUSED;
326      char *arg ATTRIBUTE_UNUSED;
327 {
328   return 0;
329 }
330
331 symbolS *
332 md_undefined_symbol (name)
333      char *name ATTRIBUTE_UNUSED;
334 {
335   return 0;
336 }
337
338 char *
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
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
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
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
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 *
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       /* FIXME: We should resolve difference expressions if possible
1239          here.  At least this is better than silently ignoring the
1240          subtrahend.  */
1241       as_bad_where (fixp->fx_file, fixp->fx_line,
1242                     _("can't resolve `%s' {%s section} - `%s' {%s section}"),
1243                     fixp->fx_addsy ? S_GET_NAME (fixp->fx_addsy) : "0",
1244                     segment_name (fixp->fx_addsy
1245                                   ? S_GET_SEGMENT (fixp->fx_addsy)
1246                                   : absolute_section),
1247                     S_GET_NAME (fixp->fx_subsy),
1248                     segment_name (S_GET_SEGMENT (fixp->fx_addsy)));
1249     }
1250
1251   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1252   if (reloc->howto == (reloc_howto_type *) NULL)
1253     {
1254       as_bad_where (fixp->fx_file, fixp->fx_line,
1255                     _("reloc %d not supported by object file format"),
1256                     (int) fixp->fx_r_type);
1257       return NULL;
1258     }
1259   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1260   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1261   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1262   reloc->addend = fixp->fx_offset;
1263   return reloc;
1264 }
1265
1266 int
1267 md_estimate_size_before_relax (fragp, seg)
1268      fragS *fragp;
1269      asection *seg;
1270 {
1271   if (fragp->fr_subtype == 6
1272       && (!S_IS_DEFINED (fragp->fr_symbol)
1273           || seg != S_GET_SEGMENT (fragp->fr_symbol)))
1274     fragp->fr_subtype = 7;
1275   else if (fragp->fr_subtype == 8
1276            && (!S_IS_DEFINED (fragp->fr_symbol)
1277                || seg != S_GET_SEGMENT (fragp->fr_symbol)))
1278     fragp->fr_subtype = 10;
1279
1280   if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
1281     abort ();
1282
1283   return md_relax_table[fragp->fr_subtype].rlx_length;
1284 }
1285
1286 long
1287 md_pcrel_from (fixp)
1288      fixS *fixp;
1289 {
1290   return fixp->fx_frag->fr_address;
1291 #if 0
1292   if (fixp->fx_addsy != (symbolS *) NULL && !S_IS_DEFINED (fixp->fx_addsy))
1293     {
1294       /* The symbol is undefined.  Let the linker figure it out.  */
1295       return 0;
1296     }
1297   return fixp->fx_frag->fr_address + fixp->fx_where;
1298 #endif
1299 }
1300
1301 void
1302 md_apply_fix3 (fixP, valP, seg)
1303      fixS * fixP;
1304      valueT * valP ATTRIBUTE_UNUSED;
1305      segT seg ATTRIBUTE_UNUSED;
1306 {
1307   /* We shouldn't ever get here because linkrelax is nonzero.  */
1308   abort ();
1309   fixP->fx_done = 1;
1310 }
1311
1312 /* Insert an operand value into an instruction.  */
1313
1314 static void
1315 mn10200_insert_operand (insnp, extensionp, operand, val, file, line, shift)
1316      unsigned long *insnp;
1317      unsigned long *extensionp;
1318      const struct mn10200_operand *operand;
1319      offsetT val;
1320      char *file;
1321      unsigned int line;
1322      unsigned int shift;
1323 {
1324   /* No need to check 24 or 32bit operands for a bit.  */
1325   if (operand->bits < 24
1326       && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
1327     {
1328       long min, max;
1329       offsetT test;
1330
1331       if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
1332         {
1333           max = (1 << (operand->bits - 1)) - 1;
1334           min = - (1 << (operand->bits - 1));
1335         }
1336       else
1337         {
1338           max = (1 << operand->bits) - 1;
1339           min = 0;
1340         }
1341
1342       test = val;
1343
1344       if (test < (offsetT) min || test > (offsetT) max)
1345         {
1346           const char *err =
1347             _("operand out of range (%s not between %ld and %ld)");
1348           char buf[100];
1349
1350           sprint_value (buf, test);
1351           if (file == (char *) NULL)
1352             as_warn (err, buf, min, max);
1353           else
1354             as_warn_where (file, line, err, buf, min, max);
1355         }
1356     }
1357
1358   if ((operand->flags & MN10200_OPERAND_EXTENDED) == 0)
1359     {
1360       *insnp |= (((long) val & ((1 << operand->bits) - 1))
1361                  << (operand->shift + shift));
1362
1363       if ((operand->flags & MN10200_OPERAND_REPEATED) != 0)
1364         *insnp |= (((long) val & ((1 << operand->bits) - 1))
1365                    << (operand->shift + shift + 2));
1366     }
1367   else
1368     {
1369       *extensionp |= (val >> 16) & 0xff;
1370       *insnp |= val & 0xffff;
1371     }
1372 }
1373
1374 static unsigned long
1375 check_operand (insn, operand, val)
1376      unsigned long insn ATTRIBUTE_UNUSED;
1377      const struct mn10200_operand *operand;
1378      offsetT val;
1379 {
1380   /* No need to check 24bit or 32bit operands for a bit.  */
1381   if (operand->bits < 24
1382       && (operand->flags & MN10200_OPERAND_NOCHECK) == 0)
1383     {
1384       long min, max;
1385       offsetT test;
1386
1387       if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
1388         {
1389           max = (1 << (operand->bits - 1)) - 1;
1390           min = - (1 << (operand->bits - 1));
1391         }
1392       else
1393         {
1394           max = (1 << operand->bits) - 1;
1395           min = 0;
1396         }
1397
1398       test = val;
1399
1400       if (test < (offsetT) min || test > (offsetT) max)
1401         return 0;
1402       else
1403         return 1;
1404     }
1405   return 1;
1406 }