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