1 /* tc-v850.c -- Assembler code for the NEC V850
2 Copyright (C) 1996-2016 Free Software Foundation, Inc.
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
19 Boston, MA 02110-1301, USA. */
20
21 #include "as.h"
22 #include "safe-ctype.h"
23 #include "subsegs.h"
24 #include "opcode/v850.h"
25 #include "dwarf2dbg.h"
26
27 /* Sign-extend a 16-bit number. */
28 #define SEXT16(x) ((((x) & 0xffff) ^ (~0x7fff)) + 0x8000)
29
30 /* Set to TRUE if we want to be pedantic about signed overflows. */
31 static bfd_boolean warn_signed_overflows = FALSE;
32 static bfd_boolean warn_unsigned_overflows = FALSE;
33
34 /* Non-zero if floating point insns are not being used. */
35 static signed int soft_float = -1;
36
37 /* Indicates the target BFD machine number. */
38 static int machine = -1;
39
40
41 /* Indiciates the target BFD architecture. */
42 enum bfd_architecture v850_target_arch = bfd_arch_v850_rh850;
43 const char * v850_target_format = "elf32-v850-rh850";
44 static flagword v850_e_flags = 0;
45
46 /* Indicates the target processor(s) for the assemble. */
47 static int processor_mask = 0;
48
49 /* Structure to hold information about predefined registers. */
50 struct reg_name
51 {
52 const char *name;
53 int value;
54 unsigned int processors;
55 };
56
57 /* Generic assembler global variables which must be defined by all
58 targets. */
59
60 /* Characters which always start a comment. */
61 const char comment_chars[] = "#";
62
63 /* Characters which start a comment at the beginning of a line. */
64 const char line_comment_chars[] = ";#";
65
66 /* Characters which may be used to separate multiple commands on a
67 single line. */
68 const char line_separator_chars[] = ";";
69
70 /* Characters which are used to indicate an exponent in a floating
71 point number. */
72 const char EXP_CHARS[] = "eE";
73
74 /* Characters which mean that a number is a floating point constant,
75 as in 0d1.0. */
76 const char FLT_CHARS[] = "dD";
77
78 const relax_typeS md_relax_table[] =
79 {
80 /* Conditional branches.(V850/V850E, max 22bit) */
81 #define SUBYPTE_COND_9_22 0
82 {0xfe, -0x100, 2, SUBYPTE_COND_9_22 + 1},
83 {0x1ffffe + 2, -0x200000 + 2, 6, 0},
84 /* Conditional branches.(V850/V850E, max 22bit) */
85 #define SUBYPTE_SA_9_22 2
86 {0xfe, -0x100, 2, SUBYPTE_SA_9_22 + 1},
87 {0x1ffffe + 4, -0x200000 + 4, 8, 0},
88 /* Unconditional branches.(V850/V850E, max 22bit) */
89 #define SUBYPTE_UNCOND_9_22 4
90 {0xfe, -0x100, 2, SUBYPTE_UNCOND_9_22 + 1},
91 {0x1ffffe, -0x200000, 4, 0},
92 /* Conditional branches.(V850E2, max 32bit) */
93 #define SUBYPTE_COND_9_22_32 6
94 {0xfe, -0x100, 2, SUBYPTE_COND_9_22_32 + 1},
95 {0x1fffff + 2, -0x200000 + 2, 6, SUBYPTE_COND_9_22_32 + 2},
96 {0x7ffffffe, -0x80000000, 8, 0},
97 /* Conditional branches.(V850E2, max 32bit) */
98 #define SUBYPTE_SA_9_22_32 9
99 {0xfe, -0x100, 2, SUBYPTE_SA_9_22_32 + 1},
100 {0x1ffffe + 4, -0x200000 + 4, 8, SUBYPTE_SA_9_22_32 + 2},
101 {0x7ffffffe, -0x80000000, 10, 0},
102 /* Unconditional branches.(V850E2, max 32bit) */
103 #define SUBYPTE_UNCOND_9_22_32 12
104 {0xfe, -0x100, 2, SUBYPTE_UNCOND_9_22_32 + 1},
105 {0x1ffffe, -0x200000, 4, SUBYPTE_UNCOND_9_22_32 + 2},
106 {0x7ffffffe, -0x80000000, 6, 0},
107 /* Conditional branches.(V850E2R max 22bit) */
108 #define SUBYPTE_COND_9_17_22 15
109 {0xfe, -0x100, 2, SUBYPTE_COND_9_17_22 + 1},
110 {0xfffe, -0x10000, 4, SUBYPTE_COND_9_17_22 + 2},
111 {0x1ffffe + 2, -0x200000 + 2, 6, 0},
112 /* Conditional branches.(V850E2R max 22bit) */
113 #define SUBYPTE_SA_9_17_22 18
114 {0xfe, -0x100, 2, SUBYPTE_SA_9_17_22 + 1},
115 {0xfffe, -0x10000, 4, SUBYPTE_SA_9_17_22 + 2},
116 {0x1ffffe + 4, -0x200000 + 4, 8, 0},
117 /* Conditional branches.(V850E2R max 32bit) */
118 #define SUBYPTE_COND_9_17_22_32 21
119 {0xfe, -0x100, 2, SUBYPTE_COND_9_17_22_32 + 1},
120 {0xfffe, -0x10000, 4, SUBYPTE_COND_9_17_22_32 + 2},
121 {0x1ffffe + 2, -0x200000 + 2, 6, SUBYPTE_COND_9_17_22_32 + 3},
122 {0x7ffffffe, -0x80000000, 8, 0},
123 /* Conditional branches.(V850E2R max 32bit) */
124 #define SUBYPTE_SA_9_17_22_32 25
125 {0xfe, -0x100, 2, SUBYPTE_SA_9_17_22_32 + 1},
126 {0xfffe, -0x10000, 4, SUBYPTE_SA_9_17_22_32 + 2},
127 {0x1ffffe + 4, -0x200000 + 4, 8, SUBYPTE_SA_9_17_22_32 + 3},
128 {0x7ffffffe, -0x80000000, 10, 0},
129 /* Loop. (V850E2V4_UP, max 22-bit). */
130 #define SUBYPTE_LOOP_16_22 29
131 {0x0, -0x0fffe, 4, SUBYPTE_LOOP_16_22 + 1},
132 {0x1ffffe + 2, -0x200000 + 2, 6, 0},
133 };
134
135 static int v850_relax = 0;
136
137 /* Default branch disp size 22 or 32. */
138 static int default_disp_size = 22;
139
140 /* Default no using bcond17. */
141 static int no_bcond17 = 0;
142
143 /* Default no using ld/st 23bit offset. */
144 static int no_stld23 = 0;
145
146 /* Fixups. */
147 #define MAX_INSN_FIXUPS 5
148
149 struct v850_fixup
150 {
151 expressionS exp;
152 int opindex;
153 bfd_reloc_code_real_type reloc;
154 };
155
156 struct v850_fixup fixups[MAX_INSN_FIXUPS];
157 static int fc;
158
159 struct v850_seg_entry
160 {
161 segT s;
162 const char *name;
163 flagword flags;
164 };
165
166 struct v850_seg_entry v850_seg_table[] =
167 {
168 { NULL, ".sdata",
169 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
170 | SEC_SMALL_DATA },
171 { NULL, ".tdata",
172 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS },
173 { NULL, ".zdata",
174 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS },
175 { NULL, ".sbss",
176 SEC_ALLOC | SEC_SMALL_DATA },
177 { NULL, ".tbss",
178 SEC_ALLOC },
179 { NULL, ".zbss",
180 SEC_ALLOC},
181 { NULL, ".rosdata",
182 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | SEC_DATA
183 | SEC_HAS_CONTENTS | SEC_SMALL_DATA },
184 { NULL, ".rozdata",
185 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | SEC_DATA
186 | SEC_HAS_CONTENTS },
187 { NULL, ".scommon",
188 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
189 | SEC_SMALL_DATA | SEC_IS_COMMON },
190 { NULL, ".tcommon",
191 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
192 | SEC_IS_COMMON },
193 { NULL, ".zcommon",
194 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
195 | SEC_IS_COMMON },
196 { NULL, ".call_table_data",
197 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS },
198 { NULL, ".call_table_text",
199 SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | SEC_CODE
200 | SEC_HAS_CONTENTS},
201 { NULL, ".bss",
202 SEC_ALLOC }
203 };
204
205 #define SDATA_SECTION 0
206 #define TDATA_SECTION 1
207 #define ZDATA_SECTION 2
208 #define SBSS_SECTION 3
209 #define TBSS_SECTION 4
210 #define ZBSS_SECTION 5
211 #define ROSDATA_SECTION 6
212 #define ROZDATA_SECTION 7
213 #define SCOMMON_SECTION 8
214 #define TCOMMON_SECTION 9
215 #define ZCOMMON_SECTION 10
216 #define CALL_TABLE_DATA_SECTION 11
217 #define CALL_TABLE_TEXT_SECTION 12
218 #define BSS_SECTION 13
219
220 static void
do_v850_seg(int i,subsegT sub)221 do_v850_seg (int i, subsegT sub)
222 {
223 struct v850_seg_entry *seg = v850_seg_table + i;
224
225 obj_elf_section_change_hook ();
226
227 if (seg->s != NULL)
228 subseg_set (seg->s, sub);
229 else
230 {
231 seg->s = subseg_new (seg->name, sub);
232 bfd_set_section_flags (stdoutput, seg->s, seg->flags);
233 if ((seg->flags & SEC_LOAD) == 0)
234 seg_info (seg->s)->bss = 1;
235 }
236 }
237
238 static void
v850_seg(int i)239 v850_seg (int i)
240 {
241 subsegT sub = get_absolute_expression ();
242
243 do_v850_seg (i, sub);
244 demand_empty_rest_of_line ();
245 }
246
247 static void
v850_offset(int ignore ATTRIBUTE_UNUSED)248 v850_offset (int ignore ATTRIBUTE_UNUSED)
249 {
250 char *pfrag;
251 int temp = get_absolute_expression ();
252
253 pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, (symbolS *)0,
254 (offsetT) temp, (char *) 0);
255 *pfrag = 0;
256
257 demand_empty_rest_of_line ();
258 }
259
260 /* Copied from obj_elf_common() in gas/config/obj-elf.c. */
261
262 static void
v850_comm(int area)263 v850_comm (int area)
264 {
265 char *name;
266 char c;
267 char *p;
268 int temp;
269 unsigned int size;
270 symbolS *symbolP;
271 int have_align;
272
273 c = get_symbol_name (&name);
274
275 /* Just after name is now '\0'. */
276 p = input_line_pointer;
277 *p = c;
278
279 SKIP_WHITESPACE ();
280
281 if (*input_line_pointer != ',')
282 {
283 as_bad (_("Expected comma after symbol-name"));
284 ignore_rest_of_line ();
285 return;
286 }
287
288 /* Skip ','. */
289 input_line_pointer++;
290
291 if ((temp = get_absolute_expression ()) < 0)
292 {
293 /* xgettext:c-format */
294 as_bad (_(".COMMon length (%d.) < 0! Ignored."), temp);
295 ignore_rest_of_line ();
296 return;
297 }
298
299 size = temp;
300 *p = 0;
301 symbolP = symbol_find_or_make (name);
302 *p = c;
303
304 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
305 {
306 as_bad (_("Ignoring attempt to re-define symbol"));
307 ignore_rest_of_line ();
308 return;
309 }
310
311 if (S_GET_VALUE (symbolP) != 0)
312 {
313 if (S_GET_VALUE (symbolP) != size)
314 /* xgettext:c-format */
315 as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."),
316 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
317 }
318
319 know (symbol_get_frag (symbolP) == &zero_address_frag);
320
321 if (*input_line_pointer != ',')
322 have_align = 0;
323 else
324 {
325 have_align = 1;
326 input_line_pointer++;
327 SKIP_WHITESPACE ();
328 }
329
330 if (! have_align || *input_line_pointer != '"')
331 {
332 if (! have_align)
333 temp = 0;
334 else
335 {
336 temp = get_absolute_expression ();
337
338 if (temp < 0)
339 {
340 temp = 0;
341 as_warn (_("Common alignment negative; 0 assumed"));
342 }
343 }
344
345 if (symbol_get_obj (symbolP)->local)
346 {
347 segT old_sec;
348 int old_subsec;
349 char *pfrag;
350 int align;
351 flagword applicable;
352
353 old_sec = now_seg;
354 old_subsec = now_subseg;
355
356 applicable = bfd_applicable_section_flags (stdoutput);
357
358 applicable &= SEC_ALLOC;
359
360 switch (area)
361 {
362 case SCOMMON_SECTION:
363 do_v850_seg (SBSS_SECTION, 0);
364 break;
365
366 case ZCOMMON_SECTION:
367 do_v850_seg (ZBSS_SECTION, 0);
368 break;
369
370 case TCOMMON_SECTION:
371 do_v850_seg (TBSS_SECTION, 0);
372 break;
373 }
374
375 if (temp)
376 {
377 /* Convert to a power of 2 alignment. */
378 for (align = 0; (temp & 1) == 0; temp >>= 1, ++align)
379 ;
380
381 if (temp != 1)
382 {
383 as_bad (_("Common alignment not a power of 2"));
384 ignore_rest_of_line ();
385 return;
386 }
387 }
388 else
389 align = 0;
390
391 record_alignment (now_seg, align);
392
393 if (align)
394 frag_align (align, 0, 0);
395
396 switch (area)
397 {
398 case SCOMMON_SECTION:
399 if (S_GET_SEGMENT (symbolP) == v850_seg_table[SBSS_SECTION].s)
400 symbol_get_frag (symbolP)->fr_symbol = 0;
401 break;
402
403 case ZCOMMON_SECTION:
404 if (S_GET_SEGMENT (symbolP) == v850_seg_table[ZBSS_SECTION].s)
405 symbol_get_frag (symbolP)->fr_symbol = 0;
406 break;
407
408 case TCOMMON_SECTION:
409 if (S_GET_SEGMENT (symbolP) == v850_seg_table[TBSS_SECTION].s)
410 symbol_get_frag (symbolP)->fr_symbol = 0;
411 break;
412
413 default:
414 abort ();
415 }
416
417 symbol_set_frag (symbolP, frag_now);
418 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
419 (offsetT) size, (char *) 0);
420 *pfrag = 0;
421 S_SET_SIZE (symbolP, size);
422
423 switch (area)
424 {
425 case SCOMMON_SECTION:
426 S_SET_SEGMENT (symbolP, v850_seg_table[SBSS_SECTION].s);
427 break;
428
429 case ZCOMMON_SECTION:
430 S_SET_SEGMENT (symbolP, v850_seg_table[ZBSS_SECTION].s);
431 break;
432
433 case TCOMMON_SECTION:
434 S_SET_SEGMENT (symbolP, v850_seg_table[TBSS_SECTION].s);
435 break;
436
437 default:
438 abort ();
439 }
440
441 S_CLEAR_EXTERNAL (symbolP);
442 obj_elf_section_change_hook ();
443 subseg_set (old_sec, old_subsec);
444 }
445 else
446 {
447 segT old_sec;
448 int old_subsec;
449
450 allocate_common:
451 old_sec = now_seg;
452 old_subsec = now_subseg;
453
454 S_SET_VALUE (symbolP, (valueT) size);
455 S_SET_ALIGN (symbolP, temp);
456 S_SET_EXTERNAL (symbolP);
457
458 switch (area)
459 {
460 case SCOMMON_SECTION:
461 case ZCOMMON_SECTION:
462 case TCOMMON_SECTION:
463 do_v850_seg (area, 0);
464 S_SET_SEGMENT (symbolP, v850_seg_table[area].s);
465 break;
466
467 default:
468 abort ();
469 }
470
471 obj_elf_section_change_hook ();
472 subseg_set (old_sec, old_subsec);
473 }
474 }
475 else
476 {
477 input_line_pointer++;
478
479 /* @@ Some use the dot, some don't. Can we get some consistency?? */
480 if (*input_line_pointer == '.')
481 input_line_pointer++;
482
483 /* @@ Some say data, some say bss. */
484 if (strncmp (input_line_pointer, "bss\"", 4)
485 && strncmp (input_line_pointer, "data\"", 5))
486 {
487 while (*--input_line_pointer != '"')
488 ;
489 input_line_pointer--;
490 goto bad_common_segment;
491 }
492
493 while (*input_line_pointer++ != '"')
494 ;
495
496 goto allocate_common;
497 }
498
499 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
500
501 demand_empty_rest_of_line ();
502 return;
503
504 {
505 bad_common_segment:
506 p = input_line_pointer;
507 while (*p && *p != '\n')
508 p++;
509 c = *p;
510 *p = '\0';
511 as_bad (_("bad .common segment %s"), input_line_pointer + 1);
512 *p = c;
513 input_line_pointer = p;
514 ignore_rest_of_line ();
515 return;
516 }
517 }
518
519 static void
set_machine(int number)520 set_machine (int number)
521 {
522 machine = number;
523 bfd_set_arch_mach (stdoutput, v850_target_arch, machine);
524
525 switch (machine)
526 {
527 case 0: SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850); break;
528 case bfd_mach_v850: SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850); break;
529 case bfd_mach_v850e: SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E); break;
530 case bfd_mach_v850e1: SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E); break;
531 case bfd_mach_v850e2: SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E2); break;
532 case bfd_mach_v850e2v3:SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E2V3); break;
533 case bfd_mach_v850e3v5: SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E3V5); break;
534 }
535 }
536
537 static void
v850_longcode(int type)538 v850_longcode (int type)
539 {
540 expressionS ex;
541
542 if (! v850_relax)
543 {
544 if (type == 1)
545 as_warn (_(".longcall pseudo-op seen when not relaxing"));
546 else
547 as_warn (_(".longjump pseudo-op seen when not relaxing"));
548 }
549
550 expression (&ex);
551
552 if (ex.X_op != O_symbol || ex.X_add_number != 0)
553 {
554 as_bad (_("bad .longcall format"));
555 ignore_rest_of_line ();
556
557 return;
558 }
559
560 if (type == 1)
561 fix_new_exp (frag_now, frag_now_fix (), 4, & ex, 1,
562 BFD_RELOC_V850_LONGCALL);
563 else
564 fix_new_exp (frag_now, frag_now_fix (), 4, & ex, 1,
565 BFD_RELOC_V850_LONGJUMP);
566
567 demand_empty_rest_of_line ();
568 }
569
570 /* The target specific pseudo-ops which we support. */
571 const pseudo_typeS md_pseudo_table[] =
572 {
573 { "sdata", v850_seg, SDATA_SECTION },
574 { "tdata", v850_seg, TDATA_SECTION },
575 { "zdata", v850_seg, ZDATA_SECTION },
576 { "sbss", v850_seg, SBSS_SECTION },
577 { "tbss", v850_seg, TBSS_SECTION },
578 { "zbss", v850_seg, ZBSS_SECTION },
579 { "rosdata", v850_seg, ROSDATA_SECTION },
580 { "rozdata", v850_seg, ROZDATA_SECTION },
581 { "bss", v850_seg, BSS_SECTION },
582 { "offset", v850_offset, 0 },
583 { "word", cons, 4 },
584 { "zcomm", v850_comm, ZCOMMON_SECTION },
585 { "scomm", v850_comm, SCOMMON_SECTION },
586 { "tcomm", v850_comm, TCOMMON_SECTION },
587 { "v850", set_machine, 0 },
588 { "call_table_data", v850_seg, CALL_TABLE_DATA_SECTION },
589 { "call_table_text", v850_seg, CALL_TABLE_TEXT_SECTION },
590 { "v850e", set_machine, bfd_mach_v850e },
591 { "v850e1", set_machine, bfd_mach_v850e1 },
592 { "v850e2", set_machine, bfd_mach_v850e2 },
593 { "v850e2v3", set_machine, bfd_mach_v850e2v3 },
594 { "v850e2v4", set_machine, bfd_mach_v850e3v5 },
595 { "v850e3v5", set_machine, bfd_mach_v850e3v5 },
596 { "longcall", v850_longcode, 1 },
597 { "longjump", v850_longcode, 2 },
598 { NULL, NULL, 0 }
599 };
600
601 /* Opcode hash table. */
602 static struct hash_control *v850_hash;
603
604 /* This table is sorted. Suitable for searching by a binary search. */
605 static const struct reg_name pre_defined_registers[] =
606 {
607 { "ep", 30, PROCESSOR_ALL }, /* ep - element ptr. */
608 { "gp", 4, PROCESSOR_ALL }, /* gp - global ptr. */
609 { "hp", 2, PROCESSOR_ALL }, /* hp - handler stack ptr. */
610 { "lp", 31, PROCESSOR_ALL }, /* lp - link ptr. */
611 { "r0", 0, PROCESSOR_ALL },
612 { "r1", 1, PROCESSOR_ALL },
613 { "r10", 10, PROCESSOR_ALL },
614 { "r11", 11, PROCESSOR_ALL },
615 { "r12", 12, PROCESSOR_ALL },
616 { "r13", 13, PROCESSOR_ALL },
617 { "r14", 14, PROCESSOR_ALL },
618 { "r15", 15, PROCESSOR_ALL },
619 { "r16", 16, PROCESSOR_ALL },
620 { "r17", 17, PROCESSOR_ALL },
621 { "r18", 18, PROCESSOR_ALL },
622 { "r19", 19, PROCESSOR_ALL },
623 { "r2", 2, PROCESSOR_ALL },
624 { "r20", 20, PROCESSOR_ALL },
625 { "r21", 21, PROCESSOR_ALL },
626 { "r22", 22, PROCESSOR_ALL },
627 { "r23", 23, PROCESSOR_ALL },
628 { "r24", 24, PROCESSOR_ALL },
629 { "r25", 25, PROCESSOR_ALL },
630 { "r26", 26, PROCESSOR_ALL },
631 { "r27", 27, PROCESSOR_ALL },
632 { "r28", 28, PROCESSOR_ALL },
633 { "r29", 29, PROCESSOR_ALL },
634 { "r3", 3, PROCESSOR_ALL },
635 { "r30", 30, PROCESSOR_ALL },
636 { "r31", 31, PROCESSOR_ALL },
637 { "r4", 4, PROCESSOR_ALL },
638 { "r5", 5, PROCESSOR_ALL },
639 { "r6", 6, PROCESSOR_ALL },
640 { "r7", 7, PROCESSOR_ALL },
641 { "r8", 8, PROCESSOR_ALL },
642 { "r9", 9, PROCESSOR_ALL },
643 { "sp", 3, PROCESSOR_ALL }, /* sp - stack ptr. */
644 { "tp", 5, PROCESSOR_ALL }, /* tp - text ptr. */
645 { "zero", 0, PROCESSOR_ALL },
646 };
647
648 #define REG_NAME_CNT \
649 (sizeof (pre_defined_registers) / sizeof (struct reg_name))
650
651 static const struct reg_name system_registers[] =
652 {
653 { "asid", 23, PROCESSOR_NOT_V850 },
654 { "bpam", 25, PROCESSOR_NOT_V850 },
655 { "bpav", 24, PROCESSOR_NOT_V850 },
656 { "bpc", 22, PROCESSOR_NOT_V850 },
657 { "bpdm", 27, PROCESSOR_NOT_V850 },
658 { "bpdv", 26, PROCESSOR_NOT_V850 },
659 { "bsel", 31, PROCESSOR_V850E2_UP },
660 { "cfg", 7, PROCESSOR_V850E2V3_UP },
661 { "ctbp", 20, PROCESSOR_NOT_V850 },
662 { "ctpc", 16, PROCESSOR_NOT_V850 },
663 { "ctpsw", 17, PROCESSOR_NOT_V850 },
664 { "dbic", 15, PROCESSOR_V850E2_UP },
665 { "dbpc", 18, PROCESSOR_NOT_V850 },
666 { "dbpsw", 19, PROCESSOR_NOT_V850 },
667 { "dbwr", 30, PROCESSOR_V850E2_UP },
668 { "dir", 21, PROCESSOR_NOT_V850 },
669 { "dpa0l", 16, PROCESSOR_V850E2V3_UP },
670 { "dpa0u", 17, PROCESSOR_V850E2V3_UP },
671 { "dpa1l", 18, PROCESSOR_V850E2V3_UP },
672 { "dpa1u", 19, PROCESSOR_V850E2V3_UP },
673 { "dpa2l", 20, PROCESSOR_V850E2V3_UP },
674 { "dpa2u", 21, PROCESSOR_V850E2V3_UP },
675 { "dpa3l", 22, PROCESSOR_V850E2V3_UP },
676 { "dpa3u", 23, PROCESSOR_V850E2V3_UP },
677 { "dpa4l", 24, PROCESSOR_V850E2V3_UP },
678 { "dpa4u", 25, PROCESSOR_V850E2V3_UP },
679 { "dpa5l", 26, PROCESSOR_V850E2V3_UP },
680 { "dpa5u", 27, PROCESSOR_V850E2V3_UP },
681 { "ecr", 4, PROCESSOR_ALL },
682 { "eh_base", 3, PROCESSOR_V850E2V3_UP },
683 { "eh_cfg", 1, PROCESSOR_V850E2V3_UP },
684 { "eh_reset", 2, PROCESSOR_V850E2V3_UP },
685 { "eiic", 13, PROCESSOR_V850E2_UP },
686 { "eipc", 0, PROCESSOR_ALL },
687 { "eipsw", 1, PROCESSOR_ALL },
688 { "eiwr", 28, PROCESSOR_V850E2_UP },
689 { "feic", 14, PROCESSOR_V850E2_UP },
690 { "fepc", 2, PROCESSOR_ALL },
691 { "fepsw", 3, PROCESSOR_ALL },
692 { "fewr", 29, PROCESSOR_V850E2_UP },
693 { "fpcc", 9, PROCESSOR_V850E2V3_UP },
694 { "fpcfg", 10, PROCESSOR_V850E2V3_UP },
695 { "fpec", 11, PROCESSOR_V850E2V3_UP },
696 { "fpepc", 7, PROCESSOR_V850E2V3_UP },
697 { "fpspc", 27, PROCESSOR_V850E2V3_UP },
698 { "fpsr", 6, PROCESSOR_V850E2V3_UP },
699 { "fpst", 8, PROCESSOR_V850E2V3_UP },
700 { "ipa0l", 6, PROCESSOR_V850E2V3_UP },
701 { "ipa0u", 7, PROCESSOR_V850E2V3_UP },
702 { "ipa1l", 8, PROCESSOR_V850E2V3_UP },
703 { "ipa1u", 9, PROCESSOR_V850E2V3_UP },
704 { "ipa2l", 10, PROCESSOR_V850E2V3_UP },
705 { "ipa2u", 11, PROCESSOR_V850E2V3_UP },
706 { "ipa3l", 12, PROCESSOR_V850E2V3_UP },
707 { "ipa3u", 13, PROCESSOR_V850E2V3_UP },
708 { "ipa4l", 14, PROCESSOR_V850E2V3_UP },
709 { "ipa4u", 15, PROCESSOR_V850E2V3_UP },
710 { "mca", 24, PROCESSOR_V850E2V3_UP },
711 { "mcc", 26, PROCESSOR_V850E2V3_UP },
712 { "mcr", 27, PROCESSOR_V850E2V3_UP },
713 { "mcs", 25, PROCESSOR_V850E2V3_UP },
714 { "mpc", 1, PROCESSOR_V850E2V3_UP },
715 { "mpm", 0, PROCESSOR_V850E2V3_UP },
716 { "mpu10_dpa0l", 16, PROCESSOR_V850E2V3_UP },
717 { "mpu10_dpa0u", 17, PROCESSOR_V850E2V3_UP },
718 { "mpu10_dpa1l", 18, PROCESSOR_V850E2V3_UP },
719 { "mpu10_dpa1u", 19, PROCESSOR_V850E2V3_UP },
720 { "mpu10_dpa2l", 20, PROCESSOR_V850E2V3_UP },
721 { "mpu10_dpa2u", 21, PROCESSOR_V850E2V3_UP },
722 { "mpu10_dpa3l", 22, PROCESSOR_V850E2V3_UP },
723 { "mpu10_dpa3u", 23, PROCESSOR_V850E2V3_UP },
724 { "mpu10_dpa4l", 24, PROCESSOR_V850E2V3_UP },
725 { "mpu10_dpa4u", 25, PROCESSOR_V850E2V3_UP },
726 { "mpu10_dpa5l", 26, PROCESSOR_V850E2V3_UP },
727 { "mpu10_dpa5u", 27, PROCESSOR_V850E2V3_UP },
728 { "mpu10_ipa0l", 6, PROCESSOR_V850E2V3_UP },
729 { "mpu10_ipa0u", 7, PROCESSOR_V850E2V3_UP },
730 { "mpu10_ipa1l", 8, PROCESSOR_V850E2V3_UP },
731 { "mpu10_ipa1u", 9, PROCESSOR_V850E2V3_UP },
732 { "mpu10_ipa2l", 10, PROCESSOR_V850E2V3_UP },
733 { "mpu10_ipa2u", 11, PROCESSOR_V850E2V3_UP },
734 { "mpu10_ipa3l", 12, PROCESSOR_V850E2V3_UP },
735 { "mpu10_ipa3u", 13, PROCESSOR_V850E2V3_UP },
736 { "mpu10_ipa4l", 14, PROCESSOR_V850E2V3_UP },
737 { "mpu10_ipa4u", 15, PROCESSOR_V850E2V3_UP },
738 { "mpu10_mpc", 1, PROCESSOR_V850E2V3_UP },
739 { "mpu10_mpm", 0, PROCESSOR_V850E2V3_UP },
740 { "mpu10_tid", 2, PROCESSOR_V850E2V3_UP },
741 { "mpu10_vmadr", 5, PROCESSOR_V850E2V3_UP },
742 { "mpu10_vmecr", 3, PROCESSOR_V850E2V3_UP },
743 { "mpu10_vmtid", 4, PROCESSOR_V850E2V3_UP },
744 { "pid", 6, PROCESSOR_V850E2V3_UP },
745 { "pmcr0", 4, PROCESSOR_V850E2V3_UP },
746 { "pmis2", 14, PROCESSOR_V850E2V3_UP },
747 { "psw", 5, PROCESSOR_ALL },
748 { "scbp", 12, PROCESSOR_V850E2V3_UP },
749 { "sccfg", 11, PROCESSOR_V850E2V3_UP },
750 { "sr0", 0, PROCESSOR_ALL },
751 { "sr1", 1, PROCESSOR_ALL },
752 { "sr10", 10, PROCESSOR_ALL },
753 { "sr11", 11, PROCESSOR_ALL },
754 { "sr12", 12, PROCESSOR_ALL },
755 { "sr13", 13, PROCESSOR_ALL },
756 { "sr14", 14, PROCESSOR_ALL },
757 { "sr15", 15, PROCESSOR_ALL },
758 { "sr16", 16, PROCESSOR_ALL },
759 { "sr17", 17, PROCESSOR_ALL },
760 { "sr18", 18, PROCESSOR_ALL },
761 { "sr19", 19, PROCESSOR_ALL },
762 { "sr2", 2, PROCESSOR_ALL },
763 { "sr20", 20, PROCESSOR_ALL },
764 { "sr21", 21, PROCESSOR_ALL },
765 { "sr22", 22, PROCESSOR_ALL },
766 { "sr23", 23, PROCESSOR_ALL },
767 { "sr24", 24, PROCESSOR_ALL },
768 { "sr25", 25, PROCESSOR_ALL },
769 { "sr26", 26, PROCESSOR_ALL },
770 { "sr27", 27, PROCESSOR_ALL },
771 { "sr28", 28, PROCESSOR_ALL },
772 { "sr29", 29, PROCESSOR_ALL },
773 { "sr3", 3, PROCESSOR_ALL },
774 { "sr30", 30, PROCESSOR_ALL },
775 { "sr31", 31, PROCESSOR_ALL },
776 { "sr4", 4, PROCESSOR_ALL },
777 { "sr5", 5, PROCESSOR_ALL },
778 { "sr6", 6, PROCESSOR_ALL },
779 { "sr7", 7, PROCESSOR_ALL },
780 { "sr8", 8, PROCESSOR_ALL },
781 { "sr9", 9, PROCESSOR_ALL },
782 { "sw_base", 3, PROCESSOR_V850E2V3_UP },
783 { "sw_cfg", 1, PROCESSOR_V850E2V3_UP },
784 { "sw_ctl", 0, PROCESSOR_V850E2V3_UP },
785 { "tid", 2, PROCESSOR_V850E2V3_UP },
786 { "vmadr", 6, PROCESSOR_V850E2V3_UP },
787 { "vmecr", 4, PROCESSOR_V850E2V3_UP },
788 { "vmtid", 5, PROCESSOR_V850E2V3_UP },
789 { "vsadr", 2, PROCESSOR_V850E2V3_UP },
790 { "vsecr", 0, PROCESSOR_V850E2V3_UP },
791 { "vstid", 1, PROCESSOR_V850E2V3_UP },
792 };
793
794 #define SYSREG_NAME_CNT \
795 (sizeof (system_registers) / sizeof (struct reg_name))
796
797
798 static const struct reg_name cc_names[] =
799 {
800 { "c", 0x1, PROCESSOR_ALL },
801 { "e", 0x2, PROCESSOR_ALL },
802 { "ge", 0xe, PROCESSOR_ALL },
803 { "gt", 0xf, PROCESSOR_ALL },
804 { "h", 0xb, PROCESSOR_ALL },
805 { "l", 0x1, PROCESSOR_ALL },
806 { "le", 0x7, PROCESSOR_ALL },
807 { "lt", 0x6, PROCESSOR_ALL },
808 { "n", 0x4, PROCESSOR_ALL },
809 { "nc", 0x9, PROCESSOR_ALL },
810 { "ne", 0xa, PROCESSOR_ALL },
811 { "nh", 0x3, PROCESSOR_ALL },
812 { "nl", 0x9, PROCESSOR_ALL },
813 { "ns", 0xc, PROCESSOR_ALL },
814 { "nv", 0x8, PROCESSOR_ALL },
815 { "nz", 0xa, PROCESSOR_ALL },
816 { "p", 0xc, PROCESSOR_ALL },
817 { "s", 0x4, PROCESSOR_ALL },
818 #define COND_SA_NUM 0xd
819 { "sa", COND_SA_NUM, PROCESSOR_ALL },
820 { "t", 0x5, PROCESSOR_ALL },
821 { "v", 0x0, PROCESSOR_ALL },
822 { "z", 0x2, PROCESSOR_ALL },
823 };
824
825 #define CC_NAME_CNT \
826 (sizeof (cc_names) / sizeof (struct reg_name))
827
828 static const struct reg_name float_cc_names[] =
829 {
830 { "eq", 0x2, PROCESSOR_V850E2V3_UP }, /* true. */
831 { "f", 0x0, PROCESSOR_V850E2V3_UP }, /* true. */
832 { "ge", 0xd, PROCESSOR_V850E2V3_UP }, /* false. */
833 { "gl", 0xb, PROCESSOR_V850E2V3_UP }, /* false. */
834 { "gle", 0x9, PROCESSOR_V850E2V3_UP }, /* false. */
835 { "gt", 0xf, PROCESSOR_V850E2V3_UP }, /* false. */
836 { "le", 0xe, PROCESSOR_V850E2V3_UP }, /* true. */
837 { "lt", 0xc, PROCESSOR_V850E2V3_UP }, /* true. */
838 { "neq", 0x2, PROCESSOR_V850E2V3_UP }, /* false. */
839 { "nge", 0xd, PROCESSOR_V850E2V3_UP }, /* true. */
840 { "ngl", 0xb, PROCESSOR_V850E2V3_UP }, /* true. */
841 { "ngle",0x9, PROCESSOR_V850E2V3_UP }, /* true. */
842 { "ngt", 0xf, PROCESSOR_V850E2V3_UP }, /* true. */
843 { "nle", 0xe, PROCESSOR_V850E2V3_UP }, /* false. */
844 { "nlt", 0xc, PROCESSOR_V850E2V3_UP }, /* false. */
845 { "oge", 0x5, PROCESSOR_V850E2V3_UP }, /* false. */
846 { "ogl", 0x3, PROCESSOR_V850E2V3_UP }, /* false. */
847 { "ogt", 0x7, PROCESSOR_V850E2V3_UP }, /* false. */
848 { "ole", 0x6, PROCESSOR_V850E2V3_UP }, /* true. */
849 { "olt", 0x4, PROCESSOR_V850E2V3_UP }, /* true. */
850 { "or", 0x1, PROCESSOR_V850E2V3_UP }, /* false. */
851 { "seq", 0xa, PROCESSOR_V850E2V3_UP }, /* true. */
852 { "sf", 0x8, PROCESSOR_V850E2V3_UP }, /* true. */
853 { "sne", 0xa, PROCESSOR_V850E2V3_UP }, /* false. */
854 { "st", 0x8, PROCESSOR_V850E2V3_UP }, /* false. */
855 { "t", 0x0, PROCESSOR_V850E2V3_UP }, /* false. */
856 { "ueq", 0x3, PROCESSOR_V850E2V3_UP }, /* true. */
857 { "uge", 0x4, PROCESSOR_V850E2V3_UP }, /* false. */
858 { "ugt", 0x6, PROCESSOR_V850E2V3_UP }, /* false. */
859 { "ule", 0x7, PROCESSOR_V850E2V3_UP }, /* true. */
860 { "ult", 0x5, PROCESSOR_V850E2V3_UP }, /* true. */
861 { "un", 0x1, PROCESSOR_V850E2V3_UP }, /* true. */
862 };
863
864 #define FLOAT_CC_NAME_CNT \
865 (sizeof (float_cc_names) / sizeof (struct reg_name))
866
867
868 static const struct reg_name cacheop_names[] =
869 {
870 { "cfald", 0x44, PROCESSOR_V850E3V5_UP },
871 { "cfali", 0x40, PROCESSOR_V850E3V5_UP },
872 { "chbid", 0x04, PROCESSOR_V850E3V5_UP },
873 { "chbii", 0x00, PROCESSOR_V850E3V5_UP },
874 { "chbiwbd", 0x06, PROCESSOR_V850E3V5_UP },
875 { "chbwbd", 0x07, PROCESSOR_V850E3V5_UP },
876 { "cibid", 0x24, PROCESSOR_V850E3V5_UP },
877 { "cibii", 0x20, PROCESSOR_V850E3V5_UP },
878 { "cibiwbd", 0x26, PROCESSOR_V850E3V5_UP },
879 { "cibwbd", 0x27, PROCESSOR_V850E3V5_UP },
880 { "cildd", 0x65, PROCESSOR_V850E3V5_UP },
881 { "cildi", 0x61, PROCESSOR_V850E3V5_UP },
882 { "cistd", 0x64, PROCESSOR_V850E3V5_UP },
883 { "cisti", 0x60, PROCESSOR_V850E3V5_UP },
884 };
885
886 #define CACHEOP_NAME_CNT \
887 (sizeof (cacheop_names) / sizeof (struct reg_name))
888
889 static const struct reg_name prefop_names[] =
890 {
891 { "prefd", 0x04, PROCESSOR_V850E3V5_UP },
892 { "prefi", 0x00, PROCESSOR_V850E3V5_UP },
893 };
894
895 #define PREFOP_NAME_CNT \
896 (sizeof (prefop_names) / sizeof (struct reg_name))
897
898 static const struct reg_name vector_registers[] =
899 {
900 { "vr0", 0, PROCESSOR_V850E3V5_UP },
901 { "vr1", 1, PROCESSOR_V850E3V5_UP },
902 { "vr10", 10, PROCESSOR_V850E3V5_UP },
903 { "vr11", 11, PROCESSOR_V850E3V5_UP },
904 { "vr12", 12, PROCESSOR_V850E3V5_UP },
905 { "vr13", 13, PROCESSOR_V850E3V5_UP },
906 { "vr14", 14, PROCESSOR_V850E3V5_UP },
907 { "vr15", 15, PROCESSOR_V850E3V5_UP },
908 { "vr16", 16, PROCESSOR_V850E3V5_UP },
909 { "vr17", 17, PROCESSOR_V850E3V5_UP },
910 { "vr18", 18, PROCESSOR_V850E3V5_UP },
911 { "vr19", 19, PROCESSOR_V850E3V5_UP },
912 { "vr2", 2, PROCESSOR_V850E3V5_UP },
913 { "vr20", 20, PROCESSOR_V850E3V5_UP },
914 { "vr21", 21, PROCESSOR_V850E3V5_UP },
915 { "vr22", 22, PROCESSOR_V850E3V5_UP },
916 { "vr23", 23, PROCESSOR_V850E3V5_UP },
917 { "vr24", 24, PROCESSOR_V850E3V5_UP },
918 { "vr25", 25, PROCESSOR_V850E3V5_UP },
919 { "vr26", 26, PROCESSOR_V850E3V5_UP },
920 { "vr27", 27, PROCESSOR_V850E3V5_UP },
921 { "vr28", 28, PROCESSOR_V850E3V5_UP },
922 { "vr29", 29, PROCESSOR_V850E3V5_UP },
923 { "vr3", 3, PROCESSOR_V850E3V5_UP },
924 { "vr30", 30, PROCESSOR_V850E3V5_UP },
925 { "vr31", 31, PROCESSOR_V850E3V5_UP },
926 { "vr4", 4, PROCESSOR_V850E3V5_UP },
927 { "vr5", 5, PROCESSOR_V850E3V5_UP },
928 { "vr6", 6, PROCESSOR_V850E3V5_UP },
929 { "vr7", 7, PROCESSOR_V850E3V5_UP },
930 { "vr8", 8, PROCESSOR_V850E3V5_UP },
931 { "vr9", 9, PROCESSOR_V850E3V5_UP },
932 };
933
934 #define VREG_NAME_CNT \
935 (sizeof (vector_registers) / sizeof (struct reg_name))
936
937 /* Do a binary search of the given register table to see if NAME is a
938 valid regiter name. Return the register number from the array on
939 success, or -1 on failure. */
940
941 static int
reg_name_search(const struct reg_name * regs,int regcount,const char * name,bfd_boolean accept_numbers)942 reg_name_search (const struct reg_name *regs,
943 int regcount,
944 const char *name,
945 bfd_boolean accept_numbers)
946 {
947 int middle, low, high;
948 int cmp;
949 symbolS *symbolP;
950
951 /* If the register name is a symbol, then evaluate it. */
952 if ((symbolP = symbol_find (name)) != NULL)
953 {
954 /* If the symbol is an alias for another name then use that.
955 If the symbol is an alias for a number, then return the number. */
956 if (symbol_equated_p (symbolP))
957 name
958 = S_GET_NAME (symbol_get_value_expression (symbolP)->X_add_symbol);
959 else if (accept_numbers)
960 {
961 int reg = S_GET_VALUE (symbolP);
962 return reg;
963 }
964
965 /* Otherwise drop through and try parsing name normally. */
966 }
967
968 low = 0;
969 high = regcount - 1;
970
971 do
972 {
973 middle = (low + high) / 2;
974 cmp = strcasecmp (name, regs[middle].name);
975 if (cmp < 0)
976 high = middle - 1;
977 else if (cmp > 0)
978 low = middle + 1;
979 else
980 return ((regs[middle].processors & processor_mask)
981 ? regs[middle].value
982 : -1);
983 }
984 while (low <= high);
985 return -1;
986 }
987
988 /* Summary of register_name().
989
990 in: Input_line_pointer points to 1st char of operand.
991
992 out: An expressionS.
993 The operand may have been a register: in this case, X_op == O_register,
994 X_add_number is set to the register number, and truth is returned.
995 Input_line_pointer->(next non-blank) char after operand, or is in
996 its original state. */
997
998 static bfd_boolean
register_name(expressionS * expressionP)999 register_name (expressionS *expressionP)
1000 {
1001 int reg_number;
1002 char *name;
1003 char *start;
1004 char c;
1005
1006 /* Find the spelling of the operand. */
1007 start = input_line_pointer;
1008 c = get_symbol_name (&name);
1009
1010 reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT,
1011 name, FALSE);
1012
1013 /* Put back the delimiting char. */
1014 (void) restore_line_pointer (c);
1015
1016 expressionP->X_add_symbol = NULL;
1017 expressionP->X_op_symbol = NULL;
1018
1019 /* Look to see if it's in the register table. */
1020 if (reg_number >= 0)
1021 {
1022 expressionP->X_op = O_register;
1023 expressionP->X_add_number = reg_number;
1024
1025 return TRUE;
1026 }
1027
1028 /* Reset the line as if we had not done anything. */
1029 input_line_pointer = start;
1030
1031 expressionP->X_op = O_illegal;
1032
1033 return FALSE;
1034 }
1035
1036 /* Summary of system_register_name().
1037
1038 in: INPUT_LINE_POINTER points to 1st char of operand.
1039 EXPRESSIONP points to an expression structure to be filled in.
1040 ACCEPT_NUMBERS is true iff numerical register names may be used.
1041
1042 out: An expressionS structure in expressionP.
1043 The operand may have been a register: in this case, X_op == O_register,
1044 X_add_number is set to the register number, and truth is returned.
1045 Input_line_pointer->(next non-blank) char after operand, or is in
1046 its original state. */
1047
1048 static bfd_boolean
system_register_name(expressionS * expressionP,bfd_boolean accept_numbers)1049 system_register_name (expressionS *expressionP,
1050 bfd_boolean accept_numbers)
1051 {
1052 int reg_number;
1053 char *name;
1054 char *start;
1055 char c;
1056
1057 /* Find the spelling of the operand. */
1058 start = input_line_pointer;
1059 c = get_symbol_name (&name);
1060 reg_number = reg_name_search (system_registers, SYSREG_NAME_CNT, name,
1061 accept_numbers);
1062
1063 /* Put back the delimiting char. */
1064 (void) restore_line_pointer (c);
1065
1066 if (reg_number < 0
1067 && accept_numbers)
1068 {
1069 /* Reset input_line pointer. */
1070 input_line_pointer = start;
1071
1072 if (ISDIGIT (*input_line_pointer))
1073 {
1074 reg_number = strtol (input_line_pointer, &input_line_pointer, 0);
1075 }
1076 }
1077
1078 expressionP->X_add_symbol = NULL;
1079 expressionP->X_op_symbol = NULL;
1080
1081 /* Look to see if it's in the register table. */
1082 if (reg_number >= 0)
1083 {
1084 expressionP->X_op = O_register;
1085 expressionP->X_add_number = reg_number;
1086
1087 return TRUE;
1088 }
1089
1090 /* Reset the line as if we had not done anything. */
1091 input_line_pointer = start;
1092
1093 expressionP->X_op = O_illegal;
1094
1095 return FALSE;
1096 }
1097
1098 /* Summary of cc_name().
1099
1100 in: INPUT_LINE_POINTER points to 1st char of operand.
1101
1102 out: An expressionS.
1103 The operand may have been a register: in this case, X_op == O_register,
1104 X_add_number is set to the register number, and truth is returned.
1105 Input_line_pointer->(next non-blank) char after operand, or is in
1106 its original state. */
1107
1108 static bfd_boolean
cc_name(expressionS * expressionP,bfd_boolean accept_numbers)1109 cc_name (expressionS *expressionP,
1110 bfd_boolean accept_numbers)
1111 {
1112 int reg_number;
1113 char *name;
1114 char *start;
1115 char c;
1116
1117 /* Find the spelling of the operand. */
1118 start = input_line_pointer;
1119 c = get_symbol_name (&name);
1120 reg_number = reg_name_search (cc_names, CC_NAME_CNT, name, accept_numbers);
1121
1122 /* Put back the delimiting char. */
1123 (void) restore_line_pointer (c);
1124
1125 if (reg_number < 0
1126 && accept_numbers)
1127 {
1128 /* Reset input_line pointer. */
1129 input_line_pointer = start;
1130
1131 if (ISDIGIT (*input_line_pointer))
1132 {
1133 reg_number = strtol (input_line_pointer, &input_line_pointer, 0);
1134 }
1135 }
1136
1137 expressionP->X_add_symbol = NULL;
1138 expressionP->X_op_symbol = NULL;
1139
1140 /* Look to see if it's in the register table. */
1141 if (reg_number >= 0)
1142 {
1143 expressionP->X_op = O_constant;
1144 expressionP->X_add_number = reg_number;
1145
1146 return TRUE;
1147 }
1148
1149 /* Reset the line as if we had not done anything. */
1150 input_line_pointer = start;
1151
1152 expressionP->X_op = O_illegal;
1153 expressionP->X_add_number = 0;
1154
1155 return FALSE;
1156 }
1157
1158 static bfd_boolean
float_cc_name(expressionS * expressionP,bfd_boolean accept_numbers)1159 float_cc_name (expressionS *expressionP,
1160 bfd_boolean accept_numbers)
1161 {
1162 int reg_number;
1163 char *name;
1164 char *start;
1165 char c;
1166
1167 /* Find the spelling of the operand. */
1168 start = input_line_pointer;
1169 c = get_symbol_name (&name);
1170 reg_number = reg_name_search (float_cc_names, FLOAT_CC_NAME_CNT, name, accept_numbers);
1171
1172 /* Put back the delimiting char. */
1173 (void) restore_line_pointer (c);
1174
1175 if (reg_number < 0
1176 && accept_numbers)
1177 {
1178 /* Reset input_line pointer. */
1179 input_line_pointer = start;
1180
1181 if (ISDIGIT (*input_line_pointer))
1182 {
1183 reg_number = strtol (input_line_pointer, &input_line_pointer, 0);
1184 }
1185 }
1186
1187 expressionP->X_add_symbol = NULL;
1188 expressionP->X_op_symbol = NULL;
1189
1190 /* Look to see if it's in the register table. */
1191 if (reg_number >= 0)
1192 {
1193 expressionP->X_op = O_constant;
1194 expressionP->X_add_number = reg_number;
1195
1196 return TRUE;
1197 }
1198
1199 /* Reset the line as if we had not done anything. */
1200 input_line_pointer = start;
1201
1202 expressionP->X_op = O_illegal;
1203 expressionP->X_add_number = 0;
1204
1205 return FALSE;
1206 }
1207
1208 static bfd_boolean
cacheop_name(expressionS * expressionP,bfd_boolean accept_numbers)1209 cacheop_name (expressionS * expressionP,
1210 bfd_boolean accept_numbers)
1211 {
1212 int reg_number;
1213 char *name;
1214 char *start;
1215 char c;
1216
1217 /* Find the spelling of the operand. */
1218 start = input_line_pointer;
1219 c = get_symbol_name (&name);
1220 reg_number = reg_name_search (cacheop_names, CACHEOP_NAME_CNT, name, accept_numbers);
1221
1222 /* Put back the delimiting char. */
1223 (void) restore_line_pointer (c);
1224
1225 if (reg_number < 0
1226 && accept_numbers)
1227 {
1228 /* Reset input_line pointer. */
1229 input_line_pointer = start;
1230
1231 if (ISDIGIT (*input_line_pointer))
1232 reg_number = strtol (input_line_pointer, &input_line_pointer, 0);
1233 }
1234
1235 expressionP->X_add_symbol = NULL;
1236 expressionP->X_op_symbol = NULL;
1237
1238 /* Look to see if it's in the register table. */
1239 if (reg_number >= 0)
1240 {
1241 expressionP->X_op = O_constant;
1242 expressionP->X_add_number = reg_number;
1243
1244 return TRUE;
1245 }
1246
1247 /* Reset the line as if we had not done anything. */
1248 input_line_pointer = start;
1249
1250 expressionP->X_op = O_illegal;
1251 expressionP->X_add_number = 0;
1252
1253 return FALSE;
1254 }
1255
1256 static bfd_boolean
prefop_name(expressionS * expressionP,bfd_boolean accept_numbers)1257 prefop_name (expressionS * expressionP,
1258 bfd_boolean accept_numbers)
1259 {
1260 int reg_number;
1261 char *name;
1262 char *start;
1263 char c;
1264
1265 /* Find the spelling of the operand. */
1266 start = input_line_pointer;
1267 c = get_symbol_name (&name);
1268 reg_number = reg_name_search (prefop_names, PREFOP_NAME_CNT, name, accept_numbers);
1269
1270 /* Put back the delimiting char. */
1271 (void) restore_line_pointer (c);
1272
1273 if (reg_number < 0
1274 && accept_numbers)
1275 {
1276 /* Reset input_line pointer. */
1277 input_line_pointer = start;
1278
1279 if (ISDIGIT (*input_line_pointer))
1280 reg_number = strtol (input_line_pointer, &input_line_pointer, 0);
1281 }
1282
1283 expressionP->X_add_symbol = NULL;
1284 expressionP->X_op_symbol = NULL;
1285
1286 /* Look to see if it's in the register table. */
1287 if (reg_number >= 0)
1288 {
1289 expressionP->X_op = O_constant;
1290 expressionP->X_add_number = reg_number;
1291
1292 return TRUE;
1293 }
1294
1295 /* Reset the line as if we had not done anything. */
1296 input_line_pointer = start;
1297
1298 expressionP->X_op = O_illegal;
1299 expressionP->X_add_number = 0;
1300
1301 return FALSE;
1302 }
1303
1304 static bfd_boolean
vector_register_name(expressionS * expressionP)1305 vector_register_name (expressionS *expressionP)
1306 {
1307 int reg_number;
1308 char *name;
1309 char *start;
1310 char c;
1311
1312 /* Find the spelling of the operand. */
1313 start = input_line_pointer;
1314 c = get_symbol_name (&name);
1315
1316 reg_number = reg_name_search (vector_registers, VREG_NAME_CNT,
1317 name, FALSE);
1318
1319 /* Put back the delimiting char. */
1320 (void) restore_line_pointer (c);
1321
1322 expressionP->X_add_symbol = NULL;
1323 expressionP->X_op_symbol = NULL;
1324
1325 /* Look to see if it's in the register table. */
1326 if (reg_number >= 0)
1327 {
1328 expressionP->X_op = O_register;
1329 expressionP->X_add_number = reg_number;
1330
1331 return TRUE;
1332 }
1333
1334 /* Reset the line as if we had not done anything. */
1335 input_line_pointer = start;
1336
1337 expressionP->X_op = O_illegal;
1338
1339 return FALSE;
1340 }
1341
1342 static void
skip_white_space(void)1343 skip_white_space (void)
1344 {
1345 while (*input_line_pointer == ' '
1346 || *input_line_pointer == '\t')
1347 ++input_line_pointer;
1348 }
1349
1350 /* Summary of parse_register_list ().
1351
1352 in: INPUT_LINE_POINTER points to 1st char of a list of registers.
1353 INSN is the partially constructed instruction.
1354 OPERAND is the operand being inserted.
1355
1356 out: NULL if the parse completed successfully, otherwise a
1357 pointer to an error message is returned. If the parse
1358 completes the correct bit fields in the instruction
1359 will be filled in.
1360
1361 Parses register lists with the syntax:
1362
1363 { rX }
1364 { rX, rY }
1365 { rX - rY }
1366 { rX - rY, rZ }
1367 etc
1368
1369 and also parses constant expressions whoes bits indicate the
1370 registers in the lists. The LSB in the expression refers to
1371 the lowest numbered permissible register in the register list,
1372 and so on upwards. System registers are considered to be very
1373 high numbers. */
1374
1375 static const char *
parse_register_list(unsigned long * insn,const struct v850_operand * operand)1376 parse_register_list (unsigned long *insn,
1377 const struct v850_operand *operand)
1378 {
1379 static int type1_regs[32] =
1380 {
1381 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1382 0, 0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24
1383 };
1384
1385 int *regs;
1386 expressionS exp;
1387
1388 /* Select a register array to parse. */
1389 switch (operand->shift)
1390 {
1391 case 0xffe00001: regs = type1_regs; break;
1392 default:
1393 as_bad (_("unknown operand shift: %x\n"), operand->shift);
1394 return _("internal failure in parse_register_list");
1395 }
1396
1397 skip_white_space ();
1398
1399 /* If the expression starts with a curly brace it is a register list.
1400 Otherwise it is a constant expression, whoes bits indicate which
1401 registers are to be included in the list. */
1402 if (*input_line_pointer != '{')
1403 {
1404 int reg;
1405 int i;
1406
1407 expression (&exp);
1408
1409 if (exp.X_op != O_constant)
1410 return _("constant expression or register list expected");
1411
1412 if (regs == type1_regs)
1413 {
1414 if (exp.X_add_number & 0xFFFFF000)
1415 return _("high bits set in register list expression");
1416
1417 for (reg = 20; reg < 32; reg++)
1418 if (exp.X_add_number & (1 << (reg - 20)))
1419 {
1420 for (i = 0; i < 32; i++)
1421 if (regs[i] == reg)
1422 *insn |= (1 << i);
1423 }
1424 }
1425
1426 return NULL;
1427 }
1428
1429 input_line_pointer++;
1430
1431 /* Parse the register list until a terminator (closing curly brace or
1432 new-line) is found. */
1433 for (;;)
1434 {
1435 skip_white_space ();
1436
1437 if (register_name (&exp))
1438 {
1439 int i;
1440
1441 /* Locate the given register in the list, and if it is there,
1442 insert the corresponding bit into the instruction. */
1443 for (i = 0; i < 32; i++)
1444 {
1445 if (regs[i] == exp.X_add_number)
1446 {
1447 *insn |= (1 << i);
1448 break;
1449 }
1450 }
1451
1452 if (i == 32)
1453 return _("illegal register included in list");
1454 }
1455 else if (system_register_name (&exp, TRUE))
1456 {
1457 if (regs == type1_regs)
1458 {
1459 return _("system registers cannot be included in list");
1460 }
1461 }
1462
1463 if (*input_line_pointer == '}')
1464 {
1465 input_line_pointer++;
1466 break;
1467 }
1468 else if (*input_line_pointer == ',')
1469 {
1470 input_line_pointer++;
1471 continue;
1472 }
1473 else if (*input_line_pointer == '-')
1474 {
1475 /* We have encountered a range of registers: rX - rY. */
1476 int j;
1477 expressionS exp2;
1478
1479 /* Skip the dash. */
1480 ++input_line_pointer;
1481
1482 /* Get the second register in the range. */
1483 if (! register_name (&exp2))
1484 {
1485 return _("second register should follow dash in register list");
1486 }
1487
1488 if (exp.X_add_number > exp2.X_add_number)
1489 {
1490 return _("second register should be greater than first register");
1491 }
1492
1493 /* Add the rest of the registers in the range. */
1494 for (j = exp.X_add_number + 1; j <= exp2.X_add_number; j++)
1495 {
1496 int i;
1497
1498 /* Locate the given register in the list, and if it is there,
1499 insert the corresponding bit into the instruction. */
1500 for (i = 0; i < 32; i++)
1501 {
1502 if (regs[i] == j)
1503 {
1504 *insn |= (1 << i);
1505 break;
1506 }
1507 }
1508
1509 if (i == 32)
1510 return _("illegal register included in list");
1511 }
1512
1513 exp = exp2;
1514 }
1515 else
1516 break;
1517 }
1518
1519 return NULL;
1520 }
1521
1522 const char *md_shortopts = "m:";
1523
1524 struct option md_longopts[] =
1525 {
1526 #define OPTION_DISP_SIZE_DEFAULT_22 (OPTION_MD_BASE)
1527 {"disp-size-default-22", no_argument, NULL, OPTION_DISP_SIZE_DEFAULT_22},
1528 #define OPTION_DISP_SIZE_DEFAULT_32 (OPTION_MD_BASE + 1)
1529 {"disp-size-default-32", no_argument, NULL, OPTION_DISP_SIZE_DEFAULT_32},
1530 {NULL, no_argument, NULL, 0}
1531 };
1532
1533 size_t md_longopts_size = sizeof (md_longopts);
1534
1535 static bfd_boolean v850_data_8 = FALSE;
1536
1537 void
md_show_usage(FILE * stream)1538 md_show_usage (FILE *stream)
1539 {
1540 fprintf (stream, _(" V850 options:\n"));
1541 fprintf (stream, _(" -mwarn-signed-overflow Warn if signed immediate values overflow\n"));
1542 fprintf (stream, _(" -mwarn-unsigned-overflow Warn if unsigned immediate values overflow\n"));
1543 fprintf (stream, _(" -mv850 The code is targeted at the v850\n"));
1544 fprintf (stream, _(" -mv850e The code is targeted at the v850e\n"));
1545 fprintf (stream, _(" -mv850e1 The code is targeted at the v850e1\n"));
1546 fprintf (stream, _(" -mv850e2 The code is targeted at the v850e2\n"));
1547 fprintf (stream, _(" -mv850e2v3 The code is targeted at the v850e2v3\n"));
1548 fprintf (stream, _(" -mv850e2v4 Alias for -mv850e3v5\n"));
1549 fprintf (stream, _(" -mv850e3v5 The code is targeted at the v850e3v5\n"));
1550 fprintf (stream, _(" -mrelax Enable relaxation\n"));
1551 fprintf (stream, _(" --disp-size-default-22 branch displacement with unknown size is 22 bits (default)\n"));
1552 fprintf (stream, _(" --disp-size-default-32 branch displacement with unknown size is 32 bits\n"));
1553 fprintf (stream, _(" -mextension enable extension opcode support\n"));
1554 fprintf (stream, _(" -mno-bcond17 disable b<cond> disp17 instruction\n"));
1555 fprintf (stream, _(" -mno-stld23 disable st/ld offset23 instruction\n"));
1556 fprintf (stream, _(" -mgcc-abi Mark the binary as using the old GCC ABI\n"));
1557 fprintf (stream, _(" -mrh850-abi Mark the binary as using the RH850 ABI (default)\n"));
1558 fprintf (stream, _(" -m8byte-align Mark the binary as using 64-bit alignment\n"));
1559 fprintf (stream, _(" -m4byte-align Mark the binary as using 32-bit alignment (default)\n"));
1560 fprintf (stream, _(" -msoft-float Mark the binary as not using FP insns (default for pre e2v3)\n"));
1561 fprintf (stream, _(" -mhard-float Mark the binary as using FP insns (default for e2v3 and up)\n"));
1562 }
1563
1564 int
md_parse_option(int c,const char * arg)1565 md_parse_option (int c, const char *arg)
1566 {
1567 if (c != 'm')
1568 {
1569 switch (c)
1570 {
1571 case OPTION_DISP_SIZE_DEFAULT_22:
1572 default_disp_size = 22;
1573 return 1;
1574
1575 case OPTION_DISP_SIZE_DEFAULT_32:
1576 default_disp_size = 32;
1577 return 1;
1578 }
1579 return 0;
1580 }
1581
1582 if (strcmp (arg, "warn-signed-overflow") == 0)
1583 warn_signed_overflows = TRUE;
1584
1585 else if (strcmp (arg, "warn-unsigned-overflow") == 0)
1586 warn_unsigned_overflows = TRUE;
1587
1588 else if (strcmp (arg, "v850") == 0)
1589 {
1590 machine = 0;
1591 SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850);
1592 }
1593 else if (strcmp (arg, "v850e") == 0)
1594 {
1595 machine = bfd_mach_v850e;
1596 SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E);
1597 }
1598 else if (strcmp (arg, "v850e1") == 0)
1599 {
1600 machine = bfd_mach_v850e1;
1601 SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E1);
1602 }
1603 else if (strcmp (arg, "v850e2") == 0)
1604 {
1605 machine = bfd_mach_v850e2;
1606 SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E2);
1607 }
1608 else if (strcmp (arg, "v850e2v3") == 0)
1609 {
1610 machine = bfd_mach_v850e2v3;
1611 SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E2V3);
1612 }
1613 else if (strcmp (arg, "v850e2v4") == 0)
1614 {
1615 machine = bfd_mach_v850e3v5;
1616 SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E3V5);
1617 }
1618 else if (strcmp (arg, "v850e3v5") == 0)
1619 {
1620 machine = bfd_mach_v850e3v5;
1621 SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E3V5);
1622 }
1623 else if (strcmp (arg, "extension") == 0)
1624 {
1625 processor_mask |= PROCESSOR_OPTION_EXTENSION | PROCESSOR_OPTION_ALIAS;
1626 }
1627 else if (strcmp (arg, "no-bcond17") == 0)
1628 {
1629 no_bcond17 = 1;
1630 }
1631 else if (strcmp (arg, "no-stld23") == 0)
1632 {
1633 no_stld23 = 1;
1634 }
1635 else if (strcmp (arg, "relax") == 0)
1636 v850_relax = 1;
1637 else if (strcmp (arg, "gcc-abi") == 0)
1638 {
1639 v850_target_arch = bfd_arch_v850;
1640 v850_target_format = "elf32-v850";
1641 }
1642 else if (strcmp (arg, "rh850-abi") == 0)
1643 {
1644 v850_target_arch = bfd_arch_v850_rh850;
1645 v850_target_format = "elf32-v850-rh850";
1646 }
1647 else if (strcmp (arg, "8byte-align") == 0)
1648 {
1649 v850_data_8 = TRUE;
1650 v850_e_flags |= EF_RH850_DATA_ALIGN8;
1651 }
1652 else if (strcmp (arg, "4byte-align") == 0)
1653 {
1654 v850_data_8 = FALSE;
1655 v850_e_flags &= ~ EF_RH850_DATA_ALIGN8;
1656 }
1657 else if (strcmp (arg, "soft-float") == 0)
1658 soft_float = 1;
1659 else if (strcmp (arg, "hard-float") == 0)
1660 soft_float = 0;
1661 else
1662 return 0;
1663
1664 return 1;
1665 }
1666
1667 symbolS *
md_undefined_symbol(char * name ATTRIBUTE_UNUSED)1668 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1669 {
1670 return 0;
1671 }
1672
1673 const char *
md_atof(int type,char * litp,int * sizep)1674 md_atof (int type, char *litp, int *sizep)
1675 {
1676 return ieee_md_atof (type, litp, sizep, FALSE);
1677 }
1678
1679 /* Very gross. */
1680
1681 void
md_convert_frag(bfd * abfd ATTRIBUTE_UNUSED,asection * sec,fragS * fragP)1682 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1683 asection *sec,
1684 fragS *fragP)
1685 {
1686 union u
1687 {
1688 bfd_reloc_code_real_type fx_r_type;
1689 char * fr_opcode;
1690 }
1691 opcode_converter;
1692 subseg_change (sec, 0);
1693
1694 opcode_converter.fr_opcode = fragP->fr_opcode;
1695
1696 subseg_change (sec, 0);
1697
1698 if (fragP->fr_subtype == SUBYPTE_LOOP_16_22)
1699 {
1700 fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
1701 fragP->fr_offset, 1,
1702 BFD_RELOC_UNUSED + opcode_converter.fx_r_type);
1703 fragP->fr_fix += 4;
1704 }
1705 else if (fragP->fr_subtype == SUBYPTE_LOOP_16_22 + 1)
1706 {
1707 unsigned char * buffer =
1708 (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
1709 int loop_reg = (buffer[0] & 0x1f);
1710
1711 /* Add -1.reg. */
1712 md_number_to_chars ((char *) buffer, 0x025f | (loop_reg << 11), 2);
1713 /* Now create the conditional branch + fixup to the final target. */
1714 /* 0x000107ea = bne LBL(disp17). */
1715 md_number_to_chars ((char *) buffer + 2, 0x000107ea, 4);
1716 fix_new (fragP, fragP->fr_fix+2, 4, fragP->fr_symbol,
1717 fragP->fr_offset, 1,
1718 BFD_RELOC_V850_17_PCREL);
1719 fragP->fr_fix += 6;
1720 }
1721 /* In range conditional or unconditional branch. */
1722 else if (fragP->fr_subtype == SUBYPTE_COND_9_22
1723 || fragP->fr_subtype == SUBYPTE_UNCOND_9_22
1724 || fragP->fr_subtype == SUBYPTE_COND_9_22_32
1725 || fragP->fr_subtype == SUBYPTE_UNCOND_9_22_32
1726 || fragP->fr_subtype == SUBYPTE_COND_9_17_22
1727 || fragP->fr_subtype == SUBYPTE_COND_9_17_22_32
1728 || fragP->fr_subtype == SUBYPTE_SA_9_22
1729 || fragP->fr_subtype == SUBYPTE_SA_9_22_32
1730 || fragP->fr_subtype == SUBYPTE_SA_9_17_22
1731 || fragP->fr_subtype == SUBYPTE_SA_9_17_22_32)
1732
1733 {
1734 fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
1735 fragP->fr_offset, 1,
1736 BFD_RELOC_UNUSED + opcode_converter.fx_r_type);
1737 fragP->fr_fix += 2;
1738 }
1739 /* V850e2r-v3 17bit conditional branch. */
1740 else if (fragP->fr_subtype == SUBYPTE_COND_9_17_22 + 1
1741 || fragP->fr_subtype == SUBYPTE_COND_9_17_22_32 + 1
1742 || fragP->fr_subtype == SUBYPTE_SA_9_17_22 + 1
1743 || fragP->fr_subtype == SUBYPTE_SA_9_17_22_32 + 1)
1744 {
1745 unsigned char *buffer =
1746 (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
1747
1748 buffer[0] &= 0x0f; /* Use condition. */
1749 buffer[0] |= 0xe0;
1750 buffer[1] = 0x07;
1751
1752 /* Now create the unconditional branch + fixup to the final
1753 target. */
1754 md_number_to_chars ((char *) buffer + 2, 0x0001, 2);
1755 fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
1756 fragP->fr_offset, 1, BFD_RELOC_V850_17_PCREL);
1757 fragP->fr_fix += 4;
1758 }
1759 /* Out of range conditional branch. Emit a branch around a 22bit jump. */
1760 else if (fragP->fr_subtype == SUBYPTE_COND_9_22 + 1
1761 || fragP->fr_subtype == SUBYPTE_COND_9_22_32 + 1
1762 || fragP->fr_subtype == SUBYPTE_COND_9_17_22 + 2
1763 || fragP->fr_subtype == SUBYPTE_COND_9_17_22_32 + 2)
1764 {
1765 unsigned char *buffer =
1766 (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
1767
1768 /* Reverse the condition of the first branch. */
1769 buffer[0] ^= 0x08;
1770 /* Mask off all the displacement bits. */
1771 buffer[0] &= 0x8f;
1772 buffer[1] &= 0x07;
1773 /* Now set the displacement bits so that we branch
1774 around the unconditional branch. */
1775 buffer[0] |= 0x30;
1776
1777 /* Now create the unconditional branch + fixup to the final
1778 target. */
1779 md_number_to_chars ((char *) buffer + 2, 0x00000780, 4);
1780 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
1781 fragP->fr_offset, 1, BFD_RELOC_V850_22_PCREL);
1782 fragP->fr_fix += 6;
1783 }
1784 /* Out of range conditional branch. Emit a branch around a 32bit jump. */
1785 else if (fragP->fr_subtype == SUBYPTE_COND_9_22_32 + 2
1786 || fragP->fr_subtype == SUBYPTE_COND_9_17_22_32 + 3)
1787 {
1788 unsigned char *buffer =
1789 (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
1790
1791 /* Reverse the condition of the first branch. */
1792 buffer[0] ^= 0x08;
1793 /* Mask off all the displacement bits. */
1794 buffer[0] &= 0x8f;
1795 buffer[1] &= 0x07;
1796 /* Now set the displacement bits so that we branch
1797 around the unconditional branch. */
1798 buffer[0] |= 0x40;
1799
1800 /* Now create the unconditional branch + fixup to the final
1801 target. */
1802 md_number_to_chars ((char *) buffer + 2, 0x02e0, 2);
1803 fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
1804 fragP->fr_offset + 2, 1, BFD_RELOC_V850_32_PCREL);
1805 fragP->fr_fix += 8;
1806 }
1807 /* Out of range unconditional branch. Emit a 22bit jump. */
1808 else if (fragP->fr_subtype == SUBYPTE_UNCOND_9_22 + 1
1809 || fragP->fr_subtype == SUBYPTE_UNCOND_9_22_32 + 1)
1810 {
1811 md_number_to_chars (fragP->fr_fix + fragP->fr_literal, 0x00000780, 4);
1812 fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
1813 fragP->fr_offset, 1, BFD_RELOC_V850_22_PCREL);
1814 fragP->fr_fix += 4;
1815 }
1816 /* Out of range unconditional branch. Emit a 32bit jump. */
1817 else if (fragP->fr_subtype == SUBYPTE_UNCOND_9_22_32 + 2)
1818 {
1819 md_number_to_chars (fragP->fr_fix + fragP->fr_literal, 0x02e0, 2);
1820 fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
1821 fragP->fr_offset + 2, 1, BFD_RELOC_V850_32_PCREL);
1822 fragP->fr_fix += 6;
1823 }
1824 /* Out of range SA conditional branch. Emit a branch to a 22bit jump. */
1825 else if (fragP->fr_subtype == SUBYPTE_SA_9_22 + 1
1826 || fragP->fr_subtype == SUBYPTE_SA_9_22_32 + 1
1827 || fragP->fr_subtype == SUBYPTE_SA_9_17_22 + 2
1828 || fragP->fr_subtype == SUBYPTE_SA_9_17_22_32 + 2)
1829 {
1830 unsigned char *buffer =
1831 (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
1832
1833 /* bsa .+4 */
1834 buffer[0] &= 0x8f;
1835 buffer[0] |= 0x20;
1836 buffer[1] &= 0x07;
1837
1838 /* br .+6 */
1839 md_number_to_chars ((char *) buffer + 2, 0x05b5, 2);
1840
1841 /* Now create the unconditional branch + fixup to the final
1842 target. */
1843 /* jr SYM */
1844 md_number_to_chars ((char *) buffer + 4, 0x00000780, 4);
1845 fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol,
1846 fragP->fr_offset, 1,
1847 BFD_RELOC_V850_22_PCREL);
1848 fragP->fr_fix += 8;
1849 }
1850 /* Out of range SA conditional branch. Emit a branch around a 32bit jump. */
1851 else if (fragP->fr_subtype == SUBYPTE_SA_9_22_32 + 2
1852 || fragP->fr_subtype == SUBYPTE_SA_9_17_22_32 + 3)
1853 {
1854 unsigned char *buffer =
1855 (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
1856
1857 /* bsa .+2 */
1858 buffer[0] &= 0x8f;
1859 buffer[0] |= 0x20;
1860 buffer[1] &= 0x07;
1861
1862 /* br .+8 */
1863 md_number_to_chars ((char *) buffer + 2, 0x05c5, 2);
1864
1865 /* Now create the unconditional branch + fixup to the final
1866 target. */
1867 /* jr SYM */
1868 md_number_to_chars ((char *) buffer + 4, 0x02e0, 2);
1869 fix_new (fragP, fragP->fr_fix + 6, 4, fragP->fr_symbol,
1870 fragP->fr_offset + 2, 1, BFD_RELOC_V850_32_PCREL);
1871
1872 fragP->fr_fix += 10;
1873 }
1874 else
1875 abort ();
1876 }
1877
1878 valueT
md_section_align(asection * seg,valueT addr)1879 md_section_align (asection *seg, valueT addr)
1880 {
1881 int align = bfd_get_section_alignment (stdoutput, seg);
1882 return ((addr + (1 << align) - 1) & -(1 << align));
1883 }
1884
1885 void
md_begin(void)1886 md_begin (void)
1887 {
1888 const char *prev_name = "";
1889 const struct v850_opcode *op;
1890
1891 if (strncmp (TARGET_CPU, "v850e3v5", 8) == 0)
1892 {
1893 if (machine == -1)
1894 machine = bfd_mach_v850e3v5;
1895
1896 if (!processor_mask)
1897 SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E3V5);
1898 }
1899 else if (strncmp (TARGET_CPU, "v850e2v4", 8) == 0)
1900 {
1901 if (machine == -1)
1902 machine = bfd_mach_v850e3v5;
1903
1904 if (!processor_mask)
1905 SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E3V5);
1906 }
1907 else if (strncmp (TARGET_CPU, "v850e2v3", 8) == 0)
1908 {
1909 if (machine == -1)
1910 machine = bfd_mach_v850e2v3;
1911
1912 if (!processor_mask)
1913 SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E2V3);
1914 }
1915 else if (strncmp (TARGET_CPU, "v850e2", 6) == 0)
1916 {
1917 if (machine == -1)
1918 machine = bfd_mach_v850e2;
1919
1920 if (!processor_mask)
1921 SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E2);
1922 }
1923 else if (strncmp (TARGET_CPU, "v850e1", 6) == 0)
1924 {
1925 if (machine == -1)
1926 machine = bfd_mach_v850e1;
1927
1928 if (!processor_mask)
1929 SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E1);
1930 }
1931 else if (strncmp (TARGET_CPU, "v850e", 5) == 0)
1932 {
1933 if (machine == -1)
1934 machine = bfd_mach_v850e;
1935
1936 if (!processor_mask)
1937 SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850E);
1938 }
1939 else if (strncmp (TARGET_CPU, "v850", 4) == 0)
1940 {
1941 if (machine == -1)
1942 machine = 0;
1943
1944 if (!processor_mask)
1945 SET_PROCESSOR_MASK (processor_mask, PROCESSOR_V850);
1946 }
1947 else
1948 /* xgettext:c-format */
1949 as_bad (_("Unable to determine default target processor from string: %s"),
1950 TARGET_CPU);
1951
1952 if (soft_float == -1)
1953 soft_float = machine < bfd_mach_v850e2v3;
1954
1955 v850_hash = hash_new ();
1956
1957 /* Insert unique names into hash table. The V850 instruction set
1958 has many identical opcode names that have different opcodes based
1959 on the operands. This hash table then provides a quick index to
1960 the first opcode with a particular name in the opcode table. */
1961 op = v850_opcodes;
1962 while (op->name)
1963 {
1964 if (strcmp (prev_name, op->name))
1965 {
1966 prev_name = (char *) op->name;
1967 hash_insert (v850_hash, op->name, (char *) op);
1968 }
1969 op++;
1970 }
1971
1972 v850_seg_table[BSS_SECTION].s = bss_section;
1973 bfd_set_arch_mach (stdoutput, v850_target_arch, machine);
1974 bfd_set_private_flags (stdoutput, v850_e_flags);
1975 }
1976
1977
1978 static bfd_reloc_code_real_type
handle_hi016(const struct v850_operand * operand,const char ** errmsg)1979 handle_hi016 (const struct v850_operand *operand, const char **errmsg)
1980 {
1981 if (operand == NULL)
1982 return BFD_RELOC_HI16;
1983
1984 if (operand->default_reloc == BFD_RELOC_HI16)
1985 return BFD_RELOC_HI16;
1986
1987 if (operand->default_reloc == BFD_RELOC_HI16_S)
1988 return BFD_RELOC_HI16;
1989
1990 if (operand->default_reloc == BFD_RELOC_16)
1991 return BFD_RELOC_HI16;
1992
1993 *errmsg = _("hi0() relocation used on an instruction which does "
1994 "not support it");
1995 return BFD_RELOC_64; /* Used to indicate an error condition. */
1996 }
1997
1998 static bfd_reloc_code_real_type
handle_hi16(const struct v850_operand * operand,const char ** errmsg)1999 handle_hi16 (const struct v850_operand *operand, const char **errmsg)
2000 {
2001 if (operand == NULL)
2002 return BFD_RELOC_HI16_S;
2003
2004 if (operand->default_reloc == BFD_RELOC_HI16_S)
2005 return BFD_RELOC_HI16_S;
2006
2007 if (operand->default_reloc == BFD_RELOC_HI16)
2008 return BFD_RELOC_HI16_S;
2009
2010 if (operand->default_reloc == BFD_RELOC_16)
2011 return BFD_RELOC_HI16_S;
2012
2013 *errmsg = _("hi() relocation used on an instruction which does "
2014 "not support it");
2015 return BFD_RELOC_64; /* Used to indicate an error condition. */
2016 }
2017
2018 static bfd_reloc_code_real_type
handle_lo16(const struct v850_operand * operand,const char ** errmsg)2019 handle_lo16 (const struct v850_operand *operand, const char **errmsg)
2020 {
2021 if (operand == NULL)
2022 return BFD_RELOC_LO16;
2023
2024 if (operand->default_reloc == BFD_RELOC_LO16)
2025 return BFD_RELOC_LO16;
2026
2027 if (operand->default_reloc == BFD_RELOC_V850_16_SPLIT_OFFSET)
2028 return BFD_RELOC_V850_LO16_SPLIT_OFFSET;
2029
2030 if (operand->default_reloc == BFD_RELOC_V850_16_S1)
2031 return BFD_RELOC_V850_LO16_S1;
2032
2033 if (operand->default_reloc == BFD_RELOC_16)
2034 return BFD_RELOC_LO16;
2035
2036 *errmsg = _("lo() relocation used on an instruction which does "
2037 "not support it");
2038 return BFD_RELOC_64; /* Used to indicate an error condition. */
2039 }
2040
2041 static bfd_reloc_code_real_type
handle_ctoff(const struct v850_operand * operand,const char ** errmsg)2042 handle_ctoff (const struct v850_operand *operand, const char **errmsg)
2043 {
2044 if (v850_target_arch == bfd_arch_v850_rh850)
2045 {
2046 *errmsg = _("ctoff() is not supported by the rh850 ABI. Use -mgcc-abi instead");
2047 return BFD_RELOC_64; /* Used to indicate an error condition. */
2048 }
2049
2050 if (operand == NULL)
2051 return BFD_RELOC_V850_CALLT_16_16_OFFSET;
2052
2053 if (operand->default_reloc == BFD_RELOC_V850_CALLT_6_7_OFFSET)
2054 return operand->default_reloc;
2055
2056 if (operand->default_reloc == BFD_RELOC_V850_16_S1)
2057 return BFD_RELOC_V850_CALLT_15_16_OFFSET;
2058
2059 if (operand->default_reloc == BFD_RELOC_16)
2060 return BFD_RELOC_V850_CALLT_16_16_OFFSET;
2061
2062 *errmsg = _("ctoff() relocation used on an instruction which does not support it");
2063 return BFD_RELOC_64; /* Used to indicate an error condition. */
2064 }
2065
2066 static bfd_reloc_code_real_type
handle_sdaoff(const struct v850_operand * operand,const char ** errmsg)2067 handle_sdaoff (const struct v850_operand *operand, const char **errmsg)
2068 {
2069 if (operand == NULL)
2070 return BFD_RELOC_V850_SDA_16_16_OFFSET;
2071
2072 if (operand->default_reloc == BFD_RELOC_V850_16_SPLIT_OFFSET)
2073 return BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET;
2074
2075 if (operand->default_reloc == BFD_RELOC_16)
2076 return BFD_RELOC_V850_SDA_16_16_OFFSET;
2077
2078 if (operand->default_reloc == BFD_RELOC_V850_16_S1)
2079 return BFD_RELOC_V850_SDA_15_16_OFFSET;
2080
2081 *errmsg = _("sdaoff() relocation used on an instruction which does not support it");
2082 return BFD_RELOC_64; /* Used to indicate an error condition. */
2083 }
2084
2085 static bfd_reloc_code_real_type
handle_zdaoff(const struct v850_operand * operand,const char ** errmsg)2086 handle_zdaoff (const struct v850_operand *operand, const char **errmsg)
2087 {
2088 if (operand == NULL)
2089 return BFD_RELOC_V850_ZDA_16_16_OFFSET;
2090
2091 if (operand->default_reloc == BFD_RELOC_V850_16_SPLIT_OFFSET)
2092 return BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET;
2093
2094 if (operand->default_reloc == BFD_RELOC_16)
2095 return BFD_RELOC_V850_ZDA_16_16_OFFSET;
2096
2097 if (operand->default_reloc == BFD_RELOC_V850_16_S1)
2098 return BFD_RELOC_V850_ZDA_15_16_OFFSET;
2099
2100 *errmsg = _("zdaoff() relocation used on an instruction which does not support it");
2101 return BFD_RELOC_64; /* Used to indicate an error condition. */
2102 }
2103
2104 static bfd_reloc_code_real_type
handle_tdaoff(const struct v850_operand * operand,const char ** errmsg)2105 handle_tdaoff (const struct v850_operand *operand, const char **errmsg)
2106 {
2107 if (operand == NULL)
2108 /* Data item, not an instruction. */
2109 return BFD_RELOC_V850_TDA_16_16_OFFSET;
2110
2111 switch (operand->default_reloc)
2112 {
2113 /* sld.hu, operand: D5-4. */
2114 case BFD_RELOC_V850_TDA_4_5_OFFSET:
2115 /* sld.bu, operand: D4. */
2116 case BFD_RELOC_V850_TDA_4_4_OFFSET:
2117 /* sld.w/sst.w, operand: D8_6. */
2118 case BFD_RELOC_V850_TDA_6_8_OFFSET:
2119 /* sld.h/sst.h, operand: D8_7. */
2120 case BFD_RELOC_V850_TDA_7_8_OFFSET:
2121 /* sld.b/sst.b, operand: D7. */
2122 case BFD_RELOC_V850_TDA_7_7_OFFSET:
2123 return operand->default_reloc;
2124 default:
2125 break;
2126 }
2127
2128 if (operand->default_reloc == BFD_RELOC_16 && operand->shift == 16)
2129 /* set1 & chums, operands: D16. */
2130 return BFD_RELOC_V850_TDA_16_16_OFFSET;
2131
2132 *errmsg = _("tdaoff() relocation used on an instruction which does not support it");
2133 /* Used to indicate an error condition. */
2134 return BFD_RELOC_64;
2135 }
2136
2137 /* Warning: The code in this function relies upon the definitions
2138 in the v850_operands[] array (defined in opcodes/v850-opc.c)
2139 matching the hard coded values contained herein. */
2140
2141 static bfd_reloc_code_real_type
v850_reloc_prefix(const struct v850_operand * operand,const char ** errmsg)2142 v850_reloc_prefix (const struct v850_operand *operand, const char **errmsg)
2143 {
2144 bfd_boolean paren_skipped = FALSE;
2145
2146 /* Skip leading opening parenthesis. */
2147 if (*input_line_pointer == '(')
2148 {
2149 ++input_line_pointer;
2150 paren_skipped = TRUE;
2151 }
2152
2153 #define CHECK_(name, reloc) \
2154 if (strncmp (input_line_pointer, name "(", strlen (name) + 1) == 0) \
2155 { \
2156 input_line_pointer += strlen (name); \
2157 return reloc; \
2158 }
2159
2160 CHECK_ ("hi0", handle_hi016(operand, errmsg) );
2161 CHECK_ ("hi", handle_hi16(operand, errmsg) );
2162 CHECK_ ("lo", handle_lo16 (operand, errmsg) );
2163 CHECK_ ("sdaoff", handle_sdaoff (operand, errmsg));
2164 CHECK_ ("zdaoff", handle_zdaoff (operand, errmsg));
2165 CHECK_ ("tdaoff", handle_tdaoff (operand, errmsg));
2166 CHECK_ ("hilo", BFD_RELOC_32);
2167 CHECK_ ("lo23", BFD_RELOC_V850_23);
2168 CHECK_ ("ctoff", handle_ctoff (operand, errmsg) );
2169
2170 /* Restore skipped parenthesis. */
2171 if (paren_skipped)
2172 --input_line_pointer;
2173
2174 return BFD_RELOC_NONE;
2175 }
2176
2177 /* Insert an operand value into an instruction. */
2178
2179 static unsigned long
v850_insert_operand(unsigned long insn,const struct v850_operand * operand,offsetT val,const char ** errmsg)2180 v850_insert_operand (unsigned long insn,
2181 const struct v850_operand *operand,
2182 offsetT val,
2183 const char **errmsg)
2184 {
2185 if (operand->insert)
2186 {
2187 const char *message = NULL;
2188
2189 insn = operand->insert (insn, val, &message);
2190 if (message != NULL)
2191 {
2192 if ((operand->flags & V850_OPERAND_SIGNED)
2193 && ! warn_signed_overflows
2194 && v850_msg_is_out_of_range (message))
2195 {
2196 /* Skip warning... */
2197 }
2198 else if ((operand->flags & V850_OPERAND_SIGNED) == 0
2199 && ! warn_unsigned_overflows
2200 && v850_msg_is_out_of_range (message))
2201 {
2202 /* Skip warning... */
2203 }
2204 else
2205 {
2206 if (errmsg != NULL)
2207 *errmsg = message;
2208 }
2209 }
2210 }
2211 else if (operand->bits == -1
2212 || operand->flags & V850E_IMMEDIATE16
2213 || operand->flags & V850E_IMMEDIATE23
2214 || operand->flags & V850E_IMMEDIATE32)
2215 {
2216 abort ();
2217 }
2218 else
2219 {
2220 if (operand->bits < 32)
2221 {
2222 long min, max;
2223
2224 if ((operand->flags & V850_OPERAND_SIGNED) != 0)
2225 {
2226 if (! warn_signed_overflows)
2227 max = (1 << operand->bits) - 1;
2228 else
2229 max = (1 << (operand->bits - 1)) - 1;
2230
2231 min = -(1 << (operand->bits - 1));
2232 }
2233 else
2234 {
2235 max = (1 << operand->bits) - 1;
2236
2237 if (! warn_unsigned_overflows)
2238 min = -(1 << (operand->bits - 1));
2239 else
2240 min = 0;
2241 }
2242
2243 /* Some people write constants with the sign extension done by
2244 hand but only up to 32 bits. This shouldn't really be valid,
2245 but, to permit this code to assemble on a 64-bit host, we
2246 sign extend the 32-bit value to 64 bits if so doing makes the
2247 value valid. */
2248 if (val > max
2249 && (offsetT) (val - 0x80000000 - 0x80000000) >= min
2250 && (offsetT) (val - 0x80000000 - 0x80000000) <= max)
2251 val = val - 0x80000000 - 0x80000000;
2252
2253 /* Similarly, people write expressions like ~(1<<15), and expect
2254 this to be OK for a 32-bit unsigned value. */
2255 else if (val < min
2256 && (offsetT) (val + 0x80000000 + 0x80000000) >= min
2257 && (offsetT) (val + 0x80000000 + 0x80000000) <= max)
2258 val = val + 0x80000000 + 0x80000000;
2259
2260 else if (val < (offsetT) min || val > (offsetT) max)
2261 {
2262 static char buf [128];
2263
2264 /* Restore min and mix to expected values for decimal ranges. */
2265 if ((operand->flags & V850_OPERAND_SIGNED)
2266 && ! warn_signed_overflows)
2267 max = (1 << (operand->bits - 1)) - 1;
2268
2269 if (! (operand->flags & V850_OPERAND_SIGNED)
2270 && ! warn_unsigned_overflows)
2271 min = 0;
2272
2273 sprintf (buf, _("operand out of range (%d is not between %d and %d)"),
2274 (int) val, (int) min, (int) max);
2275 *errmsg = buf;
2276 }
2277
2278 insn |= (((long) val & ((1 << operand->bits) - 1)) << operand->shift);
2279 }
2280 else
2281 {
2282 insn |= (((long) val) << operand->shift);
2283 }
2284 }
2285
2286 return insn;
2287 }
2288
2289 static char copy_of_instruction[128];
2290
2291 void
md_assemble(char * str)2292 md_assemble (char *str)
2293 {
2294 char *s;
2295 char *start_of_operands;
2296 struct v850_opcode *opcode;
2297 struct v850_opcode *next_opcode;
2298 const unsigned char *opindex_ptr;
2299 int next_opindex;
2300 int relaxable = 0;
2301 unsigned long insn;
2302 unsigned long insn_size;
2303 char *f = NULL;
2304 int i;
2305 int match;
2306 bfd_boolean extra_data_after_insn = FALSE;
2307 unsigned extra_data_len = 0;
2308 unsigned long extra_data = 0;
2309 char *saved_input_line_pointer;
2310 char most_match_errmsg[1024];
2311 int most_match_count = -1;
2312
2313 strncpy (copy_of_instruction, str, sizeof (copy_of_instruction) - 1);
2314 most_match_errmsg[0] = 0;
2315
2316 /* Get the opcode. */
2317 for (s = str; *s != '\0' && ! ISSPACE (*s); s++)
2318 continue;
2319
2320 if (*s != '\0')
2321 *s++ = '\0';
2322
2323 /* Find the first opcode with the proper name. */
2324 opcode = (struct v850_opcode *) hash_find (v850_hash, str);
2325 if (opcode == NULL)
2326 {
2327 /* xgettext:c-format */
2328 as_bad (_("Unrecognized opcode: `%s'"), str);
2329 ignore_rest_of_line ();
2330 return;
2331 }
2332
2333 str = s;
2334 while (ISSPACE (*str))
2335 ++str;
2336
2337 start_of_operands = str;
2338
2339 saved_input_line_pointer = input_line_pointer;
2340
2341 for (;;)
2342 {
2343 const char *errmsg = NULL;
2344 const char *warningmsg = NULL;
2345
2346 match = 0;
2347 opindex_ptr = opcode->operands;
2348
2349 if (no_stld23)
2350 {
2351 if ((strncmp (opcode->name, "st.", 3) == 0
2352 && v850_operands[opcode->operands[1]].bits == 23)
2353 || (strncmp (opcode->name, "ld.", 3) == 0
2354 && v850_operands[opcode->operands[0]].bits == 23))
2355 {
2356 errmsg = _("st/ld offset 23 instruction was disabled .");
2357 goto error;
2358 }
2359 }
2360
2361 if ((opcode->processors & processor_mask & PROCESSOR_MASK) == 0
2362 || (((opcode->processors & ~PROCESSOR_MASK) != 0)
2363 && ((opcode->processors & processor_mask & ~PROCESSOR_MASK) == 0)))
2364 {
2365 errmsg = _("Target processor does not support this instruction.");
2366 goto error;
2367 }
2368
2369 relaxable = 0;
2370 fc = 0;
2371 next_opindex = 0;
2372 insn = opcode->opcode;
2373 extra_data_len = 0;
2374 extra_data_after_insn = FALSE;
2375
2376 input_line_pointer = str = start_of_operands;
2377
2378 for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
2379 {
2380 const struct v850_operand *operand;
2381 char *hold;
2382 expressionS ex;
2383 bfd_reloc_code_real_type reloc;
2384
2385 if (next_opindex == 0)
2386 operand = &v850_operands[*opindex_ptr];
2387 else
2388 {
2389 operand = &v850_operands[next_opindex];
2390 next_opindex = 0;
2391 }
2392
2393 errmsg = NULL;
2394
2395 while (*str == ' ')
2396 ++str;
2397
2398 if (operand->flags & V850_OPERAND_BANG
2399 && *str == '!')
2400 ++str;
2401 else if (operand->flags & V850_OPERAND_PERCENT
2402 && *str == '%')
2403 ++str;
2404
2405 if (*str == ',' || *str == '[' || *str == ']')
2406 ++str;
2407
2408 while (*str == ' ')
2409 ++str;
2410
2411 if ( (strcmp (opcode->name, "pushsp") == 0
2412 || strcmp (opcode->name, "popsp") == 0
2413 || strcmp (opcode->name, "dbpush") == 0)
2414 && (*str == '-'))
2415 ++str;
2416
2417 if (operand->flags & V850_OPERAND_RELAX)
2418 relaxable = 1;
2419
2420 /* Gather the operand. */
2421 hold = input_line_pointer;
2422 input_line_pointer = str;
2423
2424 /* lo(), hi(), hi0(), etc... */
2425 if ((reloc = v850_reloc_prefix (operand, &errmsg)) != BFD_RELOC_NONE)
2426 {
2427 /* This is a fake reloc, used to indicate an error condition. */
2428 if (reloc == BFD_RELOC_64)
2429 {
2430 /* match = 1; */
2431 goto error;
2432 }
2433
2434 expression (&ex);
2435
2436 if (ex.X_op == O_constant)
2437 {
2438 switch (reloc)
2439 {
2440 case BFD_RELOC_V850_ZDA_16_16_OFFSET:
2441 case BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET:
2442 case BFD_RELOC_V850_ZDA_15_16_OFFSET:
2443 /* To cope with "not1 7, zdaoff(0xfffff006)[r0]"
2444 and the like. */
2445 /* Fall through. */
2446
2447 case BFD_RELOC_LO16:
2448 case BFD_RELOC_V850_LO16_S1:
2449 case BFD_RELOC_V850_LO16_SPLIT_OFFSET:
2450 {
2451 /* Truncate, then sign extend the value. */
2452 ex.X_add_number = SEXT16 (ex.X_add_number);
2453 break;
2454 }
2455
2456 case BFD_RELOC_HI16:
2457 {
2458 /* Truncate, then sign extend the value. */
2459 ex.X_add_number = SEXT16 (ex.X_add_number >> 16);
2460 break;
2461 }
2462
2463 case BFD_RELOC_HI16_S:
2464 {
2465 /* Truncate, then sign extend the value. */
2466 int temp = (ex.X_add_number >> 16) & 0xffff;
2467
2468 temp += (ex.X_add_number >> 15) & 1;
2469
2470 ex.X_add_number = SEXT16 (temp);
2471 break;
2472 }
2473
2474 case BFD_RELOC_V850_23:
2475 if ((operand->flags & V850E_IMMEDIATE23) == 0)
2476 {
2477 errmsg = _("immediate operand is too large");
2478 goto error;
2479 }
2480 break;
2481
2482 case BFD_RELOC_32:
2483 case BFD_RELOC_V850_32_ABS:
2484 case BFD_RELOC_V850_32_PCREL:
2485 if ((operand->flags & V850E_IMMEDIATE32) == 0)
2486 {
2487 errmsg = _("immediate operand is too large");
2488 goto error;
2489 }
2490
2491 break;
2492
2493 default:
2494 as_bad (_("AAARG -> unhandled constant reloc: %d"), reloc);
2495 break;
2496 }
2497
2498 if (operand->flags & V850E_IMMEDIATE32)
2499 {
2500 extra_data_after_insn = TRUE;
2501 extra_data_len = 4;
2502 extra_data = 0;
2503 }
2504 else if (operand->flags & V850E_IMMEDIATE23)
2505 {
2506 if (reloc != BFD_RELOC_V850_23)
2507 {
2508 errmsg = _("immediate operand is too large");
2509 goto error;
2510 }
2511 extra_data_after_insn = TRUE;
2512 extra_data_len = 2;
2513 extra_data = 0;
2514 }
2515 else if ((operand->flags & V850E_IMMEDIATE16)
2516 || (operand->flags & V850E_IMMEDIATE16HI))
2517 {
2518 if (operand->flags & V850E_IMMEDIATE16HI
2519 && reloc != BFD_RELOC_HI16
2520 && reloc != BFD_RELOC_HI16_S)
2521 {
2522 errmsg = _("immediate operand is too large");
2523 goto error;
2524 }
2525 else if (operand->flags & V850E_IMMEDIATE16
2526 && reloc != BFD_RELOC_LO16)
2527 {
2528 errmsg = _("immediate operand is too large");
2529 goto error;
2530 }
2531
2532 extra_data_after_insn = TRUE;
2533 extra_data_len = 2;
2534 extra_data = 0;
2535 }
2536
2537 if (fc > MAX_INSN_FIXUPS)
2538 as_fatal (_("too many fixups"));
2539
2540 fixups[fc].exp = ex;
2541 fixups[fc].opindex = *opindex_ptr;
2542 fixups[fc].reloc = reloc;
2543 fc++;
2544 }
2545 else /* ex.X_op != O_constant. */
2546 {
2547 if ((reloc == BFD_RELOC_32
2548 || reloc == BFD_RELOC_V850_32_ABS
2549 || reloc == BFD_RELOC_V850_32_PCREL)
2550 && operand->bits < 32)
2551 {
2552 errmsg = _("immediate operand is too large");
2553 goto error;
2554 }
2555 else if (reloc == BFD_RELOC_V850_23
2556 && (operand->flags & V850E_IMMEDIATE23) == 0)
2557 {
2558 errmsg = _("immediate operand is too large");
2559 goto error;
2560 }
2561 else if ((reloc == BFD_RELOC_HI16
2562 || reloc == BFD_RELOC_HI16_S)
2563 && operand->bits < 16)
2564 {
2565 errmsg = _("immediate operand is too large");
2566 goto error;
2567 }
2568
2569 if (operand->flags & V850E_IMMEDIATE32)
2570 {
2571 extra_data_after_insn = TRUE;
2572 extra_data_len = 4;
2573 extra_data = 0;
2574 }
2575 else if (operand->flags & V850E_IMMEDIATE23)
2576 {
2577 if (reloc != BFD_RELOC_V850_23)
2578 {
2579 errmsg = _("immediate operand is too large");
2580 goto error;
2581 }
2582 extra_data_after_insn = TRUE;
2583 extra_data_len = 2;
2584 extra_data = 0;
2585 }
2586 else if ((operand->flags & V850E_IMMEDIATE16)
2587 || (operand->flags & V850E_IMMEDIATE16HI))
2588 {
2589 if (operand->flags & V850E_IMMEDIATE16HI
2590 && reloc != BFD_RELOC_HI16
2591 && reloc != BFD_RELOC_HI16_S)
2592 {
2593 errmsg = _("immediate operand is too large");
2594 goto error;
2595 }
2596 else if (operand->flags & V850E_IMMEDIATE16
2597 && reloc != BFD_RELOC_LO16)
2598 {
2599 errmsg = _("immediate operand is too large");
2600 goto error;
2601 }
2602
2603 extra_data_after_insn = TRUE;
2604 extra_data_len = 2;
2605 extra_data = 0;
2606 }
2607
2608 if (fc > MAX_INSN_FIXUPS)
2609 as_fatal (_("too many fixups"));
2610
2611 fixups[fc].exp = ex;
2612 fixups[fc].opindex = *opindex_ptr;
2613 fixups[fc].reloc = reloc;
2614 fc++;
2615 }
2616 }
2617 else if (operand->flags & V850E_IMMEDIATE16
2618 || operand->flags & V850E_IMMEDIATE16HI)
2619 {
2620 expression (&ex);
2621
2622 switch (ex.X_op)
2623 {
2624 case O_constant:
2625 if (operand->flags & V850E_IMMEDIATE16HI)
2626 {
2627 if (ex.X_add_number & 0xffff)
2628 {
2629 errmsg = _("constant too big to fit into instruction");
2630 goto error;
2631 }
2632
2633 ex.X_add_number >>= 16;
2634 }
2635 if (operand->flags & V850E_IMMEDIATE16)
2636 {
2637 if ((ex.X_add_number & 0xffff8000)
2638 && ((ex.X_add_number & 0xffff8000) != 0xffff8000))
2639 {
2640 errmsg = _("constant too big to fit into instruction");
2641 goto error;
2642 }
2643 }
2644 break;
2645
2646 case O_illegal:
2647 errmsg = _("illegal operand");
2648 goto error;
2649
2650 case O_absent:
2651 errmsg = _("missing operand");
2652 goto error;
2653
2654 default:
2655 if (fc >= MAX_INSN_FIXUPS)
2656 as_fatal (_("too many fixups"));
2657
2658 fixups[fc].exp = ex;
2659 fixups[fc].opindex = *opindex_ptr;
2660 fixups[fc].reloc = operand->default_reloc;
2661 ++fc;
2662
2663 ex.X_add_number = 0;
2664 break;
2665 }
2666
2667 extra_data_after_insn = TRUE;
2668 extra_data_len = 2;
2669 extra_data = ex.X_add_number;
2670 }
2671 else if (operand->flags & V850E_IMMEDIATE23)
2672 {
2673 expression (&ex);
2674
2675 switch (ex.X_op)
2676 {
2677 case O_constant:
2678 break;
2679
2680 case O_illegal:
2681 errmsg = _("illegal operand");
2682 goto error;
2683
2684 case O_absent:
2685 errmsg = _("missing operand");
2686 goto error;
2687
2688 default:
2689 break;
2690 }
2691
2692 if (fc >= MAX_INSN_FIXUPS)
2693 as_fatal (_("too many fixups"));
2694
2695 fixups[fc].exp = ex;
2696 fixups[fc].opindex = *opindex_ptr;
2697 fixups[fc].reloc = operand->default_reloc;
2698 ++fc;
2699
2700 extra_data_after_insn = TRUE;
2701 extra_data_len = 2;
2702 extra_data = 0;
2703 }
2704 else if (operand->flags & V850E_IMMEDIATE32)
2705 {
2706 expression (&ex);
2707
2708 switch (ex.X_op)
2709 {
2710 case O_constant:
2711 if ((operand->default_reloc == BFD_RELOC_V850_32_ABS
2712 || operand->default_reloc == BFD_RELOC_V850_32_PCREL)
2713 && (ex.X_add_number & 1))
2714 {
2715 errmsg = _("odd number cannot be used here");
2716 goto error;
2717 }
2718 break;
2719
2720 case O_illegal:
2721 errmsg = _("illegal operand");
2722 goto error;
2723
2724 case O_absent:
2725 errmsg = _("missing operand");
2726 goto error;
2727
2728 default:
2729 if (fc >= MAX_INSN_FIXUPS)
2730 as_fatal (_("too many fixups"));
2731
2732 fixups[fc].exp = ex;
2733 fixups[fc].opindex = *opindex_ptr;
2734 fixups[fc].reloc = operand->default_reloc;
2735 ++fc;
2736
2737 ex.X_add_number = 0;
2738 break;
2739 }
2740
2741 extra_data_after_insn = TRUE;
2742 extra_data_len = 4;
2743 extra_data = ex.X_add_number;
2744 }
2745 else if (operand->flags & V850E_OPERAND_REG_LIST)
2746 {
2747 errmsg = parse_register_list (&insn, operand);
2748
2749 if (errmsg)
2750 goto error;
2751 }
2752 else
2753 {
2754 errmsg = NULL;
2755
2756 if ((operand->flags & V850_OPERAND_REG) != 0)
2757 {
2758 if (!register_name (&ex))
2759 {
2760 errmsg = _("invalid register name");
2761 }
2762
2763 if ((operand->flags & V850_NOT_R0)
2764 && ex.X_add_number == 0)
2765 {
2766 errmsg = _("register r0 cannot be used here");
2767 }
2768
2769 if (operand->flags & V850_REG_EVEN)
2770 {
2771 if (ex.X_add_number % 2)
2772 errmsg = _("odd register cannot be used here");
2773 ex.X_add_number = ex.X_add_number / 2;
2774 }
2775
2776 }
2777 else if ((operand->flags & V850_OPERAND_SRG) != 0)
2778 {
2779 if (!system_register_name (&ex, TRUE))
2780 {
2781 errmsg = _("invalid system register name");
2782 }
2783 }
2784 else if ((operand->flags & V850_OPERAND_EP) != 0)
2785 {
2786 char *start = input_line_pointer;
2787 char *name;
2788 char c = get_symbol_name (&name);
2789
2790 if (strcmp (name, "ep") != 0 && strcmp (name, "r30") != 0)
2791 {
2792 /* Put things back the way we found them. */
2793 (void) restore_line_pointer (c);
2794 input_line_pointer = start;
2795 errmsg = _("expected EP register");
2796 goto error;
2797 }
2798
2799 (void) restore_line_pointer (c);
2800 str = input_line_pointer;
2801 input_line_pointer = hold;
2802
2803 while (*str == ' ' || *str == ','
2804 || *str == '[' || *str == ']')
2805 ++str;
2806 continue;
2807 }
2808 else if ((operand->flags & V850_OPERAND_CC) != 0)
2809 {
2810 if (!cc_name (&ex, TRUE))
2811 {
2812 errmsg = _("invalid condition code name");
2813 }
2814
2815 if ((operand->flags & V850_NOT_SA)
2816 && ex.X_add_number == COND_SA_NUM)
2817 {
2818 errmsg = _("condition sa cannot be used here");
2819 }
2820 }
2821 else if ((operand->flags & V850_OPERAND_FLOAT_CC) != 0)
2822 {
2823 if (!float_cc_name (&ex, TRUE))
2824 {
2825 errmsg = _("invalid condition code name");
2826 }
2827 }
2828 else if ((operand->flags & V850_OPERAND_CACHEOP) != 0)
2829 {
2830 if (!cacheop_name (&ex, TRUE))
2831 errmsg = _("invalid cache oparation name");
2832 }
2833 else if ((operand->flags & V850_OPERAND_PREFOP) != 0)
2834 {
2835 if (!prefop_name (&ex, TRUE))
2836 errmsg = _("invalid pref oparation name");
2837 }
2838 else if ((operand->flags & V850_OPERAND_VREG) != 0)
2839 {
2840 if (!vector_register_name (&ex))
2841 errmsg = _("invalid vector register name");
2842 }
2843 else if ((register_name (&ex)
2844 && (operand->flags & V850_OPERAND_REG) == 0))
2845 {
2846 char *name;
2847 char c;
2848 int exists = 0;
2849
2850 /* It is possible that an alias has been defined that
2851 matches a register name. For example the code may
2852 include a ".set ZERO, 0" directive, which matches
2853 the register name "zero". Attempt to reparse the
2854 field as an expression, and only complain if we
2855 cannot generate a constant. */
2856
2857 input_line_pointer = str;
2858
2859 c = get_symbol_name (&name);
2860
2861 if (symbol_find (name) != NULL)
2862 exists = 1;
2863
2864 (void) restore_line_pointer (c);
2865 input_line_pointer = str;
2866
2867 expression (&ex);
2868
2869 if (ex.X_op != O_constant)
2870 {
2871 /* If this register is actually occurring too early on
2872 the parsing of the instruction, (because another
2873 field is missing) then report this. */
2874 if (opindex_ptr[1] != 0
2875 && ((v850_operands[opindex_ptr[1]].flags
2876 & V850_OPERAND_REG)
2877 ||(v850_operands[opindex_ptr[1]].flags
2878 & V850_OPERAND_VREG)))
2879 errmsg = _("syntax error: value is missing before the register name");
2880 else
2881 errmsg = _("syntax error: register not expected");
2882
2883 /* If we created a symbol in the process of this
2884 test then delete it now, so that it will not
2885 be output with the real symbols... */
2886 if (exists == 0
2887 && ex.X_op == O_symbol)
2888 symbol_remove (ex.X_add_symbol,
2889 &symbol_rootP, &symbol_lastP);
2890 }
2891 }
2892 else if (system_register_name (&ex, FALSE)
2893 && (operand->flags & V850_OPERAND_SRG) == 0)
2894 {
2895 errmsg = _("syntax error: system register not expected");
2896 }
2897 else if (cc_name (&ex, FALSE)
2898 && (operand->flags & V850_OPERAND_CC) == 0)
2899 {
2900 errmsg = _("syntax error: condition code not expected");
2901 }
2902 else if (float_cc_name (&ex, FALSE)
2903 && (operand->flags & V850_OPERAND_FLOAT_CC) == 0)
2904 {
2905 errmsg = _("syntax error: condition code not expected");
2906 }
2907 else if (vector_register_name (&ex)
2908 && (operand->flags & V850_OPERAND_VREG) == 0)
2909 {
2910 errmsg = _("syntax error: vector register not expected");
2911 }
2912 else
2913 {
2914 expression (&ex);
2915
2916 if ((operand->flags & V850_NOT_IMM0)
2917 && ex.X_op == O_constant
2918 && ex.X_add_number == 0)
2919 {
2920 errmsg = _("immediate 0 cannot be used here");
2921 }
2922
2923 /* Special case:
2924 If we are assembling a MOV/JARL/JR instruction and the immediate
2925 value does not fit into the bits available then create a
2926 fake error so that the next MOV/JARL/JR instruction will be
2927 selected. This one has a 32 bit immediate field. */
2928
2929 if ((strcmp (opcode->name, "mov") == 0
2930 || strcmp (opcode->name, "jarl") == 0
2931 || strcmp (opcode->name, "jr") == 0)
2932 && ex.X_op == O_constant
2933 && (ex.X_add_number < (-(1 << (operand->bits - 1)))
2934 || ex.X_add_number > ((1 << (operand->bits - 1)) - 1)))
2935 {
2936 errmsg = _("immediate operand is too large");
2937 }
2938
2939 if ((strcmp (opcode->name, "jarl") == 0
2940 || strcmp (opcode->name, "jr") == 0)
2941 && ex.X_op != O_constant
2942 && operand->bits != default_disp_size)
2943 {
2944 errmsg = _("immediate operand is not match");
2945 }
2946
2947 /* Special case2 :
2948 If we are assembling a ld/st instruction and the immediate
2949 value does not fit into the bits available then create a
2950 fake error so that the next ld/st instruction will be
2951 selected. */
2952 if ( ( (strncmp (opcode->name, "st.", 3) == 0)
2953 || (strncmp (opcode->name, "ld.", 3) == 0))
2954 && ex.X_op == O_constant
2955 && (ex.X_add_number < (-(1 << (operand->bits - 1)))
2956 || ex.X_add_number > ((1 << (operand->bits - 1)) - 1)))
2957 errmsg = _("displacement is too large");
2958 }
2959
2960 if (errmsg)
2961 goto error;
2962
2963 switch (ex.X_op)
2964 {
2965 case O_illegal:
2966 errmsg = _("illegal operand");
2967 goto error;
2968 case O_absent:
2969 errmsg = _("missing operand");
2970 goto error;
2971 case O_register:
2972 if ((operand->flags
2973 & (V850_OPERAND_REG | V850_OPERAND_SRG | V850_OPERAND_VREG)) == 0)
2974 {
2975 errmsg = _("invalid operand");
2976 goto error;
2977 }
2978
2979 insn = v850_insert_operand (insn, operand,
2980 ex.X_add_number,
2981 &warningmsg);
2982
2983 break;
2984
2985 case O_constant:
2986 insn = v850_insert_operand (insn, operand, ex.X_add_number,
2987 &warningmsg);
2988 break;
2989
2990 default:
2991 /* We need to generate a fixup for this expression. */
2992 if (fc >= MAX_INSN_FIXUPS)
2993 as_fatal (_("too many fixups"));
2994
2995 fixups[fc].exp = ex;
2996 fixups[fc].opindex = *opindex_ptr;
2997 fixups[fc].reloc = BFD_RELOC_NONE;
2998 ++fc;
2999 break;
3000 }
3001 }
3002
3003 str = input_line_pointer;
3004 input_line_pointer = hold;
3005
3006 while (*str == ' ' || *str == ',' || *str == '[' || *str == ']'
3007 || *str == ')')
3008 ++str;
3009 }
3010
3011 while (ISSPACE (*str))
3012 ++str;
3013
3014 if (*str == '\0')
3015 match = 1;
3016
3017 error:
3018 if (match == 0)
3019 {
3020 if ((opindex_ptr - opcode->operands) >= most_match_count)
3021 {
3022 most_match_count = opindex_ptr - opcode->operands;
3023 if (errmsg != NULL)
3024 strncpy (most_match_errmsg, errmsg, sizeof (most_match_errmsg)-1);
3025 }
3026
3027 next_opcode = opcode + 1;
3028 if (next_opcode->name != NULL
3029 && strcmp (next_opcode->name, opcode->name) == 0)
3030 {
3031 opcode = next_opcode;
3032
3033 /* Skip versions that are not supported by the target
3034 processor. */
3035 if ((opcode->processors & processor_mask) == 0)
3036 goto error;
3037
3038 continue;
3039 }
3040
3041 if (most_match_errmsg[0] == 0)
3042 /* xgettext:c-format. */
3043 as_bad (_("junk at end of line: `%s'"), str);
3044 else
3045 as_bad ("%s: %s", copy_of_instruction, most_match_errmsg);
3046
3047 if (*input_line_pointer == ']')
3048 ++input_line_pointer;
3049
3050 ignore_rest_of_line ();
3051 input_line_pointer = saved_input_line_pointer;
3052 return;
3053 }
3054
3055 if (warningmsg != NULL)
3056 as_warn ("%s", warningmsg);
3057 break;
3058 }
3059
3060 input_line_pointer = str;
3061
3062 /* Tie dwarf2 debug info to the address at the start of the insn.
3063 We can't do this after the insn has been output as the current
3064 frag may have been closed off. eg. by frag_var. */
3065 dwarf2_emit_insn (0);
3066
3067 /* Write out the instruction. */
3068
3069 if (relaxable && fc > 0)
3070 {
3071 insn_size = 2;
3072 fc = 0;
3073
3074 if (strcmp (opcode->name, "loop") == 0)
3075 {
3076 if (((processor_mask & PROCESSOR_V850E3V5_UP) == 0) || default_disp_size == 22)
3077 {
3078 insn_size = 4;
3079 f = frag_var (rs_machine_dependent, 6, 2, SUBYPTE_LOOP_16_22,
3080 fixups[0].exp.X_add_symbol,
3081 fixups[0].exp.X_add_number,
3082 (char *)(size_t) fixups[0].opindex);
3083 md_number_to_chars (f, insn, insn_size);
3084 md_number_to_chars (f+4, 0, 4);
3085 }
3086 else
3087 {
3088 as_bad (_("loop: 32-bit displacement not supported"));
3089 }
3090 }
3091 else if (strcmp (opcode->name, "br") == 0
3092 || strcmp (opcode->name, "jbr") == 0)
3093 {
3094 if ((processor_mask & PROCESSOR_V850E2_UP) == 0 || default_disp_size == 22)
3095 {
3096 f = frag_var (rs_machine_dependent, 4, 2, SUBYPTE_UNCOND_9_22,
3097 fixups[0].exp.X_add_symbol,
3098 fixups[0].exp.X_add_number,
3099 (char *)(size_t) fixups[0].opindex);
3100 md_number_to_chars (f, insn, insn_size);
3101 md_number_to_chars (f + 2, 0, 2);
3102 }
3103 else
3104 {
3105 f = frag_var (rs_machine_dependent, 6, 4, SUBYPTE_UNCOND_9_22_32,
3106 fixups[0].exp.X_add_symbol,
3107 fixups[0].exp.X_add_number,
3108 (char *)(size_t) fixups[0].opindex);
3109 md_number_to_chars (f, insn, insn_size);
3110 md_number_to_chars (f + 2, 0, 4);
3111 }
3112 }
3113 else /* b<cond>, j<cond>. */
3114 {
3115 if (default_disp_size == 22
3116 || (processor_mask & PROCESSOR_V850E2_UP) == 0)
3117 {
3118 if (processor_mask & PROCESSOR_V850E2V3_UP && !no_bcond17)
3119 {
3120 if (strcmp (opcode->name, "bsa") == 0)
3121 {
3122 f = frag_var (rs_machine_dependent, 8, 6, SUBYPTE_SA_9_17_22,
3123 fixups[0].exp.X_add_symbol,
3124 fixups[0].exp.X_add_number,
3125 (char *)(size_t) fixups[0].opindex);
3126 md_number_to_chars (f, insn, insn_size);
3127 md_number_to_chars (f + 2, 0, 6);
3128 }
3129 else
3130 {
3131 f = frag_var (rs_machine_dependent, 6, 4, SUBYPTE_COND_9_17_22,
3132 fixups[0].exp.X_add_symbol,
3133 fixups[0].exp.X_add_number,
3134 (char *)(size_t) fixups[0].opindex);
3135 md_number_to_chars (f, insn, insn_size);
3136 md_number_to_chars (f + 2, 0, 4);
3137 }
3138 }
3139 else
3140 {
3141 if (strcmp (opcode->name, "bsa") == 0)
3142 {
3143 f = frag_var (rs_machine_dependent, 8, 6, SUBYPTE_SA_9_22,
3144 fixups[0].exp.X_add_symbol,
3145 fixups[0].exp.X_add_number,
3146 (char *)(size_t) fixups[0].opindex);
3147 md_number_to_chars (f, insn, insn_size);
3148 md_number_to_chars (f + 2, 0, 6);
3149 }
3150 else
3151 {
3152 f = frag_var (rs_machine_dependent, 6, 4, SUBYPTE_COND_9_22,
3153 fixups[0].exp.X_add_symbol,
3154 fixups[0].exp.X_add_number,
3155 (char *)(size_t) fixups[0].opindex);
3156 md_number_to_chars (f, insn, insn_size);
3157 md_number_to_chars (f + 2, 0, 4);
3158 }
3159 }
3160 }
3161 else
3162 {
3163 if (processor_mask & PROCESSOR_V850E2V3_UP && !no_bcond17)
3164 {
3165 if (strcmp (opcode->name, "bsa") == 0)
3166 {
3167 f = frag_var (rs_machine_dependent, 10, 8, SUBYPTE_SA_9_17_22_32,
3168 fixups[0].exp.X_add_symbol,
3169 fixups[0].exp.X_add_number,
3170 (char *)(size_t) fixups[0].opindex);
3171 md_number_to_chars (f, insn, insn_size);
3172 md_number_to_chars (f + 2, 0, 8);
3173 }
3174 else
3175 {
3176 f = frag_var (rs_machine_dependent, 8, 6, SUBYPTE_COND_9_17_22_32,
3177 fixups[0].exp.X_add_symbol,
3178 fixups[0].exp.X_add_number,
3179 (char *)(size_t) fixups[0].opindex);
3180 md_number_to_chars (f, insn, insn_size);
3181 md_number_to_chars (f + 2, 0, 6);
3182 }
3183 }
3184 else
3185 {
3186 if (strcmp (opcode->name, "bsa") == 0)
3187 {
3188 f = frag_var (rs_machine_dependent, 10, 8, SUBYPTE_SA_9_22_32,
3189 fixups[0].exp.X_add_symbol,
3190 fixups[0].exp.X_add_number,
3191 (char *)(size_t) fixups[0].opindex);
3192 md_number_to_chars (f, insn, insn_size);
3193 md_number_to_chars (f + 2, 0, 8);
3194 }
3195 else
3196 {
3197 f = frag_var (rs_machine_dependent, 8, 6, SUBYPTE_COND_9_22_32,
3198 fixups[0].exp.X_add_symbol,
3199 fixups[0].exp.X_add_number,
3200 (char *)(size_t) fixups[0].opindex);
3201 md_number_to_chars (f, insn, insn_size);
3202 md_number_to_chars (f + 2, 0, 6);
3203 }
3204 }
3205 }
3206 }
3207 }
3208 else
3209 {
3210 /* Four byte insns have an opcode with the two high bits on. */
3211 if ((insn & 0x0600) == 0x0600)
3212 insn_size = 4;
3213 else
3214 insn_size = 2;
3215
3216 /* Special case: 32 bit MOV. */
3217 if ((insn & 0xffe0) == 0x0620)
3218 insn_size = 2;
3219
3220 /* Special case: 32 bit JARL,JMP,JR. */
3221 if ((insn & 0x1ffe0) == 0x2e0 /* JARL. */
3222 || (insn & 0x1ffe0) == 0x6e0 /* JMP. */
3223 || (insn & 0x1ffff) == 0x2e0) /* JR. */
3224 insn_size = 2;
3225
3226 if (obstack_room (& frchain_now->frch_obstack) < (insn_size + extra_data_len))
3227 {
3228 frag_wane (frag_now);
3229 frag_new (0);
3230 }
3231
3232 f = frag_more (insn_size);
3233 md_number_to_chars (f, insn, insn_size);
3234
3235 if (extra_data_after_insn)
3236 {
3237 f = frag_more (extra_data_len);
3238 md_number_to_chars (f, extra_data, extra_data_len);
3239
3240 extra_data_after_insn = FALSE;
3241 }
3242 }
3243
3244 /* Create any fixups. At this point we do not use a
3245 bfd_reloc_code_real_type, but instead just use the
3246 BFD_RELOC_UNUSED plus the operand index. This lets us easily
3247 handle fixups for any operand type, although that is admittedly
3248 not a very exciting feature. We pick a BFD reloc type in
3249 md_apply_fix. */
3250 for (i = 0; i < fc; i++)
3251 {
3252 const struct v850_operand *operand;
3253 bfd_reloc_code_real_type reloc;
3254
3255 operand = &v850_operands[fixups[i].opindex];
3256
3257 reloc = fixups[i].reloc;
3258
3259 if (reloc != BFD_RELOC_NONE)
3260 {
3261 reloc_howto_type *reloc_howto =
3262 bfd_reloc_type_lookup (stdoutput, reloc);
3263 int size;
3264 int address;
3265 fixS *fixP;
3266
3267 if (!reloc_howto)
3268 abort ();
3269
3270 size = bfd_get_reloc_size (reloc_howto);
3271
3272 /* XXX This will abort on an R_V850_8 reloc -
3273 is this reloc actually used? */
3274 if (size != 2 && size != 4)
3275 abort ();
3276
3277 if (extra_data_len == 0)
3278 {
3279 address = (f - frag_now->fr_literal) + insn_size - size;
3280 }
3281 else
3282 {
3283 address = (f - frag_now->fr_literal) + extra_data_len - size;
3284 }
3285
3286 if ((operand->flags & V850E_IMMEDIATE32) && (operand->flags & V850_PCREL))
3287 {
3288 fixups[i].exp.X_add_number += 2;
3289 }
3290 else if (operand->default_reloc == BFD_RELOC_V850_16_PCREL)
3291 {
3292 fixups[i].exp.X_add_number += 2;
3293 address += 2;
3294 }
3295
3296 /* fprintf (stderr, "0x%x %d %ld\n", address, size, fixups[i].exp.X_add_number); */
3297 fixP = fix_new_exp (frag_now, address, size,
3298 &fixups[i].exp,
3299 reloc_howto->pc_relative,
3300 reloc);
3301
3302 fixP->tc_fix_data = (void *) operand;
3303
3304 switch (reloc)
3305 {
3306 case BFD_RELOC_LO16:
3307 case BFD_RELOC_V850_LO16_S1:
3308 case BFD_RELOC_V850_LO16_SPLIT_OFFSET:
3309 case BFD_RELOC_HI16:
3310 case BFD_RELOC_HI16_S:
3311 fixP->fx_no_overflow = 1;
3312 break;
3313 default:
3314 break;
3315 }
3316 }
3317 else
3318 {
3319 gas_assert (f != NULL);
3320 fix_new_exp (frag_now,
3321 f - frag_now->fr_literal, 4,
3322 & fixups[i].exp,
3323 (operand->flags & V850_PCREL) != 0,
3324 (bfd_reloc_code_real_type) (fixups[i].opindex
3325 + (int) BFD_RELOC_UNUSED));
3326 }
3327 }
3328
3329 input_line_pointer = saved_input_line_pointer;
3330 }
3331
3332 /* If while processing a fixup, a reloc really needs to be created
3333 then it is done here. */
3334
3335 arelent *
tc_gen_reloc(asection * seg ATTRIBUTE_UNUSED,fixS * fixp)3336 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
3337 {
3338 arelent *reloc;
3339
3340 reloc = XNEW (arelent);
3341 reloc->sym_ptr_ptr = XNEW (asymbol *);
3342 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3343 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3344
3345 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
3346 || fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
3347 || fixp->fx_r_type == BFD_RELOC_V850_LONGCALL
3348 || fixp->fx_r_type == BFD_RELOC_V850_LONGJUMP
3349 || fixp->fx_r_type == BFD_RELOC_V850_ALIGN)
3350 reloc->addend = fixp->fx_offset;
3351 else
3352 {
3353 #if 0
3354 if (fixp->fx_r_type == BFD_RELOC_32
3355 && fixp->fx_pcrel)
3356 fixp->fx_r_type = BFD_RELOC_32_PCREL;
3357 #endif
3358
3359 reloc->addend = fixp->fx_addnumber;
3360 }
3361
3362 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3363
3364 if (reloc->howto == NULL)
3365 {
3366 as_bad_where (fixp->fx_file, fixp->fx_line,
3367 /* xgettext:c-format */
3368 _("reloc %d not supported by object file format"),
3369 (int) fixp->fx_r_type);
3370
3371 xfree (reloc);
3372
3373 return NULL;
3374 }
3375
3376 return reloc;
3377 }
3378
3379 void
v850_handle_align(fragS * frag)3380 v850_handle_align (fragS * frag)
3381 {
3382 if (v850_relax
3383 && frag->fr_type == rs_align
3384 && frag->fr_address + frag->fr_fix > 0
3385 && frag->fr_offset > 1
3386 && now_seg != bss_section
3387 && now_seg != v850_seg_table[SBSS_SECTION].s
3388 && now_seg != v850_seg_table[TBSS_SECTION].s
3389 && now_seg != v850_seg_table[ZBSS_SECTION].s)
3390 fix_new (frag, frag->fr_fix, 2, & abs_symbol, frag->fr_offset, 0,
3391 BFD_RELOC_V850_ALIGN);
3392 }
3393
3394 /* Return current size of variable part of frag. */
3395
3396 int
md_estimate_size_before_relax(fragS * fragp,asection * seg ATTRIBUTE_UNUSED)3397 md_estimate_size_before_relax (fragS *fragp, asection *seg ATTRIBUTE_UNUSED)
3398 {
3399 if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
3400 abort ();
3401
3402 return md_relax_table[fragp->fr_subtype].rlx_length;
3403 }
3404
3405 long
v850_pcrel_from_section(fixS * fixp,segT section)3406 v850_pcrel_from_section (fixS *fixp, segT section)
3407 {
3408 /* If the symbol is undefined, or in a section other than our own,
3409 or it is weak (in which case it may well be in another section,
3410 then let the linker figure it out. */
3411 if (fixp->fx_addsy != (symbolS *) NULL
3412 && (! S_IS_DEFINED (fixp->fx_addsy)
3413 || S_IS_WEAK (fixp->fx_addsy)
3414 || (S_GET_SEGMENT (fixp->fx_addsy) != section)))
3415 return 0;
3416
3417 return fixp->fx_frag->fr_address + fixp->fx_where;
3418 }
3419
3420 void
md_apply_fix(fixS * fixP,valueT * valueP,segT seg ATTRIBUTE_UNUSED)3421 md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
3422 {
3423 valueT value = * valueP;
3424 char *where;
3425
3426 if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
3427 || fixP->fx_r_type == BFD_RELOC_V850_LONGCALL
3428 || fixP->fx_r_type == BFD_RELOC_V850_LONGJUMP
3429 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3430 {
3431 fixP->fx_done = 0;
3432 return;
3433 }
3434
3435 if (fixP->fx_addsy == (symbolS *) NULL)
3436 fixP->fx_addnumber = value,
3437 fixP->fx_done = 1;
3438
3439 else if (fixP->fx_pcrel)
3440 fixP->fx_addnumber = fixP->fx_offset;
3441
3442 else
3443 {
3444 value = fixP->fx_offset;
3445 if (fixP->fx_subsy != (symbolS *) NULL)
3446 {
3447 if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
3448 value -= S_GET_VALUE (fixP->fx_subsy);
3449 else
3450 /* We don't actually support subtracting a symbol. */
3451 as_bad_where (fixP->fx_file, fixP->fx_line,
3452 _("expression too complex"));
3453 }
3454 fixP->fx_addnumber = value;
3455 }
3456
3457 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
3458 {
3459 int opindex;
3460 const struct v850_operand *operand;
3461 unsigned long insn;
3462 const char *errmsg = NULL;
3463
3464 opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
3465 operand = &v850_operands[opindex];
3466
3467 /* Fetch the instruction, insert the fully resolved operand
3468 value, and stuff the instruction back again.
3469
3470 Note the instruction has been stored in little endian
3471 format! */
3472 where = fixP->fx_frag->fr_literal + fixP->fx_where;
3473
3474 if (fixP->fx_size > 2)
3475 insn = bfd_getl32 ((unsigned char *) where);
3476 else
3477 insn = bfd_getl16 ((unsigned char *) where);
3478
3479 /* When inserting loop offets a backwards displacement
3480 is encoded as a positive value. */
3481 if (operand->flags & V850_INVERSE_PCREL)
3482 value = - value;
3483
3484 insn = v850_insert_operand (insn, operand, (offsetT) value,
3485 &errmsg);
3486 if (errmsg)
3487 as_warn_where (fixP->fx_file, fixP->fx_line, "%s", errmsg);
3488
3489 if (fixP->fx_size > 2)
3490 bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
3491 else
3492 bfd_putl16 ((bfd_vma) insn, (unsigned char *) where);
3493
3494 if (fixP->fx_done)
3495 /* Nothing else to do here. */
3496 return;
3497
3498 /* Determine a BFD reloc value based on the operand information.
3499 We are only prepared to turn a few of the operands into relocs. */
3500
3501 if (operand->default_reloc == BFD_RELOC_NONE)
3502 {
3503 as_bad_where (fixP->fx_file, fixP->fx_line,
3504 _("unresolved expression that must be resolved"));
3505 fixP->fx_done = 1;
3506 return;
3507 }
3508
3509 {
3510 fixP->fx_r_type = operand->default_reloc;
3511 if (operand->default_reloc == BFD_RELOC_V850_16_PCREL)
3512 {
3513 fixP->fx_where += 2;
3514 fixP->fx_size = 2;
3515 fixP->fx_addnumber += 2;
3516 }
3517 }
3518 }
3519 else if (fixP->fx_done)
3520 {
3521 /* We still have to insert the value into memory! */
3522 where = fixP->fx_frag->fr_literal + fixP->fx_where;
3523
3524 if (fixP->tc_fix_data != NULL
3525 && ((struct v850_operand *) fixP->tc_fix_data)->insert != NULL)
3526 {
3527 const char * message = NULL;
3528 struct v850_operand * operand = (struct v850_operand *) fixP->tc_fix_data;
3529 unsigned long insn;
3530
3531 /* The variable "where" currently points at the exact point inside
3532 the insn where we need to insert the value. But we need to
3533 extract the entire insn so we probably need to move "where"
3534 back a few bytes. */
3535
3536 if (fixP->fx_size == 2)
3537 where -= 2;
3538 else if (fixP->fx_size == 1)
3539 where -= 3;
3540
3541 insn = bfd_getl32 ((unsigned char *) where);
3542
3543 /* Use the operand's insertion procedure, if present, in order to
3544 make sure that the value is correctly stored in the insn. */
3545 insn = operand->insert (insn, (offsetT) value, & message);
3546 /* Ignore message even if it is set. */
3547
3548 bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
3549 }
3550 else
3551 {
3552 switch (fixP->fx_r_type)
3553 {
3554 case BFD_RELOC_V850_32_ABS:
3555 case BFD_RELOC_V850_32_PCREL:
3556 bfd_putl32 (value & 0xfffffffe, (unsigned char *) where);
3557 break;
3558
3559 case BFD_RELOC_32:
3560 bfd_putl32 (value, (unsigned char *) where);
3561 break;
3562
3563 case BFD_RELOC_V850_23:
3564 bfd_putl32 (((value & 0x7f) << 4) | ((value & 0x7fff80) << (16-7))
3565 | (bfd_getl32 (where) & ~((0x7f << 4) | (0xffff << 16))),
3566 (unsigned char *) where);
3567 break;
3568
3569 case BFD_RELOC_16:
3570 case BFD_RELOC_HI16:
3571 case BFD_RELOC_HI16_S:
3572 case BFD_RELOC_LO16:
3573 case BFD_RELOC_V850_ZDA_16_16_OFFSET:
3574 case BFD_RELOC_V850_SDA_16_16_OFFSET:
3575 case BFD_RELOC_V850_TDA_16_16_OFFSET:
3576 case BFD_RELOC_V850_CALLT_16_16_OFFSET:
3577 bfd_putl16 (value & 0xffff, (unsigned char *) where);
3578 break;
3579
3580 case BFD_RELOC_8:
3581 *where = value & 0xff;
3582 break;
3583
3584 case BFD_RELOC_V850_9_PCREL:
3585 bfd_putl16 (((value & 0x1f0) << 7) | ((value & 0x0e) << 3)
3586 | (bfd_getl16 (where) & ~((0x1f0 << 7) | (0x0e << 3))), where);
3587 break;
3588
3589 case BFD_RELOC_V850_17_PCREL:
3590 bfd_putl32 (((value & 0x10000) >> (16 - 4)) | ((value & 0xfffe) << 16)
3591 | (bfd_getl32 (where) & ~((0x10000 >> (16 - 4)) | (0xfffe << 16))), where);
3592 break;
3593
3594 case BFD_RELOC_V850_16_PCREL:
3595 bfd_putl16 ((-value & 0xfffe) | (bfd_getl16 (where + 2) & 0x0001),
3596 (unsigned char *) (where + 2));
3597 break;
3598
3599 case BFD_RELOC_V850_22_PCREL:
3600 bfd_putl32 (((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16)
3601 | (bfd_getl32 (where) & ~((0xfffe << 16) | (0x3f0000 >> 16))), where);
3602 break;
3603
3604 case BFD_RELOC_V850_16_S1:
3605 case BFD_RELOC_V850_LO16_S1:
3606 case BFD_RELOC_V850_ZDA_15_16_OFFSET:
3607 case BFD_RELOC_V850_SDA_15_16_OFFSET:
3608 bfd_putl16 (value & 0xfffe, (unsigned char *) where);
3609 break;
3610
3611 case BFD_RELOC_V850_16_SPLIT_OFFSET:
3612 case BFD_RELOC_V850_LO16_SPLIT_OFFSET:
3613 case BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET:
3614 case BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET:
3615 bfd_putl32 (((value << 16) & 0xfffe0000)
3616 | ((value << 5) & 0x20)
3617 | (bfd_getl32 (where) & ~0xfffe0020), where);
3618 break;
3619
3620 case BFD_RELOC_V850_TDA_6_8_OFFSET:
3621 *where = (*where & ~0x7e) | ((value >> 1) & 0x7e);
3622 break;
3623
3624 case BFD_RELOC_V850_TDA_7_8_OFFSET:
3625 *where = (*where & ~0x7f) | ((value >> 1) & 0x7f);
3626 break;
3627
3628 case BFD_RELOC_V850_TDA_7_7_OFFSET:
3629 *where = (*where & ~0x7f) | (value & 0x7f);
3630 break;
3631
3632 case BFD_RELOC_V850_TDA_4_5_OFFSET:
3633 *where = (*where & ~0xf) | ((value >> 1) & 0xf);
3634 break;
3635
3636 case BFD_RELOC_V850_TDA_4_4_OFFSET:
3637 *where = (*where & ~0xf) | (value & 0xf);
3638 break;
3639
3640 case BFD_RELOC_V850_CALLT_6_7_OFFSET:
3641 *where = (*where & ~0x3f) | (value & 0x3f);
3642 break;
3643
3644 default:
3645 abort ();
3646 }
3647 }
3648 }
3649 }
3650
3651 /* Parse a cons expression. We have to handle hi(), lo(), etc
3652 on the v850. */
3653
3654 bfd_reloc_code_real_type
parse_cons_expression_v850(expressionS * exp)3655 parse_cons_expression_v850 (expressionS *exp)
3656 {
3657 const char *errmsg;
3658 bfd_reloc_code_real_type r;
3659
3660 /* See if there's a reloc prefix like hi() we have to handle. */
3661 r = v850_reloc_prefix (NULL, &errmsg);
3662
3663 /* Do normal expression parsing. */
3664 expression (exp);
3665 return r;
3666 }
3667
3668 /* Create a fixup for a cons expression. If parse_cons_expression_v850
3669 found a reloc prefix, then we use that reloc, else we choose an
3670 appropriate one based on the size of the expression. */
3671
3672 void
cons_fix_new_v850(fragS * frag,int where,int size,expressionS * exp,bfd_reloc_code_real_type r)3673 cons_fix_new_v850 (fragS *frag,
3674 int where,
3675 int size,
3676 expressionS *exp,
3677 bfd_reloc_code_real_type r)
3678 {
3679 if (r == BFD_RELOC_NONE)
3680 {
3681 if (size == 4)
3682 r = BFD_RELOC_32;
3683 if (size == 2)
3684 r = BFD_RELOC_16;
3685 if (size == 1)
3686 r = BFD_RELOC_8;
3687 }
3688
3689 if (exp != NULL)
3690 fix_new_exp (frag, where, size, exp, 0, r);
3691 else
3692 fix_new (frag, where, size, NULL, 0, 0, r);
3693 }
3694
3695 bfd_boolean
v850_fix_adjustable(fixS * fixP)3696 v850_fix_adjustable (fixS *fixP)
3697 {
3698 if (fixP->fx_addsy == NULL)
3699 return 1;
3700
3701 /* Don't adjust function names. */
3702 if (S_IS_FUNCTION (fixP->fx_addsy))
3703 return 0;
3704
3705 /* We need the symbol name for the VTABLE entries. */
3706 if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
3707 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3708 return 0;
3709
3710 return 1;
3711 }
3712
3713 int
v850_force_relocation(struct fix * fixP)3714 v850_force_relocation (struct fix *fixP)
3715 {
3716 if (fixP->fx_r_type == BFD_RELOC_V850_LONGCALL
3717 || fixP->fx_r_type == BFD_RELOC_V850_LONGJUMP)
3718 return 1;
3719
3720 if (v850_relax
3721 && (fixP->fx_pcrel
3722 || fixP->fx_r_type == BFD_RELOC_V850_ALIGN
3723 || fixP->fx_r_type == BFD_RELOC_V850_9_PCREL
3724 || fixP->fx_r_type == BFD_RELOC_V850_16_PCREL
3725 || fixP->fx_r_type == BFD_RELOC_V850_17_PCREL
3726 || fixP->fx_r_type == BFD_RELOC_V850_22_PCREL
3727 || fixP->fx_r_type == BFD_RELOC_V850_32_PCREL
3728 || fixP->fx_r_type >= BFD_RELOC_UNUSED))
3729 return 1;
3730
3731 return generic_force_reloc (fixP);
3732 }
3733
3734 /* Create a v850 note section. */
3735 void
v850_md_end(void)3736 v850_md_end (void)
3737 {
3738 segT note_sec;
3739 segT orig_seg = now_seg;
3740 subsegT orig_subseg = now_subseg;
3741 enum v850_notes id;
3742
3743 note_sec = subseg_new (V850_NOTE_SECNAME, 0);
3744 bfd_set_section_flags (stdoutput, note_sec, SEC_HAS_CONTENTS | SEC_READONLY | SEC_MERGE);
3745 bfd_set_section_alignment (stdoutput, note_sec, 2);
3746
3747 /* Provide default values for all of the notes. */
3748 for (id = V850_NOTE_ALIGNMENT; id <= NUM_V850_NOTES; id++)
3749 {
3750 int val = 0;
3751 char * p;
3752
3753 /* Follow the standard note section layout:
3754 First write the length of the name string. */
3755 p = frag_more (4);
3756 md_number_to_chars (p, 4, 4);
3757
3758 /* Next comes the length of the "descriptor", i.e., the actual data. */
3759 p = frag_more (4);
3760 md_number_to_chars (p, 4, 4);
3761
3762 /* Write the note type. */
3763 p = frag_more (4);
3764 md_number_to_chars (p, (valueT) id, 4);
3765
3766 /* Write the name field. */
3767 p = frag_more (4);
3768 memcpy (p, V850_NOTE_NAME, 4);
3769
3770 /* Finally, write the descriptor. */
3771 p = frag_more (4);
3772 switch (id)
3773 {
3774 case V850_NOTE_ALIGNMENT:
3775 val = v850_data_8 ? EF_RH850_DATA_ALIGN8 : EF_RH850_DATA_ALIGN4;
3776 break;
3777
3778 case V850_NOTE_DATA_SIZE:
3779 /* GCC does not currently support an option
3780 for 32-bit doubles with the V850 backend. */
3781 val = EF_RH850_DOUBLE64;
3782 break;
3783
3784 case V850_NOTE_FPU_INFO:
3785 if (! soft_float)
3786 switch (machine)
3787 {
3788 case bfd_mach_v850e3v5: val = EF_RH850_FPU30; break;
3789 case bfd_mach_v850e2v3: val = EF_RH850_FPU20; break;
3790 default: break;
3791 }
3792 break;
3793
3794 default:
3795 break;
3796 }
3797 md_number_to_chars (p, val, 4);
3798 }
3799
3800 /* Paranoia - we probably do not need this. */
3801 subseg_set (orig_seg, orig_subseg);
3802 }
3803