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