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