* config/tc-sh.c (md_convert_frag): Improve warning when branch is
[deliverable/binutils-gdb.git] / gas / config / tc-mn10300.c
CommitLineData
ae1b99e4 1/* tc-mn10300.c -- Assembler code for the Matsushita 10300
0f91d763
JL
2
3 Copyright (C) 1996 Free Software Foundation.
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
9 the Free Software Foundation; either version 2, or (at your option)
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
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22#include <stdio.h>
23#include <ctype.h>
24#include "as.h"
25#include "subsegs.h"
ae1b99e4 26#include "opcode/mn10300.h"
0f91d763
JL
27\f
28/* Structure to hold information about predefined registers. */
29struct reg_name
30{
31 const char *name;
32 int value;
33};
34
35/* Generic assembler global variables which must be defined by all targets. */
36
37/* Characters which always start a comment. */
38const char comment_chars[] = "#";
39
40/* Characters which start a comment at the beginning of a line. */
41const char line_comment_chars[] = ";#";
42
43/* Characters which may be used to separate multiple commands on a
44 single line. */
45const char line_separator_chars[] = ";";
46
47/* Characters which are used to indicate an exponent in a floating
48 point number. */
49const char EXP_CHARS[] = "eE";
50
51/* Characters which mean that a number is a floating point constant,
52 as in 0d1.0. */
53const char FLT_CHARS[] = "dD";
54\f
55
56/* local functions */
43d695a1
JL
57static void mn10300_insert_operand PARAMS ((unsigned long *, unsigned long *,
58 const struct mn10300_operand *,
59 offsetT, char *, unsigned,
60 unsigned));
61static unsigned long check_operand PARAMS ((unsigned long,
62 const struct mn10300_operand *,
63 offsetT));
0f91d763
JL
64static int reg_name_search PARAMS ((const struct reg_name *, int, const char *));
65static boolean register_name PARAMS ((expressionS *expressionP));
66static boolean system_register_name PARAMS ((expressionS *expressionP));
67static boolean cc_name PARAMS ((expressionS *expressionP));
0f91d763
JL
68
69
70/* fixups */
71#define MAX_INSN_FIXUPS (5)
ae1b99e4 72struct mn10300_fixup
0f91d763
JL
73{
74 expressionS exp;
75 int opindex;
76 bfd_reloc_code_real_type reloc;
77};
ae1b99e4 78struct mn10300_fixup fixups[MAX_INSN_FIXUPS];
0f91d763
JL
79static int fc;
80\f
81const char *md_shortopts = "";
82struct option md_longopts[] = {
83 {NULL, no_argument, NULL, 0}
84};
85size_t md_longopts_size = sizeof(md_longopts);
86
87/* The target specific pseudo-ops which we support. */
88const pseudo_typeS md_pseudo_table[] =
89{
90 { NULL, NULL, 0 }
91};
92
93/* Opcode hash table. */
ae1b99e4 94static struct hash_control *mn10300_hash;
0f91d763
JL
95
96/* This table is sorted. Suitable for searching by a binary search. */
1217102f 97static const struct reg_name data_registers[] =
0f91d763 98{
1217102f
JL
99 { "d0", 0 },
100 { "d1", 1 },
101 { "d2", 2 },
102 { "d3", 3 },
0f91d763 103};
1217102f 104#define DATA_REG_NAME_CNT (sizeof(data_registers) / sizeof(struct reg_name))
0f91d763 105
1217102f 106static const struct reg_name address_registers[] =
0f91d763 107{
1217102f
JL
108 { "a0", 0 },
109 { "a1", 1 },
110 { "a2", 2 },
111 { "a3", 3 },
0f91d763 112};
1217102f 113#define ADDRESS_REG_NAME_CNT (sizeof(address_registers) / sizeof(struct reg_name))
0f91d763 114
1217102f 115static const struct reg_name other_registers[] =
0f91d763 116{
1217102f
JL
117 { "mdr", 0 },
118 { "psw", 0 },
119 { "sp", 0 },
0f91d763 120};
1217102f 121#define OTHER_REG_NAME_CNT (sizeof(other_registers) / sizeof(struct reg_name))
0f91d763
JL
122
123/* reg_name_search does a binary search of the given register table
124 to see if "name" is a valid regiter name. Returns the register
125 number from the array on success, or -1 on failure. */
126
127static int
128reg_name_search (regs, regcount, name)
129 const struct reg_name *regs;
130 int regcount;
131 const char *name;
132{
133 int middle, low, high;
134 int cmp;
135
136 low = 0;
137 high = regcount - 1;
138
139 do
140 {
141 middle = (low + high) / 2;
142 cmp = strcasecmp (name, regs[middle].name);
143 if (cmp < 0)
144 high = middle - 1;
145 else if (cmp > 0)
146 low = middle + 1;
147 else
148 return regs[middle].value;
149 }
150 while (low <= high);
151 return -1;
152}
153
154
155/* Summary of register_name().
156 *
157 * in: Input_line_pointer points to 1st char of operand.
158 *
159 * out: A expressionS.
160 * The operand may have been a register: in this case, X_op == O_register,
161 * X_add_number is set to the register number, and truth is returned.
162 * Input_line_pointer->(next non-blank) char after operand, or is in
163 * its original state.
164 */
165static boolean
1217102f 166data_register_name (expressionP)
0f91d763
JL
167 expressionS *expressionP;
168{
169 int reg_number;
170 char *name;
171 char *start;
172 char c;
173
174 /* Find the spelling of the operand */
175 start = name = input_line_pointer;
176
177 c = get_symbol_end ();
1217102f 178 reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name);
0f91d763
JL
179
180 /* look to see if it's in the register table */
181 if (reg_number >= 0)
182 {
183 expressionP->X_op = O_register;
184 expressionP->X_add_number = reg_number;
185
186 /* make the rest nice */
187 expressionP->X_add_symbol = NULL;
188 expressionP->X_op_symbol = NULL;
189 *input_line_pointer = c; /* put back the delimiting char */
190 return true;
191 }
192 else
193 {
194 /* reset the line as if we had not done anything */
195 *input_line_pointer = c; /* put back the delimiting char */
196 input_line_pointer = start; /* reset input_line pointer */
197 return false;
198 }
199}
200
1217102f 201/* Summary of register_name().
0f91d763
JL
202 *
203 * in: Input_line_pointer points to 1st char of operand.
204 *
205 * out: A expressionS.
206 * The operand may have been a register: in this case, X_op == O_register,
207 * X_add_number is set to the register number, and truth is returned.
208 * Input_line_pointer->(next non-blank) char after operand, or is in
209 * its original state.
210 */
211static boolean
1217102f 212address_register_name (expressionP)
0f91d763
JL
213 expressionS *expressionP;
214{
215 int reg_number;
216 char *name;
217 char *start;
218 char c;
219
220 /* Find the spelling of the operand */
221 start = name = input_line_pointer;
222
223 c = get_symbol_end ();
1217102f 224 reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name);
0f91d763
JL
225
226 /* look to see if it's in the register table */
227 if (reg_number >= 0)
228 {
229 expressionP->X_op = O_register;
230 expressionP->X_add_number = reg_number;
231
232 /* make the rest nice */
233 expressionP->X_add_symbol = NULL;
234 expressionP->X_op_symbol = NULL;
235 *input_line_pointer = c; /* put back the delimiting char */
236 return true;
237 }
238 else
239 {
240 /* reset the line as if we had not done anything */
241 *input_line_pointer = c; /* put back the delimiting char */
242 input_line_pointer = start; /* reset input_line pointer */
243 return false;
244 }
245}
246
1217102f 247/* Summary of register_name().
0f91d763
JL
248 *
249 * in: Input_line_pointer points to 1st char of operand.
250 *
251 * out: A expressionS.
252 * The operand may have been a register: in this case, X_op == O_register,
253 * X_add_number is set to the register number, and truth is returned.
254 * Input_line_pointer->(next non-blank) char after operand, or is in
255 * its original state.
256 */
257static boolean
1217102f 258other_register_name (expressionP)
0f91d763
JL
259 expressionS *expressionP;
260{
261 int reg_number;
262 char *name;
263 char *start;
264 char c;
265
266 /* Find the spelling of the operand */
267 start = name = input_line_pointer;
268
269 c = get_symbol_end ();
1217102f 270 reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name);
0f91d763
JL
271
272 /* look to see if it's in the register table */
273 if (reg_number >= 0)
274 {
1217102f 275 expressionP->X_op = O_register;
0f91d763
JL
276 expressionP->X_add_number = reg_number;
277
278 /* make the rest nice */
279 expressionP->X_add_symbol = NULL;
280 expressionP->X_op_symbol = NULL;
281 *input_line_pointer = c; /* put back the delimiting char */
282 return true;
283 }
284 else
285 {
286 /* reset the line as if we had not done anything */
287 *input_line_pointer = c; /* put back the delimiting char */
288 input_line_pointer = start; /* reset input_line pointer */
289 return false;
290 }
291}
292
293void
294md_show_usage (stream)
295 FILE *stream;
296{
ae1b99e4 297 fprintf(stream, "MN10300 options:\n\
0f91d763
JL
298none yet\n");
299}
300
301int
302md_parse_option (c, arg)
303 int c;
304 char *arg;
305{
306 return 0;
307}
308
309symbolS *
310md_undefined_symbol (name)
311 char *name;
312{
313 return 0;
314}
315
316char *
317md_atof (type, litp, sizep)
318 int type;
319 char *litp;
320 int *sizep;
321{
322 int prec;
323 LITTLENUM_TYPE words[4];
324 char *t;
325 int i;
326
327 switch (type)
328 {
329 case 'f':
330 prec = 2;
331 break;
332
333 case 'd':
334 prec = 4;
335 break;
336
337 default:
338 *sizep = 0;
339 return "bad call to md_atof";
340 }
341
342 t = atof_ieee (input_line_pointer, type, words);
343 if (t)
344 input_line_pointer = t;
345
346 *sizep = prec * 2;
347
348 for (i = prec - 1; i >= 0; i--)
349 {
350 md_number_to_chars (litp, (valueT) words[i], 2);
351 litp += 2;
352 }
353
354 return NULL;
355}
356
357
358void
359md_convert_frag (abfd, sec, fragP)
360 bfd *abfd;
361 asection *sec;
362 fragS *fragP;
363{
364 /* printf ("call to md_convert_frag \n"); */
365 abort ();
366}
367
368valueT
369md_section_align (seg, addr)
370 asection *seg;
371 valueT addr;
372{
373 int align = bfd_get_section_alignment (stdoutput, seg);
374 return ((addr + (1 << align) - 1) & (-1 << align));
375}
376
377void
378md_begin ()
379{
380 char *prev_name = "";
ae1b99e4 381 register const struct mn10300_opcode *op;
0f91d763 382
ae1b99e4 383 mn10300_hash = hash_new();
0f91d763 384
ae1b99e4 385 /* Insert unique names into hash table. The MN10300 instruction set
0f91d763
JL
386 has many identical opcode names that have different opcodes based
387 on the operands. This hash table then provides a quick index to
388 the first opcode with a particular name in the opcode table. */
389
d9a9c18f 390 op = mn10300_opcodes;
0f91d763
JL
391 while (op->name)
392 {
393 if (strcmp (prev_name, op->name))
394 {
395 prev_name = (char *) op->name;
ae1b99e4 396 hash_insert (mn10300_hash, op->name, (char *) op);
0f91d763
JL
397 }
398 op++;
399 }
d9a9c18f
JL
400
401 /* This is both a simplification (we don't have to write md_apply_fix)
402 and support for future optimizations (branch shortening and similar
403 stuff in the linker. */
404 linkrelax = 1;
0f91d763
JL
405}
406
0f91d763
JL
407void
408md_assemble (str)
409 char *str;
410{
411 char *s;
ae1b99e4
JL
412 struct mn10300_opcode *opcode;
413 struct mn10300_opcode *next_opcode;
0f91d763
JL
414 const unsigned char *opindex_ptr;
415 int next_opindex;
bfe5059c 416 unsigned long insn, extension, size;
0f91d763
JL
417 char *f;
418 int i;
419 int match;
420 bfd_reloc_code_real_type reloc;
421
422 /* Get the opcode. */
423 for (s = str; *s != '\0' && ! isspace (*s); s++)
424 ;
425 if (*s != '\0')
426 *s++ = '\0';
427
428 /* find the first opcode with the proper name */
ae1b99e4 429 opcode = (struct mn10300_opcode *)hash_find (mn10300_hash, str);
0f91d763
JL
430 if (opcode == NULL)
431 {
432 as_bad ("Unrecognized opcode: `%s'", str);
433 return;
434 }
435
436 str = s;
437 while (isspace (*str))
438 ++str;
439
440 input_line_pointer = str;
441
442 for(;;)
443 {
444 const char *errmsg = NULL;
1217102f 445 int op_idx;
1217102f 446 char *hold;
68328dc6 447 int extra_shift = 0;
0f91d763
JL
448
449 fc = 0;
450 match = 0;
451 next_opindex = 0;
452 insn = opcode->opcode;
bfe5059c 453 extension = 0;
1217102f
JL
454 for (op_idx = 1, opindex_ptr = opcode->operands;
455 *opindex_ptr != 0;
456 opindex_ptr++, op_idx++)
0f91d763 457 {
ae1b99e4 458 const struct mn10300_operand *operand;
0f91d763
JL
459 expressionS ex;
460
461 if (next_opindex == 0)
462 {
ae1b99e4 463 operand = &mn10300_operands[*opindex_ptr];
0f91d763
JL
464 }
465 else
466 {
ae1b99e4 467 operand = &mn10300_operands[next_opindex];
0f91d763
JL
468 next_opindex = 0;
469 }
470
471 errmsg = NULL;
472
7f02192d 473 while (*str == ' ' || *str == ',')
0f91d763
JL
474 ++str;
475
476 /* Gather the operand. */
477 hold = input_line_pointer;
478 input_line_pointer = str;
479
a6be605a
JL
480 if (operand->flags & MN10300_OPERAND_PAREN)
481 {
482 if (*input_line_pointer != ')' && *input_line_pointer != '(')
483 {
484 input_line_pointer = hold;
485 str = hold;
486 goto error;
487 }
1217102f 488 input_line_pointer++;
a6be605a 489 goto keep_going;
1217102f 490 }
1217102f 491 /* See if we can match the operands. */
a6be605a 492 else if (operand->flags & MN10300_OPERAND_DREG)
0f91d763 493 {
1217102f 494 if (!data_register_name (&ex))
0f91d763 495 {
1217102f
JL
496 input_line_pointer = hold;
497 str = hold;
0f91d763
JL
498 goto error;
499 }
1217102f
JL
500 }
501 else if (operand->flags & MN10300_OPERAND_AREG)
502 {
503 if (!address_register_name (&ex))
0f91d763 504 {
1217102f
JL
505 input_line_pointer = hold;
506 str = hold;
507 goto error;
0f91d763 508 }
1217102f
JL
509 }
510 else if (operand->flags & MN10300_OPERAND_SP)
511 {
512 char *start = input_line_pointer;
513 char c = get_symbol_end ();
514
515 if (strcmp (start, "sp") != 0)
516 {
517 *input_line_pointer = c;
518 input_line_pointer = hold;
519 str = hold;
520 goto error;
521 }
522 *input_line_pointer = c;
523 goto keep_going;
524 }
525 else if (operand->flags & MN10300_OPERAND_PSW)
526 {
527 char *start = input_line_pointer;
528 char c = get_symbol_end ();
529
530 if (strcmp (start, "psw") != 0)
0f91d763 531 {
1217102f
JL
532 *input_line_pointer = c;
533 input_line_pointer = hold;
534 str = hold;
535 goto error;
536 }
537 *input_line_pointer = c;
538 goto keep_going;
539 }
540 else if (operand->flags & MN10300_OPERAND_MDR)
541 {
542 char *start = input_line_pointer;
543 char c = get_symbol_end ();
0f91d763 544
1217102f
JL
545 if (strcmp (start, "mdr") != 0)
546 {
547 *input_line_pointer = c;
548 input_line_pointer = hold;
549 str = hold;
550 goto error;
0f91d763 551 }
1217102f
JL
552 *input_line_pointer = c;
553 goto keep_going;
554 }
7f02192d
JL
555 else if (operand->flags & MN10300_OPERAND_REG_LIST)
556 {
557 unsigned int value = 0;
558 if (*input_line_pointer != '[')
559 {
560 input_line_pointer = hold;
561 str = hold;
562 goto error;
563 }
564
565 /* Eat the '['. */
566 input_line_pointer++;
567
568 /* A null register list can not be specified. */
569 if (*input_line_pointer == ']')
570 {
571 input_line_pointer = hold;
572 str = hold;
573 goto error;
574 }
575
576 while (*input_line_pointer != ']')
577 {
578 char *start;
579 char c;
580
581 if (*input_line_pointer == ',')
582 input_line_pointer++;
583
584 start = input_line_pointer;
585 c = get_symbol_end ();
586
587 if (strcmp (start, "d2") == 0)
588 {
589 value |= 0x80;
590 *input_line_pointer = c;
591 }
592 else if (strcmp (start, "d3") == 0)
593 {
594 value |= 0x40;
595 *input_line_pointer = c;
596 }
597 else if (strcmp (start, "a2") == 0)
598 {
599 value |= 0x20;
600 *input_line_pointer = c;
601 }
602 else if (strcmp (start, "a3") == 0)
603 {
604 value |= 0x10;
605 *input_line_pointer = c;
606 }
607 else if (strcmp (start, "other") == 0)
608 {
609 value |= 0x08;
610 *input_line_pointer = c;
611 }
612 else
613 {
614 input_line_pointer = hold;
615 str = hold;
616 goto error;
617 }
618 }
619 input_line_pointer++;
620 mn10300_insert_operand (&insn, &extension, operand,
621 value, (char *) NULL, 0, 0);
622 goto keep_going;
623
624 }
1217102f
JL
625 else if (data_register_name (&ex))
626 {
627 input_line_pointer = hold;
628 str = hold;
629 goto error;
630 }
631 else if (address_register_name (&ex))
632 {
633 input_line_pointer = hold;
634 str = hold;
635 goto error;
636 }
637 else if (other_register_name (&ex))
638 {
639 input_line_pointer = hold;
640 str = hold;
641 goto error;
0f91d763 642 }
a6be605a
JL
643 else if (*str == ')' || *str == '(')
644 {
645 input_line_pointer = hold;
646 str = hold;
647 goto error;
648 }
0f91d763
JL
649 else
650 {
1217102f
JL
651 expression (&ex);
652 }
653
0f91d763
JL
654 switch (ex.X_op)
655 {
656 case O_illegal:
657 errmsg = "illegal operand";
658 goto error;
659 case O_absent:
660 errmsg = "missing operand";
661 goto error;
662 case O_register:
1217102f
JL
663 if (operand->flags & (MN10300_OPERAND_DREG
664 | MN10300_OPERAND_AREG) == 0)
665 {
666 input_line_pointer = hold;
667 str = hold;
668 goto error;
669 }
0f91d763 670
68328dc6
JL
671 if (opcode->format == FMT_D1 || opcode->format == FMT_S1)
672 extra_shift = 8;
673 else if (opcode->format == FMT_D2 || opcode->format == FMT_D4
674 || opcode->format == FMT_S2 || opcode->format == FMT_S4
675 || opcode->format == FMT_S6 || opcode->format == FMT_D5)
676 extra_shift = 16;
677 else
678 extra_shift = 0;
679
bfe5059c
JL
680 mn10300_insert_operand (&insn, &extension, operand,
681 ex.X_add_number, (char *) NULL,
682 0, extra_shift);
68328dc6 683
0f91d763
JL
684 break;
685
686 case O_constant:
1217102f
JL
687 /* If this operand can be promoted, and it doesn't
688 fit into the allocated bitfield for this insn,
689 then promote it (ie this opcode does not match). */
690 if (operand->flags & MN10300_OPERAND_PROMOTE
691 && ! check_operand (insn, operand, ex.X_add_number))
692 {
693 input_line_pointer = hold;
694 str = hold;
695 goto error;
696 }
697
bfe5059c
JL
698 mn10300_insert_operand (&insn, &extension, operand,
699 ex.X_add_number, (char *) NULL,
700 0, 0);
0f91d763
JL
701 break;
702
703 default:
1217102f
JL
704 /* If this operand can be promoted, then this opcode didn't
705 match since we can't know if it needed promotion! */
706 if (operand->flags & MN10300_OPERAND_PROMOTE)
707 {
708 input_line_pointer = hold;
709 str = hold;
710 goto error;
711 }
712
0f91d763
JL
713 /* We need to generate a fixup for this expression. */
714 if (fc >= MAX_INSN_FIXUPS)
715 as_fatal ("too many fixups");
716 fixups[fc].exp = ex;
717 fixups[fc].opindex = *opindex_ptr;
718 fixups[fc].reloc = BFD_RELOC_UNUSED;
719 ++fc;
720 break;
721 }
722
1217102f 723keep_going:
0f91d763
JL
724 str = input_line_pointer;
725 input_line_pointer = hold;
726
7f02192d 727 while (*str == ' ' || *str == ',')
0f91d763 728 ++str;
1217102f 729
1217102f 730 }
a6be605a
JL
731
732 /* Make sure we used all the operands! */
733 if (*str != ',')
1217102f 734 match = 1;
0f91d763
JL
735
736 error:
737 if (match == 0)
738 {
739 next_opcode = opcode + 1;
740 if (next_opcode->opcode != 0 && !strcmp(next_opcode->name, opcode->name))
741 {
742 opcode = next_opcode;
743 continue;
744 }
745
746 as_bad ("%s", errmsg);
747 return;
748 }
749 break;
750 }
751
752 while (isspace (*str))
753 ++str;
754
755 if (*str != '\0')
756 as_bad ("junk at end of line: `%s'", str);
757
758 input_line_pointer = str;
759
778c521b
JL
760 /* Determine the size of the instruction. */
761 if (opcode->format == FMT_S0)
1217102f 762 size = 1;
0f91d763 763
778c521b 764 if (opcode->format == FMT_S1 || opcode->format == FMT_D0)
0f91d763 765 size = 2;
0f91d763 766
778c521b 767 if (opcode->format == FMT_S2 || opcode->format == FMT_D1)
1217102f 768 size = 3;
0f91d763 769
778c521b 770 if (opcode->format == FMT_S4)
1217102f 771 size = 5;
0f91d763 772
778c521b 773 if (opcode->format == FMT_S6 || opcode->format == FMT_D5)
1217102f 774 size = 7;
0f91d763 775
778c521b 776 if (opcode->format == FMT_D2)
1217102f 777 size = 4;
0f91d763 778
778c521b 779 if (opcode->format == FMT_D4)
1217102f
JL
780 size = 6;
781
1217102f
JL
782 /* Write out the instruction. */
783
784 f = frag_more (size);
1c3ae169 785 number_to_chars_bigendian (f, insn, size > 4 ? 4 : size);
1217102f 786 if (size > 4)
bfe5059c 787 number_to_chars_bigendian (f + 4, extension, size - 4);
d9a9c18f
JL
788
789 /* Create any fixups. */
790 for (i = 0; i < fc; i++)
791 {
792 const struct mn10300_operand *operand;
793
794 operand = &mn10300_operands[fixups[i].opindex];
795 if (fixups[i].reloc != BFD_RELOC_UNUSED)
796 {
797 reloc_howto_type *reloc_howto;
798 int size;
799 int offset;
800 fixS *fixP;
801
802 reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
803
804 if (!reloc_howto)
805 abort();
806
807 size = bfd_get_reloc_size (reloc_howto);
808
809 if (size < 1 || size > 4)
810 abort();
811
812 offset = 4 - size;
813 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset, size,
814 &fixups[i].exp,
815 reloc_howto->pc_relative,
816 fixups[i].reloc);
817 }
818 else
819 {
820 int reloc, pcrel, reloc_size, offset;
821
822 /* How big is the reloc? Remember SPLIT relocs are
823 implicitly 32bits. */
824 if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
825 reloc_size = 32;
826 else
827 reloc_size = operand->bits;
828
829 /* Is the reloc pc-relative? */
830 pcrel = (operand->flags & MN10300_OPERAND_PCREL) != 0;
831
832 /* Gross. This disgusting hack is to make sure we
833 get the right offset for the 16/32 bit reloc in
834 "call" instructions. Basically they're a pain
835 because the reloc isn't at the end of the instruction. */
836 if ((size == 5 || size == 7)
837 && (((insn >> 24) & 0xff) == 0xcd
838 || ((insn >> 24) & 0xff) == 0xdd))
839 size -= 2;
840
841 /* Similarly for certain bit instructions which don't
842 hav their 32bit reloc at the tail of the instruction. */
843 if (size == 7
844 && (((insn >> 16) & 0xffff) == 0xfe00
845 || ((insn >> 16) & 0xffff) == 0xfe01
846 || ((insn >> 16) & 0xffff) == 0xfe02))
847 size -= 1;
848
849 /* Determine offset from start of this insn to insert the
850 reloc. Except for a few exceptions we insert the reloc
851 at the tail of the instruction. */
852 offset = size - reloc_size / 8;
853
854 /* Choose a proper BFD relocation type. */
855 if (pcrel)
856 {
857 if (reloc_size == 32)
858 reloc = BFD_RELOC_32_PCREL;
859 else if (reloc_size == 16)
860 reloc = BFD_RELOC_16_PCREL;
861 else if (reloc_size == 8)
862 reloc = BFD_RELOC_8_PCREL;
863 else
864 abort ();
865 }
866 else
867 {
868 if (reloc_size == 32)
869 reloc = BFD_RELOC_32;
870 else if (reloc_size == 16)
871 reloc = BFD_RELOC_16;
872 else if (reloc_size == 8)
873 reloc = BFD_RELOC_8;
874 else
875 abort ();
876 }
877
878 /* Convert the size of the reloc into what fix_new_exp wants. */
879 reloc_size = reloc_size / 8;
880 if (reloc_size == 8)
881 reloc_size = 0;
882 else if (reloc_size == 16)
883 reloc_size = 1;
884 else if (reloc_size == 32)
885 reloc_size = 2;
886
887 fix_new_exp (frag_now, f - frag_now->fr_literal + offset, reloc_size,
888 &fixups[i].exp, pcrel,
889 ((bfd_reloc_code_real_type) reloc));
890 }
891 }
0f91d763
JL
892}
893
894
895/* if while processing a fixup, a reloc really needs to be created */
896/* then it is done here */
897
898arelent *
899tc_gen_reloc (seg, fixp)
900 asection *seg;
901 fixS *fixp;
902{
903 arelent *reloc;
904 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
905 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
906 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
907 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
908 if (reloc->howto == (reloc_howto_type *) NULL)
909 {
910 as_bad_where (fixp->fx_file, fixp->fx_line,
911 "reloc %d not supported by object file format", (int)fixp->fx_r_type);
912 return NULL;
913 }
914 reloc->addend = fixp->fx_addnumber;
915 /* printf("tc_gen_reloc: addr=%x addend=%x\n", reloc->address, reloc->addend); */
916 return reloc;
917}
918
919int
920md_estimate_size_before_relax (fragp, seg)
921 fragS *fragp;
922 asection *seg;
923{
924 return 0;
925}
926
927long
928md_pcrel_from (fixp)
929 fixS *fixp;
930{
931 if (fixp->fx_addsy != (symbolS *) NULL && ! S_IS_DEFINED (fixp->fx_addsy))
932 {
933 /* The symbol is undefined. Let the linker figure it out. */
934 return 0;
935 }
936 return fixp->fx_frag->fr_address + fixp->fx_where;
937}
938
939int
940md_apply_fix3 (fixp, valuep, seg)
941 fixS *fixp;
942 valueT *valuep;
943 segT seg;
944{
d9a9c18f
JL
945 /* We shouldn't ever get here because linkrelax is nonzero. */
946 abort ();
1217102f
JL
947 fixp->fx_done = 1;
948 return 0;
0f91d763
JL
949}
950
0f91d763
JL
951/* Insert an operand value into an instruction. */
952
bfe5059c
JL
953static void
954mn10300_insert_operand (insnp, extensionp, operand, val, file, line, shift)
955 unsigned long *insnp;
956 unsigned long *extensionp;
ae1b99e4 957 const struct mn10300_operand *operand;
0f91d763
JL
958 offsetT val;
959 char *file;
960 unsigned int line;
68328dc6 961 unsigned int shift;
0f91d763 962{
43d695a1
JL
963 /* No need to check 32bit operands for a bit. Note that
964 MN10300_OPERAND_SPLIT is an implicit 32bit operand. */
965 if (operand->bits != 32
966 && (operand->flags & MN10300_OPERAND_SPLIT) == 0)
0f91d763
JL
967 {
968 long min, max;
969 offsetT test;
970
1217102f
JL
971 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
972 {
973 max = (1 << (operand->bits - 1)) - 1;
974 min = - (1 << (operand->bits - 1));
975 }
976 else
0f91d763
JL
977 {
978 max = (1 << operand->bits) - 1;
979 min = 0;
980 }
981
982 test = val;
983
984
985 if (test < (offsetT) min || test > (offsetT) max)
986 {
987 const char *err =
988 "operand out of range (%s not between %ld and %ld)";
989 char buf[100];
990
991 sprint_value (buf, test);
992 if (file == (char *) NULL)
993 as_warn (err, buf, min, max);
994 else
995 as_warn_where (file, line, err, buf, min, max);
996 }
997 }
998
cdde2f5c
JL
999 if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
1000 {
43d695a1
JL
1001 *insnp |= (val >> 32 - operand->bits) & ((1 << operand->bits) - 1);
1002 *extensionp |= ((val & ((1 << (32 - operand->bits)) - 1))
1003 << operand->shift);
cdde2f5c
JL
1004 }
1005 else if ((operand->flags & MN10300_OPERAND_EXTENDED) == 0)
bfe5059c
JL
1006 {
1007 *insnp |= (((long) val & ((1 << operand->bits) - 1))
1008 << (operand->shift + shift));
1009
1010 if ((operand->flags & MN10300_OPERAND_REPEATED) != 0)
1011 *insnp |= (((long) val & ((1 << operand->bits) - 1))
1012 << (operand->shift + shift + 2));
1013 }
1014 else
1015 {
1016 *extensionp |= (((long) val & ((1 << operand->bits) - 1))
1017 << (operand->shift + shift));
68328dc6 1018
bfe5059c
JL
1019 if ((operand->flags & MN10300_OPERAND_REPEATED) != 0)
1020 *extensionp |= (((long) val & ((1 << operand->bits) - 1))
1021 << (operand->shift + shift + 2));
1022 }
0f91d763 1023}
1217102f
JL
1024
1025static unsigned long
1026check_operand (insn, operand, val)
1027 unsigned long insn;
1028 const struct mn10300_operand *operand;
1029 offsetT val;
1030{
43d695a1
JL
1031 /* No need to check 32bit operands for a bit. Note that
1032 MN10300_OPERAND_SPLIT is an implicit 32bit operand. */
1033 if (operand->bits != 32
1034 && (operand->flags & MN10300_OPERAND_SPLIT) == 0)
1217102f
JL
1035 {
1036 long min, max;
1037 offsetT test;
1038
1039 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
1040 {
1041 max = (1 << (operand->bits - 1)) - 1;
1042 min = - (1 << (operand->bits - 1));
1043 }
1044 else
1045 {
1046 max = (1 << operand->bits) - 1;
1047 min = 0;
1048 }
1049
1050 test = val;
1051
1052
1053 if (test < (offsetT) min || test > (offsetT) max)
1054 return 0;
1055 else
1056 return 1;
1057 }
1058 return 1;
1059}
This page took 0.07329 seconds and 4 git commands to generate.