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