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