]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-bfin.c
Remove duplicate definitions of the md_atof() function
[thirdparty/binutils-gdb.git] / gas / config / tc-bfin.c
CommitLineData
07c1b327 1/* tc-bfin.c -- Assembler for the ADI Blackfin.
ec2655a6 2 Copyright 2005, 2006, 2007
07c1b327
CM
3 Free Software Foundation, Inc.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
ec2655a6 9 the Free Software Foundation; either version 3, or (at your option)
07c1b327
CM
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
21
22#include "as.h"
23#include "struc-symbol.h"
07c1b327
CM
24#include "bfin-defs.h"
25#include "obstack.h"
26#include "safe-ctype.h"
27#ifdef OBJ_ELF
28#include "dwarf2dbg.h"
29#endif
1ac4baed
BS
30#include "libbfd.h"
31#include "elf/common.h"
32#include "elf/bfin.h"
07c1b327
CM
33
34extern int yyparse (void);
35struct yy_buffer_state;
36typedef struct yy_buffer_state *YY_BUFFER_STATE;
37extern YY_BUFFER_STATE yy_scan_string (const char *yy_str);
38extern void yy_delete_buffer (YY_BUFFER_STATE b);
39static parse_state parse (char *line);
40static void bfin_s_bss PARAMS ((int));
9ba4c445 41static int md_chars_to_number PARAMS ((char *, int));
07c1b327
CM
42
43/* Global variables. */
44struct bfin_insn *insn;
45int last_insn_size;
46
47extern struct obstack mempool;
48FILE *errorf;
49
1ac4baed
BS
50/* Flags to set in the elf header */
51#define DEFAULT_FLAGS 0
52
53static flagword bfin_flags = DEFAULT_FLAGS;
54static const char *bfin_pic_flag = (const char *)0;
55
07c1b327
CM
56/* Registers list. */
57struct bfin_reg_entry
58{
59 const char *name;
60 int number;
61};
62
63static const struct bfin_reg_entry bfin_reg_info[] = {
64 {"R0.L", REG_RL0},
65 {"R1.L", REG_RL1},
66 {"R2.L", REG_RL2},
67 {"R3.L", REG_RL3},
68 {"R4.L", REG_RL4},
69 {"R5.L", REG_RL5},
70 {"R6.L", REG_RL6},
71 {"R7.L", REG_RL7},
72 {"R0.H", REG_RH0},
73 {"R1.H", REG_RH1},
74 {"R2.H", REG_RH2},
75 {"R3.H", REG_RH3},
76 {"R4.H", REG_RH4},
77 {"R5.H", REG_RH5},
78 {"R6.H", REG_RH6},
79 {"R7.H", REG_RH7},
80 {"R0", REG_R0},
81 {"R1", REG_R1},
82 {"R2", REG_R2},
83 {"R3", REG_R3},
84 {"R4", REG_R4},
85 {"R5", REG_R5},
86 {"R6", REG_R6},
87 {"R7", REG_R7},
88 {"P0", REG_P0},
89 {"P0.H", REG_P0},
90 {"P0.L", REG_P0},
91 {"P1", REG_P1},
92 {"P1.H", REG_P1},
93 {"P1.L", REG_P1},
94 {"P2", REG_P2},
95 {"P2.H", REG_P2},
96 {"P2.L", REG_P2},
97 {"P3", REG_P3},
98 {"P3.H", REG_P3},
99 {"P3.L", REG_P3},
100 {"P4", REG_P4},
101 {"P4.H", REG_P4},
102 {"P4.L", REG_P4},
103 {"P5", REG_P5},
104 {"P5.H", REG_P5},
105 {"P5.L", REG_P5},
106 {"SP", REG_SP},
107 {"SP.L", REG_SP},
108 {"SP.H", REG_SP},
109 {"FP", REG_FP},
110 {"FP.L", REG_FP},
111 {"FP.H", REG_FP},
112 {"A0x", REG_A0x},
113 {"A1x", REG_A1x},
114 {"A0w", REG_A0w},
115 {"A1w", REG_A1w},
116 {"A0.x", REG_A0x},
117 {"A1.x", REG_A1x},
118 {"A0.w", REG_A0w},
119 {"A1.w", REG_A1w},
120 {"A0", REG_A0},
121 {"A0.L", REG_A0},
122 {"A0.H", REG_A0},
123 {"A1", REG_A1},
124 {"A1.L", REG_A1},
125 {"A1.H", REG_A1},
126 {"I0", REG_I0},
127 {"I0.L", REG_I0},
128 {"I0.H", REG_I0},
129 {"I1", REG_I1},
130 {"I1.L", REG_I1},
131 {"I1.H", REG_I1},
132 {"I2", REG_I2},
133 {"I2.L", REG_I2},
134 {"I2.H", REG_I2},
135 {"I3", REG_I3},
136 {"I3.L", REG_I3},
137 {"I3.H", REG_I3},
138 {"M0", REG_M0},
139 {"M0.H", REG_M0},
140 {"M0.L", REG_M0},
141 {"M1", REG_M1},
142 {"M1.H", REG_M1},
143 {"M1.L", REG_M1},
144 {"M2", REG_M2},
145 {"M2.H", REG_M2},
146 {"M2.L", REG_M2},
147 {"M3", REG_M3},
148 {"M3.H", REG_M3},
149 {"M3.L", REG_M3},
150 {"B0", REG_B0},
151 {"B0.H", REG_B0},
152 {"B0.L", REG_B0},
153 {"B1", REG_B1},
154 {"B1.H", REG_B1},
155 {"B1.L", REG_B1},
156 {"B2", REG_B2},
157 {"B2.H", REG_B2},
158 {"B2.L", REG_B2},
159 {"B3", REG_B3},
160 {"B3.H", REG_B3},
161 {"B3.L", REG_B3},
162 {"L0", REG_L0},
163 {"L0.H", REG_L0},
164 {"L0.L", REG_L0},
165 {"L1", REG_L1},
166 {"L1.H", REG_L1},
167 {"L1.L", REG_L1},
168 {"L2", REG_L2},
169 {"L2.H", REG_L2},
170 {"L2.L", REG_L2},
171 {"L3", REG_L3},
172 {"L3.H", REG_L3},
173 {"L3.L", REG_L3},
174 {"AZ", S_AZ},
175 {"AN", S_AN},
176 {"AC0", S_AC0},
177 {"AC1", S_AC1},
178 {"AV0", S_AV0},
179 {"AV0S", S_AV0S},
180 {"AV1", S_AV1},
181 {"AV1S", S_AV1S},
182 {"AQ", S_AQ},
183 {"V", S_V},
184 {"VS", S_VS},
185 {"sftreset", REG_sftreset},
186 {"omode", REG_omode},
187 {"excause", REG_excause},
188 {"emucause", REG_emucause},
189 {"idle_req", REG_idle_req},
190 {"hwerrcause", REG_hwerrcause},
191 {"CC", REG_CC},
192 {"LC0", REG_LC0},
193 {"LC1", REG_LC1},
194 {"ASTAT", REG_ASTAT},
195 {"RETS", REG_RETS},
196 {"LT0", REG_LT0},
197 {"LB0", REG_LB0},
198 {"LT1", REG_LT1},
199 {"LB1", REG_LB1},
200 {"CYCLES", REG_CYCLES},
201 {"CYCLES2", REG_CYCLES2},
202 {"USP", REG_USP},
203 {"SEQSTAT", REG_SEQSTAT},
204 {"SYSCFG", REG_SYSCFG},
205 {"RETI", REG_RETI},
206 {"RETX", REG_RETX},
207 {"RETN", REG_RETN},
208 {"RETE", REG_RETE},
209 {"EMUDAT", REG_EMUDAT},
210 {0, 0}
211};
212
1ac4baed
BS
213/* Blackfin specific function to handle FD-PIC pointer initializations. */
214
215static void
216bfin_pic_ptr (int nbytes)
217{
218 expressionS exp;
219 char *p;
220
221 if (nbytes != 4)
222 abort ();
223
224#ifdef md_flush_pending_output
225 md_flush_pending_output ();
226#endif
227
228 if (is_it_end_of_statement ())
229 {
230 demand_empty_rest_of_line ();
231 return;
232 }
233
234#ifdef md_cons_align
235 md_cons_align (nbytes);
236#endif
237
238 do
239 {
240 bfd_reloc_code_real_type reloc_type = BFD_RELOC_BFIN_FUNCDESC;
241
242 if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0)
243 {
244 input_line_pointer += 9;
245 expression (&exp);
246 if (*input_line_pointer == ')')
247 input_line_pointer++;
248 else
bd3ba5d1 249 as_bad (_("missing ')'"));
1ac4baed
BS
250 }
251 else
252 error ("missing funcdesc in picptr");
253
254 p = frag_more (4);
255 memset (p, 0, 4);
256 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
257 reloc_type);
258 }
259 while (*input_line_pointer++ == ',');
260
261 input_line_pointer--; /* Put terminator back into stream. */
262 demand_empty_rest_of_line ();
263}
264
265static void
266bfin_s_bss (int ignore ATTRIBUTE_UNUSED)
267{
268 register int temp;
269
270 temp = get_absolute_expression ();
271 subseg_set (bss_section, (subsegT) temp);
272 demand_empty_rest_of_line ();
273}
07c1b327
CM
274
275const pseudo_typeS md_pseudo_table[] = {
276 {"align", s_align_bytes, 0},
277 {"byte2", cons, 2},
278 {"byte4", cons, 4},
1ac4baed 279 {"picptr", bfin_pic_ptr, 4},
07c1b327
CM
280 {"code", obj_elf_section, 0},
281 {"db", cons, 1},
282 {"dd", cons, 4},
283 {"dw", cons, 2},
284 {"p", s_ignore, 0},
285 {"pdata", s_ignore, 0},
286 {"var", s_ignore, 0},
287 {"bss", bfin_s_bss, 0},
288 {0, 0, 0}
289};
290
07c1b327
CM
291/* Characters that are used to denote comments and line separators. */
292const char comment_chars[] = "";
293const char line_comment_chars[] = "#";
294const char line_separator_chars[] = ";";
295
296/* Characters that can be used to separate the mantissa from the
297 exponent in floating point numbers. */
298const char EXP_CHARS[] = "eE";
299
300/* Characters that mean this number is a floating point constant.
301 As in 0f12.456 or 0d1.2345e12. */
302const char FLT_CHARS[] = "fFdDxX";
303
304/* Define bfin-specific command-line options (there are none). */
305const char *md_shortopts = "";
306
1ac4baed
BS
307#define OPTION_FDPIC (OPTION_MD_BASE)
308
309struct option md_longopts[] =
310{
311 { "mfdpic", no_argument, NULL, OPTION_FDPIC },
312 { NULL, no_argument, NULL, 0 },
07c1b327 313};
1ac4baed 314
07c1b327
CM
315size_t md_longopts_size = sizeof (md_longopts);
316
317
318int
319md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
320{
1ac4baed
BS
321 switch (c)
322 {
323 default:
324 return 0;
325
326 case OPTION_FDPIC:
327 bfin_flags |= EF_BFIN_FDPIC;
328 bfin_pic_flag = "-mfdpic";
329 break;
330 }
331
332 return 1;
07c1b327
CM
333}
334
335void
336md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
337{
338 fprintf (stream, _(" BFIN specific command line options:\n"));
339}
340
341/* Perform machine-specific initializations. */
342void
343md_begin ()
344{
1ac4baed
BS
345 /* Set the ELF flags if desired. */
346 if (bfin_flags)
347 bfd_set_private_flags (stdoutput, bfin_flags);
348
07c1b327
CM
349 /* Set the default machine type. */
350 if (!bfd_set_arch_mach (stdoutput, bfd_arch_bfin, 0))
bd3ba5d1 351 as_warn (_("Could not set architecture and machine."));
07c1b327
CM
352
353 /* Ensure that lines can begin with '(', for multiple
354 register stack pops. */
9f8e671b 355 lex_type ['('] = LEX_BEGIN_NAME;
07c1b327
CM
356
357#ifdef OBJ_ELF
358 record_alignment (text_section, 2);
359 record_alignment (data_section, 2);
360 record_alignment (bss_section, 2);
361#endif
362
363 errorf = stderr;
364 obstack_init (&mempool);
365
366#ifdef DEBUG
367 extern int debug_codeselection;
368 debug_codeselection = 1;
369#endif
370
371 last_insn_size = 0;
372}
373
374/* Perform the main parsing, and assembly of the input here. Also,
375 call the required routines for alignment and fixups here.
376 This is called for every line that contains real assembly code. */
377
378void
379md_assemble (char *line)
380{
381 char *toP = 0;
382 extern char *current_inputline;
383 int size, insn_size;
384 struct bfin_insn *tmp_insn;
385 size_t len;
386 static size_t buffer_len = 0;
387 parse_state state;
388
389 len = strlen (line);
390 if (len + 2 > buffer_len)
391 {
392 if (buffer_len > 0)
393 free (current_inputline);
394 buffer_len = len + 40;
395 current_inputline = xmalloc (buffer_len);
396 }
397 memcpy (current_inputline, line, len);
398 current_inputline[len] = ';';
399 current_inputline[len + 1] = '\0';
400
401 state = parse (current_inputline);
402 if (state == NO_INSN_GENERATED)
403 return;
404
405 for (insn_size = 0, tmp_insn = insn; tmp_insn; tmp_insn = tmp_insn->next)
406 if (!tmp_insn->reloc || !tmp_insn->exp->symbol)
407 insn_size += 2;
408
409 if (insn_size)
410 toP = frag_more (insn_size);
411
412 last_insn_size = insn_size;
413
414#ifdef DEBUG
415 printf ("INS:");
416#endif
417 while (insn)
418 {
419 if (insn->reloc && insn->exp->symbol)
420 {
421 char *prev_toP = toP - 2;
422 switch (insn->reloc)
423 {
424 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
425 case BFD_RELOC_24_PCREL:
426 case BFD_RELOC_BFIN_16_LOW:
427 case BFD_RELOC_BFIN_16_HIGH:
428 size = 4;
429 break;
430 default:
431 size = 2;
432 }
433
434 /* Following if condition checks for the arithmetic relocations.
435 If the case then it doesn't required to generate the code.
436 It has been assumed that, their ID will be contiguous. */
437 if ((BFD_ARELOC_BFIN_PUSH <= insn->reloc
438 && BFD_ARELOC_BFIN_COMP >= insn->reloc)
439 || insn->reloc == BFD_RELOC_BFIN_16_IMM)
440 {
441 size = 2;
442 }
443 if (insn->reloc == BFD_ARELOC_BFIN_CONST
444 || insn->reloc == BFD_ARELOC_BFIN_PUSH)
445 size = 4;
446
447 fix_new (frag_now,
448 (prev_toP - frag_now->fr_literal),
449 size, insn->exp->symbol, insn->exp->value,
450 insn->pcrel, insn->reloc);
451 }
452 else
453 {
454 md_number_to_chars (toP, insn->value, 2);
455 toP += 2;
456 }
457
458#ifdef DEBUG
459 printf (" reloc :");
460 printf (" %02x%02x", ((unsigned char *) &insn->value)[0],
461 ((unsigned char *) &insn->value)[1]);
462 printf ("\n");
463#endif
464 insn = insn->next;
465 }
466#ifdef OBJ_ELF
467 dwarf2_emit_insn (insn_size);
468#endif
469}
470
471/* Parse one line of instructions, and generate opcode for it.
472 To parse the line, YACC and LEX are used, because the instruction set
473 syntax doesn't confirm to the AT&T assembly syntax.
474 To call a YACC & LEX generated parser, we must provide the input via
475 a FILE stream, otherwise stdin is used by default. Below the input
476 to the function will be put into a temporary file, then the generated
477 parser uses the temporary file for parsing. */
478
479static parse_state
480parse (char *line)
481{
482 parse_state state;
483 YY_BUFFER_STATE buffstate;
484
485 buffstate = yy_scan_string (line);
486
487 /* our lex requires setting the start state to keyword
488 every line as the first word may be a keyword.
489 Fixes a bug where we could not have keywords as labels. */
490 set_start_state ();
491
492 /* Call yyparse here. */
493 state = yyparse ();
494 if (state == SEMANTIC_ERROR)
495 {
bd3ba5d1 496 as_bad (_("Parse failed."));
07c1b327
CM
497 insn = 0;
498 }
499
500 yy_delete_buffer (buffstate);
501 return state;
502}
503
504/* We need to handle various expressions properly.
505 Such as, [SP--] = 34, concerned by md_assemble(). */
506
507void
508md_operand (expressionS * expressionP)
509{
510 if (*input_line_pointer == '[')
511 {
512 as_tsktsk ("We found a '['!");
513 input_line_pointer++;
514 expression (expressionP);
515 }
516}
517
518/* Handle undefined symbols. */
519symbolS *
520md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
521{
522 return (symbolS *) 0;
523}
524
525int
526md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
527 segT segment ATTRIBUTE_UNUSED)
528{
529 return 0;
530}
531
532/* Convert from target byte order to host byte order. */
533
534static int
9ba4c445 535md_chars_to_number (char *val, int n)
07c1b327
CM
536{
537 int retval;
538
539 for (retval = 0; n--;)
540 {
541 retval <<= 8;
542 retval |= val[n];
543 }
544 return retval;
545}
546
547void
548md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
549{
550 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
551
552 long value = *valueP;
553 long newval;
554
555 switch (fixP->fx_r_type)
556 {
557 case BFD_RELOC_BFIN_GOT:
1ac4baed
BS
558 case BFD_RELOC_BFIN_GOT17M4:
559 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
07c1b327
CM
560 fixP->fx_no_overflow = 1;
561 newval = md_chars_to_number (where, 2);
562 newval |= 0x0 & 0x7f;
563 md_number_to_chars (where, newval, 2);
564 break;
565
566 case BFD_RELOC_BFIN_10_PCREL:
567 if (!value)
568 break;
569 if (value < -1024 || value > 1022)
570 as_bad_where (fixP->fx_file, fixP->fx_line,
bd3ba5d1 571 _("pcrel too far BFD_RELOC_BFIN_10"));
07c1b327
CM
572
573 /* 11 bit offset even numbered, so we remove right bit. */
574 value = value >> 1;
575 newval = md_chars_to_number (where, 2);
576 newval |= value & 0x03ff;
577 md_number_to_chars (where, newval, 2);
578 break;
579
580 case BFD_RELOC_BFIN_12_PCREL_JUMP:
581 case BFD_RELOC_BFIN_12_PCREL_JUMP_S:
582 case BFD_RELOC_12_PCREL:
583 if (!value)
584 break;
585
586 if (value < -4096 || value > 4094)
bd3ba5d1 587 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_12"));
07c1b327
CM
588 /* 13 bit offset even numbered, so we remove right bit. */
589 value = value >> 1;
590 newval = md_chars_to_number (where, 2);
591 newval |= value & 0xfff;
592 md_number_to_chars (where, newval, 2);
593 break;
594
595 case BFD_RELOC_BFIN_16_LOW:
596 case BFD_RELOC_BFIN_16_HIGH:
597 fixP->fx_done = FALSE;
598 break;
599
600 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
601 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
602 case BFD_RELOC_24_PCREL:
603 if (!value)
604 break;
605
606 if (value < -16777216 || value > 16777214)
bd3ba5d1 607 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_24"));
07c1b327
CM
608
609 /* 25 bit offset even numbered, so we remove right bit. */
610 value = value >> 1;
611 value++;
612
613 md_number_to_chars (where - 2, value >> 16, 1);
614 md_number_to_chars (where, value, 1);
615 md_number_to_chars (where + 1, value >> 8, 1);
616 break;
617
618 case BFD_RELOC_BFIN_5_PCREL: /* LSETUP (a, b) : "a" */
619 if (!value)
620 break;
621 if (value < 4 || value > 30)
bd3ba5d1 622 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_5"));
07c1b327
CM
623 value = value >> 1;
624 newval = md_chars_to_number (where, 1);
625 newval = (newval & 0xf0) | (value & 0xf);
626 md_number_to_chars (where, newval, 1);
627 break;
628
629 case BFD_RELOC_BFIN_11_PCREL: /* LSETUP (a, b) : "b" */
630 if (!value)
631 break;
632 value += 2;
633 if (value < 4 || value > 2046)
bd3ba5d1 634 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
07c1b327
CM
635 /* 11 bit unsigned even, so we remove right bit. */
636 value = value >> 1;
637 newval = md_chars_to_number (where, 2);
638 newval |= value & 0x03ff;
639 md_number_to_chars (where, newval, 2);
640 break;
641
642 case BFD_RELOC_8:
643 if (value < -0x80 || value >= 0x7f)
bd3ba5d1 644 as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_8"));
07c1b327
CM
645 md_number_to_chars (where, value, 1);
646 break;
647
648 case BFD_RELOC_BFIN_16_IMM:
649 case BFD_RELOC_16:
650 if (value < -0x8000 || value >= 0x7fff)
bd3ba5d1 651 as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_16"));
07c1b327
CM
652 md_number_to_chars (where, value, 2);
653 break;
654
655 case BFD_RELOC_32:
656 md_number_to_chars (where, value, 4);
657 break;
658
659 case BFD_RELOC_BFIN_PLTPC:
660 md_number_to_chars (where, value, 2);
661 break;
662
1ac4baed 663 case BFD_RELOC_BFIN_FUNCDESC:
07c1b327
CM
664 case BFD_RELOC_VTABLE_INHERIT:
665 case BFD_RELOC_VTABLE_ENTRY:
666 fixP->fx_done = FALSE;
667 break;
668
669 default:
670 if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type))
671 {
672 fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type);
673 return;
674 }
675 }
676
677 if (!fixP->fx_addsy)
678 fixP->fx_done = TRUE;
679
680}
681
682/* Round up a section size to the appropriate boundary. */
683valueT
684md_section_align (segment, size)
685 segT segment;
686 valueT size;
687{
688 int boundary = bfd_get_section_alignment (stdoutput, segment);
689 return ((size + (1 << boundary) - 1) & (-1 << boundary));
690}
691
692
07c1b327 693char *
499ac353 694md_atof (int type, char * litP, int * sizeP)
07c1b327 695{
499ac353 696 return ieee_md_atof (type, litP, sizeP, FALSE);
07c1b327
CM
697}
698
699
700/* If while processing a fixup, a reloc really needs to be created
701 then it is done here. */
702
703arelent *
704tc_gen_reloc (seg, fixp)
705 asection *seg ATTRIBUTE_UNUSED;
706 fixS *fixp;
707{
708 arelent *reloc;
709
710 reloc = (arelent *) xmalloc (sizeof (arelent));
711 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
712 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
713 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
714
715 reloc->addend = fixp->fx_offset;
716 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
717
718 if (reloc->howto == (reloc_howto_type *) NULL)
719 {
720 as_bad_where (fixp->fx_file, fixp->fx_line,
721 /* xgettext:c-format. */
722 _("reloc %d not supported by object file format"),
723 (int) fixp->fx_r_type);
724
725 xfree (reloc);
726
727 return NULL;
728 }
729
730 return reloc;
731}
732
733/* The location from which a PC relative jump should be calculated,
734 given a PC relative reloc. */
735
736long
737md_pcrel_from_section (fixP, sec)
738 fixS *fixP;
739 segT sec;
740{
741 if (fixP->fx_addsy != (symbolS *) NULL
742 && (!S_IS_DEFINED (fixP->fx_addsy)
743 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
744 {
745 /* The symbol is undefined (or is defined but not in this section).
746 Let the linker figure it out. */
747 return 0;
748 }
749 return fixP->fx_frag->fr_address + fixP->fx_where;
750}
751
752/* Return true if the fix can be handled by GAS, false if it must
753 be passed through to the linker. */
754
755bfd_boolean
756bfin_fix_adjustable (fixS *fixP)
757{
758 switch (fixP->fx_r_type)
759 {
760 /* Adjust_reloc_syms doesn't know about the GOT. */
1ac4baed
BS
761 case BFD_RELOC_BFIN_GOT:
762 case BFD_RELOC_BFIN_GOT17M4:
763 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
764 case BFD_RELOC_BFIN_PLTPC:
07c1b327
CM
765 /* We need the symbol name for the VTABLE entries. */
766 case BFD_RELOC_VTABLE_INHERIT:
767 case BFD_RELOC_VTABLE_ENTRY:
768 return 0;
769
770 default:
771 return 1;
772 }
773}
774
775
776/* Handle the LOOP_BEGIN and LOOP_END statements.
777 Parse the Loop_Begin/Loop_End and create a label. */
778void
779bfin_start_line_hook ()
780{
781 bfd_boolean maybe_begin = FALSE;
782 bfd_boolean maybe_end = FALSE;
783
784 char *c1, *label_name;
785 symbolS *line_label;
786 char *c = input_line_pointer;
8b64503a 787 int cr_num = 0;
07c1b327
CM
788
789 while (ISSPACE (*c))
8b64503a
JZ
790 {
791 if (*c == '\n')
792 cr_num++;
793 c++;
794 }
07c1b327 795
07c1b327
CM
796 /* Look for Loop_Begin or Loop_End statements. */
797
798 if (*c != 'L' && *c != 'l')
799 return;
800
801 c++;
802 if (*c != 'O' && *c != 'o')
803 return;
804
805 c++;
806 if (*c != 'O' && *c != 'o')
807 return;
808
809 c++;
810 if (*c != 'P' && *c != 'p')
811 return;
812
813 c++;
814 if (*c != '_')
815 return;
816
817 c++;
818 if (*c == 'E' || *c == 'e')
819 maybe_end = TRUE;
820 else if (*c == 'B' || *c == 'b')
821 maybe_begin = TRUE;
822 else
823 return;
824
825 if (maybe_end)
826 {
827 c++;
828 if (*c != 'N' && *c != 'n')
829 return;
830
831 c++;
832 if (*c != 'D' && *c != 'd')
833 return;
834 }
835
836 if (maybe_begin)
837 {
838 c++;
839 if (*c != 'E' && *c != 'e')
840 return;
841
842 c++;
843 if (*c != 'G' && *c != 'g')
844 return;
845
846 c++;
847 if (*c != 'I' && *c != 'i')
848 return;
849
850 c++;
851 if (*c != 'N' && *c != 'n')
852 return;
853 }
854
855 c++;
856 while (ISSPACE (*c)) c++;
857 c1 = c;
858 while (ISALPHA (*c) || ISDIGIT (*c) || *c == '_') c++;
859
8b64503a
JZ
860 if (input_line_pointer[-1] == '\n')
861 bump_line_counters ();
862
863 while (cr_num--)
864 bump_line_counters ();
865
07c1b327
CM
866 input_line_pointer = c;
867 if (maybe_end)
868 {
869 label_name = (char *) xmalloc ((c - c1) + strlen ("__END") + 1);
870 label_name[0] = 0;
871 strncat (label_name, c1, c-c1);
872 strcat (label_name, "__END");
873 }
874 else /* maybe_begin. */
875 {
876 label_name = (char *) xmalloc ((c - c1) + strlen ("__BEGIN") + 1);
877 label_name[0] = 0;
878 strncat (label_name, c1, c-c1);
879 strcat (label_name, "__BEGIN");
880 }
881
882 line_label = colon (label_name);
883
884 /* Loop_End follows the last instruction in the loop.
885 Adjust label address. */
886 if (maybe_end)
887 line_label->sy_value.X_add_number -= last_insn_size;
888
889}
890
891/* Special extra functions that help bfin-parse.y perform its job. */
892
07c1b327 893#include <assert.h>
07c1b327
CM
894
895struct obstack mempool;
896
897INSTR_T
898conscode (INSTR_T head, INSTR_T tail)
899{
900 if (!head)
901 return tail;
902 head->next = tail;
903 return head;
904}
905
906INSTR_T
907conctcode (INSTR_T head, INSTR_T tail)
908{
909 INSTR_T temp = (head);
910 if (!head)
911 return tail;
912 while (temp->next)
913 temp = temp->next;
914 temp->next = tail;
915
916 return head;
917}
918
919INSTR_T
920note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
921{
922 /* Assert that the symbol is not an operator. */
923 assert (symbol->type == Expr_Node_Reloc);
924
925 return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
926
927}
928
929INSTR_T
930note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
931{
932 code->reloc = reloc;
933 code->exp = mkexpr (0, symbol_find_or_make (symbol));
934 code->pcrel = pcrel;
935 return code;
936}
937
938INSTR_T
939note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
940{
941 code->reloc = reloc;
942 code->exp = mkexpr (value, symbol_find_or_make (symbol));
943 code->pcrel = pcrel;
944 return code;
945}
946
947INSTR_T
948gencode (unsigned long x)
949{
950 INSTR_T cell = (INSTR_T) obstack_alloc (&mempool, sizeof (struct bfin_insn));
951 memset (cell, 0, sizeof (struct bfin_insn));
952 cell->value = (x);
953 return cell;
954}
955
956int reloc;
957int ninsns;
958int count_insns;
959
960static void *
961allocate (int n)
962{
963 return (void *) obstack_alloc (&mempool, n);
964}
965
966Expr_Node *
967Expr_Node_Create (Expr_Node_Type type,
968 Expr_Node_Value value,
969 Expr_Node *Left_Child,
970 Expr_Node *Right_Child)
971{
972
973
974 Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node));
975 node->type = type;
976 node->value = value;
977 node->Left_Child = Left_Child;
978 node->Right_Child = Right_Child;
979 return node;
980}
981
982static const char *con = ".__constant";
983static const char *op = ".__operator";
984static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
985INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
986
987INSTR_T
988Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
989{
990 /* Top level reloction expression generator VDSP style.
991 If the relocation is just by itself, generate one item
992 else generate this convoluted expression. */
993
994 INSTR_T note = NULL_CODE;
995 INSTR_T note1 = NULL_CODE;
996 int pcrel = 1; /* Is the parent reloc pcrelative?
997 This calculation here and HOWTO should match. */
998
999 if (parent_reloc)
1000 {
1001 /* If it's 32 bit quantity then 16bit code needs to be added. */
1002 int value = 0;
1003
1004 if (head->type == Expr_Node_Constant)
1005 {
1006 /* If note1 is not null code, we have to generate a right
1007 aligned value for the constant. Otherwise the reloc is
1008 a part of the basic command and the yacc file
1009 generates this. */
1010 value = head->value.i_value;
1011 }
1012 switch (parent_reloc)
1013 {
708587a4 1014 /* Some relocations will need to allocate extra words. */
07c1b327
CM
1015 case BFD_RELOC_BFIN_16_IMM:
1016 case BFD_RELOC_BFIN_16_LOW:
1017 case BFD_RELOC_BFIN_16_HIGH:
1018 note1 = conscode (gencode (value), NULL_CODE);
1019 pcrel = 0;
1020 break;
1021 case BFD_RELOC_BFIN_PLTPC:
1022 note1 = conscode (gencode (value), NULL_CODE);
1023 pcrel = 0;
1024 break;
1025 case BFD_RELOC_16:
1026 case BFD_RELOC_BFIN_GOT:
1ac4baed
BS
1027 case BFD_RELOC_BFIN_GOT17M4:
1028 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
07c1b327
CM
1029 note1 = conscode (gencode (value), NULL_CODE);
1030 pcrel = 0;
1031 break;
1032 case BFD_RELOC_24_PCREL:
1033 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
1034 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
1035 /* These offsets are even numbered pcrel. */
1036 note1 = conscode (gencode (value >> 1), NULL_CODE);
1037 break;
1038 default:
1039 note1 = NULL_CODE;
1040 }
1041 }
1042 if (head->type == Expr_Node_Constant)
1043 note = note1;
1044 else if (head->type == Expr_Node_Reloc)
1045 {
1046 note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
1047 if (note1 != NULL_CODE)
1048 note = conscode (note1, note);
1049 }
beb6bfe8
BS
1050 else if (head->type == Expr_Node_Binop
1051 && (head->value.op_value == Expr_Op_Type_Add
1052 || head->value.op_value == Expr_Op_Type_Sub)
1053 && head->Left_Child->type == Expr_Node_Reloc
1054 && head->Right_Child->type == Expr_Node_Constant)
1055 {
1056 int val = head->Right_Child->value.i_value;
1057 if (head->value.op_value == Expr_Op_Type_Sub)
1058 val = -val;
1059 note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value,
1060 parent_reloc, val, 0),
1061 NULL_CODE);
1062 if (note1 != NULL_CODE)
1063 note = conscode (note1, note);
1064 }
07c1b327
CM
1065 else
1066 {
1067 /* Call the recursive function. */
1068 note = note_reloc1 (gencode (0), op, parent_reloc, pcrel);
1069 if (note1 != NULL_CODE)
1070 note = conscode (note1, note);
1071 note = conctcode (Expr_Node_Gen_Reloc_R (head), note);
1072 }
1073 return note;
1074}
1075
1076static INSTR_T
1077Expr_Node_Gen_Reloc_R (Expr_Node * head)
1078{
1079
1080 INSTR_T note = 0;
1081 INSTR_T note1 = 0;
1082
1083 switch (head->type)
1084 {
1085 case Expr_Node_Constant:
1086 note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE);
1087 break;
1088 case Expr_Node_Reloc:
1089 note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE);
1090 break;
1091 case Expr_Node_Binop:
1092 note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child));
1093 switch (head->value.op_value)
1094 {
1095 case Expr_Op_Type_Add:
1096 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE));
1097 break;
1098 case Expr_Op_Type_Sub:
1099 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE));
1100 break;
1101 case Expr_Op_Type_Mult:
1102 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE));
1103 break;
1104 case Expr_Op_Type_Div:
1105 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE));
1106 break;
1107 case Expr_Op_Type_Mod:
1108 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE));
1109 break;
1110 case Expr_Op_Type_Lshift:
1111 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE));
1112 break;
1113 case Expr_Op_Type_Rshift:
1114 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE));
1115 break;
1116 case Expr_Op_Type_BAND:
1117 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE));
1118 break;
1119 case Expr_Op_Type_BOR:
1120 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE));
1121 break;
1122 case Expr_Op_Type_BXOR:
1123 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE));
1124 break;
1125 case Expr_Op_Type_LAND:
1126 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE));
1127 break;
1128 case Expr_Op_Type_LOR:
1129 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE));
1130 break;
1131 default:
df3e8017 1132 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
07c1b327
CM
1133
1134
1135 }
1136 break;
1137 case Expr_Node_Unop:
1138 note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE);
1139 switch (head->value.op_value)
1140 {
1141 case Expr_Op_Type_NEG:
1142 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE));
1143 break;
1144 case Expr_Op_Type_COMP:
1145 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE));
1146 break;
1147 default:
df3e8017 1148 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
07c1b327
CM
1149 }
1150 break;
1151 default:
1152 fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1153 }
1154 return note;
1155}
1156
1157
1158/* Blackfin opcode generation. */
1159
1160/* These functions are called by the generated parser
1161 (from bfin-parse.y), the register type classification
1162 happens in bfin-lex.l. */
1163
1164#include "bfin-aux.h"
1165#include "opcode/bfin.h"
1166
1167#define INIT(t) t c_code = init_##t
1168#define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1169#define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1170
1171#define HI(x) ((x >> 16) & 0xffff)
1172#define LO(x) ((x ) & 0xffff)
1173
1174#define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1175
1176#define GEN_OPCODE32() \
1177 conscode (gencode (HI (c_code.opcode)), \
1178 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1179
1180#define GEN_OPCODE16() \
1181 conscode (gencode (c_code.opcode), NULL_CODE)
1182
1183
1184/* 32 BIT INSTRUCTIONS. */
1185
1186
1187/* DSP32 instruction generation. */
1188
1189INSTR_T
1190bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P,
1191 int h01, int h11, int h00, int h10, int op0,
1192 REG_T dst, REG_T src0, REG_T src1, int w0)
1193{
1194 INIT (DSP32Mac);
1195
1196 ASSIGN (op0);
1197 ASSIGN (op1);
1198 ASSIGN (MM);
1199 ASSIGN (mmod);
1200 ASSIGN (w0);
1201 ASSIGN (w1);
1202 ASSIGN (h01);
1203 ASSIGN (h11);
1204 ASSIGN (h00);
1205 ASSIGN (h10);
1206 ASSIGN (P);
1207
1208 /* If we have full reg assignments, mask out LSB to encode
1209 single or simultaneous even/odd register moves. */
1210 if (P)
1211 {
1212 dst->regno &= 0x06;
1213 }
1214
1215 ASSIGN_R (dst);
1216 ASSIGN_R (src0);
1217 ASSIGN_R (src1);
1218
1219 return GEN_OPCODE32 ();
1220}
1221
1222INSTR_T
1223bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P,
1224 int h01, int h11, int h00, int h10, int op0,
1225 REG_T dst, REG_T src0, REG_T src1, int w0)
1226{
1227 INIT (DSP32Mult);
1228
1229 ASSIGN (op0);
1230 ASSIGN (op1);
1231 ASSIGN (MM);
1232 ASSIGN (mmod);
1233 ASSIGN (w0);
1234 ASSIGN (w1);
1235 ASSIGN (h01);
1236 ASSIGN (h11);
1237 ASSIGN (h00);
1238 ASSIGN (h10);
1239 ASSIGN (P);
1240
1241 if (P)
1242 {
1243 dst->regno &= 0x06;
1244 }
1245
1246 ASSIGN_R (dst);
1247 ASSIGN_R (src0);
1248 ASSIGN_R (src1);
1249
1250 return GEN_OPCODE32 ();
1251}
1252
1253INSTR_T
1254bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x,
1255 REG_T dst0, REG_T dst1, REG_T src0, REG_T src1)
1256{
1257 INIT (DSP32Alu);
1258
1259 ASSIGN (HL);
1260 ASSIGN (aopcde);
1261 ASSIGN (aop);
1262 ASSIGN (s);
1263 ASSIGN (x);
1264 ASSIGN_R (dst0);
1265 ASSIGN_R (dst1);
1266 ASSIGN_R (src0);
1267 ASSIGN_R (src1);
1268
1269 return GEN_OPCODE32 ();
1270}
1271
1272INSTR_T
1273bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1274 REG_T src1, int sop, int HLs)
1275{
1276 INIT (DSP32Shift);
1277
1278 ASSIGN (sopcde);
1279 ASSIGN (sop);
1280 ASSIGN (HLs);
1281
1282 ASSIGN_R (dst0);
1283 ASSIGN_R (src0);
1284 ASSIGN_R (src1);
1285
1286 return GEN_OPCODE32 ();
1287}
1288
1289INSTR_T
1290bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1291 REG_T src1, int sop, int HLs)
1292{
1293 INIT (DSP32ShiftImm);
1294
1295 ASSIGN (sopcde);
1296 ASSIGN (sop);
1297 ASSIGN (HLs);
1298
1299 ASSIGN_R (dst0);
1300 ASSIGN (immag);
1301 ASSIGN_R (src1);
1302
1303 return GEN_OPCODE32 ();
1304}
1305
1306/* LOOP SETUP. */
1307
1308INSTR_T
1309bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1310 Expr_Node * peoffset, REG_T reg)
1311{
1312 int soffset, eoffset;
1313 INIT (LoopSetup);
1314
1315 soffset = (EXPR_VALUE (psoffset) >> 1);
1316 ASSIGN (soffset);
1317 eoffset = (EXPR_VALUE (peoffset) >> 1);
1318 ASSIGN (eoffset);
1319 ASSIGN (rop);
1320 ASSIGN_R (c);
1321 ASSIGN_R (reg);
1322
1323 return
1324 conscode (gencode (HI (c_code.opcode)),
1325 conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL),
1326 conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL))));
1327
1328}
1329
1330/* Call, Link. */
1331
1332INSTR_T
1333bfin_gen_calla (Expr_Node * addr, int S)
1334{
1335 int val;
1336 int high_val;
1337 int reloc = 0;
1338 INIT (CALLa);
1339
1340 switch(S){
1341 case 0 : reloc = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break;
1342 case 1 : reloc = BFD_RELOC_24_PCREL; break;
1343 case 2 : reloc = BFD_RELOC_BFIN_PLTPC; break;
1344 default : break;
1345 }
1346
1347 ASSIGN (S);
1348
1349 val = EXPR_VALUE (addr) >> 1;
1350 high_val = val >> 16;
1351
1352 return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
1353 Expr_Node_Gen_Reloc (addr, reloc));
1354 }
1355
1356INSTR_T
1357bfin_gen_linkage (int R, int framesize)
1358{
1359 INIT (Linkage);
1360
1361 ASSIGN (R);
1362 ASSIGN (framesize);
1363
1364 return GEN_OPCODE32 ();
1365}
1366
1367
1368/* Load and Store. */
1369
1370INSTR_T
1371bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int reloc)
1372{
1373 int grp, hword;
1374 unsigned val = EXPR_VALUE (phword);
1375 INIT (LDIMMhalf);
1376
1377 ASSIGN (H);
1378 ASSIGN (S);
1379 ASSIGN (Z);
1380
1381 ASSIGN_R (reg);
1382 grp = (GROUP (reg));
1383 ASSIGN (grp);
1384 if (reloc == 2)
1385 {
1386 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1387 }
1388 else if (reloc == 1)
1389 {
1390 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, IS_H (*reg) ? BFD_RELOC_BFIN_16_HIGH : BFD_RELOC_BFIN_16_LOW));
1391 }
1392 else
1393 {
1394 hword = val;
1395 ASSIGN (hword);
1396 }
1397 return GEN_OPCODE32 ();
1398}
1399
1400INSTR_T
1401bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1402{
07c1b327
CM
1403 INIT (LDSTidxI);
1404
1405 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1406 {
1407 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1408 return 0;
1409 }
1410
1411 ASSIGN_R (ptr);
1412 ASSIGN_R (reg);
1413 ASSIGN (W);
1414 ASSIGN (sz);
07c1b327
CM
1415
1416 ASSIGN (Z);
1417
1ac4baed
BS
1418 if (poffset->type != Expr_Node_Constant)
1419 {
1420 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1421 /* distinguish between R0 = [P5 + symbol@GOT] and
1422 P5 = [P5 + _current_shared_library_p5_offset_]
1423 */
1424 if (poffset->type == Expr_Node_Reloc
1425 && !strcmp (poffset->value.s_value,
1426 "_current_shared_library_p5_offset_"))
1427 {
1428 return conscode (gencode (HI (c_code.opcode)),
1429 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1430 }
1431 else if (poffset->type != Expr_Node_GOT_Reloc)
1432 abort ();
1433
1434 return conscode (gencode (HI (c_code.opcode)),
1435 Expr_Node_Gen_Reloc(poffset->Left_Child,
1436 poffset->value.i_value));
07c1b327 1437 }
1ac4baed 1438 else
07c1b327 1439 {
1ac4baed
BS
1440 int value, offset;
1441 switch (sz)
1442 { // load/store access size
1443 case 0: // 32 bit
1444 value = EXPR_VALUE (poffset) >> 2;
1445 break;
1446 case 1: // 16 bit
1447 value = EXPR_VALUE (poffset) >> 1;
1448 break;
1449 case 2: // 8 bit
1450 value = EXPR_VALUE (poffset);
1451 break;
1452 default:
1453 abort ();
1454 }
1455
1456 offset = (value & 0xffff);
1457 ASSIGN (offset);
1458 return GEN_OPCODE32 ();
07c1b327 1459 }
07c1b327
CM
1460}
1461
1462
1463INSTR_T
1464bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1465{
1466 INIT (LDST);
1467
1468 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1469 {
1470 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1471 return 0;
1472 }
1473
1474 ASSIGN_R (ptr);
1475 ASSIGN_R (reg);
1476 ASSIGN (aop);
1477 ASSIGN (sz);
1478 ASSIGN (Z);
1479 ASSIGN (W);
1480
1481 return GEN_OPCODE16 ();
1482}
1483
1484INSTR_T
1485bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int op)
1486{
1487 int offset;
1488 int value = 0;
1489 INIT (LDSTii);
1490
1491
1492 if (!IS_PREG (*ptr))
1493 {
1494 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1495 return 0;
1496 }
1497
1498 switch (op)
1499 {
1500 case 1:
1501 case 2:
1502 value = EXPR_VALUE (poffset) >> 1;
1503 break;
1504 case 0:
1505 case 3:
1506 value = EXPR_VALUE (poffset) >> 2;
1507 break;
1508 }
1509
1510 ASSIGN_R (ptr);
1511 ASSIGN_R (reg);
1512
1513 offset = value;
1514 ASSIGN (offset);
1515 ASSIGN (W);
1516 ASSIGN (op);
1517
1518 return GEN_OPCODE16 ();
1519}
1520
1521INSTR_T
1522bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
1523{
1524 /* Set bit 4 if it's a Preg. */
1525 int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0);
1526 int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1;
1527 INIT (LDSTiiFP);
1528 ASSIGN (reg);
1529 ASSIGN (offset);
1530 ASSIGN (W);
1531
1532 return GEN_OPCODE16 ();
1533}
1534
1535INSTR_T
1536bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1537{
1538 INIT (LDSTpmod);
1539
1540 ASSIGN_R (ptr);
1541 ASSIGN_R (reg);
1542 ASSIGN (aop);
1543 ASSIGN (W);
1544 ASSIGN_R (idx);
1545
1546 return GEN_OPCODE16 ();
1547}
1548
1549INSTR_T
1550bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1551{
1552 INIT (DspLDST);
1553
1554 ASSIGN_R (i);
1555 ASSIGN_R (reg);
1556 ASSIGN (aop);
1557 ASSIGN (W);
1558 ASSIGN (m);
1559
1560 return GEN_OPCODE16 ();
1561}
1562
1563INSTR_T
1564bfin_gen_logi2op (int opc, int src, int dst)
1565{
1566 INIT (LOGI2op);
1567
1568 ASSIGN (opc);
1569 ASSIGN (src);
1570 ASSIGN (dst);
1571
1572 return GEN_OPCODE16 ();
1573}
1574
1575INSTR_T
1576bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1577{
1578 int offset;
1579 INIT (BRCC);
1580
1581 ASSIGN (T);
1582 ASSIGN (B);
1583 offset = ((EXPR_VALUE (poffset) >> 1));
1584 ASSIGN (offset);
1585 return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL));
1586}
1587
1588INSTR_T
1589bfin_gen_ujump (Expr_Node * poffset)
1590{
1591 int offset;
1592 INIT (UJump);
1593
1594 offset = ((EXPR_VALUE (poffset) >> 1));
1595 ASSIGN (offset);
1596
1597 return conscode (gencode (c_code.opcode),
1598 Expr_Node_Gen_Reloc (
1599 poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1600}
1601
1602INSTR_T
1603bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1604{
1605 INIT (ALU2op);
1606
1607 ASSIGN_R (dst);
1608 ASSIGN_R (src);
1609 ASSIGN (opc);
1610
1611 return GEN_OPCODE16 ();
1612}
1613
1614INSTR_T
1615bfin_gen_compi2opd (REG_T dst, int src, int op)
1616{
1617 INIT (COMPI2opD);
1618
1619 ASSIGN_R (dst);
1620 ASSIGN (src);
1621 ASSIGN (op);
1622
1623 return GEN_OPCODE16 ();
1624}
1625
1626INSTR_T
1627bfin_gen_compi2opp (REG_T dst, int src, int op)
1628{
1629 INIT (COMPI2opP);
1630
1631 ASSIGN_R (dst);
1632 ASSIGN (src);
1633 ASSIGN (op);
1634
1635 return GEN_OPCODE16 ();
1636}
1637
1638INSTR_T
1639bfin_gen_dagmodik (REG_T i, int op)
1640{
1641 INIT (DagMODik);
1642
1643 ASSIGN_R (i);
1644 ASSIGN (op);
1645
1646 return GEN_OPCODE16 ();
1647}
1648
1649INSTR_T
1650bfin_gen_dagmodim (REG_T i, REG_T m, int op, int br)
1651{
1652 INIT (DagMODim);
1653
1654 ASSIGN_R (i);
1655 ASSIGN_R (m);
1656 ASSIGN (op);
1657 ASSIGN (br);
1658
1659 return GEN_OPCODE16 ();
1660}
1661
1662INSTR_T
1663bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1664{
1665 INIT (PTR2op);
1666
1667 ASSIGN_R (dst);
1668 ASSIGN_R (src);
1669 ASSIGN (opc);
1670
1671 return GEN_OPCODE16 ();
1672}
1673
1674INSTR_T
1675bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1676{
1677 INIT (COMP3op);
1678
1679 ASSIGN_R (src0);
1680 ASSIGN_R (src1);
1681 ASSIGN_R (dst);
1682 ASSIGN (opc);
1683
1684 return GEN_OPCODE16 ();
1685}
1686
1687INSTR_T
1688bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1689{
1690 INIT (CCflag);
1691
1692 ASSIGN_R (x);
1693 ASSIGN (y);
1694 ASSIGN (opc);
1695 ASSIGN (I);
1696 ASSIGN (G);
1697
1698 return GEN_OPCODE16 ();
1699}
1700
1701INSTR_T
1702bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1703{
1704 int s, d;
1705 INIT (CCmv);
1706
1707 ASSIGN_R (src);
1708 ASSIGN_R (dst);
1709 s = (GROUP (src));
1710 ASSIGN (s);
1711 d = (GROUP (dst));
1712 ASSIGN (d);
1713 ASSIGN (T);
1714
1715 return GEN_OPCODE16 ();
1716}
1717
1718INSTR_T
1719bfin_gen_cc2stat (int cbit, int op, int D)
1720{
1721 INIT (CC2stat);
1722
1723 ASSIGN (cbit);
1724 ASSIGN (op);
1725 ASSIGN (D);
1726
1727 return GEN_OPCODE16 ();
1728}
1729
1730INSTR_T
1731bfin_gen_regmv (REG_T src, REG_T dst)
1732{
1733 int gs, gd;
1734 INIT (RegMv);
1735
1736 ASSIGN_R (src);
1737 ASSIGN_R (dst);
1738
1739 gs = (GROUP (src));
1740 ASSIGN (gs);
1741 gd = (GROUP (dst));
1742 ASSIGN (gd);
1743
1744 return GEN_OPCODE16 ();
1745}
1746
1747INSTR_T
1748bfin_gen_cc2dreg (int op, REG_T reg)
1749{
1750 INIT (CC2dreg);
1751
1752 ASSIGN (op);
1753 ASSIGN_R (reg);
1754
1755 return GEN_OPCODE16 ();
1756}
1757
1758INSTR_T
1759bfin_gen_progctrl (int prgfunc, int poprnd)
1760{
1761 INIT (ProgCtrl);
1762
1763 ASSIGN (prgfunc);
1764 ASSIGN (poprnd);
1765
1766 return GEN_OPCODE16 ();
1767}
1768
1769INSTR_T
1770bfin_gen_cactrl (REG_T reg, int a, int op)
1771{
1772 INIT (CaCTRL);
1773
1774 ASSIGN_R (reg);
1775 ASSIGN (a);
1776 ASSIGN (op);
1777
1778 return GEN_OPCODE16 ();
1779}
1780
1781INSTR_T
1782bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1783{
1784 INIT (PushPopMultiple);
1785
1786 ASSIGN (dr);
1787 ASSIGN (pr);
1788 ASSIGN (d);
1789 ASSIGN (p);
1790 ASSIGN (W);
1791
1792 return GEN_OPCODE16 ();
1793}
1794
1795INSTR_T
1796bfin_gen_pushpopreg (REG_T reg, int W)
1797{
1798 int grp;
1799 INIT (PushPopReg);
1800
1801 ASSIGN_R (reg);
1802 grp = (GROUP (reg));
1803 ASSIGN (grp);
1804 ASSIGN (W);
1805
1806 return GEN_OPCODE16 ();
1807}
1808
1809/* Pseudo Debugging Support. */
1810
1811INSTR_T
1812bfin_gen_pseudodbg (int fn, int reg, int grp)
1813{
1814 INIT (PseudoDbg);
1815
1816 ASSIGN (fn);
1817 ASSIGN (reg);
1818 ASSIGN (grp);
1819
1820 return GEN_OPCODE16 ();
1821}
1822
1823INSTR_T
1824bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1825{
1826 INIT (PseudoDbg_Assert);
1827
1828 ASSIGN (dbgop);
1829 ASSIGN_R (regtest);
1830 ASSIGN (expected);
1831
1832 return GEN_OPCODE32 ();
1833}
1834
1835/* Multiple instruction generation. */
1836
1837INSTR_T
1838bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1839{
1840 INSTR_T walk;
1841
1842 /* If it's a 0, convert into MNOP. */
1843 if (dsp32)
1844 {
1845 walk = dsp32->next;
1846 SET_MULTI_INSTRUCTION_BIT (dsp32);
1847 }
1848 else
1849 {
1850 dsp32 = gencode (0xc803);
1851 walk = gencode (0x1800);
1852 dsp32->next = walk;
1853 }
1854
1855 if (!dsp16_grp1)
1856 {
1857 dsp16_grp1 = gencode (0x0000);
1858 }
1859
1860 if (!dsp16_grp2)
1861 {
1862 dsp16_grp2 = gencode (0x0000);
1863 }
1864
1865 walk->next = dsp16_grp1;
1866 dsp16_grp1->next = dsp16_grp2;
1867 dsp16_grp2->next = NULL_CODE;
1868
1869 return dsp32;
1870}
1871
1872INSTR_T
1873bfin_gen_loop (Expr_Node *expr, REG_T reg, int rop, REG_T preg)
1874{
1875 const char *loopsym;
1876 char *lbeginsym, *lendsym;
1877 Expr_Node_Value lbeginval, lendval;
1878 Expr_Node *lbegin, *lend;
1879
1880 loopsym = expr->value.s_value;
1881 lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 1);
1882 lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 1);
1883
1884 lbeginsym[0] = 0;
1885 lendsym[0] = 0;
1886
1887 strcat (lbeginsym, loopsym);
1888 strcat (lbeginsym, "__BEGIN");
1889
1890 strcat (lendsym, loopsym);
1891 strcat (lendsym, "__END");
1892
1893 lbeginval.s_value = lbeginsym;
1894 lendval.s_value = lendsym;
1895
1896 lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL);
1897 lend = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL);
1898 return bfin_gen_loopsetup(lbegin, reg, rop, lend, preg);
1899}
1900
1901bfd_boolean
1902bfin_eol_in_insn (char *line)
1903{
1904 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1905
1906 char *temp = line;
1907
1908 if (*line != '\n')
1909 return FALSE;
1910
1911 /* A semi-colon followed by a newline is always the end of a line. */
1912 if (line[-1] == ';')
1913 return FALSE;
1914
1915 if (line[-1] == '|')
1916 return TRUE;
1917
1918 /* If the || is on the next line, there might be leading whitespace. */
1919 temp++;
1920 while (*temp == ' ' || *temp == '\t') temp++;
1921
1922 if (*temp == '|')
1923 return TRUE;
1924
1925 return FALSE;
1926}
1927
07c1b327
CM
1928bfd_boolean
1929bfin_start_label (char *ptr)
1930{
1931 ptr--;
1932 while (!ISSPACE (*ptr) && !is_end_of_line[(unsigned char) *ptr])
1933 ptr--;
1934
1935 ptr++;
1936 if (*ptr == '(' || *ptr == '[')
1937 return FALSE;
1938
07c1b327
CM
1939 return TRUE;
1940}
1941
1942int
1943bfin_force_relocation (struct fix *fixp)
1944{
1945 if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
1946 || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
1947 return TRUE;
1948
1949 return generic_force_reloc (fixp);
1950}