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