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