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 
35 extern int yyparse (void);
36 struct yy_buffer_state;
37 typedef struct yy_buffer_state *YY_BUFFER_STATE;
38 extern YY_BUFFER_STATE yy_scan_string (const char *yy_str);
39 extern void yy_delete_buffer (YY_BUFFER_STATE b);
40 static parse_state parse (char *line);
41 static void bfin_s_bss PARAMS ((int));
42 static int md_chars_to_number PARAMS ((char *, int));
43 
44 /* Global variables. */
45 struct bfin_insn *insn;
46 int last_insn_size;
47 
48 extern struct obstack mempool;
49 FILE *errorf;
50 
51 /* Flags to set in the elf header */
52 #define DEFAULT_FLAGS 0
53 
54 static flagword bfin_flags = DEFAULT_FLAGS;
55 static const char *bfin_pic_flag = (const char *)0;
56 
57 /* Registers list.  */
58 struct bfin_reg_entry
59 {
60   const char *name;
61   int number;
62 };
63 
64 static 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 
216 static void
bfin_pic_ptr(int nbytes)217 bfin_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 
266 static void
bfin_s_bss(int ignore ATTRIBUTE_UNUSED)267 bfin_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 
276 const 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. */
293 const char comment_chars[] = "";
294 const char line_comment_chars[] = "#";
295 const char line_separator_chars[] = ";";
296 
297 /* Characters that can be used to separate the mantissa from the
298    exponent in floating point numbers. */
299 const char EXP_CHARS[] = "eE";
300 
301 /* Characters that mean this number is a floating point constant.
302    As in 0f12.456 or  0d1.2345e12.  */
303 const char FLT_CHARS[] = "fFdDxX";
304 
305 /* Define bfin-specific command-line options (there are none). */
306 const char *md_shortopts = "";
307 
308 #define OPTION_FDPIC		(OPTION_MD_BASE)
309 
310 struct option md_longopts[] =
311 {
312   { "mfdpic",		no_argument,		NULL, OPTION_FDPIC	   },
313   { NULL,		no_argument,		NULL, 0                 },
314 };
315 
316 size_t md_longopts_size = sizeof (md_longopts);
317 
318 
319 int
md_parse_option(int c ATTRIBUTE_UNUSED,char * arg ATTRIBUTE_UNUSED)320 md_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 
336 void
md_show_usage(FILE * stream ATTRIBUTE_UNUSED)337 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
338 {
339   fprintf (stream, _(" BFIN specific command line options:\n"));
340 }
341 
342 /* Perform machine-specific initializations.  */
343 void
md_begin()344 md_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 
379 void
md_assemble(char * line)380 md_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 
480 static parse_state
parse(char * line)481 parse (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 
508 void
md_operand(expressionS * expressionP)509 md_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. */
520 symbolS *
md_undefined_symbol(char * name ATTRIBUTE_UNUSED)521 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
522 {
523   return (symbolS *) 0;
524 }
525 
526 int
md_estimate_size_before_relax(fragS * fragP ATTRIBUTE_UNUSED,segT segment ATTRIBUTE_UNUSED)527 md_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 
535 static int
md_chars_to_number(char * val,int n)536 md_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 
548 void
md_apply_fix(fixS * fixP,valueT * valueP,segT seg ATTRIBUTE_UNUSED)549 md_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.  */
684 valueT
md_section_align(segment,size)685 md_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 
702 char *
md_atof(type,litP,sizeP)703 md_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 
753 arelent *
tc_gen_reloc(seg,fixp)754 tc_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 
786 long
md_pcrel_from_section(fixP,sec)787 md_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 
805 bfd_boolean
bfin_fix_adjustable(fixS * fixP)806 bfin_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.  */
828 void
bfin_start_line_hook()829 bfin_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 
938 struct obstack mempool;
939 
940 INSTR_T
conscode(INSTR_T head,INSTR_T tail)941 conscode (INSTR_T head, INSTR_T tail)
942 {
943   if (!head)
944     return tail;
945   head->next = tail;
946   return head;
947 }
948 
949 INSTR_T
conctcode(INSTR_T head,INSTR_T tail)950 conctcode (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 
962 INSTR_T
note_reloc(INSTR_T code,Expr_Node * symbol,int reloc,int pcrel)963 note_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 
972 INSTR_T
note_reloc1(INSTR_T code,const char * symbol,int reloc,int pcrel)973 note_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 
981 INSTR_T
note_reloc2(INSTR_T code,const char * symbol,int reloc,int value,int pcrel)982 note_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 
990 INSTR_T
gencode(unsigned long x)991 gencode (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 
999 int reloc;
1000 int ninsns;
1001 int count_insns;
1002 
1003 static void *
allocate(int n)1004 allocate (int n)
1005 {
1006   return (void *) obstack_alloc (&mempool, n);
1007 }
1008 
1009 Expr_Node *
Expr_Node_Create(Expr_Node_Type type,Expr_Node_Value value,Expr_Node * Left_Child,Expr_Node * Right_Child)1010 Expr_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 
1025 static const char *con = ".__constant";
1026 static const char *op = ".__operator";
1027 static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
1028 INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
1029 
1030 INSTR_T
Expr_Node_Gen_Reloc(Expr_Node * head,int parent_reloc)1031 Expr_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 
1119 static INSTR_T
Expr_Node_Gen_Reloc_R(Expr_Node * head)1120 Expr_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 
1232 INSTR_T
bfin_gen_dsp32mac(int op1,int MM,int mmod,int w1,int P,int h01,int h11,int h00,int h10,int op0,REG_T dst,REG_T src0,REG_T src1,int w0)1233 bfin_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 
1265 INSTR_T
bfin_gen_dsp32mult(int op1,int MM,int mmod,int w1,int P,int h01,int h11,int h00,int h10,int op0,REG_T dst,REG_T src0,REG_T src1,int w0)1266 bfin_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 
1296 INSTR_T
bfin_gen_dsp32alu(int HL,int aopcde,int aop,int s,int x,REG_T dst0,REG_T dst1,REG_T src0,REG_T src1)1297 bfin_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 
1315 INSTR_T
bfin_gen_dsp32shift(int sopcde,REG_T dst0,REG_T src0,REG_T src1,int sop,int HLs)1316 bfin_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 
1332 INSTR_T
bfin_gen_dsp32shiftimm(int sopcde,REG_T dst0,int immag,REG_T src1,int sop,int HLs)1333 bfin_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 
1351 INSTR_T
bfin_gen_loopsetup(Expr_Node * psoffset,REG_T c,int rop,Expr_Node * peoffset,REG_T reg)1352 bfin_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 
1375 INSTR_T
bfin_gen_calla(Expr_Node * addr,int S)1376 bfin_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 
1399 INSTR_T
bfin_gen_linkage(int R,int framesize)1400 bfin_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 
1413 INSTR_T
bfin_gen_ldimmhalf(REG_T reg,int H,int S,int Z,Expr_Node * phword,int reloc)1414 bfin_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 
1443 INSTR_T
bfin_gen_ldstidxi(REG_T ptr,REG_T reg,int W,int sz,int Z,Expr_Node * poffset)1444 bfin_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 
1506 INSTR_T
bfin_gen_ldst(REG_T ptr,REG_T reg,int aop,int sz,int Z,int W)1507 bfin_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 
1527 INSTR_T
bfin_gen_ldstii(REG_T ptr,REG_T reg,Expr_Node * poffset,int W,int op)1528 bfin_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 
1564 INSTR_T
bfin_gen_ldstiifp(REG_T sreg,Expr_Node * poffset,int W)1565 bfin_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 
1578 INSTR_T
bfin_gen_ldstpmod(REG_T ptr,REG_T reg,int aop,int W,REG_T idx)1579 bfin_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 
1592 INSTR_T
bfin_gen_dspldst(REG_T i,REG_T reg,int aop,int W,int m)1593 bfin_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 
1606 INSTR_T
bfin_gen_logi2op(int opc,int src,int dst)1607 bfin_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 
1618 INSTR_T
bfin_gen_brcc(int T,int B,Expr_Node * poffset)1619 bfin_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 
1631 INSTR_T
bfin_gen_ujump(Expr_Node * poffset)1632 bfin_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 
1645 INSTR_T
bfin_gen_alu2op(REG_T dst,REG_T src,int opc)1646 bfin_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 
1657 INSTR_T
bfin_gen_compi2opd(REG_T dst,int src,int op)1658 bfin_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 
1669 INSTR_T
bfin_gen_compi2opp(REG_T dst,int src,int op)1670 bfin_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 
1681 INSTR_T
bfin_gen_dagmodik(REG_T i,int op)1682 bfin_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 
1692 INSTR_T
bfin_gen_dagmodim(REG_T i,REG_T m,int op,int br)1693 bfin_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 
1705 INSTR_T
bfin_gen_ptr2op(REG_T dst,REG_T src,int opc)1706 bfin_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 
1717 INSTR_T
bfin_gen_comp3op(REG_T src0,REG_T src1,REG_T dst,int opc)1718 bfin_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 
1730 INSTR_T
bfin_gen_ccflag(REG_T x,int y,int opc,int I,int G)1731 bfin_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 
1744 INSTR_T
bfin_gen_ccmv(REG_T src,REG_T dst,int T)1745 bfin_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 
1761 INSTR_T
bfin_gen_cc2stat(int cbit,int op,int D)1762 bfin_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 
1773 INSTR_T
bfin_gen_regmv(REG_T src,REG_T dst)1774 bfin_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 
1790 INSTR_T
bfin_gen_cc2dreg(int op,REG_T reg)1791 bfin_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 
1801 INSTR_T
bfin_gen_progctrl(int prgfunc,int poprnd)1802 bfin_gen_progctrl (int prgfunc, int poprnd)
1803 {
1804   INIT (ProgCtrl);
1805 
1806   ASSIGN (prgfunc);
1807   ASSIGN (poprnd);
1808 
1809   return GEN_OPCODE16 ();
1810 }
1811 
1812 INSTR_T
bfin_gen_cactrl(REG_T reg,int a,int op)1813 bfin_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 
1824 INSTR_T
bfin_gen_pushpopmultiple(int dr,int pr,int d,int p,int W)1825 bfin_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 
1838 INSTR_T
bfin_gen_pushpopreg(REG_T reg,int W)1839 bfin_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 
1854 INSTR_T
bfin_gen_pseudodbg(int fn,int reg,int grp)1855 bfin_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 
1866 INSTR_T
bfin_gen_pseudodbg_assert(int dbgop,REG_T regtest,int expected)1867 bfin_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 
1880 INSTR_T
bfin_gen_multi_instr(INSTR_T dsp32,INSTR_T dsp16_grp1,INSTR_T dsp16_grp2)1881 bfin_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 
1915 INSTR_T
bfin_gen_loop(Expr_Node * expr,REG_T reg,int rop,REG_T preg)1916 bfin_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 
1944 bfd_boolean
bfin_eol_in_insn(char * line)1945 bfin_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 
1971 bfd_boolean
bfin_name_is_register(char * name)1972 bfin_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 
1993 void
bfin_equals(Expr_Node * sym)1994 bfin_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 
2007 bfd_boolean
bfin_start_label(char * ptr)2008 bfin_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 
2021 int
bfin_force_relocation(struct fix * fixp)2022 bfin_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