source: trunk/binutils/gas/config/tc-v850.c@ 2562

Last change on this file since 2562 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 60.1 KB
Line 
1/* tc-v850.c -- Assembler code for the NEC V850
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
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 "as.h"
24#include "safe-ctype.h"
25#include "subsegs.h"
26#include "opcode/v850.h"
27#include "dwarf2dbg.h"
28
29/* Sign-extend a 16-bit number. */
30#define SEXT16(x) ((((x) & 0xffff) ^ (~0x7fff)) + 0x8000)
31
32/* Temporarily holds the reloc in a cons expression. */
33static bfd_reloc_code_real_type hold_cons_reloc = BFD_RELOC_UNUSED;
34
35/* Set to TRUE if we want to be pedantic about signed overflows. */
36static bfd_boolean warn_signed_overflows = FALSE;
37static bfd_boolean warn_unsigned_overflows = FALSE;
38
39/* Indicates the target BFD machine number. */
40static int machine = -1;
41
42/* Indicates the target processor(s) for the assemble. */
43static int processor_mask = -1;
44
45
46/* Structure to hold information about predefined registers. */
47struct reg_name {
48 const char *name;
49 int value;
50};
51
52/* Generic assembler global variables which must be defined by all
53 targets. */
54
55/* Characters which always start a comment. */
56const char comment_chars[] = "#";
57
58/* Characters which start a comment at the beginning of a line. */
59const char line_comment_chars[] = ";#";
60
61/* Characters which may be used to separate multiple commands on a
62 single line. */
63const char line_separator_chars[] = ";";
64
65/* Characters which are used to indicate an exponent in a floating
66 point number. */
67const char EXP_CHARS[] = "eE";
68
69/* Characters which mean that a number is a floating point constant,
70 as in 0d1.0. */
71const char FLT_CHARS[] = "dD";
72
73
74const relax_typeS md_relax_table[] = {
75 /* Conditional branches. */
76 {0xff, -0x100, 2, 1},
77 {0x1fffff, -0x200000, 6, 0},
78 /* Unconditional branches. */
79 {0xff, -0x100, 2, 3},
80 {0x1fffff, -0x200000, 4, 0},
81};
82
83static int v850_relax = 0;
84
85/* Fixups. */
86#define MAX_INSN_FIXUPS (5)
87struct v850_fixup {
88 expressionS exp;
89 int opindex;
90 bfd_reloc_code_real_type reloc;
91};
92
93struct v850_fixup fixups[MAX_INSN_FIXUPS];
94static int fc;
95
96struct v850_seg_entry
97{
98 segT s;
99 const char *name;
100 flagword flags;
101};
102
103struct v850_seg_entry v850_seg_table[] =
104{
105 { NULL, ".sdata",
106 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
107 | SEC_SMALL_DATA },
108 { NULL, ".tdata",
109 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS },
110 { NULL, ".zdata",
111 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS },
112 { NULL, ".sbss",
113 SEC_ALLOC | SEC_SMALL_DATA },
114 { NULL, ".tbss",
115 SEC_ALLOC },
116 { NULL, ".zbss",
117 SEC_ALLOC},
118 { NULL, ".rosdata",
119 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | SEC_DATA
120 | SEC_HAS_CONTENTS | SEC_SMALL_DATA },
121 { NULL, ".rozdata",
122 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | SEC_DATA
123 | SEC_HAS_CONTENTS },
124 { NULL, ".scommon",
125 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
126 | SEC_SMALL_DATA | SEC_IS_COMMON },
127 { NULL, ".tcommon",
128 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
129 | SEC_IS_COMMON },
130 { NULL, ".zcommon",
131 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
132 | SEC_IS_COMMON },
133 { NULL, ".call_table_data",
134 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS },
135 { NULL, ".call_table_text",
136 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | SEC_CODE
137 | SEC_HAS_CONTENTS},
138 { NULL, ".bss",
139 SEC_ALLOC }
140};
141
142#define SDATA_SECTION 0
143#define TDATA_SECTION 1
144#define ZDATA_SECTION 2
145#define SBSS_SECTION 3
146#define TBSS_SECTION 4
147#define ZBSS_SECTION 5
148#define ROSDATA_SECTION 6
149#define ROZDATA_SECTION 7
150#define SCOMMON_SECTION 8
151#define TCOMMON_SECTION 9
152#define ZCOMMON_SECTION 10
153#define CALL_TABLE_DATA_SECTION 11
154#define CALL_TABLE_TEXT_SECTION 12
155#define BSS_SECTION 13
156
157static void do_v850_seg PARAMS ((int, subsegT));
158
159static void
160do_v850_seg (i, sub)
161 int i;
162 subsegT sub;
163{
164 struct v850_seg_entry *seg = v850_seg_table + i;
165
166 obj_elf_section_change_hook ();
167 if (seg->s != NULL)
168 {
169 subseg_set (seg->s, sub);
170 }
171 else
172 {
173 seg->s = subseg_new (seg->name, sub);
174 bfd_set_section_flags (stdoutput, seg->s, seg->flags);
175 if ((seg->flags & SEC_LOAD) == 0)
176 seg_info (seg->s)->bss = 1;
177 }
178}
179
180static void v850_seg PARAMS ((int i));
181
182static void
183v850_seg (i)
184 int i;
185{
186 subsegT sub = get_absolute_expression ();
187
188 do_v850_seg (i, sub);
189 demand_empty_rest_of_line ();
190}
191
192static void v850_offset PARAMS ((int));
193
194static void
195v850_offset (ignore)
196 int ignore ATTRIBUTE_UNUSED;
197{
198 char *pfrag;
199 int temp = get_absolute_expression ();
200
201 pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, (symbolS *)0,
202 (offsetT) temp, (char *) 0);
203 *pfrag = 0;
204
205 demand_empty_rest_of_line ();
206}
207
208/* Copied from obj_elf_common() in gas/config/obj-elf.c. */
209
210static void v850_comm PARAMS ((int));
211
212static void
213v850_comm (area)
214 int area;
215{
216 char *name;
217 char c;
218 char *p;
219 int temp;
220 unsigned int size;
221 symbolS *symbolP;
222 int have_align;
223
224 name = input_line_pointer;
225 c = get_symbol_end ();
226
227 /* Just after name is now '\0'. */
228 p = input_line_pointer;
229 *p = c;
230
231 SKIP_WHITESPACE ();
232
233 if (*input_line_pointer != ',')
234 {
235 as_bad (_("Expected comma after symbol-name"));
236 ignore_rest_of_line ();
237 return;
238 }
239
240 /* Skip ','. */
241 input_line_pointer++;
242
243 if ((temp = get_absolute_expression ()) < 0)
244 {
245 /* xgettext:c-format */
246 as_bad (_(".COMMon length (%d.) < 0! Ignored."), temp);
247 ignore_rest_of_line ();
248 return;
249 }
250
251 size = temp;
252 *p = 0;
253 symbolP = symbol_find_or_make (name);
254 *p = c;
255
256 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
257 {
258 as_bad (_("Ignoring attempt to re-define symbol"));
259 ignore_rest_of_line ();
260 return;
261 }
262
263 if (S_GET_VALUE (symbolP) != 0)
264 {
265 if (S_GET_VALUE (symbolP) != size)
266 {
267 /* xgettext:c-format */
268 as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."),
269 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
270 }
271 }
272
273 know (symbol_get_frag (symbolP) == &zero_address_frag);
274
275 if (*input_line_pointer != ',')
276 have_align = 0;
277 else
278 {
279 have_align = 1;
280 input_line_pointer++;
281 SKIP_WHITESPACE ();
282 }
283
284 if (! have_align || *input_line_pointer != '"')
285 {
286 if (! have_align)
287 temp = 0;
288 else
289 {
290 temp = get_absolute_expression ();
291
292 if (temp < 0)
293 {
294 temp = 0;
295 as_warn (_("Common alignment negative; 0 assumed"));
296 }
297 }
298
299 if (symbol_get_obj (symbolP)->local)
300 {
301 segT old_sec;
302 int old_subsec;
303 char *pfrag;
304 int align;
305 flagword applicable;
306
307 old_sec = now_seg;
308 old_subsec = now_subseg;
309
310 applicable = bfd_applicable_section_flags (stdoutput);
311
312 applicable &= SEC_ALLOC;
313
314 switch (area)
315 {
316 case SCOMMON_SECTION:
317 do_v850_seg (SBSS_SECTION, 0);
318 break;
319
320 case ZCOMMON_SECTION:
321 do_v850_seg (ZBSS_SECTION, 0);
322 break;
323
324 case TCOMMON_SECTION:
325 do_v850_seg (TBSS_SECTION, 0);
326 break;
327 }
328
329 if (temp)
330 {
331 /* Convert to a power of 2 alignment. */
332 for (align = 0; (temp & 1) == 0; temp >>= 1, ++align)
333 ;
334
335 if (temp != 1)
336 {
337 as_bad (_("Common alignment not a power of 2"));
338 ignore_rest_of_line ();
339 return;
340 }
341 }
342 else
343 align = 0;
344
345 record_alignment (now_seg, align);
346
347 if (align)
348 frag_align (align, 0, 0);
349
350 switch (area)
351 {
352 case SCOMMON_SECTION:
353 if (S_GET_SEGMENT (symbolP) == v850_seg_table[SBSS_SECTION].s)
354 symbol_get_frag (symbolP)->fr_symbol = 0;
355 break;
356
357 case ZCOMMON_SECTION:
358 if (S_GET_SEGMENT (symbolP) == v850_seg_table[ZBSS_SECTION].s)
359 symbol_get_frag (symbolP)->fr_symbol = 0;
360 break;
361
362 case TCOMMON_SECTION:
363 if (S_GET_SEGMENT (symbolP) == v850_seg_table[TBSS_SECTION].s)
364 symbol_get_frag (symbolP)->fr_symbol = 0;
365 break;
366
367 default:
368 abort ();
369 }
370
371 symbol_set_frag (symbolP, frag_now);
372 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
373 (offsetT) size, (char *) 0);
374 *pfrag = 0;
375 S_SET_SIZE (symbolP, size);
376
377 switch (area)
378 {
379 case SCOMMON_SECTION:
380 S_SET_SEGMENT (symbolP, v850_seg_table[SBSS_SECTION].s);
381 break;
382
383 case ZCOMMON_SECTION:
384 S_SET_SEGMENT (symbolP, v850_seg_table[ZBSS_SECTION].s);
385 break;
386
387 case TCOMMON_SECTION:
388 S_SET_SEGMENT (symbolP, v850_seg_table[TBSS_SECTION].s);
389 break;
390
391 default:
392 abort ();
393 }
394
395 S_CLEAR_EXTERNAL (symbolP);
396 obj_elf_section_change_hook ();
397 subseg_set (old_sec, old_subsec);
398 }
399 else
400 {
401 segT old_sec;
402 int old_subsec;
403
404 allocate_common:
405 old_sec = now_seg;
406 old_subsec = now_subseg;
407
408 S_SET_VALUE (symbolP, (valueT) size);
409 S_SET_ALIGN (symbolP, temp);
410 S_SET_EXTERNAL (symbolP);
411
412 switch (area)
413 {
414 case SCOMMON_SECTION:
415 case ZCOMMON_SECTION:
416 case TCOMMON_SECTION:
417 do_v850_seg (area, 0);
418 S_SET_SEGMENT (symbolP, v850_seg_table[area].s);
419 break;
420
421 default:
422 abort ();
423 }
424
425 obj_elf_section_change_hook ();
426 subseg_set (old_sec, old_subsec);
427 }
428 }
429 else
430 {
431 input_line_pointer++;
432
433 /* @@ Some use the dot, some don't. Can we get some consistency?? */
434 if (*input_line_pointer == '.')
435 input_line_pointer++;
436
437 /* @@ Some say data, some say bss. */
438 if (strncmp (input_line_pointer, "bss\"", 4)
439 && strncmp (input_line_pointer, "data\"", 5))
440 {
441 while (*--input_line_pointer != '"')
442 ;
443 input_line_pointer--;
444 goto bad_common_segment;
445 }
446 while (*input_line_pointer++ != '"')
447 ;
448 goto allocate_common;
449 }
450
451 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
452
453 demand_empty_rest_of_line ();
454 return;
455
456 {
457 bad_common_segment:
458 p = input_line_pointer;
459 while (*p && *p != '\n')
460 p++;
461 c = *p;
462 *p = '\0';
463 as_bad (_("bad .common segment %s"), input_line_pointer + 1);
464 *p = c;
465 input_line_pointer = p;
466 ignore_rest_of_line ();
467 return;
468 }
469}
470
471static void set_machine PARAMS ((int));
472
473static void
474set_machine (number)
475 int number;
476{
477 machine = number;
478 bfd_set_arch_mach (stdoutput, TARGET_ARCH, machine);
479
480 switch (machine)
481 {
482 case 0: processor_mask = PROCESSOR_V850; break;
483 case bfd_mach_v850e: processor_mask = PROCESSOR_V850E; break;
484 }
485}
486
487static void v850_longcode PARAMS ((int));
488
489static void
490v850_longcode (type)
491 int type;
492{
493 expressionS ex;
494
495 if (! v850_relax)
496 {
497 if (type == 1)
498 as_warn (".longcall pseudo-op seen when not relaxing");
499 else
500 as_warn (".longjump pseudo-op seen when not relaxing");
501 }
502
503 expression (&ex);
504
505 if (ex.X_op != O_symbol || ex.X_add_number != 0)
506 {
507 as_bad ("bad .longcall format");
508 ignore_rest_of_line ();
509
510 return;
511 }
512
513 if (type == 1)
514 fix_new_exp (frag_now, frag_now_fix (), 4, & ex, 1,
515 BFD_RELOC_V850_LONGCALL);
516 else
517 fix_new_exp (frag_now, frag_now_fix (), 4, & ex, 1,
518 BFD_RELOC_V850_LONGJUMP);
519
520 demand_empty_rest_of_line ();
521}
522
523/* The target specific pseudo-ops which we support. */
524const pseudo_typeS md_pseudo_table[] =
525{
526 { "sdata", v850_seg, SDATA_SECTION },
527 { "tdata", v850_seg, TDATA_SECTION },
528 { "zdata", v850_seg, ZDATA_SECTION },
529 { "sbss", v850_seg, SBSS_SECTION },
530 { "tbss", v850_seg, TBSS_SECTION },
531 { "zbss", v850_seg, ZBSS_SECTION },
532 { "rosdata", v850_seg, ROSDATA_SECTION },
533 { "rozdata", v850_seg, ROZDATA_SECTION },
534 { "bss", v850_seg, BSS_SECTION },
535 { "offset", v850_offset, 0 },
536 { "word", cons, 4 },
537 { "zcomm", v850_comm, ZCOMMON_SECTION },
538 { "scomm", v850_comm, SCOMMON_SECTION },
539 { "tcomm", v850_comm, TCOMMON_SECTION },
540 { "v850", set_machine, 0 },
541 { "call_table_data", v850_seg, CALL_TABLE_DATA_SECTION },
542 { "call_table_text", v850_seg, CALL_TABLE_TEXT_SECTION },
543 { "v850e", set_machine, bfd_mach_v850e },
544 { "file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
545 { "loc", dwarf2_directive_loc, 0 },
546 { "longcall", v850_longcode, 1 },
547 { "longjump", v850_longcode, 2 },
548 { NULL, NULL, 0 }
549};
550
551/* Opcode hash table. */
552static struct hash_control *v850_hash;
553
554/* This table is sorted. Suitable for searching by a binary search. */
555static const struct reg_name pre_defined_registers[] =
556{
557 { "ep", 30 }, /* ep - element ptr */
558 { "gp", 4 }, /* gp - global ptr */
559 { "hp", 2 }, /* hp - handler stack ptr */
560 { "lp", 31 }, /* lp - link ptr */
561 { "r0", 0 },
562 { "r1", 1 },
563 { "r10", 10 },
564 { "r11", 11 },
565 { "r12", 12 },
566 { "r13", 13 },
567 { "r14", 14 },
568 { "r15", 15 },
569 { "r16", 16 },
570 { "r17", 17 },
571 { "r18", 18 },
572 { "r19", 19 },
573 { "r2", 2 },
574 { "r20", 20 },
575 { "r21", 21 },
576 { "r22", 22 },
577 { "r23", 23 },
578 { "r24", 24 },
579 { "r25", 25 },
580 { "r26", 26 },
581 { "r27", 27 },
582 { "r28", 28 },
583 { "r29", 29 },
584 { "r3", 3 },
585 { "r30", 30 },
586 { "r31", 31 },
587 { "r4", 4 },
588 { "r5", 5 },
589 { "r6", 6 },
590 { "r7", 7 },
591 { "r8", 8 },
592 { "r9", 9 },
593 { "sp", 3 }, /* sp - stack ptr */
594 { "tp", 5 }, /* tp - text ptr */
595 { "zero", 0 },
596};
597
598#define REG_NAME_CNT \
599 (sizeof (pre_defined_registers) / sizeof (struct reg_name))
600
601static const struct reg_name system_registers[] =
602{
603 { "asid", 23 },
604 { "bpc", 22 },
605 { "bpav", 24 },
606 { "bpam", 25 },
607 { "bpdv", 26 },
608 { "bpdm", 27 },
609 { "ctbp", 20 },
610 { "ctpc", 16 },
611 { "ctpsw", 17 },
612 { "dbpc", 18 },
613 { "dbpsw", 19 },
614 { "dir", 21 },
615 { "ecr", 4 },
616 { "eipc", 0 },
617 { "eipsw", 1 },
618 { "fepc", 2 },
619 { "fepsw", 3 },
620 { "psw", 5 },
621};
622
623#define SYSREG_NAME_CNT \
624 (sizeof (system_registers) / sizeof (struct reg_name))
625
626static const struct reg_name system_list_registers[] =
627{
628 {"PS", 5 },
629 {"SR", 0 + 1}
630};
631
632#define SYSREGLIST_NAME_CNT \
633 (sizeof (system_list_registers) / sizeof (struct reg_name))
634
635static const struct reg_name cc_names[] =
636{
637 { "c", 0x1 },
638 { "e", 0x2 },
639 { "ge", 0xe },
640 { "gt", 0xf },
641 { "h", 0xb },
642 { "l", 0x1 },
643 { "le", 0x7 },
644 { "lt", 0x6 },
645 { "n", 0x4 },
646 { "nc", 0x9 },
647 { "ne", 0xa },
648 { "nh", 0x3 },
649 { "nl", 0x9 },
650 { "ns", 0xc },
651 { "nv", 0x8 },
652 { "nz", 0xa },
653 { "p", 0xc },
654 { "s", 0x4 },
655 { "sa", 0xd },
656 { "t", 0x5 },
657 { "v", 0x0 },
658 { "z", 0x2 },
659};
660
661#define CC_NAME_CNT \
662 (sizeof (cc_names) / sizeof (struct reg_name))
663
664/* Do a binary search of the given register table to see if NAME is a
665 valid regiter name. Return the register number from the array on
666 success, or -1 on failure. */
667
668static int reg_name_search
669 PARAMS ((const struct reg_name *, int, const char *, bfd_boolean));
670
671static int
672reg_name_search (regs, regcount, name, accept_numbers)
673 const struct reg_name *regs;
674 int regcount;
675 const char *name;
676 bfd_boolean accept_numbers;
677{
678 int middle, low, high;
679 int cmp;
680 symbolS *symbolP;
681
682 /* If the register name is a symbol, then evaluate it. */
683 if ((symbolP = symbol_find (name)) != NULL)
684 {
685 /* If the symbol is an alias for another name then use that.
686 If the symbol is an alias for a number, then return the number. */
687 if (symbol_equated_p (symbolP))
688 {
689 name
690 = S_GET_NAME (symbol_get_value_expression (symbolP)->X_add_symbol);
691 }
692 else if (accept_numbers)
693 {
694 int reg = S_GET_VALUE (symbolP);
695
696 if (reg >= 0 && reg <= 31)
697 return reg;
698 }
699
700 /* Otherwise drop through and try parsing name normally. */
701 }
702
703 low = 0;
704 high = regcount - 1;
705
706 do
707 {
708 middle = (low + high) / 2;
709 cmp = strcasecmp (name, regs[middle].name);
710 if (cmp < 0)
711 high = middle - 1;
712 else if (cmp > 0)
713 low = middle + 1;
714 else
715 return regs[middle].value;
716 }
717 while (low <= high);
718 return -1;
719}
720
721/* Summary of register_name().
722
723 in: Input_line_pointer points to 1st char of operand.
724
725 out: An expressionS.
726 The operand may have been a register: in this case, X_op == O_register,
727 X_add_number is set to the register number, and truth is returned.
728 Input_line_pointer->(next non-blank) char after operand, or is in
729 its original state. */
730
731static bfd_boolean register_name PARAMS ((expressionS *));
732
733static bfd_boolean
734register_name (expressionP)
735 expressionS *expressionP;
736{
737 int reg_number;
738 char *name;
739 char *start;
740 char c;
741
742 /* Find the spelling of the operand. */
743 start = name = input_line_pointer;
744
745 c = get_symbol_end ();
746
747 reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT,
748 name, FALSE);
749
750 /* Put back the delimiting char. */
751 *input_line_pointer = c;
752
753 /* Look to see if it's in the register table. */
754 if (reg_number >= 0)
755 {
756 expressionP->X_op = O_register;
757 expressionP->X_add_number = reg_number;
758
759 /* Make the rest nice. */
760 expressionP->X_add_symbol = NULL;
761 expressionP->X_op_symbol = NULL;
762
763 return TRUE;
764 }
765 else
766 {
767 /* Reset the line as if we had not done anything. */
768 input_line_pointer = start;
769
770 return FALSE;
771 }
772}
773
774/* Summary of system_register_name().
775
776 in: INPUT_LINE_POINTER points to 1st char of operand.
777 EXPRESSIONP points to an expression structure to be filled in.
778 ACCEPT_NUMBERS is true iff numerical register names may be used.
779 ACCEPT_LIST_NAMES is true iff the special names PS and SR may be
780 accepted.
781
782 out: An expressionS structure in expressionP.
783 The operand may have been a register: in this case, X_op == O_register,
784 X_add_number is set to the register number, and truth is returned.
785 Input_line_pointer->(next non-blank) char after operand, or is in
786 its original state. */
787
788static bfd_boolean system_register_name
789 PARAMS ((expressionS *, bfd_boolean, bfd_boolean));
790
791static bfd_boolean
792system_register_name (expressionP, accept_numbers, accept_list_names)
793 expressionS *expressionP;
794 bfd_boolean accept_numbers;
795 bfd_boolean accept_list_names;
796{
797 int reg_number;
798 char *name;
799 char *start;
800 char c;
801
802 /* Find the spelling of the operand. */
803 start = name = input_line_pointer;
804
805 c = get_symbol_end ();
806 reg_number = reg_name_search (system_registers, SYSREG_NAME_CNT, name,
807 accept_numbers);
808
809 /* Put back the delimiting char. */
810 *input_line_pointer = c;
811
812 if (reg_number < 0
813 && accept_numbers)
814 {
815 /* Reset input_line pointer. */
816 input_line_pointer = start;
817
818 if (ISDIGIT (*input_line_pointer))
819 {
820 reg_number = strtol (input_line_pointer, &input_line_pointer, 10);
821
822 /* Make sure that the register number is allowable. */
823 if (reg_number < 0
824 || (reg_number > 5 && reg_number < 16)
825 || reg_number > 27)
826 {
827 reg_number = -1;
828 }
829 }
830 else if (accept_list_names)
831 {
832 c = get_symbol_end ();
833 reg_number = reg_name_search (system_list_registers,
834 SYSREGLIST_NAME_CNT, name, FALSE);
835
836 /* Put back the delimiting char. */
837 *input_line_pointer = c;
838 }
839 }
840
841 /* Look to see if it's in the register table. */
842 if (reg_number >= 0)
843 {
844 expressionP->X_op = O_register;
845 expressionP->X_add_number = reg_number;
846
847 /* Make the rest nice. */
848 expressionP->X_add_symbol = NULL;
849 expressionP->X_op_symbol = NULL;
850
851 return TRUE;
852 }
853 else
854 {
855 /* Reset the line as if we had not done anything. */
856 input_line_pointer = start;
857
858 return FALSE;
859 }
860}
861
862/* Summary of cc_name().
863
864 in: INPUT_LINE_POINTER points to 1st char of operand.
865
866 out: An expressionS.
867 The operand may have been a register: in this case, X_op == O_register,
868 X_add_number is set to the register number, and truth is returned.
869 Input_line_pointer->(next non-blank) char after operand, or is in
870 its original state. */
871
872static bfd_boolean cc_name PARAMS ((expressionS *));
873
874static bfd_boolean
875cc_name (expressionP)
876 expressionS *expressionP;
877{
878 int reg_number;
879 char *name;
880 char *start;
881 char c;
882
883 /* Find the spelling of the operand. */
884 start = name = input_line_pointer;
885
886 c = get_symbol_end ();
887 reg_number = reg_name_search (cc_names, CC_NAME_CNT, name, FALSE);
888
889 /* Put back the delimiting char. */
890 *input_line_pointer = c;
891
892 /* Look to see if it's in the register table. */
893 if (reg_number >= 0)
894 {
895 expressionP->X_op = O_constant;
896 expressionP->X_add_number = reg_number;
897
898 /* Make the rest nice. */
899 expressionP->X_add_symbol = NULL;
900 expressionP->X_op_symbol = NULL;
901
902 return TRUE;
903 }
904 else
905 {
906 /* Reset the line as if we had not done anything. */
907 input_line_pointer = start;
908
909 return FALSE;
910 }
911}
912
913static void skip_white_space PARAMS ((void));
914
915static void
916skip_white_space ()
917{
918 while (*input_line_pointer == ' '
919 || *input_line_pointer == '\t')
920 ++input_line_pointer;
921}
922
923/* Summary of parse_register_list ().
924
925 in: INPUT_LINE_POINTER points to 1st char of a list of registers.
926 INSN is the partially constructed instruction.
927 OPERAND is the operand being inserted.
928
929 out: NULL if the parse completed successfully, otherwise a
930 pointer to an error message is returned. If the parse
931 completes the correct bit fields in the instruction
932 will be filled in.
933
934 Parses register lists with the syntax:
935
936 { rX }
937 { rX, rY }
938 { rX - rY }
939 { rX - rY, rZ }
940 etc
941
942 and also parses constant epxressions whoes bits indicate the
943 registers in the lists. The LSB in the expression refers to
944 the lowest numbered permissable register in the register list,
945 and so on upwards. System registers are considered to be very
946 high numbers. */
947
948static char *parse_register_list
949 PARAMS ((unsigned long *, const struct v850_operand *));
950
951static char *
952parse_register_list (insn, operand)
953 unsigned long *insn;
954 const struct v850_operand *operand;
955{
956 static int type1_regs[32] = {
957 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
958 0, 0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24
959 };
960 static int type2_regs[32] = {
961 19, 18, 17, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
962 0, 0, 0, 0, 30, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24
963 };
964 static int type3_regs[32] = {
965 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
966 0, 0, 0, 0, 14, 15, 13, 12, 7, 6, 5, 4, 11, 10, 9, 8
967 };
968 int *regs;
969 expressionS exp;
970
971 /* Select a register array to parse. */
972 switch (operand->shift)
973 {
974 case 0xffe00001: regs = type1_regs; break;
975 case 0xfff8000f: regs = type2_regs; break;
976 case 0xfff8001f: regs = type3_regs; break;
977 default:
978 as_bad (_("unknown operand shift: %x\n"), operand->shift);
979 return _("internal failure in parse_register_list");
980 }
981
982 skip_white_space ();
983
984 /* If the expression starts with a curly brace it is a register list.
985 Otherwise it is a constant expression, whoes bits indicate which
986 registers are to be included in the list. */
987 if (*input_line_pointer != '{')
988 {
989 int reg;
990 int i;
991
992 expression (&exp);
993
994 if (exp.X_op != O_constant)
995 return _("constant expression or register list expected");
996
997 if (regs == type1_regs)
998 {
999 if (exp.X_add_number & 0xFFFFF000)
1000 return _("high bits set in register list expression");
1001
1002 for (reg = 20; reg < 32; reg++)
1003 if (exp.X_add_number & (1 << (reg - 20)))
1004 {
1005 for (i = 0; i < 32; i++)
1006 if (regs[i] == reg)
1007 *insn |= (1 << i);
1008 }
1009 }
1010 else if (regs == type2_regs)
1011 {
1012 if (exp.X_add_number & 0xFFFE0000)
1013 return _("high bits set in register list expression");
1014
1015 for (reg = 1; reg < 16; reg++)
1016 if (exp.X_add_number & (1 << (reg - 1)))
1017 {
1018 for (i = 0; i < 32; i++)
1019 if (regs[i] == reg)
1020 *insn |= (1 << i);
1021 }
1022
1023 if (exp.X_add_number & (1 << 15))
1024 *insn |= (1 << 3);
1025
1026 if (exp.X_add_number & (1 << 16))
1027 *insn |= (1 << 19);
1028 }
1029 else /* regs == type3_regs */
1030 {
1031 if (exp.X_add_number & 0xFFFE0000)
1032 return _("high bits set in register list expression");
1033
1034 for (reg = 16; reg < 32; reg++)
1035 if (exp.X_add_number & (1 << (reg - 16)))
1036 {
1037 for (i = 0; i < 32; i++)
1038 if (regs[i] == reg)
1039 *insn |= (1 << i);
1040 }
1041
1042 if (exp.X_add_number & (1 << 16))
1043 *insn |= (1 << 19);
1044 }
1045
1046 return NULL;
1047 }
1048
1049 input_line_pointer++;
1050
1051 /* Parse the register list until a terminator (closing curly brace or
1052 new-line) is found. */
1053 for (;;)
1054 {
1055 if (register_name (&exp))
1056 {
1057 int i;
1058
1059 /* Locate the given register in the list, and if it is there,
1060 insert the corresponding bit into the instruction. */
1061 for (i = 0; i < 32; i++)
1062 {
1063 if (regs[i] == exp.X_add_number)
1064 {
1065 *insn |= (1 << i);
1066 break;
1067 }
1068 }
1069
1070 if (i == 32)
1071 return _("illegal register included in list");
1072 }
1073 else if (system_register_name (&exp, TRUE, TRUE))
1074 {
1075 if (regs == type1_regs)
1076 {
1077 return _("system registers cannot be included in list");
1078 }
1079 else if (exp.X_add_number == 5)
1080 {
1081 if (regs == type2_regs)
1082 return _("PSW cannot be included in list");
1083 else
1084 *insn |= 0x8;
1085 }
1086 else if (exp.X_add_number < 4)
1087 *insn |= 0x80000;
1088 else
1089 return _("High value system registers cannot be included in list");
1090 }
1091 else if (*input_line_pointer == '}')
1092 {
1093 input_line_pointer++;
1094 break;
1095 }
1096 else if (*input_line_pointer == ',')
1097 {
1098 input_line_pointer++;
1099 continue;
1100 }
1101 else if (*input_line_pointer == '-')
1102 {
1103 /* We have encountered a range of registers: rX - rY. */
1104 int j;
1105 expressionS exp2;
1106
1107 /* Skip the dash. */
1108 ++input_line_pointer;
1109
1110 /* Get the second register in the range. */
1111 if (! register_name (&exp2))
1112 {
1113 return _("second register should follow dash in register list");
1114 exp2.X_add_number = exp.X_add_number;
1115 }
1116
1117 /* Add the rest of the registers in the range. */
1118 for (j = exp.X_add_number + 1; j <= exp2.X_add_number; j++)
1119 {
1120 int i;
1121
1122 /* Locate the given register in the list, and if it is there,
1123 insert the corresponding bit into the instruction. */
1124 for (i = 0; i < 32; i++)
1125 {
1126 if (regs[i] == j)
1127 {
1128 *insn |= (1 << i);
1129 break;
1130 }
1131 }
1132
1133 if (i == 32)
1134 return _("illegal register included in list");
1135 }
1136 }
1137 else
1138 break;
1139
1140 skip_white_space ();
1141 }
1142
1143 return NULL;
1144}
1145
1146const char *md_shortopts = "m:";
1147
1148struct option md_longopts[] = {
1149 {NULL, no_argument, NULL, 0}
1150};
1151
1152size_t md_longopts_size = sizeof (md_longopts);
1153
1154void
1155md_show_usage (stream)
1156 FILE *stream;
1157{
1158 fprintf (stream, _(" V850 options:\n"));
1159 fprintf (stream, _(" -mwarn-signed-overflow Warn if signed immediate values overflow\n"));
1160 fprintf (stream, _(" -mwarn-unsigned-overflow Warn if unsigned immediate values overflow\n"));
1161 fprintf (stream, _(" -mv850 The code is targeted at the v850\n"));
1162 fprintf (stream, _(" -mv850e The code is targeted at the v850e\n"));
1163 fprintf (stream, _(" -mv850any The code is generic, despite any processor specific instructions\n"));
1164 fprintf (stream, _(" -mrelax Enable relaxation\n"));
1165
1166}
1167
1168int
1169md_parse_option (c, arg)
1170 int c;
1171 char *arg;
1172{
1173 if (c != 'm')
1174 {
1175 if (c != 'a')
1176 /* xgettext:c-format */
1177 fprintf (stderr, _("unknown command line option: -%c%s\n"), c, arg);
1178 return 0;
1179 }
1180
1181 if (strcmp (arg, "warn-signed-overflow") == 0)
1182 {
1183 warn_signed_overflows = TRUE;
1184 }
1185 else if (strcmp (arg, "warn-unsigned-overflow") == 0)
1186 {
1187 warn_unsigned_overflows = TRUE;
1188 }
1189 else if (strcmp (arg, "v850") == 0)
1190 {
1191 machine = 0;
1192 processor_mask = PROCESSOR_V850;
1193 }
1194 else if (strcmp (arg, "v850e") == 0)
1195 {
1196 machine = bfd_mach_v850e;
1197 processor_mask = PROCESSOR_V850E;
1198 }
1199 else if (strcmp (arg, "v850any") == 0)
1200 {
1201 /* Tell the world that this is for any v850 chip. */
1202 machine = 0;
1203
1204 /* But support instructions for the extended versions. */
1205 processor_mask = PROCESSOR_V850E;
1206 }
1207 else if (strcmp (arg, "relax") == 0)
1208 v850_relax = 1;
1209 else
1210 {
1211 /* xgettext:c-format */
1212 fprintf (stderr, _("unknown command line option: -%c%s\n"), c, arg);
1213 return 0;
1214 }
1215
1216 return 1;
1217}
1218
1219symbolS *
1220md_undefined_symbol (name)
1221 char *name ATTRIBUTE_UNUSED;
1222{
1223 return 0;
1224}
1225
1226char *
1227md_atof (type, litp, sizep)
1228 int type;
1229 char *litp;
1230 int *sizep;
1231{
1232 int prec;
1233 LITTLENUM_TYPE words[4];
1234 char *t;
1235 int i;
1236
1237 switch (type)
1238 {
1239 case 'f':
1240 prec = 2;
1241 break;
1242
1243 case 'd':
1244 prec = 4;
1245 break;
1246
1247 default:
1248 *sizep = 0;
1249 return _("bad call to md_atof");
1250 }
1251
1252 t = atof_ieee (input_line_pointer, type, words);
1253 if (t)
1254 input_line_pointer = t;
1255
1256 *sizep = prec * 2;
1257
1258 for (i = prec - 1; i >= 0; i--)
1259 {
1260 md_number_to_chars (litp, (valueT) words[i], 2);
1261 litp += 2;
1262 }
1263
1264 return NULL;
1265}
1266
1267/* Very gross. */
1268
1269void
1270md_convert_frag (abfd, sec, fragP)
1271 bfd *abfd ATTRIBUTE_UNUSED;
1272 asection *sec;
1273 fragS *fragP;
1274{
1275 subseg_change (sec, 0);
1276
1277 /* In range conditional or unconditional branch. */
1278 if (fragP->fr_subtype == 0 || fragP->fr_subtype == 2)
1279 {
1280 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
1281 fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode);
1282 fragP->fr_fix += 2;
1283 }
1284 /* Out of range conditional branch. Emit a branch around a jump. */
1285 else if (fragP->fr_subtype == 1)
1286 {
1287 unsigned char *buffer =
1288 (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
1289
1290 /* Reverse the condition of the first branch. */
1291 buffer[0] ^= 0x08;
1292 /* Mask off all the displacement bits. */
1293 buffer[0] &= 0x8f;
1294 buffer[1] &= 0x07;
1295 /* Now set the displacement bits so that we branch
1296 around the unconditional branch. */
1297 buffer[0] |= 0x30;
1298
1299 /* Now create the unconditional branch + fixup to the final
1300 target. */
1301 md_number_to_chars (buffer + 2, 0x00000780, 4);
1302 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
1303 fragP->fr_offset, 1, BFD_RELOC_UNUSED +
1304 (int) fragP->fr_opcode + 1);
1305 fragP->fr_fix += 6;
1306 }
1307 /* Out of range unconditional branch. Emit a jump. */
1308 else if (fragP->fr_subtype == 3)
1309 {
1310 md_number_to_chars (fragP->fr_fix + fragP->fr_literal, 0x00000780, 4);
1311 fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
1312 fragP->fr_offset, 1, BFD_RELOC_UNUSED +
1313 (int) fragP->fr_opcode + 1);
1314 fragP->fr_fix += 4;
1315 }
1316 else
1317 abort ();
1318}
1319
1320valueT
1321md_section_align (seg, addr)
1322 asection *seg;
1323 valueT addr;
1324{
1325 int align = bfd_get_section_alignment (stdoutput, seg);
1326 return ((addr + (1 << align) - 1) & (-1 << align));
1327}
1328
1329void
1330md_begin ()
1331{
1332 char *prev_name = "";
1333 const struct v850_opcode *op;
1334
1335 if (strncmp (TARGET_CPU, "v850e", 5) == 0)
1336 {
1337 if (machine == -1)
1338 machine = bfd_mach_v850e;
1339
1340 if (processor_mask == -1)
1341 processor_mask = PROCESSOR_V850E;
1342 }
1343 else if (strncmp (TARGET_CPU, "v850", 4) == 0)
1344 {
1345 if (machine == -1)
1346 machine = 0;
1347
1348 if (processor_mask == -1)
1349 processor_mask = PROCESSOR_V850;
1350 }
1351 else
1352 /* xgettext:c-format */
1353 as_bad (_("Unable to determine default target processor from string: %s"),
1354 TARGET_CPU);
1355
1356 v850_hash = hash_new ();
1357
1358 /* Insert unique names into hash table. The V850 instruction set
1359 has many identical opcode names that have different opcodes based
1360 on the operands. This hash table then provides a quick index to
1361 the first opcode with a particular name in the opcode table. */
1362 op = v850_opcodes;
1363 while (op->name)
1364 {
1365 if (strcmp (prev_name, op->name))
1366 {
1367 prev_name = (char *) op->name;
1368 hash_insert (v850_hash, op->name, (char *) op);
1369 }
1370 op++;
1371 }
1372
1373 v850_seg_table[BSS_SECTION].s = bss_section;
1374 bfd_set_arch_mach (stdoutput, TARGET_ARCH, machine);
1375}
1376
1377static bfd_reloc_code_real_type handle_ctoff
1378 PARAMS ((const struct v850_operand *));
1379
1380static bfd_reloc_code_real_type
1381handle_ctoff (operand)
1382 const struct v850_operand *operand;
1383{
1384 if (operand == NULL)
1385 return BFD_RELOC_V850_CALLT_16_16_OFFSET;
1386
1387 if (operand->bits != 6
1388 || operand->shift != 0)
1389 {
1390 as_bad (_("ctoff() relocation used on an instruction which does not support it"));
1391 return BFD_RELOC_64; /* Used to indicate an error condition. */
1392 }
1393
1394 return BFD_RELOC_V850_CALLT_6_7_OFFSET;
1395}
1396
1397static bfd_reloc_code_real_type handle_sdaoff
1398 PARAMS ((const struct v850_operand *));
1399
1400static bfd_reloc_code_real_type
1401handle_sdaoff (operand)
1402 const struct v850_operand *operand;
1403{
1404 if (operand == NULL)
1405 return BFD_RELOC_V850_SDA_16_16_OFFSET;
1406
1407 if (operand->bits == 15 && operand->shift == 17)
1408 return BFD_RELOC_V850_SDA_15_16_OFFSET;
1409
1410 if (operand->bits == -1)
1411 return BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET;
1412
1413 if (operand->bits != 16
1414 || operand->shift != 16)
1415 {
1416 as_bad (_("sdaoff() relocation used on an instruction which does not support it"));
1417 return BFD_RELOC_64; /* Used to indicate an error condition. */
1418 }
1419
1420 return BFD_RELOC_V850_SDA_16_16_OFFSET;
1421}
1422
1423static bfd_reloc_code_real_type handle_zdaoff
1424 PARAMS ((const struct v850_operand *));
1425
1426static bfd_reloc_code_real_type
1427handle_zdaoff (operand)
1428 const struct v850_operand *operand;
1429{
1430 if (operand == NULL)
1431 return BFD_RELOC_V850_ZDA_16_16_OFFSET;
1432
1433 if (operand->bits == 15 && operand->shift == 17)
1434 return BFD_RELOC_V850_ZDA_15_16_OFFSET;
1435
1436 if (operand->bits == -1)
1437 return BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET;
1438
1439 if (operand->bits != 16
1440 || operand->shift != 16)
1441 {
1442 as_bad (_("zdaoff() relocation used on an instruction which does not support it"));
1443 /* Used to indicate an error condition. */
1444 return BFD_RELOC_64;
1445 }
1446
1447 return BFD_RELOC_V850_ZDA_16_16_OFFSET;
1448}
1449
1450static bfd_reloc_code_real_type handle_tdaoff
1451 PARAMS ((const struct v850_operand *));
1452
1453static bfd_reloc_code_real_type
1454handle_tdaoff (operand)
1455 const struct v850_operand *operand;
1456{
1457 if (operand == NULL)
1458 /* Data item, not an instruction. */
1459 return BFD_RELOC_V850_TDA_7_7_OFFSET;
1460
1461 if (operand->bits == 6 && operand->shift == 1)
1462 /* sld.w/sst.w, operand: D8_6 */
1463 return BFD_RELOC_V850_TDA_6_8_OFFSET;
1464
1465 if (operand->bits == 4 && operand->insert != NULL)
1466 /* sld.hu, operand: D5-4 */
1467 return BFD_RELOC_V850_TDA_4_5_OFFSET;
1468
1469 if (operand->bits == 4 && operand->insert == NULL)
1470 /* sld.bu, operand: D4 */
1471 return BFD_RELOC_V850_TDA_4_4_OFFSET;
1472
1473 if (operand->bits == 16 && operand->shift == 16)
1474 /* set1 & chums, operands: D16 */
1475 return BFD_RELOC_V850_TDA_16_16_OFFSET;
1476
1477 if (operand->bits != 7)
1478 {
1479 as_bad (_("tdaoff() relocation used on an instruction which does not support it"));
1480 /* Used to indicate an error condition. */
1481 return BFD_RELOC_64;
1482 }
1483
1484 return operand->insert != NULL
1485 ? BFD_RELOC_V850_TDA_7_8_OFFSET /* sld.h/sst.h, operand: D8_7 */
1486 : BFD_RELOC_V850_TDA_7_7_OFFSET; /* sld.b/sst.b, opreand: D7 */
1487}
1488
1489/* Warning: The code in this function relies upon the definitions
1490 in the v850_operands[] array (defined in opcodes/v850-opc.c)
1491 matching the hard coded values contained herein. */
1492
1493static bfd_reloc_code_real_type v850_reloc_prefix
1494 PARAMS ((const struct v850_operand *));
1495
1496static bfd_reloc_code_real_type
1497v850_reloc_prefix (operand)
1498 const struct v850_operand *operand;
1499{
1500 bfd_boolean paren_skipped = FALSE;
1501
1502 /* Skip leading opening parenthesis. */
1503 if (*input_line_pointer == '(')
1504 {
1505 ++input_line_pointer;
1506 paren_skipped = TRUE;
1507 }
1508
1509#define CHECK_(name, reloc) \
1510 if (strncmp (input_line_pointer, name "(", strlen (name) + 1) == 0) \
1511 { \
1512 input_line_pointer += strlen (name); \
1513 return reloc; \
1514 }
1515
1516 CHECK_ ("hi0", BFD_RELOC_HI16 );
1517 CHECK_ ("hi", BFD_RELOC_HI16_S );
1518 CHECK_ ("lo", BFD_RELOC_LO16 );
1519 CHECK_ ("sdaoff", handle_sdaoff (operand));
1520 CHECK_ ("zdaoff", handle_zdaoff (operand));
1521 CHECK_ ("tdaoff", handle_tdaoff (operand));
1522 CHECK_ ("hilo", BFD_RELOC_32 );
1523 CHECK_ ("ctoff", handle_ctoff (operand) );
1524
1525 /* Restore skipped parenthesis. */
1526 if (paren_skipped)
1527 --input_line_pointer;
1528
1529 return BFD_RELOC_UNUSED;
1530}
1531
1532/* Insert an operand value into an instruction. */
1533
1534static unsigned long v850_insert_operand
1535 PARAMS ((unsigned long, const struct v850_operand *, offsetT, char *,
1536 unsigned int, char *));
1537
1538static unsigned long
1539v850_insert_operand (insn, operand, val, file, line, str)
1540 unsigned long insn;
1541 const struct v850_operand *operand;
1542 offsetT val;
1543 char *file;
1544 unsigned int line;
1545 char *str;
1546{
1547 if (operand->insert)
1548 {
1549 const char *message = NULL;
1550
1551 insn = operand->insert (insn, val, &message);
1552 if (message != NULL)
1553 {
1554 if ((operand->flags & V850_OPERAND_SIGNED)
1555 && ! warn_signed_overflows
1556 && strstr (message, "out of range") != NULL)
1557 {
1558 /* Skip warning... */
1559 }
1560 else if ((operand->flags & V850_OPERAND_SIGNED) == 0
1561 && ! warn_unsigned_overflows
1562 && strstr (message, "out of range") != NULL)
1563 {
1564 /* Skip warning... */
1565 }
1566 else if (str)
1567 {
1568 if (file == (char *) NULL)
1569 as_warn ("%s: %s", str, message);
1570 else
1571 as_warn_where (file, line, "%s: %s", str, message);
1572 }
1573 else
1574 {
1575 if (file == (char *) NULL)
1576 as_warn (message);
1577 else
1578 as_warn_where (file, line, message);
1579 }
1580 }
1581 }
1582 else
1583 {
1584 if (operand->bits != 32)
1585 {
1586 long min, max;
1587
1588 if ((operand->flags & V850_OPERAND_SIGNED) != 0)
1589 {
1590 if (! warn_signed_overflows)
1591 max = (1 << operand->bits) - 1;
1592 else
1593 max = (1 << (operand->bits - 1)) - 1;
1594
1595 min = -(1 << (operand->bits - 1));
1596 }
1597 else
1598 {
1599 max = (1 << operand->bits) - 1;
1600
1601 if (! warn_unsigned_overflows)
1602 min = -(1 << (operand->bits - 1));
1603 else
1604 min = 0;
1605 }
1606
1607 if (val < (offsetT) min || val > (offsetT) max)
1608 {
1609 /* xgettext:c-format */
1610 const char *err =
1611 _("operand out of range (%s not between %ld and %ld)");
1612 char buf[100];
1613
1614 /* Restore min and mix to expected values for decimal ranges. */
1615 if ((operand->flags & V850_OPERAND_SIGNED)
1616 && ! warn_signed_overflows)
1617 max = (1 << (operand->bits - 1)) - 1;
1618
1619 if (! (operand->flags & V850_OPERAND_SIGNED)
1620 && ! warn_unsigned_overflows)
1621 min = 0;
1622
1623 if (str)
1624 {
1625 sprintf (buf, "%s: ", str);
1626
1627 sprint_value (buf + strlen (buf), val);
1628 }
1629 else
1630 sprint_value (buf, val);
1631
1632 if (file == (char *) NULL)
1633 as_warn (err, buf, min, max);
1634 else
1635 as_warn_where (file, line, err, buf, min, max);
1636 }
1637 }
1638
1639 insn |= (((long) val & ((1 << operand->bits) - 1)) << operand->shift);
1640 }
1641
1642 return insn;
1643}
1644
1645
1646static char copy_of_instruction[128];
1647
1648void
1649md_assemble (str)
1650 char *str;
1651{
1652 char *s;
1653 char *start_of_operands;
1654 struct v850_opcode *opcode;
1655 struct v850_opcode *next_opcode;
1656 const unsigned char *opindex_ptr;
1657 int next_opindex;
1658 int relaxable = 0;
1659 unsigned long insn;
1660 unsigned long insn_size;
1661 char *f;
1662 int i;
1663 int match;
1664 bfd_boolean extra_data_after_insn = FALSE;
1665 unsigned extra_data_len = 0;
1666 unsigned long extra_data = 0;
1667 char *saved_input_line_pointer;
1668
1669 strncpy (copy_of_instruction, str, sizeof (copy_of_instruction) - 1);
1670
1671 /* Get the opcode. */
1672 for (s = str; *s != '\0' && ! ISSPACE (*s); s++)
1673 continue;
1674
1675 if (*s != '\0')
1676 *s++ = '\0';
1677
1678 /* Find the first opcode with the proper name. */
1679 opcode = (struct v850_opcode *) hash_find (v850_hash, str);
1680 if (opcode == NULL)
1681 {
1682 /* xgettext:c-format */
1683 as_bad (_("Unrecognized opcode: `%s'"), str);
1684 ignore_rest_of_line ();
1685 return;
1686 }
1687
1688 str = s;
1689 while (ISSPACE (*str))
1690 ++str;
1691
1692 start_of_operands = str;
1693
1694 saved_input_line_pointer = input_line_pointer;
1695
1696 for (;;)
1697 {
1698 const char *errmsg = NULL;
1699
1700 match = 0;
1701
1702 if ((opcode->processors & processor_mask) == 0)
1703 {
1704 errmsg = _("Target processor does not support this instruction.");
1705 goto error;
1706 }
1707
1708 relaxable = 0;
1709 fc = 0;
1710 next_opindex = 0;
1711 insn = opcode->opcode;
1712 extra_data_after_insn = FALSE;
1713
1714 input_line_pointer = str = start_of_operands;
1715
1716 for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
1717 {
1718 const struct v850_operand *operand;
1719 char *hold;
1720 expressionS ex;
1721 bfd_reloc_code_real_type reloc;
1722
1723 if (next_opindex == 0)
1724 {
1725 operand = &v850_operands[*opindex_ptr];
1726 }
1727 else
1728 {
1729 operand = &v850_operands[next_opindex];
1730 next_opindex = 0;
1731 }
1732
1733 errmsg = NULL;
1734
1735 while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')
1736 ++str;
1737
1738 if (operand->flags & V850_OPERAND_RELAX)
1739 relaxable = 1;
1740
1741 /* Gather the operand. */
1742 hold = input_line_pointer;
1743 input_line_pointer = str;
1744
1745 /* lo(), hi(), hi0(), etc... */
1746 if ((reloc = v850_reloc_prefix (operand)) != BFD_RELOC_UNUSED)
1747 {
1748 /* This is a fake reloc, used to indicate an error condition. */
1749 if (reloc == BFD_RELOC_64)
1750 {
1751 match = 1;
1752 goto error;
1753 }
1754
1755 expression (&ex);
1756
1757 if (ex.X_op == O_constant)
1758 {
1759 switch (reloc)
1760 {
1761 case BFD_RELOC_V850_ZDA_16_16_OFFSET:
1762 /* To cope with "not1 7, zdaoff(0xfffff006)[r0]"
1763 and the like. */
1764 /* Fall through. */
1765
1766 case BFD_RELOC_LO16:
1767 {
1768 /* Truncate, then sign extend the value. */
1769 ex.X_add_number = SEXT16 (ex.X_add_number);
1770 break;
1771 }
1772
1773 case BFD_RELOC_HI16:
1774 {
1775 /* Truncate, then sign extend the value. */
1776 ex.X_add_number = SEXT16 (ex.X_add_number >> 16);
1777 break;
1778 }
1779
1780 case BFD_RELOC_HI16_S:
1781 {
1782 /* Truncate, then sign extend the value. */
1783 int temp = (ex.X_add_number >> 16) & 0xffff;
1784
1785 temp += (ex.X_add_number >> 15) & 1;
1786
1787 ex.X_add_number = SEXT16 (temp);
1788 break;
1789 }
1790
1791 case BFD_RELOC_32:
1792 if ((operand->flags & V850E_IMMEDIATE32) == 0)
1793 {
1794 errmsg = _("immediate operand is too large");
1795 goto error;
1796 }
1797
1798 extra_data_after_insn = TRUE;
1799 extra_data_len = 4;
1800 extra_data = 0;
1801 break;
1802
1803 default:
1804 fprintf (stderr, "reloc: %d\n", reloc);
1805 as_bad (_("AAARG -> unhandled constant reloc"));
1806 break;
1807 }
1808
1809 if (fc > MAX_INSN_FIXUPS)
1810 as_fatal (_("too many fixups"));
1811
1812 fixups[fc].exp = ex;
1813 fixups[fc].opindex = *opindex_ptr;
1814 fixups[fc].reloc = reloc;
1815 fc++;
1816 }
1817 else
1818 {
1819 if (reloc == BFD_RELOC_32)
1820 {
1821 if ((operand->flags & V850E_IMMEDIATE32) == 0)
1822 {
1823 errmsg = _("immediate operand is too large");
1824 goto error;
1825 }
1826
1827 extra_data_after_insn = TRUE;
1828 extra_data_len = 4;
1829 extra_data = ex.X_add_number;
1830 }
1831
1832 if (fc > MAX_INSN_FIXUPS)
1833 as_fatal (_("too many fixups"));
1834
1835 fixups[fc].exp = ex;
1836 fixups[fc].opindex = *opindex_ptr;
1837 fixups[fc].reloc = reloc;
1838 fc++;
1839 }
1840 }
1841 else
1842 {
1843 errmsg = NULL;
1844
1845 if ((operand->flags & V850_OPERAND_REG) != 0)
1846 {
1847 if (!register_name (&ex))
1848 {
1849 errmsg = _("invalid register name");
1850 }
1851 else if ((operand->flags & V850_NOT_R0)
1852 && ex.X_add_number == 0)
1853 {
1854 errmsg = _("register r0 cannot be used here");
1855
1856 /* Force an error message to be generated by
1857 skipping over any following potential matches
1858 for this opcode. */
1859 opcode += 3;
1860 }
1861 }
1862 else if ((operand->flags & V850_OPERAND_SRG) != 0)
1863 {
1864 if (!system_register_name (&ex, TRUE, FALSE))
1865 {
1866 errmsg = _("invalid system register name");
1867 }
1868 }
1869 else if ((operand->flags & V850_OPERAND_EP) != 0)
1870 {
1871 char *start = input_line_pointer;
1872 char c = get_symbol_end ();
1873
1874 if (strcmp (start, "ep") != 0 && strcmp (start, "r30") != 0)
1875 {
1876 /* Put things back the way we found them. */
1877 *input_line_pointer = c;
1878 input_line_pointer = start;
1879 errmsg = _("expected EP register");
1880 goto error;
1881 }
1882
1883 *input_line_pointer = c;
1884 str = input_line_pointer;
1885 input_line_pointer = hold;
1886
1887 while (*str == ' ' || *str == ','
1888 || *str == '[' || *str == ']')
1889 ++str;
1890 continue;
1891 }
1892 else if ((operand->flags & V850_OPERAND_CC) != 0)
1893 {
1894 if (!cc_name (&ex))
1895 {
1896 errmsg = _("invalid condition code name");
1897 }
1898 }
1899 else if (operand->flags & V850E_PUSH_POP)
1900 {
1901 errmsg = parse_register_list (&insn, operand);
1902
1903 /* The parse_register_list() function has already done
1904 everything, so fake a dummy expression. */
1905 ex.X_op = O_constant;
1906 ex.X_add_number = 0;
1907 }
1908 else if (operand->flags & V850E_IMMEDIATE16)
1909 {
1910 expression (&ex);
1911
1912 if (ex.X_op != O_constant)
1913 errmsg = _("constant expression expected");
1914 else if (ex.X_add_number & 0xffff0000)
1915 {
1916 if (ex.X_add_number & 0xffff)
1917 errmsg = _("constant too big to fit into instruction");
1918 else if ((insn & 0x001fffc0) == 0x00130780)
1919 ex.X_add_number >>= 16;
1920 else
1921 errmsg = _("constant too big to fit into instruction");
1922 }
1923
1924 extra_data_after_insn = TRUE;
1925 extra_data_len = 2;
1926 extra_data = ex.X_add_number;
1927 ex.X_add_number = 0;
1928 }
1929 else if (operand->flags & V850E_IMMEDIATE32)
1930 {
1931 expression (&ex);
1932
1933 if (ex.X_op != O_constant)
1934 errmsg = _("constant expression expected");
1935
1936 extra_data_after_insn = TRUE;
1937 extra_data_len = 4;
1938 extra_data = ex.X_add_number;
1939 ex.X_add_number = 0;
1940 }
1941 else if (register_name (&ex)
1942 && (operand->flags & V850_OPERAND_REG) == 0)
1943 {
1944 char c;
1945 int exists = 0;
1946
1947 /* It is possible that an alias has been defined that
1948 matches a register name. For example the code may
1949 include a ".set ZERO, 0" directive, which matches
1950 the register name "zero". Attempt to reparse the
1951 field as an expression, and only complain if we
1952 cannot generate a constant. */
1953
1954 input_line_pointer = str;
1955
1956 c = get_symbol_end ();
1957
1958 if (symbol_find (str) != NULL)
1959 exists = 1;
1960
1961 *input_line_pointer = c;
1962 input_line_pointer = str;
1963
1964 expression (&ex);
1965
1966 if (ex.X_op != O_constant)
1967 {
1968 /* If this register is actually occuring too early on
1969 the parsing of the instruction, (because another
1970 field is missing) then report this. */
1971 if (opindex_ptr[1] != 0
1972 && (v850_operands[opindex_ptr[1]].flags
1973 & V850_OPERAND_REG))
1974 errmsg = _("syntax error: value is missing before the register name");
1975 else
1976 errmsg = _("syntax error: register not expected");
1977
1978 /* If we created a symbol in the process of this
1979 test then delete it now, so that it will not
1980 be output with the real symbols... */
1981 if (exists == 0
1982 && ex.X_op == O_symbol)
1983 symbol_remove (ex.X_add_symbol,
1984 &symbol_rootP, &symbol_lastP);
1985 }
1986 }
1987 else if (system_register_name (&ex, FALSE, FALSE)
1988 && (operand->flags & V850_OPERAND_SRG) == 0)
1989 {
1990 errmsg = _("syntax error: system register not expected");
1991 }
1992 else if (cc_name (&ex)
1993 && (operand->flags & V850_OPERAND_CC) == 0)
1994 {
1995 errmsg = _("syntax error: condition code not expected");
1996 }
1997 else
1998 {
1999 expression (&ex);
2000 /* Special case:
2001 If we are assembling a MOV instruction and the immediate
2002 value does not fit into the bits available then create a
2003 fake error so that the next MOV instruction will be
2004 selected. This one has a 32 bit immediate field. */
2005
2006 if (((insn & 0x07e0) == 0x0200)
2007 && operand->bits == 5 /* Do not match the CALLT instruction. */
2008 && ex.X_op == O_constant
2009 && (ex.X_add_number < (-(1 << (operand->bits - 1)))
2010 || ex.X_add_number > ((1 << (operand->bits - 1)) - 1)))
2011 errmsg = _("immediate operand is too large");
2012 }
2013
2014 if (errmsg)
2015 goto error;
2016
2017#if 0
2018 fprintf (stderr,
2019 " insn: %x, operand %d, op: %d, add_number: %d\n",
2020 insn, opindex_ptr - opcode->operands,
2021 ex.X_op, ex.X_add_number);
2022#endif
2023
2024 switch (ex.X_op)
2025 {
2026 case O_illegal:
2027 errmsg = _("illegal operand");
2028 goto error;
2029 case O_absent:
2030 errmsg = _("missing operand");
2031 goto error;
2032 case O_register:
2033 if ((operand->flags
2034 & (V850_OPERAND_REG | V850_OPERAND_SRG)) == 0)
2035 {
2036 errmsg = _("invalid operand");
2037 goto error;
2038 }
2039 insn = v850_insert_operand (insn, operand, ex.X_add_number,
2040 (char *) NULL, 0,
2041 copy_of_instruction);
2042 break;
2043
2044 case O_constant:
2045 insn = v850_insert_operand (insn, operand, ex.X_add_number,
2046 (char *) NULL, 0,
2047 copy_of_instruction);
2048 break;
2049
2050 default:
2051 /* We need to generate a fixup for this expression. */
2052 if (fc >= MAX_INSN_FIXUPS)
2053 as_fatal (_("too many fixups"));
2054
2055 fixups[fc].exp = ex;
2056 fixups[fc].opindex = *opindex_ptr;
2057 fixups[fc].reloc = BFD_RELOC_UNUSED;
2058 ++fc;
2059 break;
2060 }
2061 }
2062
2063 str = input_line_pointer;
2064 input_line_pointer = hold;
2065
2066 while (*str == ' ' || *str == ',' || *str == '[' || *str == ']'
2067 || *str == ')')
2068 ++str;
2069 }
2070 match = 1;
2071
2072 error:
2073 if (match == 0)
2074 {
2075 next_opcode = opcode + 1;
2076 if (next_opcode->name != NULL
2077 && strcmp (next_opcode->name, opcode->name) == 0)
2078 {
2079 opcode = next_opcode;
2080
2081 /* Skip versions that are not supported by the target
2082 processor. */
2083 if ((opcode->processors & processor_mask) == 0)
2084 goto error;
2085
2086 continue;
2087 }
2088
2089 as_bad ("%s: %s", copy_of_instruction, errmsg);
2090
2091 if (*input_line_pointer == ']')
2092 ++input_line_pointer;
2093
2094 ignore_rest_of_line ();
2095 input_line_pointer = saved_input_line_pointer;
2096 return;
2097 }
2098 break;
2099 }
2100
2101 while (ISSPACE (*str))
2102 ++str;
2103
2104 if (*str != '\0')
2105 /* xgettext:c-format */
2106 as_bad (_("junk at end of line: `%s'"), str);
2107
2108 input_line_pointer = str;
2109
2110 /* Tie dwarf2 debug info to the address at the start of the insn.
2111 We can't do this after the insn has been output as the current
2112 frag may have been closed off. eg. by frag_var. */
2113 dwarf2_emit_insn (0);
2114
2115 /* Write out the instruction. */
2116
2117 if (relaxable && fc > 0)
2118 {
2119 insn_size = 2;
2120 fc = 0;
2121
2122 if (!strcmp (opcode->name, "br"))
2123 {
2124 f = frag_var (rs_machine_dependent, 4, 2, 2,
2125 fixups[0].exp.X_add_symbol,
2126 fixups[0].exp.X_add_number,
2127 (char *) fixups[0].opindex);
2128 md_number_to_chars (f, insn, insn_size);
2129 md_number_to_chars (f + 2, 0, 2);
2130 }
2131 else
2132 {
2133 f = frag_var (rs_machine_dependent, 6, 4, 0,
2134 fixups[0].exp.X_add_symbol,
2135 fixups[0].exp.X_add_number,
2136 (char *) fixups[0].opindex);
2137 md_number_to_chars (f, insn, insn_size);
2138 md_number_to_chars (f + 2, 0, 4);
2139 }
2140 }
2141 else
2142 {
2143 /* Four byte insns have an opcode with the two high bits on. */
2144 if ((insn & 0x0600) == 0x0600)
2145 insn_size = 4;
2146 else
2147 insn_size = 2;
2148
2149 /* Special case: 32 bit MOV. */
2150 if ((insn & 0xffe0) == 0x0620)
2151 insn_size = 2;
2152
2153 f = frag_more (insn_size);
2154 md_number_to_chars (f, insn, insn_size);
2155
2156 if (extra_data_after_insn)
2157 {
2158 f = frag_more (extra_data_len);
2159 md_number_to_chars (f, extra_data, extra_data_len);
2160
2161 extra_data_after_insn = FALSE;
2162 }
2163 }
2164
2165 /* Create any fixups. At this point we do not use a
2166 bfd_reloc_code_real_type, but instead just use the
2167 BFD_RELOC_UNUSED plus the operand index. This lets us easily
2168 handle fixups for any operand type, although that is admittedly
2169 not a very exciting feature. We pick a BFD reloc type in
2170 md_apply_fix3. */
2171 for (i = 0; i < fc; i++)
2172 {
2173 const struct v850_operand *operand;
2174 bfd_reloc_code_real_type reloc;
2175
2176 operand = &v850_operands[fixups[i].opindex];
2177
2178 reloc = fixups[i].reloc;
2179
2180 if (reloc != BFD_RELOC_UNUSED)
2181 {
2182 reloc_howto_type *reloc_howto =
2183 bfd_reloc_type_lookup (stdoutput, reloc);
2184 int size;
2185 int address;
2186 fixS *fixP;
2187
2188 if (!reloc_howto)
2189 abort ();
2190
2191 size = bfd_get_reloc_size (reloc_howto);
2192
2193 /* XXX This will abort on an R_V850_8 reloc -
2194 is this reloc actually used? */
2195 if (size != 2 && size != 4)
2196 abort ();
2197
2198 address = (f - frag_now->fr_literal) + insn_size - size;
2199
2200 if (reloc == BFD_RELOC_32)
2201 address += 2;
2202
2203 fixP = fix_new_exp (frag_now, address, size,
2204 &fixups[i].exp,
2205 reloc_howto->pc_relative,
2206 reloc);
2207
2208 switch (reloc)
2209 {
2210 case BFD_RELOC_LO16:
2211 case BFD_RELOC_HI16:
2212 case BFD_RELOC_HI16_S:
2213 fixP->fx_no_overflow = 1;
2214 break;
2215 default:
2216 break;
2217 }
2218 }
2219 else
2220 {
2221 fix_new_exp (frag_now,
2222 f - frag_now->fr_literal, 4,
2223 & fixups[i].exp,
2224 1 /* FIXME: V850_OPERAND_RELATIVE ??? */,
2225 (bfd_reloc_code_real_type) (fixups[i].opindex
2226 + (int) BFD_RELOC_UNUSED));
2227 }
2228 }
2229
2230 input_line_pointer = saved_input_line_pointer;
2231}
2232
2233/* If while processing a fixup, a reloc really needs to be created
2234 then it is done here. */
2235
2236arelent *
2237tc_gen_reloc (seg, fixp)
2238 asection *seg ATTRIBUTE_UNUSED;
2239 fixS *fixp;
2240{
2241 arelent *reloc;
2242
2243 reloc = (arelent *) xmalloc (sizeof (arelent));
2244 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2245 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2246 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2247
2248 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
2249 || fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
2250 || fixp->fx_r_type == BFD_RELOC_V850_LONGCALL
2251 || fixp->fx_r_type == BFD_RELOC_V850_LONGJUMP
2252 || fixp->fx_r_type == BFD_RELOC_V850_ALIGN)
2253 reloc->addend = fixp->fx_offset;
2254 else
2255 {
2256 if (fixp->fx_r_type == BFD_RELOC_32
2257 && fixp->fx_pcrel)
2258 fixp->fx_r_type = BFD_RELOC_32_PCREL;
2259
2260 reloc->addend = fixp->fx_addnumber;
2261 }
2262
2263 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2264
2265 if (reloc->howto == (reloc_howto_type *) NULL)
2266 {
2267 as_bad_where (fixp->fx_file, fixp->fx_line,
2268 /* xgettext:c-format */
2269 _("reloc %d not supported by object file format"),
2270 (int) fixp->fx_r_type);
2271
2272 xfree (reloc);
2273
2274 return NULL;
2275 }
2276
2277 return reloc;
2278}
2279
2280void
2281v850_handle_align (frag)
2282 fragS * frag;
2283{
2284 if (v850_relax
2285 && frag->fr_type == rs_align
2286 && frag->fr_address + frag->fr_fix > 0
2287 && frag->fr_offset > 1
2288 && now_seg != bss_section
2289 && now_seg != v850_seg_table[SBSS_SECTION].s
2290 && now_seg != v850_seg_table[TBSS_SECTION].s
2291 && now_seg != v850_seg_table[ZBSS_SECTION].s)
2292 fix_new (frag, frag->fr_fix, 2, & abs_symbol, frag->fr_offset, 0,
2293 BFD_RELOC_V850_ALIGN);
2294}
2295
2296/* Return current size of variable part of frag. */
2297
2298int
2299md_estimate_size_before_relax (fragp, seg)
2300 fragS *fragp;
2301 asection *seg ATTRIBUTE_UNUSED;
2302{
2303 if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
2304 abort ();
2305
2306 return md_relax_table[fragp->fr_subtype].rlx_length;
2307}
2308
2309long
2310v850_pcrel_from_section (fixp, section)
2311 fixS *fixp;
2312 segT section;
2313{
2314 /* If the symbol is undefined, or in a section other than our own,
2315 or it is weak (in which case it may well be in another section,
2316 then let the linker figure it out. */
2317 if (fixp->fx_addsy != (symbolS *) NULL
2318 && (! S_IS_DEFINED (fixp->fx_addsy)
2319 || S_IS_WEAK (fixp->fx_addsy)
2320 || (S_GET_SEGMENT (fixp->fx_addsy) != section)))
2321 return 0;
2322
2323 return fixp->fx_frag->fr_address + fixp->fx_where;
2324}
2325
2326void
2327md_apply_fix3 (fixP, valueP, seg)
2328 fixS *fixP;
2329 valueT *valueP;
2330 segT seg ATTRIBUTE_UNUSED;
2331{
2332 valueT value = * valueP;
2333 char *where;
2334
2335 if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
2336 || fixP->fx_r_type == BFD_RELOC_V850_LONGCALL
2337 || fixP->fx_r_type == BFD_RELOC_V850_LONGJUMP
2338 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2339 {
2340 fixP->fx_done = 0;
2341 return;
2342 }
2343
2344 if (fixP->fx_addsy == (symbolS *) NULL)
2345 fixP->fx_addnumber = value,
2346 fixP->fx_done = 1;
2347
2348 else if (fixP->fx_pcrel)
2349 fixP->fx_addnumber = fixP->fx_offset;
2350
2351 else
2352 {
2353 value = fixP->fx_offset;
2354 if (fixP->fx_subsy != (symbolS *) NULL)
2355 {
2356 if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
2357 value -= S_GET_VALUE (fixP->fx_subsy);
2358 else
2359 {
2360 /* We don't actually support subtracting a symbol. */
2361 as_bad_where (fixP->fx_file, fixP->fx_line,
2362 _("expression too complex"));
2363 }
2364 }
2365 fixP->fx_addnumber = value;
2366 }
2367
2368 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
2369 {
2370 int opindex;
2371 const struct v850_operand *operand;
2372 unsigned long insn;
2373
2374 opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
2375 operand = &v850_operands[opindex];
2376
2377 /* Fetch the instruction, insert the fully resolved operand
2378 value, and stuff the instruction back again.
2379
2380 Note the instruction has been stored in little endian
2381 format! */
2382 where = fixP->fx_frag->fr_literal + fixP->fx_where;
2383
2384 insn = bfd_getl32 ((unsigned char *) where);
2385 insn = v850_insert_operand (insn, operand, (offsetT) value,
2386 fixP->fx_file, fixP->fx_line, NULL);
2387 bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
2388
2389 if (fixP->fx_done)
2390 /* Nothing else to do here. */
2391 return;
2392
2393 /* Determine a BFD reloc value based on the operand information.
2394 We are only prepared to turn a few of the operands into relocs. */
2395
2396 if (operand->bits == 22)
2397 fixP->fx_r_type = BFD_RELOC_V850_22_PCREL;
2398 else if (operand->bits == 9)
2399 fixP->fx_r_type = BFD_RELOC_V850_9_PCREL;
2400 else
2401 {
2402#if 0
2403 fprintf (stderr, "bits: %d, insn: %x\n", operand->bits, insn);
2404#endif
2405
2406 as_bad_where (fixP->fx_file, fixP->fx_line,
2407 _("unresolved expression that must be resolved"));
2408 fixP->fx_done = 1;
2409 return;
2410 }
2411 }
2412 else if (fixP->fx_done)
2413 {
2414 /* We still have to insert the value into memory! */
2415 where = fixP->fx_frag->fr_literal + fixP->fx_where;
2416
2417 if (fixP->fx_size == 1)
2418 *where = value & 0xff;
2419 else if (fixP->fx_size == 2)
2420 bfd_putl16 (value & 0xffff, (unsigned char *) where);
2421 else if (fixP->fx_size == 4)
2422 bfd_putl32 (value, (unsigned char *) where);
2423 }
2424}
2425
2426
2427/* Parse a cons expression. We have to handle hi(), lo(), etc
2428 on the v850. */
2429
2430void
2431parse_cons_expression_v850 (exp)
2432 expressionS *exp;
2433{
2434 /* See if there's a reloc prefix like hi() we have to handle. */
2435 hold_cons_reloc = v850_reloc_prefix (NULL);
2436
2437 /* Do normal expression parsing. */
2438 expression (exp);
2439}
2440
2441/* Create a fixup for a cons expression. If parse_cons_expression_v850
2442 found a reloc prefix, then we use that reloc, else we choose an
2443 appropriate one based on the size of the expression. */
2444
2445void
2446cons_fix_new_v850 (frag, where, size, exp)
2447 fragS *frag;
2448 int where;
2449 int size;
2450 expressionS *exp;
2451{
2452 if (hold_cons_reloc == BFD_RELOC_UNUSED)
2453 {
2454 if (size == 4)
2455 hold_cons_reloc = BFD_RELOC_32;
2456 if (size == 2)
2457 hold_cons_reloc = BFD_RELOC_16;
2458 if (size == 1)
2459 hold_cons_reloc = BFD_RELOC_8;
2460 }
2461
2462 if (exp != NULL)
2463 fix_new_exp (frag, where, size, exp, 0, hold_cons_reloc);
2464 else
2465 fix_new (frag, where, size, NULL, 0, 0, hold_cons_reloc);
2466
2467 hold_cons_reloc = BFD_RELOC_UNUSED;
2468}
2469
2470bfd_boolean
2471v850_fix_adjustable (fixP)
2472 fixS *fixP;
2473{
2474 if (fixP->fx_addsy == NULL)
2475 return 1;
2476
2477 /* Don't adjust function names. */
2478 if (S_IS_FUNCTION (fixP->fx_addsy))
2479 return 0;
2480
2481 /* We need the symbol name for the VTABLE entries. */
2482 if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
2483 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2484 return 0;
2485
2486 return 1;
2487}
2488
2489int
2490v850_force_relocation (fixP)
2491 struct fix *fixP;
2492{
2493 if (fixP->fx_r_type == BFD_RELOC_V850_LONGCALL
2494 || fixP->fx_r_type == BFD_RELOC_V850_LONGJUMP)
2495 return 1;
2496
2497 if (v850_relax
2498 && (fixP->fx_pcrel
2499 || fixP->fx_r_type == BFD_RELOC_V850_ALIGN
2500 || fixP->fx_r_type == BFD_RELOC_V850_22_PCREL
2501 || fixP->fx_r_type == BFD_RELOC_V850_9_PCREL
2502 || fixP->fx_r_type >= BFD_RELOC_UNUSED))
2503 return 1;
2504
2505 return generic_force_reloc (fixP);
2506}
Note: See TracBrowser for help on using the repository browser.