* config/tc-mn10300.c (r_registers): Add a0-a3,d0-d3 and e0-e7
[external/binutils.git] / gas / config / tc-mn10300.c
1 /* tc-mn10300.c -- Assembler code for the Matsushita 10300
2
3    Copyright (C) 1996, 1997, 1998 Free Software Foundation.
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 <ctype.h>
24 #include "as.h"
25 #include "subsegs.h"     
26 #include "opcode/mn10300.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 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
56 const relax_typeS md_relax_table[] = {
57   /* bCC relaxing */
58   {0x7f, -0x80, 2, 1},
59   {0x7fff, -0x8000, 5, 2},
60   {0x7fffffff, -0x80000000, 7, 0},
61
62   /* bCC relaxing (uncommon cases) */
63   {0x7f, -0x80, 3, 4},
64   {0x7fff, -0x8000, 6, 5},
65   {0x7fffffff, -0x80000000, 8, 0},
66
67   /* call relaxing */
68   {0x7fff, -0x8000, 5, 7},
69   {0x7fffffff, -0x80000000, 7, 0},
70
71   /* calls relaxing */
72   {0x7fff, -0x8000, 4, 9},
73   {0x7fffffff, -0x80000000, 6, 0},
74
75   /* jmp relaxing */
76   {0x7f, -0x80, 2, 11},
77   {0x7fff, -0x8000, 3, 12},
78   {0x7fffffff, -0x80000000, 5, 0},
79
80 };
81
82 /* local functions */
83 static void mn10300_insert_operand PARAMS ((unsigned long *, unsigned long *,
84                                             const struct mn10300_operand *,
85                                             offsetT, char *, unsigned,
86                                             unsigned));
87 static unsigned long check_operand PARAMS ((unsigned long,
88                                             const struct mn10300_operand *,
89                                             offsetT));
90 static int reg_name_search PARAMS ((const struct reg_name *, int, const char *));
91 static boolean data_register_name PARAMS ((expressionS *expressionP));
92 static boolean address_register_name PARAMS ((expressionS *expressionP));
93 static boolean other_register_name PARAMS ((expressionS *expressionP));
94
95
96 /* fixups */
97 #define MAX_INSN_FIXUPS (5)
98 struct mn10300_fixup
99 {
100   expressionS exp;
101   int opindex;
102   bfd_reloc_code_real_type reloc;
103 };
104 struct mn10300_fixup fixups[MAX_INSN_FIXUPS];
105 static int fc;
106 \f
107 const char *md_shortopts = "";
108 struct option md_longopts[] = {
109   {NULL, no_argument, NULL, 0}
110 };
111 size_t md_longopts_size = sizeof(md_longopts); 
112
113 /* The target specific pseudo-ops which we support.  */
114 const pseudo_typeS md_pseudo_table[] =
115 {
116   { NULL,       NULL,           0 }
117 };
118
119 /* Opcode hash table.  */
120 static struct hash_control *mn10300_hash;
121
122 /* This table is sorted. Suitable for searching by a binary search. */
123 static const struct reg_name data_registers[] =
124 {
125   { "d0", 0 },
126   { "d1", 1 },
127   { "d2", 2 },
128   { "d3", 3 },
129 };
130 #define DATA_REG_NAME_CNT       (sizeof(data_registers) / sizeof(struct reg_name))
131
132 static const struct reg_name address_registers[] =
133 {
134   { "a0", 0 },
135   { "a1", 1 },
136   { "a2", 2 },
137   { "a3", 3 },
138 };
139 #define ADDRESS_REG_NAME_CNT    (sizeof(address_registers) / sizeof(struct reg_name))
140
141 /* start-sanitize-am33 */
142 static const struct reg_name r_registers[] =
143 {
144   { "a0", 8 },
145   { "a1", 9 },
146   { "a2", 10 },
147   { "a3", 11 },
148   { "a0", 12 },
149   { "d1", 13 },
150   { "d2", 14 },
151   { "d3", 15 },
152   { "e0", 0 },
153   { "e1", 1 },
154   { "e2", 2 },
155   { "e3", 3 },
156   { "e4", 4 },
157   { "e5", 5 },
158   { "e6", 6 },
159   { "e7", 7 },
160   { "e8", 8 },
161   { "e9", 9 },
162   { "r0", 0 },
163   { "r1", 1 },
164   { "r10", 10 },
165   { "r11", 11 },
166   { "r12", 12 },
167   { "r13", 13 },
168   { "r14", 14 },
169   { "r15", 15 },
170   { "r2", 2 },
171   { "r3", 3 },
172   { "r4", 4 },
173   { "r5", 5 },
174   { "r6", 6 },
175   { "r7", 7 },
176   { "r8", 8 },
177   { "r9", 9 },
178 };
179 #define R_REG_NAME_CNT  (sizeof(r_registers) / sizeof(struct reg_name))
180
181 static const struct reg_name xr_registers[] =
182 {
183   { "mcrh", 2 },
184   { "mcrl", 3 },
185   { "mcvf", 4 },
186   { "mdrq", 1 },
187   { "sp", 0 },
188   { "xr0", 0 },
189   { "xr1", 1 },
190   { "xr10", 10 },
191   { "xr11", 11 },
192   { "xr12", 12 },
193   { "xr13", 13 },
194   { "xr14", 14 },
195   { "xr15", 15 },
196   { "xr2", 2 },
197   { "xr3", 3 },
198   { "xr4", 4 },
199   { "xr5", 5 },
200   { "xr6", 6 },
201   { "xr7", 7 },
202   { "xr8", 8 },
203   { "xr9", 9 },
204 };
205 #define XR_REG_NAME_CNT (sizeof(xr_registers) / sizeof(struct reg_name))
206
207 /* end-sanitize-am33 */
208
209 static const struct reg_name other_registers[] =
210 {
211   { "mdr", 0 },
212   { "psw", 0 },
213   { "sp", 0 },
214 };
215 #define OTHER_REG_NAME_CNT      (sizeof(other_registers) / sizeof(struct reg_name))
216
217 /* reg_name_search does a binary search of the given register table
218    to see if "name" is a valid regiter name.  Returns the register
219    number from the array on success, or -1 on failure. */
220
221 static int
222 reg_name_search (regs, regcount, name)
223      const struct reg_name *regs;
224      int regcount;
225      const char *name;
226 {
227   int middle, low, high;
228   int cmp;
229
230   low = 0;
231   high = regcount - 1;
232
233   do
234     {
235       middle = (low + high) / 2;
236       cmp = strcasecmp (name, regs[middle].name);
237       if (cmp < 0)
238         high = middle - 1;
239       else if (cmp > 0)
240         low = middle + 1;
241       else 
242           return regs[middle].value;
243     }
244   while (low <= high);
245   return -1;
246 }
247
248
249 /* start-sanitize-am33 */
250 /* Summary of register_name().
251  *
252  * in: Input_line_pointer points to 1st char of operand.
253  *
254  * out: A expressionS.
255  *      The operand may have been a register: in this case, X_op == O_register,
256  *      X_add_number is set to the register number, and truth is returned.
257  *      Input_line_pointer->(next non-blank) char after operand, or is in
258  *      its original state.
259  */
260 static boolean
261 r_register_name (expressionP)
262      expressionS *expressionP;
263 {
264   int reg_number;
265   char *name;
266   char *start;
267   char c;
268
269   /* Find the spelling of the operand */
270   start = name = input_line_pointer;
271
272   c = get_symbol_end ();
273   reg_number = reg_name_search (r_registers, R_REG_NAME_CNT, name);
274
275   /* look to see if it's in the register table */
276   if (reg_number >= 0) 
277     {
278       expressionP->X_op = O_register;
279       expressionP->X_add_number = reg_number;
280
281       /* make the rest nice */
282       expressionP->X_add_symbol = NULL;
283       expressionP->X_op_symbol = NULL;
284       *input_line_pointer = c;  /* put back the delimiting char */
285       return true;
286     }
287   else
288     {
289       /* reset the line as if we had not done anything */
290       *input_line_pointer = c;   /* put back the delimiting char */
291       input_line_pointer = start; /* reset input_line pointer */
292       return false;
293     }
294 }
295
296 /* Summary of register_name().
297  *
298  * in: Input_line_pointer points to 1st char of operand.
299  *
300  * out: A expressionS.
301  *      The operand may have been a register: in this case, X_op == O_register,
302  *      X_add_number is set to the register number, and truth is returned.
303  *      Input_line_pointer->(next non-blank) char after operand, or is in
304  *      its original state.
305  */
306 static boolean
307 xr_register_name (expressionP)
308      expressionS *expressionP;
309 {
310   int reg_number;
311   char *name;
312   char *start;
313   char c;
314
315   /* Find the spelling of the operand */
316   start = name = input_line_pointer;
317
318   c = get_symbol_end ();
319   reg_number = reg_name_search (xr_registers, XR_REG_NAME_CNT, name);
320
321   /* look to see if it's in the register table */
322   if (reg_number >= 0) 
323     {
324       expressionP->X_op = O_register;
325       expressionP->X_add_number = reg_number;
326
327       /* make the rest nice */
328       expressionP->X_add_symbol = NULL;
329       expressionP->X_op_symbol = NULL;
330       *input_line_pointer = c;  /* put back the delimiting char */
331       return true;
332     }
333   else
334     {
335       /* reset the line as if we had not done anything */
336       *input_line_pointer = c;   /* put back the delimiting char */
337       input_line_pointer = start; /* reset input_line pointer */
338       return false;
339     }
340 }
341 /* end-sanitize-am33 */
342
343 /* Summary of register_name().
344  *
345  * in: Input_line_pointer points to 1st char of operand.
346  *
347  * out: A expressionS.
348  *      The operand may have been a register: in this case, X_op == O_register,
349  *      X_add_number is set to the register number, and truth is returned.
350  *      Input_line_pointer->(next non-blank) char after operand, or is in
351  *      its original state.
352  */
353 static boolean
354 data_register_name (expressionP)
355      expressionS *expressionP;
356 {
357   int reg_number;
358   char *name;
359   char *start;
360   char c;
361
362   /* Find the spelling of the operand */
363   start = name = input_line_pointer;
364
365   c = get_symbol_end ();
366   reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);
367
368   /* look to see if it's in the register table */
369   if (reg_number >= 0) 
370     {
371       expressionP->X_op = O_register;
372       expressionP->X_add_number = reg_number;
373
374       /* make the rest nice */
375       expressionP->X_add_symbol = NULL;
376       expressionP->X_op_symbol = NULL;
377       *input_line_pointer = c;  /* put back the delimiting char */
378       return true;
379     }
380   else
381     {
382       /* reset the line as if we had not done anything */
383       *input_line_pointer = c;   /* put back the delimiting char */
384       input_line_pointer = start; /* reset input_line pointer */
385       return false;
386     }
387 }
388
389 /* Summary of register_name().
390  *
391  * in: Input_line_pointer points to 1st char of operand.
392  *
393  * out: A expressionS.
394  *      The operand may have been a register: in this case, X_op == O_register,
395  *      X_add_number is set to the register number, and truth is returned.
396  *      Input_line_pointer->(next non-blank) char after operand, or is in
397  *      its original state.
398  */
399 static boolean
400 address_register_name (expressionP)
401      expressionS *expressionP;
402 {
403   int reg_number;
404   char *name;
405   char *start;
406   char c;
407
408   /* Find the spelling of the operand */
409   start = name = input_line_pointer;
410
411   c = get_symbol_end ();
412   reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);
413
414   /* look to see if it's in the register table */
415   if (reg_number >= 0) 
416     {
417       expressionP->X_op = O_register;
418       expressionP->X_add_number = reg_number;
419
420       /* make the rest nice */
421       expressionP->X_add_symbol = NULL;
422       expressionP->X_op_symbol = NULL;
423       *input_line_pointer = c;  /* put back the delimiting char */
424       return true;
425     }
426   else
427     {
428       /* reset the line as if we had not done anything */
429       *input_line_pointer = c;   /* put back the delimiting char */
430       input_line_pointer = start; /* reset input_line pointer */
431       return false;
432     }
433 }
434
435 /* Summary of register_name().
436  *
437  * in: Input_line_pointer points to 1st char of operand.
438  *
439  * out: A expressionS.
440  *      The operand may have been a register: in this case, X_op == O_register,
441  *      X_add_number is set to the register number, and truth is returned.
442  *      Input_line_pointer->(next non-blank) char after operand, or is in
443  *      its original state.
444  */
445 static boolean
446 other_register_name (expressionP)
447      expressionS *expressionP;
448 {
449   int reg_number;
450   char *name;
451   char *start;
452   char c;
453
454   /* Find the spelling of the operand */
455   start = name = input_line_pointer;
456
457   c = get_symbol_end ();
458   reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);
459
460   /* look to see if it's in the register table */
461   if (reg_number >= 0) 
462     {
463       expressionP->X_op = O_register;
464       expressionP->X_add_number = reg_number;
465
466       /* make the rest nice */
467       expressionP->X_add_symbol = NULL;
468       expressionP->X_op_symbol = NULL;
469       *input_line_pointer = c;  /* put back the delimiting char */
470       return true;
471     }
472   else
473     {
474       /* reset the line as if we had not done anything */
475       *input_line_pointer = c;   /* put back the delimiting char */
476       input_line_pointer = start; /* reset input_line pointer */
477       return false;
478     }
479 }
480
481 void
482 md_show_usage (stream)
483   FILE *stream;
484 {
485   fprintf(stream, _("MN10300 options:\n\
486 none yet\n"));
487
488
489 int
490 md_parse_option (c, arg)
491      int c;
492      char *arg;
493 {
494   return 0;
495 }
496
497 symbolS *
498 md_undefined_symbol (name)
499   char *name;
500 {
501   return 0;
502 }
503
504 char *
505 md_atof (type, litp, sizep)
506   int type;
507   char *litp;
508   int *sizep;
509 {
510   int prec;
511   LITTLENUM_TYPE words[4];
512   char *t;
513   int i;
514
515   switch (type)
516     {
517     case 'f':
518       prec = 2;
519       break;
520
521     case 'd':
522       prec = 4;
523       break;
524
525     default:
526       *sizep = 0;
527       return "bad call to md_atof";
528     }
529   
530   t = atof_ieee (input_line_pointer, type, words);
531   if (t)
532     input_line_pointer = t;
533
534   *sizep = prec * 2;
535
536   for (i = prec - 1; i >= 0; i--)
537     {
538       md_number_to_chars (litp, (valueT) words[i], 2);
539       litp += 2;
540     }
541
542   return NULL;
543 }
544
545
546 void
547 md_convert_frag (abfd, sec, fragP)
548   bfd *abfd;
549   asection *sec;
550   fragS *fragP;
551 {
552   static unsigned long label_count = 0;
553   char buf[40];
554
555   subseg_change (sec, 0);
556   if (fragP->fr_subtype == 0)
557     {
558       fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
559                fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL);
560       fragP->fr_var = 0;
561       fragP->fr_fix += 2;
562     }
563   else if (fragP->fr_subtype == 1)
564     {
565       /* Reverse the condition of the first branch.  */
566       int offset = fragP->fr_fix;
567       int opcode = fragP->fr_literal[offset] & 0xff;
568
569       switch (opcode)
570         {
571         case 0xc8:
572           opcode = 0xc9;
573           break;
574         case 0xc9:
575           opcode = 0xc8;
576           break;
577         case 0xc0:
578           opcode = 0xc2;
579           break;
580         case 0xc2:
581           opcode = 0xc0;
582           break;
583         case 0xc3:
584           opcode = 0xc1;
585           break;
586         case 0xc1:
587           opcode = 0xc3;
588           break;
589         case 0xc4:
590           opcode = 0xc6;
591           break;
592         case 0xc6:
593           opcode = 0xc4;
594           break;
595         case 0xc7:
596           opcode = 0xc5;
597           break;
598         case 0xc5:
599           opcode = 0xc7;
600           break;
601         default:
602           abort ();
603         }
604       fragP->fr_literal[offset] = opcode;
605
606       /* Create a fixup for the reversed conditional branch.  */
607       sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
608       fix_new (fragP, fragP->fr_fix + 1, 1,
609                symbol_new (buf, sec, 0, fragP->fr_next),
610                fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL);
611
612       /* Now create the unconditional branch + fixup to the
613          final target.  */
614       fragP->fr_literal[offset + 2] = 0xcc;
615       fix_new (fragP, fragP->fr_fix + 3, 2, fragP->fr_symbol,
616                fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL);
617       fragP->fr_var = 0;
618       fragP->fr_fix += 5;
619     }
620   else if (fragP->fr_subtype == 2)
621     {
622       /* Reverse the condition of the first branch.  */
623       int offset = fragP->fr_fix;
624       int opcode = fragP->fr_literal[offset] & 0xff;
625
626       switch (opcode)
627         {
628         case 0xc8:
629           opcode = 0xc9;
630           break;
631         case 0xc9:
632           opcode = 0xc8;
633           break;
634         case 0xc0:
635           opcode = 0xc2;
636           break;
637         case 0xc2:
638           opcode = 0xc0;
639           break;
640         case 0xc3:
641           opcode = 0xc1;
642           break;
643         case 0xc1:
644           opcode = 0xc3;
645           break;
646         case 0xc4:
647           opcode = 0xc6;
648           break;
649         case 0xc6:
650           opcode = 0xc4;
651           break;
652         case 0xc7:
653           opcode = 0xc5;
654           break;
655         case 0xc5:
656           opcode = 0xc7;
657           break;
658         default:
659           abort ();
660         }
661       fragP->fr_literal[offset] = opcode;
662
663       /* Create a fixup for the reversed conditional branch.  */
664       sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
665       fix_new (fragP, fragP->fr_fix + 1, 1,
666                symbol_new (buf, sec, 0, fragP->fr_next),
667                fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL);
668
669       /* Now create the unconditional branch + fixup to the
670          final target.  */
671       fragP->fr_literal[offset + 2] = 0xdc;
672       fix_new (fragP, fragP->fr_fix + 3, 4, fragP->fr_symbol,
673                fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL);
674       fragP->fr_var = 0;
675       fragP->fr_fix += 7;
676     }
677   else if (fragP->fr_subtype == 3)
678     {
679       fix_new (fragP, fragP->fr_fix + 2, 1, fragP->fr_symbol,
680                fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL);
681       fragP->fr_var = 0;
682       fragP->fr_fix += 3;
683     }
684   else if (fragP->fr_subtype == 4)
685     {
686       /* Reverse the condition of the first branch.  */
687       int offset = fragP->fr_fix;
688       int opcode = fragP->fr_literal[offset + 1] & 0xff;
689
690       switch (opcode)
691         {
692         case 0xe8:
693           opcode = 0xe9;
694           break;
695         case 0xe9:
696           opcode = 0xe8;
697           break;
698         case 0xea:
699           opcode = 0xeb;
700           break;
701         case 0xeb:
702           opcode = 0xea;
703           break;
704         default:
705           abort ();
706         }
707       fragP->fr_literal[offset + 1] = opcode;
708
709       /* Create a fixup for the reversed conditional branch.  */
710       sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
711       fix_new (fragP, fragP->fr_fix + 2, 1,
712                symbol_new (buf, sec, 0, fragP->fr_next),
713                fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL);
714
715       /* Now create the unconditional branch + fixup to the
716          final target.  */
717       fragP->fr_literal[offset + 3] = 0xcc;
718       fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol,
719                fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL);
720       fragP->fr_var = 0;
721       fragP->fr_fix += 6;
722     }
723   else if (fragP->fr_subtype == 5)
724     {
725       /* Reverse the condition of the first branch.  */
726       int offset = fragP->fr_fix;
727       int opcode = fragP->fr_literal[offset + 1] & 0xff;
728
729       switch (opcode)
730         {
731         case 0xe8:
732           opcode = 0xe9;
733           break;
734         case 0xea:
735           opcode = 0xeb;
736           break;
737         case 0xeb:
738           opcode = 0xea;
739           break;
740         default:
741           abort ();
742         }
743       fragP->fr_literal[offset + 1] = opcode;
744
745       /* Create a fixup for the reversed conditional branch.  */
746       sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++);
747       fix_new (fragP, fragP->fr_fix + 2, 1,
748                symbol_new (buf, sec, 0, fragP->fr_next),
749                fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL);
750
751       /* Now create the unconditional branch + fixup to the
752          final target.  */
753       fragP->fr_literal[offset + 3] = 0xdc;
754       fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
755                fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL);
756       fragP->fr_var = 0;
757       fragP->fr_fix += 8;
758     }
759   else if (fragP->fr_subtype == 6)
760     {
761       int offset = fragP->fr_fix;
762       fragP->fr_literal[offset] = 0xcd;
763       fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol,
764                fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL);
765       fragP->fr_var = 0;
766       fragP->fr_fix += 5;
767     }
768   else if (fragP->fr_subtype == 7)
769     {
770       int offset = fragP->fr_fix;
771       fragP->fr_literal[offset] = 0xdd;
772       fragP->fr_literal[offset + 5] = fragP->fr_literal[offset + 3];
773       fragP->fr_literal[offset + 6] = fragP->fr_literal[offset + 4];
774
775       fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
776                fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL);
777       fragP->fr_var = 0;
778       fragP->fr_fix += 7;
779     }
780   else if (fragP->fr_subtype == 8)
781     {
782       int offset = fragP->fr_fix;
783       fragP->fr_literal[offset] = 0xfa;
784       fragP->fr_literal[offset + 1] = 0xff;
785       fix_new (fragP, fragP->fr_fix + 2, 2, fragP->fr_symbol,
786                fragP->fr_offset + 2, 1, BFD_RELOC_16_PCREL);
787       fragP->fr_var = 0;
788       fragP->fr_fix += 4;
789     }
790   else if (fragP->fr_subtype == 9)
791     {
792       int offset = fragP->fr_fix;
793       fragP->fr_literal[offset] = 0xfc;
794       fragP->fr_literal[offset + 1] = 0xff;
795
796       fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
797                fragP->fr_offset + 2, 1, BFD_RELOC_32_PCREL);
798       fragP->fr_var = 0;
799       fragP->fr_fix += 6;
800     }
801   else if (fragP->fr_subtype == 10)
802     {
803       fragP->fr_literal[fragP->fr_fix] = 0xca;
804       fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol,
805                fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL);
806       fragP->fr_var = 0;
807       fragP->fr_fix += 2;
808     }
809   else if (fragP->fr_subtype == 11)
810     {
811       int offset = fragP->fr_fix;
812       fragP->fr_literal[offset] = 0xcc;
813
814       fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
815                fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL);
816       fragP->fr_var = 0;
817       fragP->fr_fix += 3;
818     }
819   else if (fragP->fr_subtype == 12)
820     {
821       int offset = fragP->fr_fix;
822       fragP->fr_literal[offset] = 0xdc;
823
824       fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
825                fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL);
826       fragP->fr_var = 0;
827       fragP->fr_fix += 5;
828     }
829   else
830     abort ();
831 }
832
833 valueT
834 md_section_align (seg, addr)
835      asection *seg;
836      valueT addr;
837 {
838   int align = bfd_get_section_alignment (stdoutput, seg);
839   return ((addr + (1 << align) - 1) & (-1 << align));
840 }
841
842 void
843 md_begin ()
844 {
845   char *prev_name = "";
846   register const struct mn10300_opcode *op;
847
848   mn10300_hash = hash_new();
849
850   /* Insert unique names into hash table.  The MN10300 instruction set
851      has many identical opcode names that have different opcodes based
852      on the operands.  This hash table then provides a quick index to
853      the first opcode with a particular name in the opcode table.  */
854
855   op = mn10300_opcodes;
856   while (op->name)
857     {
858       if (strcmp (prev_name, op->name)) 
859         {
860           prev_name = (char *) op->name;
861           hash_insert (mn10300_hash, op->name, (char *) op);
862         }
863       op++;
864     }
865
866   /* This is both a simplification (we don't have to write md_apply_fix)
867      and support for future optimizations (branch shortening and similar
868      stuff in the linker.  */
869   linkrelax = 1;
870 }
871
872 void
873 md_assemble (str) 
874      char *str;
875 {
876   char *s;
877   struct mn10300_opcode *opcode;
878   struct mn10300_opcode *next_opcode;
879   const unsigned char *opindex_ptr;
880   int next_opindex, relaxable;
881   unsigned long insn, extension, size = 0;
882   char *f;
883   int i;
884   int match;
885
886   /* Get the opcode.  */
887   for (s = str; *s != '\0' && ! isspace (*s); s++)
888     ;
889   if (*s != '\0')
890     *s++ = '\0';
891
892   /* find the first opcode with the proper name */
893   opcode = (struct mn10300_opcode *)hash_find (mn10300_hash, str);
894   if (opcode == NULL)
895     {
896       as_bad (_("Unrecognized opcode: `%s'"), str);
897       return;
898     }
899
900   str = s;
901   while (isspace (*str))
902     ++str;
903
904   input_line_pointer = str;
905
906   for(;;)
907     {
908       const char *errmsg = NULL;
909       int op_idx;
910       char *hold;
911       int extra_shift = 0;
912
913       relaxable = 0;
914       fc = 0;
915       match = 0;
916       next_opindex = 0;
917       insn = opcode->opcode;
918       extension = 0;
919       for (op_idx = 1, opindex_ptr = opcode->operands;
920            *opindex_ptr != 0;
921            opindex_ptr++, op_idx++)
922         {
923           const struct mn10300_operand *operand;
924           expressionS ex;
925
926           if (next_opindex == 0)
927             {
928               operand = &mn10300_operands[*opindex_ptr];
929             }
930           else
931             {
932               operand = &mn10300_operands[next_opindex];
933               next_opindex = 0;
934             }
935
936           errmsg = NULL;
937
938           while (*str == ' ' || *str == ',')
939             ++str;
940
941           if (operand->flags & MN10300_OPERAND_RELAX)
942             relaxable = 1;
943
944           /* Gather the operand. */
945           hold = input_line_pointer;
946           input_line_pointer = str;
947
948           if (operand->flags & MN10300_OPERAND_PAREN)
949             {
950               if (*input_line_pointer != ')' && *input_line_pointer != '(')
951                 {
952                   input_line_pointer = hold;
953                   str = hold;
954                   goto error;
955                 }
956               input_line_pointer++;
957               goto keep_going;
958             }
959           /* See if we can match the operands.  */
960           else if (operand->flags & MN10300_OPERAND_DREG)
961             {
962               if (!data_register_name (&ex))
963                 {
964                   input_line_pointer = hold;
965                   str = hold;
966                   goto error;
967                 }
968             }
969           else if (operand->flags & MN10300_OPERAND_AREG)
970             {
971               if (!address_register_name (&ex))
972                 {
973                   input_line_pointer = hold;
974                   str = hold;
975                   goto error;
976                 }
977             }
978           else if (operand->flags & MN10300_OPERAND_SP)
979             {
980               char *start = input_line_pointer;
981               char c = get_symbol_end ();
982
983               if (strcasecmp (start, "sp") != 0)
984                 {
985                   *input_line_pointer = c;
986                   input_line_pointer = hold;
987                   str = hold;
988                   goto error;
989                 }
990               *input_line_pointer = c;
991               goto keep_going;
992             }
993           /* start-sanitize-am33 */
994           else if (operand->flags & MN10300_OPERAND_RREG)
995             {
996               if (!r_register_name (&ex))
997                 {
998                   input_line_pointer = hold;
999                   str = hold;
1000                   goto error;
1001                 }
1002             }
1003           else if (operand->flags & MN10300_OPERAND_XRREG)
1004             {
1005               if (!xr_register_name (&ex))
1006                 {
1007                   input_line_pointer = hold;
1008                   str = hold;
1009                   goto error;
1010                 }
1011             }
1012           else if (operand->flags & MN10300_OPERAND_USP)
1013             {
1014               char *start = input_line_pointer;
1015               char c = get_symbol_end ();
1016
1017               if (strcasecmp (start, "usp") != 0)
1018                 {
1019                   *input_line_pointer = c;
1020                   input_line_pointer = hold;
1021                   str = hold;
1022                   goto error;
1023                 }
1024               *input_line_pointer = c;
1025               goto keep_going;
1026             }
1027           else if (operand->flags & MN10300_OPERAND_SSP)
1028             {
1029               char *start = input_line_pointer;
1030               char c = get_symbol_end ();
1031
1032               if (strcasecmp (start, "ssp") != 0)
1033                 {
1034                   *input_line_pointer = c;
1035                   input_line_pointer = hold;
1036                   str = hold;
1037                   goto error;
1038                 }
1039               *input_line_pointer = c;
1040               goto keep_going;
1041             }
1042           else if (operand->flags & MN10300_OPERAND_MSP)
1043             {
1044               char *start = input_line_pointer;
1045               char c = get_symbol_end ();
1046
1047               if (strcasecmp (start, "msp") != 0)
1048                 {
1049                   *input_line_pointer = c;
1050                   input_line_pointer = hold;
1051                   str = hold;
1052                   goto error;
1053                 }
1054               *input_line_pointer = c;
1055               goto keep_going;
1056             }
1057           else if (operand->flags & MN10300_OPERAND_PC)
1058             {
1059               char *start = input_line_pointer;
1060               char c = get_symbol_end ();
1061
1062               if (strcasecmp (start, "pc") != 0)
1063                 {
1064                   *input_line_pointer = c;
1065                   input_line_pointer = hold;
1066                   str = hold;
1067                   goto error;
1068                 }
1069               *input_line_pointer = c;
1070               goto keep_going;
1071             }
1072           else if (operand->flags & MN10300_OPERAND_EPSW)
1073             {
1074               char *start = input_line_pointer;
1075               char c = get_symbol_end ();
1076
1077               if (strcasecmp (start, "epsw") != 0)
1078                 {
1079                   *input_line_pointer = c;
1080                   input_line_pointer = hold;
1081                   str = hold;
1082                   goto error;
1083                 }
1084               *input_line_pointer = c;
1085               goto keep_going;
1086             }
1087           else if (operand->flags & MN10300_OPERAND_PLUS)
1088             {
1089               if (*input_line_pointer != '+')
1090                 {
1091                   input_line_pointer = hold;
1092                   str = hold;
1093                   goto error;
1094                 }
1095               input_line_pointer++;
1096               goto keep_going;
1097             }
1098           /* end-sanitize-am33 */
1099           else if (operand->flags & MN10300_OPERAND_PSW)
1100             {
1101               char *start = input_line_pointer;
1102               char c = get_symbol_end ();
1103
1104               if (strcasecmp (start, "psw") != 0)
1105                 {
1106                   *input_line_pointer = c;
1107                   input_line_pointer = hold;
1108                   str = hold;
1109                   goto error;
1110                 }
1111               *input_line_pointer = c;
1112               goto keep_going;
1113             }
1114           else if (operand->flags & MN10300_OPERAND_MDR)
1115             {
1116               char *start = input_line_pointer;
1117               char c = get_symbol_end ();
1118
1119               if (strcasecmp (start, "mdr") != 0)
1120                 {
1121                   *input_line_pointer = c;
1122                   input_line_pointer = hold;
1123                   str = hold;
1124                   goto error;
1125                 }
1126               *input_line_pointer = c;
1127               goto keep_going;
1128             }
1129           else if (operand->flags & MN10300_OPERAND_REG_LIST)
1130             {
1131               unsigned int value = 0;
1132               if (*input_line_pointer != '[')
1133                 {
1134                   input_line_pointer = hold;
1135                   str = hold;
1136                   goto error;
1137                 }
1138
1139               /* Eat the '['.  */
1140               input_line_pointer++;
1141              
1142               /* We used to reject a null register list here; however,
1143                  we accept it now so the compiler can emit "call" instructions
1144                  for all calls to named functions.
1145
1146                  The linker can then fill in the appropriate bits for the
1147                  register list and stack size or change the instruction
1148                  into a "calls" if using "call" is not profitable.  */
1149               while (*input_line_pointer != ']')
1150                 {
1151                   char *start;
1152                   char c;
1153
1154                   if (*input_line_pointer == ',')
1155                     input_line_pointer++;
1156
1157                   start = input_line_pointer;
1158                   c = get_symbol_end ();
1159
1160                   if (strcasecmp (start, "d2") == 0)
1161                     {
1162                       value |= 0x80;
1163                       *input_line_pointer = c;
1164                     }
1165                   else if (strcasecmp (start, "d3") == 0)
1166                     {
1167                       value |= 0x40;
1168                       *input_line_pointer = c;
1169                     }
1170                   else if (strcasecmp (start, "a2") == 0)
1171                     {
1172                       value |= 0x20;
1173                       *input_line_pointer = c;
1174                     }
1175                   else if (strcasecmp (start, "a3") == 0)
1176                     {
1177                       value |= 0x10;
1178                       *input_line_pointer = c;
1179                     }
1180                   else if (strcasecmp (start, "other") == 0)
1181                     {
1182                       value |= 0x08;
1183                       *input_line_pointer = c;
1184                     }
1185                   /* start-sanitize-am33 */
1186                   else if (strcasecmp (start, "exreg0") == 0)
1187                     {
1188                       value |= 0x04;
1189                       *input_line_pointer = c;
1190                     }
1191                   else if (strcasecmp (start, "exreg1") == 0)
1192                     {
1193                       value |= 0x02;
1194                       *input_line_pointer = c;
1195                     }
1196                   else if (strcasecmp (start, "exother") == 0)
1197                     {
1198                       value |= 0x01;
1199                       *input_line_pointer = c;
1200                     }
1201                   else if (strcasecmp (start, "all") == 0)
1202                     {
1203                       value |= 0xff;
1204                       *input_line_pointer = c;
1205                     }
1206                   /* end-sanitize-am33 */
1207                   else
1208                     {
1209                       input_line_pointer = hold;
1210                       str = hold;
1211                       goto error;
1212                     }
1213                 }
1214               input_line_pointer++;
1215               mn10300_insert_operand (&insn, &extension, operand,
1216                                       value, (char *) NULL, 0, 0);
1217               goto keep_going;
1218
1219             }
1220           else if (data_register_name (&ex))
1221             {
1222               input_line_pointer = hold;
1223               str = hold;
1224               goto error;
1225             }
1226           else if (address_register_name (&ex))
1227             {
1228               input_line_pointer = hold;
1229               str = hold;
1230               goto error;
1231             }
1232           else if (other_register_name (&ex))
1233             {
1234               input_line_pointer = hold;
1235               str = hold;
1236               goto error;
1237             }
1238           else if (*str == ')' || *str == '(')
1239             {
1240               input_line_pointer = hold;
1241               str = hold;
1242               goto error;
1243             }
1244           else
1245             {
1246               expression (&ex);
1247             }
1248
1249           switch (ex.X_op) 
1250             {
1251             case O_illegal:
1252               errmsg = _("illegal operand");
1253               goto error;
1254             case O_absent:
1255               errmsg = _("missing operand");
1256               goto error;
1257             case O_register:
1258               {
1259                 int mask;
1260
1261                 mask = MN10300_OPERAND_DREG | MN10300_OPERAND_AREG;
1262                 /* start-sanitize-am33 */
1263                 mask |= MN10300_OPERAND_RREG | MN10300_OPERAND_XRREG;
1264                 /* end-sanitize-am33 */
1265                 if ((operand->flags & mask) == 0)
1266                   {
1267                     input_line_pointer = hold;
1268                     str = hold;
1269                     goto error;
1270                   }
1271                 
1272                 if (opcode->format == FMT_D1 || opcode->format == FMT_S1)
1273                   extra_shift = 8;
1274                 else if (opcode->format == FMT_D2
1275                          || opcode->format == FMT_D4
1276                          || opcode->format == FMT_S2
1277                          || opcode->format == FMT_S4
1278                          || opcode->format == FMT_S6
1279                          || opcode->format == FMT_D5)
1280                   extra_shift = 16;
1281                 /* start-sanitize-am33 */
1282                 else if (opcode->format == FMT_D7)
1283                   extra_shift = 8;
1284                 else if (opcode->format == FMT_D8 || opcode->format == FMT_D9)
1285                   extra_shift = 8;
1286                 /* end-sanitize-am33 */
1287                 else
1288                   extra_shift = 0;
1289               
1290                 mn10300_insert_operand (&insn, &extension, operand,
1291                                         ex.X_add_number, (char *) NULL,
1292                                         0, extra_shift);
1293
1294                 break;
1295               }
1296
1297             case O_constant:
1298               /* If this operand can be promoted, and it doesn't
1299                  fit into the allocated bitfield for this insn,
1300                  then promote it (ie this opcode does not match).  */
1301               if (operand->flags
1302                   & (MN10300_OPERAND_PROMOTE | MN10300_OPERAND_RELAX)
1303                   && ! check_operand (insn, operand, ex.X_add_number))
1304                 {
1305                   input_line_pointer = hold;
1306                   str = hold;
1307                   goto error;
1308                 }
1309
1310               mn10300_insert_operand (&insn, &extension, operand,
1311                                       ex.X_add_number, (char *) NULL,
1312                                       0, 0);
1313               break;
1314
1315             default:
1316               /* If this operand can be promoted, then this opcode didn't
1317                  match since we can't know if it needed promotion!  */
1318               if (operand->flags & MN10300_OPERAND_PROMOTE)
1319                 {
1320                   input_line_pointer = hold;
1321                   str = hold;
1322                   goto error;
1323                 }
1324
1325               /* We need to generate a fixup for this expression.  */
1326               if (fc >= MAX_INSN_FIXUPS)
1327                 as_fatal (_("too many fixups"));
1328               fixups[fc].exp = ex;
1329               fixups[fc].opindex = *opindex_ptr;
1330               fixups[fc].reloc = BFD_RELOC_UNUSED;
1331               ++fc;
1332               break;
1333             }
1334
1335 keep_going:
1336           str = input_line_pointer;
1337           input_line_pointer = hold;
1338
1339           while (*str == ' ' || *str == ',')
1340             ++str;
1341
1342         }
1343
1344       /* Make sure we used all the operands!  */
1345       if (*str != ',')
1346         match = 1;
1347
1348     error:
1349       if (match == 0)
1350         {
1351           next_opcode = opcode + 1;
1352           if (!strcmp(next_opcode->name, opcode->name))
1353             {
1354               opcode = next_opcode;
1355               continue;
1356             }
1357           
1358           as_bad ("%s", errmsg);
1359           return;
1360         }
1361       break;
1362     }
1363       
1364   while (isspace (*str))
1365     ++str;
1366
1367   if (*str != '\0')
1368     as_bad (_("junk at end of line: `%s'"), str);
1369
1370   input_line_pointer = str;
1371
1372   /* Determine the size of the instruction.  */
1373   if (opcode->format == FMT_S0)
1374     size = 1;
1375
1376   if (opcode->format == FMT_S1 || opcode->format == FMT_D0)
1377     size = 2;
1378
1379   if (opcode->format == FMT_S2 || opcode->format == FMT_D1)
1380     size = 3;
1381
1382   /* start-sanitize-am33 */
1383   if (opcode->format == FMT_D6)
1384     size = 3;
1385
1386   if (opcode->format == FMT_D7 || opcode->format == FMT_D10)
1387     size = 4;
1388
1389   if (opcode->format == FMT_D8)
1390     size = 6;
1391
1392   if (opcode->format == FMT_D9)
1393     size = 7;
1394   /* end-sanitize-am33 */
1395
1396   if (opcode->format == FMT_S4)
1397     size = 5;
1398
1399   if (opcode->format == FMT_S6 || opcode->format == FMT_D5)
1400     size = 7;
1401
1402   if (opcode->format == FMT_D2)
1403     size = 4;
1404
1405   if (opcode->format == FMT_D4)
1406     size = 6;
1407
1408   if (relaxable && fc > 0)
1409     {
1410       int type;
1411
1412       /* bCC */
1413       if (size == 2)
1414         {
1415           /* Handle bra specially.  Basically treat it like jmp so
1416              that we automatically handle 8, 16 and 32 bit offsets
1417              correctly as well as jumps to an undefined address.
1418
1419              It is also important to not treat it like other bCC
1420              instructions since the long forms of bra is different
1421              from other bCC instructions.  */
1422           if (opcode->opcode == 0xca00)
1423             type = 10;
1424           else
1425             type = 0;
1426         }
1427       /* call */
1428       else if (size == 5)
1429         type = 6;
1430       /* calls */
1431       else if (size == 4)
1432         type = 8;
1433       /* jmp */
1434       else if (size == 3 && opcode->opcode == 0xcc0000)
1435         type = 10;
1436       /* bCC (uncommon cases) */
1437       else
1438         type = 3;
1439
1440       f = frag_var (rs_machine_dependent, 8, 8 - size, type,
1441                     fixups[0].exp.X_add_symbol,
1442                     fixups[0].exp.X_add_number,
1443                     (char *)fixups[0].opindex);
1444       
1445       /* This is pretty hokey.  We basically just care about the
1446          opcode, so we have to write out the first word big endian.
1447
1448          The exception is "call", which has two operands that we
1449          care about.
1450
1451          The first operand (the register list) happens to be in the
1452          first instruction word, and will be in the right place if
1453          we output the first word in big endian mode.
1454
1455          The second operand (stack size) is in the extension word,
1456          and we want it to appear as the first character in the extension
1457          word (as it appears in memory).  Luckily, writing the extension
1458          word in big endian format will do what we want.  */
1459       number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);
1460       if (size > 8)
1461         {
1462           number_to_chars_bigendian (f + 4, extension, 4);
1463           number_to_chars_bigendian (f + 8, 0, size - 8);
1464         }
1465       else if (size > 4)
1466         number_to_chars_bigendian (f + 4, extension, size - 4);
1467     }
1468   else
1469     {
1470       /* Allocate space for the instruction.  */
1471       f = frag_more (size);
1472
1473       /* Fill in bytes for the instruction.  Note that opcode fields
1474          are written big-endian, 16 & 32bit immediates are written
1475          little endian.  Egad.  */
1476       if (opcode->format == FMT_S0
1477           || opcode->format == FMT_S1
1478           || opcode->format == FMT_D0
1479           /* start-sanitize-am33 */
1480           || opcode->format == FMT_D6
1481           || opcode->format == FMT_D7
1482           || opcode->format == FMT_D10
1483           /* end-sanitize-am33 */
1484           || opcode->format == FMT_D1)
1485         {
1486           number_to_chars_bigendian (f, insn, size);
1487         }
1488       else if (opcode->format == FMT_S2
1489                && opcode->opcode != 0xdf0000
1490                && opcode->opcode != 0xde0000)
1491         {
1492           /* A format S2 instruction that is _not_ "ret" and "retf".  */
1493           number_to_chars_bigendian (f, (insn >> 16) & 0xff, 1);
1494           number_to_chars_littleendian (f + 1, insn & 0xffff, 2);
1495         }
1496       else if (opcode->format == FMT_S2)
1497         {
1498           /* This must be a ret or retf, which is written entirely in
1499              big-endian format.  */
1500           number_to_chars_bigendian (f, insn, 3);
1501         }
1502       else if (opcode->format == FMT_S4
1503                && opcode->opcode != 0xdc000000)
1504         {
1505           /* This must be a format S4 "call" instruction.  What a pain.  */
1506           unsigned long temp = (insn >> 8) & 0xffff;
1507           number_to_chars_bigendian (f, (insn >> 24) & 0xff, 1);
1508           number_to_chars_littleendian (f + 1, temp, 2);
1509           number_to_chars_bigendian (f + 3, insn & 0xff, 1);
1510           number_to_chars_bigendian (f + 4, extension & 0xff, 1);
1511         }
1512       else if (opcode->format == FMT_S4)
1513         {
1514           /* This must be a format S4 "jmp" instruction.  */
1515           unsigned long temp = ((insn & 0xffffff) << 8) | (extension & 0xff);
1516           number_to_chars_bigendian (f, (insn >> 24) & 0xff, 1);
1517           number_to_chars_littleendian (f + 1, temp, 4);
1518         }
1519       else if (opcode->format == FMT_S6)
1520         {
1521           unsigned long temp = ((insn & 0xffffff) << 8)
1522             | ((extension >> 16) & 0xff);
1523           number_to_chars_bigendian (f, (insn >> 24) & 0xff, 1);
1524           number_to_chars_littleendian (f + 1, temp, 4);
1525           number_to_chars_bigendian (f + 5, (extension >> 8) & 0xff, 1);
1526           number_to_chars_bigendian (f + 6, extension & 0xff, 1);
1527         }
1528       else if (opcode->format == FMT_D2
1529                && opcode->opcode != 0xfaf80000
1530                && opcode->opcode != 0xfaf00000
1531                && opcode->opcode != 0xfaf40000)
1532         {
1533           /* A format D2 instruction where the 16bit immediate is
1534              really a single 16bit value, not two 8bit values.  */
1535           number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1536           number_to_chars_littleendian (f + 2, insn & 0xffff, 2);
1537         }
1538       else if (opcode->format == FMT_D2)
1539         {
1540           /* A format D2 instruction where the 16bit immediate
1541              is really two 8bit immediates.  */
1542           number_to_chars_bigendian (f, insn, 4);
1543         }
1544       else if (opcode->format == FMT_D4)
1545         {
1546           unsigned long temp = ((insn & 0xffff) << 16) | (extension & 0xffff);
1547           number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1548           number_to_chars_littleendian (f + 2, temp, 4);
1549         }
1550       else if (opcode->format == FMT_D5)
1551         {
1552           unsigned long temp = ((insn & 0xffff) << 16)
1553                                 | ((extension >> 8) & 0xffff);
1554           number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2);
1555           number_to_chars_littleendian (f + 2, temp, 4);
1556           number_to_chars_bigendian (f + 6, extension & 0xff, 1);
1557         }
1558       /* start-sanitize-am33 */
1559       else if (opcode->format == FMT_D8)
1560         {
1561           unsigned long temp = ((insn & 0xff) << 16) | (extension & 0xffff);
1562           number_to_chars_bigendian (f, (insn >> 8) & 0xffffff, 3);
1563           number_to_chars_bigendian (f + 3, (temp & 0xff), 1);
1564           number_to_chars_littleendian (f + 4, temp >> 8, 2);
1565         }
1566       else if (opcode->format == FMT_D9)
1567         {
1568           unsigned long temp = ((insn & 0xff) << 24) | (extension & 0xffffff);
1569           number_to_chars_bigendian (f, (insn >> 8) & 0xffffff, 3);
1570           number_to_chars_littleendian (f + 3, temp, 4);
1571         }
1572       /* end-sanitize-am33 */
1573
1574       /* Create any fixups.  */
1575       for (i = 0; i < fc; i++)
1576         {
1577           const struct mn10300_operand *operand;
1578
1579           operand = &mn10300_operands[fixups[i].opindex];
1580           if (fixups[i].reloc != BFD_RELOC_UNUSED)
1581             {
1582               reloc_howto_type *reloc_howto;
1583               int size;
1584               int offset;
1585               fixS *fixP;
1586
1587               reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
1588
1589               if (!reloc_howto)
1590                 abort();
1591           
1592               size = bfd_get_reloc_size (reloc_howto);
1593
1594               if (size < 1 || size > 4)
1595                 abort();
1596
1597               offset = 4 - size;
1598               fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1599                                   size, &fixups[i].exp,
1600                                   reloc_howto->pc_relative,
1601                                   fixups[i].reloc);
1602             }
1603           else
1604             {
1605               int reloc, pcrel, reloc_size, offset;
1606               fixS *fixP;
1607
1608               reloc = BFD_RELOC_NONE;
1609               /* How big is the reloc?  Remember SPLIT relocs are
1610                  implicitly 32bits.  */
1611               if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
1612                 reloc_size = 32;
1613               /* start-sanitize-am33 */
1614               else if ((operand->flags & MN10300_OPERAND_24BIT) != 0)
1615                 reloc_size = 24;
1616               /* end-sanitize-am33 */
1617               else
1618                 reloc_size = operand->bits;
1619
1620               /* Is the reloc pc-relative?  */
1621               pcrel = (operand->flags & MN10300_OPERAND_PCREL) != 0;
1622
1623               /* Gross.  This disgusting hack is to make sure we
1624                  get the right offset for the 16/32 bit reloc in 
1625                  "call" instructions.  Basically they're a pain
1626                  because the reloc isn't at the end of the instruction.  */
1627               if ((size == 5 || size == 7)
1628                   && (((insn >> 24) & 0xff) == 0xcd
1629                       || ((insn >> 24) & 0xff) == 0xdd))
1630                 size -= 2;
1631
1632               /* Similarly for certain bit instructions which don't
1633                  hav their 32bit reloc at the tail of the instruction.  */
1634               if (size == 7
1635                   && (((insn >> 16) & 0xffff) == 0xfe00
1636                       || ((insn >> 16) & 0xffff) == 0xfe01
1637                       || ((insn >> 16) & 0xffff) == 0xfe02))
1638                 size -= 1;
1639         
1640               offset = size - reloc_size / 8;
1641
1642               /* Choose a proper BFD relocation type.  */
1643               if (pcrel)
1644                 {
1645                   if (reloc_size == 32)
1646                     reloc = BFD_RELOC_32_PCREL;
1647                   else if (reloc_size == 16)
1648                     reloc = BFD_RELOC_16_PCREL;
1649                   else if (reloc_size == 8)
1650                     reloc = BFD_RELOC_8_PCREL;
1651                   else
1652                     abort ();
1653                 }
1654               else
1655                 {
1656                   if (reloc_size == 32)
1657                     reloc = BFD_RELOC_32;
1658                   else if (reloc_size == 16)
1659                     reloc = BFD_RELOC_16;
1660                   else if (reloc_size == 8)
1661                     reloc = BFD_RELOC_8;
1662                   else
1663                     abort ();
1664                 }
1665
1666               /* Convert the size of the reloc into what fix_new_exp wants.  */
1667               reloc_size = reloc_size / 8;
1668               if (reloc_size == 8)
1669                 reloc_size = 0;
1670               else if (reloc_size == 16)
1671                 reloc_size = 1;
1672               else if (reloc_size == 32)
1673                 reloc_size = 2;
1674
1675               fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
1676                                   reloc_size, &fixups[i].exp, pcrel,
1677                                   ((bfd_reloc_code_real_type) reloc));
1678
1679               if (pcrel)
1680                 fixP->fx_offset += offset;
1681             }
1682         }
1683     }
1684 }
1685
1686
1687 /* if while processing a fixup, a reloc really needs to be created */
1688 /* then it is done here */
1689                  
1690 arelent *
1691 tc_gen_reloc (seg, fixp)
1692      asection *seg;
1693      fixS *fixp;
1694 {
1695   arelent *reloc;
1696   reloc = (arelent *) xmalloc (sizeof (arelent));
1697
1698   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1699   if (reloc->howto == (reloc_howto_type *) NULL)
1700     {
1701       as_bad_where (fixp->fx_file, fixp->fx_line,
1702                     _("reloc %d not supported by object file format"),
1703                     (int)fixp->fx_r_type);
1704       return NULL;
1705     }
1706   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1707
1708   if (fixp->fx_addsy && fixp->fx_subsy)
1709     {
1710     
1711       if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
1712           || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
1713         {
1714           as_bad_where (fixp->fx_file, fixp->fx_line,
1715                         "Difference of symbols in different sections is not supported");
1716           return NULL;
1717         }
1718
1719       reloc->sym_ptr_ptr = &bfd_abs_symbol;
1720       reloc->addend = (S_GET_VALUE (fixp->fx_addsy)
1721                        - S_GET_VALUE (fixp->fx_subsy) + fixp->fx_offset);
1722     }
1723   else 
1724     {
1725       reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
1726       reloc->addend = fixp->fx_offset;
1727     }
1728   return reloc;
1729 }
1730
1731 int
1732 md_estimate_size_before_relax (fragp, seg)
1733      fragS *fragp;
1734      asection *seg;
1735 {
1736   if (fragp->fr_subtype == 0)
1737     return 2;
1738   if (fragp->fr_subtype == 3)
1739     return 3;
1740   if (fragp->fr_subtype == 6)
1741     {
1742       if (!S_IS_DEFINED (fragp->fr_symbol)
1743           || seg != S_GET_SEGMENT (fragp->fr_symbol))
1744         {
1745           fragp->fr_subtype = 7;
1746           return 7;
1747         }
1748       else
1749         return 5;
1750     }
1751   if (fragp->fr_subtype == 8)
1752     {
1753       if (!S_IS_DEFINED (fragp->fr_symbol)
1754           || seg != S_GET_SEGMENT (fragp->fr_symbol))
1755         {
1756           fragp->fr_subtype = 9;
1757           return 6;
1758         }
1759       else
1760         return 4;
1761     }
1762   if (fragp->fr_subtype == 10)
1763     {
1764       if (!S_IS_DEFINED (fragp->fr_symbol)
1765           || seg != S_GET_SEGMENT (fragp->fr_symbol))
1766         {
1767           fragp->fr_subtype = 12;
1768           return 5;
1769         }
1770       else
1771         return 2;
1772     }
1773
1774
1775 long
1776 md_pcrel_from (fixp)
1777      fixS *fixp;
1778 {
1779   return fixp->fx_frag->fr_address;
1780 #if 0
1781   if (fixp->fx_addsy != (symbolS *) NULL && ! S_IS_DEFINED (fixp->fx_addsy))
1782     {
1783       /* The symbol is undefined.  Let the linker figure it out.  */
1784       return 0;
1785     }
1786   return fixp->fx_frag->fr_address + fixp->fx_where;
1787 #endif
1788 }
1789
1790 int
1791 md_apply_fix3 (fixp, valuep, seg)
1792      fixS *fixp;
1793      valueT *valuep;
1794      segT seg;
1795 {
1796   /* We shouldn't ever get here because linkrelax is nonzero.  */
1797   abort ();
1798   fixp->fx_done = 1;
1799   return 0;
1800 }
1801
1802 /* Insert an operand value into an instruction.  */
1803
1804 static void
1805 mn10300_insert_operand (insnp, extensionp, operand, val, file, line, shift)
1806      unsigned long *insnp;
1807      unsigned long *extensionp;
1808      const struct mn10300_operand *operand;
1809      offsetT val;
1810      char *file;
1811      unsigned int line;
1812      unsigned int shift;
1813 {
1814   /* No need to check 32bit operands for a bit.  Note that
1815      MN10300_OPERAND_SPLIT is an implicit 32bit operand.  */
1816   if (operand->bits != 32
1817       && (operand->flags & MN10300_OPERAND_SPLIT) == 0)
1818     {
1819       long min, max;
1820       offsetT test;
1821       int bits;
1822
1823       bits = operand->bits;
1824       /* start-sanitize-am33 */
1825       if (operand->flags & MN10300_OPERAND_24BIT)
1826         bits = 24;
1827       /* end-sanitize-am33 */
1828
1829       if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
1830         {
1831           max = (1 << (bits - 1)) - 1;
1832           min = - (1 << (bits - 1));
1833         }
1834       else
1835         {
1836           max = (1 << bits) - 1;
1837           min = 0;
1838         }
1839
1840       test = val;
1841
1842
1843       if (test < (offsetT) min || test > (offsetT) max)
1844         {
1845           const char *err =
1846             _("operand out of range (%s not between %ld and %ld)");
1847           char buf[100];
1848
1849           sprint_value (buf, test);
1850           if (file == (char *) NULL)
1851             as_warn (err, buf, min, max);
1852           else
1853             as_warn_where (file, line, err, buf, min, max);
1854         }
1855     }
1856
1857   if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
1858     {
1859       *insnp |= (val >> (32 - operand->bits)) & ((1 << operand->bits) - 1);
1860       *extensionp |= ((val & ((1 << (32 - operand->bits)) - 1))
1861                       << operand->shift);
1862     }
1863   /* start-sanitize-am33 */
1864   else if ((operand->flags & MN10300_OPERAND_24BIT) != 0)
1865     {
1866       *insnp |= (val >> (24 - operand->bits)) & ((1 << operand->bits) - 1);
1867       *extensionp |= ((val & ((1 << (24 - operand->bits)) - 1))
1868                       << operand->shift);
1869     }
1870   /* end-sanitize-am33 */
1871   else if ((operand->flags & MN10300_OPERAND_EXTENDED) == 0)
1872     {
1873       *insnp |= (((long) val & ((1 << operand->bits) - 1))
1874                  << (operand->shift + shift));
1875
1876       if ((operand->flags & MN10300_OPERAND_REPEATED) != 0)
1877         *insnp |= (((long) val & ((1 << operand->bits) - 1))
1878                    << (operand->shift + shift + operand->bits));
1879     }
1880   else
1881     {
1882       *extensionp |= (((long) val & ((1 << operand->bits) - 1))
1883                       << (operand->shift + shift));
1884
1885       if ((operand->flags & MN10300_OPERAND_REPEATED) != 0)
1886         *extensionp |= (((long) val & ((1 << operand->bits) - 1))
1887                         << (operand->shift + shift + operand->bits));
1888     }
1889 }
1890
1891 static unsigned long
1892 check_operand (insn, operand, val)
1893      unsigned long insn;
1894      const struct mn10300_operand *operand;
1895      offsetT val;
1896 {
1897   /* No need to check 32bit operands for a bit.  Note that
1898      MN10300_OPERAND_SPLIT is an implicit 32bit operand.  */
1899   if (operand->bits != 32
1900       && (operand->flags & MN10300_OPERAND_SPLIT) == 0)
1901     {
1902       long min, max;
1903       offsetT test;
1904       int bits;
1905
1906       bits = operand->bits;
1907       /* start-sanitize-am33 */
1908       if (operand->flags & MN10300_OPERAND_24BIT)
1909         bits = 24;
1910       /* end-sanitize-am33 */
1911
1912       if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
1913         {
1914           max = (1 << (bits - 1)) - 1;
1915           min = - (1 << (bits - 1));
1916         }
1917       else
1918         {
1919           max = (1 << bits) - 1;
1920           min = 0;
1921         }
1922
1923       test = val;
1924
1925
1926       if (test < (offsetT) min || test > (offsetT) max)
1927         return 0;
1928       else
1929         return 1;
1930     }
1931   return 1;
1932 }