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