Home | History | Annotate | Line # | Download | only in config
tc-rl78.c revision 1.1.1.4
      1      1.1  christos /* tc-rl78.c -- Assembler for the Renesas RL78
      2  1.1.1.4  christos    Copyright (C) 2011-2018 Free Software Foundation, Inc.
      3      1.1  christos 
      4      1.1  christos    This file is part of GAS, the GNU Assembler.
      5      1.1  christos 
      6      1.1  christos    GAS is free software; you can redistribute it and/or modify
      7      1.1  christos    it under the terms of the GNU General Public License as published by
      8      1.1  christos    the Free Software Foundation; either version 3, or (at your option)
      9      1.1  christos    any later version.
     10      1.1  christos 
     11      1.1  christos    GAS is distributed in the hope that it will be useful,
     12      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14      1.1  christos    GNU General Public License for more details.
     15      1.1  christos 
     16      1.1  christos    You should have received a copy of the GNU General Public License
     17      1.1  christos    along with GAS; see the file COPYING.  If not, write to the Free
     18      1.1  christos    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     19      1.1  christos    02110-1301, USA.  */
     20      1.1  christos 
     21      1.1  christos #include "as.h"
     22      1.1  christos #include "struc-symbol.h"
     23      1.1  christos #include "safe-ctype.h"
     24      1.1  christos #include "dwarf2dbg.h"
     25      1.1  christos #include "elf/common.h"
     26      1.1  christos #include "elf/rl78.h"
     27      1.1  christos #include "rl78-defs.h"
     28      1.1  christos #include "filenames.h"
     29      1.1  christos #include "listing.h"
     30      1.1  christos #include "sb.h"
     31      1.1  christos #include "macro.h"
     32      1.1  christos 
     33      1.1  christos const char comment_chars[]        = ";";
     34      1.1  christos /* Note that input_file.c hand checks for '#' at the beginning of the
     35      1.1  christos    first line of the input file.  This is because the compiler outputs
     36      1.1  christos    #NO_APP at the beginning of its output.  */
     37      1.1  christos const char line_comment_chars[]   = "#";
     38  1.1.1.2  christos /* Use something that isn't going to be needed by any expressions or
     39  1.1.1.2  christos    other syntax.  */
     40  1.1.1.2  christos const char line_separator_chars[] = "@";
     41      1.1  christos 
     42      1.1  christos const char EXP_CHARS[]            = "eE";
     43      1.1  christos const char FLT_CHARS[]            = "dD";
     44      1.1  christos 
     45  1.1.1.2  christos /* ELF flags to set in the output file header.  */
     46  1.1.1.2  christos static int elf_flags = 0;
     47  1.1.1.2  christos 
     48      1.1  christos /*------------------------------------------------------------------*/
     49      1.1  christos 
     50      1.1  christos char * rl78_lex_start;
     51      1.1  christos char * rl78_lex_end;
     52      1.1  christos 
     53      1.1  christos typedef struct rl78_bytesT
     54      1.1  christos {
     55      1.1  christos   char prefix[1];
     56      1.1  christos   int n_prefix;
     57      1.1  christos   char base[4];
     58      1.1  christos   int n_base;
     59      1.1  christos   char ops[8];
     60      1.1  christos   int n_ops;
     61      1.1  christos   struct
     62      1.1  christos   {
     63      1.1  christos     expressionS  exp;
     64      1.1  christos     char         offset;
     65      1.1  christos     char         nbits;
     66      1.1  christos     char         type; /* RL78REL_*.  */
     67      1.1  christos     int          reloc;
     68      1.1  christos     fixS *       fixP;
     69      1.1  christos   } fixups[2];
     70      1.1  christos   int n_fixups;
     71      1.1  christos   struct
     72      1.1  christos   {
     73      1.1  christos     char type;
     74      1.1  christos     char field_pos;
     75      1.1  christos     char val_ofs;
     76      1.1  christos   } relax[2];
     77      1.1  christos   int n_relax;
     78      1.1  christos   int link_relax;
     79      1.1  christos   fixS *link_relax_fixP;
     80      1.1  christos   char times_grown;
     81      1.1  christos   char times_shrank;
     82      1.1  christos } rl78_bytesT;
     83      1.1  christos 
     84      1.1  christos static rl78_bytesT rl78_bytes;
     85      1.1  christos 
     86      1.1  christos void
     87  1.1.1.2  christos rl78_relax (int type, int pos)
     88  1.1.1.2  christos {
     89  1.1.1.2  christos   rl78_bytes.relax[rl78_bytes.n_relax].type = type;
     90  1.1.1.2  christos   rl78_bytes.relax[rl78_bytes.n_relax].field_pos = pos;
     91  1.1.1.2  christos   rl78_bytes.relax[rl78_bytes.n_relax].val_ofs = rl78_bytes.n_base + rl78_bytes.n_ops;
     92  1.1.1.2  christos   rl78_bytes.n_relax ++;
     93  1.1.1.2  christos }
     94  1.1.1.2  christos 
     95  1.1.1.2  christos void
     96      1.1  christos rl78_linkrelax_addr16 (void)
     97      1.1  christos {
     98      1.1  christos   rl78_bytes.link_relax |= RL78_RELAXA_ADDR16;
     99      1.1  christos }
    100      1.1  christos 
    101      1.1  christos void
    102      1.1  christos rl78_linkrelax_branch (void)
    103      1.1  christos {
    104  1.1.1.3  christos   rl78_relax (RL78_RELAX_BRANCH, 0);
    105      1.1  christos   rl78_bytes.link_relax |= RL78_RELAXA_BRA;
    106      1.1  christos }
    107      1.1  christos 
    108      1.1  christos static void
    109      1.1  christos rl78_fixup (expressionS exp, int offsetbits, int nbits, int type)
    110      1.1  christos {
    111      1.1  christos   rl78_bytes.fixups[rl78_bytes.n_fixups].exp = exp;
    112      1.1  christos   rl78_bytes.fixups[rl78_bytes.n_fixups].offset = offsetbits;
    113      1.1  christos   rl78_bytes.fixups[rl78_bytes.n_fixups].nbits = nbits;
    114      1.1  christos   rl78_bytes.fixups[rl78_bytes.n_fixups].type = type;
    115      1.1  christos   rl78_bytes.fixups[rl78_bytes.n_fixups].reloc = exp.X_md;
    116      1.1  christos   rl78_bytes.n_fixups ++;
    117      1.1  christos }
    118      1.1  christos 
    119      1.1  christos #define rl78_field_fixup(exp, offset, nbits, type)	\
    120      1.1  christos   rl78_fixup (exp, offset + 8 * rl78_bytes.n_prefix), nbits, type)
    121      1.1  christos 
    122      1.1  christos #define rl78_op_fixup(exp, offset, nbits, type)		\
    123      1.1  christos   rl78_fixup (exp, offset + 8 * (rl78_bytes.n_prefix + rl78_bytes.n_base), nbits, type)
    124      1.1  christos 
    125      1.1  christos void
    126      1.1  christos rl78_prefix (int p)
    127      1.1  christos {
    128      1.1  christos   rl78_bytes.prefix[0] = p;
    129      1.1  christos   rl78_bytes.n_prefix = 1;
    130      1.1  christos }
    131      1.1  christos 
    132      1.1  christos int
    133  1.1.1.3  christos rl78_has_prefix (void)
    134      1.1  christos {
    135      1.1  christos   return rl78_bytes.n_prefix;
    136      1.1  christos }
    137      1.1  christos 
    138      1.1  christos void
    139      1.1  christos rl78_base1 (int b1)
    140      1.1  christos {
    141      1.1  christos   rl78_bytes.base[0] = b1;
    142      1.1  christos   rl78_bytes.n_base = 1;
    143      1.1  christos }
    144      1.1  christos 
    145      1.1  christos void
    146      1.1  christos rl78_base2 (int b1, int b2)
    147      1.1  christos {
    148      1.1  christos   rl78_bytes.base[0] = b1;
    149      1.1  christos   rl78_bytes.base[1] = b2;
    150      1.1  christos   rl78_bytes.n_base = 2;
    151      1.1  christos }
    152      1.1  christos 
    153      1.1  christos void
    154      1.1  christos rl78_base3 (int b1, int b2, int b3)
    155      1.1  christos {
    156      1.1  christos   rl78_bytes.base[0] = b1;
    157      1.1  christos   rl78_bytes.base[1] = b2;
    158      1.1  christos   rl78_bytes.base[2] = b3;
    159      1.1  christos   rl78_bytes.n_base = 3;
    160      1.1  christos }
    161      1.1  christos 
    162      1.1  christos void
    163      1.1  christos rl78_base4 (int b1, int b2, int b3, int b4)
    164      1.1  christos {
    165      1.1  christos   rl78_bytes.base[0] = b1;
    166      1.1  christos   rl78_bytes.base[1] = b2;
    167      1.1  christos   rl78_bytes.base[2] = b3;
    168      1.1  christos   rl78_bytes.base[3] = b4;
    169      1.1  christos   rl78_bytes.n_base = 4;
    170      1.1  christos }
    171      1.1  christos 
    172      1.1  christos #define F_PRECISION 2
    173      1.1  christos 
    174      1.1  christos void
    175      1.1  christos rl78_op (expressionS exp, int nbytes, int type)
    176      1.1  christos {
    177      1.1  christos   int v = 0;
    178      1.1  christos 
    179      1.1  christos   if ((exp.X_op == O_constant || exp.X_op == O_big)
    180      1.1  christos       && type != RL78REL_PCREL)
    181      1.1  christos     {
    182      1.1  christos       if (exp.X_op == O_big && exp.X_add_number <= 0)
    183      1.1  christos 	{
    184      1.1  christos 	  LITTLENUM_TYPE w[2];
    185      1.1  christos 	  char * ip = rl78_bytes.ops + rl78_bytes.n_ops;
    186      1.1  christos 
    187      1.1  christos 	  gen_to_words (w, F_PRECISION, 8);
    188      1.1  christos 	  ip[3] = w[0] >> 8;
    189      1.1  christos 	  ip[2] = w[0];
    190      1.1  christos 	  ip[1] = w[1] >> 8;
    191      1.1  christos 	  ip[0] = w[1];
    192      1.1  christos 	  rl78_bytes.n_ops += 4;
    193      1.1  christos 	}
    194      1.1  christos       else
    195      1.1  christos 	{
    196      1.1  christos 	  v = exp.X_add_number;
    197      1.1  christos 	  while (nbytes)
    198      1.1  christos 	    {
    199      1.1  christos 	      rl78_bytes.ops[rl78_bytes.n_ops++] =v & 0xff;
    200      1.1  christos 	      v >>= 8;
    201      1.1  christos 	      nbytes --;
    202      1.1  christos 	    }
    203      1.1  christos 	}
    204      1.1  christos     }
    205      1.1  christos   else
    206      1.1  christos     {
    207  1.1.1.2  christos       if (nbytes > 2
    208  1.1.1.2  christos 	  && exp.X_md == BFD_RELOC_RL78_CODE)
    209  1.1.1.2  christos 	exp.X_md = 0;
    210  1.1.1.2  christos 
    211  1.1.1.2  christos       if (nbytes == 1
    212  1.1.1.2  christos 	  && (exp.X_md == BFD_RELOC_RL78_LO16
    213  1.1.1.2  christos 	      || exp.X_md == BFD_RELOC_RL78_HI16))
    214  1.1.1.2  christos 	as_bad (_("16-bit relocation used in 8-bit operand"));
    215  1.1.1.2  christos 
    216  1.1.1.2  christos       if (nbytes == 2
    217  1.1.1.2  christos 	  && exp.X_md == BFD_RELOC_RL78_HI8)
    218  1.1.1.2  christos 	as_bad (_("8-bit relocation used in 16-bit operand"));
    219  1.1.1.2  christos 
    220      1.1  christos       rl78_op_fixup (exp, rl78_bytes.n_ops * 8, nbytes * 8, type);
    221      1.1  christos       memset (rl78_bytes.ops + rl78_bytes.n_ops, 0, nbytes);
    222      1.1  christos       rl78_bytes.n_ops += nbytes;
    223      1.1  christos     }
    224      1.1  christos }
    225      1.1  christos 
    226      1.1  christos /* This gets complicated when the field spans bytes, because fields
    227      1.1  christos    are numbered from the MSB of the first byte as zero, and bits are
    228      1.1  christos    stored LSB towards the LSB of the byte.  Thus, a simple four-bit
    229      1.1  christos    insertion of 12 at position 4 of 0x00 yields: 0x0b.  A three-bit
    230      1.1  christos    insertion of b'MXL at position 7 is like this:
    231      1.1  christos 
    232      1.1  christos      - - - -  - - - -   - - - -  - - - -
    233      1.1  christos                     M   X L               */
    234      1.1  christos 
    235      1.1  christos void
    236      1.1  christos rl78_field (int val, int pos, int sz)
    237      1.1  christos {
    238      1.1  christos   int valm;
    239      1.1  christos   int bytep, bitp;
    240      1.1  christos 
    241      1.1  christos   if (sz > 0)
    242      1.1  christos     {
    243      1.1  christos       if (val < 0 || val >= (1 << sz))
    244      1.1  christos 	as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz);
    245      1.1  christos     }
    246      1.1  christos   else
    247      1.1  christos     {
    248      1.1  christos       sz = - sz;
    249      1.1  christos       if (val < -(1 << (sz - 1)) || val >= (1 << (sz - 1)))
    250      1.1  christos 	as_bad (_("Value %d doesn't fit in signed %d-bit field"), val, sz);
    251      1.1  christos     }
    252      1.1  christos 
    253      1.1  christos   /* This code points at 'M' in the above example.  */
    254      1.1  christos   bytep = pos / 8;
    255      1.1  christos   bitp = pos % 8;
    256      1.1  christos 
    257      1.1  christos   while (bitp + sz > 8)
    258      1.1  christos     {
    259      1.1  christos       int ssz = 8 - bitp;
    260      1.1  christos       int svalm;
    261      1.1  christos 
    262      1.1  christos       svalm = val >> (sz - ssz);
    263      1.1  christos       svalm = svalm & ((1 << ssz) - 1);
    264      1.1  christos       svalm = svalm << (8 - bitp - ssz);
    265      1.1  christos       gas_assert (bytep < rl78_bytes.n_base);
    266      1.1  christos       rl78_bytes.base[bytep] |= svalm;
    267      1.1  christos 
    268      1.1  christos       bitp = 0;
    269      1.1  christos       sz -= ssz;
    270      1.1  christos       bytep ++;
    271      1.1  christos     }
    272      1.1  christos   valm = val & ((1 << sz) - 1);
    273      1.1  christos   valm = valm << (8 - bitp - sz);
    274      1.1  christos   gas_assert (bytep < rl78_bytes.n_base);
    275      1.1  christos   rl78_bytes.base[bytep] |= valm;
    276      1.1  christos }
    277      1.1  christos 
    278      1.1  christos /*------------------------------------------------------------------*/
    279      1.1  christos 
    280      1.1  christos enum options
    281      1.1  christos {
    282      1.1  christos   OPTION_RELAX = OPTION_MD_BASE,
    283  1.1.1.3  christos   OPTION_NORELAX,
    284  1.1.1.2  christos   OPTION_G10,
    285  1.1.1.2  christos   OPTION_G13,
    286  1.1.1.2  christos   OPTION_G14,
    287  1.1.1.2  christos   OPTION_32BIT_DOUBLES,
    288  1.1.1.2  christos   OPTION_64BIT_DOUBLES,
    289      1.1  christos };
    290      1.1  christos 
    291      1.1  christos #define RL78_SHORTOPTS ""
    292      1.1  christos const char * md_shortopts = RL78_SHORTOPTS;
    293      1.1  christos 
    294      1.1  christos /* Assembler options.  */
    295      1.1  christos struct option md_longopts[] =
    296      1.1  christos {
    297      1.1  christos   {"relax", no_argument, NULL, OPTION_RELAX},
    298  1.1.1.3  christos   {"norelax", no_argument, NULL, OPTION_NORELAX},
    299  1.1.1.2  christos   {"mg10", no_argument, NULL, OPTION_G10},
    300  1.1.1.2  christos   {"mg13", no_argument, NULL, OPTION_G13},
    301  1.1.1.2  christos   {"mg14", no_argument, NULL, OPTION_G14},
    302  1.1.1.2  christos   {"mrl78", no_argument, NULL, OPTION_G14},
    303  1.1.1.2  christos   {"m32bit-doubles", no_argument, NULL, OPTION_32BIT_DOUBLES},
    304  1.1.1.2  christos   {"m64bit-doubles", no_argument, NULL, OPTION_64BIT_DOUBLES},
    305      1.1  christos   {NULL, no_argument, NULL, 0}
    306      1.1  christos };
    307      1.1  christos size_t md_longopts_size = sizeof (md_longopts);
    308      1.1  christos 
    309      1.1  christos int
    310  1.1.1.3  christos md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
    311      1.1  christos {
    312      1.1  christos   switch (c)
    313      1.1  christos     {
    314      1.1  christos     case OPTION_RELAX:
    315      1.1  christos       linkrelax = 1;
    316      1.1  christos       return 1;
    317  1.1.1.3  christos     case OPTION_NORELAX:
    318  1.1.1.3  christos       linkrelax = 0;
    319  1.1.1.3  christos       return 1;
    320      1.1  christos 
    321  1.1.1.2  christos     case OPTION_G10:
    322  1.1.1.2  christos       elf_flags &= ~ E_FLAG_RL78_CPU_MASK;
    323  1.1.1.2  christos       elf_flags |= E_FLAG_RL78_G10;
    324  1.1.1.2  christos       return 1;
    325  1.1.1.2  christos 
    326  1.1.1.2  christos     case OPTION_G13:
    327  1.1.1.2  christos       elf_flags &= ~ E_FLAG_RL78_CPU_MASK;
    328  1.1.1.2  christos       elf_flags |= E_FLAG_RL78_G13;
    329  1.1.1.2  christos       return 1;
    330  1.1.1.2  christos 
    331  1.1.1.2  christos     case OPTION_G14:
    332  1.1.1.2  christos       elf_flags &= ~ E_FLAG_RL78_CPU_MASK;
    333  1.1.1.2  christos       elf_flags |= E_FLAG_RL78_G14;
    334  1.1.1.2  christos       return 1;
    335  1.1.1.2  christos 
    336  1.1.1.2  christos     case OPTION_32BIT_DOUBLES:
    337  1.1.1.2  christos       elf_flags &= ~ E_FLAG_RL78_64BIT_DOUBLES;
    338  1.1.1.2  christos       return 1;
    339  1.1.1.2  christos 
    340  1.1.1.2  christos     case OPTION_64BIT_DOUBLES:
    341  1.1.1.2  christos       elf_flags |= E_FLAG_RL78_64BIT_DOUBLES;
    342  1.1.1.2  christos       return 1;
    343      1.1  christos     }
    344      1.1  christos   return 0;
    345      1.1  christos }
    346      1.1  christos 
    347  1.1.1.2  christos int
    348  1.1.1.2  christos rl78_isa_g10 (void)
    349      1.1  christos {
    350  1.1.1.2  christos   return (elf_flags & E_FLAG_RL78_CPU_MASK) == E_FLAG_RL78_G10;
    351      1.1  christos }
    352      1.1  christos 
    353  1.1.1.2  christos int
    354  1.1.1.2  christos rl78_isa_g13 (void)
    355  1.1.1.2  christos {
    356  1.1.1.2  christos   return (elf_flags & E_FLAG_RL78_CPU_MASK) == E_FLAG_RL78_G13;
    357  1.1.1.2  christos }
    358  1.1.1.2  christos 
    359  1.1.1.2  christos int
    360  1.1.1.2  christos rl78_isa_g14 (void)
    361  1.1.1.2  christos {
    362  1.1.1.2  christos   return (elf_flags & E_FLAG_RL78_CPU_MASK) == E_FLAG_RL78_G14;
    363  1.1.1.2  christos }
    364  1.1.1.2  christos 
    365  1.1.1.2  christos void
    366  1.1.1.2  christos md_show_usage (FILE * stream)
    367  1.1.1.2  christos {
    368  1.1.1.2  christos   fprintf (stream, _(" RL78 specific command line options:\n"));
    369  1.1.1.2  christos   fprintf (stream, _("  --mrelax          Enable link time relaxation\n"));
    370  1.1.1.2  christos   fprintf (stream, _("  --mg10            Enable support for G10 variant\n"));
    371  1.1.1.2  christos   fprintf (stream, _("  --mg13            Selects the G13 core.\n"));
    372  1.1.1.2  christos   fprintf (stream, _("  --mg14            Selects the G14 core [default]\n"));
    373  1.1.1.2  christos   fprintf (stream, _("  --mrl78           Alias for --mg14\n"));
    374  1.1.1.2  christos   fprintf (stream, _("  --m32bit-doubles  [default]\n"));
    375  1.1.1.2  christos   fprintf (stream, _("  --m64bit-doubles  Source code uses 64-bit doubles\n"));
    376  1.1.1.2  christos }
    377      1.1  christos 
    378      1.1  christos static void
    379      1.1  christos s_bss (int ignore ATTRIBUTE_UNUSED)
    380      1.1  christos {
    381      1.1  christos   int temp;
    382      1.1  christos 
    383      1.1  christos   temp = get_absolute_expression ();
    384      1.1  christos   subseg_set (bss_section, (subsegT) temp);
    385      1.1  christos   demand_empty_rest_of_line ();
    386      1.1  christos }
    387      1.1  christos 
    388  1.1.1.2  christos static void
    389  1.1.1.2  christos rl78_float_cons (int ignore ATTRIBUTE_UNUSED)
    390  1.1.1.2  christos {
    391  1.1.1.2  christos   if (elf_flags & E_FLAG_RL78_64BIT_DOUBLES)
    392  1.1.1.2  christos     return float_cons ('d');
    393  1.1.1.2  christos   return float_cons ('f');
    394  1.1.1.2  christos }
    395  1.1.1.2  christos 
    396      1.1  christos /* The target specific pseudo-ops which we support.  */
    397      1.1  christos const pseudo_typeS md_pseudo_table[] =
    398      1.1  christos {
    399  1.1.1.2  christos   /* Our "standard" pseudos.  */
    400  1.1.1.2  christos   { "double", rl78_float_cons,	'd' },
    401  1.1.1.2  christos   { "bss",    s_bss, 		0 },
    402  1.1.1.2  christos   { "3byte",  cons,		3 },
    403  1.1.1.2  christos   { "int",    cons,		4 },
    404  1.1.1.2  christos   { "word",   cons,		4 },
    405      1.1  christos 
    406      1.1  christos   /* End of list marker.  */
    407      1.1  christos   { NULL, 	NULL, 		0 }
    408      1.1  christos };
    409      1.1  christos 
    410  1.1.1.2  christos static symbolS * rl78_abs_sym = NULL;
    411  1.1.1.2  christos 
    412      1.1  christos void
    413      1.1  christos md_begin (void)
    414      1.1  christos {
    415  1.1.1.2  christos   rl78_abs_sym = symbol_make ("__rl78_abs__");
    416      1.1  christos }
    417      1.1  christos 
    418      1.1  christos void
    419      1.1  christos rl78_md_end (void)
    420      1.1  christos {
    421      1.1  christos }
    422      1.1  christos 
    423  1.1.1.2  christos /* Set the ELF specific flags.  */
    424  1.1.1.2  christos void
    425  1.1.1.2  christos rl78_elf_final_processing (void)
    426  1.1.1.2  christos {
    427  1.1.1.2  christos   elf_elfheader (stdoutput)->e_flags |= elf_flags;
    428  1.1.1.2  christos }
    429  1.1.1.2  christos 
    430      1.1  christos /* Write a value out to the object file, using the appropriate endianness.  */
    431      1.1  christos void
    432      1.1  christos md_number_to_chars (char * buf, valueT val, int n)
    433      1.1  christos {
    434      1.1  christos   number_to_chars_littleendian (buf, val, n);
    435      1.1  christos }
    436      1.1  christos 
    437  1.1.1.2  christos static void
    438  1.1.1.3  christos require_end_of_expr (const char *fname)
    439  1.1.1.2  christos {
    440  1.1.1.2  christos   while (* input_line_pointer == ' '
    441  1.1.1.2  christos 	 || * input_line_pointer == '\t')
    442  1.1.1.2  christos     input_line_pointer ++;
    443  1.1.1.2  christos 
    444  1.1.1.2  christos   if (! * input_line_pointer
    445  1.1.1.2  christos       || strchr ("\n\r,", * input_line_pointer)
    446  1.1.1.2  christos       || strchr (comment_chars, * input_line_pointer)
    447  1.1.1.2  christos       || strchr (line_comment_chars, * input_line_pointer)
    448  1.1.1.2  christos       || strchr (line_separator_chars, * input_line_pointer))
    449  1.1.1.2  christos     return;
    450  1.1.1.2  christos 
    451  1.1.1.2  christos   as_bad (_("%%%s() must be outermost term in expression"), fname);
    452  1.1.1.2  christos }
    453  1.1.1.2  christos 
    454      1.1  christos static struct
    455      1.1  christos {
    456  1.1.1.3  christos   const char * fname;
    457      1.1  christos   int    reloc;
    458      1.1  christos }
    459      1.1  christos reloc_functions[] =
    460      1.1  christos {
    461  1.1.1.2  christos   { "code", BFD_RELOC_RL78_CODE },
    462      1.1  christos   { "lo16", BFD_RELOC_RL78_LO16 },
    463      1.1  christos   { "hi16", BFD_RELOC_RL78_HI16 },
    464      1.1  christos   { "hi8",  BFD_RELOC_RL78_HI8 },
    465      1.1  christos   { 0, 0 }
    466      1.1  christos };
    467      1.1  christos 
    468      1.1  christos void
    469      1.1  christos md_operand (expressionS * exp ATTRIBUTE_UNUSED)
    470      1.1  christos {
    471      1.1  christos   int reloc = 0;
    472      1.1  christos   int i;
    473      1.1  christos 
    474      1.1  christos   for (i = 0; reloc_functions[i].fname; i++)
    475      1.1  christos     {
    476      1.1  christos       int flen = strlen (reloc_functions[i].fname);
    477      1.1  christos 
    478      1.1  christos       if (input_line_pointer[0] == '%'
    479      1.1  christos 	  && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
    480      1.1  christos 	  && input_line_pointer[flen + 1] == '(')
    481      1.1  christos 	{
    482      1.1  christos 	  reloc = reloc_functions[i].reloc;
    483      1.1  christos 	  input_line_pointer += flen + 2;
    484      1.1  christos 	  break;
    485      1.1  christos 	}
    486      1.1  christos     }
    487      1.1  christos   if (reloc == 0)
    488      1.1  christos     return;
    489      1.1  christos 
    490      1.1  christos   expression (exp);
    491      1.1  christos   if (* input_line_pointer == ')')
    492      1.1  christos     input_line_pointer ++;
    493      1.1  christos 
    494      1.1  christos   exp->X_md = reloc;
    495  1.1.1.2  christos 
    496  1.1.1.2  christos   require_end_of_expr (reloc_functions[i].fname);
    497      1.1  christos }
    498      1.1  christos 
    499      1.1  christos void
    500      1.1  christos rl78_frag_init (fragS * fragP)
    501      1.1  christos {
    502      1.1  christos   if (rl78_bytes.n_relax || rl78_bytes.link_relax)
    503      1.1  christos     {
    504  1.1.1.3  christos       fragP->tc_frag_data = XNEW (rl78_bytesT);
    505      1.1  christos       memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT));
    506      1.1  christos     }
    507      1.1  christos   else
    508      1.1  christos     fragP->tc_frag_data = 0;
    509      1.1  christos }
    510      1.1  christos 
    511      1.1  christos /* When relaxing, we need to output a reloc for any .align directive
    512      1.1  christos    so that we can retain this alignment as we adjust opcode sizes.  */
    513      1.1  christos void
    514      1.1  christos rl78_handle_align (fragS * frag)
    515      1.1  christos {
    516      1.1  christos   if (linkrelax
    517      1.1  christos       && (frag->fr_type == rs_align
    518      1.1  christos 	  || frag->fr_type == rs_align_code)
    519      1.1  christos       && frag->fr_address + frag->fr_fix > 0
    520      1.1  christos       && frag->fr_offset > 0
    521      1.1  christos       && now_seg != bss_section)
    522      1.1  christos     {
    523      1.1  christos       fix_new (frag, frag->fr_fix, 0,
    524      1.1  christos 	       &abs_symbol, RL78_RELAXA_ALIGN + frag->fr_offset,
    525      1.1  christos 	       0, BFD_RELOC_RL78_RELAX);
    526      1.1  christos       /* For the purposes of relaxation, this relocation is attached
    527      1.1  christos 	 to the byte *after* the alignment - i.e. the byte that must
    528      1.1  christos 	 remain aligned.  */
    529      1.1  christos       fix_new (frag->fr_next, 0, 0,
    530      1.1  christos 	       &abs_symbol, RL78_RELAXA_ELIGN + frag->fr_offset,
    531      1.1  christos 	       0, BFD_RELOC_RL78_RELAX);
    532      1.1  christos     }
    533      1.1  christos }
    534      1.1  christos 
    535  1.1.1.3  christos const char *
    536      1.1  christos md_atof (int type, char * litP, int * sizeP)
    537      1.1  christos {
    538      1.1  christos   return ieee_md_atof (type, litP, sizeP, target_big_endian);
    539      1.1  christos }
    540      1.1  christos 
    541      1.1  christos symbolS *
    542      1.1  christos md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
    543      1.1  christos {
    544      1.1  christos   return NULL;
    545      1.1  christos }
    546      1.1  christos 
    547      1.1  christos #define APPEND(B, N_B)				       \
    548      1.1  christos   if (rl78_bytes.N_B)				       \
    549      1.1  christos     {						       \
    550      1.1  christos       memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B);  \
    551      1.1  christos       idx += rl78_bytes.N_B;			       \
    552      1.1  christos     }
    553      1.1  christos 
    554      1.1  christos 
    555      1.1  christos void
    556      1.1  christos md_assemble (char * str)
    557      1.1  christos {
    558      1.1  christos   char * bytes;
    559      1.1  christos   fragS * frag_then = frag_now;
    560      1.1  christos   int idx = 0;
    561      1.1  christos   int i;
    562      1.1  christos   int rel;
    563      1.1  christos   expressionS  *exp;
    564      1.1  christos 
    565      1.1  christos   /*printf("\033[32mASM: %s\033[0m\n", str);*/
    566      1.1  christos 
    567      1.1  christos   dwarf2_emit_insn (0);
    568      1.1  christos 
    569      1.1  christos   memset (& rl78_bytes, 0, sizeof (rl78_bytes));
    570      1.1  christos 
    571      1.1  christos   rl78_lex_init (str, str + strlen (str));
    572      1.1  christos 
    573      1.1  christos   rl78_parse ();
    574      1.1  christos 
    575      1.1  christos   /* This simplifies the relaxation code.  */
    576  1.1.1.2  christos   if (rl78_bytes.n_relax || rl78_bytes.link_relax)
    577      1.1  christos     {
    578      1.1  christos       int olen = rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops;
    579      1.1  christos       /* We do it this way because we want the frag to have the
    580  1.1.1.2  christos 	 rl78_bytes in it, which we initialize above.  The extra bytes
    581  1.1.1.2  christos 	 are for relaxing.  */
    582  1.1.1.2  christos       bytes = frag_more (olen + 3);
    583      1.1  christos       frag_then = frag_now;
    584      1.1  christos       frag_variant (rs_machine_dependent,
    585      1.1  christos 		    olen /* max_chars */,
    586      1.1  christos 		    0 /* var */,
    587      1.1  christos 		    olen /* subtype */,
    588      1.1  christos 		    0 /* symbol */,
    589      1.1  christos 		    0 /* offset */,
    590      1.1  christos 		    0 /* opcode */);
    591      1.1  christos       frag_then->fr_opcode = bytes;
    592      1.1  christos       frag_then->fr_fix = olen + (bytes - frag_then->fr_literal);
    593      1.1  christos       frag_then->fr_subtype = olen;
    594      1.1  christos       frag_then->fr_var = 0;
    595      1.1  christos     }
    596      1.1  christos   else
    597      1.1  christos     {
    598      1.1  christos       bytes = frag_more (rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops);
    599      1.1  christos       frag_then = frag_now;
    600      1.1  christos     }
    601      1.1  christos 
    602      1.1  christos   APPEND (prefix, n_prefix);
    603      1.1  christos   APPEND (base, n_base);
    604      1.1  christos   APPEND (ops, n_ops);
    605      1.1  christos 
    606      1.1  christos   if (rl78_bytes.link_relax)
    607      1.1  christos     {
    608      1.1  christos       fixS * f;
    609      1.1  christos 
    610      1.1  christos       f = fix_new (frag_then,
    611      1.1  christos 		   (char *) bytes - frag_then->fr_literal,
    612      1.1  christos 		   0,
    613      1.1  christos 		   abs_section_sym,
    614      1.1  christos 		   rl78_bytes.link_relax | rl78_bytes.n_fixups,
    615      1.1  christos 		   0,
    616      1.1  christos 		   BFD_RELOC_RL78_RELAX);
    617      1.1  christos       frag_then->tc_frag_data->link_relax_fixP = f;
    618      1.1  christos     }
    619      1.1  christos 
    620      1.1  christos   for (i = 0; i < rl78_bytes.n_fixups; i ++)
    621      1.1  christos     {
    622      1.1  christos       /* index: [nbytes][type] */
    623      1.1  christos       static int reloc_map[5][4] =
    624      1.1  christos 	{
    625      1.1  christos 	  { 0,            0 },
    626      1.1  christos 	  { BFD_RELOC_8,  BFD_RELOC_8_PCREL },
    627      1.1  christos 	  { BFD_RELOC_16, BFD_RELOC_16_PCREL },
    628      1.1  christos 	  { BFD_RELOC_24, BFD_RELOC_24_PCREL },
    629      1.1  christos 	  { BFD_RELOC_32, BFD_RELOC_32_PCREL },
    630      1.1  christos 	};
    631      1.1  christos       fixS * f;
    632      1.1  christos 
    633      1.1  christos       idx = rl78_bytes.fixups[i].offset / 8;
    634      1.1  christos       rel = reloc_map [rl78_bytes.fixups[i].nbits / 8][(int) rl78_bytes.fixups[i].type];
    635      1.1  christos 
    636      1.1  christos       if (rl78_bytes.fixups[i].reloc)
    637      1.1  christos 	rel = rl78_bytes.fixups[i].reloc;
    638      1.1  christos 
    639      1.1  christos       if (frag_then->tc_frag_data)
    640      1.1  christos 	exp = & frag_then->tc_frag_data->fixups[i].exp;
    641      1.1  christos       else
    642      1.1  christos 	exp = & rl78_bytes.fixups[i].exp;
    643      1.1  christos 
    644      1.1  christos       f = fix_new_exp (frag_then,
    645      1.1  christos 		       (char *) bytes + idx - frag_then->fr_literal,
    646      1.1  christos 		       rl78_bytes.fixups[i].nbits / 8,
    647      1.1  christos 		       exp,
    648      1.1  christos 		       rl78_bytes.fixups[i].type == RL78REL_PCREL ? 1 : 0,
    649      1.1  christos 		       rel);
    650      1.1  christos       if (frag_then->tc_frag_data)
    651      1.1  christos 	frag_then->tc_frag_data->fixups[i].fixP = f;
    652      1.1  christos     }
    653      1.1  christos }
    654      1.1  christos 
    655      1.1  christos void
    656      1.1  christos rl78_cons_fix_new (fragS *	frag,
    657      1.1  christos 		 int		where,
    658      1.1  christos 		 int		size,
    659      1.1  christos 		 expressionS *  exp)
    660      1.1  christos {
    661      1.1  christos   bfd_reloc_code_real_type type;
    662  1.1.1.2  christos   fixS *fixP;
    663      1.1  christos 
    664      1.1  christos   switch (size)
    665      1.1  christos     {
    666      1.1  christos     case 1:
    667      1.1  christos       type = BFD_RELOC_8;
    668      1.1  christos       break;
    669      1.1  christos     case 2:
    670      1.1  christos       type = BFD_RELOC_16;
    671      1.1  christos       break;
    672      1.1  christos     case 3:
    673      1.1  christos       type = BFD_RELOC_24;
    674      1.1  christos       break;
    675      1.1  christos     case 4:
    676      1.1  christos       type = BFD_RELOC_32;
    677      1.1  christos       break;
    678      1.1  christos     default:
    679      1.1  christos       as_bad (_("unsupported constant size %d\n"), size);
    680      1.1  christos       return;
    681      1.1  christos     }
    682      1.1  christos 
    683  1.1.1.2  christos   switch (exp->X_md)
    684  1.1.1.2  christos     {
    685  1.1.1.2  christos     case BFD_RELOC_RL78_CODE:
    686  1.1.1.2  christos       if (size == 2)
    687  1.1.1.2  christos 	type = exp->X_md;
    688  1.1.1.2  christos       break;
    689  1.1.1.2  christos     case BFD_RELOC_RL78_LO16:
    690  1.1.1.2  christos     case BFD_RELOC_RL78_HI16:
    691  1.1.1.2  christos       if (size != 2)
    692  1.1.1.2  christos 	{
    693  1.1.1.2  christos 	  /* Fixups to assembler generated expressions do not use %hi or %lo.  */
    694  1.1.1.2  christos 	  if (frag->fr_file)
    695  1.1.1.2  christos 	    as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
    696  1.1.1.2  christos 	}
    697  1.1.1.2  christos       else
    698  1.1.1.2  christos 	type = exp->X_md;
    699  1.1.1.2  christos       break;
    700  1.1.1.2  christos     case BFD_RELOC_RL78_HI8:
    701  1.1.1.2  christos       if (size != 1)
    702  1.1.1.2  christos 	{
    703  1.1.1.2  christos 	  /* Fixups to assembler generated expressions do not use %hi or %lo.  */
    704  1.1.1.2  christos 	  if (frag->fr_file)
    705  1.1.1.2  christos 	    as_bad (_("%%hi8 only applies to .byte"));
    706  1.1.1.2  christos 	}
    707  1.1.1.2  christos       else
    708  1.1.1.2  christos 	type = exp->X_md;
    709  1.1.1.2  christos       break;
    710  1.1.1.2  christos     default:
    711  1.1.1.2  christos       break;
    712  1.1.1.2  christos     }
    713  1.1.1.2  christos 
    714      1.1  christos   if (exp->X_op == O_subtract && exp->X_op_symbol)
    715      1.1  christos     {
    716      1.1  christos       if (size != 4 && size != 2 && size != 1)
    717      1.1  christos 	as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
    718      1.1  christos       else
    719      1.1  christos 	type = BFD_RELOC_RL78_DIFF;
    720      1.1  christos     }
    721      1.1  christos 
    722  1.1.1.2  christos   fixP = fix_new_exp (frag, where, (int) size, exp, 0, type);
    723  1.1.1.2  christos   switch (exp->X_md)
    724  1.1.1.2  christos     {
    725  1.1.1.2  christos       /* These are intended to have values larger than the container,
    726  1.1.1.2  christos 	 since the backend puts only the portion we need in it.
    727  1.1.1.2  christos 	 However, we don't have a backend-specific reloc for them as
    728  1.1.1.2  christos 	 they're handled with complex relocations.  */
    729  1.1.1.2  christos     case BFD_RELOC_RL78_LO16:
    730  1.1.1.2  christos     case BFD_RELOC_RL78_HI16:
    731  1.1.1.2  christos     case BFD_RELOC_RL78_HI8:
    732  1.1.1.2  christos       fixP->fx_no_overflow = 1;
    733  1.1.1.2  christos       break;
    734  1.1.1.2  christos     default:
    735  1.1.1.2  christos       break;
    736  1.1.1.2  christos     }
    737  1.1.1.2  christos }
    738  1.1.1.2  christos 
    739  1.1.1.2  christos 
    740  1.1.1.2  christos /*----------------------------------------------------------------------*/
    742  1.1.1.2  christos /* To recap: we estimate everything based on md_estimate_size, then
    743  1.1.1.2  christos    adjust based on rl78_relax_frag.  When it all settles, we call
    744  1.1.1.2  christos    md_convert frag to update the bytes.  The relaxation types and
    745  1.1.1.2  christos    relocations are in fragP->tc_frag_data, which is a copy of that
    746  1.1.1.2  christos    rl78_bytes.
    747  1.1.1.2  christos 
    748  1.1.1.2  christos    Our scheme is as follows: fr_fix has the size of the smallest
    749  1.1.1.2  christos    opcode (like BRA.S).  We store the number of total bytes we need in
    750  1.1.1.2  christos    fr_subtype.  When we're done relaxing, we use fr_subtype and the
    751  1.1.1.2  christos    existing opcode bytes to figure out what actual opcode we need to
    752  1.1.1.2  christos    put in there.  If the fixup isn't resolvable now, we use the
    753  1.1.1.2  christos    maximal size.  */
    754  1.1.1.2  christos 
    755  1.1.1.2  christos #define TRACE_RELAX 0
    756  1.1.1.2  christos #define tprintf if (TRACE_RELAX) printf
    757  1.1.1.2  christos 
    758  1.1.1.2  christos 
    759  1.1.1.2  christos typedef enum
    760  1.1.1.2  christos {
    761  1.1.1.2  christos   OT_other,
    762  1.1.1.2  christos   OT_bt,
    763  1.1.1.2  christos   OT_bt_sfr,
    764  1.1.1.2  christos   OT_bt_es,
    765  1.1.1.3  christos   OT_bc,
    766  1.1.1.3  christos   OT_bh,
    767  1.1.1.3  christos   OT_sk,
    768  1.1.1.3  christos   OT_call,
    769  1.1.1.2  christos   OT_br,
    770  1.1.1.2  christos } op_type_T;
    771  1.1.1.2  christos 
    772  1.1.1.2  christos /* We're looking for these types of relaxations:
    773  1.1.1.2  christos 
    774  1.1.1.2  christos    BT		00110001 sbit0cc1 addr----	(cc is 10 (BF) or 01 (BT))
    775  1.1.1.2  christos    B~T		00110001 sbit0cc1 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
    776  1.1.1.2  christos 
    777  1.1.1.2  christos    BT sfr	00110001 sbit0cc0 sfr----- addr----
    778  1.1.1.2  christos    BT ES:	00010001 00101110 sbit0cc1 addr----
    779  1.1.1.2  christos 
    780  1.1.1.2  christos    BC		110111cc addr----
    781  1.1.1.2  christos    B~C		110111cc 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
    782  1.1.1.2  christos 
    783  1.1.1.2  christos    BH		01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
    784  1.1.1.2  christos    B~H		01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
    785  1.1.1.2  christos */
    786  1.1.1.2  christos 
    787  1.1.1.2  christos /* Given the opcode bytes at OP, figure out which opcode it is and
    788  1.1.1.2  christos    return the type of opcode.  We use this to re-encode the opcode as
    789  1.1.1.2  christos    a different size later.  */
    790  1.1.1.2  christos 
    791  1.1.1.3  christos static op_type_T
    792  1.1.1.2  christos rl78_opcode_type (char * ops)
    793  1.1.1.3  christos {
    794  1.1.1.3  christos   unsigned char *op = (unsigned char *)ops;
    795  1.1.1.2  christos 
    796  1.1.1.2  christos   if (op[0] == 0x31
    797  1.1.1.2  christos       && ((op[1] & 0x0f) == 0x05
    798  1.1.1.2  christos 	  || (op[1] & 0x0f) == 0x03))
    799  1.1.1.2  christos     return OT_bt;
    800  1.1.1.2  christos 
    801  1.1.1.2  christos   if (op[0] == 0x31
    802  1.1.1.2  christos       && ((op[1] & 0x0f) == 0x04
    803  1.1.1.2  christos 	  || (op[1] & 0x0f) == 0x02))
    804  1.1.1.2  christos     return OT_bt_sfr;
    805  1.1.1.2  christos 
    806  1.1.1.2  christos   if (op[0] == 0x11
    807  1.1.1.2  christos       && op[1] == 0x31
    808  1.1.1.2  christos       && ((op[2] & 0x0f) == 0x05
    809  1.1.1.2  christos 	  || (op[2] & 0x0f) == 0x03))
    810  1.1.1.2  christos     return OT_bt_es;
    811  1.1.1.2  christos 
    812  1.1.1.2  christos   if ((op[0] & 0xfc) == 0xdc)
    813  1.1.1.2  christos     return OT_bc;
    814  1.1.1.2  christos 
    815  1.1.1.2  christos   if (op[0] == 0x61
    816  1.1.1.2  christos       && (op[1] & 0xef) == 0xc3)
    817  1.1.1.2  christos     return OT_bh;
    818  1.1.1.3  christos 
    819  1.1.1.3  christos   if (op[0] == 0x61
    820  1.1.1.3  christos       && (op[1] & 0xcf) == 0xc8)
    821  1.1.1.3  christos     return OT_sk;
    822  1.1.1.3  christos 
    823  1.1.1.3  christos   if (op[0] == 0x61
    824  1.1.1.3  christos       && (op[1] & 0xef) == 0xe3)
    825  1.1.1.3  christos     return OT_sk;
    826  1.1.1.3  christos 
    827  1.1.1.3  christos   if (op[0] == 0xfc)
    828  1.1.1.3  christos     return OT_call;
    829  1.1.1.3  christos 
    830  1.1.1.3  christos   if ((op[0] & 0xec) == 0xec)
    831  1.1.1.3  christos     return OT_br;
    832  1.1.1.2  christos 
    833  1.1.1.2  christos   return OT_other;
    834  1.1.1.2  christos }
    835  1.1.1.2  christos 
    836  1.1.1.2  christos /* Returns zero if *addrP has the target address.  Else returns nonzero
    837  1.1.1.2  christos    if we cannot compute the target address yet.  */
    838  1.1.1.2  christos 
    839  1.1.1.2  christos static int
    840  1.1.1.2  christos rl78_frag_fix_value (fragS *    fragP,
    841  1.1.1.2  christos 		     segT       segment,
    842  1.1.1.2  christos 		     int        which,
    843  1.1.1.2  christos 		     addressT * addrP,
    844  1.1.1.2  christos 		     int        need_diff,
    845  1.1.1.2  christos 		     addressT * sym_addr)
    846  1.1.1.2  christos {
    847  1.1.1.2  christos   addressT addr = 0;
    848  1.1.1.2  christos   rl78_bytesT * b = fragP->tc_frag_data;
    849  1.1.1.2  christos   expressionS * exp = & b->fixups[which].exp;
    850  1.1.1.2  christos 
    851  1.1.1.2  christos   if (need_diff && exp->X_op != O_subtract)
    852  1.1.1.2  christos     return 1;
    853  1.1.1.2  christos 
    854  1.1.1.2  christos   if (exp->X_add_symbol)
    855  1.1.1.2  christos     {
    856  1.1.1.2  christos       if (S_FORCE_RELOC (exp->X_add_symbol, 1))
    857  1.1.1.2  christos 	return 1;
    858  1.1.1.2  christos       if (S_GET_SEGMENT (exp->X_add_symbol) != segment)
    859  1.1.1.2  christos 	return 1;
    860  1.1.1.2  christos       addr += S_GET_VALUE (exp->X_add_symbol);
    861  1.1.1.2  christos     }
    862  1.1.1.2  christos 
    863  1.1.1.2  christos   if (exp->X_op_symbol)
    864  1.1.1.2  christos     {
    865  1.1.1.2  christos       if (exp->X_op != O_subtract)
    866  1.1.1.2  christos 	return 1;
    867  1.1.1.2  christos       if (S_FORCE_RELOC (exp->X_op_symbol, 1))
    868  1.1.1.2  christos 	return 1;
    869  1.1.1.2  christos       if (S_GET_SEGMENT (exp->X_op_symbol) != segment)
    870  1.1.1.2  christos 	return 1;
    871  1.1.1.2  christos       addr -= S_GET_VALUE (exp->X_op_symbol);
    872  1.1.1.2  christos     }
    873  1.1.1.2  christos   if (sym_addr)
    874  1.1.1.2  christos     * sym_addr = addr;
    875  1.1.1.2  christos   addr += exp->X_add_number;
    876  1.1.1.2  christos   * addrP = addr;
    877      1.1  christos   return 0;
    878      1.1  christos }
    879  1.1.1.2  christos 
    880  1.1.1.2  christos /* Estimate how big the opcode is after this relax pass.  The return
    881  1.1.1.2  christos    value is the difference between fr_fix and the actual size.  We
    882  1.1.1.2  christos    compute the total size in rl78_relax_frag and store it in fr_subtype,
    883  1.1.1.2  christos    so we only need to subtract fx_fix and return it.  */
    884      1.1  christos 
    885      1.1  christos int
    886      1.1  christos md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
    887  1.1.1.2  christos {
    888  1.1.1.2  christos   int opfixsize;
    889  1.1.1.2  christos   int delta;
    890  1.1.1.2  christos 
    891  1.1.1.2  christos   /* This is the size of the opcode that's accounted for in fr_fix.  */
    892  1.1.1.2  christos   opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal);
    893  1.1.1.2  christos   /* This is the size of the opcode that isn't.  */
    894  1.1.1.2  christos   delta = (fragP->fr_subtype - opfixsize);
    895  1.1.1.2  christos 
    896  1.1.1.2  christos   tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta);
    897  1.1.1.2  christos   return delta;
    898  1.1.1.2  christos }
    899  1.1.1.2  christos 
    900  1.1.1.2  christos /* Given the new addresses for this relax pass, figure out how big
    901  1.1.1.2  christos    each opcode must be.  We store the total number of bytes needed in
    902  1.1.1.2  christos    fr_subtype.  The return value is the difference between the size
    903  1.1.1.2  christos    after the last pass and the size after this pass, so we use the old
    904  1.1.1.2  christos    fr_subtype to calculate the difference.  */
    905  1.1.1.2  christos 
    906  1.1.1.2  christos int
    907  1.1.1.2  christos rl78_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
    908  1.1.1.2  christos {
    909  1.1.1.2  christos   addressT addr0, sym_addr;
    910  1.1.1.2  christos   addressT mypc;
    911  1.1.1.2  christos   int disp;
    912  1.1.1.2  christos   int oldsize = fragP->fr_subtype;
    913  1.1.1.2  christos   int newsize = oldsize;
    914  1.1.1.2  christos   op_type_T optype;
    915  1.1.1.2  christos   int ri;
    916  1.1.1.2  christos 
    917  1.1.1.2  christos   mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
    918  1.1.1.2  christos 
    919  1.1.1.2  christos   /* If we ever get more than one reloc per opcode, this is the one
    920  1.1.1.2  christos      we're relaxing.  */
    921  1.1.1.2  christos   ri = 0;
    922  1.1.1.2  christos 
    923  1.1.1.2  christos   optype = rl78_opcode_type (fragP->fr_opcode);
    924  1.1.1.2  christos   /* Try to get the target address.  */
    925  1.1.1.2  christos   if (rl78_frag_fix_value (fragP, segment, ri, & addr0,
    926  1.1.1.2  christos 			   fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH,
    927  1.1.1.2  christos 			   & sym_addr))
    928  1.1.1.3  christos     {
    929  1.1.1.3  christos       /* If we don't expect the linker to do relaxing, don't emit
    930  1.1.1.3  christos 	 expanded opcodes that only the linker will relax.  */
    931  1.1.1.3  christos       if (!linkrelax)
    932  1.1.1.3  christos 	return newsize - oldsize;
    933  1.1.1.2  christos 
    934  1.1.1.2  christos       /* If we don't, we must use the maximum size for the linker.  */
    935  1.1.1.2  christos       switch (fragP->tc_frag_data->relax[ri].type)
    936  1.1.1.2  christos 	{
    937  1.1.1.2  christos 	case RL78_RELAX_BRANCH:
    938  1.1.1.2  christos 	  switch (optype)
    939  1.1.1.2  christos 	    {
    940  1.1.1.2  christos 	    case OT_bt:
    941  1.1.1.2  christos 	      newsize = 6;
    942  1.1.1.2  christos 	      break;
    943  1.1.1.2  christos 	    case OT_bt_sfr:
    944  1.1.1.2  christos 	    case OT_bt_es:
    945  1.1.1.2  christos 	      newsize = 7;
    946  1.1.1.2  christos 	      break;
    947  1.1.1.2  christos 	    case OT_bc:
    948  1.1.1.2  christos 	      newsize = 5;
    949  1.1.1.2  christos 	      break;
    950  1.1.1.2  christos 	    case OT_bh:
    951  1.1.1.2  christos 	      newsize = 6;
    952  1.1.1.3  christos 	      break;
    953  1.1.1.3  christos 	    case OT_sk:
    954  1.1.1.3  christos 	      newsize = 2;
    955  1.1.1.3  christos 	      break;
    956  1.1.1.2  christos 	    default:
    957  1.1.1.2  christos 	      newsize = oldsize;
    958  1.1.1.2  christos 	      break;
    959  1.1.1.2  christos 	    }
    960  1.1.1.2  christos 	  break;
    961  1.1.1.2  christos 
    962  1.1.1.2  christos 	}
    963  1.1.1.2  christos       fragP->fr_subtype = newsize;
    964  1.1.1.2  christos       tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize);
    965  1.1.1.2  christos       return newsize - oldsize;
    966  1.1.1.2  christos     }
    967  1.1.1.2  christos 
    968  1.1.1.2  christos   if (sym_addr > mypc)
    969  1.1.1.2  christos     addr0 += stretch;
    970  1.1.1.2  christos 
    971  1.1.1.2  christos   switch (fragP->tc_frag_data->relax[ri].type)
    972  1.1.1.2  christos     {
    973  1.1.1.2  christos     case  RL78_RELAX_BRANCH:
    974  1.1.1.2  christos       disp = (int) addr0 - (int) mypc;
    975  1.1.1.2  christos 
    976  1.1.1.2  christos       switch (optype)
    977  1.1.1.2  christos 	{
    978  1.1.1.2  christos 	case OT_bt:
    979  1.1.1.2  christos 	  if (disp >= -128 && (disp - (oldsize-2)) <= 127)
    980  1.1.1.2  christos 	    newsize = 3;
    981  1.1.1.2  christos 	  else
    982  1.1.1.2  christos 	    newsize = 6;
    983  1.1.1.2  christos 	  break;
    984  1.1.1.2  christos 	case OT_bt_sfr:
    985  1.1.1.2  christos 	case OT_bt_es:
    986  1.1.1.2  christos 	  if (disp >= -128 && (disp - (oldsize-3)) <= 127)
    987  1.1.1.2  christos 	    newsize = 4;
    988  1.1.1.2  christos 	  else
    989  1.1.1.2  christos 	    newsize = 7;
    990  1.1.1.2  christos 	  break;
    991  1.1.1.2  christos 	case OT_bc:
    992  1.1.1.2  christos 	  if (disp >= -128 && (disp - (oldsize-1)) <= 127)
    993  1.1.1.2  christos 	    newsize = 2;
    994  1.1.1.2  christos 	  else
    995  1.1.1.2  christos 	    newsize = 5;
    996  1.1.1.2  christos 	  break;
    997  1.1.1.2  christos 	case OT_bh:
    998  1.1.1.2  christos 	  if (disp >= -128 && (disp - (oldsize-2)) <= 127)
    999  1.1.1.2  christos 	    newsize = 3;
   1000  1.1.1.2  christos 	  else
   1001  1.1.1.2  christos 	    newsize = 6;
   1002  1.1.1.3  christos 	  break;
   1003  1.1.1.3  christos 	case OT_sk:
   1004  1.1.1.3  christos 	  newsize = 2;
   1005  1.1.1.3  christos 	  break;
   1006  1.1.1.2  christos 	default:
   1007  1.1.1.2  christos 	  newsize = oldsize;
   1008  1.1.1.2  christos 	  break;
   1009  1.1.1.2  christos 	}
   1010  1.1.1.2  christos       break;
   1011  1.1.1.2  christos     }
   1012  1.1.1.2  christos 
   1013  1.1.1.2  christos   /* This prevents infinite loops in align-heavy sources.  */
   1014  1.1.1.2  christos   if (newsize < oldsize)
   1015  1.1.1.2  christos     {
   1016  1.1.1.2  christos       if (fragP->tc_frag_data->times_shrank > 10
   1017  1.1.1.2  christos          && fragP->tc_frag_data->times_grown > 10)
   1018  1.1.1.2  christos        newsize = oldsize;
   1019  1.1.1.2  christos       if (fragP->tc_frag_data->times_shrank < 20)
   1020  1.1.1.2  christos        fragP->tc_frag_data->times_shrank ++;
   1021  1.1.1.2  christos     }
   1022  1.1.1.2  christos   else if (newsize > oldsize)
   1023  1.1.1.2  christos     {
   1024  1.1.1.2  christos       if (fragP->tc_frag_data->times_grown < 20)
   1025  1.1.1.2  christos        fragP->tc_frag_data->times_grown ++;
   1026  1.1.1.2  christos     }
   1027  1.1.1.2  christos 
   1028  1.1.1.2  christos   fragP->fr_subtype = newsize;
   1029  1.1.1.2  christos   tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
   1030      1.1  christos   return newsize - oldsize;
   1031      1.1  christos }
   1032  1.1.1.2  christos 
   1033  1.1.1.2  christos /* This lets us test for the opcode type and the desired size in a
   1034  1.1.1.2  christos    switch statement.  */
   1035  1.1.1.2  christos #define OPCODE(type,size) ((type) * 16 + (size))
   1036  1.1.1.2  christos 
   1037  1.1.1.2  christos /* Given the opcode stored in fr_opcode and the number of bytes we
   1038  1.1.1.2  christos    think we need, encode a new opcode.  We stored a pointer to the
   1039  1.1.1.2  christos    fixup for this opcode in the tc_frag_data structure.  If we can do
   1040  1.1.1.2  christos    the fixup here, we change the relocation type to "none" (we test
   1041  1.1.1.2  christos    for that in tc_gen_reloc) else we change it to the right type for
   1042  1.1.1.2  christos    the new (biggest) opcode.  */
   1043  1.1.1.2  christos 
   1044  1.1.1.2  christos void
   1045  1.1.1.2  christos md_convert_frag (bfd *   abfd ATTRIBUTE_UNUSED,
   1046  1.1.1.2  christos 		 segT    segment ATTRIBUTE_UNUSED,
   1047  1.1.1.2  christos 		 fragS * fragP ATTRIBUTE_UNUSED)
   1048  1.1.1.2  christos {
   1049  1.1.1.2  christos   rl78_bytesT * rl78b = fragP->tc_frag_data;
   1050  1.1.1.2  christos   addressT addr0, mypc;
   1051  1.1.1.2  christos   int disp;
   1052  1.1.1.2  christos   int reloc_type, reloc_adjust;
   1053  1.1.1.2  christos   char * op = fragP->fr_opcode;
   1054  1.1.1.2  christos   int keep_reloc = 0;
   1055  1.1.1.2  christos   int ri;
   1056  1.1.1.2  christos   int fi = (rl78b->n_fixups > 1) ? 1 : 0;
   1057  1.1.1.2  christos   fixS * fix = rl78b->fixups[fi].fixP;
   1058  1.1.1.2  christos 
   1059  1.1.1.2  christos   /* If we ever get more than one reloc per opcode, this is the one
   1060  1.1.1.2  christos      we're relaxing.  */
   1061  1.1.1.2  christos   ri = 0;
   1062  1.1.1.2  christos 
   1063  1.1.1.2  christos   /* We used a new frag for this opcode, so the opcode address should
   1064  1.1.1.2  christos      be the frag address.  */
   1065  1.1.1.2  christos   mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
   1066  1.1.1.2  christos   tprintf ("\033[32mmypc: 0x%x\033[0m\n", (int)mypc);
   1067  1.1.1.2  christos 
   1068  1.1.1.2  christos   /* Try to get the target address.  If we fail here, we just use the
   1069  1.1.1.2  christos      largest format.  */
   1070  1.1.1.2  christos   if (rl78_frag_fix_value (fragP, segment, 0, & addr0,
   1071  1.1.1.2  christos 			   fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH, 0))
   1072  1.1.1.2  christos     {
   1073  1.1.1.2  christos       /* We don't know the target address.  */
   1074  1.1.1.2  christos       keep_reloc = 1;
   1075  1.1.1.2  christos       addr0 = 0;
   1076  1.1.1.2  christos       disp = 0;
   1077  1.1.1.2  christos       tprintf ("unknown addr ? - %x = ?\n", (int)mypc);
   1078  1.1.1.2  christos     }
   1079  1.1.1.2  christos   else
   1080  1.1.1.2  christos     {
   1081  1.1.1.2  christos       /* We know the target address, and it's in addr0.  */
   1082  1.1.1.2  christos       disp = (int) addr0 - (int) mypc;
   1083  1.1.1.2  christos       tprintf ("known addr %x - %x = %d\n", (int)addr0, (int)mypc, disp);
   1084  1.1.1.2  christos     }
   1085  1.1.1.2  christos 
   1086  1.1.1.2  christos   if (linkrelax)
   1087  1.1.1.2  christos     keep_reloc = 1;
   1088  1.1.1.2  christos 
   1089  1.1.1.2  christos   reloc_type = BFD_RELOC_NONE;
   1090  1.1.1.2  christos   reloc_adjust = 0;
   1091  1.1.1.2  christos 
   1092  1.1.1.2  christos   switch (fragP->tc_frag_data->relax[ri].type)
   1093  1.1.1.2  christos     {
   1094  1.1.1.2  christos     case RL78_RELAX_BRANCH:
   1095  1.1.1.2  christos       switch (OPCODE (rl78_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
   1096  1.1.1.2  christos 	{
   1097  1.1.1.2  christos 
   1098  1.1.1.2  christos 	case OPCODE (OT_bt, 3): /* BT A,$ - no change.  */
   1099  1.1.1.2  christos 	  disp -= 3;
   1100  1.1.1.3  christos 	  op[2] = disp;
   1101  1.1.1.2  christos 	  reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
   1102  1.1.1.2  christos 	  break;
   1103  1.1.1.2  christos 
   1104  1.1.1.2  christos 	case OPCODE (OT_bt, 6): /* BT A,$ - long version.  */
   1105  1.1.1.2  christos 	  disp -= 3;
   1106  1.1.1.2  christos 	  op[1] ^= 0x06; /* toggle conditional.  */
   1107  1.1.1.2  christos 	  op[2] = 3; /* displacement over long branch.  */
   1108  1.1.1.2  christos 	  disp -= 3;
   1109  1.1.1.2  christos 	  op[3] = 0xEE; /* BR $!addr20 */
   1110  1.1.1.2  christos 	  op[4] = disp & 0xff;
   1111  1.1.1.2  christos 	  op[5] = disp >> 8;
   1112  1.1.1.2  christos 	  reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
   1113  1.1.1.2  christos 	  reloc_adjust = 2;
   1114  1.1.1.2  christos 	  break;
   1115  1.1.1.2  christos 
   1116  1.1.1.2  christos 	case OPCODE (OT_bt_sfr, 4): /* BT PSW,$ - no change.  */
   1117  1.1.1.2  christos 	  disp -= 4;
   1118  1.1.1.3  christos 	  op[3] = disp;
   1119  1.1.1.2  christos 	  reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
   1120  1.1.1.2  christos 	  break;
   1121  1.1.1.2  christos 
   1122  1.1.1.2  christos 	case OPCODE (OT_bt_sfr, 7): /* BT PSW,$ - long version.  */
   1123  1.1.1.2  christos 	  disp -= 4;
   1124  1.1.1.2  christos 	  op[1] ^= 0x06; /* toggle conditional.  */
   1125  1.1.1.2  christos 	  op[3] = 3; /* displacement over long branch.  */
   1126  1.1.1.2  christos 	  disp -= 3;
   1127  1.1.1.2  christos 	  op[4] = 0xEE; /* BR $!addr20 */
   1128  1.1.1.2  christos 	  op[5] = disp & 0xff;
   1129  1.1.1.2  christos 	  op[6] = disp >> 8;
   1130  1.1.1.2  christos 	  reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
   1131  1.1.1.2  christos 	  reloc_adjust = 2;
   1132  1.1.1.2  christos 	  break;
   1133  1.1.1.2  christos 
   1134  1.1.1.2  christos 	case OPCODE (OT_bt_es, 4): /* BT ES:[HL],$ - no change.  */
   1135  1.1.1.2  christos 	  disp -= 4;
   1136  1.1.1.3  christos 	  op[3] = disp;
   1137  1.1.1.2  christos 	  reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
   1138  1.1.1.2  christos 	  break;
   1139  1.1.1.2  christos 
   1140  1.1.1.2  christos 	case OPCODE (OT_bt_es, 7): /* BT PSW,$ - long version.  */
   1141  1.1.1.2  christos 	  disp -= 4;
   1142  1.1.1.2  christos 	  op[2] ^= 0x06; /* toggle conditional.  */
   1143  1.1.1.2  christos 	  op[3] = 3; /* displacement over long branch.  */
   1144  1.1.1.2  christos 	  disp -= 3;
   1145  1.1.1.2  christos 	  op[4] = 0xEE; /* BR $!addr20 */
   1146  1.1.1.2  christos 	  op[5] = disp & 0xff;
   1147  1.1.1.2  christos 	  op[6] = disp >> 8;
   1148  1.1.1.2  christos 	  reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
   1149  1.1.1.2  christos 	  reloc_adjust = 2;
   1150  1.1.1.2  christos 	  break;
   1151  1.1.1.2  christos 
   1152  1.1.1.2  christos 	case OPCODE (OT_bc, 2): /* BC $ - no change.  */
   1153  1.1.1.2  christos 	  disp -= 2;
   1154  1.1.1.3  christos 	  op[1] = disp;
   1155  1.1.1.2  christos 	  reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
   1156  1.1.1.2  christos 	  break;
   1157  1.1.1.2  christos 
   1158  1.1.1.2  christos 	case OPCODE (OT_bc, 5): /* BC $ - long version.  */
   1159  1.1.1.2  christos 	  disp -= 2;
   1160  1.1.1.2  christos 	  op[0] ^= 0x02; /* toggle conditional.  */
   1161  1.1.1.2  christos 	  op[1] = 3;
   1162  1.1.1.2  christos 	  disp -= 3;
   1163  1.1.1.2  christos 	  op[2] = 0xEE; /* BR $!addr20 */
   1164  1.1.1.2  christos 	  op[3] = disp & 0xff;
   1165  1.1.1.2  christos 	  op[4] = disp >> 8;
   1166  1.1.1.2  christos 	  reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
   1167  1.1.1.2  christos 	  reloc_adjust = 2;
   1168  1.1.1.2  christos 	  break;
   1169  1.1.1.2  christos 
   1170  1.1.1.2  christos 	case OPCODE (OT_bh, 3): /* BH $ - no change.  */
   1171  1.1.1.2  christos 	  disp -= 3;
   1172  1.1.1.3  christos 	  op[2] = disp;
   1173  1.1.1.2  christos 	  reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
   1174  1.1.1.2  christos 	  break;
   1175  1.1.1.2  christos 
   1176  1.1.1.2  christos 	case OPCODE (OT_bh, 6): /* BC $ - long version.  */
   1177  1.1.1.2  christos 	  disp -= 3;
   1178  1.1.1.2  christos 	  op[1] ^= 0x10; /* toggle conditional.  */
   1179  1.1.1.2  christos 	  op[2] = 3;
   1180  1.1.1.2  christos 	  disp -= 3;
   1181  1.1.1.2  christos 	  op[3] = 0xEE; /* BR $!addr20 */
   1182  1.1.1.2  christos 	  op[4] = disp & 0xff;
   1183  1.1.1.2  christos 	  op[5] = disp >> 8;
   1184  1.1.1.2  christos 	  reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
   1185  1.1.1.2  christos 	  reloc_adjust = 2;
   1186  1.1.1.2  christos 	  break;
   1187  1.1.1.3  christos 
   1188  1.1.1.3  christos 	case OPCODE (OT_sk, 2): /* SK<cond> - no change */
   1189  1.1.1.3  christos 	  reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
   1190  1.1.1.2  christos 	  break;
   1191  1.1.1.3  christos 
   1192  1.1.1.3  christos 	default:
   1193  1.1.1.3  christos 	  reloc_type = fix ? fix->fx_r_type : BFD_RELOC_NONE;
   1194  1.1.1.2  christos 	  break;
   1195  1.1.1.2  christos 	}
   1196  1.1.1.2  christos       break;
   1197  1.1.1.2  christos 
   1198  1.1.1.2  christos     default:
   1199  1.1.1.2  christos       if (rl78b->n_fixups)
   1200  1.1.1.2  christos 	{
   1201  1.1.1.2  christos 	  reloc_type = fix->fx_r_type;
   1202  1.1.1.2  christos 	  reloc_adjust = 0;
   1203  1.1.1.2  christos 	}
   1204  1.1.1.2  christos       break;
   1205  1.1.1.2  christos     }
   1206  1.1.1.2  christos 
   1207  1.1.1.2  christos   if (rl78b->n_fixups)
   1208  1.1.1.2  christos     {
   1209  1.1.1.2  christos 
   1210  1.1.1.2  christos       fix->fx_r_type = reloc_type;
   1211  1.1.1.2  christos       fix->fx_where += reloc_adjust;
   1212  1.1.1.2  christos       switch (reloc_type)
   1213  1.1.1.2  christos 	{
   1214  1.1.1.2  christos 	case BFD_RELOC_NONE:
   1215  1.1.1.2  christos 	  fix->fx_size = 0;
   1216  1.1.1.2  christos 	  break;
   1217  1.1.1.2  christos 	case BFD_RELOC_8:
   1218  1.1.1.2  christos 	  fix->fx_size = 1;
   1219  1.1.1.2  christos 	  break;
   1220  1.1.1.2  christos 	case BFD_RELOC_16_PCREL:
   1221  1.1.1.2  christos 	  fix->fx_size = 2;
   1222  1.1.1.2  christos 	  break;
   1223  1.1.1.2  christos 	}
   1224  1.1.1.2  christos     }
   1225  1.1.1.2  christos 
   1226  1.1.1.2  christos   fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
   1227  1.1.1.2  christos   tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix,
   1228  1.1.1.2  christos 	  fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
   1229  1.1.1.2  christos   fragP->fr_var = 0;
   1230  1.1.1.2  christos 
   1231  1.1.1.2  christos   tprintf ("compare 0x%lx vs 0x%lx - 0x%lx = 0x%lx (%p)\n",
   1232  1.1.1.2  christos 	   (long)fragP->fr_fix,
   1233  1.1.1.2  christos 	   (long)fragP->fr_next->fr_address, (long)fragP->fr_address,
   1234  1.1.1.2  christos 	   (long)(fragP->fr_next->fr_address - fragP->fr_address),
   1235  1.1.1.2  christos 	   fragP->fr_next);
   1236  1.1.1.2  christos 
   1237  1.1.1.2  christos   if (fragP->fr_next != NULL
   1238  1.1.1.2  christos 	  && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
   1239  1.1.1.2  christos 	      != fragP->fr_fix))
   1240  1.1.1.2  christos     as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
   1241  1.1.1.2  christos 	    (long) fragP->fr_fix,
   1242  1.1.1.2  christos 	    (long) fragP->fr_address, (long) fragP->fr_next->fr_address);
   1243  1.1.1.2  christos }
   1244  1.1.1.2  christos 
   1245  1.1.1.2  christos /* End of relaxation code.
   1246  1.1.1.2  christos   ----------------------------------------------------------------------*/
   1247  1.1.1.2  christos 
   1248      1.1  christos 
   1250      1.1  christos arelent **
   1251      1.1  christos tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
   1252      1.1  christos {
   1253      1.1  christos   static arelent * reloc[8];
   1254      1.1  christos   int rp;
   1255      1.1  christos 
   1256      1.1  christos   if (fixp->fx_r_type == BFD_RELOC_NONE)
   1257      1.1  christos     {
   1258      1.1  christos       reloc[0] = NULL;
   1259      1.1  christos       return reloc;
   1260  1.1.1.3  christos     }
   1261  1.1.1.3  christos 
   1262  1.1.1.3  christos   if (fixp->fx_r_type == BFD_RELOC_RL78_RELAX && !linkrelax)
   1263  1.1.1.3  christos     {
   1264  1.1.1.3  christos       reloc[0] = NULL;
   1265  1.1.1.3  christos       return reloc;
   1266      1.1  christos     }
   1267      1.1  christos 
   1268      1.1  christos   if (fixp->fx_subsy
   1269      1.1  christos       && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
   1270      1.1  christos     {
   1271      1.1  christos       fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
   1272      1.1  christos       fixp->fx_subsy = NULL;
   1273  1.1.1.3  christos     }
   1274  1.1.1.3  christos 
   1275      1.1  christos   reloc[0]		  = XNEW (arelent);
   1276      1.1  christos   reloc[0]->sym_ptr_ptr   = XNEW (asymbol *);
   1277      1.1  christos   * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   1278      1.1  christos   reloc[0]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
   1279      1.1  christos   reloc[0]->addend        = fixp->fx_offset;
   1280      1.1  christos 
   1281      1.1  christos   if (fixp->fx_r_type == BFD_RELOC_RL78_32_OP
   1282      1.1  christos       && fixp->fx_subsy)
   1283      1.1  christos     {
   1284      1.1  christos       fixp->fx_r_type = BFD_RELOC_RL78_DIFF;
   1285      1.1  christos     }
   1286  1.1.1.3  christos 
   1287  1.1.1.3  christos #define OPX(REL,SYM,ADD)							\
   1288      1.1  christos   reloc[rp]		   = XNEW (arelent);		\
   1289      1.1  christos   reloc[rp]->sym_ptr_ptr   = XNEW (asymbol *);		\
   1290      1.1  christos   reloc[rp]->howto         = bfd_reloc_type_lookup (stdoutput, REL);		\
   1291      1.1  christos   reloc[rp]->addend        = ADD;						\
   1292      1.1  christos   * reloc[rp]->sym_ptr_ptr = SYM;						\
   1293      1.1  christos   reloc[rp]->address       = fixp->fx_frag->fr_address + fixp->fx_where;	\
   1294  1.1.1.2  christos   reloc[++rp] = NULL
   1295  1.1.1.2  christos #define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
   1296  1.1.1.2  christos 
   1297  1.1.1.2  christos   /* FIXME: We cannot do the normal thing for an immediate value reloc,
   1298  1.1.1.2  christos      ie creating a RL78_SYM reloc in the *ABS* section with an offset
   1299  1.1.1.2  christos      equal to the immediate value we want to store.  This fails because
   1300  1.1.1.2  christos      the reloc processing in bfd_perform_relocation and bfd_install_relocation
   1301  1.1.1.2  christos      will short circuit such relocs and never pass them on to the special
   1302  1.1.1.2  christos      reloc processing code.  So instead we create a RL78_SYM reloc against
   1303  1.1.1.2  christos      the __rl78_abs__ symbol and arrange for the linker scripts to place
   1304  1.1.1.2  christos      this symbol at address 0.  */
   1305      1.1  christos #define OPIMM(IMM) OPX (BFD_RELOC_RL78_SYM, symbol_get_bfdsym (rl78_abs_sym), IMM)
   1306      1.1  christos 
   1307      1.1  christos #define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
   1308      1.1  christos #define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
   1309      1.1  christos 
   1310      1.1  christos   rp = 1;
   1311      1.1  christos 
   1312      1.1  christos   /* Certain BFD relocations cannot be translated directly into
   1313      1.1  christos      a single (non-Red Hat) RL78 relocation, but instead need
   1314      1.1  christos      multiple RL78 relocations - handle them here.  */
   1315      1.1  christos   switch (fixp->fx_r_type)
   1316      1.1  christos     {
   1317      1.1  christos     case BFD_RELOC_RL78_DIFF:
   1318      1.1  christos       SYM0 ();
   1319      1.1  christos       OPSYM (symbol_get_bfdsym (fixp->fx_subsy));
   1320      1.1  christos       OP(OP_SUBTRACT);
   1321      1.1  christos 
   1322      1.1  christos       switch (fixp->fx_size)
   1323      1.1  christos 	{
   1324      1.1  christos 	case 1:
   1325      1.1  christos 	  OP(ABS8);
   1326      1.1  christos 	  break;
   1327      1.1  christos 	case 2:
   1328      1.1  christos 	  OP (ABS16);
   1329      1.1  christos 	  break;
   1330      1.1  christos 	case 4:
   1331      1.1  christos 	  OP (ABS32);
   1332      1.1  christos 	  break;
   1333      1.1  christos 	}
   1334      1.1  christos       break;
   1335      1.1  christos 
   1336      1.1  christos     case BFD_RELOC_RL78_NEG32:
   1337      1.1  christos       SYM0 ();
   1338      1.1  christos       OP (OP_NEG);
   1339      1.1  christos       OP (ABS32);
   1340  1.1.1.2  christos       break;
   1341  1.1.1.2  christos 
   1342  1.1.1.2  christos     case BFD_RELOC_RL78_CODE:
   1343  1.1.1.2  christos       reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_16U);
   1344  1.1.1.2  christos       reloc[1] = NULL;
   1345      1.1  christos       break;
   1346      1.1  christos 
   1347      1.1  christos     case BFD_RELOC_RL78_LO16:
   1348      1.1  christos       SYM0 ();
   1349      1.1  christos       OPIMM (0xffff);
   1350      1.1  christos       OP (OP_AND);
   1351      1.1  christos       OP (ABS16);
   1352      1.1  christos       break;
   1353      1.1  christos 
   1354      1.1  christos     case BFD_RELOC_RL78_HI16:
   1355      1.1  christos       SYM0 ();
   1356      1.1  christos       OPIMM (16);
   1357      1.1  christos       OP (OP_SHRA);
   1358      1.1  christos       OP (ABS16);
   1359      1.1  christos       break;
   1360      1.1  christos 
   1361      1.1  christos     case BFD_RELOC_RL78_HI8:
   1362      1.1  christos       SYM0 ();
   1363      1.1  christos       OPIMM (16);
   1364      1.1  christos       OP (OP_SHRA);
   1365      1.1  christos       OPIMM (0xff);
   1366      1.1  christos       OP (OP_AND);
   1367      1.1  christos       OP (ABS8);
   1368      1.1  christos       break;
   1369      1.1  christos 
   1370      1.1  christos     default:
   1371      1.1  christos       reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
   1372      1.1  christos       reloc[1] = NULL;
   1373      1.1  christos       break;
   1374      1.1  christos     }
   1375      1.1  christos 
   1376      1.1  christos   return reloc;
   1377      1.1  christos }
   1378      1.1  christos 
   1379      1.1  christos int
   1380      1.1  christos rl78_validate_fix_sub (struct fix * f)
   1381      1.1  christos {
   1382      1.1  christos   /* We permit the subtraction of two symbols in a few cases.  */
   1383      1.1  christos   /* mov #sym1-sym2, R3 */
   1384      1.1  christos   if (f->fx_r_type == BFD_RELOC_RL78_32_OP)
   1385      1.1  christos     return 1;
   1386      1.1  christos   /* .long sym1-sym2 */
   1387      1.1  christos   if (f->fx_r_type == BFD_RELOC_RL78_DIFF
   1388      1.1  christos       && ! f->fx_pcrel
   1389      1.1  christos       && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
   1390      1.1  christos     return 1;
   1391      1.1  christos   return 0;
   1392      1.1  christos }
   1393      1.1  christos 
   1394      1.1  christos long
   1395      1.1  christos md_pcrel_from_section (fixS * fixP, segT sec)
   1396      1.1  christos {
   1397      1.1  christos   long rv;
   1398      1.1  christos 
   1399      1.1  christos   if (fixP->fx_addsy != NULL
   1400      1.1  christos       && (! S_IS_DEFINED (fixP->fx_addsy)
   1401      1.1  christos 	  || S_GET_SEGMENT (fixP->fx_addsy) != sec))
   1402      1.1  christos     /* The symbol is undefined (or is defined but not in this section).
   1403      1.1  christos        Let the linker figure it out.  */
   1404      1.1  christos     return 0;
   1405      1.1  christos 
   1406      1.1  christos   rv = fixP->fx_frag->fr_address + fixP->fx_where;
   1407      1.1  christos   switch (fixP->fx_r_type)
   1408      1.1  christos     {
   1409      1.1  christos     case BFD_RELOC_8_PCREL:
   1410      1.1  christos       rv += 1;
   1411      1.1  christos       break;
   1412      1.1  christos     case BFD_RELOC_16_PCREL:
   1413      1.1  christos       rv += 2;
   1414      1.1  christos       break;
   1415      1.1  christos     default:
   1416      1.1  christos       break;
   1417      1.1  christos     }
   1418      1.1  christos   return rv;
   1419      1.1  christos }
   1420      1.1  christos 
   1421      1.1  christos void
   1422      1.1  christos md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
   1423      1.1  christos 	      valueT *     t ATTRIBUTE_UNUSED,
   1424      1.1  christos 	      segT         s ATTRIBUTE_UNUSED)
   1425      1.1  christos {
   1426      1.1  christos   char * op;
   1427  1.1.1.3  christos   unsigned long val;
   1428  1.1.1.3  christos 
   1429  1.1.1.3  christos   /* We always defer overflow checks for these to the linker, as it
   1430  1.1.1.3  christos      needs to do PLT stuff.  */
   1431  1.1.1.3  christos   if (f->fx_r_type == BFD_RELOC_RL78_CODE)
   1432      1.1  christos     f->fx_no_overflow = 1;
   1433      1.1  christos 
   1434      1.1  christos   if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
   1435      1.1  christos     return;
   1436      1.1  christos   if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
   1437      1.1  christos     return;
   1438      1.1  christos 
   1439      1.1  christos   op = f->fx_frag->fr_literal + f->fx_where;
   1440  1.1.1.3  christos   val = (unsigned long) * t;
   1441  1.1.1.3  christos 
   1442  1.1.1.3  christos   if (f->fx_addsy == NULL)
   1443      1.1  christos     f->fx_done = 1;
   1444      1.1  christos 
   1445      1.1  christos   switch (f->fx_r_type)
   1446      1.1  christos     {
   1447      1.1  christos     case BFD_RELOC_NONE:
   1448      1.1  christos       break;
   1449  1.1.1.3  christos 
   1450      1.1  christos     case BFD_RELOC_RL78_RELAX:
   1451      1.1  christos       f->fx_done = 0;
   1452      1.1  christos       break;
   1453  1.1.1.2  christos 
   1454  1.1.1.2  christos     case BFD_RELOC_8_PCREL:
   1455  1.1.1.2  christos       if ((long)val < -128 || (long)val > 127)
   1456  1.1.1.2  christos 	as_bad_where (f->fx_file, f->fx_line,
   1457  1.1.1.2  christos 		      _("value of %ld too large for 8-bit branch"),
   1458  1.1.1.2  christos 		      val);
   1459  1.1.1.2  christos       /* Fall through.  */
   1460      1.1  christos     case BFD_RELOC_8:
   1461      1.1  christos     case BFD_RELOC_RL78_SADDR: /* We need to store the 8 LSB, but this works.  */
   1462      1.1  christos       op[0] = val;
   1463      1.1  christos       break;
   1464  1.1.1.2  christos 
   1465  1.1.1.2  christos     case BFD_RELOC_16_PCREL:
   1466  1.1.1.2  christos       if ((long)val < -32768 || (long)val > 32767)
   1467  1.1.1.2  christos 	as_bad_where (f->fx_file, f->fx_line,
   1468  1.1.1.2  christos 		      _("value of %ld too large for 16-bit branch"),
   1469  1.1.1.2  christos 		      val);
   1470  1.1.1.2  christos       /* Fall through.  */
   1471      1.1  christos     case BFD_RELOC_16:
   1472      1.1  christos     case BFD_RELOC_RL78_CODE:
   1473      1.1  christos       op[0] = val;
   1474      1.1  christos       op[1] = val >> 8;
   1475      1.1  christos       break;
   1476      1.1  christos 
   1477      1.1  christos     case BFD_RELOC_24:
   1478      1.1  christos       op[0] = val;
   1479      1.1  christos       op[1] = val >> 8;
   1480      1.1  christos       op[2] = val >> 16;
   1481      1.1  christos       break;
   1482      1.1  christos 
   1483      1.1  christos     case BFD_RELOC_32:
   1484      1.1  christos       op[0] = val;
   1485      1.1  christos       op[1] = val >> 8;
   1486      1.1  christos       op[2] = val >> 16;
   1487      1.1  christos       op[3] = val >> 24;
   1488  1.1.1.2  christos       break;
   1489  1.1.1.2  christos 
   1490  1.1.1.2  christos     case BFD_RELOC_RL78_DIFF:
   1491  1.1.1.2  christos       op[0] = val;
   1492  1.1.1.2  christos       if (f->fx_size > 1)
   1493  1.1.1.2  christos 	op[1] = val >> 8;
   1494  1.1.1.2  christos       if (f->fx_size > 2)
   1495  1.1.1.2  christos 	op[2] = val >> 16;
   1496  1.1.1.2  christos       if (f->fx_size > 3)
   1497  1.1.1.2  christos 	op[3] = val >> 24;
   1498  1.1.1.2  christos       break;
   1499  1.1.1.2  christos 
   1500  1.1.1.2  christos     case BFD_RELOC_RL78_HI8:
   1501  1.1.1.2  christos       val = val >> 16;
   1502  1.1.1.2  christos       op[0] = val;
   1503  1.1.1.2  christos       break;
   1504  1.1.1.2  christos 
   1505  1.1.1.2  christos     case BFD_RELOC_RL78_HI16:
   1506  1.1.1.2  christos       val = val >> 16;
   1507  1.1.1.2  christos       op[0] = val;
   1508  1.1.1.2  christos       op[1] = val >> 8;
   1509  1.1.1.2  christos       break;
   1510  1.1.1.2  christos 
   1511  1.1.1.2  christos     case BFD_RELOC_RL78_LO16:
   1512  1.1.1.2  christos       op[0] = val;
   1513  1.1.1.2  christos       op[1] = val >> 8;
   1514      1.1  christos       break;
   1515      1.1  christos 
   1516      1.1  christos     default:
   1517      1.1  christos       as_bad (_("Unknown reloc in md_apply_fix: %s"),
   1518      1.1  christos 	      bfd_get_reloc_code_name (f->fx_r_type));
   1519      1.1  christos       break;
   1520      1.1  christos     }
   1521      1.1  christos 
   1522      1.1  christos }
   1523      1.1  christos 
   1524      1.1  christos valueT
   1525      1.1  christos md_section_align (segT segment, valueT size)
   1526  1.1.1.2  christos {
   1527      1.1  christos   int align = bfd_get_section_alignment (stdoutput, segment);
   1528                      return ((size + (1 << align) - 1) & -(1 << align));
   1529                    }
   1530