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