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