2012-01-12 Tristan Gingold <gingold@adacore.com>
[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,
d4f4f3fb 3 2005, 2006, 2007, 2009 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;
65261832 484 break;
252b5132
RH
485 case 0xe8:
486 opcode = 0xe9;
487 break;
488 case 0xe9:
489 opcode = 0xe8;
490 break;
491 case 0xe0:
492 opcode = 0xe2;
493 break;
494 case 0xe2:
495 opcode = 0xe0;
496 break;
497 case 0xe3:
498 opcode = 0xe1;
499 break;
500 case 0xe1:
501 opcode = 0xe3;
502 break;
503 case 0xe4:
504 opcode = 0xe6;
505 break;
506 case 0xe6:
507 opcode = 0xe4;
508 break;
509 case 0xe7:
510 opcode = 0xe5;
511 break;
512 case 0xe5:
513 opcode = 0xe7;
514 break;
515 case 0xec:
516 opcode = 0xed;
517 break;
518 case 0xed:
519 opcode = 0xec;
520 break;
521 case 0xee:
522 opcode = 0xef;
523 break;
524 case 0xef:
525 opcode = 0xee;
526 break;
527 default:
528 abort ();
529 }
530 fragP->fr_literal[offset + 1] = opcode;
531
532 /* Create a fixup for the reversed conditional branch. */
2a8ce8da 533 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
252b5132
RH
534 fix_new (fragP, fragP->fr_fix + 2, 1,
535 symbol_new (buf, sec, 0, fragP->fr_next),
536 fragP->fr_offset, 1, BFD_RELOC_8_PCREL);
537
538 /* Now create the unconditional branch + fixup to the
539 final target. */
540 fragP->fr_literal[offset + 3] = 0xfc;
541 fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol,
542 fragP->fr_offset, 1, BFD_RELOC_16_PCREL);
543 fragP->fr_var = 0;
544 fragP->fr_fix += 6;
545 }
546 else if (fragP->fr_subtype == 5)
547 {
548 /* Reverse the condition of the first branch. */
549 int offset = fragP->fr_fix;
550 int opcode = fragP->fr_literal[offset + 1] & 0xff;
551
552 switch (opcode)
553 {
554 case 0xfc:
555 opcode = 0xfd;
556 break;
557 case 0xfd:
558 opcode = 0xfc;
559 break;
560 case 0xfe:
561 opcode = 0xff;
562 break;
563 case 0xff:
564 opcode = 0xfe;
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. */
2a8ce8da 613 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
252b5132
RH
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
678valueT
ea1562b3 679md_section_align (asection *seg, valueT addr)
252b5132
RH
680{
681 int align = bfd_get_section_alignment (stdoutput, seg);
682 return ((addr + (1 << align) - 1) & (-1 << align));
683}
684
685void
ea1562b3 686md_begin (void)
252b5132
RH
687{
688 char *prev_name = "";
689 register const struct mn10200_opcode *op;
690
87271fa6 691 mn10200_hash = hash_new ();
252b5132
RH
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 {
87271fa6 701 if (strcmp (prev_name, op->name))
252b5132
RH
702 {
703 prev_name = (char *) op->name;
704 hash_insert (mn10200_hash, op->name, (char *) op);
705 }
706 op++;
707 }
708
55cf6793 709 /* This is both a simplification (we don't have to write md_apply_fix)
252b5132
RH
710 and support for future optimizations (branch shortening and similar
711 stuff in the linker. */
712 linkrelax = 1;
713}
714
ea1562b3
NC
715static unsigned long
716check_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
750arelent *
751tc_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
793int
794md_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
811long
812md_pcrel_from (fixS *fixp)
813{
814 return fixp->fx_frag->fr_address;
815}
816
252b5132 817void
55cf6793 818md_apply_fix (fixS * fixP, valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
ea1562b3
NC
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
827static void
828mn10200_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
876void
877md_assemble (char *str)
252b5132
RH
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. */
3882b010 890 for (s = str; *s != '\0' && !ISSPACE (*s); s++)
252b5132
RH
891 ;
892 if (*s != '\0')
893 *s++ = '\0';
894
87271fa6
NC
895 /* Find the first opcode with the proper name. */
896 opcode = (struct mn10200_opcode *) hash_find (mn10200_hash, str);
252b5132
RH
897 if (opcode == NULL)
898 {
899 as_bad (_("Unrecognized opcode: `%s'"), str);
900 return;
901 }
902
903 str = s;
3882b010 904 while (ISSPACE (*str))
252b5132
RH
905 ++str;
906
907 input_line_pointer = str;
908
87271fa6 909 for (;;)
252b5132
RH
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
87271fa6 947 /* Gather the operand. */
252b5132
RH
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
87271fa6 1040 switch (ex.X_op)
252b5132
RH
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
87271fa6 1050 & (MN10200_OPERAND_DREG | MN10200_OPERAND_AREG)) == 0)
252b5132
RH
1051 {
1052 input_line_pointer = hold;
1053 str = hold;
1054 goto error;
1055 }
87271fa6 1056
252b5132
RH
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;
87271fa6 1064
252b5132 1065 mn10200_insert_operand (&insn, &extension, operand,
ea1562b3 1066 ex.X_add_number, NULL,
252b5132
RH
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)
87271fa6 1077 && !check_operand (insn, operand, ex.X_add_number))
252b5132
RH
1078 {
1079 input_line_pointer = hold;
1080 str = hold;
1081 goto error;
1082 }
1083
1084 mn10200_insert_operand (&insn, &extension, operand,
ea1562b3 1085 ex.X_add_number, NULL,
252b5132
RH
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
1109keep_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)
87271fa6 1124 {
252b5132 1125 next_opcode = opcode + 1;
87271fa6 1126 if (!strcmp (next_opcode->name, opcode->name))
252b5132
RH
1127 {
1128 opcode = next_opcode;
1129 continue;
1130 }
87271fa6 1131
252b5132
RH
1132 as_bad ("%s", errmsg);
1133 return;
87271fa6 1134 }
252b5132
RH
1135 break;
1136 }
87271fa6 1137
3882b010 1138 while (ISSPACE (*str))
252b5132
RH
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 ();
87271fa6 1158
252b5132 1159 /* Write out the instruction. */
d4f4f3fb 1160 dwarf2_emit_insn (0);
252b5132
RH
1161 if (relaxable && fc > 0)
1162 {
8ad7c533
NC
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;
252b5132
RH
1175 int type;
1176
87271fa6 1177 /* bCC */
252b5132
RH
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. */
87271fa6
NC
1187 if (opcode->opcode == 0xea00)
1188 type = 8;
252b5132
RH
1189 else
1190 type = 0;
1191 }
87271fa6 1192 /* jsr */
252b5132
RH
1193 else if (size == 3 && opcode->opcode == 0xfd0000)
1194 type = 6;
87271fa6 1195 /* jmp */
252b5132
RH
1196 else if (size == 3 && opcode->opcode == 0xfc0000)
1197 type = 8;
87271fa6 1198 /* bCCx */
252b5132
RH
1199 else
1200 type = 3;
1201
8ad7c533 1202 opindex_converter.opindex = fixups[0].opindex;
252b5132
RH
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,
8ad7c533 1206 opindex_converter.ptr);
252b5132
RH
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 }
252b5132
RH
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
ea1562b3 1239 number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);
252b5132
RH
1240
1241 /* Create any fixups. */
1242 for (i = 0; i < fc; i++)
1243 {
1244 const struct mn10200_operand *operand;
91d6fa6a 1245 int reloc_size;
252b5132
RH
1246
1247 operand = &mn10200_operands[fixups[i].opindex];
1248 if (fixups[i].reloc != BFD_RELOC_UNUSED)
1249 {
1250 reloc_howto_type *reloc_howto;
252b5132
RH
1251 int offset;
1252 fixS *fixP;
1253
87271fa6
NC
1254 reloc_howto = bfd_reloc_type_lookup (stdoutput,
1255 fixups[i].reloc);
252b5132
RH
1256
1257 if (!reloc_howto)
87271fa6
NC
1258 abort ();
1259
91d6fa6a 1260 reloc_size = bfd_get_reloc_size (reloc_howto);
252b5132 1261
91d6fa6a 1262 if (reloc_size < 1 || reloc_size > 4)
87271fa6 1263 abort ();
252b5132 1264
91d6fa6a 1265 offset = 4 - reloc_size;
252b5132 1266 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
91d6fa6a 1267 reloc_size,
87271fa6 1268 &fixups[i].exp,
252b5132
RH
1269 reloc_howto->pc_relative,
1270 fixups[i].reloc);
1271
87271fa6
NC
1272 /* PC-relative offsets are from the first byte of the
1273 next instruction, not from the start of the current
1274 instruction. */
252b5132 1275 if (reloc_howto->pc_relative)
91d6fa6a 1276 fixP->fx_offset += reloc_size;
252b5132
RH
1277 }
1278 else
1279 {
91d6fa6a 1280 int reloc, pcrel, offset;
252b5132
RH
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
252b5132
RH
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
87271fa6
NC
1317 /* Convert the size of the reloc into what fix_new_exp
1318 wants. */
252b5132
RH
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
87271fa6
NC
1331 /* PC-relative offsets are from the first byte of the
1332 next instruction, not from the start of the current
1333 instruction. */
252b5132
RH
1334 if (pcrel)
1335 fixP->fx_offset += size;
1336 }
1337 }
1338 }
1339}
1340
This page took 0.718036 seconds and 4 git commands to generate.