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