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