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