OSDN Git Service

* gas/app, gas/as.c, gas/as.h, gas/atof-generic.c, gas/cgen.c,
[pf3gnuchains/pf3gnuchains3x.git] / gas / config / tc-bfin.c
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 struct obstack mempool;
907
908 INSTR_T
909 conscode (INSTR_T head, INSTR_T tail)
910 {
911   if (!head)
912     return tail;
913   head->next = tail;
914   return head;
915 }
916
917 INSTR_T
918 conctcode (INSTR_T head, INSTR_T tail)
919 {
920   INSTR_T temp = (head);
921   if (!head)
922     return tail;
923   while (temp->next)
924     temp = temp->next;
925   temp->next = tail;
926
927   return head;
928 }
929
930 INSTR_T
931 note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
932 {
933   /* Assert that the symbol is not an operator.  */
934   gas_assert (symbol->type == Expr_Node_Reloc);
935
936   return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
937
938 }
939
940 INSTR_T
941 note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
942 {
943   code->reloc = reloc;
944   code->exp = mkexpr (0, symbol_find_or_make (symbol));
945   code->pcrel = pcrel;
946   return code;
947 }
948
949 INSTR_T
950 note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
951 {
952   code->reloc = reloc;
953   code->exp = mkexpr (value, symbol_find_or_make (symbol));
954   code->pcrel = pcrel;
955   return code;
956 }
957
958 INSTR_T
959 gencode (unsigned long x)
960 {
961   INSTR_T cell = obstack_alloc (&mempool, sizeof (struct bfin_insn));
962   memset (cell, 0, sizeof (struct bfin_insn));
963   cell->value = (x);
964   return cell;
965 }
966
967 int reloc;
968 int ninsns;
969 int count_insns;
970
971 static void *
972 allocate (int n)
973 {
974   return obstack_alloc (&mempool, n);
975 }
976
977 Expr_Node *
978 Expr_Node_Create (Expr_Node_Type type,
979                   Expr_Node_Value value,
980                   Expr_Node *Left_Child,
981                   Expr_Node *Right_Child)
982 {
983
984
985   Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node));
986   node->type = type;
987   node->value = value;
988   node->Left_Child = Left_Child;
989   node->Right_Child = Right_Child;
990   return node;
991 }
992
993 static const char *con = ".__constant";
994 static const char *op = ".__operator";
995 static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
996 INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
997
998 INSTR_T
999 Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
1000 {
1001   /* Top level reloction expression generator VDSP style.
1002    If the relocation is just by itself, generate one item
1003    else generate this convoluted expression.  */
1004
1005   INSTR_T note = NULL_CODE;
1006   INSTR_T note1 = NULL_CODE;
1007   int pcrel = 1;  /* Is the parent reloc pcrelative?
1008                   This calculation here and HOWTO should match.  */
1009
1010   if (parent_reloc)
1011     {
1012       /*  If it's 32 bit quantity then 16bit code needs to be added.  */
1013       int value = 0;
1014
1015       if (head->type == Expr_Node_Constant)
1016         {
1017           /* If note1 is not null code, we have to generate a right
1018              aligned value for the constant. Otherwise the reloc is
1019              a part of the basic command and the yacc file
1020              generates this.  */
1021           value = head->value.i_value;
1022         }
1023       switch (parent_reloc)
1024         {
1025           /*  Some relocations will need to allocate extra words.  */
1026         case BFD_RELOC_BFIN_16_IMM:
1027         case BFD_RELOC_BFIN_16_LOW:
1028         case BFD_RELOC_BFIN_16_HIGH:
1029           note1 = conscode (gencode (value), NULL_CODE);
1030           pcrel = 0;
1031           break;
1032         case BFD_RELOC_BFIN_PLTPC:
1033           note1 = conscode (gencode (value), NULL_CODE);
1034           pcrel = 0;
1035           break;
1036         case BFD_RELOC_16:
1037         case BFD_RELOC_BFIN_GOT:
1038         case BFD_RELOC_BFIN_GOT17M4:
1039         case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
1040           note1 = conscode (gencode (value), NULL_CODE);
1041           pcrel = 0;
1042           break;
1043         case BFD_RELOC_24_PCREL:
1044         case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
1045         case BFD_RELOC_BFIN_24_PCREL_CALL_X:
1046           /* These offsets are even numbered pcrel.  */
1047           note1 = conscode (gencode (value >> 1), NULL_CODE);
1048           break;
1049         default:
1050           note1 = NULL_CODE;
1051         }
1052     }
1053   if (head->type == Expr_Node_Constant)
1054     note = note1;
1055   else if (head->type == Expr_Node_Reloc)
1056     {
1057       note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
1058       if (note1 != NULL_CODE)
1059         note = conscode (note1, note);
1060     }
1061   else if (head->type == Expr_Node_Binop
1062            && (head->value.op_value == Expr_Op_Type_Add
1063                || head->value.op_value == Expr_Op_Type_Sub)
1064            && head->Left_Child->type == Expr_Node_Reloc
1065            && head->Right_Child->type == Expr_Node_Constant)
1066     {
1067       int val = head->Right_Child->value.i_value;
1068       if (head->value.op_value == Expr_Op_Type_Sub)
1069         val = -val;
1070       note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value,
1071                                     parent_reloc, val, 0),
1072                        NULL_CODE);
1073       if (note1 != NULL_CODE)
1074         note = conscode (note1, note);
1075     }
1076   else
1077     {
1078       /* Call the recursive function.  */
1079       note = note_reloc1 (gencode (0), op, parent_reloc, pcrel);
1080       if (note1 != NULL_CODE)
1081         note = conscode (note1, note);
1082       note = conctcode (Expr_Node_Gen_Reloc_R (head), note);
1083     }
1084   return note;
1085 }
1086
1087 static INSTR_T
1088 Expr_Node_Gen_Reloc_R (Expr_Node * head)
1089 {
1090
1091   INSTR_T note = 0;
1092   INSTR_T note1 = 0;
1093
1094   switch (head->type)
1095     {
1096     case Expr_Node_Constant:
1097       note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE);
1098       break;
1099     case Expr_Node_Reloc:
1100       note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE);
1101       break;
1102     case Expr_Node_Binop:
1103       note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child));
1104       switch (head->value.op_value)
1105         {
1106         case Expr_Op_Type_Add:
1107           note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE));
1108           break;
1109         case Expr_Op_Type_Sub:
1110           note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE));
1111           break;
1112         case Expr_Op_Type_Mult:
1113           note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE));
1114           break;
1115         case Expr_Op_Type_Div:
1116           note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE));
1117           break;
1118         case Expr_Op_Type_Mod:
1119           note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE));
1120           break;
1121         case Expr_Op_Type_Lshift:
1122           note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE));
1123           break;
1124         case Expr_Op_Type_Rshift:
1125           note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE));
1126           break;
1127         case Expr_Op_Type_BAND:
1128           note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE));
1129           break;
1130         case Expr_Op_Type_BOR:
1131           note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE));
1132           break;
1133         case Expr_Op_Type_BXOR:
1134           note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE));
1135           break;
1136         case Expr_Op_Type_LAND:
1137           note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE));
1138           break;
1139         case Expr_Op_Type_LOR:
1140           note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE));
1141           break;
1142         default:
1143           fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
1144
1145
1146         }
1147       break;
1148     case Expr_Node_Unop:
1149       note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE);
1150       switch (head->value.op_value)
1151         {
1152         case Expr_Op_Type_NEG:
1153           note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE));
1154           break;
1155         case Expr_Op_Type_COMP:
1156           note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE));
1157           break;
1158         default:
1159           fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
1160         }
1161       break;
1162     default:
1163       fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1164     }
1165   return note;
1166 }
1167
1168
1169 /* Blackfin opcode generation.  */
1170
1171 /* These functions are called by the generated parser
1172    (from bfin-parse.y), the register type classification
1173    happens in bfin-lex.l.  */
1174
1175 #include "bfin-aux.h"
1176 #include "opcode/bfin.h"
1177
1178 #define INIT(t)  t c_code = init_##t
1179 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1180 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1181
1182 #define HI(x) ((x >> 16) & 0xffff)
1183 #define LO(x) ((x      ) & 0xffff)
1184
1185 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1186
1187 #define GEN_OPCODE32()  \
1188         conscode (gencode (HI (c_code.opcode)), \
1189         conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1190
1191 #define GEN_OPCODE16()  \
1192         conscode (gencode (c_code.opcode), NULL_CODE)
1193
1194
1195 /*  32 BIT INSTRUCTIONS.  */
1196
1197
1198 /* DSP32 instruction generation.  */
1199
1200 INSTR_T
1201 bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P,
1202                    int h01, int h11, int h00, int h10, int op0,
1203                    REG_T dst, REG_T src0, REG_T src1, int w0)
1204 {
1205   INIT (DSP32Mac);
1206
1207   ASSIGN (op0);
1208   ASSIGN (op1);
1209   ASSIGN (MM);
1210   ASSIGN (mmod);
1211   ASSIGN (w0);
1212   ASSIGN (w1);
1213   ASSIGN (h01);
1214   ASSIGN (h11);
1215   ASSIGN (h00);
1216   ASSIGN (h10);
1217   ASSIGN (P);
1218
1219   /* If we have full reg assignments, mask out LSB to encode
1220   single or simultaneous even/odd register moves.  */
1221   if (P)
1222     {
1223       dst->regno &= 0x06;
1224     }
1225
1226   ASSIGN_R (dst);
1227   ASSIGN_R (src0);
1228   ASSIGN_R (src1);
1229
1230   return GEN_OPCODE32 ();
1231 }
1232
1233 INSTR_T
1234 bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P,
1235                     int h01, int h11, int h00, int h10, int op0,
1236                     REG_T dst, REG_T src0, REG_T src1, int w0)
1237 {
1238   INIT (DSP32Mult);
1239
1240   ASSIGN (op0);
1241   ASSIGN (op1);
1242   ASSIGN (MM);
1243   ASSIGN (mmod);
1244   ASSIGN (w0);
1245   ASSIGN (w1);
1246   ASSIGN (h01);
1247   ASSIGN (h11);
1248   ASSIGN (h00);
1249   ASSIGN (h10);
1250   ASSIGN (P);
1251
1252   if (P)
1253     {
1254       dst->regno &= 0x06;
1255     }
1256
1257   ASSIGN_R (dst);
1258   ASSIGN_R (src0);
1259   ASSIGN_R (src1);
1260
1261   return GEN_OPCODE32 ();
1262 }
1263
1264 INSTR_T
1265 bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x,
1266               REG_T dst0, REG_T dst1, REG_T src0, REG_T src1)
1267 {
1268   INIT (DSP32Alu);
1269
1270   ASSIGN (HL);
1271   ASSIGN (aopcde);
1272   ASSIGN (aop);
1273   ASSIGN (s);
1274   ASSIGN (x);
1275   ASSIGN_R (dst0);
1276   ASSIGN_R (dst1);
1277   ASSIGN_R (src0);
1278   ASSIGN_R (src1);
1279
1280   return GEN_OPCODE32 ();
1281 }
1282
1283 INSTR_T
1284 bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1285                 REG_T src1, int sop, int HLs)
1286 {
1287   INIT (DSP32Shift);
1288
1289   ASSIGN (sopcde);
1290   ASSIGN (sop);
1291   ASSIGN (HLs);
1292
1293   ASSIGN_R (dst0);
1294   ASSIGN_R (src0);
1295   ASSIGN_R (src1);
1296
1297   return GEN_OPCODE32 ();
1298 }
1299
1300 INSTR_T
1301 bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1302                    REG_T src1, int sop, int HLs)
1303 {
1304   INIT (DSP32ShiftImm);
1305
1306   ASSIGN (sopcde);
1307   ASSIGN (sop);
1308   ASSIGN (HLs);
1309
1310   ASSIGN_R (dst0);
1311   ASSIGN (immag);
1312   ASSIGN_R (src1);
1313
1314   return GEN_OPCODE32 ();
1315 }
1316
1317 /* LOOP SETUP.  */
1318
1319 INSTR_T
1320 bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1321                Expr_Node * peoffset, REG_T reg)
1322 {
1323   int soffset, eoffset;
1324   INIT (LoopSetup);
1325
1326   soffset = (EXPR_VALUE (psoffset) >> 1);
1327   ASSIGN (soffset);
1328   eoffset = (EXPR_VALUE (peoffset) >> 1);
1329   ASSIGN (eoffset);
1330   ASSIGN (rop);
1331   ASSIGN_R (c);
1332   ASSIGN_R (reg);
1333
1334   return
1335       conscode (gencode (HI (c_code.opcode)),
1336                 conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL),
1337                            conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL))));
1338
1339 }
1340
1341 /*  Call, Link.  */
1342
1343 INSTR_T
1344 bfin_gen_calla (Expr_Node * addr, int S)
1345 {
1346   int val;
1347   int high_val;
1348   int reloc = 0;
1349   INIT (CALLa);
1350
1351   switch(S){
1352    case 0 : reloc = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break;
1353    case 1 : reloc = BFD_RELOC_24_PCREL; break;
1354    case 2 : reloc = BFD_RELOC_BFIN_PLTPC; break;
1355    default : break;
1356   }
1357
1358   ASSIGN (S);
1359
1360   val = EXPR_VALUE (addr) >> 1;
1361   high_val = val >> 16;
1362
1363   return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
1364                      Expr_Node_Gen_Reloc (addr, reloc));
1365   }
1366
1367 INSTR_T
1368 bfin_gen_linkage (int R, int framesize)
1369 {
1370   INIT (Linkage);
1371
1372   ASSIGN (R);
1373   ASSIGN (framesize);
1374
1375   return GEN_OPCODE32 ();
1376 }
1377
1378
1379 /* Load and Store.  */
1380
1381 INSTR_T
1382 bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int reloc)
1383 {
1384   int grp, hword;
1385   unsigned val = EXPR_VALUE (phword);
1386   INIT (LDIMMhalf);
1387
1388   ASSIGN (H);
1389   ASSIGN (S);
1390   ASSIGN (Z);
1391
1392   ASSIGN_R (reg);
1393   grp = (GROUP (reg));
1394   ASSIGN (grp);
1395   if (reloc == 2)
1396     {
1397       return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1398     }
1399   else if (reloc == 1)
1400     {
1401       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));
1402     }
1403   else
1404     {
1405       hword = val;
1406       ASSIGN (hword);
1407     }
1408   return GEN_OPCODE32 ();
1409 }
1410
1411 INSTR_T
1412 bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1413 {
1414   INIT (LDSTidxI);
1415
1416   if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1417     {
1418       fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1419       return 0;
1420     }
1421
1422   ASSIGN_R (ptr);
1423   ASSIGN_R (reg);
1424   ASSIGN (W);
1425   ASSIGN (sz);
1426
1427   ASSIGN (Z);
1428
1429   if (poffset->type != Expr_Node_Constant)
1430     {
1431       /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1432       /* distinguish between R0 = [P5 + symbol@GOT] and
1433          P5 = [P5 + _current_shared_library_p5_offset_]
1434       */
1435       if (poffset->type == Expr_Node_Reloc
1436           && !strcmp (poffset->value.s_value,
1437                       "_current_shared_library_p5_offset_"))
1438         {
1439           return  conscode (gencode (HI (c_code.opcode)),
1440                             Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1441         }
1442       else if (poffset->type != Expr_Node_GOT_Reloc)
1443         abort ();
1444
1445       return conscode (gencode (HI (c_code.opcode)),
1446                        Expr_Node_Gen_Reloc(poffset->Left_Child,
1447                                            poffset->value.i_value));
1448     }
1449   else
1450     {
1451       int value, offset;
1452       switch (sz)
1453         {                               /* load/store access size */
1454         case 0:                 /* 32 bit */
1455           value = EXPR_VALUE (poffset) >> 2;
1456           break;
1457         case 1:                 /* 16 bit */
1458           value = EXPR_VALUE (poffset) >> 1;
1459           break;
1460         case 2:                 /* 8 bit */
1461           value = EXPR_VALUE (poffset);
1462           break;
1463         default:
1464           abort ();
1465         }
1466
1467       offset = (value & 0xffff);
1468       ASSIGN (offset);
1469       return GEN_OPCODE32 ();
1470     }
1471 }
1472
1473
1474 INSTR_T
1475 bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1476 {
1477   INIT (LDST);
1478
1479   if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1480     {
1481       fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1482       return 0;
1483     }
1484
1485   ASSIGN_R (ptr);
1486   ASSIGN_R (reg);
1487   ASSIGN (aop);
1488   ASSIGN (sz);
1489   ASSIGN (Z);
1490   ASSIGN (W);
1491
1492   return GEN_OPCODE16 ();
1493 }
1494
1495 INSTR_T
1496 bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int op)
1497 {
1498   int offset;
1499   int value = 0;
1500   INIT (LDSTii);
1501
1502
1503   if (!IS_PREG (*ptr))
1504     {
1505       fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1506       return 0;
1507     }
1508
1509   switch (op)
1510     {
1511     case 1:
1512     case 2:
1513       value = EXPR_VALUE (poffset) >> 1;
1514       break;
1515     case 0:
1516     case 3:
1517       value = EXPR_VALUE (poffset) >> 2;
1518       break;
1519     }
1520
1521   ASSIGN_R (ptr);
1522   ASSIGN_R (reg);
1523
1524   offset = value;
1525   ASSIGN (offset);
1526   ASSIGN (W);
1527   ASSIGN (op);
1528
1529   return GEN_OPCODE16 ();
1530 }
1531
1532 INSTR_T
1533 bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
1534 {
1535   /* Set bit 4 if it's a Preg.  */
1536   int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0);
1537   int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1;
1538   INIT (LDSTiiFP);
1539   ASSIGN (reg);
1540   ASSIGN (offset);
1541   ASSIGN (W);
1542
1543   return GEN_OPCODE16 ();
1544 }
1545
1546 INSTR_T
1547 bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1548 {
1549   INIT (LDSTpmod);
1550
1551   ASSIGN_R (ptr);
1552   ASSIGN_R (reg);
1553   ASSIGN (aop);
1554   ASSIGN (W);
1555   ASSIGN_R (idx);
1556
1557   return GEN_OPCODE16 ();
1558 }
1559
1560 INSTR_T
1561 bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1562 {
1563   INIT (DspLDST);
1564
1565   ASSIGN_R (i);
1566   ASSIGN_R (reg);
1567   ASSIGN (aop);
1568   ASSIGN (W);
1569   ASSIGN (m);
1570
1571   return GEN_OPCODE16 ();
1572 }
1573
1574 INSTR_T
1575 bfin_gen_logi2op (int opc, int src, int dst)
1576 {
1577   INIT (LOGI2op);
1578
1579   ASSIGN (opc);
1580   ASSIGN (src);
1581   ASSIGN (dst);
1582
1583   return GEN_OPCODE16 ();
1584 }
1585
1586 INSTR_T
1587 bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1588 {
1589   int offset;
1590   INIT (BRCC);
1591
1592   ASSIGN (T);
1593   ASSIGN (B);
1594   offset = ((EXPR_VALUE (poffset) >> 1));
1595   ASSIGN (offset);
1596   return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL));
1597 }
1598
1599 INSTR_T
1600 bfin_gen_ujump (Expr_Node * poffset)
1601 {
1602   int offset;
1603   INIT (UJump);
1604
1605   offset = ((EXPR_VALUE (poffset) >> 1));
1606   ASSIGN (offset);
1607
1608   return conscode (gencode (c_code.opcode),
1609                    Expr_Node_Gen_Reloc (
1610                        poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1611 }
1612
1613 INSTR_T
1614 bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1615 {
1616   INIT (ALU2op);
1617
1618   ASSIGN_R (dst);
1619   ASSIGN_R (src);
1620   ASSIGN (opc);
1621
1622   return GEN_OPCODE16 ();
1623 }
1624
1625 INSTR_T
1626 bfin_gen_compi2opd (REG_T dst, int src, int op)
1627 {
1628   INIT (COMPI2opD);
1629
1630   ASSIGN_R (dst);
1631   ASSIGN (src);
1632   ASSIGN (op);
1633
1634   return GEN_OPCODE16 ();
1635 }
1636
1637 INSTR_T
1638 bfin_gen_compi2opp (REG_T dst, int src, int op)
1639 {
1640   INIT (COMPI2opP);
1641
1642   ASSIGN_R (dst);
1643   ASSIGN (src);
1644   ASSIGN (op);
1645
1646   return GEN_OPCODE16 ();
1647 }
1648
1649 INSTR_T
1650 bfin_gen_dagmodik (REG_T i, int op)
1651 {
1652   INIT (DagMODik);
1653
1654   ASSIGN_R (i);
1655   ASSIGN (op);
1656
1657   return GEN_OPCODE16 ();
1658 }
1659
1660 INSTR_T
1661 bfin_gen_dagmodim (REG_T i, REG_T m, int op, int br)
1662 {
1663   INIT (DagMODim);
1664
1665   ASSIGN_R (i);
1666   ASSIGN_R (m);
1667   ASSIGN (op);
1668   ASSIGN (br);
1669
1670   return GEN_OPCODE16 ();
1671 }
1672
1673 INSTR_T
1674 bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1675 {
1676   INIT (PTR2op);
1677
1678   ASSIGN_R (dst);
1679   ASSIGN_R (src);
1680   ASSIGN (opc);
1681
1682   return GEN_OPCODE16 ();
1683 }
1684
1685 INSTR_T
1686 bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1687 {
1688   INIT (COMP3op);
1689
1690   ASSIGN_R (src0);
1691   ASSIGN_R (src1);
1692   ASSIGN_R (dst);
1693   ASSIGN (opc);
1694
1695   return GEN_OPCODE16 ();
1696 }
1697
1698 INSTR_T
1699 bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1700 {
1701   INIT (CCflag);
1702
1703   ASSIGN_R (x);
1704   ASSIGN (y);
1705   ASSIGN (opc);
1706   ASSIGN (I);
1707   ASSIGN (G);
1708
1709   return GEN_OPCODE16 ();
1710 }
1711
1712 INSTR_T
1713 bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1714 {
1715   int s, d;
1716   INIT (CCmv);
1717
1718   ASSIGN_R (src);
1719   ASSIGN_R (dst);
1720   s = (GROUP (src));
1721   ASSIGN (s);
1722   d = (GROUP (dst));
1723   ASSIGN (d);
1724   ASSIGN (T);
1725
1726   return GEN_OPCODE16 ();
1727 }
1728
1729 INSTR_T
1730 bfin_gen_cc2stat (int cbit, int op, int D)
1731 {
1732   INIT (CC2stat);
1733
1734   ASSIGN (cbit);
1735   ASSIGN (op);
1736   ASSIGN (D);
1737
1738   return GEN_OPCODE16 ();
1739 }
1740
1741 INSTR_T
1742 bfin_gen_regmv (REG_T src, REG_T dst)
1743 {
1744   int gs, gd;
1745   INIT (RegMv);
1746
1747   ASSIGN_R (src);
1748   ASSIGN_R (dst);
1749
1750   gs = (GROUP (src));
1751   ASSIGN (gs);
1752   gd = (GROUP (dst));
1753   ASSIGN (gd);
1754
1755   return GEN_OPCODE16 ();
1756 }
1757
1758 INSTR_T
1759 bfin_gen_cc2dreg (int op, REG_T reg)
1760 {
1761   INIT (CC2dreg);
1762
1763   ASSIGN (op);
1764   ASSIGN_R (reg);
1765
1766   return GEN_OPCODE16 ();
1767 }
1768
1769 INSTR_T
1770 bfin_gen_progctrl (int prgfunc, int poprnd)
1771 {
1772   INIT (ProgCtrl);
1773
1774   ASSIGN (prgfunc);
1775   ASSIGN (poprnd);
1776
1777   return GEN_OPCODE16 ();
1778 }
1779
1780 INSTR_T
1781 bfin_gen_cactrl (REG_T reg, int a, int op)
1782 {
1783   INIT (CaCTRL);
1784
1785   ASSIGN_R (reg);
1786   ASSIGN (a);
1787   ASSIGN (op);
1788
1789   return GEN_OPCODE16 ();
1790 }
1791
1792 INSTR_T
1793 bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1794 {
1795   INIT (PushPopMultiple);
1796
1797   ASSIGN (dr);
1798   ASSIGN (pr);
1799   ASSIGN (d);
1800   ASSIGN (p);
1801   ASSIGN (W);
1802
1803   return GEN_OPCODE16 ();
1804 }
1805
1806 INSTR_T
1807 bfin_gen_pushpopreg (REG_T reg, int W)
1808 {
1809   int grp;
1810   INIT (PushPopReg);
1811
1812   ASSIGN_R (reg);
1813   grp = (GROUP (reg));
1814   ASSIGN (grp);
1815   ASSIGN (W);
1816
1817   return GEN_OPCODE16 ();
1818 }
1819
1820 /* Pseudo Debugging Support.  */
1821
1822 INSTR_T
1823 bfin_gen_pseudodbg (int fn, int reg, int grp)
1824 {
1825   INIT (PseudoDbg);
1826
1827   ASSIGN (fn);
1828   ASSIGN (reg);
1829   ASSIGN (grp);
1830
1831   return GEN_OPCODE16 ();
1832 }
1833
1834 INSTR_T
1835 bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1836 {
1837   INIT (PseudoDbg_Assert);
1838
1839   ASSIGN (dbgop);
1840   ASSIGN_R (regtest);
1841   ASSIGN (expected);
1842
1843   return GEN_OPCODE32 ();
1844 }
1845
1846 /* Multiple instruction generation.  */
1847
1848 INSTR_T
1849 bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1850 {
1851   INSTR_T walk;
1852
1853   /* If it's a 0, convert into MNOP. */
1854   if (dsp32)
1855     {
1856       walk = dsp32->next;
1857       SET_MULTI_INSTRUCTION_BIT (dsp32);
1858     }
1859   else
1860     {
1861       dsp32 = gencode (0xc803);
1862       walk = gencode (0x1800);
1863       dsp32->next = walk;
1864     }
1865
1866   if (!dsp16_grp1)
1867     {
1868       dsp16_grp1 = gencode (0x0000);
1869     }
1870
1871   if (!dsp16_grp2)
1872     {
1873       dsp16_grp2 = gencode (0x0000);
1874     }
1875
1876   walk->next = dsp16_grp1;
1877   dsp16_grp1->next = dsp16_grp2;
1878   dsp16_grp2->next = NULL_CODE;
1879
1880   return dsp32;
1881 }
1882
1883 INSTR_T
1884 bfin_gen_loop (Expr_Node *expr, REG_T reg, int rop, REG_T preg)
1885 {
1886   const char *loopsym;
1887   char *lbeginsym, *lendsym;
1888   Expr_Node_Value lbeginval, lendval;
1889   Expr_Node *lbegin, *lend;
1890
1891   loopsym = expr->value.s_value;
1892   lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 5);
1893   lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 5);
1894
1895   lbeginsym[0] = 0;
1896   lendsym[0] = 0;
1897
1898   strcat (lbeginsym, "L$L$");
1899   strcat (lbeginsym, loopsym);
1900   strcat (lbeginsym, "__BEGIN");
1901
1902   strcat (lendsym, "L$L$");
1903   strcat (lendsym, loopsym);
1904   strcat (lendsym, "__END");
1905
1906   lbeginval.s_value = lbeginsym;
1907   lendval.s_value = lendsym;
1908
1909   lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL);
1910   lend   = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL);
1911
1912   symbol_remove (symbol_find (loopsym), &symbol_rootP, &symbol_lastP);
1913
1914   return bfin_gen_loopsetup(lbegin, reg, rop, lend, preg);
1915 }
1916
1917 bfd_boolean
1918 bfin_eol_in_insn (char *line)
1919 {
1920    /* Allow a new-line to appear in the middle of a multi-issue instruction.  */
1921
1922    char *temp = line;
1923
1924   if (*line != '\n')
1925     return FALSE;
1926
1927   /* A semi-colon followed by a newline is always the end of a line.  */
1928   if (line[-1] == ';')
1929     return FALSE;
1930
1931   if (line[-1] == '|')
1932     return TRUE;
1933
1934   /* If the || is on the next line, there might be leading whitespace.  */
1935   temp++;
1936   while (*temp == ' ' || *temp == '\t') temp++;
1937
1938   if (*temp == '|')
1939     return TRUE;
1940
1941   return FALSE;
1942 }
1943
1944 bfd_boolean
1945 bfin_start_label (char *ptr)
1946 {
1947   ptr--;
1948   while (!ISSPACE (*ptr) && !is_end_of_line[(unsigned char) *ptr])
1949     ptr--;
1950
1951   ptr++;
1952   if (*ptr == '(' || *ptr == '[')
1953     return FALSE;
1954
1955   return TRUE;
1956
1957
1958 int
1959 bfin_force_relocation (struct fix *fixp)
1960 {
1961   if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
1962       || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
1963     return TRUE;
1964
1965   return generic_force_reloc (fixp);
1966 }