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