Home | History | Annotate | Line # | Download | only in config
tc-h8300.c revision 1.1.1.5
      1      1.1  christos /* tc-h8300.c -- Assemble code for the Renesas H8/300
      2  1.1.1.5  christos    Copyright (C) 1991-2020 Free Software Foundation, Inc.
      3      1.1  christos 
      4      1.1  christos    This file is part of GAS, the GNU Assembler.
      5      1.1  christos 
      6      1.1  christos    GAS is free software; you can redistribute it and/or modify
      7      1.1  christos    it under the terms of the GNU General Public License as published by
      8      1.1  christos    the Free Software Foundation; either version 3, or (at your option)
      9      1.1  christos    any later version.
     10      1.1  christos 
     11      1.1  christos    GAS is distributed in the hope that it will be useful,
     12      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14      1.1  christos    GNU General Public License for more details.
     15      1.1  christos 
     16      1.1  christos    You should have received a copy of the GNU General Public License
     17      1.1  christos    along with GAS; see the file COPYING.  If not, write to the Free
     18      1.1  christos    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     19      1.1  christos    02110-1301, USA.  */
     20      1.1  christos 
     21      1.1  christos /* Written By Steve Chamberlain <sac (at) cygnus.com>.  */
     22      1.1  christos 
     23      1.1  christos #include "as.h"
     24      1.1  christos #include "subsegs.h"
     25      1.1  christos #include "dwarf2dbg.h"
     26      1.1  christos 
     27      1.1  christos #define DEFINE_TABLE
     28      1.1  christos #define h8_opcodes ops
     29      1.1  christos #include "opcode/h8300.h"
     30      1.1  christos #include "safe-ctype.h"
     31      1.1  christos #include "elf/h8.h"
     32      1.1  christos 
     33      1.1  christos const char comment_chars[] = ";";
     34      1.1  christos const char line_comment_chars[] = "#";
     35  1.1.1.2  christos #ifdef TE_LINUX
     36  1.1.1.2  christos const char line_separator_chars[] = "!";
     37  1.1.1.2  christos #else
     38      1.1  christos const char line_separator_chars[] = "";
     39  1.1.1.2  christos #endif
     40      1.1  christos 
     41      1.1  christos static void sbranch (int);
     42      1.1  christos static void h8300hmode (int);
     43      1.1  christos static void h8300smode (int);
     44      1.1  christos static void h8300hnmode (int);
     45      1.1  christos static void h8300snmode (int);
     46      1.1  christos static void h8300sxmode (int);
     47      1.1  christos static void h8300sxnmode (int);
     48      1.1  christos static void pint (int);
     49      1.1  christos 
     50      1.1  christos int Hmode;
     51      1.1  christos int Smode;
     52      1.1  christos int Nmode;
     53      1.1  christos int SXmode;
     54      1.1  christos 
     55  1.1.1.2  christos static int default_mach = bfd_mach_h8300;
     56  1.1.1.2  christos 
     57      1.1  christos #define PSIZE (Hmode && !Nmode ? L_32 : L_16)
     58      1.1  christos 
     59      1.1  christos static int bsize = L_8;		/* Default branch displacement.  */
     60      1.1  christos 
     61      1.1  christos struct h8_instruction
     62      1.1  christos {
     63      1.1  christos   int length;
     64      1.1  christos   int noperands;
     65      1.1  christos   int idx;
     66      1.1  christos   int size;
     67      1.1  christos   const struct h8_opcode *opcode;
     68      1.1  christos };
     69      1.1  christos 
     70      1.1  christos static struct h8_instruction *h8_instructions;
     71      1.1  christos 
     72      1.1  christos static void
     73      1.1  christos h8300hmode (int arg ATTRIBUTE_UNUSED)
     74      1.1  christos {
     75      1.1  christos   Hmode = 1;
     76      1.1  christos   Smode = 0;
     77      1.1  christos   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300h))
     78      1.1  christos     as_warn (_("could not set architecture and machine"));
     79      1.1  christos }
     80      1.1  christos 
     81      1.1  christos static void
     82      1.1  christos h8300smode (int arg ATTRIBUTE_UNUSED)
     83      1.1  christos {
     84      1.1  christos   Smode = 1;
     85      1.1  christos   Hmode = 1;
     86      1.1  christos   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300s))
     87      1.1  christos     as_warn (_("could not set architecture and machine"));
     88      1.1  christos }
     89      1.1  christos 
     90      1.1  christos static void
     91      1.1  christos h8300hnmode (int arg ATTRIBUTE_UNUSED)
     92      1.1  christos {
     93      1.1  christos   Hmode = 1;
     94      1.1  christos   Smode = 0;
     95      1.1  christos   Nmode = 1;
     96      1.1  christos   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300hn))
     97      1.1  christos     as_warn (_("could not set architecture and machine"));
     98      1.1  christos }
     99      1.1  christos 
    100      1.1  christos static void
    101      1.1  christos h8300snmode (int arg ATTRIBUTE_UNUSED)
    102      1.1  christos {
    103      1.1  christos   Smode = 1;
    104      1.1  christos   Hmode = 1;
    105      1.1  christos   Nmode = 1;
    106      1.1  christos   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300sn))
    107      1.1  christos     as_warn (_("could not set architecture and machine"));
    108      1.1  christos }
    109      1.1  christos 
    110      1.1  christos static void
    111      1.1  christos h8300sxmode (int arg ATTRIBUTE_UNUSED)
    112      1.1  christos {
    113      1.1  christos   Smode = 1;
    114      1.1  christos   Hmode = 1;
    115      1.1  christos   SXmode = 1;
    116      1.1  christos   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300sx))
    117      1.1  christos     as_warn (_("could not set architecture and machine"));
    118      1.1  christos }
    119      1.1  christos 
    120      1.1  christos static void
    121      1.1  christos h8300sxnmode (int arg ATTRIBUTE_UNUSED)
    122      1.1  christos {
    123      1.1  christos   Smode = 1;
    124      1.1  christos   Hmode = 1;
    125      1.1  christos   SXmode = 1;
    126      1.1  christos   Nmode = 1;
    127      1.1  christos   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, bfd_mach_h8300sxn))
    128      1.1  christos     as_warn (_("could not set architecture and machine"));
    129      1.1  christos }
    130      1.1  christos 
    131      1.1  christos static void
    132      1.1  christos sbranch (int size)
    133      1.1  christos {
    134      1.1  christos   bsize = size;
    135      1.1  christos }
    136      1.1  christos 
    137      1.1  christos static void
    138      1.1  christos pint (int arg ATTRIBUTE_UNUSED)
    139      1.1  christos {
    140      1.1  christos   cons (Hmode ? 4 : 2);
    141      1.1  christos }
    142      1.1  christos 
    143      1.1  christos /* Like obj_elf_section, but issues a warning for new
    144      1.1  christos    sections which do not have an attribute specification.  */
    145      1.1  christos 
    146      1.1  christos static void
    147      1.1  christos h8300_elf_section (int push)
    148      1.1  christos {
    149      1.1  christos   static const char * known_data_sections [] = { ".rodata", ".tdata", ".tbss" };
    150      1.1  christos   static const char * known_data_prefixes [] = { ".debug", ".zdebug", ".gnu.warning" };
    151      1.1  christos   char * saved_ilp = input_line_pointer;
    152  1.1.1.3  christos   const char * name;
    153      1.1  christos 
    154      1.1  christos   name = obj_elf_section_name ();
    155      1.1  christos   if (name == NULL)
    156      1.1  christos     return;
    157      1.1  christos 
    158      1.1  christos   if (* input_line_pointer != ','
    159      1.1  christos       && bfd_get_section_by_name (stdoutput, name) == NULL)
    160      1.1  christos     {
    161      1.1  christos       signed int i;
    162      1.1  christos 
    163      1.1  christos       /* Ignore this warning for well known data sections.  */
    164      1.1  christos       for (i = ARRAY_SIZE (known_data_sections); i--;)
    165      1.1  christos 	if (strcmp (name, known_data_sections[i]) == 0)
    166      1.1  christos 	  break;
    167      1.1  christos 
    168      1.1  christos       if (i < 0)
    169      1.1  christos 	for (i = ARRAY_SIZE (known_data_prefixes); i--;)
    170      1.1  christos 	  if (strncmp (name, known_data_prefixes[i],
    171      1.1  christos 		       strlen (known_data_prefixes[i])) == 0)
    172      1.1  christos 	    break;
    173      1.1  christos 
    174      1.1  christos       if (i < 0)
    175      1.1  christos 	as_warn (_("new section '%s' defined without attributes - this might cause problems"), name);
    176      1.1  christos     }
    177      1.1  christos 
    178      1.1  christos   /* FIXME: We ought to free the memory allocated by obj_elf_section_name()
    179      1.1  christos      for 'name', but we do not know if it was taken from the obstack, via
    180      1.1  christos      demand_copy_C_string(), or xmalloc()ed.  */
    181      1.1  christos   input_line_pointer = saved_ilp;
    182      1.1  christos   obj_elf_section (push);
    183      1.1  christos }
    184      1.1  christos 
    185      1.1  christos /* This table describes all the machine specific pseudo-ops the assembler
    186      1.1  christos    has to support.  The fields are:
    187      1.1  christos    pseudo-op name without dot
    188      1.1  christos    function to call to execute this pseudo-op
    189      1.1  christos    Integer arg to pass to the function.  */
    190      1.1  christos 
    191      1.1  christos const pseudo_typeS md_pseudo_table[] =
    192      1.1  christos {
    193      1.1  christos   {"h8300h",  h8300hmode,  0},
    194      1.1  christos   {"h8300hn", h8300hnmode, 0},
    195      1.1  christos   {"h8300s",  h8300smode,  0},
    196      1.1  christos   {"h8300sn", h8300snmode, 0},
    197      1.1  christos   {"h8300sx", h8300sxmode, 0},
    198      1.1  christos   {"h8300sxn", h8300sxnmode, 0},
    199      1.1  christos   {"sbranch", sbranch, L_8},
    200      1.1  christos   {"lbranch", sbranch, L_16},
    201      1.1  christos 
    202      1.1  christos   {"int", pint, 0},
    203      1.1  christos   {"data.b", cons, 1},
    204      1.1  christos   {"data.w", cons, 2},
    205      1.1  christos   {"data.l", cons, 4},
    206      1.1  christos   {"form", listing_psize, 0},
    207      1.1  christos   {"heading", listing_title, 0},
    208      1.1  christos   {"import",  s_ignore, 0},
    209      1.1  christos   {"page",    listing_eject, 0},
    210      1.1  christos   {"program", s_ignore, 0},
    211      1.1  christos 
    212      1.1  christos   {"section",   h8300_elf_section, 0},
    213      1.1  christos   {"section.s", h8300_elf_section, 0},
    214      1.1  christos   {"sect",      h8300_elf_section, 0},
    215      1.1  christos   {"sect.s",    h8300_elf_section, 0},
    216      1.1  christos 
    217      1.1  christos   {0, 0, 0}
    218      1.1  christos };
    219      1.1  christos 
    220      1.1  christos const char EXP_CHARS[] = "eE";
    221      1.1  christos 
    222      1.1  christos /* Chars that mean this number is a floating point constant
    223      1.1  christos    As in 0f12.456
    224      1.1  christos    or    0d1.2345e12.  */
    225      1.1  christos const char FLT_CHARS[] = "rRsSfFdDxXpP";
    226      1.1  christos 
    227      1.1  christos static struct hash_control *opcode_hash_control;	/* Opcode mnemonics.  */
    228      1.1  christos 
    229      1.1  christos /* This function is called once, at assembler startup time.  This
    230      1.1  christos    should set up all the tables, etc. that the MD part of the assembler
    231      1.1  christos    needs.  */
    232      1.1  christos 
    233      1.1  christos void
    234      1.1  christos md_begin (void)
    235      1.1  christos {
    236      1.1  christos   unsigned int nopcodes;
    237      1.1  christos   struct h8_opcode *p, *p1;
    238      1.1  christos   struct h8_instruction *pi;
    239      1.1  christos   char prev_buffer[100];
    240      1.1  christos   int idx = 0;
    241      1.1  christos 
    242  1.1.1.2  christos   if (!bfd_set_arch_mach (stdoutput, bfd_arch_h8300, default_mach))
    243      1.1  christos     as_warn (_("could not set architecture and machine"));
    244      1.1  christos 
    245      1.1  christos   opcode_hash_control = hash_new ();
    246      1.1  christos   prev_buffer[0] = 0;
    247      1.1  christos 
    248      1.1  christos   nopcodes = sizeof (h8_opcodes) / sizeof (struct h8_opcode);
    249  1.1.1.2  christos 
    250  1.1.1.3  christos   h8_instructions = XNEWVEC (struct h8_instruction, nopcodes);
    251      1.1  christos 
    252      1.1  christos   pi = h8_instructions;
    253      1.1  christos   p1 = h8_opcodes;
    254      1.1  christos   /* We do a minimum amount of sorting on the opcode table; this is to
    255      1.1  christos      make it easy to describe the mova instructions without unnecessary
    256      1.1  christos      code duplication.
    257      1.1  christos      Sorting only takes place inside blocks of instructions of the form
    258      1.1  christos      X/Y, so for example mova/b, mova/w and mova/l can be intermixed.  */
    259      1.1  christos   while (p1)
    260      1.1  christos     {
    261      1.1  christos       struct h8_opcode *first_skipped = 0;
    262      1.1  christos       int len, cmplen = 0;
    263  1.1.1.3  christos       const char *src = p1->name;
    264      1.1  christos       char *dst, *buffer;
    265      1.1  christos 
    266      1.1  christos       if (p1->name == 0)
    267      1.1  christos 	break;
    268      1.1  christos       /* Strip off any . part when inserting the opcode and only enter
    269      1.1  christos 	 unique codes into the hash table.  */
    270  1.1.1.3  christos       dst = buffer = XNEWVEC (char, strlen (src) + 1);
    271      1.1  christos       while (*src)
    272      1.1  christos 	{
    273      1.1  christos 	  if (*src == '.')
    274      1.1  christos 	    {
    275      1.1  christos 	      src++;
    276      1.1  christos 	      break;
    277      1.1  christos 	    }
    278      1.1  christos 	  if (*src == '/')
    279      1.1  christos 	    cmplen = src - p1->name + 1;
    280      1.1  christos 	  *dst++ = *src++;
    281      1.1  christos 	}
    282      1.1  christos       *dst = 0;
    283      1.1  christos       len = dst - buffer;
    284      1.1  christos       if (cmplen == 0)
    285      1.1  christos 	cmplen = len;
    286      1.1  christos       hash_insert (opcode_hash_control, buffer, (char *) pi);
    287      1.1  christos       strcpy (prev_buffer, buffer);
    288      1.1  christos       idx++;
    289      1.1  christos 
    290      1.1  christos       for (p = p1; p->name; p++)
    291      1.1  christos 	{
    292      1.1  christos 	  /* A negative TIME is used to indicate that we've added this opcode
    293      1.1  christos 	     already.  */
    294      1.1  christos 	  if (p->time == -1)
    295      1.1  christos 	    continue;
    296      1.1  christos 	  if (strncmp (p->name, buffer, cmplen) != 0
    297      1.1  christos 	      || (p->name[cmplen] != '\0' && p->name[cmplen] != '.'
    298      1.1  christos 		  && p->name[cmplen - 1] != '/'))
    299      1.1  christos 	    {
    300      1.1  christos 	      if (first_skipped == 0)
    301      1.1  christos 		first_skipped = p;
    302      1.1  christos 	      break;
    303      1.1  christos 	    }
    304      1.1  christos 	  if (strncmp (p->name, buffer, len) != 0)
    305      1.1  christos 	    {
    306      1.1  christos 	      if (first_skipped == 0)
    307      1.1  christos 		first_skipped = p;
    308      1.1  christos 	      continue;
    309      1.1  christos 	    }
    310      1.1  christos 
    311      1.1  christos 	  p->time = -1;
    312      1.1  christos 	  pi->size = p->name[len] == '.' ? p->name[len + 1] : 0;
    313      1.1  christos 	  pi->idx = idx;
    314      1.1  christos 
    315      1.1  christos 	  /* Find the number of operands.  */
    316      1.1  christos 	  pi->noperands = 0;
    317      1.1  christos 	  while (pi->noperands < 3 && p->args.nib[pi->noperands] != (op_type) E)
    318      1.1  christos 	    pi->noperands++;
    319      1.1  christos 
    320      1.1  christos 	  /* Find the length of the opcode in bytes.  */
    321      1.1  christos 	  pi->length = 0;
    322      1.1  christos 	  while (p->data.nib[pi->length * 2] != (op_type) E)
    323      1.1  christos 	    pi->length++;
    324      1.1  christos 
    325      1.1  christos 	  pi->opcode = p;
    326      1.1  christos 	  pi++;
    327      1.1  christos 	}
    328      1.1  christos       p1 = first_skipped;
    329      1.1  christos     }
    330      1.1  christos 
    331      1.1  christos   /* Add entry for the NULL vector terminator.  */
    332      1.1  christos   pi->length = 0;
    333      1.1  christos   pi->noperands = 0;
    334      1.1  christos   pi->idx = 0;
    335      1.1  christos   pi->size = 0;
    336      1.1  christos   pi->opcode = 0;
    337      1.1  christos 
    338      1.1  christos   linkrelax = 1;
    339      1.1  christos }
    340      1.1  christos 
    341      1.1  christos struct h8_op
    342      1.1  christos {
    343      1.1  christos   op_type mode;
    344      1.1  christos   unsigned reg;
    345      1.1  christos   expressionS exp;
    346      1.1  christos };
    347      1.1  christos 
    348      1.1  christos static void clever_message (const struct h8_instruction *, struct h8_op *);
    349      1.1  christos static void fix_operand_size (struct h8_op *, int);
    350      1.1  christos static void build_bytes (const struct h8_instruction *, struct h8_op *);
    351      1.1  christos static void do_a_fix_imm (int, int, struct h8_op *, int, const struct h8_instruction *);
    352  1.1.1.3  christos static void check_operand (struct h8_op *, unsigned int, const char *);
    353      1.1  christos static const struct h8_instruction * get_specific (const struct h8_instruction *, struct h8_op *, int) ;
    354      1.1  christos static char *get_operands (unsigned, char *, struct h8_op *);
    355      1.1  christos static void get_operand (char **, struct h8_op *, int);
    356      1.1  christos static int parse_reg (char *, op_type *, unsigned *, int);
    357      1.1  christos static char *skip_colonthing (char *, int *);
    358      1.1  christos static char *parse_exp (char *, struct h8_op *);
    359      1.1  christos 
    360      1.1  christos static int constant_fits_size_p (struct h8_op *, int, int);
    361      1.1  christos 
    362      1.1  christos /*
    363      1.1  christos   parse operands
    364      1.1  christos   WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
    365      1.1  christos   r0l,r0h,..r7l,r7h
    366      1.1  christos   @WREG
    367      1.1  christos   @WREG+
    368      1.1  christos   @-WREG
    369      1.1  christos   #const
    370      1.1  christos   ccr
    371      1.1  christos */
    372      1.1  christos 
    373      1.1  christos /* Try to parse a reg name.  Return the number of chars consumed.  */
    374      1.1  christos 
    375      1.1  christos static int
    376      1.1  christos parse_reg (char *src, op_type *mode, unsigned int *reg, int direction)
    377      1.1  christos {
    378      1.1  christos   char *end;
    379      1.1  christos   int len;
    380      1.1  christos 
    381  1.1.1.2  christos   /* Cribbed from get_symbol_name.  */
    382      1.1  christos   if (!is_name_beginner (*src) || *src == '\001')
    383      1.1  christos     return 0;
    384      1.1  christos   end = src + 1;
    385      1.1  christos   while ((is_part_of_name (*end) && *end != '.') || *end == '\001')
    386      1.1  christos     end++;
    387      1.1  christos   len = end - src;
    388      1.1  christos 
    389      1.1  christos   if (len == 2 && TOLOWER (src[0]) == 's' && TOLOWER (src[1]) == 'p')
    390      1.1  christos     {
    391      1.1  christos       *mode = PSIZE | REG | direction;
    392      1.1  christos       *reg = 7;
    393      1.1  christos       return len;
    394      1.1  christos     }
    395  1.1.1.2  christos   if (len == 3 &&
    396  1.1.1.2  christos       TOLOWER (src[0]) == 'c' &&
    397  1.1.1.2  christos       TOLOWER (src[1]) == 'c' &&
    398      1.1  christos       TOLOWER (src[2]) == 'r')
    399      1.1  christos     {
    400      1.1  christos       *mode = CCR;
    401      1.1  christos       *reg = 0;
    402      1.1  christos       return len;
    403      1.1  christos     }
    404  1.1.1.2  christos   if (len == 3 &&
    405  1.1.1.2  christos       TOLOWER (src[0]) == 'e' &&
    406  1.1.1.2  christos       TOLOWER (src[1]) == 'x' &&
    407      1.1  christos       TOLOWER (src[2]) == 'r')
    408      1.1  christos     {
    409      1.1  christos       *mode = EXR;
    410      1.1  christos       *reg = 1;
    411      1.1  christos       return len;
    412      1.1  christos     }
    413  1.1.1.2  christos   if (len == 3 &&
    414  1.1.1.2  christos       TOLOWER (src[0]) == 'v' &&
    415  1.1.1.2  christos       TOLOWER (src[1]) == 'b' &&
    416      1.1  christos       TOLOWER (src[2]) == 'r')
    417      1.1  christos     {
    418      1.1  christos       *mode = VBR;
    419      1.1  christos       *reg = 6;
    420      1.1  christos       return len;
    421      1.1  christos     }
    422  1.1.1.2  christos   if (len == 3 &&
    423  1.1.1.2  christos       TOLOWER (src[0]) == 's' &&
    424  1.1.1.2  christos       TOLOWER (src[1]) == 'b' &&
    425      1.1  christos       TOLOWER (src[2]) == 'r')
    426      1.1  christos     {
    427      1.1  christos       *mode = SBR;
    428      1.1  christos       *reg = 7;
    429      1.1  christos       return len;
    430      1.1  christos     }
    431      1.1  christos   if (len == 2 && TOLOWER (src[0]) == 'f' && TOLOWER (src[1]) == 'p')
    432      1.1  christos     {
    433      1.1  christos       *mode = PSIZE | REG | direction;
    434      1.1  christos       *reg = 6;
    435      1.1  christos       return len;
    436      1.1  christos     }
    437      1.1  christos   if (len == 3 && TOLOWER (src[0]) == 'e' && TOLOWER (src[1]) == 'r' &&
    438      1.1  christos       src[2] >= '0' && src[2] <= '7')
    439      1.1  christos     {
    440      1.1  christos       *mode = L_32 | REG | direction;
    441      1.1  christos       *reg = src[2] - '0';
    442      1.1  christos       if (!Hmode)
    443      1.1  christos 	as_warn (_("Reg not valid for H8/300"));
    444      1.1  christos       return len;
    445      1.1  christos     }
    446      1.1  christos   if (len == 2 && TOLOWER (src[0]) == 'e' && src[1] >= '0' && src[1] <= '7')
    447      1.1  christos     {
    448      1.1  christos       *mode = L_16 | REG | direction;
    449      1.1  christos       *reg = src[1] - '0' + 8;
    450      1.1  christos       if (!Hmode)
    451      1.1  christos 	as_warn (_("Reg not valid for H8/300"));
    452      1.1  christos       return len;
    453      1.1  christos     }
    454      1.1  christos 
    455      1.1  christos   if (TOLOWER (src[0]) == 'r')
    456      1.1  christos     {
    457      1.1  christos       if (src[1] >= '0' && src[1] <= '7')
    458      1.1  christos 	{
    459      1.1  christos 	  if (len == 3 && TOLOWER (src[2]) == 'l')
    460      1.1  christos 	    {
    461      1.1  christos 	      *mode = L_8 | REG | direction;
    462      1.1  christos 	      *reg = (src[1] - '0') + 8;
    463      1.1  christos 	      return len;
    464      1.1  christos 	    }
    465      1.1  christos 	  if (len == 3 && TOLOWER (src[2]) == 'h')
    466      1.1  christos 	    {
    467      1.1  christos 	      *mode = L_8 | REG | direction;
    468      1.1  christos 	      *reg = (src[1] - '0');
    469      1.1  christos 	      return len;
    470      1.1  christos 	    }
    471      1.1  christos 	  if (len == 2)
    472      1.1  christos 	    {
    473      1.1  christos 	      *mode = L_16 | REG | direction;
    474      1.1  christos 	      *reg = (src[1] - '0');
    475      1.1  christos 	      return len;
    476      1.1  christos 	    }
    477      1.1  christos 	}
    478      1.1  christos     }
    479      1.1  christos 
    480      1.1  christos   return 0;
    481      1.1  christos }
    482      1.1  christos 
    483      1.1  christos 
    484      1.1  christos /* Parse an immediate or address-related constant and store it in OP.
    485      1.1  christos    If the user also specifies the operand's size, store that size
    486      1.1  christos    in OP->MODE, otherwise leave it for later code to decide.  */
    487      1.1  christos 
    488      1.1  christos static char *
    489      1.1  christos parse_exp (char *src, struct h8_op *op)
    490      1.1  christos {
    491      1.1  christos   char *save;
    492      1.1  christos 
    493      1.1  christos   save = input_line_pointer;
    494      1.1  christos   input_line_pointer = src;
    495      1.1  christos   expression (&op->exp);
    496      1.1  christos   if (op->exp.X_op == O_absent)
    497      1.1  christos     as_bad (_("missing operand"));
    498      1.1  christos   src = input_line_pointer;
    499      1.1  christos   input_line_pointer = save;
    500      1.1  christos 
    501      1.1  christos   return skip_colonthing (src, &op->mode);
    502      1.1  christos }
    503      1.1  christos 
    504      1.1  christos 
    505      1.1  christos /* If SRC starts with an explicit operand size, skip it and store the size
    506      1.1  christos    in *MODE.  Leave *MODE unchanged otherwise.  */
    507      1.1  christos 
    508      1.1  christos static char *
    509      1.1  christos skip_colonthing (char *src, int *mode)
    510      1.1  christos {
    511      1.1  christos   if (*src == ':')
    512      1.1  christos     {
    513      1.1  christos       src++;
    514      1.1  christos       *mode &= ~SIZE;
    515      1.1  christos       if (src[0] == '8' && !ISDIGIT (src[1]))
    516      1.1  christos 	*mode |= L_8;
    517      1.1  christos       else if (src[0] == '2' && !ISDIGIT (src[1]))
    518      1.1  christos 	*mode |= L_2;
    519      1.1  christos       else if (src[0] == '3' && !ISDIGIT (src[1]))
    520      1.1  christos 	*mode |= L_3;
    521      1.1  christos       else if (src[0] == '4' && !ISDIGIT (src[1]))
    522      1.1  christos 	*mode |= L_4;
    523      1.1  christos       else if (src[0] == '5' && !ISDIGIT (src[1]))
    524      1.1  christos 	*mode |= L_5;
    525      1.1  christos       else if (src[0] == '2' && src[1] == '4' && !ISDIGIT (src[2]))
    526      1.1  christos 	*mode |= L_24;
    527      1.1  christos       else if (src[0] == '3' && src[1] == '2' && !ISDIGIT (src[2]))
    528      1.1  christos 	*mode |= L_32;
    529      1.1  christos       else if (src[0] == '1' && src[1] == '6' && !ISDIGIT (src[2]))
    530      1.1  christos 	*mode |= L_16;
    531      1.1  christos       else
    532      1.1  christos 	as_bad (_("invalid operand size requested"));
    533      1.1  christos 
    534      1.1  christos       while (ISDIGIT (*src))
    535      1.1  christos 	src++;
    536      1.1  christos     }
    537      1.1  christos   return src;
    538      1.1  christos }
    539      1.1  christos 
    540      1.1  christos /* The many forms of operand:
    541      1.1  christos 
    542      1.1  christos    Rn			Register direct
    543      1.1  christos    @Rn			Register indirect
    544      1.1  christos    @(exp[:16], Rn)	Register indirect with displacement
    545      1.1  christos    @Rn+
    546      1.1  christos    @-Rn
    547      1.1  christos    @aa:8		absolute 8 bit
    548      1.1  christos    @aa:16		absolute 16 bit
    549      1.1  christos    @aa			absolute 16 bit
    550      1.1  christos 
    551      1.1  christos    #xx[:size]		immediate data
    552      1.1  christos    @(exp:[8], pc)	pc rel
    553      1.1  christos    @@aa[:8]		memory indirect.  */
    554      1.1  christos 
    555      1.1  christos static int
    556      1.1  christos constant_fits_width_p (struct h8_op *operand, offsetT width)
    557      1.1  christos {
    558      1.1  christos   offsetT num;
    559      1.1  christos 
    560      1.1  christos   num = ((operand->exp.X_add_number & 0xffffffff) ^ 0x80000000) - 0x80000000;
    561      1.1  christos   return (num & ~width) == 0 || (num | width) == ~0;
    562      1.1  christos }
    563      1.1  christos 
    564      1.1  christos static int
    565      1.1  christos constant_fits_size_p (struct h8_op *operand, int size, int no_symbols)
    566      1.1  christos {
    567      1.1  christos   offsetT num;
    568      1.1  christos 
    569      1.1  christos   if (no_symbols
    570      1.1  christos       && (operand->exp.X_add_symbol != 0 || operand->exp.X_op_symbol != 0))
    571      1.1  christos     return 0;
    572      1.1  christos   num = operand->exp.X_add_number & 0xffffffff;
    573      1.1  christos   switch (size)
    574      1.1  christos     {
    575      1.1  christos     case L_2:
    576      1.1  christos       return (num & ~3) == 0;
    577      1.1  christos     case L_3:
    578      1.1  christos       return (num & ~7) == 0;
    579      1.1  christos     case L_3NZ:
    580      1.1  christos       return num >= 1 && num < 8;
    581      1.1  christos     case L_4:
    582      1.1  christos       return (num & ~15) == 0;
    583      1.1  christos     case L_5:
    584      1.1  christos       return num >= 1 && num < 32;
    585      1.1  christos     case L_8:
    586      1.1  christos       num = (num ^ 0x80000000) - 0x80000000;
    587      1.1  christos       return (num & ~0xFF) == 0 || (num | 0x7F) == ~0;
    588      1.1  christos     case L_8U:
    589      1.1  christos       return (num & ~0xFF) == 0;
    590      1.1  christos     case L_16:
    591      1.1  christos       num = (num ^ 0x80000000) - 0x80000000;
    592      1.1  christos       return (num & ~0xFFFF) == 0 || (num | 0x7FFF) == ~0;
    593      1.1  christos     case L_16U:
    594      1.1  christos       return (num & ~0xFFFF) == 0;
    595      1.1  christos     case L_32:
    596      1.1  christos       return 1;
    597      1.1  christos     default:
    598      1.1  christos       abort ();
    599      1.1  christos     }
    600      1.1  christos }
    601      1.1  christos 
    602      1.1  christos static void
    603      1.1  christos get_operand (char **ptr, struct h8_op *op, int direction)
    604      1.1  christos {
    605      1.1  christos   char *src = *ptr;
    606      1.1  christos   op_type mode;
    607      1.1  christos   unsigned int num;
    608      1.1  christos   unsigned int len;
    609      1.1  christos 
    610      1.1  christos   op->mode = 0;
    611      1.1  christos 
    612      1.1  christos   /* Check for '(' and ')' for instructions ldm and stm.  */
    613      1.1  christos   if (src[0] == '(' && src[8] == ')')
    614      1.1  christos     ++ src;
    615      1.1  christos 
    616      1.1  christos   /* Gross.  Gross.  ldm and stm have a format not easily handled
    617      1.1  christos      by get_operand.  We deal with it explicitly here.  */
    618  1.1.1.2  christos   if (TOLOWER (src[0]) == 'e' && TOLOWER (src[1]) == 'r' &&
    619      1.1  christos       ISDIGIT (src[2]) && src[3] == '-' &&
    620      1.1  christos       TOLOWER (src[4]) == 'e' && TOLOWER (src[5]) == 'r' && ISDIGIT (src[6]))
    621      1.1  christos     {
    622      1.1  christos       int low, high;
    623      1.1  christos 
    624      1.1  christos       low = src[2] - '0';
    625      1.1  christos       high = src[6] - '0';
    626      1.1  christos 
    627      1.1  christos        /* Check register pair's validity as per tech note TN-H8*-193A/E
    628      1.1  christos 	  from Renesas for H8S and H8SX hardware manual.  */
    629      1.1  christos       if (   !(low == 0 && (high == 1 || high == 2 || high == 3))
    630      1.1  christos           && !(low == 1 && (high == 2 || high == 3 || high == 4) && SXmode)
    631      1.1  christos           && !(low == 2 && (high == 3 || ((high == 4 || high == 5) && SXmode)))
    632      1.1  christos           && !(low == 3 && (high == 4 || high == 5 || high == 6) && SXmode)
    633      1.1  christos           && !(low == 4 && (high == 5 || high == 6))
    634      1.1  christos           && !(low == 4 && high == 7 && SXmode)
    635      1.1  christos           && !(low == 5 && (high == 6 || high == 7) && SXmode)
    636      1.1  christos           && !(low == 6 && high == 7 && SXmode))
    637      1.1  christos 	as_bad (_("Invalid register list for ldm/stm\n"));
    638      1.1  christos 
    639      1.1  christos       /* Even sicker.  We encode two registers into op->reg.  One
    640      1.1  christos 	 for the low register to save, the other for the high
    641      1.1  christos 	 register to save;  we also set the high bit in op->reg
    642      1.1  christos 	 so we know this is "very special".  */
    643      1.1  christos       op->reg = 0x80000000 | (high << 8) | low;
    644      1.1  christos       op->mode = REG;
    645      1.1  christos       if (src[7] == ')')
    646      1.1  christos 	*ptr = src + 8;
    647      1.1  christos       else
    648      1.1  christos 	*ptr = src + 7;
    649      1.1  christos       return;
    650      1.1  christos     }
    651      1.1  christos 
    652      1.1  christos   len = parse_reg (src, &op->mode, &op->reg, direction);
    653      1.1  christos   if (len)
    654      1.1  christos     {
    655      1.1  christos       src += len;
    656      1.1  christos       if (*src == '.')
    657      1.1  christos 	{
    658      1.1  christos 	  int size = op->mode & SIZE;
    659      1.1  christos 	  switch (src[1])
    660      1.1  christos 	    {
    661      1.1  christos 	    case 'l': case 'L':
    662      1.1  christos 	      if (size != L_32)
    663      1.1  christos 		as_warn (_("mismatch between register and suffix"));
    664      1.1  christos 	      op->mode = (op->mode & ~MODE) | LOWREG;
    665      1.1  christos 	      break;
    666      1.1  christos 	    case 'w': case 'W':
    667      1.1  christos 	      if (size != L_32 && size != L_16)
    668      1.1  christos 		as_warn (_("mismatch between register and suffix"));
    669      1.1  christos 	      op->mode = (op->mode & ~MODE) | LOWREG;
    670      1.1  christos 	      op->mode = (op->mode & ~SIZE) | L_16;
    671      1.1  christos 	      break;
    672      1.1  christos 	    case 'b': case 'B':
    673      1.1  christos 	      op->mode = (op->mode & ~MODE) | LOWREG;
    674      1.1  christos 	      if (size != L_32 && size != L_8)
    675      1.1  christos 		as_warn (_("mismatch between register and suffix"));
    676      1.1  christos 	      op->mode = (op->mode & ~MODE) | LOWREG;
    677      1.1  christos 	      op->mode = (op->mode & ~SIZE) | L_8;
    678      1.1  christos 	      break;
    679      1.1  christos 	    default:
    680      1.1  christos 	      as_warn (_("invalid suffix after register."));
    681      1.1  christos 	      break;
    682      1.1  christos 	    }
    683      1.1  christos 	  src += 2;
    684      1.1  christos 	}
    685      1.1  christos       *ptr = src;
    686      1.1  christos       return;
    687      1.1  christos     }
    688      1.1  christos 
    689      1.1  christos   if (*src == '@')
    690      1.1  christos     {
    691      1.1  christos       src++;
    692      1.1  christos       if (*src == '@')
    693      1.1  christos 	{
    694      1.1  christos 	  *ptr = parse_exp (src + 1, op);
    695      1.1  christos 	  if (op->exp.X_add_number >= 0x100)
    696      1.1  christos 	    {
    697      1.1  christos 	      int divisor = 1;
    698      1.1  christos 
    699      1.1  christos 	      op->mode = VECIND;
    700      1.1  christos 	      /* FIXME : 2?  or 4?  */
    701      1.1  christos 	      if (op->exp.X_add_number >= 0x400)
    702      1.1  christos 		as_bad (_("address too high for vector table jmp/jsr"));
    703      1.1  christos 	      else if (op->exp.X_add_number >= 0x200)
    704      1.1  christos 		divisor = 4;
    705      1.1  christos 	      else
    706      1.1  christos 		divisor = 2;
    707      1.1  christos 
    708      1.1  christos 	      op->exp.X_add_number = op->exp.X_add_number / divisor - 0x80;
    709      1.1  christos 	    }
    710      1.1  christos 	  else
    711      1.1  christos 	    op->mode = MEMIND;
    712      1.1  christos 	  return;
    713      1.1  christos 	}
    714      1.1  christos 
    715      1.1  christos       if (*src == '-' || *src == '+')
    716      1.1  christos 	{
    717      1.1  christos 	  len = parse_reg (src + 1, &mode, &num, direction);
    718      1.1  christos 	  if (len == 0)
    719      1.1  christos 	    {
    720      1.1  christos 	      /* Oops, not a reg after all, must be ordinary exp.  */
    721      1.1  christos 	      op->mode = ABS | direction;
    722      1.1  christos 	      *ptr = parse_exp (src, op);
    723      1.1  christos 	      return;
    724      1.1  christos 	    }
    725      1.1  christos 
    726      1.1  christos 	  if (((mode & SIZE) != PSIZE)
    727      1.1  christos 	      /* For Normal mode accept 16 bit and 32 bit pointer registers.  */
    728      1.1  christos 	      && (!Nmode || ((mode & SIZE) != L_32)))
    729      1.1  christos 	    as_bad (_("Wrong size pointer register for architecture."));
    730      1.1  christos 
    731      1.1  christos 	  op->mode = src[0] == '-' ? RDPREDEC : RDPREINC;
    732      1.1  christos 	  op->reg = num;
    733      1.1  christos 	  *ptr = src + 1 + len;
    734      1.1  christos 	  return;
    735      1.1  christos 	}
    736      1.1  christos       if (*src == '(')
    737      1.1  christos 	{
    738      1.1  christos 	  src++;
    739      1.1  christos 
    740      1.1  christos 	  /* See if this is @(ERn.x, PC).  */
    741      1.1  christos 	  len = parse_reg (src, &mode, &op->reg, direction);
    742      1.1  christos 	  if (len != 0 && (mode & MODE) == REG && src[len] == '.')
    743      1.1  christos 	    {
    744      1.1  christos 	      switch (TOLOWER (src[len + 1]))
    745      1.1  christos 		{
    746      1.1  christos 		case 'b':
    747      1.1  christos 		  mode = PCIDXB | direction;
    748      1.1  christos 		  break;
    749      1.1  christos 		case 'w':
    750      1.1  christos 		  mode = PCIDXW | direction;
    751      1.1  christos 		  break;
    752      1.1  christos 		case 'l':
    753      1.1  christos 		  mode = PCIDXL | direction;
    754      1.1  christos 		  break;
    755      1.1  christos 		default:
    756      1.1  christos 		  mode = 0;
    757      1.1  christos 		  break;
    758      1.1  christos 		}
    759      1.1  christos 	      if (mode
    760      1.1  christos 		  && src[len + 2] == ','
    761  1.1.1.2  christos 		  && TOLOWER (src[len + 3]) != 'p'
    762      1.1  christos 		  && TOLOWER (src[len + 4]) != 'c'
    763      1.1  christos 		  && src[len + 5] != ')')
    764      1.1  christos 		{
    765      1.1  christos 		  *ptr = src + len + 6;
    766      1.1  christos 		  op->mode |= mode;
    767      1.1  christos 		  return;
    768      1.1  christos 		}
    769      1.1  christos 	      /* Fall through into disp case - the grammar is somewhat
    770      1.1  christos 		 ambiguous, so we should try whether it's a DISP operand
    771      1.1  christos 		 after all ("ER3.L" might be a poorly named label...).  */
    772      1.1  christos 	    }
    773      1.1  christos 
    774      1.1  christos 	  /* Disp.  */
    775      1.1  christos 
    776      1.1  christos 	  /* Start off assuming a 16 bit offset.  */
    777      1.1  christos 
    778      1.1  christos 	  src = parse_exp (src, op);
    779      1.1  christos 	  if (*src == ')')
    780      1.1  christos 	    {
    781      1.1  christos 	      op->mode |= ABS | direction;
    782      1.1  christos 	      *ptr = src + 1;
    783      1.1  christos 	      return;
    784      1.1  christos 	    }
    785      1.1  christos 
    786      1.1  christos 	  if (*src != ',')
    787      1.1  christos 	    {
    788      1.1  christos 	      as_bad (_("expected @(exp, reg16)"));
    789      1.1  christos 	      return;
    790      1.1  christos 	    }
    791      1.1  christos 	  src++;
    792      1.1  christos 
    793      1.1  christos 	  len = parse_reg (src, &mode, &op->reg, direction);
    794      1.1  christos 	  if (len == 0 || (mode & MODE) != REG)
    795      1.1  christos 	    {
    796      1.1  christos 	      as_bad (_("expected @(exp, reg16)"));
    797      1.1  christos 	      return;
    798      1.1  christos 	    }
    799      1.1  christos 	  src += len;
    800      1.1  christos 	  if (src[0] == '.')
    801      1.1  christos 	    {
    802      1.1  christos 	      switch (TOLOWER (src[1]))
    803      1.1  christos 		{
    804      1.1  christos 		case 'b':
    805      1.1  christos 		  op->mode |= INDEXB | direction;
    806      1.1  christos 		  break;
    807      1.1  christos 		case 'w':
    808      1.1  christos 		  op->mode |= INDEXW | direction;
    809      1.1  christos 		  break;
    810      1.1  christos 		case 'l':
    811      1.1  christos 		  op->mode |= INDEXL | direction;
    812      1.1  christos 		  break;
    813      1.1  christos 		default:
    814      1.1  christos 		  as_bad (_("expected .L, .W or .B for register in indexed addressing mode"));
    815      1.1  christos 		}
    816      1.1  christos 	      src += 2;
    817      1.1  christos 	      op->reg &= 7;
    818      1.1  christos 	    }
    819      1.1  christos 	  else
    820      1.1  christos 	    op->mode |= DISP | direction;
    821      1.1  christos 	  src = skip_colonthing (src, &op->mode);
    822      1.1  christos 
    823  1.1.1.3  christos 	  if (*src != ')')
    824      1.1  christos 	    {
    825      1.1  christos 	      as_bad (_("expected @(exp, reg16)"));
    826      1.1  christos 	      return;
    827      1.1  christos 	    }
    828      1.1  christos 	  *ptr = src + 1;
    829      1.1  christos 	  return;
    830      1.1  christos 	}
    831      1.1  christos       len = parse_reg (src, &mode, &num, direction);
    832      1.1  christos 
    833      1.1  christos       if (len)
    834      1.1  christos 	{
    835      1.1  christos 	  src += len;
    836      1.1  christos 	  if (*src == '+' || *src == '-')
    837      1.1  christos 	    {
    838      1.1  christos 	      if (((mode & SIZE) != PSIZE)
    839      1.1  christos 		  /* For Normal mode accept 16 bit and 32 bit pointer registers.  */
    840      1.1  christos 		  && (!Nmode || ((mode & SIZE) != L_32)))
    841      1.1  christos 		as_bad (_("Wrong size pointer register for architecture."));
    842      1.1  christos 	      op->mode = *src == '+' ? RSPOSTINC : RSPOSTDEC;
    843      1.1  christos 	      op->reg = num;
    844      1.1  christos 	      src++;
    845      1.1  christos 	      *ptr = src;
    846      1.1  christos 	      return;
    847      1.1  christos 	    }
    848      1.1  christos 	  if (((mode & SIZE) != PSIZE)
    849      1.1  christos 	      /* For Normal mode accept 16 bit and 32 bit pointer registers.  */
    850      1.1  christos 	      && (!Nmode || ((mode & SIZE) != L_32)))
    851      1.1  christos 	    as_bad (_("Wrong size pointer register for architecture."));
    852      1.1  christos 
    853      1.1  christos 	  op->mode = direction | IND | PSIZE;
    854      1.1  christos 	  op->reg = num;
    855      1.1  christos 	  *ptr = src;
    856      1.1  christos 
    857      1.1  christos 	  return;
    858      1.1  christos 	}
    859      1.1  christos       else
    860      1.1  christos 	{
    861      1.1  christos 	  /* must be a symbol */
    862      1.1  christos 
    863      1.1  christos 	  op->mode = ABS | direction;
    864      1.1  christos 	  *ptr = parse_exp (src, op);
    865      1.1  christos 	  return;
    866      1.1  christos 	}
    867      1.1  christos     }
    868      1.1  christos 
    869      1.1  christos   if (*src == '#')
    870      1.1  christos     {
    871      1.1  christos       op->mode = IMM;
    872      1.1  christos       *ptr = parse_exp (src + 1, op);
    873      1.1  christos       return;
    874      1.1  christos     }
    875  1.1.1.2  christos   else if (strncmp (src, "mach", 4) == 0 ||
    876      1.1  christos 	   strncmp (src, "macl", 4) == 0 ||
    877  1.1.1.2  christos 	   strncmp (src, "MACH", 4) == 0 ||
    878      1.1  christos 	   strncmp (src, "MACL", 4) == 0)
    879      1.1  christos     {
    880      1.1  christos       op->reg = TOLOWER (src[3]) == 'l';
    881      1.1  christos       op->mode = MACREG;
    882      1.1  christos       *ptr = src + 4;
    883      1.1  christos       return;
    884      1.1  christos     }
    885      1.1  christos   else
    886      1.1  christos     {
    887      1.1  christos       op->mode = PCREL;
    888      1.1  christos       *ptr = parse_exp (src, op);
    889      1.1  christos     }
    890      1.1  christos }
    891      1.1  christos 
    892      1.1  christos static char *
    893      1.1  christos get_operands (unsigned int noperands, char *op_end, struct h8_op *operand)
    894      1.1  christos {
    895      1.1  christos   char *ptr = op_end;
    896      1.1  christos 
    897      1.1  christos   switch (noperands)
    898      1.1  christos     {
    899      1.1  christos     case 0:
    900      1.1  christos       break;
    901      1.1  christos 
    902      1.1  christos     case 1:
    903      1.1  christos       ptr++;
    904      1.1  christos       get_operand (&ptr, operand + 0, SRC);
    905      1.1  christos       if (*ptr == ',')
    906      1.1  christos 	{
    907      1.1  christos 	  ptr++;
    908      1.1  christos 	  get_operand (&ptr, operand + 1, DST);
    909      1.1  christos 	}
    910      1.1  christos       break;
    911      1.1  christos 
    912      1.1  christos     case 2:
    913      1.1  christos       ptr++;
    914      1.1  christos       get_operand (&ptr, operand + 0, SRC);
    915      1.1  christos       if (*ptr == ',')
    916      1.1  christos 	ptr++;
    917      1.1  christos       get_operand (&ptr, operand + 1, DST);
    918      1.1  christos       break;
    919      1.1  christos 
    920      1.1  christos     case 3:
    921      1.1  christos       ptr++;
    922      1.1  christos       get_operand (&ptr, operand + 0, SRC);
    923      1.1  christos       if (*ptr == ',')
    924      1.1  christos 	ptr++;
    925      1.1  christos       get_operand (&ptr, operand + 1, DST);
    926      1.1  christos       if (*ptr == ',')
    927      1.1  christos 	ptr++;
    928      1.1  christos       get_operand (&ptr, operand + 2, OP3);
    929      1.1  christos       break;
    930      1.1  christos 
    931      1.1  christos     default:
    932      1.1  christos       abort ();
    933      1.1  christos     }
    934      1.1  christos 
    935      1.1  christos   return ptr;
    936      1.1  christos }
    937      1.1  christos 
    938      1.1  christos /* MOVA has special requirements.  Rather than adding twice the amount of
    939      1.1  christos    addressing modes, we simply special case it a bit.  */
    940      1.1  christos static void
    941      1.1  christos get_mova_operands (char *op_end, struct h8_op *operand)
    942      1.1  christos {
    943      1.1  christos   char *ptr = op_end;
    944      1.1  christos 
    945      1.1  christos   if (ptr[1] != '@' || ptr[2] != '(')
    946      1.1  christos     goto error;
    947      1.1  christos   ptr += 3;
    948      1.1  christos   operand[0].mode = 0;
    949      1.1  christos   ptr = parse_exp (ptr, &operand[0]);
    950      1.1  christos 
    951      1.1  christos   if (*ptr !=',')
    952      1.1  christos     goto error;
    953      1.1  christos   ptr++;
    954      1.1  christos   get_operand (&ptr, operand + 1, DST);
    955      1.1  christos 
    956      1.1  christos   if (*ptr =='.')
    957      1.1  christos     {
    958      1.1  christos       ptr++;
    959      1.1  christos       switch (*ptr++)
    960      1.1  christos 	{
    961      1.1  christos 	case 'b': case 'B':
    962      1.1  christos 	  operand[0].mode = (operand[0].mode & ~MODE) | INDEXB;
    963      1.1  christos 	  break;
    964      1.1  christos 	case 'w': case 'W':
    965      1.1  christos 	  operand[0].mode = (operand[0].mode & ~MODE) | INDEXW;
    966      1.1  christos 	  break;
    967      1.1  christos 	case 'l': case 'L':
    968      1.1  christos 	  operand[0].mode = (operand[0].mode & ~MODE) | INDEXL;
    969      1.1  christos 	  break;
    970      1.1  christos 	default:
    971      1.1  christos 	  goto error;
    972      1.1  christos 	}
    973      1.1  christos     }
    974      1.1  christos   else if ((operand[1].mode & MODE) == LOWREG)
    975      1.1  christos     {
    976  1.1.1.2  christos       switch (operand[1].mode & SIZE)
    977      1.1  christos 	{
    978      1.1  christos 	case L_8:
    979      1.1  christos 	  operand[0].mode = (operand[0].mode & ~MODE) | INDEXB;
    980      1.1  christos 	  break;
    981      1.1  christos 	case L_16:
    982      1.1  christos 	  operand[0].mode = (operand[0].mode & ~MODE) | INDEXW;
    983      1.1  christos 	  break;
    984      1.1  christos 	case L_32:
    985      1.1  christos 	  operand[0].mode = (operand[0].mode & ~MODE) | INDEXL;
    986      1.1  christos 	  break;
    987      1.1  christos 	default:
    988      1.1  christos 	  goto error;
    989      1.1  christos 	}
    990      1.1  christos     }
    991      1.1  christos   else
    992      1.1  christos     goto error;
    993      1.1  christos 
    994      1.1  christos   if (*ptr++ != ')' || *ptr++ != ',')
    995      1.1  christos     goto error;
    996      1.1  christos   get_operand (&ptr, operand + 2, OP3);
    997      1.1  christos   /* See if we can use the short form of MOVA.  */
    998      1.1  christos   if (((operand[1].mode & MODE) == REG || (operand[1].mode & MODE) == LOWREG)
    999      1.1  christos       && (operand[2].mode & MODE) == REG
   1000      1.1  christos       && (operand[1].reg & 7) == (operand[2].reg & 7))
   1001      1.1  christos     {
   1002      1.1  christos       operand[1].mode = operand[2].mode = 0;
   1003      1.1  christos       operand[0].reg = operand[2].reg & 7;
   1004      1.1  christos     }
   1005      1.1  christos   return;
   1006      1.1  christos 
   1007      1.1  christos  error:
   1008      1.1  christos   as_bad (_("expected valid addressing mode for mova: \"@(disp, ea.sz),ERn\""));
   1009      1.1  christos }
   1010      1.1  christos 
   1011      1.1  christos static void
   1012      1.1  christos get_rtsl_operands (char *ptr, struct h8_op *operand)
   1013      1.1  christos {
   1014      1.1  christos   int mode, len, type = 0;
   1015      1.1  christos   unsigned int num, num2;
   1016      1.1  christos 
   1017      1.1  christos   ptr++;
   1018      1.1  christos   if (*ptr == '(')
   1019      1.1  christos     {
   1020      1.1  christos       ptr++;
   1021      1.1  christos       type = 1;
   1022      1.1  christos     }
   1023      1.1  christos   len = parse_reg (ptr, &mode, &num, SRC);
   1024      1.1  christos   if (len == 0 || (mode & MODE) != REG)
   1025      1.1  christos     {
   1026      1.1  christos       as_bad (_("expected register"));
   1027      1.1  christos       return;
   1028      1.1  christos     }
   1029      1.1  christos   ptr += len;
   1030      1.1  christos   if (*ptr == '-')
   1031      1.1  christos     {
   1032      1.1  christos       len = parse_reg (++ptr, &mode, &num2, SRC);
   1033      1.1  christos       if (len == 0 || (mode & MODE) != REG)
   1034      1.1  christos 	{
   1035      1.1  christos 	  as_bad (_("expected register"));
   1036      1.1  christos 	  return;
   1037      1.1  christos 	}
   1038      1.1  christos       ptr += len;
   1039      1.1  christos       /* CONST_xxx are used as placeholders in the opcode table.  */
   1040      1.1  christos       num = num2 - num;
   1041      1.1  christos       if (num > 3)
   1042      1.1  christos 	{
   1043      1.1  christos 	  as_bad (_("invalid register list"));
   1044      1.1  christos 	  return;
   1045      1.1  christos 	}
   1046      1.1  christos     }
   1047      1.1  christos   else
   1048      1.1  christos     num2 = num, num = 0;
   1049      1.1  christos   if (type == 1 && *ptr++ != ')')
   1050      1.1  christos     {
   1051      1.1  christos       as_bad (_("expected closing paren"));
   1052      1.1  christos       return;
   1053      1.1  christos     }
   1054      1.1  christos   operand[0].mode = RS32;
   1055      1.1  christos   operand[1].mode = RD32;
   1056      1.1  christos   operand[0].reg = num;
   1057      1.1  christos   operand[1].reg = num2;
   1058      1.1  christos }
   1059      1.1  christos 
   1060      1.1  christos /* Passed a pointer to a list of opcodes which use different
   1061      1.1  christos    addressing modes, return the opcode which matches the opcodes
   1062      1.1  christos    provided.  */
   1063      1.1  christos 
   1064      1.1  christos static const struct h8_instruction *
   1065      1.1  christos get_specific (const struct h8_instruction *instruction,
   1066      1.1  christos 	      struct h8_op *operands, int size)
   1067      1.1  christos {
   1068      1.1  christos   const struct h8_instruction *this_try = instruction;
   1069      1.1  christos   const struct h8_instruction *found_other = 0, *found_mismatched = 0;
   1070      1.1  christos   int found = 0;
   1071      1.1  christos   int this_index = instruction->idx;
   1072      1.1  christos   int noperands = 0;
   1073      1.1  christos 
   1074      1.1  christos   /* There's only one ldm/stm and it's easier to just
   1075      1.1  christos      get out quick for them.  */
   1076      1.1  christos   if (OP_KIND (instruction->opcode->how) == O_LDM
   1077      1.1  christos       || OP_KIND (instruction->opcode->how) == O_STM)
   1078      1.1  christos     return this_try;
   1079      1.1  christos 
   1080      1.1  christos   while (noperands < 3 && operands[noperands].mode != 0)
   1081      1.1  christos     noperands++;
   1082      1.1  christos 
   1083      1.1  christos   while (this_index == instruction->idx && !found)
   1084      1.1  christos     {
   1085      1.1  christos       int this_size;
   1086      1.1  christos 
   1087      1.1  christos       found = 1;
   1088      1.1  christos       this_try = instruction++;
   1089      1.1  christos       this_size = this_try->opcode->how & SN;
   1090      1.1  christos 
   1091      1.1  christos       if (this_try->noperands != noperands)
   1092      1.1  christos 	found = 0;
   1093      1.1  christos       else if (this_try->noperands > 0)
   1094      1.1  christos 	{
   1095      1.1  christos 	  int i;
   1096      1.1  christos 
   1097      1.1  christos 	  for (i = 0; i < this_try->noperands && found; i++)
   1098      1.1  christos 	    {
   1099      1.1  christos 	      op_type op = this_try->opcode->args.nib[i];
   1100      1.1  christos 	      int op_mode = op & MODE;
   1101      1.1  christos 	      int op_size = op & SIZE;
   1102      1.1  christos 	      int x = operands[i].mode;
   1103      1.1  christos 	      int x_mode = x & MODE;
   1104      1.1  christos 	      int x_size = x & SIZE;
   1105      1.1  christos 
   1106      1.1  christos 	      if (op_mode == LOWREG && (x_mode == REG || x_mode == LOWREG))
   1107      1.1  christos 		{
   1108      1.1  christos 		  if ((x_size == L_8 && (operands[i].reg & 8) == 0)
   1109      1.1  christos 		      || (x_size == L_16 && (operands[i].reg & 8) == 8))
   1110      1.1  christos 		    as_warn (_("can't use high part of register in operand %d"), i);
   1111      1.1  christos 
   1112      1.1  christos 		  if (x_size != op_size)
   1113      1.1  christos 		    found = 0;
   1114      1.1  christos 		}
   1115      1.1  christos 	      else if (op_mode == REG)
   1116      1.1  christos 		{
   1117      1.1  christos 		  if (x_mode == LOWREG)
   1118      1.1  christos 		    x_mode = REG;
   1119      1.1  christos 		  if (x_mode != REG)
   1120      1.1  christos 		    found = 0;
   1121      1.1  christos 
   1122      1.1  christos 		  if (x_size == L_P)
   1123      1.1  christos 		    x_size = (Hmode ? L_32 : L_16);
   1124      1.1  christos 		  if (op_size == L_P)
   1125      1.1  christos 		    op_size = (Hmode ? L_32 : L_16);
   1126      1.1  christos 
   1127      1.1  christos 		  /* The size of the reg is v important.  */
   1128      1.1  christos 		  if (op_size != x_size)
   1129      1.1  christos 		    found = 0;
   1130      1.1  christos 		}
   1131      1.1  christos 	      else if (op_mode & CTRL)	/* control register */
   1132      1.1  christos 		{
   1133      1.1  christos 		  if (!(x_mode & CTRL))
   1134      1.1  christos 		    found = 0;
   1135      1.1  christos 
   1136      1.1  christos 		  switch (x_mode)
   1137      1.1  christos 		    {
   1138      1.1  christos 		    case CCR:
   1139      1.1  christos 		      if (op_mode != CCR &&
   1140      1.1  christos 			  op_mode != CCR_EXR &&
   1141      1.1  christos 			  op_mode != CC_EX_VB_SB)
   1142      1.1  christos 			found = 0;
   1143      1.1  christos 		      break;
   1144      1.1  christos 		    case EXR:
   1145      1.1  christos 		      if (op_mode != EXR &&
   1146      1.1  christos 			  op_mode != CCR_EXR &&
   1147      1.1  christos 			  op_mode != CC_EX_VB_SB)
   1148      1.1  christos 			found = 0;
   1149      1.1  christos 		      break;
   1150      1.1  christos 		    case MACH:
   1151      1.1  christos 		      if (op_mode != MACH &&
   1152      1.1  christos 			  op_mode != MACREG)
   1153      1.1  christos 			found = 0;
   1154      1.1  christos 		      break;
   1155      1.1  christos 		    case MACL:
   1156      1.1  christos 		      if (op_mode != MACL &&
   1157      1.1  christos 			  op_mode != MACREG)
   1158      1.1  christos 			found = 0;
   1159      1.1  christos 		      break;
   1160      1.1  christos 		    case VBR:
   1161      1.1  christos 		      if (op_mode != VBR &&
   1162      1.1  christos 			  op_mode != VBR_SBR &&
   1163      1.1  christos 			  op_mode != CC_EX_VB_SB)
   1164      1.1  christos 			found = 0;
   1165      1.1  christos 		      break;
   1166      1.1  christos 		    case SBR:
   1167      1.1  christos 		      if (op_mode != SBR &&
   1168      1.1  christos 			  op_mode != VBR_SBR &&
   1169      1.1  christos 			  op_mode != CC_EX_VB_SB)
   1170      1.1  christos 			found = 0;
   1171      1.1  christos 		      break;
   1172      1.1  christos 		    }
   1173      1.1  christos 		}
   1174      1.1  christos 	      else if ((op & ABSJMP) && (x_mode == ABS || x_mode == PCREL))
   1175      1.1  christos 		{
   1176      1.1  christos 		  operands[i].mode &= ~MODE;
   1177      1.1  christos 		  operands[i].mode |= ABSJMP;
   1178      1.1  christos 		  /* But it may not be 24 bits long.  */
   1179      1.1  christos 		  if (x_mode == ABS && !Hmode)
   1180      1.1  christos 		    {
   1181      1.1  christos 		      operands[i].mode &= ~SIZE;
   1182      1.1  christos 		      operands[i].mode |= L_16;
   1183      1.1  christos 		    }
   1184      1.1  christos 		  if ((operands[i].mode & SIZE) == L_32
   1185      1.1  christos 		      && (op_mode & SIZE) != L_32)
   1186      1.1  christos 		   found = 0;
   1187      1.1  christos 		}
   1188      1.1  christos 	      else if (x_mode == IMM && op_mode != IMM)
   1189      1.1  christos 		{
   1190      1.1  christos 		  offsetT num = operands[i].exp.X_add_number & 0xffffffff;
   1191      1.1  christos 		  if (op_mode == KBIT || op_mode == DBIT)
   1192      1.1  christos 		    /* This is ok if the immediate value is sensible.  */;
   1193      1.1  christos 		  else if (op_mode == CONST_2)
   1194      1.1  christos 		    found = num == 2;
   1195      1.1  christos 		  else if (op_mode == CONST_4)
   1196      1.1  christos 		    found = num == 4;
   1197      1.1  christos 		  else if (op_mode == CONST_8)
   1198      1.1  christos 		    found = num == 8;
   1199      1.1  christos 		  else if (op_mode == CONST_16)
   1200      1.1  christos 		    found = num == 16;
   1201      1.1  christos 		  else
   1202      1.1  christos 		    found = 0;
   1203      1.1  christos 		}
   1204      1.1  christos 	      else if (op_mode == PCREL && op_mode == x_mode)
   1205      1.1  christos 		{
   1206      1.1  christos 		  /* movsd, bsr/bc and bsr/bs only come in PCREL16 flavour:
   1207      1.1  christos 		     If x_size is L_8, promote it.  */
   1208      1.1  christos 		  if (OP_KIND (this_try->opcode->how) == O_MOVSD
   1209      1.1  christos 		      || OP_KIND (this_try->opcode->how) == O_BSRBC
   1210      1.1  christos 		      || OP_KIND (this_try->opcode->how) == O_BSRBS)
   1211      1.1  christos 		    if (x_size == L_8)
   1212      1.1  christos 		      x_size = L_16;
   1213      1.1  christos 
   1214      1.1  christos 		  /* The size of the displacement is important.  */
   1215      1.1  christos 		  if (op_size != x_size)
   1216      1.1  christos 		    found = 0;
   1217      1.1  christos 		}
   1218      1.1  christos 	      else if ((op_mode == DISP || op_mode == IMM || op_mode == ABS
   1219      1.1  christos 			|| op_mode == INDEXB || op_mode == INDEXW
   1220      1.1  christos 			|| op_mode == INDEXL)
   1221      1.1  christos 		       && op_mode == x_mode)
   1222      1.1  christos 		{
   1223      1.1  christos 		  /* Promote a L_24 to L_32 if it makes us match.  */
   1224      1.1  christos 		  if (x_size == L_24 && op_size == L_32)
   1225      1.1  christos 		    {
   1226      1.1  christos 		      x &= ~SIZE;
   1227      1.1  christos 		      x |= x_size = L_32;
   1228      1.1  christos 		    }
   1229      1.1  christos 
   1230      1.1  christos 		  if (((x_size == L_16 && op_size == L_16U)
   1231      1.1  christos 		       || (x_size == L_8 && op_size == L_8U)
   1232      1.1  christos 		       || (x_size == L_3 && op_size == L_3NZ))
   1233      1.1  christos 		      /* We're deliberately more permissive for ABS modes.  */
   1234      1.1  christos 		      && (op_mode == ABS
   1235      1.1  christos 			  || constant_fits_size_p (operands + i, op_size,
   1236      1.1  christos 						   op & NO_SYMBOLS)))
   1237      1.1  christos 		    x_size = op_size;
   1238      1.1  christos 
   1239      1.1  christos 		  if (x_size != 0 && op_size != x_size)
   1240      1.1  christos 		    found = 0;
   1241      1.1  christos 		  else if (x_size == 0
   1242      1.1  christos 			   && ! constant_fits_size_p (operands + i, op_size,
   1243      1.1  christos 						      op & NO_SYMBOLS))
   1244      1.1  christos 		    found = 0;
   1245      1.1  christos 		}
   1246      1.1  christos 	      else if (op_mode != x_mode)
   1247      1.1  christos 		{
   1248      1.1  christos 		  found = 0;
   1249      1.1  christos 		}
   1250      1.1  christos 	    }
   1251      1.1  christos 	}
   1252      1.1  christos       if (found)
   1253      1.1  christos 	{
   1254      1.1  christos 	  if ((this_try->opcode->available == AV_H8SX && ! SXmode)
   1255      1.1  christos 	      || (this_try->opcode->available == AV_H8S && ! Smode)
   1256      1.1  christos 	      || (this_try->opcode->available == AV_H8H && ! Hmode))
   1257      1.1  christos 	    found = 0, found_other = this_try;
   1258      1.1  christos 	  else if (this_size != size && (this_size != SN && size != SN))
   1259      1.1  christos 	    found_mismatched = this_try, found = 0;
   1260      1.1  christos 
   1261      1.1  christos 	}
   1262      1.1  christos     }
   1263      1.1  christos   if (found)
   1264      1.1  christos     return this_try;
   1265      1.1  christos   if (found_other)
   1266      1.1  christos     {
   1267      1.1  christos       as_warn (_("Opcode `%s' with these operand types not available in %s mode"),
   1268      1.1  christos 	       found_other->opcode->name,
   1269      1.1  christos 	       (! Hmode && ! Smode ? "H8/300"
   1270      1.1  christos 		: SXmode ? "H8sx"
   1271      1.1  christos 		: Smode ? "H8/300S"
   1272      1.1  christos 		: "H8/300H"));
   1273      1.1  christos     }
   1274      1.1  christos   else if (found_mismatched)
   1275      1.1  christos     {
   1276      1.1  christos       as_warn (_("mismatch between opcode size and operand size"));
   1277      1.1  christos       return found_mismatched;
   1278      1.1  christos     }
   1279      1.1  christos   return 0;
   1280      1.1  christos }
   1281      1.1  christos 
   1282      1.1  christos static void
   1283  1.1.1.3  christos check_operand (struct h8_op *operand, unsigned int width, const char *string)
   1284      1.1  christos {
   1285      1.1  christos   if (operand->exp.X_add_symbol == 0
   1286      1.1  christos       && operand->exp.X_op_symbol == 0)
   1287      1.1  christos     {
   1288      1.1  christos       /* No symbol involved, let's look at offset, it's dangerous if
   1289      1.1  christos 	 any of the high bits are not 0 or ff's, find out by oring or
   1290      1.1  christos 	 anding with the width and seeing if the answer is 0 or all
   1291      1.1  christos 	 fs.  */
   1292      1.1  christos 
   1293      1.1  christos       if (! constant_fits_width_p (operand, width))
   1294      1.1  christos 	{
   1295      1.1  christos 	  if (width == 255
   1296      1.1  christos 	      && (operand->exp.X_add_number & 0xff00) == 0xff00)
   1297      1.1  christos 	    {
   1298      1.1  christos 	      /* Just ignore this one - which happens when trying to
   1299      1.1  christos 		 fit a 16 bit address truncated into an 8 bit address
   1300      1.1  christos 		 of something like bset.  */
   1301      1.1  christos 	    }
   1302      1.1  christos 	  else if (strcmp (string, "@") == 0
   1303      1.1  christos 		   && width == 0xffff
   1304      1.1  christos 		   && (operand->exp.X_add_number & 0xff8000) == 0xff8000)
   1305      1.1  christos 	    {
   1306      1.1  christos 	      /* Just ignore this one - which happens when trying to
   1307      1.1  christos 		 fit a 24 bit address truncated into a 16 bit address
   1308      1.1  christos 		 of something like mov.w.  */
   1309      1.1  christos 	    }
   1310      1.1  christos 	  else
   1311      1.1  christos 	    {
   1312      1.1  christos 	      as_warn (_("operand %s0x%lx out of range."), string,
   1313      1.1  christos 		       (unsigned long) operand->exp.X_add_number);
   1314      1.1  christos 	    }
   1315      1.1  christos 	}
   1316      1.1  christos     }
   1317      1.1  christos }
   1318      1.1  christos 
   1319      1.1  christos /* RELAXMODE has one of 3 values:
   1320      1.1  christos 
   1321      1.1  christos    0 Output a "normal" reloc, no relaxing possible for this insn/reloc
   1322      1.1  christos 
   1323      1.1  christos    1 Output a relaxable 24bit absolute mov.w address relocation
   1324      1.1  christos      (may relax into a 16bit absolute address).
   1325      1.1  christos 
   1326      1.1  christos    2 Output a relaxable 16/24 absolute mov.b address relocation
   1327      1.1  christos      (may relax into an 8bit absolute address).  */
   1328      1.1  christos 
   1329      1.1  christos static void
   1330      1.1  christos do_a_fix_imm (int offset, int nibble, struct h8_op *operand, int relaxmode, const struct h8_instruction *this_try)
   1331      1.1  christos {
   1332      1.1  christos   int idx;
   1333      1.1  christos   int size;
   1334      1.1  christos   int where;
   1335      1.1  christos   char *bytes = frag_now->fr_literal + offset;
   1336      1.1  christos 
   1337  1.1.1.3  christos   const char *t = ((operand->mode & MODE) == IMM) ? "#" : "@";
   1338      1.1  christos 
   1339      1.1  christos   if (operand->exp.X_add_symbol == 0)
   1340      1.1  christos     {
   1341      1.1  christos       switch (operand->mode & SIZE)
   1342      1.1  christos 	{
   1343      1.1  christos 	case L_2:
   1344      1.1  christos 	  check_operand (operand, 0x3, t);
   1345      1.1  christos 	  bytes[0] |= (operand->exp.X_add_number & 3) << (nibble ? 0 : 4);
   1346      1.1  christos 	  break;
   1347      1.1  christos 	case L_3:
   1348      1.1  christos 	case L_3NZ:
   1349      1.1  christos 	  check_operand (operand, 0x7, t);
   1350      1.1  christos 	  bytes[0] |= (operand->exp.X_add_number & 7) << (nibble ? 0 : 4);
   1351      1.1  christos 	  break;
   1352      1.1  christos 	case L_4:
   1353      1.1  christos 	  check_operand (operand, 0xF, t);
   1354      1.1  christos 	  bytes[0] |= (operand->exp.X_add_number & 15) << (nibble ? 0 : 4);
   1355      1.1  christos 	  break;
   1356      1.1  christos 	case L_5:
   1357      1.1  christos 	  check_operand (operand, 0x1F, t);
   1358      1.1  christos 	  bytes[0] |= operand->exp.X_add_number & 31;
   1359      1.1  christos 	  break;
   1360      1.1  christos 	case L_8:
   1361      1.1  christos 	case L_8U:
   1362      1.1  christos 	  check_operand (operand, 0xff, t);
   1363      1.1  christos 	  bytes[0] |= operand->exp.X_add_number;
   1364      1.1  christos 	  break;
   1365      1.1  christos 	case L_16:
   1366      1.1  christos 	case L_16U:
   1367      1.1  christos 	  check_operand (operand, 0xffff, t);
   1368      1.1  christos 	  bytes[0] |= operand->exp.X_add_number >> 8;
   1369      1.1  christos 	  bytes[1] |= operand->exp.X_add_number >> 0;
   1370      1.1  christos 	  /* MOVA needs both relocs to relax the second operand properly.  */
   1371      1.1  christos 	  if (relaxmode != 0
   1372      1.1  christos 	      && (OP_KIND(this_try->opcode->how) == O_MOVAB
   1373      1.1  christos 		  || OP_KIND(this_try->opcode->how) == O_MOVAW
   1374      1.1  christos 		  || OP_KIND(this_try->opcode->how) == O_MOVAL))
   1375      1.1  christos 	    {
   1376      1.1  christos 	      idx = BFD_RELOC_16;
   1377      1.1  christos 	      fix_new_exp (frag_now, offset, 2, &operand->exp, 0, idx);
   1378      1.1  christos 	    }
   1379      1.1  christos 	  break;
   1380      1.1  christos 	case L_24:
   1381      1.1  christos 	  check_operand (operand, 0xffffff, t);
   1382      1.1  christos 	  bytes[0] |= operand->exp.X_add_number >> 16;
   1383      1.1  christos 	  bytes[1] |= operand->exp.X_add_number >> 8;
   1384      1.1  christos 	  bytes[2] |= operand->exp.X_add_number >> 0;
   1385      1.1  christos 	  break;
   1386      1.1  christos 
   1387      1.1  christos 	case L_32:
   1388      1.1  christos 	  /* This should be done with bfd.  */
   1389      1.1  christos 	  bytes[0] |= operand->exp.X_add_number >> 24;
   1390      1.1  christos 	  bytes[1] |= operand->exp.X_add_number >> 16;
   1391      1.1  christos 	  bytes[2] |= operand->exp.X_add_number >> 8;
   1392      1.1  christos 	  bytes[3] |= operand->exp.X_add_number >> 0;
   1393      1.1  christos 	  if (relaxmode != 0)
   1394      1.1  christos 	    {
   1395  1.1.1.2  christos 	      if ((operand->mode & MODE) == DISP && relaxmode == 1)
   1396  1.1.1.2  christos 		idx = BFD_RELOC_H8_DISP32A16;
   1397  1.1.1.2  christos 	      else
   1398  1.1.1.2  christos 		idx = (relaxmode == 2) ? R_MOV24B1 : R_MOVL1;
   1399      1.1  christos 	      fix_new_exp (frag_now, offset, 4, &operand->exp, 0, idx);
   1400      1.1  christos 	    }
   1401      1.1  christos 	  break;
   1402      1.1  christos 	}
   1403      1.1  christos     }
   1404      1.1  christos   else
   1405      1.1  christos     {
   1406      1.1  christos       switch (operand->mode & SIZE)
   1407      1.1  christos 	{
   1408      1.1  christos 	case L_24:
   1409      1.1  christos 	case L_32:
   1410      1.1  christos 	  size = 4;
   1411      1.1  christos 	  where = (operand->mode & SIZE) == L_24 ? -1 : 0;
   1412  1.1.1.2  christos 	  if ((operand->mode & MODE) == DISP && relaxmode == 1)
   1413  1.1.1.2  christos 	    idx = BFD_RELOC_H8_DISP32A16;
   1414  1.1.1.4  christos 	  else if (relaxmode == 2)
   1415      1.1  christos 	    idx = R_MOV24B1;
   1416      1.1  christos 	  else if (relaxmode == 1)
   1417      1.1  christos 	    idx = R_MOVL1;
   1418      1.1  christos 	  else
   1419      1.1  christos 	    idx = R_RELLONG;
   1420      1.1  christos 	  break;
   1421      1.1  christos 	default:
   1422      1.1  christos 	  as_bad (_("Can't work out size of operand.\n"));
   1423  1.1.1.4  christos 	  /* Fall through.  */
   1424      1.1  christos 	case L_16:
   1425      1.1  christos 	case L_16U:
   1426      1.1  christos 	  size = 2;
   1427      1.1  christos 	  where = 0;
   1428      1.1  christos 	  if (relaxmode == 2)
   1429      1.1  christos 	    idx = R_MOV16B1;
   1430      1.1  christos 	  else
   1431      1.1  christos 	    idx = R_RELWORD;
   1432      1.1  christos 	  operand->exp.X_add_number =
   1433      1.1  christos 	    ((operand->exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
   1434      1.1  christos 	  operand->exp.X_add_number |= (bytes[0] << 8) | bytes[1];
   1435      1.1  christos 	  break;
   1436      1.1  christos 	case L_8:
   1437      1.1  christos 	  size = 1;
   1438      1.1  christos 	  where = 0;
   1439      1.1  christos 	  idx = R_RELBYTE;
   1440      1.1  christos 	  operand->exp.X_add_number =
   1441      1.1  christos 	    ((operand->exp.X_add_number & 0xff) ^ 0x80) - 0x80;
   1442      1.1  christos 	  operand->exp.X_add_number |= bytes[0];
   1443      1.1  christos 	}
   1444      1.1  christos 
   1445      1.1  christos       fix_new_exp (frag_now,
   1446      1.1  christos 		   offset + where,
   1447      1.1  christos 		   size,
   1448      1.1  christos 		   &operand->exp,
   1449      1.1  christos 		   0,
   1450      1.1  christos 		   idx);
   1451      1.1  christos     }
   1452      1.1  christos }
   1453      1.1  christos 
   1454      1.1  christos /* Now we know what sort of opcodes it is, let's build the bytes.  */
   1455      1.1  christos 
   1456      1.1  christos static void
   1457      1.1  christos build_bytes (const struct h8_instruction *this_try, struct h8_op *operand)
   1458      1.1  christos {
   1459      1.1  christos   int i;
   1460      1.1  christos   char *output = frag_more (this_try->length);
   1461      1.1  christos   const op_type *nibble_ptr = this_try->opcode->data.nib;
   1462      1.1  christos   op_type c;
   1463      1.1  christos   unsigned int nibble_count = 0;
   1464      1.1  christos   int op_at[3];
   1465      1.1  christos   int nib = 0;
   1466      1.1  christos   int movb = 0;
   1467      1.1  christos   char asnibbles[100];
   1468      1.1  christos   char *p = asnibbles;
   1469      1.1  christos   int high, low;
   1470      1.1  christos 
   1471      1.1  christos   if (!Hmode && this_try->opcode->available != AV_H8)
   1472      1.1  christos     as_warn (_("Opcode `%s' with these operand types not available in H8/300 mode"),
   1473      1.1  christos 	     this_try->opcode->name);
   1474  1.1.1.2  christos   else if (!Smode
   1475  1.1.1.2  christos 	   && this_try->opcode->available != AV_H8
   1476      1.1  christos 	   && this_try->opcode->available != AV_H8H)
   1477      1.1  christos     as_warn (_("Opcode `%s' with these operand types not available in H8/300H mode"),
   1478      1.1  christos 	     this_try->opcode->name);
   1479  1.1.1.2  christos   else if (!SXmode
   1480      1.1  christos 	   && this_try->opcode->available != AV_H8
   1481      1.1  christos 	   && this_try->opcode->available != AV_H8H
   1482      1.1  christos 	   && this_try->opcode->available != AV_H8S)
   1483      1.1  christos     as_warn (_("Opcode `%s' with these operand types not available in H8/300S mode"),
   1484      1.1  christos 	     this_try->opcode->name);
   1485      1.1  christos 
   1486      1.1  christos   while (*nibble_ptr != (op_type) E)
   1487      1.1  christos     {
   1488      1.1  christos       int d;
   1489      1.1  christos 
   1490      1.1  christos       nib = 0;
   1491      1.1  christos       c = *nibble_ptr++;
   1492      1.1  christos 
   1493      1.1  christos       d = (c & OP3) == OP3 ? 2 : (c & DST) == DST ? 1 : 0;
   1494      1.1  christos 
   1495      1.1  christos       if (c < 16)
   1496      1.1  christos 	nib = c;
   1497      1.1  christos       else
   1498      1.1  christos 	{
   1499      1.1  christos 	  int c2 = c & MODE;
   1500      1.1  christos 
   1501      1.1  christos 	  if (c2 == REG || c2 == LOWREG
   1502      1.1  christos 	      || c2 == IND || c2 == PREINC || c2 == PREDEC
   1503      1.1  christos 	      || c2 == POSTINC || c2 == POSTDEC)
   1504      1.1  christos 	    {
   1505      1.1  christos 	      nib = operand[d].reg;
   1506      1.1  christos 	      if (c2 == LOWREG)
   1507      1.1  christos 		nib &= 7;
   1508      1.1  christos 	    }
   1509      1.1  christos 
   1510      1.1  christos 	  else if (c & CTRL)	/* Control reg operand.  */
   1511      1.1  christos 	    nib = operand[d].reg;
   1512      1.1  christos 
   1513      1.1  christos 	  else if ((c & DISPREG) == (DISPREG))
   1514      1.1  christos 	    {
   1515      1.1  christos 	      nib = operand[d].reg;
   1516      1.1  christos 	    }
   1517      1.1  christos 	  else if (c2 == ABS)
   1518      1.1  christos 	    {
   1519      1.1  christos 	      operand[d].mode = c;
   1520      1.1  christos 	      op_at[d] = nibble_count;
   1521      1.1  christos 	      nib = 0;
   1522      1.1  christos 	    }
   1523      1.1  christos 	  else if (c2 == IMM || c2 == PCREL || c2 == ABS
   1524      1.1  christos 		   || (c & ABSJMP) || c2 == DISP)
   1525      1.1  christos 	    {
   1526      1.1  christos 	      operand[d].mode = c;
   1527      1.1  christos 	      op_at[d] = nibble_count;
   1528      1.1  christos 	      nib = 0;
   1529      1.1  christos 	    }
   1530      1.1  christos 	  else if ((c & IGNORE) || (c & DATA))
   1531      1.1  christos 	    nib = 0;
   1532      1.1  christos 
   1533      1.1  christos 	  else if (c2 == DBIT)
   1534      1.1  christos 	    {
   1535      1.1  christos 	      switch (operand[0].exp.X_add_number)
   1536      1.1  christos 		{
   1537      1.1  christos 		case 1:
   1538      1.1  christos 		  nib = c;
   1539      1.1  christos 		  break;
   1540      1.1  christos 		case 2:
   1541      1.1  christos 		  nib = 0x8 | c;
   1542      1.1  christos 		  break;
   1543      1.1  christos 		default:
   1544      1.1  christos 		  as_bad (_("Need #1 or #2 here"));
   1545      1.1  christos 		}
   1546      1.1  christos 	    }
   1547      1.1  christos 	  else if (c2 == KBIT)
   1548      1.1  christos 	    {
   1549      1.1  christos 	      switch (operand[0].exp.X_add_number)
   1550      1.1  christos 		{
   1551      1.1  christos 		case 1:
   1552      1.1  christos 		  nib = 0;
   1553      1.1  christos 		  break;
   1554      1.1  christos 		case 2:
   1555      1.1  christos 		  nib = 8;
   1556      1.1  christos 		  break;
   1557      1.1  christos 		case 4:
   1558      1.1  christos 		  if (!Hmode)
   1559      1.1  christos 		    as_warn (_("#4 not valid on H8/300."));
   1560      1.1  christos 		  nib = 9;
   1561      1.1  christos 		  break;
   1562      1.1  christos 
   1563      1.1  christos 		default:
   1564      1.1  christos 		  as_bad (_("Need #1 or #2 here"));
   1565      1.1  christos 		  break;
   1566      1.1  christos 		}
   1567      1.1  christos 	      /* Stop it making a fix.  */
   1568      1.1  christos 	      operand[0].mode = 0;
   1569      1.1  christos 	    }
   1570      1.1  christos 
   1571      1.1  christos 	  if (c & MEMRELAX)
   1572      1.1  christos 	    operand[d].mode |= MEMRELAX;
   1573      1.1  christos 
   1574      1.1  christos 	  if (c & B31)
   1575      1.1  christos 	    nib |= 0x8;
   1576      1.1  christos 
   1577      1.1  christos 	  if (c & B21)
   1578      1.1  christos 	    nib |= 0x4;
   1579      1.1  christos 
   1580      1.1  christos 	  if (c & B11)
   1581      1.1  christos 	    nib |= 0x2;
   1582      1.1  christos 
   1583      1.1  christos 	  if (c & B01)
   1584      1.1  christos 	    nib |= 0x1;
   1585      1.1  christos 
   1586      1.1  christos 	  if (c2 == MACREG)
   1587      1.1  christos 	    {
   1588      1.1  christos 	      if (operand[0].mode == MACREG)
   1589      1.1  christos 		/* stmac has mac[hl] as the first operand.  */
   1590      1.1  christos 		nib = 2 + operand[0].reg;
   1591      1.1  christos 	      else
   1592      1.1  christos 		/* ldmac has mac[hl] as the second operand.  */
   1593      1.1  christos 		nib = 2 + operand[1].reg;
   1594      1.1  christos 	    }
   1595      1.1  christos 	}
   1596      1.1  christos       nibble_count++;
   1597      1.1  christos 
   1598      1.1  christos       *p++ = nib;
   1599      1.1  christos     }
   1600      1.1  christos 
   1601      1.1  christos   /* Disgusting.  Why, oh why didn't someone ask us for advice
   1602      1.1  christos      on the assembler format.  */
   1603      1.1  christos   if (OP_KIND (this_try->opcode->how) == O_LDM)
   1604      1.1  christos     {
   1605      1.1  christos       high = (operand[1].reg >> 8) & 0xf;
   1606      1.1  christos       low  = (operand[1].reg) & 0xf;
   1607      1.1  christos       asnibbles[2] = high - low;
   1608      1.1  christos       asnibbles[7] = high;
   1609      1.1  christos     }
   1610      1.1  christos   else if (OP_KIND (this_try->opcode->how) == O_STM)
   1611      1.1  christos     {
   1612      1.1  christos       high = (operand[0].reg >> 8) & 0xf;
   1613      1.1  christos       low  = (operand[0].reg) & 0xf;
   1614      1.1  christos       asnibbles[2] = high - low;
   1615      1.1  christos       asnibbles[7] = low;
   1616      1.1  christos     }
   1617      1.1  christos 
   1618      1.1  christos   for (i = 0; i < this_try->length; i++)
   1619      1.1  christos     output[i] = (asnibbles[i * 2] << 4) | asnibbles[i * 2 + 1];
   1620      1.1  christos 
   1621  1.1.1.2  christos   /* Note if this is a mov.b or a bit manipulation instruction
   1622      1.1  christos      there is a special relaxation which only applies.  */
   1623      1.1  christos   if (   this_try->opcode->how == O (O_MOV,   SB)
   1624      1.1  christos       || this_try->opcode->how == O (O_BCLR,  SB)
   1625      1.1  christos       || this_try->opcode->how == O (O_BAND,  SB)
   1626      1.1  christos       || this_try->opcode->how == O (O_BIAND, SB)
   1627      1.1  christos       || this_try->opcode->how == O (O_BILD,  SB)
   1628      1.1  christos       || this_try->opcode->how == O (O_BIOR,  SB)
   1629      1.1  christos       || this_try->opcode->how == O (O_BIST,  SB)
   1630      1.1  christos       || this_try->opcode->how == O (O_BIXOR, SB)
   1631      1.1  christos       || this_try->opcode->how == O (O_BLD,   SB)
   1632      1.1  christos       || this_try->opcode->how == O (O_BNOT,  SB)
   1633      1.1  christos       || this_try->opcode->how == O (O_BOR,   SB)
   1634      1.1  christos       || this_try->opcode->how == O (O_BSET,  SB)
   1635      1.1  christos       || this_try->opcode->how == O (O_BST,   SB)
   1636      1.1  christos       || this_try->opcode->how == O (O_BTST,  SB)
   1637      1.1  christos       || this_try->opcode->how == O (O_BXOR,  SB))
   1638      1.1  christos     movb = 1;
   1639      1.1  christos 
   1640      1.1  christos   /* Output any fixes.  */
   1641      1.1  christos   for (i = 0; i < this_try->noperands; i++)
   1642      1.1  christos     {
   1643      1.1  christos       int x = operand[i].mode;
   1644      1.1  christos       int x_mode = x & MODE;
   1645      1.1  christos 
   1646      1.1  christos       if (x_mode == IMM || x_mode == DISP)
   1647  1.1.1.4  christos 	do_a_fix_imm (output - frag_now->fr_literal + op_at[i] / 2,
   1648  1.1.1.4  christos 		      op_at[i] & 1, operand + i, (x & MEMRELAX) != 0,
   1649  1.1.1.4  christos 		      this_try);
   1650      1.1  christos       else if (x_mode == ABS)
   1651      1.1  christos 	do_a_fix_imm (output - frag_now->fr_literal + op_at[i] / 2,
   1652      1.1  christos 		      op_at[i] & 1, operand + i,
   1653      1.1  christos 		      (x & MEMRELAX) ? movb + 1 : 0,
   1654      1.1  christos 		      this_try);
   1655      1.1  christos 
   1656      1.1  christos       else if (x_mode == PCREL)
   1657      1.1  christos 	{
   1658      1.1  christos 	  int size16 = (x & SIZE) == L_16;
   1659      1.1  christos 	  int size = size16 ? 2 : 1;
   1660      1.1  christos 	  int type = size16 ? R_PCRWORD : R_PCRBYTE;
   1661      1.1  christos 	  fixS *fixP;
   1662      1.1  christos 
   1663      1.1  christos 	  check_operand (operand + i, size16 ? 0x7fff : 0x7f, "@");
   1664      1.1  christos 
   1665      1.1  christos 	  if (operand[i].exp.X_add_number & 1)
   1666      1.1  christos 	    as_warn (_("branch operand has odd offset (%lx)\n"),
   1667      1.1  christos 		     (unsigned long) operand->exp.X_add_number);
   1668      1.1  christos 	  if (size16)
   1669      1.1  christos 	    {
   1670      1.1  christos 	      operand[i].exp.X_add_number =
   1671      1.1  christos 		((operand[i].exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
   1672      1.1  christos 	    }
   1673      1.1  christos 	  else
   1674      1.1  christos 	    {
   1675      1.1  christos 	      operand[i].exp.X_add_number =
   1676      1.1  christos 		((operand[i].exp.X_add_number & 0xff) ^ 0x80) - 0x80;
   1677      1.1  christos 	    }
   1678      1.1  christos 
   1679      1.1  christos 	  /* For BRA/S.  */
   1680      1.1  christos 	  if (! size16)
   1681      1.1  christos 	    operand[i].exp.X_add_number |= output[op_at[i] / 2];
   1682      1.1  christos 
   1683      1.1  christos 	  fixP = fix_new_exp (frag_now,
   1684      1.1  christos 			      output - frag_now->fr_literal + op_at[i] / 2,
   1685      1.1  christos 			      size,
   1686      1.1  christos 			      &operand[i].exp,
   1687      1.1  christos 			      1,
   1688      1.1  christos 			      type);
   1689      1.1  christos 	  fixP->fx_signed = 1;
   1690      1.1  christos 	}
   1691      1.1  christos       else if (x_mode == MEMIND)
   1692      1.1  christos 	{
   1693      1.1  christos 	  check_operand (operand + i, 0xff, "@@");
   1694      1.1  christos 	  fix_new_exp (frag_now,
   1695      1.1  christos 		       output - frag_now->fr_literal + 1,
   1696      1.1  christos 		       1,
   1697      1.1  christos 		       &operand[i].exp,
   1698      1.1  christos 		       0,
   1699      1.1  christos 		       R_MEM_INDIRECT);
   1700      1.1  christos 	}
   1701      1.1  christos       else if (x_mode == VECIND)
   1702      1.1  christos 	{
   1703      1.1  christos 	  check_operand (operand + i, 0x7f, "@@");
   1704      1.1  christos 	  /* FIXME: approximating the effect of "B31" here...
   1705      1.1  christos 	     This is very hackish, and ought to be done a better way.  */
   1706      1.1  christos 	  operand[i].exp.X_add_number |= 0x80;
   1707      1.1  christos 	  fix_new_exp (frag_now,
   1708      1.1  christos 		       output - frag_now->fr_literal + 1,
   1709      1.1  christos 		       1,
   1710      1.1  christos 		       &operand[i].exp,
   1711      1.1  christos 		       0,
   1712      1.1  christos 		       R_MEM_INDIRECT);
   1713      1.1  christos 	}
   1714      1.1  christos       else if (x & ABSJMP)
   1715      1.1  christos 	{
   1716      1.1  christos 	  int where = 0;
   1717      1.1  christos 	  bfd_reloc_code_real_type reloc_type = R_JMPL1;
   1718      1.1  christos 
   1719      1.1  christos 	  /* To be compatible with the proposed H8 ELF format, we
   1720      1.1  christos 	     want the relocation's offset to point to the first byte
   1721      1.1  christos 	     that will be modified, not to the start of the instruction.  */
   1722  1.1.1.2  christos 
   1723      1.1  christos 	  if ((operand->mode & SIZE) == L_32)
   1724      1.1  christos 	    {
   1725      1.1  christos 	      where = 2;
   1726      1.1  christos 	      reloc_type = R_RELLONG;
   1727      1.1  christos 	    }
   1728      1.1  christos 	  else
   1729      1.1  christos 	    where = 1;
   1730      1.1  christos 
   1731      1.1  christos 	  /* This jmp may be a jump or a branch.  */
   1732      1.1  christos 
   1733  1.1.1.2  christos 	  check_operand (operand + i,
   1734  1.1.1.2  christos 			 SXmode ? 0xffffffff : Hmode ? 0xffffff : 0xffff,
   1735      1.1  christos 			 "@");
   1736      1.1  christos 
   1737      1.1  christos 	  if (operand[i].exp.X_add_number & 1)
   1738      1.1  christos 	    as_warn (_("branch operand has odd offset (%lx)\n"),
   1739      1.1  christos 		     (unsigned long) operand->exp.X_add_number);
   1740      1.1  christos 
   1741      1.1  christos 	  if (!Hmode)
   1742      1.1  christos 	    operand[i].exp.X_add_number =
   1743      1.1  christos 	      ((operand[i].exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
   1744      1.1  christos 	  fix_new_exp (frag_now,
   1745      1.1  christos 		       output - frag_now->fr_literal + where,
   1746      1.1  christos 		       4,
   1747      1.1  christos 		       &operand[i].exp,
   1748      1.1  christos 		       0,
   1749      1.1  christos 		       reloc_type);
   1750      1.1  christos 	}
   1751      1.1  christos     }
   1752      1.1  christos }
   1753      1.1  christos 
   1754      1.1  christos /* Try to give an intelligent error message for common and simple to
   1755      1.1  christos    detect errors.  */
   1756      1.1  christos 
   1757      1.1  christos static void
   1758      1.1  christos clever_message (const struct h8_instruction *instruction,
   1759      1.1  christos 		struct h8_op *operand)
   1760      1.1  christos {
   1761      1.1  christos   /* Find out if there was more than one possible opcode.  */
   1762      1.1  christos 
   1763      1.1  christos   if ((instruction + 1)->idx != instruction->idx)
   1764      1.1  christos     {
   1765      1.1  christos       int argn;
   1766      1.1  christos 
   1767      1.1  christos       /* Only one opcode of this flavour, try to guess which operand
   1768      1.1  christos          didn't match.  */
   1769      1.1  christos       for (argn = 0; argn < instruction->noperands; argn++)
   1770      1.1  christos 	{
   1771      1.1  christos 	  switch (instruction->opcode->args.nib[argn])
   1772      1.1  christos 	    {
   1773      1.1  christos 	    case RD16:
   1774      1.1  christos 	      if (operand[argn].mode != RD16)
   1775      1.1  christos 		{
   1776      1.1  christos 		  as_bad (_("destination operand must be 16 bit register"));
   1777      1.1  christos 		  return;
   1778      1.1  christos 
   1779      1.1  christos 		}
   1780      1.1  christos 	      break;
   1781      1.1  christos 
   1782      1.1  christos 	    case RS8:
   1783      1.1  christos 	      if (operand[argn].mode != RS8)
   1784      1.1  christos 		{
   1785      1.1  christos 		  as_bad (_("source operand must be 8 bit register"));
   1786      1.1  christos 		  return;
   1787      1.1  christos 		}
   1788      1.1  christos 	      break;
   1789      1.1  christos 
   1790      1.1  christos 	    case ABS16DST:
   1791      1.1  christos 	      if (operand[argn].mode != ABS16DST)
   1792      1.1  christos 		{
   1793      1.1  christos 		  as_bad (_("destination operand must be 16bit absolute address"));
   1794      1.1  christos 		  return;
   1795      1.1  christos 		}
   1796      1.1  christos 	      break;
   1797      1.1  christos 	    case RD8:
   1798      1.1  christos 	      if (operand[argn].mode != RD8)
   1799      1.1  christos 		{
   1800      1.1  christos 		  as_bad (_("destination operand must be 8 bit register"));
   1801      1.1  christos 		  return;
   1802      1.1  christos 		}
   1803      1.1  christos 	      break;
   1804      1.1  christos 
   1805      1.1  christos 	    case ABS16SRC:
   1806      1.1  christos 	      if (operand[argn].mode != ABS16SRC)
   1807      1.1  christos 		{
   1808      1.1  christos 		  as_bad (_("source operand must be 16bit absolute address"));
   1809      1.1  christos 		  return;
   1810      1.1  christos 		}
   1811      1.1  christos 	      break;
   1812      1.1  christos 
   1813      1.1  christos 	    }
   1814      1.1  christos 	}
   1815      1.1  christos     }
   1816      1.1  christos   as_bad (_("invalid operands"));
   1817      1.1  christos }
   1818      1.1  christos 
   1819      1.1  christos 
   1820      1.1  christos /* If OPERAND is part of an address, adjust its size and value given
   1821      1.1  christos    that it addresses SIZE bytes.
   1822      1.1  christos 
   1823      1.1  christos    This function decides how big non-immediate constants are when no
   1824      1.1  christos    size was explicitly given.  It also scales down the assembly-level
   1825      1.1  christos    displacement in an @(d:2,ERn) operand.  */
   1826      1.1  christos 
   1827      1.1  christos static void
   1828      1.1  christos fix_operand_size (struct h8_op *operand, int size)
   1829      1.1  christos {
   1830      1.1  christos   if (SXmode && (operand->mode & MODE) == DISP)
   1831      1.1  christos     {
   1832      1.1  christos       /* If the user didn't specify an operand width, see if we
   1833      1.1  christos 	 can use @(d:2,ERn).  */
   1834      1.1  christos       if ((operand->mode & SIZE) == 0
   1835      1.1  christos 	  && operand->exp.X_add_symbol == 0
   1836      1.1  christos 	  && operand->exp.X_op_symbol == 0
   1837      1.1  christos 	  && (operand->exp.X_add_number == size
   1838      1.1  christos 	      || operand->exp.X_add_number == size * 2
   1839      1.1  christos 	      || operand->exp.X_add_number == size * 3))
   1840      1.1  christos 	operand->mode |= L_2;
   1841      1.1  christos 
   1842      1.1  christos       /* Scale down the displacement in an @(d:2,ERn) operand.
   1843      1.1  christos 	 X_add_number then contains the desired field value.  */
   1844      1.1  christos       if ((operand->mode & SIZE) == L_2)
   1845      1.1  christos 	{
   1846      1.1  christos 	  if (operand->exp.X_add_number % size != 0)
   1847      1.1  christos 	    as_warn (_("operand/size mis-match"));
   1848      1.1  christos 	  operand->exp.X_add_number /= size;
   1849      1.1  christos 	}
   1850      1.1  christos     }
   1851      1.1  christos 
   1852      1.1  christos   if ((operand->mode & SIZE) == 0)
   1853      1.1  christos     switch (operand->mode & MODE)
   1854      1.1  christos       {
   1855      1.1  christos       case DISP:
   1856      1.1  christos       case INDEXB:
   1857      1.1  christos       case INDEXW:
   1858      1.1  christos       case INDEXL:
   1859      1.1  christos       case ABS:
   1860      1.1  christos 	/* Pick a 24-bit address unless we know that a 16-bit address
   1861      1.1  christos 	   is safe.  get_specific() will relax L_24 into L_32 where
   1862      1.1  christos 	   necessary.  */
   1863      1.1  christos 	if (Hmode
   1864  1.1.1.2  christos 	    && !Nmode
   1865      1.1  christos 	    && ((((addressT) operand->exp.X_add_number + 0x8000)
   1866      1.1  christos 		 & 0xffffffff) > 0xffff
   1867      1.1  christos 		|| operand->exp.X_add_symbol != 0
   1868      1.1  christos 		|| operand->exp.X_op_symbol != 0))
   1869      1.1  christos 	  operand->mode |= L_24;
   1870      1.1  christos 	else
   1871      1.1  christos 	  operand->mode |= L_16;
   1872      1.1  christos 	break;
   1873      1.1  christos 
   1874      1.1  christos       case PCREL:
   1875      1.1  christos 	if ((((addressT) operand->exp.X_add_number + 0x80)
   1876      1.1  christos 	     & 0xffffffff) <= 0xff)
   1877      1.1  christos 	  {
   1878      1.1  christos 	    if (operand->exp.X_add_symbol != NULL)
   1879      1.1  christos 	      operand->mode |= bsize;
   1880      1.1  christos 	    else
   1881      1.1  christos 	      operand->mode |= L_8;
   1882      1.1  christos 	  }
   1883      1.1  christos 	else
   1884      1.1  christos 	  operand->mode |= L_16;
   1885      1.1  christos 	break;
   1886      1.1  christos       }
   1887      1.1  christos }
   1888      1.1  christos 
   1889      1.1  christos 
   1890      1.1  christos /* This is the guts of the machine-dependent assembler.  STR points to
   1891      1.1  christos    a machine dependent instruction.  This function is supposed to emit
   1892      1.1  christos    the frags/bytes it assembles.  */
   1893      1.1  christos 
   1894      1.1  christos void
   1895      1.1  christos md_assemble (char *str)
   1896      1.1  christos {
   1897      1.1  christos   char *op_start;
   1898      1.1  christos   char *op_end;
   1899      1.1  christos   struct h8_op operand[3];
   1900      1.1  christos   const struct h8_instruction *instruction;
   1901      1.1  christos   const struct h8_instruction *prev_instruction;
   1902      1.1  christos 
   1903      1.1  christos   char *dot = 0;
   1904      1.1  christos   char *slash = 0;
   1905      1.1  christos   char c;
   1906      1.1  christos   int size, i;
   1907      1.1  christos 
   1908      1.1  christos   /* Drop leading whitespace.  */
   1909      1.1  christos   while (*str == ' ')
   1910      1.1  christos     str++;
   1911      1.1  christos 
   1912      1.1  christos   /* Find the op code end.  */
   1913      1.1  christos   for (op_start = op_end = str;
   1914      1.1  christos        *op_end != 0 && *op_end != ' ';
   1915      1.1  christos        op_end++)
   1916      1.1  christos     {
   1917      1.1  christos       if (*op_end == '.')
   1918      1.1  christos 	{
   1919      1.1  christos 	  dot = op_end + 1;
   1920      1.1  christos 	  *op_end = 0;
   1921      1.1  christos 	  op_end += 2;
   1922      1.1  christos 	  break;
   1923      1.1  christos 	}
   1924      1.1  christos       else if (*op_end == '/' && ! slash)
   1925      1.1  christos 	slash = op_end;
   1926      1.1  christos     }
   1927      1.1  christos 
   1928      1.1  christos   if (op_end == op_start)
   1929      1.1  christos     {
   1930      1.1  christos       as_bad (_("can't find opcode "));
   1931      1.1  christos     }
   1932      1.1  christos   c = *op_end;
   1933      1.1  christos 
   1934      1.1  christos   *op_end = 0;
   1935      1.1  christos 
   1936      1.1  christos   /* The assembler stops scanning the opcode at slashes, so it fails
   1937      1.1  christos      to make characters following them lower case.  Fix them.  */
   1938      1.1  christos   if (slash)
   1939      1.1  christos     while (*++slash)
   1940      1.1  christos       *slash = TOLOWER (*slash);
   1941      1.1  christos 
   1942      1.1  christos   instruction = (const struct h8_instruction *)
   1943      1.1  christos     hash_find (opcode_hash_control, op_start);
   1944      1.1  christos 
   1945      1.1  christos   if (instruction == NULL)
   1946      1.1  christos     {
   1947      1.1  christos       as_bad (_("unknown opcode"));
   1948      1.1  christos       return;
   1949      1.1  christos     }
   1950      1.1  christos 
   1951      1.1  christos   /* We used to set input_line_pointer to the result of get_operands,
   1952      1.1  christos      but that is wrong.  Our caller assumes we don't change it.  */
   1953      1.1  christos 
   1954      1.1  christos   operand[0].mode = 0;
   1955      1.1  christos   operand[1].mode = 0;
   1956      1.1  christos   operand[2].mode = 0;
   1957      1.1  christos 
   1958      1.1  christos   if (OP_KIND (instruction->opcode->how) == O_MOVAB
   1959      1.1  christos       || OP_KIND (instruction->opcode->how) == O_MOVAW
   1960      1.1  christos       || OP_KIND (instruction->opcode->how) == O_MOVAL)
   1961      1.1  christos     get_mova_operands (op_end, operand);
   1962      1.1  christos   else if (OP_KIND (instruction->opcode->how) == O_RTEL
   1963      1.1  christos 	   || OP_KIND (instruction->opcode->how) == O_RTSL)
   1964      1.1  christos     get_rtsl_operands (op_end, operand);
   1965      1.1  christos   else
   1966      1.1  christos     get_operands (instruction->noperands, op_end, operand);
   1967      1.1  christos 
   1968      1.1  christos   *op_end = c;
   1969      1.1  christos   prev_instruction = instruction;
   1970      1.1  christos 
   1971      1.1  christos   /* Now we have operands from instruction.
   1972      1.1  christos      Let's check them out for ldm and stm.  */
   1973      1.1  christos   if (OP_KIND (instruction->opcode->how) == O_LDM)
   1974      1.1  christos     {
   1975      1.1  christos       /* The first operand must be @er7+, and the
   1976      1.1  christos 	 second operand must be a register pair.  */
   1977      1.1  christos       if ((operand[0].mode != RSINC)
   1978      1.1  christos            || (operand[0].reg != 7)
   1979      1.1  christos            || ((operand[1].reg & 0x80000000) == 0))
   1980      1.1  christos 	as_bad (_("invalid operand in ldm"));
   1981      1.1  christos     }
   1982      1.1  christos   else if (OP_KIND (instruction->opcode->how) == O_STM)
   1983      1.1  christos     {
   1984      1.1  christos       /* The first operand must be a register pair,
   1985      1.1  christos 	 and the second operand must be @-er7.  */
   1986      1.1  christos       if (((operand[0].reg & 0x80000000) == 0)
   1987      1.1  christos             || (operand[1].mode != RDDEC)
   1988      1.1  christos             || (operand[1].reg != 7))
   1989      1.1  christos 	as_bad (_("invalid operand in stm"));
   1990      1.1  christos     }
   1991      1.1  christos 
   1992      1.1  christos   size = SN;
   1993      1.1  christos   if (dot)
   1994      1.1  christos     {
   1995      1.1  christos       switch (TOLOWER (*dot))
   1996      1.1  christos 	{
   1997      1.1  christos 	case 'b':
   1998      1.1  christos 	  size = SB;
   1999      1.1  christos 	  break;
   2000      1.1  christos 
   2001      1.1  christos 	case 'w':
   2002      1.1  christos 	  size = SW;
   2003      1.1  christos 	  break;
   2004      1.1  christos 
   2005      1.1  christos 	case 'l':
   2006      1.1  christos 	  size = SL;
   2007      1.1  christos 	  break;
   2008      1.1  christos 	}
   2009      1.1  christos     }
   2010      1.1  christos   if (OP_KIND (instruction->opcode->how) == O_MOVAB ||
   2011      1.1  christos       OP_KIND (instruction->opcode->how) == O_MOVAW ||
   2012      1.1  christos       OP_KIND (instruction->opcode->how) == O_MOVAL)
   2013      1.1  christos     {
   2014      1.1  christos       switch (operand[0].mode & MODE)
   2015      1.1  christos 	{
   2016      1.1  christos 	case INDEXB:
   2017      1.1  christos 	default:
   2018      1.1  christos 	  fix_operand_size (&operand[1], 1);
   2019      1.1  christos 	  break;
   2020      1.1  christos 	case INDEXW:
   2021      1.1  christos 	  fix_operand_size (&operand[1], 2);
   2022      1.1  christos 	  break;
   2023      1.1  christos 	case INDEXL:
   2024      1.1  christos 	  fix_operand_size (&operand[1], 4);
   2025      1.1  christos 	  break;
   2026      1.1  christos 	}
   2027      1.1  christos     }
   2028      1.1  christos   else
   2029      1.1  christos     {
   2030      1.1  christos       for (i = 0; i < 3 && operand[i].mode != 0; i++)
   2031      1.1  christos 	switch (size)
   2032      1.1  christos 	  {
   2033      1.1  christos 	  case SN:
   2034      1.1  christos 	  case SB:
   2035      1.1  christos 	  default:
   2036      1.1  christos 	    fix_operand_size (&operand[i], 1);
   2037      1.1  christos 	    break;
   2038      1.1  christos 	  case SW:
   2039      1.1  christos 	    fix_operand_size (&operand[i], 2);
   2040      1.1  christos 	    break;
   2041      1.1  christos 	  case SL:
   2042      1.1  christos 	    fix_operand_size (&operand[i], 4);
   2043      1.1  christos 	    break;
   2044      1.1  christos 	  }
   2045      1.1  christos     }
   2046      1.1  christos 
   2047      1.1  christos   instruction = get_specific (instruction, operand, size);
   2048      1.1  christos 
   2049      1.1  christos   if (instruction == 0)
   2050      1.1  christos     {
   2051      1.1  christos       /* Couldn't find an opcode which matched the operands.  */
   2052      1.1  christos       char *where = frag_more (2);
   2053      1.1  christos 
   2054      1.1  christos       where[0] = 0x0;
   2055      1.1  christos       where[1] = 0x0;
   2056      1.1  christos       clever_message (prev_instruction, operand);
   2057      1.1  christos 
   2058      1.1  christos       return;
   2059      1.1  christos     }
   2060      1.1  christos 
   2061      1.1  christos   build_bytes (instruction, operand);
   2062      1.1  christos 
   2063      1.1  christos   dwarf2_emit_insn (instruction->length);
   2064      1.1  christos }
   2065      1.1  christos 
   2066      1.1  christos symbolS *
   2067      1.1  christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   2068      1.1  christos {
   2069      1.1  christos   return 0;
   2070      1.1  christos }
   2071      1.1  christos 
   2072      1.1  christos /* Various routines to kill one day.  */
   2073      1.1  christos 
   2074  1.1.1.3  christos const char *
   2075      1.1  christos md_atof (int type, char *litP, int *sizeP)
   2076      1.1  christos {
   2077      1.1  christos   return ieee_md_atof (type, litP, sizeP, TRUE);
   2078      1.1  christos }
   2079      1.1  christos 
   2080      1.1  christos #define OPTION_H_TICK_HEX      (OPTION_MD_BASE)
   2082      1.1  christos #define OPTION_MACH            (OPTION_MD_BASE+1)
   2083      1.1  christos 
   2084  1.1.1.2  christos const char *md_shortopts = "";
   2085  1.1.1.2  christos struct option md_longopts[] =
   2086      1.1  christos {
   2087  1.1.1.2  christos   { "h-tick-hex", no_argument,	      NULL, OPTION_H_TICK_HEX  },
   2088      1.1  christos   { "mach", required_argument, NULL, OPTION_MACH },
   2089      1.1  christos   {NULL, no_argument, NULL, 0}
   2090      1.1  christos };
   2091      1.1  christos 
   2092      1.1  christos size_t md_longopts_size = sizeof (md_longopts);
   2093  1.1.1.2  christos 
   2094  1.1.1.2  christos struct mach_func
   2095  1.1.1.2  christos {
   2096  1.1.1.2  christos   const char *name;
   2097  1.1.1.2  christos   void (*func) (void);
   2098  1.1.1.2  christos };
   2099  1.1.1.2  christos 
   2100  1.1.1.2  christos static void
   2101  1.1.1.2  christos mach_h8300h (void)
   2102  1.1.1.2  christos {
   2103  1.1.1.2  christos   Hmode = 1;
   2104  1.1.1.2  christos   Smode = 0;
   2105  1.1.1.2  christos   Nmode = 0;
   2106  1.1.1.2  christos   SXmode = 0;
   2107  1.1.1.2  christos   default_mach = bfd_mach_h8300h;
   2108  1.1.1.2  christos }
   2109  1.1.1.2  christos 
   2110  1.1.1.2  christos static void
   2111  1.1.1.2  christos mach_h8300hn (void)
   2112  1.1.1.2  christos {
   2113  1.1.1.2  christos   Hmode = 1;
   2114  1.1.1.2  christos   Smode = 0;
   2115  1.1.1.2  christos   Nmode = 1;
   2116  1.1.1.2  christos   SXmode = 0;
   2117  1.1.1.2  christos   default_mach = bfd_mach_h8300hn;
   2118  1.1.1.2  christos }
   2119  1.1.1.2  christos 
   2120  1.1.1.2  christos static void
   2121  1.1.1.2  christos mach_h8300s (void)
   2122  1.1.1.2  christos {
   2123  1.1.1.2  christos   Hmode = 1;
   2124  1.1.1.2  christos   Smode = 1;
   2125  1.1.1.2  christos   Nmode = 0;
   2126  1.1.1.2  christos   SXmode = 0;
   2127  1.1.1.2  christos   default_mach = bfd_mach_h8300s;
   2128  1.1.1.2  christos }
   2129  1.1.1.2  christos 
   2130  1.1.1.2  christos static void
   2131  1.1.1.2  christos mach_h8300sn (void)
   2132  1.1.1.2  christos {
   2133  1.1.1.2  christos   Hmode = 1;
   2134  1.1.1.2  christos   Smode = 1;
   2135  1.1.1.2  christos   Nmode = 1;
   2136  1.1.1.2  christos   SXmode = 0;
   2137  1.1.1.2  christos   default_mach = bfd_mach_h8300sn;
   2138  1.1.1.2  christos }
   2139  1.1.1.2  christos 
   2140  1.1.1.2  christos static void
   2141  1.1.1.2  christos mach_h8300sx (void)
   2142  1.1.1.2  christos {
   2143  1.1.1.2  christos   Hmode = 1;
   2144  1.1.1.2  christos   Smode = 1;
   2145  1.1.1.2  christos   Nmode = 0;
   2146  1.1.1.2  christos   SXmode = 1;
   2147  1.1.1.2  christos   default_mach = bfd_mach_h8300sx;
   2148  1.1.1.2  christos }
   2149  1.1.1.2  christos 
   2150  1.1.1.2  christos static void
   2151  1.1.1.2  christos mach_h8300sxn (void)
   2152  1.1.1.2  christos {
   2153  1.1.1.2  christos   Hmode = 1;
   2154  1.1.1.2  christos   Smode = 1;
   2155  1.1.1.2  christos   Nmode = 1;
   2156  1.1.1.2  christos   SXmode = 1;
   2157  1.1.1.2  christos   default_mach = bfd_mach_h8300sxn;
   2158  1.1.1.2  christos }
   2159  1.1.1.2  christos 
   2160  1.1.1.2  christos const struct mach_func mach_table[] =
   2161  1.1.1.2  christos {
   2162  1.1.1.2  christos   {"h8300h",  mach_h8300h},
   2163  1.1.1.2  christos   {"h8300hn", mach_h8300hn},
   2164  1.1.1.2  christos   {"h8300s",  mach_h8300s},
   2165  1.1.1.2  christos   {"h8300sn", mach_h8300sn},
   2166  1.1.1.2  christos   {"h8300sx", mach_h8300sx},
   2167  1.1.1.2  christos   {"h8300sxn", mach_h8300sxn}
   2168  1.1.1.2  christos };
   2169      1.1  christos 
   2170  1.1.1.3  christos int
   2171      1.1  christos md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
   2172  1.1.1.2  christos {
   2173      1.1  christos   unsigned int i;
   2174      1.1  christos   switch (c)
   2175      1.1  christos     {
   2176      1.1  christos     case OPTION_H_TICK_HEX:
   2177      1.1  christos       enable_h_tick_hex = 1;
   2178  1.1.1.2  christos       break;
   2179  1.1.1.2  christos     case OPTION_MACH:
   2180  1.1.1.2  christos       for (i = 0; i < sizeof(mach_table) / sizeof(struct mach_func); i++)
   2181  1.1.1.2  christos 	{
   2182  1.1.1.2  christos 	  if (strcasecmp (arg, mach_table[i].name) == 0)
   2183  1.1.1.2  christos 	    {
   2184  1.1.1.2  christos 	      mach_table[i].func();
   2185  1.1.1.2  christos 	      break;
   2186  1.1.1.2  christos 	    }
   2187  1.1.1.2  christos 	}
   2188  1.1.1.2  christos       if (i >= sizeof(mach_table) / sizeof(struct mach_func))
   2189  1.1.1.2  christos 	as_bad (_("Invalid argument to --mach option: %s"), arg);
   2190      1.1  christos       break;
   2191      1.1  christos     default:
   2192      1.1  christos       return 0;
   2193      1.1  christos     }
   2194      1.1  christos   return 1;
   2195      1.1  christos }
   2196      1.1  christos 
   2197  1.1.1.2  christos void
   2198      1.1  christos md_show_usage (FILE *stream)
   2199  1.1.1.2  christos {
   2200  1.1.1.2  christos   fprintf (stream, _(" H8300-specific assembler options:\n"));
   2201  1.1.1.2  christos   fprintf (stream, _("\
   2202  1.1.1.2  christos   -mach=<name>             Set the H8300 machine type to one of:\n\
   2203  1.1.1.2  christos                            h8300h, h8300hn, h8300s, h8300sn, h8300sx, h8300sxn\n"));
   2204  1.1.1.2  christos   fprintf (stream, _("\
   2205      1.1  christos   -h-tick-hex              Support H'00 style hex constants\n"));
   2206      1.1  christos }
   2207      1.1  christos 
   2208      1.1  christos void tc_aout_fix_to_chars (void);
   2210      1.1  christos 
   2211      1.1  christos void
   2212      1.1  christos tc_aout_fix_to_chars (void)
   2213      1.1  christos {
   2214      1.1  christos   printf (_("call to tc_aout_fix_to_chars \n"));
   2215      1.1  christos   abort ();
   2216      1.1  christos }
   2217      1.1  christos 
   2218      1.1  christos void
   2219      1.1  christos md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
   2220      1.1  christos 		 segT seg ATTRIBUTE_UNUSED,
   2221      1.1  christos 		 fragS *fragP ATTRIBUTE_UNUSED)
   2222      1.1  christos {
   2223      1.1  christos   printf (_("call to md_convert_frag \n"));
   2224      1.1  christos   abort ();
   2225      1.1  christos }
   2226      1.1  christos 
   2227      1.1  christos valueT
   2228  1.1.1.5  christos md_section_align (segT segment, valueT size)
   2229  1.1.1.2  christos {
   2230      1.1  christos   int align = bfd_section_alignment (segment);
   2231      1.1  christos   return ((size + (1 << align) - 1) & (-1U << align));
   2232      1.1  christos }
   2233      1.1  christos 
   2234      1.1  christos void
   2235      1.1  christos md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   2236      1.1  christos {
   2237      1.1  christos   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
   2238      1.1  christos   long val = *valP;
   2239      1.1  christos 
   2240      1.1  christos   switch (fixP->fx_size)
   2241      1.1  christos     {
   2242      1.1  christos     case 1:
   2243      1.1  christos       *buf++ = val;
   2244      1.1  christos       break;
   2245      1.1  christos     case 2:
   2246      1.1  christos       *buf++ = (val >> 8);
   2247      1.1  christos       *buf++ = val;
   2248      1.1  christos       break;
   2249      1.1  christos     case 4:
   2250      1.1  christos       *buf++ = (val >> 24);
   2251      1.1  christos       *buf++ = (val >> 16);
   2252      1.1  christos       *buf++ = (val >> 8);
   2253      1.1  christos       *buf++ = val;
   2254      1.1  christos       break;
   2255      1.1  christos     case 8:
   2256      1.1  christos       /* This can arise when the .quad or .8byte pseudo-ops are used.
   2257      1.1  christos 	 Returning here (without setting fx_done) will cause the code
   2258      1.1  christos 	 to attempt to generate a reloc which will then fail with the
   2259      1.1  christos 	 slightly more helpful error message: "Cannot represent
   2260      1.1  christos 	 relocation type BFD_RELOC_64".  */
   2261      1.1  christos       return;
   2262      1.1  christos     default:
   2263      1.1  christos       abort ();
   2264      1.1  christos     }
   2265      1.1  christos 
   2266      1.1  christos   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
   2267      1.1  christos     fixP->fx_done = 1;
   2268      1.1  christos }
   2269      1.1  christos 
   2270      1.1  christos int
   2271      1.1  christos md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
   2272      1.1  christos 			       segT segment_type ATTRIBUTE_UNUSED)
   2273      1.1  christos {
   2274      1.1  christos   printf (_("call to md_estimate_size_before_relax \n"));
   2275      1.1  christos   abort ();
   2276      1.1  christos }
   2277      1.1  christos 
   2278      1.1  christos /* Put number into target byte order.  */
   2279      1.1  christos void
   2280      1.1  christos md_number_to_chars (char *ptr, valueT use, int nbytes)
   2281      1.1  christos {
   2282      1.1  christos   number_to_chars_bigendian (ptr, use, nbytes);
   2283      1.1  christos }
   2284      1.1  christos 
   2285      1.1  christos long
   2286      1.1  christos md_pcrel_from (fixS *fixp)
   2287      1.1  christos {
   2288      1.1  christos   as_bad_where (fixp->fx_file, fixp->fx_line,
   2289      1.1  christos 		_("Unexpected reference to a symbol in a non-code section"));
   2290      1.1  christos   return 0;
   2291      1.1  christos }
   2292      1.1  christos 
   2293      1.1  christos arelent *
   2294      1.1  christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
   2295      1.1  christos {
   2296      1.1  christos   arelent *rel;
   2297      1.1  christos   bfd_reloc_code_real_type r_type;
   2298      1.1  christos 
   2299      1.1  christos   if (fixp->fx_addsy && fixp->fx_subsy)
   2300      1.1  christos     {
   2301      1.1  christos       if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
   2302      1.1  christos 	  || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
   2303      1.1  christos 	{
   2304      1.1  christos 	  as_bad_where (fixp->fx_file, fixp->fx_line,
   2305      1.1  christos 			_("Difference of symbols in different sections is not supported"));
   2306      1.1  christos 	  return NULL;
   2307      1.1  christos 	}
   2308  1.1.1.3  christos     }
   2309  1.1.1.3  christos 
   2310      1.1  christos   rel = XNEW (arelent);
   2311      1.1  christos   rel->sym_ptr_ptr = XNEW (asymbol *);
   2312      1.1  christos   *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   2313      1.1  christos   rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
   2314      1.1  christos   rel->addend = fixp->fx_offset;
   2315      1.1  christos 
   2316      1.1  christos   r_type = fixp->fx_r_type;
   2317      1.1  christos 
   2318      1.1  christos #define DEBUG 0
   2319      1.1  christos #if DEBUG
   2320      1.1  christos   fprintf (stderr, "%s\n", bfd_get_reloc_code_name (r_type));
   2321      1.1  christos   fflush (stderr);
   2322      1.1  christos #endif
   2323      1.1  christos   rel->howto = bfd_reloc_type_lookup (stdoutput, r_type);
   2324      1.1  christos   if (rel->howto == NULL)
   2325      1.1  christos     {
   2326      1.1  christos       as_bad_where (fixp->fx_file, fixp->fx_line,
   2327      1.1  christos 		    _("Cannot represent relocation type %s"),
   2328      1.1  christos 		    bfd_get_reloc_code_name (r_type));
   2329      1.1  christos       return NULL;
   2330      1.1  christos     }
   2331      1.1  christos 
   2332                      return rel;
   2333                    }
   2334