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