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