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