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