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