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