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